summaryrefslogtreecommitdiff
path: root/nslcd/log.c
diff options
context:
space:
mode:
authorArthur de Jong <arthur@arthurdejong.org>2006-12-21 19:55:55 +0000
committerArthur de Jong <arthur@arthurdejong.org>2006-12-21 19:55:55 +0000
commitfbc5ecfb8cf86d753b7c9a3b5b549a8f279666ab (patch)
tree5d008fb2963ef8a27da784ba851984f64678e6f0 /nslcd/log.c
parent8366a3eb4a9032ca43cae9fccaa536182dcece04 (diff)
rename server directory to nslcd
git-svn-id: http://arthurdejong.org/svn/nss-pam-ldapd/nss-ldapd@196 ef36b2f9-881f-0410-afb5-c4e39611909c
Diffstat (limited to 'nslcd/log.c')
-rw-r--r--nslcd/log.c187
1 files changed, 187 insertions, 0 deletions
diff --git a/nslcd/log.c b/nslcd/log.c
new file mode 100644
index 0000000..c7370cf
--- /dev/null
+++ b/nslcd/log.c
@@ -0,0 +1,187 @@
+/*
+ log.c - logging funtions
+
+ Copyright (C) 2002, 2003 Arthur de Jong
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ MA 02110-1301 USA
+*/
+
+
+#include "config.h"
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <string.h>
+
+#include "log.h"
+#include "xmalloc.h"
+
+
+/* set the logname */
+#undef PACKAGE
+#define PACKAGE "nslcd"
+
+
+/* storage for logging modes */
+static struct cvsd_log {
+ FILE *fp; /* NULL==syslog */
+ int loglevel;
+ struct cvsd_log *next;
+} *cvsd_loglist=NULL;
+
+
+/* default loglevel when no logging is configured */
+static int prelogging_loglevel=LOG_INFO;
+
+
+/* set loglevel when no logging is configured */
+void log_setdefaultloglevel(int loglevel)
+{
+ prelogging_loglevel=loglevel;
+}
+
+
+/* add logging method to configuration list */
+static void log_addlogging_fp(FILE *fp,int loglevel)
+{
+ struct cvsd_log *tmp,*lst;
+ /* create new logstruct */
+ tmp=(struct cvsd_log *)xmalloc(sizeof(struct cvsd_log));
+ tmp->fp=fp;
+ tmp->loglevel=loglevel;
+ tmp->next=NULL;
+ /* save the struct in the list */
+ if (cvsd_loglist==NULL)
+ cvsd_loglist=tmp;
+ else
+ {
+ for (lst=cvsd_loglist;lst->next!=NULL;lst=lst->next);
+ lst->next=tmp;
+ }
+}
+
+
+/* configure logging to a file */
+void log_addlogging_file(const char *filename,int loglevel)
+{
+ FILE *fp;
+ fp=fopen(filename,"a");
+ if (fp==NULL)
+ {
+ log_log(LOG_ERR,"cannot open logfile (%s) for appending: %s",filename,strerror(errno));
+ exit(1);
+ }
+ log_addlogging_fp(fp,loglevel);
+}
+
+
+/* configure logging to syslog */
+void log_addlogging_syslog(int loglevel)
+{
+ openlog(PACKAGE,LOG_PID,LOG_DAEMON);
+ log_addlogging_fp(NULL,loglevel);
+}
+
+
+/* configure a null logging mode (no logging) */
+void log_addlogging_none()
+{
+ /* this is a hack, but it's so easy */
+ log_addlogging_fp(NULL,LOG_EMERG);
+}
+
+
+/* start the logging with the configured logging methods
+ if no method is configured yet, logging is done to syslog */
+void log_startlogging(void)
+{
+ if (cvsd_loglist==NULL)
+ log_addlogging_syslog(LOG_INFO);
+ prelogging_loglevel=-1;
+}
+
+
+/* log the given message using the configured logging method */
+void log_log(int pri,const char *format, ...)
+{
+ int res;
+ struct cvsd_log *lst;
+ /* TODO: make this something better */
+ #define maxbufferlen 120
+ char buffer[maxbufferlen];
+ va_list ap;
+ /* make the message */
+ va_start(ap,format);
+ res=vsnprintf(buffer,maxbufferlen,format,ap);
+ if ((res<0)||(res>=maxbufferlen))
+ {
+ /* truncate with "..." */
+ buffer[maxbufferlen-2]='.';
+ buffer[maxbufferlen-3]='.';
+ buffer[maxbufferlen-4]='.';
+ }
+ buffer[maxbufferlen-1]='\0';
+ va_end(ap);
+ /* do the logging */
+ if (prelogging_loglevel>=0)
+ {
+ /* if logging is not yet defined, log to stderr */
+ if (pri<=prelogging_loglevel)
+ fprintf(stderr,"%s: %s%s\n",PACKAGE,pri==LOG_DEBUG?"DEBUG: ":"",buffer);
+ }
+ else
+ {
+ for (lst=cvsd_loglist;lst!=NULL;lst=lst->next)
+ {
+ if (pri<=lst->loglevel)
+ {
+ if (lst->fp==NULL) /* syslog */
+ syslog(pri,"%s",buffer);
+ else /* file */
+ {
+ fprintf(lst->fp,"%s: %s\n",PACKAGE,buffer);
+ fflush(lst->fp);
+ }
+ }
+ }
+ }
+}
+
+
+/* return the syslog loglevel represented by the string
+ return -1 on unknown */
+int log_getloglevel(const char *lvl)
+{
+ if ( strcmp(lvl,"crit")==0 )
+ return LOG_CRIT;
+ else if ( (strcmp(lvl,"error")==0) ||
+ (strcmp(lvl,"err")==0) )
+ return LOG_ERR;
+ else if ( strcmp(lvl,"warning")==0 )
+ return LOG_WARNING;
+ else if ( strcmp(lvl,"notice")==0 )
+ return LOG_NOTICE;
+ else if ( strcmp(lvl,"info")==0 )
+ return LOG_INFO;
+ else if ( strcmp(lvl,"debug")==0 )
+ return LOG_DEBUG;
+ else
+ return -1; /* unknown */
+}