util.c revision 1.10
1/*	$OpenBSD: util.c,v 1.10 2000/10/31 16:06:49 deraadt Exp $	*/
2
3/*
4 * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997
5 *	The Regents of the University of California.  All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that: (1) source code distributions
9 * retain the above copyright notice and this paragraph in its entirety, (2)
10 * distributions including binary code include the above copyright notice and
11 * this paragraph in its entirety in the documentation or other materials
12 * provided with the distribution, and (3) all advertising materials mentioning
13 * features or use of this software display the following acknowledgement:
14 * ``This product includes software developed by the University of California,
15 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
16 * the University nor the names of its contributors may be used to endorse
17 * or promote products derived from this software without specific prior
18 * written permission.
19 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
20 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22 */
23
24#ifndef lint
25static const char rcsid[] =
26    "@(#) $Header: /usr/local/opengrok/home/cvs-mirror/mirrors/openbsd/src/usr.sbin/tcpdump/util.c,v 1.10 2000/10/31 16:06:49 deraadt Exp $ (LBL)";
27#endif
28
29#include <sys/types.h>
30#include <sys/time.h>
31#include <sys/file.h>
32#include <sys/stat.h>
33
34#include <ctype.h>
35#include <errno.h>
36#ifdef HAVE_FCNTL_H
37#include <fcntl.h>
38#endif
39#include <pcap.h>
40#include <stdio.h>
41#ifdef __STDC__
42#include <stdarg.h>
43#else
44#include <varargs.h>
45#endif
46#include <stdlib.h>
47#include <string.h>
48#ifdef TIME_WITH_SYS_TIME
49#include <time.h>
50#endif
51#include <unistd.h>
52
53#include "interface.h"
54
55/*
56 * Print out a filename (or other ascii string).
57 * If ep is NULL, assume no truncation check is needed.
58 * Return true if truncated.
59 */
60int
61fn_print(register const u_char *s, register const u_char *ep)
62{
63	register int ret;
64	register u_char c;
65
66	ret = 1;			/* assume truncated */
67	while (ep == NULL || s < ep) {
68		c = *s++;
69		if (c == '\0') {
70			ret = 0;
71			break;
72		}
73		if (!isascii(c)) {
74			c = toascii(c);
75			putchar('M');
76			putchar('-');
77		}
78		if (!isprint(c)) {
79			c ^= 0x40;	/* DEL to ?, others to alpha */
80			putchar('^');
81		}
82		putchar(c);
83	}
84	return(ret);
85}
86
87/*
88 * Print out a counted filename (or other ascii string).
89 * If ep is NULL, assume no truncation check is needed.
90 * Return true if truncated.
91 */
92int
93fn_printn(register const u_char *s, register u_int n,
94	  register const u_char *ep)
95{
96	register int ret;
97	register u_char c;
98
99	ret = 1;			/* assume truncated */
100	while (ep == NULL || s < ep) {
101		if (n-- <= 0) {
102			ret = 0;
103			break;
104		}
105		c = *s++;
106		if (!isascii(c)) {
107			c = toascii(c);
108			putchar('M');
109			putchar('-');
110		}
111		if (!isprint(c)) {
112			c ^= 0x40;	/* DEL to ?, others to alpha */
113			putchar('^');
114		}
115		putchar(c);
116	}
117	return(ret);
118}
119
120/*
121 * Print the timestamp
122 */
123void
124ts_print(register const struct timeval *tvp)
125{
126	register int s;
127
128	if (tflag > 0) {
129		/* Default */
130		s = (tvp->tv_sec + thiszone) % 86400;
131		(void)printf("%02d:%02d:%02d.%06u ",
132		    s / 3600, (s % 3600) / 60, s % 60, (u_int32_t)tvp->tv_usec);
133	} else if (tflag < 0) {
134		/* Unix timeval style */
135		(void)printf("%u.%06u ",
136		    (u_int32_t)tvp->tv_sec, (u_int32_t)tvp->tv_usec);
137	}
138}
139
140/*
141 * Convert a token value to a string; use "fmt" if not found.
142 */
143const char *
144tok2str(register const struct tok *lp, register const char *fmt,
145	register int v)
146{
147	static char buf[128];
148
149	while (lp->s != NULL) {
150		if (lp->v == v)
151			return (lp->s);
152		++lp;
153	}
154	if (fmt == NULL)
155		fmt = "#%d";
156	(void)snprintf(buf, sizeof(buf), fmt, v);
157	return (buf);
158}
159
160
161/* VARARGS */
162__dead void
163#ifdef __STDC__
164error(const char *fmt, ...)
165#else
166error(fmt, va_alist)
167	const char *fmt;
168	va_dcl
169#endif
170{
171	va_list ap;
172
173	(void)fprintf(stderr, "%s: ", program_name);
174#ifdef __STDC__
175	va_start(ap, fmt);
176#else
177	va_start(ap);
178#endif
179	(void)vfprintf(stderr, fmt, ap);
180	va_end(ap);
181	if (*fmt) {
182		fmt += strlen(fmt);
183		if (fmt[-1] != '\n')
184			(void)fputc('\n', stderr);
185	}
186	exit(1);
187	/* NOTREACHED */
188}
189
190/* VARARGS */
191void
192#ifdef __STDC__
193warning(const char *fmt, ...)
194#else
195warning(fmt, va_alist)
196	const char *fmt;
197	va_dcl
198#endif
199{
200	va_list ap;
201
202	(void)fprintf(stderr, "%s: WARNING: ", program_name);
203#ifdef __STDC__
204	va_start(ap, fmt);
205#else
206	va_start(ap);
207#endif
208	(void)vfprintf(stderr, fmt, ap);
209	va_end(ap);
210	if (*fmt) {
211		fmt += strlen(fmt);
212		if (fmt[-1] != '\n')
213			(void)fputc('\n', stderr);
214	}
215}
216
217/*
218 * Copy arg vector into a new buffer, concatenating arguments with spaces.
219 */
220char *
221copy_argv(register char **argv)
222{
223	register char **p;
224	register u_int len = 0;
225	char *buf;
226	char *src, *dst;
227
228	p = argv;
229	if (*p == 0)
230		return 0;
231
232	while (*p)
233		len += strlen(*p++) + 1;
234
235	buf = (char *)malloc(len);
236	if (buf == NULL)
237		error("copy_argv: malloc");
238
239	p = argv;
240	dst = buf;
241	while ((src = *p++) != NULL) {
242		while ((*dst++ = *src++) != '\0')
243			;
244		dst[-1] = ' ';
245	}
246	dst[-1] = '\0';
247
248	return buf;
249}
250
251char *
252read_infile(char *fname)
253{
254	register int fd, cc;
255	register char *cp;
256	struct stat buf;
257
258	fd = open(fname, O_RDONLY);
259	if (fd < 0)
260		error("can't open %s: %s", fname, pcap_strerror(errno));
261
262	if (fstat(fd, &buf) < 0)
263		error("can't stat %s: %s", fname, pcap_strerror(errno));
264
265	cp = malloc((u_int)buf.st_size + 1);
266	cc = read(fd, cp, (int)buf.st_size);
267	if (cc < 0)
268		error("read %s: %s", fname, pcap_strerror(errno));
269	if (cc != buf.st_size)
270		error("short read %s (%d != %d)", fname, cc, (int)buf.st_size);
271	cp[(int)buf.st_size] = '\0';
272
273	return (cp);
274}
275