diff options
Diffstat (limited to 'mit-pthreads/net')
38 files changed, 5075 insertions, 0 deletions
diff --git a/mit-pthreads/net/GNUmakefile.inc b/mit-pthreads/net/GNUmakefile.inc new file mode 100644 index 00000000000..6b89617f63b --- /dev/null +++ b/mit-pthreads/net/GNUmakefile.inc @@ -0,0 +1,14 @@ +# from: @(#)Makefile.inc 5.21 (Berkeley) 5/24/91 +# $Id$ + +# gen sources +VPATH:= ${VPATH}:${srcdir}/net + +SRCS:= gethostbyaddr.c gethostbyname.c gethostent.c getnetbyaddr.c \ + getnetbyname.c getnetent.c getproto.c getprotoent.c getprotoname.c \ + getservbyname.c getservbyport.c getservent.c herror.c inet_addr.c \ + inet_lnaof.c inet_makeaddr.c inet_netof.c inet_network.c inet_ntoa.c \ + net_internal.c proto_internal.c res_comp.c res_init.c res_internal.c \ + res_mkquery.c res_query.c res_querydomain.c res_search.c res_send.c \ + res_debug.c serv_internal.c $(SRCS) + diff --git a/mit-pthreads/net/Makefile.inc b/mit-pthreads/net/Makefile.inc new file mode 100644 index 00000000000..08be88c808f --- /dev/null +++ b/mit-pthreads/net/Makefile.inc @@ -0,0 +1,13 @@ +# from: @(#)Makefile.inc 5.21 (Berkeley) 5/24/91 +# $Id$ + +# gen sources +.PATH: ${srcdir}/net + +SRCS+= gethostbyaddr.c gethostbyname.c gethostent.c getnetbyaddr.c \ + getnetbyname.c getnetent.c getproto.c getprotoent.c getprotoname.c \ + getservbyname.c getservbyport.c getservent.c herror.c inet_addr.c \ + inet_lnaof.c inet_makeaddr.c inet_netof.c inet_network.c inet_ntoa.c \ + net_internal.c proto_internal.c res_comp.c res_init.c res_internal.c \ + res_mkquery.c res_query.c res_querydomain.c res_search.c res_send.c \ + serv_internal.c gethostname.c diff --git a/mit-pthreads/net/gethostbyaddr.c b/mit-pthreads/net/gethostbyaddr.c new file mode 100644 index 00000000000..f80e47ffd99 --- /dev/null +++ b/mit-pthreads/net/gethostbyaddr.c @@ -0,0 +1,161 @@ +/* + * Copyright (c) 1985, 1988 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)gethostbyaddr.c 6.45 (Berkeley) 2/24/91";*/ +static char *rcsid = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + + +#include <pthread.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <netdb.h> +#include <netinet/in.h> +#include <resolv.h> +#include <netinet/in.h> +#include <errno.h> +#include <sys/socket.h> +#include "res_internal.h" + +static struct hostent *file_find_addr(const char *addr, int len, int type, + struct hostent *result, char *buf, + int bufsize, int *errval); + +struct hostent *gethostbyaddr(const char *addr, int len, int type) +{ + struct res_data *data = _res_init(); + + if (!data) + return NULL; + if (!data->buf) { + data->buf = malloc(sizeof(struct hostent) + HOST_BUFSIZE); + if (!data->buf) { + errno = 0; + data->errval = NO_RECOVERY; + return NULL; + } + } + return gethostbyaddr_r(addr, len, type, (struct hostent *) data->buf, + data->buf + sizeof(struct hostent), HOST_BUFSIZE, + &data->errval); +} + +struct hostent *gethostbyaddr_r(const char *addr, int len, int type, + struct hostent *result, char *buf, int bufsize, + int *errval) +{ + struct res_data *data; + querybuf qbuf; + char lookups[MAXDNSLUS], addrbuf[MAXDNAME], *abuf; + struct hostent *hp; + int n, i; + + /* Default failure condition is not a range error and not recoverable. */ + errno = 0; + *errval = NO_RECOVERY; + + data = _res_init(); + if (!data) + return NULL; + + if (type != AF_INET) + return NULL; + sprintf(addrbuf, "%u.%u.%u.%u.in-addr.arpa", + (unsigned)addr[3] & 0xff, (unsigned)addr[2] & 0xff, + (unsigned)addr[1] & 0xff, (unsigned)addr[0] & 0xff); + + memcpy(lookups, data->state.lookups, sizeof(lookups)); + if (*lookups == 0) + strncpy(lookups, "bf", sizeof(lookups)); + + hp = NULL; + for (i = 0; i < MAXDNSLUS && hp == NULL && lookups[i]; i++) { + switch (lookups[i]) { + case 'b': + + /* Allocate space for a one-item list of addresses. */ + abuf = SP(SP(buf, char *, 2), struct in_addr, 1); + if (abuf > buf + bufsize) { + errno = ERANGE; + return NULL; + } + + /* Perform and parse the query. */ + n = res_query(addrbuf, C_IN, T_PTR, (char *)&qbuf, sizeof(qbuf)); + if (n < 0) + break; + hp = _res_parse_answer(&qbuf, n, 1, result, abuf, + bufsize - (abuf - buf), errval); + if (hp == NULL) + break; + + /* Fill in our own address list. */ + result->h_addrtype = type; + result->h_length = len; + result->h_addr_list = (char **) ALIGN(buf, char *); + result->h_addr_list[0] = ALIGN(&result->h_addr_list[2], + struct in_addr); + result->h_addr_list[1] = NULL; + break; + + case 'f': + hp = file_find_addr(addr, len, type, result, buf, bufsize, errval); + break; + } + } + + return hp; +} + +static struct hostent *file_find_addr(const char *addr, int len, int type, + struct hostent *result, char *buf, + int bufsize, int *errval) +{ + FILE *fp = NULL; + + pthread_mutex_lock(&host_iterate_lock); + sethostent(0); + while ((result = gethostent_r(result, buf, bufsize, errval)) != NULL) { + /* Check the entry against the given address. */ + if (result->h_addrtype == type && + memcmp(result->h_addr, addr, len) == 0) + break; + } + pthread_mutex_unlock(&host_iterate_lock); + if (!result && errno != ERANGE) + *errval = HOST_NOT_FOUND; + return result; +} + diff --git a/mit-pthreads/net/gethostbyname.c b/mit-pthreads/net/gethostbyname.c new file mode 100644 index 00000000000..aaaaf79b31b --- /dev/null +++ b/mit-pthreads/net/gethostbyname.c @@ -0,0 +1,167 @@ +/* + * Copyright (c) 1985, 1988 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)gethostbyname.c 6.45 (Berkeley) 2/24/91";*/ +static char *rcsid = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <netdb.h> +#include <netinet/in.h> +#include <sys/socket.h> +#include <resolv.h> +#include "res_internal.h" + +static struct hostent *fake_hostent(const char *hostname, struct in_addr addr, + struct hostent *result, char *buf, + int bufsize, int *errval); +static struct hostent *file_find_name(const char *name, struct hostent *result, + char *buf, int bufsize, int *errval); + +struct hostent *gethostbyname(const char *hostname) +{ + struct res_data *data = _res_init(); + + if (!data) + return NULL; + if (!data->buf) { + data->buf = malloc(sizeof(struct hostent) + HOST_BUFSIZE); + if (!data->buf) { + errno = 0; + data->errval = NO_RECOVERY; + return NULL; + } + } + return gethostbyname_r(hostname, (struct hostent *) data->buf, + data->buf + sizeof(struct hostent), HOST_BUFSIZE, + &data->errval); +} + +struct hostent *gethostbyname_r(const char *hostname, struct hostent *result, + char *buf, int bufsize, int *errval) +{ + struct in_addr addr; + querybuf qbuf; + const char *p; + int n; + + /* Default failure condition is not a range error and not recoverable. */ + errno = 0; + *errval = NO_RECOVERY; + + /* Check for all-numeric hostname with no trailing dot. */ + if (isdigit(hostname[0])) { + p = hostname; + while (*p && (isdigit(*p) || *p == '.')) + p++; + if (!*p && p[-1] != '.') { + /* Looks like an IP address; convert it. */ + if (inet_aton(hostname, &addr) == -1) { + *errval = HOST_NOT_FOUND; + return NULL; + } + return fake_hostent(hostname, addr, result, buf, bufsize, errval); + } + } + + /* Do the search. */ + n = res_search(hostname, C_IN, T_A, qbuf.buf, sizeof(qbuf)); + if (n >= 0) + return _res_parse_answer(&qbuf, n, 0, result, buf, bufsize, errval); + else if (errno == ECONNREFUSED) + return file_find_name(hostname, result, buf, bufsize, errval); + else + return NULL; +} + +static struct hostent *fake_hostent(const char *hostname, struct in_addr addr, + struct hostent *result, char *buf, + int bufsize, int *errval) +{ + int len = strlen(hostname); + char *name, *addr_ptr; + + if (SP(SP(SP(buf, char, len + 1), addr, 1), char *, 3) > buf + bufsize) { + errno = ERANGE; + return NULL; + } + + /* Copy faked name and address into buffer. */ + strcpy(buf, hostname); + name = buf; + buf = ALIGN(buf + len + 1, addr); + *((struct in_addr *) buf) = addr; + addr_ptr = buf; + buf = ALIGN(buf + sizeof(addr), char *); + ((char **) buf)[0] = addr_ptr; + ((char **) buf)[1] = NULL; + ((char **) buf)[2] = NULL; + + result->h_name = name; + result->h_aliases = ((char **) buf) + 2; + result->h_addrtype = AF_INET; + result->h_length = sizeof(addr); + result->h_addr_list = (char **) buf; + + return result; +} + +static struct hostent *file_find_name(const char *name, struct hostent *result, + char *buf, int bufsize, int *errval) +{ + char **alias; + FILE *fp = NULL; + + pthread_mutex_lock(&host_iterate_lock); + sethostent(0); + while ((result = gethostent_r(result, buf, bufsize, errval)) != NULL) { + /* Check the entry's name and aliases against the given name. */ + if (strcasecmp(result->h_name, name) == 0) + break; + for (alias = result->h_aliases; *alias; alias++) { + if (strcasecmp(*alias, name) == 0) + goto end; /* Josip Gracin */ + } + } +end: + pthread_mutex_unlock(&host_iterate_lock); + if (!result && errno != ERANGE) + *errval = HOST_NOT_FOUND; + return result; +} + diff --git a/mit-pthreads/net/gethostent.c b/mit-pthreads/net/gethostent.c new file mode 100644 index 00000000000..d6feb7aa164 --- /dev/null +++ b/mit-pthreads/net/gethostent.c @@ -0,0 +1,162 @@ +/* + * Copyright (c) 1983 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)gethostent.c 5.8 (Berkeley) 2/24/91";*/ +static char *rcsid = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netdb.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include "res_internal.h" + +static pthread_mutex_t res_file_lock = PTHREAD_MUTEX_INITIALIZER; +static int res_file_stayopen; +static FILE *res_file; + +void sethostent(int stayopen) +{ + pthread_mutex_lock(&res_file_lock); + res_file_stayopen |= stayopen; + if (res_file) + rewind(res_file); + else + res_file = fopen(_PATH_HOSTS, "r"); + pthread_mutex_unlock(&res_file_lock); +} + +void endhostent() +{ + pthread_mutex_lock(&res_file_lock); + if (res_file) + fclose(res_file); + pthread_mutex_unlock(&res_file_lock); +} + +struct hostent *gethostent() +{ + struct res_data *data = _res_init(); + + if (!data) + return NULL; + if (!data->buf) { + data->buf = malloc(sizeof(struct hostent) + HOST_BUFSIZE); + if (!data->buf) { + data->errval = NO_RECOVERY; + return NULL; + } + } + return gethostent_r((struct hostent *) data->buf, + data->buf + sizeof(struct hostent), HOST_BUFSIZE, + &data->errval); +} + +struct hostent *gethostent_r(struct hostent *result, char *buf, int bufsize, + int *errval) +{ + char *p, **alias; + struct in_addr *addr; + int l; + + errno = 0; + pthread_mutex_lock(&res_file_lock); + if (res_file == NULL && (res_file = fopen(_PATH_HOSTS, "r")) == NULL) { + pthread_mutex_unlock(&res_file_lock); + return NULL; + } + while (fgets(buf, bufsize, res_file)) { + if (*buf == '#') + continue; + p = strpbrk(buf, "#\n"); + if (p == NULL) + continue; + l = strlen(buf) + 1; + *p = '\0'; + p = strpbrk(buf, " \t"); + if (p == NULL) + continue; + *p++ = '\0'; + + /* THIS STUFF IS INTERNET SPECIFIC */ + if (SP(SP(SP(buf, char, l), *addr, 1), char *, 3) > buf + bufsize) { + errno = ERANGE; + break; + } + addr = (struct in_addr *) ALIGN(buf + l, struct in_addr); + if (inet_aton(buf, addr) == 0) + continue; + result->h_length = sizeof(*addr); + result->h_addrtype = AF_INET; + result->h_addr_list = (char **) ALIGN(addr + sizeof(*addr), char *); + result->h_addr_list[0] = (char *) addr; + result->h_addr_list[1] = NULL; + result->h_aliases = result->h_addr_list + 2; + while (*p == ' ' || *p == '\t') + p++; + result->h_name = p; + alias = result->h_aliases; + p = strpbrk(p, " \t"); + if (p != NULL) + *p++ = '\0'; + while (p && *p) { + if (*p == ' ' || *p == '\t') { + p++; + continue; + } + if ((char *) &alias[2] > buf + bufsize) { + errno = ERANGE; + break; + } + *alias++ = p; + p = strpbrk(p, " \t"); + if (p != NULL) + *p++ = '\0'; + } + if (p && *p) + break; + *alias = NULL; + pthread_mutex_unlock(&res_file_lock); + return result; + } + + pthread_mutex_unlock(&res_file_lock); + *errval = (errno == ERANGE) ? NO_RECOVERY : 0; + return NULL; +} + diff --git a/mit-pthreads/net/gethostname.c b/mit-pthreads/net/gethostname.c new file mode 100644 index 00000000000..8bec0793296 --- /dev/null +++ b/mit-pthreads/net/gethostname.c @@ -0,0 +1,22 @@ +/* Copyright Abandoned 2000 TCX DataKonsult AB & Monty Program KB & Detron HB + This file is public domain and comes with NO WARRANTY of any kind */ + +#include "config.h" +#include <pthread.h> +#include <sys/utsname.h> + +#ifdef HAVE_SYSCALL_UNAME +int gethostname(char *name, int len) +{ + int ret; + struct utsname buf; + + if ((ret = machdep_sys_chroot(&buf)) < OK) + { + SET_ERRNO(-ret); + } + else + strncpy(name,uname->sysname, len); + return(ret); +} +#endif diff --git a/mit-pthreads/net/getnetbyaddr.c b/mit-pthreads/net/getnetbyaddr.c new file mode 100644 index 00000000000..6fba661c92e --- /dev/null +++ b/mit-pthreads/net/getnetbyaddr.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 1983 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)getnetbyaddr.c 5.7 (Berkeley) 6/1/90";*/ +static char *rcsid = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +#include <stdio.h> +#include <netdb.h> +#include "net_internal.h" + +struct netent *getnetbyaddr(long net, int type) +{ + char *buf = _net_buf(); + + if (!buf) + return NULL; + return getnetbyaddr_r(net, type, (struct netent *) buf, + buf + sizeof(struct netent), NET_BUFSIZE); +} + +struct netent *getnetbyaddr_r(long net, int type, struct netent *result, + char *buf, int bufsize) +{ + pthread_mutex_lock(&net_iterate_lock); + setnetent(0); + while ((result = getnetent_r(result, buf, bufsize)) != NULL) { + if (result->n_addrtype == type && result->n_net == net) + break; + } + pthread_mutex_unlock(&net_iterate_lock); + return result; +} + diff --git a/mit-pthreads/net/getnetbyname.c b/mit-pthreads/net/getnetbyname.c new file mode 100644 index 00000000000..5b044ceb7a7 --- /dev/null +++ b/mit-pthreads/net/getnetbyname.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 1983 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)getnetbyname.c 5.7 (Berkeley) 2/24/91";*/ +static char *rcsid = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +#include <netdb.h> +#include <string.h> +#include "net_internal.h" + +struct netent *getnetbyname(const char *name) +{ + char *buf = _net_buf(); + + if (!buf) + return NULL; + return getnetbyname_r(name, (struct netent *) buf, + buf + sizeof(struct netent), NET_BUFSIZE); +} + +struct netent *getnetbyname_r(const char *name, struct netent *result, + char *buf, int bufsize) +{ + char **alias; + + pthread_mutex_lock(&net_iterate_lock); + setnetent(0); + while ((result = getnetent_r(result, buf, bufsize)) != NULL) { + /* Check the entry's name and aliases against the given name. */ + if (strcmp(result->n_name, name) == 0) + break; + for (alias = result->n_aliases; *alias != 0; alias++) { + if (strcmp(*alias, name) == 0) + break; + } + } + pthread_mutex_unlock(&net_iterate_lock); + return result; +} + diff --git a/mit-pthreads/net/getnetent.c b/mit-pthreads/net/getnetent.c new file mode 100644 index 00000000000..05af0b09159 --- /dev/null +++ b/mit-pthreads/net/getnetent.c @@ -0,0 +1,145 @@ +/* + * Copyright (c) 1983 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)getnetent.c 5.8 (Berkeley) 2/24/91";*/ +static char *rcsid = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <netdb.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include "net_internal.h" + +static pthread_mutex_t net_file_lock = PTHREAD_MUTEX_INITIALIZER; +static int net_file_stayopen; +static FILE *net_file; + +void setnetent(int stayopen) +{ + pthread_mutex_lock(&net_file_lock); + net_file_stayopen |= stayopen; + if (net_file) + rewind(net_file); + else + net_file = fopen(_PATH_NETWORKS, "r"); + pthread_mutex_unlock(&net_file_lock); +} + +void endnetent() +{ + pthread_mutex_lock(&net_file_lock); + if (net_file) + fclose(net_file); + pthread_mutex_unlock(&net_file_lock); +} + +struct netent *getnetent() +{ + char *buf = _net_buf(); + + return getnetent_r((struct netent *) buf, buf + sizeof(struct netent), + NET_BUFSIZE); +} + +struct netent *getnetent_r(struct netent *result, char *buf, int bufsize) +{ + char *p, *q, **alias; + int l; + + errno = 0; + pthread_mutex_lock(&net_file_lock); + if (net_file == NULL && (net_file = fopen(_PATH_NETWORKS, "r")) == NULL) { + pthread_mutex_unlock(&net_file_lock); + return NULL; + } + while (fgets(buf, bufsize, net_file)) { + if (*buf == '#') + continue; + p = strpbrk(buf, "#\n"); + if (p == NULL) + continue; + *p = '\0'; + l = strlen(buf) + 1; + result->n_name = buf; + p = strpbrk(buf, " \t"); + if (p == NULL) + continue; + *p++ = '\0'; + while (*p == ' ' || *p == '\t') + p++; + q = strpbrk(p, " \t"); + if (q != NULL) + *q++ = '\0'; + if (SP(SP(buf, char, l), char *, 1) > buf + bufsize) { + errno = ERANGE; + break; + } + result->n_net = inet_network(p); + result->n_addrtype = AF_INET; + result->n_aliases = (char **) ALIGN(buf + l, char *); + alias = result->n_aliases; + if (q != NULL) { + p = q; + while (p && *p) { + if (*p == ' ' || *p == '\t') { + p++; + continue; + } + if ((char *) &alias[2] > buf + bufsize) { + errno = ERANGE; + break; + } + *alias++ = p; + p = strpbrk(p, " \t"); + if (p != NULL) + *p++ = '\0'; + } + if (p && *p) + break; + } + *alias = NULL; + pthread_mutex_unlock(&net_file_lock); + return result; + } + + pthread_mutex_unlock(&net_file_lock); + return NULL; +} + diff --git a/mit-pthreads/net/getproto.c b/mit-pthreads/net/getproto.c new file mode 100644 index 00000000000..f6313bf1510 --- /dev/null +++ b/mit-pthreads/net/getproto.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 1983 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)getproto.c 5.6 (Berkeley) 6/1/90";*/ +static char *rcsid = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +#include <stdio.h> +#include <netdb.h> +#include "proto_internal.h" + +struct protoent *getprotobynumber(int proto) +{ + char *buf = _proto_buf(); + + if (!buf) + return NULL; + return getprotobynumber_r(proto, (struct protoent *) buf, + buf + sizeof(struct protoent), PROTO_BUFSIZE); +} + +struct protoent *getprotobynumber_r(int proto, struct protoent *result, + char *buf, int bufsize) +{ + pthread_mutex_lock(&proto_iterate_lock); + setprotoent(0); + while ((result = getprotoent_r(result, buf, bufsize)) != NULL) { + if (result->p_proto == proto) + break; + } + pthread_mutex_unlock(&proto_iterate_lock); + return result; +} + diff --git a/mit-pthreads/net/getprotoent.c b/mit-pthreads/net/getprotoent.c new file mode 100644 index 00000000000..8bd8d95ec14 --- /dev/null +++ b/mit-pthreads/net/getprotoent.c @@ -0,0 +1,143 @@ +/* + * Copyright (c) 1983 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)getprotoent.c 5.8 (Berkeley) 2/24/91";*/ +static char *rcsid = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netdb.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include "proto_internal.h" + +static pthread_mutex_t proto_file_lock = PTHREAD_MUTEX_INITIALIZER; +static int proto_file_stayopen; +static FILE *proto_file; + +void setprotoent(int stayopen) +{ + pthread_mutex_lock(&proto_file_lock); + proto_file_stayopen |= stayopen; + if (proto_file) + rewind(proto_file); + else + proto_file = fopen(_PATH_PROTOCOLS, "r"); + pthread_mutex_unlock(&proto_file_lock); +} + +void endprotoent() +{ + pthread_mutex_lock(&proto_file_lock); + if (proto_file) + fclose(proto_file); + pthread_mutex_unlock(&proto_file_lock); +} + +struct protoent *getprotoent() +{ + char *buf = _proto_buf(); + + return getprotoent_r((struct protoent *) buf, + buf + sizeof(struct protoent), PROTO_BUFSIZE); +} + +struct protoent *getprotoent_r(struct protoent *result, char *buf, int bufsize) +{ + char *p, *q, **alias; + int l; + + errno = 0; + pthread_mutex_lock(&proto_file_lock); + if (proto_file == NULL && !(proto_file = fopen(_PATH_PROTOCOLS, "r"))) { + pthread_mutex_unlock(&proto_file_lock); + return NULL; + } + while (fgets(buf, bufsize, proto_file)) { + if (*buf == '#') + continue; + p = strpbrk(buf, "#\n"); + if (p == NULL) + continue; + *p = '\0'; + l = strlen(buf) + 1; + result->p_name = buf; + p = strpbrk(buf, " \t"); + if (p == NULL) + continue; + *p++ = '\0'; + while (*p == ' ' || *p == '\t') + p++; + q = strpbrk(p, " \t"); + if (q != NULL) + *q++ = '\0'; + if (SP(SP(buf, char, l), char *, 1) > buf + bufsize) { + errno = ERANGE; + break; + } + result->p_proto = atoi(p); + result->p_aliases = (char **) ALIGN(buf + l, char *); + alias = result->p_aliases; + if (q != NULL) { + p = q; + while (p && *p) { + if (*p == ' ' || *p == '\t') { + p++; + continue; + } + if ((char *) &alias[2] > buf + bufsize) { + errno = ERANGE; + break; + } + *alias++ = p; + p = strpbrk(p, " \t"); + if (p != NULL) + *p++ = '\0'; + } + if (p && *p) + break; + } + *alias = NULL; + pthread_mutex_unlock(&proto_file_lock); + return result; + } + + pthread_mutex_unlock(&proto_file_lock); + return NULL; +} + diff --git a/mit-pthreads/net/getprotoname.c b/mit-pthreads/net/getprotoname.c new file mode 100644 index 00000000000..7bd7b925091 --- /dev/null +++ b/mit-pthreads/net/getprotoname.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 1983 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)getprotoname.c 5.7 (Berkeley) 2/24/91";*/ +static char *rcsid = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <netdb.h> +#include <string.h> +#include "proto_internal.h" + +struct protoent *getprotobyname(const char *name) +{ + char *buf = _proto_buf(); + + if (!buf) + return NULL; + return getprotobyname_r(name, (struct protoent *) buf, + buf + sizeof(struct protoent), PROTO_BUFSIZE); +} + +struct protoent *getprotobyname_r(const char *name, struct protoent *result, + char *buf, int bufsize) +{ + char **alias; + + pthread_mutex_lock(&proto_iterate_lock); + setprotoent(0); + while ((result = getprotoent_r(result, buf, bufsize)) != NULL) { + /* Check the entry's name and aliases against the given name. */ + if (strcmp(result->p_name, name) == 0) + break; + for (alias = result->p_aliases; *alias != 0; alias++) { + if (strcmp(*alias, name) == 0) + break; + } + } + pthread_mutex_unlock(&proto_iterate_lock); + return result; +} + diff --git a/mit-pthreads/net/getservbyname.c b/mit-pthreads/net/getservbyname.c new file mode 100644 index 00000000000..f482b544fd0 --- /dev/null +++ b/mit-pthreads/net/getservbyname.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 1983 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)getservbyname.c 5.7 (Berkeley) 2/24/91";*/ +static char *rcsid = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +#include <netdb.h> +#include <string.h> +#include "serv_internal.h" + +struct servent *getservbyname(const char *name, const char *proto) +{ + char *buf = _serv_buf(); + + if (!buf) + return NULL; + return getservbyname_r(name, proto, (struct servent *) buf, + buf + sizeof(struct servent), SERV_BUFSIZE); +} + +struct servent *getservbyname_r(const char *name, const char *proto, + struct servent *result, char *buf, int bufsize) +{ + char **alias; + + pthread_mutex_lock(&serv_iterate_lock); + setservent(0); + while ((result = getservent_r(result, buf, bufsize)) != NULL) { + /* Check the entry's name and aliases against the given name. */ + if (strcmp(result->s_name, name) != 0) { + for (alias = result->s_aliases; *alias != NULL; alias++) { + if (strcmp(*alias, name) == 0) + break; + } + if (*alias == NULL) + continue; + } + if (proto == NULL || strcmp(result->s_proto, proto) == 0) + break; + } + pthread_mutex_unlock(&serv_iterate_lock); + return result; +} + diff --git a/mit-pthreads/net/getservbyport.c b/mit-pthreads/net/getservbyport.c new file mode 100644 index 00000000000..e3418212c0b --- /dev/null +++ b/mit-pthreads/net/getservbyport.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) 1983 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)getservbyport.c 5.7 (Berkeley) 2/24/91";*/ +static char *rcsid = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +#include <stdio.h> +#include <netdb.h> +#include <string.h> +#include "serv_internal.h" + +struct servent *getservbyport(int port, const char *proto) +{ + char *buf = _serv_buf(); + + if (!buf) + return NULL; + return getservbyport_r(port, proto, (struct servent *) buf, + buf + sizeof(struct servent), SERV_BUFSIZE); +} + +struct servent *getservbyport_r(int port, const char *proto, + struct servent *result, char *buf, int bufsize) +{ + pthread_mutex_lock(&serv_iterate_lock); + setservent(0); + while ((result = getservent_r(result, buf, bufsize)) != NULL) { + if (result->s_port != port) + continue; + if (proto == NULL || strcmp(result->s_proto, proto) == 0) + break; + } + pthread_mutex_unlock(&serv_iterate_lock); + return result; +} + diff --git a/mit-pthreads/net/getservent.c b/mit-pthreads/net/getservent.c new file mode 100644 index 00000000000..b0a7e039f69 --- /dev/null +++ b/mit-pthreads/net/getservent.c @@ -0,0 +1,146 @@ +/* + * Copyright (c) 1983 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)getservent.c 5.9 (Berkeley) 2/24/91";*/ +static char *rcsid = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netdb.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <errno.h> +#include "serv_internal.h" + +static pthread_mutex_t serv_file_lock = PTHREAD_MUTEX_INITIALIZER; +static int serv_file_stayopen=0; +static FILE *serv_file=NULL; + +void setservent(int stayopen) +{ + pthread_mutex_lock(&serv_file_lock); + serv_file_stayopen |= stayopen; + if (serv_file) + rewind(serv_file); + else + serv_file = fopen(_PATH_SERVICES, "r"); + pthread_mutex_unlock(&serv_file_lock); +} + +void endservent() +{ + pthread_mutex_lock(&serv_file_lock); + if (serv_file) + { + fclose(serv_file); + serv_file=NULL; + } + pthread_mutex_unlock(&serv_file_lock); +} + +struct servent *getservent() +{ + char *buf = _serv_buf(); + + return getservent_r((struct servent *) buf, buf + sizeof(struct servent), + SERV_BUFSIZE); +} + +struct servent *getservent_r(struct servent *result, char *buf, int bufsize) +{ + char *p, *q, **alias; + int l; + + errno = 0; + pthread_mutex_lock(&serv_file_lock); + if (serv_file == NULL && !(serv_file = fopen(_PATH_SERVICES, "r"))) { + pthread_mutex_unlock(&serv_file_lock); + return NULL; + } + while (fgets(buf, bufsize, serv_file)) { + if (*buf == '#') + continue; + p = strpbrk(buf, "#\n"); + if (p == NULL) + continue; + *p = '\0'; + l = strlen(buf) + 1; + result->s_name = buf; + q = strpbrk(buf, " \t"); + if (q == NULL) + continue; + *q++ = '\0'; + while (*q == ' ' || *q == '\t') + q++; + p = strpbrk(q, ",/"); + if (p == NULL) + continue; + *p++ = '\0'; + if (SP(SP(buf, char, l), char *, 1) > buf + bufsize) { + errno = ERANGE; + break; + } + result->s_port = htons((u_short)atoi(q)); + result->s_proto = p; + result->s_aliases = (char **) ALIGN(buf + l, char *); + alias = result->s_aliases; + p = strpbrk(p, " \t"); + if (p != NULL) + *p++ = '\0'; + while (p && *p) { + if (*p == ' ' || *p == '\t') { + p++; + continue; + } + if ((char *) &alias[2] > buf + bufsize) { + errno = ERANGE; + break; + } + *alias++ = p; + p = strpbrk(p, " \t"); + if (p != NULL) + *p++ = '\0'; + } + *alias = NULL; + pthread_mutex_unlock(&serv_file_lock); + return result; + } + + pthread_mutex_unlock(&serv_file_lock); + return NULL; +} + diff --git a/mit-pthreads/net/herror.c b/mit-pthreads/net/herror.c new file mode 100644 index 00000000000..935c8e7ea38 --- /dev/null +++ b/mit-pthreads/net/herror.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 1987 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)herror.c 6.6 (Berkeley) 2/24/91";*/ +static char *rcsid = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +#include <stdio.h> +#include <sys/types.h> +#include <sys/uio.h> +#include <netdb.h> +#include <unistd.h> +#include <string.h> +#include <resolv.h> + +char *h_errlist[] = { + "Error 0", + "Unknown host", /* 1 HOST_NOT_FOUND */ + "Host name lookup failure", /* 2 TRY_AGAIN */ + "Unknown server error", /* 3 NO_RECOVERY */ + "No address associated with name", /* 4 NO_ADDRESS */ +}; +int h_nerr = { sizeof(h_errlist)/sizeof(h_errlist[0]) }; + +/* + * herror -- + * print the error indicated by the h_errno value. + */ +void +herror(s) + const char *s; +{ + struct iovec iov[4]; + register struct iovec *v = iov; + int error = h_errno; + + if (s && *s) { + v->iov_base = (char *)s; + v->iov_len = strlen(s); + v++; + v->iov_base = ": "; + v->iov_len = 2; + v++; + } + v->iov_base = ((unsigned int)(error) < h_nerr) ? + h_errlist[error] : "Unknown error"; + v->iov_len = strlen(v->iov_base); + v++; + v->iov_base = "\n"; + v->iov_len = 1; + writev(STDERR_FILENO, iov, (v - iov) + 1); +} + +char * +hstrerror(err) + int err; +{ + return ((unsigned int)(err) < h_nerr) ? h_errlist[err] + : "Unknown resolver error"; +} + diff --git a/mit-pthreads/net/inet_addr.c b/mit-pthreads/net/inet_addr.c new file mode 100644 index 00000000000..75ca154d4c2 --- /dev/null +++ b/mit-pthreads/net/inet_addr.c @@ -0,0 +1,156 @@ +/* + * Copyright (c) 1983, 1990 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)inet_addr.c 5.10 (Berkeley) 2/24/91";*/ +static char *rcsid = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <sys/param.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <ctype.h> + +#ifndef INADDR_NONE +#define INADDR_NONE 0xffffffff +#endif +/* + * Ascii internet address interpretation routine. + * The value returned is in network order. + */ +pthread_ipaddr_type +inet_addr(cp) + register const char *cp; +{ + struct in_addr val; + + if (inet_aton(cp, &val)) + return (val.s_addr); + return (INADDR_NONE); +} + +/* + * Check whether "cp" is a valid ascii representation + * of an Internet address and convert to a binary address. + * Returns 1 if the address is valid, 0 if not. + * This replaces inet_addr, the return value from which + * cannot distinguish between failure and a local broadcast address. + */ + +inet_aton(cp, addr) + const register char *cp; + struct in_addr *addr; +{ + pthread_ipaddr_type parts[4], *pp = parts; + pthread_ipaddr_type val, base, n; + register char c; + + for (;;) { + /* + * Collect number up to ``.''. + * Values are specified as for C: + * 0x=hex, 0=octal, other=decimal. + */ + val = 0; base = 10; + if (*cp == '0') { + if (*++cp == 'x' || *cp == 'X') + base = 16, cp++; + else + base = 8; + } + while ((c = *cp) != '\0') { + if (isascii(c) && isdigit(c)) { + val = (val * base) + (c - '0'); + cp++; + continue; + } + if (base == 16 && isascii(c) && isxdigit(c)) { + val = (val << 4) + + (c + 10 - (islower(c) ? 'a' : 'A')); + cp++; + continue; + } + break; + } + if (*cp == '.') { + /* + * Internet format: + * a.b.c.d + * a.b.c (with c treated as 16-bits) + * a.b (with b treated as 24 bits) + */ + if (pp >= parts + 3 || val > 0xff) + return (0); + *pp++ = val, cp++; + } else + break; + } + /* + * Check for trailing characters. + */ + if (*cp && (!isascii(*cp) || !isspace(*cp))) + return (0); + /* + * Concoct the address according to + * the number of parts specified. + */ + n = pp - parts + 1; + switch (n) { + + case 1: /* a -- 32 bits */ + break; + + case 2: /* a.b -- 8.24 bits */ + if (val > 0xffffff) + return (0); + val |= parts[0] << 24; + break; + + case 3: /* a.b.c -- 8.8.16 bits */ + if (val > 0xffff) + return (0); + val |= (parts[0] << 24) | (parts[1] << 16); + break; + + case 4: /* a.b.c.d -- 8.8.8.8 bits */ + if (val > 0xff) + return (0); + val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); + break; + } + if (addr) + addr->s_addr = htonl(val); + return (1); +} + diff --git a/mit-pthreads/net/inet_lnaof.c b/mit-pthreads/net/inet_lnaof.c new file mode 100644 index 00000000000..752a5f03f79 --- /dev/null +++ b/mit-pthreads/net/inet_lnaof.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) 1983 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)inet_lnaof.c 5.7 (Berkeley) 2/24/91";*/ +static char *rcsid = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <sys/param.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +/* + * Return the local network address portion of an + * internet address; handles class a/b/c network + * number formats. + */ +pthread_ipaddr_type +inet_lnaof(in) + struct in_addr in; +{ + register pthread_ipaddr_type i = ntohl(in.s_addr); + + if (IN_CLASSA(i)) + return ((i)&IN_CLASSA_HOST); + else if (IN_CLASSB(i)) + return ((i)&IN_CLASSB_HOST); + else + return ((i)&IN_CLASSC_HOST); +} diff --git a/mit-pthreads/net/inet_makeaddr.c b/mit-pthreads/net/inet_makeaddr.c new file mode 100644 index 00000000000..a4995e2b4c4 --- /dev/null +++ b/mit-pthreads/net/inet_makeaddr.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 1983 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)inet_makeaddr.c 5.6 (Berkeley) 2/24/91";*/ +static char *rcsid = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <sys/param.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +/* + * Formulate an Internet address from network + host. Used in + * building addresses stored in the ifnet structure. + */ +struct in_addr +inet_makeaddr(net, host) + pthread_ipaddr_type net, host; +{ + pthread_ipaddr_type addr; + + if (net < 128) + addr = (net << IN_CLASSA_NSHIFT) | (host & IN_CLASSA_HOST); + else if (net < 65536) + addr = (net << IN_CLASSB_NSHIFT) | (host & IN_CLASSB_HOST); + else if (net < 16777216L) + addr = (net << IN_CLASSC_NSHIFT) | (host & IN_CLASSC_HOST); + else + addr = net | host; + addr = htonl(addr); + return (*(struct in_addr *)&addr); +} diff --git a/mit-pthreads/net/inet_netof.c b/mit-pthreads/net/inet_netof.c new file mode 100644 index 00000000000..40d3f4c3385 --- /dev/null +++ b/mit-pthreads/net/inet_netof.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 1983 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)inet_netof.c 5.7 (Berkeley) 2/24/91";*/ +static char *rcsid = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <sys/param.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +/* + * Return the network number from an internet + * address; handles class a/b/c network #'s. + */ +pthread_ipaddr_type +inet_netof(in) + struct in_addr in; +{ + register pthread_ipaddr_type i = ntohl(in.s_addr); + + if (IN_CLASSA(i)) + return (((i)&IN_CLASSA_NET) >> IN_CLASSA_NSHIFT); + else if (IN_CLASSB(i)) + return (((i)&IN_CLASSB_NET) >> IN_CLASSB_NSHIFT); + else + return (((i)&IN_CLASSC_NET) >> IN_CLASSC_NSHIFT); +} diff --git a/mit-pthreads/net/inet_network.c b/mit-pthreads/net/inet_network.c new file mode 100644 index 00000000000..cc0f1b4e603 --- /dev/null +++ b/mit-pthreads/net/inet_network.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 1983 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)inet_network.c 5.8 (Berkeley) 2/24/91";*/ +static char *rcsid = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <ctype.h> + +#ifndef INADDR_NONE +#define INADDR_NONE 0xffffffff +#endif +/* + * Internet network address interpretation routine. + * The library routines call this routine to interpret + * network numbers. + */ +pthread_ipaddr_type +inet_network(cp) + register const char *cp; +{ + pthread_ipaddr_type parts[4], *pp = parts; + pthread_ipaddr_type val, base, n; + register char c; + register int i; + +again: + val = 0; base = 10; + if (*cp == '0') + base = 8, cp++; + if (*cp == 'x' || *cp == 'X') + base = 16, cp++; + while (c = *cp) { + if (isdigit(c)) { + val = (val * base) + (c - '0'); + cp++; + continue; + } + if (base == 16 && isxdigit(c)) { + val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A')); + cp++; + continue; + } + break; + } + if (*cp == '.') { + if (pp >= parts + 4) + return (INADDR_NONE); + *pp++ = val, cp++; + goto again; + } + if (*cp && !isspace(*cp)) + return (INADDR_NONE); + *pp++ = val; + n = pp - parts; + if (n > 4) + return (INADDR_NONE); + for (val = 0, i = 0; i < n; i++) { + val <<= 8; + val |= parts[i] & 0xff; + } + return (val); +} diff --git a/mit-pthreads/net/inet_ntoa.c b/mit-pthreads/net/inet_ntoa.c new file mode 100644 index 00000000000..cd206afcf2a --- /dev/null +++ b/mit-pthreads/net/inet_ntoa.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 1983 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)inet_ntoa.c 5.6 (Berkeley) 2/24/91";*/ +static char *rcsid = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +/* + * Convert network-format internet address + * to base 256 d.d.d.d representation. + */ +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +char *inet_ntoa(struct in_addr in) +{ + static pthread_mutex_t inet_ntoa_mutex = PTHREAD_MUTEX_INITIALIZER; + static pthread_key_t inet_ntoa_key = -1; + char *buf, *inet_ntoa_r(); + + if (inet_ntoa_key < 0) { + pthread_mutex_lock(&inet_ntoa_mutex); + if (inet_ntoa_key < 0) { + if (pthread_key_create(&inet_ntoa_key, free) < 0) { + pthread_mutex_unlock(&inet_ntoa_mutex); + return(NULL); + } + } + pthread_mutex_unlock(&inet_ntoa_mutex); + } + if ((buf = pthread_getspecific(inet_ntoa_key)) == NULL) { + if ((buf = (char *) malloc(18)) == NULL) { + return(NULL); + } + pthread_setspecific(inet_ntoa_key, buf); + } + return inet_ntoa_r(in, buf, 18); +} + +char *inet_ntoa_r(struct in_addr in, char *buf, int bufsize) +{ + register char *p; + + p = (char *)∈ +#define UC(b) (((int)b)&0xff) + (void)snprintf(buf, bufsize, + "%d.%d.%d.%d", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3])); + return (buf); +} + diff --git a/mit-pthreads/net/net_internal.c b/mit-pthreads/net/net_internal.c new file mode 100644 index 00000000000..2c25ff76693 --- /dev/null +++ b/mit-pthreads/net/net_internal.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 1985 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)net_internal.c 6.22 (Berkeley) 3/19/91";*/ +static char *rcsid = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include "net_internal.h" + +static void _net_init_global(void); + +pthread_mutex_t net_iterate_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_once_t init_once = PTHREAD_ONCE_INIT; +static pthread_key_t key; +static int init_status; + +/* Performs global initialization. */ +char *_net_buf() +{ + char *buf; + + /* Make sure the global initializations have been done. */ + pthread_once(&init_once, _net_init_global); + + /* Initialize thread-specific data for this thread if it hasn't + * been done already. */ + buf = (char *) pthread_getspecific(key); + if (!buf) { + buf = (char *) malloc(NET_BUFSIZE); + if (buf == NULL) + return NULL; + if (pthread_setspecific(key, buf) < 0) { + free(buf); + return NULL; + } + } + return buf; +} + +static void _net_init_global() +{ + init_status = pthread_key_create(&key, free); +} + diff --git a/mit-pthreads/net/net_internal.h b/mit-pthreads/net/net_internal.h new file mode 100644 index 00000000000..10ece181a94 --- /dev/null +++ b/mit-pthreads/net/net_internal.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 1985 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)net_internal.h 6.22 (Berkeley) 3/19/91";*/ +static char *rcsid = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +#ifndef _NET_INTERNAL_H +#define _NET_INTERNAL_H + +#include <pthread.h> +#include <netdb.h> +#include <resolv.h> + +#define NET_BUFSIZE 4096 +#define ALIGN(p, t) ((char *)(((((long)(p) - 1) / sizeof(t)) + 1) * sizeof(t))) +#define SP(p, t, n) (ALIGN(p, t) + (n) * sizeof(t)) + +extern pthread_mutex_t net_iterate_lock; + +__BEGIN_DECLS +char *_net_buf(void); +__END_DECLS + +#endif + diff --git a/mit-pthreads/net/proto_internal.c b/mit-pthreads/net/proto_internal.c new file mode 100644 index 00000000000..db3ab04ec77 --- /dev/null +++ b/mit-pthreads/net/proto_internal.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 1985 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)proto_internal.c 6.22 (Berkeley) 3/19/91";*/ +static char *rcsid = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include "proto_internal.h" + +static void _proto_init_global(void); + +pthread_mutex_t proto_iterate_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_once_t init_once = PTHREAD_ONCE_INIT; +static pthread_key_t key; +static int init_status; + +/* Performs global initialization. */ +char *_proto_buf() +{ + char *buf; + + /* Make sure the global initializations have been done. */ + pthread_once(&init_once, _proto_init_global); + + /* Initialize thread-specific data for this thread if it hasn't + * been done already. */ + buf = (char *) pthread_getspecific(key); + if (!buf) { + buf = (char *) malloc(PROTO_BUFSIZE); + if (buf == NULL) + return NULL; + if (pthread_setspecific(key, buf) < 0) { + free(buf); + return NULL; + } + } + return buf; +} + +static void _proto_init_global() +{ + init_status = pthread_key_create(&key, free); +} + diff --git a/mit-pthreads/net/proto_internal.h b/mit-pthreads/net/proto_internal.h new file mode 100644 index 00000000000..d40f77b519e --- /dev/null +++ b/mit-pthreads/net/proto_internal.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 1985 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)proto_internal.h 6.22 (Berkeley) 3/19/91";*/ +static char *rcsid = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +#ifndef _PROTO_INTERNAL_H +#define _PROTO_INTERNAL_H + +#include <pthread.h> +#include <netdb.h> +#include <resolv.h> + +#define PROTO_BUFSIZE 4096 +#define ALIGN(p, t) ((char *)(((((long)(p) - 1) / sizeof(t)) + 1) * sizeof(t))) +#define SP(p, t, n) (ALIGN(p, t) + (n) * sizeof(t)) + +extern pthread_mutex_t proto_iterate_lock; + +__BEGIN_DECLS +char *_proto_buf(void); +__END_DECLS + +#endif + diff --git a/mit-pthreads/net/res_comp.c b/mit-pthreads/net/res_comp.c new file mode 100644 index 00000000000..45a4bcafed2 --- /dev/null +++ b/mit-pthreads/net/res_comp.c @@ -0,0 +1,340 @@ +/* + * Copyright (c) 1985 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)res_comp.c 6.22 (Berkeley) 3/19/91";*/ +static char *rcsid = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <sys/param.h> +#include <sys/cdefs.h> +#include <netinet/in.h> +#include <resolv.h> +#include <stdio.h> + +static dn_find(); + +/* + * Expand compressed domain name 'comp_dn' to full domain name. + * 'msg' is a pointer to the begining of the message, + * 'eomorig' points to the first location after the message, + * 'exp_dn' is a pointer to a buffer of size 'length' for the result. + * Return size of compressed name or -1 if there was an error. + */ +dn_expand(msg, eomorig, comp_dn, exp_dn, length) + const u_char *msg, *eomorig, *comp_dn; + u_char *exp_dn; + int length; +{ + register u_char *cp, *dn; + register int n, c; + u_char *eom; + int len = -1, checked = 0; + + dn = exp_dn; + cp = (u_char *)comp_dn; + eom = exp_dn + length; + /* + * fetch next label in domain name + */ + while (n = *cp++) { + /* + * Check for indirection + */ + switch (n & INDIR_MASK) { + case 0: + if (dn != exp_dn) { + if (dn >= eom) + return (-1); + *dn++ = '.'; + } + if (dn+n >= eom) + return (-1); + checked += n + 1; + while (--n >= 0) { + if ((c = *cp++) == '.') { + if (dn + n + 2 >= eom) + return (-1); + *dn++ = '\\'; + } + *dn++ = c; + if (cp >= eomorig) /* out of range */ + return(-1); + } + break; + + case INDIR_MASK: + if (len < 0) + len = cp - comp_dn + 1; + cp = (u_char *)msg + (((n & 0x3f) << 8) | (*cp & 0xff)); + if (cp < msg || cp >= eomorig) /* out of range */ + return(-1); + checked += 2; + /* + * Check for loops in the compressed name; + * if we've looked at the whole message, + * there must be a loop. + */ + if (checked >= eomorig - msg) + return (-1); + break; + + default: + return (-1); /* flag error */ + } + } + *dn = '\0'; + if (len < 0) + len = cp - comp_dn; + return (len); +} + +/* + * Compress domain name 'exp_dn' into 'comp_dn'. + * Return the size of the compressed name or -1. + * 'length' is the size of the array pointed to by 'comp_dn'. + * 'dnptrs' is a list of pointers to previous compressed names. dnptrs[0] + * is a pointer to the beginning of the message. The list ends with NULL. + * 'lastdnptr' is a pointer to the end of the arrary pointed to + * by 'dnptrs'. Side effect is to update the list of pointers for + * labels inserted into the message as we compress the name. + * If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr' + * is NULL, we don't update the list. + */ +dn_comp(exp_dn, comp_dn, length, dnptrs, lastdnptr) + const u_char *exp_dn; + u_char *comp_dn, **dnptrs, **lastdnptr; + int length; +{ + register u_char *cp, *dn; + register int c, l; + u_char **cpp, **lpp, *sp, *eob; + u_char *msg; + + dn = (u_char *)exp_dn; + cp = comp_dn; + eob = cp + length; + if (dnptrs != NULL) { + if ((msg = *dnptrs++) != NULL) { + for (cpp = dnptrs; *cpp != NULL; cpp++) + ; + lpp = cpp; /* end of list to search */ + } + } else + msg = NULL; + for (c = *dn++; c != '\0'; ) { + /* look to see if we can use pointers */ + if (msg != NULL) { + if ((l = dn_find(dn-1, msg, dnptrs, lpp)) >= 0) { + if (cp+1 >= eob) + return (-1); + *cp++ = (l >> 8) | INDIR_MASK; + *cp++ = l % 256; + return (cp - comp_dn); + } + /* not found, save it */ + if (lastdnptr != NULL && cpp < lastdnptr-1) { + *cpp++ = cp; + *cpp = NULL; + } + } + sp = cp++; /* save ptr to length byte */ + do { + if (c == '.') { + c = *dn++; + break; + } + if (c == '\\') { + if ((c = *dn++) == '\0') + break; + } + if (cp >= eob) { + if (msg != NULL) + *lpp = NULL; + return (-1); + } + *cp++ = c; + } while ((c = *dn++) != '\0'); + /* catch trailing '.'s but not '..' */ + if ((l = cp - sp - 1) == 0 && c == '\0') { + cp--; + break; + } + if (l <= 0 || l > MAXLABEL) { + if (msg != NULL) + *lpp = NULL; + return (-1); + } + *sp = l; + } + if (cp >= eob) { + if (msg != NULL) + *lpp = NULL; + return (-1); + } + *cp++ = '\0'; + return (cp - comp_dn); +} + +/* + * Skip over a compressed domain name. Return the size or -1. + */ +__dn_skipname(comp_dn, eom) + const u_char *comp_dn, *eom; +{ + register u_char *cp; + register int n; + + cp = (u_char *)comp_dn; + while (cp < eom && (n = *cp++)) { + /* + * check for indirection + */ + switch (n & INDIR_MASK) { + case 0: /* normal case, n == len */ + cp += n; + continue; + case INDIR_MASK: /* indirection */ + cp++; + break; + default: /* illegal type */ + return (-1); + } + break; + } + if (cp > eom) + return -1; + return (cp - comp_dn); +} + +/* + * Search for expanded name from a list of previously compressed names. + * Return the offset from msg if found or -1. + * dnptrs is the pointer to the first name on the list, + * not the pointer to the start of the message. + */ +static int +dn_find(exp_dn, msg, dnptrs, lastdnptr) + u_char *exp_dn, *msg; + u_char **dnptrs, **lastdnptr; +{ + register u_char *dn, *cp, **cpp; + register int n; + u_char *sp; + + for (cpp = dnptrs; cpp < lastdnptr; cpp++) { + dn = exp_dn; + sp = cp = *cpp; + while (n = *cp++) { + /* + * check for indirection + */ + switch (n & INDIR_MASK) { + case 0: /* normal case, n == len */ + while (--n >= 0) { + if (*dn == '.') + goto next; + if (*dn == '\\') + dn++; + if (*dn++ != *cp++) + goto next; + } + if ((n = *dn++) == '\0' && *cp == '\0') + return (sp - msg); + if (n == '.') + continue; + goto next; + + default: /* illegal type */ + return (-1); + + case INDIR_MASK: /* indirection */ + cp = msg + (((n & 0x3f) << 8) | *cp); + } + } + if (*dn == '\0') + return (sp - msg); + next: ; + } + return (-1); +} + +/* + * Routines to insert/extract short/long's. Must account for byte + * order and non-alignment problems. This code at least has the + * advantage of being portable. + * + * used by sendmail. + */ + +u_short +_getshort(msgp) + register const u_char *msgp; +{ + register u_short u; + + GETSHORT(u, msgp); + return (u); +} + +pthread_ipaddr_type +_getlong(msgp) + const u_char *msgp; +{ + pthread_ipaddr_type u; + + GETLONG(u, msgp); + return (u); +} + +void +#ifdef __STDC__ +__putshort(register u_short s, register u_char *msgp) +#else + __putshort(s, msgp) + register u_short s; + register u_char *msgp; +#endif +{ + PUTSHORT(s, msgp); +} + +void +__putlong(l, msgp) + register pthread_ipaddr_type l; + register u_char *msgp; +{ + PUTLONG(l, msgp); +} + diff --git a/mit-pthreads/net/res_debug.c b/mit-pthreads/net/res_debug.c new file mode 100644 index 00000000000..3e2084fccf8 --- /dev/null +++ b/mit-pthreads/net/res_debug.c @@ -0,0 +1,749 @@ +/* + * Copyright (c) 1985, 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Portions Copyright (c) 1993 by Digital Equipment Corporation. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies, and that + * the name of Digital Equipment Corporation not be used in advertising or + * publicity pertaining to distribution of the document or software without + * specific, written prior permission. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT + * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93"; +static char rcsid[] = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <sys/param.h> +#include <stdio.h> +#include <string.h> +#include <resolv.h> +#include <arpa/inet.h> + +void __fp_query(); +char *__p_class(), *__p_time(), *__p_type(); +char *p_cdname(), *p_fqname(), *p_rr(); +static char *p_option __P_((u_long)); + +char *_res_opcodes[] = { + "QUERY", + "IQUERY", + "CQUERYM", + "CQUERYU", + "4", + "5", + "6", + "7", + "8", + "UPDATEA", + "UPDATED", + "UPDATEDA", + "UPDATEM", + "UPDATEMA", + "ZONEINIT", + "ZONEREF", +}; + +char *_res_resultcodes[] = { + "NOERROR", + "FORMERR", + "SERVFAIL", + "NXDOMAIN", + "NOTIMP", + "REFUSED", + "6", + "7", + "8", + "9", + "10", + "11", + "12", + "13", + "14", + "NOCHANGE", +}; + +static char retbuf[16]; + +static char * +dewks(wks) + int wks; +{ + switch (wks) { + case 5: return("rje"); + case 7: return("echo"); + case 9: return("discard"); + case 11: return("systat"); + case 13: return("daytime"); + case 15: return("netstat"); + case 17: return("qotd"); + case 19: return("chargen"); + case 20: return("ftp-data"); + case 21: return("ftp"); + case 23: return("telnet"); + case 25: return("smtp"); + case 37: return("time"); + case 39: return("rlp"); + case 42: return("name"); + case 43: return("whois"); + case 53: return("domain"); + case 57: return("apts"); + case 59: return("apfs"); + case 67: return("bootps"); + case 68: return("bootpc"); + case 69: return("tftp"); + case 77: return("rje"); + case 79: return("finger"); + case 87: return("link"); + case 95: return("supdup"); + case 100: return("newacct"); + case 101: return("hostnames"); + case 102: return("iso-tsap"); + case 103: return("x400"); + case 104: return("x400-snd"); + case 105: return("csnet-ns"); + case 109: return("pop-2"); + case 111: return("sunrpc"); + case 113: return("auth"); + case 115: return("sftp"); + case 117: return("uucp-path"); + case 119: return("nntp"); + case 121: return("erpc"); + case 123: return("ntp"); + case 133: return("statsrv"); + case 136: return("profile"); + case 144: return("NeWS"); + case 161: return("snmp"); + case 162: return("snmp-trap"); + case 170: return("print-srv"); + default: (void) sprintf(retbuf, "%d", wks); return(retbuf); + } +} + +static char * +deproto(protonum) + int protonum; +{ + switch (protonum) { + case 1: return("icmp"); + case 2: return("igmp"); + case 3: return("ggp"); + case 5: return("st"); + case 6: return("tcp"); + case 7: return("ucl"); + case 8: return("egp"); + case 9: return("igp"); + case 11: return("nvp-II"); + case 12: return("pup"); + case 16: return("chaos"); + case 17: return("udp"); + default: (void) sprintf(retbuf, "%d", protonum); return(retbuf); + } +} + +static char * +do_rrset(msg, cp, cnt, pflag, file, hs) + int cnt, pflag; + char *cp,*msg, *hs; + FILE *file; +{ + int n; + int sflag; + /* + * Print answer records + */ + sflag = (_res.pfcode & pflag); + if (n = ntohs(cnt)) { + if ((!_res.pfcode) || ((sflag) && (_res.pfcode & RES_PRF_HEAD1))) + fprintf(file, hs); + while (--n >= 0) { + cp = p_rr(cp, msg, file); + if ((cp-msg) > PACKETSZ) + return (NULL); + } + if ((!_res.pfcode) || ((sflag) && (_res.pfcode & RES_PRF_HEAD1))) + putc('\n', file); + } + return(cp); +} + +__p_query(msg) + char *msg; +{ + __fp_query(msg, stdout); +} + +/* + * Print the current options. + * This is intended to be primarily a debugging routine. + */ +void +__fp_resstat(statp, file) + struct __res_state *statp; + FILE *file; +{ + int bit; + + fprintf(file, ";; res options:"); + if (!statp) + statp = &_res; + for (bit = 0; bit < 32; bit++) { /* XXX 32 - bad assumption! */ + if (statp->options & (1<<bit)) + fprintf(file, " %s", p_option(1<<bit)); + } + putc('\n', file); +} + +/* + * Print the contents of a query. + * This is intended to be primarily a debugging routine. + */ +void +__fp_query(msg,file) + char *msg; + FILE *file; +{ + register char *cp; + register HEADER *hp; + register int n; + + /* + * Print header fields. + */ + hp = (HEADER *)msg; + cp = msg + sizeof(HEADER); + if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX) || hp->rcode) { + fprintf(file,";; ->>HEADER<<- opcode: %s, status: %s, id: %d", + _res_opcodes[hp->opcode], + _res_resultcodes[hp->rcode], + ntohs(hp->id)); + putc('\n', file); + } + putc(';', file); + if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD2)) { + fprintf(file,"; flags:"); + if (hp->qr) + fprintf(file," qr"); + if (hp->aa) + fprintf(file," aa"); + if (hp->tc) + fprintf(file," tc"); + if (hp->rd) + fprintf(file," rd"); + if (hp->ra) + fprintf(file," ra"); + if (hp->pr) + fprintf(file," pr"); + } + if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD1)) { + fprintf(file,"; Ques: %d", ntohs(hp->qdcount)); + fprintf(file,", Ans: %d", ntohs(hp->ancount)); + fprintf(file,", Auth: %d", ntohs(hp->nscount)); + fprintf(file,", Addit: %d", ntohs(hp->arcount)); + } +#if 1 + if ((!_res.pfcode) || (_res.pfcode & + (RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1))) { + putc('\n',file); + } +#endif + /* + * Print question records. + */ + if (n = ntohs(hp->qdcount)) { + if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) + fprintf(file,";; QUESTIONS:\n"); + while (--n >= 0) { + fprintf(file,";;\t"); + cp = p_cdname(cp, msg, file); + if (cp == NULL) + return; + if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) + fprintf(file, ", type = %s", + __p_type(_getshort(cp))); + cp += sizeof(u_short); + if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) + fprintf(file, ", class = %s\n", + __p_class(_getshort(cp))); + cp += sizeof(u_short); + putc('\n', file); + } + } + /* + * Print authoritative answer records + */ + cp = do_rrset(msg, cp, hp->ancount, RES_PRF_ANS, file, + ";; ANSWERS:\n"); + if (cp == NULL) + return; + + /* + * print name server records + */ + cp = do_rrset(msg, cp, hp->nscount, RES_PRF_AUTH, file, + ";; AUTHORITY RECORDS:\n"); + if (!cp) + return; + + /* + * print additional records + */ + cp = do_rrset(msg, cp, hp->arcount, RES_PRF_ADD, file, + ";; ADDITIONAL RECORDS:\n"); + if (!cp) + return; +} + +char * +p_cdname(cp, msg, file) + char *cp, *msg; + FILE *file; +{ + char name[MAXDNAME]; + int n; + + if ((n = dn_expand((u_char *)msg, (u_char *)cp + MAXCDNAME, + (u_char *)cp, (u_char *)name, sizeof(name))) < 0) + return (NULL); + if (name[0] == '\0') + putc('.', file); + else + fputs(name, file); + return (cp + n); +} + +char * +p_fqname(cp, msg, file) + char *cp, *msg; + FILE *file; +{ + char name[MAXDNAME]; + int n, len; + + if ((n = dn_expand((u_char *)msg, (u_char *)cp + MAXCDNAME, + (u_char *)cp, (u_char *)name, sizeof(name))) < 0) + return (NULL); + if (name[0] == '\0') { + putc('.', file); + } else { + fputs(name, file); + if (name[strlen(name) - 1] != '.') + putc('.', file); + } + return (cp + n); +} + +/* + * Print resource record fields in human readable form. + * + * Removed calls to non-reentrant routines to simplify varifying + * POSIX thread-safe implementations. (mevans). + */ +char * +p_rr(cp, msg, file) + char *cp, *msg; + FILE *file; +{ + int type, class, dlen, n, c; + struct in_addr inaddr; + char *cp1, *cp2; + u_long tmpttl, t; + int lcnt; + char buf[32]; + + if ((cp = p_fqname(cp, msg, file)) == NULL) + return (NULL); /* compression error */ + type = _getshort(cp); + cp += sizeof(u_short); + class = _getshort(cp); + cp += sizeof(u_short); + tmpttl = _getlong(cp); + cp += sizeof(u_long); + dlen = _getshort(cp); + cp += sizeof(u_short); + cp1 = cp; + if ((!_res.pfcode) || (_res.pfcode & RES_PRF_TTLID)) + fprintf(file, "\t%lu", tmpttl); + if ((!_res.pfcode) || (_res.pfcode & RES_PRF_CLASS)) + fprintf(file, "\t%s", __p_class(class)); + fprintf(file, "\t%s", __p_type(type)); + /* + * Print type specific data, if appropriate + */ + switch (type) { + case T_A: + switch (class) { + case C_IN: + case C_HS: + bcopy(cp, (char *)&inaddr, sizeof(inaddr)); + if (dlen == 4) { + fprintf(file,"\t%s", + inet_ntoa_r(inaddr, buf, sizeof(buf))); + cp += dlen; + } else if (dlen == 7) { + char *address; + u_char protocol; + u_short port; + + address = inet_ntoa_r(inaddr, + buf, sizeof(buf)); + cp += sizeof(inaddr); + protocol = *(u_char*)cp; + cp += sizeof(u_char); + port = _getshort(cp); + cp += sizeof(u_short); + fprintf(file, "\t%s\t; proto %d, port %d", + address, protocol, port); + } + break; + default: + cp += dlen; + } + break; + case T_CNAME: + case T_MB: + case T_MG: + case T_MR: + case T_NS: + case T_PTR: + putc('\t', file); + cp = p_fqname(cp, msg, file); + break; + + case T_HINFO: + if (n = *cp++) { + fprintf(file,"\t%.*s", n, cp); + cp += n; + } + if (n = *cp++) { + fprintf(file,"\t%.*s", n, cp); + cp += n; + } + break; + + case T_SOA: + putc('\t', file); + cp = p_fqname(cp, msg, file); /* origin */ + putc(' ', file); + cp = p_fqname(cp, msg, file); /* mail addr */ + fputs(" (\n", file); + t = _getlong(cp); cp += sizeof(u_long); + fprintf(file,"\t\t\t%lu\t; serial\n", t); + t = _getlong(cp); cp += sizeof(u_long); + fprintf(file,"\t\t\t%lu\t; refresh (%s)\n", t, __p_time(t)); + t = _getlong(cp); cp += sizeof(u_long); + fprintf(file,"\t\t\t%lu\t; retry (%s)\n", t, __p_time(t)); + t = _getlong(cp); cp += sizeof(u_long); + fprintf(file,"\t\t\t%lu\t; expire (%s)\n", t, __p_time(t)); + t = _getlong(cp); cp += sizeof(u_long); + fprintf(file,"\t\t\t%lu )\t; minimum (%s)", t, __p_time(t)); + break; + + case T_MX: + case T_AFSDB: + fprintf(file,"\t%d ", _getshort(cp)); + cp += sizeof(u_short); + cp = p_fqname(cp, msg, file); + break; + + case T_TXT: + (void) fputs("\t\"", file); + cp2 = cp1 + dlen; + while (cp < cp2) { + if (n = (unsigned char) *cp++) { + for (c = n; c > 0 && cp < cp2; c--) + if (*cp == '\n') { + (void) putc('\\', file); + (void) putc(*cp++, file); + } else + (void) putc(*cp++, file); + } + } + putc('"', file); + break; + + case T_MINFO: + case T_RP: + putc('\t', file); + cp = p_fqname(cp, msg, file); + putc(' ', file); + cp = p_fqname(cp, msg, file); + break; + + case T_UINFO: + putc('\t', file); + fputs(cp, file); + cp += dlen; + break; + + case T_UID: + case T_GID: + if (dlen == 4) { + fprintf(file,"\t%u", _getlong(cp)); + cp += sizeof(long); + } + break; + + case T_WKS: + if (dlen < sizeof(u_long) + 1) + break; + bcopy(cp, (char *)&inaddr, sizeof(inaddr)); + cp += sizeof(u_long); + fprintf(file, "\t%s %s ( ", + inet_ntoa_r(inaddr, buf, sizeof(buf)), + deproto((int) *cp)); + cp += sizeof(u_char); + n = 0; + lcnt = 0; + while (cp < cp1 + dlen) { + c = *cp++; + do { + if (c & 0200) { + if (lcnt == 0) { + fputs("\n\t\t\t", file); + lcnt = 5; + } + fputs(dewks(n), file); + putc(' ', file); + lcnt--; + } + c <<= 1; + } while (++n & 07); + } + putc(')', file); + break; + +#ifdef ALLOW_T_UNSPEC + case T_UNSPEC: + { + int NumBytes = 8; + char *DataPtr; + int i; + + if (dlen < NumBytes) NumBytes = dlen; + fprintf(file, "\tFirst %d bytes of hex data:", + NumBytes); + for (i = 0, DataPtr = cp; i < NumBytes; i++, DataPtr++) + fprintf(file, " %x", *DataPtr); + cp += dlen; + } + break; +#endif /* ALLOW_T_UNSPEC */ + + default: + fprintf(file,"\t?%d?", type); + cp += dlen; + } +#if 0 + fprintf(file, "\t; dlen=%d, ttl %s\n", dlen, __p_time(tmpttl)); +#else + putc('\n', file); +#endif + if (cp - cp1 != dlen) { + fprintf(file,";; packet size error (found %d, dlen was %d)\n", + cp - cp1, dlen); + cp = NULL; + } + return (cp); +} + +static char nbuf[40]; + +/* + * Return a string for the type + */ +char * +__p_type(type) + int type; +{ + switch (type) { + case T_A: + return("A"); + case T_NS: /* authoritative server */ + return("NS"); + case T_CNAME: /* canonical name */ + return("CNAME"); + case T_SOA: /* start of authority zone */ + return("SOA"); + case T_MB: /* mailbox domain name */ + return("MB"); + case T_MG: /* mail group member */ + return("MG"); + case T_MR: /* mail rename name */ + return("MR"); + case T_NULL: /* null resource record */ + return("NULL"); + case T_WKS: /* well known service */ + return("WKS"); + case T_PTR: /* domain name pointer */ + return("PTR"); + case T_HINFO: /* host information */ + return("HINFO"); + case T_MINFO: /* mailbox information */ + return("MINFO"); + case T_MX: /* mail routing info */ + return("MX"); + case T_TXT: /* text */ + return("TXT"); + case T_RP: /* responsible person */ + return("RP"); + case T_AFSDB: /* AFS cell database */ + return("AFSDB"); + case T_AXFR: /* zone transfer */ + return("AXFR"); + case T_MAILB: /* mail box */ + return("MAILB"); + case T_MAILA: /* mail address */ + return("MAILA"); + case T_ANY: /* matches any type */ + return("ANY"); + case T_UINFO: + return("UINFO"); + case T_UID: + return("UID"); + case T_GID: + return("GID"); +#ifdef ALLOW_T_UNSPEC + case T_UNSPEC: + return("UNSPEC"); +#endif /* ALLOW_T_UNSPEC */ + + default: + (void)sprintf(nbuf, "%d", type); + return(nbuf); + } +} + +/* + * Return a mnemonic for class + */ +char * +__p_class(class) + int class; +{ + + switch (class) { + case C_IN: /* internet class */ + return("IN"); + case C_HS: /* hesiod class */ + return("HS"); + case C_ANY: /* matches any class */ + return("ANY"); + default: + (void)sprintf(nbuf, "%d", class); + return(nbuf); + } +} + +/* + * Return a mnemonic for an option + */ +static char * +p_option(option) + u_long option; +{ + switch (option) { + case RES_INIT: return "init"; + case RES_DEBUG: return "debug"; + case RES_AAONLY: return "aaonly"; + case RES_USEVC: return "usevc"; + case RES_PRIMARY: return "primry"; + case RES_IGNTC: return "igntc"; + case RES_RECURSE: return "recurs"; + case RES_DEFNAMES: return "defnam"; + case RES_STAYOPEN: return "styopn"; + case RES_DNSRCH: return "dnsrch"; + default: sprintf(nbuf, "?0x%x?", option); return nbuf; + } +} + +/* + * Return a mnemonic for a time to live + */ +char * +__p_time(value) + u_long value; +{ + int secs, mins, hours, days; + register char *p; + + if (value == 0) { + strcpy(nbuf, "0 secs"); + return(nbuf); + } + + secs = value % 60; + value /= 60; + mins = value % 60; + value /= 60; + hours = value % 24; + value /= 24; + days = value; + value = 0; + +#define PLURALIZE(x) x, (x == 1) ? "" : "s" + p = nbuf; + if (days) { + (void)sprintf(p, "%d day%s", PLURALIZE(days)); + while (*++p); + } + if (hours) { + if (days) + *p++ = ' '; + (void)sprintf(p, "%d hour%s", PLURALIZE(hours)); + while (*++p); + } + if (mins) { + if (days || hours) + *p++ = ' '; + (void)sprintf(p, "%d min%s", PLURALIZE(mins)); + while (*++p); + } + if (secs || ! (days || hours || mins)) { + if (days || hours || mins) + *p++ = ' '; + (void)sprintf(p, "%d sec%s", PLURALIZE(secs)); + } + return(nbuf); +} diff --git a/mit-pthreads/net/res_init.c b/mit-pthreads/net/res_init.c new file mode 100644 index 00000000000..0a5c944c974 --- /dev/null +++ b/mit-pthreads/net/res_init.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 1985 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)res_init.c 6.22 (Berkeley) 3/19/91";*/ +static char *rcsid = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <resolv.h> +#include <netdb.h> +#include "res_internal.h" + +int res_init() +{ + if (_res_init()) { + return 0; + } else { + /* Due to clever tricks in _res_init(), a check for h_errno will + * return NO_RECOVERY even if the next try at initialization + * succeeds, so it's okay that we can't set an error value here. */ + return -1; + } +} + diff --git a/mit-pthreads/net/res_internal.c b/mit-pthreads/net/res_internal.c new file mode 100644 index 00000000000..4eab65bf5aa --- /dev/null +++ b/mit-pthreads/net/res_internal.c @@ -0,0 +1,576 @@ +/* + * Copyright (c) 1985 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)res_internal.c 6.22 (Berkeley) 3/19/91";*/ +static char *rcsid = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <resolv.h> +#include <netdb.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <string.h> +#include <errno.h> +#include "res_internal.h" + +#define DEFAULT_RETRIES 4 + +pthread_mutex_t host_iterate_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_once_t init_once = PTHREAD_ONCE_INIT; +static pthread_key_t key; +static int init_status; + +static void _res_init_global(void); +static void set_options(const char *options, const char *source); +static pthread_ipaddr_type net_mask(struct in_addr in); +static int qcomp(const void *arg1, const void *arg2); + +static struct __res_state start; +/* We want to define _res for partial binary compatibility with libraries. */ +#undef _res +struct __res_state _res = { + RES_TIMEOUT, /* retransmition time interval */ + 4, /* number of times to retransmit */ + RES_DEFAULT, /* options flags */ + 1, /* number of name servers */ +}; + +struct hostent *_res_parse_answer(querybuf *answer, int anslen, int iquery, + struct hostent *result, char *buf, + int bufsize, int *errval) +{ + struct res_data *data = _res_init(); + register HEADER *hp; + register u_char *cp; + register int n; + u_char *eom; + char *aliases[__NETDB_MAXALIASES], *addrs[__NETDB_MAXADDRS]; + char *bp = buf, **ap = aliases, **hap = addrs; + int type, class, ancount, qdcount, getclass = C_ANY, iquery_done = 0; + + eom = answer->buf + anslen; + /* + * find first satisfactory answer + */ + hp = &answer->hdr; + ancount = ntohs(hp->ancount); + qdcount = ntohs(hp->qdcount); + bp = buf; + cp = answer->buf + sizeof(HEADER); + + /* Read in the hostname if this is an address lookup. */ + if (qdcount) { + if (iquery) { + if ((n = dn_expand((u_char *) answer->buf, + (u_char *) eom, (u_char *) cp, (u_char *) bp, + bufsize - (bp - buf))) < 0) { + *errval = NO_RECOVERY; + return ((struct hostent *) NULL); + } + cp += n + QFIXEDSZ; + result->h_name = bp; + bp += strlen(bp) + 1; + } else { + cp += __dn_skipname(cp, eom) + QFIXEDSZ; + } + while (--qdcount > 0) + cp += __dn_skipname(cp, eom) + QFIXEDSZ; + } else if (iquery) { + *errval = (hp->aa) ? HOST_NOT_FOUND : TRY_AGAIN; + return ((struct hostent *) NULL); + } + + /* Read in the answers. */ + *ap = NULL; + *hap = NULL; + while (--ancount >= 0 && cp < eom) { + if ((n = dn_expand((u_char *) answer->buf, (u_char *) eom, + (u_char *) cp, (u_char *) bp, + bufsize - (bp - buf))) < 0) + break; + cp += n; + type = _getshort(cp); + cp += sizeof(u_short); + class = _getshort(cp); + cp += sizeof(u_short) + sizeof(pthread_ipaddr_type); + n = _getshort(cp); + cp += sizeof(u_short); + if (type == T_CNAME) { + cp += n; + if (ap >= aliases + __NETDB_MAXALIASES - 1) + continue; + *ap++ = bp; + bp += strlen(bp) + 1; + continue; + } + if (iquery && type == T_PTR) { + if ((n = dn_expand((u_char *) answer->buf, (u_char *) eom, + (u_char *) cp, (u_char *) bp, + bufsize - (bp - buf))) < 0) + break; + cp += n; + result->h_name = bp; + bp += strlen(bp) + 1; + iquery_done = 1; + break; + } + if (iquery || type != T_A) { +#ifdef DEBUG_RESOLVER + if (data->state.options & RES_DEBUG) + printf("unexpected answer type %d, size %d\n", + type, n); +#endif + cp += n; + continue; + } + if (hap > addrs) { + if (n != result->h_length) { + cp += n; + continue; + } + if (class != getclass) { + cp += n; + continue; + } + } else { + result->h_length = n; + getclass = class; + result->h_addrtype = (class == C_IN) ? AF_INET : AF_UNSPEC; + if (!iquery) { + result->h_name = bp; + bp += strlen(bp) + 1; + } + } + bp = ALIGN(bp, pthread_ipaddr_type); + if (bp + n >= buf + bufsize) { + errno = ERANGE; + return NULL; + } + memcpy(bp, cp, n); + cp += n; + if (hap >= addrs + __NETDB_MAXADDRS - 1) + continue; + *hap++ = bp; + bp += n; + cp += n; + } + + if (hap > addrs || iquery_done) { + *ap++ = NULL; + *hap++ = NULL; + if (data->state.nsort) + qsort(addrs, hap - addrs, sizeof(struct in_addr), qcomp); + if (SP(bp, char *, (hap - addrs) + (ap - aliases)) > buf + bufsize) { + errno = ERANGE; + return NULL; + } + result->h_addr_list = (char **) ALIGN(bp, char *); + memcpy(result->h_addr_list, addrs, (hap - addrs) * sizeof(char *)); + result->h_aliases = result->h_addr_list + (hap - addrs); + memcpy(result->h_aliases, aliases, (ap - aliases) * sizeof(char *)); + return result; + } else { + *errval = TRY_AGAIN; + return NULL; + } +} + +/* Performs global initialization. */ +struct res_data *_res_init() +{ + struct res_data *data; + + /* Make sure the global initializations have been done. */ + pthread_once(&init_once, _res_init_global); + if (init_status < 0) + return NULL; + + /* Initialize thread-specific data for this thread if it hasn't + * been done already. */ + data = (struct res_data *) pthread_getspecific(key); + if (!data) { + data = (struct res_data *) malloc(sizeof(struct res_data)); + if (data == NULL) + return NULL; + if (pthread_setspecific(key, data) < 0) { + free(data); + return NULL; + } + data->buf = NULL; + data->state = start; + data->errval = NO_RECOVERY; + data->sock = -1; + } + return data; +} + +static void _res_init_global() +{ + int result; + char line[BUFSIZ], buf[BUFSIZ], *domain, *p, *net; + int i, localdomain_set = 0, num_servers = 0, num_sorts = 0; + FILE *fp; + struct in_addr addr; + + /* Assume an error state until we finish. */ + init_status = -1; + + /* Initialize the key for thread-specific data. */ + result = pthread_key_create(&key, free); + if (result < 0) + return; + + /* Initialize starting state. */ + start.retrans = RES_TIMEOUT; + start.retry = DEFAULT_RETRIES; + start.options = RES_DEFAULT; + start.id = 0; + start.nscount = 1; + start.nsaddr.sin_addr.s_addr = INADDR_ANY; + start.nsaddr.sin_family = AF_INET; + start.nsaddr.sin_port = htons(NAMESERVER_PORT); + start.nscount = 1; + start.ndots = 1; + start.pfcode = 0; + strncpy(start.lookups, "f", sizeof(start.lookups)); + + /* Look for a LOCALDOMAIN definition. */ + domain = getenv("LOCALDOMAIN"); + if (domain != NULL) { + strncpy(start.defdname, domain, sizeof(start.defdname)); + domain = start.defdname; + localdomain_set = 1; + + /* Construct a search path from the LOCALDOMAIN value, which is + * a space-separated list of strings. For backwards-compatibility, + * a newline terminates the list. */ + i = 0; + while (*domain && i < MAXDNSRCH) { + start.dnsrch[i] = domain; + while (*domain && !isspace(*domain)) + domain++; + if (!*domain || *domain == '\n') { + *domain = 0; + break; + } + *domain++ = 0; + while (isspace(*domain)) + domain++; + i++; + } + } + + /* Look for a config file and read it in. */ + fp = fopen(_PATH_RESCONF, "r"); + if (fp != NULL) { + strncpy(start.lookups, "bf", sizeof(start.lookups)); + + /* Read in the configuration file. */ + while (fgets(line, sizeof(line), fp)) { + + /* Ignore blank lines and comments. */ + if (*line == ';' || *line == '#' || !*line) + continue; + + if (strncmp(line, "domain", 6) == 0) { + + /* Read in the default domain, and initialize a one- + * element search path. Skip the domain line if we + * already got one from the LOCALDOMAIN environment + * variable. */ + if (localdomain_set) + continue; + + /* Look for the next word in the line. */ + p = line + 6; + while (*p == ' ' || *p == '\t') + p++; + if (!*p || *p == '\n') + continue; + + /* Copy in the domain, and null-terminate it at the + * first tab or newline. */ + strncpy(start.defdname, p, sizeof(start.defdname) - 1); + p = strpbrk(start.defdname, "\t\n"); + if (p) + *p = 0; + + start.dnsrch[0] = start.defdname; + start.dnsrch[1] = NULL; + + } else if (strncmp(line, "lookup", 6) == 0) { + + /* Get a list of lookup types. */ + memset(start.lookups, 0, sizeof(start.lookups)); + + /* Find the next word in the line. */ + p = line + 6; + while (isspace(*p)) + p++; + + i = 0; + while (*p && i < MAXDNSLUS) { + /* Add a lookup type. */ + if (*p == 'y' || *p == 'b' || *p == 'f') + start.lookups[i++] = *p; + + /* Find the next word. */ + while (*p && !isspace(*p)) + p++; + while (isspace(*p)) + p++; + } + + } else if (strncmp(line, "search", 6) == 0) { + + /* Read in a space-separated list of domains to search + * when a name is not fully-qualified. Skip this line + * if the LOCALDOMAIN environment variable was set. */ + if (localdomain_set) + continue; + + /* Look for the next word on the line. */ + p = line + 6; + while (*p == ' ' || *p == '\t') + p++; + if (!*p || *p == '\n') + continue; + + /* Copy the rest of the line into start.defdname. */ + strncpy(start.defdname, p, sizeof(start.defdname) - 1); + domain = start.defdname; + p = strchr(domain, '\n'); + if (*p) + *p = 0; + + /* Construct a search path from the line, which is a + * space-separated list of strings. */ + i = 0; + while (*domain && i < MAXDNSRCH) { + start.dnsrch[i] = domain; + while (*domain && !isspace(*domain)) + domain++; + if (!*domain || *domain == '\n') { + *domain = 0; + break; + } + *domain++ = 0; + while (isspace(*domain)) + domain++; + i++; + } + + } else if (strncmp(line, "nameserver", 10) == 0) { + + /* Add an address to the list of name servers we can + * connect to. */ + + /* Look for the next word in the line. */ + p = line + 10; + while (*p == ' ' || *p == '\t') + p++; + if (*p && *p != '\n' && inet_aton(p, &addr)) { + start.nsaddr_list[num_servers].sin_addr = addr; + start.nsaddr_list[num_servers].sin_family = AF_INET; + start.nsaddr_list[num_servers].sin_port = + htons(NAMESERVER_PORT); + if (++num_servers >= MAXNS) + break; + } + + } else if (strncmp(line, "sortlist", 8) == 0) { + + p = line + 8; + while (num_sorts < MAXRESOLVSORT) { + + /* Find the next word in the line. */ + p = line + 8; + while (*p == ' ' || *p == '\t') + p++; + + /* Read in an IP address and netmask. */ + if (sscanf(p, "%[0-9./]s", buf) != 1) + break; + net = strchr(buf, '/'); + if (net) + *net = 0; + + /* Translate the address into an IP address + * and netmask. */ + if (inet_aton(buf, &addr)) { + start.sort_list[num_sorts].addr = addr; + if (net && inet_aton(net + 1, &addr)) { + start.sort_list[num_sorts].mask = addr.s_addr; + } else { + start.sort_list[num_sorts].mask = + net_mask(start.sort_list[num_sorts].addr); + } + num_sorts++; + } + + /* Skip past this word. */ + if (net) + *net = '/'; + p += strlen(buf); + } + + } + } + fclose(fp); + } + + /* If we don't have a default domain, strip off the first + * component of this machine's domain name, and make a one- + * element search path consisting of the default domain. */ + if (*start.defdname == 0) { + if (gethostname(buf, sizeof(start.defdname) - 1) == 0) { + p = strchr(buf, '.'); + if (p) + strcpy(start.defdname, p + 1); + } + start.dnsrch[0] = start.defdname; + start.dnsrch[1] = NULL; + } + + p = getenv("RES_OPTIONS"); + if (p) + set_options(p, "env"); + + start.options |= RES_INIT; + _res = start; + init_status = 0; +} + +static void set_options(const char *options, const char *source) +{ + const char *p = options; + int i; + + while (*p) { + + /* Skip leading and inner runs of spaces. */ + while (*p == ' ' || *p == '\t') + p++; + + /* Search for and process individual options. */ + if (strncmp(p, "ndots:", 6) == 0) { + i = atoi(p + 6); + start.ndots = (i <= RES_MAXNDOTS) ? i : RES_MAXNDOTS; + } else if (!strncmp(p, "debug", 5)) + start.options |= RES_DEBUG; + else if (!strncmp(p, "usevc", 5)) + start.options |= RES_USEVC; + else if (!strncmp(p, "stayopen", 8)) + start.options |= RES_STAYOPEN; + + /* Skip to next run of spaces */ + while (*p && *p != ' ' && *p != '\t') + p++; + } +} + +static pthread_ipaddr_type net_mask(struct in_addr in) +{ + pthread_ipaddr_type i = ntohl(in.s_addr); + + if (IN_CLASSA(i)) + return htonl(IN_CLASSA_NET); + if (IN_CLASSB(i)) + return htonl(IN_CLASSB_NET); + return htonl(IN_CLASSC_NET); +} + +/* Get the error value for this thread, or NO_RECOVERY if none has been + * successfully set. The screw case to worry about here is if + * __res_init() fails for a resolver routine because it can't allocate + * or set the thread-specific data, and then __res_init() succeeds here. + * Because __res_init() sets errval to NO_RECOVERY after a successful + * initialization, we return NO_RECOVERY in that case, which is correct. */ +int _res_get_error() +{ + struct res_data *data; + + data = _res_init(); + return (data) ? data->errval : NO_RECOVERY; +} + +struct __res_state *_res_status() +{ + struct res_data *data; + + data = _res_init(); + return (data) ? &data->state : NULL; +} + +static int qcomp(const void *arg1, const void *arg2) +{ + const struct in_addr **a1 = (const struct in_addr **) arg1; + const struct in_addr **a2 = (const struct in_addr **) arg2; + struct __res_state *state = _res_status(); + + int pos1, pos2; + + for (pos1 = 0; pos1 < state->nsort; pos1++) { + if (state->sort_list[pos1].addr.s_addr == + ((*a1)->s_addr & state->sort_list[pos1].mask)) + break; + } + for (pos2 = 0; pos2 < state->nsort; pos2++) { + if (state->sort_list[pos2].addr.s_addr == + ((*a2)->s_addr & state->sort_list[pos2].mask)) + break; + } + return pos1 - pos2; +} + +/* + * This routine is for closing the socket if a virtual circuit is used and + * the program wants to close it. We don't use this routine, but libc + * might reference it. + * + * This routine is not expected to be user visible. + */ +void _res_close() +{ + struct res_data *data; + + data = _res_init(); + if (data && data->sock != -1) { + (void) close(data->sock); + data->sock = -1; + } +} diff --git a/mit-pthreads/net/res_internal.h b/mit-pthreads/net/res_internal.h new file mode 100644 index 00000000000..4a4691bab84 --- /dev/null +++ b/mit-pthreads/net/res_internal.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 1985 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)res_internal.h 6.22 (Berkeley) 3/19/91";*/ +static char *rcsid = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +#ifndef _RES_INTERNAL_H +#define _RES_INTERNAL_H + +#include <pthread.h> +#include <netdb.h> +#include <resolv.h> + +#define HOST_BUFSIZE 4096 +#define ALIGN(p, t) ((char *)(((((long)(p) - 1) / sizeof(t)) + 1) * sizeof(t))) +#define SP(p, t, n) (ALIGN(p, t) + (n) * sizeof(t)) + +struct res_data { + char *buf; + struct __res_state state; + int errval; + int sock; +}; + +#if PACKETSZ > 1024 +#define MAXPACKET PACKETSZ +#else +#define MAXPACKET 1024 +#endif + +typedef union { + HEADER hdr; + unsigned char buf[MAXPACKET]; +} querybuf; + +typedef union { + long al; + char ac; +} align; + +extern pthread_mutex_t host_iterate_lock; + +__BEGIN_DECLS +struct hostent *_res_parse_answer(querybuf *answer, int anslen, int iquery, + struct hostent *result, char *buf, + int buflen, int *errval); +void _res_set_error(int val); +struct res_data *_res_init(void); +__END_DECLS + +#endif + diff --git a/mit-pthreads/net/res_mkquery.c b/mit-pthreads/net/res_mkquery.c new file mode 100644 index 00000000000..42f27318368 --- /dev/null +++ b/mit-pthreads/net/res_mkquery.c @@ -0,0 +1,212 @@ +/* + * Copyright (c) 1985 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)res_mkquery.c 6.16 (Berkeley) 3/6/91";*/ +static char *rcsid = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <sys/param.h> +#include <sys/cdefs.h> +#include <netinet/in.h> +#include <resolv.h> +#include <stdio.h> +#include <string.h> + +/* + * Form all types of queries. + * Returns the size of the result or -1. + */ +res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen) + int op; /* opcode of query */ + const char *dname; /* domain name */ + int class, type; /* class and type of query */ + const char *data; /* resource record data */ + int datalen; /* length of data */ + const char *newrr_in; /* new rr for modify or append */ + char *buf; /* buffer to put query */ + int buflen; /* size of buffer */ +{ + register HEADER *hp; + register char *cp; + register int n; + struct rrec *newrr = (struct rrec *) newrr_in; + char *dnptrs[10], **dpp, **lastdnptr; + struct __res_state *_rs; + + /* + * Initialize header fields. + */ + + _rs = _res_status(); + if (!_rs) + return -1; + if ((buf == NULL) || (buflen < sizeof(HEADER))) + return(-1); + memset(buf, 0, sizeof(HEADER)); + hp = (HEADER *) buf; + hp->id = htons(++_rs->id); + hp->opcode = op; + hp->pr = (_rs->options & RES_PRIMARY) != 0; + hp->rd = (_rs->options & RES_RECURSE) != 0; + hp->rcode = NOERROR; + cp = buf + sizeof(HEADER); + buflen -= sizeof(HEADER); + dpp = dnptrs; + *dpp++ = buf; + *dpp++ = NULL; + lastdnptr = dnptrs + sizeof(dnptrs)/sizeof(dnptrs[0]); + /* + * perform opcode specific processing + */ + switch (op) { + case QUERY: + if ((buflen -= QFIXEDSZ) < 0) + return(-1); + if ((n = dn_comp((u_char *)dname, (u_char *)cp, buflen, + (u_char **)dnptrs, (u_char **)lastdnptr)) < 0) + return (-1); + cp += n; + buflen -= n; + __putshort(type, (u_char *)cp); + cp += sizeof(u_short); + __putshort(class, (u_char *)cp); + cp += sizeof(u_short); + hp->qdcount = htons(1); + if (op == QUERY || data == NULL) + break; + /* + * Make an additional record for completion domain. + */ + buflen -= RRFIXEDSZ; + if ((n = dn_comp((u_char *)data, (u_char *)cp, buflen, + (u_char **)dnptrs, (u_char **)lastdnptr)) < 0) + return (-1); + cp += n; + buflen -= n; + __putshort(T_NULL, (u_char *)cp); + cp += sizeof(u_short); + __putshort(class, (u_char *)cp); + cp += sizeof(u_short); + __putlong(0, (u_char *)cp); + cp += sizeof(pthread_ipaddr_type); + __putshort(0, (u_char *)cp); + cp += sizeof(u_short); + hp->arcount = htons(1); + break; + + case IQUERY: + /* + * Initialize answer section + */ + if (buflen < 1 + RRFIXEDSZ + datalen) + return (-1); + *cp++ = '\0'; /* no domain name */ + __putshort(type, (u_char *)cp); + cp += sizeof(u_short); + __putshort(class, (u_char *)cp); + cp += sizeof(u_short); + __putlong(0, (u_char *)cp); + cp += sizeof(pthread_ipaddr_type); + __putshort(datalen, (u_char *)cp); + cp += sizeof(u_short); + if (datalen) { + memcpy(cp, data, datalen); + cp += datalen; + } + hp->ancount = htons(1); + break; + +#ifdef ALLOW_UPDATES + /* + * For UPDATEM/UPDATEMA, do UPDATED/UPDATEDA followed by UPDATEA + * (Record to be modified is followed by its replacement in msg.) + */ + case UPDATEM: + case UPDATEMA: + + case UPDATED: + /* + * The res code for UPDATED and UPDATEDA is the same; user + * calls them differently: specifies data for UPDATED; server + * ignores data if specified for UPDATEDA. + */ + case UPDATEDA: + buflen -= RRFIXEDSZ + datalen; + if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0) + return (-1); + cp += n; + __putshort(type, cp); + cp += sizeof(u_short); + __putshort(class, cp); + cp += sizeof(u_short); + __putlong(0, cp); + cp += sizeof(pthread_ipaddr_type); + __putshort(datalen, cp); + cp += sizeof(u_short); + if (datalen) { + memcpy(cp, data, datalen); + cp += datalen; + } + if ( (op == UPDATED) || (op == UPDATEDA) ) { + hp->ancount = htons(0); + break; + } + /* Else UPDATEM/UPDATEMA, so drop into code for UPDATEA */ + + case UPDATEA: /* Add new resource record */ + buflen -= RRFIXEDSZ + datalen; + if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0) + return (-1); + cp += n; + __putshort(newrr->r_type, cp); + cp += sizeof(u_short); + __putshort(newrr->r_class, cp); + cp += sizeof(u_short); + __putlong(0, cp); + cp += sizeof(pthread_ipaddr_type); + __putshort(newrr->r_size, cp); + cp += sizeof(u_short); + if (newrr->r_size) { + memcpy(cp, newrr->r_data, newrr->r_size); + cp += newrr->r_size; + } + hp->ancount = htons(0); + break; + +#endif /* ALLOW_UPDATES */ + } + return (cp - buf); +} + diff --git a/mit-pthreads/net/res_query.c b/mit-pthreads/net/res_query.c new file mode 100644 index 00000000000..1727e6d1179 --- /dev/null +++ b/mit-pthreads/net/res_query.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 1985 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)res_query.c 6.22 (Berkeley) 3/19/91";*/ +static char *rcsid = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <resolv.h> +#include <netdb.h> +#include "res_internal.h" + +#if PACKETSZ > 1024 +#define MAXPACKET PACKETSZ +#else +#define MAXPACKET 1024 +#endif + +int res_query(char *name, int class, int type, unsigned char *answer, + int anslen) +{ + struct res_data *data; + char buf[MAXPACKET]; + int result; + HEADER *hp; + + data = _res_init(); + if (!data) + return -1; + + /* Make the query. */ + result = res_mkquery(QUERY, name, class, type, NULL, 0, NULL, buf, + sizeof(buf)); + if (result <= 0) { + data->errval = NO_RECOVERY; + return result; + } + + result = res_send(buf, result, (char *) answer, anslen); + if (result < 0) { + data->errval = TRY_AGAIN; + return result; + } + + hp = (HEADER *) answer; + if (hp->rcode == NOERROR && ntohs(hp->ancount) != 0) + return result; + + /* Translate the error code and return. */ + switch(hp->rcode) { + case NOERROR: + data->errval = NO_DATA; + break; + case SERVFAIL: + data->errval = TRY_AGAIN; + break; + case NXDOMAIN: + data->errval = HOST_NOT_FOUND; + break; + default: + data->errval = NO_RECOVERY; + break; + } + return -1; +} + diff --git a/mit-pthreads/net/res_querydomain.c b/mit-pthreads/net/res_querydomain.c new file mode 100644 index 00000000000..31beeb7a62c --- /dev/null +++ b/mit-pthreads/net/res_querydomain.c @@ -0,0 +1,66 @@ +/* + * Copyright (c) 1985 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)res_querydomain.c 6.22 (Berkeley) 3/19/91";*/ +static char *rcsid = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <resolv.h> +#include <string.h> + +/* For backwards compatibility. */ +int res_querydomain(char *name, char *domain, int class, int type, + unsigned char *answer, int anslen) +{ + char buf[2 * MAXDNAME + 2]; + char *longname = buf; + int len; + + if (domain == NULL) { + /* Check for trailing '.'; copy without '.' if present. */ + len = strlen(name); + if (len > 0 && name[len - 1] == '.' && len < sizeof(buf)) { + memcpy(buf, name, len - 1); + buf[len - 1] = '\0'; + } else { + longname = name; + } + } else { + sprintf(buf, "%.*s.%.*s", MAXDNAME, name, MAXDNAME, domain); + } + + return (res_query(longname, class, type, answer, anslen)); +} + diff --git a/mit-pthreads/net/res_search.c b/mit-pthreads/net/res_search.c new file mode 100644 index 00000000000..2c84f0d68f3 --- /dev/null +++ b/mit-pthreads/net/res_search.c @@ -0,0 +1,168 @@ +/* + * Copyright (c) 1985, 1988 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)res_search.c 6.45 (Berkeley) 2/24/91";*/ +static char *rcsid = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <resolv.h> +#include <netdb.h> +#include "res_internal.h" + +static char *search_aliases(const char *name, char *buf, int bufsize); + +int res_search(const char *name, int class, int type, unsigned char *answer, + int anslen) +{ + struct res_data *data; + const char *p; + int num_dots, len, result, no_data = 0, error; + char buf[2 * MAXDNAME + 2], *domain, **dptr, *alias; + + data = _res_init(); + if (!data) + return -1; + + /* Count the dots in name, and get a pointer to the end of name. */ + num_dots = 0; + for (p = name; *p; p++) { + if (*p == '.') + num_dots++; + } + len = p - name; + + /* If there aren't any dots, check to see if name is an alias for + * another host. If so, try the resolved alias as a fully-qualified + * name. */ + alias = search_aliases(name, buf, sizeof(buf)); + if (alias != NULL) + return res_query(alias, class, type, answer, anslen); + + /* If there's a trailing dot, try to strip it off and query the name. */ + if (len > 0 && p[-1] == '.') { + if (len > sizeof(buf)) { + /* It's too long; just query the original name. */ + return res_query(name, class, type, answer, anslen); + } else { + /* Copy the name without the trailing dot and query. */ + memcpy(buf, name, len - 1); + buf[len] = 0; + return res_query(buf, class, type, answer, anslen); + } + } + + if (data->state.options & RES_DNSRCH) { + /* If RES_DNSRCH is set, query all the domains until we get a + * definitive answer. */ + for (dptr = data->state.dnsrch; *dptr; dptr++) { + domain = *dptr; + sprintf(buf, "%.*s.%.*s", MAXDNAME, name, MAXDNAME, domain); + result = res_query(buf, class, type, answer, anslen); + if (result > 0) + return result; + if (data->errval == NO_DATA) + no_data = 1; + else if (data->errval != HOST_NOT_FOUND) + break; + } + } else if (num_dots == 0 && data->state.options & RES_DEFNAMES) { + /* If RES_DEFNAMES is set and there is no dot, query the default + * domain. */ + domain = data->state.defdname; + sprintf(buf, "%.*s.%.%s", MAXDNAME, name, MAXDNAME, domain); + result = res_query(buf, class, type, answer, anslen); + if (result > 0) + return result; + if (data->errval == NO_DATA) + no_data = 1; + } + + /* If all the domain queries failed, try the name as fully-qualified. + * Only do this if there is at least one dot in the name. */ + if (num_dots > 0) { + result = res_query(name, class, type, answer, anslen); + if (result > 0) + return result; + } + + if (no_data) + data->errval = NO_DATA; + + return -1; +} + +static char *search_aliases(const char *name, char *buf, int bufsize) +{ + FILE *fp; + char *filename, *p; + int len; + + filename = getenv("HOSTALIASES"); + if (filename == NULL) + return NULL; + + fp = fopen(filename, "r"); + if (fp == NULL) + return NULL; + + len = strlen(name); + while (fgets(buf, bufsize, fp)) { + + /* Get the first word from the buffer. */ + p = buf; + while (*p && !isspace(*p)) + p++; + if (!*p) + break; + + /* Null-terminate the first word and compare it with the name. */ + *p = 0; + if (strcasecmp(buf, name) != 0) + continue; + + p++; + while (isspace(*p)) + p++; + fclose(fp); + return (*p) ? p : NULL; + } + + fclose(fp); + return NULL; +} + diff --git a/mit-pthreads/net/res_send.c b/mit-pthreads/net/res_send.c new file mode 100644 index 00000000000..84162e8e387 --- /dev/null +++ b/mit-pthreads/net/res_send.c @@ -0,0 +1,313 @@ +/* + * Copyright (c) 1985, 1988 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)res_send.c 6.45 (Berkeley) 2/24/91";*/ +static char *rcsid = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <stdio.h> +#include <errno.h> +#include <resolv.h> +#include <netdb.h> +#include <time.h> +#include <sys/timers.h> +#include <sys/socket.h> +#include <sys/uio.h> +#include <netinet/in.h> +#include "res_internal.h" + +enum { SEND_GIVE_UP = -1, SEND_TRY_NEXT = -2, SEND_TRY_SAME = -3, + SEND_TIMEOUT = -4, SEND_TRUNCATED = -5 }; + +static int send_datagram(int server, int sock, const char *buf, int buflen, + char *answer, int anslen, int try, + struct res_data *data); +static int send_circuit(int server, const char *buf, int buflen, char *answer, + int anslen, struct res_data *data); +static int close_save_errno(int sock); + +int res_send(const char *buf, int buflen, char *answer, int anslen) +{ + struct res_data *data; + struct sockaddr_in local; + int use_virtual_circuit, result, udp_sock, have_seen_same, terrno = 0; + int try, server; + + data = _res_init(); + if (!data) + return -1; + + try = 0; + server = 0; + + /* Try doing connectionless queries if appropriate. */ + if (!(data->state.options & RES_USEVC) && buflen <= PACKETSZ) { + /* Create and bind a local UDP socket. */ + udp_sock = socket(AF_INET, SOCK_DGRAM, 0); + if (udp_sock < 0) + return -1; + local.sin_family = AF_INET; + local.sin_addr.s_addr = htonl(INADDR_ANY); + local.sin_port = htons(0); + if (bind(udp_sock, (struct sockaddr *) &local, sizeof(local)) < 0) { + close(udp_sock); + return -1; + } + + /* Cycle through the retries and servers, sending off queries and + * waiting for responses. */ + for (; try < data->state.retry; try++) { + for (; server < data->state.nscount; server++) { + result = send_datagram(server, udp_sock, buf, buflen, answer, + anslen, try, data); + if (result == SEND_TIMEOUT) + terrno = ETIMEDOUT; + else if (result != SEND_TRY_NEXT) + break; + } + if (server < data->state.nscount) + break; + } + + close(udp_sock); + if (result < 0) + errno = (terrno == ETIMEDOUT) ? ETIMEDOUT : ECONNREFUSED; + else + errno = 0; + if (result != SEND_TRUNCATED) + return (result >= 0) ? result : -1; + } + + /* Either we have to use the virtual circuit, or the server couldn't + * fit its response in a UDP packet. Cycle through the retries and + * servers, sending off queries and waiting for responses. Allow a + * response of SEND_TRY_SAME to cause an extra retry once. */ + for (; try < data->state.retry; try++) { + for (; server < data->state.nscount; server++) { + result = send_circuit(server, buf, buflen, answer, anslen, data); + terrno = errno; + if (result == SEND_TRY_SAME) { + if (!have_seen_same) + server--; + have_seen_same = 1; + } else if (result != SEND_TRY_NEXT) { + break; + } + } + } + + errno = terrno; + return (result >= 0) ? result : -1; +} + +static int send_datagram(int server, int sock, const char *buf, int buflen, + char *answer, int anslen, int try, + struct res_data *data) +{ + int count, interval; + struct sockaddr_in local_addr; + HEADER *request = (HEADER *) buf, *response = (HEADER *) answer; + struct timespec timeout; + struct timeval current; + struct timezone zone; + +#ifdef DEBUG_RESOLVER + if (_res.options & RES_DEBUG) { + printf("res_send: request:\n"); + __p_query(buf); + } +#endif /* DEBUG_RESOLVER */ + /* Send a packet to the server. */ + count = sendto(sock, buf, buflen, 0, + (struct sockaddr *) &data->state.nsaddr_list[server], + sizeof(struct sockaddr_in)); + + if (count != buflen) { +#ifdef DEBUG_RESOLVER + if (count < 0){ + if (_res.options & RES_DEBUG) + perror("send_datagram:sendto"); + } +#endif /* DEBUG_RESOLVER */ + return SEND_TRY_NEXT; + } + + /* Await a reply with the correct ID. */ + while (1) { + struct sockaddr_in from; + int from_len; + + from_len = sizeof(from); + interval = data->state.retrans << try; + if (try > 0) + interval /= data->state.nscount; + gettimeofday(¤t, &zone); + current.tv_sec += interval; + TIMEVAL_TO_TIMESPEC(¤t, &timeout); + count = recvfrom_timedwait(sock, answer, anslen, 0, + &from, &from_len, &timeout); + if (count < 0) + return SEND_TRY_NEXT; + /* If the ID is wrong, it's from an old query; ignore it. */ + if (response->id == request->id) + break; +#ifdef DEBUG_RESOLVER + if (_res.options & RES_DEBUG) { + printf("res_sendto: count=%d, response:\n", count); + __p_query(answer); + } +#endif /* DEBUG_RESOLVER */ + } + + /* Report a truncated response unless RES_IGNTC is set. This will + * cause the res_send() loop to fall back to TCP. */ + if (response->tc && !(data->state.options & RES_IGNTC)) + return SEND_TRUNCATED; + + return count; +} + +static int send_circuit(int server, const char *buf, int buflen, char *answer, + int anslen, struct res_data *data) +{ + HEADER *response = (HEADER *) answer; + int sock = -1, result, n, response_len, count; + unsigned short len; + struct iovec iov[2]; + char *p, junk[512]; + + /* If data->sock is valid, then it's an open connection to the + * first server. Grab it if it's appropriate; close it if not. */ + if (data->sock) { + if (server == 0) + sock = data->sock; + else + close(data->sock); + data->sock = -1; + } + + /* Initialize our socket if we didn't grab it from data. */ + if (sock == -1) { + sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock < 0) + return SEND_GIVE_UP; + result = connect(sock, + (struct sockaddr *) &data->state.nsaddr_list[server], + sizeof(struct sockaddr_in)); + if (result < 0) { + close_save_errno(sock); + return SEND_TRY_NEXT; + } + } + + /* Send length and message. */ + len = htons((unsigned short) buflen); + iov[0].iov_base = (caddr_t) &len; + iov[0].iov_len = sizeof(len); + iov[1].iov_base = (char *) buf; + iov[1].iov_len = buflen; + if (writev(sock, iov, 2) != sizeof(len) + buflen) { + close_save_errno(sock); + return SEND_TRY_NEXT; + } + + /* Receive length. */ + p = (char *) &len; + n = sizeof(len); + while (n) { + count = read(sock, p, n); + if (count <= 0) { + /* If we got ECONNRESET, the remote server may have restarted, + * and we report SEND_TRY_SAME. (The main loop will only + * allow one of these, so we don't have to worry about looping + * indefinitely.) */ + close_save_errno(sock); + return (errno == ECONNRESET) ? SEND_TRY_SAME : SEND_TRY_NEXT; + } + p += count; + n -= count; + } + len = ntohs(len); + response_len = (len > anslen) ? anslen : len; + len -= response_len; + + /* Receive message. */ + p = answer; + n = response_len; + while (n) { + count = read(sock, p, n); + if (count <= 0) { + close_save_errno(sock); + return SEND_TRY_NEXT; + } + p += count; + n -= count; + } + + /* If the reply is longer than our answer buffer, set the truncated + * bit and flush the rest of the reply, to keep the connection in + * sync. */ + if (len) { + response->tc = 1; + while (len) { + n = (len > sizeof(junk)) ? sizeof(junk) : len; + count = read(sock, junk, n); + if (count <= 0) { + close_save_errno(sock); + return response_len; + } + len -= count; + } + } + + /* If this is the first server, and RES_USEVC and RES_STAYOPEN are + * both set, save the connection. Otherwise, close it. */ + if (server == 0 && (data->state.options & RES_USEVC && + data->state.options & RES_STAYOPEN)) + data->sock = sock; + else + close_save_errno(sock); + + return response_len; +} + +static int close_save_errno(int sock) +{ + int terrno; + + terrno = errno; + close(sock); + errno = terrno; +} diff --git a/mit-pthreads/net/serv_internal.c b/mit-pthreads/net/serv_internal.c new file mode 100644 index 00000000000..f4acc8697ae --- /dev/null +++ b/mit-pthreads/net/serv_internal.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 1985 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)serv_internal.c 6.22 (Berkeley) 3/19/91";*/ +static char *rcsid = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include "serv_internal.h" + +#define DEFAULT_RETRIES 4 + +static void _serv_init_global(); + +pthread_mutex_t serv_iterate_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_once_t init_once = PTHREAD_ONCE_INIT; +static pthread_key_t key; +static int init_status; + +/* Performs global initialization. */ +char *_serv_buf() +{ + char *buf; + + /* Make sure the global initializations have been done. */ + pthread_once(&init_once, _serv_init_global); + + /* Initialize thread-specific data for this thread if it hasn't + * been done already. */ + buf = (char *) pthread_getspecific(key); + if (!buf) { + buf = (char *) malloc(sizeof(struct servent) + SERV_BUFSIZE); + if (buf == NULL) + return NULL; + if (pthread_setspecific(key, buf) < 0) { + free(buf); + return NULL; + } + } + return buf; +} + +static void _serv_init_global() +{ + init_status = pthread_key_create(&key, free); +} + diff --git a/mit-pthreads/net/serv_internal.h b/mit-pthreads/net/serv_internal.h new file mode 100644 index 00000000000..1d933826083 --- /dev/null +++ b/mit-pthreads/net/serv_internal.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 1985 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)serv_internal.h 6.22 (Berkeley) 3/19/91";*/ +static char *rcsid = "$Id$"; +#endif /* LIBC_SCCS and not lint */ + +#ifndef _SERV_INTERNAL_H +#define _SERV_INTERNAL_H + +#include <pthread.h> +#include <netdb.h> +#include <resolv.h> + +#define SERV_BUFSIZE 4096 +#define ALIGN(p, t) ((char *)(((((long)(p) - 1) / sizeof(t)) + 1) * sizeof(t))) +#define SP(p, t, n) (ALIGN(p, t) + (n) * sizeof(t)) + +extern pthread_mutex_t serv_iterate_lock; + +__BEGIN_DECLS +char *_serv_buf(void); +__END_DECLS + +#endif + |