]>
jfr.im git - irc/quakenet/newserv.git/blob - nterfacer/logging.c
2 nterface logging functions
3 Copyright (C) 2003-2004 Chris Porter.
6 - wrote own stat function as linux sucks
7 - modified permissions to allow paul to read the log files.
9 - modified debug newserv level
11 - merged logging and stdout stuff
14 - added new logging to file feature
28 #include "../core/error.h"
29 #include "../lib/sstring.h"
30 #include "../core/schedule.h"
35 #define LOG_PERMISSIONS S_IRUSR | S_IWUSR | S_IRGRP
36 #define DIR_PERMISSIONS LOG_PERMISSIONS | S_IXUSR | S_IXGRP
38 void sanitise ( char * buf
) {
45 /* 1 if exists, 0 if it doesn't */
46 /* linux sucks so we can't use stat */
47 int exists ( char * filename
) {
48 FILE * fp
= fopen ( filename
, "r" );
56 int ifexistrename ( char * from
, char * to
) {
60 return rename ( from
, to
);
64 void nterface_rotate_log ( void * arg
) {
65 struct nterface_auto_log
* us
= ( struct nterface_auto_log
*) arg
;
66 char * filename
, * filename2
, * swap
;
67 int filenamelen
= strlen ( us
-> filename
-> content
) + 15 , i
, aborted
= 0 ;
73 filename
= ntmalloc ( filenamelen
);
75 filename2
= ntmalloc ( filenamelen
);
82 /* ADD us->log checks, if rotation failed */
84 snprintf ( filename
, filenamelen
, " %s .n" , us
-> filename
-> content
);
86 newlog
= fopen ( filename
, "w" );
88 nterface_log ( us
, NL_WARNING
, "Unable to rotate log %s : %s " , us
-> filename
-> content
, strerror ( errno
));
90 snprintf ( filename
, filenamelen
, " %s . %d " , us
-> filename
-> content
, ROTATE_LOG_TIMES
);
91 for ( i
= ROTATE_LOG_TIMES
- 1 ; i
>= 0 ; i
--) {
92 snprintf ( filename2
, filenamelen
, " %s . %d " , us
-> filename
-> content
, i
);
93 if ( ifexistrename ( filename2
, filename
))
100 nterface_log ( us
, NL_WARNING
, "Error occured during log rotation (rename %s to %s ), log files will have a gap: %s " , filename2
, filename
, strerror ( errno
));
103 if ( ifexistrename ( us
-> filename
-> content
, filename
)) {
104 nterface_log ( us
, NL_WARNING
, "Error occured during log rotation (rename %s to %s ), log files will have a gap (.0 will be missing): %s " , us
-> filename
-> content
, filename
, strerror ( errno
));
107 snprintf ( filename
, filenamelen
, " %s .n" , us
-> filename
-> content
);
108 if ( ifexistrename ( filename
, us
-> filename
-> content
)) {
109 nterface_log ( us
, NL_WARNING
, "Error occured during log rotation (rename %s to %s ): %s " , filename
, us
-> filename
-> content
, strerror ( errno
));
110 snprintf ( filename
, filenamelen
, " %s .0" , us
-> filename
-> content
);
111 if ( ifexistrename ( filename
, us
-> filename
-> content
))
112 nterface_log ( us
, NL_WARNING
, "Error occured during log rotation (rename %s to %s ), now logging to: %s as rename back failed: %s " , filename
, us
-> filename
-> content
, filename
, strerror ( errno
));
115 nterface_log ( us
, NL_SYSTEM
, "Log rotated out of use" );
118 nterface_log ( us
, NL_SYSTEM
, "Log rotated into use" );
119 nterface_log ( us
, NL_INFO
| NL_DONT_LOG
, "Log rotated" );
127 snprintf ( filename
, filenamelen
, " %s .n" , us
-> filename
-> content
);
135 int direxists ( char * filename
) {
136 char * p
= filename
, * lastp
= NULL
;
143 char * newp
= ntmalloc ( lastp
- filename
+ 1 );
149 memcpy ( newp
, filename
, lastp
- filename
);
150 newp
[ lastp
- filename
] = '\0' ;
153 chmod ( newp
, DIR_PERMISSIONS
);
155 ret
= mkdir ( newp
, DIR_PERMISSIONS
);
165 struct nterface_auto_log
* nterface_open_log ( char * name
, char * filename
, int debug
) {
166 struct nterface_auto_log
* us
= ntmalloc ( sizeof ( struct nterface_auto_log
));
169 us
-> filename
= getsstring ( filename
, strlen ( filename
));
175 us
-> name
= getsstring ( name
, strlen ( name
));
178 freesstring ( us
-> filename
);
182 if ( direxists ( filename
)) {
183 us
-> log
= fopen ( filename
, "a" );
185 Error ( name
, ERR_INFO
, "Unable to open log %s : %s " , filename
, strerror ( errno
));
187 Error ( name
, ERR_INFO
, "Unable to open log %s , as directory does not exist and couldn't be created: %s " , filename
, strerror ( errno
));
192 nterface_log ( us
, NL_SYSTEM
, "Log opened" );
194 chmod ( filename
, LOG_PERMISSIONS
);
196 us
-> schedule
= schedulerecurring (( time ( NULL
)/ ROTATE_LOG_EVERY
+ 1 ) * ROTATE_LOG_EVERY
, 0 , ROTATE_LOG_EVERY
, nterface_rotate_log
, us
);
198 nterface_log ( us
, NL_WARNING
, "Unable to schedule log rotation!" );
203 struct nterface_auto_log
* nterface_close_log ( struct nterface_auto_log
* ourlog
) {
206 deleteschedule ( ourlog
-> schedule
, nterface_rotate_log
, ourlog
);
207 freesstring ( ourlog
-> name
);
208 freesstring ( ourlog
-> filename
);
209 nterface_log ( ourlog
, NL_SYSTEM
, "Log closed" );
217 void nterface_log ( struct nterface_auto_log
* ourlog
, int loglevel
, char * format
, ...) {
218 char buf
[ MAX_BUFSIZE
* 2 ], timebuf
[ 100 ], loglevelname
= '\0' ; /* lazy */
219 int newserverrorcode
= - 1 ;
224 if ( loglevel
& NL_INFO
) {
226 newserverrorcode
= ERR_INFO
;
227 } else if ( loglevel
& NL_DEBUG
) {
228 if (! ourlog
|| ourlog
-> debug
) {
230 newserverrorcode
= ERR_INFO
; /* debug only shows up if debug newserv is enabled */
232 } else if ( loglevel
& NL_WARNING
) {
234 newserverrorcode
= ERR_WARNING
;
235 } else if ( loglevel
& NL_ERROR
) {
237 newserverrorcode
= ERR_ERROR
;
238 } else if ( loglevel
& NL_SYSTEM
) {
242 if ( loglevel
& NL_LOG_ONLY
)
243 newserverrorcode
= - 1 ;
248 va_start ( va
, format
);
249 vsnprintf ( buf
, sizeof ( buf
), format
, va
);
252 if ( newserverrorcode
!= - 1 )
253 Error ( ourlog
? ourlog
-> name
-> content
: "nterface-unknown" , newserverrorcode
, " %s " , buf
);
257 if (! ourlog
|| ! ourlog
-> log
|| ( loglevel
& NL_DONT_LOG
))
263 strftime ( timebuf
, sizeof ( timebuf
), " %Y - %m - %d %H : %M : %S " , tm
);
264 fprintf ( ourlog
-> log
, "[ %s ] %c : %s \n " , timebuf
, loglevelname
, buf
);