X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=application-src%2Famstar.c;h=bcd9988b267e68dd2ff3b3ce5f2a721f45e8fbda;hb=b116e9366c7b2ea2c2eb53b0a13df4090e176235;hp=eb6e4941cd5c24f58aa4af8fbcaf0b2b3dfad86c;hpb=2627875b7d18858bc1f9f7652811e4d8c15a23eb;p=debian%2Famanda diff --git a/application-src/amstar.c b/application-src/amstar.c index eb6e494..bcd9988 100644 --- a/application-src/amstar.c +++ b/application-src/amstar.c @@ -36,19 +36,24 @@ * STAR-DLE-TARDUMP * ONE-FILE-SYSTEM * SPARSE + * NORMAL + * IGNORE + * STRANGE + * INCLUDE-LIST (for restore only) + * EXCLUDE-LIST (for restore only) + * DIRECTORY */ #include "amanda.h" +#include "match.h" #include "pipespawn.h" #include "amfeatures.h" #include "amandates.h" #include "clock.h" #include "util.h" #include "getfsent.h" -#include "version.h" #include "client_util.h" #include "conffile.h" -#include "amandad.h" #include "getopt.h" #include "sendbackup.h" @@ -59,7 +64,7 @@ int debug_application = 1; } \ } while (0) -static amregex_t re_table[] = { +static amregex_t init_re_table[] = { /* tar prints the size in bytes */ AM_SIZE_RE("star: [0-9][0-9]* blocks", 10240, 1), AM_NORMAL_RE("^could not open conf file"), @@ -90,6 +95,7 @@ static amregex_t re_table[] = { /* catch-all: DMP_STRANGE is returned for all other lines */ AM_STRANGE_RE(NULL) }; +static amregex_t *re_table; /* local functions */ int main(int argc, char **argv); @@ -101,6 +107,7 @@ typedef struct application_argument_s { int collection; int calcsize; GSList *level; + GSList *command_options; dle_t dle; int argc; char **argv; @@ -114,14 +121,20 @@ static void amstar_estimate(application_argument_t *argument); static void amstar_backup(application_argument_t *argument); static void amstar_restore(application_argument_t *argument); static void amstar_validate(application_argument_t *argument); -static char **amstar_build_argv(application_argument_t *argument, +static GPtrArray *amstar_build_argv(application_argument_t *argument, int level, int command); -char *star_path; -char *star_tardumps; -int star_dle_tardumps; -int star_onefilesystem; -int star_sparse; +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 char *star_directory; +static GSList *normal_message = NULL; +static GSList *ignore_message = NULL; +static GSList *strange_message = NULL; static struct option long_options[] = { {"config" , 1, NULL, 1}, @@ -139,6 +152,13 @@ static struct option long_options[] = { {"one-file-system" , 1, NULL, 13}, {"sparse" , 1, NULL, 14}, {"calcsize" , 0, NULL, 15}, + {"normal" , 1, NULL, 16}, + {"ignore" , 1, NULL, 17}, + {"strange" , 1, NULL, 18}, + {"include-list" , 1, NULL, 19}, + {"exclude-list" , 1, NULL, 20}, + {"directory" , 1, NULL, 21}, + {"command-options" , 1, NULL, 22}, { NULL, 0, NULL, 0} }; @@ -161,6 +181,7 @@ main( star_dle_tardumps = 0; star_onefilesystem = 1; star_sparse = 1; + star_directory = NULL; /* initialize */ @@ -169,13 +190,20 @@ main( * 1) Only set the message locale for now. * 2) Set textdomain for all amanda related programs to "amanda" * We don't want to be forced to support dozens of message catalogs. - */ + */ setlocale(LC_MESSAGES, "C"); - textdomain("amanda"); + textdomain("amanda"); - /* drop root privileges */ + if (argc < 2) { + printf("ERROR no command given to amstar\n"); + error(_("No command given to amstar")); + } + /* drop root privileges */ if (!set_root_privs(0)) { + if (strcmp(argv[1], "selfcheck") == 0) { + printf("ERROR amstar must be run setuid root\n"); + } error(_("amstar must be run setuid root")); } @@ -190,10 +218,11 @@ main( malloc_size_1 = malloc_inuse(&malloc_hist_1); #endif - erroutput_type = (ERR_INTERACTIVE|ERR_SYSLOG); + add_amanda_log_handler(amanda_log_stderr); + add_amanda_log_handler(amanda_log_syslog); dbopen(DBG_SUBDIR_CLIENT); startclock(); - dbprintf(_("version %s\n"), version()); + dbprintf(_("version %s\n"), VERSION); config_init(CONFIG_INIT_CLIENT, NULL); @@ -210,6 +239,7 @@ main( argument.collection = 0; argument.calcsize = 0; argument.level = NULL; + argument.command_options = NULL; init_dle(&argument.dle); opterr = 0; @@ -243,23 +273,64 @@ main( break; case 11: star_tardumps = stralloc(optarg); break; - case 12: if (optarg && strcasecmp(optarg, "YES") == 0) + case 12: if (optarg && strcasecmp(optarg, "NO") == 0) + star_dle_tardumps = 0; + else if (optarg && strcasecmp(optarg, "YES") == 0) star_dle_tardumps = 1; + else if (strcasecmp(command, "selfcheck") == 0) + printf(_("ERROR [%s: bad STAR-DLE-TARDUMP property value (%s)]\n"), get_pname(), optarg); break; - case 13: if (optarg && strcasecmp(optarg, "YES") != 0) - star_onefilesystem = 0; + case 13: if (optarg && strcasecmp(optarg, "YES") != 0) { + /* This option is required to be YES */ + /* star_onefilesystem = 0; */ + } break; - case 14: if (optarg && strcasecmp(optarg, "YES") != 0) + case 14: if (optarg && strcasecmp(optarg, "NO") == 0) + star_sparse = 0; + else if (optarg && strcasecmp(optarg, "YES") == 0) star_sparse = 1; + else if (strcasecmp(command, "selfcheck") == 0) + printf(_("ERROR [%s: bad SPARSE property value (%s)]\n"), get_pname(), optarg); break; case 15: argument.calcsize = 1; break; + case 16: if (optarg) + normal_message = + g_slist_append(normal_message, optarg); + break; + case 17: if (optarg) + ignore_message = + g_slist_append(ignore_message, optarg); + break; + case 18: if (optarg) + strange_message = + g_slist_append(strange_message, optarg); + break; + case 19: if (optarg) + argument.dle.include_list = + append_sl(argument.dle.include_list, optarg); + break; + case 20: if (optarg) + argument.dle.exclude_list = + append_sl(argument.dle.exclude_list, optarg); + break; + case 21: if (optarg) + star_directory = stralloc(optarg); + break; + case 22: argument.command_options = + g_slist_append(argument.command_options, + stralloc(optarg)); case ':': case '?': break; } } + if (!argument.dle.disk && argument.dle.device) + argument.dle.disk = stralloc(argument.dle.device); + if (!argument.dle.device && argument.dle.disk) + argument.dle.device = stralloc(argument.dle.disk); + argument.argc = argc - optind; argument.argv = argv + optind; @@ -275,6 +346,9 @@ main( g_critical(_("errors processing config file")); } + re_table = build_re_table(init_re_table, normal_message, ignore_message, + strange_message); + if (strcmp(command, "support") == 0) { amstar_support(&argument); } else if (strcmp(command, "selfcheck") == 0) { @@ -309,25 +383,44 @@ amstar_support( fprintf(stdout, "MESSAGE-XML NO\n"); fprintf(stdout, "RECORD YES\n"); fprintf(stdout, "INCLUDE-FILE NO\n"); - fprintf(stdout, "INCLUDE-LIST NO\n"); + fprintf(stdout, "INCLUDE-LIST YES\n"); fprintf(stdout, "EXCLUDE-FILE YES\n"); fprintf(stdout, "EXCLUDE-LIST YES\n"); fprintf(stdout, "COLLECTION NO\n"); fprintf(stdout, "MULTI-ESTIMATE YES\n"); fprintf(stdout, "CALCSIZE YES\n"); + fprintf(stdout, "CLIENT-ESTIMATE YES\n"); } static void amstar_selfcheck( application_argument_t *argument) { - char *qdisk; - char *qdevice; + fprintf(stdout, "OK amstar\n"); + if (argument->dle.disk) { + char *qdisk = quote_string(argument->dle.disk); + fprintf(stdout, "OK %s\n", qdisk); + amfree(qdisk); + } + if (argument->dle.device) { + char *qdevice = quote_string(argument->dle.device); + fprintf(stdout, "OK %s\n", qdevice); + amfree(qdevice); + } + if (star_directory) { + char *qdirectory = quote_string(star_directory); + fprintf(stdout, "OK %s\n", qdirectory); + amfree(qdirectory); + } - qdisk = quote_string(argument->dle.disk); - qdevice = quote_string(argument->dle.device); - fprintf(stdout, "OK %s\n", qdisk); - fprintf(stdout, "OK %s\n", qdevice); + if (argument->dle.include_list && + 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"); @@ -335,40 +428,82 @@ amstar_selfcheck( check_file(star_path, X_OK); } + if (argument->calcsize) { + char *calcsize = vstralloc(amlibexecdir, "/", "calcsize", NULL); + check_file(calcsize, X_OK); + check_suid(calcsize); + amfree(calcsize); + } + { char *amandates_file; amandates_file = getconf_str(CNF_AMANDATES); 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 amstar_estimate( application_argument_t *argument) { - char **my_argv = NULL; - char *cmd = NULL; - int nullfd; - int pipefd; - FILE *dumpout = NULL; - off_t size = -1; - char line[32768]; - char *errmsg = NULL; - char *qerrmsg; - char *qdisk; - amwait_t wait_status; - int starpid; - amregex_t *rp; - times_t start_time; - int level = 0; - GSList *levels = NULL; + GPtrArray *argv_ptr; + char *cmd = NULL; + int nullfd; + int pipefd; + FILE *dumpout = NULL; + off_t size = -1; + char line[32768]; + char *errmsg = NULL; + char *qerrmsg; + char *qdisk; + amwait_t wait_status; + int starpid; + amregex_t *rp; + times_t start_time; + int level = 0; + GSList *levels = NULL; + + if (!argument->level) { + fprintf(stderr, "ERROR No level argument\n"); + error(_("No level argument")); + } + if (!argument->dle.disk) { + fprintf(stderr, "ERROR No disk argument\n"); + error(_("No disk argument")); + } + if (!argument->dle.device) { + fprintf(stderr, "ERROR No device argument\n"); + error(_("No device argument")); + } + + if (argument->dle.include_list && + 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); if (argument->calcsize) { char *dirname; - dirname = amname_to_dirname(argument->dle.device); + if (star_directory) { + dirname = amname_to_dirname(star_directory); + } else { + dirname = amname_to_dirname(argument->dle.device); + } run_calcsize(argument->config, "STAR", argument->dle.disk, dirname, argument->level, NULL, NULL); return; @@ -384,7 +519,7 @@ amstar_estimate( for (levels = argument->level; levels != NULL; levels = levels->next) { level = GPOINTER_TO_INT(levels->data); - my_argv = amstar_build_argv(argument, level, CMD_ESTIMATE); + argv_ptr = amstar_build_argv(argument, level, CMD_ESTIMATE); if ((nullfd = open("/dev/null", O_RDWR)) == -1) { errmsg = vstrallocf(_("Cannot access /dev/null : %s"), @@ -393,7 +528,8 @@ amstar_estimate( } starpid = pipespawnv(cmd, STDERR_PIPE, 1, - &nullfd, &nullfd, &pipefd, my_argv); + &nullfd, &nullfd, &pipefd, + (char **)argv_ptr->pdata); dumpout = fdopen(pipefd,"r"); if (!dumpout) { @@ -434,12 +570,12 @@ amstar_estimate( walltime_str(timessub(curclock(), start_time))); if(size == (off_t)-1) { errmsg = vstrallocf(_("no size line match in %s output"), - my_argv[0]); + cmd); dbprintf(_("%s for %s\n"), errmsg, qdisk); dbprintf(".....\n"); } else if(size == (off_t)0 && argument->level == 0) { dbprintf(_("possible %s problem -- is \"%s\" really empty?\n"), - my_argv[0], argument->dle.disk); + cmd, argument->dle.disk); dbprintf(".....\n"); } dbprintf(_("estimate size for %s level %d: %lld KB\n"), @@ -449,7 +585,7 @@ amstar_estimate( kill(-starpid, SIGTERM); - dbprintf(_("waiting for %s \"%s\" child\n"), my_argv[0], qdisk); + dbprintf(_("waiting for %s \"%s\" child\n"), cmd, qdisk); waitpid(starpid, &wait_status, 0); if (WIFSIGNALED(wait_status)) { errmsg = vstrallocf(_("%s terminated with signal %d: see %s"), @@ -464,9 +600,9 @@ amstar_estimate( } else { errmsg = vstrallocf(_("%s got bad exit: see %s"), cmd, dbfn()); } - dbprintf(_("after %s %s wait\n"), my_argv[0], qdisk); + dbprintf(_("after %s %s wait\n"), cmd, qdisk); - amfree(my_argv); + g_ptr_array_free_full(argv_ptr); aclose(nullfd); afclose(dumpout); @@ -492,34 +628,70 @@ static void amstar_backup( application_argument_t *argument) { - int dumpin; - char *cmd = NULL; - char *qdisk; - char line[32768]; + int dumpin; + char *cmd = NULL; + char *qdisk; + char line[32768]; amregex_t *rp; - off_t dump_size = -1; - char *type; - char startchr; - char **my_argv; - int starpid; - int dataf = 1; - int mesgf = 3; - int indexf = 4; - int outf; - FILE *mesgstream; - FILE *indexstream = NULL; - FILE *outstream; - int level = GPOINTER_TO_INT(argument->level->data); + off_t dump_size = -1; + char *type; + char startchr; + GPtrArray *argv_ptr; + int starpid; + int dataf = 1; + int mesgf = 3; + int indexf = 4; + int outf; + FILE *mesgstream; + FILE *indexstream = NULL; + FILE *outstream; + int level; + regex_t regex_root; + regex_t regex_dir; + regex_t regex_file; + regex_t regex_special; + regex_t regex_symbolic; + regex_t regex_hard; + + mesgstream = fdopen(mesgf, "w"); + if (!mesgstream) { + error(_("error mesgstream(%d): %s\n"), mesgf, strerror(errno)); + } + + if (!argument->level) { + fprintf(mesgstream, "? No level argument\n"); + error(_("No level argument")); + } + if (!argument->dle.disk) { + fprintf(mesgstream, "? No disk argument\n"); + error(_("No disk argument")); + } + if (!argument->dle.device) { + fprintf(mesgstream, "? No device argument\n"); + error(_("No device argument")); + } + + if (argument->dle.include_list && + 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); qdisk = quote_string(argument->dle.disk); - my_argv = amstar_build_argv(argument, level, CMD_BACKUP); + argv_ptr = amstar_build_argv(argument, level, CMD_BACKUP); cmd = stralloc(star_path); starpid = pipespawnv(cmd, STDIN_PIPE|STDERR_PIPE, 1, - &dumpin, &dataf, &outf, my_argv); + &dumpin, &dataf, &outf, (char **)argv_ptr->pdata); + g_ptr_array_free_full(argv_ptr); /* close the write ends of the pipes */ aclose(dumpin); aclose(dataf); @@ -529,81 +701,60 @@ amstar_backup( error(_("error indexstream(%d): %s\n"), indexf, strerror(errno)); } } - mesgstream = fdopen(mesgf, "w"); - if (!mesgstream) { - error(_("error mesgstream(%d): %s\n"), mesgf, strerror(errno)); - } outstream = fdopen(outf, "r"); if (!outstream) { error(_("error outstream(%d): %s\n"), outf, strerror(errno)); } + regcomp(®ex_root, "^a \\.\\/ directory$", REG_EXTENDED|REG_NEWLINE); + regcomp(®ex_dir, "^a (.*) directory$", REG_EXTENDED|REG_NEWLINE); + regcomp(®ex_file, "^a (.*) (.*) bytes", REG_EXTENDED|REG_NEWLINE); + regcomp(®ex_special, "^a (.*) special", REG_EXTENDED|REG_NEWLINE); + regcomp(®ex_symbolic, "^a (.*) symbolic", REG_EXTENDED|REG_NEWLINE); + regcomp(®ex_hard, "^a (.*) link to", REG_EXTENDED|REG_NEWLINE); + while ((fgets(line, sizeof(line), outstream)) != NULL) { regmatch_t regmatch[3]; - regex_t regex; - int got_match = 0; if (line[strlen(line)-1] == '\n') /* remove trailling \n */ line[strlen(line)-1] = '\0'; - regcomp(®ex, "^a \\.\\/ directory$", REG_EXTENDED|REG_NEWLINE); - if (regexec(®ex, line, 1, regmatch, 0) == 0) { - got_match = 1; + if (regexec(®ex_root, line, 1, regmatch, 0) == 0) { if (argument->dle.create_index) - fprintf(indexstream, "%s\n", "/\n"); + fprintf(indexstream, "%s\n", "/"); + continue; } - regfree(®ex); - regcomp(®ex, "^a (.*) directory$", REG_EXTENDED|REG_NEWLINE); - if (regexec(®ex, line, 3, regmatch, 0) == 0) { - got_match = 1; + 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'; fprintf(indexstream, "/%s\n", &line[regmatch[1].rm_so]); } + continue; } - regfree(®ex); - regcomp(®ex, "^a (.*) (.*) bytes", REG_EXTENDED|REG_NEWLINE); - if (regexec(®ex, line, 3, regmatch, 0) == 0) { - got_match = 1; + if (regexec(®ex_file, line, 3, regmatch, 0) == 0 || + regexec(®ex_special, line, 3, regmatch, 0) == 0 || + regexec(®ex_symbolic, line, 3, regmatch, 0) == 0 || + regexec(®ex_hard, line, 3, regmatch, 0) == 0) { if (argument->dle.create_index && regmatch[1].rm_so == 2) { line[regmatch[1].rm_eo]='\0'; fprintf(indexstream, "/%s\n", &line[regmatch[1].rm_so]); } + continue; } - regfree(®ex); - regcomp(®ex, "^a (.*) special", REG_EXTENDED|REG_NEWLINE); - if (regexec(®ex, line, 3, regmatch, 0) == 0) { - got_match = 1; - if (argument->dle.create_index && regmatch[1].rm_so == 2) { - line[regmatch[1].rm_eo]='\0'; - fprintf(indexstream, "/%s\n", &line[regmatch[1].rm_so]); + for (rp = re_table; rp->regex != NULL; rp++) { + if (match(rp->regex, line)) { + break; } } - regfree(®ex); - - regcomp(®ex, "^a (.*) symbolic", REG_EXTENDED|REG_NEWLINE); - if (regexec(®ex, line, 3, regmatch, 0) == 0) { - got_match = 1; - if (argument->dle.create_index && regmatch[1].rm_so == 2) { - line[regmatch[1].rm_eo]='\0'; - fprintf(indexstream, "/%s\n", &line[regmatch[1].rm_so]); - } + if (rp->typ == DMP_SIZE) { + dump_size = (long)((the_num(line, rp->field)* rp->scale+1023.0)/1024.0); } - regfree(®ex); - - if (got_match == 0) { /* message */ - for(rp = re_table; rp->regex != NULL; rp++) { - if(match(rp->regex, line)) { - break; - } - } - if(rp->typ == DMP_SIZE) { - dump_size = (long)((the_num(line, rp->field)* rp->scale+1023.0)/1024.0); - } - switch(rp->typ) { + switch (rp->typ) { + case DMP_IGNORE: + continue; case DMP_NORMAL: type = "normal"; startchr = '|'; @@ -624,12 +775,18 @@ amstar_backup( type = "unknown"; startchr = '!'; break; - } - dbprintf("%3d: %7s(%c): %s\n", rp->srcline, type, startchr, line); - fprintf(mesgstream,"%c %s\n", startchr, line); - } + } + dbprintf("%3d: %7s(%c): %s\n", rp->srcline, type, startchr, line); + fprintf(mesgstream,"%c %s\n", startchr, line); } + regfree(®ex_root); + regfree(®ex_dir); + regfree(®ex_file); + regfree(®ex_special); + regfree(®ex_symbolic); + regfree(®ex_hard); + dbprintf(_("gnutar: %s: pid %ld\n"), cmd, (long)starpid); dbprintf("sendbackup: size %lld\n", (long long)dump_size); @@ -649,36 +806,67 @@ static void amstar_restore( application_argument_t *argument) { - char *cmd; - char **my_argv; - char **env; - int i, j; - char *e; + char *cmd; + GPtrArray *argv_ptr = g_ptr_array_new(); + char **env; + int j; + char *e; if (!star_path) { error(_("STAR-PATH not defined")); } cmd = stralloc(star_path); - my_argv = alloc(SIZEOF(char *) * (11 + argument->argc)); - i = 0; - my_argv[i++] = stralloc(star_path); - my_argv[i++] = stralloc("-x"); - my_argv[i++] = stralloc("-v"); - my_argv[i++] = stralloc("-xattr"); - my_argv[i++] = stralloc("-acl"); - my_argv[i++] = stralloc("errctl=WARN|SAMEFILE|SETTIME|DIFF|SETACL|SETXATTR|SETMODE|BADACL *"); - my_argv[i++] = stralloc("-no-fifo"); - my_argv[i++] = stralloc("-f"); - my_argv[i++] = stralloc("-"); + g_ptr_array_add(argv_ptr, stralloc(star_path)); + if (star_directory) { + struct stat stat_buf; + if(stat(star_directory, &stat_buf) != 0) { + fprintf(stderr,"can not stat directory %s: %s\n", star_directory, strerror(errno)); + exit(1); + } + if (!S_ISDIR(stat_buf.st_mode)) { + fprintf(stderr,"%s is not a directory\n", star_directory); + exit(1); + } + if (access(star_directory, W_OK) != 0 ) { + fprintf(stderr, "Can't write to %s: %s\n", star_directory, strerror(errno)); + exit(1); + } + + g_ptr_array_add(argv_ptr, stralloc("-C")); + g_ptr_array_add(argv_ptr, stralloc(star_directory)); + } + g_ptr_array_add(argv_ptr, stralloc("-x")); + g_ptr_array_add(argv_ptr, stralloc("-v")); + g_ptr_array_add(argv_ptr, stralloc("-xattr")); + g_ptr_array_add(argv_ptr, stralloc("-acl")); + g_ptr_array_add(argv_ptr, stralloc("errctl=WARN|SAMEFILE|SETTIME|DIFF|SETACL|SETXATTR|SETMODE|BADACL *")); + g_ptr_array_add(argv_ptr, stralloc("-no-fifo")); + g_ptr_array_add(argv_ptr, stralloc("-f")); + g_ptr_array_add(argv_ptr, stralloc("-")); + + if (argument->dle.exclude_list && + argument->dle.exclude_list->nb_element == 1) { + g_ptr_array_add(argv_ptr, stralloc("-exclude-from")); + g_ptr_array_add(argv_ptr, + stralloc(argument->dle.exclude_list->first->name)); + } + + 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)); + } for (j=1; j< argument->argc; j++) - my_argv[i++] = stralloc(argument->argv[j]+2); /* remove ./ */ - my_argv[i++] = NULL; + g_ptr_array_add(argv_ptr, stralloc(argument->argv[j]+2));/*remove ./ */ + g_ptr_array_add(argv_ptr, NULL); + debug_executing(argv_ptr); env = safe_env(); become_root(); - execve(cmd, my_argv, env); + execve(cmd, (char **)argv_ptr->pdata, env); e = strerror(errno); error(_("error [exec %s: %s]"), cmd, e); @@ -688,46 +876,56 @@ static void amstar_validate( application_argument_t *argument G_GNUC_UNUSED) { - char *cmd; - char **my_argv; - char **env; - int i; - char *e; + char *cmd; + GPtrArray *argv_ptr = g_ptr_array_new(); + char **env; + char *e; + char buf[32768]; if (!star_path) { - error(_("STAR-PATH not defined")); + dbprintf("STAR-PATH not set; Piping to /dev/null\n"); + fprintf(stderr,"STAR-PATH not set; Piping to /dev/null\n"); + goto pipe_to_null; } cmd = stralloc(star_path); - my_argv = alloc(SIZEOF(char *) * 5); - i = 0; - my_argv[i++] = stralloc(star_path); - my_argv[i++] = stralloc("-t"); - my_argv[i++] = stralloc("-f"); - my_argv[i++] = stralloc("-"); - my_argv[i++] = NULL; + g_ptr_array_add(argv_ptr, stralloc(star_path)); + g_ptr_array_add(argv_ptr, stralloc("-t")); + g_ptr_array_add(argv_ptr, stralloc("-f")); + g_ptr_array_add(argv_ptr, stralloc("-")); + g_ptr_array_add(argv_ptr, NULL); + + debug_executing(argv_ptr); env = safe_env(); - execve(cmd, my_argv, env); + execve(cmd, (char **)argv_ptr->pdata, env); e = strerror(errno); - error(_("error [exec %s: %s]"), cmd, e); + dbprintf("failed to execute %s: %s; Piping to /dev/null\n", cmd, e); + fprintf(stderr,"failed to execute %s: %s; Piping to /dev/null\n", cmd, e); +pipe_to_null: + while (read(0, buf, 32768) > 0) { + } } -char **amstar_build_argv( +static GPtrArray *amstar_build_argv( application_argument_t *argument, int level, int command) { - int i; - char *dirname; - char *fsname; - char levelstr[NUM_STR_SIZE+7]; - char **my_argv; - char *s; - char *tardumpfile; - - dirname = amname_to_dirname(argument->dle.device); + char *dirname; + char *fsname; + char levelstr[NUM_STR_SIZE+7]; + GPtrArray *argv_ptr = g_ptr_array_new(); + char *s; + char *tardumpfile; + GSList *copt; + + if (star_directory) { + dirname = amname_to_dirname(star_directory); + } else { + dirname = amname_to_dirname(argument->dle.device); + } fsname = vstralloc("fs-name=", dirname, NULL); for (s = fsname; *s != '\0'; s++) { if (iscntrl((int)*s)) @@ -743,55 +941,92 @@ char **amstar_build_argv( tardumpfile = stralloc(star_tardumps); } - my_argv = alloc(SIZEOF(char *) * 32); - i = 0; - - my_argv[i++] = star_path; + g_ptr_array_add(argv_ptr, stralloc(star_path)); - my_argv[i++] = stralloc("-c"); - my_argv[i++] = stralloc("-f"); + g_ptr_array_add(argv_ptr, stralloc("-c")); + g_ptr_array_add(argv_ptr, stralloc("-f")); if (command == CMD_ESTIMATE) { - my_argv[i++] = stralloc("/dev/null"); + g_ptr_array_add(argv_ptr, stralloc("/dev/null")); } else { - my_argv[i++] = stralloc("-"); + g_ptr_array_add(argv_ptr, stralloc("-")); } - my_argv[i++] = stralloc("-C"); + g_ptr_array_add(argv_ptr, stralloc("-C")); #if defined(__CYGWIN__) { char tmppath[PATH_MAX]; cygwin_conv_to_full_posix_path(dirname, tmppath); - my_argv[i++] = stralloc(tmppath); + g_ptr_array_add(argv_ptr, stralloc(tmppath)); } #else - my_argv[i++] = stralloc(dirname); + g_ptr_array_add(argv_ptr, stralloc(dirname)); #endif - my_argv[i++] = stralloc(fsname); + g_ptr_array_add(argv_ptr, stralloc(fsname)); if (star_onefilesystem) - my_argv[i++] = stralloc("-xdev"); - my_argv[i++] = stralloc("-link-dirs"); - my_argv[i++] = stralloc(levelstr); - my_argv[i++] = stralloc2("tardumps=", tardumpfile); + g_ptr_array_add(argv_ptr, stralloc("-xdev")); + g_ptr_array_add(argv_ptr, stralloc("-link-dirs")); + g_ptr_array_add(argv_ptr, stralloc(levelstr)); + g_ptr_array_add(argv_ptr, stralloc2("tardumps=", tardumpfile)); if (command == CMD_BACKUP) - my_argv[i++] = stralloc("-wtardumps"); - my_argv[i++] = stralloc("-xattr"); - my_argv[i++] = stralloc("-acl"); - my_argv[i++] = stralloc("H=exustar"); - my_argv[i++] = stralloc("errctl=WARN|SAMEFILE|DIFF|GROW|SHRINK|SPECIALFILE|GETXATTR|BADACL *"); + g_ptr_array_add(argv_ptr, stralloc("-wtardumps")); + g_ptr_array_add(argv_ptr, stralloc("-xattr")); + 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) - my_argv[i++] = stralloc("-sparse"); - my_argv[i++] = stralloc("-dodesc"); + g_ptr_array_add(argv_ptr, stralloc("-sparse")); + g_ptr_array_add(argv_ptr, stralloc("-dodesc")); + + 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) - my_argv[i++] = stralloc("-v"); + g_ptr_array_add(argv_ptr, stralloc("-v")); - my_argv[i++] = stralloc("."); + g_ptr_array_add(argv_ptr, stralloc(".")); - my_argv[i] = NULL; + g_ptr_array_add(argv_ptr, NULL); amfree(tardumpfile); amfree(fsname); amfree(dirname); - return(my_argv); + 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; } +