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 * 2697d92980SPeter Wemm * $FreeBSD$ 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 45182c898aSBrian Somers static const char *const LogNames[] = { 46927145beSBrian Somers "Async", 4792b09558SBrian Somers "CBCP", 48cb611434SBrian Somers "CCP", 49927145beSBrian Somers "Chat", 50927145beSBrian Somers "Command", 51927145beSBrian Somers "Connect", 52927145beSBrian Somers "Debug", 5352c9ca19SBrian Somers "DNS", 5406a43ce0SBrian Somers "Filter", /* Log discarded packets */ 55927145beSBrian Somers "HDLC", 565106c671SBrian Somers "ID0", 57cb611434SBrian Somers "IPCP", 5830949fd4SBrian Somers "IPV6CP", 59927145beSBrian Somers "LCP", 60927145beSBrian Somers "LQM", 61927145beSBrian Somers "Phase", 626815097bSBrian Somers "Physical", 636815097bSBrian Somers "Sync", 64927145beSBrian Somers "TCP/IP", 65b1ac9332SBrian Somers "Timer", 66927145beSBrian Somers "Tun", 67927145beSBrian Somers "Warning", 68927145beSBrian Somers "Error", 69927145beSBrian Somers "Alert" 70927145beSBrian Somers }; 71af57ed9fSAtsushi Murai 72927145beSBrian Somers #define MSK(n) (1<<((n)-1)) 73af57ed9fSAtsushi Murai 74d47dceb8SBrian Somers static u_long LogMask = MSK(LogPHASE); 75a1e8f937SBrian Somers static u_long LogMaskLocal = MSK(LogERROR) | MSK(LogALERT) | MSK(LogWARN); 76927145beSBrian Somers static int LogTunno = -1; 770f2f3eb3SBrian Somers static struct prompt *promptlist; /* Where to log local stuff */ 78b4f63b0bSBrian Somers struct prompt *log_PromptContext; 790bdcbcbeSBrian Somers int log_PromptListChanged; 800f2f3eb3SBrian Somers 810f2f3eb3SBrian Somers struct prompt * 820f2f3eb3SBrian Somers log_PromptList() 830f2f3eb3SBrian Somers { 840f2f3eb3SBrian Somers return promptlist; 850f2f3eb3SBrian Somers } 86b6217683SBrian Somers 87b6217683SBrian Somers void 88b6217683SBrian Somers log_RegisterPrompt(struct prompt *prompt) 89b6217683SBrian Somers { 900f2f3eb3SBrian Somers prompt->next = promptlist; 910f2f3eb3SBrian Somers promptlist = prompt; 920f2f3eb3SBrian Somers prompt->active = 1; 930f2f3eb3SBrian Somers log_DiscardAllLocal(&prompt->logmask); 94b6217683SBrian Somers } 950f2f3eb3SBrian Somers 960f2f3eb3SBrian Somers void 970f2f3eb3SBrian Somers log_ActivatePrompt(struct prompt *prompt) 980f2f3eb3SBrian Somers { 990f2f3eb3SBrian Somers prompt->active = 1; 1000f2f3eb3SBrian Somers LogMaskLocal |= prompt->logmask; 101b6217683SBrian Somers } 102b6217683SBrian Somers 10367568487SBrian Somers static void 10467568487SBrian Somers LogSetMaskLocal(void) 10567568487SBrian Somers { 10667568487SBrian Somers struct prompt *p; 10767568487SBrian Somers 10867568487SBrian Somers LogMaskLocal = MSK(LogERROR) | MSK(LogALERT) | MSK(LogWARN); 1090f2f3eb3SBrian Somers for (p = promptlist; p; p = p->next) 11067568487SBrian Somers LogMaskLocal |= p->logmask; 11167568487SBrian Somers } 11267568487SBrian Somers 113b6217683SBrian Somers void 1140f2f3eb3SBrian Somers log_DeactivatePrompt(struct prompt *prompt) 1150f2f3eb3SBrian Somers { 1160f2f3eb3SBrian Somers if (prompt->active) { 1170f2f3eb3SBrian Somers prompt->active = 0; 1180f2f3eb3SBrian Somers LogSetMaskLocal(); 1190f2f3eb3SBrian Somers } 1200f2f3eb3SBrian Somers } 1210f2f3eb3SBrian Somers 1220f2f3eb3SBrian Somers void 123b6217683SBrian Somers log_UnRegisterPrompt(struct prompt *prompt) 124b6217683SBrian Somers { 125b6217683SBrian Somers if (prompt) { 126b6217683SBrian Somers struct prompt **p; 127b6217683SBrian Somers 1280f2f3eb3SBrian Somers for (p = &promptlist; *p; p = &(*p)->next) 129b6217683SBrian Somers if (*p == prompt) { 1300f2f3eb3SBrian Somers *p = prompt->next; 1310f2f3eb3SBrian Somers prompt->next = NULL; 132b6217683SBrian Somers break; 133b6217683SBrian Somers } 13467568487SBrian Somers LogSetMaskLocal(); 1350bdcbcbeSBrian Somers log_PromptListChanged++; 136b6217683SBrian Somers } 137b6217683SBrian Somers } 138af57ed9fSAtsushi Murai 1390f2f3eb3SBrian Somers void 1400f2f3eb3SBrian Somers log_DestroyPrompts(struct server *s) 1410f2f3eb3SBrian Somers { 142a39fd214SBrian Somers struct prompt *p, *pn, *pl; 1430f2f3eb3SBrian Somers 1440f2f3eb3SBrian Somers p = promptlist; 145a39fd214SBrian Somers pl = NULL; 1460f2f3eb3SBrian Somers while (p) { 1470f2f3eb3SBrian Somers pn = p->next; 148a39fd214SBrian Somers if (s && p->owner == s) { 149a39fd214SBrian Somers if (pl) 150a39fd214SBrian Somers pl->next = p->next; 151a39fd214SBrian Somers else 152a39fd214SBrian Somers promptlist = p->next; 1530f2f3eb3SBrian Somers p->next = NULL; 1540f2f3eb3SBrian Somers prompt_Destroy(p, 1); 155a39fd214SBrian Somers } else 156a39fd214SBrian Somers pl = p; 1570f2f3eb3SBrian Somers p = pn; 1580f2f3eb3SBrian Somers } 1590f2f3eb3SBrian Somers } 1600f2f3eb3SBrian Somers 1610f2f3eb3SBrian Somers void 1620f2f3eb3SBrian Somers log_DisplayPrompts() 1630f2f3eb3SBrian Somers { 1640f2f3eb3SBrian Somers struct prompt *p; 1650f2f3eb3SBrian Somers 1660f2f3eb3SBrian Somers for (p = promptlist; p; p = p->next) 1670f2f3eb3SBrian Somers prompt_Required(p); 1680f2f3eb3SBrian Somers } 1690f2f3eb3SBrian Somers 1700f2f3eb3SBrian Somers void 171bf1d3ff6SBrian Somers log_WritePrompts(struct datalink *dl, const char *fmt,...) 1720f2f3eb3SBrian Somers { 173bf1d3ff6SBrian Somers va_list ap; 1740f2f3eb3SBrian Somers struct prompt *p; 1750f2f3eb3SBrian Somers 176bf1d3ff6SBrian Somers va_start(ap, fmt); 1770f2f3eb3SBrian Somers for (p = promptlist; p; p = p->next) 1780f2f3eb3SBrian Somers if (prompt_IsTermMode(p, dl)) 179bf1d3ff6SBrian Somers prompt_vPrintf(p, fmt, ap); 180bf1d3ff6SBrian Somers va_end(ap); 1810f2f3eb3SBrian Somers } 1820f2f3eb3SBrian Somers 1830f2f3eb3SBrian Somers void 1840f2f3eb3SBrian Somers log_SetTtyCommandMode(struct datalink *dl) 1850f2f3eb3SBrian Somers { 1860f2f3eb3SBrian Somers struct prompt *p; 1870f2f3eb3SBrian Somers 1880f2f3eb3SBrian Somers for (p = promptlist; p; p = p->next) 1890f2f3eb3SBrian Somers if (prompt_IsTermMode(p, dl)) 1900f2f3eb3SBrian Somers prompt_TtyCommandMode(p); 1910f2f3eb3SBrian Somers } 1920f2f3eb3SBrian Somers 193927145beSBrian Somers static int 194927145beSBrian Somers syslogLevel(int lev) 195927145beSBrian Somers { 196927145beSBrian Somers switch (lev) { 1976f384573SBrian Somers case LogDEBUG: 1986f384573SBrian Somers case LogTIMER: 1996f384573SBrian Somers return LOG_DEBUG; 200944f7098SBrian Somers case LogWARN: 201944f7098SBrian Somers return LOG_WARNING; 202944f7098SBrian Somers case LogERROR: 203944f7098SBrian Somers return LOG_ERR; 204944f7098SBrian Somers case LogALERT: 205944f7098SBrian Somers return LOG_ALERT; 206927145beSBrian Somers } 207927145beSBrian Somers return lev >= LogMIN && lev <= LogMAX ? LOG_INFO : 0; 208927145beSBrian Somers } 209af57ed9fSAtsushi Murai 210927145beSBrian Somers const char * 211dd7e2610SBrian Somers log_Name(int id) 212927145beSBrian Somers { 213927145beSBrian Somers return id < LogMIN || id > LogMAX ? "Unknown" : LogNames[id - 1]; 214927145beSBrian Somers } 215af57ed9fSAtsushi Murai 216af57ed9fSAtsushi Murai void 217dd7e2610SBrian Somers log_Keep(int id) 218af57ed9fSAtsushi Murai { 219927145beSBrian Somers if (id >= LogMIN && id <= LogMAXCONF) 220927145beSBrian Somers LogMask |= MSK(id); 221af57ed9fSAtsushi Murai } 222927145beSBrian Somers 223927145beSBrian Somers void 224dd7e2610SBrian Somers log_KeepLocal(int id, u_long *mask) 225a1e8f937SBrian Somers { 226b6217683SBrian Somers if (id >= LogMIN && id <= LogMAXCONF) { 227a1e8f937SBrian Somers LogMaskLocal |= MSK(id); 228b6217683SBrian Somers *mask |= MSK(id); 229b6217683SBrian Somers } 230a1e8f937SBrian Somers } 231a1e8f937SBrian Somers 232a1e8f937SBrian Somers void 233dd7e2610SBrian Somers log_Discard(int id) 234927145beSBrian Somers { 235927145beSBrian Somers if (id >= LogMIN && id <= LogMAXCONF) 236927145beSBrian Somers LogMask &= ~MSK(id); 237927145beSBrian Somers } 238927145beSBrian Somers 239927145beSBrian Somers void 240dd7e2610SBrian Somers log_DiscardLocal(int id, u_long *mask) 241a1e8f937SBrian Somers { 242b6217683SBrian Somers if (id >= LogMIN && id <= LogMAXCONF) { 243b6217683SBrian Somers *mask &= ~MSK(id); 24467568487SBrian Somers LogSetMaskLocal(); 245b6217683SBrian Somers } 246a1e8f937SBrian Somers } 247a1e8f937SBrian Somers 248a1e8f937SBrian Somers void 249dd7e2610SBrian Somers log_DiscardAll() 250927145beSBrian Somers { 251927145beSBrian Somers LogMask = 0; 252af57ed9fSAtsushi Murai } 253af57ed9fSAtsushi Murai 254a1e8f937SBrian Somers void 255dd7e2610SBrian Somers log_DiscardAllLocal(u_long *mask) 256a1e8f937SBrian Somers { 25767568487SBrian Somers *mask = MSK(LogERROR) | MSK(LogALERT) | MSK(LogWARN); 25867568487SBrian Somers LogSetMaskLocal(); 259a1e8f937SBrian Somers } 260a1e8f937SBrian Somers 261af57ed9fSAtsushi Murai int 262dd7e2610SBrian Somers log_IsKept(int id) 263af57ed9fSAtsushi Murai { 264a1e8f937SBrian Somers if (id < LogMIN || id > LogMAX) 265927145beSBrian Somers return 0; 266a1e8f937SBrian Somers if (id > LogMAXCONF) 267a1e8f937SBrian Somers return LOG_KEPT_LOCAL | LOG_KEPT_SYSLOG; 268a1e8f937SBrian Somers 269a1e8f937SBrian Somers return ((LogMaskLocal & MSK(id)) ? LOG_KEPT_LOCAL : 0) | 270a1e8f937SBrian Somers ((LogMask & MSK(id)) ? LOG_KEPT_SYSLOG : 0); 271af57ed9fSAtsushi Murai } 272af57ed9fSAtsushi Murai 273b6217683SBrian Somers int 274dd7e2610SBrian Somers log_IsKeptLocal(int id, u_long mask) 275b6217683SBrian Somers { 276b6217683SBrian Somers if (id < LogMIN || id > LogMAX) 277b6217683SBrian Somers return 0; 278b6217683SBrian Somers if (id > LogMAXCONF) 279b6217683SBrian Somers return LOG_KEPT_LOCAL | LOG_KEPT_SYSLOG; 280b6217683SBrian Somers 281b6217683SBrian Somers return ((mask & MSK(id)) ? LOG_KEPT_LOCAL : 0) | 282b6217683SBrian Somers ((LogMask & MSK(id)) ? LOG_KEPT_SYSLOG : 0); 283b6217683SBrian Somers } 284b6217683SBrian Somers 285af57ed9fSAtsushi Murai void 286dd7e2610SBrian Somers log_Open(const char *Name) 287af57ed9fSAtsushi Murai { 288927145beSBrian Somers openlog(Name, LOG_PID, LOG_DAEMON); 289af57ed9fSAtsushi Murai } 290af57ed9fSAtsushi Murai 291af57ed9fSAtsushi Murai void 292dd7e2610SBrian Somers log_SetTun(int tunno) 293af57ed9fSAtsushi Murai { 294927145beSBrian Somers LogTunno = tunno; 295af57ed9fSAtsushi Murai } 296af57ed9fSAtsushi Murai 297af57ed9fSAtsushi Murai void 298dd7e2610SBrian Somers log_Close() 299af57ed9fSAtsushi Murai { 300927145beSBrian Somers closelog(); 301927145beSBrian Somers LogTunno = -1; 3026ed9fb2fSBrian Somers } 303af57ed9fSAtsushi Murai 304af57ed9fSAtsushi Murai void 305dd7e2610SBrian Somers log_Printf(int lev, const char *fmt,...) 30653c9f6c0SAtsushi Murai { 30753c9f6c0SAtsushi Murai va_list ap; 308b6217683SBrian Somers struct prompt *prompt; 309944f7098SBrian Somers 310dd7e2610SBrian Somers if (log_IsKept(lev)) { 311d93d3a9cSBrian Somers char nfmt[200]; 31253c9f6c0SAtsushi Murai 31390d25921SBrian Somers va_start(ap, fmt); 314b4f63b0bSBrian Somers if (promptlist && (log_IsKept(lev) & LOG_KEPT_LOCAL)) { 315dd7e2610SBrian Somers if ((log_IsKept(LogTUN) & LOG_KEPT_LOCAL) && LogTunno != -1) 3161384bd27SBrian Somers snprintf(nfmt, sizeof nfmt, "%s%d: %s: %s", TUN_NAME, 317dd7e2610SBrian Somers LogTunno, log_Name(lev), fmt); 318927145beSBrian Somers else 319dd7e2610SBrian Somers snprintf(nfmt, sizeof nfmt, "%s: %s", log_Name(lev), fmt); 320b6217683SBrian Somers 321b4f63b0bSBrian Somers if (log_PromptContext && lev == LogWARN) 322b4f63b0bSBrian Somers /* Warnings just go to the current prompt */ 323b4f63b0bSBrian Somers prompt_vPrintf(log_PromptContext, nfmt, ap); 324b4f63b0bSBrian Somers else for (prompt = promptlist; prompt; prompt = prompt->next) 325b6217683SBrian Somers if (lev > LogMAXCONF || (prompt->logmask & MSK(lev))) 326b6217683SBrian Somers prompt_vPrintf(prompt, nfmt, ap); 327a1e8f937SBrian Somers } 32890d25921SBrian Somers va_end(ap); 329a1e8f937SBrian Somers 33090d25921SBrian Somers va_start(ap, fmt); 3310f2f3eb3SBrian Somers if ((log_IsKept(lev) & LOG_KEPT_SYSLOG) && 332b4f63b0bSBrian Somers (lev != LogWARN || !log_PromptContext)) { 333dd7e2610SBrian Somers if ((log_IsKept(LogTUN) & LOG_KEPT_SYSLOG) && LogTunno != -1) 3341384bd27SBrian Somers snprintf(nfmt, sizeof nfmt, "%s%d: %s: %s", TUN_NAME, 335dd7e2610SBrian Somers LogTunno, log_Name(lev), fmt); 336a1e8f937SBrian Somers else 337dd7e2610SBrian Somers snprintf(nfmt, sizeof nfmt, "%s: %s", log_Name(lev), fmt); 338927145beSBrian Somers vsyslog(syslogLevel(lev), nfmt, ap); 339927145beSBrian Somers } 34053c9f6c0SAtsushi Murai va_end(ap); 34153c9f6c0SAtsushi Murai } 34290d25921SBrian Somers } 34353c9f6c0SAtsushi Murai 34453c9f6c0SAtsushi Murai void 345dd7e2610SBrian Somers log_DumpBp(int lev, const char *hdr, const struct mbuf *bp) 346af57ed9fSAtsushi Murai { 347dd7e2610SBrian Somers if (log_IsKept(lev)) { 348ba16c840SBrian Somers char buf[68]; 349ba16c840SBrian Somers char *b, *c; 3509773f8c0SBrian Somers const u_char *ptr; 351a9e8f807SBrian Somers int f; 352a9e8f807SBrian Somers 353a9e8f807SBrian Somers if (hdr && *hdr) 354dd7e2610SBrian Somers log_Printf(lev, "%s\n", hdr); 355a9e8f807SBrian Somers 356a9e8f807SBrian Somers b = buf; 357ba16c840SBrian Somers c = b + 50; 358a9e8f807SBrian Somers do { 35926af0ae9SBrian Somers f = bp->m_len; 3609773f8c0SBrian Somers ptr = CONST_MBUF_CTOP(bp); 361a9e8f807SBrian Somers while (f--) { 362ba16c840SBrian Somers sprintf(b, " %02x", (int) *ptr); 363ba16c840SBrian Somers *c++ = isprint(*ptr) ? *ptr : '.'; 364ba16c840SBrian Somers ptr++; 365a9e8f807SBrian Somers b += 3; 366ba16c840SBrian Somers if (b == buf + 48) { 367ba16c840SBrian Somers memset(b, ' ', 2); 3689cf01ccfSBrian Somers *c = '\0'; 3699cf01ccfSBrian Somers log_Printf(lev, "%s\n", buf); 370a9e8f807SBrian Somers b = buf; 371ba16c840SBrian Somers c = b + 50; 372a9e8f807SBrian Somers } 373a9e8f807SBrian Somers } 37426af0ae9SBrian Somers } while ((bp = bp->m_next) != NULL); 375a9e8f807SBrian Somers 376a1e8f937SBrian Somers if (b > buf) { 377ba16c840SBrian Somers memset(b, ' ', 50 - (b - buf)); 3789cf01ccfSBrian Somers *c = '\0'; 3799cf01ccfSBrian Somers log_Printf(lev, "%s\n", buf); 380a9e8f807SBrian Somers } 381af57ed9fSAtsushi Murai } 382a1e8f937SBrian Somers } 383af57ed9fSAtsushi Murai 384af57ed9fSAtsushi Murai void 385dd7e2610SBrian Somers log_DumpBuff(int lev, const char *hdr, const u_char *ptr, int n) 386af57ed9fSAtsushi Murai { 387dd7e2610SBrian Somers if (log_IsKept(lev)) { 388ba16c840SBrian Somers char buf[68]; 389ba16c840SBrian Somers char *b, *c; 390af57ed9fSAtsushi Murai 391927145beSBrian Somers if (hdr && *hdr) 392dd7e2610SBrian Somers log_Printf(lev, "%s\n", hdr); 393927145beSBrian Somers while (n > 0) { 394927145beSBrian Somers b = buf; 395ba16c840SBrian Somers c = b + 50; 396ba16c840SBrian Somers for (b = buf; b != buf + 48 && n--; b += 3, ptr++) { 397ba16c840SBrian Somers sprintf(b, " %02x", (int) *ptr); 398ba16c840SBrian Somers *c++ = isprint(*ptr) ? *ptr : '.'; 399ba16c840SBrian Somers } 400ba16c840SBrian Somers memset(b, ' ', 50 - (b - buf)); 4019cf01ccfSBrian Somers *c = '\0'; 4029cf01ccfSBrian Somers log_Printf(lev, "%s\n", buf); 403af57ed9fSAtsushi Murai } 404af57ed9fSAtsushi Murai } 405c6c740beSBrian Somers } 406b6217683SBrian Somers 407b6217683SBrian Somers int 408b6217683SBrian Somers log_ShowLevel(struct cmdargs const *arg) 409b6217683SBrian Somers { 410b6217683SBrian Somers int i; 411b6217683SBrian Somers 412b6217683SBrian Somers prompt_Printf(arg->prompt, "Log: "); 413b6217683SBrian Somers for (i = LogMIN; i <= LogMAX; i++) 414dd7e2610SBrian Somers if (log_IsKept(i) & LOG_KEPT_SYSLOG) 415dd7e2610SBrian Somers prompt_Printf(arg->prompt, " %s", log_Name(i)); 416b6217683SBrian Somers 417b6217683SBrian Somers prompt_Printf(arg->prompt, "\nLocal:"); 418b6217683SBrian Somers for (i = LogMIN; i <= LogMAX; i++) 419dd7e2610SBrian Somers if (log_IsKeptLocal(i, arg->prompt->logmask) & LOG_KEPT_LOCAL) 420dd7e2610SBrian Somers prompt_Printf(arg->prompt, " %s", log_Name(i)); 421b6217683SBrian Somers 422b6217683SBrian Somers prompt_Printf(arg->prompt, "\n"); 423b6217683SBrian Somers 424b6217683SBrian Somers return 0; 425b6217683SBrian Somers } 426b6217683SBrian Somers 427b6217683SBrian Somers int 428b6217683SBrian Somers log_SetLevel(struct cmdargs const *arg) 429b6217683SBrian Somers { 430b6217683SBrian Somers int i, res, argc, local; 431b6217683SBrian Somers char const *const *argv, *argp; 432b6217683SBrian Somers 43325092092SBrian Somers argc = arg->argc - arg->argn; 43425092092SBrian Somers argv = arg->argv + arg->argn; 435b6217683SBrian Somers res = 0; 436b6217683SBrian Somers 437b6217683SBrian Somers if (argc == 0 || strcasecmp(argv[0], "local")) 438b6217683SBrian Somers local = 0; 439b6217683SBrian Somers else { 440b6217683SBrian Somers if (arg->prompt == NULL) { 4419b996792SBrian Somers log_Printf(LogWARN, "set log local: Only available on the" 4429b996792SBrian Somers " command line\n"); 443b6217683SBrian Somers return 1; 444b6217683SBrian Somers } 445b6217683SBrian Somers argc--; 446b6217683SBrian Somers argv++; 447b6217683SBrian Somers local = 1; 448b6217683SBrian Somers } 449b6217683SBrian Somers 450e43ebac1SBrian Somers if (argc == 0 || (argv[0][0] != '+' && argv[0][0] != '-')) { 451b6217683SBrian Somers if (local) 452dd7e2610SBrian Somers log_DiscardAllLocal(&arg->prompt->logmask); 453b6217683SBrian Somers else 454dd7e2610SBrian Somers log_DiscardAll(); 455e43ebac1SBrian Somers } 456b6217683SBrian Somers 457b6217683SBrian Somers while (argc--) { 458b6217683SBrian Somers argp = **argv == '+' || **argv == '-' ? *argv + 1 : *argv; 4597f03ca53SBrian Somers /* Special case 'all' */ 4607f03ca53SBrian Somers if (strcasecmp(argp, "all") == 0) { 4617f03ca53SBrian Somers if (**argv == '-') { 4627f03ca53SBrian Somers if (local) 4637f03ca53SBrian Somers for (i = LogMIN; i <= LogMAX; i++) 4647f03ca53SBrian Somers log_DiscardLocal(i, &arg->prompt->logmask); 4657f03ca53SBrian Somers else 4667f03ca53SBrian Somers for (i = LogMIN; i <= LogMAX; i++) 4677f03ca53SBrian Somers log_Discard(i); 4687f03ca53SBrian Somers } else if (local) 4697f03ca53SBrian Somers for (i = LogMIN; i <= LogMAX; i++) 4707f03ca53SBrian Somers log_KeepLocal(i, &arg->prompt->logmask); 4717f03ca53SBrian Somers else 4727f03ca53SBrian Somers for (i = LogMIN; i <= LogMAX; i++) 4737f03ca53SBrian Somers log_Keep(i); 4747f03ca53SBrian Somers argv++; 4757f03ca53SBrian Somers continue; 4767f03ca53SBrian Somers } 477b6217683SBrian Somers for (i = LogMIN; i <= LogMAX; i++) 478dd7e2610SBrian Somers if (strcasecmp(argp, log_Name(i)) == 0) { 479e43ebac1SBrian Somers if (**argv == '-') { 480b6217683SBrian Somers if (local) 481dd7e2610SBrian Somers log_DiscardLocal(i, &arg->prompt->logmask); 482b6217683SBrian Somers else 483dd7e2610SBrian Somers log_Discard(i); 484e43ebac1SBrian Somers } else if (local) 485dd7e2610SBrian Somers log_KeepLocal(i, &arg->prompt->logmask); 486b6217683SBrian Somers else 487dd7e2610SBrian Somers log_Keep(i); 488b6217683SBrian Somers break; 489b6217683SBrian Somers } 490b6217683SBrian Somers if (i > LogMAX) { 491dd7e2610SBrian Somers log_Printf(LogWARN, "%s: Invalid log value\n", argp); 492b6217683SBrian Somers res = -1; 493b6217683SBrian Somers } 494b6217683SBrian Somers argv++; 495b6217683SBrian Somers } 496b6217683SBrian Somers return res; 497b6217683SBrian Somers } 498b6217683SBrian Somers 499b6217683SBrian Somers int 500b6217683SBrian Somers log_ShowWho(struct cmdargs const *arg) 501b6217683SBrian Somers { 502b6217683SBrian Somers struct prompt *p; 503b6217683SBrian Somers 5040f2f3eb3SBrian Somers for (p = promptlist; p; p = p->next) { 505565e35e5SBrian Somers prompt_Printf(arg->prompt, "%s (%s)", p->src.type, p->src.from); 506f91ad6b0SBrian Somers if (p == arg->prompt) 507f91ad6b0SBrian Somers prompt_Printf(arg->prompt, " *"); 508f91ad6b0SBrian Somers if (!p->active) 509f91ad6b0SBrian Somers prompt_Printf(arg->prompt, " ^Z"); 510f91ad6b0SBrian Somers prompt_Printf(arg->prompt, "\n"); 511f91ad6b0SBrian Somers } 512b6217683SBrian Somers 513b6217683SBrian Somers return 0; 514b6217683SBrian Somers } 515