This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
proposal [perl #34301]: IO::Socket calls getpeername far too often
[perl5.git] / wince / wincesck.c
1 /* Time-stamp: <01/08/01 21:01:12 keuchel@w2k> */
2
3 /* wincesck.c
4  *
5  * (c) 1995 Microsoft Corporation. All rights reserved. 
6  *              Developed by hip communications inc., http://info.hip.com/info/
7  * Portions (c) 1993 Intergraph Corporation. All rights reserved.
8  *
9  *    You may distribute under the terms of either the GNU General Public
10  *    License or the Artistic License, as specified in the README file.
11  */
12
13 /* The socket calls use fd functions from celib... */
14
15 #define WIN32IO_IS_STDIO
16 #define WIN32SCK_IS_STDSCK
17 #define WIN32_LEAN_AND_MEAN
18
19 #ifdef __GNUC__
20 #define Win32_Winsock
21 #endif
22
23 #include <windows.h>
24
25 #define wince_private
26 #include "errno.h"
27
28 #include "EXTERN.h"
29 #include "perl.h"
30
31 #include "Win32iop.h"
32 #include <sys/socket.h>
33
34 #ifndef UNDER_CE
35 #include <fcntl.h>
36 #include <sys/stat.h>
37 #include <assert.h>
38 #include <io.h>
39 #endif
40
41 #ifdef UNDER_CE
42
43 XCE_EXPORT struct servent *xcegetservbyname(const char *sname, const char *sproto);
44 XCE_EXPORT struct servent * xcegetservbyport(int aport, const char *sproto);
45 XCE_EXPORT struct protoent *xcegetprotobyname(const char *name);
46 XCE_EXPORT struct protoent *xcegetprotobynumber(int number);
47
48 #define getservbyname xcegetservbyname
49 #define getservbyport xcegetservbyport
50 #define getprotobyname xcegetprotobyname
51 #define getprotobynumber xcegetprotobynumber
52
53 /* uses fdtab... */
54 #include "cesocket2.h"
55
56 #endif
57
58 #define TO_SOCKET(X) (X)
59
60 #define StartSockets() \
61     STMT_START {                                        \
62         if (!wsock_started) {                           \
63             start_sockets();                            \
64             set_socktype();                             \
65         }                                               \
66     } STMT_END
67
68 #define EndSockets() \
69     STMT_START {                                        \
70         if (wsock_started)                              \
71             WSACleanup();                               \
72     } STMT_END
73
74 #define SOCKET_TEST(x, y) \
75     STMT_START {                                        \
76         StartSockets();                                 \
77         if((x) == (y))                                  \
78             errno = WSAGetLastError();                  \
79     } STMT_END
80
81 #define SOCKET_TEST_ERROR(x) SOCKET_TEST(x, SOCKET_ERROR)
82
83 static struct servent* win32_savecopyservent(struct servent*d,
84                                              struct servent*s,
85                                              const char *proto);
86
87 static int wsock_started = 0;
88
89 void
90 start_sockets(void) 
91 {
92     dTHX;
93     unsigned short version;
94     WSADATA retdata;
95     int ret;
96
97     /*
98      * initalize the winsock interface and insure that it is
99      * cleaned up at exit.
100      */
101     version = 0x101;
102     if(ret = WSAStartup(version, &retdata))
103         Perl_croak_nocontext("Unable to locate winsock library!\n");
104     if(retdata.wVersion != version)
105         Perl_croak_nocontext("Could not find version 1.1 of winsock dll\n");
106
107     /* atexit((void (*)(void)) EndSockets); */
108     wsock_started = 1;
109 }
110
111 void
112 set_socktype(void)
113 {
114 }
115
116 u_long
117 win32_htonl(u_long hostlong)
118 {
119     StartSockets();
120     return htonl(hostlong);
121 }
122
123 u_short
124 win32_htons(u_short hostshort)
125 {
126     StartSockets();
127     return htons(hostshort);
128 }
129
130 u_long
131 win32_ntohl(u_long netlong)
132 {
133     StartSockets();
134     return ntohl(netlong);
135 }
136
137 u_short
138 win32_ntohs(u_short netshort)
139 {
140     StartSockets();
141     return ntohs(netshort);
142 }
143
144 SOCKET
145 win32_socket(int af, int type, int protocol)
146 {
147   StartSockets();
148   return xcesocket(af, type, protocol);
149 }
150
151 SOCKET
152 win32_accept(SOCKET s, struct sockaddr *addr, int *addrlen)
153 {
154   StartSockets();
155   return xceaccept(s, addr, addrlen);
156 }
157
158 int
159 win32_bind(SOCKET s, const struct sockaddr *addr, int addrlen)
160 {
161   StartSockets();
162   return xcebind(s, addr, addrlen);
163 }
164
165 int
166 win32_connect(SOCKET s, const struct sockaddr *addr, int addrlen)
167 {
168   StartSockets();
169   return xceconnect(s, addr, addrlen);
170 }
171
172
173 int
174 win32_getpeername(SOCKET s, struct sockaddr *addr, int *addrlen)
175 {
176   StartSockets();
177   return xcegetpeername(s, addr, addrlen);
178 }
179
180 int
181 win32_getsockname(SOCKET s, struct sockaddr *addr, int *addrlen)
182 {
183   StartSockets();
184   return xcegetsockname(s, addr, addrlen);
185 }
186
187 int
188 win32_getsockopt(SOCKET s, int level, int optname, char *optval, int *optlen)
189 {
190   StartSockets();
191   return xcegetsockopt(s, level, optname, optval, optlen);
192 }
193
194 int
195 win32_ioctlsocket(SOCKET s, long cmd, u_long *argp)
196 {
197   StartSockets();
198   return xceioctlsocket(s, cmd, argp);
199 }
200
201 int
202 win32_listen(SOCKET s, int backlog)
203 {
204   StartSockets();
205   return xcelisten(s, backlog);
206 }
207
208 int
209 win32_recv(SOCKET s, char *buf, int len, int flags)
210 {
211   StartSockets();
212   return xcerecv(s, buf, len, flags);
213 }
214
215 int
216 win32_recvfrom(SOCKET s, char *buf, int len, int flags, 
217                struct sockaddr *from, int *fromlen)
218 {
219   StartSockets();
220   return xcerecvfrom(s, buf, len, flags, from, fromlen);
221 }
222
223 int
224 win32_select(int nfds, Perl_fd_set* rd, Perl_fd_set* wr, 
225              Perl_fd_set* ex, const struct timeval* timeout)
226 {
227   StartSockets();
228   /* select not yet fixed */
229   errno = ENOSYS;
230   return -1;
231 }
232
233 int
234 win32_send(SOCKET s, const char *buf, int len, int flags)
235 {
236   StartSockets();
237   return xcesend(s, buf, len, flags);
238 }
239
240 int
241 win32_sendto(SOCKET s, const char *buf, int len, int flags,
242              const struct sockaddr *to, int tolen)
243 {
244   StartSockets();
245   return xcesendto(s, buf, len, flags, to, tolen);
246 }
247
248 int
249 win32_setsockopt(SOCKET s, int level, int optname, 
250                  const char *optval, int optlen)
251 {
252   StartSockets();
253   return xcesetsockopt(s, level, optname, optval, optlen);
254 }
255     
256 int
257 win32_shutdown(SOCKET s, int how)
258 {
259   StartSockets();
260   return xceshutdown(s, how);
261 }
262
263 int
264 win32_closesocket(SOCKET s)
265 {
266   StartSockets();
267   return xceclosesocket(s);
268 }
269
270 struct hostent *
271 win32_gethostbyaddr(const char *addr, int len, int type)
272 {
273   struct hostent *r;
274
275   SOCKET_TEST(r = gethostbyaddr(addr, len, type), NULL);
276   return r;
277 }
278
279 struct hostent *
280 win32_gethostbyname(const char *name)
281 {
282   struct hostent *r;
283
284   SOCKET_TEST(r = gethostbyname(name), NULL);
285   return r;
286 }
287
288 int
289 win32_gethostname(char *name, int len)
290 {
291   int r;
292
293   SOCKET_TEST_ERROR(r = gethostname(name, len));
294   return r;
295 }
296
297 struct protoent *
298 win32_getprotobyname(const char *name)
299 {
300     struct protoent *r;
301
302     SOCKET_TEST(r = getprotobyname(name), NULL);
303     return r;
304 }
305
306 struct protoent *
307 win32_getprotobynumber(int num)
308 {
309     struct protoent *r;
310
311     SOCKET_TEST(r = getprotobynumber(num), NULL);
312     return r;
313 }
314
315 struct servent *
316 win32_getservbyname(const char *name, const char *proto)
317 {
318     dTHX;    
319     struct servent *r;
320
321     SOCKET_TEST(r = getservbyname(name, proto), NULL);
322     if (r) {
323         r = win32_savecopyservent(&w32_servent, r, proto);
324     }
325     return r;
326 }
327
328 struct servent *
329 win32_getservbyport(int port, const char *proto)
330 {
331     dTHX; 
332     struct servent *r;
333
334     SOCKET_TEST(r = getservbyport(port, proto), NULL);
335     if (r) {
336         r = win32_savecopyservent(&w32_servent, r, proto);
337     }
338     return r;
339 }
340
341 int
342 win32_ioctl(int i, unsigned int u, char *data)
343 {
344     dTHX;
345     u_long argp = (u_long)data;
346     int retval;
347
348     if (!wsock_started) {
349         Perl_croak_nocontext("ioctl implemented only on sockets");
350         /* NOTREACHED */
351     }
352
353     retval = ioctlsocket(TO_SOCKET(i), (long)u, &argp);
354     if (retval == SOCKET_ERROR) {
355         if (WSAGetLastError() == WSAENOTSOCK) {
356             Perl_croak_nocontext("ioctl implemented only on sockets");
357             /* NOTREACHED */
358         }
359         errno = WSAGetLastError();
360     }
361     return retval;
362 }
363
364 char FAR *
365 win32_inet_ntoa(struct in_addr in)
366 {
367     StartSockets();
368     return inet_ntoa(in);
369 }
370
371 unsigned long
372 win32_inet_addr(const char FAR *cp)
373 {
374     StartSockets();
375     return inet_addr(cp);
376 }
377
378 /*
379  * Networking stubs
380  */
381
382 void
383 win32_endhostent() 
384 {
385     dTHX;
386     Perl_croak_nocontext("endhostent not implemented!\n");
387 }
388
389 void
390 win32_endnetent()
391 {
392     dTHX;
393     Perl_croak_nocontext("endnetent not implemented!\n");
394 }
395
396 void
397 win32_endprotoent()
398 {
399     dTHX;
400     Perl_croak_nocontext("endprotoent not implemented!\n");
401 }
402
403 void
404 win32_endservent()
405 {
406     dTHX;
407     Perl_croak_nocontext("endservent not implemented!\n");
408 }
409
410
411 struct netent *
412 win32_getnetent(void) 
413 {
414     dTHX;
415     Perl_croak_nocontext("getnetent not implemented!\n");
416     return (struct netent *) NULL;
417 }
418
419 struct netent *
420 win32_getnetbyname(char *name) 
421 {
422     dTHX;
423     Perl_croak_nocontext("getnetbyname not implemented!\n");
424     return (struct netent *)NULL;
425 }
426
427 struct netent *
428 win32_getnetbyaddr(long net, int type) 
429 {
430     dTHX;
431     Perl_croak_nocontext("getnetbyaddr not implemented!\n");
432     return (struct netent *)NULL;
433 }
434
435 struct protoent *
436 win32_getprotoent(void) 
437 {
438     dTHX;
439     Perl_croak_nocontext("getprotoent not implemented!\n");
440     return (struct protoent *) NULL;
441 }
442
443 struct servent *
444 win32_getservent(void) 
445 {
446     dTHX;
447     Perl_croak_nocontext("getservent not implemented!\n");
448     return (struct servent *) NULL;
449 }
450
451 void
452 win32_sethostent(int stayopen)
453 {
454     dTHX;
455     Perl_croak_nocontext("sethostent not implemented!\n");
456 }
457
458
459 void
460 win32_setnetent(int stayopen)
461 {
462     dTHX;
463     Perl_croak_nocontext("setnetent not implemented!\n");
464 }
465
466
467 void
468 win32_setprotoent(int stayopen)
469 {
470     dTHX;
471     Perl_croak_nocontext("setprotoent not implemented!\n");
472 }
473
474
475 void
476 win32_setservent(int stayopen)
477 {
478     dTHX;
479     Perl_croak_nocontext("setservent not implemented!\n");
480 }
481
482 static struct servent*
483 win32_savecopyservent(struct servent*d, struct servent*s, const char *proto)
484 {
485     d->s_name = s->s_name;
486     d->s_aliases = s->s_aliases;
487     d->s_port = s->s_port;
488 #ifndef __BORLANDC__    /* Buggy on Win95 and WinNT-with-Borland-WSOCK */
489     if (!IsWin95() && s->s_proto && strlen(s->s_proto))
490         d->s_proto = s->s_proto;
491     else
492 #endif
493     if (proto && strlen(proto))
494         d->s_proto = (char *)proto;
495     else
496         d->s_proto = "tcp";
497    
498     return d;
499 }