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