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. 3689730b29SDavid Greenman * 371898febeSJoerg Wunsch * $Id: args.c,v 1.10 1997/10/11 20:09:04 joerg Exp $ 384b88c807SRodney W. Grimes */ 394b88c807SRodney W. Grimes 404b88c807SRodney W. Grimes #ifndef lint 4178b09ffeSSteve Price static char const sccsid[] = "@(#)args.c 8.3 (Berkeley) 4/2/94"; 424b88c807SRodney W. Grimes #endif /* not lint */ 434b88c807SRodney W. Grimes 444b88c807SRodney W. Grimes #include <sys/types.h> 454b88c807SRodney W. Grimes 464b88c807SRodney W. Grimes #include <err.h> 474b88c807SRodney W. Grimes #include <errno.h> 484b88c807SRodney W. Grimes #include <limits.h> 494b88c807SRodney W. Grimes #include <stdio.h> 504b88c807SRodney W. Grimes #include <stdlib.h> 514b88c807SRodney W. Grimes #include <string.h> 524b88c807SRodney W. Grimes 534b88c807SRodney W. Grimes #include "dd.h" 544b88c807SRodney W. Grimes #include "extern.h" 554b88c807SRodney W. Grimes 564b88c807SRodney W. Grimes static int c_arg __P((const void *, const void *)); 574b88c807SRodney W. Grimes static int c_conv __P((const void *, const void *)); 584b88c807SRodney W. Grimes static void f_bs __P((char *)); 594b88c807SRodney W. Grimes static void f_cbs __P((char *)); 604b88c807SRodney W. Grimes static void f_conv __P((char *)); 614b88c807SRodney W. Grimes static void f_count __P((char *)); 624b88c807SRodney W. Grimes static void f_files __P((char *)); 634b88c807SRodney W. Grimes static void f_ibs __P((char *)); 644b88c807SRodney W. Grimes static void f_if __P((char *)); 654b88c807SRodney W. Grimes static void f_obs __P((char *)); 664b88c807SRodney W. Grimes static void f_of __P((char *)); 674b88c807SRodney W. Grimes static void f_seek __P((char *)); 684b88c807SRodney W. Grimes static void f_skip __P((char *)); 694b88c807SRodney W. Grimes static u_long get_bsz __P((char *)); 704b88c807SRodney W. Grimes 714b88c807SRodney W. Grimes static struct arg { 724b88c807SRodney W. Grimes char *name; 734b88c807SRodney W. Grimes void (*f) __P((char *)); 744b88c807SRodney W. Grimes u_int set, noset; 754b88c807SRodney W. Grimes } args[] = { 764b88c807SRodney W. Grimes { "bs", f_bs, C_BS, C_BS|C_IBS|C_OBS|C_OSYNC }, 774b88c807SRodney W. Grimes { "cbs", f_cbs, C_CBS, C_CBS }, 784b88c807SRodney W. Grimes { "conv", f_conv, 0, 0 }, 794b88c807SRodney W. Grimes { "count", f_count, C_COUNT, C_COUNT }, 804b88c807SRodney W. Grimes { "files", f_files, C_FILES, C_FILES }, 814b88c807SRodney W. Grimes { "ibs", f_ibs, C_IBS, C_BS|C_IBS }, 824b88c807SRodney W. Grimes { "if", f_if, C_IF, C_IF }, 834b88c807SRodney W. Grimes { "obs", f_obs, C_OBS, C_BS|C_OBS }, 844b88c807SRodney W. Grimes { "of", f_of, C_OF, C_OF }, 854b88c807SRodney W. Grimes { "seek", f_seek, C_SEEK, C_SEEK }, 864b88c807SRodney W. Grimes { "skip", f_skip, C_SKIP, C_SKIP }, 874b88c807SRodney W. Grimes }; 884b88c807SRodney W. Grimes 894b88c807SRodney W. Grimes static char *oper; 904b88c807SRodney W. Grimes 914b88c807SRodney W. Grimes /* 924b88c807SRodney W. Grimes * args -- parse JCL syntax of dd. 934b88c807SRodney W. Grimes */ 944b88c807SRodney W. Grimes void 954b88c807SRodney W. Grimes jcl(argv) 964b88c807SRodney W. Grimes char **argv; 974b88c807SRodney W. Grimes { 984b88c807SRodney W. Grimes struct arg *ap, tmp; 994b88c807SRodney W. Grimes char *arg; 1004b88c807SRodney W. Grimes 1014b88c807SRodney W. Grimes in.dbsz = out.dbsz = 512; 1024b88c807SRodney W. Grimes 103ad66f7eeSPoul-Henning Kamp while ((oper = *++argv) != NULL) { 1044c339742SEivind Eklund if ((oper = strdup(oper)) == NULL) 1054c339742SEivind Eklund errx(1, "unable to allocate space for the argument \"%s\"", *argv); 1064b88c807SRodney W. Grimes if ((arg = strchr(oper, '=')) == NULL) 1074b88c807SRodney W. Grimes errx(1, "unknown operand %s", oper); 1084b88c807SRodney W. Grimes *arg++ = '\0'; 1094b88c807SRodney W. Grimes if (!*arg) 1104b88c807SRodney W. Grimes errx(1, "no value specified for %s", oper); 1114b88c807SRodney W. Grimes tmp.name = oper; 1124b88c807SRodney W. Grimes if (!(ap = (struct arg *)bsearch(&tmp, args, 1134b88c807SRodney W. Grimes sizeof(args)/sizeof(struct arg), sizeof(struct arg), 1144b88c807SRodney W. Grimes c_arg))) 1154b88c807SRodney W. Grimes errx(1, "unknown operand %s", tmp.name); 1164b88c807SRodney W. Grimes if (ddflags & ap->noset) 1174b88c807SRodney W. Grimes errx(1, "%s: illegal argument combination or already set", 1184b88c807SRodney W. Grimes tmp.name); 1194b88c807SRodney W. Grimes ddflags |= ap->set; 1204b88c807SRodney W. Grimes ap->f(arg); 1214b88c807SRodney W. Grimes } 1224b88c807SRodney W. Grimes 1234b88c807SRodney W. Grimes /* Final sanity checks. */ 1244b88c807SRodney W. Grimes 1254b88c807SRodney W. Grimes if (ddflags & C_BS) { 1264b88c807SRodney W. Grimes /* 1274b88c807SRodney W. Grimes * Bs is turned off by any conversion -- we assume the user 1284b88c807SRodney W. Grimes * just wanted to set both the input and output block sizes 1294b88c807SRodney W. Grimes * and didn't want the bs semantics, so we don't warn. 1304b88c807SRodney W. Grimes */ 1314b88c807SRodney W. Grimes if (ddflags & (C_BLOCK|C_LCASE|C_SWAB|C_UCASE|C_UNBLOCK)) 1324b88c807SRodney W. Grimes ddflags &= ~C_BS; 1334b88c807SRodney W. Grimes 1344b88c807SRodney W. Grimes /* Bs supersedes ibs and obs. */ 1354b88c807SRodney W. Grimes if (ddflags & C_BS && ddflags & (C_IBS|C_OBS)) 1364b88c807SRodney W. Grimes warnx("bs supersedes ibs and obs"); 1374b88c807SRodney W. Grimes } 1384b88c807SRodney W. Grimes 1394b88c807SRodney W. Grimes /* 1404b88c807SRodney W. Grimes * Ascii/ebcdic and cbs implies block/unblock. 1414b88c807SRodney W. Grimes * Block/unblock requires cbs and vice-versa. 1424b88c807SRodney W. Grimes */ 1434b88c807SRodney W. Grimes if (ddflags & (C_BLOCK|C_UNBLOCK)) { 1444b88c807SRodney W. Grimes if (!(ddflags & C_CBS)) 1454b88c807SRodney W. Grimes errx(1, "record operations require cbs"); 1464b88c807SRodney W. Grimes if (cbsz == 0) 1474b88c807SRodney W. Grimes errx(1, "cbs cannot be zero"); 1484b88c807SRodney W. Grimes cfunc = ddflags & C_BLOCK ? block : unblock; 1494b88c807SRodney W. Grimes } else if (ddflags & C_CBS) { 1504b88c807SRodney W. Grimes if (ddflags & (C_ASCII|C_EBCDIC)) { 1514b88c807SRodney W. Grimes if (ddflags & C_ASCII) { 1524b88c807SRodney W. Grimes ddflags |= C_UNBLOCK; 1534b88c807SRodney W. Grimes cfunc = unblock; 1544b88c807SRodney W. Grimes } else { 1554b88c807SRodney W. Grimes ddflags |= C_BLOCK; 1564b88c807SRodney W. Grimes cfunc = block; 1574b88c807SRodney W. Grimes } 1584b88c807SRodney W. Grimes } else 1594b88c807SRodney W. Grimes errx(1, "cbs meaningless if not doing record operations"); 1604b88c807SRodney W. Grimes if (cbsz == 0) 1614b88c807SRodney W. Grimes errx(1, "cbs cannot be zero"); 1624b88c807SRodney W. Grimes } else 1634b88c807SRodney W. Grimes cfunc = def; 1644b88c807SRodney W. Grimes 1654b88c807SRodney W. Grimes if (in.dbsz == 0 || out.dbsz == 0) 1664b88c807SRodney W. Grimes errx(1, "buffer sizes cannot be zero"); 1674b88c807SRodney W. Grimes 1684b88c807SRodney W. Grimes /* 1694b88c807SRodney W. Grimes * Read, write and seek calls take ints as arguments. Seek sizes 1704b88c807SRodney W. Grimes * could be larger if we wanted to do it in stages or check only 1714b88c807SRodney W. Grimes * regular files, but it's probably not worth it. 1724b88c807SRodney W. Grimes */ 1734b88c807SRodney W. Grimes if (in.dbsz > INT_MAX || out.dbsz > INT_MAX) 1744b88c807SRodney W. Grimes errx(1, "buffer sizes cannot be greater than %d", INT_MAX); 1754b88c807SRodney W. Grimes if (in.offset > INT_MAX / in.dbsz || out.offset > INT_MAX / out.dbsz) 1764b88c807SRodney W. Grimes errx(1, "seek offsets cannot be larger than %d", INT_MAX); 1774b88c807SRodney W. Grimes } 1784b88c807SRodney W. Grimes 1794b88c807SRodney W. Grimes static int 1804b88c807SRodney W. Grimes c_arg(a, b) 1814b88c807SRodney W. Grimes const void *a, *b; 1824b88c807SRodney W. Grimes { 1834b88c807SRodney W. Grimes 1844b88c807SRodney W. Grimes return (strcmp(((struct arg *)a)->name, ((struct arg *)b)->name)); 1854b88c807SRodney W. Grimes } 1864b88c807SRodney W. Grimes 1874b88c807SRodney W. Grimes static void 1884b88c807SRodney W. Grimes f_bs(arg) 1894b88c807SRodney W. Grimes char *arg; 1904b88c807SRodney W. Grimes { 1914b88c807SRodney W. Grimes 1924b88c807SRodney W. Grimes in.dbsz = out.dbsz = (int)get_bsz(arg); 1934b88c807SRodney W. Grimes } 1944b88c807SRodney W. Grimes 1954b88c807SRodney W. Grimes static void 1964b88c807SRodney W. Grimes f_cbs(arg) 1974b88c807SRodney W. Grimes char *arg; 1984b88c807SRodney W. Grimes { 1994b88c807SRodney W. Grimes 2004b88c807SRodney W. Grimes cbsz = (int)get_bsz(arg); 2014b88c807SRodney W. Grimes } 2024b88c807SRodney W. Grimes 2034b88c807SRodney W. Grimes static void 2044b88c807SRodney W. Grimes f_count(arg) 2054b88c807SRodney W. Grimes char *arg; 2064b88c807SRodney W. Grimes { 2074b88c807SRodney W. Grimes 2084b88c807SRodney W. Grimes cpy_cnt = (u_int)get_bsz(arg); 2094b88c807SRodney W. Grimes if (!cpy_cnt) 2104b88c807SRodney W. Grimes terminate(0); 2114b88c807SRodney W. Grimes } 2124b88c807SRodney W. Grimes 2134b88c807SRodney W. Grimes static void 2144b88c807SRodney W. Grimes f_files(arg) 2154b88c807SRodney W. Grimes char *arg; 2164b88c807SRodney W. Grimes { 2174b88c807SRodney W. Grimes 2184b88c807SRodney W. Grimes files_cnt = (int)get_bsz(arg); 2194b88c807SRodney W. Grimes } 2204b88c807SRodney W. Grimes 2214b88c807SRodney W. Grimes static void 2224b88c807SRodney W. Grimes f_ibs(arg) 2234b88c807SRodney W. Grimes char *arg; 2244b88c807SRodney W. Grimes { 2254b88c807SRodney W. Grimes 2264b88c807SRodney W. Grimes if (!(ddflags & C_BS)) 2274b88c807SRodney W. Grimes in.dbsz = (int)get_bsz(arg); 2284b88c807SRodney W. Grimes } 2294b88c807SRodney W. Grimes 2304b88c807SRodney W. Grimes static void 2314b88c807SRodney W. Grimes f_if(arg) 2324b88c807SRodney W. Grimes char *arg; 2334b88c807SRodney W. Grimes { 2344b88c807SRodney W. Grimes 2354b88c807SRodney W. Grimes in.name = arg; 2364b88c807SRodney W. Grimes } 2374b88c807SRodney W. Grimes 2384b88c807SRodney W. Grimes static void 2394b88c807SRodney W. Grimes f_obs(arg) 2404b88c807SRodney W. Grimes char *arg; 2414b88c807SRodney W. Grimes { 2424b88c807SRodney W. Grimes 2434b88c807SRodney W. Grimes if (!(ddflags & C_BS)) 2444b88c807SRodney W. Grimes out.dbsz = (int)get_bsz(arg); 2454b88c807SRodney W. Grimes } 2464b88c807SRodney W. Grimes 2474b88c807SRodney W. Grimes static void 2484b88c807SRodney W. Grimes f_of(arg) 2494b88c807SRodney W. Grimes char *arg; 2504b88c807SRodney W. Grimes { 2514b88c807SRodney W. Grimes 2524b88c807SRodney W. Grimes out.name = arg; 2534b88c807SRodney W. Grimes } 2544b88c807SRodney W. Grimes 2554b88c807SRodney W. Grimes static void 2564b88c807SRodney W. Grimes f_seek(arg) 2574b88c807SRodney W. Grimes char *arg; 2584b88c807SRodney W. Grimes { 2594b88c807SRodney W. Grimes 2604b88c807SRodney W. Grimes out.offset = (u_int)get_bsz(arg); 2614b88c807SRodney W. Grimes } 2624b88c807SRodney W. Grimes 2634b88c807SRodney W. Grimes static void 2644b88c807SRodney W. Grimes f_skip(arg) 2654b88c807SRodney W. Grimes char *arg; 2664b88c807SRodney W. Grimes { 2674b88c807SRodney W. Grimes 2684b88c807SRodney W. Grimes in.offset = (u_int)get_bsz(arg); 2694b88c807SRodney W. Grimes } 2704b88c807SRodney W. Grimes 2714b88c807SRodney W. Grimes static struct conv { 2724b88c807SRodney W. Grimes char *name; 2734b88c807SRodney W. Grimes u_int set, noset; 2744b88c807SRodney W. Grimes u_char *ctab; 2754b88c807SRodney W. Grimes } clist[] = { 2764b88c807SRodney W. Grimes { "ascii", C_ASCII, C_EBCDIC, e2a_POSIX }, 2774b88c807SRodney W. Grimes { "block", C_BLOCK, C_UNBLOCK, NULL }, 2784b88c807SRodney W. Grimes { "ebcdic", C_EBCDIC, C_ASCII, a2e_POSIX }, 2794b88c807SRodney W. Grimes { "ibm", C_EBCDIC, C_ASCII, a2ibm_POSIX }, 2804b88c807SRodney W. Grimes { "lcase", C_LCASE, C_UCASE, NULL }, 2814b88c807SRodney W. Grimes { "noerror", C_NOERROR, 0, NULL }, 2824b88c807SRodney W. Grimes { "notrunc", C_NOTRUNC, 0, NULL }, 2834b88c807SRodney W. Grimes { "oldascii", C_ASCII, C_EBCDIC, e2a_32V }, 2844b88c807SRodney W. Grimes { "oldebcdic", C_EBCDIC, C_ASCII, a2e_32V }, 2854b88c807SRodney W. Grimes { "oldibm", C_EBCDIC, C_ASCII, a2ibm_32V }, 2864b88c807SRodney W. Grimes { "osync", C_OSYNC, C_BS, NULL }, 2871898febeSJoerg Wunsch { "sparse", C_SPARSE, 0, NULL }, 2884b88c807SRodney W. Grimes { "swab", C_SWAB, 0, NULL }, 2894b88c807SRodney W. Grimes { "sync", C_SYNC, 0, NULL }, 2904b88c807SRodney W. Grimes { "ucase", C_UCASE, C_LCASE, NULL }, 2914b88c807SRodney W. Grimes { "unblock", C_UNBLOCK, C_BLOCK, NULL }, 2924b88c807SRodney W. Grimes }; 2934b88c807SRodney W. Grimes 2944b88c807SRodney W. Grimes static void 2954b88c807SRodney W. Grimes f_conv(arg) 2964b88c807SRodney W. Grimes char *arg; 2974b88c807SRodney W. Grimes { 2984b88c807SRodney W. Grimes struct conv *cp, tmp; 2994b88c807SRodney W. Grimes 3004b88c807SRodney W. Grimes while (arg != NULL) { 3014b88c807SRodney W. Grimes tmp.name = strsep(&arg, ","); 3024b88c807SRodney W. Grimes if (!(cp = (struct conv *)bsearch(&tmp, clist, 3034b88c807SRodney W. Grimes sizeof(clist)/sizeof(struct conv), sizeof(struct conv), 3044b88c807SRodney W. Grimes c_conv))) 3054b88c807SRodney W. Grimes errx(1, "unknown conversion %s", tmp.name); 3064b88c807SRodney W. Grimes if (ddflags & cp->noset) 3074b88c807SRodney W. Grimes errx(1, "%s: illegal conversion combination", tmp.name); 3084b88c807SRodney W. Grimes ddflags |= cp->set; 3094b88c807SRodney W. Grimes if (cp->ctab) 3104b88c807SRodney W. Grimes ctab = cp->ctab; 3114b88c807SRodney W. Grimes } 3124b88c807SRodney W. Grimes } 3134b88c807SRodney W. Grimes 3144b88c807SRodney W. Grimes static int 3154b88c807SRodney W. Grimes c_conv(a, b) 3164b88c807SRodney W. Grimes const void *a, *b; 3174b88c807SRodney W. Grimes { 3184b88c807SRodney W. Grimes 3194b88c807SRodney W. Grimes return (strcmp(((struct conv *)a)->name, ((struct conv *)b)->name)); 3204b88c807SRodney W. Grimes } 3214b88c807SRodney W. Grimes 3224b88c807SRodney W. Grimes /* 3234b88c807SRodney W. Grimes * Convert an expression of the following forms to an unsigned long. 3244b88c807SRodney W. Grimes * 1) A positive decimal number. 3254b88c807SRodney W. Grimes * 2) A positive decimal number followed by a b (mult by 512). 3264b88c807SRodney W. Grimes * 3) A positive decimal number followed by a k (mult by 1024). 3274b88c807SRodney W. Grimes * 4) A positive decimal number followed by a m (mult by 512). 3284b88c807SRodney W. Grimes * 5) A positive decimal number followed by a w (mult by sizeof int) 3294b88c807SRodney W. Grimes * 6) Two or more positive decimal numbers (with/without k,b or w). 3304b88c807SRodney W. Grimes * seperated by x (also * for backwards compatibility), specifying 3314b88c807SRodney W. Grimes * the product of the indicated values. 3324b88c807SRodney W. Grimes */ 3334b88c807SRodney W. Grimes static u_long 3344b88c807SRodney W. Grimes get_bsz(val) 3354b88c807SRodney W. Grimes char *val; 3364b88c807SRodney W. Grimes { 3374b88c807SRodney W. Grimes u_long num, t; 3384b88c807SRodney W. Grimes char *expr; 3394b88c807SRodney W. Grimes 3404b88c807SRodney W. Grimes num = strtoul(val, &expr, 0); 3414b88c807SRodney W. Grimes if (num == ULONG_MAX) /* Overflow. */ 3424b88c807SRodney W. Grimes err(1, "%s", oper); 3434b88c807SRodney W. Grimes if (expr == val) /* No digits. */ 3444b88c807SRodney W. Grimes errx(1, "%s: illegal numeric value", oper); 3454b88c807SRodney W. Grimes 3464b88c807SRodney W. Grimes switch(*expr) { 3474b88c807SRodney W. Grimes case 'b': 3484b88c807SRodney W. Grimes t = num; 3494b88c807SRodney W. Grimes num *= 512; 3504b88c807SRodney W. Grimes if (t > num) 3514b88c807SRodney W. Grimes goto erange; 3524b88c807SRodney W. Grimes ++expr; 3534b88c807SRodney W. Grimes break; 3544b88c807SRodney W. Grimes case 'k': 3554b88c807SRodney W. Grimes t = num; 3564b88c807SRodney W. Grimes num *= 1024; 3574b88c807SRodney W. Grimes if (t > num) 3584b88c807SRodney W. Grimes goto erange; 3594b88c807SRodney W. Grimes ++expr; 3604b88c807SRodney W. Grimes break; 3614b88c807SRodney W. Grimes case 'm': 3624b88c807SRodney W. Grimes t = num; 3634b88c807SRodney W. Grimes num *= 1048576; 3644b88c807SRodney W. Grimes if (t > num) 3654b88c807SRodney W. Grimes goto erange; 3664b88c807SRodney W. Grimes ++expr; 3674b88c807SRodney W. Grimes break; 3684b88c807SRodney W. Grimes case 'w': 3694b88c807SRodney W. Grimes t = num; 3704b88c807SRodney W. Grimes num *= sizeof(int); 3714b88c807SRodney W. Grimes if (t > num) 3724b88c807SRodney W. Grimes goto erange; 3734b88c807SRodney W. Grimes ++expr; 3744b88c807SRodney W. Grimes break; 3754b88c807SRodney W. Grimes } 3764b88c807SRodney W. Grimes 3774b88c807SRodney W. Grimes switch(*expr) { 3784b88c807SRodney W. Grimes case '\0': 3794b88c807SRodney W. Grimes break; 3804b88c807SRodney W. Grimes case '*': /* Backward compatible. */ 3814b88c807SRodney W. Grimes case 'x': 3824b88c807SRodney W. Grimes t = num; 3834b88c807SRodney W. Grimes num *= get_bsz(expr + 1); 3844b88c807SRodney W. Grimes if (t > num) 3854b88c807SRodney W. Grimes erange: errx(1, "%s: %s", oper, strerror(ERANGE)); 3864b88c807SRodney W. Grimes break; 3874b88c807SRodney W. Grimes default: 3884b88c807SRodney W. Grimes errx(1, "%s: illegal numeric value", oper); 3894b88c807SRodney W. Grimes } 3904b88c807SRodney W. Grimes return (num); 3914b88c807SRodney W. Grimes } 392