diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2005-04-28 14:40:22 +0000 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2005-04-28 14:40:22 +0000 |
commit | 0d8e04d0b65246cc86aabb4beb032a84be184bda (patch) | |
tree | b9be359d35d605c8c8ebe51f51349d19d572da65 /gram.y | |
download | alck-0d8e04d0b65246cc86aabb4beb032a84be184bda.tar.gz alck-0d8e04d0b65246cc86aabb4beb032a84be184bda.tar.bz2 |
Added to the repository
git-svn-id: file:///svnroot/gsc/trunk@38 d2de0444-eb31-0410-8365-af798a554d48
Diffstat (limited to 'gram.y')
-rw-r--r-- | gram.y | 252 |
1 files changed, 252 insertions, 0 deletions
@@ -0,0 +1,252 @@ +%{ +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <getopt.h> +#include <errno.h> +#include "ckaliases.h" + +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 */ +%} + +%union { + char *string; + SLIST *slist; +}; + +%token <string> IDENT EMAIL STRING LHS +%token CONT +%token EOL +%token INCLUDE + +%type <string> string lhs +%type <slist> rhs emails email + +%% + +input : list + ; + +list : alias + | list EOL alias + | list error EOL + { + yyclearin; + yyerrok; + } + ; + +alias : /* empty */ + | lhs rhs + { + regalias($1, $2); + } + ; + +lhs : LHS ':' + ; + +rhs : emails + | rhs CONT emails + { + slist_append(&$1, $3); + $$ = $1; + } + ; + +emails: email + | emails ',' email + { + slist_append(&$1, $3); + $$ = $1; + } + ; + +email : string + { + if (restricted && ($1[0] == '|' || $1[0] == '/')) { + yyerror("Construct not allowed"); + YYERROR; + } + $$ = NULL; + slist_add(&$$, $1); + } + | EMAIL + { + $$ = NULL; + slist_add(&$$, $1); + } + | INCLUDE string + { + if (restricted) { + yyerror("Include statement is not allowed"); + YYERROR; + } + $$ = NULL; + read_include(&$$, $2); + } + ; + +string: IDENT + | STRING + ; + +%% + +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) +{ + error("%s:%d: %s", file_name, line_num, s); +} + + + +void +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"); +} + + +int +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; + + 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; + + 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 '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); + } + } + + 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 (verbose) + printf("%d files\n", file_count); + end_aliases(); + check_aliases(); + if (verbose) + printf("%lu errors\n", error_count); + exit(error_count!=0); +} |