/[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.31 - (show annotations) (download) (as text)
Tue Apr 15 08:18:03 2003 UTC (16 years, 6 months ago) by stdarg
Branch: MAIN
Changes since 1.30: +8 -4 lines
File MIME type: text/x-chdr
* Start of new module interface
* Global function table is gone

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23