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

Annotation of /innwebd/base_passive.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.8 - (hide annotations)
Thu Sep 16 15:40:37 2004 UTC (21 years, 6 months ago) by sysadm
Branch: MAIN
Changes since 1.7: +10 -3 lines
Content type: text/x-c++src
Add check_priv()

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

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