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

Contents of /messaging/newsportal/newsportal.php

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.37 - (show annotations) (download)
Mon Apr 1 01:40:44 2002 UTC (22 years, 1 month ago) by wakaba
Branch: MAIN
CVS Tags: HEAD
Changes since 1.36: +1 -1 lines
2002-04-01  wakaba <w@suika.fam.cx>

	* group.txt: Checkgroups'ed suika.*.

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

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24