X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=application-src%2Famgtar.c;h=285b05c3fb14c40fcf418cd4bddf22abe8893a78;hb=d28952249e392eb31bc8eecc53f6c477f30c617b;hp=947a986ed25e28eb2d4a69c103e5ccbac5edbeb9;hpb=fd48f3e498442f0cbff5f3606c7c403d0566150e;p=debian%2Famanda diff --git a/application-src/amgtar.c b/application-src/amgtar.c index 947a986..285b05c 100644 --- a/application-src/amgtar.c +++ b/application-src/amgtar.c @@ -1,6 +1,7 @@ /* * Amanda, The Advanced Maryland Automatic Network Disk Archiver * Copyright (c) 1991-1998 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 @@ -57,6 +58,7 @@ * EXIT-HANDLING (1=GOOD 2=BAD) * TAR-BLOCKSIZE (default does not add --blocking-factor option, * using tar's default) + * VERBOSE */ #include "amanda.h" @@ -120,6 +122,8 @@ typedef struct application_argument_s { dle_t dle; int argc; char **argv; + int verbose; + int ignore_zeros; } application_argument_t; enum { CMD_ESTIMATE, CMD_BACKUP }; @@ -135,8 +139,10 @@ 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, int command); + char *incrname, char **file_exclude, + char **file_include, int command); static char *gnutar_path; static char *gnutar_listdir; static char *gnutar_directory; @@ -190,6 +196,8 @@ static struct option long_options[] = { {"command-options" , 1, NULL, 33}, {"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} }; @@ -292,6 +300,7 @@ main( #else gnutar_path = NULL; #endif + gnutar_listdir = NULL; gnutar_directory = NULL; gnutar_onefilesystem = 1; gnutar_atimepreserve = 1; @@ -363,7 +372,10 @@ main( argument.command_options = NULL; 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; @@ -490,6 +502,12 @@ main( case 35: if (optarg) argument.exclude_list_glob = stralloc(optarg); break; + 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; @@ -514,6 +532,10 @@ main( g_critical(_("errors processing config file")); } + if (!gnutar_listdir) { + gnutar_listdir = g_strdup(getconf_str(CNF_GNUTAR_LIST_DIR)); + } + re_table = build_re_table(init_re_table, normal_message, ignore_message, strange_message); @@ -538,7 +560,6 @@ main( } } - gnutar_listdir = getconf_str(CNF_GNUTAR_LIST_DIR); if (strlen(gnutar_listdir) == 0) gnutar_listdir = NULL; @@ -628,11 +649,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")); } @@ -646,11 +693,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) { @@ -686,6 +728,8 @@ amgtar_estimate( times_t start_time; int level; GSList *levels; + char *file_exclude; + char *file_include; if (!argument->level) { fprintf(stderr, "ERROR No level argument\n"); @@ -704,15 +748,13 @@ amgtar_estimate( if (argument->calcsize) { char *dirname; - char *file_exclude; - char *file_include; int nb_exclude; int nb_include; 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, @@ -720,6 +762,13 @@ amgtar_estimate( run_calcsize(argument->config, "GNUTAR", argument->dle.disk, dirname, argument->level, file_exclude, file_include); + + if (argument->verbose == 0) { + if (file_exclude) + unlink(file_exclude); + if (file_include) + unlink(file_include); + } return; } @@ -737,7 +786,8 @@ amgtar_estimate( level = GPOINTER_TO_INT(levels->data); incrname = amgtar_get_incrname(argument, level, stdout, CMD_ESTIMATE); cmd = stralloc(gnutar_path); - argv_ptr = amgtar_build_argv(argument, incrname, CMD_ESTIMATE); + argv_ptr = amgtar_build_argv(argument, incrname, &file_exclude, + &file_include, CMD_ESTIMATE); start_time = curclock(); @@ -831,6 +881,14 @@ common_exit: if (incrname) { unlink(incrname); } + + if (argument->verbose == 0) { + if (file_exclude) + unlink(file_exclude); + if (file_include) + unlink(file_include); + } + g_ptr_array_free_full(argv_ptr); amfree(cmd); @@ -876,6 +934,8 @@ amgtar_backup( amwait_t wait_status; GPtrArray *argv_ptr; int tarpid; + char *file_exclude; + char *file_include; mesgstream = fdopen(mesgf, "w"); if (!mesgstream) { @@ -908,7 +968,8 @@ amgtar_backup( GPOINTER_TO_INT(argument->level->data), mesgstream, CMD_BACKUP); cmd = stralloc(gnutar_path); - argv_ptr = amgtar_build_argv(argument, incrname, CMD_BACKUP); + argv_ptr = amgtar_build_argv(argument, incrname, &file_exclude, + &file_include, CMD_BACKUP); tarpid = pipespawnv(cmd, STDIN_PIPE|STDERR_PIPE, 1, &dumpin, &dataf, &outf, (char **)argv_ptr->pdata); @@ -941,7 +1002,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: @@ -995,16 +1056,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); @@ -1017,6 +1087,13 @@ amgtar_backup( fclose(mesgstream); + if (argument->verbose == 0) { + if (file_exclude) + unlink(file_exclude); + if (file_include) + unlink(file_include); + } + amfree(incrname); amfree(qdisk); amfree(cmd); @@ -1032,6 +1109,9 @@ amgtar_restore( char **env; int j; char *e; + char *include_filename = NULL; + char *exclude_filename = NULL; + int tarpid; if (!gnutar_path) { error(_("GNUTAR-PATH not defined")); @@ -1048,6 +1128,14 @@ amgtar_restore( g_ptr_array_add(argv_ptr, stralloc("--selinux")); 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) */ + 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) { @@ -1073,7 +1161,6 @@ amgtar_restore( argument->dle.exclude_list->nb_element == 1) { FILE *exclude; char *sdisk; - char *filename; int in_argv; int entry_in_exclude = 0; char line[2*PATH_MAX]; @@ -1082,12 +1169,12 @@ amgtar_restore( if (argument->dle.disk) { sdisk = sanitise_filename(argument->dle.disk); } else { - sdisk = g_strdup_printf("installcheck-exclude-%d", getpid()); + sdisk = g_strdup_printf("no_dle-%d", getpid()); } - filename = vstralloc(AMANDA_TMPDIR, "/", "exclude-", sdisk, NULL); + exclude_filename= vstralloc(AMANDA_TMPDIR, "/", "exclude-", sdisk, NULL); exclude_list = fopen(argument->dle.exclude_list->first->name, "r"); - exclude = fopen(filename, "w"); + exclude = fopen(exclude_filename, "w"); while (fgets(line, 2*PATH_MAX, exclude_list)) { char *escaped; line[strlen(line)-1] = '\0'; /* remove '\n' */ @@ -1103,7 +1190,7 @@ amgtar_restore( } fclose(exclude); g_ptr_array_add(argv_ptr, stralloc("--exclude-from")); - g_ptr_array_add(argv_ptr, filename); + g_ptr_array_add(argv_ptr, exclude_filename); } if (argument->exclude_list_glob) { @@ -1115,7 +1202,6 @@ amgtar_restore( GPtrArray *argv_include = g_ptr_array_new(); FILE *include; char *sdisk; - char *filename; int in_argv; guint i; int entry_in_include = 0; @@ -1123,10 +1209,10 @@ amgtar_restore( if (argument->dle.disk) { sdisk = sanitise_filename(argument->dle.disk); } else { - sdisk = g_strdup_printf("installcheck-include-%d", getpid()); + sdisk = g_strdup_printf("no_dle-%d", getpid()); } - filename = vstralloc(AMANDA_TMPDIR, "/", "include-", sdisk, NULL); - include = fopen(filename, "w"); + include_filename = vstralloc(AMANDA_TMPDIR, "/", "include-", sdisk, NULL); + include = fopen(include_filename, "w"); if (argument->dle.include_list && argument->dle.include_list->nb_element == 1) { char line[2*PATH_MAX]; @@ -1159,7 +1245,7 @@ amgtar_restore( if (entry_in_include) { g_ptr_array_add(argv_ptr, stralloc("--files-from")); - g_ptr_array_add(argv_ptr, filename); + g_ptr_array_add(argv_ptr, include_filename); } if (argument->include_list_glob) { @@ -1174,11 +1260,27 @@ amgtar_restore( g_ptr_array_add(argv_ptr, NULL); debug_executing(argv_ptr); - env = safe_env(); - become_root(); - execve(cmd, (char **)argv_ptr->pdata, env); - e = strerror(errno); - error(_("error [exec %s: %s]"), cmd, e); + + tarpid = fork(); + switch (tarpid) { + case -1: error(_("%s: fork returned: %s"), get_pname(), strerror(errno)); + case 0: + env = safe_env(); + become_root(); + execve(cmd, (char **)argv_ptr->pdata, env); + e = strerror(errno); + error(_("error [exec %s: %s]"), cmd, e); + break; + default: break; + } + + waitpid(tarpid, NULL, 0); + if (argument->verbose == 0) { + if (exclude_filename) + unlink(exclude_filename); + if (include_filename) + unlink(include_filename); + } } static void @@ -1199,6 +1301,8 @@ amgtar_validate( cmd = stralloc(gnutar_path); g_ptr_array_add(argv_ptr, stralloc(gnutar_path)); + /* ignore trailing zero blocks on input (this was the default until tar-1.21) */ + g_ptr_array_add(argv_ptr, stralloc("--ignore-zeros")); g_ptr_array_add(argv_ptr, stralloc("-tf")); g_ptr_array_add(argv_ptr, stralloc("-")); g_ptr_array_add(argv_ptr, NULL); @@ -1364,28 +1468,64 @@ 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, - int command) + char *incrname, + char **file_exclude, + char **file_include, + int command) { int nb_exclude; int nb_include; - char *file_exclude; - char *file_include; char *dirname; char tmppath[PATH_MAX]; 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); + &nb_exclude, file_exclude, + &nb_include, file_include); 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)); @@ -1431,14 +1571,14 @@ GPtrArray *amgtar_build_argv( g_ptr_array_add(argv_ptr, stralloc((char *)copt->data)); } - if(file_exclude) { + if (*file_exclude) { g_ptr_array_add(argv_ptr, stralloc("--exclude-from")); - g_ptr_array_add(argv_ptr, stralloc(file_exclude)); + g_ptr_array_add(argv_ptr, stralloc(*file_exclude)); } - if(file_include) { + if (*file_include) { g_ptr_array_add(argv_ptr, stralloc("--files-from")); - g_ptr_array_add(argv_ptr, stralloc(file_include)); + g_ptr_array_add(argv_ptr, stralloc(*file_include)); } else { g_ptr_array_add(argv_ptr, stralloc("."));