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", 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 }