1 /*- 2 * Copyright (c) 1990 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)odsyntax.c 5.3 (Berkeley) 09/06/90"; 10 #endif /* not lint */ 11 12 #include <sys/types.h> 13 #include <stdlib.h> 14 #include <stdio.h> 15 #include "hexdump.h" 16 17 int deprecated; 18 19 oldsyntax(argc, argvp) 20 int argc; 21 char ***argvp; 22 { 23 extern enum _vflag vflag; 24 extern FS *fshead; 25 extern char *optarg; 26 extern int length, optind; 27 int ch, first; 28 char **argv; 29 30 deprecated = 1; 31 first = 0; 32 argv = *argvp; 33 while ((ch = getopt(argc, argv, "aBbcDdeFfHhIiLlOoPpswvXx")) != EOF) 34 switch (ch) { 35 case 'a': 36 if (!first++) { 37 add("\"%07.7_Ao\n\""); 38 add("\"%07.7_ao \""); 39 } else 40 add("\" \""); 41 add("16/1 \"%3_u \" \"\\n\""); 42 break; 43 case 'B': 44 case 'o': 45 if (!first++) { 46 add("\"%07.7_Ao\n\""); 47 add("\"%07.7_ao \""); 48 } else 49 add("\" \""); 50 add("8/2 \" %06o \" \"\\n\""); 51 break; 52 case 'b': 53 if (!first++) { 54 add("\"%07.7_Ao\n\""); 55 add("\"%07.7_ao \""); 56 } else 57 add("\" \""); 58 add("16/1 \"%03o \" \"\\n\""); 59 break; 60 case 'c': 61 if (!first++) { 62 add("\"%07.7_Ao\n\""); 63 add("\"%07.7_ao \""); 64 } else 65 add("\" \""); 66 add("16/1 \"%3_c \" \"\\n\""); 67 break; 68 case 'd': 69 if (!first++) { 70 add("\"%07.7_Ao\n\""); 71 add("\"%07.7_ao \""); 72 } else 73 add("\" \""); 74 add("8/2 \" %05u \" \"\\n\""); 75 break; 76 case 'D': 77 if (!first++) { 78 add("\"%07.7_Ao\n\""); 79 add("\"%07.7_ao \""); 80 } else 81 add("\" \""); 82 add("4/4 \" %010u \" \"\\n\""); 83 break; 84 case 'e': /* undocumented in od */ 85 case 'F': 86 if (!first++) { 87 add("\"%07.7_Ao\n\""); 88 add("\"%07.7_ao \""); 89 } else 90 add("\" \""); 91 add("2/8 \" %21.14e \" \"\\n\""); 92 break; 93 94 case 'f': 95 if (!first++) { 96 add("\"%07.7_Ao\n\""); 97 add("\"%07.7_ao \""); 98 } else 99 add("\" \""); 100 add("4/4 \" %14.7e \" \"\\n\""); 101 break; 102 case 'H': 103 case 'X': 104 if (!first++) { 105 add("\"%07.7_Ao\n\""); 106 add("\"%07.7_ao \""); 107 } else 108 add("\" \""); 109 add("4/4 \" %08x \" \"\\n\""); 110 break; 111 case 'h': 112 case 'x': 113 if (!first++) { 114 add("\"%07.7_Ao\n\""); 115 add("\"%07.7_ao \""); 116 } else 117 add("\" \""); 118 add("8/2 \" %04x \" \"\\n\""); 119 break; 120 case 'I': 121 case 'L': 122 case 'l': 123 if (!first++) { 124 add("\"%07.7_Ao\n\""); 125 add("\"%07.7_ao \""); 126 } else 127 add("\" \""); 128 add("4/4 \" %11d \" \"\\n\""); 129 break; 130 case 'i': 131 if (!first++) { 132 add("\"%07.7_Ao\n\""); 133 add("\"%07.7_ao \""); 134 } else 135 add("\" \""); 136 add("8/2 \" %6d \" \"\\n\""); 137 break; 138 case 'O': 139 if (!first++) { 140 add("\"%07.7_Ao\n\""); 141 add("\"%07.7_ao \""); 142 } else 143 add("\" \""); 144 add("4/4 \" %011o \" \"\\n\""); 145 break; 146 case 'v': 147 vflag = ALL; 148 break; 149 case 'P': 150 case 'p': 151 case 's': 152 case 'w': 153 case '?': 154 default: 155 (void)fprintf(stderr, 156 "od: od(1) has been deprecated for hexdump(1).\n"); 157 if (ch != '?') 158 (void)fprintf(stderr, 159 "od: hexdump(1) compatibility doesn't support the -%c option%s\n", 160 ch, ch == 's' ? "; see strings(1)." : "."); 161 usage(); 162 } 163 164 if (!fshead) { 165 add("\"%07.7_Ao\n\""); 166 add("\"%07.7_ao \" 8/2 \"%06o \" \"\\n\""); 167 } 168 169 argc -= optind; 170 *argvp += optind; 171 172 odoffset(argc, argvp); 173 } 174 175 #define ishexdigit(c) \ 176 (c >= '0' && c <= '9' || c >= 'a' && c <= 'f' || c >= 'A' && c <= 'F') 177 178 odoffset(argc, argvp) 179 int argc; 180 char ***argvp; 181 { 182 extern off_t skip; 183 register char *num, *p; 184 int base; 185 char *end; 186 187 /* 188 * The offset syntax of od(1) was genuinely bizarre. First, if 189 * it started with a plus it had to be an offset. Otherwise, if 190 * there were at least two arguments, a number or lower-case 'x' 191 * followed by a number makes it an offset. By default it was 192 * octal; if it started with 'x' or '0x' it was hex. If it ended 193 * in a '.', it was decimal. If a 'b' or 'B' was appended, it 194 * multiplied the number by 512 or 1024 byte units. There was 195 * no way to assign a block count to a hex offset. 196 * 197 * We assumes it's a file if the offset is bad. 198 */ 199 p = **argvp; 200 if (*p != '+' && (argc < 2 || 201 (!isdigit(p[0]) && (p[0] != 'x' || !ishexdigit(p[1]))))) 202 return; 203 204 base = 0; 205 /* 206 * skip over leading '+', 'x[0-9a-fA-f]' or '0x', and 207 * set base. 208 */ 209 if (p[0] == '+') 210 ++p; 211 if (p[0] == 'x' && ishexdigit(p[1])) { 212 ++p; 213 base = 16; 214 } else if (p[0] == '0' && p[1] == 'x') { 215 p += 2; 216 base = 16; 217 } 218 219 /* skip over the number */ 220 if (base == 16) 221 for (num = p; ishexdigit(*p); ++p); 222 else 223 for (num = p; isdigit(*p); ++p); 224 225 /* check for no number */ 226 if (num == p) 227 return; 228 229 /* if terminates with a '.', base is decimal */ 230 if (*p == '.') { 231 if (base) 232 return; 233 base = 10; 234 } 235 236 skip = strtol(num, &end, base ? base : 8); 237 238 /* if end isn't the same as p, we got a non-octal digit */ 239 if (end != p) 240 skip = 0; 241 else { 242 if (*p) { 243 if (*p == 'b') 244 skip *= 512; 245 else if (*p == 'B') 246 skip *= 1024; 247 ++p; 248 } 249 if (*p) 250 skip = 0; 251 else { 252 ++*argvp; 253 /* 254 * If the offset uses a non-octal base, the base of 255 * the offset is changed as well. This isn't pretty, 256 * but it's easy. 257 */ 258 #define TYPE_OFFSET 7 259 if (base == 16) { 260 fshead->nextfu->fmt[TYPE_OFFSET] = 'x'; 261 fshead->nextfs->nextfu->fmt[TYPE_OFFSET] = 'x'; 262 } else if (base == 10) { 263 fshead->nextfu->fmt[TYPE_OFFSET] = 'd'; 264 fshead->nextfs->nextfu->fmt[TYPE_OFFSET] = 'd'; 265 } 266 } 267 } 268 } 269