diff options
Diffstat (limited to 'dialects/darwin/kmem/dnode.c')
-rw-r--r-- | dialects/darwin/kmem/dnode.c | 1038 |
1 files changed, 1038 insertions, 0 deletions
diff --git a/dialects/darwin/kmem/dnode.c b/dialects/darwin/kmem/dnode.c new file mode 100644 index 0000000..d634c62 --- /dev/null +++ b/dialects/darwin/kmem/dnode.c @@ -0,0 +1,1038 @@ +/* + * dnode.c - Darwin node functions for /dev/kmem-based 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.11 2006/03/27 23:24:50 abe Exp $"; +#endif + + +#include "lsof.h" + + +/* + * Local function prototypes + */ + +#if DARWINV<600 +_PROTOTYPE(static int lkup_dev_tty,(dev_t *dr, dev_t *rdr, INODETYPE *ir)); +#endif /* DARWINV<600 */ + +#if DARWINV>=800 +_PROTOTYPE(static char *getvpath,(KA_T va, struct vnode *rv)); +_PROTOTYPE(static int readvname,(KA_T addr, char *buf, int buflen)); +#endif /* DARWINV>=800 */ + + +#if DARWINV>=800 +/* + * getvpath() - get vnode path + * adapted from build_path() (.../bsd/vfs/vfs_subr.c) + */ + +static char * +getvpath(va, rv) + KA_T va; /* kernel address of the rightmost + * vnode in the path */ + struct vnode *rv; /* pointer to rightmost vnode */ +{ + char *ap; + static char *bp = (char *)NULL; + static size_t bl = (size_t)(MAXPATHLEN + MAXPATHLEN + 1); + static char *cb = (char *)NULL; + static size_t cbl = (size_t)0; + static int ce = 0; + struct mount mb; + int pl, vnl; + char *pp, vn[MAXPATHLEN+1]; + struct vnode vb; + KA_T vas = va; +/* + * Initialize the path assembly. + */ + if (!bp) { + if (!(bp = (char *)malloc((MALLOC_S)bl))) { + (void) fprintf(stderr, "%s: no space (%d) for path assembly\n", + Pn, (int)bl); + Exit(1); + } + } + pp = bp + bl - 1; + *pp = '\0'; + pl = 0; +/* + * Process the starting vnode. + */ + if (!va) + return(0); + if ((rv->v_flag & VROOT) && rv->v_mount) { + + /* + * This is the root of a file system and it has a mount structure. + * Read the mount structure. + */ + if (kread((KA_T)rv->v_mount, (char *)&mb, sizeof(mb))) + return(0); + if (mb.mnt_flag & MNT_ROOTFS) { + + /* + * This is the root file system, so the path is "/". + */ + pp--; + *pp = '/'; + pl = 1; + goto getvpath_alloc; + } else { + + /* + * Get the covered vnode's pointer and read it. Use it to + * form the path. + */ + if ((va = (KA_T)mb.mnt_vnodecovered)) { + if (readvnode(va, &vb)) + return(0); + } + } + } else { + + /* + * Use the supplied vnode. + */ + vb = *rv; + } +/* + * Accumulate the path from the vnode chain. + */ + while (va && ((KA_T)vb.v_parent != va)) { + if (!vb.v_name) { + + /* + * If there is no name pointer or parent, the assembly is complete. + */ + if (vb.v_parent) { + + /* + * It is an error if there is a parent but no name. + */ + return((char *)NULL); + } + break; + } + /* + * Read the name and add it to the assembly. + */ + if ((vnl = readvname((KA_T)vb.v_name, vn, sizeof(vn))) <= 0) + return((char *)NULL); + if ((vnl + 1 + pl + 1) > bl) + return((char *)NULL); + memmove((void *)(pp - vnl), (void *)vn, vnl); + pp -= (vnl + 1); + *pp = '/'; + pl += vnl + 1; + if ((va == vas) && (vb.v_flag & VROOT)) { + + /* + * This is the starting vnode and it is a root vnode. Read its + * mount structure. + */ + if (vb.v_mount) { + if (kread((KA_T)vb.v_mount, (char *)&mb, sizeof(mb))) + return((char *)NULL); + if (mb.mnt_vnodecovered) { + + /* + * If there's a covered vnode, read it and use it's parent + * vnode pointer. + */ + if ((va = (KA_T)mb.mnt_vnodecovered)) { + if (readvnode(va, &vb)) + return((char *)NULL); + va = (KA_T)vb.v_parent; + } + } else + va = (KA_T)NULL; + } else + va = (KA_T)NULL; + } else + va = (KA_T)vb.v_parent; + /* + * If there's a parent vnode, read it. + */ + if (va) { + if (readvnode(va, &vb)) + return((char *)NULL); + if ((vb.v_flag & VROOT) && vb.v_mount) { + + /* + * The mount point has been reached. Read the mount structure + * and use its covered vnode pointer. + */ + if (kread((KA_T)vb.v_mount, (char *)&mb, sizeof(mb))) + return((char *)NULL); + if ((va = (KA_T)mb.mnt_vnodecovered)) { + if (readvnode(va, &vb)) + return((char *)NULL); + } + } + } + } +/* + * As a special case the following code attempts to trim a path that is + * larger than MAXPATHLEN by seeing if the lsof process CWD can be removed + * from the start of the path to make it MAXPATHLEN characters or less. + */ + if (pl > MAXPATHLEN) { + + /* + * Get the cwd. If that can't be done, return an error. + */ + if (ce) + return((char *)NULL); + if (!cb) { + if (!(cb = (char *)malloc((MALLOC_S)(MAXPATHLEN + 1)))) { + (void) fprintf(stderr, "%s: no space (%d) for CWD\n", + Pn, (int)bl); + Exit(1); + } + if (!getcwd(cb, (size_t)(MAXPATHLEN + 1))) { + if (!Fwarn) { + (void) fprintf(stderr, "%s: WARNING: can't get CWD\n", + Pn); + } + ce = 1; + return((char *)NULL); + } + cb[MAXPATHLEN - 1] = '\0'; + if (!(cbl = (size_t)strlen(cb))) { + if (!Fwarn) { + (void) fprintf(stderr, "%s: WARNING: CWD is NULL\n", + Pn); + } + ce = 1; + return((char *)NULL); + } + } + /* + * See if trimming the CWD shortens the path to MAXPATHLEN or less. + */ + if ((pl <= cbl) || strncmp(cb, pp, cbl)) + return((char *)NULL); + pp += cbl; + pl -= cbl; + if (cb[cbl - 1] == '/') { + + /* + * The CWD ends in a '/', so the path must not begin with one. If + * it does, no trimming can be done. + */ + if (*pp == '/') + return((char *)NULL); + } else { + + /* + * The CWD doesn't end in a '/', so the path must begin with one. + * If it doesn't, no trimming can be done. + */ + if (*pp != '/') + return((char *)NULL); + /* + * Skip all leading path '/' characters. Some characters must + * remain. + */ + while ((pl > 0) && (*pp == '/')) { + pp++; + pl--; + } + if (!pl) + return((char *)NULL); + } + } +/* + * Allocate space for the assembled path, including terminator, and return its + * pointer. + */ + +getvpath_alloc: + + if (!(ap = (char *)malloc(pl + 1))) { + (void) fprintf(stderr, "%s: no getvpath space (%d)\n", + Pn, pl + 1); + Exit(1); + } + (void) memmove(ap, pp, pl + 1); + return(ap); +} +#endif /* DARWINV>=800 */ + + +#if DARWINV<600 +/* + * lkup_dev_tty() - look up /dev/tty + */ + +static int +lkup_dev_tty(dr, rdr, ir) + dev_t *dr; /* place to return device number */ + dev_t *rdr; /* place to return raw device number */ + INODETYPE *ir; /* place to return inode number */ +{ + int i; + + readdev(0); + for (i = 0; i < Ndev; i++) { + if (strcmp(Devtp[i].name, "/dev/tty") == 0) { + *dr = DevDev; + *rdr = Devtp[i].rdev; + *ir = (INODETYPE)Devtp[i].inode; + return(1); + } + } + return(-1); +} +#endif /* DARWINV<600 */ + + +/* + * process_node() - process vnode + */ + +void +process_node(va) + KA_T va; /* vnode kernel space address */ +{ + dev_t dev = (dev_t)0; + dev_t rdev = (dev_t)0; + unsigned char devs = 0; + unsigned char rdevs = 0; + +#if DARWINV<800 + struct devnode *d = (struct devnode *)NULL; + struct devnode db; + unsigned char lt; + char dev_ch[32]; + +# if defined(HASFDESCFS) + struct fdescnode *f = (struct fdescnode *)NULL; + struct fdescnode fb; +# endif /* defined(HASFDESCFS) */ + + static INODETYPE fi; + static dev_t fdev, frdev; + static int fs = 0; + struct inode *i = (struct inode *)NULL; + struct inode ib; + struct lockf lf, *lff, *lfp; + struct nfsnode *n = (struct nfsnode *)NULL; + struct nfsnode nb; +#else /* DARWINV>=800 */ + struct stat sb; + char *vn; +#endif /* DARWINV<800 */ + + char *ty; + enum vtype type; + struct vnode *v, vb; + struct l_vfs *vfs; + +#if DARWINV<600 + struct hfsnode *h = (struct hfsnode *)NULL; + struct hfsnode hb; + struct hfsfilemeta *hm = (struct hfsfilemeta *)NULL; + struct hfsfilemeta hmb; +#else /* DARWINV>=600 */ +# if DARWINV<800 + struct cnode *h = (struct cnode *)NULL; + struct cnode hb; + struct filefork *hf = (struct filefork *)NULL; + struct filefork hfb; +# endif /* DARWINV<800 */ +#endif /* DARWINV<600 */ + +#if defined(HAS9660FS) + dev_t iso_dev; + int iso_dev_def = 0; + INODETYPE iso_ino; + long iso_links; + int iso_stat = 0; + SZOFFTYPE iso_sz; +#endif /* defined(HAS9660FS) */ + +/* + * Read the vnode. + */ + if ( ! va) { + enter_nm("no vnode address"); + return; + } + v = &vb; + if (readvnode(va, v)) { + enter_nm(Namech); + return; + } + type = v->v_type; + +#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 (strcasecmp(vfs->typnm, "nfs") == 0) + Ntype = N_NFS; + +#if DARWINV<130 + else if (strcasecmp(vfs->typnm, "afpfs") == 0) + Ntype = N_AFPFS; +#endif /* DARWINV<130 */ + + } + } + if (Ntype == N_REGLR) { + switch (v->v_type) { + case VFIFO: + Ntype = N_FIFO; + break; + default: + break; + } + } + +#if DARWINV<800 +/* + * Define the specific node pointer. + */ + switch (v->v_tag) { + +# if DARWINV>120 + case VT_AFP: + break; +# endif /* DARWINV>120 */ + +# if DARWINV>120 + case VT_CDDA: + break; +# endif /* DARWINV>120 */ + +# if DARWINV>120 + case VT_CIFS: + break; +# endif /* DARWINV>120 */ + + case VT_DEVFS: + if (!v->v_data + || kread((KA_T)v->v_data, (char *)&db, sizeof(db))) { + (void) snpf(Namech, Namechl, "no devfs node: %#x", v->v_data); + enter_nm(Namech); + return; + } + d = &db; + break; + +# if defined(HASFDESCFS) + case VT_FDESC: + if (!v->v_data + || kread((KA_T)v->v_data, (char *)&fb, sizeof(fb))) { + (void) snpf(Namech, Namechl, "no fdesc node: %s", + print_kptr((KA_T)v->v_data, (char *)NULL, 0)); + enter_nm(Namech); + return; + } + f = &fb; + break; +# endif /* defined(HASFDESCFS) */ + + case VT_HFS: + +# if DARWINV<130 + if (Ntype != N_AFPFS) { +# endif /* DARWINV<130 */ + + if (!v->v_data + || kread((KA_T)v->v_data, (char *)&hb, sizeof(hb))) { + (void) snpf(Namech, Namechl, "no hfs node: %s", + print_kptr((KA_T)v->v_data, (char *)NULL, 0)); + enter_nm(Namech); + return; + } + h = &hb; + +# if DARWINV<600 + if (!h->h_meta + || kread((KA_T)h->h_meta, (char *)&hmb, sizeof(hmb))) { + (void) snpf(Namech, Namechl, "no hfs node metadata: %s", + print_kptr((KA_T)v->v_data, (char *)NULL, 0)); + enter_nm(Namech); + return; + } + hm = &hmb; +# else /* DARWINV>=600 */ + if (v->v_type == VDIR) + break; + if (h->c_rsrc_vp == v) + hf = h->c_rsrcfork; + else + hf = h->c_datafork; + if (!hf + || kread((KA_T)hf, (char *)&hfb, sizeof(hfb))) { + (void) snpf(Namech, Namechl, "no hfs node fork: %s", + print_kptr((KA_T)v->v_data, (char *)NULL, 0)); + enter_nm(Namech); + return; + } + hf = &hfb; +# endif /* DARWINV<600 */ + +# if DARWINV<130 + } +# endif /* DARWINV<130 */ + + break; + +# 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) */ + + case VT_NFS: + 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; + break; + +# if DARWINV>120 + case VT_UDF: + break; +# endif /* DARWINV>120 */ + + case VT_UFS: + 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 ((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; + 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; + +# if DARWINV>120 + case VT_WEBDAV: + break; +# endif /* DARWINV>120 */ + + 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. + */ + if (n) { + dev = n->n_vattr.va_fsid; + devs = 1; + } else if (i) { + dev = i->i_dev; + devs = 1; + if ((type == VCHR) || (type == VBLK)) { + rdev = i->i_rdev ; + rdevs = 1; + } + } + +# if defined(HASFDESCFS) + else if (f) { + if (f->fd_link + && !kread((KA_T)f->fd_link, Namech, Namechl -1)) + Namech[Namechl - 1] = '\0'; + +# if DARWINV<600 + else if (f->fd_type == Fctty) { + if (fs == 0) + fs = lkup_dev_tty(&fdev, &frdev, &fi); + if (fs == 1) { + dev = fdev; + rdev = frdev; + devs = Lf->inp_ty = rdevs = 1; + Lf->inode = fi; + } + } + } +# endif /* DARWINV<600 */ +# endif /* defined(HASFDESCFS) */ + + else if (h) { + +# if DARWINV<600 + dev = hm->h_dev; +# else /* DARWINV>=600 */ + dev = h->c_dev; +# endif /* DARWINV<600 */ + + devs = 1; + if ((type == VCHR) || (type == VBLK)) { + +# if DARWINV<600 + rdev = hm->h_rdev; +# else /* DARWINV>=600 */ + rdev = h->c_rdev; +# endif /* DARWINV<600 */ + + rdevs = 1; + } + } else if (d) { + dev = DevDev; + devs = 1; + rdev = d->dn_typeinfo.dev; + rdevs = 1; + } + +# if defined(HAS9660FS) + else if (iso_stat && iso_dev_def) { + dev = iso_dev; + devs = Lf->inp_ty = 1; + } +# endif /* defined(HAS9660FS) */ + + +/* + * Obtain the inode number. + */ + if (i) { + Lf->inode = (INODETYPE)i->i_number; + Lf->inp_ty = 1; + } else if (n) { + Lf->inode = (INODETYPE)n->n_vattr.va_fileid; + Lf->inp_ty = 1; + } else if (h) { + +# if DARWINV<600 + Lf->inode = (INODETYPE)hm->h_nodeID; +# else /* DARWINV>=600 */ + Lf->inode = (INODETYPE)h->c_fileid; +# endif /* DARWINV<600 */ + + Lf->inp_ty = 1; + } + +# if defined(HAS9660FS) + else if (iso_stat) { + Lf->inode = iso_ino; + Lf->inp_ty = 1; + } +# endif /* defined(HAS9660FS) */ + +/* + * 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 DARWINV<130 + case N_AFPFS: + break; +# endif /* DARWINV<130 */ + + case N_REGLR: + if (type == VREG || type == VDIR) { + if (i) { + Lf->sz = (SZOFFTYPE)i->i_size; + Lf->sz_def = 1; + } else if (h) { + +# if DARWINV<600 + Lf->sz = (type == VDIR) ? (SZOFFTYPE)hm->h_size + : (SZOFFTYPE)h->fcbEOF; +# else /* DARWINV>=600 */ + if (type == VDIR) + Lf->sz = (SZOFFTYPE)h->c_nlink * 128; + else + Lf->sz = (SZOFFTYPE)hf->ff_size; +# endif /* DARWINV<600 */ + + Lf->sz_def = 1; + } + +# 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; + +# if DARWINV<130 + case N_AFPFS: + break; +# endif /* DARWINV<130 */ + + case N_REGLR: + if (i) { + Lf->nlink = (long)i->i_nlink; + Lf->nlink_def = 1; + } else if (h) { + +# if DARWINV<600 + Lf->nlink = (long)hm->h_nlink; +# else /* DARWINV>=600 */ + Lf->nlink = (long)h->c_nlink; +# endif /* DARWINV<600 */ + + Lf->nlink_def = 1; + } + +# if defined(HAS9660FS) + else if (iso_stat) { + Lf->nlink = iso_links; + Lf->nlink_def = 1; + } +# endif /* defined(HAS9660FS) */ + + break; + } + if (Lf->nlink_def && Nlink && (Lf->nlink < Nlink)) + Lf->sf |= SELNLINK; + } +#else /* DARWINV>=800 */ + +/* + * Process a vnode for Darwin >= 8.0. + */ + if ((vn = getvpath(va, v))) { + + /* + * If the vnode yields a path, get the file's information by doing + * a "safe" stat(2) of the path. + */ + if (!statsafely(vn, &sb)) { + + /* + * Save file size or offset. + */ + if (Foffset) { + Lf->off_def = 1; + } else { + switch (Ntype) { + case N_FIFO: + if (!Fsize) + Lf->off_def = 1; + break; + case N_NFS: + case N_REGLR: + if (type == VREG || type == VDIR) { + Lf->sz = sb.st_size; + Lf->sz_def = 1; + } else if ((type == VCHR || type == VBLK) && !Fsize) + Lf->off_def = 1; + break; + } + } + /* + * Save node number. + */ + Lf->inode = (INODETYPE)sb.st_ino; + Lf->inp_ty = 1; + /* + * Optionally save link count. + */ + if (Fnlink) { + Lf->nlink = sb.st_nlink; + Lf->nlink_def = 1; + } + /* + * Save device number and path. + */ + switch (v->v_tag) { + case VT_DEVFS: + if (vn) + (void) free((FREE_P *)vn); + dev = DevDev; + devs = 1; + break; + default : + Lf->V_path = vn; + dev = sb.st_dev; + devs = 1; + break; + } + /* + * Save character and block device number. + */ + if ((type == VCHR) || (type == VBLK)) { + rdev = sb.st_rdev; + rdevs = 1; + } + } else { + + /* + * Indicate a stat(2) failure in Namech[]. + */ + (void) snpf(Namech, Namechl, "stat(%s): %s", vn, + strerror(errno)); + (void) free((FREE_P *)vn); + } + /* + * Record an NFS file. + */ + if (vfs && !strcmp(vfs->typnm, "nfs")) + Ntype = N_NFS; + } +#endif /* DARWINV>=800 */ + +/* + * 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: + 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 = (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 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); +} + + +#if DARWINV>=800 +/* + * readvname() - read vnode's path name + */ + +static int +readvname(addr, buf, buflen) + KA_T addr; /* kernel v_path address */ + char *buf; /* receiving buffer */ + int buflen; /* sizeof(buf) */ +{ + int n, rl; +/* + * Read the name 32 characters at a time, until a NUL character + * has been read or the buffer has been filled. + */ + for (n = 0; n < buflen; addr += 32, n += 32) { + rl = buflen - n; + if (rl > 32) + rl = 32; + if (kread(addr, &buf[n], rl)) + return(0); + buf[n + rl] = '\0'; + if ((rl = (int)strlen(&buf[n])) < 32) { + return(n + rl); + } + } + return(0); +} +#endif /* DARWINV>=800 */ |