added compression support for capture file output. The Save/As dialog now has a check...
authorulfl <ulfl@f5534014-38df-0310-8fa8-9805f1628bb7>
Wed, 14 Sep 2005 21:57:30 +0000 (21:57 +0000)
committerulfl <ulfl@f5534014-38df-0310-8fa8-9805f1628bb7>
Wed, 14 Sep 2005 21:57:30 +0000 (21:57 +0000)
currently limited to Ethereal and all the variants of libpcap filetypes only.

We might want to add output compression support to the other tools as well (tethereal, mergecap, ...).

We might also want to add support for the other filetypes, but this is only possible if the filetype functions doesn't use special output operations like fseek.

One bug is still left: if the input and output filetypes while saving are the same, Ethereal currently optimizes this by simply copy the binary file instead of using wiretap (so it will be faster but it will ignore the compress setting).

Don't know a good workaround for this, as I don't know a way to find out if the input file is currently compressed or not. One idea might be to use a heuristic on the filesize (compared to the packet size summmary). Another workaround I see is to remove this optimization, which is of course not the way I like to do it ...

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

14 files changed:
capture_loop.c
editcap.c
file.c
file.h
gtk/file_dlg.c
mergecap.c
randpkt.c
ringbuffer.c
tethereal.c
wiretap/file_access.c
wiretap/libpcap.c
wiretap/wtap-int.h
wiretap/wtap.def
wiretap/wtap.h

index 8421e73a322162c4efe0e5776d735c1d65a6fa60..8ed04636a67e7880435b4e0207b3a5f43ea4400d 100644 (file)
@@ -832,7 +832,7 @@ static int capture_loop_init_wiretap_output(capture_options *capture_opts, int s
       file_snaplen, &err);
   } else {
     ld->wtap_pdh = wtap_dump_fdopen(save_file_fd, WTAP_FILE_PCAP,
-      ld->wtap_linktype, file_snaplen, &err);
+      ld->wtap_linktype, file_snaplen, FALSE /* compressed */, &err);
   }
 
   if (ld->wtap_pdh == NULL) {
@@ -1242,7 +1242,7 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
      message to our parent so that they'll open the capture file and
      update its windows to indicate that we have a live capture in
      progress. */
-  fflush(wtap_dump_file(ld.wtap_pdh));
+  wtap_dump_flush(ld.wtap_pdh);
   sync_pipe_filename_to_parent(capture_opts->save_file);
 
   /* initialize capture stop (and alike) conditions */
@@ -1328,7 +1328,7 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
             if (cnd_file_duration) {
               cnd_reset(cnd_file_duration);
             }
-            fflush(wtap_dump_file(ld.wtap_pdh));
+            wtap_dump_flush(ld.wtap_pdh);
             sync_pipe_filename_to_parent(capture_opts->save_file);
           } else {
             /* File switch failed: stop here */
@@ -1371,7 +1371,7 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
       /* Let the parent process know. */
       if (ld.packets_sync_pipe) {
         /* do sync here */
-        fflush(wtap_dump_file(ld.wtap_pdh));
+        wtap_dump_flush(ld.wtap_pdh);
 
          /* Send our parent a message saying we've written out "ld.sync_packets"
             packets to the capture file. */
@@ -1403,7 +1403,7 @@ 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);
-            fflush(wtap_dump_file(ld.wtap_pdh));
+            wtap_dump_flush(ld.wtap_pdh);
             sync_pipe_filename_to_parent(capture_opts->save_file);
           } else {
             /* File switch failed: stop here */
index 09269507e53b086716232ed749f23059285450a7..50592854a456840c3701bd658113f87218ca9220 100644 (file)
--- a/editcap.c
+++ b/editcap.c
@@ -373,7 +373,7 @@ int main(int argc, char *argv[])
       out_frame_type = wtap_file_encap(wth);
 
     pdh = wtap_dump_open(argv[optind + 1], out_file_type,
-                        out_frame_type, wtap_snapshot_length(wth), &err);
+                        out_frame_type, wtap_snapshot_length(wth), FALSE /* compressed */, &err);
     if (pdh == NULL) {
 
       fprintf(stderr, "editcap: Can't open or create %s: %s\n", argv[optind+1],
diff --git a/file.c b/file.c
index 53b7e6055f0047e7025379dedc44c71ee78253a2..9b4f9977e6ea1b1db3dfeb9e1965db2579d5eb72 100644 (file)
--- a/file.c
+++ b/file.c
@@ -983,7 +983,8 @@ cf_merge_files(char **out_filenamep, int in_file_count,
 
   pdh = wtap_dump_fdopen(out_fd, file_type,
       merge_select_frame_type(in_file_count, in_files),
-      merge_max_snapshot_length(in_file_count, in_files), &open_err);
+      merge_max_snapshot_length(in_file_count, in_files), 
+         FALSE /* compressed */, &open_err);
   if (pdh == NULL) {
     close(out_fd);
     merge_close_in_files(in_file_count, in_files);
@@ -3081,7 +3082,7 @@ save_packet(capture_file *cf _U_, frame_data *fdata,
 }
 
 cf_status_t
-cf_save(capture_file *cf, const char *fname, packet_range_t *range, guint save_format)
+cf_save(capture_file *cf, const char *fname, packet_range_t *range, guint save_format, gboolean compressed)
 {
   gchar        *from_filename;
   int           err;
@@ -3160,7 +3161,8 @@ cf_save(capture_file *cf, const char *fname, packet_range_t *range, guint save_f
     /* Either we're filtering packets, or we're saving in a different
        format; we can't do that by copying or moving the capture file,
        we have to do it by writing the packets out in Wiretap. */
-    pdh = wtap_dump_open(fname, save_format, cf->lnk_t, cf->snap, &err);
+    pdh = wtap_dump_open(fname, save_format, cf->lnk_t, cf->snap, 
+               compressed, &err);
     if (pdh == NULL) {
       cf_open_failure_alert_box(fname, err, NULL, TRUE, save_format);
       goto fail;
@@ -3359,6 +3361,11 @@ cf_open_failure_alert_box(const char *filename, int err, gchar *err_info,
                    filename);
       break;
 
+    case WTAP_ERR_COMPRESSION_NOT_SUPPORTED:
+      simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+                   "Gzip compression not supported by this file type.");
+      break;
+
     default:
       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
                    "The file \"%s\" could not be %s: %s.",
diff --git a/file.h b/file.h
index fd7ff333011f33672f8310c684730e1960991552..3eadec354d2e6e92b18e3e835e490ce0f0b9f548 100644 (file)
--- a/file.h
+++ b/file.h
@@ -157,9 +157,10 @@ cf_read_status_t cf_finish_tail(capture_file *cf, int *err);
  * @param fname the filename to save to
  * @param range the range of packets to save
  * @param save_format the format of the file to save (libpcap, ...)
+ * @param compressed wether to gzip compress the file
  * @return one of cf_status_t
  */
-cf_status_t cf_save(capture_file * cf, const char *fname, packet_range_t *range, guint save_format);
+cf_status_t cf_save(capture_file * cf, const char *fname, packet_range_t *range, guint save_format, gboolean compressed);
 
 /**
  * Get a displayable name of the capture file.
index 7288dc8396bdbd4cd15b810dff1bd31ab1d74008..100b5bf193e0affc65f1d49ba4d9e6bb73d6f77d 100644 (file)
@@ -1217,6 +1217,7 @@ static void
 select_file_type_cb(GtkWidget *w _U_, gpointer data)
 {
   int new_filetype = GPOINTER_TO_INT(data);
+  GtkWidget *compressed_cb;
 
   if (filetype != new_filetype) {
     /* We can select only the filtered or marked packets to be saved if we can
@@ -1225,6 +1226,8 @@ select_file_type_cb(GtkWidget *w _U_, gpointer data)
        range_set_displayed_sensitive(range_tb, can_save_with_wiretap(new_filetype));
     filetype = new_filetype;
     file_set_save_marked_sensitive();
+       compressed_cb = OBJECT_GET_DATA(file_save_as_w, "compressed");
+       gtk_widget_set_sensitive(compressed_cb, wtap_dump_can_compress(new_filetype));
   }
 }
 
@@ -1267,7 +1270,7 @@ gpointer            action_after_save_data_g;
 void
 file_save_as_cmd(action_after_save_e action_after_save, gpointer action_after_save_data)
 {
-  GtkWidget     *main_vb, *ft_hb, *ft_lb, *range_fr;
+  GtkWidget     *main_vb, *ft_hb, *ft_lb, *range_fr, *compressed_cb;
   GtkTooltips   *tooltips;
 
 #if GTK_MAJOR_VERSION < 2
@@ -1352,6 +1355,13 @@ file_save_as_cmd(action_after_save_e action_after_save, gpointer action_after_sa
   /* dynamic values in the range frame */
   range_update_dynamics(range_tb);
 
+  /* compressed */
+  compressed_cb = gtk_check_button_new_with_label("Compress with gzip");
+  gtk_container_add(GTK_CONTAINER(ft_hb), compressed_cb);
+  gtk_widget_show(compressed_cb);
+  OBJECT_SET_DATA(file_save_as_w, "compressed", compressed_cb);
+  gtk_widget_set_sensitive(compressed_cb, wtap_dump_can_compress(cfile.cd_t));
+
   SIGNAL_CONNECT(file_save_as_w, "destroy", file_save_as_destroy_cb, NULL);
 
 #if (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 4) || GTK_MAJOR_VERSION > 2
@@ -1389,6 +1399,7 @@ static void
 file_save_as_cb(GtkWidget *w _U_, gpointer fs) {
   gchar        *cf_name;
   gchar        *dirname;
+  GtkWidget *compressed_cb;
 
 
 #if (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 4) || GTK_MAJOR_VERSION > 2
@@ -1397,9 +1408,12 @@ file_save_as_cb(GtkWidget *w _U_, gpointer fs) {
   cf_name = g_strdup(gtk_file_selection_get_filename(GTK_FILE_SELECTION(fs)));
 #endif
 
+  compressed_cb = OBJECT_GET_DATA(file_save_as_w, "compressed");
+
   /* Write out the packets (all, or only the ones from the current
      range) to the file with the specified name. */
-  if (cf_save(&cfile, cf_name, &range, filetype) != CF_OK) {
+  if (cf_save(&cfile, cf_name, &range, filetype, 
+         gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(compressed_cb))) != CF_OK) {
     /* The write failed; don't dismiss the open dialog box,
        just leave it around so that the user can, after they
        dismiss the alert box popped up for the error, try again. */
index 83777a7ebe0b8a7e06a43dea87c504526003edb5..9136e64930b6a249810709ba2a08e8f283b336cb 100644 (file)
@@ -301,7 +301,7 @@ main(int argc, char *argv[])
   }  
     
   /* prepare the outfile */
-  pdh = wtap_dump_fdopen(out_fd, file_type, frame_type, snaplen, &open_err);
+  pdh = wtap_dump_fdopen(out_fd, file_type, frame_type, snaplen, FALSE /* compressed */, &open_err);
   if (pdh == NULL) {
     merge_close_in_files(in_file_count, in_files);
     free(in_files);
index 65873fa0e0d0879160780524534dc7da97a18140..965189b06b5d1e902a66575af350e304767a32e5 100644 (file)
--- a/randpkt.c
+++ b/randpkt.c
@@ -482,7 +482,7 @@ main(int argc, char **argv)
        pkthdr.pkt_encap = example->sample_wtap_encap;
 
        dump = wtap_dump_open(produce_filename, WTAP_FILE_PCAP,
-               example->sample_wtap_encap, produce_max_bytes, &err);
+               example->sample_wtap_encap, produce_max_bytes, FALSE /* compressed */, &err);
 
        seed();
 
index 84d2983d57d03b94f6a72347ffc62b3b316debc5..4f1d5fe0da2c40c2f15b84f450fc5d7cac11326f 100644 (file)
@@ -241,7 +241,7 @@ ringbuf_init_wtap_dump_fdopen(int filetype, int linktype, int snaplen, int *err)
   rb_data.linktype = linktype;
   rb_data.snaplen  = snaplen;
 
-  rb_data.pdh = wtap_dump_fdopen(rb_data.fd, filetype, linktype, snaplen, err);
+  rb_data.pdh = wtap_dump_fdopen(rb_data.fd, filetype, linktype, snaplen, FALSE /* compressed */, err);
 
   return rb_data.pdh;
 }
index 3fe497414086bfe44c882508fba0d503e02fc588..7b60c68157566b02c46369eeeaccacb20642c591 100644 (file)
@@ -1681,7 +1681,7 @@ capture(char *save_file, int out_file_type)
       }
     } else {
       ld.pdh = wtap_dump_open(save_file, out_file_type,
-                ld.linktype, file_snaplen, &err);
+                ld.linktype, file_snaplen, FALSE /* compress */, &err);
     }
 
     if (ld.pdh == NULL) {
@@ -1846,7 +1846,7 @@ capture(char *save_file, int out_file_type)
       }
       if (ld.output_to_pipe) {
         if (ld.packet_count > packet_count_prev) {
-          if (fflush(wtap_dump_file(ld.pdh))) {
+          if (wtap_dump_file_flush(ld.pdh)) {
             volatile_err = errno;
             ld.go = FALSE;
           }
@@ -2121,7 +2121,7 @@ load_cap_file(capture_file *cf, char *save_file, int out_file_type)
       snapshot_length = WTAP_MAX_PACKET_SIZE;
     }
     pdh = wtap_dump_open(save_file, out_file_type,
-               linktype, snapshot_length, &err);
+               linktype, snapshot_length, FALSE /* compressed */, &err);
 
     if (pdh == NULL) {
       /* We couldn't set up to write to the capture file. */
index 84705e29fd3f957bda6ac843b7a0cd91baee596e..08b4d72384c5b09ed8423ef7d075f0c8348c0ffe 100644 (file)
@@ -338,175 +338,176 @@ success:
 static const struct file_type_info {
        const char *name;
        const char *short_name;
+       gboolean        can_compress;
        int     (*can_write_encap)(int);
        int     (*dump_open)(wtap_dumper *, gboolean, int *);
 } dump_open_table[WTAP_NUM_FILE_TYPES] = {
        /* WTAP_FILE_UNKNOWN */
-       { NULL, NULL,
+       { NULL, NULL, FALSE,
          NULL, NULL },
 
        /* WTAP_FILE_WTAP */
-       { "Wiretap (Ethereal)", NULL,
+       { "Wiretap (Ethereal)", NULL, FALSE,
          NULL, NULL },
 
        /* WTAP_FILE_PCAP */
-       { "libpcap (tcpdump, Ethereal, etc.)", "libpcap",
+       { "libpcap (tcpdump, Ethereal, etc.)", "libpcap", TRUE,
          libpcap_dump_can_write_encap, libpcap_dump_open },
 
        /* WTAP_FILE_PCAP_SS990417 */
-       { "RedHat Linux 6.1 libpcap (tcpdump)", "rh6_1libpcap",
+       { "RedHat Linux 6.1 libpcap (tcpdump)", "rh6_1libpcap", TRUE,
          libpcap_dump_can_write_encap, libpcap_dump_open },
 
        /* WTAP_FILE_PCAP_SS990915 */
-       { "SuSE Linux 6.3 libpcap (tcpdump)", "suse6_3libpcap",
+       { "SuSE Linux 6.3 libpcap (tcpdump)", "suse6_3libpcap", TRUE,
          libpcap_dump_can_write_encap, libpcap_dump_open },
 
        /* WTAP_FILE_PCAP_SS991029 */
-       { "modified libpcap (tcpdump)", "modlibpcap",
+       { "modified libpcap (tcpdump)", "modlibpcap", TRUE,
          libpcap_dump_can_write_encap, libpcap_dump_open },
 
        /* WTAP_FILE_PCAP_NOKIA */
-       { "Nokia libpcap (tcpdump)", "nokialibpcap",
+       { "Nokia libpcap (tcpdump)", "nokialibpcap", TRUE,
          libpcap_dump_can_write_encap, libpcap_dump_open },
 
        /* WTAP_FILE_PCAP_AIX */
-       { "AIX libpcap (tcpdump)", NULL,
+       { "AIX libpcap (tcpdump)", NULL, TRUE,
          NULL, NULL },
 
        /* WTAP_FILE_PCAP_NSEC */
-       { "Nanosecond libpcap (Ethereal)", "nseclibpcap",
+       { "Nanosecond libpcap (Ethereal)", "nseclibpcap", TRUE,
          libpcap_dump_can_write_encap, libpcap_dump_open },
 
        /* WTAP_FILE_LANALYZER */
-       { "Novell LANalyzer","lanalyzer",
+       { "Novell LANalyzer","lanalyzer", FALSE,
          lanalyzer_dump_can_write_encap, lanalyzer_dump_open },
 
        /* WTAP_FILE_NGSNIFFER_UNCOMPRESSED */
-       { "Network Associates Sniffer (DOS-based)", "ngsniffer",
+       { "Network Associates Sniffer (DOS-based)", "ngsniffer", FALSE,
          ngsniffer_dump_can_write_encap, ngsniffer_dump_open },
 
        /* WTAP_FILE_NGSNIFFER_COMPRESSED */
-       { "Network Associates Sniffer (DOS-based), compressed", "ngsniffer_comp",
+       { "Network Associates Sniffer (DOS-based), compressed", "ngsniffer_comp", FALSE,
          NULL, NULL },
 
        /* WTAP_FILE_SNOOP */
-       { "Sun snoop", "snoop",
+       { "Sun snoop", "snoop", FALSE,
          snoop_dump_can_write_encap, snoop_dump_open },
 
        /* WTAP_FILE_SHOMITI */
-       { "Shomiti/Finisar Surveyor", "shomiti",
+       { "Shomiti/Finisar Surveyor", "shomiti", FALSE,
          NULL, NULL },
 
        /* WTAP_FILE_IPTRACE_1_0 */
-       { "AIX iptrace 1.0", NULL,
+       { "AIX iptrace 1.0", NULL, FALSE,
          NULL, NULL },
 
        /* WTAP_FILE_IPTRACE_2_0 */
-       { "AIX iptrace 2.0", NULL,
+       { "AIX iptrace 2.0", NULL, FALSE,
          NULL, NULL },
 
        /* WTAP_FILE_NETMON_1_x */
-       { "Microsoft Network Monitor 1.x", "netmon1",
+       { "Microsoft Network Monitor 1.x", "netmon1", FALSE,
          netmon_dump_can_write_encap, netmon_dump_open },
 
        /* WTAP_FILE_NETMON_2_x */
-       { "Microsoft Network Monitor 2.x", "netmon2",
+       { "Microsoft Network Monitor 2.x", "netmon2", FALSE,
          netmon_dump_can_write_encap, netmon_dump_open },
 
        /* WTAP_FILE_NETXRAY_OLD */
-       { "Cinco Networks NetXRay 1.x", NULL,
+       { "Cinco Networks NetXRay 1.x", NULL, FALSE,
          NULL, NULL },
 
        /* WTAP_FILE_NETXRAY_1_0 */
-       { "Cinco Networks NetXRay 2.0 or later", NULL,
+       { "Cinco Networks NetXRay 2.0 or later", NULL, FALSE,
          NULL, NULL },
 
        /* WTAP_FILE_NETXRAY_1_1 */
-       { "Network Associates Sniffer (Windows-based) 1.1", "ngwsniffer_1_1",
+       { "Network Associates Sniffer (Windows-based) 1.1", "ngwsniffer_1_1", FALSE,
          netxray_dump_can_write_encap_1_1, netxray_dump_open_1_1 },
 
        /* WTAP_FILE_NETXRAY_2_00x */
-       { "Network Associates Sniffer (Windows-based) 2.00x", "ngwsniffer_2_0",
+       { "Network Associates Sniffer (Windows-based) 2.00x", "ngwsniffer_2_0", FALSE,
          netxray_dump_can_write_encap_2_0, netxray_dump_open_2_0 },
 
        /* WTAP_FILE_RADCOM */
-       { "RADCOM WAN/LAN analyzer", NULL,
+       { "RADCOM WAN/LAN analyzer", NULL, FALSE,
          NULL, NULL },
 
        /* WTAP_FILE_ASCEND */
-       { "Lucent/Ascend access server trace", NULL,
+       { "Lucent/Ascend access server trace", NULL, FALSE,
          NULL, NULL },
 
        /* WTAP_FILE_NETTL */
-       { "HP-UX nettl trace", "nettl",
+       { "HP-UX nettl trace", "nettl", FALSE,
          nettl_dump_can_write_encap, nettl_dump_open },
 
        /* WTAP_FILE_TOSHIBA */
-       { "Toshiba Compact ISDN Router snoop trace", NULL,
+       { "Toshiba Compact ISDN Router snoop trace", NULL, FALSE,
          NULL, NULL },
 
        /* WTAP_FILE_I4BTRACE */
-       { "I4B ISDN trace", NULL,
+       { "I4B ISDN trace", NULL, FALSE,
          NULL, NULL },
 
         /* WTAP_FILE_CSIDS */
-        { "CSIDS IPLog", NULL,
+        { "CSIDS IPLog", NULL, FALSE,
           NULL, NULL },
 
         /* WTAP_FILE_PPPDUMP */
-        { "pppd log (pppdump format)", NULL,
+        { "pppd log (pppdump format)", NULL, FALSE,
           NULL, NULL },
 
        /* WTAP_FILE_ETHERPEEK_V56 */
-       { "EtherPeek/TokenPeek trace (V5 & V6 file format)", NULL,
+       { "EtherPeek/TokenPeek trace (V5 & V6 file format)", NULL, FALSE,
          NULL, NULL },
 
        /* WTAP_FILE_ETHERPEEK_V7 */
-       { "EtherPeek/TokenPeek/AiroPeek trace (V7 file format)", NULL,
+       { "EtherPeek/TokenPeek/AiroPeek trace (V7 file format)", NULL, FALSE,
          NULL, NULL },
 
        /* WTAP_FILE_VMS */
-       { "TCPIPtrace (VMS)", NULL,
+       { "TCPIPtrace (VMS)", NULL, FALSE,
          NULL, NULL},
 
        /* WTAP_FILE_DBS_ETHERWATCH */
-       { "DBS Etherwatch (VMS)", NULL,
+       { "DBS Etherwatch (VMS)", NULL, FALSE,
          NULL, NULL},
 
        /* WTAP_FILE_VISUAL_NETWORKS */
-       { "Visual Networks traffic capture", "visual",
+       { "Visual Networks traffic capture", "visual", FALSE,
          visual_dump_can_write_encap, visual_dump_open },
 
        /* WTAP_FILE_COSINE */
-       { "CoSine IPSX L2 capture", "cosine",
+       { "CoSine IPSX L2 capture", "cosine", FALSE,
          NULL, NULL },
 
        /* WTAP_FILE_5VIEWS */
-       { "Accellent 5Views capture", "5views",
+       { "Accellent 5Views capture", "5views", FALSE,
          _5views_dump_can_write_encap, _5views_dump_open },
 
        /* WTAP_FILE_ERF */
-       { "Endace DAG capture", "erf",
+       { "Endace DAG capture", "erf", FALSE,
          NULL, NULL },
 
        /* WTAP_FILE_HCIDUMP */
-       { "Bluetooth HCI dump", "hcidump",
+       { "Bluetooth HCI dump", "hcidump", FALSE,
          NULL, NULL },
 
        /* WTAP_FILE_NETWORK_INSTRUMENTS_V9 */
-       { "Network Instruments Observer version 9", "niobserverv9",
+       { "Network Instruments Observer version 9", "niobserverv9", FALSE,
          network_instruments_dump_can_write_encap, network_instruments_dump_open },
 
        /* WTAP_FILE_AIROPEEK_V9 */
-       { "EtherPeek/AiroPeek trace (V9 file format)", NULL,
+       { "EtherPeek/AiroPeek trace (V9 file format)", NULL, FALSE,
          NULL, NULL },
     
        /* WTAP_FILE_EYESDN */
-       { "EyeSDN USB S0/E1 ISDN trace format", NULL,
+       { "EyeSDN USB S0/E1 ISDN trace format", NULL, FALSE,
                NULL, NULL },
     
        /* WTAP_FILE_K12 */
-       { "Tektronix K12xx 32-bit .rf5 format", "rf5",
+       { "Tektronix K12xx 32-bit .rf5 format", "rf5", FALSE,
                k12_dump_can_write_encap, k12_dump_open },
 };
 
@@ -563,29 +564,51 @@ gboolean wtap_dump_can_write_encap(int filetype, int encap)
        return TRUE;
 }
 
-static gboolean wtap_dump_open_check(int filetype, int encap, int *err);
+gboolean wtap_dump_can_compress(int filetype)
+{
+#ifdef HAVE_LIBZ
+       if (filetype < 0 || filetype >= WTAP_NUM_FILE_TYPES
+           || dump_open_table[filetype].can_compress == FALSE)
+               return FALSE;
+
+       return TRUE;
+#else
+       return FALSE;
+#endif
+}
+
+
+static gboolean wtap_dump_open_check(int filetype, int encap, gboolean comressed, int *err);
 static wtap_dumper* wtap_dump_alloc_wdh(int filetype, int encap, int snaplen,
-    int *err);
-static gboolean wtap_dump_open_finish(wtap_dumper *wdh, int filetype, int *err);
+    gboolean compressed, int *err);
+static gboolean wtap_dump_open_finish(wtap_dumper *wdh, int filetype, gboolean compressed, int *err);
+
+static FILE *wtap_dump_file_open(wtap_dumper *wdh, const char *filename);
+static FILE *wtap_dump_file_fdopen(wtap_dumper *wdh, int fd);
+static int wtap_dump_file_close(wtap_dumper *wdh);
 
 wtap_dumper* wtap_dump_open(const char *filename, int filetype, int encap,
-                               int snaplen, int *err)
+                               int snaplen, gboolean compressed, int *err)
 {
        wtap_dumper *wdh;
        FILE *fh;
 
        /* Check whether we can open a capture file with that file type
           and that encapsulation. */
-       if (!wtap_dump_open_check(filetype, encap, err))
+       if (!wtap_dump_open_check(filetype, encap, compressed, err))
                return NULL;
 
        /* Allocate a data structure for the output stream. */
-       wdh = wtap_dump_alloc_wdh(filetype, encap, snaplen, err);
+       wdh = wtap_dump_alloc_wdh(filetype, encap, snaplen, compressed, err);
        if (wdh == NULL)
                return NULL;    /* couldn't allocate it */
 
        /* Empty filename means stdout */
        if (*filename == '\0') {
+               if(compressed) {
+                       g_free(wdh);
+                       return NULL;    /* compress won't work on stdout */
+               }
 #ifdef _WIN32
                setmode(fileno(stdout), O_BINARY);
 #endif
@@ -594,56 +617,64 @@ wtap_dumper* wtap_dump_open(const char *filename, int filetype, int encap,
                /* In case "fopen()" fails but doesn't set "errno", set "errno"
                   to a generic "the open failed" error. */
                errno = WTAP_ERR_CANT_OPEN;
-               fh = fopen(filename, "wb");
+               fh = wtap_dump_file_open(wdh, filename);
                if (fh == NULL) {
                        *err = errno;
+                       g_free(wdh);
                        return NULL;    /* can't create file */
                }
                wdh->fh = fh;
        }
 
-       if (!wtap_dump_open_finish(wdh, filetype, err)) {
+       if (!wtap_dump_open_finish(wdh, filetype, compressed, err)) {
                /* Get rid of the file we created; we couldn't finish
                   opening it. */
-               if (wdh->fh != stdout)
+               if (wdh->fh != stdout) {
+                       wtap_dump_file_close(wdh);
                        unlink(filename);
+               }
+               g_free(wdh);
                return NULL;
        }
        return wdh;
 }
 
 wtap_dumper* wtap_dump_fdopen(int fd, int filetype, int encap, int snaplen,
-                               int *err)
+                               gboolean compressed, int *err)
 {
        wtap_dumper *wdh;
        FILE *fh;
 
        /* Check whether we can open a capture file with that file type
           and that encapsulation. */
-       if (!wtap_dump_open_check(filetype, encap, err))
+       if (!wtap_dump_open_check(filetype, encap, compressed, err))
                return NULL;
 
        /* Allocate a data structure for the output stream. */
-       wdh = wtap_dump_alloc_wdh(filetype, encap, snaplen, err);
+       wdh = wtap_dump_alloc_wdh(filetype, encap, snaplen, compressed, err);
        if (wdh == NULL)
                return NULL;    /* couldn't allocate it */
 
        /* In case "fopen()" fails but doesn't set "errno", set "errno"
           to a generic "the open failed" error. */
        errno = WTAP_ERR_CANT_OPEN;
-       fh = fdopen(fd, "wb");
+       fh = wtap_dump_file_fdopen(wdh, fd);
        if (fh == NULL) {
                *err = errno;
+               g_free(wdh);
                return NULL;    /* can't create standard I/O stream */
        }
        wdh->fh = fh;
 
-       if (!wtap_dump_open_finish(wdh, filetype, err))
+       if (!wtap_dump_open_finish(wdh, filetype, compressed, err)) {
+               wtap_dump_file_close(wdh);
+               g_free(wdh);
                return NULL;
+       }
        return wdh;
 }
 
-static gboolean wtap_dump_open_check(int filetype, int encap, int *err)
+static gboolean wtap_dump_open_check(int filetype, int encap, gboolean compressed, int *err)
 {
        if (!wtap_dump_can_open(filetype)) {
                /* Invalid type, or type we don't know how to write. */
@@ -657,12 +688,23 @@ static gboolean wtap_dump_open_check(int filetype, int encap, int *err)
        if (*err != 0)
                return FALSE;
 
+       /* if compression is wanted, do we support this for this filetype? */
+       if(compressed && !wtap_dump_can_compress(filetype)) {
+               *err = WTAP_ERR_COMPRESSION_NOT_SUPPORTED;
+               return FALSE;
+       }
+
+       *err = (*dump_open_table[filetype].can_write_encap)(encap);
+       if (*err != 0)
+               return FALSE;
+
+
        /* All systems go! */
        return TRUE;
 }
 
 static wtap_dumper* wtap_dump_alloc_wdh(int filetype, int encap, int snaplen,
-                                       int *err)
+                                       gboolean compressed, int *err)
 {
        wtap_dumper *wdh;
 
@@ -675,6 +717,7 @@ static wtap_dumper* wtap_dump_alloc_wdh(int filetype, int encap, int snaplen,
        wdh->file_type = filetype;
        wdh->snaplen = snaplen;
        wdh->encap = encap;
+       wdh->compressed = compressed;
        wdh->bytes_dumped = 0;
        wdh->dump.opaque = NULL;
        wdh->subtype_write = NULL;
@@ -682,49 +725,52 @@ static wtap_dumper* wtap_dump_alloc_wdh(int filetype, int encap, int snaplen,
        return wdh;
 }
 
-static gboolean wtap_dump_open_finish(wtap_dumper *wdh, int filetype, int *err)
+static gboolean wtap_dump_open_finish(wtap_dumper *wdh, int filetype, gboolean compressed, int *err)
 {
        int fd;
        gboolean cant_seek;
 
        /* Can we do a seek on the file descriptor?
           If not, note that fact. */
-       fd = fileno(wdh->fh);
-       if (lseek(fd, 1, SEEK_CUR) == -1)
-         cant_seek = TRUE;
-       else {
-         /* Undo the seek. */
-         lseek(fd, 0, SEEK_SET);
-         cant_seek = FALSE;
+       if(compressed) {
+               cant_seek = TRUE;
+       } else {
+               fd = fileno(wdh->fh);
+               if (lseek(fd, 1, SEEK_CUR) == -1)
+                 cant_seek = TRUE;
+               else {
+                 /* Undo the seek. */
+                 lseek(fd, 0, SEEK_SET);
+                 cant_seek = FALSE;
+               }
        }
 
        /* Now try to open the file for writing. */
        if (!(*dump_open_table[filetype].dump_open)(wdh, cant_seek, err)) {
-               /* The attempt failed.  Close the stream for the file.
-                  NOTE: this means the FD handed to "wtap_dump_fdopen()"
-                  will be closed if the open fails. */
-               if (wdh->fh != stdout)
-                       fclose(wdh->fh);
-
-               /* Now free up the dumper handle. */
-               g_free(wdh);
                return FALSE;
        }
 
        return TRUE;    /* success! */
 }
 
-FILE* wtap_dump_file(wtap_dumper *wdh)
-{
-       return wdh->fh;
-}
-
 gboolean wtap_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
     const union wtap_pseudo_header *pseudo_header, const guchar *pd, int *err)
 {
        return (wdh->subtype_write)(wdh, phdr, pseudo_header, pd, err);
 }
 
+void wtap_dump_flush(wtap_dumper *wdh)
+{
+#ifdef HAVE_LIBZ
+       if(wdh->compressed) {
+               gzflush(wdh->fh, Z_SYNC_FLUSH); /* XXX - is Z_SYNC_FLUSH the right one? */
+       } else 
+#endif
+       {
+               fflush(wdh->fh);
+       }
+}
+
 gboolean wtap_dump_close(wtap_dumper *wdh, int *err)
 {
        gboolean ret = TRUE;
@@ -737,7 +783,7 @@ gboolean wtap_dump_close(wtap_dumper *wdh, int *err)
        errno = WTAP_ERR_CANT_CLOSE;
        /* Don't close stdout */
        if (wdh->fh != stdout) {
-               if (fclose(wdh->fh) == EOF) {
+               if (wtap_dump_file_close(wdh) == EOF) {
                        if (ret) {
                                /* The per-format close function succeeded,
                                   but the fclose didn't.  Save the reason
@@ -764,3 +810,77 @@ void wtap_set_bytes_dumped(wtap_dumper *wdh, long bytes_dumped)
        wdh->bytes_dumped = bytes_dumped;
 }
 
+
+/* internally open a file for writing (compressed or not) */
+static FILE *wtap_dump_file_open(wtap_dumper *wdh, const char *filename)
+{
+#ifdef HAVE_LIBZ
+       if(wdh->compressed) {
+               return gzopen(filename, "wb");
+       } else 
+#endif
+       {
+               return fopen(filename, "wb");
+       }
+}
+
+/* internally open a file for writing (compressed or not) */
+static FILE *wtap_dump_file_fdopen(wtap_dumper *wdh, int fd)
+{
+#ifdef HAVE_LIBZ
+       if(wdh->compressed) {
+               return gzdopen(fd, "wb");
+       } else 
+#endif
+       {
+               return fdopen(fd, "wb");
+       }
+}
+
+/* internally writing raw bytes (compressed or not) */
+size_t wtap_dump_file_write(wtap_dumper *wdh, const void *buf, unsigned bufsize)
+{
+#ifdef HAVE_LIBZ
+       if(wdh->compressed) {
+               return gzwrite(wdh->fh, buf, bufsize);
+       } else 
+#endif
+       {
+               return fwrite(buf, 1, bufsize, wdh->fh);
+       }
+}
+
+/* internally close a file for writing (compressed or not) */
+static int wtap_dump_file_close(wtap_dumper *wdh)
+{
+#ifdef HAVE_LIBZ
+       if(wdh->compressed) {
+               return gzclose(wdh->fh);
+       } else 
+#endif
+       {
+               return fclose(wdh->fh);
+       }
+}
+
+int wtap_dump_file_ferror(wtap_dumper *wdh)
+{
+#ifdef HAVE_LIBZ
+       int errnum;
+
+       if(wdh->compressed) {
+               gzerror(wdh->fh, &errnum);
+
+               if(errnum == Z_ERRNO) {
+                       return errno;
+               } else {
+                       /* XXX - what to do with this zlib specific number? */
+                       return errnum;
+               }
+       } else 
+#endif
+       {
+               return ferror(wdh->fh);
+       }
+}
+
index f3cbbe0f738f43f12378e70e0e4c696163976148..7226f78585b2d3be249b4fa397e00c3b623a6d0b 100644 (file)
@@ -1991,10 +1991,10 @@ gboolean libpcap_dump_open(wtap_dumper *wdh, gboolean cant_seek _U_, int *err)
                return FALSE;
        }
 
-       nwritten = fwrite(&magic, 1, sizeof magic, wdh->fh);
+       nwritten = wtap_dump_file_write(wdh, &magic, sizeof magic);
        if (nwritten != sizeof magic) {
-               if (nwritten == 0 && ferror(wdh->fh))
-                       *err = errno;
+               if (nwritten == 0 && wtap_dump_file_ferror(wdh))
+                       *err = wtap_dump_file_ferror(wdh);
                else
                        *err = WTAP_ERR_SHORT_WRITE;
                return FALSE;
@@ -2020,10 +2020,10 @@ gboolean libpcap_dump_open(wtap_dumper *wdh, gboolean cant_seek _U_, int *err)
        file_hdr.snaplen = (wdh->snaplen != 0) ? wdh->snaplen :
                                                 WTAP_MAX_PACKET_SIZE;
        file_hdr.network = wtap_wtap_encap_to_pcap_encap(wdh->encap);
-       nwritten = fwrite(&file_hdr, 1, sizeof file_hdr, wdh->fh);
+       nwritten = wtap_dump_file_write(wdh, &file_hdr, sizeof file_hdr);
        if (nwritten != sizeof file_hdr) {
-               if (nwritten == 0 && ferror(wdh->fh))
-                       *err = errno;
+               if (nwritten == 0 && wtap_dump_file_ferror(wdh))
+                       *err = wtap_dump_file_ferror(wdh);
                else
                        *err = WTAP_ERR_SHORT_WRITE;
                return FALSE;
@@ -2123,10 +2123,10 @@ static gboolean libpcap_dump(wtap_dumper *wdh,
                return FALSE;
        }
 
-       nwritten = fwrite(&rec_hdr, 1, hdr_size, wdh->fh);
+       nwritten = wtap_dump_file_write(wdh, &rec_hdr, hdr_size);
        if (nwritten != hdr_size) {
-               if (nwritten == 0 && ferror(wdh->fh))
-                       *err = errno;
+               if (nwritten == 0 && wtap_dump_file_ferror(wdh))
+                       *err = wtap_dump_file_ferror(wdh);
                else
                        *err = WTAP_ERR_SHORT_WRITE;
                return FALSE;
@@ -2168,10 +2168,10 @@ static gboolean libpcap_dump(wtap_dumper *wdh,
                }
                atm_hdr.vpi = (guint8) pseudo_header->atm.vpi;
                atm_hdr.vci = phtons(&pseudo_header->atm.vci);
-               nwritten = fwrite(&atm_hdr, 1, sizeof atm_hdr, wdh->fh);
+               nwritten = wtap_dump_file_write(wdh, &atm_hdr, sizeof atm_hdr);
                if (nwritten != sizeof atm_hdr) {
-                       if (nwritten == 0 && ferror(wdh->fh))
-                               *err = errno;
+                       if (nwritten == 0 && wtap_dump_file_ferror(wdh))
+                               *err = wtap_dump_file_ferror(wdh);
                        else
                                *err = WTAP_ERR_SHORT_WRITE;
                        return FALSE;
@@ -2185,10 +2185,10 @@ static gboolean libpcap_dump(wtap_dumper *wdh,
                memset(&irda_hdr, 0, sizeof(irda_hdr));
                irda_hdr.sll_pkttype  = phtons(&pseudo_header->irda.pkttype);
                irda_hdr.sll_protocol = g_htons(0x0017);
-               nwritten = fwrite(&irda_hdr, 1, sizeof(irda_hdr), wdh->fh);
+               nwritten = wtap_dump_file_write(wdh, &irda_hdr, sizeof(irda_hdr));
                if (nwritten != sizeof(irda_hdr)) {
-                       if (nwritten == 0 && ferror(wdh->fh))
-                               *err = errno;
+                       if (nwritten == 0 && wtap_dump_file_ferror(wdh))
+                               *err = wtap_dump_file_ferror(wdh);
                        else
                                *err = WTAP_ERR_SHORT_WRITE;
                        return FALSE;
@@ -2203,10 +2203,10 @@ static gboolean libpcap_dump(wtap_dumper *wdh,
                mtp2_hdr.sent         = pseudo_header->mtp2.sent;
                mtp2_hdr.annex_a_used = pseudo_header->mtp2.annex_a_used;
                mtp2_hdr.link_number  = phtons(&pseudo_header->mtp2.link_number);
-               nwritten = fwrite(&mtp2_hdr, 1, sizeof(mtp2_hdr), wdh->fh);
+               nwritten = wtap_dump_file_write(wdh, &mtp2_hdr, sizeof(mtp2_hdr));
                if (nwritten != sizeof(mtp2_hdr)) {
-                       if (nwritten == 0 && ferror(wdh->fh))
-                               *err = errno;
+                       if (nwritten == 0 && wtap_dump_file_ferror(wdh))
+                               *err = wtap_dump_file_ferror(wdh);
                        else
                                *err = WTAP_ERR_SHORT_WRITE;
                        return FALSE;
@@ -2214,10 +2214,10 @@ static gboolean libpcap_dump(wtap_dumper *wdh,
                wdh->bytes_dumped += sizeof(mtp2_hdr);
        }
 
-       nwritten = fwrite(pd, 1, phdr->caplen, wdh->fh);
+       nwritten = wtap_dump_file_write(wdh, pd, phdr->caplen);
        if (nwritten != phdr->caplen) {
-               if (nwritten == 0 && ferror(wdh->fh))
-                       *err = errno;
+               if (nwritten == 0 && wtap_dump_file_ferror(wdh))
+                       *err = wtap_dump_file_ferror(wdh);
                else
                        *err = WTAP_ERR_SHORT_WRITE;
                return FALSE;
index 79f3d072f095ca9eefdbc3277d7a6ab68c440e57..52680d5fe713b9b33c8f9ec1d1ba5614ccd9dd3d 100644 (file)
@@ -230,6 +230,7 @@ struct wtap_dumper {
        int                     file_type;
        int                     snaplen;
        int                     encap;
+       gboolean        compressed;
        long                    bytes_dumped;
 
        union {
@@ -249,6 +250,8 @@ struct wtap_dumper {
                                                         * e.g. WTAP_FILE_TSPREC_USEC */
 };
 
+extern size_t wtap_dump_file_write(wtap_dumper *wdh, const void *buf, unsigned bufsize);
+extern int wtap_dump_file_ferror(wtap_dumper *wdh);
 
 /* Macros to byte-swap 32-bit and 16-bit quantities. */
 #define        BSWAP32(x) \
index 74d11b8cb11d444d0e343a699effe2365d88c0a4..1470e460555e73b2dbd2edbe9fb04f3926a89d31 100644 (file)
@@ -4,9 +4,10 @@ wtap_close
 wtap_dump
 wtap_dump_can_open
 wtap_dump_can_write_encap
+wtap_dump_can_compress
 wtap_dump_close
 wtap_dump_fdopen
-wtap_dump_file
+wtap_dump_flush
 wtap_dump_open
 wtap_encap_short_string
 wtap_encap_string
index 916a7f8b00862032fed56ebc01c9db807d94caa9..81774048bfdb2174f60b23f73c1f6871b207a52f 100644 (file)
@@ -572,13 +572,14 @@ gboolean wtap_seek_read (wtap *wth, long seek_off,
 
 gboolean wtap_dump_can_open(int filetype);
 gboolean wtap_dump_can_write_encap(int filetype, int encap);
+gboolean wtap_dump_can_compress(int filetype);
 wtap_dumper* wtap_dump_open(const char *filename, int filetype, int encap,
-       int snaplen, int *err);
+       int snaplen, gboolean compressed, int *err);
 wtap_dumper* wtap_dump_fdopen(int fd, int filetype, int encap, int snaplen,
-       int *err);
+       gboolean compressed, int *err);
 gboolean wtap_dump(wtap_dumper *, const struct wtap_pkthdr *,
        const union wtap_pseudo_header *pseudo_header, const guchar *, int *err);
-FILE* wtap_dump_file(wtap_dumper *);
+void wtap_dump_flush(wtap_dumper *);
 gboolean wtap_dump_close(wtap_dumper *, int *);
 long wtap_get_bytes_dumped(wtap_dumper *);
 void wtap_set_bytes_dumped(wtap_dumper *wdh, long bytes_dumped);
@@ -624,6 +625,8 @@ void wtap_set_bytes_dumped(wtap_dumper *wdh, long bytes_dumped);
        /* LZ77 compressed data has bad offset to string */
 #define        WTAP_ERR_RANDOM_OPEN_STDIN              -18
        /* We're trying to open the standard input for random access */
+#define WTAP_ERR_COMPRESSION_NOT_SUPPORTED -19
+       /* The filetype doesn't support output compression */
 
 /* Errors from zlib; zlib error Z_xxx turns into Wiretap error
    WTAP_ERR_ZLIB + Z_xxx.