1 /*
2 * Copyright (C) 2004 Nathan Lutchansky <lutchann@litech.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <unistd.h>
22 #include <stdarg.h>
23 #include <time.h>
24 #include <pthread.h>
25
26 #define LOG_BUFFER_SIZE 4096
27
28 static int spookpid, minlevel;
29 static const char *month[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
30 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
31 static char *rb_data;
32 static int rb_in, rb_out, rb_size;
33 static pthread_mutex_t log_mutex;
34
spook_log_init(int min)35 int spook_log_init( int min )
36 {
37 pthread_mutex_init( &log_mutex, NULL );
38 spookpid = getpid();
39 minlevel = min;
40 rb_in = 0;
41 rb_out = 0;
42 rb_size = LOG_BUFFER_SIZE;
43 rb_data = (char *)malloc( rb_size );
44 return 0;
45 }
46
spook_log(int level,char * fmt,...)47 void spook_log( int level, char *fmt, ... )
48 {
49 va_list ap;
50 char newfmt[512], line[1024];
51 struct tm tm;
52 time_t t;
53 int i, len, overwrite = 0;
54
55 va_start( ap, fmt );
56 if( level < minlevel )
57 {
58 va_end( ap );
59 return;
60 }
61 time( &t );
62 localtime_r( &t, &tm );
63 sprintf( newfmt, "%s %2d %02d:%02d:%02d spook[%d]: %s\n",
64 month[tm.tm_mon], tm.tm_mday,
65 tm.tm_hour, tm.tm_min, tm.tm_sec,
66 spookpid, fmt );
67 len = vsnprintf( line, sizeof( line ), newfmt, ap );
68 va_end( ap );
69 fputs( line, stderr );
70 pthread_mutex_lock( &log_mutex );
71 for( i = 0; i < len; ++i )
72 {
73 rb_data[rb_in++] = line[i];
74 if( rb_in == rb_size ) rb_in = 0;
75 if( rb_in == rb_out ) overwrite = 1;
76 }
77 if( overwrite )
78 {
79 rb_out = rb_in;
80 while( rb_data[rb_out] != '\n' )
81 if( ++rb_out == rb_size ) rb_out = 0;
82 if( ++rb_out == rb_size ) rb_out = 0;
83 }
84 pthread_mutex_unlock( &log_mutex );
85 }
86
send_log_buffer(int fd)87 void send_log_buffer( int fd )
88 {
89 pthread_mutex_lock( &log_mutex );
90 if( rb_in < rb_out )
91 {
92 write( fd, rb_data + rb_out, rb_size - rb_out );
93 write( fd, rb_data, rb_in );
94 } else if( rb_in > rb_out )
95 write( fd, rb_data + rb_out, rb_in - rb_out );
96 pthread_mutex_unlock( &log_mutex );
97 }
98