log.c 6.4 KB

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