141457Sbostic /*- 2*62031Sbostic * Copyright (c) 1990, 1993 3*62031Sbostic * The Regents of the University of California. All rights reserved. 441457Sbostic * 541457Sbostic * %sccs.include.redist.c% 641457Sbostic */ 741457Sbostic 841457Sbostic #ifndef lint 9*62031Sbostic static char sccsid[] = "@(#)odsyntax.c 8.1 (Berkeley) 06/06/93"; 1041457Sbostic #endif /* not lint */ 1141457Sbostic 1241457Sbostic #include <sys/types.h> 1355201Sbostic 1445217Sbostic #include <stdlib.h> 1541457Sbostic #include <stdio.h> 1655201Sbostic #include <ctype.h> 1741457Sbostic #include "hexdump.h" 1841457Sbostic 1941457Sbostic int deprecated; 2041457Sbostic 2155201Sbostic static void odoffset __P((int, char ***)); 2255201Sbostic static void odprecede __P((void)); 2355201Sbostic 2455201Sbostic void 2541457Sbostic oldsyntax(argc, argvp) 2641457Sbostic int argc; 2741457Sbostic char ***argvp; 2841457Sbostic { 2941457Sbostic extern enum _vflag vflag; 3041457Sbostic extern FS *fshead; 3147154Sbostic int ch; 3241457Sbostic char **argv; 3341457Sbostic 3441457Sbostic deprecated = 1; 3541457Sbostic argv = *argvp; 3641457Sbostic while ((ch = getopt(argc, argv, "aBbcDdeFfHhIiLlOoPpswvXx")) != EOF) 3741457Sbostic switch (ch) { 3841457Sbostic case 'a': 3947154Sbostic odprecede(); 4042362Sbostic add("16/1 \"%3_u \" \"\\n\""); 4141457Sbostic break; 4241457Sbostic case 'B': 4341457Sbostic case 'o': 4447154Sbostic odprecede(); 4542362Sbostic add("8/2 \" %06o \" \"\\n\""); 4641457Sbostic break; 4741457Sbostic case 'b': 4847154Sbostic odprecede(); 4942362Sbostic add("16/1 \"%03o \" \"\\n\""); 5041457Sbostic break; 5141457Sbostic case 'c': 5247154Sbostic odprecede(); 5342362Sbostic add("16/1 \"%3_c \" \"\\n\""); 5441457Sbostic break; 5541457Sbostic case 'd': 5647154Sbostic odprecede(); 5742362Sbostic add("8/2 \" %05u \" \"\\n\""); 5841457Sbostic break; 5941457Sbostic case 'D': 6047154Sbostic odprecede(); 6142362Sbostic add("4/4 \" %010u \" \"\\n\""); 6241457Sbostic break; 6341457Sbostic case 'e': /* undocumented in od */ 6441457Sbostic case 'F': 6547154Sbostic odprecede(); 6642362Sbostic add("2/8 \" %21.14e \" \"\\n\""); 6741457Sbostic break; 6841457Sbostic 6941457Sbostic case 'f': 7047154Sbostic odprecede(); 7142362Sbostic add("4/4 \" %14.7e \" \"\\n\""); 7241457Sbostic break; 7341457Sbostic case 'H': 7441457Sbostic case 'X': 7547154Sbostic odprecede(); 7642362Sbostic add("4/4 \" %08x \" \"\\n\""); 7741457Sbostic break; 7841457Sbostic case 'h': 7941457Sbostic case 'x': 8047154Sbostic odprecede(); 8142362Sbostic add("8/2 \" %04x \" \"\\n\""); 8241457Sbostic break; 8341457Sbostic case 'I': 8441457Sbostic case 'L': 8541457Sbostic case 'l': 8647154Sbostic odprecede(); 8742362Sbostic add("4/4 \" %11d \" \"\\n\""); 8841457Sbostic break; 8941457Sbostic case 'i': 9047154Sbostic odprecede(); 9142362Sbostic add("8/2 \" %6d \" \"\\n\""); 9241457Sbostic break; 9341457Sbostic case 'O': 9447154Sbostic odprecede(); 9542362Sbostic add("4/4 \" %011o \" \"\\n\""); 9641457Sbostic break; 9741457Sbostic case 'v': 9841457Sbostic vflag = ALL; 9941457Sbostic break; 10041457Sbostic case 'P': 10141457Sbostic case 'p': 10241457Sbostic case 's': 10341457Sbostic case 'w': 10441457Sbostic case '?': 10541457Sbostic default: 10641457Sbostic (void)fprintf(stderr, 10741457Sbostic "od: od(1) has been deprecated for hexdump(1).\n"); 10841457Sbostic if (ch != '?') 10941457Sbostic (void)fprintf(stderr, 11041457Sbostic "od: hexdump(1) compatibility doesn't support the -%c option%s\n", 11141457Sbostic ch, ch == 's' ? "; see strings(1)." : "."); 11241457Sbostic usage(); 11341457Sbostic } 11441457Sbostic 11541457Sbostic if (!fshead) { 11641457Sbostic add("\"%07.7_Ao\n\""); 11741457Sbostic add("\"%07.7_ao \" 8/2 \"%06o \" \"\\n\""); 11841457Sbostic } 11941457Sbostic 12045217Sbostic argc -= optind; 12141457Sbostic *argvp += optind; 12245217Sbostic 12352141Sbostic if (argc) 12452141Sbostic odoffset(argc, argvp); 12541457Sbostic } 12645217Sbostic 12755201Sbostic static void 12845217Sbostic odoffset(argc, argvp) 12945217Sbostic int argc; 13045217Sbostic char ***argvp; 13145217Sbostic { 13245217Sbostic extern off_t skip; 13345217Sbostic register char *num, *p; 13445217Sbostic int base; 13545217Sbostic char *end; 13645217Sbostic 13745217Sbostic /* 13845217Sbostic * The offset syntax of od(1) was genuinely bizarre. First, if 13945217Sbostic * it started with a plus it had to be an offset. Otherwise, if 14045217Sbostic * there were at least two arguments, a number or lower-case 'x' 14145217Sbostic * followed by a number makes it an offset. By default it was 14245217Sbostic * octal; if it started with 'x' or '0x' it was hex. If it ended 14345217Sbostic * in a '.', it was decimal. If a 'b' or 'B' was appended, it 14445217Sbostic * multiplied the number by 512 or 1024 byte units. There was 14545217Sbostic * no way to assign a block count to a hex offset. 14645217Sbostic * 14752141Sbostic * We assume it's a file if the offset is bad. 14845217Sbostic */ 14952790Sbostic p = argc == 1 ? (*argvp)[0] : (*argvp)[1]; 15052790Sbostic 15145217Sbostic if (*p != '+' && (argc < 2 || 15252141Sbostic (!isdigit(p[0]) && (p[0] != 'x' || !isxdigit(p[1]))))) 15345217Sbostic return; 15445217Sbostic 15545217Sbostic base = 0; 15645217Sbostic /* 15745217Sbostic * skip over leading '+', 'x[0-9a-fA-f]' or '0x', and 15845217Sbostic * set base. 15945217Sbostic */ 16045217Sbostic if (p[0] == '+') 16145217Sbostic ++p; 16252141Sbostic if (p[0] == 'x' && isxdigit(p[1])) { 16345217Sbostic ++p; 16445217Sbostic base = 16; 16545217Sbostic } else if (p[0] == '0' && p[1] == 'x') { 16645217Sbostic p += 2; 16745217Sbostic base = 16; 16845217Sbostic } 16945217Sbostic 17045217Sbostic /* skip over the number */ 17145217Sbostic if (base == 16) 17252141Sbostic for (num = p; isxdigit(*p); ++p); 17345217Sbostic else 17445217Sbostic for (num = p; isdigit(*p); ++p); 17545217Sbostic 17645217Sbostic /* check for no number */ 17745217Sbostic if (num == p) 17845217Sbostic return; 17945217Sbostic 18045217Sbostic /* if terminates with a '.', base is decimal */ 18145217Sbostic if (*p == '.') { 18245217Sbostic if (base) 18345217Sbostic return; 18445217Sbostic base = 10; 18545217Sbostic } 18645217Sbostic 18745217Sbostic skip = strtol(num, &end, base ? base : 8); 18845217Sbostic 18945217Sbostic /* if end isn't the same as p, we got a non-octal digit */ 19052790Sbostic if (end != p) { 19145217Sbostic skip = 0; 19252790Sbostic return; 19352790Sbostic } 19452790Sbostic 19552790Sbostic if (*p) 19652790Sbostic if (*p == 'B') { 19752790Sbostic skip *= 1024; 19845217Sbostic ++p; 19952790Sbostic } else if (*p == 'b') { 20052790Sbostic skip *= 512; 20152790Sbostic ++p; 20245217Sbostic } 20352790Sbostic 20452790Sbostic if (*p) { 20552790Sbostic skip = 0; 20652790Sbostic return; 20752790Sbostic } 20852790Sbostic 20952790Sbostic /* 21052790Sbostic * If the offset uses a non-octal base, the base of the offset 21152790Sbostic * is changed as well. This isn't pretty, but it's easy. 21252790Sbostic */ 21345217Sbostic #define TYPE_OFFSET 7 21452790Sbostic if (base == 16) { 21552790Sbostic fshead->nextfu->fmt[TYPE_OFFSET] = 'x'; 21652790Sbostic fshead->nextfs->nextfu->fmt[TYPE_OFFSET] = 'x'; 21752790Sbostic } else if (base == 10) { 21852790Sbostic fshead->nextfu->fmt[TYPE_OFFSET] = 'd'; 21952790Sbostic fshead->nextfs->nextfu->fmt[TYPE_OFFSET] = 'd'; 22045217Sbostic } 22152790Sbostic 22252790Sbostic /* Terminate file list. */ 22352790Sbostic (*argvp)[1] = NULL; 22445217Sbostic } 22547154Sbostic 22647154Sbostic static void 22747154Sbostic odprecede() 22847154Sbostic { 22947154Sbostic static int first = 1; 23047154Sbostic 23147154Sbostic if (first) { 23247154Sbostic first = 0; 23347154Sbostic add("\"%07.7_Ao\n\""); 23447154Sbostic add("\"%07.7_ao \""); 23547154Sbostic } else 23647154Sbostic add("\" \""); 23747154Sbostic } 238