1 /*
2  * uhub - A tiny ADC p2p connection hub
3  * Copyright (C) 2007-2014, Jan Vidar Krey
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  *
18  */
19 
20 #include "uhub.h"
21 #include <locale.h>
22 
23 #ifndef WIN32
24 
25 #ifdef SYSTEMD
26 #define SD_JOURNAL_SUPPRESS_LOCATION
27 #include <systemd/sd-journal.h>
28 
29 #else
30 #include <syslog.h>
31 #endif
32 
33 static int use_syslog = 0;
34 #endif
35 
36 static int verbosity = 4;
37 static FILE* logfile = NULL;
38 
39 #ifdef MEMORY_DEBUG
40 static FILE* memfile = NULL;
41 #define MEMORY_DEBUG_FILE "memlog.txt"
42 #endif
43 
44 #ifdef NETWORK_DUMP_DEBUG
45 #define NETWORK_DUMP_FILE "netdump.log"
46 static FILE* netdump = NULL;
47 #endif
48 
49 
50 static const char* prefixes[] =
51 {
52 	"FATAL",
53 	"ERROR",
54 	"WARN",
55 	"USER",
56 	"INFO",
57 	"DEBUG",
58 	"TRACE",
59 	"DUMP",
60 	"MEM",
61 	"PROTO",
62 	"PLUGIN",
63 	0
64 };
65 
66 
hub_log_initialize(const char * file,int syslog)67 void hub_log_initialize(const char* file, int syslog)
68 {
69 
70 	setlocale(LC_ALL, "C");
71 
72 #ifdef MEMORY_DEBUG
73 	memfile = fopen(MEMORY_DEBUG_FILE, "w");
74 	if (!memfile)
75 	{
76 		fprintf(stderr, "Unable to create " MEMORY_DEBUG_FILE " for logging memory allocations\n");
77 		return;
78 	}
79 #endif
80 
81 #ifdef NETWORK_DUMP_DEBUG
82 	netdump = fopen(NETWORK_DUMP_FILE, "w");
83 	if (!netdump)
84 	{
85 		fprintf(stderr, "Unable to create " NETWORK_DUMP_FILE " for logging network traffic\n");
86 		return;
87 	}
88 #endif
89 
90 #ifndef WIN32
91 	if (syslog)
92 	{
93 		use_syslog = 1;
94                 #ifndef SYSTEMD
95 		openlog("uhub", LOG_PID, LOG_USER);
96                 #endif
97 	}
98 #endif
99 
100 
101 	if (!file)
102 	{
103 		logfile = stderr;
104 		return;
105 	}
106 
107 	logfile = fopen(file, "a");
108 	if (!logfile)
109 	{
110 		logfile = stderr;
111 		return;
112 	}
113 
114 }
115 
116 
hub_log_shutdown()117 void hub_log_shutdown()
118 {
119 	if (logfile && logfile != stderr)
120 	{
121 		fclose(logfile);
122 		logfile = NULL;
123 	}
124 
125 #ifdef MEMORY_DEBUG
126 	if (memfile)
127 	{
128 		fclose(memfile);
129 		memfile = NULL;
130 	}
131 #endif
132 
133 #ifdef NETWORK_DUMP_DEBUG
134 	if (netdump)
135 	{
136 		fclose(netdump);
137 		netdump = NULL;
138 	}
139 #endif
140 
141 #ifndef WIN32
142 	if (use_syslog)
143 	{
144 		use_syslog = 0;
145                 #ifndef SYSTEMD
146 		closelog();
147                 #endif
148 	}
149 #endif
150 }
151 
152 
hub_set_log_verbosity(int verb)153 void hub_set_log_verbosity(int verb)
154 {
155 	verbosity = verb;
156 }
157 
hub_log(int log_verbosity,const char * format,...)158 void hub_log(int log_verbosity, const char *format, ...)
159 {
160 	static char logmsg[1024];
161 	static char timestamp[32];
162 	struct tm *tmp;
163 	time_t t;
164 	va_list args;
165 
166 #ifdef MEMORY_DEBUG
167 	if (memfile && log_verbosity == log_memory)
168 	{
169 		va_start(args, format);
170 		vsnprintf(logmsg, 1024, format, args);
171 		va_end(args);
172 		fprintf(memfile, "%s\n", logmsg);
173 		fflush(memfile);
174 		return;
175 	}
176 #endif
177 
178 #ifdef NETWORK_DUMP_DEBUG
179 	if (netdump && log_verbosity == log_protocol)
180 	{
181 		va_start(args, format);
182 		vsnprintf(logmsg, 1024, format, args);
183 		va_end(args);
184 		fprintf(netdump, "%s\n", logmsg);
185 		fflush(netdump);
186 		return;
187 	}
188 #endif
189 
190 	if (log_verbosity < verbosity)
191 	{
192 		t = time(NULL);
193 		tmp = localtime(&t);
194 		strftime(timestamp, 32, "%Y-%m-%d %H:%M:%S", tmp);
195 		va_start(args, format);
196 		vsnprintf(logmsg, 1024, format, args);
197 		va_end(args);
198 
199 		if (logfile)
200 		{
201 			fprintf(logfile, "%s %6s: %s\n", timestamp, prefixes[log_verbosity], logmsg);
202 			fflush(logfile);
203 		}
204 		else
205 		{
206 			fprintf(stderr, "%s %6s: %s\n", timestamp, prefixes[log_verbosity], logmsg);
207 		}
208 	}
209 
210 #ifndef WIN32
211 	if (use_syslog)
212 	{
213 		int level = 0;
214 
215 		if (verbosity < log_info)
216 			return;
217 
218 		va_start(args, format);
219 		vsnprintf(logmsg, 1024, format, args);
220 		va_end(args);
221 
222 		switch (log_verbosity)
223 		{
224 			case log_fatal:    level = LOG_CRIT; break;
225 			case log_error:    level = LOG_ERR; break;
226 			case log_warning:  level = LOG_WARNING; break;
227                         #ifdef SYSTEMD
228                         case log_user:     level = LOG_INFO; break;
229 
230                         #else
231                         case log_user:     level = LOG_INFO | LOG_AUTH; break;
232                         #endif
233 			case log_info:     level = LOG_INFO; break;
234 			case log_debug:    level = LOG_DEBUG; break;
235 
236 			default:
237 				level = 0;
238 				break;
239 		}
240 
241 		if (level == 0)
242 			return;
243 
244                 #ifdef SYSTEMD
245 		sd_journal_print(level, "%s", logmsg);
246 
247                 #else
248 		level |= (LOG_USER | LOG_DAEMON);
249 		syslog(level, "%s", logmsg);
250                 #endif
251 	}
252 #endif
253 
254 }
255