/* vi: set sw=4 ts=4: */
/*
 * Support code for the hexdump and od applets,
 * based on code from util-linux v 2.11l
 *
 * Copyright (c) 1989
 *	The Regents of the University of California.  All rights reserved.
 *
 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
 *
 * Original copyright notice is retained at the end of this file.
 */

#include "libbb.h"
#include <string.h>
#include <unistd.h>
#include <ctype.h>		/* for isdigit() */
#include "dump.h"

enum _vflag bb_dump_vflag = FIRST;
FS *bb_dump_fshead;				/* head of format strings */
static FU *endfu;
static char **_argv;
static off_t savaddress;	/* saved address/offset in stream */
static off_t eaddress;	/* end address */
static off_t address;	/* address/offset in stream */
off_t bb_dump_skip;				/* bytes to skip */
static int exitval;			/* final exit value */
int bb_dump_blocksize;			/* data block size */
int bb_dump_length = -1;		/* max bytes to read */

static const char index_str[] = ".#-+ 0123456789";

static const char size_conv_str[] =
"\x1\x4\x4\x4\x4\x4\x4\x8\x8\x8\x8\010cdiouxXeEfgG";

static const char lcc[] = "diouxX";

int bb_dump_size(FS * fs)
{
	FU *fu;
	int bcnt, cur_size;
	char *fmt;
	const char *p;
	int prec;

	/* figure out the data block bb_dump_size needed for each format unit */
	for (cur_size = 0, fu = fs->nextfu; fu; fu = fu->nextfu) {
		if (fu->bcnt) {
			cur_size += fu->bcnt * fu->reps;
			continue;
		}
		for (bcnt = prec = 0, fmt = fu->fmt; *fmt; ++fmt) {
			if (*fmt != '%')
				continue;
			/*
			 * bb_dump_skip any special chars -- save precision in
			 * case it's a %s format.
			 */
			while (strchr(index_str + 1, *++fmt));
			if (*fmt == '.' && isdigit(*++fmt)) {
				prec = atoi(fmt);
				while (isdigit(*++fmt));
			}
			if (!(p = strchr(size_conv_str + 12, *fmt))) {
				if (*fmt == 's') {
					bcnt += prec;
				} else if (*fmt == '_') {
					++fmt;
					if ((*fmt == 'c') || (*fmt == 'p') || (*fmt == 'u')) {
						bcnt += 1;
					}
				}
			} else {
				bcnt += size_conv_str[p - (size_conv_str + 12)];
			}
		}
		cur_size += bcnt * fu->reps;
	}
	return (cur_size);
}

static void rewrite(FS * fs)
{
	enum { NOTOKAY, USEBCNT, USEPREC } sokay;
	PR *pr, **nextpr = NULL;
	FU *fu;
	char *p1, *p2, *p3;
	char savech, *fmtp;
	const char *byte_count_str;
	int nconv, prec = 0;

	for (fu = fs->nextfu; fu; fu = fu->nextfu) {
		/*
		 * break each format unit into print units; each
		 * conversion character gets its own.
		 */
		for (nconv = 0, fmtp = fu->fmt; *fmtp; nextpr = &pr->nextpr) {
			/* NOSTRICT */
			/* DBU:[dvae@cray.com] calloc so that forward ptrs start out NULL*/
			pr = xzalloc(sizeof(PR));
			if (!fu->nextpr)
				fu->nextpr = pr;
			/* ignore nextpr -- its unused inside the loop and is
			 * uninitialized 1st time thru.
			 */

			/* bb_dump_skip preceding text and up to the next % sign */
			for (p1 = fmtp; *p1 && *p1 != '%'; ++p1);

			/* only text in the string */
			if (!*p1) {
				pr->fmt = fmtp;
				pr->flags = F_TEXT;
				break;
			}

			/*
			 * get precision for %s -- if have a byte count, don't
			 * need it.
			 */
			if (fu->bcnt) {
				sokay = USEBCNT;
				/* bb_dump_skip to conversion character */
				for (++p1; strchr(index_str, *p1); ++p1);
			} else {
				/* bb_dump_skip any special chars, field width */
				while (strchr(index_str + 1, *++p1));
				if (*p1 == '.' && isdigit(*++p1)) {
					sokay = USEPREC;
					prec = atoi(p1);
					while (isdigit(*++p1));
				} else
					sokay = NOTOKAY;
			}

			p2 = p1 + 1;	/* set end pointer */

			/*
			 * figure out the byte count for each conversion;
			 * rewrite the format as necessary, set up blank-
			 * pbb_dump_adding for end of data.
			 */

			if (*p1 == 'c') {
				pr->flags = F_CHAR;
			DO_BYTE_COUNT_1:
				byte_count_str = "\001";
			DO_BYTE_COUNT:
				if (fu->bcnt) {
					do {
						if (fu->bcnt == *byte_count_str) {
							break;
						}
					} while (*++byte_count_str);
				}
				/* Unlike the original, output the remainder of the format string. */
				if (!*byte_count_str) {
					bb_error_msg_and_die("bad byte count for conversion character %s.", p1);
				}
				pr->bcnt = *byte_count_str;
			} else if (*p1 == 'l') {
				++p2;
				++p1;
			DO_INT_CONV:
				{
					const char *e;
					if (!(e = strchr(lcc, *p1))) {
						goto DO_BAD_CONV_CHAR;
					}
					pr->flags = F_INT;
					if (e > lcc + 1) {
						pr->flags = F_UINT;
					}
					byte_count_str = "\004\002\001";
					goto DO_BYTE_COUNT;
				}
				/* NOTREACHED */
			} else if (strchr(lcc, *p1)) {
				goto DO_INT_CONV;
			} else if (strchr("eEfgG", *p1)) {
				pr->flags = F_DBL;
				byte_count_str = "\010\004";
				goto DO_BYTE_COUNT;
			} else if (*p1 == 's') {
				pr->flags = F_STR;
				if (sokay == USEBCNT) {
					pr->bcnt = fu->bcnt;
				} else if (sokay == USEPREC) {
					pr->bcnt = prec;
				} else {	/* NOTOKAY */
					bb_error_msg_and_die("%%s requires a precision or a byte count.");
				}
			} else if (*p1 == '_') {
				++p2;
				switch (p1[1]) {
				case 'A':
					endfu = fu;
					fu->flags |= F_IGNORE;
					/* FALLTHROUGH */
				case 'a':
					pr->flags = F_ADDRESS;
					++p2;
					if ((p1[2] != 'd') && (p1[2] != 'o') && (p1[2] != 'x')) {
						goto DO_BAD_CONV_CHAR;
					}
					*p1 = p1[2];
					break;
				case 'c':
					pr->flags = F_C;
					/* *p1 = 'c';   set in conv_c */
					goto DO_BYTE_COUNT_1;
				case 'p':
					pr->flags = F_P;
					*p1 = 'c';
					goto DO_BYTE_COUNT_1;
				case 'u':
					pr->flags = F_U;
					/* *p1 = 'c';   set in conv_u */
					goto DO_BYTE_COUNT_1;
				default:
					goto DO_BAD_CONV_CHAR;
				}
			} else {
			DO_BAD_CONV_CHAR:
				bb_error_msg_and_die("bad conversion character %%%s.\n", p1);
			}

			/*
			 * copy to PR format string, set conversion character
			 * pointer, update original.
			 */
			savech = *p2;
			p1[1] = '\0';
			pr->fmt = bb_xstrdup(fmtp);
			*p2 = savech;
			pr->cchar = pr->fmt + (p1 - fmtp);

			/* DBU:[dave@cray.com] w/o this, trailing fmt text, space is lost.
			 * Skip subsequent text and up to the next % sign and tack the
			 * additional text onto fmt: eg. if fmt is "%x is a HEX number",
			 * we lose the " is a HEX number" part of fmt.
			 */
			for (p3 = p2; *p3 && *p3 != '%'; p3++);
			if (p3 > p2)
			{
				savech = *p3;
				*p3 = '\0';
				pr->fmt = xrealloc(pr->fmt, strlen(pr->fmt)+(p3-p2)+1);
				strcat(pr->fmt, p2);
				*p3 = savech;
				p2 = p3;
			}

			fmtp = p2;

			/* only one conversion character if byte count */
			if (!(pr->flags & F_ADDRESS) && fu->bcnt && nconv++) {
				bb_error_msg_and_die("byte count with multiple conversion characters.\n");
			}
		}
		/*
		 * if format unit byte count not specified, figure it out
		 * so can adjust rep count later.
		 */
		if (!fu->bcnt)
			for (pr = fu->nextpr; pr; pr = pr->nextpr)
				fu->bcnt += pr->bcnt;
	}
	/*
	 * if the format string interprets any data at all, and it's
	 * not the same as the bb_dump_blocksize, and its last format unit
	 * interprets any data at all, and has no iteration count,
	 * repeat it as necessary.
	 *
	 * if, rep count is greater than 1, no trailing whitespace
	 * gets output from the last iteration of the format unit.
	 */
	for (fu = fs->nextfu;; fu = fu->nextfu) {
		if (!fu->nextfu && fs->bcnt < bb_dump_blocksize &&
			!(fu->flags & F_SETREP) && fu->bcnt)
			fu->reps += (bb_dump_blocksize - fs->bcnt) / fu->bcnt;
		if (fu->reps > 1) {
			for (pr = fu->nextpr;; pr = pr->nextpr)
				if (!pr->nextpr)
					break;
			for (p1 = pr->fmt, p2 = NULL; *p1; ++p1)
				p2 = isspace(*p1) ? p1 : NULL;
			if (p2)
				pr->nospace = p2;
		}
		if (!fu->nextfu)
			break;
	}
}

static void do_skip(char *fname, int statok)
{
	struct stat sbuf;

	if (statok) {
		if (fstat(STDIN_FILENO, &sbuf)) {
			bb_perror_msg_and_die("%s", fname);
		}
		if ((!(S_ISCHR(sbuf.st_mode) ||
			   S_ISBLK(sbuf.st_mode) ||
			   S_ISFIFO(sbuf.st_mode))) && bb_dump_skip >= sbuf.st_size) {
			/* If bb_dump_size valid and bb_dump_skip >= size */
			bb_dump_skip -= sbuf.st_size;
			address += sbuf.st_size;
			return;
		}
	}
	if (fseek(stdin, bb_dump_skip, SEEK_SET)) {
		bb_perror_msg_and_die("%s", fname);
	}
	savaddress = address += bb_dump_skip;
	bb_dump_skip = 0;
}

static int next(char **argv)
{
	static int done;
	int statok;

	if (argv) {
		_argv = argv;
		return (1);
	}
	for (;;) {
		if (*_argv) {
			if (!(freopen(*_argv, "r", stdin))) {
				bb_perror_msg("%s", *_argv);
				exitval = 1;
				++_argv;
				continue;
			}
			statok = done = 1;
		} else {
			if (done++)
				return (0);
			statok = 0;
		}
		if (bb_dump_skip)
			do_skip(statok ? *_argv : "stdin", statok);
		if (*_argv)
			++_argv;
		if (!bb_dump_skip)
			return (1);
	}
	/* NOTREACHED */
}

static unsigned char *get(void)
{
	static int ateof = 1;
	static unsigned char *curp=NULL, *savp; /*DBU:[dave@cray.com]initialize curp */
	int n;
	int need, nread;
	unsigned char *tmpp;

	if (!curp) {
		address = (off_t)0; /*DBU:[dave@cray.com] initialize,initialize..*/
		curp = (unsigned char *) xmalloc(bb_dump_blocksize);
		savp = (unsigned char *) xmalloc(bb_dump_blocksize);
	} else {
		tmpp = curp;
		curp = savp;
		savp = tmpp;
		address = savaddress += bb_dump_blocksize;
	}
	for (need = bb_dump_blocksize, nread = 0;;) {
		/*
		 * if read the right number of bytes, or at EOF for one file,
		 * and no other files are available, zero-pad the rest of the
		 * block and set the end flag.
		 */
		if (!bb_dump_length || (ateof && !next((char **) NULL))) {
			if (need == bb_dump_blocksize) {
				return ((unsigned char *) NULL);
			}
			if (bb_dump_vflag != ALL && !memcmp(curp, savp, nread)) {
				if (bb_dump_vflag != DUP) {
					printf("*\n");
				}
				return ((unsigned char *) NULL);
			}
			memset((char *) curp + nread, 0, need);
			eaddress = address + nread;
			return (curp);
		}
		n = fread((char *) curp + nread, sizeof(unsigned char),
				  bb_dump_length == -1 ? need : MIN(bb_dump_length, need), stdin);
		if (!n) {
			if (ferror(stdin)) {
				bb_perror_msg("%s", _argv[-1]);
			}
			ateof = 1;
			continue;
		}
		ateof = 0;
		if (bb_dump_length != -1) {
			bb_dump_length -= n;
		}
		if (!(need -= n)) {
			if (bb_dump_vflag == ALL || bb_dump_vflag == FIRST
				|| memcmp(curp, savp, bb_dump_blocksize)) {
				if (bb_dump_vflag == DUP || bb_dump_vflag == FIRST) {
					bb_dump_vflag = WAIT;
				}
				return (curp);
			}
			if (bb_dump_vflag == WAIT) {
				printf("*\n");
			}
			bb_dump_vflag = DUP;
			address = savaddress += bb_dump_blocksize;
			need = bb_dump_blocksize;
			nread = 0;
		} else {
			nread += n;
		}
	}
}

static void bpad(PR * pr)
{
	char *p1, *p2;

	/*
	 * remove all conversion flags; '-' is the only one valid
	 * with %s, and it's not useful here.
	 */
	pr->flags = F_BPAD;
	*pr->cchar = 's';
	for (p1 = pr->fmt; *p1 != '%'; ++p1);
	for (p2 = ++p1; *p1 && strchr(" -0+#", *p1); ++p1)
		if (pr->nospace) pr->nospace--;
	while ((*p2++ = *p1++) != 0);
}

static const char conv_str[] =
	"\0\\0\0"
	"\007\\a\0"				/* \a */
	"\b\\b\0"
	"\f\\b\0"
	"\n\\n\0"
	"\r\\r\0"
	"\t\\t\0"
	"\v\\v\0"
	"\0";


static void conv_c(PR * pr, unsigned char * p)
{
	const char *str = conv_str;
	char buf[10];

	do {
		if (*p == *str) {
			++str;
			goto strpr;
		}
		str += 4;
	} while (*str);

	if (isprint(*p)) {
		*pr->cchar = 'c';
		(void) printf(pr->fmt, *p);
	} else {
		sprintf(buf, "%03o", (int) *p);
		str = buf;
	  strpr:
		*pr->cchar = 's';
		printf(pr->fmt, str);
	}
}

static void conv_u(PR * pr, unsigned char * p)
{
	static const char list[] =
		"nul\0soh\0stx\0etx\0eot\0enq\0ack\0bel\0"
		"bs\0_ht\0_lf\0_vt\0_ff\0_cr\0_so\0_si\0_"
		"dle\0dcl\0dc2\0dc3\0dc4\0nak\0syn\0etb\0"
		"can\0em\0_sub\0esc\0fs\0_gs\0_rs\0_us";

	/* od used nl, not lf */
	if (*p <= 0x1f) {
		*pr->cchar = 's';
		printf(pr->fmt, list + (4 * (int)*p));
	} else if (*p == 0x7f) {
		*pr->cchar = 's';
		printf(pr->fmt, "del");
	} else if (isprint(*p)) {
		*pr->cchar = 'c';
		printf(pr->fmt, *p);
	} else {
		*pr->cchar = 'x';
		printf(pr->fmt, (int) *p);
	}
}

static void display(void)
{
/*  extern FU *endfu; */
	FS *fs;
	FU *fu;
	PR *pr;
	int cnt;
	unsigned char *bp;

	off_t saveaddress;
	unsigned char savech = 0, *savebp;

	while ((bp = get()) != NULL) {
		for (fs = bb_dump_fshead, savebp = bp, saveaddress = address; fs;
			 fs = fs->nextfs, bp = savebp, address = saveaddress) {
			for (fu = fs->nextfu; fu; fu = fu->nextfu) {
				if (fu->flags & F_IGNORE) {
					break;
				}
				for (cnt = fu->reps; cnt; --cnt) {
					for (pr = fu->nextpr; pr; address += pr->bcnt,
						 bp += pr->bcnt, pr = pr->nextpr) {
						if (eaddress && address >= eaddress &&
							!(pr->flags & (F_TEXT | F_BPAD))) {
							bpad(pr);
						}
						if (cnt == 1 && pr->nospace) {
							savech = *pr->nospace;
							*pr->nospace = '\0';
						}
/*                      PRINT; */
						switch (pr->flags) {
						case F_ADDRESS:
							printf(pr->fmt, (unsigned int) address);
							break;
						case F_BPAD:
							printf(pr->fmt, "");
							break;
						case F_C:
							conv_c(pr, bp);
							break;
						case F_CHAR:
							printf(pr->fmt, *bp);
							break;
						case F_DBL:{
							double dval;
							float fval;

							switch (pr->bcnt) {
							case 4:
								memmove((char *) &fval, (char *) bp,
									  sizeof(fval));
								printf(pr->fmt, fval);
								break;
							case 8:
								memmove((char *) &dval, (char *) bp,
									  sizeof(dval));
								printf(pr->fmt, dval);
								break;
							}
							break;
						}
						case F_INT:{
							int ival;
							short sval;

							switch (pr->bcnt) {
							case 1:
								printf(pr->fmt, (int) *bp);
								break;
							case 2:
								memmove((char *) &sval, (char *) bp,
									  sizeof(sval));
								printf(pr->fmt, (int) sval);
								break;
							case 4:
								memmove((char *) &ival, (char *) bp,
									  sizeof(ival));
								printf(pr->fmt, ival);
								break;
							}
							break;
						}
						case F_P:
							printf(pr->fmt, isprint(*bp) ? *bp : '.');
							break;
						case F_STR:
							printf(pr->fmt, (char *) bp);
							break;
						case F_TEXT:
							printf(pr->fmt);
							break;
						case F_U:
							conv_u(pr, bp);
							break;
						case F_UINT:{
							unsigned int ival;
							unsigned short sval;

							switch (pr->bcnt) {
							case 1:
								printf(pr->fmt, (unsigned int) * bp);
								break;
							case 2:
								memmove((char *) &sval, (char *) bp,
									  sizeof(sval));
								printf(pr->fmt, (unsigned int) sval);
								break;
							case 4:
								memmove((char *) &ival, (char *) bp,
									  sizeof(ival));
								printf(pr->fmt, ival);
								break;
							}
							break;
						}
						}
						if (cnt == 1 && pr->nospace) {
							*pr->nospace = savech;
						}
					}
				}
			}
		}
	}
	if (endfu) {
		/*
		 * if eaddress not set, error or file bb_dump_size was multiple of
		 * bb_dump_blocksize, and no partial block ever found.
		 */
		if (!eaddress) {
			if (!address) {
				return;
			}
			eaddress = address;
		}
		for (pr = endfu->nextpr; pr; pr = pr->nextpr) {
			switch (pr->flags) {
			case F_ADDRESS:
				(void) printf(pr->fmt, (unsigned int) eaddress);
				break;
			case F_TEXT:
				(void) printf(pr->fmt);
				break;
			}
		}
	}
}

int bb_dump_dump(char **argv)
{
	FS *tfs;

	/* figure out the data block bb_dump_size */
	for (bb_dump_blocksize = 0, tfs = bb_dump_fshead; tfs; tfs = tfs->nextfs) {
		tfs->bcnt = bb_dump_size(tfs);
		if (bb_dump_blocksize < tfs->bcnt) {
			bb_dump_blocksize = tfs->bcnt;
		}
	}
	/* rewrite the rules, do syntax checking */
	for (tfs = bb_dump_fshead; tfs; tfs = tfs->nextfs) {
		rewrite(tfs);
	}

	next(argv);
	display();

	return (exitval);
}

void bb_dump_add(const char *fmt)
{
	const char *p;
	char *p1;
	char *p2;
	static FS **nextfs;
	FS *tfs;
	FU *tfu, **nextfu;
	const char *savep;

	/* start new linked list of format units */
	tfs = xzalloc(sizeof(FS)); /*DBU:[dave@cray.com] start out NULL */
	if (!bb_dump_fshead) {
		bb_dump_fshead = tfs;
	} else {
		*nextfs = tfs;
	}
	nextfs = &tfs->nextfs;
	nextfu = &tfs->nextfu;

	/* take the format string and break it up into format units */
	for (p = fmt;;) {
		/* bb_dump_skip leading white space */
		p = skip_whitespace(p);
		if (!*p) {
			break;
		}

		/* allocate a new format unit and link it in */
		/* NOSTRICT */
		/* DBU:[dave@cray.com] calloc so that forward pointers start out NULL */
		tfu = xzalloc(sizeof(FU));
		*nextfu = tfu;
		nextfu = &tfu->nextfu;
		tfu->reps = 1;

		/* if leading digit, repetition count */
		if (isdigit(*p)) {
			for (savep = p; isdigit(*p); ++p);
			if (!isspace(*p) && *p != '/') {
				bb_error_msg_and_die("bad format {%s}", fmt);
			}
			/* may overwrite either white space or slash */
			tfu->reps = atoi(savep);
			tfu->flags = F_SETREP;
			/* bb_dump_skip trailing white space */
			p = skip_whitespace(++p);
		}

		/* bb_dump_skip slash and trailing white space */
		if (*p == '/') {
			p = skip_whitespace(++p);
		}

		/* byte count */
		if (isdigit(*p)) {
			for (savep = p; isdigit(*p); ++p);
			if (!isspace(*p)) {
				bb_error_msg_and_die("bad format {%s}", fmt);
			}
			tfu->bcnt = atoi(savep);
			/* bb_dump_skip trailing white space */
			p = skip_whitespace(++p);
		}

		/* format */
		if (*p != '"') {
			bb_error_msg_and_die("bad format {%s}", fmt);
		}
		for (savep = ++p; *p != '"';) {
			if (*p++ == 0) {
				bb_error_msg_and_die("bad format {%s}", fmt);
			}
		}
		tfu->fmt = xmalloc(p - savep + 1);
		strncpy(tfu->fmt, savep, p - savep);
		tfu->fmt[p - savep] = '\0';
/*      escape(tfu->fmt); */

		p1 = tfu->fmt;

		/* alphabetic escape sequences have to be done in place */
		for (p2 = p1;; ++p1, ++p2) {
			if (!*p1) {
				*p2 = *p1;
				break;
			}
			if (*p1 == '\\') {
				const char *cs = conv_str + 4;
				++p1;
				*p2 = *p1;
				do {
					if (*p1 == cs[2]) {
						*p2 = cs[0];
						break;
					}
					cs += 4;
				} while (*cs);
			}
		}

		p++;
	}
}

/*
 * Copyright (c) 1989 The Regents of the University of California.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */
