169 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			169 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
/*	gethostent() - Interface to /etc/hosts		Author: Kees J. Bot
 | 
						|
 *								31 May 1999
 | 
						|
 */
 | 
						|
 | 
						|
/* Prefix the functions defined here with underscores to distinguish them
 | 
						|
 * from the newer replacements in the resolver library.
 | 
						|
 */
 | 
						|
#define sethostent	_sethostent
 | 
						|
#define endhostent	_endhostent
 | 
						|
#define gethostent	_gethostent
 | 
						|
#define gethostbyname	_gethostbyname
 | 
						|
#define gethostbyaddr	_gethostbyaddr
 | 
						|
 | 
						|
#define nil 0
 | 
						|
#include <sys/types.h>
 | 
						|
#include <stdio.h>
 | 
						|
#include <string.h>
 | 
						|
#include <net/gen/netdb.h>
 | 
						|
#include <net/gen/in.h>
 | 
						|
#include <net/gen/inet.h>
 | 
						|
#include <net/gen/socket.h>
 | 
						|
 | 
						|
#define arraysize(a)	(sizeof(a) / sizeof((a)[0]))
 | 
						|
#define arraylimit(a)	((a) + arraysize(a))
 | 
						|
#define isspace(c)	((unsigned) (c) <= ' ')
 | 
						|
 | 
						|
static char HOSTS[]= _PATH_HOSTS;
 | 
						|
static char *hosts= HOSTS;	/* Current hosts file. */
 | 
						|
static FILE *hfp;		/* Open hosts file. */
 | 
						|
 | 
						|
void sethostent(int stayopen)
 | 
						|
/* Start search.  (Same as ending it.) */
 | 
						|
{
 | 
						|
    endhostent();
 | 
						|
}
 | 
						|
 | 
						|
void endhostent(void)
 | 
						|
/* End search and reinitialize. */
 | 
						|
{
 | 
						|
    if (hfp != nil) {
 | 
						|
	fclose(hfp);
 | 
						|
	hfp= nil;
 | 
						|
    }
 | 
						|
    hosts= _PATH_HOSTS;
 | 
						|
}
 | 
						|
 | 
						|
struct hostent *gethostent(void)
 | 
						|
/* Return the next entry from the hosts files. */
 | 
						|
{
 | 
						|
    static char line[256];	/* One line in a hosts file. */
 | 
						|
    static ipaddr_t addr;	/* IP address found first on the line. */
 | 
						|
    static char *names[16];	/* Pointers to the words on the line. */
 | 
						|
    static char *addrs[2]= {	/* List of IP addresses (just one.) */
 | 
						|
	(char *) &addr,
 | 
						|
	nil,
 | 
						|
    };
 | 
						|
    static struct hostent host = {
 | 
						|
	nil,			/* h_name, will set to names[1]. */
 | 
						|
	names + 2,		/* h_aliases, the rest of the names. */
 | 
						|
	AF_INET,		/* h_addrtype */
 | 
						|
	sizeof(ipaddr_t),	/* Size of an address in the address list. */
 | 
						|
	addrs,			/* List of IP addresses. */
 | 
						|
    };
 | 
						|
    static char nexthosts[128];	/* Next hosts file to include. */
 | 
						|
    char *lp, **np;
 | 
						|
    int c;
 | 
						|
 | 
						|
    for (;;) {
 | 
						|
	if (hfp == nil) {
 | 
						|
	    /* No hosts file open, try to open the next one. */
 | 
						|
	    if (hosts == 0) return nil;
 | 
						|
	    if ((hfp= fopen(hosts, "r")) == nil) { hosts= nil; continue; }
 | 
						|
	}
 | 
						|
 | 
						|
	/* Read a line. */
 | 
						|
	lp= line;
 | 
						|
	while ((c= getc(hfp)) != EOF && c != '\n') {
 | 
						|
	    if (lp < arraylimit(line)) *lp++= c;
 | 
						|
	}
 | 
						|
 | 
						|
	/* EOF?  Then close and prepare for reading the next file. */
 | 
						|
	if (c == EOF) {
 | 
						|
	    fclose(hfp);
 | 
						|
	    hfp= nil;
 | 
						|
	    hosts= nil;
 | 
						|
	    continue;
 | 
						|
	}
 | 
						|
 | 
						|
	if (lp == arraylimit(line)) continue;
 | 
						|
	*lp= 0;
 | 
						|
 | 
						|
	/* Break the line up in words. */
 | 
						|
	np= names;
 | 
						|
	lp= line;
 | 
						|
	for (;;) {
 | 
						|
	    while (isspace(*lp) && *lp != 0) lp++;
 | 
						|
	    if (*lp == 0 || *lp == '#') break;
 | 
						|
	    if (np == arraylimit(names)) break;
 | 
						|
	    *np++= lp;
 | 
						|
	    while (!isspace(*lp) && *lp != 0) lp++;
 | 
						|
	    if (*lp == 0) break;
 | 
						|
	    *lp++= 0;
 | 
						|
	}
 | 
						|
 | 
						|
	if (np == arraylimit(names)) continue;
 | 
						|
	*np= nil;
 | 
						|
 | 
						|
	/* Special "include file" directive. */
 | 
						|
	if (np == names + 2 && strcmp(names[0], "include") == 0) {
 | 
						|
	    fclose(hfp);
 | 
						|
	    hfp= nil;
 | 
						|
	    hosts= nil;
 | 
						|
	    if (strlen(names[1]) < sizeof(nexthosts)) {
 | 
						|
		strcpy(nexthosts, names[1]);
 | 
						|
		hosts= nexthosts;
 | 
						|
	    }
 | 
						|
	    continue;
 | 
						|
	}
 | 
						|
 | 
						|
	/* At least two words, the first of which is an IP address. */
 | 
						|
	if (np < names + 2) continue;
 | 
						|
	if (!inet_aton((char *) names[0], &addr)) continue;
 | 
						|
	host.h_name= (char *) names[1];
 | 
						|
 | 
						|
	return &host;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/* Rest kept in reserve, we probably never need 'em. */
 | 
						|
#if XXX
 | 
						|
struct hostent *gethostbyname(const char *name)
 | 
						|
{
 | 
						|
    struct hostent *he;
 | 
						|
    char **pa;
 | 
						|
    char alias[256];
 | 
						|
    char *domain;
 | 
						|
    
 | 
						|
    sethostent(0);
 | 
						|
    while ((he= gethostent()) != nil) {
 | 
						|
	if (strcasecmp(he->h_name, name) == 0) goto found;
 | 
						|
 | 
						|
	domain= strchr(he->h_name, '.');
 | 
						|
	for (pa= he->h_aliases; *pa != nil; pa++) {
 | 
						|
	    strcpy(alias, *pa);
 | 
						|
	    if (domain != nil && strchr(alias, '.') == nil) {
 | 
						|
		strcat(alias, domain);
 | 
						|
	    }
 | 
						|
	    if (strcasecmp(alias, name) == 0) goto found;
 | 
						|
	}
 | 
						|
    }
 | 
						|
  found:
 | 
						|
    endhostent();
 | 
						|
    return he;
 | 
						|
}
 | 
						|
 | 
						|
struct hostent *gethostbyaddr(const char *addr, int len, int type)
 | 
						|
{
 | 
						|
    struct hostent *he;
 | 
						|
 | 
						|
    sethostent(0);
 | 
						|
    while ((he= gethostent()) != nil) {
 | 
						|
	if (he->h_name[0] == '%') continue;
 | 
						|
	if (type == AF_INET && memcmp(he->h_addr, addr, len) == 0) break;
 | 
						|
    }
 | 
						|
    endhostent();
 | 
						|
    return he;
 | 
						|
}
 | 
						|
#endif
 |