log.c revision 49527
125184Sjkh/*- 225184Sjkh * Copyright (c) 1997 Brian Somers <brian@Awfulhak.org> 350472Speter * All rights reserved. 425184Sjkh * 525184Sjkh * Redistribution and use in source and binary forms, with or without 625184Sjkh * modification, are permitted provided that the following conditions 725184Sjkh * are met: 825184Sjkh * 1. Redistributions of source code must retain the above copyright 925184Sjkh * notice, this list of conditions and the following disclaimer. 1025184Sjkh * 2. Redistributions in binary form must reproduce the above copyright 1125184Sjkh * notice, this list of conditions and the following disclaimer in the 1225184Sjkh * documentation and/or other materials provided with the distribution. 1325184Sjkh * 1425184Sjkh * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1525184Sjkh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1625184Sjkh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1750357Ssheldonh * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1825184Sjkh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1925184Sjkh * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2025184Sjkh * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2125184Sjkh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2250357Ssheldonh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2350357Ssheldonh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2425184Sjkh * SUCH DAMAGE. 2525184Sjkh * 2625184Sjkh * $Id: log.c,v 1.39 1999/06/01 16:01:48 brian Exp $ 2725184Sjkh */ 2840006Sphk 2950357Ssheldonh#include <sys/types.h> 3040006Sphk 3140006Sphk#include <ctype.h> 3240006Sphk#include <stdarg.h> 3340006Sphk#include <stdio.h> 3442621Shm#include <string.h> 3550357Ssheldonh#include <syslog.h> 3642621Shm#include <termios.h> 3742621Shm 3842621Shm#include "defs.h" 3942627Sjoerg#include "command.h" 4042627Sjoerg#include "mbuf.h" 4142627Sjoerg#include "log.h" 4242627Sjoerg#include "descriptor.h" 4342627Sjoerg#include "prompt.h" 4442627Sjoerg 4542627Sjoergstatic const char *LogNames[] = { 4642627Sjoerg "Async", 4742627Sjoerg "CBCP", 4842627Sjoerg "CCP", 4942627Sjoerg "Chat", 5042627Sjoerg "Command", 5142627Sjoerg "Connect", 5242627Sjoerg "Debug", 5325184Sjkh "HDLC", 5450357Ssheldonh "ID0", 5548687Speter "IPCP", 5648687Speter "LCP", 5748687Speter "LQM", 5848662Speter "Phase", 5925184Sjkh "Physical", 6033682Sbrian "Sync", 6148662Speter "TCP/IP", 6225184Sjkh "Timer", 6325184Sjkh "Tun", 6425184Sjkh "Warning", 6525184Sjkh "Error", 6648842Sjkh "Alert" 6750470Sjkh}; 6848842Sjkh 6948842Sjkh#define MSK(n) (1<<((n)-1)) 7048842Sjkh 7148842Sjkhstatic u_long LogMask = MSK(LogPHASE); 7248662Speterstatic u_long LogMaskLocal = MSK(LogERROR) | MSK(LogALERT) | MSK(LogWARN); 7325184Sjkhstatic int LogTunno = -1; 7425184Sjkhstatic struct prompt *promptlist; /* Where to log local stuff */ 7525184Sjkhint log_PromptListChanged; 7625184Sjkh 7725184Sjkhstruct prompt * 7825184Sjkhlog_PromptList() 7925184Sjkh{ 8025184Sjkh return promptlist; 8148662Speter} 8225184Sjkh 8325184Sjkhvoid 8425184Sjkhlog_RegisterPrompt(struct prompt *prompt) 8525184Sjkh{ 8625184Sjkh prompt->next = promptlist; 8725184Sjkh promptlist = prompt; 8825184Sjkh prompt->active = 1; 8925184Sjkh log_DiscardAllLocal(&prompt->logmask); 9025184Sjkh} 9148662Speter 9225184Sjkhvoid 9348662Speterlog_ActivatePrompt(struct prompt *prompt) 9448662Speter{ 9548662Speter prompt->active = 1; 9648662Speter LogMaskLocal |= prompt->logmask; 9725184Sjkh} 9829300Sdanny 9949122Sbrianstatic void 10050357SsheldonhLogSetMaskLocal(void) 10149122Sbrian{ 10250357Ssheldonh struct prompt *p; 10350357Ssheldonh 10449122Sbrian LogMaskLocal = MSK(LogERROR) | MSK(LogALERT) | MSK(LogWARN); 10549122Sbrian for (p = promptlist; p; p = p->next) 10649122Sbrian LogMaskLocal |= p->logmask; 10749122Sbrian} 10849122Sbrian 10950357Ssheldonhvoid 11050193Sbrianlog_DeactivatePrompt(struct prompt *prompt) 11149122Sbrian{ 11249122Sbrian if (prompt->active) { 11350063Sbrian prompt->active = 0; 11449122Sbrian LogSetMaskLocal(); 11549122Sbrian } 11629300Sdanny} 11729300Sdanny 11829300Sdannyvoid 11932382Salexlog_UnRegisterPrompt(struct prompt *prompt) 12032382Salex{ 12132382Salex if (prompt) { 12229300Sdanny struct prompt **p; 12329300Sdanny 12429300Sdanny for (p = &promptlist; *p; p = &(*p)->next) 12550357Ssheldonh if (*p == prompt) { 12641077Speter *p = prompt->next; 12729300Sdanny prompt->next = NULL; 12829300Sdanny break; 12929300Sdanny } 13029300Sdanny LogSetMaskLocal(); 13129300Sdanny log_PromptListChanged++; 13229300Sdanny } 13329300Sdanny} 13429300Sdanny 13550357Ssheldonhvoid 13645542Sdeslog_DestroyPrompts(struct server *s) 13745542Sdes{ 13845542Sdes struct prompt *p, *pn, *pl; 13950357Ssheldonh 14045542Sdes p = promptlist; 14145622Sbrian pl = NULL; 14244992Sbrian while (p) { 14344992Sbrian pn = p->next; 14450357Ssheldonh if (s && p->owner == s) { 14544992Sbrian if (pl) 14644992Sbrian pl->next = p->next; 14744992Sbrian else 14844992Sbrian promptlist = p->next; 14944992Sbrian p->next = NULL; 15044992Sbrian prompt_Destroy(p, 1); 15144992Sbrian } else 15244992Sbrian pl = p; 15344992Sbrian p = pn; 15429300Sdanny } 15533337Salex} 15650357Ssheldonh 15733149Salexvoid 15833149Salexlog_DisplayPrompts() 15933149Salex{ 16033149Salex struct prompt *p; 16129300Sdanny 16225184Sjkh for (p = promptlist; p; p = p->next) 16325184Sjkh prompt_Required(p); 16440006Sphk} 16540006Sphk 16640006Sphkvoid 16740006Sphklog_WritePrompts(struct datalink *dl, const char *fmt,...) 16840006Sphk{ 16929300Sdanny va_list ap; 17029300Sdanny struct prompt *p; 17150357Ssheldonh 17225184Sjkh va_start(ap, fmt); 17325184Sjkh for (p = promptlist; p; p = p->next) 17425184Sjkh if (prompt_IsTermMode(p, dl)) 17525184Sjkh prompt_vPrintf(p, fmt, ap); 17625184Sjkh va_end(ap); 17750357Ssheldonh} 17825184Sjkh 17925184Sjkhvoid 18025184Sjkhlog_SetTtyCommandMode(struct datalink *dl) 18125184Sjkh{ 18225184Sjkh struct prompt *p; 18325184Sjkh 18425184Sjkh for (p = promptlist; p; p = p->next) 18550357Ssheldonh if (prompt_IsTermMode(p, dl)) 18627218Spst prompt_TtyCommandMode(p); 18747755Sbde} 18827218Spst 18927218Spststatic int 19050357SsheldonhsyslogLevel(int lev) 19145096Simp{ 19247755Sbde switch (lev) { 19347755Sbde case LogDEBUG: 19445096Simp case LogTIMER: 19545096Simp return LOG_DEBUG; 19650357Ssheldonh case LogWARN: 19739267Sjkoshy return LOG_WARNING; 19847755Sbde case LogERROR: 19939267Sjkoshy return LOG_ERR; 20049603Sdes case LogALERT: 20150357Ssheldonh return LOG_ALERT; 20249603Sdes } 20349603Sdes return lev >= LogMIN && lev <= LogMAX ? LOG_INFO : 0; 20449603Sdes} 20549603Sdes 20650357Ssheldonhconst char * 20749603Sdeslog_Name(int id) 20849603Sdes{ 20949603Sdes return id < LogMIN || id > LogMAX ? "Unknown" : LogNames[id - 1]; 21039267Sjkoshy} 21150357Ssheldonh 21225365Sjkhvoid 21347755Sbdelog_Keep(int id) 21425184Sjkh{ 21525184Sjkh if (id >= LogMIN && id <= LogMAXCONF) 21650357Ssheldonh LogMask |= MSK(id); 21733439Sguido} 21847755Sbde 21933439Sguidovoid 22033439Sguidolog_KeepLocal(int id, u_long *mask) 22150357Ssheldonh{ 22233439Sguido if (id >= LogMIN && id <= LogMAXCONF) { 22347755Sbde LogMaskLocal |= MSK(id); 22433439Sguido *mask |= MSK(id); 22533439Sguido } 22650357Ssheldonh} 22747752Sphk 22847755Sbdevoid 22947752Sphklog_Discard(int id) 23047752Sphk{ 23150357Ssheldonh if (id >= LogMIN && id <= LogMAXCONF) 23225365Sjkh LogMask &= ~MSK(id); 23347755Sbde} 23425184Sjkh 23525184Sjkhvoid 23650357Ssheldonhlog_DiscardLocal(int id, u_long *mask) 23747755Sbde{ 23847755Sbde if (id >= LogMIN && id <= LogMAXCONF) { 23936174Sjkh *mask &= ~MSK(id); 24036174Sjkh LogSetMaskLocal(); 24136174Sjkh } 24236174Sjkh} 24350357Ssheldonh 24436174Sjkhvoid 24536174Sjkhlog_DiscardAll() 24636174Sjkh{ 24750357Ssheldonh LogMask = 0; 24836174Sjkh} 24925184Sjkh 25025184Sjkhvoid 25125765Sjkhlog_DiscardAllLocal(u_long *mask) 25250357Ssheldonh{ 25336174Sjkh *mask = MSK(LogERROR) | MSK(LogALERT) | MSK(LogWARN); 25425765Sjkh LogSetMaskLocal(); 25536174Sjkh} 25650357Ssheldonh 25734395Sjkhint 25834395Sjkhlog_IsKept(int id) 25925184Sjkh{ 26025184Sjkh if (id < LogMIN || id > LogMAX) 26125184Sjkh return 0; 26225184Sjkh if (id > LogMAXCONF) 26325184Sjkh return LOG_KEPT_LOCAL | LOG_KEPT_SYSLOG; 26425184Sjkh 26550357Ssheldonh return ((LogMaskLocal & MSK(id)) ? LOG_KEPT_LOCAL : 0) | 26632949Swollman ((LogMask & MSK(id)) ? LOG_KEPT_SYSLOG : 0); 26725184Sjkh} 26825184Sjkh 26950357Ssheldonhint 27035787Sandreaslog_IsKeptLocal(int id, u_long mask) 27131472Sobrien{ 27225184Sjkh if (id < LogMIN || id > LogMAX) 27350357Ssheldonh return 0; 27435787Sandreas if (id > LogMAXCONF) 27525184Sjkh return LOG_KEPT_LOCAL | LOG_KEPT_SYSLOG; 27625184Sjkh 27750357Ssheldonh return ((mask & MSK(id)) ? LOG_KEPT_LOCAL : 0) | 27825184Sjkh ((LogMask & MSK(id)) ? LOG_KEPT_SYSLOG : 0); 27925184Sjkh} 28025184Sjkh 28150357Ssheldonhvoid 28244668Sjfitzlog_Open(const char *Name) 28325184Sjkh{ 28425184Sjkh openlog(Name, LOG_PID, LOG_DAEMON); 28525184Sjkh} 28625184Sjkh 28750357Ssheldonhvoid 28825184Sjkhlog_SetTun(int tunno) 28925184Sjkh{ 29050357Ssheldonh LogTunno = tunno; 29125184Sjkh} 29225184Sjkh 29325184Sjkhvoid 29450357Ssheldonhlog_Close() 29525184Sjkh{ 29625184Sjkh closelog(); 29725184Sjkh LogTunno = -1; 29825184Sjkh} 29925184Sjkh 30050357Ssheldonhvoid 30125184Sjkhlog_Printf(int lev, const char *fmt,...) 30250357Ssheldonh{ 30325184Sjkh va_list ap; 30425184Sjkh struct prompt *prompt; 30525184Sjkh 30625184Sjkh va_start(ap, fmt); 30735149Smarkm if (log_IsKept(lev)) { 30850357Ssheldonh char nfmt[200]; 30935149Smarkm 31035149Smarkm if ((log_IsKept(lev) & LOG_KEPT_LOCAL) && promptlist) { 31135149Smarkm if ((log_IsKept(LogTUN) & LOG_KEPT_LOCAL) && LogTunno != -1) 31250357Ssheldonh snprintf(nfmt, sizeof nfmt, "%s%d: %s: %s", TUN_NAME, 31335149Smarkm LogTunno, log_Name(lev), fmt); 31435149Smarkm else 31535149Smarkm snprintf(nfmt, sizeof nfmt, "%s: %s", log_Name(lev), fmt); 31640006Sphk 31740006Sphk for (prompt = promptlist; prompt; prompt = prompt->next) 31840006Sphk if (lev > LogMAXCONF || (prompt->logmask & MSK(lev))) 31940006Sphk prompt_vPrintf(prompt, nfmt, ap); 32040006Sphk } 32125184Sjkh 32225184Sjkh if ((log_IsKept(lev) & LOG_KEPT_SYSLOG) && 32325184Sjkh (lev != LogWARN || !promptlist)) { 32425184Sjkh if ((log_IsKept(LogTUN) & LOG_KEPT_SYSLOG) && LogTunno != -1) 32525184Sjkh snprintf(nfmt, sizeof nfmt, "%s%d: %s: %s", TUN_NAME, 32625184Sjkh LogTunno, log_Name(lev), fmt); 32725184Sjkh else 32850357Ssheldonh snprintf(nfmt, sizeof nfmt, "%s: %s", log_Name(lev), fmt); 32925184Sjkh vsyslog(syslogLevel(lev), nfmt, ap); 33050357Ssheldonh } 33125184Sjkh } 33225184Sjkh va_end(ap); 33325184Sjkh} 33450357Ssheldonh 33547755Sbdevoid 33647755Sbdelog_DumpBp(int lev, const char *hdr, const struct mbuf *bp) 33725184Sjkh{ 33825916Sjkh if (log_IsKept(lev)) { 33950357Ssheldonh char buf[68]; 34025184Sjkh char *b, *c; 34125184Sjkh const u_char *ptr; 34250357Ssheldonh int f; 34325184Sjkh 34425184Sjkh if (hdr && *hdr) 34525184Sjkh log_Printf(lev, "%s\n", hdr); 34625184Sjkh 34750357Ssheldonh b = buf; 34825916Sjkh c = b + 50; 34950357Ssheldonh do { 35047755Sbde f = bp->cnt; 35141371Sjkoshy ptr = CONST_MBUF_CTOP(bp); 35247755Sbde while (f--) { 35341185Smsmith sprintf(b, " %02x", (int) *ptr); 35425184Sjkh *c++ = isprint(*ptr) ? *ptr : '.'; 35525184Sjkh ptr++; 35650357Ssheldonh b += 3; 35725184Sjkh if (b == buf + 48) { 35850357Ssheldonh memset(b, ' ', 2); 35939380Scracauer *c = '\0'; 36035459Sphk log_Printf(lev, "%s\n", buf); 36150357Ssheldonh b = buf; 36247838Sbrian c = b + 50; 36347838Sbrian } 36447838Sbrian } 36547838Sbrian } while ((bp = bp->next) != NULL); 36647838Sbrian 36725184Sjkh if (b > buf) { 36825184Sjkh memset(b, ' ', 50 - (b - buf)); 36950357Ssheldonh *c = '\0'; 37042270Sjkh log_Printf(lev, "%s\n", buf); 37125184Sjkh } 37225184Sjkh } 37325184Sjkh} 37450357Ssheldonh 37550357Ssheldonhvoid 37631033Sseflog_DumpBuff(int lev, const char *hdr, const u_char *ptr, int n) 37731033Ssef{ 37831033Ssef if (log_IsKept(lev)) { 37931033Ssef char buf[68]; 38031033Ssef char *b, *c; 38138316Sphk 38250357Ssheldonh if (hdr && *hdr) 38331033Ssef log_Printf(lev, "%s\n", hdr); 38438316Sphk while (n > 0) { 38531033Ssef b = buf; 38631033Ssef c = b + 50; 38725184Sjkh for (b = buf; b != buf + 48 && n--; b += 3, ptr++) { 38825184Sjkh sprintf(b, " %02x", (int) *ptr); 38925184Sjkh *c++ = isprint(*ptr) ? *ptr : '.'; 39025184Sjkh } 39125184Sjkh memset(b, ' ', 50 - (b - buf)); 392 *c = '\0'; 393 log_Printf(lev, "%s\n", buf); 394 } 395 } 396} 397 398int 399log_ShowLevel(struct cmdargs const *arg) 400{ 401 int i; 402 403 prompt_Printf(arg->prompt, "Log: "); 404 for (i = LogMIN; i <= LogMAX; i++) 405 if (log_IsKept(i) & LOG_KEPT_SYSLOG) 406 prompt_Printf(arg->prompt, " %s", log_Name(i)); 407 408 prompt_Printf(arg->prompt, "\nLocal:"); 409 for (i = LogMIN; i <= LogMAX; i++) 410 if (log_IsKeptLocal(i, arg->prompt->logmask) & LOG_KEPT_LOCAL) 411 prompt_Printf(arg->prompt, " %s", log_Name(i)); 412 413 prompt_Printf(arg->prompt, "\n"); 414 415 return 0; 416} 417 418int 419log_SetLevel(struct cmdargs const *arg) 420{ 421 int i, res, argc, local; 422 char const *const *argv, *argp; 423 424 argc = arg->argc - arg->argn; 425 argv = arg->argv + arg->argn; 426 res = 0; 427 428 if (argc == 0 || strcasecmp(argv[0], "local")) 429 local = 0; 430 else { 431 if (arg->prompt == NULL) { 432 log_Printf(LogWARN, "set log local: Only available on the command line\n"); 433 return 1; 434 } 435 argc--; 436 argv++; 437 local = 1; 438 } 439 440 if (argc == 0 || (argv[0][0] != '+' && argv[0][0] != '-')) { 441 if (local) 442 log_DiscardAllLocal(&arg->prompt->logmask); 443 else 444 log_DiscardAll(); 445 } 446 447 while (argc--) { 448 argp = **argv == '+' || **argv == '-' ? *argv + 1 : *argv; 449 for (i = LogMIN; i <= LogMAX; i++) 450 if (strcasecmp(argp, log_Name(i)) == 0) { 451 if (**argv == '-') { 452 if (local) 453 log_DiscardLocal(i, &arg->prompt->logmask); 454 else 455 log_Discard(i); 456 } else if (local) 457 log_KeepLocal(i, &arg->prompt->logmask); 458 else 459 log_Keep(i); 460 break; 461 } 462 if (i > LogMAX) { 463 log_Printf(LogWARN, "%s: Invalid log value\n", argp); 464 res = -1; 465 } 466 argv++; 467 } 468 return res; 469} 470 471int 472log_ShowWho(struct cmdargs const *arg) 473{ 474 struct prompt *p; 475 476 for (p = promptlist; p; p = p->next) { 477 prompt_Printf(arg->prompt, "%s (%s)", p->src.type, p->src.from); 478 if (p == arg->prompt) 479 prompt_Printf(arg->prompt, " *"); 480 if (!p->active) 481 prompt_Printf(arg->prompt, " ^Z"); 482 prompt_Printf(arg->prompt, "\n"); 483 } 484 485 return 0; 486} 487