Styxservers: module
{
PATH: con "/dis/o/ofsstyx.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;
new: fn(c: chan of ref Navop): ref Navigator;
stat: fn(t: self ref Navigator, q: big, tag: int): (ref Sys->Dir, string);
walk: fn(t: self ref Navigator, parentq: big, name: string, tag: int): (ref Sys->Dir, string);
readdir: fn(t: self ref Navigator, q: big, offset, count: int, tag: int): array of ref Sys->Dir;
};
Navop: adt {
tag: int;
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);
};
|