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