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
ldaplogconfig(char * logf,int size)49 ldaplogconfig(char *logf, int size)
50 {
51 	strcpy(logfile, logf);
52 	logsize = size * 1024;
53 }
54 
55 void
ldaplogconfigf(FILE * fd)56 ldaplogconfigf(FILE *fd)
57 {
58 	logfd = fd;
59 	logsize = 0;
60 }
61 
62 void
ldaploginit(char * name,int facility)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
ldaploginitlevel(char * name,int facility,int level)71 ldaploginitlevel(char *name, int facility, int level)
72 {
73 	ldaploginit(name, facility);
74 	log_debug = level;
75 }
76 
77 LogCtx *
sundsloginit(char * name,int facility,int debug_level,int syslog_level)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
ldaplog(int level,char * fmt,...)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