]> git.sur5r.net Git - bacula/bacula/commitdiff
Make bfgets handle very long lines
authorKern Sibbald <kern@sibbald.com>
Wed, 21 Nov 2012 17:26:37 +0000 (18:26 +0100)
committerKern Sibbald <kern@sibbald.com>
Sat, 20 Apr 2013 12:51:03 +0000 (14:51 +0200)
bacula/src/lib/bsys.c
bacula/src/lib/lex.c
bacula/src/lib/lex.h
bacula/src/lib/protos.h

index fdee8f6090ece9fdea725cc13955a59fad5aaf62..7900e3cf58776420a7e3241155fde9e9bce0c9a5 100644 (file)
@@ -689,6 +689,57 @@ char *bfgets(char *s, int size, FILE *fd)
    return s;
 }
 
+/*
+ * Bacula's implementation of fgets(). The difference is that it handles
+ *   being interrupted by a signal (e.g. a SIGCHLD) and it has a
+ *   different calling sequence which implements input lines of
+ *   up to a million characters.
+ */
+char *bfgets(POOLMEM *&s, FILE *fd)
+{
+   int ch;
+   int soft_max;
+   int i = 0;
+
+   s[0] = 0;
+   soft_max = sizeof_pool_memory(s) - 10;
+   for ( ;; ) {
+      do {
+         errno = 0;
+         ch = fgetc(fd);
+      } while (ch == EOF && ferror(fd) && (errno == EINTR || errno == EAGAIN));
+      if (ch == EOF) {
+         if (i == 0) {
+            return NULL;
+         } else {
+            return s;
+         }
+      }
+      if (i > soft_max) {
+         /* Insanity check */
+         if (soft_max > 1000000) {
+            return s;
+         }
+         s = check_pool_memory_size(s, soft_max+10000);
+         soft_max = sizeof_pool_memory(s) - 10;
+      }
+      s[i++] = ch;
+      s[i] = 0;
+      if (ch == '\r') { /* Support for Mac/Windows file format */
+         ch = fgetc(fd);
+         if (ch != '\n') { /* Mac (\r only) */
+            (void)ungetc(ch, fd); /* Push next character back to fd */
+         }
+         s[i-1] = '\n';
+         break;
+      }
+      if (ch == '\n') {
+         break;
+      }
+   }
+   return s;
+}
+
 /*
  * Make a "unique" filename.  It is important that if
  *   called again with the same "what" that the result
index 4e2558a8b07abcd9bf2c3dbcc4f0229d2a957a63..cd9d7c5daeeaa70e69c848a75d1c16991b5abd53 100644 (file)
@@ -139,6 +139,8 @@ LEX *lex_close_file(LEX *lf)
    }
    Dmsg1(dbglvl, "Close cfg file %s\n", lf->fname);
    free(lf->fname);
+   free_memory(lf->line);
+   lf->line = NULL;
    if (of) {
       of->options = lf->options;      /* preserve options */
       memcpy(lf, of, sizeof(LEX));
@@ -170,7 +172,6 @@ LEX *lex_open_file(LEX *lf, const char *filename, LEX_ERROR_HANDLER *scan_error)
    BPIPE *bpipe = NULL;
    char *fname = bstrdup(filename);
 
-
    if (fname[0] == '|') {
       if ((bpipe = open_bpipe(fname+1, 0, "rb")) == NULL) {
          free(fname);
@@ -206,6 +207,7 @@ LEX *lex_open_file(LEX *lf, const char *filename, LEX_ERROR_HANDLER *scan_error)
    lf->fd = fd;
    lf->bpipe = bpipe;
    lf->fname = fname;
+   lf->line = get_memory(5000);
    lf->state = lex_none;
    lf->ch = L_EOL;
    Dmsg1(dbglvl, "Return lex=%x\n", lf);
@@ -225,7 +227,7 @@ int lex_get_char(LEX *lf)
          " 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) {
+      if (bfgets(lf->line, lf->fd) == NULL) {
          lf->ch = L_EOF;
          if (lf->next) {
             lex_close_file(lf);
index 115a60ac7f04384ad7879642f8b767bb7d0d2bb5..b2a55c5f8b657871ed061be5c379853549e439ed 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2000-2007 Free Software Foundation Europe e.V.
+   Copyright (C) 2000-2012 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.
@@ -32,8 +32,6 @@
  *
  *   Kern Sibbald, MM
  *
- *   Version $Id$
- *
  */
 
 #ifndef _LEX_H
@@ -106,7 +104,7 @@ typedef struct s_lex_context {
    int options;                       /* scan options */
    char *fname;                       /* filename */
    FILE *fd;                          /* file descriptor */
-   char line[MAXSTRING];              /* input line */
+   POOLMEM *line;                     /* input line */
    char str[MAXSTRING];               /* string being scanned */
    int str_len;                       /* length of string */
    int line_no;                       /* file line number */
index 548799f6417d71cd935486f1a98d3a685c13e70b..d04c84746d0aee5fdb16a4746a0df85a1ddf9e99 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2000-2010 Free Software Foundation Europe e.V.
+   Copyright (C) 2000-2012 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.
@@ -72,6 +72,7 @@ int       delete_pid_file        (char *dir, const char *progname, int port);
 void      drop                   (char *uid, char *gid, bool keep_readall_caps);
 int       bmicrosleep            (int32_t sec, int32_t usec);
 char     *bfgets                 (char *s, int size, FILE *fd);
+char     *bfgets                 (POOLMEM *&s, FILE *fd);
 void      make_unique_filename   (POOLMEM **name, int Id, char *what);
 #ifndef HAVE_STRTOLL
 long long int strtoll            (const char *ptr, char **endptr, int base);