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