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