* implements some basic functions for NNTP protocol
*/
class nntp {
- /** socket filehandle */
- var $ns;
- /** debug mode */
- var $debug;
- /** posting allowed */
- var $posting;
- /** last NNTP error code */
- var $lasterrorcode;
- /** last NNTP error text */
- var $lasterrortext;
+ /** socket filehandle */
+ var $ns;
+ /** debug mode */
+ var $debug;
+ /** posting allowed */
+ var $posting;
+ /** last NNTP error code */
+ var $lasterrorcode;
+ /** last NNTP error text */
+ var $lasterrortext;
# Socket functions
- /** get a line from server
- * @return STRING
- */
+ /** get a line from server
+ * @return STRING
+ */
- function gline() {
- $line = preg_replace("/(\r|\n)/","",fgets($this->ns,1200));
- if ($this->debug) {
- print "NNTP >>>> $line \n";
+ function gline() {
+ $line = preg_replace("/(\r|\n)/", "", fgets($this->ns, 1200));
+ if ($this->debug) {
+ print "NNTP >>>> $line \n";
+ }
+ return $line;
}
- 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 <br />\n";
- }
- $this = false;
- return false;
+
+ /** 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));
}
- $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");
+
+ /** 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 <br />\n";
+ }
+ $this = false;
+ return false;
+ }
+ $result = $this->gline();
+ $this->posting = (substr($result, 0, 3)=="200");
+ if ($_reader && ($result{0}=="2")) {
+ $this->pline("MODE READER\r\n");
+ $result = $this->gline();
+ $this->posting = ($result{0}=="200");
+ }
+ return ($result{0}=="2");
}
- 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 {
+ /** 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 ($result{0}!="2") {
+ $this->lasterrorcode = substr($result, 0, 3);
+ $this->lasterrortext = substr($result, 4);
+ return false;
+ }
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();
+
+ /** 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 ($result{0} != '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;
}
- 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;
+
+ /** 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 ($result{0} != '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 ($result{0} != '2') {
+ $this->lasterrorcode = substr($result, 0, 3);
+ $this->lasterrortext = substr($result, 4);
+ return false;
+ }
+ if ($result{0} == '2') {
+ if (preg_match("/(<[^@>]+@[^@>]+>)/", $result, $regs)) {
+ return $regs[0];
+ } else {
+ return true;
+ }
+ }
+ return false;
}
- $result = $this->gline();
- while ($result != ".") {
- $array[] = $result;
- $result = $this->gline();
+
+ /** 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 ($result{0} != '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;
}
- 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($line,0,3);
- $this->lasterrortext = substr($line,4);
- return false;
+
+ /** 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 ($result{0}!="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;
}
- if (preg_match("/^2\d{2} (\d+) (\d+) (\d+) ([^ ]+)/",
- $line,$regs)) {
- return array($regs[1],$regs[2],$regs[3],$regs[4]);
+
+ /** 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 ($line{0}!="2") {
+ $this->lasterrorcode = substr($line, 0, 3);
+ $this->lasterrortext = substr($line, 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;
}
- 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;
+
+ /** 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 ($line{0}!="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;
}
- if (preg_match("/^2\d{2} \d+ <([^>]+)>/",$line,$regs)) {
- return "<{$regs[1]}>";
+
+ /** 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 ($line{0}!="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;
}
- 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;
+
+ /** 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 ($line{0}!="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;
}
- if (preg_match("/^2\d{2} \d+ <([^>]+)>/",$line,$regs)) {
- return "<{$regs[1]}>";
+
+ /** returns true if posting is allowed
+ * @return BOOLEAN true if posting is allowed lines
+ */
+
+ function postok() {
+ return ($this->posting);
}
- 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;
+
+ /** 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;
}
- if (preg_match("/^2\d{2} \d+ <([^>]+)>/",$line,$regs)) {
- return "<{$regs[1]}>";
+
+ /** 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();
+ $array = array();
+ 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;
}
- 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();
+
+ /** 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);
+ $array = array();
+#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;
}
- 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();
- $array=array();
- while ($result != ".") {
- preg_match("/([^ ]+) (\d+) (\d+) (.)/",$result,$regs);
- $array[$regs[1]]=array(intval($regs[2]),intval($regs[3]),
- intval($regs[4]));
- $result = $this->gline();
+
+ /** 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");
}
- 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);
- $array=array();
- #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();
+
+ /** 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 && ($result{0}=="3")) {
+ $this->pline("$message\r\n.\r\n");
+ $result = $this->gline();
+ }
+ return ($result{0}=="2");
}
- 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();
+
+ /** closes connection to server
+ */
+
+ function quit() {
+ $this->pline("QUIT\r\n");
+ $this->gline();
+ fclose($this->ns);
}
- 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]);
+ /** 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;
}
- 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();
+
+ /** 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;
}
- 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();
- $array=array();
- while ($result != ".") {
- preg_match("/([^ \t]+) (.*)$/",$result,$regs);
- $array[$regs[1]]=$regs[2];
- $result = $this->gline();
+
+ /** 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();
+ $array = array();
+ while ($result != ".") {
+ preg_match("/([^ \t]+) (.*)$/", $result, $regs);
+ $array[$regs[1]] = $regs[2];
+ $result = $this->gline();
+ }
+ return $array;
}
- return $array;
- }
-
- /** obtain the header field $_hdr matching $_pat for all the messages specified
- * @param $_hdr STRING name of the header (eg: 'From')
- * @param $_range STRING range of articles
- * @param $_pat STRING pattern
- * @return ARRAY MSGNUM => header value
- */
-
- function xpat($_hdr,$_range,$_pat) {
- $hdr = preg_replace("/(\r|\n)/","",$_hdr);
- $range = preg_replace("/(\r|\n)/","",$_range);
- $pat = preg_replace("/(\r|\n)/","",$_pat);
- $this->pline("XPAT $hdr $range $pat\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();
+
+ /** obtain the header field $_hdr matching $_pat for all the messages specified
+ * @param $_hdr STRING name of the header (eg: 'From')
+ * @param $_range STRING range of articles
+ * @param $_pat STRING pattern
+ * @return ARRAY MSGNUM => header value
+ */
+
+ function xpat($_hdr, $_range, $_pat) {
+ $hdr = preg_replace("/(\r|\n)/", "", $_hdr);
+ $range = preg_replace("/(\r|\n)/", "", $_range);
+ $pat = preg_replace("/(\r|\n)/", "", $_pat);
+ $this->pline("XPAT $hdr $range $pat\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;
}
- return $array;
- }
}
?>
*/
function headerDecode($_value) {
- if (eregi('=\?.*\?.\?.*\?=',$_value)) { // is there anything encoded ?
- if (eregi('=\?(.*)\?Q\?.*\?=',$_value,$charset)) { // quoted-printable decoding
- $result1=eregi_replace('(.*)=\?.*\?Q\?(.*)\?=(.*)','\1',$_value);
- $result2=eregi_replace('(.*)=\?.*\?Q\?(.*)\?=(.*)','\2',$_value);
- $result3=eregi_replace('(.*)=\?.*\?Q\?(.*)\?=(.*)','\3',$_value);
- $result2=str_replace("_"," ",quoted_printable_decode($result2));
- if ($charset[1] == "UTF-8")
- $result2 = utf8_decode($result2);
- $newvalue=$result1.$result2.$result3;
+ if (eregi('=\?.*\?.\?.*\?=',$_value)) { // is there anything encoded ?
+ if (eregi('=\?(.*)\?Q\?.*\?=',$_value,$charset)) { // quoted-printable decoding
+ $result1 = eregi_replace('(.*)=\?.*\?Q\?(.*)\?=(.*)','\1',$_value);
+ $result2 = eregi_replace('(.*)=\?.*\?Q\?(.*)\?=(.*)','\2',$_value);
+ $result3 = eregi_replace('(.*)=\?.*\?Q\?(.*)\?=(.*)','\3',$_value);
+ $result2 = str_replace("_"," ",quoted_printable_decode($result2));
+ if ($charset[1] == "UTF-8") {
+ $result2 = utf8_decode($result2);
+ }
+ $newvalue = $result1.$result2.$result3;
+ }
+ if (eregi('=\?(.*)\?B\?.*\?=',$_value,$charset)) { // base64 decoding
+ $result1 = eregi_replace('(.*)=\?.*\?B\?(.*)\?=(.*)','\1',$_value);
+ $result2 = eregi_replace('(.*)=\?.*\?B\?(.*)\?=(.*)','\2',$_value);
+ $result3 = eregi_replace('(.*)=\?.*\?B\?(.*)\?=(.*)','\3',$_value);
+ $result2 = base64_decode($result2);
+ if ($charset[1] == "UTF-8") {
+ $result2 = utf8_decode($result2);
+ }
+ $newvalue = $result1.$result2.$result3;
+ }
+ if (!isset($newvalue)) { // nothing of the above, must be an unknown encoding...
+ $newvalue = $_value;
+ } else {
+ $newvalue=headerDecode($newvalue); // maybe there are more encoded
+ }
+ return($newvalue); // parts
+ } else { // there wasn't anything encoded, return the original string
+ return($_value);
}
- if (eregi('=\?(.*)\?B\?.*\?=',$_value,$charset)) { // base64 decoding
- $result1=eregi_replace('(.*)=\?.*\?B\?(.*)\?=(.*)','\1',$_value);
- $result2=eregi_replace('(.*)=\?.*\?B\?(.*)\?=(.*)','\2',$_value);
- $result3=eregi_replace('(.*)=\?.*\?B\?(.*)\?=(.*)','\3',$_value);
- $result2=base64_decode($result2);
- if ($charset[1] == "UTF-8")
- $result2 = utf8_decode($result2);
- $newvalue=$result1.$result2.$result3;
- }
- if (!isset($newvalue)) // nothing of the above, must be an unknown encoding...
- $newvalue=$_value;
- else
- $newvalue=headerDecode($newvalue); // maybe there are more encoded
- return($newvalue); // parts
- } else { // there wasn't anything encoded, return the original string
- return($_value);
- }
}
?>
*/
class NNTPPost {
- /** headers */
- var $headers;
- /** body */
- var $body;
+ /** headers */
+ var $headers;
+ /** body */
+ var $body;
- /** constructor
- * @param $_nntp RESOURCE handle to NNTP socket
- * @param $_id STRING MSGNUM or MSGID (a group should be selected in this case)
- */
- function NNTPPost(&$_nntp,$_id) {
- $this->headers = new headers($_nntp,$_id);
- if (!$this->headers) {
- $this = false;
- return false;
+ /** constructor
+ * @param $_nntp RESOURCE handle to NNTP socket
+ * @param $_id STRING MSGNUM or MSGID (a group should be selected in this case)
+ */
+ function NNTPPost(&$_nntp, $_id) {
+ $this->headers = new headers($_nntp, $_id);
+ if (!$this->headers) {
+ $this = null;
+ return false;
+ }
+ $this->body = join("\n", $_nntp->body($_id));
+ if (isset($this->headers->contentencoding) && preg_match("/base64/", $this->headers->contentencoding)) {
+ $this->body = base64_decode($this->body);
+ }
+ if (isset($this->headers->contentencoding) && preg_match("/quoted-printable/", $this->headers->contentencoding)) {
+ $this->body = quoted_printable_decode($this->body);
+ }
+ if (preg_match('!charset=([^;]*);!', $this->headers->contenttype, $matches)) {
+ $this->body = iconv($matches[1], 'iso-8859-1', $this->body);
+ }
}
- $this->body = join("\n",$_nntp->body($_id));
- if ((isset($this->headers->contentencoding)) &&
- (preg_match("/base64/",$this->headers->contentencoding))) {
- $this->body = base64_decode($this->body);
- }
- if ((isset($this->headers->contentencoding)) &&
- (preg_match("/quoted-printable/",$this->headers->contentencoding))) {
- $this->body = quoted_printable_decode($this->body);
- }
- if(preg_match('!charset=([^;]*);!', $this->headers->contenttype, $matches)) {
- $this->body = iconv($matches[1], 'iso-8859-1', $this->body);
- }
- }
}
/** class for headers
*/
class Headers {
- /** MSGNUM : *local* spool id */
- var $nb; // numéro du post
- /** MSGID : Message-ID */
- var $msgid; // Message-ID
- /** From header */
- var $from; // From
- /** Name (if present in From header) */
- var $name;
- /** Mail (in From header) */
- var $mail;
- /** Subject header */
- var $subject; // Subject
- /** Newsgroup¨ header */
- var $newsgroups; // Newsgroups
- /** Followup-To header */
- var $followup;
- /** Content-Type header */
- var $contenttype;
- /** Content-Transfer-Encoding header */
- var $contentencoding;
- /** Date header */
- var $date;
- /** Organization header */
- var $organization;
- /** References header */
- var $references;
+ /** MSGNUM : *local* spool id */
+ var $nb; // numéro du post
+ /** MSGID : Message-ID */
+ var $msgid; // Message-ID
+ /** From header */
+ var $from; // From
+ /** Name (if present in From header) */
+ var $name;
+ /** Mail (in From header) */
+ var $mail;
+ /** Subject header */
+ var $subject; // Subject
+ /** Newsgroup¨ header */
+ var $newsgroups; // Newsgroups
+ /** Followup-To header */
+ var $followup;
+ /** Content-Type header */
+ var $contenttype;
+ /** Content-Transfer-Encoding header */
+ var $contentencoding;
+ /** Date header */
+ var $date;
+ /** Organization header */
+ var $organization;
+ /** References header */
+ var $references;
- /** constructor
- * @param $_nntp RESOURCE handle to NNTP socket
- * @param $_id STRING MSGNUM or MSGID
- */
-
- function headers(&$_nntp,$_id) {
- global $news;
- $hdrs = $_nntp->head($_id);
- if (!$hdrs) {
- $this = false;
- return false;
- }
- // parse headers
- foreach ($hdrs as $line) {
- if (preg_match("/^[\t\r ]+/",$line)) {
- $line = ($lasthdr=="X-Face"?"":" ").ltrim($line);
- if (in_array($lasthdr,array_keys($news['head'])))
- $this->{$news['head'][$lasthdr]} .= $line;
- } else {
- list($hdr,$val) = split(":[ \t\r]*",$line,2);
- if (in_array($hdr,array_keys($news['head'])))
- $this->{$news['head'][$hdr]} = $val;
- $lasthdr = $hdr;
- }
- }
- // decode headers
- foreach ($news['hdecode'] as $hdr) {
- if (isset($this->$hdr)) {
- $this->$hdr = headerDecode($this->$hdr);
- }
- }
- // sets name and mail
- $this->name = $this->from;
- $this->mail = $this->from;
- if (preg_match("/(.*)<(.*)@(.*)>/",$val,$match)) {
- $this->name = str_replace("\"","",trim($match[1]));
- $this->mail = $match[2]."@".$match[3];
- }
- if (preg_match("/([\w\.]+)@([\w\.]+) \((.*)\)/",$val,$match)) {
- $this->name = trim($match[3]);
- $this->mail = $match[1]."@".$match[2];
+ /** constructor
+ * @param $_nntp RESOURCE handle to NNTP socket
+ * @param $_id STRING MSGNUM or MSGID
+ */
+
+ function headers(&$_nntp, $_id) {
+ global $news;
+ $hdrs = $_nntp->head($_id);
+ if (!$hdrs) {
+ $this = null;
+ return false;
+ }
+ // parse headers
+ foreach ($hdrs as $line) {
+ if (preg_match("/^[\t\r ]+/", $line)) {
+ $line = ($lasthdr=="X-Face"?"":" ").ltrim($line);
+ if (in_array($lasthdr, array_keys($news['head']))) {
+ $this->{$news['head'][$lasthdr]} .= $line;
+ }
+ } else {
+ list($hdr, $val) = split(":[ \t\r]*", $line, 2);
+ if (in_array($hdr, array_keys($news['head']))) {
+ $this->{$news['head'][$hdr]} = $val;
+ }
+ $lasthdr = $hdr;
+ }
+ }
+ // decode headers
+ foreach ($news['hdecode'] as $hdr) {
+ if (isset($this->$hdr)) {
+ $this->$hdr = headerDecode($this->$hdr);
+ }
+ }
+ // sets name and mail
+ $this->name = $this->from;
+ $this->mail = $this->from;
+ if (preg_match("/(.*)<(.*)@(.*)>/", $val, $match)) {
+ $this->name = str_replace("\"", "", trim($match[1]));
+ $this->mail = $match[2]."@".$match[3];
+ }
+ if (preg_match("/([\w\.]+)@([\w\.]+) \((.*)\)/", $val, $match)) {
+ $this->name = trim($match[3]);
+ $this->mail = $match[1]."@".$match[2];
+ }
+ $this->nb = $_id;
+ $retour->numerr = 0;
}
- $this->nb=$_id;
- $retour->numerr=0;
- }
}
?>
/** Class spoolhead
* class used in thread overviews
*/
-class spoolhead {
- /** date (timestamp) */
- var $date;
- /** subject */
- var $subject;
- /** author */
- var $from;
- /** reference of parent */
- var $parent;
- /** paren is direct */
- var $direct_parent;
- /** array of children */
- var $children;
- /** true if post is read */
- var $isread;
- /** number of posts deeper in this branch of tree */
- var $desc;
- /** same as desc, but counts only unread posts */
- var $descunread;
+class SpoolHead
+{
+ /** date (timestamp) */
+ var $date;
+ /** subject */
+ var $subject;
+ /** author */
+ var $from;
+ /** reference of parent */
+ var $parent;
+ /** paren is direct */
+ var $direct_parent;
+ /** array of children */
+ var $children = Array();
+ /** true if post is read */
+ var $isread;
+ /** number of posts deeper in this branch of tree */
+ var $desc;
+ /** same as desc, but counts only unread posts */
+ var $descunread;
- /** constructor
- * @param $_date INTEGER timestamp of post
- * @param $_subject STRING subject of post
- * @param $_from STRING author of post
- * @param $_desc INTEGER desc value (1 for a new post)
- * @param $_read BOOLEAN true if read
- * @param $_descunread INTEGER descunread value (0 for a new post)
- */
+ /** constructor
+ * @param $_date INTEGER timestamp of post
+ * @param $_subject STRING subject of post
+ * @param $_from STRING author of post
+ * @param $_desc INTEGER desc value (1 for a new post)
+ * @param $_read BOOLEAN true if read
+ * @param $_descunread INTEGER descunread value (0 for a new post)
+ */
- function spoolhead($_date,$_subject,$_from,$_desc=1,$_read=true,$_descunread=0) {
- $this->date=$_date;
- $this->subject=$_subject;
- $this->from=$_from;
- $this->children=array();
- $this->desc=$_desc;
- $this->isread=$_read;
- $this->descunread=$_descunread;
- }
+ function SpoolHead($_date, $_subject, $_from, $_desc=1, $_read=true, $_descunread=0)
+ {
+ $this->date = $_date;
+ $this->subject = $_subject;
+ $this->from = $_from;
+ $this->desc = $_desc;
+ $this->isread = $_read;
+ $this->descunread = $_descunread;
+ }
}
/** Class spool
* builds and updates spool
*/
-class spool {
+class spool
+{
# var $date;
- /** spool */
- var $overview;
- /** group name */
- var $group;
- /** array msgid => msgnum */
- var $ids;
+ /** spool */
+ var $overview;
+ /** group name */
+ var $group;
+ /** array msgid => msgnum */
+ var $ids;
- /** constructor
- * @param $_nntp RESOURCE NNTP socket filehandle
- * @param $_group STRING group name
- * @param $_display INTEGER 1 => all posts, 2 => only threads with new posts
- * @param $_since INTEGER time stamp (used for read/unread)
- */
-
- function spool(&$_nntp,$_group,$_display=0,$_since=""){
- global $news;
- $prefix_path=(preg_match("/\/scripts\/?$/",getcwd())?"..":".");
- $groupinfo = $_nntp->group($_group);
- if (!$groupinfo) {
- $this = false;
- return false;
- }
- $spoolfile=realpath("$prefix_path/spool/spool-$_group.dat");
- if (file_exists($spoolfile)) {
- $f = fopen($spoolfile,"r");
- $this = unserialize(fread($f,filesize($spoolfile)));
- fclose($f);
- $keys = array_values($this->ids);
- rsort($keys);
- $first = max($groupinfo[2]-$news['maxspool'],$groupinfo[1]);
- $last = $groupinfo[2];
- // remove expired messages
- $msgids=array_flip($this->ids);
- for ($id=min(array_keys($this->overview)); $id<$first; $id++) {
- $this->delid($id);
- }
- $this->ids=array_flip($msgids);
- $first=max(array_keys($this->overview))+1;
- } else {
- $first = max($groupinfo[2]-$news['maxspool'],$groupinfo[1]);
- $last = $groupinfo[2];
- $this->group = $_group;
- }
-
- if (($first<=$groupinfo[2]) && ($groupinfo[0]!=0)) {
- $dates = array_map("strtotime",
- $_nntp->xhdr("Date","$first-$last"));
- $msgids=$_nntp->xhdr("Message-ID","$first-$last");
- $subjects = array_map("headerdecode",$_nntp->xhdr("Subject",
- "$first-$last"));
- $froms = array_map("headerdecode",$_nntp->xhdr("From",
- "$first-$last"));
- $refs = $_nntp->xhdr("References","$first-$last");
-# $this->date=$nntp->date;
- if (isset($this->ids)) {
- $this->ids=array_merge($this->ids,array_flip($msgids));
- } else {
- $this->ids=array_flip($msgids);
- }
+ /** constructor
+ * @param $_nntp RESOURCE NNTP socket filehandle
+ * @param $_group STRING group name
+ * @param $_display INTEGER 1 => all posts, 2 => only threads with new posts
+ * @param $_since INTEGER time stamp (used for read/unread)
+ */
- foreach ($msgids as $id=>$msgid) {
- if (isset($this->overview[$id])) {
- $msg = $this->overview[$id];
- $msg->desc++;
+ function spool(&$_nntp, $_group, $_display=0, $_since="")
+ {
+ global $news;
+ $spool_path = dirname(dirname(__FILE__)).'/spool';
+ $groupinfo = $_nntp->group($_group);
+ if (!$groupinfo) {
+ $this = null;
+ return false;
+ }
+ $spoolfile = realpath("$spool_path/spool-$_group.dat");
+ if (file_exists($spoolfile)) {
+ $this = unserialize(file_get_contents($spoolfile));
+ $keys = array_values($this->ids);
+ rsort($keys);
+ $first = max($groupinfo[2]-$news['maxspool'], $groupinfo[1]);
+ $last = $groupinfo[2];
+ // remove expired messages
+ $msgids = array_flip($this->ids);
+ for ($id=min(array_keys($this->overview)); $id<$first; $id++) {
+ $this->delid($id);
+ }
+ $this->ids = array_flip($msgids);
+ $first = max(array_keys($this->overview))+1;
} else {
- $msg = new spoolhead($dates[$id],$subjects[$id],$froms[$id],1);
+ $first = max($groupinfo[2]-$news['maxspool'], $groupinfo[1]);
+ $last = $groupinfo[2];
+ $this->group = $_group;
}
- $refs[$id]=str_replace("><","> <",$refs[$id]);
- $msgrefs=preg_split("/( |\t)/",strtr($refs[$id],$this->ids));
- $parents=preg_grep("/^\d+$/",$msgrefs);
- $msg->parent=array_pop($parents);
- $msg->parent_direct=preg_match("/^\d+$/",array_pop($msgrefs));
- $p = $msg->parent;
- while ($p) {
- if (isset($this->overview[$p])) {
- $this->overview[$p]->desc++;
- if (isset($this->overview[$p]->parent)) {
- $p = $this->overview[$p]->parent;
+
+ if (($first<=$groupinfo[2]) && ($groupinfo[0]!=0)) {
+ $dates = array_map("strtotime", $_nntp->xhdr("Date","$first-$last"));
+ $msgids = $_nntp->xhdr("Message-ID","$first-$last");
+ $subjects = array_map("headerdecode",$_nntp->xhdr("Subject", "$first-$last"));
+ $froms = array_map("headerdecode",$_nntp->xhdr("From", "$first-$last"));
+ $refs = $_nntp->xhdr("References","$first-$last");
+ #$this->date=$nntp->date;
+ if (isset($this->ids)) {
+ $this->ids = array_merge($this->ids, array_flip($msgids));
} else {
- $p = false;
+ $this->ids = array_flip($msgids);
}
- } else {
- $this->overview[$p] = new spoolhead($dates[$p],$subjects[$p],$froms[$p],1);
- $p = false;
- }
- }
- if ($msg->parent!="")
- $this->overview[$msg->parent]->children[]=$id;
- $this->overview[$id] = $msg;
- }
- uasort($this->overview,"spoolcompare");
- $f = fopen("$prefix_path/spool/spool-$_group.dat","w");
- fputs($f,serialize($this));
- fclose($f);
- }
-
- if ($_since != "") {
- $newpostsids = $_nntp->newnews($_since,$_group);
- if (sizeof($newpostsids)) {
- $newpostsids = array_intersect($newpostsids,
- array_keys($this->ids));
- if ($newpostsids && !is_null($newpostsids)) {
- foreach ($newpostsids as $mid) {
- $this->overview[$this->ids[$mid]]->isread=false;
- $this->overview[$this->ids[$mid]]->descunread=1;
- $parentmid=$this->ids[$mid];
- while (isset($parentmid)) {
- $this->overview[$parentmid]->descunread++;
- $parentmid = $this->overview[$parentmid]->parent;
+
+ foreach ($msgids as $id=>$msgid) {
+ if (isset($this->overview[$id])) {
+ $msg = $this->overview[$id];
+ $msg->desc++;
+ } else {
+ $msg = new spoolhead($dates[$id], $subjects[$id], $froms[$id], 1);
+ }
+ $refs[$id] = str_replace("><","> <", $refs[$id]);
+ $msgrefs = preg_split("/( |\t)/", strtr($refs[$id],$this->ids));
+ $parents = preg_grep("/^\d+$/", $msgrefs);
+ $msg->parent = array_pop($parents);
+ $msg->parent_direct = preg_match("/^\d+$/",array_pop($msgrefs));
+ $p = $msg->parent;
+ while ($p) {
+ if (isset($this->overview[$p])) {
+ $this->overview[$p]->desc++;
+ $p = isset($this->overview[$p]->parent) ? $this->overview[$p]->parent : false;
+ } else {
+ $this->overview[$p] = new spoolhead($dates[$p], $subjects[$p], $froms[$p], 1);
+ $p = false;
+ }
+ }
+ if ($msg->parent!="") {
+ $this->overview[$msg->parent]->children[] = $id;
+ }
+ $this->overview[$id] = $msg;
}
- }
+ uasort($this->overview, "spoolcompare");
+ file_put_contents("$spool_path/spool-$_group.dat", serialize($this));
}
- }
- if (sizeof($newpostsids)>0) {
- $flipids = array_flip($this->ids);
- switch ($_display) {
- case 1:
- foreach ($this->overview as $i=>$p) {
- if (isset($this->overview[$i]) &&
- !isset($this->overview[$i]->parent) &&
- ($this->overview[$i]->descunread==0)) {
- $this->killdesc($i);
- }
+
+ if ($_since) {
+ $newpostsids = $_nntp->newnews($_since,$_group);
+ if (sizeof($newpostsids)) {
+ $newpostsids = array_intersect($newpostsids, array_keys($this->ids));
+ if ($newpostsids && !is_null($newpostsids)) {
+ foreach ($newpostsids as $mid) {
+ $this->overview[$this->ids[$mid]]->isread = false;
+ $this->overview[$this->ids[$mid]]->descunread = 1;
+ $parentmid = $this->ids[$mid];
+ while (isset($parentmid)) {
+ $this->overview[$parentmid]->descunread++;
+ $parentmid = $this->overview[$parentmid]->parent;
+ }
+ }
+ }
}
- break;
- case 2:
- foreach ($this->overview as $i=>$p) {
- if ($p->isread) {
- unset($this->overview[$i]);
- unset($flipids[$i]);
- }
+ if (sizeof($newpostsids)>0) {
+ $flipids = array_flip($this->ids);
+ switch ($_display) {
+ case 1:
+ foreach ($this->overview as $i=>$p) {
+ if (isset($this->overview[$i]) &&
+ !isset($this->overview[$i]->parent) &&
+ ($this->overview[$i]->descunread==0))
+ {
+ $this->killdesc($i);
+ }
+ }
+ break;
+
+ case 2:
+ foreach ($this->overview as $i=>$p) {
+ if ($p->isread) {
+ unset($this->overview[$i]);
+ unset($flipids[$i]);
+ }
+ }
+ $this->ids = array_flip($flipids);
+ break;
+ }
}
- $this->ids=array_flip($flipids);
- break;
}
- }
+ return true;
}
- return true;
- }
- /** kill post and childrens
- * @param $_id MSGNUM of post
- */
+ /** kill post and childrens
+ * @param $_id MSGNUM of post
+ */
- function killdesc($_id) {
- if (sizeof($this->overview[$_id]->children)) {
- foreach ($this->overview[$_id]->children as $c) {
- $this->killdesc($c);
- }
+ function killdesc($_id)
+ {
+ if (sizeof($this->overview[$_id]->children)) {
+ foreach ($this->overview[$_id]->children as $c) {
+ $this->killdesc($c);
+ }
+ }
+ unset($this->overview[$_id]);
+ $msgid = array_search($_id, $this->ids);
+ if ($msgids) {
+ unset($this->ids[$msgid]);
+ }
}
- unset($this->overview[$_id]);
- $msgid=array_search($_id,$this->ids);
- if ($msgids) {
- unset($this->ids[$msgid]);
+
+ /** delete a post from overview
+ * @param $_id MSGNUM of post
+ */
+
+ function delid($_id)
+ {
+ if (isset($this->overview[$_id])) {
+ if (sizeof($this->overview[$_id]->parent)) {
+ $this->overview[$this->overview[$_id]->parent]->children =
+ array_diff($this->overview[$this->overview[$_id]->parent]->children, array($_id));
+ if (sizeof($this->overview[$_id]->children)) {
+ $this->overview[$this->overview[$_id]->parent]->children =
+ array_merge($this->overview[$this->overview[$_id]->parent]->children, $this->overview[$_id]->children);
+ foreach ($this->overview[$_id]->children as $c) {
+ $this->overview[$c]->parent = $this->overview[$_id]->parent;
+ $this->overview[$c]->parent_direct = false;
+ }
+ }
+ $p = $this->overview[$_id]->parent;
+ while ($p) {
+ $this->overview[$p]->desc--;
+ $p = $this->overview[$p]->parent;
+ }
+ } elseif (sizeof($this->overview[$_id]->children)) {
+ foreach ($this->overview[$_id]->children as $c) {
+ $this->overview[$c]->parent = null;
+ }
+ }
+ unset($this->overview[$_id]);
+ $msgid = array_search($_id,$this->ids);
+ if ($msgid) {
+ unset($this->ids[$msgid]);
+ }
+
+ $spool_path = dirname(dirname(__FILE__)).'/spool';
+ file_put_contents("$spool_path/spool-$_group.dat", serialize($this));
+ }
}
-# $flipid=array_flip($this->ids);
-# unset($flipid[$id]);
-# $this->ids=array_flip($flipid);
- }
- /** delete a post from overview
- * @param $_id MSGNUM of post
- */
+ /** displays children tree of a post
+ * @param $_id INTEGER MSGNUM of post
+ * @param $_index INTEGER linear number of post in the tree
+ * @param $_first INTEGER linear number of first post displayed
+ * @param $_last INTEGER linear number of last post displayed
+ * @param $_ref STRING MSGNUM of current post
+ * @param $_pfx_node STRING prefix used for current node
+ * @param $_pfx_end STRING prefix used for children of current node
+ * @param $_head BOOLEAN true if first post in thread
+ */
- function delid($_id) {
- if (isset($this->overview[$_id])) {
- if (sizeof($this->overview[$_id]->parent)) {
- $this->overview[$this->overview[$_id]->parent]->children =
- array_diff($this->overview[$this->overview[$_id]->parent]->children,
- array($_id));
- if (sizeof($this->overview[$_id]->children)) {
- $this->overview[$this->overview[$_id]->parent]->children =
- array_merge($this->overview[$this->overview[$_id]->parent]->children,
- $this->overview[$_id]->children);
- foreach ($this->overview[$_id]->children as $c) {
- $this->overview[$c]->parent = $this->overview[$_id]->parent;
- $this->overview[$c]->parent_direct = false;
- }
+ function disp_desc($_id,$_index="",$_first=0,$_last=0,$_ref="", $_pfx_node="", $_pfx_end="",$_head=true) {
+ global $css;
+ $debug = false;
+ $spfx_f = '<img src="img/k1.gif" height="21" width="9" alt="o" />';
+ $spfx_n = '<img src="img/k2.gif" height="21" width="9" alt="*" />';
+ $spfx_Tnd = '<img src="img/T-direct.gif" height="21" width="12" alt="+" />';
+ $spfx_Lnd = '<img src="img/L-direct.gif" height="21" width="12" alt="`" />';
+ $spfx_snd = '<img src="img/s-direct.gif" height="21" width="5" alt="-" />';
+ $spfx_T = '<img src="img/T.gif" height="21" width="12" alt="+" />';
+ $spfx_L = '<img src="img/L.gif" height="21" width="12" alt="`" />';
+ $spfx_s = '<img src="img/s.gif" height="21" width="5" alt="-" />';
+ $spfx_e = '<img src="img/e.gif" height="21" width="12" alt=" " />';
+ $spfx_I = '<img src="img/I.gif" height="21" width="12"alt="|" />';
+
+ if ($_index == "") {
+ $_index = $this->getndx($_id);
}
- $p = $this->overview[$_id]->parent;
- while ($p) {
- $this->overview[$p]->desc--;
- $p = $this->overview[$p]->parent;
+
+ if (!sizeof($this->overview[$_id]->children) && ($_index<=$_last) && ($_index>=$_first)) {
+ echo '<tr class="'.($_index%2?$css["pair"]:$css["impair"])."\">\n";
+ echo "<td class=\"{$css['date']}\">"
+ .formatSpoolHeader("date",$this->overview[$_id]->date,$_id,
+ $this->group,($_index==$_ref),$this->overview[$_id]->isread)
+ ." </td>\n";
+ echo "<td class=\"{$css['subject']}\"><div class=\"{$css['tree']}\">"
+ .$_pfx_node.($_head?$spfx_f:
+ ($this->overview[$_id]->parent_direct?$spfx_s:$spfx_snd))
+ ."</div>"
+ .formatSpoolHeader("subject",$this->overview[$_id]->subject,$_id,
+ $this->group,($_index==$_ref),$this->overview[$_id]->isread)
+ .($debug?" $_id $_index ".
+ $this->overview[$_id]->desc." ".$this->overview[$_id]->descunread." ":"")." </td>\n";
+ echo "<td class=\"{$css['author']}\">"
+ .formatSpoolHeader("from",$this->overview[$_id]->from,$_id,
+ $this->group,($_index==$_ref),$this->overview[$_id]->isread)
+ ." </td>\n</tr>";
+ return true;
+ }
+ $children = $this->overview[$_id]->children;
+ if (($_index<=$_last) && ($_index>=$_first)) {
+ echo '<tr class="'.($_index%2?$css["pair"]:$css["impair"])."\">\n";
+ echo "<td class=\"{$css['date']}\">"
+ .formatSpoolHeader("date",$this->overview[$_id]->date,$_id,
+ $this->group,($_index==$_ref),$this->overview[$_id]->isread)
+ ." </td>\n";
+ echo "<td class=\"{$css['subject']}\"><div class=\"{$css['tree']}\">"
+ .$_pfx_node.$spfx_n."</div>"
+ .formatSpoolHeader("subject",$this->overview[$_id]->subject,$_id,
+ $this->group,($_index==$_ref),$this->overview[$_id]->isread)
+ .($debug?" $_id $_index ".
+ $this->overview[$_id]->desc." ".$this->overview[$_id]->descunread." ":"")." </td>\n";
+ echo "<td class=\"{$css['author']}\">"
+ .formatSpoolHeader("from",$this->overview[$_id]->from,$_id,
+ $this->group,($_index==$_ref),$this->overview[$_id]->isread)
+ ." </td>\n</tr>";
}
- } elseif (sizeof($this->overview[$_id]->children)) {
- foreach ($this->overview[$_id]->children as $c) {
- $this->overview[$c]->parent = null;
+ $index=$_index+1;
+ while ($child = array_shift($children)) {
+ if (($index+$this->overview[$child]->desc-1>=$_first)
+ ||($index<$_last)){
+ if (sizeof($children)) {
+ $this->disp_desc($child,$index,$_first,$_last,$_ref,$_pfx_end.
+ ($this->overview[$child]->parent_direct?$spfx_T:$spfx_Tnd),
+ $_pfx_end.$spfx_I,false);
+ } else {
+ $this->disp_desc($child,$index,$_first,$_last,$_ref,$_pfx_end.
+ ($this->overview[$child]->parent_direct?$spfx_L:$spfx_Lnd),
+ $_pfx_end.$spfx_e,false);
+ }
+ }
+ $index += $this->overview[$child]->desc;
}
- }
- unset($this->overview[$_id]);
- $msgid=array_search($_id,$this->ids);
- if ($msgid) {
- unset($this->ids[$msgid]);
- }
-# $ids = array_flip($this->ids);
-# unset($ids[$_id]);
-# $this->ids = array_flip($ids);
- $prefix_path=(preg_match("/\/scripts\/?$/",getcwd())?"..":".");
- $f = fopen("$prefix_path/spool/spool-{$this->group}.dat","w");
- fputs($f,serialize($this));
- fclose($f);
}
- }
- /** displays children tree of a post
- * @param $_id INTEGER MSGNUM of post
- * @param $_index INTEGER linear number of post in the tree
- * @param $_first INTEGER linear number of first post displayed
- * @param $_last INTEGER linear number of last post displayed
- * @param $_ref STRING MSGNUM of current post
- * @param $_pfx_node STRING prefix used for current node
- * @param $_pfx_end STRING prefix used for children of current node
- * @param $_head BOOLEAN true if first post in thread
- */
+ /** Displays overview
+ * @param $_first INTEGER MSGNUM of first post
+ * @param $_last INTEGER MSGNUM of last post
+ * @param $_ref STRING MSGNUM of current/selectionned post
+ */
- function disp_desc($_id,$_index="",$_first=0,$_last=0,$_ref="",
- $_pfx_node="", $_pfx_end="",$_head=true) {
- global $css;
- $debug = false;
- $spfx_f = '<img src="img/k1.gif" height="21" width="9" alt="o" />';
- $spfx_n = '<img src="img/k2.gif" height="21" width="9" alt="*" />';
- $spfx_Tnd = '<img src="img/T-direct.gif" height="21" width="12" alt="+" />';
- $spfx_Lnd = '<img src="img/L-direct.gif" height="21" width="12" alt="`" />';
- $spfx_snd = '<img src="img/s-direct.gif" height="21" width="5" alt="-" />';
- $spfx_T = '<img src="img/T.gif" height="21" width="12" alt="+" />';
- $spfx_L = '<img src="img/L.gif" height="21" width="12" alt="`" />';
- $spfx_s = '<img src="img/s.gif" height="21" width="5" alt="-" />';
- $spfx_e = '<img src="img/e.gif" height="21" width="12" alt=" " />';
- $spfx_I = '<img src="img/I.gif" height="21" width="12"alt="|" />';
-
- if ($_index == "") $_index = $this->getndx($_id);
-
- if (!sizeof($this->overview[$_id]->children) && ($_index<=$_last)
- && ($_index>=$_first)) {
- echo '<tr class="'.($_index%2?$css["pair"]:$css["impair"])."\">\n";
- echo "<td class=\"{$css['date']}\">"
- .formatSpoolHeader("date",$this->overview[$_id]->date,$_id,
- $this->group,($_index==$_ref),$this->overview[$_id]->isread)
- ." </td>\n";
- echo "<td class=\"{$css['subject']}\"><div class=\"{$css['tree']}\">"
- .$_pfx_node.($_head?$spfx_f:
- ($this->overview[$_id]->parent_direct?$spfx_s:$spfx_snd))
- ."</div>"
- .formatSpoolHeader("subject",$this->overview[$_id]->subject,$_id,
- $this->group,($_index==$_ref),$this->overview[$_id]->isread)
- .($debug?" $_id $_index ".
- $this->overview[$_id]->desc." ".$this->overview[$_id]->descunread." ":"")." </td>\n";
- echo "<td class=\"{$css['author']}\">"
- .formatSpoolHeader("from",$this->overview[$_id]->from,$_id,
- $this->group,($_index==$_ref),$this->overview[$_id]->isread)
- ." </td>\n</tr>";
- return true;
- }
- $children = $this->overview[$_id]->children;
- if (($_index<=$_last) && ($_index>=$_first)) {
- echo '<tr class="'.($_index%2?$css["pair"]:$css["impair"])."\">\n";
- echo "<td class=\"{$css['date']}\">"
- .formatSpoolHeader("date",$this->overview[$_id]->date,$_id,
- $this->group,($_index==$_ref),$this->overview[$_id]->isread)
- ." </td>\n";
- echo "<td class=\"{$css['subject']}\"><div class=\"{$css['tree']}\">"
- .$_pfx_node.$spfx_n."</div>"
- .formatSpoolHeader("subject",$this->overview[$_id]->subject,$_id,
- $this->group,($_index==$_ref),$this->overview[$_id]->isread)
- .($debug?" $_id $_index ".
- $this->overview[$_id]->desc." ".$this->overview[$_id]->descunread." ":"")." </td>\n";
- echo "<td class=\"{$css['author']}\">"
- .formatSpoolHeader("from",$this->overview[$_id]->from,$_id,
- $this->group,($_index==$_ref),$this->overview[$_id]->isread)
- ." </td>\n</tr>";
- }
- $index=$_index+1;
- while ($child = array_shift($children)) {
- if (($index+$this->overview[$child]->desc-1>=$_first)
- ||($index<$_last)){
- if (sizeof($children)) {
- $this->disp_desc($child,$index,$_first,$_last,$_ref,$_pfx_end.
- ($this->overview[$child]->parent_direct?$spfx_T:$spfx_Tnd),
- $_pfx_end.$spfx_I,false);
+ function disp($_first=0,$_last=0,$_ref="") {
+ global $css;
+ $index = 1;
+ if (sizeof($this->overview)) {
+ foreach ($this->overview as $id=>$msg) {
+ if (!isset($msg->parent)) {
+ $this->disp_desc($id,$index,$_first,$_last,$_ref);
+ $index += $msg->desc;
+ }
+ }
} else {
- $this->disp_desc($child,$index,$_first,$_last,$_ref,$_pfx_end.
- ($this->overview[$child]->parent_direct?$spfx_L:$spfx_Lnd),
- $_pfx_end.$spfx_e,false);
+ echo "<tr class=\"{$css['pair']}\">\n";
+ echo "\t<td colspan=\"3\">\n";
+ echo "\t\tNo post in this newsgroup\n";
+ echo "\t</td>\n";
+ echo "</tr>\n";
}
- }
- $index += $this->overview[$child]->desc;
}
- }
- /** Displays overview
- * @param $_first INTEGER MSGNUM of first post
- * @param $_last INTEGER MSGNUM of last post
- * @param $_ref STRING MSGNUM of current/selectionned post
- */
+ /** computes linear post index
+ * @param $_id INTEGER MSGNUM of post
+ * @return INTEGER linear index of post
+ */
- function disp($_first=0,$_last=0,$_ref="") {
- global $css;
- $index=1;
- if (sizeof($this->overview)) {
- foreach ($this->overview as $id=>$msg) {
- if (!isset($msg->parent)) {
- $this->disp_desc($id,$index,$_first,$_last,$_ref);
- $index += $msg->desc;
+ function getndx($_id) {
+ $ndx = 1;
+ // on remonte l'arbre
+ $id_parent = $this->overview[$_id]->parent;
+ $id_curr = $_id;
+ while (!is_null($id_parent)) {
+ for ($i=0; $i<array_search($id_curr, $this->overview[$id_parent]->children) ; $i++) {
+ $ndx += $this->overview[$this->overview[$id_parent]->children[$i]]->desc;
+ }
+ $ndx++; //noeud père
+ $id_curr = $id_parent;
+ $id_parent = $this->overview[$id_curr]->parent;
}
- }
- } else {
- echo "<tr class=\"{$css['pair']}\">\n";
- echo "\t<td colspan=\"3\">\n";
- echo "\t\tNo post in this newsgroup\n";
- echo "\t</td>\n";
- echo "</tr>\n";
- }
- }
-
- /** computes linear post index
- * @param $_id INTEGER MSGNUM of post
- * @return INTEGER linear index of post
- */
-
- function getndx($_id) {
- $ndx = 1;
- // on remonte l'arbre
- $id_parent = $this->overview[$_id]->parent;
- $id_curr = $_id;
- while (!is_null($id_parent)) {
- for ($i=0; $i<array_search($id_curr,
- $this->overview[$id_parent]->children) ; $i++) {
- $ndx += $this->overview[$this->overview[$id_parent]->children[$i]]->desc;
- }
- $ndx++; //noeud père
- $id_curr = $id_parent;
- $id_parent = $this->overview[$id_curr]->parent;
- }
- // on compte les threads précédents
- foreach ($this->overview as $i=>$p) {
- if ($i==$id_curr) {
- break;
- }
- if (is_null($p->parent)) {
- $ndx += $this->overview[$i]->desc;
- }
+ // on compte les threads précédents
+ foreach ($this->overview as $i=>$p) {
+ if ($i==$id_curr) {
+ break;
+ }
+ if (is_null($p->parent)) {
+ $ndx += $this->overview[$i]->desc;
+ }
+ }
+ return $ndx;
}
- return $ndx;
- }
}
?>