From bb3b9f8e142ae5084088525fb25ce8c423f525de Mon Sep 17 00:00:00 2001 From: x99bachelart Date: Tue, 2 Sep 2003 21:52:24 +0000 Subject: [PATCH] NNTP subroutines --- include/NetNNTP.inc.php | 471 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 471 insertions(+) create mode 100644 include/NetNNTP.inc.php diff --git a/include/NetNNTP.inc.php b/include/NetNNTP.inc.php new file mode 100644 index 0000000..12220aa --- /dev/null +++ b/include/NetNNTP.inc.php @@ -0,0 +1,471 @@ +ns,1200)); + if ($this->debug) { + print "NNTP >>>> $line \n"; + } + return $line; + } + + /** puts a line on server + * @param STRING $_line line to put + */ + + function pline($_line) { + if ($this->debug) { + $dline = preg_replace("/\r\n$/","",$_line); + $dline = preg_replace("/(\r|\n|\r\n)/","\nNNTP <<<< ",$dline); + print "NNTP <<<< $dline \n"; + } + return fputs($this->ns,$_line,strlen($_line)); + } + + /** constructor + * @param $_host STRING NNTP host + * @param $_timeout INTEGER socket timeout + * @param $_debug BOOLEAN debug flag (generates verbose output if on) + * @param $_reader BOOLEAN sends a "MODE READER" at connection if true + */ + + function nntp($_host,$_timeout=120,$_debug=0,$_reader=true) { + if (preg_match("/([^:]+):([^:]+)/",$_host,$regs)) { + $host = $regs[1]; + $port = $regs[2]; + } else { + $host = $_host; + $port = 119; + } + $this->ns = fsockopen($host, $port, &$errno, &$errstr, $_timeout); + $this->debug = $_debug; + if (!$this->ns) { + if ($this->debug) { + echo "ERREUR: $errno - $errstr
\n"; + } + $this = false; + return false; + } + $result = $this->gline(); + $this->posting = (substr($result,0,3)=="200"); + if ($_reader && (substr($result,0,1)=="2")) { + $this->pline("MODE READER\r\n"); + $result = $this->gline(); + $this->posting = (substr($result,0,3)=="200"); + } + return (substr($result,0,1)=="2"); + } + +# strict NNTP Functions [RFC 977] +# see http://www.faqs.org/rfcs/rfc977.html + + /** authentification + * @param $_user STRING login + * @param $_pass INTEGER password + * @return BOOLEAN true if authentication was successful + */ + + function authinfo($_user,$_pass) { + $user = preg_replace("/(\r|\n)/","",$_user); + $pass = preg_replace("/(\r|\n)/","",$_pass); + $this->pline("AUTHINFO USER $user\r\n"); + $this->gline(); + $this->pline("AUTHINFO PASS $pass\r\n"); + $result=$this->gline(); + if (substr($result,0,1)!="2") { + $this->lasterrorcode = substr($result,0,3); + $this->lasterrortext = substr($result,4); + return false; + } + return true; + } + + /** retrieves an article + * MSGID is a numeric ID a shown in article's headers. MSGNUM is a + * server-dependent ID (see X-Ref on many servers) and retriving + * an article by this way will change the current article pointer. + * If an error occur, false is returned. + * @param $_msgid STRING MSGID or MSGNUM of article + * @return ARRAY lines of the article + * @see body + * @see head + */ + + function article($_msgid="") { + $msgid = preg_replace("/(\r|\n)/","",$_msgid); + $this->pline("ARTICLE $msgid\r\n"); + $result = $this->gline(); + if (substr($result,0,1)!="2") { + $this->lasterrorcode = substr($result,0,3); + $this->lasterrortext = substr($result,4); + return false; + } + $result = $this->gline(); + while ($result != ".") { + $array[] = $result; + $result = $this->gline(); + } + return $array; + } + + /** post a message + * if an error occur, false is returned + * @param $_message STRING message to post + * @return STRING MSGID of article + */ + + function post($_message) { + if (is_array($_message)) { + $message=join("\n",$_message); + } else { + $message=$_message; + } + $this->pline("POST \r\n"); + $result=$this->gline(); + if (substr($result,0,1)!="3") { + $this->lasterrorcode = substr($result,0,3); + $this->lasterrortext = substr($result,4); + return false; + } + $this->pline($message."\r\n.\r\n"); + $result = $this->gline(); + if (substr($result,0,1)!="2") { + $this->lasterrorcode = substr($result,0,3); + $this->lasterrortext = substr($result,4); + return false; + } + if (substr($result,0,1)=="2") { + if (preg_match("/(<[^@>]+@[^@>]+>)/",$result,$regs)) { + return $regs[0]; + } else { + return true; + } + } + return false; + } + + /** fetches the body of an article + * params are the same as article + * @param $_msgid STRING MSGID or MSGNUM of article + * @return ARRAY lines of the article + * @see article + * @see head + */ + + function body($_msgid="") { + $msgid = preg_replace("/(\r|\n)/","",$_msgid); + $this->pline("BODY $msgid\r\n"); + $result = $this->gline(); + if (substr($result,0,1)!="2") { + $this->lasterrorcode = substr($result,0,3); + $this->lasterrortext = substr($result,4); + return false; + } + $result = $this->gline(); + while ($result != ".") { + $array[] = $result; + $result = $this->gline(); + } + return $array; + } + + /** fetches the headers of an article + * params are the same as article + * @param $_msgid STRING MSGID or MSGNUM of article + * @return ARRAY lines of the article + * @see article + * @see body + */ + + function head($_msgid="") { + $msgid = preg_replace("/(\r|\n)/","",$_msgid); + $this->pline("HEAD $msgid\r\n"); + $result = $this->gline(); + if (substr($result,0,1)!="2") { + $this->lasterrorcode = substr($result,0,3); + $this->lasterrortext = substr($result,4); + return false; + } + $result = $this->gline(); + while ($result != ".") { + $array[] = $result; + $result = $this->gline(); + } + return $array; + } + + /** set current group + * @param $_group STRING + * @return ARRAY array : nb of articles in group, MSGNUM of first article, MSGNUM of last article, and group name + */ + + function group($_group) { + $group = preg_replace("/(\r|\n)/","",$_group); + $this->pline("GROUP $group\r\n"); + $line = $this->gline(); + if (substr($line,0,1)!="2") { + $this->lasterrorcode = substr($result,0,3); + $this->lasterrortext = substr($result,4); + return false; + } + if (preg_match("/^2\d{2} (\d+) (\d+) (\d+) ([^ ]+)/", + $line,$regs)) { + return array($regs[1],$regs[2],$regs[3],$regs[4]); + } + return $false; + } + + /** set the article pointer to the previous article in current group + * @return STRING MSGID of article + * @see next + */ + + function last() { + $this->pline("LAST \r\n"); + $line = $this->gline(); + if (substr($line,0,1)!="2") { + $this->lasterrorcode = substr($result,0,3); + $this->lasterrortext = substr($result,4); + return false; + } + if (preg_match("/^2\d{2} \d+ <([^>]+)>/",$line,$regs)) { + return "<{$regs[1]}>"; + } + return $false; + } + + /** set the article pointer to the next article in current group + * @return STRING MSGID of article + * @see last + */ + + function next() { + $this->pline("NEXT \r\n"); + $line = $this->gline(); + if (substr($line,0,1)!="2") { + $this->lasterrorcode = substr($result,0,3); + $this->lasterrortext = substr($result,4); + return false; + } + if (preg_match("/^2\d{2} \d+ <([^>]+)>/",$line,$regs)) { + return "<{$regs[1]}>"; + } + return $false; + } + + /** set the current article pointer + * @param $_msgid STRING MSGID or MSGNUM of article + * @return BOOLEAN true if authentication was successful, error code otherwise + * @see article + * @see body + */ + + function nntpstat($_msgid) { + $msgid = preg_replace("/(\r|\n)/","",$_msgid); + $this->pline("STAT $msgid\r\n"); + $line = $this->gline(); + if (substr($line,0,1)!="2") { + $this->lasterrorcode = substr($result,0,3); + $this->lasterrortext = substr($result,4); + return false; + } + if (preg_match("/^2\d{2} \d+ <([^>]+)>/",$line,$regs)) { + return "<{$regs[1]}>"; + } + return false; + } + + /** returns true if posting is allowed + * @return BOOLEAN true if posting is allowed lines + */ + + function postok() { + return ($this->posting); + } + + /** gets information about all active newsgroups + * @return ARRAY group name => (MSGNUM of first article, MSGNUM of last article, NNTP flags) + * @see newgroups + */ + + function liste() { + $this->pline("LIST\r\n"); + if (substr($this->gline(),0,1)!="2") return false; + $result = $this->gline(); + while ($result != ".") { + preg_match("/([^ ]+) (\d+) (\d+) ./",$result,$regs); + $array[$regs[1]]=array(intval($regs[2]),intval($regs[3]), + intval($regs[4])); + $result = $this->gline(); + } + return $array; + } + + /** get information about recent newsgroups + * same as list, but information are limited to newgroups created after $_since + * @param $_since INTEGER unix timestamp + * @param $_distributions STRING distributions + * @return ARRAY same format as liste + * @see liste + */ + + function newgroups($_since,$_distributions="") { + #assume $_since is a unix timestamp + $distributions = preg_replace("/(\r|\n)/","",$_distributions); + $this->pline("NEWGROUPS ".gmdate("ymd His",$_since) + ." GMT $distributions\r\n"); + if (substr($this->gline(),0,1)!="2") return false; + $result = $this->gline(); + while ($result != ".") { + preg_match("/([^ ]+) (\d+) (\d+) ./",$result,$regs); + $array[$regs[1]]=array(intval($regs[2]),intval($regs[3]), + intval($regs[4])); + $result = $this->gline(); + } + return $array; + } + + /** gets a list of new articles + * @param $_since INTEGER unix timestamp + * @parma $_groups STRING pattern of intersting groups + * @return ARRAY MSGID of new articles + */ + + function newnews($_since,$_groups="*",$_distributions="") { + $distributions = preg_replace("/(\r|\n)/","",$_distributions); + $groups = preg_replace("/(\r|\n)/","",$_groups); + #assume $since is a unix timestamp + $this->pline("NEWNEWS $_groups ".gmdate("ymd His",$_since) + ." GMT $distributions\r\n"); + if (substr($this->gline(),0,1)!="2") return false; + $result = $this->gline(); + while ($result != ".") { + $array[] = $result; + $result = $this->gline(); + } + return $array; + } + + /** Tell the remote server that I am not a user client, but probably another news server + * @return BOOLEAN true if sucessful + */ + + function slave() { + $this->pline("SLAVE \r\n"); + return (substr($this->gline(),0,1)=="2"); + } + + /** implements IHAVE method + * @param $_msgid STRING MSGID of article + * @param $_message STRING article + * @return BOOLEAN + */ + + function ihave($_msgid,$_message=false) { + $msgid = preg_replace("/(\r|\n)/","",$_msgid); + if (is_array($message)) + $message=join("\n",$_message); + else + $message=$_message; + $this->pline("IHAVE $msgid \r\n"); + $result=$this->gline(); + if ($message && (substr($result,0,1)=="3")) { + $this->pline("$message\r\n.\r\n"); + $result=$this->gline(); + } + return (substr($result,0,1)=="2"); + } + + /** closes connection to server + */ + + function quit() { + $this->pline("QUIT\r\n"); + $this->gline(); + fclose($this->ns); + } + +# NNTP Extensions [RFC 2980] + + /** Returns the date on the remote server + * @return INTEGER timestamp + */ + + function date() { + $this->pline("DATE \r\n"); + $result = $this->gline(); + if (preg_match("/^111 (\d{4})(\d{2})(\d{2})" + ."(\d{2})(\d{2})(\d{2})$/",$result,$r)) { + return gmmktime($r[4],$r[5],$r[6],$r[2],$r[3],$r[1]); + } + return false; + } + + /** returns group descriptions + * @param $_pattern STRING pattern of intersting groups + * @return ARRAY group name => description + */ + + function xgtitle($_pattern="*") { + $pattern = preg_replace("/(\r|\n)/","",$_pattern); + $this->pline("XGTITLE $pattern \r\n"); + if (substr($this->gline(),0,1)!="2") return false; + $result = $this->gline(); + while ($result != ".") { + preg_match("/([^ \t]+)( |\t)+(.+)$/",$result,$regs); + $array[$regs[1]]=$regs[3]; + $result = $this->gline(); + } + return $array; + } + + /** obtain the header field $hdr for all the messages specified + * @param $_hdr STRING name of the header (eg: 'From') + * @param $_range STRING range of articles + * @return ARRAY MSGNUM => header value + */ + + function xhdr($_hdr,$_range="") { + $hdr = preg_replace("/(\r|\n)/","",$_hdr); + $range = preg_replace("/(\r|\n)/","",$_range); + $this->pline("XHDR $hdr $range \r\n"); + if (substr($this->gline(),0,1)!="2") return false; + $result = $this->gline(); + while ($result != ".") { + preg_match("/([^ \t]+) (.*)$/",$result,$regs); + $array[$regs[1]]=$regs[2]; + $result = $this->gline(); + } + return $array; + } + +} + +?> -- 2.1.4