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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 908 - (hide 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 adx 30 /*
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 knight 31 * $Id$
23 adx 30 */
24    
25 stu 908 #ifdef WIN32
26    
27 adx 30 #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 stu 908 #endif

Properties

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

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