2 * isfn.c -- is_file_named() function for lsof library
7 * Copyright 1997 Purdue Research Foundation, West Lafayette, Indiana
8 * 47907. All rights reserved.
10 * Written by Victor A. Abell
12 * This software is not subject to any license of the American Telephone
13 * and Telegraph Company or the Regents of the University of California.
15 * Permission is granted to anyone to use this software for any purpose on
16 * any computer system, and to alter it and redistribute it freely, subject
17 * to the following restrictions:
19 * 1. Neither the authors nor Purdue University are responsible for any
20 * consequences of the use of this software.
22 * 2. The origin of this software must not be misrepresented, either by
23 * explicit claim or by omission. Credit to the authors and Purdue
24 * University must appear in documentation and sources.
26 * 3. Altered versions must be plainly marked as such, and must not be
27 * misrepresented as being the original software.
29 * 4. This notice may not be removed or altered.
34 * To use this source file:
36 * 1. Define USE_LIB_IS_FILE_NAMED.
38 * 2. If clone support is required:
40 * a. Define HAVECLONEMAJ to be the name of the variable that
41 * contains the status of the clone major device -- e.g.,
43 * #define HAVECLONEMAJ HaveCloneMaj
45 * b. Define CLONEMAJ to be the name of the constant or
46 * variable that defines the clone major device -- e.g.,
48 * #define CLONEMAJ CloneMaj
50 * c. Make sure that clone devices are identified by an lfile
51 * element is_stream value of 1.
53 * d. Accept clone searching by device number only.
57 #include "../machine.h"
59 #if defined(USE_LIB_IS_FILE_NAMED)
62 static char copyright[] =
63 "@(#) Copyright 1997 Purdue Research Foundation.\nAll rights reserved.\n";
64 static char *rcsid = "$Id: isfn.c,v 1.10 2008/10/21 16:12:36 abe Exp $";
65 # endif /* !defined(lint) */
75 struct sfile *s; /* the Sfile table address */
76 struct hsfile *next; /* the next hash bucket entry */
80 * Local static variables
83 # if defined(HAVECLONEMAJ)
84 static struct hsfile *HbyCd = /* hash by clone buckets */
85 (struct hsfile *)NULL;
86 static int HbyCdCt = 0; /* HbyCd entry count */
87 # endif /* defined(HAVECLONEMAJ) */
89 static struct hsfile *HbyFdi = /* hash by file (dev,ino) buckets */
90 (struct hsfile *)NULL;
91 static int HbyFdiCt = 0; /* HbyFdi entry count */
92 static struct hsfile *HbyFrd = /* hash by file raw device buckets */
93 (struct hsfile *)NULL;
94 static int HbyFrdCt = 0; /* HbyFrd entry count */
95 static struct hsfile *HbyFsd = /* hash by file system buckets */
96 (struct hsfile *)NULL;
97 static int HbyFsdCt = 0; /* HbyFsd entry count */
98 static struct hsfile *HbyNm = /* hash by name buckets */
99 (struct hsfile *)NULL;
100 static int HbyNmCt = 0; /* HbyNm entry count */
107 # if defined(HAVECLONEMAJ)
108 #define SFCDHASH 1024 /* Sfile hash by clone device (power
110 # endif /* defined(HAVECLONEMAJ) */
112 #define SFDIHASH 4094 /* Sfile hash by (device,inode) number
113 * pair bucket count (power of 2!) */
114 #define SFFSHASH 1024 /* Sfile hash by file system device
115 * number bucket count (power of 2!) */
116 #define SFHASHDEVINO(maj, min, ino, mod) ((int)(((int)((((int)(maj+1))*((int)((min+1))))+ino)*31415)&(mod-1)))
117 /* hash for Sfile by major device,
118 * minor device, and inode, modulo mod
119 * (mod must be a power of 2) */
120 #define SFRDHASH 1024 /* Sfile hash by raw device number
121 * bucket count (power of 2!) */
122 #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)))
123 /* hash for Sfile by major device,
124 * minor device, major raw device,
125 * minor raw device, and inode, modulo
126 * mod (mod must be a power of 2) */
127 #define SFNMHASH 4096 /* Sfile hash by name bucket count
128 * (must be a power of 2!) */
133 * hashSfile() - hash Sfile entries for use in is_file_named() searches
143 struct hsfile *sh, *sn;
145 * Do nothing if there are no file search arguments cached or if the
146 * hashes have already been constructed.
151 * Allocate hash buckets by (device,inode), file system device, and file name.
154 # if defined(HAVECLONEMAJ)
156 if (!(HbyCd = (struct hsfile *)calloc((MALLOC_S)SFCDHASH,
157 sizeof(struct hsfile))))
159 (void) fprintf(stderr,
160 "%s: can't allocate space for %d clone hash buckets\n",
166 # endif /* defined(HAVECLONEMAJ) */
168 if (!(HbyFdi = (struct hsfile *)calloc((MALLOC_S)SFDIHASH,
169 sizeof(struct hsfile))))
171 (void) fprintf(stderr,
172 "%s: can't allocate space for %d (dev,ino) hash buckets\n",
176 if (!(HbyFrd = (struct hsfile *)calloc((MALLOC_S)SFRDHASH,
177 sizeof(struct hsfile))))
179 (void) fprintf(stderr,
180 "%s: can't allocate space for %d rdev hash buckets\n",
184 if (!(HbyFsd = (struct hsfile *)calloc((MALLOC_S)SFFSHASH,
185 sizeof(struct hsfile))))
187 (void) fprintf(stderr,
188 "%s: can't allocate space for %d file sys hash buckets\n",
192 if (!(HbyNm = (struct hsfile *)calloc((MALLOC_S)SFNMHASH,
193 sizeof(struct hsfile))))
195 (void) fprintf(stderr,
196 "%s: can't allocate space for %d name hash buckets\n",
202 * Scan the Sfile chain, building file, file system, raw device, and file
203 * name hash bucket chains.
205 for (s = Sfile; s; s = s->next) {
206 for (i = 0; i < sfplm; i++) {
210 sh = &HbyNm[hashbyname(s->aname, SFNMHASH)];
214 sh = &HbyFdi[SFHASHDEVINO(GET_MAJ_DEV(s->dev),
215 GET_MIN_DEV(s->dev), s->i,
219 sh = &HbyFsd[SFHASHDEVINO(GET_MAJ_DEV(s->dev),
226 if ((s->mode == S_IFCHR) || (s->mode == S_IFBLK)) {
227 sh = &HbyFrd[SFHASHRDEVI(GET_MAJ_DEV(s->dev),
229 GET_MAJ_DEV(s->rdev),
230 GET_MIN_DEV(s->rdev),
238 # if defined(HAVECLONEMAJ)
240 if (!HAVECLONEMAJ || (GET_MAJ_DEV(s->rdev) != CLONEMAJ))
242 sh = &HbyCd[SFHASHDEVINO(0, GET_MIN_DEV(s->rdev), 0,
246 # else /* ! defined(HAVECLONEMAJ) */
249 # endif /* defined(HAVECLONEMAJ) */
253 sh->next = (struct hsfile *)NULL;
256 if (!(sn = (struct hsfile *)malloc(
257 (MALLOC_S)sizeof(struct hsfile))))
259 (void) fprintf(stderr,
260 "%s: can't allocate hsfile bucket for: %s\n",
274 * is_file_named() - is this file named?
279 char *p; /* path name; NULL = search by device
280 * and inode (from *Lf) */
281 int cd; /* character or block type file --
282 * VCHR or VBLK vnode, or S_IFCHR
283 * or S_IFBLK inode */
287 struct sfile *s = (struct sfile *)NULL;
291 * Check for a path name match, as requested.
294 for (sh = &HbyNm[hashbyname(p, SFNMHASH)]; sh; sh = sh->next) {
295 if ((s = sh->s) && strcmp(p, s->aname) == 0) {
302 # if defined(HAVECLONEMAJ)
304 * If this is a stream, check for a clone device match.
306 if (!f && HbyCdCt && Lf->is_stream && Lf->dev_def && Lf->rdev_def
307 && (Lf->dev == DevDev))
309 for (sh = &HbyCd[SFHASHDEVINO(0, GET_MAJ_DEV(Lf->rdev), 0,
314 if ((s = sh->s) && (GET_MAJ_DEV(Lf->rdev)
315 == GET_MIN_DEV(s->rdev))) {
321 # endif /* defined(HAVECLONEMAJ) */
324 * Check for a regular file.
326 if (!f && HbyFdiCt && Lf->dev_def
327 && (Lf->inp_ty == 1 || Lf->inp_ty == 3))
329 for (sh = &HbyFdi[SFHASHDEVINO(GET_MAJ_DEV(Lf->dev),
330 GET_MIN_DEV(Lf->dev),
336 if ((s = sh->s) && (Lf->dev == s->dev)
337 && (Lf->inode == s->i)) {
344 * Check for a file system match.
346 if (!f && HbyFsdCt && Lf->dev_def) {
347 for (sh = &HbyFsd[SFHASHDEVINO(GET_MAJ_DEV(Lf->dev),
348 GET_MIN_DEV(Lf->dev), 0,
353 if ((s = sh->s) && (s->dev == Lf->dev)) {
360 * Check for a character or block device match.
362 if (!f && HbyFrdCt && cd
363 && Lf->dev_def && (Lf->dev == DevDev)
365 && (Lf->inp_ty == 1 || Lf->inp_ty == 3))
367 for (sh = &HbyFrd[SFHASHRDEVI(GET_MAJ_DEV(Lf->dev),
368 GET_MIN_DEV(Lf->dev),
369 GET_MAJ_DEV(Lf->rdev),
370 GET_MIN_DEV(Lf->rdev),
371 Lf->inode, SFRDHASH)];
375 if ((s = sh->s) && (s->dev == Lf->dev)
376 && (s->rdev == Lf->rdev) && (s->i == Lf->inode))
384 * Convert the name if a match occurred.
393 * If the search argument isn't a file system, propagate it
394 * to Namech[]; otherwise, let printname() compose the name.
396 (void) snpf(Namech, Namechl, "%s", s->name);
399 (void) snpf(ep, sz, " (%s)", s->devnm);
404 (void) strcpy(Namech, p);
407 # if defined(HAVECLONEMAJ)
408 /* case 3: do nothing for stream clone matches */
409 # endif /* defined(HAVECLONEMAJ) */
416 #else /* !defined(USE_LIB_IS_FILE_NAMED) */
417 char isfn_d1[] = "d"; char *isfn_d2 = isfn_d1;
418 #endif /* defined(USE_LIB_IS_FILE_NAMED) */