aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--capture.c28
-rw-r--r--capture.h8
-rw-r--r--capture_loop.c62
-rw-r--r--capture_opts.c1
-rw-r--r--capture_sync.c80
-rw-r--r--capture_sync.h4
-rw-r--r--gtk/capture_dlg.c6
-rw-r--r--gtk/capture_dlg.h7
-rw-r--r--gtk/menu.c7
-rw-r--r--gtk/toolbar.c13
10 files changed, 131 insertions, 85 deletions
diff --git a/capture.c b/capture.c
index 951b02114b..5b4df8b907 100644
--- a/capture.c
+++ b/capture.c
@@ -102,6 +102,15 @@ capture_stop(capture_options *capture_opts)
sync_pipe_stop(capture_opts);
}
+
+void
+capture_clear(capture_options *capture_opts)
+{
+ capture_opts->restart = TRUE;
+ capture_stop(capture_opts);
+}
+
+
void
capture_kill_child(capture_options *capture_opts)
{
@@ -267,6 +276,7 @@ capture_input_new_packets(capture_options *capture_opts, int to_read)
file.
XXX - abort on a read error? */
+ main_window_update();
break;
case CF_READ_ABORTED:
@@ -325,8 +335,22 @@ capture_input_closed(capture_options *capture_opts)
cf_get_drops_known(capture_opts->cf), cf_get_drops(capture_opts->cf));
}
- /* We're not doing a capture any more, so we don't have a save file. */
- if(capture_opts->save_file) {
+ /* does the user wants to restart the current capture? */
+ if(capture_opts->restart) {
+ capture_opts->restart = FALSE;
+
+ unlink(capture_opts->save_file);
+
+ /* if it was a tempfile, throw away the old filename (so it will become a tempfile again) */
+ if(cf_is_tempfile(capture_opts->cf)) {
+ g_free(capture_opts->save_file);
+ capture_opts->save_file = NULL;
+ }
+
+ /* ... and start the capture again */
+ capture_start(capture_opts);
+ } else {
+ /* We're not doing a capture any more, so we don't have a save file. */
g_free(capture_opts->save_file);
capture_opts->save_file = NULL;
}
diff --git a/capture.h b/capture.h
index fcaaf2527a..98cafb1cc7 100644
--- a/capture.h
+++ b/capture.h
@@ -53,9 +53,10 @@ typedef struct capture_options_tag {
gchar *save_file; /**< the capture file name */
/* GUI related */
- gboolean real_time_mode;/**< Update list of packets in real time */
- gboolean show_info; /**< show the info dialog */
+ gboolean real_time_mode; /**< Update list of packets in real time */
+ gboolean show_info; /**< show the info dialog */
gboolean quit_after_cap; /** Makes a "capture only mode". Implies -k */
+ gboolean restart; /**< restart after closing is done */
/* multiple files (and ringbuffer) */
gboolean multi_files_on; /**< TRUE if ring buffer in use */
@@ -106,6 +107,9 @@ extern gboolean capture_start(capture_options *capture_opts);
/** Stop a capture session (usually from a menu item). */
extern void capture_stop(capture_options *capture_opts);
+/** Clear the current captured packets and start again. */
+extern void capture_clear(capture_options *capture_opts);
+
/** Terminate the capture child cleanly when exiting. */
extern void capture_kill_child(capture_options *capture_opts);
diff --git a/capture_loop.c b/capture_loop.c
index 2bf21491b1..dda243f68c 100644
--- a/capture_loop.c
+++ b/capture_loop.c
@@ -1037,6 +1037,11 @@ capture_loop_stop_signal_handler(int signo _U_)
}
#endif
+#ifdef _WIN32
+#define TIME_GET() GetTickCount()
+#else
+#define TIME_GET() time(NULL)
+#endif
/*
* This needs to be static, so that the SIGUSR1 handler can clear the "go"
@@ -1144,7 +1149,6 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
update its windows to indicate that we have a live capture in
progress. */
fflush(wtap_dump_file(ld.wtap_pdh));
- sync_pipe_capstart_to_parent();
sync_pipe_filename_to_parent(capture_opts->save_file);
/* initialize capture stop (and alike) conditions */
@@ -1175,8 +1179,8 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
}
/* init the time values */
- start_time = time(NULL);
- upd_time = time(NULL);
+ start_time = TIME_GET();
+ upd_time = TIME_GET();
/* WOW, everything is prepared! */
/* please fasten your seat belts, we will enter now the actual capture loop */
@@ -1186,6 +1190,26 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
/* dispatch incoming packets */
inpkts = capture_loop_dispatch(capture_opts, &ld, errmsg, sizeof(errmsg));
+ main_window_update();
+
+#ifdef _WIN32
+ /* some news from our parent (signal pipe)? -> just stop the capture */
+ {
+ HANDLE handle;
+ DWORD avail = 0;
+ gboolean result;
+
+
+ handle = (HANDLE) _get_osfhandle (0);
+ result = PeekNamedPipe(handle, NULL, 0, NULL, &avail, NULL);
+
+ if(!result || avail > 0) {
+ ld.go = FALSE;
+ /*g_warning("loop closing");*/
+ }
+ }
+#endif
+
if (inpkts > 0) {
ld.packets_sync_pipe += inpkts;
@@ -1223,9 +1247,13 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
} /* inpkts */
/* Only update once a second so as not to overload slow displays */
- cur_time = time(NULL);
- if (cur_time > upd_time) {
- upd_time = cur_time;
+ cur_time = TIME_GET();
+#ifdef _WIN32
+ if ( (cur_time - upd_time) > 500) {
+#else
+ if (cur_time - upd_time > 0) {
+#endif
+ upd_time = cur_time;
/*if (pcap_stats(pch, stats) >= 0) {
*stats_known = TRUE;
@@ -1234,29 +1262,15 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
/* calculate and display running time */
if(capture_opts->show_info) {
cur_time -= start_time;
+#ifdef _WIN32
+ capture_ui.running_time = cur_time / 1000;
+#else
capture_ui.running_time = cur_time;
+#endif
capture_ui.new_packets = ld.packets_sync_pipe;
capture_info_update(&capture_ui);
}
-#ifdef _WIN32
- /* some news from our parent (signal pipe)? -> just stop the capture */
- {
- HANDLE handle;
- DWORD avail = 0;
- gboolean result;
-
-
- handle = (HANDLE) _get_osfhandle (0);
- result = PeekNamedPipe(handle, NULL, 0, NULL, &avail, NULL);
-
- if(!result || avail > 0) {
- ld.go = FALSE;
- /*g_warning("loop closing");*/
- }
- }
-#endif
-
/* Let the parent process know. */
if (ld.packets_sync_pipe) {
/* do sync here */
diff --git a/capture_opts.c b/capture_opts.c
index f00f2fc9a8..3c4f126dc2 100644
--- a/capture_opts.c
+++ b/capture_opts.c
@@ -63,6 +63,7 @@ capture_opts_init(capture_options *capture_opts, void *cfile)
capture_opts->real_time_mode = TRUE;
capture_opts->show_info = TRUE;
capture_opts->quit_after_cap = FALSE;
+ capture_opts->restart = FALSE;
capture_opts->multi_files_on = FALSE;
capture_opts->has_file_duration = FALSE;
diff --git a/capture_sync.c b/capture_sync.c
index 169014dde5..b03cb9eb32 100644
--- a/capture_sync.c
+++ b/capture_sync.c
@@ -118,12 +118,11 @@ static void sync_pipe_wait_for_child(capture_options *capture_opts, gboolean alw
/*
* Indications sent out on the sync pipe.
*/
-#define SP_CAPSTART 'S' /* capture start message */
-#define SP_CAPQUIT 'Q' /* capture quit message */
-#define SP_PACKET_COUNT 'P' /* count of packets captured since last message */
+#define SP_FILE 'F' /* the name of the recently opened file */
#define SP_ERROR_MSG 'E' /* error message */
+#define SP_PACKET_COUNT 'P' /* count of packets captured since last message */
#define SP_DROPS 'D' /* count of packets dropped in capture */
-#define SP_FILE 'F' /* the name of the recently opened file */
+#define SP_QUIT 'Q' /* capture quit message (from parent to child) */
/* write a message to the recipient pipe in the standard format
@@ -132,7 +131,7 @@ static void sync_pipe_wait_for_child(capture_options *capture_opts, gboolean alw
static void
pipe_write_block(int pipe, char indicator, int len, const char *msg)
{
- char lenbuf[SP_DECISIZE+1+1];
+ char lenbuf[3+1+1]; /* 3 digit len + indicator + zero terminator */
int ret;
/*g_warning("write %d enter", pipe);*/
@@ -140,17 +139,21 @@ pipe_write_block(int pipe, char indicator, int len, const char *msg)
g_assert(len < 1000);
g_assert(indicator < '0' || indicator > '9');
- /* write header (3 digit len + indicator + zero terminator) */
+ /* write header (3 digit len + indicator) */
g_snprintf(lenbuf, 5, "%03u%c", len, indicator);
ret = write(pipe, lenbuf, strlen(lenbuf));
- g_assert(ret != -1);
+ if(ret == -1) {
+ return;
+ }
/* write value (if we have one) */
if(len) {
/*g_warning("write %d indicator: %c value len: %u msg: %s", pipe, indicator, len, msg);*/
ret = write(pipe, msg, len);
- g_assert(ret != -1);
+ if(ret == -1) {
+ return;
+ }
} else {
/*g_warning("write %d indicator: %c no value", pipe, indicator);*/
}
@@ -222,22 +225,12 @@ pipe_read_block(int pipe, char *indicator, int len, char *msg) {
}
void
-sync_pipe_capstart_to_parent(void)
-{
-/* static const char capstart_msg = SP_CAPSTART;
-
- write(1, &capstart_msg, 1);*/
-
- pipe_write_block(1, SP_CAPSTART, 0, NULL);
-}
-
-void
sync_pipe_packet_count_to_parent(int packet_count)
{
char tmp[SP_DECISIZE+1+1];
- g_snprintf(tmp, SP_DECISIZE, "%d", packet_count);
+ g_snprintf(tmp, sizeof(tmp), "%d", packet_count);
pipe_write_block(1, SP_PACKET_COUNT, strlen(tmp)+1, tmp);
}
@@ -260,7 +253,7 @@ sync_pipe_drops_to_parent(int drops)
char tmp[SP_DECISIZE+1+1];
- g_snprintf(tmp, SP_DROPS, "%d", drops);
+ g_snprintf(tmp, sizeof(tmp), "%d", drops);
pipe_write_block(1, SP_DROPS, strlen(tmp)+1, tmp);
}
@@ -269,11 +262,11 @@ sync_pipe_drops_to_parent(int drops)
#ifdef _WIN32
static void
-signal_pipe_capend_to_child(capture_options *capture_opts)
+signal_pipe_capquit_to_child(capture_options *capture_opts)
{
- pipe_write_block(capture_opts->signal_pipe_fd, SP_CAPQUIT, 0, NULL);
+ pipe_write_block(capture_opts->signal_pipe_fd, SP_QUIT, 0, NULL);
}
#endif
@@ -603,37 +596,32 @@ sync_pipe_input_cb(gint source, gpointer user_data)
}
switch(indicator) {
- case(SP_CAPSTART):
- break;
+ case SP_FILE:
+ if(!capture_input_new_file(capture_opts, buffer)) {
+ /* We weren't able to open the new capture file; user has been
+ alerted. Close the sync pipe. */
+ /* XXX - is it safe to close the pipe inside this callback? */
+ close(source);
+
+ /* the child has send us a filename which we couldn't open.
+ this probably means, the child is creating files faster than we can handle it.
+ this should only be the case for very fast file switches
+ we can't do much more than telling the child to stop
+ (this is the emergency brake if user e.g. wants to switch files every second) */
+ sync_pipe_stop(capture_opts);
+ }
+ break;
case SP_PACKET_COUNT:
nread = atoi(buffer);
capture_input_new_packets(capture_opts, nread);
break;
+ case SP_ERROR_MSG:
+ simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, buffer);
+ break;
case SP_DROPS:
cf_set_drops_known(capture_opts->cf, TRUE);
cf_set_drops(capture_opts->cf, atoi(buffer));
break;
- case SP_ERROR_MSG:
- simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, buffer);
- break;
- case SP_FILE:
- if(!capture_input_new_file(capture_opts, buffer)) {
- /* We weren't able to open the new capture file; user has been
- alerted. Close the sync pipe. */
-
- /* XXX - how to kill things here ? */
- /* XXX - is it safe to close the pipe inside this callback? */
- close(source);
-
- /* the child has send us a filename which we couldn't open.
- this probably means, the child is creating files faster than we can handle it.
- this should only be the case for very fast file switches
- we can't do much more than telling the child to stop
- (this is the emergency brake if user e.g. wants to switch files every second) */
- sync_pipe_stop(capture_opts);
- }
-
- break;
default:
g_assert_not_reached();
}
@@ -803,7 +791,7 @@ sync_pipe_stop(capture_options *capture_opts)
#else
/* Win32 doesn't have the kill() system call, use the special signal pipe
instead to close the capture child gracefully. */
- signal_pipe_capend_to_child(capture_opts);
+ signal_pipe_capquit_to_child(capture_opts);
#endif
}
}
diff --git a/capture_sync.h b/capture_sync.h
index b429cc4184..fc6b0a63c9 100644
--- a/capture_sync.h
+++ b/capture_sync.h
@@ -58,10 +58,6 @@ extern void
sync_pipe_kill(capture_options *capture_opts);
-/** the child will immediately start capturing, notify the parent */
-extern void
-sync_pipe_capstart_to_parent(void);
-
/** the child has opened a new capture file, notify the parent */
extern void
sync_pipe_filename_to_parent(const char *filename);
diff --git a/gtk/capture_dlg.c b/gtk/capture_dlg.c
index 470a22cf37..91be8dd60e 100644
--- a/gtk/capture_dlg.c
+++ b/gtk/capture_dlg.c
@@ -126,6 +126,12 @@ capture_stop_cb(GtkWidget *w _U_, gpointer d _U_)
capture_stop(capture_opts);
}
+void
+capture_clear_cb(GtkWidget *w _U_, gpointer d _U_)
+{
+ capture_clear(capture_opts);
+}
+
/*
* Keep a static pointer to the current "Capture Options" window, if
* any, so that if somebody tries to do "Capture:Start" while there's
diff --git a/gtk/capture_dlg.h b/gtk/capture_dlg.h
index 3bd1904d2b..0dc9e92be0 100644
--- a/gtk/capture_dlg.h
+++ b/gtk/capture_dlg.h
@@ -45,6 +45,13 @@ void capture_prep_cb(GtkWidget *widget, gpointer data);
*/
void capture_stop_cb(GtkWidget *widget, gpointer data);
+/** User requested capture clear by menu or toolbar.
+ *
+ * @param widget parent widget (unused)
+ * @param data unused
+ */
+void capture_clear_cb(GtkWidget *widget, gpointer data);
+
/** Create the "Capture Options" dialog box.
*/
void capture_prep(void);
diff --git a/gtk/menu.c b/gtk/menu.c
index 41d483c05d..449c0449e9 100644
--- a/gtk/menu.c
+++ b/gtk/menu.c
@@ -300,9 +300,11 @@ static GtkItemFactoryEntry menu_items[] =
capture_prep_cb, 0, ETHEREAL_STOCK_CAPTURE_START),
ITEM_FACTORY_STOCK_ENTRY("/Capture/S_top", "<control>E", capture_stop_cb,
0, GTK_STOCK_STOP),
+ ITEM_FACTORY_STOCK_ENTRY("/Capture/_Clear", NULL, capture_clear_cb,
+ 0, GTK_STOCK_CLEAR),
ITEM_FACTORY_ENTRY("/Capture/_Interfaces...", NULL,
capture_if_cb, 0, NULL, NULL),
- ITEM_FACTORY_STOCK_ENTRY("/Capture/_Capture Filters...", NULL, cfilter_dialog_cb,
+ ITEM_FACTORY_STOCK_ENTRY("/Capture/Capture _Filters...", NULL, cfilter_dialog_cb,
0, ETHEREAL_STOCK_CAPTURE_FILTER),
#endif /* HAVE_LIBPCAP */
ITEM_FACTORY_ENTRY("/_Analyze", NULL, NULL, 0, "<Branch>", NULL),
@@ -566,6 +568,7 @@ menus_init(void) {
set_menus_for_captured_packets(FALSE);
set_menus_for_selected_packet(&cfile);
set_menus_for_selected_tree_row(&cfile);
+ set_menus_for_capture_in_progress(FALSE);
/* init with an empty recent files list */
clear_menu_recent_capture_file_cmd_cb(NULL, NULL);
@@ -1538,6 +1541,8 @@ set_menus_for_capture_in_progress(gboolean capture_in_progress)
!capture_in_progress);
set_menu_sensitivity(main_menu_factory, "/Capture/Stop",
capture_in_progress);
+ set_menu_sensitivity(main_menu_factory, "/Capture/Clear",
+ capture_in_progress);
set_toolbar_for_capture_in_progress(capture_in_progress);
set_capture_if_dialog_for_capture_in_progress(capture_in_progress);
diff --git a/gtk/toolbar.c b/gtk/toolbar.c
index 459a88bd48..bedaa4059e 100644
--- a/gtk/toolbar.c
+++ b/gtk/toolbar.c
@@ -117,7 +117,7 @@
static gboolean toolbar_init = FALSE;
#ifdef HAVE_LIBPCAP
-static GtkWidget *new_button, *stop_button;
+static GtkWidget *new_button, *stop_button, *clear_button;
static GtkWidget *capture_filter_button;
#endif /* HAVE_LIBPCAP */
static GtkWidget *open_button, *save_button, *save_as_button, *close_button, *reload_button;
@@ -283,13 +283,15 @@ void set_toolbar_for_capture_in_progress(gboolean capture_in_progress) {
if (toolbar_init) {
#ifdef HAVE_LIBPCAP
gtk_widget_set_sensitive(new_button, !capture_in_progress);
- if (capture_in_progress) {
+ gtk_widget_set_sensitive(stop_button, capture_in_progress);
+ gtk_widget_set_sensitive(clear_button, capture_in_progress);
+ /*if (capture_in_progress) {
gtk_widget_hide(new_button);
gtk_widget_show(stop_button);
} else {
gtk_widget_show(new_button);
gtk_widget_hide(stop_button);
- }
+ }*/
#endif /* HAVE_LIBPCAP */
gtk_widget_set_sensitive(open_button, !capture_in_progress);
}
@@ -391,13 +393,12 @@ toolbar_new(void)
#ifdef HAVE_LIBPCAP
- /* either start OR stop button can be valid at a time, so no space
- * between them is needed here (stop button is hidden by default) */
-
toolbar_item(new_button, window, main_tb,
ETHEREAL_STOCK_CAPTURE_START, "Start a new live capture...", capture_24_xpm, capture_prep_cb, NULL);
toolbar_item(stop_button, window, main_tb,
GTK_STOCK_STOP, "Stop the running live capture", stock_stop_24_xpm, capture_stop_cb, NULL);
+ toolbar_item(clear_button, window, main_tb,
+ GTK_STOCK_CLEAR, "Clear the captured packets", stock_clear_24_xpm, capture_clear_cb, NULL);
toolbar_append_separator(main_tb);
#endif /* HAVE_LIBPCAP */