plptools
Loading...
Searching...
No Matches
rfsv32.cc
Go to the documentation of this file.
1/*
2 * This file is part of plptools.
3 *
4 * Copyright (C) 1999 Philip Proudman <philip.proudman@btinternet.com>
5 * Copyright (C) 1999-2001 Fritz Elfert <felfert@to.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * along with this program; if not, see <https://www.gnu.org/licenses/>.
19 *
20 */
21#include "config.h"
22
23#include "rfsv32.h"
24#include "bufferstore.h"
25#include "tcpsocket.h"
26#include "bufferarray.h"
27#include "plpdirent.h"
28
29#include <iostream>
30#include <fstream>
31
32#include <stdlib.h>
33#include <time.h>
34
35#include "ignore-value.h"
36
37using namespace std;
38
39RFSV32::RFSV32(std::unique_ptr<TCPSocket> socket) {
40 socket_ = std::move(socket);
41 operationId_ = 0;
43 reset();
44}
45
46Enum<RFSV::errs> RFSV32::fopen(uint32_t attr, const char *name, uint32_t &handle) {
48 string n = convertSlash(name);
49 a.addDWord(attr);
50 a.addWord(n.size());
51 a.addString(n.c_str());
52 if (!sendCommand(OPEN_FILE, a)) {
53 return E_PSI_FILE_DISC;
54 }
56 if (res == E_PSI_GEN_NONE && a.getLen() == 4) {
57 handle = a.getDWord(0);
58 return E_PSI_GEN_NONE;
59 }
60 return res;
61}
62
63Enum<RFSV::errs> RFSV32::mktemp(uint32_t &handle, string &tmpname) {
65 if (!sendCommand(TEMP_FILE, a)) {
66 return E_PSI_FILE_DISC;
67 }
69 if (res == E_PSI_GEN_NONE) {
70 handle = a.getDWord(0);
71 tmpname = a.getString(6);
72 }
73 return res;
74}
75
76Enum<RFSV::errs> RFSV32::fcreatefile(uint32_t attr, const char *name, uint32_t &handle) {
78 string n = convertSlash(name);
79 a.addDWord(attr);
80 a.addWord(n.size());
81 a.addString(n.c_str());
82 if (!sendCommand(CREATE_FILE, a)) {
83 return E_PSI_FILE_DISC;
84 }
86 if (res == E_PSI_GEN_NONE && a.getLen() == 4) {
87 handle = a.getDWord(0);
88 }
89 return res;
90}
91
92Enum<RFSV::errs> RFSV32:: freplacefile(const uint32_t attr, const char *const name, uint32_t &handle) {
94 string n = convertSlash(name);
95 a.addDWord(attr);
96 a.addWord(n.size());
97 a.addString(n.c_str());
98 if (!sendCommand(REPLACE_FILE, a)) {
99 return E_PSI_FILE_DISC;
100 }
102 if (res == E_PSI_GEN_NONE && a.getLen() == 4) {
103 handle = a.getDWord(0);
104 }
105 return res;
106}
107
108Enum<RFSV::errs> RFSV32::fopendir(const uint32_t attr, const char * const name, uint32_t &handle) {
110 string n = convertSlash(name);
111 a.addDWord(attr | EPOC_ATTR_GETUID);
112 a.addWord(n.size());
113 a.addString(n.c_str());
114 if (!sendCommand(OPEN_DIR, a)) {
115 return E_PSI_FILE_DISC;
116 }
118 if (!res && a.getLen() == 4) {
119 handle = a.getDWord(0);
120 }
121 return res;
122}
123
126 a.addDWord(handle);
127 if (!sendCommand(CLOSE_HANDLE, a)) {
128 return E_PSI_FILE_DISC;
129 }
130 return getResponse(a);
131}
132
133Enum<RFSV::errs> RFSV32::opendir(const uint32_t attr, const char *name, RFSVDirHandle &dH) {
134 uint32_t handle;
135 Enum<RFSV::errs> res = fopendir(std2attr(attr), name, handle);
136 dH.h = handle;
137 dH.b.init();
138 dH.name_ = name;
139 return res;
140}
141
143 return fclose(dH.h);
144}
145
148
149 if (dH.b.getLen() < 17) {
150 dH.b.init();
151 dH.b.addDWord(dH.h);
152 if (!sendCommand(READ_DIR, dH.b)) {
153 return E_PSI_FILE_DISC;
154 }
155 res = getResponse(dH.b);
156 }
157 if ((res == E_PSI_GEN_NONE) && (dH.b.getLen() > 16)) {
158 long shortLen = dH.b.getDWord(0);
159 long longLen = dH.b.getDWord(32);
160
161 e.attr = attr2std(dH.b.getDWord(4));
162 e.size = dH.b.getDWord(8);
163 e.UID = PlpUID(dH.b.getDWord(20), dH.b.getDWord(24), dH.b.getDWord(28));
164 e.time = PsiTime(dH.b.getDWord(16), dH.b.getDWord(12));
165 e.dirname_ = dH.name_;
166 e.name = "";
167 e.attrstr = string(attr2String(e.attr));
168
169 int d = 36;
170 for (int i = 0; i < longLen; i++, d++) {
171 e.name += dH.b.getByte(d);
172 }
173 while (d % 4) {
174 d++;
175 }
176 d += shortLen;
177 while (d % 4) {
178 d++;
179 }
180 dH.b.discardFirstBytes(d);
181 }
182 return res;
183}
184
185Enum<RFSV::errs> RFSV32::dir(const char *name, PlpDir &files) {
187 files.clear();
189 while (res == E_PSI_GEN_NONE) {
190 PlpDirent e;
191 res = readdir(h, e);
192 if (res == E_PSI_GEN_NONE) {
193 files.push_back(e);
194 }
195 }
196 closedir(h);
197 if (res == E_PSI_FILE_EOF) {
198 res = E_PSI_GEN_NONE;
199 }
200 return res;
201}
202
203uint32_t RFSV32::opMode(const uint32_t mode) {
204 uint32_t ret = 0;
205
206 ret |= (((mode & 03) == PSI_O_RDONLY) ? 0 : EPOC_OMODE_READ_WRITE);
207 if (!ret) {
208 ret |= (mode & PSI_O_EXCL) ? 0 : EPOC_OMODE_SHARE_READERS;
209 }
210 if ((!ret) && (mode & PSI_O_SHARE)) {
212 }
213 return ret;
214}
215
216Enum<RFSV::errs> RFSV32::fgetmtime(const char * const name, PsiTime &mtime) {
218 string n = convertSlash(name);
219 a.addWord(n.size());
220 a.addString(n.c_str());
221 if (!sendCommand(MODIFIED, a)) {
222 return E_PSI_FILE_DISC;
223 }
225 if (res != E_PSI_GEN_NONE) {
226 return res;
227 }
228 mtime.setPsiTime(a.getDWord(4), a.getDWord(0));
229 return res;
230}
231
232Enum<RFSV::errs> RFSV32::fsetmtime(const char * const name, PsiTime mtime) {
234 string n = convertSlash(name);
235 a.addDWord(mtime.getPsiTimeLo());
236 a.addDWord(mtime.getPsiTimeHi());
237 a.addWord(n.size());
238 a.addString(n.c_str());
239 if (!sendCommand(SET_MODIFIED, a)) {
240 return E_PSI_FILE_DISC;
241 }
242 return getResponse(a);
243}
244
245Enum<RFSV::errs> RFSV32::fgetattr(const char * const name, uint32_t &attr) {
247 string n = convertSlash(name);
248 a.addWord(n.size());
249 a.addString(n.c_str());
250 if (!sendCommand(ATT, a)) {
251 return E_PSI_FILE_DISC;
252 }
254 if (res != E_PSI_GEN_NONE) {
255 return res;
256 }
257 attr = attr2std(a.getDWord(0));
258 return res;
259}
260
261Enum<RFSV::errs> RFSV32::fgeteattr(const char * const name, PlpDirent &e) {
263 string n = convertSlash(name);
264 a.addWord(n.size());
265 a.addString(n.c_str());
266 const char *p = strrchr(n.c_str(), '\\');
267 if (p) {
268 p++;
269 } else {
270 p = n.c_str();
271 }
272 e.name = p;
273
275 return E_PSI_FILE_DISC;
277 if (res != E_PSI_GEN_NONE)
278 return res;
279 // long shortLen = a.getDWord(0);
280 // long longLen = a.getDWord(32);
281
282 e.attr = attr2std(a.getDWord(4));
283 e.size = a.getDWord(8);
284 e.UID = PlpUID(a.getDWord(20), a.getDWord(24), a.getDWord(28));
285 e.time = PsiTime(a.getDWord(16), a.getDWord(12));
286 e.attrstr = string(attr2String(e.attr));
287
288 return res;
289}
290
291Enum<RFSV::errs> RFSV32::fsetattr(const char * const name, const uint32_t seta, const uint32_t unseta) {
293 string n = convertSlash(name);
294 a.addDWord(std2attr(seta));
295 a.addDWord(std2attr(unseta));
296 a.addWord(n.size());
297 a.addString(n.c_str());
298 if (!sendCommand(SET_ATT, a)) {
299 return E_PSI_FILE_DISC;
300 }
301 return getResponse(a);
302}
303
304Enum<RFSV::errs> RFSV32::dircount(const char * const name, uint32_t &count) {
305 uint32_t handle;
307 count = 0;
308 if (res != E_PSI_GEN_NONE) {
309 return res;
310 }
311
312 while (1) {
314 a.addDWord(handle);
315 if (!sendCommand(READ_DIR, a)) {
316 return E_PSI_FILE_DISC;
317 }
318 res = getResponse(a);
319 if (res != E_PSI_GEN_NONE) {
320 break;
321 }
322 while (a.getLen() > 16) {
323 int d = 36 + a.getDWord(32);
324 while (d % 4) {
325 d++;
326 }
327 d += a.getDWord(0);
328 while (d % 4) {
329 d++;
330 }
331 a.discardFirstBytes(d);
332 count++;
333 }
334 }
335 fclose(handle);
336 if (res == E_PSI_FILE_EOF) {
337 res = E_PSI_GEN_NONE;
338 }
339 return res;
340}
341
345
347 return E_PSI_FILE_DISC;
348 }
349 res = getResponse(a);
350 devbits = 0;
351 if ((res == E_PSI_GEN_NONE) && (a.getLen() == 26)) {
352 for (int i = 25; i >= 0; i--) {
353 devbits <<= 1;
354 if (a.getByte(i) != 0) {
355 devbits |= 1;
356 }
357 }
358 }
359 return res;
360}
361
362Enum<RFSV::errs> RFSV32::devinfo(const char drive, Drive &dinfo) {
365
366 a.addDWord(toupper(drive) - 'A');
367 if (!sendCommand(DRIVE_INFO, a))
368 return E_PSI_FILE_DISC;
369 res = getResponse(a);
370 if (res == E_PSI_GEN_NONE) {
371 dinfo.setMediaType(static_cast<MediaType>(a.getDWord(0)));
372 dinfo.setDriveAttributes(a.getDWord(8));
373 dinfo.setMediaAttributes(a.getDWord(12));
374 dinfo.setUID(a.getDWord(16));
375 dinfo.setSize(a.getDWord(20), a.getDWord(24));
376 dinfo.setSpace(a.getDWord(28), a.getDWord(32));
377 a.addByte(0);
378 dinfo.setName(toupper(drive), a.getString(40));
379 }
380 return res;
381}
382
384 if (status_ == E_PSI_FILE_DISC) {
385 reconnect();
386 if (status_ == E_PSI_FILE_DISC) {
387 return false;
388 }
389 }
390 bool result;
392 a.addWord(cc);
393 a.addWord(operationId_);
394 if (operationId_ < 0xffff) {
395 operationId_++;
396 } else {
397 operationId_ = 0;
398 }
399 a.addBuff(data);
400 result = socket_->sendBufferStore(a);
401 if (!result) {
402 reconnect();
403 result = socket_->sendBufferStore(a);
404 if (!result) {
406 }
407 }
408 return result;
409}
410
412 if (socket_->getBufferStore(data) == 1 &&
413 data.getWord(0) == 0x11) {
414 int32_t ret = data.getDWord(4);
415 data.discardFirstBytes(8);
416 return err2psierr(ret);
417 } else {
419 }
420 return status_;
421}
422
423Enum<RFSV::errs> RFSV32::fread(const uint32_t handle, unsigned char * const buf, const uint32_t len, uint32_t &count) {
426 count = 0;
427 long l;
428 unsigned char *p = buf;
429
430 do {
431 a.addDWord(handle);
432 a.addDWord(((len - count) > RFSV_SENDLEN)?RFSV_SENDLEN:(len - count));
433 if (!sendCommand(READ_FILE, a)) {
434 return E_PSI_FILE_DISC;
435 }
436 if ((res = getResponse(a)) != E_PSI_GEN_NONE) {
437 return res;
438 }
439 if ((l = a.getLen()) > 0) {
440 memcpy(p, a.getString(), l);
441 count += l;
442 p += l;
443 }
444 a.init();
445 } while ((count < len) && (l > 0));
446 return res;
447}
448
449Enum<RFSV::errs> RFSV32::fwrite(const uint32_t handle,
450 const unsigned char *const buf,
451 const uint32_t len,
452 uint32_t &count) {
454 const unsigned char *p = buf;
455 long l;
456
457 count = 0;
458 do {
459 l = ((len - count) > RFSV_SENDLEN)?RFSV_SENDLEN:(len - count);
460 if (l > 0) {
462 BufferStore tmp(p, l);
463 a.addDWord(handle);
464 a.addBuff(tmp);
465 if (!sendCommand(WRITE_FILE, a)) {
466 return E_PSI_FILE_DISC;
467 }
468 if ((res = getResponse(a)) != E_PSI_GEN_NONE) {
469 return res;
470 }
471 count += l;
472 p += l;
473 }
474 } while ((count < len) && (l > 0));
475 return res;
476}
477
478Enum<RFSV::errs> RFSV32::copyFromPsion(const char *from, const char *to, void *ptr, cpCallback_t cb) {
480 uint32_t handle;
481 uint32_t len;
482 uint32_t total = 0;
483
484 if ((res = fopen(EPOC_OMODE_SHARE_READERS | EPOC_OMODE_BINARY, from, handle)) != E_PSI_GEN_NONE) {
485 return res;
486 }
487 ofstream op(to);
488 if (!op) {
489 fclose(handle);
490 return E_PSI_GEN_FAIL;
491 }
492 unsigned char *buff = new unsigned char[RFSV_SENDLEN];
493 do {
494 if ((res = fread(handle, buff, RFSV_SENDLEN, len)) == E_PSI_GEN_NONE) {
495 op.write((char *)buff, len);
496 total += len;
497 if (cb && !cb(ptr, total)) {
498 res = E_PSI_FILE_CANCEL;
499 }
500 }
501 } while ((len > 0) && (res == E_PSI_GEN_NONE));
502 delete [] buff;
503 fclose(handle);
504 op.close();
505 return res;
506}
507
510 uint32_t handle;
511 uint32_t len;
512 uint32_t total = 0;
513
514 if ((res = fopen(EPOC_OMODE_SHARE_READERS | EPOC_OMODE_BINARY, from, handle)) != E_PSI_GEN_NONE) {
515 return res;
516 }
517 unsigned char *buff = new unsigned char[RFSV_SENDLEN];
518 do {
519 if ((res = fread(handle, buff, RFSV_SENDLEN, len)) == E_PSI_GEN_NONE) {
520 // FIXME: return UNIX errors from this method.
521 ignore_value(write(fd, buff, len));
522 total += len;
523 if (cb && !cb(NULL, total)) {
524 res = E_PSI_FILE_CANCEL;
525 }
526 }
527 } while ((len > 0) && (res == E_PSI_GEN_NONE));
528 delete [] buff;
529 fclose(handle);
530 return res;
531}
532
533Enum<RFSV::errs> RFSV32::copyToPsion(const char *from, const char *to, void *ptr, cpCallback_t cb) {
534 uint32_t handle;
536
537 ifstream ip(from);
538 if (!ip) {
539 return E_PSI_FILE_NXIST;
540 }
542 if (res != E_PSI_GEN_NONE) {
544 if (res != E_PSI_GEN_NONE) {
545 return res;
546 }
547 }
548 unsigned char *buff = new unsigned char[RFSV_SENDLEN];
549 uint32_t total = 0;
550 while (ip && !ip.eof() && (res == E_PSI_GEN_NONE)) {
551 uint32_t len;
552 ip.read((char *)buff, RFSV_SENDLEN);
553 if ((res = fwrite(handle, buff, ip.gcount(), len)) == E_PSI_GEN_NONE) {
554 total += len;
555 if (cb && !cb(ptr, total)) {
556 res = E_PSI_FILE_CANCEL;
557 }
558 }
559 }
560 fclose(handle);
561 ip.close();
562 delete[]buff;
563 return res;
564}
565
566Enum<RFSV::errs> RFSV32::copyOnPsion(const char *from, const char *to, void *ptr, cpCallback_t cb) {
567 uint32_t handle_from;
568 uint32_t handle_to;
569 PlpDirent from_e;
571
572 if ((res = fgeteattr(from, from_e)) != E_PSI_GEN_NONE) {
573 return res;
574 }
575 if ((res = fopen(EPOC_OMODE_SHARE_READERS | EPOC_OMODE_BINARY, from, handle_from)) != E_PSI_GEN_NONE) {
576 return res;
577 }
579 if (res != E_PSI_GEN_NONE) {
581 if (res != E_PSI_GEN_NONE) {
582 fclose(handle_from);
583 return res;
584 }
585 }
586
587 uint32_t total = 0;
588 while (res == E_PSI_GEN_NONE) {
589 BufferStore b;
590 b.addDWord(RFSV_SENDLEN * 10);
591 b.addDWord(handle_to);
592 b.addDWord(handle_from);
593 if (!sendCommand(READ_WRITE_FILE, b)) {
594 return E_PSI_FILE_DISC;
595 }
596 res = getResponse(b);
597 if (res != E_PSI_GEN_NONE) {
598 break;
599 }
600 if (b.getLen() != 4) {
601 res = E_PSI_GEN_FAIL;
602 break;
603 }
604 uint32_t len = b.getDWord(0);
605 total += len;
606 if (cb && !cb(ptr, total)) {
607 res = E_PSI_FILE_CANCEL;
608 }
609 if (len != (RFSV_SENDLEN * 10)) {
610 break;
611 }
612 }
613 fclose(handle_from);
614 fclose(handle_to);
615 if (res != E_PSI_GEN_NONE) {
616 remove(to);
617 }
618 return res;
619}
620
621Enum<RFSV::errs> RFSV32::pathtest(const char * const name) {
623 string n = convertSlash(name);
624 a.addWord(n.size());
625 a.addString(n.c_str());
626 if (!sendCommand(PATH_TEST, a)) {
627 return E_PSI_FILE_DISC;
628 }
629 return getResponse(a);
630}
631
632Enum<RFSV::errs> RFSV32::fsetsize(uint32_t handle, uint32_t size) {
634 a.addDWord(handle);
635 a.addDWord(size);
636 if (!sendCommand(SET_SIZE, a)) {
637 return E_PSI_FILE_DISC;
638 }
639 return getResponse(a);
640}
641
642/*
643 * Unix-like implementation off fseek with one
644 * exception: If seeking beyond eof, the gap
645 * contains garbage instead of zeroes.
646 */
647Enum<RFSV::errs> RFSV32::fseek(const uint32_t handle, const int32_t pos, const uint32_t mode, uint32_t &resultpos) {
650 uint32_t savpos = 0;
651 uint32_t calcpos = 0;
652 int32_t mypos = pos;
653 uint32_t realpos;
654
655/*
656 seek-parameter for psion:
657 dword position
658 dword handle
659 dword mode
660 1 = from start
661 2 = from current pos
662 3 = from end
663 ??no more?? 4 = sense recpos
664 ??no more?? 5 = set recpos
665 ??no more?? 6 = text-rewind
666*/
667
668 if ((mode < PSI_SEEK_SET) || (mode > PSI_SEEK_END)) {
669 return E_PSI_GEN_ARG;
670 }
671
672 if ((mode == PSI_SEEK_CUR) && (mypos >= 0)) {
673 /* get and save current position */
674 a.addDWord(0);
675 a.addDWord(handle);
676 a.addDWord(PSI_SEEK_CUR);
677 if (!sendCommand(SEEK_FILE, a)) {
678 return E_PSI_FILE_DISC;
679 }
680 if ((res = getResponse(a)) != E_PSI_GEN_NONE) {
681 return res;
682 }
683 savpos = a.getDWord(0);
684 if (mypos == 0) {
685 resultpos = savpos;
686 return res;
687 }
688 a.init();
689 }
690 if ((mode == PSI_SEEK_END) && (mypos >= 0)) {
691 /* get and save end position */
692 a.addDWord(0);
693 a.addDWord(handle);
694 a.addDWord(PSI_SEEK_END);
695 if (!sendCommand(SEEK_FILE, a)) {
696 return E_PSI_FILE_DISC;
697 }
698 if ((res = getResponse(a)) != E_PSI_GEN_NONE) {
699 return res;
700 }
701 savpos = a.getDWord(0);
702 if (mypos == 0) {
703 resultpos = savpos;
704 return res;
705 }
706 /* Expand file */
707 a.init();
708 a.addDWord(handle);
709 a.addDWord(savpos + mypos);
710 if (!sendCommand(SET_SIZE, a)) {
711 return E_PSI_FILE_DISC;
712 }
713 if ((res = getResponse(a)) != E_PSI_GEN_NONE) {
714 return res;
715 }
716 mypos = 0;
717 a.init();
718 }
719 /* Now the real seek */
720 a.addDWord(mypos);
721 a.addDWord(handle);
722 a.addDWord(mode);
723 if (!sendCommand(SEEK_FILE, a)) {
724 return E_PSI_FILE_DISC;
725 }
726 if ((res = getResponse(a)) != E_PSI_GEN_NONE) {
727 return res;
728 }
729 realpos = a.getDWord(0);
730 switch (mode) {
731 case PSI_SEEK_SET:
732 calcpos = mypos;
733 break;
734 case PSI_SEEK_CUR:
735 calcpos = savpos + mypos;
736 break;
737 case PSI_SEEK_END:
738 resultpos = realpos;
739 return res;
740 break;
741 }
742 if (calcpos > realpos) {
743 /* Beyond end of file */
744 a.init();
745 a.addDWord(handle);
746 a.addDWord(calcpos);
747 if (!sendCommand(SET_SIZE, a)) {
748 return E_PSI_FILE_DISC;
749 }
750 if ((res = getResponse(a)) != E_PSI_GEN_NONE) {
751 return res;
752 }
753 a.addDWord(calcpos);
754 a.addDWord(handle);
755 a.addDWord(PSI_SEEK_SET);
756 if (!sendCommand(SEEK_FILE, a)) {
757 return E_PSI_FILE_DISC;
758 }
759 if ((res = getResponse(a)) != E_PSI_GEN_NONE) {
760 return res;
761 }
762 realpos = a.getDWord(0);
763 }
764 resultpos = realpos;
765 return res;
766}
767
770 string n = convertSlash(name);
771 if (n.find_last_of('\\') != (n.size() - 1)) {
772 n += '\\';
773 }
774 a.addWord(n.size());
775 a.addString(n.c_str());
776 if (!sendCommand(MK_DIR_ALL, a)) {
777 return E_PSI_FILE_DISC;
778 }
779 return getResponse(a);
780}
781
784 string n = convertSlash(name);
785 if (n.find_last_of('\\') != (n.size() - 1)) {
786 n += '\\';
787 }
788 a.addWord(n.size());
789 a.addString(n.c_str());
790 if (!sendCommand(RM_DIR, a)) {
791 return E_PSI_FILE_DISC;
792 }
793 return getResponse(a);
794}
795
796Enum<RFSV::errs> RFSV32::rename(const char *oldname, const char *newname) {
798 string on = convertSlash(oldname);
799 string nn = convertSlash(newname);
800 a.addWord(on.size());
801 a.addString(on.c_str());
802 a.addWord(nn.size());
803 a.addString(nn.c_str());
804 if (!sendCommand(RENAME, a)) {
805 return E_PSI_FILE_DISC;
806 }
807 return getResponse(a);
808}
809
812 string n = convertSlash(name);
813 a.addWord(n.size());
814 a.addString(n.c_str());
815 if (!sendCommand(DELETE, a)) {
816 return E_PSI_FILE_DISC;
817 }
818 return getResponse(a);
819}
820
821Enum<RFSV::errs> RFSV32::setVolumeName(const char drive , const char * const name) {
823 a.addDWord(toupper(drive) - 'A');
824 a.addWord(strlen(name));
825 a.addStringT(name);
827 return E_PSI_FILE_DISC;
828 }
829 return getResponse(a);
830}
831
832static enum RFSV::errs e2psi[] = {
877};
878
880 if ((istatus > E_EPOC_NONE) || (istatus < E_EPOC_DIR_FULL)) {
881 cerr << "FATAL: invalid error-code" << endl;
882 cerr << "status: " << istatus << " " << hex << istatus << endl;
883 return E_PSI_INTERNAL;
884 }
885 return e2psi[istatus - E_EPOC_DIR_FULL];
886}
887
888
889/*
890 * Translate EPOC attributes to standard attributes.
891 */
892uint32_t RFSV32::attr2std(const uint32_t attr) {
893 long res = 0;
894
895 // Common attributes
896 if (attr & EPOC_ATTR_RONLY) {
897 res |= PSI_A_RDONLY;
898 }
899 if (attr & EPOC_ATTR_HIDDEN) {
900 res |= PSI_A_HIDDEN;
901 }
902 if (attr & EPOC_ATTR_SYSTEM) {
903 res |= PSI_A_SYSTEM;
904 }
905 if (attr & EPOC_ATTR_DIRECTORY) {
906 res |= PSI_A_DIR;
907 }
908 if (attr & EPOC_ATTR_ARCHIVE) {
909 res |= PSI_A_ARCHIVE;
910 }
911 if (attr & EPOC_ATTR_VOLUME) {
912 res |= PSI_A_VOLUME;
913 }
914
915 // EPOC-specific
916 if (attr & EPOC_ATTR_NORMAL) {
917 res |= PSI_A_NORMAL;
918 }
919 if (attr & EPOC_ATTR_TEMPORARY) {
920 res |= PSI_A_TEMP;
921 }
922 if (attr & EPOC_ATTR_COMPRESSED) {
923 res |= PSI_A_COMPRESSED;
924 }
925
926 // Do what we can for SIBO
927 res |= PSI_A_READ;
928
929 return res;
930}
931
932/*
933 * Translate standard attributes to EPOC attributes.
934 */
935uint32_t RFSV32::std2attr(const uint32_t attr) {
936 long res = 0;
937 // Common attributes
938 if (attr & PSI_A_RDONLY) {
939 res |= EPOC_ATTR_RONLY;
940 }
941 if (attr & PSI_A_HIDDEN) {
942 res |= EPOC_ATTR_HIDDEN;
943 }
944 if (attr & PSI_A_SYSTEM) {
945 res |= EPOC_ATTR_SYSTEM;
946 }
947 if (attr & PSI_A_DIR) {
948 res |= EPOC_ATTR_DIRECTORY;
949 }
950 if (attr & PSI_A_ARCHIVE) {
951 res |= EPOC_ATTR_ARCHIVE;
952 }
953 if (attr & PSI_A_VOLUME) {
954 res |= EPOC_ATTR_VOLUME;
955 }
956
957 // EPOC-specific
958 if (attr & PSI_A_NORMAL) {
959 res |= EPOC_ATTR_NORMAL;
960 }
961 if (attr & PSI_A_TEMP) {
962 res |= EPOC_ATTR_TEMPORARY;
963 }
964 if (attr & PSI_A_COMPRESSED) {
966 }
967
968 return res;
969}
A generic container for an array of bytes.
Definition: bufferstore.h:36
uint16_t getWord(long pos=0) const
Retrieves the word at index pos.
Definition: bufferstore.cc:100
uint32_t getDWord(long pos=0) const
Retrieves the dword at index pos.
Definition: bufferstore.cc:104
void addDWord(long dw)
Appends a dword to the content of this instance.
Definition: bufferstore.cc:197
unsigned long getLen() const
Retrieves the length of a BufferStore.
Definition: bufferstore.cc:92
unsigned char getByte(long pos=0) const
Retrieves the byte at index pos.
Definition: bufferstore.cc:96
void discardFirstBytes(int len=0)
Removes bytes from the start of the buffer.
Definition: bufferstore.cc:141
void init()
Initializes the BufferStore.
Definition: bufferstore.cc:74
A class representing information about a Disk drive on the psion.
Definition: drive.h:51
void setSpace(uint32_t spaceLo, uint32_t spaceHi)
Definition: drive.cc:72
void setName(char drive, const char *const volname)
Definition: drive.cc:76
void setUID(uint32_t uid)
Definition: drive.cc:64
void setMediaType(MediaType type)
Definition: drive.cc:52
void setDriveAttributes(uint32_t driveAttribute)
Definition: drive.cc:56
void setMediaAttributes(uint32_t mediaAttribute)
Definition: drive.cc:60
void setSize(uint32_t sizeLo, uint32_t sizeHi)
Definition: drive.cc:68
Wrapper class featuring range-checking and string representation of enumerated values.
Definition: Enum.h:135
A class, representing a directory entry of the Psion.
Definition: plpdirent.h:79
std::string dirname_
Definition: plpdirent.h:199
std::string attrstr
Definition: plpdirent.h:198
PsiTime time
Definition: plpdirent.h:197
std::string name
Definition: plpdirent.h:200
PlpUID UID
Definition: plpdirent.h:196
uint32_t attr
Definition: plpdirent.h:195
uint32_t size
Definition: plpdirent.h:194
A class, representing the UIDs of a file on the Psion.
Definition: plpdirent.h:41
Psion time related utility class.
Definition: psitime.h:124
uint32_t getPsiTimeHi(void)
Retrieves the instance's current value in Psion time format, low 32 bits.
Definition: psitime.cc:144
uint32_t getPsiTimeLo(void)
Retrieves the instance's current value in Psion time format, high 32 bits.
Definition: psitime.cc:140
void setPsiTime(psi_timeval *_ptv)
Modifies the value of this instance.
Definition: psitime.cc:108
Enum< RFSV::errs > pathtest(const char *const)
Checks to see if the directory component of a path or file name exists and is valid.
Definition: rfsv32.cc:621
commands
Definition: rfsv32.h:148
@ CREATE_FILE
Definition: rfsv32.h:174
@ SET_ATT
Definition: rfsv32.h:167
@ DELETE
Definition: rfsv32.h:160
@ MK_DIR_ALL
Definition: rfsv32.h:165
@ SEEK_FILE
Definition: rfsv32.h:159
@ REMOTE_ENTRY
Definition: rfsv32.h:161
@ CLOSE_HANDLE
Definition: rfsv32.h:149
@ PATH_TEST
Definition: rfsv32.h:176
@ DRIVE_INFO
Definition: rfsv32.h:153
@ OPEN_FILE
Definition: rfsv32.h:155
@ READ_DIR
Definition: rfsv32.h:151
@ RM_DIR
Definition: rfsv32.h:166
@ WRITE_FILE
Definition: rfsv32.h:158
@ OPEN_DIR
Definition: rfsv32.h:150
@ READ_FILE
Definition: rfsv32.h:157
@ RENAME
Definition: rfsv32.h:164
@ REPLACE_FILE
Definition: rfsv32.h:175
@ SET_MODIFIED
Definition: rfsv32.h:169
@ SET_VOLUME_LABEL
Definition: rfsv32.h:154
@ ATT
Definition: rfsv32.h:168
@ SET_SIZE
Definition: rfsv32.h:163
@ READ_WRITE_FILE
Definition: rfsv32.h:173
@ MODIFIED
Definition: rfsv32.h:170
@ GET_DRIVE_LIST
Definition: rfsv32.h:152
@ TEMP_FILE
Definition: rfsv32.h:156
Enum< RFSV::errs > getResponse(BufferStore &)
Definition: rfsv32.cc:411
Enum< RFSV::errs > fcreatefile(const uint32_t, const char *const, uint32_t &)
Creates a named file.
Definition: rfsv32.cc:76
Enum< RFSV::errs > mktemp(uint32_t &, std::string &)
Creates a unique temporary file.
Definition: rfsv32.cc:63
Enum< RFSV::errs > devinfo(const char, Drive &)
Retrieves details about a drive.
Definition: rfsv32.cc:362
Enum< RFSV::errs > fseek(const uint32_t, const int32_t, const uint32_t, uint32_t &)
Sets the current file position of a file on the Psion.
Definition: rfsv32.cc:647
Enum< RFSV::errs > devlist(uint32_t &)
Retrieves available drives on the Psion.
Definition: rfsv32.cc:342
Enum< RFSV::errs > fgetattr(const char *const, uint32_t &)
Retrieves attributes of a file on the Psion.
Definition: rfsv32.cc:245
uint32_t attr2std(const uint32_t)
Definition: rfsv32.cc:892
Enum< RFSV::errs > mkdir(const char *const)
Creates a directory on the Psion.
Definition: rfsv32.cc:768
Enum< RFSV::errs > fread(const uint32_t, unsigned char *const, const uint32_t, uint32_t &)
Reads from a file on the Psion.
Definition: rfsv32.cc:423
Enum< RFSV::errs > fwrite(const uint32_t, const unsigned char *const, const uint32_t, uint32_t &)
Write to a file on the Psion.
Definition: rfsv32.cc:449
Enum< RFSV::errs > setVolumeName(const char, const char *const)
Set the name of a Psion Volume (Drive).
Definition: rfsv32.cc:821
uint32_t opMode(const uint32_t)
Converts an open-mode (A combination of the PSI_O_ constants.) from generic representation to the mac...
Definition: rfsv32.cc:203
bool sendCommand(enum commands, BufferStore &)
Definition: rfsv32.cc:383
Enum< RFSV::errs > rmdir(const char *const)
Removes a directory on the Psion.
Definition: rfsv32.cc:782
@ E_EPOC_NONE
Definition: rfsv32.h:102
@ E_EPOC_DIR_FULL
Definition: rfsv32.h:145
Enum< RFSV::errs > err2psierr(int32_t)
Definition: rfsv32.cc:879
Enum< RFSV::errs > fopen(const uint32_t, const char *const, uint32_t &)
Opens a file.
Definition: rfsv32.cc:46
Enum< RFSV::errs > closedir(RFSVDirHandle &)
Close a directory, previously opened with opendir.
Definition: rfsv32.cc:142
Enum< RFSV::errs > fclose(const uint32_t)
Close a file on the Psion whih was previously opened/created by using fopen , fcreatefile ,...
Definition: rfsv32.cc:124
Enum< RFSV::errs > fopendir(const uint32_t, const char *, uint32_t &)
Definition: rfsv32.cc:108
Enum< RFSV::errs > fsetsize(uint32_t, uint32_t)
Resizes an open file on the Psion.
Definition: rfsv32.cc:632
Enum< RFSV::errs > remove(const char *const)
Removes a file on the Psion.
Definition: rfsv32.cc:810
Enum< RFSV::errs > opendir(const uint32_t, const char *const, RFSVDirHandle &)
Open a directory for reading with readdir.
Definition: rfsv32.cc:133
Enum< RFSV::errs > fsetmtime(const char *const, PsiTime const)
Sets the modification time of a file on the Psion.
Definition: rfsv32.cc:232
Enum< RFSV::errs > fgeteattr(const char *const, PlpDirent &)
Retrieves attributes, size and modification time of a file on the Psion.
Definition: rfsv32.cc:261
Enum< RFSV::errs > readdir(RFSVDirHandle &, PlpDirent &)
Read directory entries.
Definition: rfsv32.cc:146
Enum< RFSV::errs > freplacefile(const uint32_t, const char *const, uint32_t &)
Creates an named file, overwriting an existing file.
Definition: rfsv32.cc:92
Enum< RFSV::errs > rename(const char *const, const char *const)
Renames a file on the Psion.
Definition: rfsv32.cc:796
Enum< RFSV::errs > copyFromPsion(const char *const, const char *const, void *, cpCallback_t)
Copies a file from the Psion to the local machine.
Definition: rfsv32.cc:478
Enum< RFSV::errs > dircount(const char *const, uint32_t &)
Counts number of entries in a directory.
Definition: rfsv32.cc:304
uint32_t std2attr(const uint32_t)
Definition: rfsv32.cc:935
Enum< RFSV::errs > copyToPsion(const char *const, const char *const, void *, cpCallback_t)
Copies a file from local machine to the Psion.
Definition: rfsv32.cc:533
Enum< RFSV::errs > dir(const char *const, PlpDir &)
Reads a directory on the Psion.
Definition: rfsv32.cc:185
@ EPOC_ATTR_RONLY
Definition: rfsv32.h:79
@ EPOC_ATTR_DIRECTORY
Definition: rfsv32.h:82
@ EPOC_ATTR_COMPRESSED
Definition: rfsv32.h:87
@ EPOC_ATTR_ARCHIVE
Definition: rfsv32.h:83
@ EPOC_ATTR_NORMAL
Definition: rfsv32.h:85
@ EPOC_ATTR_VOLUME
Definition: rfsv32.h:84
@ EPOC_ATTR_GETUID
Definition: rfsv32.h:89
@ EPOC_ATTR_HIDDEN
Definition: rfsv32.h:80
@ EPOC_ATTR_SYSTEM
Definition: rfsv32.h:81
@ EPOC_ATTR_TEMPORARY
Definition: rfsv32.h:86
Enum< RFSV::errs > fgetmtime(const char *const, PsiTime &)
Retrieves the modification time of a file on the Psion.
Definition: rfsv32.cc:216
Enum< RFSV::errs > fsetattr(const char *const, const uint32_t, const uint32_t)
Definition: rfsv32.cc:291
RFSV32(std::unique_ptr< TCPSocket > socket)
Definition: rfsv32.cc:39
@ EPOC_OMODE_SHARE_EXCLUSIVE
Definition: rfsv32.h:93
@ EPOC_OMODE_BINARY
Definition: rfsv32.h:96
@ EPOC_OMODE_READ_WRITE
Definition: rfsv32.h:98
@ EPOC_OMODE_SHARE_ANY
Definition: rfsv32.h:95
@ EPOC_OMODE_SHARE_READERS
Definition: rfsv32.h:94
Enum< RFSV::errs > copyOnPsion(const char *const, const char *const, void *, cpCallback_t)
Copies a file from the Psion to the Psion.
Definition: rfsv32.cc:566
A helper class for storing intermediate internal information in RFSV16 and RFSV32 .
Definition: rfsv.h:56
uint32_t h
Definition: rfsv.h:61
BufferStore b
Definition: rfsv.h:62
std::string name_
Definition: rfsv.h:63
@ PSI_O_RDONLY
Definition: rfsv.h:94
std::string attr2String(const uint32_t attr)
Converts a file attribute RFSV::file_attribs to human readable format, usable for showing them in dir...
Definition: rfsv.cc:156
@ PSI_SEEK_SET
Definition: rfsv.h:85
@ PSI_SEEK_END
Definition: rfsv.h:87
@ PSI_SEEK_CUR
Definition: rfsv.h:86
Enum< errs > status_
Definition: rfsv.h:661
void reset()
Definition: rfsv.cc:133
void reconnect()
Definition: rfsv.cc:127
std::unique_ptr< TCPSocket > socket_
Definition: rfsv.h:660
int32_t operationId_
Definition: rfsv.h:662
static std::string convertSlash(const std::string &name)
Utility method, converts '/' to '\'.
Definition: rfsv.cc:149
errs
The known error codes.
Definition: rfsv.h:113
@ E_PSI_GEN_POWER
Definition: rfsv.h:176
@ E_PSI_GEN_ARG
Definition: rfsv.h:116
@ E_PSI_FILE_TOOBIG
Definition: rfsv.h:177
@ E_PSI_FILE_ACCESS
Definition: rfsv.h:145
@ E_PSI_GEN_BUSY
Definition: rfsv.h:183
@ E_PSI_FILE_DIR
Definition: rfsv.h:148
@ E_PSI_GEN_DIED
Definition: rfsv.h:185
@ E_PSI_GEN_FSYS
Definition: rfsv.h:133
@ E_PSI_FILE_WRITE
Definition: rfsv.h:140
@ E_PSI_GEN_INUSE
Definition: rfsv.h:123
@ E_PSI_FILE_RETRAN
Definition: rfsv.h:158
@ E_PSI_GEN_UNDER
Definition: rfsv.h:119
@ E_PSI_GEN_FAIL
Definition: rfsv.h:115
@ E_PSI_GEN_NSUP
Definition: rfsv.h:118
@ E_PSI_GEN_TERMINATED
Definition: rfsv.h:184
@ E_PSI_FILE_FULL
Definition: rfsv.h:143
@ E_PSI_FILE_NDISC
Definition: rfsv.h:180
@ E_PSI_FILE_EXIST
Definition: rfsv.h:138
@ E_PSI_GEN_NOMEMORY
Definition: rfsv.h:124
@ E_PSI_GEN_DIVIDE
Definition: rfsv.h:122
@ E_PSI_FILE_CONNECT
Definition: rfsv.h:157
@ E_PSI_FILE_CORRUPT
Definition: rfsv.h:172
@ E_PSI_FILE_DISC
Definition: rfsv.h:156
@ E_PSI_FILE_CANCEL
Definition: rfsv.h:154
@ E_PSI_FILE_HANDLE
Definition: rfsv.h:186
@ E_PSI_FILE_NXIST
Definition: rfsv.h:139
@ E_PSI_FILE_NOTREADY
Definition: rfsv.h:168
@ E_PSI_FILE_LINE
Definition: rfsv.h:159
@ E_PSI_FILE_OVERRUN
Definition: rfsv.h:163
@ E_PSI_FILE_PARITY
Definition: rfsv.h:161
@ E_PSI_FILE_FRAME
Definition: rfsv.h:162
@ E_PSI_FILE_NAME
Definition: rfsv.h:144
@ E_PSI_GEN_NONE
Definition: rfsv.h:114
@ E_PSI_FILE_ABORT
Definition: rfsv.h:173
@ E_PSI_GEN_DESCR
Definition: rfsv.h:178
@ E_PSI_INTERNAL
Definition: rfsv.h:191
@ E_PSI_FILE_LOCKED
Definition: rfsv.h:146
@ E_PSI_FILE_DIRFULL
Definition: rfsv.h:170
@ E_PSI_FILE_COMPLETION
Definition: rfsv.h:182
@ E_PSI_GEN_RANGE
Definition: rfsv.h:121
@ E_PSI_FILE_DRIVER
Definition: rfsv.h:181
@ E_PSI_GEN_LIB
Definition: rfsv.h:179
@ E_PSI_FILE_EOF
Definition: rfsv.h:142
@ E_PSI_GEN_OVER
Definition: rfsv.h:120
@ E_PSI_FILE_UNKNOWN
Definition: rfsv.h:169
@ PSI_A_NORMAL
Attributes, valid on EPOC only.
Definition: rfsv.h:207
@ PSI_A_ARCHIVE
Definition: rfsv.h:203
@ PSI_A_DIR
Definition: rfsv.h:202
@ PSI_A_HIDDEN
Definition: rfsv.h:200
@ PSI_A_COMPRESSED
Definition: rfsv.h:209
@ PSI_A_READ
Attributes, valid on SIBO only.
Definition: rfsv.h:212
@ PSI_A_VOLUME
Definition: rfsv.h:204
@ PSI_A_RDONLY
Attributes, valid on both EPOC and SIBO.
Definition: rfsv.h:199
@ PSI_A_TEMP
Definition: rfsv.h:208
@ PSI_A_SYSTEM
Definition: rfsv.h:201
@ PSI_O_EXCL
Definition: rfsv.h:104
@ PSI_O_SHARE
Definition: rfsv.h:107
MediaType
Definition: drive.h:31
Definition: doctest.h:522
static RFSV * a
Definition: main.cc:55
static enum RFSV::errs e2psi[]
Definition: rfsv32.cc:832
int(* cpCallback_t)(void *, uint32_t)
Defines the callback procedure for progress indication of copy operations.
Definition: rfsv.h:45
std::deque< class PlpDirent > PlpDir
Definition: rfsv.h:34
const int RFSV_SENDLEN
Definition: rfsv.h:39