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

Contents of /messaging/newsportal/newsportal.php

Parent Directory Parent Directory | Revision Log Revision Log


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

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24