BBN-Vax-TCP/src/libnet/_loadmap.c

Compare this file to the similar file:
Show the results in this format:

#include "sys/types.h"
#include "sys/stat.h"
#define	LIBN
#include "netlib.h"
#include "netmap.h"
#include "netfiles.h"

char		*_mapname;	/* file name override */
static	int	loaded;		/* counter to allow nested load/free calls */
static	int	locked;		/* indicates map locked in core */
static	char	map_bin[] = MAP_BIN;	/* default map */
static	char	map_obin[] = MAP_OBIN;	/* backup map */
static	char	*map_base;	/* base of allocated area */
static	int	map_size;	/* size of allocated area */
static	time_t	map_time;	/* mode time of map */
/*
 * pointers for table access
 */
map_head	*_netmap;	/* -> network map header */
net_ent		*_nettab;	/* -> network table */
host_ent	*_hosttab;	/* -> host table */
char		*_namebuf;	/* -> name buffer */
char		*_dialbuf;	/* -> dial digit buffer */
unsigned	_lhostcnt;	/* # local hosts */
netaddr		_lhosttab[_LHOSTSIZ];	/* local host addresses */
unsigned	_dialcnt;	/* dial digit count */
char		_dialext[_DIALSIZ];	/* dial digit extension buffer */

/*
 * load the network map into core and initialize it
 *	may be called successively
 *	each call must be balanced by a call to _freemap
 *
 *	if map is locked, it will be reread if it changes
 */
_loadmap()
{
	register int fd;	/* map file descriptor */
	register char *mp;	/* map base ptr */
	struct stat sb;		/* stat buffer */
	extern char *malloc();

	if (loaded++ > 0)
		return 1;
	if (locked) {
		/*
		 * if using old map, switch to regular map
		 */
		if (!_mapname || _mapname == map_obin)
			_mapname = map_bin;
		/*
		 * if map inaccessible or unchanged just return
		 */
		if (stat(_mapname, &sb) != 0 || map_time == sb.st_mtime)
			return 1;
	}
	if (_mapname)
		fd = open(_mapname, 0);
	else if ((fd = open(_mapname = map_bin, 0)) < 0)
		fd = open(_mapname = map_obin, 0);
	if (fd < 0)
		return 0;
	/*
	 * save size and mod time
	 */
	if (fstat(fd, &sb) != 0) {
		close(fd);
		return 0;
	}
	map_size = sb.st_size;
	map_time = sb.st_mtime;
	/*
	 * allocate space and read in map
	 */
	if (!(map_base = malloc(map_size))) {
		close(fd);
		return 0;
	}
	if (read(fd, map_base, map_size) != map_size) {
		close(fd);
		return 0;
	}
	close(fd);
	/*
	 * setup access pointers
	 */
	_netmap = (map_head *)(mp = map_base);
	_nettab = (net_ent *)(mp += sizeof(map_head));
	_hosttab = (host_ent *)(mp += _netmap->map_nnet * sizeof(net_ent));
	_namebuf = (char *)(mp += _netmap->map_nhost * sizeof(host_ent));
	_dialbuf = (char *)(mp += _netmap->map_nchar);
	/*
	 * set local network chain
	 */
	localnet();
	return 1;
}

/*
 * lock map into core
 *	used by programs which access map continuously
 */
loadnetmap()
{
	if (locked)
		return 1;
	if (!_loadmap())
		return 0;
	++locked;
	return 1;
}

freenetmap()
{
	if (locked) {
		locked = 0;
		_freemap();
	}
}

/*
 * unload the map, free storage
 */
_freemap()
{
	if (--loaded > 0)
		return;
	loaded = 0;
	if (!locked) {
		_dialcnt = 0;
		if (map_base) {
			free(map_base);
			map_base = 0;
		}
	}
}

/*
 * When the network map is initially built, the network entries
 * are chained into a forward list of which _netmap[0] is the head.
 * localnet() reads a file containing the various network addresses
 * by which the host is known; it reorders the chain so that networks
 * local to the host are searched first.
 */
static
localnet()
{
#ifdef	NETWORKS
#include "stdio.h"

	FILE	*fp;
	register net_ent *np;
	register map_index *pp, *hp;
	netnumb	net;
	char	nname[NETNAMSIZ], hname[NETNAMSIZ];
	char	buf[BUFSIZ];

	if ((fp = fopen(NETWORKS, "r")) == NULL)
		return;
	/*
	 * setup pointer to index at head of list
	 * read file for network addresses
	 */
	hp = &_nettab[0].net_next;
	while (fgets(buf, sizeof buf, fp)) {
		switch (*_2parse(buf, 1, hname, nname)) {
		case '\n':
		case '\0':
			break;
		default:
			continue;
		}
		/*
		 * get net part of address
		 */
		net = _isnum(nname)? _nnetn(nname) : _snetn(nname);
		if (isbadnet(net))
			continue;
		/*
		 * look forward from the head to find ancestor net
		 * move net to head of list and make that net the new head
		 */
		for (pp = hp; *pp != 0; pp = &_nettab[*pp].net_next) {
			if (*pp == net) {
				np = &_nettab[net];
				if (hp != pp) {
					*pp = np->net_next;
					np->net_next = *hp;
					*hp = net;
				}
				hp = &np->net_next;
				break;
			}
		}
		/*
		 * install host address in table
		 */
		if (_lhostcnt < _LHOSTSIZ) {
			if (_isnum(hname))
				_lhosttab[_lhostcnt] = _nhosta(hname, net); else
				_lhosttab[_lhostcnt] = _shosta(hname, net);
			if (!isbadhost(_lhosttab[_lhostcnt]))
				++_lhostcnt;
		}
	}
	fclose(fp);
#endif	NETWORKS
}