int check_infofile( char *infodir, disklist_t *dl, char **errmsg) { disk_t *dp, *diskp; char *hostinfodir, *old_hostinfodir, *Xhostinfodir; char *diskdir, *old_diskdir, *Xdiskdir; char *infofile, *old_infofile, *Xinfofile; struct stat statbuf; int other_dle_match; if (stat(infodir, &statbuf) != 0) { return 0; } for (dp = dl->head; dp != NULL; dp = dp->next) { hostinfodir = sanitise_filename(dp->host->hostname); diskdir = sanitise_filename(dp->name); infofile = vstralloc(infodir, "/", hostinfodir, "/", diskdir, "/info", NULL); if (stat(infofile, &statbuf) == -1 && errno == ENOENT) { old_hostinfodir = old_sanitise_filename(dp->host->hostname); old_diskdir = old_sanitise_filename(dp->name); old_infofile = vstralloc(infodir, old_hostinfodir, "/", old_diskdir, "/info", NULL); if (stat(old_infofile, &statbuf) == 0) { other_dle_match = 0; diskp = dl->head; while (diskp != NULL) { Xhostinfodir = sanitise_filename(diskp->host->hostname); Xdiskdir = sanitise_filename(diskp->name); Xinfofile = vstralloc(infodir, "/", Xhostinfodir, "/", Xdiskdir, "/info", NULL); if (strcmp(old_infofile, Xinfofile) == 0) { other_dle_match = 1; diskp = NULL; } else { diskp = diskp->next; } } if (other_dle_match == 0) { if(mkpdir(infofile, (mode_t)0755, (uid_t)-1, (gid_t)-1) == -1) { *errmsg = vstralloc("Can't create directory for ", infofile, NULL); return -1; } if(copy_file(infofile, old_infofile, errmsg) == -1) return -1; } } } amfree(diskdir); amfree(hostinfodir); amfree(infofile); } return 0; }
static char * setup_vtape_dir(void) { char *cwd = g_get_current_dir(); char *device_path = NULL; char *data_dir = NULL; device_path = vstralloc(cwd, "/vfs-test-XXXXXX", NULL); amfree(cwd); if (mkdtemp(device_path) == NULL) { fprintf(stderr, "Could not create temporary directory in %s\n", cwd); return NULL; } /* append "/data/" to that for the VFS device*/ data_dir = vstralloc(device_path, "/data/", NULL); if (mkdir(data_dir, 0777) == -1) { fprintf(stderr, "Could not create %s: %s\n", cwd, strerror(errno)); amfree(data_dir); return NULL; } amfree(data_dir); return device_path; }
char * amxml_format_tag( char *tag, char *value) { char *b64value; char *c; int need_raw; char *result; char *quoted_value; char *q; quoted_value = malloc(strlen(value)+1); q = quoted_value; need_raw = 0; for(c=value; *c != '\0'; c++) { // Check include negative value, with the 8th bit set. if (*c <= ' ' || (unsigned char)*c > 127 || *c == '<' || *c == '>' || *c == '"' || *c == '&' || *c == '\\' || *c == '\'' || *c == '\t' || *c == '\f' || *c == '\r' || *c == '\n') { need_raw = 1; *q++ = '_'; } else { *q++ = *c; } } *q = '\0'; if (need_raw) { base64_encode_alloc(value, strlen(value), &b64value); result = vstralloc("<", tag, " encoding=\"raw\" raw=\"", b64value, "\">", quoted_value, "</", tag, ">", NULL); amfree(b64value); } else { result = vstralloc("<", tag, ">", value, "</", tag, ">", NULL); } amfree(quoted_value); return result; }
void run_amcleanup( char *config_name) { pid_t amcleanup_pid; char *amcleanup_program; char *amcleanup_options[4]; switch(amcleanup_pid = fork()) { case -1: return; break; case 0: /* child process */ amcleanup_program = vstralloc(sbindir, "/", "amcleanup", NULL); amcleanup_options[0] = amcleanup_program; amcleanup_options[1] = "-p"; amcleanup_options[2] = config_name; amcleanup_options[3] = NULL; execve(amcleanup_program, amcleanup_options, safe_env()); error("exec %s: %s", amcleanup_program, strerror(errno)); /*NOTREACHED*/ default: break; } waitpid(amcleanup_pid, NULL, 0); }
/**** * Test the strquotedstr function */ static int test_strquotedstr_skipping(void) { char **iter1, **iter2; gboolean success = TRUE; /* the idea here is to loop over all pairs of strings, forming a * string by quoting them with quote_string and inserting a space, then * re-splitting with strquotedstr. This should get us back to our * starting point. Note that we have to begin with a non-quoted identifier, * becuse strquotedstr requires that strtok_r has already been called. */ for (iter1 = quotable_strings; *iter1; iter1++) { for (iter2 = quotable_strings; *iter2; iter2++) { char *q1 = quote_string(*iter1); char *q2 = quote_string(*iter2); char *combined = vstralloc("START ", q1, " ", q2, NULL); char *copy = g_strdup(combined); char *saveptr = NULL; char *tok; int i; tok = strtok_r(copy, " ", &saveptr); for (i = 1; i <= 2; i++) { char *expected = (i == 1)? q1:q2; tok = strquotedstr(&saveptr); if (!tok) { g_fprintf(stderr, "while parsing '%s', call %d to strquotedstr returned NULL\n", combined, i); success = FALSE; goto next; } if (0 != strcmp(tok, expected)) { char *safe = safestr(tok); g_fprintf(stderr, "while parsing '%s', call %d to strquotedstr returned '%s' " "but '%s' was expected.\n", combined, i, safe, expected); success = FALSE; goto next; } } if (strquotedstr(&saveptr) != NULL) { g_fprintf(stderr, "while parsing '%s', call 3 to strquotedstr did not return NULL\n", combined); success = FALSE; goto next; } next: amfree(q1); amfree(q2); amfree(copy); amfree(combined); } } return success; }
static int delete_txinfofile( char * host, char * disk) { char *fn = NULL, *fn_new = NULL; int rc; char *myhost; char *mydisk; myhost = sanitise_filename(host); mydisk = sanitise_filename(disk); fn = vstralloc(infodir, "/", myhost, "/", mydisk, "/info", NULL); fn_new = stralloc2(fn, ".new"); amfree(myhost); amfree(mydisk); unlink(fn_new); amfree(fn_new); rc = rmpdir(fn, infodir); amfree(fn); return rc; }
printf_arglist_function1(void log_add, logtype_t, typ, char *, format) { va_list argp; char *leader = NULL; char *xlated_fmt = gettext(format); char linebuf[STR_SIZE]; size_t n; static gboolean in_log_add = 0; /* avoid recursion */ if (in_log_add) return; /* format error message */ if((int)typ <= (int)L_BOGUS || (int)typ > (int)L_MARKER) typ = L_BOGUS; if(multiline > 0) { leader = stralloc(" "); /* continuation line */ } else { leader = vstralloc(logtype_str[(int)typ], " ", get_pname(), " ", NULL); } arglist_start(argp, format); /* use sizeof(linebuf)-2 to save space for a trailing newline */ g_vsnprintf(linebuf, SIZEOF(linebuf)-2, xlated_fmt, argp); /* -1 to allow for '\n' */ arglist_end(argp); /* avoid recursive call from error() */ in_log_add = 1; /* append message to the log file */ if(multiline == -1) open_log(); if (full_write(logfd, leader, strlen(leader)) < strlen(leader)) { error(_("log file write error: %s"), strerror(errno)); /*NOTREACHED*/ } amfree(leader); /* add a newline if necessary */ n = strlen(linebuf); if(n == 0 || linebuf[n-1] != '\n') linebuf[n++] = '\n'; linebuf[n] = '\0'; if (full_write(logfd, linebuf, n) < n) { error(_("log file write error: %s"), strerror(errno)); /*NOTREACHED*/ } if(multiline != -1) multiline++; else close_log(); in_log_add = 0; }
int cd_glob( char * glob, int verbose) { char *regex; char *regex_path; char *s; char *uqglob; int result; char *path_on_disk = NULL; if (disk_name == NULL) { g_printf(_("Must select disk before changing directory\n")); return 0; } uqglob = unquote_string(glob); regex = glob_to_regex(uqglob); dbprintf(_("cd_glob (%s) -> %s\n"), uqglob, regex); if ((s = validate_regexp(regex)) != NULL) { g_printf(_("\"%s\" is not a valid shell wildcard pattern: "), glob); puts(s); amfree(regex); amfree(uqglob); return 0; } /* * glob_to_regex() anchors the beginning of the pattern with ^, * but we will be tacking it onto the end of the current directory * in add_file, so strip that off. Also, it anchors the end with * $, but we need to match a trailing /, add it if it is not there */ regex_path = stralloc(regex + 1); amfree(regex); if(regex_path[strlen(regex_path) - 2] != '/' ) { regex_path[strlen(regex_path) - 1] = '\0'; strappend(regex_path, "/$"); } /* convert path (assumed in cwd) to one on disk */ if (strcmp(disk_path, "/") == 0) path_on_disk = stralloc2("/", regex_path); else { char *clean_disk_path = clean_regex(disk_path, 0); path_on_disk = vstralloc(clean_disk_path, "/", regex_path, NULL); amfree(clean_disk_path); } result = cd_dir(path_on_disk, uqglob, verbose); amfree(regex_path); amfree(path_on_disk); amfree(uqglob); return result; }
int cd_regex( char * regex, int verbose) { char *s; char *uq_orig_regex; char *uqregex; int len_uqregex; int result; char *path_on_disk = NULL; if (disk_name == NULL) { g_printf(_("Must select disk before changing directory\n")); return 0; } uq_orig_regex = unquote_string(regex); uqregex = stralloc(uq_orig_regex); /* Add a terminating '/' if it is not there, maybe before a '$' */ len_uqregex = strlen(uqregex); if (uqregex[len_uqregex-1] == '$') { if (uqregex[len_uqregex-2] != '/') { uqregex[len_uqregex-1] = '\0'; strappend(uqregex, "/$"); } } else if (uqregex[len_uqregex-1] != '/') { //uqregex[len_uqregex-1] = '\0'; strappend(uqregex, "/"); } if ((s = validate_regexp(uqregex)) != NULL) { g_printf(_("\"%s\" is not a valid regular expression: "), uq_orig_regex); amfree(uqregex); amfree(uq_orig_regex); puts(s); return 0; } /* convert path (assumed in cwd) to one on disk */ if (strcmp(disk_path, "/") == 0) path_on_disk = stralloc2("/", uqregex); else { char *clean_disk_path = clean_regex(disk_path, 0); path_on_disk = vstralloc(clean_disk_path, "/", regex, NULL); amfree(clean_disk_path); } result = cd_dir(path_on_disk, uq_orig_regex, verbose); amfree(path_on_disk); amfree(uqregex); amfree(uq_orig_regex); return result; }
static FILE * open_txinfofile( char * host, char * disk, char * mode) { FILE *infof; char *myhost; char *mydisk; assert(infofile == (char *)0); writing = (*mode == 'w'); myhost = sanitise_filename(host); mydisk = sanitise_filename(disk); infofile = vstralloc(infodir, "/", myhost, "/", mydisk, "/info", NULL); amfree(myhost); amfree(mydisk); /* create the directory structure if in write mode */ if (writing) { if (mkpdir(infofile, 0755, (uid_t)-1, (gid_t)-1) == -1) { amfree(infofile); return NULL; } } newinfofile = stralloc2(infofile, ".new"); if(writing) { infof = fopen(newinfofile, mode); if(infof != NULL) amflock(fileno(infof), "info"); } else { infof = fopen(infofile, mode); /* no need to lock readers */ } if(infof == (FILE *)0) { amfree(infofile); amfree(newinfofile); return NULL; } return infof; }
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); 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); } if (argument->dle.include_list && argument->dle.include_list->nb_element >= 0) { fprintf(stdout, "ERROR include-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 (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); }
printf_arglist_function2(char *log_genstring, logtype_t, typ, char *, pname, char *, format) { va_list argp; char *leader = NULL; char linebuf[STR_SIZE]; char *xlated_fmt = dgettext("C", format); /* format error message */ if((int)typ <= (int)L_BOGUS || (int)typ > (int)L_MARKER) typ = L_BOGUS; if(multiline > 0) { leader = stralloc(" "); /* continuation line */ } else { leader = vstralloc(logtype_str[(int)typ], " ", pname, " ", NULL); } arglist_start(argp, format); g_vsnprintf(linebuf, SIZEOF(linebuf)-1, xlated_fmt, argp); /* -1 to allow for '\n' */ arglist_end(argp); return(vstralloc(leader, linebuf, "\n", NULL)); }
static void update_tapelist( taper_state_t *state) { char *tapelist_name = NULL; char *tapelist_name_old = NULL; tape_t *tp; char *comment = NULL; tapelist_name = config_dir_relative(getconf_str(CNF_TAPELIST)); if (state->cur_tape == 0) { tapelist_name_old = stralloc2(tapelist_name, ".yesterday"); } else { char cur_str[NUM_STR_SIZE]; g_snprintf(cur_str, SIZEOF(cur_str), "%d", state->cur_tape - 1); tapelist_name_old = vstralloc(tapelist_name, ".today.", cur_str, NULL); } if (read_tapelist(tapelist_name) != 0) { log_add(L_INFO, "pid-done %ld", (long)getpid()); error("could not load tapelist \"%s\"", tapelist_name); /*NOTREACHED*/ } /* make a copy of the tapelist file */ if (write_tapelist(tapelist_name_old)) { log_add(L_INFO, "pid-done %ld", (long)getpid()); error("could not write tapelist: %s", strerror(errno)); /*NOTREACHED*/ } amfree(tapelist_name_old); /* get a copy of the comment, before freeing the old record */ tp = lookup_tapelabel(state->device->volume_label); if (tp && tp->comment) comment = stralloc(tp->comment); /* edit the tapelist and rewrite it */ remove_tapelabel(state->device->volume_label); add_tapelabel(state->driver_start_time, state->device->volume_label, comment); if (write_tapelist(tapelist_name)) { error("could not write tapelist: %s", strerror(errno)); /*NOTREACHED*/ } amfree(tapelist_name); amfree(comment); }
static void cleanup_vtape_dir(char *device_path) { char *quoted = g_shell_quote(device_path); char *cmd = vstralloc("rm -rf ", quoted, NULL); /* would you rather write 'rm -rf' here? */ if (system(cmd) == -1) { exit(1); } amfree(cmd); amfree(quoted); }
static Device * setup_device(void) { Device *device; char *device_name = NULL; device_name = vstralloc("file:", device_path, NULL); device = device_open(device_name); if (device->status != DEVICE_STATUS_SUCCESS) { g_critical("Could not open device %s: %s\n", device_name, device_error(device)); } amfree(device_name); return device; }
static int test_split_quoted_strings(void) { char **iter1, **iter2, **iter3; gboolean success = TRUE; char *middle_strings[] = { "", "foo", "\"foo\"", "sp aces", NULL, }; /* the idea here is to loop over all triples of strings, forming a * string by quoting them with quote_string and inserting a space, then * re-splitting with split_quoted_string. This should get us back to our * starting point. */ for (iter1 = quotable_strings; *iter1; iter1++) { for (iter2 = middle_strings; *iter2; iter2++) { for (iter3 = quotable_strings; *iter3; iter3++) { char *q1 = quote_string(*iter1); char *q2 = quote_string(*iter2); char *q3 = quote_string(*iter3); const char *expected[4] = { *iter1, *iter2, *iter3, NULL }; char *combined = vstralloc(q1, " ", q2, " ", q3, NULL); char **tokens; tokens = split_quoted_strings(combined); success = compare_strv(expected, tokens, "split_quoted_strings", combined) && success; amfree(q1); amfree(q2); amfree(q3); amfree(combined); g_strfreev(tokens); } } } return success; }
static void amgtar_selfcheck( application_argument_t *argument) { amgtar_build_exinclude(&argument->dle, 1, NULL, NULL, NULL, NULL); printf("OK amgtar\n"); if (gnutar_path) { check_file(gnutar_path, X_OK); } else { printf(_("ERROR [GNUTAR program not available]\n")); } set_root_privs(1); if (gnutar_listdir && strlen(gnutar_listdir) == 0) gnutar_listdir = NULL; if (gnutar_listdir) { check_dir(gnutar_listdir, R_OK|W_OK); } else { 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) { check_dir(argument->dle.device, R_OK); } if (argument->calcsize) { char *calcsize = vstralloc(amlibexecdir, "/", "calcsize", versionsuffix(), NULL); check_file(calcsize, X_OK); check_suid(calcsize); amfree(calcsize); } set_root_privs(0); }
static void open_log(void) { char *conf_logdir; conf_logdir = config_dir_relative(getconf_str(CNF_LOGDIR)); logfile = vstralloc(conf_logdir, "/log", NULL); amfree(conf_logdir); logfd = open(logfile, O_WRONLY|O_CREAT|O_APPEND, 0600); if(logfd == -1) { error(_("could not open log file %s: %s"), logfile, strerror(errno)); /*NOTREACHED*/ } if(amflock(logfd, "log") == -1) { error(_("could not lock log file %s: %s"), logfile, strerror(errno)); /*NOTREACHED*/ } }
/* * Generate a debug file name. The name is based on the program name, * followed by a timestamp, an optional sequence number, and ".debug". * * @param t: timestamp * @param n: sequence number between 1 and 1000; if zero, no sequence number * is included. */ static char * get_debug_name( time_t t, int n) { char number[NUM_STR_SIZE]; char *ts; char *result; if(n < 0 || n > 1000) { return NULL; } ts = get_timestamp_from_time(t); if(n == 0) { number[0] = '\0'; } else { g_snprintf(number, SIZEOF(number), "%03d", n - 1); } result = vstralloc(get_pname(), ".", ts, number, ".debug", NULL); amfree(ts); return result; }
void cd_regex( char * regex) { char *s; char *uqregex; char *path_on_disk = NULL; if (disk_name == NULL) { g_printf(_("Must select disk before changing directory\n")); return; } uqregex = unquote_string(regex); if ((s = validate_regexp(uqregex)) != NULL) { g_printf(_("\"%s\" is not a valid regular expression: "), uqregex); amfree(uqregex); puts(s); return; } /* convert path (assumed in cwd) to one on disk */ if (strcmp(disk_path, "/") == 0) path_on_disk = stralloc2("/", regex); else { char *clean_disk_path = clean_regex(disk_path); path_on_disk = vstralloc(clean_disk_path, "/", regex, NULL); amfree(clean_disk_path); } cd_dir(path_on_disk, uqregex); amfree(path_on_disk); amfree(uqregex); }
void log_rename( char * datestamp) { char *conf_logdir; char *logfile; char *fname = NULL; char seq_str[NUM_STR_SIZE]; unsigned int seq; struct stat statbuf; if(datestamp == NULL) datestamp = "error"; conf_logdir = config_dir_relative(getconf_str(CNF_LOGDIR)); logfile = vstralloc(conf_logdir, "/log", NULL); for(seq = 0; 1; seq++) { /* if you've got MAXINT files in your dir... */ g_snprintf(seq_str, SIZEOF(seq_str), "%u", seq); fname = newvstralloc(fname, logfile, ".", datestamp, ".", seq_str, NULL); if(stat(fname, &statbuf) == -1 && errno == ENOENT) break; } if(rename(logfile, fname) == -1) { error(_("could not rename \"%s\" to \"%s\": %s"), logfile, fname, strerror(errno)); /*NOTREACHED*/ } amfree(fname); amfree(logfile); amfree(conf_logdir); }
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); amfree(qdisk); } if (argument->dle.device) { char *qdevice = quote_string(argument->dle.device); fprintf(stdout, "OK %s\n", qdevice); amfree(qdevice); } if (!star_path) { fprintf(stdout, "ERROR STAR-PATH not defined\n"); } else { 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); } }
/* * Negotiate a krb5 gss context from the client end. */ static int gss_client( struct sec_handle *rh) { struct sec_stream *rs = rh->rs; struct tcp_conn *rc = rs->rc; gss_buffer_desc send_tok, recv_tok, AA; gss_OID doid; OM_uint32 maj_stat, min_stat; unsigned int ret_flags; int rval = -1; int rvalue; gss_name_t gss_name; char *errmsg = NULL; auth_debug(1, "gss_client\n"); send_tok.value = vstralloc("host/", rs->rc->hostname, NULL); send_tok.length = strlen(send_tok.value) + 1; maj_stat = gss_import_name(&min_stat, &send_tok, GSS_C_NULL_OID, &gss_name); if (maj_stat != (OM_uint32)GSS_S_COMPLETE) { security_seterror(&rh->sech, _("can't import name %s: %s"), (char *)send_tok.value, gss_error(maj_stat, min_stat)); amfree(send_tok.value); return (-1); } amfree(send_tok.value); rc->gss_context = GSS_C_NO_CONTEXT; maj_stat = gss_display_name(&min_stat, gss_name, &AA, &doid); dbprintf(_("gss_name %s\n"), (char *)AA.value); /* * Perform the context-establishement loop. * * Every generated token is stored in send_tok which is then * transmitted to the server; every received token is stored in * recv_tok (empty on the first pass) to be processed by * the next call to gss_init_sec_context. * * GSS-API guarantees that send_tok's length will be non-zero * if and only if the server is expecting another token from us, * and that gss_init_sec_context returns GSS_S_CONTINUE_NEEDED if * and only if the server has another token to send us. */ recv_tok.value = NULL; for (recv_tok.length = 0;;) { min_stat = 0; maj_stat = gss_init_sec_context(&min_stat, GSS_C_NO_CREDENTIAL, &rc->gss_context, gss_name, GSS_C_NULL_OID, (OM_uint32)GSS_C_MUTUAL_FLAG|GSS_C_REPLAY_FLAG, 0, NULL, /* no channel bindings */ (recv_tok.length == 0 ? GSS_C_NO_BUFFER : &recv_tok), NULL, /* ignore mech type */ &send_tok, &ret_flags, NULL); /* ignore time_rec */ if (recv_tok.length != 0) { amfree(recv_tok.value); recv_tok.length = 0; } if (maj_stat != (OM_uint32)GSS_S_COMPLETE && maj_stat != (OM_uint32)GSS_S_CONTINUE_NEEDED) { security_seterror(&rh->sech, _("error getting gss context: %s %s"), gss_error(maj_stat, min_stat), (char *)send_tok.value); goto done; } /* * Send back the response */ if (send_tok.length != 0 && tcpm_send_token(rc, rc->write, rs->handle, &errmsg, send_tok.value, send_tok.length) < 0) { security_seterror(&rh->sech, "%s", rc->errmsg); gss_release_buffer(&min_stat, &send_tok); goto done; } gss_release_buffer(&min_stat, &send_tok); /* * If we need to continue, then register for more packets */ if (maj_stat != (OM_uint32)GSS_S_CONTINUE_NEEDED) break; rvalue = tcpm_recv_token(rc, rc->read, &rc->handle, &rc->errmsg, (void *)&recv_tok.value, (ssize_t *)&recv_tok.length, 60); if (rvalue <= 0) { if (rvalue < 0) security_seterror(&rh->sech, _("recv error in gss loop: %s"), rc->errmsg); else security_seterror(&rh->sech, _("EOF in gss loop")); goto done; } } rval = 0; rc->auth = 1; done: gss_release_name(&min_stat, &gss_name); return (rval); }
void run_server_script( pp_script_t *pp_script, execute_on_t execute_on, char *config, disk_t *dp, int level) { pid_t scriptpid; int scriptin, scriptout, scripterr; char *cmd; char *command = NULL; GPtrArray *argv_ptr = g_ptr_array_new(); FILE *streamout; char *line; char *plugin; char level_number[NUM_STR_SIZE]; if ((pp_script_get_execute_on(pp_script) & execute_on) == 0) return; if (pp_script_get_execute_where(pp_script) != ES_SERVER) return; plugin = pp_script_get_plugin(pp_script); cmd = vstralloc(APPLICATION_DIR, "/", plugin, NULL); g_ptr_array_add(argv_ptr, stralloc(plugin)); switch (execute_on) { case EXECUTE_ON_PRE_DLE_AMCHECK: command = "PRE-DLE-AMCHECK"; break; case EXECUTE_ON_PRE_HOST_AMCHECK: command = "PRE-HOST-AMCHECK"; break; case EXECUTE_ON_POST_DLE_AMCHECK: command = "POST-DLE-AMCHECK"; break; case EXECUTE_ON_POST_HOST_AMCHECK: command = "POST-HOST-AMCHECK"; break; case EXECUTE_ON_PRE_DLE_ESTIMATE: command = "PRE-DLE-ESTIMATE"; break; case EXECUTE_ON_PRE_HOST_ESTIMATE: command = "PRE-HOST-ESTIMATE"; break; case EXECUTE_ON_POST_DLE_ESTIMATE: command = "POST-DLE-ESTIMATE"; break; case EXECUTE_ON_POST_HOST_ESTIMATE: command = "POST-HOST-ESTIMATE"; break; case EXECUTE_ON_PRE_DLE_BACKUP: command = "PRE-DLE-BACKUP"; break; case EXECUTE_ON_PRE_HOST_BACKUP: command = "PRE-HOST-BACKUP"; break; case EXECUTE_ON_POST_DLE_BACKUP: command = "POST-DLE-BACKUP"; break; case EXECUTE_ON_POST_HOST_BACKUP: command = "POST-HOST-BACKUP"; break; case EXECUTE_ON_PRE_RECOVER: case EXECUTE_ON_POST_RECOVER: case EXECUTE_ON_PRE_LEVEL_RECOVER: case EXECUTE_ON_POST_LEVEL_RECOVER: case EXECUTE_ON_INTER_LEVEL_RECOVER: { // ERROR these script can't be executed on server. return; } } g_ptr_array_add(argv_ptr, stralloc(command)); g_ptr_array_add(argv_ptr, stralloc("--execute-where")); g_ptr_array_add(argv_ptr, stralloc("server")); if (config) { g_ptr_array_add(argv_ptr, stralloc("--config")); g_ptr_array_add(argv_ptr, stralloc(config)); } if (dp->host->hostname) { g_ptr_array_add(argv_ptr, stralloc("--host")); g_ptr_array_add(argv_ptr, stralloc(dp->host->hostname)); } if (dp->name) { g_ptr_array_add(argv_ptr, stralloc("--disk")); g_ptr_array_add(argv_ptr, stralloc(dp->name)); } if (dp->device) { g_ptr_array_add(argv_ptr, stralloc("--device")); g_ptr_array_add(argv_ptr, stralloc(dp->device)); } if (level >= 0) { g_snprintf(level_number, SIZEOF(level_number), "%d", level); g_ptr_array_add(argv_ptr, stralloc("--level")); g_ptr_array_add(argv_ptr, stralloc(level_number)); } property_add_to_argv(argv_ptr, pp_script_get_property(pp_script)); g_ptr_array_add(argv_ptr, NULL); scripterr = fileno(stderr); scriptpid = pipespawnv(cmd, STDIN_PIPE|STDOUT_PIPE, 0, &scriptin, &scriptout, &scripterr, (char **)argv_ptr->pdata); close(scriptin); streamout = fdopen(scriptout, "r"); if (streamout) { while((line = agets(streamout)) != NULL) { dbprintf("script: %s\n", line); } } fclose(streamout); waitpid(scriptpid, NULL, 0); g_ptr_array_free_full(argv_ptr); }
int main( int argc, char ** argv) { char *logfname; char *conf_logdir; FILE *logfile; config_overrides_t *cfg_ovr = NULL; char *cfg_opt = NULL; /* * Configure program for internationalization: * 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"); safe_fd(-1, 0); set_pname("amlogroll"); dbopen(DBG_SUBDIR_SERVER); add_amanda_log_handler(amanda_log_stderr); /* Process options */ cfg_ovr = extract_commandline_config_overrides(&argc, &argv); if (argc >= 2) { cfg_opt = argv[1]; } /* read configuration files */ set_config_overrides(cfg_ovr); config_init(CONFIG_INIT_EXPLICIT_NAME | CONFIG_INIT_USE_CWD, cfg_opt); if (config_errors(NULL) >= CFGERR_WARNINGS) { config_print_errors(); if (config_errors(NULL) >= CFGERR_ERRORS) { g_critical(_("errors processing config file")); } } safe_cd(); /* must happen after config_init */ check_running_as(RUNNING_AS_DUMPUSER); dbrename(get_config_name(), DBG_SUBDIR_SERVER); conf_logdir = config_dir_relative(getconf_str(CNF_LOGDIR)); logfname = vstralloc(conf_logdir, "/", "log", NULL); amfree(conf_logdir); if((logfile = fopen(logfname, "r")) == NULL) { error(_("could not open log %s: %s"), logfname, strerror(errno)); /*NOTREACHED*/ } amfree(logfname); add_amanda_log_handler(amanda_log_trace_log); while(get_logline(logfile)) { if(curlog == L_START) { handle_start(); if(datestamp != NULL) { break; } } } afclose(logfile); log_rename(datestamp); amfree(datestamp); dbclose(); return 0; }
/* Open a socket to the dumper. Returns TRUE if everything is happy, FALSE otherwise. */ static gboolean open_read_socket(dump_info_t * info, char * split_diskbuffer, guint64 splitsize, guint64 fallback_splitsize) { in_port_t port = 0; int socket; int fd; int result; struct addrinfo *res; if ((result = resolve_hostname("localhost", 0, &res, NULL) != 0)) { char *m; char *q; int save_errno = errno; char *qdiskname = quote_string(info->diskname); m = vstralloc("[localhost resolve failure: ", strerror(save_errno), "]", NULL); q = quote_string(m); putresult(TAPE_ERROR, "%s %s\n", info->handle, q); log_add(L_FAIL, "%s %s %s %d %s", info->hostname, qdiskname, info->timestamp, info->level, q); amfree(qdiskname); amfree(m); amfree(q); return FALSE; } socket = stream_server(res->ai_family, &port, 0, STREAM_BUFSIZE, 0); freeaddrinfo(res); if (socket < 0) { char *m; char *q; int save_errno = errno; char *qdiskname = quote_string(info->diskname); m = vstralloc("[port create failure: ", strerror(save_errno), "]", NULL); q = quote_string(m); putresult(TAPE_ERROR, "%s %s\n", info->handle, q); log_add(L_FAIL, "%s %s %s %d %s", info->hostname, qdiskname, info->timestamp, info->level, q); amfree(qdiskname); amfree(m); amfree(q); return FALSE; } putresult(PORT, "%d\n", port); fd = stream_accept(socket, CONNECT_TIMEOUT, 0, STREAM_BUFSIZE); if (fd < 0) { char *m, *q; int save_errno = errno; char *qdiskname = quote_string(info->diskname); m = vstralloc("[port connect failure: ", strerror(save_errno), "]", NULL); q = quote_string(m); putresult(TAPE_ERROR, "%s %s\n", info->handle, q); log_add(L_FAIL, "%s %s %s %d %s", info->hostname, qdiskname, info->timestamp, info->level, q); amfree(qdiskname); aclose(socket); amfree(m); amfree(q); return FALSE; } else { aclose(socket); } info->source = taper_source_new(info->handle, PORT_WRITE, NULL, fd, split_diskbuffer, splitsize, fallback_splitsize); /* FIXME: This should be handled properly. */ g_assert(info->source != NULL); return TRUE; }
int main( int argc, char ** argv) { disklist_t diskl; int no_keep; /* files per system to keep */ char **output_find_log; DIR *dir; struct dirent *adir; char **name; int useful; char *olddir; char *oldfile = NULL, *newfile = NULL; time_t today, date_keep; char *logname = NULL; struct stat stat_log; struct stat stat_old; char *conf_diskfile; char *conf_tapelist; char *conf_logdir; int dumpcycle; config_overwrites_t *cfg_ovr = NULL; /* * Configure program for internationalization: * 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"); safe_fd(-1, 0); safe_cd(); set_pname("amtrmlog"); /* Don't die when child closes pipe */ signal(SIGPIPE, SIG_IGN); cfg_ovr = extract_commandline_config_overwrites(&argc, &argv); if (argc > 1 && strcmp(argv[1], "-t") == 0) { amtrmidx_debug = 1; argc--; argv++; } if (argc < 2) { g_fprintf(stderr, _("Usage: %s [-t] <config> [-o configoption]*\n"), argv[0]); return 1; } dbopen(DBG_SUBDIR_SERVER); dbprintf(_("%s: version %s\n"), argv[0], version()); config_init(CONFIG_INIT_EXPLICIT_NAME, argv[1]); apply_config_overwrites(cfg_ovr); conf_diskfile = config_dir_relative(getconf_str(CNF_DISKFILE)); read_diskfile(conf_diskfile, &diskl); amfree(conf_diskfile); if (config_errors(NULL) >= CFGERR_WARNINGS) { config_print_errors(); if (config_errors(NULL) >= CFGERR_ERRORS) { g_critical(_("errors processing config file")); } } check_running_as(RUNNING_AS_DUMPUSER); dbrename(get_config_name(), DBG_SUBDIR_SERVER); conf_tapelist = config_dir_relative(getconf_str(CNF_TAPELIST)); if (read_tapelist(conf_tapelist)) { error(_("could not load tapelist \"%s\""), conf_tapelist); /*NOTREACHED*/ } amfree(conf_tapelist); today = time((time_t *)NULL); dumpcycle = getconf_int(CNF_DUMPCYCLE); if(dumpcycle > 5000) dumpcycle = 5000; date_keep = today - (dumpcycle * 86400); output_find_log = find_log(); /* determine how many log to keep */ no_keep = getconf_int(CNF_TAPECYCLE) * 2; dbprintf(plural(_("Keeping %d log file\n"), _("Keeping %d log files\n"), no_keep), no_keep); conf_logdir = config_dir_relative(getconf_str(CNF_LOGDIR)); olddir = vstralloc(conf_logdir, "/oldlog", NULL); if (mkpdir(olddir, 0700, (uid_t)-1, (gid_t)-1) != 0) { error(_("could not create parents of %s: %s"), olddir, strerror(errno)); /*NOTREACHED*/ } if (mkdir(olddir, 0700) != 0 && errno != EEXIST) { error(_("could not create %s: %s"), olddir, strerror(errno)); /*NOTREACHED*/ } if (stat(olddir,&stat_old) == -1) { error(_("can't stat oldlog directory \"%s\": %s"), olddir, strerror(errno)); /*NOTREACHED*/ } if (!S_ISDIR(stat_old.st_mode)) { error(_("Oldlog directory \"%s\" is not a directory"), olddir); /*NOTREACHED*/ } if ((dir = opendir(conf_logdir)) == NULL) { error(_("could not open log directory \"%s\": %s"), conf_logdir,strerror(errno)); /*NOTREACHED*/ } while ((adir=readdir(dir)) != NULL) { if(strncmp(adir->d_name,"log.",4)==0) { useful=0; for (name=output_find_log;*name !=NULL; name++) { if((strlen(adir->d_name) >= 13 && strlen(*name) >= 13 && adir->d_name[12] == '.' && (*name)[12] == '.' && strncmp(adir->d_name,*name,12)==0) || strncmp(adir->d_name,*name,18)==0) { useful=1; break; } } logname=newvstralloc(logname, conf_logdir, "/" ,adir->d_name, NULL); if(stat(logname,&stat_log)==0) { if((time_t)stat_log.st_mtime > date_keep) { useful = 1; } } if(useful == 0) { oldfile = newvstralloc(oldfile, conf_logdir, "/", adir->d_name, NULL); newfile = newvstralloc(newfile, olddir, "/", adir->d_name, NULL); if (rename(oldfile,newfile) != 0) { error(_("could not rename \"%s\" to \"%s\": %s"), oldfile, newfile, strerror(errno)); /*NOTREACHED*/ } } } } closedir(dir); for (name = output_find_log; *name != NULL; name++) { amfree(*name); } amfree(output_find_log); amfree(logname); amfree(oldfile); amfree(newfile); amfree(olddir); amfree(conf_logdir); clear_tapelist(); free_disklist(&diskl); dbclose(); return 0; }
/* * Negotiate a krb5 gss context from the server end. */ static int gss_server( struct tcp_conn *rc) { OM_uint32 maj_stat, min_stat, ret_flags; gss_buffer_desc send_tok, recv_tok, AA; gss_OID doid; gss_name_t gss_name; gss_cred_id_t gss_creds; char *p, *realm, *msg; int rval = -1; int rvalue; char errbuf[256]; char *errmsg = NULL; auth_debug(1, "gss_server\n"); assert(rc != NULL); /* * We need to be root while in gss_acquire_cred() to read the host key * out of the default keytab. We also need to be root in * gss_accept_context() thanks to the replay cache code. */ if (!set_root_privs(0)) { g_snprintf(errbuf, SIZEOF(errbuf), _("can't take root privileges to read krb5 host key: %s"), strerror(errno)); goto out; } rc->gss_context = GSS_C_NO_CONTEXT; send_tok.value = vstralloc("host/", myhostname, NULL); send_tok.length = strlen(send_tok.value) + 1; for (p = send_tok.value; *p != '\0'; p++) { if (isupper((int)*p)) *p = tolower(*p); } maj_stat = gss_import_name(&min_stat, &send_tok, GSS_C_NULL_OID, &gss_name); if (maj_stat != (OM_uint32)GSS_S_COMPLETE) { set_root_privs(0); g_snprintf(errbuf, SIZEOF(errbuf), _("can't import name %s: %s"), (char *)send_tok.value, gss_error(maj_stat, min_stat)); amfree(send_tok.value); goto out; } amfree(send_tok.value); maj_stat = gss_display_name(&min_stat, gss_name, &AA, &doid); dbprintf(_("gss_name %s\n"), (char *)AA.value); maj_stat = gss_acquire_cred(&min_stat, gss_name, 0, GSS_C_NULL_OID_SET, GSS_C_ACCEPT, &gss_creds, NULL, NULL); if (maj_stat != (OM_uint32)GSS_S_COMPLETE) { g_snprintf(errbuf, SIZEOF(errbuf), _("can't acquire creds for host key host/%s: %s"), myhostname, gss_error(maj_stat, min_stat)); gss_release_name(&min_stat, &gss_name); set_root_privs(0); goto out; } gss_release_name(&min_stat, &gss_name); for (recv_tok.length = 0;;) { recv_tok.value = NULL; rvalue = tcpm_recv_token(rc, rc->read, &rc->handle, &rc->errmsg, /* (void *) is to avoid type-punning warning */ (char **)(void *)&recv_tok.value, (ssize_t *)&recv_tok.length, 60); if (rvalue <= 0) { if (rvalue < 0) { g_snprintf(errbuf, SIZEOF(errbuf), _("recv error in gss loop: %s"), rc->errmsg); amfree(rc->errmsg); } else g_snprintf(errbuf, SIZEOF(errbuf), _("EOF in gss loop")); goto out; } maj_stat = gss_accept_sec_context(&min_stat, &rc->gss_context, gss_creds, &recv_tok, GSS_C_NO_CHANNEL_BINDINGS, &gss_name, &doid, &send_tok, &ret_flags, NULL, NULL); if (maj_stat != (OM_uint32)GSS_S_COMPLETE && maj_stat != (OM_uint32)GSS_S_CONTINUE_NEEDED) { g_snprintf(errbuf, SIZEOF(errbuf), _("error accepting context: %s"), gss_error(maj_stat, min_stat)); amfree(recv_tok.value); goto out; } amfree(recv_tok.value); if (send_tok.length != 0 && tcpm_send_token(rc, rc->write, 0, &errmsg, send_tok.value, send_tok.length) < 0) { strncpy(errbuf, rc->errmsg, SIZEOF(errbuf) - 1); errbuf[SIZEOF(errbuf) - 1] = '\0'; amfree(rc->errmsg); gss_release_buffer(&min_stat, &send_tok); goto out; } gss_release_buffer(&min_stat, &send_tok); /* * If we need to get more from the client, then register for * more packets. */ if (maj_stat != (OM_uint32)GSS_S_CONTINUE_NEEDED) break; } maj_stat = gss_display_name(&min_stat, gss_name, &send_tok, &doid); if (maj_stat != (OM_uint32)GSS_S_COMPLETE) { g_snprintf(errbuf, SIZEOF(errbuf), _("can't display gss name: %s"), gss_error(maj_stat, min_stat)); gss_release_name(&min_stat, &gss_name); goto out; } gss_release_name(&min_stat, &gss_name); /* get rid of the realm */ if ((p = strchr(send_tok.value, '@')) == NULL) { g_snprintf(errbuf, SIZEOF(errbuf), _("malformed gss name: %s"), (char *)send_tok.value); amfree(send_tok.value); goto out; } *p = '\0'; realm = ++p; /* * If the principal doesn't match, complain */ if ((msg = krb5_checkuser(rc->hostname, send_tok.value, realm)) != NULL) { g_snprintf(errbuf, SIZEOF(errbuf), _("access not allowed from %s: %s"), (char *)send_tok.value, msg); amfree(send_tok.value); goto out; } amfree(send_tok.value); rval = 0; out: set_root_privs(0); if (rval != 0) { rc->errmsg = stralloc(errbuf); } else { rc->auth = 1; } auth_debug(1, _("gss_server returning %d\n"), rval); return (rval); }
/* * Forks a ssh to the host listed in rc->hostname * Returns negative on error, with an errmsg in rc->errmsg. */ static int runssh( struct tcp_conn * rc, const char * amandad_path, const char * client_username, const char * ssh_keys) { int rpipe[2], wpipe[2]; char *xamandad_path = (char *)amandad_path; char *xclient_username = (char *)client_username; char *xssh_keys = (char *)ssh_keys; memset(rpipe, -1, SIZEOF(rpipe)); memset(wpipe, -1, SIZEOF(wpipe)); if (pipe(rpipe) < 0 || pipe(wpipe) < 0) { rc->errmsg = newvstrallocf(rc->errmsg, _("pipe: %s"), strerror(errno)); return (-1); } switch (rc->pid = fork()) { case -1: rc->errmsg = newvstrallocf(rc->errmsg, _("fork: %s"), strerror(errno)); aclose(rpipe[0]); aclose(rpipe[1]); aclose(wpipe[0]); aclose(wpipe[1]); return (-1); case 0: dup2(wpipe[0], 0); dup2(rpipe[1], 1); break; default: rc->read = rpipe[0]; aclose(rpipe[1]); rc->write = wpipe[1]; aclose(wpipe[0]); return (0); } safe_fd(-1, 0); if(!xamandad_path || strlen(xamandad_path) <= 1) xamandad_path = vstralloc(amlibexecdir, "/", "amandad", versionsuffix(), NULL); if(!xclient_username || strlen(xclient_username) <= 1) xclient_username = CLIENT_LOGIN; if(!ssh_keys || strlen(ssh_keys) <= 1) { execlp(SSH, SSH, SSH_OPTIONS, "-l", xclient_username, rc->hostname, xamandad_path, "-auth=ssh", "amdump", "amindexd", "amidxtaped", (char *)NULL); } else { execlp(SSH, SSH, SSH_OPTIONS, "-l", xclient_username, "-i", xssh_keys, rc->hostname, xamandad_path, "-auth=ssh", "amdump", "amindexd", "amidxtaped", (char *)NULL); } error("error: couldn't exec %s: %s", SSH, strerror(errno)); /* should never go here, shut up compiler warning */ return(-1); }
static void amgtar_restore( application_argument_t *argument) { char *cmd; GPtrArray *argv_ptr = g_ptr_array_new(); char **env; int j; char *e; char *include_filename = NULL; char *exclude_filename = NULL; int tarpid; if (!gnutar_path) { error(_("GNUTAR-PATH not defined")); } cmd = stralloc(gnutar_path); g_ptr_array_add(argv_ptr, stralloc(gnutar_path)); g_ptr_array_add(argv_ptr, stralloc("--numeric-owner")); if (gnutar_no_unquote) g_ptr_array_add(argv_ptr, stralloc("--no-unquote")); if (gnutar_acls) g_ptr_array_add(argv_ptr, stralloc("--acls")); if (gnutar_selinux) 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) */ g_ptr_array_add(argv_ptr, stralloc("--ignore-zeros")); g_ptr_array_add(argv_ptr, stralloc("-xpGvf")); g_ptr_array_add(argv_ptr, stralloc("-")); if (gnutar_directory) { struct stat stat_buf; if(stat(gnutar_directory, &stat_buf) != 0) { fprintf(stderr,"can not stat directory %s: %s\n", gnutar_directory, strerror(errno)); exit(1); } if (!S_ISDIR(stat_buf.st_mode)) { fprintf(stderr,"%s is not a directory\n", gnutar_directory); exit(1); } if (access(gnutar_directory, W_OK) != 0) { fprintf(stderr, "Can't write to %s: %s\n", gnutar_directory, strerror(errno)); exit(1); } g_ptr_array_add(argv_ptr, stralloc("--directory")); g_ptr_array_add(argv_ptr, stralloc(gnutar_directory)); } g_ptr_array_add(argv_ptr, stralloc("--wildcards")); if (argument->dle.exclude_list && argument->dle.exclude_list->nb_element == 1) { FILE *exclude; char *sdisk; int in_argv; int entry_in_exclude = 0; char line[2*PATH_MAX]; FILE *exclude_list; if (argument->dle.disk) { sdisk = sanitise_filename(argument->dle.disk); } else { sdisk = g_strdup_printf("no_dle-%d", getpid()); } exclude_filename= vstralloc(AMANDA_TMPDIR, "/", "exclude-", sdisk, NULL); exclude_list = fopen(argument->dle.exclude_list->first->name, "r"); exclude = fopen(exclude_filename, "w"); while (fgets(line, 2*PATH_MAX, exclude_list)) { char *escaped; line[strlen(line)-1] = '\0'; /* remove '\n' */ escaped = escape_tar_glob(line, &in_argv); if (in_argv) { g_ptr_array_add(argv_ptr, "--exclude"); g_ptr_array_add(argv_ptr, escaped); } else { fprintf(exclude,"%s\n", escaped); entry_in_exclude++; amfree(escaped); } } fclose(exclude); g_ptr_array_add(argv_ptr, stralloc("--exclude-from")); g_ptr_array_add(argv_ptr, exclude_filename); } if (argument->exclude_list_glob) { g_ptr_array_add(argv_ptr, stralloc("--exclude-from")); g_ptr_array_add(argv_ptr, stralloc(argument->exclude_list_glob)); } { GPtrArray *argv_include = g_ptr_array_new(); FILE *include; char *sdisk; int in_argv; guint i; int entry_in_include = 0; if (argument->dle.disk) { sdisk = sanitise_filename(argument->dle.disk); } else { sdisk = g_strdup_printf("no_dle-%d", getpid()); } 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]; FILE *include_list = fopen(argument->dle.include_list->first->name, "r"); while (fgets(line, 2*PATH_MAX, include_list)) { char *escaped; line[strlen(line)-1] = '\0'; /* remove '\n' */ escaped = escape_tar_glob(line, &in_argv); if (in_argv) { g_ptr_array_add(argv_include, escaped); } else { fprintf(include,"%s\n", escaped); entry_in_include++; amfree(escaped); } } } for (j=1; j< argument->argc; j++) { char *escaped = escape_tar_glob(argument->argv[j], &in_argv); if (in_argv) { g_ptr_array_add(argv_include, escaped); } else { fprintf(include,"%s\n", escaped); entry_in_include++; amfree(escaped); } } fclose(include); if (entry_in_include) { g_ptr_array_add(argv_ptr, stralloc("--files-from")); g_ptr_array_add(argv_ptr, include_filename); } if (argument->include_list_glob) { g_ptr_array_add(argv_ptr, stralloc("--files-from")); g_ptr_array_add(argv_ptr, stralloc(argument->include_list_glob)); } for (i = 0; i < argv_include->len; i++) { g_ptr_array_add(argv_ptr, (char *)g_ptr_array_index(argv_include,i)); } } g_ptr_array_add(argv_ptr, NULL); debug_executing(argv_ptr); 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); } }