17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * utils.c - various utility functions used in pppd. 37c478bd9Sstevel@tonic-gate * 4*24da5b34Srie * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 5*24da5b34Srie * Use is subject to license terms. 67c478bd9Sstevel@tonic-gate * 77c478bd9Sstevel@tonic-gate * Permission to use, copy, modify, and distribute this software and its 87c478bd9Sstevel@tonic-gate * documentation is hereby granted, provided that the above copyright 97c478bd9Sstevel@tonic-gate * notice appears in all copies. 107c478bd9Sstevel@tonic-gate * 117c478bd9Sstevel@tonic-gate * SUN MAKES NO REPRESENTATION OR WARRANTIES ABOUT THE SUITABILITY OF 127c478bd9Sstevel@tonic-gate * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 137c478bd9Sstevel@tonic-gate * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 147c478bd9Sstevel@tonic-gate * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR 157c478bd9Sstevel@tonic-gate * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR 167c478bd9Sstevel@tonic-gate * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES 177c478bd9Sstevel@tonic-gate * 187c478bd9Sstevel@tonic-gate * Copyright (c) 1999 The Australian National University. 197c478bd9Sstevel@tonic-gate * All rights reserved. 207c478bd9Sstevel@tonic-gate * 217c478bd9Sstevel@tonic-gate * Redistribution and use in source and binary forms are permitted 227c478bd9Sstevel@tonic-gate * provided that the above copyright notice and this paragraph are 237c478bd9Sstevel@tonic-gate * duplicated in all such forms and that any documentation, 247c478bd9Sstevel@tonic-gate * advertising materials, and other materials related to such 257c478bd9Sstevel@tonic-gate * distribution and use acknowledge that the software was developed 267c478bd9Sstevel@tonic-gate * by the Australian National University. The name of the University 277c478bd9Sstevel@tonic-gate * may not be used to endorse or promote products derived from this 287c478bd9Sstevel@tonic-gate * software without specific prior written permission. 297c478bd9Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 307c478bd9Sstevel@tonic-gate * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 317c478bd9Sstevel@tonic-gate * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 327c478bd9Sstevel@tonic-gate */ 337c478bd9Sstevel@tonic-gate 347c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 357c478bd9Sstevel@tonic-gate #define RCSID "$Id: utils.c,v 1.10 2000/03/27 01:36:48 paulus Exp $" 367c478bd9Sstevel@tonic-gate 377c478bd9Sstevel@tonic-gate #ifdef __linux__ 387c478bd9Sstevel@tonic-gate #define _GNU_SOURCE 397c478bd9Sstevel@tonic-gate #endif 407c478bd9Sstevel@tonic-gate #include <stdio.h> 417c478bd9Sstevel@tonic-gate #include <ctype.h> 427c478bd9Sstevel@tonic-gate #include <stdlib.h> 437c478bd9Sstevel@tonic-gate #include <string.h> 447c478bd9Sstevel@tonic-gate #include <unistd.h> 457c478bd9Sstevel@tonic-gate #include <signal.h> 467c478bd9Sstevel@tonic-gate #include <errno.h> 477c478bd9Sstevel@tonic-gate #include <fcntl.h> 487c478bd9Sstevel@tonic-gate #include <syslog.h> 497c478bd9Sstevel@tonic-gate #include <netdb.h> 507c478bd9Sstevel@tonic-gate #include <utmp.h> 517c478bd9Sstevel@tonic-gate #include <pwd.h> 527c478bd9Sstevel@tonic-gate #include <sys/param.h> 537c478bd9Sstevel@tonic-gate #include <sys/types.h> 547c478bd9Sstevel@tonic-gate #include <sys/wait.h> 557c478bd9Sstevel@tonic-gate #include <sys/time.h> 567c478bd9Sstevel@tonic-gate #include <sys/resource.h> 577c478bd9Sstevel@tonic-gate #include <sys/stat.h> 587c478bd9Sstevel@tonic-gate #include <sys/socket.h> 597c478bd9Sstevel@tonic-gate #include <netinet/in.h> 607c478bd9Sstevel@tonic-gate #ifdef SVR4 617c478bd9Sstevel@tonic-gate #include <sys/mkdev.h> 627c478bd9Sstevel@tonic-gate #endif 637c478bd9Sstevel@tonic-gate 647c478bd9Sstevel@tonic-gate #include "pppd.h" 657c478bd9Sstevel@tonic-gate 667c478bd9Sstevel@tonic-gate #if !defined(lint) && !defined(_lint) 677c478bd9Sstevel@tonic-gate static const char rcsid[] = RCSID; 687c478bd9Sstevel@tonic-gate #endif 697c478bd9Sstevel@tonic-gate 707c478bd9Sstevel@tonic-gate #if defined(SUNOS4) 717c478bd9Sstevel@tonic-gate extern char *strerror(); 727c478bd9Sstevel@tonic-gate #endif 737c478bd9Sstevel@tonic-gate 747c478bd9Sstevel@tonic-gate /* Don't log to stdout until we're sure it's ok to do so. */ 757c478bd9Sstevel@tonic-gate bool early_log = 1; 767c478bd9Sstevel@tonic-gate 777c478bd9Sstevel@tonic-gate static void pr_log __P((void *, const char *, ...)); 787c478bd9Sstevel@tonic-gate static void logit __P((int, const char *, va_list)); 797c478bd9Sstevel@tonic-gate static void vslp_printer __P((void *, const char *, ...)); 807c478bd9Sstevel@tonic-gate static void format_packet __P((u_char *, int, 817c478bd9Sstevel@tonic-gate void (*) (void *, const char *, ...), void *)); 827c478bd9Sstevel@tonic-gate 837c478bd9Sstevel@tonic-gate struct buffer_info { 847c478bd9Sstevel@tonic-gate char *ptr; 857c478bd9Sstevel@tonic-gate int len; 867c478bd9Sstevel@tonic-gate }; 877c478bd9Sstevel@tonic-gate 887c478bd9Sstevel@tonic-gate /* 897c478bd9Sstevel@tonic-gate * strllen - like strlen, but doesn't run past end of input. 907c478bd9Sstevel@tonic-gate */ 917c478bd9Sstevel@tonic-gate size_t 927c478bd9Sstevel@tonic-gate strllen(str, len) 937c478bd9Sstevel@tonic-gate const char *str; 947c478bd9Sstevel@tonic-gate size_t len; 957c478bd9Sstevel@tonic-gate { 967c478bd9Sstevel@tonic-gate size_t ret; 977c478bd9Sstevel@tonic-gate 987c478bd9Sstevel@tonic-gate for (ret = 0; ret < len; ret++) 997c478bd9Sstevel@tonic-gate if (*str++ == '\0') 1007c478bd9Sstevel@tonic-gate break; 1017c478bd9Sstevel@tonic-gate return (ret); 1027c478bd9Sstevel@tonic-gate } 1037c478bd9Sstevel@tonic-gate 1047c478bd9Sstevel@tonic-gate /* 1057c478bd9Sstevel@tonic-gate * slprintf - format a message into a buffer. Like sprintf except we 1067c478bd9Sstevel@tonic-gate * also specify the length of the output buffer, and we handle %m 1077c478bd9Sstevel@tonic-gate * (error message), %v (visible string), %q (quoted string), %t 1087c478bd9Sstevel@tonic-gate * (current time), %I (IP address), %P (PPP packet), and %B (sequence 1097c478bd9Sstevel@tonic-gate * of bytes) formats. Doesn't do floating-point formats. Returns the 1107c478bd9Sstevel@tonic-gate * number of chars put into buf. 1117c478bd9Sstevel@tonic-gate */ 1127c478bd9Sstevel@tonic-gate int 1137c478bd9Sstevel@tonic-gate slprintf __V((char *buf, int buflen, const char *fmt, ...)) 1147c478bd9Sstevel@tonic-gate { 1157c478bd9Sstevel@tonic-gate va_list args; 1167c478bd9Sstevel@tonic-gate int n; 1177c478bd9Sstevel@tonic-gate 1187c478bd9Sstevel@tonic-gate #if defined(__STDC__) 1197c478bd9Sstevel@tonic-gate va_start(args, fmt); 1207c478bd9Sstevel@tonic-gate #else 1217c478bd9Sstevel@tonic-gate char *buf; 1227c478bd9Sstevel@tonic-gate int buflen; 1237c478bd9Sstevel@tonic-gate const char *fmt; 1247c478bd9Sstevel@tonic-gate va_start(args); 1257c478bd9Sstevel@tonic-gate buf = va_arg(args, char *); 1267c478bd9Sstevel@tonic-gate buflen = va_arg(args, int); 1277c478bd9Sstevel@tonic-gate fmt = va_arg(args, const char *); 1287c478bd9Sstevel@tonic-gate #endif 1297c478bd9Sstevel@tonic-gate n = vslprintf(buf, buflen, fmt, args); 1307c478bd9Sstevel@tonic-gate va_end(args); 1317c478bd9Sstevel@tonic-gate return (n); 1327c478bd9Sstevel@tonic-gate } 1337c478bd9Sstevel@tonic-gate 1347c478bd9Sstevel@tonic-gate /* 1357c478bd9Sstevel@tonic-gate * Print to file or, if argument is NULL, to syslog at debug level. 1367c478bd9Sstevel@tonic-gate */ 1377c478bd9Sstevel@tonic-gate int 1387c478bd9Sstevel@tonic-gate flprintf __V((FILE *strptr, const char *fmt, ...)) 1397c478bd9Sstevel@tonic-gate { 1407c478bd9Sstevel@tonic-gate va_list args; 1417c478bd9Sstevel@tonic-gate int n; 1427c478bd9Sstevel@tonic-gate char buf[1024], *bp, *nlp, *ebp; 1437c478bd9Sstevel@tonic-gate 1447c478bd9Sstevel@tonic-gate #if defined(__STDC__) 1457c478bd9Sstevel@tonic-gate va_start(args, fmt); 1467c478bd9Sstevel@tonic-gate #else 1477c478bd9Sstevel@tonic-gate FILE *strptr; 1487c478bd9Sstevel@tonic-gate const char *fmt; 1497c478bd9Sstevel@tonic-gate va_start(args); 1507c478bd9Sstevel@tonic-gate strptr = va_arg(args, FILE *); 1517c478bd9Sstevel@tonic-gate fmt = va_arg(args, const char *); 1527c478bd9Sstevel@tonic-gate #endif 1537c478bd9Sstevel@tonic-gate n = vslprintf(buf, sizeof (buf), fmt, args); 1547c478bd9Sstevel@tonic-gate va_end(args); 1557c478bd9Sstevel@tonic-gate if (strptr == NULL) { 1567c478bd9Sstevel@tonic-gate bp = buf; 1577c478bd9Sstevel@tonic-gate ebp = buf + n; 1587c478bd9Sstevel@tonic-gate while (bp < ebp) { 1597c478bd9Sstevel@tonic-gate if ((nlp = strchr(bp, '\n')) == NULL) 1607c478bd9Sstevel@tonic-gate nlp = ebp; 1617c478bd9Sstevel@tonic-gate if (nlp > bp) { 1627c478bd9Sstevel@tonic-gate *nlp = '\0'; 1637c478bd9Sstevel@tonic-gate syslog(LOG_DEBUG, "%s", bp); 1647c478bd9Sstevel@tonic-gate } 1657c478bd9Sstevel@tonic-gate bp = nlp + 1; 1667c478bd9Sstevel@tonic-gate } 1677c478bd9Sstevel@tonic-gate } else { 1687c478bd9Sstevel@tonic-gate n = fwrite(buf, 1, n, strptr); 1697c478bd9Sstevel@tonic-gate } 1707c478bd9Sstevel@tonic-gate return (n); 1717c478bd9Sstevel@tonic-gate } 1727c478bd9Sstevel@tonic-gate 1737c478bd9Sstevel@tonic-gate /* 1747c478bd9Sstevel@tonic-gate * vslprintf - like slprintf, takes a va_list instead of a list of args. 1757c478bd9Sstevel@tonic-gate */ 1767c478bd9Sstevel@tonic-gate #define OUTCHAR(c) (buflen > 0? (--buflen, *buf++ = (c)): 0) 1777c478bd9Sstevel@tonic-gate 1787c478bd9Sstevel@tonic-gate int 1797c478bd9Sstevel@tonic-gate vslprintf(buf, buflen, fmt, args) 1807c478bd9Sstevel@tonic-gate char *buf; 1817c478bd9Sstevel@tonic-gate int buflen; 1827c478bd9Sstevel@tonic-gate const char *fmt; 1837c478bd9Sstevel@tonic-gate va_list args; 1847c478bd9Sstevel@tonic-gate { 1857c478bd9Sstevel@tonic-gate int c, n, longs; 1867c478bd9Sstevel@tonic-gate int width, prec, fillch; 1877c478bd9Sstevel@tonic-gate int base, len, neg, quoted; 1887c478bd9Sstevel@tonic-gate #ifdef SOL2 1897c478bd9Sstevel@tonic-gate uint64_t val; 1907c478bd9Sstevel@tonic-gate int64_t sval; 1917c478bd9Sstevel@tonic-gate #else 1927c478bd9Sstevel@tonic-gate unsigned long val; 1937c478bd9Sstevel@tonic-gate long sval; 1947c478bd9Sstevel@tonic-gate #endif 1957c478bd9Sstevel@tonic-gate char *buf0, *mstr; 1967c478bd9Sstevel@tonic-gate const char *f, *str; 1977c478bd9Sstevel@tonic-gate unsigned char *p; 1987c478bd9Sstevel@tonic-gate char num[32]; /* 2^64 is 20 chars decimal, 22 octal */ 1997c478bd9Sstevel@tonic-gate time_t t; 2007c478bd9Sstevel@tonic-gate u_int32_t ip; 2017c478bd9Sstevel@tonic-gate static const char hexchars[] = "0123456789abcdef"; 2027c478bd9Sstevel@tonic-gate struct buffer_info bufinfo; 2037c478bd9Sstevel@tonic-gate 2047c478bd9Sstevel@tonic-gate buf0 = buf; 2057c478bd9Sstevel@tonic-gate --buflen; 2067c478bd9Sstevel@tonic-gate while (buflen > 0) { 2077c478bd9Sstevel@tonic-gate for (f = fmt; *f != '%' && *f != 0; ++f) 2087c478bd9Sstevel@tonic-gate ; 2097c478bd9Sstevel@tonic-gate if (f > fmt) { 2107c478bd9Sstevel@tonic-gate len = f - fmt; 2117c478bd9Sstevel@tonic-gate if (len > buflen) 2127c478bd9Sstevel@tonic-gate len = buflen; 2137c478bd9Sstevel@tonic-gate (void) memcpy(buf, fmt, len); 2147c478bd9Sstevel@tonic-gate buf += len; 2157c478bd9Sstevel@tonic-gate buflen -= len; 2167c478bd9Sstevel@tonic-gate fmt = f; 2177c478bd9Sstevel@tonic-gate } 2187c478bd9Sstevel@tonic-gate if (*fmt == 0) 2197c478bd9Sstevel@tonic-gate break; 2207c478bd9Sstevel@tonic-gate c = *++fmt; 2217c478bd9Sstevel@tonic-gate width = 0; 2227c478bd9Sstevel@tonic-gate prec = -1; 2237c478bd9Sstevel@tonic-gate fillch = ' '; 2247c478bd9Sstevel@tonic-gate if (c == '0') { 2257c478bd9Sstevel@tonic-gate fillch = '0'; 2267c478bd9Sstevel@tonic-gate c = *++fmt; 2277c478bd9Sstevel@tonic-gate } 2287c478bd9Sstevel@tonic-gate if (c == '*') { 2297c478bd9Sstevel@tonic-gate width = va_arg(args, int); 2307c478bd9Sstevel@tonic-gate c = *++fmt; 2317c478bd9Sstevel@tonic-gate } else { 2327c478bd9Sstevel@tonic-gate while (isdigit(c)) { 2337c478bd9Sstevel@tonic-gate width = width * 10 + c - '0'; 2347c478bd9Sstevel@tonic-gate c = *++fmt; 2357c478bd9Sstevel@tonic-gate } 2367c478bd9Sstevel@tonic-gate } 2377c478bd9Sstevel@tonic-gate if (c == '.') { 2387c478bd9Sstevel@tonic-gate c = *++fmt; 2397c478bd9Sstevel@tonic-gate if (c == '*') { 2407c478bd9Sstevel@tonic-gate prec = va_arg(args, int); 2417c478bd9Sstevel@tonic-gate c = *++fmt; 2427c478bd9Sstevel@tonic-gate } else { 2437c478bd9Sstevel@tonic-gate prec = 0; 2447c478bd9Sstevel@tonic-gate while (isdigit(c)) { 2457c478bd9Sstevel@tonic-gate prec = prec * 10 + c - '0'; 2467c478bd9Sstevel@tonic-gate c = *++fmt; 2477c478bd9Sstevel@tonic-gate } 2487c478bd9Sstevel@tonic-gate } 2497c478bd9Sstevel@tonic-gate } 2507c478bd9Sstevel@tonic-gate longs = 0; 2517c478bd9Sstevel@tonic-gate if (c == 'l') { 2527c478bd9Sstevel@tonic-gate longs++; 2537c478bd9Sstevel@tonic-gate c = *++fmt; 2547c478bd9Sstevel@tonic-gate if (c == 'l') { 2557c478bd9Sstevel@tonic-gate longs++; 2567c478bd9Sstevel@tonic-gate c = *++fmt; 2577c478bd9Sstevel@tonic-gate } 2587c478bd9Sstevel@tonic-gate } 2597c478bd9Sstevel@tonic-gate str = 0; 2607c478bd9Sstevel@tonic-gate base = 0; 2617c478bd9Sstevel@tonic-gate neg = 0; 2627c478bd9Sstevel@tonic-gate val = 0; 2637c478bd9Sstevel@tonic-gate ++fmt; 2647c478bd9Sstevel@tonic-gate switch (c) { 2657c478bd9Sstevel@tonic-gate case 'u': 2667c478bd9Sstevel@tonic-gate #ifdef SOL2 2677c478bd9Sstevel@tonic-gate if (longs >= 2) 2687c478bd9Sstevel@tonic-gate val = va_arg(args, uint64_t); 2697c478bd9Sstevel@tonic-gate else 2707c478bd9Sstevel@tonic-gate #endif 2717c478bd9Sstevel@tonic-gate if (longs > 0) 2727c478bd9Sstevel@tonic-gate val = va_arg(args, unsigned long); 2737c478bd9Sstevel@tonic-gate else 2747c478bd9Sstevel@tonic-gate val = va_arg(args, unsigned int); 2757c478bd9Sstevel@tonic-gate base = 10; 2767c478bd9Sstevel@tonic-gate break; 2777c478bd9Sstevel@tonic-gate case 'd': 2787c478bd9Sstevel@tonic-gate #ifdef SOL2 2797c478bd9Sstevel@tonic-gate if (longs >= 2) 2807c478bd9Sstevel@tonic-gate sval = va_arg(args, int64_t); 2817c478bd9Sstevel@tonic-gate else 2827c478bd9Sstevel@tonic-gate #endif 2837c478bd9Sstevel@tonic-gate if (longs > 0) 2847c478bd9Sstevel@tonic-gate sval = va_arg(args, long); 2857c478bd9Sstevel@tonic-gate else 2867c478bd9Sstevel@tonic-gate sval = va_arg(args, int); 2877c478bd9Sstevel@tonic-gate if (sval < 0) { 2887c478bd9Sstevel@tonic-gate neg = 1; 2897c478bd9Sstevel@tonic-gate val = -sval; 2907c478bd9Sstevel@tonic-gate } else 2917c478bd9Sstevel@tonic-gate val = sval; 2927c478bd9Sstevel@tonic-gate base = 10; 2937c478bd9Sstevel@tonic-gate break; 2947c478bd9Sstevel@tonic-gate case 'o': 2957c478bd9Sstevel@tonic-gate #ifdef SOL2 2967c478bd9Sstevel@tonic-gate if (longs >= 2) 2977c478bd9Sstevel@tonic-gate val = va_arg(args, uint64_t); 2987c478bd9Sstevel@tonic-gate else 2997c478bd9Sstevel@tonic-gate #endif 3007c478bd9Sstevel@tonic-gate if (longs > 0) 3017c478bd9Sstevel@tonic-gate val = va_arg(args, unsigned long); 3027c478bd9Sstevel@tonic-gate else 3037c478bd9Sstevel@tonic-gate val = va_arg(args, unsigned int); 3047c478bd9Sstevel@tonic-gate base = 8; 3057c478bd9Sstevel@tonic-gate break; 3067c478bd9Sstevel@tonic-gate case 'x': 3077c478bd9Sstevel@tonic-gate case 'X': 3087c478bd9Sstevel@tonic-gate #ifdef SOL2 3097c478bd9Sstevel@tonic-gate if (longs >= 2) 3107c478bd9Sstevel@tonic-gate val = va_arg(args, uint64_t); 3117c478bd9Sstevel@tonic-gate else 3127c478bd9Sstevel@tonic-gate #endif 3137c478bd9Sstevel@tonic-gate if (longs > 0) 3147c478bd9Sstevel@tonic-gate val = va_arg(args, unsigned long); 3157c478bd9Sstevel@tonic-gate else 3167c478bd9Sstevel@tonic-gate val = va_arg(args, unsigned int); 3177c478bd9Sstevel@tonic-gate base = 16; 3187c478bd9Sstevel@tonic-gate break; 3197c478bd9Sstevel@tonic-gate case 'p': 3207c478bd9Sstevel@tonic-gate val = (unsigned long) va_arg(args, void *); 3217c478bd9Sstevel@tonic-gate base = 16; 3227c478bd9Sstevel@tonic-gate neg = 2; 3237c478bd9Sstevel@tonic-gate break; 3247c478bd9Sstevel@tonic-gate case 's': 3257c478bd9Sstevel@tonic-gate str = va_arg(args, const char *); 3267c478bd9Sstevel@tonic-gate break; 3277c478bd9Sstevel@tonic-gate case 'c': 3287c478bd9Sstevel@tonic-gate num[0] = va_arg(args, int); 3297c478bd9Sstevel@tonic-gate num[1] = 0; 3307c478bd9Sstevel@tonic-gate str = num; 3317c478bd9Sstevel@tonic-gate break; 3327c478bd9Sstevel@tonic-gate case 'm': 3337c478bd9Sstevel@tonic-gate str = strerror(errno); 3347c478bd9Sstevel@tonic-gate break; 3357c478bd9Sstevel@tonic-gate case 'I': 3367c478bd9Sstevel@tonic-gate ip = va_arg(args, u_int32_t); 3377c478bd9Sstevel@tonic-gate ip = ntohl(ip); 3387c478bd9Sstevel@tonic-gate (void) slprintf(num, sizeof(num), "%d.%d.%d.%d", (ip >> 24) & 0xff, 3397c478bd9Sstevel@tonic-gate (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff); 3407c478bd9Sstevel@tonic-gate str = num; 3417c478bd9Sstevel@tonic-gate break; 3427c478bd9Sstevel@tonic-gate case 't': 3437c478bd9Sstevel@tonic-gate (void) time(&t); 3447c478bd9Sstevel@tonic-gate mstr = ctime(&t); 3457c478bd9Sstevel@tonic-gate mstr += 4; /* chop off the day name */ 3467c478bd9Sstevel@tonic-gate mstr[15] = 0; /* chop off year and newline */ 3477c478bd9Sstevel@tonic-gate str = (const char *)mstr; 3487c478bd9Sstevel@tonic-gate break; 3497c478bd9Sstevel@tonic-gate case 'v': /* "visible" string */ 3507c478bd9Sstevel@tonic-gate case 'q': /* quoted string */ 3517c478bd9Sstevel@tonic-gate quoted = c == 'q'; 3527c478bd9Sstevel@tonic-gate p = va_arg(args, unsigned char *); 3537c478bd9Sstevel@tonic-gate if (fillch == '0' && prec >= 0) { 3547c478bd9Sstevel@tonic-gate n = prec; 3557c478bd9Sstevel@tonic-gate } else { 3567c478bd9Sstevel@tonic-gate n = strlen((char *)p); 3577c478bd9Sstevel@tonic-gate if (prec >= 0 && n > prec) 3587c478bd9Sstevel@tonic-gate n = prec; 3597c478bd9Sstevel@tonic-gate } 3607c478bd9Sstevel@tonic-gate while (n > 0 && buflen > 0) { 3617c478bd9Sstevel@tonic-gate c = *p++; 3627c478bd9Sstevel@tonic-gate --n; 3637c478bd9Sstevel@tonic-gate if (!quoted && c >= 0x80) { 3647c478bd9Sstevel@tonic-gate (void) OUTCHAR('M'); 3657c478bd9Sstevel@tonic-gate (void) OUTCHAR('-'); 3667c478bd9Sstevel@tonic-gate c -= 0x80; 3677c478bd9Sstevel@tonic-gate } 3687c478bd9Sstevel@tonic-gate if (quoted && (c == '"' || c == '\\')) 3697c478bd9Sstevel@tonic-gate (void) OUTCHAR('\\'); 3707c478bd9Sstevel@tonic-gate if (c < 0x20 || (0x7f <= c && c < 0xa0)) { 3717c478bd9Sstevel@tonic-gate if (quoted) { 3727c478bd9Sstevel@tonic-gate (void) OUTCHAR('\\'); 3737c478bd9Sstevel@tonic-gate switch (c) { 3747c478bd9Sstevel@tonic-gate case '\t': (void) OUTCHAR('t'); break; 3757c478bd9Sstevel@tonic-gate case '\n': (void) OUTCHAR('n'); break; 3767c478bd9Sstevel@tonic-gate case '\b': (void) OUTCHAR('b'); break; 3777c478bd9Sstevel@tonic-gate case '\f': (void) OUTCHAR('f'); break; 3787c478bd9Sstevel@tonic-gate default: 3797c478bd9Sstevel@tonic-gate (void) OUTCHAR('x'); 3807c478bd9Sstevel@tonic-gate (void) OUTCHAR(hexchars[c >> 4]); 3817c478bd9Sstevel@tonic-gate (void) OUTCHAR(hexchars[c & 0xf]); 3827c478bd9Sstevel@tonic-gate } 3837c478bd9Sstevel@tonic-gate } else { 3847c478bd9Sstevel@tonic-gate if (c == '\t') 3857c478bd9Sstevel@tonic-gate (void) OUTCHAR(c); 3867c478bd9Sstevel@tonic-gate else { 3877c478bd9Sstevel@tonic-gate (void) OUTCHAR('^'); 3887c478bd9Sstevel@tonic-gate (void) OUTCHAR(c ^ 0x40); 3897c478bd9Sstevel@tonic-gate } 3907c478bd9Sstevel@tonic-gate } 3917c478bd9Sstevel@tonic-gate } else 3927c478bd9Sstevel@tonic-gate (void) OUTCHAR(c); 3937c478bd9Sstevel@tonic-gate } 3947c478bd9Sstevel@tonic-gate continue; 3957c478bd9Sstevel@tonic-gate case 'P': /* print PPP packet */ 3967c478bd9Sstevel@tonic-gate bufinfo.ptr = buf; 3977c478bd9Sstevel@tonic-gate bufinfo.len = buflen + 1; 3987c478bd9Sstevel@tonic-gate p = va_arg(args, unsigned char *); 3997c478bd9Sstevel@tonic-gate n = va_arg(args, int); 4007c478bd9Sstevel@tonic-gate format_packet(p, n, vslp_printer, &bufinfo); 4017c478bd9Sstevel@tonic-gate buf = bufinfo.ptr; 4027c478bd9Sstevel@tonic-gate buflen = bufinfo.len - 1; 4037c478bd9Sstevel@tonic-gate continue; 4047c478bd9Sstevel@tonic-gate case 'B': 4057c478bd9Sstevel@tonic-gate p = va_arg(args, unsigned char *); 4067c478bd9Sstevel@tonic-gate if ((n = prec) > width && width > 0) 4077c478bd9Sstevel@tonic-gate n = width; 4087c478bd9Sstevel@tonic-gate /* For safety's sake */ 4097c478bd9Sstevel@tonic-gate if (n > 2000) 4107c478bd9Sstevel@tonic-gate n = 2000; 4117c478bd9Sstevel@tonic-gate while (--n >= 0) { 4127c478bd9Sstevel@tonic-gate c = *p++; 4137c478bd9Sstevel@tonic-gate if (fillch == ' ') 4147c478bd9Sstevel@tonic-gate (void) OUTCHAR(' '); 4157c478bd9Sstevel@tonic-gate (void) OUTCHAR(hexchars[(c >> 4) & 0xf]); 4167c478bd9Sstevel@tonic-gate (void) OUTCHAR(hexchars[c & 0xf]); 4177c478bd9Sstevel@tonic-gate } 4187c478bd9Sstevel@tonic-gate if (prec > width && width > 0) { 4197c478bd9Sstevel@tonic-gate (void) OUTCHAR('.'); 4207c478bd9Sstevel@tonic-gate (void) OUTCHAR('.'); 4217c478bd9Sstevel@tonic-gate (void) OUTCHAR('.'); 4227c478bd9Sstevel@tonic-gate } 4237c478bd9Sstevel@tonic-gate continue; 4247c478bd9Sstevel@tonic-gate default: 4257c478bd9Sstevel@tonic-gate *buf++ = '%'; 4267c478bd9Sstevel@tonic-gate if (c != '%') 4277c478bd9Sstevel@tonic-gate --fmt; /* so %z outputs %z etc. */ 4287c478bd9Sstevel@tonic-gate --buflen; 4297c478bd9Sstevel@tonic-gate continue; 4307c478bd9Sstevel@tonic-gate } 4317c478bd9Sstevel@tonic-gate if (base != 0) { 4327c478bd9Sstevel@tonic-gate mstr = num + sizeof(num); 4337c478bd9Sstevel@tonic-gate *--mstr = 0; 4347c478bd9Sstevel@tonic-gate while (mstr > num + neg) { 4357c478bd9Sstevel@tonic-gate *--mstr = hexchars[val % base]; 4367c478bd9Sstevel@tonic-gate val = val / base; 4377c478bd9Sstevel@tonic-gate if (--prec <= 0 && val == 0) 4387c478bd9Sstevel@tonic-gate break; 4397c478bd9Sstevel@tonic-gate } 4407c478bd9Sstevel@tonic-gate switch (neg) { 4417c478bd9Sstevel@tonic-gate case 1: 4427c478bd9Sstevel@tonic-gate *--mstr = '-'; 4437c478bd9Sstevel@tonic-gate break; 4447c478bd9Sstevel@tonic-gate case 2: 4457c478bd9Sstevel@tonic-gate *--mstr = 'x'; 4467c478bd9Sstevel@tonic-gate *--mstr = '0'; 4477c478bd9Sstevel@tonic-gate break; 4487c478bd9Sstevel@tonic-gate } 4497c478bd9Sstevel@tonic-gate len = num + sizeof(num) - 1 - mstr; 4507c478bd9Sstevel@tonic-gate str = (const char *)mstr; 4517c478bd9Sstevel@tonic-gate } else { 4527c478bd9Sstevel@tonic-gate len = strlen(str); 4537c478bd9Sstevel@tonic-gate if (prec >= 0 && len > prec) 4547c478bd9Sstevel@tonic-gate len = prec; 4557c478bd9Sstevel@tonic-gate } 4567c478bd9Sstevel@tonic-gate if (width > 0) { 4577c478bd9Sstevel@tonic-gate if (width > buflen) 4587c478bd9Sstevel@tonic-gate width = buflen; 4597c478bd9Sstevel@tonic-gate if ((n = width - len) > 0) { 4607c478bd9Sstevel@tonic-gate buflen -= n; 4617c478bd9Sstevel@tonic-gate for (; n > 0; --n) 4627c478bd9Sstevel@tonic-gate *buf++ = fillch; 4637c478bd9Sstevel@tonic-gate } 4647c478bd9Sstevel@tonic-gate } 4657c478bd9Sstevel@tonic-gate if (len > buflen) 4667c478bd9Sstevel@tonic-gate len = buflen; 4677c478bd9Sstevel@tonic-gate (void) memcpy(buf, str, len); 4687c478bd9Sstevel@tonic-gate buf += len; 4697c478bd9Sstevel@tonic-gate buflen -= len; 4707c478bd9Sstevel@tonic-gate } 4717c478bd9Sstevel@tonic-gate *buf = 0; 4727c478bd9Sstevel@tonic-gate return (buf - buf0); 4737c478bd9Sstevel@tonic-gate } 4747c478bd9Sstevel@tonic-gate 4757c478bd9Sstevel@tonic-gate /* 4767c478bd9Sstevel@tonic-gate * vslp_printer - used in processing a %P format 4777c478bd9Sstevel@tonic-gate */ 4787c478bd9Sstevel@tonic-gate static void 4797c478bd9Sstevel@tonic-gate vslp_printer __V((void *arg, const char *fmt, ...)) 4807c478bd9Sstevel@tonic-gate { 4817c478bd9Sstevel@tonic-gate int n; 4827c478bd9Sstevel@tonic-gate va_list pvar; 4837c478bd9Sstevel@tonic-gate struct buffer_info *bi; 4847c478bd9Sstevel@tonic-gate 4857c478bd9Sstevel@tonic-gate #if defined(__STDC__) 4867c478bd9Sstevel@tonic-gate va_start(pvar, fmt); 4877c478bd9Sstevel@tonic-gate #else 4887c478bd9Sstevel@tonic-gate void *arg; 4897c478bd9Sstevel@tonic-gate const char *fmt; 4907c478bd9Sstevel@tonic-gate va_start(pvar); 4917c478bd9Sstevel@tonic-gate arg = va_arg(pvar, void *); 4927c478bd9Sstevel@tonic-gate fmt = va_arg(pvar, const char *); 4937c478bd9Sstevel@tonic-gate #endif 4947c478bd9Sstevel@tonic-gate 4957c478bd9Sstevel@tonic-gate bi = (struct buffer_info *) arg; 4967c478bd9Sstevel@tonic-gate n = vslprintf(bi->ptr, bi->len, fmt, pvar); 4977c478bd9Sstevel@tonic-gate va_end(pvar); 4987c478bd9Sstevel@tonic-gate 4997c478bd9Sstevel@tonic-gate bi->ptr += n; 5007c478bd9Sstevel@tonic-gate bi->len -= n; 5017c478bd9Sstevel@tonic-gate } 5027c478bd9Sstevel@tonic-gate 5037c478bd9Sstevel@tonic-gate /* 5047c478bd9Sstevel@tonic-gate * log_packet - format a packet and log it. 5057c478bd9Sstevel@tonic-gate */ 5067c478bd9Sstevel@tonic-gate 5077c478bd9Sstevel@tonic-gate static char line[256]; /* line to be logged accumulated here */ 5087c478bd9Sstevel@tonic-gate static char *linep; 5097c478bd9Sstevel@tonic-gate 5107c478bd9Sstevel@tonic-gate void 5117c478bd9Sstevel@tonic-gate log_packet(p, len, prefix, level) 5127c478bd9Sstevel@tonic-gate u_char *p; 5137c478bd9Sstevel@tonic-gate int len; 5147c478bd9Sstevel@tonic-gate const char *prefix; 5157c478bd9Sstevel@tonic-gate int level; 5167c478bd9Sstevel@tonic-gate { 5177c478bd9Sstevel@tonic-gate (void) strlcpy(line, prefix, sizeof(line)); 5187c478bd9Sstevel@tonic-gate linep = line + strlen(line); 5197c478bd9Sstevel@tonic-gate format_packet(p, len, pr_log, (void *)level); 5207c478bd9Sstevel@tonic-gate if (linep != line) 5217c478bd9Sstevel@tonic-gate syslog(level, "%s", line); 5227c478bd9Sstevel@tonic-gate } 5237c478bd9Sstevel@tonic-gate 5247c478bd9Sstevel@tonic-gate /* 5257c478bd9Sstevel@tonic-gate * format_packet - make a readable representation of a packet, 5267c478bd9Sstevel@tonic-gate * calling `printer(arg, format, ...)' to output it. 5277c478bd9Sstevel@tonic-gate */ 5287c478bd9Sstevel@tonic-gate static void 5297c478bd9Sstevel@tonic-gate format_packet(p, len, printer, arg) 5307c478bd9Sstevel@tonic-gate u_char *p; 5317c478bd9Sstevel@tonic-gate int len; 5327c478bd9Sstevel@tonic-gate void (*printer) __P((void *, const char *, ...)); 5337c478bd9Sstevel@tonic-gate void *arg; 5347c478bd9Sstevel@tonic-gate { 5357c478bd9Sstevel@tonic-gate int i, n; 5367c478bd9Sstevel@tonic-gate u_short proto; 5377c478bd9Sstevel@tonic-gate struct protent *protp; 5387c478bd9Sstevel@tonic-gate 5397c478bd9Sstevel@tonic-gate if (len >= PPP_HDRLEN && p[0] == PPP_ALLSTATIONS && p[1] == PPP_UI) { 5407c478bd9Sstevel@tonic-gate p += 2; 5417c478bd9Sstevel@tonic-gate GETSHORT(proto, p); 5427c478bd9Sstevel@tonic-gate len -= PPP_HDRLEN; 5437c478bd9Sstevel@tonic-gate for (i = 0; (protp = protocols[i]) != NULL; ++i) 5447c478bd9Sstevel@tonic-gate if (proto == protp->protocol) 5457c478bd9Sstevel@tonic-gate break; 5467c478bd9Sstevel@tonic-gate if (protp != NULL) { 5477c478bd9Sstevel@tonic-gate printer(arg, "[%s", protp->name); 5487c478bd9Sstevel@tonic-gate n = (*protp->printpkt)(p, len, printer, arg); 5497c478bd9Sstevel@tonic-gate printer(arg, "]"); 5507c478bd9Sstevel@tonic-gate p += n; 5517c478bd9Sstevel@tonic-gate len -= n; 5527c478bd9Sstevel@tonic-gate } else { 5537c478bd9Sstevel@tonic-gate for (i = 0; (protp = protocols[i]) != NULL; ++i) 5547c478bd9Sstevel@tonic-gate if (proto == (protp->protocol & ~0x8000)) 5557c478bd9Sstevel@tonic-gate break; 5567c478bd9Sstevel@tonic-gate if (protp != NULL && protp->data_name != NULL) { 5577c478bd9Sstevel@tonic-gate printer(arg, "[%s data] %8.*B", protp->data_name, len, p); 5587c478bd9Sstevel@tonic-gate len = 0; 5597c478bd9Sstevel@tonic-gate } else 5607c478bd9Sstevel@tonic-gate printer(arg, "[proto=0x%x]", proto); 5617c478bd9Sstevel@tonic-gate } 5627c478bd9Sstevel@tonic-gate } 5637c478bd9Sstevel@tonic-gate 5647c478bd9Sstevel@tonic-gate printer(arg, "%32.*B", len, p); 5657c478bd9Sstevel@tonic-gate } 5667c478bd9Sstevel@tonic-gate 5677c478bd9Sstevel@tonic-gate static void 5687c478bd9Sstevel@tonic-gate pr_log __V((void *arg, const char *fmt, ...)) 5697c478bd9Sstevel@tonic-gate { 5707c478bd9Sstevel@tonic-gate int n; 5717c478bd9Sstevel@tonic-gate va_list pvar; 5727c478bd9Sstevel@tonic-gate char buf[256]; 5737c478bd9Sstevel@tonic-gate 5747c478bd9Sstevel@tonic-gate #if defined(__STDC__) 5757c478bd9Sstevel@tonic-gate va_start(pvar, fmt); 5767c478bd9Sstevel@tonic-gate #else 5777c478bd9Sstevel@tonic-gate void *arg; 5787c478bd9Sstevel@tonic-gate const char *fmt; 5797c478bd9Sstevel@tonic-gate va_start(pvar); 5807c478bd9Sstevel@tonic-gate arg = va_arg(pvar, void *); 5817c478bd9Sstevel@tonic-gate fmt = va_arg(pvar, const char *); 5827c478bd9Sstevel@tonic-gate #endif 5837c478bd9Sstevel@tonic-gate 5847c478bd9Sstevel@tonic-gate n = vslprintf(buf, sizeof(buf), fmt, pvar); 5857c478bd9Sstevel@tonic-gate va_end(pvar); 5867c478bd9Sstevel@tonic-gate 5877c478bd9Sstevel@tonic-gate if (linep + n + 1 > line + sizeof(line)) { 5887c478bd9Sstevel@tonic-gate syslog((int)arg, "%s", line); 5897c478bd9Sstevel@tonic-gate linep = line; 5907c478bd9Sstevel@tonic-gate } 5917c478bd9Sstevel@tonic-gate (void) strlcpy(linep, buf, line + sizeof(line) - linep); 5927c478bd9Sstevel@tonic-gate linep += n; 5937c478bd9Sstevel@tonic-gate } 5947c478bd9Sstevel@tonic-gate 5957c478bd9Sstevel@tonic-gate /* 5967c478bd9Sstevel@tonic-gate * print_string - print a readable representation of a string using 5977c478bd9Sstevel@tonic-gate * printer. 5987c478bd9Sstevel@tonic-gate */ 5997c478bd9Sstevel@tonic-gate void 6007c478bd9Sstevel@tonic-gate print_string(p, len, printer, arg) 6017c478bd9Sstevel@tonic-gate char *p; 6027c478bd9Sstevel@tonic-gate int len; 6037c478bd9Sstevel@tonic-gate void (*printer) __P((void *, const char *, ...)); 6047c478bd9Sstevel@tonic-gate void *arg; 6057c478bd9Sstevel@tonic-gate { 6067c478bd9Sstevel@tonic-gate int c; 6077c478bd9Sstevel@tonic-gate 6087c478bd9Sstevel@tonic-gate printer(arg, "\""); 6097c478bd9Sstevel@tonic-gate for (; len > 0; --len) { 6107c478bd9Sstevel@tonic-gate c = *p++; 6117c478bd9Sstevel@tonic-gate if (isprint(c)) { 6127c478bd9Sstevel@tonic-gate if (c == '\\' || c == '"') 6137c478bd9Sstevel@tonic-gate printer(arg, "\\"); 6147c478bd9Sstevel@tonic-gate printer(arg, "%c", c); 6157c478bd9Sstevel@tonic-gate } else { 6167c478bd9Sstevel@tonic-gate switch (c) { 6177c478bd9Sstevel@tonic-gate case '\n': 6187c478bd9Sstevel@tonic-gate printer(arg, "\\n"); 6197c478bd9Sstevel@tonic-gate break; 6207c478bd9Sstevel@tonic-gate case '\r': 6217c478bd9Sstevel@tonic-gate printer(arg, "\\r"); 6227c478bd9Sstevel@tonic-gate break; 6237c478bd9Sstevel@tonic-gate case '\t': 6247c478bd9Sstevel@tonic-gate printer(arg, "\\t"); 6257c478bd9Sstevel@tonic-gate break; 6267c478bd9Sstevel@tonic-gate default: 6277c478bd9Sstevel@tonic-gate printer(arg, "\\%.3o", c); 6287c478bd9Sstevel@tonic-gate } 6297c478bd9Sstevel@tonic-gate } 6307c478bd9Sstevel@tonic-gate } 6317c478bd9Sstevel@tonic-gate printer(arg, "\""); 6327c478bd9Sstevel@tonic-gate } 6337c478bd9Sstevel@tonic-gate 6347c478bd9Sstevel@tonic-gate /* 6357c478bd9Sstevel@tonic-gate * logit - does the hard work for fatal et al. 6367c478bd9Sstevel@tonic-gate */ 6377c478bd9Sstevel@tonic-gate static void 6387c478bd9Sstevel@tonic-gate logit(level, fmt, args) 6397c478bd9Sstevel@tonic-gate int level; 6407c478bd9Sstevel@tonic-gate const char *fmt; 6417c478bd9Sstevel@tonic-gate va_list args; 6427c478bd9Sstevel@tonic-gate { 6437c478bd9Sstevel@tonic-gate int n; 6447c478bd9Sstevel@tonic-gate char buf[1024]; 6457c478bd9Sstevel@tonic-gate 6467c478bd9Sstevel@tonic-gate n = vslprintf(buf, sizeof(buf), fmt, args); 6477c478bd9Sstevel@tonic-gate syslog(level, "%s", buf); 6487c478bd9Sstevel@tonic-gate if (log_to_fd >= 0 && (level != LOG_DEBUG || debug) && 6497c478bd9Sstevel@tonic-gate (!early_log || log_to_specific_fd)) { 6507c478bd9Sstevel@tonic-gate if (buf[n-1] != '\n') 6517c478bd9Sstevel@tonic-gate buf[n++] = '\n'; 6527c478bd9Sstevel@tonic-gate if (write(log_to_fd, buf, n) != n) 6537c478bd9Sstevel@tonic-gate log_to_fd = -1; 6547c478bd9Sstevel@tonic-gate } 6557c478bd9Sstevel@tonic-gate } 6567c478bd9Sstevel@tonic-gate 6577c478bd9Sstevel@tonic-gate /* 6587c478bd9Sstevel@tonic-gate * fatal - log an error message and die horribly. 6597c478bd9Sstevel@tonic-gate */ 6607c478bd9Sstevel@tonic-gate void 6617c478bd9Sstevel@tonic-gate fatal __V((const char *fmt, ...)) 6627c478bd9Sstevel@tonic-gate { 6637c478bd9Sstevel@tonic-gate va_list pvar; 6647c478bd9Sstevel@tonic-gate 6657c478bd9Sstevel@tonic-gate #if defined(__STDC__) 6667c478bd9Sstevel@tonic-gate va_start(pvar, fmt); 6677c478bd9Sstevel@tonic-gate #else 6687c478bd9Sstevel@tonic-gate const char *fmt; 6697c478bd9Sstevel@tonic-gate va_start(pvar); 6707c478bd9Sstevel@tonic-gate fmt = va_arg(pvar, const char *); 6717c478bd9Sstevel@tonic-gate #endif 6727c478bd9Sstevel@tonic-gate 6737c478bd9Sstevel@tonic-gate logit(LOG_ERR, fmt, pvar); 6747c478bd9Sstevel@tonic-gate va_end(pvar); 6757c478bd9Sstevel@tonic-gate 6767c478bd9Sstevel@tonic-gate die(1); /* as promised */ 6777c478bd9Sstevel@tonic-gate } 6787c478bd9Sstevel@tonic-gate 6797c478bd9Sstevel@tonic-gate /* 6807c478bd9Sstevel@tonic-gate * error - log an error message. 6817c478bd9Sstevel@tonic-gate */ 6827c478bd9Sstevel@tonic-gate void 6837c478bd9Sstevel@tonic-gate error __V((const char *fmt, ...)) 6847c478bd9Sstevel@tonic-gate { 6857c478bd9Sstevel@tonic-gate va_list pvar; 6867c478bd9Sstevel@tonic-gate 6877c478bd9Sstevel@tonic-gate #if defined(__STDC__) 6887c478bd9Sstevel@tonic-gate va_start(pvar, fmt); 6897c478bd9Sstevel@tonic-gate #else 6907c478bd9Sstevel@tonic-gate const char *fmt; 6917c478bd9Sstevel@tonic-gate va_start(pvar); 6927c478bd9Sstevel@tonic-gate fmt = va_arg(pvar, const char *); 6937c478bd9Sstevel@tonic-gate #endif 6947c478bd9Sstevel@tonic-gate 6957c478bd9Sstevel@tonic-gate logit(LOG_ERR, fmt, pvar); 6967c478bd9Sstevel@tonic-gate va_end(pvar); 6977c478bd9Sstevel@tonic-gate } 6987c478bd9Sstevel@tonic-gate 6997c478bd9Sstevel@tonic-gate /* 7007c478bd9Sstevel@tonic-gate * warn - log a warning message. 7017c478bd9Sstevel@tonic-gate */ 7027c478bd9Sstevel@tonic-gate void 7037c478bd9Sstevel@tonic-gate warn __V((const char *fmt, ...)) 7047c478bd9Sstevel@tonic-gate { 7057c478bd9Sstevel@tonic-gate va_list pvar; 7067c478bd9Sstevel@tonic-gate 7077c478bd9Sstevel@tonic-gate #if defined(__STDC__) 7087c478bd9Sstevel@tonic-gate va_start(pvar, fmt); 7097c478bd9Sstevel@tonic-gate #else 7107c478bd9Sstevel@tonic-gate const char *fmt; 7117c478bd9Sstevel@tonic-gate va_start(pvar); 7127c478bd9Sstevel@tonic-gate fmt = va_arg(pvar, const char *); 7137c478bd9Sstevel@tonic-gate #endif 7147c478bd9Sstevel@tonic-gate 7157c478bd9Sstevel@tonic-gate logit(LOG_WARNING, fmt, pvar); 7167c478bd9Sstevel@tonic-gate va_end(pvar); 7177c478bd9Sstevel@tonic-gate } 7187c478bd9Sstevel@tonic-gate 7197c478bd9Sstevel@tonic-gate /* 7207c478bd9Sstevel@tonic-gate * notice - log a notice-level message. 7217c478bd9Sstevel@tonic-gate */ 7227c478bd9Sstevel@tonic-gate void 7237c478bd9Sstevel@tonic-gate notice __V((const char *fmt, ...)) 7247c478bd9Sstevel@tonic-gate { 7257c478bd9Sstevel@tonic-gate va_list pvar; 7267c478bd9Sstevel@tonic-gate 7277c478bd9Sstevel@tonic-gate #if defined(__STDC__) 7287c478bd9Sstevel@tonic-gate va_start(pvar, fmt); 7297c478bd9Sstevel@tonic-gate #else 7307c478bd9Sstevel@tonic-gate const char *fmt; 7317c478bd9Sstevel@tonic-gate va_start(pvar); 7327c478bd9Sstevel@tonic-gate fmt = va_arg(pvar, const char *); 7337c478bd9Sstevel@tonic-gate #endif 7347c478bd9Sstevel@tonic-gate 7357c478bd9Sstevel@tonic-gate logit(LOG_NOTICE, fmt, pvar); 7367c478bd9Sstevel@tonic-gate va_end(pvar); 7377c478bd9Sstevel@tonic-gate } 7387c478bd9Sstevel@tonic-gate 7397c478bd9Sstevel@tonic-gate /* 7407c478bd9Sstevel@tonic-gate * info - log an informational message. 7417c478bd9Sstevel@tonic-gate */ 7427c478bd9Sstevel@tonic-gate void 7437c478bd9Sstevel@tonic-gate info __V((const char *fmt, ...)) 7447c478bd9Sstevel@tonic-gate { 7457c478bd9Sstevel@tonic-gate va_list pvar; 7467c478bd9Sstevel@tonic-gate 7477c478bd9Sstevel@tonic-gate #if defined(__STDC__) 7487c478bd9Sstevel@tonic-gate va_start(pvar, fmt); 7497c478bd9Sstevel@tonic-gate #else 7507c478bd9Sstevel@tonic-gate const char *fmt; 7517c478bd9Sstevel@tonic-gate va_start(pvar); 7527c478bd9Sstevel@tonic-gate fmt = va_arg(pvar, const char *); 7537c478bd9Sstevel@tonic-gate #endif 7547c478bd9Sstevel@tonic-gate 7557c478bd9Sstevel@tonic-gate logit(LOG_INFO, fmt, pvar); 7567c478bd9Sstevel@tonic-gate va_end(pvar); 7577c478bd9Sstevel@tonic-gate } 7587c478bd9Sstevel@tonic-gate 7597c478bd9Sstevel@tonic-gate /* 7607c478bd9Sstevel@tonic-gate * dbglog - log a debug message. 7617c478bd9Sstevel@tonic-gate */ 7627c478bd9Sstevel@tonic-gate void 7637c478bd9Sstevel@tonic-gate dbglog __V((const char *fmt, ...)) 7647c478bd9Sstevel@tonic-gate { 7657c478bd9Sstevel@tonic-gate va_list pvar; 7667c478bd9Sstevel@tonic-gate 7677c478bd9Sstevel@tonic-gate #if defined(__STDC__) 7687c478bd9Sstevel@tonic-gate va_start(pvar, fmt); 7697c478bd9Sstevel@tonic-gate #else 7707c478bd9Sstevel@tonic-gate const char *fmt; 7717c478bd9Sstevel@tonic-gate va_start(pvar); 7727c478bd9Sstevel@tonic-gate fmt = va_arg(pvar, const char *); 7737c478bd9Sstevel@tonic-gate #endif 7747c478bd9Sstevel@tonic-gate 7757c478bd9Sstevel@tonic-gate logit(LOG_DEBUG, fmt, pvar); 7767c478bd9Sstevel@tonic-gate va_end(pvar); 7777c478bd9Sstevel@tonic-gate } 7787c478bd9Sstevel@tonic-gate 7797c478bd9Sstevel@tonic-gate /* 7807c478bd9Sstevel@tonic-gate * Code names for regular PPP messages. Used by LCP and most NCPs, 7817c478bd9Sstevel@tonic-gate * not used by authentication protocols. 7827c478bd9Sstevel@tonic-gate */ 7837c478bd9Sstevel@tonic-gate const char * 7847c478bd9Sstevel@tonic-gate code_name(int code, int shortflag) 7857c478bd9Sstevel@tonic-gate { 7867c478bd9Sstevel@tonic-gate static const char *codelist[] = { 7877c478bd9Sstevel@tonic-gate "Vendor-Extension", "Configure-Request", "Configure-Ack", 7887c478bd9Sstevel@tonic-gate "Configure-Nak", "Configure-Reject", "Terminate-Request", 7897c478bd9Sstevel@tonic-gate "Terminate-Ack", "Code-Reject", "Protocol-Reject", 7907c478bd9Sstevel@tonic-gate "Echo-Request", "Echo-Reply", "Discard-Request", 7917c478bd9Sstevel@tonic-gate "Identification", "Time-Remaining", 7927c478bd9Sstevel@tonic-gate "Reset-Request", "Reset-Ack" 7937c478bd9Sstevel@tonic-gate }; 7947c478bd9Sstevel@tonic-gate static const char *shortcode[] = { 7957c478bd9Sstevel@tonic-gate "VendExt", "ConfReq", "ConfAck", 7967c478bd9Sstevel@tonic-gate "ConfNak", "ConfRej", "TermReq", 7977c478bd9Sstevel@tonic-gate "TermAck", "CodeRej", "ProtRej", 7987c478bd9Sstevel@tonic-gate "EchoReq", "EchoRep", "DiscReq", 7997c478bd9Sstevel@tonic-gate "Ident", "TimeRem", 8007c478bd9Sstevel@tonic-gate "ResetReq", "ResetAck" 8017c478bd9Sstevel@tonic-gate }; 8027c478bd9Sstevel@tonic-gate static char msgbuf[64]; 8037c478bd9Sstevel@tonic-gate 8047c478bd9Sstevel@tonic-gate if (code < 0 || code >= sizeof (codelist) / sizeof (*codelist)) { 8057c478bd9Sstevel@tonic-gate if (shortflag) 8067c478bd9Sstevel@tonic-gate (void) slprintf(msgbuf, sizeof (msgbuf), "Code#%d", code); 8077c478bd9Sstevel@tonic-gate else 8087c478bd9Sstevel@tonic-gate (void) slprintf(msgbuf, sizeof (msgbuf), "unknown code %d", code); 8097c478bd9Sstevel@tonic-gate return ((const char *)msgbuf); 8107c478bd9Sstevel@tonic-gate } 8117c478bd9Sstevel@tonic-gate return (shortflag ? shortcode[code] : codelist[code]); 8127c478bd9Sstevel@tonic-gate } 8137c478bd9Sstevel@tonic-gate 8147c478bd9Sstevel@tonic-gate /* Procedures for locking the serial device using a lock file. */ 8157c478bd9Sstevel@tonic-gate #ifndef LOCK_DIR 8167c478bd9Sstevel@tonic-gate #ifdef _linux_ 8177c478bd9Sstevel@tonic-gate #define LOCK_DIR "/var/lock" 8187c478bd9Sstevel@tonic-gate #else 8197c478bd9Sstevel@tonic-gate #ifdef SVR4 8207c478bd9Sstevel@tonic-gate #define LOCK_DIR "/var/spool/locks" 8217c478bd9Sstevel@tonic-gate #else 8227c478bd9Sstevel@tonic-gate #define LOCK_DIR "/var/spool/lock" 8237c478bd9Sstevel@tonic-gate #endif 8247c478bd9Sstevel@tonic-gate #endif 8257c478bd9Sstevel@tonic-gate #endif /* LOCK_DIR */ 8267c478bd9Sstevel@tonic-gate 8277c478bd9Sstevel@tonic-gate static char lock_file[MAXPATHLEN]; 8287c478bd9Sstevel@tonic-gate 8297c478bd9Sstevel@tonic-gate /* 8307c478bd9Sstevel@tonic-gate * lock - create a lock file for the named device 8317c478bd9Sstevel@tonic-gate */ 8327c478bd9Sstevel@tonic-gate int 8337c478bd9Sstevel@tonic-gate lock(dev) 8347c478bd9Sstevel@tonic-gate char *dev; 8357c478bd9Sstevel@tonic-gate { 8367c478bd9Sstevel@tonic-gate #ifdef LOCKLIB 8377c478bd9Sstevel@tonic-gate int result; 8387c478bd9Sstevel@tonic-gate 8397c478bd9Sstevel@tonic-gate result = mklock (dev, (void *) 0); 8407c478bd9Sstevel@tonic-gate if (result == 0) { 8417c478bd9Sstevel@tonic-gate (void) strlcpy(lock_file, sizeof(lock_file), dev); 8427c478bd9Sstevel@tonic-gate return (0); 8437c478bd9Sstevel@tonic-gate } 8447c478bd9Sstevel@tonic-gate 8457c478bd9Sstevel@tonic-gate if (result > 0) 8467c478bd9Sstevel@tonic-gate notice("Device %s is locked by pid %d", dev, result); 8477c478bd9Sstevel@tonic-gate else 8487c478bd9Sstevel@tonic-gate error("Can't create lock file %s", lock_file); 8497c478bd9Sstevel@tonic-gate return (-1); 8507c478bd9Sstevel@tonic-gate 8517c478bd9Sstevel@tonic-gate #else /* LOCKLIB */ 8527c478bd9Sstevel@tonic-gate 8537c478bd9Sstevel@tonic-gate char lock_buffer[12]; 8547c478bd9Sstevel@tonic-gate int fd, pid, n; 8557c478bd9Sstevel@tonic-gate 8567c478bd9Sstevel@tonic-gate #ifdef SVR4 8577c478bd9Sstevel@tonic-gate struct stat sbuf; 8587c478bd9Sstevel@tonic-gate 8597c478bd9Sstevel@tonic-gate if (stat(dev, &sbuf) < 0) { 8607c478bd9Sstevel@tonic-gate error("Can't get device number for %s: %m", dev); 8617c478bd9Sstevel@tonic-gate return (-1); 8627c478bd9Sstevel@tonic-gate } 8637c478bd9Sstevel@tonic-gate if ((sbuf.st_mode & S_IFMT) != S_IFCHR) { 8647c478bd9Sstevel@tonic-gate error("Can't lock %s: not a character device", dev); 8657c478bd9Sstevel@tonic-gate return (-1); 8667c478bd9Sstevel@tonic-gate } 8677c478bd9Sstevel@tonic-gate (void) slprintf(lock_file, sizeof(lock_file), "%s/LK.%03d.%03d.%03d", 8687c478bd9Sstevel@tonic-gate LOCK_DIR, major(sbuf.st_dev), 8697c478bd9Sstevel@tonic-gate major(sbuf.st_rdev), minor(sbuf.st_rdev)); 8707c478bd9Sstevel@tonic-gate #else 8717c478bd9Sstevel@tonic-gate char *p; 8727c478bd9Sstevel@tonic-gate 8737c478bd9Sstevel@tonic-gate if ((p = strrchr(dev, '/')) != NULL) 8747c478bd9Sstevel@tonic-gate dev = p + 1; 8757c478bd9Sstevel@tonic-gate (void) slprintf(lock_file, sizeof(lock_file), "%s/LCK..%s", LOCK_DIR, dev); 8767c478bd9Sstevel@tonic-gate #endif 8777c478bd9Sstevel@tonic-gate 8787c478bd9Sstevel@tonic-gate while ((fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644)) < 0) { 8797c478bd9Sstevel@tonic-gate if (errno != EEXIST) { 8807c478bd9Sstevel@tonic-gate error("Can't create lock file %s: %m", lock_file); 8817c478bd9Sstevel@tonic-gate break; 8827c478bd9Sstevel@tonic-gate } 8837c478bd9Sstevel@tonic-gate 8847c478bd9Sstevel@tonic-gate /* Read the lock file to find out who has the device locked. */ 8857c478bd9Sstevel@tonic-gate fd = open(lock_file, O_RDONLY, 0); 8867c478bd9Sstevel@tonic-gate if (fd < 0) { 8877c478bd9Sstevel@tonic-gate if (errno == ENOENT) /* This is just a timing problem. */ 8887c478bd9Sstevel@tonic-gate continue; 8897c478bd9Sstevel@tonic-gate error("Can't open existing lock file %s: %m", lock_file); 8907c478bd9Sstevel@tonic-gate break; 8917c478bd9Sstevel@tonic-gate } 8927c478bd9Sstevel@tonic-gate #ifndef LOCK_BINARY 8937c478bd9Sstevel@tonic-gate n = read(fd, lock_buffer, 11); 8947c478bd9Sstevel@tonic-gate #else 8957c478bd9Sstevel@tonic-gate n = read(fd, &pid, sizeof(pid)); 8967c478bd9Sstevel@tonic-gate #endif /* LOCK_BINARY */ 8977c478bd9Sstevel@tonic-gate (void) close(fd); 8987c478bd9Sstevel@tonic-gate fd = -1; 8997c478bd9Sstevel@tonic-gate if (n <= 0) { 9007c478bd9Sstevel@tonic-gate error("Can't read pid from lock file %s", lock_file); 9017c478bd9Sstevel@tonic-gate break; 9027c478bd9Sstevel@tonic-gate } 9037c478bd9Sstevel@tonic-gate 9047c478bd9Sstevel@tonic-gate /* See if the process still exists. */ 9057c478bd9Sstevel@tonic-gate #ifndef LOCK_BINARY 9067c478bd9Sstevel@tonic-gate lock_buffer[n] = 0; 9077c478bd9Sstevel@tonic-gate pid = atoi(lock_buffer); 9087c478bd9Sstevel@tonic-gate #endif /* LOCK_BINARY */ 9097c478bd9Sstevel@tonic-gate if (pid == getpid()) 9107c478bd9Sstevel@tonic-gate return (1); /* somebody else locked it for us */ 9117c478bd9Sstevel@tonic-gate if (pid == 0 9127c478bd9Sstevel@tonic-gate || (kill(pid, 0) == -1 && errno == ESRCH)) { 9137c478bd9Sstevel@tonic-gate if (unlink (lock_file) == 0) { 9147c478bd9Sstevel@tonic-gate notice("Removed stale lock on %s (pid %d)", dev, pid); 9157c478bd9Sstevel@tonic-gate continue; 9167c478bd9Sstevel@tonic-gate } 9177c478bd9Sstevel@tonic-gate warn("Couldn't remove stale lock on %s", dev); 9187c478bd9Sstevel@tonic-gate } else 9197c478bd9Sstevel@tonic-gate notice("Device %s is locked by pid %d", dev, pid); 9207c478bd9Sstevel@tonic-gate break; 9217c478bd9Sstevel@tonic-gate } 9227c478bd9Sstevel@tonic-gate 9237c478bd9Sstevel@tonic-gate if (fd < 0) { 9247c478bd9Sstevel@tonic-gate lock_file[0] = 0; 9257c478bd9Sstevel@tonic-gate return (-1); 9267c478bd9Sstevel@tonic-gate } 9277c478bd9Sstevel@tonic-gate 9287c478bd9Sstevel@tonic-gate pid = getpid(); 9297c478bd9Sstevel@tonic-gate #ifndef LOCK_BINARY 9307c478bd9Sstevel@tonic-gate (void) slprintf(lock_buffer, sizeof(lock_buffer), "%10d\n", pid); 9317c478bd9Sstevel@tonic-gate (void) write (fd, lock_buffer, 11); 9327c478bd9Sstevel@tonic-gate #else 9337c478bd9Sstevel@tonic-gate (void) write(fd, &pid, sizeof (pid)); 9347c478bd9Sstevel@tonic-gate #endif 9357c478bd9Sstevel@tonic-gate (void) close(fd); 9367c478bd9Sstevel@tonic-gate return (0); 9377c478bd9Sstevel@tonic-gate 9387c478bd9Sstevel@tonic-gate #endif 9397c478bd9Sstevel@tonic-gate } 9407c478bd9Sstevel@tonic-gate 9417c478bd9Sstevel@tonic-gate /* 9427c478bd9Sstevel@tonic-gate * relock - called to update our lockfile when we are about to detach, 9437c478bd9Sstevel@tonic-gate * thus changing our pid (we fork, the child carries on, and the parent dies). 9447c478bd9Sstevel@tonic-gate * Note that this is called by the parent, with pid equal to the pid 9457c478bd9Sstevel@tonic-gate * of the child. This avoids a potential race which would exist if 9467c478bd9Sstevel@tonic-gate * we had the child rewrite the lockfile (the parent might die first, 9477c478bd9Sstevel@tonic-gate * and another process could think the lock was stale if it checked 9487c478bd9Sstevel@tonic-gate * between when the parent died and the child rewrote the lockfile). 9497c478bd9Sstevel@tonic-gate */ 9507c478bd9Sstevel@tonic-gate int 9517c478bd9Sstevel@tonic-gate relock(pid) 9527c478bd9Sstevel@tonic-gate int pid; 9537c478bd9Sstevel@tonic-gate { 9547c478bd9Sstevel@tonic-gate #ifdef LOCKLIB 9557c478bd9Sstevel@tonic-gate /* XXX is there a way to do this? */ 9567c478bd9Sstevel@tonic-gate return (-1); 9577c478bd9Sstevel@tonic-gate #else /* LOCKLIB */ 9587c478bd9Sstevel@tonic-gate 9597c478bd9Sstevel@tonic-gate int fd; 9607c478bd9Sstevel@tonic-gate char lock_buffer[12]; 9617c478bd9Sstevel@tonic-gate 9627c478bd9Sstevel@tonic-gate if (lock_file[0] == 0) 9637c478bd9Sstevel@tonic-gate return (-1); 9647c478bd9Sstevel@tonic-gate fd = open(lock_file, O_WRONLY, 0); 9657c478bd9Sstevel@tonic-gate if (fd < 0) { 9667c478bd9Sstevel@tonic-gate error("Couldn't reopen lock file %s: %m", lock_file); 9677c478bd9Sstevel@tonic-gate lock_file[0] = 0; 9687c478bd9Sstevel@tonic-gate return (-1); 9697c478bd9Sstevel@tonic-gate } 9707c478bd9Sstevel@tonic-gate 9717c478bd9Sstevel@tonic-gate #ifndef LOCK_BINARY 9727c478bd9Sstevel@tonic-gate (void) slprintf(lock_buffer, sizeof(lock_buffer), "%10d\n", pid); 9737c478bd9Sstevel@tonic-gate (void) write (fd, lock_buffer, 11); 9747c478bd9Sstevel@tonic-gate #else 9757c478bd9Sstevel@tonic-gate (void) write(fd, &pid, sizeof(pid)); 9767c478bd9Sstevel@tonic-gate #endif /* LOCK_BINARY */ 9777c478bd9Sstevel@tonic-gate (void) close(fd); 9787c478bd9Sstevel@tonic-gate return (0); 9797c478bd9Sstevel@tonic-gate 9807c478bd9Sstevel@tonic-gate #endif /* LOCKLIB */ 9817c478bd9Sstevel@tonic-gate } 9827c478bd9Sstevel@tonic-gate 9837c478bd9Sstevel@tonic-gate /* 9847c478bd9Sstevel@tonic-gate * unlock - remove our lockfile 9857c478bd9Sstevel@tonic-gate */ 9867c478bd9Sstevel@tonic-gate void 9877c478bd9Sstevel@tonic-gate unlock() 9887c478bd9Sstevel@tonic-gate { 9897c478bd9Sstevel@tonic-gate if (lock_file[0]) { 9907c478bd9Sstevel@tonic-gate #ifdef LOCKLIB 9917c478bd9Sstevel@tonic-gate (void) rmlock(lock_file, (void *) 0); 9927c478bd9Sstevel@tonic-gate #else 9937c478bd9Sstevel@tonic-gate (void) unlink(lock_file); 9947c478bd9Sstevel@tonic-gate #endif 9957c478bd9Sstevel@tonic-gate lock_file[0] = 0; 9967c478bd9Sstevel@tonic-gate } 9977c478bd9Sstevel@tonic-gate } 9987c478bd9Sstevel@tonic-gate 9997c478bd9Sstevel@tonic-gate const char * 10007c478bd9Sstevel@tonic-gate signal_name(int signum) 10017c478bd9Sstevel@tonic-gate { 10027c478bd9Sstevel@tonic-gate #if defined(SOL2) || defined(__linux__) || defined(_linux_) 10037c478bd9Sstevel@tonic-gate const char *cp; 10047c478bd9Sstevel@tonic-gate 10057c478bd9Sstevel@tonic-gate if ((cp = strsignal(signum)) != NULL) 10067c478bd9Sstevel@tonic-gate return (cp); 10077c478bd9Sstevel@tonic-gate #else 10087c478bd9Sstevel@tonic-gate extern char *sys_siglist[]; 10097c478bd9Sstevel@tonic-gate extern int sys_nsig; 10107c478bd9Sstevel@tonic-gate 10117c478bd9Sstevel@tonic-gate if (signum >= 0 && signum < sys_nsig && sys_siglist[signum] != NULL) 10127c478bd9Sstevel@tonic-gate return (sys_siglist[signum]); 10137c478bd9Sstevel@tonic-gate #endif 10147c478bd9Sstevel@tonic-gate return ("??"); 10157c478bd9Sstevel@tonic-gate } 1016