Pushes the Plan 9 BSD shims into glibc (XCC)
[akaros.git] / tools / compilers / gcc-glibc / glibc-2.19-akaros / sysdeps / akaros / getsrvbynm.c
1 /* 
2  * This file is part of the UCB release of Plan 9. It is subject to the license
3  * terms in the LICENSE file found in the top-level directory of this
4  * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
5  * part of the UCB release of Plan 9, including this file, may be copied,
6  * modified, propagated, or distributed except according to the terms contained
7  * in the LICENSE file.
8  */
9 /* posix */
10 #include <sys/types.h>
11 #include <unistd.h>
12 #include <stdlib.h>
13 #include <stdio.h>
14 #include <fcntl.h>
15 #include <string.h>
16 #include <errno.h>
17 #include <ctype.h>
18
19 /* bsd extensions */
20 #include <sys/uio.h>
21 #include <sys/socket.h>
22 #include <netinet/in.h>
23 #include <netdb.h>
24
25 #include "plan9_sockets.h"
26
27 enum {
28         Nname = 6,
29 };
30
31 /*
32  *  for inet addresses only
33  */
34 struct servent *getservbyname(const char *name, const char *proto)
35 {
36         int i, fd, m, num;
37         char *p;
38         char *bp;
39         int nn, na;
40         static struct servent s;
41         static char buf[1024];
42         static char *nptr[Nname + 1];
43
44         num = 1;
45         for (p = (char *)name; *p; p++)
46                 if (!isdigit(*p))
47                         num = 0;
48
49         s.s_name = 0;
50
51         /* connect to server */
52         fd = open("/net/cs", O_RDWR);
53         if (fd < 0) {
54                 return 0;
55         }
56
57         /* construct the query, always expect an ip# back */
58         if (num)
59                 snprintf(buf, sizeof buf, "!port=%s %s=*", name, proto);
60         else
61                 snprintf(buf, sizeof buf, "!%s=%s port=*", proto, name);
62
63         /* query the server */
64         if (write(fd, buf, strlen(buf)) < 0) {
65                 return 0;
66         }
67         lseek(fd, 0, 0);
68         for (i = 0; i < sizeof(buf) - 1; i += m) {
69                 m = read(fd, buf + i, sizeof(buf) - 1 - i);
70                 if (m <= 0)
71                         break;
72                 buf[i + m++] = ' ';
73         }
74         close(fd);
75         buf[i] = 0;
76
77         /* parse the reply */
78         nn = na = 0;
79         for (bp = buf;;) {
80                 p = strchr(bp, '=');
81                 if (p == 0)
82                         break;
83                 *p++ = 0;
84                 if (strcmp(bp, proto) == 0) {
85                         if (nn < Nname)
86                                 nptr[nn++] = p;
87                 } else if (strcmp(bp, "port") == 0) {
88                         s.s_port = htons(atoi(p));
89                 }
90                 while (*p && *p != ' ')
91                         p++;
92                 if (*p)
93                         *p++ = 0;
94                 bp = p;
95         }
96         if (nn + na == 0)
97                 return 0;
98
99         nptr[nn] = 0;
100         s.s_aliases = nptr;
101         if (s.s_name == 0)
102                 s.s_name = nptr[0];
103
104         return &s;
105 }