DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T x

⟦b23eddff1⟧ TextFile

    Length: 7470 (0x1d2e)
    Types: TextFile
    Names: »xalparse.c«

Derivation

└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit
    └─⟦bfebc70e2⟧ »EurOpenD3/mail/sendmail-5.65b+IDA-1.4.3.tar.Z« 
        └─⟦f9e35cd84⟧ 
            └─⟦this⟧ »sendmail/ida/aux/xalparse.c« 

TextFile

/*
**  XALPARSE -- Xaliases file parser.
**  Copyright (c) 1987 Lennart Lovstrand
**  CIS Dept, Univ of Linkoping, Sweden
**
**  Use it, abuse it, but don't sell it.
*/

#include "useful.h"
#include <stdio.h>
#include <ctype.h>

#ifndef lint
static char     SccsId[] = "@(#)xalparse.c 1.1 (lel@ida.liu.se) 4/12/87";

#endif /* !lint */

struct alias {
	bool            a_in, a_out;
	char           *a_name;
};

#define ANULL	(struct alias *) NULL

#ifdef __STDC__
void            parsefile (FILE *, FILE *, FILE *);
int             peekc (FILE *);
int             readline (char *, int, FILE *);
char           *parsething (char *, struct alias **, int);
void            parseline (char *, struct alias **, struct alias **);
void            freebufs (struct alias **, struct alias **);
void            compressline (char *);

#else				/* !__STDC__ */
void            parsefile ();
int             peekc ();
int             readline ();
char           *parsething ();
void            parseline ();
void            freebufs ();
void            compressline ();
char           *index ();
char           *malloc ();

#endif				/* __STDC__ */

/*
**  XPARSE -- Parse an xaliases file, producing aliases + generics files.
**
**	This program parses a file in ``xaliases'' format, producing
**	a standard aliases file + a generics file.  The xaliases input
**	file has entry of the following format:
**		generic_list: mbox_list
**	where elements in both lists are separated by commas.  In
**	addition, each element in the mbox_list may be prefixed with
**	either or both of the ``redirection characters,'' "<" and ">".

**	In its simplest form, the generic_list has just one member and
**	the mbox_list uses no redirection characters.  This
**	corresponds exactly to the standard aliases format and
**	function.

**	The first extention is made by allowing more than one entry on
**	the left hand side, thus making "a, b: c" as shorthand for the
**	two entries "a: c" and "b: c".

**	The second extension is made by adding the previously
**	mentioned redirection characters to the addresses on the right
**	hand side.  These control in what direction the aliases should
**	be used.
**
**	etc.
*/

int             iflag = FALSE, Iflag = FALSE, Oflag = FALSE;

main (argc, argv)
	int             argc;
	char          **argv;
{
	extern int      optind;
	extern char    *optarg;
	char            c;
	FILE           *xaliases, *aliases, *generics;


	if (argc != 4) {
		fprintf (stderr, "usage: %s xaliases aliases generics\n", argv[0]);
		exit (1);
	}
	if (strcmp (argv[1], "-") == 0)
		xaliases = stdin;
	else {
		xaliases = fopen (argv[1], "r");
		if (xaliases == NULL)
			perror (argv[1]), exit (2);
	}
	aliases = fopen (argv[2], "w");
	if (aliases == NULL)
		perror (argv[2]), exit (2);
	generics = fopen (argv[3], "w");
	if (generics == NULL)
		perror (argv[3]), exit (2);

	parsefile (xaliases, aliases, generics);
	exit (0);
}

void
parsefile (xaliases, aliases, generics)
	FILE           *xaliases, *aliases, *generics;
{
	char            line[BUFSIZ];
	struct alias   *rhs[BUFSIZ], *lhs[BUFSIZ];
	struct alias  **a, **r, **first;

	while (readline (line, sizeof (line), xaliases) >= 0) {
		parseline (line, lhs, rhs);

		for (first = rhs; *first != ANULL; first++)
			if ((*first) -> a_in)
				break;
		if (*first != ANULL)
			for (a = lhs; *a != ANULL; a++) {
				fprintf (aliases, "%s:%s", (*a) -> a_name, (*first) -> a_name);
				for (r = first + 1; *r != ANULL; r++)
					if ((*r) -> a_in)
						fprintf (aliases, ",%s", (*r) -> a_name);
				fprintf (aliases, "\n");
			}

		for (first = rhs; *first != ANULL; first++)
			if ((*first) -> a_out)
				break;
		if (*first != ANULL) {
			fprintf (generics, "%s\t%s", lhs[0] -> a_name, (*first) -> a_name);
			for (r = first + 1; *r != ANULL; r++)
				if ((*r) -> a_out)
					fprintf (generics, " %s", (*r) -> a_name);
			fprintf (generics, "\n");
		}
		freebufs (lhs, rhs);
	}
}

/**
 **	PEEKC -- Return the next char to be read.
 **/

peekc (stream)
	FILE           *stream;
{
	int             c;

	c = getc (stream);
	if (c != EOF)
		ungetc (c, stream);
	return c;
}

/**
 **	READLINE -- Read a (logical) line and return the # of chars read
 **/

readline (buf, bufsiz, stream)
	char           *buf;
	int             bufsiz;
	FILE           *stream;
{
	int             len;
	char           *sharp;

	if (fgets (buf, bufsiz, stream) == NULL)
		return -1;
	buf[strlen (buf) - 1] = '\0';

	/*
	 * if ((sharp = index(buf, '#')) != NULL) sharp = '\0';
	 */
	if (buf[0] == '#')
		buf[0] = '\0';

	len = strlen (buf);
	if (isspace (peekc (stream)))
		return len + readline (&buf[len], bufsiz - len, stream);
	else
		return len;
}

/**
 **	PARSETHING
 **/


#define LHS	1
#define RHS	2

char           *
parsething (line, thing, side)
	char           *line;
	struct alias  **thing;
	int             side;
{
	register char  *s, *d;
	register        bool
	                insideroute = FALSE, insidestring = FALSE, quotedchar = FALSE;
	bool            i_mark, o_mark;
	char            buf[BUFSIZ];

	s = line;
	d = buf;

	while (*s != '\0' && isspace (*s))
		s++;
	if (side == RHS) {
		if (o_mark = (*s == '<'))
			s++;
		if (i_mark = (*s == '>'))
			s++;
		i_mark = i_mark || !o_mark;	/* default to '>' */
		while (*s != '\0' && isspace (*s))
			s++;
	}
	for (; *s != '\0'; s++) {
		/* exit if non-quoted comma (or colon & LHS) */
		if (!insidestring && !quotedchar && !insideroute &&
		    *s == ',' || ((side == LHS) && *s == ':'))
			break;

		/* copy if not unquoted whitespace */
		if (insidestring || quotedchar || !isspace (*s))
			*d++ = *s;

		/* special quote character handling */
		if (quotedchar)
			quotedchar = FALSE;
		else {
			quotedchar = (*s == '\\');
			if (!insidestring)
				if (*s == '<')
					insideroute = TRUE;
				else if (*s == '>')
					insideroute = FALSE;
			if (*s == '"')
				insidestring = !insidestring;
		}
	}
	while (d > buf && isspace (d[-1]))
		d--;
	*d = '\0';

	if (d == buf && *s == '\0') {
		*thing = ANULL;
		return NULL;
	} else {
		*thing = (struct alias *) malloc (sizeof (struct alias));
		(*thing) -> a_in = i_mark;
		(*thing) -> a_out = o_mark;
		(*thing) -> a_name = malloc (strlen (buf) + 1);
		strcpy ((*thing) -> a_name, buf);
		return s;
	}
}

/**
 **	PARSELINE
 **/

void
parseline (line, lhs, rhs)
	char           *line;
	struct alias  **lhs, **rhs;
{
	line--;

	while ((line = parsething (line + 1, lhs++, LHS)) != NULL)
		if (*line == ':')
			break;
	*lhs = NULL;

	if (line != NULL)
		while ((line = parsething (line + 1, rhs++, RHS)) != NULL);
	*rhs = ANULL;
}

/**
 **	FREEBUFS
 **/

void
freebufs (lhs, rhs)
	struct alias  **lhs, **rhs;
{
	while (*lhs != ANULL) {
		free ((*lhs) -> a_name);
		free (*lhs);
		lhs++;
	}
	while (*rhs != ANULL) {
		free ((*rhs) -> a_name);
		free (*rhs);
		rhs++;
	}
}

/**
 **	COMPRESSLINE -- Remove all heading & trailing whitespace around items.
 **/

void
compressline (line)
	char           *line;
{
	register char  *d, *s, *b, *e;

	for (d = s = line; *s != '\0'; s++) {
		/* eat initial whitespace */
		while (*s != '\0' && isspace (*s))
			s++;
		if (*s == '\0')
			break;
		/* remember beginning of "word" and find end */
		b = s;
		while (*s != '\0' && *s != ',' && *s != ':')
			s++;
		e = s - 1;
		/* backspace end thru whitespace */
		while (e >= b && isspace (*e))
			e--;
		/* copy "word" w/o whitespace */
		while (b <= e)
			*d++ = *b++;
		/* copy separator */
		*d++ = *s;
		if (*s == '\0')
			return;
	}
	*d = '\0';
}