|
|
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 e
Length: 5484 (0x156c)
Types: TextFile
Names: »entryfuncs.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
└─⟦dc59850a2⟧ »EurOpenD22/pp5.0/pp-5.tar.Z«
└─⟦e5a54fb17⟧
└─⟦this⟧ »pp-5.0/Tools/ntail/entryfuncs.c«
/* entryfuncs.c: */
# ifndef lint
static char Rcsid[] = "@(#)$Header: /cs/research/pp/hubris/pp-beta/Tools/ntail/RCS/entryfuncs.c,v 5.0 90/09/20 16:29:51 pp Exp Locker: pp $";
# endif
/*
* $Header: /cs/research/pp/hubris/pp-beta/Tools/ntail/RCS/entryfuncs.c,v 5.0 90/09/20 16:29:51 pp Exp Locker: pp $
*
* $Log: entryfuncs.c,v $
* Revision 5.0 90/09/20 16:29:51 pp
* rcsforce : 5.0 public release
*
*/
/*
* @(#) entryfuncs.c 2.1 89/07/26 19:16:49
*
* Package: ntail version 2
* File: entryfuncs.c
* Description: procedures to manage individual entries
*
* Mon Jul 10 02:56:22 1989 - Chip Rosenthal <chip@vector.Dallas.TX.US>
* Original composition.
*/
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/errno.h>
#include "ntail.h"
#ifdef M_XENIX
# undef NULL
# define NULL 0
#endif
extern int errno;
static struct entry_descrip *E_append(listp,entryp)
struct entry_list *listp;
struct entry_descrip *entryp;
{
if ( listp->num >= MAX_ENTRIES ) {
(void) fprintf(stderr,"%s: too many entries (%d max)\n",
entryp->name, MAX_ENTRIES);
(void) exit(2);
}
listp->list[listp->num++] = entryp;
Sorted = FALSE;
return entryp;
}
static void E_remove(listp,entryno)
struct entry_list *listp;
int entryno;
{
while ( ++entryno < listp->num )
listp->list[entryno-1] = listp->list[entryno];
--listp->num;
Sorted = FALSE;
}
static char *list_name(listp) /* for debug output only */
struct entry_list *listp;
{
if ( listp == &List_file ) return "<file>";
if ( listp == &List_dir ) return "<dir>";
if ( listp == &List_zap ) return "<zap>";
return "?unknown?";
}
/*
* Create a new entry description and append it to a list.
*/
struct entry_descrip *new_entry(listp,name)
struct entry_list *listp;
char *name;
{
struct entry_descrip *entryp;
static char malloc_error[] = "malloc: out of space\n";
extern char *strcpy(), *malloc();
Dprintf(stderr, ">>> creating entry '%s' on %s list\n",
name, list_name(listp));
entryp = (struct entry_descrip *) malloc( sizeof(struct entry_descrip) );
if ( entryp == NULL ) {
(void) fputs(malloc_error,stderr);
(void) exit(2);
}
entryp->name = malloc( (unsigned) strlen(name) + 1 );
if ( entryp->name == NULL ) {
(void) fputs(malloc_error,stderr);
(void) exit(2);
}
(void) strcpy(entryp->name,name);
entryp->fd = 0;
entryp->size = 0;
entryp->mtime = 0;
return E_append(listp,entryp);
}
/*
* Remove an entry from a list and free up its space.
*/
void rmv_entry(listp,entryno)
struct entry_list *listp;
int entryno;
{
struct entry_descrip *entryp = listp->list[entryno];
extern void free();
Dprintf(stderr, ">>> removing entry '%s' from %s list\n",
listp->list[entryno]->name, list_name(listp));
E_remove(listp,entryno);
if ( entryp->fd > 0 )
(void) close(entryp->fd);
free( entryp->name );
free( (char *) entryp );
}
/*
* Move an entry from one list to another.
* In addition we close up the entry if appropriate.
*/
void move_entry(dst_listp,src_listp,src_entryno)
struct entry_list *dst_listp;
struct entry_list *src_listp;
int src_entryno;
{
struct entry_descrip *entryp = src_listp->list[src_entryno];
Dprintf(stderr, ">>> moving entry '%s' from %s list to %s list\n",
src_listp->list[src_entryno]->name,
list_name(src_listp), list_name(dst_listp));
if ( entryp->fd > 0 ) {
(void) close(entryp->fd);
entryp->fd = 0;
}
E_remove(src_listp,src_entryno);
(void) E_append(dst_listp,entryp);
if ( Reset_status ) {
entryp->size = 0;
entryp->mtime = 0;
}
}
/*
* Get the inode status for an entry.
* Returns code describing the status of the entry.
*/
int stat_entry(listp,entryno,sbuf)
struct entry_list *listp;
int entryno;
register struct stat *sbuf;
{
register int status;
register struct entry_descrip *entryp = listp->list[entryno];
static int my_gid = -1;
static int my_uid = -1;
if ( my_gid < 0 ) {
my_gid = getegid();
my_uid = geteuid();
}
status =
( entryp->fd > 0 ? fstat(entryp->fd,sbuf) : stat(entryp->name,sbuf) );
if ( status != 0 )
return ( errno == ENOENT ? ENTRY_ZAP : ENTRY_ERROR );
if (
( ( sbuf->st_mode & 0004 ) == 0 ) &&
( ( sbuf->st_mode & 0040 ) == 0 || sbuf->st_gid != my_gid ) &&
( ( sbuf->st_mode & 0400 ) == 0 || sbuf->st_uid != my_uid )
) {
errno = EACCES;
return ENTRY_ERROR;
}
switch ( sbuf->st_mode & S_IFMT ) {
case S_IFREG: return ENTRY_FILE;
case S_IFDIR: return ENTRY_DIR;
default: return ENTRY_SPECIAL;
}
/*NOTREACHED*/
}
/*
* Open an entry.
* Returns 0 if the open is successful, else returns errno. In the case
* of an error, an appropriate diagnostic will be printed, and the entry
* will be moved or deleted as required. If the entry is already opened,
* then no action will occur and 0 will be returned.
*/
int open_entry(listp,entryno)
struct entry_list *listp;
int entryno;
{
struct entry_descrip *entryp = listp->list[entryno];
if ( entryp->fd > 0 )
return 0;
Dprintf(stderr, ">>> opening entry '%s' on %s list\n",
listp->list[entryno]->name, list_name(listp));
if ( (entryp->fd=open(entryp->name,O_RDONLY)) > 0 )
return 0;
if ( errno == ENOENT ) {
message( MSSG_ZAPPED, entryp );
move_entry( &List_zap, listp, entryno );
} else {
message( MSSG_OPEN, entryp );
rmv_entry( listp, entryno );
}
return -1;
}