From 85e5a0f25d083eb74764e674361ddf49c410c14d Mon Sep 17 00:00:00 2001 From: Fritz Elfert Date: Wed, 31 Jan 2001 02:15:23 +0000 Subject: Misc changes, needed for kioslave and backup: - Added copyOnPsion to optimize speed of copying files from Psion to Psion. - Added a void pointer to the callback function of copy{To,From,On}Psion. This permits setting up a C callback function from within a C++ method by providing this-> in that arg. In the C callback function, the apropriate method of the foreign class can then be called. - Added opendir(), readdir(), closedir() in a libc-like fashion. - Removed old time code. - Added setVolumeName() --- lib/rfsv.h | 43 ++++++++++--- lib/rfsv16.cc | 119 +++++++++++++++++++++++++++++++++-- lib/rfsv16.h | 9 ++- lib/rfsv32.cc | 194 ++++++++++++++++++++++++++++++++++++++++------------------ lib/rfsv32.h | 22 +++---- 5 files changed, 301 insertions(+), 86 deletions(-) (limited to 'lib') diff --git a/lib/rfsv.h b/lib/rfsv.h index a1241d6..99adcab 100644 --- a/lib/rfsv.h +++ b/lib/rfsv.h @@ -3,9 +3,9 @@ #include "Enum.h" #include "psitime.h" +#include "bufferstore.h" class ppsocket; -class bufferStore; class bufferArray; const long RFSV_SENDLEN = 2000; @@ -14,7 +14,13 @@ const long RFSV_SENDLEN = 2000; * Defines the callback procedure for * progress indication of copy operations. */ -typedef int (*cpCallback_t)(long); +typedef int (*cpCallback_t)(void *, long); + +class rfsvDirhandle { + public: + unsigned long h; + bufferStore b; +}; /** * Access remote file services of a Psion. @@ -44,18 +50,18 @@ class rfsv { * The known modes for file open. */ enum open_flags { - PSI_O_RDONLY = 00, - PSI_O_WRONLY = 01, - PSI_O_RDWR = 02, + PSI_O_RDONLY = 0000, + PSI_O_WRONLY = 0001, + PSI_O_RDWR = 0002, }; /** * The known modes for file creation. */ enum open_mode { - PSI_O_CREAT = 0100, - PSI_O_EXCL = 0200, - PSI_O_TRUNC = 01000, + PSI_O_CREAT = 00100, + PSI_O_EXCL = 00200, + PSI_O_TRUNC = 01000, PSI_O_APPEND = 02000, }; @@ -330,7 +336,7 @@ class rfsv { * * @returns A Psion error code (One of enum @ref #errs ). */ - virtual Enum copyFromPsion(const char *from, const char *to, cpCallback_t func) = 0; + virtual Enum copyFromPsion(const char *from, const char *to, void *, cpCallback_t func) = 0; /** * Copies a file from local machine to the Psion. @@ -343,8 +349,20 @@ class rfsv { * * @returns A Psion error code (One of enum @ref #errs ). */ - virtual Enum copyToPsion(const char * const from, const char * const to, cpCallback_t func) = 0; + virtual Enum copyToPsion(const char * const from, const char * const to, void *, cpCallback_t func) = 0; + /** + * Copies a file from the Psion to the Psion. + * + * @param from Name of the file to be copied. + * @param to Name of the destination file. + * @param func Pointer to a function which gets called on every read. + * This function can be used to show some progress etc. May be set + * to NULL, where no callback is performed. + * + * @returns A Psion error code (One of enum @ref #errs ). + */ + virtual Enum copyOnPsion(const char * const from, const char * const to, void *, cpCallback_t func) = 0; /** * Resizes an open file on the Psion. * If the new size is greater than the file's @@ -408,6 +426,11 @@ class rfsv { */ virtual Enum remove(const char * const name) = 0; + virtual Enum opendir(const long attr, const char * const name, rfsvDirhandle &handle) = 0; + virtual Enum readdir(rfsvDirhandle &handle, bufferStore &buff) = 0; + virtual Enum closedir(rfsvDirhandle &handle) = 0; + virtual Enum setVolumeName(const char drive, const char * const name) = 0; + /** * Converts a file attribute @ref rfsv::file_attribs to * human readable format, usable for showing them in directory diff --git a/lib/rfsv16.cc b/lib/rfsv16.cc index 97dcdbc..fdec2e7 100644 --- a/lib/rfsv16.cc +++ b/lib/rfsv16.cc @@ -166,6 +166,72 @@ fclose(long fileHandle) return getResponse(a); } +Enum rfsv16:: +opendir(const long attr, const char *name, rfsvDirhandle &dH) { + long handle; + Enum res = fopendir(name, handle); + dH.h = handle; + dH.b.init(); + return res; +} + +Enum rfsv16:: +closedir(rfsvDirhandle &dH) { + return fclose(dH.h); +} + +Enum rfsv16:: +readdir(rfsvDirhandle &dH, bufferStore &s) { + Enum res = E_PSI_GEN_NONE; + + if (dH.b.getLen() < 17) { + dH.b.init(); + dH.b.addWord(dH.h & 0xFFFF); + if (!sendCommand(FDIRREAD, dH.b)) + return E_PSI_FILE_DISC; + res = getResponse(dH.b); + dH.b.discardFirstBytes(2); // Don't know what these mean! + } + if ((res == E_PSI_GEN_NONE) && (dH.b.getLen() > 16)) { + int version = dH.b.getWord(0); + if (version != 2) { + cerr << "dir: not version 2" << endl; + return E_PSI_GEN_FAIL; + } + long attr = attr2std((long)dH.b.getWord(2)); + long size = dH.b.getDWord(4); + PsiTime *date = new PsiTime((time_t)dH.b.getDWord(8)); + const char *name = dH.b.getString(16); + + dH.b.discardFirstBytes(17+strlen(name)); + + s.init(); + s.addDWord((unsigned long)date); + s.addDWord(size); + s.addDWord(attr); + s.addStringT(name); + } + return res; +} + +Enum rfsv16:: +dir(const char *name, bufferArray &files) +{ + rfsvDirhandle h; + Enum res = opendir(PSI_A_HIDDEN | PSI_A_SYSTEM | PSI_A_DIR, name, h); + while (res == E_PSI_GEN_NONE) { + bufferStore b; + res = readdir(h, b); + if (res == E_PSI_GEN_NONE) + files += b; + } + closedir(h); + if (res == E_PSI_FILE_EOF) + res = E_PSI_GEN_NONE; + return res; +} + +#if 0 Enum rfsv16:: dir(const char * const dirName, bufferArray &files) { @@ -210,6 +276,7 @@ dir(const char * const dirName, bufferArray &files) fclose(fileHandle); return res; } +#endif long rfsv16:: opMode(long mode) @@ -622,7 +689,7 @@ fwrite(const long handle, const unsigned char * const buf, const long len, long } Enum rfsv16:: -copyFromPsion(const char *from, const char *to, cpCallback_t cb) +copyFromPsion(const char *from, const char *to, void *ptr, cpCallback_t cb) { long handle; Enum res; @@ -642,7 +709,7 @@ copyFromPsion(const char *from, const char *to, cpCallback_t cb) if (len > 0) op.write(buf, len); total += len; - if (cb && !cb(total)) + if (cb && !cb(ptr, total)) res = E_PSI_FILE_CANCEL; } } while (len > 0 && (res == E_PSI_GEN_NONE)); @@ -655,7 +722,7 @@ copyFromPsion(const char *from, const char *to, cpCallback_t cb) } Enum rfsv16:: -copyToPsion(const char *from, const char *to, cpCallback_t cb) +copyToPsion(const char *from, const char *to, void *ptr, cpCallback_t cb) { long handle; long len = 0; @@ -676,7 +743,7 @@ copyToPsion(const char *from, const char *to, cpCallback_t cb) ip.read(buff, RFSV_SENDLEN); if ((res = fwrite(handle, buff, ip.gcount(), len)) == E_PSI_GEN_NONE) { total += len; - if (cb && !cb(total)) + if (cb && !cb(ptr, total)) res = E_PSI_FILE_CANCEL; } } @@ -686,6 +753,43 @@ copyToPsion(const char *from, const char *to, cpCallback_t cb) return res; } +Enum rfsv16:: +copyOnPsion(const char *from, const char *to, void *ptr, cpCallback_t cb) +{ + long handle_from; + long handle_to; + long len; + long wlen; + long total = 0; + Enum res; + + if ((res = fopen(P_FSHARE | P_FSTREAM, from, handle_from)) != E_PSI_GEN_NONE) + return res; + res = fcreatefile(P_FSTREAM | P_FUPDATE, to, handle_to); + if (res != E_PSI_GEN_NONE) { + res = freplacefile(P_FSTREAM | P_FUPDATE, to, handle_to); + if (res != E_PSI_GEN_NONE) + return res; + } + do { + unsigned char buf[RFSV_SENDLEN]; + if ((res = fread(handle_from, buf, sizeof(buf), len)) == E_PSI_GEN_NONE) { + if (len > 0) { + if ((res = fwrite(handle_to, buf, len, wlen)) == E_PSI_GEN_NONE) { + total += wlen; + if (cb && !cb(ptr, total)) + res = E_PSI_FILE_CANCEL; + } + } + } + } while (len > 0 && wlen > 0 && (res == E_PSI_GEN_NONE)); + fclose(handle_from); + fclose(handle_to); + if (res == E_PSI_FILE_EOF) + res = E_PSI_GEN_NONE; + return res; +} + Enum rfsv16:: fsetsize(long handle, long size) { @@ -874,6 +978,13 @@ remove(const char* psionName) return E_PSI_GEN_FAIL; } +Enum rfsv16:: +setVolumeName(const char drive , const char * const name) +{ +// Not yet ... + return E_PSI_GEN_FAIL; +} + /* * Translate SIBO attributes to standard attributes. */ diff --git a/lib/rfsv16.h b/lib/rfsv16.h index 73c4983..852d816 100644 --- a/lib/rfsv16.h +++ b/lib/rfsv16.h @@ -23,14 +23,19 @@ public: Enum devinfo(const int, long &, long &, long &, long &, char * const); Enum fread(const long, unsigned char * const, const long, long &); Enum fwrite(const long, const unsigned char * const, const long, long &); - Enum copyFromPsion(const char * const, const char * const, cpCallback_t); - Enum copyToPsion(const char * const, const char * const, cpCallback_t); + Enum copyFromPsion(const char * const, const char * const, void *, cpCallback_t); + Enum copyToPsion(const char * const, const char * const, void *, cpCallback_t); + Enum copyOnPsion(const char *, const char *, void *, cpCallback_t); Enum fsetsize(const long, const long); Enum fseek(const long, const long, const long, long &); Enum mkdir(const char * const); Enum rmdir(const char * const); Enum rename(const char * const, const char * const); Enum remove(const char * const); + Enum opendir(const long, const char * const, rfsvDirhandle &); + Enum readdir(rfsvDirhandle &, bufferStore &); + Enum closedir(rfsvDirhandle &); + Enum setVolumeName(const char, const char * const); long opMode(const long); diff --git a/lib/rfsv32.cc b/lib/rfsv32.cc index c654228..5a23c08 100644 --- a/lib/rfsv32.cc +++ b/lib/rfsv32.cc @@ -148,66 +148,75 @@ fclose(long handle) return getResponse(a); } -#if 0 -/* Microseconds since 1.1.1980 00:00:00 */ -#define PSI_EPOCH_SECS8 0x0e8c52f4 -#define EPOCH_2H 7200 -#define EPOCH_DIFF_SECS (3652 * 24 * 60 * 60) - -unsigned long rfsv32:: -micro2time(unsigned long microHi, unsigned long microLo) -{ - unsigned long long micro = microHi; - unsigned long long pes = PSI_EPOCH_SECS8; - pes <<= 8; - micro <<= 32; - micro += microLo; - micro /= 1000000; - micro -= pes; - micro += EPOCH_DIFF_SECS; - - /* Adjust for timezone and daylight saving time */ - { - struct tm *t; - long date=micro; - - t = localtime(&date); - micro += timezone; /* Adjust for timezone */ - if (t->tm_isdst) micro -= (60*60); /* Adjust for DST */ - } - - return (long) micro; -} - -void rfsv32:: -time2micro(unsigned long time, unsigned long µHi, unsigned long µLo) -{ - unsigned long long micro = (unsigned long long)time; - unsigned long long pes = PSI_EPOCH_SECS8; - pes <<= 8; - micro += pes; - micro -= EPOCH_DIFF_SECS; - - /* Adjust for timezone and daylight saving time */ - { - struct tm *t; - long date=time; - - t = localtime(&date); - micro -= timezone; /* Adjust for timezone */ - if (t->tm_isdst) micro += (60*60); /* Adjust for DST */ - } - - micro *= (unsigned long long)1000000; - microLo = (micro & (unsigned long long)0x0FFFFFFFF); - micro >>= 32; - microHi = (micro & (unsigned long long)0x0FFFFFFFF); +Enum rfsv32:: +opendir(const long attr, const char *name, rfsvDirhandle &dH) { + long handle; + Enum res = fopendir(std2attr(attr), name, handle); + dH.h = handle; + dH.b.init(); + return res; +} + +Enum rfsv32:: +closedir(rfsvDirhandle &dH) { + return fclose(dH.h); +} + +Enum rfsv32:: +readdir(rfsvDirhandle &dH, bufferStore &s) { + Enum res = E_PSI_GEN_NONE; + + if (dH.b.getLen() < 17) { + dH.b.init(); + dH.b.addDWord(dH.h); + if (!sendCommand(READ_DIR, dH.b)) + return E_PSI_FILE_DISC; + res = getResponse(dH.b); + } + if ((res == E_PSI_GEN_NONE) && (dH.b.getLen() > 16)) { + long shortLen = dH.b.getDWord(0); + long attributes = attr2std(dH.b.getDWord(4)); + long size = dH.b.getDWord(8); + // long uid1 = dH.b.getDWord(20); + // long uid2 = dH.b.getDWord(24); + // long uid3 = dH.b.getDWord(28); + long longLen = dH.b.getDWord(32); + PsiTime *date = new PsiTime(dH.b.getDWord(16), dH.b.getDWord(12)); + + s.init(); + s.addDWord((unsigned long)date); + s.addDWord(size); + s.addDWord(attributes); + int d = 36; + for (int i = 0; i < longLen; i++, d++) + s.addByte(dH.b.getByte(d)); + s.addByte(0); + while (d % 4) + d++; + d += shortLen; + while (d % 4) + d++; + dH.b.discardFirstBytes(d); + } + return res; } -#endif Enum rfsv32:: dir(const char *name, bufferArray &files) { + rfsvDirhandle h; + Enum res = opendir(PSI_A_HIDDEN | PSI_A_SYSTEM | PSI_A_DIR, name, h); + while (res == E_PSI_GEN_NONE) { + bufferStore b; + res = readdir(h, b); + if (res == E_PSI_GEN_NONE) + files += b; + } + closedir(h); + if (res == E_PSI_FILE_EOF) + res = E_PSI_GEN_NONE; + return res; +#if 0 long handle; Enum res = fopendir(EPOC_ATTR_HIDDEN | EPOC_ATTR_SYSTEM | EPOC_ATTR_DIRECTORY, name, handle); if (res != E_PSI_GEN_NONE) @@ -256,6 +265,7 @@ dir(const char *name, bufferArray &files) res = E_PSI_GEN_NONE; fclose(handle); return res; +#endif } long rfsv32:: @@ -532,7 +542,7 @@ fwrite(const long handle, const unsigned char * const buf, const long len, long } Enum rfsv32:: -copyFromPsion(const char *from, const char *to, cpCallback_t cb) +copyFromPsion(const char *from, const char *to, void *ptr, cpCallback_t cb) { long handle; Enum res; @@ -551,7 +561,7 @@ copyFromPsion(const char *from, const char *to, cpCallback_t cb) if ((res = fread(handle, buff, RFSV_SENDLEN, len)) == E_PSI_GEN_NONE) { op.write(buff, len); total += len; - if (cb && !cb(total)) + if (cb && !cb(ptr, total)) res = E_PSI_FILE_CANCEL; } } while ((len > 0) && (res == E_PSI_GEN_NONE)); @@ -562,7 +572,7 @@ copyFromPsion(const char *from, const char *to, cpCallback_t cb) } Enum rfsv32:: -copyToPsion(const char *from, const char *to, cpCallback_t cb) +copyToPsion(const char *from, const char *to, void *ptr, cpCallback_t cb) { long handle; Enum res; @@ -583,7 +593,7 @@ copyToPsion(const char *from, const char *to, cpCallback_t cb) ip.read(buff, RFSV_SENDLEN); if ((res = fwrite(handle, buff, ip.gcount(), len)) == E_PSI_GEN_NONE) { total += len; - if (cb && !cb(total)) + if (cb && !cb(ptr, total)) res = E_PSI_FILE_CANCEL; } } @@ -593,6 +603,60 @@ copyToPsion(const char *from, const char *to, cpCallback_t cb) return res; } +Enum rfsv32:: +copyOnPsion(const char *from, const char *to, void *ptr, cpCallback_t cb) +{ + long handle_from; + long handle_to; + long attr; + long from_size; + long to_size; + PsiTime time; + Enum res; + + if ((res = fgeteattr(from, attr, from_size, time)) != E_PSI_GEN_NONE) + return res; + if ((res = fopen(EPOC_OMODE_SHARE_READERS | EPOC_OMODE_BINARY, from, handle_from)) + != E_PSI_GEN_NONE) + return res; + res = fcreatefile(EPOC_OMODE_BINARY | EPOC_OMODE_SHARE_EXCLUSIVE | EPOC_OMODE_READ_WRITE, to, handle_to); + if (res != E_PSI_GEN_NONE) { + res = freplacefile(EPOC_OMODE_BINARY | EPOC_OMODE_SHARE_EXCLUSIVE | EPOC_OMODE_READ_WRITE, to, handle_to); + if (res != E_PSI_GEN_NONE) { + fclose(handle_from); + return res; + } + } + + long total = 0; + while (res == E_PSI_GEN_NONE) { + bufferStore b; + b.addDWord(RFSV_SENDLEN * 10); + b.addDWord(handle_to); + b.addDWord(handle_from); + if (!sendCommand(READ_WRITE_FILE, b)) + return E_PSI_FILE_DISC; + res = getResponse(b); + if (res != E_PSI_GEN_NONE) + break; + if (b.getLen() != 4) { + res = E_PSI_GEN_FAIL; + break; + } + unsigned long len = b.getDWord(0); + total += len; + if (cb && !cb(ptr, total)) + res = E_PSI_FILE_CANCEL; + if (len != (RFSV_SENDLEN * 10)) + break; + } + fclose(handle_from); + fclose(handle_to); + if (res != E_PSI_GEN_NONE) + remove(to); + return res; +} + Enum rfsv32:: fsetsize(long handle, long size) { @@ -787,6 +851,18 @@ remove(const char *name) return getResponse(a); } +Enum rfsv32:: +setVolumeName(const char drive , const char * const name) +{ + bufferStore a; + a.addDWord(drive - 'A'); + a.addWord(strlen(name)); + a.addStringT(name); + if (!sendCommand(SET_VOLUME_LABEL, a)) + return E_PSI_FILE_DISC; + return getResponse(a); +} + static enum rfsv::errs e2psi[] = { rfsv::E_PSI_FILE_DIRFULL, // -43 rfsv::E_PSI_GEN_POWER, // -42 diff --git a/lib/rfsv32.h b/lib/rfsv32.h index b45f132..fb4c624 100644 --- a/lib/rfsv32.h +++ b/lib/rfsv32.h @@ -3,10 +3,6 @@ #include "rfsv.h" -class ppsocket; -class bufferStore; -class bufferArray; - class rfsv32 : public rfsv { public: @@ -14,12 +10,13 @@ public: Enum dir(const char * const, bufferArray &); Enum dircount(const char * const, long &); - Enum copyFromPsion(const char *, const char *, cpCallback_t); - Enum copyToPsion(const char *, const char *, cpCallback_t); - Enum mkdir(const char *); - Enum rmdir(const char *); - Enum remove(const char *); - Enum rename(const char *, const char *); + Enum copyFromPsion(const char * const, const char * const, void *, cpCallback_t); + Enum copyToPsion(const char * const, const char * const, void *, cpCallback_t); + Enum copyOnPsion(const char * const, const char * const, void *, cpCallback_t); + Enum mkdir(const char * const); + Enum rmdir(const char * const); + Enum remove(const char * const); + Enum rename(const char * const, const char * const); Enum mktemp(long &, char * const); Enum fgeteattr(const char * const, long &, long &, PsiTime &); Enum fgetattr(const char * const, long &); @@ -37,7 +34,10 @@ public: Enum devlist(long &); Enum devinfo(const int, long &, long &, long &, long &, char * const); - + Enum opendir(const long, const char * const, rfsvDirhandle &); + Enum readdir(rfsvDirhandle &, bufferStore &); + Enum closedir(rfsvDirhandle &); + Enum setVolumeName(const char, const char * const); long opMode(const long); private: -- cgit v1.2.3