New "chroot" feature (from Benjamin Pineau), introducing new configuration
[ngircd-alex.git] / src / ngircd / log.c
1 /*
2  * ngIRCd -- The Next Generation IRC Daemon
3  * Copyright (c)2001,2002 by 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  * Logging functions
12  */
13
14
15 #include "portab.h"
16
17 static char UNUSED id[] = "$Id: log.c,v 1.45 2004/05/07 11:19:21 alex Exp $";
18
19 #include "imp.h"
20 #include <assert.h>
21 #include <errno.h>
22 #include <stdarg.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <sys/types.h>
26 #include <unistd.h>
27
28 #ifdef SYSLOG
29 #include <syslog.h>
30 #endif
31
32 #include "ngircd.h"
33 #include "defines.h"
34 #include "conn.h"
35 #include "client.h"
36 #include "channel.h"
37 #include "irc-write.h"
38
39 #include "exp.h"
40 #include "log.h"
41
42
43 LOCAL CHAR Error_File[FNAME_LEN];
44 LOCAL CHAR Init_Txt[127];
45
46
47 LOCAL VOID Wall_ServerNotice PARAMS(( CHAR *Msg ));
48
49
50 GLOBAL VOID
51 Log_Init( VOID )
52 {
53 #ifdef SYSLOG
54         /* Syslog initialisieren */
55         openlog( PACKAGE_NAME, LOG_CONS|LOG_PID, LOG_LOCAL5 );
56 #endif
57
58         /* Hello World! */
59         Log( LOG_NOTICE, "%s started.", NGIRCd_Version( ));
60           
61         /* Informationen uebern den "Operation Mode" */
62         strcpy( Init_Txt, "" );
63 #ifdef DEBUG
64         if( NGIRCd_Debug )
65         {
66                 if( Init_Txt[0] ) strcat( Init_Txt, ", " );
67                 strcat( Init_Txt, "debug-mode" );
68         }
69 #endif
70         if( NGIRCd_NoDaemon )
71         {
72                 if( Init_Txt[0] ) strcat( Init_Txt, ", " );
73                 strcat( Init_Txt, "no-daemon-mode" );
74         }
75         if( NGIRCd_Passive )
76         {
77                 if( Init_Txt[0] ) strcat( Init_Txt, ", " );
78                 strcat( Init_Txt, "passive-mode" );
79         }
80 #ifdef SNIFFER
81         if( NGIRCd_Sniffer )
82         {
83                 if( Init_Txt[0] ) strcat( Init_Txt, ", " );
84                 strcat( Init_Txt, "network sniffer" );
85         }
86 #endif
87         if( Init_Txt[0] ) Log( LOG_INFO, "Activating: %s.", Init_Txt );
88
89         Error_File[0] = '\0';
90 } /* Log_Init */
91
92
93 GLOBAL VOID
94 Log_InitErrorfile( VOID )
95 {
96         /* "Error-Log" initialisieren: stderr in Datei umlenken. Dort
97          * landen z.B. alle Ausgaben von assert()-Aufrufen. */
98
99         /* Dateiname zusammen bauen */
100         sprintf( Error_File, "%s/%s-%ld.err", ERROR_DIR, PACKAGE_NAME, (LONG)getpid( ));
101
102         /* stderr umlenken */
103         fflush( stderr );
104         if( ! freopen( Error_File, "w", stderr ))
105         {
106                 Log( LOG_ERR, "Can't reopen stderr (\"%s\"): %s", Error_File, strerror( errno ));
107                 return;
108         }
109
110         /* Einige Infos in das Error-File schreiben */
111         fputs( ctime( &NGIRCd_Start ), stderr );
112         fprintf( stderr, "%s started.\n", NGIRCd_Version( ));
113         fprintf( stderr, "Activating: %s\n\n", Init_Txt[0] ? Init_Txt : "-" );
114         fflush( stderr );
115
116         Log( LOG_DEBUG, "Redirected stderr to \"%s\".", Error_File );
117 } /* Log_InitErrfile */
118
119
120 GLOBAL VOID
121 Log_Exit( VOID )
122 {
123         /* Good Bye! */
124         if( NGIRCd_SignalRestart ) Log( LOG_NOTICE, "%s done (restarting).", PACKAGE_NAME );
125         else Log( LOG_NOTICE, "%s done.", PACKAGE_NAME );
126
127         if( Error_File[0] )
128         {
129                 /* Error-File (stderr) loeschen */
130                 if( unlink( Error_File ) != 0 ) Log( LOG_ERR, "Can't delete \"%s\": %s", Error_File, strerror( errno ));
131         }
132
133 #ifdef SYSLOG
134         /* syslog abmelden */
135         closelog( );
136 #endif
137 } /* Log_Exit */
138
139
140 #ifdef PROTOTYPES
141 GLOBAL VOID
142 Log( INT Level, CONST CHAR *Format, ... )
143 #else
144 GLOBAL VOID
145 Log( Level, Format, va_alist )
146 INT Level;
147 CONST CHAR *Format;
148 va_dcl
149 #endif
150 {
151         /* Eintrag in Logfile(s) schreiben */
152
153         CHAR msg[MAX_LOG_MSG_LEN];
154         BOOLEAN snotice;
155         va_list ap;
156
157         assert( Format != NULL );
158
159         if( Level & LOG_snotice )
160         {
161                 /* Notice an User mit "s" Mode */
162                 snotice = TRUE;
163                 Level &= ~LOG_snotice;
164         }
165         else snotice = FALSE;
166
167 #ifdef DEBUG
168         if(( Level == LOG_DEBUG ) && ( ! NGIRCd_Debug )) return;
169 #else
170         if( Level == LOG_DEBUG ) return;
171 #endif
172
173         /* String mit variablen Argumenten zusammenbauen ... */
174 #ifdef PROTOTYPES
175         va_start( ap, Format );
176 #else
177         va_start( ap );
178 #endif
179         vsnprintf( msg, MAX_LOG_MSG_LEN, Format, ap );
180         va_end( ap );
181
182         if( NGIRCd_NoDaemon )
183         {
184                 /* auf Konsole ausgeben */
185                 fprintf( stdout, "[%d] %s\n", Level, msg );
186                 fflush( stdout );
187         }
188 #ifdef SYSLOG
189         else
190         {
191                 /* Syslog */
192                 syslog( Level, "%s", msg );
193         }
194 #endif
195
196         if( Level <= LOG_CRIT )
197         {
198                 /* Kritische Meldungen in Error-File (stderr) */
199                 fprintf( stderr, "%s\n", msg );
200                 fflush( stderr );
201         }
202
203         if( snotice )
204         {
205                 /* NOTICE an lokale User mit "s"-Mode */
206                 Wall_ServerNotice( msg );
207         }
208 } /* Log */
209
210
211 GLOBAL VOID
212 Log_Init_Resolver( VOID )
213 {
214 #ifdef SYSLOG
215         openlog( PACKAGE_NAME, LOG_CONS|LOG_PID, LOG_LOCAL5 );
216 #endif
217 } /* Log_Init_Resolver */
218
219
220 GLOBAL VOID
221 Log_Exit_Resolver( VOID )
222 {
223 #ifdef SYSLOG
224         closelog( );
225 #endif
226 } /* Log_Exit_Resolver */
227
228
229 #ifdef PROTOTYPES
230 GLOBAL VOID
231 Log_Resolver( CONST INT Level, CONST CHAR *Format, ... )
232 #else
233 GLOBAL VOID
234 Log_Resolver( Level, Format, va_alist )
235 CONST INT Level;
236 CONST CHAR *Format;
237 va_dcl
238 #endif
239 {
240         /* Eintrag des Resolver in Logfile(s) schreiben */
241
242 #ifndef SYSLOG
243         return;
244 #else
245
246         CHAR msg[MAX_LOG_MSG_LEN];
247         va_list ap;
248
249         assert( Format != NULL );
250
251         if( NGIRCd_NoDaemon ) return;
252
253 #ifdef DEBUG
254         if(( Level == LOG_DEBUG ) && ( ! NGIRCd_Debug )) return;
255 #else
256         if( Level == LOG_DEBUG ) return;
257 #endif
258
259         /* String mit variablen Argumenten zusammenbauen ... */
260 #ifdef PROTOTYPES
261         va_start( ap, Format );
262 #else
263         va_start( ap );
264 #endif
265         vsnprintf( msg, MAX_LOG_MSG_LEN, Format, ap );
266         va_end( ap );
267
268         /* ... und ausgeben */
269         syslog( Level, msg );
270
271 #endif
272 } /* Log_Resolver */
273
274
275 LOCAL VOID
276 Wall_ServerNotice( CHAR *Msg )
277 {
278         /* Server-Notice an entsprechende User verschicken */
279
280         CLIENT *c;
281
282         assert( Msg != NULL );
283
284         c = Client_First( );
285         while( c )
286         {
287                 if(( Client_Conn( c ) > NONE ) && ( Client_HasMode( c, 's' ))) IRC_WriteStrClient( c, "NOTICE %s :%s%s", Client_ThisServer( ), NOTICE_TXTPREFIX, Msg );
288                 c = Client_Next( c );
289         }
290 } /* Wall_ServerNotice */
291
292
293 /* -eof- */