hf - hostname filter

Craig Leres leres at ace.ee.lbl.gov
Tue Nov 28 13:20:46 AEST 1989


Hf is a filter that reads the named files (or from stdin if there are
none) and replaces occurrences of raw internet addresses with
hostnames. For example, a line like this:

    Nov 20 06:12:23 128.3.254.160 login: d0 leres login incorrect

would get converted to:

    Nov 20 06:12:23 helios login: d0 leres login incorrect

If you don't have flex, edit the Makefile and define LEX as lex and add
-ll to list of libraries. If you don't have gcc, define CC as cc. You
might find it necessary to delete "-lresolv" from the list of libraries

See the (brief) manual entry for operational details.

		Craig

P.S. Note that the flex distribution (a replacement for lex) is
available via anonymous ftp from host ftp.ee.lbl.gov (128.3.254.68).
------
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	Makefile
#	hf.l
#	hf.1
# This archive created: Mon Nov 27 18:17:11 1989
export PATH; PATH=/bin:$PATH
echo shar: extracting "'Makefile'" '(438 characters)'
if test -f 'Makefile'
then
	echo shar: will not over-write existing file "'Makefile'"
else
sed 's/^X//' << \SHAR_EOF > 'Makefile'
X# @(#) $Header: Makefile,v 1.14 89/11/27 17:27:49 leres Exp $ (LBL)
X
XDEFS= -DDEBUG
XCFLAGS= -O ${DEFS}
XLIBS= -lresolv
X#LEX= lex
XLEX= flex -f
X#CC= cc -fsoft
XCC= gcc -msoft-float
X
Xhf: hf.c
X	${CC} ${CFLAGS} hf.c -o hf ${LIBS}
X
Xhf.c: hf.l
X	${LEX} hf.l
X	mv lex.yy.c hf.c
X
Xclean:
X	rm -f *.o hf hf.c a.out lex.yy.c lex.backtrack
X
Xinstall: hf
X	install hf /usr/local
X
Xlint: hf.c
X	lint -bhxn hf.c
X
Xshar:
X	shar -v -c -p X Makefile hf.l hf.1 >hf.shar
SHAR_EOF
if test 438 -ne "`wc -c < 'Makefile'`"
then
	echo shar: error transmitting "'Makefile'" '(should have been 438 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'hf.l'" '(4424 characters)'
if test -f 'hf.l'
then
	echo shar: will not over-write existing file "'hf.l'"
else
sed 's/^X//' << \SHAR_EOF > 'hf.l'
XN              [0-9]
XO              ({N}{1,3})
X
X%%
X
X
X{O}\.{O}\.{O}\.{O}	convert(yytext);
X
X({O}\.){1,3}		ECHO;		/* anti-backtrack */
X{O}((\.{O}){1,2})	ECHO;		/* anti-backtrack */
X
X{N}+			ECHO;
X[^0-9\n]+		ECHO;
X[^0-9\n]+\n		ECHO;
X
X%%
X#ifndef lint
Xstatic char rcsid[] =
X    "@(#) $Header: hf.l,v 1.18 89/11/27 18:16:52 leres Exp $ (LBL)";
X#endif
X
X#include <sys/types.h>
X#include <sys/socket.h>
X#include <ctype.h>
X#include <stdio.h>
X#include <strings.h>
X#include <arpa/inet.h>
X#include <netdb.h>
X
X#include <netinet/in.h>
X#include <arpa/nameser.h>
X#include <resolv.h>
X
X
X#define HSIZE 1024		/* must be a power of two */
X
Xstruct htable {
X	u_long addr;
X	char *name;
X	struct htable *next;
X} htable[HSIZE];
X
Xint strip = 1;			/* strip domain when possible */
Xint lcase = 1;			/* force lowercase */
X#ifdef DEBUG
Xint debug = 0;
X#endif
X
Xchar domain[64];		/* current domain name (including '.') */
Xint domainlen;			/* length of domain name */
X
Xextern char *malloc();
X
Xmain(argc, argv)
X	int argc;
X	char **argv;
X{
X	register char *cp;
X	char *argv0 = argv[0];
X
X	if (cp = rindex(argv[0], '/'))
X		argv0 = cp + 1;
X	else
X		argv0 = argv[0];
X	/* Process flags */
X	for (--argc, ++argv; argc > 0 && *argv[0] == '-'; --argc, ++argv)
X		for (cp = &argv[0][1]; *cp != '\0'; ++cp)
X			switch (*cp) {
X
X			case 'i':
X				lcase = 0;
X				break;
X
X			case 'l':
X				strip = 0;
X				break;
X
X#ifdef DEBUG
X			case 'd':
X				++debug;
X				break;
X#endif
X
X			default:
X				(void) fprintf(stderr,
X				    "usage: %s [-dil] [file ...]\n", argv0);
X				exit(1);
X			}
X
X	/* Figure out our domain, if necessary */
X	if (!strip || !getdomain())
X		domain[0] = '\0';
X
X	/* Up number of retries, we really want answers */
X	_res.retry = 20;
X
X	/* Spin through filenames; if none, read from stdin */
X	for (yyin = stdin; argc > 0; --argc, ++argv)
X		if (yyin = fopen(argv[0], "r"))
X			yylex();
X		else
X			perror(argv[0]);
X
X	/* No filename arguments */
X	if (yyin == stdin)
X		yylex();
X#ifdef DEBUG
X	if (debug) {
X		fflush(stdout);
X		dump();
X	}
X#endif
X	exit(0);
X}
X
Xgetdomain()
X{
X	register char *cp;
X	register struct hostent *hp;
X	char host[128];
X
X	if (gethostname(host, sizeof(host) - 1) < 0)
X		return(0);
X	if ((cp = index(host, '.')) == 0) {
X		/* Not already canonical */
X		if ((hp = gethostbyname(host)) == 0)
X			return(0);
X		if ((cp = index(hp->h_name, '.')) == 0)
X			return(0);
X	}
X	(void) strncpy(domain, cp, sizeof(domain));
X	domain[sizeof(domain) - 1] = '\0';
X	if (lcase)
X		for (cp = domain; *cp; ++cp)
X			if (isupper(*cp))
X				*cp = tolower(*cp);
X	domainlen = strlen(domain);
X	return(1);
X}
X
Xchar *
Xaddr2host(addr)
X	u_long addr;
X{
X	register char *cp, *host;
X	register struct hostent *hp;
X	register struct htable *p, *p2;
X
X	/* First check if we already know about it */
X	for (p = &htable[addr & (HSIZE - 1)]; p; p = p->next)
X		if (p->addr == addr)
X			return(p->name);
X
X	/* Try to lookup this host */
X	if (hp = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET))
X		host = hp->h_name;
X	else
X		host = inet_ntoa(addr);
X
X	/* Try to strip the domain */
X	if (strip && *domain != '\0') {
X		cp = host + strlen(host) - domainlen;
X		if (cp > host && strcasecmp(cp, domain) == 0)
X			*cp = '\0';
X	}
X	if (lcase)
X		for (cp = host; *cp; ++cp)
X			if (isupper(*cp))
X				*cp = tolower(*cp);
X
X	/* Malloc space for new hostname */
X	cp = malloc((u_int) strlen(host) + 1);
X	if (cp == 0)
X		return(host);
X
X	/* Find slot in hash table */
X	p = &htable[addr & (HSIZE - 1)];
X	if (p->name) {
X		/* Handle the collision */
X		p2 = (struct htable *)malloc(sizeof(struct htable));
X		if (p2 == 0) {
X			/* Lose, lose */
X			free(cp);
X			return(host);
X		}
X		bzero((char *)p2, sizeof(struct htable));
X		p2->next = p->next;
X		p->next = p2;
X		p = p2;
X	}
X
X	/* Install new host */
X	p->addr = addr;
X	p->name = strcpy(cp, host);
X
X	/* Return answer */
X	return(p->name);
X}
X
X#ifdef DEBUG
Xdump()
X{
X	register int i, j, n, d;
X	register struct htable *p, *p2;
X
X	d = n = 0;
X	for (p = htable, i = 0; i < HSIZE; ++p, ++i)
X		if (p->name) {
X			++n;
X			j = 0;
X			for (p2 = p; p2; p2 = p2->next) {
X				(void) fprintf(stderr,
X				    "%4d:%d 0x%08x \"%s\"\n", i, j,
X				    p2->addr, p2->name ? p2->name : "<nil>");
X				++d;
X				++j;
X			}
X		}
X	d -= n;
X	(void) fprintf(stderr, "%d entries (%d dynamically linked)\n", n, d);
X}
X#endif
X
Xconvert(str)
X	char *str;
X{
X	char *host;
X	u_long l;
X
X	/* XXX do we always ask for nxdomain failures? */
X	if ((long)(l = inet_addr(str)) != -1 && (host = addr2host(l)))
X		fputs(host, stdout);
X	else
X		fputs(str, stdout);
X}
SHAR_EOF
if test 4424 -ne "`wc -c < 'hf.l'`"
then
	echo shar: error transmitting "'hf.l'" '(should have been 4424 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'hf.1'" '(649 characters)'
if test -f 'hf.1'
then
	echo shar: will not over-write existing file "'hf.1'"
else
sed 's/^X//' << \SHAR_EOF > 'hf.1'
X.\"	@(#) $Header: hf.1,v 1.4 89/11/27 17:13:21 leres Exp $ (LBL)
X.TH WRITE 1 "November 13, 1989"
X.UC 4
X.SH NAME
Xhf - hostname filter
X.SH SYNOPSIS
X.B hf [-dil] [file ...]
X.ft R
X.SH DESCRIPTION
X.B Hf
Xreads the named files (or from stdin if there are none) and replaces
Xoccurrences of raw internet addresses with hostnames.
X.LP
XBy default,
X.B hf
Xstrips the domain part of hostnames i the local domain. The
X.B -l
Xflag suppresses this striping.
XBy default, hostnames are converted to lowercase. The
X.B -i
Xflag suppresses this conversion.
XThe
X.B -d
Xflag is used to dump the hash table (usually for debugging purposes).
X.LP
X.SH "SEE ALSO"
Xgethostbyaddr(3)
SHAR_EOF
if test 649 -ne "`wc -c < 'hf.1'`"
then
	echo shar: error transmitting "'hf.1'" '(should have been 649 characters)'
fi
fi # end of overwriting check
#	End of shell archive
exit 0



More information about the Alt.sources mailing list