/[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.33 - (show annotations) (download) (as text)
Fri Jun 13 03:35:15 2003 UTC (16 years, 5 months ago) by stdarg
Branch: MAIN
Changes since 1.32: +3 -3 lines
File MIME type: text/x-chdr
* Added 'flags' param back to bind
* Partyline fixes/expansion
* Scripts can use 'bind' before the correct module is loaded

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23