Commit 78434152 authored by Milan Broz's avatar Milan Broz

Move string_to_size to userspace tools.

parent 5a8b045b
......@@ -490,68 +490,3 @@ ssize_t crypt_hex_to_bytes(const char *hex, char **result, int safe_alloc)
*result = bytes;
return i;
}
/*
* Device size string parsing, suffixes:
* s|S - 512 bytes sectors
* k |K |m |M |g |G |t |T - 1024 base
* kiB|KiB|miB|MiB|giB|GiB|tiB|TiB - 1024 base
* kb |KB |mM |MB |gB |GB |tB |TB - 1000 base
*/
int crypt_string_to_size(struct crypt_device *cd, const char *s, uint64_t *size)
{
char *endp = NULL;
size_t len;
uint64_t mult_base, mult, tmp;
*size = strtoull(s, &endp, 10);
if (!isdigit(s[0]) ||
(errno == ERANGE && *size == ULLONG_MAX) ||
(errno != 0 && *size == 0))
return -EINVAL;
if (!endp || !*endp)
return 0;
len = strlen(endp);
/* Allow "B" and "iB" suffixes */
if (len > 3 ||
(len == 3 && (endp[1] != 'i' || endp[2] != 'B')) ||
(len == 2 && endp[1] != 'B'))
return -EINVAL;
if (len == 1 || len == 3)
mult_base = 1024;
else
mult_base = 1000;
mult = 1;
switch (endp[0]) {
case 's':
case 'S': mult = 512;
break;
case 't':
case 'T': mult *= mult_base;
/* Fall through */
case 'g':
case 'G': mult *= mult_base;
/* Fall through */
case 'm':
case 'M': mult *= mult_base;
/* Fall through */
case 'k':
case 'K': mult *= mult_base;
break;
default:
return -EINVAL;
}
tmp = *size * mult;
if ((tmp / *size) != mult) {
log_dbg("Device size overflow.");
return -EINVAL;
}
*size = tmp;
return 0;
}
......@@ -48,6 +48,5 @@ void *crypt_safe_realloc(void *data, size_t size);
void crypt_memzero(void *s, size_t n);
ssize_t crypt_hex_to_bytes(const char *hex, char **result, int safe_alloc);
int crypt_string_to_size(struct crypt_device *cd, const char *s, uint64_t *size);
#endif /* _UTILS_CRYPT_H */
......@@ -82,6 +82,7 @@ int tools_get_key(const char *prompt,
int timeout, int verify, int pwquality,
struct crypt_device *cd);
int tools_is_stdin(const char *key_file);
int tools_string_to_size(struct crypt_device *cd, const char *s, uint64_t *size);
/* Log */
#define log_dbg(x...) clogger(NULL, CRYPT_LOG_DEBUG, __FILE__, __LINE__, x)
......
......@@ -1371,12 +1371,12 @@ int main(int argc, const char **argv)
poptGetInvocationName(popt_context));
if (opt_device_size_str &&
crypt_string_to_size(NULL, opt_device_size_str, &opt_device_size))
tools_string_to_size(NULL, opt_device_size_str, &opt_device_size))
usage(popt_context, EXIT_FAILURE, _("Invalid device size specification."),
poptGetInvocationName(popt_context));
if (opt_reduce_size_str &&
crypt_string_to_size(NULL, opt_reduce_size_str, &opt_reduce_size))
tools_string_to_size(NULL, opt_reduce_size_str, &opt_reduce_size))
usage(popt_context, EXIT_FAILURE, _("Invalid device size specification."),
poptGetInvocationName(popt_context));
if (opt_reduce_size > 64 * 1024 * 1024)
......
......@@ -262,3 +262,68 @@ int translate_errno(int r)
}
return r;
}
/*
* Device size string parsing, suffixes:
* s|S - 512 bytes sectors
* k |K |m |M |g |G |t |T - 1024 base
* kiB|KiB|miB|MiB|giB|GiB|tiB|TiB - 1024 base
* kb |KB |mM |MB |gB |GB |tB |TB - 1000 base
*/
int tools_string_to_size(struct crypt_device *cd, const char *s, uint64_t *size)
{
char *endp = NULL;
size_t len;
uint64_t mult_base, mult, tmp;
*size = strtoull(s, &endp, 10);
if (!isdigit(s[0]) ||
(errno == ERANGE && *size == ULLONG_MAX) ||
(errno != 0 && *size == 0))
return -EINVAL;
if (!endp || !*endp)
return 0;
len = strlen(endp);
/* Allow "B" and "iB" suffixes */
if (len > 3 ||
(len == 3 && (endp[1] != 'i' || endp[2] != 'B')) ||
(len == 2 && endp[1] != 'B'))
return -EINVAL;
if (len == 1 || len == 3)
mult_base = 1024;
else
mult_base = 1000;
mult = 1;
switch (endp[0]) {
case 's':
case 'S': mult = 512;
break;
case 't':
case 'T': mult *= mult_base;
/* Fall through */
case 'g':
case 'G': mult *= mult_base;
/* Fall through */
case 'm':
case 'M': mult *= mult_base;
/* Fall through */
case 'k':
case 'K': mult *= mult_base;
break;
default:
return -EINVAL;
}
tmp = *size * mult;
if ((tmp / *size) != mult) {
log_dbg("Device size overflow.");
return -EINVAL;
}
*size = tmp;
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment