Annotation of src/usr.bin/tmux/log.c, Revision 1.1
1.1 ! nicm 1: /* $OpenBSD$ */
! 2:
! 3: /*
! 4: * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
! 5: *
! 6: * Permission to use, copy, modify, and distribute this software for any
! 7: * purpose with or without fee is hereby granted, provided that the above
! 8: * copyright notice and this permission notice appear in all copies.
! 9: *
! 10: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
! 11: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
! 12: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
! 13: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
! 14: * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
! 15: * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
! 16: * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
! 17: */
! 18:
! 19: #include <sys/types.h>
! 20:
! 21: #include <errno.h>
! 22: #include <stdio.h>
! 23: #include <stdlib.h>
! 24: #include <string.h>
! 25: #include <syslog.h>
! 26: #include <time.h>
! 27:
! 28: #include "tmux.h"
! 29:
! 30: /* Logging type. */
! 31: #define LOG_TYPE_OFF 0
! 32: #define LOG_TYPE_SYSLOG 1
! 33: #define LOG_TYPE_TTY 2
! 34: #define LOG_TYPE_FILE 3
! 35: int log_type = LOG_TYPE_OFF;
! 36:
! 37: /* Log file, if needed. */
! 38: FILE *log_file;
! 39:
! 40: /* Debug level. */
! 41: int log_level;
! 42:
! 43: /* Open logging to syslog. */
! 44: void
! 45: log_open_syslog(int level)
! 46: {
! 47: log_type = LOG_TYPE_SYSLOG;
! 48: log_level = level;
! 49:
! 50: openlog(__progname, LOG_PID|LOG_NDELAY, LOG_FACILITY);
! 51:
! 52: tzset();
! 53: }
! 54:
! 55: /* Open logging to tty. */
! 56: void
! 57: log_open_tty(int level)
! 58: {
! 59: log_type = LOG_TYPE_TTY;
! 60: log_level = level;
! 61:
! 62: setlinebuf(stderr);
! 63: setlinebuf(stdout);
! 64:
! 65: tzset();
! 66: }
! 67:
! 68: /* Open logging to file. */
! 69: void
! 70: log_open_file(int level, const char *path)
! 71: {
! 72: log_file = fopen(path, "w");
! 73: if (log_file == NULL)
! 74: return;
! 75:
! 76: log_type = LOG_TYPE_FILE;
! 77: log_level = level;
! 78:
! 79: setlinebuf(log_file);
! 80:
! 81: tzset();
! 82: }
! 83:
! 84: /* Close logging. */
! 85: void
! 86: log_close(void)
! 87: {
! 88: if (log_type == LOG_TYPE_FILE)
! 89: fclose(log_file);
! 90:
! 91: log_type = LOG_TYPE_OFF;
! 92: }
! 93:
! 94: /* Write a log message. */
! 95: void
! 96: log_write(int pri, const char *msg, ...)
! 97: {
! 98: va_list ap;
! 99:
! 100: va_start(ap, msg);
! 101: log_vwrite(pri, msg, ap);
! 102: va_end(ap);
! 103: }
! 104:
! 105: /* Write a log message. */
! 106: void
! 107: log_vwrite(int pri, const char *msg, va_list ap)
! 108: {
! 109: char *fmt;
! 110: FILE *f = log_file;
! 111:
! 112: switch (log_type) {
! 113: case LOG_TYPE_SYSLOG:
! 114: vsyslog(pri, msg, ap);
! 115: break;
! 116: case LOG_TYPE_TTY:
! 117: if (pri == LOG_INFO)
! 118: f = stdout;
! 119: else
! 120: f = stderr;
! 121: /* FALLTHROUGH */
! 122: case LOG_TYPE_FILE:
! 123: if (asprintf(&fmt, "%s\n", msg) == -1)
! 124: exit(1);
! 125: if (vfprintf(f, fmt, ap) == -1)
! 126: exit(1);
! 127: fflush(f);
! 128: free(fmt);
! 129: break;
! 130: }
! 131: }
! 132:
! 133: /* Log a warning with error string. */
! 134: void printflike1
! 135: log_warn(const char *msg, ...)
! 136: {
! 137: va_list ap;
! 138: char *fmt;
! 139:
! 140: va_start(ap, msg);
! 141: if (asprintf(&fmt, "%s: %s", msg, strerror(errno)) == -1)
! 142: exit(1);
! 143: log_vwrite(LOG_CRIT, fmt, ap);
! 144: free(fmt);
! 145: va_end(ap);
! 146: }
! 147:
! 148: /* Log a warning. */
! 149: void printflike1
! 150: log_warnx(const char *msg, ...)
! 151: {
! 152: va_list ap;
! 153:
! 154: va_start(ap, msg);
! 155: log_vwrite(LOG_CRIT, msg, ap);
! 156: va_end(ap);
! 157: }
! 158:
! 159: /* Log an informational message. */
! 160: void printflike1
! 161: log_info(const char *msg, ...)
! 162: {
! 163: va_list ap;
! 164:
! 165: if (log_level > -1) {
! 166: va_start(ap, msg);
! 167: log_vwrite(LOG_INFO, msg, ap);
! 168: va_end(ap);
! 169: }
! 170: }
! 171:
! 172: /* Log a debug message. */
! 173: void printflike1
! 174: log_debug(const char *msg, ...)
! 175: {
! 176: va_list ap;
! 177:
! 178: if (log_level > 0) {
! 179: va_start(ap, msg);
! 180: log_vwrite(LOG_DEBUG, msg, ap);
! 181: va_end(ap);
! 182: }
! 183: }
! 184:
! 185: /* Log a debug message at level 2. */
! 186: void printflike1
! 187: log_debug2(const char *msg, ...)
! 188: {
! 189: va_list ap;
! 190:
! 191: if (log_level > 1) {
! 192: va_start(ap, msg);
! 193: log_vwrite(LOG_DEBUG, msg, ap);
! 194: va_end(ap);
! 195: }
! 196: }
! 197:
! 198: /* Log a debug message at level 3. */
! 199: void printflike1
! 200: log_debug3(const char *msg, ...)
! 201: {
! 202: va_list ap;
! 203:
! 204: if (log_level > 2) {
! 205: va_start(ap, msg);
! 206: log_vwrite(LOG_DEBUG, msg, ap);
! 207: va_end(ap);
! 208: }
! 209: }
! 210:
! 211: /* Log a critical error, with error string if necessary, and die. */
! 212: __dead void
! 213: log_vfatal(const char *msg, va_list ap)
! 214: {
! 215: char *fmt;
! 216:
! 217: if (errno != 0) {
! 218: if (asprintf(&fmt, "fatal: %s: %s", msg, strerror(errno)) == -1)
! 219: exit(1);
! 220: log_vwrite(LOG_CRIT, fmt, ap);
! 221: } else {
! 222: if (asprintf(&fmt, "fatal: %s", msg) == -1)
! 223: exit(1);
! 224: log_vwrite(LOG_CRIT, fmt, ap);
! 225: }
! 226: free(fmt);
! 227:
! 228: exit(1);
! 229: }
! 230:
! 231: /* Log a critical error, with error string, and die. */
! 232: __dead void printflike1
! 233: log_fatal(const char *msg, ...)
! 234: {
! 235: va_list ap;
! 236:
! 237: va_start(ap, msg);
! 238: log_vfatal(msg, ap);
! 239: }
! 240:
! 241: /* Log a critical error and die. */
! 242: __dead void printflike1
! 243: log_fatalx(const char *msg, ...)
! 244: {
! 245: va_list ap;
! 246:
! 247: errno = 0;
! 248: va_start(ap, msg);
! 249: log_vfatal(msg, ap);
! 250: }