Mercurial > hg > pnewss
annotate server.php @ 5:5d62af5270dd
Small bugfix in server STAT command (no data follows, so don't send a dot)
author | Ivo Smits <Ivo@UCIS.nl> |
---|---|
date | Tue, 12 Apr 2011 02:23:22 +0200 |
parents | 0dcdb73cbcbf |
children | 01dc7eeaf5df |
rev | line source |
---|---|
0 | 1 #!/usr/bin/php |
2 <?php | |
2
40e545510a57
Added support for POSTing to the server, added readme and todo, added support for upstream synchronization using POST
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
3 chdir(__DIR__); |
3
0dcdb73cbcbf
Increased article body length to 16MB in database scheme, cleaned up the code, added a script to forcefully reload an individual article
Ivo Smits <Ivo@UCIS.nl>
parents:
2
diff
changeset
|
4 require_once './common.php'; |
0 | 5 |
6 $logfile = fopen('./server.log', 'w'); | |
7 $currentgroup = NULL; | |
8 $currentarticle = NULL; | |
9 | |
10 function exception_handler($exception) { | |
11 nntp_writeline(STDOUT, ''); | |
12 nntp_writeline(STDOUT, '590 Exception: '.$exception->getMessage()); | |
13 die(); | |
14 } | |
15 function error_handler($errno, $errstr, $errfile, $errline) { | |
16 nntp_writeline(STDOUT, ''); | |
17 nntp_writeline(STDOUT, '590 Error in file '.$errfile.' line '.$errline.' error '.$errno.' '.$errstr); | |
18 die(); | |
19 } | |
20 set_exception_handler('exception_handler'); | |
21 set_error_handler("error_handler"); | |
22 | |
23 nntp_writeline(STDOUT, '200 pNewss ready'); | |
24 while (TRUE) { | |
25 $line = nntp_readline(STDIN); | |
2
40e545510a57
Added support for POSTing to the server, added readme and todo, added support for upstream synchronization using POST
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
26 if ($line === FALSE || $line === NULL) break; |
3
0dcdb73cbcbf
Increased article body length to 16MB in database scheme, cleaned up the code, added a script to forcefully reload an individual article
Ivo Smits <Ivo@UCIS.nl>
parents:
2
diff
changeset
|
27 $cmd = strtoupper(strtok($line, " \t")); |
0dcdb73cbcbf
Increased article body length to 16MB in database scheme, cleaned up the code, added a script to forcefully reload an individual article
Ivo Smits <Ivo@UCIS.nl>
parents:
2
diff
changeset
|
28 switch ($cmd) { |
0 | 29 case 'LIST': |
3
0dcdb73cbcbf
Increased article body length to 16MB in database scheme, cleaned up the code, added a script to forcefully reload an individual article
Ivo Smits <Ivo@UCIS.nl>
parents:
2
diff
changeset
|
30 nntp_writeline(STDOUT, '215 list of groups follows'); |
0 | 31 foreach ($db->evalAllAssoc('SELECT * FROM `groups`') as $group) { |
32 $groupmessages = $db->evalRow('SELECT MIN(`number`), MAX(`number`) FROM `groupmessages` WHERE `group` = ?', $group['id']); | |
33 nntp_writeline(STDOUT, $group['name'].' '.intval($groupmessages[1]).' '.intval($groupmessages[0]).' n'); | |
34 } | |
35 nntp_writeline(STDOUT, '.'); | |
36 break; | |
37 case 'GROUP': | |
38 $groupname = strtok(" \t"); | |
39 $group = $db->evalRowAssoc('SELECT * FROM `groups` WHERE `name` = ?', $groupname); | |
40 if ($group === FALSE) { | |
41 nntp_writeline(STDOUT, '411 No such group '.$groupname); | |
42 } else { | |
43 $currentgroup = $group; | |
44 $groupmessages = $db->evalRow('SELECT MIN(`number`), MAX(`number`), COUNT(`number`) FROM `groupmessages` WHERE `group` = ?', $group['id']); | |
45 nntp_writeline(STDOUT, '211 '.intval($groupmessages[2]).' '.intval($groupmessages[0]).' '.intval($groupmessages[1]).' '.$group['name']); | |
46 if ($groupmessages[0] === NULL) { | |
47 $currentarticle = NULL; | |
48 } else { | |
49 $currentarticle = $db->evalRowAssoc('SELECT * FROM `groupmessages` WHERE `group` = ? AND `number` = ?', array($group['id'], $groupmessages[0])); | |
50 if ($currentarticle === FALSE) $currentarticle = NULL; | |
51 } | |
52 } | |
53 break; | |
54 case 'STAT': | |
55 case 'HEAD': | |
56 case 'BODY': | |
57 case 'ARTICLE': | |
58 $article = nntp_get_article(strtok(" \t")); | |
59 if ($article === NULL) break; | |
3
0dcdb73cbcbf
Increased article body length to 16MB in database scheme, cleaned up the code, added a script to forcefully reload an individual article
Ivo Smits <Ivo@UCIS.nl>
parents:
2
diff
changeset
|
60 switch ($cmd) { |
5
5d62af5270dd
Small bugfix in server STAT command (no data follows, so don't send a dot)
Ivo Smits <Ivo@UCIS.nl>
parents:
3
diff
changeset
|
61 case 'ARTICLE': nntp_writeline(STDOUT, '220 '.$article['messagenumber'].' <'.$article['messageid'].'> article'); break; |
3
0dcdb73cbcbf
Increased article body length to 16MB in database scheme, cleaned up the code, added a script to forcefully reload an individual article
Ivo Smits <Ivo@UCIS.nl>
parents:
2
diff
changeset
|
62 case 'HEAD': nntp_writeline(STDOUT, '221 '.$article['messagenumber'].' <'.$article['messageid'].'> head'); break; |
0dcdb73cbcbf
Increased article body length to 16MB in database scheme, cleaned up the code, added a script to forcefully reload an individual article
Ivo Smits <Ivo@UCIS.nl>
parents:
2
diff
changeset
|
63 case 'BODY': nntp_writeline(STDOUT, '222 '.$article['messagenumber'].' <'.$article['messageid'].'> body'); break; |
5
5d62af5270dd
Small bugfix in server STAT command (no data follows, so don't send a dot)
Ivo Smits <Ivo@UCIS.nl>
parents:
3
diff
changeset
|
64 case 'STAT': nntp_writeline(STDOUT, '223 '.$article['messagenumber'].' <'.$article['messageid'].'> stat'); break; |
3
0dcdb73cbcbf
Increased article body length to 16MB in database scheme, cleaned up the code, added a script to forcefully reload an individual article
Ivo Smits <Ivo@UCIS.nl>
parents:
2
diff
changeset
|
65 default: throw new Exception('Internal error'); |
0dcdb73cbcbf
Increased article body length to 16MB in database scheme, cleaned up the code, added a script to forcefully reload an individual article
Ivo Smits <Ivo@UCIS.nl>
parents:
2
diff
changeset
|
66 } |
0dcdb73cbcbf
Increased article body length to 16MB in database scheme, cleaned up the code, added a script to forcefully reload an individual article
Ivo Smits <Ivo@UCIS.nl>
parents:
2
diff
changeset
|
67 if ($cmd == 'HEAD' || $cmd == 'ARTICLE') foreach (explode("\r\n", $article['header']) as $line) nntp_writeline(STDOUT, $line); |
0dcdb73cbcbf
Increased article body length to 16MB in database scheme, cleaned up the code, added a script to forcefully reload an individual article
Ivo Smits <Ivo@UCIS.nl>
parents:
2
diff
changeset
|
68 if ($cmd == 'ARTICLE') nntp_writeline(STDOUT, ''); |
0dcdb73cbcbf
Increased article body length to 16MB in database scheme, cleaned up the code, added a script to forcefully reload an individual article
Ivo Smits <Ivo@UCIS.nl>
parents:
2
diff
changeset
|
69 if ($cmd == 'BODY' || $cmd == 'ARTICLE') foreach (explode("\r\n", $article['body']) as $line) nntp_writeline(STDOUT, $line); |
5
5d62af5270dd
Small bugfix in server STAT command (no data follows, so don't send a dot)
Ivo Smits <Ivo@UCIS.nl>
parents:
3
diff
changeset
|
70 if ($cmd != 'STAT') nntp_writeline(STDOUT, '.'); |
0 | 71 break; |
72 case 'LAST': | |
73 case 'NEXT': | |
74 if ($currentarticle === NULL) { | |
75 nntp_writeline(STDOUT, '420 no current article has been selected'); | |
76 break; | |
77 } | |
3
0dcdb73cbcbf
Increased article body length to 16MB in database scheme, cleaned up the code, added a script to forcefully reload an individual article
Ivo Smits <Ivo@UCIS.nl>
parents:
2
diff
changeset
|
78 switch ($cmd) { |
0dcdb73cbcbf
Increased article body length to 16MB in database scheme, cleaned up the code, added a script to forcefully reload an individual article
Ivo Smits <Ivo@UCIS.nl>
parents:
2
diff
changeset
|
79 case 'LAST': $query = 'SELECT * FROM `groupmessages` WHERE `group` = ? AND `number` < ? ORDER BY `number` DESC LIMIT 1'; break; |
0dcdb73cbcbf
Increased article body length to 16MB in database scheme, cleaned up the code, added a script to forcefully reload an individual article
Ivo Smits <Ivo@UCIS.nl>
parents:
2
diff
changeset
|
80 case 'NEXT': $query = 'SELECT * FROM `groupmessages` WHERE `group` = ? AND `number` > ? ORDER BY `number` ASC LIMIT 1'; break; |
0dcdb73cbcbf
Increased article body length to 16MB in database scheme, cleaned up the code, added a script to forcefully reload an individual article
Ivo Smits <Ivo@UCIS.nl>
parents:
2
diff
changeset
|
81 default: throw new Exception('Internal error'); |
0dcdb73cbcbf
Increased article body length to 16MB in database scheme, cleaned up the code, added a script to forcefully reload an individual article
Ivo Smits <Ivo@UCIS.nl>
parents:
2
diff
changeset
|
82 } |
0dcdb73cbcbf
Increased article body length to 16MB in database scheme, cleaned up the code, added a script to forcefully reload an individual article
Ivo Smits <Ivo@UCIS.nl>
parents:
2
diff
changeset
|
83 $article = $db->evalRowAssoc($query, array($currentarticle['group'], $currentarticle['number'])); |
0 | 84 if ($article === FALSE) { |
85 nntp_writeline(STDOUT, '422 no previous article in this group'); | |
86 } else { | |
87 $articlea = $db->evalRowAssoc('SELECT * FROM `messages` WHERE `id` = ?', $article['message']); | |
88 if ($articlea === FALSE) { | |
89 nntp_writeline(STDOUT, '430 no such article found'); | |
90 return NULL; | |
91 } | |
92 $currentarticle = $article; | |
93 nntp_writeline(STDOUT, '223 '.$article['number'].' <'.$articlea['messageid'].'> ok'); | |
94 } | |
95 break; | |
2
40e545510a57
Added support for POSTing to the server, added readme and todo, added support for upstream synchronization using POST
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
96 case 'POST': |
40e545510a57
Added support for POSTing to the server, added readme and todo, added support for upstream synchronization using POST
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
97 nntp_writeline(STDOUT, '340 Ok, recommended message-ID <'.md5(time().rand()).'@pNews.Core.UCIS.nl>'); |
40e545510a57
Added support for POSTing to the server, added readme and todo, added support for upstream synchronization using POST
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
98 $lines = nntp_readlines(STDIN); |
3
0dcdb73cbcbf
Increased article body length to 16MB in database scheme, cleaned up the code, added a script to forcefully reload an individual article
Ivo Smits <Ivo@UCIS.nl>
parents:
2
diff
changeset
|
99 try { |
0dcdb73cbcbf
Increased article body length to 16MB in database scheme, cleaned up the code, added a script to forcefully reload an individual article
Ivo Smits <Ivo@UCIS.nl>
parents:
2
diff
changeset
|
100 $msgid = nntp_article_store($lines); |
0dcdb73cbcbf
Increased article body length to 16MB in database scheme, cleaned up the code, added a script to forcefully reload an individual article
Ivo Smits <Ivo@UCIS.nl>
parents:
2
diff
changeset
|
101 nntp_writeline(STDOUT, '240 Article received <'.$msgid.'>'); |
0dcdb73cbcbf
Increased article body length to 16MB in database scheme, cleaned up the code, added a script to forcefully reload an individual article
Ivo Smits <Ivo@UCIS.nl>
parents:
2
diff
changeset
|
102 } catch (Exception $ex) { |
0dcdb73cbcbf
Increased article body length to 16MB in database scheme, cleaned up the code, added a script to forcefully reload an individual article
Ivo Smits <Ivo@UCIS.nl>
parents:
2
diff
changeset
|
103 nntp_writeline(STDOUT, '441 '.$ex->getMessage()); |
2
40e545510a57
Added support for POSTing to the server, added readme and todo, added support for upstream synchronization using POST
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
104 } |
40e545510a57
Added support for POSTing to the server, added readme and todo, added support for upstream synchronization using POST
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
105 break; |
0 | 106 case 'QUIT': |
107 nntp_writeline(STDOUT, '205 .'); | |
108 return; | |
109 default: | |
110 nntp_writeline(STDOUT, '500 Command not understood'); | |
111 break; | |
112 } | |
113 } | |
114 | |
115 function nntp_get_article($article) { | |
116 global $currentgroup, $currentarticle, $db; | |
117 if ($article === FALSE) { | |
118 if ($currentarticle === NULL) { | |
119 nntp_writeline(STDOUT, '420 no current article has been selected'); | |
120 return NULL; | |
121 } | |
122 $messagenumber = $currentarticle['number']; | |
123 $article = $db->evalRowAssoc('SELECT * FROM `messages` WHERE `id` = ?', $currentarticle['message']); | |
124 if ($article === FALSE) { | |
125 nntp_writeline(STDOUT, '430 no such article found'); | |
126 return NULL; | |
127 } | |
128 } elseif (strlen($article) > 2 && $article[0] == '<' && $article[strlen($article)-1] == '>') { | |
129 $messagenumber = 0; | |
130 $article = substr($article, 1, -1); | |
131 $article = $db->evalRowAssoc('SELECT * FROM `messages` WHERE `messageid` = ?', $article); | |
132 if ($article === FALSE) { | |
133 nntp_writeline(STDOUT, '430 no such article found'); | |
134 return NULL; | |
135 } | |
136 } elseif (is_numeric($article)) { | |
137 if ($currentgroup === NULL) { | |
138 nntp_writeline(STDOUT, '412 no newsgroup has been selected'); | |
139 return NULL; | |
140 } | |
141 $article = $db->evalRowAssoc('SELECT * FROM `groupmessages` WHERE `group` = ? AND `number` = ?', array($currentgroup['id'], $article)); | |
142 if ($article === FALSE) { | |
143 nntp_writeline(STDOUT, '423 no such article number in this group'); | |
144 return NULL; | |
145 } | |
146 $currentarticle = $article; | |
147 $messagenumber = $article['number']; | |
148 $article = $db->evalRowAssoc('SELECT * FROM `messages` WHERE `id` = ?', $article['message']); | |
149 if ($article === FALSE) { | |
150 nntp_writeline(STDOUT, '430 no such article found'); | |
151 return NULL; | |
152 } | |
153 } else { | |
154 nntp_writeline(STDOUT, '500 Error in arguments'); | |
155 } | |
156 $article['messagenumber'] = $messagenumber; | |
157 return $article; | |
158 } | |
159 | |
160 function writelog($line) { | |
161 global $logfile; | |
162 fwrite($logfile, $line."\n"); | |
163 } |