/*
 *	Copyright (c) 1993-1997 JSC Rinet, Novosibirsk, Russia
 *
 * Redistribution and use in source forms, with and without modification,
 * are permitted provided that this entire comment appears intact.
 * Redistribution in binary form may occur without any restrictions.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' WITHOUT ANY WARRANTIES OF ANY KIND.
 */

/* util.c -- misc auxiliary routines */

#ifdef	HAVE_CONFIG_H
#include <config.h>
#endif

#include <sys/types.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef	__STDC__
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#include <unistd.h>

#include "trafshow.h"

void
#ifdef	__STDC__
error(int perrno, char *fmt, ...)
#else
error(perrno, fmt, va_alist)
	int perrno;
	char *fmt;
	va_dcl
#endif
{
	va_list ap;
	char buf[200];

#ifdef	__STDC__
	va_start(ap, fmt);
#else
	va_start(ap);
#endif
	(void)vsprintf(buf, fmt, ap);
	va_end(ap);

	(void)fprintf(stderr, "%s: ", program_name);
	if (perrno) perror(buf);
	else (void)fprintf(stderr, "%s\n", buf);
	(void)fflush(stderr);

	if (curses_initialized) cleanup(-1);
	exit(1);
}

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

	p = av;
	if (*p == 0) return 0;
	while (*p) len += strlen(*p++) + 1;
	if ((buf = (char *)malloc(len)) == NULL) error(1, "copy_argv: malloc");
	p = av;
	dst = buf;
	while ((src = *p++) != NULL) {
		while ((*dst++ = *src++) != '\0');
		dst[-1] = ' ';
	}
	dst[-1] = '\0';

	return buf;
}

char *
read_infile(fname)
	char *fname;
{
	int fd, cc;
	char *cp;
	struct stat st;

	if ((fd = open(fname, O_RDONLY)) < 0)
		error(1, "read_infile: can't open \"%s\"", fname);

	if (fstat(fd, &st) < 0)
		error(1, "read_infile: can't stat \"%s\"", fname);

	if ((cp = (char *)malloc((u_int)st.st_size + 1)) == NULL)
		error(1, "read_infile: malloc");

	if ((cc = read(fd, cp, (int)st.st_size)) < 0)
		error(1, "read_infile: read \"%s\"", fname);
	if (cc != st.st_size)
		error(0, "read_infile: short read \"%s\" (%d != %d)",
		      fname, cc, (int)st.st_size);
	cp[(int)st.st_size] = '\0';

	return (cp);
}

static struct proto_ent {
	char *name;
	u_short proto;
} proto_tab[] = {
	{ "tcp",  IPPROTO_TCP  },
	{ "udp",  IPPROTO_UDP  },
	{ "icmp", IPPROTO_ICMP },
	{ "egp",  IPPROTO_EGP  },
	{ "ospf", IPPROTO_OSPF },
	{ "igmp", IPPROTO_IGMP },
	{ "gre",  IPPROTO_GRE  },
	{ "gif",  IPPROTO_IPIP },
	{ "esp",  IPPROTO_ESP  },
#ifdef	IPPROTO_GGP
	{ "ggp",  IPPROTO_GGP  },
#endif
#ifdef	IPPROTO_ENCAP
	{ "encap",IPPROTO_ENCAP},
#endif
#ifdef	IPPROTO_IPV6
	{ "ipv6", IPPROTO_IPV6},
#endif
	{ "ip",   IPPROTO_IP   },
	{ "raw",  IPPROTO_RAW  },
	{ NULL, -1 },
};

char *
getprotoname(proto)
	u_short proto;
{
	register struct proto_ent *p;

	for (p = proto_tab; p->name != NULL; p++)
		if (proto == p->proto)
			return p->name;

	return NULL;
}

u_short
getprotonum(proto)
	char *proto;
{
	register struct proto_ent *p;

	for (p = proto_tab; p->name != NULL; p++)
		if (!strcasecmp(proto, p->name))
			return p->proto;

	return -1;
}


syntax highlighted by Code2HTML, v. 0.9.1