Home | History | Annotate | Download | only in BsdSocketLib
      1 /*-
      2  * Copyright (c) 1994, Garrett Wollman
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
     14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     16  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     23  * SUCH DAMAGE.
     24  */
     25 
     26 #if defined(LIBC_SCCS) && !defined(lint)
     27 static char sccsid[] = "@(#)$Id: gethostnamadr.c,v 1.1.1.1 2003/11/19 01:51:27 kyu3 Exp $";
     28 static char rcsid[] = "$Id: gethostnamadr.c,v 1.1.1.1 2003/11/19 01:51:27 kyu3 Exp $";
     29 #endif /* LIBC_SCCS and not lint */
     30 
     31 #include <sys/param.h>
     32 #include <sys/socket.h>
     33 #include <netinet/in.h>
     34 #include <arpa/inet.h>
     35 #include <netdb.h>
     36 #include <stdio.h>
     37 #include <ctype.h>
     38 #include <errno.h>
     39 #include <paths.h>
     40 #include <string.h>
     41 #include <arpa/nameser.h>		/* XXX hack for _res */
     42 #include <resolv.h>			/* XXX hack for _res */
     43 
     44 #include "Socklib_internals.h"
     45 
     46 
     47 enum service_type {
     48   SERVICE_NONE = 0,
     49   SERVICE_BIND,
     50   SERVICE_HOSTS,
     51   SERVICE_NIS };
     52 #define SERVICE_MAX	SERVICE_NIS
     53 
     54 static struct {
     55   const char *name;
     56   enum service_type type;
     57 } service_names[] = {
     58   { "hosts", SERVICE_HOSTS },
     59   { _PATH_HOSTS, SERVICE_HOSTS },
     60   { "hosttable", SERVICE_HOSTS },
     61   { "htable", SERVICE_HOSTS },
     62   { "bind", SERVICE_BIND },
     63   { "dns", SERVICE_BIND },
     64   { "domain", SERVICE_BIND },
     65   { "yp", SERVICE_NIS },
     66   { "yellowpages", SERVICE_NIS },
     67   { "nis", SERVICE_NIS },
     68   { 0, SERVICE_NONE }
     69 };
     70 
     71 static enum service_type service_order[SERVICE_MAX + 1];
     72 static int service_done = 0;
     73 
     74 static enum service_type
     75 get_service_name(const char *name) {
     76 	int i;
     77 	for(i = 0; service_names[i].type != SERVICE_NONE; i++) {
     78 		if(!strcasecmp(name, service_names[i].name)) {
     79 			return service_names[i].type;
     80 		}
     81 	}
     82 	return SERVICE_NONE;
     83 }
     84 
     85 static void
     86 init_services()
     87 {
     88 	char *cp, *p, buf[BUFSIZ];
     89 	register int cc = 0;
     90 	FILE *fd;
     91 
     92 	if ((fd = (FILE *)fopen(_PATH_HOSTCONF, "r")) == NULL) {
     93 				/* make some assumptions */
     94 		service_order[0] = SERVICE_HOSTS;
     95 		service_order[1] = SERVICE_BIND;
     96 		service_order[2] = SERVICE_NONE;
     97 	} else {
     98 		while (fgets(buf, BUFSIZ, fd) != NULL && cc < SERVICE_MAX) {
     99 			if(buf[0] == '#')
    100 				continue;
    101 
    102 			p = buf;
    103 			while ((cp = strsep(&p, "\n \t,:;")) != NULL && *cp == '\0')
    104 				;
    105 			if (cp == NULL)
    106 				continue;
    107 			do {
    108 				if (isalpha(cp[0])) {
    109 					service_order[cc] = get_service_name(cp);
    110 					if(service_order[cc] != SERVICE_NONE)
    111 						cc++;
    112 				}
    113 				while ((cp = strsep(&p, "\n \t,:;")) != NULL && *cp == '\0')
    114 					;
    115 			} while(cp != NULL && cc < SERVICE_MAX);
    116 		}
    117 		service_order[cc] = SERVICE_NONE;
    118 		fclose(fd);
    119 	}
    120 	service_done = 1;
    121 }
    122 
    123 struct hostent *
    124 gethostbyname(const char *name)
    125 {
    126 	struct hostent *hp;
    127 
    128 	if (_res.options & RES_USE_INET6) {		/* XXX */
    129 		hp = gethostbyname2(name, AF_INET6);	/* XXX */
    130 		if (hp)					/* XXX */
    131 			return (hp);			/* XXX */
    132 	}						/* XXX */
    133 	return (gethostbyname2(name, AF_INET));
    134 }
    135 
    136 struct hostent *
    137 gethostbyname2(const char *name, int type)
    138 {
    139 	struct hostent *hp = 0;
    140 	int nserv = 0;
    141 
    142 	if (!service_done)
    143 		init_services();
    144 
    145 	while (!hp) {
    146 		switch (service_order[nserv]) {
    147 		      case SERVICE_NONE:
    148 			return NULL;
    149 		      case SERVICE_HOSTS:
    150 			hp = _gethostbyhtname(name, type);
    151 			break;
    152 		      case SERVICE_BIND:
    153 			hp = _gethostbydnsname(name, type);
    154 			break;
    155 		      case SERVICE_NIS:
    156 			hp = _gethostbynisname(name, type);
    157 			break;
    158 		}
    159 		nserv++;
    160 	}
    161 	return hp;
    162 }
    163 
    164 struct hostent *
    165 gethostbyaddr(const char *addr, socklen_t len, int type)
    166 {
    167 	struct hostent *hp = 0;
    168 	int nserv = 0;
    169 
    170 	if (!service_done)
    171 		init_services();
    172 
    173 	while (!hp) {
    174 		switch (service_order[nserv]) {
    175 		      case SERVICE_NONE:
    176 			return 0;
    177 		      case SERVICE_HOSTS:
    178 			hp = _gethostbyhtaddr(addr, len, type);
    179 			break;
    180 		      case SERVICE_BIND:
    181 			hp = _gethostbydnsaddr(addr, len, type);
    182 			break;
    183 		      case SERVICE_NIS:
    184 			hp = _gethostbynisaddr(addr, len, type);
    185 			break;
    186 		}
    187 		nserv++;
    188 	}
    189 	return hp;
    190 }
    191 
    192 #ifdef _THREAD_SAFE
    193 struct hostent_data;
    194 
    195 /*
    196  * Temporary function (not thread safe)
    197  */
    198 int gethostbyaddr_r(const char *addr, int len, int type,
    199 	struct hostent *result, struct hostent_data *buffer)
    200 {
    201 	struct hostent *hp;
    202 	int ret;
    203 	if ((hp = gethostbyaddr(addr, len, type)) == NULL) {
    204 		ret = -1;
    205 	} else {
    206 		memcpy(result, hp, sizeof(struct hostent));
    207 		ret = 0;
    208 	}
    209 	return(ret);
    210 }
    211 #endif
    212 
    213 void
    214 sethostent(int stayopen)
    215 {
    216 	_sethosthtent(stayopen);
    217 	_sethostdnsent(stayopen);
    218 }
    219 
    220 void
    221 endhostent()
    222 {
    223 	_endhosthtent();
    224 	_endhostdnsent();
    225 }
    226