10Sstevel@tonic-gate /*
2*1914Scasper * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
3*1914Scasper * Use is subject to license terms.
40Sstevel@tonic-gate */
50Sstevel@tonic-gate
60Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
70Sstevel@tonic-gate
80Sstevel@tonic-gate #include <stdio.h>
90Sstevel@tonic-gate #include <stdlib.h>
100Sstevel@tonic-gate #include <sys/types.h>
110Sstevel@tonic-gate #include <sys/stat.h>
120Sstevel@tonic-gate #include <nl_types.h>
130Sstevel@tonic-gate #include <limits.h>
140Sstevel@tonic-gate #include <stdarg.h>
150Sstevel@tonic-gate #include <string.h>
160Sstevel@tonic-gate
170Sstevel@tonic-gate #include <syslog.h>
180Sstevel@tonic-gate #include <portable.h>
190Sstevel@tonic-gate /* #include <lthread.h> */
200Sstevel@tonic-gate #include <pthread.h>
210Sstevel@tonic-gate #include <thread.h>
220Sstevel@tonic-gate
230Sstevel@tonic-gate #include "log.h"
240Sstevel@tonic-gate
250Sstevel@tonic-gate #define LDAP_DEBUG_ANY 0xffff
260Sstevel@tonic-gate
270Sstevel@tonic-gate static pthread_mutex_t log_mutex;
280Sstevel@tonic-gate static char logfile[PATH_MAX] =
290Sstevel@tonic-gate "/var/opt/SUNWconn/ldap/log/slapd.log";
300Sstevel@tonic-gate static int logsize = 512000;
310Sstevel@tonic-gate static int logtime = 1;
320Sstevel@tonic-gate static FILE *logfd = NULL;
330Sstevel@tonic-gate static int syslogopen = 0;
340Sstevel@tonic-gate pthread_mutex_t systime_mutex;
350Sstevel@tonic-gate nl_catd sundscat;
360Sstevel@tonic-gate static int log_debug = LDAP_DEBUG_STATS;
370Sstevel@tonic-gate
380Sstevel@tonic-gate typedef struct _logctx {
390Sstevel@tonic-gate char *logfile;
400Sstevel@tonic-gate int syslogopen;
410Sstevel@tonic-gate int logsize;
420Sstevel@tonic-gate pthread_mutex_t log_mutex;
430Sstevel@tonic-gate int log_debug;
440Sstevel@tonic-gate int log_syslog;
450Sstevel@tonic-gate
460Sstevel@tonic-gate } LogCtx;
470Sstevel@tonic-gate
480Sstevel@tonic-gate void
ldaplogconfig(char * logf,int size)490Sstevel@tonic-gate ldaplogconfig(char *logf, int size)
500Sstevel@tonic-gate {
510Sstevel@tonic-gate strcpy(logfile, logf);
520Sstevel@tonic-gate logsize = size * 1024;
530Sstevel@tonic-gate }
540Sstevel@tonic-gate
550Sstevel@tonic-gate void
ldaplogconfigf(FILE * fd)560Sstevel@tonic-gate ldaplogconfigf(FILE *fd)
570Sstevel@tonic-gate {
580Sstevel@tonic-gate logfd = fd;
590Sstevel@tonic-gate logsize = 0;
600Sstevel@tonic-gate }
610Sstevel@tonic-gate
620Sstevel@tonic-gate void
ldaploginit(char * name,int facility)630Sstevel@tonic-gate ldaploginit(char *name, int facility)
640Sstevel@tonic-gate {
650Sstevel@tonic-gate openlog(name, OPENLOG_OPTIONS, facility);
660Sstevel@tonic-gate syslogopen = 1;
670Sstevel@tonic-gate pthread_mutex_init(&log_mutex, NULL);
680Sstevel@tonic-gate }
690Sstevel@tonic-gate
700Sstevel@tonic-gate void
ldaploginitlevel(char * name,int facility,int level)710Sstevel@tonic-gate ldaploginitlevel(char *name, int facility, int level)
720Sstevel@tonic-gate {
730Sstevel@tonic-gate ldaploginit(name, facility);
740Sstevel@tonic-gate log_debug = level;
750Sstevel@tonic-gate }
760Sstevel@tonic-gate
770Sstevel@tonic-gate LogCtx *
sundsloginit(char * name,int facility,int debug_level,int syslog_level)780Sstevel@tonic-gate sundsloginit(char *name, int facility, int debug_level, int syslog_level)
790Sstevel@tonic-gate {
800Sstevel@tonic-gate LogCtx *returnCtx = NULL;
810Sstevel@tonic-gate
820Sstevel@tonic-gate if ((returnCtx = (LogCtx *)malloc(sizeof (LogCtx))) == NULL)
830Sstevel@tonic-gate return (NULL);
840Sstevel@tonic-gate if ((returnCtx->logfile = strdup(name)) == NULL) {
850Sstevel@tonic-gate free(returnCtx);
860Sstevel@tonic-gate return (NULL);
870Sstevel@tonic-gate }
880Sstevel@tonic-gate openlog(returnCtx->logfile, OPENLOG_OPTIONS, facility);
890Sstevel@tonic-gate returnCtx->syslogopen = 1;
900Sstevel@tonic-gate pthread_mutex_init(&(returnCtx->log_mutex), NULL);
910Sstevel@tonic-gate returnCtx->log_debug = debug_level;
920Sstevel@tonic-gate returnCtx->log_syslog = syslog_level;
930Sstevel@tonic-gate return (returnCtx);
940Sstevel@tonic-gate }
950Sstevel@tonic-gate
960Sstevel@tonic-gate static char timestr[128];
970Sstevel@tonic-gate static time_t timelast = 0;
980Sstevel@tonic-gate
990Sstevel@tonic-gate /*VARARGS*/
1000Sstevel@tonic-gate void
ldaplog(int level,char * fmt,...)1010Sstevel@tonic-gate ldaplog(int level, char *fmt, ...)
1020Sstevel@tonic-gate {
1030Sstevel@tonic-gate va_list ap;
1040Sstevel@tonic-gate struct stat statbuf = {0};
1050Sstevel@tonic-gate char newlog1[PATH_MAX];
1060Sstevel@tonic-gate char newlog2[PATH_MAX];
1070Sstevel@tonic-gate time_t now;
1080Sstevel@tonic-gate int i;
1090Sstevel@tonic-gate
1100Sstevel@tonic-gate if (!(log_debug & level))
1110Sstevel@tonic-gate return;
1120Sstevel@tonic-gate
1130Sstevel@tonic-gate va_start(ap, fmt);
1140Sstevel@tonic-gate
1150Sstevel@tonic-gate if (level == LDAP_DEBUG_ANY) {
1160Sstevel@tonic-gate /*
1170Sstevel@tonic-gate * this message is probably an error message, send it to syslog
1180Sstevel@tonic-gate */
1190Sstevel@tonic-gate if (syslogopen) {
1200Sstevel@tonic-gate vsyslog(LOG_ERR, fmt, ap);
1210Sstevel@tonic-gate } /* end if */
1220Sstevel@tonic-gate /* and sent it also on stderr */
1230Sstevel@tonic-gate vfprintf(stderr, fmt, ap);
1240Sstevel@tonic-gate } /* end if */
1250Sstevel@tonic-gate
1260Sstevel@tonic-gate /*
1270Sstevel@tonic-gate * check that the log file is not already too big
1280Sstevel@tonic-gate */
1290Sstevel@tonic-gate pthread_mutex_lock(&log_mutex);
1300Sstevel@tonic-gate if ((logsize > 0) && (stat(logfile, &statbuf) == 0 &&
1310Sstevel@tonic-gate statbuf.st_size > logsize)) {
1320Sstevel@tonic-gate for (i = 9; i > 1; i--) {
1330Sstevel@tonic-gate (void) sprintf(newlog1, "%s.%d", logfile, i-1);
1340Sstevel@tonic-gate (void) sprintf(newlog2, "%s.%d", logfile, i);
1350Sstevel@tonic-gate (void) rename(newlog1, newlog2);
1360Sstevel@tonic-gate } /* end for */
1370Sstevel@tonic-gate if (logfd) {
1380Sstevel@tonic-gate fclose(logfd);
1390Sstevel@tonic-gate logfd = NULL;
1400Sstevel@tonic-gate } /* end if */
1410Sstevel@tonic-gate (void) rename(logfile, newlog1);
1420Sstevel@tonic-gate } /* end if */
1430Sstevel@tonic-gate /*
1440Sstevel@tonic-gate * send the message into a regular log file
1450Sstevel@tonic-gate */
1460Sstevel@tonic-gate if (!logfd) {
147*1914Scasper logfd = fopen(logfile, "aF");
1480Sstevel@tonic-gate } /* end if */
1490Sstevel@tonic-gate /*
1500Sstevel@tonic-gate * finally write the message into the log file
1510Sstevel@tonic-gate */
1520Sstevel@tonic-gate if (logfd) {
1530Sstevel@tonic-gate if (logtime) {
1540Sstevel@tonic-gate time(&now);
1550Sstevel@tonic-gate if (now-timelast > 60) {
1560Sstevel@tonic-gate pthread_mutex_lock(&systime_mutex);
1570Sstevel@tonic-gate timelast = now;
1580Sstevel@tonic-gate ctime_r(&now, timestr, 128);
1590Sstevel@tonic-gate pthread_mutex_unlock(&systime_mutex);
1600Sstevel@tonic-gate } /* end if */
1610Sstevel@tonic-gate fprintf(logfd, "%.16s : ", timestr);
1620Sstevel@tonic-gate } /* end if */
1630Sstevel@tonic-gate vfprintf(logfd, fmt, ap);
1640Sstevel@tonic-gate fflush(logfd);
1650Sstevel@tonic-gate } /* end if */
1660Sstevel@tonic-gate pthread_mutex_unlock(&log_mutex);
1670Sstevel@tonic-gate va_end(ap);
1680Sstevel@tonic-gate }
169