Remove it, introduce saner bb_strtoXX.
Saved ~350 bytes.
#define STRTOL(s, e, b) strtol(s, e, b)
#endif
+/* TODO: use bb_strtol[l]? It's easier to check for errors... */
+
/* A value is.... */
struct valinfo {
TYPE type; /* Which kind. */
static void print_direc(char *start, size_t length,
int field_width, int precision, char *argument);
-typedef int (*converter)(char *arg, void *result);
+typedef void (*converter)(char *arg, void *result);
static void multiconvert(char *arg, void *result, converter convert)
{
char s[16];
if (*arg == '"' || *arg == '\'') {
- sprintf(s, "%d", (unsigned)arg[1]);
+ sprintf(s, "%d", (unsigned char)arg[1]);
arg = s;
}
- if (convert(arg, result))
+ convert(arg, result);
+ if (errno) /* Huh, looks strange... bug? */
fputs(arg, stderr);
}
+static void conv_strtoul(char *arg, void *result)
+{
+ *(unsigned long*)result = bb_strtoul(arg, NULL, 10);
+}
+static void conv_strtol(char *arg, void *result)
+{
+ *(long*)result = bb_strtol(arg, NULL, 10);
+}
+static void conv_strtod(char *arg, void *result)
+{
+ char *end;
+ /* Well, this one allows leading whitespace... so what */
+ /* What I like much less is that "-" is accepted too! :( */
+ *(double*)result = strtod(arg, &end);
+ if (end[0]) errno = ERANGE;
+}
+
static unsigned long my_xstrtoul(char *arg)
{
unsigned long result;
-
- multiconvert(arg, &result, (converter)safe_strtoul);
+ multiconvert(arg, &result, conv_strtoul);
return result;
}
static long my_xstrtol(char *arg)
{
long result;
- multiconvert(arg, &result, (converter)safe_strtol);
+ multiconvert(arg, &result, conv_strtol);
return result;
}
static double my_xstrtod(char *arg)
{
double result;
- multiconvert(arg, &result, (converter)safe_strtod);
+ multiconvert(arg, &result, conv_strtod);
return result;
}
static int set_os(struct ext2_super_block *sb, char *os)
{
if (isdigit (*os)) {
- sb->s_creator_os = atoi (os);
+ sb->s_creator_os = atoi(os);
return 1;
}
static int PRS(int argc, char *argv[])
{
- int b, c;
+ int c;
int size;
char * tmp;
int blocksize = 0;
"b:cE:f:g:i:jl:m:no:qr:R:s:tvI:J:ST:FL:M:N:O:V")) != EOF) {
switch (c) {
case 'b':
- if (safe_strtoi(optarg, &blocksize))
- goto BLOCKSIZE_ERROR;
- b = (blocksize > 0) ? blocksize : -blocksize;
- if (b < EXT2_MIN_BLOCK_SIZE ||
- b > EXT2_MAX_BLOCK_SIZE) {
-BLOCKSIZE_ERROR:
- bb_error_msg_and_die("invalid block size - %s", optarg);
- }
+ blocksize = xatou_range(optarg, EXT2_MIN_BLOCK_SIZE, EXT2_MAX_BLOCK_SIZE);
mke2fs_warning_msg((blocksize > 4096),
"blocksize %d not usable on most systems",
blocksize);
- if (blocksize > 0)
- param.s_log_block_size =
- int_log2(blocksize >>
- EXT2_MIN_BLOCK_LOG_SIZE);
+ param.s_log_block_size =
+ int_log2(blocksize >> EXT2_MIN_BLOCK_LOG_SIZE);
break;
case 'c': /* Check for bad blocks */
case 't': /* deprecated */
cflag++;
break;
case 'f':
- if (safe_strtoi(optarg, &size) || size < EXT2_MIN_BLOCK_SIZE || size > EXT2_MAX_BLOCK_SIZE ){
- bb_error_msg_and_die("invalid fragment size - %s", optarg);
- }
+ size = xatou_range(optarg, EXT2_MIN_BLOCK_SIZE, EXT2_MAX_BLOCK_SIZE);
param.s_log_frag_size =
int_log2(size >> EXT2_MIN_BLOCK_LOG_SIZE);
mke2fs_warning_msg(1, "fragments not supported. Ignoring -f option");
break;
case 'g':
- {
- int foo;
- if (safe_strtoi(optarg, &foo)) {
- bb_error_msg_and_die("Illegal number for blocks per group");
- }
- param.s_blocks_per_group = foo;
- }
+ param.s_blocks_per_group = xatou32(optarg);
if ((param.s_blocks_per_group % 8) != 0) {
bb_error_msg_and_die("blocks per group must be multiple of 8");
}
break;
case 'i':
- if (safe_strtoi(optarg, &inode_ratio)
- || inode_ratio < EXT2_MIN_BLOCK_SIZE
- || inode_ratio > EXT2_MAX_BLOCK_SIZE * 1024) {
- bb_error_msg_and_die("invalid inode ratio %s (min %d/max %d)",
- optarg, EXT2_MIN_BLOCK_SIZE,
- EXT2_MAX_BLOCK_SIZE);
- }
+ /* Huh? is "* 1024" correct? */
+ inode_ratio = xatou_range(optarg, EXT2_MIN_BLOCK_SIZE, EXT2_MAX_BLOCK_SIZE * 1024);
break;
case 'J':
parse_journal_opts(&journal_device, &journal_flags, &journal_size, optarg);
bad_blocks_filename = optarg;
break;
case 'm':
- if (safe_strtoi(optarg, &reserved_ratio) || reserved_ratio > 50 ) {
- bb_error_msg_and_die("invalid reserved blocks percent - %s", optarg);
- }
+ reserved_ratio = xatou_range(optarg, 0, 50);
break;
case 'n':
noaction++;
creator_os = optarg;
break;
case 'r':
- param.s_rev_level = atoi(optarg);
+ param.s_rev_level = xatoi_u(optarg);
if (param.s_rev_level == EXT2_GOOD_OLD_REV) {
param.s_feature_incompat = 0;
param.s_feature_compat = 0;
}
break;
case 's': /* deprecated */
- if (atoi(optarg))
+ if (xatou(optarg))
param.s_feature_ro_compat |=
EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER;
else
break;
#ifdef EXT2_DYNAMIC_REV
case 'I':
- if (safe_strtoi(optarg, &inode_size)) {
- bb_error_msg_and_die("invalid inode size - %s", optarg);
- }
+ inode_size = xatoi_u(optarg);
break;
#endif
case 'N':
- num_inodes = atoi(optarg);
+ num_inodes = xatoi_u(optarg);
break;
case 'v':
quiet = 0;
static time_t last_check_time;
static int print_label;
static int max_mount_count, mount_count, mount_flags;
-static unsigned long interval, reserved_ratio, reserved_blocks;
+static unsigned long interval, reserved_blocks;
+static unsigned reserved_ratio;
static unsigned long resgid, resuid;
static unsigned short errors;
static int open_flag;
switch (c)
{
case 'c':
- if (safe_strtoi(optarg, &max_mount_count) || max_mount_count > 16000) {
- goto MOUNTS_COUNT_ERROR;
- }
+ max_mount_count = xatou_range(optarg, 0, 16000);
if (max_mount_count == 0)
max_mount_count = -1;
c_flag = 1;
open_flag = EXT2_FLAG_RW;
break;
case 'C':
- if (safe_strtoi(optarg, &mount_count) || mount_count > 16000) {
-MOUNTS_COUNT_ERROR:
- bb_error_msg_and_die("bad mounts count - %s", optarg);
- }
+ mount_count = xatou_range(optarg, 0, 16000);
C_flag = 1;
open_flag = EXT2_FLAG_RW;
break;
f_flag = 1;
break;
case 'g':
- if (safe_strtoul(optarg, &resgid))
+ resgid = bb_strtoul(optarg, NULL, 10);
+ if (errno)
resgid = bb_xgetgrnam(optarg);
g_flag = 1;
open_flag = EXT2_FLAG_RW;
break;
case 'i':
- interval = strtoul (optarg, &tmp, 0);
+ interval = strtoul(optarg, &tmp, 0);
switch (*tmp) {
case 's':
tmp++;
EXT2_FLAG_JOURNAL_DEV_OK;
break;
case 'm':
- if(safe_strtoul(optarg, &reserved_ratio) || reserved_ratio > 50) {
- bb_error_msg_and_die("bad reserved block ratio - %s", optarg);
- }
+ reserved_ratio = xatou_range(optarg, 0, 50);
m_flag = 1;
open_flag = EXT2_FLAG_RW;
break;
open_flag = EXT2_FLAG_RW;
break;
case 'r':
- if(safe_strtoul(optarg, &reserved_blocks)) {
- bb_error_msg_and_die("bad reserved blocks count - %s", optarg);
- }
+ reserved_blocks = xatoul(optarg);
r_flag = 1;
open_flag = EXT2_FLAG_RW;
break;
open_flag = EXT2_FLAG_RW;
break;
case 'u':
- if (safe_strtoul(optarg, &resuid))
+ resuid = bb_strtoul(optarg, NULL, 10);
+ if (errno)
resuid = bb_xgetpwnam(optarg);
u_flag = 1;
open_flag = EXT2_FLAG_RW;
}
if (m_flag) {
sb->s_r_blocks_count = (sb->s_blocks_count / 100)
- * reserved_ratio;
+ * reserved_ratio;
ext2fs_mark_super_dirty(fs);
- printf("Setting reserved blocks percentage to %lu (%u blocks)\n",
+ printf("Setting reserved blocks percentage to %u (%u blocks)\n",
reserved_ratio, sb->s_r_blocks_count);
}
if (r_flag) {
/* CONFIG_LFS is on */
# if ULONG_MAX > 0xffffffff
/* "long" is long enough on this system */
-# define STRTOOFF strtol
-# define SAFE_STRTOOFF safe_strtol
-# define XSTRTOUOFF xstrtoul
+# define XSTRTOOFF xstrtoul
+/* usage: sz = BB_STRTOOFF(s, NULL, 10); if (errno || sz < 0) die(); */
+# define BB_STRTOOFF bb_strtoul
+# define STRTOOFF strtoul
/* usage: printf("size: %"OFF_FMT"d (%"OFF_FMT"x)\n", sz, sz); */
# define OFF_FMT "l"
# else
/* "long" is too short, need "long long" */
-# define STRTOOFF strtoll
-# define SAFE_STRTOOFF safe_strtoll
-# define XSTRTOUOFF xstrtoull
+# define XSTRTOOFF xstrtoull
+# define BB_STRTOOFF bb_strtoull
+# define STRTOOFF strtoull
# define OFF_FMT "ll"
# endif
#else
# if 0 /* #if UINT_MAX == 0xffffffff */
/* Doesn't work. off_t is a long. gcc will throw warnings on printf("%d", off_t)
* even if long==int on this arch. Crap... */
+# define XSTRTOOFF xstrtou
+# define BB_STRTOOFF bb_strtoi
# define STRTOOFF strtol
-# define SAFE_STRTOOFF safe_strtoi
-# define XSTRTOUOFF xstrtou
# define OFF_FMT ""
# else
+# define XSTRTOOFF xstrtoul
+# define BB_STRTOOFF bb_strtol
# define STRTOOFF strtol
-# define SAFE_STRTOOFF safe_strtol
-# define XSTRTOUOFF xstrtoul
# define OFF_FMT "l"
# endif
#endif
extern void itoa_to_buf(int n, char *buf, unsigned buflen);
extern char *itoa(int n);
-// FIXME: the prototype doesn't match libc strtoXX -> confusion
-// FIXME: alot of unchecked strtoXXX are still in tree
-// FIXME: atoi_or_else(str, N)?
-extern int safe_strtoi(const char *arg, int* value);
-extern int safe_strtou(const char *arg, unsigned* value);
-extern int safe_strtod(const char *arg, double* value);
-extern int safe_strtol(const char *arg, long* value);
-extern int safe_strtoll(const char *arg, long long* value);
-extern int safe_strtoul(const char *arg, unsigned long* value);
-extern int safe_strtoull(const char *arg, unsigned long long* value);
-extern int safe_strtou32(const char *arg, uint32_t* value);
-
struct suffix_mult {
const char *suffix;
unsigned mult;
return xatoul(numstr);
return BUG_xatou32_unimplemented();
}
+
+/* Non-aborting kind of convertors */
+
+unsigned long long bb_strtoull(const char *arg, char **endp, int base);
+long long bb_strtoll(const char *arg, char **endp, int base);
+
+#if ULONG_MAX == ULLONG_MAX
+extern inline
+unsigned long bb_strtoul(const char *arg, char **endp, int base)
+{ return bb_strtoull(arg, endp, base); }
+extern inline
+unsigned long bb_strtol(const char *arg, char **endp, int base)
+{ return bb_strtoll(arg, endp, base); }
+#else
+unsigned long bb_strtoul(const char *arg, char **endp, int base);
+long bb_strtol(const char *arg, char **endp, int base);
+#endif
+
+#if UINT_MAX == ULLONG_MAX
+extern inline
+unsigned long bb_strtou(const char *arg, char **endp, int base)
+{ return bb_strtoull(arg, endp, base); }
+extern inline
+unsigned long bb_strtoi(const char *arg, char **endp, int base)
+{ return bb_strtoll(arg, endp, base); }
+#elif UINT_MAX == ULONG_MAX
+extern inline
+unsigned long bb_strtou(const char *arg, char **endp, int base)
+{ return bb_strtoul(arg, endp, base); }
+extern inline
+unsigned long bb_strtoi(const char *arg, char **endp, int base)
+{ return bb_strtol(arg, endp, base); }
+#else
+unsigned long bb_strtou(const char *arg, char **endp, int base);
+long bb_strtoi(const char *arg, char **endp, int base);
+#endif
+
+int BUG_bb_strtou32_unimplemented(void);
+extern inline
+uint32_t bb_strtou32(const char *arg, char **endp, int base)
+{
+ if (sizeof(uint32_t) == sizeof(unsigned))
+ return bb_strtou(arg, endp, base);
+ if (sizeof(uint32_t) == sizeof(unsigned long))
+ return bb_strtoul(arg, endp, base);
+ return BUG_bb_strtou32_unimplemented();
+}
+
+/* Floating point */
+
+/* double bb_strtod(const char *arg, char **endp); */
lib-y += bb_askpass.o
lib-y += bb_do_delay.o
lib-y += bb_pwd.o
+lib-y += bb_strtonum.o
lib-y += change_identity.o
lib-y += chomp.o
lib-y += compare_string_array.o
lib-y += restricted_shell.o
lib-y += run_shell.o
lib-y += safe_strncpy.o
-lib-y += safe_strtol.o
lib-y += safe_write.o
lib-y += setup_environment.o
lib-y += sha1.o
free_procps_scan(sp);
return NULL;
}
- if (safe_strtou(entry->d_name, &pid))
+ pid = bb_strtou(entry->d_name, NULL, 10);
+ if (errno)
continue;
/* After this point we have to break, not continue
+++ /dev/null
-/* vi: set sw=4 ts=4: */
-/*
- * Utility routines.
- *
- * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
- *
- * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
- */
-
-#include <assert.h>
-#include "libbb.h"
-
-int safe_strtod(const char *arg, double* value)
-{
- char *endptr;
- int errno_save = errno;
-
- assert(arg!=NULL);
- errno = 0;
- *value = strtod(arg, &endptr);
- if (errno != 0 || *endptr != '\0' || endptr == arg) {
- return 1;
- }
- errno = errno_save;
- return 0;
-}
-
-int safe_strtoull(const char *arg, unsigned long long* value)
-{
- char *endptr;
- int errno_save = errno;
-
- assert(arg!=NULL);
- if (!isdigit(arg[0])) /* strtouXX takes minus signs w/o error! :( */
- return 1;
- errno = 0;
- *value = strtoull(arg, &endptr, 0);
- if (errno != 0 || *endptr != '\0' || endptr == arg) {
- return 1;
- }
- errno = errno_save;
- return 0;
-}
-
-int safe_strtoll(const char *arg, long long* value)
-{
- char *endptr;
- int errno_save = errno;
-
- assert(arg!=NULL);
- errno = 0;
- *value = strtoll(arg, &endptr, 0);
- if (errno != 0 || *endptr != '\0' || endptr == arg) {
- return 1;
- }
- errno = errno_save;
- return 0;
-}
-
-int safe_strtoul(const char *arg, unsigned long* value)
-{
- char *endptr;
- int errno_save = errno;
-
- assert(arg!=NULL);
- if (!isdigit(arg[0])) /* strtouXX takes minus signs w/o error! :( */
- return 1;
- errno = 0;
- *value = strtoul(arg, &endptr, 0);
- if (errno != 0 || *endptr != '\0' || endptr == arg) {
- return 1;
- }
- errno = errno_save;
- return 0;
-}
-
-int safe_strtol(const char *arg, long* value)
-{
- char *endptr;
- int errno_save = errno;
-
- assert(arg!=NULL);
- errno = 0;
- *value = strtol(arg, &endptr, 0);
- if (errno != 0 || *endptr != '\0' || endptr == arg) {
- return 1;
- }
- errno = errno_save;
- return 0;
-}
-
-/* TODO: This is what uclibc is doing. Try to do the same? */
-
-#if 0
-#if defined __HAVE_ELF__
-
-# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
-# define _strong_alias(name, aliasname) \
- extern __typeof (name) aliasname __attribute__ ((alias (#name)));
-
-#else /* !defined __HAVE_ELF__ */
-
-# define strong_alias(name, aliasname) _strong_alias (name, aliasname)
-# define _strong_alias(name, aliasname) \
- __asm__(".global " __C_SYMBOL_PREFIX__ #aliasname "\n" \
- ".set " __C_SYMBOL_PREFIX__ #aliasname "," __C_SYMBOL_PREFIX__ #name);
-
-#endif
-#endif
-
-int safe_strtoi(const char *arg, int* value)
-{
- int error;
- long lvalue;
- if (sizeof(long) == sizeof(int))
- return safe_strtol(arg, (long*)value);
- lvalue = *value;
- error = safe_strtol(arg, &lvalue);
- if (lvalue < INT_MIN || lvalue > INT_MAX)
- return 1;
- *value = (int) lvalue;
- return error;
-}
-
-int safe_strtou(const char *arg, unsigned* value)
-{
- int error;
- unsigned long lvalue;
- if (sizeof(unsigned long) == sizeof(unsigned))
- return safe_strtoul(arg, (unsigned long*)value);
- lvalue = *value;
- error = safe_strtoul(arg, &lvalue);
- if (lvalue > UINT_MAX)
- return 1;
- *value = (unsigned) lvalue;
- return error;
-}
-
-int BUG_safe_strtou32_unimplemented(void);
-int safe_strtou32(const char *arg, uint32_t* value)
-{
- if (sizeof(uint32_t) == sizeof(unsigned))
- return safe_strtou(arg, (unsigned*)value);
- if (sizeof(uint32_t) == sizeof(unsigned long))
- return safe_strtoul(arg, (unsigned long*)value);
- return BUG_safe_strtou32_unimplemented();
-}
#define XSTR_TYPE_MIN LLONG_MIN
#define XSTR_STRTOU strtoull
#include "xatonum_template.c"
-#undef type
-#undef xstrtou
-#undef xstrto
-#undef xatou
-#undef xato
-#undef XSTR_UTYPE_MAX
-#undef XSTR_TYPE_MAX
-#undef XSTR_TYPE_MIN
-#undef XSTR_STRTOU
#if ULONG_MAX != ULLONG_MAX
#define type long
#define XSTR_TYPE_MIN LONG_MIN
#define XSTR_STRTOU strtoul
#include "xatonum_template.c"
-#undef type
-#undef xstrtou
-#undef xstrto
-#undef xatou
-#undef xato
-#undef XSTR_UTYPE_MAX
-#undef XSTR_TYPE_MAX
-#undef XSTR_TYPE_MIN
-#undef XSTR_STRTOU
#endif
#if UINT_MAX != ULONG_MAX
/* libc has no strtoui, so we need to create/use our own */
#define XSTR_STRTOU bb_strtoui
#include "xatonum_template.c"
-#undef type
-#undef xstrtou
-#undef xstrto
-#undef xatou
-#undef xato
-#undef XSTR_UTYPE_MAX
-#undef XSTR_TYPE_MAX
-#undef XSTR_TYPE_MIN
-#undef XSTR_STRTOU
#endif
/* A few special cases */
return xatou_range(numstr, 0, INT_MAX);
}
-uint32_t xatou32(const char *numstr)
-{
- return xatoul_range(numstr, 0, 0xffffffff);
-}
-
uint16_t xatou16(const char *numstr)
{
return xatou_range(numstr, 0, 0xffff);
{
return xstrto(_range_sfx)(numstr, 10, XSTR_TYPE_MIN, XSTR_TYPE_MAX, NULL);
}
+
+#undef type
+#undef xstrtou
+#undef xstrto
+#undef xatou
+#undef xato
+#undef XSTR_UTYPE_MAX
+#undef XSTR_TYPE_MAX
+#undef XSTR_TYPE_MIN
+#undef XSTR_STRTOU
static int bcode(const char *s)
{
int r;
- unsigned value;
- if (safe_strtou((char *)s, &value)) {
+ unsigned value = bb_strtou(s, NULL, 10);
+ if (errno) {
return -1;
}
r = tty_value_to_baud(value);
fd_data = xconnect_ftpdata(server, buf);
if (ftpcmd("SIZE ", server_path, control_stream, buf) == 213) {
- if (SAFE_STRTOOFF(buf + 4, &filesize))
+ filesize = BB_STRTOOFF(buf + 4, NULL, 10);
+ if (errno || filesize < 0)
bb_error_msg_and_die("SIZE error: %s", buf + 4);
} else {
filesize = -1;
static int read_u32(const char *line, void *arg)
{
- return safe_strtou32(line, (uint32_t*)arg) == 0;
+ *((uint32_t*)arg) = bb_strtou32(line, NULL, 10);
+ return errno == 0;
}
struct option_set *existing, *new, **curr;
/* add it to an existing option */
- if ((existing = find_option(*opt_list, option->code))) {
+ existing = find_option(*opt_list, option->code);
+ if (existing) {
DEBUG("Attaching option %s to existing member of list", option->name);
if (option->flags & OPTION_LIST) {
if (existing->data[OPT_LEN] + length <= 255) {
*/
while ((s = gethdr(buf, sizeof(buf), sfp, &n)) != NULL) {
if (strcasecmp(buf, "content-length") == 0) {
- if (SAFE_STRTOOFF(s, &content_len) || content_len < 0) {
+ content_len = BB_STRTOOFF(s, NULL, 10);
+ if (errno || content_len < 0) {
bb_error_msg_and_die("content-length %s is garbage", s);
}
got_clen = 1;
* Querying file size
*/
if (ftpcmd("SIZE ", target.path, sfp, buf) == 213) {
- if (SAFE_STRTOOFF(buf+4, &content_len) || content_len < 0) {
+ content_len = BB_STRTOOFF(buf+4, NULL, 10);
+ if (errno || content_len < 0) {
bb_error_msg_and_die("SIZE value is garbage");
}
got_clen = 1;
}
if (ftpcmd("RETR ", target.path, sfp, buf) > 150)
- bb_error_msg_and_die("bad response to %s: %s", "RETR", buf);
+ bb_error_msg_and_die("bad response to RETR: %s", buf);
}
*/
if (chunked) {
fgets(buf, sizeof(buf), dfp);
- content_len = STRTOOFF(buf, (char **) NULL, 16);
+ content_len = STRTOOFF(buf, NULL, 16);
/* FIXME: error check?? */
}
if (chunked) {
safe_fgets(buf, sizeof(buf), dfp); /* This is a newline */
safe_fgets(buf, sizeof(buf), dfp);
- content_len = STRTOOFF(buf, (char **) NULL, 16);
+ content_len = STRTOOFF(buf, NULL, 16);
/* FIXME: error check? */
if (content_len == 0) {
chunked = 0; /* all done! */
}
who = p->pw_uid;
} else {
- if (safe_strtou(arg, &who)) {
+ who = bb_strtou(arg, NULL, 10);
+ if (errno) {
bb_error_msg("bad value: %s", arg);
goto HAD_ERROR;
}