Преглед изворни кода

qrexec: add option to use real stdin/out of qrexec-client-vm

Marek Marczykowski-Górecki пре 9 година
родитељ
комит
a86d980ff4
1 измењених фајлова са 50 додато и 40 уклоњено
  1. 50 40
      qrexec/qrexec-client-vm.c

+ 50 - 40
qrexec/qrexec-client-vm.c

@@ -78,17 +78,21 @@ int main(int argc, char **argv)
     struct trigger_service_params params;
     struct exec_params exec_params;
     int ret, i;
+    int start_local_process = 0;
     char *abs_exec_path;
     pid_t child_pid;
     int inpipe[2], outpipe[2];
     char pid_s[10];
 
-    if (argc < 4) {
+    if (argc < 3) {
         fprintf(stderr,
-                "usage: %s target_vmname program_ident local_program [local program arguments]\n",
+                "usage: %s target_vmname program_ident [local_program [local program arguments]]\n",
                 argv[0]);
         exit(1);
     }
+    if (argc > 3) {
+        start_local_process = 1;
+    }
 
     trigger_fd = connect_unix_socket(QREXEC_AGENT_TRIGGER_PATH);
 
@@ -113,50 +117,56 @@ int main(int argc, char **argv)
         exit(1);
     }
 
-    if (socketpair(AF_UNIX, SOCK_STREAM, 0, inpipe) ||
-            socketpair(AF_UNIX, SOCK_STREAM, 0, outpipe)) {
-        perror("socketpair");
-        exit(1);
-    }
-    snprintf(pid_s, sizeof(pid_s), "%d", getpid());
-    setenv("QREXEC_AGENT_PID", pid_s, 1);
-
-    switch (child_pid = fork()) {
-    case -1:
-        perror("fork");
-        exit(-1);
-    case 0:
-        close(inpipe[1]);
-        close(outpipe[0]);
-        close(trigger_fd);
-        for (i = 0; i < 3; i++) {
-            if (i != 2 || getenv("PASS_LOCAL_STDERR")) {
-                char *env;
-                if (asprintf(&env, "SAVED_FD_%d=%d", i, dup(i)) < 0) {
-                    perror("prepare SAVED_FD_");
-                    exit(1);
-                }
-                putenv(env);
-            }
+    if (start_local_process) {
+        if (socketpair(AF_UNIX, SOCK_STREAM, 0, inpipe) ||
+                socketpair(AF_UNIX, SOCK_STREAM, 0, outpipe)) {
+            perror("socketpair");
+            exit(1);
         }
+        snprintf(pid_s, sizeof(pid_s), "%d", getpid());
+        setenv("QREXEC_AGENT_PID", pid_s, 1);
+
+        switch (child_pid = fork()) {
+            case -1:
+                perror("fork");
+                exit(-1);
+            case 0:
+                close(inpipe[1]);
+                close(outpipe[0]);
+                close(trigger_fd);
+                for (i = 0; i < 3; i++) {
+                    if (i != 2 || getenv("PASS_LOCAL_STDERR")) {
+                        char *env;
+                        if (asprintf(&env, "SAVED_FD_%d=%d", i, dup(i)) < 0) {
+                            perror("prepare SAVED_FD_");
+                            exit(1);
+                        }
+                        putenv(env);
+                    }
+                }
+
+                dup2(inpipe[0], 0);
+                dup2(outpipe[1], 1);
+                close(inpipe[0]);
+                close(outpipe[1]);
 
-        dup2(inpipe[0], 0);
-        dup2(outpipe[1], 1);
+                abs_exec_path = strdup(argv[3]);
+                argv[3] = get_program_name(argv[3]);
+                execv(abs_exec_path, argv + 3);
+                perror("execv");
+                exit(-1);
+        }
         close(inpipe[0]);
         close(outpipe[1]);
 
-        abs_exec_path = strdup(argv[3]);
-        argv[3] = get_program_name(argv[3]);
-        execv(abs_exec_path, argv + 3);
-        perror("execv");
-        exit(-1);
+        ret = handle_data_client(MSG_SERVICE_CONNECT,
+                exec_params.connect_domain, exec_params.connect_port,
+                inpipe[1], outpipe[0], -1);
+    } else {
+        ret = handle_data_client(MSG_SERVICE_CONNECT,
+                exec_params.connect_domain, exec_params.connect_port,
+                1, 0, -1);
     }
-    close(inpipe[0]);
-    close(outpipe[1]);
-
-    ret = handle_data_client(MSG_SERVICE_CONNECT,
-            exec_params.connect_domain, exec_params.connect_port,
-            inpipe[1], outpipe[0], -1);
 
     close(trigger_fd);
     waitpid(child_pid, &i, 0);