log.c revision 36452
1195534Sscottl/*-
2195534Sscottl * Copyright (c) 1997 Brian Somers <brian@Awfulhak.org>
3195534Sscottl * All rights reserved.
4195534Sscottl *
5195534Sscottl * Redistribution and use in source and binary forms, with or without
6195534Sscottl * modification, are permitted provided that the following conditions
7195534Sscottl * are met:
8195534Sscottl * 1. Redistributions of source code must retain the above copyright
9195534Sscottl *    notice, this list of conditions and the following disclaimer.
10195534Sscottl * 2. Redistributions in binary form must reproduce the above copyright
11195534Sscottl *    notice, this list of conditions and the following disclaimer in the
12195534Sscottl *    documentation and/or other materials provided with the distribution.
13195534Sscottl *
14195534Sscottl * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15195534Sscottl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16195534Sscottl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17195534Sscottl * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18195534Sscottl * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19195534Sscottl * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20195534Sscottl * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21195534Sscottl * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22195534Sscottl * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23195534Sscottl * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24195534Sscottl * SUCH DAMAGE.
25195534Sscottl *
26195534Sscottl *	$Id: log.c,v 1.28 1998/05/23 22:24:40 brian Exp $
27195534Sscottl */
28195534Sscottl
29195534Sscottl#include <sys/types.h>
30220454Smav
31220454Smav#include <stdarg.h>
32195534Sscottl#include <stdio.h>
33195534Sscottl#include <string.h>
34195534Sscottl#include <syslog.h>
35195534Sscottl#include <termios.h>
36195534Sscottl
37195534Sscottl#include "command.h"
38195534Sscottl#include "mbuf.h"
39195534Sscottl#include "log.h"
40195534Sscottl#include "descriptor.h"
41195534Sscottl#include "prompt.h"
42195534Sscottl#include "defs.h"
43195534Sscottl
44195534Sscottlstatic const char *LogNames[] = {
45195534Sscottl  "Async",
46195534Sscottl  "CCP",
47214279Sbrucec  "Chat",
48195534Sscottl  "Command",
49195534Sscottl  "Connect",
50195534Sscottl  "Debug",
51195534Sscottl  "HDLC",
52195534Sscottl  "ID0",
53195534Sscottl  "IPCP",
54195534Sscottl  "LCP",
55195534Sscottl  "LQM",
56195534Sscottl  "Phase",
57195534Sscottl  "TCP/IP",
58195534Sscottl  "Timer",
59195534Sscottl  "Tun",
60195534Sscottl  "Warning",
61195534Sscottl  "Error",
62195534Sscottl  "Alert"
63195534Sscottl};
64208349Smarius
65208349Smarius#define MSK(n) (1<<((n)-1))
66195534Sscottl
67195534Sscottlstatic u_long LogMask = MSK(LogPHASE);
68195534Sscottlstatic u_long LogMaskLocal = MSK(LogERROR) | MSK(LogALERT) | MSK(LogWARN);
69195534Sscottlstatic int LogTunno = -1;
70195534Sscottlstatic struct prompt *promptlist;	/* Where to log local stuff */
71224497Smav
72220412Smavstruct prompt *
73198708Smavlog_PromptList()
74195534Sscottl{
75195534Sscottl  return promptlist;
76195534Sscottl}
77249199Smarius
78249199Smariusvoid
79249199Smariuslog_RegisterPrompt(struct prompt *prompt)
80249199Smarius{
81249199Smarius  prompt->next = promptlist;
82249199Smarius  promptlist = prompt;
83249199Smarius  prompt->active = 1;
84249199Smarius  log_DiscardAllLocal(&prompt->logmask);
85249199Smarius}
86249199Smarius
87249199Smariusvoid
88249199Smariuslog_ActivatePrompt(struct prompt *prompt)
89249199Smarius{
90195534Sscottl  prompt->active = 1;
91195534Sscottl  LogMaskLocal |= prompt->logmask;
92195534Sscottl}
93222520Smav
94222520Smavstatic void
95195534SscottlLogSetMaskLocal(void)
96195534Sscottl{
97195534Sscottl  struct prompt *p;
98224497Smav
99224497Smav  LogMaskLocal = MSK(LogERROR) | MSK(LogALERT) | MSK(LogWARN);
100195534Sscottl  for (p = promptlist; p; p = p->next)
101195534Sscottl    LogMaskLocal |= p->logmask;
102195534Sscottl}
103201139Smav
104195534Sscottlvoid
105195534Sscottllog_DeactivatePrompt(struct prompt *prompt)
106195534Sscottl{
107195534Sscottl  if (prompt->active) {
108195534Sscottl    prompt->active = 0;
109195534Sscottl    LogSetMaskLocal();
110195534Sscottl  }
111195534Sscottl}
112195534Sscottl
113198897Smavvoid
114195534Sscottllog_UnRegisterPrompt(struct prompt *prompt)
115198897Smav{
116198897Smav  if (prompt) {
117195534Sscottl    struct prompt **p;
118195534Sscottl
119222643Smav    for (p = &promptlist; *p; p = &(*p)->next)
120249934Ssmh      if (*p == prompt) {
121222643Smav        *p = prompt->next;
122201139Smav        prompt->next = NULL;
123249934Ssmh        break;
124222628Smav      }
125201139Smav    LogSetMaskLocal();
126201139Smav  }
127195534Sscottl}
128195534Sscottl
129201139Smavvoid
130195534Sscottllog_DestroyPrompts(struct server *s)
131195534Sscottl{
132195534Sscottl  struct prompt *p, *pn;
133248922Ssmh
134195534Sscottl  p = promptlist;
135195534Sscottl  while (p) {
136201139Smav    pn = p->next;
137201139Smav    if (s && p->owner != s) {
138224497Smav      p->next = NULL;
139220454Smav      prompt_Destroy(p, 1);
140220454Smav    }
141220454Smav    p = pn;
142220454Smav  }
143220454Smav}
144220454Smav
145220454Smavvoid
146195534Sscottllog_DisplayPrompts()
147195534Sscottl{
148195534Sscottl  struct prompt *p;
149195534Sscottl
150195534Sscottl  for (p = promptlist; p; p = p->next)
151195534Sscottl    prompt_Required(p);
152201139Smav}
153195534Sscottl
154195534Sscottlvoid
155195534Sscottllog_WritePrompts(struct datalink *dl, const char *data, int len)
156195534Sscottl{
157195534Sscottl  struct prompt *p;
158195534Sscottl
159195534Sscottl  for (p = promptlist; p; p = p->next)
160199178Smav    if (prompt_IsTermMode(p, dl))
161199178Smav      prompt_Printf(p, "%.*s", len, data);
162199178Smav}
163222520Smav
164222520Smavvoid
165222520Smavlog_SetTtyCommandMode(struct datalink *dl)
166222520Smav{
167222520Smav  struct prompt *p;
168222520Smav
169228819Smav  for (p = promptlist; p; p = p->next)
170228819Smav    if (prompt_IsTermMode(p, dl))
171228819Smav      prompt_TtyCommandMode(p);
172228819Smav}
173228819Smav
174222520Smavstatic int
175222520SmavsyslogLevel(int lev)
176222520Smav{
177222520Smav  switch (lev) {
178222520Smav  case LogDEBUG:
179222520Smav  case LogTIMER:
180222520Smav    return LOG_DEBUG;
181222520Smav  case LogWARN:
182222520Smav    return LOG_WARNING;
183228819Smav  case LogERROR:
184228819Smav    return LOG_ERR;
185228819Smav  case LogALERT:
186228819Smav    return LOG_ALERT;
187228819Smav  }
188228819Smav  return lev >= LogMIN && lev <= LogMAX ? LOG_INFO : 0;
189228819Smav}
190228819Smav
191228819Smavconst char *
192228819Smavlog_Name(int id)
193222520Smav{
194222520Smav  return id < LogMIN || id > LogMAX ? "Unknown" : LogNames[id - 1];
195222520Smav}
196222520Smav
197222520Smavvoid
198222520Smavlog_Keep(int id)
199222520Smav{
200222520Smav  if (id >= LogMIN && id <= LogMAXCONF)
201222520Smav    LogMask |= MSK(id);
202222520Smav}
203222520Smav
204228819Smavvoid
205228819Smavlog_KeepLocal(int id, u_long *mask)
206228819Smav{
207228819Smav  if (id >= LogMIN && id <= LogMAXCONF) {
208228819Smav    LogMaskLocal |= MSK(id);
209228819Smav    *mask |= MSK(id);
210228819Smav  }
211228819Smav}
212228819Smav
213228819Smavvoid
214222520Smavlog_Discard(int id)
215222520Smav{
216222520Smav  if (id >= LogMIN && id <= LogMAXCONF)
217222520Smav    LogMask &= ~MSK(id);
218222520Smav}
219222520Smav
220222520Smavvoid
221222520Smavlog_DiscardLocal(int id, u_long *mask)
222222520Smav{
223228819Smav  if (id >= LogMIN && id <= LogMAXCONF) {
224228819Smav    *mask &= ~MSK(id);
225228819Smav    LogSetMaskLocal();
226228819Smav  }
227228819Smav}
228222520Smav
229222520Smavvoid
230222520Smavlog_DiscardAll()
231222520Smav{
232222520Smav  LogMask = 0;
233222520Smav}
234222520Smav
235222520Smavvoid
236222520Smavlog_DiscardAllLocal(u_long *mask)
237222520Smav{
238222520Smav  *mask = MSK(LogERROR) | MSK(LogALERT) | MSK(LogWARN);
239222520Smav  LogSetMaskLocal();
240222520Smav}
241222520Smav
242222520Smavint
243222520Smavlog_IsKept(int id)
244222520Smav{
245222520Smav  if (id < LogMIN || id > LogMAX)
246222520Smav    return 0;
247222520Smav  if (id > LogMAXCONF)
248222520Smav    return LOG_KEPT_LOCAL | LOG_KEPT_SYSLOG;
249222520Smav
250222520Smav  return ((LogMaskLocal & MSK(id)) ? LOG_KEPT_LOCAL : 0) |
251222520Smav    ((LogMask & MSK(id)) ? LOG_KEPT_SYSLOG : 0);
252222520Smav}
253222520Smav
254222520Smavint
255222520Smavlog_IsKeptLocal(int id, u_long mask)
256222520Smav{
257222520Smav  if (id < LogMIN || id > LogMAX)
258222520Smav    return 0;
259222520Smav  if (id > LogMAXCONF)
260222520Smav    return LOG_KEPT_LOCAL | LOG_KEPT_SYSLOG;
261222520Smav
262222520Smav  return ((mask & MSK(id)) ? LOG_KEPT_LOCAL : 0) |
263222520Smav    ((LogMask & MSK(id)) ? LOG_KEPT_SYSLOG : 0);
264222520Smav}
265222520Smav
266222520Smavvoid
267222520Smavlog_Open(const char *Name)
268222520Smav{
269222520Smav  openlog(Name, LOG_PID, LOG_DAEMON);
270222520Smav}
271222520Smav
272222520Smavvoid
273241784Seadlerlog_SetTun(int tunno)
274241784Seadler{
275241784Seadler  LogTunno = tunno;
276241784Seadler}
277241784Seadler
278241784Seadlervoid
279241784Seadlerlog_Close()
280241784Seadler{
281241784Seadler  closelog();
282241784Seadler  LogTunno = -1;
283241784Seadler}
284241784Seadler
285241784Seadlervoid
286241784Seadlerlog_Printf(int lev, const char *fmt,...)
287241784Seadler{
288241784Seadler  va_list ap;
289241784Seadler  struct prompt *prompt;
290241784Seadler
291241784Seadler  va_start(ap, fmt);
292241784Seadler  if (log_IsKept(lev)) {
293241784Seadler    static char nfmt[200];
294241784Seadler
295241784Seadler    if ((log_IsKept(lev) & LOG_KEPT_LOCAL) && promptlist) {
296241784Seadler      if ((log_IsKept(LogTUN) & LOG_KEPT_LOCAL) && LogTunno != -1)
297241784Seadler        snprintf(nfmt, sizeof nfmt, "%s%d: %s: %s", TUN_NAME,
298241784Seadler	         LogTunno, log_Name(lev), fmt);
299241784Seadler      else
300241784Seadler        snprintf(nfmt, sizeof nfmt, "%s: %s", log_Name(lev), fmt);
301241784Seadler
302241784Seadler      for (prompt = promptlist; prompt; prompt = prompt->next)
303241784Seadler        if (lev > LogMAXCONF || (prompt->logmask & MSK(lev)))
304241784Seadler          prompt_vPrintf(prompt, nfmt, ap);
305241784Seadler    }
306241784Seadler
307241784Seadler    if ((log_IsKept(lev) & LOG_KEPT_SYSLOG) &&
308241784Seadler        (lev != LogWARN || !promptlist)) {
309241784Seadler      if ((log_IsKept(LogTUN) & LOG_KEPT_SYSLOG) && LogTunno != -1)
310241784Seadler        snprintf(nfmt, sizeof nfmt, "%s%d: %s: %s", TUN_NAME,
311241784Seadler	         LogTunno, log_Name(lev), fmt);
312241784Seadler      else
313241784Seadler        snprintf(nfmt, sizeof nfmt, "%s: %s", log_Name(lev), fmt);
314241784Seadler      vsyslog(syslogLevel(lev), nfmt, ap);
315241784Seadler    }
316241784Seadler  }
317241784Seadler  va_end(ap);
318241784Seadler}
319241784Seadler
320241784Seadlervoid
321241784Seadlerlog_DumpBp(int lev, const char *hdr, const struct mbuf * bp)
322241784Seadler{
323241784Seadler  if (log_IsKept(lev)) {
324241784Seadler    char buf[50];
325241784Seadler    char *b;
326241784Seadler    u_char *ptr;
327241784Seadler    int f;
328241784Seadler
329241784Seadler    if (hdr && *hdr)
330241784Seadler      log_Printf(lev, "%s\n", hdr);
331241784Seadler
332241784Seadler    b = buf;
333241784Seadler    do {
334241784Seadler      f = bp->cnt;
335241784Seadler      ptr = MBUF_CTOP(bp);
336241784Seadler      while (f--) {
337241784Seadler	sprintf(b, " %02x", (int) *ptr++);
338241784Seadler        b += 3;
339241784Seadler        if (b == buf + sizeof buf - 2) {
340241784Seadler          strcpy(b, "\n");
341241784Seadler          log_Printf(lev, buf);
342241784Seadler          b = buf;
343241784Seadler        }
344241784Seadler      }
345241784Seadler    } while ((bp = bp->next) != NULL);
346241784Seadler
347241784Seadler    if (b > buf) {
348241784Seadler      strcpy(b, "\n");
349241784Seadler      log_Printf(lev, buf);
350241784Seadler    }
351241784Seadler  }
352241784Seadler}
353241784Seadler
354241784Seadlervoid
355241784Seadlerlog_DumpBuff(int lev, const char *hdr, const u_char * ptr, int n)
356241784Seadler{
357241784Seadler  if (log_IsKept(lev)) {
358241784Seadler    char buf[50];
359241784Seadler    char *b;
360241784Seadler
361241784Seadler    if (hdr && *hdr)
362241784Seadler      log_Printf(lev, "%s\n", hdr);
363241784Seadler    while (n > 0) {
364241784Seadler      b = buf;
365241784Seadler      for (b = buf; b != buf + sizeof buf - 2 && n--; b += 3)
366241784Seadler	sprintf(b, " %02x", (int) *ptr++);
367241784Seadler      strcpy(b, "\n");
368241784Seadler      log_Printf(lev, buf);
369241784Seadler    }
370241784Seadler  }
371241784Seadler}
372241784Seadler
373241784Seadlerint
374241784Seadlerlog_ShowLevel(struct cmdargs const *arg)
375241784Seadler{
376241784Seadler  int i;
377241784Seadler
378241784Seadler  prompt_Printf(arg->prompt, "Log:  ");
379241784Seadler  for (i = LogMIN; i <= LogMAX; i++)
380241784Seadler    if (log_IsKept(i) & LOG_KEPT_SYSLOG)
381241784Seadler      prompt_Printf(arg->prompt, " %s", log_Name(i));
382241784Seadler
383199178Smav  prompt_Printf(arg->prompt, "\nLocal:");
384199178Smav  for (i = LogMIN; i <= LogMAX; i++)
385199178Smav    if (log_IsKeptLocal(i, arg->prompt->logmask) & LOG_KEPT_LOCAL)
386199178Smav      prompt_Printf(arg->prompt, " %s", log_Name(i));
387199178Smav
388199178Smav  prompt_Printf(arg->prompt, "\n");
389199178Smav
390199178Smav  return 0;
391195534Sscottl}
392195534Sscottl
393195534Sscottlint
394195534Sscottllog_SetLevel(struct cmdargs const *arg)
395195534Sscottl{
396195534Sscottl  int i, res, argc, local;
397195534Sscottl  char const *const *argv, *argp;
398195534Sscottl
399195534Sscottl  argc = arg->argc - arg->argn;
400195534Sscottl  argv = arg->argv + arg->argn;
401195534Sscottl  res = 0;
402195534Sscottl
403195534Sscottl  if (argc == 0 || strcasecmp(argv[0], "local"))
404195534Sscottl    local = 0;
405195534Sscottl  else {
406198897Smav    if (arg->prompt == NULL) {
407195534Sscottl      log_Printf(LogWARN, "set log local: Only available on the command line\n");
408195534Sscottl      return 1;
409195534Sscottl    }
410220650Smav    argc--;
411220650Smav    argv++;
412195534Sscottl    local = 1;
413221071Smav  }
414221071Smav
415221071Smav  if (argc == 0 || (argv[0][0] != '+' && argv[0][0] != '-')) {
416221071Smav    if (local)
417195534Sscottl      log_DiscardAllLocal(&arg->prompt->logmask);
418195534Sscottl    else
419195534Sscottl      log_DiscardAll();
420195534Sscottl  }
421195534Sscottl
422195534Sscottl  while (argc--) {
423195534Sscottl    argp = **argv == '+' || **argv == '-' ? *argv + 1 : *argv;
424195534Sscottl    for (i = LogMIN; i <= LogMAX; i++)
425195534Sscottl      if (strcasecmp(argp, log_Name(i)) == 0) {
426195534Sscottl	if (**argv == '-') {
427195534Sscottl          if (local)
428195534Sscottl            log_DiscardLocal(i, &arg->prompt->logmask);
429214279Sbrucec          else
430214279Sbrucec	    log_Discard(i);
431214279Sbrucec	} else if (local)
432214279Sbrucec          log_KeepLocal(i, &arg->prompt->logmask);
433220650Smav        else
434220650Smav          log_Keep(i);
435220650Smav	break;
436220650Smav      }
437224497Smav    if (i > LogMAX) {
438224497Smav      log_Printf(LogWARN, "%s: Invalid log value\n", argp);
439224497Smav      res = -1;
440224497Smav    }
441220412Smav    argv++;
442220412Smav  }
443220412Smav  return res;
444220412Smav}
445224497Smav
446224497Smavint
447224497Smavlog_ShowWho(struct cmdargs const *arg)
448224497Smav{
449248922Ssmh  struct prompt *p;
450248922Ssmh
451224497Smav  for (p = promptlist; p; p = p->next) {
452208349Smarius    prompt_Printf(arg->prompt, "%s (%s)", p->src.type, p->src.from);
453208349Smarius    if (p == arg->prompt)
454208349Smarius      prompt_Printf(arg->prompt, " *");
455208349Smarius    if (!p->active)
456208349Smarius      prompt_Printf(arg->prompt, " ^Z");
457208349Smarius    prompt_Printf(arg->prompt, "\n");
458208349Smarius  }
459195534Sscottl
460221071Smav  return 0;
461195534Sscottl}
462195534Sscottl