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

Contents of /messaging/newsportal/newsportal.php

Parent Directory Parent Directory | Revision Log Revision Log


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

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24