Try to fix warning: comparison between signed and unsigned.
[obnox/wireshark/wip.git] / file.c
diff --git a/file.c b/file.c
index b114844a6ca5610a6dd1b2a7dfc6380d974ea48b..6766c8097aca70b308f0b3fb88a95b53ebc70c06 100644 (file)
--- a/file.c
+++ b/file.c
 #include "fileset.h"
 #include "tempfile.h"
 #include "merge.h"
-#include "alert_box.h"
-#include "simple_dialog.h"
-#include "main_statusbar.h"
-#include "progress_dlg.h"
-#include "ui_util.h"
+
 #include <epan/prefs.h>
 #include <epan/dfilter/dfilter.h>
 #include <epan/epan_dissect.h>
 #include <epan/strutil.h>
 #include <epan/addr_resolv.h>
 
+#include "ui/alert_box.h"
+#include "ui/simple_dialog.h"
+#include "ui/main_statusbar.h"
+#include "ui/progress_dlg.h"
+#include "ui/ui_util.h"
+
 #ifdef HAVE_LIBPCAP
 gboolean auto_scroll_live;
 #endif
@@ -126,7 +128,6 @@ static void cf_open_failure_alert_box(const char *filename, int err,
                       gchar *err_info, gboolean for_writing,
                       int file_type);
 static const char *file_rename_error_message(int err);
-static void cf_write_failure_alert_box(const char *filename, int err);
 static void cf_close_failure_alert_box(const char *filename, int err);
 static void ref_time_packets(capture_file *cf);
 /* Update the progress bar this many times when reading a file. */
@@ -135,11 +136,6 @@ static void ref_time_packets(capture_file *cf);
 #define MIN_QUANTUM         200000
 #define MIN_NUMBER_OF_PACKET 1500
 
-/* Number of "frame_data" structures per memory chunk.
-   XXX - is this the right number? */
-#define FRAME_DATA_CHUNK_SIZE   1024
-
-
 /*
  * We could probably use g_signal_...() instead of the callbacks below but that
  * would require linking our CLI programs to libgobject and creating an object
@@ -289,7 +285,7 @@ cf_open(capture_file *cf, const char *fname, gboolean is_tempfile, int *err)
 
   /* The open succeeded.  Close whatever capture file we had open,
      and fill in the information for this file. */
-  cf_reset_state(cf);
+  cf_close(cf);
 
   /* Cleanup all data structures used for dissection. */
   cleanup_dissection();
@@ -478,8 +474,8 @@ calc_progbar_val(capture_file *cf, gint64 size, gint64 file_pos, gchar *status_s
   }
 
   g_snprintf(status_str, status_size,
-            "%" G_GINT64_MODIFIER "dKB of %" G_GINT64_MODIFIER "dKB",
-            file_pos / 1024, size / 1024);
+             "%" G_GINT64_MODIFIER "dKB of %" G_GINT64_MODIFIER "dKB",
+             file_pos / 1024, size / 1024);
 
   return progbar_val;
 }
@@ -692,6 +688,14 @@ cf_read(capture_file *cf, gboolean from_save)
        if any. */
     switch (err) {
 
+    case WTAP_ERR_UNSUPPORTED:
+      g_snprintf(errmsg_errno, sizeof(errmsg_errno),
+                 "The capture file contains record data that TShark doesn't support.\n(%s)",
+                 err_info);
+      g_free(err_info);
+      errmsg = errmsg_errno;
+      break;
+
     case WTAP_ERR_UNSUPPORTED_ENCAP:
       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
                  "The capture file has a packet with a network type that Wireshark doesn't support.\n(%s)",
@@ -710,7 +714,7 @@ cf_read(capture_file *cf, gboolean from_save)
         " in the middle of a packet.";
       break;
 
-    case WTAP_ERR_BAD_RECORD:
+    case WTAP_ERR_BAD_FILE:
       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
                  "The capture file appears to be damaged or corrupt.\n(%s)",
                  err_info);
@@ -1202,8 +1206,7 @@ cf_status_t
 cf_merge_files(char **out_filenamep, int in_file_count,
                char *const *in_filenames, int file_type, gboolean do_append)
 {
-  merge_in_file_t  *in_files;
-  wtap             *wth;
+  merge_in_file_t  *in_files, *in_file;
   char             *out_filename;
   char             *tmpname;
   int               out_fd;
@@ -1286,14 +1289,19 @@ cf_merge_files(char **out_filenamep, int in_file_count,
   /* do the merge (or append) */
   for (;;) {
     if (do_append)
-      wth = merge_append_read_packet(in_file_count, in_files, &read_err,
-                                     &err_info);
+      in_file = merge_append_read_packet(in_file_count, in_files, &read_err,
+                                         &err_info);
     else
-      wth = merge_read_packet(in_file_count, in_files, &read_err,
-                              &err_info);
-    if (wth == NULL) {
-      if (read_err != 0)
-        got_read_error = TRUE;
+      in_file = merge_read_packet(in_file_count, in_files, &read_err,
+                                  &err_info);
+    if (in_file == NULL) {
+      /* EOF */
+      break;
+    }
+
+    if (read_err != 0) {
+      /* I/O error reading from in_file */
+      got_read_error = TRUE;
       break;
     }
 
@@ -1343,8 +1351,8 @@ cf_merge_files(char **out_filenamep, int in_file_count,
       break;
     }
 
-    if (!wtap_dump(pdh, wtap_phdr(wth), wtap_pseudoheader(wth),
-         wtap_buf_ptr(wth), &write_err)) {
+    if (!wtap_dump(pdh, wtap_phdr(in_file->wth), wtap_pseudoheader(in_file->wth),
+         wtap_buf_ptr(in_file->wth), &write_err)) {
       got_write_error = TRUE;
       break;
     }
@@ -1367,51 +1375,51 @@ cf_merge_files(char **out_filenamep, int in_file_count,
      */
     for (i = 0; i < in_file_count; i++) {
       if (in_files[i].state == GOT_ERROR) {
-    /* Put up a message box noting that a read failed somewhere along
-       the line. */
-    switch (read_err) {
-
-    case WTAP_ERR_UNSUPPORTED_ENCAP:
-      g_snprintf(errmsg_errno, sizeof(errmsg_errno),
-           "The capture file %%s has a packet with a network type that Wireshark doesn't support.\n(%s)",
-           err_info);
-      g_free(err_info);
-      errmsg = errmsg_errno;
-      break;
+        /* Put up a message box noting that a read failed somewhere along
+           the line. */
+        switch (read_err) {
+
+        case WTAP_ERR_UNSUPPORTED_ENCAP:
+          g_snprintf(errmsg_errno, sizeof(errmsg_errno),
+                     "The capture file %%s has a packet with a network type that Wireshark doesn't support.\n(%s)",
+                     err_info);
+          g_free(err_info);
+          errmsg = errmsg_errno;
+          break;
 
-    case WTAP_ERR_CANT_READ:
-      errmsg = "An attempt to read from the capture file %s failed for"
-           " some unknown reason.";
-      break;
+        case WTAP_ERR_CANT_READ:
+          errmsg = "An attempt to read from the capture file %s failed for"
+                   " some unknown reason.";
+          break;
 
-    case WTAP_ERR_SHORT_READ:
-      errmsg = "The capture file %s appears to have been cut short"
-           " in the middle of a packet.";
-      break;
+        case WTAP_ERR_SHORT_READ:
+          errmsg = "The capture file %s appears to have been cut short"
+                   " in the middle of a packet.";
+          break;
 
-    case WTAP_ERR_BAD_RECORD:
-      g_snprintf(errmsg_errno, sizeof(errmsg_errno),
-           "The capture file %%s appears to be damaged or corrupt.\n(%s)",
-           err_info);
-      g_free(err_info);
-      errmsg = errmsg_errno;
-      break;
+        case WTAP_ERR_BAD_FILE:
+          g_snprintf(errmsg_errno, sizeof(errmsg_errno),
+                     "The capture file %%s appears to be damaged or corrupt.\n(%s)",
+                     err_info);
+          g_free(err_info);
+          errmsg = errmsg_errno;
+          break;
 
-    case WTAP_ERR_DECOMPRESS:
-      g_snprintf(errmsg_errno, sizeof(errmsg_errno),
-                 "The compressed capture file %%s appears to be damaged or corrupt.\n"
-                 "(%s)", err_info);
-      g_free(err_info);
-      errmsg = errmsg_errno;
-      break;
+        case WTAP_ERR_DECOMPRESS:
+          g_snprintf(errmsg_errno, sizeof(errmsg_errno),
+                     "The compressed capture file %%s appears to be damaged or corrupt.\n"
+                     "(%s)", err_info);
+          g_free(err_info);
+          errmsg = errmsg_errno;
+          break;
 
-    default:
-      g_snprintf(errmsg_errno, sizeof(errmsg_errno),
-           "An error occurred while reading the"
-           " capture file %%s: %s.", wtap_strerror(read_err));
-      errmsg = errmsg_errno;
-      break;
-    }
+        default:
+          g_snprintf(errmsg_errno, sizeof(errmsg_errno),
+                     "An error occurred while reading the"
+                     " capture file %%s: %s.", wtap_strerror(read_err));
+          errmsg = errmsg_errno;
+          break;
+        }
         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, errmsg, in_files[i].filename);
       }
     }
@@ -1419,7 +1427,31 @@ cf_merge_files(char **out_filenamep, int in_file_count,
 
   if (got_write_error) {
     /* Put up an alert box for the write error. */
-    cf_write_failure_alert_box(out_filename, write_err);
+    if (write_err < 0) {
+      /* Wiretap error. */
+      switch (write_err) {
+
+      case WTAP_ERR_UNSUPPORTED_ENCAP:
+        /*
+         * This is a problem with the particular frame we're writing;
+         * note that, and give the frame number.
+         */
+        simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+                      "Frame %u of \"%s\" has a network type that can't be saved in a \"%s\" file.",
+                      in_file->packet_num, in_file->filename,
+                      wtap_file_type_string(file_type));
+        break;
+
+      default:
+        simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+                      "An error occurred while writing to the file \"%s\": %s.",
+                      out_filename, wtap_strerror(write_err));
+        break;
+      }
+    } else {
+      /* OS error. */
+      write_failure_alert_box(out_filename, write_err);
+    }
   }
 
   if (got_read_error || got_write_error || stop_flag) {
@@ -1550,7 +1582,7 @@ cf_read_frame_r(capture_file *cf, frame_data *fdata,
       g_free(err_info);
       break;
 
-    case WTAP_ERR_BAD_RECORD:
+    case WTAP_ERR_BAD_FILE:
       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
                  "An error occurred while reading from the file \"%%s\": %s.\n(%s)",
                  wtap_strerror(err), err_info);
@@ -1951,11 +1983,12 @@ ref_time_packets(capture_file *cf)
         cf->elapsed_time = fdata->rel_ts;
     }
 
-    /* Get the time elapsed between the previous displayed packet and
-     this packet. */
-    nstime_delta(&fdata->del_dis_ts, &fdata->abs_ts, &prev_dis_ts);
-
-    prev_dis_ts = fdata->abs_ts;
+    /* If this frame is displayed, get the time elapsed between the 
+     previous displayed packet and this packet. */ 
+    if( fdata->flags.passed_dfilter ) {
+        nstime_delta(&fdata->del_dis_ts, &fdata->abs_ts, &prev_dis_ts);
+        prev_dis_ts = fdata->abs_ts;
+    }
 
     /*
      * Byte counts
@@ -2489,7 +2522,7 @@ cf_write_pdml_packets(capture_file *cf, print_args_t *print_args)
   if (fh == NULL)
     return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
 
-  write_pdml_preamble(fh);
+  write_pdml_preamble(fh, cf->filename);
   if (ferror(fh)) {
     fclose(fh);
     return CF_PRINT_WRITE_ERROR;
@@ -2681,12 +2714,17 @@ cf_write_csv_packets(capture_file *cf, print_args_t *print_args)
 
 static gboolean
 write_carrays_packet(capture_file *cf _U_, frame_data *fdata,
-             union wtap_pseudo_header *pseudo_header _U_,
+             union wtap_pseudo_header *pseudo_header,
              const guint8 *pd, void *argsp)
 {
   FILE *fh = argsp;
+  epan_dissect_t edt;
+
+  epan_dissect_init(&edt, TRUE, TRUE);
+  epan_dissect_run(&edt, pseudo_header, pd, fdata, NULL);
+  proto_tree_write_carrays(fdata->num, fh, &edt);
+  epan_dissect_cleanup(&edt);
 
-  proto_tree_write_carrays(pd, fdata->cap_len, fdata->num, fh);
   return !ferror(fh);
 }
 
@@ -2758,7 +2796,7 @@ cf_find_string_protocol_tree(capture_file *cf, proto_tree *tree,  match_data *md
   mdata->cf = cf;
   /* Iterate through all the nodes looking for matching text */
   proto_tree_children_foreach(tree, match_subtree_text, mdata);
-  return mdata->frame_matched ? MR_MATCHED : MR_NOTMATCHED; 
+  return mdata->frame_matched ? MR_MATCHED : MR_NOTMATCHED;
 }
 
 static match_result
@@ -2963,22 +3001,28 @@ match_ascii_and_unicode(capture_file *cf, frame_data *fdata, void *criterion)
 
   result = MR_NOTMATCHED;
   buf_len = fdata->pkt_len;
-  for (i = 0; i < buf_len; i++) {
+  i = 0;
+  while (i < buf_len) {
     c_char = cf->pd[i];
     if (cf->case_type)
       c_char = toupper(c_char);
-    if (c_char != 0) {
+    if (c_char != '\0') {
       if (c_char == ascii_text[c_match]) {
-        c_match++;
+        c_match += 1;
         if (c_match == textlen) {
           result = MR_MATCHED;
           cf->search_pos = i; /* Save the position of the last character
                                  for highlighting the field. */
           break;
         }
-      } else
+      }
+      else {
+        g_assert(i>=c_match);
+        i -= (guint32)c_match;
         c_match = 0;
+      }
     }
+    i += 1;
   }
   return result;
 }
@@ -3003,21 +3047,28 @@ match_ascii(capture_file *cf, frame_data *fdata, void *criterion)
 
   result = MR_NOTMATCHED;
   buf_len = fdata->pkt_len;
-  for (i = 0; i < buf_len; i++) {
+  i = 0;
+  while (i < buf_len) {
     c_char = cf->pd[i];
     if (cf->case_type)
       c_char = toupper(c_char);
     if (c_char == ascii_text[c_match]) {
-      c_match++;
+      c_match += 1;
       if (c_match == textlen) {
         result = MR_MATCHED;
         cf->search_pos = i; /* Save the position of the last character
                                for highlighting the field. */
         break;
       }
-    } else
+    }
+    else {
+      g_assert(i>=c_match);
+      i -= (guint32)c_match;
       c_match = 0;
+    }
+    i += 1;
   }
+
   return result;
 }
 
@@ -3041,21 +3092,27 @@ match_unicode(capture_file *cf, frame_data *fdata, void *criterion)
 
   result = MR_NOTMATCHED;
   buf_len = fdata->pkt_len;
-  for (i = 0; i < buf_len; i++) {
+  i = 0;
+  while (i < buf_len) {
     c_char = cf->pd[i];
     if (cf->case_type)
       c_char = toupper(c_char);
     if (c_char == ascii_text[c_match]) {
-      c_match++;
-      i++;
+      c_match += 1;
       if (c_match == textlen) {
         result = MR_MATCHED;
         cf->search_pos = i; /* Save the position of the last character
                                for highlighting the field. */
         break;
       }
-    } else
+      i += 1;
+    }
+    else {
+      g_assert(i>=(c_match*2));
+      i -= (guint32)c_match*2;
       c_match = 0;
+    }
+    i += 1;
   }
   return result;
 }
@@ -3079,17 +3136,23 @@ match_binary(capture_file *cf, frame_data *fdata, void *criterion)
 
   result = MR_NOTMATCHED;
   buf_len = fdata->pkt_len;
-  for (i = 0; i < buf_len; i++) {
+  i = 0;
+  while (i < buf_len) {
     if (cf->pd[i] == binary_data[c_match]) {
-      c_match++;
+      c_match += 1;
       if (c_match == datalen) {
         result = MR_MATCHED;
         cf->search_pos = i; /* Save the position of the last character
                                for highlighting the field. */
         break;
       }
-    } else
+    }
+    else {
+      g_assert(i>=c_match);
+      i -= (guint32)c_match;
       c_match = 0;
+    }
+    i += 1;
   }
   return result;
 }
@@ -3379,7 +3442,7 @@ cf_goto_frame(capture_file *cf, guint fnumber)
 }
 
 gboolean
-cf_goto_top_frame()
+cf_goto_top_frame(void)
 {
   /* Find and select */
   new_packet_list_select_first_row();
@@ -3387,7 +3450,7 @@ cf_goto_top_frame()
 }
 
 gboolean
-cf_goto_bottom_frame()
+cf_goto_bottom_frame(void)
 {
   /* Find and select */
   new_packet_list_select_last_row();
@@ -3428,7 +3491,7 @@ cf_select_packet(capture_file *cf, int row)
   if (fdata == NULL) {
     /* XXX - if a GtkCList's selection mode is GTK_SELECTION_BROWSE, when
        the first entry is added to it by "real_insert_row()", that row
-       is selected (see "real_insert_row()", in "gtk/gtkclist.c", in both
+       is selected (see "real_insert_row()", in "ui/gtk/gtkclist.c", in both
        our version and the vanilla GTK+ version).
 
        This means that a "select-row" signal is emitted; this causes
@@ -3570,6 +3633,7 @@ cf_unignore_frame(capture_file *cf, frame_data *frame)
 typedef struct {
   wtap_dumper *pdh;
   const char  *fname;
+  int          file_type;
 } save_callback_args_t;
 
 /*
@@ -3589,15 +3653,45 @@ save_packet(capture_file *cf _U_, frame_data *fdata,
   int           err;
 
   /* init the wtap header for saving */
-  hdr.ts.secs    = fdata->abs_ts.secs;
-  hdr.ts.nsecs   = fdata->abs_ts.nsecs;
-  hdr.caplen     = fdata->cap_len;
-  hdr.len        = fdata->pkt_len;
-  hdr.pkt_encap  = fdata->lnk_t;
-
+  hdr.ts.secs      = fdata->abs_ts.secs;
+  hdr.ts.nsecs     = fdata->abs_ts.nsecs;
+  hdr.caplen       = fdata->cap_len;
+  hdr.len          = fdata->pkt_len;
+  hdr.pkt_encap    = fdata->lnk_t;
+  /* pcapng */
+  hdr.interface_id = fdata->interface_id;   /* identifier of the interface. */
+  /* options */
+  hdr.opt_comment  = fdata->opt_comment; /* NULL if not available */
+#if 0
+  hdr.drop_count   =
+  hdr.pack_flags   =     /* XXX - 0 for now (any value for "we don't have it"?) */
+#endif
   /* and save the packet */
   if (!wtap_dump(args->pdh, &hdr, pseudo_header, pd, &err)) {
-    cf_write_failure_alert_box(args->fname, err);
+    if (err < 0) {
+      /* Wiretap error. */
+      switch (err) {
+
+      case WTAP_ERR_UNSUPPORTED_ENCAP:
+        /*
+         * This is a problem with the particular frame we're writing;
+         * note that, and give the frame number.
+         */
+        simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+                      "Frame %u has a network type that can't be saved in a \"%s\" file.",
+                      fdata->num, wtap_file_type_string(args->file_type));
+        break;
+
+      default:
+        simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+                      "An error occurred while writing to the file \"%s\": %s.",
+                      args->fname, wtap_strerror(err));
+        break;
+      }
+    } else {
+      /* OS error. */
+      write_failure_alert_box(args->fname, err);
+    }
     return FALSE;
   }
   return TRUE;
@@ -3694,20 +3788,30 @@ cf_save(capture_file *cf, const char *fname, packet_range_t *range, guint save_f
     if (do_copy) {
       /* Copy the file, if we haven't moved it. */
       if (!copy_file_binary_mode(from_filename, fname))
-    goto fail;
+        goto fail;
     }
   } else {
     /* Either we're filtering packets, or we're saving in a different
        format; we can't do that by copying or moving the capture file,
        we have to do it by writing the packets out in Wiretap. */
-    pdh = wtap_dump_open(fname, save_format, cf->lnk_t, cf->snap,
-        compressed, &err);
+
+    wtapng_section_t *shb_hdr = NULL;
+    wtapng_iface_descriptions_t *idb_inf = NULL;
+
+    shb_hdr = wtap_file_get_shb_info(cf->wth);
+    idb_inf = wtap_file_get_idb_info(cf->wth);
+
+    pdh = wtap_dump_open_ng(fname, save_format, cf->lnk_t, cf->snap,
+        compressed, shb_hdr, idb_inf, &err);
     if (pdh == NULL) {
       cf_open_failure_alert_box(fname, err, NULL, TRUE, save_format);
       goto fail;
     }
 
-    /* XXX - we let the user save a subset of the packets.
+    /* Add address resolution */
+    wtap_dump_set_addrinfo_list(pdh, get_addrinfo_list());
+
+       /* XXX - we let the user save a subset of the packets.
 
        If we do that, should we make that file the current file?  If so,
        it means we can no longer get at the other packets.  What does
@@ -3722,6 +3826,7 @@ cf_save(capture_file *cf, const char *fname, packet_range_t *range, guint save_f
        "range" since we initialized it. */
     callback_args.pdh = pdh;
     callback_args.fname = fname;
+    callback_args.file_type = save_format;
     switch (process_specified_packets(cf, range, "Saving", "selected packets",
                                       TRUE, save_packet, &callback_args)) {
 
@@ -3866,7 +3971,7 @@ cf_open_failure_alert_box(const char *filename, int err, gchar *err_info,
       }
       break;
 
-    case WTAP_ERR_BAD_RECORD:
+    case WTAP_ERR_BAD_FILE:
       /* Seen only when opening a capture file for reading. */
       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
             "The file \"%s\" appears to be damaged or corrupt.\n"
@@ -3902,7 +4007,7 @@ cf_open_failure_alert_box(const char *filename, int err, gchar *err_info,
 
     case WTAP_ERR_COMPRESSION_NOT_SUPPORTED:
       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
-            "Gzip compression not supported by this file type.");
+            "This file type cannot be written as a compressed file.");
       break;
 
     case WTAP_ERR_DECOMPRESS:
@@ -3952,20 +4057,6 @@ file_rename_error_message(int err)
   return errmsg;
 }
 
-static void
-cf_write_failure_alert_box(const char *filename, int err)
-{
-  if (err < 0) {
-    /* Wiretap error. */
-    simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
-          "An error occurred while writing to the file \"%s\": %s.",
-          filename, wtap_strerror(err));
-  } else {
-    /* OS error. */
-    write_failure_alert_box(filename, err);
-  }
-}
-
 /* Check for write errors - if the file is being written to an NFS server,
    a write error may not show up until the file is closed, as NFS clients
    might not send writes to the server until the "write()" call finishes,
@@ -4063,6 +4154,6 @@ cf_reload(capture_file *cf) {
  * indent-tabs-mode: nil
  * End:
  *
- * ex: set shiftwidth=2 tabstop=8 expandtab
+ * ex: set shiftwidth=2 tabstop=8 expandtab:
  * :indentSize=2:tabSize=8:noTabs=true:
  */