use same treatment for EINVAL as for ETIMEDOUT
[p5sagit/p5-mst-13.2.git] / ext / Socket / Socket.xs
1 #define PERL_NO_GET_CONTEXT
2 #include "EXTERN.h"
3 #include "perl.h"
4 #include "XSUB.h"
5
6 #ifndef VMS
7 # ifdef I_SYS_TYPES
8 #  include <sys/types.h>
9 # endif
10 # include <sys/socket.h>
11 # if defined(USE_SOCKS) && defined(I_SOCKS)
12 #   include <socks.h>
13 # endif 
14 # ifdef MPE
15 #  define PF_INET AF_INET
16 #  define PF_UNIX AF_UNIX
17 #  define SOCK_RAW 3
18 # endif
19 # ifdef I_SYS_UN
20 #  include <sys/un.h>
21 # endif
22 # ifdef I_NETINET_IN
23 #  include <netinet/in.h>
24 # endif
25 # ifdef I_NETDB
26 #  include <netdb.h>
27 # endif
28 # ifdef I_ARPA_INET
29 #  include <arpa/inet.h>
30 # endif
31 # ifdef I_NETINET_TCP
32 #  include <netinet/tcp.h>
33 # endif
34 #else
35 # include "sockadapt.h"
36 #endif
37
38 #ifdef I_SYSUIO
39 # include <sys/uio.h>
40 #endif
41
42 #ifndef AF_NBS
43 # undef PF_NBS
44 #endif
45
46 #ifndef AF_X25
47 # undef PF_X25
48 #endif
49
50 #ifndef INADDR_NONE
51 # define INADDR_NONE    0xffffffff
52 #endif /* INADDR_NONE */
53 #ifndef INADDR_BROADCAST
54 # define INADDR_BROADCAST       0xffffffff
55 #endif /* INADDR_BROADCAST */
56 #ifndef INADDR_LOOPBACK
57 # define INADDR_LOOPBACK         0x7F000001
58 #endif /* INADDR_LOOPBACK */
59
60 #ifndef HAS_INET_ATON
61
62 /* 
63  * Check whether "cp" is a valid ascii representation
64  * of an Internet address and convert to a binary address.
65  * Returns 1 if the address is valid, 0 if not.
66  * This replaces inet_addr, the return value from which
67  * cannot distinguish between failure and a local broadcast address.
68  */
69 static int
70 my_inet_aton(register const char *cp, struct in_addr *addr)
71 {
72         dTHX;
73         register U32 val;
74         register int base;
75         register char c;
76         int nparts;
77         const char *s;
78         unsigned int parts[4];
79         register unsigned int *pp = parts;
80
81         if (!cp)
82                 return 0;
83         for (;;) {
84                 /*
85                  * Collect number up to ``.''.
86                  * Values are specified as for C:
87                  * 0x=hex, 0=octal, other=decimal.
88                  */
89                 val = 0; base = 10;
90                 if (*cp == '0') {
91                         if (*++cp == 'x' || *cp == 'X')
92                                 base = 16, cp++;
93                         else
94                                 base = 8;
95                 }
96                 while ((c = *cp) != '\0') {
97                         if (isDIGIT(c)) {
98                                 val = (val * base) + (c - '0');
99                                 cp++;
100                                 continue;
101                         }
102                         if (base == 16 && (s=strchr(PL_hexdigit,c))) {
103                                 val = (val << 4) + 
104                                         ((s - PL_hexdigit) & 15);
105                                 cp++;
106                                 continue;
107                         }
108                         break;
109                 }
110                 if (*cp == '.') {
111                         /*
112                          * Internet format:
113                          *      a.b.c.d
114                          *      a.b.c   (with c treated as 16-bits)
115                          *      a.b     (with b treated as 24 bits)
116                          */
117                         if (pp >= parts + 3 || val > 0xff)
118                                 return 0;
119                         *pp++ = val, cp++;
120                 } else
121                         break;
122         }
123         /*
124          * Check for trailing characters.
125          */
126         if (*cp && !isSPACE(*cp))
127                 return 0;
128         /*
129          * Concoct the address according to
130          * the number of parts specified.
131          */
132         nparts = pp - parts + 1;        /* force to an int for switch() */
133         switch (nparts) {
134
135         case 1:                         /* a -- 32 bits */
136                 break;
137
138         case 2:                         /* a.b -- 8.24 bits */
139                 if (val > 0xffffff)
140                         return 0;
141                 val |= parts[0] << 24;
142                 break;
143
144         case 3:                         /* a.b.c -- 8.8.16 bits */
145                 if (val > 0xffff)
146                         return 0;
147                 val |= (parts[0] << 24) | (parts[1] << 16);
148                 break;
149
150         case 4:                         /* a.b.c.d -- 8.8.8.8 bits */
151                 if (val > 0xff)
152                         return 0;
153                 val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
154                 break;
155         }
156         addr->s_addr = htonl(val);
157         return 1;
158 }
159
160 #undef inet_aton
161 #define inet_aton my_inet_aton
162
163 #endif /* ! HAS_INET_ATON */
164
165
166 static int
167 not_here(char *s)
168 {
169     croak("Socket::%s not implemented on this architecture", s);
170     return -1;
171 }
172
173 static double
174 constant(char *name, int arg)
175 {
176     errno = 0;
177     switch (*name) {
178     case 'A':
179         if (strEQ(name, "AF_802"))
180 #ifdef AF_802
181             return AF_802;
182 #else
183             goto not_there;
184 #endif
185         if (strEQ(name, "AF_APPLETALK"))
186 #ifdef AF_APPLETALK
187             return AF_APPLETALK;
188 #else
189             goto not_there;
190 #endif
191         if (strEQ(name, "AF_CCITT"))
192 #ifdef AF_CCITT
193             return AF_CCITT;
194 #else
195             goto not_there;
196 #endif
197         if (strEQ(name, "AF_CHAOS"))
198 #ifdef AF_CHAOS
199             return AF_CHAOS;
200 #else
201             goto not_there;
202 #endif
203         if (strEQ(name, "AF_DATAKIT"))
204 #ifdef AF_DATAKIT
205             return AF_DATAKIT;
206 #else
207             goto not_there;
208 #endif
209         if (strEQ(name, "AF_DECnet"))
210 #ifdef AF_DECnet
211             return AF_DECnet;
212 #else
213             goto not_there;
214 #endif
215         if (strEQ(name, "AF_DLI"))
216 #ifdef AF_DLI
217             return AF_DLI;
218 #else
219             goto not_there;
220 #endif
221         if (strEQ(name, "AF_ECMA"))
222 #ifdef AF_ECMA
223             return AF_ECMA;
224 #else
225             goto not_there;
226 #endif
227         if (strEQ(name, "AF_GOSIP"))
228 #ifdef AF_GOSIP
229             return AF_GOSIP;
230 #else
231             goto not_there;
232 #endif
233         if (strEQ(name, "AF_HYLINK"))
234 #ifdef AF_HYLINK
235             return AF_HYLINK;
236 #else
237             goto not_there;
238 #endif
239         if (strEQ(name, "AF_IMPLINK"))
240 #ifdef AF_IMPLINK
241             return AF_IMPLINK;
242 #else
243             goto not_there;
244 #endif
245         if (strEQ(name, "AF_INET"))
246 #ifdef AF_INET
247             return AF_INET;
248 #else
249             goto not_there;
250 #endif
251         if (strEQ(name, "AF_LAT"))
252 #ifdef AF_LAT
253             return AF_LAT;
254 #else
255             goto not_there;
256 #endif
257         if (strEQ(name, "AF_MAX"))
258 #ifdef AF_MAX
259             return AF_MAX;
260 #else
261             goto not_there;
262 #endif
263         if (strEQ(name, "AF_NBS"))
264 #ifdef AF_NBS
265             return AF_NBS;
266 #else
267             goto not_there;
268 #endif
269         if (strEQ(name, "AF_NIT"))
270 #ifdef AF_NIT
271             return AF_NIT;
272 #else
273             goto not_there;
274 #endif
275         if (strEQ(name, "AF_NS"))
276 #ifdef AF_NS
277             return AF_NS;
278 #else
279             goto not_there;
280 #endif
281         if (strEQ(name, "AF_OSI"))
282 #ifdef AF_OSI
283             return AF_OSI;
284 #else
285             goto not_there;
286 #endif
287         if (strEQ(name, "AF_OSINET"))
288 #ifdef AF_OSINET
289             return AF_OSINET;
290 #else
291             goto not_there;
292 #endif
293         if (strEQ(name, "AF_PUP"))
294 #ifdef AF_PUP
295             return AF_PUP;
296 #else
297             goto not_there;
298 #endif
299         if (strEQ(name, "AF_SNA"))
300 #ifdef AF_SNA
301             return AF_SNA;
302 #else
303             goto not_there;
304 #endif
305         if (strEQ(name, "AF_UNIX"))
306 #ifdef AF_UNIX
307             return AF_UNIX;
308 #else
309             goto not_there;
310 #endif
311         if (strEQ(name, "AF_UNSPEC"))
312 #ifdef AF_UNSPEC
313             return AF_UNSPEC;
314 #else
315             goto not_there;
316 #endif
317         if (strEQ(name, "AF_X25"))
318 #ifdef AF_X25
319             return AF_X25;
320 #else
321             goto not_there;
322 #endif
323         break;
324     case 'B':
325         break;
326     case 'C':
327         break;
328     case 'D':
329         break;
330     case 'E':
331         break;
332     case 'F':
333         break;
334     case 'G':
335         break;
336     case 'H':
337         break;
338     case 'I':
339         if (strEQ(name, "IOV_MAX"))
340 #ifdef IOV_MAX
341             return IOV_MAX;
342 #else
343             goto not_there;
344 #endif
345         if (strEQ(name, "IPPROTO_TCP"))
346 #ifdef IPPROTO_TCP
347             return IPPROTO_TCP;
348 #else
349             goto not_there;
350 #endif
351         break;
352     case 'J':
353         break;
354     case 'K':
355         break;
356     case 'L':
357         break;
358     case 'M':
359         if (strEQ(name, "MSG_BCAST"))
360 #ifdef MSG_BCAST
361             return MSG_BCAST;
362 #else
363             goto not_there;
364 #endif
365         if (strEQ(name, "MSG_CTLFLAGS"))
366 #ifdef MSG_CTLFLAGS
367             return MSG_CTLFLAGS;
368 #else
369             goto not_there;
370 #endif
371         if (strEQ(name, "MSG_CTLIGNORE"))
372 #ifdef MSG_CTLIGNORE
373             return MSG_CTLIGNORE;
374 #else
375             goto not_there;
376 #endif
377         if (strEQ(name, "MSG_CTRUNC"))
378 #if defined(MSG_TRUNC) || defined(HAS_MSG_CTRUNC) /* might be an enum */
379             return MSG_CTRUNC;
380 #else
381             goto not_there;
382 #endif
383         if (strEQ(name, "MSG_DONTROUTE"))
384 #if defined(MSG_DONTROUTE) || defined(HAS_MSG_DONTROUTE) /* might be an enum */
385             return MSG_DONTROUTE;
386 #else
387             goto not_there;
388 #endif
389         if (strEQ(name, "MSG_DONTWAIT"))
390 #ifdef MSG_DONTWAIT
391             return MSG_DONTWAIT;
392 #else
393             goto not_there;
394 #endif
395         if (strEQ(name, "MSG_EOF"))
396 #ifdef MSG_EOF
397             return MSG_EOF;
398 #else
399             goto not_there;
400 #endif
401         if (strEQ(name, "MSG_EOR"))
402 #ifdef MSG_EOR
403             return MSG_EOR;
404 #else
405             goto not_there;
406 #endif
407         if (strEQ(name, "MSG_ERRQUEUE"))
408 #ifdef MSG_ERRQUEUE
409             return MSG_ERRQUEUE;
410 #else
411             goto not_there;
412 #endif
413         if (strEQ(name, "MSG_FIN"))
414 #ifdef MSG_FIN
415             return MSG_FIN;
416 #else
417             goto not_there;
418 #endif
419         if (strEQ(name, "MSG_MAXIOVLEN"))
420 #ifdef MSG_MAXIOVLEN
421             return MSG_MAXIOVLEN;
422 #else
423             goto not_there;
424 #endif
425         if (strEQ(name, "MSG_MCAST"))
426 #ifdef MSG_MCAST
427             return MSG_MCAST;
428 #else
429             goto not_there;
430 #endif
431         if (strEQ(name, "MSG_NOSIGNAL"))
432 #ifdef MSG_NOSIGNAL
433             return MSG_NOSIGNAL;
434 #else
435             goto not_there;
436 #endif
437         if (strEQ(name, "MSG_OOB"))
438 #if defined(MSG_OOB) || defined(HAS_MSG_OOB) /* might be an enum */
439             return MSG_OOB;
440 #else
441             goto not_there;
442 #endif
443         if (strEQ(name, "MSG_PEEK"))
444 #if defined(MSG_PEEK) || defined(HAS_MSG_PEEK) /* might be an enum */
445             return MSG_PEEK;
446 #else
447             goto not_there;
448 #endif
449         if (strEQ(name, "MSG_PROXY"))
450 #if defined(MSG_PROXY) || defined(HAS_MSG_PROXY) /* might be an enum */
451             return MSG_PROXY;
452 #else
453             goto not_there;
454 #endif
455         if (strEQ(name, "MSG_RST"))
456 #ifdef MSG_RST
457             return MSG_RST;
458 #else
459             goto not_there;
460 #endif
461         if (strEQ(name, "MSG_SYN"))
462 #ifdef MSG_SYN
463             return MSG_SYN;
464 #else
465             goto not_there;
466 #endif
467         if (strEQ(name, "MSG_TRUNC"))
468 #ifdef MSG_TRUNC
469             return MSG_TRUNC;
470 #else
471             goto not_there;
472 #endif
473         if (strEQ(name, "MSG_WAITALL"))
474 #ifdef MSG_WAITALL
475             return MSG_WAITALL;
476 #else
477             goto not_there;
478 #endif
479         break;
480     case 'N':
481         break;
482     case 'O':
483         break;
484     case 'P':
485         if (strEQ(name, "PF_802"))
486 #ifdef PF_802
487             return PF_802;
488 #else
489             goto not_there;
490 #endif
491         if (strEQ(name, "PF_APPLETALK"))
492 #ifdef PF_APPLETALK
493             return PF_APPLETALK;
494 #else
495             goto not_there;
496 #endif
497         if (strEQ(name, "PF_CCITT"))
498 #ifdef PF_CCITT
499             return PF_CCITT;
500 #else
501             goto not_there;
502 #endif
503         if (strEQ(name, "PF_CHAOS"))
504 #ifdef PF_CHAOS
505             return PF_CHAOS;
506 #else
507             goto not_there;
508 #endif
509         if (strEQ(name, "PF_DATAKIT"))
510 #ifdef PF_DATAKIT
511             return PF_DATAKIT;
512 #else
513             goto not_there;
514 #endif
515         if (strEQ(name, "PF_DECnet"))
516 #ifdef PF_DECnet
517             return PF_DECnet;
518 #else
519             goto not_there;
520 #endif
521         if (strEQ(name, "PF_DLI"))
522 #ifdef PF_DLI
523             return PF_DLI;
524 #else
525             goto not_there;
526 #endif
527         if (strEQ(name, "PF_ECMA"))
528 #ifdef PF_ECMA
529             return PF_ECMA;
530 #else
531             goto not_there;
532 #endif
533         if (strEQ(name, "PF_GOSIP"))
534 #ifdef PF_GOSIP
535             return PF_GOSIP;
536 #else
537             goto not_there;
538 #endif
539         if (strEQ(name, "PF_HYLINK"))
540 #ifdef PF_HYLINK
541             return PF_HYLINK;
542 #else
543             goto not_there;
544 #endif
545         if (strEQ(name, "PF_IMPLINK"))
546 #ifdef PF_IMPLINK
547             return PF_IMPLINK;
548 #else
549             goto not_there;
550 #endif
551         if (strEQ(name, "PF_INET"))
552 #ifdef PF_INET
553             return PF_INET;
554 #else
555             goto not_there;
556 #endif
557         if (strEQ(name, "PF_LAT"))
558 #ifdef PF_LAT
559             return PF_LAT;
560 #else
561             goto not_there;
562 #endif
563         if (strEQ(name, "PF_MAX"))
564 #ifdef PF_MAX
565             return PF_MAX;
566 #else
567             goto not_there;
568 #endif
569         if (strEQ(name, "PF_NBS"))
570 #ifdef PF_NBS
571             return PF_NBS;
572 #else
573             goto not_there;
574 #endif
575         if (strEQ(name, "PF_NIT"))
576 #ifdef PF_NIT
577             return PF_NIT;
578 #else
579             goto not_there;
580 #endif
581         if (strEQ(name, "PF_NS"))
582 #ifdef PF_NS
583             return PF_NS;
584 #else
585             goto not_there;
586 #endif
587         if (strEQ(name, "PF_OSI"))
588 #ifdef PF_OSI
589             return PF_OSI;
590 #else
591             goto not_there;
592 #endif
593         if (strEQ(name, "PF_OSINET"))
594 #ifdef PF_OSINET
595             return PF_OSINET;
596 #else
597             goto not_there;
598 #endif
599         if (strEQ(name, "PF_PUP"))
600 #ifdef PF_PUP
601             return PF_PUP;
602 #else
603             goto not_there;
604 #endif
605         if (strEQ(name, "PF_SNA"))
606 #ifdef PF_SNA
607             return PF_SNA;
608 #else
609             goto not_there;
610 #endif
611         if (strEQ(name, "PF_UNIX"))
612 #ifdef PF_UNIX
613             return PF_UNIX;
614 #else
615             goto not_there;
616 #endif
617         if (strEQ(name, "PF_UNSPEC"))
618 #ifdef PF_UNSPEC
619             return PF_UNSPEC;
620 #else
621             goto not_there;
622 #endif
623         if (strEQ(name, "PF_X25"))
624 #ifdef PF_X25
625             return PF_X25;
626 #else
627             goto not_there;
628 #endif
629         break;
630     case 'Q':
631         break;
632     case 'R':
633         break;
634     case 'S':
635         if (strEQ(name, "SCM_CONNECT"))
636 #ifdef SCM_CONNECT
637             return SCM_CONNECT;
638 #else
639             goto not_there;
640 #endif
641         if (strEQ(name, "SCM_CREDENTIALS"))
642 #ifdef SCM_CREDENTIALS
643             return SCM_CREDENTIALS;
644 #else
645             goto not_there;
646 #endif
647         if (strEQ(name, "SCM_CREDS"))
648 #ifdef SCM_CREDS
649             return SCM_CREDS;
650 #else
651             goto not_there;
652 #endif
653         if (strEQ(name, "SCM_RIGHTS"))
654 #if defined(SCM_RIGHTS) || defined(HAS_SCM_RIGHTS) /* might be an enum */
655             return SCM_RIGHTS;
656 #else
657             goto not_there;
658 #endif
659         if (strEQ(name, "SCM_TIMESTAMP"))
660 #ifdef SCM_TIMESTAMP
661             return SCM_TIMESTAMP;
662 #else
663             goto not_there;
664 #endif
665         if (strEQ(name, "SHUT_RD"))
666 #ifdef SHUT_RD
667             return SHUT_RD;
668 #else
669             return 0;
670 #endif
671         if (strEQ(name, "SHUT_RDWR"))
672 #ifdef SHUT_RDWR
673             return SHUT_RDWR;
674 #else
675             return 2;
676 #endif
677         if (strEQ(name, "SHUT_WR"))
678 #ifdef SHUT_WR
679             return SHUT_WR;
680 #else
681             return 1;
682 #endif
683         if (strEQ(name, "SOCK_DGRAM"))
684 #ifdef SOCK_DGRAM
685             return SOCK_DGRAM;
686 #else
687             goto not_there;
688 #endif
689         if (strEQ(name, "SOCK_RAW"))
690 #ifdef SOCK_RAW
691             return SOCK_RAW;
692 #else
693             goto not_there;
694 #endif
695         if (strEQ(name, "SOCK_RDM"))
696 #ifdef SOCK_RDM
697             return SOCK_RDM;
698 #else
699             goto not_there;
700 #endif
701         if (strEQ(name, "SOCK_SEQPACKET"))
702 #ifdef SOCK_SEQPACKET
703             return SOCK_SEQPACKET;
704 #else
705             goto not_there;
706 #endif
707         if (strEQ(name, "SOCK_STREAM"))
708 #ifdef SOCK_STREAM
709             return SOCK_STREAM;
710 #else
711             goto not_there;
712 #endif
713         if (strEQ(name, "SOL_SOCKET"))
714 #ifdef SOL_SOCKET
715             return SOL_SOCKET;
716 #else
717             goto not_there;
718 #endif
719         if (strEQ(name, "SOMAXCONN"))
720 #ifdef SOMAXCONN
721             return SOMAXCONN;
722 #else
723             goto not_there;
724 #endif
725         if (strEQ(name, "SO_ACCEPTCONN"))
726 #ifdef SO_ACCEPTCONN
727             return SO_ACCEPTCONN;
728 #else
729             goto not_there;
730 #endif
731         if (strEQ(name, "SO_BROADCAST"))
732 #ifdef SO_BROADCAST
733             return SO_BROADCAST;
734 #else
735             goto not_there;
736 #endif
737         if (strEQ(name, "SO_DEBUG"))
738 #ifdef SO_DEBUG
739             return SO_DEBUG;
740 #else
741             goto not_there;
742 #endif
743         if (strEQ(name, "SO_DONTLINGER"))
744 #ifdef SO_DONTLINGER
745             return SO_DONTLINGER;
746 #else
747             goto not_there;
748 #endif
749         if (strEQ(name, "SO_DONTROUTE"))
750 #ifdef SO_DONTROUTE
751             return SO_DONTROUTE;
752 #else
753             goto not_there;
754 #endif
755         if (strEQ(name, "SO_ERROR"))
756 #ifdef SO_ERROR
757             return SO_ERROR;
758 #else
759             goto not_there;
760 #endif
761         if (strEQ(name, "SO_KEEPALIVE"))
762 #ifdef SO_KEEPALIVE
763             return SO_KEEPALIVE;
764 #else
765             goto not_there;
766 #endif
767         if (strEQ(name, "SO_LINGER"))
768 #ifdef SO_LINGER
769             return SO_LINGER;
770 #else
771             goto not_there;
772 #endif
773         if (strEQ(name, "SO_OOBINLINE"))
774 #ifdef SO_OOBINLINE
775             return SO_OOBINLINE;
776 #else
777             goto not_there;
778 #endif
779         if (strEQ(name, "SO_RCVBUF"))
780 #ifdef SO_RCVBUF
781             return SO_RCVBUF;
782 #else
783             goto not_there;
784 #endif
785         if (strEQ(name, "SO_RCVLOWAT"))
786 #ifdef SO_RCVLOWAT
787             return SO_RCVLOWAT;
788 #else
789             goto not_there;
790 #endif
791         if (strEQ(name, "SO_RCVTIMEO"))
792 #ifdef SO_RCVTIMEO
793             return SO_RCVTIMEO;
794 #else
795             goto not_there;
796 #endif
797         if (strEQ(name, "SO_REUSEADDR"))
798 #ifdef SO_REUSEADDR
799             return SO_REUSEADDR;
800 #else
801             goto not_there;
802 #endif
803         if (strEQ(name, "SO_REUSEPORT"))
804 #ifdef SO_REUSEPORT
805             return SO_REUSEPORT;
806 #else
807             goto not_there;
808 #endif
809         if (strEQ(name, "SO_SNDBUF"))
810 #ifdef SO_SNDBUF
811             return SO_SNDBUF;
812 #else
813             goto not_there;
814 #endif
815         if (strEQ(name, "SO_SNDLOWAT"))
816 #ifdef SO_SNDLOWAT
817             return SO_SNDLOWAT;
818 #else
819             goto not_there;
820 #endif
821         if (strEQ(name, "SO_SNDTIMEO"))
822 #ifdef SO_SNDTIMEO
823             return SO_SNDTIMEO;
824 #else
825             goto not_there;
826 #endif
827         if (strEQ(name, "SO_TYPE"))
828 #ifdef SO_TYPE
829             return SO_TYPE;
830 #else
831             goto not_there;
832 #endif
833         if (strEQ(name, "SO_USELOOPBACK"))
834 #ifdef SO_USELOOPBACK
835             return SO_USELOOPBACK;
836 #else
837             goto not_there;
838 #endif
839         break;
840     case 'T':
841         if (strEQ(name, "TCP_KEEPALIVE"))
842 #ifdef TCP_KEEPALIVE
843             return TCP_KEEPALIVE;
844 #else
845             goto not_there;
846 #endif
847         if (strEQ(name, "TCP_MAXRT"))
848 #ifdef TCP_MAXRT
849             return TCP_MAXRT;
850 #else
851             goto not_there;
852 #endif
853         if (strEQ(name, "TCP_MAXSEG"))
854 #ifdef TCP_MAXSEG
855             return TCP_MAXSEG;
856 #else
857             goto not_there;
858 #endif
859         if (strEQ(name, "TCP_NODELAY"))
860 #ifdef TCP_NODELAY
861             return TCP_NODELAY;
862 #else
863             goto not_there;
864 #endif
865         if (strEQ(name, "TCP_STDURG"))
866 #ifdef TCP_STDURG
867             return TCP_STDURG;
868 #else
869             goto not_there;
870 #endif
871         break;
872     case 'U':
873         if (strEQ(name, "UIO_MAXIOV"))
874 #ifdef UIO_MAXIOV
875             return UIO_MAXIOV;
876 #else
877             goto not_there;
878 #endif
879         break;
880     case 'V':
881         break;
882     case 'W':
883         break;
884     case 'X':
885         break;
886     case 'Y':
887         break;
888     case 'Z':
889         break;
890     }
891     errno = EINVAL;
892     return 0;
893
894 not_there:
895     errno = ENOENT;
896     return 0;
897 }
898
899
900 MODULE = Socket         PACKAGE = Socket
901
902 double
903 constant(name,arg)
904         char *          name
905         int             arg
906
907
908 void
909 inet_aton(host)
910         char *  host
911         CODE:
912         {
913         struct in_addr ip_address;
914         struct hostent * phe;
915         int ok = inet_aton(host, &ip_address);
916
917         if (!ok && (phe = gethostbyname(host))) {
918                 Copy( phe->h_addr, &ip_address, phe->h_length, char );
919                 ok = 1;
920         }
921
922         ST(0) = sv_newmortal();
923         if (ok) {
924                 sv_setpvn( ST(0), (char *)&ip_address, sizeof ip_address );
925         }
926         }
927
928 void
929 inet_ntoa(ip_address_sv)
930         SV *    ip_address_sv
931         CODE:
932         {
933         STRLEN addrlen;
934         struct in_addr addr;
935         char * addr_str;
936         char * ip_address = SvPV(ip_address_sv,addrlen);
937         if (addrlen != sizeof(addr)) {
938             croak("Bad arg length for %s, length is %d, should be %d",
939                         "Socket::inet_ntoa",
940                         addrlen, sizeof(addr));
941         }
942
943         Copy( ip_address, &addr, sizeof addr, char );
944         addr_str = inet_ntoa(addr);
945
946         ST(0) = sv_2mortal(newSVpvn(addr_str, strlen(addr_str)));
947         }
948
949 void
950 pack_sockaddr_un(pathname)
951         char *  pathname
952         CODE:
953         {
954 #ifdef I_SYS_UN
955         struct sockaddr_un sun_ad; /* fear using sun */
956         STRLEN len;
957
958         Zero( &sun_ad, sizeof sun_ad, char );
959         sun_ad.sun_family = AF_UNIX;
960         len = strlen(pathname);
961         if (len > sizeof(sun_ad.sun_path))
962             len = sizeof(sun_ad.sun_path);
963 #  ifdef OS2    /* Name should start with \socket\ and contain backslashes! */
964         {
965             int off;
966             char *s, *e;
967
968             if (pathname[0] != '/' && pathname[0] != '\\')
969                 croak("Relative UNIX domain socket name '%s' unsupported", pathname);
970             else if (len < 8 
971                      || pathname[7] != '/' && pathname[7] != '\\'
972                      || !strnicmp(pathname + 1, "socket", 6))
973                 off = 7;
974             else
975                 off = 0;                /* Preserve names starting with \socket\ */
976             Copy( "\\socket", sun_ad.sun_path, off, char);
977             Copy( pathname, sun_ad.sun_path + off, len, char );
978
979             s = sun_ad.sun_path + off - 1;
980             e = s + len + 1;
981             while (++s < e)
982                 if (*s = '/')
983                     *s = '\\';
984         }
985 #  else /* !( defined OS2 ) */ 
986         Copy( pathname, sun_ad.sun_path, len, char );
987 #  endif
988         ST(0) = sv_2mortal(newSVpvn((char *)&sun_ad, sizeof sun_ad));
989 #else
990         ST(0) = (SV *) not_here("pack_sockaddr_un");
991 #endif
992         
993         }
994
995 void
996 unpack_sockaddr_un(sun_sv)
997         SV *    sun_sv
998         CODE:
999         {
1000 #ifdef I_SYS_UN
1001         struct sockaddr_un addr;
1002         STRLEN sockaddrlen;
1003         char * sun_ad = SvPV(sun_sv,sockaddrlen);
1004         char * e;
1005
1006         if (sockaddrlen != sizeof(addr)) {
1007             croak("Bad arg length for %s, length is %d, should be %d",
1008                         "Socket::unpack_sockaddr_un",
1009                         sockaddrlen, sizeof(addr));
1010         }
1011
1012         Copy( sun_ad, &addr, sizeof addr, char );
1013
1014         if ( addr.sun_family != AF_UNIX ) {
1015             croak("Bad address family for %s, got %d, should be %d",
1016                         "Socket::unpack_sockaddr_un",
1017                         addr.sun_family,
1018                         AF_UNIX);
1019         }
1020         e = addr.sun_path;
1021         while (*e && e < addr.sun_path + sizeof addr.sun_path)
1022             ++e;
1023         ST(0) = sv_2mortal(newSVpvn(addr.sun_path, e - addr.sun_path));
1024 #else
1025         ST(0) = (SV *) not_here("unpack_sockaddr_un");
1026 #endif
1027         }
1028
1029 void
1030 pack_sockaddr_in(port,ip_address)
1031         unsigned short  port
1032         char *  ip_address
1033         CODE:
1034         {
1035         struct sockaddr_in sin;
1036
1037         Zero( &sin, sizeof sin, char );
1038         sin.sin_family = AF_INET;
1039         sin.sin_port = htons(port);
1040         Copy( ip_address, &sin.sin_addr, sizeof sin.sin_addr, char );
1041
1042         ST(0) = sv_2mortal(newSVpvn((char *)&sin, sizeof sin));
1043         }
1044
1045 void
1046 unpack_sockaddr_in(sin_sv)
1047         SV *    sin_sv
1048         PPCODE:
1049         {
1050         STRLEN sockaddrlen;
1051         struct sockaddr_in addr;
1052         unsigned short  port;
1053         struct in_addr  ip_address;
1054         char *  sin = SvPV(sin_sv,sockaddrlen);
1055         if (sockaddrlen != sizeof(addr)) {
1056             croak("Bad arg length for %s, length is %d, should be %d",
1057                         "Socket::unpack_sockaddr_in",
1058                         sockaddrlen, sizeof(addr));
1059         }
1060         Copy( sin, &addr,sizeof addr, char );
1061         if ( addr.sin_family != AF_INET ) {
1062             croak("Bad address family for %s, got %d, should be %d",
1063                         "Socket::unpack_sockaddr_in",
1064                         addr.sin_family,
1065                         AF_INET);
1066         } 
1067         port = ntohs(addr.sin_port);
1068         ip_address = addr.sin_addr;
1069
1070         EXTEND(SP, 2);
1071         PUSHs(sv_2mortal(newSViv((IV) port)));
1072         PUSHs(sv_2mortal(newSVpvn((char *)&ip_address,sizeof ip_address)));
1073         }
1074
1075 void
1076 INADDR_ANY()
1077         CODE:
1078         {
1079         struct in_addr  ip_address;
1080         ip_address.s_addr = htonl(INADDR_ANY);
1081         ST(0) = sv_2mortal(newSVpvn((char *)&ip_address,sizeof ip_address ));
1082         }
1083
1084 void
1085 INADDR_LOOPBACK()
1086         CODE:
1087         {
1088         struct in_addr  ip_address;
1089         ip_address.s_addr = htonl(INADDR_LOOPBACK);
1090         ST(0) = sv_2mortal(newSVpvn((char *)&ip_address,sizeof ip_address));
1091         }
1092
1093 void
1094 INADDR_NONE()
1095         CODE:
1096         {
1097         struct in_addr  ip_address;
1098         ip_address.s_addr = htonl(INADDR_NONE);
1099         ST(0) = sv_2mortal(newSVpvn((char *)&ip_address,sizeof ip_address));
1100         }
1101
1102 void
1103 INADDR_BROADCAST()
1104         CODE:
1105         {
1106         struct in_addr  ip_address;
1107         ip_address.s_addr = htonl(INADDR_BROADCAST);
1108         ST(0) = sv_2mortal(newSVpvn((char *)&ip_address,sizeof ip_address));
1109         }