/*

Part of the TCP Testing Tool (ttt)

Some utility functions.

Eloy Paris 

$Id: util.c,v 1.1.1.1 2003/04/28 23:00:20 peloy Exp $

*/

#include "includes.h"

/*
 * Copy arg vector into a new buffer, concatenating arguments with spaces.
 * (stolen from tcpdump)
 */
char *copy_argv(register char **argv)
{
	register char **p;
	register u_int len = 0;
	char *buf;
	char *src, *dst;

	p = argv;
	if (*p == 0)
		return 0;

	while (*p)
		len += strlen(*p++) + 1;

	buf = (char *)malloc(len);
	if (buf == NULL)
		error(1, "Couldn't allocate memory");

	p = argv;
	dst = buf;
	while ((src = *p++) != NULL) {
		while ((*dst++ = *src++) != '\0')
			;
		dst[-1] = ' ';
	}
	dst[-1] = '\0';

	return buf;
}

void dump(const unsigned char *data, unsigned len)
{
	unsigned i, j;

	for (i = 0; i <= len/16; i++) {
		printf("%08x  ", i*16);

		for (j = 0; j < 16; j++) {
			if (i*16 + j < len)
				printf("%02x", data[i*16 + j]);
			else
				printf("  ");

			if (j & 1)
				printf(" ");
		}

		for (j = 0; j < 16; j++)
			if (i*16 + j < len)
				printf("%c", isprint(data[i*16 + j]) ?
				       data[i*16 + j] : '.');

		printf("\n");
	}

	printf("\n");
}

/* VARARGS */
void error(int eval, const char *fmt, ...)
{
	va_list ap;

	(void)fprintf(stderr, "%s: ", program_name);
	va_start(ap, fmt);
	(void)vfprintf(stderr, fmt, ap);
	va_end(ap);
	if (*fmt) {
		fmt += strlen(fmt);
		if (fmt[-1] != '\n')
			(void)fputc('\n', stderr);
	}
	exit(eval);
}

void debug(const char *fmt, ...)
{
#ifdef DEBUG
	va_list ap;

	va_start(ap, fmt);
	(void)vfprintf(stderr, fmt, ap);
	va_end(ap);
	if (*fmt) {
		fmt += strlen(fmt);
		if (fmt[-1] != '\n')
			(void)fputc('\n', stderr);
	}
#endif
}

/*
 * Just reads a file into memory. Stores pointer to data and length of
 * data in the payload structure.
 */
void read_payload(char *fname, struct payload *payload)
{
	int fd;
	struct stat file_stat;
	char *data;

	if ( (fd = stat(fname, &file_stat) ) == -1)
		error(1, "stat()");

	if ( (fd = open(fname, O_RDONLY) ) == -1)
		error(1, "open()");

	if ( (data = malloc(file_stat.st_size) ) == NULL) {
		close(fd);
		error(1, "malloc()");
	}

	if (read(fd, data, file_stat.st_size) == -1) {
		free(data);
		close(fd);
		error(1, "read()");
	}

	close(fd);

	payload->data = data;
	payload->len = file_stat.st_size;
}

/*
 * Just reads from stdin into memory. Stores pointer to data and length of
 * data in the payload structure.
 */
void read_payload_from_stdin(struct payload *payload)
{
	ssize_t bytes_read;
	char *buffer[4096];
	char *data = NULL;

	payload->len = 0;

	while ( (bytes_read = read(STDIN_FILENO, buffer, sizeof(buffer) ) ) ) {
		if ( (data = realloc(data, payload->len + bytes_read) ) == NULL)
			error(1, "realloc()");

		memcpy(data + payload->len, buffer, bytes_read);

		payload->len += bytes_read;
	}

	payload->data = data;
}

