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

Contents of /messaging/newsportal/newsportal.php

Parent Directory Parent Directory | Revision Log Revision Log


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

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24