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

Contents of /messaging/newsportal/newsportal.php

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.14 - (show annotations) (download)
Sat Dec 1 12:55:49 2001 UTC (22 years, 5 months ago) by wakaba
Branch: MAIN
Changes since 1.13: +11 -6 lines
*** empty log message ***

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

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24