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