odsyntax.c revision 48566
11590Srgrimes/*-
21590Srgrimes * Copyright (c) 1990, 1993
31590Srgrimes *	The Regents of the University of California.  All rights reserved.
41590Srgrimes *
51590Srgrimes * Redistribution and use in source and binary forms, with or without
61590Srgrimes * modification, are permitted provided that the following conditions
71590Srgrimes * are met:
81590Srgrimes * 1. Redistributions of source code must retain the above copyright
91590Srgrimes *    notice, this list of conditions and the following disclaimer.
101590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
111590Srgrimes *    notice, this list of conditions and the following disclaimer in the
121590Srgrimes *    documentation and/or other materials provided with the distribution.
131590Srgrimes * 3. All advertising materials mentioning features or use of this software
141590Srgrimes *    must display the following acknowledgement:
151590Srgrimes *	This product includes software developed by the University of
161590Srgrimes *	California, Berkeley and its contributors.
171590Srgrimes * 4. Neither the name of the University nor the names of its contributors
181590Srgrimes *    may be used to endorse or promote products derived from this software
191590Srgrimes *    without specific prior written permission.
201590Srgrimes *
211590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
221590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
231590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
241590Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
251590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
261590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
271590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
281590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
291590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
301590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
311590Srgrimes * SUCH DAMAGE.
321590Srgrimes */
331590Srgrimes
341590Srgrimes#ifndef lint
3527315Scharnier#if 0
3623693Speterstatic char sccsid[] = "@(#)odsyntax.c	8.2 (Berkeley) 5/4/95";
3727315Scharnier#endif
3827315Scharnierstatic const char rcsid[] =
3948566Sbillf	"$Id: odsyntax.c,v 1.6 1997/11/04 05:33:14 ache Exp $";
401590Srgrimes#endif /* not lint */
411590Srgrimes
421590Srgrimes#include <sys/types.h>
431590Srgrimes
4423693Speter#include <ctype.h>
4527315Scharnier#include <err.h>
4623693Speter#include <stdio.h>
471590Srgrimes#include <stdlib.h>
4823693Speter#include <unistd.h>
4923693Speter
501590Srgrimes#include "hexdump.h"
511590Srgrimes
521590Srgrimesint deprecated;
531590Srgrimes
541590Srgrimesstatic void odoffset __P((int, char ***));
551590Srgrimesstatic void odprecede __P((void));
561590Srgrimes
571590Srgrimesvoid
581590Srgrimesoldsyntax(argc, argvp)
591590Srgrimes	int argc;
601590Srgrimes	char ***argvp;
611590Srgrimes{
621590Srgrimes	extern enum _vflag vflag;
631590Srgrimes	extern FS *fshead;
641590Srgrimes	int ch;
651590Srgrimes	char **argv;
661590Srgrimes
671590Srgrimes	deprecated = 1;
681590Srgrimes	argv = *argvp;
6924360Simp	while ((ch = getopt(argc, argv, "aBbcDdeFfHhIiLlOoPpswvXx")) != -1)
701590Srgrimes		switch (ch) {
711590Srgrimes		case 'a':
721590Srgrimes			odprecede();
731590Srgrimes			add("16/1 \"%3_u \" \"\\n\"");
741590Srgrimes			break;
751590Srgrimes		case 'B':
761590Srgrimes		case 'o':
771590Srgrimes			odprecede();
781590Srgrimes			add("8/2 \" %06o \" \"\\n\"");
791590Srgrimes			break;
801590Srgrimes		case 'b':
811590Srgrimes			odprecede();
821590Srgrimes			add("16/1 \"%03o \" \"\\n\"");
831590Srgrimes			break;
841590Srgrimes		case 'c':
851590Srgrimes			odprecede();
861590Srgrimes			add("16/1 \"%3_c \" \"\\n\"");
871590Srgrimes			break;
881590Srgrimes		case 'd':
891590Srgrimes			odprecede();
901590Srgrimes			add("8/2 \"  %05u \" \"\\n\"");
911590Srgrimes			break;
921590Srgrimes		case 'D':
931590Srgrimes			odprecede();
941590Srgrimes			add("4/4 \"     %010u \" \"\\n\"");
951590Srgrimes			break;
961590Srgrimes		case 'e':		/* undocumented in od */
971590Srgrimes		case 'F':
981590Srgrimes			odprecede();
991590Srgrimes			add("2/8 \"          %21.14e \" \"\\n\"");
1001590Srgrimes			break;
1018874Srgrimes
1021590Srgrimes		case 'f':
1031590Srgrimes			odprecede();
1041590Srgrimes			add("4/4 \" %14.7e \" \"\\n\"");
1051590Srgrimes			break;
1061590Srgrimes		case 'H':
1071590Srgrimes		case 'X':
1081590Srgrimes			odprecede();
1091590Srgrimes			add("4/4 \"       %08x \" \"\\n\"");
1101590Srgrimes			break;
1111590Srgrimes		case 'h':
1121590Srgrimes		case 'x':
1131590Srgrimes			odprecede();
1141590Srgrimes			add("8/2 \"   %04x \" \"\\n\"");
1151590Srgrimes			break;
1161590Srgrimes		case 'I':
1171590Srgrimes		case 'L':
1181590Srgrimes		case 'l':
1191590Srgrimes			odprecede();
1201590Srgrimes			add("4/4 \"    %11d \" \"\\n\"");
1211590Srgrimes			break;
1221590Srgrimes		case 'i':
1231590Srgrimes			odprecede();
1241590Srgrimes			add("8/2 \" %6d \" \"\\n\"");
1251590Srgrimes			break;
1261590Srgrimes		case 'O':
1271590Srgrimes			odprecede();
1281590Srgrimes			add("4/4 \"    %011o \" \"\\n\"");
1291590Srgrimes			break;
1301590Srgrimes		case 'v':
1311590Srgrimes			vflag = ALL;
1321590Srgrimes			break;
1331590Srgrimes		case 'P':
1341590Srgrimes		case 'p':
1351590Srgrimes		case 's':
1361590Srgrimes		case 'w':
1371590Srgrimes		case '?':
1381590Srgrimes		default:
13927315Scharnier			warnx("od(1) has been deprecated for hexdump(1)");
1401590Srgrimes			if (ch != '?')
14127315Scharnier				warnx("hexdump(1) compatibility doesn't support the -%c option%s",
14227315Scharnier				    ch, ch == 's' ? "; see strings(1)" : "");
1431590Srgrimes			usage();
1441590Srgrimes		}
1451590Srgrimes
1461590Srgrimes	if (!fshead) {
1471590Srgrimes		add("\"%07.7_Ao\n\"");
1481590Srgrimes		add("\"%07.7_ao  \" 8/2 \"%06o \" \"\\n\"");
1491590Srgrimes	}
1501590Srgrimes
1511590Srgrimes	argc -= optind;
1521590Srgrimes	*argvp += optind;
1531590Srgrimes
1541590Srgrimes	if (argc)
1551590Srgrimes		odoffset(argc, argvp);
1561590Srgrimes}
1571590Srgrimes
1581590Srgrimesstatic void
1591590Srgrimesodoffset(argc, argvp)
1601590Srgrimes	int argc;
1611590Srgrimes	char ***argvp;
1621590Srgrimes{
1631590Srgrimes	extern off_t skip;
16430921Sache	unsigned char *p, *num, *end;
1651590Srgrimes	int base;
1661590Srgrimes
1671590Srgrimes	/*
1681590Srgrimes	 * The offset syntax of od(1) was genuinely bizarre.  First, if
1691590Srgrimes	 * it started with a plus it had to be an offset.  Otherwise, if
1701590Srgrimes	 * there were at least two arguments, a number or lower-case 'x'
1711590Srgrimes	 * followed by a number makes it an offset.  By default it was
1721590Srgrimes	 * octal; if it started with 'x' or '0x' it was hex.  If it ended
1731590Srgrimes	 * in a '.', it was decimal.  If a 'b' or 'B' was appended, it
1741590Srgrimes	 * multiplied the number by 512 or 1024 byte units.  There was
1751590Srgrimes	 * no way to assign a block count to a hex offset.
1761590Srgrimes	 *
1771590Srgrimes	 * We assume it's a file if the offset is bad.
1781590Srgrimes	 */
1791590Srgrimes	p = argc == 1 ? (*argvp)[0] : (*argvp)[1];
1801590Srgrimes
1811590Srgrimes	if (*p != '+' && (argc < 2 ||
1821590Srgrimes	    (!isdigit(p[0]) && (p[0] != 'x' || !isxdigit(p[1])))))
1831590Srgrimes		return;
1841590Srgrimes
1851590Srgrimes	base = 0;
1861590Srgrimes	/*
1871590Srgrimes	 * skip over leading '+', 'x[0-9a-fA-f]' or '0x', and
1881590Srgrimes	 * set base.
1891590Srgrimes	 */
1901590Srgrimes	if (p[0] == '+')
1911590Srgrimes		++p;
1921590Srgrimes	if (p[0] == 'x' && isxdigit(p[1])) {
1931590Srgrimes		++p;
1941590Srgrimes		base = 16;
1951590Srgrimes	} else if (p[0] == '0' && p[1] == 'x') {
1961590Srgrimes		p += 2;
1971590Srgrimes		base = 16;
1981590Srgrimes	}
1991590Srgrimes
2001590Srgrimes	/* skip over the number */
2011590Srgrimes	if (base == 16)
2021590Srgrimes		for (num = p; isxdigit(*p); ++p);
2031590Srgrimes	else
2041590Srgrimes		for (num = p; isdigit(*p); ++p);
2051590Srgrimes
2061590Srgrimes	/* check for no number */
2071590Srgrimes	if (num == p)
2081590Srgrimes		return;
2091590Srgrimes
2101590Srgrimes	/* if terminates with a '.', base is decimal */
2111590Srgrimes	if (*p == '.') {
2121590Srgrimes		if (base)
2131590Srgrimes			return;
2141590Srgrimes		base = 10;
2151590Srgrimes	}
2161590Srgrimes
21730921Sache	skip = strtol(num, (char **)&end, base ? base : 8);
2181590Srgrimes
2191590Srgrimes	/* if end isn't the same as p, we got a non-octal digit */
2201590Srgrimes	if (end != p) {
2211590Srgrimes		skip = 0;
2221590Srgrimes		return;
2231590Srgrimes	}
2241590Srgrimes
22548566Sbillf	if (*p) {
2261590Srgrimes		if (*p == 'B') {
2271590Srgrimes			skip *= 1024;
2281590Srgrimes			++p;
2291590Srgrimes		} else if (*p == 'b') {
2301590Srgrimes			skip *= 512;
2311590Srgrimes			++p;
2321590Srgrimes		}
23348566Sbillf	}
2341590Srgrimes
2351590Srgrimes	if (*p) {
2361590Srgrimes		skip = 0;
2371590Srgrimes		return;
2381590Srgrimes	}
2391590Srgrimes
2401590Srgrimes	/*
2411590Srgrimes	 * If the offset uses a non-octal base, the base of the offset
2421590Srgrimes	 * is changed as well.  This isn't pretty, but it's easy.
2431590Srgrimes	 */
2441590Srgrimes#define	TYPE_OFFSET	7
2451590Srgrimes	if (base == 16) {
2461590Srgrimes		fshead->nextfu->fmt[TYPE_OFFSET] = 'x';
2471590Srgrimes		fshead->nextfs->nextfu->fmt[TYPE_OFFSET] = 'x';
2481590Srgrimes	} else if (base == 10) {
2491590Srgrimes		fshead->nextfu->fmt[TYPE_OFFSET] = 'd';
2501590Srgrimes		fshead->nextfs->nextfu->fmt[TYPE_OFFSET] = 'd';
2511590Srgrimes	}
2521590Srgrimes
2531590Srgrimes	/* Terminate file list. */
2541590Srgrimes	(*argvp)[1] = NULL;
2551590Srgrimes}
2561590Srgrimes
2571590Srgrimesstatic void
2581590Srgrimesodprecede()
2591590Srgrimes{
2601590Srgrimes	static int first = 1;
2611590Srgrimes
2621590Srgrimes	if (first) {
2631590Srgrimes		first = 0;
2641590Srgrimes		add("\"%07.7_Ao\n\"");
2651590Srgrimes		add("\"%07.7_ao  \"");
2661590Srgrimes	} else
2671590Srgrimes		add("\"         \"");
2681590Srgrimes}
269