38
36
/* set the logname */
40
38
#define PACKAGE "nslcd"
43
/* storage for logging modes */
44
static struct cvsd_log {
45
FILE *fp; /* NULL==syslog */
47
struct cvsd_log *next;
51
40
/* default loglevel when no logging is configured */
52
41
static int prelogging_loglevel=LOG_INFO;
43
/* loglevel to use before logging to syslog */
44
static int loglevel=LOG_INFO;
55
46
/* the session id that is set for this thread */
56
47
static __thread char *sessionid=NULL;
49
/* the request identifier that is set for this thread */
50
static __thread char *requestid=NULL;
51
#define MAX_REQUESTID_LENGTH 40
59
53
/* 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);
54
void log_setdefaultloglevel(int pri)
56
prelogging_loglevel=pri;
122
59
/* start the logging with the configured logging methods
123
60
if no method is configured yet, logging is done to syslog */
124
61
void log_startlogging(void)
126
if (cvsd_loglist==NULL)
127
log_addlogging_syslog(LOG_INFO);
63
openlog(PACKAGE,LOG_PID,LOG_DAEMON);
128
64
prelogging_loglevel=-1;
67
/* indicate that we should clear any session identifiers set by
69
void log_clearsession(void)
71
/* set the session id to empty */
74
/* set the request id to empty */
132
79
/* indicate that a session id should be included in the output
133
80
and set it to a new value */
146
93
sprintf(sessionid,"%06x",(int)(rand()&0xffffff));
94
/* set the request id to empty */
99
/* indicate that a request identifier should be included in the output
100
from this point on, until log_newsession() is called */
101
void log_setrequest(const char *format, ...)
104
/* ensure that requestid can hold a string */
107
requestid=(char *)malloc(MAX_REQUESTID_LENGTH);
110
fprintf(stderr,"malloc() failed: %s",strerror(errno));
111
return; /* silently fail */
114
/* make the message */
116
vsnprintf(requestid,MAX_REQUESTID_LENGTH,format,ap);
117
requestid[MAX_REQUESTID_LENGTH-1]='\0';
150
121
/* log the given message using the configured logging method */
151
122
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
127
/* make the message */
160
128
va_start(ap,format);
161
res=vsnprintf(buffer,maxbufferlen,format,ap);
162
if ((res<0)||(res>=maxbufferlen))
129
res=vsnprintf(buffer,sizeof(buffer),format,ap);
130
if ((res<0)||(res>=(int)sizeof(buffer)))
164
132
/* truncate with "..." */
165
buffer[maxbufferlen-2]='.';
166
buffer[maxbufferlen-3]='.';
167
buffer[maxbufferlen-4]='.';
133
buffer[sizeof(buffer)-2]='.';
134
buffer[sizeof(buffer)-3]='.';
135
buffer[sizeof(buffer)-4]='.';
169
buffer[maxbufferlen-1]='\0';
137
buffer[sizeof(buffer)-1]='\0';
171
139
/* do the logging */
172
140
if (prelogging_loglevel>=0)
174
142
/* if logging is not yet defined, log to stderr */
175
143
if (pri<=prelogging_loglevel)
145
if ((requestid!=NULL)&&(requestid[0]!='\0'))
146
fprintf(stderr,"%s: [%s] <%s> %s%s\n",PACKAGE,sessionid,requestid,pri==LOG_DEBUG?"DEBUG: ":"",buffer);
147
else if ((sessionid!=NULL)&&(sessionid[0]!='\0'))
178
148
fprintf(stderr,"%s: [%s] %s%s\n",PACKAGE,sessionid,pri==LOG_DEBUG?"DEBUG: ":"",buffer);
180
150
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);
157
if ((requestid!=NULL)&&(requestid[0]!='\0'))
158
syslog(pri,"[%s] <%s> %s",sessionid,requestid,buffer);
159
else if ((sessionid!=NULL)&&(sessionid[0]!='\0'))
160
syslog(pri,"[%s] %s",sessionid,buffer);
162
syslog(pri,"%s",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 */