blob: 132b41a240c504261c9db2f1728c983e09d67f3b [file] [log] [blame]
/*
* dnode.c - /dev/kmem-based HP-UX node functions for lsof
*/
/*
* Copyright 1994 Purdue Research Foundation, West Lafayette, Indiana
* 47907. All rights reserved.
*
* Written by Victor A. Abell
*
* This software is not subject to any license of the American Telephone
* and Telegraph Company or the Regents of the University of California.
*
* Permission is granted to anyone to use this software for any purpose on
* any computer system, and to alter it and redistribute it freely, subject
* to the following restrictions:
*
* 1. Neither the authors nor Purdue University are responsible for any
* consequences of the use of this software.
*
* 2. The origin of this software must not be misrepresented, either by
* explicit claim or by omission. Credit to the authors and Purdue
* University must appear in documentation and sources.
*
* 3. Altered versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 4. This notice may not be removed or altered.
*/
#ifndef lint
static char copyright[] =
"@(#) Copyright 1994 Purdue Research Foundation.\nAll rights reserved.\n";
static char *rcsid = "$Id: dnode.c,v 1.21 2007/04/24 16:25:30 abe Exp $";
#endif
#if defined(HPUXKERNBITS) && HPUXKERNBITS>=64
#define _INO_T
typedef int ino_t;
#define _TIME_T
typedef int time_t;
#endif /* defined(HPUXKERNBITS) && HPUXKERNBITS>=64 */
#include "lsof.h"
#include <sys/inode.h>
#if HPUXV>=900
_PROTOTYPE(static void enter_nma,(char *b));
_PROTOTYPE(static int islocked,(KA_T lp));
#endif /* HPUXV>=900 */
_PROTOTYPE(static int getnodety,(struct vnode *v));
_PROTOTYPE(static int readinode,(KA_T ia, struct inode *i));
_PROTOTYPE(static int read_nmn,(KA_T na, KA_T ia, struct mvfsnode *m));
#if HPUXV>=900
/*
* enter_nma() - enter NAME column addition
*/
static void
enter_nma(b)
char *b; /* addition buffer */
{
if (Lf->nma)
return;
if (strlen(b) < 1)
return;
Lf->nma = mkstrcpy(b, (MALLOC_S *)NULL);
}
/*
* islocked() - is node locked?
*/
static int
islocked(lp)
KA_T lp; /* local locklist struct pointer */
{
static int ety = -1;
static unsigned int ei = 0;
static SZOFFTYPE el = 0;
int l;
struct locklist ll;
KA_T llf, llp;
if (!(llf = (KA_T)lp))
return((int)' ');
llp = llf;
/*
* Compute the end test value the first time through.
*/
if (ety == -1) {
# if HPUXV<1020
ety = 0;
ei = 0x7fffffff;
# else /* HPUXV>=1020 */
if (sizeof(ll.ll_end) == 4) {
ety = 0;
ei = 0x80000000;
} else {
ety = 1;
el = 0x10000000000ll;
}
# endif /* HPUXV<1020 */
}
/*
* Search the locklist chain for this process.
*/
do {
if (kread(llp, (char *)&ll, sizeof(ll)))
return((int)' ');
#if !defined(L_REMOTE)
#define L_REMOTE 0x1 /* from HP-UX 9.01 */
#endif /* !defined(L_REMOTE) */
# if HPUXV<1010
if (ll.ll_flags & L_REMOTE || ll.ll_proc != (KA_T)Kpa)
# else /* HPUXV>=1010 */
if (ll.ll_flags & L_REMOTE || (KA_T)ll.ll_kthreadp != Ktp)
# endif /* HPUXV<1010 */
continue;
l = 0;
if (ll.ll_start == 0) {
switch (ety) {
case 0:
if (ll.ll_end == ei)
l = 1;
break;
case 1:
if (ll.ll_end == el)
l = 1;
break;
}
}
if (ll.ll_type == F_WRLCK)
return((int)(l ? 'W' : 'w'));
else if (ll.ll_type == F_RDLCK)
return((int)(l ? 'R' : 'r'));
return((int)' ');
}
# if HPUXV<1010
while ((llp = (KA_T)ll.ll_link) && llp != llf);
# else /* HPUXV>=1010 */
while ((llp = (KA_T)ll.ll_fwd) && llp != llf);
# endif /* HPUXV<1010 */
return((int)' ');
}
#endif /* HPUXV>=900 */
/*
* getnodety() - get node type
*/
static int
getnodety(v)
struct vnode *v; /* local vnode copy */
{
#if defined(HAS_AFS)
static int afs = 0; /* AFS test status: -1 = no AFS
* 0 = not tested
* 1 = AFS present */
struct afsnode an;
#endif /* defined(HAS_AFS) */
static int ft = 1;
static KA_T avops;
static KA_T cvops;
static KA_T fvops;
static KA_T mvops;
static KA_T nvops;
static KA_T nvops3;
static KA_T nv3ops;
static KA_T pvops;
static KA_T svops;
static KA_T uvops;
static KA_T vvops;
/*
* Do first-time only operations.
*/
if (ft) {
if (get_Nl_value("avops", Drive_Nl, &avops) < 0)
avops = (unsigned long)0;
if (get_Nl_value("cvops", Drive_Nl, &cvops) < 0)
cvops = (unsigned long)0;
if (get_Nl_value("fvops", Drive_Nl, &fvops) < 0)
fvops = (unsigned long)0;
if (get_Nl_value("mvops", Drive_Nl, &mvops) < 0)
mvops = (unsigned long)0;
if (get_Nl_value("nvops", Drive_Nl, &nvops) < 0)
nvops = (unsigned long)0;
if (get_Nl_value("nvops3", Drive_Nl, &nvops3) < 0)
nvops3 = (unsigned long)0;
if (get_Nl_value("nv3ops", Drive_Nl, &nv3ops) < 0)
nv3ops = (unsigned long)0;
if (get_Nl_value("pvops", Drive_Nl, &pvops) < 0)
pvops = (unsigned long)0;
if (get_Nl_value("svops", Drive_Nl, &svops) < 0)
svops = (unsigned long)0;
if (get_Nl_value("uvops", Drive_Nl, &uvops) < 0)
uvops = (unsigned long)0;
if (get_Nl_value("vvops", Drive_Nl, &vvops) < 0)
vvops = (unsigned long)0;
ft = 0;
}
/*
* Determine the vnode type.
*/
if (uvops && uvops == (unsigned long)v->v_op)
return(N_REGLR);
else if (nvops && nvops == (unsigned long)v->v_op)
return(N_NFS);
else if (nvops3 && nvops3 == (unsigned long)v->v_op)
return(N_NFS);
else if (nv3ops && nv3ops == (unsigned long)v->v_op)
return(N_NFS);
else if (mvops && mvops == (unsigned long)v->v_op)
return(N_MVFS);
#if defined(HASVXFS)
else if (vvops && vvops == (unsigned long)v->v_op)
return(N_VXFS);
#endif /* defined(HASVXFS) */
#if HPUXV>=1000
else if (cvops && cvops == (unsigned long)v->v_op)
return(N_CDFS);
else if (fvops && fvops == (unsigned long)v->v_op)
return(N_FIFO);
else if (pvops && pvops == (unsigned long)v->v_op)
return(N_PIPE);
else if (svops && svops == (unsigned long)v->v_op)
return(N_SPEC);
#else /* HPUXV<1000 */
else if (v->v_type == VFIFO)
return(N_FIFO);
#endif /* HPUXV<1000 */
#if defined(HAS_AFS)
/*
* Caution: this AFS test should be the last one.
*/
else if (avops) {
if (avops == (unsigned long)v->v_op)
return(N_AFS);
else {
unknown_v_op:
(void) snpf(Namech, Namechl,
"unknown file system type; v_op: %s",
print_kptr((KA_T)v->v_op, (char *)NULL, 0));
enter_nm(Namech);
return(-1);
}
} else if (v->v_data || !v->v_vfsp)
goto unknown_v_op;
else {
switch (afs) {
case -1:
goto unknown_v_op;
case 0:
if (!hasAFS(v)) {
afs = -1;
goto unknown_v_op;
}
afs = 1;
return(N_AFS);
break;
case 1:
if (v->v_vfsp == AFSVfsp)
return(N_AFS);
else
goto unknown_v_op;
}
}
#else /* !defined(HAS_AFS) */
else {
(void) snpf(Namech, Namechl,
"unknown file system type; v_op: %s",
print_kptr((KA_T)v->v_op, (char *)NULL, 0));
enter_nm(Namech);
return(-1);
}
#endif /* defined(HAS_AFS) */
}
/*
* process_node() - process vnode
*/
void
process_node(va)
KA_T va; /* vnode kernel space address */
{
#if defined(HAS_AFS)
struct afsnode an;
#endif /* defined(HAS_AFS) */
dev_t dev, rdev;
int devs = 0;
struct inode i;
int ins = 0;
struct mvfsnode m;
struct rnode r;
int rdevs = 0;
int rns = 0;
char tbuf[32], *ty;
enum vtype type;
static struct vnode *v = (struct vnode *)NULL;
struct l_vfs *vfs;
int vty;
#if HPUXV>=900
char fb[128];
int fns = 0;
int rp, sz, wp;
struct vnode rv;
struct snode s;
#endif /* HPUXV>=900 */
#if HPUXV>=1000
struct cdnode c;
struct fifonode f;
struct vattr vat;
int vats = 0;
#endif /* HPUXV>=1000 */
/*
* Read the vnode.
*/
if ( ! va) {
enter_nm("no vnode address");
return;
}
if (!v) {
/*
* Allocate space for the vnode or AFS vcache structure.
*/
#if defined(HAS_AFS)
v = alloc_vcache();
#else /* !defined(HAS_AFS) */
v = (struct vnode *)malloc(sizeof(struct vnode));
#endif /* defined(HAS_AFS) */
if (!v) {
(void) fprintf(stderr, "%s: can't allocate %s space\n", Pn,
#if defined(HAS_AFS)
"vcache"
#else /* !defined(HAS_AFS) */
"vnode"
#endif /* defined(HAS_AFS) */
);
Exit(1);
}
}
if (readvnode(va, v)) {
enter_nm(Namech);
return;
}
#if defined(HASNCACHE)
Lf->na = va;
#endif /* defined(HASNCACHE) */
#if defined(HASFSTRUCT)
Lf->fna = va;
Lf->fsv |= FSV_NI;
#endif /* defined(HASFSTRUCT) */
/*
* Get the primary vnode type.
*/
vty = getnodety(v);
if (vty == -1)
return;
Ntype = vty;
/*
* Determine lock type.
*/
#if HPUXV<900
if (v->v_shlockc || v->v_exlockc) {
if (v->v_shlockc && v->v_exlockc)
Lf->lock = 'u';
else if (v->v_shlockc)
Lf->lock = 'R';
else
Lf->lock = 'W';
}
#else /* HPUXV>900 */
# if HPUXV>=1000
Lf->lock = (char)islocked((KA_T)v->v_locklist);
# endif /* HPUXV>=1000 */
#endif /* HPUXV<900 */
/*
* Establish the local virtual file system structure.
*/
if (!v->v_vfsp)
vfs = (struct l_vfs *)NULL;
else if (!(vfs = readvfs(v))) {
(void) snpf(Namech, Namechl, "can't read vfs for %s at %s",
print_kptr(va, tbuf, sizeof(tbuf)),
print_kptr((KA_T)v->v_vfsp, (char *)NULL, 0));
enter_nm(Namech);
return;
}
/*
* Read the cdnode, fifonode, inode, rnode, snode, or vache struct.
*/
switch (Ntype) {
#if defined(HAS_AFS)
case N_AFS:
if (readafsnode(va, v, &an))
return;
break;
#endif /* defined(HAS_AFS) */
#if defined(HASVXFS)
case N_VXFS:
if (!v->v_data || read_vxnode(v, vfs, &dev, &devs, &rdev, &rdevs)) {
(void) snpf(Namech, Namechl,
"vnode at %s: can't read vx_inode (%s)",
print_kptr(va, tbuf, sizeof(tbuf)),
print_kptr((KA_T)v->v_data, (char *)NULL, 0));
enter_nm(Namech);
return;
}
break;
#endif /* defined(HASVXFS) */
#if HPUXV>=1000
case N_CDFS:
if (!v->v_data
|| kread((KA_T)v->v_data, (char *)&c, sizeof(c))) {
(void) snpf(Namech, Namechl,
"vnode at %s: can't read cdnode (%s)",
print_kptr(va, tbuf, sizeof(tbuf)),
print_kptr((KA_T)v->v_data, (char *)NULL, 0));
enter_nm(Namech);
return;
}
break;
case N_FIFO:
case N_PIPE:
if (!v->v_data
|| kread((KA_T)v->v_data, (char *)&f, sizeof(f))) {
(void) snpf(Namech, Namechl,
"vnode at %s: can't read fifonode (%s)",
print_kptr(va, tbuf, sizeof(tbuf)),
print_kptr((KA_T)v->v_data, (char *)NULL, 0));
enter_nm(Namech);
return;
}
fns = 1;
if (f.fn_vap
&& kread((KA_T)f.fn_vap, (char *)&vat, sizeof(vat)) == 0)
vats = 1;
break;
#endif /* HPUXV>=1000 */
case N_MVFS:
if (read_nmn(va, (KA_T)v->v_data, &m))
return;
break;
case N_NFS:
if (!v->v_data || readrnode((KA_T)v->v_data, &r)) {
(void) snpf(Namech, Namechl,
"vnode at %s: can't read rnode (%s)",
print_kptr(va, tbuf, sizeof(tbuf)),
print_kptr((KA_T)v->v_data, (char *)NULL, 0));
enter_nm(Namech);
return;
}
rns = 1;
break;
#if HPUXV>=1000
case N_SPEC:
if ((v->v_type == VBLK) || (v->v_type == VCHR)) {
if (!v->v_data || readsnode((KA_T)v->v_data, &s)) {
(void) snpf(Namech, Namechl,
"vnode at %s: can't read snode(%s)",
print_kptr(va, tbuf, sizeof(tbuf)),
print_kptr((KA_T)v->v_data, (char *)NULL, 0));
enter_nm(Namech);
return;
}
if (!s.s_realvp
|| readvnode((KA_T)s.s_realvp, &rv)) {
(void) snpf(Namech, Namechl,
"snode at %s: can't read real vnode (%s)",
print_kptr((KA_T)v->v_data, tbuf, sizeof(tbuf)),
print_kptr((KA_T)s.s_realvp, (char *)NULL, 0));
enter_nm(Namech);
return;
}
#if defined(HASVXFS)
if (getnodety(&rv) == N_VXFS) {
if (!rv.v_data
|| read_vxnode(&rv, vfs, &dev, &devs, &rdev, &rdevs)) {
(void) snpf(Namech, Namechl,
"vnode at %s: can't read vx_inode (%s)",
print_kptr(va, tbuf, sizeof(tbuf)),
print_kptr((KA_T)rv.v_data, (char *)NULL, 0));
enter_nm(Namech);
return;
}
Ntype = N_VXFS;
break;
}
#endif /* defined(HASVXFS) */
if (!rv.v_data || readinode((KA_T)rv.v_data, &i)) {
(void) snpf(Namech, Namechl,
"snode at %s: can't read inode (%s)",
print_kptr((KA_T)v->v_data, tbuf, sizeof(tbuf)),
print_kptr((KA_T)rv.v_data, (char *)NULL, 0));
enter_nm(Namech);
return;
}
ins = 1;
break;
}
if (!v->v_data || readinode((KA_T)v->v_data, &i)) {
(void) snpf(Namech, Namechl,
"vnode at %s: can't read inode (%s)",
print_kptr(va, tbuf, sizeof(tbuf)),
print_kptr((KA_T)v->v_data, (char *)NULL, 0));
enter_nm(Namech);
return;
}
ins = 1;
break;
#endif /* HPUXV>=1000 */
#if HPUXV>=900 && HPUXV<1000
case N_FIFO:
if (v->v_fstype == VNFS_FIFO) {
if (!v->v_data || readsnode((KA_T)v->v_data, &s)) {
(void) snpf(Namech, Namechl,
"vnode at %s: can't read snode (%s)",
print_kptr(va, tbuf, sizeof(tbuf)),
print_kptr((KA_T)v->v_data, (char *)NULL, 0));
enter_nm(Namech);
return;
}
if (!s.s_realvp || readvnode((KA_T)s.s_realvp, &rv)) {
(void) snpf(Namech, Namechl,
"snode at %s: can't read real vnode (%s)",
print_kptr((KA_T)v->v_data, tbuf, sizeof(tbuf)),
print_kptr((KA_T)s.s_realvp, (char *)NULL, 0));
enter_nm(Namech);
return;
}
if (!rv.v_data || readrnode((KA_T)rv.v_data, &r)) {
(void) snpf(Namech, Namechl,
"snode at %s: can't read real rnode (%s)",
print_kptr((KA_T)v->v_data, tbuf, sizeof(tbuf)),
print_kptr((KA_T)s.s_realvp, (char *)NULL, 0));
enter_nm(Namech);
return;
}
rns = 1;
break;
}
/* fall through */
#endif /* HPUXV>=900 && HPUXV<1000 */
case N_REGLR:
default:
if (!v->v_data || readinode((KA_T)v->v_data, &i)) {
(void) snpf(Namech, Namechl,
"vnode at %s: can't read inode (%s)",
print_kptr(va, tbuf, sizeof(tbuf)),
print_kptr((KA_T)v->v_data, (char *)NULL, 0));
enter_nm(Namech);
return;
}
ins = 1;
#if HPUXV>=900 && HPUXV<1000
if (v->v_type == VFIFO)
Ntype = N_FIFO;
#endif /* HPUXV>=900 && HPUXV<1000 */
}
#if HPUXV>=900 && HPUXV<1000
Lf->lock = (char)islocked((KA_T)i.i_locklist);
#endif /* HPUXV>=900 && HPUXV<1000 */
/*
* Get device and type for printing.
*/
switch (Ntype) {
#if defined(HAS_AFS)
case N_AFS:
dev = an.dev;
devs = 1;
break;
#endif /* defined(HAS_AFS) */
case N_MVFS:
if (vfs) {
dev = vfs->dev;
devs = 1;
}
break;
case N_NFS:
dev = vfs ? vfs->dev : 0;
devs = 1;
break;
#if HPUXV>=1000
case N_CDFS:
dev = c.cd_dev;
devs = 1;
break;
case N_FIFO:
case N_PIPE:
if (vfs && vfs->fsname) {
dev = vfs->dev;
devs = 1;
} else if (vats && (dev_t)vat.va_fsid != NODEV) {
dev = (dev_t)vat.va_fsid;
devs = 1;
} else
enter_dev_ch(print_kptr(va, (char *)NULL, 0));
break;
#endif /* _HPUX>=1000 */
#if defined(HASVXFS)
case N_VXFS:
/* obtained via read_vxnode */
break;
#endif /* defined(HASVXFS) */
case N_SPEC:
default:
#if HPUXV>=800
if (vfs && vfs->fsname) {
dev = vfs->dev;
devs = 1;
} else if (ins) {
dev = i.i_dev;
devs = 1;
}
if ((v->v_type == VBLK) || (v->v_type == VCHR)) {
rdev = v->v_rdev;
rdevs = 1;
}
#else /* HPUXV<800 */
if (ins) {
dev = i.i_dev;
devs = 1;
}
if ((v->v_type == VCHR) || (v->v_type == VBLK)) {
rdev = v->v_rdev;
rdevs = 1;
}
#endif /* HPUXV>=800 */
}
type = v->v_type;
/*
* Obtain the inode number.
*/
switch (Ntype) {
#if defined(HAS_AFS)
case N_AFS:
if (an.ino_st) {
Lf->inode = (INODETYPE)an.inode;
Lf->inp_ty = 1;
}
break;
#endif /* defined(HAS_AFS) */
case N_MVFS:
Lf->inode = (INODETYPE)m.m_ino;
Lf->inp_ty = 1;
break;
case N_NFS:
#if HPUXV<1030
Lf->inode = (INODETYPE)r.r_nfsattr.na_nodeid;
#else /* HPUXV>=1030 */
Lf->inode = (INODETYPE)r.r_attr.va_nodeid;
#endif /* HPUXV<1030 */
Lf->inp_ty = 1;
break;
#if HPUXV>=1000
case N_CDFS:
Lf->inode = (INODETYPE)c.cd_num;
Lf->inp_ty = 1;
break;
case N_FIFO:
case N_PIPE:
if (vats) {
Lf->inode = (INODETYPE)vat.va_nodeid;
Lf->inp_ty = 1;
} else {
Lf->inode = (INODETYPE)v->v_nodeid;
Lf->inp_ty = 1;
}
break;
#endif /* HPUXV>=1000 */
#if defined(HASVXFS)
case N_VXFS:
/* set in read_vxnode() */
break;
#endif /* defined(HASVXFS) */
#if HPUXV<1000
case N_FIFO:
# if HPUXV>=900
if (rns) {
Lf->inode = (INODETYPE)r.r_nfsattr.na_nodeid;
Lf->inp_ty = 1;
break;
}
# endif /* HPUXV>=900 */
/* fall through */
#endif /* HPUXV<1000 */
case N_BLK:
case N_REGLR:
case N_SPEC:
if (ins) {
Lf->inode = (INODETYPE)i.i_number;
Lf->inp_ty = 1;
}
}
#if HPUXV>=1030
/*
* Check for an HP-UX 10.30 and above stream.
*/
if (v->v_stream) {
KA_T ip, pcb;
char *pn = (char *)NULL;
Lf->dev = dev;
Lf->dev_def = devs;
Lf->rdev = rdev;
Lf->rdev_def = rdevs;
if (read_mi((KA_T)v->v_stream, &ip, &pcb, &pn))
return;
if (ip && pcb) {
process_stream_sock(ip, pcb, pn, type);
return;
}
Lf->is_stream = 1;
}
#endif /* HPUXV>=1030 */
/*
* Obtain the file size.
*/
if (Foffset)
Lf->off_def = 1;
else {
switch (Ntype) {
#if defined(HAS_AFS)
case N_AFS:
Lf->sz = (SZOFFTYPE)an.size;
Lf->sz_def = 1;
break;
#endif /* defined(HAS_AFS) */
#if HPUXV>=1000
case N_CDFS:
Lf->sz = (SZOFFTYPE)c.cd_cdc.cdc_size;
Lf->sz_def = 1;
break;
case N_PIPE:
if (vats) {
Lf->sz = (SZOFFTYPE)vat.va_size;
Lf->sz_def = 1;
}
break;
#endif /* HPUXV>=1000 */
#if HPUXV>=900
case N_FIFO:
# if HPUXV<1000
if (ins) {
rp = i.i_frptr;
sz = (int)i.i_fifosize;
wp = i.i_fwptr;
} else if (rns)
Lf->sz = (SZOFFTYPE)r.r_nfsattr.na_size;
# else /* HPUXV>=1000 */
if (fns) {
rp = f.fn_rptr;
sz = f.fn_size;
wp = f.fn_wptr;
}
# endif /* HPUXV<1000 */
if (Fsize || (Lf->access != 'r' && Lf->access != 'w')) {
if (fns || ins) {
(void) snpf(fb, sizeof(fb), "rd=%#x; wr=%#x", rp, wp);
(void) enter_nma(fb);
}
if (fns || ins || rns) {
Lf->sz = (SZOFFTYPE)sz;
Lf->sz_def = 1;
}
break;
}
if (fns || ins) {
Lf->off = (unsigned long)((Lf->access == 'r') ? rp
: wp);
(void) snpf(fb, sizeof(fb), "%s=%#x",
(Lf->access == 'r') ? "rd" : "wr",
(Lf->access == 'r') ? rp : wp);
(void) enter_nma(fb);
}
Lf->off_def = 1;
break;
#endif /* HPUXV>=900 */
case N_MVFS:
/* The location of the file size isn't known. */
break;
case N_NFS:
#if HPUXV<1030
Lf->sz = (SZOFFTYPE)r.r_nfsattr.na_size;
#else /* HPUXV>=1030 */
Lf->sz = (SZOFFTYPE)r.r_attr.va_size;
#endif /* HPUXV<1030 */
Lf->sz_def = 1;
break;
#if defined(HASVXFS)
case N_VXFS:
/* set in read_vxnode() */
break;
#endif /* defined(HASVXFS) */
case N_SPEC:
case N_REGLR:
if ((type == VCHR || type == VBLK) && !Fsize)
Lf->off_def = 1;
else if (ins) {
Lf->sz = (SZOFFTYPE)i.i_size;
Lf->sz_def = 1;
}
break;
}
}
/*
* Record link count.
*/
if (Fnlink) {
switch(Ntype) {
# if defined(HAS_AFS)
case N_AFS:
Lf->nlink = an.nlink;
Lf->nlink_def = an.nlink_st;
break;
# endif /* defined(HAS_AFS) */
case N_MVFS:
/* The location of the link count isn't known. */
break;
case N_NFS:
#if HPUXV<1030
Lf->nlink = r.r_nfsattr.na_nlink;
#else /* HPUXV>=1030 */
Lf->nlink = r.r_attr.va_nlink;
#endif /* HPUXV<1030 */
Lf->nlink_def = 1;
break;
# if HPUXV>=1000
case N_CDFS: /* no link count? */
break;
# endif /* HPUXV>=1000 */
case N_FIFO:
case N_PIPE:
# if HPUXV>=1000
if (vats) {
Lf->nlink = (long)vat.va_nlink;
Lf->nlink_def = 1;
}
# endif /* HPUXV>=1000 */
break;
# if defined(HASVXFS)
case N_VXFS:
/* set in read_vxnode() */
break;
# endif /* defined(HASVXFS) */
case N_SPEC:
default:
if (ins) {
Lf->nlink = (long)i.i_nlink;
Lf->nlink_def = 1;
}
break;
}
if (Nlink && Lf->nlink_def && (Lf->nlink < Nlink))
Lf->sf |= SELNLINK;
}
/*
* Record an NFS file selection.
*/
if (Ntype == N_NFS && Fnfs)
Lf->sf |= SELNFS;
/*
* Save the file system names.
*/
if (vfs) {
Lf->fsdir = vfs->dir;
Lf->fsdev = vfs->fsname;
#if defined(HASFSINO)
Lf->fs_ino = vfs->fs_ino;
#endif /* defined(HASFSINO) */
}
/*
* Save the device numbers and their states.
*
* Format the vnode type, and possibly the device name.
*/
Lf->dev = dev;
Lf->dev_def = devs;
Lf->rdev = rdev;
Lf->rdev_def = rdevs;
switch (type) {
case VNON:
ty ="VNON";
break;
case VREG:
case VDIR:
ty = (type == VREG) ? "VREG" : "VDIR";
break;
case VBLK:
ty = "VBLK";
Ntype = N_BLK;
break;
case VCHR:
ty = "VCHR";
Ntype = N_CHR;
break;
case VLNK:
ty = "VLNK";
break;
#if defined(VSOCK)
case VSOCK:
ty = "SOCK";
break;
#endif /* defined(VSOCK) */
case VBAD:
ty = "VBAD";
break;
case VFIFO:
switch (Ntype) {
#if HPUXV>=1000
case N_FIFO:
ty = "FIFO";
break;
case N_PIPE:
ty = "PIPE";
break;
#endif /* HPUXV>=1000 */
default:
ty = "FIFO";
}
break;
default:
(void) snpf(Lf->type, sizeof(Lf->type), "%04o", (type & 0xfff));
ty = (char *)NULL;
}
if (ty)
(void) snpf(Lf->type, sizeof(Lf->type), "%s", ty);
Lf->ntype = Ntype;
#if defined(HASBLKDEV)
/*
* If this is a VBLK file and it's missing an inode number, try to
* supply one.
*/
if ((Lf->inp_ty == 0) && (type == VBLK))
find_bl_ino();
#endif /* defined(HASBLKDEV) */
/*
* If this is a VCHR file and it's missing an inode number, try to
* supply one.
*/
if ((Lf->inp_ty == 0) && (type == VCHR))
find_ch_ino();
/*
* Test for specified file.
*/
if (Sfile && is_file_named((char *)NULL,
((type == VCHR) || (type == VBLK) ? 1 : 0)))
Lf->sf |= SELNM;
/*
* Enter name characters.
*/
if (Namech[0])
enter_nm(Namech);
}
/*
* readinode() - read inode
*/
static int
readinode(ia, i)
KA_T ia; /* inode kernel address */
struct inode *i; /* inode buffer */
{
if (kread((KA_T)ia, (char *)i, sizeof(struct inode))) {
(void) snpf(Namech, Namechl, "can't read inode at %s",
print_kptr(ia, (char *)NULL, 0));
return(1);
}
return(0);
}
/*
* read_nmn() - read node's mvfsnode
*/
static int
read_nmn(na, ma, m)
KA_T na; /* containing node's address */
KA_T ma; /* kernel mvfsnode address */
struct mvfsnode *m; /* mvfsnode receiver */
{
char tbuf[32];
if (!ma || kread((KA_T)ma, (char *)m, sizeof(struct mvfsnode))) {
(void) snpf(Namech, Namechl, "node at %s: can't read mvfsnode: %s",
print_kptr(na, tbuf, sizeof(tbuf)),
print_kptr(ma, (char *)NULL, 0));
enter_nm(Namech);
return(1);
}
return(0);
}