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", 54927145beSBrian Somers "HDLC", 555106c671SBrian Somers "ID0", 56cb611434SBrian Somers "IPCP", 57927145beSBrian Somers "LCP", 58927145beSBrian Somers "LQM", 59927145beSBrian Somers "Phase", 606815097bSBrian Somers "Physical", 616815097bSBrian Somers "Sync", 62927145beSBrian Somers "TCP/IP", 63b1ac9332SBrian Somers "Timer", 64927145beSBrian Somers "Tun", 65927145beSBrian Somers "Warning", 66927145beSBrian Somers "Error", 67927145beSBrian Somers "Alert" 68927145beSBrian Somers }; 69af57ed9fSAtsushi Murai 70927145beSBrian Somers #define MSK(n) (1<<((n)-1)) 71af57ed9fSAtsushi Murai 72d47dceb8SBrian Somers static u_long LogMask = MSK(LogPHASE); 73a1e8f937SBrian Somers static u_long LogMaskLocal = MSK(LogERROR) | MSK(LogALERT) | MSK(LogWARN); 74927145beSBrian Somers static int LogTunno = -1; 750f2f3eb3SBrian Somers static struct prompt *promptlist; /* Where to log local stuff */ 76b4f63b0bSBrian Somers struct prompt *log_PromptContext; 770bdcbcbeSBrian Somers int log_PromptListChanged; 780f2f3eb3SBrian Somers 790f2f3eb3SBrian Somers struct prompt * 800f2f3eb3SBrian Somers log_PromptList() 810f2f3eb3SBrian Somers { 820f2f3eb3SBrian Somers return promptlist; 830f2f3eb3SBrian Somers } 84b6217683SBrian Somers 85b6217683SBrian Somers void 86b6217683SBrian Somers log_RegisterPrompt(struct prompt *prompt) 87b6217683SBrian Somers { 880f2f3eb3SBrian Somers prompt->next = promptlist; 890f2f3eb3SBrian Somers promptlist = prompt; 900f2f3eb3SBrian Somers prompt->active = 1; 910f2f3eb3SBrian Somers log_DiscardAllLocal(&prompt->logmask); 92b6217683SBrian Somers } 930f2f3eb3SBrian Somers 940f2f3eb3SBrian Somers void 950f2f3eb3SBrian Somers log_ActivatePrompt(struct prompt *prompt) 960f2f3eb3SBrian Somers { 970f2f3eb3SBrian Somers prompt->active = 1; 980f2f3eb3SBrian Somers LogMaskLocal |= prompt->logmask; 99b6217683SBrian Somers } 100b6217683SBrian Somers 10167568487SBrian Somers static void 10267568487SBrian Somers LogSetMaskLocal(void) 10367568487SBrian Somers { 10467568487SBrian Somers struct prompt *p; 10567568487SBrian Somers 10667568487SBrian Somers LogMaskLocal = MSK(LogERROR) | MSK(LogALERT) | MSK(LogWARN); 1070f2f3eb3SBrian Somers for (p = promptlist; p; p = p->next) 10867568487SBrian Somers LogMaskLocal |= p->logmask; 10967568487SBrian Somers } 11067568487SBrian Somers 111b6217683SBrian Somers void 1120f2f3eb3SBrian Somers log_DeactivatePrompt(struct prompt *prompt) 1130f2f3eb3SBrian Somers { 1140f2f3eb3SBrian Somers if (prompt->active) { 1150f2f3eb3SBrian Somers prompt->active = 0; 1160f2f3eb3SBrian Somers LogSetMaskLocal(); 1170f2f3eb3SBrian Somers } 1180f2f3eb3SBrian Somers } 1190f2f3eb3SBrian Somers 1200f2f3eb3SBrian Somers void 121b6217683SBrian Somers log_UnRegisterPrompt(struct prompt *prompt) 122b6217683SBrian Somers { 123b6217683SBrian Somers if (prompt) { 124b6217683SBrian Somers struct prompt **p; 125b6217683SBrian Somers 1260f2f3eb3SBrian Somers for (p = &promptlist; *p; p = &(*p)->next) 127b6217683SBrian Somers if (*p == prompt) { 1280f2f3eb3SBrian Somers *p = prompt->next; 1290f2f3eb3SBrian Somers prompt->next = NULL; 130b6217683SBrian Somers break; 131b6217683SBrian Somers } 13267568487SBrian Somers LogSetMaskLocal(); 1330bdcbcbeSBrian Somers log_PromptListChanged++; 134b6217683SBrian Somers } 135b6217683SBrian Somers } 136af57ed9fSAtsushi Murai 1370f2f3eb3SBrian Somers void 1380f2f3eb3SBrian Somers log_DestroyPrompts(struct server *s) 1390f2f3eb3SBrian Somers { 140a39fd214SBrian Somers struct prompt *p, *pn, *pl; 1410f2f3eb3SBrian Somers 1420f2f3eb3SBrian Somers p = promptlist; 143a39fd214SBrian Somers pl = NULL; 1440f2f3eb3SBrian Somers while (p) { 1450f2f3eb3SBrian Somers pn = p->next; 146a39fd214SBrian Somers if (s && p->owner == s) { 147a39fd214SBrian Somers if (pl) 148a39fd214SBrian Somers pl->next = p->next; 149a39fd214SBrian Somers else 150a39fd214SBrian Somers promptlist = p->next; 1510f2f3eb3SBrian Somers p->next = NULL; 1520f2f3eb3SBrian Somers prompt_Destroy(p, 1); 153a39fd214SBrian Somers } else 154a39fd214SBrian Somers pl = p; 1550f2f3eb3SBrian Somers p = pn; 1560f2f3eb3SBrian Somers } 1570f2f3eb3SBrian Somers } 1580f2f3eb3SBrian Somers 1590f2f3eb3SBrian Somers void 1600f2f3eb3SBrian Somers log_DisplayPrompts() 1610f2f3eb3SBrian Somers { 1620f2f3eb3SBrian Somers struct prompt *p; 1630f2f3eb3SBrian Somers 1640f2f3eb3SBrian Somers for (p = promptlist; p; p = p->next) 1650f2f3eb3SBrian Somers prompt_Required(p); 1660f2f3eb3SBrian Somers } 1670f2f3eb3SBrian Somers 1680f2f3eb3SBrian Somers void 169bf1d3ff6SBrian Somers log_WritePrompts(struct datalink *dl, const char *fmt,...) 1700f2f3eb3SBrian Somers { 171bf1d3ff6SBrian Somers va_list ap; 1720f2f3eb3SBrian Somers struct prompt *p; 1730f2f3eb3SBrian Somers 174bf1d3ff6SBrian Somers va_start(ap, fmt); 1750f2f3eb3SBrian Somers for (p = promptlist; p; p = p->next) 1760f2f3eb3SBrian Somers if (prompt_IsTermMode(p, dl)) 177bf1d3ff6SBrian Somers prompt_vPrintf(p, fmt, ap); 178bf1d3ff6SBrian Somers va_end(ap); 1790f2f3eb3SBrian Somers } 1800f2f3eb3SBrian Somers 1810f2f3eb3SBrian Somers void 1820f2f3eb3SBrian Somers log_SetTtyCommandMode(struct datalink *dl) 1830f2f3eb3SBrian Somers { 1840f2f3eb3SBrian Somers struct prompt *p; 1850f2f3eb3SBrian Somers 1860f2f3eb3SBrian Somers for (p = promptlist; p; p = p->next) 1870f2f3eb3SBrian Somers if (prompt_IsTermMode(p, dl)) 1880f2f3eb3SBrian Somers prompt_TtyCommandMode(p); 1890f2f3eb3SBrian Somers } 1900f2f3eb3SBrian Somers 191927145beSBrian Somers static int 192927145beSBrian Somers syslogLevel(int lev) 193927145beSBrian Somers { 194927145beSBrian Somers switch (lev) { 1956f384573SBrian Somers case LogDEBUG: 1966f384573SBrian Somers case LogTIMER: 1976f384573SBrian Somers return LOG_DEBUG; 198944f7098SBrian Somers case LogWARN: 199944f7098SBrian Somers return LOG_WARNING; 200944f7098SBrian Somers case LogERROR: 201944f7098SBrian Somers return LOG_ERR; 202944f7098SBrian Somers case LogALERT: 203944f7098SBrian Somers return LOG_ALERT; 204927145beSBrian Somers } 205927145beSBrian Somers return lev >= LogMIN && lev <= LogMAX ? LOG_INFO : 0; 206927145beSBrian Somers } 207af57ed9fSAtsushi Murai 208927145beSBrian Somers const char * 209dd7e2610SBrian Somers log_Name(int id) 210927145beSBrian Somers { 211927145beSBrian Somers return id < LogMIN || id > LogMAX ? "Unknown" : LogNames[id - 1]; 212927145beSBrian Somers } 213af57ed9fSAtsushi Murai 214af57ed9fSAtsushi Murai void 215dd7e2610SBrian Somers log_Keep(int id) 216af57ed9fSAtsushi Murai { 217927145beSBrian Somers if (id >= LogMIN && id <= LogMAXCONF) 218927145beSBrian Somers LogMask |= MSK(id); 219af57ed9fSAtsushi Murai } 220927145beSBrian Somers 221927145beSBrian Somers void 222dd7e2610SBrian Somers log_KeepLocal(int id, u_long *mask) 223a1e8f937SBrian Somers { 224b6217683SBrian Somers if (id >= LogMIN && id <= LogMAXCONF) { 225a1e8f937SBrian Somers LogMaskLocal |= MSK(id); 226b6217683SBrian Somers *mask |= MSK(id); 227b6217683SBrian Somers } 228a1e8f937SBrian Somers } 229a1e8f937SBrian Somers 230a1e8f937SBrian Somers void 231dd7e2610SBrian Somers log_Discard(int id) 232927145beSBrian Somers { 233927145beSBrian Somers if (id >= LogMIN && id <= LogMAXCONF) 234927145beSBrian Somers LogMask &= ~MSK(id); 235927145beSBrian Somers } 236927145beSBrian Somers 237927145beSBrian Somers void 238dd7e2610SBrian Somers log_DiscardLocal(int id, u_long *mask) 239a1e8f937SBrian Somers { 240b6217683SBrian Somers if (id >= LogMIN && id <= LogMAXCONF) { 241b6217683SBrian Somers *mask &= ~MSK(id); 24267568487SBrian Somers LogSetMaskLocal(); 243b6217683SBrian Somers } 244a1e8f937SBrian Somers } 245a1e8f937SBrian Somers 246a1e8f937SBrian Somers void 247dd7e2610SBrian Somers log_DiscardAll() 248927145beSBrian Somers { 249927145beSBrian Somers LogMask = 0; 250af57ed9fSAtsushi Murai } 251af57ed9fSAtsushi Murai 252a1e8f937SBrian Somers void 253dd7e2610SBrian Somers log_DiscardAllLocal(u_long *mask) 254a1e8f937SBrian Somers { 25567568487SBrian Somers *mask = MSK(LogERROR) | MSK(LogALERT) | MSK(LogWARN); 25667568487SBrian Somers LogSetMaskLocal(); 257a1e8f937SBrian Somers } 258a1e8f937SBrian Somers 259af57ed9fSAtsushi Murai int 260dd7e2610SBrian Somers log_IsKept(int id) 261af57ed9fSAtsushi Murai { 262a1e8f937SBrian Somers if (id < LogMIN || id > LogMAX) 263927145beSBrian Somers return 0; 264a1e8f937SBrian Somers if (id > LogMAXCONF) 265a1e8f937SBrian Somers return LOG_KEPT_LOCAL | LOG_KEPT_SYSLOG; 266a1e8f937SBrian Somers 267a1e8f937SBrian Somers return ((LogMaskLocal & MSK(id)) ? LOG_KEPT_LOCAL : 0) | 268a1e8f937SBrian Somers ((LogMask & MSK(id)) ? LOG_KEPT_SYSLOG : 0); 269af57ed9fSAtsushi Murai } 270af57ed9fSAtsushi Murai 271b6217683SBrian Somers int 272dd7e2610SBrian Somers log_IsKeptLocal(int id, u_long mask) 273b6217683SBrian Somers { 274b6217683SBrian Somers if (id < LogMIN || id > LogMAX) 275b6217683SBrian Somers return 0; 276b6217683SBrian Somers if (id > LogMAXCONF) 277b6217683SBrian Somers return LOG_KEPT_LOCAL | LOG_KEPT_SYSLOG; 278b6217683SBrian Somers 279b6217683SBrian Somers return ((mask & MSK(id)) ? LOG_KEPT_LOCAL : 0) | 280b6217683SBrian Somers ((LogMask & MSK(id)) ? LOG_KEPT_SYSLOG : 0); 281b6217683SBrian Somers } 282b6217683SBrian Somers 283af57ed9fSAtsushi Murai void 284dd7e2610SBrian Somers log_Open(const char *Name) 285af57ed9fSAtsushi Murai { 286927145beSBrian Somers openlog(Name, LOG_PID, LOG_DAEMON); 287af57ed9fSAtsushi Murai } 288af57ed9fSAtsushi Murai 289af57ed9fSAtsushi Murai void 290dd7e2610SBrian Somers log_SetTun(int tunno) 291af57ed9fSAtsushi Murai { 292927145beSBrian Somers LogTunno = tunno; 293af57ed9fSAtsushi Murai } 294af57ed9fSAtsushi Murai 295af57ed9fSAtsushi Murai void 296dd7e2610SBrian Somers log_Close() 297af57ed9fSAtsushi Murai { 298927145beSBrian Somers closelog(); 299927145beSBrian Somers LogTunno = -1; 3006ed9fb2fSBrian Somers } 301af57ed9fSAtsushi Murai 302af57ed9fSAtsushi Murai void 303dd7e2610SBrian Somers log_Printf(int lev, const char *fmt,...) 30453c9f6c0SAtsushi Murai { 30553c9f6c0SAtsushi Murai va_list ap; 306b6217683SBrian Somers struct prompt *prompt; 307944f7098SBrian Somers 308927145beSBrian Somers va_start(ap, fmt); 309dd7e2610SBrian Somers if (log_IsKept(lev)) { 310d93d3a9cSBrian Somers char nfmt[200]; 31153c9f6c0SAtsushi Murai 312b4f63b0bSBrian Somers if (promptlist && (log_IsKept(lev) & LOG_KEPT_LOCAL)) { 313dd7e2610SBrian Somers if ((log_IsKept(LogTUN) & LOG_KEPT_LOCAL) && LogTunno != -1) 3141384bd27SBrian Somers snprintf(nfmt, sizeof nfmt, "%s%d: %s: %s", TUN_NAME, 315dd7e2610SBrian Somers LogTunno, log_Name(lev), fmt); 316927145beSBrian Somers else 317dd7e2610SBrian Somers snprintf(nfmt, sizeof nfmt, "%s: %s", log_Name(lev), fmt); 318b6217683SBrian Somers 319b4f63b0bSBrian Somers if (log_PromptContext && lev == LogWARN) 320b4f63b0bSBrian Somers /* Warnings just go to the current prompt */ 321b4f63b0bSBrian Somers prompt_vPrintf(log_PromptContext, nfmt, ap); 322b4f63b0bSBrian Somers else for (prompt = promptlist; prompt; prompt = prompt->next) 323b6217683SBrian Somers if (lev > LogMAXCONF || (prompt->logmask & MSK(lev))) 324b6217683SBrian Somers prompt_vPrintf(prompt, nfmt, ap); 325a1e8f937SBrian Somers } 326a1e8f937SBrian Somers 3270f2f3eb3SBrian Somers if ((log_IsKept(lev) & LOG_KEPT_SYSLOG) && 328b4f63b0bSBrian Somers (lev != LogWARN || !log_PromptContext)) { 329dd7e2610SBrian Somers if ((log_IsKept(LogTUN) & LOG_KEPT_SYSLOG) && LogTunno != -1) 3301384bd27SBrian Somers snprintf(nfmt, sizeof nfmt, "%s%d: %s: %s", TUN_NAME, 331dd7e2610SBrian Somers LogTunno, log_Name(lev), fmt); 332a1e8f937SBrian Somers else 333dd7e2610SBrian Somers snprintf(nfmt, sizeof nfmt, "%s: %s", log_Name(lev), fmt); 334927145beSBrian Somers vsyslog(syslogLevel(lev), nfmt, ap); 335927145beSBrian Somers } 336a1e8f937SBrian Somers } 33753c9f6c0SAtsushi Murai va_end(ap); 33853c9f6c0SAtsushi Murai } 33953c9f6c0SAtsushi Murai 34053c9f6c0SAtsushi Murai void 341dd7e2610SBrian Somers log_DumpBp(int lev, const char *hdr, const struct mbuf *bp) 342af57ed9fSAtsushi Murai { 343dd7e2610SBrian Somers if (log_IsKept(lev)) { 344ba16c840SBrian Somers char buf[68]; 345ba16c840SBrian Somers char *b, *c; 3469773f8c0SBrian Somers const u_char *ptr; 347a9e8f807SBrian Somers int f; 348a9e8f807SBrian Somers 349a9e8f807SBrian Somers if (hdr && *hdr) 350dd7e2610SBrian Somers log_Printf(lev, "%s\n", hdr); 351a9e8f807SBrian Somers 352a9e8f807SBrian Somers b = buf; 353ba16c840SBrian Somers c = b + 50; 354a9e8f807SBrian Somers do { 35526af0ae9SBrian Somers f = bp->m_len; 3569773f8c0SBrian Somers ptr = CONST_MBUF_CTOP(bp); 357a9e8f807SBrian Somers while (f--) { 358ba16c840SBrian Somers sprintf(b, " %02x", (int) *ptr); 359ba16c840SBrian Somers *c++ = isprint(*ptr) ? *ptr : '.'; 360ba16c840SBrian Somers ptr++; 361a9e8f807SBrian Somers b += 3; 362ba16c840SBrian Somers if (b == buf + 48) { 363ba16c840SBrian Somers memset(b, ' ', 2); 3649cf01ccfSBrian Somers *c = '\0'; 3659cf01ccfSBrian Somers log_Printf(lev, "%s\n", buf); 366a9e8f807SBrian Somers b = buf; 367ba16c840SBrian Somers c = b + 50; 368a9e8f807SBrian Somers } 369a9e8f807SBrian Somers } 37026af0ae9SBrian Somers } while ((bp = bp->m_next) != NULL); 371a9e8f807SBrian Somers 372a1e8f937SBrian Somers if (b > buf) { 373ba16c840SBrian Somers memset(b, ' ', 50 - (b - buf)); 3749cf01ccfSBrian Somers *c = '\0'; 3759cf01ccfSBrian Somers log_Printf(lev, "%s\n", buf); 376a9e8f807SBrian Somers } 377af57ed9fSAtsushi Murai } 378a1e8f937SBrian Somers } 379af57ed9fSAtsushi Murai 380af57ed9fSAtsushi Murai void 381dd7e2610SBrian Somers log_DumpBuff(int lev, const char *hdr, const u_char *ptr, int n) 382af57ed9fSAtsushi Murai { 383dd7e2610SBrian Somers if (log_IsKept(lev)) { 384ba16c840SBrian Somers char buf[68]; 385ba16c840SBrian Somers char *b, *c; 386af57ed9fSAtsushi Murai 387927145beSBrian Somers if (hdr && *hdr) 388dd7e2610SBrian Somers log_Printf(lev, "%s\n", hdr); 389927145beSBrian Somers while (n > 0) { 390927145beSBrian Somers b = buf; 391ba16c840SBrian Somers c = b + 50; 392ba16c840SBrian Somers for (b = buf; b != buf + 48 && n--; b += 3, ptr++) { 393ba16c840SBrian Somers sprintf(b, " %02x", (int) *ptr); 394ba16c840SBrian Somers *c++ = isprint(*ptr) ? *ptr : '.'; 395ba16c840SBrian Somers } 396ba16c840SBrian Somers memset(b, ' ', 50 - (b - buf)); 3979cf01ccfSBrian Somers *c = '\0'; 3989cf01ccfSBrian Somers log_Printf(lev, "%s\n", buf); 399af57ed9fSAtsushi Murai } 400af57ed9fSAtsushi Murai } 401c6c740beSBrian Somers } 402b6217683SBrian Somers 403b6217683SBrian Somers int 404b6217683SBrian Somers log_ShowLevel(struct cmdargs const *arg) 405b6217683SBrian Somers { 406b6217683SBrian Somers int i; 407b6217683SBrian Somers 408b6217683SBrian Somers prompt_Printf(arg->prompt, "Log: "); 409b6217683SBrian Somers for (i = LogMIN; i <= LogMAX; i++) 410dd7e2610SBrian Somers if (log_IsKept(i) & LOG_KEPT_SYSLOG) 411dd7e2610SBrian Somers prompt_Printf(arg->prompt, " %s", log_Name(i)); 412b6217683SBrian Somers 413b6217683SBrian Somers prompt_Printf(arg->prompt, "\nLocal:"); 414b6217683SBrian Somers for (i = LogMIN; i <= LogMAX; i++) 415dd7e2610SBrian Somers if (log_IsKeptLocal(i, arg->prompt->logmask) & LOG_KEPT_LOCAL) 416dd7e2610SBrian Somers prompt_Printf(arg->prompt, " %s", log_Name(i)); 417b6217683SBrian Somers 418b6217683SBrian Somers prompt_Printf(arg->prompt, "\n"); 419b6217683SBrian Somers 420b6217683SBrian Somers return 0; 421b6217683SBrian Somers } 422b6217683SBrian Somers 423b6217683SBrian Somers int 424b6217683SBrian Somers log_SetLevel(struct cmdargs const *arg) 425b6217683SBrian Somers { 426b6217683SBrian Somers int i, res, argc, local; 427b6217683SBrian Somers char const *const *argv, *argp; 428b6217683SBrian Somers 42925092092SBrian Somers argc = arg->argc - arg->argn; 43025092092SBrian Somers argv = arg->argv + arg->argn; 431b6217683SBrian Somers res = 0; 432b6217683SBrian Somers 433b6217683SBrian Somers if (argc == 0 || strcasecmp(argv[0], "local")) 434b6217683SBrian Somers local = 0; 435b6217683SBrian Somers else { 436b6217683SBrian Somers if (arg->prompt == NULL) { 437dd7e2610SBrian Somers log_Printf(LogWARN, "set log local: Only available on the command line\n"); 438b6217683SBrian Somers return 1; 439b6217683SBrian Somers } 440b6217683SBrian Somers argc--; 441b6217683SBrian Somers argv++; 442b6217683SBrian Somers local = 1; 443b6217683SBrian Somers } 444b6217683SBrian Somers 445e43ebac1SBrian Somers if (argc == 0 || (argv[0][0] != '+' && argv[0][0] != '-')) { 446b6217683SBrian Somers if (local) 447dd7e2610SBrian Somers log_DiscardAllLocal(&arg->prompt->logmask); 448b6217683SBrian Somers else 449dd7e2610SBrian Somers log_DiscardAll(); 450e43ebac1SBrian Somers } 451b6217683SBrian Somers 452b6217683SBrian Somers while (argc--) { 453b6217683SBrian Somers argp = **argv == '+' || **argv == '-' ? *argv + 1 : *argv; 454b6217683SBrian Somers for (i = LogMIN; i <= LogMAX; i++) 455dd7e2610SBrian Somers if (strcasecmp(argp, log_Name(i)) == 0) { 456e43ebac1SBrian Somers if (**argv == '-') { 457b6217683SBrian Somers if (local) 458dd7e2610SBrian Somers log_DiscardLocal(i, &arg->prompt->logmask); 459b6217683SBrian Somers else 460dd7e2610SBrian Somers log_Discard(i); 461e43ebac1SBrian Somers } else if (local) 462dd7e2610SBrian Somers log_KeepLocal(i, &arg->prompt->logmask); 463b6217683SBrian Somers else 464dd7e2610SBrian Somers log_Keep(i); 465b6217683SBrian Somers break; 466b6217683SBrian Somers } 467b6217683SBrian Somers if (i > LogMAX) { 468dd7e2610SBrian Somers log_Printf(LogWARN, "%s: Invalid log value\n", argp); 469b6217683SBrian Somers res = -1; 470b6217683SBrian Somers } 471b6217683SBrian Somers argv++; 472b6217683SBrian Somers } 473b6217683SBrian Somers return res; 474b6217683SBrian Somers } 475b6217683SBrian Somers 476b6217683SBrian Somers int 477b6217683SBrian Somers log_ShowWho(struct cmdargs const *arg) 478b6217683SBrian Somers { 479b6217683SBrian Somers struct prompt *p; 480b6217683SBrian Somers 4810f2f3eb3SBrian Somers for (p = promptlist; p; p = p->next) { 482565e35e5SBrian Somers prompt_Printf(arg->prompt, "%s (%s)", p->src.type, p->src.from); 483f91ad6b0SBrian Somers if (p == arg->prompt) 484f91ad6b0SBrian Somers prompt_Printf(arg->prompt, " *"); 485f91ad6b0SBrian Somers if (!p->active) 486f91ad6b0SBrian Somers prompt_Printf(arg->prompt, " ^Z"); 487f91ad6b0SBrian Somers prompt_Printf(arg->prompt, "\n"); 488f91ad6b0SBrian Somers } 489b6217683SBrian Somers 490b6217683SBrian Somers return 0; 491b6217683SBrian Somers } 492