aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorFritz Elfert <felfert@to.com>2001-02-06 01:01:46 +0000
committerFritz Elfert <felfert@to.com>2001-02-06 01:01:46 +0000
commita9fe8f28a4a9aaf1d9b84dbc6907849ace87f66e (patch)
tree0dd290cdf04cfd17a4ab4d0eb86bcb48137a02cb /lib
parenta8787d39b2bf1851cdea64a5e0eccc2aff7f15de (diff)
downloadplptools-a9fe8f28a4a9aaf1d9b84dbc6907849ace87f66e.tar.gz
plptools-a9fe8f28a4a9aaf1d9b84dbc6907849ace87f66e.tar.bz2
plptools-a9fe8f28a4a9aaf1d9b84dbc6907849ace87f66e.zip
- Added KDE2 PropsDialog Plugin (incomplete)
- Fixed some KDE related autoconf stuff - Added PlpDrive class for returning results from rfsv:devinfo - Added auto-watch in ppsocket and finally got rid of the nasty SIGPIPE bug. Now it's no more necessary to ignore SIGPIPE in applications. - Made constructors of rfsv16, rfsv32, rpcs16 and rpcs32 private to enforce use of the factories. - Removed error output in the factories and replaced that by error codes which can be retrieved and evaluated by an application.
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile.am3
-rw-r--r--lib/plpdirent.cc138
-rw-r--r--lib/plpdirent.h164
-rw-r--r--lib/ppsocket.cc64
-rw-r--r--lib/ppsocket.h17
-rw-r--r--lib/rfsv.h24
-rw-r--r--lib/rfsv16.cc45
-rw-r--r--lib/rfsv16.h19
-rw-r--r--lib/rfsv32.cc15
-rw-r--r--lib/rfsv32.h19
-rw-r--r--lib/rfsvfactory.cc31
-rw-r--r--lib/rfsvfactory.h22
-rw-r--r--lib/rpcs16.h12
-rw-r--r--lib/rpcs32.h53
-rw-r--r--lib/rpcsfactory.cc27
-rw-r--r--lib/rpcsfactory.h22
16 files changed, 573 insertions, 102 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 367fbb7..7e56949 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -2,7 +2,8 @@
#
lib_LTLIBRARIES = libplp.la
-libplp_la_LDFLAGS = --debug -version-info 1:1:0
+libplp_la_LDFLAGS = $(LIBDEBUG) -version-info $(LIBVERSION)
+
libplp_la_SOURCES = bufferarray.cc bufferstore.cc iowatch.cc ppsocket.cc \
rfsv16.cc rfsv32.cc rfsvfactory.cc log.cc rfsv.cc rpcs32.cc rpcs16.cc \
rpcs.cc rpcsfactory.cc psitime.cc Enum.cc plpdirent.cc
diff --git a/lib/plpdirent.cc b/lib/plpdirent.cc
index 33e1a78..9695480 100644
--- a/lib/plpdirent.cc
+++ b/lib/plpdirent.cc
@@ -83,3 +83,141 @@ operator<<(ostream &o, const PlpDirent &e) {
o.flags(old);
return o;
}
+
+PlpDrive::PlpDrive() {
+}
+
+PlpDrive::PlpDrive(const PlpDrive &other) {
+}
+
+void PlpDrive::
+setMediaType(u_int32_t type) {
+ mediatype = type;
+}
+
+void PlpDrive::
+setDriveAttribute(u_int32_t attr) {
+ driveattr = attr;
+}
+
+void PlpDrive::
+setMediaAttribute(u_int32_t attr) {
+ mediaattr = attr;
+}
+
+void PlpDrive::
+setUID(u_int32_t attr) {
+ uid = attr;
+}
+
+void PlpDrive::
+setSize(u_int32_t sizeLo, u_int32_t sizeHi) {
+ size = ((unsigned long long)sizeHi << 32) + sizeLo;
+}
+
+void PlpDrive::
+setSpace(u_int32_t spaceLo, u_int32_t spaceHi) {
+ space = ((unsigned long long)spaceHi << 32) + spaceLo;
+}
+
+void PlpDrive::
+setName(char drive, const char * const volname) {
+ drivechar = drive;
+ name = "";
+ name += volname;
+}
+
+u_int32_t PlpDrive::
+getMediaType() {
+ return mediatype;
+}
+
+static const char * const media_types[] = {
+ "Not present",
+ "Unknown",
+ "Floppy",
+ "Disk",
+ "CD-ROM",
+ "RAM",
+ "Flash Disk",
+ "ROM",
+ "Remote",
+};
+
+void PlpDrive::
+getMediaType(string &ret) {
+ ret = media_types[mediatype];
+}
+
+u_int32_t PlpDrive::
+getDriveAttribute() {
+ return driveattr;
+}
+
+static void
+appendWithDelim(string &s1, const char * const s2) {
+ if (!s1.empty())
+ s1 += ',';
+ s1 += s2;
+}
+
+void PlpDrive::
+getDriveAttribute(string &ret) {
+ ret = "";
+ if (driveattr & 1)
+ appendWithDelim(ret, "local");
+ if (driveattr & 2)
+ appendWithDelim(ret, "ROM");
+ if (driveattr & 4)
+ appendWithDelim(ret, "redirected");
+ if (driveattr & 8)
+ appendWithDelim(ret, "substituted");
+ if (driveattr & 16)
+ appendWithDelim(ret, "internal");
+ if (driveattr & 32)
+ appendWithDelim(ret, "removable");
+}
+
+u_int32_t PlpDrive::
+getMediaAttribute() {
+ return mediaattr;
+}
+
+void PlpDrive::
+getMediaAttribute(string &ret) {
+ ret = "";
+
+ if (mediaattr & 1)
+ appendWithDelim(ret, "variable size");
+ if (mediaattr & 2)
+ appendWithDelim(ret, "dual density");
+ if (mediaattr & 4)
+ appendWithDelim(ret, "formattable");
+ if (mediaattr & 8)
+ appendWithDelim(ret, "write protected");
+}
+
+u_int32_t PlpDrive::
+getUID() {
+ return uid;
+}
+
+u_int64_t PlpDrive::
+getSize() {
+ return size;
+}
+
+u_int64_t PlpDrive::
+getSpace() {
+ return space;
+}
+
+string PlpDrive::
+getName() {
+ return name;
+}
+
+char PlpDrive::
+getDrivechar() {
+ return drivechar;
+}
diff --git a/lib/plpdirent.h b/lib/plpdirent.h
index 9a25a67..c567a9b 100644
--- a/lib/plpdirent.h
+++ b/lib/plpdirent.h
@@ -157,4 +157,168 @@ private:
string attrstr;
string name;
};
+
+/**
+ * A class representing information about
+ * a Disk drive on the psion. An Object of this type
+ * is used by @ref rfsv::devinfo for returning the
+ * information of the probed drive.
+ *
+ * @author Fritz Elfert <felfert@to.com>
+ */
+class PlpDrive {
+ friend rfsv32;
+ friend rfsv16;
+
+ public:
+ /**
+ * Default constructor.
+ */
+ PlpDrive();
+
+ /**
+ * Copy constructor
+ */
+ PlpDrive(const PlpDrive &other);
+
+ /**
+ * Retrieve the media type of the drive.
+ *
+ * @returns The media type of the probed drive.
+ * <pre>
+ * Media types are encoded by a number
+ * in the range 0 .. 8 with the following
+ * meaning:
+ *
+ * 0 = Not present
+ * 1 = Unknown
+ * 2 = Floppy
+ * 3 = Disk
+ * 4 = CD-ROM
+ * 5 = RAM
+ * 6 = Flash Disk
+ * 7 = ROM
+ * 8 = Remote
+ * </pre>
+ */
+ u_int32_t getMediaType();
+
+ /**
+ * Retrieve the media type of the drive.
+ * Just like the above function, but returns
+ * the media type as human readable string.
+ *
+ * @param ret The string is returned here.
+ */
+ void getMediaType(string &ret);
+
+ /**
+ * Retrieve the attributes of the drive.
+ *
+ * @returns The attributes of the probed drive.
+ * <pre>
+ * Drive attributes are encoded by a number
+ * in the range 0 .. 63. The bits have the
+ * the following meaning:
+ *
+ * bit 0 = local
+ * bit 1 = ROM
+ * bit 2 = redirected
+ * bit 3 = substituted
+ * bit 4 = internal
+ * bit 5 = removable
+ * </pre>
+ */
+ u_int32_t getDriveAttribute();
+
+ /**
+ * Retrieve the attributes of the drive.
+ * Just like the above function, but returns
+ * the attributes as human readable string.
+ *
+ * @param ret The string is returned here.
+ */
+ void getDriveAttribute(string &ret);
+
+ /**
+ * Retrieve the attributes of the media.
+ *
+ * @returns The attributes of the probed media.
+ * <pre>
+ * Media attributes are encoded by a number
+ * in the range 0 .. 15. The bits have the
+ * following meaning:
+ *
+ * bit 0 = variable size
+ * bit 1 = dual density
+ * bit 2 = formattable
+ * bit 3 = write protected
+ * </pre>
+ */
+ u_int32_t getMediaAttribute();
+
+ /**
+ * Retrieve the attributes of the media.
+ * Just like the above function, but returns
+ * the attributes as human readable string.
+ *
+ * @param ret The string is returned here.
+ */
+ void getMediaAttribute(string &ret);
+
+ /**
+ * Retrieve the UID of the drive.
+ * Each drive, except the ROM drive on a Psion has
+ * a unique ID which can be retrieved here.
+ *
+ * @returns The UID of the probed drive.
+ */
+ u_int32_t getUID();
+
+ /**
+ * Retrieve the total capacity of the drive.
+ *
+ * @returns The capacity of the probed drive in bytes.
+ */
+ u_int64_t getSize();
+
+ /**
+ * Retrieve the free capacity on the drive.
+ *
+ * @returns The free space on the probed drive in bytes.
+ */
+ u_int64_t getSpace();
+
+ /**
+ * Retrieve the volume name of the drive.
+ *
+ * returns The volume name of the drive.
+ */
+ string getName();
+
+ /**
+ * Retrieve the drive letter of the drive.
+ *
+ * returns The letter of the probed drive.
+ */
+ char getDrivechar();
+
+ private:
+ void setMediaType(u_int32_t type);
+ void setDriveAttribute(u_int32_t attr);
+ void setMediaAttribute(u_int32_t attr);
+ void setUID(u_int32_t uid);
+ void setSize(u_int32_t sizeLo, u_int32_t sizeHi);
+ void setSpace(u_int32_t spaceLo, u_int32_t spaceHi);
+ void setName(char drive, const char * const volname);
+
+ u_int32_t mediatype;
+ u_int32_t driveattr;
+ u_int32_t mediaattr;
+ u_int32_t uid;
+ u_int64_t size;
+ u_int64_t space;
+ char drivechar;
+ string name;
+};
#endif
diff --git a/lib/ppsocket.cc b/lib/ppsocket.cc
index a482ae5..9b0a33d 100644
--- a/lib/ppsocket.cc
+++ b/lib/ppsocket.cc
@@ -38,6 +38,7 @@
#include "bufferstore.h"
#include "ppsocket.h"
+#include "iowatch.h"
#define INVALID_SOCKET -1
#define SOCKET_ERROR -1
@@ -49,6 +50,7 @@ ppsocket::ppsocket(const ppsocket & another)
m_PeerAddr = another.m_PeerAddr;
m_Bound = another.m_Bound;
m_LastError = another.m_LastError;
+ myWatch = another.myWatch;
}
@@ -64,21 +66,32 @@ ppsocket::ppsocket()
m_Bound = false;
m_LastError = 0;
+ myWatch = 0L;
}
ppsocket::~ppsocket()
{
if (m_Socket != INVALID_SOCKET) {
- shutdown(m_Socket, 3);
+ if (myWatch)
+ myWatch->remIO(m_Socket);
+ shutdown(m_Socket, SHUT_RDWR);
::close(m_Socket);
}
}
+void ppsocket::
+setWatch(IOWatch *watch) {
+ if (watch)
+ myWatch = watch;
+}
+
bool ppsocket::
reconnect()
{
if (m_Socket != INVALID_SOCKET) {
- shutdown(m_Socket, 3);
+ if (myWatch)
+ myWatch->remIO(m_Socket);
+ shutdown(m_Socket, SHUT_RDWR);
::close(m_Socket);
}
m_Socket = INVALID_SOCKET;
@@ -94,6 +107,8 @@ reconnect()
m_LastError = errno;
return (false);
}
+ if (myWatch)
+ myWatch->addIO(m_Socket);
return (true);
}
@@ -148,6 +163,8 @@ connect(const char * const Peer, int PeerPort, const char * const Host, int Host
m_LastError = errno;
return (false);
}
+ if (myWatch)
+ myWatch->addIO(m_Socket);
return (true);
}
@@ -167,6 +184,8 @@ listen(const char * const Host, int Port)
//* Listen on the port *
//**********************
+ if (myWatch)
+ myWatch->addIO(m_Socket);
if (::listen(m_Socket, 5) != 0) {
m_LastError = errno;
return (false);
@@ -215,11 +234,9 @@ accept(string *Peer)
// Make sure the new socket hasn't inherited O_NONBLOCK
// from the accept socket
- int flags = fcntl( accepted->m_Socket, F_GETFL, 0 );
- if( flags >= 0 ) {
- flags &= ~O_NONBLOCK;
- fcntl( accepted->m_Socket, F_SETFL, flags);
- }
+ int flags = fcntl(accepted->m_Socket, F_GETFL, 0);
+ flags &= ~O_NONBLOCK;
+ fcntl(accepted->m_Socket, F_SETFL, flags);
accepted->m_HostAddr = m_HostAddr;
accepted->m_Bound = true;
@@ -232,18 +249,22 @@ accept(string *Peer)
if (peer)
*Peer = peer;
}
+ if (accepted && myWatch) {
+ accepted->setWatch(myWatch);
+ myWatch->addIO(accepted->m_Socket);
+ }
return accepted;
}
bool ppsocket::
-dataToGet() const
+dataToGet(int sec, int usec) const
{
fd_set io;
FD_ZERO(&io);
FD_SET(m_Socket, &io);
struct timeval t;
- t.tv_usec = 0;
- t.tv_sec = 0;
+ t.tv_usec = usec;
+ t.tv_sec = sec;
return (select(m_Socket + 1, &io, NULL, NULL, &t) != 0) ? true : false;
}
@@ -258,16 +279,15 @@ getBufferStore(bufferStore & a, bool wait)
long count = 0;
unsigned char *buff;
unsigned char *bp;
- if (!wait && !dataToGet())
+ if (!wait && !dataToGet(0, 0))
return 0;
a.init();
-
- if (recv(&l, sizeof(l), 0) != sizeof(l))
+ if (recv(&l, sizeof(l), MSG_NOSIGNAL) != sizeof(l))
return -1;
l = ntohl(l);
bp = buff = new unsigned char[l];
while (l > 0) {
- int j = recv(bp, l, 0);
+ int j = recv(bp, l, MSG_NOSIGNAL);
if (j == SOCKET_ERROR || j == 0) {
delete[]buff;
return -1;
@@ -290,11 +310,15 @@ sendBufferStore(const bufferStore & a)
int retries = 0;
int i;
- i = send((char *) &hl, sizeof(hl), 0);
- if (i != sizeof(hl))
- return false;
+ bufferStore b;
+ b.addDWord(hl);
+ b.addBuff(a);
+// i = send((char *)&hl, sizeof(hl), MSG_NOSIGNAL);
+// if (i != sizeof(hl))
+// return false;
+ l += 4;
while (l > 0) {
- i = send((const char *)a.getString(sent), l, 0);
+ i = send((const char *)b.getString(sent), l, MSG_NOSIGNAL);
if (i == SOCKET_ERROR || i == 0)
return (false);
sent += i;
@@ -332,7 +356,9 @@ send(const void * const buf, int len, int flags)
bool ppsocket::
closeSocket(void)
{
- shutdown(m_Socket, 3);
+ if (myWatch)
+ myWatch->remIO(m_Socket);
+ shutdown(m_Socket, SHUT_RDWR);
if (::close(m_Socket) != 0) {
m_LastError = errno;
return false;
diff --git a/lib/ppsocket.h b/lib/ppsocket.h
index 57cc788..b8f7ebe 100644
--- a/lib/ppsocket.h
+++ b/lib/ppsocket.h
@@ -8,6 +8,7 @@
#include <arpa/inet.h>
class bufferStore;
+class IOWatch;
/**
* A class for dealing with sockets.
@@ -80,11 +81,14 @@ public:
ppsocket *accept(string *Peer);
/**
- * Check for incoming data.
+ * Check and optionally wait for incoming data.
+ *
+ * @param sec Timeout in seconds
+ * @param usec Timeout in microseconds
*
* @returns true if data is available, false otherwise.
*/
- bool dataToGet() const;
+ bool dataToGet(int sec, int usec) const;
/**
* Receive data into a @ref bufferStore .
@@ -169,11 +173,13 @@ public:
bool getHost(string *Host, int *Port);
/**
- * Retrieves the socket number.
+ * Registers an @ref IOWatch for this socket.
+ * This IOWatch gets the socket added/removed
+ * automatically.
*
- * @returns the socket number.
+ * @param watch The IOWatch to register.
*/
- inline int socket(void) const { return(m_Socket); }
+ void setWatch(IOWatch *watch);
private:
/**
@@ -193,6 +199,7 @@ public:
int m_Port;
bool m_Bound;
int m_LastError;
+ IOWatch *myWatch;
};
#endif
diff --git a/lib/rfsv.h b/lib/rfsv.h
index 0cfe7b2..9125f01 100644
--- a/lib/rfsv.h
+++ b/lib/rfsv.h
@@ -10,6 +10,7 @@
typedef deque<class PlpDirent> PlpDir;
class ppsocket;
+class PlpDrive;
const int RFSV_SENDLEN = 2000;
@@ -19,8 +20,20 @@ const int RFSV_SENDLEN = 2000;
*/
typedef int (*cpCallback_t)(void *, u_int32_t);
+class rfsv16;
+class rfsv32;
+
+/**
+ * A helper class for storing
+ * intermediate internal information in rfsv16 and
+ * rfsv32 .
+ * @internal
+ */
class rfsvDirhandle {
- public:
+ friend rfsv16;
+ friend rfsv32;
+
+ private:
u_int32_t h;
bufferStore b;
};
@@ -330,15 +343,12 @@ class rfsv {
*
* @param dev An integer, representing the drive to get details from.
* (0 represents A:, 1 is B: and so on ...)
- * @param free On return, the free space in bytes is returned here.
- * @param total On return, the total capacity in bytes is returned here.
- * @param attr On return, the attributes of the drive are returned here.
- * @param uniqueid On return, the unique Id of the drive is returned here.
- * @param name On return, the volume name returned here.
+ * @param drive A @ref PlpDrive object which is filled with the drive's
+ * information upon return.
*
* @returns A Psion error code (One of enum @ref #errs ).
*/
- virtual Enum<errs> devinfo(const u_int32_t dev, u_int32_t &free, u_int32_t &total, u_int32_t &attr, u_int32_t &uniqueid, string &name) = 0;
+ virtual Enum<errs> devinfo(const u_int32_t dev, PlpDrive &drive) = 0;
/**
* Reads from a file on the Psion.
diff --git a/lib/rfsv16.cc b/lib/rfsv16.cc
index 2b474cb..f98816c 100644
--- a/lib/rfsv16.cc
+++ b/lib/rfsv16.cc
@@ -413,8 +413,18 @@ devlist(u_int32_t &devbits)
return res;
}
+static int sibo_dattr[] = {
+ 1, // Unknown
+ 2, // Floppy
+ 3, // Disk
+ 6, // Flash
+ 5, // RAM
+ 7, // ROM
+ 7, // write-protected == ROM ?
+};
+
Enum<rfsv::errs> rfsv16::
-devinfo(const u_int32_t devnum, u_int32_t &free, u_int32_t &size, u_int32_t &attr, u_int32_t &uniqueid, string &name)
+devinfo(const u_int32_t devnum, PlpDrive &drive)
{
bufferStore a;
Enum<rfsv::errs> res;
@@ -448,16 +458,31 @@ devinfo(const u_int32_t devnum, u_int32_t &free, u_int32_t &size, u_int32_t &att
// cerr << "devinfo STATUSDEVICE res is " << dec << (signed short int) res << endl;
return res;
}
+
+ int attr = a.getWord(2);
+ attr = sibo_dattr[a.getWord(2) & 0xff];
+ drive.setMediaType(attr);
+
attr = a.getWord(2);
- // int changeable = a.getWord(4);
- size = a.getDWord(6);
- free = a.getDWord(10);
- // const char *volume = a.getString(14);
- // int battery = a.getWord(30);
- // const char *devicename = a.getString(62);
- uniqueid = 0;
- name = "";
- name += (char)(devnum + 'A');
+ int changeable = a.getWord(4) ? 32 : 0;
+ int internal = (attr & 0x2000) ? 16 : 0;
+
+ drive.setDriveAttribute(changeable | internal);
+
+ int variable = (attr & 0x4000) ? 1 : 0;
+ int dualdens = (attr & 0x1000) ? 2 : 0;
+ int formattable = (attr & 0x0800) ? 4 : 0;
+ int protect = ((attr & 0xff) == 6) ? 8 : 0;
+
+ drive.setMediaAttribute(variable|dualdens|formattable|protect);
+
+ drive.setUID(0);
+ drive.setSize(a.getDWord(6), 0);
+ drive.setSpace(a.getDWord(10), 0);
+
+ drive.setName('A' + devnum, a.getString(14));
+
+
return res;
}
diff --git a/lib/rfsv16.h b/lib/rfsv16.h
index a94aa5f..42661f8 100644
--- a/lib/rfsv16.h
+++ b/lib/rfsv16.h
@@ -3,15 +3,19 @@
#include "rfsv.h"
+class rfsvfactory;
+
/**
* This is the implementation of the @ref rfsv protocol for
- * Psion series 3 (SIBO) variant.
- * For a complete documentation, see @ref rfsv .
+ * Psion series 3 (SIBO) variant. You normally never create
+ * objects of this class directly. Thus the constructor is
+ * private. Use @ref rfsvfactory for creating an instance of
+ * @ref rfsv . For a complete documentation, see @ref rfsv .
*/
class rfsv16 : public rfsv {
-public:
- rfsv16(ppsocket *);
+ friend rfsvfactory;
+public:
Enum<rfsv::errs> fopen(const u_int32_t, const char * const, u_int32_t &);
Enum<rfsv::errs> mktemp(u_int32_t &, string &);
Enum<rfsv::errs> fcreatefile(const u_int32_t, const char * const, u_int32_t &);
@@ -25,7 +29,7 @@ public:
Enum<rfsv::errs> fsetattr(const char * const, const u_int32_t seta, const u_int32_t unseta);
Enum<rfsv::errs> dircount(const char * const, u_int32_t &);
Enum<rfsv::errs> devlist(u_int32_t &);
- Enum<rfsv::errs> devinfo(const u_int32_t, u_int32_t &, u_int32_t &, u_int32_t &, u_int32_t &, string &);
+ Enum<rfsv::errs> devinfo(const u_int32_t, PlpDrive &);
Enum<rfsv::errs> fread(const u_int32_t, unsigned char * const, const u_int32_t, u_int32_t &);
Enum<rfsv::errs> fwrite(const u_int32_t, const unsigned char * const, const u_int32_t, u_int32_t &);
Enum<rfsv::errs> copyFromPsion(const char * const, const char * const, void *, cpCallback_t);
@@ -102,6 +106,11 @@ private:
P_FAMASK = 0x0f3f /* All of the above */
};
+ /**
+ * Private constructor. Shall be called by
+ * rfsvfactory only.
+ */
+ rfsv16(ppsocket *);
// Miscellaneous
Enum<rfsv::errs> fopendir(const char * const, u_int32_t &);
diff --git a/lib/rfsv32.cc b/lib/rfsv32.cc
index 74a1959..0b6f120 100644
--- a/lib/rfsv32.cc
+++ b/lib/rfsv32.cc
@@ -358,7 +358,7 @@ devlist(u_int32_t &devbits)
}
Enum<rfsv::errs> rfsv32::
-devinfo(const u_int32_t dev, u_int32_t &free, u_int32_t &total, u_int32_t &attr, u_int32_t &uniqueid, string &name)
+devinfo(const u_int32_t dev, PlpDrive &drive)
{
bufferStore a;
Enum<rfsv::errs> res;
@@ -368,13 +368,14 @@ devinfo(const u_int32_t dev, u_int32_t &free, u_int32_t &total, u_int32_t &attr,
return E_PSI_FILE_DISC;
res = getResponse(a);
if (res == E_PSI_GEN_NONE) {
- attr = a.getDWord(0);
- uniqueid = a.getDWord(16);
- total = a.getDWord(20);
- free = a.getDWord(28);
- // vnamelen = a.getDWord(36);
+ drive.setMediaType(a.getDWord(0));
+ drive.setDriveAttribute(a.getDWord(8));
+ drive.setMediaAttribute(a.getDWord(12));
+ drive.setUID(a.getDWord(16));
+ drive.setSize(a.getDWord(20), a.getDWord(24));
+ drive.setSpace(a.getDWord(28), a.getDWord(32));
a.addByte(0);
- name = a.getString(40);
+ drive.setName('A' + dev, a.getString(40));
}
return res;
}
diff --git a/lib/rfsv32.h b/lib/rfsv32.h
index abbc6ad..4afb95a 100644
--- a/lib/rfsv32.h
+++ b/lib/rfsv32.h
@@ -4,16 +4,19 @@
#include "rfsv.h"
#include "plpdirent.h"
+class rfsvfactory;
+
/**
* This is the implementation of the @ref rfsv protocol for
- * Psion series 5 (EPOC) variant.
- * For a complete documentation, see @ref rfsv .
+ * Psion series 5 (EPOC) variant. You normally never create
+ * objects of this class directly. Thus the constructor is
+ * private. Use @ref rfsvfactory for creating an instance of
+ * @ref rfsv . For a complete documentation, see @ref rfsv .
*/
class rfsv32 : public rfsv {
+ friend rfsvfactory;
public:
- rfsv32(ppsocket *);
-
Enum<rfsv::errs> dir(const char * const, PlpDir &);
Enum<rfsv::errs> dircount(const char * const, u_int32_t &);
Enum<rfsv::errs> copyFromPsion(const char * const, const char * const, void *, cpCallback_t);
@@ -39,7 +42,7 @@ public:
Enum<rfsv::errs> fclose(const u_int32_t);
Enum<rfsv::errs> devlist(u_int32_t &);
- Enum<rfsv::errs> devinfo(const u_int32_t, u_int32_t &, u_int32_t &, u_int32_t &, u_int32_t &, string &);
+ Enum<rfsv::errs> devinfo(const u_int32_t, PlpDrive&);
Enum<rfsv::errs> opendir(const u_int32_t, const char * const, rfsvDirhandle &);
Enum<rfsv::errs> readdir(rfsvDirhandle &, PlpDirent &);
Enum<rfsv::errs> closedir(rfsvDirhandle &);
@@ -155,6 +158,12 @@ private:
REPLACE = 0x32
};
+ /**
+ * Private constructor. Shall be called by
+ * rfsvfactory only.
+ */
+ rfsv32(ppsocket *);
+
Enum<rfsv::errs> err2psierr(int32_t);
Enum<rfsv::errs> fopendir(const u_int32_t, const char *, u_int32_t &);
u_int32_t attr2std(const u_int32_t);
diff --git a/lib/rfsvfactory.cc b/lib/rfsvfactory.cc
index 12bd623..3699903 100644
--- a/lib/rfsvfactory.cc
+++ b/lib/rfsvfactory.cc
@@ -35,10 +35,20 @@
#include "rfsvfactory.h"
#include "bufferstore.h"
#include "ppsocket.h"
-#include "bufferarray.h"
+#include "Enum.h"
+
+ENUM_DEFINITION(rfsvfactory::errs, rfsvfactory::FACERR_NONE) {
+ stringRep.add(rfsvfactory::FACERR_NONE, "no error");
+ stringRep.add(rfsvfactory::FACERR_COULD_NOT_SEND, "could not send version request");
+ stringRep.add(rfsvfactory::FACERR_AGAIN, "try again");
+ stringRep.add(rfsvfactory::FACERR_NOPSION, "no psion connected");
+ stringRep.add(rfsvfactory::FACERR_PROTVERSION, "wrong protocol version");
+ stringRep.add(rfsvfactory::FACERR_NORESPONSE, "no response from ncpd");
+}
rfsvfactory::rfsvfactory(ppsocket *_skt) : serNum(0)
{
+ err = FACERR_NONE;
skt = _skt;
}
@@ -50,15 +60,19 @@ rfsv * rfsvfactory::create(bool reconnect)
// so we can instantiate the correct RFSV protocol handler for the
// caller. We announce ourselves to the NCP daemon, and the relevant
// RFSV module will also announce itself.
+
bufferStore a;
- a.init();
+
+ err = FACERR_NONE;
a.addStringT("NCP$INFO");
if (!skt->sendBufferStore(a)) {
if (!reconnect)
- cerr << "rfsvfactory::create couldn't send version request" << endl; else {
+ err = FACERR_COULD_NOT_SEND;
+ else {
skt->closeSocket();
serNum = 0;
skt->reconnect();
+ err = FACERR_AGAIN;
}
return NULL;
}
@@ -73,16 +87,13 @@ rfsv * rfsvfactory::create(bool reconnect)
skt->closeSocket();
serNum = 0;
skt->reconnect();
+ err = FACERR_NOPSION;
return NULL;
}
// Invalid protocol version
- cerr << "rfsvfactory::create received odd protocol version from
-ncpd! (" << a << ")" << endl;
- } else {
- cerr << "rfsvfactory::create sent, response not 1" << endl;
- }
+ err = FACERR_PROTVERSION;
+ } else
+ err = FACERR_NORESPONSE;
- // No message returned.
return NULL;
}
-
diff --git a/lib/rfsvfactory.h b/lib/rfsvfactory.h
index 99136e3..8af4575 100644
--- a/lib/rfsvfactory.h
+++ b/lib/rfsvfactory.h
@@ -10,8 +10,21 @@ class ppsocket;
* @ref rfsv protocol variant depending on the connected Psion.
*/
class rfsvfactory {
+
public:
/**
+ * The known errors which can happen during @ref create .
+ */
+ enum errs {
+ FACERR_NONE = 0,
+ FACERR_COULD_NOT_SEND = 1,
+ FACERR_AGAIN = 2,
+ FACERR_NOPSION = 3,
+ FACERR_PROTVERSION = 4,
+ FACERR_NORESPONSE = 5,
+ };
+
+ /**
* Constructs a rfsvfactory.
*
* @param skt The socket to be used for connecting
@@ -30,6 +43,14 @@ class rfsvfactory {
*/
virtual rfsv * create(bool);
+ /**
+ * Retrieve an error code.
+ *
+ * @returns The error code, in case @ref create has
+ * failed, 0 otherwise.
+ */
+ virtual Enum<errs> getError() { return err; }
+
private:
/**
* The socket to be used for connecting to the
@@ -37,6 +58,7 @@ class rfsvfactory {
*/
ppsocket *skt;
int serNum;
+ Enum<errs> err;
};
#endif
diff --git a/lib/rpcs16.h b/lib/rpcs16.h
index 7085939..cc4d601 100644
--- a/lib/rpcs16.h
+++ b/lib/rpcs16.h
@@ -5,19 +5,25 @@
class ppsocket;
class bufferStore;
+class rpcsfactory;
/**
* This is the implementation of the @ref rpcs protocol for
- * Psion series 3 (SIBO) variant.
- * For a complete documentation, see @ref rpcs .
+ * Psion series 3 (SIBO) variant. You normally never create
+ * objects of this class directly. Thus the constructor is
+ * private. Use @ref rpcsfactory for creating an instance of
+ * @ref rpcs . For a complete documentation, see @ref rpcs .
*/
class rpcs16 : public rpcs {
+ friend rpcsfactory;
+
public:
- rpcs16(ppsocket *);
~rpcs16();
Enum<rfsv::errs> queryDrive(const char, bufferArray &);
Enum<rfsv::errs> getCmdLine(const char *, bufferStore &);
+ private:
+ rpcs16(ppsocket *);
};
#endif
diff --git a/lib/rpcs32.h b/lib/rpcs32.h
index 0cab1b2..5230247 100644
--- a/lib/rpcs32.h
+++ b/lib/rpcs32.h
@@ -4,40 +4,45 @@
#include "rpcs.h"
class ppsocket;
+class rpcsfactory;
/**
* This is the implementation of the @ref rpcs protocol for
- * Psion series 5 (EPOC) variant.
- * For a complete documentation, see @ref rpcs .
+ * Psion series 5 (EPOC) variant. You normally never create
+ * objects of this class directly. Thus the constructor is
+ * private. Use @ref rpcsfactory for creating an instance of
+ * @ref rpcs . For a complete documentation, see @ref rpcs .
*/
class rpcs32 : public rpcs {
- public:
- rpcs32(ppsocket *);
- ~rpcs32();
+ friend rpcsfactory;
- Enum<rfsv::errs> queryDrive(const char, bufferArray &);
- Enum<rfsv::errs> getCmdLine(const char *, bufferStore &);
- Enum<rfsv::errs> getMachineInfo(machineInfo &);
- Enum<rfsv::errs> configOpen(void);
- Enum<rfsv::errs> configRead(void);
+ public:
+ ~rpcs32();
+
+ Enum<rfsv::errs> queryDrive(const char, bufferArray &);
+ Enum<rfsv::errs> getCmdLine(const char *, bufferStore &);
+ Enum<rfsv::errs> getMachineInfo(machineInfo &);
+ Enum<rfsv::errs> configOpen(void);
+ Enum<rfsv::errs> configRead(void);
#if 0
- Enum<rfsv::errs> closeHandle(int);
+ Enum<rfsv::errs> closeHandle(int);
#endif
- Enum<rfsv::errs> regOpenIter(void);
+ Enum<rfsv::errs> regOpenIter(void);
#if 0
- Enum<rfsv::errs> regReadIter(void);
- Enum<rfsv::errs> regWrite(void);
- Enum<rfsv::errs> regRead(void);
- Enum<rfsv::errs> regDelete(void);
- Enum<rfsv::errs> setTime(void);
- Enum<rfsv::errs> configOpen(void);
- Enum<rfsv::errs> configRead(void);
- Enum<rfsv::errs> configWrite(void);
- Enum<rfsv::errs> queryOpen(void);
- Enum<rfsv::errs> queryRead(void);
- Enum<rfsv::errs> quitServer(void);
+ Enum<rfsv::errs> regReadIter(void);
+ Enum<rfsv::errs> regWrite(void);
+ Enum<rfsv::errs> regRead(void);
+ Enum<rfsv::errs> regDelete(void);
+ Enum<rfsv::errs> setTime(void);
+ Enum<rfsv::errs> configOpen(void);
+ Enum<rfsv::errs> configRead(void);
+ Enum<rfsv::errs> configWrite(void);
+ Enum<rfsv::errs> queryOpen(void);
+ Enum<rfsv::errs> queryRead(void);
+ Enum<rfsv::errs> quitServer(void);
#endif
-
+ private:
+ rpcs32(ppsocket *);
};
#endif
diff --git a/lib/rpcsfactory.cc b/lib/rpcsfactory.cc
index 091f12a..bd3b77d 100644
--- a/lib/rpcsfactory.cc
+++ b/lib/rpcsfactory.cc
@@ -36,8 +36,20 @@
#include "bufferstore.h"
#include "ppsocket.h"
+#include "Enum.h"
+
+ENUM_DEFINITION(rpcsfactory::errs, rpcsfactory::FACERR_NONE) {
+ stringRep.add(rpcsfactory::FACERR_NONE, "no error");
+ stringRep.add(rpcsfactory::FACERR_COULD_NOT_SEND, "could not send version request");
+ stringRep.add(rpcsfactory::FACERR_AGAIN, "try again");
+ stringRep.add(rpcsfactory::FACERR_NOPSION, "no psion connected");
+ stringRep.add(rpcsfactory::FACERR_PROTVERSION, "wrong protocol version");
+ stringRep.add(rpcsfactory::FACERR_NORESPONSE, "no response from ncpd");
+}
+
rpcsfactory::rpcsfactory(ppsocket *_skt)
{
+ err = FACERR_NONE;
skt = _skt;
}
@@ -49,15 +61,18 @@ rpcs * rpcsfactory::create(bool reconnect)
// so we can instantiate the correct rpcs protocol handler for the
// caller. We announce ourselves to the NCP daemon, and the relevant
// rpcs module will also announce itself.
+
bufferStore a;
- a.init();
+
+ err = FACERR_NONE;
a.addStringT("NCP$INFO");
if (!skt->sendBufferStore(a)) {
if (!reconnect)
- cerr << "rpcsfactory::create couldn't send version request" << endl;
+ err = FACERR_COULD_NOT_SEND;
else {
skt->closeSocket();
skt->reconnect();
+ err = FACERR_AGAIN;
}
return NULL;
}
@@ -71,13 +86,13 @@ rpcs * rpcsfactory::create(bool reconnect)
if ((a.getLen() > 8) && !strncmp(a.getString(), "No Psion", 8)) {
skt->closeSocket();
skt->reconnect();
+ err = FACERR_NOPSION;
return NULL;
}
// Invalid protocol version
- cerr << "rpcsfactory::create received odd protocol version from ncpd! (" << a << ")" << endl;
- } else {
- cerr << "rpcsfactory::create sent, response not 1" << endl;
- }
+ err = FACERR_PROTVERSION;
+ } else
+ err = FACERR_NORESPONSE;
// No message returned.
return NULL;
diff --git a/lib/rpcsfactory.h b/lib/rpcsfactory.h
index d57eb29..cc36f0d 100644
--- a/lib/rpcsfactory.h
+++ b/lib/rpcsfactory.h
@@ -11,6 +11,19 @@ class ppsocket;
*/
class rpcsfactory {
public:
+
+ /**
+ * The known errors which can happen during @ref create .
+ */
+ enum errs {
+ FACERR_NONE = 0,
+ FACERR_COULD_NOT_SEND = 1,
+ FACERR_AGAIN = 2,
+ FACERR_NOPSION = 3,
+ FACERR_PROTVERSION = 4,
+ FACERR_NORESPONSE = 5,
+ };
+
/**
* Constructs a rpcsfactory.
*
@@ -30,12 +43,21 @@ class rpcsfactory {
*/
virtual rpcs * create(bool reconnect);
+ /**
+ * Retrieve an error code.
+ *
+ * @returns The error code, in case @ref create has
+ * failed, 0 otherwise.
+ */
+ virtual Enum<errs> getError() { return err; }
+
private:
/**
* The socket to be used for connecting to the
* ncpd daemon.
*/
ppsocket *skt;
+ Enum<errs> err;
};
#endif