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

Contents of /messaging/newsportal/newsportal.php

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.9 - (show annotations) (download)
Sat Dec 1 12:28:31 2001 UTC (22 years, 5 months ago) by wakaba
Branch: MAIN
Changes since 1.8: +3 -1 lines
*** empty log message ***

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

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24