+ }
+ }
+ }
+ if (dle->program_is_application_api) {
+ pid_t application_api_pid;
+ backup_support_option_t *bsu;
+ int app_err[2];
+ GPtrArray *errarray;
+
+ bsu = backup_support_option(dle->program, g_options, dle->disk,
+ dle->device, &errarray);
+
+ if (!bsu) {
+ char *line;
+ guint i;
+ for (i=0; i < errarray->len; i++) {
+ line = g_ptr_array_index(errarray, i);
+ fprintf(stdout, _("ERROR Application '%s': %s\n"),
+ dle->program, line);
+ amfree(line);
+ }
+ err = vstrallocf(_("Application '%s': can't run support command"),
+ dle->program);
+ goto common_exit;
+ }
+
+ if (dle->data_path == DATA_PATH_AMANDA &&
+ (bsu->data_path_set & DATA_PATH_AMANDA)==0) {
+ g_printf("ERROR application %s doesn't support amanda data-path\n",
+ dle->program);
+ }
+ if (dle->data_path == DATA_PATH_DIRECTTCP &&
+ (bsu->data_path_set & DATA_PATH_DIRECTTCP)==0) {
+ g_printf("ERROR application %s doesn't support directtcp data-path\n",
+ dle->program);
+ }
+ if (GPOINTER_TO_INT(dle->estimatelist->data) == ES_CALCSIZE &&
+ !bsu->calcsize) {
+ g_printf("ERROR application %s doesn't support calcsize estimate\n",
+ dle->program);
+ }
+ if (dle->include_file && dle->include_file->nb_element > 0 &&
+ !bsu->include_file) {
+ g_printf("ERROR application %s doesn't support include-file\n",
+ dle->program);
+ }
+ if (dle->include_list && dle->include_list->nb_element > 0 &&
+ !bsu->include_list) {
+ g_printf("ERROR application %s doesn't support include-list\n",
+ dle->program);
+ }
+ if (dle->include_optional && !bsu->include_optional) {
+ g_printf("ERROR application %s doesn't support optional include\n",
+ dle->program);
+ }
+ if (dle->exclude_file && dle->exclude_file->nb_element > 0 &&
+ !bsu->exclude_file) {
+ g_printf("ERROR application %s doesn't support exclude-file\n",
+ dle->program);
+ }
+ if (dle->exclude_list && dle->exclude_list->nb_element > 0 &&
+ !bsu->exclude_list) {
+ g_printf("ERROR application %s doesn't support exclude-list\n",
+ dle->program);
+ }
+ if (dle->exclude_optional && !bsu->exclude_optional) {
+ g_printf("ERROR application %s doesn't support optional exclude\n",
+ dle->program);
+ }
+ fflush(stdout);fflush(stderr);
+
+ if (pipe(app_err) < 0) {
+ err = vstrallocf(_("Application '%s': can't create pipe"),
+ dle->program);
+ goto common_exit;
+ }
+
+ switch (application_api_pid = fork()) {
+ case -1:
+ err = vstrallocf(_("fork failed: %s"), strerror(errno));
+ goto common_exit;
+
+ case 0: /* child */
+ {
+ GPtrArray *argv_ptr = g_ptr_array_new();
+ guint i;
+ char *cmd = vstralloc(APPLICATION_DIR, "/", dle->program, NULL);
+ GSList *scriptlist;
+ script_t *script;
+ estimatelist_t el;
+ char *cmdline;
+
+ aclose(app_err[0]);
+ dup2(app_err[1], 2);
+
+ g_ptr_array_add(argv_ptr, stralloc(dle->program));
+ g_ptr_array_add(argv_ptr, stralloc("selfcheck"));
+ if (bsu->message_line == 1) {
+ g_ptr_array_add(argv_ptr, stralloc("--message"));
+ g_ptr_array_add(argv_ptr, stralloc("line"));
+ }
+ if (g_options->config != NULL && bsu->config == 1) {
+ g_ptr_array_add(argv_ptr, stralloc("--config"));
+ g_ptr_array_add(argv_ptr, stralloc(g_options->config));
+ }
+ if (g_options->hostname != NULL && bsu->host == 1) {
+ g_ptr_array_add(argv_ptr, stralloc("--host"));
+ g_ptr_array_add(argv_ptr, stralloc(g_options->hostname));
+ }
+ if (dle->disk != NULL && bsu->disk == 1) {
+ g_ptr_array_add(argv_ptr, stralloc("--disk"));
+ g_ptr_array_add(argv_ptr, stralloc(dle->disk));
+ }
+ if (dle->device) {
+ g_ptr_array_add(argv_ptr, stralloc("--device"));
+ g_ptr_array_add(argv_ptr, stralloc(dle->device));
+ }
+ if (dle->create_index && bsu->index_line == 1) {
+ g_ptr_array_add(argv_ptr, stralloc("--index"));
+ g_ptr_array_add(argv_ptr, stralloc("line"));
+ }
+ if (dle->record && bsu->record == 1) {
+ g_ptr_array_add(argv_ptr, stralloc("--record"));
+ }
+
+ for (el = dle->estimatelist; el != NULL; el=el->next) {
+ estimate_t estimate = (estimate_t)GPOINTER_TO_INT(el->data);
+ if (estimate == ES_CALCSIZE && bsu->calcsize == 1) {
+ g_ptr_array_add(argv_ptr, stralloc("--calcsize"));
+ }
+ }
+ application_property_add_to_argv(argv_ptr, dle, bsu,
+ g_options->features);
+
+ for (scriptlist = dle->scriptlist; scriptlist != NULL;
+ scriptlist = scriptlist->next) {
+ script = (script_t *)scriptlist->data;
+ if (script->result && script->result->proplist) {
+ property_add_to_argv(argv_ptr,
+ script->result->proplist);
+ }
+ }
+
+ g_ptr_array_add(argv_ptr, NULL);
+
+ cmdline = stralloc(cmd);
+ for (i = 0; i < argv_ptr->len-1; i++) {
+ char *quoted = quote_string(
+ (char *)g_ptr_array_index(argv_ptr,i));
+ cmdline = vstrextend(&cmdline, " ", quoted, NULL);
+ amfree(quoted);
+ }
+ dbprintf(_("Spawning \"%s\" in pipeline\n"), cmdline);
+ amfree(cmdline);
+
+ safe_fd(-1, 0);
+ execve(cmd, (char **)argv_ptr->pdata, safe_env());
+ g_printf(_("ERROR [Can't execute %s: %s]\n"), cmd, strerror(errno));
+ exit(127);
+ }
+ default: /* parent */
+ {
+ int status;
+ FILE *app_stderr;
+ char *line;
+
+ aclose(app_err[1]);
+ app_stderr = fdopen(app_err[0], "r");
+ while((line = agets(app_stderr)) != NULL) {
+ if (strlen(line) > 0) {
+ fprintf(stdout, "ERROR Application '%s': %s\n",
+ dle->program, line);
+ dbprintf("ERROR %s\n", line);
+ }
+ amfree(line);
+ }
+ fclose(app_stderr);
+ if (waitpid(application_api_pid, &status, 0) < 0) {
+ err = vstrallocf(_("waitpid failed: %s"),
+ strerror(errno));
+ goto common_exit;
+ } else if (!WIFEXITED(status)) {
+ err = vstrallocf(_("Application '%s': exited with signal %d"),
+ dle->program, WTERMSIG(status));
+ goto common_exit;
+ } else if (WEXITSTATUS(status) != 0) {
+ err = vstrallocf(_("Application '%s': exited with status %d"),
+ dle->program, WEXITSTATUS(status));
+ goto common_exit;
+ }
+ }