diff options
Diffstat (limited to 'ldap/admin/lib/dsalib_tailf.c')
-rw-r--r-- | ldap/admin/lib/dsalib_tailf.c | 206 |
1 files changed, 206 insertions, 0 deletions
diff --git a/ldap/admin/lib/dsalib_tailf.c b/ldap/admin/lib/dsalib_tailf.c new file mode 100644 index 00000000..04e04578 --- /dev/null +++ b/ldap/admin/lib/dsalib_tailf.c @@ -0,0 +1,206 @@ +/** BEGIN COPYRIGHT BLOCK + * Copyright 2001 Sun Microsystems, Inc. + * Portions copyright 1999, 2001-2003 Netscape Communications Corporation. + * All rights reserved. + * END COPYRIGHT BLOCK **/ +#if defined( XP_WIN32 ) +#include <windows.h> +#endif +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> +#include "dsalib.h" +#include "prthread.h" + +/* + * Function: adjustFile + * Property: Adjust the file offset to the "tail" of the file + * Called by: DisplayTail + * Return: -1 for error, else file size + */ +static int +adjustFile(FILE *fp, int curSize) +{ + struct stat statBuf; + int fd = fileno(fp); + + if ( fstat(fd, &statBuf) == -1 ) + return(-1); + if ( statBuf.st_size < curSize ) /* file has shrunk! */ + { + if ( fseek(fp, 0L, 0) == -1 ) /* get back to the beginning */ + return(-1); + } + curSize = (int) statBuf.st_size; + if ( !curSize ) + curSize = 1; + return(curSize); +} + +/* + * Function: wrapLines + * Property: wrap lines at 50 characters. When a wrap point is encountered, + * insert the string "\n", since the buffer is going to be placed + * inside a JavaScript alert() call. + * Called by: ds_display_tail + * Return: pointer to wrapped buffer. Caller should free. + */ +static char * +wrapLines( char *buf ) +{ + char *src = buf; + char *obuf, *dst; + int lwidth = 0; + + obuf = malloc( strlen( buf ) * 2 ); /* conservative */ + if ( obuf == NULL ) { + return NULL; + } + dst = obuf; + while ( *src != '\0' ) { + if (( ++lwidth > 50 ) && isspace( *src )) { + *dst++ = '\\'; + *dst++ = 'n'; + lwidth = 0; + src++; + } else { + *dst++ = *src++; + } + } + *dst = '\0'; + return obuf; +} + +DS_EXPORT_SYMBOL int +ds_get_file_size(char *fileName) +{ + struct stat statBuf; + + if ( fileName == NULL ) + return(0); + + if ( stat(fileName, &statBuf) == -1 ) + return(0); + + return(statBuf.st_size); +} + +/* + * Function: ds_display_tail + * Property: follow the tail and display it for timeOut secs or until the line + * read from the file contains the string doneMsg; the lastLine, if not null, + * will be filled in with the last line read from the file; this is useful + * for determining why the server failed to start e.g. port in use, ran out + * of semaphores, database is corrupted, etc. + * Calls: adjustFile + */ +DS_EXPORT_SYMBOL void +ds_display_tail(char *fileName, int timeOut, int startSeek, char *doneMsg, + char *lastLine) +{ + FILE *fp = NULL; + int fd; + char msgBuf[BIG_LINE]; + struct stat statBuf; + int curSize; + int i = timeOut; + + if (lastLine != NULL) + lastLine[0] = 0; + + if ( fileName == NULL ) + return; + /* + * Open the file. + * Try to keep reading it assuming that it may get truncated. + */ + while (i && !fp) + { + fp = fopen(fileName, "r"); + if (!fp) + { + PR_Sleep(PR_SecondsToInterval(1)); + --i; + /* need to print something so http connection doesn't + timeout and also to let the user know something is + happening . . . + */ + if (!(i % 10)) + { + ds_send_status("Attempting to obtain server status . . ."); + } + } + } + + if (!i || !fp) + return; + + fd = fileno(fp); + if ( fstat(fd, &statBuf) == -1 ) { + (void) fclose(fp); + return; + } + curSize = (int) statBuf.st_size; + if ( startSeek < curSize ) + curSize = startSeek; + if ( curSize > 0 ) + if ( fseek(fp, curSize, SEEK_SET) == -1 ) { + (void) fclose(fp); + return; + } + if ( !curSize ) + curSize = 1; /* ensure minimum */ + + while ( i ) + { + int newCurSize; + + newCurSize = curSize = adjustFile(fp, curSize); + if ( curSize == -1 ) { + (void) fclose(fp); + return; + } + while ( fgets(msgBuf, sizeof(msgBuf), fp) ) + { + char *tmp; + if (lastLine != NULL) + strcpy(lastLine, msgBuf); + if ( (tmp = strchr(msgBuf, ((int) '\n'))) != NULL ) + *tmp = '\0'; /* strip out real newlines from here */ + ds_send_status(msgBuf); + if ( (strstr(msgBuf, "WARNING: ") != NULL) || + (strstr(msgBuf, "ERROR: ") != NULL) ) { + char *wrapBuf; + + wrapBuf = wrapLines( msgBuf ); + if ( wrapBuf != NULL ) { + ds_send_error(wrapBuf, 5); + } else { + ds_send_error(msgBuf, 5); + } + } + if ( (doneMsg != NULL) && (strstr(msgBuf, doneMsg)) ) { + (void) fclose(fp); + return; + } + newCurSize = adjustFile(fp, newCurSize); + if ( newCurSize == -1 ) { + (void) fclose(fp); + return; + } + } + if ( ferror(fp) ) { + (void) fclose(fp); + return; + } + clearerr(fp); /* clear eof condition */ + PR_Sleep(PR_SecondsToInterval(1)); + if ( newCurSize != curSize ) + i = timeOut; /* keep going till no more changes */ + else + i--; + } + (void) fclose(fp); +} |