Blame lib/isfn.c

Packit 6f02de
/*
Packit 6f02de
 * isfn.c -- is_file_named() function for lsof library
Packit 6f02de
 */
Packit 6f02de
Packit 6f02de
Packit 6f02de
/*
Packit 6f02de
 * Copyright 1997 Purdue Research Foundation, West Lafayette, Indiana
Packit 6f02de
 * 47907.  All rights reserved.
Packit 6f02de
 *
Packit 6f02de
 * Written by Victor A. Abell
Packit 6f02de
 *
Packit 6f02de
 * This software is not subject to any license of the American Telephone
Packit 6f02de
 * and Telegraph Company or the Regents of the University of California.
Packit 6f02de
 *
Packit 6f02de
 * Permission is granted to anyone to use this software for any purpose on
Packit 6f02de
 * any computer system, and to alter it and redistribute it freely, subject
Packit 6f02de
 * to the following restrictions:
Packit 6f02de
 *
Packit 6f02de
 * 1. Neither the authors nor Purdue University are responsible for any
Packit 6f02de
 *    consequences of the use of this software.
Packit 6f02de
 *
Packit 6f02de
 * 2. The origin of this software must not be misrepresented, either by
Packit 6f02de
 *    explicit claim or by omission.  Credit to the authors and Purdue
Packit 6f02de
 *    University must appear in documentation and sources.
Packit 6f02de
 *
Packit 6f02de
 * 3. Altered versions must be plainly marked as such, and must not be
Packit 6f02de
 *    misrepresented as being the original software.
Packit 6f02de
 *
Packit 6f02de
 * 4. This notice may not be removed or altered.
Packit 6f02de
 */
Packit 6f02de
Packit 6f02de
Packit 6f02de
/*
Packit 6f02de
 * To use this source file:
Packit 6f02de
 *
Packit 6f02de
 * 1. Define USE_LIB_IS_FILE_NAMED.
Packit 6f02de
 *
Packit 6f02de
 * 2. If clone support is required:
Packit 6f02de
 *
Packit 6f02de
 *    a.  Define HAVECLONEMAJ to be the name of the variable that
Packit 6f02de
 *	  contains the status of the clone major device -- e.g.,
Packit 6f02de
 *
Packit 6f02de
 *		#define HAVECLONEMAJ HaveCloneMaj
Packit 6f02de
 *
Packit 6f02de
 *    b.  Define CLONEMAJ to be the name of the constant or
Packit 6f02de
 *	  variable that defines the clone major device -- e.g.,
Packit 6f02de
 *
Packit 6f02de
 *		#define CLONEMAJ CloneMaj
Packit 6f02de
 *
Packit 6f02de
 *    c.  Make sure that clone devices are identified by an lfile
Packit 6f02de
 *	  element is_stream value of 1.
Packit 6f02de
 *
Packit 6f02de
 *    d.  Accept clone searching by device number only.
Packit 6f02de
 */
Packit 6f02de
Packit 6f02de
Packit 6f02de
#include "../machine.h"
Packit 6f02de
Packit 6f02de
#if	defined(USE_LIB_IS_FILE_NAMED)
Packit 6f02de
Packit 6f02de
# if	!defined(lint)
Packit 6f02de
static char copyright[] =
Packit 6f02de
"@(#) Copyright 1997 Purdue Research Foundation.\nAll rights reserved.\n";
Packit 6f02de
static char *rcsid = "$Id: isfn.c,v 1.10 2008/10/21 16:12:36 abe Exp $";
Packit 6f02de
# endif	/* !defined(lint) */
Packit 6f02de
Packit 6f02de
#include "../lsof.h"
Packit 6f02de
Packit 6f02de
Packit 6f02de
/*
Packit 6f02de
 * Local structures
Packit 6f02de
 */
Packit 6f02de
Packit 6f02de
struct hsfile {
Packit 6f02de
	struct sfile *s;		/* the Sfile table address */
Packit 6f02de
	struct hsfile *next;		/* the next hash bucket entry */
Packit 6f02de
};
Packit 6f02de
Packit 6f02de
/*
Packit 6f02de
 * Local static variables
Packit 6f02de
 */
Packit 6f02de
Packit 6f02de
# if	defined(HAVECLONEMAJ)
Packit 6f02de
static struct hsfile *HbyCd =		/* hash by clone buckets */
Packit 6f02de
	(struct hsfile *)NULL;
Packit 6f02de
static int HbyCdCt = 0;			/* HbyCd entry count */
Packit 6f02de
# endif	/* defined(HAVECLONEMAJ) */
Packit 6f02de
Packit 6f02de
static struct hsfile *HbyFdi =		/* hash by file (dev,ino) buckets */
Packit 6f02de
	(struct hsfile *)NULL;
Packit 6f02de
static int HbyFdiCt = 0;		/* HbyFdi entry count */
Packit 6f02de
static struct hsfile *HbyFrd =		/* hash by file raw device buckets */
Packit 6f02de
	(struct hsfile *)NULL;
Packit 6f02de
static int HbyFrdCt = 0;		/* HbyFrd entry count */
Packit 6f02de
static struct hsfile *HbyFsd =		/* hash by file system buckets */
Packit 6f02de
	(struct hsfile *)NULL;
Packit 6f02de
static int HbyFsdCt = 0;		/* HbyFsd entry count */
Packit 6f02de
static struct hsfile *HbyNm =		/* hash by name buckets */
Packit 6f02de
	(struct hsfile *)NULL;
Packit 6f02de
static int HbyNmCt = 0;			/* HbyNm entry count */
Packit 6f02de
Packit 6f02de
Packit 6f02de
/*
Packit 6f02de
 * Local definitions
Packit 6f02de
 */
Packit 6f02de
Packit 6f02de
# if	defined(HAVECLONEMAJ)
Packit 6f02de
#define	SFCDHASH	1024		/* Sfile hash by clone device (power
Packit 6f02de
					 * of 2!) */
Packit 6f02de
# endif	/* defined(HAVECLONEMAJ) */
Packit 6f02de
Packit 6f02de
#define	SFDIHASH	4094		/* Sfile hash by (device,inode) number
Packit 6f02de
					 * pair bucket count (power of 2!) */
Packit 6f02de
#define	SFFSHASH	1024		/* Sfile hash by file system device
Packit 6f02de
					 * number bucket count (power of 2!) */
Packit 6f02de
#define SFHASHDEVINO(maj, min, ino, mod) ((int)(((int)((((int)(maj+1))*((int)((min+1))))+ino)*31415)&(mod-1)))
Packit 6f02de
					/* hash for Sfile by major device,
Packit 6f02de
					 * minor device, and inode, modulo mod
Packit 6f02de
					 * (mod must be a power of 2) */
Packit 6f02de
#define	SFRDHASH	1024		/* Sfile hash by raw device number
Packit 6f02de
					 * bucket count (power of 2!) */
Packit 6f02de
#define SFHASHRDEVI(maj, min, rmaj, rmin, ino, mod) ((int)(((int)((((int)(maj+1))*((int)((min+1))))+((int)(rmaj+1)*(int)(rmin+1))+ino)*31415)&(mod-1)))
Packit 6f02de
					/* hash for Sfile by major device,
Packit 6f02de
					 * minor device, major raw device,
Packit 6f02de
					 * minor raw device, and inode, modulo
Packit 6f02de
					 * mod (mod must be a power of 2) */
Packit 6f02de
#define	SFNMHASH	4096		/* Sfile hash by name bucket count
Packit 6f02de
					 * (must be a power of 2!) */
Packit 6f02de
Packit 6f02de
Packit 6f02de
Packit 6f02de
/*
Packit 6f02de
 * hashSfile() - hash Sfile entries for use in is_file_named() searches
Packit 6f02de
 */
Packit 6f02de
Packit 6f02de
void
Packit 6f02de
hashSfile()
Packit 6f02de
{
Packit 6f02de
	static int hs = 0;
Packit 6f02de
	int i;
Packit 6f02de
	int sfplm = 3;
Packit 6f02de
	struct sfile *s;
Packit 6f02de
	struct hsfile *sh, *sn;
Packit 6f02de
/*
Packit 6f02de
 * Do nothing if there are no file search arguments cached or if the
Packit 6f02de
 * hashes have already been constructed.
Packit 6f02de
 */
Packit 6f02de
	if (!Sfile || hs)
Packit 6f02de
	    return;
Packit 6f02de
/*
Packit 6f02de
 * Allocate hash buckets by (device,inode), file system device, and file name.
Packit 6f02de
 */
Packit 6f02de
Packit 6f02de
# if	defined(HAVECLONEMAJ)
Packit 6f02de
	if (HAVECLONEMAJ) {
Packit 6f02de
	    if (!(HbyCd = (struct hsfile *)calloc((MALLOC_S)SFCDHASH,
Packit 6f02de
						  sizeof(struct hsfile))))
Packit 6f02de
	    {
Packit 6f02de
		(void) fprintf(stderr,
Packit 6f02de
		    "%s: can't allocate space for %d clone hash buckets\n",
Packit 6f02de
		    Pn, SFCDHASH);
Packit 6f02de
		Exit(1);
Packit 6f02de
	    }
Packit 6f02de
	    sfplm++;
Packit 6f02de
	}
Packit 6f02de
# endif	/* defined(HAVECLONEMAJ) */
Packit 6f02de
Packit 6f02de
	if (!(HbyFdi = (struct hsfile *)calloc((MALLOC_S)SFDIHASH,
Packit 6f02de
					       sizeof(struct hsfile))))
Packit 6f02de
	{
Packit 6f02de
	    (void) fprintf(stderr,
Packit 6f02de
		"%s: can't allocate space for %d (dev,ino) hash buckets\n",
Packit 6f02de
		Pn, SFDIHASH);
Packit 6f02de
	    Exit(1);
Packit 6f02de
	}
Packit 6f02de
	if (!(HbyFrd = (struct hsfile *)calloc((MALLOC_S)SFRDHASH,
Packit 6f02de
					       sizeof(struct hsfile))))
Packit 6f02de
	{
Packit 6f02de
	    (void) fprintf(stderr,
Packit 6f02de
		"%s: can't allocate space for %d rdev hash buckets\n",
Packit 6f02de
		Pn, SFRDHASH);
Packit 6f02de
	    Exit(1);
Packit 6f02de
	}
Packit 6f02de
	if (!(HbyFsd = (struct hsfile *)calloc((MALLOC_S)SFFSHASH,
Packit 6f02de
					       sizeof(struct hsfile))))
Packit 6f02de
	{
Packit 6f02de
	    (void) fprintf(stderr,
Packit 6f02de
		"%s: can't allocate space for %d file sys hash buckets\n",
Packit 6f02de
		Pn, SFFSHASH);
Packit 6f02de
	    Exit(1);
Packit 6f02de
	}
Packit 6f02de
	if (!(HbyNm = (struct hsfile *)calloc((MALLOC_S)SFNMHASH,
Packit 6f02de
					      sizeof(struct hsfile))))
Packit 6f02de
	{
Packit 6f02de
	    (void) fprintf(stderr,
Packit 6f02de
		"%s: can't allocate space for %d name hash buckets\n",
Packit 6f02de
		Pn, SFNMHASH);
Packit 6f02de
	    Exit(1);
Packit 6f02de
	}
Packit 6f02de
	hs++;
Packit 6f02de
/*
Packit 6f02de
 * Scan the Sfile chain, building file, file system, raw device, and file
Packit 6f02de
 * name hash bucket chains.
Packit 6f02de
 */
Packit 6f02de
	for (s = Sfile; s; s = s->next) {
Packit 6f02de
	    for (i = 0; i < sfplm; i++) {
Packit 6f02de
		if (i == 0) {
Packit 6f02de
		    if (!s->aname)
Packit 6f02de
			continue;
Packit 6f02de
		    sh = &HbyNm[hashbyname(s->aname, SFNMHASH)];
Packit 6f02de
		    HbyNmCt++;
Packit 6f02de
		} else if (i == 1) {
Packit 6f02de
		    if (s->type) {
Packit 6f02de
			sh = &HbyFdi[SFHASHDEVINO(GET_MAJ_DEV(s->dev),
Packit 6f02de
						  GET_MIN_DEV(s->dev), s->i,
Packit 6f02de
						  SFDIHASH)];
Packit 6f02de
			HbyFdiCt++;
Packit 6f02de
		    } else {
Packit 6f02de
			sh = &HbyFsd[SFHASHDEVINO(GET_MAJ_DEV(s->dev),
Packit 6f02de
						  GET_MIN_DEV(s->dev),
Packit 6f02de
						  0,
Packit 6f02de
						  SFFSHASH)];
Packit 6f02de
			HbyFsdCt++;
Packit 6f02de
		    }
Packit 6f02de
		} else if (i == 2) {
Packit 6f02de
		    if ((s->mode == S_IFCHR) || (s->mode == S_IFBLK)) {
Packit 6f02de
			sh = &HbyFrd[SFHASHRDEVI(GET_MAJ_DEV(s->dev),
Packit 6f02de
						 GET_MIN_DEV(s->dev),
Packit 6f02de
						 GET_MAJ_DEV(s->rdev),
Packit 6f02de
						 GET_MIN_DEV(s->rdev),
Packit 6f02de
						 s->i,
Packit 6f02de
						 SFRDHASH)];
Packit 6f02de
			HbyFrdCt++;
Packit 6f02de
		    } else
Packit 6f02de
			continue;
Packit 6f02de
		}
Packit 6f02de
Packit 6f02de
# if	defined(HAVECLONEMAJ)
Packit 6f02de
		else {
Packit 6f02de
		    if (!HAVECLONEMAJ || (GET_MAJ_DEV(s->rdev) != CLONEMAJ))
Packit 6f02de
			continue;
Packit 6f02de
		    sh = &HbyCd[SFHASHDEVINO(0, GET_MIN_DEV(s->rdev), 0,
Packit 6f02de
					     SFCDHASH)];
Packit 6f02de
		    HbyCdCt++;
Packit 6f02de
		}
Packit 6f02de
# else	/* ! defined(HAVECLONEMAJ) */
Packit 6f02de
		else
Packit 6f02de
		    continue;
Packit 6f02de
# endif	/* defined(HAVECLONEMAJ) */
Packit 6f02de
Packit 6f02de
		if (!sh->s) {
Packit 6f02de
		    sh->s = s;
Packit 6f02de
		    sh->next = (struct hsfile *)NULL;
Packit 6f02de
		    continue;
Packit 6f02de
		} else {
Packit 6f02de
		    if (!(sn = (struct hsfile *)malloc(
Packit 6f02de
				(MALLOC_S)sizeof(struct hsfile))))
Packit 6f02de
		    {
Packit 6f02de
			(void) fprintf(stderr,
Packit 6f02de
			    "%s: can't allocate hsfile bucket for: %s\n",
Packit 6f02de
			    Pn, s->aname);
Packit 6f02de
			Exit(1);
Packit 6f02de
		    }
Packit 6f02de
		    sn->s = s;
Packit 6f02de
		    sn->next = sh->next;
Packit 6f02de
		    sh->next = sn;
Packit 6f02de
		}
Packit 6f02de
	    }
Packit 6f02de
	}
Packit 6f02de
}
Packit 6f02de
Packit 6f02de
Packit 6f02de
/*
Packit 6f02de
 * is_file_named() - is this file named?
Packit 6f02de
 */
Packit 6f02de
Packit 6f02de
int
Packit 6f02de
is_file_named(p, cd)
Packit 6f02de
	char *p;			/* path name; NULL = search by device
Packit 6f02de
					 * and inode (from *Lf) */
Packit 6f02de
	int cd;				/* character or block type file --
Packit 6f02de
					 * VCHR or VBLK vnode, or S_IFCHR
Packit 6f02de
					 * or S_IFBLK inode */
Packit 6f02de
{
Packit 6f02de
	char *ep;
Packit 6f02de
	int f = 0;
Packit 6f02de
	struct sfile *s = (struct sfile *)NULL;
Packit 6f02de
	struct hsfile *sh;
Packit 6f02de
	size_t sz;
Packit 6f02de
/*
Packit 6f02de
 * Check for a path name match, as requested.
Packit 6f02de
 */
Packit 6f02de
	if (p && HbyNmCt) {
Packit 6f02de
	    for (sh = &HbyNm[hashbyname(p, SFNMHASH)]; sh; sh = sh->next) {
Packit 6f02de
		if ((s = sh->s) && strcmp(p, s->aname) == 0) {
Packit 6f02de
		    f = 2;
Packit 6f02de
		    break;
Packit 6f02de
		}
Packit 6f02de
	    }
Packit 6f02de
	}
Packit 6f02de
Packit 6f02de
# if	defined(HAVECLONEMAJ)
Packit 6f02de
/*
Packit 6f02de
 * If this is a stream, check for a clone device match.
Packit 6f02de
 */
Packit 6f02de
	if (!f && HbyCdCt && Lf->is_stream && Lf->dev_def && Lf->rdev_def
Packit 6f02de
	&&  (Lf->dev == DevDev))
Packit 6f02de
	{
Packit 6f02de
	    for (sh = &HbyCd[SFHASHDEVINO(0, GET_MAJ_DEV(Lf->rdev), 0,
Packit 6f02de
					  SFCDHASH)];
Packit 6f02de
		 sh;
Packit 6f02de
		 sh = sh->next)
Packit 6f02de
	    {
Packit 6f02de
		if ((s = sh->s) && (GET_MAJ_DEV(Lf->rdev)
Packit 6f02de
		==		    GET_MIN_DEV(s->rdev))) {
Packit 6f02de
		    f = 3;
Packit 6f02de
		    break;
Packit 6f02de
		}
Packit 6f02de
	    }
Packit 6f02de
	}
Packit 6f02de
# endif	/* defined(HAVECLONEMAJ) */
Packit 6f02de
Packit 6f02de
/*
Packit 6f02de
 * Check for a regular file.
Packit 6f02de
 */
Packit 6f02de
	if (!f && HbyFdiCt && Lf->dev_def
Packit 6f02de
	&& (Lf->inp_ty == 1 || Lf->inp_ty == 3))
Packit 6f02de
	{
Packit 6f02de
	    for (sh = &HbyFdi[SFHASHDEVINO(GET_MAJ_DEV(Lf->dev),
Packit 6f02de
					   GET_MIN_DEV(Lf->dev),
Packit 6f02de
					   Lf->inode,
Packit 6f02de
					   SFDIHASH)];
Packit 6f02de
		 sh;
Packit 6f02de
		 sh = sh->next)
Packit 6f02de
	    {
Packit 6f02de
		if ((s = sh->s) && (Lf->dev == s->dev)
Packit 6f02de
		&&  (Lf->inode == s->i)) {
Packit 6f02de
		    f = 1;
Packit 6f02de
		    break;
Packit 6f02de
		}
Packit 6f02de
	    }
Packit 6f02de
	}
Packit 6f02de
/*
Packit 6f02de
 * Check for a file system match.
Packit 6f02de
 */
Packit 6f02de
	if (!f && HbyFsdCt && Lf->dev_def) {
Packit 6f02de
	    for (sh = &HbyFsd[SFHASHDEVINO(GET_MAJ_DEV(Lf->dev),
Packit 6f02de
	    				   GET_MIN_DEV(Lf->dev), 0,
Packit 6f02de
					   SFFSHASH)];
Packit 6f02de
		 sh;
Packit 6f02de
		 sh = sh->next)
Packit 6f02de
	    {
Packit 6f02de
		if ((s = sh->s) && (s->dev == Lf->dev)) {
Packit 6f02de
		    f = 1;
Packit 6f02de
		    break;
Packit 6f02de
		}
Packit 6f02de
	    }
Packit 6f02de
	}
Packit 6f02de
/*
Packit 6f02de
 * Check for a character or block device match.
Packit 6f02de
 */
Packit 6f02de
	if (!f && HbyFrdCt && cd
Packit 6f02de
	&&  Lf->dev_def && (Lf->dev == DevDev)
Packit 6f02de
	&&  Lf->rdev_def
Packit 6f02de
	&& (Lf->inp_ty == 1 || Lf->inp_ty == 3))
Packit 6f02de
	{
Packit 6f02de
	    for (sh = &HbyFrd[SFHASHRDEVI(GET_MAJ_DEV(Lf->dev),
Packit 6f02de
					  GET_MIN_DEV(Lf->dev),
Packit 6f02de
					  GET_MAJ_DEV(Lf->rdev),
Packit 6f02de
					  GET_MIN_DEV(Lf->rdev),
Packit 6f02de
					  Lf->inode, SFRDHASH)];
Packit 6f02de
		 sh;
Packit 6f02de
		 sh = sh->next)
Packit 6f02de
	    {
Packit 6f02de
		if ((s = sh->s) && (s->dev == Lf->dev)
Packit 6f02de
		&&  (s->rdev == Lf->rdev) && (s->i == Lf->inode))
Packit 6f02de
		{
Packit 6f02de
		    f = 1;
Packit 6f02de
		    break;
Packit 6f02de
		}
Packit 6f02de
	    }
Packit 6f02de
	}
Packit 6f02de
/*
Packit 6f02de
 * Convert the name if a match occurred.
Packit 6f02de
 */
Packit 6f02de
	switch (f) {
Packit 6f02de
	case 0:
Packit 6f02de
	    return(0);
Packit 6f02de
	case 1:
Packit 6f02de
	    if (s->type) {
Packit 6f02de
Packit 6f02de
	    /*
Packit 6f02de
	     * If the search argument isn't a file system, propagate it
Packit 6f02de
	     * to Namech[]; otherwise, let printname() compose the name.
Packit 6f02de
	     */
Packit 6f02de
		(void) snpf(Namech, Namechl, "%s", s->name);
Packit 6f02de
		if (s->devnm) {
Packit 6f02de
		    ep = endnm(&sz);
Packit 6f02de
		    (void) snpf(ep, sz, " (%s)", s->devnm);
Packit 6f02de
		}
Packit 6f02de
	    }
Packit 6f02de
	    break;
Packit 6f02de
	case 2:
Packit 6f02de
	    (void) strcpy(Namech, p);
Packit 6f02de
	    break;
Packit 6f02de
Packit 6f02de
# if	defined(HAVECLONEMAJ)
Packit 6f02de
	/* case 3:		do nothing for stream clone matches */
Packit 6f02de
# endif	/* defined(HAVECLONEMAJ) */
Packit 6f02de
Packit 6f02de
	}
Packit 6f02de
	if (s)
Packit 6f02de
	    s->f = 1;
Packit 6f02de
	return(1);
Packit 6f02de
}
Packit 6f02de
#else	/* !defined(USE_LIB_IS_FILE_NAMED) */
Packit 6f02de
char isfn_d1[] = "d"; char *isfn_d2 = isfn_d1;
Packit 6f02de
#endif	/* defined(USE_LIB_IS_FILE_NAMED) */