aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>1999-07-23 08:29:24 +0000
committerGuy Harris <guy@alum.mit.edu>1999-07-23 08:29:24 +0000
commit356a07b384d1b3ff58ccf8a5f01b76f879055baf (patch)
tree5546665a4b2e1fa09c5d4a74623c5c860cf70b03
parentde459d1426cc27341dcf681cf5b35c27c9a5732a (diff)
Add a "File/Print" menu item, which prints *all* the packets in the
capture to a file or printer. This should eventually get the ability to print either all the packets or only the packets selected by the display filter, and possibly also the ability to print only packets M through N. Get rid of "cur" member of "capture_file" structure; nobody used it. There's no need to pass a pointer to a "dialog_button" variable to "simple_dialog()" for the error boxes displayed if a file copy or move fails; that dialog box is just a message box and has only an "OK" button. Put the declaration of "prefs" into "prefs.h". svn path=/trunk/; revision=378
-rw-r--r--capture.c5
-rw-r--r--column.c4
-rw-r--r--ethereal.c329
-rw-r--r--file.c65
-rw-r--r--file.h5
-rw-r--r--menu.c6
-rw-r--r--prefs.h4
-rw-r--r--print.c45
-rw-r--r--print.h7
9 files changed, 417 insertions, 53 deletions
diff --git a/capture.c b/capture.c
index b7ebe8ca89..5d5db6197c 100644
--- a/capture.c
+++ b/capture.c
@@ -1,7 +1,7 @@
/* capture.c
* Routines for packet capture windows
*
- * $Id: capture.c,v 1.33 1999/07/20 06:16:08 guy Exp $
+ * $Id: capture.c,v 1.34 1999/07/23 08:29:23 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -567,7 +567,8 @@ capture(void) {
}
}
set_menu_sensitivity("/File/Save", TRUE);
- set_menu_sensitivity("/File/Save as", FALSE);
+ set_menu_sensitivity("/File/Save As...", FALSE);
+ set_menu_sensitivity("/File/Print...", TRUE);
set_menu_sensitivity("/Tools/Summary", TRUE);
}
diff --git a/column.c b/column.c
index 77cfc7cc97..c3d9c35203 100644
--- a/column.c
+++ b/column.c
@@ -1,7 +1,7 @@
/* column.c
* Routines for handling column preferences
*
- * $Id: column.c,v 1.18 1999/07/22 21:14:13 guy Exp $
+ * $Id: column.c,v 1.19 1999/07/23 08:29:23 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -48,8 +48,6 @@
#include "column.h"
#include "packet.h"
-extern e_prefs prefs;
-
static GtkWidget *column_l, *chg_bt, *del_bt, *title_te, *fmt_m, *up_bt,
*dn_bt;
static gint cur_fmt;
diff --git a/ethereal.c b/ethereal.c
index 1b080b534a..1e29b9041f 100644
--- a/ethereal.c
+++ b/ethereal.c
@@ -1,6 +1,6 @@
/* ethereal.c
*
- * $Id: ethereal.c,v 1.58 1999/07/22 21:14:12 guy Exp $
+ * $Id: ethereal.c,v 1.59 1999/07/23 08:29:21 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -100,6 +100,12 @@
static void file_save_ok_cb(GtkWidget *w, GtkFileSelection *fs);
static void file_save_as_ok_cb(GtkWidget *w, GtkFileSelection *fs);
+static void print_cmd_toggle_dest(GtkWidget *widget, gpointer data);
+static void print_file_cb(GtkWidget *file_bt, gpointer file_te);
+static void print_fs_ok_cb(GtkWidget *w, gpointer data);
+static void print_fs_cancel_cb(GtkWidget *w, gpointer data);
+static void print_ok_cb(GtkWidget *ok_bt, gpointer parent_w);
+static void print_close_cb(GtkWidget *close_bt, gpointer parent_w);
FILE *data_out_file = NULL;
packet_info pi;
@@ -188,6 +194,7 @@ file_sel_ok_cb(GtkWidget *w, GtkFileSelection *fs) {
g_free(cf_name);
set_menu_sensitivity("/File/Save", FALSE);
set_menu_sensitivity("/File/Save As...", TRUE);
+ set_menu_sensitivity("/File/Print...", TRUE);
set_menu_sensitivity("/Tools/Summary", TRUE);
}
@@ -422,6 +429,7 @@ file_close_cmd_cb(GtkWidget *widget, gpointer data) {
close_cap_file(&cf, info_bar, file_ctx);
set_menu_sensitivity("/File/Close", FALSE);
set_menu_sensitivity("/File/Reload", FALSE);
+ set_menu_sensitivity("/File/Print...", FALSE);
set_menu_sensitivity("/Tools/Summary", FALSE);
}
@@ -537,15 +545,321 @@ filter_activate_cb(GtkWidget *w, gpointer data) {
filter_packets(&cf);
}
-/* Print a packet */
+/*
+ * Remember whether we printed to a printer or a file the last time we
+ * printed something.
+ */
+static int print_to_file;
+
+/* Keys for gtk_object_set_data */
+#define PRINT_CMD_LB_KEY "printer_command_label"
+#define PRINT_CMD_TE_KEY "printer_command_entry"
+#define PRINT_FILE_BT_KEY "printer_file_button"
+#define PRINT_FILE_TE_KEY "printer_file_entry"
+#define PRINT_DEST_RB_KEY "printer_destination_radio_button"
+
+/* Print the capture */
void
-file_print_cmd_cb(GtkWidget *widget, gpointer data) {
- if (protocol_tree == NULL) {
+file_print_cmd_cb(GtkWidget *widget, gpointer data)
+{
+ GtkWidget *print_w;
+ GtkWidget *main_vb, *main_tb, *button;
+ GtkWidget *format_hb, *format_lb;
+ GtkWidget *dest_rb;
+ GtkWidget *dest_hb, *dest_lb;
+ GtkWidget *cmd_lb, *cmd_te;
+ GtkWidget *file_bt_hb, *file_bt, *file_te;
+ GSList *format_grp, *dest_grp;
+ GtkWidget *bbox, *ok_bt, *cancel_bt;
+
+ /* XXX - don't pop up one if there's already one open; instead,
+ give it the input focus if that's possible. */
+
+ print_w = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_title(GTK_WINDOW(print_w), "Ethereal: Print");
+
+ /* Enclosing containers for each row of widgets */
+ main_vb = gtk_vbox_new(FALSE, 5);
+ gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
+ gtk_container_add(GTK_CONTAINER(print_w), main_vb);
+ gtk_widget_show(main_vb);
+
+ main_tb = gtk_table_new(4, 2, FALSE);
+ gtk_box_pack_start(GTK_BOX(main_vb), main_tb, FALSE, FALSE, 0);
+ gtk_table_set_row_spacings(GTK_TABLE(main_tb), 10);
+ gtk_table_set_col_spacings(GTK_TABLE(main_tb), 15);
+ gtk_widget_show(main_tb);
+
+ /* Output format */
+ format_lb = gtk_label_new("Format:");
+ gtk_misc_set_alignment(GTK_MISC(format_lb), 1.0, 0.5);
+ gtk_table_attach_defaults(GTK_TABLE(main_tb), format_lb, 0, 1, 0, 1);
+ gtk_widget_show(format_lb);
+
+ format_hb = gtk_hbox_new(FALSE, 0);
+ gtk_table_attach_defaults(GTK_TABLE(main_tb), format_hb, 1, 2, 0, 1);
+ gtk_widget_show(format_hb);
+
+ button = gtk_radio_button_new_with_label(NULL, "Plain Text");
+ if (prefs.pr_format == PR_FMT_TEXT)
+ gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button), TRUE);
+ format_grp = gtk_radio_button_group(GTK_RADIO_BUTTON(button));
+ gtk_box_pack_start(GTK_BOX(format_hb), button, FALSE, FALSE, 10);
+ gtk_widget_show(button);
+
+ button = gtk_radio_button_new_with_label(format_grp, "PostScript");
+ if (prefs.pr_format == PR_FMT_PS)
+ gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button), TRUE);
+ gtk_box_pack_start(GTK_BOX(format_hb), button, FALSE, FALSE, 10);
+ gtk_widget_show(button);
+
+ /* Output destination */
+ dest_lb = gtk_label_new("Print to:");
+ gtk_misc_set_alignment(GTK_MISC(dest_lb), 1.0, 0.5);
+ gtk_table_attach_defaults(GTK_TABLE(main_tb), dest_lb, 0, 1, 1, 2);
+ gtk_widget_show(dest_lb);
+
+ dest_hb = gtk_hbox_new(FALSE, 0);
+ gtk_table_attach_defaults(GTK_TABLE(main_tb), dest_hb, 1, 2, 1, 2);
+ gtk_widget_show(dest_hb);
+
+ button = gtk_radio_button_new_with_label(NULL, "Command");
+ if (!print_to_file)
+ gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button), TRUE);
+ dest_grp = gtk_radio_button_group(GTK_RADIO_BUTTON(button));
+ gtk_box_pack_start(GTK_BOX(dest_hb), button, FALSE, FALSE, 10);
+ gtk_widget_show(button);
+
+ dest_rb = gtk_radio_button_new_with_label(dest_grp, "File");
+ if (print_to_file)
+ gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(dest_rb), TRUE);
+ gtk_signal_connect(GTK_OBJECT(dest_rb), "toggled",
+ GTK_SIGNAL_FUNC(print_cmd_toggle_dest), NULL);
+ gtk_box_pack_start(GTK_BOX(dest_hb), dest_rb, FALSE, FALSE, 10);
+ gtk_widget_show(dest_rb);
+
+ /* Command text entry */
+ cmd_lb = gtk_label_new("Command:");
+ gtk_object_set_data(GTK_OBJECT(dest_rb), PRINT_CMD_LB_KEY, cmd_lb);
+ gtk_misc_set_alignment(GTK_MISC(cmd_lb), 1.0, 0.5);
+ gtk_table_attach_defaults(GTK_TABLE(main_tb), cmd_lb, 0, 1, 2, 3);
+ gtk_widget_set_sensitive(cmd_lb, !print_to_file);
+ gtk_widget_show(cmd_lb);
+
+ cmd_te = gtk_entry_new();
+ gtk_object_set_data(GTK_OBJECT(dest_rb), PRINT_CMD_TE_KEY, cmd_te);
+ if (prefs.pr_cmd)
+ gtk_entry_set_text(GTK_ENTRY(cmd_te), prefs.pr_cmd);
+ gtk_table_attach_defaults(GTK_TABLE(main_tb), cmd_te, 1, 2, 2, 3);
+ gtk_widget_set_sensitive(cmd_te, !print_to_file);
+ gtk_widget_show(cmd_te);
+
+ /* File button and text entry */
+ file_bt_hb = gtk_hbox_new(FALSE, 0);
+ gtk_table_attach_defaults(GTK_TABLE(main_tb), file_bt_hb, 0, 1, 3, 4);
+ gtk_widget_show(file_bt_hb);
+
+ file_bt = gtk_button_new_with_label("File:");
+ gtk_object_set_data(GTK_OBJECT(dest_rb), PRINT_FILE_BT_KEY, file_bt);
+ gtk_box_pack_end(GTK_BOX(file_bt_hb), file_bt, FALSE, FALSE, 0);
+ gtk_widget_set_sensitive(file_bt, print_to_file);
+ gtk_widget_show(file_bt);
+
+ file_te = gtk_entry_new();
+ gtk_object_set_data(GTK_OBJECT(dest_rb), PRINT_FILE_TE_KEY, file_te);
+ if (prefs.pr_file)
+ gtk_entry_set_text(GTK_ENTRY(file_te), prefs.pr_file);
+ gtk_table_attach_defaults(GTK_TABLE(main_tb), file_te, 1, 2, 3, 4);
+ gtk_widget_set_sensitive(file_te, print_to_file);
+ gtk_widget_show(file_te);
+
+ gtk_signal_connect(GTK_OBJECT(file_bt), "clicked",
+ GTK_SIGNAL_FUNC(print_file_cb), GTK_OBJECT(file_te));
+
+ /* Button row: OK and Cancel buttons */
+ bbox = gtk_hbutton_box_new();
+ gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_END);
+ gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5);
+ gtk_container_add(GTK_CONTAINER(main_vb), bbox);
+ gtk_widget_show(bbox);
+
+ ok_bt = gtk_button_new_with_label ("OK");
+ gtk_object_set_data(GTK_OBJECT(ok_bt), PRINT_DEST_RB_KEY, dest_rb);
+ gtk_object_set_data(GTK_OBJECT(ok_bt), PRINT_CMD_TE_KEY, cmd_te);
+ gtk_object_set_data(GTK_OBJECT(ok_bt), PRINT_FILE_TE_KEY, file_te);
+ gtk_signal_connect(GTK_OBJECT(ok_bt), "clicked",
+ GTK_SIGNAL_FUNC(print_ok_cb), GTK_OBJECT(print_w));
+ GTK_WIDGET_SET_FLAGS(ok_bt, GTK_CAN_DEFAULT);
+ gtk_box_pack_start (GTK_BOX (bbox), ok_bt, TRUE, TRUE, 0);
+ gtk_widget_grab_default(ok_bt);
+ gtk_widget_show(ok_bt);
+
+ cancel_bt = gtk_button_new_with_label ("Cancel");
+ gtk_signal_connect(GTK_OBJECT(cancel_bt), "clicked",
+ GTK_SIGNAL_FUNC(print_close_cb), GTK_OBJECT(print_w));
+ GTK_WIDGET_SET_FLAGS(cancel_bt, GTK_CAN_DEFAULT);
+ gtk_box_pack_start (GTK_BOX (bbox), cancel_bt, TRUE, TRUE, 0);
+ gtk_widget_show(cancel_bt);
+
+#if 0
+ display_opt_window_active = TRUE;
+#endif
+ gtk_widget_show(print_w);
+}
+
+static void
+print_cmd_toggle_dest(GtkWidget *widget, gpointer data)
+{
+ GtkWidget *cmd_lb, *cmd_te, *file_bt, *file_te;
+ int to_file;
+
+ cmd_lb = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(widget),
+ PRINT_CMD_LB_KEY));
+ cmd_te = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(widget),
+ PRINT_CMD_TE_KEY));
+ file_bt = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(widget),
+ PRINT_FILE_BT_KEY));
+ file_te = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(widget),
+ PRINT_FILE_TE_KEY));
+ if (GTK_TOGGLE_BUTTON (widget)->active) {
+ /* They selected "Print to File" */
+ to_file = TRUE;
+ } else {
+ /* They selected "Print to Command" */
+ to_file = FALSE;
+ }
+ gtk_widget_set_sensitive(cmd_lb, !to_file);
+ gtk_widget_set_sensitive(cmd_te, !to_file);
+ gtk_widget_set_sensitive(file_bt, to_file);
+ gtk_widget_set_sensitive(file_te, to_file);
+}
+
+static void
+print_file_cb(GtkWidget *file_bt, gpointer file_te)
+{
+ GtkWidget *fs;
+
+ fs = gtk_file_selection_new ("Ethereal: Print to File");
+ gtk_object_set_data(GTK_OBJECT(fs), PRINT_FILE_TE_KEY, file_te);
+
+ gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION(fs)->ok_button),
+ "clicked", (GtkSignalFunc) print_fs_ok_cb, fs);
+
+ /* Connect the cancel_button to destroy the widget */
+ gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION(fs)->cancel_button),
+ "clicked", (GtkSignalFunc) print_fs_cancel_cb, fs);
+
+ gtk_widget_show(fs);
+}
+
+static void
+print_fs_ok_cb(GtkWidget *w, gpointer data)
+{
+
+ gtk_entry_set_text(GTK_ENTRY(gtk_object_get_data(GTK_OBJECT(data),
+ PRINT_FILE_TE_KEY)),
+ gtk_file_selection_get_filename (GTK_FILE_SELECTION(data)));
+ gtk_widget_destroy(GTK_WIDGET(data));
+}
+
+static void
+print_fs_cancel_cb(GtkWidget *w, gpointer data)
+{
+
+ gtk_widget_destroy(GTK_WIDGET(data));
+}
+
+static void
+print_ok_cb(GtkWidget *ok_bt, gpointer parent_w)
+{
+ GtkWidget *button;
+ char *dest;
+
+ button = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(ok_bt),
+ PRINT_DEST_RB_KEY);
+ if (GTK_TOGGLE_BUTTON (button)->active)
+ print_to_file = TRUE;
+ else
+ print_to_file = FALSE;
+
+ if (print_to_file)
+ dest = g_strdup(gtk_entry_get_text(GTK_ENTRY(gtk_object_get_data(GTK_OBJECT(ok_bt),
+ PRINT_FILE_TE_KEY))));
+ else
+ dest = g_strdup(gtk_entry_get_text(GTK_ENTRY(gtk_object_get_data(GTK_OBJECT(ok_bt),
+ PRINT_CMD_TE_KEY))));
+
+ gtk_widget_destroy(GTK_WIDGET(parent_w));
+#if 0
+ display_opt_window_active = FALSE;
+#endif
+
+ /* Now print the packets */
+ if (!print_packets(&cf, print_to_file, dest)) {
+ if (print_to_file)
simple_dialog(ESD_TYPE_WARN, NULL,
- "No packet is selected, so there's no packet to print.");
- return;
+ file_write_error_message(errno), dest);
+ else
+ simple_dialog(ESD_TYPE_WARN, NULL, "Couldn't run print command %s.",
+ prefs.pr_cmd);
+ }
+
+ g_free(dest);
+}
+
+static void
+print_close_cb(GtkWidget *close_bt, gpointer parent_w)
+{
+
+ gtk_grab_remove(GTK_WIDGET(parent_w));
+ gtk_widget_destroy(GTK_WIDGET(parent_w));
+#if 0
+ display_opt_window_active = FALSE;
+#endif
+}
+
+/* Print a packet */
+void
+file_print_packet_cmd_cb(GtkWidget *widget, gpointer data) {
+ FILE *fh;
+
+ switch (prefs.pr_dest) {
+
+ case PR_DEST_CMD:
+ fh = popen(prefs.pr_cmd, "w");
+ break;
+
+ case PR_DEST_FILE:
+ fh = fopen(prefs.pr_file, "w");
+ break;
+
+ default:
+ fh = NULL; /* XXX - "can't happen" */
+ break;
+ }
+ if (fh == NULL) {
+ switch (prefs.pr_dest) {
+
+ case PR_DEST_CMD:
+ simple_dialog(ESD_TYPE_WARN, NULL, "Couldn't run print command %s.",
+ prefs.pr_cmd);
+ break;
+
+ case PR_DEST_FILE:
+ simple_dialog(ESD_TYPE_WARN, NULL, file_write_error_message(errno),
+ prefs.pr_file);
+ break;
}
- proto_tree_print((GNode*) protocol_tree, cf.pd, fd);
+ return;
+ }
+
+ if (protocol_tree == NULL) {
+ simple_dialog(ESD_TYPE_WARN, NULL,
+ "No packet is selected, so there's no packet to print.");
+ return;
+ }
+ proto_tree_print((GNode*) protocol_tree, cf.pd, fd, fh);
+ close_print_dest(prefs.pr_dest == PR_DEST_FILE, fh);
}
/* What to do when a list item is selected/unselected */
@@ -1052,6 +1366,7 @@ main(int argc, char *argv[])
}
cf_name[0] = '\0';
set_menu_sensitivity("/File/Save As...", TRUE);
+ set_menu_sensitivity("/File/Print...", TRUE);
set_menu_sensitivity("/Tools/Summary", TRUE);
}
diff --git a/file.c b/file.c
index 609514a736..6196368c78 100644
--- a/file.c
+++ b/file.c
@@ -1,7 +1,7 @@
/* file.c
* File I/O routines
*
- * $Id: file.c,v 1.40 1999/07/22 21:14:11 guy Exp $
+ * $Id: file.c,v 1.41 1999/07/23 08:29:20 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -69,6 +69,7 @@
#include "column.h"
#include "menu.h"
#include "packet.h"
+#include "print.h"
#include "file.h"
#include "util.h"
#include "dfilter.h"
@@ -233,6 +234,7 @@ load_cap_file(char *fname, capture_file *cf) {
/* name_ptr[-1] = '\0'; Why is this here? It causes problems with capture files */
set_menu_sensitivity("/File/Close", TRUE);
set_menu_sensitivity("/File/Reload", TRUE);
+ set_menu_sensitivity("/File/Print...", TRUE);
set_menu_sensitivity("/Tools/Summary", TRUE);
} else {
msg_len = strlen(name_ptr) + strlen(err_fmt) + 2;
@@ -243,6 +245,7 @@ load_cap_file(char *fname, capture_file *cf) {
set_menu_sensitivity("/File/Close", FALSE);
set_menu_sensitivity("/File/Save", FALSE);
set_menu_sensitivity("/File/Save As...", FALSE);
+ set_menu_sensitivity("/File/Print...", FALSE);
set_menu_sensitivity("/File/Reload", FALSE);
set_menu_sensitivity("/Tools/Summary", FALSE);
}
@@ -292,6 +295,7 @@ cap_file_input_cb (gpointer data, gint source, GdkInputCondition condition) {
set_menu_sensitivity("/File/Open...", TRUE);
set_menu_sensitivity("/File/Close", TRUE);
set_menu_sensitivity("/File/Save As...", TRUE);
+ set_menu_sensitivity("/File/Print...", TRUE);
set_menu_sensitivity("/File/Reload", TRUE);
set_menu_sensitivity("/Capture/Start...", TRUE);
set_menu_sensitivity("/Tools/Capture...", TRUE);
@@ -357,6 +361,7 @@ tail_cap_file(char *fname, capture_file *cf) {
set_menu_sensitivity("/File/Open...", FALSE);
set_menu_sensitivity("/File/Close", FALSE);
set_menu_sensitivity("/File/Reload", FALSE);
+ set_menu_sensitivity("/File/Print...", FALSE);
set_menu_sensitivity("/Capture/Start...", FALSE);
set_menu_sensitivity("/Tools/Capture...", FALSE);
set_menu_sensitivity("/Tools/Summary", FALSE);
@@ -377,6 +382,7 @@ tail_cap_file(char *fname, capture_file *cf) {
set_menu_sensitivity("/File/Save", FALSE);
set_menu_sensitivity("/File/Save As...", FALSE);
set_menu_sensitivity("/File/Reload", FALSE);
+ set_menu_sensitivity("/File/Print...", FALSE);
set_menu_sensitivity("/Tools/Summary", FALSE);
close(sync_pipe[0]);
}
@@ -468,7 +474,6 @@ wtap_dispatch_cb(u_char *user, const struct wtap_pkthdr *phdr, int offset,
fdata = (frame_data *) g_malloc(sizeof(frame_data));
cf->plist = g_list_append(cf->plist, (gpointer) fdata);
- cf->cur = fdata;
cf->count++;
fdata->pkt_len = phdr->len;
@@ -488,7 +493,6 @@ filter_packets_cb(gpointer data, gpointer user_data)
frame_data *fd = data;
capture_file *cf = user_data;
- cf->cur = fd;
cf->count++;
fseek(cf->fh, fd->file_off, SEEK_SET);
@@ -535,13 +539,54 @@ filter_packets(capture_file *cf)
}
static void
+print_packets_cb(gpointer data, gpointer user_data)
+{
+ frame_data *fd = data;
+ capture_file *cf = user_data;
+ proto_tree *protocol_tree;
+
+ cf->count++;
+
+ fseek(cf->fh, fd->file_off, SEEK_SET);
+ fread(cf->pd, sizeof(guint8), fd->cap_len, cf->fh);
+
+ /* create the logical protocol tree */
+ protocol_tree = proto_tree_create_root();
+ dissect_packet(cf->pd, fd, protocol_tree);
+
+ /* Print the packet */
+ fprintf(cf->print_fh, "Frame %d:\n\n", cf->count);
+ proto_tree_print((GNode *)protocol_tree, cf->pd, fd, cf->print_fh);
+ fprintf(cf->print_fh, "\n");
+
+ proto_tree_free(protocol_tree);
+}
+
+int
+print_packets(capture_file *cf, int to_file, const char *dest)
+{
+ cf->print_fh = open_print_dest(to_file, dest);
+ if (cf->print_fh == NULL)
+ return FALSE; /* attempt to open destination failed */
+
+ /*
+ * Iterate through the list of packets, printing each of them.
+ */
+ cf->count = 0;
+ g_list_foreach(cf->plist, print_packets_cb, cf);
+
+ close_print_dest(to_file, cf->print_fh);
+ cf->print_fh = NULL;
+ return TRUE;
+}
+
+static void
change_time_formats_cb(gpointer data, gpointer user_data)
{
frame_data *fd = data;
capture_file *cf = user_data;
gint i;
- cf->cur = fd;
cf->count++;
/* XXX - there really should be a way of checking "cf->cinfo" for this;
@@ -652,20 +697,19 @@ file_cp(char *from, char *to)
int from_fd, to_fd, nread, nwritten;
char *buffer;
- gint dialogue_button = ESD_BTN_OK;
buffer = g_malloc(COPY_BUFFER_SIZE);
from_fd = open(from, O_RDONLY);
if (from_fd < 0) {
- simple_dialog(ESD_TYPE_WARN, &dialogue_button,
+ simple_dialog(ESD_TYPE_WARN, NULL,
file_open_error_message(errno, TRUE), from);
return 0;
}
to_fd = creat(to, 0644);
if (to_fd < 0) {
- simple_dialog(ESD_TYPE_WARN, &dialogue_button,
+ simple_dialog(ESD_TYPE_WARN, NULL,
file_open_error_message(errno, TRUE), to);
close(from_fd);
return 0;
@@ -675,10 +719,10 @@ file_cp(char *from, char *to)
nwritten = write(to_fd, buffer, nread);
if (nwritten < nread) {
if (nwritten < 0) {
- simple_dialog(ESD_TYPE_WARN, &dialogue_button,
+ simple_dialog(ESD_TYPE_WARN, NULL,
file_write_error_message(errno), to);
} else {
- simple_dialog(ESD_TYPE_WARN, &dialogue_button,
+ simple_dialog(ESD_TYPE_WARN, NULL,
"The file \"%s\" could not be saved: tried writing %d, wrote %d.\n",
to, nread, nwritten);
}
@@ -688,7 +732,7 @@ file_cp(char *from, char *to)
}
}
if (nread < 0) {
- simple_dialog(ESD_TYPE_WARN, &dialogue_button,
+ simple_dialog(ESD_TYPE_WARN, NULL,
file_read_error_message(errno), from);
close(from_fd);
close(to_fd);
@@ -772,4 +816,3 @@ file_write_error_message(int err)
}
return errmsg;
}
-
diff --git a/file.h b/file.h
index 290c450a83..54cd456431 100644
--- a/file.h
+++ b/file.h
@@ -1,7 +1,7 @@
/* file.h
* Definitions for file structures and routines
*
- * $Id: file.h,v 1.20 1999/07/13 02:52:50 gram Exp $
+ * $Id: file.h,v 1.21 1999/07/23 08:29:22 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -75,8 +75,8 @@ typedef struct _capture_file {
/*guint8 pd[MAX_PACKET_SIZE];*/ /* Packet data */
guint8 pd[65536]; /* Packet data */
GList *plist; /* Packet list */
- frame_data *cur; /* Frame data for current list item */
column_info cinfo; /* Column formatting information */
+ FILE *print_fh; /* File we're printing to */
} capture_file;
@@ -98,6 +98,7 @@ int load_cap_file(char *, capture_file *);
int tail_cap_file(char *, capture_file *);
/* size_t read_frame_header(capture_file *); */
+int print_packets(capture_file *cf, int to_file, const char *dest);
void filter_packets(capture_file *);
void change_time_formats(capture_file *);
diff --git a/menu.c b/menu.c
index b4b94b2fd9..f0a55b788d 100644
--- a/menu.c
+++ b/menu.c
@@ -1,7 +1,7 @@
/* menu.c
* Menu routines
*
- * $Id: menu.c,v 1.26 1999/07/17 04:19:02 gram Exp $
+ * $Id: menu.c,v 1.27 1999/07/23 08:29:23 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -80,7 +80,8 @@ static GtkItemFactoryEntry menu_items[] =
{"/File/Save _As...", NULL, GTK_MENU_FUNC(file_save_as_cmd_cb), 0, NULL},
{"/File/_Reload", "<control>R", GTK_MENU_FUNC(file_reload_cmd_cb), 0, NULL},
{"/File/<separator>", NULL, NULL, 0, "<Separator>"},
- {"/File/_Print Packet", "<control>P", GTK_MENU_FUNC(file_print_cmd_cb), 0, NULL},
+ {"/File/Print...", NULL, GTK_MENU_FUNC(file_print_cmd_cb), 0, NULL},
+ {"/File/Print Pac_ket", "<control>P", GTK_MENU_FUNC(file_print_packet_cmd_cb), 0, NULL},
{"/File/<separator>", NULL, NULL, 0, "<Separator>"},
{"/File/_Quit", "<control>Q", GTK_MENU_FUNC(file_quit_cmd_cb), 0, NULL},
{"/_Edit", NULL, NULL, 0, "<Branch>" },
@@ -142,6 +143,7 @@ menus_init(void) {
set_menu_sensitivity("/File/Save", FALSE);
set_menu_sensitivity("/File/Save As...", FALSE);
set_menu_sensitivity("/File/Reload", FALSE);
+ set_menu_sensitivity("/File/Print...", FALSE);
set_menu_sensitivity("/Edit/Cut", FALSE);
set_menu_sensitivity("/Edit/Copy", FALSE);
set_menu_sensitivity("/Edit/Paste", FALSE);
diff --git a/prefs.h b/prefs.h
index 3e6348f999..930b1c8c00 100644
--- a/prefs.h
+++ b/prefs.h
@@ -1,7 +1,7 @@
/* prefs.h
* Definitions for preference handling routines
*
- * $Id: prefs.h,v 1.6 1999/06/12 07:04:35 guy Exp $
+ * $Id: prefs.h,v 1.7 1999/07/23 08:29:24 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -41,6 +41,8 @@ typedef struct _e_prefs {
gint num_cols;
} e_prefs;
+extern e_prefs prefs;
+
#define E_PR_PG_NONE -1
#define E_PR_PG_PRINTING 0
#define E_PR_PG_FILTER 1
diff --git a/print.c b/print.c
index 68ba00762f..41e294a790 100644
--- a/print.c
+++ b/print.c
@@ -1,7 +1,7 @@
/* print.c
* Routines for printing packet analysis trees.
*
- * $Id: print.c,v 1.13 1999/07/15 15:32:43 gram Exp $
+ * $Id: print.c,v 1.14 1999/07/23 08:29:22 guy Exp $
*
* Gilbert Ramirez <gram@verdict.uthscsa.edu>
*
@@ -56,7 +56,6 @@ static void ps_clean_string(unsigned char *out, const unsigned char *in,
int outbuf_size);
static void dumpit_ps (FILE *fh, register const u_char *cp, register u_int length);
-extern e_prefs prefs;
extern int proto_data; /* in packet-data.c */
/* #include "ps.c" */
@@ -262,26 +261,34 @@ typedef struct {
const guint8 *pd;
} print_data;
-void proto_tree_print(GNode *protocol_tree, const u_char *pd, frame_data *fd)
+FILE *open_print_dest(int to_file, const char *dest)
{
FILE *fh;
char *out;
- print_data data;
/* Open the file or command for output */
- if (prefs.pr_dest == PR_DEST_CMD) {
- out = prefs.pr_cmd;
+ out = dest;
+ if (to_file)
+ fh = fopen(dest, "w");
+ else
fh = popen(prefs.pr_cmd, "w");
- }
- else {
- out = prefs.pr_file;
- fh = fopen(prefs.pr_file, "w");
- }
- if (!fh) {
- g_error("Cannot open %s for output.\n", out);
- return;
- }
+ return fh;
+}
+
+void close_print_dest(int to_file, FILE *fh)
+{
+ /* Close the file or command */
+ if (to_file)
+ fclose(fh);
+ else
+ pclose(fh);
+}
+
+void proto_tree_print(GNode *protocol_tree, const u_char *pd, frame_data *fd,
+ FILE *fh)
+{
+ print_data data;
/* Create the output */
data.level = 0;
@@ -296,14 +303,6 @@ void proto_tree_print(GNode *protocol_tree, const u_char *pd, frame_data *fd)
proto_tree_print_node_ps, &data);
print_ps_finale(fh);
}
-
- /* Close the file or command */
- if (prefs.pr_dest == PR_DEST_CMD) {
- pclose(fh);
- }
- else {
- fclose(fh);
- }
}
/* Print a tree's data, and any child nodes, in plain text */
diff --git a/print.h b/print.h
index bd3548b2a3..ce9699b91b 100644
--- a/print.h
+++ b/print.h
@@ -1,7 +1,7 @@
/* print.h
* Definitions for printing packet analysis trees.
*
- * $Id: print.h,v 1.7 1999/07/13 04:38:15 guy Exp $
+ * $Id: print.h,v 1.8 1999/07/23 08:29:22 guy Exp $
*
* Gilbert Ramirez <gram@verdict.uthscsa.edu>
*
@@ -34,6 +34,9 @@ GtkWidget *printer_prefs_show();
void printer_prefs_ok(GtkWidget *w);
void printer_prefs_save(GtkWidget *w);
void printer_prefs_cancel(GtkWidget *w);
-void proto_tree_print(GNode *protocol_tree, const u_char *pd, frame_data *fd);
+FILE *open_print_dest(int to_file, const char *dest);
+void close_print_dest(int to_file, FILE *fh);
+void proto_tree_print(GNode *protocol_tree, const u_char *pd, frame_data *fd,
+ FILE *fh);
#endif /* print.h */