2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
24 * (c) Copyright 1993, 1994 Hewlett-Packard Company *
25 * (c) Copyright 1993, 1994 International Business Machines Corp. *
26 * (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
27 * (c) Copyright 1993, 1994 Novell, Inc. *
30 * xdm - display manager daemon
32 * $XConsortium: error.c /main/6 1996/10/21 12:50:31 mgreess $
34 * Copyright 1988 Massachusetts Institute of Technology
36 * Permission to use, copy, modify, and distribute this software and its
37 * documentation for any purpose and without fee is hereby granted, provided
38 * that the above copyright notice appear in all copies and that both that
39 * copyright notice and this permission notice appear in supporting
40 * documentation, and that the name of M.I.T. not be used in advertising or
41 * publicity pertaining to distribution of the software without specific,
42 * written prior permission. M.I.T. makes no representations about the
43 * suitability of this software for any purpose. It is provided "as is"
44 * without express or implied warranty.
46 * Author: Keith Packard, MIT X Consortium
52 * Log display manager errors to a file as
53 * we generally do not have a terminal to talk to
56 # include <sys/stat.h>
62 # define Va_start(a,b) va_start(a,b)
64 extern char DisplayName[];
75 * add TimeZone to our environment so error message time stamps
76 * have the correct value...
79 if (timeZone != NULL && strlen(timeZone) < 29) {
86 if (errorLogFile && errorLogFile[0]) {
87 i = creat (errorLogFile, 0666);
95 MC_LOG_SET,MC_LOG_NO_ERRLOG,MC_DEF_LOG_NO_ERRLOG),
100 /****************************************************************************
104 * Just a quick check to verify that we can open an error log.
105 * Do this before we do BecomeDeamon.
107 ****************************************************************************/
109 CheckErrorFile( void )
113 if (errorLogFile && errorLogFile[0]) {
114 i = creat (errorLogFile, 0666);
118 fprintf(stderr, (char *)ReadCatalog(
119 MC_LOG_SET,MC_LOG_NO_ERRLOG,MC_DEF_LOG_NO_ERRLOG),
123 fprintf(stderr, (char *)ReadCatalog(
124 MC_LOG_SET,MC_LOG_NO_ERRLOG,MC_DEF_LOG_NO_ERRLOG),
130 /****************************************************************************
134 * point the stderr stream to the most current Error Log File. This allows
135 * the user to muck with the file while XDM is running and have everything
138 * optionally, write a time stamp to the file
139 ****************************************************************************/
142 SyncErrorFile( int stamp )
147 if (errorLogFile && errorLogFile[0] &&
148 (freopen(errorLogFile, "a", stderr) != NULL)) {
152 fprintf(stderr, "\n%s", ctime(&timer));
161 /****************************************************************************
165 * Trim the length of the error log file until it is 75% of the maximum
166 * specified by the resource "errorLogSize".
168 ****************************************************************************/
171 TrimErrorFile( void )
187 * convert user-specified units of 1Kb to bytes...
188 * put an upper cap of 200Kb on the file...
191 if (errorLogSize < 1024) errorLogSize *= 1024;
193 if (errorLogSize > (200*1024) ) {
194 errorLogSize = 200*1024;
195 LogError(ReadCatalog(
196 MC_LOG_SET,MC_LOG_MAX_LOGFILE,MC_DEF_LOG_MAX_LOGFILE));
199 if ( errorLogFile && errorLogFile[0] &&
200 (stat(errorLogFile, &statb) == 0) &&
201 (statb.st_size > errorLogSize) ) {
203 deleteBytes = (statb.st_size - errorLogSize) + (errorLogSize / 4);
205 Debug("TrimErrorLog(): discarding oldest %d bytes from logfile %s\n",
206 deleteBytes, errorLogFile);
210 * get two pointers to the file...
213 if ( (f1 = open(errorLogFile, O_RDWR)) < 0 ||
214 (f2 = open(errorLogFile, O_RDWR)) < 0 ) {
215 Debug("TrimErrorLog(): Cannot open file %s, error number = %d\n",
216 errorLogFile, errno);
228 * position read pointer to the first full line after the trim
232 if ( (status = lseek(f2, deleteBytes, SEEK_SET)) < 0 ) {
233 Debug("TrimErrorLog(): Cannot lseek() in file %s, error number = %d\n",
234 errorLogFile, errno);
240 memset(buf, 0, BUFSIZ);
241 n = read(f2, buf, BUFSIZ - 1);
243 if ( (p = strchr(buf,'\n')) != NULL ) {
246 deleteBytes += p - buf;
254 * shift bytes to be saved to the beginning of the file...
257 if(-1 == write (f1, p, n)) {
258 perror(strerror(errno));
261 while ( (n = read(f2, buf, BUFSIZ)) > 0 ) {
262 if(-1 == write(f1, buf, n)) {
263 perror(strerror(errno));
268 * truncate file to new length and close file pointers...
271 if(-1 == truncate(errorLogFile, statb.st_size - deleteBytes)) {
272 perror(strerror(errno));
282 /****************************************************************************
286 * Write an information message to the log file
288 ****************************************************************************/
291 LogInfo( unsigned char *fmt, ...)
297 if ( SyncErrorFile(1) ) {
298 fprintf (stderr, "info (pid %ld): ", (long)getpid());
299 vfprintf (stderr, (char *)fmt, args);
308 /****************************************************************************
312 * Write an error message to the log file.
314 ****************************************************************************/
317 LogError( unsigned char *fmt, ...)
323 if ( SyncErrorFile(1) ) {
324 fprintf (stderr, "error (pid %ld): ", (long)getpid());
325 vfprintf (stderr, (char *)fmt, args);
334 /****************************************************************************
338 * Write an "out of memory" message to the log file.
340 ****************************************************************************/
343 LogOutOfMem( unsigned char *fmt, ...)
349 if ( SyncErrorFile(1) ) {
350 fprintf(stderr, "%s", (char *)ReadCatalog(MC_ERROR_SET,MC_NO_MEMORY,MC_DEF_NO_MEMORY));
351 vfprintf (stderr, (char *)fmt, args);
360 /***************************************************************************
362 * CODE DISABLED!!! The following routines...
367 * ForEachMatchingIndirectHost()
369 * ForEachChooserHost()
371 * are disabled until indirect queries are supported...
373 ***************************************************************************/
377 /****************************************************************************
381 * Write a panic message to the log file.
383 ****************************************************************************/
385 LogPanic( char *fmt, ...)
391 if ( SyncErrorFile(1) ) {
392 fprintf (stderr, "panic (pid %ld): ", (long)getpid());
393 vfprintf (stderr, fmt, args);
402 /****************************************************************************
406 * Write a panic message to the console
408 ****************************************************************************/
415 i = creat ("/dev/console", 0666);
416 write (i, "panic: ", 7);
417 write (i, mesg, strlen (mesg));
420 #endif /* DISABLED CODE */
424 /****************************************************************************
428 * Write a debug message to stdout
430 ****************************************************************************/
432 static int DoName=True;
435 Debug( char *fmt, ...)
443 if ( strlen(DisplayName) > 0 && DoName)
444 fprintf(stdout, "(%s) ", DisplayName);
450 * don't prepend the display name next time if this debug message
451 * does not contain a "new line" character...
454 if ( strchr(fmt,'\n') == NULL )