|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T n
Length: 9286 (0x2446)
Types: TextFile
Names: »ntail.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
└─⟦dc59850a2⟧ »EurOpenD22/pp5.0/pp-5.tar.Z«
└─⟦e5a54fb17⟧
└─⟦this⟧ »pp-5.0/Tools/ntail/ntail.c«
/* ntail.c: */
# ifndef lint
static char Rcsid[] = "@(#)$Header: /cs/research/pp/hubris/pp-beta/Tools/ntail/RCS/ntail.c,v 5.0 90/09/20 16:29:57 pp Exp Locker: pp $";
# endif
/*
* $Header: /cs/research/pp/hubris/pp-beta/Tools/ntail/RCS/ntail.c,v 5.0 90/09/20 16:29:57 pp Exp Locker: pp $
*
* $Log: ntail.c,v $
* Revision 5.0 90/09/20 16:29:57 pp
* rcsforce : 5.0 public release
*
*/
/*
* @(#) ntail.c 2.1 89/07/26 19:15:42
*
* Package: ntail version 2
* File: ntail.c
* Description: main program
*
* Mon Jul 10 02:56:22 1989 - Chip Rosenthal <chip@vector.Dallas.TX.US>
* Original composition.
*/
#ifndef LINT
static char SCCSID[] = "@(#) ntail.c 2.1 89/07/26 19:15:42";
#endif
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#define INTERN
#include "ntail.h"
#ifdef M_XENIX
# undef NULL
# define NULL 0
#endif
int sigcaught = 0;
SIGTYPE sigcatcher(sig)
int sig;
{
/* extern SIGTYPE (*signal)(); */
if ( sig == SIGQUIT )
(void) exit(0);
sigcaught = sig;
#ifdef STATUS_ENAB
(void) signal(SIGINT,sigcatcher);
(void) signal(SIGQUIT,sigcatcher);
#endif
}
main(argc,argv)
int argc;
char *argv[];
{
int open_files_only, already_open, iteration, i;
struct entry_descrip *entryp;
struct stat sbuf;
/*
* Initialize.
*/
List_file.num = 0;
List_dir.num = 0;
List_zap.num = 0;
Sorted = FALSE;
Reset_status = FALSE;
Debug = FALSE;
sigcatcher(0);
/*
* Place all of the entries onto lists.
*/
for ( i = 1 ; i < argc ; ++i ) {
if ( i == 1 && strcmp(argv[i],"-D") == 0 ) {
Debug = TRUE;
continue;
}
/*
* Temporarily throw this entry onto the end of the zapped list.
*/
entryp = new_entry( &List_zap, argv[i] );
/*
* Stat the file and get it to its proper place.
*/
switch ( stat_entry( &List_zap, List_zap.num-1, &sbuf ) ) {
case ENTRY_FILE: /* move entry to file list */
move_entry( &List_file, &List_zap, List_zap.num-1 );
entryp->size = sbuf.st_size;
entryp->mtime = sbuf.st_mtime;
break;
case ENTRY_DIR: /* move entry to dir list */
move_entry( &List_dir, &List_zap, List_zap.num-1 );
entryp->size = sbuf.st_size;
entryp->mtime = sbuf.st_mtime;
if ( scan_directory( entryp->name ) != 0 ) {
message( MSSG_OPEN, entryp );
rmv_entry( &List_dir, List_dir.num-1 );
}
break;
case ENTRY_ZAP: /* keep entry on zap list */
break;
case ENTRY_SPECIAL: /* entry is a special file */
message( MSSG_NOTAFIL, entryp );
rmv_entry( &List_zap, List_zap.num-1 );
break;
default: /* stat error */
message( MSSG_STAT, entryp );
rmv_entry( &List_zap, List_zap.num-1 );
break;
}
}
/*
* Make sure we are watching something reasonable.
*/
if ( List_file.num == 0 ) {
if ( List_dir.num == 0 && List_zap.num == 0 ) {
(void) fprintf(stderr, "%s: no valid entries specified\n", argv[0]);
(void) exit(1);
}
(void) puts("\n*** warning - no files are being watched ***");
}
/*
* From this point on we want to reset the status of an entry any
* time we move it around to another list.
*/
Reset_status = TRUE;
/*
* Force a check of everything first time through the loop.
*/
iteration = CHECK_COUNT;
/*
* Loop forever.
*/
for (;;) {
/*
* Once every CHECK_COUNT iterations check everything.
* All other times only look at the opened files.
*/
open_files_only = ( ++iteration < CHECK_COUNT );
if ( !open_files_only )
iteration = 0;
/*
* Make sure that the most recently modified files are open.
*/
if ( !Sorted )
fixup_open_files();
/*
* Display what we are watching if a SIGINT was caught.
*/
if ( sigcaught ) {
show_status();
sigcatcher(0);
}
/*
* Go through all of the files looking for changes.
*/
Dprintf(stderr, ">>> checking files list (%s)\n",
( open_files_only ? "open files only" : "all files" ));
for ( i = 0 ; i < List_file.num ; ++i ) {
entryp = List_file.list[i];
already_open = ( entryp->fd > 0 ) ;
/*
* Ignore closed files except every CHECK_COUNT iterations.
*/
if ( !already_open && open_files_only )
continue;
/*
* Get the status of this file.
*/
switch ( stat_entry( &List_file, i, &sbuf ) ) {
case ENTRY_FILE: /* got status OK */
break;
case ENTRY_DIR: /* huh??? it's now a dir */
move_entry( &List_dir, &List_file, i-- );
continue;
case ENTRY_ZAP: /* entry has been deleted */
message( MSSG_ZAPPED, entryp );
move_entry( &List_zap, &List_file, i-- );
continue;
case ENTRY_SPECIAL: /* entry is a special file */
message( MSSG_NOTAFIL, entryp );
rmv_entry( &List_file, i-- );
continue;
default: /* stat error */
message( MSSG_STAT, entryp );
rmv_entry( &List_file, i-- );
continue;
}
/*
* See if an opened file has been deleted.
*/
if ( already_open && sbuf.st_nlink == 0 ) {
message( MSSG_ZAPPED, entryp );
move_entry( &List_zap, &List_file, i-- );
continue;
}
/*
* If nothing has changed then continue on.
*/
if ( entryp->size==sbuf.st_size && entryp->mtime==sbuf.st_mtime )
continue;
/*
* If the file isn't already open, then do so.
* Note -- it is important that we call "fixup_open_files()"
* at the end of the loop to make sure too many files don't
* stay opened.
*/
if ( !already_open && open_entry( &List_file, i ) != 0 ) {
--i;
continue;
}
/*
* See if the file has been truncated.
*/
if ( sbuf.st_size < entryp->size ) {
message( MSSG_TRUNC, entryp );
entryp->size = 0;
}
/*
* Seek to where the changes begin.
*/
{
extern long lseek();
if ( lseek( entryp->fd, entryp->size, 0 ) < 0 ) {
message( MSSG_SEEK, entryp );
rmv_entry( &List_file, i-- );
continue;
}
}
/*
* Dump the recently added info.
*/
{
int nb;
static char buf[BUFSIZ];
message( MSSG_BANNER, entryp );
while ( ( nb = read( entryp->fd, buf, sizeof(buf) ) ) > 0 ) {
(void) fwrite( buf, sizeof(char), (unsigned) nb, stdout );
entryp->size += nb;
}
if ( nb < 0 ) {
message( MSSG_READ, entryp );
rmv_entry( &List_file, i-- );
continue;
}
}
/*
* Update the modification time.
*/
entryp->mtime = sbuf.st_mtime;
/*
* Since we've changed the mtime, the list might no longer be
* sorted. However if this entry is already at the top of the
* list then it's OK.
*/
if ( i != 0 )
Sorted = FALSE;
/*
* If we've just opened the file then force a resort now to
* prevent too many files from being opened.
*/
if ( !already_open )
fixup_open_files();
}
/*
* Go through list of nonexistent entries to see if any have appeared.
* This is done only once every CHECK_COUNT iterations.
*/
if ( !open_files_only ) {
Dprintf(stderr, ">>> checking zapped list\n");
for ( i = 0 ; i < List_zap.num ; ++i ) {
entryp = List_zap.list[i];
switch ( stat_entry( &List_zap, i, &sbuf ) ) {
case ENTRY_FILE: /* entry has appeared as a file */
message( MSSG_CREATED, entryp );
move_entry( &List_file, &List_zap, i-- );
break;
case ENTRY_DIR: /* entry has appeared as a dir */
message( MSSG_CREATED, entryp );
move_entry( &List_dir, &List_zap, i-- );
break;
case ENTRY_ZAP: /* entry still doesn't exist */
break;
case ENTRY_SPECIAL: /* entry is a special file */
message( MSSG_NOTAFIL, entryp );
rmv_entry( &List_zap, i-- );
break;
default: /* error - entry removed */
message( MSSG_STAT, entryp );
rmv_entry( &List_zap, i-- );
break;
}
}
}
/*
* Go through the list of dirs to see if any new files were created.
* This is done only once every CHECK_COUNT iterations.
*/
if ( !open_files_only ) {
Dprintf(stderr, ">>> checking directory list\n");
for ( i = 0 ; !open_files_only && i < List_dir.num ; ++i ) {
entryp = List_dir.list[i];
switch ( stat_entry( &List_dir, i, &sbuf ) ) {
case ENTRY_DIR: /* got status OK */
break;
case ENTRY_FILE: /* huh??? it's now a reg file */
move_entry( &List_file, &List_dir, i-- );
continue;
case ENTRY_ZAP: /* entry has been deleted */
message( MSSG_ZAPPED, entryp );
move_entry( &List_zap, &List_dir, i-- );
continue;
case ENTRY_SPECIAL: /* entry is a special file */
message( MSSG_NOTAFIL, entryp );
rmv_entry( &List_dir, i-- );
continue;
default: /* stat error */
message( MSSG_STAT, entryp );
rmv_entry( &List_dir, i-- );
continue;
}
if ( entryp->mtime == sbuf.st_mtime )
continue;
if ( scan_directory( entryp->name ) != 0 ) {
message( MSSG_OPEN, entryp );
rmv_entry( &List_dir, i-- );
}
entryp->mtime = sbuf.st_mtime;
}
}
/*
* End of checking loop.
*/
{
extern unsigned sleep();
(void) fflush(stdout);
(void) sleep(SLEEP_TIME);
}
}
/*NOTREACHED*/
}