| /* |
| * dnode.c - SCO UnixWare node functions for lsof |
| */ |
| |
| |
| /* |
| * Copyright 1996 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 1996 Purdue Research Foundation.\nAll rights reserved.\n"; |
| static char *rcsid = "$Id: dnode.c,v 1.28 2006/03/28 21:57:57 abe Exp $"; |
| #endif |
| |
| |
| #include "lsof.h" |
| #include <sys/fs/namenode.h> |
| |
| #if UNIXWAREV>=70000 |
| #undef IREAD |
| #undef IWRITE |
| #undef IEXEC |
| #endif /* UNIXWAREV>=70000 */ |
| |
| #if defined(HAS_UW_CFS) |
| #include <fs/nsc_cfs/cnode.h> |
| #endif /* defined(HAS_UW_CFS) */ |
| |
| #include <sys/fs/ufs_inode.h> |
| |
| #if defined(HASXNAMNODE) |
| #include <sys/fs/xnamnode.h> |
| #endif /* defined(HASXNAMNODE) */ |
| |
| |
| _PROTOTYPE(static void ent_fa,(KA_T *a1, KA_T *a2, char *d)); |
| _PROTOTYPE(static int get_vty,(struct vnode *v, KA_T va, struct vfs *kv, int *fx)); |
| |
| #if UNIXWAREV<70103 |
| _PROTOTYPE(static int examine_stream,(KA_T vs, struct queue *q, char *mn, |
| char *sn, KA_T *sqp)); |
| #else /* UNIXWAREV>=70103 */ |
| _PROTOTYPE(static int examine_stream,(KA_T vs, struct queue *q, char **mch, |
| char **mn, char *sn, KA_T *sqp)); |
| _PROTOTYPE(static struct l_dev * findspdev,(dev_t *dev, dev_t *rdev)); |
| _PROTOTYPE(static void getspdev,(void)); |
| _PROTOTYPE(static int get_vty,(struct vnode *v, KA_T va, struct vfs *kv, |
| int *fx)); |
| _PROTOTYPE(static struct l_dev * ismouse,(struct vnode *va, struct l_ino *i, |
| int fx, struct vfs *kv)); |
| #endif /* UNIXWAREV<70103 */ |
| |
| _PROTOTYPE(static struct l_dev * findstrdev,(dev_t *dev, dev_t *rdev)); |
| _PROTOTYPE(static char isvlocked,(struct vnode *va)); |
| _PROTOTYPE(static int readlino,(int fx, struct vnode *v, struct l_ino *i)); |
| |
| |
| /* |
| * Local variables and definitions |
| */ |
| |
| static struct protos { |
| char *module; /* stream module name */ |
| char *proto; /* TCP/IP protocol name */ |
| } Protos[] = { |
| { "tcpu", "TCP" }, |
| { "udpu", "UDP" }, |
| { "tcpl", "TCP" }, |
| { "tcp", "TCP" }, |
| { "udpl", "UDP" }, |
| { "udp", "UDP" }, |
| |
| #if UNIXWAREV<70103 |
| { "icmp", "ICMP" }, |
| { "ipu", "IP" }, |
| { "ipl", "IP" }, |
| { "ip", "IP" }, |
| #endif /* UNIXWAREV<70103 */ |
| |
| }; |
| #define NPROTOS (sizeof(Protos)/sizeof(struct protos)) |
| |
| #if UNIXWAREV>=70103 |
| static struct specdev { |
| char *name; |
| struct l_dev *dp; |
| } SpDev[] = { |
| { "/dev/log", (struct l_dev *)NULL }, |
| { "/dev/mouse", (struct l_dev *)NULL }, |
| }; |
| #define SPDEV_CT (sizeof(SpDev) / sizeof(struct specdev)) |
| static int SpDevX = -1; /* SpDev[] maximum index */ |
| #endif /* UNIXWAREV>=70103 */ |
| |
| |
| /* |
| * ent_fa() - enter fattach addresses in NAME column addition |
| */ |
| |
| static void |
| ent_fa(a1, a2, d) |
| KA_T *a1; /* first fattach address (NULL OK) */ |
| KA_T *a2; /* second fattach address */ |
| char *d; /* direction ("->" or "<-") */ |
| { |
| char buf[64], *cp, tbuf[32]; |
| MALLOC_S len; |
| |
| if (Lf->nma) |
| return; |
| if (!a1) |
| (void) snpf(buf, sizeof(buf), "(FA:%s%s)", d, |
| print_kptr(*a2, (char *)NULL, 0)); |
| else |
| (void) snpf(buf, sizeof(buf), " (FA:%s%s%s)", |
| print_kptr(*a1, tbuf, sizeof(tbuf)), d, |
| print_kptr(*a2, (char *)NULL, 0)); |
| len = strlen(buf) + 1; |
| if ((cp = (char *)malloc(len)) == NULL) { |
| (void) fprintf(stderr, |
| "%s: no space for fattach addresses at PID %d, FD %s\n", |
| Pn, Lp->pid, Lf->fd); |
| Exit(1); |
| } |
| (void) snpf(cp, len, "%s", buf); |
| Lf->nma = cp; |
| } |
| |
| |
| /* |
| * examine_stream() - examine stream |
| */ |
| |
| static int |
| |
| #if UNIXWAREV<70103 |
| examine_stream(vs, q, mn, sn, sqp) |
| #else /* UNIXWAREV>=70103 */ |
| examine_stream(vs, q, mch, mn, sn, sqp) |
| #endif /* UNIXWAREV<70103 */ |
| |
| KA_T vs; /* stream head's stdata kernel |
| * address */ |
| struct queue *q; /* queue structure buffer */ |
| |
| #if UNIXWAREV>=70103 |
| char **mch; /* important stream module name chain, |
| * module names separated by "->" */ |
| char **mn; /* pointer to module name receiver */ |
| #else /* UNIXWAREV<70103 */ |
| char *mn; /* module name receiver */ |
| #endif /* UNIXWAREV>=70103 */ |
| |
| char *sn; /* special module name */ |
| KA_T *sqp; /* special module's q_ptr */ |
| { |
| struct module_info mi; |
| KA_T qp; |
| struct qinit qi; |
| struct stdata sd; |
| char tbuf[32]; |
| |
| #if UNIXWAREV>=70103 |
| static char *ab = (char *)NULL; |
| static MALLOC_S aba = (size_t)0; |
| MALLOC_S al, len, naba, tlen; |
| char *ap; |
| char tmnb[STRNML+1]; |
| #endif /* UNIXWAREV>=70103 */ |
| |
| /* |
| * Read stream's head. |
| */ |
| if (!vs || readstdata(vs, &sd)) { |
| (void) snpf(Namech, Namechl, "can't read stream head from %s", |
| print_kptr(vs, (char *)NULL, 0)); |
| enter_nm(Namech); |
| return(1); |
| } |
| if (!sd.sd_wrq) { |
| enter_nm("no stream write queue"); |
| return(1); |
| } |
| /* |
| * Examine the write queue. |
| */ |
| |
| #if UNIXWAREV<70103 |
| for (qp = (KA_T)sd.sd_wrq, *mn = '\0'; qp; qp = (KA_T)q->q_next) |
| #else /* UNIXWAREV>=70103 */ |
| for (qp = (KA_T)sd.sd_wrq, al = (MALLOC_S)0, ap = ab, |
| *mn = (char *)NULL, tmnb[sizeof(tmnb) - 1] = '\0'; |
| qp; |
| qp = (KA_T)q->q_next) |
| #endif /* UNIXWAREV<70103 */ |
| |
| { |
| |
| /* |
| * Read stream queue entry. |
| */ |
| if (kread(qp, (char *)q, sizeof(struct queue))) { |
| (void) snpf(Namech, Namechl, "can't read stream queue from %s", |
| print_kptr(qp, (char *)NULL, 0)); |
| enter_nm(Namech); |
| return(1); |
| } |
| /* |
| * Read queue's information structure. |
| */ |
| if (!q->q_qinfo || readstqinit((KA_T)q->q_qinfo, &qi)) { |
| (void) snpf(Namech, Namechl, "can't read qinit for %s from %s", |
| print_kptr(qp, tbuf, sizeof(tbuf)), |
| print_kptr((KA_T)q->q_qinfo, (char *)NULL, 0)); |
| enter_nm(Namech); |
| return(1); |
| } |
| /* |
| * Read module information structure. |
| */ |
| if (!qi.qi_minfo || readstmin((KA_T)qi.qi_minfo, &mi)) { |
| (void) snpf(Namech, Namechl, |
| "can't read module info for %s from %s", |
| print_kptr((KA_T)q->q_qinfo, tbuf, sizeof(tbuf)), |
| print_kptr((KA_T)qi.qi_minfo, (char *)NULL, 0)); |
| enter_nm(Namech); |
| return(1); |
| } |
| /* |
| * Read module name. |
| */ |
| |
| #if UNIXWAREV<70103 |
| if (!mi.mi_idname || kread((KA_T)mi.mi_idname, mn, STRNML-1)) |
| #else /* UNIXWAREV>=70103 */ |
| if (!mi.mi_idname || kread((KA_T)mi.mi_idname, tmnb, STRNML)) |
| #endif /* UNIXWAREV<70103 */ |
| |
| { |
| (void) snpf(Namech, Namechl, |
| "can't read module name for %s from %s", |
| print_kptr((KA_T)qi.qi_minfo, tbuf, sizeof(tbuf)), |
| print_kptr((KA_T)mi.mi_idname, (char *)NULL, 0)); |
| enter_nm(Namech); |
| return(1); |
| } |
| |
| #if UNIXWAREV<70103 |
| *(mn + STRNML - 1) = '\0'; |
| #endif /* UNIXWAREV<70103 */ |
| |
| /* |
| * Save the q_ptr of the first special module. |
| */ |
| |
| #if UNIXWAREV<70103 |
| if (!sn || *sqp || !q->q_ptr) |
| continue; |
| if (strcmp(mn, sn) == 0) |
| *sqp = (KA_T)q->q_ptr; |
| #else /* UNIXWAREV>=70103 */ |
| if (sn && !*sqp && q->q_ptr) { |
| if (strcmp(tmnb, sn) == 0) |
| *sqp = (KA_T)q->q_ptr; |
| } |
| /* |
| * Assemble the module name chain. Allocate space as required. |
| * Skip null module names and some "uninteresting" ones. |
| */ |
| len = strlen(tmnb); |
| if (len |
| && strcmp(tmnb, "strrhead") |
| && strcmp(tmnb, "strwhead") |
| ) { |
| tlen = len + 1 + (al ? 2 : 0); |
| if ((tlen + al) > aba) { |
| aba = tlen + al + 64; /* allocate some extra */ |
| if (!ab) { |
| ab = ap = (char *)malloc(aba); |
| } else { |
| ab = (char *)realloc((MALLOC_P *)ab, aba); |
| if (al) |
| ap = ab + (al - 1); |
| else |
| ap = ab; |
| } |
| if (!ab) { |
| (void) fprintf(stderr, |
| "%s: no space for stream chain", Pn); |
| Exit(1); |
| } |
| } |
| (void) snpf(ap, aba - (al - 1), "%s%s", |
| (ap == ab) ? "" : "->", tmnb); |
| *mn = ap + ((ap == ab) ? 0 : 2); |
| al += tlen; |
| ap += (tlen - 1); |
| } |
| #endif /* UNIXWAREV<70103 */ |
| |
| } |
| |
| #if UNIXWAREV>=70103 |
| *mch = ab; |
| if (!*mn) |
| *mn = ""; |
| #endif /* UNIXWAREV>=70103 */ |
| |
| return(0); |
| } |
| |
| |
| #if UNIXWAREV>=70103 |
| /* |
| * findspdev() - find special device by raw major device number |
| */ |
| |
| static struct l_dev * |
| findspdev(dev, rdev) |
| dev_t *dev; /* containing device */ |
| dev_t *rdev; /* raw device */ |
| { |
| int i; |
| struct l_dev *dp; |
| |
| if (*dev != DevDev) |
| return((struct l_dev *)NULL); |
| if (SpDevX < 0) |
| (void) getspdev(); |
| for (i = 0; i < SpDevX; i++) { |
| if (!(dp = SpDev[i].dp)) |
| continue; |
| if (GET_MAJ_DEV(*rdev) == GET_MAJ_DEV(dp->rdev)) |
| return(dp); |
| } |
| return((struct l_dev *)NULL); |
| } |
| #endif /* UNIXWAREV>=70103 */ |
| |
| |
| /* |
| * findstrdev() - look up stream device by device number |
| */ |
| |
| static struct l_dev * |
| findstrdev(dev, rdev) |
| dev_t *dev; /* device */ |
| dev_t *rdev; /* raw device */ |
| { |
| struct clone *c; |
| struct l_dev *dp; |
| /* |
| * Search device table for match. |
| */ |
| |
| #if HASDCACHE |
| |
| findstrdev_again: |
| |
| #endif /* HASDCACHE */ |
| |
| if ((dp = lkupdev(dev, rdev, 0, 0))) |
| return(dp); |
| /* |
| * Search for clone. |
| */ |
| if (Clone) { |
| for (c = Clone; c; c = c->next) { |
| if (GET_MAJ_DEV(*rdev) == GET_MIN_DEV(Devtp[c->dx].rdev)) { |
| |
| #if HASDCACHE |
| if (DCunsafe && !Devtp[c->dx].v && !vfy_dev(&Devtp[c->dx])) |
| goto findstrdev_again; |
| #endif /* HASDCACHE */ |
| |
| return(&Devtp[c->dx]); |
| } |
| } |
| } |
| |
| #if UNIXWAREV<70103 |
| return((struct l_dev *)NULL); |
| #else /* UNIXWAREV>=70103 */ |
| /* |
| * Search for non-clone clone. |
| */ |
| return(findspdev(dev, rdev)); |
| #endif /* UNIXWAREV<70103 */ |
| |
| } |
| |
| |
| #if UNIXWAREV>=70103 |
| /* |
| * getspecdev() -- get Devtp[] pointers for "special" devices |
| */ |
| |
| static void |
| getspdev() |
| { |
| struct l_dev *dp; |
| int i, j, n; |
| |
| if (SpDevX >= 0) |
| return; |
| /* |
| * Scan Devtp[] for the devices named in SpDev[]. |
| */ |
| for (i = n = 0; (i < Ndev) && (n < SPDEV_CT); i++) { |
| dp = Sdev[i]; |
| for (j = 0; j < SPDEV_CT; j++) { |
| if (SpDev[j].dp) |
| continue; |
| if (strcmp(SpDev[j].name, dp->name) == 0) { |
| SpDev[j].dp = dp; |
| n++; |
| SpDevX = j + 1; |
| break; |
| } |
| } |
| } |
| if (SpDevX < 0) |
| SpDevX = 0; |
| } |
| #endif /* UNIXWAREV>=70103 */ |
| |
| |
| /* |
| * get_vty() - get vnode type |
| * |
| * return: vnode type as an N_* symbol value |
| * N_REGLR if no special file system type applies |
| * -1 if the vnode type is VUNNAMED |
| * -2 if the vfs structure has an illegal type index |
| * -3 if the vfs structure can't be read |
| */ |
| |
| static int |
| get_vty(v, va, kv, fx) |
| struct vnode *v; /* vnode to test */ |
| KA_T va; /* vnode's kernel address */ |
| struct vfs *kv; /* copy of vnode's kernel vfs struct */ |
| int *fx; /* file system type index */ |
| { |
| int fxt; |
| int nty = N_REGLR; |
| char tbuf[32]; |
| |
| if (v->v_type == VUNNAMED) { |
| *fx = 0; |
| return(-1); |
| } |
| if (!v->v_vfsp) { |
| *fx = 0; |
| if ((v->v_type == VFIFO) || v->v_stream) |
| return(N_STREAM); |
| return(N_REGLR); |
| } |
| if (!kread((KA_T)v->v_vfsp, (char *)kv, sizeof(struct vfs))) { |
| |
| /* |
| * Check the file system type. |
| */ |
| fxt = kv->vfs_fstype; |
| if (fxt > 0 && fxt <= Fsinfomax) { |
| if (!strcmp(Fsinfo[fxt-1], "fifofs")) |
| nty = N_FIFO; |
| else if (!strcmp(Fsinfo[fxt-1], "nfs")) |
| nty = N_NFS; |
| else if (!strcmp(Fsinfo[fxt-1], "namefs")) |
| nty = N_NM; |
| else if (!strcmp(Fsinfo[fxt-1], "nsc_cfs")) |
| nty = N_CFS; |
| |
| |
| #if defined(HASPROCFS) |
| else if (!strcmp(Fsinfo[fxt-1], "proc")) |
| nty = N_PROC; |
| #endif /* defined(HASPROCFS) */ |
| |
| } else { |
| (void) snpf(Namech, Namechl, |
| "vnode@%s: bad file system index (%d)", |
| print_kptr(va, (char *)NULL, 0), fxt); |
| enter_nm(Namech); |
| return(-2); |
| } |
| } else { |
| (void) snpf(Namech, Namechl, "vnode@%s: bad vfs pointer (%s)", |
| print_kptr(va, tbuf, sizeof(tbuf)), |
| print_kptr((KA_T)v->v_vfsp, (char *)NULL, 0)); |
| enter_nm(Namech); |
| return(-3); |
| } |
| if (nty == N_REGLR) { |
| if (v->v_type == VFIFO) |
| nty = N_FIFO; |
| else if (v->v_stream) |
| nty = N_STREAM; |
| } |
| *fx = fxt; |
| return(nty); |
| } |
| |
| |
| #if UNIXWAREV>=70103 |
| /* |
| * ismouse() - is vnode attached to /dev/mouse |
| */ |
| |
| static struct l_dev * |
| ismouse(va, i, fx, kv) |
| struct vnode *va; /* local vnode address */ |
| struct l_ino *i; /* local inode structure */ |
| int fx; /* file system index */ |
| struct vfs *kv; /* copy of kernel VFS structure */ |
| { |
| struct l_dev *dp; |
| int j; |
| |
| if ((fx < 1) || (fx > Fsinfomax)) |
| return((struct l_dev *)NULL); |
| if ((dp = findspdev(&kv->vfs_dev, &va->v_rdev))) { |
| i->dev = kv->vfs_dev; |
| i->dev_def = 1; |
| i->nlink = (long)0; |
| i->nlink_def = 0; |
| i->nm = (char *)NULL; |
| i->number = dp->inode; |
| i->number_def = 1; |
| i->rdev = va->v_rdev; |
| i->rdev_def = 0; |
| i->size = (SZOFFTYPE)0; |
| i->size_def = 0; |
| Ntype = N_REGLR; |
| } |
| return(dp); |
| } |
| #endif /* UNIXWAREV>=70103 */ |
| |
| |
| /* |
| * isvlocked() - is a vnode locked |
| */ |
| |
| static char |
| isvlocked(va) |
| struct vnode *va; /* local vnode address */ |
| { |
| struct filock f; |
| KA_T flf, flp; |
| int i, l; |
| |
| if (!(flf = (KA_T)va->v_filocks)) |
| return(' '); |
| flp = flf; |
| i = 0; |
| do { |
| if (i++ > 1000) |
| break; |
| if (kread(flp, (char *)&f, sizeof(f))) |
| break; |
| if (f.set.l_sysid || f.set.l_pid != (pid_t)Lp->pid) |
| continue; |
| if (!f.set.l_whence && !f.set.l_start |
| |
| #if UNIXWAREV>=70101 |
| # if UNIXWAREV<70103 |
| && (f.set.l_len == 0x7fffffffffffffff) |
| # else /* UNIXWAREV>=70103 */ |
| && (f.set.l_len == 0x7fffffffffffffffLL) |
| # endif /* UNIXWAREV<70103 */ |
| #else /* UNIXWAREV<70101 */ |
| && ((f.set.l_len == 0) || (f.set.l_len == 0x7fffffff)) |
| #endif /* UNIXWAREV>=70101*/ |
| |
| ) |
| l = 1; |
| else |
| l = 0; |
| switch (f.set.l_type & (F_RDLCK | F_WRLCK)) { |
| case F_RDLCK: |
| return((l) ? 'R' : 'r'); |
| case F_WRLCK: |
| return((l) ? 'W' : 'w'); |
| case (F_RDLCK + F_WRLCK): |
| return('u'); |
| default: |
| return(' '); |
| } |
| } while (flp != (KA_T)f.next && (flp = (KA_T)f.next) && flp != flf); |
| return(' '); |
| } |
| |
| |
| /* |
| * process_node() - process node |
| */ |
| |
| void |
| process_node(na) |
| KA_T na; /* vnode kernel space address */ |
| { |
| char *cp, *ep; |
| dev_t dev, rdev; |
| unsigned char devs = 0; |
| unsigned char rdevs = 0; |
| unsigned char ni = 0; |
| struct l_dev *dp; |
| struct fifonode f; |
| int fx, rfx; |
| struct l_ino i; |
| int is = 1; |
| int j, k; |
| KA_T ka; |
| struct vfs kv, rkv; |
| |
| #if UNIXWAREV<70103 |
| struct module_info mi; |
| char mn[STRNML]; |
| #else /* UNIXWAREV>=70103 */ |
| char *mch, *mn; |
| #endif /* UNIXWAREV<70103 */ |
| |
| struct mnode mno; |
| MALLOC_S msz; |
| struct namenode nn; |
| int px; |
| struct queue q; |
| struct rnode r; |
| struct vnode rv, v; |
| struct snode s; |
| unsigned char sd = 1; |
| struct so_so so; |
| KA_T sqp = (KA_T)NULL; |
| size_t sz; |
| char tbuf[32], *ty; |
| enum vtype type; |
| struct sockaddr_un ua; |
| |
| #if defined(HASPROCFS) |
| struct as as; |
| struct proc p; |
| KA_T pa; |
| struct procfsid *pfi; |
| long pid; |
| struct prnode pr; |
| # if UNIXWAREV<20102 |
| struct pid pids; |
| # else /* UNIXWAREV>=20102 */ |
| struct prcommon prc; |
| # endif /* UNIXWAREV>=20102 */ |
| #endif /* defined(HASPROCFS) */ |
| |
| /* |
| * Read the vnode. |
| */ |
| if (!na) { |
| enter_nm("no vnode address"); |
| return; |
| } |
| if (readvnode((KA_T)na, &v)) { |
| enter_nm(Namech); |
| return; |
| } |
| |
| #if defined(HASNCACHE) |
| Lf->na = na; |
| #endif /* defined(HASNCACHE) */ |
| |
| #if defined(HASFSTRUCT) |
| Lf->fna = na; |
| Lf->fsv |= FSV_NI; |
| #endif /* defined(HASFSTRUCT) */ |
| |
| /* |
| * Determine the vnode type. |
| */ |
| if ((Ntype = get_vty(&v, na, &kv, &fx)) < 0) { |
| if (Ntype == -1) |
| Lf->sf = 0; |
| return; |
| } |
| /* |
| * Determine the lock state. |
| */ |
| |
| get_lock_state: |
| |
| Lf->lock = isvlocked(&v); |
| /* |
| * Read the fifonode, inode, namenode, prnode, rnode, snode, ... |
| */ |
| switch (Ntype) { |
| case N_FIFO: |
| if (!v.v_data || readfifonode((KA_T)v.v_data, &f)) { |
| (void) snpf(Namech, Namechl, |
| "vnode@%s: can't read fifonode (%s)", |
| print_kptr(na, tbuf, sizeof(tbuf)), |
| print_kptr((KA_T)v.v_data, (char *)NULL, 0)); |
| enter_nm(Namech); |
| return; |
| } |
| if (f.fn_realvp) { |
| if (readvnode((KA_T)f.fn_realvp, &rv)) { |
| (void) snpf(Namech, Namechl, |
| "fifonode@%s: can't read real vnode (%s)", |
| print_kptr((KA_T)v.v_data, tbuf, sizeof(tbuf)), |
| print_kptr((KA_T)f.fn_realvp, (char *)NULL, 0)); |
| enter_nm(Namech); |
| return; |
| } |
| |
| #if defined(HASNCACHE) |
| Lf->na = (KA_T)f.fn_realvp; |
| #endif /* defined(HASNCACHE) */ |
| |
| if (!rv.v_data || (is = readlino(fx, &rv, &i))) { |
| (void) snpf(Namech, Namechl, |
| "fifonode@%s: can't read inode (%s)", |
| print_kptr((KA_T)v.v_data, tbuf, sizeof(tbuf)), |
| print_kptr((KA_T)rv.v_data, (char *)NULL, 0)); |
| enter_nm(Namech); |
| return; |
| } |
| } else |
| ni = 1; |
| break; |
| case N_NFS: |
| if (!v.v_data || readrnode((KA_T)v.v_data, &r)) { |
| (void) snpf(Namech, Namechl, "vnode@%s: can't read rnode (%s)", |
| print_kptr(na, tbuf, sizeof(tbuf)), |
| print_kptr((KA_T)v.v_data, (char *)NULL, 0)); |
| enter_nm(Namech); |
| return; |
| } |
| break; |
| case N_NM: |
| if (!v.v_data || kread((KA_T)v.v_data, (char *)&nn, sizeof(nn))) { |
| (void) snpf(Namech, Namechl, "vnode@%s: no namenode (%s)", |
| print_kptr(na, tbuf, sizeof(tbuf)), |
| print_kptr((KA_T)v.v_data, (char *)NULL, 0)); |
| enter_nm(Namech); |
| return; |
| } |
| i.dev = nn.nm_vattr.va_fsid; |
| i.rdev = nn.nm_vattr.va_rdev; |
| i.number = (INODETYPE)nn.nm_vattr.va_nodeid; |
| i.size = nn.nm_vattr.va_size; |
| if (!nn.nm_mountpt) |
| break; |
| /* |
| * The name node is mounted over/to another vnode. Process that node. |
| */ |
| (void) ent_fa(&na, (KA_T *)&nn.nm_mountpt, "->"); |
| if (kread((KA_T)nn.nm_mountpt, (char *)&rv, sizeof(rv))) { |
| (void) snpf(Namech, Namechl, |
| "vnode@%s: can't read namenode's mounted vnode (%s)", |
| print_kptr(na, tbuf, sizeof(tbuf)), |
| print_kptr((KA_T)nn.nm_mountpt, (char *)NULL, 0)); |
| return; |
| } |
| if ((Ntype = get_vty(&rv, (KA_T)nn.nm_mountpt, &rkv, &rfx)) < 0) { |
| if (Ntype == -1) |
| Lf->sf = 0; |
| return; |
| } |
| /* |
| * Unless the mounted-over/to node is another "namefs" node, promote |
| * it to the vnode of interest. |
| */ |
| if (Ntype == N_NM) |
| break; |
| fx = rfx; |
| kv = rkv; |
| v = rv; |
| goto get_lock_state; |
| |
| #if defined(HASPROCFS) |
| case N_PROC: |
| ni = 1; |
| if (!v.v_data || kread((KA_T)v.v_data, (char *)&pr, sizeof(pr))) { |
| (void) snpf(Namech, Namechl, "vnode@%s: can't read prnode (%s)", |
| print_kptr(na, tbuf, sizeof(tbuf)), |
| print_kptr((KA_T)v.v_data, (char *)NULL, 0)); |
| enter_nm(Namech); |
| return; |
| } |
| |
| # if UNIXWAREV>=20102 |
| i.number = (INODETYPE)pr.pr_ino; |
| sd = 0; |
| if (pr.pr_common |
| && !kread((KA_T)pr.pr_common, (char *)&prc, sizeof(prc))) { |
| pid = (long)prc.prc_pid; |
| switch(pr.pr_type) { |
| case PR_PIDDIR: |
| (void) snpf(Namech, Namechl, "/%s/%ld", HASPROCFS, pid); |
| break; |
| case PR_AS: |
| (void) snpf(Namech, Namechl, "/%s/%ld/as", HASPROCFS, pid); |
| break; |
| case PR_CTL: |
| (void) snpf(Namech, Namechl, "/%s/%ld/ctl", HASPROCFS, pid); |
| break; |
| case PR_STATUS: |
| (void) snpf(Namech, Namechl, "/%s/%ld/status", HASPROCFS, |
| pid); |
| break; |
| case PR_MAP: |
| (void) snpf(Namech, Namechl, "/%s/%ld/map", HASPROCFS, pid); |
| break; |
| case PR_CRED: |
| (void) snpf(Namech, Namechl, "/%s/%ld/cred", HASPROCFS, pid); |
| break; |
| case PR_SIGACT: |
| (void) snpf(Namech, Namechl, "/%s/%ld/sigact", HASPROCFS, |
| pid); |
| break; |
| case PR_OBJECTDIR: |
| (void) snpf(Namech, Namechl, "/%s/%ld/object", HASPROCFS, |
| pid); |
| break; |
| case PR_LWPDIR: |
| (void) snpf(Namech, Namechl, "/%s/%ld/lwp", HASPROCFS, pid); |
| break; |
| case PR_LWPIDDIR: |
| (void) snpf(Namech, Namechl, "/%s/%ld/lwp/%d", |
| HASPROCFS, pid, prc.prc_lwpid); |
| break; |
| case PR_LWPCTL: |
| (void) snpf(Namech, Namechl, "/%s/%ld/lwp/%d/lwpctl", |
| HASPROCFS, pid, prc.prc_lwpid); |
| break; |
| case PR_LWPSTATUS: |
| (void) snpf(Namech, Namechl, "/%s/%ld/lwp/%d/lwpstatus", |
| HASPROCFS, pid, prc.prc_lwpid); |
| break; |
| case PR_LWPSINFO: |
| (void) snpf(Namech, Namechl, "/%s/%ld/lwp/%d/lwpsinfo", |
| HASPROCFS, pid, prc.prc_lwpid); |
| break; |
| } |
| } else |
| pid = 0l; |
| break; |
| # else /* UNIXWAREV<20102 */ |
| if (!pr.pr_proc) { |
| sd = 0; |
| pid = 0l; |
| if (v.v_type == VDIR) |
| i.number = (INODETYPE)PR_ROOTINO; |
| else |
| i.number = (INODETYPE)0; |
| break; |
| } |
| if (kread((KA_T)pr.pr_proc, (char *)&p, sizeof(p))) { |
| (void) snpf(Namech, Namechl, "prnode@%s: can't read proc (%s)", |
| print_kptr((KA_T)v.v_data, tbuf, sizeof(tbuf)), |
| print_kptr((KA_T)pr.pr_proc, (char *)NULL, 0)); |
| enter_nm(Namech); |
| return; |
| } |
| if (!p.p_pidp || kread((KA_T)p.p_pidp, (char *)&pids, sizeof(pids))) |
| { |
| (void) snpf(Namech, Namechl, |
| "proc struct at %s: can't read pid (%s)", |
| print_kptr((KA_T)pr.pr_proc, tbuf, sizeof(tbuf)), |
| print_kptr((KA_T)p.p_pidp, (char *)NULL, 0)); |
| enter_nm(Namech); |
| return; |
| } |
| pid = (long)pids.pid_id; |
| (void) snpf(Namech, Namechl, "/%s/%ld", HASPROCFS, pid); |
| i.number = (INODETYPE)(pid + PR_INOBIAS); |
| if (!p.p_as || kread((KA_T)p.p_as, (char *)&as, sizeof(as))) |
| sd = 0; |
| else |
| i.size = as.a_size; |
| break; |
| # endif /* UNIXWAREV>=20102 */ |
| #endif /* defined(HASPROCFS) */ |
| |
| case N_STREAM: |
| if (v.v_stream) { |
| Lf->is_stream = ni = 1; |
| |
| #if UNIXWAREV>=70101 |
| if (process_unix_sockstr(&v, na)) { |
| |
| /* |
| * The stream is a UNIX socket stream. No more need be done; |
| * process_unix_stream() has done it all. |
| */ |
| return; |
| } |
| #endif /* UNIXWAREV>=70101 */ |
| |
| /* |
| * Get the queue pointer and module name at the end of the stream. |
| * The module name identifies socket streams. |
| */ |
| if (examine_stream((KA_T)v.v_stream, &q, |
| |
| #if UNIXWAREV>=70103 |
| &mch, &mn, |
| #else /* UNIXWAREV<70103 */ |
| mn, |
| #endif /* UNIXWAREV>=70103 */ |
| |
| "sockmod", &sqp)) |
| return; |
| for (px = 0; px < NPROTOS; px++) { |
| if (strcmp(mn, Protos[px].module) == 0) { |
| process_socket(Protos[px].proto, &q); |
| return; |
| } |
| } |
| /* |
| * If this stream has a "sockmod" module with a non-NULL q_ptr, |
| * try to use it to read an so_so structure. |
| */ |
| if (sqp && kread(sqp, (char *)&so, sizeof(so)) == 0) |
| break; |
| sqp = (KA_T)NULL; |
| (void) snpf(Namech, Namechl, "STR"); |
| j = strlen(Namech); |
| if (v.v_type == VCHR) { |
| /* |
| * If this is a VCHR stream, look up the device name and record it. |
| */ |
| if ((dp = findstrdev(&DevDev, (dev_t *)&v.v_rdev))) { |
| Lf->inode = dp->inode; |
| Lf->inp_ty = 1; |
| Namech[j++] = ':'; |
| k = strlen(dp->name); |
| if ((j + k) <= (Namechl - 1)) { |
| (void) snpf(&Namech[j], Namechl - j, "%s", |
| dp->name); |
| j += k; |
| if ((cp = strrchr(Namech, '/')) |
| && *(cp + 1) == '\0') |
| { |
| *cp = '\0'; |
| j--; |
| } |
| } |
| } |
| } |
| /* |
| * Follow the "STR" and possibly the device name with "->" and |
| * the module name or the stream's significant module names. |
| */ |
| if ((j + 2) <= (Namechl - 1)) { |
| (void) snpf(&Namech[j], Namechl - j, "->"); |
| j += 2; |
| } |
| |
| #if UNIXWAREV<70103 |
| if (mn[0]) { |
| if ((j + strlen(mn)) <= (Namechl - 1)) |
| (void) snpf(&Namech[j], Namechl - j, mn); |
| #else /* UNIXWAREV>=70103 */ |
| if (*mch) { |
| if ((j + strlen(mch)) <= (Namechl - 1)) |
| (void) snpf(&Namech[j], Namechl - j, mch); |
| #endif /* UNIXWAREV<70103 */ |
| |
| } else { |
| if ((j + strlen("none")) <= (Namechl - 1)) |
| (void) snpf(&Namech[j], Namechl - j, "none"); |
| } |
| } |
| break; |
| case N_REGLR: |
| default: |
| |
| /* |
| * Follow a VBLK or VCHR vnode to its snode, then to its real vnode, |
| * finally to its inode. |
| */ |
| if ((v.v_type == VBLK) || (v.v_type == VCHR)) { |
| if (!v.v_data || readsnode((KA_T)v.v_data, &s)) { |
| (void) snpf(Namech, Namechl, |
| "vnode@%s: can't read snode (%s)", |
| print_kptr(na, tbuf, sizeof(tbuf)), |
| print_kptr((KA_T)v.v_data, (char *)NULL, 0)); |
| enter_nm(Namech); |
| return; |
| } |
| if (s.s_realvp) { |
| if (readvnode((KA_T)s.s_realvp, &rv)) { |
| (void) snpf(Namech, Namechl, |
| "snode@%s: can't read real vnode (%s)", |
| print_kptr((KA_T)v.v_data, tbuf, sizeof(tbuf)), |
| print_kptr((KA_T)s.s_realvp, (char *)NULL, 0)); |
| enter_nm(Namech); |
| return; |
| } |
| if (!rv.v_data || (is = readlino(fx, &rv, &i))) { |
| (void) snpf(Namech, Namechl, |
| "snode@%s: unknown inode@%s; fx=", |
| print_kptr((KA_T)v.v_data, tbuf, sizeof(tbuf)), |
| print_kptr((KA_T)rv.v_data, (char *)NULL, 0)); |
| ep = endnm(&sz); |
| if (fx < 1 || fx > Fsinfomax) |
| (void) snpf(ep, sz, "%d", fx); |
| else |
| (void) snpf(ep, sz, "%s", Fsinfo[fx - 1]); |
| enter_nm(Namech); |
| return; |
| } |
| } |
| /* |
| * If there's no real vnode, look for a common vnode and a |
| * common snode. |
| */ |
| else if ((ka = (KA_T)s.s_commonvp)) { |
| if (readvnode(ka, &rv)) { |
| (void) snpf(Namech, Namechl, |
| "snode@%s: can't read common vnode (%s)", |
| print_kptr((KA_T)v.v_data, tbuf, sizeof(tbuf)), |
| print_kptr((KA_T)ka, (char *)NULL, 0)); |
| enter_nm(Namech); |
| return; |
| } |
| |
| #if UNIXWAREV>=70103 |
| if (!rv.v_vfsp) { |
| if ((dp = ismouse(&rv, &i, fx, &kv))) { |
| (void) snpf(Namech, Namechl, "STR:%s", dp->name); |
| break; |
| } |
| } |
| #endif /* UNIXWAREV>=70103 */ |
| |
| if (get_vty(&rv, ka, &rkv, &rfx) < 0) |
| Lf->is_com = ni = 1; |
| else { |
| if ((is = readlino(rfx, &rv, &i))) { |
| (void) snpf(Namech, Namechl, |
| "vnode@%s: unknown successor@%s; fx=", |
| print_kptr((KA_T)ka, tbuf, sizeof(tbuf)), |
| print_kptr((KA_T)v.v_data, (char *)NULL, 0)); |
| ep = endnm(&sz); |
| if (rfx < 1 || rfx > Fsinfomax) |
| (void) snpf(ep, sz, "%d", rfx); |
| else |
| (void) snpf(ep, sz, "%s", Fsinfo[rfx - 1]); |
| enter_nm(Namech); |
| return; |
| } |
| } |
| } else |
| ni = 1; |
| break; |
| } |
| |
| #if UNIXWAREV>=70103 |
| else if (v.v_type == VNON) { |
| ni = 1; |
| break; |
| } |
| #endif /* UNIXWAREV>=70103 */ |
| |
| if (v.v_data == NULL) { |
| (void) snpf(Namech, Namechl, "vnode@%s: no further information", |
| print_kptr(na, (char *)NULL, 0)); |
| enter_nm(Namech); |
| return; |
| } |
| /* |
| * Read inode information. |
| */ |
| if ((is = readlino(fx, &v, &i))) { |
| (void) snpf(Namech, Namechl, |
| "vnode@%s: unknown successor@%s; fx=", |
| print_kptr(na, tbuf, sizeof(tbuf)), |
| print_kptr((KA_T)v.v_data, (char *)NULL, 0)); |
| ep = endnm(&sz); |
| if (fx < 1 || fx > Fsinfomax) |
| (void) snpf(ep, sz, "%d", fx); |
| else |
| (void) snpf(ep, sz, "%s", Fsinfo[fx - 1]); |
| enter_nm(Namech); |
| return; |
| } |
| } |
| /* |
| * Get device and type for printing. |
| */ |
| switch (Ntype) { |
| case N_NFS: |
| dev = r.r_attr.va_fsid; |
| devs = 1; |
| break; |
| |
| #if defined(HASPROCFS) |
| case N_PROC: |
| dev = kv.vfs_dev; |
| devs = 1; |
| break; |
| #endif /* defined(HASPROCFS) */ |
| |
| case N_STREAM: |
| if (sqp) { |
| if (so.lux_dev.size >= 8) { |
| dev = DevDev; |
| rdev = so.lux_dev.addr.tu_addr.dev; |
| devs = rdevs = 1; |
| } else |
| enter_dev_ch(print_kptr(sqp, (char *)NULL, 0)); |
| break; |
| } |
| if (v.v_type == VFIFO) { |
| KA_T ta; |
| |
| if ((ta = (KA_T)(v.v_data ? v.v_data : v.v_stream))) |
| enter_dev_ch(print_kptr(ta, (char *)NULL, 0)); |
| break; |
| } |
| /* fall through */ |
| default: |
| if (!ni) { |
| dev = i.dev; |
| devs = (Ntype == N_CFS) ? i.dev_def : 1; |
| } else if ((Ntype == N_STREAM) |
| && ((v.v_type == VCHR) || (v.v_type == VBLK))) |
| { |
| dev = DevDev; |
| devs = 1; |
| } |
| if ((v.v_type == VCHR) || (v.v_type == VBLK)) { |
| rdev = v.v_rdev; |
| rdevs = (Ntype == N_CFS) ? i.rdev_def : 1; |
| } |
| } |
| type = v.v_type; |
| /* |
| * Obtain the inode number. |
| */ |
| switch (Ntype) { |
| |
| case N_NFS: |
| Lf->inode = (INODETYPE)r.r_attr.va_nodeid; |
| Lf->inp_ty = 1; |
| break; |
| |
| #if defined(HASPROCFS) |
| case N_PROC: |
| Lf->inode = i.number; |
| Lf->inp_ty = 1; |
| break; |
| #endif /* defined(HASPROCFS) */ |
| |
| case N_FIFO: |
| if (!f.fn_realvp) { |
| enter_dev_ch(print_kptr((KA_T)v.v_data, (char *)NULL, 0)); |
| Lf->inode = (INODETYPE)f.fn_ino; |
| Lf->inp_ty = 1; |
| if (f.fn_flag & ISPIPE) |
| (void) snpf(Namech, Namechl, "PIPE"); |
| if (f.fn_mate) { |
| ep = endnm(&sz); |
| (void) snpf(ep, sz, "->%s", |
| print_kptr((KA_T)f.fn_mate, (char *)NULL, 0)); |
| } |
| break; |
| } |
| /* fall through */ |
| case N_CFS: |
| case N_REGLR: |
| if (!ni) { |
| Lf->inode = i.number; |
| Lf->inp_ty = (Ntype == N_CFS) ? i.number_def : 1; |
| } |
| break; |
| case N_STREAM: |
| if (sqp && so.lux_dev.size >= 8) { |
| Lf->inode = (INODETYPE)so.lux_dev.addr.tu_addr.ino; |
| Lf->inp_ty = 1; |
| } |
| } |
| /* |
| * Obtain the file size. |
| */ |
| if (Foffset) |
| Lf->off_def = 1; |
| else { |
| switch (Ntype) { |
| |
| case N_FIFO: |
| case N_STREAM: |
| if (!Fsize) |
| Lf->off_def = 1; |
| break; |
| case N_NFS: |
| Lf->sz = (SZOFFTYPE)r.r_attr.va_size; |
| Lf->sz_def = sd; |
| break; |
| |
| #if defined(HASPROCFS) |
| case N_PROC: |
| |
| #if UNIXWAREV<70103 |
| Lf->sz = (SZOFFTYPE)i.size; |
| Lf->sz_def = sd; |
| #else /* UNIXWAREV>=70103 */ |
| Lf->sz = (SZOFFTYPE)0; |
| Lf->sz_def = 0; |
| #endif /* UNIXWAREV<70103 */ |
| |
| break; |
| #endif /* defined(HASPROCFS) */ |
| |
| case N_CFS: |
| case N_REGLR: |
| if ((type == VREG) || (type == VDIR)) { |
| if (!ni) { |
| Lf->sz = (SZOFFTYPE)i.size; |
| Lf->sz_def = (Ntype == N_CFS) ? i.size_def : sd; |
| } |
| } else if (((type == VBLK) || (type == VCHR)) && !Fsize) |
| Lf->off_def = 1; |
| break; |
| } |
| } |
| /* |
| * Record link count. |
| */ |
| if (Fnlink) { |
| switch(Ntype) { |
| case N_FIFO: |
| Lf->nlink = (long)f.fn_open; |
| Lf->nlink_def = 1; |
| break; |
| case N_NFS: |
| Lf->nlink = (long)r.r_attr.va_nlink; |
| Lf->nlink_def = 1; |
| break; |
| |
| #if defined(HASPROCFS) |
| case N_PROC: |
| #endif /* defined(HASPROCFS) */ |
| |
| case N_CFS: |
| case N_REGLR: |
| if (!ni) { |
| Lf->nlink = (long)i.nlink; |
| Lf->nlink_def = i.nlink_def; |
| } |
| break; |
| } |
| if (Nlink && Lf->nlink_def && (Lf->nlink < Nlink)) |
| Lf->sf |= SELNLINK; |
| } |
| /* |
| * Record an NFS file selection. |
| */ |
| if (Ntype == N_NFS && Fnfs) |
| Lf->sf |= SELNFS; |
| /* |
| * Defer file system info lookup until printname(). |
| */ |
| Lf->lmi_srch = 1; |
| /* |
| * Save the device numbers and their states. |
| * |
| * Format the vnode type, and possibly the device name. |
| */ |
| if (type != VFIFO) { |
| 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"; |
| if (Lf->is_stream == 0) |
| Ntype = N_CHR; |
| break; |
| case VLNK: |
| ty = "VLNK"; |
| break; |
| |
| #if defined(VSOCK) |
| case VSOCK: |
| ty = "SOCK"; |
| break; |
| #endif /* VSOCK */ |
| |
| case VBAD: |
| ty = "VBAD"; |
| break; |
| case VFIFO: |
| if (!Lf->dev_ch || Lf->dev_ch[0] == '\0') { |
| Lf->dev = dev; |
| Lf->dev_def = devs; |
| Lf->rdev = rdev; |
| Lf->rdev_def = rdevs; |
| } |
| ty = "FIFO"; |
| break; |
| case VUNNAMED: |
| ty = "UNNM"; |
| 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; |
| /* |
| * If this is a VBLK file and it's missing an inode number, try to |
| * supply one. |
| */ |
| if ((Lf->inp_ty == 0) && (Lf->ntype == N_BLK)) |
| find_bl_ino(); |
| /* |
| * 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(); |
| /* |
| * If this is a stream with a "sockmod" module whose q_ptr leads to an |
| * so_so structure, assume it's a UNIX domain socket and try to get |
| * the path. Clear the is_stream status. |
| */ |
| if (Ntype == N_STREAM && sqp) { |
| if (Funix) |
| Lf->sf |= SELUNX; |
| (void) snpf(Lf->type, sizeof(Lf->type), "unix"); |
| if (!Namech[0] |
| && so.laddr.buf && so.laddr.len == sizeof(ua) |
| && !kread((KA_T)so.laddr.buf, (char *)&ua, sizeof(ua))) { |
| ua.sun_path[sizeof(ua.sun_path) - 1] = '\0'; |
| (void) snpf(Namech, Namechl, "%s", ua.sun_path); |
| if (Sfile && is_file_named(Namech, 0)) |
| Lf->sf = SELNM; |
| if (so.lux_dev.size >= 8) { |
| Lf->inode = (INODETYPE)so.lux_dev.addr.tu_addr.ino; |
| Lf->inp_ty = 1; |
| } |
| } |
| if (so.so_conn) { |
| ep = endnm(&sz); |
| (void) snpf(ep, sz, "->%s", |
| print_kptr((KA_T)so.so_conn, (char *)NULL, 0)); |
| } |
| Lf->is_stream = 0; |
| } |
| /* |
| * 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 && pid && pfi->pid == (pid_t)pid) |
| |
| # if defined(HASPINODEN) |
| || ((Lf->inp_ty == 1) && (Lf->inode == pfi->inode)) |
| # endif /* defined(HASPINODEN) */ |
| |
| ) { |
| pfi->f = 1; |
| Lf->sf |= SELNM; |
| if (!Namech[0] && pfi->nm) { |
| (void) strncpy(Namech, pfi->nm, Namechl - 1); |
| Namech[Namechl-1] = '\0'; |
| } |
| 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 there's an l_ino structure with a file name |
| * pointer, and no name column addition exists, make what the l_ino file |
| * name pointer addresses a name column addition. |
| */ |
| if (!Lf->nma && !is && i.nm) { |
| if ((msz = (MALLOC_S)strlen(i.nm))) { |
| if (!(cp = (char *)malloc(msz + 1))) { |
| (void) fprintf(stderr, |
| "%s: can't allocate %d bytes for l_ino name addition\n", |
| msz, Pn); |
| Exit(1); |
| } |
| (void) snpf(cp, msz + 1, "%s", i.nm); |
| Lf->nma = cp; |
| } |
| } |
| if (Namech[0]) |
| enter_nm(Namech); |
| } |
| |
| |
| /* |
| * readlino() - read local inode information |
| */ |
| |
| static int |
| readlino(fx, v, i) |
| int fx; /* file system index */ |
| struct vnode *v; /* vnode pointing to inode */ |
| struct l_ino *i; /* local inode */ |
| { |
| |
| #if defined(HAS_UW_CFS) |
| cnode_t cn; |
| #endif /* defined(HAS_UW_CFS) */ |
| |
| struct vnode fa; |
| struct mnode mn; |
| struct inode sn; |
| |
| #if defined(HASXNAMNODE) |
| struct xnamnode xn; |
| #endif /* defined(HASXNAMNODE) */ |
| |
| i->nlink_def = 0; |
| if (fx < 1 || fx > Fsinfomax || !v->v_data) |
| return(1); |
| if (!strcmp(Fsinfo[fx-1], "fifofs") |
| || !strcmp(Fsinfo[fx-1], "sfs") |
| || !strcmp(Fsinfo[fx-1], "ufs")) { |
| if (kread((KA_T)v->v_data, (char *)&sn, sizeof(sn))) |
| return(1); |
| i->dev = sn.i_dev; |
| i->dev_def = 1; |
| i->rdev = v->v_rdev; |
| i->rdev_def = 1; |
| i->nlink = (long)sn.i_nlink; |
| i->nlink_def = 1; |
| i->nm = (char *)NULL; |
| i->number = (INODETYPE)sn.i_number; |
| i->size = (SZOFFTYPE)sn.i_size; |
| i->size_def = 1; |
| return(0); |
| } |
| |
| #if defined(HAS_UW_CFS) |
| else if (!strcmp(Fsinfo[fx-1], "nsc_cfs")) { |
| if (kread((KA_T)v->v_data, (char *)&cn, sizeof(cn))) |
| return(1); |
| if (cn.c_attr.va_mask & AT_FSID) { |
| i->dev = cn.c_attr.va_fsid; |
| i->dev_def = 1; |
| } else |
| i->dev_def = 0; |
| i->rdev = v->v_rdev; |
| i->rdev_def = 1; |
| if (cn.c_attr.va_mask & AT_NLINK) { |
| i->nlink = cn.c_attr.va_nlink; |
| i->nlink_def = 1; |
| } else |
| i->nlink_def = 0; |
| i->nm = (char *)NULL; |
| if (cn.c_attr.va_mask & AT_NODEID) { |
| i->number = (INODETYPE)cn.c_attr.va_nodeid; |
| i->number_def = 1; |
| } else |
| i->number_def = 0; |
| if (cn.c_attr.va_mask & AT_SIZE) { |
| i->size = cn.c_attr.va_size; |
| i->size_def = 1; |
| } else |
| i->size_def = 0; |
| return(0); |
| } |
| #endif /* defined(HAS_UW_CFS) */ |
| |
| else if (!strcmp(Fsinfo[fx-1], "s5")) |
| return(reads5lino(v, i)); |
| else if (!strcmp(Fsinfo[fx-1], "vxfs")) |
| return(readvxfslino(v, i)); |
| else if (!strcmp(Fsinfo[fx-1], "bfs")) |
| return(readbfslino(v, i)); |
| |
| #if defined(HASXNAMNODE) |
| else if (!strcmp(Fsinfo[fx-1], "xnamfs") |
| || !strcmp(Fsinfo[fx-1], "XENIX")) |
| { |
| if (kread((KA_T)v->v_data, (char *)&xn, sizeof(xn))) |
| return(1); |
| i->dev = xn.x_dev; |
| i->nlink = (long)xn.x_count; |
| i->nlink_def = 1; |
| i->nm = (char *)NULL; |
| i->rdev = xn.x_fsid; |
| i->size = xn.x_size; |
| return(0); |
| } |
| #endif /* defined(HASXNAMNODE) */ |
| |
| else if (!strcmp(Fsinfo[fx-1], "memfs")) { |
| if (kread((KA_T)v->v_data, (char *)&mn, sizeof(mn))) |
| return(1); |
| i->dev = mn.mno_fsid; |
| i->dev_def = 1; |
| i->nlink = (long)mn.mno_nlink; |
| i->nlink_def = 1; |
| i->nm = (char *)NULL; |
| i->number = (INODETYPE)mn.mno_nodeid; |
| i->number_def = 1; |
| i->rdev = mn.mno_rdev; |
| i->rdev = mn.mno_rdev; |
| i->size = (SZOFFTYPE)mn.mno_size; |
| i->size_def = 1; |
| return(0); |
| } |
| |
| #if UNIXWAREV>=70000 |
| else if (!strcmp(Fsinfo[fx-1], "cdfs")) |
| return readcdfslino(v, i); |
| else if (!strcmp(Fsinfo[fx-1], "dosfs")) |
| return readdosfslino(v, i); |
| #endif /* UNIXWAREV>=70000 */ |
| |
| return(1); |
| } |