|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T x
Length: 7470 (0x1d2e)
Types: TextFile
Names: »xalparse.c«
└─⟦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«
/*
** 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';
}