/[svn]/ircd-hybrid-7.2/src/s_bsd_win32.c
ViewVC logotype

Contents of /ircd-hybrid-7.2/src/s_bsd_win32.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 908 - (show annotations)
Sun Nov 4 23:21:51 2007 UTC (13 years, 5 months ago) by stu
File MIME type: text/x-chdr
File size: 12798 byte(s)
Completely redo the build system.  Now uses libtool and automake.  Suggest you clean out your tree and then do ./autogen.sh.
1 /*
2 * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 * s_bsd_win32.c: Winsock WSAAsyncSelect() compatible network routines.
4 *
5 * Copyright (C) 2002 by the past and present ircd coders, and others.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20 * USA
21 *
22 * $Id$
23 */
24
25 #ifdef WIN32
26
27 #include "stdinc.h"
28 #include <iphlpapi.h>
29 #include "fdlist.h"
30 #include "ircd.h"
31 #include "s_bsd.h"
32 #include "common.h"
33 #include "client.h"
34 #include "numeric.h"
35 #include "restart.h"
36
37 #define WM_SOCKET (WM_USER + 0)
38 #define WM_DNS (WM_USER + 1)
39 #define WM_REHASH (WM_USER + 0x100)
40 #define WM_REMOTD (WM_USER + 0x101)
41
42 static HWND wndhandle;
43 static dlink_list dns_queries = {NULL, NULL, 0};
44 static dlink_node *setupfd_hook;
45 static DWORD (WINAPI * _GetNetworkParams) (PFIXED_INFO, PULONG) = NULL;
46
47 extern int main(int, char *[]);
48
49 /*
50 * Initial entry point for Win32 GUI applications, called by the C runtime.
51 *
52 * It should be only a wrapper for main(), since when compiled as a console
53 * application, main() is called instead.
54 */
55 int WINAPI
56 WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
57 LPSTR lpCmdLine, int nCmdShow)
58 {
59 /* Do we really need these pidfile, logfile etc arguments?
60 * And we are not on a console, so -help or -foreground is meaningless. */
61
62 char *argv[2] = {"ircd", NULL};
63
64 return main(1, argv);
65 }
66
67 /*
68 * Handler for Win32 messages.
69 */
70 static LRESULT CALLBACK
71 hybrid_wndproc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
72 {
73 switch (uMsg)
74 {
75 case WM_SOCKET:
76 {
77 fde_t *F = lookup_fd((int) wParam);
78 PF *hdl;
79
80 if (F != NULL && F->flags.open)
81 switch (WSAGETSELECTEVENT(lParam))
82 {
83 case FD_ACCEPT:
84 case FD_CLOSE:
85 case FD_READ:
86 if ((hdl = F->read_handler) != NULL)
87 {
88 F->read_handler = NULL;
89 hdl(F, F->read_data);
90 if (F->flags.open)
91 comm_setselect(F, 0, NULL, NULL, 0);
92 }
93 break;
94
95 case FD_CONNECT:
96 case FD_WRITE:
97 if ((hdl = F->write_handler) != NULL)
98 {
99 F->write_handler = NULL;
100 hdl(F, F->write_data);
101 if (F->flags.open)
102 comm_setselect(F, 0, NULL, NULL, 0);
103 }
104 }
105
106 return 0;
107 }
108
109 case WM_DNS:
110 {
111 dlink_node *ptr;
112
113 DLINK_FOREACH(ptr, dns_queries.head)
114 if (((struct DNSQuery *) ptr->data)->handle == wParam)
115 {
116 struct DNSQuery *query = ptr->data;
117 struct DNSReply *reply = NULL;
118
119 dlinkDelete(&query->node, &dns_queries);
120
121 if (WSAGETASYNCERROR(lParam) == 0)
122 {
123 struct hostent *h = (struct hostent *) &query->reply;
124 static struct DNSReply _reply;
125 reply = &_reply;
126
127 reply->h_name = h->h_name;
128 reply->addr.ss.ss_family = h->h_addrtype;
129
130 switch (h->h_addrtype)
131 {
132 case AF_INET:
133 memcpy(&((struct sockaddr_in *) &reply->addr)->sin_addr,
134 h->h_addr_list[0], h->h_length);
135 break;
136
137 #ifdef IPV6
138 case AF_INET6:
139 memcpy(&((struct sockaddr_in6 *) &reply->addr)->sin6_addr,
140 h->h_addr_list[0], h->h_length);
141 break;
142 #endif
143
144 default: /* shouldn't happen */
145 reply = NULL;
146 }
147 }
148
149 query->callback(query->ptr, reply);
150 return 0;
151 }
152
153 return 0;
154 }
155
156 case WM_REHASH:
157 dorehash = 1;
158 return 0;
159
160 case WM_REMOTD:
161 doremotd = 1;
162 return 0;
163
164 case WM_DESTROY:
165 PostQuitMessage(0);
166 return 0;
167
168 default:
169 return DefWindowProc(hwnd, uMsg, wParam, lParam);
170 }
171 }
172
173 /*
174 * Associates a window message with the given socket.
175 * This will automagically switch it to nonblocking.
176 */
177 static void *
178 setup_winsock_fd(va_list args)
179 {
180 int fd = va_arg(args, int);
181
182 WSAAsyncSelect(fd, wndhandle, WM_SOCKET, 0);
183
184 return pass_callback(setupfd_hook, fd);
185 }
186
187 /*
188 * Initialize Winsock, create a window handle.
189 */
190 void
191 init_netio(void)
192 {
193 WNDCLASS wndclass;
194 WSADATA wsa;
195 HMODULE lib;
196
197 /* Initialize Winsock networking */
198 if (WSAStartup(0x101, &wsa) != 0)
199 {
200 MessageBox(NULL, "Cannot initialize Winsock -- terminating ircd",
201 NULL, MB_OK | MB_ICONERROR);
202 exit(1);
203 }
204
205 /* First, we need a class for our window that has message handler
206 * set to hybrid_wndproc() */
207 memset(&wndclass, 0, sizeof(wndclass));
208
209 wndclass.lpfnWndProc = hybrid_wndproc;
210 wndclass.hInstance = GetModuleHandle(NULL);
211 wndclass.lpszClassName = PACKAGE_NAME;
212
213 RegisterClass(&wndclass);
214
215 /* Now, initialize the window */
216 wndhandle = CreateWindow(PACKAGE_NAME, NULL, 0,
217 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
218 NULL, NULL, wndclass.hInstance, NULL);
219
220 if (!wndhandle)
221 {
222 MessageBox(NULL, "Cannot allocate window handle -- terminating ircd",
223 NULL, MB_OK | MB_ICONERROR);
224 exit(1);
225 }
226
227 /* Set up a timer which will periodically post a message to our queue.
228 * This way, ircd won't wait infinitely for a network event */
229 SetTimer(wndhandle, 0, SELECT_DELAY, NULL);
230
231 if ((lib = LoadLibrary("IPHLPAPI.DLL")) != NULL)
232 _GetNetworkParams = GetProcAddress(lib, "GetNetworkParams");
233
234 setupfd_hook = install_hook(setup_socket_cb, setup_winsock_fd);
235 }
236
237 /*
238 * comm_setselect
239 *
240 * This is a needed exported function which will be called to register
241 * and deregister interest in a pending IO state for a given FD.
242 */
243 void
244 comm_setselect(fde_t *F, unsigned int type, PF *handler,
245 void *client_data, time_t timeout)
246 {
247 int new_events = 0;
248
249 if ((type & COMM_SELECT_READ))
250 {
251 F->read_handler = handler;
252 F->read_data = client_data;
253 }
254
255 if ((type & COMM_SELECT_WRITE))
256 {
257 F->write_handler = handler;
258 F->write_data = client_data;
259 }
260
261 new_events = (F->read_handler ? (FD_ACCEPT | FD_CLOSE | FD_READ) : 0) |
262 (F->write_handler ? (FD_CONNECT | FD_WRITE) : 0);
263
264 if (timeout != 0)
265 F->timeout = CurrentTime + (timeout / 1000);
266
267 if (new_events != F->evcache)
268 {
269 WSAAsyncSelect(F->fd, wndhandle, WM_SOCKET, new_events);
270 F->evcache = new_events;
271 }
272 }
273
274 /*
275 * Waits until a message is posted in our window queue and deals with it.
276 */
277 void
278 comm_select(void)
279 {
280 MSG msg;
281
282 if (!GetMessage(&msg, NULL, 0, 0))
283 server_die("WM_QUIT received", NO);
284
285 set_time();
286
287 DispatchMessage(&msg);
288 }
289
290 /* This is our win32 super-light resolver ;) */
291
292 void
293 delete_resolver_queries(const struct DNSQuery *query)
294 {
295 WSACancelAsyncRequest(query->handle);
296 dlinkDelete(&query->node, &dns_queries);
297 }
298
299 void
300 gethost_byname_type(const char *name, struct DNSQuery *query, int type)
301 {
302 gethost_byname(name, query);
303 }
304
305 void
306 gethost_byname(const char *name, struct DNSQuery *query)
307 {
308 query->handle = WSAAsyncGetHostByName(wndhandle, WM_DNS, name, query->reply,
309 sizeof(query->reply));
310
311 if (!query->handle)
312 query->callback(query->ptr, NULL);
313 else
314 dlinkAdd(query, &query->node, &dns_queries);
315 }
316
317 void
318 gethost_byaddr(const struct irc_ssaddr *addr, struct DNSQuery *query)
319 {
320 query->handle = WSAAsyncGetHostByAddr(
321 wndhandle, WM_DNS,
322 #ifdef IPV6
323 addr.ss.ss_family == AF_INET6 ? &((struct sockaddr_in6*)addr)->sin6_addr) :
324 #endif
325 &((struct sockaddr_in *) addr)->sin_addr,
326 #ifdef IPV6
327 addr.ss.ss_family == AF_INET6 ? sizeof(struct in6_addr) :
328 #endif
329 sizeof(struct in_addr),
330 addr->ss.ss_family, query->reply, sizeof(query->reply)
331 );
332
333 if (!query->handle)
334 query->callback(query->ptr, NULL);
335 else
336 dlinkAdd(query, &query->node, &dns_queries);
337 }
338
339 void
340 report_dns_servers(struct Client *source_p)
341 {
342 FIXED_INFO *FixedInfo;
343 ULONG ulOutBufLen;
344 IP_ADDR_STRING *ip;
345
346 if (_GetNetworkParams == NULL)
347 return;
348
349 FixedInfo = MyMalloc(sizeof(FIXED_INFO));
350 ulOutBufLen = sizeof(FIXED_INFO);
351
352 if (_GetNetworkParams(FixedInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW)
353 {
354 MyFree(FixedInfo);
355 FixedInfo = MyMalloc(ulOutBufLen);
356
357 if (_GetNetworkParams(FixedInfo, &ulOutBufLen) != ERROR_SUCCESS)
358 return;
359 }
360
361 for (ip = &FixedInfo->DnsServerList; ip != NULL; ip = ip->Next)
362 sendto_one(source_p, form_str(RPL_STATSALINE), me.name, source_p->name,
363 ip->IpAddress.String);
364
365 MyFree(FixedInfo);
366 }
367
368 /* Copyright (C) 2001 Free Software Foundation, Inc.
369 *
370 * Get name and information about current kernel.
371 */
372 int
373 uname(struct utsname *uts)
374 {
375 enum { WinNT, Win95, Win98, WinUnknown };
376 OSVERSIONINFO osver;
377 SYSTEM_INFO sysinfo;
378 DWORD sLength;
379 DWORD os = WinUnknown;
380
381 memset(uts, 0, sizeof(*uts));
382
383 osver.dwOSVersionInfoSize = sizeof (osver);
384 GetVersionEx (&osver);
385 GetSystemInfo (&sysinfo);
386
387 switch (osver.dwPlatformId)
388 {
389 case VER_PLATFORM_WIN32_NT: /* NT, Windows 2000 or Windows XP */
390 if (osver.dwMajorVersion == 4)
391 strcpy (uts->sysname, "Windows NT4x"); /* NT4x */
392 else if (osver.dwMajorVersion <= 3)
393 strcpy (uts->sysname, "Windows NT3x"); /* NT3x */
394 else if (osver.dwMajorVersion == 5 && osver.dwMinorVersion < 1)
395 strcpy (uts->sysname, "Windows 2000"); /* 2k */
396 else if (osver.dwMajorVersion == 5 && osver.dwMinorVersion == 2)
397 strcpy (uts->sysname, "Windows 2003"); /* 2003 */
398 else if (osver.dwMajorVersion == 5 && osver.dwMinorVersion == 1)
399 strcpy (uts->sysname, "Windows XP"); /* XP */
400 os = WinNT;
401 break;
402
403 case VER_PLATFORM_WIN32_WINDOWS: /* Win95, Win98 or WinME */
404 if ((osver.dwMajorVersion > 4) ||
405 ((osver.dwMajorVersion == 4) && (osver.dwMinorVersion > 0)))
406 {
407 if (osver.dwMinorVersion >= 90)
408 strcpy (uts->sysname, "Windows ME"); /* ME */
409 else
410 strcpy (uts->sysname, "Windows 98"); /* 98 */
411 os = Win98;
412 }
413 else
414 {
415 strcpy (uts->sysname, "Windows 95"); /* 95 */
416 os = Win95;
417 }
418 break;
419
420 case VER_PLATFORM_WIN32s: /* Windows 3.x */
421 strcpy (uts->sysname, "Windows");
422 break;
423 }
424
425 sprintf (uts->version, "%ld.%02ld",
426 osver.dwMajorVersion, osver.dwMinorVersion);
427
428 if (osver.szCSDVersion[0] != '\0' &&
429 (strlen (osver.szCSDVersion) + strlen (uts->version) + 1) <
430 sizeof (uts->version))
431 {
432 strcat (uts->version, " ");
433 strcat (uts->version, osver.szCSDVersion);
434 }
435
436 sprintf (uts->release, "build %ld", osver.dwBuildNumber & 0xFFFF);
437
438 switch (sysinfo.wProcessorArchitecture)
439 {
440 case PROCESSOR_ARCHITECTURE_PPC:
441 strcpy (uts->machine, "ppc");
442 break;
443 case PROCESSOR_ARCHITECTURE_ALPHA:
444 strcpy (uts->machine, "alpha");
445 break;
446 case PROCESSOR_ARCHITECTURE_MIPS:
447 strcpy (uts->machine, "mips");
448 break;
449 case PROCESSOR_ARCHITECTURE_INTEL:
450 /*
451 * dwProcessorType is only valid in Win95 and Win98 and WinME
452 * wProcessorLevel is only valid in WinNT
453 */
454 switch (os)
455 {
456 case Win95:
457 case Win98:
458 switch (sysinfo.dwProcessorType)
459 {
460 case PROCESSOR_INTEL_386:
461 case PROCESSOR_INTEL_486:
462 case PROCESSOR_INTEL_PENTIUM:
463 sprintf (uts->machine, "i%ld", sysinfo.dwProcessorType);
464 break;
465 default:
466 strcpy (uts->machine, "i386");
467 break;
468 }
469 break;
470 case WinNT:
471 switch(sysinfo.wProcessorArchitecture)
472 {
473 case PROCESSOR_ARCHITECTURE_INTEL:
474 sprintf (uts->machine, "x86(%d)", sysinfo.wProcessorLevel);
475 break;
476 case PROCESSOR_ARCHITECTURE_IA64:
477 sprintf (uts->machine, "ia64(%d)", sysinfo.wProcessorLevel);
478 break;
479 #ifdef PROCESSOR_ARCHITECTURE_AMD64
480 case PROCESSOR_ARCHITECTURE_AMD64:
481 sprintf (uts->machine, "x86_64(%d)", sysinfo.wProcessorLevel);
482 break;
483 #endif
484 default:
485 sprintf (uts->machine, "unknown(%d)", sysinfo.wProcessorLevel);
486 break;
487 }
488 break;
489 default:
490 strcpy (uts->machine, "unknown");
491 break;
492 }
493 break;
494 default:
495 strcpy (uts->machine, "unknown");
496 break;
497 }
498
499 sLength = sizeof (uts->nodename) - 1;
500 GetComputerName (uts->nodename, &sLength);
501 return 0;
502 }
503 #endif

Properties

Name Value
svn:eol-style native
svn:keywords Id Revision

svnadmin@ircd-hybrid.org
ViewVC Help
Powered by ViewVC 1.1.28