|
|
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 m
Length: 5840 (0x16d0)
Types: TextFile
Names: »miscfuncs.c«
└─⟦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«
/* 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 );
}