<?php 
// 
// whois.php3 v1.8.4 1999/08/08 
// 
// Copyright (c) 1998, 1999 Mark Jeftovic / easyDNS Technologies Inc. 
//              email: markjr@easyDNS.com 
// 
// For most recent version check: 
http://www.shmOOze.net/~markjr/whois/ // 
// All rights reserved.  
// This code provided \"As Is\" with no warrantees express or implied. 
// The author and contributors are not liable for anything good or 
// bad that results from your use of this code. 
// 
// You are free to distribute this for free provided this notice is 
// included. Please forward fixes/enhancements to the author for 
// inclusion in the next revision. 
// 
// CHANGES: 
// 1.8.4 (11/08/99): should be sending query with \\r\\n, not 
//             just \\n, thanks to Steve Bright <steve@netdevils.net> 
//             for noticing 
// 1.8.3 (08/20/99): added adamsnames TLD\'s and .ac and .sh 
// 1.8.2 (07/12/99): added $this->DISCLAIMER for the floating 
//             goddamn disclaimer they keep moving around 
// 1.8.0 (07/03/99): added getRegInfo() and parseRegInfo() which 
//             get called from zonelookup() so it\'ll work 
//             for .com/.net/.org regardless of registrar 
//             because it\'ll ask whois.crsnic.net first     
// 1.7.1 (05/15/99): added not found string for whois.ripe.net 
// 1.7 - (05/13/99): added getTLD() in order to support 2nd level 
//     registries like nominet, which we now support as well 
//     (.uk.com/.gb.net/.gb.com) 
// 1.6 - (05/04/99): added .sg to server list. 
//    -changed all easydns TLD\'s to whois.easydns.net 
// 1.5 - (04/22/99): DOMAIN_STATUS and CREATED are back in 
//    - added support for pretty well every TLD, including 
//      ccTLD\'s and alternate like ORSC, SuperRoot and our 
//      own. parsezone() probably won\'t work outside .com/.net/.org 
//      and found/not found might be broken for a given whois/tld 
//      your milage may vary, let me know of any tweaks 
// 1.4b4 -(03/24/99): A few changes by Colin Viebrock (cmv@easydns.com) 
//    - tried to trim() as much of the returned data as possible 
//    - removed DOMAIN_STATUS and CREATED, since Internic decided 
//      not to give out this info anymore 
//    - added dns_query() function which just checks the DNS records 
//      of the domain for NS entries and returns true if it finds 
//      some, false otherwise ... this needs to be integrated into 
//      into the class better (toggle for LOOKUP_METHOD, perhaps?) 
// 1.4b3 -(01/05/99): Internic chenged the \"Too Busy\" message wording 
//      again. Reported by Gregory A. Carter <omni@dynmc.net> 
// 1.4b2 -(08/24/98): put the old code back in parse_contact_line() with 
//      a bit ofa modification (the version in 1.4b couldn\'t parse 
//      the result from doing a rawlookup() on a nic handle properly) 
// 1.4b - (08/17/98): added ability to cache results, set $whois->use_cache 
//     and rawlookup() will  
//          a) check the cache_dir for a previously cached zone file 
//           and use it if it finds it, sets $whois->FROM_CACHE 
//        b) write a zone record there after it looks it up 
//    It\'s up to the user to expire the cache (i.e. cron job to delete 
//    entries older than x seconds) 
//    -TODO: if caching is turned on and $whois->HANDLES is set (query 
//    returned multiple handles) the result still gets cached. I don\'t 
//    want this but it happens anyways. This is probably a bug. 
//    - pushed default server (whois.internic.net) from param to connect() 
//    to rawlookup(), because i realized you couldn\'t do rawlookup() 
//    to other whois servers the old way. For now just use: 
//    $whois->rawlookup(\"example.ca\", \"whois.cdnnet.ca\") to do  
//    alternate lookups 
//    -parse_contact_line() rewritten by Ben Ginter <bginter@abilnet.com> 
//    (although I added the chop()\'s, some code here broke without them) 
// 1.3 - (07/28/98): the whois server is starting to spit out a couple 
//     or few blank lines and then dying, which wouldn\'t set 
//     $whois->ERROR, even though it should, so now it does 
// 1.2 - format change on Internic side, Organization info preceded by 
//      a \"Registrant:\" line. 
// 1.1 - couple of bugfixes by Colin Viebrock <cmv@privateworld.com> 
//     ORG_ADDRESS wasn\'t getting caught because of a typo 
//  
//     added trim() function (now internal to php anyways i think) 
// 
// USAGE: 
// $domain    = \"somedomain.com\"; 
// $whois     = new whois; 
// 
// the following line simply loads an array with the raw output of 
// a whois query and sets $whois->FOUND (if the query finds no 
// match $whois->FOUND will be 0) if an error occurs in the lookup 
// $whois->ERROR will be set. 
// $array    = $whois->rawlookup($domain) 
// 
// this parses the array into variables available to the package: 
// $whois->parsezone($array); 
//      
// will set vars such as $whois->ORGANIZATION, $whois->ORG_HANDLE 
// $whois->DOMAIN_NAME, the hashes $whois->TECH, $whois->ADMIN, etc. 
// and the arrays: $whois->DNS_NAME and $whois->DNS_IP 
// (for a complete list, see below) 
// 
// you can complete both steps (rawlookup and parsezone) with: 
// $whois->zonelookup($domain); 
// 
// TODO: 
//    - support to parse other types of queries (host, contact, etc) 
//      (you can still use rawlookup for these types of handles) 
//    - support for alternate servers/queries (i.e. netblocks via 
//      whois.arin.net) 
//    - need to verify found/not found syntax for all the other 
//      whois servers in the $SERVER array \"not found\" or 
//      \"no match for\" case insensitive seems to be a pretty safe bet 
//      so far 
//    - now we need to be able to parse the various output formats from 
//      the shared registrars (what a fucking mess) 
// 
class whois {
var $use_cache = 0;
var $FROM_CACHE=0; 
var $cache_dir = $DIRS[ \"whois_cache\"];
var $port = 43;
var $MAXLEN = 1024;
// we need querytype now that we will support queries outside of  
// .com/.net/.org 
// possible values (whether support is in this version or not): 
//    \"raw\" = unspecified 
//    \"domain\" = domain name 
//    \"handle\" = contact handle 
//    \"server\" = nameserver 
//    \"registrar\"  
var $QUERY_TYPE =  \"domain\";     
var $DEFAULT_SERVER =  \"whois.internic.net\";
var $REGISTRY_SERVER =  \"whois.crsnic.net\";
var $REG_INFO;     // array of \"domain\",\"registrar\",\"whois\",\"referrer\" and 
         // \"nameserver[]\"; 
var $REG_FIELDS = array( \"domain\"=> \"Domain Name\",
             \"registrar\"=> \"Registrar\",
             \"whois\"=> \"Whois Server\",
             \"referrer\"=> \"Referral URL\",
             \"nameserver\"=> \"Name Server\",  // identical descriptors 
             \"upadated\"=> \"Updated Date\"
            );
// if we want to automagically retry after a failed connect then 
// set $MAX_RETRIES the number of retries you want 
var $MAX_RETRIES = 0;
var $SLEEP_VAL = 1;
var $RETRY = 0;
var $FOUND = 0;     // this will be 0 if the query yields no match 
var $ERROR = 0;  // this will be set if an error occurs in the lookup 
var $DATA_MIN = 8;  // we should at least this many bytes of data, or 
         // we assume the whois server just spit out nothing 
         // and died (which it\'s starting to do more often) 
var $DATA_COUNT = 0;
// these are the vars set when you parse the results of a domain lookup 
var $DISCLAIMER;
var $ORGANIZATION;
var $ORG_HANDLE;
var $ORG_ADDRESS;     // array that holds the org\'s address info 
var $DOMAIN_NAME;
var $DOMAIN_STATUS;    
var $ADMIN;         // hash with subscripts: \"name\", \"nic\" and \"email\" 
var $TECH;         // hash with subscripts: \"name\", \"nic\" and \"email\" 
var $ZONE;         // hash with subscripts: \"name\", \"nic\" and \"email\" 
var $BILLING;
var $UPDATED;
var $CREATED;        
var $DNS_NAME;         // array of nameserver hostnames (primary first) 
var $DNS_IP;         // array of nameserver ips (primary first) 
var $HANDLES;         // array of nic handles if a zonelookup yields 
             // multiple results 
var $SERVER = array(
         \"ac\"=> \"whois.nic.ac\",
         \"al\"=> \"whois.ripe.net\",
         \"am\"=> \"whois.amnic.net\",
         \"art\"=> \"whois.skyscape.net\",
         \"arts\"=> \"whois.skyscape.net\",
         \"at\"=> \"whois.ripe.net\",
         \"au\"=> \"whois.aunic.net\",
         \"az\"=> \"whois.ripe.net\",
         \"ba\"=> \"whois.ripe.net\",
         \"bank\"=> \"whois.skyscape.net\",
         \"be\"=> \"whois.ripe.net\",
         \"bg\"=> \"whois.ripe.net\",
         \"biz\"=> \"rs.mcs.net\",
         \"by\"=> \"whois.ripe.net\",
         \"ca\"=> \"whois.cdnnet.ca\",
         \"can\"=> \"whois.easydns.net\",
         \"cc\"=> \"whois.nic.cc\",
         \"cdn\"=> \"whois2.vrx.net\",
         \"ch\"=> \"whois.nic.ch\",
         \"cn\"=> \"whois.apnic.net\",
         \"com\"=> \"rs.internic.net\",
         \"corp\"=> \"rs.mcs.net\",
         \"cx\"=> \"whois.nic.cx\",
         \"cy\"=> \"whois.ripe.net\",
         \"cz\"=> \"whois.ripe.net\",
         \"dds\"=> \"whois.vrx.net\",
         \"de\"=> \"whois.ripe.net\",
         \"dir\"=> \"whois.skyscape.net\",
         \"dk\"=> \"whois.ripe.net\",
         \"dz\"=> \"whois.ripe.net\",
         \"edu\"=> \"rs.internic.net\",
         \"ee\"=> \"whois.ripe.net\",
         \"eg\"=> \"whois.ripe.net\",
         \"es\"=> \"whois.ripe.net\",
         \"etc\"=> \"whois.easydns.net\",
         \"faq\"=> \"whois.vrx.net\",
         \"fi\"=> \"whois.ripe.net\",
         \"film\"=> \"whois.skyscape.net\",
         \"fo\"=> \"whois.ripe.net\",
         \"fr\"=> \"whois.ripe.net\",
         \"fund\"=> \"whois.skyscape.net\",
         \"gallery\"=> \"whois.vrx.net\",
         \"gb\"=> \"whois.ripe.net\",
         \"gb.com\"=> \"whois.nomination.net\",
         \"gb.net\"=> \"whois.nomination.net\",
         \"ge\"=> \"whois.ripe.net\",
         \"gmbh\"=> \"whois.vrx.net\",
         \"gov\"=> \"whois.nic.gov\",
         \"gr\"=> \"whois.ripe.net\",
         \"gs\"=> \"whois.adamsnames.tc\",
         \"help\"=> \"whois.skyscape.net\",
         \"hk\"=> \"whois.apnic.net\",
         \"hotel\"=> \"whois.skyscape.net\",
         \"hr\"=> \"whois.ripe.net\",
         \"hu\"=> \"whois.ripe.net\",
         \"ie\"=> \"whois.ripe.net\",
         \"il\"=> \"whois.ripe.net\",
         \"is\"=> \"whois.ripe.net\",
         \"isp\"=> \"whois.skyscape.net\",
         \"it\"=> \"whois.nic.it\",
         \"jp\"=> \"whois.nic.ad.jp\",
         \"k12\"=> \"rs.mcs.net\",
         \"kr\"=> \"whois.apnic.net\",
         \"li\"=> \"whois.nic.ch\",
         \"list\"=> \"whois.vrx.net\",
         \"llb\"=> \"whois.vrx.net\",
         \"lt\"=> \"whois.ripe.net\",
         \"lu\"=> \"whois.ripe.net\",
         \"lv\"=> \"whois.ripe.net\",
         \"ma\"=> \"whois.ripe.net\",
         \"md\"=> \"whois.ripe.net\",
         \"med\"=> \"whois.skyscape.net\",
         \"mil\"=> \"whois.nic.mil\",
         \"mk\"=> \"whois.ripe.net\",
         \"ms\"=> \"whois.adamsnames.tc\",
         \"mt\"=> \"whois.ripe.net\",
         \"mx\"=> \"nic.mx\",
         \"music\"=> \"whois.skyscape.net\",
         \"net\"=> \"rs.internic.net\",
         \"nic\"=> \"whois.vrx.net\",
         \"nl\"=> \"domain-registry.nl\",
         \"no\"=> \"whois.ripe.net\",
         \"npo\"=> \"rs.mcs.net\",
         \"org\"=> \"rs.internic.net\",
         \"php\"=> \"whois.easydns.net\",
         \"pl\"=> \"whois.ripe.net\",
         \"prices\"=> \"whois.vrx.net\",
         \"pt\"=> \"whois.ripe.net\",
         \"radio\"=> \"whois.skyscape.net\",
         \"ro\"=> \"whois.ripe.net\",
         \"ru\"=> \"whois.ripn.ru\",
         \"se\"=> \"whois.nic-se.se\",
         \"sg\"=> \"whois.nic.net.sg\",
         \"si\"=> \"whois.ripe.net\",
         \"sh\"=> \"whois.nic.sh\",
         \"sk\"=> \"whois.ripe.net\",
         \"sky\"=> \"whois.skyscape.net\",
         \"sm\"=> \"whois.ripe.net\",
         \"sql\"=> \"whois.vrx.net\",
         \"su\"=> \"whois.ripe.net\",
         \"tc\"=> \"whois.adamsnames.tc\",
         \"tf\"=> \"whois.adamsnames.tc\",
         \"tj\"=> \"whois.nic.tj\",
         \"tn\"=> \"whois.ripe.net\",
         \"tr\"=> \"whois.ripe.net\",
         \"tw\"=> \"whois.apnic.net\",
         \"ua\"=> \"whois.ripe.net\",
         \"uk\"=> \"whois.nic.uk\",
         \"uk.com\"=> \"whois.nomination.net\",
         \"us\"=> \"whois.isi.edu\",
         \"va\"=> \"whois.ripe.net\",
         \"vg\"=> \"whois.adamsnames.tc\",
         \"video\"=> \"whois.skyscape.net\",
         \"xxx\"=> \"whois.skyscape.net\",
         \"y2k\"=> \"whois.easydns.net\",
         \"yu\"=> \"whois.ripe.net\",
         \"zine\"=> \"whois.skyscape.net\",
         \"zoo\"=> \"whois.vrx.net\",
         \"666\"=> \"whois.easydns.net\",
         \"800\"=> \"whois.vrx.net\",
         \"888\"=> \"whois.vrx.net\",
         \"int\"=> \"whois.isi.edu\"
        );
var $TLD;
var $RAWINFO;
var $i, $k, $tld, $max;
// open a socket to the whois server 
// defaults to whois.internic.net if an alternate is not passed 
// returns: a pointer on success, sets $this->ERROR on fail 
function connect ($server) {
    while($this->RETRY <= $this->MAX_RETRIES):
        $ptr = fsockopen($server, $this->port); 
        if($ptr>0):
            $this->ERROR=0;     // just in case we\'re on a retry 
            return($ptr);
        else:
            $this->ERROR++;
            $this->RETRY++;
            sleep($this->SLEEP_VAL);
        endif;
    endwhile;
    }
// getTLD($domain) 
// this returns the registry level domain since we\'re 
// now supporting a registry with 2nd-level domains 
// (nominet\'s uk.com, gb.net and gb.com) 
function getTLD ($domain) {
     // unfortunately the only reliable way to do this is 
     // to blow through the entire server/tld list  
    reset($this->SERVER);
    for($this->i=0,$this->max=count($this->SERVER);$this->i<$this->max;
                            $this->i++) {
        $this->k=key($this->SERVER);
        if(eregi( \"$this->k$\", $domain)) { 
            if(!empty($this->tld)) {
                 // FIXME: we assume we\'ll never support a 3rd 
                 // level registry. If we do, this breaks. 
                $this->tld = strchr($this->k, \".\") ?
                         $this->k : $this->tld;
                }    
            else    { $this->tld = $this->k; }
            }        
        next($this->SERVER);
        }
    return($this->tld);
    }
// simply gets the output of the query from the whois server 
// and loads it into array 
function rawlookup ($query) {
    if(!$query):
        return( \"\");
    endif;
    $this->TLD=$this->getTLD(strtolower($query));
    if($this->QUERY_TYPE== \"domain\" && empty($this->REG_INFO[whois])):
        $server = 
            !empty($this->TLD) && isSet($this->SERVER[$this->TLD]) ?
            $this->SERVER[$this->TLD] : $this->DEFAULT_SERVER;
    elseif($this->QUERY_TYPE== \"registrar\"):
        $server=$this->REGISTRY_SERVER;
    else:
        $server=$this->DEFAULT_SERVER;
    endif;
    $ptr=$this->connect($server);
    if($ptr):
        fputs($ptr, sprintf( \"%s\\r\\n\",trim($query)));
        $i=0;
        $this->FOUND=1;
        while(!feof($ptr)):
            $array[$i]=fgets($ptr,$this->MAXLEN);
            $this->DATA_COUNT+=strlen(trim($array[$i]));
            if(eregi( \"No match for\", $array[$i])):
                $this->FOUND=0;
            elseif(eregi( \"Not found\", $array[$i])):
                $this->FOUND=0;
            elseif(eregi( \"No entries found for the selected source\", $array[$i])):
                $this->FOUND=0;
             elseif(eregi( \"WHOIS database is down\",$array[$i])):
                        $this->ERROR++;
                            $this->FOUND=0;
             elseif(eregi( \"Please wait a while and try again\",$array[$i])):
                        $this->ERROR++;
                            $this->FOUND=0;
                        break;
            endif;
            $i++;
        endwhile;
        fclose($ptr);
        if($this->DATA_COUNT>$this->DATA_MIN):
            return($array);        
        else:
            $this->ERROR++;
        endif;
    else:
        $this->ERROR++;
    endif;
    }
// takes a contact info line from a zone record and parses it 
// into name, nic, and email 
// reverted to old code with a modified email pattern in 1.4b_2 
function parse_contact_line ($line) {
    $hash[ \"name\"]=trim(ereg_replace( \"(.+) \\(.+\",  \"\\\\1\", $line));
        $hash[ \"nic\"]=ereg_replace( \".+\\((.+)\\).+\",  \"\\\\1\", $line);
        $hash[ \"email\"]=trim(ereg_replace( \".+\\)[[:space:]]+(.+)\",  \"\\\\1\", $line));
        return($hash);
}
// parses an array with zone info into the package variables for e-z access 
function parsezone ($array) {
    if(!$array || !$this->FOUND || $this->ERROR):
        return( \"\");
    endif;
     // alas, we need to blow through this array twice, the 
     // first time to determine a few things 
    $lookahead=0; 
    $dis_start=0;
    $dis_stop=0;
    while($lookahead<count($array)):
         // at what point will we stop assuming input 
         // gets added to $this->ORG_ADDRESS 
        if(ereg( \"Domain Name: .+\",$array[$lookahead])):
            $dline=$lookahead;    
        elseif(ereg( \"Registrant:\", $array[$lookahead])):
            $dis_stop=$lookahead-1;
        elseif(ereg( \"To single out one record\", $array[$lookahead])):
            $this->FOUND++;
        endif;
        $lookahead++;
    endwhile;
    $i=0; 
    while($i<count($array)):
       if($this->FOUND==1):
        if(ereg( \"Registrant:\", $array[$i])):
            $i++;
            list($this->ORGANIZATION,$this->ORG_HANDLE)=split( \"\\(\",$array[$i],2);
            $this->ORGANIZATION = trim($this->ORGANIZATION);
            $this->ORG_HANDLE=ereg_replace( \"\\)$\", \"\",trim($this->ORG_HANDLE));
            $bline=$i;
        elseif($i>dis_start && $i<$dis_stop):
            $this->DISCLAIMER[]=$array[$i];
        elseif($i>bline && $i<$dline):
            $x1 = trim($array[$i]);
            if ($x1):
                $this->ORG_ADDRESS[] = $x1;
            endif;
        elseif(ereg( \"Domain Name: .+\", $array[$i])):
            $x1 = ereg_replace( \"Domain Name: (.+$)\", \"\\\\1\",$array[$i]);
            $this->DOMAIN_NAME = trim($x1);
        elseif(ereg( \"Domain Status: .+\", $array[$i])):
            $this->DOMAIN_STATUS=ereg_replace( \"Domain Status: (.+$)\", \"\\\\1\",$array[$i]);
        elseif(ereg( \"Record last updated on\",$array[$i])):
            $x1 = ereg_replace( \"Record last updated on (.+$)\", \"\\\\1\",$array[$i]);
            $this->UPDATED = ereg_replace( \"\\.$\",  \"\", trim($x1));
        elseif(ereg( \"Record created on\",$array[$i])):
            $this->CREATED=ereg_replace( \"Record created on (.+$)\", \"\\\\1\",$array[$i]);
        elseif(ereg( \"Domain servers in listed order:\",$array[$i])):
            $i++;
            while($i<count($array)):
                $i++;
                if(ereg( \".+\\..+\\..+[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+\", $array[$i])):
                    list($x1,$x2) = split( \"(\\20|\\t)+\",$array[$i],2);
                    $this->DNS_NAME[] = trim($x1);
                    $this->DNS_IP[] = trim($x2);
                endif;
            endwhile;
        endif;
         // looks like we can\'t use backreferences outside the 
         // regex functions they\'re used in, so we\'re kinda 
         // stuck here and have to put these checks 
         // outside the above switch. (cause two or more 
         // of these could appear on the same line) 
        if(ereg( \"Administrative Contact\",$array[$i])):
            $this->ADMIN=$this->parse_contact_line($array[$i+1]);
        endif;
        if(ereg( \"Technical Contact\",$array[$i])):
            $this->TECH=$this->parse_contact_line($array[$i+1]);
        endif;
        if(ereg( \"Zone Contact\",$array[$i])):
            $this->ZONE=$this->parse_contact_line($array[$i+1]);
        endif;
        if(ereg( \"Billing Contact\",$array[$i])):
            $this->BILLING=$this->parse_contact_line($array[$i+1]);
        endif;
       else:
        if(ereg( \".+\\(.+\\).+\", $array[$i])):
            $this->HANDLES[]=ereg_replace( \".+\\((.+)\\).+\", \"\\\\1\",$array[$i]);
            $this->FOUND++;
        endif;
       endif;
       $i++;
    endwhile;
     // we still get spurious blank results, so we\'ll check that  
     // the nic handles aren\'t null and set $this->ERROR if they are 
    if(!count($this->ADMIN) || !count($this->TECH)) { $this->ERROR++; }
    }
// gets the registry/registrar info now that .com/.net/.org has a 
// sahred registry 
function getRegInfo ($query) {
    $old_type = $this->QUERY_TYPE;
    $this->QUERY_TYPE= \"registrar\";
    $raw_reg_info=$this->rawlookup($query);    
    $this->QUERY_TYPE=$old_type;
    return($this->parseRegInfo($raw_reg_info));
}
function parseRegInfo ($array) {
    for($i=0,$max=count($array);$i<$max;$i++) {
        reset($this->REG_FIELDS);
        while(list($key,$val)=each($this->REG_FIELDS)):
            list($f_name,$f_val)=split( \":\", $array[$i]);
            if($val==trim($f_name)) { 
                if($key== \"nameserver\") {
                    $ret_val[$key][]=trim($f_val);
                } else {
                    $ret_val[$key]=trim($f_val);
                }
                break;
            }
        endwhile;
        }
    return($ret_val);
}
// does rawlookup() and passes the resultant array to parsezone() 
function zonelookup ($query) {
    if($this->use_cache):
        $rawinfo = $this->cache_lookup(strtolower(trim($query)));
        if($this->FOUND && !$this->FROM_CACHE && !$this->HANDLES):
            $this->cache_write($query, $rawinfo);
        endif;
    else:
        $this->REG_INFO = $this->getRegInfo($query);
        if(!empty($this->REG_INFO[whois])) {
            $this->DEFAULT_SERVER=$this->REG_INFO[whois];
            }
        $this->RAWINFO = $this->rawlookup($query);
    endif;
    if($this->FOUND):
        $this->parsezone($this->RAWINFO);
    endif;
    }
function cache_lookup ($query) {
    $cache_file = $this->cache_dir . \"/\". $query;
    if(file_exists($cache_file)):
        $this->FROM_CACHE=1;
        $this->FOUND=1;
        return(file($cache_file));
    else:
        $rawinfo = $this->rawlookup($query);
        if(!$this->ERROR && $this->FOUND):
            return($rawinfo);
        endif;    
    endif;    
    }
function cache_write ($query, $rawinfo) {
    $fp = fopen( \"$this->cache_dir/$query\",  \"w\");
    for($i=0,$num=count($rawinfo);$i<$num;$i++) {
        fputs($fp, $rawinfo[$i]);
        }
    }
function dns_lookup($query) {
    return checkdnsrr($query, \"NS\");
}
};
?>
Det er nok det beste :) funder på:
http://www.shmooze.net/~markjr/whois/