diff --git a/capture.c b/capture.c index dfee5f82b7..c29447b4fc 100644 --- a/capture.c +++ b/capture.c @@ -72,7 +72,7 @@ #define O_BINARY 0 #endif -static gboolean normal_do_capture(capture_options *capture_opts, gboolean is_tempfile); +/*static gboolean normal_do_capture(capture_options *capture_opts, gboolean is_tempfile);*/ static void stop_capture_signal_handler(int signo); @@ -92,8 +92,16 @@ capture_open_output(capture_options *capture_opts, gboolean *is_tempfile) { capfile_name = g_strdup(capture_opts->save_file); if (capture_opts->multi_files_on) { /* ringbuffer is enabled */ - capture_opts->save_file_fd = ringbuf_init(capfile_name, - (capture_opts->has_ring_num_files) ? capture_opts->ring_num_files : 0); +/* capture_opts->save_file_fd = ringbuf_init(capfile_name, + (capture_opts->has_ring_num_files) ? capture_opts->ring_num_files : 0);*/ + /* XXX - this is a hack, we need to find a way to move this whole function to capture_loop.c */ + capture_opts->save_file_fd = -1; + if(capture_opts->save_file != NULL) { + g_free(capture_opts->save_file); + } + capture_opts->save_file = capfile_name; + *is_tempfile = FALSE; + return TRUE; } else { /* Try to open/create the specified file for use as a capture buffer. */ capture_opts->save_file_fd = open(capfile_name, O_RDWR|O_BINARY|O_TRUNC|O_CREAT, @@ -115,7 +123,7 @@ capture_open_output(capture_options *capture_opts, gboolean *is_tempfile) { "could not be opened: %s.", capfile_name, strerror(errno)); } else { if (capture_opts->multi_files_on) { - ringbuf_error_cleanup(); +/* ringbuf_error_cleanup();*/ } open_failure_alert_box(capfile_name, errno, TRUE); } @@ -134,17 +142,19 @@ capture_open_output(capture_options *capture_opts, gboolean *is_tempfile) { } +#if 0 /* close the output file (NOT the capture file) */ static void capture_close_output(capture_options *capture_opts) { if (capture_opts->multi_files_on) { - ringbuf_free(); +/* ringbuf_free();*/ } else { g_free(capture_opts->save_file); } capture_opts->save_file = NULL; } +#endif /* Open a specified file, or create a temporary file, and start a capture @@ -173,17 +183,19 @@ do_capture(capture_options *capture_opts) * If this is fixed, we could always use the sync mode, throwing away the * normal mode completely and doing some more cleanup. */ /* if (TRUE) {*/ - if (capture_opts->sync_mode) { +/* if (capture_opts->sync_mode) {*/ /* sync mode: do the capture in a child process */ ret = sync_pipe_do_capture(capture_opts, is_tempfile); /* capture is still running */ cf_callback_invoke(cf_cb_live_capture_prepare, capture_opts); +#if 0 } else { /* normal mode: do the capture synchronously */ cf_callback_invoke(cf_cb_live_capture_prepare, capture_opts); ret = normal_do_capture(capture_opts, is_tempfile); /* capture is finished here */ } +#endif return ret; } @@ -268,6 +280,7 @@ guint32 drops) } +#if 0 /* start a normal capture session */ static gboolean normal_do_capture(capture_options *capture_opts, gboolean is_tempfile) @@ -292,6 +305,7 @@ normal_do_capture(capture_options *capture_opts, gboolean is_tempfile) capture_close_output(capture_opts); return succeeded; } +#endif static void @@ -304,7 +318,7 @@ stop_capture_signal_handler(int signo _U_) int capture_child_start(capture_options *capture_opts, gboolean *stats_known, struct pcap_stat *stats) { - gchar *err_msg; +/* gchar *err_msg;*/ g_assert(capture_opts->capture_child); @@ -316,6 +330,7 @@ capture_child_start(capture_options *capture_opts, gboolean *stats_known, struct signal(SIGUSR1, stop_capture_signal_handler); #endif +#if 0 /* parent must have send us a file descriptor for the opened output file */ if (capture_opts->save_file_fd == -1) { /* send this to the standard output as something our parent @@ -325,6 +340,7 @@ capture_child_start(capture_options *capture_opts, gboolean *stats_known, struct g_free(err_msg); return FALSE; } +#endif return capture_loop_start(capture_opts, stats_known, stats); } diff --git a/capture_loop.c b/capture_loop.c index 1f947fa6f1..32771d5c04 100644 --- a/capture_loop.c +++ b/capture_loop.c @@ -1027,6 +1027,26 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct /* We haven't yet gotten the capture statistics. */ *stats_known = FALSE; + /*g_warning("capture_loop_start"); + capture_opts_info(capture_opts);*/ + + /*_asm {int 3};*/ + + if (capture_opts->multi_files_on) { + /* ringbuffer is enabled */ + capture_opts->save_file_fd = ringbuf_init(capture_opts->save_file, + (capture_opts->has_ring_num_files) ? capture_opts->ring_num_files : 0); + if (capture_opts->save_file_fd == -1) { + ringbuf_error_cleanup(); + goto error; + } + + /* replace save_file by current ringbuffer filename */ + if(capture_opts->save_file) { + g_free(capture_opts->save_file); + } + capture_opts->save_file = g_strdup(ringbuf_current_filename()); + } /* open the "input file" from network interface or capture pipe */ if (!capture_loop_open_input(capture_opts, &ld, errmsg, sizeof(errmsg))) { @@ -1123,6 +1143,9 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct if (cnd_file_duration) { cnd_reset(cnd_file_duration); } + if (capture_opts->capture_child) { + sync_pipe_filename_to_parent(capture_opts->save_file); + } } else { /* File switch failed: stop here */ ld.go = FALSE; @@ -1191,6 +1214,9 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct cnd_reset(cnd_file_duration); if(cnd_autostop_size) cnd_reset(cnd_autostop_size); + if (capture_opts->capture_child) { + sync_pipe_filename_to_parent(capture_opts->save_file); + } } else { /* File switch failed: stop here */ ld.go = FALSE; diff --git a/capture_opts.c b/capture_opts.c index f2bdc06900..ccf73f62bb 100644 --- a/capture_opts.c +++ b/capture_opts.c @@ -85,6 +85,39 @@ capture_opts_init(capture_options *capture_opts, void *cfile) capture_opts->fork_child = -1; /* invalid process handle */ } + +/* debug only: print content of capture_opts to console */ +void +capture_opts_info(capture_options *capture_opts) { + g_warning("CAPTURE OPTIONS :"); + g_warning("File : %s", capture_opts->cf); + g_warning("Filter : %s", capture_opts->cfilter); + g_warning("Interface : %s", capture_opts->iface); +#ifdef _WIN32 + g_warning("BufferSize : %u (MB)", capture_opts->buffer_size); +#endif + g_warning("SnapLen (%u): %u", capture_opts->has_snaplen, capture_opts->snaplen); + g_warning("Promisc : %u", capture_opts->promisc_mode); + g_warning("LinkType : %d", capture_opts->linktype); + g_warning("Child : %u", capture_opts->capture_child); + g_warning("SaveFile : %s", capture_opts->save_file); + g_warning("SaveFileFd : %d", capture_opts->save_file_fd); + g_warning("SyncMode : %u", capture_opts->sync_mode); + g_warning("ShowInfo : %u", capture_opts->show_info); + g_warning("QuitAfterCap : %u", capture_opts->quit_after_cap); + + g_warning("MultiFilesOn : %u", capture_opts->multi_files_on); + g_warning("FileDuration (%u): %u", capture_opts->has_file_duration, capture_opts->file_duration); + g_warning("RingNumFiles (%u): %u", capture_opts->has_ring_num_files, capture_opts->ring_num_files); + + g_warning("AutostopFiles (%u): %u", capture_opts->has_autostop_files, capture_opts->autostop_files); + g_warning("AutostopPackets (%u): %u", capture_opts->has_autostop_packets, capture_opts->autostop_packets); + g_warning("AutostopFilesize(%u): %u", capture_opts->has_autostop_filesize, capture_opts->autostop_filesize); + g_warning("AutostopDuration(%u): %u", capture_opts->has_autostop_duration, capture_opts->autostop_duration); + + g_warning("ForkChild : %d", capture_opts->fork_child); +} + /* * Given a string of the form ":", as might appear * as an argument to a "-a" option, parse it and set the criterion in @@ -148,18 +181,12 @@ get_ring_arguments(capture_options *capture_opts, const char *appname, const cha gchar *p = NULL, *colonp; colonp = strchr(arg, ':'); - - if (colonp != NULL) { - p = colonp; - *p++ = '\0'; - } - - capture_opts->ring_num_files = - get_natural_int(appname, arg, "number of ring buffer files"); - if (colonp == NULL) return TRUE; + p = colonp; + *p++ = '\0'; + /* * Skip over any white space (there probably won't be any, but * as we allow it in the preferences file, we might as well @@ -177,9 +204,16 @@ get_ring_arguments(capture_options *capture_opts, const char *appname, const cha return FALSE; } - capture_opts->has_file_duration = TRUE; - capture_opts->file_duration = get_positive_int(appname, p, - "ring buffer duration"); + if (strcmp(arg,"files") == 0) { + capture_opts->has_ring_num_files = TRUE; + capture_opts->ring_num_files = get_natural_int(appname, p, "number of ring buffer files"); + } else if (strcmp(arg,"filesize") == 0) { + capture_opts->has_autostop_filesize = TRUE; + capture_opts->autostop_filesize = get_positive_int(appname, p, "ring buffer filesize"); + } else if (strcmp(arg,"duration") == 0) { + capture_opts->has_file_duration = TRUE; + capture_opts->file_duration = get_positive_int(appname, p, "ring buffer duration"); + } *colonp = ':'; /* put the colon back */ return TRUE; @@ -202,7 +236,6 @@ capture_opts_add_opt(capture_options *capture_opts, const char *appname, int opt break; case 'b': /* Ringbuffer option */ capture_opts->multi_files_on = TRUE; - capture_opts->has_ring_num_files = TRUE; if (get_ring_arguments(capture_opts, appname, optarg) == FALSE) { fprintf(stderr, "%s: Invalid or unknown -b arg \"%s\"\n", appname, optarg); exit(1); diff --git a/capture_sync.c b/capture_sync.c index 092cce08d5..9cb7a12e4f 100644 --- a/capture_sync.c +++ b/capture_sync.c @@ -221,7 +221,11 @@ sync_pipe_do_capture(capture_options *capture_opts, gboolean is_tempfile) { char *msg; int err; char ssnap[24]; - char scount[24]; /* need a constant for len of numbers */ + char scount[24]; /* need a constant for len of numbers */ + char sfilesize[24]; /* need a constant for len of numbers */ + char sfile_duration[24]; /* need a constant for len of numbers */ + char sring_num_files[24]; /* need a constant for len of numbers */ + char sautostop_files[24]; /* need a constant for len of numbers */ char sautostop_filesize[24]; /* need a constant for len of numbers */ char sautostop_duration[24]; /* need a constant for len of numbers */ char save_file_fd_str[24]; @@ -239,6 +243,10 @@ sync_pipe_do_capture(capture_options *capture_opts, gboolean is_tempfile) { enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */ int sync_pipe[2]; /* pipes used to sync between instances */ + + /*g_warning("sync_pipe_do_capture"); + capture_opts_info(capture_opts);*/ + capture_opts->fork_child = -1; /* Allocate the string pointer array with enough space for the @@ -260,12 +268,6 @@ sync_pipe_do_capture(capture_options *capture_opts, gboolean is_tempfile) { sprintf(save_file_fd_str,"%d",capture_opts->save_file_fd); /* in lieu of itoa */ argv = sync_pipe_add_arg(argv, &argc, save_file_fd_str); - if (capture_opts->has_autostop_packets) { - argv = sync_pipe_add_arg(argv, &argc, "-c"); - sprintf(scount,"%d",capture_opts->autostop_packets); - argv = sync_pipe_add_arg(argv, &argc, scount); - } - if (capture_opts->has_snaplen) { argv = sync_pipe_add_arg(argv, &argc, "-s"); sprintf(ssnap,"%d",capture_opts->snaplen); @@ -283,10 +285,42 @@ sync_pipe_do_capture(capture_options *capture_opts, gboolean is_tempfile) { argv = sync_pipe_add_arg(argv, &argc, ssnap); } - if (capture_opts->has_autostop_filesize) { - argv = sync_pipe_add_arg(argv, &argc, "-a"); - sprintf(sautostop_filesize,"filesize:%d",capture_opts->autostop_filesize); - argv = sync_pipe_add_arg(argv, &argc, sautostop_filesize); + if(capture_opts->multi_files_on) { + if (capture_opts->has_autostop_filesize) { + argv = sync_pipe_add_arg(argv, &argc, "-b"); + sprintf(sfilesize,"filesize:%d",capture_opts->autostop_filesize); + argv = sync_pipe_add_arg(argv, &argc, sfilesize); + } + + if (capture_opts->has_file_duration) { + argv = sync_pipe_add_arg(argv, &argc, "-b"); + sprintf(sfile_duration,"duration:%d",capture_opts->file_duration); + argv = sync_pipe_add_arg(argv, &argc, sfile_duration); + } + + if (capture_opts->has_ring_num_files) { + argv = sync_pipe_add_arg(argv, &argc, "-b"); + sprintf(sring_num_files,"files:%d",capture_opts->ring_num_files); + argv = sync_pipe_add_arg(argv, &argc, sring_num_files); + } + + if (capture_opts->has_autostop_files) { + argv = sync_pipe_add_arg(argv, &argc, "-a"); + sprintf(sautostop_files,"files:%d",capture_opts->autostop_files); + argv = sync_pipe_add_arg(argv, &argc, sautostop_files); + } + } else { + if (capture_opts->has_autostop_filesize) { + argv = sync_pipe_add_arg(argv, &argc, "-a"); + sprintf(sautostop_filesize,"filesize:%d",capture_opts->autostop_filesize); + argv = sync_pipe_add_arg(argv, &argc, sautostop_filesize); + } + } + + if (capture_opts->has_autostop_packets) { + argv = sync_pipe_add_arg(argv, &argc, "-c"); + sprintf(scount,"%d",capture_opts->autostop_packets); + argv = sync_pipe_add_arg(argv, &argc, scount); } if (capture_opts->has_autostop_duration) { @@ -304,7 +338,6 @@ sync_pipe_do_capture(capture_options *capture_opts, gboolean is_tempfile) { #ifdef _WIN32 /* Create a pipe for the child process */ - if(_pipe(sync_pipe, 512, O_BINARY) < 0) { /* Couldn't create the pipe between parent and child. */ error = errno; @@ -402,7 +435,9 @@ sync_pipe_do_capture(capture_options *capture_opts, gboolean is_tempfile) { /* Close the save file FD, as we won't be using it - we'll be opening it and reading the save file through Wiretap. */ - close(capture_opts->save_file_fd); + if(capture_opts->save_file_fd != -1) { + close(capture_opts->save_file_fd); + } if (capture_opts->fork_child == -1) { /* We couldn't even create the child process. */ @@ -676,10 +711,6 @@ sync_pipe_input_cb(gint source, gpointer user_data) } *r = '\0'; - /* currently, both filenames must be equal */ - /* (this will change, when multiple files together with sync_mode are captured) */ - g_assert(strcmp(capture_opts->save_file, msg) == 0); - /* save the new filename */ if(capture_opts->save_file != NULL) { g_free(capture_opts->save_file); diff --git a/gtk/main.c b/gtk/main.c index 327f257a21..a269d867d0 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -2070,12 +2070,12 @@ main(int argc, char *argv[]) fprintf(stderr, "ethereal: Ring buffer requested, but capture isn't being saved to a permanent file.\n"); capture_opts->multi_files_on = FALSE; } - if (capture_opts->sync_mode) { +/* if (capture_opts->sync_mode) { fprintf(stderr, "ethereal: Ring buffer requested, but an \"Update list of packets in real time\" capture is being done.\n"); capture_opts->multi_files_on = FALSE; - } - if (!capture_opts->has_autostop_filesize) { - fprintf(stderr, "ethereal: Ring buffer requested, but no maximum capture file size was specified.\n"); + }*/ + if (!capture_opts->has_autostop_filesize && !capture_opts->has_file_duration) { + fprintf(stderr, "ethereal: Ring buffer requested, but no maximum capture file size or duration were specified.\n"); capture_opts->multi_files_on = FALSE; } } diff --git a/ringbuffer.c b/ringbuffer.c index 1a89e6d4bb..4cfc637a3c 100644 --- a/ringbuffer.c +++ b/ringbuffer.c @@ -232,6 +232,12 @@ ringbuf_init(const char *capfile_name, guint num_files) return rb_data.fd; } + +const gchar *ringbuf_current_filename(void) +{ + return rb_data.files[rb_data.curr_file_num % rb_data.num_files].name; +} + /* * Calls wtap_dump_fdopen() for the current ringbuffer file */ diff --git a/ringbuffer.h b/ringbuffer.h index b5904053e3..8962cf1dac 100644 --- a/ringbuffer.h +++ b/ringbuffer.h @@ -38,6 +38,7 @@ #define RINGBUFFER_MAX_NUM_FILES 1024 int ringbuf_init(const char *capture_name, guint num_files); +const gchar *ringbuf_current_filename(void); wtap_dumper* ringbuf_init_wtap_dump_fdopen(int filetype, int linktype, int snaplen, int *err); gboolean ringbuf_switch_file(wtap_dumper **pdh, gchar **save_file, int *save_file_fd, int *err);