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