log.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  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.57.2.1 2005/08/29 11:19:48 alex 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. LOCAL char Init_Txt[127];
  39. LOCAL bool Is_Daemon;
  40. #ifdef DEBUG
  41. LOCAL char Error_File[FNAME_LEN];
  42. #endif
  43. LOCAL 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. #ifdef PROTOTYPES
  134. GLOBAL void
  135. Log( int Level, const char *Format, ... )
  136. #else
  137. GLOBAL void
  138. Log( Level, Format, va_alist )
  139. int Level;
  140. const char *Format;
  141. va_dcl
  142. #endif
  143. {
  144. /* Eintrag in Logfile(s) schreiben */
  145. char msg[MAX_LOG_MSG_LEN];
  146. bool snotice;
  147. va_list ap;
  148. assert( Format != NULL );
  149. if( Level & LOG_snotice )
  150. {
  151. /* Notice an User mit "s" Mode */
  152. snotice = true;
  153. Level &= ~LOG_snotice;
  154. }
  155. else snotice = false;
  156. #ifdef DEBUG
  157. if(( Level == LOG_DEBUG ) && ( ! NGIRCd_Debug )) return;
  158. #else
  159. if( Level == LOG_DEBUG ) return;
  160. #endif
  161. /* String mit variablen Argumenten zusammenbauen ... */
  162. #ifdef PROTOTYPES
  163. va_start( ap, Format );
  164. #else
  165. va_start( ap );
  166. #endif
  167. vsnprintf( msg, MAX_LOG_MSG_LEN, Format, ap );
  168. va_end( ap );
  169. if( ! Is_Daemon )
  170. {
  171. /* auf Konsole ausgeben */
  172. fprintf( stdout, "[%d:%d] %s\n", (int)getpid( ), Level, msg );
  173. fflush( stdout );
  174. }
  175. #ifdef SYSLOG
  176. else
  177. {
  178. /* Syslog */
  179. syslog( Level, "%s", msg );
  180. }
  181. #endif
  182. if( Level <= LOG_CRIT )
  183. {
  184. /* log critical messages to stderr */
  185. fprintf( stderr, "%s\n", msg );
  186. fflush( stderr );
  187. }
  188. if( snotice )
  189. {
  190. /* NOTICE an lokale User mit "s"-Mode */
  191. Wall_ServerNotice( msg );
  192. }
  193. } /* Log */
  194. GLOBAL void
  195. Log_Init_Resolver( void )
  196. {
  197. #ifdef SYSLOG
  198. openlog( PACKAGE_NAME, LOG_CONS|LOG_PID, LOG_LOCAL5 );
  199. #endif
  200. #ifdef DEBUG
  201. Log_Resolver( LOG_DEBUG, "Resolver sub-process starting, PID %d.", getpid( ));
  202. #endif
  203. } /* Log_Init_Resolver */
  204. GLOBAL void
  205. Log_Exit_Resolver( void )
  206. {
  207. #ifdef DEBUG
  208. Log_Resolver( LOG_DEBUG, "Resolver sub-process %d done.", getpid( ));
  209. #endif
  210. #ifdef SYSLOG
  211. closelog( );
  212. #endif
  213. } /* Log_Exit_Resolver */
  214. #ifdef PROTOTYPES
  215. GLOBAL void
  216. Log_Resolver( const int Level, const char *Format, ... )
  217. #else
  218. GLOBAL void
  219. Log_Resolver( Level, Format, va_alist )
  220. const int Level;
  221. const char *Format;
  222. va_dcl
  223. #endif
  224. {
  225. /* Eintrag des Resolver in Logfile(s) schreiben */
  226. char msg[MAX_LOG_MSG_LEN];
  227. va_list ap;
  228. assert( Format != NULL );
  229. #ifdef DEBUG
  230. if(( Level == LOG_DEBUG ) && ( ! NGIRCd_Debug )) return;
  231. #else
  232. if( Level == LOG_DEBUG ) return;
  233. #endif
  234. /* String mit variablen Argumenten zusammenbauen ... */
  235. #ifdef PROTOTYPES
  236. va_start( ap, Format );
  237. #else
  238. va_start( ap );
  239. #endif
  240. vsnprintf( msg, MAX_LOG_MSG_LEN, Format, ap );
  241. va_end( ap );
  242. if( ! Is_Daemon )
  243. {
  244. /* Output to console */
  245. fprintf( stdout, "[%d:%d] %s\n", (int)getpid( ), Level, msg );
  246. fflush( stdout );
  247. }
  248. #ifdef SYSLOG
  249. else syslog( Level, "%s", msg );
  250. #endif
  251. } /* Log_Resolver */
  252. /**
  253. * Send log messages to users flagged with the "s" mode.
  254. * @param Msg The message to send.
  255. */
  256. LOCAL void
  257. Wall_ServerNotice( char *Msg )
  258. {
  259. CLIENT *c;
  260. assert( Msg != NULL );
  261. c = Client_First( );
  262. while(c) {
  263. if (Client_Conn(c) > NONE && Client_HasMode(c, 's'))
  264. IRC_WriteStrClient(c, "NOTICE %s :%s%s", Client_ID(c),
  265. NOTICE_TXTPREFIX, Msg);
  266. c = Client_Next( c );
  267. }
  268. } /* Wall_ServerNotice */
  269. /* -eof- */