Fix the calculation of a file's "basename".
authorGuy Harris <guy@alum.mit.edu>
Fri, 6 Jul 2018 09:06:56 +0000 (02:06 -0700)
committerGuy Harris <guy@alum.mit.edu>
Fri, 6 Jul 2018 09:07:52 +0000 (09:07 +0000)
Strip off only extensions that correspond to file types we know about;
QFileInfo::baseName() strips off *all* extensions, where "extension" is
"anything preceded by a .", so it turns foo.bar.pcap.gz into foo, not
foo.bar.  We don't want that; instead, we strip off only those
extensions that correspond to file types we know how to read, so we'd
strip off .pcap.gz in foo.bar.pcap.gz, and strip off .pcap in
foo.bar.pcap, leaving foo.bar in both cases.

Change-Id: I5385921ad2f0fef815d52e9902fef15735fd9dae
Reviewed-on: https://code.wireshark.org/review/28636
Reviewed-by: Guy Harris <guy@alum.mit.edu>
debian/libwiretap0.symbols
file.c
file.h
ui/qt/capture_file.cpp
wiretap/file_access.c
wiretap/wtap.h

index 400458cfb24130bc556a07b89bd9dd6e1848ecb3..0f7e397ab05e28f3448c555555b85caa68b94806 100644 (file)
@@ -97,6 +97,7 @@ libwiretap.so.0 libwiretap0 #MINVER#
  wtap_free_idb_info@Base 1.99.9
  wtap_fstat@Base 1.9.1
  wtap_get_all_capture_file_extensions_list@Base 2.3.0
+ wtap_get_all_file_extensions_list@Base 2.6.2
  wtap_get_buf_ptr@Base 2.5.1
  wtap_get_bytes_dumped@Base 1.9.1
  wtap_get_debug_if_descr@Base 1.99.9
diff --git a/file.c b/file.c
index 6d95766040c7df8fcb253e7915d133376e02f34f..a94ecd5eff430421271ed0a7c0cd936b6a39ecd5 100644 (file)
--- a/file.c
+++ b/file.c
@@ -1023,6 +1023,52 @@ cf_get_display_name(capture_file *cf)
   return displayname;
 }
 
+gchar *
+cf_get_basename(capture_file *cf)
+{
+  gchar *displayname;
+
+  /* Return a name to use in the GUI for the basename for files to
+     which we save statistics */
+  if (!cf->is_tempfile) {
+    /* Get the last component of the file name, and use that. */
+    if (cf->filename) {
+      displayname = g_filename_display_basename(cf->filename);
+
+      /* If the file name ends with any extension that corresponds
+         to a file type we support - including compressed versions
+         of those files - strip it off. */
+      size_t displayname_len = strlen(displayname);
+      GSList *extensions = wtap_get_all_file_extensions_list();
+      GSList *suffix;
+      for (suffix = extensions; suffix != NULL; suffix = g_slist_next(suffix)) {
+        /* Does the file name end with that extension? */
+        const char *extension = (char *)suffix->data;
+        size_t extension_len = strlen(extension);
+        if (displayname_len > extension_len &&
+          displayname[displayname_len - extension_len - 1] == '.' &&
+          strcmp(&displayname[displayname_len - extension_len], extension) == 0) {
+            /* Yes.  Strip the extension off, and return the result. */
+            displayname[displayname_len - extension_len - 1] = '\0';
+            return displayname;
+        }
+      }
+    } else {
+      displayname=g_strdup("");
+    }
+  } else {
+    /* The file we read is a temporary file from a live capture or
+       a merge operation; we don't mention its name, but, if it's
+       from a capture, give the source of the capture. */
+    if (cf->source) {
+      displayname = g_strdup(cf->source);
+    } else {
+      displayname = g_strdup("");
+    }
+  }
+  return displayname;
+}
+
 void cf_set_tempfile_source(capture_file *cf, gchar *source) {
   if (cf->source) {
     g_free(cf->source);
diff --git a/file.h b/file.h
index 3088435a609606f3ac4c19fdd3f1f4a0b6d19c7b..090528654b143cc7f0e7dd590958274579e54cbd 100644 (file)
--- a/file.h
+++ b/file.h
@@ -275,6 +275,17 @@ cf_write_status_t cf_export_specified_packets(capture_file *cf,
  */
 gchar *cf_get_display_name(capture_file *cf);
 
+/**
+ * Get a name that can be used to generate a file name from the
+ * capture file name.  It's based on the displayable name, so it's
+ * UTF-8; if it ends with a suffix that's used by a file type libwiretap
+ * can read, we strip that suffix off.
+ *
+ * @param cf the capture file
+ * @return the base name (must be g_free'd)
+ */
+gchar *cf_get_basename(capture_file *cf);
+
 /**
  * Set the source of the capture data for temporary files, e.g.
  * "Interface eth0" or "Pipe from Pong"
index 3aee4f557c62e11ee4f4e147701d6bc8e62ae145..039ded83aa696f310d2b09bbfc197f7eef2ba622 100644 (file)
@@ -160,16 +160,15 @@ const QString CaptureFile::fileName()
 
 const QString CaptureFile::fileBaseName()
 {
-    QString path, baseName;
+    QString baseName;
 
-    path = filePath();
-    if (!path.isEmpty()) {
-        QFileInfo cfi(path);
-        baseName = cfi.baseName();
+    if (isValid()) {
+        char *basename = cf_get_basename(cap_file_);
+        baseName = basename;
+        g_free(basename);
     } else {
         baseName = QString();
     }
-
     return baseName;
 }
 
index cc29ed8eb7c5ea1aaa7f0ef8fa2a1189dd6d320c..5de6744e3ac3b75269be555cc4b8f2c07395abcd 100644 (file)
@@ -1635,7 +1635,7 @@ static const struct file_type_subtype_info* dump_open_table = dump_open_table_ba
  * to the number of elements in the static table, but, if we have to
  * allocate the GArray, it's changed to have the size of the GArray.
  */
-gint wtap_num_file_types_subtypes = sizeof(dump_open_table_base) / sizeof(struct file_type_subtype_info);
+static gint wtap_num_file_types_subtypes = sizeof(dump_open_table_base) / sizeof(struct file_type_subtype_info);
 
 /*
  * Pointer to the GArray; NULL until it's needed.
@@ -2025,11 +2025,13 @@ add_extensions_for_file_type_subtype(int file_type_subtype, GSList *extensions,
 
        /*
         * Add the default extension, and all compressed variants of
-        * it.
+        * it, if there is a default extension.
         */
-       extensions = add_extensions(extensions,
-           dump_open_table[file_type_subtype].default_file_extension,
-           compressed_file_extensions);
+       if (dump_open_table[file_type_subtype].default_file_extension != NULL) {
+               extensions = add_extensions(extensions,
+                   dump_open_table[file_type_subtype].default_file_extension,
+                   compressed_file_extensions);
+       }
 
        if (dump_open_table[file_type_subtype].additional_file_extensions != NULL) {
                /*
@@ -2095,10 +2097,37 @@ wtap_get_file_extensions_list(int file_type_subtype, gboolean include_compressed
        return extensions;
 }
 
+/* Return a list of all extensions that are used by all file types that
+   we can read, including compressed extensions, e.g. not just "pcap" but
+   also "pcap.gz" if we can read gzipped files.
+
+   "File type" means "include file types that correspond to collections
+   of network packets, as well as file types that store data that just
+   happens to be transported over protocols such as HTTP but that aren't
+   collections of network packets, and plain text files".
+
+   All strings in the list are allocated with g_malloc() and must be freed
+   with g_free(). */
+GSList *
+wtap_get_all_file_extensions_list(void)
+{
+       GSList *extensions;
+       int i;
+
+       extensions = NULL;      /* empty list, to start with */
+
+       for (i = 0; i < WTAP_NUM_FILE_TYPES_SUBTYPES; i++) {
+               extensions = add_extensions_for_file_type_subtype(i, extensions,
+                   compressed_file_extension_table);
+       }
+
+       return extensions;
+}
+
 /*
  * Free a list returned by wtap_get_file_extension_type_extensions(),
- * wtap_get_all_capture_file_extensions_list, or
- * wtap_get_file_extensions_list().
+ * wtap_get_all_capture_file_extensions_list, wtap_get_file_extensions_list(),
+ * or wtap_get_all_file_extensions_list().
  */
 void
 wtap_free_extensions_list(GSList *extensions)
index ceedb762a84eb314f5e26037d163f3dcc8e9b0dc..d1beb85dfe6b62eec6246765e1b7813dff729038 100644 (file)
@@ -2004,6 +2004,8 @@ const char *wtap_default_file_extension(int filetype);
 WS_DLL_PUBLIC
 GSList *wtap_get_file_extensions_list(int filetype, gboolean include_compressed);
 WS_DLL_PUBLIC
+GSList *wtap_get_all_file_extensions_list(void);
+WS_DLL_PUBLIC
 void wtap_free_extensions_list(GSList *extensions);
 
 WS_DLL_PUBLIC