/* * dnode.c - FreeBSD 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.41 2011/08/07 22:51:28 abe Exp $"; #endif #include "lsof.h" #if defined(HAS_LOCKF_ENTRY) #include "./lockf_owner.h" #endif /* defined(HAS_LOCKF_ENTRY) */ #if defined(HAS_ZFS) #include "dzfs.h" #endif /* defined(HAS_ZFS) */ #if defined(HASFDESCFS) && HASFDESCFS==1 _PROTOTYPE(static int lkup_dev_tty,(dev_t *dr, INODETYPE *ir)); #endif /* defined(HASFDESCFS) && HASFDESCFS==1 */ _PROTOTYPE(static void get_lock_state,(KA_T f)); /* * get_lock_state() -- get the lock state */ static void get_lock_state(f) KA_T f; /* inode's lock pointer */ { struct lockf lf; /* lockf structure */ int lt; /* lock type */ #if defined(HAS_LOCKF_ENTRY) struct lockf_entry le; /* lock_entry structure */ KA_T lef, lep; /* lock_entry pointers */ struct lock_owner lo; /* lock owner structure */ if (!f || kread(f, (char *)&lf, sizeof(lf))) return; if (!(lef = (KA_T)lf.ls_active.lh_first)) return; lep = lef; do { if (kread(lep, (char *)&le, sizeof(le))) return; if (!le.lf_owner || kread((KA_T)le.lf_owner, (char *)&lo, sizeof(lo))) continue; if (lo.lo_pid == (pid_t)Lp->pid) { if (le.lf_start == (off_t)0 && le.lf_end == 0x7fffffffffffffffLL) lt = 1; else lt = 0; if (le.lf_type == F_RDLCK) Lf->lock = lt ? 'R' : 'r'; else if (le.lf_type == F_WRLCK) Lf->lock = lt ? 'W' : 'w'; else if (le.lf_type == (F_RDLCK | F_WRLCK)) Lf->lock = 'u'; return; } } while ((lep = (KA_T)le.lf_link.le_next) && (lep != lef)); #else /* !defined(HAS_LOCKF_ENTRY) */ unsigned char l; /* lock status */ KA_T lfp; /* lockf structure pointer */ if ((lfp = f)) { /* * Determine the lock state. */ do { if (kread(lfp, (char *)&lf, sizeof(lf))) break; l = 0; switch (lf.lf_flags & (F_FLOCK|F_POSIX)) { case F_FLOCK: if (Cfp && (struct file *)lf.lf_id == Cfp) l = 1; break; case F_POSIX: # if defined(P_ADDR) if ((KA_T)lf.lf_id == Kpa) l = 1; # endif /* defined(P_ADDR) */ break; } if (!l) 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 = (KA_T)lf.lf_next) && (lfp != f)); } #endif /* defined(HAS_LOCKF_ENTRY) */ } #if FREEBSDV>=2000 # if defined(HASPROCFS) _PROTOTYPE(static void getmemsz,(pid_t pid)); /* * getmemsz() - get memory size of a /proc//mem entry */ static void getmemsz(pid) pid_t pid; { int n; struct kinfo_proc *p; struct vmspace vm; 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; Lf->sz = (SZOFFTYPE)ctob(vm.vm_tsize+vm.vm_dsize+vm.vm_ssize); Lf->sz_def = 1; return; } } } # endif /* defined(HASPROCFS) */ #endif /* FREEBSDV>=2000 */ #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 */ { struct kqueue kq; /* kqueue structure */ (void) snpf(Lf->type, sizeof(Lf->type), "KQUEUE"); enter_dev_ch(print_kptr(ka, (char *)NULL, 0)); 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(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 rdevs; char dev_ch[32], *ep; struct inode *i; struct nfsnode *n; size_t sz; char *ty; enum vtype type; struct vnode *v, vb; struct l_vfs *vfs; #if FREEBSDV>=2000 struct inode ib; struct nfsnode nb; # if FREEBSDV>=4000 # if FREEBSDV<5000 struct specinfo si; # else /* FREEBSDV>=5000 */ # if !defined(HAS_CONF_MINOR) && !defined(HAS_CDEV2PRIV) struct cdev si; # endif /* !defined(HAS_CONF_MINOR) && !defined(HAS_CDEV2PRIV) */ # endif /* FREEBSDV<5000 */ # endif /* FREEBSDV>=4000 */ #endif /* FREEBSDV>=2000 */ #if FREEBSDV<5000 struct mfsnode *m; # if FREEBSDV>=2000 struct mfsnode mb; # endif /* FREEBSDV>=2000 */ #endif /* FREEBSDV<5000 */ #if defined(HAS9660FS) dev_t iso_dev; int iso_dev_def, iso_stat; INODETYPE iso_ino; long iso_links; 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 */ # if FREEBSDV>=2000 struct fdescnode fb; # endif /* FREEBSDV>=2000 */ #endif /* defined(HASFDESCFS) */ #if FREEBSDV>=5000 # if defined(HAS_UFS1_2) int ufst; struct ufsmount um; struct ufs1_dinode d1; struct ufs2_dinode d2; # endif /* !defined(HAS_UFS1_2) */ # if !defined(HAS_CONF_MINOR) && !defined(HAS_CDEV2PRIV) struct cdev cd; # endif /* !defined(HAS_CONF_MINOR) && !defined(HAS_CDEV2PRIV) */ int cds; struct devfs_dirent de; struct devfs_dirent *d; char vtbuf[32]; char *vtbp; enum vtagtype { VT_DEVFS, VT_FDESC, VT_ISOFS, VT_PSEUDOFS, VT_NFS, VT_NULL, VT_UFS, VT_ZFS, VT_UNKNOWN }; #endif /* FREEBSDV>=5000 */ #if defined(HASNULLFS) # if !defined(HASPRINTDEV) char dbuf[32]; # endif /* !defined(HASPRINTDEV) */ char *dp, *np, tbuf[1024]; struct null_node nu; int sc = 0; #endif /* defined(HASNULLFS) */ #if defined(HASPROCFS) struct pfsnode *p; struct procfsid *pfi; static int pgsz = -1; struct vmspace vm; # if FREEBSDV>=2000 struct pfsnode pb; # endif /* FREEBSDV>=2000 */ #endif /* defined(HASPROCFS) */ #if defined(HASPSEUDOFS) struct pfs_node pn; struct pfs_node *pnp; #endif /* defined(HASPSEUDOFS) */ #if defined(HAS_ZFS) zfs_info_t *z = (zfs_info_t *)NULL; zfs_info_t zi; char *zm = (char *)NULL; #else /* !defined(HAS_ZFS) */ static unsigned char zw = 0; #endif /* HAS_VFS */ enum vtagtype vtag; /* placed here to use the * artificial vtagtype * definition required for * FREEBSDV>=5000 */ #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; i = (struct inode *)NULL; n = (struct nfsnode *)NULL; Namech[0] = '\0'; #if defined(HAS9660FS) iso_dev_def = iso_stat = 0; #endif /* defined(HAS9660FS) */ #if defined(HASFDESCFS) f = (struct fdescnode *)NULL; #endif /* defined(HASFDESCFS) */ #if FREEBSDV<5000 m = (struct mfsnode *)NULL; #else /* FREEBSDV>=5000 */ cds = 0; d = (struct devfs_dirent *)NULL; # if defined(HAS_UFS1_2) ufst = 0; # endif /* !defined(HAS_UFS1_2) */ #endif /* FREEBSDV<5000 */ #if defined(HASPROCFS) p = (struct pfsnode *)NULL; #endif /* defined(HASPROCFS) */ #if defined(HASPSEUDOFS) pnp = (struct pfs_node *)NULL; #endif /* defined(HASPSEUDOFS) */ #if defined(HAS_ZFS) z = (zfs_info_t *)NULL; zm = (char *)NULL; #endif /* defined(HAS_ZFS) */ /* * 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 defined(MOUNT_NONE) switch (vfs->type) { case MOUNT_NFS: Ntype = N_NFS; break; # if defined(HASPROCFS) case MOUNT_PROCFS: Ntype = N_PROC; break; # endif /* defined(HASPROCFS) */ } #else /* !defined(MOUNT_NONE) */ if (strcasecmp(vfs->typnm, "nfs") == 0) Ntype = N_NFS; # if defined(HASPROCFS) else if (strcasecmp(vfs->typnm, "procfs") == 0) Ntype = N_PROC; # endif /* defined(HASPROCFS) */ # if defined(HASPSEUDOFS) else if (strcasecmp(vfs->typnm, "pseudofs") == 0) Ntype = N_PSEU; # endif /* defined(HASPSEUDOFS) */ #endif /* defined(MOUNT_NONE) */ } } if (Ntype == N_REGLR) { switch (v->v_type) { case VFIFO: Ntype = N_FIFO; break; default: break; } } #if FREEBSDV>=5000 /* * For FreeBSD 5 and above VCHR and VBLK vnodes get the v_rdev structure. */ if (((v->v_type == VCHR) || (v->v_type == VBLK)) && v->v_rdev # if !defined(HAS_CONF_MINOR) && !defined(HAS_CDEV2PRIV) && !kread((KA_T)v->v_rdev, (char *)&cd, sizeof(cd)) # endif /* !defined(HAS_CONF_MINOR) && !defined(HAS_CDEV2PRIV) */ ) { cds = 1; } #endif /* FREEBSDV>=5000 */ /* * Define the specific node pointer. */ #if FREEBSDV>=5000 /* * Get the pseudo vnode tag type for FreeBSD >= 5. */ vtag = VT_UNKNOWN; if (v->v_tag && !kread((KA_T)v->v_tag, (char *)&vtbuf, sizeof(vtbuf))) { vtbuf[sizeof(vtbuf) - 1] = '\0'; vtbp = vtbuf; if (!strcmp(vtbuf, "ufs")) vtag = VT_UFS; else if (!strcmp(vtbuf, "zfs")) { #if !defined(HAS_ZFS) if (!Fwarn && !zw) { (void) fprintf(stderr, "%s: WARNING: no ZFS support has been defined.\n", Pn); (void) fprintf(stderr, " See 00FAQ for more information.\n"); zw = 1; } #else /* defined(HAS_ZFS) */ vtag = VT_ZFS; #endif /* !defined(HAS_ZFS) */ } else if (!strcmp(vtbuf, "devfs")) vtag = VT_DEVFS; else if (!strcmp(vtbuf, "nfs")) vtag = VT_NFS; else if (!strcmp(vtbuf, "isofs")) vtag = VT_ISOFS; else if (!strcmp(vtbuf, "pseudofs")) vtag = VT_PSEUDOFS; else if (!strcmp(vtbuf, "null")) vtag = VT_NULL; else if (!strcmp(vtbuf, "fdesc")) vtag = VT_FDESC; } else vtbp = "(unknown)"; #else /* FREEBSDV<5000 */ vtag = v->v_tag; #endif /* FREEBSDV>=5000 */ switch (vtag) { #if FREEBSDV>=5000 case VT_DEVFS: if (!v->v_data || kread((KA_T)v->v_data, (char *)&de, sizeof(de))) { (void) snpf(Namech, Namechl, "no devfs node: %s", print_kptr((KA_T)v->v_data, (char *)NULL, 0)); enter_nm(Namech); return; } d = &de; if (v->v_type == VDIR) { if (!d->de_dir || kread((KA_T)d->de_dir, (char *)&de, sizeof(de))) { (void) snpf(Namech, Namechl, "no devfs dir node: %s", print_kptr((KA_T)d->de_dir, (char *)NULL, 0)); enter_nm(Namech); return; } } break; #endif /* FREEBSDV>=5000 */ #if defined(HASFDESCFS) case VT_FDESC: # if FREEBSDV<2000 f = (struct fdescnode *)v->v_data; # else /* FREEBSDV>=2000 */ if (kread((KA_T)v->v_data, (char *)&fb, sizeof(fb)) != 0) { (void) snpf(Namech, Namechl, "can't read fdescnode at: %s", print_kptr((KA_T)v->v_data, (char *)NULL, 0)); enter_nm(Namech); return; } f = &fb; break; # endif /* FREEBSDV<2000 */ #endif /* defined(HASFDESCFS) */ #if defined(HAS9660FS) case VT_ISOFS: if (read_iso_node(v, &iso_dev, &iso_dev_def, &iso_ino, &iso_links, &iso_sz)) { (void) snpf(Namech, Namechl, "no iso node: %s", print_kptr((KA_T)v->v_data, (char *)NULL, 0)); enter_nm(Namech); return; } iso_stat = 1; break; #endif /* defined(HAS9660FS) */ #if FREEBSDV<5000 case VT_MFS: # if FREEBSDV<2000 m = (struct mfsnode *)v->v_data; # else /* FREEBSDV>=2000 */ if (!v->v_data || kread((KA_T)v->v_data, (char *)&mb, sizeof(mb))) { (void) snpf(Namech, Namechl, "no mfs node: %s", print_kptr((KA_T)v->v_data, (char *)NULL, 0)); enter_nm(Namech); return; } m = &mb; # endif /* FREEBSDV<2000 */ #endif /* FREEBSDV<5000 */ break; case VT_NFS: #if FREEBSDV<2000 n = (struct nfsnode *)v->v_data; #else /* FREEBSDV>=2000 */ if (!v->v_data || kread((KA_T)v->v_data, (char *)&nb, sizeof(nb))) { (void) snpf(Namech, Namechl, "no nfs node: %s", print_kptr((KA_T)v->v_data, (char *)NULL, 0)); enter_nm(Namech); return; } n = &nb; #endif /* FREEBSDV<2000 */ break; #if defined(HASNULLFS) case VT_NULL: if (sc == 1) { /* * If this is the first null_node, enter a name addition containing * the mounted-on directory, the file system name, and the device * number. */ if (vfs && (vfs->dir || vfs->fsname || vfs->fsid.val[0])) { if (vfs->fsid.val[0]) { #if defined(HASPRINTDEV) dp = HASPRINTDEV(Lf, &dev); #else /* !defined(HASPRINTDEV) */ (void) snpf(dbuf, sizeof(dbuf) - 1, "%d,%d", GET_MAJ_DEV(dev), GET_MIN_DEV(dev)); dbuf[sizeof(dbuf) - 1] = '\0'; dp = dbuf; #endif /* defined(HASPRINTDEV) */ } else dp = (char *)NULL; (void) snpf(tbuf, sizeof(tbuf) - 1, "(nullfs%s%s%s%s%s%s%s)", (vfs && vfs->fsname) ? " " : "", (vfs && vfs->fsname) ? vfs->fsname : "", (vfs && vfs->dir) ? " on " : "", (vfs && vfs->dir) ? vfs->dir : "", (dp && vfs && vfs->dir) ? " (" : "", (dp && vfs && vfs->dir) ? dp : "", (dp && vfs && vfs->dir) ? ")" : ""); tbuf[sizeof(tbuf) - 1] = '\0'; np = tbuf; } else np = "(nullfs)"; (void) add_nma(np, (int)strlen(np)); } 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 FREEBSDV<2000 p = (struct pfsnode *)v->v_data; # else /* FREEBSDV>=2000 */ if (!v->v_data || kread((KA_T)v->v_data, (char *)&pb, sizeof(pb))) { (void) snpf(Namech, Namechl, "no pfs node: %s", print_kptr((KA_T)v->v_data, (char *)NULL, 0)); enter_nm(Namech); return; } p = &pb; # endif /* FREEBSDV<2000 */ break; #endif /* defined(HASPROCFS) */ #if defined(HASPSEUDOFS) case VT_PSEUDOFS: if (!v->v_data || kread((KA_T)v->v_data, (char *)&pn, sizeof(pn))) { (void) snpf(Namech, Namechl, "no pfs_node: %s", print_kptr((KA_T)v->v_data, (char *)NULL, 0)); enter_nm(Namech); return; } pnp = &pn; break; #endif /* defined(HASPSEUDOFS) */ case VT_UFS: #if FREEBSDV<2000 i = (struct inode *)v->v_data; #else /* FREEBSDV>=2000 */ if (!v->v_data || kread((KA_T)v->v_data, (char *)&ib, sizeof(ib))) { (void) snpf(Namech, Namechl, "no ufs node: %s", print_kptr((KA_T)v->v_data, (char *)NULL, 0)); enter_nm(Namech); return; } i = &ib; # if defined(HAS_UFS1_2) if (i->i_ump && !kread((KA_T)i->i_ump, (char *)&um, sizeof(um))) { if (um.um_fstype == UFS1) { if (i->i_din1 && !kread((KA_T)i->i_din1, (char *)&d1, sizeof(d1))) ufst = 1; } else { if (i->i_din2 && !kread((KA_T)i->i_din2, (char *)&d2, sizeof(d2))) ufst = 2; } } # endif /* defined(HAS_UFS1_2) */ #endif /* FREEBSDV<2000 */ #if defined(HAS_V_LOCKF) if (v->v_lockf) (void) get_lock_state((KA_T)v->v_lockf); #else /* !defined(HAS_V_LOCKF) */ if (i->i_lockf) (void) get_lock_state((KA_T)i->i_lockf); #endif /* defined(HAS_V_LOCKF) */ break; #if defined(HAS_ZFS) case VT_ZFS: if (!v->v_data || (zm = readzfsnode((KA_T)v->v_data, &zi, ((v->v_vflag & VV_ROOT) ? 1 : 0))) ) { (void) snpf(Namech, Namechl, "%s: %s", zm, print_kptr((KA_T)v->v_data, (char *)NULL, 0)); enter_nm(Namech); return; } z = &zi; #if defined(HAS_V_LOCKF) if (v->v_lockf) (void) get_lock_state((KA_T)v->v_lockf); #else /* !defined(HAS_V_LOCKF) */ if (z->lockf) (void) get_lock_state((KA_T)z->lockf); #endif /* defined(HAS_V_LOCKF) */ break; #endif /* defined(HAS_ZFS) */ default: if (v->v_type == VBAD || v->v_type == VNON) break; #if FREEBSDV<5000 (void) snpf(Namech,Namechl,"unknown file system type: %d",v->v_tag); #else /* FREEBSDV>=5000 */ (void) snpf(Namech, Namechl, "unknown file system type: %s", vtbp); #endif /* FREEBSDV<5000 */ enter_nm(Namech); return; } /* * Get device and type for printing. */ type = v->v_type; if (n) { dev = n->n_vattr.va_fsid; devs = 1; if ((type == VCHR) || (type == VBLK)) { rdev = n->n_vattr.va_rdev; rdevs = 1; } } else if (i) { #if FREEBSDV>=4000 if (i->i_dev # if !defined(HAS_CONF_MINOR) && !defined(HAS_CDEV2PRIV) && !kread((KA_T)i->i_dev, (char *)&si, sizeof(si)) # endif /* !defined(HAS_CONF_MINOR) && !defined(HAS_CDEV2PRIV) */ ) { # if defined(HAS_NO_SI_UDEV) # if defined(HAS_CONF_MINOR) || defined(HAS_CDEV2PRIV) dev = Dev2Udev((KA_T)i->i_dev); # else /* !defined(HAS_CONF_MINOR) && !defined(HAS_CDEV2PRIV) */ dev = Dev2Udev(&si); # endif /* defined(HAS_CONF_MINOR) || defined(HAS_CDEV2PRIV) */ # else /* !defined(HAS_NO_SI_UDEV) */ dev = si.si_udev; # endif /* defined(HAS_NO_SI_UDEV) */ devs = 1; } #else /* FREEBSDV<4000 */ dev = i->i_dev; devs = 1; #endif /* FREEBSDV>=4000 */ if ((type == VCHR) || (type == VBLK)) { #if FREEBSDV>=5000 # if defined(HAS_UFS1_2) if (ufst == 1) { rdev = d1.di_rdev; rdevs = 1; } else if (ufst == 2) { rdev = d2.di_rdev; rdevs = 1; } else # endif /* defined(HAS_UFS1_2) */ if (cds) { # if defined(HAS_NO_SI_UDEV) # if defined(HAS_CONF_MINOR) || defined(HAS_CDEV2PRIV) rdev = Dev2Udev((KA_T)v->v_rdev); # else /* !defined(HAS_CONF_MINOR) && !defined(HAS_CDEV2PRIV) */ rdev = Dev2Udev(&cd); # endif /* defined(HAS_CONF_MINOR) || defined(HAS_CDEV2PRIV) */ # else /* !defined(HAS_NO_SI_UDEV) */ rdev = cd.si_udev; # endif /* defined(HAS_NO_SI_UDEV) */ rdevs = 1; } #else /* FREEBSDV<5000 */ rdev = i->i_rdev; rdevs = 1; #endif /* FREEBSDV>=5000 */ } } #if defined(HAS_ZFS) else if (z) { /* * Record information returned by readzfsnode(). */ if (vfs) { dev = vfs->fsid.val[0]; devs = 1; } if ((type == VCHR) || (type == VBLK)) { if (z->rdev_def) { rdev = z->rdev; rdevs = 1; } } } #endif /* defined(HAS_ZFS) */ #if defined(HASFDESCFS) && (defined(HASFDLINK) || HASFDESCFS==1) else if (f) { # if defined(HASFDLINK) if (f->fd_link && kread((KA_T)f->fd_link, Namech, Namechl - 1) == 0) Namech[Namechl - 1] = '\0'; # if HASFDESCFS==1 else # endif /* HASFDESFS==1 */ # 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 = f_tty_dev; Lf->inode = f_tty_ino; devs = Lf->inp_ty = 1; } } # endif /* HASFDESFS==1 */ } #endif /* defined(HASFDESCFS) && (defined(HASFDLINK) || HASFDESCFS==1) */ #if defined(HAS9660FS) else if (iso_stat && iso_dev_def) { dev = iso_dev; devs = Lf->inp_ty = 1; } #endif /* defined(HAS9660FS) */ #if FREEBSDV>=5000 else if (d) { if (vfs) { dev = vfs->fsid.val[0]; devs = 1; } else { dev = DevDev; devs = 1; } if ((type == VCHR)) { # if defined(HAS_UFS1_2) if (ufst == 1) { rdev = d1.di_rdev; rdevs = 1; } else if (ufst == 2) { rdev = d2.di_rdev; rdevs = 1; } else # endif /* defined(HAS_UFS1_2) */ if (cds) { # if defined(HAS_NO_SI_UDEV) # if defined(HAS_CONF_MINOR) || defined(HAS_CDEV2PRIV) rdev = Dev2Udev((KA_T)v->v_rdev); # else /* !defined(HAS_CONF_MINOR) && !defined(HAS_CDEV2PRIV) */ rdev = Dev2Udev(&cd); # endif /* defined(HAS_CONF_MINOR) || defined(HAS_CDEV2PRIV) */ # else /* !defined(HAS_NO_SI_UDEV) */ rdev = cd.si_udev; # endif /* defined(HAS_NO_SI_UDEV) */ rdevs = 1; } } } #endif /* FREEBSDV>=5000 */ #if defined(HASPSEUDOFS) else if (pnp) { if (vfs) { dev = vfs->fsid.val[0]; devs = 1; } } #endif /* defined(HASPSEUDOFS) */ /* * Obtain the inode number. */ if (i) { Lf->inode = (INODETYPE)i->i_number; Lf->inp_ty = 1; } #if defined(HAS_ZFS) else if (z) { if (z->ino_def) { Lf->inode = z->ino; Lf->inp_ty = 1; } } #endif /* defined(HAS_ZFS) */ else if (n) { Lf->inode = (INODETYPE)n->n_vattr.va_fileid; Lf->inp_ty = 1; } #if defined(HAS9660FS) else if (iso_stat) { Lf->inode = iso_ino; Lf->inp_ty = 1; } #endif /* defined(HAS9660FS) */ #if defined(HASPROCFS) # if FREEBSDV>=2000 else if (p) { Lf->inode = (INODETYPE)p->pfs_fileno; Lf->inp_ty = 1; } # endif /* FREEBSDV>=2000 */ #endif /* defined(HASPROCFS) */ #if defined(HASPSEUDOFS) else if (pnp) { Lf->inode = (INODETYPE)pnp->pn_fileno; Lf->inp_ty = 1; } #endif /* defined(HASPSEUDOFS) */ #if FREEBSDV>=5000 else if (d) { Lf->inode = (INODETYPE)d->de_inode; Lf->inp_ty = 1; } #endif /* FREEBSDV>=5000 */ /* * Obtain the file size. */ if (Foffset) Lf->off_def = 1; else { switch (Ntype) { case N_FIFO: if (!Fsize) Lf->off_def = 1; break; case N_NFS: if (n) { Lf->sz = (SZOFFTYPE)n->n_vattr.va_size; Lf->sz_def = 1; } break; #if defined(HASPROCFS) case N_PROC: # if FREEBSDV<2000 if (type == VDIR || !p || !p->pfs_vs || kread((KA_T)p->pfs_vs, (char *)&vm, sizeof(vm))) break; if (pgsz < 0) pgsz = getpagesize(); Lf->sz = (SZOFFTYPE)((pgsz * vm.vm_tsize) + (pgsz * vm.vm_dsize) + (pgsz * vm.vm_ssize)); Lf->sz_def = 1; break; # else /* FREEBSDV>=2000 */ if (p) { switch(p->pfs_type) { case Proot: case Pproc: 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; case Pfpregs: Lf->sz = (SZOFFTYPE)sizeof(struct fpreg); Lf->sz_def = 1; break; } } # endif /* FREEBSDV<2000 */ #endif /* defined(HASPROCFS) */ #if defined(HASPSEUDOFS) case N_PSEU: Lf->sz = 0; Lf->sz_def = 1; break; #endif /* defined(PSEUDOFS) */ case N_REGLR: if (type == VREG || type == VDIR) { if (i) { #if defined(HAS_UFS1_2) if (ufst == 1) Lf->sz = (SZOFFTYPE)d1.di_size; else if (ufst == 2) Lf->sz = (SZOFFTYPE)d2.di_size; else #endif /* defined(HAS_UFS1_2) */ Lf->sz = (SZOFFTYPE)i->i_size; Lf->sz_def = 1; } #if defined(HAS_ZFS) else if (z) { if (z->sz_def) { Lf->sz = z->sz; Lf->sz_def = 1; } } #endif /* defined(HAS_ZFS) */ #if FREEBSDV<5000 else if (m) { Lf->sz = (SZOFFTYPE)m->mfs_size; Lf->sz_def = 1; } #endif /* FREEBSDV<5000 */ #if defined(HAS9660FS) else if (iso_stat) { Lf->sz = (SZOFFTYPE)iso_sz; Lf->sz_def = 1; } #endif /* defined(HAS9660FS) */ } else if ((type == VCHR || type == VBLK) && !Fsize) Lf->off_def = 1; break; } } /* * Record the link count. */ if (Fnlink) { switch(Ntype) { case N_NFS: if (n) { Lf->nlink = (long)n->n_vattr.va_nlink; Lf->nlink_def = 1; } break; case N_REGLR: if (i) { #if defined(HASEFFNLINK) Lf->nlink = (long)i->HASEFFNLINK; #else /* !defined(HASEFFNLINK) */ Lf->nlink = (long)i->i_nlink; #endif /* defined(HASEFFNLINK) */ Lf->nlink_def = 1; } #if defined(HAS_ZFS) else if (z) { if (z->nl_def) { Lf->nlink = z->nl; Lf->nlink_def = 1; } } #endif /* defined(HAS_ZFS) */ #if defined(HAS9660FS) else if (iso_stat) { Lf->nlink = iso_links; Lf->nlink_def = 1; } #endif /* defined(HAS9660FS) */ #if FREEBSDV>=5000 else if (d) { Lf->nlink = d->de_links; Lf->nlink_def = 1; } #endif /* FREEBSDV>=5000 */ break; #if defined(HASPSEUODOFS) case N_PSEU: if (pnp) { Lf->nlink = 1L; Lf->nlink_def = 1; } break; #endif /* defined(HASPSEUODOFS) */ } if (Lf->nlink_def && Nlink && (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; } /* * 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: 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; /* * Handle some special cases: * * ioctl(fd, TIOCNOTTY) files; * memory node files; * /proc files. */ if (type == VBAD) (void) snpf(Namech, Namechl, "(revoked)"); #if FREEBSDV<5000 else if (m) { Lf->dev_def = Lf->rdev_def = 0; (void) snpf(Namech, Namechl, "%#x", m->mfs_baseoff); (void) snpf(dev_ch, sizeof(dev_ch), " memory"); enter_dev_ch(dev_ch); } #endif /* FREEBSDV<5000 */ #if defined(HASPROCFS) else if (p) { Lf->dev_def = Lf->rdev_def = 0; # if FREEBSDV<2000 if (type == VDIR) (void) snpf(Namech, Namechl, "/%s", HASPROCFS); else (void) snpf(Namech, Namechl, "/%s/%0*d", HASPROCFS, PNSIZ, p->pfs_pid); enter_nm(Namech); # else /* FREEBSDV>=2000 */ ty = (char *)NULL; (void) snpf(Namech, Namechl, "/%s", HASPROCFS); switch (p->pfs_type) { case Proot: ty = "PDIR"; 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 FREEBSDV>=3000 case Pmap: ep = endnm(&sz); (void) snpf(ep, sz, "/%d/map", p->pfs_pid); ty = "PMAP"; break; case Ptype: ep = endnm(&sz); (void) snpf(ep, sz, "/%d/etype", p->pfs_pid); ty = "PETY"; break; # endif /* FREEBSDV>=3000 */ } if (ty) (void) snpf(Lf->type, sizeof(Lf->type), "%s", ty); enter_nm(Namech); # endif /* FREEBSDV<2000 */ } #endif /* defined(HASPROCFS) */ #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 { for (pfi = Procfsid; pfi; pfi = pfi->next) { if ((pfi->pid && pfi->pid == p->pfs_pid) # if defined(HASPINODEN) || (Lf->inp_ty == 1 && Lf->inode == pfi->inode) # else /* !defined(HASPINODEN) */ if (pfi->pid == p->pfs_pid) # endif /* defined(HASPINODEN) */ ) { pfi->f = 1; if (!Namech[0]) (void) snpf(Namech, Namechl, "%s", pfi->nm); Lf->sf |= SELNM; break; } } } } else #endif /* defined(HASPROCFS) */ { 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); } #if FREEBSDV>=2020 /* * process_pipe() - process a file structure whose type is DTYPE_PIPE */ void process_pipe(pa) KA_T pa; /* pipe structure address */ { char dev_ch[32], *ep; struct pipe p; size_t sz; if (!pa || kread(pa, (char *)&p, sizeof(p))) { (void) snpf(Namech, Namechl, "can't read DTYPE_PIPE pipe struct: %s", print_kptr((KA_T)pa, (char *)NULL, 0)); enter_nm(Namech); return; } (void) snpf(Lf->type, sizeof(Lf->type), "PIPE"); (void) snpf(dev_ch, sizeof(dev_ch), "%s", print_kptr(pa, (char *)NULL, 0)); enter_dev_ch(dev_ch); 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 /* FREEBSDV>=2020 */