14b88c807SRodney W. Grimes /*- 24b88c807SRodney W. Grimes * Copyright (c) 1991, 1993, 1994 34b88c807SRodney W. Grimes * The Regents of the University of California. All rights reserved. 44b88c807SRodney W. Grimes * 54b88c807SRodney W. Grimes * This code is derived from software contributed to Berkeley by 64b88c807SRodney W. Grimes * Keith Muller of the University of California, San Diego and Lance 74b88c807SRodney W. Grimes * Visser of Convex Computer Corporation. 84b88c807SRodney W. Grimes * 94b88c807SRodney W. Grimes * Redistribution and use in source and binary forms, with or without 104b88c807SRodney W. Grimes * modification, are permitted provided that the following conditions 114b88c807SRodney W. Grimes * are met: 124b88c807SRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 134b88c807SRodney W. Grimes * notice, this list of conditions and the following disclaimer. 144b88c807SRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 154b88c807SRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 164b88c807SRodney W. Grimes * documentation and/or other materials provided with the distribution. 174b88c807SRodney W. Grimes * 3. All advertising materials mentioning features or use of this software 184b88c807SRodney W. Grimes * must display the following acknowledgement: 194b88c807SRodney W. Grimes * This product includes software developed by the University of 204b88c807SRodney W. Grimes * California, Berkeley and its contributors. 214b88c807SRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 224b88c807SRodney W. Grimes * may be used to endorse or promote products derived from this software 234b88c807SRodney W. Grimes * without specific prior written permission. 244b88c807SRodney W. Grimes * 254b88c807SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 264b88c807SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 274b88c807SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 284b88c807SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 294b88c807SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 304b88c807SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 314b88c807SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 324b88c807SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 334b88c807SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 344b88c807SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 354b88c807SRodney W. Grimes * SUCH DAMAGE. 364b88c807SRodney W. Grimes */ 374b88c807SRodney W. Grimes 384b88c807SRodney W. Grimes #ifndef lint 39cbf6f7d3SPhilippe Charnier #if 0 401ba0e048SPhilippe Charnier static char sccsid[] = "@(#)args.c 8.3 (Berkeley) 4/2/94"; 41cbf6f7d3SPhilippe Charnier #endif 42cbf6f7d3SPhilippe Charnier static const char rcsid[] = 432a456239SPeter Wemm "$FreeBSD$"; 444b88c807SRodney W. Grimes #endif /* not lint */ 454b88c807SRodney W. Grimes 464b88c807SRodney W. Grimes #include <sys/types.h> 474b88c807SRodney W. Grimes 484b88c807SRodney W. Grimes #include <err.h> 494b88c807SRodney W. Grimes #include <errno.h> 504b88c807SRodney W. Grimes #include <limits.h> 514b88c807SRodney W. Grimes #include <stdlib.h> 524b88c807SRodney W. Grimes #include <string.h> 534b88c807SRodney W. Grimes 544b88c807SRodney W. Grimes #include "dd.h" 554b88c807SRodney W. Grimes #include "extern.h" 564b88c807SRodney W. Grimes 574b88c807SRodney W. Grimes static int c_arg __P((const void *, const void *)); 584b88c807SRodney W. Grimes static int c_conv __P((const void *, const void *)); 594b88c807SRodney W. Grimes static void f_bs __P((char *)); 604b88c807SRodney W. Grimes static void f_cbs __P((char *)); 614b88c807SRodney W. Grimes static void f_conv __P((char *)); 624b88c807SRodney W. Grimes static void f_count __P((char *)); 634b88c807SRodney W. Grimes static void f_files __P((char *)); 644b88c807SRodney W. Grimes static void f_ibs __P((char *)); 654b88c807SRodney W. Grimes static void f_if __P((char *)); 664b88c807SRodney W. Grimes static void f_obs __P((char *)); 674b88c807SRodney W. Grimes static void f_of __P((char *)); 684b88c807SRodney W. Grimes static void f_seek __P((char *)); 694b88c807SRodney W. Grimes static void f_skip __P((char *)); 70e14f7e78SBrian Feldman static quad_t get_num __P((char *)); 7158687472SBrian Feldman static off_t get_offset __P((char *)); 724b88c807SRodney W. Grimes 7358687472SBrian Feldman static const struct arg { 7467f80d12SBrian Feldman const char *name; 754b88c807SRodney W. Grimes void (*f) __P((char *)); 764b88c807SRodney W. Grimes u_int set, noset; 774b88c807SRodney W. Grimes } args[] = { 784b88c807SRodney W. Grimes { "bs", f_bs, C_BS, C_BS|C_IBS|C_OBS|C_OSYNC }, 794b88c807SRodney W. Grimes { "cbs", f_cbs, C_CBS, C_CBS }, 804b88c807SRodney W. Grimes { "conv", f_conv, 0, 0 }, 814b88c807SRodney W. Grimes { "count", f_count, C_COUNT, C_COUNT }, 824b88c807SRodney W. Grimes { "files", f_files, C_FILES, C_FILES }, 834b88c807SRodney W. Grimes { "ibs", f_ibs, C_IBS, C_BS|C_IBS }, 844b88c807SRodney W. Grimes { "if", f_if, C_IF, C_IF }, 854b88c807SRodney W. Grimes { "obs", f_obs, C_OBS, C_BS|C_OBS }, 864b88c807SRodney W. Grimes { "of", f_of, C_OF, C_OF }, 874b88c807SRodney W. Grimes { "seek", f_seek, C_SEEK, C_SEEK }, 884b88c807SRodney W. Grimes { "skip", f_skip, C_SKIP, C_SKIP }, 894b88c807SRodney W. Grimes }; 904b88c807SRodney W. Grimes 914b88c807SRodney W. Grimes static char *oper; 924b88c807SRodney W. Grimes 934b88c807SRodney W. Grimes /* 944b88c807SRodney W. Grimes * args -- parse JCL syntax of dd. 954b88c807SRodney W. Grimes */ 964b88c807SRodney W. Grimes void 974b88c807SRodney W. Grimes jcl(argv) 984b88c807SRodney W. Grimes char **argv; 994b88c807SRodney W. Grimes { 1004b88c807SRodney W. Grimes struct arg *ap, tmp; 1014b88c807SRodney W. Grimes char *arg; 1024b88c807SRodney W. Grimes 1034b88c807SRodney W. Grimes in.dbsz = out.dbsz = 512; 1044b88c807SRodney W. Grimes 105ad66f7eeSPoul-Henning Kamp while ((oper = *++argv) != NULL) { 1064c339742SEivind Eklund if ((oper = strdup(oper)) == NULL) 10754946e00SBrian Feldman errx(1, "unable to allocate space for the argument \"%s\"", *argv); 1084b88c807SRodney W. Grimes if ((arg = strchr(oper, '=')) == NULL) 1094b88c807SRodney W. Grimes errx(1, "unknown operand %s", oper); 1104b88c807SRodney W. Grimes *arg++ = '\0'; 1114b88c807SRodney W. Grimes if (!*arg) 1124b88c807SRodney W. Grimes errx(1, "no value specified for %s", oper); 1134b88c807SRodney W. Grimes tmp.name = oper; 11454946e00SBrian Feldman if (!(ap = (struct arg *)bsearch(&tmp, args, 11554946e00SBrian Feldman sizeof(args)/sizeof(struct arg), sizeof(struct arg), 11654946e00SBrian Feldman c_arg))) 1174b88c807SRodney W. Grimes errx(1, "unknown operand %s", tmp.name); 1184b88c807SRodney W. Grimes if (ddflags & ap->noset) 11954946e00SBrian Feldman errx(1, "%s: illegal argument combination or already set", 12054946e00SBrian Feldman tmp.name); 1214b88c807SRodney W. Grimes ddflags |= ap->set; 1224b88c807SRodney W. Grimes ap->f(arg); 1234b88c807SRodney W. Grimes } 1244b88c807SRodney W. Grimes 1254b88c807SRodney W. Grimes /* Final sanity checks. */ 1264b88c807SRodney W. Grimes 1274b88c807SRodney W. Grimes if (ddflags & C_BS) { 1284b88c807SRodney W. Grimes /* 1294b88c807SRodney W. Grimes * Bs is turned off by any conversion -- we assume the user 1304b88c807SRodney W. Grimes * just wanted to set both the input and output block sizes 1314b88c807SRodney W. Grimes * and didn't want the bs semantics, so we don't warn. 1324b88c807SRodney W. Grimes */ 1334b88c807SRodney W. Grimes if (ddflags & (C_BLOCK|C_LCASE|C_SWAB|C_UCASE|C_UNBLOCK)) 1344b88c807SRodney W. Grimes ddflags &= ~C_BS; 1354b88c807SRodney W. Grimes 1364b88c807SRodney W. Grimes /* Bs supersedes ibs and obs. */ 1374b88c807SRodney W. Grimes if (ddflags & C_BS && ddflags & (C_IBS|C_OBS)) 1384b88c807SRodney W. Grimes warnx("bs supersedes ibs and obs"); 1394b88c807SRodney W. Grimes } 1404b88c807SRodney W. Grimes 1414b88c807SRodney W. Grimes /* 1424b88c807SRodney W. Grimes * Ascii/ebcdic and cbs implies block/unblock. 1434b88c807SRodney W. Grimes * Block/unblock requires cbs and vice-versa. 1444b88c807SRodney W. Grimes */ 1454b88c807SRodney W. Grimes if (ddflags & (C_BLOCK | C_UNBLOCK)) { 1464b88c807SRodney W. Grimes if (!(ddflags & C_CBS)) 1474b88c807SRodney W. Grimes errx(1, "record operations require cbs"); 1484b88c807SRodney W. Grimes if (cbsz == 0) 1494b88c807SRodney W. Grimes errx(1, "cbs cannot be zero"); 1504b88c807SRodney W. Grimes cfunc = ddflags & C_BLOCK ? block : unblock; 1514b88c807SRodney W. Grimes } else if (ddflags & C_CBS) { 1524b88c807SRodney W. Grimes if (ddflags & (C_ASCII | C_EBCDIC)) { 1534b88c807SRodney W. Grimes if (ddflags & C_ASCII) { 1544b88c807SRodney W. Grimes ddflags |= C_UNBLOCK; 1554b88c807SRodney W. Grimes cfunc = unblock; 1564b88c807SRodney W. Grimes } else { 1574b88c807SRodney W. Grimes ddflags |= C_BLOCK; 1584b88c807SRodney W. Grimes cfunc = block; 1594b88c807SRodney W. Grimes } 1604b88c807SRodney W. Grimes } else 1614b88c807SRodney W. Grimes errx(1, "cbs meaningless if not doing record operations"); 1624b88c807SRodney W. Grimes } else 1634b88c807SRodney W. Grimes cfunc = def; 1647599187eSBrian Feldman 16558687472SBrian Feldman /* 16658687472SBrian Feldman * Bail out if the calculation of a file offset would overflow. 16758687472SBrian Feldman */ 16858687472SBrian Feldman if (in.offset > QUAD_MAX / in.dbsz || out.offset > QUAD_MAX / out.dbsz) 16958687472SBrian Feldman errx(1, "seek offsets cannot be larger than %qd", QUAD_MAX); 1704b88c807SRodney W. Grimes } 1714b88c807SRodney W. Grimes 1724b88c807SRodney W. Grimes static int 1734b88c807SRodney W. Grimes c_arg(a, b) 1744b88c807SRodney W. Grimes const void *a, *b; 1754b88c807SRodney W. Grimes { 1764b88c807SRodney W. Grimes 177dd923702SBrian Feldman return (strcmp(((const struct arg *)a)->name, 178dd923702SBrian Feldman ((const struct arg *)b)->name)); 1794b88c807SRodney W. Grimes } 1804b88c807SRodney W. Grimes 1814b88c807SRodney W. Grimes static void 1824b88c807SRodney W. Grimes f_bs(arg) 1834b88c807SRodney W. Grimes char *arg; 1844b88c807SRodney W. Grimes { 18558687472SBrian Feldman quad_t res; 1864b88c807SRodney W. Grimes 18758687472SBrian Feldman res = get_num(arg); 18858687472SBrian Feldman if (res < 1 || res > SSIZE_MAX) 18958687472SBrian Feldman errx(1, "bs must be between 1 and %d", SSIZE_MAX); 19058687472SBrian Feldman in.dbsz = out.dbsz = (size_t)res; 1914b88c807SRodney W. Grimes } 1924b88c807SRodney W. Grimes 1934b88c807SRodney W. Grimes static void 1944b88c807SRodney W. Grimes f_cbs(arg) 1954b88c807SRodney W. Grimes char *arg; 1964b88c807SRodney W. Grimes { 19758687472SBrian Feldman quad_t res; 1984b88c807SRodney W. Grimes 19958687472SBrian Feldman res = get_num(arg); 20058687472SBrian Feldman if (res < 1 || res > SSIZE_MAX) 20158687472SBrian Feldman errx(1, "cbs must be between 1 and %d", SSIZE_MAX); 20258687472SBrian Feldman cbsz = (size_t)res; 2034b88c807SRodney W. Grimes } 2044b88c807SRodney W. Grimes 2054b88c807SRodney W. Grimes static void 2064b88c807SRodney W. Grimes f_count(arg) 2074b88c807SRodney W. Grimes char *arg; 2084b88c807SRodney W. Grimes { 2094b88c807SRodney W. Grimes 210e14f7e78SBrian Feldman cpy_cnt = get_num(arg); 2111838cf56SBrian Feldman if (cpy_cnt < 0) 2121838cf56SBrian Feldman errx(1, "count cannot be negative"); 2135ff6541eSBrian Feldman if (cpy_cnt == 0) 2145ff6541eSBrian Feldman cpy_cnt = -1; 2154b88c807SRodney W. Grimes } 2164b88c807SRodney W. Grimes 2174b88c807SRodney W. Grimes static void 2184b88c807SRodney W. Grimes f_files(arg) 2194b88c807SRodney W. Grimes char *arg; 2204b88c807SRodney W. Grimes { 2214b88c807SRodney W. Grimes 222e14f7e78SBrian Feldman files_cnt = get_num(arg); 2237599187eSBrian Feldman if (files_cnt < 1) 2247599187eSBrian Feldman errx(1, "files must be between 1 and %qd", QUAD_MAX); 2254b88c807SRodney W. Grimes } 2264b88c807SRodney W. Grimes 2274b88c807SRodney W. Grimes static void 2284b88c807SRodney W. Grimes f_ibs(arg) 2294b88c807SRodney W. Grimes char *arg; 2304b88c807SRodney W. Grimes { 23158687472SBrian Feldman quad_t res; 2324b88c807SRodney W. Grimes 23354946e00SBrian Feldman if (!(ddflags & C_BS)) { 23458687472SBrian Feldman res = get_num(arg); 23558687472SBrian Feldman if (res < 1 || res > SSIZE_MAX) 2367599187eSBrian Feldman errx(1, "ibs must be between 1 and %d", SSIZE_MAX); 2377599187eSBrian Feldman in.dbsz = (size_t)res; 23854946e00SBrian Feldman } 2394b88c807SRodney W. Grimes } 2404b88c807SRodney W. Grimes 2414b88c807SRodney W. Grimes static void 2424b88c807SRodney W. Grimes f_if(arg) 2434b88c807SRodney W. Grimes char *arg; 2444b88c807SRodney W. Grimes { 2454b88c807SRodney W. Grimes 2464b88c807SRodney W. Grimes in.name = arg; 2474b88c807SRodney W. Grimes } 2484b88c807SRodney W. Grimes 2494b88c807SRodney W. Grimes static void 2504b88c807SRodney W. Grimes f_obs(arg) 2514b88c807SRodney W. Grimes char *arg; 2524b88c807SRodney W. Grimes { 25358687472SBrian Feldman quad_t res; 2544b88c807SRodney W. Grimes 25554946e00SBrian Feldman if (!(ddflags & C_BS)) { 25658687472SBrian Feldman res = get_num(arg); 25758687472SBrian Feldman if (res < 1 || res > SSIZE_MAX) 25858687472SBrian Feldman errx(1, "obs must be between 1 and %d", SSIZE_MAX); 25958687472SBrian Feldman out.dbsz = (size_t)res; 26054946e00SBrian Feldman } 2614b88c807SRodney W. Grimes } 2624b88c807SRodney W. Grimes 2634b88c807SRodney W. Grimes static void 2644b88c807SRodney W. Grimes f_of(arg) 2654b88c807SRodney W. Grimes char *arg; 2664b88c807SRodney W. Grimes { 2674b88c807SRodney W. Grimes 2684b88c807SRodney W. Grimes out.name = arg; 2694b88c807SRodney W. Grimes } 2704b88c807SRodney W. Grimes 2714b88c807SRodney W. Grimes static void 2724b88c807SRodney W. Grimes f_seek(arg) 2734b88c807SRodney W. Grimes char *arg; 2744b88c807SRodney W. Grimes { 2754b88c807SRodney W. Grimes 27658687472SBrian Feldman out.offset = get_offset(arg); 2774b88c807SRodney W. Grimes } 2784b88c807SRodney W. Grimes 2794b88c807SRodney W. Grimes static void 2804b88c807SRodney W. Grimes f_skip(arg) 2814b88c807SRodney W. Grimes char *arg; 2824b88c807SRodney W. Grimes { 2834b88c807SRodney W. Grimes 28458687472SBrian Feldman in.offset = get_offset(arg); 2854b88c807SRodney W. Grimes } 2864b88c807SRodney W. Grimes 28758687472SBrian Feldman static const struct conv { 28867f80d12SBrian Feldman const char *name; 2894b88c807SRodney W. Grimes u_int set, noset; 29058687472SBrian Feldman const u_char *ctab; 2914b88c807SRodney W. Grimes } clist[] = { 2924b88c807SRodney W. Grimes { "ascii", C_ASCII, C_EBCDIC, e2a_POSIX }, 2934b88c807SRodney W. Grimes { "block", C_BLOCK, C_UNBLOCK, NULL }, 2944b88c807SRodney W. Grimes { "ebcdic", C_EBCDIC, C_ASCII, a2e_POSIX }, 2954b88c807SRodney W. Grimes { "ibm", C_EBCDIC, C_ASCII, a2ibm_POSIX }, 2964b88c807SRodney W. Grimes { "lcase", C_LCASE, C_UCASE, NULL }, 2974b88c807SRodney W. Grimes { "noerror", C_NOERROR, 0, NULL }, 2984b88c807SRodney W. Grimes { "notrunc", C_NOTRUNC, 0, NULL }, 2994b88c807SRodney W. Grimes { "oldascii", C_ASCII, C_EBCDIC, e2a_32V }, 3004b88c807SRodney W. Grimes { "oldebcdic", C_EBCDIC, C_ASCII, a2e_32V }, 3014b88c807SRodney W. Grimes { "oldibm", C_EBCDIC, C_ASCII, a2ibm_32V }, 3024b88c807SRodney W. Grimes { "osync", C_OSYNC, C_BS, NULL }, 3031898febeSJoerg Wunsch { "sparse", C_SPARSE, 0, NULL }, 3044b88c807SRodney W. Grimes { "swab", C_SWAB, 0, NULL }, 3054b88c807SRodney W. Grimes { "sync", C_SYNC, 0, NULL }, 3064b88c807SRodney W. Grimes { "ucase", C_UCASE, C_LCASE, NULL }, 3074b88c807SRodney W. Grimes { "unblock", C_UNBLOCK, C_BLOCK, NULL }, 3084b88c807SRodney W. Grimes }; 3094b88c807SRodney W. Grimes 3104b88c807SRodney W. Grimes static void 3114b88c807SRodney W. Grimes f_conv(arg) 3124b88c807SRodney W. Grimes char *arg; 3134b88c807SRodney W. Grimes { 3144b88c807SRodney W. Grimes struct conv *cp, tmp; 3154b88c807SRodney W. Grimes 3164b88c807SRodney W. Grimes while (arg != NULL) { 3174b88c807SRodney W. Grimes tmp.name = strsep(&arg, ","); 31858687472SBrian Feldman cp = bsearch(&tmp, clist, sizeof(clist) / sizeof(struct conv), 31958687472SBrian Feldman sizeof(struct conv), c_conv); 32058687472SBrian Feldman if (cp == NULL) 3214b88c807SRodney W. Grimes errx(1, "unknown conversion %s", tmp.name); 3224b88c807SRodney W. Grimes if (ddflags & cp->noset) 3234b88c807SRodney W. Grimes errx(1, "%s: illegal conversion combination", tmp.name); 3244b88c807SRodney W. Grimes ddflags |= cp->set; 3254b88c807SRodney W. Grimes if (cp->ctab) 3264b88c807SRodney W. Grimes ctab = cp->ctab; 3274b88c807SRodney W. Grimes } 3284b88c807SRodney W. Grimes } 3294b88c807SRodney W. Grimes 3304b88c807SRodney W. Grimes static int 3314b88c807SRodney W. Grimes c_conv(a, b) 3324b88c807SRodney W. Grimes const void *a, *b; 3334b88c807SRodney W. Grimes { 3344b88c807SRodney W. Grimes 335dd923702SBrian Feldman return (strcmp(((const struct conv *)a)->name, 336dd923702SBrian Feldman ((const struct conv *)b)->name)); 3374b88c807SRodney W. Grimes } 3384b88c807SRodney W. Grimes 3394b88c807SRodney W. Grimes /* 34054946e00SBrian Feldman * Convert an expression of the following forms to a quad_t. 3414b88c807SRodney W. Grimes * 1) A positive decimal number. 34254946e00SBrian Feldman * 2) A positive decimal number followed by a b (mult by 512.) 34354946e00SBrian Feldman * 3) A positive decimal number followed by a k (mult by 1 << 10.) 34454946e00SBrian Feldman * 4) A positive decimal number followed by a m (mult by 1 << 20.) 34554946e00SBrian Feldman * 5) A positive decimal number followed by a g (mult by 1 << 30.) 34654946e00SBrian Feldman * 5) A positive decimal number followed by a w (mult by sizeof int.) 34754946e00SBrian Feldman * 6) Two or more positive decimal numbers (with/without [bkmgw]) 34846be34b9SKris Kennaway * separated by x (also * for backwards compatibility), specifying 3494b88c807SRodney W. Grimes * the product of the indicated values. 3504b88c807SRodney W. Grimes */ 35154946e00SBrian Feldman static quad_t 352e14f7e78SBrian Feldman get_num(val) 3534b88c807SRodney W. Grimes char *val; 3544b88c807SRodney W. Grimes { 35554946e00SBrian Feldman quad_t num, t; 3564b88c807SRodney W. Grimes char *expr; 3574b88c807SRodney W. Grimes 35854946e00SBrian Feldman errno = 0; 359767bc8adSBrian Feldman num = strtoq(val, &expr, 0); 36058687472SBrian Feldman if (errno != 0) /* Overflow or underflow. */ 36154946e00SBrian Feldman err(1, "%s", oper); 36254946e00SBrian Feldman 36358687472SBrian Feldman if (expr == val) /* No valid digits. */ 3644b88c807SRodney W. Grimes errx(1, "%s: illegal numeric value", oper); 3654b88c807SRodney W. Grimes 3664b88c807SRodney W. Grimes switch (*expr) { 3674b88c807SRodney W. Grimes case 'b': 3684b88c807SRodney W. Grimes t = num; 3694b88c807SRodney W. Grimes num *= 512; 3704b88c807SRodney W. Grimes if (t > num) 3714b88c807SRodney W. Grimes goto erange; 3724b88c807SRodney W. Grimes ++expr; 3734b88c807SRodney W. Grimes break; 3744b88c807SRodney W. Grimes case 'k': 3754b88c807SRodney W. Grimes t = num; 37654946e00SBrian Feldman num *= 1 << 10; 3774b88c807SRodney W. Grimes if (t > num) 3784b88c807SRodney W. Grimes goto erange; 3794b88c807SRodney W. Grimes ++expr; 3804b88c807SRodney W. Grimes break; 3814b88c807SRodney W. Grimes case 'm': 3824b88c807SRodney W. Grimes t = num; 38354946e00SBrian Feldman num *= 1 << 20; 38454946e00SBrian Feldman if (t > num) 38554946e00SBrian Feldman goto erange; 38654946e00SBrian Feldman ++expr; 38754946e00SBrian Feldman break; 38854946e00SBrian Feldman case 'g': 38954946e00SBrian Feldman t = num; 39054946e00SBrian Feldman num *= 1 << 30; 3914b88c807SRodney W. Grimes if (t > num) 3924b88c807SRodney W. Grimes goto erange; 3934b88c807SRodney W. Grimes ++expr; 3944b88c807SRodney W. Grimes break; 3954b88c807SRodney W. Grimes case 'w': 3964b88c807SRodney W. Grimes t = num; 3974b88c807SRodney W. Grimes num *= sizeof(int); 3984b88c807SRodney W. Grimes if (t > num) 3994b88c807SRodney W. Grimes goto erange; 4004b88c807SRodney W. Grimes ++expr; 4014b88c807SRodney W. Grimes break; 4024b88c807SRodney W. Grimes } 4034b88c807SRodney W. Grimes 4044b88c807SRodney W. Grimes switch (*expr) { 4054b88c807SRodney W. Grimes case '\0': 4064b88c807SRodney W. Grimes break; 4074b88c807SRodney W. Grimes case '*': /* Backward compatible. */ 4084b88c807SRodney W. Grimes case 'x': 4094b88c807SRodney W. Grimes t = num; 410e14f7e78SBrian Feldman num *= get_num(expr + 1); 411e14f7e78SBrian Feldman if (t <= num) 4124b88c807SRodney W. Grimes break; 413e14f7e78SBrian Feldman erange: 414e14f7e78SBrian Feldman errx(1, "%s: %s", oper, strerror(ERANGE)); 4154b88c807SRodney W. Grimes default: 4164b88c807SRodney W. Grimes errx(1, "%s: illegal numeric value", oper); 4174b88c807SRodney W. Grimes } 4184b88c807SRodney W. Grimes return (num); 4194b88c807SRodney W. Grimes } 42058687472SBrian Feldman 42158687472SBrian Feldman static off_t 42258687472SBrian Feldman get_offset(val) 42358687472SBrian Feldman char *val; 42458687472SBrian Feldman { 42558687472SBrian Feldman quad_t num; 42658687472SBrian Feldman 42758687472SBrian Feldman num = get_num(val); 42858687472SBrian Feldman if (num > QUAD_MAX || num < 0) /* XXX quad_t != off_t */ 42958687472SBrian Feldman errx(1, "%s: illegal offset", oper); /* Too big/negative. */ 43058687472SBrian Feldman return ((off_t)num); 43158687472SBrian Feldman } 432