11ae349f5Scvs2svn /*- 21ae349f5Scvs2svn * Copyright (c) 1997 Brian Somers <brian@Awfulhak.org> 31ae349f5Scvs2svn * All rights reserved. 41ae349f5Scvs2svn * 51ae349f5Scvs2svn * Redistribution and use in source and binary forms, with or without 61ae349f5Scvs2svn * modification, are permitted provided that the following conditions 71ae349f5Scvs2svn * are met: 81ae349f5Scvs2svn * 1. Redistributions of source code must retain the above copyright 91ae349f5Scvs2svn * notice, this list of conditions and the following disclaimer. 101ae349f5Scvs2svn * 2. Redistributions in binary form must reproduce the above copyright 111ae349f5Scvs2svn * notice, this list of conditions and the following disclaimer in the 121ae349f5Scvs2svn * documentation and/or other materials provided with the distribution. 131ae349f5Scvs2svn * 141ae349f5Scvs2svn * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 151ae349f5Scvs2svn * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 161ae349f5Scvs2svn * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 171ae349f5Scvs2svn * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 181ae349f5Scvs2svn * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 191ae349f5Scvs2svn * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 201ae349f5Scvs2svn * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 211ae349f5Scvs2svn * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 221ae349f5Scvs2svn * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 231ae349f5Scvs2svn * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 241ae349f5Scvs2svn * SUCH DAMAGE. 251ae349f5Scvs2svn * 26d47dceb8SBrian Somers * $Id: log.c,v 1.25.2.8 1998/04/14 23:17:08 brian Exp $ 271ae349f5Scvs2svn */ 281ae349f5Scvs2svn 292764b86aSBrian Somers #include <sys/types.h> 301ae349f5Scvs2svn 311ae349f5Scvs2svn #include <stdarg.h> 321ae349f5Scvs2svn #include <stdio.h> 33b6217683SBrian Somers #include <string.h> 341ae349f5Scvs2svn #include <syslog.h> 3585b542cfSBrian Somers #include <termios.h> 361ae349f5Scvs2svn 371ae349f5Scvs2svn #include "command.h" 381ae349f5Scvs2svn #include "mbuf.h" 391ae349f5Scvs2svn #include "log.h" 4085b542cfSBrian Somers #include "descriptor.h" 4185b542cfSBrian Somers #include "prompt.h" 421ae349f5Scvs2svn 431ae349f5Scvs2svn static const char *LogNames[] = { 441ae349f5Scvs2svn "Async", 451ae349f5Scvs2svn "Carrier", 461ae349f5Scvs2svn "CCP", 471ae349f5Scvs2svn "Chat", 481ae349f5Scvs2svn "Command", 491ae349f5Scvs2svn "Connect", 501ae349f5Scvs2svn "Debug", 511ae349f5Scvs2svn "HDLC", 521ae349f5Scvs2svn "ID0", 531ae349f5Scvs2svn "IPCP", 541ae349f5Scvs2svn "LCP", 551ae349f5Scvs2svn "Link", 561ae349f5Scvs2svn "LQM", 571ae349f5Scvs2svn "Phase", 581ae349f5Scvs2svn "TCP/IP", 591ae349f5Scvs2svn "Tun", 601ae349f5Scvs2svn "Warning", 611ae349f5Scvs2svn "Error", 621ae349f5Scvs2svn "Alert" 631ae349f5Scvs2svn }; 641ae349f5Scvs2svn 651ae349f5Scvs2svn #define MSK(n) (1<<((n)-1)) 661ae349f5Scvs2svn 67d47dceb8SBrian Somers static u_long LogMask = MSK(LogPHASE); 681ae349f5Scvs2svn static u_long LogMaskLocal = MSK(LogERROR) | MSK(LogALERT) | MSK(LogWARN); 691ae349f5Scvs2svn static int LogTunno = -1; 70b6217683SBrian Somers static struct prompt *logprompt; /* Where to log local stuff */ 71b6217683SBrian Somers 72b6217683SBrian Somers void 73b6217683SBrian Somers log_RegisterPrompt(struct prompt *prompt) 74b6217683SBrian Somers { 75b6217683SBrian Somers if (prompt) { 76b6217683SBrian Somers prompt->lognext = logprompt; 77b6217683SBrian Somers logprompt = prompt; 78b6217683SBrian Somers LogMaskLocal |= prompt->logmask; 79b6217683SBrian Somers } 80b6217683SBrian Somers } 81b6217683SBrian Somers 8267568487SBrian Somers static void 8367568487SBrian Somers LogSetMaskLocal(void) 8467568487SBrian Somers { 8567568487SBrian Somers struct prompt *p; 8667568487SBrian Somers 8767568487SBrian Somers LogMaskLocal = MSK(LogERROR) | MSK(LogALERT) | MSK(LogWARN); 8867568487SBrian Somers for (p = logprompt; p; p = p->lognext) 8967568487SBrian Somers LogMaskLocal |= p->logmask; 9067568487SBrian Somers } 9167568487SBrian Somers 92b6217683SBrian Somers void 93b6217683SBrian Somers log_UnRegisterPrompt(struct prompt *prompt) 94b6217683SBrian Somers { 95b6217683SBrian Somers if (prompt) { 96b6217683SBrian Somers struct prompt **p; 97b6217683SBrian Somers 9867568487SBrian Somers for (p = &logprompt; *p; p = &(*p)->lognext) 99b6217683SBrian Somers if (*p == prompt) { 10067568487SBrian Somers *p = prompt->lognext; 101b6217683SBrian Somers prompt->lognext = NULL; 102b6217683SBrian Somers break; 103b6217683SBrian Somers } 10467568487SBrian Somers LogSetMaskLocal(); 105b6217683SBrian Somers } 106b6217683SBrian Somers } 1071ae349f5Scvs2svn 1081ae349f5Scvs2svn static int 1091ae349f5Scvs2svn syslogLevel(int lev) 1101ae349f5Scvs2svn { 1111ae349f5Scvs2svn switch (lev) { 1121ae349f5Scvs2svn case LogDEBUG:return LOG_DEBUG; 1131ae349f5Scvs2svn case LogWARN: 1141ae349f5Scvs2svn return LOG_WARNING; 1151ae349f5Scvs2svn case LogERROR: 1161ae349f5Scvs2svn return LOG_ERR; 1171ae349f5Scvs2svn case LogALERT: 1181ae349f5Scvs2svn return LOG_ALERT; 1191ae349f5Scvs2svn } 1201ae349f5Scvs2svn return lev >= LogMIN && lev <= LogMAX ? LOG_INFO : 0; 1211ae349f5Scvs2svn } 1221ae349f5Scvs2svn 1231ae349f5Scvs2svn const char * 1241ae349f5Scvs2svn LogName(int id) 1251ae349f5Scvs2svn { 1261ae349f5Scvs2svn return id < LogMIN || id > LogMAX ? "Unknown" : LogNames[id - 1]; 1271ae349f5Scvs2svn } 1281ae349f5Scvs2svn 1291ae349f5Scvs2svn void 1301ae349f5Scvs2svn LogKeep(int id) 1311ae349f5Scvs2svn { 1321ae349f5Scvs2svn if (id >= LogMIN && id <= LogMAXCONF) 1331ae349f5Scvs2svn LogMask |= MSK(id); 1341ae349f5Scvs2svn } 1351ae349f5Scvs2svn 1361ae349f5Scvs2svn void 137b6217683SBrian Somers LogKeepLocal(int id, u_long *mask) 1381ae349f5Scvs2svn { 139b6217683SBrian Somers if (id >= LogMIN && id <= LogMAXCONF) { 1401ae349f5Scvs2svn LogMaskLocal |= MSK(id); 141b6217683SBrian Somers *mask |= MSK(id); 142b6217683SBrian Somers } 1431ae349f5Scvs2svn } 1441ae349f5Scvs2svn 1451ae349f5Scvs2svn void 1461ae349f5Scvs2svn LogDiscard(int id) 1471ae349f5Scvs2svn { 1481ae349f5Scvs2svn if (id >= LogMIN && id <= LogMAXCONF) 1491ae349f5Scvs2svn LogMask &= ~MSK(id); 1501ae349f5Scvs2svn } 1511ae349f5Scvs2svn 1521ae349f5Scvs2svn void 153b6217683SBrian Somers LogDiscardLocal(int id, u_long *mask) 1541ae349f5Scvs2svn { 155b6217683SBrian Somers if (id >= LogMIN && id <= LogMAXCONF) { 156b6217683SBrian Somers *mask &= ~MSK(id); 15767568487SBrian Somers LogSetMaskLocal(); 158b6217683SBrian Somers } 1591ae349f5Scvs2svn } 1601ae349f5Scvs2svn 1611ae349f5Scvs2svn void 1621ae349f5Scvs2svn LogDiscardAll() 1631ae349f5Scvs2svn { 1641ae349f5Scvs2svn LogMask = 0; 1651ae349f5Scvs2svn } 1661ae349f5Scvs2svn 1671ae349f5Scvs2svn void 168b6217683SBrian Somers LogDiscardAllLocal(u_long *mask) 1691ae349f5Scvs2svn { 17067568487SBrian Somers *mask = MSK(LogERROR) | MSK(LogALERT) | MSK(LogWARN); 17167568487SBrian Somers LogSetMaskLocal(); 1721ae349f5Scvs2svn } 1731ae349f5Scvs2svn 1741ae349f5Scvs2svn int 1751ae349f5Scvs2svn LogIsKept(int id) 1761ae349f5Scvs2svn { 1771ae349f5Scvs2svn if (id < LogMIN || id > LogMAX) 1781ae349f5Scvs2svn return 0; 1791ae349f5Scvs2svn if (id > LogMAXCONF) 1801ae349f5Scvs2svn return LOG_KEPT_LOCAL | LOG_KEPT_SYSLOG; 1811ae349f5Scvs2svn 1821ae349f5Scvs2svn return ((LogMaskLocal & MSK(id)) ? LOG_KEPT_LOCAL : 0) | 1831ae349f5Scvs2svn ((LogMask & MSK(id)) ? LOG_KEPT_SYSLOG : 0); 1841ae349f5Scvs2svn } 1851ae349f5Scvs2svn 186b6217683SBrian Somers int 187b6217683SBrian Somers LogIsKeptLocal(int id, u_long mask) 188b6217683SBrian Somers { 189b6217683SBrian Somers if (id < LogMIN || id > LogMAX) 190b6217683SBrian Somers return 0; 191b6217683SBrian Somers if (id > LogMAXCONF) 192b6217683SBrian Somers return LOG_KEPT_LOCAL | LOG_KEPT_SYSLOG; 193b6217683SBrian Somers 194b6217683SBrian Somers return ((mask & MSK(id)) ? LOG_KEPT_LOCAL : 0) | 195b6217683SBrian Somers ((LogMask & MSK(id)) ? LOG_KEPT_SYSLOG : 0); 196b6217683SBrian Somers } 197b6217683SBrian Somers 1981ae349f5Scvs2svn void 1991ae349f5Scvs2svn LogOpen(const char *Name) 2001ae349f5Scvs2svn { 2011ae349f5Scvs2svn openlog(Name, LOG_PID, LOG_DAEMON); 2021ae349f5Scvs2svn } 2031ae349f5Scvs2svn 2041ae349f5Scvs2svn void 2051ae349f5Scvs2svn LogSetTun(int tunno) 2061ae349f5Scvs2svn { 2071ae349f5Scvs2svn LogTunno = tunno; 2081ae349f5Scvs2svn } 2091ae349f5Scvs2svn 2101ae349f5Scvs2svn void 2111ae349f5Scvs2svn LogClose() 2121ae349f5Scvs2svn { 2131ae349f5Scvs2svn closelog(); 2141ae349f5Scvs2svn LogTunno = -1; 2151ae349f5Scvs2svn } 2161ae349f5Scvs2svn 2171ae349f5Scvs2svn void 2181ae349f5Scvs2svn LogPrintf(int lev, const char *fmt,...) 2191ae349f5Scvs2svn { 2201ae349f5Scvs2svn va_list ap; 221b6217683SBrian Somers struct prompt *prompt; 2221ae349f5Scvs2svn 2231ae349f5Scvs2svn va_start(ap, fmt); 2241ae349f5Scvs2svn if (LogIsKept(lev)) { 2251ae349f5Scvs2svn static char nfmt[200]; 2261ae349f5Scvs2svn 227b6217683SBrian Somers if ((LogIsKept(lev) & LOG_KEPT_LOCAL) && logprompt) { 2281ae349f5Scvs2svn if ((LogIsKept(LogTUN) & LOG_KEPT_LOCAL) && LogTunno != -1) 2291ae349f5Scvs2svn snprintf(nfmt, sizeof nfmt, "tun%d: %s: %s", 2301ae349f5Scvs2svn LogTunno, LogName(lev), fmt); 2311ae349f5Scvs2svn else 2321ae349f5Scvs2svn snprintf(nfmt, sizeof nfmt, "%s: %s", LogName(lev), fmt); 233b6217683SBrian Somers 234b6217683SBrian Somers for (prompt = logprompt; prompt; prompt = prompt->lognext) 235b6217683SBrian Somers if (lev > LogMAXCONF || (prompt->logmask & MSK(lev))) 236b6217683SBrian Somers prompt_vPrintf(prompt, nfmt, ap); 2371ae349f5Scvs2svn } 2381ae349f5Scvs2svn 239b6217683SBrian Somers if ((LogIsKept(lev) & LOG_KEPT_SYSLOG) && (lev != LogWARN || !logprompt)) { 2401ae349f5Scvs2svn if ((LogIsKept(LogTUN) & LOG_KEPT_SYSLOG) && LogTunno != -1) 2411ae349f5Scvs2svn snprintf(nfmt, sizeof nfmt, "tun%d: %s: %s", 2421ae349f5Scvs2svn LogTunno, LogName(lev), fmt); 2431ae349f5Scvs2svn else 2441ae349f5Scvs2svn snprintf(nfmt, sizeof nfmt, "%s: %s", LogName(lev), fmt); 2451ae349f5Scvs2svn vsyslog(syslogLevel(lev), nfmt, ap); 2461ae349f5Scvs2svn } 2471ae349f5Scvs2svn } 2481ae349f5Scvs2svn va_end(ap); 2491ae349f5Scvs2svn } 2501ae349f5Scvs2svn 2511ae349f5Scvs2svn void 2521ae349f5Scvs2svn LogDumpBp(int lev, const char *hdr, const struct mbuf * bp) 2531ae349f5Scvs2svn { 2541ae349f5Scvs2svn if (LogIsKept(lev)) { 2551ae349f5Scvs2svn char buf[50]; 2561ae349f5Scvs2svn char *b; 2571ae349f5Scvs2svn u_char *ptr; 2581ae349f5Scvs2svn int f; 2591ae349f5Scvs2svn 2601ae349f5Scvs2svn if (hdr && *hdr) 2611ae349f5Scvs2svn LogPrintf(lev, "%s\n", hdr); 2621ae349f5Scvs2svn 2631ae349f5Scvs2svn b = buf; 2641ae349f5Scvs2svn do { 2651ae349f5Scvs2svn f = bp->cnt; 2661ae349f5Scvs2svn ptr = MBUF_CTOP(bp); 2671ae349f5Scvs2svn while (f--) { 2681ae349f5Scvs2svn sprintf(b, " %02x", (int) *ptr++); 2691ae349f5Scvs2svn b += 3; 2701ae349f5Scvs2svn if (b == buf + sizeof buf - 2) { 2711ae349f5Scvs2svn strcpy(b, "\n"); 2721ae349f5Scvs2svn LogPrintf(lev, buf); 2731ae349f5Scvs2svn b = buf; 2741ae349f5Scvs2svn } 2751ae349f5Scvs2svn } 2761ae349f5Scvs2svn } while ((bp = bp->next) != NULL); 2771ae349f5Scvs2svn 2781ae349f5Scvs2svn if (b > buf) { 2791ae349f5Scvs2svn strcpy(b, "\n"); 2801ae349f5Scvs2svn LogPrintf(lev, buf); 2811ae349f5Scvs2svn } 2821ae349f5Scvs2svn } 2831ae349f5Scvs2svn } 2841ae349f5Scvs2svn 2851ae349f5Scvs2svn void 2861ae349f5Scvs2svn LogDumpBuff(int lev, const char *hdr, const u_char * ptr, int n) 2871ae349f5Scvs2svn { 2881ae349f5Scvs2svn if (LogIsKept(lev)) { 2891ae349f5Scvs2svn char buf[50]; 2901ae349f5Scvs2svn char *b; 2911ae349f5Scvs2svn 2921ae349f5Scvs2svn if (hdr && *hdr) 2931ae349f5Scvs2svn LogPrintf(lev, "%s\n", hdr); 2941ae349f5Scvs2svn while (n > 0) { 2951ae349f5Scvs2svn b = buf; 2961ae349f5Scvs2svn for (b = buf; b != buf + sizeof buf - 2 && n--; b += 3) 2971ae349f5Scvs2svn sprintf(b, " %02x", (int) *ptr++); 2981ae349f5Scvs2svn strcpy(b, "\n"); 2991ae349f5Scvs2svn LogPrintf(lev, buf); 3001ae349f5Scvs2svn } 3011ae349f5Scvs2svn } 3021ae349f5Scvs2svn } 303b6217683SBrian Somers 304b6217683SBrian Somers int 305b6217683SBrian Somers log_ShowLevel(struct cmdargs const *arg) 306b6217683SBrian Somers { 307b6217683SBrian Somers int i; 308b6217683SBrian Somers 309b6217683SBrian Somers prompt_Printf(arg->prompt, "Log: "); 310b6217683SBrian Somers for (i = LogMIN; i <= LogMAX; i++) 311b6217683SBrian Somers if (LogIsKept(i) & LOG_KEPT_SYSLOG) 312b6217683SBrian Somers prompt_Printf(arg->prompt, " %s", LogName(i)); 313b6217683SBrian Somers 314b6217683SBrian Somers prompt_Printf(arg->prompt, "\nLocal:"); 315b6217683SBrian Somers for (i = LogMIN; i <= LogMAX; i++) 316b6217683SBrian Somers if (LogIsKeptLocal(i, arg->prompt->logmask) & LOG_KEPT_LOCAL) 317b6217683SBrian Somers prompt_Printf(arg->prompt, " %s", LogName(i)); 318b6217683SBrian Somers 319b6217683SBrian Somers prompt_Printf(arg->prompt, "\n"); 320b6217683SBrian Somers 321b6217683SBrian Somers return 0; 322b6217683SBrian Somers } 323b6217683SBrian Somers 324b6217683SBrian Somers int 325b6217683SBrian Somers log_SetLevel(struct cmdargs const *arg) 326b6217683SBrian Somers { 327b6217683SBrian Somers int i, res, argc, local; 328b6217683SBrian Somers char const *const *argv, *argp; 329b6217683SBrian Somers 33025092092SBrian Somers argc = arg->argc - arg->argn; 33125092092SBrian Somers argv = arg->argv + arg->argn; 332b6217683SBrian Somers res = 0; 333b6217683SBrian Somers 334b6217683SBrian Somers if (argc == 0 || strcasecmp(argv[0], "local")) 335b6217683SBrian Somers local = 0; 336b6217683SBrian Somers else { 337b6217683SBrian Somers if (arg->prompt == NULL) { 338b6217683SBrian Somers LogPrintf(LogWARN, "set log local: Only available on the command line\n"); 339b6217683SBrian Somers return 1; 340b6217683SBrian Somers } 341b6217683SBrian Somers argc--; 342b6217683SBrian Somers argv++; 343b6217683SBrian Somers local = 1; 344b6217683SBrian Somers } 345b6217683SBrian Somers 346b6217683SBrian Somers if (argc == 0 || (argv[0][0] != '+' && argv[0][0] != '-')) 347b6217683SBrian Somers if (local) 348b6217683SBrian Somers LogDiscardAllLocal(&arg->prompt->logmask); 349b6217683SBrian Somers else 350b6217683SBrian Somers LogDiscardAll(); 351b6217683SBrian Somers 352b6217683SBrian Somers while (argc--) { 353b6217683SBrian Somers argp = **argv == '+' || **argv == '-' ? *argv + 1 : *argv; 354b6217683SBrian Somers for (i = LogMIN; i <= LogMAX; i++) 355b6217683SBrian Somers if (strcasecmp(argp, LogName(i)) == 0) { 356b6217683SBrian Somers if (**argv == '-') 357b6217683SBrian Somers if (local) 358b6217683SBrian Somers LogDiscardLocal(i, &arg->prompt->logmask); 359b6217683SBrian Somers else 360b6217683SBrian Somers LogDiscard(i); 361b6217683SBrian Somers else if (local) 362b6217683SBrian Somers LogKeepLocal(i, &arg->prompt->logmask); 363b6217683SBrian Somers else 364b6217683SBrian Somers LogKeep(i); 365b6217683SBrian Somers break; 366b6217683SBrian Somers } 367b6217683SBrian Somers if (i > LogMAX) { 368b6217683SBrian Somers LogPrintf(LogWARN, "%s: Invalid log value\n", argp); 369b6217683SBrian Somers res = -1; 370b6217683SBrian Somers } 371b6217683SBrian Somers argv++; 372b6217683SBrian Somers } 373b6217683SBrian Somers return res; 374b6217683SBrian Somers } 375b6217683SBrian Somers 376b6217683SBrian Somers int 377b6217683SBrian Somers log_ShowWho(struct cmdargs const *arg) 378b6217683SBrian Somers { 379b6217683SBrian Somers struct prompt *p; 380b6217683SBrian Somers 381f91ad6b0SBrian Somers for (p = logprompt; p; p = p->lognext) { 382565e35e5SBrian Somers prompt_Printf(arg->prompt, "%s (%s)", p->src.type, p->src.from); 383f91ad6b0SBrian Somers if (p == arg->prompt) 384f91ad6b0SBrian Somers prompt_Printf(arg->prompt, " *"); 385f91ad6b0SBrian Somers if (!p->active) 386f91ad6b0SBrian Somers prompt_Printf(arg->prompt, " ^Z"); 387f91ad6b0SBrian Somers prompt_Printf(arg->prompt, "\n"); 388f91ad6b0SBrian Somers } 389b6217683SBrian Somers 390b6217683SBrian Somers return 0; 391b6217683SBrian Somers } 392