1 /*
2  * Copyright (C) 2000-2008 - Shaun Clowes <delius@progsoc.org>
3  * 				 2008-2011 - Robert Hogan <robert@roberthogan.net>
4  * 				 	  2013 - David Goulet <dgoulet@ev0ke.net>
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License, version 2 only, as
8  * published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13  * more details.
14  *
15  * You should have received a copy of the GNU General Public License along with
16  * this program; if not, write to the Free Software Foundation, Inc., 51
17  * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 #ifndef TORSOCKS_LOG_H
21 #define TORSOCKS_LOG_H
22 
23 #include <errno.h>
24 #include <string.h>
25 #include <sys/types.h>
26 #include <unistd.h>
27 
28 #include "compat.h"
29 
30 /* Stringify the expansion of a define */
31 #define XSTR(d) STR(d)
32 #define STR(s) #s
33 
34 #define MSGNONE		0x1
35 #define MSGERR		0x2
36 #define MSGWARN		0x3
37 #define MSGNOTICE	0x4
38 #define MSGDEBUG	0x5
39 
40 /*
41  * Used during logging initialization whether or not to add the time or
42  * suppress it from a log entry.
43  */
44 enum log_time_status {
45 	LOG_TIME_NONE	= 0,
46 	LOG_TIME_ADD	= 1,
47 };
48 
49 extern int tsocks_loglevel;
50 
51 void log_print(const char *fmt, ...);
52 int log_init(int level, const char *filepath, enum log_time_status t_status);
53 void log_destroy(void);
54 void log_fd_close_notify(int fd);
55 
56 #define __tsocks_print(level, fmt, args...) \
57 	do { \
58 		if (level != MSGNONE && level <= tsocks_loglevel) { \
59 			log_print(fmt, ## args); \
60 		} \
61 	} while (0)
62 
63 #define _ERRMSG(msg, type, fmt, args...) __tsocks_print(type, msg \
64 		" torsocks[%ld]: " fmt " (in %s() at " __FILE__ ":" XSTR(__LINE__) ")\n", \
65 		(long) getpid(), ## args, __func__)
66 
67 #define MSG(fmt, args...) __tsocks_print(MSGNOTICE, fmt "\n", ## args)
68 #define ERR(fmt, args...) _ERRMSG("ERROR", MSGERR, fmt, ## args)
69 #define WARN(fmt, args...) _ERRMSG("WARNING", MSGWARN, fmt, ## args)
70 #define DBG(fmt, args...) _ERRMSG("DEBUG", MSGDEBUG, fmt, ## args)
71 
72 /*
73  * Local wrapper used by the PERROR() call below. Should NOT be used outside of
74  * this scope.
75  */
76 #define _PERROR(fmt, args...) _ERRMSG("PERROR", MSGERR, fmt, ## args)
77 
78 #if !defined(__linux__) || \
79 	((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !defined(_GNU_SOURCE)) || \
80 	!defined(__GLIBC__)
81 
82 /*
83  * Version using XSI strerror_r.
84  */
85 #define PERROR(call, args...) \
86 	do { \
87 		char buf[200]; \
88 		strerror_r(errno, buf, sizeof(buf)); \
89 		_PERROR(call ": %s", ## args, buf); \
90 	} while(0);
91 
92 #else /* _POSIX_C_SOURCE */
93 
94 /*
95  * Version using GNU strerror_r, for linux with appropriate defines.
96  */
97 #define PERROR(call, args...) \
98 	do { \
99 		char *buf; \
100 		char tmp[200]; \
101 		buf = strerror_r(errno, tmp, sizeof(tmp)); \
102 		_PERROR(call ": %s", ## args, buf); \
103 	} while(0);
104 
105 #endif /* _POSIX_C_SOURCE */
106 
107 #endif /* TORSOCKS_LOG_H */
108