struct _output_fields {
gboolean print_header;
gchar separator;
+ gchar occurrence;
+ gchar aggregator;
GPtrArray* fields;
GHashTable* field_indicies;
- const gchar** field_values;
+ emem_strbuf_t** field_values;
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);
data.src_list = edt->pi.data_src;
data.edt = edt;
- /* We shouldn't be called with a NULL pointer here because we've
- * created a visible protocol tree */
- g_assert(data.src_list);
-
fprintf(fh, "<packet>\n");
/* Print a "geninfo" protocol as required by PDML */
#if 0
/* PDML spec, see:
- * http://analyzer.polito.it/30alpha/docs/dissectors/PDMLSpec.htm
+ * http://www.nbee.org/doku.php?id=netpdl:pdml_specification
*
* the show fields contains things in 'human readable' format
* showname: contains only the name of the field
if (g_ptr_array_len(finfo_array) < 1) {
return;
}
- frame_finfo = finfo_array->pdata[0];
+ frame_finfo = (field_info *)finfo_array->pdata[0];
g_ptr_array_free(finfo_array, TRUE);
/* frame.number --> geninfo.num */
if (g_ptr_array_len(finfo_array) < 1) {
return;
}
- timestamp = fvalue_get(&((field_info*)finfo_array->pdata[0])->value);
+ timestamp = (nstime_t *)fvalue_get(&((field_info*)finfo_array->pdata[0])->value);
g_ptr_array_free(finfo_array, TRUE);
/* Print geninfo start */
/* Print geninfo.timestamp */
fprintf(fh,
" <field name=\"timestamp\" pos=\"0\" show=\"%s\" showname=\"Captured Time\" value=\"%d.%09d\" size=\"%u\"/>\n",
- abs_time_to_str(timestamp, FALSE), (int) timestamp->secs, timestamp->nsecs, frame_finfo->length);
+ abs_time_to_str(timestamp, ABSOLUTE_TIME_LOCAL, TRUE), (int) timestamp->secs, timestamp->nsecs, frame_finfo->length);
/* Print geninfo end */
fprintf(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++) {
fprintf(fh, "</structure>\n\n");
- structure_written = TRUE;
+ write_headers = FALSE;
}
fprintf(fh, "<packet>\n");
void
write_csv_preamble(FILE *fh _U_)
{
+ write_headers = TRUE;
+}
+static gchar *csv_massage_str(const gchar *source, const gchar *exceptions)
+{
+ gchar *csv_str;
+ gchar *tmp_str;
+
+ csv_str = g_strescape(source, exceptions);
+ tmp_str = csv_str;
+ while ( (tmp_str = strstr(tmp_str, "\\\"")) != NULL )
+ *tmp_str = '\"';
+ return csv_str;
}
-void
-proto_tree_write_csv(epan_dissect_t *edt, FILE *fh)
+static void csv_write_str(const char *str, char sep, FILE *fh)
{
- gint i;
+ gchar *csv_str;
- /* if this is the first packet, we have to write the CSV header */
- if(edt->pi.fd->num == 1) {
- for(i=0; i < edt->pi.cinfo->num_cols - 1; i++)
- fprintf(fh, "\"%s\",", edt->pi.cinfo->col_title[i]);
+ csv_str = csv_massage_str(str, NULL);
+ fprintf(fh, "\"%s\"%c", csv_str, sep);
+ g_free(csv_str);
+}
- fprintf(fh, "\"%s\"\n", edt->pi.cinfo->col_title[i]);
- }
+void
+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(write_headers) {
for(i=0; i < edt->pi.cinfo->num_cols - 1; i++)
- fprintf(fh, "\"%s\",", edt->pi.cinfo->col_data[i]);
+ csv_write_str(edt->pi.cinfo->col_title[i], ',', fh);
+ csv_write_str(edt->pi.cinfo->col_title[i], '\n', fh);
+ write_headers = FALSE;
+ }
- fprintf(fh, "\"%s\"\n", edt->pi.cinfo->col_data[i]);
+ for(i=0; i < edt->pi.cinfo->num_cols - 1; i++)
+ csv_write_str(edt->pi.cinfo->col_data[i], ',', fh);
+ csv_write_str(edt->pi.cinfo->col_data[i], '\n', fh);
}
void
gint length, tvbuff_length;
for (src_le = src_list; src_le != NULL; src_le = src_le->next) {
- src = src_le->data;
+ src = (data_source *)src_le->data;
src_tvb = src->tvb;
if (fi->ds_tvb == src_tvb) {
/*
print_escaped_xml(FILE *fh, const char *unescaped_string)
{
const char *p;
+ char temp_str[8];
for (p = unescaped_string; *p != '\0'; p++) {
switch (*p) {
fputs("'", fh);
break;
default:
- fputc(*p, fh);
+ if (g_ascii_isprint(*p))
+ fputc(*p, fh);
+ else {
+ g_snprintf(temp_str, sizeof(temp_str), "\\x%x", (guint8)*p);
+ fputs(temp_str, fh);
+ }
}
}
}
const guchar *cp;
guint length;
- /* We shouldn't be called with a NULL pointer here because we've
- * created a visible protocol tree */
- g_assert(edt->pi.data_src);
-
/*
* Set "multiple_sources" iff this frame has more than one
* data source; if it does, we need to print the name of
for (src_le = edt->pi.data_src; src_le != NULL;
src_le = src_le->next) {
- src = src_le->data;
+ src = (data_source *)src_le->data;
tvb = src->tvb;
if (multiple_sources) {
name = get_data_source_name(src);
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) {
static gboolean
print_line_text(print_stream_t *self, int indent, const char *line)
{
- output_text *output = self->data;
+ output_text *output = (output_text *)self->data;
char space[MAX_INDENT+1];
int i;
int num_spaces;
static gboolean
new_page_text(print_stream_t *self)
{
- output_text *output = self->data;
+ output_text *output = (output_text *)self->data;
fputs("\f", output->fh);
return !ferror(output->fh);
static gboolean
destroy_text(print_stream_t *self)
{
- output_text *output = self->data;
+ output_text *output = (output_text *)self->data;
gboolean ret;
ret = close_print_dest(output->to_file, output->fh);
print_stream_t *stream;
output_text *output;
- output = g_malloc(sizeof *output);
+ output = (output_text *)g_malloc(sizeof *output);
output->to_file = to_file;
output->fh = fh;
- stream = g_malloc(sizeof (print_stream_t));
+ stream = (print_stream_t *)g_malloc(sizeof (print_stream_t));
stream->ops = &print_text_ops;
stream->data = output;
static gboolean
print_preamble_ps(print_stream_t *self, gchar *filename)
{
- output_ps *output = self->data;
+ output_ps *output = (output_ps *)self->data;
unsigned char psbuffer[MAX_PS_LINE_LENGTH]; /* static sized buffer! */
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);
static gboolean
print_line_ps(print_stream_t *self, int indent, const char *line)
{
- output_ps *output = self->data;
+ output_ps *output = (output_ps *)self->data;
unsigned char psbuffer[MAX_PS_LINE_LENGTH]; /* static sized buffer! */
ps_clean_string(psbuffer, line, MAX_PS_LINE_LENGTH);
static gboolean
print_bookmark_ps(print_stream_t *self, const gchar *name, const gchar *title)
{
- output_ps *output = self->data;
+ output_ps *output = (output_ps *)self->data;
unsigned char psbuffer[MAX_PS_LINE_LENGTH]; /* static sized buffer! */
/*
static gboolean
new_page_ps(print_stream_t *self)
{
- output_ps *output = self->data;
+ output_ps *output = (output_ps *)self->data;
fputs("formfeed\n", output->fh);
return !ferror(output->fh);
static gboolean
print_finale_ps(print_stream_t *self)
{
- output_ps *output = self->data;
+ output_ps *output = (output_ps *)self->data;
print_ps_finale(output->fh);
return !ferror(output->fh);
static gboolean
destroy_ps(print_stream_t *self)
{
- output_ps *output = self->data;
+ output_ps *output = (output_ps *)self->data;
gboolean ret;
ret = close_print_dest(output->to_file, output->fh);
print_stream_t *stream;
output_ps *output;
- output = g_malloc(sizeof *output);
+ output = (output_ps *)g_malloc(sizeof *output);
output->to_file = to_file;
output->fh = fh;
- stream = g_malloc(sizeof (print_stream_t));
+ stream = (print_stream_t *)g_malloc(sizeof (print_stream_t));
stream->ops = &print_ps_ops;
stream->data = output;
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;
fields->field_values = NULL;
if(NULL != fields->fields) {
gsize i;
for(i = 0; i < fields->fields->len; ++i) {
- gchar* field = g_ptr_array_index(fields->fields,i);
+ gchar* field = (gchar *)g_ptr_array_index(fields->fields,i);
g_free(field);
}
g_ptr_array_free(fields->fields, TRUE);
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':
+ return FALSE;
+ case '/':
+ switch(*++option_value) {
+ case 's':
+ info->aggregator = ' ';
+ break;
+ default:
+ info->aggregator = '\\';
+ }
+ break;
+ default:
+ info->aggregator = *option_value;
+ break;
+ }
+ return TRUE;
+ }
+
if(0 == strcmp(option_name, "quote")) {
switch(NULL == option_value ? '\0' : *option_value) {
default: /* Fall through */
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);
}
}
for(i = 0; i < fields->fields->len; ++i) {
- const gchar* field = g_ptr_array_index(fields->fields,i);
+ const gchar* field = (const gchar *)g_ptr_array_index(fields->fields,i);
if(i != 0 ) {
fputc(fields->separator, fh);
}
field_info *fi;
gpointer field_index;
- call_data = data;
+ call_data = (write_field_data_t *)data;
fi = PNODE_FINFO(node);
g_assert(fi && "dissection with an invisible proto tree?");
guint actual_index;
actual_index = GPOINTER_TO_UINT(field_index);
/* Unwrap change made to disambiguiate zero / null */
- call_data->fields->field_values[actual_index - 1] = value;
+ if ( call_data->fields->field_values[actual_index - 1] == NULL ) {
+ call_data->fields->field_values[actual_index - 1] = ep_strbuf_new(value);
+ } 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);
+ }
}
}
i = 0;
while( i < fields->fields->len) {
- gchar* field = g_ptr_array_index(fields->fields, i);
+ gchar* field = (gchar *)g_ptr_array_index(fields->fields, i);
/* Store field indicies +1 so that zero is not a valid value,
* and can be distinguished from NULL as a pointer.
*/
}
/* Buffer to store values for this packet */
- fields->field_values = ep_alloc_array0(const gchar*, fields->fields->len);
+ fields->field_values = ep_alloc_array0(emem_strbuf_t*, fields->fields->len);
proto_tree_children_foreach(edt->tree, proto_tree_get_node_field_values,
&data);
if(fields->quote != '\0') {
fputc(fields->quote, fh);
}
- fputs(fields->field_values[i], fh);
+ fputs(fields->field_values[i]->str, fh);
if(fields->quote != '\0') {
fputc(fields->quote, fh);
}