Commit | Line | Data |
68dc0745 |
1 | /* NTSock.C |
2 | * |
3 | * (c) 1995 Microsoft Corporation. All rights reserved. |
4 | * Developed by hip communications inc., http://info.hip.com/info/ |
5 | * Portions (c) 1993 Intergraph Corporation. All rights reserved. |
6 | * |
7 | * You may distribute under the terms of either the GNU General Public |
8 | * License or the Artistic License, as specified in the README file. |
9 | */ |
0a753a76 |
10 | |
11 | #include <windows.h> |
12 | #define WIN32_LEAN_AND_MEAN |
13 | #include "EXTERN.h" |
14 | #include "perl.h" |
15 | #include <sys/socket.h> |
16 | #include <fcntl.h> |
17 | #include <sys/stat.h> |
18 | #include <assert.h> |
19 | |
20 | #define CROAK croak |
21 | |
22 | #ifdef USE_SOCKETS_AS_HANDLES |
68dc0745 |
23 | /* thanks to Beverly Brown (beverly@datacube.com) */ |
0a753a76 |
24 | |
3e3baf6d |
25 | #define OPEN_SOCKET(x) _open_osfhandle(x,O_RDWR|O_BINARY) |
137443ea |
26 | #define TO_SOCKET(x) _get_osfhandle(x) |
0a753a76 |
27 | |
28 | #else |
29 | |
30 | # define OPEN_SOCKET(x) (x) |
31 | # define TO_SOCKET(x) (x) |
32 | |
68dc0745 |
33 | #endif /* USE_SOCKETS_AS_HANDLES */ |
0a753a76 |
34 | |
137443ea |
35 | static struct servent* win32_savecopyservent(struct servent*d, |
36 | struct servent*s, |
37 | const char *proto); |
0a753a76 |
38 | #define SOCKETAPI PASCAL |
39 | |
40 | typedef SOCKET (SOCKETAPI *LPSOCKACCEPT)(SOCKET, struct sockaddr *, int *); |
41 | typedef int (SOCKETAPI *LPSOCKBIND)(SOCKET, const struct sockaddr *, int); |
42 | typedef int (SOCKETAPI *LPSOCKCLOSESOCKET)(SOCKET); |
43 | typedef int (SOCKETAPI *LPSOCKCONNECT)(SOCKET, const struct sockaddr *, int); |
44 | typedef int (SOCKETAPI *LPSOCKIOCTLSOCKET)(SOCKET, long, u_long *); |
45 | typedef int (SOCKETAPI *LPSOCKGETPEERNAME)(SOCKET, struct sockaddr *, int *); |
46 | typedef int (SOCKETAPI *LPSOCKGETSOCKNAME)(SOCKET, struct sockaddr *, int *); |
47 | typedef int (SOCKETAPI *LPSOCKGETSOCKOPT)(SOCKET, int, int, char *, int *); |
48 | typedef u_long (SOCKETAPI *LPSOCKHTONL)(u_long); |
49 | typedef u_short (SOCKETAPI *LPSOCKHTONS)(u_short); |
50 | typedef int (SOCKETAPI *LPSOCKLISTEN)(SOCKET, int); |
51 | typedef u_long (SOCKETAPI *LPSOCKNTOHL)(u_long); |
52 | typedef u_short (SOCKETAPI *LPSOCKNTOHS)(u_short); |
53 | typedef int (SOCKETAPI *LPSOCKRECV)(SOCKET, char *, int, int); |
54 | typedef int (SOCKETAPI *LPSOCKRECVFROM)(SOCKET, char *, int, int, struct sockaddr *, int *); |
55 | typedef int (SOCKETAPI *LPSOCKSELECT)(int, fd_set *, fd_set *, fd_set *, const struct timeval *); |
56 | typedef int (SOCKETAPI *LPSOCKSEND)(SOCKET, const char *, int, int); |
57 | typedef int (SOCKETAPI *LPSOCKSENDTO)(SOCKET, const char *, int, int, const struct sockaddr *, int); |
58 | typedef int (SOCKETAPI *LPSOCKSETSOCKOPT)(SOCKET, int, int, const char *, int); |
59 | typedef int (SOCKETAPI *LPSOCKSHUTDOWN)(SOCKET, int); |
60 | typedef SOCKET (SOCKETAPI *LPSOCKSOCKET)(int, int, int); |
61 | typedef char FAR *(SOCKETAPI *LPSOCKINETNTOA)(struct in_addr in); |
62 | typedef unsigned long (SOCKETAPI *LPSOCKINETADDR)(const char FAR * cp); |
63 | |
64 | |
65 | /* Database function prototypes */ |
66 | typedef struct hostent *(SOCKETAPI *LPSOCKGETHOSTBYADDR)(const char *, int, int); |
67 | typedef struct hostent *(SOCKETAPI *LPSOCKGETHOSTBYNAME)(const char *); |
68 | typedef int (SOCKETAPI *LPSOCKGETHOSTNAME)(char *, int); |
69 | typedef struct servent *(SOCKETAPI *LPSOCKGETSERVBYPORT)(int, const char *); |
70 | typedef struct servent *(SOCKETAPI *LPSOCKGETSERVBYNAME)(const char *, const char *); |
71 | typedef struct protoent *(SOCKETAPI *LPSOCKGETPROTOBYNUMBER)(int); |
72 | typedef struct protoent *(SOCKETAPI *LPSOCKGETPROTOBYNAME)(const char *); |
73 | |
74 | /* Microsoft Windows Extension function prototypes */ |
75 | typedef int (SOCKETAPI *LPSOCKWSASTARTUP)(unsigned short, LPWSADATA); |
76 | typedef int (SOCKETAPI *LPSOCKWSACLEANUP)(void); |
77 | typedef int (SOCKETAPI *LPSOCKWSAGETLASTERROR)(void); |
78 | typedef int (SOCKETAPI *LPWSAFDIsSet)(SOCKET, fd_set *); |
79 | |
80 | static HINSTANCE hWinSockDll = 0; |
68dc0745 |
81 | /* extern CRITICAL_SECTION csSock; */ |
0a753a76 |
82 | |
83 | static LPSOCKACCEPT paccept = 0; |
84 | static LPSOCKBIND pbind = 0; |
85 | static LPSOCKCLOSESOCKET pclosesocket = 0; |
86 | static LPSOCKCONNECT pconnect = 0; |
87 | static LPSOCKIOCTLSOCKET pioctlsocket = 0; |
88 | static LPSOCKGETPEERNAME pgetpeername = 0; |
89 | static LPSOCKGETSOCKNAME pgetsockname = 0; |
90 | static LPSOCKGETSOCKOPT pgetsockopt = 0; |
91 | static LPSOCKHTONL phtonl = 0; |
92 | static LPSOCKHTONS phtons = 0; |
93 | static LPSOCKLISTEN plisten = 0; |
94 | static LPSOCKNTOHL pntohl = 0; |
95 | static LPSOCKNTOHS pntohs = 0; |
96 | static LPSOCKRECV precv = 0; |
97 | static LPSOCKRECVFROM precvfrom = 0; |
98 | static LPSOCKSELECT pselect = 0; |
99 | static LPSOCKSEND psend = 0; |
100 | static LPSOCKSENDTO psendto = 0; |
101 | static LPSOCKSETSOCKOPT psetsockopt = 0; |
102 | static LPSOCKSHUTDOWN pshutdown = 0; |
103 | static LPSOCKSOCKET psocket = 0; |
104 | static LPSOCKGETHOSTBYADDR pgethostbyaddr = 0; |
105 | static LPSOCKGETHOSTBYNAME pgethostbyname = 0; |
106 | static LPSOCKGETHOSTNAME pgethostname = 0; |
107 | static LPSOCKGETSERVBYPORT pgetservbyport = 0; |
108 | static LPSOCKGETSERVBYNAME pgetservbyname = 0; |
109 | static LPSOCKGETPROTOBYNUMBER pgetprotobynumber = 0; |
110 | static LPSOCKGETPROTOBYNAME pgetprotobyname = 0; |
111 | static LPSOCKWSASTARTUP pWSAStartup = 0; |
112 | static LPSOCKWSACLEANUP pWSACleanup = 0; |
113 | static LPSOCKWSAGETLASTERROR pWSAGetLastError = 0; |
114 | static LPWSAFDIsSet pWSAFDIsSet = 0; |
115 | static LPSOCKINETNTOA pinet_ntoa = 0; |
116 | static LPSOCKINETADDR pinet_addr = 0; |
117 | |
118 | __declspec(thread) struct servent myservent; |
119 | |
120 | |
68dc0745 |
121 | void * |
122 | GetAddress(HINSTANCE hInstance, char *lpFunctionName) |
123 | { |
68dc0745 |
124 | FARPROC proc = GetProcAddress(hInstance, lpFunctionName); |
fc36a67e |
125 | if(proc == 0) |
126 | CROAK("Unable to get address of %s in WSock32.dll", lpFunctionName); |
68dc0745 |
127 | return proc; |
128 | } |
129 | |
130 | void |
131 | LoadWinSock(void) |
132 | { |
133 | /* EnterCriticalSection(&csSock); */ |
134 | if(hWinSockDll == NULL) { |
135 | HINSTANCE hLib = LoadLibrary("WSock32.DLL"); |
136 | if(hLib == NULL) |
137 | CROAK("Could not load WSock32.dll\n"); |
138 | |
139 | paccept = (LPSOCKACCEPT)GetAddress(hLib, "accept"); |
140 | pbind = (LPSOCKBIND)GetAddress(hLib, "bind"); |
141 | pclosesocket = (LPSOCKCLOSESOCKET)GetAddress(hLib, "closesocket"); |
142 | pconnect = (LPSOCKCONNECT)GetAddress(hLib, "connect"); |
143 | pioctlsocket = (LPSOCKIOCTLSOCKET)GetAddress(hLib, "ioctlsocket"); |
144 | pgetpeername = (LPSOCKGETPEERNAME)GetAddress(hLib, "getpeername"); |
145 | pgetsockname = (LPSOCKGETSOCKNAME)GetAddress(hLib, "getsockname"); |
146 | pgetsockopt = (LPSOCKGETSOCKOPT)GetAddress(hLib, "getsockopt"); |
147 | phtonl = (LPSOCKHTONL)GetAddress(hLib, "htonl"); |
148 | phtons = (LPSOCKHTONS)GetAddress(hLib, "htons"); |
149 | plisten = (LPSOCKLISTEN)GetAddress(hLib, "listen"); |
150 | pntohl = (LPSOCKNTOHL)GetAddress(hLib, "ntohl"); |
151 | pntohs = (LPSOCKNTOHS)GetAddress(hLib, "ntohs"); |
152 | precv = (LPSOCKRECV)GetAddress(hLib, "recv"); |
153 | precvfrom = (LPSOCKRECVFROM)GetAddress(hLib, "recvfrom"); |
154 | pselect = (LPSOCKSELECT)GetAddress(hLib, "select"); |
155 | psend = (LPSOCKSEND)GetAddress(hLib, "send"); |
156 | psendto = (LPSOCKSENDTO)GetAddress(hLib, "sendto"); |
157 | psetsockopt = (LPSOCKSETSOCKOPT)GetAddress(hLib, "setsockopt"); |
158 | pshutdown = (LPSOCKSHUTDOWN)GetAddress(hLib, "shutdown"); |
159 | psocket = (LPSOCKSOCKET)GetAddress(hLib, "socket"); |
160 | pgethostbyaddr = (LPSOCKGETHOSTBYADDR)GetAddress(hLib, "gethostbyaddr"); |
161 | pgethostbyname = (LPSOCKGETHOSTBYNAME)GetAddress(hLib, "gethostbyname"); |
162 | pgethostname = (LPSOCKGETHOSTNAME)GetAddress(hLib, "gethostname"); |
163 | pgetservbyport = (LPSOCKGETSERVBYPORT)GetAddress(hLib, "getservbyport"); |
164 | pgetservbyname = (LPSOCKGETSERVBYNAME)GetAddress(hLib, "getservbyname"); |
165 | pgetprotobynumber = (LPSOCKGETPROTOBYNUMBER)GetAddress(hLib, "getprotobynumber"); |
166 | pgetprotobyname = (LPSOCKGETPROTOBYNAME)GetAddress(hLib, "getprotobyname"); |
167 | pWSAStartup = (LPSOCKWSASTARTUP)GetAddress(hLib, "WSAStartup"); |
168 | pWSACleanup = (LPSOCKWSACLEANUP)GetAddress(hLib, "WSACleanup"); |
169 | pWSAGetLastError = (LPSOCKWSAGETLASTERROR)GetAddress(hLib, "WSAGetLastError"); |
170 | pWSAFDIsSet = (LPWSAFDIsSet)GetAddress(hLib, "__WSAFDIsSet"); |
171 | pinet_addr = (LPSOCKINETADDR)GetAddress(hLib,"inet_addr"); |
172 | pinet_ntoa = (LPSOCKINETNTOA)GetAddress(hLib,"inet_ntoa"); |
173 | |
174 | hWinSockDll = hLib; |
175 | } |
176 | /* LeaveCriticalSection(&csSock); */ |
177 | } |
178 | |
179 | void |
180 | EndSockets(void) |
181 | { |
182 | if(hWinSockDll != NULL) { |
183 | pWSACleanup(); |
184 | FreeLibrary(hWinSockDll); |
185 | } |
186 | hWinSockDll = NULL; |
187 | } |
188 | |
189 | void |
190 | StartSockets(void) |
191 | { |
192 | unsigned short version; |
193 | WSADATA retdata; |
194 | int ret; |
195 | int iSockOpt = SO_SYNCHRONOUS_NONALERT; |
196 | |
197 | LoadWinSock(); |
198 | /* |
199 | * initalize the winsock interface and insure that it is |
200 | * cleaned up at exit. |
201 | */ |
202 | version = 0x101; |
203 | if(ret = pWSAStartup(version, &retdata)) |
204 | CROAK("Unable to locate winsock library!\n"); |
205 | if(retdata.wVersion != version) |
206 | CROAK("Could not find version 1.1 of winsock dll\n"); |
207 | |
208 | /* atexit((void (*)(void)) EndSockets); */ |
0a753a76 |
209 | |
210 | #ifdef USE_SOCKETS_AS_HANDLES |
68dc0745 |
211 | /* |
212 | * Enable the use of sockets as filehandles |
213 | */ |
214 | psetsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, |
215 | (char *)&iSockOpt, sizeof(iSockOpt)); |
216 | #endif /* USE_SOCKETS_AS_HANDLES */ |
0a753a76 |
217 | } |
218 | |
219 | |
220 | #ifndef USE_SOCKETS_AS_HANDLES |
68dc0745 |
221 | FILE * |
222 | myfdopen(int fd, char *mode) |
0a753a76 |
223 | { |
68dc0745 |
224 | FILE *fp; |
225 | char sockbuf[256]; |
226 | int optlen = sizeof(sockbuf); |
227 | int retval; |
0a753a76 |
228 | |
68dc0745 |
229 | if (hWinSockDll == 0) |
fb73857a |
230 | return(fdopen(fd, mode)); |
0a753a76 |
231 | |
68dc0745 |
232 | retval = pgetsockopt((SOCKET)fd, SOL_SOCKET, SO_TYPE, sockbuf, &optlen); |
233 | if(retval == SOCKET_ERROR && pWSAGetLastError() == WSAENOTSOCK) { |
fb73857a |
234 | return(fdopen(fd, mode)); |
68dc0745 |
235 | } |
0a753a76 |
236 | |
68dc0745 |
237 | /* |
238 | * If we get here, then fd is actually a socket. |
239 | */ |
fc36a67e |
240 | Newz(1310, fp, 1, FILE); |
68dc0745 |
241 | if(fp == NULL) { |
242 | errno = ENOMEM; |
243 | return NULL; |
244 | } |
0a753a76 |
245 | |
68dc0745 |
246 | fp->_file = fd; |
247 | if(*mode == 'r') |
248 | fp->_flag = _IOREAD; |
249 | else |
250 | fp->_flag = _IOWRT; |
251 | |
252 | return fp; |
0a753a76 |
253 | } |
68dc0745 |
254 | #endif /* USE_SOCKETS_AS_HANDLES */ |
0a753a76 |
255 | |
256 | |
68dc0745 |
257 | u_long |
258 | win32_htonl(u_long hostlong) |
0a753a76 |
259 | { |
68dc0745 |
260 | if(hWinSockDll == 0) |
fb73857a |
261 | StartSockets(); |
0a753a76 |
262 | |
68dc0745 |
263 | return phtonl(hostlong); |
0a753a76 |
264 | } |
265 | |
68dc0745 |
266 | u_short |
267 | win32_htons(u_short hostshort) |
0a753a76 |
268 | { |
68dc0745 |
269 | if(hWinSockDll == 0) |
fb73857a |
270 | StartSockets(); |
0a753a76 |
271 | |
68dc0745 |
272 | return phtons(hostshort); |
0a753a76 |
273 | } |
274 | |
68dc0745 |
275 | u_long |
276 | win32_ntohl(u_long netlong) |
0a753a76 |
277 | { |
68dc0745 |
278 | if(hWinSockDll == 0) |
fb73857a |
279 | StartSockets(); |
0a753a76 |
280 | |
68dc0745 |
281 | return pntohl(netlong); |
0a753a76 |
282 | } |
283 | |
68dc0745 |
284 | u_short |
285 | win32_ntohs(u_short netshort) |
0a753a76 |
286 | { |
68dc0745 |
287 | if(hWinSockDll == 0) |
fb73857a |
288 | StartSockets(); |
0a753a76 |
289 | |
68dc0745 |
290 | return pntohs(netshort); |
0a753a76 |
291 | } |
292 | |
293 | |
294 | #define SOCKET_TEST(x, y) if(hWinSockDll == 0) StartSockets();\ |
68dc0745 |
295 | if((x) == (y)) errno = pWSAGetLastError() |
0a753a76 |
296 | |
68dc0745 |
297 | #define SOCKET_TEST_ERROR(x) SOCKET_TEST(x, SOCKET_ERROR) |
0a753a76 |
298 | |
68dc0745 |
299 | SOCKET |
300 | win32_accept(SOCKET s, struct sockaddr *addr, int *addrlen) |
0a753a76 |
301 | { |
68dc0745 |
302 | SOCKET r; |
0a753a76 |
303 | |
68dc0745 |
304 | SOCKET_TEST((r = paccept(TO_SOCKET(s), addr, addrlen)), INVALID_SOCKET); |
305 | return OPEN_SOCKET(r); |
0a753a76 |
306 | } |
307 | |
68dc0745 |
308 | int |
309 | win32_bind(SOCKET s, const struct sockaddr *addr, int addrlen) |
0a753a76 |
310 | { |
68dc0745 |
311 | int r; |
0a753a76 |
312 | |
68dc0745 |
313 | SOCKET_TEST_ERROR(r = pbind(TO_SOCKET(s), addr, addrlen)); |
314 | return r; |
0a753a76 |
315 | } |
316 | |
68dc0745 |
317 | int |
318 | win32_connect(SOCKET s, const struct sockaddr *addr, int addrlen) |
0a753a76 |
319 | { |
68dc0745 |
320 | int r; |
0a753a76 |
321 | |
68dc0745 |
322 | SOCKET_TEST_ERROR(r = pconnect(TO_SOCKET(s), addr, addrlen)); |
323 | return r; |
0a753a76 |
324 | } |
325 | |
326 | |
68dc0745 |
327 | int |
328 | win32_getpeername(SOCKET s, struct sockaddr *addr, int *addrlen) |
0a753a76 |
329 | { |
68dc0745 |
330 | int r; |
0a753a76 |
331 | |
68dc0745 |
332 | SOCKET_TEST_ERROR(r = pgetpeername(TO_SOCKET(s), addr, addrlen)); |
333 | return r; |
0a753a76 |
334 | } |
335 | |
68dc0745 |
336 | int |
337 | win32_getsockname(SOCKET s, struct sockaddr *addr, int *addrlen) |
0a753a76 |
338 | { |
68dc0745 |
339 | int r; |
0a753a76 |
340 | |
68dc0745 |
341 | SOCKET_TEST_ERROR(r = pgetsockname(TO_SOCKET(s), addr, addrlen)); |
342 | return r; |
0a753a76 |
343 | } |
344 | |
68dc0745 |
345 | int |
346 | win32_getsockopt(SOCKET s, int level, int optname, char *optval, int *optlen) |
0a753a76 |
347 | { |
68dc0745 |
348 | int r; |
0a753a76 |
349 | |
68dc0745 |
350 | SOCKET_TEST_ERROR(r = pgetsockopt(TO_SOCKET(s), level, optname, optval, optlen)); |
351 | return r; |
0a753a76 |
352 | } |
353 | |
68dc0745 |
354 | int |
355 | win32_ioctlsocket(SOCKET s, long cmd, u_long *argp) |
0a753a76 |
356 | { |
68dc0745 |
357 | int r; |
0a753a76 |
358 | |
68dc0745 |
359 | SOCKET_TEST_ERROR(r = pioctlsocket(TO_SOCKET(s), cmd, argp)); |
360 | return r; |
0a753a76 |
361 | } |
362 | |
68dc0745 |
363 | int |
364 | win32_listen(SOCKET s, int backlog) |
0a753a76 |
365 | { |
68dc0745 |
366 | int r; |
0a753a76 |
367 | |
68dc0745 |
368 | SOCKET_TEST_ERROR(r = plisten(TO_SOCKET(s), backlog)); |
369 | return r; |
0a753a76 |
370 | } |
371 | |
68dc0745 |
372 | int |
373 | win32_recv(SOCKET s, char *buf, int len, int flags) |
0a753a76 |
374 | { |
68dc0745 |
375 | int r; |
0a753a76 |
376 | |
68dc0745 |
377 | SOCKET_TEST_ERROR(r = precv(TO_SOCKET(s), buf, len, flags)); |
378 | return r; |
0a753a76 |
379 | } |
380 | |
68dc0745 |
381 | int |
382 | win32_recvfrom(SOCKET s, char *buf, int len, int flags, struct sockaddr *from, int *fromlen) |
0a753a76 |
383 | { |
68dc0745 |
384 | int r; |
0a753a76 |
385 | |
68dc0745 |
386 | SOCKET_TEST_ERROR(r = precvfrom(TO_SOCKET(s), buf, len, flags, from, fromlen)); |
387 | return r; |
0a753a76 |
388 | } |
389 | |
68dc0745 |
390 | /* select contributed by Vincent R. Slyngstad (vrs@ibeam.intel.com) */ |
391 | int |
392 | win32_select(int nfds, int* rd, int* wr, int* ex, const struct timeval* timeout) |
0a753a76 |
393 | { |
68dc0745 |
394 | long r; |
395 | int dummy = 0; |
396 | int i, fd, bit, offset; |
397 | FD_SET nrd, nwr, nex,*prd,*pwr,*pex; |
0a753a76 |
398 | |
68dc0745 |
399 | if (!rd) |
400 | rd = &dummy, prd = NULL; |
401 | else |
402 | prd = &nrd; |
403 | if (!wr) |
404 | wr = &dummy, pwr = NULL; |
405 | else |
406 | pwr = &nwr; |
407 | if (!ex) |
408 | ex = &dummy, pex = NULL; |
409 | else |
410 | pex = &nex; |
0a753a76 |
411 | |
68dc0745 |
412 | FD_ZERO(&nrd); |
413 | FD_ZERO(&nwr); |
414 | FD_ZERO(&nex); |
415 | for (i = 0; i < nfds; i++) { |
416 | fd = TO_SOCKET(i); |
417 | bit = 1L<<(i % (sizeof(int)*8)); |
418 | offset = i / (sizeof(int)*8); |
419 | if (rd[offset] & bit) |
420 | FD_SET(fd, &nrd); |
421 | if (wr[offset] & bit) |
422 | FD_SET(fd, &nwr); |
423 | if (ex[offset] & bit) |
424 | FD_SET(fd, &nex); |
425 | } |
426 | |
427 | SOCKET_TEST_ERROR(r = pselect(nfds, prd, pwr, pex, timeout)); |
0a753a76 |
428 | |
68dc0745 |
429 | for (i = 0; i < nfds; i++) { |
430 | fd = TO_SOCKET(i); |
431 | bit = 1L<<(i % (sizeof(int)*8)); |
432 | offset = i / (sizeof(int)*8); |
433 | if (rd[offset] & bit) { |
434 | if (!pWSAFDIsSet(fd, &nrd)) |
435 | rd[offset] &= ~bit; |
436 | } |
437 | if (wr[offset] & bit) { |
438 | if (!pWSAFDIsSet(fd, &nwr)) |
439 | wr[offset] &= ~bit; |
440 | } |
441 | if (ex[offset] & bit) { |
442 | if (!pWSAFDIsSet(fd, &nex)) |
443 | ex[offset] &= ~bit; |
0a753a76 |
444 | } |
68dc0745 |
445 | } |
446 | return r; |
0a753a76 |
447 | } |
448 | |
68dc0745 |
449 | int |
450 | win32_send(SOCKET s, const char *buf, int len, int flags) |
0a753a76 |
451 | { |
68dc0745 |
452 | int r; |
0a753a76 |
453 | |
68dc0745 |
454 | SOCKET_TEST_ERROR(r = psend(TO_SOCKET(s), buf, len, flags)); |
455 | return r; |
0a753a76 |
456 | } |
457 | |
68dc0745 |
458 | int |
459 | win32_sendto(SOCKET s, const char *buf, int len, int flags, |
460 | const struct sockaddr *to, int tolen) |
0a753a76 |
461 | { |
68dc0745 |
462 | int r; |
0a753a76 |
463 | |
68dc0745 |
464 | SOCKET_TEST_ERROR(r = psendto(TO_SOCKET(s), buf, len, flags, to, tolen)); |
465 | return r; |
0a753a76 |
466 | } |
467 | |
68dc0745 |
468 | int |
469 | win32_setsockopt(SOCKET s, int level, int optname, const char *optval, int optlen) |
0a753a76 |
470 | { |
68dc0745 |
471 | int r; |
0a753a76 |
472 | |
68dc0745 |
473 | SOCKET_TEST_ERROR(r = psetsockopt(TO_SOCKET(s), level, optname, optval, optlen)); |
474 | return r; |
0a753a76 |
475 | } |
476 | |
68dc0745 |
477 | int |
478 | win32_shutdown(SOCKET s, int how) |
0a753a76 |
479 | { |
68dc0745 |
480 | int r; |
0a753a76 |
481 | |
68dc0745 |
482 | SOCKET_TEST_ERROR(r = pshutdown(TO_SOCKET(s), how)); |
483 | return r; |
0a753a76 |
484 | } |
485 | |
68dc0745 |
486 | SOCKET |
487 | win32_socket(int af, int type, int protocol) |
0a753a76 |
488 | { |
68dc0745 |
489 | SOCKET s; |
0a753a76 |
490 | |
491 | #ifndef USE_SOCKETS_AS_HANDLES |
68dc0745 |
492 | SOCKET_TEST(s = psocket(af, type, protocol), INVALID_SOCKET); |
0a753a76 |
493 | #else |
68dc0745 |
494 | if(hWinSockDll == 0) |
495 | StartSockets(); |
0a753a76 |
496 | |
68dc0745 |
497 | if((s = psocket(af, type, protocol)) == INVALID_SOCKET) |
498 | errno = pWSAGetLastError(); |
499 | else |
500 | s = OPEN_SOCKET(s); |
501 | #endif /* USE_SOCKETS_AS_HANDLES */ |
0a753a76 |
502 | |
68dc0745 |
503 | return s; |
0a753a76 |
504 | } |
505 | |
fb73857a |
506 | #undef fclose |
507 | int |
508 | my_fclose (FILE *pf) |
509 | { |
510 | int osf, retval; |
511 | if (hWinSockDll == 0) /* No WinSockDLL? */ |
512 | return(fclose(pf)); /* Then not a socket. */ |
513 | osf = TO_SOCKET(fileno(pf)); /* Get it now before it's gone! */ |
514 | retval = fclose(pf); /* Must fclose() before closesocket() */ |
515 | if (osf != -1 |
516 | && pclosesocket(osf) == SOCKET_ERROR |
517 | && WSAGetLastError() != WSAENOTSOCK) |
518 | retval = EOF; |
519 | return retval; |
520 | } |
521 | |
68dc0745 |
522 | struct hostent * |
523 | win32_gethostbyaddr(const char *addr, int len, int type) |
0a753a76 |
524 | { |
68dc0745 |
525 | struct hostent *r; |
0a753a76 |
526 | |
68dc0745 |
527 | SOCKET_TEST(r = pgethostbyaddr(addr, len, type), NULL); |
528 | return r; |
0a753a76 |
529 | } |
530 | |
68dc0745 |
531 | struct hostent * |
532 | win32_gethostbyname(const char *name) |
0a753a76 |
533 | { |
68dc0745 |
534 | struct hostent *r; |
0a753a76 |
535 | |
68dc0745 |
536 | SOCKET_TEST(r = pgethostbyname(name), NULL); |
537 | return r; |
0a753a76 |
538 | } |
539 | |
68dc0745 |
540 | int |
541 | win32_gethostname(char *name, int len) |
0a753a76 |
542 | { |
68dc0745 |
543 | int r; |
0a753a76 |
544 | |
68dc0745 |
545 | SOCKET_TEST_ERROR(r = pgethostname(name, len)); |
546 | return r; |
0a753a76 |
547 | } |
548 | |
68dc0745 |
549 | struct protoent * |
550 | win32_getprotobyname(const char *name) |
0a753a76 |
551 | { |
68dc0745 |
552 | struct protoent *r; |
0a753a76 |
553 | |
68dc0745 |
554 | SOCKET_TEST(r = pgetprotobyname(name), NULL); |
555 | return r; |
0a753a76 |
556 | } |
557 | |
68dc0745 |
558 | struct protoent * |
559 | win32_getprotobynumber(int num) |
0a753a76 |
560 | { |
68dc0745 |
561 | struct protoent *r; |
0a753a76 |
562 | |
68dc0745 |
563 | SOCKET_TEST(r = pgetprotobynumber(num), NULL); |
564 | return r; |
0a753a76 |
565 | } |
566 | |
68dc0745 |
567 | struct servent * |
568 | win32_getservbyname(const char *name, const char *proto) |
0a753a76 |
569 | { |
68dc0745 |
570 | struct servent *r; |
571 | |
572 | SOCKET_TEST(r = pgetservbyname(name, proto), NULL); |
573 | if (r) { |
574 | r = win32_savecopyservent(&myservent, r, proto); |
575 | } |
576 | return r; |
0a753a76 |
577 | } |
578 | |
68dc0745 |
579 | struct servent * |
580 | win32_getservbyport(int port, const char *proto) |
0a753a76 |
581 | { |
68dc0745 |
582 | struct servent *r; |
0a753a76 |
583 | |
68dc0745 |
584 | SOCKET_TEST(r = pgetservbyport(port, proto), NULL); |
585 | if (r) { |
586 | r = win32_savecopyservent(&myservent, r, proto); |
587 | } |
588 | return r; |
0a753a76 |
589 | } |
590 | |
68dc0745 |
591 | char FAR * |
592 | win32_inet_ntoa(struct in_addr in) |
0a753a76 |
593 | { |
68dc0745 |
594 | if(hWinSockDll == 0) |
fb73857a |
595 | StartSockets(); |
0a753a76 |
596 | |
68dc0745 |
597 | return pinet_ntoa(in); |
0a753a76 |
598 | } |
599 | |
68dc0745 |
600 | unsigned long |
601 | win32_inet_addr(const char FAR *cp) |
0a753a76 |
602 | { |
68dc0745 |
603 | if(hWinSockDll == 0) |
fb73857a |
604 | StartSockets(); |
0a753a76 |
605 | |
68dc0745 |
606 | return pinet_addr(cp); |
0a753a76 |
607 | |
608 | } |
68dc0745 |
609 | |
610 | /* |
611 | * Networking stubs |
612 | */ |
0a753a76 |
613 | #undef CROAK |
614 | #define CROAK croak |
615 | |
68dc0745 |
616 | void |
617 | win32_endhostent() |
0a753a76 |
618 | { |
68dc0745 |
619 | CROAK("endhostent not implemented!\n"); |
0a753a76 |
620 | } |
621 | |
68dc0745 |
622 | void |
623 | win32_endnetent() |
0a753a76 |
624 | { |
68dc0745 |
625 | CROAK("endnetent not implemented!\n"); |
0a753a76 |
626 | } |
627 | |
68dc0745 |
628 | void |
629 | win32_endprotoent() |
0a753a76 |
630 | { |
68dc0745 |
631 | CROAK("endprotoent not implemented!\n"); |
0a753a76 |
632 | } |
633 | |
68dc0745 |
634 | void |
635 | win32_endservent() |
0a753a76 |
636 | { |
68dc0745 |
637 | CROAK("endservent not implemented!\n"); |
0a753a76 |
638 | } |
639 | |
640 | |
68dc0745 |
641 | struct netent * |
642 | win32_getnetent(void) |
0a753a76 |
643 | { |
68dc0745 |
644 | CROAK("getnetent not implemented!\n"); |
645 | return (struct netent *) NULL; |
0a753a76 |
646 | } |
647 | |
68dc0745 |
648 | struct netent * |
649 | win32_getnetbyname(char *name) |
0a753a76 |
650 | { |
68dc0745 |
651 | CROAK("getnetbyname not implemented!\n"); |
652 | return (struct netent *)NULL; |
0a753a76 |
653 | } |
654 | |
68dc0745 |
655 | struct netent * |
656 | win32_getnetbyaddr(long net, int type) |
0a753a76 |
657 | { |
68dc0745 |
658 | CROAK("getnetbyaddr not implemented!\n"); |
659 | return (struct netent *)NULL; |
0a753a76 |
660 | } |
661 | |
68dc0745 |
662 | struct protoent * |
663 | win32_getprotoent(void) |
0a753a76 |
664 | { |
68dc0745 |
665 | CROAK("getprotoent not implemented!\n"); |
666 | return (struct protoent *) NULL; |
0a753a76 |
667 | } |
668 | |
68dc0745 |
669 | struct servent * |
670 | win32_getservent(void) |
0a753a76 |
671 | { |
68dc0745 |
672 | CROAK("getservent not implemented!\n"); |
673 | return (struct servent *) NULL; |
0a753a76 |
674 | } |
675 | |
68dc0745 |
676 | void |
677 | win32_sethostent(int stayopen) |
0a753a76 |
678 | { |
68dc0745 |
679 | CROAK("sethostent not implemented!\n"); |
0a753a76 |
680 | } |
681 | |
682 | |
68dc0745 |
683 | void |
684 | win32_setnetent(int stayopen) |
0a753a76 |
685 | { |
68dc0745 |
686 | CROAK("setnetent not implemented!\n"); |
0a753a76 |
687 | } |
688 | |
689 | |
68dc0745 |
690 | void |
691 | win32_setprotoent(int stayopen) |
0a753a76 |
692 | { |
68dc0745 |
693 | CROAK("setprotoent not implemented!\n"); |
0a753a76 |
694 | } |
695 | |
696 | |
68dc0745 |
697 | void |
698 | win32_setservent(int stayopen) |
0a753a76 |
699 | { |
68dc0745 |
700 | CROAK("setservent not implemented!\n"); |
0a753a76 |
701 | } |
702 | |
137443ea |
703 | #define WIN32IO_IS_STDIO |
704 | #include <io.h> |
d55594ae |
705 | |
706 | #ifdef __cplusplus |
707 | extern "C" { |
708 | #endif |
137443ea |
709 | #include "win32iop.h" |
d55594ae |
710 | #ifdef __cplusplus |
711 | } |
712 | #endif |
137443ea |
713 | |
714 | static struct servent* |
715 | win32_savecopyservent(struct servent*d, struct servent*s, const char *proto) |
716 | { |
717 | d->s_name = s->s_name; |
718 | d->s_aliases = s->s_aliases; |
719 | d->s_port = s->s_port; |
0af56dfe |
720 | #ifndef __BORLANDC__ /* Buggy on Win95 and WinNT-with-Borland-WSOCK */ |
137443ea |
721 | if (!IsWin95() && s->s_proto && strlen(s->s_proto)) |
722 | d->s_proto = s->s_proto; |
0af56dfe |
723 | else |
724 | #endif |
725 | if (proto && strlen(proto)) |
137443ea |
726 | d->s_proto = (char *)proto; |
727 | else |
728 | d->s_proto = "tcp"; |
729 | |
730 | return d; |
731 | } |
732 | |
0a753a76 |
733 | |