diff options
author | Kiyoshi Aman <kiyoshi.aman+adelie@gmail.com> | 2019-05-16 11:47:54 -0500 |
---|---|---|
committer | Kiyoshi Aman <kiyoshi.aman+adelie@gmail.com> | 2019-05-16 11:47:54 -0500 |
commit | 5fa3142cdbb67cbb8287b2ec4fc35ee6532b3c6d (patch) | |
tree | 6abb866f965d62c64868a01950e53e0e6c21f06a | |
parent | 5aef04248e45a1a0ce74d96e78abd871048369bf (diff) | |
download | userland-5fa3142cdbb67cbb8287b2ec4fc35ee6532b3c6d.tar.gz userland-5fa3142cdbb67cbb8287b2ec4fc35ee6532b3c6d.tar.bz2 userland-5fa3142cdbb67cbb8287b2ec4fc35ee6532b3c6d.tar.xz userland-5fa3142cdbb67cbb8287b2ec4fc35ee6532b3c6d.zip |
bin/dd: make buildable with libbsd
-rw-r--r-- | bin/dd/args.c | 33 | ||||
-rw-r--r-- | bin/dd/conv.c | 23 | ||||
-rw-r--r-- | bin/dd/conv_tab.c | 9 | ||||
-rw-r--r-- | bin/dd/dd.c | 24 | ||||
-rw-r--r-- | bin/dd/dd.h | 18 | ||||
-rw-r--r-- | bin/dd/dd_hostops.c | 6 | ||||
-rw-r--r-- | bin/dd/dd_rumpops.c | 52 | ||||
-rw-r--r-- | bin/dd/extern.h | 32 | ||||
-rw-r--r-- | bin/dd/misc.c | 13 | ||||
-rw-r--r-- | bin/dd/position.c | 10 | ||||
-rw-r--r-- | bin/dd/strsuftoll.c | 234 |
11 files changed, 287 insertions, 167 deletions
diff --git a/bin/dd/args.c b/bin/dd/args.c index 748f52c..ff4cc58 100644 --- a/bin/dd/args.c +++ b/bin/dd/args.c @@ -33,15 +33,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)args.c 8.3 (Berkeley) 4/2/94"; -#else -__RCSID("$NetBSD: args.c,v 1.40 2019/01/30 01:40:02 mrg Exp $"); -#endif -#endif /* not lint */ - #include <sys/types.h> #include <sys/time.h> @@ -60,22 +51,18 @@ __RCSID("$NetBSD: args.c,v 1.40 2019/01/30 01:40:02 mrg Exp $"); static int c_arg(const void *, const void *); -#ifdef NO_MSGFMT -static void f_msgfmt(char *) __dead; -#else static void f_msgfmt(char *); -#endif /* NO_MSGFMT */ #ifdef NO_CONV -static void f_conv(char *) __dead; +static void f_conv(char *); #else static void f_conv(char *); static int c_conv(const void *, const void *); #endif /* NO_CONV */ #ifdef NO_IOFLAG -static void f_iflag(char *) __dead; -static void f_oflag(char *) __dead; +static void f_iflag(char *); +static void f_oflag(char *); #else static void f_iflag(char *); static void f_oflag(char *); @@ -120,6 +107,8 @@ static const struct arg { { "seek", f_seek, C_SEEK, C_SEEK }, { "skip", f_skip, C_SKIP, C_SKIP }, }; +/* number of entries in the above */ +const int args_count = 17; /* * args -- parse JCL syntax of dd. @@ -149,8 +138,7 @@ jcl(char **argv) /* NOTREACHED */ } tmp.name = oper; - if (!(ap = bsearch(&tmp, args, - __arraycount(args), sizeof(*args), c_arg))) { + if (!(ap = bsearch(&tmp, args, args_count, sizeof(*args), c_arg))) { errx(EXIT_FAILURE, "unknown operand %s", tmp.name); /* NOTREACHED */ } @@ -371,6 +359,8 @@ static const struct conv { * conversions to the C_BS check in the jcl routine above. */ }; +/* number of entries in the above table */ +const int clist_count = 16; static void f_conv(char *arg) @@ -379,8 +369,7 @@ f_conv(char *arg) while (arg != NULL) { tmp.name = strsep(&arg, ","); - if (!(cp = bsearch(&tmp, clist, - __arraycount(clist), sizeof(*clist), c_conv))) { + if (!(cp = bsearch(&tmp, clist, clist_count, sizeof(*clist), c_conv))) { errx(EXIT_FAILURE, "unknown conversion %s", tmp.name); /* NOTREACHED */ } @@ -434,8 +423,8 @@ f_oflag(char *arg) #ifndef NO_IOFLAG static const struct ioflag { const char *name; - u_int set; - u_int allowed; + uint32_t set; + uint32_t allowed; } olist[] = { /* the array needs to be sorted by the first column so bsearch() can be used to find commands quickly */ diff --git a/bin/dd/conv.c b/bin/dd/conv.c index d4a8a09..4c85c9d 100644 --- a/bin/dd/conv.c +++ b/bin/dd/conv.c @@ -33,15 +33,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)conv.c 8.3 (Berkeley) 4/2/94"; -#else -__RCSID("$NetBSD: conv.c,v 1.17 2003/08/07 09:05:10 agc Exp $"); -#endif -#endif /* not lint */ - #include <sys/param.h> #include <sys/time.h> @@ -62,8 +53,8 @@ void def(void) { uint64_t cnt; - u_char *inp; - const u_char *t; + uint8_t *inp; + const uint8_t *t; if ((t = ctab) != NULL) for (inp = in.dbp - (cnt = in.dbrcnt); cnt--; ++inp) @@ -119,8 +110,8 @@ block(void) static int intrunc; int ch = 0; /* pacify gcc */ uint64_t cnt, maxlen; - u_char *inp, *outp; - const u_char *t; + uint8_t *inp, *outp; + const uint8_t *t; /* * Record truncation can cross block boundaries. If currently in a @@ -230,8 +221,8 @@ void unblock(void) { uint64_t cnt; - u_char *inp; - const u_char *t; + uint8_t *inp; + const uint8_t *t; /* Translation and case conversion. */ if ((t = ctab) != NULL) @@ -264,7 +255,7 @@ void unblock_close(void) { uint64_t cnt; - u_char *t; + uint8_t *t; if (in.dbcnt) { warnx("%s: short input record", in.name); diff --git a/bin/dd/conv_tab.c b/bin/dd/conv_tab.c index 89d32da..549df80 100644 --- a/bin/dd/conv_tab.c +++ b/bin/dd/conv_tab.c @@ -33,15 +33,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)conv_tab.c 8.1 (Berkeley) 5/31/93"; -#else -__RCSID("$NetBSD: conv_tab.c,v 1.9 2003/08/07 09:05:10 agc Exp $"); -#endif -#endif /* not lint */ - #include <sys/types.h> /* diff --git a/bin/dd/dd.c b/bin/dd/dd.c index c4fb1e8..aa2897d 100644 --- a/bin/dd/dd.c +++ b/bin/dd/dd.c @@ -33,20 +33,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -#ifndef lint -__COPYRIGHT("@(#) Copyright (c) 1991, 1993, 1994\ - The Regents of the University of California. All rights reserved."); -#endif /* not lint */ - -#ifndef lint -#if 0 -static char sccsid[] = "@(#)dd.c 8.5 (Berkeley) 4/2/94"; -#else -__RCSID("$NetBSD: dd.c,v 1.51 2016/09/05 01:00:07 sevan Exp $"); -#endif -#endif /* not lint */ - #include <sys/param.h> #include <sys/stat.h> #include <sys/ioctl.h> @@ -61,6 +47,7 @@ __RCSID("$NetBSD: dd.c,v 1.51 2016/09/05 01:00:07 sevan Exp $"); #include <signal.h> #include <stdio.h> #include <stdlib.h> +#include <bsd/stdlib.h> #include <string.h> #include <unistd.h> @@ -135,10 +122,10 @@ main(int argc, char *argv[]) #endif setup(); - (void)signal(SIGINFO, summaryx); + (void)signal(SIGHUP, summaryx); (void)signal(SIGINT, terminate); (void)sigemptyset(&infoset); - (void)sigaddset(&infoset, SIGINFO); + (void)sigaddset(&infoset, SIGHUP); (void)atexit(summary); @@ -203,15 +190,14 @@ setup(void) #endif /* NO_IOFLAG */ #define OFLAGS \ (oflag | (ddflags & (C_SEEK | C_NOTRUNC) ? 0 : O_TRUNC)) - out.fd = ddop_open(out, out.name, O_RDWR | OFLAGS, DEFFILEMODE); + out.fd = ddop_open(out, out.name, O_RDWR | OFLAGS); /* * May not have read access, so try again with write only. * Without read we may have a problem if output also does * not support seeks. */ if (out.fd < 0) { - out.fd = ddop_open(out, out.name, O_WRONLY | OFLAGS, - DEFFILEMODE); + out.fd = ddop_open(out, out.name, O_WRONLY | OFLAGS); out.flags |= NOREAD; } if (out.fd < 0) { diff --git a/bin/dd/dd.h b/bin/dd/dd.h index 2b2712d..c630c0a 100644 --- a/bin/dd/dd.h +++ b/bin/dd/dd.h @@ -36,6 +36,10 @@ */ #include <sys/stat.h> +#include <stdint.h> +#include <stdio.h> +#include <sys/time.h> +#include <stdarg.h> struct ddfops { int (*op_init)(void); @@ -44,7 +48,7 @@ struct ddfops { int (*op_close)(int); int (*op_fcntl)(int, int, ...); - int (*op_ioctl)(int, unsigned long, ...); + int (*op_ioctl)(int, int, ...); int (*op_fstat)(int, struct stat *); int (*op_fsync)(int); @@ -56,10 +60,10 @@ struct ddfops { ssize_t (*op_write)(int, const void *, size_t); }; -#define ddop_open(dir, a1, a2, ...) dir.ops->op_open(a1, a2, __VA_ARGS__) +#define ddop_open(dir, a1, a2, ...) dir.ops->op_open(a1, a2, ##__VA_ARGS__) #define ddop_close(dir, a1) dir.ops->op_close(a1) -#define ddop_fcntl(dir, a1, a2, ...) dir.ops->op_fcntl(a1, a2, __VA_ARGS__) -#define ddop_ioctl(dir, a1, a2, ...) dir.ops->op_ioctl(a1, a2, __VA_ARGS__) +#define ddop_fcntl(dir, a1, a2, ...) dir.ops->op_fcntl(a1, a2, ##__VA_ARGS__) +#define ddop_ioctl(dir, a1, a2, ...) dir.ops->op_ioctl(a1, a2, ##__VA_ARGS__) #define ddop_fsync(dir, a1) dir.ops->op_fsync(a1) #define ddop_ftruncate(dir, a1, a2) dir.ops->op_ftruncate(a1, a2) #define ddop_lseek(dir, a1, a2, a3) dir.ops->op_lseek(a1, a2, a3) @@ -68,8 +72,8 @@ struct ddfops { /* Input/output stream state. */ typedef struct { - u_char *db; /* buffer address */ - u_char *dbp; /* current buffer I/O address */ + unsigned char *db; /* buffer address */ + unsigned char *dbp; /* current buffer I/O address */ uint64_t dbcnt; /* current buffer byte count */ int64_t dbrcnt; /* last read byte count */ uint64_t dbsz; /* buffer size */ @@ -78,7 +82,7 @@ typedef struct { #define ISPIPE 0x02 /* pipe (not truncatable) */ #define ISTAPE 0x04 /* tape (not seekable) */ #define NOREAD 0x08 /* not readable */ - u_int flags; + unsigned int flags; const char *name; /* name */ int fd; /* file descriptor */ diff --git a/bin/dd/dd_hostops.c b/bin/dd/dd_hostops.c index d6e7a89..b9a2fd4 100644 --- a/bin/dd/dd_hostops.c +++ b/bin/dd/dd_hostops.c @@ -26,12 +26,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include <sys/cdefs.h> -#ifndef lint -__RCSID("$NetBSD: dd_hostops.c,v 1.1 2011/02/04 19:42:12 pooka Exp $"); -#endif /* !lint */ - -#include <sys/types.h> #include <sys/ioctl.h> #include <fcntl.h> diff --git a/bin/dd/dd_rumpops.c b/bin/dd/dd_rumpops.c deleted file mode 100644 index 71f7db4..0000000 --- a/bin/dd/dd_rumpops.c +++ /dev/null @@ -1,52 +0,0 @@ -/* $NetBSD: dd_rumpops.c,v 1.1 2011/02/04 19:42:12 pooka Exp $ */ - -/*- - * Copyright (c) 2010 The NetBSD Foundation, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -#ifndef lint -__RCSID("$NetBSD: dd_rumpops.c,v 1.1 2011/02/04 19:42:12 pooka Exp $"); -#endif /* !lint */ - -#include <rump/rump_syscalls.h> -#include <rump/rumpclient.h> - -#include "dd.h" - -const struct ddfops ddfops_prog = { - .op_init = rumpclient_init, - - .op_open = rump_sys_open, - .op_close = rump_sys_close, - .op_fcntl = rump_sys_fcntl, - .op_ioctl = rump_sys_ioctl, - .op_fstat = rump_sys_fstat, - .op_fsync = rump_sys_fsync, - .op_ftruncate = rump_sys_ftruncate, - .op_lseek = rump_sys_lseek, - .op_read = rump_sys_read, - .op_write = rump_sys_write, -}; diff --git a/bin/dd/extern.h b/bin/dd/extern.h index 27b51a0..6185f4d 100644 --- a/bin/dd/extern.h +++ b/bin/dd/extern.h @@ -35,13 +35,14 @@ * @(#)extern.h 8.3 (Berkeley) 4/2/94 */ -#include <sys/cdefs.h> +#define NO_IOFLAG +#define NO_MSGFMT #ifdef NO_CONV -__dead void block(void); -__dead void block_close(void); -__dead void unblock(void); -__dead void unblock_close(void); +void block(void); +void block_close(void); +void unblock(void); +void unblock_close(void); #else void block(void); void block_close(void); @@ -61,7 +62,7 @@ void pos_in(void); void pos_out(void); void summary(void); void summaryx(int); -__dead void terminate(int); +void terminate(int); void unblock(void); void unblock_close(void); ssize_t bwrite(IO *, const void *, size_t); @@ -71,16 +72,17 @@ extern STAT st; extern void (*cfunc)(void); extern uint64_t cpy_cnt; extern uint64_t cbsz; -extern u_int ddflags; +extern uint32_t ddflags; #ifndef NO_IOFLAG -extern u_int iflag; -extern u_int oflag; +extern uint32_t iflag; +extern uint32_t oflag; #endif /* NO_IOFLAG */ -extern u_int files_cnt; +extern unsigned int files_cnt; extern uint64_t progress; -extern const u_char *ctab; -extern const u_char a2e_32V[], a2e_POSIX[]; -extern const u_char e2a_32V[], e2a_POSIX[]; -extern const u_char a2ibm_32V[], a2ibm_POSIX[]; -extern u_char casetab[]; +extern const uint8_t *ctab; +extern const uint8_t a2e_32V[], a2e_POSIX[]; +extern const uint8_t e2a_32V[], e2a_POSIX[]; +extern const uint8_t a2ibm_32V[], a2ibm_POSIX[]; +extern uint8_t casetab[]; extern const char *msgfmt; +extern long long strsuftoll(const char *, const char *, long long, long long); diff --git a/bin/dd/misc.c b/bin/dd/misc.c index 0fac98b..b32ccc7 100644 --- a/bin/dd/misc.c +++ b/bin/dd/misc.c @@ -33,15 +33,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)misc.c 8.3 (Berkeley) 4/2/94"; -#else -__RCSID("$NetBSD: misc.c,v 1.23 2011/11/07 22:24:23 jym Exp $"); -#endif -#endif /* not lint */ - #include <sys/param.h> #include <sys/types.h> #include <sys/time.h> @@ -51,8 +42,8 @@ __RCSID("$NetBSD: misc.c,v 1.23 2011/11/07 22:24:23 jym Exp $"); #include <stdlib.h> #include <string.h> #include <unistd.h> -#include <util.h> #include <inttypes.h> +#include <signal.h> #include "dd.h" #include "extern.h" @@ -153,7 +144,7 @@ terminate(int signo) { summary(); - (void)raise_default_signal(signo); + (void)raise(signo); _exit(127); } diff --git a/bin/dd/position.c b/bin/dd/position.c index 36dd580..f70008b 100644 --- a/bin/dd/position.c +++ b/bin/dd/position.c @@ -33,16 +33,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)position.c 8.3 (Berkeley) 4/2/94"; -#else -__RCSID("$NetBSD: position.c,v 1.18 2010/11/22 21:04:28 pooka Exp $"); -#endif -#endif /* not lint */ - -#include <sys/types.h> #include <sys/stat.h> #include <sys/ioctl.h> #include <sys/mtio.h> diff --git a/bin/dd/strsuftoll.c b/bin/dd/strsuftoll.c new file mode 100644 index 0000000..e031ff3 --- /dev/null +++ b/bin/dd/strsuftoll.c @@ -0,0 +1,234 @@ +/* $NetBSD: strsuftoll.c,v 1.9 2011/10/22 22:08:47 christos Exp $ */ +/*- + * Copyright (c) 2001-2002,2004 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Luke Mewburn. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +/*- + * Copyright (c) 1991, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Keith Muller of the University of California, San Diego and Lance + * Visser of Convex Computer Corporation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef HAVE_STRSUFTOLL + +#include <sys/types.h> +#include <sys/time.h> + +#include <assert.h> +#include <ctype.h> +#include <err.h> +#include <errno.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +/* + * Convert an expression of the following forms to a (u)int64_t. + * 1) A positive decimal number. + * 2) A positive decimal number followed by a b (mult by 512). + * 3) A positive decimal number followed by a k (mult by 1024). + * 4) A positive decimal number followed by a m (mult by 1048576). + * 5) A positive decimal number followed by a g (mult by 1073741824). + * 6) A positive decimal number followed by a t (mult by 1099511627776). + * 7) A positive decimal number followed by a w (mult by sizeof int) + * 8) Two or more positive decimal numbers (with/without k,b or w). + * separated by x (also * for backwards compatibility), specifying + * the product of the indicated values. + * Returns the result upon successful conversion, or exits with an + * appropriate error. + * + */ +/* LONGLONG */ + +long long strsuftollx(const char *, const char *, long long, long long, char *, size_t); + +long long +strsuftoll(const char *desc, const char *val, + long long min, long long max) +{ + long long result; + char errbuf[100]; + + result = strsuftollx(desc, val, min, max, errbuf, sizeof(errbuf)); + if (*errbuf != '\0') + errx(EXIT_FAILURE, "%s", errbuf); + return result; +} + +/* + * As strsuftoll(), but returns the error message into the provided buffer + * rather than exiting with it. + */ +/* LONGLONG */ +static long long +__strsuftollx(const char *desc, const char *val, + long long min, long long max, char *ebuf, size_t ebuflen, size_t depth) +{ + long long num, t; + char *expr; + +#ifndef NDEBUG + assert(desc != NULL); + assert(val != NULL); + assert(ebuf != NULL); +#endif + + if (depth > 16) { + snprintf(ebuf, ebuflen, "%s: Recursion limit exceeded", desc); + return 0; + } + + while (isspace((unsigned char)*val)) /* Skip leading space */ + val++; + + errno = 0; + num = strtoll(val, &expr, 10); + if (errno == ERANGE) + goto erange; /* Overflow */ + + if (expr == val) /* No digits */ + goto badnum; + + switch (*expr) { + case 'b': + t = num; + num *= 512; /* 1 block */ + if (t > num) + goto erange; + ++expr; + break; + case 'k': + t = num; + num *= 1024; /* 1 kibibyte */ + if (t > num) + goto erange; + ++expr; + break; + case 'm': + t = num; + num *= 1048576; /* 1 mebibyte */ + if (t > num) + goto erange; + ++expr; + break; + case 'g': + t = num; + num *= 1073741824; /* 1 gibibyte */ + if (t > num) + goto erange; + ++expr; + break; + case 't': + t = num; + num *= 1099511627776LL; /* 1 tebibyte */ + if (t > num) + goto erange; + ++expr; + break; + case 'w': + t = num; + num *= sizeof(int); /* 1 word */ + if (t > num) + goto erange; + ++expr; + break; + } + + switch (*expr) { + case '\0': + break; + case '*': /* Backward compatible */ + case 'x': + t = num; + num *= __strsuftollx(desc, expr + 1, min, max, ebuf, ebuflen, + depth + 1); + if (*ebuf != '\0') + return 0; + if (t > num) { + erange: + errno = ERANGE; + snprintf(ebuf, ebuflen, "%s: %s", desc, strerror(errno)); + return 0; + } + break; + default: + badnum: + snprintf(ebuf, ebuflen, "%s `%s': illegal number", desc, val); + return 0; + } + if (num < min) { + /* LONGLONG */ + snprintf(ebuf, ebuflen, "%s %lld is less than %lld.", + desc, (long long)num, (long long)min); + return 0; + } + if (num > max) { + /* LONGLONG */ + snprintf(ebuf, ebuflen, "%s %lld is greater than %lld.", + desc, (long long)num, (long long)max); + return 0; + } + *ebuf = '\0'; + return num; +} + + +long long +strsuftollx(const char *desc, const char *val, + long long min, long long max, char *ebuf, size_t ebuflen) +{ + return __strsuftollx(desc, val, min, max, ebuf, ebuflen, 0); +} +#endif /* !HAVE_STRSUFTOLL */ |