Move the new files to the same places as in automake.
[obnox/wireshark/wip.git] / wiretap / file_access.c
index ed213e6df84f2403e6fe755367a74534857c12b2..3b604217b56a41a3af0c8f6a6bc9a87b2538b363 100644 (file)
 #include "netscreen.h"
 #include "commview.h"
 #include "pcapng.h"
+#include "aethra.h"
 #include "btsnoop.h"
 #include "tnef.h"
 #include "dct3trace.h"
 #include "packetlogger.h"
 #include "daintree-sna.h"
 #include "netscaler.h"
-#include "jpeg_jfif.h"
+#include "mime_file.h"
 #include "ipfix.h"
-
+#include "pcap-encap.h"
 
 /* The open_file_* routines should return:
  *
@@ -126,6 +127,7 @@ static wtap_open_routine_t open_routines_base[] = {
        catapult_dct2000_open,
        ber_open,
        pcapng_open,
+       aethra_open,
        btsnoop_open,
        packetlogger_open, /* This type does not have a magic number, but its
                            * files are sometimes grabbed by mpeg_open. */
@@ -133,7 +135,7 @@ static wtap_open_routine_t open_routines_base[] = {
        tnef_open,
        dct3trace_open,
        daintree_sna_open,
-       jpeg_jfif_open,
+       mime_file_open,
        /* Files that don't have magic bytes at a fixed location,
         * but that instead require a heuristic of some sort to
         * identify them.  This includes the ASCII trace files that
@@ -222,6 +224,7 @@ void wtap_register_open_routine(wtap_open_routine_t open_routine, gboolean has_m
 wtap* wtap_open_offline(const char *filename, int *err, char **err_info,
                        gboolean do_random)
 {
+       int     fd;
        ws_statb64 statb;
        wtap    *wth;
        unsigned int    i;
@@ -296,23 +299,23 @@ wtap* wtap_open_offline(const char *filename, int *err, char **err_info,
                 * a file_close of wth->fh closing the standard
                 * input of the process.
                 */
-               wth->fd = ws_dup(0);
-               if (wth->fd < 0) {
+               fd = ws_dup(0);
+               if (fd < 0) {
                        *err = errno;
                        g_free(wth);
                        return NULL;
                }
 #ifdef _WIN32
-               if (_setmode(wth->fd, O_BINARY) == -1) {
+               if (_setmode(fd, O_BINARY) == -1) {
                        /* "Shouldn't happen" */
                        *err = errno;
                        g_free(wth);
                        return NULL;
                }
 #endif
-               if (!(wth->fh = filed_open(wth->fd))) {
+               if (!(wth->fh = filed_open(fd))) {
                        *err = errno;
-                       ws_close(wth->fd);
+                       ws_close(fd);
                        g_free(wth);
                        return NULL;
                }
@@ -406,245 +409,246 @@ static const struct file_type_info dump_open_table_base[] = {
        { NULL, NULL, NULL, NULL, FALSE, FALSE,
          NULL, NULL },
 
-       /* WTAP_FILE_WTAP (only used internally while capturing) */
-       { NULL, NULL, NULL, NULL, FALSE, FALSE,
-         NULL, NULL },
-
        /* WTAP_FILE_PCAP */
-       { "Wireshark/tcpdump/... - libpcap", "libpcap", "*.pcap;*.cap", ".pcap", FALSE, FALSE,
+        /* Gianluca Varenni suggests that we add "deprecated" to the description. */
+       { "Wireshark/tcpdump/... - libpcap", "libpcap", "pcap", "cap", FALSE, FALSE,
          libpcap_dump_can_write_encap, libpcap_dump_open },
 
+       /* WTAP_FILE_PCAPNG */
+       { "Wireshark - pcapng", "pcapng", "pcapng", NULL, FALSE, TRUE,
+         pcapng_dump_can_write_encap, pcapng_dump_open },
+
        /* WTAP_FILE_PCAP_NSEC */
-       { "Wireshark - nanosecond libpcap", "nseclibpcap", "*.pcap;*.cap", ".pcap", FALSE, FALSE,
+       { "Wireshark - nanosecond libpcap", "nseclibpcap", "pcap", "cap", FALSE, FALSE,
          libpcap_dump_can_write_encap, libpcap_dump_open },
 
        /* WTAP_FILE_PCAP_AIX */
-       { "AIX tcpdump - libpcap", "aixlibpcap", "*.pcap;*.cap", ".pcap", FALSE, FALSE,
+       { "AIX tcpdump - libpcap", "aixlibpcap", "pcap", "cap", FALSE, FALSE,
          NULL, NULL },
 
        /* WTAP_FILE_PCAP_SS991029 */
-       { "Modified tcpdump - libpcap", "modlibpcap", "*.pcap;*.cap", ".pcap", FALSE, FALSE,
+       { "Modified tcpdump - libpcap", "modlibpcap", "pcap", "cap", FALSE, FALSE,
          libpcap_dump_can_write_encap, libpcap_dump_open },
 
        /* WTAP_FILE_PCAP_NOKIA */
-       { "Nokia tcpdump - libpcap ", "nokialibpcap", "*.pcap;*.cap", ".pcap", FALSE, FALSE,
+       { "Nokia tcpdump - libpcap ", "nokialibpcap", "pcap", "cap", FALSE, FALSE,
          libpcap_dump_can_write_encap, libpcap_dump_open },
 
        /* WTAP_FILE_PCAP_SS990417 */
-       { "RedHat 6.1 tcpdump - libpcap", "rh6_1libpcap", "*.pcap;*.cap", ".pcap", FALSE, FALSE,
+       { "RedHat 6.1 tcpdump - libpcap", "rh6_1libpcap", "pcap", "cap", FALSE, FALSE,
          libpcap_dump_can_write_encap, libpcap_dump_open },
 
        /* WTAP_FILE_PCAP_SS990915 */
-       { "SuSE 6.3 tcpdump - libpcap", "suse6_3libpcap", "*.pcap;*.cap", ".pcap", FALSE, FALSE,
+       { "SuSE 6.3 tcpdump - libpcap", "suse6_3libpcap", "pcap", "cap", FALSE, FALSE,
          libpcap_dump_can_write_encap, libpcap_dump_open },
 
        /* WTAP_FILE_5VIEWS */
-       { "Accellent 5Views capture", "5views", "*.5vw", ".5vw", TRUE, FALSE,
+       { "Accellent 5Views capture", "5views", "5vw", NULL, TRUE, FALSE,
          _5views_dump_can_write_encap, _5views_dump_open },
 
        /* WTAP_FILE_IPTRACE_1_0 */
-       { "AIX iptrace 1.0", "iptrace_1", "*.*", NULL, FALSE, FALSE,
+       { "AIX iptrace 1.0", "iptrace_1", NULL, NULL, FALSE, FALSE,
          NULL, NULL },
 
        /* WTAP_FILE_IPTRACE_2_0 */
-       { "AIX iptrace 2.0", "iptrace_2", "*.*", NULL, FALSE, FALSE,
+       { "AIX iptrace 2.0", "iptrace_2", NULL, NULL, FALSE, FALSE,
          NULL, NULL },
 
        /* WTAP_FILE_BER */
-       { "ASN.1 Basic Encoding Rules", "ber", "*.*", NULL, FALSE, FALSE,
+       { "ASN.1 Basic Encoding Rules", "ber", NULL, NULL, FALSE, FALSE,
                NULL, NULL },
 
        /* WTAP_FILE_HCIDUMP */
-       { "Bluetooth HCI dump", "hcidump", "*.*", NULL, FALSE, FALSE,
+       { "Bluetooth HCI dump", "hcidump", NULL, NULL, FALSE, FALSE,
          NULL, NULL },
 
        /* WTAP_FILE_CATAPULT_DCT2000 */
-       { "Catapult DCT2000 trace (.out format)", "dct2000", "*.out", ".out", FALSE, FALSE,
+       { "Catapult DCT2000 trace (.out format)", "dct2000", "out", NULL, FALSE, FALSE,
          catapult_dct2000_dump_can_write_encap, catapult_dct2000_dump_open },
 
        /* WTAP_FILE_NETXRAY_OLD */
-       { "Cinco Networks NetXRay 1.x", "netxray1", "*.cap", ".cap", TRUE, FALSE,
+       { "Cinco Networks NetXRay 1.x", "netxray1", "cap", NULL, TRUE, FALSE,
          NULL, NULL },
 
        /* WTAP_FILE_NETXRAY_1_0 */
-       { "Cinco Networks NetXRay 2.0 or later", "netxray2", "*.cap", ".cap", TRUE, FALSE,
+       { "Cinco Networks NetXRay 2.0 or later", "netxray2", "cap", NULL, TRUE, FALSE,
          NULL, NULL },
 
        /* WTAP_FILE_COSINE */
-       { "CoSine IPSX L2 capture", "cosine", "*.*", NULL, FALSE, FALSE,
+       { "CoSine IPSX L2 capture", "cosine", "txt", NULL, FALSE, FALSE,
          NULL, NULL },
 
        /* WTAP_FILE_CSIDS */
-       { "CSIDS IPLog", "csids", "*.*", NULL, FALSE, FALSE,
+       { "CSIDS IPLog", "csids", NULL, NULL, FALSE, FALSE,
          NULL, NULL },
 
        /* WTAP_FILE_DBS_ETHERWATCH */
-       { "DBS Etherwatch (VMS)", "etherwatch", "*.*", NULL, FALSE, FALSE,
+       { "DBS Etherwatch (VMS)", "etherwatch", "txt", NULL, FALSE, FALSE,
          NULL, NULL},
 
        /* WTAP_FILE_ERF */
-       { "Endace ERF capture", "erf", "*.erf", ".erf", FALSE, FALSE,
-         NULL, NULL },
+       { "Endace ERF capture", "erf", "erf", NULL, FALSE, FALSE,
+         erf_dump_can_write_encap, erf_dump_open },
 
        /* WTAP_FILE_EYESDN */
-       { "EyeSDN USB S0/E1 ISDN trace format", "eyesdn", "*.trc", ".trc", FALSE, FALSE,
+       { "EyeSDN USB S0/E1 ISDN trace format", "eyesdn", "trc", NULL, FALSE, FALSE,
           eyesdn_dump_can_write_encap, eyesdn_dump_open },
 
        /* WTAP_FILE_NETTL */
-       { "HP-UX nettl trace", "nettl", "*.TRC0;*.TRC1", ".TRC0", FALSE, FALSE,
+       { "HP-UX nettl trace", "nettl", "trc0", "trc1", FALSE, FALSE,
          nettl_dump_can_write_encap, nettl_dump_open },
 
        /* WTAP_FILE_ISERIES */
-       { "IBM iSeries comm. trace (ASCII)", "iseries_ascii", "*.*", NULL, FALSE, FALSE,
+       { "IBM iSeries comm. trace (ASCII)", "iseries_ascii", "txt", NULL, FALSE, FALSE,
          NULL, NULL },
 
        /* WTAP_FILE_ISERIES_UNICODE */
-       { "IBM iSeries comm. trace (UNICODE)", "iseries_unicode", "*.*", NULL, FALSE, FALSE,
+       { "IBM iSeries comm. trace (UNICODE)", "iseries_unicode", "txt", NULL, FALSE, FALSE,
          NULL, NULL },
 
        /* WTAP_FILE_I4BTRACE */
-       { "I4B ISDN trace", "i4btrace", "*.*", NULL, FALSE, FALSE,
+       { "I4B ISDN trace", "i4btrace", NULL, NULL, FALSE, FALSE,
          NULL, NULL },
 
        /* WTAP_FILE_ASCEND */
-       { "Lucent/Ascend access server trace", "ascend", "*.*", NULL, FALSE, FALSE,
+       { "Lucent/Ascend access server trace", "ascend", "txt", NULL, FALSE, FALSE,
          NULL, NULL },
 
        /* WTAP_FILE_NETMON_1_x */
-       { "Microsoft NetMon 1.x", "netmon1", "*.cap", ".cap", TRUE, FALSE,
-         netmon_dump_can_write_encap, netmon_dump_open },
+       { "Microsoft NetMon 1.x", "netmon1", "cap", NULL, TRUE, FALSE,
+         netmon_dump_can_write_encap_1_x, netmon_dump_open },
 
        /* WTAP_FILE_NETMON_2_x */
-       { "Microsoft NetMon 2.x", "netmon2", "*.cap", ".cap", TRUE, FALSE,
-         netmon_dump_can_write_encap, netmon_dump_open },
+       { "Microsoft NetMon 2.x", "netmon2", "cap", NULL, TRUE, FALSE,
+         netmon_dump_can_write_encap_2_x, netmon_dump_open },
 
        /* WTAP_FILE_NGSNIFFER_UNCOMPRESSED */
-       { "NA Sniffer (DOS)", "ngsniffer", "*.cap;*.enc;*.trc;*.fdc;*.syc", ".cap", FALSE, FALSE,
+       { "NA Sniffer (DOS)", "ngsniffer", "cap", "enc;trc;fdc;syc", FALSE, FALSE,
          ngsniffer_dump_can_write_encap, ngsniffer_dump_open },
 
        /* WTAP_FILE_NGSNIFFER_COMPRESSED */
-       { "NA Sniffer (DOS), compressed", "ngsniffer_comp", "*.caz", ".caz", FALSE, FALSE,
+       { "NA Sniffer (DOS), compressed", "ngsniffer_comp", "caz", NULL, FALSE, FALSE,
          NULL, NULL },
 
        /* WTAP_FILE_NETXRAY_1_1 */
-       { "NA Sniffer (Windows) 1.1", "ngwsniffer_1_1", "*.cap", ".cap", TRUE, FALSE,
+       { "NA Sniffer (Windows) 1.1", "ngwsniffer_1_1", "cap", NULL, TRUE, FALSE,
          netxray_dump_can_write_encap_1_1, netxray_dump_open_1_1 },
 
        /* WTAP_FILE_NETXRAY_2_00x */
-       { "NA Sniffer (Windows) 2.00x", "ngwsniffer_2_0", "*.cap", ".cap", TRUE, FALSE,
+       { "NA Sniffer (Windows) 2.00x", "ngwsniffer_2_0", "cap", NULL, TRUE, FALSE,
          netxray_dump_can_write_encap_2_0, netxray_dump_open_2_0 },
 
        /* WTAP_FILE_NETWORK_INSTRUMENTS */
-       { "Network Instruments Observer", "niobserverv", "*.bfr", ".bfr", FALSE, FALSE,
+       { "Network Instruments Observer", "niobserver", "bfr", NULL, FALSE, FALSE,
          network_instruments_dump_can_write_encap, network_instruments_dump_open },
 
        /* WTAP_FILE_LANALYZER */
-       { "Novell LANalyzer","lanalyzer", "*.tr1", ".tr1", TRUE, FALSE,
+       { "Novell LANalyzer","lanalyzer", "tr1", NULL, TRUE, FALSE,
          lanalyzer_dump_can_write_encap, lanalyzer_dump_open },
 
        /* WTAP_FILE_PPPDUMP */
-       { "pppd log (pppdump format)", "pppd", "*.*", NULL, FALSE, FALSE,
+       { "pppd log (pppdump format)", "pppd", NULL, NULL, FALSE, FALSE,
          NULL, NULL },
 
        /* WTAP_FILE_RADCOM */
-       { "RADCOM WAN/LAN analyzer", "radcom", "*.*", NULL, FALSE, FALSE,
+       { "RADCOM WAN/LAN analyzer", "radcom", NULL, NULL, FALSE, FALSE,
          NULL, NULL },
 
        /* WTAP_FILE_SNOOP */
-       { "Sun snoop", "snoop", "*.snoop;*.cap", ".snoop", FALSE, FALSE,
+       { "Sun snoop", "snoop", "snoop", "cap", FALSE, FALSE,
          snoop_dump_can_write_encap, snoop_dump_open },
 
        /* WTAP_FILE_SHOMITI */
-       { "Shomiti/Finisar Surveyor", "shomiti", "*.cap", ".cap", FALSE, FALSE,
+       { "Shomiti/Finisar Surveyor", "shomiti", "cap", NULL, FALSE, FALSE,
          NULL, NULL },
 
        /* WTAP_FILE_VMS */
-       { "TCPIPtrace (VMS)", "tcpiptrace", "*.*", NULL, FALSE, FALSE,
+       { "TCPIPtrace (VMS)", "tcpiptrace", "txt", NULL, FALSE, FALSE,
          NULL, NULL},
 
        /* WTAP_FILE_K12 */
-       { "Tektronix K12xx 32-bit .rf5 format", "rf5", "*.rf5", ".rf5", TRUE, FALSE,
+       { "Tektronix K12xx 32-bit .rf5 format", "rf5", "rf5", NULL, TRUE, FALSE,
                k12_dump_can_write_encap, k12_dump_open },
 
        /* WTAP_FILE_TOSHIBA */
-       { "Toshiba Compact ISDN Router snoop", "toshiba", "*.*", NULL, FALSE, FALSE,
+       { "Toshiba Compact ISDN Router snoop", "toshiba", "txt", NULL, FALSE, FALSE,
          NULL, NULL },
 
        /* WTAP_FILE_VISUAL_NETWORKS */
-       { "Visual Networks traffic capture", "visual", "*.*", NULL, TRUE, FALSE,
+       { "Visual Networks traffic capture", "visual", NULL, NULL, TRUE, FALSE,
          visual_dump_can_write_encap, visual_dump_open },
 
        /* WTAP_FILE_ETHERPEEK_V56 */
-       { "WildPackets Ether/TokenPeek (V5 & V6)", "peek56", "*.tpc;*.apc;*.pkt;*.wpz", ".pkt", FALSE, FALSE,
+       { "WildPackets Ether/TokenPeek (V5 & V6)", "peek56", "pkt", "tpc;apc;wpz", FALSE, FALSE,
          NULL, NULL },
 
        /* WTAP_FILE_ETHERPEEK_V7 */
-       { "WildPackets Ether/Token/AiroPeek (V7)", "peek7", "*.tpc;*.apc;*.pkt;*.wpz", ".pkt", FALSE, FALSE,
+       { "WildPackets Ether/Token/AiroPeek (V7)", "peek7", "pkt", "tpc;apc;wpz", FALSE, FALSE,
          NULL, NULL },
 
        /* WTAP_FILE_ETHERPEEK_V9 */
-       { "WildPackets Ether/AiroPeek (V9)", "peek9", "*.tpc;*.apc;*.pkt;*.wpz", ".pkt", FALSE, FALSE,
+       { "WildPackets Ether/AiroPeek (V9)", "peek9", "pkt", "tpc;apc;wpz", FALSE, FALSE,
          NULL, NULL },
 
        /* WTAP_FILE_MPEG */
-       { "MPEG", "mpeg", "*.mpeg;*.mpg;*.mp3", ".mpeg", FALSE, FALSE,
+       { "MPEG", "mpeg", "mpeg", "mpg;mp3", FALSE, FALSE,
          NULL, NULL },
 
        /* WTAP_FILE_K12TEXT  */
-       { "K12 text file", "k12text", "*.txt", ".txt", FALSE, FALSE,
+       { "K12 text file", "k12text", "txt", NULL, FALSE, FALSE,
          k12text_dump_can_write_encap, k12text_dump_open },
 
        /* WTAP_FILE_NETSCREEN */
-       { "NetScreen snoop text file", "netscreen", "*.*", NULL, FALSE, FALSE,
+       { "NetScreen snoop text file", "netscreen", "txt", NULL, FALSE, FALSE,
          NULL, NULL },
 
        /* WTAP_FILE_COMMVIEW */
-       { "TamoSoft CommView", "commview", "*.ncf", ".ncf", FALSE, FALSE,
+       { "TamoSoft CommView", "commview", "ncf", NULL, FALSE, FALSE,
          commview_dump_can_write_encap, commview_dump_open },
 
-       /* WTAP_FILE_PCAPNG */
-       { "Wireshark - pcapng", "pcapng", "*.pcapng", NULL, FALSE, TRUE,
-         pcapng_dump_can_write_encap, pcapng_dump_open },
-
        /* WTAP_FILE_BTSNOOP */
-       { "Symbian OS btsnoop", "btsnoop", "*.log", ".log", FALSE, FALSE,
+       { "Symbian OS btsnoop", "btsnoop", "log", NULL, FALSE, FALSE,
          btsnoop_dump_can_write_encap, btsnoop_dump_open_h4 },
 
-       /* WTAP_FILE_X2E_XORAYA */
-       { NULL, NULL, NULL, NULL, FALSE, FALSE,
-         NULL, NULL },
-
        /* WTAP_FILE_TNEF */
-       { "Transport-Neutral Encapsulation Format", "tnef", "*.*", NULL, FALSE, FALSE,
+       { "Transport-Neutral Encapsulation Format", "tnef", NULL, NULL, FALSE, FALSE,
          NULL, NULL },
 
        /* WTAP_FILE_DCT3TRACE */
-       { "Gammu DCT3 trace", "dct3trace", "*.xml", NULL, FALSE, FALSE,
+       { "Gammu DCT3 trace", "dct3trace", "xml", NULL, FALSE, FALSE,
          NULL, NULL },
 
        /* WTAP_FILE_PACKETLOGGER */
-       { "PacketLogger", "pklg", "*.pklg", NULL, FALSE, FALSE,
+       { "PacketLogger", "pklg", "pklg", NULL, FALSE, FALSE,
          NULL, NULL },
 
        /* WTAP_FILE_DAINTREE_SNA */
-       { "Daintree SNA", "dsna", "*.dcf", NULL, FALSE, FALSE,
+       { "Daintree SNA", "dsna", "dcf", NULL, FALSE, FALSE,
          NULL, NULL },
 
        /* WTAP_FILE_NETSCALER_1_0 */
-       { "NetScaler Trace (Version 1.0)", "nstrace10", "*.*", "*.*", TRUE, FALSE,
+       { "NetScaler Trace (Version 1.0)", "nstrace10", NULL, NULL, TRUE, FALSE,
          nstrace_10_dump_can_write_encap, nstrace_dump_open },
 
        /* WTAP_FILE_NETSCALER_2_0 */
-       { "NetScaler Trace (Version 2.0)", "nstrace20", "*.cap", "*.cap", TRUE, FALSE,
+       { "NetScaler Trace (Version 2.0)", "nstrace20", "cap", NULL, TRUE, FALSE,
          nstrace_20_dump_can_write_encap, nstrace_dump_open },
 
        /* WTAP_FILE_JPEG_JFIF */
-       { "JPEG/JFIF", "jpeg", "*.jpg;*.jpeg;*.jfif", ".jpg", FALSE, FALSE,
+       { "JPEG/JFIF", "jpeg", "jpg", "jpeg;jfif", FALSE, FALSE,
          NULL, NULL },
 
        /* WTAP_FILE_IPFIX */
-       { "IPFIX File Format", "ipfix", "*.pfx;*.ipfix", NULL, FALSE, FALSE,
-         NULL, NULL }
+       { "IPFIX File Format", "ipfix", "pfx", "ipfix", FALSE, FALSE,
+         NULL, NULL },
+
+       /* WTAP_ENCAP_MIME */
+       { "MIME File Format", "mime", NULL, NULL, FALSE, FALSE,
+          NULL, NULL },
+
+       /* WTAP_FILE_AETHRA */
+       { "Aethra .aps file", "aethra", "aps", NULL, FALSE, FALSE,
+         NULL, NULL },
 };
 
 gint wtap_num_file_types = sizeof(dump_open_table_base) / sizeof(struct file_type_info);
@@ -679,6 +683,89 @@ int wtap_get_num_file_types(void)
        return wtap_num_file_types;
 }
 
+/*
+ * Get a GArray of WTAP_FILE_ values for file types that can be used
+ * to save a file of a given type with a given WTAP_ENCAP_ type.
+ */
+static gboolean
+can_save_with_wiretap(int ft, int encap)
+{
+       /*
+        * To save a file in a given file format, we have to handle that
+        * format, and the code to handle that format must be able to
+        * write a file with that file's encapsulation type.
+        */
+       return wtap_dump_can_open(ft) &&
+           wtap_dump_can_write_encap(ft, encap);
+}
+
+GArray *
+wtap_get_savable_file_types(int file_type, int file_encap)
+{
+       GArray *savable_file_types;
+       int ft;
+       int default_file_type = -1;
+       int other_file_type = -1;
+
+       /* Can we save this file in its own file type? */
+       if (can_save_with_wiretap(file_type, file_encap)) {
+               /* Yes - make that the default file type. */
+               default_file_type = file_type;
+       } else {
+               /* No - can we save it as a pcap-NG file? */
+               if (can_save_with_wiretap(WTAP_FILE_PCAPNG, file_encap)) {
+                       /* Yes - default to pcap-NG, instead. */
+                       default_file_type = WTAP_FILE_PCAPNG;
+               } else {
+                       /* OK, find the first file type we *can* save it as. */
+                       default_file_type = -1;
+                       for (ft = 0; ft < WTAP_NUM_FILE_TYPES; ft++) {
+                               if (can_save_with_wiretap(ft, file_encap)) {
+                                       /* OK, got it. */
+                                       default_file_type = ft;
+                               }
+                       }
+               }
+       }
+
+       if (default_file_type == -1) {
+               /* We don't support writing this file as any file type. */
+               return NULL;
+       }
+
+       /* Allocate the array. */
+       savable_file_types = g_array_new(FALSE, FALSE, (guint)sizeof (int));
+
+       /* Put the default file format first in the list. */
+       g_array_append_val(savable_file_types, default_file_type);
+
+       /* If it's pcap, put pcap-NG right after it; otherwise, if it's
+          pcap-NG, put pcap right after it. */
+       if (default_file_type == WTAP_FILE_PCAP) {
+               if (can_save_with_wiretap(WTAP_FILE_PCAPNG, file_encap))
+                       other_file_type = WTAP_FILE_PCAPNG;
+       } else if (default_file_type == WTAP_FILE_PCAPNG) {
+               if (can_save_with_wiretap(WTAP_FILE_PCAP, file_encap))
+                       other_file_type = WTAP_FILE_PCAP;
+       }
+       if (other_file_type != -1)
+               g_array_append_val(savable_file_types, other_file_type);
+
+       /* Add all the other file types that work. */
+       for (ft = 0; ft < WTAP_NUM_FILE_TYPES; ft++) {
+               if (ft == WTAP_FILE_UNKNOWN)
+                       continue;       /* not a real file type */
+               if (ft == default_file_type || ft == other_file_type)
+                       continue;       /* we've already done this one */
+               if (can_save_with_wiretap(ft, file_encap)) {
+                       /* OK, we can write it out in this type. */
+                       g_array_append_val(savable_file_types, ft);
+               }
+       }
+
+       return savable_file_types;
+}
+
 /* Name that should be somewhat descriptive. */
 const char *wtap_file_type_string(int filetype)
 {
@@ -712,22 +799,118 @@ int wtap_short_string_to_file_type(const char *short_name)
        return -1;      /* no such file type, or we can't write it */
 }
 
-/* file extensions to use. */
-const char *wtap_file_extensions_string(int filetype)
+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;
+}
+
+/* Return a list of file extensions that are used by the specified file type.
+   This includes 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_file_extensions_list(int filetype)
 {
+       gchar **extensions_set, **extensionp;
+       gchar *extension;
+       GSList *compressed_file_extensions;
+       GSList *extensions;
+
        if (filetype < 0 || filetype >= wtap_num_file_types)
-               return NULL;
-       else
-               return dump_open_table[filetype].file_extensions;
+               return NULL;    /* not a valid file type */
+
+       if (dump_open_table[filetype].default_file_extension == NULL)
+               return NULL;    /* valid, but no extensions known */
+
+       extensions = NULL;      /* empty list, to start with */
+
+       /*
+        * Get the list of compressed-file extensions.
+        */
+       compressed_file_extensions = wtap_get_compressed_file_extensions();
+
+       /*
+        * Add the default extension, and all compressed variants of
+        * it.
+        */
+       extensions = add_extensions(extensions,
+           dump_open_table[filetype].default_file_extension,
+           compressed_file_extensions);
+
+       if (dump_open_table[filetype].additional_file_extensions != NULL) {
+               /*
+                * We have additional extensions; add them.
+                *
+                * First, split the extension-list string into a set of
+                * extensions.
+                */
+               extensions_set = g_strsplit(dump_open_table[filetype].additional_file_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);
+       }
+       g_slist_free(compressed_file_extensions);
+       return extensions;
+}
+
+/*
+ * Free a list returned by wtap_file_extensions_list().
+ */
+void wtap_free_file_extensions_list(GSList *extensions)
+{
+       GSList *extension;
+
+       for (extension = extensions; extension != NULL;
+           extension = g_slist_next(extension)) {
+               g_free(extension->data);
+       }
+       g_slist_free(extensions);
 }
 
-/* default file extension to use. */
-const char *wtap_file_extension_default_string(int filetype)
+/* Return the default file extension to use with the specified file type;
+   that's just the extension, without any ".". */
+const char *wtap_default_file_extension(int filetype)
 {
        if (filetype < 0 || filetype >= wtap_num_file_types)
                return NULL;
        else
-               return dump_open_table[filetype].file_extension_default;
+               return dump_open_table[filetype].default_file_extension;
 }
 
 gboolean wtap_dump_can_open(int filetype)
@@ -792,6 +975,12 @@ static int wtap_dump_file_close(wtap_dumper *wdh);
 
 wtap_dumper* wtap_dump_open(const char *filename, int filetype, int encap,
                                int snaplen, gboolean compressed, int *err)
+{
+       return wtap_dump_open_ng(filename, filetype, encap,snaplen, compressed, NULL, NULL, err);
+}
+
+wtap_dumper* wtap_dump_open_ng(const char *filename, int filetype, int encap,
+                               int snaplen, gboolean compressed, wtapng_section_t *shb_hdr, wtapng_iface_descriptions_t *idb_inf, int *err)
 {
        wtap_dumper *wdh;
        WFILE_T fh;
@@ -806,6 +995,33 @@ wtap_dumper* wtap_dump_open(const char *filename, int filetype, int encap,
        if (wdh == NULL)
                return NULL;    /* couldn't allocate it */
 
+       /* Set Section Header Block data */
+       wdh->shb_hdr = shb_hdr;
+       /* Set Interface Description Block data */
+       if ((idb_inf != NULL) && (idb_inf->number_of_interfaces > 0)) {
+               wdh->number_of_interfaces = idb_inf->number_of_interfaces;
+               wdh->interface_data = idb_inf->interface_data;
+               g_free(idb_inf);
+       } else {
+               wtapng_if_descr_t descr;
+
+               descr.wtap_encap = encap;
+               descr.time_units_per_second = 0;
+               descr.link_type = wtap_wtap_encap_to_pcap_encap(encap);
+               descr.snap_len = snaplen;
+               descr.opt_comment = NULL;
+               descr.if_name = NULL;
+               descr.if_description = NULL;
+               descr.if_speed = 0;
+               descr.if_tsresol = 6;
+               descr.if_filter= NULL;
+               descr.if_os = NULL;
+               descr.if_fcslen = -1;
+               wdh->number_of_interfaces= 1;
+               wdh->interface_data= g_array_new(FALSE, FALSE, sizeof(wtapng_if_descr_t));
+               g_array_append_val(wdh->interface_data, descr);
+       }
+
        /* "-" means stdout */
        if (strcmp(filename, "-") == 0) {
                if (compressed) {
@@ -975,7 +1191,7 @@ static gboolean wtap_dump_open_finish(wtap_dumper *wdh, int filetype, gboolean c
 }
 
 gboolean wtap_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
-                  const union wtap_pseudo_header *pseudo_header, const guchar *pd, int *err)
+                  const union wtap_pseudo_header *pseudo_header, const guint8 *pd, int *err)
 {
        return (wdh->subtype_write)(wdh, phdr, pseudo_header, pd, err);
 }