HTTP Gateway Version: 0.24pre3 this Script is licensed under the GNU Public License Author: Florian Amrhein eMail: florian.amrhein@gmx.de Homepage: http://floh.gartenhaus.net */ /* * the name and the description of a newsgroup */ class newsgroupType { var $name; var $description; var $count; } /* * Stores a complete article: * - The parsed Header as an headerType * - The bodies and attachments as an array of array of lines */ class messageType { var $header; var $body; } /* * Stores the Header of an article */ class headerType { var $number; // the Number of an article inside a group var $id; // Message-ID var $from; // eMail of the author var $name; // Name of the author var $subject; // the subject var $newsgroups; // the Newsgroups where the article belongs to var $followup; var $date; var $references; var $content_transfer_encoding; var $mime_version; var $content_type; // array, Content-Type of the Body (Index=0) and the // Attachments (Index>0) var $content_type_charset; // like content_type var $content_type_name; // array of the names of the attachments var $content_type_boundary; // The boundary of an multipart-article. var $answers; var $isAnswer; var $username; var $field; var $isReply; } /* * opens the connection to the NNTP-Server * * $server: adress of the NNTP-Server * $port: port of the server */ function OpenNNTPconnection($nserver=0,$nport=0) { global $text_error,$server_auth_user,$server_auth_pass,$readonly; global $server,$port; if ($nserver==0) $nserver=$server; if ($nport==0) $nport=$port; $ns=fsockopen($nserver,$nport); $weg=lieszeile($ns); // kill the first line if (substr($weg,0,2) != "20") { echo "

".$text_error["error:"]."

"; } else { if ($ns != false) { fputs($ns,"mode reader\r\n"); $weg=lieszeile($ns); // and once more if (substr($weg,0,2) != "20") { echo "

".$text_error["error:"]."

"; } } if ((isset($server_auth_user)) && (isset($server_auth_pass)) && ($server_auth_user != "")) { fputs($ns,"authinfo user $server_auth_user\r\n"); $weg=lieszeile($ns); fputs($ns,"authinfo pass $server_auth_pass\r\n"); $weg=lieszeile($ns); if (substr($weg,0,3) != "281") { echo "

".$text_error["error:"]."

"; echo "

".$text_error["auth_error"]."

"; } } } if ($ns==false) echo "

".$text_error["connection_failed"]."

"; return $ns; } /* * Close a NNTP connection * * $ns: the handle of the connection */ function closeNNTPconnection(&$ns) { if ($ns != false) { fputs($ns,"quit\r\n"); fclose($ns); } } /* * Validates an email adress * * $address: a string containing the email-address to be validated * * returns true if the address passes the tests, false otherwise. */ function validate_email($address) { global $validate_email; $return=true; if (($validate_email >= 1) && ($return == true)) $return = (ereg('^[-!#$%&\'*+\\./0-9=?A-Z^_A-z{|}~]+'.'@'. '[-!#$%&\'*+\\/0-9=?A-Z^_A-z{|}~]+\.'. '[-!#$%&\'*+\\./0-9=?A-Z^_A-z{|}~]+$',$address)); if (($validate_email >= 2) && ($return == true)) { $addressarray=address_decode($address,"garantiertungueltig"); $return=checkdnsrr($addressarray[0]["host"],"MX"); if (!$return) $return=checkdnsrr($addressarray[0]["host"],"A"); } return($return); } /* * decodes a block of 7bit-data in uuencoded format to it's original * 8bit format. * The headerline containing filename and permissions doesn't have to * be included. * * $data: The uuencoded data as a string * * returns the 8bit data as a string * * Note: this function is very slow and doesn't recognize incorrect code. */ function uudecode_line($line) { $data=substr($line,1); $length=ord($line[0])-32; $decoded=""; for ($i=0; $i<(strlen($data)>>2); $i++) { $pack=substr($data,$i<<2,4); $upack=""; $bitmaske=0; for ($o=0; $o<4; $o++) { $g=((ord($pack[3-$o])-32)); if ($g==64) $g=0; $bitmaske=$bitmaske | ($g << (6*$o)); } $schablone=255; for ($o=0; $o<3; $o++) { $c=($bitmaske & $schablone) >> ($o << 3); $schablone=($schablone << 8); $upack=chr($c).$upack; } $decoded.=$upack; } $decoded=substr($decoded,0,$length); return $decoded; } function uudecode($data) { $d=explode("\n",$data); $u=""; for ($i=0; $i $articles_per_page) for ($i = 0; $i < $pages; $i++) { echo '['; if ($first != $i*$articles_per_page+1) echo ''; echo ($i*$articles_per_page+1).'-'; if ($i == $pages-1) { echo $article_count; } else { echo ($i+1)*$articles_per_page; } if ($first != $i*$articles_per_page+1) echo ''; echo '] '; } } function testGroup($groupname) { global $testgroup; if ($testgroup) { $gf=fopen("groups.txt","r"); while (!feof($gf)) { $read=trim(lieszeile($gf)); $pos=strpos($read," "); if ($pos != false) { if (substr($read,0,$pos)==trim($groupname)) return true; } else { if ($read == trim($groupname)) return true; } } fclose($gf); return false; } else { return true; } } function testGroups($newsgroups) { $groups=explode(",",$newsgroups); $count=count($groups); $return=""; $o=0; for ($i=0; $i<$count; $i++) { if (testgroup($groups[$i])) { if ($o>0) $return.=","; $o++; $return.=$groups[$i]; } } return($return); } /* * read one line from the NNTP-server */ function lieszeile(&$ns) { if ($ns != false) { $t=str_replace("\n","",str_replace("\r","",fgets($ns,1200))); return $t; } } /* * Split an internet-address string into its parts. An address string could * be for example: * - user@host.domain (Realname) * - "Realname" * - user@host.domain * * The address will be split into user, host (incl. domain) and realname * * $adrstring: The string containing the address in internet format * $defaulthost: The name of the host which should be returned if the * address-string doesn't contain a hostname. * * returns an hash containing the fields "mailbox", "host" and "personal" */ function address_decode($adrstring,$defaulthost) { $parsestring=trim($adrstring); $len=strlen($parsestring); $at_pos=strpos($parsestring,'@'); // find @ $ka_pos=strpos($parsestring,"("); // find ( $kz_pos=strpos($parsestring,')'); // find ) $ha_pos=strpos($parsestring,'<'); // find < $hz_pos=strpos($parsestring,'>'); // find > $space_pos=strpos($parsestring,')'); // find ' ' $email=""; $mailbox=""; $host=""; $personal=""; if ($space_pos != false) { if (($ka_pos != false) && ($kz_pos != false)) { $personal=substr($parsestring,$ka_pos+1,$kz_pos-$ka_pos-1); $email=trim(substr($parsestring,0,$ka_pos-1)); } } else { $email=$adrstring; } if (($ha_pos != false) && ($hz_pos != false)) { $email=trim(substr($parsestring,$ha_pos+1,$hz_pos-$ha_pos-1)); $personal=substr($parsestring,0,$ha_pos-1); } if ($at_pos != false) { $mailbox=substr($email,0,strpos($email,'@')); $host=substr($email,strpos($email,'@')+1); } else { $mailbox=$email; $host=$defaulthost; } $personal=trim($personal); if (substr($personal,0,1) == '"') $personal=substr($personal,1); if (substr($personal,strlen($personal)-1,1) == '"') $personal=substr($personal,0,strlen($personal)-1); $result["mailbox"]=trim($mailbox); $result["host"]=trim($host); // $personal = mb_convert_encoding($personal, "EUC-JP", "auto"); if ($personal!="") $result["personal"]=$personal; $complete[]=$result; return ($complete); } function readGroups($server,$port) { $ns=OpenNNTPconnection($server,$port); if ($ns == false) return false; $gf=fopen("groups.txt","r"); while (!feof($gf)) { $gruppe=new newsgroupType; $tmp=trim(lieszeile($gf)); $pos=strpos($tmp," "); if ($pos != false) { $gruppe->name=substr($tmp,0,$pos); $desc=substr($tmp,$pos); } else { $gruppe->name=$tmp; fputs($ns,"xgtitle $gruppe->name\r\n"); $response=liesZeile($ns); if (strcmp(substr($response,0,3),"282") == 0) { $neu=liesZeile($ns); do { $response=$neu; if ($neu != ".") $neu=liesZeile($ns); } while ($neu != "."); $desc=strrchr($response,"\t"); if (strcmp($response,".") == 0) { $desc="-"; } } else { $desc=$response; } if (strcmp(substr($response,0,3),"500") == 0) $desc="-"; } if (strcmp($desc,"") == 0) $desc="-"; $gruppe->description=$desc; fputs($ns,"group ".$gruppe->name."\r\n"); $response=liesZeile($ns); $t=strchr($response," "); $t=substr($t,1,strlen($t)-1); $gruppe->count=substr($t,0,strpos($t," ")); if ((strcmp(trim($gruppe->name),"") != 0) && (substr($gruppe->name,0,1) != "#")) $newsgroups[]=$gruppe; } fclose($gf); closeNNTPconnection($ns); return $newsgroups; } /* * print the group names from an array to the webpage */ function showgroups($gruppen) { if ($gruppen == false) return; global $file_thread,$text_groups; $c = count($gruppen); echo "\n"; echo "\n"; for($i = 0 ; $i < $c ; $i++) { $g = $gruppen[$i]; echo "\n"; echo "\n"; flush(); } echo "
#".$text_groups["newsgroup"]. "".$text_groups["description"]."
"; echo "$g->count"; echo ''.$g->name."$g->description
\n"; } function encode_newsgroup ($groupname) { return urlencode (str_replace ('.', ':', $groupname)); } /* * gets a list of aviable articles in the group $groupname */ function getArticleList(&$von,$groupname) { fputs($von,"listgroup $groupname \r\n"); $zeile=lieszeile($von); $zeile=lieszeile($von); while(strcmp($zeile,".") != 0) { $articleList[] = trim($zeile); $zeile=lieszeile($von); } if (!isset($articleList)) $articleList="-"; return $articleList; } /* * Decode quoted-printable or base64 encoded headerlines * * $value: The to be decoded line * * returns the decoded line */ function headerDecode($value) { if (eregi('=\?.*\?.\?.*\?=',$value)) { // is there anything encoded? if (eregi('=\?.*\?Q\?.*\?=',$value)) { // quoted-printable decoding $result1=eregi_replace('(.*)=\?.*\?Q\?(.*)\?=(.*)','\1',$value); $result2=eregi_replace('(.*)=\?.*\?Q\?(.*)\?=(.*)','\2',$value); $result3=eregi_replace('(.*)=\?.*\?Q\?(.*)\?=(.*)','\3',$value); $result2=str_replace("_"," ",quoted_printable_decode($result2)); $newvalue=$result1.$result2.$result3; } if (eregi('=\?.*\?B\?.*\?=',$value)) { // base64 decoding $result1=eregi_replace('(.*)=\?.*\?B\?(.*)\?=(.*)','\1',$value); $result2=eregi_replace('(.*)=\?.*\?B\?(.*)\?=(.*)','\2',$value); $result3=eregi_replace('(.*)=\?.*\?B\?(.*)\?=(.*)','\3',$value); $result2=base64_decode($result2); $newvalue=$result1.$result2.$result3; } if (!isset($newvalue)) // nothig of them, must be an unknown encoding... $newvalue=$value; else $newvalue=headerDecode($newvalue); // maybe there are more encoded return(mb_convert_encoding($newvalue, "EUC-JP", "auto")); // parts } else { return(mb_convert_encoding(decode_structured_body($value), "EUC-JP", "auto")); } } function parse_header($hdr,$number="") { for ($i=count($hdr)-1; $i>0; $i--) if (preg_match("/^(\x09|\x20)/",$hdr[$i])) $hdr[$i-1]=$hdr[$i-1].ltrim($hdr[$i]); $header = new headerType; $header->isAnswer=false; for ($count=0;$countfield[strtolower($variable)][] = $value; switch (strtolower($variable)) { case "from": $fromline=address_decode(headerDecode($value),"nirgendwo"); if (!isset($fromline[0]["host"])) $fromline[0]["host"]=""; $header->from=$fromline[0]["mailbox"]."@".$fromline[0]["host"]; $header->username=$fromline[0]["mailbox"]; if (!isset($fromline[0]["personal"])) { $header->name=""; } else { $header->name=$fromline[0]["personal"]; } break; case "message-id": $header->id=$value; break; case "subject": $header->subject = decode_unstructured_body($value); break; case "newsgroups": $header->newsgroups=$value; break; case "content-transfer-encoding": $header->content_transfer_encoding=trim(strtolower($value)); break; case "content-type": $header->content_type=array(); $subheader=split(";",$value); $header->content_type[0]=strtolower(trim($subheader[0])); for ($i=1; $icontent_type_charset=array(strtolower($subvalue)); break; case "name": $header->content_type_name=array($subvalue); break; case "boundary": $header->content_type_boundary=$subvalue; } } } break; case "references": $ref=ereg_replace("> *<", "> <", trim($value)); while (strpos($ref,"> <") != false) { $header->references[]=substr($ref,0,strpos($ref," ")); $ref=substr($ref,strpos($ref,"> <")+2); } $header->references[]=trim($ref); break; case "date": $header->date = strtotime(trim($value)); break; case "followup-to": $header->followup=trim($value); break; /* case "x-newsreader": case "x-mailer": case "user-agent": $header->user_agent= decode_structured_body($value); break; */ } } if (!isset($header->content_type[0])) $header->content_type[0]="text/plain"; if (!isset($header->content_transfer_encoding)) $header->content_transfer_encoding="8bit"; if ($number != "") $header->number=$number; return $header; } function decode_unstructured_body ($body) { $patterns = array ( "/(=\\?[^\\x00-\\x20()<>@,;:\\\"\\/\\[\\]?.=\\x7F]+\\?[BQ]\\?[^\\x00-\\x20\\x3F\\x7F]*\\?=)/ei", ); $replace = array ( "mb_decode_mimeheader('\\1')", ); return preg_replace ($patterns, $replace, mb_convert_encoding(fake_jisx0213($body), "EUC-JP", "auto")); } function decode_structured_body ($body) { $patterns = array ( "/\"((?:[^\"\\\\]+|\\\\.)*)\"/e", "/\(((?:[^()\\\\]+|\\\\.|(?:\((?:[^()\\\\]+|\\\\.|(?:\((?:[^)\\\\]+|\\\\.\ )*\)))*\)))*)\)/e", ); $replace = array ( "mb_convert_encoding(fake_jisx0213(decode_quoted_pair('\\1')),'EUC-JP','auto')", "'('.mb_convert_encoding(fake_jisx0213(decode_quoted_pair('\\1')), 'EUC-JP','auto').')'", ); return preg_replace ($patterns, $replace, $body); } function decode_quoted_pair($value) { $value = ereg_replace('\\\\(\\\\")', "\\1", $value); return ereg_replace('\\\\(.)', "\\1", $value); } function fake_jisx0213 ($value) { $value = preg_replace ("/\\x1B\\\$\\(O/", "\x1B\\\$B", $value); $value = preg_replace ("/\\x1B\\\$\\(P/", "\x1B\\\$(D", $value); return $value; } function decode_body($body,$encoding) { $bodyzeile=""; switch ($encoding) { case "base64": $body=base64_decode($body); break; case "quoted-printable": $body=Quoted_printable_decode($body); $body=str_replace("=\n","",$body); // default: // $body=str_replace("\n..\n","\n.\n",$body); } return $body; } function parse_message($rawmessage) { global $attachment_delete_alternative,$attachment_uudecode; // Read the header of the message: $count_rawmessage=count($rawmessage); $message = new messageType; $rawheader=array(); $i=0; while ($rawmessage[$i] != "") { $rawheader[]=$rawmessage[$i]; $i++; } // Parse the Header: $message->header=parse_header($rawheader); // Now we know if the message is a mime-multipart message: $content_type=split("/",$message->header->content_type[0]); if ($content_type[0]=="multipart") { $message->header->content_type=array(); // We have multible bodies, so we split the message into its parts $boundary="--".$message->header->content_type_boundary; // lets find the first part while($rawmessage[$i] != $boundary) $i++; $i++; $part=array(); while($i<=$count_rawmessage) { if (($rawmessage[$i]==$boundary) || ($i==$count_rawmessage-1) || ($rawmessage[$i]==$boundary.'--')) { $partmessage=parse_message($part); // merge the content-types of the message with those of the part for ($o=0; $oheader->content_type); $o++) { $message->header->content_type[]= $partmessage->header->content_type[$o]; $message->header->content_type_charset[]= $partmessage->header->content_type_charset[$o]; $message->header->content_type_name[]= $partmessage->header->content_type_name[$o]; $message->body[]=$partmessage->body[$o]; } $part=array(); } else { if ($i<$count_rawmessage) $part[]=$rawmessage[$i]; } if ($rawmessage[$i]==$boundary.'--') break; $i++; } // Is this a multipart/alternative multipart-message? Do we have to // delete all non plain/text parts? if (($attachment_delete_alternative) && ($content_type[1]=="alternative")) { $plaintext=false; for ($o=0; $oheader->content_type); $o++) { if ($message->header->content_type[$o]=="text/plain") $plaintext=true; // we found at least one text/plain } if ($plaintext) { // now we can delete the other parts for ($o=0; $oheader->content_type); $o++) { if ($message->header->content_type[$o]!="text/plain") { unset($message->header->content_type[$o]); unset($message->header->content_type_name[$o]); unset($message->header->content_type_charset[$o]); unset($message->body[$o]); } } } } } else { // No mime-attachments in the message: $body=""; $uueatt=0; // as default we have no uuencoded attachments for($i++;$i<$count_rawmessage; $i++) { // do we have an inlay uuencoded file? if ((strtolower(substr($rawmessage[$i],0,5))!="begin") || ($attachment_uudecode==false)) { $body.=$rawmessage[$i]."\n"; // yes, it seems, we have! } else { $old_i=$i; $uue_infoline_raw=$rawmessage[$i]; $uue_infoline=explode(" ",$uue_infoline_raw); $uue_data=""; $i++; while($rawmessage[$i]!="end") { if (strlen(trim($rawmessage[$i])) > 2) $uue_data.=$rawmessage[$i]."\n"; $i++; } // now write the data in an attachment $uueatt++; $message->body[$uueatt]=uudecode($uue_data); $message->header->content_type_name[$uueatt]=""; for ($o=2; $oheader->content_type_name[$uueatt].=$uue_infoline[$o]; $message->header->content_type[$uueatt]= get_mimetype_by_filename($message->header->content_type_name[$uueatt]); } } // if ($message->header->content_type[0]=="text/plain") { // $body=trim($body); // if ($body=="") $body=" "; // } $body=decode_body($body,$message->header->content_transfer_encoding); $message->body[0] = mb_convert_encoding($body, "EUC-JP", "auto"); } if (!isset($message->header->content_type_charset)) $message->header->content_type_charset=array("ISO-8859-1"); if (!isset($message->header->content_type_name)) $message->header->content_type_name=array("unnamed"); for ($o=0; $obody); $o++) { if (!isset($message->header->content_type_charset[$o])) $message->header->content_type_charset[$o]="ISO-8859-1"; if (!isset($message->header->content_type_name[$o])) $message->header->content_type_name[$o]="unnamed"; } return $message; } /* * read an article from the newsserver or the spool-directory * * $id: the Message-ID of an article * $bodynum: the number of the attachment: * -1: return only the header without any bodies or attachments. * 0: the body * 1: the first attachment... * * The function returns an article as an messageType or false if the article * doesn't exists on the newsserver or doesn't contain the given * attachment. */ function read_message($id,$bodynum=0,$group="") { global $cache_articles,$spooldir,$text_error; $message = new messageType; if ((isset($cache_articles)) && ($cache_articles == true)) { if ((ereg('^[0-9]+$',$id)) && ($group != '')) $filename=$group.'_'.$id; else $filename=base64_encode($id); $cachefilename_header=$spooldir."/".$filename.'.header'; $cachefilename_body=$spooldir."/".$filename.'.body'; if (file_exists($cachefilename_header)) { $cachefile=fopen($cachefilename_header,"r"); $message->header=unserialize(fread($cachefile,filesize($cachefilename_header))); fclose($cachefile); } else { unset($message->header); } // Is a non-existing attachment of an article requested? if ((isset($message->header)) && ($bodynum!= -1) && (!isset($message->header->content_type[$bodynum]))) return false; if ((file_exists($cachefilename_body.$bodynum)) && ($bodynum != -1)) { $cachefile=fopen($cachefilename_body.$bodynum,"r"); $message->body[$bodynum]= fread($cachefile,filesize($cachefilename_body.$bodynum)); fclose($cachefile); } } if ((!isset($message->header)) || ((!isset($message->body[$bodynum])) && ($bodynum != -1))) { if (!isset($ns)) $ns=openNNTPconnection(); if ($group != "") { fputs($ns,"group ".$group."\r\n"); $zeile=lieszeile($ns); } fputs($ns,'article '.$id."\r\n"); $zeile=lieszeile($ns); if (substr($zeile,0,3) != "220") return false; $rawmessage=array(); $line=lieszeile($ns); #$line=mb_convert_encoding($line, "EUC-JP", "ISO-2022-JP"); while(strcmp($line,".") != 0) { $rawmessage[]=$line; $line=lieszeile($ns); #$line=mb_convert_encoding($line, "EUC-JP", "ISO-2022-JP"); } $message=parse_message($rawmessage); if (ereg('^[0-9]+$',$id)) $message->header->number=$id; // write header, body and attachments to disk if ((isset($cache_articles)) && ($cache_articles == true)) { $cachefile=fopen($cachefilename_header,"w"); if ($cachefile) { fputs($cachefile,serialize($message->header)); } fclose($cachefile); for ($i=0; $iheader->content_type); $i++) { if (isset($message->body[$i])) { $cachefile=fopen($cachefilename_body.$i,"w"); fwrite($cachefile,$message->body[$i]); fclose($cachefile); } } } } return $message; } function textwrap($text, $wrap=80, $break="\n"){ $len = strlen($text); if ($len > $wrap) { $h = ''; // massaged text $lastWhite = 0; // position of last whitespace char $lastChar = 0; // position of last char $lastBreak = 0; // position of last break // while there is text to process while ($lastChar < $len) { $char = substr($text, $lastChar, 1); // get the next character // if we are beyond the wrap boundry and there is a place to break if (($lastChar - $lastBreak > $wrap) && ($lastWhite > $lastBreak)) { $h .= substr($text, $lastBreak, ($lastWhite - $lastBreak)) . $break; $lastChar = $lastWhite + 1; $lastBreak = $lastChar; } // You may wish to include other characters as valid whitespace... if ($char == ' ' || $char == chr(13) || $char == chr(10)) { $lastWhite = $lastChar; // note the position of the last whitespace } $lastChar = $lastChar + 1; // advance the last character position by one } $h .= substr($text, $lastBreak); // build line } else { $h = $text; // in this case everything can fit on one line } return $h; } /* * makes URLs clickable * * $comment: A text-line probably containing links. * * the function returns the text-line with HTML-Links to the links or * email-adresses. */ function html_parse($comment, $group = "", $msgidregex = "") { global $frame_externallink; global $file_article; if ((isset($frame_externallink)) && ($frame_externallink != "")) { $target=' TARGET="'.$frame_externallink.'" '; } else { $target=' '; } $ncomment = eregi_replace( 'http://([-a-z0-9_./~@?=%#&;]+)', 'http://\1', $comment); if ($ncomment == $comment) $ncomment = eregi_replace( '(www\.[-a-z]+\.(de|int|eu|dk|org|net|at|ch|com|jp))','\1',$comment); $comment=$ncomment; $comment = eregi_replace( 'https://([-a-z0-9_./~@?=%#&;\n]+)', 'https://\1', $comment); $comment = eregi_replace( 'gopher://([-a-z0-9_./~@?=%\n]+)','gopher://\1', $comment); $comment = eregi_replace( 'news://([-a-z0-9_./~@?=%\n]+)','news://\1', $comment); $comment = eregi_replace( 'ftp://([-a-z0-9_./~@?=%\n]+)', 'ftp://\1', $comment); if(!empty($msgidregex) && ereg($msgidregex, $comment)){ //$comment = ereg_replace( $msgidregex, '<\1>', $comment); $comment = preg_replace( '/'.$msgidregex.'/e', "'').'.html\">\\1\\2\\3'", $comment); } else{ $comment = eregi_replace( '([-a-z0-9_./n]+)@([-a-z0-9_.]+)','\1@\2', $comment); } return($comment); } function uri_to_link($comment, $group = "", $msgidregex = "") { global $frame_externallink; global $file_article; $comment = preg_replace ( '"((?:https?|mailto|urn|news|ftp|irc|mid|data|nntp|gother)):((?:[-_.!~*\'()A-Z0-9:;@=+$,%?/]+|&)+)(#(?:[-_.!~*\'()A-Z0-9;/?:@&=+$,%]+|&)+)?"ie', 'uri_to_link_uri("\1", "\2", "\3")', $comment); return($comment); } function uri_to_link_uri ($scheme, $body, $fragment) { global $file_article; switch (strtolower($scheme)) { case "urn": case "data": $uri = '/uri-res/N2L?'.urlencode($scheme.':'.$body); break; case "news": if (!preg_match('"^//"', $body)) { $uri = "../../".addslashes($file_article).'/junk/%3C'.$nbody.'%3E'; } else { $uri = $scheme.':'.$body; } break; case "mid": $nbody = preg_replace('"/.*$"', "", $body); $uri = "../../".addslashes($file_article).'/junk/%3C'.$nbody.'%3E'; break; default: $uri = $scheme.':'.$body; break; } $uri = $uri . $fragment; if (!empty($uri)) { $uri = ''.$scheme.':'.$body.$fragment.''; } return $uri; } /* * read the header of an article in plaintext into an array * $articleNumber can be the number of an article or its message-id. */ function readPlainHeader(&$von,$group,$articleNumber) { fputs($von,"group $group\r\n"); $zeile=lieszeile($von); fputs($von,"head $articleNumber\r\n"); $zeile=lieszeile($von); if (substr($zeile,0,3) != "221") { echo $text_error["article_not_found"]; $header=false; } else { $zeile=lieszeile($von); $body=""; while(strcmp(trim($zeile),".") != 0) { $body .= $zeile."\n"; $zeile=lieszeile($von); } return split("\n",str_replace("\r\n","\n",$body)); } } function readArticles(&$von,$groupname,$articleList) { for($i = 0; $i <= count($articleList)-1 ; $i++) { $temp=read_header($von,$articleList[$i]); $articles[$temp->id] = $temp; } return $articles; } /* * Remove re: aw: etc. from a subject. * * $subject: a string containing the complete Subject * * The function removes the re:, aw: etc. from $subject end returns true * if it removed anything, and false if not. */ function splitSubject(&$subject) { $s=eregi_replace('^(aw:|re:|re\[2\]:| )+','',$subject); $return=($s != $subject); $subject=$s; return $return; } function interpretOverviewLine($zeile,$overviewformat,$groupname) { $return=""; $overviewfmt=explode("\t",$overviewformat); echo " "; // keep the connection to the webbrowser alive flush(); // while generating the message-tree $over=split("\t",$zeile,count($overviewfmt)-1); $article=new headerType; for ($i=0; $iisReply=splitSubject($subject); $article->subject=$subject; } if ($overviewfmt[$i]=="Date:") { $article->date = strtotime($over[$i+1]); } if ($overviewfmt[$i]=="From:") { $fromline=address_decode(headerDecode($over[$i+1]),"nirgendwo"); $article->from=$fromline[0]["mailbox"]."@".$fromline[0]["host"]; $article->username=$fromline[0]["mailbox"]; if (!isset($fromline[0]["personal"])) { $article->name=$fromline[0]["mailbox"]; if (strpos($article->name,'%')) { $article->name=substr($article->name,0,strpos($article->name,'%')); } $article->name=strtr($article->name,'_',' '); } else { $article->name=$fromline[0]["personal"]; } } if ($overviewfmt[$i]=="Message-ID:") $article->id=$over[$i+1]; if (($overviewfmt[$i]=="References:") && ($over[$i+1] != "")) $article->references=explode(" ",$over[$i+1]); } $article->number=$over[0]; $article->isAnswer=false; return($article); } /* * Rebuild the Overview-File */ function rebuildOverview(&$von,$groupname,$poll) { global $spooldir,$maxarticles,$maxfetch,$initialfetch,$maxarticles_extra; global $text_error,$text_thread,$compress_spoolfiles,$server; $idstring="0.22,".$server.",".$compress_spoolfiles.",".$maxarticles.",". $maxarticles_extra.",".$maxfetch.",".$initialfetch; fputs($von,"list overview.fmt\r\n"); // find out the format of the $tmp=liesZeile($von); // xover-command $zeile=liesZeile($von); while (strcmp($zeile,".") != 0) { $overviewfmt[]=$zeile; $zeile=liesZeile($von); } $overviewformat=implode("\t",$overviewfmt); $spoolfilename=$spooldir."/".$groupname."-data.dat"; fputs($von,"group $groupname\r\n"); // select a group $groupinfo=explode(" ",liesZeile($von)); if (substr($groupinfo[0],0,1) != 2) { echo "

".$text_error["error:"]."

"; echo "

".$text_thread["no_such_group"]."

"; flush(); } else { $infofilename=$spooldir."/".$groupname."-info.txt"; $spoolopenmodus="n"; if (!((file_exists($infofilename)) && (file_exists($spoolfilename)))) { $spoolopenmodus="w"; } else { $infofile=fopen($infofilename,"r"); $oldid=fgets($infofile,100); if (trim($oldid) != $idstring) { echo "\n"; $spoolopenmodus="w"; } $oldgroupinfo=explode(" ",trim(fgets($infofile,200))); fclose($infofile); if ($groupinfo[3] < $oldgroupinfo[1]) { $spoolopenmodus="w"; } if ($maxarticles == 0) { if ($groupinfo[2] != $oldgroupinfo[0]) $spoolopenmodus="w"; } else { if ($groupinfo[2] > $oldgroupinfo[0]) $spoolopenmodus="w"; } if (($spoolopenmodus == "n") && ($groupinfo[3] > $oldgroupinfo[1])) $spoolopenmodus="a"; } if ($spoolopenmodus=="a") { $firstarticle=$oldgroupinfo[1]+1; $lastarticle=$groupinfo[3]; } if ($spoolopenmodus=="w") { $firstarticle=$groupinfo[2]; $lastarticle=$groupinfo[3]; } if ($spoolopenmodus != "n") { if ($maxarticles != 0) { if ($spoolopenmodus == "w") { $firstarticle=$lastarticle-$maxarticles+1; if ($firstarticle < $groupinfo[2]) $firstarticle=$groupinfo[2]; } else { if ($lastarticle-$oldgroupinfo[0]+1 > $maxarticles + $maxarticles_extra) { $firstarticle=$lastarticle-$maxarticles+1; $spoolopenmodus="w"; } } } if (($maxfetch!=0) && (($lastarticle-$firstarticle+1) > $maxfetch)) { if ($spoolopenmodus=="w") { $tofetch=($initialfetch != 0) ? $initialfetch : $maxfetch; $lastarticle=$firstarticle+$tofetch-1; } else { $lastarticle=$firstarticle+$maxfetch-1; } } } echo "\n"; if ($spoolopenmodus != "w") $headers=loadThreadData($groupname); if ($spoolopenmodus != "n") { fputs($von,"xover ".$firstarticle."-".$lastarticle."\r\n"); // and read the overview $tmp=liesZeile($von); if (substr($tmp,0,3) == "224") { $zeile=liesZeile($von); while ($zeile != ".") { $article=interpretOverviewLine($zeile,$overviewformat,$groupname); $headers[$article->id]=$article; if($poll) { echo $article->number.", "; flush(); read_message($article->number,0,$groupname); } $zeile=lieszeile($von); } } if (file_exists($spoolfilename)) unlink($spoolfilename); if (count($headers)>0) { $infofile=fopen($infofilename,"w"); if ($spoolopenmodus=="a") $firstarticle=$oldgroupinfo[0]; fputs($infofile,$idstring."\n"); fputs($infofile,$firstarticle." ".$lastarticle."\r\n"); fclose($infofile); reset($headers); $c=current($headers); // read one article for ($i=0 ; $i<=count($headers)-1 ; $i++) { if (($c->isAnswer == false) && (isset($c->references[0]))) { // is the article an answer to an // other article? $o=count($c->references)-1; $ref=$c->references[$o]; while (($o >= 0) && (!isset($headers[$ref]))) { // try to find a $ref=$c->references[$o]; // matching article $o--; // to the reference } if ($o >= 0) { // found a matching article? $c->isAnswer=true; // so the Article is an answer $headers[$c->id]=$c; $headers[$ref]->answers[]=$c->id; // the referenced article gets // the ID of the article } } $c=next($headers); } reset($headers); saveThreadData($headers,$groupname); } } return((isset($headers)) ? $headers : false); } } /* * Read the Overview. * Format of the overview-file: * message-id * date * subject * author * email * references */ function mycompare($a,$b) { global $thread_sorting; if ($a->date==$b->date) $r=0; $r=($a->date<$b->date) ? -1 : 1; return $r*$thread_sorting; } function readOverview(&$von,$groupname,$readmode = 1,$poll=false) { global $text_error, $maxarticles; global $spooldir,$thread_sorting; if (!testGroup($groupname)) { echo $text_error["read_access_denied"]; return; } if ($von == false) return false; if (($von!=false) && ($readmode > 0)) $articles=rebuildOverview($von,$groupname,$poll); if ((isset($articles)) && ($articles)) { if (($thread_sorting != 0) && (count($articles)>0)) uasort($articles,'mycompare'); return $articles; } else { return false; } } function str_change($str,$pos,$char) { return(substr($str,0,$pos).$char.substr($str,$pos+1,strlen($str)-$pos)); } function formatDate($c) { global $age_count,$age_time,$age_color,$date_format; $return=""; $currentTime=time(); $color=""; if ($age_count > 0) for($t = $age_count; $t >= 1; $t--) if ($currentTime - $c->date < $age_time[$t]) $color = $age_color[$t]; if ($color != "") $return .= ''; if (!isset($date_format)) $date_format = "d.m."; $return .= date($date_format,$c->date); // format the date if ($color != "") $return .= ''; return($return); } function calculateTree($newtree,$depth,$num,$liste,$c) { if ((isset($c->answers[0])) && (count($c->answers)>0)) { $newtree.="*"; } else { if ($depth == 1) { $newtree.="o"; } else { $newtree.="-"; } } if (($num == count($liste)-1) && ($depth>1)) { $newtree=str_change($newtree,$depth-2,"`"); } return($newtree); } /* * Format the message-tree * Zeichen im Baum: * o : leerer Kasten k1.gif * * : Kasten mit Zeichen drin k2.gif * i : vertikale Linie I.gif * - : horizontale Linie s.gif * + : T-Stueck T.gif * ` : Winkel L.gif */ function formatTreeGraphic($newtree) { global $imgdir; $return=""; for ($o=0 ; $oisReply) { $re="Re: "; } else { $re=""; } global $file_article, $thread_maxSubject, $frame_article; $return=''. '/'.urlencode($group).'/'.urlencode($c->number).'.html">'. $re.htmlspecialchars(substr(trim($c->subject),0,$thread_maxSubject)).""; return($return); } function formatAuthor($c) { $return = ''; if (trim($c->name)!="") { // $return .= htmlspecialchars(trim(mb_convert_encoding($c->name, "EUC-JP", "auto"))); $return .= htmlspecialchars(trim($c->name)); } else { if (isset($c->username)) { $s = strpos($c->username,"%"); if ($s != false) { $return .= htmlspecialchars(substr($c->username,0,$s)); } else { $return .= htmlspecialchars($c->username); } } } $return .= ""; return($return); } function showThread(&$headers,&$liste,$depth,$tree,$group,$article_first=0,$article_last=0,&$article_count) { global $thread_treestyle; global $thread_showDate,$thread_showSubject; global $thread_showAuthor,$imgdir; global $file_article,$thread_maxSubject; global $age_count,$age_time,$age_color; global $frame_article,$thread_fontPre,$thread_fontPost; if ($thread_treestyle==3) echo "\n
    \n"; for ($i = 0 ; $i= $article_first) && ($article_count <= $article_last))) { switch ($thread_treestyle) { case 0: // simple list echo $thread_fontPre; if ($thread_showDate) echo formatDate($c)." "; if ($thread_showSubject) echo formatSubject($c,$group)." "; if ($thread_showAuthor) echo "(".formatAuthor($c).")"; echo $thread_fontPost; echo "
    \n"; break; case 1: // html-auflistung, kein baum echo "
  • ".$thread_fontPre; if ($thread_showDate) echo formatDate($c)." "; if ($thread_showSubject) echo formatSubject($c,$group)." "; if ($thread_showAuthor) echo "(".formatAuthor($c).")"; echo $thread_fontPost."
  • "; break; case 2: // table echo ""; if ($thread_showDate) echo "".$thread_fontPre.formatDate($c)." ".$thread_fontPost.""; if ($thread_showSubject) { echo ''.$thread_fontPre.formatSubject($c,$group); echo $thread_fontPost.""; } if ($thread_showAuthor) { echo ""; echo ''.$thread_fontPre.formatAuthor($c); echo $thread_fontPost.""; } echo "\n"; break; case 3: // html-tree echo "
  • ".$thread_fontPre; if ($thread_showDate) echo formatDate($c)." "; if ($thread_showSubject) echo formatSubject($c,$group)." "; if ($thread_showAuthor) echo "(".formatAuthor($c).")"; echo $thread_fontPost."\n"; break; case 4: // thread echo "".$thread_fontPre; if ($thread_showDate) echo formatDate($c)." "; echo formatTreeText($newtree)." "; if ($thread_showSubject) echo formatSubject($c,$group)." "; if ($thread_showAuthor) echo "(".formatAuthor($c).")"; echo $thread_fontPost."
    "; break; case 5: // thread, graphic echo "\n"; if ($thread_showDate) echo '"; echo ""; if ($thread_showSubject) echo '"; echo "
    '.$thread_fontPre.formatDate($c)." ".$thread_fontPost."".$thread_fontPre.formatTreeGraphic($newtree).$thread_fontPost."'.$thread_fontPre." ".formatSubject($c,$group)." "; if ($thread_showAuthor) echo "(".formatAuthor($c).")".$thread_fontPost."
    "; break; case 6: // thread, table echo ""; if ($thread_showDate) echo ''.$thread_fontPre.formatDate($c)." ".$thread_fontPost.""; echo ''.$thread_fontPre.formatTreeText($newtree)." "; if ($thread_showSubject) { echo formatSubject($c,$group).$thread_fontPost.""; echo ""; } if ($thread_showAuthor) echo ''.$thread_fontPre.formatAuthor($c).$thread_fontPost.""; echo ""; break; case 7: // thread, table, graphic echo ""; if ($thread_showDate) echo ''.$thread_fontPre.formatDate($c)." ".$thread_fontPost.""; echo "\n"; echo ""; if ($thread_showSubject) echo '"; echo "
    ".formatTreeGraphic($newtree)."'.$thread_fontPre." ".formatSubject($c,$group).$thread_fontPost."
    "; if ($thread_showSubject) echo ""; if ($thread_showAuthor) echo ''.$thread_fontPre.formatAuthor($c).$thread_fontPost.""; echo ""; break; } } if ((isset($c->answers[0])) && (count($c->answers)>0) && ($article_count<=$article_last)) { if ($thread_treestyle >= 4) { if (substr($newtree,$depth-2,1) == "+") $newtree=str_change($newtree,$depth-2,"i"); $newtree=str_change($newtree,$depth-1,"+"); $newtree=strtr($newtree,"`","."); } if (!isset($newtree)) $newtree=""; showThread($headers,$c->answers,$depth+1,$newtree."",$group, $article_first,$article_last,$article_count); } flush(); } if ($thread_treestyle==3) echo "
"; } /* * Load a thread from disk * * $group: name of the newsgroup, is needed to create the filename * * the function returns an array of headerType containing the * overview-data of the thread. */ function loadThreadData($group) { global $spooldir,$compress_spoolfiles; $filename=$spooldir."/".$group."-data.dat"; if ($compress_spoolfiles) { $file=gzopen("$spooldir/$group-data.dat","r"); $headers=unserialize(gzread($file,1000000)); gzclose($file); } else { $file=fopen($filename,"r"); $headers=unserialize(fread($file,filesize($filename))); fclose($file); } return($headers); } /* * Save the thread to disk * * $header: is an array of headerType containing all overview-information * of a newsgroup * $group: name of the newsgroup, is needed to create the filename */ function saveThreadData($headers,$group) { global $spooldir,$compress_spoolfiles; if ($compress_spoolfiles) { $file=gzopen("$spooldir/$group-data.dat","w"); gzputs($file,serialize($headers)); gzclose($file); } else { $file=fopen("$spooldir/$group-data.dat","w"); fputs($file,serialize($headers)); fclose($file); } } function showHeaders(&$headers,$group,$article_first=0,$article_last=0) { global $thread_showDate, $thread_showTable; global $thread_showAuthor,$thread_showSubject; global $text_thread,$thread_treestyle; $article_count=0; if ($headers == false) { echo $text_thread["no_articles"]; } else { reset($headers); $c=current($headers); for ($i=0; $i<=count($headers)-1; $i++) { // create the array $liste if ($c->isAnswer == false) { // where are all the articles $liste[]=$c->id; // in that don't have } // references $c=next($headers); } reset($liste); if (count($liste)>0) { if (($thread_treestyle==2) || ($thread_treestyle==6) || ($thread_treestyle==7)) { echo "\n"; echo "\n"; if ($thread_showDate) echo ""; if ($thread_showSubject) echo ""; if ($thread_showAuthor) { echo ""; echo "\n"; } echo "\n"; showThread($headers,$liste,1,"",$group,$article_first,$article_last, $article_count); echo "
".$text_thread["date"]." ".$text_thread["subject"]."  ".$text_thread["author"]."
\n"; } else { if ($thread_treestyle==1) echo "
    \n"; showThread($headers,$liste,1,"",$group,$article_first,$article_last, $article_count); if ($thread_treestyle==1) echo "
\n"; } } } } function MessageIdToUrl($id) { $id = ereg_replace("^<","",$id); $id = ereg_replace(">$","",$id); return urlencode($id); } /* * Print the header of a message to the webpage * * $head: the header of the message as an headerType * $group: the name of the newsgroup, is needed for the links to post.php3 * and the header. */ function show_header($head,$group) { global $article_show,$text_header,$file_article,$attachment_show; global $file_attachment, $file_article, $server; if ($article_show["Subject"]) echo $text_header["subject"].htmlspecialchars($head->subject)."
"; if ($article_show["From"]) { echo $text_header["from"].''.$head->from.' '; if ($head->name != "") echo '('.htmlspecialchars($head->name).')'; echo "
"; } if ($article_show["Newsgroups"]) echo $text_header["newsgroups"].htmlspecialchars(str_replace(',',', ',$head->newsgroups))."
\n"; if (isset($head->followup) && ($article_show["Followup"]) && ($head->followup != "")) echo $text_header["followup"].htmlspecialchars($head->followup)."
\n"; if ($article_show["Date"]) echo $text_header["date"].date($text_header["date_format"],$head->date)."
\n"; if ($article_show["Message-ID"]) $a = MessageIdToUrl($head->id); echo $text_header["message-id"].htmlspecialchars($head->id)."[".''."HTTP"."][".''."NNTP"."]
\n"; if (($article_show["References"]) && (isset($head->references[0]))) { echo $text_header["references"]; for ($i=0; $i<=count($head->references)-1; $i++) { $ref=$head->references[$i]; echo ' '.''.($i+1).''; } echo "
"; } $fields = array ("x-moe", "x-brother", "x-syster", "x-wife", "x-daughter", "x-respect", "user-agent", "x-mailer", "x-newsreader", "list-id", "x-uri", "x-mail-count", "keywords"); for ($i = 0; $i < count($fields); $i++) { if (count($head->field[$fields[$i]])) { if ((isset($article_show[$fields[$i]])) && ($article_show[$fields[$i]])) { echo "
" .$text_header[$fields[$i]]." " .uri_to_link(htmlspecialchars(decode_structured_body( join(', ', $head->field[$fields[$i]])))) ."
\n"; } } } $fields = array ("x-weather", "x-copyright", "comments", "organization"); for ($i = 0; $i < count($fields); $i++) { if (count($head->field[$fields[$i]])) { if ((isset($article_show[$fields[$i]])) && ($article_show[$fields[$i]])) { for ($j = 0; $j > count($head->field[$fields[$i]]); $j++) { echo "
" .$text_header[$fields[$i]]." " .uri_to_link(htmlspecialchars(decode_unstructured_body( $head->field[$fields[$i]][$j]))) ."
\n"; } } } } if ((isset($attachment_show)) && ($attachment_show==true) && (isset($head->content_type[1]))) { echo $text_header["attachments"]; for ($i=1; $icontent_type); $i++) { echo ''. $head->content_type_name[$i].' ('. $head->content_type[$i].')'; if ($icontent_type)-1) echo ', '; } } } /* function showAntwortKnopf($group,$id) { global $file_post; echo "
\n"; echo ""; echo "\n"; echo "\n"; echo "\n"; echo "
\n"; } */ /* * print an article to the webpage * * $group: The name of the newsgroup * $id: the ID of the article inside the group or the message-id * $attachment: The number of the attachment of the article. * 0 means the normal textbody. */ function show_article($group,$id,$attachment=0,$article_data=false) { global $file_article; global $text_header,$article_showthread; if ($article_data == false) $article_data=read_message($id,$attachment,$group); $head=$article_data->header; $body=$article_data->body[$attachment]; if ($head!=false) { if (($head->content_type[$attachment]=="text/plain") && ($attachment==0)){ show_header($head,$group); echo "
\n";
      if(count($head->references)){
	$refs = $head->references;
	array_walk($refs, 'escape_regex');
	$msgidregex = "(<|news:)(".join("|", $refs).")(>)?";
	$msgidregex = str_replace("><", "|", $msgidregex);
      }
      $body=split("\n",$body);
      for ($i=0; $i<=count($body)-1; $i++) {
//        $b=textwrap($body[$i],80,"\n");
//        if ((strpos(substr($b,0,strpos($b," ")),'>') != false ) ||
//            (strcmp(substr($b,0,1),'>') == 0) ||
//            (strcmp(substr($b,0,1),':') == 0)) {
//          echo "".html_parse(htmlspecialchars($b))."\n";
//        } else {
//          echo html_parse(htmlspecialchars($b)."\n");
//        }
//	echo $body[$i]."\n";
        $b=$body[$i];
        echo uri_to_link(htmlspecialchars($b)."\n", $group, $msgidregex);
      }
      echo "\n
\n"; } else { echo $body; } } if ($article_showthread > 0) { } } function escape_regex(&$value, $key){ $value = QuoteMeta(substr($value, 1, -1)); } /* * Encode lines with 8bit-characters to quote-printable * * $line: the to be encoded line * * the function returns a sting containing the quoted-printable encoded * $line */ function quoted_printable_encode($line) { $qp_table=array( '=00', '=01', '=02', '=03', '=04', '=05', '=06', '=07', '=08', '=09', '=0A', '=0B', '=0C', '=0D', '=0E', '=0F', '=10', '=11', '=12', '=13', '=14', '=15', '=16', '=17', '=18', '=19', '=1A', '=1B', '=1C', '=1D', '=1E', '=1F', '_', '!', '"', '#', '$', '%', '&', "'", '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=3D', '>', '=3F', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '=5F', '', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', '=7F', '=80', '=81', '=82', '=83', '=84', '=85', '=86', '=87', '=88', '=89', '=8A', '=8B', '=8C', '=8D', '=8E', '=8F', '=90', '=91', '=92', '=93', '=94', '=95', '=96', '=97', '=98', '=99', '=9A', '=9B', '=9C', '=9D', '=9E', '=9F', '=A0', '=A1', '=A2', '=A3', '=A4', '=A5', '=A6', '=A7', '=A8', '=A9', '=AA', '=AB', '=AC', '=AD', '=AE', '=AF', '=B0', '=B1', '=B2', '=B3', '=B4', '=B5', '=B6', '=B7', '=B8', '=B9', '=BA', '=BB', '=BC', '=BD', '=BE', '=BF', '=C0', '=C1', '=C2', '=C3', '=C4', '=C5', '=C6', '=C7', '=C8', '=C9', '=CA', '=CB', '=CC', '=CD', '=CE', '=CF', '=D0', '=D1', '=D2', '=D3', '=D4', '=D5', '=D6', '=D7', '=D8', '=D9', '=DA', '=DB', '=DC', '=DD', '=DE', '=DF', '=E0', '=E1', '=E2', '=E3', '=E4', '=E5', '=E6', '=E7', '=E8', '=E9', '=EA', '=EB', '=EC', '=ED', '=EE', '=EF', '=F0', '=F1', '=F2', '=F3', '=F4', '=F5', '=F6', '=F7', '=F8', '=F9', '=FA', '=FB', '=FC', '=FD', '=FE', '=FF'); // are there "forbidden" characters in the string? for($i=0; $i0 && $line[$from] != ' '; $from--); if($from>0) $from++; for(;$to") != false ) | (strcmp(substr($b[$i],0,1),">") == 0)) { $body .= textwrap(stripSlashes($b[$i]),78,"\r\n")."\r\n"; } else { $body .= textwrap(stripSlashes($b[$i]),74,"\r\n")."\r\n"; } } $body = mb_convert_encoding($body, "ISO-2022-JP", "EUC-JP"); fputs($ns,"\r\n".$body."\r\n.\r\n"); $message=lieszeile($ns); closeNNTPconnection($ns); } else { $message=$text_error["post_failed"]; } return $message . mb_encode_mimeheader($subject) . mb_encode_mimeheader($from); } ?>