X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=client-src%2Fsendbackup.c;h=6da1326a86a7a28ff4941f98af9c25cc3662a17a;hb=2627875b7d18858bc1f9f7652811e4d8c15a23eb;hp=9f26dafe2e2d3ccf02db171a2da62cc57d227b12;hpb=94a044f90357edefa6f4ae9f0b1d5885b0e34aee;p=debian%2Famanda diff --git a/client-src/sendbackup.c b/client-src/sendbackup.c index 9f26daf..6da1326 100644 --- a/client-src/sendbackup.c +++ b/client-src/sendbackup.c @@ -39,6 +39,7 @@ #include "getfsent.h" #include "version.h" #include "conffile.h" +#include "amandates.h" #define sendbackup_debug(i, ...) do { \ if ((i) <= debug_sendbackup) { \ @@ -53,18 +54,19 @@ pid_t dumppid = (pid_t)-1; pid_t tarpid = (pid_t)-1; pid_t encpid = (pid_t)-1; pid_t indexpid = (pid_t)-1; +pid_t application_api_pid = (pid_t)-1; char *errorstr = NULL; int datafd; int mesgfd; int indexfd; -option_t *options; g_option_t *g_options = NULL; long dump_size = -1; backup_program_t *program = NULL; +dle_t *gdle = NULL; static am_feature_t *our_features = NULL; static char *our_feature_string = NULL; @@ -72,110 +74,38 @@ static char *amandad_auth = NULL; /* local functions */ int main(int argc, char **argv); -char *optionstr(option_t *options); char *childstr(pid_t pid); -int check_status(pid_t pid, amwait_t w); +int check_status(pid_t pid, amwait_t w, int mesgfd); pid_t pipefork(void (*func)(void), char *fname, int *stdinfd, int stdoutfd, int stderrfd); -void parse_backup_messages(int mesgin); +int check_result(int mesgfd); +void parse_backup_messages(dle_t *dle, int mesgin); static void process_dumpline(char *str); static void save_fd(int *, int); -void backup_api_info_tapeheader(int mesgfd, char *prog, option_t *options); +void application_api_info_tapeheader(int mesgfd, char *prog, dle_t *dle); -double the_num(char *str, int pos); +int fdprintf(int fd, char *format, ...) G_GNUC_PRINTF(2, 3); - -char * -optionstr( - option_t * options) +int +fdprintf( + int fd, + char *format, + ...) { - static char *optstr = NULL; - char *compress_opt; - char *encrypt_opt; - char *decrypt_opt; - char *record_opt = ""; - char *index_opt = ""; - char *auth_opt; - char *exclude_file_opt; - char *exclude_list_opt; - char *exc = NULL; - sle_t *excl; - - if(options->compress == COMP_BEST) - compress_opt = stralloc("compress-best;"); - else if(options->compress == COMP_FAST) - compress_opt = stralloc("compress-fast;"); - else if(options->compress == COMP_SERVER_BEST) - compress_opt = stralloc("srvcomp-best;"); - else if(options->compress == COMP_SERVER_FAST) - compress_opt = stralloc("srvcomp-fast;"); - else if(options->compress == COMP_SERVER_CUST) - compress_opt = vstralloc("srvcomp-cust=", options->srvcompprog, ";", NULL); - else if(options->compress == COMP_CUST) - compress_opt = vstralloc("comp-cust=", options->clntcompprog, ";", NULL); - else - compress_opt = stralloc(""); - - if(options->encrypt == ENCRYPT_CUST) { - encrypt_opt = vstralloc("encrypt-cust=", options->clnt_encrypt, ";", NULL); - if (options->clnt_decrypt_opt) - decrypt_opt = vstralloc("client-decrypt-option=", options->clnt_decrypt_opt, ";", NULL); - else - decrypt_opt = stralloc(""); - } - else if(options->encrypt == ENCRYPT_SERV_CUST) { - encrypt_opt = vstralloc("encrypt-serv-cust=", options->srv_encrypt, ";", NULL); - if(options->srv_decrypt_opt) - decrypt_opt = vstralloc("server-decrypt-option=", options->srv_decrypt_opt, ";", NULL); - else - decrypt_opt = stralloc(""); - } - else { - encrypt_opt = stralloc(""); - decrypt_opt = stralloc(""); - } + va_list argp; + char *s; + int r; - if(options->no_record) record_opt = "no-record;"; - if(options->auth) auth_opt = vstralloc("auth=", options->auth, ";", NULL); - else auth_opt = stralloc(""); - if(options->createindex) index_opt = "index;"; + arglist_start(argp, format); + s = g_strdup_vprintf(format, argp); + arglist_end(argp); - exclude_file_opt = stralloc(""); - if(options->exclude_file) { - for(excl = options->exclude_file->first; excl != NULL; excl=excl->next){ - exc = newvstralloc(exc, "exclude-file=", excl->name, ";", NULL); - strappend(exclude_file_opt, exc); - } - } - exclude_list_opt = stralloc(""); - if(options->exclude_list) { - for(excl = options->exclude_list->first; excl != NULL; excl=excl->next){ - exc = newvstralloc(exc, "exclude-list=", excl->name, ";", NULL); - strappend(exclude_list_opt, exc); - } - } - amfree(exc); - optstr = newvstralloc(optstr, - compress_opt, - encrypt_opt, - decrypt_opt, - record_opt, - index_opt, - auth_opt, - exclude_file_opt, - exclude_list_opt, - NULL); - amfree(compress_opt); - amfree(encrypt_opt); - amfree(decrypt_opt); - amfree(auth_opt); - amfree(exclude_file_opt); - amfree(exclude_list_opt); - return optstr; + r = full_write(fd, s, strlen(s)); + amfree(s); + return r; } - int main( int argc, @@ -184,22 +114,19 @@ main( int interactive = 0; int level = 0; int mesgpipe[2]; - char *prog, *dumpdate, *stroptions; - int program_is_backup_api; - char *disk = NULL; + dle_t *dle = NULL; + char *dumpdate, *stroptions; char *qdisk = NULL; - char *amdevice = NULL; char *qamdevice = NULL; char *line = NULL; char *err_extra = NULL; char *s; int i; int ch; - FILE *toolin; - int status; + GSList *errlist; + FILE *mesgstream; /* initialize */ - /* * Configure program for internationalization: * 1) Only set the message locale for now. @@ -242,6 +169,7 @@ main( our_feature_string = am_feature_to_string(our_features); config_init(CONFIG_INIT_CLIENT, NULL); + /* (check for config errors comes later) */ check_running_as(RUNNING_AS_CLIENT_LOGIN); @@ -256,13 +184,9 @@ main( fflush(stderr); } - prog = NULL; - disk = NULL; qdisk = NULL; - amdevice = NULL; dumpdate = NULL; stroptions = NULL; - program_is_backup_api=0; for(; (line = agets(stdin)) != NULL; free(line)) { if (line[0] == '\0') @@ -284,17 +208,31 @@ main( config_init(CONFIG_INIT_CLIENT | CONFIG_INIT_EXPLICIT_NAME | CONFIG_INIT_OVERLAY, g_options->config); - dbrename(config_name, DBG_SUBDIR_CLIENT); + dbrename(get_config_name(), DBG_SUBDIR_CLIENT); + } + + /* check for any config errors now */ + if (config_errors(&errlist) >= CFGERR_ERRORS) { + char *errstr = config_errors_to_error_string(errlist); + g_printf("%s\n", errstr); + dbclose(); + return 1; + } + + if (am_has_feature(g_options->features, fe_req_xml)) { + break; } continue; } - if (prog != NULL) { + if (dle && dle->program != NULL) { err_extra = _("multiple requests"); goto err; } dbprintf(_(" sendbackup req: <%s>\n"), line); + dle = alloc_dle(); + s = line; ch = *s++; @@ -303,21 +241,21 @@ main( err_extra = _("no program name"); goto err; /* no program name */ } - prog = s - 1; + dle->program = s - 1; skip_non_whitespace(s, ch); s[-1] = '\0'; - if(strcmp(prog,"BACKUP")==0) { - program_is_backup_api=1; - skip_whitespace(s, ch); /* find dumper name */ - if (ch == '\0') { - goto err; /* no program */ - } - prog = s - 1; - skip_non_whitespace(s, ch); - s[-1] = '\0'; - } - prog = stralloc(prog); + if (strcmp(dle->program, "APPLICATION")==0) { + dle->program_is_application_api=1; + skip_whitespace(s, ch); /* find dumper name */ + if (ch == '\0') { + goto err; /* no program */ + } + dle->program = s - 1; + skip_non_whitespace(s, ch); + s[-1] = '\0'; + } + dle->program = stralloc(dle->program); skip_whitespace(s, ch); /* find the disk name */ if(ch == '\0') { @@ -325,14 +263,13 @@ main( goto err; /* no disk name */ } - amfree(disk); amfree(qdisk); qdisk = s - 1; ch = *qdisk; skip_quoted_string(s, ch); s[-1] = '\0'; qdisk = stralloc(qdisk); - disk = unquote_string(qdisk); + dle->disk = unquote_string(qdisk); skip_whitespace(s, ch); /* find the device or level */ if (ch == '\0') { @@ -341,18 +278,17 @@ main( } if(!isdigit((int)s[-1])) { - amfree(amdevice); amfree(qamdevice); qamdevice = s - 1; ch = *qamdevice; skip_quoted_string(s, ch); s[-1] = '\0'; qamdevice = stralloc(qamdevice); - amdevice = unquote_string(qamdevice); + dle->device = unquote_string(qamdevice); skip_whitespace(s, ch); /* find level number */ } else { - amdevice = stralloc(disk); + dle->device = stralloc(dle->disk); qamdevice = stralloc(qdisk); } /* find the level number */ @@ -361,6 +297,7 @@ main( goto err; /* bad level */ } skip_integer(s, ch); + dle->level = g_slist_append(dle->level, GINT_TO_POINTER(level)); skip_whitespace(s, ch); /* find the dump date */ if(ch == '\0') { @@ -392,63 +329,95 @@ main( } amfree(line); if (g_options == NULL) { - printf(_("ERROR [Missing OPTIONS line in sendbackup input]\n")); + g_printf(_("ERROR [Missing OPTIONS line in sendbackup input]\n")); error(_("Missing OPTIONS line in sendbackup input\n")); /*NOTREACHED*/ } - if (prog == NULL || - disk == NULL || - amdevice == NULL || - dumpdate == NULL || - stroptions == NULL) { + if (am_has_feature(g_options->features, fe_req_xml)) { + char *errmsg = NULL; + + dle = amxml_parse_node_FILE(stdin, &errmsg); + if (errmsg) { + err_extra = errmsg; + goto err; + } + if (!dle) { + err_extra = _("One DLE required"); + goto err; + } else if (dle->next) { + err_extra = _("Only one DLE allowed"); + goto err; + } + + qdisk = quote_string(dle->disk); + if (dle->device == NULL) + dle->device = stralloc(dle->disk); + qamdevice = quote_string(dle->device); + dumpdate = stralloc("NODATE"); + stroptions = stralloc(""); + } else { + parse_options(stroptions, dle, g_options->features, 0); + } + gdle = dle; + + if (dle->program == NULL || + dle->disk == NULL || + dle->device == NULL || + dle->level == NULL || + dumpdate == NULL) { err_extra = _("no valid sendbackup request"); goto err; } - - dbprintf(_(" Parsed request as: program `%s'\n"), prog); + + if (g_slist_length(dle->level) != 1) { + err_extra = _("Too many level"); + goto err; + } + + level = GPOINTER_TO_INT(dle->level->data); + dbprintf(_(" Parsed request as: program `%s'\n"), dle->program); dbprintf(_(" disk `%s'\n"), qdisk); dbprintf(_(" device `%s'\n"), qamdevice); dbprintf(_(" level %d\n"), level); dbprintf(_(" since %s\n"), dumpdate); dbprintf(_(" options `%s'\n"), stroptions); - if(program_is_backup_api==1) { - /* check that the backup_api exist */ - } - else { + if (dle->program_is_application_api==1) { + /* check that the application_api exist */ + } else { for(i = 0; programs[i]; i++) { - if (strcmp(programs[i]->name, prog) == 0) { + if (strcmp(programs[i]->name, dle->program) == 0) { break; } } if (programs[i] == NULL) { - dbprintf(_("ERROR [%s: unknown program %s]\n"), get_pname(), prog); - error(_("ERROR [%s: unknown program %s]"), get_pname(), prog); + dbprintf(_("ERROR [%s: unknown program %s]\n"), get_pname(), + dle->program); + error(_("ERROR [%s: unknown program %s]"), get_pname(), + dle->program); /*NOTREACHED*/ } program = programs[i]; } - options = parse_options(stroptions, disk, amdevice, g_options->features, 0); - if(!interactive) { datafd = DATA_FD_OFFSET + 0; mesgfd = DATA_FD_OFFSET + 2; indexfd = DATA_FD_OFFSET + 4; } - if (!options->createindex) + if (!dle->create_index) indexfd = -1; - if(options->auth && amandad_auth) { - if(strcasecmp(options->auth, amandad_auth) != 0) { + if (dle->auth && amandad_auth) { + if(strcasecmp(dle->auth, amandad_auth) != 0) { g_printf(_("ERROR [client configured for auth=%s while server requested '%s']\n"), - amandad_auth, options->auth); + amandad_auth, dle->auth); exit(-1); } } - if (options->kencrypt) { + if (dle->kencrypt) { g_printf("KENCRYPT\n"); } @@ -462,9 +431,6 @@ main( if(am_has_feature(g_options->features, fe_rep_options_hostname)) { g_printf("hostname=%s;", g_options->hostname); } - if(am_has_feature(g_options->features, fe_rep_options_sendbackup_options)) { - g_printf("%s", optionstr(options)); - } g_printf("\n"); fflush(stdout); if (freopen("/dev/null", "w", stdout) == NULL) { @@ -484,56 +450,135 @@ main( } if(!interactive) { - if(datafd == -1 || mesgfd == -1 || (options->createindex && indexfd == -1)) { + if(datafd == -1 || mesgfd == -1 || (dle->create_index && indexfd == -1)) { dbclose(); exit(1); } } - if(program_is_backup_api==1) { - pid_t backup_api_pid; - int i, j; + mesgstream = fdopen(mesgfd,"w"); + run_client_scripts(EXECUTE_ON_PRE_DLE_BACKUP, g_options, dle, mesgstream); + fflush(mesgstream); + + if (dle->program_is_application_api==1) { + int i, j, k; char *cmd=NULL; - char *argvchild[20]; + char **argvchild; char levelstr[20]; - int property_pipe[2]; backup_support_option_t *bsu; - - if (pipe(property_pipe) < 0) { - error(_("Can't create pipe: %s"),strerror(errno)); - /*NOTREACHED*/ + char *compopt = NULL; + char *encryptopt = skip_argument; + int compout, dumpout; + GSList *scriptlist; + script_t *script; + time_t cur_dumptime; + int result; + GPtrArray *errarray; + int errfd[2]; + FILE *dumperr; + + /* apply client-side encryption here */ + if ( dle->encrypt == ENCRYPT_CUST ) { + encpid = pipespawn(dle->clnt_encrypt, STDIN_PIPE, 0, + &compout, &datafd, &mesgfd, + dle->clnt_encrypt, encryptopt, NULL); + dbprintf(_("encrypt: pid %ld: %s\n"), (long)encpid, dle->clnt_encrypt); + } else { + compout = datafd; + encpid = -1; } - bsu = backup_support_option(prog, g_options, disk, amdevice); - switch(backup_api_pid=fork()) { - case 0: - aclose(property_pipe[1]); - if(dup2(property_pipe[0], 0) == -1) { - error(_("Can't dup2: %s"),strerror(errno)); - /*NOTREACHED*/ + /* 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; } - if(dup2(datafd, 1) == -1) { - error(_("Can't dup2: %s"),strerror(errno)); - /*NOTREACHED*/ +#endif + comppid = pipespawn(COMPRESS_PATH, STDIN_PIPE, 0, + &dumpout, &compout, &mesgfd, + 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); } - if(dup2(mesgfd, 2) == -1) { - error(_("Can't dup2: %s"),strerror(errno)); - /*NOTREACHED*/ + } else if (dle->compress == COMP_CUST) { + compopt = skip_argument; + comppid = pipespawn(dle->compprog, STDIN_PIPE, 0, + &dumpout, &compout, &mesgfd, + 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); } - if(indexfd != 0) { - if(dup2(indexfd, 3) == -1) { - error(_("Can't dup2: %s"),strerror(errno)); - /*NOTREACHED*/ + } else { + dumpout = compout; + comppid = -1; + } + + cur_dumptime = time(0); + bsu = backup_support_option(dle->program, g_options, dle->disk, + dle->device, &errarray); + if (!bsu) { + char *errmsg; + char *qerrmsg; + guint i; + for (i=0; i < errarray->len; i++) { + errmsg = g_ptr_array_index(errarray, i); + qerrmsg = quote_string(errmsg); + fdprintf(mesgfd, + _("sendbackup: error [Application '%s': %s]\n"), + dle->program, errmsg); + dbprintf("aa: %s\n",qerrmsg); + amfree(qerrmsg); + } + if (i == 0) { /* no errarray */ + errmsg = vstrallocf(_("Can't execute application '%s'"), + dle->program); + qerrmsg = quote_string(errmsg); + fdprintf(mesgfd, _("sendbackup: error [%s]\n"), errmsg); + dbprintf(_("ERROR %s\n"), qerrmsg); + amfree(qerrmsg); + amfree(errmsg); + } + return 0; + } + + if (pipe(errfd) < 0) { + char *errmsg; + char *qerrmsg; + errmsg = vstrallocf(_("Application '%s': can't create pipe"), + dle->program); + qerrmsg = quote_string(errmsg); + fdprintf(mesgfd, _("sendbackup: error [%s]\n"), errmsg); + dbprintf(_("ERROR %s\n"), qerrmsg); + amfree(qerrmsg); + amfree(errmsg); + return 0; + } + + switch(application_api_pid=fork()) { + case 0: + cmd = vstralloc(APPLICATION_DIR, "/", dle->program, NULL); + k = application_property_argv_size(dle); + for (scriptlist = dle->scriptlist; scriptlist != NULL; + scriptlist = scriptlist->next) { + script = (script_t *)scriptlist->data; + if (script->result && script->result->proplist) { + k += property_argv_size(script->result->proplist); } - fcntl(indexfd, F_SETFD, 0); - fcntl(3, F_SETFD, 0); - safe_fd(3, 1); - } else { - safe_fd(-1, 0); } - cmd = vstralloc(DUMPER_DIR, "/", prog, NULL); + argvchild = g_new0(char *, 20 + k); i=0; - argvchild[i++] = prog; + argvchild[i++] = dle->program; argvchild[i++] = "backup"; if (bsu->message_line == 1) { argvchild[i++] = "--message"; @@ -547,59 +592,110 @@ main( argvchild[i++] = "--host"; argvchild[i++] = g_options->hostname; } - if (disk && bsu->disk == 1) { + if (dle->disk && bsu->disk == 1) { argvchild[i++] = "--disk"; - argvchild[i++] = disk; + argvchild[i++] = dle->disk; } argvchild[i++] = "--device"; - argvchild[i++] = amdevice; + argvchild[i++] = dle->device; if (level <= bsu->max_level) { argvchild[i++] = "--level"; g_snprintf(levelstr,19,"%d",level); argvchild[i++] = levelstr; } - if (indexfd != 0 && bsu->index_line == 1) { + if (indexfd != -1 && bsu->index_line == 1) { argvchild[i++] = "--index"; argvchild[i++] = "line"; } - if (!options->no_record && bsu->record == 1) { + if (dle->record && bsu->record == 1) { argvchild[i++] = "--record"; } + i += application_property_add_to_argv(&argvchild[i], dle, bsu); + + for (scriptlist = dle->scriptlist; scriptlist != NULL; + scriptlist = scriptlist->next) { + script = (script_t *)scriptlist->data; + if (script->result && script->result->proplist) { + i += property_add_to_argv(&argvchild[i], + script->result->proplist); + } + } + argvchild[i] = NULL; - dbprintf(_("%s: running \"%s"), get_pname(), cmd); - for(j=1;j 0) { + if(dup2(indexfd, 4) == -1) { + error(_("Can't dup2: %s"),strerror(errno)); + /*NOTREACHED*/ + } + fcntl(indexfd, F_SETFD, 0); + } + application_api_info_tapeheader(mesgfd, dle->program, dle); + if (indexfd != 0) { + safe_fd(3, 2); + } else { + safe_fd(3, 1); + } execve(cmd, argvchild, safe_env()); exit(1); break; default: - aclose(property_pipe[0]); - toolin = fdopen(property_pipe[1],"w"); - if (!toolin) { - error(_("Can't fdopen: %s"), strerror(errno)); - /*NOTREACHED*/ - } - output_tool_property(toolin, options); - fflush(toolin); - fclose(toolin); break; case -1: error(_("%s: fork returned: %s"), get_pname(), strerror(errno)); } - amfree(bsu); - if (waitpid(backup_api_pid, &status, 0) < 0) { - if (!WIFEXITED(status)) { - dbprintf(_("Tool exited with signal %d"), WTERMSIG(status)); - } else if (WEXITSTATUS(status) != 0) { - dbprintf(_("Tool exited with status %d"), WEXITSTATUS(status)); + + close(errfd[1]); + dumperr = fdopen(errfd[0],"r"); + if (!dumperr) { + error(_("Can't fdopen: %s"), strerror(errno)); + /*NOTREACHED*/ + } + + while ((line = agets(dumperr)) != NULL) { + if (strlen(line) > 0) { + fdprintf(mesgfd, "sendbackup: error [%s]\n", line); + dbprintf("error: %s\n", line); + } + amfree(line); + } + + result = check_result(mesgfd); + if (result == 0) { + char *amandates_file; + + amandates_file = getconf_str(CNF_AMANDATES); + if(start_amandates(amandates_file, 1)) { + amandates_updateone(dle->disk, level, cur_dumptime); + finish_amandates(); + free_amandates(); } else { - dbprintf(_("waitpid returned negative value")); + if (dle->calcsize && bsu->calcsize) { + error(_("error [opening %s for writing: %s]"), + amandates_file, strerror(errno)); + } else { + g_debug(_("non-fatal error opening '%s' for writing: %s]"), + amandates_file, strerror(errno)); + } } } - } - else { + amfree(bsu); + } else { if(!interactive) { /* redirect stderr */ if(dup2(mesgfd, 2) == -1) { @@ -616,17 +712,17 @@ main( error(_("error [opening mesg pipe: %s]"), s); } - program->start_backup(g_options->hostname, disk, amdevice, level, - dumpdate, datafd, mesgpipe[1], indexfd); + program->start_backup(dle, g_options->hostname, + datafd, mesgpipe[1], indexfd); dbprintf(_("Started backup\n")); - parse_backup_messages(mesgpipe[0]); + parse_backup_messages(dle, mesgpipe[0]); dbprintf(_("Parsed backup messages\n")); } - amfree(prog); - amfree(disk); + run_client_scripts(EXECUTE_ON_POST_DLE_BACKUP, g_options, dle, mesgstream); + fflush(mesgstream); + amfree(qdisk); - amfree(amdevice); amfree(qamdevice); amfree(dumpdate); amfree(stroptions); @@ -640,10 +736,20 @@ main( return 0; err: - g_printf(_("FORMAT ERROR IN REQUEST PACKET\n")); - dbprintf(_("REQ packet is bogus%s%s\n"), - err_extra ? ": " : "", - err_extra ? err_extra : ""); + if (err_extra) { + g_printf(_("ERROR FORMAT ERROR IN REQUEST PACKET '%s'\n"), err_extra); + dbprintf(_("REQ packet is bogus: %s\n"), err_extra); + } else { + g_printf(_("ERROR FORMAT ERROR IN REQUEST PACKET\n")); + dbprintf(_("REQ packet is bogus\n")); + } + + amfree(qdisk); + amfree(qamdevice); + amfree(dumpdate); + amfree(stroptions); + amfree(our_feature_string); + dbclose(); return 1; } @@ -662,6 +768,13 @@ childstr( if(pid == comppid) return "compress"; if(pid == encpid) return "encrypt"; if(pid == indexpid) return "index"; + if(pid == application_api_pid) { + if (!gdle) { + dbprintf("gdle == NULL\n"); + return "gdle == NULL"; + } + return gdle->program; + } return "unknown"; } @@ -675,7 +788,8 @@ childstr( int check_status( pid_t pid, - amwait_t w) + amwait_t w, + int mesgfd) { char *thiserr = NULL; char *str, *strX; @@ -698,11 +812,11 @@ check_status( * but the failure is noted. */ if(ret != 0) { - g_fprintf(stderr, _("? index %s returned %d\n"), str, ret); + fdprintf(mesgfd, _("? index %s returned %d\n"), str, ret); rc = 0; } indexpid = -1; - strX = "index "; + strX = "index"; } else if(pid == comppid) { /* * compress returns 2 sometimes, but it is ok. @@ -713,7 +827,7 @@ check_status( } #endif comppid = -1; - strX = "compress "; + strX = "compress"; } else if(pid == dumppid && tarpid == -1) { /* * Ultrix dump returns 1 sometimes, but it is ok. @@ -724,7 +838,7 @@ check_status( } #endif dumppid = -1; - strX = "dump "; + strX = "dump"; } else if(pid == tarpid) { if (ret == 1) { rc = 0; @@ -738,9 +852,11 @@ check_status( } #endif dumppid = tarpid = -1; - strX = "dump "; + strX = "dump"; + } else if(pid == application_api_pid) { + strX = "Application"; } else { - strX = "unknown "; + strX = "unknown"; } if(rc == 0) { @@ -754,6 +870,8 @@ check_status( thiserr = vstrallocf(_("%s (%d) %s returned %d"), strX, (int)pid, str, ret); } + fdprintf(mesgfd, "? %s\n", thiserr); + if(errorstr) { errorstr = newvstrallocf(errorstr, "%s, %s", errorstr, thiserr); amfree(thiserr); @@ -769,12 +887,13 @@ check_status( *Send header info to the message file. */ void -info_tapeheader(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 (options->compress == COMP_FAST || options->compress == COMP_BEST) + if (dle->compress == COMP_FAST || dle->compress == COMP_BEST) g_fprintf(stderr, "%s %s |", UNCOMPRESS_PATH, #ifdef UNCOMPRESS_OPT UNCOMPRESS_OPT @@ -785,7 +904,7 @@ info_tapeheader(void) g_fprintf(stderr, "%s -xpGf - ...\n", program->restore_name); - if (options->compress == COMP_FAST || options->compress == COMP_BEST) + if (dle->compress == COMP_FAST || dle->compress == COMP_BEST) g_fprintf(stderr, "%s: info COMPRESS_SUFFIX=%s\n", get_pname(), COMPRESS_SUFFIX); @@ -793,32 +912,32 @@ info_tapeheader(void) } void -backup_api_info_tapeheader( +application_api_info_tapeheader( int mesgfd, char *prog, - option_t *options) + dle_t *dle) { char line[1024]; - g_snprintf(line, 1024, "%s: info BACKUP=DUMPER\n", get_pname()); - if (fullwrite(mesgfd, line, strlen(line)) != (ssize_t)strlen(line)) { + g_snprintf(line, 1024, "%s: info BACKUP=APPLICATION\n", get_pname()); + if (full_write(mesgfd, line, strlen(line)) != strlen(line)) { dbprintf(_("error writing to mesgfd socket: %s"), strerror(errno)); return; } - g_snprintf(line, 1024, "%s: info DUMPER=%s\n", get_pname(), prog); - if (fullwrite(mesgfd, line, strlen(line)) != (ssize_t)strlen(line)) { + g_snprintf(line, 1024, "%s: info APPLICATION=%s\n", get_pname(), prog); + if (full_write(mesgfd, line, strlen(line)) != strlen(line)) { dbprintf(_("error writing to mesgfd socket: %s"), strerror(errno)); return; } g_snprintf(line, 1024, "%s: info RECOVER_CMD=", get_pname()); - if (fullwrite(mesgfd, line, strlen(line)) != (ssize_t)strlen(line)) { + if (full_write(mesgfd, line, strlen(line)) != strlen(line)) { dbprintf(_("error writing to mesgfd socket: %s"), strerror(errno)); return; } - if (options->compress) { + if (dle->compress == COMP_FAST || dle->compress == COMP_BEST) { g_snprintf(line, 1024, "%s %s |", UNCOMPRESS_PATH, #ifdef UNCOMPRESS_OPT UNCOMPRESS_OPT @@ -826,28 +945,29 @@ backup_api_info_tapeheader( "" #endif ); - if (fullwrite(mesgfd, line, strlen(line)) != (ssize_t)strlen(line)) { + if (full_write(mesgfd, line, strlen(line)) != strlen(line)) { dbprintf(_("error writing to mesgfd socket: %s"), strerror(errno)); return; } } - g_snprintf(line, 1024, "%s -f... -\n", prog); - if (fullwrite(mesgfd, line, strlen(line)) != (ssize_t)strlen(line)) { + g_snprintf(line, 1024, "%s/%s restore [./file-to-restore]+\n", + APPLICATION_DIR, prog); + if (full_write(mesgfd, line, strlen(line)) != strlen(line)) { dbprintf(_("error writing to mesgfd socket: %s"), strerror(errno)); return; } - if (options->compress) { + if (dle->compress) { g_snprintf(line, 1024, "%s: info COMPRESS_SUFFIX=%s\n", get_pname(), COMPRESS_SUFFIX); - if (fullwrite(mesgfd, line, strlen(line)) != (ssize_t)strlen(line)) { + if (full_write(mesgfd, line, strlen(line)) != strlen(line)) { dbprintf(_("error writing to mesgfd socket: %s"), strerror(errno)); return; } } g_snprintf(line, 1024, "%s: info end\n", get_pname()); - if (fullwrite(mesgfd, line, strlen(line)) != (ssize_t)strlen(line)) { + if (full_write(mesgfd, line, strlen(line)) != strlen(line)) { dbprintf(_("error writing to mesgfd socket: %s"), strerror(errno)); return; } @@ -905,35 +1025,25 @@ pipefork( return pid; } -void -parse_backup_messages( - int mesgin) +int +check_result( + int mesgfd) { int goterror; pid_t wpid; amwait_t retstat; - char *line; goterror = 0; - amfree(errorstr); - - for(; (line = areads(mesgin)) != NULL; free(line)) { - process_dumpline(line); - } - if(errno) { - error(_("error [read mesg pipe: %s]"), strerror(errno)); - /*NOTREACHED*/ - } while((wpid = waitpid((pid_t)-1, &retstat, WNOHANG)) > 0) { - if(check_status(wpid, retstat)) goterror = 1; + if(check_status(wpid, retstat, mesgfd)) goterror = 1; } if (dumppid != -1) { sleep(5); while((wpid = waitpid((pid_t)-1, &retstat, WNOHANG)) > 0) { - if(check_status(wpid, retstat)) goterror = 1; + if(check_status(wpid, retstat, mesgfd)) goterror = 1; } } if (dumppid != -1) { @@ -948,7 +1058,7 @@ parse_backup_messages( } sleep(5); while((wpid = waitpid((pid_t)-1, &retstat, WNOHANG)) > 0) { - if(check_status(wpid, retstat)) goterror = 1; + if(check_status(wpid, retstat, mesgfd)) goterror = 1; } } if (dumppid != -1) { @@ -963,10 +1073,34 @@ parse_backup_messages( } sleep(5); while((wpid = waitpid((pid_t)-1, &retstat, WNOHANG)) > 0) { - if(check_status(wpid, retstat)) goterror = 1; + if(check_status(wpid, retstat, mesgfd)) goterror = 1; } } + return goterror; +} + +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*/ @@ -975,39 +1109,10 @@ parse_backup_messages( /*NOTREACHED*/ } - program->end_backup(goterror); + program->end_backup(dle, goterror); - g_fprintf(stderr, _("%s: size %ld\n"), get_pname(), dump_size); - g_fprintf(stderr, _("%s: end\n"), get_pname()); -} - - -/* - * Returns the value of the first integer in a string. - */ - -double -the_num( - char * str, - int pos) -{ - char *num; - int ch; - double d; - - do { - ch = *str++; - while(ch && !isdigit(ch)) ch = *str++; - if (pos == 1) break; - pos--; - while(ch && (isdigit(ch) || ch == '.')) ch = *str++; - } while (ch); - num = str - 1; - while(isdigit(ch) || ch == '.') ch = *str++; - str[-1] = '\0'; - d = atof(num); - str[-1] = (char)ch; - return d; + fdprintf(mesgfd, _("%s: size %ld\n"), get_pname(), dump_size); + fdprintf(mesgfd, _("%s: end\n"), get_pname()); } @@ -1057,7 +1162,7 @@ process_dumpline( type, startchr, str); - g_fprintf(stderr, "%c %s\n", startchr, str); + fdprintf(mesgfd, "%c %s\n", startchr, str); } @@ -1161,7 +1266,7 @@ start_index( char buffer[BUFSIZ], *ptr; ssize_t bytes_read; size_t bytes_written; - ssize_t just_written; + size_t just_written; do { bytes_read = read(0, buffer, SIZEOF(buffer)); @@ -1178,8 +1283,8 @@ start_index( /* write the stuff to the subprocess */ ptr = buffer; bytes_written = 0; - just_written = fullwrite(fileno(pipe_fp), ptr, (size_t)bytes_read); - if (just_written < 0) { + just_written = full_write(fileno(pipe_fp), ptr, (size_t)bytes_read); + if (just_written < (size_t)bytes_read) { /* * just as we waited for write() to complete. */ @@ -1196,8 +1301,8 @@ start_index( occurs */ ptr = buffer; bytes_written = 0; - just_written = fullwrite(3, ptr, (size_t)bytes_read); - if (just_written < 0) { + just_written = full_write(3, ptr, bytes_read); + if (just_written < (size_t)bytes_read) { error(_("index tee cannot write [%s]"), strerror(errno)); /*NOTREACHED*/ } else {