oyo
This commit is contained in:
parent
8912f31a1d
commit
3a2037dcfe
|
@ -0,0 +1,6 @@
|
|||
<?
|
||||
if(($iconv_enable==true) &&
|
||||
(!function_exists("iconv")))
|
||||
die('There is no iconv-extension in PHP. set <tt>$iconv_enable=false</tt>
|
||||
in config.inc.php to disable automatic charset recoding.');
|
||||
?>
|
|
@ -0,0 +1,539 @@
|
|||
<?
|
||||
/*
|
||||
* NewsPortal: Functions for handling single messages
|
||||
*
|
||||
* Copyright (C) 2002-2004 Florian Amrhein
|
||||
* E-Mail: newsportal@florian-amrhein.de
|
||||
* Web: http://florian-amrhein.de
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
function message_parse($rawmessage) {
|
||||
global $attachment_delete_alternative,$attachment_uudecode,$www_charset;
|
||||
global $iconv_enable;
|
||||
// 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=message_parse($part);
|
||||
// merge the content-types of the message with those of the part
|
||||
for ($o=0; $o<count($partmessage->header->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; $o<count($message->header->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; $o<count($message->header->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 ((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; $o<count($uue_infoline); $o++)
|
||||
$message->header->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=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; $o<count($message->body); $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;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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 message_read($id,$bodynum=0,$group="") {
|
||||
global $cache_articles,$spooldir,$text_error,$ns;
|
||||
if (!testGroup($group)) {
|
||||
echo $text_error["read_access_denied"];
|
||||
return;
|
||||
}
|
||||
$message = new messageType;
|
||||
if ((isset($cache_articles)) && ($cache_articles == true)) {
|
||||
// Try to load a cached article
|
||||
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=nntp_open();
|
||||
}
|
||||
if ($group != "") {
|
||||
fputs($ns,"GROUP ".$group."\r\n");
|
||||
$line=line_read($ns);
|
||||
}
|
||||
fputs($ns,'ARTICLE '.$id."\r\n");
|
||||
$line=line_read($ns);
|
||||
if (substr($line,0,3) != "220") {
|
||||
// requested article doesn't exist on the newsserver. Now we
|
||||
// should check, if the thread stored in the spool-directory
|
||||
// also doesnt't contain that article...
|
||||
thread_cache_removearticle($group,$id);
|
||||
return false;
|
||||
}
|
||||
$rawmessage=array();
|
||||
$line=line_read($ns);
|
||||
while(strcmp($line,".") != 0) {
|
||||
$rawmessage[]=$line;
|
||||
$line=line_read($ns);
|
||||
}
|
||||
$message=message_parse($rawmessage);
|
||||
if (ereg('^[0-9]+$',$id)) $message->header->number=$id;
|
||||
// write header, body and attachments to the cache
|
||||
if ((isset($cache_articles)) && ($cache_articles == true)) {
|
||||
$cachefile=fopen($cachefilename_header,"w");
|
||||
if ($cachefile) {
|
||||
fputs($cachefile,serialize($message->header));
|
||||
}
|
||||
fclose($cachefile);
|
||||
for ($i=0; $i<count($message->header->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",$maxlen=false){
|
||||
$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 && (($maxlen==false) || (strlen($h)<$maxlen))) {
|
||||
$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;
|
||||
}
|
||||
/*
|
||||
* Displays a (Sub)-Thread. Is used in article.php
|
||||
*
|
||||
* $id: Message-ID (not number!) of an article in the thread
|
||||
* $group: name of the newsgroup
|
||||
*/
|
||||
function message_thread($id,$group,$thread,$highlightids=false) {
|
||||
$current=$id;
|
||||
// set the highlightid, if not set
|
||||
if(!$highlightids)
|
||||
$highlightids=array($current);
|
||||
flush();
|
||||
// find the first article in the subthread of $id
|
||||
while(isset($thread[$id]->references)) {
|
||||
foreach($thread[$id]->references as $reference) {
|
||||
if((trim($reference)!='') && (isset($thread[$reference]))) {
|
||||
$id=$reference;
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
$liste=array();
|
||||
$liste[]=$id;
|
||||
$tmp=0;
|
||||
thread_show_head();
|
||||
echo thread_show_recursive($thread,$liste,1,"",$group,0,100,$tmp,$highlightids);
|
||||
thread_show_tail();
|
||||
}
|
||||
|
||||
/*
|
||||
* 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,$anonym_address;
|
||||
echo '<div class="np_article_header">';
|
||||
if ($article_show["Subject"]) echo $text_header["subject"].htmlspecialchars($head->subject)."<br>";
|
||||
if ($article_show["From"]) {
|
||||
echo $text_header["from"];
|
||||
if($head->from==$anonym_address) {
|
||||
// this is the anonymous address, so only show the name
|
||||
echo htmlspecialchars($head->name);
|
||||
} else {
|
||||
if($article_show["From_link"])
|
||||
echo '<a href="mailto:'.htmlspecialchars($head->from).'">';
|
||||
if(isset($article_show["From_rewrite"]))
|
||||
echo eregi_replace($article_show["From_rewrite"][0],
|
||||
$article_show["From_rewrite"][1],
|
||||
htmlspecialchars($head->from));
|
||||
else
|
||||
echo htmlspecialchars($head->from);
|
||||
if($article_show["From_link"])
|
||||
echo '</a>';
|
||||
if ($head->name != "") echo ' ('.htmlspecialchars($head->name).')';
|
||||
}
|
||||
echo "<br>";
|
||||
}
|
||||
if ($article_show["Newsgroups"])
|
||||
echo $text_header["newsgroups"].htmlspecialchars(str_replace(',',', ',$head->newsgroups))."<br>\n";
|
||||
if (isset($head->followup) && ($article_show["Followup"]) && ($head->followup != ""))
|
||||
echo $text_header["followup"].htmlspecialchars($head->followup)."<br>\n";
|
||||
if ((isset($head->organization)) && ($article_show["Organization"]) &&
|
||||
($head->organization != ""))
|
||||
echo $text_header["organization"].
|
||||
html_parse(htmlspecialchars($head->organization))."<br>\n";
|
||||
if ($article_show["Date"])
|
||||
echo $text_header["date"].date($text_header["date_format"],$head->date)."<br>\n";
|
||||
if ($article_show["Message-ID"])
|
||||
echo $text_header["message-id"].htmlspecialchars($head->id)."<br>\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 ' '.'<a href="'.$file_article.'?group='.urlencode($group).
|
||||
'&id='.urlencode($ref).'">'.($i+1).'</a>';
|
||||
}
|
||||
echo "<br>";
|
||||
}
|
||||
if (isset($head->user_agent)) {
|
||||
if ((isset($article_show["User-Agent"])) &&
|
||||
($article_show["User-Agent"])) {
|
||||
echo $text_header["user-agent"].htmlspecialchars($head->user_agent)."<br>\n";
|
||||
} else {
|
||||
echo "<!-- User-Agent: ".htmlspecialchars($head->user_agent)." -->\n";
|
||||
}
|
||||
}
|
||||
if ((isset($attachment_show)) && ($attachment_show==true) &&
|
||||
(isset($head->content_type[1]))) {
|
||||
echo $text_header["attachments"];
|
||||
for ($i=1; $i<count($head->content_type); $i++) {
|
||||
echo '<a href="'.$file_attachment.'?group='.urlencode($group).'&'.
|
||||
'id='.urlencode($head->number).'&'.
|
||||
'attachment='.$i.'">'.
|
||||
$head->content_type_name[$i].'</a> ('.
|
||||
$head->content_type[$i].')';
|
||||
if ($i<count($head->content_type)-1) echo ', ';
|
||||
}
|
||||
}
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
/*
|
||||
* decodes a body. Splits the content of $body into an array of several
|
||||
* lines, respecting the special decoding issues of format=flowed
|
||||
* articles. Each returned line consists of two fields: text and
|
||||
* the quote depth (depth)
|
||||
*/
|
||||
function decode_textbody($body,$format="fixed") {
|
||||
$body=split("\n",$body);
|
||||
$nbody=array();
|
||||
$depth=0;
|
||||
$paragraph=""; // empty paragraph
|
||||
$lastline="";
|
||||
for($i=0; $i<count($body)+1; $i++) {
|
||||
// calculate the quote depth of the actual line
|
||||
$ndepth=0;
|
||||
$tdepth=0;
|
||||
for($j=0; $j<=strlen($body[$i]); $j++) {
|
||||
$tdepth=$j;
|
||||
if($body[$i][$j]=='>') {
|
||||
$ndepth++;
|
||||
} else {
|
||||
if(($body[$i][$j]!=' ') || ($body[$i][$j-1]==' ') || ($j==0)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// generate a new paragraph?
|
||||
if(($i>0) && (($ndepth!=$depth) || $format!="flowed" ||
|
||||
($paragraph[strlen($paragraph)-1]!=' ')) || ($i==count($body))) {
|
||||
$tmp->text=$lastline=$paragraph;
|
||||
$tmp->depth=$depth;
|
||||
$paragraph="";
|
||||
if(phpversion()>=5)
|
||||
$nbody[]=clone($tmp);
|
||||
else
|
||||
$nbody[]=$tmp;
|
||||
}
|
||||
if($body[$i]=="-- " && $format=="flowed") $body[$i]="--";
|
||||
$paragraph.=substr($body[$i],$tdepth);
|
||||
$depth=$ndepth;
|
||||
}
|
||||
return $nbody;
|
||||
}
|
||||
|
||||
/*
|
||||
* replaces multiple spaces in texts by es and convert special-chars
|
||||
* to their entities
|
||||
*/
|
||||
function text2html($text) {
|
||||
return eregi_replace("^ "," ",
|
||||
str_replace(" "," ",
|
||||
str_replace(" "," ",
|
||||
str_replace("\n","<br>",
|
||||
htmlspecialchars($text)))));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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 message_show($group,$id,$attachment=0,$article_data=false,$maxlen=false) {
|
||||
global $file_article,$file_article_full;
|
||||
global $text_header,$text_article,$article_showthread;
|
||||
global $block_xnoarchive,$article_graphicquotes;
|
||||
if ($article_data == false)
|
||||
$article_data=message_read($id,$attachment,$group);
|
||||
$head=$article_data->header;
|
||||
$body=$article_data->body[$attachment];
|
||||
if ($head) {
|
||||
if (($block_xnoarchive) && (isset($head->xnoarchive)) &&
|
||||
($head->xnoarchive=="yes")) {
|
||||
echo $text_article["block-xnoarchive"];
|
||||
} else
|
||||
if (($head->content_type[$attachment]=="text/plain") &&
|
||||
($attachment==0)) {
|
||||
show_header($head,$group);
|
||||
$body=decode_textbody($body,
|
||||
$article_data->header->content_type_format[$attachment]);
|
||||
$depth=0;
|
||||
echo '<div class="np_article_body">';
|
||||
$currentlen=0; // needed if $maxlen is set
|
||||
for ($i=0; $i<=count($body) &&
|
||||
(($currentlen<$maxlen) || ($maxlen==false)); $i++) {
|
||||
// HTMLized Quotings instead of boring > ?
|
||||
if($article_graphicquotes) {
|
||||
// HTMLized Quotings
|
||||
for($j=$depth; $j<$body[$i]->depth; $j++)
|
||||
echo '<blockquote class="np_article_quote">';
|
||||
for($j=$body[$i]->depth; $j<$depth; $j++)
|
||||
echo '</blockquote>';
|
||||
$t=html_parse(text2html($body[$i]->text)).'<br>';
|
||||
echo $t;
|
||||
$currentlen+=strlen($t);
|
||||
echo "\n";
|
||||
$depth=$body[$i]->depth;
|
||||
} else {
|
||||
// Boring old Quotings with >
|
||||
if($body[$i]->depth==0) {
|
||||
if(trim($body[$i]->text)=='')
|
||||
$t="<br>\n";
|
||||
else
|
||||
$t=html_parse(text2html($body[$i]->text))."<br>\n";
|
||||
} else {
|
||||
$t='<i>'.str_repeat('>',$body[$i]->depth).' '.
|
||||
html_parse(text2html(
|
||||
textwrap($body[$i]->text,72-$body[$i]->depth,
|
||||
"\n".str_repeat('>',$body[$i]->depth).' '))).
|
||||
"</i><br>\n";
|
||||
}
|
||||
echo $t;
|
||||
$currentlen+=strlen($t);
|
||||
}
|
||||
}
|
||||
echo '</div>';
|
||||
if($maxlen!=false && $currentlen>=$maxlen) {
|
||||
echo '<br><a href="'.$file_article_full.'?id='.$id.'&group='.
|
||||
$group.'">'.$text_article["full_article"].'</a>';
|
||||
}
|
||||
} else {
|
||||
echo $body;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Shows the little menu on article-flat.php where you can select the
|
||||
* different pages with the articles on it
|
||||
*/
|
||||
function articleflat_pageselect($group,$id,$article_count,$first) {
|
||||
global $articleflat_articles_per_page,$file_article,$file_framethread,$name;
|
||||
global $text_thread,$thread_show;
|
||||
$pages=ceil($article_count / $articleflat_articles_per_page);
|
||||
$return="";
|
||||
if ($article_count > $articleflat_articles_per_page)
|
||||
$return.= $text_thread["pages"];
|
||||
for ($i = 0; $i < $pages; $i++) {
|
||||
if ($first != $i*$articleflat_articles_per_page+1)
|
||||
$return.= '<a class="np_pages_unselected" href="'.
|
||||
$file_article.'?group='.$group.
|
||||
'&id='.urlencode($id).
|
||||
'&first='.($i*$articleflat_articles_per_page+1).'&last='.
|
||||
($i+1)*$articleflat_articles_per_page.'">';
|
||||
else
|
||||
$return.= '<span class="np_pages_selected">';
|
||||
$return.= $i+1;
|
||||
if ($i == $pages-1) {
|
||||
// $return.= $article_count;
|
||||
}
|
||||
if ($first != $i*$articleflat_articles_per_page+1)
|
||||
$return.= '</a>';
|
||||
else
|
||||
$return.= '</span>';
|
||||
}
|
||||
return $return;
|
||||
}
|
|
@ -0,0 +1,195 @@
|
|||
<?
|
||||
/*
|
||||
* NewsPortal: Functions for posting articles to a newsgroup
|
||||
*
|
||||
* Copyright (C) 2002-2004 Florian Amrhein
|
||||
* E-Mail: newsportal@florian-amrhein.de
|
||||
* Web: http://florian-amrhein.de
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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) {
|
||||
global $www_charset;
|
||||
$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; $i<strlen($line) && ord($line[$i])<=127 ; $i++);
|
||||
if ($i<strlen($line)) { // yes, there are. So lets encode them!
|
||||
$from=$i;
|
||||
for($to=strlen($line)-1; ord($line[$to])<=127; $to--);
|
||||
// lets scan for the start and the end of the to be encoded _words_
|
||||
for(;$from>0 && $line[$from] != ' '; $from--);
|
||||
if($from>0) $from++;
|
||||
for(;$to<strlen($line) && $line[$to] != ' '; $to++);
|
||||
// split the string into the to be encoded middle and the rest
|
||||
$begin=substr($line,0,$from);
|
||||
$middle=substr($line,$from,$to-$from);
|
||||
$end=substr($line,$to);
|
||||
// ok, now lets encode $middle...
|
||||
$newmiddle="";
|
||||
for($i=0; $i<strlen($middle); $i++)
|
||||
$newmiddle .= $qp_table[ord($middle[$i])];
|
||||
// now we glue the parts together...
|
||||
$line=$begin.'=?'.$www_charset.'?Q?'.$newmiddle.'?='.$end;
|
||||
}
|
||||
return $line;
|
||||
}
|
||||
|
||||
/*
|
||||
* generate a message-id for posting.
|
||||
* $identity: a string containing informations about the article, to
|
||||
* make a md5-hash out of it.
|
||||
*
|
||||
* returns: a complete message-id
|
||||
*/
|
||||
function generate_msgid($identity) {
|
||||
global $msgid_generate,$msgid_fqdn;
|
||||
switch($msgid_generate) {
|
||||
case "no":
|
||||
// no, we don't want to generate a message-id.
|
||||
return false;
|
||||
break;
|
||||
case "md5":
|
||||
return '<'.md5($identity).'$1@'.$msgid_fqdn.'>';
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Post an article to a newsgroup
|
||||
*
|
||||
* $subject: The Subject of the article
|
||||
* $from: The authors name and email of the article
|
||||
* $newsgroups: The groups to post to
|
||||
* $ref: The references of the article
|
||||
* $body: The article itself
|
||||
*/
|
||||
function message_post($subject,$from,$newsgroups,$ref,$body) {
|
||||
global $server,$port,$send_poster_host,$organization,$text_error;
|
||||
global $file_footer,$www_charset,$spooldir;
|
||||
global $msgid_generate,$msgid_fqdn;
|
||||
flush();
|
||||
$ns=nntp_open($server,$port);
|
||||
if ($ns != false) {
|
||||
fputs($ns,"POST\r\n");
|
||||
$weg=line_read($ns);
|
||||
fputs($ns,'Subject: '.quoted_printable_encode($subject)."\r\n");
|
||||
fputs($ns,'From: '.$from."\r\n");
|
||||
fputs($ns,'Newsgroups: '.$newsgroups."\r\n");
|
||||
fputs($ns,"Mime-Version: 1.0\r\n");
|
||||
fputs($ns,"Content-Type: text/plain; charset=".$www_charset."; format=flowed\r\n");
|
||||
fputs($ns,"Content-Transfer-Encoding: 8bit\r\n");
|
||||
fputs($ns,"User-Agent: NewsPortal/0.36 (http://florian-amrhein.de/newsportal)\r\n");
|
||||
if ($send_poster_host)
|
||||
@fputs($ns,'X-HTTP-Posting-Host: '.gethostbyaddr(getenv("REMOTE_ADDR"))."\r\n");
|
||||
if (($ref!=false) && (count($ref)>0)) {
|
||||
// strip references
|
||||
if(strlen(implode(" ",$ref))>900) {
|
||||
$ref_first=array_shift($ref);
|
||||
do {
|
||||
$ref=array_slice($ref,1);
|
||||
} while(strlen(implode(" ",$ref))>800);
|
||||
array_unshift($ref,$ref_first);
|
||||
}
|
||||
fputs($ns,'References: '.implode(" ",$ref)."\r\n");
|
||||
}
|
||||
if (isset($organization))
|
||||
fputs($ns,'Organization: '.quoted_printable_encode($organization)."\r\n");
|
||||
if ((isset($file_footer)) && ($file_footer!="")) {
|
||||
$footerfile=fopen($file_footer,"r");
|
||||
$body.="\n".fread($footerfile,filesize($file_footer));
|
||||
fclose($footerfile);
|
||||
}
|
||||
if($msgid=generate_msgid(
|
||||
$subject.",".$from.",".$newsgroups.",".$ref.",".$body))
|
||||
fputs($ns,'Message-ID: '.$msgid."\r\n");
|
||||
$body=str_replace("\n.\r","\n..\r",$body);
|
||||
$body=str_replace("\r",'',$body);
|
||||
$b=split("\n",$body);
|
||||
$body="";
|
||||
for ($i=0; $i<count($b); $i++) {
|
||||
if ((strpos(substr($b[$i],0,strpos($b[$i]," ")),">") != 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";
|
||||
}
|
||||
}
|
||||
fputs($ns,"\r\n".$body."\r\n.\r\n");
|
||||
$message=line_read($ns);
|
||||
nntp_close($ns);
|
||||
} else {
|
||||
$message=$text_error["post_failed"];
|
||||
}
|
||||
// let thread.php ignore the cache for this group, so this new
|
||||
// article will be visible instantly
|
||||
$cachefile=$spooldir.'/'.$newsgroups.'-cache.txt';
|
||||
@unlink($cachefile);
|
||||
return $message;
|
||||
}
|
||||
?>
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,79 @@
|
|||
<?
|
||||
/*
|
||||
* NewsPortal: Data type declarations
|
||||
*
|
||||
* Copyright (C) 2002-2004 Florian Amrhein
|
||||
* E-Mail: newsportal@florian-amrhein.de
|
||||
* Web: http://florian-amrhein.de
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* the name and the description of a newsgroup
|
||||
*/
|
||||
class newsgroupType {
|
||||
var $name;
|
||||
var $description;
|
||||
var $count;
|
||||
var $text;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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; // timestamp of the article
|
||||
var $date_thread; // timestamp of the newest article in the thread
|
||||
var $organization;
|
||||
var $xnoarchive;
|
||||
var $references; // all references to the article
|
||||
var $bestreference; // nearest reference found
|
||||
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 $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
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,243 @@
|
|||
<?
|
||||
/*
|
||||
* Validator
|
||||
*
|
||||
* Validierung von Formulareingaben
|
||||
*
|
||||
* Autor: Florian Amrhein
|
||||
*/
|
||||
|
||||
class formvalidate {
|
||||
var $fields=array();
|
||||
/*
|
||||
* Überprüft ein komplettes Formular auf korrekte Eingaben, und liefert
|
||||
* false, falls irgendwo ein Fehler vorhanden ist.
|
||||
* Setzt intern die entsprechenden Daten, die show_error und
|
||||
* is_error zum Abfragen der Daten benötigen.
|
||||
*/
|
||||
function validate() {
|
||||
$errors=false;
|
||||
foreach($this->fields as $field) {
|
||||
switch($field->typ) {
|
||||
case "text":
|
||||
case "textarea":
|
||||
case "checkbox":
|
||||
case "radiobutton":
|
||||
// Basteln wegen scheiss PHP
|
||||
$valtmp=$field->validator;
|
||||
// feld_leer*feld_darf_leer +
|
||||
// nicht_feld_leer*(testfkt.ex.*testfkt +
|
||||
// nicht_testfkt.ex)
|
||||
if(
|
||||
(
|
||||
(
|
||||
(!isset($_REQUEST[$field->name])) ||
|
||||
(trim($_REQUEST[$field->name])=="")
|
||||
) &&
|
||||
(isset($field->empty)) &&
|
||||
($field->empty==true)
|
||||
) || (
|
||||
(isset($_REQUEST[$field->name])) &&
|
||||
(trim($_REQUEST[$field->name])!="") &&
|
||||
(
|
||||
($field->validator==false) ||
|
||||
($field->validator!=false) &&
|
||||
(($errmsg=$valtmp($_REQUEST[$field->name]))===true)
|
||||
)
|
||||
)
|
||||
) {
|
||||
// Feld leer und darf leer sein, oder
|
||||
// feld voll und (testfunktion existiert und testfkt.=true
|
||||
// oder testfunktion existiert nicht)
|
||||
$this->fields[$field->name]->error=false;
|
||||
} else {
|
||||
// Feld leer und darf nicht leer sein, oder
|
||||
// Feld voll und testfkt.ex und testfunktion=false
|
||||
$errors=true;
|
||||
$this->fields[$field->name]->error=true;
|
||||
if(isset($errmsg)) {
|
||||
$this->fields[$field->name]->errormessage=$errmsg;
|
||||
unset($errmsg);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "pulldown":
|
||||
case "check-text":
|
||||
case "radio-text":
|
||||
if((isset($field->empty)) && (!$field->empty) &&
|
||||
((!isset($_REQUEST[$field->name])) ||
|
||||
(trim($_REQUEST[$field->name])=="") ||
|
||||
(($_REQUEST[$field->name]=="_frei") &&
|
||||
((!isset($_REQUEST[$field->name."_frei"])) ||
|
||||
(trim($_REQUEST[$field->name."_frei"])=="")
|
||||
)
|
||||
)
|
||||
)
|
||||
) {
|
||||
$errors=true;
|
||||
$this->fields[$field->name]->error=true;
|
||||
} else {
|
||||
$this->fields[$field->name]->error=false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
// echo '<p>eval: '.$field->name.': '.$_REQUEST[$field->name].'</p>';
|
||||
}
|
||||
return !$errors;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* liefert true, falls $name fehlerhaft ausgefüllt wurde
|
||||
*/
|
||||
function is_error($name) {
|
||||
return $this->fields[$name]->error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Liefert die individuelle Fehlermeldung, falls $name fehlerhaft
|
||||
* ausgefüllt wurde. Falls keine Meldung vorliegt, wird false
|
||||
* geliefert.
|
||||
*/
|
||||
function geterrormessage($name) {
|
||||
if(isset($this->fields[$name]->errormessage))
|
||||
return $this->fields[$name]->errormessage;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Zeigt gegebenenfalls eine Fehlermeldung an, falls $name nicht
|
||||
* korrekt ausgefüllt wurde
|
||||
*/
|
||||
function show_error($name) {
|
||||
if($this->is_error($name)) {
|
||||
echo "<p>fehler</p>";
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Zeigt den Titel zu einem Feld an. Ist das zugehörige Feld fehlerhaft
|
||||
* ausgefüllt worden, wird es (z.B. farblich) markiert.
|
||||
*
|
||||
* $name: Name des Feldes
|
||||
* $text: auszugebener Text
|
||||
*/
|
||||
function show_title($name,$text) {
|
||||
if($this->is_error($name))
|
||||
echo '<font color="red"><b>'.$text.'</b></font>';
|
||||
else
|
||||
echo $text;
|
||||
}
|
||||
|
||||
/*
|
||||
* Zeigt die Daten an, die der Benutzer in das Formular, ob richtig oder
|
||||
* falsch ist egal, eingegeben hatte.
|
||||
*/
|
||||
function show_value($name) {
|
||||
echo stripslashes($_REQUEST[$name]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Liefert Variablenwerte ohne vorherige Umkodierung/Zusammenfassung
|
||||
* zurück
|
||||
*/
|
||||
function value($name) {
|
||||
if(is_array($_REQUEST[$name])) {
|
||||
$a=$_REQUEST[$name];
|
||||
return $a;
|
||||
}
|
||||
return stripslashes($_REQUEST[$name]);
|
||||
}
|
||||
|
||||
/* Liefert Variablenwerte mit vorheriger Umkodierung/Zusammenfassung
|
||||
* zurück. Vor allem wichtig bei Typ check-text und radio-text, wo
|
||||
* der eigentliche Inhalt über mehrere Variablen verteilt ist, bzw.
|
||||
* teilweise gar nicht zum Zuge kommt (freies Textfeld ausgefüllt,
|
||||
* aber nicht angeklickt)
|
||||
*/
|
||||
function get_value($name) {
|
||||
if(is_array($_REQUEST[$name])) {
|
||||
$a=$_REQUEST[$name];
|
||||
// Freies Textfeld?
|
||||
if(in_array("_frei",$a)) {
|
||||
if((isset($_REQUEST[$name.'_frei'])) &&
|
||||
($_REQUEST[$name.'_frei']!=""))
|
||||
$a[]=$_REQUEST[$name.'_frei'];
|
||||
unset($a[$name.'_frei']);
|
||||
}
|
||||
|
||||
return $a;
|
||||
} else if(($_REQUEST[$name]=='_frei') &&
|
||||
($this->fields[$name]->typ=='radio-text')) {
|
||||
return stripslashes($_REQUEST[$name.'_frei']);
|
||||
} else
|
||||
return stripslashes($_REQUEST[$name]);
|
||||
}
|
||||
|
||||
/*
|
||||
* gibt einfach nur " checked" aus, wenn $name den wert $value enthält.
|
||||
* Nötig für das Vorselektieren von Knöpfen
|
||||
*/
|
||||
function show_checked($name,$value) {
|
||||
global $fields;
|
||||
if(($this->fields[$name]->typ!="checkbox") &&
|
||||
($this->fields[$name]->typ!="check-text")) {
|
||||
if($this->value($name)==$value) {
|
||||
if($this->fields[$name]->typ=="pulldown")
|
||||
echo ' selected';
|
||||
else
|
||||
echo ' checked';
|
||||
}
|
||||
} else {
|
||||
if(in_array($value,$this->value($name)))
|
||||
echo ' checked';
|
||||
}
|
||||
}
|
||||
|
||||
function show_selected($name,$value) {
|
||||
global $fields;
|
||||
if(($this->fields[$name]->typ!="checkbox") &&
|
||||
($this->fields[$name]->typ!="check-text")) {
|
||||
if($this->value($name)==$value) {
|
||||
echo ' selected';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Registriert eine Variable als zum Formular gehörend
|
||||
*
|
||||
* $name: Name der Variablen
|
||||
* $typ: Art der Eingabe:
|
||||
* - text: Textfeld mit einfacher freier Eingabe
|
||||
* - textarea: Mehrzeiliger Text mit freier Eingabe
|
||||
* - checkbox: Ankreuzfelder, mehrere gleichzeitig
|
||||
* - radiobutton: Ankreuzfelder, nur eins gleichzeitig
|
||||
* - pulldown: Pulldown-Menu, nut eins gleichzeitig
|
||||
* - check-text: Ankreuzfelder+Textfeld, mehrere gleichzeitig
|
||||
* - radio-text: Ankreuzfelder+Textfeld, maximal eins
|
||||
* $empty: Darf das entsprechende Feld leer gelassen werden?
|
||||
* bzw. mindestens kein angekreuzt bzw. ausgefüllt?
|
||||
* $validator: Information, wie der Inhalt auf Korrektheit geprüft
|
||||
* werden soll
|
||||
* $errmsg: Fehlermeldung, die bei erkanntem Fehler ausgegeben
|
||||
* werden soll
|
||||
*/
|
||||
function register($name,$typ,$empty=true,$validator=false,$errmsg=false) {
|
||||
$var->name=$name;
|
||||
$var->typ=$typ;
|
||||
$var->empty=$empty;
|
||||
$var->validator=$validator;
|
||||
$var->errmsg=$errmsg;
|
||||
$this->fields[$name]=$var;
|
||||
}
|
||||
|
||||
/*
|
||||
* der Konstruktor
|
||||
*/
|
||||
function formvalidate() {
|
||||
}
|
||||
}
|
||||
?>
|
Loading…
Reference in New Issue