]> jfr.im git - irc/quakenet/newserv.git/blob - core/error.c
SIGNONTRACKER: RENAME hook uses an array.
[irc/quakenet/newserv.git] / core / error.c
1 /* error.c */
2
3 #include <stdarg.h>
4 #include <time.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include "error.h"
8 #include "hooks.h"
9
10 FILE *logfile;
11
12 static corehandler *coreh, *coret;
13
14 char *sevtostring(int severity) {
15 switch(severity) {
16 case ERR_DEBUG:
17 return "debug";
18
19 case ERR_INFO:
20 return "info";
21
22 case ERR_WARNING:
23 return "warning";
24
25 case ERR_ERROR:
26 return "error";
27
28 case ERR_FATAL:
29 return "fatal error";
30
31 case ERR_STOP:
32 return "terminal error";
33
34 default:
35 return "unknown error";
36 }
37 }
38
39 void reopen_logfile(int hooknum, void *arg) {
40 if (logfile)
41 fclose(logfile);
42
43 logfile=fopen("logs/newserv.log","a");
44 }
45
46 void init_logfile() {
47 logfile=fopen("logs/newserv.log","a");
48 if (!logfile) {
49 fprintf(stderr,"Failed to open logfile...\n");
50 }
51 registerhook(HOOK_CORE_SIGUSR1, reopen_logfile);
52 }
53
54 void fini_logfile() {
55 if (logfile)
56 fclose(logfile);
57 deregisterhook(HOOK_CORE_SIGUSR1, reopen_logfile);
58 if (logfile)
59 fclose(logfile);
60 }
61
62 void Error(char *source, int severity, char *reason, ... ) {
63 char buf[512];
64 va_list va;
65 struct tm *tm;
66 time_t now;
67 char timebuf[100];
68 struct error_event evt;
69
70 va_start(va,reason);
71 vsnprintf(buf,512,reason,va);
72 va_end(va);
73
74 evt.severity=severity;
75 evt.message=buf;
76 evt.source=source;
77 triggerhook(HOOK_CORE_ERROR, &evt);
78
79 if (severity>ERR_DEBUG) {
80 now=time(NULL);
81 tm=gmtime(&now);
82 strftime(timebuf,100,"%Y-%m-%d %H:%M:%S",tm);
83 fprintf(stderr,"[%s] %s(%s): %s\n",timebuf,sevtostring(severity),source,buf);
84 fflush(stderr);
85
86 if (logfile) {
87 fprintf(logfile,"[%s] %s(%s): %s\n",timebuf,sevtostring(severity),source,buf);
88 fflush(logfile);
89 }
90 }
91
92 if (severity>=ERR_STOP) {
93 fprintf(stderr,"Terminal error occured, exiting...\n");
94 triggerhook(HOOK_CORE_STOPERROR, NULL);
95 exit(0);
96 }
97 }
98
99 void handlecore(void) {
100 corehandler *n;
101
102 /* no attempt is made to clean these up */
103 for(n=coreh;coreh;n=coreh->next)
104 (n->fn)(n->arg);
105 }
106
107 corehandler *registercorehandler(CoreHandlerFn fn, void *arg) {
108 corehandler *c = (corehandler *)malloc(sizeof(corehandler));
109 /* core if we can't allocate!! */
110
111 c->fn = fn;
112 c->arg = arg;
113 c->next = NULL;
114 c->prev = coret;
115 coret = c->prev;
116
117 if(!coreh)
118 coreh = c;
119
120 return c;
121 }
122
123 void deregistercorehandler(corehandler *c) {
124 if(!c->prev) {
125 coreh = c->next;
126 } else {
127 c->prev->next = c->next;
128 }
129
130 if(!c->next) {
131 coret = c->prev;
132 } else {
133 c->next->prev = c->prev;
134 }
135
136 free(c);
137 }
138