/[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.40 - (show annotations) (download) (as text)
Tue Jun 15 19:19:16 2004 UTC (15 years, 4 months ago) by wingman
Branch: MAIN
Changes since 1.39: +4 -4 lines
File MIME type: text/x-chdr
* Added 'DDD' tags to mark stuff for documentation. Example:

	# list of everything which needs to be documented
	grep -nR "DDD" eggdrop1.7/

	# list of all todos
	grep -nR "XXX" eggdrop1.7/

  I'm sure i've missed some binds/commands/vars so if anyone finds more
  - go ahead. After all current stuff is marked we'll (note, that includes
  YOU (whoever reads this! ;-)) begin with eliminating the DDD lines.

  The user who removes most of the DDD lines gets a cold beer ;-)

* Cleaned up and made xml api more consistent

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23