xref: /freebsd/usr.sbin/ppp/log.c (revision e715b13bca2dd758a8baeec374e1993e64caee2f)
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",
63e715b13bSBrian Somers   "Radius",
646815097bSBrian Somers   "Sync",
65927145beSBrian Somers   "TCP/IP",
66b1ac9332SBrian Somers   "Timer",
67927145beSBrian Somers   "Tun",
68927145beSBrian Somers   "Warning",
69927145beSBrian Somers   "Error",
70927145beSBrian Somers   "Alert"
71927145beSBrian Somers };
72af57ed9fSAtsushi Murai 
73927145beSBrian Somers #define MSK(n) (1<<((n)-1))
74af57ed9fSAtsushi Murai 
75d47dceb8SBrian Somers static u_long LogMask = MSK(LogPHASE);
76a1e8f937SBrian Somers static u_long LogMaskLocal = MSK(LogERROR) | MSK(LogALERT) | MSK(LogWARN);
77927145beSBrian Somers static int LogTunno = -1;
780f2f3eb3SBrian Somers static struct prompt *promptlist;	/* Where to log local stuff */
79b4f63b0bSBrian Somers struct prompt *log_PromptContext;
800bdcbcbeSBrian Somers int log_PromptListChanged;
810f2f3eb3SBrian Somers 
820f2f3eb3SBrian Somers struct prompt *
830f2f3eb3SBrian Somers log_PromptList()
840f2f3eb3SBrian Somers {
850f2f3eb3SBrian Somers   return promptlist;
860f2f3eb3SBrian Somers }
87b6217683SBrian Somers 
88b6217683SBrian Somers void
89b6217683SBrian Somers log_RegisterPrompt(struct prompt *prompt)
90b6217683SBrian Somers {
910f2f3eb3SBrian Somers   prompt->next = promptlist;
920f2f3eb3SBrian Somers   promptlist = prompt;
930f2f3eb3SBrian Somers   prompt->active = 1;
940f2f3eb3SBrian Somers   log_DiscardAllLocal(&prompt->logmask);
95b6217683SBrian Somers }
960f2f3eb3SBrian Somers 
970f2f3eb3SBrian Somers void
980f2f3eb3SBrian Somers log_ActivatePrompt(struct prompt *prompt)
990f2f3eb3SBrian Somers {
1000f2f3eb3SBrian Somers   prompt->active = 1;
1010f2f3eb3SBrian Somers   LogMaskLocal |= prompt->logmask;
102b6217683SBrian Somers }
103b6217683SBrian Somers 
10467568487SBrian Somers static void
10567568487SBrian Somers LogSetMaskLocal(void)
10667568487SBrian Somers {
10767568487SBrian Somers   struct prompt *p;
10867568487SBrian Somers 
10967568487SBrian Somers   LogMaskLocal = MSK(LogERROR) | MSK(LogALERT) | MSK(LogWARN);
1100f2f3eb3SBrian Somers   for (p = promptlist; p; p = p->next)
11167568487SBrian Somers     LogMaskLocal |= p->logmask;
11267568487SBrian Somers }
11367568487SBrian Somers 
114b6217683SBrian Somers void
1150f2f3eb3SBrian Somers log_DeactivatePrompt(struct prompt *prompt)
1160f2f3eb3SBrian Somers {
1170f2f3eb3SBrian Somers   if (prompt->active) {
1180f2f3eb3SBrian Somers     prompt->active = 0;
1190f2f3eb3SBrian Somers     LogSetMaskLocal();
1200f2f3eb3SBrian Somers   }
1210f2f3eb3SBrian Somers }
1220f2f3eb3SBrian Somers 
1230f2f3eb3SBrian Somers void
124b6217683SBrian Somers log_UnRegisterPrompt(struct prompt *prompt)
125b6217683SBrian Somers {
126b6217683SBrian Somers   if (prompt) {
127b6217683SBrian Somers     struct prompt **p;
128b6217683SBrian Somers 
1290f2f3eb3SBrian Somers     for (p = &promptlist; *p; p = &(*p)->next)
130b6217683SBrian Somers       if (*p == prompt) {
1310f2f3eb3SBrian Somers         *p = prompt->next;
1320f2f3eb3SBrian Somers         prompt->next = NULL;
133b6217683SBrian Somers         break;
134b6217683SBrian Somers       }
13567568487SBrian Somers     LogSetMaskLocal();
1360bdcbcbeSBrian Somers     log_PromptListChanged++;
137b6217683SBrian Somers   }
138b6217683SBrian Somers }
139af57ed9fSAtsushi Murai 
1400f2f3eb3SBrian Somers void
1410f2f3eb3SBrian Somers log_DestroyPrompts(struct server *s)
1420f2f3eb3SBrian Somers {
143a39fd214SBrian Somers   struct prompt *p, *pn, *pl;
1440f2f3eb3SBrian Somers 
1450f2f3eb3SBrian Somers   p = promptlist;
146a39fd214SBrian Somers   pl = NULL;
1470f2f3eb3SBrian Somers   while (p) {
1480f2f3eb3SBrian Somers     pn = p->next;
149a39fd214SBrian Somers     if (s && p->owner == s) {
150a39fd214SBrian Somers       if (pl)
151a39fd214SBrian Somers         pl->next = p->next;
152a39fd214SBrian Somers       else
153a39fd214SBrian Somers         promptlist = p->next;
1540f2f3eb3SBrian Somers       p->next = NULL;
1550f2f3eb3SBrian Somers       prompt_Destroy(p, 1);
156a39fd214SBrian Somers     } else
157a39fd214SBrian Somers       pl = p;
1580f2f3eb3SBrian Somers     p = pn;
1590f2f3eb3SBrian Somers   }
1600f2f3eb3SBrian Somers }
1610f2f3eb3SBrian Somers 
1620f2f3eb3SBrian Somers void
1630f2f3eb3SBrian Somers log_DisplayPrompts()
1640f2f3eb3SBrian Somers {
1650f2f3eb3SBrian Somers   struct prompt *p;
1660f2f3eb3SBrian Somers 
1670f2f3eb3SBrian Somers   for (p = promptlist; p; p = p->next)
1680f2f3eb3SBrian Somers     prompt_Required(p);
1690f2f3eb3SBrian Somers }
1700f2f3eb3SBrian Somers 
1710f2f3eb3SBrian Somers void
172bf1d3ff6SBrian Somers log_WritePrompts(struct datalink *dl, const char *fmt,...)
1730f2f3eb3SBrian Somers {
174bf1d3ff6SBrian Somers   va_list ap;
1750f2f3eb3SBrian Somers   struct prompt *p;
1760f2f3eb3SBrian Somers 
177bf1d3ff6SBrian Somers   va_start(ap, fmt);
1780f2f3eb3SBrian Somers   for (p = promptlist; p; p = p->next)
1790f2f3eb3SBrian Somers     if (prompt_IsTermMode(p, dl))
180bf1d3ff6SBrian Somers       prompt_vPrintf(p, fmt, ap);
181bf1d3ff6SBrian Somers   va_end(ap);
1820f2f3eb3SBrian Somers }
1830f2f3eb3SBrian Somers 
1840f2f3eb3SBrian Somers void
1850f2f3eb3SBrian Somers log_SetTtyCommandMode(struct datalink *dl)
1860f2f3eb3SBrian Somers {
1870f2f3eb3SBrian Somers   struct prompt *p;
1880f2f3eb3SBrian Somers 
1890f2f3eb3SBrian Somers   for (p = promptlist; p; p = p->next)
1900f2f3eb3SBrian Somers     if (prompt_IsTermMode(p, dl))
1910f2f3eb3SBrian Somers       prompt_TtyCommandMode(p);
1920f2f3eb3SBrian Somers }
1930f2f3eb3SBrian Somers 
194927145beSBrian Somers static int
195927145beSBrian Somers syslogLevel(int lev)
196927145beSBrian Somers {
197927145beSBrian Somers   switch (lev) {
19846df5aa7SBrian Somers   case LogLOG:
19946df5aa7SBrian Somers     return LOG_INFO;
2006f384573SBrian Somers   case LogDEBUG:
2016f384573SBrian Somers   case LogTIMER:
2026f384573SBrian Somers     return LOG_DEBUG;
203944f7098SBrian Somers   case LogWARN:
204944f7098SBrian Somers     return LOG_WARNING;
205944f7098SBrian Somers   case LogERROR:
206944f7098SBrian Somers     return LOG_ERR;
207944f7098SBrian Somers   case LogALERT:
208944f7098SBrian Somers     return LOG_ALERT;
209927145beSBrian Somers   }
210927145beSBrian Somers   return lev >= LogMIN && lev <= LogMAX ? LOG_INFO : 0;
211927145beSBrian Somers }
212af57ed9fSAtsushi Murai 
213927145beSBrian Somers const char *
214dd7e2610SBrian Somers log_Name(int id)
215927145beSBrian Somers {
21646df5aa7SBrian Somers   if (id == LogLOG)
21746df5aa7SBrian Somers     return "LOG";
218927145beSBrian Somers   return id < LogMIN || id > LogMAX ? "Unknown" : LogNames[id - 1];
219927145beSBrian Somers }
220af57ed9fSAtsushi Murai 
221af57ed9fSAtsushi Murai void
222dd7e2610SBrian Somers log_Keep(int id)
223af57ed9fSAtsushi Murai {
224927145beSBrian Somers   if (id >= LogMIN && id <= LogMAXCONF)
225927145beSBrian Somers     LogMask |= MSK(id);
226af57ed9fSAtsushi Murai }
227927145beSBrian Somers 
228927145beSBrian Somers void
229dd7e2610SBrian Somers log_KeepLocal(int id, u_long *mask)
230a1e8f937SBrian Somers {
231b6217683SBrian Somers   if (id >= LogMIN && id <= LogMAXCONF) {
232a1e8f937SBrian Somers     LogMaskLocal |= MSK(id);
233b6217683SBrian Somers     *mask |= MSK(id);
234b6217683SBrian Somers   }
235a1e8f937SBrian Somers }
236a1e8f937SBrian Somers 
237a1e8f937SBrian Somers void
238dd7e2610SBrian Somers log_Discard(int id)
239927145beSBrian Somers {
240927145beSBrian Somers   if (id >= LogMIN && id <= LogMAXCONF)
241927145beSBrian Somers     LogMask &= ~MSK(id);
242927145beSBrian Somers }
243927145beSBrian Somers 
244927145beSBrian Somers void
245dd7e2610SBrian Somers log_DiscardLocal(int id, u_long *mask)
246a1e8f937SBrian Somers {
247b6217683SBrian Somers   if (id >= LogMIN && id <= LogMAXCONF) {
248b6217683SBrian Somers     *mask &= ~MSK(id);
24967568487SBrian Somers     LogSetMaskLocal();
250b6217683SBrian Somers   }
251a1e8f937SBrian Somers }
252a1e8f937SBrian Somers 
253a1e8f937SBrian Somers void
254dd7e2610SBrian Somers log_DiscardAll()
255927145beSBrian Somers {
256927145beSBrian Somers   LogMask = 0;
257af57ed9fSAtsushi Murai }
258af57ed9fSAtsushi Murai 
259a1e8f937SBrian Somers void
260dd7e2610SBrian Somers log_DiscardAllLocal(u_long *mask)
261a1e8f937SBrian Somers {
26267568487SBrian Somers   *mask = MSK(LogERROR) | MSK(LogALERT) | MSK(LogWARN);
26367568487SBrian Somers   LogSetMaskLocal();
264a1e8f937SBrian Somers }
265a1e8f937SBrian Somers 
266af57ed9fSAtsushi Murai int
267dd7e2610SBrian Somers log_IsKept(int id)
268af57ed9fSAtsushi Murai {
26946df5aa7SBrian Somers   if (id == LogLOG)
27046df5aa7SBrian Somers     return LOG_KEPT_SYSLOG;
271a1e8f937SBrian Somers   if (id < LogMIN || id > LogMAX)
272927145beSBrian Somers     return 0;
273a1e8f937SBrian Somers   if (id > LogMAXCONF)
274a1e8f937SBrian Somers     return LOG_KEPT_LOCAL | LOG_KEPT_SYSLOG;
275a1e8f937SBrian Somers 
276a1e8f937SBrian Somers   return ((LogMaskLocal & MSK(id)) ? LOG_KEPT_LOCAL : 0) |
277a1e8f937SBrian Somers     ((LogMask & MSK(id)) ? LOG_KEPT_SYSLOG : 0);
278af57ed9fSAtsushi Murai }
279af57ed9fSAtsushi Murai 
280b6217683SBrian Somers int
281dd7e2610SBrian Somers log_IsKeptLocal(int id, u_long mask)
282b6217683SBrian Somers {
283b6217683SBrian Somers   if (id < LogMIN || id > LogMAX)
284b6217683SBrian Somers     return 0;
285b6217683SBrian Somers   if (id > LogMAXCONF)
286b6217683SBrian Somers     return LOG_KEPT_LOCAL | LOG_KEPT_SYSLOG;
287b6217683SBrian Somers 
288b6217683SBrian Somers   return ((mask & MSK(id)) ? LOG_KEPT_LOCAL : 0) |
289b6217683SBrian Somers     ((LogMask & MSK(id)) ? LOG_KEPT_SYSLOG : 0);
290b6217683SBrian Somers }
291b6217683SBrian Somers 
292af57ed9fSAtsushi Murai void
293dd7e2610SBrian Somers log_Open(const char *Name)
294af57ed9fSAtsushi Murai {
295927145beSBrian Somers   openlog(Name, LOG_PID, LOG_DAEMON);
296af57ed9fSAtsushi Murai }
297af57ed9fSAtsushi Murai 
298af57ed9fSAtsushi Murai void
299dd7e2610SBrian Somers log_SetTun(int tunno)
300af57ed9fSAtsushi Murai {
301927145beSBrian Somers   LogTunno = tunno;
302af57ed9fSAtsushi Murai }
303af57ed9fSAtsushi Murai 
304af57ed9fSAtsushi Murai void
305dd7e2610SBrian Somers log_Close()
306af57ed9fSAtsushi Murai {
307927145beSBrian Somers   closelog();
308927145beSBrian Somers   LogTunno = -1;
3096ed9fb2fSBrian Somers }
310af57ed9fSAtsushi Murai 
311af57ed9fSAtsushi Murai void
312dd7e2610SBrian Somers log_Printf(int lev, const char *fmt,...)
31353c9f6c0SAtsushi Murai {
31453c9f6c0SAtsushi Murai   va_list ap;
315b6217683SBrian Somers   struct prompt *prompt;
316944f7098SBrian Somers 
317dd7e2610SBrian Somers   if (log_IsKept(lev)) {
318d93d3a9cSBrian Somers     char nfmt[200];
31953c9f6c0SAtsushi Murai 
32090d25921SBrian Somers     va_start(ap, fmt);
321b4f63b0bSBrian Somers     if (promptlist && (log_IsKept(lev) & LOG_KEPT_LOCAL)) {
322dd7e2610SBrian Somers       if ((log_IsKept(LogTUN) & LOG_KEPT_LOCAL) && LogTunno != -1)
3231384bd27SBrian Somers         snprintf(nfmt, sizeof nfmt, "%s%d: %s: %s", TUN_NAME,
324dd7e2610SBrian Somers 	         LogTunno, log_Name(lev), fmt);
325927145beSBrian Somers       else
326dd7e2610SBrian Somers         snprintf(nfmt, sizeof nfmt, "%s: %s", log_Name(lev), fmt);
327b6217683SBrian Somers 
328b4f63b0bSBrian Somers       if (log_PromptContext && lev == LogWARN)
329b4f63b0bSBrian Somers         /* Warnings just go to the current prompt */
330b4f63b0bSBrian Somers         prompt_vPrintf(log_PromptContext, nfmt, ap);
331b4f63b0bSBrian Somers       else for (prompt = promptlist; prompt; prompt = prompt->next)
332b6217683SBrian Somers         if (lev > LogMAXCONF || (prompt->logmask & MSK(lev)))
333b6217683SBrian Somers           prompt_vPrintf(prompt, nfmt, ap);
334a1e8f937SBrian Somers     }
33590d25921SBrian Somers     va_end(ap);
336a1e8f937SBrian Somers 
33790d25921SBrian Somers     va_start(ap, fmt);
3380f2f3eb3SBrian Somers     if ((log_IsKept(lev) & LOG_KEPT_SYSLOG) &&
339b4f63b0bSBrian Somers         (lev != LogWARN || !log_PromptContext)) {
340dd7e2610SBrian Somers       if ((log_IsKept(LogTUN) & LOG_KEPT_SYSLOG) && LogTunno != -1)
3411384bd27SBrian Somers         snprintf(nfmt, sizeof nfmt, "%s%d: %s: %s", TUN_NAME,
342dd7e2610SBrian Somers 	         LogTunno, log_Name(lev), fmt);
343a1e8f937SBrian Somers       else
344dd7e2610SBrian Somers         snprintf(nfmt, sizeof nfmt, "%s: %s", log_Name(lev), fmt);
345927145beSBrian Somers       vsyslog(syslogLevel(lev), nfmt, ap);
346927145beSBrian Somers     }
34753c9f6c0SAtsushi Murai     va_end(ap);
34853c9f6c0SAtsushi Murai   }
34990d25921SBrian Somers }
35053c9f6c0SAtsushi Murai 
35153c9f6c0SAtsushi Murai void
352dd7e2610SBrian Somers log_DumpBp(int lev, const char *hdr, const struct mbuf *bp)
353af57ed9fSAtsushi Murai {
354dd7e2610SBrian Somers   if (log_IsKept(lev)) {
355ba16c840SBrian Somers     char buf[68];
356ba16c840SBrian Somers     char *b, *c;
3579773f8c0SBrian Somers     const u_char *ptr;
358a9e8f807SBrian Somers     int f;
359a9e8f807SBrian Somers 
360a9e8f807SBrian Somers     if (hdr && *hdr)
361dd7e2610SBrian Somers       log_Printf(lev, "%s\n", hdr);
362a9e8f807SBrian Somers 
363a9e8f807SBrian Somers     b = buf;
364ba16c840SBrian Somers     c = b + 50;
365a9e8f807SBrian Somers     do {
36626af0ae9SBrian Somers       f = bp->m_len;
3679773f8c0SBrian Somers       ptr = CONST_MBUF_CTOP(bp);
368a9e8f807SBrian Somers       while (f--) {
369ba16c840SBrian Somers 	sprintf(b, " %02x", (int) *ptr);
370ba16c840SBrian Somers         *c++ = isprint(*ptr) ? *ptr : '.';
371ba16c840SBrian Somers         ptr++;
372a9e8f807SBrian Somers         b += 3;
373ba16c840SBrian Somers         if (b == buf + 48) {
374ba16c840SBrian Somers           memset(b, ' ', 2);
3759cf01ccfSBrian Somers           *c = '\0';
3769cf01ccfSBrian Somers           log_Printf(lev, "%s\n", buf);
377a9e8f807SBrian Somers           b = buf;
378ba16c840SBrian Somers           c = b + 50;
379a9e8f807SBrian Somers         }
380a9e8f807SBrian Somers       }
38126af0ae9SBrian Somers     } while ((bp = bp->m_next) != NULL);
382a9e8f807SBrian Somers 
383a1e8f937SBrian Somers     if (b > buf) {
384ba16c840SBrian Somers       memset(b, ' ', 50 - (b - buf));
3859cf01ccfSBrian Somers       *c = '\0';
3869cf01ccfSBrian Somers       log_Printf(lev, "%s\n", buf);
387a9e8f807SBrian Somers     }
388af57ed9fSAtsushi Murai   }
389a1e8f937SBrian Somers }
390af57ed9fSAtsushi Murai 
391af57ed9fSAtsushi Murai void
392dd7e2610SBrian Somers log_DumpBuff(int lev, const char *hdr, const u_char *ptr, int n)
393af57ed9fSAtsushi Murai {
394dd7e2610SBrian Somers   if (log_IsKept(lev)) {
395ba16c840SBrian Somers     char buf[68];
396ba16c840SBrian Somers     char *b, *c;
397af57ed9fSAtsushi Murai 
398927145beSBrian Somers     if (hdr && *hdr)
399dd7e2610SBrian Somers       log_Printf(lev, "%s\n", hdr);
400927145beSBrian Somers     while (n > 0) {
401927145beSBrian Somers       b = buf;
402ba16c840SBrian Somers       c = b + 50;
403ba16c840SBrian Somers       for (b = buf; b != buf + 48 && n--; b += 3, ptr++) {
404ba16c840SBrian Somers 	sprintf(b, " %02x", (int) *ptr);
405ba16c840SBrian Somers         *c++ = isprint(*ptr) ? *ptr : '.';
406ba16c840SBrian Somers       }
407ba16c840SBrian Somers       memset(b, ' ', 50 - (b - buf));
4089cf01ccfSBrian Somers       *c = '\0';
4099cf01ccfSBrian Somers       log_Printf(lev, "%s\n", buf);
410af57ed9fSAtsushi Murai     }
411af57ed9fSAtsushi Murai   }
412c6c740beSBrian Somers }
413b6217683SBrian Somers 
414b6217683SBrian Somers int
415b6217683SBrian Somers log_ShowLevel(struct cmdargs const *arg)
416b6217683SBrian Somers {
417b6217683SBrian Somers   int i;
418b6217683SBrian Somers 
419b6217683SBrian Somers   prompt_Printf(arg->prompt, "Log:  ");
420b6217683SBrian Somers   for (i = LogMIN; i <= LogMAX; i++)
421dd7e2610SBrian Somers     if (log_IsKept(i) & LOG_KEPT_SYSLOG)
422dd7e2610SBrian Somers       prompt_Printf(arg->prompt, " %s", log_Name(i));
423b6217683SBrian Somers 
424b6217683SBrian Somers   prompt_Printf(arg->prompt, "\nLocal:");
425b6217683SBrian Somers   for (i = LogMIN; i <= LogMAX; i++)
426dd7e2610SBrian Somers     if (log_IsKeptLocal(i, arg->prompt->logmask) & LOG_KEPT_LOCAL)
427dd7e2610SBrian Somers       prompt_Printf(arg->prompt, " %s", log_Name(i));
428b6217683SBrian Somers 
429b6217683SBrian Somers   prompt_Printf(arg->prompt, "\n");
430b6217683SBrian Somers 
431b6217683SBrian Somers   return 0;
432b6217683SBrian Somers }
433b6217683SBrian Somers 
434b6217683SBrian Somers int
435b6217683SBrian Somers log_SetLevel(struct cmdargs const *arg)
436b6217683SBrian Somers {
437b6217683SBrian Somers   int i, res, argc, local;
438b6217683SBrian Somers   char const *const *argv, *argp;
439b6217683SBrian Somers 
44025092092SBrian Somers   argc = arg->argc - arg->argn;
44125092092SBrian Somers   argv = arg->argv + arg->argn;
442b6217683SBrian Somers   res = 0;
443b6217683SBrian Somers 
444b6217683SBrian Somers   if (argc == 0 || strcasecmp(argv[0], "local"))
445b6217683SBrian Somers     local = 0;
446b6217683SBrian Somers   else {
447b6217683SBrian Somers     if (arg->prompt == NULL) {
4489b996792SBrian Somers       log_Printf(LogWARN, "set log local: Only available on the"
4499b996792SBrian Somers                  " command line\n");
450b6217683SBrian Somers       return 1;
451b6217683SBrian Somers     }
452b6217683SBrian Somers     argc--;
453b6217683SBrian Somers     argv++;
454b6217683SBrian Somers     local = 1;
455b6217683SBrian Somers   }
456b6217683SBrian Somers 
457e43ebac1SBrian Somers   if (argc == 0 || (argv[0][0] != '+' && argv[0][0] != '-')) {
458b6217683SBrian Somers     if (local)
459dd7e2610SBrian Somers       log_DiscardAllLocal(&arg->prompt->logmask);
460b6217683SBrian Somers     else
461dd7e2610SBrian Somers       log_DiscardAll();
462e43ebac1SBrian Somers   }
463b6217683SBrian Somers 
464b6217683SBrian Somers   while (argc--) {
465b6217683SBrian Somers     argp = **argv == '+' || **argv == '-' ? *argv + 1 : *argv;
4667f03ca53SBrian Somers     /* Special case 'all' */
4677f03ca53SBrian Somers     if (strcasecmp(argp, "all") == 0) {
4687f03ca53SBrian Somers         if (**argv == '-') {
4697f03ca53SBrian Somers           if (local)
4707f03ca53SBrian Somers             for (i = LogMIN; i <= LogMAX; i++)
4717f03ca53SBrian Somers               log_DiscardLocal(i, &arg->prompt->logmask);
4727f03ca53SBrian Somers           else
4737f03ca53SBrian Somers             for (i = LogMIN; i <= LogMAX; i++)
4747f03ca53SBrian Somers               log_Discard(i);
4757f03ca53SBrian Somers         } else if (local)
4767f03ca53SBrian Somers           for (i = LogMIN; i <= LogMAX; i++)
4777f03ca53SBrian Somers             log_KeepLocal(i, &arg->prompt->logmask);
4787f03ca53SBrian Somers         else
4797f03ca53SBrian Somers           for (i = LogMIN; i <= LogMAX; i++)
4807f03ca53SBrian Somers             log_Keep(i);
4817f03ca53SBrian Somers         argv++;
4827f03ca53SBrian Somers         continue;
4837f03ca53SBrian Somers     }
484b6217683SBrian Somers     for (i = LogMIN; i <= LogMAX; i++)
485dd7e2610SBrian Somers       if (strcasecmp(argp, log_Name(i)) == 0) {
486e43ebac1SBrian Somers 	if (**argv == '-') {
487b6217683SBrian Somers           if (local)
488dd7e2610SBrian Somers             log_DiscardLocal(i, &arg->prompt->logmask);
489b6217683SBrian Somers           else
490dd7e2610SBrian Somers 	    log_Discard(i);
491e43ebac1SBrian Somers 	} else if (local)
492dd7e2610SBrian Somers           log_KeepLocal(i, &arg->prompt->logmask);
493b6217683SBrian Somers         else
494dd7e2610SBrian Somers           log_Keep(i);
495b6217683SBrian Somers 	break;
496b6217683SBrian Somers       }
497b6217683SBrian Somers     if (i > LogMAX) {
498dd7e2610SBrian Somers       log_Printf(LogWARN, "%s: Invalid log value\n", argp);
499b6217683SBrian Somers       res = -1;
500b6217683SBrian Somers     }
501b6217683SBrian Somers     argv++;
502b6217683SBrian Somers   }
503b6217683SBrian Somers   return res;
504b6217683SBrian Somers }
505b6217683SBrian Somers 
506b6217683SBrian Somers int
507b6217683SBrian Somers log_ShowWho(struct cmdargs const *arg)
508b6217683SBrian Somers {
509b6217683SBrian Somers   struct prompt *p;
510b6217683SBrian Somers 
5110f2f3eb3SBrian Somers   for (p = promptlist; p; p = p->next) {
512565e35e5SBrian Somers     prompt_Printf(arg->prompt, "%s (%s)", p->src.type, p->src.from);
513f91ad6b0SBrian Somers     if (p == arg->prompt)
514f91ad6b0SBrian Somers       prompt_Printf(arg->prompt, " *");
515f91ad6b0SBrian Somers     if (!p->active)
516f91ad6b0SBrian Somers       prompt_Printf(arg->prompt, " ^Z");
517f91ad6b0SBrian Somers     prompt_Printf(arg->prompt, "\n");
518f91ad6b0SBrian Somers   }
519b6217683SBrian Somers 
520b6217683SBrian Somers   return 0;
521b6217683SBrian Somers }
522