/[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.41 - (show annotations) (download) (as text)
Thu Jun 17 13:32:44 2004 UTC (15 years, 4 months ago) by wingman
Branch: MAIN
Changes since 1.40: +4 -13 lines
File MIME type: text/x-chdr
* Added new TAG: DDC for "this feature is document". After we are sure
  that all source code variables/commands/functions/ are tagged with either
  DDD or DDC we'll remove them.

* Made module Makefile.am's more centralized by moving common stuff
  to acconfig/module.mk.

* Introducted new help system. It's now on per module basis and localized.
  Default language is "en_EN" else not otherwise specified. Beside the
  %b formattings of 1.6 it has all features of the 1.6 help system.

  It's also more intelligent since help files are automaticly bound to
  module load/unload events. You don't need to manually load module help
  files any more. (Though unloading not tested yet... 8-))

* Fixed some tweaks here and there.

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.40 2004/06/15 19:19:16 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 logfile_minutely()
84 {
85 struct tm *nowtm;
86 int miltime;
87
88 if (core_config.quick_logs) {
89 flushlogs();
90 check_logsizes();
91 }
92
93 nowtm = localtime(&now);
94 miltime = 100 * nowtm->tm_hour + nowtm->tm_min;
95
96 if (miltime == core_config.switch_logfiles_at) logfile_cycle();
97
98 return(0);
99 }
100
101 static int logfile_5minutely()
102 {
103 if (!core_config.quick_logs) {
104 flushlogs();
105 check_logsizes();
106 }
107 return(0);
108 }
109
110 static int logfile_cycle()
111 {
112 log_t *log, *prev;
113 char suffix[32];
114 char *newfname;
115
116 putlog(LOG_MISC, "*", _("Cycling logfiles..."));
117 flushlogs();
118
119 /* Determine suffix for cycled logfiles. */
120 if (core_config.keep_all_logs) {
121 strftime(suffix, 32, core_config.logfile_suffix, localtime(&now));
122 }
123
124 prev = NULL;
125 for (log = log_list_head; log; log = log->next) {
126 fclose(log->fp);
127
128 if (core_config.keep_all_logs) newfname = egg_mprintf("%s%s", log->filename, suffix);
129 else newfname = egg_mprintf("%s.yesterday", log->filename);
130
131 unlink(newfname);
132 movefile(log->filename, newfname);
133 free(newfname);
134
135 log->fp = fopen(log->filename, "a");
136 if (!log->fp) {
137 logfile_del(log->filename);
138 if (prev) log = prev;
139 else log = log_list_head;
140 }
141 else prev = log;
142 }
143 return(0);
144 }
145
146 char *logfile_add(char *modes, char *chan, char *fname)
147 {
148 FILE *fp;
149 log_t *log;
150
151 /* Get rid of any duplicates. */
152 logfile_del(fname);
153
154 /* Test the filename. */
155 fp = fopen(fname, "a");
156 if (!fp) return("");
157
158 log = (log_t *)calloc(1, sizeof(*log));
159 log->filename = strdup(fname);
160 log->chname = strdup(chan);
161 log->last_msg = strdup("");
162 log->mask = LOG_ALL;
163 log->fp = fp;
164
165 log->next = log_list_head;
166 log_list_head = log;
167
168 return(log->filename);
169 }
170
171 int logfile_del(char *filename)
172 {
173 log_t *log, *prev;
174 char timestamp[32];
175
176 prev = NULL;
177 for (log = log_list_head; log; log = log->next) {
178 if (!strcmp(log->filename, filename)) break;
179 prev = log;
180 }
181 if (!log) return(1);
182 if (prev) prev->next = log->next;
183 else log_list_head = log->next;
184 if (log->fp) {
185 timer_get_timestamp(timestamp, sizeof (timestamp));
186 flushlog(log, timestamp);
187 fclose(log->fp);
188 }
189 free(log->last_msg);
190 free(log->filename);
191 free(log);
192 return(0);
193 }
194
195 static int on_putlog(int flags, const char *chan, const char *text, int len)
196 {
197 log_t *log;
198 char timestamp[32];
199
200 timer_get_timestamp(timestamp, sizeof (timestamp));
201 for (log = log_list_head; log; log = log->next) {
202 /* If this log doesn't match, skip it. */
203 if (!(log->mask & flags)) continue;
204 if (chan[0] != '*' && log->chname[0] != '*' && irccmp(chan, log->chname)) continue;
205
206
207 /* If it's a repeat message, don't write it again. */
208 if (!strcasecmp(text, log->last_msg)) {
209 log->repeats++;
210 continue;
211 }
212
213 /* If there was a repeated message, write the count. */
214 if (log->repeats) {
215 fprintf(log->fp, "%s", timestamp);
216 fprintf(log->fp, _("Last message repeated %d time(s).\n"), log->repeats);
217 log->repeats = 0;
218 }
219
220 /* Save this msg to check for repeats next time. */
221 str_redup(&log->last_msg, text);
222
223 /* Now output to the file. */
224 fprintf(log->fp, "%s%s\n", timestamp, text);
225 }
226
227 if (!backgrd || use_stderr) {
228
229 if (partyline_terminal_mode) {
230 /* check if HQ is on console. If yes we disable
231 * output to stdout since otherwise everything would
232 * be printed out twice. */
233 if (!terminal_enabled) {
234 terminal_enabled = (
235 partymember_lookup_nick (PARTY_TERMINAL_NICK) != NULL);
236 }
237 if (terminal_enabled)
238 return 0;
239
240 }
241
242 fprintf (stdout, "%s%s\n", timestamp, text);
243 }
244
245 return(0);
246 }
247
248 static void check_logsizes()
249 {
250 int size;
251 char *newfname;
252 log_t *log;
253
254 if (core_config.keep_all_logs || core_config.max_logsize <= 0) return;
255
256 for (log = log_list_head; log; log = log->next) {
257 size = ftell(log->fp) / 1024; /* Size in kilobytes. */
258 if (size < core_config.max_logsize) continue;
259
260 /* It's too big. */
261 putlog(LOG_MISC, "*", _("Cycling logfile %s: over max-logsize (%d kilobytes)."), log->filename, size);
262 fclose(log->fp);
263
264 newfname = egg_mprintf("%s.yesterday", log->filename);
265 unlink(newfname);
266 movefile(log->filename, newfname);
267 free(newfname);
268 }
269 }
270
271 static void flushlog(log_t *log, char *timestamp)
272 {
273 if (log->repeats) {
274 fprintf(log->fp, "%s", timestamp);
275 fprintf(log->fp, _("Last message repeated %d time(s).\n"), log->repeats);
276 log->repeats = 0;
277 realloc_strcpy(log->last_msg, "");
278 }
279 fflush(log->fp);
280 }
281
282 /* Flush the logfiles to disk
283 */
284 void flushlogs()
285 {
286 char timestamp[32];
287 log_t *log;
288
289 timer_get_timestamp(timestamp, sizeof (timestamp));
290 for (log = log_list_head; log; log = log->next) {
291 flushlog(log, timestamp);
292 }
293 }

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23