/[cvs]/eggdrop1.9/src/logfile.c
ViewVC logotype

Contents of /eggdrop1.9/src/logfile.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.36 - (show annotations) (download) (as text)
Tue Dec 16 22:36:38 2003 UTC (15 years, 10 months ago) by wcc
Branch: MAIN
Changes since 1.35: +3 -3 lines
File MIME type: text/x-chdr
* src/ gettextification.
* More cleanups.

1 /* logfile.c: logging
2 *
3 * Copyright (C) 2001, 2002, 2003, 2004 Eggheads Development Team
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 *
19 */
20
21 #ifndef lint
22 static const char rcsid[] = "$Id: logfile.c,v 1.35 2003/12/16 21:45:35 wcc Exp $";
23 #endif
24
25 #include <eggdrop/eggdrop.h>
26 #include <stdio.h>
27 #include <unistd.h>
28 #include "core_config.h"
29 #include "logfile.h"
30
31 typedef struct log_b {
32 struct log_b *next;
33 char *filename;
34 int mask;
35 char *chname;
36 char *last_msg;
37 int repeats;
38 int flags;
39 FILE *fp;
40 } log_t;
41
42 extern int backgrd, use_stderr;
43 extern time_t now;
44
45 static log_t *log_list_head = NULL; /* Linked list of logfiles. */
46
47 static int logfile_minutely();
48 static int logfile_5minutely();
49 static int logfile_cycle();
50 static void check_logsizes();
51 static void flushlog(log_t *log, char *timestamp);
52
53 /* Bind for the log table. The core does logging to files and the partyline, but
54 * modules may implement sql logging or whatever. */
55 static int on_putlog(int flags, const char *chan, const char *text, int len);
56
57 static script_command_t log_script_cmds[] = {
58 {"", "logfile", logfile_add, NULL, 3, "sss", "modes chan filename", SCRIPT_STRING, 0},
59 {0}
60 };
61
62 static bind_list_t log_binds[] = {
63 {NULL, NULL, on_putlog},
64 {0}
65 };
66
67 static bind_list_t log_events[] = {
68 {NULL, "minutely", logfile_minutely},
69 {NULL, "5minutely", logfile_5minutely},
70 {0}
71 };
72
73 void logfile_init()
74 {
75 script_create_commands(log_script_cmds);
76 bind_add_list("log", log_binds);
77 bind_add_list("event", log_events);
78 }
79
80 static int get_timestamp(char *t)
81 {
82 time_t now2 = time(NULL);
83
84 /* Calculate timestamp. */
85 strftime(t, 32, "[%H:%M] ", localtime(&now2));
86 return(0);
87 }
88
89 static int logfile_minutely()
90 {
91 struct tm *nowtm;
92 int miltime;
93
94 if (core_config.quick_logs) {
95 flushlogs();
96 check_logsizes();
97 }
98
99 nowtm = localtime(&now);
100 miltime = 100 * nowtm->tm_hour + nowtm->tm_min;
101
102 if (miltime == core_config.switch_logfiles_at) logfile_cycle();
103
104 return(0);
105 }
106
107 static int logfile_5minutely()
108 {
109 if (!core_config.quick_logs) {
110 flushlogs();
111 check_logsizes();
112 }
113 return(0);
114 }
115
116 static int logfile_cycle()
117 {
118 log_t *log, *prev;
119 char suffix[32];
120 char *newfname;
121
122 putlog(LOG_MISC, "*", _("Cycling logfiles..."));
123 flushlogs();
124
125 /* Determine suffix for cycled logfiles. */
126 if (core_config.keep_all_logs) {
127 strftime(suffix, 32, core_config.logfile_suffix, localtime(&now));
128 }
129
130 prev = NULL;
131 for (log = log_list_head; log; log = log->next) {
132 fclose(log->fp);
133
134 if (core_config.keep_all_logs) newfname = egg_mprintf("%s%s", log->filename, suffix);
135 else newfname = egg_mprintf("%s.yesterday", log->filename);
136
137 unlink(newfname);
138 movefile(log->filename, newfname);
139 free(newfname);
140
141 log->fp = fopen(log->filename, "a");
142 if (!log->fp) {
143 logfile_del(log->filename);
144 if (prev) log = prev;
145 else log = log_list_head;
146 }
147 else prev = log;
148 }
149 return(0);
150 }
151
152 char *logfile_add(char *modes, char *chan, char *fname)
153 {
154 FILE *fp;
155 log_t *log;
156
157 /* Get rid of any duplicates. */
158 logfile_del(fname);
159
160 /* Test the filename. */
161 fp = fopen(fname, "a");
162 if (!fp) return("");
163
164 log = (log_t *)calloc(1, sizeof(*log));
165 log->filename = strdup(fname);
166 log->chname = strdup(chan);
167 log->last_msg = strdup("");
168 log->mask = LOG_ALL;
169 log->fp = fp;
170
171 log->next = log_list_head;
172 log_list_head = log;
173
174 return(log->filename);
175 }
176
177 int logfile_del(char *filename)
178 {
179 log_t *log, *prev;
180 char timestamp[32];
181
182 prev = NULL;
183 for (log = log_list_head; log; log = log->next) {
184 if (!strcmp(log->filename, filename)) break;
185 prev = log;
186 }
187 if (!log) return(1);
188 if (prev) prev->next = log->next;
189 else log_list_head = log->next;
190 if (log->fp) {
191 get_timestamp(timestamp);
192 flushlog(log, timestamp);
193 fclose(log->fp);
194 }
195 free(log->last_msg);
196 free(log->filename);
197 free(log);
198 return(0);
199 }
200
201 static int on_putlog(int flags, const char *chan, const char *text, int len)
202 {
203 log_t *log;
204 char timestamp[32];
205
206 get_timestamp(timestamp);
207 for (log = log_list_head; log; log = log->next) {
208 /* If this log doesn't match, skip it. */
209 if (!(log->mask & flags)) continue;
210 if (chan[0] != '*' && log->chname[0] != '*' && irccmp(chan, log->chname)) continue;
211
212 /* If it's a repeat message, don't write it again. */
213 if (!strcasecmp(text, log->last_msg)) {
214 log->repeats++;
215 continue;
216 }
217
218 /* If there was a repeated message, write the count. */
219 if (log->repeats) {
220 fprintf(log->fp, "%s", timestamp);
221 fprintf(log->fp, _("Last message repeated %d time(s).\n"), log->repeats);
222 log->repeats = 0;
223 }
224
225 /* Save this msg to check for repeats next time. */
226 str_redup(&log->last_msg, text);
227
228 /* Now output to the file. */
229 fprintf(log->fp, "%s%s\n", timestamp, text);
230 }
231
232 if (!backgrd || use_stderr) printf("%s%s\n", timestamp, text);
233 return(0);
234 }
235
236 static void check_logsizes()
237 {
238 int size;
239 char *newfname;
240 log_t *log;
241
242 if (core_config.keep_all_logs || core_config.max_logsize <= 0) return;
243
244 for (log = log_list_head; log; log = log->next) {
245 size = ftell(log->fp) / 1024; /* Size in kilobytes. */
246 if (size < core_config.max_logsize) continue;
247
248 /* It's too big. */
249 putlog(LOG_MISC, "*", _("Cycling logfile %s: over max-logsize (%d kilobytes)."), log->filename, size);
250 fclose(log->fp);
251
252 newfname = egg_mprintf("%s.yesterday", log->filename);
253 unlink(newfname);
254 movefile(log->filename, newfname);
255 free(newfname);
256 }
257 }
258
259 static void flushlog(log_t *log, char *timestamp)
260 {
261 if (log->repeats) {
262 fprintf(log->fp, "%s", timestamp);
263 fprintf(log->fp, _("Last message repeated %d time(s).\n"), log->repeats);
264 log->repeats = 0;
265 realloc_strcpy(log->last_msg, "");
266 }
267 fflush(log->fp);
268 }
269
270 /* Flush the logfiles to disk
271 */
272 void flushlogs()
273 {
274 char timestamp[32];
275 log_t *log;
276
277 get_timestamp(timestamp);
278 for (log = log_list_head; log; log = log->next) {
279 flushlog(log, timestamp);
280 }
281 }

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23