xref: /freebsd/usr.sbin/ppp/log.c (revision 9cf01ccf8c4d91ecdc4b63302ec1a1d6f8bb797f)
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