summaryrefslogtreecommitdiff
path: root/module/styxservers.m
diff options
context:
space:
mode:
Diffstat (limited to 'module/styxservers.m')
-rw-r--r--module/styxservers.m135
1 files changed, 135 insertions, 0 deletions
diff --git a/module/styxservers.m b/module/styxservers.m
new file mode 100644
index 00000000..b9b47cf7
--- /dev/null
+++ b/module/styxservers.m
@@ -0,0 +1,135 @@
+Styxservers: module
+{
+ PATH: con "/dis/lib/styxservers.dis";
+
+ Fid: adt {
+ fid: int; # client's fid
+ path: big; # file's 64-bit unique path
+ qtype: int; # file's qid type (eg, Sys->QTDIR if directory)
+ isopen: int; # non-zero if file is open
+ mode: int; # if open, the open mode
+ doffset: (int, int); # (internal) cache of directory offset
+ uname: string; # user name from original attach
+ param: string; # attach aname from original attach
+ data: array of byte; # application data
+
+ clone: fn(f: self ref Fid, nf: ref Fid): ref Fid;
+ open: fn(f: self ref Fid, mode: int, qid: Sys->Qid);
+ walk: fn(f: self ref Fid, qid: Sys->Qid);
+ };
+
+ Navigator: adt {
+ c: chan of ref Navop;
+ reply: chan of (ref Sys->Dir, string);
+
+ new: fn(c: chan of ref Navop): ref Navigator;
+ stat: fn(t: self ref Navigator, q: big): (ref Sys->Dir, string);
+ walk: fn(t: self ref Navigator, parentq: big, name: string): (ref Sys->Dir, string);
+ readdir: fn(t: self ref Navigator, q: big, offset, count: int): array of ref Sys->Dir;
+ };
+
+ Navop: adt {
+ reply: chan of (ref Sys->Dir, string); # channel for reply
+ path: big; # file or directory path
+ pick {
+ Stat =>
+ Walk =>
+ name: string;
+ Readdir =>
+ offset: int; # index (origin 0) of first directory entry to return
+ count: int; # number of directory entries requested
+ }
+ };
+
+ Styxserver: adt {
+ fd: ref Sys->FD; # file server end of connection
+ fids: array of list of ref Fid; # hash table of fids
+ fidlock: chan of int;
+ t: ref Navigator; # name space navigator for this server
+ rootpath: big; # Qid.path of root of its name space
+ msize: int; # negotiated Styx message size
+ replychan: chan of ref Styx->Rmsg;
+
+ new: fn(fd: ref Sys->FD, t: ref Navigator, rootpath: big): (chan of ref Styx->Tmsg, ref Styxserver);
+ reply: fn(srv: self ref Styxserver, m: ref Styx->Rmsg): int;
+ replydirect: fn(srv: self ref Styxserver, m: ref Styx->Rmsg): int;
+
+ # protocol operations
+ attach: fn(srv: self ref Styxserver, m: ref Styx->Tmsg.Attach): ref Fid;
+ clunk: fn(srv: self ref Styxserver, m: ref Styx->Tmsg.Clunk): ref Fid;
+ walk: fn(srv: self ref Styxserver, m: ref Styx->Tmsg.Walk): ref Fid;
+ open: fn(srv: self ref Styxserver, m: ref Styx->Tmsg.Open): ref Fid;
+ read: fn(srv: self ref Styxserver, m: ref Styx->Tmsg.Read): ref Fid;
+ remove: fn(srv: self ref Styxserver, m: ref Styx->Tmsg.Remove): ref Fid;
+ stat: fn(srv: self ref Styxserver, m: ref Styx->Tmsg.Stat);
+
+ default: fn(srv: self ref Styxserver, gm: ref Styx->Tmsg);
+
+ # check validity but don't reply
+ cancreate: fn(srv: self ref Styxserver, m: ref Styx->Tmsg.Create): (ref Fid, int, ref Sys->Dir, string);
+ canopen: fn(srv: self ref Styxserver, m: ref Styx->Tmsg.Open): (ref Fid, int, ref Sys->Dir, string);
+ canremove: fn(srv: self ref Styxserver, m: ref Styx->Tmsg.Remove): (ref Fid, big, string);
+ canread: fn(srv: self ref Styxserver, m: ref Styx->Tmsg.Read): (ref Fid, string);
+ canwrite: fn(srv: self ref Styxserver, m: ref Styx->Tmsg.Write): (ref Fid, string);
+
+ # fid management
+ getfid: fn(srv: self ref Styxserver, fid: int): ref Fid;
+ newfid: fn(srv: self ref Styxserver, fid: int): ref Fid;
+ delfid: fn(srv: self ref Styxserver, c: ref Fid);
+ allfids: fn(srv: self ref Styxserver): list of ref Fid;
+
+ iounit: fn(srv: self ref Styxserver): int;
+ };
+
+ init: fn(styx: Styx);
+ traceset: fn(on: int);
+
+ readbytes: fn(m: ref Styx->Tmsg.Read, d: array of byte): ref Styx->Rmsg.Read;
+ readstr: fn(m: ref Styx->Tmsg.Read, s: string): ref Styx->Rmsg.Read;
+
+ openok: fn(uname: string, omode, perm: int, fuid, fgid: string): int;
+ openmode: fn(o: int): int;
+
+ Einuse: con "fid already in use";
+ Ebadfid: con "bad fid";
+ Eopen: con "fid already opened";
+ Enotfound: con "file does not exist";
+ Enotdir: con "not a directory";
+ Eperm: con "permission denied";
+ Ebadarg: con "bad argument";
+ Eexists: con "file already exists";
+ Emode: con "open/create -- unknown mode";
+ Eoffset: con "read/write -- bad offset";
+ Ecount: con "read/write -- count negative or exceeds msgsize";
+ Enotopen: con "read/write -- on non open fid";
+ Eaccess: con "read/write -- not open in suitable mode";
+ Ename: con "bad character in file name";
+ Edot: con ". and .. are illegal names";
+};
+
+Nametree: module {
+ PATH: con "/dis/lib/nametree.dis";
+ Tree: adt {
+ c: chan of ref Treeop;
+ reply: chan of string;
+
+ quit: fn(t: self ref Tree);
+ create: fn(t: self ref Tree, parent: big, d: Sys->Dir): string;
+ wstat: fn(t: self ref Tree, path: big, d: Sys->Dir): string;
+ remove: fn(t: self ref Tree, path: big): string;
+ getpath: fn(t: self ref Tree, path: big): string;
+ };
+ Treeop: adt {
+ reply: chan of string;
+ q: big;
+ pick {
+ Create or
+ Wstat =>
+ d: Sys->Dir;
+ Remove =>
+ Getpath =>
+ }
+ };
+ init: fn();
+ start: fn(): (ref Tree, chan of ref Styxservers->Navop);
+};