17dd7cddfSDavid du Colombier #pragma src "/sys/src/lib9p" 27dd7cddfSDavid du Colombier #pragma lib "lib9p.a" 37dd7cddfSDavid du Colombier 49a747e4fSDavid du Colombier /* 59a747e4fSDavid du Colombier * Maps from ulongs to void*s. 69a747e4fSDavid du Colombier */ 79a747e4fSDavid du Colombier typedef struct Intmap Intmap; 89a747e4fSDavid du Colombier 9*12fd1c83SDavid du Colombier #pragma incomplete Intmap 10*12fd1c83SDavid du Colombier 119a747e4fSDavid du Colombier Intmap* allocmap(void (*inc)(void*)); 129a747e4fSDavid du Colombier void freemap(Intmap*, void (*destroy)(void*)); 139a747e4fSDavid du Colombier void* lookupkey(Intmap*, ulong); 149a747e4fSDavid du Colombier void* insertkey(Intmap*, ulong, void*); 159a747e4fSDavid du Colombier int caninsertkey(Intmap*, ulong, void*); 169a747e4fSDavid du Colombier void* deletekey(Intmap*, ulong); 179a747e4fSDavid du Colombier 189a747e4fSDavid du Colombier /* 199a747e4fSDavid du Colombier * Fid and Request structures. 209a747e4fSDavid du Colombier */ 217dd7cddfSDavid du Colombier typedef struct Fid Fid; 229a747e4fSDavid du Colombier typedef struct Req Req; 237dd7cddfSDavid du Colombier typedef struct Fidpool Fidpool; 249a747e4fSDavid du Colombier typedef struct Reqpool Reqpool; 257dd7cddfSDavid du Colombier typedef struct File File; 267dd7cddfSDavid du Colombier typedef struct Filelist Filelist; 277dd7cddfSDavid du Colombier typedef struct Tree Tree; 289a747e4fSDavid du Colombier typedef struct Readdir Readdir; 299a747e4fSDavid du Colombier typedef struct Srv Srv; 307dd7cddfSDavid du Colombier 31*12fd1c83SDavid du Colombier #pragma incomplete Filelist 32*12fd1c83SDavid du Colombier #pragma incomplete Readdir 33*12fd1c83SDavid du Colombier 347dd7cddfSDavid du Colombier struct Fid 357dd7cddfSDavid du Colombier { 367dd7cddfSDavid du Colombier ulong fid; 377dd7cddfSDavid du Colombier char omode; /* -1 = not open */ 387dd7cddfSDavid du Colombier File* file; 399a747e4fSDavid du Colombier char* uid; 407dd7cddfSDavid du Colombier Qid qid; 417dd7cddfSDavid du Colombier void* aux; 427dd7cddfSDavid du Colombier 437dd7cddfSDavid du Colombier /* below is implementation-specific; don't use */ 449a747e4fSDavid du Colombier Readdir* rdir; 457dd7cddfSDavid du Colombier Ref ref; 467dd7cddfSDavid du Colombier Fidpool* pool; 479a747e4fSDavid du Colombier vlong diroffset; 489a747e4fSDavid du Colombier long dirindex; 497dd7cddfSDavid du Colombier }; 507dd7cddfSDavid du Colombier 517dd7cddfSDavid du Colombier struct Req 527dd7cddfSDavid du Colombier { 537dd7cddfSDavid du Colombier ulong tag; 547dd7cddfSDavid du Colombier void* aux; 559a747e4fSDavid du Colombier Fcall ifcall; 567dd7cddfSDavid du Colombier Fcall ofcall; 579a747e4fSDavid du Colombier Dir d; 589a747e4fSDavid du Colombier Req* oldreq; 599a747e4fSDavid du Colombier Fid* fid; 609a747e4fSDavid du Colombier Fid* afid; 619a747e4fSDavid du Colombier Fid* newfid; 629a747e4fSDavid du Colombier Srv* srv; 637dd7cddfSDavid du Colombier 647dd7cddfSDavid du Colombier /* below is implementation-specific; don't use */ 657fd46167SDavid du Colombier QLock lk; 667dd7cddfSDavid du Colombier Ref ref; 677dd7cddfSDavid du Colombier Reqpool* pool; 689a747e4fSDavid du Colombier uchar* buf; 697dd7cddfSDavid du Colombier uchar type; 707dd7cddfSDavid du Colombier uchar responded; 717dd7cddfSDavid du Colombier char* error; 7259cc4ca5SDavid du Colombier void* rbuf; 737fd46167SDavid du Colombier Req** flush; 747fd46167SDavid du Colombier int nflush; 757dd7cddfSDavid du Colombier }; 767dd7cddfSDavid du Colombier 779a747e4fSDavid du Colombier /* 789a747e4fSDavid du Colombier * Pools to maintain Fid <-> fid and Req <-> tag maps. 799a747e4fSDavid du Colombier */ 807dd7cddfSDavid du Colombier 819a747e4fSDavid du Colombier struct Fidpool { 829a747e4fSDavid du Colombier Intmap *map; 839a747e4fSDavid du Colombier void (*destroy)(Fid*); 849a747e4fSDavid du Colombier Srv *srv; 857dd7cddfSDavid du Colombier }; 867dd7cddfSDavid du Colombier 879a747e4fSDavid du Colombier struct Reqpool { 889a747e4fSDavid du Colombier Intmap *map; 899a747e4fSDavid du Colombier void (*destroy)(Req*); 909a747e4fSDavid du Colombier Srv *srv; 919a747e4fSDavid du Colombier }; 929a747e4fSDavid du Colombier 939a747e4fSDavid du Colombier Fidpool* allocfidpool(void (*destroy)(Fid*)); 949a747e4fSDavid du Colombier void freefidpool(Fidpool*); 959a747e4fSDavid du Colombier Fid* allocfid(Fidpool*, ulong); 969a747e4fSDavid du Colombier Fid* lookupfid(Fidpool*, ulong); 979a747e4fSDavid du Colombier void closefid(Fid*); 989a747e4fSDavid du Colombier Fid* removefid(Fidpool*, ulong); 999a747e4fSDavid du Colombier 1009a747e4fSDavid du Colombier Reqpool* allocreqpool(void (*destroy)(Req*)); 1019a747e4fSDavid du Colombier void freereqpool(Reqpool*); 1029a747e4fSDavid du Colombier Req* allocreq(Reqpool*, ulong); 1039a747e4fSDavid du Colombier Req* lookupreq(Reqpool*, ulong); 1049a747e4fSDavid du Colombier void closereq(Req*); 1059a747e4fSDavid du Colombier Req* removereq(Reqpool*, ulong); 1069a747e4fSDavid du Colombier 1079a747e4fSDavid du Colombier typedef int Dirgen(int, Dir*, void*); 1089a747e4fSDavid du Colombier void dirread9p(Req*, Dirgen*, void*); 1099a747e4fSDavid du Colombier 1109a747e4fSDavid du Colombier /* 1119a747e4fSDavid du Colombier * File trees. 1129a747e4fSDavid du Colombier */ 1137dd7cddfSDavid du Colombier struct File { 1149a747e4fSDavid du Colombier Ref; 1157dd7cddfSDavid du Colombier Dir; 1167dd7cddfSDavid du Colombier File *parent; 1177dd7cddfSDavid du Colombier void *aux; 1187dd7cddfSDavid du Colombier 1197dd7cddfSDavid du Colombier /* below is implementation-specific; don't use */ 1209a747e4fSDavid du Colombier RWLock; 1217dd7cddfSDavid du Colombier Filelist *filelist; 1227dd7cddfSDavid du Colombier Tree *tree; 1239a747e4fSDavid du Colombier int nchild; 1249a747e4fSDavid du Colombier int allocd; 1257dd7cddfSDavid du Colombier }; 1267dd7cddfSDavid du Colombier 1277dd7cddfSDavid du Colombier struct Tree { 1287dd7cddfSDavid du Colombier File *root; 1299a747e4fSDavid du Colombier void (*destroy)(File *file); 1307dd7cddfSDavid du Colombier 1317dd7cddfSDavid du Colombier /* below is implementation-specific; don't use */ 1329a747e4fSDavid du Colombier Lock genlock; 1337dd7cddfSDavid du Colombier ulong qidgen; 1347dd7cddfSDavid du Colombier ulong dirqidgen; 1357dd7cddfSDavid du Colombier }; 1367dd7cddfSDavid du Colombier 1379a747e4fSDavid du Colombier Tree* alloctree(char*, char*, ulong, void(*destroy)(File*)); 1389a747e4fSDavid du Colombier void freetree(Tree*); 1399a747e4fSDavid du Colombier File* createfile(File*, char*, char*, ulong, void*); 1409a747e4fSDavid du Colombier int removefile(File*); 1419a747e4fSDavid du Colombier void closefile(File*); 1429a747e4fSDavid du Colombier File* walkfile(File*, char*); 1439a747e4fSDavid du Colombier Readdir* opendirfile(File*); 1449a747e4fSDavid du Colombier long readdirfile(Readdir*, uchar*, long); 1459a747e4fSDavid du Colombier void closedirfile(Readdir*); 1467dd7cddfSDavid du Colombier 1479a747e4fSDavid du Colombier /* 1483ff48bf5SDavid du Colombier * Kernel-style command parser 1493ff48bf5SDavid du Colombier */ 1503ff48bf5SDavid du Colombier typedef struct Cmdbuf Cmdbuf; 1513ff48bf5SDavid du Colombier typedef struct Cmdtab Cmdtab; 1523ff48bf5SDavid du Colombier Cmdbuf* parsecmd(char *a, int n); 1533ff48bf5SDavid du Colombier void respondcmderror(Req*, Cmdbuf*, char*, ...); 1543ff48bf5SDavid du Colombier Cmdtab* lookupcmd(Cmdbuf*, Cmdtab*, int); 1553ff48bf5SDavid du Colombier #pragma varargck argpos respondcmderr 3 1563ff48bf5SDavid du Colombier struct Cmdbuf 1573ff48bf5SDavid du Colombier { 1583ff48bf5SDavid du Colombier char *buf; 1593ff48bf5SDavid du Colombier char **f; 1603ff48bf5SDavid du Colombier int nf; 1613ff48bf5SDavid du Colombier }; 1623ff48bf5SDavid du Colombier 1633ff48bf5SDavid du Colombier struct Cmdtab 1643ff48bf5SDavid du Colombier { 1653ff48bf5SDavid du Colombier int index; /* used by client to switch on result */ 1663ff48bf5SDavid du Colombier char *cmd; /* command name */ 1673ff48bf5SDavid du Colombier int narg; /* expected #args; 0 ==> variadic */ 1683ff48bf5SDavid du Colombier }; 1693ff48bf5SDavid du Colombier 1703ff48bf5SDavid du Colombier /* 1719a747e4fSDavid du Colombier * File service loop. 1729a747e4fSDavid du Colombier */ 1739a747e4fSDavid du Colombier struct Srv { 1749a747e4fSDavid du Colombier Tree* tree; 1759a747e4fSDavid du Colombier void (*destroyfid)(Fid*); 1769a747e4fSDavid du Colombier void (*destroyreq)(Req*); 1779a747e4fSDavid du Colombier void (*end)(Srv*); 1789a747e4fSDavid du Colombier void* aux; 1797dd7cddfSDavid du Colombier 1809a747e4fSDavid du Colombier void (*attach)(Req*); 1819a747e4fSDavid du Colombier void (*auth)(Req*); 1829a747e4fSDavid du Colombier void (*open)(Req*); 1839a747e4fSDavid du Colombier void (*create)(Req*); 1849a747e4fSDavid du Colombier void (*read)(Req*); 1859a747e4fSDavid du Colombier void (*write)(Req*); 1869a747e4fSDavid du Colombier void (*remove)(Req*); 1879a747e4fSDavid du Colombier void (*flush)(Req*); 1889a747e4fSDavid du Colombier void (*stat)(Req*); 1899a747e4fSDavid du Colombier void (*wstat)(Req*); 1909a747e4fSDavid du Colombier void (*walk)(Req*); 1919a747e4fSDavid du Colombier char* (*clone)(Fid*, Fid*); 1929a747e4fSDavid du Colombier char* (*walk1)(Fid*, char*, Qid*); 1937dd7cddfSDavid du Colombier 1949a747e4fSDavid du Colombier int infd; 1959a747e4fSDavid du Colombier int outfd; 1969a747e4fSDavid du Colombier int nopipe; 1979a747e4fSDavid du Colombier int srvfd; 1982ebbfa15SDavid du Colombier int leavefdsopen; /* magic for acme win */ 1997dd7cddfSDavid du Colombier 2009a747e4fSDavid du Colombier /* below is implementation-specific; don't use */ 2019a747e4fSDavid du Colombier Fidpool* fpool; 2029a747e4fSDavid du Colombier Reqpool* rpool; 2039a747e4fSDavid du Colombier uint msize; 2049a747e4fSDavid du Colombier 2059a747e4fSDavid du Colombier uchar* rbuf; 2069a747e4fSDavid du Colombier QLock rlock; 2079a747e4fSDavid du Colombier uchar* wbuf; 2089a747e4fSDavid du Colombier QLock wlock; 2099a747e4fSDavid du Colombier }; 2109a747e4fSDavid du Colombier 2119a747e4fSDavid du Colombier void srv(Srv*); 2127dd7cddfSDavid du Colombier void postmountsrv(Srv*, char*, char*, int); 2139a747e4fSDavid du Colombier int postfd(char*, int); 2149a747e4fSDavid du Colombier int chatty9p; 2157dd7cddfSDavid du Colombier void respond(Req*, char*); 21680ee5cbfSDavid du Colombier void threadpostmountsrv(Srv*, char*, char*, int); 21759cc4ca5SDavid du Colombier 2189a747e4fSDavid du Colombier /* 2199a747e4fSDavid du Colombier * Helper. Assumes user is same as group. 2209a747e4fSDavid du Colombier */ 2217dd7cddfSDavid du Colombier int hasperm(File*, char*, int); 2227dd7cddfSDavid du Colombier 2239a747e4fSDavid du Colombier void* emalloc9p(ulong); 2249a747e4fSDavid du Colombier void* erealloc9p(void*, ulong); 2259a747e4fSDavid du Colombier char* estrdup9p(char*); 2267dd7cddfSDavid du Colombier 2277dd7cddfSDavid du Colombier enum { 2287dd7cddfSDavid du Colombier OMASK = 3 2297dd7cddfSDavid du Colombier }; 23059cc4ca5SDavid du Colombier 2319a747e4fSDavid du Colombier void readstr(Req*, char*); 2329a747e4fSDavid du Colombier void readbuf(Req*, void*, long); 2337fd46167SDavid du Colombier void walkandclone(Req*, char*(*walk1)(Fid*,char*,void*), char*(*clone)(Fid*,Fid*,void*), void*); 2347fd46167SDavid du Colombier 235