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