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

Contents of /innwebd/innd.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.13 - (show annotations)
Fri Apr 11 17:14:49 2008 UTC (17 years, 11 months ago) by sysadm
Branch: MAIN
CVS Tags: HEAD
Changes since 1.12: +8 -8 lines
Content type: text/x-c++src
Error occurred while calculating annotation data.
Update copyright
Add extra log for exception

1 /*******************************************************/
2 /* */
3 /* LeafOK Innbbsd */
4 /* */
5 /* Copyright (C) LeafOK.com, 2003-2008 */
6 /* */
7 /* http://www.leafok.com */
8 /* */
9 /*******************************************************/
10
11 #include "StdAfx.h"
12 #include ".\innd.h"
13 #include ".\base_active.h"
14 #include ".\App_common.h"
15
16 using namespace std;
17
18 bool innd::thread_terminate = true;
19
20 innd::innd(void)
21 {
22 }
23
24 innd::~innd(void)
25 {
26 }
27
28 int innd::Accept(void)
29 {
30 CString out,cmd;
31 char temp[256];
32
33 try
34 {
35 out.Format("200 %s ready.",App_common::GetVersion());
36 this->s_send(out);
37 while(!this->thread_terminate)
38 {
39 this->GetParentThread()->GetThreadPool()->SetThreadStatus(GetCurrentThreadId(),thread_pool::S_WAITING);
40
41 if (this->s_receive(out) == 0) //Connection closed
42 break;
43 out.Trim();
44
45 this->GetParentThread()->GetThreadPool()->SetThreadStatus(GetCurrentThreadId(),thread_pool::S_WORKING);
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 char strErrMsg[1024];
124 e->GetErrorMessage(strErrMsg,1024);
125 syslog << logfile::log_head << "Error in accept() [" << strErrMsg << "]" << endl;
126 e->Delete();
127 return -1;
128 }
129
130 return 0;
131 }
132
133 innd* innd::new_client(void)
134 {
135 return (new innd());
136 }
137
138 bool innd::IsShutdown(void)
139 {
140 return this->thread_terminate;
141 }
142
143 int innd::cmd_list(void)
144 {
145 CRecordset RS(&(this->Db));
146 CDBVariant dbVar;
147 CString sql,group,out;
148 long art_begin,art_end;
149 bool p;
150
151 try
152 {
153 this->s_send("215 Newsgroups(group last first p)");
154
155 sql = "select * from innd_conf order by `group`";
156
157 RS.Open(CRecordset::snapshot,sql,CRecordset::forwardOnly | CRecordset::readOnly);
158 while(!RS.IsEOF())
159 {
160 RS.GetFieldValue("group",dbVar,SQL_C_CHAR);
161 group = *(dbVar.m_pstring);
162 art_begin = 1;
163 art_end = 0;;
164 RS.GetFieldValue("in",dbVar,SQL_C_SSHORT);
165 p = (dbVar.m_iVal!=0);
166 out.Format("%s %.10ld %.10ld %c",group,art_end,art_begin,(p?'y':'n'));
167 this->s_send(out);
168 RS.MoveNext();
169 }
170 RS.Close();
171
172 this->s_send(".");
173 }
174 catch(CException* e)
175 {
176 char strErrMsg[1024];
177 e->GetErrorMessage(strErrMsg,1024);
178 syslog << logfile::log_head << "Error in cmd_list() [" << strErrMsg << "]" << endl;
179 e->Delete();
180 return -1;
181 }
182
183 return 0;
184 }
185
186 int innd::cmd_ihave(const char* msg_id)
187 {
188 CRecordset RS(&(this->Db));
189 CStringArray group_list;
190 CDBVariant dbVar;
191 const char *p,*p1,*p2;
192 bool head_find;
193 char cmd[50],cancel_msg_id[256];
194 CString head_name,head_value,path,control,newsgroups,organization; //Head
195 CString head,body,sql,out,group;
196 long sid[256];
197 int sid_count = 0;
198
199 try
200 {
201 this->s_send("335 OK, send article to be transferred.");
202 this->s_receive(out,".\r\n");
203
204 if (out.Right(5) != "\r\n.\r\n")
205 {
206 this->s_send("437 Empty article");
207 syslog << logfile::log_head << "Empty article" << endl;
208 return 1;
209 }
210
211 out = out.Left(out.GetLength()-3);
212 head = out.Left(out.Find("\r\n\r\n")+2);
213 body = out.Mid(out.Find("\r\n\r\n")+4);
214
215 p = p1 = p2 = head;
216 control = "none";
217 newsgroups = organization = "";
218
219 while(*p1)
220 {
221 head_find = false;
222 head_name = "";
223 head_value = "";
224 while (*p2)
225 {
226 if (!head_find && *p2==':' && *(p2+1)==' ')
227 {
228 //Get head name
229 head_name = head.Mid((int)(p1-p),(int)(p2-p1));
230 head_find=true;
231 p2+=2;
232 p1=p2;
233 }
234 if (*p2=='\r' && *(p2+1)=='\n')
235 {
236 //Get head value
237 head_value = head.Mid((int)(p1-p),(int)(p2-p1));
238 p2 += 2;
239 p1 = p2;
240 if (head_find)
241 {
242 //Set head info
243 if (head_name == "Path")
244 path = head_value;
245 if (head_name == "Control")
246 control = head_value;
247 if (head_name == "Newsgroups")
248 newsgroups = head_value;
249 if (head_name == "Organization")
250 organization = head_value;
251 }
252 break;
253 }
254 p2++;
255 }
256 }
257
258 newsgroups = base::addslashes(newsgroups);
259 newsgroups.Replace(",","','");
260
261 sql.Format("select SID from innd_conf right join innd_access on"
262 " innd_conf.server=innd_access.server where `group` in ('%s') and"
263 " `in`=1 and innd_conf.passive_mode=1 and innd_access.ip='%s'",
264 newsgroups,this->access.ip);
265
266 RS.Open(CRecordset::snapshot,sql,CRecordset::forwardOnly | CRecordset::readOnly);
267 while(!RS.IsEOF())
268 {
269 RS.GetFieldValue("SID",dbVar,SQL_C_SSHORT);
270 sid[sid_count++] = dbVar.m_iVal;
271 RS.MoveNext();
272 }
273 RS.Close();
274
275 if (sid_count == 0)
276 {
277 this->s_send("437 Not in a allowed newsgroup");
278 syslog << logfile::log_head << "Not in a allowed newsgroup" << endl;
279 return 2;
280 }
281
282 if (organization==this->innd_name ||
283 path.Right(CString::StringLength(this->innd_id))==this->innd_id)
284 {
285 this->s_send("437 I already have it");
286 syslog << logfile::log_head << "I already have it" << endl;
287 return 2;
288 }
289
290 if (control == "none")
291 {
292 strcpy(cmd,"");
293 }
294 else
295 {
296 sscanf(control,"%s %s",cmd,cancel_msg_id);
297 }
298
299 if (strcmp(cmd,"")==0)
300 {
301 for (int i=0; i<sid_count; i++)
302 {
303 if (this->bbs_post(head,body,sid[i],0) == 0)
304 {
305 syslog << logfile::log_head << "Post OK" << endl;
306 }
307 else
308 {
309 syslog << logfile::log_head << "Post failed" << endl;
310 }
311 }
312 this->s_send("235 Article transferred ok");
313 return 0;
314 }
315
316 if (strcmp(cmd,"cancel")==0 && strcmp(cancel_msg_id,"")!=0) //Empty Message-ID
317 {
318 //Delete article
319 sql.Format("select AID from innd_log where msg_id='%s'"
320 " and op='I' and cancel=0",base::addslashes(cancel_msg_id));
321
322 RS.Open(CRecordset::snapshot,sql,CRecordset::forwardOnly | CRecordset::readOnly);
323
324 if(!RS.IsEOF())
325 {
326 RS.GetFieldValue("AID",dbVar,SQL_C_SLONG);
327
328 if (this->bbs_delete(dbVar.m_lVal) == 0)
329 {
330 syslog << logfile::log_head << "Delete OK" << endl;
331 }
332 else
333 {
334 syslog << logfile::log_head << "Delete failed" << endl;
335 }
336 }
337 else
338 {
339 syslog << logfile::log_head << "Message-ID not found" << endl;
340 }
341 RS.Close();
342 this->s_send("235 Article transferred ok");
343 return 0;
344 }
345
346 if (strcmp(cmd,"checkgroups")==0)
347 {
348 this->s_send("235 Article transferred ok");
349 syslog << logfile::log_head << "Checkgroups" << endl;
350 return 0;
351 }
352
353 this->s_send("235 Article transferred ok");
354 syslog << logfile::log_head << "Incorrect message" << endl;
355 }
356 catch(CException* e)
357 {
358 char strErrMsg[1024];
359 e->GetErrorMessage(strErrMsg,1024);
360 syslog << logfile::log_head << "Error in cmd_ihave() [" << strErrMsg << "]" << endl;
361 e->Delete();
362 return -1;
363 }
364
365 return 0;
366 }
367
368 int innd::Shutdown(void)
369 {
370 base_active nntpClient;
371
372 if (this->thread_terminate)
373 return 1;
374
375 this->thread_terminate = true;
376 nntpClient.configure(this->innd_id,this->innd_name,this->innd_server,this->innd_uid,this->w_address,0,this->w_conn_str);
377 nntpClient.s_connect((strlen(this->hostaddr)>0 ? this->hostaddr : "127.0.0.1"),this->port);
378 nntpClient.s_close();
379
380 return 0;
381 }
382
383 int innd::Startup(void)
384 {
385 if (!this->thread_terminate)
386 return 1;
387
388 this->thread_terminate = false;
389
390 return 0;
391 }
392
393 int innd::db_env_init(void)
394 {
395 if (this->db_open(this->w_conn_str) != 0)
396 {
397 return -1;
398 }
399 return 0;
400 }
401
402 bool innd::check_priv(void)
403 {
404 return this->access.get;
405 }

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