OLD | NEW |
1 #include <sys/socket.h> | 1 #include <sys/socket.h> |
2 #include <netinet/in.h> | 2 #include <netinet/in.h> |
3 #include <netdb.h> | 3 #include <netdb.h> |
4 #include <ctype.h> | 4 #include <ctype.h> |
5 #include <string.h> | 5 #include <string.h> |
6 #include <fcntl.h> | 6 #include <fcntl.h> |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include "lookup.h" | 8 #include "lookup.h" |
9 #include "stdio_impl.h" | 9 #include "stdio_impl.h" |
10 | 10 |
11 int __lookup_serv(struct service buf[static MAXSERVS], const char *name, int pro
to, int socktype, int flags) | 11 int __lookup_serv(struct service buf[static MAXSERVS], |
12 { | 12 const char* name, |
13 » char line[128]; | 13 int proto, |
14 » int cnt = 0; | 14 int socktype, |
15 » char *p, *z = ""; | 15 int flags) { |
16 » unsigned long port = 0; | 16 char line[128]; |
| 17 int cnt = 0; |
| 18 char *p, *z = ""; |
| 19 unsigned long port = 0; |
17 | 20 |
18 » switch (socktype) { | 21 switch (socktype) { |
19 » case SOCK_STREAM: | 22 case SOCK_STREAM: |
20 » » switch (proto) { | 23 switch (proto) { |
21 » » case 0: | 24 case 0: |
22 » » » proto = IPPROTO_TCP; | 25 proto = IPPROTO_TCP; |
23 » » case IPPROTO_TCP: | 26 case IPPROTO_TCP: |
24 » » » break; | 27 break; |
25 » » default: | 28 default: |
26 » » » return EAI_SERVICE; | 29 return EAI_SERVICE; |
27 » » } | 30 } |
28 » » break; | 31 break; |
29 » case SOCK_DGRAM: | 32 case SOCK_DGRAM: |
30 » » switch (proto) { | 33 switch (proto) { |
31 » » case 0: | 34 case 0: |
32 » » » proto = IPPROTO_UDP; | 35 proto = IPPROTO_UDP; |
33 » » case IPPROTO_UDP: | 36 case IPPROTO_UDP: |
34 » » » break; | 37 break; |
35 » » default: | 38 default: |
36 » » » return EAI_SERVICE; | 39 return EAI_SERVICE; |
37 » » } | 40 } |
38 » case 0: | 41 case 0: |
39 » » break; | 42 break; |
40 » default: | 43 default: |
41 » » if (name) return EAI_SERVICE; | 44 if (name) |
42 » » buf[0].port = 0; | 45 return EAI_SERVICE; |
43 » » buf[0].proto = proto; | 46 buf[0].port = 0; |
44 » » buf[0].socktype = socktype; | 47 buf[0].proto = proto; |
45 » » return 1; | 48 buf[0].socktype = socktype; |
46 » } | 49 return 1; |
| 50 } |
47 | 51 |
48 » if (name) { | 52 if (name) { |
49 » » if (!*name) return EAI_SERVICE; | 53 if (!*name) |
50 » » port = strtoul(name, &z, 10); | 54 return EAI_SERVICE; |
51 » } | 55 port = strtoul(name, &z, 10); |
52 » if (!*z) { | 56 } |
53 » » if (port > 65535) return EAI_SERVICE; | 57 if (!*z) { |
54 » » if (proto != IPPROTO_UDP) { | 58 if (port > 65535) |
55 » » » buf[cnt].port = port; | 59 return EAI_SERVICE; |
56 » » » buf[cnt].socktype = SOCK_STREAM; | 60 if (proto != IPPROTO_UDP) { |
57 » » » buf[cnt++].proto = IPPROTO_TCP; | 61 buf[cnt].port = port; |
58 » » } | 62 buf[cnt].socktype = SOCK_STREAM; |
59 » » if (proto != IPPROTO_TCP) { | 63 buf[cnt++].proto = IPPROTO_TCP; |
60 » » » buf[cnt].port = port; | 64 } |
61 » » » buf[cnt].socktype = SOCK_DGRAM; | 65 if (proto != IPPROTO_TCP) { |
62 » » » buf[cnt++].proto = IPPROTO_UDP; | 66 buf[cnt].port = port; |
63 » » } | 67 buf[cnt].socktype = SOCK_DGRAM; |
64 » » return cnt; | 68 buf[cnt++].proto = IPPROTO_UDP; |
65 » } | 69 } |
| 70 return cnt; |
| 71 } |
66 | 72 |
67 » if (flags & AI_NUMERICSERV) return EAI_SERVICE; | 73 if (flags & AI_NUMERICSERV) |
| 74 return EAI_SERVICE; |
68 | 75 |
69 » size_t l = strlen(name); | 76 size_t l = strlen(name); |
70 | 77 |
71 » unsigned char _buf[1032]; | 78 unsigned char _buf[1032]; |
72 » FILE _f, *f = __fopen_rb_ca("/etc/services", &_f, _buf, sizeof _buf); | 79 FILE _f, *f = __fopen_rb_ca("/etc/services", &_f, _buf, sizeof _buf); |
73 » if (!f) switch (errno) { | 80 if (!f) |
74 » case ENOENT: | 81 switch (errno) { |
75 » case ENOTDIR: | 82 case ENOENT: |
76 » case EACCES: | 83 case ENOTDIR: |
77 » » return EAI_SERVICE; | 84 case EACCES: |
78 » default: | 85 return EAI_SERVICE; |
79 » » return EAI_SYSTEM; | 86 default: |
80 » } | 87 return EAI_SYSTEM; |
| 88 } |
81 | 89 |
82 » while (fgets(line, sizeof line, f) && cnt < MAXSERVS) { | 90 while (fgets(line, sizeof line, f) && cnt < MAXSERVS) { |
83 » » if ((p=strchr(line, '#'))) *p++='\n', *p=0; | 91 if ((p = strchr(line, '#'))) |
| 92 *p++ = '\n', *p = 0; |
84 | 93 |
85 » » /* Find service name */ | 94 /* Find service name */ |
86 » » for(p=line; (p=strstr(p, name)); p++) { | 95 for (p = line; (p = strstr(p, name)); p++) { |
87 » » » if (p>line && !isspace(p[-1])) continue; | 96 if (p > line && !isspace(p[-1])) |
88 » » » if (p[l] && !isspace(p[l])) continue; | 97 continue; |
89 » » » break; | 98 if (p[l] && !isspace(p[l])) |
90 » » } | 99 continue; |
91 » » if (!p) continue; | 100 break; |
| 101 } |
| 102 if (!p) |
| 103 continue; |
92 | 104 |
93 » » /* Skip past canonical name at beginning of line */ | 105 /* Skip past canonical name at beginning of line */ |
94 » » for (p=line; *p && !isspace(*p); p++); | 106 for (p = line; *p && !isspace(*p); p++) |
| 107 ; |
95 | 108 |
96 » » port = strtoul(p, &z, 10); | 109 port = strtoul(p, &z, 10); |
97 » » if (port > 65535 || z==p) continue; | 110 if (port > 65535 || z == p) |
98 » » if (!strncmp(z, "/udp", 4)) { | 111 continue; |
99 » » » if (proto == IPPROTO_TCP) continue; | 112 if (!strncmp(z, "/udp", 4)) { |
100 » » » buf[cnt].port = port; | 113 if (proto == IPPROTO_TCP) |
101 » » » buf[cnt].socktype = SOCK_DGRAM; | 114 continue; |
102 » » » buf[cnt++].proto = IPPROTO_UDP; | 115 buf[cnt].port = port; |
103 » » } | 116 buf[cnt].socktype = SOCK_DGRAM; |
104 » » if (!strncmp(z, "/tcp", 4)) { | 117 buf[cnt++].proto = IPPROTO_UDP; |
105 » » » if (proto == IPPROTO_UDP) continue; | 118 } |
106 » » » buf[cnt].port = port; | 119 if (!strncmp(z, "/tcp", 4)) { |
107 » » » buf[cnt].socktype = SOCK_STREAM; | 120 if (proto == IPPROTO_UDP) |
108 » » » buf[cnt++].proto = IPPROTO_TCP; | 121 continue; |
109 » » } | 122 buf[cnt].port = port; |
110 » } | 123 buf[cnt].socktype = SOCK_STREAM; |
111 » __fclose_ca(f); | 124 buf[cnt++].proto = IPPROTO_TCP; |
112 » return cnt > 0 ? cnt : EAI_SERVICE; | 125 } |
| 126 } |
| 127 __fclose_ca(f); |
| 128 return cnt > 0 ? cnt : EAI_SERVICE; |
113 } | 129 } |
OLD | NEW |