X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=application-src%2Famstar.c;h=c20832140dfc29e0fe60eeb79788af498e0e418c;hb=refs%2Fheads%2Fmaster;hp=2f8b17c26f9f80c23c25fbdeb9398dbd610f4bb1;hpb=fd48f3e498442f0cbff5f3606c7c403d0566150e;p=debian%2Famanda diff --git a/application-src/amstar.c b/application-src/amstar.c index 2f8b17c..c208321 100644 --- a/application-src/amstar.c +++ b/application-src/amstar.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 @@ -40,7 +41,8 @@ * IGNORE * STRANGE * INCLUDE-LIST (for restore only) - * EXCLUDE-LIST (for restore only) + * EXCLUDE-FILE + * EXCLUDE-LIST * DIRECTORY */ @@ -124,12 +126,14 @@ static void amstar_validate(application_argument_t *argument); static GPtrArray *amstar_build_argv(application_argument_t *argument, int level, int command); +static int check_device(application_argument_t *argument); static char *star_path; static char *star_tardumps; static int star_dle_tardumps; static int star_onefilesystem; static int star_sparse; +static int star_acl; static char *star_directory; static GSList *normal_message = NULL; static GSList *ignore_message = NULL; @@ -158,6 +162,8 @@ static struct option long_options[] = { {"exclude-list" , 1, NULL, 20}, {"directory" , 1, NULL, 21}, {"command-options" , 1, NULL, 22}, + {"exclude-file" , 1, NULL, 23}, + {"acl" , 1, NULL, 24}, { NULL, 0, NULL, 0} }; @@ -180,6 +186,7 @@ main( star_dle_tardumps = 0; star_onefilesystem = 1; star_sparse = 1; + star_acl = 1; star_directory = NULL; /* initialize */ @@ -240,6 +247,7 @@ main( argument.level = NULL; argument.command_options = NULL; init_dle(&argument.dle); + argument.dle.record = 0; opterr = 0; while (1) { @@ -319,6 +327,18 @@ main( case 22: argument.command_options = g_slist_append(argument.command_options, stralloc(optarg)); + break; + case 23: if (optarg) + argument.dle.exclude_file = + append_sl(argument.dle.exclude_file, optarg); + break; + case 24: if (optarg && strcasecmp(optarg, "NO") == 0) + star_acl = 0; + else if (optarg && strcasecmp(optarg, "YES") == 0) + star_acl = 1; + else if (strcasecmp(command, "selfcheck") == 0) + printf(_("ERROR [%s: bad ACL property value (%s)]\n"), get_pname(), optarg); + break; case ':': case '?': break; @@ -395,12 +415,15 @@ static void amstar_selfcheck( application_argument_t *argument) { - fprintf(stdout, "OK amstar\n"); if (argument->dle.disk) { char *qdisk = quote_string(argument->dle.disk); - fprintf(stdout, "OK %s\n", qdisk); + fprintf(stdout, "OK disk %s\n", qdisk); amfree(qdisk); } + + fprintf(stdout, "OK amstar version %s\n", VERSION); + fprintf(stdout, "OK amstar\n"); + if (argument->dle.device) { char *qdevice = quote_string(argument->dle.device); fprintf(stdout, "OK %s\n", qdevice); @@ -416,15 +439,33 @@ amstar_selfcheck( argument->dle.include_list->nb_element >= 0) { fprintf(stdout, "ERROR include-list not supported for backup\n"); } - if (argument->dle.exclude_list && - argument->dle.exclude_list->nb_element >= 0) { - fprintf(stdout, "ERROR exclude-list not supported for backup\n"); - } if (!star_path) { fprintf(stdout, "ERROR STAR-PATH not defined\n"); } else { - check_file(star_path, X_OK); + if (check_file(star_path, X_OK)) { + char *star_version; + GPtrArray *argv_ptr = g_ptr_array_new(); + + g_ptr_array_add(argv_ptr, star_path); + g_ptr_array_add(argv_ptr, "--version"); + g_ptr_array_add(argv_ptr, NULL); + + star_version = get_first_line(argv_ptr); + + if (star_version) { + char *sv, *sv1; + for (sv = star_version; *sv && !g_ascii_isdigit(*sv); sv++); + for (sv1 = sv; *sv1 && *sv1 != ' '; sv1++); + *sv1 = '\0'; + printf("OK amstar star-version %s\n", sv); + } else { + printf(_("ERROR [Can't get %s version]\n"), star_path); + } + g_ptr_array_free(argv_ptr, TRUE); + amfree(star_version); + + } } if (argument->calcsize) { @@ -440,6 +481,11 @@ amstar_selfcheck( check_file(amandates_file, R_OK|W_OK); } + set_root_privs(1); + if (argument->dle.device) { + check_dir(argument->dle.device, R_OK); + } + set_root_privs(0); } static void @@ -480,9 +526,9 @@ amstar_estimate( argument->dle.include_list->nb_element >= 0) { fprintf(stderr, "ERROR include-list not supported for backup\n"); } - if (argument->dle.exclude_list && - argument->dle.exclude_list->nb_element >= 0) { - fprintf(stderr, "ERROR exclude-list not supported for backup\n"); + + if (check_device(argument) == 0) { + return; } qdisk = quote_string(argument->dle.disk); @@ -490,9 +536,9 @@ amstar_estimate( char *dirname; if (star_directory) { - dirname = amname_to_dirname(star_directory); + dirname = star_directory; } else { - dirname = amname_to_dirname(argument->dle.device); + dirname = argument->dle.device; } run_calcsize(argument->config, "STAR", argument->dle.disk, dirname, argument->level, NULL, NULL); @@ -665,10 +711,6 @@ amstar_backup( argument->dle.include_list->nb_element >= 0) { fprintf(mesgstream, "? include-list not supported for backup\n"); } - if (argument->dle.exclude_list && - argument->dle.exclude_list->nb_element >= 0) { - fprintf(mesgstream, "? exclude-list not supported for backup\n"); - } level = GPOINTER_TO_INT(argument->level->data); @@ -717,7 +759,7 @@ amstar_backup( if (regexec(®ex_dir, line, 3, regmatch, 0) == 0) { if (argument->dle.create_index && regmatch[1].rm_so == 2) { - line[regmatch[1].rm_eo+1]='\0'; + line[regmatch[1].rm_eo]='\0'; fprintf(indexstream, "/%s\n", &line[regmatch[1].rm_so]); } continue; @@ -740,7 +782,7 @@ amstar_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_IGNORE: @@ -845,12 +887,23 @@ amstar_restore( if (argument->dle.include_list && argument->dle.include_list->nb_element == 1) { - g_ptr_array_add(argv_ptr, - stralloc2("list=", - argument->dle.include_list->first->name)); + FILE *include_list = fopen(argument->dle.include_list->first->name, "r"); + char line[2*PATH_MAX+2]; + while (fgets(line, 2*PATH_MAX, include_list)) { + line[strlen(line)-1] = '\0'; /* remove '\n' */ + if (strncmp(line, "./", 2) == 0) + g_ptr_array_add(argv_ptr, stralloc(line+2)); /* remove ./ */ + else if (strcmp(line, ".") != 0) + g_ptr_array_add(argv_ptr, stralloc(line)); + } + fclose(include_list); + } + for (j=1; j< argument->argc; j++) { + if (strncmp(argument->argv[j], "./", 2) == 0) + g_ptr_array_add(argv_ptr, stralloc(argument->argv[j]+2));/*remove ./ */ + else if (strcmp(argument->argv[j], ".") != 0) + g_ptr_array_add(argv_ptr, stralloc(argument->argv[j])); } - for (j=1; j< argument->argc; j++) - g_ptr_array_add(argv_ptr, stralloc(argument->argv[j]+2));/*remove ./ */ g_ptr_array_add(argv_ptr, NULL); debug_executing(argv_ptr); @@ -912,9 +965,9 @@ static GPtrArray *amstar_build_argv( GSList *copt; if (star_directory) { - dirname = amname_to_dirname(star_directory); + dirname = star_directory; } else { - dirname = amname_to_dirname(argument->dle.device); + dirname = argument->dle.device; } fsname = vstralloc("fs-name=", dirname, NULL); for (s = fsname; *s != '\0'; s++) { @@ -941,6 +994,7 @@ static GPtrArray *amstar_build_argv( g_ptr_array_add(argv_ptr, stralloc("-")); } g_ptr_array_add(argv_ptr, stralloc("-C")); + #if defined(__CYGWIN__) { char tmppath[PATH_MAX]; @@ -959,28 +1013,117 @@ static GPtrArray *amstar_build_argv( g_ptr_array_add(argv_ptr, stralloc2("tardumps=", tardumpfile)); if (command == CMD_BACKUP) g_ptr_array_add(argv_ptr, stralloc("-wtardumps")); + g_ptr_array_add(argv_ptr, stralloc("-xattr")); - g_ptr_array_add(argv_ptr, stralloc("-acl")); + if (star_acl) + g_ptr_array_add(argv_ptr, stralloc("-acl")); g_ptr_array_add(argv_ptr, stralloc("H=exustar")); g_ptr_array_add(argv_ptr, stralloc("errctl=WARN|SAMEFILE|DIFF|GROW|SHRINK|SPECIALFILE|GETXATTR|BADACL *")); if (star_sparse) g_ptr_array_add(argv_ptr, stralloc("-sparse")); g_ptr_array_add(argv_ptr, stralloc("-dodesc")); + if (command == CMD_BACKUP && argument->dle.create_index) + g_ptr_array_add(argv_ptr, stralloc("-v")); + + if ((argument->dle.exclude_file && + argument->dle.exclude_file->nb_element >= 1) || + (argument->dle.exclude_list && + argument->dle.exclude_list->nb_element >= 1)) { + g_ptr_array_add(argv_ptr, stralloc("-match-tree")); + g_ptr_array_add(argv_ptr, stralloc("-not")); + } + if (argument->dle.exclude_file && + argument->dle.exclude_file->nb_element >= 1) { + sle_t *excl; + for (excl = argument->dle.exclude_file->first; excl != NULL; + excl = excl->next) { + char *ex; + if (strcmp(excl->name, "./") == 0) { + ex = g_strdup_printf("pat=%s", excl->name+2); + } else { + ex = g_strdup_printf("pat=%s", excl->name); + } + g_ptr_array_add(argv_ptr, ex); + } + } + if (argument->dle.exclude_list && + argument->dle.exclude_list->nb_element >= 1) { + sle_t *excl; + for (excl = argument->dle.exclude_list->first; excl != NULL; + excl = excl->next) { + char *exclname = fixup_relative(excl->name, argument->dle.device); + FILE *exclude; + char *aexc; + if ((exclude = fopen(exclname, "r")) != NULL) { + while ((aexc = agets(exclude)) != NULL) { + if (aexc[0] != '\0') { + char *ex; + if (strcmp(aexc, "./") == 0) { + ex = g_strdup_printf("pat=%s", aexc+2); + } else { + ex = g_strdup_printf("pat=%s", aexc); + } + g_ptr_array_add(argv_ptr, ex); + } + amfree(aexc); + } + fclose(exclude); + } + amfree(exclname); + } + } + + /* It is best to place command_options at the and of command line. + * For example '-find' option requires that it is the last option used. + * See: http://cdrecord.berlios.de/private/man/star/star.1.html + */ for (copt = argument->command_options; copt != NULL; copt = copt->next) { g_ptr_array_add(argv_ptr, stralloc((char *)copt->data)); } - if (command == CMD_BACKUP && argument->dle.create_index) - g_ptr_array_add(argv_ptr, stralloc("-v")); - g_ptr_array_add(argv_ptr, stralloc(".")); g_ptr_array_add(argv_ptr, NULL); amfree(tardumpfile); amfree(fsname); - amfree(dirname); return(argv_ptr); } + +static int +check_device( + application_argument_t *argument) +{ + char *qdevice; + struct stat stat_buf; + + qdevice = quote_string(argument->dle.device); + set_root_privs(1); + if(!stat(argument->dle.device, &stat_buf)) { + if (!S_ISDIR(stat_buf.st_mode)) { + set_root_privs(0); + g_fprintf(stderr, _("ERROR %s is not a directory\n"), qdevice); + amfree(qdevice); + return 0; + } + } else { + set_root_privs(0); + g_fprintf(stderr, _("ERROR can not stat %s: %s\n"), qdevice, + strerror(errno)); + amfree(qdevice); + return 0; + } + if (access(argument->dle.device, R_OK|X_OK) == -1) { + set_root_privs(0); + g_fprintf(stderr, _("ERROR can not access %s: %s\n"), + argument->dle.device, strerror(errno)); + amfree(qdevice); + return 0; + } + set_root_privs(0); + amfree(qdevice); + return 1; +} +