xref: /illumos-gate/usr/src/lib/libldap5/sources/ldap/util/log.c (revision d85c7355a624618ba1de7b63e2a8824a763959f1)
1  /*
2   * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
3   * Use is subject to license terms.
4   */
5  
6  #pragma ident	"%Z%%M%	%I%	%E% SMI"
7  
8  #include <stdio.h>
9  #include <stdlib.h>
10  #include <sys/types.h>
11  #include <sys/stat.h>
12  #include <nl_types.h>
13  #include <limits.h>
14  #include <stdarg.h>
15  #include <string.h>
16  
17  #include <syslog.h>
18  #include <portable.h>
19  /* #include <lthread.h> */
20  #include <pthread.h>
21  #include <thread.h>
22  
23  #include "log.h"
24  
25  #define	LDAP_DEBUG_ANY	0xffff
26  
27  static pthread_mutex_t	log_mutex;
28  static char		logfile[PATH_MAX] =
29  					"/var/opt/SUNWconn/ldap/log/slapd.log";
30  static int		logsize = 512000;
31  static int		logtime = 1;
32  static FILE		*logfd = NULL;
33  static int		syslogopen = 0;
34  pthread_mutex_t		systime_mutex;
35  nl_catd			sundscat;
36  static int		log_debug = LDAP_DEBUG_STATS;
37  
38  typedef struct _logctx {
39  	char		*logfile;
40  	int		syslogopen;
41  	int		logsize;
42  	pthread_mutex_t	log_mutex;
43  	int		log_debug;
44  	int		log_syslog;
45  
46  } LogCtx;
47  
48  void
49  ldaplogconfig(char *logf, int size)
50  {
51  	strcpy(logfile, logf);
52  	logsize = size * 1024;
53  }
54  
55  void
56  ldaplogconfigf(FILE *fd)
57  {
58  	logfd = fd;
59  	logsize = 0;
60  }
61  
62  void
63  ldaploginit(char *name, int facility)
64  {
65  	openlog(name, OPENLOG_OPTIONS, facility);
66  	syslogopen = 1;
67  	pthread_mutex_init(&log_mutex, NULL);
68  }
69  
70  void
71  ldaploginitlevel(char *name, int facility, int level)
72  {
73  	ldaploginit(name, facility);
74  	log_debug = level;
75  }
76  
77  LogCtx *
78  sundsloginit(char *name, int facility, int debug_level, int syslog_level)
79  {
80  	LogCtx *returnCtx = NULL;
81  
82  	if ((returnCtx = (LogCtx *)malloc(sizeof (LogCtx))) == NULL)
83  		return (NULL);
84  	if ((returnCtx->logfile = strdup(name)) == NULL) {
85  		free(returnCtx);
86  		return (NULL);
87  	}
88  	openlog(returnCtx->logfile, OPENLOG_OPTIONS, facility);
89  	returnCtx->syslogopen = 1;
90  	pthread_mutex_init(&(returnCtx->log_mutex), NULL);
91  	returnCtx->log_debug = debug_level;
92  	returnCtx->log_syslog = syslog_level;
93  	return (returnCtx);
94  }
95  
96  static char timestr[128];
97  static time_t timelast = 0;
98  
99  /*VARARGS*/
100  void
101  ldaplog(int level, char *fmt, ...)
102  {
103  	va_list ap;
104  	struct stat statbuf = {0};
105  	char newlog1[PATH_MAX];
106  	char newlog2[PATH_MAX];
107  	time_t now;
108  	int i;
109  
110  	if (!(log_debug & level))
111  		return;
112  
113  	va_start(ap, fmt);
114  
115  	if (level == LDAP_DEBUG_ANY) {
116  		/*
117  		 * this message is probably an error message, send it to syslog
118  		 */
119  		if (syslogopen) {
120  			vsyslog(LOG_ERR, fmt, ap);
121  		} /* end if */
122  		/* and sent it also on stderr */
123  		vfprintf(stderr, fmt, ap);
124  	} /* end if */
125  
126  	/*
127  	 * check that the log file is not already too big
128  	 */
129  	pthread_mutex_lock(&log_mutex);
130  	if ((logsize > 0) && (stat(logfile, &statbuf) == 0 &&
131  					statbuf.st_size > logsize)) {
132  		for (i = 9; i > 1; i--) {
133  			(void) sprintf(newlog1, "%s.%d", logfile, i-1);
134  			(void) sprintf(newlog2, "%s.%d", logfile, i);
135  			(void) rename(newlog1, newlog2);
136  		} /* end for */
137  		if (logfd) {
138  			fclose(logfd);
139  			logfd = NULL;
140  		} /* end if */
141  		(void) rename(logfile, newlog1);
142  	} /* end if */
143  	/*
144  	 * send the message into a regular log file
145  	 */
146  	if (!logfd) {
147  		logfd = fopen(logfile, "aF");
148  	} /* end if */
149  	/*
150  	 * finally write the message into the log file
151  	 */
152  	if (logfd) {
153  		if (logtime) {
154  			time(&now);
155  			if (now-timelast > 60) {
156  				pthread_mutex_lock(&systime_mutex);
157  				timelast = now;
158  				ctime_r(&now, timestr, 128);
159  				pthread_mutex_unlock(&systime_mutex);
160  			} /* end if */
161  			fprintf(logfd, "%.16s : ", timestr);
162  		} /* end if */
163  		vfprintf(logfd, fmt, ap);
164  		fflush(logfd);
165  	} /* end if */
166  	pthread_mutex_unlock(&log_mutex);
167  	va_end(ap);
168  }
169