log.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  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_NOTICE, "%s done%s, served %lu connections.", PACKAGE_NAME,
  96. NGIRCd_SignalRestart ? " (restarting)" : "", Conn_CountAccepted());
  97. #ifdef SYSLOG
  98. closelog();
  99. #endif
  100. } /* Log_Exit */
  101. /**
  102. * Log function for debug messages.
  103. * This function is only functional when the program is compiled with debug
  104. * code enabled; otherwise it is an empty function which the compiler will
  105. * hopefully mangle down to "nothing" (see log.h). Therefore you should use
  106. * LogDebug(...) in favor to Log(LOG_DEBUG, ...).
  107. * @param Format Format string like printf().
  108. * @param ... Further arguments.
  109. */
  110. #ifdef DEBUG
  111. # ifdef PROTOTYPES
  112. GLOBAL void
  113. LogDebug( const char *Format, ... )
  114. # else
  115. GLOBAL void
  116. LogDebug( Format, va_alist )
  117. const char *Format;
  118. va_dcl
  119. # endif /* PROTOTYPES */
  120. {
  121. char msg[MAX_LOG_MSG_LEN];
  122. va_list ap;
  123. if (!NGIRCd_Debug) return;
  124. #ifdef PROTOTYPES
  125. va_start( ap, Format );
  126. #else
  127. va_start( ap );
  128. #endif
  129. vsnprintf( msg, MAX_LOG_MSG_LEN, Format, ap );
  130. va_end( ap );
  131. Log(LOG_DEBUG, "%s", msg);
  132. }
  133. #endif /* DEBUG */
  134. /**
  135. * Logging function of ngIRCd.
  136. * This function logs messages to the console and/or syslog, whichever is
  137. * suitable for the mode ngIRCd is running in (daemon vs. non-daemon).
  138. * If LOG_snotice is set, the log messages goes to all user with the mode +s
  139. * set and the local &SERVER channel, too.
  140. * Please note: you sould use LogDebug(...) for debug messages!
  141. * @param Level syslog level (LOG_xxx)
  142. * @param Format Format string like printf().
  143. * @param ... Further arguments.
  144. */
  145. #ifdef PROTOTYPES
  146. GLOBAL void
  147. Log( int Level, const char *Format, ... )
  148. #else
  149. GLOBAL void
  150. Log( Level, Format, va_alist )
  151. int Level;
  152. const char *Format;
  153. va_dcl
  154. #endif
  155. {
  156. char msg[MAX_LOG_MSG_LEN];
  157. bool snotice;
  158. va_list ap;
  159. assert( Format != NULL );
  160. if( Level & LOG_snotice )
  161. {
  162. /* Notice an User mit "s" Mode */
  163. snotice = true;
  164. Level &= ~LOG_snotice;
  165. }
  166. else snotice = false;
  167. #ifdef DEBUG
  168. if(( Level == LOG_DEBUG ) && ( ! NGIRCd_Debug )) return;
  169. #else
  170. if( Level == LOG_DEBUG ) return;
  171. #endif
  172. #ifdef PROTOTYPES
  173. va_start( ap, Format );
  174. #else
  175. va_start( ap );
  176. #endif
  177. vsnprintf( msg, MAX_LOG_MSG_LEN, Format, ap );
  178. va_end( ap );
  179. Log_Message(Level, msg);
  180. if (snotice) {
  181. /* Send NOTICE to all local users with mode +s and to the
  182. * local &SERVER channel */
  183. Log_ServerNotice('s', "%s", msg);
  184. Channel_LogServer(msg);
  185. }
  186. } /* Log */
  187. GLOBAL void
  188. Log_Init_Subprocess(char UNUSED *Name)
  189. {
  190. #ifdef SYSLOG
  191. openlog(PACKAGE, LOG_CONS|LOG_PID, Conf_SyslogFacility);
  192. #endif
  193. #ifdef DEBUG
  194. Log_Subprocess(LOG_DEBUG, "%s sub-process starting, PID %ld.",
  195. Name, (long)getpid());
  196. #endif
  197. }
  198. GLOBAL void
  199. Log_Exit_Subprocess(char UNUSED *Name)
  200. {
  201. #ifdef DEBUG
  202. Log_Subprocess(LOG_DEBUG, "%s sub-process %ld done.",
  203. Name, (long)getpid());
  204. #endif
  205. #ifdef SYSLOG
  206. closelog( );
  207. #endif
  208. }
  209. #ifdef PROTOTYPES
  210. GLOBAL void
  211. Log_Subprocess(const int Level, const char *Format, ...)
  212. #else
  213. GLOBAL void
  214. Log_Subprocess(Level, Format, va_alist)
  215. const int Level;
  216. const char *Format;
  217. va_dcl
  218. #endif
  219. {
  220. char msg[MAX_LOG_MSG_LEN];
  221. va_list ap;
  222. assert(Format != NULL);
  223. #ifdef DEBUG
  224. if ((Level == LOG_DEBUG) && (!NGIRCd_Debug))
  225. return;
  226. #else
  227. if (Level == LOG_DEBUG)
  228. return;
  229. #endif
  230. #ifdef PROTOTYPES
  231. va_start(ap, Format);
  232. #else
  233. va_start(ap);
  234. #endif
  235. vsnprintf(msg, MAX_LOG_MSG_LEN, Format, ap);
  236. va_end(ap);
  237. Log_Message(Level, msg);
  238. }
  239. /**
  240. * Send a log message to all local users flagged with the given user mode.
  241. * @param UserMode User mode which the target user must have set,
  242. * @param Format The format string.
  243. */
  244. #ifdef PROTOTYPES
  245. GLOBAL void
  246. Log_ServerNotice(const char UserMode, const char *Format, ... )
  247. #else
  248. GLOBAL void
  249. Log_ServerNotice(UserMode, Format, va_alist)
  250. const char UserMode;
  251. const char *Format;
  252. va_dcl
  253. #endif
  254. {
  255. CLIENT *c;
  256. char msg[MAX_LOG_MSG_LEN];
  257. va_list ap;
  258. assert(Format != NULL);
  259. #ifdef PROTOTYPES
  260. va_start(ap, Format);
  261. #else
  262. va_start(ap);
  263. #endif
  264. vsnprintf(msg, MAX_LOG_MSG_LEN, Format, ap);
  265. va_end(ap);
  266. for(c=Client_First(); c != NULL; c=Client_Next(c)) {
  267. if (Client_Conn(c) > NONE && Client_HasMode(c, UserMode))
  268. IRC_WriteStrClient(c, "NOTICE %s :%s%s", Client_ID(c),
  269. NOTICE_TXTPREFIX, msg);
  270. }
  271. } /* Log_ServerNotice */
  272. /* -eof- */