/[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.5 by sysadm, Sat Jul 3 13:56:04 2004 UTC
# 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            HANDLE hThreadCurrent;
37    
38            try
39          {          {
40                  // TODO: 更改错误代码以符合您的需要                  hThreadCurrent = GetCurrentThread();
41                  _tprintf(_T("致命错误: MFC 初始化失败\n"));  
42                  return 1;                  out.Format("200 %s ready.",App_common::GetVersion());
43                    this->s_send(out);
44                    while(!this->thread_terminate)
45                    {
46                            this->GetParentThread()->GetThreadPool()->SetThreadStatus(hThreadCurrent,thread_pool::S_WAITING);
47    
48                            if (this->s_receive(out) == 0)  //Connection closed
49                                    break;
50                            out.Trim();
51    
52                            this->GetParentThread()->GetThreadPool()->SetThreadStatus(hThreadCurrent,thread_pool::S_WORKING);
53    
54                            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    
125                            this->s_send("500 What?");
126                    }
127            }
128            catch(CException* e)
129            {
130                    syslog << logfile::log_head << "Error in accept()" << endl;
131                    e->Delete();
132                    return -1;
133          }          }
134    
135          // TODO: 在此处为应用程序的行为编写代码。          return 0;
136    }
137    
138          // System settings  innd* innd::new_client(void)
139          const char* log_file = _T("innd.log");  {
140            return (new innd());
141    }
142    
143          nntp_log::nlog.open(log_file,ios_base::out | ios_base::app);  bool innd::IsShutdown(void)
144    {
145            return this->thread_terminate;
146    }
147    
148          if(!AfxSocketInit())  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                  nntp_log::nlog << "Sockets init failed" << endl;              this->s_send("215 Newsgroups(group last first p)");
                 return 3;  
         }  
159    
160      // Create the service object                  sql = "select * from innd_conf order by `group`";
161      innd_service innd_srv;  
162                    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    
177          CString conf_file;                  this->s_send(".");
178          conf_file = argv[0];          }
179          conf_file = conf_file.Left(conf_file.ReverseFind('\\')) + "\\innd.conf";          catch(CException* e)
180            {
181                    syslog << logfile::log_head << "Error in cmd_list()" << endl;
182                    e->Delete();
183                    return -1;
184            }
185    
186          innd_srv.nntp_ctrl.load_conf(conf_file);          return 0;
187    }
188    
189          //Standalone mode  int innd::cmd_ihave(const char* msg_id)
190          if (argc == 2 && _stricmp(argv[1], "-s") == 0)  {
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                  innd_srv.nntp_ctrl.begin();                  this->s_send("335 OK, send article to be transferred.");
205                  innd_srv.nntp_ctrl.StartupChild();                  this->s_receive(out,".\r\n");
206    
207                    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    
222                  while (innd_srv.nntp_ctrl.IsRunning())                  while(*p1)
223                  {                  {
224                      Sleep(100);                          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    
269                  innd_srv.nntp_ctrl.bbsd.end();                  RS.Open(CRecordset::snapshot,sql,CRecordset::forwardOnly | CRecordset::readOnly);
270                  innd_srv.nntp_ctrl.innd.end();                  while(!RS.IsEOF())
271                  innd_srv.nntp_ctrl.outd.end();                  {
272                  innd_srv.nntp_ctrl.end();                          RS.GetFieldValue("SID",dbVar,SQL_C_SSHORT);
273                            sid[sid_count++] = dbVar.m_iVal;
274                            RS.MoveNext();
275                    }
276                    RS.Close();
277    
278                  return 0;                  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    
319                    if (strcmp(cmd,"cancel")==0 && strcmp(cancel_msg_id,"")!=0) //Empty Message-ID
320                    {
321                            //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    
349                    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    
356                    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          }          }
365    
366      // Parse for standard arguments (install, uninstall, version etc.)          return 0;
367      if (!innd_srv.ParseStandardArgs(argc, argv)) {  }
368          //DebugBreak();  
369          innd_srv.StartService();  int innd::Shutdown(void)
370      }  {
371            base_active nntpClient;
372    
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      // When we get here, the service has been stopped  int innd::db_env_init(void)
395      return innd_srv.m_Status.dwWin32ExitCode;  {
396            if (this->db_open(this->w_conn_str) != 0)
397            {
398                    return -1;
399            }
400            return 0;
401  }  }


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

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