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

Annotation of /innwebd/base_passive.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.2 - (hide annotations)
Sat Jul 3 08:47:07 2004 UTC (21 years, 8 months ago) by sysadm
Branch: MAIN
Changes since 1.1: +1 -1 lines
Content type: text/x-c++src
Rename MAX_THREAD to MAX_CLIENT

1 sysadm 1.1 /*******************************************************/
2     /* */
3     /* LeafOK Innd */
4     /* Copyright (C) LeafOK.com, 2003-2004 */
5     /* */
6     /* Programmed by Leaf */
7     /* E-mail:leaf@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 ".\base_passive.h"
17     #include ".\base_active.h"
18    
19     using namespace std;
20    
21     UINT base_passive::uThreadCount = 0;
22    
23     base_passive::base_passive(void)
24     : p_ParentThread(NULL)
25     {
26     }
27    
28     base_passive::~base_passive(void)
29     {
30     this->s_close();
31     this->db_close();
32     }
33    
34     int base_passive::s_connect(const char* hostaddr, unsigned int port)
35     {
36     SOCKADDR_IN sin;
37    
38     if (this->isConnected)
39     {
40     this->s_close();
41     }
42    
43     //Create a TCP/IP socket
44     if ((this->s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
45     {
46     syslog << logfile::log_head << "Cannot create socket" << endl;
47     return -1;
48     }
49    
50     //fill in sockaddr_in struct
51    
52     sin.sin_family = PF_INET;
53     sin.sin_port = htons(port);
54     sin.sin_addr.s_addr = (strlen(hostaddr) > 0 ? inet_addr(hostaddr) : INADDR_ANY);
55    
56     //bind the socket
57     if(bind(this->s, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR)
58     {
59     syslog << logfile::log_head << "Cannot bind" << endl;
60     return -1;
61     }
62    
63     if(listen(this->s,5) == SOCKET_ERROR)
64     {
65     syslog << logfile::log_head << "Cannot listen" << endl;
66     return -1;
67     }
68    
69     strcpy(this->hostaddr,hostaddr);
70     this->port = port;
71    
72     this->isConnected = true;
73    
74     return 0;
75     }
76    
77     int base_passive::s_close(void)
78     {
79     if (!this->isConnected)
80     return 0;
81    
82     if (closesocket(this->s) == SOCKET_ERROR)
83     {
84     syslog << logfile::log_head << "Close socket error" << endl;
85     }
86    
87     this->isConnected = false;
88    
89     return 0;
90     }
91    
92     int base_passive::work()
93     {
94     HANDLE hThreadCurrent;
95     ULONG ulThreadId;
96     base_passive* p;
97     SOCKADDR_IN sin;
98     int namelen;
99    
100     if (this->running)
101     return 1;
102    
103     if (this->load_priv() != 0)
104     return -1;
105    
106     if (this->s_connect(this->w_address,this->w_port) == 0)
107     {
108     this->Startup();
109    
110     syslog << logfile::log_head << "Listen at port [" << this->w_port << "]" << endl;
111    
112     while(!this->IsShutdown())
113     {
114     if ((p = this->new_client()) == NULL)
115     {
116     syslog << logfile::log_head << "Assign new client failed" << endl;
117     continue;
118     }
119    
120     p->p_ParentThread = this;
121     p->configure(this->innd_id,this->innd_name,this->innd_server,this->innd_uid,this->w_address,this->w_port,this->w_conn_str);
122    
123     this->running = true;
124    
125     namelen = sizeof(sin);
126     if ((p->s = accept(this->s,(LPSOCKADDR)&sin,&namelen)) == INVALID_SOCKET)
127     {
128     syslog << logfile::log_head << "Socket accept failed (" << GetLastError() <<")" << endl;
129     this->unload_priv();
130     this->Shutdown();
131     this->running = false;
132     return -2;
133     }
134    
135     if (this->IsShutdown())
136     {
137     break;
138     }
139    
140    
141     strcpy(p->hostaddr,inet_ntoa(sin.sin_addr));
142     p->port = sin.sin_port;
143     p->isConnected = true;
144    
145     // strcpy(p->w_conn_str,this->w_conn_str);
146     if (this->>get_priv(p)!=0)
147     if (this->get_priv(p)!=0)
148     {
149     p->s_send("502 Load access file failed.\r\n");
150     delete(p);
151     continue;
152     }
153    
154     if (!p->access.get)
155     {
156     p->s_send("502 You are not in my access file.\r\n");
157     delete(p);
158     continue;
159     }
160 sysadm 1.2 if (base_passive::uThreadCount < MAX_CLIENT)
161 sysadm 1.1 if (this->GetThreadPool()->GetThreadCount() < MAX_CLIENT)
162     {
163     if (hThreadCurrent = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)base_passive::AcceptThread,(LPVOID)p,0,&ulThreadId))
164     base_passive::uThreadCount++;
165     CloseHandle(hThreadCurrent);
166     syslog << logfile::log_head << "Create accept thread ... OK" << endl;
167     }
168     else
169     {
170     delete(p);
171     syslog << logfile::log_head << "Create accept thread ... Failed" << endl;
172     }
173     }
174     else
175     {
176     p->s_send("502 Too many connections\r\n");
177     delete(p);
178     }
179     }
180     delete(p);
181     Sleep(1000*5); // Wait several seconds for all threads to exit
182     }
183     this->s_close();
184    
185     this->unload_priv();
186    
187     this->running = false;
188    
189     return 0;
190     }
191    
192     DWORD base_passive::AcceptThread(LPVOID pParam)
193     {
194     base_passive* p;
195    
196     try
197     {
198    
199     if (p->db_env_init() == 0)
200     {
201     p->Accept();
202     }
203     else
204     {
205     syslog << logfile::log_head << "DB_ENV_INIT failed" << endl;
206    
207     base_passive::uThreadCount--;
208     delete(p);
209     syslog << logfile::log_head << "Delete accept thread ... OK" << endl;
210     }
211     catch(CException* e)
212     {
213     syslog << logfile::log_head << "Error in AcceptThread()" << endl;
214     e->Delete();
215     return -1;
216     }
217    
218     return 0;
219     }
220    
221     int base_passive::get_priv(base_passive* p)
222     {
223     try
224     {
225     //Default value
226     strcpy(p->access.ip,p->hostaddr);
227     p->access.control = false;
228     p->access.get = true;
229     p->access.post = false;
230     p->access.ihave = false;
231    
232     //Check access list
233     for (int i=1; i<this->access_array.GetCount(); i++)
234     {
235     if (strcmp(this->access_array[i]->ip,p->hostaddr) == 0)
236     {
237     p->access = *(this->access_array[i]);
238     break;
239     }
240     }
241     }
242     catch(CException* e)
243     {
244     syslog << logfile::log_head << "Error in get_priv()" << endl;
245     e->Delete();
246     return -1;
247     }
248    
249     return 0;
250     }
251    
252     int base_passive::load_priv(void)
253     {
254     CRecordset RS;
255     CString sql;
256     CDBVariant dbVar;
257     Access_STRUCT* p_access;
258    
259     try
260     {
261     if (this->db_open(this->w_conn_str) == 0)
262     {
263     RS.m_pDatabase = &(this->Db);
264     }
265     else
266     return -2;
267    
268     //Check access list
269     sql = "select * from innd_access where enable order by ip";
270     RS.Open(CRecordset::snapshot,sql,CRecordset::readOnly);
271     this->access_array.SetSize(RS.GetRecordCount());
272     while(!RS.IsEOF())
273     {
274     p_access = new Access_STRUCT();
275    
276     RS.GetFieldValue("ip",dbVar,SQL_C_CHAR);
277     strcpy(p_access->ip,*(dbVar.m_pstring));
278     RS.GetFieldValue("control",dbVar,SQL_C_SSHORT);
279     p_access->control = (dbVar.m_iVal!=0);
280     RS.GetFieldValue("get",dbVar,SQL_C_SSHORT);
281     p_access->get = (dbVar.m_iVal!=0);
282     RS.GetFieldValue("post",dbVar,SQL_C_SSHORT);
283     p_access->post = (dbVar.m_iVal!=0);
284     RS.GetFieldValue("ihave",dbVar,SQL_C_SSHORT);
285     p_access->ihave = (dbVar.m_iVal!=0);
286    
287     this->access_array.Add(p_access);
288     RS.MoveNext();
289     }
290     RS.Close();
291    
292     this->db_close();
293     }
294     catch(CException* e)
295     {
296     syslog << logfile::log_head << "Error in load_priv()" << endl;
297     e->Delete();
298     return -1;
299     }
300    
301     return 0;
302     }
303    
304     int base_passive::unload_priv(void)
305     {
306     Access_STRUCT* p_access;
307    
308     try
309     {
310     for (int i=1; i<this->access_array.GetCount();i++)
311     {
312     p_access = this->access_array[i];
313     delete (p_access);
314     }
315     this->access_array.RemoveAll();
316     }
317     catch(CException* e)
318     {
319     syslog << logfile::log_head << "Error in unload_priv()" << endl;
320     e->Delete();
321     return -1;
322     }
323    
324     return 0;
325     }
326    
327     int base_passive::w_call(void)
328     {
329     this->work();
330     return 0;
331     }

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