/*
 * 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 <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>		/* for isdigit() */
#include "libbb.h"
#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)
{
	register FU *fu;
	register int bcnt, cur_size;
	register 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;
	register PR *pr, **nextpr = NULL;
	register FU *fu;
	register 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 = (PR *) xcalloc(1,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';
				if (!(pr->fmt = realloc(pr->fmt, strlen(pr->fmt)+(p3-p2)+1)))
					bb_perror_msg_and_die("hexdump");
				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 */
	register 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)
{
	register 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);
	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; */
	register FS *fs;
	register FU *fu;
	register PR *pr;
	register int cnt;
	register 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)
{
	register 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)
{
	register const char *p;
	register char *p1;
	register char *p2;
	static FS **nextfs;
	FS *tfs;
	FU *tfu, **nextfu;
	const char *savep;

	/* start new linked list of format units */
	/* NOSTRICT */
	tfs = (FS *) xcalloc(1,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 = bb_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 = (FU *) xcalloc(1,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 = bb_skip_whitespace(++p);
		}

		/* bb_dump_skip slash and trailing white space */
		if (*p == '/') {
			p = bb_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 = bb_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.
 */
