4.3BSD/usr/contrib/pathalias/printit.c

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

/* pathalias -- by steve bellovin, as told to peter honeyman */
#ifndef lint
static char	*sccsid = "@(#)printit.c	8.2 (down!honey) 86/01/29";
#endif

#include "def.h"

/* use lots of char bufs -- profiling indicates this costs about 5 kbytes */

/* in practice, even the longest paths are < 100 bytes */
#define PSIZE 512

printit()
{	link *l;
	char pbuf[PSIZE];

	/* print home */
	if (Cflag)
		printf("%ld\t", (long) Home->n_cost);
	printf("%s\t%%s\n", Home->n_name);
	
	strcpy(pbuf, "%s");
	for (l = Home->n_link; l; l = l->l_next) {
		if (l->l_flag & LTREE) {
			preorder(l, pbuf);
			strcpy(pbuf, "%s");
		}
	}
}

/* preorder traversal of shortest path tree */
preorder(l, ppath)
register link *l;
char *ppath;
{
	register node *n;
	char npath[PSIZE];

	setpath(l, ppath, npath);
	n = l->l_to;
	if ((n->n_flag & NNET) || ISADOMAIN(n))
		printnet(n, npath, n->n_cost);
	else
		printhost(n, npath, n->n_cost);
	for (l = n->n_link; l; l = l->l_next)
		if (l->l_flag & LTREE)
			preorder(l, npath);
}

setpath(l, ppath, npath) 
link *l;
register char *ppath, *npath;
{
	register node *next;
	char netchar;
	extern char *hostpath();

	next = l->l_to;
	/*
	 * for magic @-% conversion.
	 * assume that gateways to domains want no @'s
	 */
	if (next->n_parent->n_flag & ATSIGN || ISADOMAIN(next))
		next->n_flag |= ATSIGN;

	/* special handling for aliases , domains, and nets */
	if ((l->l_flag & LALIAS) || (next->n_flag & NNET) || ISADOMAIN(next)) {
		strcpy(npath, ppath);
		return;
	}
		
	netchar = NETCHAR(l);
	if (netchar == '@')
		if (next->n_flag & ATSIGN)
			netchar = '%';	/* shazam?  shaman? */
		else
			next->n_flag |= ATSIGN;

	/* remainder should be a sprintf -- foo on '%' as an operator */
	for ( ; *npath = *ppath; ppath++) {
		if (*ppath == '%') {
			switch(ppath[1]) {
			case 's':
				ppath++;
				npath = hostpath(npath, l, netchar);
				break;

			case '%':
				*++npath = *++ppath;
				npath++;
				break;

			default:
				fprintf(stderr, "%s: %%%c found in setpath\n",
						ProgName, ppath[1]);
				badmagic(1);
				break;
			}
		} else
			npath++;
	}
}

char *
hostpath(path, l, netchar)
register char *path;
register link *l;
char netchar;
{
	register node *prev;

	prev = l->l_to->n_parent;
	if (NETDIR(l) == LLEFT) {
		/* host!user */
		strcpy(path, l->l_to->n_name);
		path += strlen(path);
		while (ISADOMAIN(prev)) {
			strcpy(path, prev->n_name);
			path += strlen(path);
			prev = prev->n_parent;
		}
		*path++ = netchar;
		if (netchar == '%')
			*path++ = '%';
		*path++ = '%';
		*path++ = 's';
	} else {
		/* %s@host */
		*path++ = '%';
		*path++ = 's';
		*path++ = netchar;
		if (netchar == '%')
			*path++ = '%';
		strcpy(path, l->l_to->n_name);
		path += strlen(path);
		while (ISADOMAIN(prev)) {
			strcpy(path, prev->n_name);
			path += strlen(path);
			prev = prev->n_parent;
		}
	}
	return(path);
}

STATIC
printhost(n, path, cost)
node *n;
char *path;
Cost cost;
{
	/* skip private hosts */
	if ((n->n_flag & ISPRIVATE) == 0) {
		if (Cflag)
			printf("%ld\t", (long) cost);
		fputs(n->n_name, stdout);
		putchar('\t');
		puts(path);
	}
}

STATIC
printnet(n, path, cost)
node	*n;
char	*path;
Cost	cost;
{
	node	*parent;

	/* print domains only */
	if (!ISADOMAIN(n))
		return;

	/* print top-level domain */
	if (!ISADOMAIN(n->n_parent)) {
		if (n->n_flag & ISPRIVATE)
			fprintf(stderr, "%s: warning: private top-level domain %s ignored\n", ProgName, n->n_name);
		else
			printdomain(n, path, cost);
		return;
	}

	/* remainder is for subdomains */

	/* don't print if it has a non-private ancestor */
	for (parent = n->n_parent; parent; parent = parent->n_parent)
		if (ISADOMAIN(parent) && (parent->n_flag & ISPRIVATE) == 0)
			return;

	/* don't print if this domain is also private */
	if (n->n_flag & ISPRIVATE)
		return;

	/* ancestors all private, this domain not private */
	printdomain(n, path, cost);
}

STATIC
printdomain(n, path, cost)
node *n;
char *path;
Cost cost;
{
	/* skip subdomains, since the gateway to the parent suffices */
	if (ISADOMAIN(n->n_parent))
		return;
	if (Cflag)
		printf("%ld\t", (long) cost);
	do {
		fputs(n->n_name, stdout);
		n = n->n_parent;
	} while (ISADOMAIN(n));
	putchar('\t');
	puts(path);
}