1 #pragma src "/sys/src/lib9p" 2 #pragma lib "lib9p.a" 3 4 /* 5 * Maps from ulongs to void*s. 6 */ 7 typedef struct Intmap Intmap; 8 9 #pragma incomplete Intmap 10 11 Intmap* allocmap(void (*inc)(void*)); 12 void freemap(Intmap*, void (*destroy)(void*)); 13 void* lookupkey(Intmap*, ulong); 14 void* insertkey(Intmap*, ulong, void*); 15 int caninsertkey(Intmap*, ulong, void*); 16 void* deletekey(Intmap*, ulong); 17 18 /* 19 * Fid and Request structures. 20 */ 21 typedef struct Fid Fid; 22 typedef struct Req Req; 23 typedef struct Fidpool Fidpool; 24 typedef struct Reqpool Reqpool; 25 typedef struct File File; 26 typedef struct Filelist Filelist; 27 typedef struct Tree Tree; 28 typedef struct Readdir Readdir; 29 typedef struct Srv Srv; 30 31 #pragma incomplete Filelist 32 #pragma incomplete Readdir 33 34 struct Fid 35 { 36 ulong fid; 37 char omode; /* -1 = not open */ 38 File* file; 39 char* uid; 40 Qid qid; 41 void* aux; 42 43 /* below is implementation-specific; don't use */ 44 Readdir* rdir; 45 Ref ref; 46 Fidpool* pool; 47 vlong diroffset; 48 long dirindex; 49 }; 50 51 struct Req 52 { 53 ulong tag; 54 void* aux; 55 Fcall ifcall; 56 Fcall ofcall; 57 Dir d; 58 Req* oldreq; 59 Fid* fid; 60 Fid* afid; 61 Fid* newfid; 62 Srv* srv; 63 64 /* below is implementation-specific; don't use */ 65 QLock lk; 66 Ref ref; 67 Reqpool* pool; 68 uchar* buf; 69 uchar type; 70 uchar responded; 71 char* error; 72 void* rbuf; 73 Req** flush; 74 int nflush; 75 }; 76 77 /* 78 * Pools to maintain Fid <-> fid and Req <-> tag maps. 79 */ 80 81 struct Fidpool { 82 Intmap *map; 83 void (*destroy)(Fid*); 84 Srv *srv; 85 }; 86 87 struct Reqpool { 88 Intmap *map; 89 void (*destroy)(Req*); 90 Srv *srv; 91 }; 92 93 Fidpool* allocfidpool(void (*destroy)(Fid*)); 94 void freefidpool(Fidpool*); 95 Fid* allocfid(Fidpool*, ulong); 96 Fid* lookupfid(Fidpool*, ulong); 97 void closefid(Fid*); 98 Fid* removefid(Fidpool*, ulong); 99 100 Reqpool* allocreqpool(void (*destroy)(Req*)); 101 void freereqpool(Reqpool*); 102 Req* allocreq(Reqpool*, ulong); 103 Req* lookupreq(Reqpool*, ulong); 104 void closereq(Req*); 105 Req* removereq(Reqpool*, ulong); 106 107 typedef int Dirgen(int, Dir*, void*); 108 void dirread9p(Req*, Dirgen*, void*); 109 110 /* 111 * File trees. 112 */ 113 struct File { 114 Ref; 115 Dir; 116 File *parent; 117 void *aux; 118 119 /* below is implementation-specific; don't use */ 120 RWLock; 121 Filelist *filelist; 122 Tree *tree; 123 int nchild; 124 int allocd; 125 int nxchild; 126 Ref readers; 127 }; 128 129 struct Tree { 130 File *root; 131 void (*destroy)(File *file); 132 133 /* below is implementation-specific; don't use */ 134 Lock genlock; 135 ulong qidgen; 136 ulong dirqidgen; 137 }; 138 139 Tree* alloctree(char*, char*, ulong, void(*destroy)(File*)); 140 void freetree(Tree*); 141 File* createfile(File*, char*, char*, ulong, void*); 142 int removefile(File*); 143 void closefile(File*); 144 File* walkfile(File*, char*); 145 Readdir* opendirfile(File*); 146 long readdirfile(Readdir*, uchar*, long); 147 void closedirfile(Readdir*); 148 149 /* 150 * Kernel-style command parser 151 */ 152 typedef struct Cmdbuf Cmdbuf; 153 typedef struct Cmdtab Cmdtab; 154 Cmdbuf* parsecmd(char *a, int n); 155 void respondcmderror(Req*, Cmdbuf*, char*, ...); 156 Cmdtab* lookupcmd(Cmdbuf*, Cmdtab*, int); 157 #pragma varargck argpos respondcmderr 3 158 struct Cmdbuf 159 { 160 char *buf; 161 char **f; 162 int nf; 163 }; 164 165 struct Cmdtab 166 { 167 int index; /* used by client to switch on result */ 168 char *cmd; /* command name */ 169 int narg; /* expected #args; 0 ==> variadic */ 170 }; 171 172 /* 173 * File service loop. 174 */ 175 struct Srv { 176 Tree* tree; 177 void (*destroyfid)(Fid*); 178 void (*destroyreq)(Req*); 179 void (*end)(Srv*); 180 void* aux; 181 182 void (*attach)(Req*); 183 void (*auth)(Req*); 184 void (*open)(Req*); 185 void (*create)(Req*); 186 void (*read)(Req*); 187 void (*write)(Req*); 188 void (*remove)(Req*); 189 void (*flush)(Req*); 190 void (*stat)(Req*); 191 void (*wstat)(Req*); 192 void (*walk)(Req*); 193 char* (*clone)(Fid*, Fid*); 194 char* (*walk1)(Fid*, char*, Qid*); 195 196 int infd; 197 int outfd; 198 int nopipe; 199 int srvfd; 200 int leavefdsopen; /* magic for acme win */ 201 char* keyspec; 202 203 /* below is implementation-specific; don't use */ 204 Fidpool* fpool; 205 Reqpool* rpool; 206 uint msize; 207 208 uchar* rbuf; 209 QLock rlock; 210 uchar* wbuf; 211 QLock wlock; 212 213 char* addr; 214 }; 215 216 void srv(Srv*); 217 void postmountsrv(Srv*, char*, char*, int); 218 void _postmountsrv(Srv*, char*, char*, int); 219 void listensrv(Srv*, char*); 220 void _listensrv(Srv*, char*); 221 int postfd(char*, int); 222 int chatty9p; 223 void respond(Req*, char*); 224 void responderror(Req*); 225 void threadpostmountsrv(Srv*, char*, char*, int); 226 void threadlistensrv(Srv *s, char *addr); 227 228 /* 229 * Helper. Assumes user is same as group. 230 */ 231 int hasperm(File*, char*, int); 232 233 void* emalloc9p(ulong); 234 void* erealloc9p(void*, ulong); 235 char* estrdup9p(char*); 236 237 enum { 238 OMASK = 3 239 }; 240 241 void readstr(Req*, char*); 242 void readbuf(Req*, void*, long); 243 void walkandclone(Req*, char*(*walk1)(Fid*,char*,void*), 244 char*(*clone)(Fid*,Fid*,void*), void*); 245 246 void auth9p(Req*); 247 void authread(Req*); 248 void authwrite(Req*); 249 void authdestroy(Fid*); 250 int authattach(Req*); 251 252 extern void (*_forker)(void (*)(void*), void*, int); 253 254