cvs: php-news-web / article.php common.inc getpart.php group.php index.php nntp.inc style.css /i l.gif
| From: | Mehdi Achour | Date: | Wed, 26 Jan 2005 16:52:40 +0000 |
| Subject: | cvs: php-news-web / article.php common.inc getpart.php group.php index.php nntp.inc style.css /i l.gif | ||
| Groups: | php.mirrors | ||
| Request: | Send a blank email to php-mirrors+get-27328@lists.php.net to get a copy of this message | ||
didou Wed Jan 26 11:52:40 2005 EDT
Modified files:
/php-news-web article.php common.inc getpart.php group.php
index.php nntp.inc style.css
/php-news-web/i l.gif
Log:
Switch to XHTML 1.0 Strict
Apply our coding standards
Fix a bug with quoting (sean)
Use php.net's logo and apply somehow the same styles
http://cvs.php.net/diff.php/php-news-web/article.php?r1=1.28&r2=1.29&ty=u Index: php-news-web/article.php diff -u php-news-web/article.php:1.28 php-news-web/article.php:1.29 --- php-news-web/article.php:1.28 Mon Dec 27 10:42:10 2004 +++ php-news-web/article.php Wed Jan 26 11:52:39 2005 @@ -1,21 +1,36 @@ <?php -// vim:sw=2:ts=2:et - -$article = (int)$article; -if (!$article) die("no article specified"); require 'common.inc'; require 'nntp.inc'; -$s = nntp_connect(NNTP_HOST) - or die("failed to connect to news server"); +if (isset($_GET['article'])) { + $article = (int)$_GET['article']; +} else { + error("No article specified"); +} + +if (isset($_GET['group'])) { + $group = $_GET['group']; +} else { + $group = false; +} + +$s = nntp_connect(NNTP_HOST); +if (!$s) { + error("Failed to connect to news server"); +} if ($group) { - $res = nntp_cmd($s,"GROUP $group",211) - or die("failed to select group .".htmlspecialchars($group)); + $res = nntp_cmd($s,"GROUP $group",211); + if (!$res) { + error("Failed to select group"); + } +} + +$res = nntp_cmd($s, "ARTICLE $article",220); +if (!$res) { + error("Failed to get article ". $article); } -$res = nntp_cmd($s, "ARTICLE $article",220) - or die("failed to get article ".htmlspecialchars($article)); $started = 0; $inheaders = 1; $headers = array(); @@ -24,183 +39,216 @@ $mimecount = 0; // number of mime parts $boundaries = array(); $lk = ''; +$prevquote = 0; +$prevline = ''; while (!feof($s)) { - $line = fgets($s, 4096); - if ($line == ".\r\n") break; - if ($inheaders && ($line == "\n" || $line == "\r\n")) { - $inheaders = 0; - if ($headers['content-type'] - && preg_match("/charset=(\"|'|)(.+)\\1/is", $headers['content-type'], $m)) { - $charset = trim($m[2]); - } - if ($headers['content-type'] - && preg_match("/boundary=(\"|'|)(.+)\\1/is", $headers['content-type'], $m)) { - $boundaries[] = trim($m[2]); - $boundary = end($boundaries); - } - if ($headers['content-type'] - && preg_match("/([^;]+)(;|\$)/", $headers['content-type'], $m)) { - $mimetype = trim(strtolower($m[1])); - ++$mimecount; - } - if (!$started) { - head("$group: ".format_title($headers[subject], $charset)); - start_article($group,$headers,$charset); - $started = 1; - } - - $encoding = strtolower(trim($headers['content-transfer-encoding'])); - if (strlen($mimetype) - && $mimetype != "text/plain" - && substr($mimetype,0,10) != "multipart/") { - # Display a link to the attachment - $name = ""; - if ($headers['content-type'] - && preg_match("/name=(\"|'|)(.+)\\1/s", $headers['content-type'], $m)) - $name = trim($m[2]); - else if ($headers['content-disposition'] - && preg_match("/filename=(\"|'|)(.+)\\1/s", $headers['content-type'], $m)) - $name = trim($m[2]); - - if ($headers['content-description']) - $description = trim($headers['content-description']) . " "; - else - $description = ""; - - $description .= $name; - $link_desc = "[$mimetype]"; - if (strlen($description)) - $link_desc .= " " . $description; - - $dl_link = "/getpart.php?group=$group&article=$article&part=$mimecount"; - - echo "Attachment: <a target=\"_blank\" href=\"$dl_link\">${link_desc}</a><br />\n"; - } - - if ($masterheaders == null) - $headers = $masterheaders; - continue; - } - # fix lines that started with a period and got escaped - if (substr($line,0,2) == "..") $line = substr($line,1); - if ($inheaders) { - list($k,$v) = explode(": ", $line, 2); - if ($k && $v) { - $headers[strtolower($k)] = $v; - $lk = strtolower($k); - } - else { - $headers[$lk] .= $line; - } - } - else { - - if ($boundary - && substr($line,0,2) == '--' - && substr($line,2,strlen($boundary)) == $boundary) { - - $inheaders = 1; - - if (substr($line,2+strlen($boundary)) == '--') { - # end of this container - array_pop($boundaries); - $boundary = end($boundaries); - } else { - # next section; start with an inherited set of headers - $headers = $masterheaders; - $mimetype = ""; - } - - continue; - } - - if (strlen($mimetype) && $mimetype != "text/plain") - continue; - - switch($encoding) { - case "quoted-printable": - $line = quoted_printable_decode($line); - break; - case "base64": - $line = base64_decode($line); - break; - } - if (strlen($charset)) - $line = to_utf8($line, $charset); - - # this is some amazingly simplistic code to color quotes/signatures - # differently, and turn links into real links. it actually appears - # to work fairly well, but could easily be made more sophistimicated. - $line = htmlentities($line,ENT_NOQUOTES,"utf-8"); - $line = preg_replace("/((mailto|http|ftp|nntp|news):.+?)(>|\\s|\\)|\\.\\s|$)/","<a href=\"\\1\">\\1</a>\\3",$line); - if (!$insig && $line == "-- \r\n") { - echo "<span class=\"signature\">"; - $insig = 1; - } - if ($insig && $line == "\r\n") { - echo "</span>"; - $insig = 0; - } - if (!$insig && substr($line,0,4) == ">") { - echo "<span class=\"quote\">$line</span>"; - } - else { - echo $line; - } - } + $line = fgets($s, 4096); + if ($line == ".\r\n") break; + if ($inheaders && ($line == "\n" || $line == "\r\n")) { + $inheaders = 0; + if ($headers['content-type'] + && preg_match("/charset=(\"|'|)(.+)\\1/is", $headers['content-type'], $m)) { + $charset = trim($m[2]); + } + if ($headers['content-type'] + && preg_match("/boundary=(\"|'|)(.+)\\1/is", $headers['content-type'], $m)) { + $boundaries[] = trim($m[2]); + $boundary = end($boundaries); + } + if ($headers['content-type'] + && preg_match("/([^;]+)(;|\$)/", $headers['content-type'], $m)) { + $mimetype = trim(strtolower($m[1])); + ++$mimecount; + } + if (!$started) { + head("$group: ".format_title($headers['subject'], $charset)); + start_article($group,$headers,$charset); + $started = 1; + } + + $encoding = strtolower(trim($headers['content-transfer-encoding'])); + if (strlen($mimetype) + && $mimetype != "text/plain" + && substr($mimetype,0,10) != "multipart/") { + # Display a link to the attachment + $name = ''; + if ($headers['content-type'] + && preg_match("/name=(\"|'|)(.+)\\1/s", $headers['content-type'], $m)) { + $name = trim($m[2]); + } else if ($headers['content-disposition'] + && preg_match("/filename=(\"|'|)(.+)\\1/s", $headers['content-type'], $m)) { + $name = trim($m[2]); + } + + if ($headers['content-description']) { + $description = trim($headers['content-description']) . " "; + } else { + $description = ''; + } + + $description .= $name; + $link_desc = "[$mimetype]"; + if (strlen($description)) { + $link_desc .= " " . $description; + } + + $dl_link = "/getpart.php?group=$group&article=$article&part=$mimecount"; + + echo "Attachment: <a href=\"$dl_link\">${link_desc}</a><br />\n"; + } + + if ($masterheaders == null) { + $headers = $masterheaders; + } + continue; + } + # fix lines that started with a period and got escaped + if (substr($line,0,2) == "..") { + $line = substr($line,1); + } + + if ($inheaders) { + list($k,$v) = explode(": ", $line, 2); + if ($k && $v) { + $headers[strtolower($k)] = $v; + $lk = strtolower($k); + } else { + $headers[$lk] .= $line; + } + } + else { + + if ($boundary + && substr($line,0,2) == '--' + && substr($line,2,strlen($boundary)) == $boundary) { + + $inheaders = 1; + + if (substr($line,2+strlen($boundary)) == '--') { + # end of this container + array_pop($boundaries); + $boundary = end($boundaries); + } else { + # next section; start with an inherited set of headers + $headers = $masterheaders; + $mimetype = ""; + } + + continue; + } + + if (strlen($mimetype) && $mimetype != "text/plain") { + continue; + } + + switch($encoding) { + case "quoted-printable": + $line = quoted_printable_decode($line); + break; + case "base64": + $line = base64_decode($line); + break; + } + if (strlen($charset)) { + $line = to_utf8($line, $charset); + } + + # this is some amazingly simplistic code to color quotes/signatures + # differently, and turn links into real links. it actually appears + # to work fairly well, but could easily be made more sophistimicated. + $line = htmlentities($line,ENT_NOQUOTES,"utf-8"); + $line = preg_replace("/((mailto|http|ftp|nntp|news):.+?)(>|\\s|\\)|\\.\\s|$)/","<a href=\"\\1\">\\1</a>\\3",$line); + if (!$insig && $line == "-- \r\n") { + echo "<span class=\"signature\">"; + $insig = 1; + } + if ($insig && $line == "\r\n") { + echo "</span>"; + $insig = 0; + } + if ( + (!$insig && substr($line,0,4) == ">") || + ($prevquote && !in_array(substr($prevline, -1), array("\r","\n"))) + ) { + echo "<span class=\"quote\">$line</span>"; + $prevquote = 1; + } else { + echo $line; + $prevquote = 0; + } + $prevline = $line; + } } if ($inheaders && !$started) { - head("$group: ". $headers[subject]); - start_article($group,$headers,$charset); + head("$group: ". $headers[subject]); + start_article($group,$headers,$charset); +} +if ($insig) { + echo "</span>"; } -if ($insig) echo "</span>"; -echo "</pre></blockquote>"; +echo " </pre>\n"; +echo " </blockquote>\n"; function start_article ($group,$headers,$charset) { - echo "<blockquote>\n"; - echo '<table border="0" cellpadding="2" cellspacing="2" width="100%">'; - # from - echo '<tr><td class="headerlabel">From:</td><td class="headervalue">'.format_author($headers['from'], $charset)."</td>\n"; - # date - echo '<td class="headerlabel">Date:</td><td class="headervalue">'.format_date($headers["date"])."</td></tr>\n"; - # subject - echo '<tr><td class="headerlabel">Subject:</td><td class="headervalue" colspan="3">'.format_subject($headers["subject"], $charset)."</td></tr>\n"; - echo "<tr>"; - # references - if ($headers["references"] || $headers["in-reply-to"]) { - $ref = $headers["references"] ? $headers["references"] : $headers["in-reply-to"]; - echo '<td class="headerlabel">References:</td><td class="headervalue">'; - $r = explode(" ", $ref); - $c = 1; - $s = nntp_connect(NNTP_HOST) - or die("failed to connect to news server"); - while (list($k,$v) = each($r)) { - if (!$v) continue; - $v = trim($v); - if (!preg_match("/^<.+>\$/", $v)) continue; - $res2 = nntp_cmd($s, "XPATH $v",223) - or print("failed to get reference article id ".htmlspecialchars($v)."<br />\n"); - list(,$v) = split("/", trim($res2)); - if (empty($v)) continue; - echo "<a href=\"/$group/".htmlspecialchars(urlencode($v))."\">".($c++)."</a>\n"; - } - echo "</td>\n"; - } - # groups - if ($headers["newsgroups"]) { - echo '<td class="headerlabel">Groups:</td><td class="headervalue">'; - $r = explode(",", chop($headers["newsgroups"])); - while (list($k,$v) = each($r)) { - echo "<a href=\"/".htmlspecialchars(urlencode($v))."\">".htmlspecialchars($v)."</a>\n"; - } - echo "</td>\n"; - } - echo "</tr>"; - //while (list($k,$v) = each($headers)) { - // echo "<!-- ", htmlspecialchars($k),": ",preg_replace("/-+/", "-", htmlspecialchars($v))," -->\n"; - //} - echo "</table></blockquote>\n"; - echo "<blockquote><pre>"; + echo " <blockquote>\n"; + echo ' <table border="0" cellpadding="2" cellspacing="2" width="100%">' . "\n"; + # from + echo ' <tr>' . "\n"; + echo ' <td class="headerlabel">From:</td>' . "\n"; + echo ' <td class="headervalue">' . format_author($headers['from'], $charset)."</td>\n"; + # date + echo ' <td class="headerlabel">Date:</td>' . "\n"; + echo ' <td class="headervalue">' . format_date($headers["date"])."</td>\n"; + echo " </tr>\n"; + # subject + echo ' <tr>' . "\n"; + echo ' <td class="headerlabel">Subject:</td>' . "\n"; + echo ' <td class="headervalue" colspan="3">'.format_subject($headers["subject"], $charset)."</td>\n"; + echo " </tr>\n"; + echo " <tr>\n"; + # references + if ($headers["references"] || $headers["in-reply-to"]) { + $ref = $headers["references"] ? $headers["references"] : $headers["in-reply-to"]; + echo ' <td class="headerlabel">References:</td>' . "\n"; + echo ' <td class="headervalue">'; + $r = explode(" ", $ref); + $c = 1; + $s = nntp_connect(NNTP_HOST) + or die("failed to connect to news server"); + while (list($k,$v) = each($r)) { + if (!$v) continue; + $v = trim($v); + if (!preg_match("/^<.+>\$/", $v)) { + continue; + } + $res2 = nntp_cmd($s, "XPATH $v",223) + or print("failed to get reference article id ".htmlspecialchars($v)."<br />"); + list(,$v) = split("/", trim($res2)); + if (empty($v)) { + continue; + } + echo "<a href=\"/$group/".htmlspecialchars(urlencode($v))."\">".($c++)."</a>"; + } + echo "</td>\n"; + } + # groups + if ($headers["newsgroups"]) { + echo ' <td class="headerlabel">Groups:</td>' . "\n"; + echo ' <td class="headervalue">'; + $r = explode(",", chop($headers["newsgroups"])); + while (list($k,$v) = each($r)) { + echo "<a href=\"/".htmlspecialchars(urlencode($v))."\">".htmlspecialchars($v)."</a>"; + } + echo "</td>\n"; + } + echo " </tr>\n"; + //while (list($k,$v) = each($headers)) { + // echo "<!-- ", htmlspecialchars($k),": ",preg_replace("/-+/", "-", htmlspecialchars($v))," -->\n"; + //} + echo " </table>\n"; + echo " </blockquote>\n"; + echo " <blockquote>\n"; + echo " <pre>\n"; } foot(); http://cvs.php.net/diff.php/php-news-web/common.inc?r1=1.28&r2=1.29&ty=u Index: php-news-web/common.inc diff -u php-news-web/common.inc:1.28 php-news-web/common.inc:1.29 --- php-news-web/common.inc:1.28 Tue Jan 25 19:03:19 2005 +++ php-news-web/common.inc Wed Jan 26 11:52:39 2005 @@ -1,100 +1,109 @@ -<?php # vim:ft=php:ts=2:sw=2:et +<?php define('NNTP_HOST', 'localhost'); +function error($str) { + head("PHP news : error"); + echo "<p><strong>Error:</strong> $str</p>\n"; + foot(); + die(); +} + function head($title="PHP news") { - header("Content-type: text/html; charset=utf-8"); + header("Content-type: text/html; charset=utf-8"); + echo '<?xml version="1.0"?>' . "\n"; + ?> -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> -<html> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> - <title><?php echo $title?></title> - <link rel="stylesheet" href="/style.css" type="text/css" /> -</head> -<body leftmargin="0" topmargin="0" marginheight="0" marginwidth="0"> -<table width="100%" border="0" cellspacing="0" cellpadding="0"> - <tr bgcolor="#9999cc"> - <td> - <a href="/index.php"><img src="/i/l.gif" border="0" width="120" height="64" alt="php" /></a> - </td> - <td align="right" valign="bottom"> - PHP.net <a href="news://<?php echo $_SERVER['HTTP_HOST']; ?>/" clas="top">news server</a> web interface - </td> - </tr> - <tr bgcolor="#333366"> - <td colspan="3"><img src="/i/g.gif" width="1" height="1" alt="" /></td> - </tr> -</table> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <title><?php echo $title?></title> + <link rel="stylesheet" href="/style.css" type="text/css" /> + </head> + <body> + <table width="100%" border="0" cellspacing="0" cellpadding="0"> + <tr class="header"> + <td> + <a href="/index.php"><img src="/i/l.gif" width="120" height="67" alt="PHP" /></a> + </td> + <td align="right" valign="bottom"> + PHP.net <a href="news://<?php echo $_SERVER['HTTP_HOST']; ?>/" class="top">news server</a> web interface + </td> + </tr> + <tr class="subheader"> + <td colspan="2"> + <img src="/i/g.gif" width="1" height="1" alt="" /> + </td> + </tr> + </table> <?php } function foot() {?> -<hr noshade="noshade" size="1" width="60%" align="right" /> -<div align="right"> -<small> -written by jim winstead. no rights reserved. (<a href="http://cvs.php.net/cvs.php/php-news-web">source code</a>) -</small> -</div> -</body> + <hr /> + <div class="small"> + Written by Jim Winstead. no rights reserved. (<a href="http://cvs.php.net/cvs.php/php-news-web">source code</a>) + </div> + </body> </html> <?php } - function to_utf8($str, $charset) - { - $n = iconv(strlen($charset) ? $charset : "iso-8859-1", "utf-8", $str); - if ($n === false) - return $str; - return $n; - } +function to_utf8($str, $charset) +{ + $n = iconv(strlen($charset) ? $charset : "iso-8859-1", "utf-8", $str); + if ($n === false) { + return $str; + } + return $n; +} /* if (function_exists("mb_convert_encoding")) { - function to_utf8($str, $charset) - { - return mb_convert_encoding($str, "utf-8", strlen($charset) ? $charset : "iso-8859-1"); - } +function to_utf8($str, $charset) +{ +return mb_convert_encoding($str, "utf-8", strlen($charset) ? $charset : "iso-8859-1"); +} } else if (function_exists("recode_string")) { - function to_utf8($str, $charset) - { - if (strlen($charset) == 0) - $charset = "iso-8859-1"; - return recode_string("$charset..utf-8", $str); - } +function to_utf8($str, $charset) +{ +if (strlen($charset) == 0) +$charset = "iso-8859-1"; +return recode_string("$charset..utf-8", $str); +} } else if (function_exists("iconv")) { - function to_utf8($str, $charset) - { - return iconv(strlen($charset) ? $charset : "iso-8859-1", "utf-8", $str); - } +function to_utf8($str, $charset) +{ +return iconv(strlen($charset) ? $charset : "iso-8859-1", "utf-8", $str); +} } else { - function to_utf8($str, $charset) - { - return $str; - } +function to_utf8($str, $charset) +{ +return $str; +} } */ function decode_header($charset,$encoding,$text) { - if (strtolower($encoding) == "b") { - $text = base64_decode($text); - } - else { - $text = quoted_printable_decode($text); - } - return to_utf8($text, $charset); + if (strtolower($encoding) == "b") { + $text = base64_decode($text); + } else { + $text = quoted_printable_decode($text); + } + return to_utf8($text, $charset); } -function recode_header($header, $basecharset) -{ - if (strpos($header, "=?") === false) - return to_utf8($header, $basecharset); - return preg_replace("/=\\?(.+?)\\?([qb])\\?(.+?)\\?=/ie", "decode_header('\\1','\\2','\\3')", $header); +function recode_header($header, $basecharset) { + if (strpos($header, "=?") === false) { + return to_utf8($header, $basecharset); + } + return preg_replace("/=\\?(.+?)\\?([qb])\\?(.+?)\\?=/ie", "decode_header('\\1','\\2','\\3')", $header); } /* Email spam protection (taken from php-bugs-web) */ -function spam_protect($txt) -{ +function spam_protect($txt) { $translate = array('@' => ' at ', '.' => ' dot '); /* php.net addresses are not protected! */ @@ -108,49 +117,49 @@ # this turns some common forms of email addresses into mailto: links function format_author($a, $charset) { - $a = recode_header($a, $charset); - if (preg_match("/^\s*(.+)\s+\\(\"?(.+?)\"?\\)\s*$/",$a,$ar)) { - return "<a href=\"mailto:".htmlspecialchars(urlencode(spam_protect($ar[1])))."\">".str_replace(" ", " ", htmlspecialchars($ar[2]))."</a>"; - } - if (preg_match("/^\s*\"?(.+?)\"?\s*<(.+)>\s*$/",$a,$ar)) { - return "<a href=\"mailto:".htmlspecialchars(urlencode(spam_protect($ar[2])))."\">".str_replace(" ", " ", htmlspecialchars($ar[1]))."</a>"; - } - if (ereg("@",$a)) { - $a = spam_protect($a); - return "<a href=\"mailto:".htmlspecialchars(urlencode($a))."\">".htmlspecialchars($a)."</a>"; - } - return str_replace(" ", " ", htmlspecialchars($a)); + $a = recode_header($a, $charset); + if (preg_match("/^\s*(.+)\s+\\(\"?(.+?)\"?\\)\s*$/",$a,$ar)) { + return "<a href=\"mailto:".htmlspecialchars(urlencode(spam_protect($ar[1])))."\">".str_replace(" ", " ", htmlspecialchars($ar[2]))."</a>"; + } + if (preg_match("/^\s*\"?(.+?)\"?\s*<(.+)>\s*$/",$a,$ar)) { + return "<a href=\"mailto:".htmlspecialchars(urlencode(spam_protect($ar[2])))."\">".str_replace(" ", " ", htmlspecialchars($ar[1]))."</a>"; + } + if (ereg("@",$a)) { + $a = spam_protect($a); + return "<a href=\"mailto:".htmlspecialchars(urlencode($a))."\">".htmlspecialchars($a)."</a>"; + } + return str_replace(" ", " ", htmlspecialchars($a)); } function format_subject($s, $charset) { - global $article; - $s = recode_header($s, $charset); - $s = preg_replace("/^(Re: *)?\[(PHP|PEAR)(-.*)?\] /i", "\\1", $s); - // make this look better on the preview page.. - if (strlen($s) > 150 && !isset($article)) { - $s = substr($s, 0, 150) . "..."; - } else { - $s = wordwrap($s, 150); - } - return nl2br(htmlspecialchars($s)); + global $article; + $s = recode_header($s, $charset); + $s = preg_replace("/^(Re: *)?\[(PHP|PEAR)(-.*)?\] /i", "\\1", $s); + // make this look better on the preview page.. + if (strlen($s) > 150 && !isset($article)) { + $s = substr($s, 0, 150) . "..."; + } else { + $s = wordwrap($s, 150); + } + return nl2br(htmlspecialchars($s)); } function format_title($s, $charset) { - global $article; - $s = recode_header($s, $charset); - $s = preg_replace("/^(Re: *)?\[(PHP|PEAR)(-.*)?\] /i", "\\1", $s); - // make this look better on the preview page.. - if (strlen($s) > 150 && !isset($article)) { - $s = substr($s, 0, 150) . "..."; - } else { - $s = wordwrap($s, 150); - } - return $s; + global $article; + $s = recode_header($s, $charset); + $s = preg_replace("/^(Re: *)?\[(PHP|PEAR)(-.*)?\] /i", "\\1", $s); + // make this look better on the preview page.. + if (strlen($s) > 150 && !isset($article)) { + $s = substr($s, 0, 150) . "..."; + } else { + $s = wordwrap($s, 150); + } + return $s; } function format_date($d) { - $d = strtotime($d); - $d = strftime("%c", $d); - return str_replace(" ", " ", $d); + $d = strtotime($d); + $d = strftime("%c", $d); + return str_replace(" ", " ", $d); } http://cvs.php.net/diff.php/php-news-web/getpart.php?r1=1.2&r2=1.3&ty=u Index: php-news-web/getpart.php diff -u php-news-web/getpart.php:1.2 php-news-web/getpart.php:1.3 --- php-news-web/getpart.php:1.2 Wed Dec 22 17:39:19 2004 +++ php-news-web/getpart.php Wed Jan 26 11:52:39 2005 @@ -1,20 +1,42 @@ <?php -// vim:sw=2:ts=2:et -if (!$article) die("no article specified"); -if (!$part) die("no part specified"); require 'common.inc'; require 'nntp.inc'; -$s = nntp_connect(NNTP_HOST) - or die("failed to connect to news server"); +if (isset($_GET['group'])) { + $group = $_GET['group']; +} else { + $group = false; +} + +if (isset($_GET['article'])) { + $article = (int)$_GET['article']; +} else { + error("No article specified"); +} + +if (isset($_GET['part'])) { + $part = $_GET['part']; +} else { + error("No part specified"); +} + +$s = nntp_connect(NNTP_HOST); +if (!$s) { + error("Failed to connect to news server"); +} if ($group) { - $res = nntp_cmd($s,"GROUP $group",211) - or die("failed to select group .".htmlspecialchars($group)); + $res = nntp_cmd($s,"GROUP $group",211); + if (!$res) { + error("Failed to select group"); + } +} + +$res = nntp_cmd($s, "ARTICLE $article",220); +if (!$res) { + error("Failed to get article ". $article); } -$res = nntp_cmd($s, "ARTICLE $article",220) - or die("failed to get article ".htmlspecialchars($article)); $emit = false; @@ -25,88 +47,95 @@ $boundaries = array(); $lk = ''; while (!feof($s)) { - $line = fgets($s, 4096); - if ($line == ".\r\n") break; - if ($inheaders && ($line == "\n" || $line == "\r\n")) { - $inheaders = 0; - if ($headers['content-type'] - && preg_match("/charset=(\"|'|)(.+)\\1/is", $headers['content-type'], $m)) { - $charset = trim($m[2]); - } - if ($headers['content-type'] - && preg_match("/boundary=(\"|'|)(.+)\\1/is", $headers['content-type'], $m)) { - $boundaries[] = trim($m[2]); - $boundary = end($boundaries); - } - if ($headers['content-type'] - && preg_match("/([^;]+)(;|\$)/", $headers['content-type'], $m)) { - $mimetype = trim(strtolower($m[1])); - ++$mimecount; - } - - $emit = ($mimecount == $part); - - $encoding = strtolower(trim($headers['content-transfer-encoding'])); - if ($emit) { - if ($headers['content-type']) - header('Content-Type: ' . $headers['content-type']); - if ($headers['content-disposition']) - header('Content-Disposition: ' . $headers['content-disposition']); - if ($headers['content-description']) - header('Content-Description: ' . $headers['content-description']); - } - - if ($masterheaders == null) - $headers = $masterheaders; - continue; - } - # fix lines that started with a period and got escaped - if (substr($line,0,2) == "..") $line = substr($line,1); - if ($inheaders) { - list($k,$v) = explode(": ", $line, 2); - if ($k && $v) { - $headers[strtolower($k)] = $v; - $lk = strtolower($k); - } - else { - $headers[$lk] .= $line; - } - } - else { - - if ($boundary - && substr($line,0,2) == '--' - && substr($line,2,strlen($boundary)) == $boundary) { - - $inheaders = 1; - - if (substr($line,2+strlen($boundary)) == '--') { - # end of this container - array_pop($boundaries); - $boundary = end($boundaries); - } else { - # next section; start with an inherited set of headers - $headers = $masterheaders; - $mimetype = ""; - } - - continue; - } - - if (!$emit) + $line = fgets($s, 4096); + if ($line == ".\r\n") { + break; + } + if ($inheaders && ($line == "\n" || $line == "\r\n")) { + $inheaders = 0; + if ($headers['content-type'] + && preg_match("/charset=(\"|'|)(.+)\\1/is", $headers['content-type'], $m)) { + $charset = trim($m[2]); + } + if ($headers['content-type'] + && preg_match("/boundary=(\"|'|)(.+)\\1/is", $headers['content-type'], $m)) { + $boundaries[] = trim($m[2]); + $boundary = end($boundaries); + } + if ($headers['content-type'] + && preg_match("/([^;]+)(;|\$)/", $headers['content-type'], $m)) { + $mimetype = trim(strtolower($m[1])); + ++$mimecount; + } + + $emit = ($mimecount == $part); + + $encoding = strtolower(trim($headers['content-transfer-encoding'])); + if ($emit) { + if (isset($headers['content-type'])) { + header('Content-Type: ' . $headers['content-type']); + } + if (isset($headers['content-disposition'])) { + header('Content-Disposition: ' . $headers['content-disposition']); + } + if (isset($headers['content-description'])) { + header('Content-Description: ' . $headers['content-description']); + } + } + + if ($masterheaders == null) { + $headers = $masterheaders; + } continue; + } + # fix lines that started with a period and got escaped + if (substr($line,0,2) == "..") { + $line = substr($line,1); + } + if ($inheaders) { + list($k,$v) = explode(": ", $line, 2); + if ($k && $v) { + $headers[strtolower($k)] = $v; + $lk = strtolower($k); + } else { + $headers[$lk] .= $line; + } + } else { + + if ($boundary + && substr($line,0,2) == '--' + && substr($line,2,strlen($boundary)) == $boundary) { + + $inheaders = 1; + + if (substr($line,2+strlen($boundary)) == '--') { + # end of this container + array_pop($boundaries); + $boundary = end($boundaries); + } else { + # next section; start with an inherited set of headers + $headers = $masterheaders; + $mimetype = ""; + } + + continue; + } + + if (!$emit) { + continue; + } + + switch($encoding) { + case "quoted-printable": + $line = quoted_printable_decode($line); + break; + case "base64": + $line = base64_decode($line); + break; + } + + echo $line; - switch($encoding) { - case "quoted-printable": - $line = quoted_printable_decode($line); - break; - case "base64": - $line = base64_decode($line); - break; - } - - echo $line; - - } + } } http://cvs.php.net/diff.php/php-news-web/group.php?r1=1.19&r2=1.20&ty=u Index: php-news-web/group.php diff -u php-news-web/group.php:1.19 php-news-web/group.php:1.20 --- php-news-web/group.php:1.19 Tue Jan 25 19:01:54 2005 +++ php-news-web/group.php Wed Jan 26 11:52:39 2005 @@ -3,50 +3,84 @@ require 'common.inc'; require 'nntp.inc'; -$s = nntp_connect(NNTP_HOST) - or die("failed to connect to news server"); +if (isset($_GET['group'])) { + $group = $_GET['group']; +} else { + error("Missing group"); +} -$res = nntp_cmd($s,"GROUP $group",211) - or die("failed to get info on group"); -list (,$f,$l,$g) = explode(" ", $res); -$i=(int)$i; -if (!$i || $i > $l - 20 || $i < $f) $i = $l - $f > 20 ? $l - 20 : $f; -$n = min($l+1,$i+20); -$res = nntp_cmd($s,"XOVER $i-$n", 224) - or die("failed to get xover data\n"); +if (isset($_GET['format'])) { + $format = $_GET['format']; +} else { + // assume html + $format = 'html'; +} + +if (isset($_GET['i'])) { + $i = (int)$_GET['i']; +} else { + $i = 0; +} + +$s = nntp_connect(NNTP_HOST); +if (!$s) { + error("Failed to connect to news server"); +} + +$res = nntp_cmd($s,"GROUP $group",211); +if (!$res) { + error("Failed to get info on group"); +} + +list (, $f, $l, $g) = explode(" ", $res); +if (!$i || $i > $l - 20 || $i < $f) { + $i = $l - $f > 20 ? $l - 20 : $f; +} +$n = min($l + 1, $i + 20); + +$res = nntp_cmd($s,"XOVER $i-$n", 224); +if (!$res) { + error("Failed to get xover data"); +} switch($format) { - case 'rss': - header("Content-type: text/xml"); - echo '<?xml version="1.0" encoding="utf-8"?>';?> + case 'rss': + header("Content-type: text/xml"); + echo '<?xml version="1.0" encoding="utf-8"?>' . "\n";?> <rss version="0.93"> -<channel> - <title><?php echo $_SERVER['HTTP_HOST']; ?>: <?php echo $group?></title> - <link>http://<?php echo $_SERVER['HTTP_HOST']; ?>/group.php?group=<?php echo $group?></link> - <description></description> + <channel> + <title><?php echo $_SERVER['HTTP_HOST']; ?>: <?php echo $group?></title> + <link>http://<?php echo $_SERVER['HTTP_HOST']; ?>/group.php?group=<?php echo $group?></link> + <description></description> <?php break; - case 'rdf': - header("Content-type: text/xml"); - echo '<?xml version="1.0" encoding="utf-8"?>'; +case 'rdf': +header("Content-type: text/xml"); +echo '<?xml version="1.0" encoding="utf-8"?>' . "\n"; ?> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://my.netscape.com/rdf/simple/0.9/"> -<channel> + <channel> <title><?php echo $_SERVER['HTTP_HOST']; ?>: <?php echo $group?></title> <link>http://<?php echo $_SERVER['HTTP_HOST']; ?>/group.php?group=<?php echo $group?></link> <description><?php echo $group?> Newsgroup at <?php echo NNTP_HOST; ?></description> <language>en-US</language> -</channel> + </channel> <?php break; - case 'html': - default: - head($group); - navbar($group,$f,$l,$i); - echo '<table class="alist" width="100%">'; - echo '<tr><td class="alisthead">#</td><td class="alisthead">subject</td><td class="alisthead">author</td><td class="alisthead">date</td><td class="alisthead">lines</td></tr>',"\n"; - break; +case 'html': +default: +head($group); +navbar($group,$f,$l,$i); +echo ' <table class="alist" width="100%">' . "\n"; +echo ' <tr>' . "\n"; +echo ' <td class="alisthead">#</td>' . "\n"; +echo ' <td class="alisthead">subject</td>' . "\n"; +echo ' <td class="alisthead">author</td>' . "\n"; +echo ' <td class="alisthead">date</td>' . "\n"; +echo ' <td class="alisthead">lines</td>' . "\n"; +echo ' </tr>' . "\n"; +break; } # list of articles @@ -55,80 +89,82 @@ $charset = ""; while ($line = fgets($s, 16384)) { - if ($line == ".\r\n") break; - $line = chop($line); - list($n,$subj,$author,$odate,$messageid,$references,$bytes,$lines,$extra) - = explode("\t", $line, 9); -/* $date = date("H:i:s M/d/y", strtotime($odate)); */ - $date822 = date("r", strtotime($odate)); - - switch($format) { - case 'rss': - echo "<item>\n"; - echo "<link>http://{$_SERVER['HTTP_HOST']}/$group/$n</link>\n"; - echo "<title>", format_subject($subj, $charset), "</title>\n"; - echo "<description>", htmlspecialchars(format_author($author, $charset)), "</description>\n"; - echo "<pubDate>$date822</pubDate>\n"; - echo "</item>\n"; - break; - case 'rdf': - echo "<item>\n"; - echo "<title>", format_subject($subj, $charset), "</title>\n"; - echo "<link>http://{$_SERVER['HTTP_HOST']}/$group/$n</link>\n"; - echo "<description>", htmlspecialchars(format_author($author, $charset)), "</description>\n"; - echo "<pubDate>$date822</pubDate>\n"; - echo "</item>\n"; - break; - case 'html': - default: - echo "<tr>"; - echo "<td class=\"$class\"><a href=\"/$group/$n\">$n</a></td>"; - echo "<td class=\"$class\"><a href=\"/$group/$n\">"; - echo format_subject($subj, $charset); - echo "</a></td>"; - echo "<td class=\"$class\">".format_author($author, $charset)."</td>\n"; - echo "<td align=\"center\" class=\"$class\"><tt>" . format_date($odate) . "</tt></td>\n"; - echo "<td align=\"right\" class=\"$class\">$lines</td>\n"; - } - $class = $class == "even" ? "odd" : "even"; + if ($line == ".\r\n") break; + $line = chop($line); + list($n,$subj,$author,$odate,$messageid,$references,$bytes,$lines,$extra) + = explode("\t", $line, 9); + /* $date = date("H:i:s M/d/y", strtotime($odate)); */ + $date822 = date("r", strtotime($odate)); + + switch($format) { + case 'rss': + echo " <item>\n"; + echo " <link>http://{$_SERVER['HTTP_HOST']}/$group/$n</link>\n"; + echo " <title>", format_subject($subj, $charset), "</title>\n"; + echo " <description>", htmlspecialchars(format_author($author, $charset)), "</description>\n"; + echo " <pubDate>$date822</pubDate>\n"; + echo " </item>\n"; + break; + case 'rdf': + echo " <item>\n"; + echo " <title>", format_subject($subj, $charset), "</title>\n"; + echo " <link>http://{$_SERVER['HTTP_HOST']}/$group/$n</link>\n"; + echo " <description>", htmlspecialchars(format_author($author, $charset)), "</description>\n"; + echo " <pubDate>$date822</pubDate>\n"; + echo " </item>\n"; + break; + case 'html': + default: + echo " <tr>\n"; + echo " <td class=\"$class\"><a href=\"/$group/$n\">$n</a></td>\n"; + echo " <td class=\"$class\"><a href=\"/$group/$n\">"; + echo format_subject($subj, $charset); + echo "</a></td>\n"; + echo " <td class=\"$class\">".format_author($author, $charset)."</td>\n"; + echo " <td align=\"center\" class=\"$class\"><tt>" . format_date($odate) . "</tt></td>\n"; + echo " <td align=\"right\" class=\"$class\">$lines</td>\n"; + echo " </tr>\n"; + } + $class = ($class == "even") ? "odd" : "even"; } switch ($format) { - case 'rss': - echo "</channel>\n</rss>\n"; - break; - case 'rdf': - echo "</rdf:RDF>\n"; - break; - case 'html': - default: - echo "</table>\n"; - navbar($group,$f,$l,$i); - foot(); -} - -function navbar($g,$f,$l,$i) { - echo '<table border="0" cellpadding="2" cellspacing="2" width="100%"><tr class="alisthead">'; - echo '<td width="20%">'; - if ($i > $f) { - $p = max($i-20,$f); - echo "<a href=\"/".htmlspecialchars($g)."/start/$p\"><b>« previous</b></a>"; - } - else { - echo " "; - } - echo '</td>'; - $j = min($i+20,$l); - $c = $l - $f + 1; - echo '<td align="center" class="alisthead" width="60%">'.htmlspecialchars($g)." ($i-$j of $c)</td>"; - echo '<td align="right" width="20%">'; - if ($i+20 < $l) { - $n = min($i+20,$l-20); - echo "<a href=\"/".htmlspecialchars($g)."/start/$n\"><b>next »</b></a>"; - } - else { - echo " "; - } - echo '</td>'; - echo '</tr></table>'; + case 'rss': + echo " </channel>\n</rss>\n"; + break; + case 'rdf': + echo "</rdf:RDF>\n"; + break; + case 'html': + default: + echo " </table>\n"; + navbar($group, $f, $l, $i); + foot(); +} + +function navbar($g, $f, $l, $i) { + echo ' <table border="0" cellpadding="2" cellspacing="2" width="100%">' . "\n"; + echo ' <tr class="alisthead">' . "\n"; + echo ' <td class="nav">'; + if ($i > $f) { + $p = max($i-20,$f); + echo "<a href=\"/" . htmlspecialchars($g) . "/start/$p\"><b>« previous</b></a>"; + } else { + echo " "; + } + echo '</td>' . "\n"; + $j = min($i + 20, $l); + $c = $l - $f + 1; + echo ' <td align="center" class="alisthead">'.htmlspecialchars($g)." ($i-$j of $c)</td>\n"; + echo ' <td align="right" class="nav">'; + if ($i+20 < $l) { + $n = min($i + 20, $l - 20); + echo "<a href=\"/" . htmlspecialchars($g) . "/start/$n\"><b>next »</b></a>"; + } + else { + echo " "; + } + echo '</td>' . "\n"; + echo ' </tr>' . "\n"; + echo ' </table>' . "\n"; } http://cvs.php.net/diff.php/php-news-web/index.php?r1=1.9&r2=1.10&ty=u Index: php-news-web/index.php diff -u php-news-web/index.php:1.9 php-news-web/index.php:1.10 --- php-news-web/index.php:1.9 Tue Jan 25 19:01:54 2005 +++ php-news-web/index.php Wed Jan 26 11:52:39 2005 @@ -3,52 +3,72 @@ require 'common.inc'; require 'nntp.inc'; -$s = nntp_connect(NNTP_HOST) - or die("failed to connect to news server"); +$s = nntp_connect(NNTP_HOST); +if (!$s) { + error("Failed to connect to news server"); +} -nntp_cmd($s,"LIST",215) - or die("failed to get list of news groups"); -head(); +if (!nntp_cmd($s,"LIST",215)) { + error("failed to get list of news groups"); +} -echo '<table border="0" cellpadding="6" cellspacing="0"><tr><td>'; +head(); -echo "<table class=\"grouplist\">\n"; -echo '<tr><td class="grouplisthead">name</td><td class="grouplisthead">messages</td><td class="grouplisthead">rss</td><td class="grouplisthead">rdf</td></tr>',"\n"; +?> + <table border="0" cellpadding="6" cellspacing="0"> + <tr> + <td> + <table class="grouplist"> + <tr class="grouplisthead"> + <td>name</td> + <td>messages</td> + <td>rss</td> + <td>rdf</td> + </tr> +<?php $class = "even"; while ($line = fgets($s, 1024)) { - if ($line == ".\r\n") break; - $line = chop($line); - list($group,$high,$low,$active) = explode(" ", $line); - echo "<tr>"; - echo "<td class=\"$class\">"; - echo "<a class=\"active$active\" href=\"/$group\">$group</a>"; - echo "</td>\n"; - echo "<td align=\"right\" class=\"$class\">", $high-$low+1, "</td>\n"; - echo "<td class=\"$class\">"; - if ($active != 'n') { - echo "<a href=\"group.php?group=$group&format=rss\">rss</a>"; - } - echo "</td>\n"; - echo "<td class=\"$class\">"; - if ($active != 'n') { - echo "<a href=\"group.php?group=$group&format=rdf\">rdf</a>"; - } - echo "</td>\n"; - echo "</tr>\n"; - $class = $class == "even" ? "odd" : "even"; + if ($line == ".\r\n") { + break; + } + $line = chop($line); + list($group, $high, $low, $active) = explode(" ", $line); + echo " <tr>\n"; + echo " <td class=\"$class\"><a class=\"active$active\" href=\"/$group\">$group</a></td>\n"; + echo " <td align=\"right\" class=\"$class\">", $high-$low+1, "</td>\n"; + echo " <td class=\"$class\">"; + if ($active != 'n') { + echo "<a href=\"group.php?group=$group&format=rss\">rss</a>"; + } + echo "</td>\n"; + echo " <td class=\"$class\">"; + if ($active != 'n') { + echo "<a href=\"group.php?group=$group&format=rdf\">rdf</a>"; + } + echo "</td>\n"; + echo " </tr>\n"; + $class = ($class == "even") ? "odd" : "even"; } -echo "</table>\n"; - -echo '</td><td valign="top">'; ?> -<h1>Welcome!</h1> -<p>This is a completely experimental interface to the PHP mailing -lists as reflected on the <a href="news://<?php echo $_SERVER['HTTP_HOST']; ?>/"> -<?php echo $_SERVER['HTTP_HOST']; ?> NNTP server</a>.</p> -<p>There may be a little more info in the <a href="README">README</a> file.</p> -<p>The news server software that is used is <a -href="http://trainedmonkey.com/colobus/">colobus</a>.</p> + </table> + </td> + <td valign="top"> + <h1>Welcome!</h1> + <p> + This is a completely experimental interface to the PHP mailing lists as + reflected on the <a href="news://<?php echo $_SERVER['HTTP_HOST']; ?>/"> + <?php echo $_SERVER['HTTP_HOST']; ?> NNTP server</a>. + </p> + <p> + There may be a little more info in the <a href="README">README</a> file. + </p> + <p> + The news server software that is used is <a + href="http://trainedmonkey.com/colobus/">colobus</a>. + </p> + </td> + </tr> + </table> <?php -echo '</td></tr></table>'; foot(); http://cvs.php.net/diff.php/php-news-web/nntp.inc?r1=1.3&r2=1.4&ty=u Index: php-news-web/nntp.inc diff -u php-news-web/nntp.inc:1.3 php-news-web/nntp.inc:1.4 --- php-news-web/nntp.inc:1.3 Mon Dec 22 03:39:02 2003 +++ php-news-web/nntp.inc Wed Jan 26 11:52:39 2005 @@ -1,24 +1,23 @@ <?php -function nntp_connect($server,$port=119) { - $s = @fsockopen($server,$port,$errno,$errstr,30); - if (!$s) { - echo "<!-- error connecting to nntp server: $errstr -->\n"; - return false; - } - $hello = fgets($s, 1024); - if (substr($hello,0,4) != "200 ") { - echo "<!-- unexpected greeting: $hello -->\n"; - return false; - } - #echo "<!-- $hello -->\n"; - return $s; +function nntp_connect($server, $port = 119) { + $s = @fsockopen($server, $port, $errno, $errstr, 30); + if (!$s) { + return false; + } + $hello = fgets($s, 1024); + if (substr($hello,0,4) != "200 ") { + return false; + } + return $s; } -function nntp_cmd($conn,$command,$expected) { - if (strlen($command) > 510) die("command too long: $command"); - fputs($conn, "$command\r\n"); - $res = fgets($conn, 1024); - list($code,$extra) = explode(" ", $res, 2); - return $code == $expected ? $extra : false; +function nntp_cmd($conn, $command, $expected) { + if (strlen($command) > 510) { + die("command too long: $command"); + } + fputs($conn, "$command\r\n"); + $res = fgets($conn, 1024); + list($code, $extra) = explode(" ", $res, 2); + return ($code == $expected) ? $extra : false; } http://cvs.php.net/diff.php/php-news-web/style.css?r1=1.4&r2=1.5&ty=u Index: php-news-web/style.css diff -u php-news-web/style.css:1.4 php-news-web/style.css:1.5 --- php-news-web/style.css:1.4 Mon Oct 14 20:45:39 2002 +++ php-news-web/style.css Wed Jan 26 11:52:39 2005 @@ -3,32 +3,118 @@ font-size: 95%; } -body { margin: 0px; background: white; color: black; } -td,th { color: black; } - -.quote { color: green; } - -.signature { font-size: smaller; color: gray; } -.signature a:link { color: #9999ff; } -.signature a:hover { color: #ff9999; } -.signature a:active { color: #ff9999; } -.signature a:visited { color: #ff66ff; } - -a:link { color: blue; } -a:hover { color: red; } -a:active { color: red; } -a:visited { color: purple; } - -.grouplisthead { background: #cccccc; font-weight: bold; text-align: center; } -.even { background: #eeeeee; } -.odd { background: #dddddd; } -.grouplistmsgs { text-align: right; } - -.alisthead { background: #cccccc; font-weight: bold; text-align: center; } - -.activen { color: gray; } - -.headerlabel { background: #cccccc; font-weight: bold; text-align: right; } -.headervalue { background: #eeeeee; } - -a.top { text-decoration: none; color: blue; } \ No newline at end of file +body { + margin: 0px; + background: #ffffff; + color: #000000; +} + +td,th { + color: #000000; +} + + +img { + border : 0px; +} + +a:link { + color: #000099; +} + +a:hover { + color: #ff0000; +} + +a:active { + color: #ff0000; +} + +a:visited { + color: #000099; +} + +.quote { + color: green; +} + +.signature { + font-size: smaller; + color: gray; +} + +.signature a:link { + color: #9999ff; +} + +.signature a:hover { + color: #ff9999; +} + +.signature a:active { + color: #ff9999; +} + +.signature a:visited { + color: #ff66ff; +} + +.grouplisthead { + background: #cccccc; + font-weight: bold; + text-align: center; +} + +.even { + background: #eeeeee; +} + +.odd { + background: #dddddd; +} + +.grouplistmsgs { + text-align: right; +} + +.alisthead { + background: #cccccc; + font-weight: bold; + text-align: center; +} + +.activen { + color: gray; +} + +.headerlabel { + background: #cccccc; + font-weight: bold; + text-align: right; +} + +.headervalue { + background: #eeeeee; +} + +a.top { + text-decoration: none; +} + +tr.header { + background: #9999cc; +} + +tr.subheader { + background: #666699; + height : 2px; +} + +.small { + font-size: 75%; + text-align: right; +} + +.nav { + width: 20%; +} \ No newline at end of file http://cvs.php.net/diff.php/php-news-web/i/l.gif?r1=1.1&r2=1.2&ty=u Index: php-news-web/i/l.gif
http://cvs.php.net/diff.php/php-news-web/article.php?r1=1.28&r2=1.29&ty=u Index: php-news-web/article.php diff -u php-news-web/article.php:1.28 php-news-web/article.php:1.29 --- php-news-web/article.php:1.28 Mon Dec 27 10:42:10 2004 +++ php-news-web/article.php Wed Jan 26 11:52:39 2005 @@ -1,21 +1,36 @@ <?php -// vim:sw=2:ts=2:et - -$article = (int)$article; -if (!$article) die("no article specified"); require 'common.inc'; require 'nntp.inc'; -$s = nntp_connect(NNTP_HOST) - or die("failed to connect to news server"); +if (isset($_GET['article'])) { + $article = (int)$_GET['article']; +} else { + error("No article specified"); +} + +if (isset($_GET['group'])) { + $group = $_GET['group']; +} else { + $group = false; +} + +$s = nntp_connect(NNTP_HOST); +if (!$s) { + error("Failed to connect to news server"); +} if ($group) { - $res = nntp_cmd($s,"GROUP $group",211) - or die("failed to select group .".htmlspecialchars($group)); + $res = nntp_cmd($s,"GROUP $group",211); + if (!$res) { + error("Failed to select group"); + } +} + +$res = nntp_cmd($s, "ARTICLE $article",220); +if (!$res) { + error("Failed to get article ". $article); } -$res = nntp_cmd($s, "ARTICLE $article",220) - or die("failed to get article ".htmlspecialchars($article)); $started = 0; $inheaders = 1; $headers = array(); @@ -24,183 +39,216 @@ $mimecount = 0; // number of mime parts $boundaries = array(); $lk = ''; +$prevquote = 0; +$prevline = ''; while (!feof($s)) { - $line = fgets($s, 4096); - if ($line == ".\r\n") break; - if ($inheaders && ($line == "\n" || $line == "\r\n")) { - $inheaders = 0; - if ($headers['content-type'] - && preg_match("/charset=(\"|'|)(.+)\\1/is", $headers['content-type'], $m)) { - $charset = trim($m[2]); - } - if ($headers['content-type'] - && preg_match("/boundary=(\"|'|)(.+)\\1/is", $headers['content-type'], $m)) { - $boundaries[] = trim($m[2]); - $boundary = end($boundaries); - } - if ($headers['content-type'] - && preg_match("/([^;]+)(;|\$)/", $headers['content-type'], $m)) { - $mimetype = trim(strtolower($m[1])); - ++$mimecount; - } - if (!$started) { - head("$group: ".format_title($headers[subject], $charset)); - start_article($group,$headers,$charset); - $started = 1; - } - - $encoding = strtolower(trim($headers['content-transfer-encoding'])); - if (strlen($mimetype) - && $mimetype != "text/plain" - && substr($mimetype,0,10) != "multipart/") { - # Display a link to the attachment - $name = ""; - if ($headers['content-type'] - && preg_match("/name=(\"|'|)(.+)\\1/s", $headers['content-type'], $m)) - $name = trim($m[2]); - else if ($headers['content-disposition'] - && preg_match("/filename=(\"|'|)(.+)\\1/s", $headers['content-type'], $m)) - $name = trim($m[2]); - - if ($headers['content-description']) - $description = trim($headers['content-description']) . " "; - else - $description = ""; - - $description .= $name; - $link_desc = "[$mimetype]"; - if (strlen($description)) - $link_desc .= " " . $description; - - $dl_link = "/getpart.php?group=$group&article=$article&part=$mimecount"; - - echo "Attachment: <a target=\"_blank\" href=\"$dl_link\">${link_desc}</a><br />\n"; - } - - if ($masterheaders == null) - $headers = $masterheaders; - continue; - } - # fix lines that started with a period and got escaped - if (substr($line,0,2) == "..") $line = substr($line,1); - if ($inheaders) { - list($k,$v) = explode(": ", $line, 2); - if ($k && $v) { - $headers[strtolower($k)] = $v; - $lk = strtolower($k); - } - else { - $headers[$lk] .= $line; - } - } - else { - - if ($boundary - && substr($line,0,2) == '--' - && substr($line,2,strlen($boundary)) == $boundary) { - - $inheaders = 1; - - if (substr($line,2+strlen($boundary)) == '--') { - # end of this container - array_pop($boundaries); - $boundary = end($boundaries); - } else { - # next section; start with an inherited set of headers - $headers = $masterheaders; - $mimetype = ""; - } - - continue; - } - - if (strlen($mimetype) && $mimetype != "text/plain") - continue; - - switch($encoding) { - case "quoted-printable": - $line = quoted_printable_decode($line); - break; - case "base64": - $line = base64_decode($line); - break; - } - if (strlen($charset)) - $line = to_utf8($line, $charset); - - # this is some amazingly simplistic code to color quotes/signatures - # differently, and turn links into real links. it actually appears - # to work fairly well, but could easily be made more sophistimicated. - $line = htmlentities($line,ENT_NOQUOTES,"utf-8"); - $line = preg_replace("/((mailto|http|ftp|nntp|news):.+?)(>|\\s|\\)|\\.\\s|$)/","<a href=\"\\1\">\\1</a>\\3",$line); - if (!$insig && $line == "-- \r\n") { - echo "<span class=\"signature\">"; - $insig = 1; - } - if ($insig && $line == "\r\n") { - echo "</span>"; - $insig = 0; - } - if (!$insig && substr($line,0,4) == ">") { - echo "<span class=\"quote\">$line</span>"; - } - else { - echo $line; - } - } + $line = fgets($s, 4096); + if ($line == ".\r\n") break; + if ($inheaders && ($line == "\n" || $line == "\r\n")) { + $inheaders = 0; + if ($headers['content-type'] + && preg_match("/charset=(\"|'|)(.+)\\1/is", $headers['content-type'], $m)) { + $charset = trim($m[2]); + } + if ($headers['content-type'] + && preg_match("/boundary=(\"|'|)(.+)\\1/is", $headers['content-type'], $m)) { + $boundaries[] = trim($m[2]); + $boundary = end($boundaries); + } + if ($headers['content-type'] + && preg_match("/([^;]+)(;|\$)/", $headers['content-type'], $m)) { + $mimetype = trim(strtolower($m[1])); + ++$mimecount; + } + if (!$started) { + head("$group: ".format_title($headers['subject'], $charset)); + start_article($group,$headers,$charset); + $started = 1; + } + + $encoding = strtolower(trim($headers['content-transfer-encoding'])); + if (strlen($mimetype) + && $mimetype != "text/plain" + && substr($mimetype,0,10) != "multipart/") { + # Display a link to the attachment + $name = ''; + if ($headers['content-type'] + && preg_match("/name=(\"|'|)(.+)\\1/s", $headers['content-type'], $m)) { + $name = trim($m[2]); + } else if ($headers['content-disposition'] + && preg_match("/filename=(\"|'|)(.+)\\1/s", $headers['content-type'], $m)) { + $name = trim($m[2]); + } + + if ($headers['content-description']) { + $description = trim($headers['content-description']) . " "; + } else { + $description = ''; + } + + $description .= $name; + $link_desc = "[$mimetype]"; + if (strlen($description)) { + $link_desc .= " " . $description; + } + + $dl_link = "/getpart.php?group=$group&article=$article&part=$mimecount"; + + echo "Attachment: <a href=\"$dl_link\">${link_desc}</a><br />\n"; + } + + if ($masterheaders == null) { + $headers = $masterheaders; + } + continue; + } + # fix lines that started with a period and got escaped + if (substr($line,0,2) == "..") { + $line = substr($line,1); + } + + if ($inheaders) { + list($k,$v) = explode(": ", $line, 2); + if ($k && $v) { + $headers[strtolower($k)] = $v; + $lk = strtolower($k); + } else { + $headers[$lk] .= $line; + } + } + else { + + if ($boundary + && substr($line,0,2) == '--' + && substr($line,2,strlen($boundary)) == $boundary) { + + $inheaders = 1; + + if (substr($line,2+strlen($boundary)) == '--') { + # end of this container + array_pop($boundaries); + $boundary = end($boundaries); + } else { + # next section; start with an inherited set of headers + $headers = $masterheaders; + $mimetype = ""; + } + + continue; + } + + if (strlen($mimetype) && $mimetype != "text/plain") { + continue; + } + + switch($encoding) { + case "quoted-printable": + $line = quoted_printable_decode($line); + break; + case "base64": + $line = base64_decode($line); + break; + } + if (strlen($charset)) { + $line = to_utf8($line, $charset); + } + + # this is some amazingly simplistic code to color quotes/signatures + # differently, and turn links into real links. it actually appears + # to work fairly well, but could easily be made more sophistimicated. + $line = htmlentities($line,ENT_NOQUOTES,"utf-8"); + $line = preg_replace("/((mailto|http|ftp|nntp|news):.+?)(>|\\s|\\)|\\.\\s|$)/","<a href=\"\\1\">\\1</a>\\3",$line); + if (!$insig && $line == "-- \r\n") { + echo "<span class=\"signature\">"; + $insig = 1; + } + if ($insig && $line == "\r\n") { + echo "</span>"; + $insig = 0; + } + if ( + (!$insig && substr($line,0,4) == ">") || + ($prevquote && !in_array(substr($prevline, -1), array("\r","\n"))) + ) { + echo "<span class=\"quote\">$line</span>"; + $prevquote = 1; + } else { + echo $line; + $prevquote = 0; + } + $prevline = $line; + } } if ($inheaders && !$started) { - head("$group: ". $headers[subject]); - start_article($group,$headers,$charset); + head("$group: ". $headers[subject]); + start_article($group,$headers,$charset); +} +if ($insig) { + echo "</span>"; } -if ($insig) echo "</span>"; -echo "</pre></blockquote>"; +echo " </pre>\n"; +echo " </blockquote>\n"; function start_article ($group,$headers,$charset) { - echo "<blockquote>\n"; - echo '<table border="0" cellpadding="2" cellspacing="2" width="100%">'; - # from - echo '<tr><td class="headerlabel">From:</td><td class="headervalue">'.format_author($headers['from'], $charset)."</td>\n"; - # date - echo '<td class="headerlabel">Date:</td><td class="headervalue">'.format_date($headers["date"])."</td></tr>\n"; - # subject - echo '<tr><td class="headerlabel">Subject:</td><td class="headervalue" colspan="3">'.format_subject($headers["subject"], $charset)."</td></tr>\n"; - echo "<tr>"; - # references - if ($headers["references"] || $headers["in-reply-to"]) { - $ref = $headers["references"] ? $headers["references"] : $headers["in-reply-to"]; - echo '<td class="headerlabel">References:</td><td class="headervalue">'; - $r = explode(" ", $ref); - $c = 1; - $s = nntp_connect(NNTP_HOST) - or die("failed to connect to news server"); - while (list($k,$v) = each($r)) { - if (!$v) continue; - $v = trim($v); - if (!preg_match("/^<.+>\$/", $v)) continue; - $res2 = nntp_cmd($s, "XPATH $v",223) - or print("failed to get reference article id ".htmlspecialchars($v)."<br />\n"); - list(,$v) = split("/", trim($res2)); - if (empty($v)) continue; - echo "<a href=\"/$group/".htmlspecialchars(urlencode($v))."\">".($c++)."</a>\n"; - } - echo "</td>\n"; - } - # groups - if ($headers["newsgroups"]) { - echo '<td class="headerlabel">Groups:</td><td class="headervalue">'; - $r = explode(",", chop($headers["newsgroups"])); - while (list($k,$v) = each($r)) { - echo "<a href=\"/".htmlspecialchars(urlencode($v))."\">".htmlspecialchars($v)."</a>\n"; - } - echo "</td>\n"; - } - echo "</tr>"; - //while (list($k,$v) = each($headers)) { - // echo "<!-- ", htmlspecialchars($k),": ",preg_replace("/-+/", "-", htmlspecialchars($v))," -->\n"; - //} - echo "</table></blockquote>\n"; - echo "<blockquote><pre>"; + echo " <blockquote>\n"; + echo ' <table border="0" cellpadding="2" cellspacing="2" width="100%">' . "\n"; + # from + echo ' <tr>' . "\n"; + echo ' <td class="headerlabel">From:</td>' . "\n"; + echo ' <td class="headervalue">' . format_author($headers['from'], $charset)."</td>\n"; + # date + echo ' <td class="headerlabel">Date:</td>' . "\n"; + echo ' <td class="headervalue">' . format_date($headers["date"])."</td>\n"; + echo " </tr>\n"; + # subject + echo ' <tr>' . "\n"; + echo ' <td class="headerlabel">Subject:</td>' . "\n"; + echo ' <td class="headervalue" colspan="3">'.format_subject($headers["subject"], $charset)."</td>\n"; + echo " </tr>\n"; + echo " <tr>\n"; + # references + if ($headers["references"] || $headers["in-reply-to"]) { + $ref = $headers["references"] ? $headers["references"] : $headers["in-reply-to"]; + echo ' <td class="headerlabel">References:</td>' . "\n"; + echo ' <td class="headervalue">'; + $r = explode(" ", $ref); + $c = 1; + $s = nntp_connect(NNTP_HOST) + or die("failed to connect to news server"); + while (list($k,$v) = each($r)) { + if (!$v) continue; + $v = trim($v); + if (!preg_match("/^<.+>\$/", $v)) { + continue; + } + $res2 = nntp_cmd($s, "XPATH $v",223) + or print("failed to get reference article id ".htmlspecialchars($v)."<br />"); + list(,$v) = split("/", trim($res2)); + if (empty($v)) { + continue; + } + echo "<a href=\"/$group/".htmlspecialchars(urlencode($v))."\">".($c++)."</a>"; + } + echo "</td>\n"; + } + # groups + if ($headers["newsgroups"]) { + echo ' <td class="headerlabel">Groups:</td>' . "\n"; + echo ' <td class="headervalue">'; + $r = explode(",", chop($headers["newsgroups"])); + while (list($k,$v) = each($r)) { + echo "<a href=\"/".htmlspecialchars(urlencode($v))."\">".htmlspecialchars($v)."</a>"; + } + echo "</td>\n"; + } + echo " </tr>\n"; + //while (list($k,$v) = each($headers)) { + // echo "<!-- ", htmlspecialchars($k),": ",preg_replace("/-+/", "-", htmlspecialchars($v))," -->\n"; + //} + echo " </table>\n"; + echo " </blockquote>\n"; + echo " <blockquote>\n"; + echo " <pre>\n"; } foot(); http://cvs.php.net/diff.php/php-news-web/common.inc?r1=1.28&r2=1.29&ty=u Index: php-news-web/common.inc diff -u php-news-web/common.inc:1.28 php-news-web/common.inc:1.29 --- php-news-web/common.inc:1.28 Tue Jan 25 19:03:19 2005 +++ php-news-web/common.inc Wed Jan 26 11:52:39 2005 @@ -1,100 +1,109 @@ -<?php # vim:ft=php:ts=2:sw=2:et +<?php define('NNTP_HOST', 'localhost'); +function error($str) { + head("PHP news : error"); + echo "<p><strong>Error:</strong> $str</p>\n"; + foot(); + die(); +} + function head($title="PHP news") { - header("Content-type: text/html; charset=utf-8"); + header("Content-type: text/html; charset=utf-8"); + echo '<?xml version="1.0"?>' . "\n"; + ?> -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> -<html> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> - <title><?php echo $title?></title> - <link rel="stylesheet" href="/style.css" type="text/css" /> -</head> -<body leftmargin="0" topmargin="0" marginheight="0" marginwidth="0"> -<table width="100%" border="0" cellspacing="0" cellpadding="0"> - <tr bgcolor="#9999cc"> - <td> - <a href="/index.php"><img src="/i/l.gif" border="0" width="120" height="64" alt="php" /></a> - </td> - <td align="right" valign="bottom"> - PHP.net <a href="news://<?php echo $_SERVER['HTTP_HOST']; ?>/" clas="top">news server</a> web interface - </td> - </tr> - <tr bgcolor="#333366"> - <td colspan="3"><img src="/i/g.gif" width="1" height="1" alt="" /></td> - </tr> -</table> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <title><?php echo $title?></title> + <link rel="stylesheet" href="/style.css" type="text/css" /> + </head> + <body> + <table width="100%" border="0" cellspacing="0" cellpadding="0"> + <tr class="header"> + <td> + <a href="/index.php"><img src="/i/l.gif" width="120" height="67" alt="PHP" /></a> + </td> + <td align="right" valign="bottom"> + PHP.net <a href="news://<?php echo $_SERVER['HTTP_HOST']; ?>/" class="top">news server</a> web interface + </td> + </tr> + <tr class="subheader"> + <td colspan="2"> + <img src="/i/g.gif" width="1" height="1" alt="" /> + </td> + </tr> + </table> <?php } function foot() {?> -<hr noshade="noshade" size="1" width="60%" align="right" /> -<div align="right"> -<small> -written by jim winstead. no rights reserved. (<a href="http://cvs.php.net/cvs.php/php-news-web">source code</a>) -</small> -</div> -</body> + <hr /> + <div class="small"> + Written by Jim Winstead. no rights reserved. (<a href="http://cvs.php.net/cvs.php/php-news-web">source code</a>) + </div> + </body> </html> <?php } - function to_utf8($str, $charset) - { - $n = iconv(strlen($charset) ? $charset : "iso-8859-1", "utf-8", $str); - if ($n === false) - return $str; - return $n; - } +function to_utf8($str, $charset) +{ + $n = iconv(strlen($charset) ? $charset : "iso-8859-1", "utf-8", $str); + if ($n === false) { + return $str; + } + return $n; +} /* if (function_exists("mb_convert_encoding")) { - function to_utf8($str, $charset) - { - return mb_convert_encoding($str, "utf-8", strlen($charset) ? $charset : "iso-8859-1"); - } +function to_utf8($str, $charset) +{ +return mb_convert_encoding($str, "utf-8", strlen($charset) ? $charset : "iso-8859-1"); +} } else if (function_exists("recode_string")) { - function to_utf8($str, $charset) - { - if (strlen($charset) == 0) - $charset = "iso-8859-1"; - return recode_string("$charset..utf-8", $str); - } +function to_utf8($str, $charset) +{ +if (strlen($charset) == 0) +$charset = "iso-8859-1"; +return recode_string("$charset..utf-8", $str); +} } else if (function_exists("iconv")) { - function to_utf8($str, $charset) - { - return iconv(strlen($charset) ? $charset : "iso-8859-1", "utf-8", $str); - } +function to_utf8($str, $charset) +{ +return iconv(strlen($charset) ? $charset : "iso-8859-1", "utf-8", $str); +} } else { - function to_utf8($str, $charset) - { - return $str; - } +function to_utf8($str, $charset) +{ +return $str; +} } */ function decode_header($charset,$encoding,$text) { - if (strtolower($encoding) == "b") { - $text = base64_decode($text); - } - else { - $text = quoted_printable_decode($text); - } - return to_utf8($text, $charset); + if (strtolower($encoding) == "b") { + $text = base64_decode($text); + } else { + $text = quoted_printable_decode($text); + } + return to_utf8($text, $charset); } -function recode_header($header, $basecharset) -{ - if (strpos($header, "=?") === false) - return to_utf8($header, $basecharset); - return preg_replace("/=\\?(.+?)\\?([qb])\\?(.+?)\\?=/ie", "decode_header('\\1','\\2','\\3')", $header); +function recode_header($header, $basecharset) { + if (strpos($header, "=?") === false) { + return to_utf8($header, $basecharset); + } + return preg_replace("/=\\?(.+?)\\?([qb])\\?(.+?)\\?=/ie", "decode_header('\\1','\\2','\\3')", $header); } /* Email spam protection (taken from php-bugs-web) */ -function spam_protect($txt) -{ +function spam_protect($txt) { $translate = array('@' => ' at ', '.' => ' dot '); /* php.net addresses are not protected! */ @@ -108,49 +117,49 @@ # this turns some common forms of email addresses into mailto: links function format_author($a, $charset) { - $a = recode_header($a, $charset); - if (preg_match("/^\s*(.+)\s+\\(\"?(.+?)\"?\\)\s*$/",$a,$ar)) { - return "<a href=\"mailto:".htmlspecialchars(urlencode(spam_protect($ar[1])))."\">".str_replace(" ", " ", htmlspecialchars($ar[2]))."</a>"; - } - if (preg_match("/^\s*\"?(.+?)\"?\s*<(.+)>\s*$/",$a,$ar)) { - return "<a href=\"mailto:".htmlspecialchars(urlencode(spam_protect($ar[2])))."\">".str_replace(" ", " ", htmlspecialchars($ar[1]))."</a>"; - } - if (ereg("@",$a)) { - $a = spam_protect($a); - return "<a href=\"mailto:".htmlspecialchars(urlencode($a))."\">".htmlspecialchars($a)."</a>"; - } - return str_replace(" ", " ", htmlspecialchars($a)); + $a = recode_header($a, $charset); + if (preg_match("/^\s*(.+)\s+\\(\"?(.+?)\"?\\)\s*$/",$a,$ar)) { + return "<a href=\"mailto:".htmlspecialchars(urlencode(spam_protect($ar[1])))."\">".str_replace(" ", " ", htmlspecialchars($ar[2]))."</a>"; + } + if (preg_match("/^\s*\"?(.+?)\"?\s*<(.+)>\s*$/",$a,$ar)) { + return "<a href=\"mailto:".htmlspecialchars(urlencode(spam_protect($ar[2])))."\">".str_replace(" ", " ", htmlspecialchars($ar[1]))."</a>"; + } + if (ereg("@",$a)) { + $a = spam_protect($a); + return "<a href=\"mailto:".htmlspecialchars(urlencode($a))."\">".htmlspecialchars($a)."</a>"; + } + return str_replace(" ", " ", htmlspecialchars($a)); } function format_subject($s, $charset) { - global $article; - $s = recode_header($s, $charset); - $s = preg_replace("/^(Re: *)?\[(PHP|PEAR)(-.*)?\] /i", "\\1", $s); - // make this look better on the preview page.. - if (strlen($s) > 150 && !isset($article)) { - $s = substr($s, 0, 150) . "..."; - } else { - $s = wordwrap($s, 150); - } - return nl2br(htmlspecialchars($s)); + global $article; + $s = recode_header($s, $charset); + $s = preg_replace("/^(Re: *)?\[(PHP|PEAR)(-.*)?\] /i", "\\1", $s); + // make this look better on the preview page.. + if (strlen($s) > 150 && !isset($article)) { + $s = substr($s, 0, 150) . "..."; + } else { + $s = wordwrap($s, 150); + } + return nl2br(htmlspecialchars($s)); } function format_title($s, $charset) { - global $article; - $s = recode_header($s, $charset); - $s = preg_replace("/^(Re: *)?\[(PHP|PEAR)(-.*)?\] /i", "\\1", $s); - // make this look better on the preview page.. - if (strlen($s) > 150 && !isset($article)) { - $s = substr($s, 0, 150) . "..."; - } else { - $s = wordwrap($s, 150); - } - return $s; + global $article; + $s = recode_header($s, $charset); + $s = preg_replace("/^(Re: *)?\[(PHP|PEAR)(-.*)?\] /i", "\\1", $s); + // make this look better on the preview page.. + if (strlen($s) > 150 && !isset($article)) { + $s = substr($s, 0, 150) . "..."; + } else { + $s = wordwrap($s, 150); + } + return $s; } function format_date($d) { - $d = strtotime($d); - $d = strftime("%c", $d); - return str_replace(" ", " ", $d); + $d = strtotime($d); + $d = strftime("%c", $d); + return str_replace(" ", " ", $d); } http://cvs.php.net/diff.php/php-news-web/getpart.php?r1=1.2&r2=1.3&ty=u Index: php-news-web/getpart.php diff -u php-news-web/getpart.php:1.2 php-news-web/getpart.php:1.3 --- php-news-web/getpart.php:1.2 Wed Dec 22 17:39:19 2004 +++ php-news-web/getpart.php Wed Jan 26 11:52:39 2005 @@ -1,20 +1,42 @@ <?php -// vim:sw=2:ts=2:et -if (!$article) die("no article specified"); -if (!$part) die("no part specified"); require 'common.inc'; require 'nntp.inc'; -$s = nntp_connect(NNTP_HOST) - or die("failed to connect to news server"); +if (isset($_GET['group'])) { + $group = $_GET['group']; +} else { + $group = false; +} + +if (isset($_GET['article'])) { + $article = (int)$_GET['article']; +} else { + error("No article specified"); +} + +if (isset($_GET['part'])) { + $part = $_GET['part']; +} else { + error("No part specified"); +} + +$s = nntp_connect(NNTP_HOST); +if (!$s) { + error("Failed to connect to news server"); +} if ($group) { - $res = nntp_cmd($s,"GROUP $group",211) - or die("failed to select group .".htmlspecialchars($group)); + $res = nntp_cmd($s,"GROUP $group",211); + if (!$res) { + error("Failed to select group"); + } +} + +$res = nntp_cmd($s, "ARTICLE $article",220); +if (!$res) { + error("Failed to get article ". $article); } -$res = nntp_cmd($s, "ARTICLE $article",220) - or die("failed to get article ".htmlspecialchars($article)); $emit = false; @@ -25,88 +47,95 @@ $boundaries = array(); $lk = ''; while (!feof($s)) { - $line = fgets($s, 4096); - if ($line == ".\r\n") break; - if ($inheaders && ($line == "\n" || $line == "\r\n")) { - $inheaders = 0; - if ($headers['content-type'] - && preg_match("/charset=(\"|'|)(.+)\\1/is", $headers['content-type'], $m)) { - $charset = trim($m[2]); - } - if ($headers['content-type'] - && preg_match("/boundary=(\"|'|)(.+)\\1/is", $headers['content-type'], $m)) { - $boundaries[] = trim($m[2]); - $boundary = end($boundaries); - } - if ($headers['content-type'] - && preg_match("/([^;]+)(;|\$)/", $headers['content-type'], $m)) { - $mimetype = trim(strtolower($m[1])); - ++$mimecount; - } - - $emit = ($mimecount == $part); - - $encoding = strtolower(trim($headers['content-transfer-encoding'])); - if ($emit) { - if ($headers['content-type']) - header('Content-Type: ' . $headers['content-type']); - if ($headers['content-disposition']) - header('Content-Disposition: ' . $headers['content-disposition']); - if ($headers['content-description']) - header('Content-Description: ' . $headers['content-description']); - } - - if ($masterheaders == null) - $headers = $masterheaders; - continue; - } - # fix lines that started with a period and got escaped - if (substr($line,0,2) == "..") $line = substr($line,1); - if ($inheaders) { - list($k,$v) = explode(": ", $line, 2); - if ($k && $v) { - $headers[strtolower($k)] = $v; - $lk = strtolower($k); - } - else { - $headers[$lk] .= $line; - } - } - else { - - if ($boundary - && substr($line,0,2) == '--' - && substr($line,2,strlen($boundary)) == $boundary) { - - $inheaders = 1; - - if (substr($line,2+strlen($boundary)) == '--') { - # end of this container - array_pop($boundaries); - $boundary = end($boundaries); - } else { - # next section; start with an inherited set of headers - $headers = $masterheaders; - $mimetype = ""; - } - - continue; - } - - if (!$emit) + $line = fgets($s, 4096); + if ($line == ".\r\n") { + break; + } + if ($inheaders && ($line == "\n" || $line == "\r\n")) { + $inheaders = 0; + if ($headers['content-type'] + && preg_match("/charset=(\"|'|)(.+)\\1/is", $headers['content-type'], $m)) { + $charset = trim($m[2]); + } + if ($headers['content-type'] + && preg_match("/boundary=(\"|'|)(.+)\\1/is", $headers['content-type'], $m)) { + $boundaries[] = trim($m[2]); + $boundary = end($boundaries); + } + if ($headers['content-type'] + && preg_match("/([^;]+)(;|\$)/", $headers['content-type'], $m)) { + $mimetype = trim(strtolower($m[1])); + ++$mimecount; + } + + $emit = ($mimecount == $part); + + $encoding = strtolower(trim($headers['content-transfer-encoding'])); + if ($emit) { + if (isset($headers['content-type'])) { + header('Content-Type: ' . $headers['content-type']); + } + if (isset($headers['content-disposition'])) { + header('Content-Disposition: ' . $headers['content-disposition']); + } + if (isset($headers['content-description'])) { + header('Content-Description: ' . $headers['content-description']); + } + } + + if ($masterheaders == null) { + $headers = $masterheaders; + } continue; + } + # fix lines that started with a period and got escaped + if (substr($line,0,2) == "..") { + $line = substr($line,1); + } + if ($inheaders) { + list($k,$v) = explode(": ", $line, 2); + if ($k && $v) { + $headers[strtolower($k)] = $v; + $lk = strtolower($k); + } else { + $headers[$lk] .= $line; + } + } else { + + if ($boundary + && substr($line,0,2) == '--' + && substr($line,2,strlen($boundary)) == $boundary) { + + $inheaders = 1; + + if (substr($line,2+strlen($boundary)) == '--') { + # end of this container + array_pop($boundaries); + $boundary = end($boundaries); + } else { + # next section; start with an inherited set of headers + $headers = $masterheaders; + $mimetype = ""; + } + + continue; + } + + if (!$emit) { + continue; + } + + switch($encoding) { + case "quoted-printable": + $line = quoted_printable_decode($line); + break; + case "base64": + $line = base64_decode($line); + break; + } + + echo $line; - switch($encoding) { - case "quoted-printable": - $line = quoted_printable_decode($line); - break; - case "base64": - $line = base64_decode($line); - break; - } - - echo $line; - - } + } } http://cvs.php.net/diff.php/php-news-web/group.php?r1=1.19&r2=1.20&ty=u Index: php-news-web/group.php diff -u php-news-web/group.php:1.19 php-news-web/group.php:1.20 --- php-news-web/group.php:1.19 Tue Jan 25 19:01:54 2005 +++ php-news-web/group.php Wed Jan 26 11:52:39 2005 @@ -3,50 +3,84 @@ require 'common.inc'; require 'nntp.inc'; -$s = nntp_connect(NNTP_HOST) - or die("failed to connect to news server"); +if (isset($_GET['group'])) { + $group = $_GET['group']; +} else { + error("Missing group"); +} -$res = nntp_cmd($s,"GROUP $group",211) - or die("failed to get info on group"); -list (,$f,$l,$g) = explode(" ", $res); -$i=(int)$i; -if (!$i || $i > $l - 20 || $i < $f) $i = $l - $f > 20 ? $l - 20 : $f; -$n = min($l+1,$i+20); -$res = nntp_cmd($s,"XOVER $i-$n", 224) - or die("failed to get xover data\n"); +if (isset($_GET['format'])) { + $format = $_GET['format']; +} else { + // assume html + $format = 'html'; +} + +if (isset($_GET['i'])) { + $i = (int)$_GET['i']; +} else { + $i = 0; +} + +$s = nntp_connect(NNTP_HOST); +if (!$s) { + error("Failed to connect to news server"); +} + +$res = nntp_cmd($s,"GROUP $group",211); +if (!$res) { + error("Failed to get info on group"); +} + +list (, $f, $l, $g) = explode(" ", $res); +if (!$i || $i > $l - 20 || $i < $f) { + $i = $l - $f > 20 ? $l - 20 : $f; +} +$n = min($l + 1, $i + 20); + +$res = nntp_cmd($s,"XOVER $i-$n", 224); +if (!$res) { + error("Failed to get xover data"); +} switch($format) { - case 'rss': - header("Content-type: text/xml"); - echo '<?xml version="1.0" encoding="utf-8"?>';?> + case 'rss': + header("Content-type: text/xml"); + echo '<?xml version="1.0" encoding="utf-8"?>' . "\n";?> <rss version="0.93"> -<channel> - <title><?php echo $_SERVER['HTTP_HOST']; ?>: <?php echo $group?></title> - <link>http://<?php echo $_SERVER['HTTP_HOST']; ?>/group.php?group=<?php echo $group?></link> - <description></description> + <channel> + <title><?php echo $_SERVER['HTTP_HOST']; ?>: <?php echo $group?></title> + <link>http://<?php echo $_SERVER['HTTP_HOST']; ?>/group.php?group=<?php echo $group?></link> + <description></description> <?php break; - case 'rdf': - header("Content-type: text/xml"); - echo '<?xml version="1.0" encoding="utf-8"?>'; +case 'rdf': +header("Content-type: text/xml"); +echo '<?xml version="1.0" encoding="utf-8"?>' . "\n"; ?> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://my.netscape.com/rdf/simple/0.9/"> -<channel> + <channel> <title><?php echo $_SERVER['HTTP_HOST']; ?>: <?php echo $group?></title> <link>http://<?php echo $_SERVER['HTTP_HOST']; ?>/group.php?group=<?php echo $group?></link> <description><?php echo $group?> Newsgroup at <?php echo NNTP_HOST; ?></description> <language>en-US</language> -</channel> + </channel> <?php break; - case 'html': - default: - head($group); - navbar($group,$f,$l,$i); - echo '<table class="alist" width="100%">'; - echo '<tr><td class="alisthead">#</td><td class="alisthead">subject</td><td class="alisthead">author</td><td class="alisthead">date</td><td class="alisthead">lines</td></tr>',"\n"; - break; +case 'html': +default: +head($group); +navbar($group,$f,$l,$i); +echo ' <table class="alist" width="100%">' . "\n"; +echo ' <tr>' . "\n"; +echo ' <td class="alisthead">#</td>' . "\n"; +echo ' <td class="alisthead">subject</td>' . "\n"; +echo ' <td class="alisthead">author</td>' . "\n"; +echo ' <td class="alisthead">date</td>' . "\n"; +echo ' <td class="alisthead">lines</td>' . "\n"; +echo ' </tr>' . "\n"; +break; } # list of articles @@ -55,80 +89,82 @@ $charset = ""; while ($line = fgets($s, 16384)) { - if ($line == ".\r\n") break; - $line = chop($line); - list($n,$subj,$author,$odate,$messageid,$references,$bytes,$lines,$extra) - = explode("\t", $line, 9); -/* $date = date("H:i:s M/d/y", strtotime($odate)); */ - $date822 = date("r", strtotime($odate)); - - switch($format) { - case 'rss': - echo "<item>\n"; - echo "<link>http://{$_SERVER['HTTP_HOST']}/$group/$n</link>\n"; - echo "<title>", format_subject($subj, $charset), "</title>\n"; - echo "<description>", htmlspecialchars(format_author($author, $charset)), "</description>\n"; - echo "<pubDate>$date822</pubDate>\n"; - echo "</item>\n"; - break; - case 'rdf': - echo "<item>\n"; - echo "<title>", format_subject($subj, $charset), "</title>\n"; - echo "<link>http://{$_SERVER['HTTP_HOST']}/$group/$n</link>\n"; - echo "<description>", htmlspecialchars(format_author($author, $charset)), "</description>\n"; - echo "<pubDate>$date822</pubDate>\n"; - echo "</item>\n"; - break; - case 'html': - default: - echo "<tr>"; - echo "<td class=\"$class\"><a href=\"/$group/$n\">$n</a></td>"; - echo "<td class=\"$class\"><a href=\"/$group/$n\">"; - echo format_subject($subj, $charset); - echo "</a></td>"; - echo "<td class=\"$class\">".format_author($author, $charset)."</td>\n"; - echo "<td align=\"center\" class=\"$class\"><tt>" . format_date($odate) . "</tt></td>\n"; - echo "<td align=\"right\" class=\"$class\">$lines</td>\n"; - } - $class = $class == "even" ? "odd" : "even"; + if ($line == ".\r\n") break; + $line = chop($line); + list($n,$subj,$author,$odate,$messageid,$references,$bytes,$lines,$extra) + = explode("\t", $line, 9); + /* $date = date("H:i:s M/d/y", strtotime($odate)); */ + $date822 = date("r", strtotime($odate)); + + switch($format) { + case 'rss': + echo " <item>\n"; + echo " <link>http://{$_SERVER['HTTP_HOST']}/$group/$n</link>\n"; + echo " <title>", format_subject($subj, $charset), "</title>\n"; + echo " <description>", htmlspecialchars(format_author($author, $charset)), "</description>\n"; + echo " <pubDate>$date822</pubDate>\n"; + echo " </item>\n"; + break; + case 'rdf': + echo " <item>\n"; + echo " <title>", format_subject($subj, $charset), "</title>\n"; + echo " <link>http://{$_SERVER['HTTP_HOST']}/$group/$n</link>\n"; + echo " <description>", htmlspecialchars(format_author($author, $charset)), "</description>\n"; + echo " <pubDate>$date822</pubDate>\n"; + echo " </item>\n"; + break; + case 'html': + default: + echo " <tr>\n"; + echo " <td class=\"$class\"><a href=\"/$group/$n\">$n</a></td>\n"; + echo " <td class=\"$class\"><a href=\"/$group/$n\">"; + echo format_subject($subj, $charset); + echo "</a></td>\n"; + echo " <td class=\"$class\">".format_author($author, $charset)."</td>\n"; + echo " <td align=\"center\" class=\"$class\"><tt>" . format_date($odate) . "</tt></td>\n"; + echo " <td align=\"right\" class=\"$class\">$lines</td>\n"; + echo " </tr>\n"; + } + $class = ($class == "even") ? "odd" : "even"; } switch ($format) { - case 'rss': - echo "</channel>\n</rss>\n"; - break; - case 'rdf': - echo "</rdf:RDF>\n"; - break; - case 'html': - default: - echo "</table>\n"; - navbar($group,$f,$l,$i); - foot(); -} - -function navbar($g,$f,$l,$i) { - echo '<table border="0" cellpadding="2" cellspacing="2" width="100%"><tr class="alisthead">'; - echo '<td width="20%">'; - if ($i > $f) { - $p = max($i-20,$f); - echo "<a href=\"/".htmlspecialchars($g)."/start/$p\"><b>« previous</b></a>"; - } - else { - echo " "; - } - echo '</td>'; - $j = min($i+20,$l); - $c = $l - $f + 1; - echo '<td align="center" class="alisthead" width="60%">'.htmlspecialchars($g)." ($i-$j of $c)</td>"; - echo '<td align="right" width="20%">'; - if ($i+20 < $l) { - $n = min($i+20,$l-20); - echo "<a href=\"/".htmlspecialchars($g)."/start/$n\"><b>next »</b></a>"; - } - else { - echo " "; - } - echo '</td>'; - echo '</tr></table>'; + case 'rss': + echo " </channel>\n</rss>\n"; + break; + case 'rdf': + echo "</rdf:RDF>\n"; + break; + case 'html': + default: + echo " </table>\n"; + navbar($group, $f, $l, $i); + foot(); +} + +function navbar($g, $f, $l, $i) { + echo ' <table border="0" cellpadding="2" cellspacing="2" width="100%">' . "\n"; + echo ' <tr class="alisthead">' . "\n"; + echo ' <td class="nav">'; + if ($i > $f) { + $p = max($i-20,$f); + echo "<a href=\"/" . htmlspecialchars($g) . "/start/$p\"><b>« previous</b></a>"; + } else { + echo " "; + } + echo '</td>' . "\n"; + $j = min($i + 20, $l); + $c = $l - $f + 1; + echo ' <td align="center" class="alisthead">'.htmlspecialchars($g)." ($i-$j of $c)</td>\n"; + echo ' <td align="right" class="nav">'; + if ($i+20 < $l) { + $n = min($i + 20, $l - 20); + echo "<a href=\"/" . htmlspecialchars($g) . "/start/$n\"><b>next »</b></a>"; + } + else { + echo " "; + } + echo '</td>' . "\n"; + echo ' </tr>' . "\n"; + echo ' </table>' . "\n"; } http://cvs.php.net/diff.php/php-news-web/index.php?r1=1.9&r2=1.10&ty=u Index: php-news-web/index.php diff -u php-news-web/index.php:1.9 php-news-web/index.php:1.10 --- php-news-web/index.php:1.9 Tue Jan 25 19:01:54 2005 +++ php-news-web/index.php Wed Jan 26 11:52:39 2005 @@ -3,52 +3,72 @@ require 'common.inc'; require 'nntp.inc'; -$s = nntp_connect(NNTP_HOST) - or die("failed to connect to news server"); +$s = nntp_connect(NNTP_HOST); +if (!$s) { + error("Failed to connect to news server"); +} -nntp_cmd($s,"LIST",215) - or die("failed to get list of news groups"); -head(); +if (!nntp_cmd($s,"LIST",215)) { + error("failed to get list of news groups"); +} -echo '<table border="0" cellpadding="6" cellspacing="0"><tr><td>'; +head(); -echo "<table class=\"grouplist\">\n"; -echo '<tr><td class="grouplisthead">name</td><td class="grouplisthead">messages</td><td class="grouplisthead">rss</td><td class="grouplisthead">rdf</td></tr>',"\n"; +?> + <table border="0" cellpadding="6" cellspacing="0"> + <tr> + <td> + <table class="grouplist"> + <tr class="grouplisthead"> + <td>name</td> + <td>messages</td> + <td>rss</td> + <td>rdf</td> + </tr> +<?php $class = "even"; while ($line = fgets($s, 1024)) { - if ($line == ".\r\n") break; - $line = chop($line); - list($group,$high,$low,$active) = explode(" ", $line); - echo "<tr>"; - echo "<td class=\"$class\">"; - echo "<a class=\"active$active\" href=\"/$group\">$group</a>"; - echo "</td>\n"; - echo "<td align=\"right\" class=\"$class\">", $high-$low+1, "</td>\n"; - echo "<td class=\"$class\">"; - if ($active != 'n') { - echo "<a href=\"group.php?group=$group&format=rss\">rss</a>"; - } - echo "</td>\n"; - echo "<td class=\"$class\">"; - if ($active != 'n') { - echo "<a href=\"group.php?group=$group&format=rdf\">rdf</a>"; - } - echo "</td>\n"; - echo "</tr>\n"; - $class = $class == "even" ? "odd" : "even"; + if ($line == ".\r\n") { + break; + } + $line = chop($line); + list($group, $high, $low, $active) = explode(" ", $line); + echo " <tr>\n"; + echo " <td class=\"$class\"><a class=\"active$active\" href=\"/$group\">$group</a></td>\n"; + echo " <td align=\"right\" class=\"$class\">", $high-$low+1, "</td>\n"; + echo " <td class=\"$class\">"; + if ($active != 'n') { + echo "<a href=\"group.php?group=$group&format=rss\">rss</a>"; + } + echo "</td>\n"; + echo " <td class=\"$class\">"; + if ($active != 'n') { + echo "<a href=\"group.php?group=$group&format=rdf\">rdf</a>"; + } + echo "</td>\n"; + echo " </tr>\n"; + $class = ($class == "even") ? "odd" : "even"; } -echo "</table>\n"; - -echo '</td><td valign="top">'; ?> -<h1>Welcome!</h1> -<p>This is a completely experimental interface to the PHP mailing -lists as reflected on the <a href="news://<?php echo $_SERVER['HTTP_HOST']; ?>/"> -<?php echo $_SERVER['HTTP_HOST']; ?> NNTP server</a>.</p> -<p>There may be a little more info in the <a href="README">README</a> file.</p> -<p>The news server software that is used is <a -href="http://trainedmonkey.com/colobus/">colobus</a>.</p> + </table> + </td> + <td valign="top"> + <h1>Welcome!</h1> + <p> + This is a completely experimental interface to the PHP mailing lists as + reflected on the <a href="news://<?php echo $_SERVER['HTTP_HOST']; ?>/"> + <?php echo $_SERVER['HTTP_HOST']; ?> NNTP server</a>. + </p> + <p> + There may be a little more info in the <a href="README">README</a> file. + </p> + <p> + The news server software that is used is <a + href="http://trainedmonkey.com/colobus/">colobus</a>. + </p> + </td> + </tr> + </table> <?php -echo '</td></tr></table>'; foot(); http://cvs.php.net/diff.php/php-news-web/nntp.inc?r1=1.3&r2=1.4&ty=u Index: php-news-web/nntp.inc diff -u php-news-web/nntp.inc:1.3 php-news-web/nntp.inc:1.4 --- php-news-web/nntp.inc:1.3 Mon Dec 22 03:39:02 2003 +++ php-news-web/nntp.inc Wed Jan 26 11:52:39 2005 @@ -1,24 +1,23 @@ <?php -function nntp_connect($server,$port=119) { - $s = @fsockopen($server,$port,$errno,$errstr,30); - if (!$s) { - echo "<!-- error connecting to nntp server: $errstr -->\n"; - return false; - } - $hello = fgets($s, 1024); - if (substr($hello,0,4) != "200 ") { - echo "<!-- unexpected greeting: $hello -->\n"; - return false; - } - #echo "<!-- $hello -->\n"; - return $s; +function nntp_connect($server, $port = 119) { + $s = @fsockopen($server, $port, $errno, $errstr, 30); + if (!$s) { + return false; + } + $hello = fgets($s, 1024); + if (substr($hello,0,4) != "200 ") { + return false; + } + return $s; } -function nntp_cmd($conn,$command,$expected) { - if (strlen($command) > 510) die("command too long: $command"); - fputs($conn, "$command\r\n"); - $res = fgets($conn, 1024); - list($code,$extra) = explode(" ", $res, 2); - return $code == $expected ? $extra : false; +function nntp_cmd($conn, $command, $expected) { + if (strlen($command) > 510) { + die("command too long: $command"); + } + fputs($conn, "$command\r\n"); + $res = fgets($conn, 1024); + list($code, $extra) = explode(" ", $res, 2); + return ($code == $expected) ? $extra : false; } http://cvs.php.net/diff.php/php-news-web/style.css?r1=1.4&r2=1.5&ty=u Index: php-news-web/style.css diff -u php-news-web/style.css:1.4 php-news-web/style.css:1.5 --- php-news-web/style.css:1.4 Mon Oct 14 20:45:39 2002 +++ php-news-web/style.css Wed Jan 26 11:52:39 2005 @@ -3,32 +3,118 @@ font-size: 95%; } -body { margin: 0px; background: white; color: black; } -td,th { color: black; } - -.quote { color: green; } - -.signature { font-size: smaller; color: gray; } -.signature a:link { color: #9999ff; } -.signature a:hover { color: #ff9999; } -.signature a:active { color: #ff9999; } -.signature a:visited { color: #ff66ff; } - -a:link { color: blue; } -a:hover { color: red; } -a:active { color: red; } -a:visited { color: purple; } - -.grouplisthead { background: #cccccc; font-weight: bold; text-align: center; } -.even { background: #eeeeee; } -.odd { background: #dddddd; } -.grouplistmsgs { text-align: right; } - -.alisthead { background: #cccccc; font-weight: bold; text-align: center; } - -.activen { color: gray; } - -.headerlabel { background: #cccccc; font-weight: bold; text-align: right; } -.headervalue { background: #eeeeee; } - -a.top { text-decoration: none; color: blue; } \ No newline at end of file +body { + margin: 0px; + background: #ffffff; + color: #000000; +} + +td,th { + color: #000000; +} + + +img { + border : 0px; +} + +a:link { + color: #000099; +} + +a:hover { + color: #ff0000; +} + +a:active { + color: #ff0000; +} + +a:visited { + color: #000099; +} + +.quote { + color: green; +} + +.signature { + font-size: smaller; + color: gray; +} + +.signature a:link { + color: #9999ff; +} + +.signature a:hover { + color: #ff9999; +} + +.signature a:active { + color: #ff9999; +} + +.signature a:visited { + color: #ff66ff; +} + +.grouplisthead { + background: #cccccc; + font-weight: bold; + text-align: center; +} + +.even { + background: #eeeeee; +} + +.odd { + background: #dddddd; +} + +.grouplistmsgs { + text-align: right; +} + +.alisthead { + background: #cccccc; + font-weight: bold; + text-align: center; +} + +.activen { + color: gray; +} + +.headerlabel { + background: #cccccc; + font-weight: bold; + text-align: right; +} + +.headervalue { + background: #eeeeee; +} + +a.top { + text-decoration: none; +} + +tr.header { + background: #9999cc; +} + +tr.subheader { + background: #666699; + height : 2px; +} + +.small { + font-size: 75%; + text-align: right; +} + +.nav { + width: 20%; +} \ No newline at end of file http://cvs.php.net/diff.php/php-news-web/i/l.gif?r1=1.1&r2=1.2&ty=u Index: php-news-web/i/l.gif