2
0

RfsClientProxy.Mod 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915
  1. (* Patrick Stuedi, 30.08.01 *)
  2. MODULE RfsClientProxy; (** AUTHOR "pstuedi"; PURPOSE "Remote File System proxy"; *)
  3. IMPORT SYSTEM, RfsConnection, Files, Network, TCP, KernelLog, Streams;
  4. CONST
  5. (*Server Procedures*)
  6. ERROR = 0;
  7. GETATTR = 1;
  8. SETATTR = 2;
  9. LOOKUP = 3;
  10. READ = 4;
  11. WRITE = 5;
  12. CREATE = 6;
  13. REMOVE = 8;
  14. RENAME = 10;
  15. READDIR = 11;
  16. CREATETMP = 12;
  17. CHDIR = 13;
  18. KILL = 14;
  19. AUTHENT = 15;
  20. (*Errorcodes*)
  21. REPLYOK* = 0;
  22. RECEIVERROR* = 1;
  23. PARAMERROR* = 2;
  24. CACHEMISS* = 3;
  25. GETATTRERROR* = 4;
  26. SETATTRERROR* = 5;
  27. NOFILE* = 6;
  28. READERROR* = 7;
  29. WRITEERROR* = 8;
  30. REMOVEERROR* = 9;
  31. RENAMEERROR* = 10;
  32. NODIR* = 11;
  33. AUTHENTICATIONERROR* = 12;
  34. HeaderLength = 100;
  35. Payload* = 16280;
  36. BufSize = Payload + HeaderLength;
  37. MaxNameLen = 64;
  38. DataOff = 8;
  39. Ok = TCP.Ok;
  40. DefaultPort = 9107;
  41. (* Dummy Types for Files.Volume interface *)
  42. TYPE
  43. Address* = LONGINT;
  44. TYPE
  45. (** Type for storing Directory Information, used by RfsFS.Filesystem.Enumerate() **)
  46. Dir *= OBJECT
  47. VAR
  48. first*: Dirent;
  49. last*: Dirent;
  50. nbrOfEntrys*: LONGINT;
  51. PROCEDURE &Init*;
  52. BEGIN
  53. first := NIL;
  54. last := NIL;
  55. nbrOfEntrys := 0;
  56. END Init;
  57. (** insert tuple name, time, date and size. name is at offset off in Array **)
  58. PROCEDURE Insert*(VAR name: ARRAY OF CHAR; off, len, time, date, size: LONGINT);
  59. VAR entry: Dirent;
  60. BEGIN
  61. NEW(entry);
  62. CopyBuffer(name, off, entry.name, 0, len);
  63. entry.name[len] := 0X;
  64. entry.time := time;
  65. entry.date := date;
  66. entry.size := size;
  67. entry.next := NIL;
  68. IF last # NIL THEN
  69. last.next := entry;
  70. last := last.next;
  71. ELSE
  72. last := entry;
  73. first := last;
  74. END;
  75. INC(nbrOfEntrys);
  76. END Insert;
  77. (** Get next tuple from Object **)
  78. PROCEDURE Get*(VAR name: ARRAY OF CHAR; VAR time, date, size: LONGINT);
  79. VAR len: LONGINT;
  80. BEGIN
  81. IF first # NIL THEN
  82. len := Len(first.name);
  83. CopyBuffer(first.name, 0, name, 0, len);
  84. name[len] := 0X;
  85. time := first.time;
  86. date := first.date;
  87. size := first.size;
  88. DEC(nbrOfEntrys);
  89. first := first.next;
  90. END;
  91. END Get;
  92. END Dir;
  93. TYPE
  94. (** Type of Dir Entry **)
  95. Dirent* = OBJECT
  96. VAR
  97. name: ARRAY MaxNameLen OF CHAR;
  98. time, date, size: LONGINT;
  99. next: Dirent;
  100. END Dirent;
  101. TYPE
  102. (** Virtual Filesystem Object (Rfs File Protocoll), communicates via RfsRPC with rfsServerProxy on the serverside **)
  103. Proxy* = OBJECT (Files.Volume)
  104. VAR
  105. connection: RfsConnection.Connection;
  106. user, passwd, host, path: ARRAY MaxNameLen OF CHAR;
  107. port : INTEGER;
  108. buf, backupBuf: ARRAY BufSize OF CHAR;
  109. PROCEDURE &InitProxy*(VAR user, passwd, host, path: ARRAY OF CHAR; port: INTEGER);
  110. VAR lenHost, lenUser, lenPasswd, lenPath: LONGINT;
  111. BEGIN
  112. lenUser := Len(user);
  113. lenPasswd := Len(passwd);
  114. lenHost := Len(host);
  115. lenPath := Len(path);
  116. CopyBuffer(user, 0, SELF.user, 0, lenUser);
  117. CopyBuffer(passwd, 0, SELF.passwd, 0, lenPasswd);
  118. CopyBuffer(host, 0, SELF.host, 0, lenHost);
  119. CopyBuffer(path, 0, SELF.path, 0, lenPath);
  120. SELF.user[lenUser] := 0X;
  121. SELF.passwd[lenPasswd] := 0X;
  122. SELF.host[lenHost] := 0X;
  123. SELF.path[lenPath] := 0X;
  124. SELF.port := port;
  125. NEW(connection, host, port);
  126. END InitProxy;
  127. (** does nothing, just for benchmarking **)
  128. PROCEDURE Error*(VAR errorcode: LONGINT);
  129. VAR msgBytes, procID, testID, dataBytes, received: LONGINT; res: WORD;
  130. BEGIN
  131. (*prepare params and send*)
  132. procID := ERROR;
  133. dataBytes := 0;
  134. msgBytes := dataBytes + 8;
  135. Int2Char(procID, buf, 0);
  136. Int2Char(dataBytes, buf, 4);
  137. connection.Send(buf, 0, msgBytes, res);
  138. (*receiving result*)
  139. GetResult(connection, errorcode, dataBytes, received, buf);
  140. IF errorcode = RECEIVERROR THEN
  141. CopyBuffer(buf, 0, backupBuf, 0, msgBytes);
  142. connection.Reset();
  143. Mount(errorcode);
  144. IF errorcode = REPLYOK THEN
  145. Char2Int(backupBuf, 0, testID);
  146. IF testID = procID THEN
  147. connection.Send(backupBuf, 0, msgBytes, res);
  148. GetResult(connection, errorcode, dataBytes, received, buf);
  149. ELSE
  150. errorcode := RECEIVERROR;
  151. END;
  152. END;
  153. END;
  154. connection.Close();
  155. END Error;
  156. (** retrieves fileLength, time and date of a file identified by fileID **)
  157. PROCEDURE GetAttr*(fileID: LONGINT; VAR fileLen, time, date, errorcode: LONGINT);
  158. VAR procID, testID, dataBytes, msgBytes, received: LONGINT; res: WORD;
  159. BEGIN
  160. (*prepare params and send*)
  161. procID := GETATTR;
  162. dataBytes := 8;
  163. msgBytes := dataBytes + 8;
  164. Int2Char(procID, buf, 0);
  165. Int2Char(dataBytes, buf, 4);
  166. Int2Char(4, buf, DataOff);
  167. Int2Char(fileID, buf, DataOff + 4);
  168. connection.Send(buf, 0, msgBytes, res);
  169. (*getting result*)
  170. GetResult(connection, errorcode, dataBytes, received, buf);
  171. IF errorcode = RECEIVERROR THEN
  172. CopyBuffer(buf, 0, backupBuf, 0, msgBytes);
  173. connection.Reset();
  174. Mount(errorcode);
  175. IF errorcode = REPLYOK THEN
  176. Char2Int(backupBuf, 0, testID);
  177. IF testID = procID THEN
  178. connection.Send(backupBuf, 0, msgBytes, res);
  179. GetResult(connection, errorcode, dataBytes, received, buf);
  180. ELSE
  181. errorcode := RECEIVERROR;
  182. END;
  183. END;
  184. END;
  185. IF errorcode # REPLYOK THEN
  186. fileLen := 0;
  187. time := 0;
  188. date := 0;
  189. ELSE
  190. Char2Int(buf, 0, fileLen);
  191. Char2Int(buf, 4, time);
  192. Char2Int(buf, 8, date);
  193. END;
  194. END GetAttr;
  195. (** Sets the attributes time and date of a file identified by filename **)
  196. PROCEDURE SetAttr*(VAR filename: ARRAY OF CHAR; time, date: LONGINT; VAR errorcode: LONGINT);
  197. VAR msgBytes, procID, testID, dataBytes, filenameLen, received: LONGINT; res: WORD;
  198. BEGIN
  199. (*prepare params and send*)
  200. procID := SETATTR;
  201. filenameLen := Len(filename);
  202. dataBytes := 12 + filenameLen;
  203. msgBytes := dataBytes + 8;
  204. Int2Char(procID, buf, 0);
  205. Int2Char(dataBytes, buf, 4);
  206. Int2Char(time, buf, DataOff);
  207. Int2Char(date, buf, DataOff + 4);
  208. Int2Char(filenameLen, buf, DataOff + 8);
  209. CopyBuffer(filename, 0, buf, DataOff + 12, filenameLen);
  210. connection.Send(buf, 0, msgBytes, res);
  211. (*getting result*)
  212. GetResult(connection, errorcode, dataBytes, received, buf);
  213. IF errorcode = RECEIVERROR THEN
  214. CopyBuffer(buf, 0, backupBuf, 0, msgBytes);
  215. connection.Reset();
  216. Mount(errorcode);
  217. IF errorcode = REPLYOK THEN
  218. Char2Int(backupBuf, 0, testID);
  219. IF testID = procID THEN
  220. connection.Send(backupBuf, 0, msgBytes, res);
  221. GetResult(connection, errorcode, dataBytes, received, buf);
  222. ELSE
  223. errorcode := RECEIVERROR;
  224. END;
  225. END;
  226. END;
  227. END SetAttr;
  228. (** transforms a filename into a fileID **)
  229. PROCEDURE Lookup*(VAR filename : ARRAY OF CHAR; VAR fileID, errorcode: LONGINT);
  230. VAR filenameLen, procID, testID, received, dataBytes, msgBytes, fileIDLen: LONGINT; res: WORD;
  231. BEGIN
  232. (*prepare params and send*)
  233. procID := LOOKUP;
  234. filenameLen := Len(filename);
  235. dataBytes := filenameLen + 4;
  236. msgBytes := dataBytes + 8;
  237. Int2Char(procID, buf, 0);
  238. Int2Char(dataBytes, buf, 4);
  239. Int2Char(filenameLen, buf, DataOff);
  240. CopyBuffer(filename, 0, buf, DataOff + 4, filenameLen);
  241. connection.Send(buf, 0, msgBytes, res);
  242. (*getting result*)
  243. GetResult(connection, errorcode, dataBytes, received, buf);
  244. IF errorcode = RECEIVERROR THEN
  245. CopyBuffer(buf, 0, backupBuf, 0, msgBytes);
  246. connection.Reset();
  247. Mount(errorcode);
  248. IF errorcode = REPLYOK THEN
  249. Char2Int(backupBuf, 0, testID);
  250. IF testID = procID THEN
  251. connection.Send(backupBuf, 0, msgBytes, res);
  252. GetResult(connection, errorcode, dataBytes, received, buf);
  253. ELSE
  254. errorcode := RECEIVERROR;
  255. END;
  256. END;
  257. END;
  258. IF errorcode # 0 THEN
  259. fileIDLen := 0;
  260. fileID := 0;
  261. ELSE
  262. Char2Int(buf, 0, fileIDLen);
  263. Char2Int(buf, 4, fileID);
  264. END;
  265. END Lookup;
  266. (** Reads len Bytes of data from a given offset off in a file identified by fileID and returns the data in buf at offset dstOff **)
  267. PROCEDURE Read*(fileID, off, len: LONGINT; VAR buffer: ARRAY OF CHAR; dstOff: LONGINT; VAR received, errorcode: LONGINT);
  268. VAR procID, testID, dataBytes, msgBytes, fileLen: LONGINT; res: WORD;
  269. BEGIN
  270. (*prepare params and send*)
  271. procID := READ;
  272. dataBytes := 16;
  273. msgBytes := dataBytes + 8;
  274. Int2Char(procID, buf, 0);
  275. Int2Char(dataBytes, buf, 4);
  276. Int2Char(4, buf, DataOff);
  277. Int2Char(fileID, buf, DataOff + 4);
  278. Int2Char(off, buf, DataOff + 8);
  279. Int2Char(len, buf, DataOff + 12);
  280. connection.Send(buf, 0, msgBytes, res);
  281. (*getting result*)
  282. GetResult(connection, errorcode, dataBytes, received, buf);
  283. IF errorcode = RECEIVERROR THEN
  284. CopyBuffer(buf, 0, backupBuf, 0, msgBytes);
  285. connection.Reset();
  286. Mount(errorcode);
  287. IF errorcode = REPLYOK THEN
  288. Char2Int(backupBuf, 0, testID);
  289. IF testID = procID THEN
  290. connection.Send(backupBuf, 0, msgBytes, res);
  291. GetResult(connection, errorcode, dataBytes, received, buf);
  292. ELSE
  293. errorcode := RECEIVERROR;
  294. END;
  295. END;
  296. END;
  297. IF errorcode # 0 THEN
  298. fileLen := 0;
  299. received := 0;
  300. ELSE
  301. Char2Int(buf, 0, fileLen);
  302. CopyBuffer(buf, 4, buffer, dstOff, fileLen);
  303. received := received -4;
  304. END;
  305. END Read;
  306. (** Writes len Bytes of data beginning off bytes from the beginning of file into a file identified by fileID **)
  307. PROCEDURE Write*(fileID, off, len: LONGINT; VAR buffer: ARRAY OF CHAR; VAR written, errorcode: LONGINT);
  308. VAR procID, testID, dataBytes, msgBytes, received: LONGINT; res: WORD;
  309. BEGIN
  310. (*prepare params and send*)
  311. procID := WRITE;
  312. dataBytes := 16 + len;
  313. msgBytes := dataBytes + 8;
  314. Int2Char(procID, buf, 0);
  315. Int2Char(dataBytes, buf, 4);
  316. Int2Char(4, buf, DataOff);
  317. Int2Char(fileID, buf, DataOff + 4);
  318. Int2Char(off, buf, DataOff + 8);
  319. Int2Char(len, buf, DataOff + 12);
  320. CopyBuffer(buffer, 0, buf, DataOff + 16, len);
  321. connection.Send(buf, 0, msgBytes, res);
  322. (*getting result*)
  323. GetResult(connection, errorcode, dataBytes, received, buf);
  324. IF errorcode = RECEIVERROR THEN
  325. CopyBuffer(buf, 0, backupBuf, 0, msgBytes);
  326. connection.Reset();
  327. Mount(errorcode);
  328. IF errorcode = REPLYOK THEN
  329. Char2Int(backupBuf, 0, testID);
  330. IF testID = procID THEN
  331. connection.Send(backupBuf, 0, msgBytes, res);
  332. GetResult(connection, errorcode, dataBytes, received, buf);
  333. ELSE
  334. errorcode := RECEIVERROR;
  335. END;
  336. END;
  337. END;
  338. IF errorcode # 0 THEN
  339. written := 0;
  340. ELSE
  341. Char2Int(buf, 0, written);
  342. END;
  343. END Write;
  344. (** Creates a file with name filename and return a fileID for it **)
  345. PROCEDURE Create*(VAR filename : ARRAY OF CHAR; VAR fileID, errorcode: LONGINT);
  346. VAR filenameLen, procID, testID, received, dataBytes, msgBytes, fileIDLen: LONGINT; res: WORD;
  347. BEGIN
  348. (*prepare params and send*)
  349. procID := CREATE;
  350. filenameLen := Len(filename);
  351. dataBytes := filenameLen + 4;
  352. msgBytes := dataBytes + 8;
  353. Int2Char(procID, buf, 0);
  354. Int2Char(dataBytes, buf, 4);
  355. Int2Char(filenameLen, buf, DataOff);
  356. CopyBuffer(filename, 0, buf, DataOff + 4, filenameLen);
  357. connection.Send(buf, 0, msgBytes, res);
  358. (*getting result*)
  359. GetResult(connection, errorcode, dataBytes, received, buf);
  360. IF errorcode = RECEIVERROR THEN
  361. CopyBuffer(buf, 0, backupBuf, 0, msgBytes);
  362. connection.Reset();
  363. Mount(errorcode);
  364. IF errorcode = REPLYOK THEN
  365. Char2Int(backupBuf, 0, testID);
  366. IF testID = procID THEN
  367. connection.Send(backupBuf, 0, msgBytes, res);
  368. GetResult(connection, errorcode, dataBytes, received, buf);
  369. ELSE
  370. errorcode := RECEIVERROR;
  371. END;
  372. END;
  373. END;
  374. IF errorcode # 0 THEN
  375. fileIDLen := 0;
  376. fileID := 0;
  377. ELSE
  378. Char2Int(buf, 0, fileIDLen);
  379. Char2Int(buf, 4, fileID);
  380. END;
  381. END Create;
  382. (** Deletes a File with name filename **)
  383. PROCEDURE Remove*(VAR filename : ARRAY OF CHAR; VAR errorcode: LONGINT);
  384. VAR filenameLen, procID, testID, received, dataBytes, msgBytes: LONGINT; res: WORD;
  385. BEGIN
  386. (*prepare params and send*)
  387. procID := REMOVE;
  388. filenameLen := Len(filename);
  389. dataBytes := filenameLen + 4;
  390. msgBytes := dataBytes + 8;
  391. Int2Char(procID, buf, 0);
  392. Int2Char(dataBytes, buf, 4);
  393. Int2Char(filenameLen, buf, DataOff);
  394. CopyBuffer(filename, 0, buf, DataOff + 4, filenameLen);
  395. connection.Send(buf, 0, msgBytes, res);
  396. (*getting result*)
  397. GetResult(connection, errorcode, dataBytes, received, buf);
  398. IF errorcode = RECEIVERROR THEN
  399. CopyBuffer(buf, 0, backupBuf, 0, msgBytes);
  400. connection.Reset();
  401. Mount(errorcode);
  402. IF errorcode = REPLYOK THEN
  403. Char2Int(backupBuf, 0, testID);
  404. IF testID = procID THEN
  405. connection.Send(backupBuf, 0, msgBytes, res);
  406. GetResult(connection, errorcode, dataBytes, received, buf);
  407. ELSE
  408. errorcode := RECEIVERROR;
  409. END;
  410. END;
  411. END;
  412. END Remove;
  413. (** Renames a file with name filenemFrom into a new name filenameTo **)
  414. PROCEDURE Rename*(VAR filenameFrom, filenameTo: ARRAY OF CHAR; VAR errorcode: LONGINT);
  415. VAR filenameLenFrom, filenameLenTo, procID, testID, received, dataBytes, msgBytes: LONGINT; res: WORD;
  416. BEGIN
  417. (*prepare params and send*)
  418. procID := RENAME;
  419. filenameLenFrom := Len(filenameFrom);
  420. filenameLenTo := Len(filenameTo);
  421. dataBytes := filenameLenFrom + filenameLenTo + 8;
  422. msgBytes := dataBytes + 8;
  423. Int2Char(procID, buf, 0);
  424. Int2Char(dataBytes, buf, 4);
  425. Int2Char(filenameLenFrom, buf, DataOff);
  426. CopyBuffer(filenameFrom, 0, buf, DataOff + 4, filenameLenFrom);
  427. Int2Char(filenameLenTo, buf, DataOff + 4 + filenameLenFrom);
  428. CopyBuffer(filenameTo, 0, buf, DataOff + 4 + filenameLenFrom + 4, filenameLenTo);
  429. connection.Send(buf, 0, msgBytes, res);
  430. (*getting result*)
  431. GetResult(connection, errorcode, dataBytes, received, buf);
  432. IF errorcode = RECEIVERROR THEN
  433. CopyBuffer(buf, 0, backupBuf, 0, msgBytes);
  434. connection.Reset();
  435. Mount(errorcode);
  436. IF errorcode = REPLYOK THEN
  437. Char2Int(backupBuf, 0, testID);
  438. IF testID = procID THEN
  439. connection.Send(backupBuf, 0, msgBytes, res);
  440. GetResult(connection, errorcode, dataBytes, received, buf);
  441. ELSE
  442. errorcode := RECEIVERROR;
  443. END;
  444. END;
  445. END;
  446. END Rename;
  447. (** Retrieves a variable number of entries with names matching the mask string from a directory identified by filename.
  448. the detail is set to 1 if time, data and size information is also to be retrieved. the offset value tells how many entries
  449. should be skip first **)
  450. PROCEDURE ReadDir*(VAR filename, mask : ARRAY OF CHAR; detail, cookie: LONGINT; dir: Dir; VAR endOfDir, errorcode: LONGINT);
  451. VAR filenameLen, procID, testID, received, dataBytes, msgBytes, currentIndex, maskLen, time, date, size: LONGINT; res: WORD;
  452. BEGIN
  453. (*prepare params and send*)
  454. procID := READDIR;
  455. filenameLen := Len(filename);
  456. maskLen := Len(mask);
  457. dataBytes := 4 + 4 + 4 + 4 + filenameLen + maskLen;
  458. msgBytes := dataBytes + 8;
  459. Int2Char(procID, buf, 0);
  460. Int2Char(dataBytes, buf, 4);
  461. Int2Char(filenameLen, buf, DataOff);
  462. CopyBuffer(filename, 0, buf, DataOff + 4, filenameLen);
  463. Int2Char(maskLen, buf, DataOff + 4 + filenameLen);
  464. CopyBuffer(mask, 0, buf, DataOff + 8 + filenameLen, maskLen);
  465. Int2Char(detail, buf, DataOff + 8 + filenameLen + maskLen);
  466. Int2Char(cookie, buf, DataOff + 12 + filenameLen + maskLen);
  467. connection.Send(buf, 0, msgBytes, res);
  468. (*getting result*)
  469. GetResult(connection, errorcode, dataBytes, received, buf);
  470. IF errorcode = RECEIVERROR THEN
  471. CopyBuffer(buf, 0, backupBuf, 0, msgBytes);
  472. connection.Reset();
  473. Mount(errorcode);
  474. IF errorcode = REPLYOK THEN
  475. Char2Int(backupBuf, 0, testID);
  476. IF testID = procID THEN
  477. connection.Send(backupBuf, 0, msgBytes, res);
  478. GetResult(connection, errorcode, dataBytes, received, buf);
  479. ELSE
  480. errorcode := RECEIVERROR;
  481. END;
  482. END;
  483. END;
  484. IF errorcode # 0 THEN
  485. endOfDir := 0;
  486. dir := NIL;
  487. ELSE
  488. Char2Int(buf, 0, endOfDir);
  489. currentIndex := 4;
  490. filenameLen := 0;
  491. IF detail > 0 THEN
  492. WHILE (currentIndex + 16) <= received DO
  493. Char2Int(buf, currentIndex, filenameLen);
  494. Char2Int(buf, currentIndex + 4, time);
  495. Char2Int(buf, currentIndex + 8, date);
  496. Char2Int(buf, currentIndex + 12, size);
  497. IF (currentIndex + 16 + filenameLen) <= received THEN
  498. dir.Insert(buf, currentIndex + 16, filenameLen, time, date, size);
  499. END;
  500. currentIndex := currentIndex + 16 + filenameLen;
  501. END;
  502. ELSE
  503. WHILE (currentIndex + 4) <= received DO
  504. Char2Int(buf, currentIndex, filenameLen);
  505. IF (currentIndex + 4 + filenameLen) <= received THEN
  506. dir.Insert(buf, currentIndex + 4, filenameLen, 0, 0, 0);
  507. END;
  508. currentIndex := currentIndex + 4 + filenameLen;
  509. END;
  510. END;
  511. END;
  512. END ReadDir;
  513. (** Creates a temporary File on the server and returns the name for it **)
  514. PROCEDURE CreateTmp*(VAR filename : ARRAY OF CHAR; VAR hashval, errorcode: LONGINT);
  515. VAR filenameLen, procID, testID, received, dataBytes, msgBytes, hashvalLen: LONGINT; res: WORD;
  516. BEGIN
  517. (*prepare params and send*)
  518. procID := CREATETMP;
  519. filenameLen := Len(filename);
  520. dataBytes := filenameLen + 4;
  521. msgBytes := dataBytes + 8;
  522. Int2Char(procID, buf, 0);
  523. Int2Char(dataBytes, buf, 4);
  524. Int2Char(filenameLen, buf, DataOff);
  525. CopyBuffer(filename, 0, buf, DataOff + 4, filenameLen);
  526. connection.Send(buf, 0, msgBytes, res);
  527. (*getting result*)
  528. GetResult(connection, errorcode, dataBytes, received, buf);
  529. IF errorcode = RECEIVERROR THEN
  530. CopyBuffer(buf, 0, backupBuf, 0, msgBytes);
  531. connection.Reset();
  532. Mount(errorcode);
  533. IF errorcode = REPLYOK THEN
  534. Char2Int(backupBuf, 0, testID);
  535. IF testID = procID THEN
  536. connection.Send(backupBuf, 0, msgBytes, res);
  537. GetResult(connection, errorcode, dataBytes, received, buf);
  538. ELSE
  539. errorcode := RECEIVERROR;
  540. END;
  541. END;
  542. END;
  543. IF errorcode # 0 THEN
  544. hashvalLen := 0;
  545. hashval := 0;
  546. filenameLen := 0;
  547. filename[0] := 0X;
  548. ELSE
  549. Char2Int(buf, 0, hashvalLen);
  550. Char2Int(buf, 4, hashval);
  551. Char2Int(buf, 8, filenameLen);
  552. CopyBuffer(buf, 12, filename, 0, filenameLen);
  553. filename[filenameLen] := 0X;
  554. END;
  555. END CreateTmp;
  556. (** Changes the Directory of the corresponding rfsServerProxy Process **)
  557. PROCEDURE ChDir*(VAR dir : ARRAY OF CHAR; VAR errorcode: LONGINT);
  558. VAR dirLen, procID, testID, received, dataBytes, msgBytes: LONGINT; res: WORD;
  559. BEGIN
  560. (*prepare params and send*)
  561. procID := CHDIR;
  562. dirLen := Len(dir);
  563. dataBytes := dirLen + 4;
  564. msgBytes := dataBytes + 8;
  565. Int2Char(procID, buf, 0);
  566. Int2Char(dataBytes, buf, 4);
  567. Int2Char(dirLen, buf, DataOff);
  568. CopyBuffer(dir, 0, buf, DataOff + 4, dirLen);
  569. connection.Send(buf, 0, msgBytes, res);
  570. (*getting result*)
  571. GetResult(connection, errorcode, dataBytes, received, buf);
  572. IF errorcode = RECEIVERROR THEN
  573. CopyBuffer(buf, 0, backupBuf, 0, msgBytes);
  574. connection.Reset();
  575. Mount(errorcode);
  576. IF errorcode = REPLYOK THEN
  577. Char2Int(backupBuf, 0, testID);
  578. IF testID = procID THEN
  579. connection.Send(backupBuf, 0, msgBytes, res);
  580. GetResult(connection, errorcode, dataBytes, received, buf);
  581. ELSE
  582. errorcode := RECEIVERROR;
  583. END;
  584. END;
  585. END;
  586. END ChDir;
  587. (** cleans the open file structure on the server an kills the process **)
  588. PROCEDURE Kill*(VAR errorcode: LONGINT);
  589. VAR msgBytes, procID, testID, dataBytes, received: LONGINT; res: WORD;
  590. BEGIN
  591. (*prepare params and send*)
  592. procID := KILL;
  593. dataBytes := 0;
  594. msgBytes := dataBytes + 8;
  595. Int2Char(procID, buf, 0);
  596. Int2Char(dataBytes, buf, 4);
  597. connection.Send(buf, 0, msgBytes, res);
  598. (*getting result*)
  599. GetResult(connection, errorcode, dataBytes, received, buf);
  600. IF errorcode = RECEIVERROR THEN
  601. CopyBuffer(buf, 0, backupBuf, 0, msgBytes);
  602. connection.Reset();
  603. Mount(errorcode);
  604. IF errorcode = REPLYOK THEN
  605. Char2Int(backupBuf, 0, testID);
  606. IF testID = procID THEN
  607. connection.Send(backupBuf, 0, msgBytes, res);
  608. GetResult(connection, errorcode, dataBytes, received, buf);
  609. ELSE
  610. errorcode := RECEIVERROR;
  611. END;
  612. END;
  613. END;
  614. connection.Close();
  615. END Kill;
  616. (** Authenticates the session. User and Passwd are sending in plainttext **)
  617. PROCEDURE Authent*(VAR user, passwd, path: ARRAY OF CHAR; VAR errorcode: LONGINT);
  618. VAR userLen, passwdLen, pathLen, procID, received, dataBytes, msgBytes: LONGINT; res: WORD;
  619. BEGIN
  620. (*prepare params and send*)
  621. procID := AUTHENT;
  622. userLen := Len(user);
  623. passwdLen := Len(passwd);
  624. pathLen := Len(path);
  625. dataBytes := userLen + passwdLen + pathLen + 12;
  626. msgBytes := dataBytes + 8;
  627. Int2Char(procID, buf, 0);
  628. Int2Char(dataBytes, buf, 4);
  629. Int2Char(userLen, buf, DataOff);
  630. CopyBuffer(user, 0, buf, DataOff + 4, userLen);
  631. Int2Char(passwdLen, buf, DataOff + 4 + userLen);
  632. CopyBuffer(passwd, 0, buf, DataOff + 4 + userLen + 4, passwdLen);
  633. Int2Char(pathLen, buf, DataOff + 4 + userLen + 4 + passwdLen);
  634. CopyBuffer(path, 0, buf, DataOff + 4 + userLen + 4 + passwdLen + 4, pathLen);
  635. connection.Send(buf, 0, msgBytes, res);
  636. (*getting result*)
  637. GetResult(connection, errorcode, dataBytes, received, buf);
  638. IF errorcode # REPLYOK THEN
  639. connection.Close();
  640. END;
  641. END Authent;
  642. (** this procedure is called from RfsClientProxy.New, it dows the Authentication and changes **)
  643. (** the directory on the server **)
  644. PROCEDURE Mount*(VAR errorcode: LONGINT);
  645. VAR res: WORD;
  646. BEGIN
  647. errorcode := RECEIVERROR;
  648. connection.Open(res);
  649. IF res = Ok THEN
  650. Authent(user, passwd, path, errorcode);
  651. IF errorcode = REPLYOK THEN
  652. ChDir(path, errorcode);
  653. IF errorcode # REPLYOK THEN
  654. KernelLog.String("Mount->cant change Directory");
  655. KernelLog.Ln;
  656. END;
  657. ELSE
  658. KernelLog.String("Mount->Authentication Error");
  659. KernelLog.Ln;
  660. END;
  661. ELSE
  662. KernelLog.String("Mount->can`t open the connection");
  663. KernelLog.Ln;
  664. END;
  665. END Mount;
  666. (** Kill the rfsServerProxy Process and closes the connection **)
  667. PROCEDURE Unmount*(VAR errorcode: LONGINT);
  668. BEGIN
  669. Kill(errorcode);
  670. END Unmount;
  671. PROCEDURE AllocBlock*(hint: Address; VAR adr: Address);
  672. END AllocBlock;
  673. PROCEDURE FreeBlock*(adr: Address);
  674. END FreeBlock;
  675. PROCEDURE MarkBlock*(adr: Address);
  676. END MarkBlock;
  677. PROCEDURE Marked*(adr: Address): BOOLEAN;
  678. END Marked;
  679. PROCEDURE Available*(): LONGINT;
  680. BEGIN
  681. RETURN 0;
  682. END Available;
  683. PROCEDURE GetBlock*(adr: LONGINT; VAR blk: ARRAY OF CHAR);
  684. END GetBlock;
  685. PROCEDURE PutBlock*(adr: LONGINT; VAR blk: ARRAY OF CHAR);
  686. END PutBlock;
  687. END Proxy;
  688. (** a new global Proxy for a specific host, port pair is created. in addition a dummy Volume is set to par.vol.
  689. this is needed so that the mounting works correctly **)
  690. PROCEDURE New*(context : Files.Parameters);
  691. VAR
  692. server, user, passwd, path: ARRAY MaxNameLen OF CHAR;
  693. i, errorcode: LONGINT; ch: CHAR; port: LONGINT; newVol: Proxy;
  694. BEGIN
  695. context.arg.SkipWhitespace;
  696. ch := context.arg.Peek();
  697. i := 0;
  698. WHILE (i < LEN(user)-1) & (ch > " ") & (ch # ":") & (context.arg.res = Streams.Ok) DO
  699. context.arg.Char(ch); (* consume ch *)
  700. user[i] := ch; INC(i);
  701. ch := context.arg.Peek();
  702. END;
  703. user[i] := 0X;
  704. ch := context.arg.Peek();
  705. i := 0;
  706. WHILE (i < LEN(passwd)-1) & (ch > " ") & (ch # "@") & (context.arg.res = Streams.Ok) DO
  707. context.arg.Char(ch); (* consume ch *)
  708. passwd[i] := ch; INC(i);
  709. ch := context.arg.Peek();
  710. END;
  711. passwd[i] := 0X;
  712. ch := context.arg.Peek();
  713. i := 0;
  714. WHILE (i < LEN(server)-1) & (ch > " ") & (ch # ":") & (context.arg.res = Streams.Ok) DO
  715. context.arg.Char(ch); (* consume ch *)
  716. server[i] := ch; INC(i);
  717. ch := context.arg.Peek();
  718. END;
  719. server[i] := 0X;
  720. port := 0;
  721. IF (ch = ":") THEN
  722. context.arg.Char(ch); (* consume ":" *)
  723. context.arg.Int(port, FALSE);
  724. ELSE
  725. port := DefaultPort;
  726. END;
  727. ch := context.arg.Peek();
  728. i := 0;
  729. IF ch = "/" THEN
  730. context.arg.Char(ch); (* consume "/" *)
  731. ch := context.arg.Peek();
  732. WHILE (i < LEN(path)-1) & (ch > " ") & (ch # ":") & (context.arg.res = Streams.Ok) DO
  733. context.arg.Char(ch); (* consume ch *)
  734. path[i] := ch; INC(i);
  735. ch := context.arg.Peek();
  736. END;
  737. path[i] := 0X;
  738. ELSE
  739. CopyBuffer(user, 0, path, 0, Len(user));
  740. END;
  741. context.out.String("Proxy->user: "); context.out.String(user);
  742. context.out.String(", server: "); context.out.String(server);
  743. context.out.String(", port "); context.out.Int(port, 4);
  744. context.out.String(", path: "); context.out.String(path);
  745. context.out.String(", password: "); context.out.String(passwd);
  746. context.out.Ln;
  747. NEW(newVol, user, passwd, server, path, SHORT(port));
  748. newVol.Mount(errorcode);
  749. IF errorcode = REPLYOK THEN
  750. context.vol := newVol;
  751. context.out.String("Proxy->done");
  752. context.out.Ln;
  753. ELSE
  754. context.error.String("Proxy->Failure");
  755. context.error.Ln;
  756. END;
  757. END New;
  758. PROCEDURE GetResult(connection: RfsConnection.Connection; VAR errorcode, dataBytes, received: LONGINT; VAR buf: ARRAY OF CHAR);
  759. VAR res: WORD;
  760. BEGIN
  761. errorcode := ReadInteger(connection, res);
  762. IF res = Ok THEN
  763. dataBytes := ReadInteger(connection, res);
  764. IF res = Ok THEN
  765. connection.Receive(buf, 0, dataBytes, received, res);
  766. IF res = Ok THEN
  767. RETURN;
  768. END;
  769. END;
  770. END;
  771. errorcode := RECEIVERROR;
  772. END GetResult;
  773. (** An integer is filled into an array of character **)
  774. PROCEDURE Int2Char*(int: LONGINT; VAR buf: ARRAY OF CHAR; off: LONGINT);
  775. BEGIN
  776. (*
  777. buf[off + 0] := CHR(int MOD Block);
  778. int := int DIV Block;
  779. buf[off + 1] := CHR(int MOD Block);
  780. int := int DIV Block;
  781. buf[off + 2] := CHR(int MOD Block);
  782. int := int DIV Block;
  783. buf[off + 3] := CHR(int MOD Block);
  784. *)
  785. Network.PutNet4(buf, off, int);
  786. END Int2Char;
  787. (** four bytes of an array of characters are casted into an integer **)
  788. PROCEDURE Char2Int*(buf: ARRAY OF CHAR; off: LONGINT; VAR int: LONGINT);
  789. BEGIN
  790. int := Network.GetNet4(buf, off);
  791. END Char2Int;
  792. PROCEDURE ReadInteger*(connection: RfsConnection.Connection; VAR res: WORD): LONGINT;
  793. VAR val, received: LONGINT; buf: ARRAY 4 OF CHAR;
  794. BEGIN
  795. connection.Receive(buf, 0, 4, received, res);
  796. IF received # 4 THEN
  797. val := -1;
  798. res := PARAMERROR;
  799. ELSE
  800. Char2Int(buf, 0, val);
  801. END;
  802. RETURN val;
  803. END ReadInteger;
  804. PROCEDURE Len(x: ARRAY OF CHAR): LONGINT;
  805. VAR j: LONGINT;
  806. BEGIN
  807. j := 0;
  808. WHILE x[j] # 0X DO
  809. INC(j);
  810. END;
  811. RETURN j;
  812. END Len;
  813. (** Fast Buffer Copying. copy from offset offFrom len Bytes of Buffer bufFrom into bufTo at offset offTo **)
  814. PROCEDURE CopyBuffer*(VAR bufFrom: ARRAY OF CHAR; offFrom: LONGINT; VAR bufTo: ARRAY OF CHAR; offTo, len: LONGINT);
  815. BEGIN
  816. ASSERT(offTo + len <= LEN(bufTo));
  817. SYSTEM.MOVE(ADDRESSOF(bufFrom[offFrom]), ADDRESSOF(bufTo[offTo]), len);
  818. END CopyBuffer;
  819. END RfsClientProxy.