xref: /freebsd/usr.sbin/ppp/log.c (revision a39fd2143cb2a1498dcabd0736b780b44b5df1b7)
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  *
26a39fd214SBrian Somers  *	$Id: log.c,v 1.35 1998/08/21 18:10:14 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 {
135a39fd214SBrian Somers   struct prompt *p, *pn, *pl;
1360f2f3eb3SBrian Somers 
1370f2f3eb3SBrian Somers   p = promptlist;
138a39fd214SBrian Somers   pl = NULL;
1390f2f3eb3SBrian Somers   while (p) {
1400f2f3eb3SBrian Somers     pn = p->next;
141a39fd214SBrian Somers     if (s && p->owner == s) {
142a39fd214SBrian Somers       if (pl)
143a39fd214SBrian Somers         pl->next = p->next;
144a39fd214SBrian Somers       else
145a39fd214SBrian Somers         promptlist = p->next;
1460f2f3eb3SBrian Somers       p->next = NULL;
1470f2f3eb3SBrian Somers       prompt_Destroy(p, 1);
148a39fd214SBrian Somers     } else
149a39fd214SBrian Somers       pl = p;
1500f2f3eb3SBrian Somers     p = pn;
1510f2f3eb3SBrian Somers   }
1520f2f3eb3SBrian Somers }
1530f2f3eb3SBrian Somers 
1540f2f3eb3SBrian Somers void
1550f2f3eb3SBrian Somers log_DisplayPrompts()
1560f2f3eb3SBrian Somers {
1570f2f3eb3SBrian Somers   struct prompt *p;
1580f2f3eb3SBrian Somers 
1590f2f3eb3SBrian Somers   for (p = promptlist; p; p = p->next)
1600f2f3eb3SBrian Somers     prompt_Required(p);
1610f2f3eb3SBrian Somers }
1620f2f3eb3SBrian Somers 
1630f2f3eb3SBrian Somers void
164bf1d3ff6SBrian Somers log_WritePrompts(struct datalink *dl, const char *fmt,...)
1650f2f3eb3SBrian Somers {
166bf1d3ff6SBrian Somers   va_list ap;
1670f2f3eb3SBrian Somers   struct prompt *p;
1680f2f3eb3SBrian Somers 
169bf1d3ff6SBrian Somers   va_start(ap, fmt);
1700f2f3eb3SBrian Somers   for (p = promptlist; p; p = p->next)
1710f2f3eb3SBrian Somers     if (prompt_IsTermMode(p, dl))
172bf1d3ff6SBrian Somers       prompt_vPrintf(p, fmt, ap);
173bf1d3ff6SBrian Somers   va_end(ap);
1740f2f3eb3SBrian Somers }
1750f2f3eb3SBrian Somers 
1760f2f3eb3SBrian Somers void
1770f2f3eb3SBrian Somers log_SetTtyCommandMode(struct datalink *dl)
1780f2f3eb3SBrian Somers {
1790f2f3eb3SBrian Somers   struct prompt *p;
1800f2f3eb3SBrian Somers 
1810f2f3eb3SBrian Somers   for (p = promptlist; p; p = p->next)
1820f2f3eb3SBrian Somers     if (prompt_IsTermMode(p, dl))
1830f2f3eb3SBrian Somers       prompt_TtyCommandMode(p);
1840f2f3eb3SBrian Somers }
1850f2f3eb3SBrian Somers 
186927145beSBrian Somers static int
187927145beSBrian Somers syslogLevel(int lev)
188927145beSBrian Somers {
189927145beSBrian Somers   switch (lev) {
1906f384573SBrian Somers   case LogDEBUG:
1916f384573SBrian Somers   case LogTIMER:
1926f384573SBrian Somers     return LOG_DEBUG;
193944f7098SBrian Somers   case LogWARN:
194944f7098SBrian Somers     return LOG_WARNING;
195944f7098SBrian Somers   case LogERROR:
196944f7098SBrian Somers     return LOG_ERR;
197944f7098SBrian Somers   case LogALERT:
198944f7098SBrian Somers     return LOG_ALERT;
199927145beSBrian Somers   }
200927145beSBrian Somers   return lev >= LogMIN && lev <= LogMAX ? LOG_INFO : 0;
201927145beSBrian Somers }
202af57ed9fSAtsushi Murai 
203927145beSBrian Somers const char *
204dd7e2610SBrian Somers log_Name(int id)
205927145beSBrian Somers {
206927145beSBrian Somers   return id < LogMIN || id > LogMAX ? "Unknown" : LogNames[id - 1];
207927145beSBrian Somers }
208af57ed9fSAtsushi Murai 
209af57ed9fSAtsushi Murai void
210dd7e2610SBrian Somers log_Keep(int id)
211af57ed9fSAtsushi Murai {
212927145beSBrian Somers   if (id >= LogMIN && id <= LogMAXCONF)
213927145beSBrian Somers     LogMask |= MSK(id);
214af57ed9fSAtsushi Murai }
215927145beSBrian Somers 
216927145beSBrian Somers void
217dd7e2610SBrian Somers log_KeepLocal(int id, u_long *mask)
218a1e8f937SBrian Somers {
219b6217683SBrian Somers   if (id >= LogMIN && id <= LogMAXCONF) {
220a1e8f937SBrian Somers     LogMaskLocal |= MSK(id);
221b6217683SBrian Somers     *mask |= MSK(id);
222b6217683SBrian Somers   }
223a1e8f937SBrian Somers }
224a1e8f937SBrian Somers 
225a1e8f937SBrian Somers void
226dd7e2610SBrian Somers log_Discard(int id)
227927145beSBrian Somers {
228927145beSBrian Somers   if (id >= LogMIN && id <= LogMAXCONF)
229927145beSBrian Somers     LogMask &= ~MSK(id);
230927145beSBrian Somers }
231927145beSBrian Somers 
232927145beSBrian Somers void
233dd7e2610SBrian Somers log_DiscardLocal(int id, u_long *mask)
234a1e8f937SBrian Somers {
235b6217683SBrian Somers   if (id >= LogMIN && id <= LogMAXCONF) {
236b6217683SBrian Somers     *mask &= ~MSK(id);
23767568487SBrian Somers     LogSetMaskLocal();
238b6217683SBrian Somers   }
239a1e8f937SBrian Somers }
240a1e8f937SBrian Somers 
241a1e8f937SBrian Somers void
242dd7e2610SBrian Somers log_DiscardAll()
243927145beSBrian Somers {
244927145beSBrian Somers   LogMask = 0;
245af57ed9fSAtsushi Murai }
246af57ed9fSAtsushi Murai 
247a1e8f937SBrian Somers void
248dd7e2610SBrian Somers log_DiscardAllLocal(u_long *mask)
249a1e8f937SBrian Somers {
25067568487SBrian Somers   *mask = MSK(LogERROR) | MSK(LogALERT) | MSK(LogWARN);
25167568487SBrian Somers   LogSetMaskLocal();
252a1e8f937SBrian Somers }
253a1e8f937SBrian Somers 
254af57ed9fSAtsushi Murai int
255dd7e2610SBrian Somers log_IsKept(int id)
256af57ed9fSAtsushi Murai {
257a1e8f937SBrian Somers   if (id < LogMIN || id > LogMAX)
258927145beSBrian Somers     return 0;
259a1e8f937SBrian Somers   if (id > LogMAXCONF)
260a1e8f937SBrian Somers     return LOG_KEPT_LOCAL | LOG_KEPT_SYSLOG;
261a1e8f937SBrian Somers 
262a1e8f937SBrian Somers   return ((LogMaskLocal & MSK(id)) ? LOG_KEPT_LOCAL : 0) |
263a1e8f937SBrian Somers     ((LogMask & MSK(id)) ? LOG_KEPT_SYSLOG : 0);
264af57ed9fSAtsushi Murai }
265af57ed9fSAtsushi Murai 
266b6217683SBrian Somers int
267dd7e2610SBrian Somers log_IsKeptLocal(int id, u_long mask)
268b6217683SBrian Somers {
269b6217683SBrian Somers   if (id < LogMIN || id > LogMAX)
270b6217683SBrian Somers     return 0;
271b6217683SBrian Somers   if (id > LogMAXCONF)
272b6217683SBrian Somers     return LOG_KEPT_LOCAL | LOG_KEPT_SYSLOG;
273b6217683SBrian Somers 
274b6217683SBrian Somers   return ((mask & MSK(id)) ? LOG_KEPT_LOCAL : 0) |
275b6217683SBrian Somers     ((LogMask & MSK(id)) ? LOG_KEPT_SYSLOG : 0);
276b6217683SBrian Somers }
277b6217683SBrian Somers 
278af57ed9fSAtsushi Murai void
279dd7e2610SBrian Somers log_Open(const char *Name)
280af57ed9fSAtsushi Murai {
281927145beSBrian Somers   openlog(Name, LOG_PID, LOG_DAEMON);
282af57ed9fSAtsushi Murai }
283af57ed9fSAtsushi Murai 
284af57ed9fSAtsushi Murai void
285dd7e2610SBrian Somers log_SetTun(int tunno)
286af57ed9fSAtsushi Murai {
287927145beSBrian Somers   LogTunno = tunno;
288af57ed9fSAtsushi Murai }
289af57ed9fSAtsushi Murai 
290af57ed9fSAtsushi Murai void
291dd7e2610SBrian Somers log_Close()
292af57ed9fSAtsushi Murai {
293927145beSBrian Somers   closelog();
294927145beSBrian Somers   LogTunno = -1;
2956ed9fb2fSBrian Somers }
296af57ed9fSAtsushi Murai 
297af57ed9fSAtsushi Murai void
298dd7e2610SBrian Somers log_Printf(int lev, const char *fmt,...)
29953c9f6c0SAtsushi Murai {
30053c9f6c0SAtsushi Murai   va_list ap;
301b6217683SBrian Somers   struct prompt *prompt;
302944f7098SBrian Somers 
303927145beSBrian Somers   va_start(ap, fmt);
304dd7e2610SBrian Somers   if (log_IsKept(lev)) {
305d93d3a9cSBrian Somers     char nfmt[200];
30653c9f6c0SAtsushi Murai 
3070f2f3eb3SBrian Somers     if ((log_IsKept(lev) & LOG_KEPT_LOCAL) && promptlist) {
308dd7e2610SBrian Somers       if ((log_IsKept(LogTUN) & LOG_KEPT_LOCAL) && LogTunno != -1)
3091384bd27SBrian Somers         snprintf(nfmt, sizeof nfmt, "%s%d: %s: %s", TUN_NAME,
310dd7e2610SBrian Somers 	         LogTunno, log_Name(lev), fmt);
311927145beSBrian Somers       else
312dd7e2610SBrian Somers         snprintf(nfmt, sizeof nfmt, "%s: %s", log_Name(lev), fmt);
313b6217683SBrian Somers 
3140f2f3eb3SBrian Somers       for (prompt = promptlist; prompt; prompt = prompt->next)
315b6217683SBrian Somers         if (lev > LogMAXCONF || (prompt->logmask & MSK(lev)))
316b6217683SBrian Somers           prompt_vPrintf(prompt, nfmt, ap);
317a1e8f937SBrian Somers     }
318a1e8f937SBrian Somers 
3190f2f3eb3SBrian Somers     if ((log_IsKept(lev) & LOG_KEPT_SYSLOG) &&
3200f2f3eb3SBrian Somers         (lev != LogWARN || !promptlist)) {
321dd7e2610SBrian Somers       if ((log_IsKept(LogTUN) & LOG_KEPT_SYSLOG) && LogTunno != -1)
3221384bd27SBrian Somers         snprintf(nfmt, sizeof nfmt, "%s%d: %s: %s", TUN_NAME,
323dd7e2610SBrian Somers 	         LogTunno, log_Name(lev), fmt);
324a1e8f937SBrian Somers       else
325dd7e2610SBrian Somers         snprintf(nfmt, sizeof nfmt, "%s: %s", log_Name(lev), fmt);
326927145beSBrian Somers       vsyslog(syslogLevel(lev), nfmt, ap);
327927145beSBrian Somers     }
328a1e8f937SBrian Somers   }
32953c9f6c0SAtsushi Murai   va_end(ap);
33053c9f6c0SAtsushi Murai }
33153c9f6c0SAtsushi Murai 
33253c9f6c0SAtsushi Murai void
333dd7e2610SBrian Somers log_DumpBp(int lev, const char *hdr, const struct mbuf *bp)
334af57ed9fSAtsushi Murai {
335dd7e2610SBrian Somers   if (log_IsKept(lev)) {
336a1e8f937SBrian Somers     char buf[50];
337a9e8f807SBrian Somers     char *b;
3389773f8c0SBrian Somers     const u_char *ptr;
339a9e8f807SBrian Somers     int f;
340a9e8f807SBrian Somers 
341a9e8f807SBrian Somers     if (hdr && *hdr)
342dd7e2610SBrian Somers       log_Printf(lev, "%s\n", hdr);
343a9e8f807SBrian Somers 
344a9e8f807SBrian Somers     b = buf;
345a9e8f807SBrian Somers     do {
346a9e8f807SBrian Somers       f = bp->cnt;
3479773f8c0SBrian Somers       ptr = CONST_MBUF_CTOP(bp);
348a9e8f807SBrian Somers       while (f--) {
349a9e8f807SBrian Somers 	sprintf(b, " %02x", (int) *ptr++);
350a9e8f807SBrian Somers         b += 3;
351a1e8f937SBrian Somers         if (b == buf + sizeof buf - 2) {
352a1e8f937SBrian Somers           strcpy(b, "\n");
353dd7e2610SBrian Somers           log_Printf(lev, buf);
354a9e8f807SBrian Somers           b = buf;
355a9e8f807SBrian Somers         }
356a9e8f807SBrian Somers       }
357a9e8f807SBrian Somers     } while ((bp = bp->next) != NULL);
358a9e8f807SBrian Somers 
359a1e8f937SBrian Somers     if (b > buf) {
360a1e8f937SBrian Somers       strcpy(b, "\n");
361dd7e2610SBrian Somers       log_Printf(lev, buf);
362a9e8f807SBrian Somers     }
363af57ed9fSAtsushi Murai   }
364a1e8f937SBrian Somers }
365af57ed9fSAtsushi Murai 
366af57ed9fSAtsushi Murai void
367dd7e2610SBrian Somers log_DumpBuff(int lev, const char *hdr, const u_char * ptr, int n)
368af57ed9fSAtsushi Murai {
369dd7e2610SBrian Somers   if (log_IsKept(lev)) {
370a1e8f937SBrian Somers     char buf[50];
371927145beSBrian Somers     char *b;
372af57ed9fSAtsushi Murai 
373927145beSBrian Somers     if (hdr && *hdr)
374dd7e2610SBrian Somers       log_Printf(lev, "%s\n", hdr);
375927145beSBrian Somers     while (n > 0) {
376927145beSBrian Somers       b = buf;
37770ee81ffSBrian Somers       for (b = buf; b != buf + sizeof buf - 2 && n--; b += 3)
378927145beSBrian Somers 	sprintf(b, " %02x", (int) *ptr++);
379a1e8f937SBrian Somers       strcpy(b, "\n");
380dd7e2610SBrian Somers       log_Printf(lev, buf);
381af57ed9fSAtsushi Murai     }
382af57ed9fSAtsushi Murai   }
383c6c740beSBrian Somers }
384b6217683SBrian Somers 
385b6217683SBrian Somers int
386b6217683SBrian Somers log_ShowLevel(struct cmdargs const *arg)
387b6217683SBrian Somers {
388b6217683SBrian Somers   int i;
389b6217683SBrian Somers 
390b6217683SBrian Somers   prompt_Printf(arg->prompt, "Log:  ");
391b6217683SBrian Somers   for (i = LogMIN; i <= LogMAX; i++)
392dd7e2610SBrian Somers     if (log_IsKept(i) & LOG_KEPT_SYSLOG)
393dd7e2610SBrian Somers       prompt_Printf(arg->prompt, " %s", log_Name(i));
394b6217683SBrian Somers 
395b6217683SBrian Somers   prompt_Printf(arg->prompt, "\nLocal:");
396b6217683SBrian Somers   for (i = LogMIN; i <= LogMAX; i++)
397dd7e2610SBrian Somers     if (log_IsKeptLocal(i, arg->prompt->logmask) & LOG_KEPT_LOCAL)
398dd7e2610SBrian Somers       prompt_Printf(arg->prompt, " %s", log_Name(i));
399b6217683SBrian Somers 
400b6217683SBrian Somers   prompt_Printf(arg->prompt, "\n");
401b6217683SBrian Somers 
402b6217683SBrian Somers   return 0;
403b6217683SBrian Somers }
404b6217683SBrian Somers 
405b6217683SBrian Somers int
406b6217683SBrian Somers log_SetLevel(struct cmdargs const *arg)
407b6217683SBrian Somers {
408b6217683SBrian Somers   int i, res, argc, local;
409b6217683SBrian Somers   char const *const *argv, *argp;
410b6217683SBrian Somers 
41125092092SBrian Somers   argc = arg->argc - arg->argn;
41225092092SBrian Somers   argv = arg->argv + arg->argn;
413b6217683SBrian Somers   res = 0;
414b6217683SBrian Somers 
415b6217683SBrian Somers   if (argc == 0 || strcasecmp(argv[0], "local"))
416b6217683SBrian Somers     local = 0;
417b6217683SBrian Somers   else {
418b6217683SBrian Somers     if (arg->prompt == NULL) {
419dd7e2610SBrian Somers       log_Printf(LogWARN, "set log local: Only available on the command line\n");
420b6217683SBrian Somers       return 1;
421b6217683SBrian Somers     }
422b6217683SBrian Somers     argc--;
423b6217683SBrian Somers     argv++;
424b6217683SBrian Somers     local = 1;
425b6217683SBrian Somers   }
426b6217683SBrian Somers 
427e43ebac1SBrian Somers   if (argc == 0 || (argv[0][0] != '+' && argv[0][0] != '-')) {
428b6217683SBrian Somers     if (local)
429dd7e2610SBrian Somers       log_DiscardAllLocal(&arg->prompt->logmask);
430b6217683SBrian Somers     else
431dd7e2610SBrian Somers       log_DiscardAll();
432e43ebac1SBrian Somers   }
433b6217683SBrian Somers 
434b6217683SBrian Somers   while (argc--) {
435b6217683SBrian Somers     argp = **argv == '+' || **argv == '-' ? *argv + 1 : *argv;
436b6217683SBrian Somers     for (i = LogMIN; i <= LogMAX; i++)
437dd7e2610SBrian Somers       if (strcasecmp(argp, log_Name(i)) == 0) {
438e43ebac1SBrian Somers 	if (**argv == '-') {
439b6217683SBrian Somers           if (local)
440dd7e2610SBrian Somers             log_DiscardLocal(i, &arg->prompt->logmask);
441b6217683SBrian Somers           else
442dd7e2610SBrian Somers 	    log_Discard(i);
443e43ebac1SBrian Somers 	} else if (local)
444dd7e2610SBrian Somers           log_KeepLocal(i, &arg->prompt->logmask);
445b6217683SBrian Somers         else
446dd7e2610SBrian Somers           log_Keep(i);
447b6217683SBrian Somers 	break;
448b6217683SBrian Somers       }
449b6217683SBrian Somers     if (i > LogMAX) {
450dd7e2610SBrian Somers       log_Printf(LogWARN, "%s: Invalid log value\n", argp);
451b6217683SBrian Somers       res = -1;
452b6217683SBrian Somers     }
453b6217683SBrian Somers     argv++;
454b6217683SBrian Somers   }
455b6217683SBrian Somers   return res;
456b6217683SBrian Somers }
457b6217683SBrian Somers 
458b6217683SBrian Somers int
459b6217683SBrian Somers log_ShowWho(struct cmdargs const *arg)
460b6217683SBrian Somers {
461b6217683SBrian Somers   struct prompt *p;
462b6217683SBrian Somers 
4630f2f3eb3SBrian Somers   for (p = promptlist; p; p = p->next) {
464565e35e5SBrian Somers     prompt_Printf(arg->prompt, "%s (%s)", p->src.type, p->src.from);
465f91ad6b0SBrian Somers     if (p == arg->prompt)
466f91ad6b0SBrian Somers       prompt_Printf(arg->prompt, " *");
467f91ad6b0SBrian Somers     if (!p->active)
468f91ad6b0SBrian Somers       prompt_Printf(arg->prompt, " ^Z");
469f91ad6b0SBrian Somers     prompt_Printf(arg->prompt, "\n");
470f91ad6b0SBrian Somers   }
471b6217683SBrian Somers 
472b6217683SBrian Somers   return 0;
473b6217683SBrian Somers }
474