DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T m

⟦bc088f722⟧ TextFile

    Length: 5840 (0x16d0)
    Types: TextFile
    Names: »miscfuncs.c«

Derivation

└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
    └─⟦dc59850a2⟧ »EurOpenD22/pp5.0/pp-5.tar.Z« 
        └─⟦e5a54fb17⟧ 
            └─⟦this⟧ »pp-5.0/Tools/ntail/miscfuncs.c« 

TextFile

/* miscfuncs.c: */

# ifndef lint
static char Rcsid[] = "@(#)$Header: /cs/research/pp/hubris/pp-beta/Tools/ntail/RCS/miscfuncs.c,v 5.0 90/09/20 16:29:54 pp Exp Locker: pp $";
# endif

/*
 * $Header: /cs/research/pp/hubris/pp-beta/Tools/ntail/RCS/miscfuncs.c,v 5.0 90/09/20 16:29:54 pp Exp Locker: pp $
 *
 * $Log:	miscfuncs.c,v $
 * Revision 5.0  90/09/20  16:29:54  pp
 * rcsforce : 5.0 public release
 * 
 */



/*
 * @(#) miscfuncs.c 2.1 89/07/26 19:16:50
 *
 * Package:	ntail version 2
 * File:	miscfuncs.c
 * Description:	miscelaneous support procedures
 *
 * Mon Jul 10 02:56:22 1989 - Chip Rosenthal <chip@vector.Dallas.TX.US>
 *	Original composition.
 */

#ifndef LINT
static char SCCSID[] = "@(#) miscfuncs.c 2.1 89/07/26 19:16:50";
#endif

#include <stdio.h>
#include <fcntl.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "ntail.h"

#ifdef M_XENIX
# undef  NULL
# define NULL 0
#endif

/*
 * How come the portable directory routines are so !$*&@# unportable?
 */
#ifdef DIR_XENIX
#   include <sys/ndir.h>
    typedef struct direct DIRENT;
#endif
#ifdef DIR_BSD
#   include <sys/dir.h>
    typedef struct direct DIRENT;
#endif
#ifdef DIR_SYSV
#   include <dirent.h>
    typedef struct dirent DIRENT;
#endif

extern int errno;
extern char *sys_errlist[];


/*
 * Scan a directory for files not currently on a list.
 */
int scan_directory(dirname)
char *dirname;
{
    register int i;
    register DIRENT *dp;
    register struct entry_descrip **elist, *entryp;
    char *basename;
    struct stat sbuf;
    DIR *dirp;
    static char pathname[MAXNAMLEN];
    extern char *strcpy(), *strcat();

    Dprintf(stderr, ">>> scanning directory '%s'\n", dirname);
    if ( (dirp=opendir(dirname)) == NULL )
	return -1;

    (void) strcat( strcpy(pathname,dirname), "/" );
    basename = pathname + strlen(pathname);

#define SKIP_DIR(D) \
    ( D[0] == '.' && ( D[1] == '\0' || ( D[1] == '.' && D[2] == '\0' ) ) )

    while ( (dp=readdir(dirp)) != NULL ) {

	if ( SKIP_DIR(dp->d_name) )
	    continue;
	(void) strcpy( basename, dp->d_name );
	if ( stat(pathname,&sbuf) != 0 )
	    continue;
	if ( (sbuf.st_mode&S_IFMT) != S_IFREG )
	    continue;

	for ( i=List_file.num, elist=List_file.list ; i > 0 ; --i, ++elist ) {
	    if ( strcmp( (*elist)->name, pathname ) == 0 )
		break;
	}
	if ( i > 0 )
	    continue;

	for ( i=List_zap.num, elist=List_zap.list ; i > 0 ; --i, ++elist ) {
	    if ( strcmp( (*elist)->name, pathname ) == 0 )
		break;
	}
	if ( i > 0 )
	    continue;

	entryp = new_entry( &List_file, pathname );
	if ( Reset_status ) {
	    message( MSSG_CREATED, entryp );
	} else {
	    entryp->mtime = sbuf.st_mtime;
	    entryp->size = sbuf.st_size;
	}

    }

    (void) closedir(dirp);
    return 0;

}


/*
 * Compare mtime of two entries.  Used by the "qsort()" in "fixup_open_files()".
 */
static int ecmp(ep1,ep2)
register struct entry_descrip **ep1, **ep2;
{
    return ( (*ep2)->mtime - (*ep1)->mtime );
}

/*
 * Manage the open files.
 *   A small number of entries in "List_file" are kept open to minimize
 *   the overhead in checking for changes.  The strategy is to make sure
 *   the MAX_OPEN most recently modified files are all open.
 */
void fixup_open_files()
{
    register int i;
    register struct entry_descrip **elist;
    extern void qsort();

    Dprintf(stderr, ">>> resorting file list\n");
    (void) qsort(
	(char *) List_file.list,
	List_file.num,
	sizeof(struct entry_descrip *),
	ecmp
    );
    Sorted = TRUE;

    /*
     * Start at the end of the list.
     */
    i = List_file.num - 1;
    elist = &List_file.list[i];

    /*
     * All the files at the end of the list should be closed.
     */
    for ( ; i >= MAX_OPEN ; --i, --elist ) {
	if ( (*elist)->fd > 0 ) {
	    (void) close( (*elist)->fd );
	    (*elist)->fd = 0;
	}
    }

    /*
     * The first MAX_OPEN files in the list should be open.
     */
    for ( ; i >= 0 ; --i, --elist ) {
	if ( (*elist)->fd <= 0 )
	    (void) open_entry( &List_file, i );
    }

}


/*
 * Standard message interface.
 *   There are two reasons for this message interface.  First, it provides
 *   consistent diagnostics for all the messages.  Second, it manages the
 *   filename banner display whenever we switch to a different file.
 *   Warning - "errno" is used in some of the messages, so care must be
 *   taken not to step on it before message() can be called.
 */
void message(sel,e)
int sel;
struct entry_descrip *e;
{
    static char *ofile = NULL;

    /*
     * Don't display the file banner if the file hasn't changed since last time.
     */
    if ( sel == MSSG_BANNER && ofile != NULL && strcmp(ofile,e->name) == 0 )
	return;

    /*
     * Make sure the message selector is within range.
     */
    if ( sel < 0 || sel > MSSG_UNKNOWN )
	sel = MSSG_UNKNOWN;

    /*
     * Display the message.
     */
    if ( mssg_list[sel] != NULL )
	(void) printf(mssg_list[sel], e->name, sys_errlist[errno]);

    ofile = ( sel == MSSG_BANNER ? e->name : NULL );
}


/*
 * Display currently opened files.
 */
void show_status()
{
    int i, n;
    struct tm *tp;
    static char *monname[] = {
	"Jan", "Feb", "Mar", "Apr", "May", "Jun",
	"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
    };
    extern struct tm *localtime();

    (void) printf("\n*** recently changed files ***\n");
    for ( i = 0, n = 0 ; i < List_file.num ; ++i ) {
	if ( List_file.list[i]->fd > 0 ) {
	    tp = localtime(&List_file.list[i]->mtime);
	    (void) printf("%4d  %2d-%3s-%02d %02d:%02d:%02d  %s\n",
		++n,
		tp->tm_mday, monname[tp->tm_mon], tp->tm_year,
		tp->tm_hour, tp->tm_min, tp->tm_sec,
		List_file.list[i]->name
	    );
	}
    }

    (void) printf( 
	"currently watching:  %d files  %d dirs  %d unknown entries\n",
	List_file.num, List_dir.num, List_zap.num);

    message( MSSG_NONE, (struct entry_descrip *) NULL  );

}