log.c 6.3 KB

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