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