1 #include <sys/socket.h>
2 #include <netinet/in.h>
10 #include "stdio_impl.h"
12 int __lookup_serv(struct service buf
[static MAXSERVS
], const char *name
, int proto
, int socktype
, int flags
)
17 unsigned long port
= 0;
42 if (name
) return EAI_SERVICE
;
45 buf
[0].socktype
= socktype
;
50 if (!*name
) return EAI_SERVICE
;
51 port
= strtoul(name
, &z
, 10);
54 if (port
> 65535) return EAI_SERVICE
;
55 if (proto
!= IPPROTO_UDP
) {
57 buf
[cnt
].socktype
= SOCK_STREAM
;
58 buf
[cnt
++].proto
= IPPROTO_TCP
;
60 if (proto
!= IPPROTO_TCP
) {
62 buf
[cnt
].socktype
= SOCK_DGRAM
;
63 buf
[cnt
++].proto
= IPPROTO_UDP
;
68 if (flags
& AI_NUMERICSERV
) return EAI_NONAME
;
70 size_t l
= strlen(name
);
72 unsigned char _buf
[1032];
73 FILE _f
, *f
= __fopen_rb_ca("/etc/services", &_f
, _buf
, sizeof _buf
);
74 if (!f
) switch (errno
) {
83 while (fgets(line
, sizeof line
, f
) && cnt
< MAXSERVS
) {
84 if ((p
=strchr(line
, '#'))) *p
++='\n', *p
=0;
86 /* Find service name */
87 for(p
=line
; (p
=strstr(p
, name
)); p
++) {
88 if (p
>line
&& !isspace(p
[-1])) continue;
89 if (p
[l
] && !isspace(p
[l
])) continue;
94 /* Skip past canonical name at beginning of line */
95 for (p
=line
; *p
&& !isspace(*p
); p
++);
97 port
= strtoul(p
, &z
, 10);
98 if (port
> 65535 || z
==p
) continue;
99 if (!strncmp(z
, "/udp", 4)) {
100 if (proto
== IPPROTO_TCP
) continue;
101 buf
[cnt
].port
= port
;
102 buf
[cnt
].socktype
= SOCK_DGRAM
;
103 buf
[cnt
++].proto
= IPPROTO_UDP
;
105 if (!strncmp(z
, "/tcp", 4)) {
106 if (proto
== IPPROTO_UDP
) continue;
107 buf
[cnt
].port
= port
;
108 buf
[cnt
].socktype
= SOCK_STREAM
;
109 buf
[cnt
++].proto
= IPPROTO_TCP
;
113 return cnt
> 0 ? cnt
: EAI_SERVICE
;