/[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.1.1 by sysadm, Fri Jun 25 07:01:51 2004 UTC Revision 1.13 by sysadm, Fri Apr 11 17:14:49 2008 UTC
# Line 1  Line 1 
1  /*******************************************************/  /*******************************************************/
2  /*                                                     */  /*                                                     */
3  /*  LeafOK Innd                                        */  /*  LeafOK Innbbsd                                     */
 /*  Copyright (C) LeafOK.com, 2003-2004                */  
4  /*                                                     */  /*                                                     */
5  /*  Programmed by Leaf                                 */  /*  Copyright (C) LeafOK.com, 2003-2008                */
 /*  E-mail:leaf@leafok.com  QQ:6049044                 */  
6  /*                                                     */  /*                                                     */
7  /*  http://bbs.leafok.com                              */  /*  http://www.leafok.com                              */
 /*  http://bbs.leafok.net                              */  
 /*  http://bbs.fenglin.info                            */  
8  /*                                                     */  /*                                                     */
9  /*******************************************************/  /*******************************************************/
10    
11  // innd.cpp : 定义控制台应用程序的入口点。  #include "StdAfx.h"
 //  
   
 #include "stdafx.h"  
 #include "afxsock.h"  
12  #include ".\innd.h"  #include ".\innd.h"
13  #include ".\nntp_log.h"  #include ".\base_active.h"
14  #include ".\innd_service.h"  #include ".\App_common.h"
 #include ".\bbs_fun.h"  
   
 #ifdef _DEBUG  
 #define new DEBUG_NEW  
 #endif  
15    
16    using namespace std;
17    
18  // 唯一的应用程序对象  bool innd::thread_terminate = true;
19    
20  CWinApp theApp;  innd::innd(void)
21    {
22    }
23    
24  using namespace std;  innd::~innd(void)
25    {
26    }
27    
28  int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])  int innd::Accept(void)
29  {  {
30          // 初始化 MFC 并在失败时显示错误          CString out,cmd;
31          if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))          char temp[256];
32    
33            try
34          {          {
35                  // TODO: 更改错误代码以符合您的需要                  out.Format("200 %s ready.",App_common::GetVersion());
36                  _tprintf(_T("致命错误: MFC 初始化失败\n"));                  this->s_send(out);
37                  return 1;                  while(!this->thread_terminate)
38                    {
39                            this->GetParentThread()->GetThreadPool()->SetThreadStatus(GetCurrentThreadId(),thread_pool::S_WAITING);
40    
41                            if (this->s_receive(out) == 0)  //Connection closed
42                                    break;
43                            out.Trim();
44    
45                            this->GetParentThread()->GetThreadPool()->SetThreadStatus(GetCurrentThreadId(),thread_pool::S_WORKING);
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                    char strErrMsg[1024];
124                    e->GetErrorMessage(strErrMsg,1024);
125                    syslog << logfile::log_head << "Error in accept() [" << strErrMsg << "]" << endl;
126                    e->Delete();
127                    return -1;
128            }
129    
130            return 0;
131    }
132    
133          // TODO: 在此处为应用程序的行为编写代码。  innd* innd::new_client(void)
134    {
135            return (new innd());
136    }
137    
138          // System settings  bool innd::IsShutdown(void)
139          const char* log_file = _T("innd.log");  {
140            return this->thread_terminate;
141    }
142    
143          nntp_log::nlog.open(log_file,ios_base::out | ios_base::app);  int innd::cmd_list(void)
144    {
145            CRecordset RS(&(this->Db));
146            CDBVariant dbVar;
147            CString sql,group,out;
148            long art_begin,art_end;
149            bool p;
150            
151            try
152            {
153                this->s_send("215 Newsgroups(group last first p)");
154    
155                    sql = "select * from innd_conf order by `group`";
156    
157                    RS.Open(CRecordset::snapshot,sql,CRecordset::forwardOnly | CRecordset::readOnly);
158                    while(!RS.IsEOF())
159                    {
160                            RS.GetFieldValue("group",dbVar,SQL_C_CHAR);
161                            group = *(dbVar.m_pstring);
162                            art_begin = 1;
163                            art_end = 0;;
164                            RS.GetFieldValue("in",dbVar,SQL_C_SSHORT);
165                            p = (dbVar.m_iVal!=0);
166                            out.Format("%s %.10ld %.10ld %c",group,art_end,art_begin,(p?'y':'n'));
167                            this->s_send(out);
168                            RS.MoveNext();
169                    }
170                    RS.Close();
171    
172          if(!AfxSocketInit())                  this->s_send(".");
173            }
174            catch(CException* e)
175          {          {
176                  nntp_log::nlog << "Sockets init failed" << endl;                  char strErrMsg[1024];
177                  return 3;                  e->GetErrorMessage(strErrMsg,1024);
178                    syslog << logfile::log_head << "Error in cmd_list() [" << strErrMsg << "]" << endl;
179                    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                  while (innd_srv.nntp_ctrl.IsRunning())                  RS.Open(CRecordset::snapshot,sql,CRecordset::forwardOnly | CRecordset::readOnly);
267                    while(!RS.IsEOF())
268                  {                  {
269                      Sleep(100);                          RS.GetFieldValue("SID",dbVar,SQL_C_SSHORT);
270              }                          sid[sid_count++] = dbVar.m_iVal;
271                            RS.MoveNext();
272                    }
273                    RS.Close();
274    
275                  innd_srv.nntp_ctrl.bbsd.end();                  if (sid_count == 0)
276                  innd_srv.nntp_ctrl.innd.end();                  {
277                  innd_srv.nntp_ctrl.outd.end();                          this->s_send("437 Not in a allowed newsgroup");
278                  innd_srv.nntp_ctrl.end();                          syslog << logfile::log_head << "Not in a allowed newsgroup" << endl;
279                            return 2;
280                    }
281    
282                  return 0;                  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[1024];
359                    e->GetErrorMessage(strErrMsg,1024);
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      // When we get here, the service has been stopped          if (this->thread_terminate)
373      return innd_srv.m_Status.dwWin32ExitCode;                  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    }
401    
402    bool innd::check_priv(void)
403    {
404            return this->access.get;
405  }  }


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

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