blob: 79d7795e349c7ab5573d6aa4ab56fa2befe7e19f [file] [log] [blame]
/*
* dnode.c - NetBSD and OpenBSD 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.38 2007/04/24 16:22:02 abe Exp $";
#endif
#include "lsof.h"
#if defined(HAS_DINODE_U)
#define DINODE_U dinode_u
#else /* !defined(HAS_DINODE_U) */
#define DINODE_U i_din
#endif /* defined(HAS_DINODE_U) */
#if defined(HASFDESCFS) && HASFDESCFS==1
_PROTOTYPE(static int lkup_dev_tty,(dev_t *dr, INODETYPE *ir));
#endif /* defined(HASFDESCFS) && HASFDESCFS==1 */
#if defined(HAS_UM_UFS)
#define UFS1 UM_UFS1
#define UFS2 UM_UFS2
#endif /* defined(HAS_UM_UFS) */
#if defined(HASPROCFS)
_PROTOTYPE(static void getmemsz,(pid_t pid));
# if !defined(PGSHIFT)
#define PGSHIFT pgshift
# endif /* !defined(PGSHIFT) */
/*
* getmemsz() - get memory size of a /proc/<n>/mem entry
*/
static void
getmemsz(pid)
pid_t pid;
{
int n;
struct vmspace vm;
#if defined(HASKVMGETPROC2)
struct kinfo_proc2 *p;
#else /* !defined(HASKVMGETPROC2) */
struct kinfo_proc *p;
#endif /* defined(HASKVMGETPROC2) */
for (n = 0, p = P; n < Np; n++, p++) {
if (p->P_PID == pid) {
if (!p->P_VMSPACE
|| kread((KA_T)p->P_VMSPACE, (char *)&vm, sizeof(vm)))
return;
# if defined(OPENBSDV)
Lf->sz = (SZOFFTYPE)((vm.vm_tsize + vm.vm_dsize
+ vm.vm_ssize) * sysconf(_SC_PAGESIZE));
# else /* !defined(OPENBSDV */
Lf->sz = (SZOFFTYPE)ctob(vm.vm_tsize + vm.vm_dsize
+ vm.vm_ssize);
# endif /* defined(OPENBSDV) */
Lf->sz_def = 1;
return;
}
}
}
#undef PGSHIFT
#endif /* defined(HASPROCFS) */
#if defined(HASFDESCFS) && HASFDESCFS==1
/*
* lkup_dev_tty() - look up /dev/tty
*/
static int
lkup_dev_tty(dr, ir)
dev_t *dr; /* place to return device number */
INODETYPE *ir; /* place to return inode number */
{
int i;
readdev(0);
# if defined(HASDCACHE)
lkup_dev_tty_again:
# endif /* defined(HASDCACHE) */
for (i = 0; i < Ndev; i++) {
if (strcmp(Devtp[i].name, "/dev/tty") == 0) {
# if defined(HASDCACHE)
if (DCunsafe && !Devtp[i].v && !vfy_dev(&Devtp[i]))
goto lkup_dev_tty_again;
# endif /* defined(HASDCACHE) */
*dr = Devtp[i].rdev;
*ir = Devtp[i].inode;
return(1);
}
}
# if defined(HASDCACHE)
if (DCunsafe) {
(void) rereaddev();
goto lkup_dev_tty_again;
}
# endif /* defined(HASDCACHE) */
return(-1);
}
#endif /* defined(HASFDESCFS) && HASFDESCFS==1 */
#if defined(HASKQUEUE)
/*
* process_kqueue() -- process kqueue file
*
* Strictly speaking this function should appear in dfile.c, because it is
* a file processing function. However, the Net and Open BSD sources don't
* require a dfile.c, so this is the next best location for the function.
*/
void
process_kqueue(ka)
KA_T ka; /* kqueue file structure address */
{
# if defined(OPENBSDV)
struct kqueue kq; /* kqueue structure */
# endif /* defined(OPENBSDV) */
(void) snpf(Lf->type, sizeof(Lf->type), "KQUEUE");
enter_dev_ch(print_kptr(ka, (char *)NULL, 0));
# if defined(OPENBSDV)
if (!ka || kread(ka, (char *)&kq, sizeof(kq)))
return;
(void) snpf(Namech, Namechl, "count=%d, state=%#x", kq.kq_count,
kq.kq_state);
enter_nm(Namech);
# endif /* defined(OPENBSDV) */
}
#endif /* defined(HASKQUEUE) */
/*
* process_node() - process vnode
*/
void
process_node(va)
KA_T va; /* vnode kernel space address */
{
dev_t dev, rdev;
unsigned char devs;
unsigned char lt;
unsigned char ns;
unsigned char rdevs;
char *ep, *ty;
struct lockf lf, *lff, *lfp;
struct inode i;
struct mfsnode m;
struct nfsnode n;
enum nodetype {NONODE, CDFSNODE, DOSNODE, EXT2NODE, FDESCNODE, INODE,
KERNFSNODE, MFSNODE, NFSNODE, PFSNODE, PTYFSNODE} nty;
enum vtype type;
struct vnode *v, vb;
struct l_vfs *vfs;
#if defined(HAS9660FS)
dev_t iso_dev;
INODETYPE iso_ino;
long iso_nlink;
int iso_stat;
SZOFFTYPE iso_sz;
#endif /* defined(HAS9660FS) */
#if defined(HASFDESCFS)
struct fdescnode f;
# if HASFDESCFS==1
static dev_t f_tty_dev;
static INODETYPE f_tty_ino;
static int f_tty_s = 0;
# endif /* HASFDESCFS==1 */
#endif /* defined(HASFDESCFS) */
#if defined(HASEXT2FS)
# if defined(HASI_E2FS_PTR)
struct ext2fs_dinode ed;
# endif /* defined(HASI_E2FS_PTR) */
struct ext2fs_dinode *edp = (struct ext2fs_dinode *)NULL;
#endif /* defined(HASEXT2FS) */
#if defined(HASI_FFS1)
unsigned char ffs = 0;
unsigned char u1s = 0;
unsigned char u2s = 0;
struct ufs1_dinode u1;
struct ufs2_dinode u2;
struct ufsmount um;
#endif /* defined(HASI_FFS1) */
#if defined(HASKERNFS)
struct kernfs_node kn;
struct stat ksb;
int ksbs;
struct kern_target kt;
int ktnl;
char ktnm[MAXPATHLEN+1];
#endif /* defined(HASKERNFS) */
#if defined(HASMSDOSFS)
struct denode d;
u_long dpb;
INODETYPE nn;
struct msdosfsmount pm;
#endif /* defined(HASMSDOSFS) */
#if defined(HASNFSVATTRP)
struct vattr nv;
#define NVATTR nv
#else /* !defined(HASNFSVATTRP) */
#define NVATTR n.n_vattr
#endif /* defined(HASNFSVATTRP) */
#if defined(HASNULLFS)
struct null_node nu;
int sc = 0;
struct l_vfs *nvfs = (struct l_vfs *)NULL;
#endif /* defined(HASNULLFS) */
#if defined(HASPROCFS)
struct pfsnode p;
struct procfsid *pfi;
size_t sz;
#endif /* defined(HASPROCFS) */
#if defined(HASPTYFS)
struct ptyfsnode pt;
struct specinfo si;
#endif /* defined(HASPTYFS) */
#if defined(HASNULLFS)
process_overlaid_node:
if (++sc > 1024) {
(void) snpf(Namech, Namechl, "too many overlaid nodes");
enter_nm(Namech);
return;
}
#endif /* defined(HASNULLFS) */
/*
* Initialize miscellaneous variables. This is done so that processing an
* overlaid node will be a fresh start.
*/
devs = rdevs = 0;
nty = NONODE;
Namech[0] = '\0';
#if defined(HAS9660FS)
iso_stat = 0;
#endif /* defined(HAS9660FS) */
#if defined(HASKERNFS)
ksbs = 0;
#endif /* defined(HASKERNFS) */
#if defined(HASEXT2FS)
edp = (struct ext2fs_dinode *)NULL;
#endif /* defined(HASEXT2FS) */
#if defined(HASI_FFS1)
ffs = u1s = u2s = 0;
#endif /* defined(HASI_FFS1) */
/*
* Read the vnode.
*/
if (!va) {
enter_nm("no vnode address");
return;
}
v = &vb;
if (readvnode(va, v)) {
enter_nm(Namech);
return;
}
#if defined(HASNCACHE)
Lf->na = va;
# if defined(HASNCVPID)
Lf->id = v->v_id;
# endif /* defined(HASNCVPID) */
#endif /* defined(HASNCACHE) */
#if defined(HASFSTRUCT)
Lf->fna = va;
Lf->fsv |= FSV_NI;
#endif /* defined(HASFSTRUCT) */
/*
* Get the vnode type.
*/
if (!v->v_mount)
vfs = (struct l_vfs *)NULL;
else {
vfs = readvfs((KA_T)v->v_mount);
if (vfs) {
if (strcmp(vfs->type, MOUNT_NFS) == 0)
Ntype = N_NFS;
#if defined(HASKERNFS)
else if (strcmp(vfs->type, MOUNT_KERNFS) == 0)
Ntype = N_KERN;
#endif /* defined(HASKERNFS) */
#if defined(HASPROCFS)
else if (strcmp(vfs->type, MOUNT_PROCFS) == 0)
Ntype = N_PROC;
#endif /* defined(HASPROCFS) */
#if defined(HAS9660FS)
else if (strcmp(vfs->type, MOUNT_CD9660) == 0)
Ntype = N_CDFS;
#endif /* defined(HAS9660FS) */
}
}
if (Ntype == N_REGLR) {
switch (v->v_type) {
case VFIFO:
Ntype = N_FIFO;
break;
}
}
/*
* Read the successor node.
*/
switch (v->v_tag) {
#if defined(HAS9660FS)
case VT_ISOFS:
if (read_iso_node(v, &iso_dev, &iso_ino, &iso_nlink, &iso_sz))
{
(void) snpf(Namech, Namechl, "can't read iso_node at: %s",
print_kptr((KA_T)v->v_data, (char *)NULL, 0));
enter_nm(Namech);
return;
}
iso_stat = 1;
nty = CDFSNODE;
break;
#endif /* defined(HAS9660FS) */
#if defined(HASFDESCFS)
case VT_FDESC:
if (!v->v_data
|| kread((KA_T)v->v_data, (char *)&f, sizeof(f))) {
(void) snpf(Namech, Namechl, "can't read fdescnode at: %x",
print_kptr((KA_T)v->v_data, (char *)NULL, 0));
enter_nm(Namech);
return;
}
nty = FDESCNODE;
break;
#endif /* defined(HASFDESCFS) */
#if defined(HASKERNFS)
case VT_KERNFS:
/*
* Read the kernfs_node.
*/
if (!v->v_data
|| kread((KA_T)v->v_data, (char *)&kn, sizeof(kn))) {
if (v->v_type != VDIR || !(v->v_flag && VROOT)) {
(void) snpf(Namech, Namechl,
"can't read kernfs_node at: %s",
print_kptr((KA_T)v->v_data, (char *)NULL, 0));
enter_nm(Namech);
return;
} else
kn.kf_kt = (struct kern_target *)NULL;
}
/*
* Generate the /kern file name by reading the kern_target to which
* the kernfs_node points.
*/
if (kn.kf_kt
&& kread((KA_T)kn.kf_kt, (char *)&kt, sizeof(kt)) == 0
&& (ktnl = (int)kt.kt_namlen) > 0
&& kt.kt_name)
{
if (ktnl > (sizeof(ktnm) - 1))
ktnl = sizeof(ktnm) - 1;
if (!kread((KA_T)kt.kt_name, ktnm, ktnl)) {
ktnm[ktnl] = 0;
ktnl = strlen(ktnm);
if (ktnl > (MAXPATHLEN - strlen(_PATH_KERNFS) - 2)) {
ktnl = MAXPATHLEN - strlen(_PATH_KERNFS) - 2;
ktnm[ktnl] = '\0';
}
(void) snpf(Namech, Namechl, "%s/%s", _PATH_KERNFS, ktnm);
}
}
/*
* If this is the /kern root directory, its name, inode number and
* size are fixed; otherwise, safely stat() the file to get the
* inode number and size.
*/
if (v->v_type == VDIR && (v->v_flag & VROOT)) {
(void) snpf(Namech, Namechl, "%s", _PATH_KERNFS);
ksb.st_ino = (ino_t)2;
ksb.st_size = DEV_BSIZE;
ksbs = 1;
} else if (Namech[0] && statsafely(Namech, &ksb) == 0)
ksbs = 1;
nty = KERNFSNODE;
break;
#endif /* defined(HASKERNFS) */
case VT_MFS:
if (!v->v_data
|| kread((KA_T)v->v_data, (char *)&m, sizeof(m))) {
(void) snpf(Namech, Namechl, "can't read mfsnode at: %s",
print_kptr((KA_T)v->v_data, (char *)NULL, 0));
enter_nm(Namech);
return;
}
nty = MFSNODE;
break;
#if defined(HASMSDOSFS)
case VT_MSDOSFS:
if (!v->v_data
|| kread((KA_T)v->v_data, (char *)&d, sizeof(d))) {
(void) snpf(Namech, Namechl, "can't read denode at: %s",
print_kptr((KA_T)v->v_data, (char *)NULL, 0));
enter_nm(Namech);
return;
}
nty = DOSNODE;
break;
#endif /* defined(HASMSDOSFS) */
case VT_NFS:
if (!v->v_data
|| kread((KA_T)v->v_data, (char *)&n, sizeof(n))) {
(void) snpf(Namech, Namechl, "can't read nfsnode at: %s",
print_kptr((KA_T)v->v_data, (char *)NULL, 0));
enter_nm(Namech);
return;
}
#if defined(HASNFSVATTRP)
if (!n.n_vattr
|| kread((KA_T)n.n_vattr, (char *)&nv, sizeof(nv))) {
(void) snpf(Namech, Namechl, "can't read n_vattr at: %x",
print_kptr((KA_T)n.n_vattr, (char *)NULL, 0));
enter_nm(Namech);
return;
}
#endif /* defined(HASNFSVATTRP) */
nty = NFSNODE;
break;
#if defined(HASNULLFS)
case VT_NULL:
if ((sc == 1) && vfs)
nvfs = vfs;
if (!v->v_data
|| kread((KA_T)v->v_data, (char *)&nu, sizeof(nu))) {
(void) snpf(Namech, Namechl, "can't read null_node at: %s",
print_kptr((KA_T)v->v_data, (char *)NULL, 0));
enter_nm(Namech);
return;
}
if (!nu.null_lowervp) {
(void) snpf(Namech, Namechl, "null_node overlays nothing");
enter_nm(Namech);
return;
}
va = (KA_T)nu.null_lowervp;
goto process_overlaid_node;
#endif /* defined(HASNULLFS) */
#if defined(HASPROCFS)
case VT_PROCFS:
if (!v->v_data
|| kread((KA_T)v->v_data, (char *)&p, sizeof(p))) {
(void) snpf(Namech, Namechl, "can't read pfsnode at: %s",
print_kptr((KA_T)v->v_data, (char *)NULL, 0));
enter_nm(Namech);
return;
}
nty = PFSNODE;
break;
#endif /* defined(HASPROCFS) */
#if defined(HASPTYFS)
case VT_PTYFS:
if (!v->v_data
|| kread((KA_T)v->v_data, (char *)&pt, sizeof(pt))) {
(void) snpf(Namech, Namechl, "can't read ptyfsnode at: %s",
print_kptr((KA_T)v->v_data, (char *)NULL, 0));
enter_nm(Namech);
return;
}
nty = PTYFSNODE;
break;
#endif /* defined(HASPTYFS) */
#if defined(HASEXT2FS)
case VT_EXT2FS:
#endif /* defined(HASEXT2FS) */
#if defined(HASLFS)
case VT_LFS:
#endif /* defined(HASLFS) */
case VT_UFS:
if (!v->v_data
|| kread((KA_T)v->v_data, (char *)&i, sizeof(i))) {
(void) snpf(Namech, Namechl, "can't read inode at: %s",
print_kptr((KA_T)v->v_data, (char *)NULL, 0));
enter_nm(Namech);
return;
}
#if defined(HASEXT2FS)
if (v->v_tag == VT_EXT2FS) {
nty = EXT2NODE;
# if defined(HASI_E2FS_PTR)
if (i.DINODE_U.e2fs_din
&& !kread((KA_T)i.DINODE_U.e2fs_din, (char *)&ed, sizeof(ed)))
edp = &ed;
# else /* !defined(HASI_E2FS_PTR) */
# if HASEXT2FS<2
edp = &i.DINODE_U.e2fs_din;
# else /* HASEXT2FS>=2 */
edp = &i.i_e2din;
# endif /* HASEXT2FS>=2 */
# endif /* defined(HASI_E2FS_PTR) */
} else
#endif /* defined(HASEXT2FS) */
{
nty = INODE;
#if defined(HASI_FFS1)
/*
* If there are multiple FFS's, read the relevant structures.
*/
if (i.i_ump
&& !kread((KA_T)i.i_ump, (char *)&um, sizeof(um))) {
if (um.um_fstype == UFS1) {
ffs = 1;
if (i.DINODE_U.ffs1_din
&& !kread((KA_T)i.DINODE_U.ffs1_din, (char *)&u1,
sizeof(u1)))
{
u1s = 1;
}
} else if (um.um_fstype == UFS2) {
ffs = 2;
if (i.DINODE_U.ffs2_din
&& !kread((KA_T)i.DINODE_U.ffs2_din, (char *)&u2,
sizeof(u2)))
{
u2s = 1;
}
}
}
#endif /* defined(HASI_FFS1) */
}
if ((lff = i.i_lockf)) {
/*
* Determine the lock state.
*/
lfp = lff;
do {
if (kread((KA_T)lfp, (char *)&lf, sizeof(lf)))
break;
lt = 0;
switch(lf.lf_flags & (F_FLOCK|F_POSIX)) {
case F_FLOCK:
if (Cfp && (struct file *)lf.lf_id == Cfp)
lt = 1;
break;
case F_POSIX:
if ((KA_T)lf.lf_id == Kpa)
lt = 1;
#if defined(HAS_LWP_H) && !defined(HAS_LF_LWP)
else {
struct lwp lw;
if (!kread((KA_T)lf.lf_id, (char *)&lw, sizeof(lw))
&& (KA_T)lw.l_proc == Kpa)
lt = 1;
}
#endif /* defined(HAS_LWP_H) && !defined(HAS_LF_LWP) */
break;
}
if (!lt)
continue;
if (lf.lf_start == (off_t)0
&& lf.lf_end == 0xffffffffffffffffLL)
lt = 1;
else
lt = 0;
if (lf.lf_type == F_RDLCK)
Lf->lock = lt ? 'R' : 'r';
else if (lf.lf_type == F_WRLCK)
Lf->lock = lt ? 'W' : 'w';
else if (lf.lf_type == (F_RDLCK | F_WRLCK))
Lf->lock = 'u';
break;
} while ((lfp = lf.lf_next) && lfp != lff);
}
break;
default:
if (v->v_type == VBAD || v->v_type == VNON)
break;
(void) snpf(Namech, Namechl, "unknown file system type: %d",
v->v_tag);
enter_nm(Namech);
return;
}
/*
* Get device and type for printing.
*/
type = v->v_type;
switch (nty) {
#if defined(HASMSDOSFS)
case DOSNODE:
dev = d.de_dev;
devs = 1;
break;
#endif /* defined(HASMSDOSFS) */
#if defined(HASFDESCFS)
case FDESCNODE:
# if defined(HASFDLINK)
if (f.fd_link
&& !kread((KA_T)f.fd_link, Namech, Namechl - 1)) {
Namech[Namechl - 1] = '\0';
break;
}
# endif /* defined(HASFDLINK) */
# if HASFDESCFS==1
if (f.fd_type == Fctty) {
if (f_tty_s == 0)
f_tty_s = lkup_dev_tty(&f_tty_dev, &f_tty_ino);
if (f_tty_s == 1) {
dev = DevDev;
rdev = f_tty_dev;
Lf->inode = f_tty_ino;
devs = Lf->inp_ty = rdevs = 1;
}
}
break;
# endif /* HASFDESCFS==1 */
#endif /* defined(HASFDESCFS) */
#if defined(HASEXT2FS)
case EXT2NODE:
dev = i.i_dev;
devs = 1;
if ((type == VCHR) || (type == VBLK)) {
# if defined(HASI_E2FS_PTR)
if (edp) {
rdev = edp->e2di_rdev;
rdevs = 1;
}
# else /* !defined(HASI_E2FS_PTR) */
# if HASEXT2FS<2
rdev = i.DINODE_U.e2fs_din.e2di_rdev;
# else /* HASEXT2FS>=2 */
rdev = i.i_e2din.e2di_rdev;
# endif /* HASEXT2FS>=2 */
rdevs = 1;
# endif /* defined(HASI_E2FS_PTR) */
}
break;
#endif /* defined(HASEXT2FS) */
case INODE:
dev = i.i_dev;
devs = 1;
if ((type == VCHR) || (type == VBLK)) {
#if defined(HASI_FFS)
rdev = i.i_ffs_rdev;
rdevs = 1;
#else /* !defined(HASI_FFS) */
# if defined(HASI_FFS1)
if (ffs == 1) {
if (u1s) {
rdev = u1.di_rdev;
rdevs = 1;
}
} else if (ffs == 2) {
if (u2s) {
rdev = u2.di_rdev;
rdevs = 1;
}
}
# else /* !defined(HASI_FFS1) */
rdev = i.i_rdev;
rdevs = 1;
# endif /* defined(HASI_FFS1) */
#endif /* defined(HASI_FFS) */
}
break;
#if defined(HASKERNFS)
case KERNFSNODE:
if (vfs) {
# if defined(HASSTATVFS)
dev = (dev_t)vfs->fsid.__fsid_val[0];
# else /* !defined(HASSTATVFS) */
dev = (dev_t)vfs->fsid.val[0];
# endif /* defined(HASSTATVFS) */
devs = 1;
}
break;
#endif /* defined(HASKERNFS) */
#if defined(HAS9660FS)
case CDFSNODE:
if (iso_stat) {
dev = iso_dev;
devs = 1;
}
break;
#endif /* defined(HAS9660FS) */
case NFSNODE:
dev = NVATTR.va_fsid;
devs = 1;
break;
#if defined(HASPTYFS)
case PTYFSNODE:
if (v->v_un.vu_specinfo
&& !kread((KA_T)v->v_un.vu_specinfo, (char *)&si, sizeof(si))) {
rdev = si.si_rdev;
rdevs = 1;
}
if (vfs) {
# if defined(HASSTATVFS)
dev = (dev_t)vfs->fsid.__fsid_val[0];
# else /* !defined(HASSTATVFS) */
dev = (dev_t)vfs->fsid.val[0];
# endif /* defined(HASSTATVFS) */
devs = 1;
}
break;
#endif /* defined(HASPTYFS) */
}
/*
* Obtain the inode number.
*/
switch (nty) {
#if defined(HASMSDOSFS)
case DOSNODE:
if (d.de_pmp && !kread((KA_T)d.de_pmp, (char *)&pm, sizeof(pm))) {
dpb = (u_long)(pm.pm_BytesPerSec / sizeof(struct direntry));
if (d.de_Attributes & ATTR_DIRECTORY) {
if (d.de_StartCluster == MSDOSFSROOT)
nn = (INODETYPE)1;
else
nn = (INODETYPE)(cntobn(&pm, d.de_StartCluster) * dpb);
} else {
if (d.de_dirclust == MSDOSFSROOT)
nn = (INODETYPE)(roottobn(&pm, 0) * dpb);
else
nn = (INODETYPE)(cntobn(&pm, d.de_dirclust) * dpb);
nn += (INODETYPE)(d.de_diroffset / sizeof(struct direntry));
}
Lf->inode = nn;
Lf->inp_ty = 1;
}
break;
#endif /* defined(HASMSDOSFS) */
#if defined(HASEXT2FS)
case EXT2NODE:
#endif /* defined(HASEXT2FS) */
case INODE:
Lf->inode = (INODETYPE)i.i_number;
Lf->inp_ty = 1;
break;
#if defined(HASKERNFS)
case KERNFSNODE:
if (ksbs) {
Lf->inode = (INODETYPE)ksb.st_ino;
Lf->inp_ty = 1;
}
break;
#endif /* defined(HASKERNFS) */
#if defined(HAS9660FS)
case CDFSNODE:
if (iso_stat) {
Lf->inode = iso_ino;
Lf->inp_ty = 1;
}
break;
#endif /* defined(HAS9660FS) */
case NFSNODE:
Lf->inode = (INODETYPE)NVATTR.va_fileid;
Lf->inp_ty = 1;
break;
#if defined(HASPROCFS)
case PFSNODE:
Lf->inode = (INODETYPE)p.pfs_fileno;
Lf->inp_ty = 1;
break;
#endif /* defined(HASPROCFS) */
#if defined(HASPTYFS)
case PTYFSNODE:
if (pt.ptyfs_type == PTYFSptc) {
if (pt.ptyfs_fileno > 0x3fffffff)
Lf->inode = (INODETYPE)(pt.ptyfs_fileno & 0x3fffffff);
else
Lf->inode = (INODETYPE)(pt.ptyfs_fileno - 1);
} else
Lf->inode = (INODETYPE)pt.ptyfs_fileno;
Lf->inp_ty = 1;
break;
#endif /* defined(HASPTYFS) */
}
/*
* Obtain the file size.
*/
if (Foffset)
Lf->off_def = 1;
else {
switch (Ntype) {
#if defined(HAS9660FS)
case N_CDFS:
if (iso_stat) {
Lf->sz = (SZOFFTYPE)iso_sz;
Lf->sz_def = 1;
}
break;
#endif /* defined(HAS9660FS) */
case N_FIFO:
if (!Fsize)
Lf->off_def = 1;
break;
#if defined(HASKERNFS)
case N_KERN:
if (ksbs) {
Lf->sz = (SZOFFTYPE)ksb.st_size;
Lf->sz_def = 1;
}
break;
#endif /* defined(HASKERNFS) */
case N_NFS:
if (nty == NFSNODE) {
Lf->sz = (SZOFFTYPE)NVATTR.va_size;
Lf->sz_def = 1;
}
break;
#if defined(HASPROCFS)
case N_PROC:
if (nty == PFSNODE) {
switch (p.pfs_type) {
case Proot:
case Pproc:
Lf->sz = (SZOFFTYPE)DEV_BSIZE;
Lf->sz_def = 1;
break;
case Pcurproc:
Lf->sz = (SZOFFTYPE)DEV_BSIZE;
Lf->sz_def = 1;
break;
case Pmem:
(void) getmemsz(p.pfs_pid);
break;
case Pregs:
Lf->sz = (SZOFFTYPE)sizeof(struct reg);
Lf->sz_def = 1;
break;
# if defined(FP_QSIZE)
case Pfpregs:
Lf->sz = (SZOFFTYPE)sizeof(struct fpreg);
Lf->sz_def = 1;
break;
# endif /* defined(FP_QSIZE) */
}
}
break;
#endif /* defined(HASPROCFS) */
case N_REGLR:
if (type == VREG || type == VDIR) {
switch (nty) {
case INODE:
#if defined(HASI_FFS)
Lf->sz = (SZOFFTYPE)i.i_ffs_size;
Lf->sz_def = 1;
break;
#else /* !defined(HASI_FFS) */
# if defined(HASI_FFS1)
if (ffs == 1) {
if (u1s) {
Lf->sz = (SZOFFTYPE)u1.di_size;
Lf->sz_def = 1;
}
} else if (ffs == 2) {
if (u2s) {
Lf->sz = (SZOFFTYPE)u2.di_size;
Lf->sz_def = 1;
}
}
break;
# else /* !defined(HASI_FFS1) */
Lf->sz = (SZOFFTYPE)i.i_size;
Lf->sz_def = 1;
# endif /* defined(HASI_FFS1) */
#endif /* defined(HASI_FFS) */
break;
#if defined(HASMSDOSFS)
case DOSNODE:
Lf->sz = (SZOFFTYPE)d.de_FileSize;
Lf->sz_def = 1;
break;
#endif /* defined(HASMSDOSFS) */
case MFSNODE:
Lf->sz = (SZOFFTYPE)m.mfs_size;
Lf->sz_def = 1;
break;
#if defined(HASEXT2FS)
case EXT2NODE:
# if defined(HASI_E2FS_PTR)
if (edp) {
Lf->sz = (SZOFFTYPE)edp->e2di_size;
Lf->sz_def = 1;
}
# else /* !defined(HASI_E2FS_PTR) */
Lf->sz = (SZOFFTYPE)i.i_e2fs_size;
Lf->sz_def = 1;
# endif /* defined(HASI_E2FS_PTR) */
break;
#endif /* defined(HASEXT2FS) */
}
} else if ((type == VCHR || type == VBLK) && !Fsize)
Lf->off_def = 1;
break;
}
}
/*
* Record the link count.
*/
if (Fnlink) {
switch(Ntype) {
#if defined(HAS9660FS)
case N_CDFS:
if (iso_stat) {
Lf->nlink = iso_nlink;
Lf->nlink_def = 1;
}
break;
#endif /* defined(HAS9660FS) */
#if defined(HASKERNFS)
case N_KERN:
if (ksbs) {
Lf->nlink = (long)ksb.st_nlink;
Lf->nlink_def = 1;
}
break;
#endif /* defined(HASKERNFS) */
case N_NFS:
if (nty == NFSNODE) {
Lf->nlink = (long)NVATTR.va_nlink;
Lf->nlink_def = 1;
}
break;
case N_REGLR:
switch (nty) {
case INODE:
#if defined(HASEFFNLINK)
Lf->nlink = (long)i.HASEFFNLINK;
#else /* !defined(HASEFFNLINK) */
# if defined(HASI_FFS)
Lf->nlink = (long)i.i_ffs_nlink;
# else /* !defined(HASI_FFS) */
# if defined(HASI_FFS1)
if (ffs == 1) {
if (u1s)
Lf->nlink = (long)u1.di_nlink;
} else if (ffs == 2) {
if (u2s)
Lf->nlink = (long)u2.di_nlink;
}
# else /* !defined(HASI_FFS1) */
Lf->nlink = (long)i.i_nlink;
# endif /* defined(HASI_FFS1) */
# endif /* defined(HASI_FFS) */
#endif /* defined(HASEFFNLINK) */
Lf->nlink_def = 1;
break;
#if defined(HASMSDOSFS)
case DOSNODE:
Lf->nlink = (long)d.de_refcnt;
Lf->nlink_def = 1;
break;
#endif /* defined(HASMSDOSFS) */
#if defined(HASEXT2FS)
case EXT2NODE:
# if defined(HASI_E2FS_PTR)
if (edp) {
Lf->nlink = (long)edp->e2di_nlink;
Lf->nlink_def = 1;
}
# else /* !defined(HASI_E2FS_PTR) */
Lf->nlink = (long)i.i_e2fs_nlink;
Lf->nlink_def = 1;
# endif /* defined(HASI_E2FS_PTR) */
break;
#endif /* defined(HASEXT2FS) */
}
break;
}
if (Lf->nlink_def && Nlink && (Lf->nlink < Nlink))
Lf->sf |= SELNLINK;
}
/*
* Record an NFS file selection.
*/
if (Ntype == N_NFS && Fnfs)
Lf->sf |= SELNFS;
#if defined(HASNULLFS)
/*
* If there is a saved nullfs vfs pointer, propagate its device number.
*/
if (nvfs) {
# if defined(HASSTATVFS)
dev = nvfs->fsid.__fsid_val[0];
# else /* !defined(HASSTATVFS) */
dev = nvfs->fsid.val[0];
# endif /* defined(HASSTATVFS) */
devs = 1;
}
#endif /* defined(HASNULLFS) */
/*
* Save the file system names.
*/
if (vfs) {
Lf->fsdir = vfs->dir;
Lf->fsdev = vfs->fsname;
}
/*
* 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:
ty = "VREG";
break;
case VDIR:
ty = "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:
ty = "FIFO";
break;
default:
(void) snpf(Lf->type, sizeof(Lf->type), "%04o", (type & 0xfff));
ty = NULL;
}
if (ty)
(void) snpf(Lf->type, sizeof(Lf->type), "%s", ty);
Lf->ntype = Ntype;
/*
* Handle some special cases:
*
* ioctl(fd, TIOCNOTTY) files;
* /kern files
* memory node files;
* /proc files;
* ptyfs files.
*/
if (type == VBAD)
(void) snpf(Namech, Namechl, "(revoked)");
else if (nty == MFSNODE) {
Lf->dev_def = Lf->rdev_def = 0;
(void) snpf(Namech, Namechl, "%#x", m.mfs_baseoff);
enter_dev_ch("memory");
}
#if defined(HASPROCFS)
else if (nty == PFSNODE) {
Lf->dev_def= Lf->rdev_def = 0;
ty = NULL;
(void) snpf(Namech, Namechl, "/%s", HASPROCFS);
switch (p.pfs_type) {
case Proot:
ty = "PDIR";
break;
case Pcurproc:
ep = endnm(&sz);
(void) snpf(ep, sz, "/curproc");
ty = "PCUR";
break;
case Pproc:
ep = endnm(&sz);
(void) snpf(ep, sz, "/%d", p.pfs_pid);
ty = "PDIR";
break;
case Pfile:
ep = endnm(&sz);
(void) snpf(ep, sz, "/%d/file", p.pfs_pid);
ty = "PFIL";
break;
case Pmem:
ep = endnm(&sz);
(void) snpf(ep, sz, "/%d/mem", p.pfs_pid);
ty = "PMEM";
break;
case Pregs:
ep = endnm(&sz);
(void) snpf(ep, sz, "/%d/regs", p.pfs_pid);
ty = "PREG";
break;
case Pfpregs:
ep = endnm(&sz);
(void) snpf(ep, sz, "/%d/fpregs", p.pfs_pid);
ty = "PFPR";
break;
case Pctl:
ep = endnm(&sz);
(void) snpf(ep, sz, "/%d/ctl", p.pfs_pid);
ty = "PCTL";
break;
case Pstatus:
ep = endnm(&sz);
(void) snpf(ep, sz, "/%d/status", p.pfs_pid);
ty = "PSTA";
break;
case Pnote:
ep = endnm(&sz);
(void) snpf(ep, sz, "/%d/note", p.pfs_pid);
ty = "PNTF";
break;
case Pnotepg:
ep = endnm(&sz);
(void) snpf(ep, sz, "/%d/notepg", p.pfs_pid);
ty = "PGID";
break;
# if defined(Pfd)
case Pfd:
ep = endnm(&sz);
(void) snpf(ep, sz, "/%d/fd", p.pfs_pid);
ty = "PFD";
break;
# endif /* defined(Pfd) */
# if defined(Pmap)
case Pmap:
ep = endnm(&sz);
(void) snpf(ep, sz, "/%d/map", p.pfs_pid);
ty = "PMAP";
break;
# endif /* defined(Pmap) */
# if defined(Pmaps)
case Pmaps:
ep = endnm(&sz);
(void) snpf(ep, sz, "/%d/maps", p.pfs_pid);
ty = "PMPS";
break;
# endif /* defined(Pmaps) */
}
if (ty)
(void) snpf(Lf->type, sizeof(Lf->type), ty);
}
#endif /* defined(HASPROCFS) */
#if defined(HASPTYFS)
else if (nty == PTYFSNODE) {
(void) snpf(Namech, Namechl, "%s", Lf->fsdir);
Lf->nlink = 1;
Lf->nlink_def = 1;
switch (pt.ptyfs_type) {
case PTYFSpts:
ep = endnm(&sz);
(void) snpf(ep, sz, "/%lu", (unsigned long)pt.ptyfs_pty);
break;
case PTYFSptc:
ep = endnm(&sz);
(void) snpf(ep, sz, "/%lu (master)",
(unsigned long)pt.ptyfs_pty);
break;
case PTYFSroot:
Lf->sz = 512;
Lf->sz_def = 1;
break;
}
if (ty)
(void) snpf(Lf->type, sizeof(Lf->type), ty);
}
#endif /* defined(HASPTYFS) */
#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 defined(HASPROCFS)
if (Ntype == N_PROC) {
if (Procsrch) {
Procfind = 1;
Lf->sf |= SELNM;
} else if (nty == PFSNODE) {
for (pfi = Procfsid; pfi; pfi = pfi->next) {
if ((pfi->pid && pfi->pid == p.pfs_pid)
# if defined(HASPINODEN)
|| ((Lf->inp_ty == 1) && (pfi->inode == Lf->inode))
# endif /* defined(HASPINODEN) */
) {
pfi->f = 1;
if (Namech[0] && pfi->nm)
(void) snpf(Namech, Namechl, "%s", pfi->nm);
Lf->sf |= SELNM;
break;
}
}
}
} else
#endif /* defined(HASPROCFS) */
{
if (Namech[0]) {
enter_nm(Namech);
ns = 1;
} else
ns = 0;
if (Sfile && is_file_named((char *)NULL,
((type == VCHR) || (type == VBLK)) ? 1
: 0))
{
Lf->sf |= SELNM;
}
if (ns)
Namech[0] = '\0';
}
/*
* Enter name characters.
*/
if (Namech[0])
enter_nm(Namech);
}
#if defined(HAS_SYS_PIPEH)
/*
* process_pipe() - process a file structure whose type is DTYPE_PIPE
*/
void
process_pipe(pa)
KA_T pa; /* pipe structure kernel address */
{
char *ep;
struct pipe p;
size_t sz;
if (!pa || kread((KA_T)pa, (char *)&p, sizeof(p))) {
(void) snpf(Namech, Namechl,
"can't read DTYPE_PIPE pipe struct: %#s",
print_kptr(pa, (char *)NULL, 0));
enter_nm(Namech);
return;
}
(void) snpf(Lf->type, sizeof(Lf->type), "PIPE");
enter_dev_ch(print_kptr(pa, (char *)NULL, 0));
if (Foffset)
Lf->off_def = 1;
else {
Lf->sz = (SZOFFTYPE)p.pipe_buffer.size;
Lf->sz_def = 1;
}
if (p.pipe_peer)
(void) snpf(Namech, Namechl, "->%s",
print_kptr((KA_T)p.pipe_peer, (char *)NULL, 0));
else
Namech[0] = '\0';
if (p.pipe_buffer.cnt) {
ep = endnm(&sz);
(void) snpf(ep, sz, ", cnt=%d", p.pipe_buffer.cnt);
}
if (p.pipe_buffer.in) {
ep = endnm(&sz);
(void) snpf(ep, sz, ", in=%d", p.pipe_buffer.in);
}
if (p.pipe_buffer.out) {
ep = endnm(&sz);
(void) snpf(ep, sz, ", out=%d", p.pipe_buffer.out);
}
/*
* Enter name characters.
*/
if (Namech[0])
enter_nm(Namech);
}
#endif /* defined(HAS_SYS_PIPEH) */