log.c 6.2 KB

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