/[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.27 - (show annotations) (download) (as text)
Mon Feb 3 06:42:40 2003 UTC (16 years, 8 months ago) by stdarg
Branch: MAIN
Changes since 1.26: +6 -4 lines
File MIME type: text/x-chdr
*** empty log message ***

1 /*
2 * logfile.c --
3 *
4 */
5
6 #include "main.h"
7 #include "modules.h" /* add_hook() */
8 #include "logfile.h" /* prototypes */
9 #include "dccutil.h" /* dprintf_eggdrop */
10 #include "irccmp.h" /* irccmp */
11 #include "chanprog.h" /* logmodes */
12 #include <eggdrop/eggdrop.h>
13
14 typedef struct log_b {
15 struct log_b *next;
16 char *filename;
17 int mask;
18 char *chname;
19 char *last_msg;
20 int repeats;
21 int flags;
22 FILE *fp;
23 } log_t;
24
25 extern int use_stderr; /* From main.c, while we're starting eggdrop. */
26 extern int term_z;
27 extern int backgrd;
28 extern int con_chan;
29 extern time_t now;
30
31 extern int dcc_total;
32 extern struct dcc_t *dcc;
33
34 #ifndef MAKING_MODS
35 extern struct dcc_table DCC_CHAT;
36 #endif /* MAKING_MODS */
37
38 static int cycle_at = 300; /* Military time where we cycle logfiles. */
39 static int keep_all_logs = 0; /* Keep all logs? */
40 static int max_logsize = 0; /* Max log size in kilobytes. */
41 static int quick_logs = 0; /* Check size more often? */
42 static char *logfile_suffix = NULL; /* Suffix for old logfiles. */
43
44 static log_t *log_list_head = NULL; /* Linked list of logfiles. */
45
46 static int logfile_minutely();
47 static int logfile_5minutely();
48 static int logfile_cycle();
49 static void check_logsizes();
50 static void flushlog(log_t *log, char *timestamp);
51
52 /* Bind for the log table. The core does logging to files and the partyline, but
53 * modules may implement sql logging or whatever. */
54 static int on_putlog(int flags, const char *chan, const char *text, int len);
55
56 static script_linked_var_t log_script_vars[] = {
57 {"", "logfile_suffix", &logfile_suffix, SCRIPT_STRING, NULL},
58 {"", "max_logsize", &max_logsize, SCRIPT_INTEGER, NULL},
59 {"", "switch_logfiles_at", &cycle_at, SCRIPT_INTEGER, NULL},
60 {"", "keep_all_logs", &keep_all_logs, SCRIPT_INTEGER, NULL},
61 {"", "quick_logs", &quick_logs, SCRIPT_INTEGER, NULL},
62 {0}
63 };
64
65 static script_command_t log_script_cmds[] = {
66 {"", "logfile", logfile_add, NULL, 3, "sss", "modes chan filename", SCRIPT_STRING, 0},
67 {0}
68 };
69
70 static bind_list_t log_binds[] = {
71 {"", on_putlog},
72 {0}
73 };
74
75 void logfile_init()
76 {
77 logfile_suffix = strdup(".%d%b%Y");
78 script_link_vars(log_script_vars);
79 script_create_commands(log_script_cmds);
80 add_hook(HOOK_MINUTELY, logfile_minutely);
81 add_hook(HOOK_5MINUTELY, logfile_5minutely);
82 bind_add_list("log", log_binds);
83 }
84
85 static int get_timestamp(char *t)
86 {
87 time_t now2 = time(NULL);
88
89 /* Calculate timestamp. */
90 strftime(t, 32, "[%H:%M] ", localtime(&now2));
91 return(0);
92 }
93
94 static int logfile_minutely()
95 {
96 struct tm *nowtm;
97 int miltime;
98
99 if (quick_logs) {
100 flushlogs();
101 check_logsizes();
102 }
103
104 nowtm = localtime(&now);
105 miltime = 100 * nowtm->tm_hour + nowtm->tm_min;
106
107 if (miltime == cycle_at) logfile_cycle();
108
109 return(0);
110 }
111
112 static int logfile_5minutely()
113 {
114 if (!quick_logs) {
115 flushlogs();
116 check_logsizes();
117 }
118 return(0);
119 }
120
121 static int logfile_cycle()
122 {
123 log_t *log, *prev;
124 char suffix[32];
125 char *newfname;
126
127 putlog(LOG_MISC, "*", _("Cycling logfiles"));
128 flushlogs();
129
130 /* Determine suffix for cycled logfiles. */
131 if (keep_all_logs) {
132 strftime(suffix, 32, logfile_suffix, localtime(&now));
133 }
134
135 prev = NULL;
136 for (log = log_list_head; log; log = log->next) {
137 fclose(log->fp);
138
139 if (keep_all_logs) newfname = egg_mprintf("%s%s", log->filename, suffix);
140 else newfname = egg_mprintf("%s.yesterday", log->filename);
141
142 unlink(newfname);
143 movefile(log->filename, newfname);
144 free(newfname);
145
146 log->fp = fopen(log->filename, "a");
147 if (!log->fp) {
148 logfile_del(log->filename);
149 if (prev) log = prev;
150 else log = log_list_head;
151 }
152 else prev = log;
153 }
154 return(0);
155 }
156
157 char *logfile_add(char *modes, char *chan, char *fname)
158 {
159 FILE *fp;
160 log_t *log;
161
162 /* Get rid of any duplicates. */
163 logfile_del(fname);
164
165 /* Test the filename. */
166 fp = fopen(fname, "a");
167 if (!fp) return("");
168
169 log = (log_t *)calloc(1, sizeof(*log));
170 log->filename = strdup(fname);
171 log->chname = strdup(chan);
172 log->last_msg = strdup("");
173 log->mask = logmodes(modes);
174 log->fp = fp;
175
176 log->next = log_list_head;
177 log_list_head = log;
178
179 return(log->filename);
180 }
181
182 int logfile_del(char *filename)
183 {
184 log_t *log, *prev;
185 char timestamp[32];
186
187 prev = NULL;
188 for (log = log_list_head; log; log = log->next) {
189 if (!strcmp(log->filename, filename)) break;
190 prev = log;
191 }
192 if (!log) return(1);
193 if (prev) prev->next = log->next;
194 else log_list_head = log->next;
195 if (log->fp) {
196 get_timestamp(timestamp);
197 flushlog(log, timestamp);
198 fclose(log->fp);
199 }
200 free(log->last_msg);
201 free(log->filename);
202 free(log);
203 return(0);
204 }
205
206 static int on_putlog(int flags, const char *chan, const char *text, int len)
207 {
208 log_t *log;
209 char timestamp[32];
210 int i;
211
212 get_timestamp(timestamp);
213 for (log = log_list_head; log; log = log->next) {
214 /* If this log doesn't match, skip it. */
215 if (!(log->mask & flags)) continue;
216 if (chan[0] != '*' && log->chname[0] != '*' && irccmp(chan, log->chname)) continue;
217
218 /* If it's a repeat message, don't write it again. */
219 if (!strcasecmp(text, log->last_msg)) {
220 log->repeats++;
221 continue;
222 }
223
224 /* If there was a repeated message, write the count. */
225 if (log->repeats) {
226 fprintf(log->fp, "%s", timestamp);
227 fprintf(log->fp, _("Last message repeated %d time(s).\n"), log->repeats);
228 log->repeats = 0;
229 }
230
231 /* Save this msg to check for repeats next time. */
232 str_redup(&log->last_msg, text);
233
234 /* Now output to the file. */
235 fprintf(log->fp, "%s%s\n", timestamp, text);
236 }
237
238 for (i = 0; i < dcc_total; i++)
239 if ((dcc[i].type == &DCC_CHAT)) {
240 dprintf(i, "%s%s\n", timestamp, text);
241 }
242 if ((!backgrd) && (!con_chan) && (!term_z))
243 dprintf(DP_STDOUT, "%s%s\n", timestamp, text);
244 else if (use_stderr) {
245 dprintf(DP_STDERR, "%s%s\n", timestamp, text);
246 }
247
248 return(0);
249 }
250
251 static void check_logsizes()
252 {
253 int size;
254 char *newfname;
255 log_t *log;
256
257 if (keep_all_logs || max_logsize <= 0) return;
258
259 for (log = log_list_head; log; log = log->next) {
260 size = ftell(log->fp) / 1024; /* Size in kilobytes. */
261 if (size < max_logsize) continue;
262
263 /* It's too big. */
264 putlog(LOG_MISC, "*", _("Cycling logfile %s, over max-logsize (%d kilobytes)"), log->filename, size);
265 fclose(log->fp);
266
267 newfname = egg_mprintf("%s.yesterday", log->filename);
268 unlink(newfname);
269 movefile(log->filename, newfname);
270 free(newfname);
271 }
272 }
273
274 static void flushlog(log_t *log, char *timestamp)
275 {
276 if (log->repeats) {
277 fprintf(log->fp, "%s", timestamp);
278 fprintf(log->fp, _("Last message repeated %d time(s).\n"), log->repeats);
279 log->repeats = 0;
280 realloc_strcpy(log->last_msg, "");
281 }
282 fflush(log->fp);
283 }
284
285 /* Flush the logfiles to disk
286 */
287 void flushlogs()
288 {
289 char timestamp[32];
290 log_t *log;
291
292 get_timestamp(timestamp);
293 for (log = log_list_head; log; log = log->next) {
294 flushlog(log, timestamp);
295 }
296 }

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23