devroot.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. #include "u.h"
  2. #include "../port/lib.h"
  3. #include "mem.h"
  4. #include "dat.h"
  5. #include "fns.h"
  6. #include "../port/error.h"
  7. enum
  8. {
  9. Qdir = 0,
  10. Qboot = 0x1000,
  11. Nrootfiles = 32,
  12. Nbootfiles = 32,
  13. };
  14. typedef struct Dirlist Dirlist;
  15. struct Dirlist
  16. {
  17. uint base;
  18. Dirtab *dir;
  19. uchar **data;
  20. int ndir;
  21. int mdir;
  22. };
  23. static Dirtab rootdir[Nrootfiles] = {
  24. "#/", {Qdir, 0, QTDIR}, 0, DMDIR|0555,
  25. "boot", {Qboot, 0, QTDIR}, 0, DMDIR|0555,
  26. };
  27. static uchar *rootdata[Nrootfiles];
  28. static Dirlist rootlist =
  29. {
  30. 0,
  31. rootdir,
  32. rootdata,
  33. 2,
  34. Nrootfiles
  35. };
  36. static Dirtab bootdir[Nbootfiles] = {
  37. "boot", {Qboot, 0, QTDIR}, 0, DMDIR|0555,
  38. };
  39. static uchar *bootdata[Nbootfiles];
  40. static Dirlist bootlist =
  41. {
  42. Qboot,
  43. bootdir,
  44. bootdata,
  45. 1,
  46. Nbootfiles
  47. };
  48. /*
  49. * add a file to the list
  50. */
  51. static void
  52. addlist(Dirlist *l, char *name, uchar *contents, ulong len, int perm)
  53. {
  54. Dirtab *d;
  55. if(l->ndir >= l->mdir)
  56. panic("too many root files");
  57. l->data[l->ndir] = contents;
  58. d = &l->dir[l->ndir];
  59. strcpy(d->name, name);
  60. d->length = len;
  61. d->perm = perm;
  62. d->qid.type = 0;
  63. d->qid.vers = 0;
  64. d->qid.path = ++l->ndir + l->base;
  65. if(perm & DMDIR)
  66. d->qid.type |= QTDIR;
  67. }
  68. /*
  69. * add a root file
  70. */
  71. void
  72. addbootfile(char *name, uchar *contents, ulong len)
  73. {
  74. addlist(&bootlist, name, contents, len, 0555);
  75. }
  76. /*
  77. * add a root directory
  78. */
  79. static void
  80. addrootdir(char *name)
  81. {
  82. addlist(&rootlist, name, nil, 0, DMDIR|0555);
  83. }
  84. static void
  85. rootreset(void)
  86. {
  87. addrootdir("bin");
  88. addrootdir("dev");
  89. addrootdir("env");
  90. addrootdir("fd");
  91. addrootdir("mnt");
  92. addrootdir("net");
  93. addrootdir("net.alt");
  94. addrootdir("proc");
  95. addrootdir("root");
  96. addrootdir("srv");
  97. }
  98. static Chan*
  99. rootattach(char *spec)
  100. {
  101. return devattach('/', spec);
  102. }
  103. static int
  104. rootgen(Chan *c, char *name, Dirtab*, int, int s, Dir *dp)
  105. {
  106. int t;
  107. Dirtab *d;
  108. Dirlist *l;
  109. switch((int)c->qid.path){
  110. case Qdir:
  111. if(s == DEVDOTDOT){
  112. devdir(c, (Qid){Qdir, 0, QTDIR}, "#/", 0, eve, 0555, dp);
  113. return 1;
  114. }
  115. return devgen(c, name, rootlist.dir, rootlist.ndir, s, dp);
  116. case Qboot:
  117. if(s == DEVDOTDOT){
  118. devdir(c, (Qid){Qdir, 0, QTDIR}, "#/", 0, eve, 0555, dp);
  119. return 1;
  120. }
  121. return devgen(c, name, bootlist.dir, bootlist.ndir, s, dp);
  122. default:
  123. if(s == DEVDOTDOT){
  124. if((int)c->qid.path < Qboot)
  125. devdir(c, (Qid){Qdir, 0, QTDIR}, "#/", 0, eve, 0555, dp);
  126. else
  127. devdir(c, (Qid){Qboot, 0, QTDIR}, "#/", 0, eve, 0555, dp);
  128. return 1;
  129. }
  130. if(s != 0)
  131. return -1;
  132. if((int)c->qid.path < Qboot){
  133. t = c->qid.path-1;
  134. l = &rootlist;
  135. }else{
  136. t = c->qid.path - Qboot - 1;
  137. l = &bootlist;
  138. }
  139. if(t >= l->ndir)
  140. return -1;
  141. if(t < 0){
  142. print("rootgen %llud %d %d\n", c->qid.path, s, t);
  143. panic("whoops");
  144. }
  145. d = &l->dir[t];
  146. devdir(c, d->qid, d->name, d->length, eve, d->perm, dp);
  147. return 1;
  148. }
  149. }
  150. static Walkqid*
  151. rootwalk(Chan *c, Chan *nc, char **name, int nname)
  152. {
  153. return devwalk(c, nc, name, nname, nil, 0, rootgen);
  154. }
  155. static int
  156. rootstat(Chan *c, uchar *dp, int n)
  157. {
  158. return devstat(c, dp, n, nil, 0, rootgen);
  159. }
  160. static Chan*
  161. rootopen(Chan *c, int omode)
  162. {
  163. return devopen(c, omode, nil, 0, devgen);
  164. }
  165. /*
  166. * sysremove() knows this is a nop
  167. */
  168. static void
  169. rootclose(Chan*)
  170. {
  171. }
  172. static long
  173. rootread(Chan *c, void *buf, long n, vlong off)
  174. {
  175. ulong t;
  176. Dirtab *d;
  177. Dirlist *l;
  178. uchar *data;
  179. ulong offset = off;
  180. t = c->qid.path;
  181. switch(t){
  182. case Qdir:
  183. case Qboot:
  184. return devdirread(c, buf, n, nil, 0, rootgen);
  185. }
  186. if(t<Qboot)
  187. l = &rootlist;
  188. else{
  189. t -= Qboot;
  190. l = &bootlist;
  191. }
  192. t--;
  193. if(t >= l->ndir)
  194. error(Egreg);
  195. d = &l->dir[t];
  196. data = l->data[t];
  197. if(offset >= d->length)
  198. return 0;
  199. if(offset+n > d->length)
  200. n = d->length - offset;
  201. #ifdef asdf
  202. print("[%d] kaddr %.8ulx base %.8ulx offset %ld (%.8ulx), n %d %.8ulx %.8ulx %.8ulx\n",
  203. t, buf, data, offset, offset, n,
  204. ((ulong*)(data+offset))[0],
  205. ((ulong*)(data+offset))[1],
  206. ((ulong*)(data+offset))[2]);
  207. #endif asdf
  208. memmove(buf, data+offset, n);
  209. return n;
  210. }
  211. static long
  212. rootwrite(Chan*, void*, long, vlong)
  213. {
  214. error(Egreg);
  215. return 0;
  216. }
  217. Dev rootdevtab = {
  218. '/',
  219. "root",
  220. rootreset,
  221. devinit,
  222. devshutdown,
  223. rootattach,
  224. rootwalk,
  225. rootstat,
  226. rootopen,
  227. devcreate,
  228. rootclose,
  229. rootread,
  230. devbread,
  231. rootwrite,
  232. devbwrite,
  233. devremove,
  234. devwstat,
  235. };