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