Imported Upstream version 3.3.2
[debian/amanda] / application-src / amgtar.c
index 95869693fdc48a0c6c728425a95f1e26d5ae55b7..47103ad45a466f0f248ce5ce47944e0c518b851b 100644 (file)
@@ -122,6 +122,7 @@ typedef struct application_argument_s {
     int        argc;
     char     **argv;
     int        verbose;
+    int        ignore_zeros;
 } application_argument_t;
 
 enum { CMD_ESTIMATE, CMD_BACKUP };
@@ -137,6 +138,7 @@ static void amgtar_build_exinclude(dle_t *dle, int verbose,
                                   int *nb_include, char **file_include);
 static char *amgtar_get_incrname(application_argument_t *argument, int level,
                                 FILE *mesgstream, int command);
+static void check_no_check_device(void);
 static GPtrArray *amgtar_build_argv(application_argument_t *argument,
                                char *incrname, char **file_exclude,
                                char **file_include, int command);
@@ -194,6 +196,7 @@ static struct option long_options[] = {
     {"include-list-glob", 1, NULL, 34},
     {"exclude-list-glob", 1, NULL, 35},
     {"verbose"          , 1, NULL, 36},
+    {"ignore-zeros"     , 1, NULL, 37},
     {NULL, 0, NULL, 0}
 };
 
@@ -296,6 +299,7 @@ main(
 #else
     gnutar_path = NULL;
 #endif
+    gnutar_listdir = NULL;
     gnutar_directory = NULL;
     gnutar_onefilesystem = 1;
     gnutar_atimepreserve = 1;
@@ -357,6 +361,7 @@ main(
     /* parse argument */
     command = argv[1];
 
+    gnutar_listdir = stralloc(getconf_str(CNF_GNUTAR_LIST_DIR));
     argument.config     = NULL;
     argument.host       = NULL;
     argument.message    = 0;
@@ -368,7 +373,9 @@ main(
     argument.include_list_glob = NULL;
     argument.exclude_list_glob = NULL;
     argument.verbose = 0;
+    argument.ignore_zeros = 1;
     init_dle(&argument.dle);
+    argument.dle.record = 0;
 
     while (1) {
        int option_index = 0;
@@ -498,6 +505,9 @@ main(
        case 36: if (optarg  && strcasecmp(optarg, "YES") == 0)
                     argument.verbose = 1;
                 break;
+       case 37: if (strcasecmp(optarg, "YES") != 0)
+                    argument.ignore_zeros = 0;
+                break;
        case ':':
        case '?':
                break;
@@ -546,7 +556,6 @@ main(
        }
     }
 
-    gnutar_listdir = getconf_str(CNF_GNUTAR_LIST_DIR);
     if (strlen(gnutar_listdir) == 0)
        gnutar_listdir = NULL;
 
@@ -636,11 +645,37 @@ static void
 amgtar_selfcheck(
     application_argument_t *argument)
 {
+    if (argument->dle.disk) {
+       char *qdisk = quote_string(argument->dle.disk);
+       fprintf(stdout, "OK disk %s\n", qdisk);
+       amfree(qdisk);
+    }
+
+    printf("OK amgtar version %s\n", VERSION);
     amgtar_build_exinclude(&argument->dle, 1, NULL, NULL, NULL, NULL);
 
     printf("OK amgtar\n");
     if (gnutar_path) {
-       check_file(gnutar_path, X_OK);
+       if (check_file(gnutar_path, X_OK)) {
+           char *gtar_version;
+           GPtrArray *argv_ptr = g_ptr_array_new();
+
+           g_ptr_array_add(argv_ptr, gnutar_path);
+           g_ptr_array_add(argv_ptr, "--version");
+           g_ptr_array_add(argv_ptr, NULL);
+
+           gtar_version = get_first_line(argv_ptr);
+           if (gtar_version) {
+               char *gv;
+               for (gv = gtar_version; *gv && !g_ascii_isdigit(*gv); gv++);
+               printf("OK amgtar gtar-version %s\n", gv);
+           } else {
+               printf(_("ERROR [Can't get %s version]\n"), gnutar_path);
+           }
+
+           g_ptr_array_free(argv_ptr, TRUE);
+           amfree(gtar_version);
+       }
     } else {
        printf(_("ERROR [GNUTAR program not available]\n"));
     }
@@ -654,11 +689,6 @@ amgtar_selfcheck(
        printf(_("ERROR [No GNUTAR-LISTDIR]\n"));
     }
 
-    if (argument->dle.disk) {
-       char *qdisk = quote_string(argument->dle.disk);
-       fprintf(stdout, "OK %s\n", qdisk);
-       amfree(qdisk);
-    }
     if (gnutar_directory) {
        check_dir(gnutar_directory, R_OK);
     } else if (argument->dle.device) {
@@ -720,7 +750,7 @@ amgtar_estimate(
        if (gnutar_directory) {
            dirname = gnutar_directory;
        } else {
-           dirname = amname_to_dirname(argument->dle.device);
+           dirname = argument->dle.device;
        }
        amgtar_build_exinclude(&argument->dle, 1,
                               &nb_exclude, &file_exclude,
@@ -968,7 +998,7 @@ amgtar_backup(
                }
            }
            if(rp->typ == DMP_SIZE) {
-               dump_size = (long)((the_num(line, rp->field)* rp->scale+1023.0)/1024.0);
+               dump_size = (off_t)((the_num(line, rp->field)* rp->scale+1023.0)/1024.0);
            }
            switch(rp->typ) {
            case DMP_NORMAL:
@@ -1022,16 +1052,25 @@ amgtar_backup(
     }
 
     if (!errmsg && incrname && strlen(incrname) > 4) {
-       char *nodotnew;
-       nodotnew = stralloc(incrname);
-       nodotnew[strlen(nodotnew)-4] = '\0';
-       if (rename(incrname, nodotnew)) {
-           dbprintf(_("%s: warning [renaming %s to %s: %s]\n"),
-                    get_pname(), incrname, nodotnew, strerror(errno));
-           g_fprintf(mesgstream, _("? warning [renaming %s to %s: %s]\n"),
-                     incrname, nodotnew, strerror(errno));
+       if (argument->dle.record) {
+           char *nodotnew;
+           nodotnew = stralloc(incrname);
+           nodotnew[strlen(nodotnew)-4] = '\0';
+           if (rename(incrname, nodotnew)) {
+               dbprintf(_("%s: warning [renaming %s to %s: %s]\n"),
+                        get_pname(), incrname, nodotnew, strerror(errno));
+               g_fprintf(mesgstream, _("? warning [renaming %s to %s: %s]\n"),
+                         incrname, nodotnew, strerror(errno));
+           }
+           amfree(nodotnew);
+       } else {
+           if (unlink(incrname) == -1) {
+               dbprintf(_("%s: warning [unlink %s: %s]\n"),
+                        get_pname(), incrname, strerror(errno));
+               g_fprintf(mesgstream, _("? warning [unlink %s: %s]\n"),
+                         incrname, strerror(errno));
+           }
        }
-       amfree(nodotnew);
     }
 
     dbprintf("sendbackup: size %lld\n", (long long)dump_size);
@@ -1086,7 +1125,13 @@ amgtar_restore(
     if (gnutar_xattrs)
        g_ptr_array_add(argv_ptr, stralloc("--xattrs"));
     /* ignore trailing zero blocks on input (this was the default until tar-1.21) */
-    g_ptr_array_add(argv_ptr, stralloc("--ignore-zeros"));
+    if (argument->ignore_zeros) {
+       g_ptr_array_add(argv_ptr, stralloc("--ignore-zeros"));
+    }
+    if (argument->tar_blocksize) {
+       g_ptr_array_add(argv_ptr, stralloc("--blocking-factor"));
+       g_ptr_array_add(argv_ptr, stralloc(argument->tar_blocksize));
+    }
     g_ptr_array_add(argv_ptr, stralloc("-xpGvf"));
     g_ptr_array_add(argv_ptr, stralloc("-"));
     if (gnutar_directory) {
@@ -1419,6 +1464,41 @@ amgtar_get_incrname(
     return incrname;
 }
 
+static void
+check_no_check_device(void)
+{
+    if (gnutar_checkdevice == 0) {
+       GPtrArray *argv_ptr = g_ptr_array_new();
+       int dumpin;
+       int dataf;
+       int outf;
+       int size;
+       char buf[32768];
+
+       g_ptr_array_add(argv_ptr, gnutar_path);
+       g_ptr_array_add(argv_ptr, "-x");
+       g_ptr_array_add(argv_ptr, "--no-check-device");
+       g_ptr_array_add(argv_ptr, "-f");
+       g_ptr_array_add(argv_ptr, "-");
+       g_ptr_array_add(argv_ptr, NULL);
+
+       pipespawnv(gnutar_path, STDIN_PIPE|STDOUT_PIPE|STDERR_PIPE, 0,
+                            &dumpin, &dataf, &outf, (char **)argv_ptr->pdata);
+       aclose(dumpin);
+       aclose(dataf);
+       size = read(outf, buf, 32767);
+       if (size > 0) {
+           buf[size] = '\0';
+           if (strstr(buf, "--no-check-device")) {
+               g_debug("disabling --no-check-device since '%s' doesn't support it", gnutar_path);
+               gnutar_checkdevice = 1;
+           }
+       }
+       aclose(outf);
+       g_ptr_array_free(argv_ptr, TRUE);
+    }
+}
+
 GPtrArray *amgtar_build_argv(
     application_argument_t *argument,
     char  *incrname,
@@ -1433,6 +1513,7 @@ GPtrArray *amgtar_build_argv(
     GPtrArray *argv_ptr = g_ptr_array_new();
     GSList    *copt;
 
+    check_no_check_device();
     amgtar_build_exinclude(&argument->dle, 1,
                           &nb_exclude, file_exclude,
                           &nb_include, file_include);
@@ -1440,7 +1521,7 @@ GPtrArray *amgtar_build_argv(
     if (gnutar_directory) {
        dirname = gnutar_directory;
     } else {
-       dirname = amname_to_dirname(argument->dle.device);
+       dirname = argument->dle.device;
     }
 
     g_ptr_array_add(argv_ptr, stralloc(gnutar_path));