/[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.30 - (show annotations) (download) (as text)
Tue Feb 25 10:28:22 2003 UTC (16 years, 7 months ago) by stdarg
Branch: MAIN
Changes since 1.29: +4 -15 lines
File MIME type: text/x-chdr
* Cleanups

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23