aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2006-11-27 14:43:21 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2006-11-27 14:43:21 +0000
commitd686a045c8134d3a42fa5cc6b2e09118e08d603f (patch)
tree38f509fc9556f68f758c77b06b480cc33b2725eb
parent8a0a83d503a7971895254efa9e79cf15ba1850d4 (diff)
downloadbusybox-w32-d686a045c8134d3a42fa5cc6b2e09118e08d603f.tar.gz
busybox-w32-d686a045c8134d3a42fa5cc6b2e09118e08d603f.tar.bz2
busybox-w32-d686a045c8134d3a42fa5cc6b2e09118e08d603f.zip
safe_strtoXX interface proved to be a bit unconvenient.
Remove it, introduce saner bb_strtoXX. Saved ~350 bytes.
-rw-r--r--coreutils/expr.c2
-rw-r--r--coreutils/printf.c31
-rw-r--r--e2fsprogs/mke2fs.c54
-rw-r--r--e2fsprogs/tune2fs.c32
-rw-r--r--include/libbb.h33
-rw-r--r--include/xatonum.h51
-rw-r--r--libbb/Kbuild2
-rw-r--r--libbb/procps.c3
-rw-r--r--libbb/safe_strtol.c147
-rw-r--r--libbb/xatonum.c32
-rw-r--r--libbb/xatonum_template.c10
-rw-r--r--loginutils/getty.c4
-rw-r--r--networking/ftpgetput.c3
-rw-r--r--networking/udhcp/files.c6
-rw-r--r--networking/wget.c12
-rw-r--r--procps/renice.c3
16 files changed, 145 insertions, 280 deletions
diff --git a/coreutils/expr.c b/coreutils/expr.c
index 854a657f9..191473446 100644
--- a/coreutils/expr.c
+++ b/coreutils/expr.c
@@ -49,6 +49,8 @@ typedef long arith_t;
49#define STRTOL(s, e, b) strtol(s, e, b) 49#define STRTOL(s, e, b) strtol(s, e, b)
50#endif 50#endif
51 51
52/* TODO: use bb_strtol[l]? It's easier to check for errors... */
53
52/* A value is.... */ 54/* A value is.... */
53struct valinfo { 55struct valinfo {
54 TYPE type; /* Which kind. */ 56 TYPE type; /* Which kind. */
diff --git a/coreutils/printf.c b/coreutils/printf.c
index 1511034a1..0e818354f 100644
--- a/coreutils/printf.c
+++ b/coreutils/printf.c
@@ -44,38 +44,55 @@ static int print_formatted(char *format, int argc, char **argv);
44static void print_direc(char *start, size_t length, 44static void print_direc(char *start, size_t length,
45 int field_width, int precision, char *argument); 45 int field_width, int precision, char *argument);
46 46
47typedef int (*converter)(char *arg, void *result); 47typedef void (*converter)(char *arg, void *result);
48 48
49static void multiconvert(char *arg, void *result, converter convert) 49static void multiconvert(char *arg, void *result, converter convert)
50{ 50{
51 char s[16]; 51 char s[16];
52 if (*arg == '"' || *arg == '\'') { 52 if (*arg == '"' || *arg == '\'') {
53 sprintf(s, "%d", (unsigned)arg[1]); 53 sprintf(s, "%d", (unsigned char)arg[1]);
54 arg = s; 54 arg = s;
55 } 55 }
56 if (convert(arg, result)) 56 convert(arg, result);
57 if (errno) /* Huh, looks strange... bug? */
57 fputs(arg, stderr); 58 fputs(arg, stderr);
58} 59}
59 60
61static void conv_strtoul(char *arg, void *result)
62{
63 *(unsigned long*)result = bb_strtoul(arg, NULL, 10);
64}
65static void conv_strtol(char *arg, void *result)
66{
67 *(long*)result = bb_strtol(arg, NULL, 10);
68}
69static void conv_strtod(char *arg, void *result)
70{
71 char *end;
72 /* Well, this one allows leading whitespace... so what */
73 /* What I like much less is that "-" is accepted too! :( */
74 *(double*)result = strtod(arg, &end);
75 if (end[0]) errno = ERANGE;
76}
77
60static unsigned long my_xstrtoul(char *arg) 78static unsigned long my_xstrtoul(char *arg)
61{ 79{
62 unsigned long result; 80 unsigned long result;
63 81 multiconvert(arg, &result, conv_strtoul);
64 multiconvert(arg, &result, (converter)safe_strtoul);
65 return result; 82 return result;
66} 83}
67 84
68static long my_xstrtol(char *arg) 85static long my_xstrtol(char *arg)
69{ 86{
70 long result; 87 long result;
71 multiconvert(arg, &result, (converter)safe_strtol); 88 multiconvert(arg, &result, conv_strtol);
72 return result; 89 return result;
73} 90}
74 91
75static double my_xstrtod(char *arg) 92static double my_xstrtod(char *arg)
76{ 93{
77 double result; 94 double result;
78 multiconvert(arg, &result, (converter)safe_strtod); 95 multiconvert(arg, &result, conv_strtod);
79 return result; 96 return result;
80} 97}
81 98
diff --git a/e2fsprogs/mke2fs.c b/e2fsprogs/mke2fs.c
index 1c4f1541e..f25ecfb6c 100644
--- a/e2fsprogs/mke2fs.c
+++ b/e2fsprogs/mke2fs.c
@@ -673,7 +673,7 @@ static void show_stats(ext2_filsys fs)
673static int set_os(struct ext2_super_block *sb, char *os) 673static int set_os(struct ext2_super_block *sb, char *os)
674{ 674{
675 if (isdigit (*os)) { 675 if (isdigit (*os)) {
676 sb->s_creator_os = atoi (os); 676 sb->s_creator_os = atoi(os);
677 return 1; 677 return 1;
678 } 678 }
679 679
@@ -790,7 +790,7 @@ static __u32 ok_features[3] = {
790 790
791static int PRS(int argc, char *argv[]) 791static int PRS(int argc, char *argv[])
792{ 792{
793 int b, c; 793 int c;
794 int size; 794 int size;
795 char * tmp; 795 char * tmp;
796 int blocksize = 0; 796 int blocksize = 0;
@@ -848,54 +848,32 @@ static int PRS(int argc, char *argv[])
848 "b:cE:f:g:i:jl:m:no:qr:R:s:tvI:J:ST:FL:M:N:O:V")) != EOF) { 848 "b:cE:f:g:i:jl:m:no:qr:R:s:tvI:J:ST:FL:M:N:O:V")) != EOF) {
849 switch (c) { 849 switch (c) {
850 case 'b': 850 case 'b':
851 if (safe_strtoi(optarg, &blocksize)) 851 blocksize = xatou_range(optarg, EXT2_MIN_BLOCK_SIZE, EXT2_MAX_BLOCK_SIZE);
852 goto BLOCKSIZE_ERROR;
853 b = (blocksize > 0) ? blocksize : -blocksize;
854 if (b < EXT2_MIN_BLOCK_SIZE ||
855 b > EXT2_MAX_BLOCK_SIZE) {
856BLOCKSIZE_ERROR:
857 bb_error_msg_and_die("invalid block size - %s", optarg);
858 }
859 mke2fs_warning_msg((blocksize > 4096), 852 mke2fs_warning_msg((blocksize > 4096),
860 "blocksize %d not usable on most systems", 853 "blocksize %d not usable on most systems",
861 blocksize); 854 blocksize);
862 if (blocksize > 0) 855 param.s_log_block_size =
863 param.s_log_block_size = 856 int_log2(blocksize >> EXT2_MIN_BLOCK_LOG_SIZE);
864 int_log2(blocksize >>
865 EXT2_MIN_BLOCK_LOG_SIZE);
866 break; 857 break;
867 case 'c': /* Check for bad blocks */ 858 case 'c': /* Check for bad blocks */
868 case 't': /* deprecated */ 859 case 't': /* deprecated */
869 cflag++; 860 cflag++;
870 break; 861 break;
871 case 'f': 862 case 'f':
872 if (safe_strtoi(optarg, &size) || size < EXT2_MIN_BLOCK_SIZE || size > EXT2_MAX_BLOCK_SIZE ){ 863 size = xatou_range(optarg, EXT2_MIN_BLOCK_SIZE, EXT2_MAX_BLOCK_SIZE);
873 bb_error_msg_and_die("invalid fragment size - %s", optarg);
874 }
875 param.s_log_frag_size = 864 param.s_log_frag_size =
876 int_log2(size >> EXT2_MIN_BLOCK_LOG_SIZE); 865 int_log2(size >> EXT2_MIN_BLOCK_LOG_SIZE);
877 mke2fs_warning_msg(1, "fragments not supported. Ignoring -f option"); 866 mke2fs_warning_msg(1, "fragments not supported. Ignoring -f option");
878 break; 867 break;
879 case 'g': 868 case 'g':
880 { 869 param.s_blocks_per_group = xatou32(optarg);
881 int foo;
882 if (safe_strtoi(optarg, &foo)) {
883 bb_error_msg_and_die("Illegal number for blocks per group");
884 }
885 param.s_blocks_per_group = foo;
886 }
887 if ((param.s_blocks_per_group % 8) != 0) { 870 if ((param.s_blocks_per_group % 8) != 0) {
888 bb_error_msg_and_die("blocks per group must be multiple of 8"); 871 bb_error_msg_and_die("blocks per group must be multiple of 8");
889 } 872 }
890 break; 873 break;
891 case 'i': 874 case 'i':
892 if (safe_strtoi(optarg, &inode_ratio) 875 /* Huh? is "* 1024" correct? */
893 || inode_ratio < EXT2_MIN_BLOCK_SIZE 876 inode_ratio = xatou_range(optarg, EXT2_MIN_BLOCK_SIZE, EXT2_MAX_BLOCK_SIZE * 1024);
894 || inode_ratio > EXT2_MAX_BLOCK_SIZE * 1024) {
895 bb_error_msg_and_die("invalid inode ratio %s (min %d/max %d)",
896 optarg, EXT2_MIN_BLOCK_SIZE,
897 EXT2_MAX_BLOCK_SIZE);
898 }
899 break; 877 break;
900 case 'J': 878 case 'J':
901 parse_journal_opts(&journal_device, &journal_flags, &journal_size, optarg); 879 parse_journal_opts(&journal_device, &journal_flags, &journal_size, optarg);
@@ -910,9 +888,7 @@ BLOCKSIZE_ERROR:
910 bad_blocks_filename = optarg; 888 bad_blocks_filename = optarg;
911 break; 889 break;
912 case 'm': 890 case 'm':
913 if (safe_strtoi(optarg, &reserved_ratio) || reserved_ratio > 50 ) { 891 reserved_ratio = xatou_range(optarg, 0, 50);
914 bb_error_msg_and_die("invalid reserved blocks percent - %s", optarg);
915 }
916 break; 892 break;
917 case 'n': 893 case 'n':
918 noaction++; 894 noaction++;
@@ -921,7 +897,7 @@ BLOCKSIZE_ERROR:
921 creator_os = optarg; 897 creator_os = optarg;
922 break; 898 break;
923 case 'r': 899 case 'r':
924 param.s_rev_level = atoi(optarg); 900 param.s_rev_level = xatoi_u(optarg);
925 if (param.s_rev_level == EXT2_GOOD_OLD_REV) { 901 if (param.s_rev_level == EXT2_GOOD_OLD_REV) {
926 param.s_feature_incompat = 0; 902 param.s_feature_incompat = 0;
927 param.s_feature_compat = 0; 903 param.s_feature_compat = 0;
@@ -929,7 +905,7 @@ BLOCKSIZE_ERROR:
929 } 905 }
930 break; 906 break;
931 case 's': /* deprecated */ 907 case 's': /* deprecated */
932 if (atoi(optarg)) 908 if (xatou(optarg))
933 param.s_feature_ro_compat |= 909 param.s_feature_ro_compat |=
934 EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER; 910 EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER;
935 else 911 else
@@ -938,13 +914,11 @@ BLOCKSIZE_ERROR:
938 break; 914 break;
939#ifdef EXT2_DYNAMIC_REV 915#ifdef EXT2_DYNAMIC_REV
940 case 'I': 916 case 'I':
941 if (safe_strtoi(optarg, &inode_size)) { 917 inode_size = xatoi_u(optarg);
942 bb_error_msg_and_die("invalid inode size - %s", optarg);
943 }
944 break; 918 break;
945#endif 919#endif
946 case 'N': 920 case 'N':
947 num_inodes = atoi(optarg); 921 num_inodes = xatoi_u(optarg);
948 break; 922 break;
949 case 'v': 923 case 'v':
950 quiet = 0; 924 quiet = 0;
diff --git a/e2fsprogs/tune2fs.c b/e2fsprogs/tune2fs.c
index d22deede2..c8dfc6927 100644
--- a/e2fsprogs/tune2fs.c
+++ b/e2fsprogs/tune2fs.c
@@ -54,7 +54,8 @@ static int m_flag, M_flag, r_flag, s_flag = -1, u_flag, U_flag, T_flag;
54static time_t last_check_time; 54static time_t last_check_time;
55static int print_label; 55static int print_label;
56static int max_mount_count, mount_count, mount_flags; 56static int max_mount_count, mount_count, mount_flags;
57static unsigned long interval, reserved_ratio, reserved_blocks; 57static unsigned long interval, reserved_blocks;
58static unsigned reserved_ratio;
58static unsigned long resgid, resuid; 59static unsigned long resgid, resuid;
59static unsigned short errors; 60static unsigned short errors;
60static int open_flag; 61static int open_flag;
@@ -410,19 +411,14 @@ static void parse_tune2fs_options(int argc, char **argv)
410 switch (c) 411 switch (c)
411 { 412 {
412 case 'c': 413 case 'c':
413 if (safe_strtoi(optarg, &max_mount_count) || max_mount_count > 16000) { 414 max_mount_count = xatou_range(optarg, 0, 16000);
414 goto MOUNTS_COUNT_ERROR;
415 }
416 if (max_mount_count == 0) 415 if (max_mount_count == 0)
417 max_mount_count = -1; 416 max_mount_count = -1;
418 c_flag = 1; 417 c_flag = 1;
419 open_flag = EXT2_FLAG_RW; 418 open_flag = EXT2_FLAG_RW;
420 break; 419 break;
421 case 'C': 420 case 'C':
422 if (safe_strtoi(optarg, &mount_count) || mount_count > 16000) { 421 mount_count = xatou_range(optarg, 0, 16000);
423MOUNTS_COUNT_ERROR:
424 bb_error_msg_and_die("bad mounts count - %s", optarg);
425 }
426 C_flag = 1; 422 C_flag = 1;
427 open_flag = EXT2_FLAG_RW; 423 open_flag = EXT2_FLAG_RW;
428 break; 424 break;
@@ -443,13 +439,14 @@ MOUNTS_COUNT_ERROR:
443 f_flag = 1; 439 f_flag = 1;
444 break; 440 break;
445 case 'g': 441 case 'g':
446 if (safe_strtoul(optarg, &resgid)) 442 resgid = bb_strtoul(optarg, NULL, 10);
443 if (errno)
447 resgid = bb_xgetgrnam(optarg); 444 resgid = bb_xgetgrnam(optarg);
448 g_flag = 1; 445 g_flag = 1;
449 open_flag = EXT2_FLAG_RW; 446 open_flag = EXT2_FLAG_RW;
450 break; 447 break;
451 case 'i': 448 case 'i':
452 interval = strtoul (optarg, &tmp, 0); 449 interval = strtoul(optarg, &tmp, 0);
453 switch (*tmp) { 450 switch (*tmp) {
454 case 's': 451 case 's':
455 tmp++; 452 tmp++;
@@ -497,9 +494,7 @@ MOUNTS_COUNT_ERROR:
497 EXT2_FLAG_JOURNAL_DEV_OK; 494 EXT2_FLAG_JOURNAL_DEV_OK;
498 break; 495 break;
499 case 'm': 496 case 'm':
500 if(safe_strtoul(optarg, &reserved_ratio) || reserved_ratio > 50) { 497 reserved_ratio = xatou_range(optarg, 0, 50);
501 bb_error_msg_and_die("bad reserved block ratio - %s", optarg);
502 }
503 m_flag = 1; 498 m_flag = 1;
504 open_flag = EXT2_FLAG_RW; 499 open_flag = EXT2_FLAG_RW;
505 break; 500 break;
@@ -524,9 +519,7 @@ MOUNTS_COUNT_ERROR:
524 open_flag = EXT2_FLAG_RW; 519 open_flag = EXT2_FLAG_RW;
525 break; 520 break;
526 case 'r': 521 case 'r':
527 if(safe_strtoul(optarg, &reserved_blocks)) { 522 reserved_blocks = xatoul(optarg);
528 bb_error_msg_and_die("bad reserved blocks count - %s", optarg);
529 }
530 r_flag = 1; 523 r_flag = 1;
531 open_flag = EXT2_FLAG_RW; 524 open_flag = EXT2_FLAG_RW;
532 break; 525 break;
@@ -540,7 +533,8 @@ MOUNTS_COUNT_ERROR:
540 open_flag = EXT2_FLAG_RW; 533 open_flag = EXT2_FLAG_RW;
541 break; 534 break;
542 case 'u': 535 case 'u':
543 if (safe_strtoul(optarg, &resuid)) 536 resuid = bb_strtoul(optarg, NULL, 10);
537 if (errno)
544 resuid = bb_xgetpwnam(optarg); 538 resuid = bb_xgetpwnam(optarg);
545 u_flag = 1; 539 u_flag = 1;
546 open_flag = EXT2_FLAG_RW; 540 open_flag = EXT2_FLAG_RW;
@@ -646,9 +640,9 @@ int tune2fs_main(int argc, char **argv)
646 } 640 }
647 if (m_flag) { 641 if (m_flag) {
648 sb->s_r_blocks_count = (sb->s_blocks_count / 100) 642 sb->s_r_blocks_count = (sb->s_blocks_count / 100)
649 * reserved_ratio; 643 * reserved_ratio;
650 ext2fs_mark_super_dirty(fs); 644 ext2fs_mark_super_dirty(fs);
651 printf("Setting reserved blocks percentage to %lu (%u blocks)\n", 645 printf("Setting reserved blocks percentage to %u (%u blocks)\n",
652 reserved_ratio, sb->s_r_blocks_count); 646 reserved_ratio, sb->s_r_blocks_count);
653 } 647 }
654 if (r_flag) { 648 if (r_flag) {
diff --git a/include/libbb.h b/include/libbb.h
index e93031231..63748c85d 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -85,30 +85,31 @@
85/* CONFIG_LFS is on */ 85/* CONFIG_LFS is on */
86# if ULONG_MAX > 0xffffffff 86# if ULONG_MAX > 0xffffffff
87/* "long" is long enough on this system */ 87/* "long" is long enough on this system */
88# define STRTOOFF strtol 88# define XSTRTOOFF xstrtoul
89# define SAFE_STRTOOFF safe_strtol 89/* usage: sz = BB_STRTOOFF(s, NULL, 10); if (errno || sz < 0) die(); */
90# define XSTRTOUOFF xstrtoul 90# define BB_STRTOOFF bb_strtoul
91# define STRTOOFF strtoul
91/* usage: printf("size: %"OFF_FMT"d (%"OFF_FMT"x)\n", sz, sz); */ 92/* usage: printf("size: %"OFF_FMT"d (%"OFF_FMT"x)\n", sz, sz); */
92# define OFF_FMT "l" 93# define OFF_FMT "l"
93# else 94# else
94/* "long" is too short, need "long long" */ 95/* "long" is too short, need "long long" */
95# define STRTOOFF strtoll 96# define XSTRTOOFF xstrtoull
96# define SAFE_STRTOOFF safe_strtoll 97# define BB_STRTOOFF bb_strtoull
97# define XSTRTOUOFF xstrtoull 98# define STRTOOFF strtoull
98# define OFF_FMT "ll" 99# define OFF_FMT "ll"
99# endif 100# endif
100#else 101#else
101# if 0 /* #if UINT_MAX == 0xffffffff */ 102# if 0 /* #if UINT_MAX == 0xffffffff */
102/* Doesn't work. off_t is a long. gcc will throw warnings on printf("%d", off_t) 103/* Doesn't work. off_t is a long. gcc will throw warnings on printf("%d", off_t)
103 * even if long==int on this arch. Crap... */ 104 * even if long==int on this arch. Crap... */
105# define XSTRTOOFF xstrtou
106# define BB_STRTOOFF bb_strtoi
104# define STRTOOFF strtol 107# define STRTOOFF strtol
105# define SAFE_STRTOOFF safe_strtoi
106# define XSTRTOUOFF xstrtou
107# define OFF_FMT "" 108# define OFF_FMT ""
108# else 109# else
110# define XSTRTOOFF xstrtoul
111# define BB_STRTOOFF bb_strtol
109# define STRTOOFF strtol 112# define STRTOOFF strtol
110# define SAFE_STRTOOFF safe_strtol
111# define XSTRTOUOFF xstrtoul
112# define OFF_FMT "l" 113# define OFF_FMT "l"
113# endif 114# endif
114#endif 115#endif
@@ -299,18 +300,6 @@ extern char *utoa(unsigned n);
299extern void itoa_to_buf(int n, char *buf, unsigned buflen); 300extern void itoa_to_buf(int n, char *buf, unsigned buflen);
300extern char *itoa(int n); 301extern char *itoa(int n);
301 302
302// FIXME: the prototype doesn't match libc strtoXX -> confusion
303// FIXME: alot of unchecked strtoXXX are still in tree
304// FIXME: atoi_or_else(str, N)?
305extern int safe_strtoi(const char *arg, int* value);
306extern int safe_strtou(const char *arg, unsigned* value);
307extern int safe_strtod(const char *arg, double* value);
308extern int safe_strtol(const char *arg, long* value);
309extern int safe_strtoll(const char *arg, long long* value);
310extern int safe_strtoul(const char *arg, unsigned long* value);
311extern int safe_strtoull(const char *arg, unsigned long long* value);
312extern int safe_strtou32(const char *arg, uint32_t* value);
313
314struct suffix_mult { 303struct suffix_mult {
315 const char *suffix; 304 const char *suffix;
316 unsigned mult; 305 unsigned mult;
diff --git a/include/xatonum.h b/include/xatonum.h
index 46e49b0eb..585d84623 100644
--- a/include/xatonum.h
+++ b/include/xatonum.h
@@ -104,3 +104,54 @@ extern inline uint32_t xatou32(const char *numstr)
104 return xatoul(numstr); 104 return xatoul(numstr);
105 return BUG_xatou32_unimplemented(); 105 return BUG_xatou32_unimplemented();
106} 106}
107
108/* Non-aborting kind of convertors */
109
110unsigned long long bb_strtoull(const char *arg, char **endp, int base);
111long long bb_strtoll(const char *arg, char **endp, int base);
112
113#if ULONG_MAX == ULLONG_MAX
114extern inline
115unsigned long bb_strtoul(const char *arg, char **endp, int base)
116{ return bb_strtoull(arg, endp, base); }
117extern inline
118unsigned long bb_strtol(const char *arg, char **endp, int base)
119{ return bb_strtoll(arg, endp, base); }
120#else
121unsigned long bb_strtoul(const char *arg, char **endp, int base);
122long bb_strtol(const char *arg, char **endp, int base);
123#endif
124
125#if UINT_MAX == ULLONG_MAX
126extern inline
127unsigned long bb_strtou(const char *arg, char **endp, int base)
128{ return bb_strtoull(arg, endp, base); }
129extern inline
130unsigned long bb_strtoi(const char *arg, char **endp, int base)
131{ return bb_strtoll(arg, endp, base); }
132#elif UINT_MAX == ULONG_MAX
133extern inline
134unsigned long bb_strtou(const char *arg, char **endp, int base)
135{ return bb_strtoul(arg, endp, base); }
136extern inline
137unsigned long bb_strtoi(const char *arg, char **endp, int base)
138{ return bb_strtol(arg, endp, base); }
139#else
140unsigned long bb_strtou(const char *arg, char **endp, int base);
141long bb_strtoi(const char *arg, char **endp, int base);
142#endif
143
144int BUG_bb_strtou32_unimplemented(void);
145extern inline
146uint32_t bb_strtou32(const char *arg, char **endp, int base)
147{
148 if (sizeof(uint32_t) == sizeof(unsigned))
149 return bb_strtou(arg, endp, base);
150 if (sizeof(uint32_t) == sizeof(unsigned long))
151 return bb_strtoul(arg, endp, base);
152 return BUG_bb_strtou32_unimplemented();
153}
154
155/* Floating point */
156
157/* double bb_strtod(const char *arg, char **endp); */
diff --git a/libbb/Kbuild b/libbb/Kbuild
index 550723cea..c15615302 100644
--- a/libbb/Kbuild
+++ b/libbb/Kbuild
@@ -10,6 +10,7 @@ lib-y += ask_confirmation.o
10lib-y += bb_askpass.o 10lib-y += bb_askpass.o
11lib-y += bb_do_delay.o 11lib-y += bb_do_delay.o
12lib-y += bb_pwd.o 12lib-y += bb_pwd.o
13lib-y += bb_strtonum.o
13lib-y += change_identity.o 14lib-y += change_identity.o
14lib-y += chomp.o 15lib-y += chomp.o
15lib-y += compare_string_array.o 16lib-y += compare_string_array.o
@@ -67,7 +68,6 @@ lib-y += remove_file.o
67lib-y += restricted_shell.o 68lib-y += restricted_shell.o
68lib-y += run_shell.o 69lib-y += run_shell.o
69lib-y += safe_strncpy.o 70lib-y += safe_strncpy.o
70lib-y += safe_strtol.o
71lib-y += safe_write.o 71lib-y += safe_write.o
72lib-y += setup_environment.o 72lib-y += setup_environment.o
73lib-y += sha1.o 73lib-y += sha1.o
diff --git a/libbb/procps.c b/libbb/procps.c
index ee4f5e53f..017710ff4 100644
--- a/libbb/procps.c
+++ b/libbb/procps.c
@@ -119,7 +119,8 @@ procps_status_t* procps_scan(procps_status_t* sp, int flags)
119 free_procps_scan(sp); 119 free_procps_scan(sp);
120 return NULL; 120 return NULL;
121 } 121 }
122 if (safe_strtou(entry->d_name, &pid)) 122 pid = bb_strtou(entry->d_name, NULL, 10);
123 if (errno)
123 continue; 124 continue;
124 125
125 /* After this point we have to break, not continue 126 /* After this point we have to break, not continue
diff --git a/libbb/safe_strtol.c b/libbb/safe_strtol.c
deleted file mode 100644
index d3bb29cdd..000000000
--- a/libbb/safe_strtol.c
+++ /dev/null
@@ -1,147 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * Utility routines.
4 *
5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
6 *
7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
8 */
9
10#include <assert.h>
11#include "libbb.h"
12
13int safe_strtod(const char *arg, double* value)
14{
15 char *endptr;
16 int errno_save = errno;
17
18 assert(arg!=NULL);
19 errno = 0;
20 *value = strtod(arg, &endptr);
21 if (errno != 0 || *endptr != '\0' || endptr == arg) {
22 return 1;
23 }
24 errno = errno_save;
25 return 0;
26}
27
28int safe_strtoull(const char *arg, unsigned long long* value)
29{
30 char *endptr;
31 int errno_save = errno;
32
33 assert(arg!=NULL);
34 if (!isdigit(arg[0])) /* strtouXX takes minus signs w/o error! :( */
35 return 1;
36 errno = 0;
37 *value = strtoull(arg, &endptr, 0);
38 if (errno != 0 || *endptr != '\0' || endptr == arg) {
39 return 1;
40 }
41 errno = errno_save;
42 return 0;
43}
44
45int safe_strtoll(const char *arg, long long* value)
46{
47 char *endptr;
48 int errno_save = errno;
49
50 assert(arg!=NULL);
51 errno = 0;
52 *value = strtoll(arg, &endptr, 0);
53 if (errno != 0 || *endptr != '\0' || endptr == arg) {
54 return 1;
55 }
56 errno = errno_save;
57 return 0;
58}
59
60int safe_strtoul(const char *arg, unsigned long* value)
61{
62 char *endptr;
63 int errno_save = errno;
64
65 assert(arg!=NULL);
66 if (!isdigit(arg[0])) /* strtouXX takes minus signs w/o error! :( */
67 return 1;
68 errno = 0;
69 *value = strtoul(arg, &endptr, 0);
70 if (errno != 0 || *endptr != '\0' || endptr == arg) {
71 return 1;
72 }
73 errno = errno_save;
74 return 0;
75}
76
77int safe_strtol(const char *arg, long* value)
78{
79 char *endptr;
80 int errno_save = errno;
81
82 assert(arg!=NULL);
83 errno = 0;
84 *value = strtol(arg, &endptr, 0);
85 if (errno != 0 || *endptr != '\0' || endptr == arg) {
86 return 1;
87 }
88 errno = errno_save;
89 return 0;
90}
91
92/* TODO: This is what uclibc is doing. Try to do the same? */
93
94#if 0
95#if defined __HAVE_ELF__
96
97# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
98# define _strong_alias(name, aliasname) \
99 extern __typeof (name) aliasname __attribute__ ((alias (#name)));
100
101#else /* !defined __HAVE_ELF__ */
102
103# define strong_alias(name, aliasname) _strong_alias (name, aliasname)
104# define _strong_alias(name, aliasname) \
105 __asm__(".global " __C_SYMBOL_PREFIX__ #aliasname "\n" \
106 ".set " __C_SYMBOL_PREFIX__ #aliasname "," __C_SYMBOL_PREFIX__ #name);
107
108#endif
109#endif
110
111int safe_strtoi(const char *arg, int* value)
112{
113 int error;
114 long lvalue;
115 if (sizeof(long) == sizeof(int))
116 return safe_strtol(arg, (long*)value);
117 lvalue = *value;
118 error = safe_strtol(arg, &lvalue);
119 if (lvalue < INT_MIN || lvalue > INT_MAX)
120 return 1;
121 *value = (int) lvalue;
122 return error;
123}
124
125int safe_strtou(const char *arg, unsigned* value)
126{
127 int error;
128 unsigned long lvalue;
129 if (sizeof(unsigned long) == sizeof(unsigned))
130 return safe_strtoul(arg, (unsigned long*)value);
131 lvalue = *value;
132 error = safe_strtoul(arg, &lvalue);
133 if (lvalue > UINT_MAX)
134 return 1;
135 *value = (unsigned) lvalue;
136 return error;
137}
138
139int BUG_safe_strtou32_unimplemented(void);
140int safe_strtou32(const char *arg, uint32_t* value)
141{
142 if (sizeof(uint32_t) == sizeof(unsigned))
143 return safe_strtou(arg, (unsigned*)value);
144 if (sizeof(uint32_t) == sizeof(unsigned long))
145 return safe_strtoul(arg, (unsigned long*)value);
146 return BUG_safe_strtou32_unimplemented();
147}
diff --git a/libbb/xatonum.c b/libbb/xatonum.c
index 0d487dd9b..35607c317 100644
--- a/libbb/xatonum.c
+++ b/libbb/xatonum.c
@@ -19,15 +19,6 @@
19#define XSTR_TYPE_MIN LLONG_MIN 19#define XSTR_TYPE_MIN LLONG_MIN
20#define XSTR_STRTOU strtoull 20#define XSTR_STRTOU strtoull
21#include "xatonum_template.c" 21#include "xatonum_template.c"
22#undef type
23#undef xstrtou
24#undef xstrto
25#undef xatou
26#undef xato
27#undef XSTR_UTYPE_MAX
28#undef XSTR_TYPE_MAX
29#undef XSTR_TYPE_MIN
30#undef XSTR_STRTOU
31 22
32#if ULONG_MAX != ULLONG_MAX 23#if ULONG_MAX != ULLONG_MAX
33#define type long 24#define type long
@@ -40,15 +31,6 @@
40#define XSTR_TYPE_MIN LONG_MIN 31#define XSTR_TYPE_MIN LONG_MIN
41#define XSTR_STRTOU strtoul 32#define XSTR_STRTOU strtoul
42#include "xatonum_template.c" 33#include "xatonum_template.c"
43#undef type
44#undef xstrtou
45#undef xstrto
46#undef xatou
47#undef xato
48#undef XSTR_UTYPE_MAX
49#undef XSTR_TYPE_MAX
50#undef XSTR_TYPE_MIN
51#undef XSTR_STRTOU
52#endif 34#endif
53 35
54#if UINT_MAX != ULONG_MAX 36#if UINT_MAX != ULONG_MAX
@@ -72,15 +54,6 @@ extern inline unsigned bb_strtoui(const char *str, char **end, int b)
72/* libc has no strtoui, so we need to create/use our own */ 54/* libc has no strtoui, so we need to create/use our own */
73#define XSTR_STRTOU bb_strtoui 55#define XSTR_STRTOU bb_strtoui
74#include "xatonum_template.c" 56#include "xatonum_template.c"
75#undef type
76#undef xstrtou
77#undef xstrto
78#undef xatou
79#undef xato
80#undef XSTR_UTYPE_MAX
81#undef XSTR_TYPE_MAX
82#undef XSTR_TYPE_MIN
83#undef XSTR_STRTOU
84#endif 57#endif
85 58
86/* A few special cases */ 59/* A few special cases */
@@ -90,11 +63,6 @@ int xatoi_u(const char *numstr)
90 return xatou_range(numstr, 0, INT_MAX); 63 return xatou_range(numstr, 0, INT_MAX);
91} 64}
92 65
93uint32_t xatou32(const char *numstr)
94{
95 return xatoul_range(numstr, 0, 0xffffffff);
96}
97
98uint16_t xatou16(const char *numstr) 66uint16_t xatou16(const char *numstr)
99{ 67{
100 return xatou_range(numstr, 0, 0xffff); 68 return xatou_range(numstr, 0, 0xffff);
diff --git a/libbb/xatonum_template.c b/libbb/xatonum_template.c
index 245586a5a..53ba544eb 100644
--- a/libbb/xatonum_template.c
+++ b/libbb/xatonum_template.c
@@ -173,3 +173,13 @@ type xato()(const char *numstr)
173{ 173{
174 return xstrto(_range_sfx)(numstr, 10, XSTR_TYPE_MIN, XSTR_TYPE_MAX, NULL); 174 return xstrto(_range_sfx)(numstr, 10, XSTR_TYPE_MIN, XSTR_TYPE_MAX, NULL);
175} 175}
176
177#undef type
178#undef xstrtou
179#undef xstrto
180#undef xatou
181#undef xato
182#undef XSTR_UTYPE_MAX
183#undef XSTR_TYPE_MAX
184#undef XSTR_TYPE_MIN
185#undef XSTR_STRTOU
diff --git a/loginutils/getty.c b/loginutils/getty.c
index 0c269de98..a85e52306 100644
--- a/loginutils/getty.c
+++ b/loginutils/getty.c
@@ -147,8 +147,8 @@ static FILE *dbf;
147static int bcode(const char *s) 147static int bcode(const char *s)
148{ 148{
149 int r; 149 int r;
150 unsigned value; 150 unsigned value = bb_strtou(s, NULL, 10);
151 if (safe_strtou((char *)s, &value)) { 151 if (errno) {
152 return -1; 152 return -1;
153 } 153 }
154 r = tty_value_to_baud(value); 154 r = tty_value_to_baud(value);
diff --git a/networking/ftpgetput.c b/networking/ftpgetput.c
index fa1854903..3773f9937 100644
--- a/networking/ftpgetput.c
+++ b/networking/ftpgetput.c
@@ -124,7 +124,8 @@ int ftp_receive(ftp_host_info_t *server, FILE *control_stream,
124 fd_data = xconnect_ftpdata(server, buf); 124 fd_data = xconnect_ftpdata(server, buf);
125 125
126 if (ftpcmd("SIZE ", server_path, control_stream, buf) == 213) { 126 if (ftpcmd("SIZE ", server_path, control_stream, buf) == 213) {
127 if (SAFE_STRTOOFF(buf + 4, &filesize)) 127 filesize = BB_STRTOOFF(buf + 4, NULL, 10);
128 if (errno || filesize < 0)
128 bb_error_msg_and_die("SIZE error: %s", buf + 4); 129 bb_error_msg_and_die("SIZE error: %s", buf + 4);
129 } else { 130 } else {
130 filesize = -1; 131 filesize = -1;
diff --git a/networking/udhcp/files.c b/networking/udhcp/files.c
index 829d7e960..5e399e1f8 100644
--- a/networking/udhcp/files.c
+++ b/networking/udhcp/files.c
@@ -64,7 +64,8 @@ static int read_str(const char *line, void *arg)
64 64
65static int read_u32(const char *line, void *arg) 65static int read_u32(const char *line, void *arg)
66{ 66{
67 return safe_strtou32(line, (uint32_t*)arg) == 0; 67 *((uint32_t*)arg) = bb_strtou32(line, NULL, 10);
68 return errno == 0;
68} 69}
69 70
70 71
@@ -101,7 +102,8 @@ static void attach_option(struct option_set **opt_list,
101 struct option_set *existing, *new, **curr; 102 struct option_set *existing, *new, **curr;
102 103
103 /* add it to an existing option */ 104 /* add it to an existing option */
104 if ((existing = find_option(*opt_list, option->code))) { 105 existing = find_option(*opt_list, option->code);
106 if (existing) {
105 DEBUG("Attaching option %s to existing member of list", option->name); 107 DEBUG("Attaching option %s to existing member of list", option->name);
106 if (option->flags & OPTION_LIST) { 108 if (option->flags & OPTION_LIST) {
107 if (existing->data[OPT_LEN] + length <= 255) { 109 if (existing->data[OPT_LEN] + length <= 255) {
diff --git a/networking/wget.c b/networking/wget.c
index 1e51ce96b..49ebda73c 100644
--- a/networking/wget.c
+++ b/networking/wget.c
@@ -335,7 +335,8 @@ int wget_main(int argc, char **argv)
335 */ 335 */
336 while ((s = gethdr(buf, sizeof(buf), sfp, &n)) != NULL) { 336 while ((s = gethdr(buf, sizeof(buf), sfp, &n)) != NULL) {
337 if (strcasecmp(buf, "content-length") == 0) { 337 if (strcasecmp(buf, "content-length") == 0) {
338 if (SAFE_STRTOOFF(s, &content_len) || content_len < 0) { 338 content_len = BB_STRTOOFF(s, NULL, 10);
339 if (errno || content_len < 0) {
339 bb_error_msg_and_die("content-length %s is garbage", s); 340 bb_error_msg_and_die("content-length %s is garbage", s);
340 } 341 }
341 got_clen = 1; 342 got_clen = 1;
@@ -402,7 +403,8 @@ int wget_main(int argc, char **argv)
402 * Querying file size 403 * Querying file size
403 */ 404 */
404 if (ftpcmd("SIZE ", target.path, sfp, buf) == 213) { 405 if (ftpcmd("SIZE ", target.path, sfp, buf) == 213) {
405 if (SAFE_STRTOOFF(buf+4, &content_len) || content_len < 0) { 406 content_len = BB_STRTOOFF(buf+4, NULL, 10);
407 if (errno || content_len < 0) {
406 bb_error_msg_and_die("SIZE value is garbage"); 408 bb_error_msg_and_die("SIZE value is garbage");
407 } 409 }
408 got_clen = 1; 410 got_clen = 1;
@@ -437,7 +439,7 @@ int wget_main(int argc, char **argv)
437 } 439 }
438 440
439 if (ftpcmd("RETR ", target.path, sfp, buf) > 150) 441 if (ftpcmd("RETR ", target.path, sfp, buf) > 150)
440 bb_error_msg_and_die("bad response to %s: %s", "RETR", buf); 442 bb_error_msg_and_die("bad response to RETR: %s", buf);
441 } 443 }
442 444
443 445
@@ -446,7 +448,7 @@ int wget_main(int argc, char **argv)
446 */ 448 */
447 if (chunked) { 449 if (chunked) {
448 fgets(buf, sizeof(buf), dfp); 450 fgets(buf, sizeof(buf), dfp);
449 content_len = STRTOOFF(buf, (char **) NULL, 16); 451 content_len = STRTOOFF(buf, NULL, 16);
450 /* FIXME: error check?? */ 452 /* FIXME: error check?? */
451 } 453 }
452 454
@@ -480,7 +482,7 @@ int wget_main(int argc, char **argv)
480 if (chunked) { 482 if (chunked) {
481 safe_fgets(buf, sizeof(buf), dfp); /* This is a newline */ 483 safe_fgets(buf, sizeof(buf), dfp); /* This is a newline */
482 safe_fgets(buf, sizeof(buf), dfp); 484 safe_fgets(buf, sizeof(buf), dfp);
483 content_len = STRTOOFF(buf, (char **) NULL, 16); 485 content_len = STRTOOFF(buf, NULL, 16);
484 /* FIXME: error check? */ 486 /* FIXME: error check? */
485 if (content_len == 0) { 487 if (content_len == 0) {
486 chunked = 0; /* all done! */ 488 chunked = 0; /* all done! */
diff --git a/procps/renice.c b/procps/renice.c
index 65674a4ee..08e0dc264 100644
--- a/procps/renice.c
+++ b/procps/renice.c
@@ -87,7 +87,8 @@ int renice_main(int argc, char **argv)
87 } 87 }
88 who = p->pw_uid; 88 who = p->pw_uid;
89 } else { 89 } else {
90 if (safe_strtou(arg, &who)) { 90 who = bb_strtou(arg, NULL, 10);
91 if (errno) {
91 bb_error_msg("bad value: %s", arg); 92 bb_error_msg("bad value: %s", arg);
92 goto HAD_ERROR; 93 goto HAD_ERROR;
93 } 94 }