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

Annotation of /innwebd/innd.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.9 - (hide annotations)
Sun Jul 4 22:15:25 2004 UTC (21 years, 8 months ago) by sysadm
Branch: MAIN
Changes since 1.8: +1 -1 lines
Content type: text/x-c++src
no message

1 sysadm 1.1 /*******************************************************/
2     /* */
3 sysadm 1.6 /* LeafOK Innbbsd */
4 sysadm 1.1 /* Copyright (C) LeafOK.com, 2003-2004 */
5     /* */
6     /* Programmed by Leaf */
7 sysadm 1.6 /* E-mail:leaflet@leafok.com QQ:6049044 */
8 sysadm 1.1 /* */
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.1
37 sysadm 1.3 try
38     {
39     out.Format("200 %s ready.",App_common::GetVersion());
40     this->s_send(out);
41     while(!this->thread_terminate)
42     {
43 sysadm 1.6 this->GetParentThread()->GetThreadPool()->SetThreadStatus(GetCurrentThreadId(),thread_pool::S_WAITING);
44 sysadm 1.5
45 sysadm 1.3 if (this->s_receive(out) == 0) //Connection closed
46     break;
47     out.Trim();
48    
49 sysadm 1.6 this->GetParentThread()->GetThreadPool()->SetThreadStatus(GetCurrentThreadId(),thread_pool::S_WORKING);
50 sysadm 1.5
51 sysadm 1.3 syslog << logfile::log_head << "Cmd: " << out << endl;
52    
53     if (sscanf(out,"%20s",temp) ==1)
54     cmd = strupr(temp);
55     else
56     cmd = "";
57    
58     if (cmd == "") //Blank command
59     continue;
60    
61     if (cmd == "MODE")
62     {
63     if (sscanf(out,"%*s %20s",temp) ==1)
64     cmd = strupr(temp);
65     else
66     cmd = "";
67     cmd.Trim();
68    
69     if (cmd == "READER" || cmd == "STREAM")
70     {
71     if (cmd == "READER")
72     {
73     out.Format("200 %s ready <posting ok>.",App_common::GetVersion());
74     this->s_send(out);
75     }
76     if (cmd == "STREAM")
77     {
78     this->s_send("203 StreamOK.");
79     }
80     }
81     else
82     {
83     this->s_send("501 reader");
84     }
85     continue;
86     }
87    
88     if (cmd == "LIST")
89     {
90     this->cmd_list();
91     continue;
92     }
93    
94     if (cmd == "IHAVE")
95     {
96     if (sscanf(out,"%*s %255s",temp) == 1)
97     cmd = strupr(temp);
98     else
99     cmd = "";
100     cmd.Trim();
101    
102     if (cmd != "" && cmd.Left(1) == "<" && cmd.Right(1) == ">")
103     {
104     if (this->access.ihave)
105     this->cmd_ihave(out);
106     else
107     this->s_send("480 Transfer permission denied");
108     }
109     else
110     {
111     this->s_send("501 Message-ID");
112     }
113     continue;
114     }
115    
116     if (cmd == "QUIT")
117     {
118     this->s_send("205 .\r\n");
119     break;
120     }
121 sysadm 1.1
122 sysadm 1.3 this->s_send("500 What?");
123     }
124     }
125     catch(CException* e)
126 sysadm 1.1 {
127 sysadm 1.3 syslog << logfile::log_head << "Error in accept()" << endl;
128     e->Delete();
129     return -1;
130 sysadm 1.1 }
131    
132 sysadm 1.3 return 0;
133     }
134    
135     innd* innd::new_client(void)
136     {
137     return (new innd());
138     }
139    
140     bool innd::IsShutdown(void)
141     {
142     return this->thread_terminate;
143     }
144    
145     int innd::cmd_list(void)
146     {
147     CRecordset RS(&(this->Db));
148     CDBVariant dbVar;
149     CString sql,group,out;
150     long art_begin,art_end;
151     bool p;
152    
153     try
154     {
155     this->s_send("215 Newsgroups(group last first p)");
156 sysadm 1.1
157 sysadm 1.3 sql = "select * from innd_conf order by `group`";
158 sysadm 1.1
159 sysadm 1.9 RS.Open(CRecordset::snapshot,sql,CRecordset::forwardOnly | CRecordset::readOnly);
160 sysadm 1.8 while(!RS.IsEOF())
161 sysadm 1.3 {
162     RS.GetFieldValue("group",dbVar,SQL_C_CHAR);
163 sysadm 1.7 group = *(dbVar.m_pstring);
164 sysadm 1.3 art_begin = 1;
165     art_end = 0;;
166     RS.GetFieldValue("in",dbVar,SQL_C_SSHORT);
167     p = (dbVar.m_iVal!=0);
168     out.Format("%s %.10ld %.10ld %c",group,art_end,art_begin,(p?'y':'n'));
169     this->s_send(out);
170     RS.MoveNext();
171     }
172     RS.Close();
173 sysadm 1.1
174 sysadm 1.3 this->s_send(".");
175     }
176     catch(CException* e)
177 sysadm 1.1 {
178 sysadm 1.3 syslog << logfile::log_head << "Error in cmd_list()" << endl;
179     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.7 char strErrMsg[256];
359     e->GetErrorMessage(strErrMsg,256);
360     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 }

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