]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/lib/lex.c
Added fix for bug #1275 where acl or xattr data is saved for virtual filenames genera...
[bacula/bacula] / bacula / src / lib / lex.c
index 2c438da08ca6f5dd88b497ed8fb3fe6eb5d1e562..03b64ac0d23498426259807bbc5a9c9bd7756be5 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2000-2007 Free Software Foundation Europe e.V.
+   Copyright (C) 2000-2008 Free Software Foundation Europe e.V.
 
    The main author of Bacula is Kern Sibbald, with contributions from
    many others, a complete list can be found in the file AUTHORS.
@@ -20,7 +20,7 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Bacula® is a registered trademark of John Walker.
+   Bacula® is a registered trademark of Kern Sibbald.
    The licensor of Bacula is the Free Software Foundation Europe
    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
    Switzerland, email:ftf@fsfeurope.org.
@@ -174,7 +174,7 @@ LEX *lex_open_file(LEX *lf, const char *filename, LEX_ERROR_HANDLER *scan_error)
 
 
    if (fname[0] == '|') {
-      if ((bpipe = open_bpipe(fname, 0, "rb")) == NULL) {
+      if ((bpipe = open_bpipe(fname+1, 0, "rb")) == NULL) {
          free(fname);
          return NULL;
       }
@@ -190,6 +190,11 @@ LEX *lex_open_file(LEX *lf, const char *filename, LEX_ERROR_HANDLER *scan_error)
       memset(lf, 0, sizeof(LEX));
       lf->next = nf;                  /* if have lf, push it behind new one */
       lf->options = nf->options;      /* preserve user options */
+      /*
+       * preserve err_type to prevent bacula exiting on 'reload' 
+       * if config is invalid. Fixes bug #877         
+       */
+      lf->err_type = nf->err_type;    
    } else {
       lf = nf;                        /* start new packet */
       memset(lf, 0, sizeof(LEX));
@@ -218,7 +223,8 @@ LEX *lex_open_file(LEX *lf, const char *filename, LEX_ERROR_HANDLER *scan_error)
 int lex_get_char(LEX *lf)
 {
    if (lf->ch == L_EOF) {
-      Emsg0(M_ABORT, 0, _("get_char: called after EOF\n"));
+      Emsg0(M_ABORT, 0, _("get_char: called after EOF."
+         " You may have a open double quote without the closing double quote.\n"));
    }
    if (lf->ch == L_EOL) {
       if (bfgets(lf->line, MAXSTRING, lf->fd) == NULL) {
@@ -291,6 +297,8 @@ static const char *lex_state_to_str(int state)
    case lex_identifier:    return _("identifier");
    case lex_string:        return _("string");
    case lex_quoted_string: return _("quoted_string");
+   case lex_include:       return _("include");
+   case lex_include_quoted_string: return _("include_quoted_string");
    case lex_utf8_bom:      return _("UTF-8 Byte Order Mark");
    case lex_utf16_le_bom:  return _("UTF-16le Byte Order Mark");
    default:                return "??????";
@@ -343,6 +351,23 @@ static uint32_t scan_pint(LEX *lf, char *str)
    return (uint32_t)val;
 }
 
+static uint64_t scan_pint64(LEX *lf, char *str)
+{
+   uint64_t val = 0;
+   if (!is_a_number(str)) {
+      scan_err1(lf, _("expected a positive integer number, got: %s"), str);
+      /* NOT REACHED */
+   } else {
+      errno = 0;
+      val = str_to_uint64(str);
+      if (errno != 0) {
+         scan_err1(lf, _("expected a positive integer number, got: %s"), str);
+         /* NOT REACHED */
+      }
+   }
+   return val;
+}
+
 /*
  *
  * Get the next token from the input
@@ -561,11 +586,49 @@ lex_get_token(LEX *lf, int expect)
          }
          add_str(lf, ch);
          break;
+      case lex_include_quoted_string:
+         if (ch == L_EOF) {
+            token = T_ERROR;
+            break;
+         }
+         if (esc_next) {
+            add_str(lf, ch);
+            esc_next = false;
+            break;
+         }
+         if (ch == '\\') {
+            esc_next = true;
+            break;
+         }
+         if (ch == '"') {
+            /* Keep the original LEX so we can print an error if the included file can't be opened. */
+            LEX* lfori = lf;
+            /* Skip the double quote when restarting parsing */
+            lex_get_char(lf);
+
+            lf->state = lex_none;
+            lf = lex_open_file(lf, lf->str, lf->scan_error);
+            if (lf == NULL) {
+               berrno be;
+               scan_err2(lfori, _("Cannot open included config file %s: %s\n"),
+                  lfori->str, be.bstrerror());
+               return T_ERROR;
+            }
+            break;
+         }
+         add_str(lf, ch);
+         break;
       case lex_include:            /* scanning a filename */
          if (ch == L_EOF) {
             token = T_ERROR;
             break;
          }
+         if (ch == '"') {
+            lf->state = lex_include_quoted_string;
+            break;
+         }
+
+
          if (B_ISSPACE(ch) || ch == '\n' || ch == L_EOL || ch == '}' || ch == '{' ||
              ch == ';' || ch == ','   || ch == '"' || ch == '#') {
             /* Keep the original LEX so we can print an error if the included file can't be opened. */
@@ -594,18 +657,18 @@ lex_get_token(LEX *lf, int expect)
             lf->state = lex_none;
          } else {
             token = T_ERROR;
-        }
+         }
          break;
       case lex_utf16_le_bom:
          /* we only end up in this state if we have read an 0xFF 
             as the first byte of the file -- indicating that we are
             probably dealing with an Intel based (little endian) UTF-16 file*/
-        if (ch == 0xFE) {
-           token = T_UTF16_BOM;
-           lf->state = lex_none;
-        } else {
-           token = T_ERROR;
-        }
+         if (ch == 0xFE) {
+            token = T_UTF16_BOM;
+            lf->state = lex_none;
+         } else {
+            token = T_ERROR;
+         }
          break;
       }
       Dmsg4(dbglvl, "ch=%d state=%s token=%s %c\n", ch, lex_state_to_str(lf->state),
@@ -683,6 +746,26 @@ lex_get_token(LEX *lf, int expect)
       }
       break;
 
+   case T_PINT64_RANGE:
+      if (token == T_NUMBER) {
+         lf->pint64_val = scan_pint64(lf, lf->str);
+         lf->pint64_val2 = lf->pint64_val;
+         token = T_PINT64;
+      } else {
+         char *p = strchr(lf->str, '-');
+         if (!p) {
+            scan_err2(lf, _("expected an integer or a range, got %s: %s"),
+               lex_tok_to_str(token), lf->str);
+            token = T_ERROR;
+            break;
+         }
+         *p++ = 0;                       /* terminate first half of range */
+         lf->pint64_val  = scan_pint64(lf, lf->str);
+         lf->pint64_val2 = scan_pint64(lf, p);
+         token = T_PINT64_RANGE;
+      }
+      break;
+
    case T_NAME:
       if (token != T_IDENTIFIER && token != T_UNQUOTED_STRING && token != T_QUOTED_STRING) {
          scan_err2(lf, _("expected a name, got %s: %s"),