1c39934eaSBrian Somers /*- 2c39934eaSBrian Somers * Copyright (c) 1997 Brian Somers <brian@Awfulhak.org> 3c39934eaSBrian Somers * All rights reserved. 4c39934eaSBrian Somers * 5c39934eaSBrian Somers * Redistribution and use in source and binary forms, with or without 6c39934eaSBrian Somers * modification, are permitted provided that the following conditions 7c39934eaSBrian Somers * are met: 8c39934eaSBrian Somers * 1. Redistributions of source code must retain the above copyright 9c39934eaSBrian Somers * notice, this list of conditions and the following disclaimer. 10c39934eaSBrian Somers * 2. Redistributions in binary form must reproduce the above copyright 11c39934eaSBrian Somers * notice, this list of conditions and the following disclaimer in the 12c39934eaSBrian Somers * documentation and/or other materials provided with the distribution. 13c39934eaSBrian Somers * 14c39934eaSBrian Somers * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15c39934eaSBrian Somers * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16c39934eaSBrian Somers * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17c39934eaSBrian Somers * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18c39934eaSBrian Somers * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19c39934eaSBrian Somers * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20c39934eaSBrian Somers * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21c39934eaSBrian Somers * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22c39934eaSBrian Somers * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23c39934eaSBrian Somers * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24c39934eaSBrian Somers * SUCH DAMAGE. 25c39934eaSBrian Somers * 269cf01ccfSBrian Somers * $Id: log.c,v 1.39 1999/06/01 16:01:48 brian Exp $ 2775240ed1SBrian Somers */ 2875240ed1SBrian Somers 292764b86aSBrian Somers #include <sys/types.h> 3075240ed1SBrian Somers 31ba16c840SBrian Somers #include <ctype.h> 3253c9f6c0SAtsushi Murai #include <stdarg.h> 3353c9f6c0SAtsushi Murai #include <stdio.h> 3470a91e4cSBrian Somers #include <string.h> 3575240ed1SBrian Somers #include <syslog.h> 3685b542cfSBrian Somers #include <termios.h> 3775240ed1SBrian Somers 38c9e11a11SBrian Somers #include "defs.h" 39b6e82f33SBrian Somers #include "command.h" 40927145beSBrian Somers #include "mbuf.h" 41927145beSBrian Somers #include "log.h" 4285b542cfSBrian Somers #include "descriptor.h" 4385b542cfSBrian Somers #include "prompt.h" 44af57ed9fSAtsushi Murai 45b6e82f33SBrian Somers static const char *LogNames[] = { 46927145beSBrian Somers "Async", 4792b09558SBrian Somers "CBCP", 48cb611434SBrian Somers "CCP", 49927145beSBrian Somers "Chat", 50927145beSBrian Somers "Command", 51927145beSBrian Somers "Connect", 52927145beSBrian Somers "Debug", 53927145beSBrian Somers "HDLC", 545106c671SBrian Somers "ID0", 55cb611434SBrian Somers "IPCP", 56927145beSBrian Somers "LCP", 57927145beSBrian Somers "LQM", 58927145beSBrian Somers "Phase", 596815097bSBrian Somers "Physical", 606815097bSBrian Somers "Sync", 61927145beSBrian Somers "TCP/IP", 62b1ac9332SBrian Somers "Timer", 63927145beSBrian Somers "Tun", 64927145beSBrian Somers "Warning", 65927145beSBrian Somers "Error", 66927145beSBrian Somers "Alert" 67927145beSBrian Somers }; 68af57ed9fSAtsushi Murai 69927145beSBrian Somers #define MSK(n) (1<<((n)-1)) 70af57ed9fSAtsushi Murai 71d47dceb8SBrian Somers static u_long LogMask = MSK(LogPHASE); 72a1e8f937SBrian Somers static u_long LogMaskLocal = MSK(LogERROR) | MSK(LogALERT) | MSK(LogWARN); 73927145beSBrian Somers static int LogTunno = -1; 740f2f3eb3SBrian Somers static struct prompt *promptlist; /* Where to log local stuff */ 750bdcbcbeSBrian Somers int log_PromptListChanged; 760f2f3eb3SBrian Somers 770f2f3eb3SBrian Somers struct prompt * 780f2f3eb3SBrian Somers log_PromptList() 790f2f3eb3SBrian Somers { 800f2f3eb3SBrian Somers return promptlist; 810f2f3eb3SBrian Somers } 82b6217683SBrian Somers 83b6217683SBrian Somers void 84b6217683SBrian Somers log_RegisterPrompt(struct prompt *prompt) 85b6217683SBrian Somers { 860f2f3eb3SBrian Somers prompt->next = promptlist; 870f2f3eb3SBrian Somers promptlist = prompt; 880f2f3eb3SBrian Somers prompt->active = 1; 890f2f3eb3SBrian Somers log_DiscardAllLocal(&prompt->logmask); 90b6217683SBrian Somers } 910f2f3eb3SBrian Somers 920f2f3eb3SBrian Somers void 930f2f3eb3SBrian Somers log_ActivatePrompt(struct prompt *prompt) 940f2f3eb3SBrian Somers { 950f2f3eb3SBrian Somers prompt->active = 1; 960f2f3eb3SBrian Somers LogMaskLocal |= prompt->logmask; 97b6217683SBrian Somers } 98b6217683SBrian Somers 9967568487SBrian Somers static void 10067568487SBrian Somers LogSetMaskLocal(void) 10167568487SBrian Somers { 10267568487SBrian Somers struct prompt *p; 10367568487SBrian Somers 10467568487SBrian Somers LogMaskLocal = MSK(LogERROR) | MSK(LogALERT) | MSK(LogWARN); 1050f2f3eb3SBrian Somers for (p = promptlist; p; p = p->next) 10667568487SBrian Somers LogMaskLocal |= p->logmask; 10767568487SBrian Somers } 10867568487SBrian Somers 109b6217683SBrian Somers void 1100f2f3eb3SBrian Somers log_DeactivatePrompt(struct prompt *prompt) 1110f2f3eb3SBrian Somers { 1120f2f3eb3SBrian Somers if (prompt->active) { 1130f2f3eb3SBrian Somers prompt->active = 0; 1140f2f3eb3SBrian Somers LogSetMaskLocal(); 1150f2f3eb3SBrian Somers } 1160f2f3eb3SBrian Somers } 1170f2f3eb3SBrian Somers 1180f2f3eb3SBrian Somers void 119b6217683SBrian Somers log_UnRegisterPrompt(struct prompt *prompt) 120b6217683SBrian Somers { 121b6217683SBrian Somers if (prompt) { 122b6217683SBrian Somers struct prompt **p; 123b6217683SBrian Somers 1240f2f3eb3SBrian Somers for (p = &promptlist; *p; p = &(*p)->next) 125b6217683SBrian Somers if (*p == prompt) { 1260f2f3eb3SBrian Somers *p = prompt->next; 1270f2f3eb3SBrian Somers prompt->next = NULL; 128b6217683SBrian Somers break; 129b6217683SBrian Somers } 13067568487SBrian Somers LogSetMaskLocal(); 1310bdcbcbeSBrian Somers log_PromptListChanged++; 132b6217683SBrian Somers } 133b6217683SBrian Somers } 134af57ed9fSAtsushi Murai 1350f2f3eb3SBrian Somers void 1360f2f3eb3SBrian Somers log_DestroyPrompts(struct server *s) 1370f2f3eb3SBrian Somers { 138a39fd214SBrian Somers struct prompt *p, *pn, *pl; 1390f2f3eb3SBrian Somers 1400f2f3eb3SBrian Somers p = promptlist; 141a39fd214SBrian Somers pl = NULL; 1420f2f3eb3SBrian Somers while (p) { 1430f2f3eb3SBrian Somers pn = p->next; 144a39fd214SBrian Somers if (s && p->owner == s) { 145a39fd214SBrian Somers if (pl) 146a39fd214SBrian Somers pl->next = p->next; 147a39fd214SBrian Somers else 148a39fd214SBrian Somers promptlist = p->next; 1490f2f3eb3SBrian Somers p->next = NULL; 1500f2f3eb3SBrian Somers prompt_Destroy(p, 1); 151a39fd214SBrian Somers } else 152a39fd214SBrian Somers pl = p; 1530f2f3eb3SBrian Somers p = pn; 1540f2f3eb3SBrian Somers } 1550f2f3eb3SBrian Somers } 1560f2f3eb3SBrian Somers 1570f2f3eb3SBrian Somers void 1580f2f3eb3SBrian Somers log_DisplayPrompts() 1590f2f3eb3SBrian Somers { 1600f2f3eb3SBrian Somers struct prompt *p; 1610f2f3eb3SBrian Somers 1620f2f3eb3SBrian Somers for (p = promptlist; p; p = p->next) 1630f2f3eb3SBrian Somers prompt_Required(p); 1640f2f3eb3SBrian Somers } 1650f2f3eb3SBrian Somers 1660f2f3eb3SBrian Somers void 167bf1d3ff6SBrian Somers log_WritePrompts(struct datalink *dl, const char *fmt,...) 1680f2f3eb3SBrian Somers { 169bf1d3ff6SBrian Somers va_list ap; 1700f2f3eb3SBrian Somers struct prompt *p; 1710f2f3eb3SBrian Somers 172bf1d3ff6SBrian Somers va_start(ap, fmt); 1730f2f3eb3SBrian Somers for (p = promptlist; p; p = p->next) 1740f2f3eb3SBrian Somers if (prompt_IsTermMode(p, dl)) 175bf1d3ff6SBrian Somers prompt_vPrintf(p, fmt, ap); 176bf1d3ff6SBrian Somers va_end(ap); 1770f2f3eb3SBrian Somers } 1780f2f3eb3SBrian Somers 1790f2f3eb3SBrian Somers void 1800f2f3eb3SBrian Somers log_SetTtyCommandMode(struct datalink *dl) 1810f2f3eb3SBrian Somers { 1820f2f3eb3SBrian Somers struct prompt *p; 1830f2f3eb3SBrian Somers 1840f2f3eb3SBrian Somers for (p = promptlist; p; p = p->next) 1850f2f3eb3SBrian Somers if (prompt_IsTermMode(p, dl)) 1860f2f3eb3SBrian Somers prompt_TtyCommandMode(p); 1870f2f3eb3SBrian Somers } 1880f2f3eb3SBrian Somers 189927145beSBrian Somers static int 190927145beSBrian Somers syslogLevel(int lev) 191927145beSBrian Somers { 192927145beSBrian Somers switch (lev) { 1936f384573SBrian Somers case LogDEBUG: 1946f384573SBrian Somers case LogTIMER: 1956f384573SBrian Somers return LOG_DEBUG; 196944f7098SBrian Somers case LogWARN: 197944f7098SBrian Somers return LOG_WARNING; 198944f7098SBrian Somers case LogERROR: 199944f7098SBrian Somers return LOG_ERR; 200944f7098SBrian Somers case LogALERT: 201944f7098SBrian Somers return LOG_ALERT; 202927145beSBrian Somers } 203927145beSBrian Somers return lev >= LogMIN && lev <= LogMAX ? LOG_INFO : 0; 204927145beSBrian Somers } 205af57ed9fSAtsushi Murai 206927145beSBrian Somers const char * 207dd7e2610SBrian Somers log_Name(int id) 208927145beSBrian Somers { 209927145beSBrian Somers return id < LogMIN || id > LogMAX ? "Unknown" : LogNames[id - 1]; 210927145beSBrian Somers } 211af57ed9fSAtsushi Murai 212af57ed9fSAtsushi Murai void 213dd7e2610SBrian Somers log_Keep(int id) 214af57ed9fSAtsushi Murai { 215927145beSBrian Somers if (id >= LogMIN && id <= LogMAXCONF) 216927145beSBrian Somers LogMask |= MSK(id); 217af57ed9fSAtsushi Murai } 218927145beSBrian Somers 219927145beSBrian Somers void 220dd7e2610SBrian Somers log_KeepLocal(int id, u_long *mask) 221a1e8f937SBrian Somers { 222b6217683SBrian Somers if (id >= LogMIN && id <= LogMAXCONF) { 223a1e8f937SBrian Somers LogMaskLocal |= MSK(id); 224b6217683SBrian Somers *mask |= MSK(id); 225b6217683SBrian Somers } 226a1e8f937SBrian Somers } 227a1e8f937SBrian Somers 228a1e8f937SBrian Somers void 229dd7e2610SBrian Somers log_Discard(int id) 230927145beSBrian Somers { 231927145beSBrian Somers if (id >= LogMIN && id <= LogMAXCONF) 232927145beSBrian Somers LogMask &= ~MSK(id); 233927145beSBrian Somers } 234927145beSBrian Somers 235927145beSBrian Somers void 236dd7e2610SBrian Somers log_DiscardLocal(int id, u_long *mask) 237a1e8f937SBrian Somers { 238b6217683SBrian Somers if (id >= LogMIN && id <= LogMAXCONF) { 239b6217683SBrian Somers *mask &= ~MSK(id); 24067568487SBrian Somers LogSetMaskLocal(); 241b6217683SBrian Somers } 242a1e8f937SBrian Somers } 243a1e8f937SBrian Somers 244a1e8f937SBrian Somers void 245dd7e2610SBrian Somers log_DiscardAll() 246927145beSBrian Somers { 247927145beSBrian Somers LogMask = 0; 248af57ed9fSAtsushi Murai } 249af57ed9fSAtsushi Murai 250a1e8f937SBrian Somers void 251dd7e2610SBrian Somers log_DiscardAllLocal(u_long *mask) 252a1e8f937SBrian Somers { 25367568487SBrian Somers *mask = MSK(LogERROR) | MSK(LogALERT) | MSK(LogWARN); 25467568487SBrian Somers LogSetMaskLocal(); 255a1e8f937SBrian Somers } 256a1e8f937SBrian Somers 257af57ed9fSAtsushi Murai int 258dd7e2610SBrian Somers log_IsKept(int id) 259af57ed9fSAtsushi Murai { 260a1e8f937SBrian Somers if (id < LogMIN || id > LogMAX) 261927145beSBrian Somers return 0; 262a1e8f937SBrian Somers if (id > LogMAXCONF) 263a1e8f937SBrian Somers return LOG_KEPT_LOCAL | LOG_KEPT_SYSLOG; 264a1e8f937SBrian Somers 265a1e8f937SBrian Somers return ((LogMaskLocal & MSK(id)) ? LOG_KEPT_LOCAL : 0) | 266a1e8f937SBrian Somers ((LogMask & MSK(id)) ? LOG_KEPT_SYSLOG : 0); 267af57ed9fSAtsushi Murai } 268af57ed9fSAtsushi Murai 269b6217683SBrian Somers int 270dd7e2610SBrian Somers log_IsKeptLocal(int id, u_long mask) 271b6217683SBrian Somers { 272b6217683SBrian Somers if (id < LogMIN || id > LogMAX) 273b6217683SBrian Somers return 0; 274b6217683SBrian Somers if (id > LogMAXCONF) 275b6217683SBrian Somers return LOG_KEPT_LOCAL | LOG_KEPT_SYSLOG; 276b6217683SBrian Somers 277b6217683SBrian Somers return ((mask & MSK(id)) ? LOG_KEPT_LOCAL : 0) | 278b6217683SBrian Somers ((LogMask & MSK(id)) ? LOG_KEPT_SYSLOG : 0); 279b6217683SBrian Somers } 280b6217683SBrian Somers 281af57ed9fSAtsushi Murai void 282dd7e2610SBrian Somers log_Open(const char *Name) 283af57ed9fSAtsushi Murai { 284927145beSBrian Somers openlog(Name, LOG_PID, LOG_DAEMON); 285af57ed9fSAtsushi Murai } 286af57ed9fSAtsushi Murai 287af57ed9fSAtsushi Murai void 288dd7e2610SBrian Somers log_SetTun(int tunno) 289af57ed9fSAtsushi Murai { 290927145beSBrian Somers LogTunno = tunno; 291af57ed9fSAtsushi Murai } 292af57ed9fSAtsushi Murai 293af57ed9fSAtsushi Murai void 294dd7e2610SBrian Somers log_Close() 295af57ed9fSAtsushi Murai { 296927145beSBrian Somers closelog(); 297927145beSBrian Somers LogTunno = -1; 2986ed9fb2fSBrian Somers } 299af57ed9fSAtsushi Murai 300af57ed9fSAtsushi Murai void 301dd7e2610SBrian Somers log_Printf(int lev, const char *fmt,...) 30253c9f6c0SAtsushi Murai { 30353c9f6c0SAtsushi Murai va_list ap; 304b6217683SBrian Somers struct prompt *prompt; 305944f7098SBrian Somers 306927145beSBrian Somers va_start(ap, fmt); 307dd7e2610SBrian Somers if (log_IsKept(lev)) { 308d93d3a9cSBrian Somers char nfmt[200]; 30953c9f6c0SAtsushi Murai 3100f2f3eb3SBrian Somers if ((log_IsKept(lev) & LOG_KEPT_LOCAL) && promptlist) { 311dd7e2610SBrian Somers if ((log_IsKept(LogTUN) & LOG_KEPT_LOCAL) && LogTunno != -1) 3121384bd27SBrian Somers snprintf(nfmt, sizeof nfmt, "%s%d: %s: %s", TUN_NAME, 313dd7e2610SBrian Somers LogTunno, log_Name(lev), fmt); 314927145beSBrian Somers else 315dd7e2610SBrian Somers snprintf(nfmt, sizeof nfmt, "%s: %s", log_Name(lev), fmt); 316b6217683SBrian Somers 3170f2f3eb3SBrian Somers for (prompt = promptlist; prompt; prompt = prompt->next) 318b6217683SBrian Somers if (lev > LogMAXCONF || (prompt->logmask & MSK(lev))) 319b6217683SBrian Somers prompt_vPrintf(prompt, nfmt, ap); 320a1e8f937SBrian Somers } 321a1e8f937SBrian Somers 3220f2f3eb3SBrian Somers if ((log_IsKept(lev) & LOG_KEPT_SYSLOG) && 3230f2f3eb3SBrian Somers (lev != LogWARN || !promptlist)) { 324dd7e2610SBrian Somers if ((log_IsKept(LogTUN) & LOG_KEPT_SYSLOG) && LogTunno != -1) 3251384bd27SBrian Somers snprintf(nfmt, sizeof nfmt, "%s%d: %s: %s", TUN_NAME, 326dd7e2610SBrian Somers LogTunno, log_Name(lev), fmt); 327a1e8f937SBrian Somers else 328dd7e2610SBrian Somers snprintf(nfmt, sizeof nfmt, "%s: %s", log_Name(lev), fmt); 329927145beSBrian Somers vsyslog(syslogLevel(lev), nfmt, ap); 330927145beSBrian Somers } 331a1e8f937SBrian Somers } 33253c9f6c0SAtsushi Murai va_end(ap); 33353c9f6c0SAtsushi Murai } 33453c9f6c0SAtsushi Murai 33553c9f6c0SAtsushi Murai void 336dd7e2610SBrian Somers log_DumpBp(int lev, const char *hdr, const struct mbuf *bp) 337af57ed9fSAtsushi Murai { 338dd7e2610SBrian Somers if (log_IsKept(lev)) { 339ba16c840SBrian Somers char buf[68]; 340ba16c840SBrian Somers char *b, *c; 3419773f8c0SBrian Somers const u_char *ptr; 342a9e8f807SBrian Somers int f; 343a9e8f807SBrian Somers 344a9e8f807SBrian Somers if (hdr && *hdr) 345dd7e2610SBrian Somers log_Printf(lev, "%s\n", hdr); 346a9e8f807SBrian Somers 347a9e8f807SBrian Somers b = buf; 348ba16c840SBrian Somers c = b + 50; 349a9e8f807SBrian Somers do { 350a9e8f807SBrian Somers f = bp->cnt; 3519773f8c0SBrian Somers ptr = CONST_MBUF_CTOP(bp); 352a9e8f807SBrian Somers while (f--) { 353ba16c840SBrian Somers sprintf(b, " %02x", (int) *ptr); 354ba16c840SBrian Somers *c++ = isprint(*ptr) ? *ptr : '.'; 355ba16c840SBrian Somers ptr++; 356a9e8f807SBrian Somers b += 3; 357ba16c840SBrian Somers if (b == buf + 48) { 358ba16c840SBrian Somers memset(b, ' ', 2); 3599cf01ccfSBrian Somers *c = '\0'; 3609cf01ccfSBrian Somers log_Printf(lev, "%s\n", buf); 361a9e8f807SBrian Somers b = buf; 362ba16c840SBrian Somers c = b + 50; 363a9e8f807SBrian Somers } 364a9e8f807SBrian Somers } 365a9e8f807SBrian Somers } while ((bp = bp->next) != NULL); 366a9e8f807SBrian Somers 367a1e8f937SBrian Somers if (b > buf) { 368ba16c840SBrian Somers memset(b, ' ', 50 - (b - buf)); 3699cf01ccfSBrian Somers *c = '\0'; 3709cf01ccfSBrian Somers log_Printf(lev, "%s\n", buf); 371a9e8f807SBrian Somers } 372af57ed9fSAtsushi Murai } 373a1e8f937SBrian Somers } 374af57ed9fSAtsushi Murai 375af57ed9fSAtsushi Murai void 376dd7e2610SBrian Somers log_DumpBuff(int lev, const char *hdr, const u_char *ptr, int n) 377af57ed9fSAtsushi Murai { 378dd7e2610SBrian Somers if (log_IsKept(lev)) { 379ba16c840SBrian Somers char buf[68]; 380ba16c840SBrian Somers char *b, *c; 381af57ed9fSAtsushi Murai 382927145beSBrian Somers if (hdr && *hdr) 383dd7e2610SBrian Somers log_Printf(lev, "%s\n", hdr); 384927145beSBrian Somers while (n > 0) { 385927145beSBrian Somers b = buf; 386ba16c840SBrian Somers c = b + 50; 387ba16c840SBrian Somers for (b = buf; b != buf + 48 && n--; b += 3, ptr++) { 388ba16c840SBrian Somers sprintf(b, " %02x", (int) *ptr); 389ba16c840SBrian Somers *c++ = isprint(*ptr) ? *ptr : '.'; 390ba16c840SBrian Somers } 391ba16c840SBrian Somers memset(b, ' ', 50 - (b - buf)); 3929cf01ccfSBrian Somers *c = '\0'; 3939cf01ccfSBrian Somers log_Printf(lev, "%s\n", buf); 394af57ed9fSAtsushi Murai } 395af57ed9fSAtsushi Murai } 396c6c740beSBrian Somers } 397b6217683SBrian Somers 398b6217683SBrian Somers int 399b6217683SBrian Somers log_ShowLevel(struct cmdargs const *arg) 400b6217683SBrian Somers { 401b6217683SBrian Somers int i; 402b6217683SBrian Somers 403b6217683SBrian Somers prompt_Printf(arg->prompt, "Log: "); 404b6217683SBrian Somers for (i = LogMIN; i <= LogMAX; i++) 405dd7e2610SBrian Somers if (log_IsKept(i) & LOG_KEPT_SYSLOG) 406dd7e2610SBrian Somers prompt_Printf(arg->prompt, " %s", log_Name(i)); 407b6217683SBrian Somers 408b6217683SBrian Somers prompt_Printf(arg->prompt, "\nLocal:"); 409b6217683SBrian Somers for (i = LogMIN; i <= LogMAX; i++) 410dd7e2610SBrian Somers if (log_IsKeptLocal(i, arg->prompt->logmask) & LOG_KEPT_LOCAL) 411dd7e2610SBrian Somers prompt_Printf(arg->prompt, " %s", log_Name(i)); 412b6217683SBrian Somers 413b6217683SBrian Somers prompt_Printf(arg->prompt, "\n"); 414b6217683SBrian Somers 415b6217683SBrian Somers return 0; 416b6217683SBrian Somers } 417b6217683SBrian Somers 418b6217683SBrian Somers int 419b6217683SBrian Somers log_SetLevel(struct cmdargs const *arg) 420b6217683SBrian Somers { 421b6217683SBrian Somers int i, res, argc, local; 422b6217683SBrian Somers char const *const *argv, *argp; 423b6217683SBrian Somers 42425092092SBrian Somers argc = arg->argc - arg->argn; 42525092092SBrian Somers argv = arg->argv + arg->argn; 426b6217683SBrian Somers res = 0; 427b6217683SBrian Somers 428b6217683SBrian Somers if (argc == 0 || strcasecmp(argv[0], "local")) 429b6217683SBrian Somers local = 0; 430b6217683SBrian Somers else { 431b6217683SBrian Somers if (arg->prompt == NULL) { 432dd7e2610SBrian Somers log_Printf(LogWARN, "set log local: Only available on the command line\n"); 433b6217683SBrian Somers return 1; 434b6217683SBrian Somers } 435b6217683SBrian Somers argc--; 436b6217683SBrian Somers argv++; 437b6217683SBrian Somers local = 1; 438b6217683SBrian Somers } 439b6217683SBrian Somers 440e43ebac1SBrian Somers if (argc == 0 || (argv[0][0] != '+' && argv[0][0] != '-')) { 441b6217683SBrian Somers if (local) 442dd7e2610SBrian Somers log_DiscardAllLocal(&arg->prompt->logmask); 443b6217683SBrian Somers else 444dd7e2610SBrian Somers log_DiscardAll(); 445e43ebac1SBrian Somers } 446b6217683SBrian Somers 447b6217683SBrian Somers while (argc--) { 448b6217683SBrian Somers argp = **argv == '+' || **argv == '-' ? *argv + 1 : *argv; 449b6217683SBrian Somers for (i = LogMIN; i <= LogMAX; i++) 450dd7e2610SBrian Somers if (strcasecmp(argp, log_Name(i)) == 0) { 451e43ebac1SBrian Somers if (**argv == '-') { 452b6217683SBrian Somers if (local) 453dd7e2610SBrian Somers log_DiscardLocal(i, &arg->prompt->logmask); 454b6217683SBrian Somers else 455dd7e2610SBrian Somers log_Discard(i); 456e43ebac1SBrian Somers } else if (local) 457dd7e2610SBrian Somers log_KeepLocal(i, &arg->prompt->logmask); 458b6217683SBrian Somers else 459dd7e2610SBrian Somers log_Keep(i); 460b6217683SBrian Somers break; 461b6217683SBrian Somers } 462b6217683SBrian Somers if (i > LogMAX) { 463dd7e2610SBrian Somers log_Printf(LogWARN, "%s: Invalid log value\n", argp); 464b6217683SBrian Somers res = -1; 465b6217683SBrian Somers } 466b6217683SBrian Somers argv++; 467b6217683SBrian Somers } 468b6217683SBrian Somers return res; 469b6217683SBrian Somers } 470b6217683SBrian Somers 471b6217683SBrian Somers int 472b6217683SBrian Somers log_ShowWho(struct cmdargs const *arg) 473b6217683SBrian Somers { 474b6217683SBrian Somers struct prompt *p; 475b6217683SBrian Somers 4760f2f3eb3SBrian Somers for (p = promptlist; p; p = p->next) { 477565e35e5SBrian Somers prompt_Printf(arg->prompt, "%s (%s)", p->src.type, p->src.from); 478f91ad6b0SBrian Somers if (p == arg->prompt) 479f91ad6b0SBrian Somers prompt_Printf(arg->prompt, " *"); 480f91ad6b0SBrian Somers if (!p->active) 481f91ad6b0SBrian Somers prompt_Printf(arg->prompt, " ^Z"); 482f91ad6b0SBrian Somers prompt_Printf(arg->prompt, "\n"); 483f91ad6b0SBrian Somers } 484b6217683SBrian Somers 485b6217683SBrian Somers return 0; 486b6217683SBrian Somers } 487