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

Contents of /messaging/newsportal/newsportal.php

Parent Directory Parent Directory | Revision Log Revision Log


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

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24