Types
FileDescriptor: TYPE ~ REF;
FType: TYPE ~ SunNFS.FType -- { non(0), reg(1), dir(2), blk(3), chr(4), lnk(5) } -- ;
GMT: TYPE ~ BasicTime.GMT;
Mode: TYPE ~ CARD32 -- rwxrwxrwx, only the low order 9 bits are significant -- ;
ROPE: TYPE ~ Rope.ROPE;
ServerHandle: TYPE ~ RemoteFile.ServerHandle;
STREAM: TYPE ~ IO.STREAM;
FileDescriptorInner: TYPE ~ SunNFS.FHandle;
Operations
InnerProc: TYPE ~ PROC [data: SunNFSRemoteFile.ServerData, rpcH: SunRPC.Handle, c: SunRPCAuth.Conversation];
SunNFSUnixOpen:
PUBLIC UnixRemoteFile.OpenProc
-- [sH: ServerHandle, path: ROPE] RETURNS [fD: FileDescriptor] -- ~ {
OpenInner: InnerProc ~ {
fHStatus: SunMount.FHStatus;
pathRefText: REF TEXT ← Rope.ToRefText[path];
rpcH ← SetMountPort[data, rpcH];
fHStatus ← SunMountClient.Mnt[rpcH, c, pathRefText];
IF fHStatus.status # 0 THEN UnixError[$noent, sH, path, "NFS mount lookup failed"];
fD ← fHStatus.directory;
SunMountClient.Umnt[rpcH, c, pathRefText
! SunRPC.Error => CONTINUE];
rpcH ← SetNFSPort[data, rpcH];
};
CallServer[sH, OpenInner];
};
SunNFSUnixClose:
PUBLIC UnixRemoteFile.CloseProc
-- [sH: ServerHandle, fD: FileDescriptor] -- ~ {
NULL;
};
SunNFSUnixCreate:
PUBLIC UnixRemoteFile.CreateProc
-- [sH: ServerHandle, path: ROPE, mode: Mode] RETURNS [fD: FileDescriptor] -- ~ {
dirOpArgs: SunNFS.DirOpArgs;
CreateInner: InnerProc ~ {
attributes: SunNFS.SAttr ← defaultCreateAttributes;
dirOpRes: SunNFS.DirOpRes;
attributes.mode ← SunNFSRemoteFile.FixModeForRegularFile[mode];
dirOpRes ← SunNFSClient.Create[rpcH, c, dirOpArgs, attributes];
IF dirOpRes.status # ok THEN NFSToUnixError[dirOpRes.status, sH, path, "NFS create error"];
fD ← dirOpRes.file;
};
dirOpArgs ← ResolvePath[sH, path];
CallServer[sH, CreateInner];
};
SunNFSUnixDelete:
PUBLIC UnixRemoteFile.DeleteProc
-- [sH: ServerHandle, path: ROPE] -- ~ {
dirOpArgs: SunNFS.DirOpArgs;
DeleteInner: InnerProc ~ {
status: SunNFS.Stat ← SunNFSClient.Remove[rpcH, c, dirOpArgs];
IF status # ok THEN NFSToUnixError[status, sH, path, "NFS delete error"];
};
dirOpArgs ← ResolvePath[sH, path];
CallServer[sH, DeleteInner];
};
SunNFSUnixMkDir:
PUBLIC UnixRemoteFile.MkDirProc
-- [sH: ServerHandle, path: ROPE, mode: Mode] -- ~ {
dirOpArgs: SunNFS.DirOpArgs;
MkDirInner: InnerProc ~ {
attributes: SunNFS.SAttr ← defaultCreateAttributes;
dirOpRes: SunNFS.DirOpRes;
attributes.mode ← SunNFSRemoteFile.FixModeForDirectory[mode];
dirOpRes ← SunNFSClient.Mkdir[rpcH, c, dirOpArgs, attributes];
IF dirOpRes.status # ok THEN NFSToUnixError[dirOpRes.status, sH, path, "NFS mkdir error"];
};
dirOpArgs ← ResolvePath[sH, path];
CallServer[sH, MkDirInner];
};
SunNFSUnixRmDir:
PUBLIC UnixRemoteFile.RmDirProc
-- [sH: ServerHandle, path: ROPE] -- ~ {
dirOpArgs: SunNFS.DirOpArgs;
RmDirInner: InnerProc ~ {
status: SunNFS.Stat ← SunNFSClient.Rmdir[rpcH, c, dirOpArgs];
IF status # ok THEN NFSToUnixError[status, sH, path, "NFS rmdir error"];
};
dirOpArgs ← ResolvePath[sH, path];
CallServer[sH, RmDirInner];
};
SunNFSUnixLink:
PUBLIC UnixRemoteFile.LinkProc
-- [sH: ServerHandle, toPath, asPath: ROPE] -- ~ {
asDirOpArgs: SunNFS.DirOpArgs;
toFD: FileDescriptor;
LinkInner: InnerProc ~ {
status: SunNFS.Stat ← SunNFSClient.Link[rpcH, c, NARROW[toFD], asDirOpArgs];
IF status # ok THEN NFSToUnixError[status, sH, asPath, "NFS link error"];
};
asDirOpArgs ← ResolvePath[sH, asPath];
toFD ← SunNFSUnixOpen[sH, toPath];
CallServer[sH, LinkInner];
};
SunNFSUnixSymLink:
PUBLIC UnixRemoteFile.SymLinkProc
-- [sH: ServerHandle, toPath, asPath: ROPE] -- ~ {
asDirOpArgs: SunNFS.DirOpArgs;
SymLinkInner: InnerProc ~ {
attributes: SunNFS.SAttr ← defaultCreateAttributes;
status: SunNFS.Stat;
attributes.mode ← SunNFSRemoteFile.FixModeForRegularFile[defaultSymLinkCreateMode];
status ← SunNFSClient.Symlink[rpcH, c, asDirOpArgs, Rope.ToRefText[asPath], attributes];
IF status # ok THEN NFSToUnixError[status, sH, asPath, "NFS symlink error"];
};
asDirOpArgs ← ResolvePath[sH, asPath];
CallServer[sH, SymLinkInner];
};
SunNFSUnixRename:
PUBLIC UnixRemoteFile.RenameProc
-- [sH: ServerHandle, fromPath, toPath: ROPE] -- ~ {
fromDirOpArgs, toDirOpArgs: SunNFS.DirOpArgs;
RenameInner: InnerProc ~ {
status: SunNFS.Stat ← SunNFSClient.Rename[rpcH, c, fromDirOpArgs, toDirOpArgs];
IF status # ok THEN NFSToUnixError[status, sH, fromPath, "NFS rename error"];
};
fromDirOpArgs ← ResolvePath[sH, fromPath];
toDirOpArgs ← ResolvePath[sH, toPath];
CallServer[sH, RenameInner];
};
SunNFSUnixEnumerate:
PUBLIC UnixRemoteFile.EnumerateProc
-- [sH: ServerHandle, dirPath: ROPE, pattern: ROPE, eachName: EachNameProc] -- ~ {
dD: FileDescriptor;
EachEntry: SunNFS.EachDirEntryProc
-- [fileid: CARD, filename: FileName] RETURNS [continue: BOOL ← TRUE] -- ~ {
continue ← eachName[Rope.FromRefText[filename]];
};
EnumerateInner: InnerProc ~ {
status: SunNFS.Stat;
eof: BOOL ← FALSE;
cookie: SunNFS.Cookie ← NIL;
WHILE
NOT eof
DO
[status, eof, cookie] ← SunNFSClient.Readdir[rpcH, c, NARROW[dD], cookie, dirSearchBlocksize, EachEntry];
IF status # ok THEN NFSToUnixError[status, sH, dirPath, "NFS enumerate error"];
ENDLOOP;
};
dD ← SunNFSUnixOpen[sH, dirPath];
CallServer[sH, EnumerateInner];
};
SunNFSUnixGetInfo:
PUBLIC UnixRemoteFile.GetInfoProc
-- [sH: ServerHandle, fD: FileDescriptor] RETURNS [type: FType, size: CARD, mode: Mode, mTime: GMT] -- ~ {
GetInfoInner: InnerProc ~ {
attrStat: SunNFS.AttrStat ← SunNFSClient.Getattr[rpcH, c, NARROW[fD]];
IF attrStat.status # ok THEN NFSToUnixError[attrStat.status, sH, NIL, "NFS stat error"];
type ← attrStat.attributes.type;
size ← attrStat.attributes.size;
mode ← SunNFSRemoteFile.GetModeAccessBits[attrStat.attributes.mode];
mTime ← SunNFSRemoteFile.GMTFromSunTime[attrStat.attributes.mtime];
};
CallServer[sH, GetInfoInner];
};
SunNFSUnixSetInfo:
PUBLIC UnixRemoteFile.SetInfoProc
-- [sH: ServerHandle, fD: FileDescriptor, mode: Mode, mTime: GMT] -- ~ {
SetInfoInner: InnerProc ~ {
attrStat: SunNFS.AttrStat;
attributes: SunNFS.SAttr ← defaultCreateAttributes;
IF mode #
CARD.
LAST
THEN
attributes.mode ← SunNFSRemoteFile.UpdateModeAccessBits[attributes.mode, mode];
IF mTime # BasicTime.nullGMT
THEN
attributes.mtime ← SunNFSRemoteFile.SunTimeFromGMT[mTime];
attrStat ← SunNFSClient.Setattr[rpcH, c, NARROW[fD], attributes];
IF attrStat.status # ok THEN NFSToUnixError[attrStat.status, sH, NIL, "NFS setattr error"];
};
CallServer[sH, SetInfoInner];
};
SunNFSUnixRead:
PUBLIC UnixRemoteFile.ReadProc
-- [sH: ServerHandle, fD: FileDescriptor, offset, count: CARD, bOffset: CARD, block: REF TEXT] RETURNS [bytesRead: CARD] -- ~ {
ReadInner: InnerProc ~ {
attrStat: SunNFS.AttrStat ← SunNFSClient.Read[rpcH, c, NARROW[fD], offset, count, bOffset, block];
IF attrStat.status # ok THEN NFSToUnixError[attrStat.status, sH, NIL, "NFS write error"];
bytesRead ← block.length - bOffset;
};
CallServer[sH, ReadInner];
};
SunNFSUnixWrite:
PUBLIC UnixRemoteFile.WriteProc
-- [sH: ServerHandle, fD: FileDescriptor, offset, count: CARD, bOffset: CARD, block: REF TEXT] RETURNS [bytesWritten: CARD] -- ~ {
WriteInner: InnerProc ~ {
attrStat: SunNFS.AttrStat;
IF bOffset >= block.length THEN { bytesWritten ← 0; RETURN };
count ← MIN[count, block.length-bOffset];
attrStat ← SunNFSClient.Write[rpcH, c, NARROW[fD], offset, count, bOffset, block];
IF attrStat.status # ok THEN NFSToUnixError[attrStat.status, sH, NIL, "NFS write error"];
bytesWritten ← count;
};
CallServer[sH, WriteInner];
};
Private Procedures
CallServer:
PROC [sH: ServerHandle, proc: InnerProc] ~ {
data: SunNFSRemoteFile.ServerData ← NARROW[sH.data];
rpcH: SunRPC.Handle;
c: SunRPCAuth.Conversation;
{
ENABLE
UNWIND =>
IF rpcH #
NIL
THEN {
rpcH ← SetNFSPort[data, rpcH];
SunNFSRemoteFile.ReleaseRPCHandleAndConversation[sH, rpcH, c]; rpcH ← NIL;
};
[rpcH, c] ← SunNFSRemoteFile.ObtainRPCHandleAndConversation[sH];
proc[data, rpcH, c ! SunRPC.Error => UnixError[code, sH, NIL, "rpc error"]];
};
SunNFSRemoteFile.ReleaseRPCHandleAndConversation[sH, rpcH, c];
};
SetNFSPort:
PROC [data: SunNFSRemoteFile.ServerData, rpcH: SunRPC.Handle]
RETURNS [SunRPC.Handle] ~
--INLINE-- {
RETURN[SunRPC.SetRemote[rpcH, data.address, data.port]];
};
SetMountPort:
PROC [data: SunNFSRemoteFile.ServerData, rpcH: SunRPC.Handle]
RETURNS [SunRPC.Handle] ~
--INLINE-- {
RETURN[SunRPC.SetRemote[rpcH, data.address, data.mountPort]];
};
ResolvePath:
PROC [sH: ServerHandle, path:
ROPE]
RETURNS [dirOpArgs: SunNFS.DirOpArgs] ~ {
lastSlashPos: INT;
pathPrefix: ROPE;
lastSlashPos ← Rope.FindBackward[path, "/"];
IF lastSlashPos < 0 THEN UnixError[$pathNameSyntax, sH, path, "relative pathnames not supported"];
IF lastSlashPos > 0
THEN pathPrefix ← Rope.Substr[path, 0, lastSlashPos]
ELSE pathPrefix ← "/";
dirOpArgs.dir ← NARROW[SunNFSUnixOpen[sH, pathPrefix]];
dirOpArgs.name ← Rope.ToRefText[Rope.Substr[path, lastSlashPos+1]];
};
}...