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

Contents of /messaging/newsportal/newsportal.php

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.2 - (hide annotations) (download)
Sat Dec 1 11:51:33 2001 UTC (22 years, 5 months ago) by wakaba
Branch: MAIN
Changes since 1.1: +1 -0 lines
*** empty log message ***

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

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24