void XParam::saveXmlDoc(string xdoc, bool show_runtime, const int &indent, bool with_endl) const throw (Exception) { string sxml; try { sxml = xml(show_runtime, indent, with_endl); } catch (std::exception &e) { throw Exception("Can't generate xml to save " + get_pname() + " !: " + e.what(), TracePoint("pparam")); } std::fstream xfile; try { xfile.open(xdoc.c_str(), std::ios_base::trunc | std::ios_base::out); } catch (std::exception &e) { throw Exception("Can't open file to save " + get_pname() + " !: " + e.what(), TracePoint("pparam")); } if (xfile.fail()) throw Exception("Can't open file to save " + get_pname() + " !", TracePoint("pparam")); xfile << sxml; xfile.close(); }
void parse_backup_messages( dle_t *dle, int mesgin) { int goterror; char *line; amfree(errorstr); for(; (line = areads(mesgin)) != NULL; free(line)) { process_dumpline(line); } if(errno) { error(_("error [read mesg pipe: %s]"), strerror(errno)); /*NOTREACHED*/ } goterror = check_result(mesgfd); if(errorstr) { error(_("error [%s]"), errorstr); /*NOTREACHED*/ } else if(dump_size == -1) { error(_("error [no backup size line]")); /*NOTREACHED*/ } program->end_backup(dle, goterror); fdprintf(mesgfd, _("%s: size %ld\n"), get_pname(), dump_size); fdprintf(mesgfd, _("%s: end\n"), get_pname()); }
int cmp(const void *a, const void *b) { char *pa; char *pb; pa=get_pname(*(char **)a); pb=get_pname(*(char **)b); return strcmp(pa, pb); }
int get_line(void) { char *line = NULL; char *part = NULL; size_t len; while(1) { if((part = areads(server_socket)) == NULL) { int save_errno = errno; if(server_line) { fputs(server_line, stderr); /* show the last line read */ fputc('\n', stderr); } if(save_errno != 0) { g_fprintf(stderr, _("%s: Error reading line from server: %s\n"), get_pname(), strerror(save_errno)); } else { g_fprintf(stderr, _("%s: Unexpected end of file, check amindexd*debug on server %s\n"), get_pname(), server_name); } errno = save_errno; break; /* exit while loop */ } if(line) { strappend(line, part); amfree(part); } else { line = part; part = NULL; } if((len = strlen(line)) > 0 && line[len-1] == '\r') { line[len-1] = '\0'; g_free(server_line); server_line = g_strdup(line); amfree(line); return 0; } /* * Hmmm. We got a "line" from areads(), which means it saw * a '\n' (or EOF, etc), but there was not a '\r' before it. * Put a '\n' back in the buffer and loop for more. */ strappend(line, "\n"); } amfree(line); amfree(server_line); return -1; }
/* * Open file descriptor for current disk (cur_file) * with "p0" path or cur_disk->disk_path */ void open_cur_file(int mode) { char *dkpath; char pbuf[MAXPATHLEN]; switch (mode) { case FD_USE_P0_PATH: (void) get_pname(&pbuf[0]); dkpath = pbuf; break; case FD_USE_CUR_DISK_PATH: if (cur_disk->fdisk_part.systid == SUNIXOS || cur_disk->fdisk_part.systid == SUNIXOS2) { (void) get_sname(&pbuf[0]); dkpath = pbuf; } else { dkpath = cur_disk->disk_path; } break; default: err_print("Error: Invalid mode option for opening cur_file\n"); fullabort(); } /* Close previous cur_file */ (void) close(cur_file); /* Open cur_file with the required path dkpath */ if ((cur_file = open_disk(dkpath, O_RDWR | O_NDELAY)) < 0) { err_print( "Error: can't open selected disk '%s'.\n", dkpath); fullabort(); } }
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; }
void log_add(logtype_t typ, char *format, ...) { va_list argp; arglist_start(argp, format); log_add_full_v(typ, get_pname(), format, argp); arglist_end(argp); }
void plot_output( double *t, ///< time (I) double *xd, ///< differential states (I) double *xa, ///< algebraic states (I) double *u, ///< controls (I) double *p_free, ///< global model parameters (I) double *rwh, ///< real work array (I) long *iwh, ///< integer work array (I) InfoPtr *info ){ FILE *fp; stringstream output_filename(""); // Filename char problemname[50]; get_pname(problemname); output_filename << "./RES/" << problemname <<".plt"; if (*t == 0) fp = fopen(output_filename.str().c_str(), "w"); else fp = fopen(output_filename.str().c_str(), "a"); if (!fp) { fprintf(stderr, "Error: Could not open file '%s'!\n", output_filename.str().c_str()); return; } if (*t == 0) { // write header: /// Get names of model quantities. char **xd_name[1]; /* differential state names (O) */ char **xa_name[1]; /* algebraic state names (O) */ char **u_name[1]; /* control names (O) */ char **h_name[1]; /* model stage duration names (O) */ char **p_name[1]; /* global model parameter names (O) */ char *of_name[1]; /* objective name (O) */ get_names(xd_name, xa_name, u_name, h_name, p_name, of_name); fprintf(fp, "//time\t"); for (int i = 0; i<NY; i++){ fprintf(fp, "%s\t",xd_name[0][i]); } for (int i = 0; i<NU; i++){ fprintf(fp, "%s\t",u_name[0][i]); } fprintf(fp, "\n"); } fprintf(fp, "%e\t", *t); for (int i = 0; i<NY; i++){ fprintf(fp, "%e\t",xd[i]); } for (int i = 0; i<NU; i++){ fprintf(fp, "%e\t",u[i]); } fprintf(fp, "\n"); // Close file fclose(fp); }
/* The tape drive does not have an idea of current slot so * we use a file to store the current slot. It is not ideal * but it gets the job done */ int get_current_slot(char *count_file) { FILE *inf; int retval; if ((inf=fopen(count_file,"r")) == NULL) { g_fprintf(stderr, _("%s: unable to open current slot file (%s)\n"), get_pname(), count_file); return 0; } if (fscanf(inf, "%d", &retval) != 1) { g_fprintf(stderr, _("%s: unable to read current slot file (%s)\n"), get_pname(), count_file); retval = 0; } fclose(inf); return retval; }
void put_current_slot(char *count_file,int slot) { FILE *inf; if ((inf=fopen(count_file,"w")) == NULL) { g_fprintf(stderr, _("%s: unable to open current slot file (%s)\n"), get_pname(), count_file); exit(2); } g_fprintf(inf, "%d\n", slot); fclose(inf); }
static void strange_header( dumpfile_t *file, const char *buffer, size_t buflen, const char *expected, const char *actual) { if (actual == NULL) actual = "<null>"; if (expected == NULL) expected = "<null>"; g_fprintf(stderr, _("%s: strange amanda header: \"%.*s\"\n"), get_pname(), (int)buflen, buffer); g_fprintf(stderr, _("%s: Expected: \"%s\" Actual: \"%s\"\n"), get_pname(), expected, actual); file->type = F_WEIRD; }
/* *Send header info to the message file. */ void info_tapeheader( dle_t *dle) { g_fprintf(stderr, "%s: info BACKUP=%s\n", get_pname(), program->backup_name); g_fprintf(stderr, "%s: info RECOVER_CMD=", get_pname()); if (dle->compress == COMP_FAST || dle->compress == COMP_BEST) g_fprintf(stderr, "%s %s |", UNCOMPRESS_PATH, #ifdef UNCOMPRESS_OPT UNCOMPRESS_OPT #else "" #endif ); g_fprintf(stderr, "%s -xpGf - ...\n", program->restore_name); if (dle->compress == COMP_FAST || dle->compress == COMP_BEST) g_fprintf(stderr, "%s: info COMPRESS_SUFFIX=%s\n", get_pname(), COMPRESS_SUFFIX); g_fprintf(stderr, "%s: info end\n", get_pname()); }
XParam& XFloatParam::operator =(const XParam& xp) throw (Exception) { const XFloatParam* xip = dynamic_cast<const XFloatParam*>(&xp); if (xip == NULL) throw Exception( get_pname() + ": Bad XFloatParam in assignment !", TracePoint("pparam")); // check prameter name. if (get_pname() != xip->get_pname()) throw Exception("Different mix xparameters " "in assignment !", TracePoint("pparam")); try { assignHelper(xp); } catch (Exception &e) { e.addTracePoint(TracePoint("pparam")); throw e; } min = xip->min; max = xip->max; val = xip->val; return *this; }
static void end_backup( dle_t *dle, int goterror) { char *amandates_file = NULL; if(dle->record && !goterror) { if (incrname != NULL && strlen(incrname) > 4) { char *nodotnew; nodotnew = g_strdup(incrname); nodotnew[strlen(nodotnew)-4] = '\0'; if (rename(incrname, nodotnew)) { g_fprintf(stderr, _("%s: warning [renaming %s to %s: %s]\n"), get_pname(), incrname, nodotnew, strerror(errno)); } amfree(nodotnew); amfree(incrname); } /* update the amandates file */ amandates_file = getconf_str(CNF_AMANDATES); if(start_amandates(amandates_file, 1)) { amandates_updateone(cur_disk, cur_level, cur_dumptime); finish_amandates(); free_amandates(); } else { /* failure is only fatal if we didn't get a gnutar-listdir */ char *gnutar_list_dir = getconf_str(CNF_GNUTAR_LIST_DIR); if (!gnutar_list_dir || !*gnutar_list_dir) { error(_("error [opening %s for writing: %s]"), amandates_file, strerror(errno)); /* NOTREACHED */ } else { g_debug(_("non-fatal error opening '%s' for writing: %s]"), amandates_file, strerror(errno)); } } } }
/* * 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; }
int good_fdisk() { char buf[MAXPATHLEN]; struct stat statbuf; (void) get_pname(&buf[0]); if (stat(buf, &statbuf) == -1 || !S_ISCHR(statbuf.st_mode) || cur_label == L_TYPE_EFI) { /* * Return if this disk does not support fdisk table or * if the disk is labeled with EFI. */ return (1); } if (lel(cur_disk->fdisk_part.numsect) > 0) return (1); else return (0); }
XParam &XTextParam::operator = (const XParam &xp) throw (Exception) { const XTextParam* xtp = dynamic_cast<const XTextParam*>(&xp); if (xtp == NULL) throw Exception("Bad text XParam in assignment !", TracePoint("pparam")); // check prameter name. if (get_pname() != xtp->get_pname()) throw Exception("Different test xparameters " "in assignment !", TracePoint("pparam")); try { assignHelper(xp); } catch (Exception &e) { e.addTracePoint(TracePoint("pparam")); throw e; } val = xtp->val; return *this; }
struct cmdargs * getcmd(void) { char *line; cmd_t cmd_i; struct cmdargs *cmdargs = g_new0(struct cmdargs, 1); if (isatty(0)) { g_printf("%s> ", get_pname()); fflush(stdout); line = agets(stdin); } else { line = areads(0); } if (line == NULL) { line = g_strdup("QUIT"); } dbprintf(_("getcmd: %s\n"), line); cmdargs->argv = split_quoted_strings(line); cmdargs->argc = g_strv_length(cmdargs->argv); cmdargs->cmd = BOGUS; amfree(line); if (cmdargs->argc < 1) { return cmdargs; } for(cmd_i=BOGUS; cmdstr[cmd_i] != NULL; cmd_i++) if(g_str_equal(cmdargs->argv[0], cmdstr[cmd_i])) { cmdargs->cmd = cmd_i; return cmdargs; } return cmdargs; }
int main( int argc, char ** argv) { #ifndef ERRMSG char *dump_program; int i; char *e; char *cmdline; #endif /* ERRMSG */ /* * 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("rundump"); /* Don't die when child closes pipe */ signal(SIGPIPE, SIG_IGN); dbopen(DBG_SUBDIR_CLIENT); config_init(CONFIG_INIT_CLIENT, NULL); if (argc < 3) { error(_("Need at least 3 arguments\n")); /*NOTREACHED*/ } dbprintf(_("version %s\n"), VERSION); #ifdef ERRMSG /* { */ g_fprintf(stderr, ERRMSG); dbprintf("%s: %s", argv[0], ERRMSG); dbclose(); return 1; #else /* } { */ #ifdef WANT_SETUID_CLIENT check_running_as(RUNNING_AS_CLIENT_LOGIN | RUNNING_AS_UID_ONLY); if (!become_root()) { error(_("error [%s could not become root (is the setuid bit set?)]\n"), get_pname()); /*NOTREACHED*/ } #else check_running_as(RUNNING_AS_CLIENT_LOGIN); #endif /* skip argv[0] */ argc--; argv++; dbprintf(_("config: %s\n"), argv[0]); if (strcmp(argv[0], "NOCONFIG") != 0) dbrename(argv[0], DBG_SUBDIR_CLIENT); argc--; argv++; #ifdef XFSDUMP if (strcmp(argv[0], "xfsdump") == 0) dump_program = XFSDUMP; else /* strcmp(argv[0], "xfsdump") != 0 */ #endif #ifdef VXDUMP if (strcmp(argv[0], "vxdump") == 0) dump_program = VXDUMP; else /* strcmp(argv[0], "vxdump") != 0 */ #endif #ifdef VDUMP if (strcmp(argv[0], "vdump") == 0) dump_program = VDUMP; else /* strcmp(argv[0], "vdump") != 0 */ #endif #if defined(DUMP) dump_program = DUMP; #else # if defined(XFSDUMP) dump_program = XFSDUMP; # else # if defined(VXDUMP) dump_program = VXDUMP; # else dump_program = "dump"; # endif # endif #endif cmdline = stralloc(dump_program); for (i = 1; argv[i]; i++) { char *quoted; quoted = quote_string(argv[i]); cmdline = vstrextend(&cmdline, " ", quoted, NULL); amfree(quoted); } dbprintf(_("running: %s\n"), cmdline); amfree(cmdline); execve(dump_program, argv, safe_env()); e = strerror(errno); dbprintf(_("failed (%s)\n"), e); dbclose(); g_fprintf(stderr, _("rundump: could not exec %s: %s\n"), dump_program, e); return 1; #endif /* } */ }
void parse_file_header( const char *buffer, dumpfile_t *file, size_t buflen) { char *buf, *line, *tok, *line1; size_t lsize; char *uqname; int in_quotes; char *saveptr = NULL; /* put the buffer into a writable chunk of memory and nul-term it */ buf = alloc(buflen + 1); memcpy(buf, buffer, buflen); buf[buflen] = '\0'; fh_init(file); /* extract the first unquoted line */ in_quotes = 0; for (line = buf, lsize = 0; lsize < buflen; line++) { if ((*line == '\n') && !in_quotes) break; if (*line == '"') { in_quotes = !in_quotes; } else if ((*line == '\\') && (*(line + 1) == '"')) { line++; lsize++; } lsize++; } *line = '\0'; line1 = alloc(lsize + 1); strncpy(line1, buf, lsize); line1[lsize] = '\0'; *line = '\n'; tok = strtok_r(line1, " ", &saveptr); if (tok == NULL) { g_fprintf(stderr, _("%s: Empty amanda header: buflen=%zu lsize=%zu\n"), get_pname(), buflen, lsize); hexdump(buffer, lsize); strange_header(file, buffer, buflen, _("<Non-empty line>"), tok); goto out; } if (strcmp(tok, "NETDUMP:") != 0 && strcmp(tok, "AMANDA:") != 0) { amfree(buf); file->type = F_UNKNOWN; amfree(line1); return; } tok = strtok_r(NULL, " ", &saveptr); if (tok == NULL) { strange_header(file, buffer, buflen, _("<file type>"), tok); goto out; } file->type = str2filetype(tok); switch (file->type) { case F_TAPESTART: tok = strtok_r(NULL, " ", &saveptr); if ((tok == NULL) || (strcmp(tok, "DATE") != 0)) { strange_header(file, buffer, buflen, "DATE", tok); goto out; } tok = strtok_r(NULL, " ", &saveptr); if (tok == NULL) { strange_header(file, buffer, buflen, _("<date stamp>"), tok); goto out; } strncpy(file->datestamp, tok, SIZEOF(file->datestamp) - 1); tok = strtok_r(NULL, " ", &saveptr); if ((tok == NULL) || (strcmp(tok, "TAPE") != 0)) { strange_header(file, buffer, buflen, "TAPE", tok); goto out; } tok = strtok_r(NULL, " ", &saveptr); if (tok == NULL) { strange_header(file, buffer, buflen, _("<file type>"), tok); goto out; } strncpy(file->name, tok, SIZEOF(file->name) - 1); break; case F_DUMPFILE: case F_CONT_DUMPFILE: case F_SPLIT_DUMPFILE: tok = strtok_r(NULL, " ", &saveptr); if (tok == NULL) { strange_header(file, buffer, buflen, _("<date stamp>"), tok); goto out; } strncpy(file->datestamp, tok, SIZEOF(file->datestamp) - 1); tok = strtok_r(NULL, " ", &saveptr); if (tok == NULL) { strange_header(file, buffer, buflen, _("<file name>"), tok); goto out; } strncpy(file->name, tok, SIZEOF(file->name) - 1); tok = strquotedstr(&saveptr); if (tok == NULL) { strange_header(file, buffer, buflen, _("<disk name>"), tok); goto out; } uqname = unquote_string(tok); strncpy(file->disk, uqname, SIZEOF(file->disk) - 1); amfree(uqname); if(file->type == F_SPLIT_DUMPFILE) { tok = strtok_r(NULL, " ", &saveptr); if (tok == NULL || strcmp(tok, "part") != 0) { strange_header(file, buffer, buflen, "part", tok); goto out; } tok = strtok_r(NULL, "/", &saveptr); if ((tok == NULL) || (sscanf(tok, "%d", &file->partnum) != 1)) { strange_header(file, buffer, buflen, _("<part num param>"), tok); goto out; } /* If totalparts == -1, then the original dump was done in streaming mode (no holding disk), thus we don't know how many parts there are. */ tok = strtok_r(NULL, " ", &saveptr); if((tok == NULL) || (sscanf(tok, "%d", &file->totalparts) != 1)) { strange_header(file, buffer, buflen, _("<total parts param>"), tok); goto out; } } tok = strtok_r(NULL, " ", &saveptr); if ((tok == NULL) || (strcmp(tok, "lev") != 0)) { strange_header(file, buffer, buflen, "lev", tok); goto out; } tok = strtok_r(NULL, " ", &saveptr); if ((tok == NULL) || (sscanf(tok, "%d", &file->dumplevel) != 1)) { strange_header(file, buffer, buflen, _("<dump level param>"), tok); goto out; } tok = strtok_r(NULL, " ", &saveptr); if ((tok == NULL) || (strcmp(tok, "comp") != 0)) { strange_header(file, buffer, buflen, "comp", tok); goto out; } tok = strtok_r(NULL, " ", &saveptr); if (tok == NULL) { strange_header(file, buffer, buflen, _("<comp param>"), tok); goto out; } strncpy(file->comp_suffix, tok, SIZEOF(file->comp_suffix) - 1); file->compressed = strcmp(file->comp_suffix, "N"); /* compatibility with pre-2.2 amanda */ if (strcmp(file->comp_suffix, "C") == 0) strncpy(file->comp_suffix, ".Z", SIZEOF(file->comp_suffix) - 1); tok = strtok_r(NULL, " ", &saveptr); /* "program" is optional */ if (tok == NULL || strcmp(tok, "program") != 0) { break; } tok = strtok_r(NULL, " ", &saveptr); if (tok == NULL) { strange_header(file, buffer, buflen, _("<program name>"), tok); goto out; } strncpy(file->program, tok, SIZEOF(file->program) - 1); if (file->program[0] == '\0') strncpy(file->program, "RESTORE", SIZEOF(file->program) - 1); if ((tok = strtok_r(NULL, " ", &saveptr)) == NULL) break; /* reached the end of the buffer */ /* "encryption" is optional */ if (BSTRNCMP(tok, "crypt") == 0) { tok = strtok_r(NULL, " ", &saveptr); if (tok == NULL) { strange_header(file, buffer, buflen, _("<crypt param>"), tok); goto out; } strncpy(file->encrypt_suffix, tok, SIZEOF(file->encrypt_suffix) - 1); file->encrypted = BSTRNCMP(file->encrypt_suffix, "N"); if ((tok = strtok_r(NULL, " ", &saveptr)) == NULL) break; } /* "srvcompprog" is optional */ if (BSTRNCMP(tok, "server_custom_compress") == 0) { tok = strtok_r(NULL, " ", &saveptr); if (tok == NULL) { strange_header(file, buffer, buflen, _("<server custom compress param>"), tok); goto out; } strncpy(file->srvcompprog, tok, SIZEOF(file->srvcompprog) - 1); if ((tok = strtok_r(NULL, " ", &saveptr)) == NULL) break; } /* "clntcompprog" is optional */ if (BSTRNCMP(tok, "client_custom_compress") == 0) { tok = strtok_r(NULL, " ", &saveptr); if (tok == NULL) { strange_header(file, buffer, buflen, _("<client custom compress param>"), tok); goto out; } strncpy(file->clntcompprog, tok, SIZEOF(file->clntcompprog) - 1); if ((tok = strtok_r(NULL, " ", &saveptr)) == NULL) break; } /* "srv_encrypt" is optional */ if (BSTRNCMP(tok, "server_encrypt") == 0) { tok = strtok_r(NULL, " ", &saveptr); if (tok == NULL) { strange_header(file, buffer, buflen, _("<server encrypt param>"), tok); goto out; } strncpy(file->srv_encrypt, tok, SIZEOF(file->srv_encrypt) - 1); if ((tok = strtok_r(NULL, " ", &saveptr)) == NULL) break; } /* "clnt_encrypt" is optional */ if (BSTRNCMP(tok, "client_encrypt") == 0) { tok = strtok_r(NULL, " ", &saveptr); if (tok == NULL) { strange_header(file, buffer, buflen, _("<client encrypt param>"), tok); goto out; } strncpy(file->clnt_encrypt, tok, SIZEOF(file->clnt_encrypt) - 1); if ((tok = strtok_r(NULL, " ", &saveptr)) == NULL) break; } /* "srv_decrypt_opt" is optional */ if (BSTRNCMP(tok, "server_decrypt_option") == 0) { tok = strtok_r(NULL, " ", &saveptr); if (tok == NULL) { strange_header(file, buffer, buflen, _("<server decrypt param>"), tok); goto out; } strncpy(file->srv_decrypt_opt, tok, SIZEOF(file->srv_decrypt_opt) - 1); if ((tok = strtok_r(NULL, " ", &saveptr)) == NULL) break; } /* "clnt_decrypt_opt" is optional */ if (BSTRNCMP(tok, "client_decrypt_option") == 0) { tok = strtok_r(NULL, " ", &saveptr); if (tok == NULL) { strange_header(file, buffer, buflen, _("<client decrypt param>"), tok); goto out; } strncpy(file->clnt_decrypt_opt, tok, SIZEOF(file->clnt_decrypt_opt) - 1); if ((tok = strtok_r(NULL, " ", &saveptr)) == NULL) break; } break; case F_TAPEEND: tok = strtok_r(NULL, " ", &saveptr); /* DATE is optional */ if (tok != NULL) { if (strcmp(tok, "DATE") == 0) { tok = strtok_r(NULL, " ", &saveptr); if(tok == NULL) file->datestamp[0] = '\0'; else strncpy(file->datestamp, tok, SIZEOF(file->datestamp) - 1); } else { strange_header(file, buffer, buflen, _("<DATE>"), tok); } } else { file->datestamp[0] = '\0'; } break; case F_NOOP: /* nothing follows */ break; default: strange_header(file, buffer, buflen, _("TAPESTART|DUMPFILE|CONT_DUMPFILE|SPLIT_DUMPFILE|TAPEEND|NOOP"), tok); goto out; } (void)strtok_r(buf, "\n", &saveptr); /* this is the first line */ /* iterate through the rest of the lines */ while ((line = strtok_r(NULL, "\n", &saveptr)) != NULL) { #define SC "CONT_FILENAME=" if (strncmp(line, SC, SIZEOF(SC) - 1) == 0) { line += SIZEOF(SC) - 1; strncpy(file->cont_filename, line, SIZEOF(file->cont_filename) - 1); continue; } #undef SC #define SC "PARTIAL=" if (strncmp(line, SC, SIZEOF(SC) - 1) == 0) { line += SIZEOF(SC) - 1; file->is_partial = !strcasecmp(line, "yes"); continue; } #undef SC #define SC "APPLICATION=" if (strncmp(line, SC, SIZEOF(SC) - 1) == 0) { line += SIZEOF(SC) - 1; strncpy(file->application, line, SIZEOF(file->application) - 1); continue; } #undef SC #define SC "DLE=" if (strncmp(line, SC, SIZEOF(SC) - 1) == 0) { line += SIZEOF(SC) - 1; file->dle_str = parse_heredoc(line, &saveptr); } #undef SC #define SC _("To restore, position tape at start of file and run:") if (strncmp(line, SC, SIZEOF(SC) - 1) == 0) continue; #undef SC #define SC "\tdd if=<tape> " if (strncmp(line, SC, SIZEOF(SC) - 1) == 0) { char *cmd1, *cmd2, *cmd3=NULL; /* skip over dd command */ if ((cmd1 = strchr(line, '|')) == NULL) { strncpy(file->recover_cmd, "BUG", SIZEOF(file->recover_cmd) - 1); continue; } *cmd1++ = '\0'; /* block out first pipeline command */ if ((cmd2 = strchr(cmd1, '|')) != NULL) { *cmd2++ = '\0'; if ((cmd3 = strchr(cmd2, '|')) != NULL) *cmd3++ = '\0'; } /* clean up some extra spaces in various fields */ chomp(cmd1); chomp(cmd2); chomp(cmd3); /* three cmds: decrypt | uncompress | recover * two cmds: uncompress | recover * XXX note that if there are two cmds, the first one * XXX could be either uncompress or decrypt. Since no * XXX code actually call uncompress_cmd/decrypt_cmd, it's ok * XXX for header information. * one cmds: recover */ if ( cmd3 == NULL) { if (cmd2 == NULL) { strncpy(file->recover_cmd, cmd1, SIZEOF(file->recover_cmd) - 1); } else { g_snprintf(file->uncompress_cmd, SIZEOF(file->uncompress_cmd), "%s |", cmd1); strncpy(file->recover_cmd, cmd2, SIZEOF(file->recover_cmd) - 1); } } else { /* cmd3 presents: decrypt | uncompress | recover */ g_snprintf(file->decrypt_cmd, SIZEOF(file->decrypt_cmd), "%s |", cmd1); g_snprintf(file->uncompress_cmd, SIZEOF(file->uncompress_cmd), "%s |", cmd2); strncpy(file->recover_cmd, cmd3, SIZEOF(file->recover_cmd) - 1); } continue; } #undef SC /* XXX complain about weird lines? */ } out: amfree(buf); amfree(line1); }
int main( int argc, char ** argv) { #ifdef TEST /* standalone test to ckeck wether the calculated file size is ok */ struct stat finfo; int i; off_t dump_total = (off_t)0; off_t gtar_total = (off_t)0; char *d; int l, w; /* * 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("calcsize"); dbopen(NULL); config_init(CONFIG_INIT_CLIENT, NULL); /* Don't die when child closes pipe */ signal(SIGPIPE, SIG_IGN); if (argc < 2) { g_fprintf(stderr,_("Usage: %s file[s]\n"),argv[0]); return 1; } for(i=1; i<argc; i++) { if(lstat(argv[i], &finfo) == -1) { g_fprintf(stderr, "%s: %s\n", argv[i], strerror(errno)); continue; } g_printf("%s: st_size=%lu", argv[i],(unsigned long)finfo.st_size); g_printf(": blocks=%llu\n", ST_BLOCKS(finfo)); dump_total += (ST_BLOCKS(finfo) + (off_t)1) / (off_t)2 + (off_t)1; gtar_total += ROUND(4,(ST_BLOCKS(finfo) + (off_t)1)); } g_printf(" gtar dump\n"); g_printf("total %-9lu %-9lu\n",gtar_total,dump_total); return 0; #else int i; char *dirname=NULL; char *amname=NULL, *qamname=NULL; char *filename=NULL, *qfilename = NULL; if (argc > 1 && argv[1] && g_str_equal(argv[1], "--version")) { printf("calcsize-%s\n", VERSION); return (0); } safe_fd(-1, 0); safe_cd(); set_pname("calcsize"); dbopen(DBG_SUBDIR_CLIENT); config_init(CONFIG_INIT_CLIENT, NULL); dbprintf(_("version %s\n"), VERSION); /* drop root privileges; we'll regain them for the required operations */ #ifdef WANT_SETUID_CLIENT check_running_as(RUNNING_AS_CLIENT_LOGIN | RUNNING_AS_UID_ONLY); if (!set_root_privs(0)) { error(_("calcsize must be run setuid root")); } #else check_running_as(RUNNING_AS_CLIENT_LOGIN); #endif argc--, argv++; /* skip program name */ /* need at least program, amname, and directory name */ if(argc < 4) { error(_("Usage: %s config [DUMP|STAR|GNUTAR] name dir [-X exclude-file] [-I include-file] [level date]*"), get_pname()); /*NOTREACHED*/ } dbprintf(_("config: %s\n"), *argv); if (!g_str_equal(*argv, "NOCONFIG")) { dbrename(*argv, DBG_SUBDIR_CLIENT); } argc--; argv++; /* parse backup program name */ if(g_str_equal(*argv, "DUMP")) { #if !defined(DUMP) && !defined(XFSDUMP) error("dump not available on this system"); /*NOTREACHED*/ #else add_file_name = add_file_name_dump; add_file = add_file_dump; final_size = final_size_dump; #endif } else if(g_str_equal(*argv, "GNUTAR")) { #ifndef GNUTAR error("gnutar not available on this system"); /*NOTREACHED*/ #else add_file_name = add_file_name_gnutar; add_file = add_file_gnutar; final_size = final_size_gnutar; use_gtar_excl++; #endif } else { add_file_name = add_file_name_unknown; add_file = add_file_unknown; final_size = final_size_unknown; } argc--, argv++; /* the amanda name can be different from the directory name */ if (argc > 0) { amname = *argv; qamname = quote_string(amname); argc--, argv++; } else { error("missing <name>"); /*NOTREACHED*/ } /* the toplevel directory name to search from */ if (argc > 0) { dirname = *argv; argc--, argv++; } else { error("missing <dir>"); /*NOTREACHED*/ } if ((argc > 1) && g_str_equal(*argv, "-X")) { argv++; if (!(use_gtar_excl || use_star_excl)) { error("exclusion specification not supported"); /*NOTREACHED*/ } filename = g_strdup(*argv); qfilename = quote_string(filename); if (access(filename, R_OK) != 0) { g_fprintf(stderr,"Cannot open exclude file %s\n", qfilename); use_gtar_excl = use_star_excl = 0; } else { exclude_sl = calc_load_file(filename); if (!exclude_sl) { g_fprintf(stderr,"Cannot open exclude file %s: %s\n", qfilename, strerror(errno)); use_gtar_excl = use_star_excl = 0; } } amfree(qfilename); amfree(filename); argc -= 2; argv++; } else { use_gtar_excl = use_star_excl = 0; } if ((argc > 1) && g_str_equal(*argv, "-I")) { argv++; filename = g_strdup(*argv); qfilename = quote_string(filename); if (access(filename, R_OK) != 0) { g_fprintf(stderr,"Cannot open include file %s\n", qfilename); use_gtar_excl = use_star_excl = 0; } else { include_sl = calc_load_file(filename); if (!include_sl) { g_fprintf(stderr,"Cannot open include file %s: %s\n", qfilename, strerror(errno)); use_gtar_excl = use_star_excl = 0; } } amfree(qfilename); amfree(filename); argc -= 2; argv++; } /* the dump levels to calculate sizes for */ ndumps = 0; while(argc >= 2) { if(ndumps < MAXDUMPS) { dumplevel[ndumps] = atoi(argv[0]); dumpdate [ndumps] = (time_t) atol(argv[1]); ndumps++; argc -= 2, argv += 2; } } if(argc) { error("leftover arg \"%s\", expected <level> and <date>", *argv); /*NOTREACHED*/ } if(is_empty_sl(include_sl)) { traverse_dirs(dirname,"."); } else { sle_t *an_include = include_sl->first; while(an_include != NULL) { /* char *adirname = stralloc2(dirname, an_include->name+1); traverse_dirs(adirname); amfree(adirname); */ traverse_dirs(dirname, an_include->name); an_include = an_include->next; } } for(i = 0; i < ndumps; i++) { amflock(1, "size"); dbprintf("calcsize: %s %d SIZE %lld\n", qamname, dumplevel[i], (long long)final_size(i, dirname)); g_fprintf(stderr, "%s %d SIZE %lld\n", qamname, dumplevel[i], (long long)final_size(i, dirname)); fflush(stderr); amfunlock(1, "size"); } amfree(qamname); return 0; #endif }
static void amgtar_backup( application_argument_t *argument) { int dumpin; char *cmd = NULL; char *qdisk; char *incrname; char line[32768]; amregex_t *rp; off_t dump_size = -1; char *type; char startchr; int dataf = 1; int mesgf = 3; int indexf = 4; int outf; FILE *mesgstream; FILE *indexstream = NULL; FILE *outstream; char *errmsg = NULL; amwait_t wait_status; GPtrArray *argv_ptr; int tarpid; mesgstream = fdopen(mesgf, "w"); if (!mesgstream) { error(_("error mesgstream(%d): %s\n"), mesgf, strerror(errno)); } if (!gnutar_path) { error(_("GNUTAR-PATH not defined")); } if (!gnutar_listdir) { error(_("GNUTAR-LISTDIR not defined")); } 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")); } qdisk = quote_string(argument->dle.disk); incrname = amgtar_get_incrname(argument, GPOINTER_TO_INT(argument->level->data)); cmd = stralloc(gnutar_path); argv_ptr = amgtar_build_argv(argument, incrname, CMD_BACKUP); tarpid = pipespawnv(cmd, STDIN_PIPE|STDERR_PIPE, 1, &dumpin, &dataf, &outf, (char **)argv_ptr->pdata); /* close the write ends of the pipes */ aclose(dumpin); aclose(dataf); if (argument->dle.create_index) { indexstream = fdopen(indexf, "w"); if (!indexstream) { error(_("error indexstream(%d): %s\n"), indexf, strerror(errno)); } } outstream = fdopen(outf, "r"); if (!outstream) { error(_("error outstream(%d): %s\n"), outf, strerror(errno)); } while (fgets(line, sizeof(line), outstream) != NULL) { if (line[strlen(line)-1] == '\n') /* remove trailling \n */ line[strlen(line)-1] = '\0'; if (*line == '.' && *(line+1) == '/') { /* filename */ if (argument->dle.create_index) { fprintf(indexstream, "%s\n", &line[1]); /* remove . */ } } else { /* 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) { case DMP_NORMAL: type = "normal"; startchr = '|'; break; case DMP_IGNORE: continue; case DMP_STRANGE: type = "strange"; startchr = '?'; break; case DMP_SIZE: type = "size"; startchr = '|'; break; case DMP_ERROR: type = "error"; startchr = '?'; break; default: type = "unknown"; startchr = '!'; break; } dbprintf("%3d: %7s(%c): %s\n", rp->srcline, type, startchr, line); fprintf(mesgstream,"%c %s\n", startchr, line); } } waitpid(tarpid, &wait_status, 0); if (WIFSIGNALED(wait_status)) { errmsg = vstrallocf(_("%s terminated with signal %d: see %s"), cmd, WTERMSIG(wait_status), dbfn()); } else if (WIFEXITED(wait_status)) { if (exit_value[WEXITSTATUS(wait_status)] == 1) { errmsg = vstrallocf(_("%s exited with status %d: see %s"), cmd, WEXITSTATUS(wait_status), dbfn()); } else { /* Normal exit */ } } else { errmsg = vstrallocf(_("%s got bad exit: see %s"), cmd, dbfn()); } dbprintf(_("after %s %s wait\n"), cmd, qdisk); dbprintf(_("amgtar: %s: pid %ld\n"), cmd, (long)tarpid); if (errmsg) { dbprintf("%s", errmsg); g_fprintf(mesgstream, "sendbackup: error [%s]\n", errmsg); } 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)); } amfree(nodotnew); } dbprintf("sendbackup: size %lld\n", (long long)dump_size); fprintf(mesgstream, "sendbackup: size %lld\n", (long long)dump_size); dbprintf("sendbackup: end\n"); fprintf(mesgstream, "sendbackup: end\n"); if (argument->dle.create_index) fclose(indexstream); fclose(mesgstream); amfree(incrname); amfree(qdisk); amfree(cmd); g_ptr_array_free_full(argv_ptr); }
int main( int argc, char ** argv) { int c; char *command; application_argument_t argument; int i; #ifdef GNUTAR gnutar_path = GNUTAR; #else gnutar_path = NULL; #endif gnutar_directory = NULL; gnutar_onefilesystem = 1; gnutar_atimepreserve = 1; gnutar_checkdevice = 1; gnutar_sparse = 1; gnutar_no_unquote = 0; exit_handling = NULL; /* initialize */ /* * 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"); if (argc < 2) { printf("ERROR no command given to amgtar\n"); error(_("No command given to amgtar")); } /* drop root privileges */ if (!set_root_privs(0)) { if (strcmp(argv[1], "selfcheck") == 0) { printf("ERROR amgtar must be run setuid root\n"); } error(_("amgtar must be run setuid root")); } safe_fd(3, 2); set_pname("amgtar"); /* Don't die when child closes pipe */ signal(SIGPIPE, SIG_IGN); #if defined(USE_DBMALLOC) malloc_size_1 = malloc_inuse(&malloc_hist_1); #endif add_amanda_log_handler(amanda_log_stderr); add_amanda_log_handler(amanda_log_syslog); dbopen(DBG_SUBDIR_CLIENT); startclock(); dbprintf(_("version %s\n"), version()); config_init(CONFIG_INIT_CLIENT, NULL); //check_running_as(RUNNING_AS_DUMPUSER_PREFERRED); //root for amrecover //RUNNING_AS_CLIENT_LOGIN from selfcheck, sendsize, sendbackup /* parse argument */ command = argv[1]; argument.config = NULL; argument.host = NULL; argument.message = 0; argument.collection = 0; argument.calcsize = 0; argument.tar_blocksize = NULL; argument.level = NULL; init_dle(&argument.dle); while (1) { int option_index = 0; c = getopt_long (argc, argv, "", long_options, &option_index); if (c == -1) { break; } switch (c) { case 1: argument.config = stralloc(optarg); break; case 2: argument.host = stralloc(optarg); break; case 3: argument.dle.disk = stralloc(optarg); break; case 4: argument.dle.device = stralloc(optarg); break; case 5: argument.level = g_slist_append(argument.level, GINT_TO_POINTER(atoi(optarg))); break; case 6: argument.dle.create_index = 1; break; case 7: argument.message = 1; break; case 8: argument.collection = 1; break; case 9: argument.dle.record = 1; break; case 10: gnutar_path = stralloc(optarg); break; case 11: gnutar_listdir = stralloc(optarg); break; case 12: if (optarg && strcasecmp(optarg, "NO") == 0) gnutar_onefilesystem = 0; else if (optarg && strcasecmp(optarg, "YES") == 0) gnutar_onefilesystem = 1; else if (strcasecmp(command, "selfcheck") == 0) printf(_("ERROR [%s: bad ONE-FILE-SYSTEM property value (%s)]\n"), get_pname(), optarg); break; case 13: if (optarg && strcasecmp(optarg, "NO") == 0) gnutar_sparse = 0; else if (optarg && strcasecmp(optarg, "YES") == 0) gnutar_sparse = 1; else if (strcasecmp(command, "selfcheck") == 0) printf(_("ERROR [%s: bad SPARSE property value (%s)]\n"), get_pname(), optarg); break; case 14: if (optarg && strcasecmp(optarg, "NO") == 0) gnutar_atimepreserve = 0; else if (optarg && strcasecmp(optarg, "YES") == 0) gnutar_atimepreserve = 1; else if (strcasecmp(command, "selfcheck") == 0) printf(_("ERROR [%s: bad ATIME-PRESERVE property value (%s)]\n"), get_pname(), optarg); break; case 15: if (optarg && strcasecmp(optarg, "NO") == 0) gnutar_checkdevice = 0; else if (optarg && strcasecmp(optarg, "YES") == 0) gnutar_checkdevice = 1; else if (strcasecmp(command, "selfcheck") == 0) printf(_("ERROR [%s: bad CHECK-DEVICE property value (%s)]\n"), get_pname(), optarg); break; case 16: if (optarg) argument.dle.include_file = append_sl(argument.dle.include_file, optarg); break; case 17: if (optarg) argument.dle.include_list = append_sl(argument.dle.include_list, optarg); break; case 18: argument.dle.include_optional = 1; break; case 19: if (optarg) argument.dle.exclude_file = append_sl(argument.dle.exclude_file, optarg); break; case 20: if (optarg) argument.dle.exclude_list = append_sl(argument.dle.exclude_list, optarg); break; case 21: argument.dle.exclude_optional = 1; break; case 22: gnutar_directory = stralloc(optarg); break; case 23: if (optarg) normal_message = g_slist_append(normal_message, optarg); break; case 24: if (optarg) ignore_message = g_slist_append(ignore_message, optarg); break; case 25: if (optarg) strange_message = g_slist_append(strange_message, optarg); break; case 26: if (optarg) exit_handling = stralloc(optarg); break; case 27: argument.calcsize = 1; break; case 28: argument.tar_blocksize = stralloc(optarg); break; case 29: if (optarg && strcasecmp(optarg, "NO") == 0) gnutar_no_unquote = 0; else if (optarg && strcasecmp(optarg, "YES") == 0) gnutar_no_unquote = 1; else if (strcasecmp(command, "selfcheck") == 0) printf(_("ERROR [%s: bad No_UNQUOTE property value (%s)]\n"), get_pname(), optarg); break; case ':': case '?': break; } } argument.argc = argc - optind; argument.argv = argv + optind; if (argument.config) { config_init(CONFIG_INIT_CLIENT | CONFIG_INIT_EXPLICIT_NAME | CONFIG_INIT_OVERLAY, argument.config); dbrename(get_config_name(), DBG_SUBDIR_CLIENT); } if (config_errors(NULL) >= CFGERR_ERRORS) { g_critical(_("errors processing config file")); } re_table = build_re_table(init_re_table, normal_message, ignore_message, strange_message); for(i=0;i<256;i++) exit_value[i] = 1; /* BAD */ exit_value[0] = 0; /* GOOD */ exit_value[1] = 0; /* GOOD */ if (exit_handling) { char *s = exit_handling; while (s) { char *r = strchr(s, '='); if (r) { int j = atoi(s); if (j >= 0 && j < 256) { r++; if (strncasecmp(r, "GOOD", 4) == 0) { exit_value[j] = 0; } } } s = strchr(s+1, ' '); } } gnutar_listdir = getconf_str(CNF_GNUTAR_LIST_DIR); if (strlen(gnutar_listdir) == 0) gnutar_listdir = NULL; if (gnutar_path) { dbprintf("GNUTAR-PATH %s\n", gnutar_path); } else { dbprintf("GNUTAR-PATH is not set\n"); } if (gnutar_listdir) { dbprintf("GNUTAR-LISTDIR %s\n", gnutar_listdir); } else { dbprintf("GNUTAR-LISTDIR is not set\n"); } if (gnutar_directory) { dbprintf("DIRECTORY %s\n", gnutar_directory); } dbprintf("ONE-FILE-SYSTEM %s\n", gnutar_onefilesystem? "yes":"no"); dbprintf("SPARSE %s\n", gnutar_sparse? "yes":"no"); dbprintf("NO-UNQUOTE %s\n", gnutar_no_unquote? "yes":"no"); dbprintf("ATIME-PRESERVE %s\n", gnutar_atimepreserve? "yes":"no"); dbprintf("CHECK-DEVICE %s\n", gnutar_checkdevice? "yes":"no"); { amregex_t *rp; for (rp = re_table; rp->regex != NULL; rp++) { switch (rp->typ) { case DMP_NORMAL : dbprintf("NORMAL %s\n", rp->regex); break; case DMP_IGNORE : dbprintf("IGNORE %s\n", rp->regex); break; case DMP_STRANGE: dbprintf("STRANGE %s\n", rp->regex); break; case DMP_SIZE : dbprintf("SIZE %s\n", rp->regex); break; case DMP_ERROR : dbprintf("ERROR %s\n", rp->regex); break; } } } if (strcmp(command, "support") == 0) { amgtar_support(&argument); } else if (strcmp(command, "selfcheck") == 0) { amgtar_selfcheck(&argument); } else if (strcmp(command, "estimate") == 0) { amgtar_estimate(&argument); } else if (strcmp(command, "backup") == 0) { amgtar_backup(&argument); } else if (strcmp(command, "restore") == 0) { amgtar_restore(&argument); } else if (strcmp(command, "validate") == 0) { amgtar_validate(&argument); } else { dbprintf("Unknown command `%s'.\n", command); fprintf(stderr, "Unknown command `%s'.\n", command); exit (1); } return 0; }
static void start_backup( dle_t *dle, char *host, int dataf, int mesgf, int indexf) { int dumpin, dumpout, compout; char *dumpkeys = NULL; char *device = NULL; char *fstype = NULL; char *cmd = NULL; char *cmdX = NULL; char *indexcmd = NULL; char level_str[NUM_STR_SIZE]; char *compopt = NULL; char *encryptopt = skip_argument; char *qdisk; char *config; am_level_t *alevel = (am_level_t *)dle->levellist->data; int level = alevel->level; g_snprintf(level_str, sizeof(level_str), "%d", level); qdisk = quote_string(dle->disk); dbprintf(_("start: %s:%s lev %d\n"), host, qdisk, level); g_fprintf(stderr, _("%s: start [%s:%s level %d]\n"), get_pname(), host, qdisk, level); amfree(qdisk); /* apply client-side encryption here */ if (dle->encrypt == ENCRYPT_CUST ) { encpid = pipespawn(dle->clnt_encrypt, STDIN_PIPE, 0, &compout, &dataf, &mesgf, dle->clnt_encrypt, encryptopt, NULL); dbprintf(_("gnutar: pid %ld: %s\n"), (long)encpid, dle->clnt_encrypt); } else { compout = dataf; encpid = -1; } /* now do the client-side compression */ if(dle->compress == COMP_FAST || dle->compress == COMP_BEST) { compopt = skip_argument; #if defined(COMPRESS_BEST_OPT) && defined(COMPRESS_FAST_OPT) if(dle->compress == COMP_BEST) { compopt = COMPRESS_BEST_OPT; } else { compopt = COMPRESS_FAST_OPT; } #endif comppid = pipespawn(COMPRESS_PATH, STDIN_PIPE, 0, &dumpout, &compout, &mesgf, COMPRESS_PATH, compopt, NULL); dbprintf(_("dump: pid %ld: %s"), (long)comppid, COMPRESS_PATH); if(compopt != skip_argument) { dbprintf(" %s", compopt); } dbprintf("\n"); } else if (dle->compress == COMP_CUST) { compopt = skip_argument; comppid = pipespawn(dle->compprog, STDIN_PIPE, 0, &dumpout, &compout, &mesgf, dle->compprog, compopt, NULL); dbprintf(_("gnutar-cust: pid %ld: %s"), (long)comppid, dle->compprog); if(compopt != skip_argument) { dbprintf(" %s", compopt); } dbprintf("\n"); } else { dumpout = compout; comppid = -1; } /* invoke dump */ device = amname_to_devname(dle->device); fstype = amname_to_fstype(dle->device); dbprintf(_("dumping device '%s' with '%s'\n"), device, fstype); #if defined(USE_RUNDUMP) || !defined(DUMP) cmd = g_strjoin(NULL, amlibexecdir, "/", "rundump", NULL); cmdX = cmd; if (g_options->config) config = g_options->config; else config = "NOCONFIG"; #else cmd = g_strdup(DUMP); cmdX = skip_argument; config = skip_argument; #endif #ifndef AIX_BACKUP /* { */ /* normal dump */ #ifdef XFSDUMP /* { */ #ifdef DUMP /* { */ if (g_str_equal(amname_to_fstype(dle->device), "xfs")) #else /* } { */ if (1) #endif /* } */ { char *progname; g_free(cmd); progname = cmd = g_strconcat(amlibexecdir, "/", "rundump", NULL); cmdX = cmd; if (g_options->config) config = g_options->config; else config = "NOCONFIG"; program->backup_name = XFSDUMP; program->restore_name = XFSRESTORE; indexcmd = g_strjoin(NULL, XFSRESTORE, " -t", " -v", " silent", " -", " 2>/dev/null", " | sed", " -e", " \'s/^/\\//\'", NULL); info_tapeheader(dle); start_index(dle->create_index, dumpout, mesgf, indexf, indexcmd); dumpkeys = g_strdup(level_str); dumppid = pipespawn(progname, STDIN_PIPE, 0, &dumpin, &dumpout, &mesgf, cmdX, config, "xfsdump", !dle->record ? "-J" : skip_argument, "-F", "-l", dumpkeys, "-", device, NULL); } else #endif /* } */ #ifdef VXDUMP /* { */ #ifdef DUMP if (g_str_equal(amname_to_fstype(dle->device), "vxfs")) #else if (1) #endif { char *progname; #ifdef USE_RUNDUMP g_free(cmd); progname = cmd = g_strconcat(amlibexecdir, "/", "rundump", NULL); cmdX = cmd; if (g_options->config) config = g_options->config; else config = "NOCONFIG"; #else char *progname; g_free(cmd); progname = cmd = g_strdup(VXDUMP); cmdX = skip_argument; config = skip_argument; #endif program->backup_name = VXDUMP; program->restore_name = VXRESTORE; dumpkeys = g_strjoin(NULL, level_str, !dle->record ? "" : "u", "s", "f", NULL); indexcmd = g_strjoin(NULL, VXRESTORE, " -tvf", " -", " 2>/dev/null", " | ", LEAF_AND_DIRS, NULL); info_tapeheader(dle); start_index(dle->create_index, dumpout, mesgf, indexf, indexcmd); dumppid = pipespawn(progname, STDIN_PIPE, 0, &dumpin, &dumpout, &mesgf, cmdX, config, "vxdump", dumpkeys, "1048576", "-", device, NULL); } else #endif /* } */ #ifdef VDUMP /* { */ #ifdef DUMP if (g_str_equal(amname_to_fstype(dle->device), "advfs")) #else if (1) #endif { g_free(cmd); cmd = g_strconcat(amlibexecdir, "/", "rundump", NULL); cmdX = cmd; if (g_options->config) config = g_options->config; else config = "NOCONFIG"; g_free(device); device = g_strdup(amname_to_dirname(dle->device)); program->backup_name = VDUMP; program->restore_name = VRESTORE; dumpkeys = g_strjoin(NULL, level_str, !dle->record ? "" : "u", "b", "f", NULL); indexcmd = g_strjoin(NULL, VRESTORE, " -tvf", " -", " 2>/dev/null", " | ", "sed -e \'\n/^\\./ {\ns/^\\.//\ns/, [0-9]*$//\ns/^\\.//\ns/ @-> .*$//\nt\n}\nd\n\'", NULL); info_tapeheader(dle); start_index(dle->create_index, dumpout, mesgf, indexf, indexcmd); dumppid = pipespawn(cmd, STDIN_PIPE, 0, &dumpin, &dumpout, &mesgf, cmdX, config, "vdump", dumpkeys, "60", "-", device, NULL); } else #endif /* } */ { #ifndef RESTORE #define RESTORE "restore" #endif #ifdef HAVE_HONOR_NODUMP # define PARAM_HONOR_NODUMP "h" #else # define PARAM_HONOR_NODUMP "" #endif #ifdef __FreeBSD__ # if defined(__FreeBSD_version) && (__FreeBSD_version >= 500043) # define FREEBSD_EXTRA_KEYS "bL" # else # define FREEBSD_EXTRA_KEYS "b" # endif #else # define FREEBSD_EXTRA_KEYS "" #endif dumpkeys = g_strjoin(NULL, level_str, !dle->record ? "" : "u", FREEBSD_EXTRA_KEYS, "s", PARAM_HONOR_NODUMP, "f", NULL); indexcmd = g_strjoin(NULL, RESTORE, " -tvf", " -", " 2>&1", /* not to /dev/null because of DU's dump */ " | ", LEAF_AND_DIRS, NULL); info_tapeheader(dle); start_index(dle->create_index, dumpout, mesgf, indexf, indexcmd); dumppid = pipespawn(cmd, STDIN_PIPE, 0, &dumpin, &dumpout, &mesgf, cmdX, config, "dump", dumpkeys, #ifdef __FreeBSD__ "64", #endif "1048576", #ifdef HAVE_HONOR_NODUMP "0", #endif "-", device, NULL); } #else /* } { */ /* AIX backup program */ dumpkeys = g_strjoin(NULL, "-", level_str, !dle->record ? "" : "u", "f", NULL); indexcmd = g_strjoin(NULL, RESTORE, " -B", " -tvf", " -", " 2>/dev/null", " | ", LEAF_AND_DIRS, NULL); info_tapeheader(dle); start_index(dle->create_index, dumpout, mesgf, indexf, indexcmd); dumppid = pipespawn(cmd, STDIN_PIPE, 0, &dumpin, &dumpout, &mesgf, cmdX, config, "backup", dumpkeys, "-", device, NULL); #endif /* } */ amfree(dumpkeys); amfree(fstype); amfree(device); amfree(cmd); amfree(indexcmd); /* close the write ends of the pipes */ aclose(dumpin); aclose(dumpout); aclose(compout); aclose(dataf); aclose(mesgf); if (dle->create_index) aclose(indexf); }
int main(int argc, char ** argv) { char * tapelist_name; taper_state_t state; config_overwrites_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("taper"); dbopen("server"); device_api_init(); init_taper_state(&state); /* Don't die when child closes pipe */ signal(SIGPIPE, SIG_IGN); g_fprintf(stderr, _("%s: pid %ld executable %s version %s\n"), get_pname(), (long) getpid(), argv[0], version()); dbprintf(_("%s: pid %ld executable %s version %s\n"), get_pname(), (long) getpid(), argv[0], version()); /* Process options */ cfg_ovr = extract_commandline_config_overwrites(&argc, &argv); if(argc > 2) { error("Too many arguments!\n"); g_assert_not_reached(); } if (argc > 1) cfg_opt = argv[1]; config_init(CONFIG_INIT_EXPLICIT_NAME | CONFIG_INIT_USE_CWD, cfg_opt); apply_config_overwrites(cfg_ovr); if (config_errors(NULL) >= CFGERR_ERRORS) { g_critical(_("errors processing config file")); } safe_cd(); add_amanda_log_handler(amanda_log_stderr); add_amanda_log_handler(amanda_log_trace_log); check_running_as(RUNNING_AS_DUMPUSER); dbrename(get_config_name(), DBG_SUBDIR_SERVER); log_add(L_INFO, "%s pid %ld", get_pname(), (long)getpid()); tapelist_name = config_dir_relative(getconf_str(CNF_TAPELIST)); if (read_tapelist(tapelist_name) != 0) { log_add(L_INFO, "pid-done %ld", (long)getpid()); error("could not load tapelist \"%s\"", tapelist_name); g_assert_not_reached(); } amfree(tapelist_name); state.have_changer = changer_init(); if (state.have_changer < 0) { log_add(L_INFO, "pid-done %ld", (long)getpid()); error("changer initialization failed: %s", strerror(errno)); g_assert_not_reached(); } state.next_tape_label = NULL; state.next_tape_device = NULL; state.cur_tape = 0; if (!find_first_tape(&state)) { log_add(L_INFO, "pid-done %ld", (long)getpid()); return EXIT_SUCCESS; } while (process_driver_command(&state)); log_add(L_INFO, "pid-done %ld", (long)getpid()); return EXIT_SUCCESS; }
int main( int argc, char ** argv) { #ifdef GNUTAR int i; char *e; char *dbf; char *cmdline; GPtrArray *array = g_ptr_array_new(); gchar **strings; char **new_argv; #endif if (argc > 1 && argv[1] && g_str_equal(argv[1], "--version")) { printf("runtar-%s\n", VERSION); return (0); } /* * 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("runtar"); /* Don't die when child closes pipe */ signal(SIGPIPE, SIG_IGN); dbopen(DBG_SUBDIR_CLIENT); config_init(CONFIG_INIT_CLIENT, NULL); if (argc < 3) { error(_("Need at least 3 arguments\n")); /*NOTREACHED*/ } dbprintf(_("version %s\n"), VERSION); if (!g_str_equal(argv[3], "--create")) { error(_("Can only be used to create tar archives\n")); /*NOTREACHED*/ } #ifndef GNUTAR g_fprintf(stderr,_("gnutar not available on this system.\n")); dbprintf(_("%s: gnutar not available on this system.\n"), argv[0]); dbclose(); return 1; #else /* * Print out version information for tar. */ do { FILE * version_file; char version_buf[80]; if ((version_file = popen(GNUTAR " --version 2>&1", "r")) != NULL) { if (fgets(version_buf, (int)sizeof(version_buf), version_file) != NULL) { dbprintf(_(GNUTAR " version: %s\n"), version_buf); } else { if (ferror(version_file)) { dbprintf(_(GNUTAR " version: Read failure: %s\n"), strerror(errno)); } else { dbprintf(_(GNUTAR " version: Read failure; EOF\n")); } } } else { dbprintf(_(GNUTAR " version: unavailable: %s\n"), strerror(errno)); } } while(0); #ifdef WANT_SETUID_CLIENT check_running_as(RUNNING_AS_CLIENT_LOGIN | RUNNING_AS_UID_ONLY); if (!become_root()) { error(_("error [%s could not become root (is the setuid bit set?)]\n"), get_pname()); /*NOTREACHED*/ } #else check_running_as(RUNNING_AS_CLIENT_LOGIN); #endif /* skip argv[0] */ argc--; argv++; dbprintf(_("config: %s\n"), argv[0]); if (!g_str_equal(argv[0], "NOCONFIG")) dbrename(argv[0], DBG_SUBDIR_CLIENT); argc--; argv++; new_argv = g_new0(char *, argc+1); new_argv[0] = g_strdup_printf("%s", argv[0]); g_ptr_array_add(array, g_strdup(GNUTAR)); for (i = 1; argv[i]; i++) { g_ptr_array_add(array, quote_string(argv[i])); new_argv[i] = g_strdup_printf("%s", argv[i]); } g_ptr_array_add(array, NULL); strings = (gchar **)g_ptr_array_free(array, FALSE); cmdline = g_strjoinv(" ", strings); g_strfreev(strings); dbprintf(_("running: %s\n"), cmdline); amfree(cmdline); dbf = dbfn(); if (dbf) { dbf = g_strdup(dbf); } dbclose(); execve(GNUTAR, new_argv, safe_env()); e = strerror(errno); dbreopen(dbf, "more"); amfree(dbf); dbprintf(_("execve of %s failed (%s)\n"), GNUTAR, e); dbclose(); g_fprintf(stderr, _("runtar: could not exec %s: %s\n"), GNUTAR, e); return 1; #endif }
/* * doing similar to $ gtar | compression | encryption */ static void start_backup( dle_t *dle, char *host, int dataf, int mesgf, int indexf) { char tmppath[PATH_MAX]; int dumpin, dumpout, compout; char *cmd = NULL; char *indexcmd = NULL; char *dirname = NULL; int l; char dumptimestr[80] = "UNUSED"; struct tm *gmtm; amandates_t *amdates = NULL; time_t prev_dumptime = 0; char *error_pn = NULL; char *compopt = NULL; char *encryptopt = skip_argument; char *tquoted; char *fquoted; char *qdisk; int infd, outfd; ssize_t nb; char buf[32768]; char *amandates_file = NULL; am_level_t *alevel = (am_level_t *)dle->levellist->data; int level = alevel->level; int native_pipe[2]; int client_pipe[2]; int data_out; have_filter = FALSE; crc32_init(&native_crc.crc); crc32_init(&client_crc.crc); /* create pipes to compute the native CRC */ if (pipe(native_pipe) < 0) { char *errmsg; char *qerrmsg; errmsg = g_strdup_printf(_("Program '%s': can't create pipe"), dle->program); qerrmsg = quote_string(errmsg); fdprintf(mesgf, _("sendbackup: error [%s]\n"), errmsg); dbprintf(_("ERROR %s\n"), qerrmsg); amfree(qerrmsg); amfree(errmsg); return; } if (dle->encrypt == ENCRYPT_CUST || dle->compress == COMP_FAST || dle->compress == COMP_BEST || dle->compress == COMP_CUST) { have_filter = TRUE; /* create pipes to compute the client CRC */ if (pipe(client_pipe) < 0) { char *errmsg; char *qerrmsg; errmsg = g_strdup_printf(_("Application '%s': can't create pipe"), dle->program); qerrmsg = quote_string(errmsg); fdprintf(mesgf, _("sendbackup: error [%s]\n"), errmsg); dbprintf(_("ERROR %s\n"), qerrmsg); amfree(qerrmsg); amfree(errmsg); return; } data_out = client_pipe[1]; client_pipe[1] = -1; } else { data_out = dataf; dataf = -1; } error_pn = g_strconcat(get_pname(), "-smbclient", NULL); qdisk = quote_string(dle->disk); dbprintf(_("start: %s:%s lev %d\n"), host, qdisk, level); g_fprintf(stderr, _("%s: start [%s:%s level %d]\n"), get_pname(), host, qdisk, level); /* apply client-side encryption here */ if ( dle->encrypt == ENCRYPT_CUST ) { encpid = pipespawn(dle->clnt_encrypt, STDIN_PIPE, 0, &compout, &data_out, &mesgf, dle->clnt_encrypt, encryptopt, NULL); dbprintf(_("gnutar: pid %ld: %s\n"), (long)encpid, dle->clnt_encrypt); aclose(data_out); } else { compout = data_out; data_out = -1; encpid = -1; } /* now do the client-side compression */ if (dle->compress == COMP_FAST || dle->compress == COMP_BEST) { compopt = skip_argument; #if defined(COMPRESS_BEST_OPT) && defined(COMPRESS_FAST_OPT) if(dle->compress == COMP_BEST) { compopt = COMPRESS_BEST_OPT; } else { compopt = COMPRESS_FAST_OPT; } #endif comppid = pipespawn(COMPRESS_PATH, STDIN_PIPE, 0, &dumpout, &compout, &mesgf, COMPRESS_PATH, compopt, NULL); dbprintf(_("gnutar: pid %ld: %s"), (long)comppid, COMPRESS_PATH); if(compopt != skip_argument) { dbprintf(_("pid %ld: %s %s\n"), (long)comppid, COMPRESS_PATH, compopt); } else { dbprintf(_("pid %ld: %s\n"), (long)comppid, COMPRESS_PATH); } aclose(compout); } else if (dle->compress == COMP_CUST) { compopt = skip_argument; comppid = pipespawn(dle->compprog, STDIN_PIPE, 0, &dumpout, &compout, &mesgf, dle->compprog, compopt, NULL); if(compopt != skip_argument) { dbprintf(_("pid %ld: %s %s\n"), (long)comppid, dle->compprog, compopt); } else { dbprintf(_("pid %ld: %s\n"), (long)comppid, dle->compprog); } aclose(compout); } else { dumpout = compout; compout = -1; comppid = -1; } gnutar_list_dir = getconf_str(CNF_GNUTAR_LIST_DIR); if (strlen(gnutar_list_dir) == 0) gnutar_list_dir = NULL; #ifdef SAMBA_CLIENT /* { */ if (dle->device[0] == '/' && dle->device[1]=='/') amfree(incrname); else #endif /* } */ if (gnutar_list_dir) { char *basename = NULL; char number[NUM_STR_SIZE]; char *inputname = NULL; int baselevel; char *sdisk = sanitise_filename(dle->disk); basename = g_strjoin(NULL, gnutar_list_dir, "/", host, sdisk, NULL); amfree(sdisk); g_snprintf(number, sizeof(number), "%d", level); incrname = g_strjoin(NULL, basename, "_", number, ".new", NULL); unlink(incrname); /* * Open the listed incremental file from the previous level. Search * backward until one is found. If none are found (which will also * be true for a level 0), arrange to read from /dev/null. */ baselevel = level; infd = -1; while (infd == -1) { if (--baselevel >= 0) { g_snprintf(number, sizeof(number), "%d", baselevel); g_free(inputname); inputname = g_strconcat(basename, "_", number, NULL); } else { g_free(inputname); inputname = g_strdup("/dev/null"); } if ((infd = open(inputname, O_RDONLY)) == -1) { int save_errno = errno; char *qname = quote_string(inputname); dbprintf(_("gnutar: error opening '%s': %s\n"), qname, strerror(save_errno)); if (baselevel < 0) { error(_("error [opening '%s': %s]"), qname, strerror(save_errno)); /*NOTREACHED*/ } amfree(qname); } } /* * Copy the previous listed incremental file to the new one. */ if ((outfd = open(incrname, O_WRONLY|O_CREAT, 0600)) == -1) { error(_("error [opening '%s': %s]"), incrname, strerror(errno)); /*NOTREACHED*/ } while ((nb = read(infd, &buf, sizeof(buf))) > 0) { if (full_write(outfd, &buf, (size_t)nb) < (size_t)nb) { error(_("error [writing to '%s': %s]"), incrname, strerror(errno)); /*NOTREACHED*/ } } if (nb < 0) { error(_("error [reading from '%s': %s]"), inputname, strerror(errno)); /*NOTREACHED*/ } if (close(infd) != 0) { error(_("error [closing '%s': %s]"), inputname, strerror(errno)); /*NOTREACHED*/ } if (close(outfd) != 0) { error(_("error [closing '%s': %s]"), incrname, strerror(errno)); /*NOTREACHED*/ } tquoted = quote_string(incrname); if(baselevel >= 0) { fquoted = quote_string(inputname); dbprintf(_("doing level %d dump as listed-incremental from '%s' to '%s'\n"), level, fquoted, tquoted); amfree(fquoted); } else { dbprintf(_("doing level %d dump as listed-incremental to '%s'\n"), level, tquoted); } amfree(tquoted); amfree(inputname); amfree(basename); } else { /* no gnutar-listdir, so we're using amandates */ /* find previous dump time, failing completely if there's a problem */ amandates_file = getconf_str(CNF_AMANDATES); if(!start_amandates(amandates_file, 0)) { error(_("error [opening %s: %s]"), amandates_file, strerror(errno)); /*NOTREACHED*/ } amdates = amandates_lookup(dle->disk); prev_dumptime = EPOCH; for(l = 0; l < level; l++) { if(amdates->dates[l] > prev_dumptime) prev_dumptime = amdates->dates[l]; } finish_amandates(); free_amandates(); gmtm = gmtime(&prev_dumptime); g_snprintf(dumptimestr, sizeof(dumptimestr), "%04d-%02d-%02d %2d:%02d:%02d GMT", gmtm->tm_year + 1900, gmtm->tm_mon+1, gmtm->tm_mday, gmtm->tm_hour, gmtm->tm_min, gmtm->tm_sec); dbprintf(_("gnutar: doing level %d dump from amandates-derived date: %s\n"), level, dumptimestr); } dirname = amname_to_dirname(dle->device); cur_dumptime = time(0); cur_level = level; cur_disk = g_strdup(dle->disk); #ifdef GNUTAR # define PROGRAM_GNUTAR GNUTAR #else # define PROGRAM_GNUTAR "tar" #endif indexcmd = g_strjoin(NULL, PROGRAM_GNUTAR, " -tf", " -", " 2>/dev/null", " | sed", " -e", " \'s/^\\.//\'", NULL); #ifdef SAMBA_CLIENT /* { */ /* Use sambatar if the disk to back up is a PC disk */ if (dle->device[0] == '/' && dle->device[1]=='/') { char *sharename = NULL, *user_and_password = NULL, *domain = NULL; char *share = NULL, *subdir = NULL; char *pwtext = NULL; char *taropt; int passwdf = -1; size_t lpass; size_t pwtext_len; char *pw_fd_env; parsesharename(dle->device, &share, &subdir); if (!share) { amfree(share); amfree(subdir); set_pname(error_pn); amfree(error_pn); error(_("cannot parse disk entry %s for share/subdir"), qdisk); /*NOTREACHED*/ } if ((subdir) && (SAMBA_VERSION < 2)) { amfree(share); amfree(subdir); set_pname(error_pn); amfree(error_pn); error(_("subdirectory specified for share %s but samba not v2 or better"), qdisk); /*NOTREACHED*/ } if ((user_and_password = findpass(share, &domain)) == NULL) { if(domain) { memset(domain, '\0', strlen(domain)); amfree(domain); } set_pname(error_pn); amfree(error_pn); error(_("error [invalid samba host or password not found?]")); /*NOTREACHED*/ } lpass = strlen(user_and_password); if ((pwtext = strchr(user_and_password, '%')) == NULL) { memset(user_and_password, '\0', lpass); amfree(user_and_password); if(domain) { memset(domain, '\0', strlen(domain)); amfree(domain); } set_pname(error_pn); amfree(error_pn); error(_("password field not \'user%%pass\' for %s"), qdisk); /*NOTREACHED*/ } *pwtext++ = '\0'; pwtext_len = strlen(pwtext); if ((sharename = makesharename(share, 0)) == 0) { memset(user_and_password, '\0', lpass); amfree(user_and_password); if(domain) { memset(domain, '\0', strlen(domain)); amfree(domain); } set_pname(error_pn); amfree(error_pn); error(_("error [can't make share name of %s]"), share); /*NOTREACHED*/ } taropt = g_strdup("-T"); if(dle->exclude_file && dle->exclude_file->nb_element == 1) { strappend(taropt, "X"); } #if SAMBA_VERSION >= 2 strappend(taropt, "q"); #endif strappend(taropt, "c"); if (level != 0) { strappend(taropt, "g"); } else if (dle->record) { strappend(taropt, "a"); } if (subdir) { dbprintf(_("gnutar: backup of %s/%s\n"), sharename, subdir); } else { dbprintf(_("gnutar: backup of %s\n"), sharename); } program->backup_name = program->restore_name = SAMBA_CLIENT; cmd = g_strdup(program->backup_name); info_tapeheader(dle); start_index(dle->create_index, native_pipe[1], mesgf, indexf, indexcmd); if (pwtext_len > 0) { pw_fd_env = "PASSWD_FD"; } else { pw_fd_env = "dummy_PASSWD_FD"; } dumppid = pipespawn(cmd, STDIN_PIPE|PASSWD_PIPE, 0, &dumpin, &native_pipe[1], &mesgf, pw_fd_env, &passwdf, "smbclient", sharename, *user_and_password ? "-U" : skip_argument, *user_and_password ? user_and_password : skip_argument, "-E", domain ? "-W" : skip_argument, domain ? domain : skip_argument, #if SAMBA_VERSION >= 2 subdir ? "-D" : skip_argument, subdir ? subdir : skip_argument, #endif "-d0", taropt, "-", dle->exclude_file && dle->exclude_file->nb_element == 1 ? dle->exclude_file->first->name : skip_argument, NULL); if(domain) { memset(domain, '\0', strlen(domain)); amfree(domain); } if(pwtext_len > 0 && full_write(passwdf, pwtext, pwtext_len) < pwtext_len) { int save_errno = errno; aclose(passwdf); memset(user_and_password, '\0', lpass); amfree(user_and_password); set_pname(error_pn); amfree(error_pn); error(_("error [password write failed: %s]"), strerror(save_errno)); /*NOTREACHED*/ } memset(user_and_password, '\0', lpass); amfree(user_and_password); aclose(passwdf); amfree(sharename); amfree(share); amfree(subdir); amfree(taropt); tarpid = dumppid; } else #endif /*end of samba */ { int nb_exclude = 0; int nb_include = 0; GPtrArray *argv_ptr = g_ptr_array_new(); char *file_exclude = NULL; char *file_include = NULL; messagelist_t mlist = NULL; if (dle->exclude_file) nb_exclude+=dle->exclude_file->nb_element; if (dle->exclude_list) nb_exclude+=dle->exclude_list->nb_element; if (dle->include_file) nb_include+=dle->include_file->nb_element; if (dle->include_list) nb_include+=dle->include_list->nb_element; if (nb_exclude > 0) file_exclude = build_exclude(dle, &mlist); if (nb_include > 0) file_include = build_include(dle, dirname, &mlist); g_slist_free(mlist); // MUST also free the message cmd = g_strjoin(NULL, amlibexecdir, "/", "runtar", NULL); info_tapeheader(dle); start_index(dle->create_index, native_pipe[1], mesgf, indexf, indexcmd); g_ptr_array_add(argv_ptr, g_strdup("runtar")); if (g_options->config) g_ptr_array_add(argv_ptr, g_strdup(g_options->config)); else g_ptr_array_add(argv_ptr, g_strdup("NOCONFIG")); #ifdef GNUTAR g_ptr_array_add(argv_ptr, g_strdup(GNUTAR)); #else g_ptr_array_add(argv_ptr, g_strdup("tar")); #endif g_ptr_array_add(argv_ptr, g_strdup("--create")); g_ptr_array_add(argv_ptr, g_strdup("--file")); g_ptr_array_add(argv_ptr, g_strdup("-")); g_ptr_array_add(argv_ptr, g_strdup("--directory")); canonicalize_pathname(dirname, tmppath); g_ptr_array_add(argv_ptr, g_strdup(tmppath)); g_ptr_array_add(argv_ptr, g_strdup("--one-file-system")); if (gnutar_list_dir && incrname) { g_ptr_array_add(argv_ptr, g_strdup("--listed-incremental")); g_ptr_array_add(argv_ptr, g_strdup(incrname)); } else { g_ptr_array_add(argv_ptr, g_strdup("--incremental")); g_ptr_array_add(argv_ptr, g_strdup("--newer")); g_ptr_array_add(argv_ptr, g_strdup(dumptimestr)); } #ifdef ENABLE_GNUTAR_ATIME_PRESERVE /* --atime-preserve causes gnutar to call * utime() after reading files in order to * adjust their atime. However, utime() * updates the file's ctime, so incremental * dumps will think the file has changed. */ g_ptr_array_add(argv_ptr, g_strdup("--atime-preserve")); #endif g_ptr_array_add(argv_ptr, g_strdup("--sparse")); g_ptr_array_add(argv_ptr, g_strdup("--ignore-failed-read")); g_ptr_array_add(argv_ptr, g_strdup("--totals")); if(file_exclude) { g_ptr_array_add(argv_ptr, g_strdup("--exclude-from")); g_ptr_array_add(argv_ptr, g_strdup(file_exclude)); } if(file_include) { g_ptr_array_add(argv_ptr, g_strdup("--files-from")); g_ptr_array_add(argv_ptr, g_strdup(file_include)); } else { g_ptr_array_add(argv_ptr, g_strdup(".")); } g_ptr_array_add(argv_ptr, NULL); dumppid = pipespawnv(cmd, STDIN_PIPE, 0, &dumpin, &native_pipe[1], &mesgf, (char **)argv_ptr->pdata); tarpid = dumppid; amfree(file_exclude); amfree(file_include); g_ptr_array_free_full(argv_ptr); } dbprintf(_("gnutar: %s: pid %ld\n"), cmd, (long)dumppid); amfree(qdisk); amfree(dirname); amfree(cmd); amfree(indexcmd); amfree(error_pn); /* close the write ends of the pipes */ aclose(dumpin); aclose(native_pipe[1]); aclose(mesgf); if (dle->create_index) aclose(indexf); if (shm_control_name) { shm_ring = shm_ring_link(shm_control_name); shm_ring_producer_set_size(shm_ring, NETWORK_BLOCK_BYTES*16, NETWORK_BLOCK_BYTES*4); native_crc.in = native_pipe[0]; if (!have_filter) { native_crc.out = dumpout; native_crc.shm_ring = shm_ring; native_crc.thread = g_thread_create(handle_crc_to_shm_ring_thread, (gpointer)&native_crc, TRUE, NULL); } else { native_crc.out = dumpout; native_crc.thread = g_thread_create(handle_crc_thread, (gpointer)&native_crc, TRUE, NULL); client_crc.in = client_pipe[0]; client_crc.out = dataf; client_crc.shm_ring = shm_ring; client_crc.thread = g_thread_create(handle_crc_to_shm_ring_thread, (gpointer)&client_crc, TRUE, NULL); } } else { native_crc.in = native_pipe[0]; native_crc.out = dumpout; native_crc.thread = g_thread_create(handle_crc_thread, (gpointer)&native_crc, TRUE, NULL); if (have_filter) { client_crc.in = client_pipe[0]; client_crc.out = dataf; client_crc.thread = g_thread_create(handle_crc_thread, (gpointer)&client_crc, TRUE, NULL); } } }
int main( int argc, char ** argv) { int foreground; int batch; int redirect; char **datearg = NULL; int nb_datearg = 0; char *conf_diskfile; char *conf_tapelist; char *conf_logfile; int conf_usetimestamps; disklist_t diskq; disk_t *dp; pid_t pid; pid_t driver_pid, reporter_pid; amwait_t exitcode; int opt; GSList *holding_list=NULL, *holding_file; int driver_pipe[2]; char date_string[100]; char date_string_standard[100]; time_t today; char *errstr; struct tm *tm; char *tapedev; char *tpchanger; char *qdisk, *qhname; GSList *datestamp_list = NULL; config_overrides_t *cfg_ovr; char **config_options; find_result_t *holding_files; disklist_t holding_disklist = { NULL, 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("amflush"); /* Don't die when child closes pipe */ signal(SIGPIPE, SIG_IGN); dbopen(DBG_SUBDIR_SERVER); add_amanda_log_handler(amanda_log_stderr); foreground = 0; batch = 0; redirect = 1; /* process arguments */ cfg_ovr = new_config_overrides(argc/2); while((opt = getopt(argc, argv, "bfso:D:")) != EOF) { switch(opt) { case 'b': batch = 1; break; case 'f': foreground = 1; break; case 's': redirect = 0; break; case 'o': add_config_override_opt(cfg_ovr, optarg); break; case 'D': if (datearg == NULL) datearg = g_malloc(21*sizeof(char *)); if(nb_datearg == 20) { g_fprintf(stderr,_("maximum of 20 -D arguments.\n")); exit(1); } datearg[nb_datearg++] = g_strdup(optarg); datearg[nb_datearg] = NULL; break; } } argc -= optind, argv += optind; if(!foreground && !redirect) { g_fprintf(stderr,_("Can't redirect to stdout/stderr if not in forground.\n")); exit(1); } if(argc < 1) { error(_("Usage: amflush [-b] [-f] [-s] [-D date]* [-o configoption]* <confdir> [host [disk]* ]*")); /*NOTREACHED*/ } set_config_overrides(cfg_ovr); config_init(CONFIG_INIT_EXPLICIT_NAME, argv[0]); conf_diskfile = config_dir_relative(getconf_str(CNF_DISKFILE)); read_diskfile(conf_diskfile, &diskq); 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); /* load DLEs from the holding disk, in case there's anything to flush there */ search_holding_disk(&holding_files, &holding_disklist); /* note that the dumps are added to the global disklist, so we need not * consult holding_files or holding_disklist after this. The holding-only * dumps will be filtered properly by match_disklist, setting the dp->todo * flag appropriately. */ errstr = match_disklist(&diskq, argc-1, argv+1); if (errstr) { g_printf(_("%s"),errstr); amfree(errstr); } 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); conf_usetimestamps = getconf_boolean(CNF_USETIMESTAMPS); amflush_datestamp = get_datestamp_from_time(0); if(conf_usetimestamps == 0) { amflush_timestamp = g_strdup(amflush_datestamp); } else { amflush_timestamp = get_timestamp_from_time(0); } conf_logdir = config_dir_relative(getconf_str(CNF_LOGDIR)); conf_logfile = g_strjoin(NULL, conf_logdir, "/log", NULL); if (access(conf_logfile, F_OK) == 0) { run_amcleanup(get_config_name()); } if (access(conf_logfile, F_OK) == 0) { char *process_name = get_master_process(conf_logfile); error(_("%s exists: %s is already running, or you must run amcleanup"), conf_logfile, process_name); /*NOTREACHED*/ } driver_program = g_strjoin(NULL, amlibexecdir, "/", "driver", NULL); reporter_program = g_strjoin(NULL, sbindir, "/", "amreport", NULL); logroll_program = g_strjoin(NULL, amlibexecdir, "/", "amlogroll", NULL); tapedev = getconf_str(CNF_TAPEDEV); tpchanger = getconf_str(CNF_TPCHANGER); if (tapedev == NULL && tpchanger == NULL) { error(_("No tapedev or tpchanger specified")); } /* if dates were specified (-D), then use match_datestamp * against the list of all datestamps to turn that list * into a set of existing datestamps (basically, evaluate the * expressions into actual datestamps) */ if(datearg) { GSList *all_datestamps; GSList *datestamp; int i, ok; all_datestamps = holding_get_all_datestamps(); for(datestamp = all_datestamps; datestamp != NULL; datestamp = datestamp->next) { ok = 0; for(i=0; i<nb_datearg && ok==0; i++) { ok = match_datestamp(datearg[i], (char *)datestamp->data); } if (ok) datestamp_list = g_slist_insert_sorted(datestamp_list, g_strdup((char *)datestamp->data), g_compare_strings); } slist_free_full(all_datestamps, g_free); } else { /* otherwise, in batch mode, use all datestamps */ if(batch) { datestamp_list = holding_get_all_datestamps(); } /* or allow the user to pick datestamps */ else { datestamp_list = pick_datestamp(); } } if(!datestamp_list) { g_printf(_("Could not find any Amanda directories to flush.\n")); exit(1); } holding_list = holding_get_files_for_flush(datestamp_list); if (holding_list == NULL) { g_printf(_("Could not find any valid dump image, check directory.\n")); exit(1); } if (access(conf_logfile, F_OK) == 0) { char *process_name = get_master_process(conf_logfile); error(_("%s exists: someone started %s"), conf_logfile, process_name); /*NOTREACHED*/ } log_add(L_INFO, "%s pid %ld", get_pname(), (long)getpid()); if(!batch) confirm(datestamp_list); for(dp = diskq.head; dp != NULL; dp = dp->next) { if(dp->todo) { char *qname; qname = quote_string(dp->name); log_add(L_DISK, "%s %s", dp->host->hostname, qname); amfree(qname); } } if(!foreground) { /* write it before redirecting stdout */ puts(_("Running in background, you can log off now.")); puts(_("You'll get mail when amflush is finished.")); } if(redirect) redirect_stderr(); if(!foreground) detach(); add_amanda_log_handler(amanda_log_stderr); add_amanda_log_handler(amanda_log_trace_log); today = time(NULL); tm = localtime(&today); if (tm) { strftime(date_string, 100, "%a %b %e %H:%M:%S %Z %Y", tm); strftime(date_string_standard, 100, "%Y-%m-%d %H:%M:%S %Z", tm); } else { error(_("BAD DATE")); /* should never happen */ } g_fprintf(stderr, _("amflush: start at %s\n"), date_string); g_fprintf(stderr, _("amflush: datestamp %s\n"), amflush_timestamp); g_fprintf(stderr, _("amflush: starttime %s\n"), amflush_timestamp); g_fprintf(stderr, _("amflush: starttime-locale-independent %s\n"), date_string_standard); log_add(L_START, _("date %s"), amflush_timestamp); /* START DRIVER */ if(pipe(driver_pipe) == -1) { error(_("error [opening pipe to driver: %s]"), strerror(errno)); /*NOTREACHED*/ } if((driver_pid = fork()) == 0) { /* * This is the child process. */ dup2(driver_pipe[0], 0); close(driver_pipe[1]); config_options = get_config_options(3); config_options[0] = "driver"; config_options[1] = get_config_name(); config_options[2] = "nodump"; safe_fd(-1, 0); execve(driver_program, config_options, safe_env()); error(_("cannot exec %s: %s"), driver_program, strerror(errno)); /*NOTREACHED*/ } else if(driver_pid == -1) { error(_("cannot fork for %s: %s"), driver_program, strerror(errno)); /*NOTREACHED*/ } driver_stream = fdopen(driver_pipe[1], "w"); if (!driver_stream) { error(_("Can't fdopen: %s"), strerror(errno)); /*NOTREACHED*/ } g_fprintf(driver_stream, "DATE %s\n", amflush_timestamp); for(holding_file=holding_list; holding_file != NULL; holding_file = holding_file->next) { dumpfile_t file; holding_file_get_dumpfile((char *)holding_file->data, &file); if (holding_file_size((char *)holding_file->data, 1) <= 0) { g_debug("%s is empty - ignoring", (char *)holding_file->data); log_add(L_INFO, "%s: removing file with no data.", (char *)holding_file->data); holding_file_unlink((char *)holding_file->data); dumpfile_free_data(&file); continue; } /* search_holding_disk should have already ensured that every * holding dumpfile has an entry in the dynamic disklist */ dp = lookup_disk(file.name, file.disk); assert(dp != NULL); /* but match_disklist may have indicated we should not flush it */ if (dp->todo == 0) continue; qdisk = quote_string(file.disk); qhname = quote_string((char *)holding_file->data); g_fprintf(stderr, "FLUSH %s %s %s %d %s\n", file.name, qdisk, file.datestamp, file.dumplevel, qhname); g_debug("flushing '%s'", (char *)holding_file->data); g_fprintf(driver_stream, "FLUSH %s %s %s %d %s\n", file.name, qdisk, file.datestamp, file.dumplevel, qhname); amfree(qdisk); amfree(qhname); dumpfile_free_data(&file); } g_fprintf(stderr, "ENDFLUSH\n"); fflush(stderr); g_fprintf(driver_stream, "ENDFLUSH\n"); fflush(driver_stream); fclose(driver_stream); /* WAIT DRIVER */ while(1) { if((pid = wait(&exitcode)) == -1) { if(errno == EINTR) { continue; } else { error(_("wait for %s: %s"), driver_program, strerror(errno)); /*NOTREACHED*/ } } else if (pid == driver_pid) { break; } } slist_free_full(datestamp_list, g_free); datestamp_list = NULL; slist_free_full(holding_list, g_free); holding_list = NULL; if(redirect) { /* rename errfile */ char *errfile, *errfilex, *nerrfilex, number[100]; int tapecycle; int maxdays, days; struct stat stat_buf; errfile = g_strjoin(NULL, conf_logdir, "/amflush", NULL); errfilex = NULL; nerrfilex = NULL; tapecycle = getconf_int(CNF_TAPECYCLE); maxdays = tapecycle + 2; days = 1; /* First, find out the last existing errfile, */ /* to avoid ``infinite'' loops if tapecycle is infinite */ g_snprintf(number,100,"%d",days); errfilex = newvstralloc(errfilex, errfile, ".", number, NULL); while ( days < maxdays && stat(errfilex,&stat_buf)==0) { days++; g_snprintf(number,100,"%d",days); errfilex = newvstralloc(errfilex, errfile, ".", number, NULL); } g_snprintf(number,100,"%d",days); errfilex = newvstralloc(errfilex, errfile, ".", number, NULL); nerrfilex = NULL; while (days > 1) { amfree(nerrfilex); nerrfilex = errfilex; days--; g_snprintf(number,100,"%d",days); errfilex = g_strjoin(NULL, errfile, ".", number, NULL); if (rename(errfilex, nerrfilex) != 0) { error(_("cannot rename \"%s\" to \"%s\": %s"), errfilex, nerrfilex, strerror(errno)); /*NOTREACHED*/ } } errfilex = newvstralloc(errfilex, errfile, ".1", NULL); if (rename(errfile,errfilex) != 0) { error(_("cannot rename \"%s\" to \"%s\": %s"), errfilex, nerrfilex, strerror(errno)); /*NOTREACHED*/ } amfree(errfile); amfree(errfilex); amfree(nerrfilex); } /* * Have amreport generate report and send mail. Note that we do * not bother checking the exit status. If it does not work, it * can be rerun. */ if((reporter_pid = fork()) == 0) { /* * This is the child process. */ config_options = get_config_options(3); config_options[0] = "amreport"; config_options[1] = get_config_name(); config_options[2] = "--from-amdump"; safe_fd(-1, 0); execve(reporter_program, config_options, safe_env()); error(_("cannot exec %s: %s"), reporter_program, strerror(errno)); /*NOTREACHED*/ } else if(reporter_pid == -1) { error(_("cannot fork for %s: %s"), reporter_program, strerror(errno)); /*NOTREACHED*/ } while(1) { if((pid = wait(&exitcode)) == -1) { if(errno == EINTR) { continue; } else { error(_("wait for %s: %s"), reporter_program, strerror(errno)); /*NOTREACHED*/ } } else if (pid == reporter_pid) { break; } } log_add(L_INFO, "pid-done %ld", (long)getpid()); /* * Call amlogroll to rename the log file to its datestamped version. * Since we exec at this point, our exit code will be that of amlogroll. */ config_options = get_config_options(2); config_options[0] = "amlogroll"; config_options[1] = get_config_name(); safe_fd(-1, 0); execve(logroll_program, config_options, safe_env()); error(_("cannot exec %s: %s"), logroll_program, strerror(errno)); /*NOTREACHED*/ return 0; /* keep the compiler happy */ }
char *look_in_lisp_variable(char *o, int prefix) { Lisp_Object nil, var; /* * I will start by tagging a '$' (or whatever) on in front of the * parameter name. */ o[0] = (char)prefix; var = make_undefined_symbol(o); nil = C_nil; /* * make_undefined_symbol() could fail either if we had utterly run out * of memory or if somebody generated an interrupt (eg ^C) around now. Ugh. */ if (exception_pending()) { flip_exception(); return NULL; } /* * If the variable $name was undefined then I use an empty replacement * text for it. Otherwise I need to look harder at its value. */ if (qvalue(var) == unset_var) return o; else { Header h; intptr_t len; var = qvalue(var); /* * Mostly I expect that the value will be a string or symbol. */ #ifdef COMMON if (complex_stringp(var)) { var = simplify_string(var); nil = C_nil; if (exception_pending()) { flip_exception(); return NULL; } } #endif /* COMMON */ if (symbolp(var)) { var = get_pname(var); nil = C_nil; if (exception_pending()) { flip_exception(); return NULL; } h = vechdr(var); } else if (!is_vector(var) || type_of_header(h = vechdr(var)) != TYPE_STRING) return NULL; len = length_of_header(h) - CELL; /* * Copy the characters from the string or from the name of the variable * into the file-name buffer. There could at present be a crash here * if the expansion was very very long and overflowed my buffer. Tough * luck for now - people doing that (maybe) get what they (maybe) deserve. */ memcpy(o, (char *)var + (CELL - TAG_VECTOR), (size_t)len); o = o + len; return o; } }
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 = g_strdup(gnutar_path); g_ptr_array_add(argv_ptr, g_strdup(gnutar_path)); g_ptr_array_add(argv_ptr, g_strdup("--numeric-owner")); if (gnutar_no_unquote) g_ptr_array_add(argv_ptr, g_strdup("--no-unquote")); if (gnutar_acls) g_ptr_array_add(argv_ptr, g_strdup("--acls")); if (gnutar_selinux) g_ptr_array_add(argv_ptr, g_strdup("--selinux")); if (gnutar_xattrs) g_ptr_array_add(argv_ptr, g_strdup("--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, g_strdup("--ignore-zeros")); } if (argument->tar_blocksize) { g_ptr_array_add(argv_ptr, g_strdup("--blocking-factor")); g_ptr_array_add(argv_ptr, g_strdup(argument->tar_blocksize)); } g_ptr_array_add(argv_ptr, g_strdup("-xpGvf")); g_ptr_array_add(argv_ptr, g_strdup("-")); 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, g_strdup("--directory")); g_ptr_array_add(argv_ptr, g_strdup(gnutar_directory)); } g_ptr_array_add(argv_ptr, g_strdup("--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", (int)getpid()); } exclude_filename= g_strjoin(NULL, AMANDA_TMPDIR, "/", "exclude-", sdisk, NULL); exclude_list = fopen(argument->dle.exclude_list->first->name, "r"); if (!exclude_list) { fprintf(stderr, "Cannot open exclude file '%s': %s\n", argument->dle.exclude_list->first->name, strerror(errno)); error("Cannot open exclude file '%s': %s\n", argument->dle.exclude_list->first->name, strerror(errno)); /*NOTREACHED*/ } exclude = fopen(exclude_filename, "w"); if (!exclude) { fprintf(stderr, "Cannot open exclude file '%s': %s\n", exclude_filename, strerror(errno)); fclose(exclude_list); error("Cannot open exclude file '%s': %s\n", exclude_filename, strerror(errno)); /*NOTREACHED*/ } 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_list); fclose(exclude); g_ptr_array_add(argv_ptr, g_strdup("--exclude-from")); g_ptr_array_add(argv_ptr, exclude_filename); } if (argument->exclude_list_glob) { g_ptr_array_add(argv_ptr, g_strdup("--exclude-from")); g_ptr_array_add(argv_ptr, g_strdup(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", (int)getpid()); } include_filename = g_strjoin(NULL, AMANDA_TMPDIR, "/", "include-", sdisk, NULL); include = fopen(include_filename, "w"); if (!include) { fprintf(stderr, "Cannot open include file '%s': %s\n", include_filename, strerror(errno)); error("Cannot open include file '%s': %s\n", include_filename, strerror(errno)); /*NOTREACHED*/ } 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"); if (!include_list) { fclose(include); fprintf(stderr, "Cannot open include file '%s': %s\n", argument->dle.include_list->first->name, strerror(errno)); error("Cannot open include file '%s': %s\n", argument->dle.include_list->first->name, strerror(errno)); /*NOTREACHED*/ } 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); } } fclose(include_list); } 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, g_strdup("--files-from")); g_ptr_array_add(argv_ptr, include_filename); } if (argument->include_list_glob) { g_ptr_array_add(argv_ptr, g_strdup("--files-from")); g_ptr_array_add(argv_ptr, g_strdup(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)); } amfree(sdisk); } 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); unlink(include_filename); } amfree(cmd); amfree(include_filename); amfree(exclude_filename); }