akaros/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/getsrvbynm_r.c
<<
>>
Prefs
   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 <sys/plan9_helpers.h>
  26
  27enum {
  28        Nname = 6,
  29};
  30
  31/*
  32 *  for inet addresses only
  33 */
  34int __getservbyname_r(const char *name, const char *proto,
  35                      struct servent *result_buf, char *buf, size_t buflen,
  36                      struct servent **result)
  37{
  38        int i, fd, m, num;
  39        char *p;
  40        char *bp;
  41        int nn, na;
  42        /* This used to be:
  43                static char *nptr[Nname + 1];
  44         * we need to use space in buf for it */
  45        char **nptr;
  46        size_t nptr_sz = sizeof(char *) * (Nname + 1);
  47
  48        if (nptr_sz >= buflen) {
  49                *result = 0;
  50                return -ERANGE;
  51        }
  52        nptr = buf; buf += nptr_sz; buflen -= nptr_sz;
  53
  54        num = 1;
  55        for (p = (char *)name; *p; p++)
  56                if (!isdigit(*p))
  57                        num = 0;
  58
  59        result_buf->s_name = 0;
  60
  61        /* connect to server */
  62        fd = open("/net/cs", O_RDWR);
  63        if (fd < 0) {
  64                *result = 0;
  65                return -errno;
  66        }
  67
  68        /* construct the query, always expect an ip# back */
  69        if (num)
  70                snprintf(buf, sizeof buf, "!port=%s %s=*", name, proto);
  71        else
  72                snprintf(buf, sizeof buf, "!%s=%s port=*", proto, name);
  73
  74        /* query the server */
  75        if (write(fd, buf, strlen(buf)) < 0) {
  76                close(fd);
  77                *result = 0;
  78                return -errno;
  79        }
  80        lseek(fd, 0, 0);
  81        for (i = 0; i < sizeof(buf) - 1; i += m) {
  82                m = read(fd, buf + i, sizeof(buf) - 1 - i);
  83                if (m <= 0)
  84                        break;
  85                buf[i + m++] = ' ';
  86        }
  87        close(fd);
  88        buf[i] = 0;
  89
  90        /* parse the reply */
  91        nn = na = 0;
  92        for (bp = buf;;) {
  93                p = strchr(bp, '=');
  94                if (p == 0)
  95                        break;
  96                *p++ = 0;
  97                if (strcmp(bp, proto) == 0) {
  98                        if (nn < Nname)
  99                                nptr[nn++] = p;
 100                } else if (strcmp(bp, "port") == 0) {
 101                        result_buf->s_port = htons(atoi(p));
 102                }
 103                while (*p && *p != ' ')
 104                        p++;
 105                if (*p)
 106                        *p++ = 0;
 107                bp = p;
 108        }
 109        if (nn + na == 0) {
 110                *result = 0;
 111                return -1;
 112        }
 113
 114        nptr[nn] = 0;
 115        result_buf->s_aliases = nptr;
 116        if (result_buf->s_name == 0)
 117                result_buf->s_name = nptr[0];
 118
 119        *result = result_buf;
 120        return 0;
 121}
 122weak_alias(__getservbyname_r, getservbyname_r);
 123