#!/usr/bin/php 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 $content_type_format; // array, is the body in flowed format? var $answers; // which articles are followups of this article? var $isAnswer; // is the article an answer to an other article? var $username; var $user_agent; var $isReply; // has this article "Re: " at the beginning of the subject? var $threadsize; // number of articles in this thread } $data = vichan_message_read($argv[1], $argv[2]); echo serialize($data); exit(); function vichan_message_read($id, $group) { $spooldir="/var/spool/rslight/articles/"; $spoolpath=$spooldir; $message = new messageType; $articlepath = $spoolpath.preg_replace('/\./', '/', $group)."/".$id; if (file_exists($articlepath)) { $rawmessage_fh = fopen($articlepath, "r"); $rawmessage=array(); $line=rtrim(fgets($rawmessage_fh), PHP_EOL); while(!feof($rawmessage_fh)) { if(strcmp($line,".") == 0) { break; } $rawmessage[]=$line; $line=rtrim(fgets($rawmessage_fh), PHP_EOL); } fclose($rawmessage_fh); } else { return false; } $message=vichan_message_parse($rawmessage); return $message; } function vichan_message_parse($rawmessage) { $www_charset = "utf-8"; $iconv_enable=true; $attachment_delete_alternative=true; $attachment_uudecode=false; // 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=explode("/",$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=message_parse($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->header->content_type_format[]= $partmessage->header->content_type_format[$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->header->content_type_format[$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(1) { $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]); } } $body=decode_body($body,$message->header->content_transfer_encoding); $body=recode_charset($body, $message->header->content_type_charset[0], $www_charset); if ($body=="") $body=" "; $message->body[0]=$body; } if (!isset($message->header->content_type_charset)) $message->header->content_type_charset=array($www_charset); if (!isset($message->header->content_type_name)) $message->header->content_type_name=array("unnamed"); if (!isset($message->header->content_type_format)) $message->header->content_type_format=array("fixed"); for ($o=0; $obody); $o++) { if (!isset($message->header->content_type_charset[$o])) $message->header->content_type_charset[$o]=$www_charset; if (!isset($message->header->content_type_name[$o])) $message->header->content_type_name[$o]="unnamed"; if (!isset($message->header->content_type_format[$o])) $message->header->content_type_format[$o]="fixed"; } return $message; } 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;$countfrom=$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=headerDecode($value); break; case "newsgroups:": $header->newsgroups=$value; break; case "organization:": $header->organization=headerDecode($value); break; case "content-transfer-encoding:": $header->content_transfer_encoding=trim(strtolower($value)); break; case "content-type:": $header->content_type=array(); $subheader=explode(";",$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 "format": $header->content_type_format=array($subvalue); } } } break; case "references:": $ref=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=getTimestamp(trim($value)); break; case "followup-to:": $header->followup=trim($value); break; case "x-newsreader:": case "x-mailer:": case "x-rslight-to:": $header->rslight_to=trim($value); break; case "x-rslight-site:": $header->rslight_site=trim($value); break; case "user-agent:": $header->user_agent=trim($value); break; case "x-face:": // not ready // echo "

-".base64_decode($value)."-

"; break; case "x-no-archive:": $header->xnoarchive=strtolower(trim($value)); } } 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 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); if ($personal!="") $result["personal"]=$personal; $complete[]=$result; return ($complete); } function headerDecode($value) { return mb_decode_mimeheader($value); } function getTimestamp($value) { global $timezone; return strtotime($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 recode_charset($text,$source=false,$dest=false) { global $iconv_enable,$www_charset; if($dest==false) $dest=$www_charset; if(($iconv_enable) && ($source!=false)) { $return=iconv($source, $dest."//TRANSLIT",$text); if($return!="") return $return; else return $text; } else { return $text; } } ?>