/[suikacvs]/messaging/newsportal/newsportal.php
Suika

Contents of /messaging/newsportal/newsportal.php

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (hide annotations) (download)
Sat Dec 1 11:17:31 2001 UTC (22 years, 5 months ago) by wakaba
Branch: MAIN
Branch point for: suika
Initial revision

1 wakaba 1.1 <?
2     /*
3     Newsportal NNTP<->HTTP Gateway
4    
5     Version: 0.24pre3
6    
7     this Script is licensed under the GNU Public License
8    
9     Author: Florian Amrhein
10     eMail: florian.amrhein@gmx.de
11     Homepage: http://floh.gartenhaus.net
12     */
13    
14     /*
15     * the name and the description of a newsgroup
16     */
17     class newsgroupType {
18     var $name;
19     var $description;
20     var $count;
21     }
22    
23     /*
24     * Stores a complete article:
25     * - The parsed Header as an headerType
26     * - The bodies and attachments as an array of array of lines
27     */
28     class messageType {
29     var $header;
30     var $body;
31     }
32    
33    
34    
35     /*
36     * Stores the Header of an article
37     */
38     class headerType {
39     var $number; // the Number of an article inside a group
40     var $id; // Message-ID
41     var $from; // eMail of the author
42     var $name; // Name of the author
43     var $subject; // the subject
44     var $newsgroups; // the Newsgroups where the article belongs to
45     var $followup;
46     var $date;
47     var $organization;
48     var $references;
49     var $content_transfer_encoding;
50     var $mime_version;
51     var $content_type; // array, Content-Type of the Body (Index=0) and the
52     // Attachments (Index>0)
53     var $content_type_charset; // like content_type
54     var $content_type_name; // array of the names of the attachments
55     var $content_type_boundary; // The boundary of an multipart-article.
56     var $answers;
57     var $isAnswer;
58     var $username;
59     var $user_agent;
60     var $isReply;
61     }
62    
63     /*
64     * opens the connection to the NNTP-Server
65     *
66     * $server: adress of the NNTP-Server
67     * $port: port of the server
68     */
69     function OpenNNTPconnection($nserver=0,$nport=0) {
70     global $text_error,$server_auth_user,$server_auth_pass,$readonly;
71     global $server,$port;
72     if ($nserver==0) $nserver=$server;
73     if ($nport==0) $nport=$port;
74     $ns=fsockopen($nserver,$nport);
75     $weg=lieszeile($ns); // kill the first line
76     if (substr($weg,0,2) != "20") {
77     echo "<p>".$text_error["error:"]."</p>";
78     } else {
79     if ($ns != false) {
80     fputs($ns,"mode reader\r\n");
81     $weg=lieszeile($ns); // and once more
82     if (substr($weg,0,2) != "20") {
83     echo "<p>".$text_error["error:"]."</p>";
84     }
85     }
86     if ((isset($server_auth_user)) && (isset($server_auth_pass)) &&
87     ($server_auth_user != "")) {
88     fputs($ns,"authinfo user $server_auth_user\r\n");
89     $weg=lieszeile($ns);
90     fputs($ns,"authinfo pass $server_auth_pass\r\n");
91     $weg=lieszeile($ns);
92     if (substr($weg,0,3) != "281") {
93     echo "<p>".$text_error["error:"]."</p>";
94     echo "<p>".$text_error["auth_error"]."</p>";
95     }
96     }
97     }
98     if ($ns==false) echo "<p>".$text_error["connection_failed"]."</p>";
99     return $ns;
100     }
101    
102     /*
103     * Close a NNTP connection
104     *
105     * $ns: the handle of the connection
106     */
107     function closeNNTPconnection(&$ns) {
108     if ($ns != false) {
109     fputs($ns,"quit\r\n");
110     fclose($ns);
111     }
112     }
113    
114     /*
115     * Validates an email adress
116     *
117     * $address: a string containing the email-address to be validated
118     *
119     * returns true if the address passes the tests, false otherwise.
120     */
121     function validate_email($address)
122     {
123     global $validate_email;
124     $return=true;
125     if (($validate_email >= 1) && ($return == true))
126     $return = (ereg('^[-!#$%&\'*+\\./0-9=?A-Z^_A-z{|}~]+'.'@'.
127     '[-!#$%&\'*+\\/0-9=?A-Z^_A-z{|}~]+\.'.
128     '[-!#$%&\'*+\\./0-9=?A-Z^_A-z{|}~]+$',$address));
129     if (($validate_email >= 2) && ($return == true)) {
130     $addressarray=address_decode($address,"garantiertungueltig");
131     $return=checkdnsrr($addressarray[0]["host"],"MX");
132     if (!$return) $return=checkdnsrr($addressarray[0]["host"],"A");
133     }
134     return($return);
135     }
136    
137     /*
138     * decodes a block of 7bit-data in uuencoded format to it's original
139     * 8bit format.
140     * The headerline containing filename and permissions doesn't have to
141     * be included.
142     *
143     * $data: The uuencoded data as a string
144     *
145     * returns the 8bit data as a string
146     *
147     * Note: this function is very slow and doesn't recognize incorrect code.
148     */
149     function uudecode_line($line) {
150     $data=substr($line,1);
151     $length=ord($line[0])-32;
152     $decoded="";
153     for ($i=0; $i<(strlen($data)>>2); $i++) {
154     $pack=substr($data,$i<<2,4);
155     $upack="";
156     $bitmaske=0;
157     for ($o=0; $o<4; $o++) {
158     $g=((ord($pack[3-$o])-32));
159     if ($g==64) $g=0;
160     $bitmaske=$bitmaske | ($g << (6*$o));
161     }
162     $schablone=255;
163     for ($o=0; $o<3; $o++) {
164     $c=($bitmaske & $schablone) >> ($o << 3);
165     $schablone=($schablone << 8);
166     $upack=chr($c).$upack;
167     }
168     $decoded.=$upack;
169     }
170     $decoded=substr($decoded,0,$length);
171     return $decoded;
172     }
173     function uudecode($data) {
174     $d=explode("\n",$data);
175     $u="";
176     for ($i=0; $i<count($d)-1; $i++)
177     $u.=uudecode_line($d[$i]);
178     return $u;
179     }
180    
181     /*
182     * returns the mimetype of an filename
183     *
184     * $name: the complete filename of a file
185     *
186     * returns a string containing the mimetype
187     */
188     function get_mimetype_by_filename($name) {
189     $ending=strtolower(strrchr($name,"."));
190     switch($ending) {
191     case ".jpg":
192     $type="image/jpeg";
193     break;
194     case ".gif":
195     $type="image/gif";
196     break;
197     default:
198     $type="text/plain";
199     }
200     return $type;
201     }
202    
203     function showPageSelectMenu($article_count,$first) {
204     global $articles_per_page,$file_thread,$file_framethread,$name;
205     /* if (isset($file_framethread)) {
206     $thread=$file_framethread;
207     } else {
208     $thread=$file_thread;
209     }
210     */
211     $pages=ceil($article_count / $articles_per_page);
212     if ($article_count > $articles_per_page)
213     for ($i = 0; $i < $pages; $i++) {
214     echo '[';
215     if ($first != $i*$articles_per_page+1)
216     echo '<a href="'.($i*$articles_per_page+1).'_'.
217     ($i+1)*$articles_per_page.'.html">';
218     echo ($i*$articles_per_page+1).'-';
219     if ($i == $pages-1) {
220     echo $article_count;
221     } else {
222     echo ($i+1)*$articles_per_page;
223     }
224     if ($first != $i*$articles_per_page+1)
225     echo '</a>';
226     echo '] ';
227     }
228     }
229    
230     function testGroup($groupname) {
231     global $testgroup;
232     if ($testgroup) {
233     $gf=fopen("groups.txt","r");
234     while (!feof($gf)) {
235     $read=trim(lieszeile($gf));
236     $pos=strpos($read," ");
237     if ($pos != false) {
238     if (substr($read,0,$pos)==trim($groupname)) return true;
239     } else {
240     if ($read == trim($groupname)) return true;
241     }
242     }
243     fclose($gf);
244     return false;
245     } else {
246     return true;
247     }
248     }
249    
250     function testGroups($newsgroups) {
251     $groups=explode(",",$newsgroups);
252     $count=count($groups);
253     $return="";
254     $o=0;
255     for ($i=0; $i<$count; $i++) {
256     if (testgroup($groups[$i])) {
257     if ($o>0) $return.=",";
258     $o++;
259     $return.=$groups[$i];
260     }
261     }
262     return($return);
263     }
264    
265     /*
266     * read one line from the NNTP-server
267     */
268     function lieszeile(&$ns) {
269     if ($ns != false) {
270     $t=str_replace("\n","",str_replace("\r","",fgets($ns,1200)));
271     return $t;
272     }
273     }
274    
275     /*
276     * Split an internet-address string into its parts. An address string could
277     * be for example:
278     * - user@host.domain (Realname)
279     * - "Realname" <user@host.domain>
280     * - user@host.domain
281     *
282     * The address will be split into user, host (incl. domain) and realname
283     *
284     * $adrstring: The string containing the address in internet format
285     * $defaulthost: The name of the host which should be returned if the
286     * address-string doesn't contain a hostname.
287     *
288     * returns an hash containing the fields "mailbox", "host" and "personal"
289     */
290     function address_decode($adrstring,$defaulthost) {
291     $parsestring=trim($adrstring);
292     $len=strlen($parsestring);
293     $at_pos=strpos($parsestring,'@'); // find @
294     $ka_pos=strpos($parsestring,"("); // find (
295     $kz_pos=strpos($parsestring,')'); // find )
296     $ha_pos=strpos($parsestring,'<'); // find <
297     $hz_pos=strpos($parsestring,'>'); // find >
298     $space_pos=strpos($parsestring,')'); // find ' '
299     $email="";
300     $mailbox="";
301     $host="";
302     $personal="";
303     if ($space_pos != false) {
304     if (($ka_pos != false) && ($kz_pos != false)) {
305     $personal=substr($parsestring,$ka_pos+1,$kz_pos-$ka_pos-1);
306     $email=trim(substr($parsestring,0,$ka_pos-1));
307     }
308     } else {
309     $email=$adrstring;
310     }
311     if (($ha_pos != false) && ($hz_pos != false)) {
312     $email=trim(substr($parsestring,$ha_pos+1,$hz_pos-$ha_pos-1));
313     $personal=substr($parsestring,0,$ha_pos-1);
314     }
315     if ($at_pos != false) {
316     $mailbox=substr($email,0,strpos($email,'@'));
317     $host=substr($email,strpos($email,'@')+1);
318     } else {
319     $mailbox=$email;
320     $host=$defaulthost;
321     }
322     $personal=trim($personal);
323     if (substr($personal,0,1) == '"') $personal=substr($personal,1);
324     if (substr($personal,strlen($personal)-1,1) == '"')
325     $personal=substr($personal,0,strlen($personal)-1);
326     $result["mailbox"]=trim($mailbox);
327     $result["host"]=trim($host);
328     // $personal = mb_convert_encoding($personal, "EUC-JP", "auto");
329     if ($personal!="") $result["personal"]=$personal;
330     $complete[]=$result;
331     return ($complete);
332     }
333    
334    
335    
336     function readGroups($server,$port) {
337     $ns=OpenNNTPconnection($server,$port);
338     if ($ns == false) return false;
339     $gf=fopen("groups.txt","r");
340     while (!feof($gf)) {
341     $gruppe=new newsgroupType;
342     $tmp=trim(lieszeile($gf));
343     $pos=strpos($tmp," ");
344     if ($pos != false) {
345     $gruppe->name=substr($tmp,0,$pos);
346     $desc=substr($tmp,$pos);
347     } else {
348     $gruppe->name=$tmp;
349     fputs($ns,"xgtitle $gruppe->name\r\n");
350     $response=liesZeile($ns);
351     if (strcmp(substr($response,0,3),"282") == 0) {
352     $neu=liesZeile($ns);
353     do {
354     $response=$neu;
355     if ($neu != ".") $neu=liesZeile($ns);
356     } while ($neu != ".");
357     $desc=strrchr($response,"\t");
358     if (strcmp($response,".") == 0) {
359     $desc="-";
360     }
361     } else {
362     $desc=$response;
363     }
364     if (strcmp(substr($response,0,3),"500") == 0)
365     $desc="-";
366     }
367     if (strcmp($desc,"") == 0) $desc="-";
368     $gruppe->description=$desc;
369     fputs($ns,"group ".$gruppe->name."\r\n");
370     $response=liesZeile($ns);
371     $t=strchr($response," ");
372     $t=substr($t,1,strlen($t)-1);
373     $gruppe->count=substr($t,0,strpos($t," "));
374     if ((strcmp(trim($gruppe->name),"") != 0) &&
375     (substr($gruppe->name,0,1) != "#"))
376     $newsgroups[]=$gruppe;
377     }
378     fclose($gf);
379     closeNNTPconnection($ns);
380     return $newsgroups;
381     }
382    
383     /*
384     * print the group names from an array to the webpage
385     */
386     function showgroups($gruppen) {
387     if ($gruppen == false) return;
388     global $file_thread,$text_groups;
389     $c = count($gruppen);
390     echo "<table>\n";
391     echo "<tr><td>#</td><td>".$text_groups["newsgroup"].
392     "</td><td>".$text_groups["description"]."</td></tr>\n";
393     for($i = 0 ; $i < $c ; $i++) {
394     $g = $gruppen[$i];
395     echo "<tr><td>";
396     echo "$g->count</td><td>";
397     echo '<a ';
398     if ((isset($frame_threadframeset)) && ($frame_threadframeset != ""))
399     echo 'target="'.$frame_threadframeset.'" ';
400     echo 'href="'.$file_thread.'/'.urlencode($g->name).'/index.html">'.$g->name."</a></td>\n";
401     echo "<td>$g->description</td></tr>\n";
402     flush();
403     }
404     echo "</table>\n";
405     }
406    
407     /*
408     * gets a list of aviable articles in the group $groupname
409     */
410     function getArticleList(&$von,$groupname) {
411     fputs($von,"listgroup $groupname \r\n");
412     $zeile=lieszeile($von);
413     $zeile=lieszeile($von);
414     while(strcmp($zeile,".") != 0) {
415     $articleList[] = trim($zeile);
416     $zeile=lieszeile($von);
417     }
418     if (!isset($articleList)) $articleList="-";
419     return $articleList;
420     }
421    
422     /*
423     * Decode quoted-printable or base64 encoded headerlines
424     *
425     * $value: The to be decoded line
426     *
427     * returns the decoded line
428     */
429     function headerDecode($value) {
430     if (eregi('=\?.*\?.\?.*\?=',$value)) { // is there anything encoded?
431     if (eregi('=\?.*\?Q\?.*\?=',$value)) { // quoted-printable decoding
432     $result1=eregi_replace('(.*)=\?.*\?Q\?(.*)\?=(.*)','\1',$value);
433     $result2=eregi_replace('(.*)=\?.*\?Q\?(.*)\?=(.*)','\2',$value);
434     $result3=eregi_replace('(.*)=\?.*\?Q\?(.*)\?=(.*)','\3',$value);
435     $result2=str_replace("_"," ",quoted_printable_decode($result2));
436     $newvalue=$result1.$result2.$result3;
437     }
438     if (eregi('=\?.*\?B\?.*\?=',$value)) { // base64 decoding
439     $result1=eregi_replace('(.*)=\?.*\?B\?(.*)\?=(.*)','\1',$value);
440     $result2=eregi_replace('(.*)=\?.*\?B\?(.*)\?=(.*)','\2',$value);
441     $result3=eregi_replace('(.*)=\?.*\?B\?(.*)\?=(.*)','\3',$value);
442     $result2=base64_decode($result2);
443     $newvalue=$result1.$result2.$result3;
444     }
445     if (!isset($newvalue)) // nothig of them, must be an unknown encoding...
446     $newvalue=$value;
447     else
448     $newvalue=headerDecode($newvalue); // maybe there are more encoded
449     return(mb_convert_encoding($newvalue, "EUC-JP", "auto")); // parts
450     } else { // there wasn't anything encoded, return the original string
451     return(mb_convert_encoding($value, "EUC-JP", "auto"));
452     }
453     }
454    
455     function getTimestamp($value) {
456     $months=array("Jan"=>1,"Feb"=>2,"Mar"=>3,"Apr"=>4,"May"=>5,"Jun"=>6,"Jul"=>7,"Aug"=>8,"Sep"=>9,"Oct"=>10,"Nov"=>11,"Dec"=>12);
457     $value=str_replace(" "," ",$value);
458     $d=split(" ",$value,5);
459     if (strcmp(substr($d[0],strlen($d[0])-1,1),",") == 0) {
460     $date[0]=$d[1]; // day
461     $date[1]=$d[2]; // month
462     $date[2]=$d[3]; // year
463     $date[3]=$d[4]; // hours:minutes:seconds
464     } else {
465     $date[0]=$d[0]; // day
466     $date[1]=$d[1]; // month
467     $date[2]=$d[2]; // year
468     $date[3]=$d[3]; // hours:minutes:seconds
469     }
470     $time=split(":",$date[3]);
471     $timestamp=mktime($time[0],$time[1],$time[2],$months[$date[1]],$date[0],$date[2]);
472     return $timestamp;
473     }
474    
475     function parse_header($hdr,$number="") {
476     for ($i=count($hdr)-1; $i>0; $i--)
477     if (preg_match("/^(\x09|\x20)/",$hdr[$i]))
478     $hdr[$i-1]=$hdr[$i-1].ltrim($hdr[$i]);
479     $header = new headerType;
480     $header->isAnswer=false;
481     for ($count=0;$count<count($hdr);$count++) {
482     $variable=substr($hdr[$count],0,strpos($hdr[$count]," "));
483     $value=trim(substr($hdr[$count],strpos($hdr[$count]," ")+1));
484     switch (strtolower($variable)) {
485     case "from:":
486     $fromline=address_decode(headerDecode($value),"nirgendwo");
487     if (!isset($fromline[0]["host"])) $fromline[0]["host"]="";
488     $header->from=$fromline[0]["mailbox"]."@".$fromline[0]["host"];
489     $header->username=$fromline[0]["mailbox"];
490     if (!isset($fromline[0]["personal"])) {
491     $header->name="";
492     } else {
493     $header->name=$fromline[0]["personal"];
494     }
495     break;
496     case "message-id:":
497     $header->id=$value;
498     break;
499     case "subject:":
500     $header->subject=headerDecode($value);
501     break;
502     case "newsgroups:":
503     $header->newsgroups=$value;
504     break;
505     case "organization:":
506     $header->organization=$value;
507     break;
508     case "content-transfer-encoding:":
509     $header->content_transfer_encoding=trim(strtolower($value));
510     break;
511     case "content-type:":
512     $header->content_type=array();
513     $subheader=split(";",$value);
514     $header->content_type[0]=strtolower(trim($subheader[0]));
515     for ($i=1; $i<count($subheader); $i++) {
516     $gleichpos=strpos($subheader[$i],"=");
517     if ($gleichpos) {
518     $subvariable=trim(substr($subheader[$i],0,$gleichpos));
519     $subvalue=trim(substr($subheader[$i],$gleichpos+1));
520     if (($subvalue[0]=='"') &&
521     ($subvalue[strlen($subvalue)-1]=='"'))
522     $subvalue=substr($subvalue,1,strlen($subvalue)-2);
523     switch($subvariable) {
524     case "charset":
525     $header->content_type_charset=array(strtolower($subvalue));
526     break;
527     case "name":
528     $header->content_type_name=array($subvalue);
529     break;
530     case "boundary":
531     $header->content_type_boundary=$subvalue;
532     }
533     }
534     }
535     break;
536     case "references:":
537     $ref=ereg_replace("> *<", "> <", trim($value));
538     while (strpos($ref,"> <") != false) {
539     $header->references[]=substr($ref,0,strpos($ref," "));
540     $ref=substr($ref,strpos($ref,"> <")+2);
541     }
542     $header->references[]=trim($ref);
543     break;
544     case "date:":
545     $header->date=getTimestamp(trim($value));
546     break;
547     case "followup-to:":
548     $header->followup=trim($value);
549     break;
550     case "x-newsreader:":
551     case "x-mailer:":
552     case "user-agent:":
553     $header->user_agent=trim($value);
554     break;
555     case "x-face:":
556     // echo "<p>-".base64_decode($value)."-</p>";
557     break;
558     }
559     }
560     if (!isset($header->content_type[0]))
561     $header->content_type[0]="text/plain";
562     if (!isset($header->content_transfer_encoding))
563     $header->content_transfer_encoding="8bit";
564     if ($number != "") $header->number=$number;
565     return $header;
566     }
567    
568     function decode_body($body,$encoding) {
569     $bodyzeile="";
570     switch ($encoding) {
571     case "base64":
572     $body=base64_decode($body);
573     break;
574     case "quoted-printable":
575     $body=Quoted_printable_decode($body);
576     $body=str_replace("=\n","",$body);
577     // default:
578     // $body=str_replace("\n..\n","\n.\n",$body);
579     }
580     return $body;
581     }
582    
583     function parse_message($rawmessage) {
584     global $attachment_delete_alternative,$attachment_uudecode;
585     // Read the header of the message:
586     $count_rawmessage=count($rawmessage);
587     $message = new messageType;
588     $rawheader=array();
589     $i=0;
590     while ($rawmessage[$i] != "") {
591     $rawheader[]=$rawmessage[$i];
592     $i++;
593     }
594     // Parse the Header:
595     $message->header=parse_header($rawheader);
596     // Now we know if the message is a mime-multipart message:
597     $content_type=split("/",$message->header->content_type[0]);
598     if ($content_type[0]=="multipart") {
599     $message->header->content_type=array();
600     // We have multible bodies, so we split the message into its parts
601     $boundary="--".$message->header->content_type_boundary;
602     // lets find the first part
603     while($rawmessage[$i] != $boundary)
604     $i++;
605     $i++;
606     $part=array();
607     while($i<=$count_rawmessage) {
608     if (($rawmessage[$i]==$boundary) || ($i==$count_rawmessage-1) ||
609     ($rawmessage[$i]==$boundary.'--')) {
610     $partmessage=parse_message($part);
611     // merge the content-types of the message with those of the part
612     for ($o=0; $o<count($partmessage->header->content_type); $o++) {
613     $message->header->content_type[]=
614     $partmessage->header->content_type[$o];
615     $message->header->content_type_charset[]=
616     $partmessage->header->content_type_charset[$o];
617     $message->header->content_type_name[]=
618     $partmessage->header->content_type_name[$o];
619     $message->body[]=$partmessage->body[$o];
620     }
621     $part=array();
622     } else {
623     if ($i<$count_rawmessage)
624     $part[]=$rawmessage[$i];
625     }
626     if ($rawmessage[$i]==$boundary.'--') break;
627     $i++;
628     }
629     // Is this a multipart/alternative multipart-message? Do we have to
630     // delete all non plain/text parts?
631     if (($attachment_delete_alternative) &&
632     ($content_type[1]=="alternative")) {
633     $plaintext=false;
634     for ($o=0; $o<count($message->header->content_type); $o++) {
635     if ($message->header->content_type[$o]=="text/plain")
636     $plaintext=true; // we found at least one text/plain
637     }
638     if ($plaintext) { // now we can delete the other parts
639     for ($o=0; $o<count($message->header->content_type); $o++) {
640     if ($message->header->content_type[$o]!="text/plain") {
641     unset($message->header->content_type[$o]);
642     unset($message->header->content_type_name[$o]);
643     unset($message->header->content_type_charset[$o]);
644     unset($message->body[$o]);
645     }
646     }
647     }
648     }
649     } else {
650     // No mime-attachments in the message:
651     $body="";
652     $uueatt=0; // as default we have no uuencoded attachments
653     for($i++;$i<$count_rawmessage; $i++) {
654     // do we have an inlay uuencoded file?
655     if ((strtolower(substr($rawmessage[$i],0,5))!="begin") ||
656     ($attachment_uudecode==false)) {
657     $body.=$rawmessage[$i]."\n";
658     // yes, it seems, we have!
659     } else {
660     $old_i=$i;
661     $uue_infoline_raw=$rawmessage[$i];
662     $uue_infoline=explode(" ",$uue_infoline_raw);
663     $uue_data="";
664     $i++;
665     while($rawmessage[$i]!="end") {
666     if (strlen(trim($rawmessage[$i])) > 2)
667     $uue_data.=$rawmessage[$i]."\n";
668     $i++;
669     }
670     // now write the data in an attachment
671     $uueatt++;
672     $message->body[$uueatt]=uudecode($uue_data);
673     $message->header->content_type_name[$uueatt]="";
674     for ($o=2; $o<count($uue_infoline); $o++)
675     $message->header->content_type_name[$uueatt].=$uue_infoline[$o];
676     $message->header->content_type[$uueatt]=
677     get_mimetype_by_filename($message->header->content_type_name[$uueatt]);
678     }
679     }
680     // if ($message->header->content_type[0]=="text/plain") {
681     // $body=trim($body);
682     // if ($body=="") $body=" ";
683     // }
684     $body=decode_body($body,$message->header->content_transfer_encoding);
685     $message->body[0]=$body;
686     }
687     if (!isset($message->header->content_type_charset))
688     $message->header->content_type_charset=array("ISO-8859-1");
689     if (!isset($message->header->content_type_name))
690     $message->header->content_type_name=array("unnamed");
691     for ($o=0; $o<count($message->body); $o++) {
692     if (!isset($message->header->content_type_charset[$o]))
693     $message->header->content_type_charset[$o]="ISO-8859-1";
694     if (!isset($message->header->content_type_name[$o]))
695     $message->header->content_type_name[$o]="unnamed";
696     }
697     return $message;
698     }
699    
700     /*
701     * read an article from the newsserver or the spool-directory
702     *
703     * $id: the Message-ID of an article
704     * $bodynum: the number of the attachment:
705     * -1: return only the header without any bodies or attachments.
706     * 0: the body
707     * 1: the first attachment...
708     *
709     * The function returns an article as an messageType or false if the article
710     * doesn't exists on the newsserver or doesn't contain the given
711     * attachment.
712     */
713     function read_message($id,$bodynum=0,$group="") {
714     global $cache_articles,$spooldir,$text_error;
715     $message = new messageType;
716     if ((isset($cache_articles)) && ($cache_articles == true)) {
717     if ((ereg('^[0-9]+$',$id)) && ($group != ''))
718     $filename=$group.'_'.$id;
719     else
720     $filename=base64_encode($id);
721     $cachefilename_header=$spooldir."/".$filename.'.header';
722     $cachefilename_body=$spooldir."/".$filename.'.body';
723     if (file_exists($cachefilename_header)) {
724     $cachefile=fopen($cachefilename_header,"r");
725     $message->header=unserialize(fread($cachefile,filesize($cachefilename_header)));
726     fclose($cachefile);
727     } else {
728     unset($message->header);
729     }
730     // Is a non-existing attachment of an article requested?
731     if ((isset($message->header)) &&
732     ($bodynum!= -1) &&
733     (!isset($message->header->content_type[$bodynum])))
734     return false;
735     if ((file_exists($cachefilename_body.$bodynum)) &&
736     ($bodynum != -1)) {
737     $cachefile=fopen($cachefilename_body.$bodynum,"r");
738     $message->body[$bodynum]=
739     fread($cachefile,filesize($cachefilename_body.$bodynum));
740     fclose($cachefile);
741     }
742     }
743     if ((!isset($message->header)) ||
744     ((!isset($message->body[$bodynum])) &&
745     ($bodynum != -1))) {
746     if (!isset($ns)) $ns=openNNTPconnection();
747     if ($group != "") {
748     fputs($ns,"group ".$group."\r\n");
749     $zeile=lieszeile($ns);
750     }
751     fputs($ns,'article '.$id."\r\n");
752     $zeile=lieszeile($ns);
753     if (substr($zeile,0,3) != "220")
754     return false;
755     $rawmessage=array();
756     $line=lieszeile($ns);
757     $line=mb_convert_encoding($line, "EUC-JP", "ISO-2022-JP");
758     while(strcmp($line,".") != 0) {
759     $rawmessage[]=$line;
760     $line=lieszeile($ns);
761     $line=mb_convert_encoding($line, "EUC-JP", "ISO-2022-JP");
762     }
763     $message=parse_message($rawmessage);
764     if (ereg('^[0-9]+$',$id)) $message->header->number=$id;
765     // write header, body and attachments to disk
766     if ((isset($cache_articles)) && ($cache_articles == true)) {
767     $cachefile=fopen($cachefilename_header,"w");
768     if ($cachefile) {
769     fputs($cachefile,serialize($message->header));
770     }
771     fclose($cachefile);
772     for ($i=0; $i<count($message->header->content_type); $i++) {
773     if (isset($message->body[$i])) {
774     $cachefile=fopen($cachefilename_body.$i,"w");
775     fwrite($cachefile,$message->body[$i]);
776     fclose($cachefile);
777     }
778     }
779     }
780     }
781     return $message;
782     }
783    
784     function textwrap($text, $wrap=80, $break="\n"){
785     $len = strlen($text);
786     if ($len > $wrap) {
787     $h = ''; // massaged text
788     $lastWhite = 0; // position of last whitespace char
789     $lastChar = 0; // position of last char
790     $lastBreak = 0; // position of last break
791     // while there is text to process
792     while ($lastChar < $len) {
793     $char = substr($text, $lastChar, 1); // get the next character
794     // if we are beyond the wrap boundry and there is a place to break
795     if (($lastChar - $lastBreak > $wrap) && ($lastWhite > $lastBreak)) {
796     $h .= substr($text, $lastBreak, ($lastWhite - $lastBreak)) . $break;
797     $lastChar = $lastWhite + 1;
798     $lastBreak = $lastChar;
799     }
800     // You may wish to include other characters as valid whitespace...
801     if ($char == ' ' || $char == chr(13) || $char == chr(10)) {
802     $lastWhite = $lastChar; // note the position of the last whitespace
803     }
804     $lastChar = $lastChar + 1; // advance the last character position by one
805     }
806     $h .= substr($text, $lastBreak); // build line
807     } else {
808     $h = $text; // in this case everything can fit on one line
809     }
810     return $h;
811     }
812    
813     /*
814     * makes URLs clickable
815     *
816     * $comment: A text-line probably containing links.
817     *
818     * the function returns the text-line with HTML-Links to the links or
819     * email-adresses.
820     */
821     function html_parse($comment, $group = "", $msgidregex = "") {
822     global $frame_externallink;
823     global $file_article;
824     if ((isset($frame_externallink)) && ($frame_externallink != "")) {
825     $target=' TARGET="'.$frame_externallink.'" ';
826     } else {
827     $target=' ';
828     }
829     $ncomment = eregi_replace( 'http://([-a-z0-9_./~@?=%#&;]+)', '<a'.$target.'href="http://\1">http://\1</a>', $comment);
830     if ($ncomment == $comment)
831     $ncomment = eregi_replace( '(www\.[-a-z]+\.(de|int|eu|dk|org|net|at|ch|com|jp))','<a'.$target.'href="http://\1">\1</a>',$comment);
832     $comment=$ncomment;
833     $comment = eregi_replace( 'https://([-a-z0-9_./~@?=%#&;\n]+)', '<a'.$target.'href="https://\1">https://\1</a>', $comment);
834     $comment = eregi_replace( 'gopher://([-a-z0-9_./~@?=%\n]+)','<a'.$target.'href="gopher://\1">gopher://\1</a>', $comment);
835     $comment = eregi_replace( 'news://([-a-z0-9_./~@?=%\n]+)','<a'.$target.'href="news://\1">news://\1</a>', $comment);
836     $comment = eregi_replace( 'ftp://([-a-z0-9_./~@?=%\n]+)', '<a'.$target.'href="ftp://\1">ftp://\1</a>', $comment);
837     if(!empty($msgidregex) && ereg($msgidregex, $comment)){
838     //$comment = ereg_replace( $msgidregex, '<a'.$target.'href="http://'.$SERVER_NAME.'/\1">&lt;\1&gt;</a>', $comment);
839     $comment = preg_replace( '/'.$msgidregex.'/e', "'<a$target'.'href=\"../../'.addslashes('$file_article').'/'.urlencode('$group').'/'.urlencode('<\\2>').'.html\">\\1\\2\\3</a>'", $comment);
840     } else{
841     $comment = eregi_replace( '([-a-z0-9_./n]+)@([-a-z0-9_.]+)','<a href="mailto:\1@\2">\1@\2</a>', $comment);
842     }
843     return($comment);
844     }
845    
846    
847    
848    
849     /*
850     * read the header of an article in plaintext into an array
851     * $articleNumber can be the number of an article or its message-id.
852     */
853     function readPlainHeader(&$von,$group,$articleNumber) {
854     fputs($von,"group $group\r\n");
855     $zeile=lieszeile($von);
856     fputs($von,"head $articleNumber\r\n");
857     $zeile=lieszeile($von);
858     if (substr($zeile,0,3) != "221") {
859     echo $text_error["article_not_found"];
860     $header=false;
861     } else {
862     $zeile=lieszeile($von);
863     $body="";
864     while(strcmp(trim($zeile),".") != 0) {
865     $body .= $zeile."\n";
866     $zeile=lieszeile($von);
867     }
868     return split("\n",str_replace("\r\n","\n",$body));
869     }
870     }
871    
872     function readArticles(&$von,$groupname,$articleList) {
873     for($i = 0; $i <= count($articleList)-1 ; $i++) {
874     $temp=read_header($von,$articleList[$i]);
875     $articles[$temp->id] = $temp;
876     }
877     return $articles;
878     }
879    
880     /*
881     * Remove re: aw: etc. from a subject.
882     *
883     * $subject: a string containing the complete Subject
884     *
885     * The function removes the re:, aw: etc. from $subject end returns true
886     * if it removed anything, and false if not.
887     */
888     function splitSubject(&$subject) {
889     $s=eregi_replace('^(aw:|re:|re\[2\]:| )+','',$subject);
890     $return=($s != $subject);
891     $subject=$s;
892     return $return;
893     }
894    
895     function interpretOverviewLine($zeile,$overviewformat,$groupname) {
896     $return="";
897     $overviewfmt=explode("\t",$overviewformat);
898     echo " "; // keep the connection to the webbrowser alive
899     flush(); // while generating the message-tree
900     $over=split("\t",$zeile,count($overviewfmt)-1);
901     $article=new headerType;
902     for ($i=0; $i<count($overviewfmt)-1; $i++) {
903     if ($overviewfmt[$i]=="Subject:") {
904     $subject=headerDecode($over[$i+1]);
905     $article->isReply=splitSubject($subject);
906     $article->subject=$subject;
907     }
908     if ($overviewfmt[$i]=="Date:") {
909     $article->date=getTimestamp($over[$i+1]);
910     }
911     if ($overviewfmt[$i]=="From:") {
912     $fromline=address_decode(headerDecode($over[$i+1]),"nirgendwo");
913     $article->from=$fromline[0]["mailbox"]."@".$fromline[0]["host"];
914     $article->username=$fromline[0]["mailbox"];
915     if (!isset($fromline[0]["personal"])) {
916     $article->name=$fromline[0]["mailbox"];
917     if (strpos($article->name,'%')) {
918     $article->name=substr($article->name,0,strpos($article->name,'%'));
919     }
920     $article->name=strtr($article->name,'_',' ');
921     } else {
922     $article->name=$fromline[0]["personal"];
923     }
924     }
925     if ($overviewfmt[$i]=="Message-ID:") $article->id=$over[$i+1];
926     if (($overviewfmt[$i]=="References:") && ($over[$i+1] != ""))
927     $article->references=explode(" ",$over[$i+1]);
928     }
929     $article->number=$over[0];
930     $article->isAnswer=false;
931     return($article);
932     }
933    
934     /*
935     * Rebuild the Overview-File
936     */
937     function rebuildOverview(&$von,$groupname,$poll) {
938     global $spooldir,$maxarticles,$maxfetch,$initialfetch,$maxarticles_extra;
939     global $text_error,$text_thread,$compress_spoolfiles,$server;
940     $idstring="0.22,".$server.",".$compress_spoolfiles.",".$maxarticles.",".
941     $maxarticles_extra.",".$maxfetch.",".$initialfetch;
942     fputs($von,"list overview.fmt\r\n"); // find out the format of the
943     $tmp=liesZeile($von); // xover-command
944     $zeile=liesZeile($von);
945     while (strcmp($zeile,".") != 0) {
946     $overviewfmt[]=$zeile;
947     $zeile=liesZeile($von);
948     }
949     $overviewformat=implode("\t",$overviewfmt);
950     $spoolfilename=$spooldir."/".$groupname."-data.dat";
951     fputs($von,"group $groupname\r\n"); // select a group
952     $groupinfo=explode(" ",liesZeile($von));
953     if (substr($groupinfo[0],0,1) != 2) {
954     echo "<p>".$text_error["error:"]."</p>";
955     echo "<p>".$text_thread["no_such_group"]."</p>";
956     flush();
957     } else {
958     $infofilename=$spooldir."/".$groupname."-info.txt";
959     $spoolopenmodus="n";
960     if (!((file_exists($infofilename)) && (file_exists($spoolfilename)))) {
961     $spoolopenmodus="w";
962     } else {
963     $infofile=fopen($infofilename,"r");
964     $oldid=fgets($infofile,100);
965     if (trim($oldid) != $idstring) {
966     echo "<!-- Database Error, rebuilding Database...-->\n";
967     $spoolopenmodus="w";
968     }
969     $oldgroupinfo=explode(" ",trim(fgets($infofile,200)));
970     fclose($infofile);
971     if ($groupinfo[3] < $oldgroupinfo[1]) {
972     $spoolopenmodus="w";
973     }
974     if ($maxarticles == 0) {
975     if ($groupinfo[2] != $oldgroupinfo[0]) $spoolopenmodus="w";
976     } else {
977     if ($groupinfo[2] > $oldgroupinfo[0]) $spoolopenmodus="w";
978     }
979     if (($spoolopenmodus == "n") && ($groupinfo[3] > $oldgroupinfo[1]))
980     $spoolopenmodus="a";
981     }
982     if ($spoolopenmodus=="a") {
983     $firstarticle=$oldgroupinfo[1]+1;
984     $lastarticle=$groupinfo[3];
985     }
986     if ($spoolopenmodus=="w") {
987     $firstarticle=$groupinfo[2];
988     $lastarticle=$groupinfo[3];
989     }
990     if ($spoolopenmodus != "n") {
991     if ($maxarticles != 0) {
992     if ($spoolopenmodus == "w") {
993     $firstarticle=$lastarticle-$maxarticles+1;
994     if ($firstarticle < $groupinfo[2])
995     $firstarticle=$groupinfo[2];
996     } else {
997     if ($lastarticle-$oldgroupinfo[0]+1 > $maxarticles + $maxarticles_extra) {
998     $firstarticle=$lastarticle-$maxarticles+1;
999     $spoolopenmodus="w";
1000     }
1001     }
1002     }
1003     if (($maxfetch!=0) && (($lastarticle-$firstarticle+1) > $maxfetch)) {
1004     if ($spoolopenmodus=="w") {
1005     $tofetch=($initialfetch != 0) ? $initialfetch : $maxfetch;
1006     $lastarticle=$firstarticle+$tofetch-1;
1007     } else {
1008     $lastarticle=$firstarticle+$maxfetch-1;
1009     }
1010     }
1011     }
1012     echo "<!--openmodus: ".$spoolopenmodus."-->\n";
1013     if ($spoolopenmodus != "w") $headers=loadThreadData($groupname);
1014     if ($spoolopenmodus != "n") {
1015     fputs($von,"xover ".$firstarticle."-".$lastarticle."\r\n"); // and read the overview
1016     $tmp=liesZeile($von);
1017     if (substr($tmp,0,3) == "224") {
1018     $zeile=liesZeile($von);
1019     while ($zeile != ".") {
1020     $article=interpretOverviewLine($zeile,$overviewformat,$groupname);
1021     $headers[$article->id]=$article;
1022     if($poll) {
1023     echo $article->number.", "; flush();
1024     read_message($article->number,0,$groupname);
1025     }
1026     $zeile=lieszeile($von);
1027     }
1028     }
1029     if (file_exists($spoolfilename)) unlink($spoolfilename);
1030     if (count($headers)>0) {
1031     $infofile=fopen($infofilename,"w");
1032     if ($spoolopenmodus=="a") $firstarticle=$oldgroupinfo[0];
1033     fputs($infofile,$idstring."\n");
1034     fputs($infofile,$firstarticle." ".$lastarticle."\r\n");
1035     fclose($infofile);
1036     reset($headers);
1037     $c=current($headers); // read one article
1038     for ($i=0 ; $i<=count($headers)-1 ; $i++) {
1039     if (($c->isAnswer == false) &&
1040     (isset($c->references[0]))) { // is the article an answer to an
1041     // other article?
1042     $o=count($c->references)-1;
1043     $ref=$c->references[$o];
1044     while (($o >= 0) && (!isset($headers[$ref]))) { // try to find a
1045     $ref=$c->references[$o]; // matching article
1046     $o--; // to the reference
1047     }
1048     if ($o >= 0) { // found a matching article?
1049     $c->isAnswer=true; // so the Article is an answer
1050     $headers[$c->id]=$c;
1051     $headers[$ref]->answers[]=$c->id; // the referenced article gets
1052     // the ID of the article
1053     }
1054     }
1055     $c=next($headers);
1056     }
1057     reset($headers);
1058     saveThreadData($headers,$groupname);
1059     }
1060     }
1061     return((isset($headers)) ? $headers : false);
1062     }
1063     }
1064    
1065    
1066     /*
1067     * Read the Overview.
1068     * Format of the overview-file:
1069     * message-id
1070     * date
1071     * subject
1072     * author
1073     * email
1074     * references
1075     */
1076     function mycompare($a,$b) {
1077     global $thread_sorting;
1078     if ($a->date==$b->date) $r=0;
1079     $r=($a->date<$b->date) ? -1 : 1;
1080     return $r*$thread_sorting;
1081     }
1082     function readOverview(&$von,$groupname,$readmode = 1,$poll=false) {
1083     global $text_error, $maxarticles;
1084     global $spooldir,$thread_sorting;
1085     if (!testGroup($groupname)) {
1086     echo $text_error["read_access_denied"];
1087     return;
1088     }
1089     if ($von == false) return false;
1090     if (($von!=false) && ($readmode > 0))
1091     $articles=rebuildOverview($von,$groupname,$poll);
1092     if ((isset($articles)) && ($articles)) {
1093     if (($thread_sorting != 0) && (count($articles)>0))
1094     uasort($articles,'mycompare');
1095     return $articles;
1096     } else {
1097     return false;
1098     }
1099     }
1100    
1101     function str_change($str,$pos,$char) {
1102     return(substr($str,0,$pos).$char.substr($str,$pos+1,strlen($str)-$pos));
1103     }
1104    
1105     function formatDate($c) {
1106     global $age_count,$age_time,$age_color,$date_format;
1107     $return="";
1108     $currentTime=time();
1109     $color="";
1110     if ($age_count > 0)
1111     for($t = $age_count; $t >= 1; $t--)
1112     if ($currentTime - $c->date < $age_time[$t]) $color = $age_color[$t];
1113     if ($color != "") $return .= '<font color="'.$color.'">';
1114     if (!isset($date_format)) $date_format = "d.m.";
1115     $return .= date($date_format,$c->date); // format the date
1116     if ($color != "") $return .= '</font>';
1117     return($return);
1118     }
1119    
1120     function calculateTree($newtree,$depth,$num,$liste,$c) {
1121     if ((isset($c->answers[0])) && (count($c->answers)>0)) {
1122     $newtree.="*";
1123     } else {
1124     if ($depth == 1) {
1125     $newtree.="o";
1126     } else {
1127     $newtree.="-";
1128     }
1129     }
1130     if (($num == count($liste)-1) && ($depth>1)) {
1131     $newtree=str_change($newtree,$depth-2,"`");
1132     }
1133     return($newtree);
1134     }
1135    
1136    
1137     /*
1138     * Format the message-tree
1139     * Zeichen im Baum:
1140     * o : leerer Kasten k1.gif
1141     * * : Kasten mit Zeichen drin k2.gif
1142     * i : vertikale Linie I.gif
1143     * - : horizontale Linie s.gif
1144     * + : T-Stueck T.gif
1145     * ` : Winkel L.gif
1146     */
1147     function formatTreeGraphic($newtree) {
1148     global $imgdir;
1149     $return="";
1150     for ($o=0 ; $o<strlen($newtree) ; $o++) {
1151     $return .= '<img src="../../'.$imgdir.'/';
1152     $k=substr($newtree,$o,1);
1153     $alt=$k;
1154     switch ($k) {
1155     case "o":
1156     $return .= 'k1.gif';
1157     break;
1158     case "*":
1159     $return .= 'k2.gif';
1160     break;
1161     case "i":
1162     $return .= 'I.gif';
1163     $alt='|';
1164     break;
1165     case "-":
1166     $return .= 's.gif';
1167     break;
1168     case "+":
1169     $return .= 'T.gif';
1170     break;
1171     case "`":
1172     $return .= 'L.gif';
1173     break;
1174     case ".":
1175     $return .= 'e.gif';
1176     $alt='&nbsp;';
1177     break;
1178     }
1179     $return .= '" alt="'.$alt.'"';
1180     if (strcmp($k,".") == 0) $return .=(' width="12" height="9"');
1181     $return .= ' />';
1182     }
1183     return($return);
1184     }
1185    
1186     function formatTreeText($tree) {
1187     $tree=str_replace("i","|",$tree);
1188     $tree=str_replace(".","&nbsp;",$tree);
1189     return($tree);
1190     }
1191    
1192     function formatSubject($c,$group) {
1193     if ($c->isReply) {
1194     $re="Re: ";
1195     } else {
1196     $re="";
1197     }
1198     global $file_article, $thread_maxSubject, $frame_article;
1199     $return='<a ';
1200     if ((isset($frame_article)) && ($frame_article != ""))
1201     $return .= 'target="'.$frame_article.'" ';
1202     $return .= 'href="../../'.$file_article.
1203     // '?id='.urlencode($c->id).'&amp;group='.urlencode($group).'">'.
1204     '/'.urlencode($group).'/'.urlencode($c->number).'.html">'.
1205     $re.htmlspecialchars(substr(trim($c->subject),0,$thread_maxSubject))."</a>";
1206     return($return);
1207     }
1208    
1209     function formatAuthor($c) {
1210     $return = '<a href="mailto:'.trim($c->from).'">';
1211     if (trim($c->name)!="") {
1212     // $return .= htmlspecialchars(trim(mb_convert_encoding($c->name, "EUC-JP", "auto")));
1213     $return .= htmlspecialchars(trim($c->name));
1214     } else {
1215     if (isset($c->username)) {
1216     $s = strpos($c->username,"%");
1217     if ($s != false) {
1218     $return .= htmlspecialchars(substr($c->username,0,$s));
1219     } else {
1220     $return .= htmlspecialchars($c->username);
1221     }
1222     }
1223     }
1224     $return .= "</a>";
1225     return($return);
1226     }
1227    
1228     function showThread(&$headers,&$liste,$depth,$tree,$group,$article_first=0,$article_last=0,&$article_count) {
1229     global $thread_treestyle;
1230     global $thread_showDate,$thread_showSubject;
1231     global $thread_showAuthor,$imgdir;
1232     global $file_article,$thread_maxSubject;
1233     global $age_count,$age_time,$age_color;
1234     global $frame_article,$thread_fontPre,$thread_fontPost;
1235     if ($thread_treestyle==3) echo "\n<UL>\n";
1236     for ($i = 0 ; $i<count($liste) ; $i++) {
1237     $c=$headers[$liste[$i]]; // read the first article
1238     $article_count++;
1239     switch ($thread_treestyle) {
1240     case 4: // thread
1241     case 5: // thread, graphic
1242     case 6: // thread, table
1243     case 7: // thread, table, graphic
1244     $newtree=calculateTree($tree,$depth,$i,$liste,$c);
1245     }
1246     if (($article_first == 0) ||
1247     (($article_count >= $article_first) &&
1248     ($article_count <= $article_last))) {
1249     switch ($thread_treestyle) {
1250     case 0: // simple list
1251     echo $thread_fontPre;
1252     if ($thread_showDate) echo formatDate($c)." ";
1253     if ($thread_showSubject) echo formatSubject($c,$group)." ";
1254     if ($thread_showAuthor) echo "(".formatAuthor($c).")";
1255     echo $thread_fontPost;
1256     echo "<br>\n";
1257     break;
1258     case 1: // html-auflistung, kein baum
1259     echo "<li><nobr>".$thread_fontPre;
1260     if ($thread_showDate)
1261     echo formatDate($c)." ";
1262     if ($thread_showSubject)
1263     echo formatSubject($c,$group)." ";
1264     if ($thread_showAuthor)
1265     echo "<i>(".formatAuthor($c).")</i>";
1266     echo $thread_fontPost."</nobr></li>";
1267     break;
1268     case 2: // table
1269     echo "<tr>";
1270     if ($thread_showDate)
1271     echo "<td>".$thread_fontPre.formatDate($c)." ".$thread_fontPost."</td>";
1272     if ($thread_showSubject) {
1273     echo '<td nowrap="nowrap">'.$thread_fontPre.formatSubject($c,$group);
1274     echo $thread_fontPost."</td>";
1275     }
1276     if ($thread_showAuthor) {
1277     echo "<td></td>";
1278     echo '<td nowrap="nowrap">'.$thread_fontPre.formatAuthor($c);
1279     echo $thread_fontPost."</td>";
1280     }
1281     echo "</tr>\n";
1282     break;
1283     case 3: // html-tree
1284     echo "<li><nobr>".$thread_fontPre;
1285     if ($thread_showDate)
1286     echo formatDate($c)." ";
1287     if ($thread_showSubject)
1288     echo formatSubject($c,$group)." ";
1289     if ($thread_showAuthor)
1290     echo "<i>(".formatAuthor($c).")</i>";
1291     echo $thread_fontPost."</nobr>\n";
1292     break;
1293     case 4: // thread
1294     echo "<nobr><tt>".$thread_fontPre;
1295     if ($thread_showDate)
1296     echo formatDate($c)." ";
1297     echo formatTreeText($newtree)." ";
1298     if ($thread_showSubject)
1299     echo formatSubject($c,$group)." ";
1300     if ($thread_showAuthor)
1301     echo "<i>(".formatAuthor($c).")</i>";
1302     echo $thread_fontPost."</tt></nobr><br>";
1303     break;
1304     case 5: // thread, graphic
1305     echo "<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\"><tr>\n";
1306     if ($thread_showDate)
1307     echo '<td nowrap="nowrap">'.$thread_fontPre.formatDate($c)." ".$thread_fontPost."</td>";
1308     echo "<td>".$thread_fontPre.formatTreeGraphic($newtree).$thread_fontPost."</td>";
1309     if ($thread_showSubject)
1310     echo '<td nowrap="nowrap">'.$thread_fontPre."&nbsp;".formatSubject($c,$group)." ";
1311     if ($thread_showAuthor)
1312     echo "(".formatAuthor($c).")".$thread_fontPost."</td>";
1313     echo "</tr></table>";
1314     break;
1315     case 6: // thread, table
1316     echo "<tr>";
1317     if ($thread_showDate)
1318     echo '<td nowrap="nowrap"><tt>'.$thread_fontPre.formatDate($c)." ".$thread_fontPost."</tt></td>";
1319     echo '<td nowrap="nowrap"><tt>'.$thread_fontPre.formatTreeText($newtree)." ";
1320     if ($thread_showSubject) {
1321     echo formatSubject($c,$group).$thread_fontPost."</tt></td>";
1322     echo "<td></td>";
1323     }
1324     if ($thread_showAuthor)
1325     echo '<td nowrap="nowrap"><tt>'.$thread_fontPre.formatAuthor($c).$thread_fontPost."</tt></td>";
1326     echo "</tr>";
1327     break;
1328     case 7: // thread, table, graphic
1329     echo "<tr>";
1330     if ($thread_showDate)
1331     echo '<td nowrap="nowrap">'.$thread_fontPre.formatDate($c)." ".$thread_fontPost."</td>";
1332     echo "<td><table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n";
1333     echo "<td>".formatTreeGraphic($newtree)."</td>";
1334     if ($thread_showSubject)
1335     echo '<td nowrap="nowrap">'.$thread_fontPre."&nbsp;".formatSubject($c,$group).$thread_fontPost."</td>";
1336     echo "</table></td>";
1337     if ($thread_showSubject) echo "<td></td>";
1338     if ($thread_showAuthor)
1339     echo '<td nowrap="nowrap">'.$thread_fontPre.formatAuthor($c).$thread_fontPost."</td>";
1340     echo "</tr>";
1341     break;
1342     }
1343     }
1344     if ((isset($c->answers[0])) && (count($c->answers)>0) &&
1345     ($article_count<=$article_last)) {
1346     if ($thread_treestyle >= 4) {
1347     if (substr($newtree,$depth-2,1) == "+")
1348     $newtree=str_change($newtree,$depth-2,"i");
1349     $newtree=str_change($newtree,$depth-1,"+");
1350     $newtree=strtr($newtree,"`",".");
1351     }
1352     if (!isset($newtree)) $newtree="";
1353     showThread($headers,$c->answers,$depth+1,$newtree."",$group,
1354     $article_first,$article_last,$article_count);
1355     }
1356     flush();
1357     }
1358     if ($thread_treestyle==3) echo "</UL>";
1359     }
1360    
1361    
1362     /*
1363     * Load a thread from disk
1364     *
1365     * $group: name of the newsgroup, is needed to create the filename
1366     *
1367     * the function returns an array of headerType containing the
1368     * overview-data of the thread.
1369     */
1370     function loadThreadData($group) {
1371     global $spooldir,$compress_spoolfiles;
1372     $filename=$spooldir."/".$group."-data.dat";
1373     if ($compress_spoolfiles) {
1374     $file=gzopen("$spooldir/$group-data.dat","r");
1375     $headers=unserialize(gzread($file,1000000));
1376     gzclose($file);
1377     } else {
1378     $file=fopen($filename,"r");
1379     $headers=unserialize(fread($file,filesize($filename)));
1380     fclose($file);
1381     }
1382     return($headers);
1383     }
1384    
1385    
1386     /*
1387     * Save the thread to disk
1388     *
1389     * $header: is an array of headerType containing all overview-information
1390     * of a newsgroup
1391     * $group: name of the newsgroup, is needed to create the filename
1392     */
1393     function saveThreadData($headers,$group) {
1394     global $spooldir,$compress_spoolfiles;
1395     if ($compress_spoolfiles) {
1396     $file=gzopen("$spooldir/$group-data.dat","w");
1397     gzputs($file,serialize($headers));
1398     gzclose($file);
1399     } else {
1400     $file=fopen("$spooldir/$group-data.dat","w");
1401     fputs($file,serialize($headers));
1402     fclose($file);
1403     }
1404     }
1405    
1406    
1407     function showHeaders(&$headers,$group,$article_first=0,$article_last=0) {
1408     global $thread_showDate, $thread_showTable;
1409     global $thread_showAuthor,$thread_showSubject;
1410     global $text_thread,$thread_treestyle;
1411     $article_count=0;
1412     if ($headers == false) {
1413     echo $text_thread["no_articles"];
1414     } else {
1415     reset($headers);
1416     $c=current($headers);
1417     for ($i=0; $i<=count($headers)-1; $i++) { // create the array $liste
1418     if ($c->isAnswer == false) { // where are all the articles
1419     $liste[]=$c->id; // in that don't have
1420     } // references
1421     $c=next($headers);
1422     }
1423     reset($liste);
1424     if (count($liste)>0) {
1425     if (($thread_treestyle==2) || ($thread_treestyle==6) ||
1426     ($thread_treestyle==7)) {
1427     echo "<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n";
1428     echo "<tr>\n";
1429     if ($thread_showDate) echo "<td>".$text_thread["date"]."&nbsp;</td>";
1430     if ($thread_showSubject) echo "<td>".$text_thread["subject"]."</td>";
1431     if ($thread_showAuthor) {
1432     echo "<td>&nbsp;&nbsp;</td>";
1433     echo "<td>".$text_thread["author"]."</td>\n";
1434     }
1435     echo "</tr>\n";
1436     showThread($headers,$liste,1,"",$group,$article_first,$article_last,
1437     $article_count);
1438     echo "</table>\n";
1439     } else {
1440     if ($thread_treestyle==1) echo "<ul>\n";
1441     showThread($headers,$liste,1,"",$group,$article_first,$article_last,
1442     $article_count);
1443     if ($thread_treestyle==1) echo "</ul>\n";
1444     }
1445     }
1446     }
1447     }
1448    
1449     function MessageIdToUrl($id) {
1450     $id = ereg_replace("^<","",$id);
1451     $id = ereg_replace(">$","",$id);
1452     return urlencode($id);
1453     }
1454    
1455     /*
1456     * Print the header of a message to the webpage
1457     *
1458     * $head: the header of the message as an headerType
1459     * $group: the name of the newsgroup, is needed for the links to post.php3
1460     * and the header.
1461     */
1462     function show_header($head,$group) {
1463     global $article_show,$text_header,$file_article,$attachment_show;
1464     global $file_attachment, $file_article, $server;
1465     if ($article_show["Subject"]) echo $text_header["subject"].htmlspecialchars($head->subject)."<br>";
1466     if ($article_show["From"]) {
1467     echo $text_header["from"].'<a href="mailto:'.htmlspecialchars($head->from).'">'.$head->from.'</a> ';
1468     if ($head->name != "") echo '('.htmlspecialchars($head->name).')';
1469     echo "<br>";
1470     }
1471     if ($article_show["Newsgroups"])
1472     echo $text_header["newsgroups"].htmlspecialchars(str_replace(',',', ',$head->newsgroups))."<br>\n";
1473     if (isset($head->followup) && ($article_show["Followup"]) && ($head->followup != ""))
1474     echo $text_header["followup"].htmlspecialchars($head->followup)."<br>\n";
1475     if ((isset($head->organization)) && ($article_show["Organization"]) &&
1476     ($head->organization != ""))
1477     echo $text_header["organization"].
1478     html_parse(htmlspecialchars($head->organization))."<br>\n";
1479     if ($article_show["Date"])
1480     echo $text_header["date"].date($text_header["date_format"],$head->date)."<br>\n";
1481     if ($article_show["Message-ID"])
1482     $a = MessageIdToUrl($head->id);
1483     echo $text_header["message-id"].htmlspecialchars($head->id)."[".'<a href="http://'.$server.'/'.$a.'">'."HTTP"."</a>][".'<a href="news://'.$server.'/'.$a.'">'."NNTP"."</a>]<br>\n";
1484     if (($article_show["References"]) && (isset($head->references[0]))) {
1485     echo $text_header["references"];
1486     for ($i=0; $i<=count($head->references)-1; $i++) {
1487     $ref=$head->references[$i];
1488     echo ' '.'<a href="../../'.$file_article.'/'.urlencode($group).'/'.
1489     urlencode($ref).'.html">'.($i+1).'</a>';
1490     }
1491     echo "<br>";
1492     }
1493     if (isset($head->user_agent)) {
1494     if ((isset($article_show["User-Agent"])) &&
1495     ($article_show["User-Agent"])) {
1496     echo $text_header["user-agent"].htmlspecialchars($head->user_agent)."<br>\n";
1497     } else {
1498     echo "<!-- User-Agent: ".htmlspecialchars($head->user_agent)." -->\n";
1499     }
1500     }
1501     if ((isset($attachment_show)) && ($attachment_show==true) &&
1502     (isset($head->content_type[1]))) {
1503     echo $text_header["attachments"];
1504     for ($i=1; $i<count($head->content_type); $i++) {
1505     echo '<a href="../../'.$file_attachment.'/'.urlencode($group).'/'.
1506     urlencode($head->number).'/'.
1507     $i.'/'.
1508     urlencode($head->content_type_name[$i]).'">'.
1509     $head->content_type_name[$i].'</a> ('.
1510     $head->content_type[$i].')';
1511     if ($i<count($head->content_type)-1) echo ', ';
1512     }
1513     }
1514     }
1515    
1516    
1517     /*
1518     function showAntwortKnopf($group,$id) {
1519     global $file_post;
1520     echo "<form action=\"$file_post\" method=post>\n";
1521     echo "<input type=submit value=\"Antworten\"\n>";
1522     echo "<input type=hidden name=\"type\" value=\"reply\">\n";
1523     echo "<input type=hidden name=\"id\" value=\"$id\">\n";
1524     echo "<input type=hidden name=\"group\" value=\"$group\">\n";
1525     echo "</form>\n";
1526     }
1527     */
1528    
1529     /*
1530     * print an article to the webpage
1531     *
1532     * $group: The name of the newsgroup
1533     * $id: the ID of the article inside the group or the message-id
1534     * $attachment: The number of the attachment of the article.
1535     * 0 means the normal textbody.
1536     */
1537     function show_article($group,$id,$attachment=0,$article_data=false) {
1538     global $file_article;
1539     global $text_header,$article_showthread;
1540     if ($article_data == false)
1541     $article_data=read_message($id,$attachment,$group);
1542     $head=$article_data->header;
1543     $body=$article_data->body[$attachment];
1544     if ($head!=false) {
1545     if (($head->content_type[$attachment]=="text/plain") &&
1546     ($attachment==0)){
1547     show_header($head,$group);
1548     echo "<pre>\n";
1549     if(count($head->references)){
1550     $refs = $head->references;
1551     array_walk($refs, 'escape_regex');
1552     $msgidregex = "(&lt;|news:)(".join("|", $refs).")(&gt;)?";
1553     $msgidregex = str_replace("><", "|", $msgidregex);
1554     }
1555     $body=split("\n",$body);
1556     for ($i=0; $i<=count($body)-1; $i++) {
1557     // $b=textwrap($body[$i],80,"\n");
1558     // if ((strpos(substr($b,0,strpos($b," ")),'>') != false ) ||
1559     // (strcmp(substr($b,0,1),'>') == 0) ||
1560     // (strcmp(substr($b,0,1),':') == 0)) {
1561     // echo "<i>".html_parse(htmlspecialchars($b))."</i>\n";
1562     // } else {
1563     // echo html_parse(htmlspecialchars($b)."\n");
1564     // }
1565     // echo $body[$i]."\n";
1566     $b=$body[$i];
1567     echo html_parse(htmlspecialchars($b)."\n", $group, $msgidregex);
1568     }
1569     echo "\n</pre>\n";
1570     } else {
1571     echo $body;
1572     }
1573     }
1574     if ($article_showthread > 0) {
1575     }
1576     }
1577    
1578     function escape_regex(&$value, $key){
1579     $value = QuoteMeta(substr($value, 1, -1));
1580     }
1581    
1582     /*
1583     * Encode lines with 8bit-characters to quote-printable
1584     *
1585     * $line: the to be encoded line
1586     *
1587     * the function returns a sting containing the quoted-printable encoded
1588     * $line
1589     */
1590     function quoted_printable_encode($line) {
1591     $qp_table=array(
1592     '=00', '=01', '=02', '=03', '=04', '=05',
1593     '=06', '=07', '=08', '=09', '=0A', '=0B',
1594     '=0C', '=0D', '=0E', '=0F', '=10', '=11',
1595     '=12', '=13', '=14', '=15', '=16', '=17',
1596     '=18', '=19', '=1A', '=1B', '=1C', '=1D',
1597     '=1E', '=1F', '_', '!', '"', '#',
1598     '$', '%', '&', "'", '(', ')',
1599     '*', '+', ',', '-', '.', '/',
1600     '0', '1', '2', '3', '4', '5',
1601     '6', '7', '8', '9', ':', ';',
1602     '<', '=3D', '>', '=3F', '@', 'A',
1603     'B', 'C', 'D', 'E', 'F', 'G',
1604     'H', 'I', 'J', 'K', 'L', 'M',
1605     'N', 'O', 'P', 'Q', 'R', 'S',
1606     'T', 'U', 'V', 'W', 'X', 'Y',
1607     'Z', '[', '\\', ']', '^', '=5F',
1608     '', 'a', 'b', 'c', 'd', 'e',
1609     'f', 'g', 'h', 'i', 'j', 'k',
1610     'l', 'm', 'n', 'o', 'p', 'q',
1611     'r', 's', 't', 'u', 'v', 'w',
1612     'x', 'y', 'z', '{', '|', '}',
1613     '~', '=7F', '=80', '=81', '=82', '=83',
1614     '=84', '=85', '=86', '=87', '=88', '=89',
1615     '=8A', '=8B', '=8C', '=8D', '=8E', '=8F',
1616     '=90', '=91', '=92', '=93', '=94', '=95',
1617     '=96', '=97', '=98', '=99', '=9A', '=9B',
1618     '=9C', '=9D', '=9E', '=9F', '=A0', '=A1',
1619     '=A2', '=A3', '=A4', '=A5', '=A6', '=A7',
1620     '=A8', '=A9', '=AA', '=AB', '=AC', '=AD',
1621     '=AE', '=AF', '=B0', '=B1', '=B2', '=B3',
1622     '=B4', '=B5', '=B6', '=B7', '=B8', '=B9',
1623     '=BA', '=BB', '=BC', '=BD', '=BE', '=BF',
1624     '=C0', '=C1', '=C2', '=C3', '=C4', '=C5',
1625     '=C6', '=C7', '=C8', '=C9', '=CA', '=CB',
1626     '=CC', '=CD', '=CE', '=CF', '=D0', '=D1',
1627     '=D2', '=D3', '=D4', '=D5', '=D6', '=D7',
1628     '=D8', '=D9', '=DA', '=DB', '=DC', '=DD',
1629     '=DE', '=DF', '=E0', '=E1', '=E2', '=E3',
1630     '=E4', '=E5', '=E6', '=E7', '=E8', '=E9',
1631     '=EA', '=EB', '=EC', '=ED', '=EE', '=EF',
1632     '=F0', '=F1', '=F2', '=F3', '=F4', '=F5',
1633     '=F6', '=F7', '=F8', '=F9', '=FA', '=FB',
1634     '=FC', '=FD', '=FE', '=FF');
1635     // are there "forbidden" characters in the string?
1636     for($i=0; $i<strlen($line) && ord($line[$i])<=127 ; $i++);
1637     if ($i<strlen($line)) { // yes, there are. So lets encode them!
1638     $from=$i;
1639     for($to=strlen($line)-1; ord($line[$to])<=127; $to--);
1640     // lets scan for the start and the end of the to be encoded _words_
1641     for(;$from>0 && $line[$from] != ' '; $from--);
1642     if($from>0) $from++;
1643     for(;$to<strlen($line) && $line[$to] != ' '; $to++);
1644     // split the string into the to be encoded middle and the rest
1645     $begin=substr($line,0,$from);
1646     $middle=substr($line,$from,$to-$from);
1647     $end=substr($line,$to);
1648     // ok, now lets encode $middle...
1649     $newmiddle="";
1650     for($i=0; $i<strlen($middle); $i++)
1651     $newmiddle .= $qp_table[ord($middle[$i])];
1652     // now we glue the parts together...
1653     $line=$begin.'=?ISO-8859-1?Q?'.$newmiddle.'?='.$end;
1654     }
1655     return $line;
1656     }
1657    
1658    
1659    
1660     /*
1661     * Post an article to a newsgroup
1662     *
1663     * $subject: The Subject of the article
1664     * $from: The authors name and email of the article
1665     * $newsgroups: The groups to post to
1666     * $ref: The references of the article
1667     * $body: The article itself
1668     */
1669     function verschicken($subject,$from,$newsgroups,$ref,$body) {
1670     global $server,$port,$send_poster_host,$organization,$text_error;
1671     global $file_footer;
1672     flush();
1673     $ns=OpenNNTPconnection($server,$port);
1674     if ($ns != false) {
1675     fputs($ns,"post\r\n");
1676     $weg=lieszeile($ns);
1677     // fputs($ns,'Subject: '.quoted_printable_encode($subject)."\r\n");
1678     // fputs($ns,'Subject: '.mb_convert_encoding($subject, "ISO-2022-JP", "EUC-JP")."\r\n");
1679     fputs($ns,'Subject: '.mb_encode_mimeheader($subject)."\r\n");
1680     fputs($ns,'From: '.$from."\r\n");
1681     fputs($ns,'Newsgroups: '.$newsgroups."\r\n");
1682     // fputs($ns,"Mime-Version: 1.0\r\n");
1683     // fputs($ns,"Content-Type: text/plain; charset=ISO-8859-1\r\n");
1684     // fputs($ns,"Content-Transfer-Encoding: 8bit\r\n");
1685     fputs($ns,"User-Agent: NewsPortal 0.24pre3\r\n");
1686     if ($send_poster_host)
1687     fputs($ns,'X-HTTP-Posting-Host: '.gethostbyaddr(getenv("REMOTE_ADDR"))."\r\n");
1688     if ($ref!=false) fputs($ns,'References: '.$ref."\r\n");
1689     if (isset($organization))
1690     fputs($ns,'Organization: '.mb_encode_mimeheader($organization)."\r\n");
1691     if ((isset($file_footer)) && ($file_footer!="")) {
1692     $footerfile=fopen($file_footer,"r");
1693     $body.="\n".fread($footerfile,filesize($file_footer));
1694     fclose($footerfile);
1695     }
1696     $body=str_replace("\n.\r","\n..\r",$body);
1697     $body=str_replace("\r",'',$body);
1698     $b=split("\n",$body);
1699     $body="";
1700     for ($i=0; $i<count($b); $i++) {
1701     if ((strpos(substr($b[$i],0,strpos($b[$i]," ")),">") != false ) | (strcmp(substr($b[$i],0,1),">") == 0)) {
1702     $body .= textwrap(stripSlashes($b[$i]),78,"\r\n")."\r\n";
1703     } else {
1704     $body .= textwrap(stripSlashes($b[$i]),74,"\r\n")."\r\n";
1705     }
1706     }
1707     $body = mb_convert_encoding($body, "ISO-2022-JP", "EUC-JP");
1708     fputs($ns,"\r\n".$body."\r\n.\r\n");
1709     $message=lieszeile($ns);
1710     closeNNTPconnection($ns);
1711     } else {
1712     $message=$text_error["post_failed"];
1713     }
1714     return $message . mb_encode_mimeheader($subject) . mb_encode_mimeheader($from);
1715     }
1716    
1717     ?>

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24