log.c revision 9ace9065
105b261ecSmrg/* 205b261ecSmrg 305b261ecSmrgCopyright 1987, 1998 The Open Group 405b261ecSmrg 505b261ecSmrgPermission to use, copy, modify, distribute, and sell this software and its 605b261ecSmrgdocumentation for any purpose is hereby granted without fee, provided that 705b261ecSmrgthe above copyright notice appear in all copies and that both that 805b261ecSmrgcopyright notice and this permission notice appear in supporting 905b261ecSmrgdocumentation. 1005b261ecSmrg 1105b261ecSmrgThe above copyright notice and this permission notice shall be included 1205b261ecSmrgin all copies or substantial portions of the Software. 1305b261ecSmrg 1405b261ecSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 1505b261ecSmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 1605b261ecSmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 1705b261ecSmrgIN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR 1805b261ecSmrgOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 1905b261ecSmrgARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 2005b261ecSmrgOTHER DEALINGS IN THE SOFTWARE. 2105b261ecSmrg 2205b261ecSmrgExcept as contained in this notice, the name of The Open Group shall 2305b261ecSmrgnot be used in advertising or otherwise to promote the sale, use or 2405b261ecSmrgother dealings in this Software without prior written authorization 2505b261ecSmrgfrom The Open Group. 2605b261ecSmrg 2705b261ecSmrg 2805b261ecSmrgCopyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts, 2905b261ecSmrgCopyright 1994 Quarterdeck Office Systems. 3005b261ecSmrg 3105b261ecSmrg All Rights Reserved 3205b261ecSmrg 3305b261ecSmrgPermission to use, copy, modify, and distribute this software and its 3405b261ecSmrgdocumentation for any purpose and without fee is hereby granted, 3505b261ecSmrgprovided that the above copyright notice appear in all copies and that 3605b261ecSmrgboth that copyright notice and this permission notice appear in 3705b261ecSmrgsupporting documentation, and that the names of Digital and 3805b261ecSmrgQuarterdeck not be used in advertising or publicity pertaining to 3905b261ecSmrgdistribution of the software without specific, written prior 4005b261ecSmrgpermission. 4105b261ecSmrg 4205b261ecSmrgDIGITAL AND QUARTERDECK DISCLAIM ALL WARRANTIES WITH REGARD TO THIS 4305b261ecSmrgSOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 4405b261ecSmrgFITNESS, IN NO EVENT SHALL DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT 4505b261ecSmrgOR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS 4605b261ecSmrgOF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 4705b261ecSmrgOR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE 4805b261ecSmrgOR PERFORMANCE OF THIS SOFTWARE. 4905b261ecSmrg 5005b261ecSmrg*/ 5105b261ecSmrg 5205b261ecSmrg/* 5305b261ecSmrg * Copyright (c) 1997-2003 by The XFree86 Project, Inc. 5405b261ecSmrg * 5505b261ecSmrg * Permission is hereby granted, free of charge, to any person obtaining a 5605b261ecSmrg * copy of this software and associated documentation files (the "Software"), 5705b261ecSmrg * to deal in the Software without restriction, including without limitation 5805b261ecSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 5905b261ecSmrg * and/or sell copies of the Software, and to permit persons to whom the 6005b261ecSmrg * Software is furnished to do so, subject to the following conditions: 6105b261ecSmrg * 6205b261ecSmrg * The above copyright notice and this permission notice shall be included in 6305b261ecSmrg * all copies or substantial portions of the Software. 6405b261ecSmrg * 6505b261ecSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 6605b261ecSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 6705b261ecSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 6805b261ecSmrg * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 6905b261ecSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 7005b261ecSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 7105b261ecSmrg * OTHER DEALINGS IN THE SOFTWARE. 7205b261ecSmrg * 7305b261ecSmrg * Except as contained in this notice, the name of the copyright holder(s) 7405b261ecSmrg * and author(s) shall not be used in advertising or otherwise to promote 7505b261ecSmrg * the sale, use or other dealings in this Software without prior written 7605b261ecSmrg * authorization from the copyright holder(s) and author(s). 7705b261ecSmrg */ 7805b261ecSmrg 7905b261ecSmrg 8005b261ecSmrg#ifdef HAVE_DIX_CONFIG_H 8105b261ecSmrg#include <dix-config.h> 8205b261ecSmrg#endif 8305b261ecSmrg 8405b261ecSmrg#include <X11/Xos.h> 8505b261ecSmrg#include <stdio.h> 8605b261ecSmrg#include <time.h> 8705b261ecSmrg#include <sys/stat.h> 8805b261ecSmrg#include <stdarg.h> 8905b261ecSmrg#include <stdlib.h> /* for malloc() */ 9005b261ecSmrg#include <errno.h> 9105b261ecSmrg 9205b261ecSmrg#include "input.h" 9305b261ecSmrg#include "site.h" 9405b261ecSmrg#include "opaque.h" 9505b261ecSmrg 9605b261ecSmrg#ifdef WIN32 9705b261ecSmrg#include <process.h> 9805b261ecSmrg#define getpid(x) _getpid(x) 9905b261ecSmrg#endif 10005b261ecSmrg 1016747b715Smrg#ifdef XF86BIGFONT 1026747b715Smrg#include "xf86bigfontsrv.h" 1036747b715Smrg#endif 10405b261ecSmrg 1059ace9065Smrg#ifdef __clang__ 1069ace9065Smrg#pragma clang diagnostic ignored "-Wformat-nonliteral" 1079ace9065Smrg#endif 1089ace9065Smrg 10905b261ecSmrg#ifdef DDXOSVERRORF 11005b261ecSmrgvoid (*OsVendorVErrorFProc)(const char *, va_list args) = NULL; 11105b261ecSmrg#endif 11205b261ecSmrg 11305b261ecSmrgstatic FILE *logFile = NULL; 11405b261ecSmrgstatic Bool logFlush = FALSE; 11505b261ecSmrgstatic Bool logSync = FALSE; 11605b261ecSmrgstatic int logVerbosity = DEFAULT_LOG_VERBOSITY; 11705b261ecSmrgstatic int logFileVerbosity = DEFAULT_LOG_FILE_VERBOSITY; 11805b261ecSmrg 11905b261ecSmrg/* Buffer to information logged before the log file is opened. */ 12005b261ecSmrgstatic char *saveBuffer = NULL; 12105b261ecSmrgstatic int bufferSize = 0, bufferUnused = 0, bufferPos = 0; 12205b261ecSmrgstatic Bool needBuffer = TRUE; 12305b261ecSmrg 1246747b715Smrg#ifdef __APPLE__ 1256747b715Smrg#include <AvailabilityMacros.h> 1266747b715Smrg 1276747b715Smrgstatic char __crashreporter_info_buff__[4096] = {0}; 1288223e2f2Smrgstatic const char *__crashreporter_info__ __attribute__((__used__)) = &__crashreporter_info_buff__[0]; 1296747b715Smrg#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050 1306747b715Smrg// This is actually a toolchain requirement, but I'm not sure the correct check, 1316747b715Smrg// but it should be fine to just only include it for Leopard and later. This line 1326747b715Smrg// just tells the linker to never strip this symbol (such as for space optimization) 1336747b715Smrgasm (".desc ___crashreporter_info__, 0x10"); 1346747b715Smrg#endif 1356747b715Smrg#endif 1366747b715Smrg 13705b261ecSmrg/* Prefix strings for log messages. */ 13805b261ecSmrg#ifndef X_UNKNOWN_STRING 13905b261ecSmrg#define X_UNKNOWN_STRING "(\?\?)" 14005b261ecSmrg#endif 14105b261ecSmrg#ifndef X_PROBE_STRING 14205b261ecSmrg#define X_PROBE_STRING "(--)" 14305b261ecSmrg#endif 14405b261ecSmrg#ifndef X_CONFIG_STRING 14505b261ecSmrg#define X_CONFIG_STRING "(**)" 14605b261ecSmrg#endif 14705b261ecSmrg#ifndef X_DEFAULT_STRING 14805b261ecSmrg#define X_DEFAULT_STRING "(==)" 14905b261ecSmrg#endif 15005b261ecSmrg#ifndef X_CMDLINE_STRING 15105b261ecSmrg#define X_CMDLINE_STRING "(++)" 15205b261ecSmrg#endif 15305b261ecSmrg#ifndef X_NOTICE_STRING 15405b261ecSmrg#define X_NOTICE_STRING "(!!)" 15505b261ecSmrg#endif 15605b261ecSmrg#ifndef X_ERROR_STRING 15705b261ecSmrg#define X_ERROR_STRING "(EE)" 15805b261ecSmrg#endif 15905b261ecSmrg#ifndef X_WARNING_STRING 16005b261ecSmrg#define X_WARNING_STRING "(WW)" 16105b261ecSmrg#endif 16205b261ecSmrg#ifndef X_INFO_STRING 16305b261ecSmrg#define X_INFO_STRING "(II)" 16405b261ecSmrg#endif 16505b261ecSmrg#ifndef X_NOT_IMPLEMENTED_STRING 16605b261ecSmrg#define X_NOT_IMPLEMENTED_STRING "(NI)" 16705b261ecSmrg#endif 16805b261ecSmrg 16905b261ecSmrg/* 17005b261ecSmrg * LogInit is called to start logging to a file. It is also called (with 17105b261ecSmrg * NULL arguments) when logging to a file is not wanted. It must always be 17205b261ecSmrg * called, otherwise log messages will continue to accumulate in a buffer. 17305b261ecSmrg * 17405b261ecSmrg * %s, if present in the fname or backup strings, is expanded to the display 17505b261ecSmrg * string. 17605b261ecSmrg */ 17705b261ecSmrg 17805b261ecSmrgconst char * 17905b261ecSmrgLogInit(const char *fname, const char *backup) 18005b261ecSmrg{ 18105b261ecSmrg char *logFileName = NULL; 18205b261ecSmrg 18305b261ecSmrg if (fname && *fname) { 1849ace9065Smrg if (asprintf(&logFileName, fname, display) == -1) 18505b261ecSmrg FatalError("Cannot allocate space for the log file name\n"); 18605b261ecSmrg 18705b261ecSmrg if (backup && *backup) { 18805b261ecSmrg struct stat buf; 18905b261ecSmrg 19005b261ecSmrg if (!stat(logFileName, &buf) && S_ISREG(buf.st_mode)) { 19105b261ecSmrg char *suffix; 19205b261ecSmrg char *oldLog; 19305b261ecSmrg 1949ace9065Smrg if ((asprintf(&suffix, backup, display) == -1) || 1959ace9065Smrg (asprintf(&oldLog, "%s%s", logFileName, suffix) == -1)) 19605b261ecSmrg FatalError("Cannot allocate space for the log file name\n"); 19705b261ecSmrg free(suffix); 19805b261ecSmrg if (rename(logFileName, oldLog) == -1) { 1996747b715Smrg FatalError("Cannot move old log file \"%s\" to \"%s\"\n", 20005b261ecSmrg logFileName, oldLog); 20105b261ecSmrg } 20205b261ecSmrg free(oldLog); 20305b261ecSmrg } 20405b261ecSmrg } 20505b261ecSmrg if ((logFile = fopen(logFileName, "w")) == NULL) 20605b261ecSmrg FatalError("Cannot open log file \"%s\"\n", logFileName); 20705b261ecSmrg setvbuf(logFile, NULL, _IONBF, 0); 20805b261ecSmrg 20905b261ecSmrg /* Flush saved log information. */ 21005b261ecSmrg if (saveBuffer && bufferSize > 0) { 21105b261ecSmrg fwrite(saveBuffer, bufferPos, 1, logFile); 21205b261ecSmrg fflush(logFile); 21305b261ecSmrg#ifndef WIN32 21405b261ecSmrg fsync(fileno(logFile)); 21505b261ecSmrg#endif 21605b261ecSmrg } 21705b261ecSmrg } 21805b261ecSmrg 21905b261ecSmrg /* 22005b261ecSmrg * Unconditionally free the buffer, and flag that the buffer is no longer 22105b261ecSmrg * needed. 22205b261ecSmrg */ 22305b261ecSmrg if (saveBuffer && bufferSize > 0) { 2246747b715Smrg free(saveBuffer); /* Must be free(), not free() */ 22505b261ecSmrg saveBuffer = NULL; 22605b261ecSmrg bufferSize = 0; 22705b261ecSmrg } 22805b261ecSmrg needBuffer = FALSE; 22905b261ecSmrg 23005b261ecSmrg return logFileName; 23105b261ecSmrg} 23205b261ecSmrg 23305b261ecSmrgvoid 23405b261ecSmrgLogClose(void) 23505b261ecSmrg{ 23605b261ecSmrg if (logFile) { 23705b261ecSmrg fclose(logFile); 23805b261ecSmrg logFile = NULL; 23905b261ecSmrg } 24005b261ecSmrg} 24105b261ecSmrg 24205b261ecSmrgBool 24305b261ecSmrgLogSetParameter(LogParameter param, int value) 24405b261ecSmrg{ 24505b261ecSmrg switch (param) { 24605b261ecSmrg case XLOG_FLUSH: 24705b261ecSmrg logFlush = value ? TRUE : FALSE; 24805b261ecSmrg return TRUE; 24905b261ecSmrg case XLOG_SYNC: 25005b261ecSmrg logSync = value ? TRUE : FALSE; 25105b261ecSmrg return TRUE; 25205b261ecSmrg case XLOG_VERBOSITY: 25305b261ecSmrg logVerbosity = value; 25405b261ecSmrg return TRUE; 25505b261ecSmrg case XLOG_FILE_VERBOSITY: 25605b261ecSmrg logFileVerbosity = value; 25705b261ecSmrg return TRUE; 25805b261ecSmrg default: 25905b261ecSmrg return FALSE; 26005b261ecSmrg } 26105b261ecSmrg} 26205b261ecSmrg 26305b261ecSmrg/* This function does the actual log message writes. */ 26405b261ecSmrg 2656747b715Smrgvoid 26605b261ecSmrgLogVWrite(int verb, const char *f, va_list args) 26705b261ecSmrg{ 26805b261ecSmrg static char tmpBuffer[1024]; 26905b261ecSmrg int len = 0; 2706747b715Smrg static Bool newline = TRUE; 2716747b715Smrg 2726747b715Smrg if (newline) { 2736747b715Smrg sprintf(tmpBuffer, "[%10.3f] ", GetTimeInMillis() / 1000.0); 2746747b715Smrg len = strlen(tmpBuffer); 2756747b715Smrg if (logFile) 2766747b715Smrg fwrite(tmpBuffer, len, 1, logFile); 2776747b715Smrg } 27805b261ecSmrg 27905b261ecSmrg /* 28005b261ecSmrg * Since a va_list can only be processed once, write the string to a 28105b261ecSmrg * buffer, and then write the buffer out to the appropriate output 28205b261ecSmrg * stream(s). 28305b261ecSmrg */ 28405b261ecSmrg if (verb < 0 || logFileVerbosity >= verb || logVerbosity >= verb) { 28505b261ecSmrg vsnprintf(tmpBuffer, sizeof(tmpBuffer), f, args); 28605b261ecSmrg len = strlen(tmpBuffer); 28705b261ecSmrg } 2886747b715Smrg newline = (tmpBuffer[len-1] == '\n'); 28905b261ecSmrg if ((verb < 0 || logVerbosity >= verb) && len > 0) 29005b261ecSmrg fwrite(tmpBuffer, len, 1, stderr); 29105b261ecSmrg if ((verb < 0 || logFileVerbosity >= verb) && len > 0) { 29205b261ecSmrg if (logFile) { 29305b261ecSmrg fwrite(tmpBuffer, len, 1, logFile); 29405b261ecSmrg if (logFlush) { 29505b261ecSmrg fflush(logFile); 29605b261ecSmrg#ifndef WIN32 29705b261ecSmrg if (logSync) 29805b261ecSmrg fsync(fileno(logFile)); 29905b261ecSmrg#endif 30005b261ecSmrg } 30105b261ecSmrg } else if (needBuffer) { 30205b261ecSmrg if (len > bufferUnused) { 30305b261ecSmrg bufferSize += 1024; 30405b261ecSmrg bufferUnused += 1024; 3059ace9065Smrg saveBuffer = realloc(saveBuffer, bufferSize); 30605b261ecSmrg if (!saveBuffer) 30705b261ecSmrg FatalError("realloc() failed while saving log messages\n"); 30805b261ecSmrg } 30905b261ecSmrg bufferUnused -= len; 31005b261ecSmrg memcpy(saveBuffer + bufferPos, tmpBuffer, len); 31105b261ecSmrg bufferPos += len; 31205b261ecSmrg } 31305b261ecSmrg } 31405b261ecSmrg} 31505b261ecSmrg 3166747b715Smrgvoid 31705b261ecSmrgLogWrite(int verb, const char *f, ...) 31805b261ecSmrg{ 31905b261ecSmrg va_list args; 32005b261ecSmrg 32105b261ecSmrg va_start(args, f); 32205b261ecSmrg LogVWrite(verb, f, args); 32305b261ecSmrg va_end(args); 32405b261ecSmrg} 32505b261ecSmrg 3266747b715Smrgvoid 32705b261ecSmrgLogVMessageVerb(MessageType type, int verb, const char *format, va_list args) 32805b261ecSmrg{ 32905b261ecSmrg const char *s = X_UNKNOWN_STRING; 33052397711Smrg char tmpBuf[1024]; 33105b261ecSmrg 33205b261ecSmrg /* Ignore verbosity for X_ERROR */ 33305b261ecSmrg if (logVerbosity >= verb || logFileVerbosity >= verb || type == X_ERROR) { 33405b261ecSmrg switch (type) { 33505b261ecSmrg case X_PROBED: 33605b261ecSmrg s = X_PROBE_STRING; 33705b261ecSmrg break; 33805b261ecSmrg case X_CONFIG: 33905b261ecSmrg s = X_CONFIG_STRING; 34005b261ecSmrg break; 34105b261ecSmrg case X_DEFAULT: 34205b261ecSmrg s = X_DEFAULT_STRING; 34305b261ecSmrg break; 34405b261ecSmrg case X_CMDLINE: 34505b261ecSmrg s = X_CMDLINE_STRING; 34605b261ecSmrg break; 34705b261ecSmrg case X_NOTICE: 34805b261ecSmrg s = X_NOTICE_STRING; 34905b261ecSmrg break; 35005b261ecSmrg case X_ERROR: 35105b261ecSmrg s = X_ERROR_STRING; 35205b261ecSmrg if (verb > 0) 35305b261ecSmrg verb = 0; 35405b261ecSmrg break; 35505b261ecSmrg case X_WARNING: 35605b261ecSmrg s = X_WARNING_STRING; 35705b261ecSmrg break; 35805b261ecSmrg case X_INFO: 35905b261ecSmrg s = X_INFO_STRING; 36005b261ecSmrg break; 36105b261ecSmrg case X_NOT_IMPLEMENTED: 36205b261ecSmrg s = X_NOT_IMPLEMENTED_STRING; 36305b261ecSmrg break; 36405b261ecSmrg case X_UNKNOWN: 36505b261ecSmrg s = X_UNKNOWN_STRING; 36605b261ecSmrg break; 36705b261ecSmrg case X_NONE: 36805b261ecSmrg s = NULL; 36905b261ecSmrg break; 37005b261ecSmrg } 37105b261ecSmrg 37252397711Smrg /* if s is not NULL we need a space before format */ 37352397711Smrg snprintf(tmpBuf, sizeof(tmpBuf), "%s%s%s", s ? s : "", 37452397711Smrg s ? " " : "", 37552397711Smrg format); 37652397711Smrg LogVWrite(verb, tmpBuf, args); 37705b261ecSmrg } 37805b261ecSmrg} 37905b261ecSmrg 38005b261ecSmrg/* Log message with verbosity level specified. */ 3816747b715Smrgvoid 38205b261ecSmrgLogMessageVerb(MessageType type, int verb, const char *format, ...) 38305b261ecSmrg{ 38405b261ecSmrg va_list ap; 38505b261ecSmrg 38605b261ecSmrg va_start(ap, format); 38705b261ecSmrg LogVMessageVerb(type, verb, format, ap); 38805b261ecSmrg va_end(ap); 38905b261ecSmrg} 39005b261ecSmrg 39105b261ecSmrg/* Log a message with the standard verbosity level of 1. */ 3926747b715Smrgvoid 39305b261ecSmrgLogMessage(MessageType type, const char *format, ...) 39405b261ecSmrg{ 39505b261ecSmrg va_list ap; 39605b261ecSmrg 39705b261ecSmrg va_start(ap, format); 39805b261ecSmrg LogVMessageVerb(type, 1, format, ap); 39905b261ecSmrg va_end(ap); 40005b261ecSmrg} 40105b261ecSmrg 4026747b715Smrgvoid 4036747b715SmrgAbortServer(void) _X_NORETURN; 40405b261ecSmrg 40505b261ecSmrgvoid 40605b261ecSmrgAbortServer(void) 40705b261ecSmrg{ 4086747b715Smrg#ifdef XF86BIGFONT 4096747b715Smrg XF86BigfontCleanup(); 4106747b715Smrg#endif 4114642e01fSmrg CloseWellKnownConnections(); 41205b261ecSmrg OsCleanup(TRUE); 41305b261ecSmrg CloseDownDevices(); 41405b261ecSmrg AbortDDX(); 41505b261ecSmrg fflush(stderr); 41605b261ecSmrg if (CoreDump) 4176747b715Smrg OsAbort(); 41805b261ecSmrg exit (1); 41905b261ecSmrg} 42005b261ecSmrg 4214642e01fSmrg#define AUDIT_PREFIX "AUDIT: %s: %ld: " 42205b261ecSmrg#ifndef AUDIT_TIMEOUT 42305b261ecSmrg#define AUDIT_TIMEOUT ((CARD32)(120 * 1000)) /* 2 mn */ 42405b261ecSmrg#endif 42505b261ecSmrg 42605b261ecSmrgstatic int nrepeat = 0; 42705b261ecSmrgstatic int oldlen = -1; 42805b261ecSmrgstatic OsTimerPtr auditTimer = NULL; 42905b261ecSmrg 4306747b715Smrgvoid 43105b261ecSmrgFreeAuditTimer(void) 43205b261ecSmrg{ 43305b261ecSmrg if (auditTimer != NULL) { 43405b261ecSmrg /* Force output of pending messages */ 43505b261ecSmrg TimerForce(auditTimer); 43605b261ecSmrg TimerFree(auditTimer); 43705b261ecSmrg auditTimer = NULL; 43805b261ecSmrg } 43905b261ecSmrg} 44005b261ecSmrg 44105b261ecSmrgstatic char * 44205b261ecSmrgAuditPrefix(void) 44305b261ecSmrg{ 44405b261ecSmrg time_t tm; 44505b261ecSmrg char *autime, *s; 44605b261ecSmrg char *tmpBuf; 44705b261ecSmrg int len; 44805b261ecSmrg 44905b261ecSmrg time(&tm); 45005b261ecSmrg autime = ctime(&tm); 45105b261ecSmrg if ((s = strchr(autime, '\n'))) 45205b261ecSmrg *s = '\0'; 4534642e01fSmrg len = strlen(AUDIT_PREFIX) + strlen(autime) + 10 + 1; 45405b261ecSmrg tmpBuf = malloc(len); 45505b261ecSmrg if (!tmpBuf) 45605b261ecSmrg return NULL; 4574642e01fSmrg snprintf(tmpBuf, len, AUDIT_PREFIX, autime, (unsigned long)getpid()); 45805b261ecSmrg return tmpBuf; 45905b261ecSmrg} 46005b261ecSmrg 46105b261ecSmrgvoid 46205b261ecSmrgAuditF(const char * f, ...) 46305b261ecSmrg{ 46405b261ecSmrg va_list args; 46505b261ecSmrg 46605b261ecSmrg va_start(args, f); 46705b261ecSmrg 46805b261ecSmrg VAuditF(f, args); 46905b261ecSmrg va_end(args); 47005b261ecSmrg} 47105b261ecSmrg 47205b261ecSmrgstatic CARD32 47305b261ecSmrgAuditFlush(OsTimerPtr timer, CARD32 now, pointer arg) 47405b261ecSmrg{ 47505b261ecSmrg char *prefix; 47605b261ecSmrg 47705b261ecSmrg if (nrepeat > 0) { 47805b261ecSmrg prefix = AuditPrefix(); 47905b261ecSmrg ErrorF("%slast message repeated %d times\n", 48005b261ecSmrg prefix != NULL ? prefix : "", nrepeat); 48105b261ecSmrg nrepeat = 0; 4829ace9065Smrg free(prefix); 48305b261ecSmrg return AUDIT_TIMEOUT; 48405b261ecSmrg } else { 48505b261ecSmrg /* if the timer expires without anything to print, flush the message */ 48605b261ecSmrg oldlen = -1; 48705b261ecSmrg return 0; 48805b261ecSmrg } 48905b261ecSmrg} 49005b261ecSmrg 49105b261ecSmrgvoid 49205b261ecSmrgVAuditF(const char *f, va_list args) 49305b261ecSmrg{ 49405b261ecSmrg char *prefix; 49505b261ecSmrg char buf[1024]; 49605b261ecSmrg int len; 49705b261ecSmrg static char oldbuf[1024]; 49805b261ecSmrg 49905b261ecSmrg prefix = AuditPrefix(); 50005b261ecSmrg len = vsnprintf(buf, sizeof(buf), f, args); 50105b261ecSmrg 50205b261ecSmrg if (len == oldlen && strcmp(buf, oldbuf) == 0) { 50305b261ecSmrg /* Message already seen */ 50405b261ecSmrg nrepeat++; 50505b261ecSmrg } else { 50605b261ecSmrg /* new message */ 50705b261ecSmrg if (auditTimer != NULL) 50805b261ecSmrg TimerForce(auditTimer); 50905b261ecSmrg ErrorF("%s%s", prefix != NULL ? prefix : "", buf); 51005b261ecSmrg strlcpy(oldbuf, buf, sizeof(oldbuf)); 51105b261ecSmrg oldlen = len; 51205b261ecSmrg nrepeat = 0; 51305b261ecSmrg auditTimer = TimerSet(auditTimer, 0, AUDIT_TIMEOUT, AuditFlush, NULL); 51405b261ecSmrg } 5159ace9065Smrg free(prefix); 51605b261ecSmrg} 51705b261ecSmrg 5186747b715Smrgvoid 51905b261ecSmrgFatalError(const char *f, ...) 52005b261ecSmrg{ 52105b261ecSmrg va_list args; 52205b261ecSmrg static Bool beenhere = FALSE; 52305b261ecSmrg 52405b261ecSmrg if (beenhere) 52505b261ecSmrg ErrorF("\nFatalError re-entered, aborting\n"); 52605b261ecSmrg else 52705b261ecSmrg ErrorF("\nFatal server error:\n"); 52805b261ecSmrg 52905b261ecSmrg va_start(args, f); 5306747b715Smrg#ifdef __APPLE__ 5316747b715Smrg (void)vsnprintf(__crashreporter_info_buff__, sizeof(__crashreporter_info_buff__), f, args); 5326747b715Smrg#endif 53305b261ecSmrg VErrorF(f, args); 53405b261ecSmrg va_end(args); 53505b261ecSmrg ErrorF("\n"); 53605b261ecSmrg if (!beenhere) 53705b261ecSmrg OsVendorFatalError(); 53805b261ecSmrg if (!beenhere) { 53905b261ecSmrg beenhere = TRUE; 54005b261ecSmrg AbortServer(); 54105b261ecSmrg } else 5426747b715Smrg OsAbort(); 54305b261ecSmrg /*NOTREACHED*/ 54405b261ecSmrg} 54505b261ecSmrg 5466747b715Smrgvoid 54705b261ecSmrgVErrorF(const char *f, va_list args) 54805b261ecSmrg{ 54905b261ecSmrg#ifdef DDXOSVERRORF 55005b261ecSmrg if (OsVendorVErrorFProc) 55105b261ecSmrg OsVendorVErrorFProc(f, args); 55205b261ecSmrg else 55305b261ecSmrg LogVWrite(-1, f, args); 55405b261ecSmrg#else 55505b261ecSmrg LogVWrite(-1, f, args); 55605b261ecSmrg#endif 55705b261ecSmrg} 55805b261ecSmrg 5596747b715Smrgvoid 56005b261ecSmrgErrorF(const char * f, ...) 56105b261ecSmrg{ 56205b261ecSmrg va_list args; 56305b261ecSmrg 56405b261ecSmrg va_start(args, f); 56505b261ecSmrg VErrorF(f, args); 56605b261ecSmrg va_end(args); 56705b261ecSmrg} 56805b261ecSmrg 56905b261ecSmrg/* A perror() workalike. */ 57005b261ecSmrg 5716747b715Smrgvoid 5729ace9065SmrgError(const char *str) 57305b261ecSmrg{ 5749ace9065Smrg const char *err = strerror(errno); 5759ace9065Smrg 5769ace9065Smrg if (str) 5779ace9065Smrg LogWrite(-1, "%s: %s", str, err); 5789ace9065Smrg else 5794642e01fSmrg LogWrite(-1, "%s", err); 58005b261ecSmrg} 58105b261ecSmrg 58205b261ecSmrgvoid 58305b261ecSmrgLogPrintMarkers(void) 58405b261ecSmrg{ 58505b261ecSmrg /* Show what the message marker symbols mean. */ 5866747b715Smrg LogWrite(0, "Markers: "); 5876747b715Smrg LogMessageVerb(X_PROBED, 0, "probed, "); 5886747b715Smrg LogMessageVerb(X_CONFIG, 0, "from config file, "); 5896747b715Smrg LogMessageVerb(X_DEFAULT, 0, "default setting,\n\t"); 5906747b715Smrg LogMessageVerb(X_CMDLINE, 0, "from command line, "); 5916747b715Smrg LogMessageVerb(X_NOTICE, 0, "notice, "); 5926747b715Smrg LogMessageVerb(X_INFO, 0, "informational,\n\t"); 5936747b715Smrg LogMessageVerb(X_WARNING, 0, "warning, "); 5946747b715Smrg LogMessageVerb(X_ERROR, 0, "error, "); 5956747b715Smrg LogMessageVerb(X_NOT_IMPLEMENTED, 0, "not implemented, "); 5966747b715Smrg LogMessageVerb(X_UNKNOWN, 0, "unknown.\n"); 59705b261ecSmrg} 59805b261ecSmrg 599