Huge thanks to our Platinum Members Endace and LiveAction,
and our Silver Member Veeam, for supporting the Wireshark Foundation and project.

Ethereal-dev: Re: [Ethereal-dev] Saving the contents of the TCP follow dialog without formatti

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

From: Alan Jenkins <sourcejedi@xxxxxxxxxxxxxx>
Date: Tue, 20 Jul 2004 17:43:01 +0000
OK, I have a patch done now.  This addresses two issues:

1.  There was no way to save data wihtout any character set conversion.  If 
you use the ASCII mode, all non printable characters are replaced with 
periods.

2.  A "write_line" function was called with the contents of whole packets, so 
that a new line would be inserted after each packet.  I assume this would 
also cause problems when printing in postscript mode.

While testing this patch, remember to try printing in postcript and plain 
text, as well as saving raw and ascii files.

Alan
Index: follow_dlg.c
===================================================================
--- follow_dlg.c
+++ .svn/tmp/follow_dlg.c.61240.00001.tmp	2004-07-20 17:42:18.000000000 +0000
@@ -78,7 +78,8 @@
 	SHOW_ASCII,
 	SHOW_EBCDIC,
 	SHOW_HEXDUMP,
-	SHOW_CARRAY
+	SHOW_CARRAY,
+	SHOW_RAW
 } show_type_t;
 
 typedef struct {
@@ -90,6 +91,7 @@
 	GtkWidget	*ebcdic_bt;
 	GtkWidget	*hexdump_bt;
 	GtkWidget	*carray_bt;
+	GtkWidget	*raw_bt;
 	GtkWidget	*follow_save_as_w;
 	gboolean        is_ipv6;
 	char		*filter_out_filter;
@@ -415,6 +417,16 @@
 	SIGNAL_CONNECT(radio_bt, "toggled", follow_charset_toggle_cb,
                        follow_info);
 	follow_info->carray_bt = radio_bt;
+	
+	/* Raw  radio button */
+	radio_bt = gtk_radio_button_new_with_label(gtk_radio_button_group
+					    (GTK_RADIO_BUTTON(radio_bt)),
+					    "Raw");
+	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio_bt), FALSE);
+	gtk_box_pack_start(GTK_BOX(hbox), radio_bt, FALSE, FALSE, 0);
+	SIGNAL_CONNECT(radio_bt, "toggled", follow_charset_toggle_cb,
+                       follow_info);
+	follow_info->raw_bt = radio_bt;
 
 	/* button hbox */
 	button_hbox = gtk_hbutton_box_new();
@@ -519,6 +531,8 @@
 		follow_info->show_type = SHOW_CARRAY;
 	else if (GTK_TOGGLE_BUTTON(follow_info->ascii_bt)->active)
 		follow_info->show_type = SHOW_ASCII;
+	else if (GTK_TOGGLE_BUTTON(follow_info->raw_bt)->active)
+		follow_info->show_type = SHOW_RAW;
 	else
 		g_assert_not_reached();
 
@@ -534,10 +548,26 @@
 	FRS_PRINT_ERROR
 } frs_return_t;
 
+/*
+ *  convert non printable characters to periods
+ */
+
+static void ascii_to_raw (char* buffer, int nchars)
+{
+	int i;
+	for (i = 0; i < nchars; i++) {
+		if (buffer[i] == '\n' || buffer[i] == '\r')
+			continue;
+		if (! isprint(buffer[i])) {
+			buffer[i] = '.';
+		}
+	}
+}
+
 static frs_return_t
 follow_read_stream(follow_info_t *follow_info,
-		   gboolean (*print_line) (char *, int, gboolean, void *, print_format_e),
-		   void *arg, print_format_e format)
+		   gboolean (*write_data) (char *, int, gboolean, void *),
+		   void *arg)
 {
     tcp_stream_chunk	sc;
     int			bcount, iplen;
@@ -595,20 +625,18 @@
 		switch (follow_info->show_type) {
 
 		case SHOW_EBCDIC:
-		    /* If our native arch is ASCII, call: */
-		    EBCDIC_to_ASCII(buffer, nchars);
-		    if (!(*print_line) (buffer, nchars, is_server, arg, format))
-			goto print_error;
-		    break;
+			/* convert EBDIC characters to ASCII */
+			EBCDIC_to_ASCII(buffer, nchars);
 
 		case SHOW_ASCII:
-		    /* If our native arch is EBCDIC, call:
-		     * ASCII_TO_EBCDIC(buffer, nchars);
-		     */
-		    if (!(*print_line) (buffer, nchars, is_server, arg, format))
+			ascii_to_raw (buffer, nchars);
+
+		case SHOW_RAW:
+		    if (!(*write_data) (buffer, nchars, is_server, arg))
 			goto print_error;
 		    break;
 
+
 		case SHOW_HEXDUMP:
 		    current_pos = 0;
 		    while (current_pos < nchars) {
@@ -662,7 +690,7 @@
 			(*global_pos) += i;
 			hexbuf[cur++] = '\n';
 			hexbuf[cur] = 0;
-			if (!(*print_line) (hexbuf, strlen(hexbuf), is_server, arg, format))
+			if (!(*write_data) (hexbuf, strlen(hexbuf), is_server, arg))
 			    goto print_error;
 		    }
 		    break;
@@ -671,7 +699,7 @@
 		    current_pos = 0;
 		    g_snprintf(initbuf, 256, "char peer%d_%d[] = {\n", is_server ? 1 : 0,
 			    is_server ? server_packet_count++ : client_packet_count++);
-		    if (!(*print_line) (initbuf, strlen(initbuf), is_server, arg, format))
+		    if (!(*write_data) (initbuf, strlen(initbuf), is_server, arg))
 			goto print_error;
 		    while (current_pos < nchars) {
 			gchar hexbuf[256];
@@ -705,7 +733,7 @@
 			(*global_pos) += i;
 			hexbuf[cur++] = '\n';
 			hexbuf[cur] = 0;
-			if (!(*print_line) (hexbuf, strlen(hexbuf), is_server, arg, format))
+			if (!(*write_data) (hexbuf, strlen(hexbuf), is_server, arg))
 			    goto print_error;
 		    }
 		    break;
@@ -740,29 +768,35 @@
  * suggestion.
  */
 static gboolean
-follow_print_text(char *buffer, int nchars, gboolean is_server _U_, void *arg, print_format_e format)
+follow_print_text(char *buffer, int nchars, gboolean is_server _U_, void *arg)
 {
     FILE *fh = arg;
-    int i;
-    char *str;
+	return nchars == (int) fwrite (buffer, 1, nchars, fh);
+}
 
-    /* convert non printable characters */
-    for (i = 0; i < nchars; i++) {
-        if (buffer[i] == '\n' || buffer[i] == '\r')
-            continue;
-        if (! isprint(buffer[i])) {
-            buffer[i] = '.';
-        }
-    }
+static gboolean
+follow_print_postscript(char *buffer, int nchars, gboolean is_server _U_, void *arg)
+{
+	FILE *fh = arg;
+    char *str, *line, *next_line;
 
-    /* convert unterminated char array to a zero terminated string */
-    str = g_malloc(nchars + 1);
+	/* convert unterminated char array to a zero terminated string */
+	line = str = g_malloc(nchars + 1);
     memcpy(str, buffer, nchars);
     str[nchars] = 0;
-    print_line(fh, /*indent*/ 0, format, str);
-    g_free(str);
 
-    return TRUE;
+	/* print buffer a line at a time */
+	do {
+		next_line = strchr (line, '\n');
+		if (next_line != NULL) {
+			*next_line = '\0';
+			next_line++;
+		}
+
+		print_line (fh, 0, PR_FMT_PS, line);
+		line = next_line;
+	} while (line != NULL);
+	g_free(str);
 }
 
 static void
@@ -835,7 +869,19 @@
     if (ferror(fh))
         goto print_error;
 
-    switch (follow_read_stream(follow_info, follow_print_text, fh, prefs.pr_format)) {
+	gboolean (*print_function) (char *, int, gboolean, void *);
+	switch (prefs.pr_format) {
+		case PR_FMT_TEXT:
+			print_function = follow_print_text;
+			break;
+		case PR_FMT_PS:
+			print_function = follow_print_postscript;
+			break;
+		default:
+			g_assert_not_reached();
+	}
+
+    switch (follow_read_stream(follow_info, print_function, fh)) {
     case FRS_OK:
     	break;
     case FRS_OPEN_ERROR:
@@ -888,8 +934,7 @@
 }
 
 static gboolean
-follow_add_to_gtk_text(char *buffer, int nchars, gboolean is_server,
-		       void *arg, print_format_e format _U_)
+follow_add_to_gtk_text(char *buffer, int nchars, gboolean is_server, void *arg)
 {
     GtkWidget *text = arg;
     GdkColor   fg, bg;
@@ -964,7 +1009,7 @@
 #else
     gtk_text_buffer_set_text(buf, "", -1);
 #endif
-    follow_read_stream(follow_info, follow_add_to_gtk_text, follow_info->text, PR_FMT_TEXT);
+    follow_read_stream(follow_info, follow_add_to_gtk_text, follow_info->text);
 #if GTK_MAJOR_VERSION < 2
     gtk_text_thaw(GTK_TEXT(follow_info->text));
 #endif
@@ -1008,10 +1053,10 @@
 #else
     /* Connect the ok_button to file_save_as_ok_cb function and pass along a
        pointer to the file selection box widget */
-    SIGNAL_CONNECT(GTK_FILE_SELECTION(new_win)->ok_button, 
+    SIGNAL_CONNECT(GTK_FILE_SELECTION(new_win)->ok_button,
         "clicked", follow_save_as_ok_cb, new_win);
 
-    window_set_cancel_button(new_win, 
+    window_set_cancel_button(new_win,
         GTK_FILE_SELECTION(new_win)->cancel_button, window_cancel_button_cb);
 
     gtk_file_selection_set_filename(GTK_FILE_SELECTION(new_win), "");
@@ -1060,7 +1105,7 @@
     follow_info = OBJECT_GET_DATA(fs, E_FOLLOW_INFO_KEY);
     window_destroy(GTK_WIDGET(fs));
 
-    switch (follow_read_stream(follow_info, follow_print_text, fh, PR_FMT_TEXT)) {
+    switch (follow_read_stream(follow_info, follow_print_text, fh)) {
 
     case FRS_OK:
         if (fclose(fh) == EOF)