Merge tag 'upstream/3.3.3'
[debian/amanda] / client-src / sendbackup-gnutar.c
index d9c5e2001d2b350d3c3f18fbff2fb89a5505c0d3..52ca5d22675c73a1c3b21e6de6e5650b58080d7c 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Amanda, The Advanced Maryland Automatic Network Disk Archiver
  * Copyright (c) 1991-1999 University of Maryland at College Park
+ * Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
  * All Rights Reserved.
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
@@ -35,7 +36,6 @@
 #include "clock.h"
 #include "util.h"
 #include "getfsent.h"                  /* for amname_to_dirname lookup */
-#include "version.h"
 #include "conffile.h"
 
 #ifdef SAMBA_CLIENT
@@ -65,8 +65,7 @@ static amregex_t re_table[] = {
   /* samba may produce these output messages */
   AM_NORMAL_RE("^[Aa]dded interface"),
   AM_NORMAL_RE("^session request to "),
-  AM_NORMAL_RE("^ *tar: dumped [0-9][0-9]* (tar )?files"),
-  AM_NORMAL_RE("^Domain="),
+  AM_NORMAL_RE("^tar: dumped [0-9][0-9]* (tar )?files"),
 
 #if SAMBA_VERSION < 2
   AM_NORMAL_RE("^doing parameter"),
@@ -74,6 +73,7 @@ static amregex_t re_table[] = {
   AM_NORMAL_RE("^adding IPC"),
   AM_NORMAL_RE("^Opening"),
   AM_NORMAL_RE("^Connect"),
+  AM_NORMAL_RE("^Domain="),
   AM_NORMAL_RE("^max"),
   AM_NORMAL_RE("^security="),
   AM_NORMAL_RE("^capabilities"),
@@ -126,91 +126,89 @@ time_t cur_dumptime;
 
 static char *gnutar_list_dir = NULL;
 static char *incrname = NULL;
-static char *amandates_file;
 /*
  *  doing similar to $ gtar | compression | encryption 
  */
 static void
 start_backup(
-    char *     host,
-    char *     disk,
-    char *     amdevice,
-    int                level,
-    char *     dumpdate,
+    dle_t      *dle,
+    char       *host,
     int                dataf,
     int                mesgf,
     int                indexf)
 {
+    char tmppath[PATH_MAX];
     int dumpin, dumpout, compout;
     char *cmd = NULL;
     char *indexcmd = NULL;
     char *dirname = NULL;
     int l;
-    char dumptimestr[80];
+    char dumptimestr[80] = "UNUSED";
     struct tm *gmtm;
-    amandates_t *amdates;
-    time_t prev_dumptime;
+    amandates_t *amdates = NULL;
+    time_t prev_dumptime = 0;
     char *error_pn = NULL;
     char *compopt  = NULL;
     char *encryptopt = skip_argument;
-    char *quoted;
+    char *tquoted;
+    char *fquoted;
     char *qdisk;
     int infd, outfd;
     ssize_t nb;
     char buf[32768];
-
-    (void)dumpdate;    /* Quiet unused parameter warning */
+    char *amandates_file = NULL;
+    am_level_t *alevel = (am_level_t *)dle->levellist->data;
+    int      level  = alevel->level;
 
     error_pn = stralloc2(get_pname(), "-smbclient");
 
-    qdisk = quote_string(disk);
-    dbprintf(("%s: start: %s:%s lev %d\n",
-             get_pname(), host, qdisk, level));
+    qdisk = quote_string(dle->disk);
+    dbprintf(_("start: %s:%s lev %d\n"), host, qdisk, level);
 
-    fprintf(stderr, "%s: start [%s:%s level %d]\n",
+    g_fprintf(stderr, _("%s: start [%s:%s level %d]\n"),
            get_pname(), host, qdisk, level);
 
      /*  apply client-side encryption here */
-     if ( options->encrypt == ENCRYPT_CUST ) {
-         encpid = pipespawn(options->clnt_encrypt, STDIN_PIPE,
+     if ( dle->encrypt == ENCRYPT_CUST ) {
+         encpid = pipespawn(dle->clnt_encrypt, STDIN_PIPE, 0, 
                        &compout, &dataf, &mesgf, 
-                       options->clnt_encrypt, encryptopt, NULL);
-         dbprintf(("%s: pid %ld: %s\n",
-                 debug_prefix_time("-gnutar"), (long)encpid, options->clnt_encrypt));
+                       dle->clnt_encrypt, encryptopt, NULL);
+         dbprintf(_("gnutar: pid %ld: %s\n"), (long)encpid, dle->clnt_encrypt);
     } else {
        compout = dataf;
        encpid = -1;
     } 
      /*  now do the client-side compression */
-    if(options->compress == COMP_FAST || options->compress == COMP_BEST) {
+    if(dle->compress == COMP_FAST || dle->compress == COMP_BEST) {
           compopt = skip_argument;
 #if defined(COMPRESS_BEST_OPT) && defined(COMPRESS_FAST_OPT)
-       if(options->compress == COMP_BEST) {
+       if(dle->compress == COMP_BEST) {
            compopt = COMPRESS_BEST_OPT;
        } else {
            compopt = COMPRESS_FAST_OPT;
        }
 #endif
-       comppid = pipespawn(COMPRESS_PATH, STDIN_PIPE,
+       comppid = pipespawn(COMPRESS_PATH, STDIN_PIPE, 0,
                            &dumpout, &compout, &mesgf,
                            COMPRESS_PATH, compopt, NULL);
-       dbprintf(("%s: pid %ld: %s",
-                 debug_prefix_time("-gnutar"), (long)comppid, COMPRESS_PATH));
+       dbprintf(_("gnutar: pid %ld: %s"), (long)comppid, COMPRESS_PATH);
        if(compopt != skip_argument) {
-           dbprintf((" %s", compopt));
+           dbprintf(_("pid %ld: %s %s\n"),
+                       (long)comppid, COMPRESS_PATH, compopt);
+       } else {
+           dbprintf(_("pid %ld: %s\n"), (long)comppid, COMPRESS_PATH);
        }
-       dbprintf(("\n"));
-     } else if (options->compress == COMP_CUST) {
+     } else if (dle->compress == COMP_CUST) {
         compopt = skip_argument;
-       comppid = pipespawn(options->clntcompprog, STDIN_PIPE,
+       comppid = pipespawn(dle->compprog, STDIN_PIPE, 0,
                            &dumpout, &compout, &mesgf,
-                           options->clntcompprog, compopt, NULL);
-       dbprintf(("%s: pid %ld: %s",
-                 debug_prefix_time("-gnutar-cust"), (long)comppid, options->clntcompprog));
+                           dle->compprog, compopt, NULL);
        if(compopt != skip_argument) {
-           dbprintf((" %s", compopt));
+           dbprintf(_("pid %ld: %s %s\n"),
+                    (long)comppid, dle->compprog, compopt);
+       } else {
+           dbprintf(_("pid %ld: %s\n"), (long)comppid, dle->compprog);
        }
-       dbprintf(("\n"));
     } else {
        dumpout = compout;
        comppid = -1;
@@ -221,34 +219,25 @@ start_backup(
        gnutar_list_dir = NULL;
 
 #ifdef SAMBA_CLIENT                                                    /* { */
-    if (amdevice[0] == '/' && amdevice[1]=='/')
+    if (dle->device[0] == '/' && dle->device[1]=='/')
        amfree(incrname);
     else
 #endif                                                                 /* } */
     if (gnutar_list_dir) {
        char *basename = NULL;
        char number[NUM_STR_SIZE];
-       char *s;
-       int ch;
        char *inputname = NULL;
        int baselevel;
+       char *sdisk = sanitise_filename(dle->disk);
 
        basename = vstralloc(gnutar_list_dir,
                             "/",
                             host,
-                            disk,
+                            sdisk,
                             NULL);
-       /*
-        * The loop starts at the first character of the host name,
-        * not the '/'.
-        */
-       s = basename + strlen(gnutar_list_dir) + 1;
-       while((ch = *s++) != '\0') {
-           if(ch == '/')
-               s[-1] = '_';
-       }
+       amfree(sdisk);
 
-       snprintf(number, SIZEOF(number), "%d", level);
+       g_snprintf(number, SIZEOF(number), "%d", level);
        incrname = vstralloc(basename, "_", number, ".new", NULL);
        unlink(incrname);
 
@@ -261,7 +250,7 @@ start_backup(
        infd = -1;
        while (infd == -1) {
            if (--baselevel >= 0) {
-               snprintf(number, SIZEOF(number), "%d", baselevel);
+               g_snprintf(number, SIZEOF(number), "%d", baselevel);
                inputname = newvstralloc(inputname,
                                         basename, "_", number, NULL);
            } else {
@@ -271,12 +260,11 @@ start_backup(
                int save_errno = errno;
                char *qname = quote_string(inputname);
 
-               dbprintf(("%s: error opening '%s': %s\n",
-                         debug_prefix_time("-gnutar"),
+               dbprintf(_("gnutar: error opening '%s': %s\n"),
                          qname,
-                         strerror(save_errno)));
+                         strerror(save_errno));
                if (baselevel < 0) {
-                   error("error [opening '%s': %s]", qname, strerror(save_errno));
+                   error(_("error [opening '%s': %s]"), qname, strerror(save_errno));
                    /*NOTREACHED*/
                }
                amfree(qname);
@@ -287,79 +275,81 @@ start_backup(
         * Copy the previous listed incremental file to the new one.
         */
        if ((outfd = open(incrname, O_WRONLY|O_CREAT, 0600)) == -1) {
-           error("error [opening '%s': %s]", incrname, strerror(errno));
+           error(_("error [opening '%s': %s]"), incrname, strerror(errno));
            /*NOTREACHED*/
        }
 
        while ((nb = read(infd, &buf, SIZEOF(buf))) > 0) {
-           if (fullwrite(outfd, &buf, (size_t)nb) < nb) {
-               error("error [writing to '%s': %s]", incrname,
+           if (full_write(outfd, &buf, (size_t)nb) < (size_t)nb) {
+               error(_("error [writing to '%s': %s]"), incrname,
                       strerror(errno));
                /*NOTREACHED*/
            }
        }
 
        if (nb < 0) {
-           error("error [reading from '%s': %s]", inputname, strerror(errno));
+           error(_("error [reading from '%s': %s]"), inputname, strerror(errno));
            /*NOTREACHED*/
        }
 
        if (close(infd) != 0) {
-           error("error [closing '%s': %s]", inputname, strerror(errno));
+           error(_("error [closing '%s': %s]"), inputname, strerror(errno));
            /*NOTREACHED*/
        }
        if (close(outfd) != 0) {
-           error("error [closing '%s': %s]", incrname, strerror(errno));
+           error(_("error [closing '%s': %s]"), incrname, strerror(errno));
            /*NOTREACHED*/
        }
 
-       dbprintf(("%s: doing level %d dump as listed-incremental",
-                 debug_prefix_time("-gnutar"), level));
+       tquoted = quote_string(incrname);
        if(baselevel >= 0) {
-           quoted = quote_string(inputname);
-           dbprintf((" from '%s'", quoted));
-           amfree(quoted);
+           fquoted = quote_string(inputname);
+           dbprintf(_("doing level %d dump as listed-incremental from '%s' to '%s'\n"),
+                    level, fquoted, tquoted);
+           amfree(fquoted);
+       } else {
+           dbprintf(_("doing level %d dump as listed-incremental to '%s'\n"),
+                    level, tquoted);
        }
-       quoted = quote_string(incrname);
-       dbprintf((" to '%s'\n", quoted));
-       amfree(quoted);
+       amfree(tquoted);
        amfree(inputname);
        amfree(basename);
-    }
-
-    /* find previous dump time */
+    } else {
+       /* no gnutar-listdir, so we're using amandates */
 
-    amandates_file = getconf_str(CNF_AMANDATES);
-    if(!start_amandates(amandates_file, 0)) {
-       error("error [opening %s: %s]", amandates_file, strerror(errno));
-       /*NOTREACHED*/
-    }
+       /* find previous dump time, failing completely if there's a problem */
+       amandates_file = getconf_str(CNF_AMANDATES);
+       if(!start_amandates(amandates_file, 0)) {
+           error(_("error [opening %s: %s]"), amandates_file, strerror(errno));
+           /*NOTREACHED*/
+       }
 
-    amdates = amandates_lookup(disk);
+       amdates = amandates_lookup(dle->disk);
 
-    prev_dumptime = EPOCH;
-    for(l = 0; l < level; l++) {
-       if(amdates->dates[l] > prev_dumptime)
-           prev_dumptime = amdates->dates[l];
-    }
+       prev_dumptime = EPOCH;
+       for(l = 0; l < level; l++) {
+           if(amdates->dates[l] > prev_dumptime)
+               prev_dumptime = amdates->dates[l];
+       }
 
-    finish_amandates();
-    free_amandates();
+       finish_amandates();
+       free_amandates();
 
-    gmtm = gmtime(&prev_dumptime);
-    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);
+       gmtm = gmtime(&prev_dumptime);
+       g_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);
 
-    dbprintf(("%s: doing level %d dump from date: %s\n",
-             debug_prefix_time("-gnutar"), level, dumptimestr));
+       dbprintf(_("gnutar: doing level %d dump from amandates-derived date: %s\n"),
+                 level, dumptimestr);
+    }
 
-    dirname = amname_to_dirname(amdevice);
+    dirname = amname_to_dirname(dle->device);
 
     cur_dumptime = time(0);
     cur_level = level;
-    cur_disk = stralloc(disk);
+    cur_disk = stralloc(dle->disk);
 #ifdef GNUTAR
 #  define PROGRAM_GNUTAR GNUTAR
 #else
@@ -375,7 +365,7 @@ start_backup(
 
 #ifdef SAMBA_CLIENT                                                    /* { */
     /* Use sambatar if the disk to back up is a PC disk */
-    if (amdevice[0] == '/' && amdevice[1]=='/') {
+    if (dle->device[0] == '/' && dle->device[1]=='/') {
        char *sharename = NULL, *user_and_password = NULL, *domain = NULL;
        char *share = NULL, *subdir = NULL;
        char *pwtext = NULL;
@@ -385,13 +375,13 @@ start_backup(
        size_t pwtext_len;
        char *pw_fd_env;
 
-       parsesharename(amdevice, &share, &subdir);
+       parsesharename(dle->device, &share, &subdir);
        if (!share) {
            amfree(share);
            amfree(subdir);
            set_pname(error_pn);
            amfree(error_pn);
-           error("cannot parse disk entry %s for share/subdir", qdisk);
+           error(_("cannot parse disk entry %s for share/subdir"), qdisk);
            /*NOTREACHED*/
        }
        if ((subdir) && (SAMBA_VERSION < 2)) {
@@ -399,7 +389,7 @@ start_backup(
            amfree(subdir);
            set_pname(error_pn);
            amfree(error_pn);
-           error("subdirectory specified for share %s but samba not v2 or better", qdisk);
+           error(_("subdirectory specified for share %s but samba not v2 or better"), qdisk);
            /*NOTREACHED*/
        }
        if ((user_and_password = findpass(share, &domain)) == NULL) {
@@ -409,7 +399,7 @@ start_backup(
            }
            set_pname(error_pn);
            amfree(error_pn);
-           error("error [invalid samba host or password not found?]");
+           error(_("error [invalid samba host or password not found?]"));
            /*NOTREACHED*/
        }
        lpass = strlen(user_and_password);
@@ -422,7 +412,7 @@ start_backup(
            }
            set_pname(error_pn);
            amfree(error_pn);
-           error("password field not \'user%%pass\' for %s", qdisk);
+           error(_("password field not \'user%%pass\' for %s"), qdisk);
            /*NOTREACHED*/
        }
        *pwtext++ = '\0';
@@ -436,12 +426,12 @@ start_backup(
            }
            set_pname(error_pn);
            amfree(error_pn);
-           error("error [can't make share name of %s]", share);
+           error(_("error [can't make share name of %s]"), share);
            /*NOTREACHED*/
        }
 
        taropt = stralloc("-T");
-       if(options->exclude_file && options->exclude_file->nb_element == 1) {
+       if(dle->exclude_file && dle->exclude_file->nb_element == 1) {
            strappend(taropt, "X");
        }
 #if SAMBA_VERSION >= 2
@@ -450,28 +440,28 @@ start_backup(
        strappend(taropt, "c");
        if (level != 0) {
            strappend(taropt, "g");
-       } else if (!options->no_record) {
+       } else if (dle->record) {
            strappend(taropt, "a");
        }
 
-       dbprintf(("%s: backup of %s", debug_prefix_time("-gnutar"), sharename));
        if (subdir) {
-           dbprintf(("/%s",subdir));
+           dbprintf(_("gnutar: backup of %s/%s\n"), sharename, subdir);
+       } else {
+           dbprintf(_("gnutar: backup of %s\n"), sharename);
        }
-       dbprintf(("\n"));
 
        program->backup_name = program->restore_name = SAMBA_CLIENT;
        cmd = stralloc(program->backup_name);
-       info_tapeheader();
+       info_tapeheader(dle);
 
-       start_index(options->createindex, dumpout, mesgf, indexf, indexcmd);
+       start_index(dle->create_index, dumpout, mesgf, indexf, indexcmd);
 
        if (pwtext_len > 0) {
            pw_fd_env = "PASSWD_FD";
        } else {
            pw_fd_env = "dummy_PASSWD_FD";
        }
-       dumppid = pipespawn(cmd, STDIN_PIPE|PASSWD_PIPE,
+       dumppid = pipespawn(cmd, STDIN_PIPE|PASSWD_PIPE, 0,
                            &dumpin, &dumpout, &mesgf,
                            pw_fd_env, &passwdf,
                            "smbclient",
@@ -488,13 +478,13 @@ start_backup(
                            "-d0",
                            taropt,
                            "-",
-                           options->exclude_file && options->exclude_file->nb_element == 1 ? options->exclude_file->first->name : skip_argument,
+                           dle->exclude_file && dle->exclude_file->nb_element == 1 ? dle->exclude_file->first->name : skip_argument,
                            NULL);
        if(domain) {
            memset(domain, '\0', strlen(domain));
            amfree(domain);
        }
-       if(pwtext_len > 0 && fullwrite(passwdf, pwtext, pwtext_len) < 0) {
+       if(pwtext_len > 0 && full_write(passwdf, pwtext, pwtext_len) < pwtext_len) {
            int save_errno = errno;
 
            aclose(passwdf);
@@ -502,7 +492,7 @@ start_backup(
            amfree(user_and_password);
            set_pname(error_pn);
            amfree(error_pn);
-           error("error [password write failed: %s]", strerror(save_errno));
+           error(_("error [password write failed: %s]"), strerror(save_errno));
            /*NOTREACHED*/
        }
        memset(user_and_password, '\0', lpass);
@@ -519,45 +509,47 @@ start_backup(
 
        int nb_exclude = 0;
        int nb_include = 0;
-       char **my_argv;
-       int i = 0;
+       GPtrArray *argv_ptr = g_ptr_array_new();
        char *file_exclude = NULL;
        char *file_include = NULL;
 
-       if(options->exclude_file) nb_exclude+=options->exclude_file->nb_element;
-       if(options->exclude_list) nb_exclude+=options->exclude_list->nb_element;
-       if(options->include_file) nb_include+=options->include_file->nb_element;
-       if(options->include_list) nb_include+=options->include_list->nb_element;
+       if (dle->exclude_file) nb_exclude+=dle->exclude_file->nb_element;
+       if (dle->exclude_list) nb_exclude+=dle->exclude_list->nb_element;
+       if (dle->include_file) nb_include+=dle->include_file->nb_element;
+       if (dle->include_list) nb_include+=dle->include_list->nb_element;
 
-       if(nb_exclude > 0) file_exclude = build_exclude(disk, amdevice, options, 0);
-       if(nb_include > 0) file_include = build_include(disk, amdevice, options, 0);
+       if (nb_exclude > 0) file_exclude = build_exclude(dle, 0);
+       if (nb_include > 0) file_include = build_include(dle, 0);
 
-       my_argv = alloc(SIZEOF(char *) * (22 + (nb_exclude*2)+(nb_include*2)));
+       cmd = vstralloc(amlibexecdir, "/", "runtar", NULL);
+       info_tapeheader(dle);
 
-       cmd = vstralloc(libexecdir, "/", "runtar", versionsuffix(), NULL);
-       info_tapeheader();
+       start_index(dle->create_index, dumpout, mesgf, indexf, indexcmd);
 
-       start_index(options->createindex, dumpout, mesgf, indexf, indexcmd);
-
-        my_argv[i++] = "runtar";
+       g_ptr_array_add(argv_ptr, stralloc("runtar"));
        if (g_options->config)
-           my_argv[i++] = g_options->config;
+           g_ptr_array_add(argv_ptr, stralloc(g_options->config));
        else
-           my_argv[i++] = "NOCONFIG";
-       my_argv[i++] = "gtar";
-       my_argv[i++] = "--create";
-       my_argv[i++] = "--file";
-       my_argv[i++] = "-";
-       my_argv[i++] = "--directory";
-       my_argv[i++] = dirname;
-       my_argv[i++] = "--one-file-system";
+           g_ptr_array_add(argv_ptr, stralloc("NOCONFIG"));
+#ifdef GNUTAR
+       g_ptr_array_add(argv_ptr, stralloc(GNUTAR));
+#else
+       g_ptr_array_add(argv_ptr, stralloc("tar"));
+#endif
+       g_ptr_array_add(argv_ptr, stralloc("--create"));
+       g_ptr_array_add(argv_ptr, stralloc("--file"));
+       g_ptr_array_add(argv_ptr, stralloc("-"));
+       g_ptr_array_add(argv_ptr, stralloc("--directory"));
+       canonicalize_pathname(dirname, tmppath);
+       g_ptr_array_add(argv_ptr, stralloc(tmppath));
+       g_ptr_array_add(argv_ptr, stralloc("--one-file-system"));
        if (gnutar_list_dir && incrname) {
-           my_argv[i++] = "--listed-incremental";
-           my_argv[i++] = incrname;
+           g_ptr_array_add(argv_ptr, stralloc("--listed-incremental"));
+           g_ptr_array_add(argv_ptr, stralloc(incrname));
        } else {
-           my_argv[i++] = "--incremental";
-           my_argv[i++] = "--newer";
-           my_argv[i++] = dumptimestr;
+           g_ptr_array_add(argv_ptr, stralloc("--incremental"));
+           g_ptr_array_add(argv_ptr, stralloc("--newer"));
+           g_ptr_array_add(argv_ptr, stralloc(dumptimestr));
        }
 #ifdef ENABLE_GNUTAR_ATIME_PRESERVE
        /* --atime-preserve causes gnutar to call
@@ -565,36 +557,34 @@ start_backup(
         * adjust their atime.  However, utime()
         * updates the file's ctime, so incremental
         * dumps will think the file has changed. */
-       my_argv[i++] = "--atime-preserve";
+       g_ptr_array_add(argv_ptr, stralloc("--atime-preserve"));
 #endif
-       my_argv[i++] = "--sparse";
-       my_argv[i++] = "--ignore-failed-read";
-       my_argv[i++] = "--totals";
+       g_ptr_array_add(argv_ptr, stralloc("--sparse"));
+       g_ptr_array_add(argv_ptr, stralloc("--ignore-failed-read"));
+       g_ptr_array_add(argv_ptr, stralloc("--totals"));
 
        if(file_exclude) {
-           my_argv[i++] = "--exclude-from";
-           my_argv[i++] = file_exclude;
+           g_ptr_array_add(argv_ptr, stralloc("--exclude-from"));
+           g_ptr_array_add(argv_ptr, stralloc(file_exclude));
        }
 
        if(file_include) {
-           my_argv[i++] = "--files-from";
-           my_argv[i++] = file_include;
+           g_ptr_array_add(argv_ptr, stralloc("--files-from"));
+           g_ptr_array_add(argv_ptr, stralloc(file_include));
        }
        else {
-           my_argv[i++] = ".";
+           g_ptr_array_add(argv_ptr, stralloc("."));
        }
-       my_argv[i++] = NULL;
-       dumppid = pipespawnv(cmd, STDIN_PIPE,
-                            &dumpin, &dumpout, &mesgf, my_argv);
+           g_ptr_array_add(argv_ptr, NULL);
+       dumppid = pipespawnv(cmd, STDIN_PIPE, 0,
+                            &dumpin, &dumpout, &mesgf,
+                            (char **)argv_ptr->pdata);
        tarpid = dumppid;
        amfree(file_exclude);
        amfree(file_include);
-       amfree(my_argv);
+       g_ptr_array_free_full(argv_ptr);
     }
-    dbprintf(("%s: %s: pid %ld\n",
-             debug_prefix_time("-gnutar"),
-             cmd,
-             (long)dumppid));
+    dbprintf(_("gnutar: %s: pid %ld\n"), cmd, (long)dumppid);
 
     amfree(qdisk);
     amfree(dirname);
@@ -609,36 +599,47 @@ start_backup(
     aclose(compout);
     aclose(dataf);
     aclose(mesgf);
-    if (options->createindex)
+    if (dle->create_index)
        aclose(indexf);
 }
 
 static void
 end_backup(
+    dle_t      *dle,
     int                goterror)
 {
-    if(!options->no_record && !goterror) {
+    char *amandates_file = NULL;
+
+    if(dle->record && !goterror) {
        if (incrname != NULL && strlen(incrname) > 4) {
            char *nodotnew;
        
            nodotnew = stralloc(incrname);
            nodotnew[strlen(nodotnew)-4] = '\0';
            if (rename(incrname, nodotnew)) {
-               fprintf(stderr, "%s: warning [renaming %s to %s: %s]\n"
+               g_fprintf(stderr, _("%s: warning [renaming %s to %s: %s]\n")
                        get_pname(), incrname, nodotnew, strerror(errno));
            }
            amfree(nodotnew);
            amfree(incrname);
        }
 
-        if(!start_amandates(amandates_file, 1)) {
-           fprintf(stderr, "%s: warning [opening %s: %s]", get_pname(),
-                   amandates_file, strerror(errno));
-       }
-       else {
+       /* update the amandates file */
+       amandates_file = getconf_str(CNF_AMANDATES);
+       if(start_amandates(amandates_file, 1)) {
            amandates_updateone(cur_disk, cur_level, cur_dumptime);
            finish_amandates();
            free_amandates();
+       } else {
+           /* failure is only fatal if we didn't get a gnutar-listdir */
+           char *gnutar_list_dir = getconf_str(CNF_GNUTAR_LIST_DIR);
+           if (!gnutar_list_dir || !*gnutar_list_dir) {
+               error(_("error [opening %s for writing: %s]"), amandates_file, strerror(errno));
+               /* NOTREACHED */
+           } else {
+               g_debug(_("non-fatal error opening '%s' for writing: %s]"),
+                       amandates_file, strerror(errno));
+           }
        }
     }
 }