parseoffset.c (1148B)
1 /* See LICENSE file for copyright and license details. */ 2 #include <ctype.h> 3 #include <errno.h> 4 #include <inttypes.h> 5 #include <stdlib.h> 6 #include <string.h> 7 8 #include "../util.h" 9 10 off_t 11 parseoffset(const char *str) 12 { 13 off_t res, scale = 1; 14 char *end; 15 16 /* strictly check what strtol() usually would let pass */ 17 if (!str || !*str || isspace(*str) || *str == '+' || *str == '-') { 18 weprintf("parseoffset %s: invalid value\n", str); 19 return -1; 20 } 21 22 errno = 0; 23 res = strtol(str, &end, 0); 24 if (errno) { 25 weprintf("parseoffset %s: invalid value\n", str); 26 return -1; 27 } 28 if (res < 0) { 29 weprintf("parseoffset %s: negative value\n", str); 30 return -1; 31 } 32 33 /* suffix */ 34 if (*end) { 35 switch (toupper((int)*end)) { 36 case 'B': 37 scale = 512L; 38 break; 39 case 'K': 40 scale = 1024L; 41 break; 42 case 'M': 43 scale = 1024L * 1024L; 44 break; 45 case 'G': 46 scale = 1024L * 1024L * 1024L; 47 break; 48 default: 49 weprintf("parseoffset %s: invalid suffix '%s'\n", str, end); 50 return -1; 51 } 52 } 53 54 /* prevent overflow */ 55 if (res > (SSIZE_MAX / scale)) { 56 weprintf("parseoffset %s: out of range\n", str); 57 return -1; 58 } 59 60 return res * scale; 61 }