home *** CD-ROM | disk | FTP | other *** search
- /* History:
- 5/3/91 DJB various modifications
- 5/1/91 DJB baseline
- Rewritten by DJB to store rather than print information.
- Originally stolen from Dupuy ofiles.
- */
-
- /* XXX: error checks! support strerr! */
-
- /*
-
- int getnode(node,buf) struct Xnode *node; struct nodebuf *buf; looks up
- the filesystem node (in kernel memory) and places its vital statistics
- into buf. buf->type is a three-character file type as defined by the
- virtype library. buf->flagdev is NODE_ID_INO if node is a regular inode,
- NODE_ID_DEV if it is a device, NODE_ID_FIFO if it is a fifo, and
- NODE_ID_FIFOINO if it is a fifo but the regular inode information is
- also filled in. (Some systems do not support type NODE_ID_FIFOINO.)
-
- If buf->flagdev is NODE_ID_INO, buf->id.ino has the following elements:
- inum is the file serial number; dev is the file device number; name is
- the filename of the device, or 0 if it is unknown; flagnfs is 0 for a
- local file and 1 for a remote file.
-
- If buf->flagdev is NODE_ID_DEV, buf->id.dev has the following elements:
- maj is the major number of the remote device; min is the minor number;
- and name is the filename, or 0 if it is unknown.
-
- getnode() returns 0 on success, -1 on error. XXX: need getnodestrerr.
-
- getnodeinit() does optional initialization to cooperate with other
- libraries.
-
- */
-
- #ifdef NFS
- #define NL_NFS "_nfs_vnodeops"
- static unsigned long nlnfsv;
- static short nlnfst;
- #define NL_UFS "_ufs_vnodeops"
- static unsigned long nlufsv;
- static short nlufst;
- #endif
-
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include "confnfs.h"
- #include "structxnode.h"
- #include "nlistlist.h"
- #include "stattimeout.h"
- #include "rpcnfs.h"
- #include "virtype.h"
- #include "mntops.h"
- #include "getdevicename.h"
- #include "getnode.h"
- #include "confneedmntinfo.h"
- #include "confgnode.h"
- #include "confmajorminor.h"
-
- #define istype(mode,type) (((mode) & S_IFMT) == (type))
- #define ispecial(mode) (istype((mode),S_IFBLK) || istype((mode),S_IFCHR))
- #ifdef NFS
- #define vspecial(vtype) ((vtype) == VCHR || (vtype) == VBLK)
- #endif
-
- static int init = 0;
-
- #ifdef GNODE
-
- int getnode(node,buf)
- struct gnode *node;
- struct nodebuf *buf;
- {
- struct gnode g;
- struct statlist *fsstats;
-
- if (!node)
- return -1;
- kmemcpy(&g,node,sizeof(g));
- buf->type = itype(g.g_mode);
- if (ispecial(g.g_mode))
- {
- buf->flagdev = NODE_ID_DEV;
- buf->id.dev.maj = major(g.g_rdev);
- buf->id.dev.min = minor(g.g_rdev);
- buf->id.dev.name = getdevicename(&g);
- return 0;
- }
- if (!init)
- pervn();
- fsstats = stats;
-
- buf->flagdev = NODE_ID_INO;
- buf->id.ino.inum = g.g_number;
- buf->id.ino.dev = g.g_dev;
-
- while (fsstats) /* XXX: hash! */
- {
- if (fsstats->device == g.g_dev)
- {
- buf->id.ino.name = fsstats->filename;
- /* another iffy test for nfs */
- if (itype(g.g_mode) == vtype(((struct vnode *) &g)->v_type))
- buf->id.ino.flagnfs = 1;
- else
- buf->id.ino.flagnfs = 0;
- return 0;
- }
- fsstats = fsstats->next;
- }
-
- buf->id.ino.name = 0;
- return 0;
- }
-
- #else
-
- int getnode(node,buf)
- struct Xnode *node;
- struct nodebuf *buf;
- {
- #ifdef NFS
- struct vnode v;
- #endif
- static union xnode
- {
- struct inode i;
- #ifdef NFS
- struct rnode r;
- #endif
- }
- x;
- struct statlist *fsstats;
-
- if (!init)
- pervn();
- fsstats = stats;
-
- if (!node)
- return -1;
-
- #ifdef NFS
- kmemcpy(&v,node,sizeof(v));
-
- buf->type = vtype(v.v_type);
-
- if (vspecial(v.v_type))
- {
- buf->flagdev = NODE_ID_DEV;
- buf->id.dev.maj = major(v.v_rdev);
- buf->id.dev.min = minor(v.v_rdev);
- buf->id.dev.name = getdevicename(&v);
- return 0;
- }
-
- buf->flagdev = NODE_ID_INO;
- #ifdef S_IFIFO
- if (v.v_type == VFIFO)
- {
- #ifdef GET_FIFOS
- struct snode sn;
- buf->flagdev = NODE_ID_FIFOINO;
- kmemcpy(&sn,v.v_data,sizeof(sn));
- kmemcpy(&v,sn.s_realvp,sizeof(v));
- #else
- buf->flagdev = NODE_ID_FIFO;
- return 0;
- #endif
- }
- #endif
-
- kmemcpy(&x,v.v_data,sizeof(x));
-
- if ((unsigned long) v.v_op == nlnfsv)
- {
- #ifndef NEED_MNTINFO
- buf->id.ino.flagnfs = 1;
- buf->id.ino.inum = x.r.r_attr.va_nodeid;
- buf->id.ino.dev = x.r.r_attr.va_fsid;
-
- while (fsstats)
- {
- if (fsstats->device == (dev_t) x.r.r_attr.va_fsid)
- {
- buf->id.ino.name = fsstats->filename;
- return 0;
- }
- fsstats = fsstats->next;
- }
- buf->id.ino.name = 0;
- return 0;
- #else
- struct vfs vf;
- struct mntinfo mi;
- dev_t fsdev;
-
- kmemcpy(&vf,v.v_vfsp,sizeof(vf));
- kmemcpy(&mi,vf.vfs_data,sizeof(mi));
- fsdev = makedev(0xff,mi.mi_mntno);
-
- buf->id.ino.flagnfs = 1;
- buf->id.ino.inum = x.r.r_nfsattr.na_nodeid;
-
- while (fsstats)
- {
- if (fsstats->device == fsdev)
- {
- buf->id.ino.dev = mi.mi_mntno;
- buf->id.ino.name = fsstats->filename;
- return 0;
- }
- fsstats = fsstats->next;
- }
-
- buf->id.ino.dev = x.r.r_nfsattr.na_fsid; /* XXX: is this right? */
- buf->id.ino.name = 0;
- return 0;
- #endif
- }
- else if ((unsigned long) v.v_op == nlufsv)
- {
- /* XXX: Yes, this *is* a confusing interaction between {} and #ifdef. */
- #else
- kmemcpy(&x.i,node,sizeof(x.i));
- buf->type = itype(x.i.i_mode);
-
- if (ispecial(x.i.i_mode))
- {
- buf->flagdev = NODE_ID_DEV;
- buf->id.dev.maj = major(x.i.i_rdev);
- buf->id.dev.min = minor(x.i.i_rdev);
- buf->id.dev.name = getdevicename(&x.i);
- return 0;
- }
- #endif
-
- buf->flagdev = NODE_ID_INO;
- buf->id.ino.inum = x.i.i_number;
- buf->id.ino.dev = x.i.i_dev;
- buf->id.ino.flagnfs = 0;
- while (fsstats)
- {
- if (fsstats->device == x.i.i_dev)
- {
- buf->id.ino.name = fsstats->filename;
- return 0;
- }
- fsstats = fsstats->next;
- }
- buf->id.ino.name = 0;
- #ifdef NFS
- }
- else
- return -1; /* XXX: inode unrecognized fs type */
- #endif
- return 0;
- }
-
- #endif
-
- static pervn()
- {
- if (!init)
- getnodeinit();
- #ifdef NFS
- if (!nlnfst)
- nlistdo();
- #endif
- }
-
- getnodeinit()
- {
- #ifdef NFS
- nlistadd(NL_NFS,&nlnfst,&nlnfsv); /*XXX*/
- nlistadd(NL_UFS,&nlufst,&nlufsv);
- #endif
- init = 1;
- }
-