1 #include <sys/socket.h>
2 #include <netinet/in.h>
9 #include "stdio_impl.h"
11 int __lookup_serv(struct service buf
[static MAXSERVS
], const char *name
, int proto
, int socktype
, int flags
)
16 unsigned long port
= 0;
41 if (name
) return EAI_SERVICE
;
44 buf
[0].socktype
= socktype
;
49 if (!*name
) return EAI_SERVICE
;
50 port
= strtoul(name
, &z
, 10);
53 if (port
> 65535) return EAI_SERVICE
;
54 if (proto
!= IPPROTO_UDP
) {
56 buf
[cnt
].socktype
= SOCK_STREAM
;
57 buf
[cnt
++].proto
= IPPROTO_TCP
;
59 if (proto
!= IPPROTO_TCP
) {
61 buf
[cnt
].socktype
= SOCK_DGRAM
;
62 buf
[cnt
++].proto
= IPPROTO_UDP
;
67 if (flags
& AI_NUMERICSERV
) return EAI_NONAME
;
69 size_t l
= strlen(name
);
71 unsigned char _buf
[1032];
72 FILE _f
, *f
= __fopen_rb_ca("/etc/services", &_f
, _buf
, sizeof _buf
);
73 if (!f
) switch (errno
) {
82 while (fgets(line
, sizeof line
, f
) && cnt
< MAXSERVS
) {
83 if ((p
=strchr(line
, '#'))) *p
++='\n', *p
=0;
85 /* Find service name */
86 for(p
=line
; (p
=strstr(p
, name
)); p
++) {
87 if (p
>line
&& !isspace(p
[-1])) continue;
88 if (p
[l
] && !isspace(p
[l
])) continue;
93 /* Skip past canonical name at beginning of line */
94 for (p
=line
; *p
&& !isspace(*p
); p
++);
96 port
= strtoul(p
, &z
, 10);
97 if (port
> 65535 || z
==p
) continue;
98 if (!strncmp(z
, "/udp", 4)) {
99 if (proto
== IPPROTO_TCP
) continue;
100 buf
[cnt
].port
= port
;
101 buf
[cnt
].socktype
= SOCK_DGRAM
;
102 buf
[cnt
++].proto
= IPPROTO_UDP
;
104 if (!strncmp(z
, "/tcp", 4)) {
105 if (proto
== IPPROTO_UDP
) continue;
106 buf
[cnt
].port
= port
;
107 buf
[cnt
].socktype
= SOCK_STREAM
;
108 buf
[cnt
++].proto
= IPPROTO_TCP
;
112 return cnt
> 0 ? cnt
: EAI_SERVICE
;