OSDN Git Service

fix the domain name length limit checks
[android-x86/external-musl-libc.git] / src / network / lookup_serv.c
1 #include <sys/socket.h>
2 #include <netinet/in.h>
3 #include <netdb.h>
4 #include <ctype.h>
5 #include <string.h>
6 #include <fcntl.h>
7 #include "lookup.h"
8 #include "stdio_impl.h"
9
10 int __lookup_serv(struct service buf[static MAXSERVS], const char *name, int proto, int flags)
11 {
12         char line[128];
13         int cnt = 0;
14         char *p, *z = "";
15         unsigned long port = 0;
16
17         if (name) {
18                 if (!*name) return EAI_SERVICE;
19                 port = strtoul(name, &z, 10);
20         }
21         if (!*z) {
22                 if (port > 65535) return EAI_SERVICE;
23                 if (proto != IPPROTO_UDP) {
24                         buf[cnt].port = port;
25                         buf[cnt++].proto = IPPROTO_TCP;
26                 }
27                 if (proto != IPPROTO_TCP) {
28                         buf[cnt].port = port;
29                         buf[cnt++].proto = IPPROTO_UDP;
30                 }
31                 return cnt;
32         }
33
34         if (flags & AI_NUMERICSERV) return EAI_SERVICE;
35
36         size_t l = strlen(name);
37
38         unsigned char _buf[1032];
39         FILE _f, *f = __fopen_rb_ca("/etc/services", &_f, _buf, sizeof _buf);
40         if (!f) return EAI_SERVICE;
41
42         while (fgets(line, sizeof line, f) && cnt < MAXSERVS) {
43                 if ((p=strchr(line, '#'))) *p++='\n', *p=0;
44
45                 /* Find service name */
46                 for(p=line; (p=strstr(p, name)); p++) {
47                         if (p>line && !isspace(p[-1])) continue;
48                         if (p[l] && !isspace(p[l])) continue;
49                         break;
50                 }
51                 if (!p) continue;
52
53                 /* Skip past canonical name at beginning of line */
54                 for (p=line; *p && !isspace(*p); p++);
55                 if (!p) continue;
56
57                 port = strtoul(p, &z, 10);
58                 if (port > 65535 || z==p) continue;
59                 if (!strncmp(z, "/udp", 4)) {
60                         if (proto == IPPROTO_TCP) continue;
61                         buf[cnt].port = port;
62                         buf[cnt++].proto = IPPROTO_UDP;
63                 }
64                 if (!strncmp(z, "/tcp", 4)) {
65                         if (proto == IPPROTO_UDP) continue;
66                         buf[cnt].port = port;
67                         buf[cnt++].proto = IPPROTO_TCP;
68                 }
69         }
70         __fclose_ca(f);
71         return cnt > 0 ? cnt : EAI_SERVICE;
72 }