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

Annotation of /innwebd/innd.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.4 - (hide annotations)
Sat Jul 3 05:30:04 2004 UTC (21 years, 8 months ago) by sysadm
Branch: MAIN
Changes since 1.3: +2 -2 lines
Content type: text/x-c++src
Rename to class nntp_active to base_active
Rename to class nntp_passive to base_passive

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

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