[BACK]Return to Log.c++ CVS log [TXT][DIR] Up to [Development] / fam / fam

Annotation of fam/fam/Log.c++, Revision 1.1

1.1     ! trev        1: //  Copyright (C) 1999-2002 Silicon Graphics, Inc.  All Rights Reserved.
        !             2: //
        !             3: //  This program is free software; you can redistribute it and/or modify it
        !             4: //  under the terms of version 2 of the GNU General Public License as
        !             5: //  published by the Free Software Foundation.
        !             6: //
        !             7: //  This program is distributed in the hope that it would be useful, but
        !             8: //  WITHOUT ANY WARRANTY; without even the implied warranty of
        !             9: //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  Further, any
        !            10: //  license provided herein, whether implied or otherwise, is limited to
        !            11: //  this program in accordance with the express provisions of the GNU
        !            12: //  General Public License.  Patent licenses, if any, provided herein do not
        !            13: //  apply to combinations of this program with other product or programs, or
        !            14: //  any other product whatsoever.  This program is distributed without any
        !            15: //  warranty that the program is delivered free of the rightful claim of any
        !            16: //  third person by way of infringement or the like.  See the GNU General
        !            17: //  Public License for more details.
        !            18: //
        !            19: //  You should have received a copy of the GNU General Public License along
        !            20: //  with this program; if not, write the Free Software Foundation, Inc., 59
        !            21: //  Temple Place - Suite 330, Boston MA 02111-1307, USA.
        !            22:
        !            23: #include "Log.h"
        !            24:
        !            25: #include <assert.h>
        !            26: #include <errno.h>
        !            27: #include <stdio.h>
        !            28: #include <stdlib.h>
        !            29: #include <string.h>
        !            30: #include <syslog.h>
        !            31: #include <sys/resource.h>
        !            32: #include <sys/stat.h>
        !            33: #include <sys/time.h>
        !            34: #include <sys/types.h>
        !            35: #include <unistd.h>
        !            36: #ifdef HAVE_AUDIT
        !            37: #include <sat.h>
        !            38: #endif
        !            39:
        !            40: Log::LogLevel Log::level         = ERROR;
        !            41: bool       Log::log_to_stderr = false;
        !            42: const char   *Log::program_name  = "fam";
        !            43: bool       Log::syslog_open   = false;
        !            44: unsigned      Log::count         = 0;
        !            45: #ifdef HAVE_AUDIT
        !            46: bool       Log::audit_enabled = true;
        !            47: #endif
        !            48:
        !            49: void
        !            50: Log::debug()
        !            51: {
        !            52:     level = DEBUG;
        !            53:     info("log level is LOG_DEBUG");
        !            54: }
        !            55:
        !            56: void
        !            57: Log::info()
        !            58: {
        !            59:     level = INFO;
        !            60:     info("log level is LOG_INFO");
        !            61: }
        !            62:
        !            63: void
        !            64: Log::error()
        !            65: {
        !            66:     level = INFO;
        !            67:     info("log level is LOG_ERR");
        !            68:     level = ERROR;
        !            69: }
        !            70:
        !            71: void
        !            72: Log::disable_audit()
        !            73: {
        !            74: #ifdef HAVE_AUDIT
        !            75:     audit_enabled = false;
        !            76:     info("disabling security audit trail");
        !            77: #endif
        !            78: }
        !            79:
        !            80: void
        !            81: Log::foreground()
        !            82: {
        !            83:     log_to_stderr = true;
        !            84:     if (syslog_open)
        !            85:     {   closelog();
        !            86: 	syslog_open = false;
        !            87:     }
        !            88: }
        !            89:
        !            90: void
        !            91: Log::background()
        !            92: {
        !            93:     log_to_stderr = false;
        !            94: }
        !            95:
        !            96: void
        !            97: Log::name(const char *newname)
        !            98: {
        !            99:     program_name = newname;
        !           100:     audit(true, "fam changing process name to \"%s\"", newname);
        !           101: }
        !           102:
        !           103: void
        !           104: Log::debug(const char *fmt, ...)
        !           105: {
        !           106:     if (level >= DEBUG)
        !           107:     {
        !           108: 	va_list a;
        !           109: 	va_start(a, fmt);
        !           110: 	vlog(DEBUG, fmt, a);
        !           111: 	va_end(a);
        !           112:     }
        !           113: }
        !           114:
        !           115: void
        !           116: Log::info(const char *fmt, ...)
        !           117: {
        !           118:     if (level >= INFO)
        !           119:     {
        !           120: 	va_list a;
        !           121: 	va_start(a, fmt);
        !           122: 	vlog(INFO, fmt, a);
        !           123: 	va_end(a);
        !           124:     }
        !           125: }
        !           126:
        !           127: void
        !           128: Log::error(const char *fmt, ...)
        !           129: {
        !           130:     if (level >= ERROR)
        !           131:     {
        !           132: 	va_list a;
        !           133: 	va_start(a, fmt);
        !           134: 	vlog(ERROR, fmt, a);
        !           135: 	va_end(a);
        !           136:     }
        !           137: }
        !           138:
        !           139: void
        !           140: Log::critical(const char *fmt, ...)
        !           141: {
        !           142:     if (level >= CRITICAL)
        !           143:     {
        !           144: 	va_list a;
        !           145: 	va_start(a, fmt);
        !           146: 	vlog(CRITICAL, fmt, a);
        !           147: 	va_end(a);
        !           148:     }
        !           149: }
        !           150:
        !           151: void
        !           152: Log::perror(const char *format, ...)
        !           153: {
        !           154:     if (level >= ERROR)
        !           155:     {   char * buf = new char[strlen(format) + 5];
        !           156: 	(void) strcpy(buf, format);
        !           157: 	(void) strcat(buf, ": %m");
        !           158: 	va_list args;
        !           159: 	va_start(args, format);
        !           160: 	vlog(ERROR, buf, args);
        !           161: 	va_end(args);
        !           162:         delete[] buf;
        !           163:     }
        !           164: }
        !           165:
        !           166: void
        !           167: Log::audit(bool success, const char *format, ...)
        !           168: {
        !           169: #ifdef HAVE_AUDIT
        !           170:     if (audit_enabled)
        !           171:     {
        !           172:         //  This is not so good.  If there were a version of satwrite
        !           173:         //  which took a va_list, this buffer would not need to be here.
        !           174:         char buf[SAT_MAX_USER_REC];
        !           175:         va_list args;
        !           176:         va_start(args, format);
        !           177:         int len = vsnprintf(buf, SAT_MAX_USER_REC, format, args);
        !           178:         va_end(args);
        !           179:         if(len > 0) satwrite(SAT_AE_CUSTOM, success ? SAT_SUCCESS : SAT_FAILURE,
        !           180:                              buf, len);
        !           181:     }
        !           182: #endif
        !           183: }
        !           184:
        !           185: //  This is like debug(), info(), & error(), but it logs regardless of the
        !           186: //  current log level.
        !           187: void
        !           188: Log::log(LogLevel l, const char *fmt, ...)
        !           189: {
        !           190:     va_list a;
        !           191:     va_start(a, fmt);
        !           192:     vlog(l, fmt, a);
        !           193:     va_end(a);
        !           194: }
        !           195:
        !           196: void
        !           197: Log::vlog(LogLevel l, const char *format, va_list args)
        !           198: {
        !           199:     if (log_to_stderr)
        !           200:         vfglog(format, args);
        !           201:     else {
        !           202:         if (!syslog_open) {
        !           203:             openlog(program_name, LOG_PID, LOG_DAEMON);
        !           204:             syslog_open = true;
        !           205:         }
        !           206:         int ll;
        !           207:         switch (l) {
        !           208:         case DEBUG:
        !           209:             ll = LOG_DEBUG; break;
        !           210:         case INFO:
        !           211:             ll = LOG_INFO;  break;
        !           212:         case ERROR:
        !           213:             ll = LOG_ERR;   break;
        !           214:         case CRITICAL:
        !           215:         default:
        !           216:             ll = LOG_CRIT;   break;
        !           217:         }
        !           218:         vsyslog(ll, format, args);
        !           219:     }
        !           220: }
        !           221:
        !           222: void
        !           223: Log::vfglog(const char *format, va_list args)
        !           224: {
        !           225:     // Count number of %'s in the format string.  That's the max
        !           226:     // number of %m's that there can be.
        !           227:     int numPercents = 0;
        !           228:     const char *pt = format;
        !           229:     while(*pt) {
        !           230:         if (*pt++ == '%') numPercents++;
        !           231:     }
        !           232:     char * err;
        !           233:
        !           234:     // Only get the error string if there's a chance we'll use it.
        !           235:     if (numPercents > 0) {
        !           236:         err =  strerror(errno);
        !           237:         if (err == NULL) {
        !           238:             err = "Unknown error";
        !           239:         }
        !           240:     } else {
        !           241:         err = "";
        !           242:     }
        !           243:
        !           244:     //  This 2 is for the \n and the null terminator added by the strcpy.
        !           245:     char *buf = new char[strlen(format) + 2 + strlen(err) *
        !           246:                         numPercents];
        !           247:     char *p = buf;
        !           248:     while (*format) {
        !           249:         if (format[0] == '%' && format[1] == 'm') {
        !           250:             p += strlen(strcpy(p, err));
        !           251:             format += 2;
        !           252:         } else {
        !           253:             *p++ = *format++;
        !           254:         }
        !           255:     }
        !           256:     (void) strcpy(p, "\n");
        !           257:     (void) fprintf(stderr, "%s[%d]: ", program_name, getpid());
        !           258:     (void) vfprintf(stderr, buf, args);
        !           259:     delete[] buf;
        !           260: }
        !           261:
        !           262: #ifndef NDEBUG
        !           263:
        !           264: //  New back end for assert() will log to syslog, put core file
        !           265: //  in known directory.
        !           266:
        !           267: void __assert(const char *msg, const char *file, int line)
        !           268: {
        !           269:     char *dirname = new char[strlen(Log::getName()) + 20];
        !           270:     (void) sprintf(dirname, "/usr/tmp/%s.%d", Log::getName(), getpid());
        !           271:     Log::error("Assertion failed at %s line %d: %s", file, line, msg);
        !           272:     Log::error("Dumping core in %s/core", dirname);
        !           273:
        !           274:     if (setreuid(0, 0) < 0)
        !           275: 	Log::perror("setreuid");
        !           276:     if (mkdir(dirname, 0755) < 0)
        !           277: 	Log::perror("mkdir");
        !           278:     if (chdir(dirname) < 0)
        !           279: 	Log::perror("chdir");
        !           280:     struct rlimit rl = { RLIM_INFINITY, RLIM_INFINITY };
        !           281:     if (setrlimit(RLIMIT_CORE, &rl) < 0)
        !           282: 	Log::perror("setrlimit(RLIMIT_CORE)");
        !           283:     delete[] dirname;
        !           284:     abort();
        !           285: }
        !           286:
        !           287: #endif /* !NDEBUG */
        !           288:
        !           289: #ifdef HAPPY_PURIFY
        !           290:
        !           291: Log::Log()
        !           292: {
        !           293:     count++;
        !           294: }
        !           295:
        !           296: Log::~Log()
        !           297: {
        !           298:     if (!--count)
        !           299:     {   if (syslog_open)
        !           300: 	{   closelog();
        !           301: 	    syslog_open = false;
        !           302: 	}
        !           303:     }
        !           304: }
        !           305:
        !           306: #endif /* HAPPY_PURIFY */
        !           307:
        !           308: #ifdef UNIT_TEST_Log
        !           309:
        !           310: #include <fcntl.h>
        !           311: #include <sys/stat.h>
        !           312:
        !           313: int
        !           314: main()
        !           315: {
        !           316:     Log::name("unit test");
        !           317:     Log::debug();
        !           318:     Log::foreground();
        !           319:     Log::debug("De bug is in %s.", "de rug");
        !           320:     Log::info("Thank %s for sharing %s.", "you", "that");
        !           321:     Log::error("The %s in %s falls.", "rain", "Spain");
        !           322:     if (open("/foo%bar", 0) < 0)
        !           323: 	Log::perror("/foo%c%s", '%', "bar");
        !           324:     if (chmod("/", 0777) < 0)
        !           325: 	Log::error("%m on chmod(\"%s\", 0%o)", "/", 0777);
        !           326:     return 0;
        !           327: }
        !           328:
        !           329: #endif /* UNIT_TEST_Log */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>