1 /*
2  * Copyright (c) 1983 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  */
6 
7 #if defined(LIBC_SCCS) && !defined(lint)
8 static char sccsid[] = "@(#)gethostnamadr.c	5.5 (Berkeley) 03/09/86";
9 #endif LIBC_SCCS and not lint
10 
11 #include <stdio.h>
12 #include <netdb.h>
13 #include <sys/file.h>
14 #include <ndbm.h>
15 #include <ctype.h>
16 
17 #define	MAXALIASES	35
18 
19 static struct hostent host;
20 static char *host_aliases[MAXALIASES];
21 static char hostbuf[BUFSIZ+1];
22 static char *host_addrs[2];
23 
24 int h_errno;
25 
26 /*
27  * The following is shared with gethostent.c
28  */
29 extern	char *_host_file;
30 DBM	*_host_db = (DBM *)NULL;
31 int	_host_stayopen;	/* set by sethostent(), cleared by endhostent() */
32 
33 static struct hostent *
34 fetchhost(key)
35 	datum key;
36 {
37         register char *cp, *tp, **ap;
38 	int naliases;
39 
40         if (key.dptr == 0)
41                 return ((struct hostent *)NULL);
42 	key = dbm_fetch(_host_db, key);
43 	if (key.dptr == 0)
44                 return ((struct hostent *)NULL);
45         cp = key.dptr;
46 	tp = hostbuf;
47 	host.h_name = tp;
48 	while (*tp++ = *cp++)
49 		;
50 	bcopy(cp, (char *)&naliases, sizeof(int)); cp += sizeof (int);
51 	for (ap = host_aliases; naliases > 0; naliases--) {
52 		*ap++ = tp;
53 		while (*tp++ = *cp++)
54 			;
55 	}
56 	*ap = (char *)NULL;
57 	host.h_aliases = host_aliases;
58 	bcopy(cp, (char *)&host.h_addrtype, sizeof (int));
59 	cp += sizeof (int);
60 	bcopy(cp, (char *)&host.h_length, sizeof (int));
61 	cp += sizeof (int);
62 	host.h_addr_list = host_addrs;
63 	host.h_addr = tp;
64 	bcopy(cp, tp, host.h_length);
65         return (&host);
66 }
67 
68 struct hostent *
69 gethostbyname(nam)
70 	register char *nam;
71 {
72 	register struct hostent *hp;
73 	register char **cp;
74         datum key;
75 	char lowname[128];
76 	register char *lp = lowname;
77 
78 	while (*nam)
79 		if (isupper(*nam))
80 			*lp++ = tolower(*nam++);
81 		else
82 			*lp++ = *nam++;
83 	*lp = '\0';
84 
85 	if ((_host_db == (DBM *)NULL)
86 	  && ((_host_db = dbm_open(_host_file, O_RDONLY)) == (DBM *)NULL)) {
87 		sethostent(_host_stayopen);
88 		while (hp = gethostent()) {
89 			if (strcmp(hp->h_name, lowname) == 0)
90 				break;
91 			for (cp = hp->h_aliases; cp != 0 && *cp != 0; cp++)
92 				if (strcmp(*cp, lowname) == 0)
93 					goto found;
94 		}
95 	found:
96 		if (!_host_stayopen)
97 			endhostent();
98 		return (hp);
99 	}
100         key.dptr = lowname;
101         key.dsize = strlen(lowname);
102 	hp = fetchhost(key);
103 	if (!_host_stayopen) {
104 		dbm_close(_host_db);
105 		_host_db = (DBM *)NULL;
106 	}
107 	if ( hp == NULL)
108 		h_errno = HOST_NOT_FOUND;
109         return (hp);
110 }
111 
112 struct hostent *
113 gethostbyaddr(addr, length, type)
114 	char *addr;
115 	register int length;
116 	register int type;
117 {
118 	register struct hostent *hp;
119         datum key;
120 
121 	if ((_host_db == (DBM *)NULL)
122 	  && ((_host_db = dbm_open(_host_file, O_RDONLY)) == (DBM *)NULL)) {
123 		sethostent(_host_stayopen);
124 		while (hp = gethostent()) {
125 			if (hp->h_addrtype == type && hp->h_length == length
126 			    && bcmp(hp->h_addr, addr, length) == 0)
127 				break;
128 		}
129 		if (!_host_stayopen)
130 			endhostent();
131 		if ( hp == NULL)
132 			h_errno = HOST_NOT_FOUND;
133 		return (hp);
134 	}
135         key.dptr = addr;
136         key.dsize = length;
137 	hp = fetchhost(key);
138 	if (!_host_stayopen) {
139 		dbm_close(_host_db);
140 		_host_db = (DBM *)NULL;
141 	}
142 	if ( hp == NULL)
143 		h_errno = HOST_NOT_FOUND;
144         return (hp);
145 }
146