summaryrefslogtreecommitdiff
path: root/capture_sync.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2006-02-17 09:45:52 +0000
committerGuy Harris <guy@alum.mit.edu>2006-02-17 09:45:52 +0000
commitbb3d513158cfac6d5bef4e51b88ef76964e63b58 (patch)
tree4ef74579657e1f453a333bb5b68b979345e41bcc /capture_sync.c
parentd238e5ef1efd6161126f595576c398398705b8ba (diff)
downloadwireshark-bb3d513158cfac6d5bef4e51b88ef76964e63b58.tar.gz
On Windows. quote arguments as necessary before sticking them into the
command line passed to Create_Process(). On UN*X, use "execv()", not "execvp()", as we now construct the absolute pathname of "dumpcap". svn path=/trunk/; revision=17330
Diffstat (limited to 'capture_sync.c')
-rw-r--r--capture_sync.c84
1 files changed, 81 insertions, 3 deletions
diff --git a/capture_sync.c b/capture_sync.c
index 6cb53e8ae7..ccc40f318c 100644
--- a/capture_sync.c
+++ b/capture_sync.c
@@ -291,6 +291,75 @@ sync_pipe_add_arg(const char **args, int *argc, const char *arg)
+#ifdef _WIN32
+/* Quote the argument element if necessary, so that it will get
+ * reconstructed correctly in the C runtime startup code. Note that
+ * the unquoting algorithm in the C runtime is really weird, and
+ * rather different than what Unix shells do. See stdargv.c in the C
+ * runtime sources (in the Platform SDK, in src/crt).
+ *
+ * Stolen from GLib's protect_argv(), an internal routine that quotes
+ * string in an argument list so that they arguments will be handled
+ * correctly in the command-line string passed to CreateProcess()
+ * if that string is constructed by gluing those strings together.
+ */
+static gchar *
+protect_arg (gchar *argv)
+{
+ gchar *new_arg;
+ gchar *p = argv;
+ gchar *q;
+ gint len = 0;
+ gboolean need_dblquotes = FALSE;
+
+ while (*p) {
+ if (*p == ' ' || *p == '\t')
+ need_dblquotes = TRUE;
+ else if (*p == '"')
+ len++;
+ else if (*p == '\\') {
+ gchar *pp = p;
+
+ while (*pp && *pp == '\\')
+ pp++;
+ if (*pp == '"')
+ len++;
+ }
+ len++;
+ p++;
+ }
+
+ q = new_arg = g_malloc (len + need_dblquotes*2 + 1);
+ p = argv;
+
+ if (need_dblquotes)
+ *q++ = '"';
+
+ while (*p) {
+ if (*p == '"')
+ *q++ = '\\';
+ else if (*p == '\\') {
+ gchar *pp = p;
+
+ while (*pp && *pp == '\\')
+ pp++;
+ if (*pp == '"')
+ *q++ = '\\';
+ }
+ *q++ = *p;
+ p++;
+ }
+
+ if (need_dblquotes)
+ *q++ = '"';
+ *q++ = '\0';
+
+ return new_arg;
+}
+#endif
+
+
+
#define ARGV_NUMBER_LEN 24
gboolean
@@ -312,6 +381,7 @@ sync_pipe_start(capture_options *capture_opts) {
HANDLE signal_pipe_read; /* pipe used to send messages from parent to child (currently only stop) */
HANDLE signal_pipe_write; /* pipe used to send messages from parent to child (currently only stop) */
GString *args = g_string_sized_new(200);
+ gchar *quoted_arg;
SECURITY_ATTRIBUTES sa;
STARTUPINFO si;
PROCESS_INFORMATION pi;
@@ -479,14 +549,22 @@ sync_pipe_start(capture_options *capture_opts) {
/*si.hStdError = (HANDLE) _get_osfhandle(2);*/
#endif
- g_string_append(args, exename);
+ /*
+ * XXX - is this necessary? argv[0] should be the full path of
+ * dumpcap.
+ */
+ quoted_arg = protect_arg(exename);
+ g_string_append(args, quoted_arg);
+ g_free(quoted_arg);
/* convert args array into a single string */
/* XXX - could change sync_pipe_add_arg() instead */
/* there is a drawback here: the length is internally limited to 1024 bytes */
for(i=0; argv[i] != 0; i++) {
g_string_append_c(args, ' ');
- g_string_append(args, argv[i]);
+ quoted_arg = protect_arg(argv[i]);
+ g_string_append(args, quoted_arg);
+ g_free(quoted_arg);
}
/* call dumpcap */
@@ -548,7 +626,7 @@ sync_pipe_start(capture_options *capture_opts) {
eth_close(1);
dup(sync_pipe[PIPE_WRITE]);
eth_close(sync_pipe[PIPE_READ]);
- execvp(exename, argv);
+ execv(exename, argv);
g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
exename, strerror(errno));
sync_pipe_errmsg_to_parent(errmsg);