aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2004-10-29 00:36:52 +0000
committerGuy Harris <guy@alum.mit.edu>2004-10-29 00:36:52 +0000
commite09e12621adefe25905804de8ba7e2687c2c72f2 (patch)
treec12d542a15efb8683f2228ca69aff9142672b6a7
parent24f30a8850a1f11ae2470fd5124e827f443fa62b (diff)
The common merge code merely needs to offer the abstraction of routines
that return the next packet from a set of {chronologically sorted, sequential-by-file} packets; it doesn't need to have a loop over all those packets, or any code to write packets. Supply those abstractions, change the code that merges packets to do its own writing, and have the Ethereal version manage a progress bar and have the mergecap version print packet numbers in verbose mode, as the common merge code used to do. svn path=/trunk/; revision=12427
-rw-r--r--file.c141
-rw-r--r--merge.c222
-rw-r--r--merge.h89
-rw-r--r--mergecap.c92
4 files changed, 282 insertions, 262 deletions
diff --git a/file.c b/file.c
index 4e3149cbbb..e624f6d096 100644
--- a/file.c
+++ b/file.c
@@ -975,60 +975,136 @@ cf_merge_files(const char *out_filename, int out_fd, int in_file_count,
char *const *in_filenames, int file_type, gboolean do_append)
{
merge_in_file_t *in_files;
- merge_out_file_t out_file;
- int err, close_err;
+ wtap *wth;
+ wtap_dumper *pdh;
+ int open_err, read_err, write_err, close_err;
gchar *err_info;
int err_fileno;
- merge_status_e status;
int i;
char errmsg_errno[1024+1];
gchar err_str[2048+1];
char *errmsg;
+ gboolean got_read_error = FALSE, got_write_error = FALSE;
+ long data_offset;
+ progdlg_t *progbar = NULL;
+ gboolean stop_flag;
+ /*
+ * XXX - should be "off_t", but Wiretap would need more work to handle
+ * the full size of "off_t" on platforms where it's more than a "long"
+ * as well.
+ */
+ long f_len, file_pos;
+ float prog_val;
+ GTimeVal start_time;
+ gchar status_str[100];
+ int progbar_nextstep;
+ int progbar_quantum;
/* open the input files */
if (!merge_open_in_files(in_file_count, in_filenames, &in_files,
- &err, &err_info, &err_fileno)) {
+ &open_err, &err_info, &err_fileno)) {
free(in_files);
- cf_open_failure_alert_box(in_filenames[err_fileno], err, err_info, FALSE, 0);
+ cf_open_failure_alert_box(in_filenames[err_fileno], open_err, err_info,
+ FALSE, 0);
return FALSE;
}
- if (!merge_open_outfile(&out_file, out_fd, file_type,
+ 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), &err)) {
+ merge_max_snapshot_length(in_file_count, in_files), &open_err);
+ if (pdh == NULL) {
merge_close_in_files(in_file_count, in_files);
free(in_files);
- cf_open_failure_alert_box(out_filename, err, err_info, TRUE, file_type);
+ cf_open_failure_alert_box(out_filename, open_err, err_info, TRUE,
+ file_type);
return FALSE;
}
+ /* Get the sum of the sizes of all the files. */
+ f_len = 0;
+ for (i = 0; i < in_file_count; i++)
+ f_len += in_files[i].size;
+
+ /* Update the progress bar when it gets to this value. */
+ progbar_nextstep = 0;
+ /* When we reach the value that triggers a progress bar update,
+ bump that value by this amount. */
+ progbar_quantum = f_len/N_PROGBAR_UPDATES;
+
+ stop_flag = FALSE;
+ g_get_current_time(&start_time);
+
/* do the merge (or append) */
- if (do_append)
- status = merge_append_files(in_file_count, in_files, &out_file, &err);
- else
- status = merge_files(in_file_count, in_files, &out_file, &err);
+ for (;;) {
+ if (do_append)
+ wth = merge_append_read_packet(in_file_count, in_files, &read_err,
+ &err_info);
+ else
+ wth = merge_read_packet(in_file_count, in_files, &read_err,
+ &err_info);
+ if (wth == NULL) {
+ if (read_err != 0)
+ got_read_error = TRUE;
+ break;
+ }
- merge_close_in_files(in_file_count, in_files);
- if (status == MERGE_SUCCESS) {
- if (!merge_close_outfile(&out_file, &err))
- status = MERGE_WRITE_ERROR;
- } else
- merge_close_outfile(&out_file, &close_err);
+ /* Get the sum of the data offsets in all of the files. */
+ data_offset = 0;
+ for (i = 0; i < in_file_count; i++)
+ data_offset += in_files[i].data_offset;
+
+ if (data_offset >= progbar_nextstep) {
+ /* Get the sum of the seek positions in all of the files. */
+ file_pos = 0;
+ for (i = 0; i < in_file_count; i++)
+ file_pos += lseek(wtap_fd(in_files[i].wth), 0, SEEK_CUR);
+ prog_val = (gfloat) file_pos / (gfloat) f_len;
+ if (prog_val > 1.0) {
+ /* Some file probably grew while we were reading it.
+ That "shouldn't happen", so we'll just clip the progress
+ value at 1.0. */
+ prog_val = 1.0;
+ }
+ if (progbar == NULL) {
+ /* Create the progress bar if necessary */
+ progbar = delayed_create_progress_dlg("Merging", "files",
+ &stop_flag, &start_time, prog_val);
+ }
+ if (progbar != NULL) {
+ g_snprintf(status_str, sizeof(status_str),
+ "%luKB of %luKB", file_pos / 1024, f_len / 1024);
+ update_progress_dlg(progbar, prog_val, status_str);
+ }
+ progbar_nextstep += progbar_quantum;
+ }
- switch (status) {
+ if (!wtap_dump(pdh, wtap_phdr(wth), wtap_pseudoheader(wth),
+ wtap_buf_ptr(wth), &write_err)) {
+ got_write_error = TRUE;
+ break;
+ }
+ }
- case MERGE_SUCCESS:
- break;
+ /* We're done merging the files; destroy the progress bar if it was created. */
+ if (progbar != NULL)
+ destroy_progress_dlg(progbar);
- case MERGE_READ_ERROR:
+ merge_close_in_files(in_file_count, in_files);
+ if (!got_read_error && !got_write_error) {
+ if (!wtap_dump_close(pdh, &write_err))
+ got_write_error = TRUE;
+ } else
+ wtap_dump_close(pdh, &close_err);
+
+ if (got_read_error) {
/*
* Find the file on which we got the error, and report the error.
*/
for (i = 0; i < in_file_count; i++) {
- if (!in_files[i].ok) {
- /* Put up a message box noting that the read failed somewhere along
+ if (in_files[i].state == GOT_ERROR) {
+ /* Put up a message box noting that a read failed somewhere along
the line. */
- switch (err) {
+ switch (read_err) {
case WTAP_ERR_UNSUPPORTED_ENCAP:
snprintf(errmsg_errno, sizeof(errmsg_errno),
@@ -1050,7 +1126,7 @@ cf_merge_files(const char *out_filename, int out_fd, int in_file_count,
case WTAP_ERR_BAD_RECORD:
snprintf(errmsg_errno, sizeof(errmsg_errno),
- "The capture file %%sappears to be damaged or corrupt.\n(%s)",
+ "The capture file %%s appears to be damaged or corrupt.\n(%s)",
err_info);
g_free(err_info);
errmsg = errmsg_errno;
@@ -1059,7 +1135,7 @@ cf_merge_files(const char *out_filename, int out_fd, int in_file_count,
default:
snprintf(errmsg_errno, sizeof(errmsg_errno),
"An error occurred while reading the"
- " capture file %%s: %s.", wtap_strerror(err));
+ " capture file %%s: %s.", wtap_strerror(read_err));
errmsg = errmsg_errno;
break;
}
@@ -1067,13 +1143,14 @@ cf_merge_files(const char *out_filename, int out_fd, int in_file_count,
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, err_str);
}
}
- break;
+ }
- case MERGE_WRITE_ERROR:
- cf_write_failure_alert_box(out_filename, err);
- break;
+ if (got_write_error) {
+ /* Put up an alert box for the write error. */
+ cf_write_failure_alert_box(out_filename, write_err);
}
- return (status == MERGE_SUCCESS);
+
+ return (!got_read_error && !got_write_error);
}
gboolean
diff --git a/merge.c b/merge.c
index 81f2a78ec2..d82c14136b 100644
--- a/merge.c
+++ b/merge.c
@@ -1,4 +1,4 @@
-/* Combine two dump files, either by appending or by merging by timestamp
+/* Combine multiple dump files, either by appending or by merging by timestamp
*
* $Id$
*
@@ -14,6 +14,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <glib.h>
+#include <errno.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
@@ -23,6 +24,10 @@
#include <sys/time.h>
#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
#include <string.h>
#include "wtap.h"
#include "merge.h"
@@ -38,6 +43,7 @@ merge_open_in_files(int in_file_count, char *const *in_file_names,
int i, j;
int files_size = in_file_count * sizeof(merge_in_file_t);
merge_in_file_t *files;
+ struct stat statb;
files = g_malloc(files_size);
*in_files = files;
@@ -45,9 +51,8 @@ merge_open_in_files(int in_file_count, char *const *in_file_names,
for (i = 0; i < in_file_count; i++) {
files[i].filename = in_file_names[i];
files[i].wth = wtap_open_offline(in_file_names[i], err, err_info, FALSE);
- files[i].err = 0;
files[i].data_offset = 0;
- files[i].ok = TRUE;
+ files[i].state = PACKET_NOT_PRESENT;
if (!files[i].wth) {
/* Close the files we've already opened. */
for (j = 0; j < i; j++)
@@ -55,6 +60,14 @@ merge_open_in_files(int in_file_count, char *const *in_file_names,
*err_fileno = i;
return FALSE;
}
+ if (fstat(wtap_fd(files[i].wth), &statb) < 0) {
+ *err = errno;
+ for (j = 0; j <= i; j++)
+ wtap_close(files[j].wth);
+ *err_fileno = i;
+ return FALSE;
+ }
+ files[i].size = statb.st_size;
}
return TRUE;
}
@@ -72,37 +85,6 @@ merge_close_in_files(int count, merge_in_file_t in_files[])
}
/*
- * Open the output file
- *
- * Return FALSE if file cannot be opened (so caller can report an error
- * and clean up)
- */
-gboolean
-merge_open_outfile(merge_out_file_t *out_file, int fd, int file_type,
- int frame_type, int snapshot_len, int *err)
-{
- out_file->pdh = wtap_dump_fdopen(fd, file_type, frame_type, snapshot_len,
- err);
- if (!out_file->pdh)
- return FALSE;
-
- out_file->snaplen = snapshot_len;
- out_file->count = 1;
- return TRUE;
-}
-
-/*
- * Close the output file
- */
-gboolean
-merge_close_outfile(merge_out_file_t *out_file, int *err)
-{
- if (!wtap_dump_close(out_file->pdh, err))
- return FALSE;
- return TRUE;
-}
-
-/*
* Select an output frame type based on the input files
* From Guy: If all files have the same frame type, then use that.
* Otherwise select WTAP_ENCAP_PER_PACKET. If the selected
@@ -152,29 +134,6 @@ merge_max_snapshot_length(int count, merge_in_file_t in_files[])
}
/*
- * Routine to write frame to output file
- */
-static gboolean
-write_frame(wtap *wth, merge_out_file_t *out_file, int *err)
-{
- const struct wtap_pkthdr *phdr = wtap_phdr(wth);
- struct wtap_pkthdr snap_phdr;
-
- /* We simply write it, perhaps after truncating it; we could do other
- * things, like modify it. */
- if (out_file->snaplen != 0 && phdr->caplen > out_file->snaplen) {
- snap_phdr = *phdr;
- snap_phdr.caplen = out_file->snaplen;
- phdr = &snap_phdr;
- }
-
- if (!wtap_dump(out_file->pdh, phdr, wtap_pseudoheader(wth), wtap_buf_ptr(wth), err))
- return FALSE;
-
- return TRUE;
-}
-
-/*
* returns TRUE if first argument is earlier than second
*/
static gboolean
@@ -192,105 +151,94 @@ is_earlier(struct timeval *l, struct timeval *r) {
return TRUE;
}
-
/*
- * returns index of earliest timestamp in set of input files
- * or -1 if no valid files remain
+ * Read the next packet, in chronological order, from the set of files
+ * to be merged.
*/
-static int
-earliest(int count, merge_in_file_t in_files[]) {
+wtap *
+merge_read_packet(int in_file_count, merge_in_file_t in_files[], int *err,
+ gchar **err_info)
+{
int i;
int ei = -1;
struct timeval tv = {LONG_MAX, LONG_MAX};
+ struct wtap_pkthdr *phdr;
- for (i = 0; i < count; i++) {
- struct wtap_pkthdr *phdr = wtap_phdr(in_files[i].wth);
-
- if (in_files[i].ok && is_earlier(&(phdr->ts), &tv)) {
- tv = phdr->ts;
- ei = i;
+ /*
+ * Make sure we have a packet available from each file, if there are any
+ * packets left in the file in question, and search for the packet
+ * with the earliest time stamp.
+ */
+ for (i = 0; i < in_file_count; i++) {
+ if (in_files[i].state == PACKET_NOT_PRESENT) {
+ /*
+ * No packet available, and we haven't seen an error or EOF yet,
+ * so try to read the next packet.
+ */
+ if (!wtap_read(in_files[i].wth, err, err_info, &in_files[i].data_offset)) {
+ if (*err != 0) {
+ in_files[i].state = GOT_ERROR;
+ return NULL;
+ }
+ in_files[i].state = AT_EOF;
+ } else
+ in_files[i].state = PACKET_PRESENT;
+ }
+
+ if (in_files[i].state == PACKET_PRESENT) {
+ phdr = wtap_phdr(in_files[i].wth);
+ if (is_earlier(&phdr->ts, &tv)) {
+ tv = phdr->ts;
+ ei = i;
+ }
}
- }
- return ei;
-}
-
-/*
- * actually merge the files
- */
-merge_status_e
-merge_files(int count, merge_in_file_t in_files[], merge_out_file_t *out_file, int *err)
-{
- int i;
-
- /* prime the pump (read in first frame from each file) */
- for (i = 0; i < count; i++) {
- in_files[i].ok = wtap_read(in_files[i].wth, &(in_files[i].err),
- &(in_files[i].err_info),
- &(in_files[i].data_offset));
- if (!in_files[i].ok)
- return MERGE_READ_ERROR;
}
- /* now keep writing the earliest frame until we're out of frames */
- while ( -1 != (i = earliest(count, in_files))) {
-
- /* write out earliest frame, and fetch another from its
- * input file
- */
- if(!write_frame(in_files[i].wth, out_file, err))
- return MERGE_WRITE_ERROR;
- in_files[i].ok = wtap_read(in_files[i].wth, &(in_files[i].err),
- &(in_files[i].err_info),
- &(in_files[i].data_offset));
- if (!in_files[i].ok)
- return MERGE_READ_ERROR;
+ if (ei == -1) {
+ /* All the streams are at EOF. Return an EOF indication. */
+ *err = 0;
+ return NULL;
}
- return MERGE_SUCCESS;
-}
-
-static merge_status_e
-append_loop(merge_in_file_t in_files[], int i, int count,
- merge_out_file_t *out_file, int *err)
-{
- gchar *err_info;
- long data_offset;
- int loop = 0;
-
- /* Start by clearing error flag */
- *err = 0;
-
- while ( (wtap_read(in_files[i].wth, err, &err_info, &data_offset)) ) {
- if(!write_frame(in_files[i].wth, out_file, err))
- return MERGE_WRITE_ERROR;
- if (count > 0 && ++loop >= count)
- break;
- }
+ /* We'll need to read another packet from this file. */
+ in_files[ei].state = PACKET_NOT_PRESENT;
- if (*err != 0) {
- in_files[i].ok = FALSE;
- in_files[i].err = *err;
- in_files[i].err_info = err_info;
- return MERGE_READ_ERROR;
- }
- return MERGE_SUCCESS;
+ /* Return a pointer to the wtap structure for the file with that frame. */
+ return in_files[ei].wth;
}
/*
- * routine to concatenate files
+ * Read the next packet, in file sequence order, from the set of files
+ * to be merged.
*/
-merge_status_e
-merge_append_files(int count, merge_in_file_t in_files[],
- merge_out_file_t *out_file, int *err)
+wtap *
+merge_append_read_packet(int in_file_count, merge_in_file_t in_files[],
+ int *err, gchar **err_info)
{
int i;
- merge_status_e status;
- for (i = 0; i < count; i++) {
- status = append_loop(in_files, i, 0, out_file, err);
- if (status != MERGE_SUCCESS)
- return status;
+ /*
+ * Find the first file not at EOF, and read the next packet from it.
+ */
+ for (i = 0; i < in_file_count; i++) {
+ if (in_files[i].state == AT_EOF)
+ continue; /* This file is already at EOF */
+ if (wtap_read(in_files[i].wth, err, err_info, &in_files[i].data_offset))
+ break; /* We have a packet */
+ if (*err != 0) {
+ /* Read error - quit immediately. */
+ in_files[i].state = GOT_ERROR;
+ return NULL;
+ }
+ /* EOF - flag this file as being at EOF, and try the next one. */
+ in_files[i].state = AT_EOF;
+ }
+ if (i == in_file_count) {
+ /* All the streams are at EOF. Return an EOF indication. */
+ *err = 0;
+ return NULL;
}
- return MERGE_SUCCESS;
+ /* Return a pointer to the wtap structure for the file with that frame. */
+ return in_files[i].wth;
}
diff --git a/merge.h b/merge.h
index fe7bf296e6..887e1b866c 100644
--- a/merge.h
+++ b/merge.h
@@ -29,27 +29,24 @@
extern "C" {
#endif /* __cplusplus */
+typedef enum {
+ PACKET_PRESENT,
+ PACKET_NOT_PRESENT,
+ AT_EOF,
+ GOT_ERROR
+} in_file_state_e;
+
/**
* Structures to manage our input files.
*/
typedef struct merge_in_file_s {
- const char *filename;
- wtap *wth;
- int err;
- gchar *err_info;
- long data_offset;
- gboolean ok;
+ const char *filename;
+ wtap *wth;
+ long data_offset;
+ in_file_state_e state;
+ long size; /* file size */
} merge_in_file_t;
-/**
- * Structures to manage our output file.
- */
-typedef struct merge_out_file_s {
- wtap_dumper *pdh;
- unsigned int snaplen;
- int count;
-} merge_out_file_t;
-
/** Open a number of input files to merge.
*
* @param in_file_count number of entries in in_file_names and in_files
@@ -73,29 +70,6 @@ merge_open_in_files(int in_file_count, char *const *in_file_names,
extern void
merge_close_in_files(int in_file_count, merge_in_file_t in_files[]);
-/** Open the output file.
- *
- * @param out_file the output file array, which we fill in
- * @param fd the file descriptor to use for the output file
- * @param file_type the file type to write
- * @param frame_type the frame type to write
- * @param snapshot_len the snapshot length of the output file
- * @param err wiretap error, if failed
- * @return TRUE, if the output file could be opened, and FALSE otherwise
- */
-extern gboolean
-merge_open_outfile(merge_out_file_t *out_file, int fd, int file_type,
- int frame_type, int snapshot_len, int *err);
-
-/** Close the output file again.
- *
- * @param out_file the output file array
- * @param err wiretap error, if failed
- * @return TRUE if the close succeeded, FALSE otherwise
- */
-extern gboolean
-merge_close_outfile(merge_out_file_t *out_file, int *err);
-
/** Try to get the frame type from the input files.
*
* @param in_file_count number of entries in in_files
@@ -114,39 +88,34 @@ merge_select_frame_type(int in_file_count, merge_in_file_t in_files[]);
extern int
merge_max_snapshot_length(int in_file_count, merge_in_file_t in_files[]);
-/*
- * Status from the merge-files routines.
- */
-typedef enum {
- MERGE_SUCCESS,
- MERGE_READ_ERROR,
- MERGE_WRITE_ERROR
-} merge_status_e;
-
-/** Merge the packets from the input files into the output file sorted chronologically.
+/** Read the next packet, in chronological order, from the set of files to
+ * be merged.
*
* @param in_file_count number of entries in in_files
* @param in_files input file array
- * @param out_file the output file array
* @param err wiretap error, if failed
- * @return MERGE_SUCCESS on success, MERGE_READ_ERROR on read error,
- * MERGE_WRITE_ERROR on write error
+ * @param err_info wiretap error string, if failed
+ * @return pointer to wtap for file from which that packet came, or NULL on
+ * error or EOF
*/
-extern merge_status_e
-merge_files(int in_file_count, merge_in_file_t in_files[], merge_out_file_t *out_file, int *err);
+extern wtap *
+merge_read_packet(int in_file_count, merge_in_file_t in_files[], int *err,
+ gchar **err_info);
-/** Append the packets from the input files into the output file.
+
+/** Read the next packet, in file sequence order, from the set of files
+ * to be merged.
*
* @param in_file_count number of entries in in_files
* @param in_files input file array
- * @param out_file the output file array
* @param err wiretap error, if failed
- * @return MERGE_SUCCESS on success, MERGE_READ_ERROR on read error,
- * MERGE_WRITE_ERROR on write error
+ * @param err_info wiretap error string, if failed
+ * @return pointer to wtap for file from which that packet came, or NULL on
+ * error or EOF
*/
-extern merge_status_e
-merge_append_files(int in_file_count, merge_in_file_t in_files[],
- merge_out_file_t *out_file, int *err);
+extern wtap *
+merge_append_read_packet(int in_file_count, merge_in_file_t in_files[],
+ int *err, gchar **err_info);
#ifdef __cplusplus
}
diff --git a/mergecap.c b/mergecap.c
index 19116a42ee..54bffc5539 100644
--- a/mergecap.c
+++ b/mergecap.c
@@ -131,18 +131,21 @@ main(int argc, char *argv[])
gboolean do_append = FALSE;
gboolean verbose = FALSE;
int in_file_count = 0;
- int snaplen = 0;
+ guint snaplen = 0;
int file_type = WTAP_FILE_PCAP; /* default to libpcap format */
int frame_type = -2;
int out_fd;
merge_in_file_t *in_files = NULL;
int i;
- merge_out_file_t out_file;
- int err, close_err;
+ wtap *wth;
+ struct wtap_pkthdr *phdr, snap_phdr;
+ wtap_dumper *pdh;
+ int open_err, read_err, write_err, close_err;
gchar *err_info;
int err_fileno;
char *out_filename = NULL;
- merge_status_e status;
+ gboolean got_read_error = FALSE, got_write_error = FALSE;
+ int count;
/* Process the options first */
while ((opt = getopt(argc, argv, "hvas:T:F:w:")) != -1) {
@@ -217,10 +220,10 @@ main(int argc, char *argv[])
/* open the input files */
if (!merge_open_in_files(in_file_count, &argv[optind], &in_files,
- &err, &err_info, &err_fileno)) {
+ &open_err, &err_info, &err_fileno)) {
fprintf(stderr, "mergecap: Can't open %s: %s\n", argv[optind + err_fileno],
- wtap_strerror(err));
- switch (err) {
+ wtap_strerror(open_err));
+ switch (open_err) {
case WTAP_ERR_UNSUPPORTED:
case WTAP_ERR_UNSUPPORTED_ENCAP:
@@ -298,60 +301,83 @@ main(int argc, char *argv[])
}
/* prepare the outfile */
- if (!merge_open_outfile(&out_file, out_fd, file_type, frame_type, snaplen,
- &err)) {
+ pdh = wtap_dump_fdopen(out_fd, file_type, frame_type, snaplen, &open_err);
+ if (pdh == NULL) {
merge_close_in_files(in_file_count, in_files);
free(in_files);
fprintf(stderr, "mergecap: Can't open or create %s: %s\n", out_filename,
- wtap_strerror(err));
+ wtap_strerror(open_err));
exit(1);
}
/* do the merge (or append) */
- if (do_append)
- status = merge_append_files(in_file_count, in_files, &out_file, &err);
- else
- status = merge_files(in_file_count, in_files, &out_file, &err);
+ count = 1;
+ for (;;) {
+ if (do_append)
+ wth = merge_append_read_packet(in_file_count, in_files, &read_err,
+ &err_info);
+ else
+ wth = merge_read_packet(in_file_count, in_files, &read_err,
+ &err_info);
+ if (wth == NULL) {
+ if (read_err != 0)
+ got_read_error = TRUE;
+ break;
+ }
+
+ if (verbose)
+ fprintf(stderr, "Record: %u\n", count++);
+
+ /* We simply write it, perhaps after truncating it; we could do other
+ * things, like modify it. */
+ phdr = wtap_phdr(wth);
+ if (snaplen != 0 && phdr->caplen > snaplen) {
+ snap_phdr = *phdr;
+ snap_phdr.caplen = snaplen;
+ phdr = &snap_phdr;
+ }
+
+ if (!wtap_dump(pdh, phdr, wtap_pseudoheader(wth),
+ wtap_buf_ptr(wth), &write_err)) {
+ got_write_error = TRUE;
+ break;
+ }
+ }
merge_close_in_files(in_file_count, in_files);
- if (status == MERGE_SUCCESS) {
- if (!merge_close_outfile(&out_file, &err))
- status = MERGE_WRITE_ERROR;
+ if (!got_read_error && !got_write_error) {
+ if (!wtap_dump_close(pdh, &write_err))
+ got_write_error = TRUE;
} else
- merge_close_outfile(&out_file, &close_err);
- switch (status) {
+ wtap_dump_close(pdh, &close_err);
- case MERGE_SUCCESS:
- break;
-
- case MERGE_READ_ERROR:
+ if (got_read_error) {
/*
* Find the file on which we got the error, and report the error.
*/
for (i = 0; i < in_file_count; i++) {
- if (!in_files[i].ok) {
+ if (in_files[i].state == GOT_ERROR) {
fprintf(stderr, "mergecap: Error reading %s: %s\n",
- in_files[i].filename, wtap_strerror(in_files[i].err));
- switch (err) {
+ in_files[i].filename, wtap_strerror(read_err));
+ switch (read_err) {
case WTAP_ERR_UNSUPPORTED:
case WTAP_ERR_UNSUPPORTED_ENCAP:
case WTAP_ERR_BAD_RECORD:
- fprintf(stderr, "(%s)\n", in_files[i].err_info);
- g_free(in_files[i].err_info);
+ fprintf(stderr, "(%s)\n", err_info);
+ g_free(err_info);
break;
}
}
}
- break;
+ }
- case MERGE_WRITE_ERROR:
+ if (got_write_error) {
fprintf(stderr, "mergecap: Error writing to outfile: %s\n",
- wtap_strerror(err));
- break;
+ wtap_strerror(write_err));
}
free(in_files);
- return (status == MERGE_SUCCESS) ? 0 : 2;
+ return (!got_read_error && !got_write_error) ? 0 : 2;
}