]> The Tcpdump Group git mirrors - tcpdump/commitdiff
Improve the handling of size suffixes for -C.
authorGuy Harris <[email protected]>
Sat, 10 Jul 2021 21:01:18 +0000 (14:01 -0700)
committerfxlb <[email protected]>
Fri, 28 Mar 2025 14:44:07 +0000 (14:44 +0000)
Support upper-case suffixes (K/M/G) as well as lower-case suffixes.

Make sure nothing *follows* the suffix.

We don't need to check for the suffix before parsing the number; the
parsing routines stop if they see a non-digit character.

(cherry picked from commit 5ff873f0d277e10ad9deffa92b00b38cbfef4914)

tcpdump.1.in
tcpdump.c

index 82983e63b84127eb2c579e45ecb22dee9488f058..1a32945f71fae78eaa4e54b237bfea87ac421cf7 100644 (file)
@@ -274,7 +274,7 @@ flag, with a number after it, starting at 1 and continuing upward.
 The default unit of \fIfile_size\fP is millions of bytes (1,000,000 bytes,
 not 1,048,576 bytes).
 .IP
-By adding a suffix of k, m or g to the value, the unit
+By adding a suffix of k/K, m/M or g/G to the value, the unit
 can be changed to 1,024 (KiB), 1,048,576 (MiB), or 1,073,741,824 (GiB)
 respectively.
 .TP
index 17f6487039464e0808e90ea3e77a43b493981635..3e69e207623db7c0b3ccbc88e56195fffdd77156 100644 (file)
--- a/tcpdump.c
+++ b/tcpdump.c
@@ -1522,7 +1522,7 @@ main(int argc, char **argv)
        int yflag_dlt = -1;
        const char *yflag_dlt_name = NULL;
        int print = 0;
-       long Cflagmult = 1000000;
+       long Cflagmult;
 
        netdissect_options Ndo;
        netdissect_options *ndo = &Ndo;
@@ -1757,26 +1757,72 @@ main(int argc, char **argv)
 
                case 'C':
                        errno = 0;
-                       if (optarg[strlen(optarg)-1] == 'k') {
-                               Cflagmult = 1024;
-                               optarg[strlen(optarg)-1] = '\0';
-                       }
-                       if (optarg[strlen(optarg)-1] == 'm') {
-                               Cflagmult = 1024*1024;
-                               optarg[strlen(optarg)-1] = '\0';
-                       }
-                       if (optarg[strlen(optarg)-1] == 'g') {
-                               Cflagmult = 1024*1024*1024;
-                               optarg[strlen(optarg)-1] = '\0';
-                       }
 #ifdef HAVE_PCAP_DUMP_FTELL64
                        Cflag = strtoint64_t(optarg, &endp, 10);
 #else
                        Cflag = strtol(optarg, &endp, 10);
 #endif
-                       if (endp == optarg || *endp != '\0' || errno != 0
-                           || Cflag <= 0)
+                       if (endp == optarg || errno != 0 || Cflag <= 0)
                                error("invalid file size %s", optarg);
+
+                       if (*endp == '\0') {
+                               /*
+                                * There's nothing after the file size,
+                                * so the size is in units of 1 MB
+                                * (1,000,000 bytes).
+                                */
+                               Cflagmult = 1000000;
+                       } else {
+                               /*
+                                * There's something after the file
+                                * size.
+                                *
+                                * If it's a single letter, then:
+                                *
+                                *   if the letter is k or K, the size
+                                *   is in units of 1 KiB (1024 bytes);
+                                *
+                                *   if the letter is m or M, the size
+                                *   is in units of 1 MiB (1,048,576 bytes);
+                                *
+                                *   if the letter is g or G, the size
+                                *   is in units of 1 GiB (1,073,741,824 bytes).
+                                *
+                                * Otherwise, it's an error.
+                                */
+                               switch (*endp) {
+
+                               case 'k':
+                               case 'K':
+                                       Cflagmult = 1024;
+                                       break;
+
+                               case 'm':
+                               case 'M':
+                                       Cflagmult = 1024*1024;
+                                       break;
+
+                               case 'g':
+                               case 'G':
+                                       Cflagmult = 1024*1024*1024;
+                                       break;
+
+                               default:
+                                       error("invalid file size %s", optarg);
+                               }
+
+                               /*
+                                * OK, there was a letter that we treat
+                                * as a units indication; was there
+                                * anything after it?
+                                */
+                               endp++;
+                               if (*endp != '\0') {
+                                       /* Yes - error */
+                                       error("invalid file size %s", optarg);
+                               }
+                       }
+
                        /*
                         * Will multiplying it by multiplier overflow?
                         */