From b5eae55c8bd4d089b55ee1c20b944cabd94e78f4 Mon Sep 17 00:00:00 2001 From: Jaromil Date: Wed, 21 Dec 2022 10:08:33 +0100 Subject: [PATCH] portable: remove strtosize and use MiB --- portable/GNUmakefile | 3 +- portable/strtosize.c | 214 --------------------------- portable/test/create_open_close.bats | 2 +- portable/tomb | 25 ++-- 4 files changed, 15 insertions(+), 229 deletions(-) delete mode 100644 portable/strtosize.c diff --git a/portable/GNUmakefile b/portable/GNUmakefile index ddf64b9..8f0e8b7 100644 --- a/portable/GNUmakefile +++ b/portable/GNUmakefile @@ -8,8 +8,7 @@ TOMB ?= test.tomb ######### ## BUILD ######### -all: - ${CC} -O2 -Wall -Wextra --std=c99 --pedantic -o tomb-str2size strtosize.c +test: create-open-close check-random-data ######## ## TEST diff --git a/portable/strtosize.c b/portable/strtosize.c deleted file mode 100644 index e9b5087..0000000 --- a/portable/strtosize.c +++ /dev/null @@ -1,214 +0,0 @@ -/* strtosize from util-linux */ - -/* No copyright is claimed. This code is in the public domain. */ - -#include -#include -#include -#include -#include -#include - -static int do_scale_by_power (uintmax_t *x, int base, int power) -{ - while (power--) { - if (UINTMAX_MAX / base < *x) - return -ERANGE; - *x *= base; - } - return 0; -} - -/* - * strtosize() - convert string to size (uintmax_t). - * - * Supported suffixes: - * - * XiB or X for 2^N - * where X = {K,M,G,T,P,E,Z,Y} - * or X = {k,m,g,t,p,e} (undocumented for backward compatibility only) - * for example: - * 10KiB = 10240 - * 10K = 10240 - * - * XB for 10^N - * where X = {K,M,G,T,P,E,Z,Y} - * for example: - * 10KB = 10000 - * - * The optional 'power' variable returns number associated with used suffix - * {K,M,G,T,P,E,Z,Y} = {1,2,3,4,5,6,7,8}. - * - * The function also supports decimal point, for example: - * 0.5MB = 500000 - * 0.5MiB = 512000 - * - * Note that the function does not accept numbers with '-' (negative sign) - * prefix. - */ -int strtosize(const char *str, uintmax_t *res, int *power) -{ - const char *p; - char *end; - uintmax_t x, frac = 0; - int base = 1024, rc = 0, pwr = 0, frac_zeros = 0; - - static const char *suf = "KMGTPEZY"; - static const char *suf2 = "kmgtpezy"; - const char *sp; - - *res = 0; - - if (!str || !*str) { - rc = -EINVAL; - goto err; - } - - /* Only positive numbers are acceptable - * - * Note that this check is not perfect, it would be better to - * use lconv->negative_sign. But coreutils use the same solution, - * so it's probably good enough... - */ - p = str; - while (isspace((unsigned char) *p)) - p++; - if (*p == '-') { - rc = -EINVAL; - goto err; - } - - errno = 0, end = NULL; - x = strtoumax(str, &end, 0); - - if (end == str || - (errno != 0 && (x == UINTMAX_MAX || x == 0))) { - rc = errno ? -errno : -EINVAL; - goto err; - } - if (!end || !*end) - goto done; /* without suffix */ - p = end; - - /* - * Check size suffixes - */ -check_suffix: - if (*(p + 1) == 'i' && (*(p + 2) == 'B' || *(p + 2) == 'b') && !*(p + 3)) - base = 1024; /* XiB, 2^N */ - else if ((*(p + 1) == 'B' || *(p + 1) == 'b') && !*(p + 2)) - base = 1000; /* XB, 10^N */ - else if (*(p + 1)) { - struct lconv const *l = localeconv(); - const char *dp = l ? l->decimal_point : NULL; - size_t dpsz = dp ? strlen(dp) : 0; - - if (frac == 0 && *p && dp && strncmp(dp, p, dpsz) == 0) { - const char *fstr = p + dpsz; - - for (p = fstr; *p == '0'; p++) - frac_zeros++; - fstr = p; - if (isdigit(*fstr)) { - errno = 0, end = NULL; - frac = strtoumax(fstr, &end, 0); - if (end == fstr || - (errno != 0 && (frac == UINTMAX_MAX || frac == 0))) { - rc = errno ? -errno : -EINVAL; - goto err; - } - } else - end = (char *) p; - - if (frac && (!end || !*end)) { - rc = -EINVAL; - goto err; /* without suffix, but with frac */ - } - p = end; - goto check_suffix; - } - rc = -EINVAL; - goto err; /* unexpected suffix */ - } - - sp = strchr(suf, *p); - if (sp) - pwr = (sp - suf) + 1; - else { - sp = strchr(suf2, *p); - if (sp) - pwr = (sp - suf2) + 1; - else { - rc = -EINVAL; - goto err; - } - } - - rc = do_scale_by_power(&x, base, pwr); - if (power) - *power = pwr; - if (frac && pwr) { - int i; - uintmax_t frac_div = 10, frac_poz = 1, frac_base = 1; - - /* mega, giga, ... */ - do_scale_by_power(&frac_base, base, pwr); - - /* maximal divisor for last digit (e.g. for 0.05 is - * frac_div=100, for 0.054 is frac_div=1000, etc.) - * - * Reduce frac if too large. - */ - while (frac_div < frac) { - if (frac_div <= UINTMAX_MAX/10) - frac_div *= 10; - else - frac /= 10; - } - - /* 'frac' is without zeros (5 means 0.5 as well as 0.05) */ - for (i = 0; i < frac_zeros; i++) { - if (frac_div <= UINTMAX_MAX/10) - frac_div *= 10; - else - frac /= 10; - } - - /* - * Go backwardly from last digit and add to result what the - * digit represents in the frac_base. For example 0.25G - * - * 5 means 1GiB / (100/5) - * 2 means 1GiB / (10/2) - */ - do { - unsigned int seg = frac % 10; /* last digit of the frac */ - uintmax_t seg_div = frac_div / frac_poz; /* what represents the segment 1000, 100, .. */ - - frac /= 10; /* remove last digit from frac */ - frac_poz *= 10; - - if (seg && seg_div / seg) - x += frac_base / (seg_div / seg); - } while (frac); - } -done: - *res = x; -err: - if (rc < 0) - errno = -rc; - return rc; -} - -int main(int argc, char **argv) { - // TODO: secure check args - uint64_t size; - if(argc!=2) return(1); - int res = strtosize(argv[1], &size, NULL); - if(res==0) { - fprintf(stdout,"%lu\n",size); - } else { - fprintf(stderr,"%s\n",strerror(errno)); - } - return(res); -} diff --git a/portable/test/create_open_close.bats b/portable/test/create_open_close.bats index 42d45cd..e1926be 100644 --- a/portable/test/create_open_close.bats +++ b/portable/test/create_open_close.bats @@ -3,7 +3,7 @@ load bats_setup @test "Dig tomb" { rm -f "$TOMB" >&3 echo "$TOMB" - ./tomb dig -s 20MiB "$TOMB" + ./tomb dig -s 20 "$TOMB" } @test "Forge key" { diff --git a/portable/tomb b/portable/tomb index 87a3b7b..27fddbc 100755 --- a/portable/tomb +++ b/portable/tomb @@ -167,14 +167,14 @@ linux_mount() { # usage: echo PASSWORD | posix_create file size pim posix_create() { file="$1" # must not exist - size="$2" # veracrypt format (accepts M or G) + size="$2" # size in bytes pim="$3" # any number _verbose "posix_create $file $size $pim" veracrypt --text --non-interactive --stdin \ -m nokernelcrypto \ -c "$file" --volume-type normal \ --hash sha512 --encryption serpent-aes \ - --filesystem none --size "$size" --pim "$pim" \ + --filesystem none --size "${size}" --pim "$pim" \ --random-source /dev/urandom -k '' return $? } @@ -274,20 +274,21 @@ case "$cmd" in _error "A tomb exists already. I'm not digging here:" ls -l "$tombfile"; exit 1 } - _message "Commanded to dig tomb " "$tombfile" " sized $tombsize" + _message "Commanded to dig tomb " "$tombfile" " sized $tombsize MiB" touch "$tombfile" || _failure "Error creating the tomb " "$tombfile" # dd if=/dev/urandom bs=1048576 count=$tombsize of="$tombfile" || { # _failure "Error creating the tomb " "$tombfile" # exit 1 # } + bytesize="$(( $tombsize * 1048576 ))" + [ "$bytesize" = "" ] && + _failure "Error reading tomb size " "$tombsize" if [ "$system" = "Linux" ]; then - fallocate -x -l "$tombsize" "$tombfile" || + fallocate -x -l "$bytesize" "$tombfile" || _failure "Error creating the tomb " "$tombfile" else - bytesize="`tomb-str2size $tombsize`" - [ "$bytesize" = "" ] && _failure "Error reading tomb size " "$tombsize" - dd if=/dev/zero of="$tombfile" count="$(( bytesize / 1048576))" bs=1048576 || - _failure "Error creating the tomb " "$tombfile of $tombsize" + dd if=/dev/zero of="$tombfile" count="$tombsize" bs=1048576 || + _failure "Error creating the tomb " "$tombfile of $tombsize MiB" fi ;; @@ -327,18 +328,18 @@ EOF done case "$system" in Linux) - tombsize=`stat "$tombfile" | awk '/Size:/ {print $2; exit}'` + bytesize=`stat "$tombfile" | awk '/Size:/ {print $2; exit}'` ;; *) - tombsize=`stat -f '%z' "$tombfile"` + bytesize=`stat -f '%z' "$tombfile"` ;; esac - _message "Commanded to lock tomb " "$tombfile of $tombsize with key $tombkey" + _message "Commanded to lock tomb " "$tombfile with key $tombkey" [ "$tombfile" = "" ] && _failure "Missing path to tomb" [ -r "$tombfile" ] || _failure "Tomb file not readable" [ "$tombkey" = "" ] && _failure "Missing path to key" [ -r "$tombkey" ] || _failure "Key file not readable" - "$create" "$tombfile" "$tombsize" "$PIM" < "$tombkey" || { + "$create" "$tombfile" "$bytesize" "$PIM" < "$tombkey" || { _failure "Error creating the tomb " "$tombfile" exit 1 }