We now quote args as necessary on Windows when constructing the command
[obnox/wireshark/wip.git] / capture_sync.c
1 /* capture_sync.c
2  * Synchronisation between Ethereal capture parent and child instances
3  *
4  * $Id$
5  *
6  * Ethereal - Network traffic analyzer
7  * By Gerald Combs <gerald@ethereal.com>
8  * Copyright 1998 Gerald Combs
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #ifdef HAVE_LIBPCAP
30
31 #include <glib.h>
32 #include <stdio.h>
33 #include <ctype.h>
34 #include <string.h>
35
36 #ifdef HAVE_UNISTD_H
37 #include <unistd.h>
38 #endif
39
40 #include <signal.h>
41
42 #ifdef _WIN32
43 #include <fcntl.h>
44 #endif
45
46 #ifdef HAVE_SYS_WAIT_H
47 # include <sys/wait.h>
48 #endif
49
50 #include "capture-pcap-util.h"
51
52 #ifndef _WIN32
53 /*
54  * Define various POSIX macros (and, in the case of WCOREDUMP, non-POSIX
55  * macros) on UNIX systems that don't have them.
56  */
57 #ifndef WIFEXITED
58 # define WIFEXITED(status)      (((status) & 0177) == 0)
59 #endif
60 #ifndef WIFSTOPPED
61 # define WIFSTOPPED(status)     (((status) & 0177) == 0177)
62 #endif
63 #ifndef WIFSIGNALED
64 # define WIFSIGNALED(status)    (!WIFSTOPPED(status) && !WIFEXITED(status))
65 #endif
66 #ifndef WEXITSTATUS
67 # define WEXITSTATUS(status)    ((status) >> 8)
68 #endif
69 #ifndef WTERMSIG
70 # define WTERMSIG(status)       ((status) & 0177)
71 #endif
72 #ifndef WCOREDUMP
73 # define WCOREDUMP(status)      ((status) & 0200)
74 #endif
75 #ifndef WSTOPSIG
76 # define WSTOPSIG(status)       ((status) >> 8)
77 #endif
78 #endif /* _WIN32 */
79
80 #include <epan/packet.h>
81 #include <epan/prefs.h>
82
83 #include "globals.h"
84 #include "file.h"
85 #include <epan/filesystem.h>
86
87 #include "capture.h"
88 #include "capture_sync.h"
89 #include "simple_dialog.h"
90
91 #ifdef _WIN32
92 #include "capture-wpcap.h"
93 #endif
94 #include "ui_util.h"
95 #include "file_util.h"
96 #include "log.h"
97
98 #ifdef _WIN32
99 #include <process.h>    /* For spawning child process */
100 #endif
101
102
103 #ifndef _WIN32
104 static const char *sync_pipe_signame(int);
105 #endif
106
107
108 static gboolean sync_pipe_input_cb(gint source, gpointer user_data);
109 static void sync_pipe_wait_for_child(capture_options *capture_opts);
110
111 /*
112  * Maximum length of sync pipe message data.  Must be < 2^24, as the
113  * message length is 3 bytes.
114  * XXX - this must be large enough to handle a Really Big Filter
115  * Expression, as the error message for an incorrect filter expression
116  * is a bit larger than the filter expression.
117  */
118 #define SP_MAX_MSG_LEN  4096
119
120
121  /* write a message to the recipient pipe in the standard format 
122    (3 digit message length (excluding length and indicator field), 
123    1 byte message indicator and the rest is the message) */
124 static void
125 pipe_write_block(int pipe, char indicator, int len, const char *msg)
126 {
127     guchar header[3+1]; /* indicator + 3-byte len */
128     int ret;
129
130     g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "write %d enter", pipe);
131
132     g_assert(indicator < '0' || indicator > '9');
133     g_assert(len <= SP_MAX_MSG_LEN);
134
135     /* write header (indicator + 3-byte len) */
136     header[0] = indicator;
137     header[1] = (len >> 16) & 0xFF;
138     header[2] = (len >> 8) & 0xFF;
139     header[3] = (len >> 0) & 0xFF;
140
141     ret = write(pipe, header, sizeof header);
142     if(ret == -1) {
143         g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
144               "write %d header: error %s", pipe, strerror(errno));
145         return;
146     }
147
148     /* write value (if we have one) */
149     if(len) {
150         g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG,
151               "write %d indicator: %c value len: %u msg: %s", pipe, indicator,
152               len, msg);
153         ret = write(pipe, msg, len);
154         if(ret == -1) {
155             g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
156                   "write %d value: error %s", pipe, strerror(errno));
157             return;
158         }
159     } else {
160         g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG,
161               "write %d indicator: %c no value", pipe, indicator);
162     }
163
164     g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "write %d leave", pipe);
165 }
166
167
168 #ifndef _WIN32
169 void
170 sync_pipe_errmsg_to_parent(const char *errmsg)
171 {
172     g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "sync_pipe_errmsg_to_parent: %s", errmsg);
173
174     pipe_write_block(1, SP_ERROR_MSG, strlen(errmsg)+1, errmsg);
175 }
176 #endif
177
178
179 #ifdef _WIN32
180 static void
181 signal_pipe_capquit_to_child(capture_options *capture_opts)
182 {
183
184     g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "signal_pipe_capquit_to_child");
185
186     pipe_write_block(capture_opts->signal_pipe_write_fd, SP_QUIT, 0, NULL);
187 }
188 #endif
189
190
191
192 /* read a message from the sending pipe in the standard format 
193    (1-byte message indicator, 3-byte message length (excluding length
194    and indicator field), and the rest is the message) */
195 static int
196 pipe_read_block(int pipe, char *indicator, int len, char *msg) {
197     int required;
198     int newly;
199     guchar header[4];
200     int offset;
201
202
203     /* read header (indicator and 3-byte length) */
204     required = 4;
205     offset = 0;
206     while(required) {
207         newly = read(pipe, &header[offset], required);
208         if (newly == 0) {
209             /* EOF */
210             g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
211                   "read %d header empty (capture closed)", pipe);
212             return newly;
213         }
214         if (newly < 0) {
215             /* error */
216             g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
217                   "read %d header error: %s", pipe, strerror(errno));
218             return newly;
219         }
220
221         required -= newly;
222         offset += newly;
223     }
224
225     /* convert header values */
226     *indicator = header[0];
227     required = header[1]<<16 | header[2]<<8 | header[3];
228
229     /* only indicator with no value? */
230     if(required == 0) {
231         g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
232               "read %d indicator: %c empty value", pipe, *indicator);
233         return 4;
234     }
235
236     if(required > len) {
237         g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
238               "read %d length error, required %d > len %d, indicator: %u",
239               pipe, required, len, *indicator);
240         return -1;
241     }
242     len = required;
243
244     /* read value */
245     offset = 0;
246     while(required) {
247         newly = read(pipe, &msg[offset], required);
248         if (newly == -1) {
249             /* error */
250             g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
251                   "read %d value error: %s, indicator: %u", pipe,
252                   strerror(errno), *indicator);
253             return newly;
254         }
255
256         required -= newly;
257         offset += newly;
258     }
259
260     g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
261           "read %d ok indicator: %c len: %u msg: %s", pipe, *indicator,
262           len, msg);
263     return len + 4;
264 }
265
266
267
268 /* Add a string pointer to a NULL-terminated array of string pointers. */
269 static const char **
270 sync_pipe_add_arg(const char **args, int *argc, const char *arg)
271 {
272   /* Grow the array; "*argc" currently contains the number of string
273      pointers, *not* counting the NULL pointer at the end, so we have
274      to add 2 in order to get the new size of the array, including the
275      new pointer and the terminating NULL pointer. */
276   args = g_realloc( (gpointer) args, (*argc + 2) * sizeof (char *));
277
278   /* Stuff the pointer into the penultimate element of the array, which
279      is the one at the index specified by "*argc". */
280   args[*argc] = arg;
281
282   /* Now bump the count. */
283   (*argc)++;
284
285   /* We overwrite the NULL pointer; put it back right after the
286      element we added. */
287   args[*argc] = NULL;
288
289   return args;
290 }
291
292
293
294 #ifdef _WIN32
295 /* Quote the argument element if necessary, so that it will get
296  * reconstructed correctly in the C runtime startup code.  Note that
297  * the unquoting algorithm in the C runtime is really weird, and
298  * rather different than what Unix shells do. See stdargv.c in the C
299  * runtime sources (in the Platform SDK, in src/crt).
300  *
301  * Stolen from GLib's protect_argv(), an internal routine that quotes
302  * string in an argument list so that they arguments will be handled
303  * correctly in the command-line string passed to CreateProcess()
304  * if that string is constructed by gluing those strings together.
305  */
306 static gchar *
307 protect_arg (gchar *argv)
308 {
309     gchar *new_arg;
310     gchar *p = argv;
311     gchar *q;
312     gint len = 0;
313     gboolean need_dblquotes = FALSE;
314
315     while (*p) {
316         if (*p == ' ' || *p == '\t')
317             need_dblquotes = TRUE;
318         else if (*p == '"')
319             len++;
320         else if (*p == '\\') {
321             gchar *pp = p;
322
323             while (*pp && *pp == '\\')
324                 pp++;
325             if (*pp == '"')
326                 len++;
327         }
328         len++;
329         p++;
330     }
331
332     q = new_arg = g_malloc (len + need_dblquotes*2 + 1);
333     p = argv;
334
335     if (need_dblquotes)
336         *q++ = '"';
337
338     while (*p) {
339         if (*p == '"')
340             *q++ = '\\';
341         else if (*p == '\\') {
342             gchar *pp = p;
343
344             while (*pp && *pp == '\\')
345                 pp++;
346             if (*pp == '"')
347                 *q++ = '\\';
348         }
349         *q++ = *p;
350         p++;
351     }
352
353     if (need_dblquotes)
354         *q++ = '"';
355     *q++ = '\0';
356
357     return new_arg;
358 }
359 #endif
360
361
362
363 #define ARGV_NUMBER_LEN 24
364
365 gboolean
366 sync_pipe_start(capture_options *capture_opts) {
367     char ssnap[ARGV_NUMBER_LEN];
368     char scount[ARGV_NUMBER_LEN];
369     char sfilesize[ARGV_NUMBER_LEN];
370     char sfile_duration[ARGV_NUMBER_LEN];
371     char sring_num_files[ARGV_NUMBER_LEN];
372     char sautostop_files[ARGV_NUMBER_LEN];
373     char sautostop_filesize[ARGV_NUMBER_LEN];
374     char sautostop_duration[ARGV_NUMBER_LEN];
375 #ifdef _WIN32
376     char buffer_size[ARGV_NUMBER_LEN];
377     char *filterstring;
378     char *savefilestring;
379     HANDLE sync_pipe_read;                  /* pipe used to send messages from child to parent */
380     HANDLE sync_pipe_write;                 /* pipe used to send messages from child to parent */
381     HANDLE signal_pipe_read;                /* pipe used to send messages from parent to child (currently only stop) */
382     HANDLE signal_pipe_write;               /* pipe used to send messages from parent to child (currently only stop) */
383     GString *args = g_string_sized_new(200);
384     gchar *quoted_arg;
385     SECURITY_ATTRIBUTES sa; 
386     STARTUPINFO si;
387     PROCESS_INFORMATION pi;
388     int i;
389 #else
390     char errmsg[1024+1];
391     int sync_pipe[2];                       /* pipe used to send messages from child to parent */
392     enum PIPES { PIPE_READ, PIPE_WRITE };   /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
393 #endif
394     int sync_pipe_read_fd;
395     char *exename;
396     int argc;
397     const char **argv;
398
399
400     g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_start");
401     capture_opts_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, capture_opts);
402
403     capture_opts->fork_child = -1;
404
405     /* Allocate the string pointer array with enough space for the
406        terminating NULL pointer. */
407     argc = 0;
408     argv = g_malloc(sizeof (char *));
409     *argv = NULL;
410
411     /* take ethereal's absolute program path and replace ethereal with dumpcap */
412     exename = g_strdup_printf("%s" G_DIR_SEPARATOR_S "dumpcap",
413                               get_progfile_dir());
414
415     /* Make that the first argument in the argument list (argv[0]). */
416     argv = sync_pipe_add_arg(argv, &argc, exename);
417
418     argv = sync_pipe_add_arg(argv, &argc, "-i");
419     argv = sync_pipe_add_arg(argv, &argc, capture_opts->iface);
420
421     if (capture_opts->has_snaplen) {
422       argv = sync_pipe_add_arg(argv, &argc, "-s");
423       g_snprintf(ssnap, ARGV_NUMBER_LEN, "%d",capture_opts->snaplen);
424       argv = sync_pipe_add_arg(argv, &argc, ssnap);
425     }
426
427     if (capture_opts->linktype != -1) {
428       argv = sync_pipe_add_arg(argv, &argc, "-y");
429 #ifdef HAVE_PCAP_DATALINK_VAL_TO_NAME
430       g_snprintf(ssnap, ARGV_NUMBER_LEN, "%s",linktype_val_to_name(capture_opts->linktype));
431 #else
432       /* XXX - just treat it as a number */
433       g_snprintf(ssnap, ARGV_NUMBER_LEN, "%d",capture_opts->linktype);
434 #endif
435       argv = sync_pipe_add_arg(argv, &argc, ssnap);
436     }
437
438     if(capture_opts->multi_files_on) {
439       if (capture_opts->has_autostop_filesize) {
440         argv = sync_pipe_add_arg(argv, &argc, "-b");
441         g_snprintf(sfilesize, ARGV_NUMBER_LEN, "filesize:%d",capture_opts->autostop_filesize);
442         argv = sync_pipe_add_arg(argv, &argc, sfilesize);
443       }
444
445       if (capture_opts->has_file_duration) {
446         argv = sync_pipe_add_arg(argv, &argc, "-b");
447         g_snprintf(sfile_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->file_duration);
448         argv = sync_pipe_add_arg(argv, &argc, sfile_duration);
449       }
450
451       if (capture_opts->has_ring_num_files) {
452         argv = sync_pipe_add_arg(argv, &argc, "-b");
453         g_snprintf(sring_num_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->ring_num_files);
454         argv = sync_pipe_add_arg(argv, &argc, sring_num_files);
455       }
456
457       if (capture_opts->has_autostop_files) {
458         argv = sync_pipe_add_arg(argv, &argc, "-a");
459         g_snprintf(sautostop_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->autostop_files);
460         argv = sync_pipe_add_arg(argv, &argc, sautostop_files);
461       }
462     } else {
463         if (capture_opts->has_autostop_filesize) {
464           argv = sync_pipe_add_arg(argv, &argc, "-a");
465           g_snprintf(sautostop_filesize, ARGV_NUMBER_LEN, "filesize:%d",capture_opts->autostop_filesize);
466           argv = sync_pipe_add_arg(argv, &argc, sautostop_filesize);
467         }
468     }
469
470     if (capture_opts->has_autostop_packets) {
471       argv = sync_pipe_add_arg(argv, &argc, "-c");
472       g_snprintf(scount, ARGV_NUMBER_LEN, "%d",capture_opts->autostop_packets);
473       argv = sync_pipe_add_arg(argv, &argc, scount);
474     }
475
476     if (capture_opts->has_autostop_duration) {
477       argv = sync_pipe_add_arg(argv, &argc, "-a");
478       g_snprintf(sautostop_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->autostop_duration);
479       argv = sync_pipe_add_arg(argv, &argc, sautostop_duration);
480     }
481
482     if (!capture_opts->promisc_mode)
483       argv = sync_pipe_add_arg(argv, &argc, "-p");
484
485     /* dumpcap should be running in capture child mode (hidden feature) */
486 #ifndef DEBUG_CHILD
487     argv = sync_pipe_add_arg(argv, &argc, "-Z");
488 #endif
489
490 #ifdef _WIN32
491     argv = sync_pipe_add_arg(argv, &argc, "-B");
492     g_snprintf(buffer_size, ARGV_NUMBER_LEN, "%d",capture_opts->buffer_size);
493     argv = sync_pipe_add_arg(argv, &argc, buffer_size);
494 #endif
495
496     if (capture_opts->cfilter) {
497       argv = sync_pipe_add_arg(argv, &argc, "-f");
498       argv = sync_pipe_add_arg(argv, &argc, capture_opts->cfilter);
499     }
500
501     if(capture_opts->save_file) {
502       argv = sync_pipe_add_arg(argv, &argc, "-w");
503       argv = sync_pipe_add_arg(argv, &argc, capture_opts->save_file);
504     }
505
506 #ifdef _WIN32
507     /* init SECURITY_ATTRIBUTES */
508     sa.nLength = sizeof(SECURITY_ATTRIBUTES); 
509     sa.bInheritHandle = TRUE; 
510     sa.lpSecurityDescriptor = NULL; 
511
512     /* Create a pipe for the child process */
513     /* (inrease this value if you have trouble while fast capture file switches) */
514     if (! CreatePipe(&sync_pipe_read, &sync_pipe_write, &sa, 5120)) {
515       /* Couldn't create the pipe between parent and child. */
516       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Couldn't create sync pipe: %s",
517                         strerror(errno));
518       g_free( (gpointer) argv);
519       return FALSE;
520     }
521
522     /* Create a pipe for the parent process */
523     if (! CreatePipe(&signal_pipe_read, &signal_pipe_write, &sa, 512)) {
524       /* Couldn't create the signal pipe between parent and child. */
525       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Couldn't create signal pipe: %s",
526                         strerror(errno));
527       CloseHandle(sync_pipe_read);
528       CloseHandle(sync_pipe_write);
529       g_free( (gpointer) argv);
530       return FALSE;
531     }
532
533     /* init STARTUPINFO */
534     memset(&si, 0, sizeof(si));
535     si.cb           = sizeof(si);
536 #ifdef DEBUG_CHILD
537     si.dwFlags = STARTF_USESHOWWINDOW;
538     si.wShowWindow  = SW_SHOW;
539 #else
540     si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
541     si.wShowWindow  = SW_HIDE;  /* this hides the console window */
542     si.hStdInput = signal_pipe_read;
543     si.hStdOutput = sync_pipe_write;
544     si.hStdError = sync_pipe_write;
545     /*si.hStdError = (HANDLE) _get_osfhandle(2);*/
546 #endif
547
548     /*
549      * XXX - is this necessary?  argv[0] should be the full path of
550      * dumpcap.
551      */
552     quoted_arg = protect_arg(exename);
553     g_string_append(args, quoted_arg);
554     g_free(quoted_arg);
555
556     /* convert args array into a single string */
557     /* XXX - could change sync_pipe_add_arg() instead */
558     /* there is a drawback here: the length is internally limited to 1024 bytes */
559     for(i=0; argv[i] != 0; i++) {
560         g_string_append_c(args, ' ');
561         quoted_arg = protect_arg(argv[i]);
562         g_string_append(args, quoted_arg);
563         g_free(quoted_arg);
564     }
565
566     /* call dumpcap */
567     if(!CreateProcess(NULL, args->str, NULL, NULL, TRUE,
568                       CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
569         g_error("couldn't open dumpcap.exe!");
570     }
571     capture_opts->fork_child = (int) pi.hProcess;
572     g_string_free(args, TRUE);
573
574     /* associate the operating system filehandle to a C run-time file handle */
575     /* (good file handle infos at: http://www.flounder.com/handles.htm) */
576     sync_pipe_read_fd = _open_osfhandle( (long) sync_pipe_read, _O_BINARY);
577
578     /* associate the operating system filehandle to a C run-time file handle */
579     capture_opts->signal_pipe_write_fd = _open_osfhandle( (long) signal_pipe_write, _O_BINARY);
580
581     if (filterstring) {
582       g_free(filterstring);
583     }
584     if(savefilestring) {
585       g_free(savefilestring);
586     }
587
588     /* child own's the read side now, close our handle */
589     CloseHandle(signal_pipe_read);
590 #else /* _WIN32 */
591     if (pipe(sync_pipe) < 0) {
592       /* Couldn't create the pipe between parent and child. */
593       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Couldn't create sync pipe: %s",
594                         strerror(errno));
595       g_free(argv);
596       return FALSE;
597     }
598
599     if ((capture_opts->fork_child = fork()) == 0) {
600       /*
601        * Child process - run Ethereal with the right arguments to make
602        * it just pop up the live capture dialog box and capture with
603        * the specified capture parameters, writing to the specified file.
604        *
605        * args: -i interface specification
606        * -w file to write
607        * -c count to capture
608        * -s snaplen
609        * -m / -b fonts
610        * -f "filter expression"
611        */
612       eth_close(1);
613       dup(sync_pipe[PIPE_WRITE]);
614       eth_close(sync_pipe[PIPE_READ]);
615       execv(exename, argv);
616       g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
617                 exename, strerror(errno));
618       sync_pipe_errmsg_to_parent(errmsg);
619
620       /* Exit with "_exit()", so that we don't close the connection
621          to the X server (and cause stuff buffered up by our parent but
622          not yet sent to be sent, as that stuff should only be sent by
623          our parent). */
624       _exit(2);
625     }
626
627     sync_pipe_read_fd = sync_pipe[PIPE_READ];
628 #endif
629
630     g_free(exename);
631
632     /* Parent process - read messages from the child process over the
633        sync pipe. */
634     g_free( (gpointer) argv);   /* free up arg array */
635
636     /* Close the write side of the pipe, so that only the child has it
637        open, and thus it completely closes, and thus returns to us
638        an EOF indication, if the child closes it (either deliberately
639        or by exiting abnormally). */
640 #ifdef _WIN32
641     CloseHandle(sync_pipe_write);
642 #else
643     eth_close(sync_pipe[PIPE_WRITE]);
644 #endif
645
646     if (capture_opts->fork_child == -1) {
647       /* We couldn't even create the child process. */
648       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
649                         "Couldn't create child process: %s", strerror(errno));
650       eth_close(sync_pipe_read_fd);
651 #ifdef _WIN32
652       eth_close(capture_opts->signal_pipe_write_fd);
653 #endif
654       return FALSE;
655     }
656
657     /* we might wait for a moment till child is ready, so update screen now */
658     main_window_update();
659
660     /* We were able to set up to read the capture file;
661        arrange that our callback be called whenever it's possible
662        to read from the sync pipe, so that it's called when
663        the child process wants to tell us something. */
664
665     /* we have a running capture, now wait for the real capture filename */
666     pipe_input_set_handler(sync_pipe_read_fd, (gpointer) capture_opts, 
667         &capture_opts->fork_child, sync_pipe_input_cb);
668
669     return TRUE;
670 }
671
672 /* There's stuff to read from the sync pipe, meaning the child has sent
673    us a message, or the sync pipe has closed, meaning the child has
674    closed it (perhaps because it exited). */
675 static gboolean 
676 sync_pipe_input_cb(gint source, gpointer user_data)
677 {
678   capture_options *capture_opts = (capture_options *)user_data;
679   char buffer[SP_MAX_MSG_LEN+1];
680   int  nread;
681   char indicator;
682
683
684   nread = pipe_read_block(source, &indicator, SP_MAX_MSG_LEN, buffer);
685   if(nread <= 0) {
686     if (nread == 0)
687       g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
688             "sync_pipe_input_cb: child has closed sync_pipe");
689     else
690       g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
691             "sync_pipe_input_cb: error reading from sync pipe");
692
693     /* The child has closed the sync pipe, meaning it's not going to be
694        capturing any more packets.  Pick up its exit status, and
695        complain if it did anything other than exit with status 0.
696
697        XXX - what if we got an error from the sync pipe?  Do we have
698        to kill the child? */
699     sync_pipe_wait_for_child(capture_opts);
700
701 #ifdef _WIN32
702     eth_close(capture_opts->signal_pipe_write_fd);
703 #endif
704     capture_input_closed(capture_opts);
705     return FALSE;
706   }
707
708   switch(indicator) {
709   case SP_FILE:
710       if(!capture_input_new_file(capture_opts, buffer)) {
711         g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: file failed, closing capture");
712
713         /* We weren't able to open the new capture file; user has been
714            alerted. Close the sync pipe. */
715         eth_close(source);
716
717         /* the child has send us a filename which we couldn't open.
718            this probably means, the child is creating files faster than we can handle it.
719            this should only be the case for very fast file switches
720            we can't do much more than telling the child to stop
721            (this is the "emergency brake" if user e.g. wants to switch files every second) */
722         sync_pipe_stop(capture_opts);
723       }
724       break;
725   case SP_PACKET_COUNT:
726     nread = atoi(buffer);
727     g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: new packets %u", nread);
728     capture_input_new_packets(capture_opts, nread);
729     break;
730   case SP_ERROR_MSG:
731     capture_input_error_message(capture_opts, buffer);
732     /* the capture child will close the sync_pipe, nothing to do for now */
733     break;
734   case SP_DROPS:
735     capture_input_drops(capture_opts, atoi(buffer));
736     break;
737   default:
738       g_assert_not_reached();
739   }
740
741   return TRUE;
742 }
743
744
745
746 /* the child process is going down, wait until it's completely terminated */
747 static void
748 sync_pipe_wait_for_child(capture_options *capture_opts)
749 {
750   int  wstatus;
751
752
753   g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: wait till child closed");
754   g_assert(capture_opts->fork_child != -1);
755
756 #ifdef _WIN32
757   /* XXX - analyze the wait status and display more information
758      in the dialog box?
759      XXX - set "fork_child" to -1 if we find it exited? */
760   if (_cwait(&wstatus, capture_opts->fork_child, _WAIT_CHILD) == -1) {
761     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
762                 "Child capture process stopped unexpectedly");
763   }
764 #else
765   if (wait(&wstatus) != -1) {
766     if (WIFEXITED(wstatus)) {
767       /* The child exited; display its exit status, if it seems uncommon (0=ok, 1=error) */
768       /* the child will inform us about errors through the sync_pipe, which will popup */
769       /* an error message, so don't popup another one */
770
771       /* XXX - if there are situations where the child won't send us such an error message, */
772       /* this should be fixed in the child and not here! */
773       if (WEXITSTATUS(wstatus) != 0 && WEXITSTATUS(wstatus) != 1) {
774         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
775                       "Child capture process exited: exit status %d",
776                       WEXITSTATUS(wstatus));
777       }
778     } else if (WIFSTOPPED(wstatus)) {
779       /* It stopped, rather than exiting.  "Should not happen." */
780       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
781                     "Child capture process stopped: %s",
782                     sync_pipe_signame(WSTOPSIG(wstatus)));
783     } else if (WIFSIGNALED(wstatus)) {
784       /* It died with a signal. */
785       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
786                     "Child capture process died: %s%s",
787                     sync_pipe_signame(WTERMSIG(wstatus)),
788                     WCOREDUMP(wstatus) ? " - core dumped" : "");
789     } else {
790       /* What?  It had to either have exited, or stopped, or died with
791          a signal; what happened here? */
792       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
793                     "Child capture process died: wait status %#o", wstatus);
794     }
795   }
796
797   /* No more child process. */
798   capture_opts->fork_child = -1;
799 #endif
800
801   g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: capture child closed");
802 }
803
804
805 #ifndef _WIN32
806 /* convert signal to corresponding name */
807 static const char *
808 sync_pipe_signame(int sig)
809 {
810   const char *sigmsg;
811   static char sigmsg_buf[6+1+3+1];
812
813   switch (sig) {
814
815   case SIGHUP:
816     sigmsg = "Hangup";
817     break;
818
819   case SIGINT:
820     sigmsg = "Interrupted";
821     break;
822
823   case SIGQUIT:
824     sigmsg = "Quit";
825     break;
826
827   case SIGILL:
828     sigmsg = "Illegal instruction";
829     break;
830
831   case SIGTRAP:
832     sigmsg = "Trace trap";
833     break;
834
835   case SIGABRT:
836     sigmsg = "Abort";
837     break;
838
839   case SIGFPE:
840     sigmsg = "Arithmetic exception";
841     break;
842
843   case SIGKILL:
844     sigmsg = "Killed";
845     break;
846
847   case SIGBUS:
848     sigmsg = "Bus error";
849     break;
850
851   case SIGSEGV:
852     sigmsg = "Segmentation violation";
853     break;
854
855   /* http://metalab.unc.edu/pub/Linux/docs/HOWTO/GCC-HOWTO
856      Linux is POSIX compliant.  These are not POSIX-defined signals ---
857      ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990), paragraph B.3.3.1.1 sez:
858
859         ``The signals SIGBUS, SIGEMT, SIGIOT, SIGTRAP, and SIGSYS
860         were omitted from POSIX.1 because their behavior is
861         implementation dependent and could not be adequately catego-
862         rized.  Conforming implementations may deliver these sig-
863         nals, but must document the circumstances under which they
864         are delivered and note any restrictions concerning their
865         delivery.''
866
867      So we only check for SIGSYS on those systems that happen to
868      implement them (a system can be POSIX-compliant and implement
869      them, it's just that POSIX doesn't *require* a POSIX-compliant
870      system to implement them).
871    */
872
873 #ifdef SIGSYS
874   case SIGSYS:
875     sigmsg = "Bad system call";
876     break;
877 #endif
878
879   case SIGPIPE:
880     sigmsg = "Broken pipe";
881     break;
882
883   case SIGALRM:
884     sigmsg = "Alarm clock";
885     break;
886
887   case SIGTERM:
888     sigmsg = "Terminated";
889     break;
890
891   default:
892         /* XXX - returning a static buffer is ok in the context we use it here */
893     g_snprintf(sigmsg_buf, sizeof sigmsg_buf, "Signal %d", sig);
894     sigmsg = sigmsg_buf;
895     break;
896   }
897   return sigmsg;
898 }
899 #endif
900
901
902 /* user wants to stop the capture run */
903 void
904 sync_pipe_stop(capture_options *capture_opts)
905 {
906   /* XXX - in which cases this will be 0? */
907   if (capture_opts->fork_child != -1 && capture_opts->fork_child != 0) {
908 #ifndef _WIN32
909     /* send the SIGUSR1 signal to close the capture child gracefully. */
910     kill(capture_opts->fork_child, SIGUSR1);
911 #else
912     /* Win32 doesn't have the kill() system call, use the special signal pipe 
913        instead to close the capture child gracefully. */
914     signal_pipe_capquit_to_child(capture_opts);
915 #endif
916   }
917 }
918
919
920 /* Ethereal has to exit, force the capture child to close */
921 void
922 sync_pipe_kill(capture_options *capture_opts)
923 {
924   /* XXX - in which cases this will be 0? */
925   if (capture_opts->fork_child != -1 && capture_opts->fork_child != 0) {
926 #ifndef _WIN32
927       kill(capture_opts->fork_child, SIGTERM);  /* SIGTERM so it can clean up if necessary */
928 #else
929       /* XXX: this is not the preferred method of closing a process!
930        * the clean way would be getting the process id of the child process,
931        * then getting window handle hWnd of that process (using EnumChildWindows),
932        * and then do a SendMessage(hWnd, WM_CLOSE, 0, 0) 
933        *
934        * Unfortunately, I don't know how to get the process id from the
935        * handle.  OpenProcess will get an handle (not a window handle)
936        * from the process ID; it will not get a window handle from the
937        * process ID.  (How could it?  A process can have more than one
938        * window.)
939        *
940        * Hint: GenerateConsoleCtrlEvent() will only work if both processes are 
941        * running in the same console; that's not necessarily the case for
942        * us, as we might not be running in a console.
943        * And this also will require to have the process id.
944        */
945       TerminateProcess((HANDLE) (capture_opts->fork_child), 0);
946 #endif
947   }
948 }
949
950 #endif /* HAVE_LIBPCAP */