forked from osmocom/wireshark
Have separate merge APIs for regular file/temporary file/standard output.
This is similar to what we have for opening a dump file - one API that uses the file name as specified, one that creates a temporary file and provides the file name, and one that uses the standard output. All of those APIs handle closing the output file. Change-Id: I56beea7be347402773460b9148ab31a8f8bc51e1 Reviewed-on: https://code.wireshark.org/review/19059 Reviewed-by: Guy Harris <guy@alum.mit.edu>
This commit is contained in:
parent
5aede1bc50
commit
dd98856afc
|
@ -10,6 +10,8 @@ libwiretap.so.0 libwiretap0 #MINVER#
|
|||
file_tell@Base 1.9.1
|
||||
init_open_routines@Base 1.12.0~rc1
|
||||
merge_files@Base 1.99.9
|
||||
merge_files_to_stdout@Base 2.3.0
|
||||
merge_files_to_tempfile@Base 2.3.0
|
||||
merge_idb_merge_mode_to_string@Base 1.99.9
|
||||
merge_string_to_idb_merge_mode@Base 1.99.9
|
||||
open_info_name_to_type@Base 1.12.0~rc1
|
||||
|
|
42
file.c
42
file.c
|
@ -1335,45 +1335,27 @@ merge_callback(merge_event event, int num _U_,
|
|||
|
||||
|
||||
cf_status_t
|
||||
cf_merge_files(char **out_filenamep, int in_file_count,
|
||||
char *const *in_filenames, int file_type, gboolean do_append)
|
||||
cf_merge_files_to_tempfile(char **out_filenamep, int in_file_count,
|
||||
char *const *in_filenames, int file_type,
|
||||
gboolean do_append)
|
||||
{
|
||||
char *out_filename;
|
||||
char *tmpname;
|
||||
int out_fd;
|
||||
int err = 0;
|
||||
gchar *err_info = NULL;
|
||||
guint err_fileno;
|
||||
merge_result status;
|
||||
merge_progress_callback_t cb;
|
||||
|
||||
|
||||
if (*out_filenamep != NULL) {
|
||||
out_filename = *out_filenamep;
|
||||
out_fd = ws_open(out_filename, O_CREAT|O_TRUNC|O_BINARY, 0600);
|
||||
if (out_fd == -1)
|
||||
err = errno;
|
||||
} else {
|
||||
out_fd = create_tempfile(&tmpname, "wireshark", NULL);
|
||||
if (out_fd == -1)
|
||||
err = errno;
|
||||
out_filename = g_strdup(tmpname);
|
||||
*out_filenamep = out_filename;
|
||||
}
|
||||
if (out_fd == -1) {
|
||||
cf_open_failure_alert_box(out_filename, err, NULL, TRUE, file_type);
|
||||
return CF_ERROR;
|
||||
}
|
||||
|
||||
/* prepare our callback routine */
|
||||
cb.callback_func = merge_callback;
|
||||
cb.data = g_malloc0(sizeof(callback_data_t));
|
||||
|
||||
/* merge the files */
|
||||
status = merge_files(out_fd, out_filename, file_type,
|
||||
(const char *const *) in_filenames, in_file_count,
|
||||
do_append, IDB_MERGE_MODE_ALL_SAME, 0 /* snaplen */,
|
||||
"Wireshark", &cb, &err, &err_info, &err_fileno);
|
||||
status = merge_files_to_tempfile(out_filenamep, "wireshark", file_type,
|
||||
(const char *const *) in_filenames,
|
||||
in_file_count, do_append,
|
||||
IDB_MERGE_MODE_ALL_SAME, 0 /* snaplen */,
|
||||
"Wireshark", &cb, &err, &err_info,
|
||||
&err_fileno);
|
||||
|
||||
g_free(cb.data);
|
||||
|
||||
|
@ -1388,13 +1370,11 @@ cf_merge_files(char **out_filenamep, int in_file_count,
|
|||
case MERGE_ERR_CANT_OPEN_INFILE:
|
||||
cf_open_failure_alert_box(in_filenames[err_fileno], err, err_info,
|
||||
FALSE, 0);
|
||||
ws_close(out_fd);
|
||||
break;
|
||||
|
||||
case MERGE_ERR_CANT_OPEN_OUTFILE:
|
||||
cf_open_failure_alert_box(out_filename, err, err_info, TRUE,
|
||||
cf_open_failure_alert_box(*out_filenamep, err, err_info, TRUE,
|
||||
file_type);
|
||||
ws_close(out_fd);
|
||||
break;
|
||||
|
||||
case MERGE_ERR_CANT_READ_INFILE: /* fall through */
|
||||
|
@ -1407,8 +1387,6 @@ cf_merge_files(char **out_filenamep, int in_file_count,
|
|||
}
|
||||
|
||||
g_free(err_info);
|
||||
/* for general case, no need to close out_fd: file handle associated to this file
|
||||
descriptor was already closed by the call to wtap_dump_close() in merge_files() */
|
||||
|
||||
if (status != MERGE_OK) {
|
||||
/* Callers aren't expected to treat an error or an explicit abort
|
||||
|
|
12
file.h
12
file.h
|
@ -645,12 +645,11 @@ void cf_ignore_frame(capture_file *cf, frame_data *frame);
|
|||
void cf_unignore_frame(capture_file *cf, frame_data *frame);
|
||||
|
||||
/**
|
||||
* Merge two (or more) capture files into one.
|
||||
* Merge two or more capture files into a temporary file.
|
||||
* @todo is this the right place for this function? It doesn't have to do a lot with capture_file.
|
||||
*
|
||||
* @param out_filename pointer to output filename; if output filename is
|
||||
* NULL, a temporary file name is generated and *out_filename is set
|
||||
* to point to the generated file name
|
||||
* @param out_filenamep Points to a pointer that's set to point to the
|
||||
* pathname of the temporary file; it's allocated with g_malloc()
|
||||
* @param in_file_count the number of input files to merge
|
||||
* @param in_filenames array of input filenames
|
||||
* @param file_type the output filetype
|
||||
|
@ -658,8 +657,9 @@ void cf_unignore_frame(capture_file *cf, frame_data *frame);
|
|||
* @return one of cf_status_t
|
||||
*/
|
||||
cf_status_t
|
||||
cf_merge_files(char **out_filename, int in_file_count,
|
||||
char *const *in_filenames, int file_type, gboolean do_append);
|
||||
cf_merge_files_to_tempfile(char **out_filenamep, int in_file_count,
|
||||
char *const *in_filenames, int file_type,
|
||||
gboolean do_append);
|
||||
|
||||
|
||||
/**
|
||||
|
|
30
mergecap.c
30
mergecap.c
|
@ -257,7 +257,6 @@ main(int argc, char *argv[])
|
|||
#else
|
||||
int file_type = WTAP_FILE_TYPE_SUBTYPE_PCAP; /* default to pcapng format */
|
||||
#endif
|
||||
int out_fd;
|
||||
int err = 0;
|
||||
gchar *err_info = NULL;
|
||||
int err_fileno;
|
||||
|
@ -428,24 +427,20 @@ main(int argc, char *argv[])
|
|||
|
||||
/* open the outfile */
|
||||
if (strcmp(out_filename, "-") == 0) {
|
||||
/* use stdout as the outfile */
|
||||
/* merge the files to the standard output */
|
||||
use_stdout = TRUE;
|
||||
out_fd = 1 /*stdout*/;
|
||||
status = merge_files_to_stdout(file_type,
|
||||
(const char *const *) &argv[optind],
|
||||
in_file_count, do_append, mode, snaplen,
|
||||
"mergecap", verbose ? &cb : NULL,
|
||||
&err, &err_info, &err_fileno);
|
||||
} else {
|
||||
/* open the outfile */
|
||||
out_fd = ws_open(out_filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
|
||||
if (out_fd == -1) {
|
||||
fprintf(stderr, "mergecap: Couldn't open output file %s: %s\n",
|
||||
out_filename, g_strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* merge the files */
|
||||
status = merge_files(out_fd, out_filename, file_type,
|
||||
/* merge the files to the outfile */
|
||||
status = merge_files(out_filename, file_type,
|
||||
(const char *const *) &argv[optind], in_file_count,
|
||||
do_append, mode, snaplen, "mergecap", verbose ? &cb : NULL,
|
||||
&err, &err_info, &err_fileno);
|
||||
}
|
||||
|
||||
switch (status) {
|
||||
case MERGE_OK:
|
||||
|
@ -462,10 +457,13 @@ main(int argc, char *argv[])
|
|||
break;
|
||||
|
||||
case MERGE_ERR_CANT_OPEN_OUTFILE:
|
||||
if (use_stdout) {
|
||||
fprintf(stderr, "mergecap: Can't set up the standard output: %s\n",
|
||||
wtap_strerror(err));
|
||||
} else {
|
||||
fprintf(stderr, "mergecap: Can't open or create %s: %s\n", out_filename,
|
||||
wtap_strerror(err));
|
||||
if (!use_stdout)
|
||||
ws_close(out_fd);
|
||||
}
|
||||
break;
|
||||
|
||||
case MERGE_ERR_CANT_READ_INFILE: /* fall through */
|
||||
|
|
|
@ -912,22 +912,21 @@ file_merge_cmd(GtkWidget *w _U_)
|
|||
file_type = cfile.cd_t;
|
||||
|
||||
/* Try to merge or append the two files */
|
||||
tmpname = NULL;
|
||||
if (merge_type == 0) {
|
||||
/* chronological order */
|
||||
in_filenames[0] = cfile.filename;
|
||||
in_filenames[1] = file_name->str;
|
||||
merge_status = cf_merge_files(&tmpname, 2, in_filenames, file_type, FALSE);
|
||||
merge_status = cf_merge_files_to_tempfile(&tmpname, 2, in_filenames, file_type, FALSE);
|
||||
} else if (merge_type < 0) {
|
||||
/* prepend file */
|
||||
in_filenames[0] = file_name->str;
|
||||
in_filenames[1] = cfile.filename;
|
||||
merge_status = cf_merge_files(&tmpname, 2, in_filenames, file_type, TRUE);
|
||||
merge_status = cf_merge_files_to_tempfile(&tmpname, 2, in_filenames, file_type, TRUE);
|
||||
} else {
|
||||
/* append file */
|
||||
in_filenames[0] = cfile.filename;
|
||||
in_filenames[1] = file_name->str;
|
||||
merge_status = cf_merge_files(&tmpname, 2, in_filenames, file_type, TRUE);
|
||||
merge_status = cf_merge_files_to_tempfile(&tmpname, 2, in_filenames, file_type, TRUE);
|
||||
}
|
||||
|
||||
if (merge_status != CF_OK) {
|
||||
|
|
|
@ -208,8 +208,7 @@ dnd_open_file_cmd(gchar *cf_names_freeme)
|
|||
}
|
||||
} else {
|
||||
/* merge the files in chronological order */
|
||||
tmpname = NULL;
|
||||
if (cf_merge_files(&tmpname, in_file_count, in_filenames,
|
||||
if (cf_merge_files_to_tempfile(&tmpname, in_file_count, in_filenames,
|
||||
WTAP_FILE_TYPE_SUBTYPE_PCAPNG, FALSE) == CF_OK) {
|
||||
/* Merge succeeded; close the currently-open file and try
|
||||
to open the merged capture file. */
|
||||
|
|
|
@ -1075,22 +1075,21 @@ void MainWindow::mergeCaptureFile()
|
|||
file_type = capture_file_.capFile()->cd_t;
|
||||
|
||||
/* Try to merge or append the two files */
|
||||
tmpname = NULL;
|
||||
if (merge_dlg.mergeType() == 0) {
|
||||
/* chronological order */
|
||||
in_filenames[0] = g_strdup(capture_file_.capFile()->filename);
|
||||
in_filenames[1] = qstring_strdup(file_name);
|
||||
merge_status = cf_merge_files(&tmpname, 2, in_filenames, file_type, FALSE);
|
||||
merge_status = cf_merge_files_to_tempfile(&tmpname, 2, in_filenames, file_type, FALSE);
|
||||
} else if (merge_dlg.mergeType() <= 0) {
|
||||
/* prepend file */
|
||||
in_filenames[0] = qstring_strdup(file_name);
|
||||
in_filenames[1] = g_strdup(capture_file_.capFile()->filename);
|
||||
merge_status = cf_merge_files(&tmpname, 2, in_filenames, file_type, TRUE);
|
||||
merge_status = cf_merge_files_to_tempfile(&tmpname, 2, in_filenames, file_type, TRUE);
|
||||
} else {
|
||||
/* append file */
|
||||
in_filenames[0] = g_strdup(capture_file_.capFile()->filename);
|
||||
in_filenames[1] = qstring_strdup(file_name);
|
||||
merge_status = cf_merge_files(&tmpname, 2, in_filenames, file_type, TRUE);
|
||||
merge_status = cf_merge_files_to_tempfile(&tmpname, 2, in_filenames, file_type, TRUE);
|
||||
}
|
||||
|
||||
g_free(in_filenames[0]);
|
||||
|
|
392
wiretap/merge.c
392
wiretap/merge.c
|
@ -122,8 +122,8 @@ add_idb_index_map(merge_in_file_t *in_file, const guint orig_index, const guint
|
|||
*/
|
||||
static gboolean
|
||||
merge_open_in_files(guint in_file_count, const char *const *in_file_names,
|
||||
merge_in_file_t **in_files, int *err, gchar **err_info,
|
||||
guint *err_fileno)
|
||||
merge_in_file_t **in_files, merge_progress_callback_t* cb,
|
||||
int *err, gchar **err_info, guint *err_fileno)
|
||||
{
|
||||
guint i;
|
||||
guint j;
|
||||
|
@ -158,6 +158,10 @@ merge_open_in_files(guint in_file_count, const char *const *in_file_names,
|
|||
files[i].size = size;
|
||||
files[i].idb_index_map = g_array_new(FALSE, FALSE, sizeof(guint));
|
||||
}
|
||||
|
||||
if (cb)
|
||||
cb->callback_func(MERGE_EVENT_INPUT_FILES_OPENED, 0, files, in_file_count, cb->data);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -960,96 +964,19 @@ get_write_error_string(const merge_in_file_t *in_file, const int file_type,
|
|||
return *err_info;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Merges the files based on given input, and invokes callback during
|
||||
* execution. Returns MERGE_OK on success, or a MERGE_ERR_XXX on failure; note
|
||||
* that the passed-in 'err' variable will be more specific to what failed, and
|
||||
* err_info will have pretty output.
|
||||
*/
|
||||
merge_result
|
||||
merge_files(int out_fd, const gchar* out_filename, const int file_type,
|
||||
const char *const *in_filenames, const guint in_file_count,
|
||||
const gboolean do_append, const idb_merge_mode mode,
|
||||
guint snaplen, const gchar *app_name, merge_progress_callback_t* cb,
|
||||
int *err, gchar **err_info, guint *err_fileno)
|
||||
static merge_result
|
||||
merge_process_packets(const gchar* out_filename, wtap_dumper *pdh,
|
||||
const int file_type,
|
||||
merge_in_file_t *in_files, const guint in_file_count,
|
||||
const gboolean do_append, guint snaplen,
|
||||
merge_progress_callback_t* cb,
|
||||
int *err, gchar **err_info)
|
||||
{
|
||||
merge_in_file_t *in_files = NULL, *in_file = NULL;
|
||||
int frame_type = WTAP_ENCAP_PER_PACKET;
|
||||
merge_result status = MERGE_OK;
|
||||
wtap_dumper *pdh;
|
||||
struct wtap_pkthdr *phdr, snap_phdr;
|
||||
merge_in_file_t *in_file;
|
||||
int count = 0;
|
||||
gboolean stop_flag = FALSE;
|
||||
GArray *shb_hdrs = NULL;
|
||||
wtapng_iface_descriptions_t *idb_inf = NULL;
|
||||
|
||||
g_assert(out_fd > 0);
|
||||
g_assert(in_file_count > 0);
|
||||
g_assert(in_filenames != NULL);
|
||||
g_assert(err != NULL);
|
||||
g_assert(err_info != NULL);
|
||||
g_assert(err_fileno != NULL);
|
||||
|
||||
/* if a callback was given, it has to have a callback function ptr */
|
||||
g_assert((cb != NULL) ? (cb->callback_func != NULL) : TRUE);
|
||||
|
||||
merge_debug("merge_files: begin");
|
||||
|
||||
/* open the input files */
|
||||
if (!merge_open_in_files(in_file_count, in_filenames, &in_files,
|
||||
err, err_info, err_fileno)) {
|
||||
merge_debug("merge_files: merge_open_in_files() failed with err=%d", *err);
|
||||
return MERGE_ERR_CANT_OPEN_INFILE;
|
||||
}
|
||||
|
||||
if (cb)
|
||||
cb->callback_func(MERGE_EVENT_INPUT_FILES_OPENED, 0, in_files, in_file_count, cb->data);
|
||||
|
||||
if (snaplen == 0) {
|
||||
/* Snapshot length not specified - default to the maximum. */
|
||||
snaplen = WTAP_MAX_PACKET_SIZE;
|
||||
}
|
||||
|
||||
/*
|
||||
* This doesn't tell us that much. It tells us what to set the outfile's
|
||||
* encap type to, but that's all - for example, it does *not* tells us
|
||||
* whether the input files had the same number of IDBs, for the same exact
|
||||
* interfaces, and only one IDB each, so it doesn't actually tell us
|
||||
* whether we can merge IDBs into one or not.
|
||||
*/
|
||||
frame_type = merge_select_frame_type(in_file_count, in_files);
|
||||
merge_debug("merge_files: got frame_type=%d", frame_type);
|
||||
|
||||
if (cb)
|
||||
cb->callback_func(MERGE_EVENT_FRAME_TYPE_SELECTED, frame_type, in_files, in_file_count, cb->data);
|
||||
|
||||
/* prepare the outfile */
|
||||
if (file_type == WTAP_FILE_TYPE_SUBTYPE_PCAPNG) {
|
||||
shb_hdrs = create_shb_header(in_files, in_file_count, app_name);
|
||||
merge_debug("merge_files: SHB created");
|
||||
|
||||
idb_inf = generate_merged_idb(in_files, in_file_count, mode);
|
||||
merge_debug("merge_files: IDB merge operation complete, got %u IDBs", idb_inf ? idb_inf->interface_data->len : 0);
|
||||
|
||||
pdh = wtap_dump_fdopen_ng(out_fd, file_type, frame_type, snaplen,
|
||||
FALSE /* compressed */, shb_hdrs, idb_inf,
|
||||
NULL, err);
|
||||
}
|
||||
else {
|
||||
pdh = wtap_dump_fdopen(out_fd, file_type, frame_type, snaplen, FALSE /* compressed */, err);
|
||||
}
|
||||
|
||||
if (pdh == NULL) {
|
||||
merge_close_in_files(in_file_count, in_files);
|
||||
g_free(in_files);
|
||||
wtap_block_array_free(shb_hdrs);
|
||||
wtap_free_idb_info(idb_inf);
|
||||
return MERGE_ERR_CANT_OPEN_OUTFILE;
|
||||
}
|
||||
|
||||
if (cb)
|
||||
cb->callback_func(MERGE_EVENT_READY_TO_MERGE, 0, in_files, in_file_count, cb->data);
|
||||
struct wtap_pkthdr *phdr, snap_phdr;
|
||||
|
||||
for (;;) {
|
||||
*err = 0;
|
||||
|
@ -1172,6 +1099,295 @@ merge_files(int out_fd, const gchar* out_filename, const int file_type,
|
|||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Merges the files to an output file whose name is supplied as an argument,
|
||||
* based on given input, and invokes callback during execution. Returns
|
||||
* MERGE_OK on success, or a MERGE_ERR_XXX on failure; note that the passed-in
|
||||
* 'err' variable will be more specific to what failed, and err_info will
|
||||
* have pretty output.
|
||||
*/
|
||||
merge_result
|
||||
merge_files(const gchar* out_filename, const int file_type,
|
||||
const char *const *in_filenames, const guint in_file_count,
|
||||
const gboolean do_append, const idb_merge_mode mode,
|
||||
guint snaplen, const gchar *app_name, merge_progress_callback_t* cb,
|
||||
int *err, gchar **err_info, guint *err_fileno)
|
||||
{
|
||||
merge_in_file_t *in_files = NULL;
|
||||
int frame_type = WTAP_ENCAP_PER_PACKET;
|
||||
merge_result status = MERGE_OK;
|
||||
wtap_dumper *pdh;
|
||||
GArray *shb_hdrs = NULL;
|
||||
wtapng_iface_descriptions_t *idb_inf = NULL;
|
||||
|
||||
g_assert(out_filename != NULL);
|
||||
g_assert(in_file_count > 0);
|
||||
g_assert(in_filenames != NULL);
|
||||
g_assert(err != NULL);
|
||||
g_assert(err_info != NULL);
|
||||
g_assert(err_fileno != NULL);
|
||||
|
||||
/* if a callback was given, it has to have a callback function ptr */
|
||||
g_assert((cb != NULL) ? (cb->callback_func != NULL) : TRUE);
|
||||
|
||||
merge_debug("merge_files: begin");
|
||||
|
||||
/* open the input files */
|
||||
if (!merge_open_in_files(in_file_count, in_filenames, &in_files, cb,
|
||||
err, err_info, err_fileno)) {
|
||||
merge_debug("merge_files: merge_open_in_files() failed with err=%d", *err);
|
||||
return MERGE_ERR_CANT_OPEN_INFILE;
|
||||
}
|
||||
|
||||
if (snaplen == 0) {
|
||||
/* Snapshot length not specified - default to the maximum. */
|
||||
snaplen = WTAP_MAX_PACKET_SIZE;
|
||||
}
|
||||
|
||||
/*
|
||||
* This doesn't tell us that much. It tells us what to set the outfile's
|
||||
* encap type to, but that's all - for example, it does *not* tells us
|
||||
* whether the input files had the same number of IDBs, for the same exact
|
||||
* interfaces, and only one IDB each, so it doesn't actually tell us
|
||||
* whether we can merge IDBs into one or not.
|
||||
*/
|
||||
frame_type = merge_select_frame_type(in_file_count, in_files);
|
||||
merge_debug("merge_files: got frame_type=%d", frame_type);
|
||||
|
||||
if (cb)
|
||||
cb->callback_func(MERGE_EVENT_FRAME_TYPE_SELECTED, frame_type, in_files, in_file_count, cb->data);
|
||||
|
||||
/* prepare the outfile */
|
||||
if (file_type == WTAP_FILE_TYPE_SUBTYPE_PCAPNG) {
|
||||
shb_hdrs = create_shb_header(in_files, in_file_count, app_name);
|
||||
merge_debug("merge_files: SHB created");
|
||||
|
||||
idb_inf = generate_merged_idb(in_files, in_file_count, mode);
|
||||
merge_debug("merge_files: IDB merge operation complete, got %u IDBs", idb_inf ? idb_inf->interface_data->len : 0);
|
||||
|
||||
pdh = wtap_dump_open_ng(out_filename, file_type, frame_type, snaplen,
|
||||
FALSE /* compressed */, shb_hdrs, idb_inf,
|
||||
NULL, err);
|
||||
}
|
||||
else {
|
||||
pdh = wtap_dump_open(out_filename, file_type, frame_type, snaplen,
|
||||
FALSE /* compressed */, err);
|
||||
}
|
||||
|
||||
if (pdh == NULL) {
|
||||
merge_close_in_files(in_file_count, in_files);
|
||||
g_free(in_files);
|
||||
wtap_block_array_free(shb_hdrs);
|
||||
wtap_free_idb_info(idb_inf);
|
||||
return MERGE_ERR_CANT_OPEN_OUTFILE;
|
||||
}
|
||||
|
||||
if (cb)
|
||||
cb->callback_func(MERGE_EVENT_READY_TO_MERGE, 0, in_files, in_file_count, cb->data);
|
||||
|
||||
status = merge_process_packets(out_filename, pdh, file_type, in_files,
|
||||
in_file_count, do_append, snaplen, cb,
|
||||
err, err_info);
|
||||
|
||||
g_free(in_files);
|
||||
wtap_block_array_free(shb_hdrs);
|
||||
wtap_free_idb_info(idb_inf);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Merges the files to a temporary file based on given input, and invokes
|
||||
* callback during execution. Returns MERGE_OK on success, or a MERGE_ERR_XXX
|
||||
* on failure; note that the passed-in 'err' variable will be more specific
|
||||
* to what failed, and err_info will have pretty output.
|
||||
*/
|
||||
merge_result
|
||||
merge_files_to_tempfile(gchar **out_filenamep, const char *pfx,
|
||||
const int file_type, const char *const *in_filenames,
|
||||
const guint in_file_count, const gboolean do_append,
|
||||
const idb_merge_mode mode, guint snaplen,
|
||||
const gchar *app_name, merge_progress_callback_t* cb,
|
||||
int *err, gchar **err_info, guint *err_fileno)
|
||||
{
|
||||
merge_in_file_t *in_files = NULL;
|
||||
int frame_type = WTAP_ENCAP_PER_PACKET;
|
||||
merge_result status = MERGE_OK;
|
||||
wtap_dumper *pdh;
|
||||
GArray *shb_hdrs = NULL;
|
||||
wtapng_iface_descriptions_t *idb_inf = NULL;
|
||||
|
||||
g_assert(out_filenamep != NULL);
|
||||
g_assert(in_file_count > 0);
|
||||
g_assert(in_filenames != NULL);
|
||||
g_assert(err != NULL);
|
||||
g_assert(err_info != NULL);
|
||||
g_assert(err_fileno != NULL);
|
||||
|
||||
/* if a callback was given, it has to have a callback function ptr */
|
||||
g_assert((cb != NULL) ? (cb->callback_func != NULL) : TRUE);
|
||||
|
||||
merge_debug("merge_files: begin");
|
||||
|
||||
/* no temporary file name yet */
|
||||
*out_filenamep = NULL;
|
||||
|
||||
/* open the input files */
|
||||
if (!merge_open_in_files(in_file_count, in_filenames, &in_files, cb,
|
||||
err, err_info, err_fileno)) {
|
||||
merge_debug("merge_files: merge_open_in_files() failed with err=%d", *err);
|
||||
return MERGE_ERR_CANT_OPEN_INFILE;
|
||||
}
|
||||
|
||||
if (snaplen == 0) {
|
||||
/* Snapshot length not specified - default to the maximum. */
|
||||
snaplen = WTAP_MAX_PACKET_SIZE;
|
||||
}
|
||||
|
||||
/*
|
||||
* This doesn't tell us that much. It tells us what to set the outfile's
|
||||
* encap type to, but that's all - for example, it does *not* tells us
|
||||
* whether the input files had the same number of IDBs, for the same exact
|
||||
* interfaces, and only one IDB each, so it doesn't actually tell us
|
||||
* whether we can merge IDBs into one or not.
|
||||
*/
|
||||
frame_type = merge_select_frame_type(in_file_count, in_files);
|
||||
merge_debug("merge_files: got frame_type=%d", frame_type);
|
||||
|
||||
if (cb)
|
||||
cb->callback_func(MERGE_EVENT_FRAME_TYPE_SELECTED, frame_type, in_files, in_file_count, cb->data);
|
||||
|
||||
/* prepare the outfile */
|
||||
if (file_type == WTAP_FILE_TYPE_SUBTYPE_PCAPNG) {
|
||||
shb_hdrs = create_shb_header(in_files, in_file_count, app_name);
|
||||
merge_debug("merge_files: SHB created");
|
||||
|
||||
idb_inf = generate_merged_idb(in_files, in_file_count, mode);
|
||||
merge_debug("merge_files: IDB merge operation complete, got %u IDBs", idb_inf ? idb_inf->interface_data->len : 0);
|
||||
|
||||
pdh = wtap_dump_open_tempfile_ng(out_filenamep, pfx, file_type,
|
||||
frame_type, snaplen,
|
||||
FALSE /* compressed */,
|
||||
shb_hdrs, idb_inf, NULL, err);
|
||||
}
|
||||
else {
|
||||
pdh = wtap_dump_open_tempfile(out_filenamep, pfx, file_type, frame_type,
|
||||
snaplen, FALSE /* compressed */, err);
|
||||
}
|
||||
|
||||
if (pdh == NULL) {
|
||||
merge_close_in_files(in_file_count, in_files);
|
||||
g_free(in_files);
|
||||
wtap_block_array_free(shb_hdrs);
|
||||
wtap_free_idb_info(idb_inf);
|
||||
return MERGE_ERR_CANT_OPEN_OUTFILE;
|
||||
}
|
||||
|
||||
if (cb)
|
||||
cb->callback_func(MERGE_EVENT_READY_TO_MERGE, 0, in_files, in_file_count, cb->data);
|
||||
|
||||
status = merge_process_packets(*out_filenamep, pdh, file_type, in_files,
|
||||
in_file_count, do_append, snaplen, cb,
|
||||
err, err_info);
|
||||
|
||||
g_free(in_files);
|
||||
wtap_block_array_free(shb_hdrs);
|
||||
wtap_free_idb_info(idb_inf);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Merges the files to the standard output based on given input, and invokes
|
||||
* callback during execution. Returns MERGE_OK on success, or a MERGE_ERR_XXX
|
||||
* on failure; note that the passed-in 'err' variable will be more specific
|
||||
* to what failed, and err_info will have pretty output.
|
||||
*/
|
||||
merge_result
|
||||
merge_files_to_stdout(const int file_type, const char *const *in_filenames,
|
||||
const guint in_file_count, const gboolean do_append,
|
||||
const idb_merge_mode mode, guint snaplen,
|
||||
const gchar *app_name, merge_progress_callback_t* cb,
|
||||
int *err, gchar **err_info, guint *err_fileno)
|
||||
{
|
||||
merge_in_file_t *in_files = NULL;
|
||||
int frame_type = WTAP_ENCAP_PER_PACKET;
|
||||
merge_result status = MERGE_OK;
|
||||
wtap_dumper *pdh;
|
||||
GArray *shb_hdrs = NULL;
|
||||
wtapng_iface_descriptions_t *idb_inf = NULL;
|
||||
|
||||
g_assert(in_file_count > 0);
|
||||
g_assert(in_filenames != NULL);
|
||||
g_assert(err != NULL);
|
||||
g_assert(err_info != NULL);
|
||||
g_assert(err_fileno != NULL);
|
||||
|
||||
/* if a callback was given, it has to have a callback function ptr */
|
||||
g_assert((cb != NULL) ? (cb->callback_func != NULL) : TRUE);
|
||||
|
||||
merge_debug("merge_files: begin");
|
||||
|
||||
/* open the input files */
|
||||
if (!merge_open_in_files(in_file_count, in_filenames, &in_files, cb,
|
||||
err, err_info, err_fileno)) {
|
||||
merge_debug("merge_files: merge_open_in_files() failed with err=%d", *err);
|
||||
return MERGE_ERR_CANT_OPEN_INFILE;
|
||||
}
|
||||
|
||||
if (snaplen == 0) {
|
||||
/* Snapshot length not specified - default to the maximum. */
|
||||
snaplen = WTAP_MAX_PACKET_SIZE;
|
||||
}
|
||||
|
||||
/*
|
||||
* This doesn't tell us that much. It tells us what to set the outfile's
|
||||
* encap type to, but that's all - for example, it does *not* tells us
|
||||
* whether the input files had the same number of IDBs, for the same exact
|
||||
* interfaces, and only one IDB each, so it doesn't actually tell us
|
||||
* whether we can merge IDBs into one or not.
|
||||
*/
|
||||
frame_type = merge_select_frame_type(in_file_count, in_files);
|
||||
merge_debug("merge_files: got frame_type=%d", frame_type);
|
||||
|
||||
if (cb)
|
||||
cb->callback_func(MERGE_EVENT_FRAME_TYPE_SELECTED, frame_type, in_files, in_file_count, cb->data);
|
||||
|
||||
/* prepare the outfile */
|
||||
if (file_type == WTAP_FILE_TYPE_SUBTYPE_PCAPNG) {
|
||||
shb_hdrs = create_shb_header(in_files, in_file_count, app_name);
|
||||
merge_debug("merge_files: SHB created");
|
||||
|
||||
idb_inf = generate_merged_idb(in_files, in_file_count, mode);
|
||||
merge_debug("merge_files: IDB merge operation complete, got %u IDBs", idb_inf ? idb_inf->interface_data->len : 0);
|
||||
|
||||
pdh = wtap_dump_open_stdout_ng(file_type, frame_type, snaplen,
|
||||
FALSE /* compressed */, shb_hdrs,
|
||||
idb_inf, NULL, err);
|
||||
}
|
||||
else {
|
||||
pdh = wtap_dump_open_stdout(file_type, frame_type, snaplen,
|
||||
FALSE /* compressed */, err);
|
||||
}
|
||||
|
||||
if (pdh == NULL) {
|
||||
merge_close_in_files(in_file_count, in_files);
|
||||
g_free(in_files);
|
||||
wtap_block_array_free(shb_hdrs);
|
||||
wtap_free_idb_info(idb_inf);
|
||||
return MERGE_ERR_CANT_OPEN_OUTFILE;
|
||||
}
|
||||
|
||||
if (cb)
|
||||
cb->callback_func(MERGE_EVENT_READY_TO_MERGE, 0, in_files, in_file_count, cb->data);
|
||||
|
||||
status = merge_process_packets("standard output", pdh, file_type, in_files,
|
||||
in_file_count, do_append, snaplen, cb,
|
||||
err, err_info);
|
||||
|
||||
g_free(in_files);
|
||||
wtap_block_array_free(shb_hdrs);
|
||||
wtap_free_idb_info(idb_inf);
|
||||
|
|
|
@ -122,10 +122,9 @@ typedef struct {
|
|||
} merge_progress_callback_t;
|
||||
|
||||
|
||||
/** Merge the given input files to the output file descriptor.
|
||||
/** Merge the given input files to a file with the given filename
|
||||
*
|
||||
* @param out_fd The already opened output file decriptor
|
||||
* @param out_filename The output filename, used in error messages
|
||||
* @param out_filename The output filename
|
||||
* @param file_type The WTAP_FILE_TYPE_SUBTYPE_XXX output file type
|
||||
* @param in_filenames An array of input filenames to merge from
|
||||
* @param in_file_count The number of entries in in_filenames
|
||||
|
@ -140,12 +139,60 @@ typedef struct {
|
|||
* @return the frame type
|
||||
*/
|
||||
WS_DLL_PUBLIC merge_result
|
||||
merge_files(int out_fd, const gchar* out_filename, const int file_type,
|
||||
merge_files(const gchar* out_filename, const int file_type,
|
||||
const char *const *in_filenames, const guint in_file_count,
|
||||
const gboolean do_append, const idb_merge_mode mode,
|
||||
guint snaplen, const gchar *app_name, merge_progress_callback_t* cb,
|
||||
int *err, gchar **err_info, guint *err_fileno);
|
||||
|
||||
/** Merge the given input files to a temporary file
|
||||
*
|
||||
* @param out_filenamep Points to a pointer that's set to point to the
|
||||
* pathname of the temporary file; it's allocated with g_malloc()
|
||||
* @param pfx A string to be used as the prefix for the temporary file name
|
||||
* @param file_type The WTAP_FILE_TYPE_SUBTYPE_XXX output file type
|
||||
* @param in_filenames An array of input filenames to merge from
|
||||
* @param in_file_count The number of entries in in_filenames
|
||||
* @param do_append Whether to append by file order instead of chronological order
|
||||
* @param mode The IDB_MERGE_MODE_XXX merge mode for interface data
|
||||
* @param snaplen The snaplen to limit it to, or 0 to leave as it is in the files
|
||||
* @param app_name The application name performing the merge, used in SHB info
|
||||
* @param cb The callback information to use during execution
|
||||
* @param[out] err Set to the internal WTAP_ERR_XXX error code if it failed
|
||||
* @param[out] err_info Set to a descriptive error string, which must be g_free'd
|
||||
* @param[out] err_fileno Set to the input file number which failed, if it failed
|
||||
* @return the frame type
|
||||
*/
|
||||
WS_DLL_PUBLIC merge_result
|
||||
merge_files_to_tempfile(gchar **out_filenamep, const char *pfx,
|
||||
const int file_type, const char *const *in_filenames,
|
||||
const guint in_file_count, const gboolean do_append,
|
||||
const idb_merge_mode mode, guint snaplen,
|
||||
const gchar *app_name, merge_progress_callback_t* cb,
|
||||
int *err, gchar **err_info, guint *err_fileno);
|
||||
|
||||
/** Merge the given input files to the standard output
|
||||
*
|
||||
* @param file_type The WTAP_FILE_TYPE_SUBTYPE_XXX output file type
|
||||
* @param in_filenames An array of input filenames to merge from
|
||||
* @param in_file_count The number of entries in in_filenames
|
||||
* @param do_append Whether to append by file order instead of chronological order
|
||||
* @param mode The IDB_MERGE_MODE_XXX merge mode for interface data
|
||||
* @param snaplen The snaplen to limit it to, or 0 to leave as it is in the files
|
||||
* @param app_name The application name performing the merge, used in SHB info
|
||||
* @param cb The callback information to use during execution
|
||||
* @param[out] err Set to the internal WTAP_ERR_XXX error code if it failed
|
||||
* @param[out] err_info Set to a descriptive error string, which must be g_free'd
|
||||
* @param[out] err_fileno Set to the input file number which failed, if it failed
|
||||
* @return the frame type
|
||||
*/
|
||||
WS_DLL_PUBLIC merge_result
|
||||
merge_files_to_stdout(const int file_type, const char *const *in_filenames,
|
||||
const guint in_file_count, const gboolean do_append,
|
||||
const idb_merge_mode mode, guint snaplen,
|
||||
const gchar *app_name, merge_progress_callback_t* cb,
|
||||
int *err, gchar **err_info, guint *err_fileno);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
|
Loading…
Reference in New Issue