+/*
+ * Add an extension, and all compressed versions thereof, to a GSList
+ * of extensions.
+ */
+static GSList *add_extensions(GSList *extensions, const gchar *extension,
+ GSList *compressed_file_extensions)
+{
+ GSList *compressed_file_extension;
+
+ /*
+ * Add the specified extension.
+ */
+ extensions = g_slist_append(extensions, g_strdup(extension));
+
+ /*
+ * Now add the extensions for compressed-file versions of
+ * that extension.
+ */
+ for (compressed_file_extension = compressed_file_extensions;
+ compressed_file_extension != NULL;
+ compressed_file_extension = g_slist_next(compressed_file_extension)) {
+ extensions = g_slist_append(extensions,
+ g_strdup_printf("%s.%s", extension,
+ (gchar *)compressed_file_extension->data));
+ }
+
+ return extensions;
+}
+
+/*
+ * File types that can be identified by file extensions.
+ */
+static const struct file_extension_info file_type_extensions_base[] = {
+ { "Wireshark/tcpdump/... - pcap", "pcap;cap;dmp" },
+ { "Wireshark/... - pcapng", "pcapng;ntar" },
+ { "Network Monitor, Surveyor, NetScaler", "cap" },
+ { "InfoVista 5View capture", "5vw" },
+ { "Sniffer (DOS)", "cap;enc;trc;fdc;syc" },
+ { "NetXRay, Sniffer (Windows)", "cap;caz" },
+ { "Endace ERF capture", "erf" },
+ { "EyeSDN USB S0/E1 ISDN trace format", "trc" },
+ { "HP-UX nettl trace", "trc0;trc1" },
+ { "Network Instruments Observer", "bfr" },
+ { "Novell LANalyzer", "tr1" },
+ { "Tektronix K12xx 32-bit .rf5 format", "rf5" },
+ { "WildPackets *Peek", "pkt;tpc;apc;wpz" },
+ { "Catapult DCT2000 trace (.out format)", "out" },
+ { "MPEG files", "mpg;mp3" },
+ { "CommView", "ncf" },
+ { "Symbian OS btsnoop", "log" },
+ { "Transport-Neutral Encapsulation Format", "tnef" },
+ { "XML files (including Gammu DCT3 traces)", "xml" },
+ { "OS X PacketLogger", "pklg" },
+ { "Daintree SNA", "dcf" },
+ { "JPEG/JFIF files", "jpg;jpeg;jfif" },
+ { "IPFIX File Format", "pfx;ipfix" },
+ { "Aethra .aps file", "aps" },
+ { "MPEG2 transport stream", "mp2t;ts;mpg" },
+ { "Ixia IxVeriWave .vwr Raw 802.11 Capture", "vwr" },
+ { "CAM Inspector file", "camins" },
+};
+
+#define N_FILE_TYPE_EXTENSIONS (sizeof file_type_extensions_base / sizeof file_type_extensions_base[0])
+
+static const struct file_extension_info* file_type_extensions = NULL;
+
+static GArray* file_type_extensions_arr = NULL;
+
+/* initialize the extensions array if it has not been initialized yet */
+static void init_file_type_extensions(void) {
+
+ if (file_type_extensions_arr) return;
+
+ file_type_extensions_arr = g_array_new(FALSE,TRUE,sizeof(struct file_extension_info));
+
+ g_array_append_vals(file_type_extensions_arr,file_type_extensions_base,N_FILE_TYPE_EXTENSIONS);
+
+ file_type_extensions = (struct file_extension_info*)(void *)file_type_extensions_arr->data;
+}
+
+void wtap_register_file_type_extension(const struct file_extension_info *ei) {
+ init_file_type_extensions();
+
+ g_array_append_val(file_type_extensions_arr,*ei);
+
+ file_type_extensions = (const struct file_extension_info*)(void *)file_type_extensions_arr->data;
+}
+
+int wtap_get_num_file_type_extensions(void)
+{
+ return file_type_extensions_arr->len;
+}
+
+const char *wtap_get_file_extension_type_name(int extension_type)
+{
+ return file_type_extensions[extension_type].name;
+}
+
+static GSList *add_extensions_for_file_extensions_type(int extension_type,
+ GSList *extensions, GSList *compressed_file_extensions)
+{
+ gchar **extensions_set, **extensionp, *extension;
+
+ /*
+ * Split the extension-list string into a set of extensions.
+ */
+ extensions_set = g_strsplit(file_type_extensions[extension_type].extensions,
+ ";", 0);
+
+ /*
+ * Add each of those extensions to the list.
+ */
+ for (extensionp = extensions_set; *extensionp != NULL; extensionp++) {
+ extension = *extensionp;
+
+ /*
+ * Add the extension, and all compressed variants
+ * of it.
+ */
+ extensions = add_extensions(extensions, extension,
+ compressed_file_extensions);
+ }
+
+ g_strfreev(extensions_set);
+ return extensions;
+}
+
+/* Return a list of file extensions that are used by the specified file
+ extension type.
+
+ All strings in the list are allocated with g_malloc() and must be freed
+ with g_free(). */
+GSList *wtap_get_file_extension_type_extensions(guint extension_type)
+{
+ GSList *compressed_file_extensions;
+ GSList *extensions;
+
+ if (extension_type >= file_type_extensions_arr->len)
+ return NULL; /* not a valid extension type */
+
+ extensions = NULL; /* empty list, to start with */
+
+ /*
+ * Get the list of compressed-file extensions.
+ */
+ compressed_file_extensions = wtap_get_compressed_file_extensions();
+
+ /*
+ * Add all this file extension type's extensions, with compressed
+ * variants.
+ */
+ extensions = add_extensions_for_file_extensions_type(extension_type,
+ extensions, compressed_file_extensions);
+
+ g_slist_free(compressed_file_extensions);
+ return extensions;
+}
+
+/* Return a list of all extensions that are used by all file types,
+ including compressed extensions, e.g. not just "pcap" but also
+ "pcap.gz" if we can read gzipped 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 *compressed_file_extensions;
+ GSList *extensions;
+ unsigned int i;
+
+ init_file_type_extensions();
+
+ extensions = NULL; /* empty list, to start with */
+
+ /*
+ * Get the list of compressed-file extensions.
+ */
+ compressed_file_extensions = wtap_get_compressed_file_extensions();
+
+ for (i = 0; i < file_type_extensions_arr->len; i++) {
+ /*
+ * Add all this file extension type's extensions, with
+ * compressed variants.
+ */
+ extensions = add_extensions_for_file_extensions_type(i,
+ extensions, compressed_file_extensions);
+ }
+
+ g_slist_free(compressed_file_extensions);
+ return extensions;
+}
+