2
log.c - logging funtions
4
Copyright (C) 2002, 2003, 2008 Arthur de Jong
6
This library is free software; you can redistribute it and/or
7
modify it under the terms of the GNU Lesser General Public
8
License as published by the Free Software Foundation; either
9
version 2.1 of the License, or (at your option) any later version.
11
This library is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
Lesser General Public License for more details.
16
You should have received a copy of the GNU Lesser General Public
17
License along with this library; if not, write to the Free Software
18
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
27
#include <sys/types.h>
40
#define PACKAGE "nslcd"
43
/* storage for logging modes */
44
static struct cvsd_log {
45
FILE *fp; /* NULL==syslog */
47
struct cvsd_log *next;
51
/* default loglevel when no logging is configured */
52
static int prelogging_loglevel=LOG_INFO;
55
/* the session id that is set for this thread */
56
static __thread char *sessionid=NULL;
59
/* set loglevel when no logging is configured */
60
void log_setdefaultloglevel(int loglevel)
62
prelogging_loglevel=loglevel;
66
/* add logging method to configuration list */
67
static void log_addlogging_fp(FILE *fp,int loglevel)
69
struct cvsd_log *tmp,*lst;
70
/* create new logstruct */
71
tmp=(struct cvsd_log *)malloc(sizeof(struct cvsd_log));
74
fprintf(stderr,"malloc() failed: %s",strerror(errno));
75
/* since this is done during initialisation it's best to bail out */
79
tmp->loglevel=loglevel;
81
/* save the struct in the list */
82
if (cvsd_loglist==NULL)
86
for (lst=cvsd_loglist;lst->next!=NULL;lst=lst->next);
92
/* configure logging to a file */
93
void log_addlogging_file(const char *filename,int loglevel)
96
fp=fopen(filename,"a");
99
log_log(LOG_ERR,"cannot open logfile (%s) for appending: %s",filename,strerror(errno));
102
log_addlogging_fp(fp,loglevel);
106
/* configure logging to syslog */
107
void log_addlogging_syslog(int loglevel)
109
openlog(PACKAGE,LOG_PID,LOG_DAEMON);
110
log_addlogging_fp(NULL,loglevel);
114
/* configure a null logging mode (no logging) */
115
void log_addlogging_none()
117
/* this is a hack, but it's so easy */
118
log_addlogging_fp(NULL,LOG_EMERG);
122
/* start the logging with the configured logging methods
123
if no method is configured yet, logging is done to syslog */
124
void log_startlogging(void)
126
if (cvsd_loglist==NULL)
127
log_addlogging_syslog(LOG_INFO);
128
prelogging_loglevel=-1;
132
/* indicate that a session id should be included in the output
133
and set it to a new value */
134
void log_newsession(void)
136
/* ensure that sessionid can hold a string */
139
sessionid=(char *)malloc(7);
142
fprintf(stderr,"malloc() failed: %s",strerror(errno));
143
return; /* silently fail */
146
sprintf(sessionid,"%06x",(int)(rand()&0xffffff));
150
/* log the given message using the configured logging method */
151
void log_log(int pri,const char *format, ...)
154
struct cvsd_log *lst;
155
/* TODO: make this something better */
156
#define maxbufferlen 200
157
char buffer[maxbufferlen];
159
/* make the message */
161
res=vsnprintf(buffer,maxbufferlen,format,ap);
162
if ((res<0)||(res>=maxbufferlen))
164
/* truncate with "..." */
165
buffer[maxbufferlen-2]='.';
166
buffer[maxbufferlen-3]='.';
167
buffer[maxbufferlen-4]='.';
169
buffer[maxbufferlen-1]='\0';
172
if (prelogging_loglevel>=0)
174
/* if logging is not yet defined, log to stderr */
175
if (pri<=prelogging_loglevel)
178
fprintf(stderr,"%s: [%s] %s%s\n",PACKAGE,sessionid,pri==LOG_DEBUG?"DEBUG: ":"",buffer);
180
fprintf(stderr,"%s: %s%s\n",PACKAGE,pri==LOG_DEBUG?"DEBUG: ":"",buffer);
185
for (lst=cvsd_loglist;lst!=NULL;lst=lst->next)
187
if (pri<=lst->loglevel)
189
if (lst->fp==NULL) /* syslog */
192
syslog(pri,"[%s] %s",sessionid,buffer);
194
syslog(pri,"%s",buffer);
199
fprintf(lst->fp,"%s: [%s] %s\n",sessionid,PACKAGE,buffer);
201
fprintf(lst->fp,"%s: %s\n",PACKAGE,buffer);
210
/* return the syslog loglevel represented by the string
211
return -1 on unknown */
212
int log_getloglevel(const char *lvl)
214
if ( strcmp(lvl,"crit")==0 )
216
else if ( (strcmp(lvl,"error")==0) ||
217
(strcmp(lvl,"err")==0) )
219
else if ( strcmp(lvl,"warning")==0 )
221
else if ( strcmp(lvl,"notice")==0 )
223
else if ( strcmp(lvl,"info")==0 )
225
else if ( strcmp(lvl,"debug")==0 )
228
return -1; /* unknown */