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 * 26e43ebac1SBrian Somers * $Id: log.c,v 1.25.2.10 1998/04/24 19:16:05 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 "CCP", 461ae349f5Scvs2svn "Chat", 471ae349f5Scvs2svn "Command", 481ae349f5Scvs2svn "Connect", 491ae349f5Scvs2svn "Debug", 501ae349f5Scvs2svn "HDLC", 511ae349f5Scvs2svn "ID0", 521ae349f5Scvs2svn "IPCP", 531ae349f5Scvs2svn "LCP", 541ae349f5Scvs2svn "LQM", 551ae349f5Scvs2svn "Phase", 561ae349f5Scvs2svn "TCP/IP", 571ae349f5Scvs2svn "Tun", 581ae349f5Scvs2svn "Warning", 591ae349f5Scvs2svn "Error", 601ae349f5Scvs2svn "Alert" 611ae349f5Scvs2svn }; 621ae349f5Scvs2svn 631ae349f5Scvs2svn #define MSK(n) (1<<((n)-1)) 641ae349f5Scvs2svn 65d47dceb8SBrian Somers static u_long LogMask = MSK(LogPHASE); 661ae349f5Scvs2svn static u_long LogMaskLocal = MSK(LogERROR) | MSK(LogALERT) | MSK(LogWARN); 671ae349f5Scvs2svn static int LogTunno = -1; 68b6217683SBrian Somers static struct prompt *logprompt; /* Where to log local stuff */ 69b6217683SBrian Somers 70b6217683SBrian Somers void 71b6217683SBrian Somers log_RegisterPrompt(struct prompt *prompt) 72b6217683SBrian Somers { 73b6217683SBrian Somers if (prompt) { 74b6217683SBrian Somers prompt->lognext = logprompt; 75b6217683SBrian Somers logprompt = prompt; 76b6217683SBrian Somers LogMaskLocal |= prompt->logmask; 77b6217683SBrian Somers } 78b6217683SBrian Somers } 79b6217683SBrian Somers 8067568487SBrian Somers static void 8167568487SBrian Somers LogSetMaskLocal(void) 8267568487SBrian Somers { 8367568487SBrian Somers struct prompt *p; 8467568487SBrian Somers 8567568487SBrian Somers LogMaskLocal = MSK(LogERROR) | MSK(LogALERT) | MSK(LogWARN); 8667568487SBrian Somers for (p = logprompt; p; p = p->lognext) 8767568487SBrian Somers LogMaskLocal |= p->logmask; 8867568487SBrian Somers } 8967568487SBrian Somers 90b6217683SBrian Somers void 91b6217683SBrian Somers log_UnRegisterPrompt(struct prompt *prompt) 92b6217683SBrian Somers { 93b6217683SBrian Somers if (prompt) { 94b6217683SBrian Somers struct prompt **p; 95b6217683SBrian Somers 9667568487SBrian Somers for (p = &logprompt; *p; p = &(*p)->lognext) 97b6217683SBrian Somers if (*p == prompt) { 9867568487SBrian Somers *p = prompt->lognext; 99b6217683SBrian Somers prompt->lognext = NULL; 100b6217683SBrian Somers break; 101b6217683SBrian Somers } 10267568487SBrian Somers LogSetMaskLocal(); 103b6217683SBrian Somers } 104b6217683SBrian Somers } 1051ae349f5Scvs2svn 1061ae349f5Scvs2svn static int 1071ae349f5Scvs2svn syslogLevel(int lev) 1081ae349f5Scvs2svn { 1091ae349f5Scvs2svn switch (lev) { 1101ae349f5Scvs2svn case LogDEBUG:return LOG_DEBUG; 1111ae349f5Scvs2svn case LogWARN: 1121ae349f5Scvs2svn return LOG_WARNING; 1131ae349f5Scvs2svn case LogERROR: 1141ae349f5Scvs2svn return LOG_ERR; 1151ae349f5Scvs2svn case LogALERT: 1161ae349f5Scvs2svn return LOG_ALERT; 1171ae349f5Scvs2svn } 1181ae349f5Scvs2svn return lev >= LogMIN && lev <= LogMAX ? LOG_INFO : 0; 1191ae349f5Scvs2svn } 1201ae349f5Scvs2svn 1211ae349f5Scvs2svn const char * 1221ae349f5Scvs2svn LogName(int id) 1231ae349f5Scvs2svn { 1241ae349f5Scvs2svn return id < LogMIN || id > LogMAX ? "Unknown" : LogNames[id - 1]; 1251ae349f5Scvs2svn } 1261ae349f5Scvs2svn 1271ae349f5Scvs2svn void 1281ae349f5Scvs2svn LogKeep(int id) 1291ae349f5Scvs2svn { 1301ae349f5Scvs2svn if (id >= LogMIN && id <= LogMAXCONF) 1311ae349f5Scvs2svn LogMask |= MSK(id); 1321ae349f5Scvs2svn } 1331ae349f5Scvs2svn 1341ae349f5Scvs2svn void 135b6217683SBrian Somers LogKeepLocal(int id, u_long *mask) 1361ae349f5Scvs2svn { 137b6217683SBrian Somers if (id >= LogMIN && id <= LogMAXCONF) { 1381ae349f5Scvs2svn LogMaskLocal |= MSK(id); 139b6217683SBrian Somers *mask |= MSK(id); 140b6217683SBrian Somers } 1411ae349f5Scvs2svn } 1421ae349f5Scvs2svn 1431ae349f5Scvs2svn void 1441ae349f5Scvs2svn LogDiscard(int id) 1451ae349f5Scvs2svn { 1461ae349f5Scvs2svn if (id >= LogMIN && id <= LogMAXCONF) 1471ae349f5Scvs2svn LogMask &= ~MSK(id); 1481ae349f5Scvs2svn } 1491ae349f5Scvs2svn 1501ae349f5Scvs2svn void 151b6217683SBrian Somers LogDiscardLocal(int id, u_long *mask) 1521ae349f5Scvs2svn { 153b6217683SBrian Somers if (id >= LogMIN && id <= LogMAXCONF) { 154b6217683SBrian Somers *mask &= ~MSK(id); 15567568487SBrian Somers LogSetMaskLocal(); 156b6217683SBrian Somers } 1571ae349f5Scvs2svn } 1581ae349f5Scvs2svn 1591ae349f5Scvs2svn void 1601ae349f5Scvs2svn LogDiscardAll() 1611ae349f5Scvs2svn { 1621ae349f5Scvs2svn LogMask = 0; 1631ae349f5Scvs2svn } 1641ae349f5Scvs2svn 1651ae349f5Scvs2svn void 166b6217683SBrian Somers LogDiscardAllLocal(u_long *mask) 1671ae349f5Scvs2svn { 16867568487SBrian Somers *mask = MSK(LogERROR) | MSK(LogALERT) | MSK(LogWARN); 16967568487SBrian Somers LogSetMaskLocal(); 1701ae349f5Scvs2svn } 1711ae349f5Scvs2svn 1721ae349f5Scvs2svn int 1731ae349f5Scvs2svn LogIsKept(int id) 1741ae349f5Scvs2svn { 1751ae349f5Scvs2svn if (id < LogMIN || id > LogMAX) 1761ae349f5Scvs2svn return 0; 1771ae349f5Scvs2svn if (id > LogMAXCONF) 1781ae349f5Scvs2svn return LOG_KEPT_LOCAL | LOG_KEPT_SYSLOG; 1791ae349f5Scvs2svn 1801ae349f5Scvs2svn return ((LogMaskLocal & MSK(id)) ? LOG_KEPT_LOCAL : 0) | 1811ae349f5Scvs2svn ((LogMask & MSK(id)) ? LOG_KEPT_SYSLOG : 0); 1821ae349f5Scvs2svn } 1831ae349f5Scvs2svn 184b6217683SBrian Somers int 185b6217683SBrian Somers LogIsKeptLocal(int id, u_long mask) 186b6217683SBrian Somers { 187b6217683SBrian Somers if (id < LogMIN || id > LogMAX) 188b6217683SBrian Somers return 0; 189b6217683SBrian Somers if (id > LogMAXCONF) 190b6217683SBrian Somers return LOG_KEPT_LOCAL | LOG_KEPT_SYSLOG; 191b6217683SBrian Somers 192b6217683SBrian Somers return ((mask & MSK(id)) ? LOG_KEPT_LOCAL : 0) | 193b6217683SBrian Somers ((LogMask & MSK(id)) ? LOG_KEPT_SYSLOG : 0); 194b6217683SBrian Somers } 195b6217683SBrian Somers 1961ae349f5Scvs2svn void 1971ae349f5Scvs2svn LogOpen(const char *Name) 1981ae349f5Scvs2svn { 1991ae349f5Scvs2svn openlog(Name, LOG_PID, LOG_DAEMON); 2001ae349f5Scvs2svn } 2011ae349f5Scvs2svn 2021ae349f5Scvs2svn void 2031ae349f5Scvs2svn LogSetTun(int tunno) 2041ae349f5Scvs2svn { 2051ae349f5Scvs2svn LogTunno = tunno; 2061ae349f5Scvs2svn } 2071ae349f5Scvs2svn 2081ae349f5Scvs2svn void 2091ae349f5Scvs2svn LogClose() 2101ae349f5Scvs2svn { 2111ae349f5Scvs2svn closelog(); 2121ae349f5Scvs2svn LogTunno = -1; 2131ae349f5Scvs2svn } 2141ae349f5Scvs2svn 2151ae349f5Scvs2svn void 2161ae349f5Scvs2svn LogPrintf(int lev, const char *fmt,...) 2171ae349f5Scvs2svn { 2181ae349f5Scvs2svn va_list ap; 219b6217683SBrian Somers struct prompt *prompt; 2201ae349f5Scvs2svn 2211ae349f5Scvs2svn va_start(ap, fmt); 2221ae349f5Scvs2svn if (LogIsKept(lev)) { 2231ae349f5Scvs2svn static char nfmt[200]; 2241ae349f5Scvs2svn 225b6217683SBrian Somers if ((LogIsKept(lev) & LOG_KEPT_LOCAL) && logprompt) { 2261ae349f5Scvs2svn if ((LogIsKept(LogTUN) & LOG_KEPT_LOCAL) && LogTunno != -1) 2271ae349f5Scvs2svn snprintf(nfmt, sizeof nfmt, "tun%d: %s: %s", 2281ae349f5Scvs2svn LogTunno, LogName(lev), fmt); 2291ae349f5Scvs2svn else 2301ae349f5Scvs2svn snprintf(nfmt, sizeof nfmt, "%s: %s", LogName(lev), fmt); 231b6217683SBrian Somers 232b6217683SBrian Somers for (prompt = logprompt; prompt; prompt = prompt->lognext) 233b6217683SBrian Somers if (lev > LogMAXCONF || (prompt->logmask & MSK(lev))) 234b6217683SBrian Somers prompt_vPrintf(prompt, nfmt, ap); 2351ae349f5Scvs2svn } 2361ae349f5Scvs2svn 237b6217683SBrian Somers if ((LogIsKept(lev) & LOG_KEPT_SYSLOG) && (lev != LogWARN || !logprompt)) { 2381ae349f5Scvs2svn if ((LogIsKept(LogTUN) & LOG_KEPT_SYSLOG) && LogTunno != -1) 2391ae349f5Scvs2svn snprintf(nfmt, sizeof nfmt, "tun%d: %s: %s", 2401ae349f5Scvs2svn LogTunno, LogName(lev), fmt); 2411ae349f5Scvs2svn else 2421ae349f5Scvs2svn snprintf(nfmt, sizeof nfmt, "%s: %s", LogName(lev), fmt); 2431ae349f5Scvs2svn vsyslog(syslogLevel(lev), nfmt, ap); 2441ae349f5Scvs2svn } 2451ae349f5Scvs2svn } 2461ae349f5Scvs2svn va_end(ap); 2471ae349f5Scvs2svn } 2481ae349f5Scvs2svn 2491ae349f5Scvs2svn void 2501ae349f5Scvs2svn LogDumpBp(int lev, const char *hdr, const struct mbuf * bp) 2511ae349f5Scvs2svn { 2521ae349f5Scvs2svn if (LogIsKept(lev)) { 2531ae349f5Scvs2svn char buf[50]; 2541ae349f5Scvs2svn char *b; 2551ae349f5Scvs2svn u_char *ptr; 2561ae349f5Scvs2svn int f; 2571ae349f5Scvs2svn 2581ae349f5Scvs2svn if (hdr && *hdr) 2591ae349f5Scvs2svn LogPrintf(lev, "%s\n", hdr); 2601ae349f5Scvs2svn 2611ae349f5Scvs2svn b = buf; 2621ae349f5Scvs2svn do { 2631ae349f5Scvs2svn f = bp->cnt; 2641ae349f5Scvs2svn ptr = MBUF_CTOP(bp); 2651ae349f5Scvs2svn while (f--) { 2661ae349f5Scvs2svn sprintf(b, " %02x", (int) *ptr++); 2671ae349f5Scvs2svn b += 3; 2681ae349f5Scvs2svn if (b == buf + sizeof buf - 2) { 2691ae349f5Scvs2svn strcpy(b, "\n"); 2701ae349f5Scvs2svn LogPrintf(lev, buf); 2711ae349f5Scvs2svn b = buf; 2721ae349f5Scvs2svn } 2731ae349f5Scvs2svn } 2741ae349f5Scvs2svn } while ((bp = bp->next) != NULL); 2751ae349f5Scvs2svn 2761ae349f5Scvs2svn if (b > buf) { 2771ae349f5Scvs2svn strcpy(b, "\n"); 2781ae349f5Scvs2svn LogPrintf(lev, buf); 2791ae349f5Scvs2svn } 2801ae349f5Scvs2svn } 2811ae349f5Scvs2svn } 2821ae349f5Scvs2svn 2831ae349f5Scvs2svn void 2841ae349f5Scvs2svn LogDumpBuff(int lev, const char *hdr, const u_char * ptr, int n) 2851ae349f5Scvs2svn { 2861ae349f5Scvs2svn if (LogIsKept(lev)) { 2871ae349f5Scvs2svn char buf[50]; 2881ae349f5Scvs2svn char *b; 2891ae349f5Scvs2svn 2901ae349f5Scvs2svn if (hdr && *hdr) 2911ae349f5Scvs2svn LogPrintf(lev, "%s\n", hdr); 2921ae349f5Scvs2svn while (n > 0) { 2931ae349f5Scvs2svn b = buf; 2941ae349f5Scvs2svn for (b = buf; b != buf + sizeof buf - 2 && n--; b += 3) 2951ae349f5Scvs2svn sprintf(b, " %02x", (int) *ptr++); 2961ae349f5Scvs2svn strcpy(b, "\n"); 2971ae349f5Scvs2svn LogPrintf(lev, buf); 2981ae349f5Scvs2svn } 2991ae349f5Scvs2svn } 3001ae349f5Scvs2svn } 301b6217683SBrian Somers 302b6217683SBrian Somers int 303b6217683SBrian Somers log_ShowLevel(struct cmdargs const *arg) 304b6217683SBrian Somers { 305b6217683SBrian Somers int i; 306b6217683SBrian Somers 307b6217683SBrian Somers prompt_Printf(arg->prompt, "Log: "); 308b6217683SBrian Somers for (i = LogMIN; i <= LogMAX; i++) 309b6217683SBrian Somers if (LogIsKept(i) & LOG_KEPT_SYSLOG) 310b6217683SBrian Somers prompt_Printf(arg->prompt, " %s", LogName(i)); 311b6217683SBrian Somers 312b6217683SBrian Somers prompt_Printf(arg->prompt, "\nLocal:"); 313b6217683SBrian Somers for (i = LogMIN; i <= LogMAX; i++) 314b6217683SBrian Somers if (LogIsKeptLocal(i, arg->prompt->logmask) & LOG_KEPT_LOCAL) 315b6217683SBrian Somers prompt_Printf(arg->prompt, " %s", LogName(i)); 316b6217683SBrian Somers 317b6217683SBrian Somers prompt_Printf(arg->prompt, "\n"); 318b6217683SBrian Somers 319b6217683SBrian Somers return 0; 320b6217683SBrian Somers } 321b6217683SBrian Somers 322b6217683SBrian Somers int 323b6217683SBrian Somers log_SetLevel(struct cmdargs const *arg) 324b6217683SBrian Somers { 325b6217683SBrian Somers int i, res, argc, local; 326b6217683SBrian Somers char const *const *argv, *argp; 327b6217683SBrian Somers 32825092092SBrian Somers argc = arg->argc - arg->argn; 32925092092SBrian Somers argv = arg->argv + arg->argn; 330b6217683SBrian Somers res = 0; 331b6217683SBrian Somers 332b6217683SBrian Somers if (argc == 0 || strcasecmp(argv[0], "local")) 333b6217683SBrian Somers local = 0; 334b6217683SBrian Somers else { 335b6217683SBrian Somers if (arg->prompt == NULL) { 336b6217683SBrian Somers LogPrintf(LogWARN, "set log local: Only available on the command line\n"); 337b6217683SBrian Somers return 1; 338b6217683SBrian Somers } 339b6217683SBrian Somers argc--; 340b6217683SBrian Somers argv++; 341b6217683SBrian Somers local = 1; 342b6217683SBrian Somers } 343b6217683SBrian Somers 344e43ebac1SBrian Somers if (argc == 0 || (argv[0][0] != '+' && argv[0][0] != '-')) { 345b6217683SBrian Somers if (local) 346b6217683SBrian Somers LogDiscardAllLocal(&arg->prompt->logmask); 347b6217683SBrian Somers else 348b6217683SBrian Somers LogDiscardAll(); 349e43ebac1SBrian Somers } 350b6217683SBrian Somers 351b6217683SBrian Somers while (argc--) { 352b6217683SBrian Somers argp = **argv == '+' || **argv == '-' ? *argv + 1 : *argv; 353b6217683SBrian Somers for (i = LogMIN; i <= LogMAX; i++) 354b6217683SBrian Somers if (strcasecmp(argp, LogName(i)) == 0) { 355e43ebac1SBrian Somers if (**argv == '-') { 356b6217683SBrian Somers if (local) 357b6217683SBrian Somers LogDiscardLocal(i, &arg->prompt->logmask); 358b6217683SBrian Somers else 359b6217683SBrian Somers LogDiscard(i); 360e43ebac1SBrian Somers } else if (local) 361b6217683SBrian Somers LogKeepLocal(i, &arg->prompt->logmask); 362b6217683SBrian Somers else 363b6217683SBrian Somers LogKeep(i); 364b6217683SBrian Somers break; 365b6217683SBrian Somers } 366b6217683SBrian Somers if (i > LogMAX) { 367b6217683SBrian Somers LogPrintf(LogWARN, "%s: Invalid log value\n", argp); 368b6217683SBrian Somers res = -1; 369b6217683SBrian Somers } 370b6217683SBrian Somers argv++; 371b6217683SBrian Somers } 372b6217683SBrian Somers return res; 373b6217683SBrian Somers } 374b6217683SBrian Somers 375b6217683SBrian Somers int 376b6217683SBrian Somers log_ShowWho(struct cmdargs const *arg) 377b6217683SBrian Somers { 378b6217683SBrian Somers struct prompt *p; 379b6217683SBrian Somers 380f91ad6b0SBrian Somers for (p = logprompt; p; p = p->lognext) { 381565e35e5SBrian Somers prompt_Printf(arg->prompt, "%s (%s)", p->src.type, p->src.from); 382f91ad6b0SBrian Somers if (p == arg->prompt) 383f91ad6b0SBrian Somers prompt_Printf(arg->prompt, " *"); 384f91ad6b0SBrian Somers if (!p->active) 385f91ad6b0SBrian Somers prompt_Printf(arg->prompt, " ^Z"); 386f91ad6b0SBrian Somers prompt_Printf(arg->prompt, "\n"); 387f91ad6b0SBrian Somers } 388b6217683SBrian Somers 389b6217683SBrian Somers return 0; 390b6217683SBrian Somers } 391