".$text_error["error:"]."
"; echo "".$text_thread["no_such_group"]."
"; flush(); } else { $infofilename=$spooldir."/".$groupname."-info.txt"; // lets find out, in which mode wie want to read articles: // w: complete rebuild of the group-info file // a: add new articles to the group-info file // n: there are no new articles, no rebuild or actualisation // t: low watermark increased, remove expired articles $spoolopenmodus="n"; // if the group-info file doesn't exist: create it if (!((file_exists($infofilename)) && (file_exists($spoolfilename)))) { file_put_contents($logfile, "\n".format_log_date()." ".$config_name." ".$infofilename." or ".$spoolfilename." does not exist. Rebuilding ".$groupname, FILE_APPEND); $spoolopenmodus="w"; } else { $infofile=fopen($infofilename,"r"); $oldid=fgets($infofile,100); if (trim($oldid) != $idstring) { echo "\n"; file_put_contents($logfile, "\n".format_log_date()." ".$config_name." config changed, Rebuilding ".$groupname, FILE_APPEND); $spoolopenmodus="w"; } $oldgroupinfo=explode(" ",trim(fgets($infofile,200))); fclose($infofile); if ($groupinfo[3] < $oldgroupinfo[1]) { file_put_contents($logfile, "\n".format_log_date()." ".$config_name." high watermark reduced. Rebuilding ".$groupname, FILE_APPEND); $spoolopenmodus="w"; } if ($maxarticles == 0) { if ($groupinfo[2] != $oldgroupinfo[0]) $spoolopenmodus="w"; } else { if ($groupinfo[2] > $oldgroupinfo[0]) { file_put_contents($logfile, "\n".format_log_date()." ".$config_name." low watermark increased. Trimming ".$groupname, FILE_APPEND); $spoolopenmodus="t"; } } // if the high watermark increased, add articles to the existing spool if (($spoolopenmodus == "n") && ($groupinfo[3] > $oldgroupinfo[1])) { file_put_contents($logfile, "\n".format_log_date()." ".$config_name." Adding articles to ".$groupname, FILE_APPEND); $spoolopenmodus="a"; } } if ($spoolopenmodus=="a") { $firstarticle=$oldgroupinfo[1]+1; $lastarticle=$groupinfo[3]; } if ($spoolopenmodus=="w") { $firstarticle=$groupinfo[2]; $lastarticle=$groupinfo[3]; } if ($spoolopenmodus != "n") { if ($maxarticles != 0) { if ($spoolopenmodus == "w") { $firstarticle=$lastarticle-$maxarticles+1; if ($firstarticle < $groupinfo[2]) $firstarticle=$groupinfo[2]; } else { if ($lastarticle-$oldgroupinfo[0]+1 > $maxarticles + $maxarticles_extra) { $firstarticle=$lastarticle-$maxarticles+1; $spoolopenmodus="w"; } } } if (($maxfetch!=0) && (($lastarticle-$firstarticle+1) > $maxfetch)) { if ($spoolopenmodus=="w") { $tofetch=($initialfetch != 0) ? $initialfetch : $maxfetch; $lastarticle=$firstarticle+$tofetch-1; } else { $lastarticle=$firstarticle+$maxfetch-1; } } } echo "\n"; // load the old spool-file, if we do not have a complete rebuild if (($spoolopenmodus != "w") && ($spoolopenmodus != "t")) { $headers=thread_cache_load($groupname); } if ($spoolopenmodus == 't') { $count = 0; for($i=$oldgroupinfo[0]; $i<$groupinfo[2]; $i++) { thread_cache_removearticle($groupname,$i); $count++; } // Save the info-file $oldinfo=file($infofilename); $oldstring=explode(" ", $oldinfo[1]); $infofile=fopen($infofilename,"w"); fputs($infofile,$idstring."\n"); fputs($infofile,$groupinfo[2]." ".$oldstring[1]." ".($oldgroupinfo[2] - $count)."\r\n"); fclose($infofile); $spoolopenmodus = "n"; } // read articles from the newsserver if ($spoolopenmodus != "n") { // order the article overviews from the newsserver fputs($ns,"XOVER ".$firstarticle."-".$lastarticle."\r\n"); $tmp=line_read($ns); // have the server accepted our order? if (substr($tmp,0,3) == "224") { $line=line_read($ns); // read overview by overview until the data ends while ($line != ".") { // parse the output of the server... $article=thread_overview_interpret($line,$overviewformat,$groupname); // ... and save it in our data structure $article->threadsize++; $article->date_thread=$article->date; $headers[$article->id]=$article; // if we are in poll-mode: print status information and // decode the article itself, so it can be saved in the article // cache if($poll) { echo $article->number.", "; flush(); message_read($article->number,0,$groupname); } // read the next line from the newsserver $line=line_read($ns); } // write information about the last article to the spool-directory $infofile=fopen($spooldir."/".$groupname."-lastarticleinfo.dat","w"); $lastarticleinfo->from=$article->from; $lastarticleinfo->date=$article->date; $lastarticleinfo->name=$article->name; fputs($infofile,serialize($lastarticleinfo)); fclose($infofile); } // remove the old spoolfile // if (file_exists($spoolfilename)) unlink($spoolfilename); if ((isset($headers)) && (count($headers)>0)) { //$infofile=fopen($infofilename,"w"); //if ($spoolopenmodus=="a") $firstarticle=$oldgroupinfo[0]; //fputs($infofile,$idstring."\n"); //fputs($infofile,$firstarticle." ".$lastarticle."\r\n"); //fclose($infofile); foreach($headers as $c) { if (($c->isAnswer == false) && (isset($c->references))) { // is the article an answer to an // other article? // try to find a matching article to one of the references $refmatch=false; foreach ($c->references as $reference) { if(isset($headers[$reference])) { $refmatch=$reference; } } // have we found an article, to which this article is an answer? if($refmatch!=false) { $c->isAnswer=true; $c->bestreference=$refmatch; $headers[$c->id]=$c; // the referenced article get the ID af this article as in // its answers-array $headers[$refmatch]->answers[]=$c->id; // propagate down the number of articles in this thread $d =& $headers[$c->bestreference]; do { $d->threadsize+=$c->threadsize; $d->date_thread=max($c->date,$d->date_thread); } while(($headers[$d->bestreference]) && (isset($d->bestreference)) && ($d =& $headers[$d->bestreference])); } } } reset($headers); // sort the articles if (($thread_sort_order != 0) && (count($headers)>0)) uasort($headers,'thread_mycompare'); // Save the thread-informations // if (file_exists($spoolfilename)) unlink($spoolfilename); thread_cache_save($headers,$groupname); // Save the info-file $infofile=fopen($infofilename,"w"); if ($spoolopenmodus=="a") $firstarticle=$oldgroupinfo[0]; fputs($infofile,$idstring."\n"); fputs($infofile,$firstarticle." ".$lastarticle." ".count($headers)."\r\n"); fclose($infofile); } // remove cached articles that are not in this group // (expired on the server or canceled) $dirhandle=opendir($spooldir); while ($cachefile = readdir($dirhandle)) { if(substr($cachefile,0,strlen($groupname)+1)==$groupname."_") { $num=preg_replace('/^(.*)_(.*)\.(.*)$/i','\2',$cachefile); if(($num<$firstarticle) || ($num>$lastarticle)) unlink($spooldir.'/'.$cachefile); } // remove the html cache files of this group if((substr($cachefile,strlen($cachefile)-5)==".html") && (substr($cachefile,0,strlen($groupname)+1)==$groupname."-")) unlink($spooldir.'/'.$cachefile); } } if(isset($headers)) return $headers; return false; //return((isset($headers)) ? $headers : false); } } /* * Read the Overview. * Format of the overview-file: * message-id * date * subject * author * email * references * * $groupname: name of the newsgroup * $readmode: if set to 0, this function only reads data from the * newsserver, if there exists no cached data for this group * $poll: polling mode, see description at thread_load_newsserver() */ function thread_load($groupname,$readmode = 1,$poll=false) { global $text_error, $maxarticles, $server, $port; global $spooldir,$thread_sort_order,$cache_thread; global $articles_per_page; if (!testGroup($groupname)) { echo $text_error["read_access_denied"]; return; } // first assume that we have to query the newsserver $query_ns=true; // name of the file that indicates by it's timestamp when the // last query of the newsserver was $cachefile=$spooldir.'/'.$groupname.'-cache.txt'; // should we load the data only from cache if it's recent enough, or // do we have to query the newsserver every time? if(is_file($cachefile)) { if(filemtime($cachefile)+$cache_thread < time()) { if(is_file($spooldir.'/'.$groupname.'-1-'.$articles_per_page.'.html')) { unlink($spooldir.'/'.$groupname.'-1-'.$articles_per_page.'.html'); } unlink($cachefile); } } if($cache_thread>0) { if(file_exists($cachefile)) { // cached file exists and is new enough. so lets read it out. $articles=thread_cache_load($groupname); return $articles; $query_ns=false; } } // do we have to query the newsserver? if($query_ns) { // look if there is new data on the newsserver $ns=nntp_open($server,$port); if ($ns == false) return false; if (($ns!=false) && ($readmode > 0)) $articles=thread_load_newsserver($ns,$groupname,$poll); if ((isset($articles)) && ($articles)) { // write the file which indicates the time of the last newsserver query touch($cachefile); return $articles; } else { // uh, we didn't get articles from the newsservers... // for now, return false. but it would also make sense to get // the articles from the cache then... return false; } nntp_close($ns); } } /* * Remove re:, aw: etc. from a subject. * * $subject: a string containing the complete Subject * * The function removes the re:, aw: etc. from $subject end returns true * if it removed anything, and false if not. */ function splitSubject(&$subject) { $s=preg_replace('/^(odp:|aw:|re:|re\[2\]:| )+/i','',$subject); $return=($s != $subject); $subject=$s; return $return; } function str_change($str,$pos,$char) { return(substr($str,0,$pos).$char.substr($str,$pos+1,strlen($str)-$pos)); } /* * calculate the graphic representation of the thread */ function thread_show_calculate($newtree,$depth,$num,$liste,$c) { global $thread_show; // displays the replies to an article? if(!$thread_show["replies"]) { // no if ((isset($c->answers[0])) && (count($c->answers)>0)) $newtree.="o"; else $newtree.="o"; } else { // yes, display the replies if ((isset($c->answers[0])) && (count($c->answers)>0)) { $newtree.="*"; } else { if ($depth == 1) { $newtree.="o"; } else { $newtree.="-"; } } if (($num == count($liste)-1) && ($depth>1)) { $newtree=str_change($newtree,$depth-2,"`"); } } return($newtree); } /* * Format the message-tree * Zeichen im Baum: * o : leerer Kasten k1.gif * * : Kasten mit Zeichen drin k2.gif * i : vertikale Linie I.gif * - : horizontale Linie s.gif * + : T-Stueck T.gif * ` : Winkel L.gif */ function thread_show_treegraphic($newtree) { global $imgdir; $return=""; for ($o=0 ; $oBy: '.create_name_link($started, $c->from).' on '.date("D, j M Y",$newdate).'
'; $return.=''.get_date_interval(date("D, j M Y H:i T",$c->date_thread)).''; } else { $return.='
'.get_date_interval(date("D, j M Y H:i T",$c->date_thread)).'
'; } $return.='By: '.create_name_link($poster_name, $name_from).'
'; return($return); } /* * Displays a part of the thread. This function is recursively called * It is used by thread_show */ function thread_show_recursive(&$headers,&$liste,$depth,$tree,$group,$article_first=0,$article_last=0,&$article_count,$highlight=false,$lastmessage=1) { global $thread_treestyle; global $thread_show,$imgdir; global $file_article,$thread_maxSubject; global $age_count,$age_time,$age_color,$spooldir; global $frame_article; $output=""; if ($thread_treestyle==3) $output.= "\n'. ''. thread_format_date($c).' | '; $output.= ''. thread_show_treegraphic($newtree).' | '; if ($thread_show["subject"]) $output.= ''. ' '. thread_format_subject($c,$group,$highlight)." "; if ($thread_show["author"]) $output.= '('.thread_format_author($c,$group,$lastmessage).') | '; $output.= "
'.$text_thread["date"]." | "; if ($thread_show["subject"]) echo ''. $text_thread["subject"]." | "; if ($thread_show["threadsize"]) echo ''. $text_thread["threadsize"]." | "; if ($thread_show["author"]) { if($lastmessage == 1) { echo ''.$text_thread["lastmessage"]." | \n"; } else { echo ''.$text_thread["author"]." | \n"; } } echo "