aboutsummaryrefslogtreecommitdiff
path: root/libbb
diff options
context:
space:
mode:
authorvda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277>2006-10-08 12:49:22 +0000
committervda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277>2006-10-08 12:49:22 +0000
commit87d25a2b8535dc627a02eb539fa3946be2a24647 (patch)
treefc4d14a910593d1235318bb36abe5e9f72d2039e /libbb
parent81177b14907e73f11560f69e0b4ec34371f1a7d5 (diff)
downloadbusybox-w32-87d25a2b8535dc627a02eb539fa3946be2a24647.tar.gz
busybox-w32-87d25a2b8535dc627a02eb539fa3946be2a24647.tar.bz2
busybox-w32-87d25a2b8535dc627a02eb539fa3946be2a24647.zip
attempt to regularize atoi mess.
git-svn-id: svn://busybox.net/trunk/busybox@16342 69ca8d6d-28ef-0310-b511-8ec308f3f277
Diffstat (limited to 'libbb')
-rw-r--r--libbb/Kbuild6
-rw-r--r--libbb/loop.c60
-rw-r--r--libbb/parse_number.c50
-rw-r--r--libbb/safe_strtol.c102
-rw-r--r--libbb/xatol.c210
-rw-r--r--libbb/xgetlarg.c32
-rw-r--r--libbb/xgetularg.c127
7 files changed, 326 insertions, 261 deletions
diff --git a/libbb/Kbuild b/libbb/Kbuild
index 909f527ba..4e992ef5b 100644
--- a/libbb/Kbuild
+++ b/libbb/Kbuild
@@ -15,7 +15,7 @@ lib-y:= \
15 human_readable.o inet_common.o inode_hash.o isdirectory.o \ 15 human_readable.o inet_common.o inode_hash.o isdirectory.o \
16 kernel_version.o last_char_is.o login.o \ 16 kernel_version.o last_char_is.o login.o \
17 make_directory.o md5.o mode_string.o mtab_file.o \ 17 make_directory.o md5.o mode_string.o mtab_file.o \
18 obscure.o parse_mode.o parse_number.o perror_msg.o \ 18 obscure.o parse_mode.o perror_msg.o \
19 perror_msg_and_die.o get_console.o \ 19 perror_msg_and_die.o get_console.o \
20 process_escape_sequence.o procps.o \ 20 process_escape_sequence.o procps.o \
21 recursive_action.o remove_file.o \ 21 recursive_action.o remove_file.o \
@@ -23,7 +23,7 @@ lib-y:= \
23 safe_strncpy.o setup_environment.o sha1.o simplify_path.o \ 23 safe_strncpy.o setup_environment.o sha1.o simplify_path.o \
24 trim.o u_signal_names.o vdprintf.o verror_msg.o \ 24 trim.o u_signal_names.o vdprintf.o verror_msg.o \
25 vherror_msg.o vperror_msg.o wfopen.o xconnect.o xgetcwd.o \ 25 vherror_msg.o vperror_msg.o wfopen.o xconnect.o xgetcwd.o \
26 xgethostbyname.o xgethostbyname2.o xreadlink.o xgetlarg.o \ 26 xgethostbyname.o xgethostbyname2.o xreadlink.o \
27 fclose_nonstdin.o fflush_stdout_and_exit.o \ 27 fclose_nonstdin.o fflush_stdout_and_exit.o \
28 getopt32.o default_error_retval.o wfopen_input.o speed_table.o \ 28 getopt32.o default_error_retval.o wfopen_input.o speed_table.o \
29 perror_nomsg_and_die.o perror_nomsg.o skip_whitespace.o bb_askpass.o \ 29 perror_nomsg_and_die.o perror_nomsg.o skip_whitespace.o bb_askpass.o \
@@ -55,7 +55,7 @@ lib-$(CONFIG_DEVFSD) += xregcomp.o
55lib-y += messages.o 55lib-y += messages.o
56lib-y += xfuncs.o 56lib-y += xfuncs.o
57lib-y += printf.o 57lib-y += printf.o
58lib-y += xgetularg.o 58lib-y += xatol.o
59lib-y += safe_strtol.o 59lib-y += safe_strtol.o
60lib-y += bb_pwd.o 60lib-y += bb_pwd.o
61lib-y += llist.o 61lib-y += llist.o
diff --git a/libbb/loop.c b/libbb/loop.c
index d22b39800..1b296d99b 100644
--- a/libbb/loop.c
+++ b/libbb/loop.c
@@ -48,11 +48,12 @@ char *query_loop(const char *device)
48{ 48{
49 int fd; 49 int fd;
50 bb_loop_info loopinfo; 50 bb_loop_info loopinfo;
51 char *dev=0; 51 char *dev = 0;
52 52
53 if ((fd = open(device, O_RDONLY)) < 0) return 0; 53 fd = open(device, O_RDONLY);
54 if (fd < 0) return 0;
54 if (!ioctl(fd, BB_LOOP_GET_STATUS, &loopinfo)) 55 if (!ioctl(fd, BB_LOOP_GET_STATUS, &loopinfo))
55 dev=xasprintf("%ld %s", (long) loopinfo.lo_offset, 56 dev = xasprintf("%ld %s", (long) loopinfo.lo_offset,
56 (char *)loopinfo.lo_file_name); 57 (char *)loopinfo.lo_file_name);
57 close(fd); 58 close(fd);
58 59
@@ -64,8 +65,9 @@ int del_loop(const char *device)
64{ 65{
65 int fd, rc; 66 int fd, rc;
66 67
67 if ((fd = open(device, O_RDONLY)) < 0) return 1; 68 fd = open(device, O_RDONLY);
68 rc=ioctl(fd, LOOP_CLR_FD, 0); 69 if (fd < 0) return 1;
70 rc = ioctl(fd, LOOP_CLR_FD, 0);
69 close(fd); 71 close(fd);
70 72
71 return rc; 73 return rc;
@@ -77,7 +79,7 @@ int del_loop(const char *device)
77 search will re-use an existing loop device already bound to that 79 search will re-use an existing loop device already bound to that
78 file/offset if it finds one. 80 file/offset if it finds one.
79 */ 81 */
80int set_loop(char **device, const char *file, int offset) 82int set_loop(char **device, const char *file, unsigned long long offset)
81{ 83{
82 char dev[20], *try; 84 char dev[20], *try;
83 bb_loop_info loopinfo; 85 bb_loop_info loopinfo;
@@ -85,34 +87,43 @@ int set_loop(char **device, const char *file, int offset)
85 int i, dfd, ffd, mode, rc=-1; 87 int i, dfd, ffd, mode, rc=-1;
86 88
87 /* Open the file. Barf if this doesn't work. */ 89 /* Open the file. Barf if this doesn't work. */
88 if((ffd = open(file, mode=O_RDWR))<0 && (ffd = open(file,mode=O_RDONLY))<0) 90 mode = O_RDWR;
89 return -errno; 91 ffd = open(file, mode);
92 if (ffd < 0) {
93 mode = O_RDONLY;
94 ffd = open(file, mode);
95 if (ffd < 0)
96 return -errno;
97 }
90 98
91 /* Find a loop device. */ 99 /* Find a loop device. */
92 try=*device ? : dev; 100 try = *device ? : dev;
93 for(i=0;rc;i++) { 101 for (i=0;rc;i++) {
94 sprintf(dev, LOOP_FORMAT, i); 102 sprintf(dev, LOOP_FORMAT, i);
95 103
96 /* Ran out of block devices, return failure. */ 104 /* Ran out of block devices, return failure. */
97 if(stat(try, &statbuf) || !S_ISBLK(statbuf.st_mode)) { 105 if (stat(try, &statbuf) || !S_ISBLK(statbuf.st_mode)) {
98 rc=-ENOENT; 106 rc=-ENOENT;
99 break; 107 break;
100 } 108 }
101 /* Open the sucker and check its loopiness. */ 109 /* Open the sucker and check its loopiness. */
102 if((dfd=open(try, mode))<0 && errno==EROFS) 110 dfd = open(try, mode);
103 dfd=open(try, mode = O_RDONLY); 111 if (dfd < 0 && errno == EROFS) {
104 if(dfd<0) goto try_again; 112 mode = O_RDONLY;
113 dfd = open(try, mode);
114 }
115 if (dfd < 0) goto try_again;
105 116
106 rc=ioctl(dfd, BB_LOOP_GET_STATUS, &loopinfo); 117 rc = ioctl(dfd, BB_LOOP_GET_STATUS, &loopinfo);
107 118
108 /* If device free, claim it. */ 119 /* If device free, claim it. */
109 if(rc && errno==ENXIO) { 120 if (rc && errno == ENXIO) {
110 memset(&loopinfo, 0, sizeof(loopinfo)); 121 memset(&loopinfo, 0, sizeof(loopinfo));
111 safe_strncpy((char *)loopinfo.lo_file_name, file, LO_NAME_SIZE); 122 safe_strncpy((char *)loopinfo.lo_file_name, file, LO_NAME_SIZE);
112 loopinfo.lo_offset = offset; 123 loopinfo.lo_offset = offset;
113 /* Associate free loop device with file. */ 124 /* Associate free loop device with file. */
114 if(!ioctl(dfd, LOOP_SET_FD, ffd)) { 125 if (!ioctl(dfd, LOOP_SET_FD, ffd)) {
115 if (!ioctl(dfd, BB_LOOP_SET_STATUS, &loopinfo)) rc=0; 126 if (!ioctl(dfd, BB_LOOP_SET_STATUS, &loopinfo)) rc = 0;
116 else ioctl(dfd, LOOP_CLR_FD, 0); 127 else ioctl(dfd, LOOP_CLR_FD, 0);
117 } 128 }
118 129
@@ -121,15 +132,16 @@ int set_loop(char **device, const char *file, int offset)
121 file isn't pretty either. In general, mounting the same file twice 132 file isn't pretty either. In general, mounting the same file twice
122 without using losetup manually is problematic.) 133 without using losetup manually is problematic.)
123 */ 134 */
124 } else if(strcmp(file,(char *)loopinfo.lo_file_name) 135 } else if (strcmp(file,(char *)loopinfo.lo_file_name)
125 || offset!=loopinfo.lo_offset) rc=-1; 136 || offset!=loopinfo.lo_offset) rc = -1;
126 close(dfd); 137 close(dfd);
127try_again: 138try_again:
128 if(*device) break; 139 if (*device) break;
129 } 140 }
130 close(ffd); 141 close(ffd);
131 if(!rc) { 142 if (!rc) {
132 if(!*device) *device=strdup(dev); 143 if (!*device) *device = strdup(dev);
133 return mode==O_RDONLY ? 1 : 0; 144 return mode==O_RDONLY ? 1 : 0;
134 } else return rc; 145 }
146 return rc;
135} 147}
diff --git a/libbb/parse_number.c b/libbb/parse_number.c
deleted file mode 100644
index c7dafb7f0..000000000
--- a/libbb/parse_number.c
+++ /dev/null
@@ -1,50 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * bb_xparse_number implementation for busybox
4 *
5 * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org>
6 *
7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
8 */
9
10#include <stdlib.h>
11#include <string.h>
12#include <limits.h>
13#include <errno.h>
14#include <assert.h>
15#include "libbb.h"
16
17unsigned long bb_xparse_number(const char *numstr,
18 const struct suffix_mult *suffixes)
19{
20 unsigned long int r;
21 char *e;
22 int old_errno;
23
24 /* Since this is a lib function, we're not allowed to reset errno to 0.
25 * Doing so could break an app that is deferring checking of errno.
26 * So, save the old value so that we can restore it if successful. */
27 old_errno = errno;
28 errno = 0;
29 r = strtoul(numstr, &e, 10);
30
31 if ((numstr != e) && !errno) {
32 errno = old_errno; /* Ok. So restore errno. */
33 if (!*e) {
34 return r;
35 }
36 if (suffixes) {
37 assert(suffixes->suffix); /* No nul suffixes. */
38 do {
39 if (strcmp(suffixes->suffix, e) == 0) {
40 if (ULONG_MAX / suffixes->mult < r) { /* Overflow! */
41 break;
42 }
43 return r * suffixes->mult;
44 }
45 ++suffixes;
46 } while (suffixes->suffix);
47 }
48 }
49 bb_error_msg_and_die("invalid number '%s'", numstr);
50}
diff --git a/libbb/safe_strtol.c b/libbb/safe_strtol.c
index 027fc1e62..a7f012fbc 100644
--- a/libbb/safe_strtol.c
+++ b/libbb/safe_strtol.c
@@ -7,21 +7,10 @@
7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
8 */ 8 */
9 9
10#include <stdlib.h>
11#include <errno.h>
12#include <assert.h> 10#include <assert.h>
13#include "libbb.h" 11#include "libbb.h"
14 12
15int safe_strtoi(char *arg, int* value) 13int safe_strtod(const char *arg, double* value)
16{
17 int error;
18 long lvalue = *value;
19 error = safe_strtol(arg, &lvalue);
20 *value = (int) lvalue;
21 return error;
22}
23
24int safe_strtod(char *arg, double* value)
25{ 14{
26 char *endptr; 15 char *endptr;
27 int errno_save = errno; 16 int errno_save = errno;
@@ -29,69 +18,132 @@ int safe_strtod(char *arg, double* value)
29 assert(arg!=NULL); 18 assert(arg!=NULL);
30 errno = 0; 19 errno = 0;
31 *value = strtod(arg, &endptr); 20 *value = strtod(arg, &endptr);
32 if (errno != 0 || *endptr!='\0' || endptr==arg) { 21 if (errno != 0 || *endptr != '\0' || endptr == arg) {
33 return 1; 22 return 1;
34 } 23 }
35 errno = errno_save; 24 errno = errno_save;
36 return 0; 25 return 0;
37} 26}
38 27
39int safe_strtol(char *arg, long* value) 28int safe_strtoull(const char *arg, unsigned long long* value)
40{ 29{
41 char *endptr; 30 char *endptr;
42 int errno_save = errno; 31 int errno_save = errno;
43 32
44 assert(arg!=NULL); 33 assert(arg!=NULL);
34 if (!isdigit(arg[0])) /* strtouXX takes minus signs w/o error! :( */
35 return 1;
45 errno = 0; 36 errno = 0;
46 *value = strtol(arg, &endptr, 0); 37 *value = strtoull(arg, &endptr, 0);
47 if (errno != 0 || *endptr!='\0' || endptr==arg) { 38 if (errno != 0 || *endptr != '\0' || endptr == arg) {
48 return 1; 39 return 1;
49 } 40 }
50 errno = errno_save; 41 errno = errno_save;
51 return 0; 42 return 0;
52} 43}
53 44
54int safe_strtoul(char *arg, unsigned long* value) 45int safe_strtoll(const char *arg, long long* value)
55{ 46{
56 char *endptr; 47 char *endptr;
57 int errno_save = errno; 48 int errno_save = errno;
58 49
59 assert(arg!=NULL); 50 assert(arg!=NULL);
60 errno = 0; 51 errno = 0;
61 *value = strtoul(arg, &endptr, 0); 52 *value = strtoll(arg, &endptr, 0);
62 if (errno != 0 || *endptr!='\0' || endptr==arg) { 53 if (errno != 0 || *endptr != '\0' || endptr == arg) {
63 return 1; 54 return 1;
64 } 55 }
65 errno = errno_save; 56 errno = errno_save;
66 return 0; 57 return 0;
67} 58}
68 59
69int safe_strtoll(char *arg, long long* value) 60int safe_strtoul(const char *arg, unsigned long* value)
70{ 61{
71 char *endptr; 62 char *endptr;
72 int errno_save = errno; 63 int errno_save = errno;
73 64
74 assert(arg!=NULL); 65 assert(arg!=NULL);
66 if (!isdigit(arg[0])) /* strtouXX takes minus signs w/o error! :( */
67 return 1;
75 errno = 0; 68 errno = 0;
76 *value = strtoll(arg, &endptr, 0); 69 *value = strtoul(arg, &endptr, 0);
77 if (errno != 0 || *endptr!='\0' || endptr==arg) { 70 if (errno != 0 || *endptr != '\0' || endptr == arg) {
78 return 1; 71 return 1;
79 } 72 }
80 errno = errno_save; 73 errno = errno_save;
81 return 0; 74 return 0;
82} 75}
83 76
84int safe_strtoull(char *arg, unsigned long long* value) 77int safe_strtol(const char *arg, long* value)
85{ 78{
86 char *endptr; 79 char *endptr;
87 int errno_save = errno; 80 int errno_save = errno;
88 81
89 assert(arg!=NULL); 82 assert(arg!=NULL);
90 errno = 0; 83 errno = 0;
91 *value = strtoull(arg, &endptr, 0); 84 *value = strtol(arg, &endptr, 0);
92 if (errno != 0 || *endptr!='\0' || endptr==arg) { 85 if (errno != 0 || *endptr != '\0' || endptr == arg) {
93 return 1; 86 return 1;
94 } 87 }
95 errno = errno_save; 88 errno = errno_save;
96 return 0; 89 return 0;
97} 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 if (sizeof(long) == sizeof(int)) {
114 return safe_strtol(arg, (long*)value);
115 } else {
116 int error;
117 long 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}
125
126int safe_strtou(const char *arg, unsigned* value)
127{
128 if (sizeof(unsigned long) == sizeof(unsigned)) {
129 return safe_strtoul(arg, (unsigned long*)value);
130 } else {
131 int error;
132 unsigned long lvalue = *value;
133 error = safe_strtoul(arg, &lvalue);
134 if (lvalue > UINT_MAX)
135 return 1;
136 *value = (unsigned) lvalue;
137 return error;
138 }
139}
140
141int BUG_safe_strtou32_unimplemented(void);
142int safe_strtou32(const char *arg, uint32_t* value)
143{
144 if (sizeof(uint32_t) == sizeof(unsigned))
145 return safe_strtou(arg, (unsigned*)value);
146 if (sizeof(uint32_t) == sizeof(unsigned long))
147 return safe_strtoul(arg, (unsigned long*)value);
148 return BUG_safe_strtou32_unimplemented();
149}
diff --git a/libbb/xatol.c b/libbb/xatol.c
new file mode 100644
index 000000000..82250a7bb
--- /dev/null
+++ b/libbb/xatol.c
@@ -0,0 +1,210 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * ascii-to-numbers implementations for busybox
4 *
5 * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org>
6 *
7 * Licensed under GPLv2, see file LICENSE in this tarball for details.
8 */
9
10#include "libbb.h"
11
12unsigned long long xatoull(const char *numstr)
13{
14 unsigned long long r;
15 int old_errno;
16 char *e;
17 if ((*numstr == '-') || (isspace)(*numstr))
18 bb_error_msg_and_die("invalid number '%s'", numstr);
19 old_errno = errno;
20 errno = 0;
21 r = strtoull(numstr, &e, 10);
22 if (errno || (numstr == e) || *e)
23 /* Error / no digits / illegal trailing chars */
24 bb_error_msg_and_die("invalid number '%s'", numstr);
25 /* No error. So restore errno. */
26 errno = old_errno;
27 return r;
28}
29
30unsigned long xstrtoul_range_sfx(const char *numstr, int base,
31 unsigned long lower,
32 unsigned long upper,
33 const struct suffix_mult *suffixes)
34{
35 unsigned long r;
36 int old_errno;
37 char *e;
38
39 /* Disallow '-' and any leading whitespace. Speed isn't critical here
40 * since we're parsing commandline args. So make sure we get the
41 * actual isspace function rather than a lnumstrer macro implementaion. */
42 if ((*numstr == '-') || (isspace)(*numstr))
43 goto inval;
44
45 /* Since this is a lib function, we're not allowed to reset errno to 0.
46 * Doing so could break an app that is deferring checking of errno.
47 * So, save the old value so that we can restore it if successful. */
48 old_errno = errno;
49 errno = 0;
50 r = strtoul(numstr, &e, base);
51 /* Do the initial validity check. Note: The standards do not
52 * guarantee that errno is set if no digits were found. So we
53 * must test for this explicitly. */
54 if (errno || (numstr == e))
55 goto inval; /* error / no digits / illegal trailing chars */
56
57 errno = old_errno; /* Ok. So restore errno. */
58
59 /* Do optional suffix parsing. Allow 'empty' suffix tables.
60 * Note that we also allow nul suffixes with associated multipliers,
61 * to allow for scaling of the numstr by some default multiplier. */
62 if (suffixes) {
63 while (suffixes->suffix) {
64 if (strcmp(suffixes->suffix, e) == 0) {
65 if (ULONG_MAX / suffixes->mult < r)
66 goto range; /* overflow! */
67 ++e;
68 r *= suffixes->mult;
69 break;
70 }
71 ++suffixes;
72 }
73 }
74
75 /* Note: trailing space is an error.
76 It would be easy enough to allow though if desired. */
77 if (*e)
78 goto inval;
79 /* Finally, check for range limits. */
80 if (r >= lower && r <= upper)
81 return r;
82 range:
83 bb_error_msg_and_die("number %s is not in %lu..%lu range",
84 numstr, lower, upper);
85 inval:
86 bb_error_msg_and_die("invalid number '%s'", numstr);
87}
88
89unsigned long xstrtoul_range(const char *numstr, int base,
90 unsigned long lower,
91 unsigned long upper)
92{
93 return xstrtoul_range_sfx(numstr, base, lower, upper, NULL);
94}
95
96unsigned long xstrtoul(const char *numstr, int base)
97{
98 return xstrtoul_range_sfx(numstr, base, 0, ULONG_MAX, NULL);
99}
100
101unsigned long xatoul_range_sfx(const char *numstr,
102 unsigned long lower,
103 unsigned long upper,
104 const struct suffix_mult *suffixes)
105{
106 return xstrtoul_range_sfx(numstr, 10, lower, upper, suffixes);
107}
108
109unsigned long xatoul_sfx(const char *numstr,
110 const struct suffix_mult *suffixes)
111{
112 return xstrtoul_range_sfx(numstr, 10, 0, ULONG_MAX, suffixes);
113}
114
115unsigned long xatoul_range(const char *numstr,
116 unsigned long lower,
117 unsigned long upper)
118{
119 return xstrtol_range_sfx(numstr, 10, lower, upper, NULL);
120}
121
122unsigned long xatoul(const char *numstr)
123{
124 return xatoul_sfx(numstr, NULL);
125}
126
127/* Signed ones */
128
129long xstrtol_range_sfx(const char *numstr, int base,
130 long lower,
131 long upper,
132 const struct suffix_mult *suffixes)
133{
134 unsigned long u = LONG_MAX;
135 long r;
136 const char *p = numstr;
137
138 if ((p[0] == '-') && (p[1] != '+')) {
139 ++p;
140 ++u; /* two's complement */
141 }
142
143 r = xstrtoul_range_sfx(p, base, 0, u, suffixes);
144
145 if (*numstr == '-') {
146 r = -r;
147 }
148
149 if (r < lower || r > upper) {
150 bb_error_msg_and_die("number %s is not in %ld..%ld range",
151 numstr, lower, upper);
152 }
153
154 return r;
155}
156
157long xstrtol_range(const char *numstr, int base, long lower, long upper)
158{
159 return xstrtol_range_sfx(numstr, base, lower, upper, NULL);
160}
161
162long xatol_range_sfx(const char *numstr,
163 long lower,
164 long upper,
165 const struct suffix_mult *suffixes)
166{
167 return xstrtol_range_sfx(numstr, 10, lower, upper, suffixes);
168}
169
170long xatol_range(const char *numstr, long lower, long upper)
171{
172 return xstrtol_range_sfx(numstr, 10, lower, upper, NULL);
173}
174
175long xatol_sfx(const char *numstr, const struct suffix_mult *suffixes)
176{
177 return xstrtol_range_sfx(numstr, 10, LONG_MIN, LONG_MAX, suffixes);
178}
179
180long xatol(const char *numstr)
181{
182 return xstrtol_range_sfx(numstr, 10, LONG_MIN, LONG_MAX, NULL);
183}
184
185/* Others */
186
187unsigned xatou(const char *numstr)
188{
189 return xatoul_range(numstr, 0, UINT_MAX);
190}
191
192int xatoi(const char *numstr)
193{
194 return xatol_range(numstr, INT_MIN, INT_MAX);
195}
196
197int xatoi_u(const char *numstr)
198{
199 return xatoul_range(numstr, 0, INT_MAX);
200}
201
202uint32_t xatou32(const char *numstr)
203{
204 return xatoul_range(numstr, 0, 0xffffffff);
205}
206
207uint16_t xatou16(const char *numstr)
208{
209 return xatoul_range(numstr, 0, 0xffff);
210}
diff --git a/libbb/xgetlarg.c b/libbb/xgetlarg.c
deleted file mode 100644
index 5b1e7b9d5..000000000
--- a/libbb/xgetlarg.c
+++ /dev/null
@@ -1,32 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * Copyright (C) 2003-2004 Erik Andersen <andersen@codepoet.org>
4 *
5 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
6 */
7
8#include <stdio.h>
9#include <stdlib.h>
10#include <getopt.h>
11#include <errno.h>
12#include <assert.h>
13#include <ctype.h>
14
15#include "libbb.h"
16
17long bb_xgetlarg(const char *arg, int base, long lower, long upper)
18{
19 long result;
20 char *endptr;
21 int errno_save = errno;
22
23 if (ENABLE_DEBUG && arg==NULL)
24 bb_error_msg_and_die("Null in xgetlarg.");
25
26 errno = 0;
27 result = strtol(arg, &endptr, base);
28 if (errno != 0 || *endptr!='\0' || endptr==arg || result < lower || result > upper)
29 bb_show_usage();
30 errno = errno_save;
31 return result;
32}
diff --git a/libbb/xgetularg.c b/libbb/xgetularg.c
deleted file mode 100644
index 17ba581f7..000000000
--- a/libbb/xgetularg.c
+++ /dev/null
@@ -1,127 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * xgetularg* implementations for busybox
4 *
5 * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org>
6 *
7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
8 */
9
10#include <stdlib.h>
11#include <string.h>
12#include <limits.h>
13#include <ctype.h>
14#include <errno.h>
15#include <assert.h>
16#include "libbb.h"
17
18unsigned long bb_xgetularg_bnd_sfx(const char *arg, int base,
19 unsigned long lower,
20 unsigned long upper,
21 const struct suffix_mult *suffixes)
22{
23 unsigned long r;
24 int old_errno;
25 char *e;
26
27 assert(arg);
28
29 /* Disallow '-' and any leading whitespace. Speed isn't critical here
30 * since we're parsing commandline args. So make sure we get the
31 * actual isspace function rather than a larger macro implementaion. */
32 if ((*arg == '-') || (isspace)(*arg)) {
33 bb_show_usage();
34 }
35
36 /* Since this is a lib function, we're not allowed to reset errno to 0.
37 * Doing so could break an app that is deferring checking of errno.
38 * So, save the old value so that we can restore it if successful. */
39 old_errno = errno;
40 errno = 0;
41 r = strtoul(arg, &e, base);
42 /* Do the initial validity check. Note: The standards do not
43 * guarantee that errno is set if no digits were found. So we
44 * must test for this explicitly. */
45 if (errno || (arg == e)) { /* error or no digits */
46 bb_show_usage();
47 }
48 errno = old_errno; /* Ok. So restore errno. */
49
50 /* Do optional suffix parsing. Allow 'empty' suffix tables.
51 * Note that we also all nul suffixes with associated multipliers,
52 * to allow for scaling of the arg by some default multiplier. */
53
54 if (suffixes) {
55 while (suffixes->suffix) {
56 if (strcmp(suffixes->suffix, e) == 0) {
57 if (ULONG_MAX / suffixes->mult < r) { /* Overflow! */
58 bb_show_usage();
59 }
60 ++e;
61 r *= suffixes->mult;
62 break;
63 }
64 ++suffixes;
65 }
66 }
67
68 /* Finally, check for illegal trailing chars and range limits. */
69 /* Note: although we allow leading space (via stroul), trailing space
70 * is an error. It would be easy enough to allow though if desired. */
71 if (*e || (r < lower) || (r > upper)) {
72 bb_show_usage();
73 }
74
75 return r;
76}
77
78long bb_xgetlarg_bnd_sfx(const char *arg, int base,
79 long lower,
80 long upper,
81 const struct suffix_mult *suffixes)
82{
83 unsigned long u = LONG_MAX;
84 long r;
85 const char *p = arg;
86
87 if ((*p == '-') && (p[1] != '+')) {
88 ++p;
89 ++u; /* two's complement */
90 }
91
92 r = bb_xgetularg_bnd_sfx(p, base, 0, u, suffixes);
93
94 if (*arg == '-') {
95 r = -r;
96 }
97
98 if ((r < lower) || (r > upper)) {
99 bb_show_usage();
100 }
101
102 return r;
103}
104
105long bb_xgetlarg10_sfx(const char *arg, const struct suffix_mult *suffixes)
106{
107 return bb_xgetlarg_bnd_sfx(arg, 10, LONG_MIN, LONG_MAX, suffixes);
108}
109
110unsigned long bb_xgetularg_bnd(const char *arg, int base,
111 unsigned long lower,
112 unsigned long upper)
113{
114 return bb_xgetularg_bnd_sfx(arg, base, lower, upper, NULL);
115}
116
117unsigned long bb_xgetularg10_bnd(const char *arg,
118 unsigned long lower,
119 unsigned long upper)
120{
121 return bb_xgetularg_bnd(arg, 10, lower, upper);
122}
123
124unsigned long bb_xgetularg10(const char *arg)
125{
126 return bb_xgetularg10_bnd(arg, 0, ULONG_MAX);
127}