]> arthur.barton.de Git - ngircd-alex.git/blob - src/ngircd/log.c
Use correct sender as target for ISUPPORT replies on "VERSION"
[ngircd-alex.git] / src / ngircd / log.c
1 /*
2  * ngIRCd -- The Next Generation IRC Daemon
3  * Copyright (c)2001-2012 Alexander Barton (alex@barton.de)
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 2 of the License, or
8  * (at your option) any later version.
9  * Please read the file COPYING, README and AUTHORS for more information.
10  */
11
12 #include "portab.h"
13
14 /**
15  * @file
16  * Logging functions
17  */
18
19 #include "imp.h"
20 #include <assert.h>
21 #include <errno.h>
22 #ifdef PROTOTYPES
23 #       include <stdarg.h>
24 #else
25 #       include <varargs.h>
26 #endif
27 #include <stdio.h>
28 #include <string.h>
29 #include <sys/types.h>
30 #include <unistd.h>
31
32 #ifdef SYSLOG
33 #include <syslog.h>
34 #endif
35
36 #include "ngircd.h"
37 #include "defines.h"
38 #include "conn.h"
39 #include "channel.h"
40 #include "irc-write.h"
41 #include "conf.h"
42
43 #include "exp.h"
44 #include "log.h"
45
46
47 static bool Is_Daemon;
48
49
50 static void
51 Log_Message(int Level, const char *msg)
52 {
53         if (!Is_Daemon) {
54                 /* log to console */
55                 fprintf(stdout, "[%ld:%d %4ld] %s\n", (long)getpid(), Level,
56                                 (long)(time(NULL) - NGIRCd_Start), msg);
57                 fflush(stdout);
58         }
59 #ifdef SYSLOG
60         else {
61                 syslog(Level, "%s", msg);
62         }
63 #endif
64 }
65
66
67 /**
68  * Initialitze logging.
69  * This function is called before the configuration file is read in.
70  *
71  * @param Daemon_Mode Set to true if ngIRCd is running as daemon.
72  */
73 GLOBAL void
74 Log_Init(bool Daemon_Mode)
75 {
76         Is_Daemon = Daemon_Mode;
77
78 #ifdef SYSLOG
79 #ifndef LOG_CONS     /* Kludge: mips-dec-ultrix4.5 has no LOG_CONS */
80 #define LOG_CONS 0
81 #endif
82 #ifdef LOG_DAEMON
83         openlog(PACKAGE, LOG_CONS|LOG_PID, LOG_DAEMON);
84 #else
85         openlog(PACKAGE, LOG_CONS|LOG_PID, 0);
86 #endif
87 #endif
88 } /* Log_Init */
89
90
91 /**
92  * Re-init logging after reading the configuration file.
93  */
94 GLOBAL void
95 Log_ReInit(void)
96 {
97 #ifdef SYSLOG
98 #ifndef LOG_CONS     /* Kludge: mips-dec-ultrix4.5 has no LOG_CONS */
99 #define LOG_CONS 0
100 #endif
101         closelog();
102         openlog(PACKAGE, LOG_CONS|LOG_PID, Conf_SyslogFacility);
103 #endif
104         Log(LOG_NOTICE, "%s started.", NGIRCd_Version);
105         Log(LOG_INFO, "Using configuration file \"%s\" ...", NGIRCd_ConfFile);
106 }
107
108
109 GLOBAL void
110 Log_Exit( void )
111 {
112         Log(LOG_INFO, "%s done%s, served %lu connection%s.", PACKAGE_NAME,
113             NGIRCd_SignalRestart ? " (restarting)" : "", Conn_CountAccepted(),
114             Conn_CountAccepted() == 1 ? "" : "s");
115 #ifdef SYSLOG
116         closelog();
117 #endif
118 } /* Log_Exit */
119
120
121 /**
122  * Log function for debug messages.
123  * This function is only functional when the program is compiled with debug
124  * code enabled; otherwise it is an empty function which the compiler will
125  * hopefully mangle down to "nothing" (see log.h). Therefore you should use
126  * LogDebug(...) in favor to Log(LOG_DEBUG, ...).
127  * @param Format Format string like printf().
128  * @param ... Further arguments.
129  */
130 #ifdef DEBUG
131 # ifdef PROTOTYPES
132 GLOBAL void
133 LogDebug( const char *Format, ... )
134 # else
135 GLOBAL void
136 LogDebug( Format, va_alist )
137 const char *Format;
138 va_dcl
139 # endif /* PROTOTYPES */
140 {
141         char msg[MAX_LOG_MSG_LEN];
142         va_list ap;
143
144         if (!NGIRCd_Debug) return;
145 #ifdef PROTOTYPES
146         va_start( ap, Format );
147 #else
148         va_start( ap );
149 #endif
150         vsnprintf( msg, MAX_LOG_MSG_LEN, Format, ap );
151         va_end( ap );
152         Log(LOG_DEBUG, "%s", msg);
153 }
154 #endif  /* DEBUG */
155
156
157 /**
158  * Logging function of ngIRCd.
159  * This function logs messages to the console and/or syslog, whichever is
160  * suitable for the mode ngIRCd is running in (daemon vs. non-daemon).
161  * If LOG_snotice is set, the log messages goes to all user with the mode +s
162  * set and the local &SERVER channel, too.
163  * Please note: you should use LogDebug(...) for debug messages!
164  * @param Level syslog level (LOG_xxx)
165  * @param Format Format string like printf().
166  * @param ... Further arguments.
167  */
168 #ifdef PROTOTYPES
169 GLOBAL void
170 Log( int Level, const char *Format, ... )
171 #else
172 GLOBAL void
173 Log( Level, Format, va_alist )
174 int Level;
175 const char *Format;
176 va_dcl
177 #endif
178 {
179         char msg[MAX_LOG_MSG_LEN];
180         bool snotice;
181         va_list ap;
182
183         assert( Format != NULL );
184
185         if( Level & LOG_snotice )
186         {
187                 /* Notice an User mit "s" Mode */
188                 snotice = true;
189                 Level &= ~LOG_snotice;
190         }
191         else snotice = false;
192
193 #ifdef DEBUG
194         if(( Level == LOG_DEBUG ) && ( ! NGIRCd_Debug )) return;
195 #else
196         if( Level == LOG_DEBUG ) return;
197 #endif
198
199 #ifdef PROTOTYPES
200         va_start( ap, Format );
201 #else
202         va_start( ap );
203 #endif
204         vsnprintf( msg, MAX_LOG_MSG_LEN, Format, ap );
205         va_end( ap );
206
207         Log_Message(Level, msg);
208
209         if (snotice) {
210                 /* Send NOTICE to all local users with mode +s and to the
211                  * local &SERVER channel */
212                 Log_ServerNotice('s', "%s", msg);
213                 Channel_LogServer(msg);
214         }
215 } /* Log */
216
217
218 GLOBAL void
219 Log_Init_Subprocess(char UNUSED *Name)
220 {
221 #ifdef SYSLOG
222         openlog(PACKAGE, LOG_CONS|LOG_PID, Conf_SyslogFacility);
223 #endif
224 #ifdef DEBUG
225         Log_Subprocess(LOG_DEBUG, "%s sub-process starting, PID %ld.",
226                      Name, (long)getpid());
227 #endif
228 }
229
230
231 GLOBAL void
232 Log_Exit_Subprocess(char UNUSED *Name)
233 {
234 #ifdef DEBUG
235         Log_Subprocess(LOG_DEBUG, "%s sub-process %ld done.",
236                      Name, (long)getpid());
237 #endif
238 #ifdef SYSLOG
239         closelog( );
240 #endif
241 }
242
243
244 #ifdef PROTOTYPES
245 GLOBAL void
246 Log_Subprocess(const int Level, const char *Format, ...)
247 #else
248 GLOBAL void
249 Log_Subprocess(Level, Format, va_alist)
250 const int Level;
251 const char *Format;
252 va_dcl
253 #endif
254 {
255         char msg[MAX_LOG_MSG_LEN];
256         va_list ap;
257
258         assert(Format != NULL);
259
260 #ifdef DEBUG
261         if ((Level == LOG_DEBUG) && (!NGIRCd_Debug))
262                 return;
263 #else
264         if (Level == LOG_DEBUG)
265                 return;
266 #endif
267
268 #ifdef PROTOTYPES
269         va_start(ap, Format);
270 #else
271         va_start(ap);
272 #endif
273         vsnprintf(msg, MAX_LOG_MSG_LEN, Format, ap);
274         va_end(ap);
275
276         Log_Message(Level, msg);
277 }
278
279
280 /**
281  * Send a log message to all local users flagged with the given user mode.
282  * @param UserMode User mode which the target user must have set,
283  * @param Format The format string.
284  */
285 #ifdef PROTOTYPES
286 GLOBAL void
287 Log_ServerNotice(const char UserMode, const char *Format, ... )
288 #else
289 GLOBAL void
290 Log_ServerNotice(UserMode, Format, va_alist)
291 const char UserMode;
292 const char *Format;
293 va_dcl
294 #endif
295 {
296         CLIENT *c;
297         char msg[MAX_LOG_MSG_LEN];
298         va_list ap;
299
300         assert(Format != NULL);
301
302 #ifdef PROTOTYPES
303         va_start(ap, Format);
304 #else
305         va_start(ap);
306 #endif
307         vsnprintf(msg, MAX_LOG_MSG_LEN, Format, ap);
308         va_end(ap);
309
310         for(c=Client_First(); c != NULL; c=Client_Next(c)) {
311                 if (Client_Conn(c) > NONE && Client_HasMode(c, UserMode))
312                         IRC_WriteStrClient(c, "NOTICE %s :%s%s", Client_ID(c),
313                                                         NOTICE_TXTPREFIX, msg);
314         }
315 } /* Log_ServerNotice */
316
317
318 /* -eof- */