util.c revision 26180
1139749Simp/* 229138Sdg * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996 329138Sdg * The Regents of the University of California. All rights reserved. 4185269Syongari * 529138Sdg * Redistribution and use in source and binary forms, with or without 629138Sdg * modification, are permitted provided that: (1) source code distributions 7185269Syongari * retain the above copyright notice and this paragraph in its entirety, (2) 829138Sdg * distributions including binary code include the above copyright notice and 929138Sdg * this paragraph in its entirety in the documentation or other materials 10185269Syongari * provided with the distribution, and (3) all advertising materials mentioning 1129138Sdg * features or use of this software display the following acknowledgement: 1229138Sdg * ``This product includes software developed by the University of California, 1329138Sdg * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 1429138Sdg * the University nor the names of its contributors may be used to endorse 1529138Sdg * or promote products derived from this software without specific prior 1629138Sdg * written permission. 1729138Sdg * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 1829138Sdg * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 1929138Sdg * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 2029138Sdg */ 2129138Sdg 2229138Sdg#ifndef lint 2329138Sdgstatic const char rcsid[] = 2429138Sdg "@(#) $Header: util.c,v 1.55 96/09/26 23:36:51 leres Exp $ (LBL)"; 2529138Sdg#endif 2629138Sdg 2750477Speter#include <sys/types.h> 2829138Sdg#include <sys/time.h> 2929138Sdg#include <sys/file.h> 3029138Sdg#include <sys/stat.h> 3129138Sdg 3229138Sdg#include <ctype.h> 3329138Sdg#include <errno.h> 3474178Sjlemon#ifdef HAVE_FCNTL_H 3538006Sdg#include <fcntl.h> 3674178Sjlemon#endif 3774178Sjlemon#include <pcap.h> 3874178Sjlemon#include <stdio.h> 3974178Sjlemon#if __STDC__ 4074178Sjlemon#include <stdarg.h> 41185285Syongari#else 4274178Sjlemon#include <varargs.h> 4374178Sjlemon#endif 44185330Syongari#include <stdlib.h> 45185330Syongari#include <string.h> 46185330Syongari#ifdef TIME_WITH_SYS_TIME 47185330Syongari#include <time.h> 48185330Syongari#endif 49112982Smux#include <unistd.h> 50112982Smux 51112982Smux#include "interface.h" 52112982Smux 53112982Smux/* 54112982Smux * Print out a filename (or other ascii string). 55112982Smux * If ep is NULL, assume no truncation check is needed. 56112982Smux * Return true if truncated. 57112982Smux */ 58112982Smuxint 59112982Smuxfn_print(register const u_char *s, register const u_char *ep) 60112982Smux{ 61112982Smux register int ret; 6274178Sjlemon register u_char c; 6374178Sjlemon 6474178Sjlemon ret = 1; /* assume truncated */ 6574178Sjlemon while (ep == NULL || s < ep) { 6674178Sjlemon c = *s++; 6774178Sjlemon if (c == '\0') { 6874178Sjlemon ret = 0; 6974178Sjlemon break; 7074178Sjlemon } 7174178Sjlemon if (!isascii(c)) { 7274178Sjlemon c = toascii(c); 7374178Sjlemon putchar('M'); 7474178Sjlemon putchar('-'); 7574178Sjlemon } 7674178Sjlemon if (!isprint(c)) { 7774178Sjlemon c ^= 0x40; /* DEL to ?, others to alpha */ 7874178Sjlemon putchar('^'); 7987902Sluigi } 8087902Sluigi putchar(c); 8187902Sluigi } 8274178Sjlemon return(ret); 8387902Sluigi} 8474178Sjlemon 8574178Sjlemon/* 8674178Sjlemon * Print out a counted filename (or other ascii string). 8774178Sjlemon * If ep is NULL, assume no truncation check is needed. 8874178Sjlemon * Return true if truncated. 8974178Sjlemon */ 9074178Sjlemonint 9174178Sjlemonfn_printn(register const u_char *s, register u_int n, 9274178Sjlemon register const u_char *ep) 9385461Sjlemon{ 9485461Sjlemon register int ret; 95185269Syongari register u_char c; 9685461Sjlemon 9785461Sjlemon ret = 1; /* assume truncated */ 9885461Sjlemon while (ep == NULL || s < ep) { 9985461Sjlemon if (n-- <= 0) { 10085461Sjlemon ret = 0; 10185461Sjlemon break; 102185269Syongari } 10385461Sjlemon c = *s++; 104185269Syongari if (!isascii(c)) { 10585461Sjlemon c = toascii(c); 10685461Sjlemon putchar('M'); 10785461Sjlemon putchar('-'); 10885461Sjlemon } 10985461Sjlemon if (!isprint(c)) { 11074178Sjlemon c ^= 0x40; /* DEL to ?, others to alpha */ 11174178Sjlemon putchar('^'); 112130020Smux } 11374178Sjlemon putchar(c); 114112982Smux } 115112982Smux return(ret); 116112982Smux} 117112982Smux 118112982Smux/* 119112982Smux * Print the timestamp 120112982Smux */ 121143167Smuxvoid 122112982Smuxts_print(register const struct timeval *tvp) 12374178Sjlemon{ 124112982Smux register int s; 125112982Smux 126112982Smux if (tflag > 0) { 127112982Smux /* Default */ 128112982Smux s = (tvp->tv_sec + thiszone) % 86400; 129112982Smux (void)printf("%02d:%02d:%02d.%06u ", 130112982Smux s / 3600, (s % 3600) / 60, s % 60, (u_int32_t)tvp->tv_usec); 131112982Smux } else if (tflag < 0) { 132112982Smux /* Unix timeval style */ 133112982Smux (void)printf("%u.%06u ", 134112982Smux (u_int32_t)tvp->tv_sec, (u_int32_t)tvp->tv_usec); 135112982Smux } 136112982Smux} 137112982Smux 138112982Smux/* 139112982Smux * Convert a token value to a string; use "fmt" if not found. 140112982Smux */ 141143167Smuxconst char * 142112982Smuxtok2str(register const struct tok *lp, register const char *fmt, 143112982Smux register int v) 144112982Smux{ 14574178Sjlemon static char buf[128]; 14638006Sdg 14738006Sdg while (lp->s != NULL) { 14838006Sdg if (lp->v == v) 14929138Sdg return (lp->s); 150147256Sbrooks ++lp; 151150610Smux } 152150610Smux if (fmt == NULL) 15345720Speter fmt = "#%d"; 15465983Scp (void)sprintf(buf, fmt, v); 155112982Smux return (buf); 156112982Smux} 157112982Smux 158112982Smux 159112982Smux/* VARARGS */ 160112982Smux__dead void 161112982Smux#if __STDC__ 162112982Smuxerror(const char *fmt, ...) 163112982Smux#else 164143243Smuxerror(fmt, va_alist) 165185330Syongari const char *fmt; 16631447Sdg va_dcl 16731447Sdg#endif 16829138Sdg{ 169143167Smux va_list ap; 17031447Sdg 171119786Ssam (void)fprintf(stderr, "%s: ", program_name); 172164771Sglebius#if __STDC__ 17331447Sdg va_start(ap, fmt); 174143167Smux#else 17538006Sdg va_start(ap); 17674178Sjlemon#endif 17774178Sjlemon (void)vfprintf(stderr, fmt, ap); 17885461Sjlemon va_end(ap); 17985461Sjlemon if (*fmt) { 180130019Smux fmt += strlen(fmt); 181130019Smux if (fmt[-1] != '\n') 18258715Sdg (void)fputc('\n', stderr); 183114269Simp } 18476777Sjlemon exit(1); 18585461Sjlemon /* NOTREACHED */ 18674178Sjlemon} 187143167Smux 188143167Smux/* VARARGS */ 18929138Sdgvoid 19029138Sdg#if __STDC__ 19174178Sjlemonwarning(const char *fmt, ...) 19274178Sjlemon#else 19374178Sjlemonwarning(fmt, va_alist) 19474178Sjlemon const char *fmt; 19574178Sjlemon va_dcl 19674178Sjlemon#endif 19774178Sjlemon{ 19876777Sjlemon va_list ap; 19985461Sjlemon 200106554Siedowse (void)fprintf(stderr, "%s: WARNING: ", program_name); 201111578Swpaul#if __STDC__ 202129718Syar va_start(ap, fmt); 203185329Syongari#else 204185354Syongari va_start(ap); 205185354Syongari#endif 20674178Sjlemon (void)vfprintf(stderr, fmt, ap); 20729138Sdg va_end(ap); 208150610Smux if (*fmt) { 209150610Smux fmt += strlen(fmt); 210150610Smux if (fmt[-1] != '\n') 211150610Smux (void)fputc('\n', stderr); 212150610Smux } 213150610Smux} 214 215/* 216 * Copy arg vector into a new buffer, concatenating arguments with spaces. 217 */ 218char * 219copy_argv(register char **argv) 220{ 221 register char **p; 222 register u_int len = 0; 223 char *buf; 224 char *src, *dst; 225 226 p = argv; 227 if (*p == 0) 228 return 0; 229 230 while (*p) 231 len += strlen(*p++) + 1; 232 233 buf = (char *)malloc(len); 234 if (buf == NULL) 235 error("copy_argv: malloc"); 236 237 p = argv; 238 dst = buf; 239 while ((src = *p++) != NULL) { 240 while ((*dst++ = *src++) != '\0') 241 ; 242 dst[-1] = ' '; 243 } 244 dst[-1] = '\0'; 245 246 return buf; 247} 248 249/* A replacement for strdup() that cuts down on malloc() overhead */ 250char * 251savestr(register const char *str) 252{ 253 register u_int size; 254 register char *p; 255 static char *strptr = NULL; 256 static u_int strsize = 0; 257 258 size = strlen(str) + 1; 259 if (size > strsize) { 260 strsize = 1024; 261 if (strsize < size) 262 strsize = size; 263 strptr = (char *)malloc(strsize); 264 if (strptr == NULL) 265 error("savestr: malloc"); 266 } 267 (void)strcpy(strptr, str); 268 p = strptr; 269 strptr += size; 270 strsize -= size; 271 return (p); 272} 273 274char * 275read_infile(char *fname) 276{ 277 register int fd, cc; 278 register char *cp; 279 struct stat buf; 280 281 fd = open(fname, O_RDONLY); 282 if (fd < 0) 283 error("can't open %s: %s", fname, pcap_strerror(errno)); 284 285 if (fstat(fd, &buf) < 0) 286 error("can't stat %s: %s", fname, pcap_strerror(errno)); 287 288 cp = malloc((u_int)buf.st_size + 1); 289 cc = read(fd, cp, (int)buf.st_size); 290 if (cc < 0) 291 error("read %s: %s", fname, pcap_strerror(errno)); 292 if (cc != buf.st_size) 293 error("short read %s (%d != %d)", fname, cc, (int)buf.st_size); 294 cp[(int)buf.st_size] = '\0'; 295 296 return (cp); 297} 298 299/* 300 * Returns the difference between gmt and local time in seconds. 301 * Use gmtime() and localtime() to keep things simple. 302 */ 303int32_t 304gmt2local(void) 305{ 306 register int dt, dir; 307 register struct tm *gmt, *loc; 308 time_t t; 309 struct tm sgmt; 310 311 t = time(NULL); 312 gmt = &sgmt; 313 *gmt = *gmtime(&t); 314 loc = localtime(&t); 315 dt = (loc->tm_hour - gmt->tm_hour) * 60 * 60 + 316 (loc->tm_min - gmt->tm_min) * 60; 317 318 /* 319 * If the year or julian day is different, we span 00:00 GMT 320 * and must add or subtract a day. Check the year first to 321 * avoid problems when the julian day wraps. 322 */ 323 dir = loc->tm_year - gmt->tm_year; 324 if (dir == 0) 325 dir = loc->tm_yday - gmt->tm_yday; 326 dt += dir * 24 * 60 * 60; 327 328 return (dt); 329} 330