Follow up to rev 34073: Since "-b files:0" is no longer necessary to
[obnox/wireshark/wip.git] / print.c
diff --git a/print.c b/print.c
index 6c22250ed653446b4415b188220f9eee585b21f3..ad67e0a86861bbeba599350630c9b922704bea30 100644 (file)
--- a/print.c
+++ b/print.c
@@ -75,6 +75,7 @@ typedef struct {
 struct _output_fields {
     gboolean print_header;
     gchar separator;
+    gchar occurrence;
     gchar aggregator;
     GPtrArray* fields;
     GHashTable* field_indicies;
@@ -82,6 +83,8 @@ struct _output_fields {
     gchar quote;
 };
 
+static gboolean write_headers = FALSE;
+
 static const gchar* get_field_hex_value(GSList* src_list, field_info *fi);
 static void proto_tree_print_node(proto_node *node, gpointer data);
 static void proto_tree_write_node_pdml(proto_node *node, gpointer data);
@@ -570,16 +573,16 @@ write_psml_preamble(FILE *fh)
        fputs("<?xml version=\"1.0\"?>\n", fh);
        fputs("<psml version=\"" PSML_VERSION "\" ", fh);
        fprintf(fh, "creator=\"%s/%s\">\n", PACKAGE, VERSION);
+       write_headers = TRUE;
 }
 
 void
 proto_tree_write_psml(epan_dissect_t *edt, FILE *fh)
 {
        gint    i;
-       static gboolean structure_written = FALSE;
 
        /* if this is the first packet, we have to create the PSML structure output */
-       if(!structure_written) {
+       if(write_headers) {
            fprintf(fh, "<structure>\n");
 
            for(i=0; i < edt->pi.cinfo->num_cols; i++) {
@@ -590,7 +593,7 @@ proto_tree_write_psml(epan_dissect_t *edt, FILE *fh)
 
            fprintf(fh, "</structure>\n\n");
 
-           structure_written = TRUE;
+           write_headers = FALSE;
        }
 
        fprintf(fh, "<packet>\n");
@@ -613,7 +616,7 @@ write_psml_finale(FILE *fh)
 void
 write_csv_preamble(FILE *fh _U_)
 {
-
+       write_headers = TRUE;
 }
 
 void
@@ -622,11 +625,13 @@ proto_tree_write_csv(epan_dissect_t *edt, FILE *fh)
         gint    i;
 
         /* if this is the first packet, we have to write the CSV header */
-        if(edt->pi.fd->num == 1) {
+        if(write_headers) {
             for(i=0; i < edt->pi.cinfo->num_cols - 1; i++)
                fprintf(fh, "\"%s\",", edt->pi.cinfo->col_title[i]);
 
             fprintf(fh, "\"%s\"\n", edt->pi.cinfo->col_title[i]);
+
+           write_headers = FALSE;
         }
 
         for(i=0; i < edt->pi.cinfo->num_cols - 1; i++)
@@ -938,6 +943,11 @@ void ps_clean_string(unsigned char *out, const unsigned char *in,
        int rd, wr;
        char c;
 
+       if (in == NULL) {
+               out[0] = '\0';
+               return;
+       }
+
        for (rd = 0, wr = 0 ; wr < outbuf_size; rd++, wr++ ) {
                c = in[rd];
                switch (c) {
@@ -1127,9 +1137,6 @@ print_preamble_ps(print_stream_t *self, gchar *filename)
 
        print_ps_preamble(output->fh);
 
-       fputs("%% Set the font to 8 point\n", output->fh);
-       fputs("/Courier findfont 8 scalefont setfont\n", output->fh);
-       fputs("\n", output->fh);
        fputs("%% the page title\n", output->fh);
        ps_clean_string(psbuffer, filename, MAX_PS_LINE_LENGTH);
        fprintf(output->fh, "/ws_pagetitle (%s - Wireshark " VERSION "%s) def\n", psbuffer, wireshark_svnversion);
@@ -1256,6 +1263,7 @@ output_fields_t* output_fields_new()
     output_fields_t* fields = g_new(output_fields_t, 1);
     fields->print_header = FALSE;
     fields->separator = '\t';
+    fields->occurrence = 'a';
     fields->aggregator = ',';
     fields->fields = NULL; /*Do lazy initialisation */
     fields->field_indicies = NULL;
@@ -1364,6 +1372,19 @@ gboolean output_fields_set_option(output_fields_t* info, gchar* option)
         return TRUE;
     }
 
+    if(0 == strcmp(option_name, "occurrence")) {
+        switch(NULL == option_value ? '\0' : *option_value) {
+        case 'f':
+        case 'l':
+        case 'a':
+            info->occurrence = *option_value;
+            break;
+        default:
+            return FALSE;
+        }
+        return TRUE;
+    }
+
     if(0 == strcmp(option_name,"aggregator")) {
         switch(NULL == option_value ? '\0' : *option_value) {
         case '\0':
@@ -1409,9 +1430,11 @@ gboolean output_fields_set_option(output_fields_t* info, gchar* option)
 void output_fields_list_options(FILE *fh)
 {
     fprintf(fh, "TShark: The available options for field output \"E\" are:\n");
-    fputs("header=y|n   Print field abbreviations as first line of output (def: N: no)\n", fh);
-    fputs("separator=/t|/s|<character>   Set the separator to use; \"/t\" = tab,\n \"/s\" = space (def: /t: tab)\n", fh);
-    fputs("quote=d|s|n   Print either d: double-quotes, s: single quotes or n: no quotes around field values (def: n: none)\n", fh);
+    fputs("header=y|n    Print field abbreviations as first line of output (def: N: no)\n", fh);
+    fputs("separator=/t|/s|<character>   Set the separator to use;\n     \"/t\" = tab, \"/s\" = space (def: /t: tab)\n", fh);
+    fputs("occurrence=f|l|a  Select the occurrence of a field to use;\n     \"f\" = first, \"l\" = last, \"a\" = all (def: a: all)\n", fh);
+    fputs("aggregator=,|/s|<character>   Set the aggregator to use;\n     \",\" = comma, \"/s\" = space (def: ,: comma)\n", fh);
+    fputs("quote=d|s|n   Print either d: double-quotes, s: single quotes or \n     n: no quotes around field values (def: n: none)\n", fh);
 }
 
 
@@ -1457,9 +1480,13 @@ static void proto_tree_get_node_field_values(proto_node *node, gpointer data)
             guint actual_index;
             actual_index = GPOINTER_TO_UINT(field_index);
             /* Unwrap change made to disambiguiate zero / null */
-            if (call_data->fields->field_values[actual_index - 1] == NULL ) {
+            if ( call_data->fields->field_values[actual_index - 1] == NULL ) {
                 call_data->fields->field_values[actual_index - 1] = ep_strbuf_new(value);
-            } else {
+            } else if ( call_data->fields->occurrence == 'l' ) {
+                /* print only the value of the last occurrence of the field */
+                ep_strbuf_printf(call_data->fields->field_values[actual_index - 1],"%s",value);
+            } else if ( call_data->fields->occurrence == 'a' ) {
+                /* print the value of all accurrences of the field */
                 ep_strbuf_append_printf(call_data->fields->field_values[actual_index - 1],
                     "%c%s",call_data->fields->aggregator,value);
             }