[BACK]Return to parse.y CVS log [TXT][DIR] Up to [local] / blind

Diff for /blind/parse.y between version 1.7 and 1.17

version 1.7, 2022/03/22 01:51:36 version 1.17, 2022/04/10 21:04:06
Line 16 
Line 16 
   
 %{  %{
 #include <sys/queue.h>  #include <sys/queue.h>
 #include <sys/stat.h>  
   
 #include <stdio.h>  
 #include <stdarg.h>  
 #include <unistd.h>  
 #include <ctype.h>  #include <ctype.h>
   #include <stdarg.h>
   #include <stdio.h>
   
 #include "blind.h"  #include "blind.h"
   #include "config.h"
 #include "log.h"  #include "log.h"
   
 TAILQ_HEAD(files, file)          files = TAILQ_HEAD_INITIALIZER(files);  #define START_EXPAND    1
 static struct file {  #define DONE_EXPAND     2
         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;  
   
   static struct file *f;
   
 int             lookup(char *);  int             lookup(char *);
 int             igetc(void);  int             igetc(void);
 int             lgetc(int);  int             lgetc(int);
Line 48  int  kw_cmp(const void *, const void *);
Line 39  int  kw_cmp(const void *, const void *);
 int             yyparse(void);  int             yyparse(void);
 int             yylex(void);  int             yylex(void);
 int             yyerror(const char *, ...)  int             yyerror(const char *, ...)
         __attribute__((__format__ (printf, 1, 2)))                  __attribute__((__format__ (printf, 1, 2)))
         __attribute__((__nonnull__ (1)));                  __attribute__((__nonnull__ (1)));
   
 int             config_load(struct blind *);  int             config_load(struct blind *);
 struct file    *config_push(const char *);  struct file    *config_push(const char *);
 int             config_pop(void);  int             config_close(void);
 int             config_perm(int, const char *);  
   
   static int      expanding;
   static int      errors = 0;
   struct blind   *env = NULL;
   
 TAILQ_HEAD(symhead, sym)         symhead = TAILQ_HEAD_INITIALIZER(symhead);  TAILQ_HEAD(symhead, sym)         symhead = TAILQ_HEAD_INITIALIZER(symhead);
 struct sym {  struct sym {
Line 65  struct sym {
Line 58  struct sym {
         char                    *nam;          char                    *nam;
         char                    *val;          char                    *val;
 };  };
   
 char           *symget(const char *);  char           *symget(const char *);
   
 struct blind   *env = NULL;  
 static int      errors = 0;  
   
 typedef struct {  typedef struct {
         union {          union {
                 int64_t  number;                  int64_t  number;
Line 89  typedef struct {
Line 80  typedef struct {
 grammar :  grammar :
         | grammar '\n'          | grammar '\n'
         | grammar set '\n'          | grammar set '\n'
         | grammar error '\n'    { file->errors++; }          | grammar error '\n'    { errors++; }
         ;          ;
   
 set     : SET EXPIRE NUMBER {  set     : SET EXPIRE NUMBER {
Line 116  yyerror(const char *fmt, ...)
Line 107  yyerror(const char *fmt, ...)
         va_list          ap;          va_list          ap;
         char            *msg;          char            *msg;
   
         file->errors++;          errors++;
         va_start(ap, fmt);          va_start(ap, fmt);
         if (vasprintf(&msg, fmt, ap) == -1)          if (vasprintf(&msg, fmt, ap) == -1)
                 log_fatal("yyerror vasprintf");                  log_fatal("yyerror vasprintf");
         va_end(ap);          va_end(ap);
         log_info("%s:%d: %s", file->name, yylval.lineno, msg);          log_info("%s:%d: %s", f->name, yylval.lineno, msg);
         free(msg);          free(msg);
         return (0);          return (0);
 }  }
Line 154  lookup(char *s)
Line 145  lookup(char *s)
                 return (STRING);                  return (STRING);
 }  }
   
 #define START_EXPAND    1  
 #define DONE_EXPAND     2  
   
 static int      expanding;  
   
 char *  char *
 symget(const char *nam)  symget(const char *nam)
 {  {
Line 179  igetc(void)
Line 165  igetc(void)
         int     c;          int     c;
   
         while (1) {          while (1) {
                 if (file->ungetpos > 0)                  if (f->unpos > 0)
                         c = file->ungetbuf[--file->ungetpos];                          c = f->unbuf[--f->unpos];
                 else                  else
                         c = getc(file->stream);                          c = getc(f->stream);
   
                 if (c == START_EXPAND)                  if (c == START_EXPAND)
                         expanding = 1;                          expanding = 1;
Line 203  lgetc(int quotec)
Line 189  lgetc(int quotec)
                 if ((c = igetc()) == EOF) {                  if ((c = igetc()) == EOF) {
                         yyerror("reached end of file while parsing "                          yyerror("reached end of file while parsing "
                             "quoted string");                              "quoted string");
                         if (file == top || config_pop() == EOF)                          if (config_close() == EOF)
                                 return (EOF);                                  return (EOF);
                         return (quotec);                          return (quotec);
                 }                  }
Line 216  lgetc(int quotec)
Line 202  lgetc(int quotec)
                         c = next;                          c = next;
                         break;                          break;
                 }                  }
                 yylval.lineno = file->lineno;                  yylval.lineno = f->lineno;
                 file->lineno++;                  f->lineno++;
         }          }
   
         if (c == EOF) {          if (c == EOF) {
Line 226  lgetc(int quotec)
Line 212  lgetc(int quotec)
                  * count right if last line in included file is syntactically                   * count right if last line in included file is syntactically
                  * invalid and has no newline.                   * invalid and has no newline.
                  */                   */
                 if (file->eof_reached == 0) {                  if (f->eof == 0) {
                         file->eof_reached = 1;                          f->eof = 1;
                         return ('\n');                          return ('\n');
                 }                  }
                 while (c == EOF) {                  while (c == EOF) {
                         if (file == top || config_pop() == EOF)                          if (config_close() == EOF)
                                 return (EOF);                                  return (EOF);
                         c = igetc();                          c = igetc();
                 }                  }
Line 245  lungetc(int c)
Line 231  lungetc(int c)
         if (c == EOF)          if (c == EOF)
                 return;                  return;
   
         if (file->ungetpos >= file->ungetsize) {          if (f->unpos >= f->unsize) {
                 void *p = reallocarray(file->ungetbuf, file->ungetsize, 2);                  void *p = reallocarray(f->unbuf, f->unsize, 2);
                 if (p == NULL)                  if (p == NULL)
                         log_fatal("cannot reallocate memory");                          log_fatal("cannot reallocate memory");
                 file->ungetbuf = p;                  f->unbuf = p;
                 file->ungetsize *= 2;                  f->unsize *= 2;
         }          }
         file->ungetbuf[file->ungetpos++] = c;          f->unbuf[f->unpos++] = c;
 }  }
   
 int  int
Line 264  findeol(void)
Line 250  findeol(void)
         while (1) {          while (1) {
                 c = lgetc(0);                  c = lgetc(0);
                 if (c == '\n') {                  if (c == '\n') {
                         file->lineno++;                          f->lineno++;
                         break;                          break;
                 }                  }
                 if (c == EOF)                  if (c == EOF)
Line 286  top:
Line 272  top:
         while ((c = lgetc(0)) == ' ' || c == '\t')          while ((c = lgetc(0)) == ' ' || c == '\t')
                 ; /* nothing */                  ; /* nothing */
   
         yylval.lineno = file->lineno;          yylval.lineno = f->lineno;
         if (c == '#')          if (c == '#')
                 while ((c = lgetc(0)) != '\n' && c != EOF)                  while ((c = lgetc(0)) != '\n' && c != EOF)
                         ; /* nothing */                          ; /* nothing */
Line 330  top:
Line 316  top:
                         if ((c = lgetc(quotec)) == EOF)                          if ((c = lgetc(quotec)) == EOF)
                                 return (0);                                  return (0);
                         if (c == '\n') {                          if (c == '\n') {
                                 file->lineno++;                                  f->lineno++;
                                 continue;                                  continue;
                         } else if (c == '\\') {                          } else if (c == '\\') {
                                 if ((next = lgetc(quotec)) == EOF)                                  if ((next = lgetc(quotec)) == EOF)
Line 339  top:
Line 325  top:
                                     next == '\t')                                      next == '\t')
                                         c = next;                                          c = next;
                                 else if (next == '\n') {                                  else if (next == '\n') {
                                         file->lineno++;                                          f->lineno++;
                                         continue;                                          continue;
                                 } else                                  } else
                                         lungetc(next);                                          lungetc(next);
Line 368  top:
Line 354  top:
         if (c == '-' || isdigit(c)) {          if (c == '-' || isdigit(c)) {
                 do {                  do {
                         *p++ = c;                          *p++ = c;
                         if ((size_t)(p-buf) >= sizeof(buf)) {                                  if ((size_t)(p-buf) >= sizeof(buf)) {
                                 yyerror("string too long");                                  yyerror("string too long");
                                 return (findeol());                                  return (findeol());
                         }                          }
Line 427  nodigits:
Line 413  nodigits:
                 return (token);                  return (token);
         }          }
         if (c == '\n') {          if (c == '\n') {
                 yylval.lineno = file->lineno;                  yylval.lineno = f->lineno;
                 file->lineno++;                  f->lineno++;
         }          }
         if (c == EOF)          if (c == EOF)
                 return (0);                  return (0);
Line 438  nodigits:
Line 424  nodigits:
 int  int
 config_load(struct blind *temp)  config_load(struct blind *temp)
 {  {
         env = temp;          env = temp;
         errors = 0;          errors = 0;
   
         if ((file = config_push(env->bl_conf)) == NULL) {          if ((f = calloc(1, sizeof(struct file))) == NULL) {
                 //       config_purge(PURGE_ALL);                  log_debug("cannot allocate memory");
                 return (-1);                  return (-1);
           }
           if ((f->name = strdup(env->bl_conf)) == NULL) {
                   log_debug("cannot duplicate name");
                   free(f);
                   return (-1);
         }          }
         top = file;          if ((f->stream = fopen(f->name, "r")) == NULL) {
                   log_debug("cannot open config file");
                   free(f->name);
                   free(f);
                   return (-1);
           }
           if (config_perm(fileno(f->stream), f->name)) {
                   fclose(f->stream);
                   free(f->name);
                   free(f);
                   return (-1);
           }
           f->lineno = 1;
           f->unsize = 16;
           if ((f->unbuf = malloc(f->unsize)) == NULL) {
                   log_debug("cannot allocate buffer");
                   fclose(f->stream);
                   free(f->name);
                   free(f);
                   return (-1);
           }
   
         yyparse();          yyparse();
           // setup
   
         errors = file->errors;          if (errors)
         config_pop();                  return (-1);
   
         // setup          return (0);
   
         if (errors) {  
                 //      config_purge(PURGE_ALL);  
                 return (-1);  
         }  
   
         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  int
 config_pop(void)  config_close(void)
 {  {
         struct file *prv;          fclose(f->stream);
           free(f->name);
           free(f->unbuf);
           free(f);
   
         if ((prv = TAILQ_PREV(file, files, entry)) != NULL)          return (EOF);
                 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);  
 }  }

Legend:
Removed from v.1.7  
changed lines
  Added in v.1.17

https://cvs.kroczynski.net