+unsigned long parse_size_arg(char *arg, char *arg_name)
+{
+ char *tail, *power_name;
+ unsigned long power, res;
+
+ res = strtoul(arg, &tail, 0);
+
+ if (arg == tail) {
+ lose("%s argument is not a number: %s", arg_name, arg);
+ } else if (tail[0]) {
+ int i, size;
+ power_name = copied_string(tail);
+ size = strlen(power_name);
+ for (i=0; i<size; i++)
+ power_name[i] = toupper(power_name[i]);
+ } else {
+ power = 20;
+ power_name = NULL;
+ }
+ if (power_name) {
+ if ((0==strcmp("KB", power_name)) ||
+ (0==strcmp("KIB", power_name))) {
+ power = 10;
+ } else if ((0==strcmp("MB", power_name)) ||
+ (0==strcmp("MIB", power_name))) {
+ power = 20;
+ } else if ((0==strcmp("GB", power_name)) ||
+ (0==strcmp("GIB", power_name))) {
+ power = 30;
+ } else {
+ lose("%s argument has an unknown suffix: %s", arg_name, tail);
+ }
+ free(power_name);
+ }
+ if ((res <= 0) ||
+ (res > (ULONG_MAX >> power))) {
+ lose("%s argument is out of range: %s", arg_name, arg);
+ }
+ res <<= power;
+ return res;
+}
+