capture engine:
authorulfl <ulfl@f5534014-38df-0310-8fa8-9805f1628bb7>
Tue, 12 Apr 2005 21:44:55 +0000 (21:44 +0000)
committerulfl <ulfl@f5534014-38df-0310-8fa8-9805f1628bb7>
Tue, 12 Apr 2005 21:44:55 +0000 (21:44 +0000)
add a new feature to clear the currently captured packets and restart the capture with the previous parameters

various code cleanup and minor bugfixes

Win32: use millisecond resolution in capture_loop, to smooth screen update a bit (500ms instead of 1000ms)

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@14059 f5534014-38df-0310-8fa8-9805f1628bb7

capture.c
capture.h
capture_loop.c
capture_opts.c
capture_sync.c
capture_sync.h
gtk/capture_dlg.c
gtk/capture_dlg.h
gtk/menu.c
gtk/toolbar.c

index 951b02114b8eb400ee8c0eb420a729c2e649f7cf..5b4df8b907ee272dfb2407b764386e2fc23d8ad5 100644 (file)
--- 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;
     }
index fcaaf2527a99ab20590b1c7bfe2b8ee20bd5bfcb..98cafb1cc75ee7c9a26759ab18d266d73c987720 100644 (file)
--- 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);
 
index 2bf21491b19a54419c16585192b0f04f0b9b4aba..dda243f68c2684f166c8bcb968981fd0cd7f357c 100644 (file)
@@ -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 */
index f00f2fc9a8016953eabcda5494c25df777727dae..3c4f126dc2ff515ee18d9608ac622326d30b9505 100644 (file)
@@ -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;
index 169014dde5c28f216ff0f8811ae0d2d225a6b98c..b03cb9eb327ec4d49d16c5587c00c5b43821b3ef 100644 (file)
@@ -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);*/
     }
@@ -221,23 +224,13 @@ pipe_read_block(int pipe, char *indicator, int len, char *msg) {
     return len + 4;
 }
 
-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
   }
 }
index b429cc418465a9272aecb8adbffc482d570ad92f..fc6b0a63c9da2721cd5c189e7dff0b500e0d925a 100644 (file)
@@ -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);
index 470a22cf3793bd1be75459d17fa1e128bb77a519..91be8dd60eaaa7a928564cec56fce7b75e095912 100644 (file)
@@ -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
index 3bd1904d2bcf970d09d2d3142ade9d2ed465a2a7..0dc9e92be092e3ecdefeca4f73ca2fb217a0189f 100644 (file)
@@ -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);
index 41d483c05d515e1ff3eb8881b24d137c1913bd10..449c0449e97076a9b7d932fc41b558168abc35f0 100644 (file)
@@ -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);
index 459a88bd48036f6ade810c91c03fa6b5016944c1..bedaa4059e03f752aba6630bc3458e6e08443149 100644 (file)
 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 */