mntgen.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <fcall.h>
  4. #include <thread.h>
  5. #include <9p.h>
  6. typedef struct Name Name;
  7. enum {
  8. Qroot = ~0,
  9. };
  10. struct Name {
  11. Ref; // one per fid in use.
  12. char* s;
  13. };
  14. static void aopen(Req*);
  15. static void aread(Req*);
  16. static void astat(Req*);
  17. static void awstat(Req*);
  18. static char* awalk1(Fid* fid, char *name, Qid *qid);
  19. static char* aclone(Fid*, Fid*);
  20. static void aattach(Req*);
  21. static void aclunk(Fid*);
  22. Name** names;
  23. int nnames;
  24. Srv asrv = {
  25. .tree = nil,
  26. .attach = aattach,
  27. .auth = nil,
  28. .open = aopen,
  29. .create = nil,
  30. .read = aread,
  31. .write = nil,
  32. .remove = nil,
  33. .flush = nil,
  34. .stat = astat,
  35. .wstat = awstat,
  36. .walk = nil,
  37. .walk1 = awalk1,
  38. .clone = aclone,
  39. .destroyfid = aclunk,
  40. .destroyreq = nil,
  41. .end = nil,
  42. .aux = nil,
  43. .infd = -1,
  44. .outfd = -1,
  45. .nopipe = 0,
  46. .srvfd = -1,
  47. };
  48. static void
  49. usage(void)
  50. {
  51. fprint(2, "usage: mntgen [-s srv] [mnt]\n");
  52. exits("usage");
  53. }
  54. static Name*
  55. newname(char* name)
  56. {
  57. Name* n;
  58. if ((nnames % 100) == 0)
  59. names = realloc(names, (nnames+100)*sizeof(Name*));
  60. n = names[nnames++] = malloc(sizeof(Name));
  61. n->s = strdup(name);
  62. n->ref = 1;
  63. return n;
  64. }
  65. static void
  66. closename(int i)
  67. {
  68. assert (i >= 0 && i < nnames && names[i] != nil);
  69. if (decref(names[i]) <= 0){
  70. free(names[i]->s);
  71. free(names[i]);
  72. names[i] = nil; // never reused; qids are unique
  73. }
  74. }
  75. static int
  76. n2i(int n)
  77. {
  78. int i;
  79. for(i=0; i<nnames; i++)
  80. if(names[i] != nil && n-- == 0)
  81. return i;
  82. return -1;
  83. }
  84. static int
  85. agen(int n, Dir *dir, void* a)
  86. {
  87. int i;
  88. i = n2i(n);
  89. if (a == nil || i < 0)
  90. return -1;
  91. dir->qid.type = QTDIR;
  92. dir->qid.path = i;
  93. dir->qid.vers = 0;
  94. dir->name = estrdup9p(names[i]->s);
  95. dir->uid = estrdup9p("sys");
  96. dir->gid = estrdup9p("sys");
  97. dir->mode= 0555|DMDIR;
  98. dir->length= 0;
  99. return 0;
  100. }
  101. static void
  102. aattach(Req* r)
  103. {
  104. Qid q;
  105. q.type = QTDIR;
  106. q.path = Qroot;
  107. q.vers = 0;
  108. r->fid->qid = q;
  109. r->ofcall.qid = q;
  110. respond(r, nil);
  111. }
  112. static void
  113. aopen(Req* r)
  114. {
  115. respond(r, nil);
  116. }
  117. static void
  118. aread(Req* r)
  119. {
  120. Qid q;
  121. q = r->fid->qid;
  122. if (q.path < 0 || q.path >= nnames && q.path != Qroot)
  123. respond(r, "bug: bad qid");
  124. if (q.path == Qroot)
  125. dirread9p(r, agen, names);
  126. else
  127. dirread9p(r, agen, nil);
  128. respond(r, nil);
  129. }
  130. static void
  131. astat(Req* r)
  132. {
  133. Qid q;
  134. q = r->fid->qid;
  135. if (q.path < 0 || q.path >= nnames && q.path != Qroot)
  136. respond(r, "bug: bad qid");
  137. r->d.qid = q;
  138. if (q.path == Qroot)
  139. r->d.name = estrdup9p("/");
  140. else
  141. r->d.name = estrdup9p(names[q.path]->s);
  142. r->d.uid = estrdup9p("sys");
  143. r->d.gid = estrdup9p("sys");
  144. r->d.length= 0;
  145. r->d.mode= 0555|DMDIR;
  146. respond(r, nil);
  147. }
  148. static void
  149. awstat(Req* r)
  150. {
  151. respond(r, "wstat not allowed");
  152. }
  153. static char*
  154. awalk1(Fid* fid, char *name, Qid *qid)
  155. {
  156. int i, oldi;
  157. oldi = fid->qid.path;
  158. if (strcmp(name, "..") == 0){
  159. i = Qroot;
  160. goto done;
  161. }
  162. if (fid->qid.path != Qroot)
  163. return "no such name";
  164. for (i = 0; i < nnames; i++)
  165. if (names[i] != nil && strcmp(name, names[i]->s) == 0){
  166. incref(names[i]);
  167. break;
  168. }
  169. if (i == nnames)
  170. newname(name);
  171. done:
  172. if (oldi >=0 && oldi < nnames)
  173. closename(oldi);
  174. qid->path = i;
  175. qid->type = QTDIR;
  176. qid->vers = 0;
  177. fid->qid = *qid;
  178. return nil;
  179. }
  180. static char*
  181. aclone(Fid* old, Fid*)
  182. {
  183. int i;
  184. i = old->qid.path;
  185. if (i >= 0 && i < nnames)
  186. incref(names[i]);
  187. return nil;
  188. }
  189. static void
  190. aclunk(Fid* fid)
  191. {
  192. int i;
  193. i = fid->qid.path;
  194. if (i >= 0 && i < nnames)
  195. closename(i);
  196. }
  197. void
  198. main(int argc, char* argv[])
  199. {
  200. char* mnt;
  201. char* srvname;
  202. srvname = nil;
  203. ARGBEGIN{
  204. case 's':
  205. srvname = EARGF(usage());
  206. break;
  207. default:
  208. usage();
  209. }ARGEND;
  210. if (argc > 1)
  211. usage();
  212. if (argc == 0)
  213. mnt = "/n";
  214. else
  215. mnt = *argv;
  216. postmountsrv(&asrv, srvname, mnt, MAFTER);
  217. exits(nil);
  218. }