aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--capture_loop.c10
-rw-r--r--editcap.c2
-rw-r--r--file.c13
-rw-r--r--file.h3
-rw-r--r--gtk/file_dlg.c18
-rw-r--r--mergecap.c2
-rw-r--r--randpkt.c2
-rw-r--r--ringbuffer.c2
-rw-r--r--tethereal.c6
-rw-r--r--wiretap/file_access.c280
-rw-r--r--wiretap/libpcap.c42
-rw-r--r--wiretap/wtap-int.h3
-rw-r--r--wiretap/wtap.def3
-rw-r--r--wiretap/wtap.h9
14 files changed, 272 insertions, 123 deletions
diff --git a/capture_loop.c b/capture_loop.c
index 8421e73a32..8ed04636a6 100644
--- a/capture_loop.c
+++ b/capture_loop.c
@@ -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 */
diff --git a/editcap.c b/editcap.c
index 09269507e5..50592854a4 100644
--- 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 53b7e6055f..9b4f9977e6 100644
--- 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 fd7ff33301..3eadec354d 100644
--- 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.
diff --git a/gtk/file_dlg.c b/gtk/file_dlg.c
index 7288dc8396..100b5bf193 100644
--- a/gtk/file_dlg.c
+++ b/gtk/file_dlg.c
@@ -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. */
diff --git a/mergecap.c b/mergecap.c
index 83777a7ebe..9136e64930 100644
--- a/mergecap.c
+++ b/mergecap.c
@@ -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);
diff --git a/randpkt.c b/randpkt.c
index 65873fa0e0..965189b06b 100644
--- 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();
diff --git a/ringbuffer.c b/ringbuffer.c
index 84d2983d57..4f1d5fe0da 100644
--- a/ringbuffer.c
+++ b/ringbuffer.c
@@ -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;
}
diff --git a/tethereal.c b/tethereal.c
index 3fe4974140..7b60c68157 100644
--- a/tethereal.c
+++ b/tethereal.c
@@ -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. */
diff --git a/wiretap/file_access.c b/wiretap/file_access.c
index 84705e29fd..08b4d72384 100644
--- a/wiretap/file_access.c
+++ b/wiretap/file_access.c
@@ -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);
+ }
+}
+
diff --git a/wiretap/libpcap.c b/wiretap/libpcap.c
index f3cbbe0f73..7226f78585 100644
--- a/wiretap/libpcap.c
+++ b/wiretap/libpcap.c
@@ -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;
diff --git a/wiretap/wtap-int.h b/wiretap/wtap-int.h
index 79f3d072f0..52680d5fe7 100644
--- a/wiretap/wtap-int.h
+++ b/wiretap/wtap-int.h
@@ -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) \
diff --git a/wiretap/wtap.def b/wiretap/wtap.def
index 74d11b8cb1..1470e46055 100644
--- a/wiretap/wtap.def
+++ b/wiretap/wtap.def
@@ -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
diff --git a/wiretap/wtap.h b/wiretap/wtap.h
index 916a7f8b00..81774048bf 100644
--- a/wiretap/wtap.h
+++ b/wiretap/wtap.h
@@ -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.