| #ifndef __9P_H__ |
| #define __9P_H__ 1 |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| /* |
| #pragma src "/sys/src/lib9p" |
| #pragma lib "lib9p.a" |
| */ |
| AUTOLIB(9p) |
| |
| /* |
| * Maps from ulongs to void*s. |
| */ |
| typedef struct Intmap Intmap; |
| |
| Intmap* allocmap(void (*inc)(void*)); |
| void freemap(Intmap*, void (*destroy)(void*)); |
| void* lookupkey(Intmap*, ulong); |
| void* insertkey(Intmap*, ulong, void*); |
| int caninsertkey(Intmap*, ulong, void*); |
| void* deletekey(Intmap*, ulong); |
| |
| /* |
| * Fid and Request structures. |
| */ |
| typedef struct Fid Fid; |
| typedef struct Req Req; |
| typedef struct Fidpool Fidpool; |
| typedef struct Reqpool Reqpool; |
| typedef struct File File; |
| typedef struct Filelist Filelist; |
| typedef struct Tree Tree; |
| typedef struct Readdir Readdir; |
| typedef struct Srv Srv; |
| |
| struct Fid |
| { |
| ulong fid; |
| int omode; /* -1 = not open */ |
| File* file; |
| char* uid; |
| Qid qid; |
| void* aux; |
| |
| /* below is implementation-specific; don't use */ |
| Readdir* rdir; |
| Ref ref; |
| Fidpool* pool; |
| vlong diroffset; |
| long dirindex; |
| }; |
| |
| struct Req |
| { |
| ulong tag; |
| void* aux; |
| Fcall ifcall; |
| Fcall ofcall; |
| Dir d; |
| Req* oldreq; |
| Fid* fid; |
| Fid* afid; |
| Fid* newfid; |
| Srv* srv; |
| |
| /* below is implementation-specific; don't use */ |
| QLock lk; |
| Ref ref; |
| Reqpool* pool; |
| uchar* buf; |
| uchar type; |
| uchar responded; |
| char* error; |
| void* rbuf; |
| Req** flush; |
| int nflush; |
| }; |
| |
| /* |
| * Pools to maintain Fid <-> fid and Req <-> tag maps. |
| */ |
| |
| struct Fidpool { |
| Intmap *map; |
| void (*destroy)(Fid*); |
| Srv *srv; |
| }; |
| |
| struct Reqpool { |
| Intmap *map; |
| void (*destroy)(Req*); |
| Srv *srv; |
| }; |
| |
| Fidpool* allocfidpool(void (*destroy)(Fid*)); |
| void freefidpool(Fidpool*); |
| Fid* allocfid(Fidpool*, ulong); |
| Fid* lookupfid(Fidpool*, ulong); |
| void closefid(Fid*); |
| Fid* removefid(Fidpool*, ulong); |
| |
| Reqpool* allocreqpool(void (*destroy)(Req*)); |
| void freereqpool(Reqpool*); |
| Req* allocreq(Reqpool*, ulong); |
| Req* lookupreq(Reqpool*, ulong); |
| void closereq(Req*); |
| Req* removereq(Reqpool*, ulong); |
| |
| typedef int Dirgen(int, Dir*, void*); |
| void dirread9p(Req*, Dirgen*, void*); |
| |
| /* |
| * File trees. |
| */ |
| struct File { |
| Ref ref; |
| Dir dir; |
| File *parent; |
| void *aux; |
| |
| /* below is implementation-specific; don't use */ |
| RWLock rwlock; |
| Filelist *filelist; |
| Tree *tree; |
| int nchild; |
| int allocd; |
| }; |
| |
| struct Tree { |
| File *root; |
| void (*destroy)(File *file); |
| |
| /* below is implementation-specific; don't use */ |
| Lock genlock; |
| ulong qidgen; |
| ulong dirqidgen; |
| }; |
| |
| Tree* alloctree(char*, char*, ulong, void(*destroy)(File*)); |
| void freetree(Tree*); |
| File* createfile(File*, char*, char*, ulong, void*); |
| int removefile(File*); |
| void closefile(File*); |
| File* walkfile(File*, char*); |
| Readdir* opendirfile(File*); |
| long readdirfile(Readdir*, uchar*, long); |
| void closedirfile(Readdir*); |
| |
| /* |
| * Kernel-style command parser |
| */ |
| typedef struct Cmdbuf Cmdbuf; |
| typedef struct Cmdtab Cmdtab; |
| Cmdbuf* parsecmd(char *a, int n); |
| void respondcmderror(Req*, Cmdbuf*, char*, ...); |
| Cmdtab* lookupcmd(Cmdbuf*, Cmdtab*, int); |
| /* |
| #pragma varargck argpos respondcmderr 3 |
| */ |
| struct Cmdbuf |
| { |
| char *buf; |
| char **f; |
| int nf; |
| }; |
| |
| struct Cmdtab |
| { |
| int index; /* used by client to switch on result */ |
| char *cmd; /* command name */ |
| int narg; /* expected #args; 0 ==> variadic */ |
| }; |
| |
| /* |
| * File service loop. |
| */ |
| struct Srv { |
| Tree* tree; |
| void (*destroyfid)(Fid*); |
| void (*destroyreq)(Req*); |
| void (*start)(Srv*); |
| void (*end)(Srv*); |
| void* aux; |
| |
| void (*attach)(Req*); |
| void (*auth)(Req*); |
| void (*open)(Req*); |
| void (*create)(Req*); |
| void (*read)(Req*); |
| void (*write)(Req*); |
| void (*remove)(Req*); |
| void (*flush)(Req*); |
| void (*stat)(Req*); |
| void (*wstat)(Req*); |
| void (*walk)(Req*); |
| char* (*clone)(Fid*, Fid*); |
| char* (*walk1)(Fid*, char*, Qid*); |
| |
| int infd; |
| int outfd; |
| int nopipe; |
| int srvfd; |
| int leavefdsopen; /* magic for acme win */ |
| int foreground; /* run in foreground */ |
| int fake; |
| |
| /* below is implementation-specific; don't use */ |
| Fidpool* fpool; |
| Reqpool* rpool; |
| uint msize; |
| |
| uchar* rbuf; |
| QLock rlock; |
| uchar* wbuf; |
| QLock wlock; |
| }; |
| |
| void srv(Srv*); |
| void postmountsrv(Srv*, char*, char*, int); |
| int postfd(char*, int); |
| extern int chatty9p; |
| void respond(Req*, char*); |
| void threadpostmountsrv(Srv*, char*, char*, int); |
| |
| /* |
| * Helper. Assumes user is same as group. |
| */ |
| int hasperm(File*, char*, int); |
| |
| void* emalloc9p(ulong); |
| void* erealloc9p(void*, ulong); |
| char* estrdup9p(char*); |
| |
| enum { |
| OMASK = 3 |
| }; |
| |
| void readstr(Req*, char*); |
| void readbuf(Req*, void*, long); |
| void walkandclone(Req*, char*(*walk1)(Fid*,char*,void*), char*(*clone)(Fid*,Fid*,void*), void*); |
| |
| #ifdef __cplusplus |
| } |
| #endif |
| #endif |