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

Contents of /innwebd/base_passive.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (show annotations)
Sat Jul 3 05:22:23 2004 UTC (21 years, 8 months ago) by sysadm
Branch: MAIN
Content type: text/x-c++src
nntp_passive.cpp

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 if (base_passive::uThreadCount < MAX_THREAD)
161 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