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

Annotation of /innwebd/innd.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.5 - (hide 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 sysadm 1.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 sysadm 1.3 #include "StdAfx.h"
16     #include ".\innd.h"
17 sysadm 1.4 #include ".\base_active.h"
18 sysadm 1.3 #include ".\App_common.h"
19 sysadm 1.1
20 sysadm 1.3 using namespace std;
21 sysadm 1.1
22 sysadm 1.3 bool innd::thread_terminate = true;
23 sysadm 1.1
24 sysadm 1.3 innd::innd(void)
25     {
26     }
27 sysadm 1.1
28 sysadm 1.3 innd::~innd(void)
29     {
30     }
31 sysadm 1.1
32 sysadm 1.3 int innd::Accept(void)
33     {
34     CString out,cmd;
35     char temp[256];
36 sysadm 1.5 HANDLE hThreadCurrent;
37 sysadm 1.1
38 sysadm 1.3 try
39     {
40 sysadm 1.5 hThreadCurrent = GetCurrentThread();
41    
42 sysadm 1.3 out.Format("200 %s ready.",App_common::GetVersion());
43     this->s_send(out);
44     while(!this->thread_terminate)
45     {
46 sysadm 1.5 this->GetParentThread()->GetThreadPool()->SetThreadStatus(hThreadCurrent,thread_pool::S_WAITING);
47    
48 sysadm 1.3 if (this->s_receive(out) == 0) //Connection closed
49     break;
50     out.Trim();
51    
52 sysadm 1.5 this->GetParentThread()->GetThreadPool()->SetThreadStatus(hThreadCurrent,thread_pool::S_WORKING);
53    
54 sysadm 1.3 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 sysadm 1.1
125 sysadm 1.3 this->s_send("500 What?");
126     }
127     }
128     catch(CException* e)
129 sysadm 1.1 {
130 sysadm 1.3 syslog << logfile::log_head << "Error in accept()" << endl;
131     e->Delete();
132     return -1;
133 sysadm 1.1 }
134    
135 sysadm 1.3 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 sysadm 1.1
160 sysadm 1.3 sql = "select * from innd_conf order by `group`";
161 sysadm 1.1
162 sysadm 1.3 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 sysadm 1.1
177 sysadm 1.3 this->s_send(".");
178     }
179     catch(CException* e)
180 sysadm 1.1 {
181 sysadm 1.3 syslog << logfile::log_head << "Error in cmd_list()" << endl;
182     e->Delete();
183     return -1;
184 sysadm 1.1 }
185    
186 sysadm 1.3 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 sysadm 1.1
207 sysadm 1.3 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 sysadm 1.1
222 sysadm 1.3 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 sysadm 1.1
269 sysadm 1.3 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 sysadm 1.1
319 sysadm 1.3 if (strcmp(cmd,"cancel")==0 && strcmp(cancel_msg_id,"")!=0) //Empty Message-ID
320 sysadm 1.1 {
321 sysadm 1.3 //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 sysadm 1.1
349 sysadm 1.3 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 sysadm 1.1
356 sysadm 1.3 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 sysadm 1.1 }
365    
366 sysadm 1.3 return 0;
367     }
368 sysadm 1.1
369 sysadm 1.3 int innd::Shutdown(void)
370     {
371 sysadm 1.4 base_active nntpClient;
372 sysadm 1.3
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 sysadm 1.1 }

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