Merge tag 'upstream/3.3.2'
[debian/amanda] / application-src / amgtar.c
index 7cf28a1ffce292a70c68b0bd3a31d4f1036eb130..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}
 };
 
@@ -370,6 +373,7 @@ 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;
 
@@ -501,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;
@@ -1118,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) {
@@ -1451,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,
@@ -1465,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);