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

Annotation of /innwebd/innd.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.13 - (hide 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
Update copyright
Add extra log for exception

1 sysadm 1.1 /*******************************************************/
2     /* */
3 sysadm 1.6 /* LeafOK Innbbsd */
4 sysadm 1.1 /* */
5 sysadm 1.13 /* Copyright (C) LeafOK.com, 2003-2008 */
6 sysadm 1.1 /* */
7 sysadm 1.13 /* http://www.leafok.com */
8 sysadm 1.1 /* */
9     /*******************************************************/
10    
11 sysadm 1.3 #include "StdAfx.h"
12     #include ".\innd.h"
13 sysadm 1.4 #include ".\base_active.h"
14 sysadm 1.3 #include ".\App_common.h"
15 sysadm 1.1
16 sysadm 1.3 using namespace std;
17 sysadm 1.1
18 sysadm 1.3 bool innd::thread_terminate = true;
19 sysadm 1.1
20 sysadm 1.3 innd::innd(void)
21     {
22     }
23 sysadm 1.1
24 sysadm 1.3 innd::~innd(void)
25     {
26     }
27 sysadm 1.1
28 sysadm 1.3 int innd::Accept(void)
29     {
30     CString out,cmd;
31     char temp[256];
32 sysadm 1.1
33 sysadm 1.3 try
34     {
35     out.Format("200 %s ready.",App_common::GetVersion());
36     this->s_send(out);
37     while(!this->thread_terminate)
38     {
39 sysadm 1.6 this->GetParentThread()->GetThreadPool()->SetThreadStatus(GetCurrentThreadId(),thread_pool::S_WAITING);
40 sysadm 1.5
41 sysadm 1.3 if (this->s_receive(out) == 0) //Connection closed
42     break;
43     out.Trim();
44    
45 sysadm 1.6 this->GetParentThread()->GetThreadPool()->SetThreadStatus(GetCurrentThreadId(),thread_pool::S_WORKING);
46 sysadm 1.5
47 sysadm 1.3 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 sysadm 1.1
118 sysadm 1.3 this->s_send("500 What?");
119     }
120     }
121     catch(CException* e)
122 sysadm 1.1 {
123 sysadm 1.13 char strErrMsg[1024];
124     e->GetErrorMessage(strErrMsg,1024);
125     syslog << logfile::log_head << "Error in accept() [" << strErrMsg << "]" << endl;
126 sysadm 1.3 e->Delete();
127     return -1;
128 sysadm 1.1 }
129    
130 sysadm 1.3 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 sysadm 1.1
155 sysadm 1.3 sql = "select * from innd_conf order by `group`";
156 sysadm 1.1
157 sysadm 1.9 RS.Open(CRecordset::snapshot,sql,CRecordset::forwardOnly | CRecordset::readOnly);
158 sysadm 1.8 while(!RS.IsEOF())
159 sysadm 1.3 {
160     RS.GetFieldValue("group",dbVar,SQL_C_CHAR);
161 sysadm 1.7 group = *(dbVar.m_pstring);
162 sysadm 1.3 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 sysadm 1.1
172 sysadm 1.3 this->s_send(".");
173     }
174     catch(CException* e)
175 sysadm 1.1 {
176 sysadm 1.13 char strErrMsg[1024];
177     e->GetErrorMessage(strErrMsg,1024);
178     syslog << logfile::log_head << "Error in cmd_list() [" << strErrMsg << "]" << endl;
179 sysadm 1.3 e->Delete();
180     return -1;
181 sysadm 1.1 }
182    
183 sysadm 1.3 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 sysadm 1.1
204 sysadm 1.3 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 sysadm 1.1
219 sysadm 1.3 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 sysadm 1.1
266 sysadm 1.3 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 sysadm 1.1
316 sysadm 1.3 if (strcmp(cmd,"cancel")==0 && strcmp(cancel_msg_id,"")!=0) //Empty Message-ID
317 sysadm 1.1 {
318 sysadm 1.3 //Delete article
319 sysadm 1.7 sql.Format("select AID from innd_log where msg_id='%s'"
320 sysadm 1.3 " 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 sysadm 1.1
346 sysadm 1.3 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 sysadm 1.1
353 sysadm 1.3 this->s_send("235 Article transferred ok");
354     syslog << logfile::log_head << "Incorrect message" << endl;
355     }
356     catch(CException* e)
357     {
358 sysadm 1.10 char strErrMsg[1024];
359     e->GetErrorMessage(strErrMsg,1024);
360 sysadm 1.7 syslog << logfile::log_head << "Error in cmd_ihave() [" << strErrMsg << "]" << endl;
361 sysadm 1.3 e->Delete();
362     return -1;
363 sysadm 1.1 }
364    
365 sysadm 1.3 return 0;
366     }
367 sysadm 1.1
368 sysadm 1.3 int innd::Shutdown(void)
369     {
370 sysadm 1.4 base_active nntpClient;
371 sysadm 1.3
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 sysadm 1.1 }
401 sysadm 1.11
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