log.c 6.2 KB

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