diff options
-rw-r--r-- | Makefile.am | 3 | ||||
-rw-r--r-- | ckaliases.c | 416 | ||||
-rw-r--r-- | ckaliases.h | 62 | ||||
-rw-r--r-- | gram.y | 336 | ||||
-rw-r--r-- | lex.l | 213 |
5 files changed, 522 insertions, 508 deletions
diff --git a/Makefile.am b/Makefile.am index c43b7a3..12f531c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -16,3 +16,2 @@ -AM_INSTALLCHECK_STD_OPTIONS_EXEMPT=ckaliases AM_YFLAGS=-vtd @@ -22 +21,3 @@ noinst_HEADERS=gram.h ckaliases_SOURCES=gram.y lex.l ckaliases.c ckaliases.h +LDADD=../lib/libgsc.a ../gnu/libgnu.a +INCLUDES = -I$(top_srcdir)/lib -I$(top_srcdir)/gnu -I../gnu diff --git a/ckaliases.c b/ckaliases.c index 343a52f..d77e62d 100644 --- a/ckaliases.c +++ b/ckaliases.c @@ -1,3 +1,3 @@ /* ckaliases - verify syntax of sendmail-style alias files - Copyright (C) 2005 Sergey Poznyakoff + Copyright (C) 2005, 2007 Sergey Poznyakoff @@ -16,24 +16,4 @@ -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif -#include <stdio.h> -#include <stdlib.h> -#define obstack_chunk_alloc malloc -#define obstack_chunk_free free -#include <obstack.h> #include "ckaliases.h" -void * -xmalloc(size_t size) -{ - void *p = malloc(size); - if (!p) { - fprintf(stderr, "not enough memory\n"); - exit(1); - } - return p; -} - - #ifndef CHAR_BIT @@ -53,48 +33,53 @@ xmalloc(size_t size) void -TC(unsigned *R, int n) +TC (unsigned *R, int n) { - register int rowsize; - register unsigned mask; - register unsigned *rowj; - register unsigned *rp; - register unsigned *rend; - register unsigned *ccol; - - unsigned *relend; - unsigned *cword; - unsigned *rowi; - - rowsize = WORDSIZE(n) * sizeof(unsigned); - relend = (unsigned *) ((char *) R + (n * rowsize)); - - cword = R; - mask = 1; - rowi = R; - while (rowi < relend) { - ccol = cword; - rowj = R; - - while (rowj < relend) { - if (*ccol & mask) { - rp = rowi; - rend = (unsigned *) ((char *) rowj + rowsize); - - while (rowj < rend) - *rowj++ |= *rp++; - } else { - rowj = (unsigned *) ((char *) rowj + rowsize); - } - - ccol = (unsigned *) ((char *) ccol + rowsize); - } - - mask <<= 1; - if (mask == 0) { - mask = 1; - cword++; - } - rowi = (unsigned *) ((char *) rowi + rowsize); - } -} + register int rowsize; + register unsigned mask; + register unsigned *rowj; + register unsigned *rp; + register unsigned *rend; + register unsigned *ccol; + + unsigned *relend; + unsigned *cword; + unsigned *rowi; + + rowsize = WORDSIZE (n) * sizeof (unsigned); + relend = (unsigned *) ((char *) R + (n * rowsize)); + + cword = R; + mask = 1; + rowi = R; + while (rowi < relend) + { + ccol = cword; + rowj = R; + + while (rowj < relend) + { + if (*ccol & mask) + { + rp = rowi; + rend = (unsigned *) ((char *) rowj + rowsize); + + while (rowj < rend) + *rowj++ |= *rp++; + } + else + { + rowj = (unsigned *) ((char *) rowj + rowsize); + } + + ccol = (unsigned *) ((char *) ccol + rowsize); + } + mask <<= 1; + if (mask == 0) + { + mask = 1; + cword++; + } + rowi = (unsigned *) ((char *) rowi + rowsize); + } +} @@ -102,21 +87,25 @@ TC(unsigned *R, int n) void -slist_add(SLIST **plist, char *str) +slist_add (SLIST **plist, char *str) { - struct string_list *p = xmalloc(sizeof(*p)); - p->str = str; - p->next = NULL; - - if (!*plist) { - *plist = xmalloc(sizeof(**plist)); - (*plist)->head = NULL; - } - - if ((*plist)->head == NULL) { - (*plist)->head = p; - (*plist)->count = 0; - } else { - (*plist)->tail->next = p; - (*plist)->count++; - } - (*plist)->tail = p; + struct string_list *p = xmalloc (sizeof (*p)); + p->str = str; + p->next = NULL; + + if (!*plist) + { + *plist = xmalloc (sizeof (**plist)); + (*plist)->head = NULL; + } + + if ((*plist)->head == NULL) + { + (*plist)->head = p; + (*plist)->count = 0; + } + else + { + (*plist)->tail->next = p; + (*plist)->count++; + } + (*plist)->tail = p; } @@ -124,20 +113,21 @@ slist_add(SLIST **plist, char *str) void -slist_append(SLIST **pdst, SLIST *src) +slist_append (SLIST **pdst, SLIST *src) { - struct string_list *tail; - - if (!*pdst) { - *pdst = xmalloc(sizeof(**pdst)); - (*pdst)->head = NULL; - (*pdst)->count = 0; - } + struct string_list *tail; + + if (!*pdst) + { + *pdst = xmalloc (sizeof (**pdst)); + (*pdst)->head = NULL; + (*pdst)->count = 0; + } + + if ((*pdst)->head = NULL) + (*pdst)->head = src->head; + + for (tail = src->tail; tail->next; tail = tail->next) + ; - if ((*pdst)->head = NULL) - (*pdst)->head = src->head; - - for (tail = src->tail; tail->next; tail = tail->next) - ; - - (*pdst)->tail = tail; - (*pdst)->count += src->count; + (*pdst)->tail = tail; + (*pdst)->count += src->count; } @@ -145,11 +135,11 @@ slist_append(SLIST **pdst, SLIST *src) char * -slist_member(SLIST *plist, char *name) +slist_member (SLIST *plist, char *name) { - struct string_list *p; - - if (plist) - for (p = plist->head; p; p = p->next) - if (p->str && strcmp(p->str, name) == 0) - return p->str; - return NULL; + struct string_list *p; + + if (plist) + for (p = plist->head; p; p = p->next) + if (p->str && strcmp (p->str, name) == 0) + return p->str; + return NULL; } @@ -157,23 +147,23 @@ slist_member(SLIST *plist, char *name) void -slist_destroy(SLIST **plist) +slist_destroy (SLIST **plist) { - struct string_list *p; - if (!plist || !*plist) - return; - p = (*plist)->head; - while (p) { - struct string_list *next = p->next; - free(p); - p = next; - } - free(*plist); - *plist = NULL; + struct string_list *p; + if (!plist || !*plist) + return; + p = (*plist)->head; + while (p) + { + struct string_list *next = p->next; + free (p); + p = next; + } + free (*plist); + *plist = NULL; } - - -typedef struct { - char *name; - SLIST *exp; +typedef struct +{ + char *name; + SLIST *exp; } ALIAS; @@ -185,9 +175,9 @@ ALIAS *aliases; void -regalias(char *name, SLIST *exp) +regalias (char *name, SLIST *exp) { - ALIAS a; - a.name = name; - a.exp = exp; - obstack_grow(&alias_stk, &a, sizeof a); - alias_count++; + ALIAS a; + a.name = name; + a.exp = exp; + obstack_grow (&alias_stk, &a, sizeof a); + alias_count++; } @@ -195,5 +185,5 @@ regalias(char *name, SLIST *exp) void -begin_aliases() +begin_aliases () { - obstack_init(&alias_stk); + obstack_init (&alias_stk); } @@ -201,5 +191,5 @@ begin_aliases() static int -alias_cmp(const void *a, const void *b) +alias_cmp (const void *a, const void *b) { - return strcmp(((ALIAS*)a)->name, ((ALIAS*)b)->name); + return strcmp (((ALIAS *) a)->name, ((ALIAS *) b)->name); } @@ -207,25 +197,25 @@ alias_cmp(const void *a, const void *b) static int -alias_cmp2(const void *a, const void *b) +alias_cmp2 (const void *a, const void *b) { - char *aname = ((ALIAS*)a)->name; - char *bname = ((ALIAS*)b)->name; - int rc; - int alen; - int blen; - char *p; - - if ((p = strchr(aname, '@')) && slist_member(cw_list, p+1)) - alen = p - aname; - else - alen = strlen(aname); - - if ((p = strchr(bname, '@')) && slist_member(cw_list, p+1)) - blen = p - bname; - else - blen = strlen(bname); - - if (alen == blen) - return memcmp(aname, bname, alen); - - return strcmp(aname, bname); + char *aname = ((ALIAS *) a)->name; + char *bname = ((ALIAS *) b)->name; + int rc; + int alen; + int blen; + char *p; + + if ((p = strchr (aname, '@')) && slist_member (cw_list, p + 1)) + alen = p - aname; + else + alen = strlen (aname); + + if ((p = strchr (bname, '@')) && slist_member (cw_list, p + 1)) + blen = p - bname; + else + blen = strlen (bname); + + if (alen == blen) + return memcmp (aname, bname, alen); + + return strcmp (aname, bname); } @@ -233,10 +223,13 @@ alias_cmp2(const void *a, const void *b) void -end_aliases() +end_aliases () { - int i; - aliases = obstack_finish(&alias_stk); - qsort(aliases, alias_count, sizeof aliases[0], alias_cmp); - for (i = 1; i < alias_count; i++) - if (alias_cmp(aliases + i - 1, aliases + i) == 0) - error("alias `%s' multiply defined", aliases[i].name); + int i; + aliases = obstack_finish (&alias_stk); + qsort (aliases, alias_count, sizeof aliases[0], alias_cmp); + for (i = 1; i < alias_count; i++) + if (alias_cmp (aliases + i - 1, aliases + i) == 0) + { + error (0, 0, "alias `%s' multiply defined", aliases[i].name); + error_count++; + } } @@ -245,11 +238,11 @@ end_aliases() int -find_alias(char *name) +find_alias (char *name) { - ALIAS a, *p; + ALIAS a, *p; - if (!name) - return -1; - a.name = name; - p = bsearch(&a, aliases, alias_count, sizeof aliases[0], alias_cmp2); - return p ? p - aliases : -1; + if (!name) + return -1; + a.name = name; + p = bsearch (&a, aliases, alias_count, sizeof aliases[0], alias_cmp2); + return p ? p - aliases : -1; } @@ -258,5 +251,5 @@ find_alias(char *name) static void -alias_setbit(unsigned *r, unsigned rowsize, unsigned row, unsigned col) +alias_setbit (unsigned *r, unsigned rowsize, unsigned row, unsigned col) { - SETBIT(r + rowsize * row, col); + SETBIT (r + rowsize * row, col); } @@ -264,5 +257,5 @@ alias_setbit(unsigned *r, unsigned rowsize, unsigned row, unsigned col) static int -alias_bitisset(unsigned *r, unsigned rowsize, unsigned row, unsigned col) +alias_bitisset (unsigned *r, unsigned rowsize, unsigned row, unsigned col) { - return BITISSET(r + rowsize * row, col); + return BITISSET (r + rowsize * row, col); } @@ -271,16 +264,19 @@ alias_bitisset(unsigned *r, unsigned rowsize, unsigned row, unsigned col) void -mark_connected(unsigned *r, unsigned size) +mark_connected (unsigned *r, unsigned size) { - int i; - - for (i = 0; i < alias_count; i++) { - if (aliases[i].exp) { - struct string_list *p; - for (p = aliases[i].exp->head; p; p = p->next) { - int n = find_alias(p->str); - if (n >= 0) - alias_setbit(r, size, i, n); - } - } + int i; + + for (i = 0; i < alias_count; i++) + { + if (aliases[i].exp) + { + struct string_list *p; + for (p = aliases[i].exp->head; p; p = p->next) + { + int n = find_alias (p->str); + if (n >= 0) + alias_setbit (r, size, i, n); + } } + } } @@ -288,10 +284,14 @@ mark_connected(unsigned *r, unsigned size) void -check_circular_deps(unsigned *r, unsigned size) +check_circular_deps (unsigned *r, unsigned size) { - int i; - - for (i = 0; i < alias_count; i++) { - if (alias_bitisset(r, size, i, i)) - error("%s: circular dependency", aliases[i].name); + int i; + + for (i = 0; i < alias_count; i++) + { + if (alias_bitisset (r, size, i, i)) + { + error (0, 0, "%s: circular dependency", aliases[i].name); + error_count++; } + } } @@ -299,23 +299,23 @@ check_circular_deps(unsigned *r, unsigned size) void -check_aliases() +check_aliases () { - size_t size; - unsigned *r; - - /* Allocate matrix */ - size = (alias_count + BITS_PER_WORD - 1) / BITS_PER_WORD; - r = xmalloc(alias_count*size*sizeof(*r)); - memset(r, 0, alias_count*size*sizeof(*r)); + size_t size; + unsigned *r; + + /* Allocate matrix */ + size = (alias_count + BITS_PER_WORD - 1) / BITS_PER_WORD; + r = xmalloc (alias_count * size * sizeof (*r)); + memset (r, 0, alias_count * size * sizeof (*r)); - /* First pass: mark directly connected entries */ - mark_connected(r, size); + /* First pass: mark directly connected entries */ + mark_connected (r, size); - /* Compute transitive closure of the matrix r */ - TC(r, alias_count); + /* Compute transitive closure of the matrix r */ + TC (r, alias_count); - /* Third pass: check for circular deps */ - check_circular_deps(r, size); + /* Third pass: check for circular deps */ + check_circular_deps (r, size); - if (verbose) - printf("%lu aliases\n", alias_count); + if (verbose) + printf ("%lu aliases\n", alias_count); } diff --git a/ckaliases.h b/ckaliases.h index 8d6546d..d3e053c 100644 --- a/ckaliases.h +++ b/ckaliases.h @@ -16,32 +16,54 @@ +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif +#include <stdio.h> +#include <stdlib.h> +#define obstack_chunk_alloc malloc +#define obstack_chunk_free free +#include <obstack.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <unistd.h> +#include <sys/file.h> +#include <sys/stat.h> +#include <errno.h> +#include <string.h> +#include "getopt.h" +#include "progname.h" +#include "error.h" +#include "xalloc.h" + extern char *file_name; extern int line_num; +extern int error_count; -void init_lex(); -void lex_debug(int n); -void openaliases(char *name); -void openaliases_prefix(char *prefix, char *name); +void init_lex (); +void lex_debug (int n); +void openaliases (char *name); +void openaliases_prefix (char *prefix, char *name); -struct string_list { - struct string_list *next; - char *str; +struct string_list +{ + struct string_list *next; + char *str; }; -typedef struct slist { - struct string_list *head, *tail; - int count; +typedef struct slist +{ + struct string_list *head, *tail; + int count; } SLIST; -void slist_add(SLIST **plist, char *str); -void slist_append(SLIST **pdst, SLIST *src); -char *slist_member(SLIST *plist, char *name); -void slist_destroy(SLIST **plist); - -void read_include(SLIST **plist, char *name); +void slist_add (SLIST ** plist, char *str); +void slist_append (SLIST ** pdst, SLIST * src); +char *slist_member (SLIST * plist, char *name); +void slist_destroy (SLIST ** plist); -void regalias(char *name, SLIST *exp); -void begin_aliases(void); -void end_aliases(void); +void read_include (SLIST ** plist, char *name); -void error(char *fmt, ...); +void regalias (char *name, SLIST * exp); +void begin_aliases (void); +void end_aliases (void); @@ -2,3 +2,3 @@ /* ckaliases - verify syntax of sendmail-style alias files - Copyright (C) 2005 Sergey Poznyakoff + Copyright (C) 2005, 2007 Sergey Poznyakoff @@ -17,7 +17,2 @@ -#include <stdio.h> -#include <stdlib.h> -#include <stdarg.h> -#include <getopt.h> -#include <errno.h> #include "ckaliases.h" @@ -25,6 +20,6 @@ SLIST *cw_list; /* List of domain names pertaining to Sendmail 'w' class */ -static int restricted; /* prohibit use of `special' aliases (pipes, file redirections - and includes */ -int verbose; /* Verbose mode */ -static int error_count; /* Number of errors detected so far */ +static int restricted; /* prohibit use of `special' aliases (pipes, + file redirections and includes */ +int verbose; /* Verbose mode */ +int error_count; /* Number of errors detected so far */ %} @@ -32,4 +27,4 @@ static int error_count; /* Number of errors detected so far */ %union { - char *string; - SLIST *slist; + char *string; + SLIST *slist; }; @@ -53,4 +48,4 @@ list : alias { - yyclearin; - yyerrok; + yyclearin; + yyerrok; } @@ -61,3 +56,3 @@ alias : /* empty */ { - regalias($1, $2); + regalias ($1, $2); } @@ -71,4 +66,4 @@ rhs : emails { - slist_append(&$1, $3); - $$ = $1; + slist_append (&$1, $3); + $$ = $1; } @@ -79,4 +74,4 @@ emails: email { - slist_append(&$1, $3); - $$ = $1; + slist_append (&$1, $3); + $$ = $1; } @@ -86,8 +81,9 @@ email : string { - if (restricted && ($1[0] == '|' || $1[0] == '/')) { - yyerror("Construct not allowed"); - YYERROR; - } - $$ = NULL; - slist_add(&$$, $1); + if (restricted && ($1[0] == '|' || $1[0] == '/')) + { + yyerror ("Construct not allowed"); + YYERROR; + } + $$ = NULL; + slist_add (&$$, $1); } @@ -95,4 +91,4 @@ email : string { - $$ = NULL; - slist_add(&$$, $1); + $$ = NULL; + slist_add (&$$, $1); } @@ -100,8 +96,9 @@ email : string { - if (restricted) { - yyerror("Include statement is not allowed"); - YYERROR; - } - $$ = NULL; - read_include(&$$, $2); + if (restricted) + { + yyerror ("Include statement is not allowed"); + YYERROR; + } + $$ = NULL; + read_include (&$$, $2); } @@ -115,154 +112,165 @@ string: IDENT -void -error(char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - fprintf(stderr, "\n"); - error_count++; -} - -yyerror(char *s) +int +yyerror (char *s) { - error("%s:%d: %s", file_name, line_num, s); + error_at_line (0, 0, file_name, line_num, "%s", s); + error_count++; } - void -usage() +usage () { - printf("usage: ckaliases [OPTIONS] [FILES...]\n"); - printf("OPTIONS and FILES may be interspered.\n"); - printf("Valid options are:\n"); - printf(" -d SPEC Set debug level. SPEC consists of the following\n"); - printf(" letters:\n"); - printf(" y enable parser debugging\n"); - printf(" l enable lexical analizer debugging\n"); - printf(" Upper-case variants are also accepted. Prepending\n"); - printf(" a letter with '-' reverts its sense\n"); - printf(" -h Display this help list\n"); - printf(" -r Restrict alias file syntax to aliases only (i.e.\n"); - printf(" prohibit use of pipes and file redirections\n"); - printf(" -u Revert the effect of the previous -r option\n"); - printf(" -v Verbose mode\n"); - printf(" -w FILE Read contents of Sendmail `w' class from the given\n"); - printf(" file.\n"); + printf ("usage: ckaliases [OPTIONS] [FILES...]\n"); + printf ("OPTIONS and FILES may be interspered.\n"); + printf ("Valid options are:\n"); + printf (" -d,--debug=SPEC Set debug level. SPEC consists of the following\n"); + printf (" letters:\n"); + printf (" y enable parser debugging\n"); + printf (" l enable lexical analizer debugging\n"); + printf (" Upper-case variants are also accepted. Prepending\n"); + printf (" a letter with '-' reverts its sense\n"); + printf (" -f, --files-from=FILE\n"); + printf (" Read names of alias files from FILE\n"); + printf (" -h, --help Display this help list\n"); + printf (" -r, --restrict Restrict alias file syntax to aliases only (i.e.\n"); + printf (" prohibit use of pipes and file redirections\n"); + printf (" -u, --unrestrict Revert the effect of the previous -r option\n"); + printf (" -v, --verbose Verbose mode\n"); + printf (" -V, --version print program version and exit\n"); + printf (" -w FILE Read contents of Sendmail `w' class from the given\n"); + printf (" file.\n"); } +struct option options[] = { + { "debug", required_argument, NULL, 'd' }, + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, 'V' }, + { "restrict", no_argument, NULL, 'r' }, + { "unrestrict", no_argument, NULL, 'u' }, + { "verbose", no_argument, NULL, 'v' }, + { "files-from", required_argument, NULL, 'f' }, + { NULL } +}; int -main(int argc, char **argv) +main (int argc, char **argv) { - char *p; - int c; - int file_count = 0; - int true = 1; - char *cwfile = "/etc/mail/sendmail.cw"; - SLIST *file_list; /* List of files to be read */ - struct string_list *s; + char *p; + int c; + int file_count = 0; + int true = 1; + char *cwfile = "/etc/mail/sendmail.cw"; + SLIST *file_list; /* List of files to be read */ + struct string_list *s; - begin_aliases(); - init_lex(); - while ((c = getopt(argc, argv, "-d:f:hp:ruvw:")) != EOF) { - switch (c) { - case 1: - if (!cw_list) - read_include(&cw_list, cwfile); - openaliases(optarg); - yyparse(); - file_count++; - break; + begin_aliases (); + init_lex (); + program_name = argv[0]; + while ((c = getopt_long (argc, argv, "-d:f:hp:ruvw:", options, NULL)) != EOF) + { + switch (c) + { + case 1: + if (!cw_list) + read_include (&cw_list, cwfile); + openaliases (optarg); + yyparse (); + file_count++; + break; - case 'd': - for (p = optarg; *p; p++) { - switch (*p) { - case '-': - true = 0; - break; - case 'y': - case 'Y': - yydebug = true; - true = 1; - break; - case 'l': - case 'L': - lex_debug(true); - true = 1; - break; - default: - fprintf(stderr, "%s: unknown debug option %c\n", - argv[0], *p); - exit(1); - } - } - break; - - case 'f': - if (!cw_list) - read_include(&cw_list, cwfile); - file_list = NULL; - read_include(&file_list, optarg); - for (s = file_list->head; s; s = s->next) { - openaliases_prefix(optarg, s->str); - yyparse(); - file_count++; - } - slist_destroy(&file_list); - break; - - case 'h': - usage(); - exit(0); - - case 'r': - restricted = 1; - break; - - case 'u': - restricted = 0; - break; + case 'd': + for (p = optarg; *p; p++) + { + switch (*p) + { + case '-': + true = 0; + break; + + case 'y': + case 'Y': + yydebug = true; + true = 1; + break; + + case 'l': + case 'L': + lex_debug (true); + true = 1; + break; - case 'v': - verbose++; - break; - - case 'w': - if (file_count) { - error("-w must be used before first non-option argument"); - exit(1); - } - cwfile = optarg; - break; - default: - exit(1); + error (1, 0, "%s: unknown debug option %c", argv[0]); } - } + } + break; + + case 'f': + if (!cw_list) + read_include (&cw_list, cwfile); + file_list = NULL; + read_include (&file_list, optarg); + for (s = file_list->head; s; s = s->next) + { + openaliases_prefix (optarg, s->str); + yyparse (); + file_count++; + } + slist_destroy (&file_list); + break; + + case 'h': + usage (); + exit (0); - argc -= optind; - argv += optind; + case 'r': + restricted = 1; + break; + + case 'u': + restricted = 0; + break; + + case 'v': + verbose++; + break; - if (!cw_list) - read_include(&cw_list, cwfile); - while (argc--) { - openaliases(*argv++); - yyparse(); - file_count++; + case 'V': + gsc_version ("ckaliases"); + exit (0); + + case 'w': + if (file_count) + error (1, 0, "-w must be used before first non-option argument"); + cwfile = optarg; + break; + + default: + exit (1); } + } + + argc -= optind; + argv += optind; + + if (!cw_list) + read_include (&cw_list, cwfile); + while (argc--) + { + openaliases (*argv++); + yyparse (); + file_count++; + } - if (!file_count) { - error("no files specified"); - exit(1); - } + if (!file_count) + error (1, 0, "no files specified"); - if (verbose) - printf("%d files\n", file_count); - end_aliases(); - check_aliases(); - if (verbose) - printf("%lu errors\n", error_count); - exit(error_count!=0); + if (verbose) + printf ("%d files\n", file_count); + end_aliases (); + check_aliases (); + if (verbose) + printf ("%lu errors\n", error_count); + exit (error_count!=0); } @@ -2,3 +2,3 @@ /* ckaliases - verify syntax of sendmail-style alias files - Copyright (C) 2005 Sergey Poznyakoff + Copyright (C) 2005, 2007 Sergey Poznyakoff @@ -17,12 +17,2 @@ -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <sys/file.h> -#include <sys/stat.h> -#include <errno.h> -#include <string.h> -#define obstack_chunk_alloc malloc -#define obstack_chunk_free free -#include <obstack.h> #include "ckaliases.h" @@ -30,6 +20,6 @@ -static void line_begin(void); -static void line_add(char *text, size_t len); -static void line_add_unescape(char *text, size_t len); -static void line_finish(void); +static void line_begin (void); +static void line_add (char *text, size_t len); +static void line_add_unescape (char *text, size_t len); +static void line_finish (void); @@ -56,28 +46,28 @@ SPEC [:@\\] ^{IDENT} { - line_begin(); - line_add(yytext, yyleng); - line_finish(); + line_begin (); + line_add (yytext, yyleng); + line_finish (); return LHS; } {IDENT}@{IDENT} { - line_begin(); - line_add(yytext, yyleng); - line_finish(); + line_begin (); + line_add (yytext, yyleng); + line_finish (); return EMAIL; } -{IDENT} { line_begin(); - line_add(yytext, yyleng); - line_finish(); +{IDENT} { line_begin (); + line_add (yytext, yyleng); + line_finish (); return IDENT; } /* Quoted strings */ -\"[^\\"\n]*\" { line_begin(); - line_add(yytext, yyleng); - line_finish(); +\"[^\\"\n]*\" { line_begin (); + line_add (yytext, yyleng); + line_finish (); return STRING; } -\"[^\\"\n]*\\. { BEGIN(STR); - line_begin(); - line_add_unescape(yytext + 1, yyleng - 1); } -<STR>[^\\"\n]*\\. { line_add_unescape(yytext, yyleng); } -<STR>[^\\"\n]*\" { BEGIN(INITIAL); +\"[^\\"\n]*\\. { BEGIN (STR); + line_begin (); + line_add_unescape (yytext + 1, yyleng - 1); } +<STR>[^\\"\n]*\\. { line_add_unescape (yytext, yyleng); } +<STR>[^\\"\n]*\" { BEGIN (INITIAL); if (yyleng > 1) - line_add(yytext, yyleng - 1); - line_finish(); + line_add (yytext, yyleng - 1); + line_finish (); return STRING; } @@ -89,7 +79,5 @@ SPEC [:@\\] , return yytext[0]; -. { char *p; - asprintf(&p, - "Stray character %03o in alias file", yytext[0]); - yyerror(p); - free (p); } +. { error_at_line (0, 0, file_name, line_num, + "Stray character %03o in alias file", yytext[0]); + error_count++; } %% @@ -97,6 +85,6 @@ SPEC [:@\\] int -yywrap() +yywrap () { - fclose(yyin); - return 1; + fclose (yyin); + return 1; } @@ -119,5 +107,5 @@ unescape_char (int c) void -line_add(char *text, size_t len) +line_add (char *text, size_t len) { - obstack_grow(&string_stk, text, len); + obstack_grow (&string_stk, text, len); } @@ -125,8 +113,8 @@ line_add(char *text, size_t len) void -line_add_unescape(char *text, size_t len) +line_add_unescape (char *text, size_t len) { - char c; - obstack_grow(&string_stk, text, len - 2); - c = unescape_char(text[len - 1]); - obstack_1grow(&string_stk, c); + char c; + obstack_grow (&string_stk, text, len - 2); + c = unescape_char (text[len - 1]); + obstack_1grow (&string_stk, c); } @@ -134,3 +122,3 @@ line_add_unescape(char *text, size_t len) void -line_begin() +line_begin () { @@ -139,6 +127,6 @@ line_begin() void -line_finish() +line_finish () { - obstack_1grow(&string_stk, 0); - yylval.string = obstack_finish(&string_stk); + obstack_1grow (&string_stk, 0); + yylval.string = obstack_finish (&string_stk); } @@ -146,12 +134,9 @@ line_finish() void -openaliases(char *name) +openaliases (char *name) { - yyin = fopen(name, "r"); - if (!yyin) { - fprintf(stderr, "cannot open file `%s': %s\n", - name, strerror(errno)); - exit(1); - } - file_name = name; - line_num = 0; + yyin = fopen (name, "r"); + if (!yyin) + error (1, errno, "cannot open file `%s'", name); + file_name = name; + line_num = 0; } @@ -159,23 +144,21 @@ openaliases(char *name) void -openaliases_prefix(char *prefix, char *name) +openaliases_prefix (char *prefix, char *name) { - char *fullname = NULL; - struct stat st; + char *fullname = NULL; + struct stat st; - if (stat(prefix, &st)) { - fprintf(stderr, "cannot stat `%s': %s\n", - prefix, strerror(errno)); - exit(1); - } - - if (!S_ISDIR(st.st_mode)) { - char *p = strrchr(prefix, '/'); - if (p) - *p = 0; - else - prefix = "."; - } - asprintf(&fullname, "%s/%s", prefix, name); - openaliases(fullname); - free(fullname); + if (stat (prefix, &st)) + error (1, errno, "cannot stat `%s'", prefix); + + if (!S_ISDIR (st.st_mode)) + { + char *p = strrchr (prefix, '/'); + if (p) + *p = 0; + else + prefix = "."; + } + asprintf (&fullname, "%s/%s", prefix, name); + openaliases (fullname); + free (fullname); } @@ -183,6 +166,6 @@ openaliases_prefix(char *prefix, char *name) void -init_lex() +init_lex () { - obstack_init(&string_stk); - yy_flex_debug = 0; + obstack_init (&string_stk); + yy_flex_debug = 0; } @@ -190,5 +173,5 @@ init_lex() void -lex_debug(int debug) +lex_debug (int debug) { - yy_flex_debug = debug; + yy_flex_debug = debug; } @@ -196,32 +179,32 @@ lex_debug(int debug) void -read_include(SLIST **plist, char *name) +read_include (SLIST **plist, char *name) { - char *p; - char buffer[256]; - FILE *fp = fopen(name, "r"); - - if (!fp) { - char *p; - asprintf(&p, - "cannot open include file `%s': %s", - name, strerror(errno)); - yyerror(p); - free(p); - return; - } - - while (p = fgets(buffer, sizeof buffer, fp)) { - char *q; - - while (*p && isspace(*p)) - p++; - if (*p == '#') - continue; - for (q = p + strlen(p) - 1; q > p && isspace(*q); q--) - ; - q[1] = 0; - if (*p) - slist_add(plist, strdup(p)); - } - fclose(fp); + char *p; + char buffer[256]; + FILE *fp = fopen (name, "r"); + + if (!fp) + { + error_at_line (0, 0, file_name, line_num, + "cannot open include file `%s': %s", + name, strerror (errno)); + error_count++; + return; + } + + while (p = fgets (buffer, sizeof buffer, fp)) + { + char *q; + + while (*p && isspace (*p)) + p++; + if (*p == '#') + continue; + for (q = p + strlen (p) - 1; q > p && isspace (*q); q--) + ; + q[1] = 0; + if (*p) + slist_add ( |