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