Ethereal-dev: [ethereal-dev] PATCH: Print followed TCP stream

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: Warren Young <tangent@xxxxxxxx>
Date: Fri, 22 Oct 1999 12:34:10 -0600
I just hacked up this little bit of code to allow the program to print a
followed TCP stream.  This is a unified diff against CVS.

It works fine, with the following caveats:

1. Long lines in text mode are chopped off.  I don't know if this should
be fixed, or if this is the desired behavior.

2. Postscript mode doesn't seem to work, and I don't know enough about
Postscript to figure out why.  I just copied code from the packet
printing code, so it should be close.

If I print a bit of text after a failed Postscript run, I see the
following at the top of the page: "Error: /undefined in GET\rOperand
stack:\r\rExecution stack:\r   %interp_exit    .runexec".  (That's an
approximate error.  \r is a carriage return, resulting in stairstepped
text.  The .runexec bit is right up against the right edge of the page,
so there may be more to the error.  I'm running Ghostscript to an HP PCL
4 printer, if that helps.)

Anyway, the patches follow.  The first is against gtk/main.c, the second
against print.c, and the last against print.h.
-- 
= Warren Young: www.cyberport.com/~tangent |   Yesterday it worked.
= ICBM Address: 36.8274040N, 108.0204086W, | Today it is not working.
=               alt. 1714m                 |   Windows is like that.
Index: gtk/main.c
===================================================================
RCS file: /cvsroot/ethereal/gtk/main.c,v
retrieving revision 1.24
diff -u -r1.24 main.c
--- main.c      1999/10/19 04:11:23     1.24
+++ main.c      1999/10/22 18:16:32
@@ -118,6 +118,7 @@
 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, gboolean show_ascii);
+static void follow_print_stream(GtkWidget *w, gpointer parent_w);
 
 /* About Ethereal window */
 void
@@ -166,7 +167,7 @@
 follow_stream_cb( GtkWidget *w, gpointer data ) {
   char      filename1[128+1];
   GtkWidget *streamwindow, *box, *text, *vscrollbar, *table;
-  GtkWidget *hbox, *close_bt, *button;
+  GtkWidget *hbox, *close_bt, *print_bt, *button;
   int        tmp_fd;
   gchar     *follow_filter;
 
@@ -279,6 +280,13 @@
     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 );
 
     /* create the scrollbar */
     vscrollbar = gtk_vscrollbar_new( GTK_TEXT(text)->vadj );
@@ -345,6 +353,65 @@
                show_ascii = TRUE;
 
        follow_load_text(text, filename, show_ascii);
+}
+
+static void follow_print_stream(GtkWidget *w, gpointer parent_w)
+{
+       FILE *fh = NULL;
+       int to_file = -1;
+       char* print_dest = NULL;
+       char* filename;
+
+       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;
+       }
+
+       if (print_dest != NULL) {
+               fh = open_print_dest(to_file, print_dest);
+       }
+
+       if (fh == NULL) {
+               switch (to_file) {
+                       case -1:
+                               simple_dialog(ESD_TYPE_WARN, NULL,
+                                               "Couldn't figure out where to send the print "
+                                               "job. Check your preferences.");
+                               break;
+
+                       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;
+       }
+
+       filename = (char*) gtk_object_get_data(GTK_OBJECT(parent_w),
+                       E_FOLLOW_FILENAME_KEY);
+
+       if (filename != NULL) {
+               print_preamble(fh);
+               print_file(fh, filename);
+               print_finale(fh);
+               close_print_dest(to_file, fh);
+       }
+       else {
+               simple_dialog(ESD_TYPE_WARN, NULL, "Could not find data to print.");
+       }
 }
 
 static void
Index: print.c
===================================================================
RCS file: /cvsroot/ethereal/print.c,v
retrieving revision 1.21
diff -u -r1.21 print.c
--- print.c     1999/09/29 22:19:13     1.21
+++ print.c     1999/10/22 18:31:00
@@ -47,6 +47,8 @@
 static void ps_clean_string(unsigned char *out, const unsigned char *in,
                        int outbuf_size);
 static void print_hex_data_ps(FILE *fh, register const u_char *cp, register u_int length);
+static void print_ps_file(FILE* target_fh, FILE* source_fh);
+static void print_text_file(FILE* target_fh, FILE* source_fh);
 
 extern int proto_data; /* in packet-data.c */
 
@@ -93,6 +95,20 @@
                print_ps_finale(fh);
 }
 
+void print_file(FILE* fh, const char* filename)
+{
+       FILE* fh2 = fopen(filename, "r");
+       if (fh2 == NULL) {
+               fprintf(stderr, "Could not open file %s for reading.\n", filename);
+               return;
+       }
+
+       if (prefs.pr_format == PR_FMT_PS)
+               print_ps_file(fh, fh2);
+       else
+               print_text_file(fh, fh2);
+}
+
 void proto_tree_print(gboolean print_one_packet, print_args_t *print_args,
     GNode *protocol_tree, const u_char *pd, frame_data *fd, FILE *fh)
 {
@@ -317,3 +333,25 @@
         return;
 
 }
+
+static 
+void print_text_file(FILE* target_fh, FILE* source_fh)
+{
+       gchar buffer[MAX_LINE_LENGTH];
+       while (fgets(buffer, sizeof(buffer), source_fh) != NULL) {
+               fputs(buffer, target_fh);
+       }
+}
+
+static 
+void print_ps_file(FILE* target_fh, FILE* source_fh)
+{
+       gchar buffer[MAX_LINE_LENGTH];
+       gchar ps_buffer[MAX_LINE_LENGTH];
+
+       while (fgets(buffer, sizeof(buffer), source_fh) != NULL) {
+               ps_clean_string(ps_buffer, buffer, MAX_LINE_LENGTH);
+               fputs(ps_buffer, target_fh);
+       }
+}
+
Index: print.h
===================================================================
RCS file: /cvsroot/ethereal/print.h,v
retrieving revision 1.13
diff -u -r1.13 print.h
--- print.h     1999/09/29 22:19:13     1.13
+++ print.h     1999/10/22 18:31:43
@@ -46,6 +46,7 @@
 void close_print_dest(int to_file, FILE *fh);
 void print_preamble(FILE *fh);
 void print_finale(FILE *fh);
+void print_file(FILE* fh, const char* filename);
 void proto_tree_print(gboolean print_one_packet, print_args_t *print_args,
     GNode *protocol_tree, const u_char *pd, frame_data *fd, FILE *fh);
 void print_hex_data(FILE *fh, register const u_char *cp,