util.c revision 17680
1137587Snik/* 2137587Snik * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996 3137587Snik * The Regents of the University of California. All rights reserved. 4137587Snik * 5137587Snik * Redistribution and use in source and binary forms, with or without 6137587Snik * modification, are permitted provided that: (1) source code distributions 7 * retain the above copyright notice and this paragraph in its entirety, (2) 8 * distributions including binary code include the above copyright notice and 9 * this paragraph in its entirety in the documentation or other materials 10 * provided with the distribution, and (3) all advertising materials mentioning 11 * features or use of this software display the following acknowledgement: 12 * ``This product includes software developed by the University of California, 13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 14 * the University nor the names of its contributors may be used to endorse 15 * or promote products derived from this software without specific prior 16 * written permission. 17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20 */ 21 22#ifndef lint 23static char rcsid[] = 24 "@(#) $Header: util.c,v 1.52 96/07/15 18:22:54 leres Exp $ (LBL)"; 25#endif 26 27#include <sys/types.h> 28#include <sys/time.h> 29#include <sys/file.h> 30#include <sys/stat.h> 31 32#include <ctype.h> 33#include <errno.h> 34#ifdef HAVE_FCNTL_H 35#include <fcntl.h> 36#endif 37#include <pcap.h> 38#include <stdio.h> 39#if __STDC__ 40#include <stdarg.h> 41#else 42#include <varargs.h> 43#endif 44#include <stdlib.h> 45#include <string.h> 46#ifdef TIME_WITH_SYS_TIME 47#include <time.h> 48#endif 49#include <unistd.h> 50 51#include "interface.h" 52 53/* 54 * Print out a filename (or other ascii string). 55 * If ep is NULL, assume no truncation check is needed. 56 * Return true if truncated. 57 */ 58int 59fn_print(register const u_char *s, register const u_char *ep) 60{ 61 register int ret; 62 register u_char c; 63 64 ret = 1; /* assume truncated */ 65 while (ep == NULL || s < ep) { 66 c = *s++; 67 if (c == '\0') { 68 ret = 0; 69 break; 70 } 71 if (!isascii(c)) { 72 c = toascii(c); 73 putchar('M'); 74 putchar('-'); 75 } 76 if (!isprint(c)) { 77 c ^= 0x40; /* DEL to ?, others to alpha */ 78 putchar('^'); 79 } 80 putchar(c); 81 } 82 return(ret); 83} 84 85/* 86 * Print out a counted filename (or other ascii string). 87 * If ep is NULL, assume no truncation check is needed. 88 * Return true if truncated. 89 */ 90int 91fn_printn(register const u_char *s, register u_int n, 92 register const u_char *ep) 93{ 94 register int ret; 95 register u_char c; 96 97 ret = 1; /* assume truncated */ 98 while (ep == NULL || s < ep) { 99 if (n-- <= 0) { 100 ret = 0; 101 break; 102 } 103 c = *s++; 104 if (!isascii(c)) { 105 c = toascii(c); 106 putchar('M'); 107 putchar('-'); 108 } 109 if (!isprint(c)) { 110 c ^= 0x40; /* DEL to ?, others to alpha */ 111 putchar('^'); 112 } 113 putchar(c); 114 } 115 return(ret); 116} 117 118/* 119 * Print the timestamp 120 */ 121void 122ts_print(register const struct timeval *tvp) 123{ 124 register int s; 125 126 if (tflag > 0) { 127 /* Default */ 128 s = (tvp->tv_sec + thiszone) % 86400; 129 (void)printf("%02d:%02d:%02d.%06u ", 130 s / 3600, (s % 3600) / 60, s % 60, (u_int32_t)tvp->tv_usec); 131 } else if (tflag < 0) { 132 /* Unix timeval style */ 133 (void)printf("%u.%06u ", 134 (u_int32_t)tvp->tv_sec, (u_int32_t)tvp->tv_usec); 135 } 136} 137 138/* 139 * Convert a token value to a string; use "fmt" if not found. 140 */ 141const char * 142tok2str(register const struct tok *lp, register const char *fmt, 143 register int v) 144{ 145 static char buf[128]; 146 147 while (lp->s != NULL) { 148 if (lp->v == v) 149 return (lp->s); 150 ++lp; 151 } 152 if (fmt == NULL) 153 fmt = "#%d"; 154 (void)sprintf(buf, fmt, v); 155 return (buf); 156} 157 158 159/* VARARGS */ 160__dead void 161#if __STDC__ 162error(const char *fmt, ...) 163#else 164error(fmt, va_alist) 165 const char *fmt; 166 va_dcl 167#endif 168{ 169 va_list ap; 170 171 (void)fprintf(stderr, "%s: ", program_name); 172#if __STDC__ 173 va_start(ap, fmt); 174#else 175 va_start(ap); 176#endif 177 (void)vfprintf(stderr, fmt, ap); 178 va_end(ap); 179 if (*fmt) { 180 fmt += strlen(fmt); 181 if (fmt[-1] != '\n') 182 (void)fputc('\n', stderr); 183 } 184 exit(1); 185 /* NOTREACHED */ 186} 187 188/* VARARGS */ 189void 190#if __STDC__ 191warning(const char *fmt, ...) 192#else 193warning(fmt, va_alist) 194 const char *fmt; 195 va_dcl 196#endif 197{ 198 va_list ap; 199 200 (void)fprintf(stderr, "%s: WARNING: ", program_name); 201#if __STDC__ 202 va_start(ap, fmt); 203#else 204 va_start(ap); 205#endif 206 (void)vfprintf(stderr, fmt, ap); 207 va_end(ap); 208 if (*fmt) { 209 fmt += strlen(fmt); 210 if (fmt[-1] != '\n') 211 (void)fputc('\n', stderr); 212 } 213} 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 299int32_t 300gmt2local() 301{ 302 register int t; 303#if !defined(HAVE_ALTZONE) && !defined(HAVE_TIMEZONE) 304 struct timeval tv; 305 struct timezone tz; 306 register struct tm *tm; 307#endif 308 309 t = 0; 310#if !defined(HAVE_ALTZONE) && !defined(HAVE_TIMEZONE) 311 if (gettimeofday(&tv, &tz) < 0) 312 error("gettimeofday"); 313 tm = localtime((time_t *)&tv.tv_sec); 314#ifdef HAVE_TM_GMTOFF 315 t = tm->tm_gmtoff; 316#else 317 t = tz.tz_minuteswest * -60; 318 /* XXX Some systems need this, some auto offset tz_minuteswest... */ 319 if (tm->tm_isdst) 320 t += 60 * 60; 321#endif 322#endif 323 324#ifdef HAVE_TIMEZONE 325 tzset(); 326 t = -timezone; 327 if (daylight) 328 t += 60 * 60; 329#endif 330 331#ifdef HAVE_ALTZONE 332 tzset(); 333 t = -altzone; 334#endif 335 336 return (t); 337} 338