comparison server.php @ 0:d7ab68b71c74

Initial commit
author Ivo Smits <Ivo@UCIS.nl>
date Mon, 11 Apr 2011 22:44:47 +0200
parents
children 40e545510a57
comparison
equal deleted inserted replaced
-1:000000000000 0:d7ab68b71c74
1 #!/usr/bin/php
2 <?php
3 chdir('/home/ivo/projects/pnewss');
4 require_once './pdo.php';
5 require_once './config.php';
6
7 $logfile = fopen('./server.log', 'w');
8 $currentgroup = NULL;
9 $currentarticle = NULL;
10
11 function exception_handler($exception) {
12 nntp_writeline(STDOUT, '');
13 nntp_writeline(STDOUT, '590 Exception: '.$exception->getMessage());
14 die();
15 }
16 function error_handler($errno, $errstr, $errfile, $errline) {
17 nntp_writeline(STDOUT, '');
18 nntp_writeline(STDOUT, '590 Error in file '.$errfile.' line '.$errline.' error '.$errno.' '.$errstr);
19 die();
20 }
21 set_exception_handler('exception_handler');
22 set_error_handler("error_handler");
23
24 nntp_writeline(STDOUT, '200 pNewss ready');
25 while (TRUE) {
26 $line = nntp_readline(STDIN);
27 if ($line === FALSE || $line === NULL) break;
28 $cmd = strtok($line, " \t");
29 switch (strtoupper($cmd)) {
30 case 'LIST':
31 nntp_writeline(STDOUT, '215 List of groups follows');
32 foreach ($db->evalAllAssoc('SELECT * FROM `groups`') as $group) {
33 $groupmessages = $db->evalRow('SELECT MIN(`number`), MAX(`number`) FROM `groupmessages` WHERE `group` = ?', $group['id']);
34 nntp_writeline(STDOUT, $group['name'].' '.intval($groupmessages[1]).' '.intval($groupmessages[0]).' n');
35 }
36 nntp_writeline(STDOUT, '.');
37 break;
38 case 'GROUP':
39 $groupname = strtok(" \t");
40 $group = $db->evalRowAssoc('SELECT * FROM `groups` WHERE `name` = ?', $groupname);
41 if ($group === FALSE) {
42 nntp_writeline(STDOUT, '411 No such group '.$groupname);
43 } else {
44 $currentgroup = $group;
45 $groupmessages = $db->evalRow('SELECT MIN(`number`), MAX(`number`), COUNT(`number`) FROM `groupmessages` WHERE `group` = ?', $group['id']);
46 nntp_writeline(STDOUT, '211 '.intval($groupmessages[2]).' '.intval($groupmessages[0]).' '.intval($groupmessages[1]).' '.$group['name']);
47 if ($groupmessages[0] === NULL) {
48 $currentarticle = NULL;
49 } else {
50 $currentarticle = $db->evalRowAssoc('SELECT * FROM `groupmessages` WHERE `group` = ? AND `number` = ?', array($group['id'], $groupmessages[0]));
51 if ($currentarticle === FALSE) $currentarticle = NULL;
52 }
53 }
54 break;
55 case 'STAT':
56 $article = nntp_get_article(strtok(" \t"));
57 if ($article === NULL) break;
58 nntp_writeline(STDOUT, '223 '.$article['messagenumber'].' <'.$article['messageid'].'> stat');
59 break;
60 case 'HEAD':
61 $article = nntp_get_article(strtok(" \t"));
62 if ($article === NULL) break;
63 nntp_writeline(STDOUT, '221 '.$article['messagenumber'].' <'.$article['messageid'].'> head');
64 foreach (explode("\r\n", $article['header']) as $line) nntp_writeline(STDOUT, $line);
65 nntp_writeline(STDOUT, '.');
66 break;
67 case 'BODY':
68 $article = nntp_get_article(strtok(" \t"));
69 if ($article === NULL) break;
70 nntp_writeline(STDOUT, '222 '.$article['messagenumber'].' <'.$article['messageid'].'> body');
71 foreach (explode("\r\n", $article['body']) as $line) nntp_writeline(STDOUT, $line);
72 nntp_writeline(STDOUT, '.');
73 break;
74 case 'ARTICLE':
75 $article = nntp_get_article(strtok(" \t"));
76 if ($article === NULL) break;
77 nntp_writeline(STDOUT, '220 '.$article['messagenumber'].' <'.$article['messageid'].'> article');
78 foreach (explode("\r\n", $article['header']) as $line) nntp_writeline(STDOUT, $line);
79 nntp_writeline(STDOUT, '');
80 foreach (explode("\r\n", $article['body']) as $line) nntp_writeline(STDOUT, $line);
81 nntp_writeline(STDOUT, '.');
82 break;
83 case 'LAST':
84 if ($currentarticle === NULL) {
85 nntp_writeline(STDOUT, '420 no current article has been selected');
86 break;
87 }
88 $article = $db->evalRowAssoc('SELECT * FROM `groupmessages` WHERE `group` = ? AND `number` < ? ORDER BY `number` DESC LIMIT 1', array($currentarticle['group'], $currentarticle['number']));
89 if ($article === FALSE) {
90 nntp_writeline(STDOUT, '422 no previous article in this group');
91 } else {
92 $articlea = $db->evalRowAssoc('SELECT * FROM `messages` WHERE `id` = ?', $article['message']);
93 if ($articlea === FALSE) {
94 nntp_writeline(STDOUT, '430 no such article found');
95 return NULL;
96 }
97 $currentarticle = $article;
98 nntp_writeline(STDOUT, '223 '.$article['number'].' <'.$articlea['messageid'].'> ok');
99 }
100 break;
101 case 'NEXT':
102 if ($currentarticle === NULL) {
103 nntp_writeline(STDOUT, '420 no current article has been selected');
104 break;
105 }
106 $article = $db->evalRowAssoc('SELECT * FROM `groupmessages` WHERE `group` = ? AND `number` > ? ORDER BY `number` ASC LIMIT 1', array($currentarticle['group'], $currentarticle['number']));
107 if ($article === FALSE) {
108 nntp_writeline(STDOUT, '422 no previous article in this group');
109 } else {
110 $articlea = $db->evalRowAssoc('SELECT * FROM `messages` WHERE `id` = ?', $article['message']);
111 if ($articlea === FALSE) {
112 nntp_writeline(STDOUT, '430 no such article found');
113 return NULL;
114 }
115 $currentarticle = $article;
116 nntp_writeline(STDOUT, '223 '.$article['number'].' <'.$articlea['messageid'].'> ok');
117 }
118 break;
119 case 'QUIT':
120 nntp_writeline(STDOUT, '205 .');
121 return;
122 case 'XOVER':
123 case 'MODE':
124 case 'CAPABILITIES':
125 nntp_writeline(STDOUT, '500 Command not implemented');
126 break;
127 default:
128 nntp_writeline(STDOUT, '500 Command not understood');
129 break;
130 }
131 }
132
133 function nntp_get_article($article) {
134 global $currentgroup, $currentarticle, $db;
135 if ($article === FALSE) {
136 if ($currentarticle === NULL) {
137 nntp_writeline(STDOUT, '420 no current article has been selected');
138 return NULL;
139 }
140 $messagenumber = $currentarticle['number'];
141 $article = $db->evalRowAssoc('SELECT * FROM `messages` WHERE `id` = ?', $currentarticle['message']);
142 if ($article === FALSE) {
143 nntp_writeline(STDOUT, '430 no such article found');
144 return NULL;
145 }
146 } elseif (strlen($article) > 2 && $article[0] == '<' && $article[strlen($article)-1] == '>') {
147 $messagenumber = 0;
148 $article = substr($article, 1, -1);
149 $article = $db->evalRowAssoc('SELECT * FROM `messages` WHERE `messageid` = ?', $article);
150 if ($article === FALSE) {
151 nntp_writeline(STDOUT, '430 no such article found');
152 return NULL;
153 }
154 } elseif (is_numeric($article)) {
155 if ($currentgroup === NULL) {
156 nntp_writeline(STDOUT, '412 no newsgroup has been selected');
157 return NULL;
158 }
159 $article = $db->evalRowAssoc('SELECT * FROM `groupmessages` WHERE `group` = ? AND `number` = ?', array($currentgroup['id'], $article));
160 if ($article === FALSE) {
161 nntp_writeline(STDOUT, '423 no such article number in this group');
162 return NULL;
163 }
164 $currentarticle = $article;
165 $messagenumber = $article['number'];
166 $article = $db->evalRowAssoc('SELECT * FROM `messages` WHERE `id` = ?', $article['message']);
167 if ($article === FALSE) {
168 nntp_writeline(STDOUT, '430 no such article found');
169 return NULL;
170 }
171 } else {
172 nntp_writeline(STDOUT, '500 Error in arguments');
173 }
174 $article['messagenumber'] = $messagenumber;
175 return $article;
176 }
177
178 function writelog($line) {
179 global $logfile;
180 fwrite($logfile, $line."\n");
181 }
182 function nntp_readline($socket) {
183 global $logfile;
184 $line = fgets($socket, 512);
185 if ($line === FALSE || $line === NULL) return $line;
186 $line = rtrim($line, "\r\n");
187 fwrite($logfile, 'R: '.$line."\n");
188 return $line;
189 }
190 function nntp_writeline($socket, $line) {
191 global $logfile;
192 fwrite($logfile, 'W: '.$line."\n");
193 fwrite($socket, $line."\r\n");
194 }
195 function nntp_readlines($socket) {
196 $line = nntp_readline($socket);
197 $lines = array();
198 while ($line != '.' && $line !== FALSE && $line !== FALSE) {
199 $lines[] = $line;
200 $line = nntp_readline($socket);
201 }
202 if ($line != '.') die("Unexpected end of message header\n");
203 return $lines;
204 }