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) { #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 }
static void amgtar_estimate( application_argument_t *argument) { char *incrname = NULL; GPtrArray *argv_ptr; char *cmd = NULL; int nullfd = -1; int pipefd = -1; FILE *dumpout = NULL; off_t size = -1; char line[32768]; char *errmsg = NULL; char *qerrmsg = NULL; char *qdisk; amwait_t wait_status; int tarpid; amregex_t *rp; times_t start_time; int level; GSList *levels; if (!argument->level) { fprintf(stderr, "ERROR No level argument\n"); error(_("No level argument")); } if (!argument->dle.disk) { fprintf(stderr, "ERROR No disk argument\n"); error(_("No disk argument")); } if (!argument->dle.device) { fprintf(stderr, "ERROR No device argument\n"); error(_("No device argument")); } qdisk = quote_string(argument->dle.disk); if (argument->calcsize) { char *dirname; char *file_exclude; char *file_include; int nb_exclude; int nb_include; if (gnutar_directory) { dirname = gnutar_directory; } else { dirname = amname_to_dirname(argument->dle.device); } amgtar_build_exinclude(&argument->dle, 1, &nb_exclude, &file_exclude, &nb_include, &file_include); run_calcsize(argument->config, "GNUTAR", argument->dle.disk, dirname, argument->level, file_exclude, file_include); return; } if (!gnutar_path) { errmsg = vstrallocf(_("GNUTAR-PATH not defined")); goto common_error; } if (!gnutar_listdir) { errmsg = vstrallocf(_("GNUTAR-LISTDIR not defined")); goto common_error; } for (levels = argument->level; levels != NULL; levels = levels->next) { level = GPOINTER_TO_INT(levels->data); incrname = amgtar_get_incrname(argument, level); cmd = stralloc(gnutar_path); argv_ptr = amgtar_build_argv(argument, incrname, CMD_ESTIMATE); start_time = curclock(); if ((nullfd = open("/dev/null", O_RDWR)) == -1) { errmsg = vstrallocf(_("Cannot access /dev/null : %s"), strerror(errno)); goto common_exit; } tarpid = pipespawnv(cmd, STDERR_PIPE, 1, &nullfd, &nullfd, &pipefd, (char **)argv_ptr->pdata); dumpout = fdopen(pipefd,"r"); if (!dumpout) { error(_("Can't fdopen: %s"), strerror(errno)); /*NOTREACHED*/ } size = (off_t)-1; while (size < 0 && (fgets(line, sizeof(line), dumpout) != NULL)) { if (line[strlen(line)-1] == '\n') /* remove trailling \n */ line[strlen(line)-1] = '\0'; if (line[0] == '\0') continue; dbprintf("%s\n", line); /* check for size match */ /*@ignore@*/ for(rp = re_table; rp->regex != NULL; rp++) { if(match(rp->regex, line)) { if (rp->typ == DMP_SIZE) { size = ((the_num(line, rp->field)*rp->scale+1023.0)/1024.0); if(size < 0.0) size = 1.0; /* found on NeXT -- sigh */ } break; } } /*@end@*/ } while (fgets(line, sizeof(line), dumpout) != NULL) { dbprintf("%s", line); } dbprintf(".....\n"); dbprintf(_("estimate time for %s level %d: %s\n"), qdisk, level, walltime_str(timessub(curclock(), start_time))); if(size == (off_t)-1) { errmsg = vstrallocf(_("no size line match in %s output"), cmd); dbprintf(_("%s for %s\n"), errmsg, qdisk); dbprintf(".....\n"); } else if(size == (off_t)0 && argument->level == 0) { dbprintf(_("possible %s problem -- is \"%s\" really empty?\n"), cmd, argument->dle.disk); dbprintf(".....\n"); } dbprintf(_("estimate size for %s level %d: %lld KB\n"), qdisk, level, (long long)size); kill(-tarpid, SIGTERM); dbprintf(_("waiting for %s \"%s\" child\n"), cmd, qdisk); 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); common_exit: if (errmsg) { dbprintf("%s", errmsg); fprintf(stdout, "ERROR %s\n", errmsg); } if (incrname) { unlink(incrname); } g_ptr_array_free_full(argv_ptr); amfree(cmd); aclose(nullfd); afclose(dumpout); fprintf(stdout, "%d %lld 1\n", level, (long long)size); } amfree(qdisk); return; common_error: qerrmsg = quote_string(errmsg); amfree(qdisk); dbprintf("%s", errmsg); fprintf(stdout, "ERROR %s\n", qerrmsg); amfree(errmsg); amfree(qerrmsg); return; }