/*
 * 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. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the University of
 *	California, Berkeley and its contributors.
 * 4. 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.
 */

#include <sys/param.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "hexdump.h"
#include "xalloc.h"
#include "c.h"
#include "nls.h"
#include "colors.h"

static void doskip(const char *, int, struct hexdump *);
static u_char *get(struct hexdump *);

enum _vflag vflag = FIRST;

static off_t address;			/* address/offset in stream */
static off_t eaddress;			/* end address */

static const char *color_cond(struct hexdump_pr *pr, unsigned char *bp, int bcnt)
{
	register struct list_head *p;
	register struct hexdump_clr *clr;
	off_t offt;
	int match;

	list_for_each(p, pr->colorlist) {
		clr = list_entry(p, struct hexdump_clr, colorlist);
		offt = clr->offt;
		match = 0;

		/* no offset or offset outside this print unit */
		if (offt < 0)
			offt = address;
		if (offt < address || offt + clr->range > address + bcnt)
			continue;

		/* match a string */
		if (clr->str) {
			if (pr->flags == F_ADDRESS) {
				/* TODO */
			}
			else if (!strncmp(clr->str, (char *)bp + offt
				- address, clr->range))
				match = 1;
		/* match a value */
		} else if (clr->val != -1) {
			int val = 0;
			/* addresses are not part of the input, so we can't
			 * compare with the contents of bp */
			if (pr->flags == F_ADDRESS) {
				if (clr->val == address)
					match = 1;
			} else {
				memcpy(&val, bp + offt - address, clr->range);
				if (val == clr->val)
					match = 1;
			}
		/* no conditions, only a color was specified */
		} else
			return clr->fmt;

		/* return the format string or check for another */
		if (match ^ clr->invert)
			return clr->fmt;
		continue;
	}

	/* no match */
	return NULL;
}

static inline void
print(struct hexdump_pr *pr, unsigned char *bp) {

	const char *color = NULL;

	if (pr->colorlist && (color = color_cond(pr, bp, pr->bcnt)))
		color_enable(color);

	switch(pr->flags) {
	case F_ADDRESS:
		printf(pr->fmt, 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(&fval, bp, sizeof(fval));
			printf(pr->fmt, fval);
			break;
		case 8:
			memmove(&dval, bp, sizeof(dval));
			printf(pr->fmt, dval);
			break;
		}
		break;
	    }
	case F_INT:
	    {
		short sval;	/* int16_t */
		int ival;	/* int32_t */
		long long Lval;	/* int64_t, int64_t */

		switch(pr->bcnt) {
		case 1:
			printf(pr->fmt, (unsigned long long) *bp);
			break;
		case 2:
			memmove(&sval, bp, sizeof(sval));
			printf(pr->fmt, (unsigned long long) sval);
			break;
		case 4:
			memmove(&ival, bp, sizeof(ival));
			printf(pr->fmt, (unsigned long long) ival);
			break;
		case 8:
			memmove(&Lval, bp, sizeof(Lval));
			printf(pr->fmt, Lval);
			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("%s", pr->fmt);
		break;
	case F_U:
		conv_u(pr, bp);
		break;
	case F_UINT:
	    {
		unsigned short sval;	/* u_int16_t */
		unsigned int ival;	/* u_int32_t */
		unsigned long long Lval;/* u_int64_t, u_int64_t */

		switch(pr->bcnt) {
		case 1:
			printf(pr->fmt, (unsigned long long) *bp);
			break;
		case 2:
			memmove(&sval, bp, sizeof(sval));
			printf(pr->fmt, (unsigned long long) sval);
			break;
		case 4:
			memmove(&ival, bp, sizeof(ival));
			printf(pr->fmt, (unsigned long long) ival);
			break;
		case 8:
			memmove(&Lval, bp, sizeof(Lval));
			printf(pr->fmt, Lval);
			break;
		}
		break;
	    }
	}
	if (color) /* did we colorize something? */
		color_disable();
}

static void bpad(struct hexdump_pr *pr)
{
	static const char *spec = " -0+#";
	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[0] = 's';
	pr->cchar[1] = 0;

	p1 = pr->fmt;
	while (*p1 != '%')
		++p1;

	p2 = ++p1;
	while (*p1 && strchr(spec, *p1))
		++p1;

	while ((*p2++ = *p1++))
		;
}

void display(struct hexdump *hex)
{
	register struct list_head *fs;
	register struct hexdump_fs *fss;
	register struct hexdump_fu *fu;
	register struct hexdump_pr *pr;
	register int cnt;
	register unsigned char *bp;
	off_t saveaddress;
	unsigned char savech = 0, *savebp;
	struct list_head *p, *q, *r;

	while ((bp = get(hex)) != NULL) {
		fs = &hex->fshead; savebp = bp; saveaddress = address;

		list_for_each(p, fs) {
			fss = list_entry(p, struct hexdump_fs, fslist);

			list_for_each(q, &fss->fulist) {
				fu = list_entry(q, struct hexdump_fu, fulist);

				if (fu->flags&F_IGNORE)
					break;

				cnt = fu->reps;

				while (cnt) {
					list_for_each(r, &fu->prlist) {
						pr = list_entry(r, struct hexdump_pr, prlist);

						if (eaddress && address >= eaddress
						    && !(pr->flags&(F_TEXT|F_BPAD)))
							bpad(pr);

						if (cnt == 1 && pr->nospace) {
							savech = *pr->nospace;
							*pr->nospace = '\0';
							print(pr, bp);
							*pr->nospace = savech;
						} else
							print(pr, bp);

						address += pr->bcnt;
						bp += pr->bcnt;
					}
					--cnt;
				}
			}
			bp = savebp;
			address = saveaddress;
		}
	}
	if (endfu) {
		/*
		 * if eaddress not set, error or file size was multiple of
		 * blocksize, and no partial block ever found.
		 */
		if (!eaddress) {
			if (!address)
				return;
			eaddress = address;
		}
		list_for_each (p, &endfu->prlist) {
			const char *color = NULL;

			pr = list_entry(p, struct hexdump_pr, prlist);
			if (colors_wanted() && pr->colorlist
			    && (color = color_cond(pr, bp, pr->bcnt))) {
				color_enable(color);
			}

			switch(pr->flags) {
			case F_ADDRESS:
				printf(pr->fmt, eaddress);
				break;
			case F_TEXT:
				printf("%s", pr->fmt);
				break;
			}
			if (color) /* did we highlight something? */
				color_disable();
		}
	}
}

static char **_argv;

static u_char *
get(struct hexdump *hex)
{
	static int ateof = 1;
	static u_char *curp, *savp;
	ssize_t n, need, nread;
	u_char *tmpp;

	if (!curp) {
		curp = xcalloc(1, hex->blocksize);
		savp = xcalloc(1, hex->blocksize);
	} else {
		tmpp = curp;
		curp = savp;
		savp = tmpp;
		address += hex->blocksize;
	}
	need = hex->blocksize, nread = 0;
	while (TRUE) {
		/*
		 * 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 (!hex->length || (ateof && !next(NULL, hex))) {
			if (need == hex->blocksize)
				goto retnul;
			if (!need && vflag != ALL &&
			    !memcmp(curp, savp, nread)) {
				if (vflag != DUP)
					printf("*\n");
				goto retnul;
			}
			if (need > 0)
				memset((char *)curp + nread, 0, need);
			eaddress = address + nread;
			return(curp);
		}
		if (fileno(stdin) == -1) {
			warnx(_("all input file arguments failed"));
			goto retnul;
		}
		n = fread((char *)curp + nread, sizeof(unsigned char),
		    hex->length == -1 ? need : min(hex->length, need), stdin);
		if (!n) {
			if (ferror(stdin))
				warn("%s", _argv[-1]);
			ateof = 1;
			continue;
		}
		ateof = 0;
		if (hex->length != -1)
			hex->length -= n;
		if (!(need -= n)) {
			if (vflag == ALL || vflag == FIRST ||
			    memcmp(curp, savp, hex->blocksize)) {
				if (vflag == DUP || vflag == FIRST)
					vflag = WAIT;
				return(curp);
			}
			if (vflag == WAIT)
				printf("*\n");
			vflag = DUP;
			address += hex->blocksize;
			need = hex->blocksize;
			nread = 0;
		}
		else
			nread += n;
	}
retnul:
	free (curp);
	free (savp);
	return NULL;
}

int next(char **argv, struct hexdump *hex)
{
	static int done;
	int statok;

	if (argv) {
		_argv = argv;
		return(1);
	}
	while (TRUE) {
		if (*_argv) {
			if (!(freopen(*_argv, "r", stdin))) {
				warn("%s", *_argv);
				hex->exitval = EXIT_FAILURE;
				++_argv;
				continue;
			}
			statok = done = 1;
		} else {
			if (done++)
				return(0);
			statok = 0;
		}
		if (hex->skip)
			doskip(statok ? *_argv : "stdin", statok, hex);
		if (*_argv)
			++_argv;
		if (!hex->skip)
			return(1);
	}
	/* NOTREACHED */
}

static void
doskip(const char *fname, int statok, struct hexdump *hex)
{
	struct stat sbuf;

	if (statok) {
		if (fstat(fileno(stdin), &sbuf))
		        err(EXIT_FAILURE, "%s", fname);
		if (S_ISREG(sbuf.st_mode) && hex->skip > sbuf.st_size) {
		  /* If size valid and skip >= size */
			hex->skip -= sbuf.st_size;
			address += sbuf.st_size;
			return;
		}
	}
	/* sbuf may be undefined here - do not test it */
	if (fseek(stdin, hex->skip, SEEK_SET))
	        err(EXIT_FAILURE, "%s", fname);
	address += hex->skip;
	hex->skip = 0;
}
