MODULE RfsClientProxy;
IMPORT SYSTEM, RfsConnection, Files, Network, TCP, KernelLog, Streams;
CONST
ERROR = 0;
GETATTR = 1;
SETATTR = 2;
LOOKUP = 3;
READ = 4;
WRITE = 5;
CREATE = 6;
REMOVE = 8;
RENAME = 10;
READDIR = 11;
CREATETMP = 12;
CHDIR = 13;
KILL = 14;
AUTHENT = 15;
REPLYOK* = 0;
RECEIVERROR* = 1;
PARAMERROR* = 2;
CACHEMISS* = 3;
GETATTRERROR* = 4;
SETATTRERROR* = 5;
NOFILE* = 6;
READERROR* = 7;
WRITEERROR* = 8;
REMOVEERROR* = 9;
RENAMEERROR* = 10;
NODIR* = 11;
AUTHENTICATIONERROR* = 12;
HeaderLength = 100;
Payload* = 16280;
BufSize = Payload + HeaderLength;
MaxNameLen = 64;
DataOff = 8;
Ok = TCP.Ok;
DefaultPort = 9107;
TYPE
Address* = LONGINT;
TYPE
Dir *= OBJECT
VAR
first*: Dirent;
last*: Dirent;
nbrOfEntrys*: LONGINT;
PROCEDURE &Init*;
BEGIN
first := NIL;
last := NIL;
nbrOfEntrys := 0;
END Init;
PROCEDURE Insert*(VAR name: ARRAY OF CHAR; off, len, time, date, size: LONGINT);
VAR entry: Dirent;
BEGIN
NEW(entry);
CopyBuffer(name, off, entry.name, 0, len);
entry.name[len] := 0X;
entry.time := time;
entry.date := date;
entry.size := size;
entry.next := NIL;
IF last # NIL THEN
last.next := entry;
last := last.next;
ELSE
last := entry;
first := last;
END;
INC(nbrOfEntrys);
END Insert;
PROCEDURE Get*(VAR name: ARRAY OF CHAR; VAR time, date, size: LONGINT);
VAR len: LONGINT;
BEGIN
IF first # NIL THEN
len := Len(first.name);
CopyBuffer(first.name, 0, name, 0, len);
name[len] := 0X;
time := first.time;
date := first.date;
size := first.size;
DEC(nbrOfEntrys);
first := first.next;
END;
END Get;
END Dir;
TYPE
Dirent* = OBJECT
VAR
name: ARRAY MaxNameLen OF CHAR;
time, date, size: LONGINT;
next: Dirent;
END Dirent;
TYPE
Proxy* = OBJECT (Files.Volume)
VAR
connection: RfsConnection.Connection;
user, passwd, host, path: ARRAY MaxNameLen OF CHAR;
port : INTEGER;
buf, backupBuf: ARRAY BufSize OF CHAR;
PROCEDURE &InitProxy*(VAR user, passwd, host, path: ARRAY OF CHAR; port: INTEGER);
VAR lenHost, lenUser, lenPasswd, lenPath: LONGINT;
BEGIN
lenUser := Len(user);
lenPasswd := Len(passwd);
lenHost := Len(host);
lenPath := Len(path);
CopyBuffer(user, 0, SELF.user, 0, lenUser);
CopyBuffer(passwd, 0, SELF.passwd, 0, lenPasswd);
CopyBuffer(host, 0, SELF.host, 0, lenHost);
CopyBuffer(path, 0, SELF.path, 0, lenPath);
SELF.user[lenUser] := 0X;
SELF.passwd[lenPasswd] := 0X;
SELF.host[lenHost] := 0X;
SELF.path[lenPath] := 0X;
SELF.port := port;
NEW(connection, host, port);
END InitProxy;
PROCEDURE Error*(VAR errorcode: LONGINT);
VAR msgBytes, procID, testID, dataBytes, res, received: LONGINT;
BEGIN
procID := ERROR;
dataBytes := 0;
msgBytes := dataBytes + 8;
Int2Char(procID, buf, 0);
Int2Char(dataBytes, buf, 4);
connection.Send(buf, 0, msgBytes, res);
GetResult(connection, errorcode, dataBytes, received, buf);
IF errorcode = RECEIVERROR THEN
CopyBuffer(buf, 0, backupBuf, 0, msgBytes);
connection.Reset();
Mount(errorcode);
IF errorcode = REPLYOK THEN
Char2Int(backupBuf, 0, testID);
IF testID = procID THEN
connection.Send(backupBuf, 0, msgBytes, res);
GetResult(connection, errorcode, dataBytes, received, buf);
ELSE
errorcode := RECEIVERROR;
END;
END;
END;
connection.Close();
END Error;
PROCEDURE GetAttr*(fileID: LONGINT; VAR fileLen, time, date, errorcode: LONGINT);
VAR procID, testID, dataBytes, msgBytes, res, received: LONGINT;
BEGIN
procID := GETATTR;
dataBytes := 8;
msgBytes := dataBytes + 8;
Int2Char(procID, buf, 0);
Int2Char(dataBytes, buf, 4);
Int2Char(4, buf, DataOff);
Int2Char(fileID, buf, DataOff + 4);
connection.Send(buf, 0, msgBytes, res);
GetResult(connection, errorcode, dataBytes, received, buf);
IF errorcode = RECEIVERROR THEN
CopyBuffer(buf, 0, backupBuf, 0, msgBytes);
connection.Reset();
Mount(errorcode);
IF errorcode = REPLYOK THEN
Char2Int(backupBuf, 0, testID);
IF testID = procID THEN
connection.Send(backupBuf, 0, msgBytes, res);
GetResult(connection, errorcode, dataBytes, received, buf);
ELSE
errorcode := RECEIVERROR;
END;
END;
END;
IF errorcode # REPLYOK THEN
fileLen := 0;
time := 0;
date := 0;
ELSE
Char2Int(buf, 0, fileLen);
Char2Int(buf, 4, time);
Char2Int(buf, 8, date);
END;
END GetAttr;
PROCEDURE SetAttr*(VAR filename: ARRAY OF CHAR; time, date: LONGINT; VAR errorcode: LONGINT);
VAR msgBytes, procID, testID, dataBytes, res, filenameLen, received: LONGINT;
BEGIN
procID := SETATTR;
filenameLen := Len(filename);
dataBytes := 12 + filenameLen;
msgBytes := dataBytes + 8;
Int2Char(procID, buf, 0);
Int2Char(dataBytes, buf, 4);
Int2Char(time, buf, DataOff);
Int2Char(date, buf, DataOff + 4);
Int2Char(filenameLen, buf, DataOff + 8);
CopyBuffer(filename, 0, buf, DataOff + 12, filenameLen);
connection.Send(buf, 0, msgBytes, res);
GetResult(connection, errorcode, dataBytes, received, buf);
IF errorcode = RECEIVERROR THEN
CopyBuffer(buf, 0, backupBuf, 0, msgBytes);
connection.Reset();
Mount(errorcode);
IF errorcode = REPLYOK THEN
Char2Int(backupBuf, 0, testID);
IF testID = procID THEN
connection.Send(backupBuf, 0, msgBytes, res);
GetResult(connection, errorcode, dataBytes, received, buf);
ELSE
errorcode := RECEIVERROR;
END;
END;
END;
END SetAttr;
PROCEDURE Lookup*(VAR filename : ARRAY OF CHAR; VAR fileID, errorcode: LONGINT);
VAR filenameLen, procID, testID, received, dataBytes, msgBytes, fileIDLen, res: LONGINT;
BEGIN
procID := LOOKUP;
filenameLen := Len(filename);
dataBytes := filenameLen + 4;
msgBytes := dataBytes + 8;
Int2Char(procID, buf, 0);
Int2Char(dataBytes, buf, 4);
Int2Char(filenameLen, buf, DataOff);
CopyBuffer(filename, 0, buf, DataOff + 4, filenameLen);
connection.Send(buf, 0, msgBytes, res);
GetResult(connection, errorcode, dataBytes, received, buf);
IF errorcode = RECEIVERROR THEN
CopyBuffer(buf, 0, backupBuf, 0, msgBytes);
connection.Reset();
Mount(errorcode);
IF errorcode = REPLYOK THEN
Char2Int(backupBuf, 0, testID);
IF testID = procID THEN
connection.Send(backupBuf, 0, msgBytes, res);
GetResult(connection, errorcode, dataBytes, received, buf);
ELSE
errorcode := RECEIVERROR;
END;
END;
END;
IF errorcode # 0 THEN
fileIDLen := 0;
fileID := 0;
ELSE
Char2Int(buf, 0, fileIDLen);
Char2Int(buf, 4, fileID);
END;
END Lookup;
PROCEDURE Read*(fileID, off, len: LONGINT; VAR buffer: ARRAY OF CHAR; dstOff: LONGINT; VAR received, errorcode: LONGINT);
VAR procID, testID, dataBytes, msgBytes, fileLen, res: LONGINT;
BEGIN
procID := READ;
dataBytes := 16;
msgBytes := dataBytes + 8;
Int2Char(procID, buf, 0);
Int2Char(dataBytes, buf, 4);
Int2Char(4, buf, DataOff);
Int2Char(fileID, buf, DataOff + 4);
Int2Char(off, buf, DataOff + 8);
Int2Char(len, buf, DataOff + 12);
connection.Send(buf, 0, msgBytes, res);
GetResult(connection, errorcode, dataBytes, received, buf);
IF errorcode = RECEIVERROR THEN
CopyBuffer(buf, 0, backupBuf, 0, msgBytes);
connection.Reset();
Mount(errorcode);
IF errorcode = REPLYOK THEN
Char2Int(backupBuf, 0, testID);
IF testID = procID THEN
connection.Send(backupBuf, 0, msgBytes, res);
GetResult(connection, errorcode, dataBytes, received, buf);
ELSE
errorcode := RECEIVERROR;
END;
END;
END;
IF errorcode # 0 THEN
fileLen := 0;
received := 0;
ELSE
Char2Int(buf, 0, fileLen);
CopyBuffer(buf, 4, buffer, dstOff, fileLen);
received := received -4;
END;
END Read;
PROCEDURE Write*(fileID, off, len: LONGINT; VAR buffer: ARRAY OF CHAR; VAR written, errorcode: LONGINT);
VAR procID, testID, dataBytes, msgBytes, res, received: LONGINT;
BEGIN
procID := WRITE;
dataBytes := 16 + len;
msgBytes := dataBytes + 8;
Int2Char(procID, buf, 0);
Int2Char(dataBytes, buf, 4);
Int2Char(4, buf, DataOff);
Int2Char(fileID, buf, DataOff + 4);
Int2Char(off, buf, DataOff + 8);
Int2Char(len, buf, DataOff + 12);
CopyBuffer(buffer, 0, buf, DataOff + 16, len);
connection.Send(buf, 0, msgBytes, res);
GetResult(connection, errorcode, dataBytes, received, buf);
IF errorcode = RECEIVERROR THEN
CopyBuffer(buf, 0, backupBuf, 0, msgBytes);
connection.Reset();
Mount(errorcode);
IF errorcode = REPLYOK THEN
Char2Int(backupBuf, 0, testID);
IF testID = procID THEN
connection.Send(backupBuf, 0, msgBytes, res);
GetResult(connection, errorcode, dataBytes, received, buf);
ELSE
errorcode := RECEIVERROR;
END;
END;
END;
IF errorcode # 0 THEN
written := 0;
ELSE
Char2Int(buf, 0, written);
END;
END Write;
PROCEDURE Create*(VAR filename : ARRAY OF CHAR; VAR fileID, errorcode: LONGINT);
VAR filenameLen, procID, testID, received, dataBytes, msgBytes, fileIDLen, res: LONGINT;
BEGIN
procID := CREATE;
filenameLen := Len(filename);
dataBytes := filenameLen + 4;
msgBytes := dataBytes + 8;
Int2Char(procID, buf, 0);
Int2Char(dataBytes, buf, 4);
Int2Char(filenameLen, buf, DataOff);
CopyBuffer(filename, 0, buf, DataOff + 4, filenameLen);
connection.Send(buf, 0, msgBytes, res);
GetResult(connection, errorcode, dataBytes, received, buf);
IF errorcode = RECEIVERROR THEN
CopyBuffer(buf, 0, backupBuf, 0, msgBytes);
connection.Reset();
Mount(errorcode);
IF errorcode = REPLYOK THEN
Char2Int(backupBuf, 0, testID);
IF testID = procID THEN
connection.Send(backupBuf, 0, msgBytes, res);
GetResult(connection, errorcode, dataBytes, received, buf);
ELSE
errorcode := RECEIVERROR;
END;
END;
END;
IF errorcode # 0 THEN
fileIDLen := 0;
fileID := 0;
ELSE
Char2Int(buf, 0, fileIDLen);
Char2Int(buf, 4, fileID);
END;
END Create;
PROCEDURE Remove*(VAR filename : ARRAY OF CHAR; VAR errorcode: LONGINT);
VAR filenameLen, procID, testID, received, dataBytes, msgBytes, res: LONGINT;
BEGIN
procID := REMOVE;
filenameLen := Len(filename);
dataBytes := filenameLen + 4;
msgBytes := dataBytes + 8;
Int2Char(procID, buf, 0);
Int2Char(dataBytes, buf, 4);
Int2Char(filenameLen, buf, DataOff);
CopyBuffer(filename, 0, buf, DataOff + 4, filenameLen);
connection.Send(buf, 0, msgBytes, res);
GetResult(connection, errorcode, dataBytes, received, buf);
IF errorcode = RECEIVERROR THEN
CopyBuffer(buf, 0, backupBuf, 0, msgBytes);
connection.Reset();
Mount(errorcode);
IF errorcode = REPLYOK THEN
Char2Int(backupBuf, 0, testID);
IF testID = procID THEN
connection.Send(backupBuf, 0, msgBytes, res);
GetResult(connection, errorcode, dataBytes, received, buf);
ELSE
errorcode := RECEIVERROR;
END;
END;
END;
END Remove;
PROCEDURE Rename*(VAR filenameFrom, filenameTo: ARRAY OF CHAR; VAR errorcode: LONGINT);
VAR filenameLenFrom, filenameLenTo, procID, testID, received, dataBytes, msgBytes, res: LONGINT;
BEGIN
procID := RENAME;
filenameLenFrom := Len(filenameFrom);
filenameLenTo := Len(filenameTo);
dataBytes := filenameLenFrom + filenameLenTo + 8;
msgBytes := dataBytes + 8;
Int2Char(procID, buf, 0);
Int2Char(dataBytes, buf, 4);
Int2Char(filenameLenFrom, buf, DataOff);
CopyBuffer(filenameFrom, 0, buf, DataOff + 4, filenameLenFrom);
Int2Char(filenameLenTo, buf, DataOff + 4 + filenameLenFrom);
CopyBuffer(filenameTo, 0, buf, DataOff + 4 + filenameLenFrom + 4, filenameLenTo);
connection.Send(buf, 0, msgBytes, res);
GetResult(connection, errorcode, dataBytes, received, buf);
IF errorcode = RECEIVERROR THEN
CopyBuffer(buf, 0, backupBuf, 0, msgBytes);
connection.Reset();
Mount(errorcode);
IF errorcode = REPLYOK THEN
Char2Int(backupBuf, 0, testID);
IF testID = procID THEN
connection.Send(backupBuf, 0, msgBytes, res);
GetResult(connection, errorcode, dataBytes, received, buf);
ELSE
errorcode := RECEIVERROR;
END;
END;
END;
END Rename;
PROCEDURE ReadDir*(VAR filename, mask : ARRAY OF CHAR; detail, cookie: LONGINT; dir: Dir; VAR endOfDir, errorcode: LONGINT);
VAR filenameLen, procID, testID, received, dataBytes, msgBytes, currentIndex, maskLen, res, time, date, size: LONGINT;
BEGIN
procID := READDIR;
filenameLen := Len(filename);
maskLen := Len(mask);
dataBytes := 4 + 4 + 4 + 4 + filenameLen + maskLen;
msgBytes := dataBytes + 8;
Int2Char(procID, buf, 0);
Int2Char(dataBytes, buf, 4);
Int2Char(filenameLen, buf, DataOff);
CopyBuffer(filename, 0, buf, DataOff + 4, filenameLen);
Int2Char(maskLen, buf, DataOff + 4 + filenameLen);
CopyBuffer(mask, 0, buf, DataOff + 8 + filenameLen, maskLen);
Int2Char(detail, buf, DataOff + 8 + filenameLen + maskLen);
Int2Char(cookie, buf, DataOff + 12 + filenameLen + maskLen);
connection.Send(buf, 0, msgBytes, res);
GetResult(connection, errorcode, dataBytes, received, buf);
IF errorcode = RECEIVERROR THEN
CopyBuffer(buf, 0, backupBuf, 0, msgBytes);
connection.Reset();
Mount(errorcode);
IF errorcode = REPLYOK THEN
Char2Int(backupBuf, 0, testID);
IF testID = procID THEN
connection.Send(backupBuf, 0, msgBytes, res);
GetResult(connection, errorcode, dataBytes, received, buf);
ELSE
errorcode := RECEIVERROR;
END;
END;
END;
IF errorcode # 0 THEN
endOfDir := 0;
dir := NIL;
ELSE
Char2Int(buf, 0, endOfDir);
currentIndex := 4;
filenameLen := 0;
IF detail > 0 THEN
WHILE (currentIndex + 16) <= received DO
Char2Int(buf, currentIndex, filenameLen);
Char2Int(buf, currentIndex + 4, time);
Char2Int(buf, currentIndex + 8, date);
Char2Int(buf, currentIndex + 12, size);
IF (currentIndex + 16 + filenameLen) <= received THEN
dir.Insert(buf, currentIndex + 16, filenameLen, time, date, size);
END;
currentIndex := currentIndex + 16 + filenameLen;
END;
ELSE
WHILE (currentIndex + 4) <= received DO
Char2Int(buf, currentIndex, filenameLen);
IF (currentIndex + 4 + filenameLen) <= received THEN
dir.Insert(buf, currentIndex + 4, filenameLen, 0, 0, 0);
END;
currentIndex := currentIndex + 4 + filenameLen;
END;
END;
END;
END ReadDir;
PROCEDURE CreateTmp*(VAR filename : ARRAY OF CHAR; VAR hashval, errorcode: LONGINT);
VAR filenameLen, procID, testID, received, dataBytes, msgBytes, hashvalLen, res: LONGINT;
BEGIN
procID := CREATETMP;
filenameLen := Len(filename);
dataBytes := filenameLen + 4;
msgBytes := dataBytes + 8;
Int2Char(procID, buf, 0);
Int2Char(dataBytes, buf, 4);
Int2Char(filenameLen, buf, DataOff);
CopyBuffer(filename, 0, buf, DataOff + 4, filenameLen);
connection.Send(buf, 0, msgBytes, res);
GetResult(connection, errorcode, dataBytes, received, buf);
IF errorcode = RECEIVERROR THEN
CopyBuffer(buf, 0, backupBuf, 0, msgBytes);
connection.Reset();
Mount(errorcode);
IF errorcode = REPLYOK THEN
Char2Int(backupBuf, 0, testID);
IF testID = procID THEN
connection.Send(backupBuf, 0, msgBytes, res);
GetResult(connection, errorcode, dataBytes, received, buf);
ELSE
errorcode := RECEIVERROR;
END;
END;
END;
IF errorcode # 0 THEN
hashvalLen := 0;
hashval := 0;
filenameLen := 0;
filename[0] := 0X;
ELSE
Char2Int(buf, 0, hashvalLen);
Char2Int(buf, 4, hashval);
Char2Int(buf, 8, filenameLen);
CopyBuffer(buf, 12, filename, 0, filenameLen);
filename[filenameLen] := 0X;
END;
END CreateTmp;
PROCEDURE ChDir*(VAR dir : ARRAY OF CHAR; VAR errorcode: LONGINT);
VAR dirLen, procID, testID, received, dataBytes, msgBytes, res: LONGINT;
BEGIN
procID := CHDIR;
dirLen := Len(dir);
dataBytes := dirLen + 4;
msgBytes := dataBytes + 8;
Int2Char(procID, buf, 0);
Int2Char(dataBytes, buf, 4);
Int2Char(dirLen, buf, DataOff);
CopyBuffer(dir, 0, buf, DataOff + 4, dirLen);
connection.Send(buf, 0, msgBytes, res);
GetResult(connection, errorcode, dataBytes, received, buf);
IF errorcode = RECEIVERROR THEN
CopyBuffer(buf, 0, backupBuf, 0, msgBytes);
connection.Reset();
Mount(errorcode);
IF errorcode = REPLYOK THEN
Char2Int(backupBuf, 0, testID);
IF testID = procID THEN
connection.Send(backupBuf, 0, msgBytes, res);
GetResult(connection, errorcode, dataBytes, received, buf);
ELSE
errorcode := RECEIVERROR;
END;
END;
END;
END ChDir;
PROCEDURE Kill*(VAR errorcode: LONGINT);
VAR msgBytes, procID, testID, dataBytes, res, received: LONGINT;
BEGIN
procID := KILL;
dataBytes := 0;
msgBytes := dataBytes + 8;
Int2Char(procID, buf, 0);
Int2Char(dataBytes, buf, 4);
connection.Send(buf, 0, msgBytes, res);
GetResult(connection, errorcode, dataBytes, received, buf);
IF errorcode = RECEIVERROR THEN
CopyBuffer(buf, 0, backupBuf, 0, msgBytes);
connection.Reset();
Mount(errorcode);
IF errorcode = REPLYOK THEN
Char2Int(backupBuf, 0, testID);
IF testID = procID THEN
connection.Send(backupBuf, 0, msgBytes, res);
GetResult(connection, errorcode, dataBytes, received, buf);
ELSE
errorcode := RECEIVERROR;
END;
END;
END;
connection.Close();
END Kill;
PROCEDURE Authent*(VAR user, passwd, path: ARRAY OF CHAR; VAR errorcode: LONGINT);
VAR userLen, passwdLen, pathLen, procID, received, dataBytes, msgBytes, res: LONGINT;
BEGIN
procID := AUTHENT;
userLen := Len(user);
passwdLen := Len(passwd);
pathLen := Len(path);
dataBytes := userLen + passwdLen + pathLen + 12;
msgBytes := dataBytes + 8;
Int2Char(procID, buf, 0);
Int2Char(dataBytes, buf, 4);
Int2Char(userLen, buf, DataOff);
CopyBuffer(user, 0, buf, DataOff + 4, userLen);
Int2Char(passwdLen, buf, DataOff + 4 + userLen);
CopyBuffer(passwd, 0, buf, DataOff + 4 + userLen + 4, passwdLen);
Int2Char(pathLen, buf, DataOff + 4 + userLen + 4 + passwdLen);
CopyBuffer(path, 0, buf, DataOff + 4 + userLen + 4 + passwdLen + 4, pathLen);
connection.Send(buf, 0, msgBytes, res);
GetResult(connection, errorcode, dataBytes, received, buf);
IF errorcode # REPLYOK THEN
connection.Close();
END;
END Authent;
PROCEDURE Mount*(VAR errorcode: LONGINT);
VAR res: LONGINT;
BEGIN
errorcode := RECEIVERROR;
connection.Open(res);
IF res = Ok THEN
Authent(user, passwd, path, errorcode);
IF errorcode = REPLYOK THEN
ChDir(path, errorcode);
IF errorcode # REPLYOK THEN
KernelLog.String("Mount->cant change Directory");
KernelLog.Ln;
END;
ELSE
KernelLog.String("Mount->Authentification Error");
KernelLog.Ln;
END;
ELSE
KernelLog.String("Mount->can`t open the connection");
KernelLog.Ln;
END;
END Mount;
PROCEDURE Unmount*(VAR errorcode: LONGINT);
BEGIN
Kill(errorcode);
END Unmount;
PROCEDURE AllocBlock*(hint: Address; VAR adr: Address);
END AllocBlock;
PROCEDURE FreeBlock*(adr: Address);
END FreeBlock;
PROCEDURE MarkBlock*(adr: Address);
END MarkBlock;
PROCEDURE Marked*(adr: Address): BOOLEAN;
END Marked;
PROCEDURE Available*(): LONGINT;
BEGIN
RETURN 0;
END Available;
PROCEDURE GetBlock*(adr: LONGINT; VAR blk: ARRAY OF CHAR);
END GetBlock;
PROCEDURE PutBlock*(adr: LONGINT; VAR blk: ARRAY OF CHAR);
END PutBlock;
END Proxy;
PROCEDURE New*(context : Files.Parameters);
VAR
server, user, passwd, path: ARRAY MaxNameLen OF CHAR;
i, errorcode: LONGINT; ch: CHAR; port: LONGINT; newVol: Proxy;
BEGIN
context.arg.SkipWhitespace;
ch := context.arg.Peek();
i := 0;
WHILE (i < LEN(user)-1) & (ch > " ") & (ch # ":") & (context.arg.res = Streams.Ok) DO
context.arg.Char(ch);
user[i] := ch; INC(i);
ch := context.arg.Peek();
END;
user[i] := 0X;
ch := context.arg.Peek();
i := 0;
WHILE (i < LEN(passwd)-1) & (ch > " ") & (ch # "@") & (context.arg.res = Streams.Ok) DO
context.arg.Char(ch);
passwd[i] := ch; INC(i);
ch := context.arg.Peek();
END;
passwd[i] := 0X;
ch := context.arg.Peek();
i := 0;
WHILE (i < LEN(server)-1) & (ch > " ") & (ch # ":") & (context.arg.res = Streams.Ok) DO
context.arg.Char(ch);
server[i] := ch; INC(i);
ch := context.arg.Peek();
END;
server[i] := 0X;
port := 0;
IF (ch = ":") THEN
context.arg.Char(ch);
context.arg.Int(port, FALSE);
ELSE
port := DefaultPort;
END;
ch := context.arg.Peek();
i := 0;
IF ch = "/" THEN
context.arg.Char(ch);
ch := context.arg.Peek();
WHILE (i < LEN(path)-1) & (ch > " ") & (ch # ":") & (context.arg.res = Streams.Ok) DO
context.arg.Char(ch);
path[i] := ch; INC(i);
ch := context.arg.Peek();
END;
path[i] := 0X;
ELSE
CopyBuffer(user, 0, path, 0, Len(user));
END;
context.out.String("Proxy->user: "); context.out.String(user);
context.out.String(", server: "); context.out.String(server);
context.out.String(", port "); context.out.Int(port, 4);
context.out.String(", path: "); context.out.String(path);
context.out.String(", password: "); context.out.String(passwd);
context.out.Ln;
NEW(newVol, user, passwd, server, path, SHORT(port));
newVol.Mount(errorcode);
IF errorcode = REPLYOK THEN
context.vol := newVol;
context.out.String("Proxy->done");
context.out.Ln;
ELSE
context.error.String("Proxy->Failure");
context.error.Ln;
END;
END New;
PROCEDURE GetResult(connection: RfsConnection.Connection; VAR errorcode, dataBytes, received: LONGINT; VAR buf: ARRAY OF CHAR);
VAR res: LONGINT;
BEGIN
errorcode := ReadInteger(connection, res);
IF res = Ok THEN
dataBytes := ReadInteger(connection, res);
IF res = Ok THEN
connection.Receive(buf, 0, dataBytes, received, res);
IF res = Ok THEN
RETURN;
END;
END;
END;
errorcode := RECEIVERROR;
END GetResult;
PROCEDURE Int2Char*(int: LONGINT; VAR buf: ARRAY OF CHAR; off: LONGINT);
BEGIN
Network.PutNet4(buf, off, int);
END Int2Char;
PROCEDURE Char2Int*(buf: ARRAY OF CHAR; off: LONGINT; VAR int: LONGINT);
BEGIN
int := Network.GetNet4(buf, off);
END Char2Int;
PROCEDURE ReadInteger*(connection: RfsConnection.Connection; VAR res: LONGINT): LONGINT;
VAR val, received: LONGINT; buf: ARRAY 4 OF CHAR;
BEGIN
connection.Receive(buf, 0, 4, received, res);
IF received # 4 THEN
val := -1;
res := PARAMERROR;
ELSE
Char2Int(buf, 0, val);
END;
RETURN val;
END ReadInteger;
PROCEDURE Len(x: ARRAY OF CHAR): LONGINT;
VAR j: LONGINT;
BEGIN
j := 0;
WHILE x[j] # 0X DO
INC(j);
END;
RETURN j;
END Len;
PROCEDURE CopyBuffer*(VAR bufFrom: ARRAY OF CHAR; offFrom: LONGINT; VAR bufTo: ARRAY OF CHAR; offTo, len: LONGINT);
BEGIN
ASSERT(offTo + len <= LEN(bufTo));
SYSTEM.MOVE(SYSTEM.ADR(bufFrom[offFrom]), SYSTEM.ADR(bufTo[offTo]), len);
END CopyBuffer;
END RfsClientProxy.