home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 3 / 3299 / getnode.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-07  |  5.8 KB  |  280 lines

  1. /* History:
  2. 5/3/91 DJB various modifications
  3. 5/1/91 DJB baseline
  4. Rewritten by DJB to store rather than print information.
  5. Originally stolen from Dupuy ofiles.
  6. */
  7.  
  8. /* XXX: error checks! support strerr! */
  9.  
  10. /*
  11.  
  12. int getnode(node,buf) struct Xnode *node; struct nodebuf *buf; looks up
  13. the filesystem node (in kernel memory) and places its vital statistics
  14. into buf. buf->type is a three-character file type as defined by the
  15. virtype library. buf->flagdev is NODE_ID_INO if node is a regular inode,
  16. NODE_ID_DEV if it is a device, NODE_ID_FIFO if it is a fifo, and
  17. NODE_ID_FIFOINO if it is a fifo but the regular inode information is
  18. also filled in. (Some systems do not support type NODE_ID_FIFOINO.)
  19.  
  20. If buf->flagdev is NODE_ID_INO, buf->id.ino has the following elements:
  21. inum is the file serial number; dev is the file device number; name is
  22. the filename of the device, or 0 if it is unknown; flagnfs is 0 for a
  23. local file and 1 for a remote file.
  24.  
  25. If buf->flagdev is NODE_ID_DEV, buf->id.dev has the following elements:
  26. maj is the major number of the remote device; min is the minor number;
  27. and name is the filename, or 0 if it is unknown.
  28.  
  29. getnode() returns 0 on success, -1 on error. XXX: need getnodestrerr.
  30.  
  31. getnodeinit() does optional initialization to cooperate with other
  32. libraries.
  33.  
  34. */
  35.  
  36. #ifdef NFS
  37. #define NL_NFS "_nfs_vnodeops"
  38. static unsigned long nlnfsv;
  39. static short nlnfst;
  40. #define NL_UFS "_ufs_vnodeops"
  41. static unsigned long nlufsv;
  42. static short nlufst;
  43. #endif
  44.  
  45. #include <stdio.h>
  46. #include <sys/types.h>
  47. #include <sys/stat.h>
  48. #include "confnfs.h"
  49. #include "structxnode.h"
  50. #include "nlistlist.h"
  51. #include "stattimeout.h"
  52. #include "rpcnfs.h"
  53. #include "virtype.h"
  54. #include "mntops.h"
  55. #include "getdevicename.h"
  56. #include "getnode.h"
  57. #include "confneedmntinfo.h"
  58. #include "confgnode.h"
  59. #include "confmajorminor.h"
  60.  
  61. #define istype(mode,type) (((mode) & S_IFMT) == (type))
  62. #define ispecial(mode) (istype((mode),S_IFBLK) || istype((mode),S_IFCHR))
  63. #ifdef NFS
  64. #define vspecial(vtype) ((vtype) == VCHR || (vtype) == VBLK)
  65. #endif
  66.  
  67. static int init = 0;
  68.  
  69. #ifdef GNODE
  70.  
  71. int getnode(node,buf)
  72. struct gnode *node;
  73. struct nodebuf *buf;
  74. {
  75.  struct gnode g;
  76.  struct statlist *fsstats;
  77.  
  78.  if (!node)
  79.    return -1;
  80.  kmemcpy(&g,node,sizeof(g));
  81.  buf->type = itype(g.g_mode);
  82.  if (ispecial(g.g_mode))
  83.   {
  84.    buf->flagdev = NODE_ID_DEV;
  85.    buf->id.dev.maj = major(g.g_rdev);
  86.    buf->id.dev.min = minor(g.g_rdev);
  87.    buf->id.dev.name = getdevicename(&g);
  88.    return 0;
  89.   }
  90.  if (!init)
  91.    pervn();
  92.  fsstats = stats;
  93.  
  94.  buf->flagdev = NODE_ID_INO;
  95.  buf->id.ino.inum = g.g_number;
  96.  buf->id.ino.dev = g.g_dev;
  97.  
  98.  while (fsstats) /* XXX: hash! */
  99.   {
  100.    if (fsstats->device == g.g_dev)
  101.     {
  102.      buf->id.ino.name = fsstats->filename;
  103.      /* another iffy test for nfs */
  104.      if (itype(g.g_mode) == vtype(((struct vnode *) &g)->v_type))
  105.        buf->id.ino.flagnfs = 1;
  106.      else
  107.        buf->id.ino.flagnfs = 0;
  108.      return 0;
  109.     }
  110.    fsstats = fsstats->next;
  111.   }
  112.  
  113.  buf->id.ino.name = 0;
  114.  return 0;
  115. }
  116.  
  117. #else
  118.  
  119. int getnode(node,buf)
  120. struct Xnode *node;
  121. struct nodebuf *buf;
  122. {
  123. #ifdef NFS
  124.  struct vnode v;
  125. #endif
  126.  static union xnode
  127.   {
  128.    struct inode i;
  129. #ifdef NFS
  130.    struct rnode r;
  131. #endif
  132.   }
  133.  x;
  134.  struct statlist *fsstats;
  135.  
  136.  if (!init)
  137.    pervn();
  138.  fsstats = stats;
  139.  
  140.  if (!node)
  141.    return -1;
  142.  
  143. #ifdef NFS
  144.  kmemcpy(&v,node,sizeof(v));
  145.  
  146.  buf->type = vtype(v.v_type);
  147.  
  148.  if (vspecial(v.v_type))
  149.   {
  150.    buf->flagdev = NODE_ID_DEV;
  151.    buf->id.dev.maj = major(v.v_rdev);
  152.    buf->id.dev.min = minor(v.v_rdev);
  153.    buf->id.dev.name = getdevicename(&v);
  154.    return 0;
  155.   }
  156.  
  157.  buf->flagdev = NODE_ID_INO;
  158. #ifdef S_IFIFO
  159.  if (v.v_type == VFIFO)
  160.   {
  161. #ifdef GET_FIFOS
  162.    struct snode sn;
  163.    buf->flagdev = NODE_ID_FIFOINO;
  164.    kmemcpy(&sn,v.v_data,sizeof(sn));
  165.    kmemcpy(&v,sn.s_realvp,sizeof(v));
  166. #else
  167.    buf->flagdev = NODE_ID_FIFO;
  168.    return 0;
  169. #endif
  170.   }
  171. #endif
  172.  
  173.  kmemcpy(&x,v.v_data,sizeof(x));
  174.  
  175.  if ((unsigned long) v.v_op == nlnfsv)
  176.   {
  177. #ifndef NEED_MNTINFO
  178.    buf->id.ino.flagnfs = 1;
  179.    buf->id.ino.inum = x.r.r_attr.va_nodeid;
  180.    buf->id.ino.dev = x.r.r_attr.va_fsid;
  181.  
  182.    while (fsstats)
  183.     {
  184.      if (fsstats->device == (dev_t) x.r.r_attr.va_fsid)
  185.       {
  186.        buf->id.ino.name = fsstats->filename;
  187.        return 0;
  188.       }
  189.      fsstats = fsstats->next;
  190.     }
  191.    buf->id.ino.name = 0;
  192.    return 0;
  193. #else
  194.    struct vfs vf;
  195.    struct mntinfo mi;
  196.    dev_t fsdev;
  197.  
  198.    kmemcpy(&vf,v.v_vfsp,sizeof(vf));
  199.    kmemcpy(&mi,vf.vfs_data,sizeof(mi));
  200.    fsdev = makedev(0xff,mi.mi_mntno);
  201.  
  202.    buf->id.ino.flagnfs = 1;
  203.    buf->id.ino.inum = x.r.r_nfsattr.na_nodeid;
  204.  
  205.    while (fsstats)
  206.     {
  207.      if (fsstats->device == fsdev)
  208.       {
  209.        buf->id.ino.dev = mi.mi_mntno;
  210.        buf->id.ino.name = fsstats->filename;
  211.        return 0;
  212.       }
  213.      fsstats = fsstats->next;
  214.     }
  215.  
  216.    buf->id.ino.dev = x.r.r_nfsattr.na_fsid; /* XXX: is this right? */
  217.    buf->id.ino.name = 0;
  218.    return 0;
  219. #endif
  220.   }
  221.  else if ((unsigned long) v.v_op == nlufsv)
  222.   {
  223.    /* XXX: Yes, this *is* a confusing interaction between {} and #ifdef. */
  224. #else
  225.  kmemcpy(&x.i,node,sizeof(x.i));
  226.  buf->type = itype(x.i.i_mode);
  227.  
  228.  if (ispecial(x.i.i_mode))
  229.   {
  230.    buf->flagdev = NODE_ID_DEV;
  231.    buf->id.dev.maj = major(x.i.i_rdev);
  232.    buf->id.dev.min = minor(x.i.i_rdev);
  233.    buf->id.dev.name = getdevicename(&x.i);
  234.    return 0;
  235.   }
  236. #endif
  237.  
  238.  buf->flagdev = NODE_ID_INO;
  239.  buf->id.ino.inum = x.i.i_number;
  240.  buf->id.ino.dev = x.i.i_dev;
  241.  buf->id.ino.flagnfs = 0;
  242.  while (fsstats)
  243.   {
  244.    if (fsstats->device == x.i.i_dev)
  245.     {
  246.      buf->id.ino.name = fsstats->filename;
  247.      return 0;
  248.     }
  249.    fsstats = fsstats->next;
  250.   }
  251.  buf->id.ino.name = 0;
  252. #ifdef NFS
  253.   }
  254.  else
  255.    return -1; /* XXX: inode unrecognized fs type */
  256. #endif
  257.  return 0;
  258. }
  259.  
  260. #endif
  261.  
  262. static pervn()
  263. {
  264.  if (!init)
  265.    getnodeinit();
  266. #ifdef NFS
  267.  if (!nlnfst)
  268.    nlistdo();
  269. #endif
  270. }
  271.  
  272. getnodeinit()
  273. {
  274. #ifdef NFS
  275.  nlistadd(NL_NFS,&nlnfst,&nlnfsv); /*XXX*/
  276.  nlistadd(NL_UFS,&nlufst,&nlufsv);
  277. #endif
  278.  init = 1;
  279. }
  280.