Path: utzoo!utgpu!jarvis.csri.toronto.edu!cs.utexas.edu!hellgate.utah.edu!helios.ee.lbl.gov!ace.ee.lbl.gov!leres From: leres@ace.ee.lbl.gov (Craig Leres) Newsgroups: alt.sources Subject: hf - hostname filter Message-ID: <4301@helios.ee.lbl.gov> Date: 28 Nov 89 02:20:46 GMT Sender: usenet@helios.ee.lbl.gov Reply-To: leres@helios.ee.lbl.gov (Craig Leres) Organization: Lawrence Berkeley Laboratory, Berkeley Lines: 359 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 X#include X#include X#include X#include X#include X#include X X#include X#include X#include 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 : ""); 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 Brought to you by Super Global Mega Corp .com