akaros/tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/getprtname_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
  18/* bsd extensions */
  19#include <sys/uio.h>
  20#include <sys/socket.h>
  21#include <netinet/in.h>
  22#include <netdb.h>
  23
  24#include <sys/plan9_helpers.h>
  25
  26enum {
  27        Nname = 6,
  28};
  29
  30int __getprotobyname_r(const char *name, struct protoent *result_buf, char *buf,
  31                       size_t buflen, struct protoent **result)
  32{
  33        int fd, i, m;
  34        char *p, *bp;
  35        int nn, na;
  36        unsigned long x;
  37        /* This used to be:
  38                static char *nptr[Nname + 1];
  39         * we need to use space in buf for it */
  40        char **nptr;
  41        size_t nptr_sz = sizeof(char *) * (Nname + 1);
  42
  43        if (nptr_sz >= buflen) {
  44                *result = 0;
  45                return -ERANGE;
  46        }
  47        nptr = buf; buf += nptr_sz; buflen -= nptr_sz;
  48
  49        /* connect to server */
  50        fd = open("/net/cs", O_RDWR);
  51        if (fd < 0) {
  52                *result = 0;
  53                return -errno;
  54        }
  55
  56        /* construct the query, always expect a protocol# back */
  57        snprintf(buf, sizeof buf, "!protocol=%s ipv4proto=*", name);
  58
  59        /* query the server */
  60        if (write(fd, buf, strlen(buf)) < 0) {
  61                close(fd);
  62                *result = 0;
  63                return -errno;
  64        }
  65        lseek(fd, 0, 0);
  66        for (i = 0; i < sizeof(buf) - 1; i += m) {
  67                m = read(fd, buf + i, sizeof(buf) - 1 - i);
  68                if (m <= 0)
  69                        break;
  70                buf[i + m++] = ' ';
  71        }
  72        close(fd);
  73        buf[i] = 0;
  74
  75        /* parse the reply */
  76        nn = na = 0;
  77        for (bp = buf;;) {
  78                p = strchr(bp, '=');
  79                if (p == 0)
  80                        break;
  81                *p++ = 0;
  82                if (strcmp(bp, "protocol") == 0) {
  83                        if (!nn)
  84                                result_buf->p_name = p;
  85                        if (nn < Nname)
  86                                nptr[nn++] = p;
  87                } else if (strcmp(bp, "ipv4proto") == 0) {
  88                        result_buf->p_proto = atoi(p);
  89                        na++;
  90                }
  91                while (*p && *p != ' ')
  92                        p++;
  93                if (*p)
  94                        *p++ = 0;
  95                bp = p;
  96        }
  97        nptr[nn] = 0;
  98        result_buf->p_aliases = nptr;
  99        if (nn + na == 0) {
 100                *result = 0;
 101                return -1;
 102        }
 103
 104        *result = result_buf;
 105        return 0;
 106}
 107weak_alias(__getprotobyname_r, getprotobyname_r);
 108