141457Sbostic /*- 241457Sbostic * Copyright (c) 1990 The Regents of the University of California. 341457Sbostic * All rights reserved. 441457Sbostic * 541457Sbostic * %sccs.include.redist.c% 641457Sbostic */ 741457Sbostic 841457Sbostic #ifndef lint 9*45217Sbostic static char sccsid[] = "@(#)odsyntax.c 5.3 (Berkeley) 09/06/90"; 1041457Sbostic #endif /* not lint */ 1141457Sbostic 1241457Sbostic #include <sys/types.h> 13*45217Sbostic #include <stdlib.h> 1441457Sbostic #include <stdio.h> 1541457Sbostic #include "hexdump.h" 1641457Sbostic 1741457Sbostic int deprecated; 1841457Sbostic 1941457Sbostic oldsyntax(argc, argvp) 2041457Sbostic int argc; 2141457Sbostic char ***argvp; 2241457Sbostic { 2341457Sbostic extern enum _vflag vflag; 2441457Sbostic extern FS *fshead; 2541457Sbostic extern char *optarg; 2641457Sbostic extern int length, optind; 2742362Sbostic int ch, first; 2841457Sbostic char **argv; 2941457Sbostic 3041457Sbostic deprecated = 1; 3142362Sbostic first = 0; 3241457Sbostic argv = *argvp; 3341457Sbostic while ((ch = getopt(argc, argv, "aBbcDdeFfHhIiLlOoPpswvXx")) != EOF) 3441457Sbostic switch (ch) { 3541457Sbostic case 'a': 3642362Sbostic if (!first++) { 3742362Sbostic add("\"%07.7_Ao\n\""); 3842362Sbostic add("\"%07.7_ao \""); 3942362Sbostic } else 4042362Sbostic add("\" \""); 4142362Sbostic add("16/1 \"%3_u \" \"\\n\""); 4241457Sbostic break; 4341457Sbostic case 'B': 4441457Sbostic case 'o': 4542362Sbostic if (!first++) { 4642362Sbostic add("\"%07.7_Ao\n\""); 4742362Sbostic add("\"%07.7_ao \""); 4842362Sbostic } else 4942362Sbostic add("\" \""); 5042362Sbostic add("8/2 \" %06o \" \"\\n\""); 5141457Sbostic break; 5241457Sbostic case 'b': 5342362Sbostic if (!first++) { 5442362Sbostic add("\"%07.7_Ao\n\""); 5542362Sbostic add("\"%07.7_ao \""); 5642362Sbostic } else 5742362Sbostic add("\" \""); 5842362Sbostic add("16/1 \"%03o \" \"\\n\""); 5941457Sbostic break; 6041457Sbostic case 'c': 6142362Sbostic if (!first++) { 6242362Sbostic add("\"%07.7_Ao\n\""); 6342362Sbostic add("\"%07.7_ao \""); 6442362Sbostic } else 6542362Sbostic add("\" \""); 6642362Sbostic add("16/1 \"%3_c \" \"\\n\""); 6741457Sbostic break; 6841457Sbostic case 'd': 6942362Sbostic if (!first++) { 7042362Sbostic add("\"%07.7_Ao\n\""); 7142362Sbostic add("\"%07.7_ao \""); 7242362Sbostic } else 7342362Sbostic add("\" \""); 7442362Sbostic add("8/2 \" %05u \" \"\\n\""); 7541457Sbostic break; 7641457Sbostic case 'D': 7742362Sbostic if (!first++) { 7842362Sbostic add("\"%07.7_Ao\n\""); 7942362Sbostic add("\"%07.7_ao \""); 8042362Sbostic } else 8142362Sbostic add("\" \""); 8242362Sbostic add("4/4 \" %010u \" \"\\n\""); 8341457Sbostic break; 8441457Sbostic case 'e': /* undocumented in od */ 8541457Sbostic case 'F': 8642362Sbostic if (!first++) { 8742362Sbostic add("\"%07.7_Ao\n\""); 8842362Sbostic add("\"%07.7_ao \""); 8942362Sbostic } else 9042362Sbostic add("\" \""); 9142362Sbostic add("2/8 \" %21.14e \" \"\\n\""); 9241457Sbostic break; 9341457Sbostic 9441457Sbostic case 'f': 9542362Sbostic if (!first++) { 9642362Sbostic add("\"%07.7_Ao\n\""); 9742362Sbostic add("\"%07.7_ao \""); 9842362Sbostic } else 9942362Sbostic add("\" \""); 10042362Sbostic add("4/4 \" %14.7e \" \"\\n\""); 10141457Sbostic break; 10241457Sbostic case 'H': 10341457Sbostic case 'X': 10442362Sbostic if (!first++) { 10542362Sbostic add("\"%07.7_Ao\n\""); 10642362Sbostic add("\"%07.7_ao \""); 10742362Sbostic } else 10842362Sbostic add("\" \""); 10942362Sbostic add("4/4 \" %08x \" \"\\n\""); 11041457Sbostic break; 11141457Sbostic case 'h': 11241457Sbostic case 'x': 11342362Sbostic if (!first++) { 11442362Sbostic add("\"%07.7_Ao\n\""); 11542362Sbostic add("\"%07.7_ao \""); 11642362Sbostic } else 11742362Sbostic add("\" \""); 11842362Sbostic add("8/2 \" %04x \" \"\\n\""); 11941457Sbostic break; 12041457Sbostic case 'I': 12141457Sbostic case 'L': 12241457Sbostic case 'l': 12342362Sbostic if (!first++) { 12442362Sbostic add("\"%07.7_Ao\n\""); 12542362Sbostic add("\"%07.7_ao \""); 12642362Sbostic } else 12742362Sbostic add("\" \""); 12842362Sbostic add("4/4 \" %11d \" \"\\n\""); 12941457Sbostic break; 13041457Sbostic case 'i': 13142362Sbostic if (!first++) { 13242362Sbostic add("\"%07.7_Ao\n\""); 13342362Sbostic add("\"%07.7_ao \""); 13442362Sbostic } else 13542362Sbostic add("\" \""); 13642362Sbostic add("8/2 \" %6d \" \"\\n\""); 13741457Sbostic break; 13841457Sbostic case 'O': 13942362Sbostic if (!first++) { 14042362Sbostic add("\"%07.7_Ao\n\""); 14142362Sbostic add("\"%07.7_ao \""); 14242362Sbostic } else 14342362Sbostic add("\" \""); 14442362Sbostic add("4/4 \" %011o \" \"\\n\""); 14541457Sbostic break; 14641457Sbostic case 'v': 14741457Sbostic vflag = ALL; 14841457Sbostic break; 14941457Sbostic case 'P': 15041457Sbostic case 'p': 15141457Sbostic case 's': 15241457Sbostic case 'w': 15341457Sbostic case '?': 15441457Sbostic default: 15541457Sbostic (void)fprintf(stderr, 15641457Sbostic "od: od(1) has been deprecated for hexdump(1).\n"); 15741457Sbostic if (ch != '?') 15841457Sbostic (void)fprintf(stderr, 15941457Sbostic "od: hexdump(1) compatibility doesn't support the -%c option%s\n", 16041457Sbostic ch, ch == 's' ? "; see strings(1)." : "."); 16141457Sbostic usage(); 16241457Sbostic } 16341457Sbostic 16441457Sbostic if (!fshead) { 16541457Sbostic add("\"%07.7_Ao\n\""); 16641457Sbostic add("\"%07.7_ao \" 8/2 \"%06o \" \"\\n\""); 16741457Sbostic } 16841457Sbostic 169*45217Sbostic argc -= optind; 17041457Sbostic *argvp += optind; 171*45217Sbostic 172*45217Sbostic odoffset(argc, argvp); 17341457Sbostic } 174*45217Sbostic 175*45217Sbostic #define ishexdigit(c) \ 176*45217Sbostic (c >= '0' && c <= '9' || c >= 'a' && c <= 'f' || c >= 'A' && c <= 'F') 177*45217Sbostic 178*45217Sbostic odoffset(argc, argvp) 179*45217Sbostic int argc; 180*45217Sbostic char ***argvp; 181*45217Sbostic { 182*45217Sbostic extern off_t skip; 183*45217Sbostic register char *num, *p; 184*45217Sbostic int base; 185*45217Sbostic char *end; 186*45217Sbostic 187*45217Sbostic /* 188*45217Sbostic * The offset syntax of od(1) was genuinely bizarre. First, if 189*45217Sbostic * it started with a plus it had to be an offset. Otherwise, if 190*45217Sbostic * there were at least two arguments, a number or lower-case 'x' 191*45217Sbostic * followed by a number makes it an offset. By default it was 192*45217Sbostic * octal; if it started with 'x' or '0x' it was hex. If it ended 193*45217Sbostic * in a '.', it was decimal. If a 'b' or 'B' was appended, it 194*45217Sbostic * multiplied the number by 512 or 1024 byte units. There was 195*45217Sbostic * no way to assign a block count to a hex offset. 196*45217Sbostic * 197*45217Sbostic * We assumes it's a file if the offset is bad. 198*45217Sbostic */ 199*45217Sbostic p = **argvp; 200*45217Sbostic if (*p != '+' && (argc < 2 || 201*45217Sbostic (!isdigit(p[0]) && (p[0] != 'x' || !ishexdigit(p[1]))))) 202*45217Sbostic return; 203*45217Sbostic 204*45217Sbostic base = 0; 205*45217Sbostic /* 206*45217Sbostic * skip over leading '+', 'x[0-9a-fA-f]' or '0x', and 207*45217Sbostic * set base. 208*45217Sbostic */ 209*45217Sbostic if (p[0] == '+') 210*45217Sbostic ++p; 211*45217Sbostic if (p[0] == 'x' && ishexdigit(p[1])) { 212*45217Sbostic ++p; 213*45217Sbostic base = 16; 214*45217Sbostic } else if (p[0] == '0' && p[1] == 'x') { 215*45217Sbostic p += 2; 216*45217Sbostic base = 16; 217*45217Sbostic } 218*45217Sbostic 219*45217Sbostic /* skip over the number */ 220*45217Sbostic if (base == 16) 221*45217Sbostic for (num = p; ishexdigit(*p); ++p); 222*45217Sbostic else 223*45217Sbostic for (num = p; isdigit(*p); ++p); 224*45217Sbostic 225*45217Sbostic /* check for no number */ 226*45217Sbostic if (num == p) 227*45217Sbostic return; 228*45217Sbostic 229*45217Sbostic /* if terminates with a '.', base is decimal */ 230*45217Sbostic if (*p == '.') { 231*45217Sbostic if (base) 232*45217Sbostic return; 233*45217Sbostic base = 10; 234*45217Sbostic } 235*45217Sbostic 236*45217Sbostic skip = strtol(num, &end, base ? base : 8); 237*45217Sbostic 238*45217Sbostic /* if end isn't the same as p, we got a non-octal digit */ 239*45217Sbostic if (end != p) 240*45217Sbostic skip = 0; 241*45217Sbostic else { 242*45217Sbostic if (*p) { 243*45217Sbostic if (*p == 'b') 244*45217Sbostic skip *= 512; 245*45217Sbostic else if (*p == 'B') 246*45217Sbostic skip *= 1024; 247*45217Sbostic ++p; 248*45217Sbostic } 249*45217Sbostic if (*p) 250*45217Sbostic skip = 0; 251*45217Sbostic else { 252*45217Sbostic ++*argvp; 253*45217Sbostic /* 254*45217Sbostic * If the offset uses a non-octal base, the base of 255*45217Sbostic * the offset is changed as well. This isn't pretty, 256*45217Sbostic * but it's easy. 257*45217Sbostic */ 258*45217Sbostic #define TYPE_OFFSET 7 259*45217Sbostic if (base == 16) { 260*45217Sbostic fshead->nextfu->fmt[TYPE_OFFSET] = 'x'; 261*45217Sbostic fshead->nextfs->nextfu->fmt[TYPE_OFFSET] = 'x'; 262*45217Sbostic } else if (base == 10) { 263*45217Sbostic fshead->nextfu->fmt[TYPE_OFFSET] = 'd'; 264*45217Sbostic fshead->nextfs->nextfu->fmt[TYPE_OFFSET] = 'd'; 265*45217Sbostic } 266*45217Sbostic } 267*45217Sbostic } 268*45217Sbostic } 269