Imported Upstream version 2.5.1
[debian/amanda] / client-src / sendsize.c
index dc8a67dd9e6b2e978a8edffaf737e2f128285b1c..bf3595ab223aa29ae8571519a813f2679969f2a3 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /* 
- * $Id: sendsize.c,v 1.152 2006/03/09 16:51:41 martinea Exp $
+ * $Id: sendsize.c,v 1.171 2006/08/24 01:57:15 paddy_s Exp $
  *
  * send estimated backup sizes using dump
  */
@@ -38,6 +38,8 @@
 #include "getfsent.h"
 #include "version.h"
 #include "client_util.h"
+#include "clientconf.h"
+#include "amandad.h"
 
 #ifdef SAMBA_CLIENT
 #include "findpass.h"
@@ -76,8 +78,11 @@ typedef struct level_estimates_s {
 typedef struct disk_estimates_s {
     struct disk_estimates_s *next;
     char *amname;
+    char *qamname;
     char *amdevice;
+    char *qamdevice;
     char *dirname;
+    char *qdirname;
     char *program;
     char *calcprog;
     int program_is_wrapper;
@@ -95,25 +100,27 @@ static char *our_feature_string = NULL;
 static g_option_t *g_options = NULL;
 
 /* local functions */
-int main P((int argc, char **argv));
-void add_diskest P((char *disk, char *amdevice, int level, int spindle, 
+int main(int argc, char **argv);
+void add_diskest(char *disk, char *amdevice, int level, int spindle, 
                    int program_is_wrapper, char *prog, char *calcprog,
-                   option_t *options));
-void calc_estimates P((disk_estimates_t *est));
-void free_estimates P((disk_estimates_t *est));
-void dump_calc_estimates P((disk_estimates_t *));
-void smbtar_calc_estimates P((disk_estimates_t *));
-void gnutar_calc_estimates P((disk_estimates_t *));
-void wrapper_calc_estimates P((disk_estimates_t *));
-void generic_calc_estimates P((disk_estimates_t *));
-
-
-int main(argc, argv)
-int argc;
-char **argv;
+                   option_t *options);
+void calc_estimates(disk_estimates_t *est);
+void free_estimates(disk_estimates_t *est);
+void dump_calc_estimates(disk_estimates_t *);
+void star_calc_estimates(disk_estimates_t *);
+void smbtar_calc_estimates(disk_estimates_t *);
+void gnutar_calc_estimates(disk_estimates_t *);
+void wrapper_calc_estimates(disk_estimates_t *);
+void generic_calc_estimates(disk_estimates_t *);
+
+
+int
+main(
+    int                argc,
+    char **    argv)
 {
     int level, spindle;
-    char *prog, *calcprog, *disk, *amdevice, *dumpdate;
+    char *prog, *calcprog, *dumpdate;
     option_t *options = NULL;
     int program_is_wrapper;
     disk_estimates_t *est;
@@ -123,12 +130,23 @@ char **argv;
     char *s, *fp;
     int ch;
     char *err_extra = NULL;
-    unsigned long malloc_hist_1, malloc_size_1;
-    unsigned long malloc_hist_2, malloc_size_2;
     int done;
     int need_wait;
     int dumpsrunning;
+    char *disk = NULL;
+    char *qdisk = NULL;
+    char *qlist = NULL;
+    char *amdevice = NULL;
+    char *qamdevice = NULL;
+    char *conffile;
+    char *amandates_file;
+#if defined(USE_DBMALLOC)
+    unsigned long malloc_hist_1, malloc_size_1;
+    unsigned long malloc_hist_2, malloc_size_2;
+#endif
 
+    (void)argc;        /* Quiet unused parameter warning */
+    (void)argv;        /* Quiet unused parameter warning */
 
     /* initialize */
 
@@ -140,10 +158,12 @@ char **argv;
     /* Don't die when child closes pipe */
     signal(SIGPIPE, SIG_IGN);
 
+#if defined(USE_DBMALLOC)
     malloc_size_1 = malloc_inuse(&malloc_hist_1);
+#endif
 
     erroutput_type = (ERR_INTERACTIVE|ERR_SYSLOG);
-    dbopen();
+    dbopen(DBG_SUBDIR_CLIENT);
     startclock();
     dbprintf(("%s: version %s\n", get_pname(), version()));
 
@@ -152,13 +172,24 @@ char **argv;
 
     set_debug_prefix_pid(getpid());
 
+    conffile = vstralloc(CONFIG_DIR, "/", "amanda-client.conf", NULL);
+    if (read_clientconf(conffile) > 0) {
+       error("error reading conffile: %s", conffile);
+       /*NOTREACHED*/
+    }
+    amfree(conffile);
+
     /* handle all service requests */
 
-    start_amandates(0);
+    amandates_file = client_getconf_str(CLN_AMANDATES);
+    if(!start_amandates(amandates_file, 0))
+        error("error [opening %s: %s]", amandates_file, strerror(errno));
 
     for(; (line = agets(stdin)) != NULL; free(line)) {
+       if (line[0] == '\0')
+           continue;
 #define sc "OPTIONS "
-       if(strncmp(line, sc, sizeof(sc)-1) == 0) {
+       if(strncmp(line, sc, SIZEOF(sc)-1) == 0) {
 #undef sc
            g_options = parse_g_options(line+8, 1);
            if(!g_options->hostname) {
@@ -179,6 +210,19 @@ char **argv;
            }
            printf("\n");
            fflush(stdout);
+
+           if (g_options->config) {
+               conffile = vstralloc(CONFIG_DIR, "/", g_options->config, "/",
+                                    "amanda-client.conf", NULL);
+               if (read_clientconf(conffile) > 0) {
+                   error("error reading conffile: %s", conffile);
+                   /*NOTREACHED*/
+               }
+               amfree(conffile);
+
+               dbrename(g_options->config, DBG_SUBDIR_CLIENT);
+           }
+
            continue;
        }
 
@@ -187,7 +231,7 @@ char **argv;
 
        skip_whitespace(s, ch);                 /* find the program name */
        if(ch == '\0') {
-           err_extra = "no program name";
+           err_extra = stralloc("no program name");
            goto err;                           /* no program name */
        }
        prog = s - 1;
@@ -209,7 +253,7 @@ char **argv;
        if(strncmp(prog, "CALCSIZE", 8) == 0) {
            skip_whitespace(s, ch);             /* find the program name */
            if(ch == '\0') {
-               err_extra = "no program name";
+               err_extra = stralloc("no program name");
                goto err;
            }
            calcprog = s - 1;
@@ -222,56 +266,71 @@ char **argv;
 
        skip_whitespace(s, ch);                 /* find the disk name */
        if(ch == '\0') {
-           err_extra = "no disk name";
+           err_extra = stralloc("no disk name");
            goto err;                           /* no disk name */
        }
-       disk = s - 1;
-       skip_non_whitespace(s, ch);
-       s[-1] = '\0';
+
+       if (qdisk != NULL)
+           amfree(qdisk);
+       if (disk != NULL)
+           amfree(disk);
+
+       fp = s - 1;
+       skip_quoted_string(s, ch);
+       s[-1] = '\0';                           /* terminate the disk name */
+       qdisk = stralloc(fp);
+       disk = unquote_string(qdisk);
 
        skip_whitespace(s, ch);                 /* find the device or level */
        if (ch == '\0') {
-           err_extra = "bad level";
+           err_extra = stralloc("bad level");
            goto err;
        }
        if(!isdigit((int)s[-1])) {
            fp = s - 1;
-           skip_non_whitespace(s, ch);
+           skip_quoted_string(s, ch);
            s[-1] = '\0';
-           amdevice = stralloc(fp);
+           qamdevice = stralloc(fp);
+           amdevice = unquote_string(qamdevice);
            skip_whitespace(s, ch);             /* find level number */
        }
        else {
            amdevice = stralloc(disk);
+           qamdevice = stralloc(qdisk);
        }
 
                                                /* find the level number */
        if(ch == '\0' || sscanf(s - 1, "%d", &level) != 1) {
-           err_extra = "bad level";
+           err_extra = stralloc("bad level");
            goto err;                           /* bad level */
        }
+       if (level < 0 || level >= DUMP_LEVELS) {
+           err_extra = stralloc("bad level");
+           goto err;
+       }
        skip_integer(s, ch);
 
        skip_whitespace(s, ch);                 /* find the dump date */
        if(ch == '\0') {
-           err_extra = "no dumpdate";
+           err_extra = stralloc("no dumpdate");
            goto err;                           /* no dumpdate */
        }
        dumpdate = s - 1;
        skip_non_whitespace(s, ch);
        s[-1] = '\0';
+       (void)dumpdate;                         /* XXX: Set but not used */
 
        spindle = 0;                            /* default spindle */
 
        skip_whitespace(s, ch);                 /* find the spindle */
        if(ch != '\0') {
            if(sscanf(s - 1, "%d", &spindle) != 1) {
-               err_extra = "bad spindle";
+               err_extra = stralloc("bad spindle");
                goto err;                       /* bad spindle */
            }
            skip_integer(s, ch);
 
-           skip_whitespace(s, ch);             /* find the exclusion list */
+           skip_whitespace(s, ch);             /* find the parameters */
            if(ch != '\0') {
                if(strncmp(s-1, "OPTIONS |;",10) == 0) {
                    options = parse_options(s + 8,
@@ -281,32 +340,61 @@ char **argv;
                                            0);
                }
                else {
-                   options = alloc(sizeof(option_t));
+                   options = alloc(SIZEOF(option_t));
                    init_options(options);
-                   if(strncmp(s-1, "exclude-file=", 13) == 0) {
-                       options->exclude_file =
-                               append_sl(options->exclude_file, s+12);
-                   }
-                   if(strncmp(s-1, "exclude-list=", 13) == 0) {
-                       options->exclude_list =
-                               append_sl(options->exclude_list, s+12);
-                   }
-
-                   skip_non_whitespace(s, ch);
-                   if(ch) {
-                       err_extra = "extra text at end";
-                       goto err;               /* should have gotten to end */
+                   while (ch != '\0') {
+                       if(strncmp(s-1, "exclude-file=", 13) == 0) {
+                           qlist = unquote_string(s+12);
+                           options->exclude_file =
+                               append_sl(options->exclude_file, qlist);
+                           amfree(qlist);
+                       } else if(strncmp(s-1, "exclude-list=", 13) == 0) {
+                           options->exclude_list =
+                               append_sl(options->exclude_list, qlist);
+                           qlist = unquote_string(s+12);
+                           amfree(qlist);
+                       } else if(strncmp(s-1, "include-file=", 13) == 0) {
+                           options->include_file =
+                               append_sl(options->include_file, qlist);
+                           qlist = unquote_string(s+12);
+                           amfree(qlist);
+                       } else if(strncmp(s-1, "include-list=", 13) == 0) {
+                           options->include_list =
+                               append_sl(options->include_list, qlist);
+                           qlist = unquote_string(s+12);
+                           amfree(qlist);
+                       } else {
+                           err_extra = vstralloc("Invalid parameter (",
+                               s-1, ")", NULL);
+                           goto err;           /* should have gotten to end */
+                       }
+                       skip_quoted_string(s, ch);
+                       skip_whitespace(s, ch); /* find the inclusion list */
+                       amfree(qlist);
                    }
                }
            }
            else {
-               options = alloc(sizeof(option_t));
+               options = alloc(SIZEOF(option_t));
                init_options(options);
            }
        }
+       else {
+           options = alloc(SIZEOF(option_t));
+           init_options(options);
+       }
 
+       /*@ignore@*/
        add_diskest(disk, amdevice, level, spindle, program_is_wrapper, prog, calcprog, options);
+       /*@end@*/
+       amfree(disk);
+       amfree(qdisk);
        amfree(amdevice);
+       amfree(qamdevice);
+    }
+    if (g_options == NULL) {
+       error("Missing OPTIONS line in sendsize input\n");
+       /*NOTREACHED*/
     }
     amfree(line);
 
@@ -333,6 +421,7 @@ char **argv;
            child_pid = wait(&child_status);
            if(child_pid == -1) {
                error("wait failed: %s", strerror(errno));
+               /*NOTREACHED*/
            }
            if(WIFSIGNALED(child_status)) {
                dbprintf(("%s: child %ld terminated with signal %d\n",
@@ -419,6 +508,7 @@ char **argv;
                exit(0);
            } else if(est->child == -1) {
                error("calc_estimates fork failed: %s", strerror(errno));
+               /*NOTREACHED*/
            }
            dumpsrunning++;                     /* parent */
        }
@@ -440,13 +530,13 @@ char **argv;
     amfree(g_options->str);
     amfree(g_options);
 
+#if defined(USE_DBMALLOC)
     malloc_size_2 = malloc_inuse(&malloc_hist_2);
 
     if(malloc_size_1 != malloc_size_2) {
-#if defined(USE_DBMALLOC)
        malloc_list(dbfd(), malloc_hist_1, malloc_hist_2);
-#endif
     }
+#endif
 
     dbclose();
     return 0;
@@ -456,21 +546,33 @@ char **argv;
              debug_prefix_time(NULL),
              err_extra ? ": " : "",
              err_extra ? err_extra : ""));
+    amfree(err_extra);
     dbclose();
     return 1;
 }
 
 
-void add_diskest(disk, amdevice, level, spindle, program_is_wrapper, prog, calcprog, options)
-char *disk, *amdevice, *prog, *calcprog;
-int level, spindle, program_is_wrapper;
-option_t *options;
+void
+add_diskest(
+    char *     disk,
+    char *     amdevice,
+    int                level,
+    int                spindle,
+    int                program_is_wrapper,
+    char *     prog,
+    char *     calcprog,
+    option_t * options)
 {
     disk_estimates_t *newp, *curp;
     amandates_t *amdp;
     int dumplev, estlev;
     time_t dumpdate;
 
+    if (level < 0)
+       level = 0;
+    if (level >= DUMP_LEVELS)
+       level = DUMP_LEVELS - 1;
+
     for(curp = est_list; curp != NULL; curp = curp->next) {
        if(strcmp(curp->amname, disk) == 0) {
            /* already have disk info, just note the level request */
@@ -488,13 +590,16 @@ option_t *options;
        }
     }
 
-    newp = (disk_estimates_t *) alloc(sizeof(disk_estimates_t));
-    memset(newp, 0, sizeof(*newp));
+    newp = (disk_estimates_t *) alloc(SIZEOF(disk_estimates_t));
+    memset(newp, 0, SIZEOF(*newp));
     newp->next = est_list;
     est_list = newp;
     newp->amname = stralloc(disk);
+    newp->qamname = quote_string(disk);
     newp->amdevice = stralloc(amdevice);
+    newp->qamdevice = quote_string(amdevice);
     newp->dirname = amname_to_dirname(newp->amdevice);
+    newp->qdirname = quote_string(newp->dirname);
     newp->program = stralloc(prog);
     if(calcprog != NULL)
        newp->calcprog = stralloc(calcprog);
@@ -520,12 +625,16 @@ option_t *options;
 }
 
 
-void free_estimates(est)
-disk_estimates_t *est;
+void
+free_estimates(
+    disk_estimates_t * est)
 {
     amfree(est->amname);
+    amfree(est->qamname);
     amfree(est->amdevice);
+    amfree(est->qamdevice);
     amfree(est->dirname);
+    amfree(est->qdirname);
     amfree(est->program);
     if(est->options) {
        free_sl(est->options->exclude_file);
@@ -543,13 +652,14 @@ disk_estimates_t *est;
  *
  */
 
-void calc_estimates(est)
-disk_estimates_t *est;
+void
+calc_estimates(
+    disk_estimates_t * est)
 {
-    dbprintf(("%s: calculating for amname '%s', dirname '%s', spindle %d\n",
+    dbprintf(("%s: calculating for amname %s, dirname %s, spindle %d\n",
              debug_prefix_time(NULL),
-             est->amname, est->dirname, est->spindle));
-
+             est->qamname, est->qdirname, est->spindle));
+       
     if(est->program_is_wrapper ==  1)
        wrapper_calc_estimates(est);
     else
@@ -573,14 +683,14 @@ disk_estimates_t *est;
          if (est->amdevice[0] == '/' && est->amdevice[1] == '/')
            dbprintf(("%s: Can't use CALCSIZE for samba estimate: %s %s\n",
                      debug_prefix_time(NULL),
-                     est->amname, est->dirname));
+                     est->qamname, est->qdirname));
          else
 #endif
            generic_calc_estimates(est);
 
-    dbprintf(("%s: done with amname '%s', dirname '%s', spindle %d\n",
+    dbprintf(("%s: done with amname %s dirname %s spindle %d\n",
              debug_prefix_time(NULL),
-             est->amname, est->dirname, est->spindle));
+             est->qamname, est->qdirname, est->spindle));
 }
 
 /*
@@ -589,33 +699,40 @@ disk_estimates_t *est;
  */
 
 /* local functions */
-long getsize_dump P((char *disk, char *amdevice, int level, option_t *options));
-long getsize_smbtar P((char *disk, char *amdevice, int level, option_t *options));
-long getsize_gnutar P((char *disk, char *amdevice, int level,
-                      option_t *options, time_t dumpsince));
-long getsize_wrapper P((char *program, char *disk, char *amdevice, int level,
-                       option_t *options, time_t dumpsince));
-long handle_dumpline P((char *str));
-double first_num P((char *str));
-
-void wrapper_calc_estimates(est)
-disk_estimates_t *est;
+off_t getsize_dump(char *disk, char *amdevice, int level, option_t *options);
+off_t getsize_star(char *disk, char *amdevice, int level,
+                      option_t *options, time_t dumpsince);
+off_t getsize_smbtar(char *disk, char *amdevice, int level, option_t *options);
+off_t getsize_gnutar(char *disk, char *amdevice, int level,
+                      option_t *options, time_t dumpsince);
+off_t getsize_wrapper(char *program, char *disk, char *amdevice, int level,
+                       option_t *options, time_t dumpsince);
+off_t handle_dumpline(char *str);
+double first_num(char *str);
+
+void
+wrapper_calc_estimates(
+    disk_estimates_t * est)
 {
   int level;
-  long size;
+  off_t size;
 
   for(level = 0; level < DUMP_LEVELS; level++) {
       if (est->est[level].needestimate) {
          dbprintf(("%s: getting size via wrapper for %s level %d\n",
-                   debug_prefix_time(NULL), est->amname, level));
-         size = getsize_wrapper(est->program, est->amname, est->amdevice, level, est->options,
-                                est->est[level].dumpsince);
+                   debug_prefix_time(NULL), est->qamname, level));
+         size = getsize_wrapper(est->program, est->amname, est->amdevice,
+                       level, est->options, est->est[level].dumpsince);
 
          amflock(1, "size");
 
-         fseek(stdout, (off_t)0, SEEK_SET);
+         if (fseek(stdout, 0L, SEEK_END) < 0) {
+             dbprintf(("wrapper_calc_estimates: warning - seek failed: %s\n",
+                       strerror(errno)));
+         }
 
-         printf("%s %d SIZE %ld\n", est->amname, level, size);
+         printf("%s %d SIZE " OFF_T_FMT "\n", est->qamname, level,
+                (OFF_T_FMT_TYPE)size);
          fflush(stdout);
 
          amfunlock(1, "size");
@@ -624,28 +741,36 @@ disk_estimates_t *est;
 }
 
 
-void generic_calc_estimates(est)
-disk_estimates_t *est;
+void
+generic_calc_estimates(
+    disk_estimates_t * est)
 {
     int pipefd = -1, nullfd = -1;
     char *cmd;
-    char *my_argv[DUMP_LEVELS*2+20];
+    char *my_argv[DUMP_LEVELS*2+22];
     char number[NUM_STR_SIZE];
-    int i, level, my_argc, calcpid;
+    int i, level, my_argc, status;
+    pid_t calcpid;
     int nb_exclude = 0;
     int nb_include = 0;
     char *file_exclude = NULL;
     char *file_include = NULL;
     times_t start_time;
     FILE *dumpout = NULL;
-    long size = 1;
+    off_t size = (off_t)1;
     char *line = NULL;
     char *match_expr;
 
     cmd = vstralloc(libexecdir, "/", "calcsize", versionsuffix(), NULL);
 
     my_argc = 0;
+
     my_argv[my_argc++] = stralloc("calcsize");
+    if (g_options->config)
+       my_argv[my_argc++] = stralloc(g_options->config);
+    else
+       my_argv[my_argc++] = stralloc("NOCONFIG");
+
     my_argv[my_argc++] = stralloc(est->calcprog);
 
     my_argv[my_argc++] = stralloc(est->amname);
@@ -662,9 +787,11 @@ disk_estimates_t *est;
        nb_include += est->options->include_list->nb_element;
 
     if(nb_exclude > 0)
-       file_exclude = build_exclude(est->amname, est->amdevice,est->options,0);
+       file_exclude = build_exclude(est->amname,
+               est->amdevice, est->options, 0);
     if(nb_include > 0)
-       file_include = build_include(est->amname, est->amdevice,est->options,0);
+       file_include = build_include(est->amname,
+               est->amdevice, est->options, 0);
 
     if(file_exclude) {
        my_argv[my_argc++] = stralloc("-X");
@@ -683,10 +810,10 @@ disk_estimates_t *est;
 
     for(level = 0; level < DUMP_LEVELS; level++) {
        if(est->est[level].needestimate) {
-           snprintf(number, sizeof(number), "%d", level);
+           snprintf(number, SIZEOF(number), "%d", level);
            my_argv[my_argc++] = stralloc(number); 
            dbprintf((" %s", number));
-           snprintf(number, sizeof(number),
+           snprintf(number, SIZEOF(number),
                        "%ld", (long)est->est[level].dumpsince);
            my_argv[my_argc++] = stralloc(number); 
            dbprintf((" %s", number));
@@ -706,29 +833,36 @@ disk_estimates_t *est;
     amfree(cmd);
 
     dumpout = fdopen(pipefd,"r");
-    match_expr = vstralloc(est->amname," %d SIZE %ld", NULL);
-    for(size = -1; (line = agets(dumpout)) != NULL; free(line)) {
+    if (!dumpout) {
+       error("Can't fdopen: %s", strerror(errno));
+       /*NOTREACHED*/
+    }
+    match_expr = vstralloc(est->qamname," %d SIZE " OFF_T_FMT, NULL);
+    for(size = (off_t)-1; (line = agets(dumpout)) != NULL; free(line)) {
+       if (line[0] == '\0')
+           continue;
        if(sscanf(line, match_expr, &level, &size) == 2) {
            printf("%s\n", line); /* write to amandad */
-           dbprintf(("%s: estimate size for %s level %d: %ld KB\n",
+           dbprintf(("%s: estimate size for %s level %d: " OFF_T_FMT " KB\n",
                      debug_prefix(NULL),
-                     est->amname,
+                     est->qamname,
                      level,
                      size));
        }
     }
     amfree(match_expr);
 
-    dbprintf(("%s: waiting for %s \"%s\" child\n",
-             debug_prefix_time(NULL), my_argv[0], est->amdevice));
-    wait(NULL);
-    dbprintf(("%s: after %s \"%s\" wait\n",
-             debug_prefix_time(NULL), my_argv[0], est->amdevice));
+    dbprintf(("%s: waiting for %s %s child (pid=%d)\n",
+             debug_prefix_time(NULL), my_argv[0], est->qamdevice, calcpid));
+    wait(&status);
+    dbprintf(("%s: after %s %s wait: child pid=%d status=%d\n",
+             debug_prefix_time(NULL), my_argv[0], est->qamdevice,
+             calcpid, WEXITSTATUS(status)));
 
     dbprintf(("%s: .....\n", debug_prefix_time(NULL)));
     dbprintf(("%s: estimate time for %s: %s\n",
              debug_prefix(NULL),
-             est->amname,
+             est->qamname,
              walltime_str(timessub(curclock(), start_time))));
 
 common_exit:
@@ -739,23 +873,29 @@ common_exit:
 }
 
 
-void dump_calc_estimates(est)
-disk_estimates_t *est;
+void
+dump_calc_estimates(
+    disk_estimates_t * est)
 {
     int level;
-    long size;
+    off_t size;
 
     for(level = 0; level < DUMP_LEVELS; level++) {
        if(est->est[level].needestimate) {
            dbprintf(("%s: getting size via dump for %s level %d\n",
-                     debug_prefix_time(NULL), est->amname, level));
-           size = getsize_dump(est->amname, est->amdevice,level, est->options);
+                     debug_prefix_time(NULL), est->qamname, level));
+           size = getsize_dump(est->amname, est->amdevice,
+                       level, est->options);
 
            amflock(1, "size");
 
-           fseek(stdout, (off_t)0, SEEK_SET);
+           if (fseek(stdout, 0L, SEEK_END) < 0) {
+               dbprintf(("dump_calc_estimates: warning - seek failed: %s\n",
+                               strerror(errno)));
+           }
 
-           printf("%s %d SIZE %ld\n", est->amname, level, size);
+           printf("%s %d SIZE " OFF_T_FMT "\n",
+                  est->qamname, level, (OFF_T_FMT_TYPE)size);
            fflush(stdout);
 
            amfunlock(1, "size");
@@ -764,23 +904,28 @@ disk_estimates_t *est;
 }
 
 #ifdef SAMBA_CLIENT
-void smbtar_calc_estimates(est)
-disk_estimates_t *est;
+void
+smbtar_calc_estimates(
+    disk_estimates_t * est)
 {
     int level;
-    long size;
+    off_t size;
 
     for(level = 0; level < DUMP_LEVELS; level++) {
        if(est->est[level].needestimate) {
            dbprintf(("%s: getting size via smbclient for %s level %d\n",
-                     debug_prefix_time(NULL), est->amname, level));
+                     debug_prefix_time(NULL), est->qamname, level));
            size = getsize_smbtar(est->amname, est->amdevice, level, est->options);
 
            amflock(1, "size");
 
-           fseek(stdout, (off_t)0, SEEK_SET);
+           if (fseek(stdout, 0L, SEEK_END) < 0) {
+               dbprintf(("smbtar_calc_estimates: warning - seek failed: %s\n",
+                               strerror(errno)));
+           }
 
-           printf("%s %d SIZE %ld\n", est->amname, level, size);
+           printf("%s %d SIZE " OFF_T_FMT "\n",
+                  est->qamname, level, (OFF_T_FMT_TYPE)size);
            fflush(stdout);
 
            amfunlock(1, "size");
@@ -790,24 +935,29 @@ disk_estimates_t *est;
 #endif
 
 #ifdef GNUTAR
-void gnutar_calc_estimates(est)
-disk_estimates_t *est;
+void
+gnutar_calc_estimates(
+    disk_estimates_t * est)
 {
   int level;
-  long size;
+  off_t size;
 
   for(level = 0; level < DUMP_LEVELS; level++) {
       if (est->est[level].needestimate) {
          dbprintf(("%s: getting size via gnutar for %s level %d\n",
-                   debug_prefix_time(NULL), est->amname, level));
+                   debug_prefix_time(NULL), est->qamname, level));
          size = getsize_gnutar(est->amname, est->amdevice, level,
                                est->options, est->est[level].dumpsince);
 
          amflock(1, "size");
 
-         fseek(stdout, (off_t)0, SEEK_SET);
+         if (fseek(stdout, 0L, SEEK_END) < 0) {
+             dbprintf(("gnutar_calc_estimates: warning - seek failed: %s\n",
+                               strerror(errno)));
+         }
 
-         printf("%s %d SIZE %ld\n", est->amname, level, size);
+         printf("%s %d SIZE " OFF_T_FMT "\n",
+                est->qamname, level, (OFF_T_FMT_TYPE)size);
          fflush(stdout);
 
          amfunlock(1, "size");
@@ -821,12 +971,13 @@ typedef struct regex_s {
     int scale;
 } regex_t;
 
+/*@ignore@*/
 regex_t re_size[] = {
 #ifdef DUMP
     {"  DUMP: estimated -*[0-9][0-9]* tape blocks", 1024},
     {"  DUMP: [Ee]stimated [0-9][0-9]* blocks", 512},
-    {"  DUMP: [Ee]stimated [0-9][0-9]* bytes", 1},            /* Ultrix 4.4 */
-    {" UFSDUMP: estimated [0-9][0-9]* blocks", 512},           /* NEC EWS-UX */
+    {"  DUMP: [Ee]stimated [0-9][0-9]* bytes", 1},             /* Ultrix 4.4 */
+    {" UFSDUMP: estimated [0-9][0-9]* blocks", 512},           /* NEC EWS-UX */
     {"dump: Estimate: [0-9][0-9]* tape blocks", 1024},             /* OSF/1 */
     {"backup: There are an estimated [0-9][0-9]* tape blocks.",1024}, /* AIX */
     {"backup: estimated [0-9][0-9]* 1k blocks", 1024},               /* AIX */
@@ -834,27 +985,27 @@ regex_t re_size[] = {
     {"backup: [0-9][0-9]* tape blocks on [0-9][0-9]* tape(s)",1024},  /* AIX */
     {"backup: [0-9][0-9]* 1k blocks on [0-9][0-9]* volume(s)",1024},  /* AIX */
     {"dump: Estimate: [0-9][0-9]* blocks being output to pipe",1024},
-                                                              /* DU 4.0 dump */
-    {"dump: Dumping [0-9][0-9]* bytes, ", 1},                /* DU 4.0 vdump */
-    {"DUMP: estimated [0-9][0-9]* KB output", 1024},                 /* HPUX */
-    {"DUMP: estimated [0-9][0-9]* KB\\.", 1024},                 /* NetApp */
-    {"  UFSDUMP: estimated [0-9][0-9]* blocks", 512},               /* Sinix */
+                                                             /* DU 4.0 dump  */
+    {"dump: Dumping [0-9][0-9]* bytes, ", 1},                /* DU 4.0 vdump */
+    {"DUMP: estimated [0-9][0-9]* KB output", 1024},                 /* HPUX */
+    {"DUMP: estimated [0-9][0-9]* KB\\.", 1024},                   /* NetApp */
+    {"  UFSDUMP: estimated [0-9][0-9]* blocks", 512},               /* Sinix */
 
 #ifdef HAVE_DUMP_ESTIMATE
     {"[0-9][0-9]* blocks, [0-9][0-9]*.[0-9][0-9]* volumes", 1024},
-                                                          /* DU 3.2g dump -E */
-    {"^[0-9][0-9]* blocks$", 1024},                      /* DU 4.0 dump  -E */
-    {"^[0-9][0-9]*$", 1},                             /* Solaris ufsdump -S */
+                                                          /* DU 3.2g dump -E */
+    {"^[0-9][0-9]* blocks$", 1024},                       /* DU 4.0 dump  -E */
+    {"^[0-9][0-9]*$", 1},                              /* Solaris ufsdump -S */
 #endif
 #endif
 
 #ifdef VDUMP
-    {"vdump: Dumping [0-9][0-9]* bytes, ", 1},               /* OSF/1 vdump */
+    {"vdump: Dumping [0-9][0-9]* bytes, ", 1},                /* OSF/1 vdump */
 #endif
     
 #ifdef VXDUMP
-    {"vxdump: estimated [0-9][0-9]* blocks", 512},          /* HPUX's vxdump */
-    {"  VXDUMP: estimated [0-9][0-9]* blocks", 512},                /* Sinix */
+    {"vxdump: estimated [0-9][0-9]* blocks", 512},          /* HPUX's vxdump */
+    {"  VXDUMP: estimated [0-9][0-9]* blocks", 512},                /* Sinix */
 #endif
 
 #ifdef XFSDUMP
@@ -877,16 +1028,18 @@ regex_t re_size[] = {
 
     { NULL, 0 }
 };
-
-
-long getsize_dump(disk, amdevice, level, options)
-    char *disk, *amdevice;
-    int level;
-    option_t *options;
+/*@end@*/
+
+off_t
+getsize_dump(
+    char       *disk,
+    char       *amdevice,
+    int                level,
+    option_t * options)
 {
     int pipefd[2], nullfd, stdoutfd, killctl[2];
     pid_t dumppid;
-    long size;
+    off_t size;
     FILE *dumpout;
     char *dumpkeys = NULL;
     char *device = NULL;
@@ -898,29 +1051,55 @@ long getsize_dump(disk, amdevice, level, options)
     char level_str[NUM_STR_SIZE];
     int s;
     times_t start_time;
+    char *qdisk = quote_string(disk);
+    char *qdevice;
+    char *config;
+#ifdef DUMP
+    int is_rundump = 1;
+#endif
+
+    (void)options;     /* Quiet unused parameter warning */
 
-    snprintf(level_str, sizeof(level_str), "%d", level);
+    (void)getsize_smbtar;      /* Quiet unused parameter warning */
+
+    snprintf(level_str, SIZEOF(level_str), "%d", level);
 
     device = amname_to_devname(amdevice);
+    qdevice = quote_string(device);
     fstype = amname_to_fstype(amdevice);
 
-    dbprintf(("%s: calculating for device '%s' with '%s'\n",
-             debug_prefix_time(NULL), device, fstype));
+    dbprintf(("%s: calculating for device %s with %s\n",
+             debug_prefix_time(NULL), qdevice, fstype));
 
     cmd = vstralloc(libexecdir, "/rundump", versionsuffix(), NULL);
     rundump_cmd = stralloc(cmd);
-
+    if (g_options->config)
+        config = g_options->config;
+    else
+        config = "NOCONFIG";
     if ((stdoutfd = nullfd = open("/dev/null", O_RDWR)) == -1) {
        dbprintf(("getsize_dump could not open /dev/null: %s\n",
-                 strerror(errno)));
+                 strerror(errno)));
        amfree(cmd);
        amfree(rundump_cmd);
        amfree(fstype);
        amfree(device);
+       amfree(qdevice);
+       amfree(qdisk);
        return(-1);
     }
     pipefd[0] = pipefd[1] = killctl[0] = killctl[1] = -1;
-    pipe(pipefd);
+    if (pipe(pipefd) < 0) {
+       dbprintf(("getsize_dump could create data pipes: %s\n",
+                 strerror(errno)));
+       amfree(cmd);
+       amfree(rundump_cmd);
+       amfree(fstype);
+       amfree(device);
+       amfree(qdevice);
+       amfree(qdisk);
+       return(-1);
+    }
 
 #ifdef XFSDUMP                                         /* { */
 #ifdef DUMP                                            /* { */
@@ -929,9 +1108,9 @@ long getsize_dump(disk, amdevice, level, options)
     if (1)
 #endif                                                 /* } */
     {
-        name = stralloc(" (xfsdump)");
+       name = stralloc(" (xfsdump)");
        dbprintf(("%s: running \"%s%s -F -J -l %s - %s\"\n",
-                 debug_prefix_time(NULL), cmd, name, level_str, device));
+                 debug_prefix_time(NULL), cmd, name, level_str, qdevice));
     }
     else
 #endif                                                 /* } */
@@ -943,14 +1122,16 @@ long getsize_dump(disk, amdevice, level, options)
 #endif                                                 /* } */
     {
 #ifdef USE_RUNDUMP
-        name = stralloc(" (vxdump)");
+       name = stralloc(" (vxdump)");
 #else
        name = stralloc("");
        cmd = newstralloc(cmd, VXDUMP);
+       config = skip_argument;
+       is_rundump = 0;
 #endif
        dumpkeys = vstralloc(level_str, "s", "f", NULL);
-        dbprintf(("%s: running \"%s%s %s 1048576 - %s\"\n",
-                 debug_prefix_time(NULL), cmd, name, dumpkeys, device));
+       dbprintf(("%s: running \"%s%s %s 1048576 - %s\"\n",
+                 debug_prefix_time(NULL), cmd, name, dumpkeys, qdevice));
     }
     else
 #endif                                                 /* } */
@@ -963,10 +1144,12 @@ long getsize_dump(disk, amdevice, level, options)
     {
        name = stralloc(" (vdump)");
        amfree(device);
+       amfree(qdevice);
        device = amname_to_dirname(amdevice);
+       qdevice = quote_string(device);
        dumpkeys = vstralloc(level_str, "b", "f", NULL);
        dbprintf(("%s: running \"%s%s %s 60 - %s\"\n",
-                 debug_prefix_time(NULL), cmd, name, dumpkeys, device));
+                 debug_prefix_time(NULL), cmd, name, dumpkeys, qdevice));
     }
     else
 #endif                                                 /* } */
@@ -981,12 +1164,14 @@ long getsize_dump(disk, amdevice, level, options)
 # else                                                 /* } { */
        name = stralloc("");
        cmd = newstralloc(cmd, DUMP);
+        config = skip_argument;
+       is_rundump = 0;
 # endif                                                        /* } */
 
 # ifdef AIX_BACKUP                                     /* { */
        dumpkeys = vstralloc("-", level_str, "f", NULL);
        dbprintf(("%s: running \"%s%s %s - %s\"\n",
-                 debug_prefix_time(NULL), cmd, name, dumpkeys, device));
+                 debug_prefix_time(NULL), cmd, name, dumpkeys, qdevice));
 # else                                                 /* } { */
        dumpkeys = vstralloc(level_str,
 #  ifdef HAVE_DUMP_ESTIMATE                            /* { */
@@ -1003,10 +1188,10 @@ long getsize_dump(disk, amdevice, level, options)
 
 #  ifdef HAVE_HONOR_NODUMP                             /* { */
        dbprintf(("%s: running \"%s%s %s 0 1048576 - %s\"\n",
-                 debug_prefix_time(NULL), cmd, name, dumpkeys, device));
+                 debug_prefix_time(NULL), cmd, name, dumpkeys, qdevice));
 #  else                                                        /* } { */
        dbprintf(("%s: running \"%s%s %s 1048576 - %s\"\n",
-                 debug_prefix_time(NULL), cmd, name, dumpkeys, device));
+                 debug_prefix_time(NULL), cmd, name, dumpkeys, qdevice));
 #  endif                                               /* } */
 # endif                                                        /* } */
     }
@@ -1014,9 +1199,15 @@ long getsize_dump(disk, amdevice, level, options)
 #endif                                                 /* } */
     {
        error("no dump program available");
+       /*NOTREACHED*/
     }
 
-    pipe(killctl);
+    if (pipe(killctl) < 0) {
+       dbprintf(("%s: Could not create pipe: %s\n",
+               debug_prefix(NULL), strerror(errno)));
+       /* Message will be printed later... */
+       killctl[0] = killctl[1] = -1;
+    }
 
     start_time = curclock();
     switch(dumppid = fork()) {
@@ -1027,6 +1218,8 @@ long getsize_dump(disk, amdevice, level, options)
        amfree(cmd);
        amfree(rundump_cmd);
        amfree(device);
+       amfree(qdevice);
+       amfree(qdisk);
        amfree(name);
        amfree(fstype);
        return -1;
@@ -1036,8 +1229,7 @@ long getsize_dump(disk, amdevice, level, options)
        if(SETPGRP == -1)
            SETPGRP_FAILED();
        else if (killctl[0] == -1 || killctl[1] == -1)
-           dbprintf(("%s: pipe for killpgrp failed, trying without killpgrp\n",
-                     debug_prefix(NULL)));
+           dbprintf(("%s: Trying without killpgrp\n", debug_prefix(NULL)));
        else {
            switch(fork()) {
            case -1:
@@ -1047,6 +1239,7 @@ long getsize_dump(disk, amdevice, level, options)
 
            default:
            {
+               char *config;
                char *killpgrp_cmd = vstralloc(libexecdir, "/killpgrp",
                                               versionsuffix(), NULL);
                dbprintf(("%s: running %s\n",
@@ -1058,7 +1251,12 @@ long getsize_dump(disk, amdevice, level, options)
                close(pipefd[1]);
                close(killctl[1]);
                close(nullfd);
-               execle(killpgrp_cmd, killpgrp_cmd, (char *)0, safe_env());
+               if (g_options->config)
+                   config = g_options->config;
+               else
+                   config = "NOCONFIG";
+               execle(killpgrp_cmd, killpgrp_cmd, config, (char *)0,
+                      safe_env());
                dbprintf(("%s: cannot execute %s: %s\n",
                          debug_prefix(NULL), killpgrp_cmd, strerror(errno)));
                exit(-1);
@@ -1084,8 +1282,12 @@ long getsize_dump(disk, amdevice, level, options)
 #else
        if (1)
 #endif
-           execle(cmd, "xfsdump", "-F", "-J", "-l", level_str, "-", device,
-                  (char *)0, safe_env());
+           if (is_rundump)
+               execle(cmd, "rundump", config, "xfsdump", "-F", "-J", "-l",
+                      level_str, "-", device, (char *)0, safe_env());
+           else
+               execle(cmd, "xfsdump", "-F", "-J", "-l",
+                      level_str, "-", device, (char *)0, safe_env());
        else
 #endif
 #ifdef VXDUMP
@@ -1094,8 +1296,12 @@ long getsize_dump(disk, amdevice, level, options)
 #else
        if (1)
 #endif
-           execle(cmd, "vxdump", dumpkeys, "1048576", "-", device, (char *)0,
-                  safe_env());
+           if (is_rundump)
+               execle(cmd, "rundump", config, "vxdump", dumpkeys, "1048576",
+                      "-", device, (char *)0, safe_env());
+           else
+               execle(cmd, "vxdump", dumpkeys, "1048576", "-",
+                      device, (char *)0, safe_env());
        else
 #endif
 #ifdef VDUMP
@@ -1104,24 +1310,42 @@ long getsize_dump(disk, amdevice, level, options)
 #else
        if (1)
 #endif
-           execle(cmd, "vdump", dumpkeys, "60", "-", device, (char *)0,
-                  safe_env());
+           if (is_rundump)
+               execle(cmd, "rundump", config, "vdump", dumpkeys, "60", "-",
+                      device, (char *)0, safe_env());
+           else
+               execle(cmd, "vdump", dumpkeys, "60", "-",
+                      device, (char *)0, safe_env());
        else
 #endif
 #ifdef DUMP
 # ifdef AIX_BACKUP
-           execle(cmd, "backup", dumpkeys, "-", device, (char *)0, safe_env());
+           if (is_rundump)
+               execle(cmd, "rundump", config, "backup", dumpkeys, "-",
+                      device, (char *)0, safe_env());
+           else
+               execle(cmd, "backup", dumpkeys, "-",
+                      device, (char *)0, safe_env());
 # else
-           execle(cmd, "dump", dumpkeys, 
+           if (is_rundump) {
+               execle(cmd, "rundump", config, "dump", dumpkeys, 
 #ifdef HAVE_HONOR_NODUMP
-                  "0",
+                      "0",
 #endif
-                  "1048576", "-", device, (char *)0, safe_env());
+                      "1048576", "-", device, (char *)0, safe_env());
+           } else {
+               execle(cmd, "dump", dumpkeys, 
+#ifdef HAVE_HONOR_NODUMP
+                      "0",
+#endif
+                      "1048576", "-", device, (char *)0, safe_env());
 # endif
+           }
 #endif
        {
            error("exec %s failed or no dump program available: %s",
                  cmd, strerror(errno));
+           /*NOTREACHED*/
        }
     }
 
@@ -1132,13 +1356,24 @@ long getsize_dump(disk, amdevice, level, options)
     if (killctl[0] != -1)
        aclose(killctl[0]);
     dumpout = fdopen(pipefd[0],"r");
+    if (!dumpout) {
+       error("Can't fdopen: %s", strerror(errno));
+       /*NOTREACHED*/
+    }
 
-    for(size = -1; (line = agets(dumpout)) != NULL; free(line)) {
+    for(size = (off_t)-1; (line = agets(dumpout)) != NULL; free(line)) {
+       if (line[0] == '\0')
+           continue;
        dbprintf(("%s: %s\n", debug_prefix_time(NULL), line));
        size = handle_dumpline(line);
-       if(size > -1) {
+       if(size > (off_t)-1) {
            amfree(line);
-           if((line = agets(dumpout)) != NULL) {
+           while ((line = agets(dumpout)) != NULL) {
+               if (line[0] != '\0')
+                   break;
+               amfree(line);
+           }
+           if (line != NULL) {
                dbprintf(("%s: %s\n", debug_prefix_time(NULL), line));
            }
            break;
@@ -1149,23 +1384,23 @@ long getsize_dump(disk, amdevice, level, options)
     dbprintf(("%s: .....\n", debug_prefix_time(NULL)));
     dbprintf(("%s: estimate time for %s level %d: %s\n",
              debug_prefix(NULL),
-             disk,
+             qdisk,
              level,
              walltime_str(timessub(curclock(), start_time))));
-    if(size == -1) {
+    if(size == (off_t)-1) {
        dbprintf(("%s: no size line match in %s%s output for \"%s\"\n",
                  debug_prefix(NULL), cmd, name, disk));
        dbprintf(("%s: .....\n", debug_prefix(NULL)));
        dbprintf(("%s: Run %s%s manually to check for errors\n",
                    debug_prefix(NULL), cmd, name));
-    } else if(size == 0 && level == 0) {
+    } else if(size == (off_t)0 && level == 0) {
        dbprintf(("%s: possible %s%s problem -- is \"%s\" really empty?\n",
                  debug_prefix(NULL), cmd, name, disk));
        dbprintf(("%s: .....\n", debug_prefix(NULL)));
     } else {
            dbprintf(("%s: estimate size for %s level %d: %ld KB\n",
              debug_prefix(NULL),
-             disk,
+             qdisk,
              level,
              size));
     }
@@ -1211,10 +1446,10 @@ long getsize_dump(disk, amdevice, level, options)
     }
 
     dbprintf(("%s: waiting for %s%s \"%s\" child\n",
-             debug_prefix_time(NULL), cmd, name, disk));
+             debug_prefix_time(NULL), cmd, name, qdisk));
     wait(NULL);
-    dbprintf(("%s: after %s%s \"%s\" wait\n",
-             debug_prefix_time(NULL), cmd, name, disk));
+    dbprintf(("%s: after %s%s %s wait\n",
+             debug_prefix_time(NULL), cmd, name, qdisk));
 
  terminated:
 
@@ -1222,6 +1457,8 @@ long getsize_dump(disk, amdevice, level, options)
     afclose(dumpout);
 
     amfree(device);
+    amfree(qdevice);
+    amfree(qdisk);
     amfree(fstype);
 
     amfree(cmd);
@@ -1231,24 +1468,29 @@ long getsize_dump(disk, amdevice, level, options)
 }
 
 #ifdef SAMBA_CLIENT
-long getsize_smbtar(disk, amdevice, level, optionns)
-    char *disk, *amdevice;
-    int level;
-    option_t *optionns;
+off_t
+getsize_smbtar(
+    char       *disk,
+    char       *amdevice,
+    int                level,
+    option_t * options)
 {
     int pipefd = -1, nullfd = -1, passwdfd = -1;
-    int dumppid;
-    long size;
+    pid_t dumppid;
+    off_t size;
     FILE *dumpout;
     char *tarkeys, *sharename, *user_and_password = NULL, *domain = NULL;
     char *share = NULL, *subdir = NULL;
-    int lpass;
+    size_t lpass;
     char *pwtext;
-    int pwtext_len;
+    size_t pwtext_len;
     char *line;
     char *pw_fd_env;
     times_t start_time;
     char *error_pn = NULL;
+    char *qdisk = quote_string(disk);
+
+    (void)options;     /* Quiet unused parameter warning */
 
     error_pn = stralloc2(get_pname(), "-smbclient");
 
@@ -1258,14 +1500,16 @@ long getsize_smbtar(disk, amdevice, level, optionns)
        amfree(subdir);
        set_pname(error_pn);
        amfree(error_pn);
-       error("cannot parse disk entry '%s' for share/subdir", disk);
+       error("cannot parse disk entry %s for share/subdir", qdisk);
+       /*NOTREACHED*/
     }
     if ((subdir) && (SAMBA_VERSION < 2)) {
        amfree(share);
        amfree(subdir);
        set_pname(error_pn);
        amfree(error_pn);
-       error("subdirectory specified for share '%s' but samba not v2 or better", disk);
+       error("subdirectory specified for share %s but samba not v2 or better", qdisk);
+       /*NOTREACHED*/
     }
     if ((user_and_password = findpass(share, &domain)) == NULL) {
 
@@ -1276,10 +1520,11 @@ long getsize_smbtar(disk, amdevice, level, optionns)
        set_pname(error_pn);
        amfree(error_pn);
        error("cannot find password for %s", disk);
+       /*NOTREACHED*/
     }
     lpass = strlen(user_and_password);
     if ((pwtext = strchr(user_and_password, '%')) == NULL) {
-       memset(user_and_password, '\0', lpass);
+       memset(user_and_password, '\0', (size_t)lpass);
        amfree(user_and_password);
        if(domain) {
            memset(domain, '\0', strlen(domain));
@@ -1288,11 +1533,12 @@ long getsize_smbtar(disk, amdevice, level, optionns)
        set_pname(error_pn);
        amfree(error_pn);
        error("password field not \'user%%pass\' for %s", disk);
+       /*NOTREACHED*/
     }
     *pwtext++ = '\0';
     pwtext_len = strlen(pwtext);
     if ((sharename = makesharename(share, 0)) == NULL) {
-       memset(user_and_password, '\0', lpass);
+       memset(user_and_password, '\0', (size_t)lpass);
        amfree(user_and_password);
        if(domain) {
            memset(domain, '\0', strlen(domain));
@@ -1301,9 +1547,10 @@ long getsize_smbtar(disk, amdevice, level, optionns)
        set_pname(error_pn);
        amfree(error_pn);
        error("cannot make share name of %s", share);
+       /*NOTREACHED*/
     }
     if ((nullfd = open("/dev/null", O_RDWR)) == -1) {
-       memset(user_and_password, '\0', lpass);
+       memset(user_and_password, '\0', (size_t)lpass);
        amfree(user_and_password);
        if(domain) {
            memset(domain, '\0', strlen(domain));
@@ -1314,6 +1561,7 @@ long getsize_smbtar(disk, amdevice, level, optionns)
        amfree(sharename);
        error("could not open /dev/null: %s\n",
              strerror(errno));
+       /*NOTREACHED*/
     }
 
 #if SAMBA_VERSION >= 2
@@ -1357,17 +1605,18 @@ long getsize_smbtar(disk, amdevice, level, optionns)
        amfree(domain);
     }
     aclose(nullfd);
-    if(pwtext_len > 0 && fullwrite(passwdfd, pwtext, pwtext_len) < 0) {
+    if(pwtext_len > 0 && fullwrite(passwdfd, pwtext, (size_t)pwtext_len) < 0) {
        int save_errno = errno;
 
-       memset(user_and_password, '\0', lpass);
+       memset(user_and_password, '\0', (size_t)lpass);
        amfree(user_and_password);
        aclose(passwdfd);
        set_pname(error_pn);
        amfree(error_pn);
        error("password write failed: %s", strerror(save_errno));
+       /*NOTREACHED*/
     }
-    memset(user_and_password, '\0', lpass);
+    memset(user_and_password, '\0', (size_t)lpass);
     amfree(user_and_password);
     aclose(passwdfd);
     amfree(sharename);
@@ -1375,13 +1624,24 @@ long getsize_smbtar(disk, amdevice, level, optionns)
     amfree(subdir);
     amfree(error_pn);
     dumpout = fdopen(pipefd,"r");
+    if (!dumpout) {
+       error("Can't fdopen: %s", strerror(errno));
+       /*NOTREACHED*/
+    }
 
-    for(size = -1; (line = agets(dumpout)) != NULL; free(line)) {
+    for(size = (off_t)-1; (line = agets(dumpout)) != NULL; free(line)) {
+       if (line[0] == '\0')
+           continue;
        dbprintf(("%s: %s\n", debug_prefix_time(NULL), line));
        size = handle_dumpline(line);
        if(size > -1) {
            amfree(line);
-           if((line = agets(dumpout)) != NULL) {
+           while ((line = agets(dumpout)) != NULL) {
+               if (line[0] != '\0')
+                   break;
+               amfree(line);
+           }
+           if(line != NULL) {
                dbprintf(("%s: %s\n", debug_prefix_time(NULL), line));
            }
            break;
@@ -1392,50 +1652,54 @@ long getsize_smbtar(disk, amdevice, level, optionns)
     dbprintf(("%s: .....\n", debug_prefix_time(NULL)));
     dbprintf(("%s: estimate time for %s level %d: %s\n",
              debug_prefix(NULL),
-             disk,
+             qdisk,
              level,
              walltime_str(timessub(curclock(), start_time))));
-    if(size == -1) {
+    if(size == (off_t)-1) {
        dbprintf(("%s: no size line match in %s output for \"%s\"\n",
                  debug_prefix(NULL), SAMBA_CLIENT, disk));
        dbprintf(("%s: .....\n", debug_prefix(NULL)));
-    } else if(size == 0 && level == 0) {
+    } else if(size == (off_t)0 && level == 0) {
        dbprintf(("%s: possible %s problem -- is \"%s\" really empty?\n",
                  debug_prefix(NULL), SAMBA_CLIENT, disk));
        dbprintf(("%s: .....\n", debug_prefix(NULL)));
     }
     dbprintf(("%s: estimate size for %s level %d: %ld KB\n",
              debug_prefix(NULL),
-             disk,
+             qdisk,
              level,
              size));
 
     kill(-dumppid, SIGTERM);
 
     dbprintf(("%s: waiting for %s \"%s\" child\n",
-             debug_prefix_time(NULL), SAMBA_CLIENT, disk));
+             debug_prefix_time(NULL), SAMBA_CLIENT, qdisk));
     wait(NULL);
-    dbprintf(("%s: after %s \"%s\" wait\n",
-             debug_prefix_time(NULL), SAMBA_CLIENT, disk));
+    dbprintf(("%s: after %s %s wait\n",
+             debug_prefix_time(NULL), SAMBA_CLIENT, qdisk));
 
     afclose(dumpout);
     pipefd = -1;
 
     amfree(error_pn);
+    amfree(qdisk);
 
     return size;
 }
 #endif
 
 #ifdef GNUTAR
-long getsize_gnutar(disk, amdevice, level, options, dumpsince)
-char *disk, *amdevice;
-int level;
-option_t *options;
-time_t dumpsince;
+off_t
+getsize_gnutar(
+    char       *disk,
+    char       *amdevice,
+    int                level,
+    option_t * options,
+    time_t     dumpsince)
 {
-    int pipefd = -1, nullfd = -1, dumppid;
-    long size = -1;
+    int pipefd = -1, nullfd = -1;
+    pid_t dumppid;
+    off_t size = (off_t)-1;
     FILE *dumpout = NULL;
     char *incrname = NULL;
     char *basename = NULL;
@@ -1454,6 +1718,11 @@ time_t dumpsince;
     char *file_exclude = NULL;
     char *file_include = NULL;
     times_t start_time;
+    int infd, outfd;
+    ssize_t nb;
+    char buf[32768];
+    char *qdisk = quote_string(disk);
+    char *gnutar_list_dir;
 
     if(options->exclude_file) nb_exclude += options->exclude_file->nb_element;
     if(options->exclude_list) nb_exclude += options->exclude_list->nb_element;
@@ -1463,17 +1732,19 @@ time_t dumpsince;
     if(nb_exclude > 0) file_exclude = build_exclude(disk, amdevice, options, 0);
     if(nb_include > 0) file_include = build_include(disk, amdevice, options, 0);
 
-    my_argv = alloc(sizeof(char *) * 21);
+    my_argv = alloc(SIZEOF(char *) * 22);
     i = 0;
 
-#ifdef GNUTAR_LISTED_INCREMENTAL_DIR
-    {
+    gnutar_list_dir = client_getconf_str(CLN_GNUTAR_LIST_DIR);
+    if (strlen(gnutar_list_dir) == 0)
+       gnutar_list_dir = NULL;
+    if (gnutar_list_dir) {
        char number[NUM_STR_SIZE];
        char *s;
        int ch;
        int baselevel;
 
-       basename = vstralloc(GNUTAR_LISTED_INCREMENTAL_DIR,
+       basename = vstralloc(gnutar_list_dir,
                             "/",
                             g_options->hostname,
                             disk,
@@ -1482,12 +1753,12 @@ time_t dumpsince;
         * The loop starts at the first character of the host name,
         * not the '/'.
         */
-       s = basename + sizeof(GNUTAR_LISTED_INCREMENTAL_DIR);
+       s = basename + strlen(gnutar_list_dir) + 1;
        while((ch = *s++) != '\0') {
            if(ch == '/' || isspace(ch)) s[-1] = '_';
        }
 
-       snprintf(number, sizeof(number), "%d", level);
+       snprintf(number, SIZEOF(number), "%d", level);
        incrname = vstralloc(basename, "_", number, ".new", NULL);
        unlink(incrname);
 
@@ -1497,15 +1768,16 @@ time_t dumpsince;
         * be true for a level 0), arrange to read from /dev/null.
         */
        baselevel = level;
-       while (in == NULL) {
+       infd = -1;
+       while (infd == -1) {
            if (--baselevel >= 0) {
-               snprintf(number, sizeof(number), "%d", baselevel);
+               snprintf(number, SIZEOF(number), "%d", baselevel);
                inputname = newvstralloc(inputname,
                                         basename, "_", number, NULL);
            } else {
                inputname = newstralloc(inputname, "/dev/null");
            }
-           if ((in = fopen(inputname, "r")) == NULL) {
+           if ((infd = open(inputname, O_RDONLY)) == -1) {
                int save_errno = errno;
 
                dbprintf(("%s: gnutar: error opening %s: %s\n",
@@ -1519,59 +1791,57 @@ time_t dumpsince;
        /*
         * Copy the previous listed incremental file to the new one.
         */
-       if ((out = fopen(incrname, "w")) == NULL) {
+       if ((outfd = open(incrname, O_WRONLY|O_CREAT, 0600)) == -1) {
            dbprintf(("%s: opening %s: %s\n",
                      debug_prefix(NULL), incrname, strerror(errno)));
            goto common_exit;
        }
 
-       for (; (line = agets(in)) != NULL; free(line)) {
-           if (fputs(line, out) == EOF || putc('\n', out) == EOF) {
+       while ((nb = read(infd, &buf, SIZEOF(buf))) > 0) {
+           if (fullwrite(outfd, &buf, (size_t)nb) < nb) {
                dbprintf(("%s: writing to %s: %s\n",
                           debug_prefix(NULL), incrname, strerror(errno)));
                goto common_exit;
            }
        }
-       amfree(line);
 
-       if (ferror(in)) {
+       if (nb < 0) {
            dbprintf(("%s: reading from %s: %s\n",
                      debug_prefix(NULL), inputname, strerror(errno)));
            goto common_exit;
        }
-       if (fclose(in) == EOF) {
+
+       if (close(infd) != 0) {
            dbprintf(("%s: closing %s: %s\n",
                      debug_prefix(NULL), inputname, strerror(errno)));
-           in = NULL;
            goto common_exit;
        }
-       in = NULL;
-       if (fclose(out) == EOF) {
+       if (close(outfd) != 0) {
            dbprintf(("%s: closing %s: %s\n",
                      debug_prefix(NULL), incrname, strerror(errno)));
-           out = NULL;
            goto common_exit;
        }
-       out = NULL;
 
        amfree(inputname);
        amfree(basename);
     }
-#endif
 
     gmtm = gmtime(&dumpsince);
-    snprintf(dumptimestr, sizeof(dumptimestr),
+    snprintf(dumptimestr, SIZEOF(dumptimestr),
                "%04d-%02d-%02d %2d:%02d:%02d GMT",
                gmtm->tm_year + 1900, gmtm->tm_mon+1, gmtm->tm_mday,
                gmtm->tm_hour, gmtm->tm_min, gmtm->tm_sec);
 
     dirname = amname_to_dirname(amdevice);
 
-
-
-#ifdef GNUTAR
     cmd = vstralloc(libexecdir, "/", "runtar", versionsuffix(), NULL);
+    my_argv[i++] = "runtar";
+    if (g_options->config)
+       my_argv[i++] = g_options->config;
+    else
+       my_argv[i++] = "NOCONFIG";
 
+#ifdef GNUTAR
     my_argv[i++] = GNUTAR;
 #else
     my_argv[i++] = "tar";
@@ -1582,14 +1852,14 @@ time_t dumpsince;
     my_argv[i++] = "--directory";
     my_argv[i++] = dirname;
     my_argv[i++] = "--one-file-system";
-#ifdef GNUTAR_LISTED_INCREMENTAL_DIR
-    my_argv[i++] = "--listed-incremental";
-    my_argv[i++] = incrname;
-#else
-    my_argv[i++] = "--incremental";
-    my_argv[i++] = "--newer";
-    my_argv[i++] = dumptimestr;
-#endif
+    if (gnutar_list_dir) {
+           my_argv[i++] = "--listed-incremental";
+           my_argv[i++] = incrname;
+    } else {
+       my_argv[i++] = "--incremental";
+       my_argv[i++] = "--newer";
+       my_argv[i++] = dumptimestr;
+    }
 #ifdef ENABLE_GNUTAR_ATIME_PRESERVE
     /* --atime-preserve causes gnutar to call
      * utime() after reading files in order to
@@ -1618,21 +1888,35 @@ time_t dumpsince;
 
     start_time = curclock();
 
-    nullfd = open("/dev/null", O_RDWR);
+    if ((nullfd = open("/dev/null", O_RDWR)) == -1) {
+       dbprintf(("Cannot access /dev/null : %s\n", strerror(errno)));
+       goto common_exit;
+    }
+
     dumppid = pipespawnv(cmd, STDERR_PIPE, &nullfd, &nullfd, &pipefd, my_argv);
-    amfree(cmd);
-    amfree(file_exclude);
-    amfree(file_include);
 
     dumpout = fdopen(pipefd,"r");
+    if (!dumpout) {
+       error("Can't fdopen: %s", strerror(errno));
+       /*NOTREACHED*/
+    }
 
-    for(size = -1; (line = agets(dumpout)) != NULL; free(line)) {
+    for(size = (off_t)-1; (line = agets(dumpout)) != NULL; free(line)) {
+       if (line[0] == '\0')
+           continue;
        dbprintf(("%s: %s\n", debug_prefix_time(NULL), line));
        size = handle_dumpline(line);
-       if(size > -1) {
+       if(size > (off_t)-1) {
            amfree(line);
-           if((line = agets(dumpout)) != NULL) {
+           while ((line = agets(dumpout)) != NULL) {
+               if (line[0] != '\0') {
+                   break;
+               }
+               amfree(line);
+           }
+           if (line != NULL) {
                dbprintf(("%s: %s\n", debug_prefix_time(NULL), line));
+               break;
            }
            break;
        }
@@ -1642,31 +1926,31 @@ time_t dumpsince;
     dbprintf(("%s: .....\n", debug_prefix_time(NULL)));
     dbprintf(("%s: estimate time for %s level %d: %s\n",
              debug_prefix(NULL),
-             disk,
+             qdisk,
              level,
              walltime_str(timessub(curclock(), start_time))));
-    if(size == -1) {
+    if(size == (off_t)-1) {
        dbprintf(("%s: no size line match in %s output for \"%s\"\n",
                  debug_prefix(NULL), my_argv[0], disk));
        dbprintf(("%s: .....\n", debug_prefix(NULL)));
-    } else if(size == 0 && level == 0) {
+    } else if(size == (off_t)0 && level == 0) {
        dbprintf(("%s: possible %s problem -- is \"%s\" really empty?\n",
                  debug_prefix(NULL), my_argv[0], disk));
        dbprintf(("%s: .....\n", debug_prefix(NULL)));
     }
     dbprintf(("%s: estimate size for %s level %d: %ld KB\n",
              debug_prefix(NULL),
-             disk,
+             qdisk,
              level,
              size));
 
     kill(-dumppid, SIGTERM);
 
     dbprintf(("%s: waiting for %s \"%s\" child\n",
-             debug_prefix_time(NULL), my_argv[0], disk));
+             debug_prefix_time(NULL), my_argv[0], qdisk));
     wait(NULL);
-    dbprintf(("%s: after %s \"%s\" wait\n",
-             debug_prefix_time(NULL), my_argv[0], disk));
+    dbprintf(("%s: after %s %s wait\n",
+             debug_prefix_time(NULL), my_argv[0], qdisk));
 
 common_exit:
 
@@ -1678,6 +1962,10 @@ common_exit:
     amfree(dirname);
     amfree(inputname);
     amfree(my_argv);
+    amfree(qdisk);
+    amfree(cmd);
+    amfree(file_exclude);
+    amfree(file_include);
 
     aclose(nullfd);
     afclose(dumpout);
@@ -1688,14 +1976,18 @@ common_exit:
 }
 #endif
 
-long getsize_wrapper(program, disk, amdevice, level, options, dumpsince)
-char *program, *disk, *amdevice;
-int level;
-option_t *options;
-time_t dumpsince;
+off_t
+getsize_wrapper(
+    char       *program,
+    char       *disk,
+    char       *amdevice,
+    int                level,
+    option_t * options,
+    time_t     dumpsince)
 {
-    int pipefd[2], nullfd, dumppid;
-    long size;
+    int pipefd[2], nullfd;
+    pid_t dumppid;
+    off_t size = (off_t)-1;
     FILE *dumpout;
     char *line = NULL;
     char *cmd = NULL;
@@ -1704,11 +1996,13 @@ time_t dumpsince;
     int  i, j;
     char *argvchild[10];
     char *newoptstr = NULL;
-    long size1, size2;
+    off_t size1, size2;
     times_t start_time;
+    char *qdisk = quote_string(disk);
+    char *qamdevice = quote_string(amdevice);
 
     gmtm = gmtime(&dumpsince);
-    snprintf(dumptimestr, sizeof(dumptimestr),
+    snprintf(dumptimestr, SIZEOF(dumptimestr),
                "%04d-%02d-%02d %2d:%02d:%02d GMT",
                gmtm->tm_year + 1900, gmtm->tm_mon+1, gmtm->tm_mday,
                gmtm->tm_hour, gmtm->tm_min, gmtm->tm_sec);
@@ -1722,7 +2016,7 @@ time_t dumpsince;
        argvchild[i++] = "full";
     else {
        char levelstr[NUM_STR_SIZE];
-       snprintf(levelstr,sizeof(levelstr),"%d",level);
+       snprintf(levelstr,SIZEOF(levelstr),"%d",level);
        argvchild[i++] = "level";
        argvchild[i++] = levelstr;
     }
@@ -1736,14 +2030,23 @@ time_t dumpsince;
        dbprintf((" %s", argvchild[j]));
     }
     dbprintf(("\n"));
-    nullfd = open("/dev/null", O_RDWR);
-    pipe(pipefd);
+
+    if ((nullfd = open("/dev/null", O_RDWR)) == -1) {
+       dbprintf(("Cannot access /dev/null : %s\n", strerror(errno)));
+       goto common_exit;
+    }
+
+    if (pipe(pipefd) < 0) {
+       dbprintf(("getsize_wrapper could create data pipes: %s\n",
+                 strerror(errno)));
+       goto common_exit;
+    }
 
     start_time = curclock();
 
     switch(dumppid = fork()) {
     case -1:
-      size = -1;
+      size = (off_t)-1;
       goto common_exit;
     default:
       break; /* parent */
@@ -1755,21 +2058,35 @@ time_t dumpsince;
 
       execve(cmd, argvchild, safe_env());
       error("exec %s failed: %s", cmd, strerror(errno));
+      /*NOTREACHED*/
     }
     amfree(newoptstr);
 
     aclose(pipefd[1]);
     dumpout = fdopen(pipefd[0],"r");
+    if (!dumpout) {
+       error("Can't fdopen: %s", strerror(errno));
+       /*NOTREACHED*/
+    }
 
-    for(size = -1; (line = agets(dumpout)) != NULL; free(line)) {
+    for(size = (off_t)-1; (line = agets(dumpout)) != NULL; free(line)) {
+       if (line[0] == '\0')
+           continue;
        dbprintf(("%s: %s\n", debug_prefix_time(NULL), line));
-       i = sscanf(line,"%ld %ld",&size1, &size2);
+       i = sscanf(line, OFF_T_FMT " " OFF_T_FMT,
+               (OFF_T_FMT_TYPE *)&size1, 
+               (OFF_T_FMT_TYPE *)&size2);
        if(i == 2) {
            size = size1 * size2;
        }
        if(size > -1) {
            amfree(line);
-           if((line = agets(dumpout)) != NULL) {
+           while ((line = agets(dumpout)) != NULL) {
+               if (line[0] != '\0')
+                   break;
+               amfree(line);
+           }
+           if(line != NULL) {
                dbprintf(("%s: %s\n", debug_prefix_time(NULL), line));
            }
            break;
@@ -1780,31 +2097,31 @@ time_t dumpsince;
     dbprintf(("%s: .....\n", debug_prefix_time(NULL)));
     dbprintf(("%s: estimate time for %s level %d: %s\n",
              debug_prefix(NULL),
-             amdevice,
+             qamdevice,
              level,
              walltime_str(timessub(curclock(), start_time))));
-    if(size == -1) {
+    if(size == (off_t)-1) {
        dbprintf(("%s: no size line match in %s output for \"%s\"\n",
-                 debug_prefix(NULL), cmd, disk));
+                 debug_prefix(NULL), cmd, qdisk));
        dbprintf(("%s: .....\n", debug_prefix(NULL)));
-    } else if(size == 0 && level == 0) {
+    } else if(size == (off_t)0 && level == 0) {
        dbprintf(("%s: possible %s problem -- is \"%s\" really empty?\n",
-                 debug_prefix(NULL), cmd, disk));
+                 debug_prefix(NULL), cmd, qdisk));
        dbprintf(("%s: .....\n", debug_prefix(NULL)));
     }
-    dbprintf(("%s: estimate size for %s level %d: %ld KB\n",
+    dbprintf(("%s: estimate size for %s level %d: " OFF_T_FMT " KB\n",
              debug_prefix(NULL),
-             amdevice,
+             qamdevice,
              level,
              size));
 
     kill(-dumppid, SIGTERM);
 
     dbprintf(("%s: waiting for %s \"%s\" child\n",
-             debug_prefix_time(NULL), cmd, disk));
+             debug_prefix_time(NULL), cmd, qdisk));
     wait(NULL);
-    dbprintf(("%s: after %s \"%s\" wait\n",
-             debug_prefix_time(NULL), cmd, disk));
+    dbprintf(("%s: after %s %s wait\n",
+             debug_prefix_time(NULL), cmd, qdisk));
 
     aclose(nullfd);
     afclose(dumpout);
@@ -1813,15 +2130,19 @@ common_exit:
 
     amfree(cmd);
     amfree(newoptstr);
+    amfree(qdisk);
+    amfree(qamdevice);
     return size;
 }
 
 
-double first_num(str)
-char *str;
 /*
  * Returns the value of the first integer in a string.
  */
+
+double
+first_num(
+    char *     str)
 {
     char *start;
     int ch;
@@ -1833,27 +2154,32 @@ char *str;
     while(isdigit(ch) || (ch == '.')) ch = *str++;
     str[-1] = '\0';
     d = atof(start);
-    str[-1] = ch;
+    str[-1] = (char)ch;
     return d;
 }
 
 
-long handle_dumpline(str)
-char *str;
 /*
  * Checks the dump output line against the error and size regex tables.
  */
+
+off_t
+handle_dumpline(
+    char *     str)
 {
     regex_t *rp;
     double size;
 
     /* check for size match */
+    /*@ignore@*/
     for(rp = re_size; rp->regex != NULL; rp++) {
        if(match(rp->regex, str)) {
            size = ((first_num(str)*rp->scale+1023.0)/1024.0);
-           if(size < 0) size = 1;              /* found on NeXT -- sigh */
-           return (long) size;
+           if(size < 0.0)
+               size = 1.0;             /* found on NeXT -- sigh */
+           return (off_t)size;
        }
     }
-    return -1;
+    /*@end@*/
+    return (off_t)-1;
 }