error.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  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)
  10. * any later version.
  11. *
  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
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with these libraries and programs; if not, write
  20. * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
  21. * Floor, Boston, MA 02110-1301 USA
  22. */
  23. /* *
  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. *
  28. */
  29. /*
  30. * xdm - display manager daemon
  31. *
  32. * $XConsortium: error.c /main/6 1996/10/21 12:50:31 mgreess $
  33. *
  34. * Copyright 1988 Massachusetts Institute of Technology
  35. *
  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.
  45. *
  46. * Author: Keith Packard, MIT X Consortium
  47. */
  48. /*
  49. * error.c
  50. *
  51. * Log display manager errors to a file as
  52. * we generally do not have a terminal to talk to
  53. */
  54. # include <sys/stat.h>
  55. # include <time.h>
  56. # include "dm.h"
  57. # include "vgmsg.h"
  58. # include <stdarg.h>
  59. # define Va_start(a,b) va_start(a,b)
  60. extern char DisplayName[];
  61. void
  62. InitErrorLog( void )
  63. {
  64. int i;
  65. static char tz[32];
  66. /*
  67. * add TimeZone to our environment so error message time stamps
  68. * have the correct value...
  69. */
  70. if (timeZone != NULL && strlen(timeZone) < 29) {
  71. strcpy(tz,"TZ=");
  72. strcat(tz,timeZone);
  73. putenv(tz);
  74. }
  75. if (errorLogFile && errorLogFile[0]) {
  76. i = creat (errorLogFile, 0666);
  77. if (i != -1) {
  78. if (i != 2) {
  79. dup2 (i, 2);
  80. close (i);
  81. }
  82. } else
  83. LogError(ReadCatalog(
  84. MC_LOG_SET,MC_LOG_NO_ERRLOG,MC_DEF_LOG_NO_ERRLOG),
  85. errorLogFile);
  86. }
  87. }
  88. /****************************************************************************
  89. *
  90. * CheckErrorFile
  91. *
  92. * Just a quick check to verify that we can open an error log.
  93. * Do this before we do BecomeDeamon.
  94. *
  95. ****************************************************************************/
  96. void
  97. CheckErrorFile( void )
  98. {
  99. int i;
  100. if (errorLogFile && errorLogFile[0]) {
  101. i = creat (errorLogFile, 0666);
  102. if (i != -1) {
  103. close (i);
  104. } else {
  105. fprintf(stderr, (char *)ReadCatalog(
  106. MC_LOG_SET,MC_LOG_NO_ERRLOG,MC_DEF_LOG_NO_ERRLOG),
  107. errorLogFile);
  108. }
  109. } else {
  110. fprintf(stderr, (char *)ReadCatalog(
  111. MC_LOG_SET,MC_LOG_NO_ERRLOG,MC_DEF_LOG_NO_ERRLOG),
  112. "\"\"");
  113. }
  114. }
  115. /****************************************************************************
  116. *
  117. * SyncErrorFile
  118. *
  119. * point the stderr stream to the most current Error Log File. This allows
  120. * the user to muck with the file while XDM is running and have everything
  121. * sync up later.
  122. *
  123. * optionally, write a time stamp to the file
  124. ****************************************************************************/
  125. int
  126. SyncErrorFile( int stamp )
  127. {
  128. time_t timer;
  129. TrimErrorFile();
  130. if (errorLogFile && errorLogFile[0] &&
  131. (freopen(errorLogFile, "a", stderr) != NULL)) {
  132. if (stamp) {
  133. timer = time(NULL);
  134. fprintf(stderr, "\n%s", ctime(&timer));
  135. }
  136. return(1);
  137. }
  138. else
  139. return(0);
  140. }
  141. /****************************************************************************
  142. *
  143. * TrimErrorFile
  144. *
  145. * Trim the length of the error log file until it is 75% of the maximum
  146. * specified by the resource "errorLogSize".
  147. *
  148. ****************************************************************************/
  149. void
  150. TrimErrorFile( void )
  151. {
  152. int f1 = -1;
  153. int f2 = -1;
  154. int deleteBytes;
  155. char buf[BUFSIZ];
  156. char *p;
  157. int n;
  158. off_t status;
  159. struct stat statb;
  160. /*
  161. * convert user-specified units of 1Kb to bytes...
  162. * put an upper cap of 200Kb on the file...
  163. */
  164. if (errorLogSize < 1024) errorLogSize *= 1024;
  165. if (errorLogSize > (200*1024) ) {
  166. errorLogSize = 200*1024;
  167. LogError(ReadCatalog(
  168. MC_LOG_SET,MC_LOG_MAX_LOGFILE,MC_DEF_LOG_MAX_LOGFILE));
  169. }
  170. if ( errorLogFile && errorLogFile[0] &&
  171. (stat(errorLogFile, &statb) == 0) &&
  172. (statb.st_size > errorLogSize) ) {
  173. deleteBytes = (statb.st_size - errorLogSize) + (errorLogSize / 4);
  174. Debug("TrimErrorLog(): discarding oldest %d bytes from logfile %s\n",
  175. deleteBytes, errorLogFile);
  176. /*
  177. * get two pointers to the file...
  178. */
  179. if ( (f1 = open(errorLogFile, O_RDWR)) < 0 ||
  180. (f2 = open(errorLogFile, O_RDWR)) < 0 ) {
  181. Debug("TrimErrorLog(): Cannot open file %s, error number = %d\n",
  182. errorLogFile, errno);
  183. if(f1 >= 0) {
  184. close(f1);
  185. }
  186. if(f2 >= 0) {
  187. close(f2);
  188. }
  189. return;
  190. }
  191. /*
  192. * position read pointer to the first full line after the trim
  193. * point...
  194. */
  195. if ( (status = lseek(f2, deleteBytes, SEEK_SET)) < 0 ) {
  196. Debug("TrimErrorLog(): Cannot lseek() in file %s, error number = %d\n",
  197. errorLogFile, errno);
  198. close(f1);
  199. close(f2);
  200. return;
  201. }
  202. memset(buf, 0, BUFSIZ);
  203. n = read(f2, buf, BUFSIZ - 1);
  204. if ( (p = strchr(buf,'\n')) != NULL ) {
  205. p++;
  206. n -= p - buf;
  207. deleteBytes += p - buf;
  208. }
  209. else {
  210. p = buf;
  211. }
  212. /*
  213. * shift bytes to be saved to the beginning of the file...
  214. */
  215. if(-1 == write (f1, p, n)) {
  216. perror(strerror(errno));
  217. }
  218. while ( (n = read(f2, buf, BUFSIZ)) > 0 ) {
  219. if(-1 == write(f1, buf, n)) {
  220. perror(strerror(errno));
  221. }
  222. }
  223. /*
  224. * truncate file to new length and close file pointers...
  225. */
  226. if(-1 == truncate(errorLogFile, statb.st_size - deleteBytes)) {
  227. perror(strerror(errno));
  228. }
  229. close(f1);
  230. close(f2);
  231. }
  232. }
  233. /****************************************************************************
  234. *
  235. * LogInfo
  236. *
  237. * Write an information message to the log file
  238. *
  239. ****************************************************************************/
  240. void
  241. LogInfo( unsigned char *fmt, ...)
  242. {
  243. va_list args;
  244. Va_start(args,fmt);
  245. if ( SyncErrorFile(1) ) {
  246. fprintf (stderr, "info (pid %ld): ", (long)getpid());
  247. vfprintf (stderr, (char *)fmt, args);
  248. fflush (stderr);
  249. }
  250. va_end(args);
  251. }
  252. /****************************************************************************
  253. *
  254. * LogError
  255. *
  256. * Write an error message to the log file.
  257. *
  258. ****************************************************************************/
  259. void
  260. LogError( unsigned char *fmt, ...)
  261. {
  262. va_list args;
  263. Va_start(args,fmt);
  264. if ( SyncErrorFile(1) ) {
  265. fprintf (stderr, "error (pid %ld): ", (long)getpid());
  266. vfprintf (stderr, (char *)fmt, args);
  267. fflush (stderr);
  268. }
  269. va_end(args);
  270. }
  271. /****************************************************************************
  272. *
  273. * LogOutOfMem
  274. *
  275. * Write an "out of memory" message to the log file.
  276. *
  277. ****************************************************************************/
  278. void
  279. LogOutOfMem( unsigned char *fmt, ...)
  280. {
  281. va_list args;
  282. Va_start(args,fmt);
  283. if ( SyncErrorFile(1) ) {
  284. fprintf(stderr, "%s", (char *)ReadCatalog(MC_ERROR_SET,MC_NO_MEMORY,MC_DEF_NO_MEMORY));
  285. vfprintf (stderr, (char *)fmt, args);
  286. fflush (stderr);
  287. }
  288. va_end(args);
  289. }
  290. /***************************************************************************
  291. *
  292. * CODE DISABLED!!! The following routines...
  293. *
  294. * getLocalAddress()
  295. * scanHostList()
  296. * indirectAlias()
  297. * ForEachMatchingIndirectHost()
  298. * UseChooser()
  299. * ForEachChooserHost()
  300. *
  301. * are disabled until indirect queries are supported...
  302. *
  303. ***************************************************************************/
  304. #if 0
  305. /****************************************************************************
  306. *
  307. * LogPanic
  308. *
  309. * Write a panic message to the log file.
  310. *
  311. ****************************************************************************/
  312. void
  313. LogPanic( char *fmt, ...)
  314. {
  315. va_list args;
  316. Va_start(args,fmt);
  317. if ( SyncErrorFile(1) ) {
  318. fprintf (stderr, "panic (pid %ld): ", (long)getpid());
  319. vfprintf (stderr, fmt, args);
  320. fflush (stderr);
  321. }
  322. va_end(args);
  323. }
  324. /****************************************************************************
  325. *
  326. * Panic
  327. *
  328. * Write a panic message to the console
  329. *
  330. ****************************************************************************/
  331. int
  332. Panic( char *mesg )
  333. {
  334. int i;
  335. i = creat ("/dev/console", 0666);
  336. write (i, "panic: ", 7);
  337. write (i, mesg, strlen (mesg));
  338. exit (1);
  339. }
  340. #endif /* DISABLED CODE */
  341. /****************************************************************************
  342. *
  343. * Debug
  344. *
  345. * Write a debug message to stdout
  346. *
  347. ****************************************************************************/
  348. static int DoName=True;
  349. void
  350. Debug( char *fmt, ...)
  351. {
  352. va_list args;
  353. Va_start(args,fmt);
  354. if (debugLevel > 0)
  355. {
  356. if ( strlen(DisplayName) > 0 && DoName)
  357. fprintf(stdout, "(%s) ", DisplayName);
  358. vprintf (fmt, args);
  359. fflush (stdout);
  360. /*
  361. * don't prepend the display name next time if this debug message
  362. * does not contain a "new line" character...
  363. */
  364. if ( strchr(fmt,'\n') == NULL )
  365. DoName=False;
  366. else
  367. DoName=True;
  368. }
  369. va_end(args);
  370. }