Mercurial > hg > pnewss
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 } |