home *** CD-ROM | disk | FTP | other *** search
- /*
- ** Copyright 1989 BBN Systems and Technologies Corporation.
- ** All Rights Reserved.
- ** This is free software, and may be distributed under the terms of the
- ** GNU Public License; see the file COPYING for more details.
- **
- ** An implementation of the 4.2BSD hostname lookup routines.
- ** Not based on licensed code.
- */
- #include <stdio.h>
- #include <ctype.h>
- #ifdef XENIX
- #include <netdb.h>
- #define HAVE_HOSTENT
- /* Stupid, just plain stupid... */
- #undef NULL
- #define NULL 0
- #endif /* XENIX */
- #ifdef RCSID
- static char RCS[] =
- "$Header: hostdb.c,v 2.0 90/03/23 14:41:30 rsalz Exp $";
- #endif /* RCSID */
-
- /* Constants and shorthands. */
- #define TRUE 1
- #define FALSE 0
- #define MAXALIASES 10
- #define HOSTFILENAME "/etc/hosts"
- #define ADDRLEN 4
-
- #define WHITE(c) ((c) == ' ' || (c) == '\t')
-
- #ifndef AF_INET
- #define AF_INET 2
- #endif /* AF_INET */
-
-
- #ifndef HAVE_HOSTENT
- struct hostent {
- char *h_name; /* The host's official name */
- char **h_aliases; /* A/K/A list */
- int h_addrtype; /* Address type */
- int h_length; /* Size of the address */
- char *h_addr; /* Pointer to the address */
- };
- #endif /* HAVE_HOSTENT */
-
-
- static FILE *HostFile = NULL; /* The open /etc/hosts file */
-
-
- extern char *strchr();
-
-
- /*
- ** Close the host file.
- */
- void
- endhostent()
- {
- if (HostFile) {
- (void)fclose(HostFile);
- HostFile = NULL;
- }
- }
-
-
- /*
- ** Read the next line from the host file.
- */
- static struct hostent *
- gethostent()
- {
- static struct hostent E;
- static char buff[200];
- static char *aliases[MAXALIASES];
- static char addr[ADDRLEN];
- register int i;
- register char *q;
- register char *p;
-
- /* Open the file if necessary, reset state. */
- if (HostFile == NULL) {
- if ((HostFile = fopen(HOSTFILENAME, "r")) == NULL)
- return NULL;
- E.h_addrtype = AF_INET;
- E.h_length = ADDRLEN;
- E.h_addr = addr;
- E.h_aliases = aliases;
- }
-
- /* Loop until we get a good line. */
- for ( ; ; ) {
- if (fgets(buff, sizeof buff, HostFile) == NULL)
- return NULL;
-
- /* Kill the comment and newline character, skip blank lines. */
- if (p = strchr(buff, '#'))
- *p = '\0';
- if (p = strchr(buff, '\n'))
- *p = '\0';
- if (buff[0] == '\0')
- continue;
-
- /* Parse the first field as a dotted quad. */
- for (q = p = buff, i = 0; i < ADDRLEN; i++) {
- while (*p && *p != '.' && !WHITE(*p))
- p++;
- if (*p == '\0')
- break;
- *p = '\0';
- addr[i] = atoi(q);
- q = ++p;
- }
- if (i == ADDRLEN)
- break;
- }
-
- /* Skip whitespace, get the second field as the full name. */
- while (*q && WHITE(*q))
- q++;
- for (E.h_name = q; *q && !WHITE(*q); )
- q++;
- if (*q)
- *q++ = '\0';
-
- /* Parse any aliases. */
- for (i = 0; i < MAXALIASES - 1 && *q; i++) {
- while (*q && WHITE(*q))
- q++;
- for (aliases[i] = q; *q && !WHITE(*q); )
- q++;
- if (*q)
- *q++ = '\0';
- }
- aliases[i] = NULL;
-
- return &E;
- }
-
-
- /*
- ** Compare two strings, ignoring case.
- */
- static int
- samehostname(n1, n2)
- register char *n1;
- register char *n2;
- {
- register char c1;
- register char c2;
-
- for ( ; ; ) {
- if ((c1 = *n1++) == (c2 = *n2++)) {
- if (c1 || c2)
- continue;
- return TRUE;
- }
- if (islower(c1))
- c1 = toupper(c1);
- if (islower(c2))
- c2 = toupper(c2);
- if (c1 != c2)
- return FALSE;
- }
- }
-
-
- /*
- ** Given a name, find the hostent structure.
- */
- struct hostent *
- gethostbyname(name)
- register char *name;
- {
- register struct hostent *E;
- register int i;
-
- while (E = gethostent()) {
- if (samehostname(name, E->h_name))
- break;
- for (i = 0; E->h_aliases[i]; i++)
- if (samehostname(name, E->h_aliases[i]))
- break;
- if (E->h_aliases[i])
- break;
- }
- endhostent();
-
- return E;
- }
-
-
- #if 0
- /*
- ** Given an address, find the hostent structure.
- */
- struct hostent *
- gethostbyaddr(p, length, type)
- register char *p;
- int length;
- int type;
- {
- register struct hostent *E;
-
- /* We only handle Internet addresses here. */
- if (length != ADDRLEN || type != AF_INET)
- return NULL;
-
- while (E = gethostent())
- if (he->h_addr[0] == p[0] && he->h_addr[1] == p[1]
- && he->h_addr[2] == p[2] && he->h_addr[3] == p[3])
- break;
- endhostent();
-
- return E;
- }
- #endif /* 0 */
-