log.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. /*
  2. * ngIRCd -- The Next Generation IRC Daemon
  3. * Copyright (c)2001-2005 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. #include "portab.h"
  14. static char UNUSED id[] = "$Id: log.c,v 1.61.2.1 2006/12/02 13:02:07 fw Exp $";
  15. #include "imp.h"
  16. #include <assert.h>
  17. #include <errno.h>
  18. #ifdef PROTOTYPES
  19. # include <stdarg.h>
  20. #else
  21. # include <varargs.h>
  22. #endif
  23. #include <stdio.h>
  24. #include <string.h>
  25. #include <sys/types.h>
  26. #include <unistd.h>
  27. #ifdef SYSLOG
  28. #include <syslog.h>
  29. #endif
  30. #include "ngircd.h"
  31. #include "defines.h"
  32. #include "conn.h"
  33. #include "client.h"
  34. #include "channel.h"
  35. #include "irc-write.h"
  36. #include "exp.h"
  37. #include "log.h"
  38. static char Init_Txt[127];
  39. static bool Is_Daemon;
  40. #ifdef DEBUG
  41. static char Error_File[FNAME_LEN];
  42. #endif
  43. static void Wall_ServerNotice PARAMS(( char *Msg ));
  44. GLOBAL void
  45. Log_Init( bool Daemon_Mode )
  46. {
  47. Is_Daemon = Daemon_Mode;
  48. #ifdef SYSLOG
  49. #ifndef LOG_CONS /* Kludge: mips-dec-ultrix4.5 has no LOG_CONS/LOG_LOCAL5 */
  50. #define LOG_CONS 0
  51. #endif
  52. #ifndef LOG_LOCAL5
  53. #define LOG_LOCAL5 0
  54. #endif
  55. /* Syslog initialisieren */
  56. openlog( PACKAGE_NAME, LOG_CONS|LOG_PID, LOG_LOCAL5 );
  57. #endif
  58. /* Hello World! */
  59. Log( LOG_NOTICE, "%s started.", NGIRCd_Version );
  60. /* Informationen uebern den "Operation Mode" */
  61. Init_Txt[0] = '\0';
  62. #ifdef DEBUG
  63. if( NGIRCd_Debug )
  64. {
  65. strlcpy( Init_Txt, "debug-mode", sizeof Init_Txt );
  66. }
  67. #endif
  68. if( ! Is_Daemon )
  69. {
  70. if( Init_Txt[0] ) strlcat( Init_Txt, ", ", sizeof Init_Txt );
  71. strlcat( Init_Txt, "no-daemon-mode", sizeof Init_Txt );
  72. }
  73. if( NGIRCd_Passive )
  74. {
  75. if( Init_Txt[0] ) strlcat( Init_Txt, ", ", sizeof Init_Txt );
  76. strlcat( Init_Txt, "passive-mode", sizeof Init_Txt );
  77. }
  78. #ifdef SNIFFER
  79. if( NGIRCd_Sniffer )
  80. {
  81. if( Init_Txt[0] ) strlcat( Init_Txt, ", ", sizeof Init_Txt );
  82. strlcat( Init_Txt, "network sniffer", sizeof Init_Txt );
  83. }
  84. #endif
  85. if( Init_Txt[0] ) Log( LOG_INFO, "Activating: %s.", Init_Txt );
  86. #ifdef DEBUG
  87. Error_File[0] = '\0';
  88. #endif
  89. } /* Log_Init */
  90. #ifdef DEBUG
  91. GLOBAL void
  92. Log_InitErrorfile( void )
  93. {
  94. /* "Error-Log" initialisieren: stderr in Datei umlenken. Dort
  95. * landen z.B. alle Ausgaben von assert()-Aufrufen. */
  96. /* Dateiname zusammen bauen */
  97. snprintf( Error_File, sizeof Error_File, "%s/%s-%ld.err", ERROR_DIR, PACKAGE_NAME, (long)getpid( ));
  98. /* stderr umlenken */
  99. fflush( stderr );
  100. if( ! freopen( Error_File, "w", stderr ))
  101. {
  102. Log( LOG_ERR, "Can't reopen stderr (\"%s\"): %s", Error_File, strerror( errno ));
  103. return;
  104. }
  105. /* Einige Infos in das Error-File schreiben */
  106. fputs( ctime( &NGIRCd_Start ), stderr );
  107. fprintf( stderr, "%s started.\n", NGIRCd_Version );
  108. fprintf( stderr, "Activating: %s\n\n", Init_Txt[0] ? Init_Txt : "-" );
  109. fflush( stderr );
  110. #ifdef DEBUG
  111. Log( LOG_DEBUG, "Redirected stderr to \"%s\".", Error_File );
  112. #endif
  113. } /* Log_InitErrfile */
  114. #endif
  115. GLOBAL void
  116. Log_Exit( void )
  117. {
  118. /* Good Bye! */
  119. if( NGIRCd_SignalRestart ) Log( LOG_NOTICE, "%s done (restarting).", PACKAGE_NAME );
  120. else Log( LOG_NOTICE, "%s done.", PACKAGE_NAME );
  121. #ifdef DEBUG
  122. if( Error_File[0] )
  123. {
  124. /* Error-File (stderr) loeschen */
  125. if( unlink( Error_File ) != 0 ) Log( LOG_ERR, "Can't delete \"%s\": %s", Error_File, strerror( errno ));
  126. }
  127. #endif
  128. #ifdef SYSLOG
  129. /* syslog abmelden */
  130. closelog( );
  131. #endif
  132. } /* Log_Exit */
  133. /**
  134. * Log function for debug messages.
  135. * This function is only functional when the program is compiled with debug
  136. * code enabled; otherwise it is an empty function which the compiler will
  137. * hopefully mangle down to "nothing" (see log.h). Therefore you should use
  138. * LogDebug(...) in favor to Log(LOG_DEBUG, ...).
  139. * @param Format Format string like printf().
  140. * @param ... Further arguments.
  141. */
  142. #ifdef DEBUG
  143. # ifdef PROTOTYPES
  144. GLOBAL void
  145. LogDebug( const char *Format, ... )
  146. # else
  147. GLOBAL void
  148. LogDebug( Format, va_alist )
  149. const char *Format;
  150. va_dcl
  151. # endif /* PROTOTYPES */
  152. {
  153. char msg[MAX_LOG_MSG_LEN];
  154. va_list ap;
  155. if (!NGIRCd_Debug) return;
  156. #ifdef PROTOTYPES
  157. va_start( ap, Format );
  158. #else
  159. va_start( ap );
  160. #endif
  161. vsnprintf( msg, MAX_LOG_MSG_LEN, Format, ap );
  162. va_end( ap );
  163. Log(LOG_DEBUG, "%s", msg);
  164. }
  165. #endif /* DEBUG */
  166. /**
  167. * Logging function of ngIRCd.
  168. * This function logs messages to the console and/or syslog, whichever is
  169. * suitable for the mode ngIRCd is running in (daemon vs. non-daemon).
  170. * Please note: you sould use LogDebug(...) for debug messages!
  171. * @param Level syslog level (LOG_xxx)
  172. * @param Format Format string like printf().
  173. * @param ... Further arguments.
  174. */
  175. #ifdef PROTOTYPES
  176. GLOBAL void
  177. Log( int Level, const char *Format, ... )
  178. #else
  179. GLOBAL void
  180. Log( Level, Format, va_alist )
  181. int Level;
  182. const char *Format;
  183. va_dcl
  184. #endif
  185. {
  186. /* Eintrag in Logfile(s) schreiben */
  187. char msg[MAX_LOG_MSG_LEN];
  188. bool snotice;
  189. va_list ap;
  190. assert( Format != NULL );
  191. if( Level & LOG_snotice )
  192. {
  193. /* Notice an User mit "s" Mode */
  194. snotice = true;
  195. Level &= ~LOG_snotice;
  196. }
  197. else snotice = false;
  198. #ifdef DEBUG
  199. if(( Level == LOG_DEBUG ) && ( ! NGIRCd_Debug )) return;
  200. #else
  201. if( Level == LOG_DEBUG ) return;
  202. #endif
  203. /* String mit variablen Argumenten zusammenbauen ... */
  204. #ifdef PROTOTYPES
  205. va_start( ap, Format );
  206. #else
  207. va_start( ap );
  208. #endif
  209. vsnprintf( msg, MAX_LOG_MSG_LEN, Format, ap );
  210. va_end( ap );
  211. if( ! Is_Daemon )
  212. {
  213. /* auf Konsole ausgeben */
  214. fprintf( stdout, "[%d:%d] %s\n", (int)getpid( ), Level, msg );
  215. fflush( stdout );
  216. }
  217. #ifdef SYSLOG
  218. else
  219. {
  220. /* Syslog */
  221. syslog( Level, "%s", msg );
  222. }
  223. #endif
  224. if( Level <= LOG_CRIT )
  225. {
  226. /* log critical messages to stderr */
  227. fprintf( stderr, "%s\n", msg );
  228. fflush( stderr );
  229. }
  230. if( snotice )
  231. {
  232. /* NOTICE an lokale User mit "s"-Mode */
  233. Wall_ServerNotice( msg );
  234. }
  235. } /* Log */
  236. GLOBAL void
  237. Log_Init_Resolver( void )
  238. {
  239. #ifdef SYSLOG
  240. openlog( PACKAGE_NAME, LOG_CONS|LOG_PID, LOG_LOCAL5 );
  241. #endif
  242. #ifdef DEBUG
  243. Log_Resolver( LOG_DEBUG, "Resolver sub-process starting, PID %d.", getpid( ));
  244. #endif
  245. } /* Log_Init_Resolver */
  246. GLOBAL void
  247. Log_Exit_Resolver( void )
  248. {
  249. #ifdef DEBUG
  250. Log_Resolver( LOG_DEBUG, "Resolver sub-process %d done.", getpid( ));
  251. #endif
  252. #ifdef SYSLOG
  253. closelog( );
  254. #endif
  255. } /* Log_Exit_Resolver */
  256. #ifdef PROTOTYPES
  257. GLOBAL void
  258. Log_Resolver( const int Level, const char *Format, ... )
  259. #else
  260. GLOBAL void
  261. Log_Resolver( Level, Format, va_alist )
  262. const int Level;
  263. const char *Format;
  264. va_dcl
  265. #endif
  266. {
  267. /* Eintrag des Resolver in Logfile(s) schreiben */
  268. char msg[MAX_LOG_MSG_LEN];
  269. va_list ap;
  270. assert( Format != NULL );
  271. #ifdef DEBUG
  272. if(( Level == LOG_DEBUG ) && ( ! NGIRCd_Debug )) return;
  273. #else
  274. if( Level == LOG_DEBUG ) return;
  275. #endif
  276. /* String mit variablen Argumenten zusammenbauen ... */
  277. #ifdef PROTOTYPES
  278. va_start( ap, Format );
  279. #else
  280. va_start( ap );
  281. #endif
  282. vsnprintf( msg, MAX_LOG_MSG_LEN, Format, ap );
  283. va_end( ap );
  284. if( ! Is_Daemon )
  285. {
  286. /* Output to console */
  287. fprintf( stdout, "[%d:%d] %s\n", (int)getpid( ), Level, msg );
  288. fflush( stdout );
  289. }
  290. #ifdef SYSLOG
  291. else syslog( Level, "%s", msg );
  292. #endif
  293. } /* Log_Resolver */
  294. /**
  295. * Send log messages to users flagged with the "s" mode.
  296. * @param Msg The message to send.
  297. */
  298. static void
  299. Wall_ServerNotice( char *Msg )
  300. {
  301. CLIENT *c;
  302. assert( Msg != NULL );
  303. c = Client_First( );
  304. while(c) {
  305. if (Client_Conn(c) > NONE && Client_HasMode(c, 's'))
  306. IRC_WriteStrClient(c, "NOTICE %s :%s%s", Client_ID(c),
  307. NOTICE_TXTPREFIX, Msg);
  308. c = Client_Next( c );
  309. }
  310. } /* Wall_ServerNotice */
  311. /* -eof- */