parseoffset.c - sbase - suckless unix tools | |
git clone git://git.suckless.org/sbase | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
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"… | |
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 } |