/[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.2 by sysadm, Wed Jun 30 12:53:36 2004 UTC Revision 1.3 by sysadm, Fri Jul 2 11:32:20 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 ".\innd_service.h"  #include ".\nntp_active.h"
18  #include ".\bbs_fun.h"  #include ".\App_common.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                            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    
118                            this->s_send("500 What?");
119                    }
120            }
121            catch(CException* e)
122            {
123                    syslog << logfile::log_head << "Error in accept()" << endl;
124                    e->Delete();
125                    return -1;
126          }          }
127    
128          // TODO: 在此处为应用程序的行为编写代码。          return 0;
129    }
130    
131          // System settings  innd* innd::new_client(void)
132          const char* log_file = _T("innd.log");  {
133            return (new innd());
134    }
135    
136          nlog.open(log_file,ios_base::out | ios_base::app);  bool innd::IsShutdown(void)
137    {
138            return this->thread_terminate;
139    }
140    
141          if(!AfxSocketInit())  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                  nlog << nntp_log::log_head << "Sockets init failed" << endl;              this->s_send("215 Newsgroups(group last first p)");
152                  return 3;  
153          }                  sql = "select * from innd_conf order by `group`";
154    
155      // Create the service object                  RS.Open(CRecordset::snapshot,sql,CRecordst::forwardOnly | CRecordset::readOnly);
156      innd_service innd_srv;                  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    
170          CString conf_file;                  this->s_send(".");
171          conf_file = argv[0];          }
172          conf_file = conf_file.Left(conf_file.ReverseFind('\\')) + "\\innd.conf";          catch(CException* e)
173            {
174                    syslog << logfile::log_head << "Error in cmd_list()" << endl;
175                    e->Delete();
176                    return -1;
177            }
178    
179          innd_srv.nntp_ctrl.load_conf(conf_file);          return 0;
180    }
181    
182          //Standalone mode  int innd::cmd_ihave(const char* msg_id)
183          if (argc == 2 && _stricmp(argv[1], "-s") == 0)  {
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                  innd_srv.nntp_ctrl.begin();                  this->s_send("335 OK, send article to be transferred.");
198                  innd_srv.nntp_ctrl.StartupChild();                  this->s_receive(out,".\r\n");
199    
200                  while (innd_srv.nntp_ctrl.IsRunning())                  if (out.Right(5) != "\r\n.\r\n")
201                  {                  {
202                      Sleep(100);                          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    
215                  innd_srv.nntp_ctrl.bbsd.end();                  while(*p1)
216                  innd_srv.nntp_ctrl.innd.end();                  {
217                  innd_srv.nntp_ctrl.outd.end();                          head_find = false;
218                  innd_srv.nntp_ctrl.end();                          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    
262                    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                  return 0;                  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    
312                    if (strcmp(cmd,"cancel")==0 && strcmp(cancel_msg_id,"")!=0) //Empty Message-ID
313                    {
314                            //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    
342                    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    
349                    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          }          }
358    
359      // Parse for standard arguments (install, uninstall, version etc.)          return 0;
360      if (!innd_srv.ParseStandardArgs(argc, argv)) {  }
         //DebugBreak();  
         innd_srv.StartService();  
     }  
361    
362      // When we get here, the service has been stopped  int innd::Shutdown(void)
363      return innd_srv.m_Status.dwWin32ExitCode;  {
364            nntp_active nntpClient;
365    
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  }  }


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

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