/* file.c
* File I/O routines
*
- * $Id: file.c,v 1.90 1999/09/12 06:11:34 guy Exp $
+ * $Id: file.c,v 1.112 1999/10/22 08:30:02 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
+#include <signal.h>
#ifdef NEED_SNPRINTF_H
# ifdef HAVE_STDARG_H
# include <netinet/in.h>
#endif
+#ifdef HAVE_SYS_WAIT_H
+# include <sys/wait.h>
+#endif
+
#include "gtk/main.h"
#include "column.h"
#include "gtk/menu.h"
#include "gtk/proto_draw.h"
#include "dfilter.h"
#include "timestamp.h"
+#include "conversation.h"
+
+#ifndef __RESOLV_H__
+#include "resolv.h"
+#endif
+
+#include "packet-atalk.h"
+
+#include "packet-ipv6.h"
#include "packet-ncp.h"
extern GtkWidget *packet_list, *prog_bar, *info_bar, *byte_view, *tree_view;
extern guint file_ctx;
-extern int sync_mode;
extern int sync_pipe[];
guint cap_input_id;
+gboolean auto_scroll_live = FALSE;
static guint32 firstsec, firstusec;
static guint32 prevsec, prevusec;
open_cap_file(char *fname, capture_file *cf) {
wtap *wth;
int err;
- FILE *fh;
+ FILE_T fh;
+ int fd;
struct stat cf_stat;
wth = wtap_open_offline(fname, &err);
/* Find the size of the file. */
fh = wtap_file(wth);
- if (fstat(fileno(fh), &cf_stat) < 0) {
+ fd = wtap_fd(wth);
+ if (fstat(fd, &cf_stat) < 0) {
err = errno;
wtap_close(wth);
goto fail;
and fill in the information for this file. */
close_cap_file(cf, info_bar, file_ctx);
+ /* Initialize the table of conversations. */
+ conversation_init();
+
/* Initialize protocol-specific variables */
+ afs_init_protocol();
ncp_init_protocol();
+ smb_init_protocol();
cf->wth = wth;
cf->fh = fh;
+ cf->filed = fd;
cf->f_len = cf_stat.st_size;
/* set the file name because we need it to set the follow stream filter */
frame_data *fd, *fd_next;
if (cf->fh) {
- fclose(cf->fh);
+ file_close(cf->fh);
cf->fh = NULL;
}
if (cf->wth) {
success = wtap_loop(cf->wth, 0, wtap_dispatch_cb, (u_char *) cf, &err);
wtap_close(cf->wth);
cf->wth = NULL;
- cf->fh = fopen(cf->filename, "r");
+ cf->filed = open(cf->filename, O_RDONLY);
+ cf->fh = filed_open(cf->filed, "r");
+ cf->unfiltered_count = cf->count;
thaw_clist(cf);
-
- gtk_progress_bar_update(GTK_PROGRESS_BAR(prog_bar), 0);
+
+ gtk_progress_set_activity_mode(GTK_PROGRESS(prog_bar), FALSE);
+ gtk_progress_set_value(GTK_PROGRESS(prog_bar), 0);
gtk_statusbar_pop(GTK_STATUSBAR(info_bar), file_ctx);
cap_file_input_cb (gpointer data, gint source, GdkInputCondition condition) {
capture_file *cf = (capture_file *)data;
- char buffer[256], *p = buffer, *q = buffer;
+ char buffer[256+1], *p = buffer, *q = buffer;
int nread;
int to_read = 0;
gboolean exit_loop = FALSE;
int err;
+ int wstatus;
+ int wsignal;
+ char *msg;
+ char *sigmsg;
+ char sigmsg_buf[6+1+3+1];
+ char *coredumped;
/* avoid reentrancy problems and stack overflow */
gtk_input_remove(cap_input_id);
if ((nread = read(sync_pipe[0], buffer, 256)) <= 0) {
/* The child has closed the sync pipe, meaning it's not going to be
- capturing any more packets. Read what remains of the capture file,
- and stop capture (restore menu items) */
+ capturing any more packets. Pick up its exit status, and
+ complain if it died of a signal. */
+ if (wait(&wstatus) != -1) {
+ /* XXX - are there any platforms on which we can run that *don't*
+ support POSIX.1's <sys/wait.h> and macros therein? */
+ wsignal = wstatus & 0177;
+ coredumped = "";
+ if (wstatus == 0177) {
+ /* It stopped, rather than exiting. "Should not happen." */
+ msg = "stopped";
+ wsignal = (wstatus >> 8) & 0xFF;
+ } else {
+ msg = "terminated";
+ if (wstatus & 0200)
+ coredumped = " - core dumped";
+ }
+ if (wsignal != 0) {
+ switch (wsignal) {
+
+ case SIGHUP:
+ sigmsg = "Hangup";
+ break;
+
+ case SIGINT:
+ sigmsg = "Interrupted";
+ break;
+
+ case SIGQUIT:
+ sigmsg = "Quit";
+ break;
+
+ case SIGILL:
+ sigmsg = "Illegal instruction";
+ break;
+
+ case SIGTRAP:
+ sigmsg = "Trace trap";
+ break;
+
+ case SIGABRT:
+ sigmsg = "Abort";
+ break;
+
+ case SIGFPE:
+ sigmsg = "Arithmetic exception";
+ break;
+
+ case SIGKILL:
+ sigmsg = "Killed";
+ break;
+
+ case SIGBUS:
+ sigmsg = "Bus error";
+ break;
+
+ case SIGSEGV:
+ sigmsg = "Segmentation violation";
+ break;
+
+ /* http://metalab.unc.edu/pub/Linux/docs/HOWTO/GCC-HOWTO
+ Linux is POSIX compliant. These are not POSIX-defined signals ---
+ ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990), paragraph B.3.3.1.1 sez:
+
+ ``The signals SIGBUS, SIGEMT, SIGIOT, SIGTRAP, and SIGSYS
+ were omitted from POSIX.1 because their behavior is
+ implementation dependent and could not be adequately catego-
+ rized. Conforming implementations may deliver these sig-
+ nals, but must document the circumstances under which they
+ are delivered and note any restrictions concerning their
+ delivery.''
+ */
+
+ #ifdef SIGSYS
+ case SIGSYS:
+ sigmsg = "Bad system call";
+ break;
+ #endif
+
+ case SIGPIPE:
+ sigmsg = "Broken pipe";
+ break;
+
+ case SIGALRM:
+ sigmsg = "Alarm clock";
+ break;
+
+ case SIGTERM:
+ sigmsg = "Terminated";
+ break;
+
+ default:
+ sprintf(sigmsg_buf, "Signal %d", wsignal);
+ sigmsg = sigmsg_buf;
+ break;
+ }
+ simple_dialog(ESD_TYPE_WARN, NULL,
+ "Child capture process %s: %s%s", msg, sigmsg, coredumped);
+ }
+ }
+
+ /* Read what remains of the capture file, and stop capture (restore
+ menu items) */
gtk_clist_freeze(GTK_CLIST(packet_list));
/* XXX - do something if this fails? */
wtap_loop(cf->wth, 0, wtap_dispatch_cb, (u_char *) cf, &err);
thaw_clist(cf);
+ if (auto_scroll_live)
+ gtk_clist_moveto(GTK_CLIST(packet_list),
+ cf->plist_end->row, -1, 1.0, 1.0);
wtap_close(cf->wth);
cf->wth = NULL;
set_menu_sensitivity("/File/Save As...", TRUE);
set_menu_sensitivity("/File/Print...", TRUE);
set_menu_sensitivity("/File/Reload", TRUE);
-#ifdef HAVE_LIBPCAP
set_menu_sensitivity("/Capture/Start...", TRUE);
-#endif
set_menu_sensitivity("/Tools/Summary", TRUE);
gtk_statusbar_push(GTK_STATUSBAR(info_bar), file_ctx, " File: <none>");
return;
/* XXX - do something if this fails? */
wtap_loop(cf->wth, to_read, wtap_dispatch_cb, (u_char *) cf, &err);
gtk_clist_thaw(GTK_CLIST(packet_list));
+ if (auto_scroll_live)
+ gtk_clist_moveto(GTK_CLIST(packet_list), cf->plist_end->row, -1, 1.0, 1.0);
/* restore pipe handler */
cap_input_id = gtk_input_add_full (sync_pipe[0],
set_menu_sensitivity("/File/Open...", FALSE);
set_menu_sensitivity("/Display/Options...", TRUE);
-#ifdef HAVE_LIBPCAP
set_menu_sensitivity("/Capture/Start...", FALSE);
-#endif
for (i = 0; i < cf->cinfo.num_cols; i++) {
if (get_column_resize_type(cf->cinfo.col_fmt[i]) == RESIZE_LIVE)
}
}
- cf->fh = fopen(fname, "r");
+ cf->fh = file_open(fname, "r");
cap_input_id = gtk_input_add_full (sync_pipe[0],
GDK_INPUT_READ,
}
return err;
}
-#endif
+#endif /* HAVE_LIBPCAP */
/* To do: Add check_col checks to the col_add* routines */
static void
-col_add_abs_time(frame_data *fd, gint el)
+col_set_abs_time(frame_data *fd, int col)
{
struct tm *tmp;
time_t then;
then = fd->abs_secs;
tmp = localtime(&then);
- col_add_fstr(fd, el, "%02d:%02d:%02d.%04ld",
+ snprintf(fd->cinfo->col_data[col], COL_MAX_LEN, "%02d:%02d:%02d.%04ld",
tmp->tm_hour,
tmp->tm_min,
tmp->tm_sec,
}
static void
-col_add_rel_time(frame_data *fd, gint el)
+col_set_rel_time(frame_data *fd, int col)
{
- col_add_fstr(fd, el, "%d.%06d", fd->rel_secs, fd->rel_usecs);
+ snprintf(fd->cinfo->col_data[col], COL_MAX_LEN, "%d.%06d", fd->rel_secs,
+ fd->rel_usecs);
}
static void
-col_add_delta_time(frame_data *fd, gint el)
+col_set_delta_time(frame_data *fd, int col)
{
- col_add_fstr(fd, el, "%d.%06d", fd->del_secs, fd->del_usecs);
+ snprintf(fd->cinfo->col_data[col], COL_MAX_LEN, "%d.%06d", fd->del_secs,
+ fd->del_usecs);
}
/* Add "command-line-specified" time. */
static void
-col_add_cls_time(frame_data *fd)
+col_set_cls_time(frame_data *fd, int col)
{
switch (timestamp_type) {
case ABSOLUTE:
- col_add_abs_time(fd, COL_CLS_TIME);
+ col_set_abs_time(fd, col);
break;
case RELATIVE:
- col_add_rel_time(fd, COL_CLS_TIME);
+ col_set_rel_time(fd, col);
break;
case DELTA:
- col_add_delta_time(fd, COL_CLS_TIME);
+ col_set_delta_time(fd, col);
break;
}
}
+static void
+col_set_addr(frame_data *fd, int col, address *addr, gboolean is_res)
+{
+ u_int ipv4_addr;
+ struct e_in6_addr ipv6_addr;
+ struct atalk_ddp_addr ddp_addr;
+
+ switch (addr->type) {
+
+ case AT_ETHER:
+ if (is_res)
+ strncpy(fd->cinfo->col_data[col], get_ether_name(addr->data), COL_MAX_LEN);
+ else
+ strncpy(fd->cinfo->col_data[col], ether_to_str(addr->data), COL_MAX_LEN);
+ break;
+
+ case AT_IPv4:
+ memcpy(&ipv4_addr, addr->data, sizeof ipv4_addr);
+ if (is_res)
+ strncpy(fd->cinfo->col_data[col], get_hostname(ipv4_addr), COL_MAX_LEN);
+ else
+ strncpy(fd->cinfo->col_data[col], ip_to_str(addr->data), COL_MAX_LEN);
+ break;
+
+ case AT_IPv6:
+ memcpy(&ipv6_addr.s6_addr, addr->data, sizeof ipv6_addr.s6_addr);
+ if (is_res)
+ strncpy(fd->cinfo->col_data[col], get_hostname6(&ipv6_addr), COL_MAX_LEN);
+ else
+ strncpy(fd->cinfo->col_data[col], ip6_to_str(&ipv6_addr), COL_MAX_LEN);
+ break;
+
+ case AT_IPX:
+ strncpy(fd->cinfo->col_data[col],
+ ipx_addr_to_str(pntohl(&addr->data[0]), &addr->data[4]), COL_MAX_LEN);
+ break;
+
+ case AT_SNA:
+ switch (addr->len) {
+
+ case 1:
+ snprintf(fd->cinfo->col_data[col], COL_MAX_LEN, "%04X", addr->data[0]);
+ break;
+
+ case 2:
+ snprintf(fd->cinfo->col_data[col], COL_MAX_LEN, "%04X",
+ pntohs(&addr->data[0]));
+ break;
+ }
+ break;
+
+ case AT_ATALK:
+ memcpy(&ddp_addr, addr->data, sizeof ddp_addr);
+ strncpy(fd->cinfo->col_data[col], atalk_addr_to_str(&ddp_addr),
+ COL_MAX_LEN);
+ break;
+
+ case AT_VINES:
+ strncpy(fd->cinfo->col_data[col], vines_addr_to_str(&addr->data[0]),
+ COL_MAX_LEN);
+ break;
+
+ default:
+ break;
+ }
+ fd->cinfo->col_data[col][COL_MAX_LEN - 1] = '\0';
+}
+
+static void
+col_set_port(frame_data *fd, int col, port_type ptype, guint32 port,
+ gboolean is_res)
+{
+ switch (ptype) {
+
+ case PT_TCP:
+ if (is_res)
+ strncpy(fd->cinfo->col_data[col], get_tcp_port(port), COL_MAX_LEN);
+ else
+ snprintf(fd->cinfo->col_data[col], COL_MAX_LEN, "%u", port);
+ break;
+
+ case PT_UDP:
+ if (is_res)
+ strncpy(fd->cinfo->col_data[col], get_udp_port(port), COL_MAX_LEN);
+ else
+ snprintf(fd->cinfo->col_data[col], COL_MAX_LEN, "%u", port);
+ break;
+
+ default:
+ break;
+ }
+ fd->cinfo->col_data[col][COL_MAX_LEN - 1] = '\0';
+}
+
static void
fill_in_columns(frame_data *fd)
{
- if (check_col(fd, COL_NUMBER))
- col_add_fstr(fd, COL_NUMBER, "%u", fd->num);
-
- /* Set any time stamp columns. */
- if (check_col(fd, COL_CLS_TIME))
- col_add_cls_time(fd);
- if (check_col(fd, COL_ABS_TIME))
- col_add_abs_time(fd, COL_ABS_TIME);
- if (check_col(fd, COL_REL_TIME))
- col_add_rel_time(fd, COL_REL_TIME);
- if (check_col(fd, COL_DELTA_TIME))
- col_add_delta_time(fd, COL_DELTA_TIME);
-
- if (check_col(fd, COL_PACKET_LENGTH))
- col_add_fstr(fd, COL_PACKET_LENGTH, "%d", fd->pkt_len);
+ int i;
+
+ for (i = 0; i < fd->cinfo->num_cols; i++) {
+ switch (fd->cinfo->col_fmt[i]) {
+
+ case COL_NUMBER:
+ snprintf(fd->cinfo->col_data[i], COL_MAX_LEN, "%u", fd->num);
+ break;
+
+ case COL_CLS_TIME:
+ col_set_cls_time(fd, i);
+ break;
+
+ case COL_ABS_TIME:
+ col_set_abs_time(fd, i);
+ break;
+
+ case COL_REL_TIME:
+ col_set_rel_time(fd, i);
+ break;
+
+ case COL_DELTA_TIME:
+ col_set_delta_time(fd, i);
+ break;
+
+ case COL_DEF_SRC:
+ case COL_RES_SRC: /* COL_DEF_SRC is currently just like COL_RES_SRC */
+ col_set_addr(fd, i, &pi.src, TRUE);
+ break;
+
+ case COL_UNRES_SRC:
+ col_set_addr(fd, i, &pi.src, FALSE);
+ break;
+
+ case COL_DEF_DL_SRC:
+ case COL_RES_DL_SRC:
+ col_set_addr(fd, i, &pi.dl_src, TRUE);
+ break;
+
+ case COL_UNRES_DL_SRC:
+ col_set_addr(fd, i, &pi.dl_src, FALSE);
+ break;
+
+ case COL_DEF_NET_SRC:
+ case COL_RES_NET_SRC:
+ col_set_addr(fd, i, &pi.net_src, TRUE);
+ break;
+
+ case COL_UNRES_NET_SRC:
+ col_set_addr(fd, i, &pi.net_src, FALSE);
+ break;
+
+ case COL_DEF_DST:
+ case COL_RES_DST: /* COL_DEF_DST is currently just like COL_RES_DST */
+ col_set_addr(fd, i, &pi.dst, TRUE);
+ break;
+
+ case COL_UNRES_DST:
+ col_set_addr(fd, i, &pi.dst, FALSE);
+ break;
+
+ case COL_DEF_DL_DST:
+ case COL_RES_DL_DST:
+ col_set_addr(fd, i, &pi.dl_dst, TRUE);
+ break;
+
+ case COL_UNRES_DL_DST:
+ col_set_addr(fd, i, &pi.dl_dst, FALSE);
+ break;
+
+ case COL_DEF_NET_DST:
+ case COL_RES_NET_DST:
+ col_set_addr(fd, i, &pi.net_dst, TRUE);
+ break;
+
+ case COL_UNRES_NET_DST:
+ col_set_addr(fd, i, &pi.net_dst, FALSE);
+ break;
+
+ case COL_DEF_SRC_PORT:
+ case COL_RES_SRC_PORT: /* COL_DEF_SRC_PORT is currently just like COL_RES_SRC_PORT */
+ col_set_port(fd, i, pi.ptype, pi.srcport, TRUE);
+ break;
+
+ case COL_UNRES_SRC_PORT:
+ col_set_port(fd, i, pi.ptype, pi.srcport, FALSE);
+ break;
+
+ case COL_DEF_DST_PORT:
+ case COL_RES_DST_PORT: /* COL_DEF_DST_PORT is currently just like COL_RES_DST_PORT */
+ col_set_port(fd, i, pi.ptype, pi.destport, TRUE);
+ break;
+
+ case COL_UNRES_DST_PORT:
+ col_set_port(fd, i, pi.ptype, pi.destport, FALSE);
+ break;
+
+ case COL_PROTOCOL: /* currently done by dissectors */
+ case COL_INFO: /* currently done by dissectors */
+ break;
+
+ case COL_PACKET_LENGTH:
+ snprintf(fd->cinfo->col_data[i], COL_MAX_LEN, "%d", fd->pkt_len);
+ break;
+
+ case NUM_COL_FMTS: /* keep compiler happy - shouldn't get here */
+ break;
+ }
+ }
}
static void
}
/* Apply the filters */
- if (DFILTER_CONTAINS_FILTER(cf->dfcode) ||
+ if (cf->dfcode != NULL ||
CFILTERS_CONTAINS_FILTER(cf)) {
protocol_tree = proto_tree_create_root();
dissect_packet(buf, fdata, protocol_tree);
- if( DFILTER_CONTAINS_FILTER(cf->dfcode) )
+ if (cf->dfcode != NULL)
fdata->passed_dfilter = dfilter_apply(cf->dfcode, protocol_tree, cf->pd);
else
fdata->passed_dfilter = TRUE;
color = -1;
for(crow = 0; cf->colors->num_of_filters &&
crow < cf->colors->num_of_filters; crow++) {
+
+ if(color_filter(cf,crow)->c_colorfilter == NULL) {
+ continue;
+ }
if(dfilter_apply(color_filter(cf,crow)->c_colorfilter, protocol_tree,
cf->pd)){
color = crow;
int passed;
proto_tree *protocol_tree;
frame_data *plist_end;
+ int file_pos;
+ float prog_val;
/* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
when we update it, we have to run the GTK+ main loop to get it
being updated by a live capture, we don't do so (as we're not
"done" until the capture stops, so we don't know how close to
"done" we are. */
+
if (cf->update_progbar && offset >= cf->progbar_nextstep) {
- gtk_progress_bar_update(GTK_PROGRESS_BAR(prog_bar),
- (gfloat) ftell(cf->fh) / (gfloat) cf->f_len);
- cf->progbar_nextstep += cf->progbar_quantum;
- while (gtk_events_pending())
+ file_pos = lseek(cf->filed, 0, SEEK_CUR);
+ prog_val = (gfloat) file_pos / (gfloat) cf->f_len;
+ gtk_progress_bar_update(GTK_PROGRESS_BAR(prog_bar), prog_val);
+ cf->progbar_nextstep += cf->progbar_quantum;
+ while (gtk_events_pending())
gtk_main_iteration();
}
passed = TRUE;
if (cf->rfcode) {
- if (DFILTER_CONTAINS_FILTER(cf->rfcode)) {
- protocol_tree = proto_tree_create_root();
- dissect_packet(buf, fdata, protocol_tree);
- passed = dfilter_apply(cf->rfcode, protocol_tree, cf->pd);
- proto_tree_free(protocol_tree);
- }
+ protocol_tree = proto_tree_create_root();
+ dissect_packet(buf, fdata, protocol_tree);
+ passed = dfilter_apply(cf->rfcode, protocol_tree, cf->pd);
+ proto_tree_free(protocol_tree);
}
if (passed) {
plist_end = cf->plist_end;
}
void
-filter_packets(capture_file *cf)
+filter_packets(capture_file *cf, gchar *dftext)
{
- frame_data *fd;
- guint32 progbar_quantum;
- guint32 progbar_nextstep;
+ dfilter *dfcode;
- if (cf->dfilter == NULL) {
- dfilter_clear_filter(cf->dfcode);
- }
- else {
+ if (dftext == NULL) {
+ /* The new filter is an empty filter (i.e., display all packets). */
+ dfcode = NULL;
+ } else {
/*
- * Compile the filter.
+ * We have a filter; try to compile it.
*/
- if (dfilter_compile(cf->dfcode, cf->dfilter) != 0) {
+ if (dfilter_compile(dftext, &dfcode) != 0) {
+ /* The attempt failed; report an error. */
simple_dialog(ESD_TYPE_WARN, NULL, dfilter_error_msg);
return;
}
+
+ /* Was it empty? */
+ if (dfcode == NULL) {
+ /* Yes - free the filter text, and set it to null. */
+ g_free(dftext);
+ dftext = NULL;
+ }
}
+ /* We have a valid filter. Replace the current filter. */
+ if (cf->dfilter != NULL)
+ g_free(cf->dfilter);
+ cf->dfilter = dftext;
+ if (cf->dfcode != NULL)
+ dfilter_destroy(cf->dfcode);
+ cf->dfcode = dfcode;
+
+ /* Now go through the list of packets we've read from the capture file,
+ applying the current display filter, and, if the packet passes the
+ display filter, add it to the summary display, appropriately
+ colored. (That's how we colorize the display - it's like filtering
+ the display, only we don't install a new filter.) */
+ colorize_packets(cf);
+}
+
+void
+colorize_packets(capture_file *cf)
+{
+ frame_data *fd;
+ guint32 progbar_quantum;
+ guint32 progbar_nextstep;
+
+ gtk_progress_set_activity_mode(GTK_PROGRESS(prog_bar), FALSE);
+
/* Freeze the packet list while we redo it, so we don't get any
screen updates while it happens. */
gtk_clist_freeze(GTK_CLIST(packet_list));
/* When we reach the value that triggers a progress bar update,
bump that value by this amount. */
progbar_quantum = cf->unfiltered_count/N_PROGBAR_UPDATES;
+ gtk_progress_bar_set_orientation(GTK_PROGRESS_BAR(prog_bar), GTK_PROGRESS_LEFT_TO_RIGHT);
for (fd = cf->plist; fd != NULL; fd = fd->next) {
/* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
*/
g_assert(cf->unfiltered_count > 0);
- gtk_progress_bar_update(GTK_PROGRESS_BAR(prog_bar),
- (gfloat) cf->count / cf->unfiltered_count);
+ gtk_progress_bar_update(GTK_PROGRESS_BAR(prog_bar),
+ (gfloat) cf->count / cf->unfiltered_count);
+
progbar_nextstep += progbar_quantum;
while (gtk_events_pending())
gtk_main_iteration();
{
int i;
frame_data *fd;
+ guint32 progbar_quantum;
+ guint32 progbar_nextstep;
+ guint32 count;
proto_tree *protocol_tree;
gint *col_widths = NULL;
gint data_width;
print_separator = FALSE;
proto_tree_is_visible = TRUE;
+ /* 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 = cf->unfiltered_count/N_PROGBAR_UPDATES;
+ /* Count of packets we've looked at. */
+ count = 0;
+
/* Iterate through the list of packets, printing the packets that
were selected by the current display filter. */
for (fd = cf->plist; fd != NULL; fd = fd->next) {
+ /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
+ when we update it, we have to run the GTK+ main loop to get it
+ to repaint what's pending, and doing so may involve an "ioctl()"
+ to see if there's any pending input from an X server, and doing
+ that for every packet can be costly, especially on a big file. */
+ if (count >= progbar_nextstep) {
+ /* let's not divide by zero. I should never be started
+ * with unfiltered_count == 0, so let's assert that
+ */
+ g_assert(cf->unfiltered_count > 0);
+
+ gtk_progress_bar_update(GTK_PROGRESS_BAR(prog_bar),
+ (gfloat) count / cf->unfiltered_count);
+ progbar_nextstep += progbar_quantum;
+ while (gtk_events_pending())
+ gtk_main_iteration();
+ }
+ count++;
+
if (fd->passed_dfilter) {
wtap_seek_read (cf->cd_t, cf->fh, fd->file_off, cf->pd, fd->cap_len);
if (print_args->print_summary) {
dissect_packet(cf->pd, fd, protocol_tree);
/* Print the information in that tree. */
- proto_tree_print(FALSE, (GNode *)protocol_tree, cf->pd, fd, cf->print_fh);
+ proto_tree_print(FALSE, print_args, (GNode *)protocol_tree,
+ cf->pd, fd, cf->print_fh);
proto_tree_free(protocol_tree);
+ if (print_args->print_hex) {
+ /* Print the full packet data as hex. */
+ print_hex_data(cf->print_fh, cf->pd, fd->cap_len);
+ }
+
/* Print a blank line if we print anything after this. */
print_separator = TRUE;
}
}
}
+ if (col_widths != NULL)
+ g_free(col_widths);
+
#if 0
print_finale(cf->print_fh);
#endif
close_print_dest(print_args->to_file, cf->print_fh);
+
+ gtk_progress_bar_update(GTK_PROGRESS_BAR(prog_bar), 0);
+
cf->print_fh = NULL;
return TRUE;
}
if (check_col(fd, COL_CLS_TIME)) {
/* There are columns that show the time in the "command-line-specified"
format; update them. */
- for (i = 0; i < cf->cinfo.num_cols; i++) {
- cf->cinfo.col_data[i][0] = '\0';
- }
- col_add_cls_time(fd);
for (i = 0; i < cf->cinfo.num_cols; i++) {
if (cf->cinfo.fmt_matx[i][COL_CLS_TIME]) {
/* This is one of the columns that shows the time in
"command-line-specified" format; update it. */
+ cf->cinfo.col_data[i][0] = '\0';
+ col_set_cls_time(fd, i);
gtk_clist_set_text(GTK_CLIST(packet_list), fd->row, i,
cf->cinfo.col_data[i]);
}
if (fd->row == row)
break;
}
+
+ g_assert(fd != NULL);
+
cf->fd = fd;
/* Remember the ordinal number of that frame. */