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 * 260f2f3eb3SBrian Somers * $Id: log.c,v 1.27 1998/05/21 21:46:25 brian Exp $ 2775240ed1SBrian Somers */ 2875240ed1SBrian Somers 292764b86aSBrian Somers #include <sys/types.h> 3075240ed1SBrian Somers 3153c9f6c0SAtsushi Murai #include <stdarg.h> 3253c9f6c0SAtsushi Murai #include <stdio.h> 3370a91e4cSBrian Somers #include <string.h> 3475240ed1SBrian Somers #include <syslog.h> 3585b542cfSBrian Somers #include <termios.h> 3675240ed1SBrian Somers 37b6e82f33SBrian Somers #include "command.h" 38927145beSBrian Somers #include "mbuf.h" 39927145beSBrian Somers #include "log.h" 4085b542cfSBrian Somers #include "descriptor.h" 4185b542cfSBrian Somers #include "prompt.h" 42af57ed9fSAtsushi Murai 43b6e82f33SBrian Somers static const char *LogNames[] = { 44927145beSBrian Somers "Async", 45cb611434SBrian Somers "CCP", 46927145beSBrian Somers "Chat", 47927145beSBrian Somers "Command", 48927145beSBrian Somers "Connect", 49927145beSBrian Somers "Debug", 50927145beSBrian Somers "HDLC", 515106c671SBrian Somers "ID0", 52cb611434SBrian Somers "IPCP", 53927145beSBrian Somers "LCP", 54927145beSBrian Somers "LQM", 55927145beSBrian Somers "Phase", 56927145beSBrian Somers "TCP/IP", 57b1ac9332SBrian Somers "Timer", 58927145beSBrian Somers "Tun", 59927145beSBrian Somers "Warning", 60927145beSBrian Somers "Error", 61927145beSBrian Somers "Alert" 62927145beSBrian Somers }; 63af57ed9fSAtsushi Murai 64927145beSBrian Somers #define MSK(n) (1<<((n)-1)) 65af57ed9fSAtsushi Murai 66d47dceb8SBrian Somers static u_long LogMask = MSK(LogPHASE); 67a1e8f937SBrian Somers static u_long LogMaskLocal = MSK(LogERROR) | MSK(LogALERT) | MSK(LogWARN); 68927145beSBrian Somers static int LogTunno = -1; 690f2f3eb3SBrian Somers static struct prompt *promptlist; /* Where to log local stuff */ 700f2f3eb3SBrian Somers 710f2f3eb3SBrian Somers struct prompt * 720f2f3eb3SBrian Somers log_PromptList() 730f2f3eb3SBrian Somers { 740f2f3eb3SBrian Somers return promptlist; 750f2f3eb3SBrian Somers } 76b6217683SBrian Somers 77b6217683SBrian Somers void 78b6217683SBrian Somers log_RegisterPrompt(struct prompt *prompt) 79b6217683SBrian Somers { 800f2f3eb3SBrian Somers prompt->next = promptlist; 810f2f3eb3SBrian Somers promptlist = prompt; 820f2f3eb3SBrian Somers prompt->active = 1; 830f2f3eb3SBrian Somers log_DiscardAllLocal(&prompt->logmask); 84b6217683SBrian Somers } 850f2f3eb3SBrian Somers 860f2f3eb3SBrian Somers void 870f2f3eb3SBrian Somers log_ActivatePrompt(struct prompt *prompt) 880f2f3eb3SBrian Somers { 890f2f3eb3SBrian Somers prompt->active = 1; 900f2f3eb3SBrian Somers LogMaskLocal |= prompt->logmask; 91b6217683SBrian Somers } 92b6217683SBrian Somers 9367568487SBrian Somers static void 9467568487SBrian Somers LogSetMaskLocal(void) 9567568487SBrian Somers { 9667568487SBrian Somers struct prompt *p; 9767568487SBrian Somers 9867568487SBrian Somers LogMaskLocal = MSK(LogERROR) | MSK(LogALERT) | MSK(LogWARN); 990f2f3eb3SBrian Somers for (p = promptlist; p; p = p->next) 10067568487SBrian Somers LogMaskLocal |= p->logmask; 10167568487SBrian Somers } 10267568487SBrian Somers 103b6217683SBrian Somers void 1040f2f3eb3SBrian Somers log_DeactivatePrompt(struct prompt *prompt) 1050f2f3eb3SBrian Somers { 1060f2f3eb3SBrian Somers if (prompt->active) { 1070f2f3eb3SBrian Somers prompt->active = 0; 1080f2f3eb3SBrian Somers LogSetMaskLocal(); 1090f2f3eb3SBrian Somers } 1100f2f3eb3SBrian Somers } 1110f2f3eb3SBrian Somers 1120f2f3eb3SBrian Somers void 113b6217683SBrian Somers log_UnRegisterPrompt(struct prompt *prompt) 114b6217683SBrian Somers { 115b6217683SBrian Somers if (prompt) { 116b6217683SBrian Somers struct prompt **p; 117b6217683SBrian Somers 1180f2f3eb3SBrian Somers for (p = &promptlist; *p; p = &(*p)->next) 119b6217683SBrian Somers if (*p == prompt) { 1200f2f3eb3SBrian Somers *p = prompt->next; 1210f2f3eb3SBrian Somers prompt->next = NULL; 122b6217683SBrian Somers break; 123b6217683SBrian Somers } 12467568487SBrian Somers LogSetMaskLocal(); 125b6217683SBrian Somers } 126b6217683SBrian Somers } 127af57ed9fSAtsushi Murai 1280f2f3eb3SBrian Somers void 1290f2f3eb3SBrian Somers log_DestroyPrompts(struct server *s) 1300f2f3eb3SBrian Somers { 1310f2f3eb3SBrian Somers struct prompt *p, *pn; 1320f2f3eb3SBrian Somers 1330f2f3eb3SBrian Somers p = promptlist; 1340f2f3eb3SBrian Somers while (p) { 1350f2f3eb3SBrian Somers pn = p->next; 1360f2f3eb3SBrian Somers if (s && p->owner != s) { 1370f2f3eb3SBrian Somers p->next = NULL; 1380f2f3eb3SBrian Somers prompt_Destroy(p, 1); 1390f2f3eb3SBrian Somers } 1400f2f3eb3SBrian Somers p = pn; 1410f2f3eb3SBrian Somers } 1420f2f3eb3SBrian Somers } 1430f2f3eb3SBrian Somers 1440f2f3eb3SBrian Somers void 1450f2f3eb3SBrian Somers log_DisplayPrompts() 1460f2f3eb3SBrian Somers { 1470f2f3eb3SBrian Somers struct prompt *p; 1480f2f3eb3SBrian Somers 1490f2f3eb3SBrian Somers for (p = promptlist; p; p = p->next) 1500f2f3eb3SBrian Somers prompt_Required(p); 1510f2f3eb3SBrian Somers } 1520f2f3eb3SBrian Somers 1530f2f3eb3SBrian Somers void 1540f2f3eb3SBrian Somers log_WritePrompts(struct datalink *dl, const char *data, int len) 1550f2f3eb3SBrian Somers { 1560f2f3eb3SBrian Somers struct prompt *p; 1570f2f3eb3SBrian Somers 1580f2f3eb3SBrian Somers for (p = promptlist; p; p = p->next) 1590f2f3eb3SBrian Somers if (prompt_IsTermMode(p, dl)) 1600f2f3eb3SBrian Somers prompt_Printf(p, "%.*s", len, data); 1610f2f3eb3SBrian Somers } 1620f2f3eb3SBrian Somers 1630f2f3eb3SBrian Somers void 1640f2f3eb3SBrian Somers log_SetTtyCommandMode(struct datalink *dl) 1650f2f3eb3SBrian Somers { 1660f2f3eb3SBrian Somers struct prompt *p; 1670f2f3eb3SBrian Somers 1680f2f3eb3SBrian Somers for (p = promptlist; p; p = p->next) 1690f2f3eb3SBrian Somers if (prompt_IsTermMode(p, dl)) 1700f2f3eb3SBrian Somers prompt_TtyCommandMode(p); 1710f2f3eb3SBrian Somers } 1720f2f3eb3SBrian Somers 173927145beSBrian Somers static int 174927145beSBrian Somers syslogLevel(int lev) 175927145beSBrian Somers { 176927145beSBrian Somers switch (lev) { 1776f384573SBrian Somers case LogDEBUG: 1786f384573SBrian Somers case LogTIMER: 1796f384573SBrian Somers return LOG_DEBUG; 180944f7098SBrian Somers case LogWARN: 181944f7098SBrian Somers return LOG_WARNING; 182944f7098SBrian Somers case LogERROR: 183944f7098SBrian Somers return LOG_ERR; 184944f7098SBrian Somers case LogALERT: 185944f7098SBrian Somers return LOG_ALERT; 186927145beSBrian Somers } 187927145beSBrian Somers return lev >= LogMIN && lev <= LogMAX ? LOG_INFO : 0; 188927145beSBrian Somers } 189af57ed9fSAtsushi Murai 190927145beSBrian Somers const char * 191dd7e2610SBrian Somers log_Name(int id) 192927145beSBrian Somers { 193927145beSBrian Somers return id < LogMIN || id > LogMAX ? "Unknown" : LogNames[id - 1]; 194927145beSBrian Somers } 195af57ed9fSAtsushi Murai 196af57ed9fSAtsushi Murai void 197dd7e2610SBrian Somers log_Keep(int id) 198af57ed9fSAtsushi Murai { 199927145beSBrian Somers if (id >= LogMIN && id <= LogMAXCONF) 200927145beSBrian Somers LogMask |= MSK(id); 201af57ed9fSAtsushi Murai } 202927145beSBrian Somers 203927145beSBrian Somers void 204dd7e2610SBrian Somers log_KeepLocal(int id, u_long *mask) 205a1e8f937SBrian Somers { 206b6217683SBrian Somers if (id >= LogMIN && id <= LogMAXCONF) { 207a1e8f937SBrian Somers LogMaskLocal |= MSK(id); 208b6217683SBrian Somers *mask |= MSK(id); 209b6217683SBrian Somers } 210a1e8f937SBrian Somers } 211a1e8f937SBrian Somers 212a1e8f937SBrian Somers void 213dd7e2610SBrian Somers log_Discard(int id) 214927145beSBrian Somers { 215927145beSBrian Somers if (id >= LogMIN && id <= LogMAXCONF) 216927145beSBrian Somers LogMask &= ~MSK(id); 217927145beSBrian Somers } 218927145beSBrian Somers 219927145beSBrian Somers void 220dd7e2610SBrian Somers log_DiscardLocal(int id, u_long *mask) 221a1e8f937SBrian Somers { 222b6217683SBrian Somers if (id >= LogMIN && id <= LogMAXCONF) { 223b6217683SBrian Somers *mask &= ~MSK(id); 22467568487SBrian Somers LogSetMaskLocal(); 225b6217683SBrian Somers } 226a1e8f937SBrian Somers } 227a1e8f937SBrian Somers 228a1e8f937SBrian Somers void 229dd7e2610SBrian Somers log_DiscardAll() 230927145beSBrian Somers { 231927145beSBrian Somers LogMask = 0; 232af57ed9fSAtsushi Murai } 233af57ed9fSAtsushi Murai 234a1e8f937SBrian Somers void 235dd7e2610SBrian Somers log_DiscardAllLocal(u_long *mask) 236a1e8f937SBrian Somers { 23767568487SBrian Somers *mask = MSK(LogERROR) | MSK(LogALERT) | MSK(LogWARN); 23867568487SBrian Somers LogSetMaskLocal(); 239a1e8f937SBrian Somers } 240a1e8f937SBrian Somers 241af57ed9fSAtsushi Murai int 242dd7e2610SBrian Somers log_IsKept(int id) 243af57ed9fSAtsushi Murai { 244a1e8f937SBrian Somers if (id < LogMIN || id > LogMAX) 245927145beSBrian Somers return 0; 246a1e8f937SBrian Somers if (id > LogMAXCONF) 247a1e8f937SBrian Somers return LOG_KEPT_LOCAL | LOG_KEPT_SYSLOG; 248a1e8f937SBrian Somers 249a1e8f937SBrian Somers return ((LogMaskLocal & MSK(id)) ? LOG_KEPT_LOCAL : 0) | 250a1e8f937SBrian Somers ((LogMask & MSK(id)) ? LOG_KEPT_SYSLOG : 0); 251af57ed9fSAtsushi Murai } 252af57ed9fSAtsushi Murai 253b6217683SBrian Somers int 254dd7e2610SBrian Somers log_IsKeptLocal(int id, u_long mask) 255b6217683SBrian Somers { 256b6217683SBrian Somers if (id < LogMIN || id > LogMAX) 257b6217683SBrian Somers return 0; 258b6217683SBrian Somers if (id > LogMAXCONF) 259b6217683SBrian Somers return LOG_KEPT_LOCAL | LOG_KEPT_SYSLOG; 260b6217683SBrian Somers 261b6217683SBrian Somers return ((mask & MSK(id)) ? LOG_KEPT_LOCAL : 0) | 262b6217683SBrian Somers ((LogMask & MSK(id)) ? LOG_KEPT_SYSLOG : 0); 263b6217683SBrian Somers } 264b6217683SBrian Somers 265af57ed9fSAtsushi Murai void 266dd7e2610SBrian Somers log_Open(const char *Name) 267af57ed9fSAtsushi Murai { 268927145beSBrian Somers openlog(Name, LOG_PID, LOG_DAEMON); 269af57ed9fSAtsushi Murai } 270af57ed9fSAtsushi Murai 271af57ed9fSAtsushi Murai void 272dd7e2610SBrian Somers log_SetTun(int tunno) 273af57ed9fSAtsushi Murai { 274927145beSBrian Somers LogTunno = tunno; 275af57ed9fSAtsushi Murai } 276af57ed9fSAtsushi Murai 277af57ed9fSAtsushi Murai void 278dd7e2610SBrian Somers log_Close() 279af57ed9fSAtsushi Murai { 280927145beSBrian Somers closelog(); 281927145beSBrian Somers LogTunno = -1; 2826ed9fb2fSBrian Somers } 283af57ed9fSAtsushi Murai 284af57ed9fSAtsushi Murai void 285dd7e2610SBrian Somers log_Printf(int lev, const char *fmt,...) 28653c9f6c0SAtsushi Murai { 28753c9f6c0SAtsushi Murai va_list ap; 288b6217683SBrian Somers struct prompt *prompt; 289944f7098SBrian Somers 290927145beSBrian Somers va_start(ap, fmt); 291dd7e2610SBrian Somers if (log_IsKept(lev)) { 292927145beSBrian Somers static char nfmt[200]; 29353c9f6c0SAtsushi Murai 2940f2f3eb3SBrian Somers if ((log_IsKept(lev) & LOG_KEPT_LOCAL) && promptlist) { 295dd7e2610SBrian Somers if ((log_IsKept(LogTUN) & LOG_KEPT_LOCAL) && LogTunno != -1) 296927145beSBrian Somers snprintf(nfmt, sizeof nfmt, "tun%d: %s: %s", 297dd7e2610SBrian Somers LogTunno, log_Name(lev), fmt); 298927145beSBrian Somers else 299dd7e2610SBrian Somers snprintf(nfmt, sizeof nfmt, "%s: %s", log_Name(lev), fmt); 300b6217683SBrian Somers 3010f2f3eb3SBrian Somers for (prompt = promptlist; prompt; prompt = prompt->next) 302b6217683SBrian Somers if (lev > LogMAXCONF || (prompt->logmask & MSK(lev))) 303b6217683SBrian Somers prompt_vPrintf(prompt, nfmt, ap); 304a1e8f937SBrian Somers } 305a1e8f937SBrian Somers 3060f2f3eb3SBrian Somers if ((log_IsKept(lev) & LOG_KEPT_SYSLOG) && 3070f2f3eb3SBrian Somers (lev != LogWARN || !promptlist)) { 308dd7e2610SBrian Somers if ((log_IsKept(LogTUN) & LOG_KEPT_SYSLOG) && LogTunno != -1) 309a1e8f937SBrian Somers snprintf(nfmt, sizeof nfmt, "tun%d: %s: %s", 310dd7e2610SBrian Somers LogTunno, log_Name(lev), fmt); 311a1e8f937SBrian Somers else 312dd7e2610SBrian Somers snprintf(nfmt, sizeof nfmt, "%s: %s", log_Name(lev), fmt); 313927145beSBrian Somers vsyslog(syslogLevel(lev), nfmt, ap); 314927145beSBrian Somers } 315a1e8f937SBrian Somers } 31653c9f6c0SAtsushi Murai va_end(ap); 31753c9f6c0SAtsushi Murai } 31853c9f6c0SAtsushi Murai 31953c9f6c0SAtsushi Murai void 320dd7e2610SBrian Somers log_DumpBp(int lev, const char *hdr, const struct mbuf * bp) 321af57ed9fSAtsushi Murai { 322dd7e2610SBrian Somers if (log_IsKept(lev)) { 323a1e8f937SBrian Somers char buf[50]; 324a9e8f807SBrian Somers char *b; 325a9e8f807SBrian Somers u_char *ptr; 326a9e8f807SBrian Somers int f; 327a9e8f807SBrian Somers 328a9e8f807SBrian Somers if (hdr && *hdr) 329dd7e2610SBrian Somers log_Printf(lev, "%s\n", hdr); 330a9e8f807SBrian Somers 331a9e8f807SBrian Somers b = buf; 332a9e8f807SBrian Somers do { 333a9e8f807SBrian Somers f = bp->cnt; 334a9e8f807SBrian Somers ptr = MBUF_CTOP(bp); 335a9e8f807SBrian Somers while (f--) { 336a9e8f807SBrian Somers sprintf(b, " %02x", (int) *ptr++); 337a9e8f807SBrian Somers b += 3; 338a1e8f937SBrian Somers if (b == buf + sizeof buf - 2) { 339a1e8f937SBrian Somers strcpy(b, "\n"); 340dd7e2610SBrian Somers log_Printf(lev, buf); 341a9e8f807SBrian Somers b = buf; 342a9e8f807SBrian Somers } 343a9e8f807SBrian Somers } 344a9e8f807SBrian Somers } while ((bp = bp->next) != NULL); 345a9e8f807SBrian Somers 346a1e8f937SBrian Somers if (b > buf) { 347a1e8f937SBrian Somers strcpy(b, "\n"); 348dd7e2610SBrian Somers log_Printf(lev, buf); 349a9e8f807SBrian Somers } 350af57ed9fSAtsushi Murai } 351a1e8f937SBrian Somers } 352af57ed9fSAtsushi Murai 353af57ed9fSAtsushi Murai void 354dd7e2610SBrian Somers log_DumpBuff(int lev, const char *hdr, const u_char * ptr, int n) 355af57ed9fSAtsushi Murai { 356dd7e2610SBrian Somers if (log_IsKept(lev)) { 357a1e8f937SBrian Somers char buf[50]; 358927145beSBrian Somers char *b; 359af57ed9fSAtsushi Murai 360927145beSBrian Somers if (hdr && *hdr) 361dd7e2610SBrian Somers log_Printf(lev, "%s\n", hdr); 362927145beSBrian Somers while (n > 0) { 363927145beSBrian Somers b = buf; 36470ee81ffSBrian Somers for (b = buf; b != buf + sizeof buf - 2 && n--; b += 3) 365927145beSBrian Somers sprintf(b, " %02x", (int) *ptr++); 366a1e8f937SBrian Somers strcpy(b, "\n"); 367dd7e2610SBrian Somers log_Printf(lev, buf); 368af57ed9fSAtsushi Murai } 369af57ed9fSAtsushi Murai } 370c6c740beSBrian Somers } 371b6217683SBrian Somers 372b6217683SBrian Somers int 373b6217683SBrian Somers log_ShowLevel(struct cmdargs const *arg) 374b6217683SBrian Somers { 375b6217683SBrian Somers int i; 376b6217683SBrian Somers 377b6217683SBrian Somers prompt_Printf(arg->prompt, "Log: "); 378b6217683SBrian Somers for (i = LogMIN; i <= LogMAX; i++) 379dd7e2610SBrian Somers if (log_IsKept(i) & LOG_KEPT_SYSLOG) 380dd7e2610SBrian Somers prompt_Printf(arg->prompt, " %s", log_Name(i)); 381b6217683SBrian Somers 382b6217683SBrian Somers prompt_Printf(arg->prompt, "\nLocal:"); 383b6217683SBrian Somers for (i = LogMIN; i <= LogMAX; i++) 384dd7e2610SBrian Somers if (log_IsKeptLocal(i, arg->prompt->logmask) & LOG_KEPT_LOCAL) 385dd7e2610SBrian Somers prompt_Printf(arg->prompt, " %s", log_Name(i)); 386b6217683SBrian Somers 387b6217683SBrian Somers prompt_Printf(arg->prompt, "\n"); 388b6217683SBrian Somers 389b6217683SBrian Somers return 0; 390b6217683SBrian Somers } 391b6217683SBrian Somers 392b6217683SBrian Somers int 393b6217683SBrian Somers log_SetLevel(struct cmdargs const *arg) 394b6217683SBrian Somers { 395b6217683SBrian Somers int i, res, argc, local; 396b6217683SBrian Somers char const *const *argv, *argp; 397b6217683SBrian Somers 39825092092SBrian Somers argc = arg->argc - arg->argn; 39925092092SBrian Somers argv = arg->argv + arg->argn; 400b6217683SBrian Somers res = 0; 401b6217683SBrian Somers 402b6217683SBrian Somers if (argc == 0 || strcasecmp(argv[0], "local")) 403b6217683SBrian Somers local = 0; 404b6217683SBrian Somers else { 405b6217683SBrian Somers if (arg->prompt == NULL) { 406dd7e2610SBrian Somers log_Printf(LogWARN, "set log local: Only available on the command line\n"); 407b6217683SBrian Somers return 1; 408b6217683SBrian Somers } 409b6217683SBrian Somers argc--; 410b6217683SBrian Somers argv++; 411b6217683SBrian Somers local = 1; 412b6217683SBrian Somers } 413b6217683SBrian Somers 414e43ebac1SBrian Somers if (argc == 0 || (argv[0][0] != '+' && argv[0][0] != '-')) { 415b6217683SBrian Somers if (local) 416dd7e2610SBrian Somers log_DiscardAllLocal(&arg->prompt->logmask); 417b6217683SBrian Somers else 418dd7e2610SBrian Somers log_DiscardAll(); 419e43ebac1SBrian Somers } 420b6217683SBrian Somers 421b6217683SBrian Somers while (argc--) { 422b6217683SBrian Somers argp = **argv == '+' || **argv == '-' ? *argv + 1 : *argv; 423b6217683SBrian Somers for (i = LogMIN; i <= LogMAX; i++) 424dd7e2610SBrian Somers if (strcasecmp(argp, log_Name(i)) == 0) { 425e43ebac1SBrian Somers if (**argv == '-') { 426b6217683SBrian Somers if (local) 427dd7e2610SBrian Somers log_DiscardLocal(i, &arg->prompt->logmask); 428b6217683SBrian Somers else 429dd7e2610SBrian Somers log_Discard(i); 430e43ebac1SBrian Somers } else if (local) 431dd7e2610SBrian Somers log_KeepLocal(i, &arg->prompt->logmask); 432b6217683SBrian Somers else 433dd7e2610SBrian Somers log_Keep(i); 434b6217683SBrian Somers break; 435b6217683SBrian Somers } 436b6217683SBrian Somers if (i > LogMAX) { 437dd7e2610SBrian Somers log_Printf(LogWARN, "%s: Invalid log value\n", argp); 438b6217683SBrian Somers res = -1; 439b6217683SBrian Somers } 440b6217683SBrian Somers argv++; 441b6217683SBrian Somers } 442b6217683SBrian Somers return res; 443b6217683SBrian Somers } 444b6217683SBrian Somers 445b6217683SBrian Somers int 446b6217683SBrian Somers log_ShowWho(struct cmdargs const *arg) 447b6217683SBrian Somers { 448b6217683SBrian Somers struct prompt *p; 449b6217683SBrian Somers 4500f2f3eb3SBrian Somers for (p = promptlist; p; p = p->next) { 451565e35e5SBrian Somers prompt_Printf(arg->prompt, "%s (%s)", p->src.type, p->src.from); 452f91ad6b0SBrian Somers if (p == arg->prompt) 453f91ad6b0SBrian Somers prompt_Printf(arg->prompt, " *"); 454f91ad6b0SBrian Somers if (!p->active) 455f91ad6b0SBrian Somers prompt_Printf(arg->prompt, " ^Z"); 456f91ad6b0SBrian Somers prompt_Printf(arg->prompt, "\n"); 457f91ad6b0SBrian Somers } 458b6217683SBrian Somers 459b6217683SBrian Somers return 0; 460b6217683SBrian Somers } 461