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

Contents of /innwebd/innd.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.5 - (show annotations)
Sat Jul 3 13:56:04 2004 UTC (21 years, 8 months ago) by sysadm
Branch: MAIN
Changes since 1.4: +7 -0 lines
Content type: text/x-c++src
Add thread_pool

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

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