Patch up holes in realclean target
[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, "SOCK_DGRAM"))
666 #ifdef SOCK_DGRAM
667             return SOCK_DGRAM;
668 #else
669             goto not_there;
670 #endif
671         if (strEQ(name, "SOCK_RAW"))
672 #ifdef SOCK_RAW
673             return SOCK_RAW;
674 #else
675             goto not_there;
676 #endif
677         if (strEQ(name, "SOCK_RDM"))
678 #ifdef SOCK_RDM
679             return SOCK_RDM;
680 #else
681             goto not_there;
682 #endif
683         if (strEQ(name, "SOCK_SEQPACKET"))
684 #ifdef SOCK_SEQPACKET
685             return SOCK_SEQPACKET;
686 #else
687             goto not_there;
688 #endif
689         if (strEQ(name, "SOCK_STREAM"))
690 #ifdef SOCK_STREAM
691             return SOCK_STREAM;
692 #else
693             goto not_there;
694 #endif
695         if (strEQ(name, "SOL_SOCKET"))
696 #ifdef SOL_SOCKET
697             return SOL_SOCKET;
698 #else
699             goto not_there;
700 #endif
701         if (strEQ(name, "SOMAXCONN"))
702 #ifdef SOMAXCONN
703             return SOMAXCONN;
704 #else
705             goto not_there;
706 #endif
707         if (strEQ(name, "SO_ACCEPTCONN"))
708 #ifdef SO_ACCEPTCONN
709             return SO_ACCEPTCONN;
710 #else
711             goto not_there;
712 #endif
713         if (strEQ(name, "SO_BROADCAST"))
714 #ifdef SO_BROADCAST
715             return SO_BROADCAST;
716 #else
717             goto not_there;
718 #endif
719         if (strEQ(name, "SO_DEBUG"))
720 #ifdef SO_DEBUG
721             return SO_DEBUG;
722 #else
723             goto not_there;
724 #endif
725         if (strEQ(name, "SO_DONTLINGER"))
726 #ifdef SO_DONTLINGER
727             return SO_DONTLINGER;
728 #else
729             goto not_there;
730 #endif
731         if (strEQ(name, "SO_DONTROUTE"))
732 #ifdef SO_DONTROUTE
733             return SO_DONTROUTE;
734 #else
735             goto not_there;
736 #endif
737         if (strEQ(name, "SO_ERROR"))
738 #ifdef SO_ERROR
739             return SO_ERROR;
740 #else
741             goto not_there;
742 #endif
743         if (strEQ(name, "SO_KEEPALIVE"))
744 #ifdef SO_KEEPALIVE
745             return SO_KEEPALIVE;
746 #else
747             goto not_there;
748 #endif
749         if (strEQ(name, "SO_LINGER"))
750 #ifdef SO_LINGER
751             return SO_LINGER;
752 #else
753             goto not_there;
754 #endif
755         if (strEQ(name, "SO_OOBINLINE"))
756 #ifdef SO_OOBINLINE
757             return SO_OOBINLINE;
758 #else
759             goto not_there;
760 #endif
761         if (strEQ(name, "SO_RCVBUF"))
762 #ifdef SO_RCVBUF
763             return SO_RCVBUF;
764 #else
765             goto not_there;
766 #endif
767         if (strEQ(name, "SO_RCVLOWAT"))
768 #ifdef SO_RCVLOWAT
769             return SO_RCVLOWAT;
770 #else
771             goto not_there;
772 #endif
773         if (strEQ(name, "SO_RCVTIMEO"))
774 #ifdef SO_RCVTIMEO
775             return SO_RCVTIMEO;
776 #else
777             goto not_there;
778 #endif
779         if (strEQ(name, "SO_REUSEADDR"))
780 #ifdef SO_REUSEADDR
781             return SO_REUSEADDR;
782 #else
783             goto not_there;
784 #endif
785         if (strEQ(name, "SO_REUSEPORT"))
786 #ifdef SO_REUSEPORT
787             return SO_REUSEPORT;
788 #else
789             goto not_there;
790 #endif
791         if (strEQ(name, "SO_SNDBUF"))
792 #ifdef SO_SNDBUF
793             return SO_SNDBUF;
794 #else
795             goto not_there;
796 #endif
797         if (strEQ(name, "SO_SNDLOWAT"))
798 #ifdef SO_SNDLOWAT
799             return SO_SNDLOWAT;
800 #else
801             goto not_there;
802 #endif
803         if (strEQ(name, "SO_SNDTIMEO"))
804 #ifdef SO_SNDTIMEO
805             return SO_SNDTIMEO;
806 #else
807             goto not_there;
808 #endif
809         if (strEQ(name, "SO_TYPE"))
810 #ifdef SO_TYPE
811             return SO_TYPE;
812 #else
813             goto not_there;
814 #endif
815         if (strEQ(name, "SO_USELOOPBACK"))
816 #ifdef SO_USELOOPBACK
817             return SO_USELOOPBACK;
818 #else
819             goto not_there;
820 #endif
821         break;
822     case 'T':
823         if (strEQ(name, "TCP_KEEPALIVE"))
824 #ifdef TCP_KEEPALIVE
825             return TCP_KEEPALIVE;
826 #else
827             goto not_there;
828 #endif
829         if (strEQ(name, "TCP_MAXRT"))
830 #ifdef TCP_MAXRT
831             return TCP_MAXRT;
832 #else
833             goto not_there;
834 #endif
835         if (strEQ(name, "TCP_MAXSEG"))
836 #ifdef TCP_MAXSEG
837             return TCP_MAXSEG;
838 #else
839             goto not_there;
840 #endif
841         if (strEQ(name, "TCP_NODELAY"))
842 #ifdef TCP_NODELAY
843             return TCP_NODELAY;
844 #else
845             goto not_there;
846 #endif
847         if (strEQ(name, "TCP_STDURG"))
848 #ifdef TCP_STDURG
849             return TCP_STDURG;
850 #else
851             goto not_there;
852 #endif
853         break;
854     case 'U':
855         if (strEQ(name, "UIO_MAXIOV"))
856 #ifdef UIO_MAXIOV
857             return UIO_MAXIOV;
858 #else
859             goto not_there;
860 #endif
861         break;
862     case 'V':
863         break;
864     case 'W':
865         break;
866     case 'X':
867         break;
868     case 'Y':
869         break;
870     case 'Z':
871         break;
872     }
873     errno = EINVAL;
874     return 0;
875
876 not_there:
877     errno = ENOENT;
878     return 0;
879 }
880
881
882 MODULE = Socket         PACKAGE = Socket
883
884 double
885 constant(name,arg)
886         char *          name
887         int             arg
888
889
890 void
891 inet_aton(host)
892         char *  host
893         CODE:
894         {
895         struct in_addr ip_address;
896         struct hostent * phe;
897         int ok = inet_aton(host, &ip_address);
898
899         if (!ok && (phe = gethostbyname(host))) {
900                 Copy( phe->h_addr, &ip_address, phe->h_length, char );
901                 ok = 1;
902         }
903
904         ST(0) = sv_newmortal();
905         if (ok) {
906                 sv_setpvn( ST(0), (char *)&ip_address, sizeof ip_address );
907         }
908         }
909
910 void
911 inet_ntoa(ip_address_sv)
912         SV *    ip_address_sv
913         CODE:
914         {
915         STRLEN addrlen;
916         struct in_addr addr;
917         char * addr_str;
918         char * ip_address = SvPV(ip_address_sv,addrlen);
919         if (addrlen != sizeof(addr)) {
920             croak("Bad arg length for %s, length is %d, should be %d",
921                         "Socket::inet_ntoa",
922                         addrlen, sizeof(addr));
923         }
924
925         Copy( ip_address, &addr, sizeof addr, char );
926         addr_str = inet_ntoa(addr);
927
928         ST(0) = sv_2mortal(newSVpvn(addr_str, strlen(addr_str)));
929         }
930
931 void
932 pack_sockaddr_un(pathname)
933         char *  pathname
934         CODE:
935         {
936 #ifdef I_SYS_UN
937         struct sockaddr_un sun_ad; /* fear using sun */
938         STRLEN len;
939
940         Zero( &sun_ad, sizeof sun_ad, char );
941         sun_ad.sun_family = AF_UNIX;
942         len = strlen(pathname);
943         if (len > sizeof(sun_ad.sun_path))
944             len = sizeof(sun_ad.sun_path);
945 #  ifdef OS2    /* Name should start with \socket\ and contain backslashes! */
946         {
947             int off;
948             char *s, *e;
949
950             if (pathname[0] != '/' && pathname[0] != '\\')
951                 croak("Relative UNIX domain socket name '%s' unsupported", pathname);
952             else if (len < 8 
953                      || pathname[7] != '/' && pathname[7] != '\\'
954                      || !strnicmp(pathname + 1, "socket", 6))
955                 off = 7;
956             else
957                 off = 0;                /* Preserve names starting with \socket\ */
958             Copy( "\\socket", sun_ad.sun_path, off, char);
959             Copy( pathname, sun_ad.sun_path + off, len, char );
960
961             s = sun_ad.sun_path + off - 1;
962             e = s + len + 1;
963             while (++s < e)
964                 if (*s = '/')
965                     *s = '\\';
966         }
967 #  else /* !( defined OS2 ) */ 
968         Copy( pathname, sun_ad.sun_path, len, char );
969 #  endif
970         ST(0) = sv_2mortal(newSVpvn((char *)&sun_ad, sizeof sun_ad));
971 #else
972         ST(0) = (SV *) not_here("pack_sockaddr_un");
973 #endif
974         
975         }
976
977 void
978 unpack_sockaddr_un(sun_sv)
979         SV *    sun_sv
980         CODE:
981         {
982 #ifdef I_SYS_UN
983         struct sockaddr_un addr;
984         STRLEN sockaddrlen;
985         char * sun_ad = SvPV(sun_sv,sockaddrlen);
986         char * e;
987
988         if (sockaddrlen != sizeof(addr)) {
989             croak("Bad arg length for %s, length is %d, should be %d",
990                         "Socket::unpack_sockaddr_un",
991                         sockaddrlen, sizeof(addr));
992         }
993
994         Copy( sun_ad, &addr, sizeof addr, char );
995
996         if ( addr.sun_family != AF_UNIX ) {
997             croak("Bad address family for %s, got %d, should be %d",
998                         "Socket::unpack_sockaddr_un",
999                         addr.sun_family,
1000                         AF_UNIX);
1001         }
1002         e = addr.sun_path;
1003         while (*e && e < addr.sun_path + sizeof addr.sun_path)
1004             ++e;
1005         ST(0) = sv_2mortal(newSVpvn(addr.sun_path, e - addr.sun_path));
1006 #else
1007         ST(0) = (SV *) not_here("unpack_sockaddr_un");
1008 #endif
1009         }
1010
1011 void
1012 pack_sockaddr_in(port,ip_address)
1013         unsigned short  port
1014         char *  ip_address
1015         CODE:
1016         {
1017         struct sockaddr_in sin;
1018
1019         Zero( &sin, sizeof sin, char );
1020         sin.sin_family = AF_INET;
1021         sin.sin_port = htons(port);
1022         Copy( ip_address, &sin.sin_addr, sizeof sin.sin_addr, char );
1023
1024         ST(0) = sv_2mortal(newSVpvn((char *)&sin, sizeof sin));
1025         }
1026
1027 void
1028 unpack_sockaddr_in(sin_sv)
1029         SV *    sin_sv
1030         PPCODE:
1031         {
1032         STRLEN sockaddrlen;
1033         struct sockaddr_in addr;
1034         unsigned short  port;
1035         struct in_addr  ip_address;
1036         char *  sin = SvPV(sin_sv,sockaddrlen);
1037         if (sockaddrlen != sizeof(addr)) {
1038             croak("Bad arg length for %s, length is %d, should be %d",
1039                         "Socket::unpack_sockaddr_in",
1040                         sockaddrlen, sizeof(addr));
1041         }
1042         Copy( sin, &addr,sizeof addr, char );
1043         if ( addr.sin_family != AF_INET ) {
1044             croak("Bad address family for %s, got %d, should be %d",
1045                         "Socket::unpack_sockaddr_in",
1046                         addr.sin_family,
1047                         AF_INET);
1048         } 
1049         port = ntohs(addr.sin_port);
1050         ip_address = addr.sin_addr;
1051
1052         EXTEND(SP, 2);
1053         PUSHs(sv_2mortal(newSViv((IV) port)));
1054         PUSHs(sv_2mortal(newSVpvn((char *)&ip_address,sizeof ip_address)));
1055         }
1056
1057 void
1058 INADDR_ANY()
1059         CODE:
1060         {
1061         struct in_addr  ip_address;
1062         ip_address.s_addr = htonl(INADDR_ANY);
1063         ST(0) = sv_2mortal(newSVpvn((char *)&ip_address,sizeof ip_address ));
1064         }
1065
1066 void
1067 INADDR_LOOPBACK()
1068         CODE:
1069         {
1070         struct in_addr  ip_address;
1071         ip_address.s_addr = htonl(INADDR_LOOPBACK);
1072         ST(0) = sv_2mortal(newSVpvn((char *)&ip_address,sizeof ip_address));
1073         }
1074
1075 void
1076 INADDR_NONE()
1077         CODE:
1078         {
1079         struct in_addr  ip_address;
1080         ip_address.s_addr = htonl(INADDR_NONE);
1081         ST(0) = sv_2mortal(newSVpvn((char *)&ip_address,sizeof ip_address));
1082         }
1083
1084 void
1085 INADDR_BROADCAST()
1086         CODE:
1087         {
1088         struct in_addr  ip_address;
1089         ip_address.s_addr = htonl(INADDR_BROADCAST);
1090         ST(0) = sv_2mortal(newSVpvn((char *)&ip_address,sizeof ip_address));
1091         }