log.c 7.2 KB

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