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