]> jfr.im git - irc/rqf/shadowircd.git/blame - src/s_log.c
[svn] - fix off-by-one memory overflow error.
[irc/rqf/shadowircd.git] / src / s_log.c
CommitLineData
212380e3 1/*
2 * ircd-ratbox: an advanced Internet Relay Chat Daemon(ircd).
3 *
4 * Copyright (C) 2003 Lee H <lee@leeh.co.uk>
5 * Copyright (C) 2003-2005 ircd-ratbox development team
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
9 * met:
10 *
11 * 1.Redistributions of source code must retain the above copyright notice,
12 * this list of conditions and the following disclaimer.
13 * 2.Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3.The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
23 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
28 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 *
31 * $Id: s_log.c 1563 2006-06-02 00:43:35Z nenolod $
32 */
33
34#include "stdinc.h"
35#include "ircd_defs.h"
36#include "s_log.h"
37#include "s_conf.h"
38#include "sprintf_irc.h"
39#include "send.h"
40#include "client.h"
41#include "s_serv.h"
42
43static FILE *log_main;
44static FILE *log_user;
45static FILE *log_fuser;
46static FILE *log_oper;
47static FILE *log_foper;
48static FILE *log_server;
49static FILE *log_kill;
50static FILE *log_gline;
51static FILE *log_kline;
52static FILE *log_operspy;
53static FILE *log_ioerror;
54
55struct log_struct
56{
57 char **name;
58 FILE **logfile;
59};
60
61static struct log_struct log_table[LAST_LOGFILE] =
62{
63 { NULL, &log_main },
64 { &ConfigFileEntry.fname_userlog, &log_user },
65 { &ConfigFileEntry.fname_fuserlog, &log_fuser },
66 { &ConfigFileEntry.fname_operlog, &log_oper },
67 { &ConfigFileEntry.fname_foperlog, &log_foper },
68 { &ConfigFileEntry.fname_serverlog, &log_server },
69 { &ConfigFileEntry.fname_killlog, &log_kill },
70 { &ConfigFileEntry.fname_klinelog, &log_kline },
71 { &ConfigFileEntry.fname_glinelog, &log_gline },
72 { &ConfigFileEntry.fname_operspylog, &log_operspy },
73 { &ConfigFileEntry.fname_ioerrorlog, &log_ioerror }
74};
75
76void
77init_main_logfile(void)
78{
79 if(log_main == NULL)
80 log_main = fopen(LPATH, "a");
81}
82
83void
84open_logfiles(void)
85{
86 int i;
87
88 if(log_main != NULL)
89 fclose(log_main);
90
91 log_main = fopen(LPATH, "a");
92
93 /* log_main is handled above, so just do the rest */
94 for(i = 1; i < LAST_LOGFILE; i++)
95 {
96 /* close open logfiles */
97 if(*log_table[i].logfile != NULL)
98 {
99 fclose(*log_table[i].logfile);
100 *log_table[i].logfile = NULL;
101 }
102
103 /* reopen those with paths */
104 if(!EmptyString(*log_table[i].name))
105 *log_table[i].logfile = fopen(*log_table[i].name, "a");
106 }
107}
108
109void
110ilog(ilogfile dest, const char *format, ...)
111{
112 FILE *logfile = *log_table[dest].logfile;
113 char buf[BUFSIZE];
114 char buf2[BUFSIZE];
115 va_list args;
116
117 if(logfile == NULL)
118 return;
119
120 va_start(args, format);
121 ircvsnprintf(buf, sizeof(buf), format, args);
122 va_end(args);
123
124 ircsnprintf(buf2, sizeof(buf2), "%s %s\n", smalldate(), buf);
125
126 if(fputs(buf2, logfile) < 0)
127 {
128 fclose(logfile);
129 *log_table[dest].logfile = NULL;
130 }
131
132 fflush(logfile);
133}
134
135static void
136_iprint(const char *domain, char *buf)
137{
138 if (domain == NULL || buf == NULL)
139 return;
140
141 fprintf(stderr, "%8s: %s\n", domain, buf);
142}
143
144void
145inotice(const char *format, ...)
146{
147 char buf[BUFSIZE];
148 va_list args;
149
150 va_start(args, format);
151 ircvsnprintf(buf, sizeof(buf), format, args);
152 va_end(args);
153
154 _iprint("notice", buf);
155
156 ilog(L_MAIN, "%s", buf);
157}
158
159void
160iwarn(const char *format, ...)
161{
162 char buf[BUFSIZE];
163 va_list args;
164
165 va_start(args, format);
166 ircvsnprintf(buf, sizeof(buf), format, args);
167 va_end(args);
168
169 _iprint("warning", buf);
170
171 ilog(L_MAIN, "%s", buf);
172}
173
174void
175ierror(const char *format, ...)
176{
177 char buf[BUFSIZE];
178 va_list args;
179
180 va_start(args, format);
181 ircvsnprintf(buf, sizeof(buf), format, args);
182 va_end(args);
183
184 _iprint("error", buf);
185
186 ilog(L_MAIN, "%s", buf);
187}
188
189void
190report_operspy(struct Client *source_p, const char *token, const char *arg)
191{
192 /* if its not my client its already propagated */
193 if(MyClient(source_p))
194 sendto_match_servs(source_p, "*", CAP_ENCAP, NOCAPS,
195 "ENCAP * OPERSPY %s %s",
196 token, arg ? arg : "");
197
198 sendto_realops_snomask(SNO_OPERSPY,
199 ConfigFileEntry.operspy_admin_only ? L_ADMIN : L_ALL,
200 "OPERSPY %s %s %s",
201 get_oper_name(source_p), token,
202 arg ? arg : "");
203
204 ilog(L_OPERSPY, "OPERSPY %s %s %s",
205 get_oper_name(source_p), token, arg ? arg : "");
206}
207
208const char *
209smalldate(void)
210{
211 static char buf[MAX_DATE_STRING];
212 struct tm *lt;
213 time_t ltime = CurrentTime;
214
215 lt = localtime(&ltime);
216
217 ircsnprintf(buf, sizeof(buf), "%d/%d/%d %02d.%02d",
218 lt->tm_year + 1900, lt->tm_mon + 1,
219 lt->tm_mday, lt->tm_hour, lt->tm_min);
220
221 return buf;
222}
223
224/*
225 * report_error - report an error from an errno.
226 * Record error to log and also send a copy to all *LOCAL* opers online.
227 *
228 * text is a *format* string for outputing error. It must
229 * contain only two '%s', the first will be replaced
230 * by the sockhost from the client_p, and the latter will
231 * be taken from sys_errlist[errno].
232 *
233 * client_p if not NULL, is the *LOCAL* client associated with
234 * the error.
235 *
236 * Cannot use perror() within daemon. stderr is closed in
237 * ircd and cannot be used. And, worse yet, it might have
238 * been reassigned to a normal connection...
239 *
240 * Actually stderr is still there IFF ircd was run with -s --Rodder
241 */
242
243void
244report_error(const char *text, const char *who, const char *wholog, int error)
245{
246 who = (who) ? who : "";
247 wholog = (wholog) ? wholog : "";
248
249 sendto_realops_snomask(SNO_DEBUG, L_ALL, text, who, strerror(error));
250
251 ilog(L_IOERROR, text, wholog, strerror(error));
252}