=================================================================== RCS file: /cvs/cvs/blind/parse.y,v retrieving revision 1.1 retrieving revision 1.5 diff -u -p -r1.1 -r1.5 --- blind/parse.y 2022/03/19 10:04:59 1.1 +++ blind/parse.y 2022/03/20 22:00:51 1.5 @@ -15,19 +15,47 @@ */ %{ +#include +#include + +#include #include +#include #include "blind.h" +#include "log.h" -int yylex(void); -int yyerror(const char *, ...); +TAILQ_HEAD(files, file) files = TAILQ_HEAD_INITIALIZER(files); +static struct file { + TAILQ_ENTRY(file) entry; + FILE *stream; + char *name; + size_t ungetpos; + size_t ungetsize; + u_char *ungetbuf; + int eof_reached; + int lineno; + int errors; +} *file, *top; -struct blind *env = NULL; +int yyparse(void); +int yylex(void); +int yyerror(const char *, ...) + __attribute__((__format__ (printf, 1, 2))) + __attribute__((__nonnull__ (1))); +int config_load(struct blind *); +struct file *config_push(const char *); +int config_pop(void); +int config_perm(int, const char *); + +struct blind *env = NULL; +static int errors = 0; + typedef struct { union { - int64_t number; - char *string; + int64_t number; + char *string; } v; int lineno; } YYSTYPE; @@ -36,18 +64,21 @@ typedef struct { %token EXPIRE -%token STRING %token NUMBER +%token STRING %% grammar : | grammar '\n' | grammar expire '\n' + | grammar error '\n' { file->errors++; } ; expire : EXPIRE NUMBER { - } - ; + log_debug("found EXPIRE"); + env->bl_ttl = $2; +} +; %% @@ -61,4 +92,104 @@ int yylex(void) { return (0); +} + +int +config_load(struct blind *temp) +{ + env = temp; + errors = 0; + + if ((file = config_push(env->bl_conf)) == NULL) { + // config_purge(PURGE_ALL); + return (-1); + } + top = file; + + yyparse(); + + errors = file->errors; + config_pop(); + + // setup + + return (0); +} + +struct file * +config_push(const char *name) +{ + struct file *nfile; + + if ((nfile = calloc(1, sizeof(struct file))) == NULL) { + log_debug("cannot allocate memory"); + return (NULL); + } + if ((nfile->name = strdup(name)) == NULL) { + log_debug("cannot duplicate name"); + free(nfile); + return (NULL); + } + if ((nfile->stream = fopen(nfile->name, "r")) == NULL) { + log_debug("cannot open config file"); + free(nfile->name); + free(nfile); + return (NULL); + } + if (config_perm(fileno(nfile->stream), nfile->name)) { + fclose(nfile->stream); + free(nfile->name); + free(nfile); + return (NULL); + } + nfile->lineno = TAILQ_EMPTY(&files) ? 1 : 0; + nfile->ungetsize = 16; + nfile->ungetbuf = malloc(nfile->ungetsize); + if (nfile->ungetbuf == NULL) { + log_debug("cannot allocate buffer"); + fclose(nfile->stream); + free(nfile->name); + free(nfile); + return (NULL); + } + TAILQ_INSERT_TAIL(&files, nfile, entry); + return (nfile); +} + +int +config_pop(void) +{ + struct file *prv; + + if ((prv = TAILQ_PREV(file, files, entry)) != NULL) + prv->errors += file->errors; + + TAILQ_REMOVE(&files, file, entry); + fclose(file->stream); + free(file->name); + free(file->ungetbuf); + free(file); + file = prv; + + return (file ? 0 : EOF); +} + +int +config_perm(int fd, const char *name) +{ + struct stat st; + + if (fstat(fd, &st)) { + log_debug("cannot stat config file"); + return (-1); + } + if (st.st_uid != 0 && st.st_uid != getuid()) { + log_debug("not root or current user owned"); + return (-1); + } + if (st.st_mode & (S_IWGRP | S_IXGRP | S_IRWXO)) { + log_debug("insecure config file"); + return (-1); + } + return (0); }