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 * 2692b09558SBrian Somers * $Id: log.c,v 1.32 1998/08/02 13:01:15 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 37c9e11a11SBrian Somers #include "defs.h" 38b6e82f33SBrian Somers #include "command.h" 39927145beSBrian Somers #include "mbuf.h" 40927145beSBrian Somers #include "log.h" 4185b542cfSBrian Somers #include "descriptor.h" 4285b542cfSBrian Somers #include "prompt.h" 43af57ed9fSAtsushi Murai 44b6e82f33SBrian Somers static const char *LogNames[] = { 45927145beSBrian Somers "Async", 4692b09558SBrian Somers "CBCP", 47cb611434SBrian Somers "CCP", 48927145beSBrian Somers "Chat", 49927145beSBrian Somers "Command", 50927145beSBrian Somers "Connect", 51927145beSBrian Somers "Debug", 52927145beSBrian Somers "HDLC", 535106c671SBrian Somers "ID0", 54cb611434SBrian Somers "IPCP", 55927145beSBrian Somers "LCP", 56927145beSBrian Somers "LQM", 57927145beSBrian Somers "Phase", 58927145beSBrian Somers "TCP/IP", 59b1ac9332SBrian Somers "Timer", 60927145beSBrian Somers "Tun", 61927145beSBrian Somers "Warning", 62927145beSBrian Somers "Error", 63927145beSBrian Somers "Alert" 64927145beSBrian Somers }; 65af57ed9fSAtsushi Murai 66927145beSBrian Somers #define MSK(n) (1<<((n)-1)) 67af57ed9fSAtsushi Murai 68d47dceb8SBrian Somers static u_long LogMask = MSK(LogPHASE); 69a1e8f937SBrian Somers static u_long LogMaskLocal = MSK(LogERROR) | MSK(LogALERT) | MSK(LogWARN); 70927145beSBrian Somers static int LogTunno = -1; 710f2f3eb3SBrian Somers static struct prompt *promptlist; /* Where to log local stuff */ 720bdcbcbeSBrian Somers int log_PromptListChanged; 730f2f3eb3SBrian Somers 740f2f3eb3SBrian Somers struct prompt * 750f2f3eb3SBrian Somers log_PromptList() 760f2f3eb3SBrian Somers { 770f2f3eb3SBrian Somers return promptlist; 780f2f3eb3SBrian Somers } 79b6217683SBrian Somers 80b6217683SBrian Somers void 81b6217683SBrian Somers log_RegisterPrompt(struct prompt *prompt) 82b6217683SBrian Somers { 830f2f3eb3SBrian Somers prompt->next = promptlist; 840f2f3eb3SBrian Somers promptlist = prompt; 850f2f3eb3SBrian Somers prompt->active = 1; 860f2f3eb3SBrian Somers log_DiscardAllLocal(&prompt->logmask); 87b6217683SBrian Somers } 880f2f3eb3SBrian Somers 890f2f3eb3SBrian Somers void 900f2f3eb3SBrian Somers log_ActivatePrompt(struct prompt *prompt) 910f2f3eb3SBrian Somers { 920f2f3eb3SBrian Somers prompt->active = 1; 930f2f3eb3SBrian Somers LogMaskLocal |= prompt->logmask; 94b6217683SBrian Somers } 95b6217683SBrian Somers 9667568487SBrian Somers static void 9767568487SBrian Somers LogSetMaskLocal(void) 9867568487SBrian Somers { 9967568487SBrian Somers struct prompt *p; 10067568487SBrian Somers 10167568487SBrian Somers LogMaskLocal = MSK(LogERROR) | MSK(LogALERT) | MSK(LogWARN); 1020f2f3eb3SBrian Somers for (p = promptlist; p; p = p->next) 10367568487SBrian Somers LogMaskLocal |= p->logmask; 10467568487SBrian Somers } 10567568487SBrian Somers 106b6217683SBrian Somers void 1070f2f3eb3SBrian Somers log_DeactivatePrompt(struct prompt *prompt) 1080f2f3eb3SBrian Somers { 1090f2f3eb3SBrian Somers if (prompt->active) { 1100f2f3eb3SBrian Somers prompt->active = 0; 1110f2f3eb3SBrian Somers LogSetMaskLocal(); 1120f2f3eb3SBrian Somers } 1130f2f3eb3SBrian Somers } 1140f2f3eb3SBrian Somers 1150f2f3eb3SBrian Somers void 116b6217683SBrian Somers log_UnRegisterPrompt(struct prompt *prompt) 117b6217683SBrian Somers { 118b6217683SBrian Somers if (prompt) { 119b6217683SBrian Somers struct prompt **p; 120b6217683SBrian Somers 1210f2f3eb3SBrian Somers for (p = &promptlist; *p; p = &(*p)->next) 122b6217683SBrian Somers if (*p == prompt) { 1230f2f3eb3SBrian Somers *p = prompt->next; 1240f2f3eb3SBrian Somers prompt->next = NULL; 125b6217683SBrian Somers break; 126b6217683SBrian Somers } 12767568487SBrian Somers LogSetMaskLocal(); 1280bdcbcbeSBrian Somers log_PromptListChanged++; 129b6217683SBrian Somers } 130b6217683SBrian Somers } 131af57ed9fSAtsushi Murai 1320f2f3eb3SBrian Somers void 1330f2f3eb3SBrian Somers log_DestroyPrompts(struct server *s) 1340f2f3eb3SBrian Somers { 1350f2f3eb3SBrian Somers struct prompt *p, *pn; 1360f2f3eb3SBrian Somers 1370f2f3eb3SBrian Somers p = promptlist; 1380f2f3eb3SBrian Somers while (p) { 1390f2f3eb3SBrian Somers pn = p->next; 1400f2f3eb3SBrian Somers if (s && p->owner != s) { 1410f2f3eb3SBrian Somers p->next = NULL; 1420f2f3eb3SBrian Somers prompt_Destroy(p, 1); 1430f2f3eb3SBrian Somers } 1440f2f3eb3SBrian Somers p = pn; 1450f2f3eb3SBrian Somers } 1460f2f3eb3SBrian Somers } 1470f2f3eb3SBrian Somers 1480f2f3eb3SBrian Somers void 1490f2f3eb3SBrian Somers log_DisplayPrompts() 1500f2f3eb3SBrian Somers { 1510f2f3eb3SBrian Somers struct prompt *p; 1520f2f3eb3SBrian Somers 1530f2f3eb3SBrian Somers for (p = promptlist; p; p = p->next) 1540f2f3eb3SBrian Somers prompt_Required(p); 1550f2f3eb3SBrian Somers } 1560f2f3eb3SBrian Somers 1570f2f3eb3SBrian Somers void 1580f2f3eb3SBrian Somers log_WritePrompts(struct datalink *dl, const char *data, int len) 1590f2f3eb3SBrian Somers { 1600f2f3eb3SBrian Somers struct prompt *p; 1610f2f3eb3SBrian Somers 1620f2f3eb3SBrian Somers for (p = promptlist; p; p = p->next) 1630f2f3eb3SBrian Somers if (prompt_IsTermMode(p, dl)) 1640f2f3eb3SBrian Somers prompt_Printf(p, "%.*s", len, data); 1650f2f3eb3SBrian Somers } 1660f2f3eb3SBrian Somers 1670f2f3eb3SBrian Somers void 1680f2f3eb3SBrian Somers log_SetTtyCommandMode(struct datalink *dl) 1690f2f3eb3SBrian Somers { 1700f2f3eb3SBrian Somers struct prompt *p; 1710f2f3eb3SBrian Somers 1720f2f3eb3SBrian Somers for (p = promptlist; p; p = p->next) 1730f2f3eb3SBrian Somers if (prompt_IsTermMode(p, dl)) 1740f2f3eb3SBrian Somers prompt_TtyCommandMode(p); 1750f2f3eb3SBrian Somers } 1760f2f3eb3SBrian Somers 177927145beSBrian Somers static int 178927145beSBrian Somers syslogLevel(int lev) 179927145beSBrian Somers { 180927145beSBrian Somers switch (lev) { 1816f384573SBrian Somers case LogDEBUG: 1826f384573SBrian Somers case LogTIMER: 1836f384573SBrian Somers return LOG_DEBUG; 184944f7098SBrian Somers case LogWARN: 185944f7098SBrian Somers return LOG_WARNING; 186944f7098SBrian Somers case LogERROR: 187944f7098SBrian Somers return LOG_ERR; 188944f7098SBrian Somers case LogALERT: 189944f7098SBrian Somers return LOG_ALERT; 190927145beSBrian Somers } 191927145beSBrian Somers return lev >= LogMIN && lev <= LogMAX ? LOG_INFO : 0; 192927145beSBrian Somers } 193af57ed9fSAtsushi Murai 194927145beSBrian Somers const char * 195dd7e2610SBrian Somers log_Name(int id) 196927145beSBrian Somers { 197927145beSBrian Somers return id < LogMIN || id > LogMAX ? "Unknown" : LogNames[id - 1]; 198927145beSBrian Somers } 199af57ed9fSAtsushi Murai 200af57ed9fSAtsushi Murai void 201dd7e2610SBrian Somers log_Keep(int id) 202af57ed9fSAtsushi Murai { 203927145beSBrian Somers if (id >= LogMIN && id <= LogMAXCONF) 204927145beSBrian Somers LogMask |= MSK(id); 205af57ed9fSAtsushi Murai } 206927145beSBrian Somers 207927145beSBrian Somers void 208dd7e2610SBrian Somers log_KeepLocal(int id, u_long *mask) 209a1e8f937SBrian Somers { 210b6217683SBrian Somers if (id >= LogMIN && id <= LogMAXCONF) { 211a1e8f937SBrian Somers LogMaskLocal |= MSK(id); 212b6217683SBrian Somers *mask |= MSK(id); 213b6217683SBrian Somers } 214a1e8f937SBrian Somers } 215a1e8f937SBrian Somers 216a1e8f937SBrian Somers void 217dd7e2610SBrian Somers log_Discard(int id) 218927145beSBrian Somers { 219927145beSBrian Somers if (id >= LogMIN && id <= LogMAXCONF) 220927145beSBrian Somers LogMask &= ~MSK(id); 221927145beSBrian Somers } 222927145beSBrian Somers 223927145beSBrian Somers void 224dd7e2610SBrian Somers log_DiscardLocal(int id, u_long *mask) 225a1e8f937SBrian Somers { 226b6217683SBrian Somers if (id >= LogMIN && id <= LogMAXCONF) { 227b6217683SBrian Somers *mask &= ~MSK(id); 22867568487SBrian Somers LogSetMaskLocal(); 229b6217683SBrian Somers } 230a1e8f937SBrian Somers } 231a1e8f937SBrian Somers 232a1e8f937SBrian Somers void 233dd7e2610SBrian Somers log_DiscardAll() 234927145beSBrian Somers { 235927145beSBrian Somers LogMask = 0; 236af57ed9fSAtsushi Murai } 237af57ed9fSAtsushi Murai 238a1e8f937SBrian Somers void 239dd7e2610SBrian Somers log_DiscardAllLocal(u_long *mask) 240a1e8f937SBrian Somers { 24167568487SBrian Somers *mask = MSK(LogERROR) | MSK(LogALERT) | MSK(LogWARN); 24267568487SBrian Somers LogSetMaskLocal(); 243a1e8f937SBrian Somers } 244a1e8f937SBrian Somers 245af57ed9fSAtsushi Murai int 246dd7e2610SBrian Somers log_IsKept(int id) 247af57ed9fSAtsushi Murai { 248a1e8f937SBrian Somers if (id < LogMIN || id > LogMAX) 249927145beSBrian Somers return 0; 250a1e8f937SBrian Somers if (id > LogMAXCONF) 251a1e8f937SBrian Somers return LOG_KEPT_LOCAL | LOG_KEPT_SYSLOG; 252a1e8f937SBrian Somers 253a1e8f937SBrian Somers return ((LogMaskLocal & MSK(id)) ? LOG_KEPT_LOCAL : 0) | 254a1e8f937SBrian Somers ((LogMask & MSK(id)) ? LOG_KEPT_SYSLOG : 0); 255af57ed9fSAtsushi Murai } 256af57ed9fSAtsushi Murai 257b6217683SBrian Somers int 258dd7e2610SBrian Somers log_IsKeptLocal(int id, u_long mask) 259b6217683SBrian Somers { 260b6217683SBrian Somers if (id < LogMIN || id > LogMAX) 261b6217683SBrian Somers return 0; 262b6217683SBrian Somers if (id > LogMAXCONF) 263b6217683SBrian Somers return LOG_KEPT_LOCAL | LOG_KEPT_SYSLOG; 264b6217683SBrian Somers 265b6217683SBrian Somers return ((mask & MSK(id)) ? LOG_KEPT_LOCAL : 0) | 266b6217683SBrian Somers ((LogMask & MSK(id)) ? LOG_KEPT_SYSLOG : 0); 267b6217683SBrian Somers } 268b6217683SBrian Somers 269af57ed9fSAtsushi Murai void 270dd7e2610SBrian Somers log_Open(const char *Name) 271af57ed9fSAtsushi Murai { 272927145beSBrian Somers openlog(Name, LOG_PID, LOG_DAEMON); 273af57ed9fSAtsushi Murai } 274af57ed9fSAtsushi Murai 275af57ed9fSAtsushi Murai void 276dd7e2610SBrian Somers log_SetTun(int tunno) 277af57ed9fSAtsushi Murai { 278927145beSBrian Somers LogTunno = tunno; 279af57ed9fSAtsushi Murai } 280af57ed9fSAtsushi Murai 281af57ed9fSAtsushi Murai void 282dd7e2610SBrian Somers log_Close() 283af57ed9fSAtsushi Murai { 284927145beSBrian Somers closelog(); 285927145beSBrian Somers LogTunno = -1; 2866ed9fb2fSBrian Somers } 287af57ed9fSAtsushi Murai 288af57ed9fSAtsushi Murai void 289dd7e2610SBrian Somers log_Printf(int lev, const char *fmt,...) 29053c9f6c0SAtsushi Murai { 29153c9f6c0SAtsushi Murai va_list ap; 292b6217683SBrian Somers struct prompt *prompt; 293944f7098SBrian Somers 294927145beSBrian Somers va_start(ap, fmt); 295dd7e2610SBrian Somers if (log_IsKept(lev)) { 296d93d3a9cSBrian Somers char nfmt[200]; 29753c9f6c0SAtsushi Murai 2980f2f3eb3SBrian Somers if ((log_IsKept(lev) & LOG_KEPT_LOCAL) && promptlist) { 299dd7e2610SBrian Somers if ((log_IsKept(LogTUN) & LOG_KEPT_LOCAL) && LogTunno != -1) 3001384bd27SBrian Somers snprintf(nfmt, sizeof nfmt, "%s%d: %s: %s", TUN_NAME, 301dd7e2610SBrian Somers LogTunno, log_Name(lev), fmt); 302927145beSBrian Somers else 303dd7e2610SBrian Somers snprintf(nfmt, sizeof nfmt, "%s: %s", log_Name(lev), fmt); 304b6217683SBrian Somers 3050f2f3eb3SBrian Somers for (prompt = promptlist; prompt; prompt = prompt->next) 306b6217683SBrian Somers if (lev > LogMAXCONF || (prompt->logmask & MSK(lev))) 307b6217683SBrian Somers prompt_vPrintf(prompt, nfmt, ap); 308a1e8f937SBrian Somers } 309a1e8f937SBrian Somers 3100f2f3eb3SBrian Somers if ((log_IsKept(lev) & LOG_KEPT_SYSLOG) && 3110f2f3eb3SBrian Somers (lev != LogWARN || !promptlist)) { 312dd7e2610SBrian Somers if ((log_IsKept(LogTUN) & LOG_KEPT_SYSLOG) && LogTunno != -1) 3131384bd27SBrian Somers snprintf(nfmt, sizeof nfmt, "%s%d: %s: %s", TUN_NAME, 314dd7e2610SBrian Somers LogTunno, log_Name(lev), fmt); 315a1e8f937SBrian Somers else 316dd7e2610SBrian Somers snprintf(nfmt, sizeof nfmt, "%s: %s", log_Name(lev), fmt); 317927145beSBrian Somers vsyslog(syslogLevel(lev), nfmt, ap); 318927145beSBrian Somers } 319a1e8f937SBrian Somers } 32053c9f6c0SAtsushi Murai va_end(ap); 32153c9f6c0SAtsushi Murai } 32253c9f6c0SAtsushi Murai 32353c9f6c0SAtsushi Murai void 324dd7e2610SBrian Somers log_DumpBp(int lev, const char *hdr, const struct mbuf * bp) 325af57ed9fSAtsushi Murai { 326dd7e2610SBrian Somers if (log_IsKept(lev)) { 327a1e8f937SBrian Somers char buf[50]; 328a9e8f807SBrian Somers char *b; 329a9e8f807SBrian Somers u_char *ptr; 330a9e8f807SBrian Somers int f; 331a9e8f807SBrian Somers 332a9e8f807SBrian Somers if (hdr && *hdr) 333dd7e2610SBrian Somers log_Printf(lev, "%s\n", hdr); 334a9e8f807SBrian Somers 335a9e8f807SBrian Somers b = buf; 336a9e8f807SBrian Somers do { 337a9e8f807SBrian Somers f = bp->cnt; 338a9e8f807SBrian Somers ptr = MBUF_CTOP(bp); 339a9e8f807SBrian Somers while (f--) { 340a9e8f807SBrian Somers sprintf(b, " %02x", (int) *ptr++); 341a9e8f807SBrian Somers b += 3; 342a1e8f937SBrian Somers if (b == buf + sizeof buf - 2) { 343a1e8f937SBrian Somers strcpy(b, "\n"); 344dd7e2610SBrian Somers log_Printf(lev, buf); 345a9e8f807SBrian Somers b = buf; 346a9e8f807SBrian Somers } 347a9e8f807SBrian Somers } 348a9e8f807SBrian Somers } while ((bp = bp->next) != NULL); 349a9e8f807SBrian Somers 350a1e8f937SBrian Somers if (b > buf) { 351a1e8f937SBrian Somers strcpy(b, "\n"); 352dd7e2610SBrian Somers log_Printf(lev, buf); 353a9e8f807SBrian Somers } 354af57ed9fSAtsushi Murai } 355a1e8f937SBrian Somers } 356af57ed9fSAtsushi Murai 357af57ed9fSAtsushi Murai void 358dd7e2610SBrian Somers log_DumpBuff(int lev, const char *hdr, const u_char * ptr, int n) 359af57ed9fSAtsushi Murai { 360dd7e2610SBrian Somers if (log_IsKept(lev)) { 361a1e8f937SBrian Somers char buf[50]; 362927145beSBrian Somers char *b; 363af57ed9fSAtsushi Murai 364927145beSBrian Somers if (hdr && *hdr) 365dd7e2610SBrian Somers log_Printf(lev, "%s\n", hdr); 366927145beSBrian Somers while (n > 0) { 367927145beSBrian Somers b = buf; 36870ee81ffSBrian Somers for (b = buf; b != buf + sizeof buf - 2 && n--; b += 3) 369927145beSBrian Somers sprintf(b, " %02x", (int) *ptr++); 370a1e8f937SBrian Somers strcpy(b, "\n"); 371dd7e2610SBrian Somers log_Printf(lev, buf); 372af57ed9fSAtsushi Murai } 373af57ed9fSAtsushi Murai } 374c6c740beSBrian Somers } 375b6217683SBrian Somers 376b6217683SBrian Somers int 377b6217683SBrian Somers log_ShowLevel(struct cmdargs const *arg) 378b6217683SBrian Somers { 379b6217683SBrian Somers int i; 380b6217683SBrian Somers 381b6217683SBrian Somers prompt_Printf(arg->prompt, "Log: "); 382b6217683SBrian Somers for (i = LogMIN; i <= LogMAX; i++) 383dd7e2610SBrian Somers if (log_IsKept(i) & LOG_KEPT_SYSLOG) 384dd7e2610SBrian Somers prompt_Printf(arg->prompt, " %s", log_Name(i)); 385b6217683SBrian Somers 386b6217683SBrian Somers prompt_Printf(arg->prompt, "\nLocal:"); 387b6217683SBrian Somers for (i = LogMIN; i <= LogMAX; i++) 388dd7e2610SBrian Somers if (log_IsKeptLocal(i, arg->prompt->logmask) & LOG_KEPT_LOCAL) 389dd7e2610SBrian Somers prompt_Printf(arg->prompt, " %s", log_Name(i)); 390b6217683SBrian Somers 391b6217683SBrian Somers prompt_Printf(arg->prompt, "\n"); 392b6217683SBrian Somers 393b6217683SBrian Somers return 0; 394b6217683SBrian Somers } 395b6217683SBrian Somers 396b6217683SBrian Somers int 397b6217683SBrian Somers log_SetLevel(struct cmdargs const *arg) 398b6217683SBrian Somers { 399b6217683SBrian Somers int i, res, argc, local; 400b6217683SBrian Somers char const *const *argv, *argp; 401b6217683SBrian Somers 40225092092SBrian Somers argc = arg->argc - arg->argn; 40325092092SBrian Somers argv = arg->argv + arg->argn; 404b6217683SBrian Somers res = 0; 405b6217683SBrian Somers 406b6217683SBrian Somers if (argc == 0 || strcasecmp(argv[0], "local")) 407b6217683SBrian Somers local = 0; 408b6217683SBrian Somers else { 409b6217683SBrian Somers if (arg->prompt == NULL) { 410dd7e2610SBrian Somers log_Printf(LogWARN, "set log local: Only available on the command line\n"); 411b6217683SBrian Somers return 1; 412b6217683SBrian Somers } 413b6217683SBrian Somers argc--; 414b6217683SBrian Somers argv++; 415b6217683SBrian Somers local = 1; 416b6217683SBrian Somers } 417b6217683SBrian Somers 418e43ebac1SBrian Somers if (argc == 0 || (argv[0][0] != '+' && argv[0][0] != '-')) { 419b6217683SBrian Somers if (local) 420dd7e2610SBrian Somers log_DiscardAllLocal(&arg->prompt->logmask); 421b6217683SBrian Somers else 422dd7e2610SBrian Somers log_DiscardAll(); 423e43ebac1SBrian Somers } 424b6217683SBrian Somers 425b6217683SBrian Somers while (argc--) { 426b6217683SBrian Somers argp = **argv == '+' || **argv == '-' ? *argv + 1 : *argv; 427b6217683SBrian Somers for (i = LogMIN; i <= LogMAX; i++) 428dd7e2610SBrian Somers if (strcasecmp(argp, log_Name(i)) == 0) { 429e43ebac1SBrian Somers if (**argv == '-') { 430b6217683SBrian Somers if (local) 431dd7e2610SBrian Somers log_DiscardLocal(i, &arg->prompt->logmask); 432b6217683SBrian Somers else 433dd7e2610SBrian Somers log_Discard(i); 434e43ebac1SBrian Somers } else if (local) 435dd7e2610SBrian Somers log_KeepLocal(i, &arg->prompt->logmask); 436b6217683SBrian Somers else 437dd7e2610SBrian Somers log_Keep(i); 438b6217683SBrian Somers break; 439b6217683SBrian Somers } 440b6217683SBrian Somers if (i > LogMAX) { 441dd7e2610SBrian Somers log_Printf(LogWARN, "%s: Invalid log value\n", argp); 442b6217683SBrian Somers res = -1; 443b6217683SBrian Somers } 444b6217683SBrian Somers argv++; 445b6217683SBrian Somers } 446b6217683SBrian Somers return res; 447b6217683SBrian Somers } 448b6217683SBrian Somers 449b6217683SBrian Somers int 450b6217683SBrian Somers log_ShowWho(struct cmdargs const *arg) 451b6217683SBrian Somers { 452b6217683SBrian Somers struct prompt *p; 453b6217683SBrian Somers 4540f2f3eb3SBrian Somers for (p = promptlist; p; p = p->next) { 455565e35e5SBrian Somers prompt_Printf(arg->prompt, "%s (%s)", p->src.type, p->src.from); 456f91ad6b0SBrian Somers if (p == arg->prompt) 457f91ad6b0SBrian Somers prompt_Printf(arg->prompt, " *"); 458f91ad6b0SBrian Somers if (!p->active) 459f91ad6b0SBrian Somers prompt_Printf(arg->prompt, " ^Z"); 460f91ad6b0SBrian Somers prompt_Printf(arg->prompt, "\n"); 461f91ad6b0SBrian Somers } 462b6217683SBrian Somers 463b6217683SBrian Somers return 0; 464b6217683SBrian Somers } 465