log.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. /*
  2. * log.c -- handles:
  3. *
  4. * What else?!
  5. *
  6. */
  7. #include "common.h"
  8. #include "log.h"
  9. #include "tandem.h"
  10. #include "color.h"
  11. #include "userrec.h"
  12. #include "botnet.h"
  13. #include "botmsg.h"
  14. #include "dcc.h"
  15. #include "dccutil.h"
  16. #include "rfc1459.h"
  17. #include "users.h"
  18. #include "misc.h"
  19. #include "main.h"
  20. #include <ctype.h>
  21. #include <stdarg.h>
  22. int conmask = LOG_MODES | LOG_CMDS | LOG_MISC; /* Console mask */
  23. int debug_output = 1; /* Disply output to server to LOG_SERVEROUT */
  24. int use_console_r = 1; /* Allow users to set their console +r */
  25. typedef struct {
  26. int flag;
  27. unsigned char c;
  28. char *type;
  29. } logmode_mapping_t;
  30. static logmode_mapping_t logmode_mappings[] = {
  31. {LOG_MSGS, 'm', "msgs"},
  32. {LOG_PUBLIC, 'p', "public"},
  33. {LOG_JOIN, 'j', "joins"},
  34. {LOG_MODES, 'k', "kicks/modes"},
  35. {LOG_CMDS, 'c', "cmds"},
  36. {LOG_MISC, 'o', "misc"},
  37. {LOG_BOTS, 'b', "bots"},
  38. {LOG_RAW, 'r', "raw"},
  39. {LOG_WALL, 'w', "wallops"},
  40. {LOG_FILES, 'x', "files"},
  41. {LOG_SERV, 's', "server"},
  42. {LOG_DEBUG, 'd', "debug"},
  43. {LOG_SRVOUT, 'v', "server output"},
  44. {LOG_BOTNET, 't', "botnet traffic"},
  45. {LOG_BOTSHARE, 'h', "share traffic"},
  46. {LOG_ERRORS, 'e', "errors"},
  47. {LOG_GETIN, 'g', "getin"},
  48. {LOG_WARN, 'u', "warnings"},
  49. {0, 0, NULL}
  50. };
  51. #define LOG_LEVELS 18 /* change this if you change the levels */
  52. #define NEEDS_DEBUG_OUTPUT (LOG_RAW|LOG_SRVOUT|LOG_BOTNET|LOG_BOTSHARE)
  53. int logmodes(const char *s)
  54. {
  55. logmode_mapping_t *mapping = NULL;
  56. int modes = 0;
  57. while (*s) {
  58. if (*s == '*') return(LOG_ALL);
  59. for (mapping = logmode_mappings; mapping->type; mapping++) {
  60. if (mapping->c == tolower(*s)) break;
  61. }
  62. if (mapping->type) modes |= mapping->flag;
  63. s++;
  64. }
  65. return(modes);
  66. }
  67. char *masktype(int x)
  68. {
  69. static char s[LOG_LEVELS + 1];
  70. char *p = s;
  71. logmode_mapping_t *mapping = NULL;
  72. for (mapping = logmode_mappings; mapping->type; mapping++) {
  73. if (x & mapping->flag) {
  74. if ((mapping->flag & NEEDS_DEBUG_OUTPUT) && !debug_output) continue;
  75. *p++ = mapping->c;
  76. }
  77. }
  78. if (p == s) *p++ = '-';
  79. *p = 0;
  80. return(s);
  81. }
  82. char *maskname(int x)
  83. {
  84. static char s[1024] = "";
  85. logmode_mapping_t *mapping = NULL;
  86. int len;
  87. *s = 0;
  88. for (mapping = logmode_mappings; mapping->type; mapping++) {
  89. if (x & mapping->flag) {
  90. if ((mapping->flag & NEEDS_DEBUG_OUTPUT) && !debug_output) continue;
  91. strcat(s, mapping->type);
  92. strcat(s, ", ");
  93. }
  94. }
  95. len = strlen(s);
  96. if (len) s[len-2] = 0;
  97. else strcpy(s, "none");
  98. return(s);
  99. }
  100. /*
  101. * Logging functions
  102. */
  103. void logidx(int idx, const char *format, ...)
  104. {
  105. char va_out[LOGLINEMAX + 1];
  106. va_list va;
  107. va_start(va, format);
  108. egg_vsnprintf(va_out, LOGLINEMAX, format, va);
  109. va_end(va);
  110. if (idx < 0)
  111. putlog(LOG_DEBUG, "*", "%s", va_out);
  112. else
  113. dprintf(idx, "%s\n", va_out);
  114. }
  115. /* Log something
  116. * putlog(level,channel_name,format,...);
  117. * Broadcast the log if chname is not '@'
  118. */
  119. void putlog(int type, const char *chname, const char *format, ...)
  120. {
  121. int idx = 0;
  122. char va_out[LOGLINEMAX + 1] = "", out[LOGLINEMAX + 1] = "", *p = NULL;
  123. #ifdef HUB
  124. char stamp[34] = "";
  125. struct tm *t = NULL;
  126. #endif /* HUB */
  127. va_list va;
  128. va_start(va, format);
  129. #ifdef HUB
  130. # ifdef S_UTCTIME
  131. t = gmtime(&now);
  132. # else /* !S_UTCTIME */
  133. t = localtime(&now);
  134. # endif /* S_UTCTIME */
  135. egg_strftime(stamp, sizeof(stamp), LOG_TS, t);
  136. #endif /* HUB */
  137. /* No need to check if out should be null-terminated here,
  138. * just do it! <cybah>
  139. */
  140. egg_vsnprintf(va_out, LOGLINEMAX, format, va);
  141. va_end(va);
  142. if (!va_out[0]) {
  143. putlog(LOG_ERRORS, "*", "Empty putlog() detected");
  144. return;
  145. }
  146. if ((p = strchr(va_out, '\n'))) /* make sure no trailing newline */
  147. *p = 0;
  148. #ifdef HUB
  149. /* Place the timestamp in the string to be printed */
  150. if (stamp[0])
  151. egg_snprintf(out, sizeof out, "%s %s", stamp, va_out);
  152. #endif /* HUB */
  153. #ifdef LEAF
  154. egg_snprintf(out, sizeof out, "%s", va_out);
  155. #endif /* LEAF */
  156. /* strcat(out, "\n"); */
  157. /* FIXME: WRITE LOG HERE */
  158. /* broadcast to hubs */
  159. if (chname[0] == '*' && conf.bot && conf.bot->nick) {
  160. char outbuf[LOGLINEMAX + 1] = "";
  161. egg_snprintf(outbuf, sizeof outbuf, "hl %d %s", type, out);
  162. if (userlist && !loading) {
  163. tand_t *bot = NULL;
  164. struct userrec *ubot = NULL;
  165. for (bot = tandbot; bot; bot = bot->next) {
  166. if ((ubot = get_user_by_handle(userlist, bot->bot))) {
  167. if (bot_hublevel(ubot) < 999)
  168. putbot(ubot->handle, outbuf);
  169. }
  170. }
  171. } else {
  172. putallbots(outbuf);
  173. }
  174. }
  175. for (idx = 0; idx < dcc_total; idx++) {
  176. if ((dcc[idx].type == &DCC_CHAT && !dcc[idx].simul) && (dcc[idx].u.chat->con_flags & type)) {
  177. if ((chname[0] == '@') || (chname[0] == '*') || (dcc[idx].u.chat->con_chan[0] == '*') ||
  178. (!rfc_casecmp(chname, dcc[idx].u.chat->con_chan)))
  179. dprintf(idx, "%s\n", out);
  180. }
  181. }
  182. if ((!backgrd) && (!term_z)) {
  183. dprintf(DP_STDOUT, "%s\n", out);
  184. } else if ((type & LOG_ERRORS || type & LOG_MISC) && use_stderr) {
  185. dprintf(DP_STDERR, "%s\n", va_out);
  186. }
  187. }
  188. void
  189. irc_log(struct chanset_t *chan, const char *format, ...)
  190. {
  191. char va_out[LOGLINEMAX + 1];
  192. va_list va;
  193. va_start(va, format);
  194. egg_vsnprintf(va_out, LOGLINEMAX, format, va);
  195. va_end(va);
  196. // if (egg_strcasecmp(chan->dname, TO))
  197. // dprintf(DP_HELP, "PRIVMSG %s :[%s] %s\n", TO, chan->dname, va_out);
  198. // chanout_but(-1, 1, "[%s] %s\n", chan->dname, va_out);
  199. // botnet_send_chan(-1, conf.bot->nick, chan->dname, 1, va_out);
  200. if (chan)
  201. putlog(LOG_PUBLIC, "*", "[%s] %s", chan->dname, va_out);
  202. else
  203. putlog(LOG_PUBLIC, "*", "%s", va_out);
  204. // sdprintf("%s", va_out);
  205. }