[PATCH 2/2] Adds some resolv functionality (XCC)
[akaros.git] / user / bsd / getservbyname.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 "priv.h"
26
27 enum
28 {
29         Nname= 6,
30 };
31
32 /*
33  *  for inet addresses only
34  */
35 struct servent*
36 getservbyname(const char *name, const char *proto)
37 {
38         int i, fd, m, num;
39         char *p;
40         char *bp;
41         int nn, na;
42         static struct servent s;
43         static char buf[1024];
44         static char *nptr[Nname+1];
45
46         num = 1;
47         for(p = (char *)name; *p; p++)
48                 if(!isdigit(*p))
49                         num = 0;
50
51         s.s_name = 0;
52
53         /* connect to server */
54         fd = open("/net/cs", O_RDWR);
55         if(fd < 0){
56                 return 0;
57         }
58
59         /* construct the query, always expect an ip# back */
60         if(num)
61                 snprintf(buf, sizeof buf, "!port=%s %s=*", name, proto);
62         else
63                 snprintf(buf, sizeof buf, "!%s=%s port=*", proto, name);
64
65         /* query the server */
66         if(write(fd, buf, strlen(buf)) < 0){
67                 return 0;
68         }
69         lseek(fd, 0, 0);
70         for(i = 0; i < sizeof(buf)-1; i += m){
71                 m = read(fd, buf+i, sizeof(buf) - 1 - i);
72                 if(m <= 0)
73                         break;
74                 buf[i+m++] = ' ';
75         }
76         close(fd);
77         buf[i] = 0;
78
79         /* parse the reply */
80         nn = na = 0;
81         for(bp = buf;;){
82                 p = strchr(bp, '=');
83                 if(p == 0)
84                         break;
85                 *p++ = 0;
86                 if(strcmp(bp, proto) == 0){
87                         if(nn < Nname)
88                                 nptr[nn++] = p;
89                 } else if(strcmp(bp, "port") == 0){
90                         s.s_port = htons(atoi(p));
91                 }
92                 while(*p && *p != ' ')
93                         p++;
94                 if(*p)
95                         *p++ = 0;
96                 bp = p;
97         }
98         if(nn+na == 0)
99                 return 0;
100
101         nptr[nn] = 0;
102         s.s_aliases = nptr;
103         if(s.s_name == 0)
104                 s.s_name = nptr[0];
105
106         return &s;
107 }