dsalib_tailf.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. /** BEGIN COPYRIGHT BLOCK
  2. * This Program is free software; you can redistribute it and/or modify it under
  3. * the terms of the GNU General Public License as published by the Free Software
  4. * Foundation; version 2 of the License.
  5. *
  6. * This Program is distributed in the hope that it will be useful, but WITHOUT
  7. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  8. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  9. *
  10. * You should have received a copy of the GNU General Public License along with
  11. * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
  12. * Place, Suite 330, Boston, MA 02111-1307 USA.
  13. *
  14. * In addition, as a special exception, Red Hat, Inc. gives You the additional
  15. * right to link the code of this Program with code not covered under the GNU
  16. * General Public License ("Non-GPL Code") and to distribute linked combinations
  17. * including the two, subject to the limitations in this paragraph. Non-GPL Code
  18. * permitted under this exception must only link to the code of this Program
  19. * through those well defined interfaces identified in the file named EXCEPTION
  20. * found in the source code files (the "Approved Interfaces"). The files of
  21. * Non-GPL Code may instantiate templates or use macros or inline functions from
  22. * the Approved Interfaces without causing the resulting work to be covered by
  23. * the GNU General Public License. Only Red Hat, Inc. may make changes or
  24. * additions to the list of Approved Interfaces. You must obey the GNU General
  25. * Public License in all respects for all of the Program code and other code used
  26. * in conjunction with the Program except the Non-GPL Code covered by this
  27. * exception. If you modify this file, you may extend this exception to your
  28. * version of the file, but you are not obligated to do so. If you do not wish to
  29. * provide this exception without modification, you must delete this exception
  30. * statement from your version and license this file solely under the GPL without
  31. * exception.
  32. *
  33. *
  34. * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  35. * Copyright (C) 2005 Red Hat, Inc.
  36. * All rights reserved.
  37. * END COPYRIGHT BLOCK **/
  38. #ifdef HAVE_CONFIG_H
  39. # include <config.h>
  40. #endif
  41. #if defined( XP_WIN32 )
  42. #include <windows.h>
  43. #endif
  44. #include <ctype.h>
  45. #include <stdio.h>
  46. #include <stdlib.h>
  47. #include <string.h>
  48. #include <sys/stat.h>
  49. #include "dsalib.h"
  50. #include "prthread.h"
  51. #include "plstr.h"
  52. /*
  53. * Function: adjustFile
  54. * Property: Adjust the file offset to the "tail" of the file
  55. * Called by: DisplayTail
  56. * Return: -1 for error, else file size
  57. */
  58. static int
  59. adjustFile(FILE *fp, int curSize)
  60. {
  61. struct stat statBuf;
  62. int fd = fileno(fp);
  63. if ( fstat(fd, &statBuf) == -1 )
  64. return(-1);
  65. if ( statBuf.st_size < curSize ) /* file has shrunk! */
  66. {
  67. if ( fseek(fp, 0L, 0) == -1 ) /* get back to the beginning */
  68. return(-1);
  69. }
  70. curSize = (int) statBuf.st_size;
  71. if ( !curSize )
  72. curSize = 1;
  73. return(curSize);
  74. }
  75. /*
  76. * Function: wrapLines
  77. * Property: wrap lines at 50 characters. When a wrap point is encountered,
  78. * insert the string "\n", since the buffer is going to be placed
  79. * inside a JavaScript alert() call.
  80. * Called by: ds_display_tail
  81. * Return: pointer to wrapped buffer. Caller should free.
  82. */
  83. static char *
  84. wrapLines( char *buf )
  85. {
  86. char *src = buf;
  87. char *obuf, *dst;
  88. int lwidth = 0;
  89. obuf = malloc( strlen( buf ) * 2 ); /* conservative */
  90. if ( obuf == NULL ) {
  91. return NULL;
  92. }
  93. dst = obuf;
  94. while ( *src != '\0' ) {
  95. if (( ++lwidth > 50 ) && isspace( *src )) {
  96. *dst++ = '\\';
  97. *dst++ = 'n';
  98. lwidth = 0;
  99. src++;
  100. } else {
  101. *dst++ = *src++;
  102. }
  103. }
  104. *dst = '\0';
  105. return obuf;
  106. }
  107. DS_EXPORT_SYMBOL int
  108. ds_get_file_size(char *fileName)
  109. {
  110. struct stat statBuf;
  111. if ( fileName == NULL )
  112. return(0);
  113. if ( stat(fileName, &statBuf) == -1 )
  114. return(0);
  115. return(statBuf.st_size);
  116. }
  117. /*
  118. * Function: ds_display_tail
  119. * Property: follow the tail and display it for timeOut secs or until the line
  120. * read from the file contains the string doneMsg; the lastLine, if not null,
  121. * will be filled in with the last line read from the file; this is useful
  122. * for determining why the server failed to start e.g. port in use, ran out
  123. * of semaphores, database is corrupted, etc.
  124. * Calls: adjustFile
  125. */
  126. DS_EXPORT_SYMBOL void
  127. ds_display_tail(char *fileName, int timeOut, int startSeek, char *doneMsg,
  128. char *lastLine)
  129. {
  130. FILE *fp = NULL;
  131. int fd;
  132. char msgBuf[BIG_LINE];
  133. struct stat statBuf;
  134. int curSize;
  135. int i = timeOut;
  136. if (lastLine != NULL)
  137. lastLine[0] = 0;
  138. if ( fileName == NULL )
  139. return;
  140. /*
  141. * Open the file.
  142. * Try to keep reading it assuming that it may get truncated.
  143. */
  144. while (i && !fp)
  145. {
  146. fp = fopen(fileName, "r");
  147. if (!fp)
  148. {
  149. PR_Sleep(PR_SecondsToInterval(1));
  150. --i;
  151. /* need to print something so http connection doesn't
  152. timeout and also to let the user know something is
  153. happening . . .
  154. */
  155. if (!(i % 10))
  156. {
  157. ds_send_status("Attempting to obtain server status . . .");
  158. }
  159. }
  160. }
  161. if (!i || !fp)
  162. return;
  163. fd = fileno(fp);
  164. if ( fstat(fd, &statBuf) == -1 ) {
  165. (void) fclose(fp);
  166. return;
  167. }
  168. curSize = (int) statBuf.st_size;
  169. if ( startSeek < curSize )
  170. curSize = startSeek;
  171. if ( curSize > 0 )
  172. if ( fseek(fp, curSize, SEEK_SET) == -1 ) {
  173. (void) fclose(fp);
  174. return;
  175. }
  176. if ( !curSize )
  177. curSize = 1; /* ensure minimum */
  178. while ( i )
  179. {
  180. int newCurSize;
  181. newCurSize = curSize = adjustFile(fp, curSize);
  182. if ( curSize == -1 ) {
  183. (void) fclose(fp);
  184. return;
  185. }
  186. while ( fgets(msgBuf, sizeof(msgBuf), fp) )
  187. {
  188. char *tmp;
  189. if (lastLine != NULL)
  190. PL_strncpyz(lastLine, msgBuf, BIG_LINE);
  191. if ( (tmp = strchr(msgBuf, ((int) '\n'))) != NULL )
  192. *tmp = '\0'; /* strip out real newlines from here */
  193. ds_send_status(msgBuf);
  194. if ( (strstr(msgBuf, "WARNING: ") != NULL) ||
  195. (strstr(msgBuf, "ERROR: ") != NULL) ) {
  196. char *wrapBuf;
  197. wrapBuf = wrapLines( msgBuf );
  198. if ( wrapBuf != NULL ) {
  199. ds_send_error(wrapBuf, 5);
  200. } else {
  201. ds_send_error(msgBuf, 5);
  202. }
  203. }
  204. if ( (doneMsg != NULL) && (strstr(msgBuf, doneMsg)) ) {
  205. (void) fclose(fp);
  206. return;
  207. }
  208. newCurSize = adjustFile(fp, newCurSize);
  209. if ( newCurSize == -1 ) {
  210. (void) fclose(fp);
  211. return;
  212. }
  213. }
  214. if ( ferror(fp) ) {
  215. (void) fclose(fp);
  216. return;
  217. }
  218. clearerr(fp); /* clear eof condition */
  219. PR_Sleep(PR_SecondsToInterval(1));
  220. if ( newCurSize != curSize )
  221. i = timeOut; /* keep going till no more changes */
  222. else
  223. i--;
  224. }
  225. (void) fclose(fp);
  226. }