diff options
-rw-r--r-- | file.c | 130 | ||||
-rw-r--r-- | file.h | 4 | ||||
-rw-r--r-- | follow.c | 4 | ||||
-rw-r--r-- | globals.h | 3 | ||||
-rw-r--r-- | gtk/Makefile.am | 4 | ||||
-rw-r--r-- | gtk/Makefile.nmake | 1 | ||||
-rw-r--r-- | gtk/follow_dlg.c | 551 | ||||
-rw-r--r-- | gtk/follow_dlg.h | 26 | ||||
-rw-r--r-- | gtk/main.c | 437 | ||||
-rw-r--r-- | gtk/main.h | 3 | ||||
-rw-r--r-- | gtk/menu.c | 4 | ||||
-rw-r--r-- | gtk/packet_win.c | 3 | ||||
-rw-r--r-- | print.h | 6 | ||||
-rw-r--r-- | tethereal.c | 3 |
14 files changed, 674 insertions, 505 deletions
@@ -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; +} @@ -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 */ @@ -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; @@ -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" @@ -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" |