aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--file.c130
-rw-r--r--file.h4
-rw-r--r--follow.c4
-rw-r--r--globals.h3
-rw-r--r--gtk/Makefile.am4
-rw-r--r--gtk/Makefile.nmake1
-rw-r--r--gtk/follow_dlg.c551
-rw-r--r--gtk/follow_dlg.h26
-rw-r--r--gtk/main.c437
-rw-r--r--gtk/main.h3
-rw-r--r--gtk/menu.c4
-rw-r--r--gtk/packet_win.c3
-rw-r--r--print.h6
-rw-r--r--tethereal.c3
14 files changed, 674 insertions, 505 deletions
diff --git a/file.c b/file.c
index f21ffa50c0..b71c1c968a 100644
--- a/file.c
+++ b/file.c
@@ -1,7 +1,7 @@
/* file.c
* File I/O routines
*
- * $Id: file.c,v 1.202 2000/08/03 12:02:15 gram Exp $
+ * $Id: file.c,v 1.203 2000/08/03 12:44:18 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -1610,7 +1610,6 @@ save_cap_file(char *fname, capture_file *cf, gboolean save_filtered,
size_t msg_len;
int err;
gboolean do_copy;
- int from_fd, to_fd, nread, nwritten;
wtap_dumper *pdh;
frame_data *fdata;
struct wtap_pkthdr hdr;
@@ -1672,58 +1671,9 @@ save_cap_file(char *fname, capture_file *cf, gboolean save_filtered,
}
/* Copy the file, if we haven't moved it. */
if (do_copy) {
- /* Copy the raw bytes of the file. */
- from_fd = open(from_filename, O_RDONLY | O_BINARY);
- if (from_fd < 0) {
- err = errno;
- simple_dialog(ESD_TYPE_CRIT, NULL,
- file_open_error_message(err, TRUE), from_filename);
- goto done;
- }
-
- /* Use open() instead of creat() so that we can pass the O_BINARY
- flag, which is relevant on Win32; it appears that "creat()"
- may open the file in text mode, not binary mode, but we want
- to copy the raw bytes of the file, so we need the output file
- to be open in binary mode. */
- to_fd = open(fname, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
- if (to_fd < 0) {
- err = errno;
- simple_dialog(ESD_TYPE_CRIT, NULL,
- file_open_error_message(err, TRUE), fname);
- close(from_fd);
- goto done;
- }
-
- while ((nread = read(from_fd, pd, sizeof pd)) > 0) {
- nwritten = write(to_fd, pd, nread);
- if (nwritten < nread) {
- if (nwritten < 0)
- err = errno;
- else
- err = WTAP_ERR_SHORT_WRITE;
- simple_dialog(ESD_TYPE_CRIT, NULL,
- file_write_error_message(err), fname);
- close(from_fd);
- close(to_fd);
- goto done;
- }
- }
- if (nread < 0) {
- err = errno;
- simple_dialog(ESD_TYPE_CRIT, NULL,
- file_read_error_message(err), from_filename);
- close(from_fd);
- close(to_fd);
- goto done;
- }
- close(from_fd);
- if (close(to_fd) < 0) {
- err = errno;
- simple_dialog(ESD_TYPE_CRIT, NULL,
- file_close_error_message(err), fname);
- goto done;
- }
+ if (!copy_binary_file(from_filename, fname)) {
+ goto done;
+ }
}
} else {
/* Either we're filtering packets, or we're saving in a different
@@ -1997,3 +1947,75 @@ file_close_error_message(int err)
}
return errmsg;
}
+
+
+/* Copies a file in binary mode, for those operating systems that care about
+ * such things.
+ * Returns TRUE on success, FALSE on failure. If a failure, it also
+ * displays a simple dialog window with the error message.
+ */
+gboolean
+copy_binary_file(char *from_filename, char *to_filename)
+{
+ int from_fd, to_fd, nread, nwritten, err;
+ guint8 pd[65536]; /* XXX - Hmm, 64K here, 64K in save_cap_file(),
+ perhaps we should make just one 64K buffer. */
+
+ /* Copy the raw bytes of the file. */
+ from_fd = open(from_filename, O_RDONLY | O_BINARY);
+ if (from_fd < 0) {
+ err = errno;
+ simple_dialog(ESD_TYPE_CRIT, NULL,
+ file_open_error_message(err, TRUE), from_filename);
+ goto done;
+ }
+
+ /* Use open() instead of creat() so that we can pass the O_BINARY
+ flag, which is relevant on Win32; it appears that "creat()"
+ may open the file in text mode, not binary mode, but we want
+ to copy the raw bytes of the file, so we need the output file
+ to be open in binary mode. */
+ to_fd = open(to_filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
+ if (to_fd < 0) {
+ err = errno;
+ simple_dialog(ESD_TYPE_CRIT, NULL,
+ file_open_error_message(err, TRUE), to_filename);
+ close(from_fd);
+ goto done;
+ }
+
+ while ((nread = read(from_fd, pd, sizeof pd)) > 0) {
+ nwritten = write(to_fd, pd, nread);
+ if (nwritten < nread) {
+ if (nwritten < 0)
+ err = errno;
+ else
+ err = WTAP_ERR_SHORT_WRITE;
+ simple_dialog(ESD_TYPE_CRIT, NULL,
+ file_write_error_message(err), to_filename);
+ close(from_fd);
+ close(to_fd);
+ goto done;
+ }
+ }
+ if (nread < 0) {
+ err = errno;
+ simple_dialog(ESD_TYPE_CRIT, NULL,
+ file_read_error_message(err), from_filename);
+ close(from_fd);
+ close(to_fd);
+ goto done;
+ }
+ close(from_fd);
+ if (close(to_fd) < 0) {
+ err = errno;
+ simple_dialog(ESD_TYPE_CRIT, NULL,
+ file_close_error_message(err), to_filename);
+ goto done;
+ }
+
+ return TRUE;
+
+ done:
+ return FALSE;
+}
diff --git a/file.h b/file.h
index c8439a83c8..023e130f8c 100644
--- a/file.h
+++ b/file.h
@@ -1,7 +1,7 @@
/* file.h
* Definitions for file structures and routines
*
- * $Id: file.h,v 1.72 2000/07/20 05:09:46 guy Exp $
+ * $Id: file.h,v 1.73 2000/08/03 12:44:20 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -165,4 +165,6 @@ char *file_open_error_message(int, gboolean);
char *file_read_error_message(int);
char *file_write_error_message(int);
+gboolean copy_binary_file(char *from_filename, char *to_filename);
+
#endif /* file.h */
diff --git a/follow.c b/follow.c
index d4d0220e23..68dbd61943 100644
--- a/follow.c
+++ b/follow.c
@@ -1,6 +1,6 @@
/* follow.c
*
- * $Id: follow.c,v 1.22 2000/07/07 09:30:56 guy Exp $
+ * $Id: follow.c,v 1.23 2000/08/03 12:44:20 gram Exp $
*
* Copyright 1998 Mike Hall <mlh@io.com>
*
@@ -44,7 +44,7 @@
#include "packet.h"
#include "follow.h"
-extern FILE* data_out_file;
+FILE* data_out_file;
gboolean incomplete_tcp_stream = FALSE;
diff --git a/globals.h b/globals.h
index 5b54356049..265f8af0f8 100644
--- a/globals.h
+++ b/globals.h
@@ -1,7 +1,7 @@
/* globals.h
* Global defines, etc.
*
- * $Id: globals.h,v 1.18 2000/06/27 04:35:45 guy Exp $
+ * $Id: globals.h,v 1.19 2000/08/03 12:44:21 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -74,7 +74,6 @@
# define MIN(x, y) ((x) < (y) ? (x) : (y))
#endif
-extern FILE *data_out_file;
extern packet_info pi;
extern capture_file cfile;
extern guint main_ctx, file_ctx;
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index 09d89b70b4..b4c67f165d 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -1,7 +1,7 @@
# Makefile.am
# Automake file for the GTK interface routines for Ethereal
#
-# $Id: Makefile.am,v 1.27 2000/07/03 08:36:02 guy Exp $
+# $Id: Makefile.am,v 1.28 2000/08/03 12:44:35 gram Exp $
#
# Ethereal - Network traffic analyzer
# By Gerald Combs <gerald@zing.org>
@@ -47,6 +47,8 @@ libui_a_SOURCES = \
filter_prefs.h \
find_dlg.c \
find_dlg.h \
+ follow_dlg.c \
+ follow_dlg.h \
goto_dlg.c \
goto_dlg.h \
gtkclist.c \
diff --git a/gtk/Makefile.nmake b/gtk/Makefile.nmake
index 051d7d7309..03edb0ce36 100644
--- a/gtk/Makefile.nmake
+++ b/gtk/Makefile.nmake
@@ -23,6 +23,7 @@ OBJECTS=capture_dlg.obj \
file_dlg.obj \
filter_prefs.obj \
find_dlg.obj \
+ follow_dlg.obj \
goto_dlg.obj \
gui_prefs.obj \
main.obj \
diff --git a/gtk/follow_dlg.c b/gtk/follow_dlg.c
new file mode 100644
index 0000000000..23115eae36
--- /dev/null
+++ b/gtk/follow_dlg.c
@@ -0,0 +1,551 @@
+/* follow_dlg.c
+ *
+ * $Id: follow_dlg.c,v 1.1 2000/08/03 12:44:36 gram Exp $
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@zing.org>
+ * Copyright 2000 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <gtk/gtk.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef HAVE_IO_H
+#include <io.h> /* open/close on win32 */
+#endif
+
+#include "file.h"
+#include "follow_dlg.h"
+#include "follow.h"
+#include "dlg_utils.h"
+#include "keys.h"
+#include "globals.h"
+#include "gtkglobals.h"
+#include "main.h"
+#include "simple_dialog.h"
+#include "prefs.h"
+#include "util.h"
+#include "ui_util.h"
+
+
+static void follow_destroy_cb(GtkWidget *win, gpointer data);
+static void follow_charset_toggle_cb(GtkWidget *w, gpointer parent_w);
+static void follow_load_text(GtkWidget *text, char *filename, guint8 show_type);
+static void follow_print_stream(GtkWidget *w, gpointer parent_w);
+static void follow_save_as_cmd_cb(GtkWidget *w, gpointer data);
+static void follow_save_as_ok_cb(GtkWidget *w, GtkFileSelection *fs);
+static void follow_save_as_destroy_cb(GtkWidget *win, gpointer user_data);
+
+FILE *data_out_file = NULL;
+static char data_out_filename[128+1];
+
+/* Follow the TCP stream, if any, to which the last packet that we called
+ a dissection routine on belongs (this might be the most recently
+ selected packet, or it might be the last packet in the file). */
+void
+follow_stream_cb( GtkWidget *w, gpointer data )
+{
+ GtkWidget *streamwindow, *box, *txt_scrollw, *text, *filter_te;
+ GtkWidget *hbox, *button;
+ GtkWidget *b_ascii, *b_ebcdic, *b_hexdump;
+ int tmp_fd;
+ gchar *follow_filter;
+
+ if( pi.ipproto == 6 ) {
+ /* we got tcp so we can follow */
+ /* Create a temporary file into which to dump the reassembled data
+ from the TCP stream, and set "data_out_file" to refer to it, so
+ that the TCP code will write to it.
+
+ XXX - it might be nicer to just have the TCP code directly
+ append stuff to the text widget for the TCP stream window,
+ if we can arrange that said window not pop up until we're
+ done. */
+ tmp_fd = create_tempfile( data_out_filename, sizeof data_out_filename, "follow");
+ if (tmp_fd == -1) {
+ simple_dialog(ESD_TYPE_WARN, NULL,
+ "Could not create temporary file %s: %s", data_out_filename, strerror(errno));
+ return;
+ }
+ data_out_file = fdopen( tmp_fd, "wb" );
+ if( data_out_file == NULL ) {
+ simple_dialog(ESD_TYPE_WARN, NULL,
+ "Could not create temporary file %s: %s", data_out_filename, strerror(errno));
+ close(tmp_fd);
+ unlink(data_out_filename);
+ return;
+ }
+
+ /* Create a new filter that matches all packets in the TCP stream,
+ and set the display filter entry accordingly */
+ reset_tcp_reassembly();
+ follow_filter = build_follow_filter( &pi );
+
+ /* set the display filter entry accordingly */
+ filter_te = gtk_object_get_data(GTK_OBJECT(w), E_DFILTER_TE_KEY);
+ gtk_entry_set_text(GTK_ENTRY(filter_te), follow_filter);
+
+ /* Run the display filter so it goes in effect. */
+ filter_packets(&cfile, follow_filter);
+
+ /* the data_out_file should now be full of the streams information */
+ fclose( data_out_file );
+
+ /* the data_out_filename file now has all the text that was in the session */
+ streamwindow = gtk_window_new( GTK_WINDOW_TOPLEVEL);
+ gtk_widget_set_name( streamwindow, "TCP stream window" );
+
+ gtk_signal_connect( GTK_OBJECT(streamwindow), "destroy",
+ GTK_SIGNAL_FUNC(follow_destroy_cb), NULL);
+
+ if( incomplete_tcp_stream ) {
+ gtk_window_set_title( GTK_WINDOW(streamwindow),
+ "Contents of TCP stream (incomplete)" );
+ } else {
+ gtk_window_set_title( GTK_WINDOW(streamwindow),
+ "Contents of TCP stream" );
+ }
+ gtk_widget_set_usize( GTK_WIDGET(streamwindow), DEF_WIDTH, DEF_HEIGHT );
+ gtk_container_border_width( GTK_CONTAINER(streamwindow), 2 );
+
+ /* setup the container */
+ box = gtk_vbox_new( FALSE, 0 );
+ gtk_container_add( GTK_CONTAINER(streamwindow), box );
+ gtk_widget_show( box );
+
+ /* create a scrolled window for the text */
+ txt_scrollw = gtk_scrolled_window_new( NULL, NULL );
+ gtk_box_pack_start( GTK_BOX(box), txt_scrollw, TRUE, TRUE, 0 );
+ gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(txt_scrollw),
+ GTK_POLICY_NEVER,
+ GTK_POLICY_ALWAYS );
+ set_scrollbar_placement_scrollw(txt_scrollw, prefs.gui_scrollbar_on_right);
+ remember_scrolled_window(txt_scrollw);
+ gtk_widget_show( txt_scrollw );
+
+ /* create a text box */
+ text = gtk_text_new( NULL, NULL );
+ gtk_text_set_editable( GTK_TEXT(text), FALSE);
+ gtk_container_add( GTK_CONTAINER(txt_scrollw), text );
+ gtk_widget_show(text);
+
+ /* Create hbox */
+ hbox = gtk_hbox_new( FALSE, 1 );
+ gtk_box_pack_end( GTK_BOX(box), hbox, FALSE, FALSE, 0);
+ gtk_widget_show(hbox);
+
+#define E_FOLLOW_ASCII_KEY "follow_ascii_key"
+#define E_FOLLOW_EBCDIC_KEY "follow_ebcdic_key"
+#define E_FOLLOW_HEXDUMP_KEY "follow_hexdump_key"
+
+ /* Create Radio Buttons */
+ b_ascii = gtk_radio_button_new_with_label(NULL, "ASCII");
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b_ascii), TRUE);
+ gtk_object_set_data(GTK_OBJECT(streamwindow), E_FOLLOW_ASCII_KEY, b_ascii);
+ gtk_box_pack_start(GTK_BOX(hbox), b_ascii, FALSE, FALSE, 0);
+ gtk_signal_connect(GTK_OBJECT(b_ascii), "toggled",
+ GTK_SIGNAL_FUNC(follow_charset_toggle_cb),
+ GTK_OBJECT(streamwindow));
+ gtk_widget_show(b_ascii);
+
+ b_ebcdic = gtk_radio_button_new_with_label(
+ gtk_radio_button_group(GTK_RADIO_BUTTON(b_ascii)),
+ "EBCDIC");
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b_ebcdic), FALSE);
+ gtk_object_set_data(GTK_OBJECT(streamwindow), E_FOLLOW_EBCDIC_KEY, b_ebcdic);
+ gtk_box_pack_start(GTK_BOX(hbox), b_ebcdic, FALSE, FALSE, 0);
+ gtk_signal_connect(GTK_OBJECT(b_ebcdic), "toggled",
+ GTK_SIGNAL_FUNC(follow_charset_toggle_cb),
+ GTK_OBJECT(streamwindow));
+ gtk_widget_show(b_ebcdic);
+
+ b_hexdump = gtk_radio_button_new_with_label(
+ gtk_radio_button_group(GTK_RADIO_BUTTON(b_ascii)),
+ "Hex. Dump");
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b_hexdump), FALSE);
+ gtk_object_set_data(GTK_OBJECT(streamwindow), E_FOLLOW_HEXDUMP_KEY, b_hexdump);
+ gtk_box_pack_start(GTK_BOX(hbox), b_hexdump, FALSE, FALSE, 0);
+ gtk_signal_connect(GTK_OBJECT(b_hexdump), "toggled",
+ GTK_SIGNAL_FUNC(follow_charset_toggle_cb),
+ GTK_OBJECT(streamwindow));
+ gtk_widget_show(b_hexdump);
+
+ /* Create Close Button */
+ button = gtk_button_new_with_label("Close");
+ gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
+ GTK_SIGNAL_FUNC(gtk_widget_destroy),
+ GTK_OBJECT(streamwindow));
+ gtk_box_pack_end( GTK_BOX(hbox), button, FALSE, FALSE, 0);
+ gtk_widget_show( button );
+
+ /* Create Save As Button */
+ button = gtk_button_new_with_label("Save As");
+ gtk_signal_connect(GTK_OBJECT(button), "clicked",
+ GTK_SIGNAL_FUNC(follow_save_as_cmd_cb),
+ GTK_OBJECT(streamwindow));
+ gtk_box_pack_end( GTK_BOX(hbox), button, FALSE, FALSE, 0);
+ gtk_widget_show( button );
+
+ /* Create Print Button */
+ button = gtk_button_new_with_label("Print");
+ gtk_signal_connect(GTK_OBJECT(button), "clicked",
+ GTK_SIGNAL_FUNC(follow_print_stream),
+ GTK_OBJECT(streamwindow));
+ gtk_box_pack_end( GTK_BOX(hbox), button, FALSE, FALSE, 0);
+ gtk_widget_show( button );
+
+ /* Tuck away the textbox into streamwindow */
+#define E_FOLLOW_TEXT_KEY "follow_text_key"
+ gtk_object_set_data(GTK_OBJECT(streamwindow), E_FOLLOW_TEXT_KEY, text);
+
+ follow_load_text(text, data_out_filename, 0);
+
+ data_out_file = NULL;
+
+ /* Make sure this widget gets destroyed if we quit the main loop,
+ so that if we exit, we clean up any temporary files we have
+ for "Follow TCP Stream" windows. */
+ gtk_quit_add_destroy(gtk_main_level(), GTK_OBJECT(streamwindow));
+ gtk_widget_show( streamwindow );
+ } else {
+ simple_dialog(ESD_TYPE_CRIT, NULL,
+ "Error following stream. Please make\n"
+ "sure you have a TCP packet selected.");
+ }
+}
+
+/* The destroy call back has the responsibility of
+ * unlinking the temporary file */
+static void
+follow_destroy_cb(GtkWidget *win, gpointer data)
+{
+ unlink(data_out_filename);
+ gtk_widget_destroy(win);
+}
+
+#define E_FOLLOW_ASCII_TYPE 0
+#define E_FOLLOW_EBCDIC_TYPE 1
+#define E_FOLLOW_HEXDUMP_TYPE 2
+
+/* Handles the ASCII/EBCDIC toggling */
+static void
+follow_charset_toggle_cb(GtkWidget *w, gpointer parent_w)
+{
+ guint8 show_type = E_FOLLOW_ASCII_TYPE;
+ GtkWidget *b_ascii, *b_ebcdic, *b_hexdump, *text;
+
+ b_ascii = (GtkWidget*) gtk_object_get_data(GTK_OBJECT(parent_w),
+ E_FOLLOW_ASCII_KEY);
+ b_ebcdic = (GtkWidget*) gtk_object_get_data(GTK_OBJECT(parent_w),
+ E_FOLLOW_EBCDIC_KEY);
+ b_hexdump = (GtkWidget*) gtk_object_get_data(GTK_OBJECT(parent_w),
+ E_FOLLOW_HEXDUMP_KEY);
+ text = (GtkWidget*) gtk_object_get_data(GTK_OBJECT(parent_w),
+ E_FOLLOW_TEXT_KEY);
+
+ g_assert(b_ascii);
+ g_assert(b_ebcdic);
+ g_assert(b_hexdump);
+ g_assert(text);
+
+ if (GTK_TOGGLE_BUTTON(b_ebcdic)->active)
+ show_type = E_FOLLOW_EBCDIC_TYPE;
+ else if (GTK_TOGGLE_BUTTON(b_hexdump)->active)
+ show_type = E_FOLLOW_HEXDUMP_TYPE;
+
+ follow_load_text(text, data_out_filename, show_type);
+}
+
+#define FLT_BUF_SIZE 1024
+static void
+follow_read_stream(char *filename, guint8 show_type,
+ void (*print_line)(char *, int, gboolean, void *), void *arg)
+{
+ tcp_stream_chunk sc;
+ int bcount;
+ guint32 client_addr = 0;
+ guint16 client_port = 0;
+ gboolean is_server;
+ guint16 current_pos, global_client_pos = 0, global_server_pos = 0;
+ guint16 *global_pos;
+
+ data_out_file = fopen( filename, "rb" );
+ if( data_out_file ) {
+ char buffer[FLT_BUF_SIZE];
+ int nchars;
+ while(fread(&sc.src_addr, 1, sizeof(sc), data_out_file)) {
+ if (client_addr == 0) {
+ client_addr = sc.src_addr;
+ client_port = sc.src_port;
+ }
+ if (client_addr == sc.src_addr && client_port == sc.src_port) {
+ is_server = FALSE;
+ global_pos = &global_client_pos;
+ }
+ else {
+ is_server = TRUE;
+ global_pos = &global_server_pos;
+ }
+
+ while (sc.dlen > 0) {
+ bcount = (sc.dlen < FLT_BUF_SIZE) ? sc.dlen : FLT_BUF_SIZE;
+ nchars = fread( buffer, 1, bcount, data_out_file );
+ if (nchars == 0)
+ break;
+ sc.dlen -= bcount;
+ switch (show_type) {
+ case E_FOLLOW_EBCDIC_TYPE:
+ /* If our native arch is ASCII, call: */
+ EBCDIC_to_ASCII(buffer, nchars);
+ case E_FOLLOW_ASCII_TYPE:
+ /* If our native arch is EBCDIC, call:
+ * ASCII_TO_EBCDIC(buffer, nchars);
+ */
+ (*print_line)( buffer, nchars, is_server, arg );
+ break;
+ case E_FOLLOW_HEXDUMP_TYPE:
+ current_pos = 0;
+ while (current_pos < nchars)
+ {
+ gchar hexbuf[256];
+ gchar hexchars[] = "0123456789abcdef";
+ int i, cur;
+ /* is_server indentation : put 63 spaces at the begenning
+ * of the string */
+ sprintf(hexbuf, is_server ?
+ " "
+ " %08X " :
+ "%08X ", *global_pos);
+ cur = strlen(hexbuf);
+ for (i=0; i < 16 && current_pos+i < nchars; i++) {
+ hexbuf[cur++] = hexchars[(buffer[current_pos+i] & 0xf0) >> 4];
+ hexbuf[cur++] = hexchars[buffer[current_pos+i] & 0x0f];
+ if (i == 7) {
+ hexbuf[cur++] = ' '; hexbuf[cur++] = ' ';
+ }
+ else if (i != 15)
+ hexbuf[cur++] = ' ';
+ }
+ current_pos += i;
+ (*global_pos) += i;
+ hexbuf[cur++] = '\n';
+ hexbuf[cur] = 0;
+ (*print_line)( hexbuf, strlen(hexbuf), is_server, arg );
+ }
+ break;
+ }
+ }
+ }
+ if( ferror( data_out_file ) ) {
+ simple_dialog(ESD_TYPE_WARN, NULL,
+ "Error reading temporary file %s: %s", filename, strerror(errno));
+ }
+ fclose( data_out_file );
+ data_out_file = NULL;
+ } else {
+ simple_dialog(ESD_TYPE_WARN, NULL,
+ "Could not open temporary file %s: %s", filename, strerror(errno));
+ }
+}
+
+/*
+ * XXX - for text printing, we probably want to wrap lines at 80 characters;
+ * for PostScript printing, we probably want to wrap them at the appropriate
+ * width, and perhaps put some kind of dingbat (to use the technical term)
+ * to indicate a wrapped line, along the lines of what's done when displaying
+ * this in a window, as per Warren Young's suggestion.
+ *
+ * For now, we support only text printing.
+ */
+static void
+follow_print_text(char *buffer, int nchars, gboolean is_server, void *arg)
+{
+ FILE *fh = arg;
+
+ fwrite(buffer, nchars, 1, fh);
+}
+
+static void
+follow_print_stream(GtkWidget *w, gpointer parent_w)
+{
+ FILE *fh;
+ gboolean to_file;
+ char* print_dest;
+ guint8 show_type = E_FOLLOW_ASCII_TYPE;
+ GtkWidget *button;
+
+ switch (prefs.pr_dest) {
+ case PR_DEST_CMD:
+ print_dest = prefs.pr_cmd;
+ to_file = FALSE;
+ break;
+
+ case PR_DEST_FILE:
+ print_dest = prefs.pr_file;
+ to_file = TRUE;
+ break;
+ default: /* "Can't happen" */
+ simple_dialog(ESD_TYPE_CRIT, NULL,
+ "Couldn't figure out where to send the print "
+ "job. Check your preferences.");
+ return;
+ }
+
+ fh = open_print_dest(to_file, print_dest);
+ if (fh == NULL) {
+ switch (to_file) {
+ case FALSE:
+ simple_dialog(ESD_TYPE_WARN, NULL,
+ "Couldn't run print command %s.", prefs.pr_cmd);
+ break;
+
+ case TRUE:
+ simple_dialog(ESD_TYPE_WARN, NULL,
+ file_write_error_message(errno),
+ prefs.pr_file);
+ break;
+ }
+ return;
+ }
+
+ button = (GtkWidget*) gtk_object_get_data(GTK_OBJECT(parent_w),
+ E_FOLLOW_EBCDIC_KEY);
+ if (GTK_TOGGLE_BUTTON(button)->active)
+ show_type = E_FOLLOW_EBCDIC_TYPE;
+ button = (GtkWidget*) gtk_object_get_data(GTK_OBJECT(parent_w),
+ E_FOLLOW_HEXDUMP_KEY);
+ if (GTK_TOGGLE_BUTTON(button)->active)
+ show_type = E_FOLLOW_HEXDUMP_TYPE;
+
+ print_preamble(fh, PR_FMT_TEXT);
+ follow_read_stream(data_out_filename, show_type, follow_print_text, fh);
+ print_finale(fh, PR_FMT_TEXT);
+ close_print_dest(to_file, fh);
+}
+
+static void
+follow_add_to_gtk_text(char *buffer, int nchars, gboolean is_server, void *arg)
+{
+ GtkWidget *text = arg;
+
+ if (is_server)
+ gtk_text_insert( GTK_TEXT(text), m_r_font, &prefs.st_server_fg,
+ &prefs.st_server_bg, buffer, nchars );
+ else
+ gtk_text_insert( GTK_TEXT(text), m_r_font, &prefs.st_client_fg,
+ &prefs.st_client_bg, buffer, nchars );
+}
+
+static void
+follow_load_text(GtkWidget *text, char *filename, guint8 show_type)
+{
+ int bytes_already;
+
+ /* Delete any info already in text box */
+ bytes_already = gtk_text_get_length(GTK_TEXT(text));
+ if (bytes_already > 0) {
+ gtk_text_set_point(GTK_TEXT(text), 0);
+ gtk_text_forward_delete(GTK_TEXT(text), bytes_already);
+ }
+
+ /* stop the updates while we fill the text box */
+ gtk_text_freeze( GTK_TEXT(text) );
+ follow_read_stream(filename, show_type, follow_add_to_gtk_text, text);
+ gtk_text_thaw( GTK_TEXT(text) );
+}
+
+
+/*
+ * Keep a static pointer to the current "Save TCP Follow Stream As" window, if
+ * any, so that if somebody tries to do "Save"
+ * while there's already a "Save TCP Follow Stream" window up, we just pop
+ * up the existing one, rather than creating a new one.
+ */
+static GtkWidget *follow_save_as_w;
+
+static void
+follow_save_as_cmd_cb(GtkWidget *w, gpointer data)
+{
+ GtkWidget *ok_bt;
+
+ if (follow_save_as_w != NULL) {
+ /* There's already a dialog box; reactivate it. */
+ reactivate_window(follow_save_as_w);
+ return;
+ }
+
+ follow_save_as_w = gtk_file_selection_new ("Ethereal: Save TCP Follow Stream As");
+ gtk_signal_connect(GTK_OBJECT(follow_save_as_w), "destroy",
+ GTK_SIGNAL_FUNC(follow_save_as_destroy_cb), NULL);
+
+ /* If we've opened a file, start out by showing the files in the directory
+ in which that file resided. */
+ if (last_open_dir)
+ gtk_file_selection_complete(GTK_FILE_SELECTION(follow_save_as_w), last_open_dir);
+
+ /* Connect the ok_button to file_save_as_ok_cb function and pass along a
+ pointer to the file selection box widget */
+ ok_bt = GTK_FILE_SELECTION (follow_save_as_w)->ok_button;
+ gtk_signal_connect(GTK_OBJECT (ok_bt), "clicked",
+ (GtkSignalFunc) follow_save_as_ok_cb, follow_save_as_w);
+
+ /* Connect the cancel_button to destroy the widget */
+ gtk_signal_connect_object(GTK_OBJECT (GTK_FILE_SELECTION
+ (follow_save_as_w)->cancel_button), "clicked", (GtkSignalFunc)
+ gtk_widget_destroy, GTK_OBJECT (follow_save_as_w));
+
+ /* Catch the "key_press_event" signal in the window, so that we can catch
+ the ESC key being pressed and act as if the "Cancel" button had
+ been selected. */
+ dlg_set_cancel(follow_save_as_w, GTK_FILE_SELECTION(follow_save_as_w)->cancel_button);
+
+ gtk_file_selection_set_filename(GTK_FILE_SELECTION(follow_save_as_w), "");
+ gtk_widget_show(follow_save_as_w);
+}
+
+static void
+follow_save_as_ok_cb(GtkWidget *w, GtkFileSelection *fs)
+{
+ gchar *to_name;
+
+ to_name = g_strdup(gtk_file_selection_get_filename(GTK_FILE_SELECTION(fs)));
+ gtk_widget_hide(GTK_WIDGET (fs));
+ gtk_widget_destroy(GTK_WIDGET (fs));
+
+ copy_binary_file(data_out_filename, to_name);
+
+ g_free(to_name);
+}
+
+static void
+follow_save_as_destroy_cb(GtkWidget *win, gpointer user_data)
+{
+ /* Note that we no longer have a dialog box. */
+ follow_save_as_w = NULL;
+}
diff --git a/gtk/follow_dlg.h b/gtk/follow_dlg.h
new file mode 100644
index 0000000000..6dd606294e
--- /dev/null
+++ b/gtk/follow_dlg.h
@@ -0,0 +1,26 @@
+/* follow_dlg.c
+ *
+ * $Id: follow_dlg.h,v 1.1 2000/08/03 12:44:37 gram Exp $
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@zing.org>
+ * Copyright 2000 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+void follow_stream_cb( GtkWidget *, gpointer);
+
diff --git a/gtk/main.c b/gtk/main.c
index 52e5a10eaf..82ca8d8b35 100644
--- a/gtk/main.c
+++ b/gtk/main.c
@@ -1,6 +1,6 @@
/* main.c
*
- * $Id: main.c,v 1.130 2000/07/20 05:10:00 guy Exp $
+ * $Id: main.c,v 1.131 2000/08/03 12:44:37 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -107,7 +107,6 @@
#include "column.h"
#include "print.h"
#include "resolv.h"
-#include "follow.h"
#include "util.h"
#include "simple_dialog.h"
#include "proto_draw.h"
@@ -117,7 +116,6 @@
#include "gtkglobals.h"
#include "plugins.h"
-FILE *data_out_file = NULL;
packet_info pi;
capture_file cfile;
GtkWidget *top_level, *packet_list, *tree_view, *byte_view,
@@ -138,10 +136,6 @@ GtkStyle *item_style;
/* Specifies the field currently selected in the GUI protocol tree */
field_info *finfo_selected = NULL;
-static void follow_destroy_cb(GtkWidget *win, gpointer data);
-static void follow_charset_toggle_cb(GtkWidget *w, gpointer parent_w);
-static void follow_load_text(GtkWidget *text, char *filename, guint8 show_type);
-static void follow_print_stream(GtkWidget *w, gpointer parent_w);
static char* hfinfo_numeric_format(header_field_info *hfinfo);
static void create_main_window(gint, gint, gint, e_prefs*);
@@ -160,435 +154,6 @@ about_ethereal( GtkWidget *w, gpointer data ) {
comp_info_str);
}
-/* Follow the TCP stream, if any, to which the last packet that we called
- a dissection routine on belongs (this might be the most recently
- selected packet, or it might be the last packet in the file). */
-void
-follow_stream_cb( GtkWidget *w, gpointer data ) {
- char filename1[128+1];
- GtkWidget *streamwindow, *box, *txt_scrollw, *text, *filter_te;
- GtkWidget *hbox, *close_bt, *print_bt;
- GtkWidget *b_ascii, *b_ebcdic, *b_hexdump;
- int tmp_fd;
- gchar *follow_filter;
-
- if( pi.ipproto == 6 ) {
- /* we got tcp so we can follow */
- /* Create a temporary file into which to dump the reassembled data
- from the TCP stream, and set "data_out_file" to refer to it, so
- that the TCP code will write to it.
-
- XXX - it might be nicer to just have the TCP code directly
- append stuff to the text widget for the TCP stream window,
- if we can arrange that said window not pop up until we're
- done. */
- tmp_fd = create_tempfile( filename1, sizeof filename1, "follow");
- if (tmp_fd == -1) {
- simple_dialog(ESD_TYPE_WARN, NULL,
- "Could not create temporary file %s: %s", filename1, strerror(errno));
- return;
- }
- data_out_file = fdopen( tmp_fd, "wb" );
- if( data_out_file == NULL ) {
- simple_dialog(ESD_TYPE_WARN, NULL,
- "Could not create temporary file %s: %s", filename1, strerror(errno));
- close(tmp_fd);
- unlink(filename1);
- return;
- }
-
- /* Create a new filter that matches all packets in the TCP stream,
- and set the display filter entry accordingly */
- reset_tcp_reassembly();
- follow_filter = build_follow_filter( &pi );
-
- /* set the display filter entry accordingly */
- filter_te = gtk_object_get_data(GTK_OBJECT(w), E_DFILTER_TE_KEY);
- gtk_entry_set_text(GTK_ENTRY(filter_te), follow_filter);
-
- /* Run the display filter so it goes in effect. */
- filter_packets(&cfile, follow_filter);
-
- /* the data_out_file should now be full of the streams information */
- fclose( data_out_file );
-
- /* the filename1 file now has all the text that was in the session */
- streamwindow = gtk_window_new( GTK_WINDOW_TOPLEVEL);
- gtk_widget_set_name( streamwindow, "TCP stream window" );
-
- gtk_signal_connect( GTK_OBJECT(streamwindow), "destroy",
- GTK_SIGNAL_FUNC(follow_destroy_cb), NULL);
-
- if( incomplete_tcp_stream ) {
- gtk_window_set_title( GTK_WINDOW(streamwindow),
- "Contents of TCP stream (incomplete)" );
- } else {
- gtk_window_set_title( GTK_WINDOW(streamwindow),
- "Contents of TCP stream" );
- }
- gtk_widget_set_usize( GTK_WIDGET(streamwindow), DEF_WIDTH, DEF_HEIGHT );
- gtk_container_border_width( GTK_CONTAINER(streamwindow), 2 );
-
- /* setup the container */
- box = gtk_vbox_new( FALSE, 0 );
- gtk_container_add( GTK_CONTAINER(streamwindow), box );
- gtk_widget_show( box );
-
- /* create a scrolled window for the text */
- txt_scrollw = gtk_scrolled_window_new( NULL, NULL );
- gtk_box_pack_start( GTK_BOX(box), txt_scrollw, TRUE, TRUE, 0 );
- gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(txt_scrollw),
- GTK_POLICY_NEVER,
- GTK_POLICY_ALWAYS );
- set_scrollbar_placement_scrollw(txt_scrollw, prefs.gui_scrollbar_on_right);
- remember_scrolled_window(txt_scrollw);
- gtk_widget_show( txt_scrollw );
-
- /* create a text box */
- text = gtk_text_new( NULL, NULL );
- gtk_text_set_editable( GTK_TEXT(text), FALSE);
- gtk_container_add( GTK_CONTAINER(txt_scrollw), text );
- gtk_widget_show(text);
-
- /* Create hbox */
- hbox = gtk_hbox_new( FALSE, 1 );
- gtk_box_pack_end( GTK_BOX(box), hbox, FALSE, FALSE, 0);
- gtk_widget_show(hbox);
-
-#define E_FOLLOW_ASCII_KEY "follow_ascii_key"
-#define E_FOLLOW_EBCDIC_KEY "follow_ebcdic_key"
-#define E_FOLLOW_HEXDUMP_KEY "follow_hexdump_key"
-
- /* Create Radio Buttons */
- b_ascii = gtk_radio_button_new_with_label(NULL, "ASCII");
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b_ascii), TRUE);
- gtk_object_set_data(GTK_OBJECT(streamwindow), E_FOLLOW_ASCII_KEY, b_ascii);
- gtk_box_pack_start(GTK_BOX(hbox), b_ascii, FALSE, FALSE, 0);
- gtk_signal_connect(GTK_OBJECT(b_ascii), "toggled",
- GTK_SIGNAL_FUNC(follow_charset_toggle_cb),
- GTK_OBJECT(streamwindow));
- gtk_widget_show(b_ascii);
-
- b_ebcdic = gtk_radio_button_new_with_label(
- gtk_radio_button_group(GTK_RADIO_BUTTON(b_ascii)),
- "EBCDIC");
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b_ebcdic), FALSE);
- gtk_object_set_data(GTK_OBJECT(streamwindow), E_FOLLOW_EBCDIC_KEY, b_ebcdic);
- gtk_box_pack_start(GTK_BOX(hbox), b_ebcdic, FALSE, FALSE, 0);
- gtk_signal_connect(GTK_OBJECT(b_ebcdic), "toggled",
- GTK_SIGNAL_FUNC(follow_charset_toggle_cb),
- GTK_OBJECT(streamwindow));
- gtk_widget_show(b_ebcdic);
-
- b_hexdump = gtk_radio_button_new_with_label(
- gtk_radio_button_group(GTK_RADIO_BUTTON(b_ascii)),
- "Hex. Dump");
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b_hexdump), FALSE);
- gtk_object_set_data(GTK_OBJECT(streamwindow), E_FOLLOW_HEXDUMP_KEY, b_hexdump);
- gtk_box_pack_start(GTK_BOX(hbox), b_hexdump, FALSE, FALSE, 0);
- gtk_signal_connect(GTK_OBJECT(b_hexdump), "toggled",
- GTK_SIGNAL_FUNC(follow_charset_toggle_cb),
- GTK_OBJECT(streamwindow));
- gtk_widget_show(b_hexdump);
-
- /* Create Close Button */
- close_bt = gtk_button_new_with_label("Close");
- gtk_signal_connect_object(GTK_OBJECT(close_bt), "clicked",
- GTK_SIGNAL_FUNC(gtk_widget_destroy),
- GTK_OBJECT(streamwindow));
- gtk_box_pack_end( GTK_BOX(hbox), close_bt, FALSE, FALSE, 0);
- gtk_widget_show( close_bt );
-
- /* Create Print Button */
- print_bt = gtk_button_new_with_label("Print");
- gtk_signal_connect(GTK_OBJECT(print_bt), "clicked",
- GTK_SIGNAL_FUNC(follow_print_stream),
- GTK_OBJECT(streamwindow));
- gtk_box_pack_end( GTK_BOX(hbox), print_bt, FALSE, FALSE, 0);
- gtk_widget_show( print_bt );
-
- /* Tuck away the filename and textbox into streamwindow */
-#define E_FOLLOW_FILENAME_KEY "follow_filename_key"
-#define E_FOLLOW_TEXT_KEY "follow_text_key"
-
- gtk_object_set_data(GTK_OBJECT(streamwindow), E_FOLLOW_FILENAME_KEY,
- g_strdup(filename1));
- gtk_object_set_data(GTK_OBJECT(streamwindow), E_FOLLOW_TEXT_KEY, text);
-
- follow_load_text(text, filename1, 0);
-
- data_out_file = NULL;
-
- /* Make sure this widget gets destroyed if we quit the main loop,
- so that if we exit, we clean up any temporary files we have
- for "Follow TCP Stream" windows. */
- gtk_quit_add_destroy(gtk_main_level(), GTK_OBJECT(streamwindow));
- gtk_widget_show( streamwindow );
- } else {
- simple_dialog(ESD_TYPE_CRIT, NULL,
- "Error following stream. Please make\n"
- "sure you have a TCP packet selected.");
- }
-}
-
-/* The destroy call back has the responsibility of
- * unlinking the temporary file */
-static void
-follow_destroy_cb(GtkWidget *win, gpointer data)
-{
- char *filename;
-
- filename = (char*) gtk_object_get_data(GTK_OBJECT(win),
- E_FOLLOW_FILENAME_KEY);
- g_assert(filename);
-
- unlink(filename);
- gtk_widget_destroy(win);
-}
-
-#define E_FOLLOW_ASCII_TYPE 0
-#define E_FOLLOW_EBCDIC_TYPE 1
-#define E_FOLLOW_HEXDUMP_TYPE 2
-
-/* Handles the ASCII/EBCDIC toggling */
-static void
-follow_charset_toggle_cb(GtkWidget *w, gpointer parent_w)
-{
- guint8 show_type = E_FOLLOW_ASCII_TYPE;
- GtkWidget *b_ascii, *b_ebcdic, *b_hexdump, *text;
- char *filename;
-
- b_ascii = (GtkWidget*) gtk_object_get_data(GTK_OBJECT(parent_w),
- E_FOLLOW_ASCII_KEY);
- b_ebcdic = (GtkWidget*) gtk_object_get_data(GTK_OBJECT(parent_w),
- E_FOLLOW_EBCDIC_KEY);
- b_hexdump = (GtkWidget*) gtk_object_get_data(GTK_OBJECT(parent_w),
- E_FOLLOW_HEXDUMP_KEY);
- text = (GtkWidget*) gtk_object_get_data(GTK_OBJECT(parent_w),
- E_FOLLOW_TEXT_KEY);
- filename = (char*) gtk_object_get_data(GTK_OBJECT(parent_w),
- E_FOLLOW_FILENAME_KEY);
-
- g_assert(b_ascii);
- g_assert(b_ebcdic);
- g_assert(b_hexdump);
- g_assert(text);
- g_assert(filename);
-
- if (GTK_TOGGLE_BUTTON(b_ebcdic)->active)
- show_type = E_FOLLOW_EBCDIC_TYPE;
- else if (GTK_TOGGLE_BUTTON(b_hexdump)->active)
- show_type = E_FOLLOW_HEXDUMP_TYPE;
-
- follow_load_text(text, filename, show_type);
-}
-
-#define FLT_BUF_SIZE 1024
-static void
-follow_read_stream(char *filename, guint8 show_type,
- void (*print_line)(char *, int, gboolean, void *), void *arg)
-{
- tcp_stream_chunk sc;
- int bcount;
- guint32 client_addr = 0;
- guint16 client_port = 0;
- gboolean is_server;
- guint16 current_pos, global_client_pos = 0, global_server_pos = 0;
- guint16 *global_pos;
-
- data_out_file = fopen( filename, "rb" );
- if( data_out_file ) {
- char buffer[FLT_BUF_SIZE];
- int nchars;
- while(fread(&sc.src_addr, 1, sizeof(sc), data_out_file)) {
- if (client_addr == 0) {
- client_addr = sc.src_addr;
- client_port = sc.src_port;
- }
- if (client_addr == sc.src_addr && client_port == sc.src_port) {
- is_server = FALSE;
- global_pos = &global_client_pos;
- }
- else {
- is_server = TRUE;
- global_pos = &global_server_pos;
- }
-
- while (sc.dlen > 0) {
- bcount = (sc.dlen < FLT_BUF_SIZE) ? sc.dlen : FLT_BUF_SIZE;
- nchars = fread( buffer, 1, bcount, data_out_file );
- if (nchars == 0)
- break;
- sc.dlen -= bcount;
- switch (show_type) {
- case E_FOLLOW_EBCDIC_TYPE:
- /* If our native arch is ASCII, call: */
- EBCDIC_to_ASCII(buffer, nchars);
- case E_FOLLOW_ASCII_TYPE:
- /* If our native arch is EBCDIC, call:
- * ASCII_TO_EBCDIC(buffer, nchars);
- */
- (*print_line)( buffer, nchars, is_server, arg );
- break;
- case E_FOLLOW_HEXDUMP_TYPE:
- current_pos = 0;
- while (current_pos < nchars)
- {
- gchar hexbuf[256];
- gchar hexchars[] = "0123456789abcdef";
- int i, cur;
- /* is_server indentation : put 63 spaces at the begenning
- * of the string */
- sprintf(hexbuf, is_server ?
- " "
- " %08X " :
- "%08X ", *global_pos);
- cur = strlen(hexbuf);
- for (i=0; i < 16 && current_pos+i < nchars; i++) {
- hexbuf[cur++] = hexchars[(buffer[current_pos+i] & 0xf0) >> 4];
- hexbuf[cur++] = hexchars[buffer[current_pos+i] & 0x0f];
- if (i == 7) {
- hexbuf[cur++] = ' '; hexbuf[cur++] = ' ';
- }
- else if (i != 15)
- hexbuf[cur++] = ' ';
- }
- current_pos += i;
- (*global_pos) += i;
- hexbuf[cur++] = '\n';
- hexbuf[cur] = 0;
- (*print_line)( hexbuf, strlen(hexbuf), is_server, arg );
- }
- break;
- }
- }
- }
- if( ferror( data_out_file ) ) {
- simple_dialog(ESD_TYPE_WARN, NULL,
- "Error reading temporary file %s: %s", filename, strerror(errno));
- }
- fclose( data_out_file );
- data_out_file = NULL;
- } else {
- simple_dialog(ESD_TYPE_WARN, NULL,
- "Could not open temporary file %s: %s", filename, strerror(errno));
- }
-}
-
-/*
- * XXX - for text printing, we probably want to wrap lines at 80 characters;
- * for PostScript printing, we probably want to wrap them at the appropriate
- * width, and perhaps put some kind of dingbat (to use the technical term)
- * to indicate a wrapped line, along the lines of what's done when displaying
- * this in a window, as per Warren Young's suggestion.
- *
- * For now, we support only text printing.
- */
-static void
-follow_print_text(char *buffer, int nchars, gboolean is_server, void *arg)
-{
- FILE *fh = arg;
-
- fwrite(buffer, nchars, 1, fh);
-}
-
-static void
-follow_print_stream(GtkWidget *w, gpointer parent_w)
-{
- FILE *fh;
- gboolean to_file;
- char* print_dest;
- char* filename;
- guint8 show_type = E_FOLLOW_ASCII_TYPE;
- GtkWidget *button;
-
- switch (prefs.pr_dest) {
- case PR_DEST_CMD:
- print_dest = prefs.pr_cmd;
- to_file = FALSE;
- break;
-
- case PR_DEST_FILE:
- print_dest = prefs.pr_file;
- to_file = TRUE;
- break;
- default: /* "Can't happen" */
- simple_dialog(ESD_TYPE_CRIT, NULL,
- "Couldn't figure out where to send the print "
- "job. Check your preferences.");
- return;
- }
-
- fh = open_print_dest(to_file, print_dest);
- if (fh == NULL) {
- switch (to_file) {
- case FALSE:
- simple_dialog(ESD_TYPE_WARN, NULL,
- "Couldn't run print command %s.", prefs.pr_cmd);
- break;
-
- case TRUE:
- simple_dialog(ESD_TYPE_WARN, NULL,
- file_write_error_message(errno),
- prefs.pr_file);
- break;
- }
- return;
- }
-
- button = (GtkWidget*) gtk_object_get_data(GTK_OBJECT(parent_w),
- E_FOLLOW_EBCDIC_KEY);
- if (GTK_TOGGLE_BUTTON(button)->active)
- show_type = E_FOLLOW_EBCDIC_TYPE;
- button = (GtkWidget*) gtk_object_get_data(GTK_OBJECT(parent_w),
- E_FOLLOW_HEXDUMP_KEY);
- if (GTK_TOGGLE_BUTTON(button)->active)
- show_type = E_FOLLOW_HEXDUMP_TYPE;
-
- filename = (char*) gtk_object_get_data(GTK_OBJECT(parent_w),
- E_FOLLOW_FILENAME_KEY);
-
- if (filename != NULL) {
- print_preamble(fh, PR_FMT_TEXT);
- follow_read_stream(filename, show_type, follow_print_text, fh);
- print_finale(fh, PR_FMT_TEXT);
- close_print_dest(to_file, fh);
- }
- else {
- simple_dialog(ESD_TYPE_WARN, NULL, "Could not find data to print.");
- }
-}
-
-static void
-follow_add_to_gtk_text(char *buffer, int nchars, gboolean is_server, void *arg)
-{
- GtkWidget *text = arg;
-
- if (is_server)
- gtk_text_insert( GTK_TEXT(text), m_r_font, &prefs.st_server_fg,
- &prefs.st_server_bg, buffer, nchars );
- else
- gtk_text_insert( GTK_TEXT(text), m_r_font, &prefs.st_client_fg,
- &prefs.st_client_bg, buffer, nchars );
-}
-
-static void
-follow_load_text(GtkWidget *text, char *filename, guint8 show_type)
-{
- int bytes_already;
-
- /* Delete any info already in text box */
- bytes_already = gtk_text_get_length(GTK_TEXT(text));
- if (bytes_already > 0) {
- gtk_text_set_point(GTK_TEXT(text), 0);
- gtk_text_forward_delete(GTK_TEXT(text), bytes_already);
- }
-
- /* stop the updates while we fill the text box */
- gtk_text_freeze( GTK_TEXT(text) );
- follow_read_stream(filename, show_type, follow_add_to_gtk_text, text);
- gtk_text_thaw( GTK_TEXT(text) );
-}
/* Match selected byte pattern */
void
diff --git a/gtk/main.h b/gtk/main.h
index 3de597e83e..f846cfd9bb 100644
--- a/gtk/main.h
+++ b/gtk/main.h
@@ -1,7 +1,7 @@
/* ethereal.h
* Global defines, etc.
*
- * $Id: main.h,v 1.14 2000/02/20 14:52:28 deniel Exp $
+ * $Id: main.h,v 1.15 2000/08/03 12:44:39 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -59,7 +59,6 @@ extern GtkStyle *item_style;
void about_ethereal( GtkWidget *, gpointer);
void blank_packetinfo();
-void follow_stream_cb( GtkWidget *, gpointer);
void match_selected_cb( GtkWidget *, gpointer);
void file_quit_cmd_cb(GtkWidget *, gpointer);
void file_print_cmd_cb(GtkWidget *, gpointer);
diff --git a/gtk/menu.c b/gtk/menu.c
index 91ef29d834..dcf2fd13df 100644
--- a/gtk/menu.c
+++ b/gtk/menu.c
@@ -1,7 +1,7 @@
/* menu.c
* Menu routines
*
- * $Id: menu.c,v 1.31 2000/07/05 06:33:01 guy Exp $
+ * $Id: menu.c,v 1.32 2000/08/03 12:44:40 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -53,7 +53,7 @@
#include "prefs_dlg.h"
#include "packet_win.h"
#include "print.h"
-#include "follow.h"
+#include "follow_dlg.h"
#include "keys.h"
#include "plugins.h"
diff --git a/gtk/packet_win.c b/gtk/packet_win.c
index 423ea58d3d..7547c5c3ec 100644
--- a/gtk/packet_win.c
+++ b/gtk/packet_win.c
@@ -3,7 +3,7 @@
*
* Copyright 2000, Jeffrey C. Foster <jfoste@woodward.com>
*
- * $Id: packet_win.c,v 1.9 2000/06/27 04:36:03 guy Exp $
+ * $Id: packet_win.c,v 1.10 2000/08/03 12:44:40 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -58,7 +58,6 @@
#include "column.h"
#include "print.h"
#include "resolv.h"
-#include "follow.h"
#include "util.h"
#include "packet_win.h"
#include "simple_dialog.h"
diff --git a/print.h b/print.h
index fa5f409ce6..d47d66936e 100644
--- a/print.h
+++ b/print.h
@@ -1,7 +1,7 @@
/* print.h
* Definitions for printing packet analysis trees.
*
- * $Id: print.h,v 1.18 2000/01/22 06:22:19 guy Exp $
+ * $Id: print.h,v 1.19 2000/08/03 12:44:21 gram Exp $
*
* Gilbert Ramirez <gram@xiexie.org>
*
@@ -28,6 +28,10 @@
#ifndef __PRINT_H__
#define __PRINT_H__
+#ifndef __PACKET_H__
+#include "packet.h"
+#endif
+
#define PR_FMT_TEXT 0
#define PR_FMT_PS 1
diff --git a/tethereal.c b/tethereal.c
index c5d1ac63d1..b0fdc0d837 100644
--- a/tethereal.c
+++ b/tethereal.c
@@ -1,6 +1,6 @@
/* tethereal.c
*
- * $Id: tethereal.c,v 1.37 2000/07/24 16:27:34 gram Exp $
+ * $Id: tethereal.c,v 1.38 2000/08/03 12:44:21 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -78,7 +78,6 @@
#include "column.h"
#include "print.h"
#include "resolv.h"
-#include "follow.h"
#include "util.h"
#include "ui_util.h"
#include "conversation.h"