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

Diff of /innwebd/innd.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 1.1 by sysadm, Fri Jun 25 07:01:51 2004 UTC Revision 1.7 by sysadm, Sun Jul 4 08:04:08 2004 UTC
# Line 1  Line 1 
1  /*******************************************************/  /*******************************************************/
2  /*                                                     */  /*                                                     */
3  /*  LeafOK Innd                                        */  /*  LeafOK Innbbsd                                     */
4  /*  Copyright (C) LeafOK.com, 2003-2004                */  /*  Copyright (C) LeafOK.com, 2003-2004                */
5  /*                                                     */  /*                                                     */
6  /*  Programmed by Leaf                                 */  /*  Programmed by Leaf                                 */
7  /*  E-mail:leaf@leafok.com  QQ:6049044                 */  /*  E-mail:leaflet@leafok.com  QQ:6049044              */
8  /*                                                     */  /*                                                     */
9  /*  http://bbs.leafok.com                              */  /*  http://bbs.leafok.com                              */
10  /*  http://bbs.leafok.net                              */  /*  http://bbs.leafok.net                              */
# Line 12  Line 12 
12  /*                                                     */  /*                                                     */
13  /*******************************************************/  /*******************************************************/
14    
15  // innd.cpp : 定义控制台应用程序的入口点。  #include "StdAfx.h"
 //  
   
 #include "stdafx.h"  
 #include "afxsock.h"  
16  #include ".\innd.h"  #include ".\innd.h"
17  #include ".\nntp_log.h"  #include ".\base_active.h"
18  #include ".\innd_service.h"  #include ".\App_common.h"
 #include ".\bbs_fun.h"  
   
 #ifdef _DEBUG  
 #define new DEBUG_NEW  
 #endif  
19    
20    using namespace std;
21    
22  // 唯一的应用程序对象  bool innd::thread_terminate = true;
23    
24  CWinApp theApp;  innd::innd(void)
25    {
26    }
27    
28  using namespace std;  innd::~innd(void)
29    {
30    }
31    
32  int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])  int innd::Accept(void)
33  {  {
34          // 初始化 MFC 并在失败时显示错误          CString out,cmd;
35          if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))          char temp[256];
36    
37            try
38          {          {
39                  // TODO: 更改错误代码以符合您的需要                  out.Format("200 %s ready.",App_common::GetVersion());
40                  _tprintf(_T("致命错误: MFC 初始化失败\n"));                  this->s_send(out);
41                  return 1;                  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          // TODO: 在此处为应用程序的行为编写代码。          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          // System settings                  sql = "select * from innd_conf order by `group`";
         const char* log_file = _T("innd.log");  
158    
159          nntp_log::nlog.open(log_file,ios_base::out | ios_base::app);                  RS.Open(CRecordset::snapshot,sql,CRecordst::forwardOnly | CRecordset::readOnly);
160                    while(!RS.IsEEOF())
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          if(!AfxSocketInit())                  this->s_send(".");
175            }
176            catch(CException* e)
177          {          {
178                  nntp_log::nlog << "Sockets init failed" << endl;                  syslog << logfile::log_head << "Error in cmd_list()" << endl;
179                  return 3;                  e->Delete();
180                    return -1;
181          }          }
182    
183      // Create the service object          return 0;
184      innd_service innd_srv;  }
185    
186          CString conf_file;  int innd::cmd_ihave(const char* msg_id)
187          conf_file = argv[0];  {
188          conf_file = conf_file.Left(conf_file.ReverseFind('\\')) + "\\innd.conf";          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          innd_srv.nntp_ctrl.load_conf(conf_file);                  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          //Standalone mode                  while(*p1)
220          if (argc == 2 && _stricmp(argv[1], "-s") == 0)                  {
221          {                          head_find = false;
222                  innd_srv.nntp_ctrl.begin();                          head_name = "";
223                  innd_srv.nntp_ctrl.StartupChild();                          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                  while (innd_srv.nntp_ctrl.IsRunning())                  if (strcmp(cmd,"cancel")==0 && strcmp(cancel_msg_id,"")!=0) //Empty Message-ID
317                  {                  {
318                      Sleep(100);                          //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                  innd_srv.nntp_ctrl.bbsd.end();                  if (strcmp(cmd,"checkgroups")==0)
347                  innd_srv.nntp_ctrl.innd.end();                  {
348                  innd_srv.nntp_ctrl.outd.end();                          this->s_send("235 Article transferred ok");
349                  innd_srv.nntp_ctrl.end();                          syslog << logfile::log_head << "Checkgroups" << endl;
350                            return 0;
351                    }
352    
353                  return 0;                  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      // Parse for standard arguments (install, uninstall, version etc.)          return 0;
366      if (!innd_srv.ParseStandardArgs(argc, argv)) {  }
367          //DebugBreak();  
368          innd_srv.StartService();  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      // When we get here, the service has been stopped  int innd::db_env_init(void)
394      return innd_srv.m_Status.dwWin32ExitCode;  {
395            if (this->db_open(this->w_conn_str) != 0)
396            {
397                    return -1;
398            }
399            return 0;
400  }  }


Legend:
Removed lines/characters  
Changed lines/characters
  Added lines/characters

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