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