+ else { /* program_is_application_api==1 */
+ 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->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 */
+ {
+ char **argvchild, **arg;
+ char *cmd = vstralloc(APPLICATION_DIR, "/", dle->program, NULL);
+ GSList *scriptlist;
+ script_t *script;
+ char *cmdline;
+ int j=0;
+ int k;
+
+ aclose(app_err[0]);
+ dup2(app_err[1], 2);
+
+ 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);
+ }
+ }
+ argvchild = g_new0(char *, 18 + k);
+ argvchild[j++] = dle->program;
+ argvchild[j++] = "selfcheck";
+ if (bsu->message_line == 1) {
+ argvchild[j++] = "--message";
+ argvchild[j++] = "line";
+ }
+ if (g_options->config != NULL && bsu->config == 1) {
+ argvchild[j++] = "--config";
+ argvchild[j++] = g_options->config;
+ }
+ if (g_options->hostname != NULL && bsu->host == 1) {
+ argvchild[j++] = "--host";
+ argvchild[j++] = g_options->hostname;
+ }
+ if (dle->disk != NULL && bsu->disk == 1) {
+ argvchild[j++] = "--disk";
+ argvchild[j++] = dle->disk;
+ }
+ argvchild[j++] = "--device";
+ argvchild[j++] = dle->device;
+ if (dle->create_index && bsu->index_line == 1) {
+ argvchild[j++] = "--index";
+ argvchild[j++] = "line";
+ }
+ if (dle->record && bsu->record == 1) {
+ argvchild[j++] = "--record";
+ }
+ if (dle->calcsize && bsu->calcsize == 1) {
+ argvchild[j++] = "--calcsize";
+ }
+ j += application_property_add_to_argv(&argvchild[j], dle, bsu);
+
+ for (scriptlist = dle->scriptlist; scriptlist != NULL;
+ scriptlist = scriptlist->next) {
+ script = (script_t *)scriptlist->data;
+ if (script->result && script->result->proplist) {
+ j += property_add_to_argv(&argvchild[j],
+ script->result->proplist);
+ }
+ }
+
+ argvchild[j++] = NULL;
+
+ cmdline = stralloc(cmd);
+ for(arg = argvchild; *arg != NULL; arg++) {
+ char *quoted = quote_string(*arg);
+ cmdline = vstrextend(&cmdline, " ", quoted, NULL);
+ amfree(quoted);
+ }
+ dbprintf(_("Spawning \"%s\" in pipeline\n"), cmdline);
+ amfree(cmdline);
+
+ safe_fd(-1, 0);
+ execve(cmd, argvchild, 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);
+ }
+ 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;
+ }
+ }
+ }
+ amfree(bsu);
+ fflush(stdout);fflush(stderr);
+ amfree(device);
+ amfree(qamdevice);
+ amfree(qdisk);
+ return;
+ }