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

Contents of /messaging/newsportal/newsportal.php

Parent Directory Parent Directory | Revision Log Revision Log


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

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

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24