comparison server.php @ 2:40e545510a57

Added support for POSTing to the server, added readme and todo, added support for upstream synchronization using POST
author Ivo Smits <Ivo@UCIS.nl>
date Tue, 12 Apr 2011 00:29:41 +0200
parents d7ab68b71c74
children 0dcdb73cbcbf
comparison
equal deleted inserted replaced
1:61fac319ca3e 2:40e545510a57
1 #!/usr/bin/php 1 #!/usr/bin/php
2 <?php 2 <?php
3 chdir('/home/ivo/projects/pnewss'); 3 chdir(__DIR__);
4 require_once './pdo.php'; 4 require_once './pdo.php';
5 require_once './config.php'; 5 require_once './config.php';
6 6
7 $logfile = fopen('./server.log', 'w'); 7 $logfile = fopen('./server.log', 'w');
8 $currentgroup = NULL; 8 $currentgroup = NULL;
22 set_error_handler("error_handler"); 22 set_error_handler("error_handler");
23 23
24 nntp_writeline(STDOUT, '200 pNewss ready'); 24 nntp_writeline(STDOUT, '200 pNewss ready');
25 while (TRUE) { 25 while (TRUE) {
26 $line = nntp_readline(STDIN); 26 $line = nntp_readline(STDIN);
27 if ($line === FALSE || $line === NULL) break; 27 if ($line === FALSE || $line === NULL) break;
28 $cmd = strtok($line, " \t"); 28 $cmd = strtok($line, " \t");
29 switch (strtoupper($cmd)) { 29 switch (strtoupper($cmd)) {
30 case 'LIST': 30 case 'LIST':
31 nntp_writeline(STDOUT, '215 List of groups follows'); 31 nntp_writeline(STDOUT, '215 List of groups follows');
32 foreach ($db->evalAllAssoc('SELECT * FROM `groups`') as $group) { 32 foreach ($db->evalAllAssoc('SELECT * FROM `groups`') as $group) {
114 } 114 }
115 $currentarticle = $article; 115 $currentarticle = $article;
116 nntp_writeline(STDOUT, '223 '.$article['number'].' <'.$articlea['messageid'].'> ok'); 116 nntp_writeline(STDOUT, '223 '.$article['number'].' <'.$articlea['messageid'].'> ok');
117 } 117 }
118 break; 118 break;
119 case 'POST':
120 nntp_writeline(STDOUT, '340 Ok, recommended message-ID <'.md5(time().rand()).'@pNews.Core.UCIS.nl>');
121 $lines = nntp_readlines(STDIN);
122 $header = array();
123 $headers = array();
124 while (count($lines)) {
125 $line = array_shift($lines);
126 if (!strlen($line)) break;
127 $parts = explode(': ', $line, 2);
128 $headers[strtoupper($parts[0])] = $parts[1];
129 switch (strtoupper($parts[0])) {
130 case 'PATH':
131 $line = $parts[0].': pNews.Core.UCIS.nl!'.$parts[1];
132 break;
133 case 'FROM': case 'NEWSGROUPS': case 'SUBJECT': case 'DATE': case 'ORGANIZATION':
134 case 'LINES': case 'MESSAGE-ID': case 'MIME-VERSION': case 'CONTENT-TYPE': case 'CONTENT-TRANSFER-ENCODING':
135 case 'USER-AGENT': case 'REFERENCES': case 'REPLY-TO': case 'SENDER': case 'FOLLOWUP-TO':
136 case 'EXPIRES': case 'CONTROL': case 'DISTRIBUTION': case 'KEYWORDS': case 'SUMMARY':
137 case 'IN-REPLY-TO':
138 break;
139 case 'NNTP-POSTING-HOST': case 'X-TRACE': case 'XREF': case 'X-COMPLAINTS-TO':
140 case 'NNTP-POSTING-DATE':
141 $line = NULL;
142 break;
143 default:
144 writelog("Received unknown header $parts[0]");
145 }
146 if ($line !== NULL) $header[] = $line;
147 }
148 if (!isset($headers['NEWSGROUPS'])) {
149 nntp_writeline(STDOUT, '441 Missing required Newsgroups: header');
150 break;
151 }
152 if (!isset($headers['MESSAGE-ID'])) {
153 $headers['MESSAGE-ID'] = '<'.md5(time().rand()).'@pNews.Core.UCIS.nl>';
154 $header[] = 'Message-ID: '.$headers['MESSAGE-ID'];
155 }
156 if (!isset($headers['PATH'])) {
157 $headers['PATH'] = 'pNews.Core.UCIS.nl';
158 $header[] = 'Path: '.$headers['PATH'];
159 }
160 $msgid = $headers['MESSAGE-ID'];
161 if (strlen($msgid) <= 2 || $msgid[0] != '<' || $msgid[strlen($msgid)-1] != '>') {
162 nntp_writeline(STDOUT, '441 435 Bad Message-ID');
163 break;
164 }
165 $msgid = substr($msgid, 1, -1);
166 $article = $db->evalRowAssoc('SELECT * FROM `messages` WHERE `messageid` = ?', $msgid);
167 if ($article !== FALSE) {
168 nntp_writeline(STDOUT, '441 435 Duplicate');
169 return NULL;
170 }
171 $id = $db->insert('INSERT INTO `messages` (`messageid`, `header`, `body`) VALUES (?, ?, ?)', array($msgid, implode("\r\n", $header), implode("\r\n", $lines)));
172 foreach (explode(',', $headers['NEWSGROUPS']) as $groupname) {
173 $group = $db->evalRowAssoc('SELECT * FROM `groups` WHERE `name` = ?', $groupname);
174 if ($group === FALSE) continue;
175 $db->insert('INSERT INTO `groupmessages` (`group`, `message`) VALUES (?, ?)', array($group['id'], $id));
176 }
177 nntp_writeline(STDOUT, '240 Article received <'.$msgid.'>');
178 break;
119 case 'QUIT': 179 case 'QUIT':
120 nntp_writeline(STDOUT, '205 .'); 180 nntp_writeline(STDOUT, '205 .');
121 return; 181 return;
122 case 'XOVER': 182 case 'XOVER':
123 case 'MODE': 183 case 'MODE':