/[LeafOK_CVS]/innwebd/innd.cpp
ViewVC logotype

Contents of /innwebd/innd.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.4 - (show annotations)
Sat Jul 3 05:30:04 2004 UTC (21 years, 8 months ago) by sysadm
Branch: MAIN
Changes since 1.3: +2 -2 lines
Content type: text/x-c++src
Rename to class nntp_active to base_active
Rename to class nntp_passive to base_passive

1 /*******************************************************/
2 /* */
3 /* LeafOK Innd */
4 /* Copyright (C) LeafOK.com, 2003-2004 */
5 /* */
6 /* Programmed by Leaf */
7 /* E-mail:leaf@leafok.com QQ:6049044 */
8 /* */
9 /* http://bbs.leafok.com */
10 /* http://bbs.leafok.net */
11 /* http://bbs.fenglin.info */
12 /* */
13 /*******************************************************/
14
15 #include "StdAfx.h"
16 #include ".\innd.h"
17 #include ".\base_active.h"
18 #include ".\App_common.h"
19
20 using namespace std;
21
22 bool innd::thread_terminate = true;
23
24 innd::innd(void)
25 {
26 }
27
28 innd::~innd(void)
29 {
30 }
31
32 int innd::Accept(void)
33 {
34 CString out,cmd;
35 char temp[256];
36
37 try
38 {
39 out.Format("200 %s ready.",App_common::GetVersion());
40 this->s_send(out);
41 while(!this->thread_terminate)
42 {
43 if (this->s_receive(out) == 0) //Connection closed
44 break;
45 out.Trim();
46
47 syslog << logfile::log_head << "Cmd: " << out << endl;
48
49 if (sscanf(out,"%20s",temp) ==1)
50 cmd = strupr(temp);
51 else
52 cmd = "";
53
54 if (cmd == "") //Blank command
55 continue;
56
57 if (cmd == "MODE")
58 {
59 if (sscanf(out,"%*s %20s",temp) ==1)
60 cmd = strupr(temp);
61 else
62 cmd = "";
63 cmd.Trim();
64
65 if (cmd == "READER" || cmd == "STREAM")
66 {
67 if (cmd == "READER")
68 {
69 out.Format("200 %s ready <posting ok>.",App_common::GetVersion());
70 this->s_send(out);
71 }
72 if (cmd == "STREAM")
73 {
74 this->s_send("203 StreamOK.");
75 }
76 }
77 else
78 {
79 this->s_send("501 reader");
80 }
81 continue;
82 }
83
84 if (cmd == "LIST")
85 {
86 this->cmd_list();
87 continue;
88 }
89
90 if (cmd == "IHAVE")
91 {
92 if (sscanf(out,"%*s %255s",temp) == 1)
93 cmd = strupr(temp);
94 else
95 cmd = "";
96 cmd.Trim();
97
98 if (cmd != "" && cmd.Left(1) == "<" && cmd.Right(1) == ">")
99 {
100 if (this->access.ihave)
101 this->cmd_ihave(out);
102 else
103 this->s_send("480 Transfer permission denied");
104 }
105 else
106 {
107 this->s_send("501 Message-ID");
108 }
109 continue;
110 }
111
112 if (cmd == "QUIT")
113 {
114 this->s_send("205 .\r\n");
115 break;
116 }
117
118 this->s_send("500 What?");
119 }
120 }
121 catch(CException* e)
122 {
123 syslog << logfile::log_head << "Error in accept()" << endl;
124 e->Delete();
125 return -1;
126 }
127
128 return 0;
129 }
130
131 innd* innd::new_client(void)
132 {
133 return (new innd());
134 }
135
136 bool innd::IsShutdown(void)
137 {
138 return this->thread_terminate;
139 }
140
141 int innd::cmd_list(void)
142 {
143 CRecordset RS(&(this->Db));
144 CDBVariant dbVar;
145 CString sql,group,out;
146 long art_begin,art_end;
147 bool p;
148
149 try
150 {
151 this->s_send("215 Newsgroups(group last first p)");
152
153 sql = "select * from innd_conf order by `group`";
154
155 RS.Open(CRecordset::snapshot,sql,CRecordst::forwardOnly | CRecordset::readOnly);
156 while(!RS.IsEEOF())
157 {
158 RS.GetFieldValue("group",dbVar,SQL_C_CHAR);
159 group = *(dbVr.m_pstring);
160 art_begin = 1;
161 art_end = 0;;
162 RS.GetFieldValue("in",dbVar,SQL_C_SSHORT);
163 p = (dbVar.m_iVal!=0);
164 out.Format("%s %.10ld %.10ld %c",group,art_end,art_begin,(p?'y':'n'));
165 this->s_send(out);
166 RS.MoveNext();
167 }
168 RS.Close();
169
170 this->s_send(".");
171 }
172 catch(CException* e)
173 {
174 syslog << logfile::log_head << "Error in cmd_list()" << endl;
175 e->Delete();
176 return -1;
177 }
178
179 return 0;
180 }
181
182 int innd::cmd_ihave(const char* msg_id)
183 {
184 CRecordset RS(&(this->Db));
185 CStringArray group_list;
186 CDBVariant dbVar;
187 const char *p,*p1,*p2;
188 bool head_find;
189 char cmd[50],cancel_msg_id[256];
190 CString head_name,head_value,path,control,newsgroups,organization; //Head
191 CString head,body,sql,out,group;
192 long sid[256];
193 int sid_count = 0;
194
195 try
196 {
197 this->s_send("335 OK, send article to be transferred.");
198 this->s_receive(out,".\r\n");
199
200 if (out.Right(5) != "\r\n.\r\n")
201 {
202 this->s_send("437 Empty article");
203 syslog << logfile::log_head << "Empty article" << endl;
204 return 1;
205 }
206
207 out = out.Left(out.GetLength()-3);
208 head = out.Left(out.Find("\r\n\r\n")+2);
209 body = out.Mid(out.Find("\r\n\r\n")+4);
210
211 p = p1 = p2 = head;
212 control = "none";
213 newsgroups = organization = "";
214
215 while(*p1)
216 {
217 head_find = false;
218 head_name = "";
219 head_value = "";
220 while (*p2)
221 {
222 if (!head_find && *p2==':' && *(p2+1)==' ')
223 {
224 //Get head name
225 head_name = head.Mid((int)(p1-p),(int)(p2-p1));
226 head_find=true;
227 p2+=2;
228 p1=p2;
229 }
230 if (*p2=='\r' && *(p2+1)=='\n')
231 {
232 //Get head value
233 head_value = head.Mid((int)(p1-p),(int)(p2-p1));
234 p2 += 2;
235 p1 = p2;
236 if (head_find)
237 {
238 //Set head info
239 if (head_name == "Path")
240 path = head_value;
241 if (head_name == "Control")
242 control = head_value;
243 if (head_name == "Newsgroups")
244 newsgroups = head_value;
245 if (head_name == "Organization")
246 organization = head_value;
247 }
248 break;
249 }
250 p2++;
251 }
252 }
253
254 newsgroups = base::addslashes(newsgroups);
255 newsgroups.Replace(",","','");
256
257 sql.Format("select SID from innd_conf right join innd_access on"
258 " innd_conf.server=innd_access.server where `group` in ('%s') and"
259 " `in`=1 and innd_conf.passive_mode=1 and innd_access.ip='%s'",
260 newsgroups,this->access.ip);
261
262 RS.Open(CRecordset::snapshot,sql,CRecordset::forwardOnly | CRecordset::readOnly);
263 while(!RS.IsEOF())
264 {
265 RS.GetFieldValue("SID",dbVar,SQL_C_SSHORT);
266 sid[sid_count++] = dbVar.m_iVal;
267 RS.MoveNext();
268 }
269 RS.Close();
270
271 if (sid_count == 0)
272 {
273 this->s_send("437 Not in a allowed newsgroup");
274 syslog << logfile::log_head << "Not in a allowed newsgroup" << endl;
275 return 2;
276 }
277
278 if (organization==this->innd_name ||
279 path.Right(CString::StringLength(this->innd_id))==this->innd_id)
280 {
281 this->s_send("437 I already have it");
282 syslog << logfile::log_head << "I already have it" << endl;
283 return 2;
284 }
285
286 if (control == "none")
287 {
288 strcpy(cmd,"");
289 }
290 else
291 {
292 sscanf(control,"%s %s",cmd,cancel_msg_id);
293 }
294
295 if (strcmp(cmd,"")==0)
296 {
297 for (int i=0; i<sid_count; i++)
298 {
299 if (this->bbs_post(head,body,sid[i],0) == 0)
300 {
301 syslog << logfile::log_head << "Post OK" << endl;
302 }
303 else
304 {
305 syslog << logfile::log_head << "Post failed" << endl;
306 }
307 }
308 this->s_send("235 Article transferred ok");
309 return 0;
310 }
311
312 if (strcmp(cmd,"cancel")==0 && strcmp(cancel_msg_id,"")!=0) //Empty Message-ID
313 {
314 //Delete article
315 sql.Format("select AID from innd_logfile where msg_id='%s'"
316 " and op='I' and cancel=0",base::addslashes(cancel_msg_id));
317
318 RS.Open(CRecordset::snapshot,sql,CRecordset::forwardOnly | CRecordset::readOnly);
319
320 if(!RS.IsEOF())
321 {
322 RS.GetFieldValue("AID",dbVar,SQL_C_SLONG);
323
324 if (this->bbs_delete(dbVar.m_lVal) == 0)
325 {
326 syslog << logfile::log_head << "Delete OK" << endl;
327 }
328 else
329 {
330 syslog << logfile::log_head << "Delete failed" << endl;
331 }
332 }
333 else
334 {
335 syslog << logfile::log_head << "Message-ID not found" << endl;
336 }
337 RS.Close();
338 this->s_send("235 Article transferred ok");
339 return 0;
340 }
341
342 if (strcmp(cmd,"checkgroups")==0)
343 {
344 this->s_send("235 Article transferred ok");
345 syslog << logfile::log_head << "Checkgroups" << endl;
346 return 0;
347 }
348
349 this->s_send("235 Article transferred ok");
350 syslog << logfile::log_head << "Incorrect message" << endl;
351 }
352 catch(CException* e)
353 {
354 syslog << logfile::log_head << "Error in cmd_ihave()" << endl;
355 e->Delete();
356 return -1;
357 }
358
359 return 0;
360 }
361
362 int innd::Shutdown(void)
363 {
364 base_active nntpClient;
365
366 if (this->thread_terminate)
367 return 1;
368
369 this->thread_terminate = true;
370 nntpClient.configure(this->innd_id,this->innd_name,this->innd_server,this->innd_uid,this->w_address,0,this->w_conn_str);
371 nntpClient.s_connect((strlen(this->hostaddr)>0 ? this->hostaddr : "127.0.0.1"),this->port);
372 nntpClient.s_close();
373
374 return 0;
375 }
376
377 int innd::Startup(void)
378 {
379 if (!this->thread_terminate)
380 return 1;
381
382 this->thread_terminate = false;
383
384 return 0;
385 }
386
387 int innd::db_env_init(void)
388 {
389 if (this->db_open(this->w_conn_str) != 0)
390 {
391 return -1;
392 }
393 return 0;
394 }

webmaster@leafok.com
ViewVC Help
Powered by ViewVC 1.3.0-beta1