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

Contents of /innwebd/innd.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.8 - (show annotations)
Sun Jul 4 21:54:39 2004 UTC (21 years, 8 months ago) by sysadm
Branch: MAIN
Changes since 1.7: +2 -2 lines
Content type: text/x-c++src
no message

1 /*******************************************************/
2 /* */
3 /* LeafOK Innbbsd */
4 /* Copyright (C) LeafOK.com, 2003-2004 */
5 /* */
6 /* Programmed by Leaf */
7 /* E-mail:leaflet@leafok.com QQ:6049044 */
8 /* */
9 /* http://bbs.leafok.com */
10 /* http://bbs.leafok.net */
11 /* http://bbs.fenglin.info */
12 /* */
13 /*******************************************************/
14
15 #include "StdAfx.h"
16 #include ".\innd.h"
17 #include ".\base_active.h"
18 #include ".\App_common.h"
19
20 using namespace std;
21
22 bool innd::thread_terminate = true;
23
24 innd::innd(void)
25 {
26 }
27
28 innd::~innd(void)
29 {
30 }
31
32 int innd::Accept(void)
33 {
34 CString out,cmd;
35 char temp[256];
36
37 try
38 {
39 out.Format("200 %s ready.",App_common::GetVersion());
40 this->s_send(out);
41 while(!this->thread_terminate)
42 {
43 this->GetParentThread()->GetThreadPool()->SetThreadStatus(GetCurrentThreadId(),thread_pool::S_WAITING);
44
45 if (this->s_receive(out) == 0) //Connection closed
46 break;
47 out.Trim();
48
49 this->GetParentThread()->GetThreadPool()->SetThreadStatus(GetCurrentThreadId(),thread_pool::S_WORKING);
50
51 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
122 this->s_send("500 What?");
123 }
124 }
125 catch(CException* e)
126 {
127 syslog << logfile::log_head << "Error in accept()" << endl;
128 e->Delete();
129 return -1;
130 }
131
132 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
157 sql = "select * from innd_conf order by `group`";
158
159 RS.Open(CRecordset::snapshot,sql,CRecordset:forwardOnly | CRecordsset::readOnly);
160 while(!RS.IsEOF())
161 {
162 RS.GetFieldValue("group",dbVar,SQL_C_CHAR);
163 group = *(dbVar.m_pstring);
164 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
174 this->s_send(".");
175 }
176 catch(CException* e)
177 {
178 syslog << logfile::log_head << "Error in cmd_list()" << 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[256];
359 e->GetErrorMessage(strErrMsg,256);
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 }

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