Mercurial > hg > pnewss
view server.php @ 0:d7ab68b71c74
Initial commit
author | Ivo Smits <Ivo@UCIS.nl> |
---|---|
date | Mon, 11 Apr 2011 22:44:47 +0200 |
parents | |
children | 40e545510a57 |
line wrap: on
line source
#!/usr/bin/php <?php chdir('/home/ivo/projects/pnewss'); require_once './pdo.php'; require_once './config.php'; $logfile = fopen('./server.log', 'w'); $currentgroup = NULL; $currentarticle = NULL; function exception_handler($exception) { nntp_writeline(STDOUT, ''); nntp_writeline(STDOUT, '590 Exception: '.$exception->getMessage()); die(); } function error_handler($errno, $errstr, $errfile, $errline) { nntp_writeline(STDOUT, ''); nntp_writeline(STDOUT, '590 Error in file '.$errfile.' line '.$errline.' error '.$errno.' '.$errstr); die(); } set_exception_handler('exception_handler'); set_error_handler("error_handler"); nntp_writeline(STDOUT, '200 pNewss ready'); while (TRUE) { $line = nntp_readline(STDIN); if ($line === FALSE || $line === NULL) break; $cmd = strtok($line, " \t"); switch (strtoupper($cmd)) { case 'LIST': nntp_writeline(STDOUT, '215 List of groups follows'); foreach ($db->evalAllAssoc('SELECT * FROM `groups`') as $group) { $groupmessages = $db->evalRow('SELECT MIN(`number`), MAX(`number`) FROM `groupmessages` WHERE `group` = ?', $group['id']); nntp_writeline(STDOUT, $group['name'].' '.intval($groupmessages[1]).' '.intval($groupmessages[0]).' n'); } nntp_writeline(STDOUT, '.'); break; case 'GROUP': $groupname = strtok(" \t"); $group = $db->evalRowAssoc('SELECT * FROM `groups` WHERE `name` = ?', $groupname); if ($group === FALSE) { nntp_writeline(STDOUT, '411 No such group '.$groupname); } else { $currentgroup = $group; $groupmessages = $db->evalRow('SELECT MIN(`number`), MAX(`number`), COUNT(`number`) FROM `groupmessages` WHERE `group` = ?', $group['id']); nntp_writeline(STDOUT, '211 '.intval($groupmessages[2]).' '.intval($groupmessages[0]).' '.intval($groupmessages[1]).' '.$group['name']); if ($groupmessages[0] === NULL) { $currentarticle = NULL; } else { $currentarticle = $db->evalRowAssoc('SELECT * FROM `groupmessages` WHERE `group` = ? AND `number` = ?', array($group['id'], $groupmessages[0])); if ($currentarticle === FALSE) $currentarticle = NULL; } } break; case 'STAT': $article = nntp_get_article(strtok(" \t")); if ($article === NULL) break; nntp_writeline(STDOUT, '223 '.$article['messagenumber'].' <'.$article['messageid'].'> stat'); break; case 'HEAD': $article = nntp_get_article(strtok(" \t")); if ($article === NULL) break; nntp_writeline(STDOUT, '221 '.$article['messagenumber'].' <'.$article['messageid'].'> head'); foreach (explode("\r\n", $article['header']) as $line) nntp_writeline(STDOUT, $line); nntp_writeline(STDOUT, '.'); break; case 'BODY': $article = nntp_get_article(strtok(" \t")); if ($article === NULL) break; nntp_writeline(STDOUT, '222 '.$article['messagenumber'].' <'.$article['messageid'].'> body'); foreach (explode("\r\n", $article['body']) as $line) nntp_writeline(STDOUT, $line); nntp_writeline(STDOUT, '.'); break; case 'ARTICLE': $article = nntp_get_article(strtok(" \t")); if ($article === NULL) break; nntp_writeline(STDOUT, '220 '.$article['messagenumber'].' <'.$article['messageid'].'> article'); foreach (explode("\r\n", $article['header']) as $line) nntp_writeline(STDOUT, $line); nntp_writeline(STDOUT, ''); foreach (explode("\r\n", $article['body']) as $line) nntp_writeline(STDOUT, $line); nntp_writeline(STDOUT, '.'); break; case 'LAST': if ($currentarticle === NULL) { nntp_writeline(STDOUT, '420 no current article has been selected'); break; } $article = $db->evalRowAssoc('SELECT * FROM `groupmessages` WHERE `group` = ? AND `number` < ? ORDER BY `number` DESC LIMIT 1', array($currentarticle['group'], $currentarticle['number'])); if ($article === FALSE) { nntp_writeline(STDOUT, '422 no previous article in this group'); } else { $articlea = $db->evalRowAssoc('SELECT * FROM `messages` WHERE `id` = ?', $article['message']); if ($articlea === FALSE) { nntp_writeline(STDOUT, '430 no such article found'); return NULL; } $currentarticle = $article; nntp_writeline(STDOUT, '223 '.$article['number'].' <'.$articlea['messageid'].'> ok'); } break; case 'NEXT': if ($currentarticle === NULL) { nntp_writeline(STDOUT, '420 no current article has been selected'); break; } $article = $db->evalRowAssoc('SELECT * FROM `groupmessages` WHERE `group` = ? AND `number` > ? ORDER BY `number` ASC LIMIT 1', array($currentarticle['group'], $currentarticle['number'])); if ($article === FALSE) { nntp_writeline(STDOUT, '422 no previous article in this group'); } else { $articlea = $db->evalRowAssoc('SELECT * FROM `messages` WHERE `id` = ?', $article['message']); if ($articlea === FALSE) { nntp_writeline(STDOUT, '430 no such article found'); return NULL; } $currentarticle = $article; nntp_writeline(STDOUT, '223 '.$article['number'].' <'.$articlea['messageid'].'> ok'); } break; case 'QUIT': nntp_writeline(STDOUT, '205 .'); return; case 'XOVER': case 'MODE': case 'CAPABILITIES': nntp_writeline(STDOUT, '500 Command not implemented'); break; default: nntp_writeline(STDOUT, '500 Command not understood'); break; } } function nntp_get_article($article) { global $currentgroup, $currentarticle, $db; if ($article === FALSE) { if ($currentarticle === NULL) { nntp_writeline(STDOUT, '420 no current article has been selected'); return NULL; } $messagenumber = $currentarticle['number']; $article = $db->evalRowAssoc('SELECT * FROM `messages` WHERE `id` = ?', $currentarticle['message']); if ($article === FALSE) { nntp_writeline(STDOUT, '430 no such article found'); return NULL; } } elseif (strlen($article) > 2 && $article[0] == '<' && $article[strlen($article)-1] == '>') { $messagenumber = 0; $article = substr($article, 1, -1); $article = $db->evalRowAssoc('SELECT * FROM `messages` WHERE `messageid` = ?', $article); if ($article === FALSE) { nntp_writeline(STDOUT, '430 no such article found'); return NULL; } } elseif (is_numeric($article)) { if ($currentgroup === NULL) { nntp_writeline(STDOUT, '412 no newsgroup has been selected'); return NULL; } $article = $db->evalRowAssoc('SELECT * FROM `groupmessages` WHERE `group` = ? AND `number` = ?', array($currentgroup['id'], $article)); if ($article === FALSE) { nntp_writeline(STDOUT, '423 no such article number in this group'); return NULL; } $currentarticle = $article; $messagenumber = $article['number']; $article = $db->evalRowAssoc('SELECT * FROM `messages` WHERE `id` = ?', $article['message']); if ($article === FALSE) { nntp_writeline(STDOUT, '430 no such article found'); return NULL; } } else { nntp_writeline(STDOUT, '500 Error in arguments'); } $article['messagenumber'] = $messagenumber; return $article; } function writelog($line) { global $logfile; fwrite($logfile, $line."\n"); } function nntp_readline($socket) { global $logfile; $line = fgets($socket, 512); if ($line === FALSE || $line === NULL) return $line; $line = rtrim($line, "\r\n"); fwrite($logfile, 'R: '.$line."\n"); return $line; } function nntp_writeline($socket, $line) { global $logfile; fwrite($logfile, 'W: '.$line."\n"); fwrite($socket, $line."\r\n"); } function nntp_readlines($socket) { $line = nntp_readline($socket); $lines = array(); while ($line != '.' && $line !== FALSE && $line !== FALSE) { $lines[] = $line; $line = nntp_readline($socket); } if ($line != '.') die("Unexpected end of message header\n"); return $lines; }