move capture_opts related things (init, command line, ...) from capture.c to a new...
authorulfl <ulfl@f5534014-38df-0310-8fa8-9805f1628bb7>
Wed, 23 Feb 2005 01:01:19 +0000 (01:01 +0000)
committerulfl <ulfl@f5534014-38df-0310-8fa8-9805f1628bb7>
Wed, 23 Feb 2005 01:01:19 +0000 (01:01 +0000)
git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@13474 f5534014-38df-0310-8fa8-9805f1628bb7

Makefile.common
capture.c
capture_opts.c [new file with mode: 0644]
gtk/main.c
tethereal.c

index 287c8e3856745a2150639189b44d495240781565..a5b896490967f9b637cde369fe4594eea1203976 100644 (file)
@@ -152,6 +152,7 @@ ethereal_SOURCES =  \
        $(ETHEREAL_COMMON_SRC)  \
        alert_box.c     \
        capture.c       \
+    capture_opts.c \
        capture_sync.c  \
        capture_loop.c  \
        color_filters.c \
@@ -186,6 +187,7 @@ ethereal_INCLUDES = \
 tethereal_SOURCES =    \
        $(ETHEREAL_COMMON_SRC)  \
        $(TETHEREAL_TAP_SRC)    \
+    capture_opts.c \
        tethereal-tap-register.c        \
        tethereal.c
 
index f6fff57de30bc863e07841abb9d8b5b4a84e30df..f728cc2d027f0bc767d647d405a18a6df0409425 100644 (file)
--- a/capture.c
+++ b/capture.c
@@ -76,278 +76,6 @@ static gboolean normal_do_capture(capture_options *capture_opts, gboolean is_tem
 static void stop_capture_signal_handler(int signo);
 
 
-void
-capture_opts_init(capture_options *capture_opts, void *cfile)
-{
-  capture_opts->cf                      = cfile;
-  capture_opts->cfilter                            = g_strdup("");
-  capture_opts->iface                   = NULL;
-#ifdef _WIN32
-  capture_opts->buffer_size             = 1;                /* 1 MB */
-#endif
-  capture_opts->has_snaplen             = FALSE;
-  capture_opts->snaplen                 = MIN_PACKET_SIZE;
-  capture_opts->promisc_mode            = TRUE;
-  capture_opts->linktype                = -1;               /* the default linktype */
-  capture_opts->capture_child           = FALSE;
-  capture_opts->save_file               = NULL;
-  capture_opts->save_file_fd            = -1;
-  capture_opts->sync_mode               = TRUE;
-  capture_opts->show_info               = TRUE;
-  capture_opts->quit_after_cap          = FALSE;
-
-  capture_opts->multi_files_on          = FALSE;
-  capture_opts->has_file_duration       = FALSE;
-  capture_opts->file_duration           = 60;               /* 1 min */
-  capture_opts->has_ring_num_files      = TRUE;
-  capture_opts->ring_num_files          = 2;
-
-  capture_opts->has_autostop_files      = FALSE;
-  capture_opts->autostop_files          = 1;
-  capture_opts->has_autostop_packets    = FALSE;
-  capture_opts->autostop_packets        = 1;
-  capture_opts->has_autostop_filesize   = FALSE;
-  capture_opts->autostop_filesize       = 1024 * 1024;      /* 1 MB */
-  capture_opts->has_autostop_duration   = FALSE;
-  capture_opts->autostop_duration       = 60;               /* 1 min */
-
-}
-
-static int
-get_natural_int(const char *string, const char *name)
-{
-  long number;
-  char *p;
-
-  number = strtol(string, &p, 10);
-  if (p == string || *p != '\0') {
-    fprintf(stderr, "ethereal: The specified %s \"%s\" isn't a decimal number\n",
-           name, string);
-    exit(1);
-  }
-  if (number < 0) {
-    fprintf(stderr, "ethereal: The specified %s \"%s\" is a negative number\n",
-           name, string);
-    exit(1);
-  }
-  if (number > INT_MAX) {
-    fprintf(stderr, "ethereal: The specified %s \"%s\" is too large (greater than %d)\n",
-           name, string, INT_MAX);
-    exit(1);
-  }
-  return number;
-}
-
-
-static int
-get_positive_int(const char *string, const char *name)
-{
-  long number;
-
-  number = get_natural_int(string, name);
-
-  if (number == 0) {
-    fprintf(stderr, "ethereal: The specified %s is zero\n",
-           name);
-    exit(1);
-  }
-
-  return number;
-}
-
-
-/*
- * Given a string of the form "<autostop criterion>:<value>", as might appear
- * as an argument to a "-a" option, parse it and set the criterion in
- * question.  Return an indication of whether it succeeded or failed
- * in some fashion.
- */
-static gboolean
-set_autostop_criterion(capture_options *capture_opts, const char *autostoparg)
-{
-  gchar *p, *colonp;
-
-  colonp = strchr(autostoparg, ':');
-  if (colonp == NULL)
-    return FALSE;
-
-  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
-   * allow it here).
-   */
-  while (isspace((guchar)*p))
-    p++;
-  if (*p == '\0') {
-    /*
-     * Put the colon back, so if our caller uses, in an
-     * error message, the string they passed us, the message
-     * looks correct.
-     */
-    *colonp = ':';
-    return FALSE;
-  }
-  if (strcmp(autostoparg,"duration") == 0) {
-    capture_opts->has_autostop_duration = TRUE;
-    capture_opts->autostop_duration = get_positive_int(p,"autostop duration");
-  } else if (strcmp(autostoparg,"filesize") == 0) {
-    capture_opts->has_autostop_filesize = TRUE;
-    capture_opts->autostop_filesize = get_positive_int(p,"autostop filesize");
-  } else if (strcmp(autostoparg,"files") == 0) {
-    capture_opts->multi_files_on = TRUE;
-    capture_opts->has_autostop_files = TRUE;
-    capture_opts->autostop_files = get_positive_int(p,"autostop files");
-  } else {
-    return FALSE;
-  }
-  *colonp = ':'; /* put the colon back */
-  return TRUE;
-}
-
-/*
- * Given a string of the form "<ring buffer file>:<duration>", as might appear
- * as an argument to a "-b" option, parse it and set the arguments in
- * question.  Return an indication of whether it succeeded or failed
- * in some fashion.
- */
-static gboolean
-get_ring_arguments(capture_options *capture_opts, const char *arg)
-{
-  gchar *p = NULL, *colonp;
-
-  colonp = strchr(arg, ':');
-
-  if (colonp != NULL) {
-    p = colonp;
-    *p++ = '\0';
-  }
-
-  capture_opts->ring_num_files = 
-    get_natural_int(arg, "number of ring buffer files");
-
-  if (colonp == NULL)
-    return TRUE;
-
-  /*
-   * Skip over any white space (there probably won't be any, but
-   * as we allow it in the preferences file, we might as well
-   * allow it here).
-   */
-  while (isspace((guchar)*p))
-    p++;
-  if (*p == '\0') {
-    /*
-     * Put the colon back, so if our caller uses, in an
-     * error message, the string they passed us, the message
-     * looks correct.
-     */
-    *colonp = ':';
-    return FALSE;
-  }
-
-  capture_opts->has_file_duration = TRUE;
-  capture_opts->file_duration = get_positive_int(p,
-                                                     "ring buffer duration");
-
-  *colonp = ':';       /* put the colon back */
-  return TRUE;
-}
-
-
-void
-capture_opt_add(capture_options *capture_opts, int opt, const char *optarg, gboolean *start_capture)
-{
-#ifdef _WIN32
-    int i;
-#endif
-
-    switch(opt) {
-    case 'a':        /* autostop criteria */
-        if (set_autostop_criterion(capture_opts, optarg) == FALSE) {
-          fprintf(stderr, "ethereal: Invalid or unknown -a flag \"%s\"\n", optarg);
-          exit(1);
-        }
-        break;
-    case 'b':        /* Ringbuffer option */
-        capture_opts->multi_files_on = TRUE;
-        capture_opts->has_ring_num_files = TRUE;
-        if (get_ring_arguments(capture_opts, optarg) == FALSE) {
-          fprintf(stderr, "ethereal: Invalid or unknown -b arg \"%s\"\n", optarg);
-          exit(1);
-        }
-        break;
-    case 'c':        /* Capture xxx packets */
-        capture_opts->has_autostop_packets = TRUE;
-        capture_opts->autostop_packets = get_positive_int(optarg, "packet count");
-        break;
-    case 'f':        /* capture filter */
-        if (capture_opts->cfilter)
-            g_free(capture_opts->cfilter);
-        capture_opts->cfilter = g_strdup(optarg);
-        break;
-    case 'H':        /* Hide capture info dialog box */
-        capture_opts->show_info = FALSE;
-        break;
-    case 'i':        /* Use interface xxx */
-        capture_opts->iface = g_strdup(optarg);
-        break;
-    case 'k':        /* Start capture immediately */
-        *start_capture = TRUE;
-        break;
-    /*case 'l':*/    /* Automatic scrolling in live capture mode */
-    case 'p':        /* Don't capture in promiscuous mode */
-        capture_opts->promisc_mode = FALSE;
-        break;
-    case 'Q':        /* Quit after capture (just capture to file) */
-        capture_opts->quit_after_cap  = TRUE;
-        *start_capture   = TRUE;  /*** -Q implies -k !! ***/
-        break;
-    case 's':        /* Set the snapshot (capture) length */
-        capture_opts->has_snaplen = TRUE;
-        capture_opts->snaplen = get_positive_int(optarg, "snapshot length");
-        break;
-    case 'S':        /* "Sync" mode: used for following file ala tail -f */
-        capture_opts->sync_mode = TRUE;
-        break;
-    case 'w':        /* Write to capture file xxx */
-        capture_opts->save_file = g_strdup(optarg);
-           break;
-    case 'W':        /* Write to capture file FD xxx */
-        capture_opts->save_file_fd = atoi(optarg);
-        break;
-    case 'y':        /* Set the pcap data link type */
-#ifdef HAVE_PCAP_DATALINK_NAME_TO_VAL
-        capture_opts->linktype = pcap_datalink_name_to_val(optarg);
-        if (capture_opts->linktype == -1) {
-          fprintf(stderr, "ethereal: The specified data link type \"%s\" isn't valid\n",
-                  optarg);
-          exit(1);
-        }
-#else /* HAVE_PCAP_DATALINK_NAME_TO_VAL */
-        /* XXX - just treat it as a number */
-        capture_opts->linktype = get_natural_int(optarg, "data link type");
-#endif /* HAVE_PCAP_DATALINK_NAME_TO_VAL */
-        break;
-#ifdef _WIN32
-      /* Hidden option supporting Sync mode */
-    case 'Z':        /* Write to pipe FD XXX */
-        /* associate stdout with pipe */
-        i = atoi(optarg);
-        if (dup2(i, 1) < 0) {
-          fprintf(stderr, "Unable to dup pipe handle\n");
-          exit(1);
-        }
-        break;
-#endif /* _WIN32 */
-    default:
-        /* the caller is responsible to send us only the right opt's */
-        g_assert_not_reached();
-    }
-}
-
 /* open the output file (temporary/specified name/ringbuffer) and close the old one */
 /* Returns TRUE if the file opened successfully, FALSE otherwise. */
 static gboolean
diff --git a/capture_opts.c b/capture_opts.c
new file mode 100644 (file)
index 0000000..3935085
--- /dev/null
@@ -0,0 +1,318 @@
+/* capture_opts.c
+ * Routines for capture options setting
+ *
+ * $Id$
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@ethereal.com>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#ifdef HAVE_LIBPCAP
+
+#ifdef HAVE_IO_H
+# include <io.h>
+#endif
+
+#include <pcap.h>
+
+#include <glib.h>
+
+#include <epan/packet.h>
+
+#include "capture.h"
+#include "ringbuffer.h"
+
+
+void
+capture_opts_init(capture_options *capture_opts, void *cfile)
+{
+  capture_opts->cf                      = cfile;            
+  capture_opts->cfilter                            = g_strdup("");     /* No capture filter string specified */
+  capture_opts->iface                   = NULL;             /* Default is "pick the first interface" */
+#ifdef _WIN32
+  capture_opts->buffer_size             = 1;                /* 1 MB */
+#endif
+  capture_opts->has_snaplen             = FALSE;
+  capture_opts->snaplen                 = WTAP_MAX_PACKET_SIZE; /* snapshot length - default is
+                                                                    infinite, in effect */
+  capture_opts->promisc_mode            = TRUE;             /* promiscuous mode is the default */
+  capture_opts->linktype                = -1;               /* the default linktype */
+  capture_opts->capture_child           = FALSE;
+  capture_opts->save_file               = NULL;
+  capture_opts->save_file_fd            = -1;
+  capture_opts->sync_mode               = TRUE;
+  capture_opts->show_info               = TRUE;
+  capture_opts->quit_after_cap          = FALSE;
+
+  capture_opts->multi_files_on          = FALSE;
+  capture_opts->has_file_duration       = FALSE;
+  capture_opts->file_duration           = 60;               /* 1 min */
+  capture_opts->has_ring_num_files      = FALSE;
+  capture_opts->ring_num_files          = RINGBUFFER_MIN_NUM_FILES;
+
+  capture_opts->has_autostop_files      = FALSE;
+  capture_opts->autostop_files          = 1;
+  capture_opts->has_autostop_packets    = FALSE;            
+  capture_opts->autostop_packets        = 1;
+  capture_opts->has_autostop_filesize   = FALSE;
+  capture_opts->autostop_filesize       = 1024 * 1024;      /* 1 MB */
+  capture_opts->has_autostop_duration   = FALSE;
+  capture_opts->autostop_duration       = 60;               /* 1 min */
+
+}
+
+static int
+get_natural_int(const char *string, const char *name)
+{
+  long number;
+  char *p;
+
+  number = strtol(string, &p, 10);
+  if (p == string || *p != '\0') {
+    fprintf(stderr, "ethereal: The specified %s \"%s\" isn't a decimal number\n",
+           name, string);
+    exit(1);
+  }
+  if (number < 0) {
+    fprintf(stderr, "ethereal: The specified %s \"%s\" is a negative number\n",
+           name, string);
+    exit(1);
+  }
+  if (number > INT_MAX) {
+    fprintf(stderr, "ethereal: The specified %s \"%s\" is too large (greater than %d)\n",
+           name, string, INT_MAX);
+    exit(1);
+  }
+  return number;
+}
+
+
+static int
+get_positive_int(const char *string, const char *name)
+{
+  long number;
+
+  number = get_natural_int(string, name);
+
+  if (number == 0) {
+    fprintf(stderr, "ethereal: The specified %s is zero\n",
+           name);
+    exit(1);
+  }
+
+  return number;
+}
+
+
+/*
+ * Given a string of the form "<autostop criterion>:<value>", as might appear
+ * as an argument to a "-a" option, parse it and set the criterion in
+ * question.  Return an indication of whether it succeeded or failed
+ * in some fashion.
+ */
+static gboolean
+set_autostop_criterion(capture_options *capture_opts, const char *autostoparg)
+{
+  gchar *p, *colonp;
+
+  colonp = strchr(autostoparg, ':');
+  if (colonp == NULL)
+    return FALSE;
+
+  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
+   * allow it here).
+   */
+  while (isspace((guchar)*p))
+    p++;
+  if (*p == '\0') {
+    /*
+     * Put the colon back, so if our caller uses, in an
+     * error message, the string they passed us, the message
+     * looks correct.
+     */
+    *colonp = ':';
+    return FALSE;
+  }
+  if (strcmp(autostoparg,"duration") == 0) {
+    capture_opts->has_autostop_duration = TRUE;
+    capture_opts->autostop_duration = get_positive_int(p,"autostop duration");
+  } else if (strcmp(autostoparg,"filesize") == 0) {
+    capture_opts->has_autostop_filesize = TRUE;
+    capture_opts->autostop_filesize = get_positive_int(p,"autostop filesize");
+  } else if (strcmp(autostoparg,"files") == 0) {
+    capture_opts->multi_files_on = TRUE;
+    capture_opts->has_autostop_files = TRUE;
+    capture_opts->autostop_files = get_positive_int(p,"autostop files");
+  } else {
+    return FALSE;
+  }
+  *colonp = ':'; /* put the colon back */
+  return TRUE;
+}
+
+/*
+ * Given a string of the form "<ring buffer file>:<duration>", as might appear
+ * as an argument to a "-b" option, parse it and set the arguments in
+ * question.  Return an indication of whether it succeeded or failed
+ * in some fashion.
+ */
+static gboolean
+get_ring_arguments(capture_options *capture_opts, const char *arg)
+{
+  gchar *p = NULL, *colonp;
+
+  colonp = strchr(arg, ':');
+
+  if (colonp != NULL) {
+    p = colonp;
+    *p++ = '\0';
+  }
+
+  capture_opts->ring_num_files = 
+    get_natural_int(arg, "number of ring buffer files");
+
+  if (colonp == NULL)
+    return TRUE;
+
+  /*
+   * Skip over any white space (there probably won't be any, but
+   * as we allow it in the preferences file, we might as well
+   * allow it here).
+   */
+  while (isspace((guchar)*p))
+    p++;
+  if (*p == '\0') {
+    /*
+     * Put the colon back, so if our caller uses, in an
+     * error message, the string they passed us, the message
+     * looks correct.
+     */
+    *colonp = ':';
+    return FALSE;
+  }
+
+  capture_opts->has_file_duration = TRUE;
+  capture_opts->file_duration = get_positive_int(p,
+                                                     "ring buffer duration");
+
+  *colonp = ':';       /* put the colon back */
+  return TRUE;
+}
+
+
+void
+capture_opt_add(capture_options *capture_opts, int opt, const char *optarg, gboolean *start_capture)
+{
+#ifdef _WIN32
+    int i;
+#endif
+
+    switch(opt) {
+    case 'a':        /* autostop criteria */
+        if (set_autostop_criterion(capture_opts, optarg) == FALSE) {
+          fprintf(stderr, "ethereal: Invalid or unknown -a flag \"%s\"\n", optarg);
+          exit(1);
+        }
+        break;
+    case 'b':        /* Ringbuffer option */
+        capture_opts->multi_files_on = TRUE;
+        capture_opts->has_ring_num_files = TRUE;
+        if (get_ring_arguments(capture_opts, optarg) == FALSE) {
+          fprintf(stderr, "ethereal: Invalid or unknown -b arg \"%s\"\n", optarg);
+          exit(1);
+        }
+        break;
+    case 'c':        /* Capture xxx packets */
+        capture_opts->has_autostop_packets = TRUE;
+        capture_opts->autostop_packets = get_positive_int(optarg, "packet count");
+        break;
+    case 'f':        /* capture filter */
+        if (capture_opts->cfilter)
+            g_free(capture_opts->cfilter);
+        capture_opts->cfilter = g_strdup(optarg);
+        break;
+    case 'H':        /* Hide capture info dialog box */
+        capture_opts->show_info = FALSE;
+        break;
+    case 'i':        /* Use interface xxx */
+        capture_opts->iface = g_strdup(optarg);
+        break;
+    case 'k':        /* Start capture immediately */
+        *start_capture = TRUE;
+        break;
+    /*case 'l':*/    /* Automatic scrolling in live capture mode */
+    case 'p':        /* Don't capture in promiscuous mode */
+        capture_opts->promisc_mode = FALSE;
+        break;
+    case 'Q':        /* Quit after capture (just capture to file) */
+        capture_opts->quit_after_cap  = TRUE;
+        *start_capture   = TRUE;  /*** -Q implies -k !! ***/
+        break;
+    case 's':        /* Set the snapshot (capture) length */
+        capture_opts->has_snaplen = TRUE;
+        capture_opts->snaplen = get_positive_int(optarg, "snapshot length");
+        break;
+    case 'S':        /* "Sync" mode: used for following file ala tail -f */
+        capture_opts->sync_mode = TRUE;
+        break;
+    case 'w':        /* Write to capture file xxx */
+        capture_opts->save_file = g_strdup(optarg);
+           break;
+    case 'W':        /* Write to capture file FD xxx */
+        capture_opts->save_file_fd = atoi(optarg);
+        break;
+    case 'y':        /* Set the pcap data link type */
+#ifdef HAVE_PCAP_DATALINK_NAME_TO_VAL
+        capture_opts->linktype = pcap_datalink_name_to_val(optarg);
+        if (capture_opts->linktype == -1) {
+          fprintf(stderr, "ethereal: The specified data link type \"%s\" isn't valid\n",
+                  optarg);
+          exit(1);
+        }
+#else /* HAVE_PCAP_DATALINK_NAME_TO_VAL */
+        /* XXX - just treat it as a number */
+        capture_opts->linktype = get_natural_int(optarg, "data link type");
+#endif /* HAVE_PCAP_DATALINK_NAME_TO_VAL */
+        break;
+#ifdef _WIN32
+      /* Hidden option supporting Sync mode */
+    case 'Z':        /* Write to pipe FD XXX */
+        /* associate stdout with pipe */
+        i = atoi(optarg);
+        if (dup2(i, 1) < 0) {
+          fprintf(stderr, "Unable to dup pipe handle\n");
+          exit(1);
+        }
+        break;
+#endif /* _WIN32 */
+    default:
+        /* the caller is responsible to send us only the right opt's */
+        g_assert_not_reached();
+    }
+}
+
+#endif /* HAVE_LIBPCAP */
\ No newline at end of file
index 704c8327d2066f0ddc7f4b464d26cc8cb0f18471..abb88f89a10db561a88038a25f08c26453741648 100644 (file)
@@ -1620,6 +1620,9 @@ main(int argc, char *argv[])
      by preference settings and then again by the command line parameters. */
   capture_opts_init(capture_opts, &cfile);
 
+  capture_opts->snaplen             = MIN_PACKET_SIZE;
+  capture_opts->has_ring_num_files  = TRUE;
+
   command_name = get_basename(ethereal_path);
   /* Set "capture_child" to indicate whether this is going to be a child
      process for a "-S" capture. */
index 83f0b7046cef83f069eeae15e2ddb7d0482820f0..bdee92e93ce0abff789188393c6464153143449a 100644 (file)
 #ifdef HAVE_LIBPCAP
 #include <wiretap/wtap-capture.h>
 #include <wiretap/libpcap.h>
-#endif
-
 #ifdef _WIN32
 #include "capture-wpcap.h"
 #endif
+#include "capture.h"
+#endif
+
 
 /*
  * This is the template for the decode as option; it is shared between the
@@ -168,22 +169,23 @@ typedef struct _loop_data {
 static loop_data ld;
 
 #ifdef HAVE_LIBPCAP
+#if 0
 typedef struct {
     gchar    *cfilter;              /* Capture filter string */
     gchar    *iface;                /* the network interface to capture from */
     int      snaplen;               /* Maximum captured packet length */
     int      promisc_mode;          /* Capture in promiscuous mode */
-    int      autostop_count;        /* Maximum packet count */
+    int      autostop_packets;        /* Maximum packet count */
     gboolean has_autostop_duration; /* TRUE if maximum capture duration
                                        is specified */
     gint32   autostop_duration;     /* Maximum capture duration */
     gboolean has_autostop_filesize; /* TRUE if maximum capture file size
                                        is specified */
     gint32   autostop_filesize;     /* Maximum capture file size */
-    gboolean ringbuffer_on;         /* TRUE if ring buffer in use */
-    guint32  ringbuffer_num_files;  /* Number of ring buffer files */
-    gboolean has_ring_duration;     /* TRUE if ring duration specified */
-    gint32   ringbuffer_duration;   /* Switch file after n seconds */
+    gboolean multi_files_on;        /* TRUE if ring buffer in use */
+    guint32  ring_num_files;        /* Number of ring buffer files */
+    gboolean has_file_duration;     /* TRUE if ring duration specified */
+    gint32   file_duration;         /* Switch file after n seconds */
     int      linktype;              /* Data link type to use, or -1 for
                                        "use default" */
 } capture_options;
@@ -208,6 +210,8 @@ static capture_options capture_opts = {
     0,                              /* specified time is off by default */
     -1                              /* Default to not change link type */
 };
+#endif /* 0 */
+static capture_options capture_opts;
 
 static gboolean list_link_layer_types;
 
@@ -306,145 +310,6 @@ print_usage(gboolean print_ver)
   fprintf(output, "\tdefault is libpcap\n");
 }
 
-#ifdef HAVE_LIBPCAP
-static int
-get_natural_int(const char *string, const char *name)
-{
-  long number;
-  char *p;
-
-  number = strtol(string, &p, 10);
-  if (p == string || *p != '\0') {
-    fprintf(stderr, "tethereal: The specified %s \"%s\" isn't a decimal number\n",
-           name, string);
-    exit(1);
-  }
-  if (number < 0) {
-    fprintf(stderr, "tethereal: The specified %s is a negative number\n",
-           name);
-    exit(1);
-  }
-  if (number > INT_MAX) {
-    fprintf(stderr, "tethereal: The specified %s is too large (greater than %d)\n",
-           name, INT_MAX);
-    exit(1);
-  }
-  return number;
-}
-
-static int
-get_positive_int(const char *string, const char *name)
-{
-  long number;
-
-  number = get_natural_int(string, name);
-
-  if (number == 0) {
-    fprintf(stderr, "tethereal: The specified %s is zero\n",
-           name);
-    exit(1);
-  }
-
-  return number;
-}
-
-/*
- * Given a string of the form "<autostop criterion>:<value>", as might appear
- * as an argument to a "-a" option, parse it and set the criterion in
- * question.  Return an indication of whether it succeeded or failed
- * in some fashion.
- */
-static gboolean
-set_autostop_criterion(const char *autostoparg)
-{
-  guchar *p, *colonp;
-
-  colonp = strchr(autostoparg, ':');
-  if (colonp == NULL)
-    return FALSE;
-
-  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
-   * allow it here).
-   */
-  while (isspace(*p))
-    p++;
-  if (*p == '\0') {
-    /*
-     * Put the colon back, so if our caller uses, in an
-     * error message, the string they passed us, the message
-     * looks correct.
-     */
-    *colonp = ':';
-    return FALSE;
-  }
-  if (strcmp(autostoparg,"duration") == 0) {
-    capture_opts.has_autostop_duration = TRUE;
-    capture_opts.autostop_duration = get_positive_int(p,"autostop duration");
-  } else if (strcmp(autostoparg,"filesize") == 0) {
-    capture_opts.has_autostop_filesize = TRUE;
-    capture_opts.autostop_filesize = get_positive_int(p,"autostop filesize");
-  } else {
-    return FALSE;
-  }
-  *colonp = ':';       /* put the colon back */
-  return TRUE;
-}
-
-/*
- * Given a string of the form "<ring buffer file>:<duration>", as might appear
- * as an argument to a "-b" option, parse it and set the arguments in
- * question.  Return an indication of whether it succeeded or failed
- * in some fashion.
- */
-static gboolean
-get_ring_arguments(const char *arg)
-{
-  guchar *p = NULL, *colonp;
-
-  colonp = strchr(arg, ':');
-
-  if (colonp != NULL) {
-    p = colonp;
-    *p++ = '\0';
-  }
-
-  capture_opts.ringbuffer_num_files = 
-    get_natural_int(arg, "number of ring buffer files");
-
-  if (colonp == NULL)
-    return TRUE;
-
-  /*
-   * Skip over any white space (there probably won't be any, but
-   * as we allow it in the preferences file, we might as well
-   * allow it here).
-   */
-  while (isspace(*p))
-    p++;
-  if (*p == '\0') {
-    /*
-     * Put the colon back, so if our caller uses, in an
-     * error message, the string they passed us, the message
-     * looks correct.
-     */
-    *colonp = ':';
-    return FALSE;
-  }
-
-  capture_opts.has_ring_duration = TRUE;
-  capture_opts.ringbuffer_duration = get_positive_int(p,
-                                                     "ring buffer duration");
-
-  *colonp = ':';       /* put the colon back */
-  return TRUE;
-}
-#endif
-
 /* structure to keep track of what tap listeners have been registered.
  */
 typedef struct _ethereal_tap_list {
@@ -847,6 +712,7 @@ main(int argc, char *argv[])
   int                  out_file_type = WTAP_FILE_PCAP;
   gchar               *cf_name = NULL, *rfilter = NULL;
 #ifdef HAVE_LIBPCAP
+  gboolean             start_capture = FALSE;
   gchar               *if_text;
   GList               *lt_list, *lt_entry;
   data_link_info_t    *data_link_info;
@@ -861,8 +727,7 @@ main(int argc, char *argv[])
   gboolean got_tap = FALSE;
   
 #ifdef HAVE_LIBPCAP
-  /* XXX - better use capture_opts_init instead */
-  capture_opts.cfilter = g_strdup("");
+  capture_opts_init(&capture_opts, NULL /* cfile */);
 #endif
 
   set_timestamp_setting(TS_RELATIVE);
@@ -974,32 +839,14 @@ main(int argc, char *argv[])
   while ((opt = getopt(argc, argv, "a:b:c:d:Df:F:hi:lLnN:o:pqr:R:s:St:T:vw:Vxy:z:")) != -1) {
     switch (opt) {
       case 'a':        /* autostop criteria */
-#ifdef HAVE_LIBPCAP
-        if (set_autostop_criterion(optarg) == FALSE) {
-          fprintf(stderr, "tethereal: Invalid or unknown -a flag \"%s\"\n", optarg);
-          exit(1);
-        }
-#else
-        capture_option_specified = TRUE;
-        arg_error = TRUE;
-#endif
-        break;
       case 'b':        /* Ringbuffer option */
-#ifdef HAVE_LIBPCAP
-        capture_opts.ringbuffer_on = TRUE;
-       if (get_ring_arguments(optarg) == FALSE) {
-          fprintf(stderr, "tethereal: Invalid or unknown -b arg \"%s\"\n", optarg);
-          exit(1);
-       }
-#else
-        capture_option_specified = TRUE;
-        arg_error = TRUE;
-#endif
-        break;
       case 'c':        /* Capture xxx packets */
+      case 'f':        /* capture filter */
+      case 'p':        /* Don't capture in promiscuous mode */
+      case 's':        /* Set the snapshot (capture) length */
+      case 'y':        /* Set the pcap data link type */
 #ifdef HAVE_LIBPCAP
-        capture_opts.autostop_count =
-            get_positive_int(optarg, "packet count");
+        capture_opt_add(&capture_opts, opt, optarg, &start_capture);
 #else
         capture_option_specified = TRUE;
         arg_error = TRUE;
@@ -1044,17 +891,6 @@ main(int argc, char *argv[])
         arg_error = TRUE;
 #endif
         break;
-      case 'f':
-#ifdef HAVE_LIBPCAP
-        capture_filter_specified = TRUE;
-       if (capture_opts.cfilter)
-               g_free(capture_opts.cfilter);
-       capture_opts.cfilter = g_strdup(optarg);
-#else
-        capture_option_specified = TRUE;
-        arg_error = TRUE;
-#endif
-       break;
       case 'F':
         out_file_type = wtap_short_string_to_file_type(optarg);
         if (out_file_type < 0) {
@@ -1178,14 +1014,6 @@ main(int argc, char *argv[])
           break;
         }
         break;
-      case 'p':        /* Don't capture in promiscuous mode */
-#ifdef HAVE_LIBPCAP
-       capture_opts.promisc_mode = FALSE;
-#else
-        capture_option_specified = TRUE;
-        arg_error = TRUE;
-#endif
-       break;
       case 'q':        /* Quiet */
         quiet = TRUE;
         break;
@@ -1195,14 +1023,6 @@ main(int argc, char *argv[])
       case 'R':        /* Read file filter */
         rfilter = optarg;
         break;
-      case 's':        /* Set the snapshot (capture) length */
-#ifdef HAVE_LIBPCAP
-        capture_opts.snaplen = get_positive_int(optarg, "snapshot length");
-#else
-        capture_option_specified = TRUE;
-        arg_error = TRUE;
-#endif
-        break;
       case 'S':        /* show packets in real time */
         print_packet_info = TRUE;
         break;
@@ -1260,24 +1080,6 @@ main(int argc, char *argv[])
       case 'x':        /* Print packet data in hex (and ASCII) */
         print_hex = TRUE;
         break;
-      case 'y':        /* Set the pcap data link type */
-#ifdef HAVE_LIBPCAP
-#ifdef HAVE_PCAP_DATALINK_NAME_TO_VAL
-        capture_opts.linktype = pcap_datalink_name_to_val(optarg);
-        if (capture_opts.linktype == -1) {
-          fprintf(stderr, "tethereal: The specified data link type \"%s\" isn't valid\n",
-                  optarg);
-          exit(1);
-        }
-#else /* HAVE_PCAP_DATALINK_NAME_TO_VAL */
-        /* XXX - just treat it as a number */
-        capture_opts.linktype = get_natural_int(optarg, "data link type");
-#endif /* HAVE_PCAP_DATALINK_NAME_TO_VAL */
-#else
-        capture_option_specified = TRUE;
-        arg_error = TRUE;
-#endif
-        break;
       case 'z':
         for(tli=tap_list;tli;tli=tli->next){
           if(!strncmp(tli->cmd,optarg,strlen(tli->cmd))){
@@ -1417,7 +1219,7 @@ main(int argc, char *argv[])
       exit(1);
     }
     /* No - did they specify a ring buffer option? */
-    if (capture_opts.ringbuffer_on) {
+    if (capture_opts.multi_files_on) {
       fprintf(stderr, "tethereal: Ring buffer requested, but a capture isn't being done.\n");
       exit(1);
     }
@@ -1430,7 +1232,7 @@ main(int argc, char *argv[])
       exit(1);
     }
 
-    if (capture_opts.ringbuffer_on) {
+    if (capture_opts.multi_files_on) {
       /* Ring buffer works only under certain conditions:
         a) ring buffer does not work if you're not saving the capture to
            a file;
@@ -1520,12 +1322,12 @@ main(int argc, char *argv[])
   else if (capture_opts.snaplen < MIN_PACKET_SIZE)
     capture_opts.snaplen = MIN_PACKET_SIZE;
 
-  /* Check the value range of the ringbuffer_num_files parameter */
-  if (capture_opts.ringbuffer_num_files > RINGBUFFER_MAX_NUM_FILES)
-    capture_opts.ringbuffer_num_files = RINGBUFFER_MAX_NUM_FILES;
+  /* Check the value range of the ring_num_files parameter */
+  if (capture_opts.ring_num_files > RINGBUFFER_MAX_NUM_FILES)
+    capture_opts.ring_num_files = RINGBUFFER_MAX_NUM_FILES;
 #if RINGBUFFER_MIN_NUM_FILES > 0
-  else if (capture_opts.ringbuffer_num_files < RINGBUFFER_MIN_NUM_FILES)
-    capture_opts.ringbuffer_num_files = RINGBUFFER_MIN_NUM_FILES;
+  else if (capture_opts.ring_num_files < RINGBUFFER_MIN_NUM_FILES)
+    capture_opts.ring_num_files = RINGBUFFER_MIN_NUM_FILES;
 #endif
 #endif
 
@@ -1694,7 +1496,7 @@ main(int argc, char *argv[])
 
     capture(save_file, out_file_type);
 
-    if (capture_opts.ringbuffer_on) {
+    if (capture_opts.multi_files_on) {
       ringbuf_free();
     }
 #else
@@ -1909,9 +1711,9 @@ capture(char *save_file, int out_file_type)
       goto error;
     }
     ld.save_file = save_file;
-    if (capture_opts.ringbuffer_on) {
+    if (capture_opts.multi_files_on) {
       save_file_fd = ringbuf_init(save_file,
-        capture_opts.ringbuffer_num_files);
+        capture_opts.ring_num_files);
       if (save_file_fd != -1) {
         ld.pdh = ringbuf_init_wtap_dump_fdopen(out_file_type, ld.linktype,
           file_snaplen, &err);
@@ -1972,9 +1774,9 @@ capture(char *save_file, int out_file_type)
     cnd_stop_timeout = cnd_new((const char*)CND_CLASS_TIMEOUT,
                                (gint32)capture_opts.autostop_duration);
 
-  if (capture_opts.ringbuffer_on && capture_opts.has_ring_duration)
+  if (capture_opts.multi_files_on && capture_opts.has_file_duration)
     cnd_ring_timeout = cnd_new(CND_CLASS_TIMEOUT, 
-                              capture_opts.ringbuffer_duration);
+                              capture_opts.file_duration);
 
   if (!setjmp(ld.stopenv)) {
     ld.go = TRUE;
@@ -2025,15 +1827,15 @@ capture(char *save_file, int out_file_type)
          reading the FIFO sees the packets immediately and doesn't get
          any partial packet, forcing it to block in the middle of reading
          that packet. */
-      if (capture_opts.autostop_count == 0)
+      if (capture_opts.autostop_packets == 0)
         pcap_cnt = -1;
       else {
-        if (ld.packet_count >= capture_opts.autostop_count) {
+        if (ld.packet_count >= capture_opts.autostop_packets) {
           /* XXX do we need this test here? */
           /* It appears there's nothing more to capture. */
           break;
         }
-        pcap_cnt = capture_opts.autostop_count - ld.packet_count;
+        pcap_cnt = capture_opts.autostop_packets - ld.packet_count;
       }
     } else {
       /* We need to check the capture file size or the timeout after
@@ -2055,8 +1857,8 @@ capture(char *save_file, int out_file_type)
       /* The specified capture time has elapsed; stop the capture. */
       ld.go = FALSE;
     } else if (inpkts > 0) {
-      if (capture_opts.autostop_count != 0 &&
-                 ld.packet_count >= capture_opts.autostop_count) {
+      if (capture_opts.autostop_packets != 0 &&
+                 ld.packet_count >= capture_opts.autostop_packets) {
         /* The specified number of packets have been captured and have
            passed both any capture filter in effect and any read filter
            in effect. */
@@ -2066,7 +1868,7 @@ capture(char *save_file, int out_file_type)
                               (guint32)wtap_get_bytes_dumped(ld.pdh))) {
         /* We're saving the capture to a file, and the capture file reached
            its maximum size. */
-        if (capture_opts.ringbuffer_on) {
+        if (capture_opts.multi_files_on) {
           /* Switch to the next ringbuffer file */
           if (ringbuf_switch_file(&ld.pdh, &save_file, &save_file_fd, &loop_err)) {
             /* File switch succeeded: reset the condition */
@@ -2135,7 +1937,7 @@ capture(char *save_file, int out_file_type)
 
   if (save_file != NULL) {
     /* We're saving to a file or files; close all files. */
-    if (capture_opts.ringbuffer_on) {
+    if (capture_opts.multi_files_on) {
       dump_ok = ringbuf_wtap_dump_close(&save_file, &err);
     } else {
       dump_ok = wtap_dump_close(ld.pdh, &err);
@@ -2172,7 +1974,7 @@ capture(char *save_file, int out_file_type)
   return TRUE;
 
 error:
-  if (capture_opts.ringbuffer_on) {
+  if (capture_opts.multi_files_on) {
     ringbuf_error_cleanup();
   }
   g_free(save_file);