Treat "-" as "standard input" in the CLI, not in libwiretap.
authorGuy Harris <guy@alum.mit.edu>
Tue, 10 Nov 2015 01:21:46 +0000 (17:21 -0800)
committerGuy Harris <guy@alum.mit.edu>
Tue, 10 Nov 2015 01:23:22 +0000 (01:23 +0000)
That's a UI convention, and the GUI shouldn't honor that convention - a
user might get confused if they try to save to "-" and end up with
nothing (and with a ton of crap in a log file if programs launched from
the GUI end up with their standard output and error logged).

While we're at it, make randcap report write and close errors.

Change-Id: I9c450f0ca0320ce4c36d13d209b56d72edb43012
Reviewed-on: https://code.wireshark.org/review/11666
Reviewed-by: Guy Harris <guy@alum.mit.edu>
editcap.c
randpkt.c
reordercap.c
tshark.c
wiretap/file_access.c

index 8f69671cb152e10c0aea4ecf9dcc1193be9652d8..c2522c59a8fce0ba34ebca22f1c04b506bce299a 100644 (file)
--- a/editcap.c
+++ b/editcap.c
@@ -888,6 +888,29 @@ get_editcap_runtime_info(GString *str)
 #endif
 }
 
+static wtap_dumper *
+editcap_dump_open(const char *filename, guint32 snaplen,
+                  wtapng_section_t *shb_hdr,
+                  wtapng_iface_descriptions_t *idb_inf,
+                  wtapng_name_res_t *nrb_hdr, int *write_err)
+{
+  wtap_dumper *pdh;
+
+  if (strcmp(filename, "-") == 0) {
+    /* Write to the standard output. */
+    pdh = wtap_dump_fdopen_ng(1, out_file_type_subtype, out_frame_type,
+                              snaplen, FALSE /* compressed */,
+                              shb_hdr, idb_inf, nrb_hdr,
+                              write_err);
+  } else {
+    pdh = wtap_dump_open_ng(filename, out_file_type_subtype, out_frame_type,
+                            snaplen, FALSE /* compressed */,
+                            shb_hdr, idb_inf, nrb_hdr,
+                           write_err);
+  }
+  return pdh;
+}
+
 int
 main(int argc, char *argv[])
 {
@@ -1334,9 +1357,9 @@ DIAG_ON(cast-qual)
                     shb_hdr->shb_user_appl = g_strdup("Editcap " VERSION);
                 }
 
-                pdh = wtap_dump_open_ng(filename, out_file_type_subtype, out_frame_type,
+                pdh = editcap_dump_open(filename,
                                         snaplen ? MIN(snaplen, wtap_snapshot_length(wth)) : wtap_snapshot_length(wth),
-                                        FALSE /* compressed */, shb_hdr, idb_inf, nrb_hdr, &write_err);
+                                        shb_hdr, idb_inf, nrb_hdr, &write_err);
 
                 if (pdh == NULL) {
                     fprintf(stderr, "editcap: Can't open or create %s: %s\n",
@@ -1376,9 +1399,9 @@ DIAG_ON(cast-qual)
                         if (verbose)
                             fprintf(stderr, "Continuing writing in file %s\n", filename);
 
-                        pdh = wtap_dump_open_ng(filename, out_file_type_subtype, out_frame_type,
+                        pdh = editcap_dump_open(filename,
                                                 snaplen ? MIN(snaplen, wtap_snapshot_length(wth)) : wtap_snapshot_length(wth),
-                                                FALSE /* compressed */, shb_hdr, idb_inf, nrb_hdr, &write_err);
+                                                shb_hdr, idb_inf, nrb_hdr, &write_err);
 
                         if (pdh == NULL) {
                             fprintf(stderr, "editcap: Can't open or create %s: %s\n",
@@ -1405,9 +1428,9 @@ DIAG_ON(cast-qual)
                     if (verbose)
                         fprintf(stderr, "Continuing writing in file %s\n", filename);
 
-                    pdh = wtap_dump_open_ng(filename, out_file_type_subtype, out_frame_type,
+                    pdh = editcap_dump_open(filename,
                                             snaplen ? MIN(snaplen, wtap_snapshot_length(wth)) : wtap_snapshot_length(wth),
-                                            FALSE /* compressed */, shb_hdr, idb_inf, nrb_hdr, &write_err);
+                                            shb_hdr, idb_inf, nrb_hdr, &write_err);
                     if (pdh == NULL) {
                         fprintf(stderr, "editcap: Can't open or create %s: %s\n",
                                 filename, wtap_strerror(write_err));
@@ -1776,9 +1799,9 @@ DIAG_ON(cast-qual)
             g_free (filename);
             filename = g_strdup(argv[optind+1]);
 
-            pdh = wtap_dump_open_ng(filename, out_file_type_subtype, out_frame_type,
+            pdh = editcap_dump_open(filename,
                                     snaplen ? MIN(snaplen, wtap_snapshot_length(wth)): wtap_snapshot_length(wth),
-                                    FALSE /* compressed */, shb_hdr, idb_inf, nrb_hdr, &write_err);
+                                    shb_hdr, idb_inf, nrb_hdr, &write_err);
             if (pdh == NULL) {
                 fprintf(stderr, "editcap: Can't open or create %s: %s\n",
                         filename, wtap_strerror(write_err));
index 82d2a9a26dcf0eb4c115cb6f60b26ea084423e3e..b5db8407f3e4df0379e1613d20164c662d88ed39 100644 (file)
--- a/randpkt.c
+++ b/randpkt.c
@@ -84,6 +84,7 @@ typedef struct {
        guint8*      pseudo_buffer;
        guint        pseudo_length;
        wtap_dumper* dump;
+       const char*  filename;
        guint        produce_max_bytes;
 
 } randpkt_example;
@@ -374,154 +375,176 @@ randpkt_example examples[] = {
                PKT_ARP,        WTAP_ENCAP_ETHERNET,
                pkt_arp,        array_length(pkt_arp),
                NULL,           0,
-               NULL,           1000,
+               NULL,           NULL,
+               1000,
        },
 
        { "bgp", "Border Gateway Protocol",
                PKT_BGP,        WTAP_ENCAP_ETHERNET,
                pkt_bgp,        array_length(pkt_bgp),
                NULL,           0,
-               NULL,           1000,
+               NULL,           NULL,
+               1000,
        },
 
        { "bvlc", "BACnet Virtual Link Control",
                PKT_BVLC,       WTAP_ENCAP_ETHERNET,
                pkt_bvlc,       array_length(pkt_bvlc),
                NULL,           0,
-               NULL,           1000,
+               NULL,           NULL,
+               1000,
        },
 
        { "dns", "Domain Name Service",
                PKT_DNS,        WTAP_ENCAP_ETHERNET,
                pkt_dns,        array_length(pkt_dns),
                NULL,           0,
-               NULL,           1000,
+               NULL,           NULL,
+               1000,
        },
 
        { "eth", "Ethernet",
                PKT_ETHERNET,   WTAP_ENCAP_ETHERNET,
                NULL,           0,
                NULL,           0,
-               NULL,           1000,
+               NULL,           NULL,
+               1000,
        },
 
        { "fddi", "Fiber Distributed Data Interface",
                PKT_FDDI,       WTAP_ENCAP_FDDI,
                NULL,           0,
                NULL,           0,
-               NULL,           1000,
+               NULL,           NULL,
+               1000,
        },
 
        { "giop", "General Inter-ORB Protocol",
                PKT_GIOP,       WTAP_ENCAP_ETHERNET,
                pkt_giop,       array_length(pkt_giop),
                NULL,           0,
-               NULL,           1000,
+               NULL,           NULL,
+               1000,
        },
 
        { "icmp", "Internet Control Message Protocol",
                PKT_ICMP,       WTAP_ENCAP_ETHERNET,
                pkt_icmp,       array_length(pkt_icmp),
                NULL,           0,
-               NULL,           1000,
+               NULL,           NULL,
+               1000,
        },
 
        { "ip", "Internet Protocol",
                PKT_IP,         WTAP_ENCAP_ETHERNET,
                pkt_ip,         array_length(pkt_ip),
                NULL,           0,
-               NULL,           1000,
+               NULL,           NULL,
+               1000,
        },
 
        { "llc", "Logical Link Control",
                PKT_LLC,        WTAP_ENCAP_TOKEN_RING,
                pkt_llc,        array_length(pkt_llc),
                NULL,           0,
-               NULL,           1000,
+               NULL,           NULL,
+               1000,
        },
 
        { "m2m", "WiMAX M2M Encapsulation Protocol",
                PKT_M2M,        WTAP_ENCAP_ETHERNET,
                pkt_m2m,        array_length(pkt_m2m),
                NULL,           0,
-               NULL,           1000,
+               NULL,           NULL,
+               1000,
        },
 
        { "megaco", "MEGACO",
                PKT_MEGACO,     WTAP_ENCAP_ETHERNET,
                pkt_megaco,     array_length(pkt_megaco),
                NULL,           0,
-               NULL,           1000,
+               NULL,           NULL,
+               1000,
        },
 
        { "nbns", "NetBIOS-over-TCP Name Service",
                PKT_NBNS,       WTAP_ENCAP_ETHERNET,
                pkt_nbns,       array_length(pkt_nbns),
                NULL,           0,
-               NULL,           1000,
+               NULL,           NULL,
+               1000,
        },
 
        { "ncp2222", "NetWare Core Protocol",
                PKT_NCP2222,    WTAP_ENCAP_TOKEN_RING,
                pkt_ncp2222,    array_length(pkt_ncp2222),
                NULL,           0,
-               NULL,           1000,
+               NULL,           NULL,
+               1000,
        },
 
        { "sctp", "Stream Control Transmission Protocol",
                PKT_SCTP,       WTAP_ENCAP_ETHERNET,
                pkt_sctp,       array_length(pkt_sctp),
                NULL,           0,
-               NULL,           1000,
+               NULL,           NULL,
+               1000,
        },
 
        { "syslog", "Syslog message",
                PKT_SYSLOG,     WTAP_ENCAP_ETHERNET,
                pkt_syslog,     array_length(pkt_syslog),
                NULL,           0,
-               NULL,           1000,
+               NULL,           NULL,
+               1000,
        },
 
        { "tds", "TDS NetLib",
                PKT_TDS,        WTAP_ENCAP_ETHERNET,
                pkt_tds,        array_length(pkt_tds),
                NULL,           0,
-               NULL,           1000,
+               NULL,           NULL,
+               1000,
        },
 
        { "tcp", "Transmission Control Protocol",
                PKT_TCP,        WTAP_ENCAP_TOKEN_RING,
                pkt_tcp,        array_length(pkt_tcp),
                NULL,           0,
-               NULL,           1000,
+               NULL,           NULL,
+               1000,
        },
 
        { "tr",  "Token-Ring",
                PKT_TR,         WTAP_ENCAP_TOKEN_RING,
                NULL,           0,
                NULL,           0,
-               NULL,           1000,
+               NULL,           NULL,
+               1000,
        },
 
        { "udp", "User Datagram Protocol",
                PKT_UDP,        WTAP_ENCAP_ETHERNET,
                pkt_udp,        array_length(pkt_udp),
                NULL,           0,
-               NULL,           1000,
+               NULL,           NULL,
+               1000,
        },
 
        { "usb", "Universal Serial Bus",
                PKT_USB,        WTAP_ENCAP_USB,
                NULL,           0,
                NULL,           0,
-               NULL,           1000,
+               NULL,           NULL,
+               1000,
        },
 
        { "usb-linux", "Universal Serial Bus with Linux specific header",
                PKT_USB_LINUX,  WTAP_ENCAP_USB_LINUX,
                NULL,           0,
                NULL,           0,
-               NULL,           1000,
+               NULL,           NULL,
+               1000,
        },
 
 };
@@ -611,10 +634,18 @@ static void randpkt_example_init(randpkt_example* example, char* produce_filenam
 {
        int err;
 
-       example->dump = wtap_dump_open(produce_filename, WTAP_FILE_TYPE_SUBTYPE_PCAP,
-               example->sample_wtap_encap, produce_max_bytes, FALSE /* compressed */, &err);
+       if (strcmp(produce_filename, "-") == 0) {
+               /* Write to the standard output. */
+               example->dump = wtap_dump_fdopen(1, WTAP_FILE_TYPE_SUBTYPE_PCAP,
+                       example->sample_wtap_encap, produce_max_bytes, FALSE /* compressed */, &err);
+               example->filename = "the standard output";
+       } else {
+               example->dump = wtap_dump_open(produce_filename, WTAP_FILE_TYPE_SUBTYPE_PCAP,
+                       example->sample_wtap_encap, produce_max_bytes, FALSE /* compressed */, &err);
+               example->filename = produce_filename;
+       }
        if (!example->dump) {
-               fprintf(stderr, "randpkt: Error writing to %s\n", produce_filename);
+               fprintf(stderr, "randpkt: Error writing to %s\n", example->filename);
                exit(2);
        }
 
@@ -629,10 +660,16 @@ static void randpkt_example_init(randpkt_example* example, char* produce_filenam
        }
 }
 
-static void randpkt_example_close(randpkt_example* example)
+static gboolean randpkt_example_close(randpkt_example* example)
 {
        int err;
-       wtap_dump_close(example->dump, &err);
+
+       if (!wtap_dump_close(example->dump, &err)) {
+               fprintf(stderr, "Error writing to %s: %s\n",
+                   example->filename, wtap_strerror(err));
+               return FALSE;
+        }
+        return TRUE;
 }
 
 static void randpkt_loop(randpkt_example* example, guint64 produce_count)
@@ -695,10 +732,64 @@ static void randpkt_loop(randpkt_example* example, guint64 produce_count)
                        }
                }
 
-               /* XXX - report errors! */
                if (!wtap_dump(example->dump, pkthdr, buffer, &err, &err_info)) {
-                       if (err_info != NULL)
+                       fprintf(stderr, "randpkt: Error writing to %s: %s\n",
+                           example->filename, wtap_strerror(err));
+                       switch (err) {
+
+                       case WTAP_ERR_UNWRITABLE_ENCAP:
+                               /*
+                                * This is a problem with the particular
+                                * frame we're writing and the file type
+                                * and subtype we're writing; note that,
+                                * and report the file type/subtype.
+                                */
+                               fprintf(stderr,
+                                   "Frame has a network type that can't be saved in a \"%s\" file.\n",
+                                   wtap_file_type_subtype_short_string(WTAP_FILE_TYPE_SUBTYPE_PCAP));
+                               break;
+
+                       case WTAP_ERR_PACKET_TOO_LARGE:
+                               /*
+                                * This is a problem with the particular
+                                * frame we're writing and the file type
+                                * and subtype we're writing; note that,
+                                * and report the file type/subtype.
+                                */
+                               fprintf(stderr,
+                                   "Frame is too large for a \"%s\" file.\n",
+                                   wtap_file_type_subtype_short_string(WTAP_FILE_TYPE_SUBTYPE_PCAP));
+                               break;
+
+                       case WTAP_ERR_UNWRITABLE_REC_TYPE:
+                               /*
+                                * This is a problem with the particular
+                                * record we're writing and the file type
+                                * and subtype we're writing; note that,
+                                * and report the file type/subtype.
+                                */
+                               fprintf(stderr,
+                                   "Record has a record type that can't be saved in a \"%s\" file.\n",
+                                   wtap_file_type_subtype_short_string(WTAP_FILE_TYPE_SUBTYPE_PCAP));
+                               break;
+
+                       case WTAP_ERR_UNWRITABLE_REC_DATA:
+                               /*
+                                * This is a problem with the particular
+                                * record we're writing and the file type
+                                * and subtype we're writing; note that,
+                                * and report the file type/subtype.
+                                */
+                               fprintf(stderr,
+                                   "Record has data that can't be saved in a \"%s\" file.\n(%s)\n",
+                                   wtap_file_type_subtype_short_string(WTAP_FILE_TYPE_SUBTYPE_PCAP),
+                                   err_info != NULL ? err_info : "no information supplied");
                                g_free(err_info);
+                               break;
+
+                       default:
+                               break;
+                       }
                }
        }
 
@@ -708,12 +799,12 @@ static void randpkt_loop(randpkt_example* example, guint64 produce_count)
 int
 main(int argc, char **argv)
 {
-       int                             opt;
-       int                             produce_type = -1;
+       int                     opt;
+       int                     produce_type = -1;
        char                    *produce_filename = NULL;
-       int                             produce_max_bytes = 5000;
-       int                             produce_count = 1000;
-       randpkt_example *example;
+       int                     produce_max_bytes = 5000;
+       int                     produce_count = 1000;
+       randpkt_example         *example;
        guint8*                 type = NULL;
        int                     allrandom = FALSE;
        wtap_dumper             *savedump;
@@ -781,7 +872,6 @@ DIAG_ON(cast-qual)
 
                randpkt_example_init(example, produce_filename, produce_max_bytes);
                randpkt_loop(example, produce_count);
-               randpkt_example_close(example);
        } else {
                if (type) {
                        fprintf(stderr, "Can't set type in random mode\n");
@@ -805,8 +895,9 @@ DIAG_ON(cast-qual)
                                return 1;
                        example->dump = savedump;
                }
-               randpkt_example_close(example);
        }
+       if (!randpkt_example_close(example))
+               return 2;
        return 0;
 
 }
index 9939f26987e7269d83d801e6e56aeaaf15b768c7..efbbfdaf3632788c8905812e5a19b5d9d078c34d 100644 (file)
@@ -204,7 +204,7 @@ DIAG_OFF(cast-qual)
 DIAG_ON(cast-qual)
     int file_count;
     char *infile;
-    char *outfile;
+    const char *outfile;
 
     /* Get the compile-time version information string */
     comp_info_str = get_compiled_version_info(NULL, get_reordercap_compiled_info);
@@ -275,8 +275,14 @@ DIAG_ON(cast-qual)
     nrb_hdr = wtap_file_get_nrb_for_new_file(wth);
 
     /* Open outfile (same filetype/encap as input file) */
-    pdh = wtap_dump_open_ng(outfile, wtap_file_type_subtype(wth), wtap_file_encap(wth),
-                            65535, FALSE, shb_hdr, idb_inf, nrb_hdr, &err);
+    if (strcmp(outfile, "-") == 0) {
+      pdh = wtap_dump_fdopen_ng(1, wtap_file_type_subtype(wth), wtap_file_encap(wth),
+                                65535, FALSE, shb_hdr, idb_inf, nrb_hdr, &err);
+      outfile = "standard output";
+    } else {
+      pdh = wtap_dump_open_ng(outfile, wtap_file_type_subtype(wth), wtap_file_encap(wth),
+                              65535, FALSE, shb_hdr, idb_inf, nrb_hdr, &err);
+    }
     g_free(idb_inf);
     idb_inf = NULL;
 
index 8d3d3052bff453e85bc2cbff2292d79a19412215..a43417b63e575c8e6a3437ace3341ad7e96976e7 100644 (file)
--- a/tshark.c
+++ b/tshark.c
@@ -3199,13 +3199,25 @@ load_cap_file(capture_file *cf, char *save_file, int out_file_type,
     if (linktype != WTAP_ENCAP_PER_PACKET &&
         out_file_type == WTAP_FILE_TYPE_SUBTYPE_PCAP) {
         tshark_debug("tshark: writing PCAP format to %s", save_file);
-        pdh = wtap_dump_open(save_file, out_file_type, linktype,
-            snapshot_length, FALSE /* compressed */, &err);
+        if (strcmp(save_file, "-")) {
+          /* Write to the standard output. */
+          pdh = wtap_dump_fdopen(1, out_file_type, linktype,
+              snapshot_length, FALSE /* compressed */, &err);
+        } else {
+          pdh = wtap_dump_open(save_file, out_file_type, linktype,
+              snapshot_length, FALSE /* compressed */, &err);
+        }
     }
     else {
         tshark_debug("tshark: writing format type %d, to %s", out_file_type, save_file);
-        pdh = wtap_dump_open_ng(save_file, out_file_type, linktype,
-            snapshot_length, FALSE /* compressed */, shb_hdr, idb_inf, nrb_hdr, &err);
+        if (strcmp(save_file, "-")) {
+          /* Write to the standard output. */
+          pdh = wtap_dump_fdopen_ng(1, out_file_type, linktype,
+              snapshot_length, FALSE /* compressed */, shb_hdr, idb_inf, nrb_hdr, &err);
+        } else {
+          pdh = wtap_dump_open_ng(save_file, out_file_type, linktype,
+              snapshot_length, FALSE /* compressed */, shb_hdr, idb_inf, nrb_hdr, &err);
+        }
     }
 
     g_free(idb_inf);
index 15e5940ac75f9cf73a1c23e93e6c49f7d4fbf32e..c667118408cca51726b3a7e57f319aabcadeacb6 100644 (file)
@@ -2217,34 +2217,16 @@ wtap_dump_open_ng(const char *filename, int file_type_subtype, int encap,
        if (wdh == NULL)
                return NULL;
 
-       /* "-" means stdout */
-       if (strcmp(filename, "-") == 0) {
-               if (compressed) {
-                       *err = EINVAL;  /* XXX - return a Wiretap error code for this */
-                       g_free(wdh);
-                       return NULL;    /* compress won't work on stdout */
-               }
-#ifdef _WIN32
-               if (_setmode(fileno(stdout), O_BINARY) == -1) {
-                       /* "Should not happen" */
-                       *err = errno;
-                       g_free(wdh);
-                       return NULL;    /* couldn't put standard output in binary mode */
-               }
-#endif
-               wdh->fh = stdout;
-       } else {
-               /* In case "fopen()" fails but doesn't set "errno", set "errno"
-                  to a generic "the open failed" error. */
-               errno = WTAP_ERR_CANT_OPEN;
-               fh = wtap_dump_file_open(wdh, filename);
-               if (fh == NULL) {
-                       *err = errno;
-                       g_free(wdh);
-                       return NULL;    /* can't create file */
-               }
-               wdh->fh = fh;
+       /* In case "fopen()" fails but doesn't set "errno", set "errno"
+          to a generic "the open failed" error. */
+       errno = WTAP_ERR_CANT_OPEN;
+       fh = wtap_dump_file_open(wdh, filename);
+       if (fh == NULL) {
+               *err = errno;
+               g_free(wdh);
+               return NULL;    /* can't create file */
        }
+       wdh->fh = fh;
 
        if (!wtap_dump_open_finish(wdh, file_type_subtype, compressed, err)) {
                /* Get rid of the file we created; we couldn't finish