From 0a669967fa719111db64437f7dd3b2869091f9e8 Mon Sep 17 00:00:00 2001 From: Jeff Morriss Date: Tue, 16 Jul 2013 02:35:33 +0000 Subject: Move merge.{h,c} into wiretap: these modules use wiretap to merge files. svn path=/trunk/; revision=50656 --- CMakeLists.txt | 2 - Makefile.common | 5 +- file.c | 27 ++--- merge.c | 287 ---------------------------------------------- merge.h | 128 --------------------- mergecap.c | 12 +- ui/gtk/capture_file_dlg.c | 5 +- ui/gtk/main.c | 3 +- ui/qt/QtShark.pro | 1 - ui/qt/main.cpp | 3 +- ui/win32/file_dlg_win32.c | 8 +- wiretap/CMakeLists.txt | 1 + wiretap/Makefile.common | 2 + wiretap/merge.c | 286 +++++++++++++++++++++++++++++++++++++++++++++ wiretap/merge.h | 130 +++++++++++++++++++++ 15 files changed, 450 insertions(+), 450 deletions(-) delete mode 100644 merge.c delete mode 100644 merge.h create mode 100644 wiretap/merge.c create mode 100644 wiretap/merge.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 06d5bb6290..29f65b6e2b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -762,7 +762,6 @@ if( (BUILD_wireshark AND GTK_FOUND) OR (BUILD_qtshark AND QT_FOUND) ) fileset.c filters.c iface_monitor.c - merge.c proto_hier_stats.c summary.c ws80211_utils.c @@ -927,7 +926,6 @@ if(BUILD_mergecap) ) set(mergecap_FILES mergecap.c - merge.c svnversion.h ${WTAP_PLUGIN_SOURCES} ) diff --git a/Makefile.common b/Makefile.common index dcd139d34a..b4dab9ae88 100644 --- a/Makefile.common +++ b/Makefile.common @@ -97,7 +97,6 @@ WIRESHARK_COMMON_SRC = \ fileset.c \ filters.c \ iface_monitor.c \ - merge.c \ proto_hier_stats.c \ summary.c \ ws80211_utils.c @@ -114,7 +113,6 @@ WIRESHARK_COMMON_INCLUDES = \ globals.h \ iface_monitor.h \ log.h \ - merge.h \ proto_hier_stats.h \ stat_menu.h \ summary.h \ @@ -145,8 +143,7 @@ text2pcap_INCLUDES = \ # mergecap specifics mergecap_SOURCES = \ - mergecap.c \ - merge.c + mergecap.c # editcap specifics editcap_SOURCES = \ diff --git a/file.c b/file.c index 6a0d2ba86d..dfb1d1b0ce 100644 --- a/file.c +++ b/file.c @@ -41,22 +41,17 @@ #include #endif -#include -#include -#include +#include +#include -#include "color.h" -#include "color_filters.h" -#include "cfile.h" +#include + +#include #include #include #include -#include "file.h" -#include "fileset.h" -#include "frame_tvbuff.h" -#include "wsutil/tempfile.h" -#include "merge.h" - +#include +#include #include #include #include @@ -65,10 +60,16 @@ #include #include #include -#include #include #include +#include "color.h" +#include "color_filters.h" +#include "cfile.h" +#include "file.h" +#include "fileset.h" +#include "frame_tvbuff.h" + #include "ui/alert_box.h" #include "ui/simple_dialog.h" #include "ui/main_statusbar.h" diff --git a/merge.c b/merge.c deleted file mode 100644 index f68c4758c8..0000000000 --- a/merge.c +++ /dev/null @@ -1,287 +0,0 @@ -/* Combine multiple dump files, either by appending or by merging by timestamp - * - * Written by Scott Renfro based on - * editcap by Richard Sharpe and Guy Harris - * - * Copyright 2013, Scott Renfro - * - * $Id$ - * - * Wireshark - Network traffic analyzer - * By Gerald Combs - * Copyright 1998 Gerald Combs - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include "config.h" - -#include -#include -#include -#include - -#ifdef HAVE_UNISTD_H -#include -#endif - -#ifdef HAVE_SYS_TIME_H -#include -#endif - -#include -#include "wtap.h" -#include "merge.h" - -/* - * Scan through the arguments and open the input files - */ -gboolean -merge_open_in_files(int in_file_count, char *const *in_file_names, - merge_in_file_t **in_files, int *err, gchar **err_info, - int *err_fileno) -{ - int i, j; - size_t files_size = in_file_count * sizeof(merge_in_file_t); - merge_in_file_t *files; - gint64 size; - - files = (merge_in_file_t *)g_malloc(files_size); - *in_files = files; - - 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].data_offset = 0; - files[i].state = PACKET_NOT_PRESENT; - files[i].packet_num = 0; - if (!files[i].wth) { - /* Close the files we've already opened. */ - for (j = 0; j < i; j++) - wtap_close(files[j].wth); - *err_fileno = i; - return FALSE; - } - size = wtap_file_size(files[i].wth, err); - if (size == -1) { - for (j = 0; j <= i; j++) - wtap_close(files[j].wth); - *err_fileno = i; - return FALSE; - } - files[i].size = size; - } - return TRUE; -} - -/* - * Scan through and close each input file - */ -void -merge_close_in_files(int count, merge_in_file_t in_files[]) -{ - int i; - for (i = 0; i < count; i++) { - wtap_close(in_files[i].wth); - } -} - -/* - * 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 - * output file type doesn't support per packet frame types, - * then the wtap_dump_open call will fail with a reasonable - * error condition. - */ -int -merge_select_frame_type(int count, merge_in_file_t files[]) -{ - int i; - int selected_frame_type; - - selected_frame_type = wtap_file_encap(files[0].wth); - - for (i = 1; i < count; i++) { - int this_frame_type = wtap_file_encap(files[i].wth); - if (selected_frame_type != this_frame_type) { - selected_frame_type = WTAP_ENCAP_PER_PACKET; - break; - } - } - - return selected_frame_type; -} - -/* - * Scan through input files and find maximum snapshot length - */ -int -merge_max_snapshot_length(int count, merge_in_file_t in_files[]) -{ - int i; - int max_snapshot = 0; - int snapshot_length; - - for (i = 0; i < count; i++) { - snapshot_length = wtap_snapshot_length(in_files[i].wth); - if (snapshot_length == 0) { - /* Snapshot length of input file not known. */ - snapshot_length = WTAP_MAX_PACKET_SIZE; - } - if (snapshot_length > max_snapshot) - max_snapshot = snapshot_length; - } - return max_snapshot; -} - -/* - * returns TRUE if first argument is earlier than second - */ -static gboolean -is_earlier(struct wtap_nstime *l, struct wtap_nstime *r) { - if (l->secs > r->secs) { /* left is later */ - return FALSE; - } else if (l->secs < r->secs) { /* left is earlier */ - return TRUE; - } else if (l->nsecs > r->nsecs) { /* tv_sec equal, l.usec later */ - return FALSE; - } - /* either one < two or one == two - * either way, return one - */ - return TRUE; -} - -/* - * Read the next packet, in chronological order, from the set of files - * to be merged. - * - * On success, set *err to 0 and return a pointer to the merge_in_file_t - * for the file from which the packet was read. - * - * On a read error, set *err to the error and return a pointer to the - * merge_in_file_t for the file on which we got an error. - * - * On an EOF (meaning all the files are at EOF), set *err to 0 and return - * NULL. - */ -merge_in_file_t * -merge_read_packet(int in_file_count, merge_in_file_t in_files[], - int *err, gchar **err_info) -{ - int i; - int ei = -1; - struct wtap_nstime tv = { sizeof(time_t) > sizeof(int) ? LONG_MAX : INT_MAX, INT_MAX }; - struct wtap_pkthdr *phdr; - - /* - * 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 &in_files[i]; - } - 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; - } - } - } - - if (ei == -1) { - /* All the streams are at EOF. Return an EOF indication. */ - *err = 0; - return NULL; - } - - /* We'll need to read another packet from this file. */ - in_files[ei].state = PACKET_NOT_PRESENT; - - /* Count this packet. */ - in_files[ei].packet_num++; - - /* - * Return a pointer to the merge_in_file_t of the file from which the - * packet was read. - */ - *err = 0; - return &in_files[ei]; -} - -/* - * Read the next packet, in file sequence order, from the set of files - * to be merged. - * - * On success, set *err to 0 and return a pointer to the merge_in_file_t - * for the file from which the packet was read. - * - * On a read error, set *err to the error and return a pointer to the - * merge_in_file_t for the file on which we got an error. - * - * On an EOF (meaning all the files are at EOF), set *err to 0 and return - * NULL. - */ -merge_in_file_t * -merge_append_read_packet(int in_file_count, merge_in_file_t in_files[], - int *err, gchar **err_info) -{ - int i; - - /* - * 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 &in_files[i]; - } - /* 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 a pointer to the merge_in_file_t of the file from which the - * packet was read. - */ - *err = 0; - return &in_files[i]; -} diff --git a/merge.h b/merge.h deleted file mode 100644 index a9a36f2c93..0000000000 --- a/merge.h +++ /dev/null @@ -1,128 +0,0 @@ -/* merge.h - * Definitions for routines for merging files. - * - * $Id$ - * - * Wireshark - Network traffic analyzer - * By Gerald Combs - * Copyright 1998 Gerald Combs - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef __MERGE_H__ -#define __MERGE_H__ - -#ifdef __cplusplus -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; - gint64 data_offset; - in_file_state_e state; - guint32 packet_num; /* current packet number */ - gint64 size; /* file size */ - guint32 interface_id; /* identifier of the interface. - * Used for fake interfaces when writing WTAP_ENCAP_PER_PACKET */ -} merge_in_file_t; - -/** Open a number of input files to merge. - * - * @param in_file_count number of entries in in_file_names and in_files - * @param in_file_names filenames of the input files - * @param in_files input file array to be filled (>= sizeof(merge_in_file_t) * in_file_count) - * @param err wiretap error, if failed - * @param err_info wiretap error string, if failed - * @param err_fileno file on which open failed, if failed - * @return TRUE if all files could be opened, FALSE otherwise - */ -extern gboolean -merge_open_in_files(int in_file_count, char *const *in_file_names, - merge_in_file_t **in_files, int *err, gchar **err_info, - int *err_fileno); - -/** Close the input files again. - * - * @param in_file_count number of entries in in_files - * @param in_files input file array to be closed - */ -extern void -merge_close_in_files(int in_file_count, merge_in_file_t in_files[]); - -/** Try to get the frame type from the input files. - * - * @param in_file_count number of entries in in_files - * @param in_files input file array - * @return the frame type - */ -extern int -merge_select_frame_type(int in_file_count, merge_in_file_t in_files[]); - -/** Try to get the snapshot length from the input files. - * - * @param in_file_count number of entries in in_files - * @param in_files input file array - * @return the snapshot length - */ -extern int -merge_max_snapshot_length(int in_file_count, merge_in_file_t in_files[]); - -/** 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 err wiretap error, if failed - * @param err_info wiretap error string, if failed - * @return pointer to merge_in_file_t for file from which that packet - * came, or NULL on error or EOF - */ -extern merge_in_file_t * -merge_read_packet(int in_file_count, merge_in_file_t in_files[], int *err, - gchar **err_info); - - -/** 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 err wiretap error, if failed - * @param err_info wiretap error string, if failed - * @return pointer to merge_in_file_t for file from which that packet - * came, or NULL on error or EOF - */ -extern merge_in_file_t * -merge_append_read_packet(int in_file_count, merge_in_file_t in_files[], - int *err, gchar **err_info); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __MERGE_H__ */ - diff --git a/mergecap.c b/mergecap.c index 35609ee074..e8cae5d43f 100644 --- a/mergecap.c +++ b/mergecap.c @@ -44,19 +44,15 @@ #include "wtap.h" #ifndef HAVE_GETOPT -#include "wsutil/wsgetopt.h" +#include #endif -#include "wsutil/strnatcmp.h" +#include +#include -#define WS_BUILD_DLL -#define RESET_SYMBOL_EXPORT /* wsutil/wsgetopt.h set export behavior above. */ -#undef WS_BUILD_DLL -#define RESET_SYMBOL_EXPORT +#include #include "svnversion.h" -#include "merge.h" -#include "wsutil/file_util.h" #ifdef HAVE_FCNTL_H #include diff --git a/ui/gtk/capture_file_dlg.c b/ui/gtk/capture_file_dlg.c index 6d24dff82c..0c97311512 100644 --- a/ui/gtk/capture_file_dlg.c +++ b/ui/gtk/capture_file_dlg.c @@ -39,11 +39,12 @@ #include "globals.h" #include "color.h" #include "color_filters.h" -#include "merge.h" -#include "ui/util.h" #include +#include + +#include "ui/util.h" #include "ui/alert_box.h" #include "ui/file_dialog.h" #include "ui/recent.h" diff --git a/ui/gtk/main.c b/ui/gtk/main.c index 8aa1c6792b..ab137a2d97 100644 --- a/ui/gtk/main.c +++ b/ui/gtk/main.c @@ -68,6 +68,8 @@ #include #include +#include + #include #include #include @@ -103,7 +105,6 @@ #include "../clopts_common.h" #include "../cmdarg_err.h" #include "../version_info.h" -#include "../merge.h" #include "../log.h" #include "gtk_iface_monitor.h" diff --git a/ui/qt/QtShark.pro b/ui/qt/QtShark.pro index c590d0643f..dad81c2af3 100644 --- a/ui/qt/QtShark.pro +++ b/ui/qt/QtShark.pro @@ -177,7 +177,6 @@ SOURCES_WS_C = \ ../../filters.c \ ../../frame_tvbuff.c \ ../../g711.c \ - ../../merge.c \ ../../proto_hier_stats.c \ ../../summary.c \ ../../sync_pipe_write.c \ diff --git a/ui/qt/main.cpp b/ui/qt/main.cpp index ba271236a4..9f497e9803 100644 --- a/ui/qt/main.cpp +++ b/ui/qt/main.cpp @@ -44,6 +44,8 @@ #include #include +#include + #include #include #include @@ -79,7 +81,6 @@ #include "clopts_common.h" #include "cmdarg_err.h" #include "version_info.h" -#include "merge.h" #include "log.h" #include "ui/alert_box.h" diff --git a/ui/win32/file_dlg_win32.c b/ui/win32/file_dlg_win32.c index c9fa01b997..955767f156 100644 --- a/ui/win32/file_dlg_win32.c +++ b/ui/win32/file_dlg_win32.c @@ -40,16 +40,18 @@ #include +#include "wsutil/file_util.h" +#include "wsutil/unicode-utils.h" + +#include "wiretap/merge.h" + #include "epan/filesystem.h" #include "epan/addr_resolv.h" #include "epan/prefs.h" #include "epan/print.h" -#include "wsutil/file_util.h" -#include "wsutil/unicode-utils.h" #include "color.h" #include "color_filters.h" -#include "merge.h" #include "ui/alert_box.h" #include "ui/help_url.h" diff --git a/wiretap/CMakeLists.txt b/wiretap/CMakeLists.txt index 1ddbcfdbf1..4dcacdbd46 100644 --- a/wiretap/CMakeLists.txt +++ b/wiretap/CMakeLists.txt @@ -50,6 +50,7 @@ set(WIRETAP_FILES k12.c lanalyzer.c libpcap.c + merge.c mpeg.c mime_file.c mp2t.c diff --git a/wiretap/Makefile.common b/wiretap/Makefile.common index 8726adbb2e..eb54501c61 100644 --- a/wiretap/Makefile.common +++ b/wiretap/Makefile.common @@ -57,6 +57,7 @@ NONGENERATED_C_FILES = \ k12.c \ lanalyzer.c \ libpcap.c \ + merge.c \ mpeg.c \ mp2t.c \ netmon.c \ @@ -113,6 +114,7 @@ NONGENERATED_HEADER_FILES = \ lanalyzer.h \ libpcap.h \ mpeg.h \ + mpeg.h \ mp2t.h \ netmon.h \ netscreen.h \ diff --git a/wiretap/merge.c b/wiretap/merge.c new file mode 100644 index 0000000000..264f66c3ed --- /dev/null +++ b/wiretap/merge.c @@ -0,0 +1,286 @@ +/* Combine multiple dump files, either by appending or by merging by timestamp + * + * Written by Scott Renfro based on + * editcap by Richard Sharpe and Guy Harris + * + * Copyright 2013, Scott Renfro + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" + +#include +#include +#include +#include + +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef HAVE_SYS_TIME_H +#include +#endif + +#include +#include "merge.h" + +/* + * Scan through the arguments and open the input files + */ +gboolean +merge_open_in_files(int in_file_count, char *const *in_file_names, + merge_in_file_t **in_files, int *err, gchar **err_info, + int *err_fileno) +{ + int i, j; + size_t files_size = in_file_count * sizeof(merge_in_file_t); + merge_in_file_t *files; + gint64 size; + + files = (merge_in_file_t *)g_malloc(files_size); + *in_files = files; + + 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].data_offset = 0; + files[i].state = PACKET_NOT_PRESENT; + files[i].packet_num = 0; + if (!files[i].wth) { + /* Close the files we've already opened. */ + for (j = 0; j < i; j++) + wtap_close(files[j].wth); + *err_fileno = i; + return FALSE; + } + size = wtap_file_size(files[i].wth, err); + if (size == -1) { + for (j = 0; j <= i; j++) + wtap_close(files[j].wth); + *err_fileno = i; + return FALSE; + } + files[i].size = size; + } + return TRUE; +} + +/* + * Scan through and close each input file + */ +void +merge_close_in_files(int count, merge_in_file_t in_files[]) +{ + int i; + for (i = 0; i < count; i++) { + wtap_close(in_files[i].wth); + } +} + +/* + * 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 + * output file type doesn't support per packet frame types, + * then the wtap_dump_open call will fail with a reasonable + * error condition. + */ +int +merge_select_frame_type(int count, merge_in_file_t files[]) +{ + int i; + int selected_frame_type; + + selected_frame_type = wtap_file_encap(files[0].wth); + + for (i = 1; i < count; i++) { + int this_frame_type = wtap_file_encap(files[i].wth); + if (selected_frame_type != this_frame_type) { + selected_frame_type = WTAP_ENCAP_PER_PACKET; + break; + } + } + + return selected_frame_type; +} + +/* + * Scan through input files and find maximum snapshot length + */ +int +merge_max_snapshot_length(int count, merge_in_file_t in_files[]) +{ + int i; + int max_snapshot = 0; + int snapshot_length; + + for (i = 0; i < count; i++) { + snapshot_length = wtap_snapshot_length(in_files[i].wth); + if (snapshot_length == 0) { + /* Snapshot length of input file not known. */ + snapshot_length = WTAP_MAX_PACKET_SIZE; + } + if (snapshot_length > max_snapshot) + max_snapshot = snapshot_length; + } + return max_snapshot; +} + +/* + * returns TRUE if first argument is earlier than second + */ +static gboolean +is_earlier(struct wtap_nstime *l, struct wtap_nstime *r) { + if (l->secs > r->secs) { /* left is later */ + return FALSE; + } else if (l->secs < r->secs) { /* left is earlier */ + return TRUE; + } else if (l->nsecs > r->nsecs) { /* tv_sec equal, l.usec later */ + return FALSE; + } + /* either one < two or one == two + * either way, return one + */ + return TRUE; +} + +/* + * Read the next packet, in chronological order, from the set of files + * to be merged. + * + * On success, set *err to 0 and return a pointer to the merge_in_file_t + * for the file from which the packet was read. + * + * On a read error, set *err to the error and return a pointer to the + * merge_in_file_t for the file on which we got an error. + * + * On an EOF (meaning all the files are at EOF), set *err to 0 and return + * NULL. + */ +merge_in_file_t * +merge_read_packet(int in_file_count, merge_in_file_t in_files[], + int *err, gchar **err_info) +{ + int i; + int ei = -1; + struct wtap_nstime tv = { sizeof(time_t) > sizeof(int) ? LONG_MAX : INT_MAX, INT_MAX }; + struct wtap_pkthdr *phdr; + + /* + * 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 &in_files[i]; + } + 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; + } + } + } + + if (ei == -1) { + /* All the streams are at EOF. Return an EOF indication. */ + *err = 0; + return NULL; + } + + /* We'll need to read another packet from this file. */ + in_files[ei].state = PACKET_NOT_PRESENT; + + /* Count this packet. */ + in_files[ei].packet_num++; + + /* + * Return a pointer to the merge_in_file_t of the file from which the + * packet was read. + */ + *err = 0; + return &in_files[ei]; +} + +/* + * Read the next packet, in file sequence order, from the set of files + * to be merged. + * + * On success, set *err to 0 and return a pointer to the merge_in_file_t + * for the file from which the packet was read. + * + * On a read error, set *err to the error and return a pointer to the + * merge_in_file_t for the file on which we got an error. + * + * On an EOF (meaning all the files are at EOF), set *err to 0 and return + * NULL. + */ +merge_in_file_t * +merge_append_read_packet(int in_file_count, merge_in_file_t in_files[], + int *err, gchar **err_info) +{ + int i; + + /* + * 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 &in_files[i]; + } + /* 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 a pointer to the merge_in_file_t of the file from which the + * packet was read. + */ + *err = 0; + return &in_files[i]; +} diff --git a/wiretap/merge.h b/wiretap/merge.h new file mode 100644 index 0000000000..12be91bc12 --- /dev/null +++ b/wiretap/merge.h @@ -0,0 +1,130 @@ +/* merge.h + * Definitions for routines for merging files. + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __MERGE_H__ +#define __MERGE_H__ + +#include "wiretap/wtap.h" + +#ifdef __cplusplus +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; + gint64 data_offset; + in_file_state_e state; + guint32 packet_num; /* current packet number */ + gint64 size; /* file size */ + guint32 interface_id; /* identifier of the interface. + * Used for fake interfaces when writing WTAP_ENCAP_PER_PACKET */ +} merge_in_file_t; + +/** Open a number of input files to merge. + * + * @param in_file_count number of entries in in_file_names and in_files + * @param in_file_names filenames of the input files + * @param in_files input file array to be filled (>= sizeof(merge_in_file_t) * in_file_count) + * @param err wiretap error, if failed + * @param err_info wiretap error string, if failed + * @param err_fileno file on which open failed, if failed + * @return TRUE if all files could be opened, FALSE otherwise + */ +WS_DLL_PUBLIC gboolean +merge_open_in_files(int in_file_count, char *const *in_file_names, + merge_in_file_t **in_files, int *err, gchar **err_info, + int *err_fileno); + +/** Close the input files again. + * + * @param in_file_count number of entries in in_files + * @param in_files input file array to be closed + */ +WS_DLL_PUBLIC void +merge_close_in_files(int in_file_count, merge_in_file_t in_files[]); + +/** Try to get the frame type from the input files. + * + * @param in_file_count number of entries in in_files + * @param in_files input file array + * @return the frame type + */ +WS_DLL_PUBLIC int +merge_select_frame_type(int in_file_count, merge_in_file_t in_files[]); + +/** Try to get the snapshot length from the input files. + * + * @param in_file_count number of entries in in_files + * @param in_files input file array + * @return the snapshot length + */ +WS_DLL_PUBLIC int +merge_max_snapshot_length(int in_file_count, merge_in_file_t in_files[]); + +/** 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 err wiretap error, if failed + * @param err_info wiretap error string, if failed + * @return pointer to merge_in_file_t for file from which that packet + * came, or NULL on error or EOF + */ +WS_DLL_PUBLIC merge_in_file_t * +merge_read_packet(int in_file_count, merge_in_file_t in_files[], int *err, + gchar **err_info); + + +/** 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 err wiretap error, if failed + * @param err_info wiretap error string, if failed + * @return pointer to merge_in_file_t for file from which that packet + * came, or NULL on error or EOF + */ +WS_DLL_PUBLIC merge_in_file_t * +merge_append_read_packet(int in_file_count, merge_in_file_t in_files[], + int *err, gchar **err_info); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __MERGE_H__ */ + -- cgit v1.2.3