v13i036: Tools for pathalias with MMDF

Rich Salz rsalz at bbn.com
Fri Feb 12 00:43:10 AEST 1988


Submitted-by: David Herron E-Mail Hack <david at E.MS.UKY.EDU>
Posting-number: Volume 13, Issue 36
Archive-name: process-uucp

Enclosed is a program to process pathalias output for MMDF use.
It's real short and sweet.  There's a complete description enclosed
with the package.

		-- David

#! /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:
:	'process-uucp'
: By:	'David Herron -- Resident E-mail Hack ()'
export PATH; PATH=/bin:$PATH
if test ! -d 'process-uucp'
then
	echo shar: creating directory "'process-uucp'"
	mkdir 'process-uucp'
fi
echo shar: entering directory "'process-uucp'"
cd 'process-uucp'
echo shar: extracting "'Makefile'" '(703 characters)'
if test -f 'Makefile'
then
	echo shar: will not over-write existing file "'Makefile'"
else
sed 's/^X//'  >'Makefile' <<'SHAR_EOF'
X# Makefile for "process-uucp"
X#
X# A lot of these tags are for our internal use.  Especially "addman"
X# which basically copies the named manual page to /usr/man/manx ...
X
XDESTDIR=/usr/mmdf
XCC=cc
XCFLAGS=-O
X
Xnotes:
X	@echo Package: process-uucp
X	@echo Process output from pathalias to make channel and domain
X	@echo tables for MMDF.  Locally written by David Herron.
X
Xclean:
X	-rm -f *.o core a.out process-uucp
X
Xall:	process-uucp
X
Xinstall: $(DESTDIR)/process-uucp
X
X$(DESTDIR)/process-uucp: process-uucp
X	cp process-uucp $(DESTDIR)/process-uucp
X
Xuninstall:
X	rm -f $(DESTDIR)/process-uucp
X
Xdoc:
X	addman process-uucp.8 8
X
Xprocess-uucp: process-uucp.o
X	$(CC) process-uucp.o $(CFLAGS) $(LDFLAGS) -o process-uucp
SHAR_EOF
if test 703 -ne "`wc -c < 'Makefile'`"
then
	echo shar: error transmitting "'Makefile'" '(should have been 703 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'PROCESS'" '(58 characters)'
if test -f 'PROCESS'
then
	echo shar: will not over-write existing file "'PROCESS'"
else
sed 's/^X//'  >'PROCESS' <<'SHAR_EOF'
X#! /bin/sh
X
Xprocess-uucp -r g.ms.uky.edu -d uucp ukma.new
SHAR_EOF
if test 58 -ne "`wc -c < 'PROCESS'`"
then
	echo shar: error transmitting "'PROCESS'" '(should have been 58 characters)'
fi
chmod +x 'PROCESS'
fi # end of overwriting check
echo shar: extracting "'README'" '(862 characters)'
if test -f 'README'
then
	echo shar: will not over-write existing file "'README'"
else
sed 's/^X//'  >'README' <<'SHAR_EOF'
XThese files make up the do-whickies which I use to generate tables for
XMMDF from the comp.mail.maps information.  The files are as follows:
X
XMakefile, README
XRUN			The shell script I use to run pathalias
XPROCESS			The shell script run from RUN to do process-uucp.
Xprocess-uucp.c		The program
Xprocess-uucp.8		The manual page
X
XIf you have any problems, send me some mail.  The addresses are listed
Xon the manual page.
X
XSorry, I don't run sendmail here.  I have no idea how useful this stuff
Xwould be to anybody who doesn't run MMDF.  It is possible that PMDF people
Xmight find this useful if the table formats are the same.
X
XI don't see any point in copyrighting this program.  But please leave
Xmy name intact and mark your own changes as such.  If anybody wishes
Xto discuss additions, please do it directly with me.
X
X		David Herron
X		Mon Nov 16 17:38:53 EST 1987
SHAR_EOF
if test 862 -ne "`wc -c < 'README'`"
then
	echo shar: error transmitting "'README'" '(should have been 862 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'RUN'" '(150 characters)'
if test -f 'RUN'
then
	echo shar: will not over-write existing file "'RUN'"
else
sed 's/^X//'  >'RUN' <<'SHAR_EOF'
X#! /bin/sh
X
Xpathalias \
X	-d cbatt -d vax135 -d ihnp4 -d cbosgd!ihnp4 -d ihnp4!cbosgd \
X	-v -l ukma \
X	d.* u.* \
X	2>ERRORS >ukma.new
X
XPROCESS ukma.new
SHAR_EOF
if test 150 -ne "`wc -c < 'RUN'`"
then
	echo shar: error transmitting "'RUN'" '(should have been 150 characters)'
fi
chmod +x 'RUN'
fi # end of overwriting check
echo shar: extracting "'process-uucp.8'" '(2819 characters)'
if test -f 'process-uucp.8'
then
	echo shar: will not over-write existing file "'process-uucp.8'"
else
sed 's/^X//'  >'process-uucp.8' <<'SHAR_EOF'
X.TH PROCESS-UUCP 8 "November 11, 1987" "U of Kentucky" "Brand X Programmer's Manual"
X.SH NAME
Xprocess-uucp \- generate MMDF mail style domain and channel tables from pathalias output
X.SH SYNOPSIS
X.B process-uucp
X[
X.B \-r
Xrelay-host ] [
X.B \-c
Xhost ... ] [
X.B \-d
Xdomain ... ] file ... 
X.SH DESCRIPTION
X.B Process-uucp(8)
Xtakes output from pathalias and generates tables one would want to use
Xwithin MMDF for routing UUCP based mail.
XThe two type of tables which can be generated are channel tables
Xand domain tables.
X.PP
XBy default, the domain tables contain entries of the form:
X.nf
X
X    domain: domain.upper.domain
X
X.fi
XAnd channel table entries are of the form:
X.nf
X
X    domain.upper.domain: path!path!path!%s
X
X.fi
XThese tables can be modified by the following options:
X.IP -r
XThis option causes domain entries to be changed to have the form:
X.nf
X
X    domain: domain.upper.domain, relay-host
X
X.nf
XLocally I use this option in generating the original table, then
Xwhen installing the table I run the following sed command:
X.nf
X
X    sed "s/, *`hostname`.*$//" <table.new >table
X
X.fi
Xwhich will remove the ", relay-host" stuff when we're installing
Xthe table on "relay-host".
XWe have one host here which interfaces us to the UUCP network,
Xand that host is what is listed as relay-host.
X.IP -c
XThis option causes there to be generated many channel tables
Xdepending on the first host of the path.
XThe intention is to have authorization set up so that channels
Xwhere we pay out money to make the UUCP connection can be restricted
Xfrom people as necessary.
XHowever, I have not managed to understand authorization as yet
Xand this is not used.
X.IP -d
XThis option selects domains for which to make extra domain tables.
XDomain entries for domains not listed in a -d option are
Xput into wrkdmn.uucp-top with an entry like:
X.nf
X
X    domain.upper.domain: domain.upper.domain
X
X.fi
XSometimes it is desired to have other domains seperated out into
Xtheir own tables.
XIf -d is used, entries in these tables will be as described earlier.
X.PP
XNOTE that a wrkdmn.uucp-uucp file is not automatically created.
X.SH FILES
Xwrkchn.uucp-uucp, wrkchn.uucp-<host>, wrkdmn.uucp-top, wrkdmn.uucp-<domain>
X.SH SEE ALSO
Xpathalias(1), the MMDF manual pages and installation documents
X.SH AUTHOR
XDavid Herron -- Resident E-Mail Hack
X.br
XUniversity of Kentucky
X.br
XMathematical Sciences
X.br
XPatterson Office Tower rm 907
X.br
XLexington, KY  40506
X.br
X.sp 2
Xdavid at ms.uky.edu, {rutgers,uunet,cbosgd}!ukma!david, david at ukma.bitnet
X.SH BUGS
XWhen writing records to files, all opens are done in "append" mode.
XThis means that if you do not remove the files before you run process-uucp
Xthen you probably won't get what you really want.
X.PP
XThe file names chosen are arguably silly.
XHowever for my justification of the file names,
Xsee the comments in the source.
SHAR_EOF
if test 2819 -ne "`wc -c < 'process-uucp.8'`"
then
	echo shar: error transmitting "'process-uucp.8'" '(should have been 2819 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'process-uucp.c'" '(10182 characters)'
if test -f 'process-uucp.c'
then
	echo shar: will not over-write existing file "'process-uucp.c'"
else
sed 's/^X//'  >'process-uucp.c' <<'SHAR_EOF'
X/*
X * process-uucp.c -- Make mmdf tables from uucp project derived information.
X *
X * USAGE: process-uucp [ -d domain ... ] [ -r relay-host ] 
X *			[ -c host ... ] file ...
X *
X * -d domain		generate a domain table for the domain.
X *			The file name is "wrkdmn.uucp-dom.ain", and
X *			the entries are like:
X *
X *	dom: dom.ain
X *
X * -r relay-host 	have the entries in the domain file be
X *			routed through "relay-host". i.e.
X *
X *	dom: dom.ain, relay-host
X *
X * -c host		This causes the wrkchn.uucp-uucp file to be split into
X *			multiple files.  If a path has its' first component
X *			as the named host, then the entry will be put
X *			into a seperate file named "wrkchn.uucp-host".
X *
X * The input file is the output of pathalias.  The format is:
X *
X * {host,domain}	a!b!c!...%s...
X *
X * From this we make both domain tables and channel tables.
X *
X * There are a couple of files which are automatically created:
X *
X * wrkchn.uucp-uucp	This contains domain:path entries for any paths
X *			which did not match hosts given in the -c list.
X * wrkdmn.uucp-top	This domains dom:dom.ain entries for domains
X *			which did not match domains given in -d's.
X *
X * A word about the file naming scheme.  The general format of file
X * names which I use on tables is "<type>.<source>-<subtype>".
X * "<type>" is something like domain, chan, or alias.  "<source>"
X * is some identifier saying where the information came from, like
X * uucp or bitnet.  "<subtype>" is something like domain for domain
X * tables, channel name for channel tables, or some other sort of
X * identifier depending on what the table is for.  (For instance,
X * I also have alias-global, alias-forward, and alias-local tables).
X *
X * Suggested use is something like:
X *
X * process-uucp -d uucp -d edu -d arpa pathalias-output-file
X *
X * AUTHOR:
X * 
X * David Herron, University of Kentucky Mathematical Sciences
X * Mon Nov 16 17:39:18 EST 1987
X */
X
X#include <stdio.h>
X#include <ctype.h>
X
Xstruct namelist {
X	char *name;
X	char *fname;
X	/* FILE *ofile; */
X};
X
X/* File name prefixes */
X#define WRK_CHAN	"wrkchn.uucp"
X#define WRK_DMN		"wrkdmn.uucp"
X
Xvoid process();
Xchar buf[BUFSIZ];
X
X
Xvoid addfile();
Xchar *files[BUFSIZ];
Xint numfiles = 0;
X
X
Xvoid addomain();
Xstruct namelist domains[BUFSIZ];
Xint numdomains = 0;
X
X
Xvoid addhost();
Xstruct namelist hosts[BUFSIZ];
Xint numhosts = 0;
X
X
Xchar *lowerify();
Xchar *RelayHost = (char *)0;
X
Xextern char *malloc();
X
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X{
X	int i;
X
X	if (argc <= 1) {
X		fprintf(stderr, "Usage: %s file ...\n", argv[0]);
X		exit(1);
X	}
X	sprintf(buf, "%s-uucp", WRK_CHAN);
X	close(creat(buf, 0644));
X	for (i=1; i < argc; i++) {
X		if (argv[i][0] == '-') {
X			switch(argv[i][1]) {
X			case 'd':
X				i++;
X				printf("addomain(%s);\n", argv[i]);
X				addomain(argv[i]);
X				break;
X			case 'c':
X				i++;
X				printf("addhost(%s);\n", argv[i]);
X				addhost(argv[i]);
X				break;
X			case 'r':
X				i++;
X				RelayHost = lowerify(argv[i]);
X				printf("relay-host: %s\n", RelayHost);
X				break;
X			default:
X				break;
X			}
X		}
X		else {
X			addfile(argv[i]);
X		}
X	}
X	for (i=0; i<numfiles; i++) {
X		/* printf("process(%s);\n", files[i]); */
X		process(files[i]);
X	}
X	exit(0);
X}
X
Xvoid
Xaddomain(s)
Xchar *s;
X{
X	int slen;
X
X	domains[numdomains].name = s;
X	slen = strlen(WRK_DMN) + 1 + strlen(s) + 1;
X	domains[numdomains].fname = malloc(slen);
X	sprintf(domains[numdomains].fname, "%s-%s", WRK_DMN, s);
X	numdomains++;
X}
X
Xvoid
Xaddhost(s)
Xchar *s;
X{
X	int slen;
X
X	hosts[numhosts].name = s;
X	slen = strlen(WRK_DMN) + 1 + strlen(s) + 1;
X	hosts[numhosts].fname = malloc(slen);
X	sprintf(hosts[numhosts].fname, "%s-%s", WRK_CHAN, s);
X	numhosts++;
X}
X
Xvoid
Xaddfile(s)
Xchar *s;
X{
X	files[numfiles++] = s;
X}
X
Xchar *
Xlowerify(s)
Xchar *s;
X{
X	register char *sp = s;
X
X	while (*sp != '\0') {
X		if (isupper(*sp))
X			*sp = tolower(*sp);
X		sp++;
X	}
X	return(s);
X}
X
X/*
X * indomain(name, domain) -- Test to see if the given name is 
X * within a domain ... we do this as a sort of reverse-strcmp().
X *
X * The return value is NULL if it is not, and a pointer within the
X * tested name if it is.
X */
Xchar *
Xindomain(name, domain)
Xchar *name, *domain;
X{
X	register char *namp, *domp;
X
X	namp = name; domp = domain;
X	if (!namp || !domp)
X		return(NULL);
X	/* printf("indomain(%s, %s); -- ", name, domain); */
X	/* Find the end of the strings */
X	namp = &(name[strlen(name)-1]);
X	domp = &(domain[strlen(domain)-1]);
X	/* printf("start at namp=<%s> domp=<%s> -- ", namp, domp); */
X	for (; namp>=name && domp>=domain; namp--, domp--)
X		if (namp[0] != domp[0])
X			break;
X	namp++; domp++;
X	/* printf("match at namp=<%s> domp=<%s>\n", namp, domp); */
X	if (
X	       (namp>name && domp==domain && namp[-1]=='.') 
X	    || namp == name
X	   )
X		return(namp);
X	else
X		return(NULL);
X}
X
X/* These have to be here because the compiler chokes if they're
X * inside process().
X */
Xchar pathbuf[BUFSIZ], dmnbuf[BUFSIZ], bf2[BUFSIZ];
X
X/*
X * process(file) -- Process the file making all the tables which 
X * which we were told to make on the command line.
X *
X * A note about the algorithm.  If you read the code below you will
X * notice that I am constantly open()ing and close()ing files to
X * append records to the end of the files.  This is because, in
X * theory at least, someone could have 50 domain files that they
X * generate from this program.  
X *
X * Maybe in practice one will never have more than 10 (to pick a number 
X * out of the air).  If you really want to "fix" this, be my guest.  It 
X * should be a fairly trivial re-write.  The "fix" I have in mind is to
X * change "domains[]" into an array of structures remembering the domain
X * name, the file name for the domain, and the FILE * pointing to that
X * file.  Then there are a few places below where one looks up the
X * file name, fopen()s the file in "a" mode, write the record, and close
X * the file.  One would need to change those places to merely write the 
X * record after looking up the FILE * in the struct namelist.
X *
X * NOTE NOTE NOTE ... The procedure as it is opens files in append mode
X * and there's no automatic truncation of any files.  You will have to
X * do this by hand.  (Well, engrave it in your shell script which processes
X * the pathalias output).
X */
Xvoid
Xprocess(file)
Xchar *file;
X{
X	register char *sp, *sp2;
X	register int i;
X	FILE *ifile, *cfile, *tcfile, *dfile, *topfile;
X	int hlen;
X	char *index(), *strcpy(), *strcat();
X
X	ifile = fopen(file, "r");
X	if (ifile == NULL) {
X		/* printf("Open of %s failed with errno=%d\n", file, errno); */
X		perror(file);
X		return;
X	}
X	sprintf(buf, "%s-uucp", WRK_CHAN);
X	cfile = fopen(buf, "a");
X	if (cfile == NULL) {
X		/* printf("Open of %s failed with errno=%d\n", buf, errno); */
X		perror(buf);
X		fclose(ifile);
X		return;
X	}
X	sprintf(buf, "%s-top", WRK_DMN);
X	topfile = fopen(buf, "a");
X	if (topfile == NULL) {
X		/* printf("Open of %s failed with errno=%d\n", buf, errno); */
X		perror(buf);
X		fclose(ifile);
X		fclose(cfile);
X		return;
X	}
X	while (fgets(buf, BUFSIZ, ifile) != NULL) {
X		if ((sp = index(buf, '\n')) != NULL)
X			*sp = '\0';
X		/* copy the domain part */
X		for (sp=buf, sp2=dmnbuf;
X		     *sp!='\0' && *sp!=' ' && *sp!='\t';
X		     sp++, sp2++)
X			*sp2 = *sp;
X		*sp2 = '\0';
X		/* Then the path part */
X		if (*sp != '\0') {
X			while (*sp==' ' || *sp=='\t')
X			     sp++;
X			for (sp2=pathbuf;
X			     *sp!='\0' && *sp!=' ' && *sp!='\t';
X			     sp++, sp2++)
X				*sp2 = *sp;
X			*sp2 = '\0';
X		}
X		if (pathbuf[0] == '\0')
X			strcpy(pathbuf, "NO-PATH-GIVEN!%s");
X		/* printf("before = %s\n", dmnbuf); */
X		(void) lowerify(dmnbuf);
X		/* printf("after = %s\n", dmnbuf); */
X		if ((sp = index(dmnbuf, '.')) == NULL)
X			strcat(dmnbuf, ".uucp");
X		if (dmnbuf[0] == '.')
X			for (sp = dmnbuf; *sp != '\0'; sp++)
X				*sp = *(sp+1);
X		/*
X		 * If the given domain name is within one of those for which
X		 * we have a domain table, output it into the domain table
X		 * and into the channel table.
X		 */
X		for (i=0; i<numdomains; i++) {
X			if ((sp2=indomain(dmnbuf, domains[i].name)) != NULL) {
X				if (sp2 > dmnbuf) {
X					dfile = fopen(domains[i].fname, "a");
X					/* write out first part of dom.ain */
X					for (sp=dmnbuf; sp < (sp2-1); sp++)
X						fputc(*sp, dfile);
X					if (RelayHost)
X						fprintf(dfile, ":\t%s, %s\n", 
X							dmnbuf, RelayHost);
X					else
X						fprintf(dfile, ":\t%s\n", dmnbuf);
X					fclose(dfile);
X					break;
X				}
X				else {
X					/*
X					 * This case is for when the name we're
X					 * testing fully matches the domain name
X					 * for one of the tables.  We aren't 
X					 * supposed to make an entry for him
X					 * in this table, but in the table for
X					 * the parent domain.  But we don't
X					 * know here whether we are keeping
X					 * a table for that domain ... HOWEVER,
X					 * if we keep looping through the rest of
X					 * the table names we will eventually 
X					 * find out.
X					 */
X					continue;
X				}
X			}
X		}
X		/*
X		 * This case is for when we've run through the entire list 
X		 * of domains for which we have tables and the name we
X		 * have does not fit with any of those.  So, we insert
X		 * it into the top-level table.
X		 */
X		if (i == numdomains) {
X			if (RelayHost)
X				fprintf(topfile, "%s:\t%s, %s\n", 
X					dmnbuf, dmnbuf, RelayHost);
X			else
X				fprintf(topfile, "%s:\t%s\n", dmnbuf, dmnbuf);
X		}
X		/*
X		 * This section handles making entries in the channel table.
X		 */
X		if (numhosts > 0) {
X			for (i=0; i<numhosts; i++) {
X				hlen = strlen(hosts[i].name);
X				/* This shortcuts if we already know that
X				 * the names CANNOT match. i.e. if the next
X				 * character is not '!', then the lengths
X				 * of the two names are not the same.
X				 */
X				if (pathbuf[hlen] != '!')
X					continue;
X				if (strncmp(pathbuf, hosts[i].name, hlen) != 0)
X					continue;
X				tcfile = fopen(hosts[i].fname, "a");
X				fprintf(tcfile, "%s:\t%s\n", dmnbuf, pathbuf);
X				fclose(tcfile);
X				break;
X			}
X			/* If we make it all the way through the list, then
X			 * we didn't write out the record to a file.  Put
X			 * the record out into the default file.
X			 */
X			if (i == numhosts)
X				fprintf(cfile, "%s:\t%s\n", dmnbuf, pathbuf);
X		}
X		else
X			fprintf(cfile, "%s:\t%s\n", dmnbuf, pathbuf);
X	}
X	/* printf("done with %s\n", file); */
X	fclose(cfile);
X	fclose(ifile);
X	fclose(topfile);
X}
SHAR_EOF
if test 10182 -ne "`wc -c < 'process-uucp.c'`"
then
	echo shar: error transmitting "'process-uucp.c'" '(should have been 10182 characters)'
fi
fi # end of overwriting check
echo shar: done with directory "'process-uucp'"
cd ..
:	End of shell archive
exit 0
--
<---- David Herron -- Resident E-Mail Hack     <david at ms.uky.edu>
<---- or:                {rutgers,uunet,cbosgd}!ukma!david, david at UKMA.BITNET
<---- "The market doesn't drop hundreds of points on a normal day..." --
<---- 		Fidelity Investments Corporation

-- 
For comp.sources.unix stuff, mail to sources at uunet.uu.net.



More information about the Comp.sources.unix mailing list