/* * Copyright 2000, International Business Machines Corporation and others. * All Rights Reserved. * * This software has been released under the terms of the IBM Public * License. For details, see the LICENSE file in the top-level source * directory or online at http://www.openafs.org/dl/license10.html */ /* serverLog.c - Server logging */ /* */ /* Information Technology Center */ /* Date: 05/21/97 */ /* */ /* Function - These routiens implement logging from the servers */ /* */ /* ********************************************************************** */ #include #include RCSID ("$Header$"); #include #ifdef AFS_NT40_ENV #include #include #else #ifdef AFS_AIX_ENV #include #endif #include #include #include #endif #include /* signal(), kill(), wait(), etc. */ #include #include #ifdef HAVE_STRING_H #include #else #ifdef HAVE_STRINGS_H #include #endif #endif #include "afsutil.h" #include "fileutil.h" #if defined(AFS_PTHREAD_ENV) #include #include static pthread_mutex_t serverLogMutex; #define LOCK_SERVERLOG() assert(pthread_mutex_lock(&serverLogMutex)==0) #define UNLOCK_SERVERLOG() assert(pthread_mutex_unlock(&serverLogMutex)==0) #ifdef AFS_NT40_ENV #define NULLDEV "NUL" #else #define NULLDEV "/dev/null" #endif #else /* AFS_PTHREAD_ENV */ #define LOCK_SERVERLOG() #define UNLOCK_SERVERLOG() #endif /* AFS_PTHREAD_ENV */ #ifdef AFS_NT40_ENV #define F_OK 0 #endif char *(*threadNameProgram) (); static int serverLogFD = -1; #ifndef AFS_NT40_ENV int serverLogSyslog = 0; int serverLogSyslogFacility = LOG_DAEMON; char *serverLogSyslogTag = 0; #endif #include int LogLevel; int mrafsStyleLogs = 0; int printLocks = 0; static char ourName[MAXPATHLEN]; void WriteLogBuffer(char *buf, afs_uint32 len) { LOCK_SERVERLOG(); if (serverLogFD > 0) (void)write(serverLogFD, buf, len); UNLOCK_SERVERLOG(); } void vFSLog(const char *format, va_list args) { time_t currenttime; char *timeStamp; char tbuffer[1024]; char *info; int len; char *name; currenttime = time(0); timeStamp = afs_ctime(¤ttime, tbuffer, sizeof(tbuffer)); timeStamp[24] = ' '; /* ts[24] is the newline, 25 is the null */ info = &timeStamp[25]; if (mrafsStyleLogs) { name = (*threadNameProgram) (); (void)afs_snprintf(info, (sizeof tbuffer) - strlen(tbuffer), "[%s] ", name); info += strlen(info); } (void)afs_vsnprintf(info, (sizeof tbuffer) - strlen(tbuffer), format, args); len = strlen(tbuffer); LOCK_SERVERLOG(); #ifndef AFS_NT40_ENV if (serverLogSyslog) { syslog(LOG_INFO, "%s", info); } else #endif if (serverLogFD > 0) (void)write(serverLogFD, tbuffer, len); UNLOCK_SERVERLOG(); #if !defined(AFS_PTHREAD_ENV) && !defined(AFS_NT40_ENV) if (!serverLogSyslog) { fflush(stdout); fflush(stderr); /* in case they're sharing the same FD */ } #endif } /*vFSLog */ /* VARARGS1 */ /*@printflike@*/ void FSLog(const char *format, ...) { va_list args; va_start(args, format); vFSLog(format, args); va_end(args); } /*FSLog */ static int DebugOn(int loglevel) { if (loglevel == 0) { ViceLog(0, ("Reset Debug levels to 0\n")); } else { ViceLog(0, ("Set Debug On level = %d\n", loglevel)); } return 0; } /*DebugOn */ void SetDebug_Signal(int signo) { /* extern int IOMGR_SoftSig();*/ if (LogLevel > 0) { LogLevel *= 5; } else { LogLevel = 1; } printLocks = 2; #if defined(AFS_PTHREAD_ENV) DebugOn(LogLevel); #else /* AFS_PTHREAD_ENV */ IOMGR_SoftSig(DebugOn, LogLevel); #endif /* AFS_PTHREAD_ENV */ (void)signal(signo, SetDebug_Signal); /* on some platforms, this * signal handler needs to * be set again */ } /*SetDebug_Signal */ void ResetDebug_Signal(int signo) { LogLevel = 0; if (printLocks > 0) --printLocks; #if defined(AFS_PTHREAD_ENV) DebugOn(LogLevel); #else /* AFS_PTHREAD_ENV */ IOMGR_SoftSig(DebugOn, (void *)LogLevel); #endif /* AFS_PTHREAD_ENV */ (void)signal(signo, ResetDebug_Signal); /* on some platforms, * this signal handler * needs to be set * again */ if (mrafsStyleLogs) OpenLog((char *)&ourName); } /*ResetDebug_Signal */ void SetupLogSignals(void) { (void)signal(SIGHUP, ResetDebug_Signal); /* Note that we cannot use SIGUSR1 -- Linux stole it for pthreads! */ (void)signal(SIGTSTP, SetDebug_Signal); } int OpenLog(const char *fileName) { /* * This function should allow various libraries that inconsistently * use stdout/stderr to all go to the same place */ int tempfd; char oldName[MAXPATHLEN]; struct timeval Start; struct tm *TimeFields; char FileName[MAXPATHLEN]; #ifndef AFS_NT40_ENV if (serverLogSyslog) { openlog(serverLogSyslogTag, LOG_PID, serverLogSyslogFacility); return (0); } #endif if (mrafsStyleLogs) { time_t t = Start.tv_sec; TM_GetTimeOfDay(&Start, 0); TimeFields = localtime(&t); if (fileName) { if (strncmp(fileName, (char *)&ourName, strlen(fileName))) strcpy((char *)&ourName, (char *)fileName); } afs_snprintf(FileName, MAXPATHLEN, "%s.%d%02d%02d%02d%02d%02d", ourName, TimeFields->tm_year + 1900, TimeFields->tm_mon + 1, TimeFields->tm_mday, TimeFields->tm_hour, TimeFields->tm_min, TimeFields->tm_sec); rename(fileName, FileName); /* don't check error code */ tempfd = open(fileName, O_WRONLY | O_TRUNC | O_CREAT, 0666); } else { strcpy(oldName, fileName); strcat(oldName, ".old"); /* don't check error */ renamefile(fileName, oldName); tempfd = open(fileName, O_WRONLY | O_TRUNC | O_CREAT, 0666); } if (tempfd < 0) { printf("Unable to open log file %s\n", fileName); return -1; } #if defined(AFS_PTHREAD_ENV) /* redirect stdout and stderr so random printf's don't write to data */ assert(freopen(NULLDEV, "w", stdout) != NULL); assert(freopen(NULLDEV, "w", stderr) != NULL); assert(pthread_mutex_init(&serverLogMutex, NULL) == 0); serverLogFD = tempfd; #else close(tempfd); /* just checking.... */ (void)freopen(fileName, "w", stdout); (void)freopen(fileName, "w", stderr); serverLogFD = fileno(stdout); #endif /* AFS_PTHREAD_ENV */ return 0; } /*OpenLog */ int ReOpenLog(const char *fileName) { #if !defined(AFS_PTHREAD_ENV) int tempfd; #endif if (access(fileName, F_OK) == 0) return 0; /* exists, no need to reopen. */ #if !defined(AFS_NT40_ENV) if (serverLogSyslog) { return 0; } #endif #if defined(AFS_PTHREAD_ENV) LOCK_SERVERLOG(); if (serverLogFD > 0) close(serverLogFD); serverLogFD = open(fileName, O_WRONLY | O_APPEND | O_CREAT, 0666); UNLOCK_SERVERLOG(); return serverLogFD < 0 ? -1 : 0; #else tempfd = open(fileName, O_WRONLY | O_APPEND | O_CREAT, 0666); if (tempfd < 0) { printf("Unable to open log file %s\n", fileName); return -1; } close(tempfd); (void)freopen(fileName, "a", stdout); (void)freopen(fileName, "a", stderr); serverLogFD = fileno(stdout); return 0; #endif /* AFS_PTHREAD_ENV */ }