/* * 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//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) */