1 /*
2  * Copyright (c) 1983 Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * advertising materials, and other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * by the University of California, Berkeley.  The name of the
11  * University may not be used to endorse or promote products derived
12  * from this software without specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  */
17 
18 #if defined(LIBC_SCCS) && !defined(lint)
19 static char sccsid[] = "@(#)gethostnamadr.c	5.7 (Berkeley) 06/27/88";
20 #endif /* LIBC_SCCS and not lint */
21 
22 #include <stdio.h>
23 #include <netdb.h>
24 #include <sys/file.h>
25 #include <ndbm.h>
26 #include <ctype.h>
27 
28 #define	MAXALIASES	35
29 
30 static struct hostent host;
31 static char *host_aliases[MAXALIASES];
32 static char hostbuf[BUFSIZ+1];
33 static char *host_addrs[2];
34 
35 int h_errno;
36 
37 /*
38  * The following is shared with gethostent.c
39  */
40 extern	char *_host_file;
41 DBM	*_host_db = (DBM *)NULL;
42 int	_host_stayopen;	/* set by sethostent(), cleared by endhostent() */
43 
44 static struct hostent *
45 fetchhost(key)
46 	datum key;
47 {
48         register char *cp, *tp, **ap;
49 	int naliases;
50 
51         if (key.dptr == 0)
52                 return ((struct hostent *)NULL);
53 	key = dbm_fetch(_host_db, key);
54 	if (key.dptr == 0)
55                 return ((struct hostent *)NULL);
56         cp = key.dptr;
57 	tp = hostbuf;
58 	host.h_name = tp;
59 	while (*tp++ = *cp++)
60 		;
61 	bcopy(cp, (char *)&naliases, sizeof(int)); cp += sizeof (int);
62 	for (ap = host_aliases; naliases > 0; naliases--) {
63 		*ap++ = tp;
64 		while (*tp++ = *cp++)
65 			;
66 	}
67 	*ap = (char *)NULL;
68 	host.h_aliases = host_aliases;
69 	bcopy(cp, (char *)&host.h_addrtype, sizeof (int));
70 	cp += sizeof (int);
71 	bcopy(cp, (char *)&host.h_length, sizeof (int));
72 	cp += sizeof (int);
73 	host.h_addr_list = host_addrs;
74 	host.h_addr = tp;
75 	bcopy(cp, tp, host.h_length);
76         return (&host);
77 }
78 
79 struct hostent *
80 gethostbyname(nam)
81 	register char *nam;
82 {
83 	register struct hostent *hp;
84 	register char **cp;
85         datum key;
86 	char lowname[128];
87 	register char *lp = lowname;
88 
89 	while (*nam)
90 		if (isupper(*nam))
91 			*lp++ = tolower(*nam++);
92 		else
93 			*lp++ = *nam++;
94 	*lp = '\0';
95 
96 	if ((_host_db == (DBM *)NULL)
97 	  && ((_host_db = dbm_open(_host_file, O_RDONLY)) == (DBM *)NULL)) {
98 		sethostent(_host_stayopen);
99 		while (hp = gethostent()) {
100 			if (strcmp(hp->h_name, lowname) == 0)
101 				break;
102 			for (cp = hp->h_aliases; cp != 0 && *cp != 0; cp++)
103 				if (strcmp(*cp, lowname) == 0)
104 					goto found;
105 		}
106 	found:
107 		if (!_host_stayopen)
108 			endhostent();
109 		return (hp);
110 	}
111         key.dptr = lowname;
112         key.dsize = strlen(lowname);
113 	hp = fetchhost(key);
114 	if (!_host_stayopen) {
115 		dbm_close(_host_db);
116 		_host_db = (DBM *)NULL;
117 	}
118 	if ( hp == NULL)
119 		h_errno = HOST_NOT_FOUND;
120         return (hp);
121 }
122 
123 struct hostent *
124 gethostbyaddr(addr, length, type)
125 	char *addr;
126 	register int length;
127 	register int type;
128 {
129 	register struct hostent *hp;
130         datum key;
131 
132 	if ((_host_db == (DBM *)NULL)
133 	  && ((_host_db = dbm_open(_host_file, O_RDONLY)) == (DBM *)NULL)) {
134 		sethostent(_host_stayopen);
135 		while (hp = gethostent()) {
136 			if (hp->h_addrtype == type && hp->h_length == length
137 			    && bcmp(hp->h_addr, addr, length) == 0)
138 				break;
139 		}
140 		if (!_host_stayopen)
141 			endhostent();
142 		if ( hp == NULL)
143 			h_errno = HOST_NOT_FOUND;
144 		return (hp);
145 	}
146         key.dptr = addr;
147         key.dsize = length;
148 	hp = fetchhost(key);
149 	if (!_host_stayopen) {
150 		dbm_close(_host_db);
151 		_host_db = (DBM *)NULL;
152 	}
153 	if ( hp == NULL)
154 		h_errno = HOST_NOT_FOUND;
155         return (hp);
156 }
157