devroot.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. #include "dat.h"
  2. #include "fns.h"
  3. #include "error.h"
  4. extern Rootdata rootdata[];
  5. extern Dirtab roottab[];
  6. extern int rootmaxq;
  7. static Chan*
  8. rootattach(char *spec)
  9. {
  10. int i;
  11. ulong len;
  12. Rootdata *r;
  13. if(*spec)
  14. error(Ebadspec);
  15. for (i = 0; i < rootmaxq; i++){
  16. r = &rootdata[i];
  17. if (r->sizep){
  18. len = *r->sizep;
  19. r->size = len;
  20. roottab[i].length = len;
  21. }
  22. }
  23. return devattach('/', spec);
  24. }
  25. static int
  26. rootgen(Chan *c, char *name, Dirtab *tab, int nd, int s, Dir *dp)
  27. {
  28. int p, i;
  29. Rootdata *r;
  30. if(s == DEVDOTDOT){
  31. p = rootdata[c->qid.path].dotdot;
  32. c->qid.path = p;
  33. c->qid.type = QTDIR;
  34. name = "#/";
  35. if(p != 0){
  36. for(i = 0; i < rootmaxq; i++)
  37. if(roottab[i].qid.path == c->qid.path){
  38. name = roottab[i].name;
  39. break;
  40. }
  41. }
  42. devdir(c, c->qid, name, 0, eve, 0555, dp);
  43. return 1;
  44. }
  45. if(name != nil){
  46. isdir(c);
  47. r = &rootdata[(int)c->qid.path];
  48. tab = r->ptr;
  49. for(i=0; i<r->size; i++, tab++)
  50. if(strcmp(tab->name, name) == 0){
  51. devdir(c, tab->qid, tab->name, tab->length, eve, tab->perm, dp);
  52. return 1;
  53. }
  54. return -1;
  55. }
  56. if(s >= nd)
  57. return -1;
  58. tab += s;
  59. devdir(c, tab->qid, tab->name, tab->length, eve, tab->perm, dp);
  60. return 1;
  61. }
  62. static Walkqid*
  63. rootwalk(Chan *c, Chan *nc, char **name, int nname)
  64. {
  65. ulong p;
  66. p = c->qid.path;
  67. if(nname == 0)
  68. p = rootdata[p].dotdot;
  69. return devwalk(c, nc, name, nname, rootdata[p].ptr, rootdata[p].size, rootgen);
  70. }
  71. static int
  72. rootstat(Chan *c, uchar *dp, int n)
  73. {
  74. int p;
  75. p = rootdata[c->qid.path].dotdot;
  76. return devstat(c, dp, n, rootdata[p].ptr, rootdata[p].size, rootgen);
  77. }
  78. static Chan*
  79. rootopen(Chan *c, int omode)
  80. {
  81. int p;
  82. p = rootdata[c->qid.path].dotdot;
  83. return devopen(c, omode, rootdata[p].ptr, rootdata[p].size, rootgen);
  84. }
  85. /*
  86. * sysremove() knows this is a nop
  87. */
  88. static void
  89. rootclose(Chan *c)
  90. {
  91. USED(c);
  92. }
  93. static long
  94. rootread(Chan *c, void *buf, long n, vlong offset)
  95. {
  96. ulong p, len;
  97. uchar *data;
  98. p = c->qid.path;
  99. if(c->qid.type & QTDIR)
  100. return devdirread(c, buf, n, rootdata[p].ptr, rootdata[p].size, rootgen);
  101. len = rootdata[p].size;
  102. if(offset < 0 || offset >= len)
  103. return 0;
  104. if(offset+n > len)
  105. n = len - offset;
  106. data = rootdata[p].ptr;
  107. memmove(buf, data+offset, n);
  108. return n;
  109. }
  110. static long
  111. rootwrite(Chan *c, void *a, long n, vlong off)
  112. {
  113. USED(c); USED(a); USED(n); USED(off);
  114. error(Eperm);
  115. return 0;
  116. }
  117. Dev rootdevtab = {
  118. '/',
  119. "root",
  120. devinit,
  121. rootattach,
  122. rootwalk,
  123. rootstat,
  124. rootopen,
  125. devcreate,
  126. rootclose,
  127. rootread,
  128. devbread,
  129. rootwrite,
  130. devbwrite,
  131. devremove,
  132. devwstat,
  133. };