|
Packit Service |
603f59 |
/*
|
|
Packit Service |
603f59 |
* rnmh.c -- functions to read BSD format name cache information from a
|
|
Packit Service |
603f59 |
* kernel hash table
|
|
Packit Service |
603f59 |
*/
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
/*
|
|
Packit Service |
603f59 |
* Copyright 1997 Purdue Research Foundation, West Lafayette, Indiana
|
|
Packit Service |
603f59 |
* 47907. All rights reserved.
|
|
Packit Service |
603f59 |
*
|
|
Packit Service |
603f59 |
* Written by Victor A. Abell
|
|
Packit Service |
603f59 |
*
|
|
Packit Service |
603f59 |
* This software is not subject to any license of the American Telephone
|
|
Packit Service |
603f59 |
* and Telegraph Company or the Regents of the University of California.
|
|
Packit Service |
603f59 |
*
|
|
Packit Service |
603f59 |
* Permission is granted to anyone to use this software for any purpose on
|
|
Packit Service |
603f59 |
* any computer system, and to alter it and redistribute it freely, subject
|
|
Packit Service |
603f59 |
* to the following restrictions:
|
|
Packit Service |
603f59 |
*
|
|
Packit Service |
603f59 |
* 1. Neither the authors nor Purdue University are responsible for any
|
|
Packit Service |
603f59 |
* consequences of the use of this software.
|
|
Packit Service |
603f59 |
*
|
|
Packit Service |
603f59 |
* 2. The origin of this software must not be misrepresented, either by
|
|
Packit Service |
603f59 |
* explicit claim or by omission. Credit to the authors and Purdue
|
|
Packit Service |
603f59 |
* University must appear in documentation and sources.
|
|
Packit Service |
603f59 |
*
|
|
Packit Service |
603f59 |
* 3. Altered versions must be plainly marked as such, and must not be
|
|
Packit Service |
603f59 |
* misrepresented as being the original software.
|
|
Packit Service |
603f59 |
*
|
|
Packit Service |
603f59 |
* 4. This notice may not be removed or altered.
|
|
Packit Service |
603f59 |
*/
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
#include "../machine.h"
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
#if defined(HASNCACHE) && defined(USE_LIB_RNMH)
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
# if !defined(lint)
|
|
Packit Service |
603f59 |
static char copyright[] =
|
|
Packit Service |
603f59 |
"@(#) Copyright 1997 Purdue Research Foundation.\nAll rights reserved.\n";
|
|
Packit Service |
603f59 |
static char *rcsid = "$Id: rnmh.c,v 1.13 2008/10/21 16:13:23 abe Exp $";
|
|
Packit Service |
603f59 |
# endif /* !defined(lint) */
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
#include "../lsof.h"
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
/*
|
|
Packit Service |
603f59 |
* rnmh.c - read BSD format hashed kernel name cache
|
|
Packit Service |
603f59 |
*/
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
/*
|
|
Packit Service |
603f59 |
* The caller must:
|
|
Packit Service |
603f59 |
*
|
|
Packit Service |
603f59 |
* #include the relevant header file -- e.g., <sys/namei.h>.
|
|
Packit Service |
603f59 |
*
|
|
Packit Service |
603f59 |
* Define X_NCACHE as the nickname for the kernel cache hash tables
|
|
Packit Service |
603f59 |
* address.
|
|
Packit Service |
603f59 |
*
|
|
Packit Service |
603f59 |
* Define X_NCSIZE as the nickname for the size of the kernel cache has
|
|
Packit Service |
603f59 |
* table length.
|
|
Packit Service |
603f59 |
*
|
|
Packit Service |
603f59 |
* Define NCACHE_NO_ROOT if the calling dialect doesn't support
|
|
Packit Service |
603f59 |
* the locating of the root node of a file system.
|
|
Packit Service |
603f59 |
*
|
|
Packit Service |
603f59 |
* Define the name of the name cache structure -- e.g.,
|
|
Packit Service |
603f59 |
*
|
|
Packit Service |
603f59 |
* #define NCACHE <structure name>
|
|
Packit Service |
603f59 |
*
|
|
Packit Service |
603f59 |
*
|
|
Packit Service |
603f59 |
* Define the following casts, if they differ from the defaults:
|
|
Packit Service |
603f59 |
*
|
|
Packit Service |
603f59 |
* NCACHE_SZ_CAST case for X_NCSIZE (default unsigned long)
|
|
Packit Service |
603f59 |
*
|
|
Packit Service |
603f59 |
* Define the names of these elements of struct NCACHE:
|
|
Packit Service |
603f59 |
*
|
|
Packit Service |
603f59 |
* #define NCACHE_NM <name>
|
|
Packit Service |
603f59 |
* #define NCACHE_NXT <link to next entry>
|
|
Packit Service |
603f59 |
* #define NCACHE_NODEADDR <node address>
|
|
Packit Service |
603f59 |
* #define NCACHE_PARADDR <parent node address>
|
|
Packit Service |
603f59 |
*
|
|
Packit Service |
603f59 |
* Optionally define:
|
|
Packit Service |
603f59 |
*
|
|
Packit Service |
603f59 |
* #define NCACHE_NMLEN <name length>
|
|
Packit Service |
603f59 |
*
|
|
Packit Service |
603f59 |
* Optionally define *both*:
|
|
Packit Service |
603f59 |
*
|
|
Packit Service |
603f59 |
* #define NCACHE_NODEID <node capability ID>
|
|
Packit Service |
603f59 |
* #define NCACHE_PARID <parent node capability ID>
|
|
Packit Service |
603f59 |
*
|
|
Packit Service |
603f59 |
* The caller may need to:
|
|
Packit Service |
603f59 |
*
|
|
Packit Service |
603f59 |
* Define this prototype for ncache_load():
|
|
Packit Service |
603f59 |
*
|
|
Packit Service |
603f59 |
* _PROTOTYPE(static void ncache_load,(void));
|
|
Packit Service |
603f59 |
*
|
|
Packit Service |
603f59 |
* Define NCACHE_VROOT to be the value of the flag that signifies that
|
|
Packit Service |
603f59 |
* the vnode is the root of its file system.
|
|
Packit Service |
603f59 |
*
|
|
Packit Service |
603f59 |
* E.g., for BSDI >= 5:
|
|
Packit Service |
603f59 |
*
|
|
Packit Service |
603f59 |
* #define NCACHE_VROOT VV_ROOT
|
|
Packit Service |
603f59 |
*
|
|
Packit Service |
603f59 |
* If not defined, NCACHE_VROOT is defined as "VROOT".
|
|
Packit Service |
603f59 |
*
|
|
Packit Service |
603f59 |
* Define VNODE_VFLAG if the vnode's flag member's name isn't v_flag.
|
|
Packit Service |
603f59 |
*
|
|
Packit Service |
603f59 |
* Note: if NCHNAMLEN is defined, the name is assumed to be in
|
|
Packit Service |
603f59 |
* NCACHE_NM[NCHNAMLEN]; if it isn't defined, the name is assumed to be in an
|
|
Packit Service |
603f59 |
* extension that begins at NCACHE_NM[0].
|
|
Packit Service |
603f59 |
*
|
|
Packit Service |
603f59 |
* Note: if NCACHE_NMLEN is not defined, then NCACHE_NM must be a pointer to
|
|
Packit Service |
603f59 |
* a kernel allocated, NUL-terminated, string buffer.
|
|
Packit Service |
603f59 |
*/
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
/*
|
|
Packit Service |
603f59 |
* Casts
|
|
Packit Service |
603f59 |
*/
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
# if !defined(NCACHE_NC_CAST)
|
|
Packit Service |
603f59 |
#define NCACHE_SZ_CAST unsigned long
|
|
Packit Service |
603f59 |
# endif /* !defined(NCACHE_NC_CAST) */
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
/*
|
|
Packit Service |
603f59 |
* Flags
|
|
Packit Service |
603f59 |
*/
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
# if !defined(NCACHE_NMLEN)
|
|
Packit Service |
603f59 |
#undef NCHNAMLEN
|
|
Packit Service |
603f59 |
# endif /* !defined(NCACHE_NMLEN) */
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
# if !defined(NCACHE_VROOT)
|
|
Packit Service |
603f59 |
#define NCACHE_VROOT VROOT /* vnode is root of its file system */
|
|
Packit Service |
603f59 |
# endif /* !defined(NCACHE_VROOT) */
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
# if !defined(VNODE_VFLAG)
|
|
Packit Service |
603f59 |
#define VNODE_VFLAG v_flag
|
|
Packit Service |
603f59 |
# endif /* !defined(VNODE_VFLAG) */
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
/*
|
|
Packit Service |
603f59 |
* Local static values
|
|
Packit Service |
603f59 |
*/
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
static int Mch; /* name cache hash mask */
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
struct l_nch {
|
|
Packit Service |
603f59 |
KA_T na; /* node address */
|
|
Packit Service |
603f59 |
KA_T pa; /* parent node address */
|
|
Packit Service |
603f59 |
struct l_nch *pla; /* parent local node address */
|
|
Packit Service |
603f59 |
int nl; /* name length */
|
|
Packit Service |
603f59 |
struct l_nch *next; /* next entry */
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
# if defined(NCACHE_NODEID)
|
|
Packit Service |
603f59 |
unsigned long id; /* capability ID */
|
|
Packit Service |
603f59 |
unsigned long did; /* parent capability ID */
|
|
Packit Service |
603f59 |
# endif /* defined(NCACHE_NODEID) */
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
# if defined(NCHNAMLEN)
|
|
Packit Service |
603f59 |
char nm[NCHNAMLEN + 1]; /* name */
|
|
Packit Service |
603f59 |
# else /* !defined(NCHNAMLEN) */
|
|
Packit Service |
603f59 |
char nm[1]; /* variable length name */
|
|
Packit Service |
603f59 |
# endif /* defined(NCHNAMLEN) */
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
};
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
static struct l_nch *Ncache = (struct l_nch *)NULL;
|
|
Packit Service |
603f59 |
/* the head of the local name cache */
|
|
Packit Service |
603f59 |
static struct l_nch **Nchash = (struct l_nch **)NULL;
|
|
Packit Service |
603f59 |
/* Ncache hash pointers */
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
# if defined(NCACHE_NODEID)
|
|
Packit Service |
603f59 |
#define ncachehash(i,n) Nchash+(((((int)(n)>>2)+((int)(i)))*31415)&Mch)
|
|
Packit Service |
603f59 |
_PROTOTYPE(static struct l_nch *ncache_addr,(unsigned long i, KA_T na));
|
|
Packit Service |
603f59 |
# else /* !defined(NCACHE_NODEID) */
|
|
Packit Service |
603f59 |
#define ncachehash(n) Nchash+((((int)(n)>>2)*31415)&Mch)
|
|
Packit Service |
603f59 |
_PROTOTYPE(static struct l_nch *ncache_addr,(KA_T na));
|
|
Packit Service |
603f59 |
# endif /* defined(NCACHE_NODEID) */
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
# if !defined(NCACHE_NO_ROOT)
|
|
Packit Service |
603f59 |
_PROTOTYPE(static int ncache_isroot,(KA_T na, char *cp));
|
|
Packit Service |
603f59 |
# endif /* !defined(NCACHE_NO_ROOT) */
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
/*
|
|
Packit Service |
603f59 |
* ncache_addr() - look up a node's local ncache address
|
|
Packit Service |
603f59 |
*/
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
static struct l_nch *
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
# if defined(NCACHE_NODEID)
|
|
Packit Service |
603f59 |
ncache_addr(i, na)
|
|
Packit Service |
603f59 |
unsigned long i; /* node's capability ID */
|
|
Packit Service |
603f59 |
# else /* !defined(NCACHE_NODEID) */
|
|
Packit Service |
603f59 |
ncache_addr(na)
|
|
Packit Service |
603f59 |
# endif /* defined(NCACHE_NODEID) */
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
KA_T na; /* node's address */
|
|
Packit Service |
603f59 |
{
|
|
Packit Service |
603f59 |
struct l_nch **hp;
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
# if defined(NCACHE_NODEID)
|
|
Packit Service |
603f59 |
for (hp = ncachehash(i, na); *hp; hp++)
|
|
Packit Service |
603f59 |
# else /* !defined(NCACHE_NODEID) */
|
|
Packit Service |
603f59 |
for (hp = ncachehash(na); *hp; hp++)
|
|
Packit Service |
603f59 |
# endif /* defined(NCACHE_NODEID) */
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
{
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
# if defined(NCACHE_NODEID)
|
|
Packit Service |
603f59 |
if ((*hp)->id == i && (*hp)->na == na)
|
|
Packit Service |
603f59 |
# else /* !defined(NCACHE_NODEID) */
|
|
Packit Service |
603f59 |
if ((*hp)->na == na)
|
|
Packit Service |
603f59 |
# endif /* defined(NCACHE_NODEID) */
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
return(*hp);
|
|
Packit Service |
603f59 |
}
|
|
Packit Service |
603f59 |
return((struct l_nch *)NULL);
|
|
Packit Service |
603f59 |
}
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
# if !defined(NCACHE_NO_ROOT)
|
|
Packit Service |
603f59 |
/*
|
|
Packit Service |
603f59 |
* ncache_isroot() - is head of name cache path a file system root?
|
|
Packit Service |
603f59 |
*/
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
static int
|
|
Packit Service |
603f59 |
ncache_isroot(na, cp)
|
|
Packit Service |
603f59 |
KA_T na; /* kernel node address */
|
|
Packit Service |
603f59 |
char *cp; /* partial path */
|
|
Packit Service |
603f59 |
{
|
|
Packit Service |
603f59 |
char buf[MAXPATHLEN];
|
|
Packit Service |
603f59 |
int i;
|
|
Packit Service |
603f59 |
MALLOC_S len;
|
|
Packit Service |
603f59 |
struct mounts *mtp;
|
|
Packit Service |
603f59 |
static int nca = 0;
|
|
Packit Service |
603f59 |
static int ncn = 0;
|
|
Packit Service |
603f59 |
static KA_T *nc = (KA_T *)NULL;
|
|
Packit Service |
603f59 |
struct stat sb;
|
|
Packit Service |
603f59 |
struct vnode v;
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
if (!na)
|
|
Packit Service |
603f59 |
return(0);
|
|
Packit Service |
603f59 |
/*
|
|
Packit Service |
603f59 |
* Search the root vnode cache.
|
|
Packit Service |
603f59 |
*/
|
|
Packit Service |
603f59 |
for (i = 0; i < ncn; i++) {
|
|
Packit Service |
603f59 |
if (na == nc[i])
|
|
Packit Service |
603f59 |
return(1);
|
|
Packit Service |
603f59 |
}
|
|
Packit Service |
603f59 |
/*
|
|
Packit Service |
603f59 |
* Read the vnode and see if it's a VDIR node with the NCACHE_VROOT flag set.
|
|
Packit Service |
603f59 |
* If it is, then the path is complete.
|
|
Packit Service |
603f59 |
*
|
|
Packit Service |
603f59 |
* If it isn't, and if the file has an inode number, search the mount table
|
|
Packit Service |
603f59 |
* and see if the file system's inode number is known. If it is, form the
|
|
Packit Service |
603f59 |
* possible full path, safely stat() it, and see if it's inode number matches
|
|
Packit Service |
603f59 |
* the one we have for this file. If it does, then the path is complete.
|
|
Packit Service |
603f59 |
*/
|
|
Packit Service |
603f59 |
if (kread((KA_T)na, (char *)&v, sizeof(v))
|
|
Packit Service |
603f59 |
|| v.v_type != VDIR || !(v.VNODE_VFLAG & NCACHE_VROOT)) {
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
/*
|
|
Packit Service |
603f59 |
* The vnode tests failed. Try the inode tests.
|
|
Packit Service |
603f59 |
*/
|
|
Packit Service |
603f59 |
if (Lf->inp_ty != 1 || !Lf->inode
|
|
Packit Service |
603f59 |
|| !Lf->fsdir || (len = strlen(Lf->fsdir)) < 1)
|
|
Packit Service |
603f59 |
return(0);
|
|
Packit Service |
603f59 |
if ((len + 1 + strlen(cp) + 1) > sizeof(buf))
|
|
Packit Service |
603f59 |
return(0);
|
|
Packit Service |
603f59 |
for (mtp = readmnt(); mtp; mtp = mtp->next) {
|
|
Packit Service |
603f59 |
if (!mtp->dir || !mtp->inode)
|
|
Packit Service |
603f59 |
continue;
|
|
Packit Service |
603f59 |
if (strcmp(Lf->fsdir, mtp->dir) == 0)
|
|
Packit Service |
603f59 |
break;
|
|
Packit Service |
603f59 |
}
|
|
Packit Service |
603f59 |
if (!mtp)
|
|
Packit Service |
603f59 |
return(0);
|
|
Packit Service |
603f59 |
(void) strcpy(buf, Lf->fsdir);
|
|
Packit Service |
603f59 |
if (buf[len - 1] != '/')
|
|
Packit Service |
603f59 |
buf[len++] = '/';
|
|
Packit Service |
603f59 |
(void) strcpy(&buf[len], cp);
|
|
Packit Service |
603f59 |
if (statsafely(buf, &sb) != 0
|
|
Packit Service |
603f59 |
|| (unsigned long)sb.st_ino != Lf->inode)
|
|
Packit Service |
603f59 |
return(0);
|
|
Packit Service |
603f59 |
}
|
|
Packit Service |
603f59 |
/*
|
|
Packit Service |
603f59 |
* Add the node address to the root node cache.
|
|
Packit Service |
603f59 |
*/
|
|
Packit Service |
603f59 |
if (ncn >= nca) {
|
|
Packit Service |
603f59 |
if (!nca) {
|
|
Packit Service |
603f59 |
len = (MALLOC_S)(10 * sizeof(KA_T));
|
|
Packit Service |
603f59 |
nc = (KA_T *)malloc(len);
|
|
Packit Service |
603f59 |
} else {
|
|
Packit Service |
603f59 |
len = (MALLOC_S)((nca + 10) * sizeof(KA_T));
|
|
Packit Service |
603f59 |
nc = (KA_T *)realloc(nc, len);
|
|
Packit Service |
603f59 |
}
|
|
Packit Service |
603f59 |
if (!nc) {
|
|
Packit Service |
603f59 |
(void) fprintf(stderr, "%s: no space for root node table\n",
|
|
Packit Service |
603f59 |
Pn);
|
|
Packit Service |
603f59 |
Exit(1);
|
|
Packit Service |
603f59 |
}
|
|
Packit Service |
603f59 |
nca += 10;
|
|
Packit Service |
603f59 |
}
|
|
Packit Service |
603f59 |
nc[ncn++] = na;
|
|
Packit Service |
603f59 |
return(1);
|
|
Packit Service |
603f59 |
}
|
|
Packit Service |
603f59 |
# endif /* !defined(NCACHE_NO_ROOT) */
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
/*
|
|
Packit Service |
603f59 |
* ncache_load() - load the kernel's name cache
|
|
Packit Service |
603f59 |
*/
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
void
|
|
Packit Service |
603f59 |
ncache_load()
|
|
Packit Service |
603f59 |
{
|
|
Packit Service |
603f59 |
struct NCACHE c;
|
|
Packit Service |
603f59 |
struct l_nch **hp, *ln;
|
|
Packit Service |
603f59 |
KA_T ka, knx;
|
|
Packit Service |
603f59 |
static struct NCACHE **khp = (struct namecache **)NULL;
|
|
Packit Service |
603f59 |
static int khpl = 0;
|
|
Packit Service |
603f59 |
NCACHE_SZ_CAST khsz;
|
|
Packit Service |
603f59 |
unsigned long kx;
|
|
Packit Service |
603f59 |
static struct l_nch *lc = (struct l_nch *)NULL;
|
|
Packit Service |
603f59 |
static int lcl = 0;
|
|
Packit Service |
603f59 |
int len, lim, n, nch, nchl, nlcl;
|
|
Packit Service |
603f59 |
char tbuf[32];
|
|
Packit Service |
603f59 |
KA_T v;
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
# if !defined(NCHNAMLEN)
|
|
Packit Service |
603f59 |
int cin = sizeof(c.NCACHE_NM);
|
|
Packit Service |
603f59 |
KA_T nmo = (KA_T)offsetof(struct NCACHE, NCACHE_NM);
|
|
Packit Service |
603f59 |
# endif /* !defined(NCHNAMLEN) */
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
# if !defined(NCACHE_NMLEN)
|
|
Packit Service |
603f59 |
char nbf[MAXPATHLEN + 1];
|
|
Packit Service |
603f59 |
int nbfl = (int)(sizeof(nbf) - 1);
|
|
Packit Service |
603f59 |
KA_T nk;
|
|
Packit Service |
603f59 |
char *np;
|
|
Packit Service |
603f59 |
int rl;
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
nbf[nbfl] = '\0';
|
|
Packit Service |
603f59 |
# endif /* !defined(NCACHE_NMLEN) */
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
if (!Fncache)
|
|
Packit Service |
603f59 |
return;
|
|
Packit Service |
603f59 |
/*
|
|
Packit Service |
603f59 |
* Free previously allocated space.
|
|
Packit Service |
603f59 |
*/
|
|
Packit Service |
603f59 |
for (lc = Ncache; lc; lc = ln) {
|
|
Packit Service |
603f59 |
ln = lc->next;
|
|
Packit Service |
603f59 |
(void) free((FREE_P *)lc);
|
|
Packit Service |
603f59 |
}
|
|
Packit Service |
603f59 |
Ncache = (struct l_nch *)NULL;
|
|
Packit Service |
603f59 |
if (Nchash)
|
|
Packit Service |
603f59 |
(void) free((FREE_P *)Nchash);
|
|
Packit Service |
603f59 |
Nchash = (struct l_nch **)NULL;
|
|
Packit Service |
603f59 |
/*
|
|
Packit Service |
603f59 |
* Get kernel cache hash table size
|
|
Packit Service |
603f59 |
*/
|
|
Packit Service |
603f59 |
v = (KA_T)0;
|
|
Packit Service |
603f59 |
if (get_Nl_value(X_NCSIZE, (struct drive_Nl *)NULL, &v) < 0
|
|
Packit Service |
603f59 |
|| !v
|
|
Packit Service |
603f59 |
|| kread((KA_T)v, (char *)&khsz, sizeof(khsz)))
|
|
Packit Service |
603f59 |
{
|
|
Packit Service |
603f59 |
if (!Fwarn)
|
|
Packit Service |
603f59 |
(void) fprintf(stderr,
|
|
Packit Service |
603f59 |
"%s: WARNING: can't read name cache hash size: %s\n",
|
|
Packit Service |
603f59 |
Pn, print_kptr(v, (char *)NULL, 0));
|
|
Packit Service |
603f59 |
return;
|
|
Packit Service |
603f59 |
}
|
|
Packit Service |
603f59 |
if (khsz < 1) {
|
|
Packit Service |
603f59 |
if (!Fwarn)
|
|
Packit Service |
603f59 |
(void) fprintf(stderr,
|
|
Packit Service |
603f59 |
"%s: WARNING: name cache hash size length error: %#lx\n",
|
|
Packit Service |
603f59 |
Pn, khsz);
|
|
Packit Service |
603f59 |
return;
|
|
Packit Service |
603f59 |
}
|
|
Packit Service |
603f59 |
/*
|
|
Packit Service |
603f59 |
* Get kernel cache hash table address.
|
|
Packit Service |
603f59 |
*/
|
|
Packit Service |
603f59 |
ka = (KA_T)0;
|
|
Packit Service |
603f59 |
v = (KA_T)0;
|
|
Packit Service |
603f59 |
if (get_Nl_value(X_NCACHE, (struct drive_Nl *)NULL, &v) < 0
|
|
Packit Service |
603f59 |
|| !v
|
|
Packit Service |
603f59 |
|| kread((KA_T)v, (char *)&ka, sizeof(ka))
|
|
Packit Service |
603f59 |
|| !ka)
|
|
Packit Service |
603f59 |
{
|
|
Packit Service |
603f59 |
if (!Fwarn)
|
|
Packit Service |
603f59 |
(void) fprintf(stderr,
|
|
Packit Service |
603f59 |
"%s: WARNING: unusable name cache hash pointer: (%s)=%s\n",
|
|
Packit Service |
603f59 |
Pn, print_kptr(v, tbuf, sizeof(tbuf)),
|
|
Packit Service |
603f59 |
print_kptr(ka, (char *)NULL, 0));
|
|
Packit Service |
603f59 |
return;
|
|
Packit Service |
603f59 |
}
|
|
Packit Service |
603f59 |
/*
|
|
Packit Service |
603f59 |
* Allocate space for the hash table pointers and read them.
|
|
Packit Service |
603f59 |
*/
|
|
Packit Service |
603f59 |
len = (MALLOC_S)(khsz * sizeof(struct NCACHE *));
|
|
Packit Service |
603f59 |
if (len > khpl) {
|
|
Packit Service |
603f59 |
if (khp)
|
|
Packit Service |
603f59 |
khp = (struct NCACHE **)realloc((MALLOC_P *)khp, len);
|
|
Packit Service |
603f59 |
else
|
|
Packit Service |
603f59 |
khp = (struct NCACHE **)malloc(len);
|
|
Packit Service |
603f59 |
if (!khp) {
|
|
Packit Service |
603f59 |
(void) fprintf(stderr,
|
|
Packit Service |
603f59 |
"%s: can't allocate %d bytes for name cache hash table\n",
|
|
Packit Service |
603f59 |
Pn, len);
|
|
Packit Service |
603f59 |
Exit(1);
|
|
Packit Service |
603f59 |
}
|
|
Packit Service |
603f59 |
khpl = len;
|
|
Packit Service |
603f59 |
}
|
|
Packit Service |
603f59 |
if (kread((KA_T)ka, (char *)khp, len)) {
|
|
Packit Service |
603f59 |
(void) fprintf(stderr,
|
|
Packit Service |
603f59 |
"%s: can't read name cache hash pointers from: %s\n",
|
|
Packit Service |
603f59 |
Pn, print_kptr(ka, (char *)NULL, 0));
|
|
Packit Service |
603f59 |
return;
|
|
Packit Service |
603f59 |
}
|
|
Packit Service |
603f59 |
/*
|
|
Packit Service |
603f59 |
* Process the kernel's name cache hash table buckets.
|
|
Packit Service |
603f59 |
*/
|
|
Packit Service |
603f59 |
lim = khsz * 10;
|
|
Packit Service |
603f59 |
for (kx = nch = 0; kx < khsz; kx++) {
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
/*
|
|
Packit Service |
603f59 |
* Loop through the entries for a hash bucket.
|
|
Packit Service |
603f59 |
*/
|
|
Packit Service |
603f59 |
for (ka = (KA_T)khp[kx], n = 0; ka; ka = knx, n++) {
|
|
Packit Service |
603f59 |
if (n > lim) {
|
|
Packit Service |
603f59 |
if (!Fwarn)
|
|
Packit Service |
603f59 |
(void) fprintf(stderr,
|
|
Packit Service |
603f59 |
"%s: WARNING: name cache hash chain too long\n",
|
|
Packit Service |
603f59 |
Pn);
|
|
Packit Service |
603f59 |
break;
|
|
Packit Service |
603f59 |
}
|
|
Packit Service |
603f59 |
if (kread(ka, (char *)&c, sizeof(c)))
|
|
Packit Service |
603f59 |
break;
|
|
Packit Service |
603f59 |
knx = (KA_T)c.NCACHE_NXT;
|
|
Packit Service |
603f59 |
if (!c.NCACHE_NODEADDR)
|
|
Packit Service |
603f59 |
continue;
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
# if defined(NCACHE_NMLEN)
|
|
Packit Service |
603f59 |
if ((len = c.NCACHE_NMLEN) < 1)
|
|
Packit Service |
603f59 |
continue;
|
|
Packit Service |
603f59 |
# else /* !defined(NCACHE_NMLEN) */
|
|
Packit Service |
603f59 |
/*
|
|
Packit Service |
603f59 |
* If it's possible to read the first four characters of the name,
|
|
Packit Service |
603f59 |
* do so and check for "." and "..".
|
|
Packit Service |
603f59 |
*/
|
|
Packit Service |
603f59 |
if (!c.NCACHE_NM
|
|
Packit Service |
603f59 |
|| kread((KA_T)c.NCACHE_NM, nbf, 4))
|
|
Packit Service |
603f59 |
continue;
|
|
Packit Service |
603f59 |
if (nbf[0] == '.') {
|
|
Packit Service |
603f59 |
if (!nbf[1]
|
|
Packit Service |
603f59 |
|| ((nbf[1] == '.') && !nbf[2]))
|
|
Packit Service |
603f59 |
continue;
|
|
Packit Service |
603f59 |
}
|
|
Packit Service |
603f59 |
/*
|
|
Packit Service |
603f59 |
* Read the rest of the name, 32 characters at a time, until a NUL
|
|
Packit Service |
603f59 |
* character has been read or nbfl characters have been read.
|
|
Packit Service |
603f59 |
*/
|
|
Packit Service |
603f59 |
nbf[4] = '\0';
|
|
Packit Service |
603f59 |
if ((len = (int)strlen(nbf)) < 4) {
|
|
Packit Service |
603f59 |
if (!len)
|
|
Packit Service |
603f59 |
continue;
|
|
Packit Service |
603f59 |
} else {
|
|
Packit Service |
603f59 |
for (np = &nbf[4]; len < nbfl; np += rl) {
|
|
Packit Service |
603f59 |
if ((rl = nbfl - len) > 32) {
|
|
Packit Service |
603f59 |
rl = 32;
|
|
Packit Service |
603f59 |
nbf[len + rl] = '\0';
|
|
Packit Service |
603f59 |
}
|
|
Packit Service |
603f59 |
nk = (KA_T)((char *)c.NCACHE_NM + len);
|
|
Packit Service |
603f59 |
if (kread(nk, np, rl)) {
|
|
Packit Service |
603f59 |
rl = -1;
|
|
Packit Service |
603f59 |
break;
|
|
Packit Service |
603f59 |
}
|
|
Packit Service |
603f59 |
rl = (int)strlen(np);
|
|
Packit Service |
603f59 |
len += rl;
|
|
Packit Service |
603f59 |
if (rl < 32)
|
|
Packit Service |
603f59 |
break;
|
|
Packit Service |
603f59 |
}
|
|
Packit Service |
603f59 |
if (rl < 0)
|
|
Packit Service |
603f59 |
continue;
|
|
Packit Service |
603f59 |
}
|
|
Packit Service |
603f59 |
# endif /* defined(NCACHE_NMLEN) */
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
/*
|
|
Packit Service |
603f59 |
* Allocate a cache entry long enough to contain the name and
|
|
Packit Service |
603f59 |
* move the name to it.
|
|
Packit Service |
603f59 |
*/
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
# if defined(NCHNAMLEN)
|
|
Packit Service |
603f59 |
if (len > NCHNAMLEN)
|
|
Packit Service |
603f59 |
continue;
|
|
Packit Service |
603f59 |
if (len < 3 && c.NCACHE_NM[0] == '.') {
|
|
Packit Service |
603f59 |
if (len == 1 || (len == 2 && c.NCACHE_NM[1] == '.'))
|
|
Packit Service |
603f59 |
continue;
|
|
Packit Service |
603f59 |
}
|
|
Packit Service |
603f59 |
if ((nlcl = sizeof(struct l_nch)) > lcl)
|
|
Packit Service |
603f59 |
# else /* !defined(NCHNAMLEN) */
|
|
Packit Service |
603f59 |
if ((nlcl = sizeof(struct l_nch) + len) > lcl)
|
|
Packit Service |
603f59 |
# endif /* defined(NCHNAMLEN) */
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
{
|
|
Packit Service |
603f59 |
if (lc)
|
|
Packit Service |
603f59 |
lc = (struct l_nch *)realloc(lc, nlcl);
|
|
Packit Service |
603f59 |
else
|
|
Packit Service |
603f59 |
lc = (struct l_nch *)malloc(nlcl);
|
|
Packit Service |
603f59 |
if (!lc) {
|
|
Packit Service |
603f59 |
(void) fprintf(stderr,
|
|
Packit Service |
603f59 |
"%s: can't allocate %d local name cache bytes\n",
|
|
Packit Service |
603f59 |
Pn, nlcl);
|
|
Packit Service |
603f59 |
Exit(1);
|
|
Packit Service |
603f59 |
}
|
|
Packit Service |
603f59 |
lcl = nlcl;
|
|
Packit Service |
603f59 |
}
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
# if defined(NCHNAMLEN)
|
|
Packit Service |
603f59 |
(void) strncpy(lc->nm, c.NCACHE_NM, len);
|
|
Packit Service |
603f59 |
# else /* !defined(NCHNAMLEN) */
|
|
Packit Service |
603f59 |
# if defined(NCACHE_NMLEN)
|
|
Packit Service |
603f59 |
if ((len < 3) && (cin > 1)) {
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
/*
|
|
Packit Service |
603f59 |
* If this is a one or two character name, and if NCACHE_NM[]
|
|
Packit Service |
603f59 |
* in c has room for at least two characters, check for "."
|
|
Packit Service |
603f59 |
* and ".." first, ignoring this entry if the name is either.
|
|
Packit Service |
603f59 |
*/
|
|
Packit Service |
603f59 |
if (len < 3 && c.NCACHE_NM[0] == '.') {
|
|
Packit Service |
603f59 |
if (len == 1 || (len == 2 && c.NCACHE_NM[1] == '.'))
|
|
Packit Service |
603f59 |
continue;
|
|
Packit Service |
603f59 |
}
|
|
Packit Service |
603f59 |
}
|
|
Packit Service |
603f59 |
if (len > cin) {
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
/*
|
|
Packit Service |
603f59 |
* If not all (possibly not any, depending on the value in
|
|
Packit Service |
603f59 |
* cin) of the name has yet been read to lc->nm[], read it
|
|
Packit Service |
603f59 |
* or the rest of it. If it wasn't possible before to check
|
|
Packit Service |
603f59 |
* for "." or "..", do that. too.
|
|
Packit Service |
603f59 |
*/
|
|
Packit Service |
603f59 |
if (cin > 0)
|
|
Packit Service |
603f59 |
(void) strncpy(lc->nm, c.NCACHE_NM, cin);
|
|
Packit Service |
603f59 |
if (kread(ka + (KA_T)(nmo + cin), &lc->nm[cin], len - cin))
|
|
Packit Service |
603f59 |
continue;
|
|
Packit Service |
603f59 |
if ((cin < 2) && (len < 3) && (lc->nm[0] == '.')) {
|
|
Packit Service |
603f59 |
if (len == 1 || (len == 2 && lc->nm[1] == '.'))
|
|
Packit Service |
603f59 |
continue;
|
|
Packit Service |
603f59 |
}
|
|
Packit Service |
603f59 |
} else
|
|
Packit Service |
603f59 |
(void) strncpy(lc->nm, c.NCACHE_NM, len);
|
|
Packit Service |
603f59 |
# else /* !defined(NCACHE_NMLEN) */
|
|
Packit Service |
603f59 |
(void) strncpy(lc->nm, nbf, len);
|
|
Packit Service |
603f59 |
# endif /* defined(NCACHE_NMLEN) */
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
# endif /* defined(NCHNAMLEN) */
|
|
Packit Service |
603f59 |
lc->nm[len] = '\0';
|
|
Packit Service |
603f59 |
/*
|
|
Packit Service |
603f59 |
* Complete the new local cache entry and link it to the previous
|
|
Packit Service |
603f59 |
* local cache chain.
|
|
Packit Service |
603f59 |
*/
|
|
Packit Service |
603f59 |
lc->next = Ncache;
|
|
Packit Service |
603f59 |
Ncache = lc;
|
|
Packit Service |
603f59 |
lc->na = (KA_T)c.NCACHE_NODEADDR;
|
|
Packit Service |
603f59 |
lc->nl = len;
|
|
Packit Service |
603f59 |
lc->pa = (KA_T)c.NCACHE_PARADDR;
|
|
Packit Service |
603f59 |
lc->pla = (struct l_nch *)NULL;
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
# if defined(NCACHE_NODEID)
|
|
Packit Service |
603f59 |
lc->id = c.NCACHE_NODEID;
|
|
Packit Service |
603f59 |
lc->did = c.NCACHE_PARID;
|
|
Packit Service |
603f59 |
# endif /* defined(NCACHE_NODEID) */
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
lcl = 0;
|
|
Packit Service |
603f59 |
lc = (struct l_nch *)NULL;
|
|
Packit Service |
603f59 |
nch++;
|
|
Packit Service |
603f59 |
}
|
|
Packit Service |
603f59 |
}
|
|
Packit Service |
603f59 |
/*
|
|
Packit Service |
603f59 |
* Reduce memory usage, as required.
|
|
Packit Service |
603f59 |
*/
|
|
Packit Service |
603f59 |
if (!RptTm) {
|
|
Packit Service |
603f59 |
(void) free((FREE_P *)khp);
|
|
Packit Service |
603f59 |
khp = (struct NCACHE **)NULL;
|
|
Packit Service |
603f59 |
khpl = 0;
|
|
Packit Service |
603f59 |
}
|
|
Packit Service |
603f59 |
if (nch < 1) {
|
|
Packit Service |
603f59 |
if (!Fwarn)
|
|
Packit Service |
603f59 |
(void) fprintf(stderr,
|
|
Packit Service |
603f59 |
"%s: WARNING: unusable name cache size: %d\n", Pn, nch);
|
|
Packit Service |
603f59 |
return;
|
|
Packit Service |
603f59 |
}
|
|
Packit Service |
603f59 |
/*
|
|
Packit Service |
603f59 |
* Build a hash table to locate Ncache entries.
|
|
Packit Service |
603f59 |
*/
|
|
Packit Service |
603f59 |
for (nchl = 1; nchl < nch; nchl <<= 1)
|
|
Packit Service |
603f59 |
;
|
|
Packit Service |
603f59 |
nchl <<= 1;
|
|
Packit Service |
603f59 |
Mch = nchl - 1;
|
|
Packit Service |
603f59 |
len = nchl + nch;
|
|
Packit Service |
603f59 |
if (!(Nchash = (struct l_nch **)calloc(len, sizeof(struct l_nch *)))) {
|
|
Packit Service |
603f59 |
if (!Fwarn)
|
|
Packit Service |
603f59 |
(void) fprintf(stderr,
|
|
Packit Service |
603f59 |
"%s: no space for %d local name cache hash pointers\n",
|
|
Packit Service |
603f59 |
Pn, len);
|
|
Packit Service |
603f59 |
Exit(1);
|
|
Packit Service |
603f59 |
}
|
|
Packit Service |
603f59 |
for (lc = Ncache; lc; lc = lc->next) {
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
# if defined(NCACHE_NODEID)
|
|
Packit Service |
603f59 |
for (hp = ncachehash(lc->id, lc->na),
|
|
Packit Service |
603f59 |
# else /* !defined(NCACHE_NODEID) */
|
|
Packit Service |
603f59 |
for (hp = ncachehash(lc->na),
|
|
Packit Service |
603f59 |
# endif /* defined(NCACHE_NODEID) */
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
n = 1; *hp; hp++)
|
|
Packit Service |
603f59 |
{
|
|
Packit Service |
603f59 |
if ((*hp)->na == lc->na && strcmp((*hp)->nm, lc->nm) == 0) {
|
|
Packit Service |
603f59 |
n = 0;
|
|
Packit Service |
603f59 |
break;
|
|
Packit Service |
603f59 |
}
|
|
Packit Service |
603f59 |
}
|
|
Packit Service |
603f59 |
if (n)
|
|
Packit Service |
603f59 |
*hp = lc;
|
|
Packit Service |
603f59 |
else
|
|
Packit Service |
603f59 |
lc->pa = (KA_T)0;
|
|
Packit Service |
603f59 |
}
|
|
Packit Service |
603f59 |
/*
|
|
Packit Service |
603f59 |
* Make a final pass through the local cache and convert parent node
|
|
Packit Service |
603f59 |
* addresses to local name cache pointers.
|
|
Packit Service |
603f59 |
*/
|
|
Packit Service |
603f59 |
for (lc = Ncache; lc; lc = lc->next) {
|
|
Packit Service |
603f59 |
if (!lc->pa)
|
|
Packit Service |
603f59 |
continue;
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
# if defined(NCACHE_NODEID)
|
|
Packit Service |
603f59 |
lc->pla = ncache_addr(lc->did, lc->pa);
|
|
Packit Service |
603f59 |
# else /* !defined(NCACHE_NODEID) */
|
|
Packit Service |
603f59 |
lc->pla = ncache_addr(lc->pa);
|
|
Packit Service |
603f59 |
# endif /* defined(NCACHE_NODEID) */
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
}
|
|
Packit Service |
603f59 |
}
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
/*
|
|
Packit Service |
603f59 |
* ncache_lookup() - look up a node's name in the kernel's name cache
|
|
Packit Service |
603f59 |
*/
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
char *
|
|
Packit Service |
603f59 |
ncache_lookup(buf, blen, fp)
|
|
Packit Service |
603f59 |
char *buf; /* receiving name buffer */
|
|
Packit Service |
603f59 |
int blen; /* receiving buffer length */
|
|
Packit Service |
603f59 |
int *fp; /* full path reply */
|
|
Packit Service |
603f59 |
{
|
|
Packit Service |
603f59 |
char *cp = buf;
|
|
Packit Service |
603f59 |
struct l_nch *lc;
|
|
Packit Service |
603f59 |
struct mounts *mtp;
|
|
Packit Service |
603f59 |
int nl, rlen;
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
*cp = '\0';
|
|
Packit Service |
603f59 |
*fp = 0;
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
# if defined(HASFSINO)
|
|
Packit Service |
603f59 |
/*
|
|
Packit Service |
603f59 |
* If the entry has an inode number that matches the inode number of the
|
|
Packit Service |
603f59 |
* file system mount point, return an empty path reply. That tells the
|
|
Packit Service |
603f59 |
* caller to print the file system mount point name only.
|
|
Packit Service |
603f59 |
*/
|
|
Packit Service |
603f59 |
if ((Lf->inp_ty == 1) && Lf->fs_ino && (Lf->inode == Lf->fs_ino))
|
|
Packit Service |
603f59 |
return(cp);
|
|
Packit Service |
603f59 |
# endif /* defined(HASFSINO) */
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
/*
|
|
Packit Service |
603f59 |
* Look up the name cache entry for the node address.
|
|
Packit Service |
603f59 |
*/
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
# if defined(NCACHE_NODEID)
|
|
Packit Service |
603f59 |
if (!Nchash || !(lc = ncache_addr(Lf->id, Lf->na)))
|
|
Packit Service |
603f59 |
# else /* !defined(NCACHE_NODEID) */
|
|
Packit Service |
603f59 |
if (!Nchash || !(lc = ncache_addr(Lf->na)))
|
|
Packit Service |
603f59 |
# endif /* defined(NCACHE_NODEID) */
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
{
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
/*
|
|
Packit Service |
603f59 |
* If the node has no cache entry, see if it's the mount
|
|
Packit Service |
603f59 |
* point of a known file system.
|
|
Packit Service |
603f59 |
*/
|
|
Packit Service |
603f59 |
if (!Lf->fsdir || !Lf->dev_def || Lf->inp_ty != 1)
|
|
Packit Service |
603f59 |
return((char *)NULL);
|
|
Packit Service |
603f59 |
for (mtp = readmnt(); mtp; mtp = mtp->next) {
|
|
Packit Service |
603f59 |
if (!mtp->dir || !mtp->inode)
|
|
Packit Service |
603f59 |
continue;
|
|
Packit Service |
603f59 |
if (Lf->dev == mtp->dev
|
|
Packit Service |
603f59 |
&& mtp->inode == Lf->inode
|
|
Packit Service |
603f59 |
&& (strcmp(mtp->dir, Lf->fsdir) == 0))
|
|
Packit Service |
603f59 |
return(cp);
|
|
Packit Service |
603f59 |
}
|
|
Packit Service |
603f59 |
return((char *)NULL);
|
|
Packit Service |
603f59 |
}
|
|
Packit Service |
603f59 |
/*
|
|
Packit Service |
603f59 |
* Start the path assembly.
|
|
Packit Service |
603f59 |
*/
|
|
Packit Service |
603f59 |
if ((nl = lc->nl) > (blen - 1))
|
|
Packit Service |
603f59 |
return((char *)NULL);
|
|
Packit Service |
603f59 |
cp = buf + blen - nl - 1;
|
|
Packit Service |
603f59 |
rlen = blen - nl - 1;
|
|
Packit Service |
603f59 |
(void) strcpy(cp, lc->nm);
|
|
Packit Service |
603f59 |
/*
|
|
Packit Service |
603f59 |
* Look up the name cache entries that are parents of the node address.
|
|
Packit Service |
603f59 |
* Quit when:
|
|
Packit Service |
603f59 |
*
|
|
Packit Service |
603f59 |
* there's no parent;
|
|
Packit Service |
603f59 |
* the name length is too large to fit in the receiving buffer.
|
|
Packit Service |
603f59 |
*/
|
|
Packit Service |
603f59 |
for (;;) {
|
|
Packit Service |
603f59 |
if (!lc->pla) {
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
# if !defined(NCACHE_NO_ROOT)
|
|
Packit Service |
603f59 |
if (ncache_isroot(lc->pa, cp))
|
|
Packit Service |
603f59 |
*fp = 1;
|
|
Packit Service |
603f59 |
# endif /* !defined(NCACHE_NO_ROOT) */
|
|
Packit Service |
603f59 |
|
|
Packit Service |
603f59 |
break;
|
|
Packit Service |
603f59 |
}
|
|
Packit Service |
603f59 |
lc = lc->pla;
|
|
Packit Service |
603f59 |
if (((nl = lc->nl) + 1) > rlen)
|
|
Packit Service |
603f59 |
break;
|
|
Packit Service |
603f59 |
*(cp - 1) = '/';
|
|
Packit Service |
603f59 |
cp--;
|
|
Packit Service |
603f59 |
rlen--;
|
|
Packit Service |
603f59 |
(void) strncpy((cp - nl), lc->nm, nl);
|
|
Packit Service |
603f59 |
cp -= nl;
|
|
Packit Service |
603f59 |
rlen -= nl;
|
|
Packit Service |
603f59 |
}
|
|
Packit Service |
603f59 |
return(cp);
|
|
Packit Service |
603f59 |
}
|
|
Packit Service |
603f59 |
#else /* !defined(HASNCACHE) || !defined(USE_LIB_RNMH) */
|
|
Packit Service |
603f59 |
char rnmh_d1[] = "d"; char *rnmh_d2 = rnmh_d1;
|
|
Packit Service |
603f59 |
#endif /* defined(HASNCACHE) && defined(USE_LIB_RNMH) */
|