From 23f25b04b95f08f5fc3aeaf9ea745326246dec9f Mon Sep 17 00:00:00 2001 From: Fritz Elfert Date: Mon, 18 Mar 2002 05:01:40 +0000 Subject: - made kpsion SIBO-aware - Added SIBO-related stuff in PsiTime - Added new class PsiProcess, renamed rpcs:queryDrive to queryPrograms and changed it accordingly - Adapted kspion, plpbackup, plpnfsd and plpftp to use queryPrograms - Several cleanups in rfsv16 --- lib/Makefile.am | 4 +- lib/psiprocess.cc | 102 ++++++++++++++++++++++++++++++++++++++ lib/psiprocess.h | 126 +++++++++++++++++++++++++++++++++++++++++++++++ lib/psitime.cc | 20 +++++++- lib/psitime.h | 17 ++++++- lib/rfsv.h | 2 +- lib/rfsv16.cc | 143 +++++++++++++----------------------------------------- lib/rpcs.cc | 87 ++++++++++++++++++++++++++++++++- lib/rpcs.h | 35 ++++++++++--- lib/rpcs16.cc | 21 ++++---- lib/rpcs16.h | 5 +- lib/rpcs32.cc | 55 ++++----------------- lib/rpcs32.h | 5 +- 13 files changed, 439 insertions(+), 183 deletions(-) create mode 100644 lib/psiprocess.cc create mode 100644 lib/psiprocess.h (limited to 'lib') diff --git a/lib/Makefile.am b/lib/Makefile.am index 440570e..d419387 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -13,12 +13,12 @@ libplp_la_SOURCES = bufferarray.cc bufferstore.cc iowatch.cc ppsocket.cc \ rpcs.cc rpcsfactory.cc psitime.cc Enum.cc plpdirent.cc wprt.cc \ rclip.cc siscomponentrecord.cpp sisfile.cpp sisfileheader.cpp \ sisfilerecord.cpp sislangrecord.cpp sisreqrecord.cpp sistypes.cpp \ - psibitmap.cpp + psibitmap.cpp psiprocess.cc pkginclude_HEADERS = bufferarray.h bufferstore.h iowatch.h ppsocket.h \ rfsv.h rfsv16.h rfsv32.h rfsvfactory.h log.h rpcs32.h rpcs16.h rpcs.h \ rpcsfactory.h psitime.h Enum.h plpdirent.h wprt.h plpintl.h rclip.h \ siscomponentrecord.h sisfile.h sisfileheader.h sisfilerecord.h \ - sislangrecord.h sisreqrecord.h sistypes.h psibitmap.h + sislangrecord.h sisreqrecord.h sistypes.h psibitmap.h psiprocess.h maintainer-clean-local: rm -f Makefile.in diff --git a/lib/psiprocess.cc b/lib/psiprocess.cc new file mode 100644 index 0000000..ce27450 --- /dev/null +++ b/lib/psiprocess.cc @@ -0,0 +1,102 @@ +/*-*-c++-*- + * $Id$ + * + * This file is part of plptools. + * + * Copyright (C) 1999-2002 Fritz Elfert + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#include "psiprocess.h" +#include +#include +#include + +PsiProcess::PsiProcess() + : pid(0), name(""), args(""), s5mx(false) { +} + +PsiProcess::PsiProcess(const PsiProcess &p) { + pid = p.pid; + name = p.name; + args = p.args; + s5mx = p.s5mx; +} + +PsiProcess::PsiProcess(int _pid, const char * const _name, + const char * const _args, bool _s5mx) { + pid = _pid; + name = _name; + args = _args; + s5mx = _s5mx; +} + +int PsiProcess:: +getPID() { + return pid; +} + +const char *PsiProcess:: +getName() { + return name.c_str(); +} + +const char *PsiProcess:: +getArgs() { + return args.c_str(); +} + +const char *PsiProcess:: +getProcId() { + ostrstream tmp; + + if (s5mx) + tmp << name << ".$" << setw(2) << setfill('0') << pid << '\0'; + else + tmp << name << ".$" << pid << '\0'; + return tmp.str(); +} + +void PsiProcess:: +setArgs(string _args) { + args = _args; +} + +PsiProcess &PsiProcess:: +operator=(const PsiProcess &p) { + pid = p.pid; + name = p.name; + args = p.args; + s5mx = p.s5mx; + return *this; +} + +ostream & +operator<<(ostream &o, const PsiProcess &p) { + ostream::fmtflags old = o.flags(); + + o << dec << setw(5) << setfill(' ') << p.pid << " " << setw(12) + << setfill(' ') << setiosflags(ios::left) << p.name.c_str() + << resetiosflags(ios::left) << " " << p.args; + o.flags(old); + return o; +} + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ diff --git a/lib/psiprocess.h b/lib/psiprocess.h new file mode 100644 index 0000000..24d47eb --- /dev/null +++ b/lib/psiprocess.h @@ -0,0 +1,126 @@ +/*-*-c++-*- + * $Id$ + * + * This file is part of plptools. + * + * Copyright (C) 1999-2002 Fritz Elfert + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#ifndef _PSIPROCESS_H_ +#define _PSIPROCESS_H_ + +#include + +class rpcs; + +/** + * A class, describing a Process on the Psion. + * Objects of this type are used by @ref rpcs::queryPrograms + * for returning the currently running processes. + * + * @author Fritz Elfert + */ +class PsiProcess { + +public: + /** + * Default constructor + */ + PsiProcess(); + + /** + * A copy constructor. + * Mainly used by STL container classes. + * + * @param d The object to be used as initializer. + */ + PsiProcess(const PsiProcess &p); + + /** + * Initializing Constructor + */ + PsiProcess(const int, const char * const, const char * const, bool); + + /** + * Default destructor. + */ + ~PsiProcess() {}; + + /** + * Retrieves the PID of a process. + * + * @returns The PID of this instance. + */ + int getPID(); + + /** + * Retrieve the file name of a process. + * + * @returns The name of this instance. + */ + const char *getName(); + + /** + * Retrieve the file name of a process. + * + * @returns The arguments of this instance. + */ + const char *getArgs(); + + /** + * Retrieve the file name and PID of a process. + * + * @returns The name and PID this instance in the format + * name.$pid . + */ + const char *getProcId(); + + /** + * Assignment operator + * Mainly used by STL container classes. + * + * @param e The new value to assign. + * + * @returns The modified object. + */ + PsiProcess &operator=(const PsiProcess &p); + + /** + * Prints the object contents. + * The output is in human readable similar to the + * output of a "ls" command. + */ + friend ostream &operator<<(ostream &o, const PsiProcess &p); + +private: + friend class rpcs; + + void setArgs(string _args); + + int pid; + string name; + string args; + bool s5mx; +}; + +#endif + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ diff --git a/lib/psitime.cc b/lib/psitime.cc index 298e494..213858d 100644 --- a/lib/psitime.cc +++ b/lib/psitime.cc @@ -3,7 +3,7 @@ * * This file is part of plptools. * - * Copyright (C) 2000-2001 Fritz Elfert + * Copyright (C) 2000-2002 Fritz Elfert * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,6 +24,8 @@ #include #include +#define OnePM 3600 // 13:00 offset for SIBO + PsiTime::PsiTime(void) { ptzValid = false; tryPsiZone(); @@ -210,6 +212,22 @@ evalOffset(psi_timezone ptz, time_t time, bool valid) { return offset; } +void PsiTime::setSiboTime(u_int32_t stime) { + unsigned long long micro = evalOffset(ptz, time(0), false); + + micro /= 1000000; + utv.tv_sec = stime + OnePM - micro; + utv.tv_usec = 0; +// unix2psi(); +} + +u_int32_t PsiTime::getSiboTime(void) { + unsigned long long micro = evalOffset(ptz, time(0), false); + + micro /= 1000000; + return utv.tv_sec - OnePM + micro; +} + void PsiTime::psi2unix(void) { u_int64_t micro = ptv.tv_high; micro = (micro << 32) | ptv.tv_low; diff --git a/lib/psitime.h b/lib/psitime.h index 587faaf..605d531 100644 --- a/lib/psitime.h +++ b/lib/psitime.h @@ -3,7 +3,7 @@ * * This file is part of plptools. * - * Copyright (C) 2000-2001 Fritz Elfert + * Copyright (C) 2000-2002 Fritz Elfert * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -189,6 +189,13 @@ public: */ void setPsiTime(psi_timeval *_ptv); + /** + * Modifies the value of this instance. + * + * @param stime The new SIBO time representation. + */ + void setSiboTime(u_int32_t stime); + /** * Modifies the value of this instance. * @@ -240,6 +247,14 @@ public: */ time_t getTime(void); + /** + * Retrieves the instance's current value + * in SIBO time format. + * + * @returns The instance's current time as SIBO time. + */ + u_int32_t getSiboTime(); + /** * Retrieves the instance's current value * in Psion time format. diff --git a/lib/rfsv.h b/lib/rfsv.h index b9a7321..40f3799 100644 --- a/lib/rfsv.h +++ b/lib/rfsv.h @@ -4,7 +4,7 @@ * This file is part of plptools. * * Copyright (C) 1999 Philip Proudman - * Copyright (C) 1999-2001 Fritz Elfert + * Copyright (C) 1999-2002 Fritz Elfert * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/lib/rfsv16.cc b/lib/rfsv16.cc index 773a5c1..c8e50a0 100644 --- a/lib/rfsv16.cc +++ b/lib/rfsv16.cc @@ -5,7 +5,7 @@ * * Copyright (C) 1999 Philip Proudman * Copyright (C) 1999 Matt J. Gumbley - * Copyright (C) 1999-2001 Fritz Elfert + * Copyright (C) 1999-2002 Fritz Elfert * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -87,14 +87,12 @@ mktemp(u_int32_t &handle, string &tmpname) return res; } -// internal and external Enum rfsv16:: fcreatefile(u_int32_t attr, const char *name, u_int32_t &handle) { return fopen(attr | P_FCREATE, name, handle); } -// this is internal - not used by plpnfsd, unlike fcreatefile Enum rfsv16:: freplacefile(u_int32_t attr, const char *name, u_int32_t &handle) { @@ -141,19 +139,22 @@ readdir(rfsvDirhandle &dH, PlpDirent &e) { 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) { + u_int16_t bufferLen = dH.b.getWord(0); + dH.b.discardFirstBytes(2); + if (dH.b.getLen() != bufferLen) + return E_PSI_GEN_FAIL; + } } if ((res == E_PSI_GEN_NONE) && (dH.b.getLen() > 16)) { u_int16_t version = dH.b.getWord(0); - if (version != 2) { - cerr << "dir: not version 2" << endl; + if (version != 2) return E_PSI_GEN_FAIL; - } e.attr = attr2std((u_int32_t)dH.b.getWord(2)); e.size = dH.b.getDWord(4); - e.time = PsiTime((time_t)dH.b.getDWord(8)); + e.time.setSiboTime(dH.b.getDWord(8)); e.name = dH.b.getString(16); - // e.UID = PlpUID(0,0,0); + //e.UID = PlpUID(0,0,0); e.attrstr = attr2String(e.attr); dH.b.discardFirstBytes(17 + e.name.length()); @@ -167,7 +168,7 @@ dir(const char *name, PlpDir &files) { rfsvDirhandle h; files.clear(); - Enum res = opendir(PSI_A_HIDDEN | PSI_A_SYSTEM | PSI_A_DIR, name, h); + Enum res = opendir(PSI_A_HIDDEN|PSI_A_SYSTEM|PSI_A_DIR, name, h); while (res == E_PSI_GEN_NONE) { PlpDirent e; res = readdir(h, e); @@ -197,25 +198,21 @@ opMode(u_int32_t mode) Enum rfsv16:: fgetmtime(const char * const name, PsiTime &mtime) { - cerr << "rfsv16::fgetmtime" << endl; - // NB: fgetattr, fgeteattr is almost identical... bufferStore a; string realName = convertSlash(name); a.addStringT(realName.c_str()); - // and this needs sending in the length word. if (!sendCommand(FINFO, a)) return E_PSI_FILE_DISC; Enum res = getResponse(a); - if (res != E_PSI_GEN_NONE) { - cerr << "fgetmtime: Error " << res << " on file " << name << endl; + if (res != E_PSI_GEN_NONE) return res; - } else if (a.getLen() == 16) { - mtime.setUnixTime(a.getDWord(8)); + // According to Alex's docs, Psion's file times are in + // seconds since 13:00!!, 1.1.1970 + mtime.setSiboTime(a.getDWord(8)); return res; } - cerr << "fgetmtime: Unknown response (" << name << ") " << a < res = getResponse(a); - if (res != E_PSI_GEN_NONE) - cerr << "fsetmtime: Error " << res << " on file " << name << endl; - return res; + return getResponse(a); } Enum rfsv16:: fgetattr(const char * const name, u_int32_t &attr) { - // NB: fgetmtime, fgeteattr are almost identical... bufferStore a; string realName = convertSlash(name); a.addStringT(realName.c_str()); - // and this needs sending in the length word. if (!sendCommand(FINFO, a)) return E_PSI_FILE_DISC; Enum res = getResponse(a); - if (res != 0) { - cerr << "fgetattr: Error " << res << " on file " << name << endl; + if (res != E_PSI_GEN_NONE) return res; - } else if (a.getLen() == 16) { attr = attr2std((long)a.getWord(2)); return res; } - cerr << "fgetattr: Unknown response (" << name << ") " << a < res = getResponse(a); - if (res != 0) { - cerr << "fgeteattr: Error " << res << " on file " << name << endl; + if (res != E_PSI_GEN_NONE) return res; - } else if (a.getLen() == 16) { const char *p = strrchr(realName.c_str(), '\\'); if (p) @@ -285,36 +272,24 @@ fgeteattr(const char * const name, PlpDirent &e) e.name = p; e.attr = attr2std((long)a.getWord(2)); e.size = a.getDWord(4); - e.time = PsiTime(a.getDWord(8)); + e.time.setSiboTime(a.getDWord(8)); e.UID = PlpUID(0,0,0); e.attrstr = string(attr2String(e.attr)); return res; } - cerr << "fgeteattr: Unknown response (" << name << ") " << a < rfsv16:: fsetattr(const char *name, u_int32_t seta, u_int32_t unseta) { - cerr << "rfsv16::fsetattr" << endl; - // seta are attributes to set; unseta are attributes to unset. Need to - // turn this into attributes to change state and a bit mask. - // 210000 - // 008421 - // a shr u_int32_t statusword = std2attr(seta) & (~ std2attr(unseta)); statusword ^= 0x0000001; // r bit is inverted u_int32_t bitmask = std2attr(seta) | std2attr(unseta); - // cerr << "seta is " << hex << setw(2) << setfill('0') << seta << endl; - // cerr << "unseta is " << hex << setw(2) << setfill('0') << unseta << endl; - // cerr << "statusword is " << hex << setw(2) << setfill('0') << statusword << endl; - // cerr << "bitmask is " << hex << setw(2) << setfill('0') << bitmask << endl; bufferStore a; a.addWord(statusword & 0xFFFF); a.addWord(bitmask & 0xFFFF); a.addStringT(name); - // and this needs sending in the length word. if (!sendCommand(SFSTAT, a)) return E_PSI_FILE_DISC; return getResponse(a); @@ -323,41 +298,17 @@ fsetattr(const char *name, u_int32_t seta, u_int32_t unseta) Enum rfsv16:: dircount(const char * const name, u_int32_t &count) { - u_int32_t fileHandle; - Enum res; - count = 0; - - res = fopen(P_FDIR, name, fileHandle); - if (res != E_PSI_GEN_NONE) - return res; - - while (1) { - bufferStore a; - a.addWord(fileHandle & 0xFFFF); - if (!sendCommand(FDIRREAD, a)) - return E_PSI_FILE_DISC; - res = getResponse(a); - if (res != E_PSI_GEN_NONE) - break; - a.discardFirstBytes(2); // Don't know what these mean! - while (a.getLen() > 16) { - int version = a.getWord(0); - if (version != 2) { - cerr << "dir: not version 2" << endl; - fclose(fileHandle); - return E_PSI_GEN_FAIL; - } - // int status = a.getWord(2); - // long size = a.getDWord(4); - // long date = a.getDWord(8); - const char *s = a.getString(16); - a.discardFirstBytes(17+strlen(s)); + rfsvDirhandle h; + Enum res = opendir(PSI_A_HIDDEN|PSI_A_SYSTEM|PSI_A_DIR, name, h); + while (res == E_PSI_GEN_NONE) { + PlpDirent e; + res = readdir(h, e); + if (res == E_PSI_GEN_NONE) count++; - } } + closedir(h); if (res == E_PSI_FILE_EOF) res = E_PSI_GEN_NONE; - fclose(fileHandle); return res; } @@ -439,7 +390,6 @@ devinfo(const char drive, PlpDrive &dinfo) { bufferStore a; Enum res; - // long fileHandle; // Again, this is taken from an exchange between PsiWin and a 3c. // For each drive, we PARSE with its drive letter to get a response @@ -454,10 +404,8 @@ devinfo(const char drive, PlpDrive &dinfo) a.addByte(0x00); // No name 3 if (!sendCommand(PARSE, a)) return E_PSI_FILE_DISC; - if ((res = getResponse(a)) != E_PSI_GEN_NONE) { - // cerr << "devinfo PARSE res is " << dec << (signed short int) res << endl; + if ((res = getResponse(a)) != E_PSI_GEN_NONE) return res; - } a.init(); a.addByte(toupper(drive)); // Name 1 @@ -466,10 +414,8 @@ devinfo(const char drive, PlpDrive &dinfo) a.addByte(0x00); if (!sendCommand(STATUSDEVICE, a)) return E_PSI_FILE_DISC; - if ((res = getResponse(a)) != E_PSI_GEN_NONE) { - // cerr << "devinfo STATUSDEVICE res is " << dec << (signed short int) res << endl; + if ((res = getResponse(a)) != E_PSI_GEN_NONE) return res; - } int attr = a.getWord(2); attr = sibo_dattr[a.getWord(2) & 0xff]; @@ -867,13 +813,7 @@ mkdir(const char* dirName) bufferStore a; a.addStringT(realName.c_str()); sendCommand(MKDIR, a); - Enum res = getResponse(a); - if (res == E_PSI_GEN_NONE) { - // Correct response - return res; - } - cerr << "Unknown response from mkdir "<< res < rfsv16:: @@ -887,39 +827,24 @@ rmdir(const char *dirName) Enum rfsv16:: rename(const char *oldName, const char *newName) { - cerr << "rfsv16::rename ***" << endl; - string realOldName = convertSlash(oldName); string realNewName = convertSlash(newName); bufferStore a; a.addStringT(realOldName.c_str()); a.addStringT(realNewName.c_str()); sendCommand(RENAME, a); - Enum res = getResponse(a); - if (res == E_PSI_GEN_NONE) { - // Correct response - return res; - } - cerr << "Unknown response from rename "<< res < rfsv16:: remove(const char* psionName) { - Enum res; string realName = convertSlash(psionName); bufferStore a; a.addStringT(realName.c_str()); // and this needs sending in the length word. sendCommand(DELETE, a); - res = getResponse(a); - if (res == E_PSI_GEN_NONE) { - // Correct response - return res; - } - cerr << "Unknown response from delete "<< res < rfsv16:: diff --git a/lib/rpcs.cc b/lib/rpcs.cc index 6cf7fee..bc24272 100644 --- a/lib/rpcs.cc +++ b/lib/rpcs.cc @@ -25,6 +25,7 @@ #endif #include +#include #include #include #include @@ -35,6 +36,7 @@ #include "bufferstore.h" #include "ppsocket.h" #include "bufferarray.h" +#include "psiprocess.h" #include "Enum.h" ENUM_DEFINITION(rpcs::machs, rpcs::PSI_MACH_UNKNOWN) { @@ -110,6 +112,7 @@ void rpcs:: reset(void) { bufferStore a; + mtCacheS5mx = 0; status = rfsv::E_PSI_FILE_DISC; a.addStringT(getConnectName()); if (skt->sendBufferStore(a)) { @@ -215,10 +218,11 @@ execProgram(const char *program, const char *args) * Without this hack, The Drive-Character gets lost. Other apps don't * seem to be hurt by the additional blank. */ - a.addByte(strlen(args) + 1); + a.addByte(strlen(args)+1); a.addByte(' '); a.addStringT(args); + if (!sendCommand(EXEC_PROG, a)) return rfsv::E_PSI_FILE_DISC; return getResponse(a, true); @@ -246,6 +250,82 @@ queryProgram(const char *program) return getResponse(a, true); } +Enum rpcs:: +queryPrograms(processList &ret) +{ + bufferStore a; + const char *drives; + const char *dptr; + bool anySuccess = false; + Enum res; + + // First, check how many drives we need to query + a.addStringT("M:"); // Drive M only exists on a SIBO + if (!sendCommand(rpcs::GET_UNIQUEID, a)) + return rfsv::E_PSI_FILE_DISC; + if (getResponse(a, false) == rfsv::E_PSI_GEN_NONE) + // A SIBO; Must query all possible drives + drives = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + else + // A Series 5; Query of C is sufficient + drives = "C"; + + dptr = drives; + ret.clear(); + + if ((mtCacheS5mx & 4) == 0) { + Enum tmp; + if (getMachineType(tmp) != rfsv::E_PSI_GEN_NONE) + return rfsv::E_PSI_GEN_FAIL; + + } + if ((mtCacheS5mx & 9) == 1) { + machineInfo tmp; + if (getMachineInfo(tmp) == rfsv::E_PSI_FILE_DISC) + return rfsv::E_PSI_FILE_DISC; + } + bool s5mx = (mtCacheS5mx == 15); + while (*dptr) { + a.init(); + a.addByte(*dptr); + if (!sendCommand(rpcs::QUERY_DRIVE, a)) + return rfsv::E_PSI_FILE_DISC; + if (getResponse(a, false) == rfsv::E_PSI_GEN_NONE) { + anySuccess = true; + int l = a.getLen(); + while (l > 0) { + const char *s; + char *p; + int pid; + int sl; + + s = a.getString(0); + sl = strlen(s) + 1; + l -= sl; + a.discardFirstBytes(sl); + if ((p = strstr(s, ".$"))) { + *p = '\0'; p += 2; + sscanf(p, "%d", &pid); + } else + pid = 0; + PsiProcess proc(pid, s, a.getString(0), s5mx); + ret.push_back(proc); + sl = strlen(a.getString(0)) + 1; + l -= sl; + a.discardFirstBytes(sl); + } + } + dptr++; + } + if (anySuccess && !ret.empty()) + for (processList::iterator i = ret.begin(); i != ret.end(); i++) { + string cmdline; + if (getCmdLine(i->getProcId(), cmdline) == rfsv::E_PSI_GEN_NONE) + i->setArgs(cmdline + " " + i->getArgs()); + } + return anySuccess ? rfsv::E_PSI_GEN_NONE : rfsv::E_PSI_GEN_FAIL; +} + Enum rpcs:: formatOpen(const char drive, int &handle, int &count) { @@ -339,6 +419,11 @@ getMachineType(Enum &type) if (a.getLen() != 2) return rfsv::E_PSI_GEN_FAIL; type = (enum machs)a.getWord(0); + mtCacheS5mx |= 4; + if (res == rfsv::E_PSI_GEN_NONE) { + if (type == rpcs::PSI_MACH_S5) + mtCacheS5mx |= 1; + } return res; } diff --git a/lib/rpcs.h b/lib/rpcs.h index 5a64013..9d1e736 100644 --- a/lib/rpcs.h +++ b/lib/rpcs.h @@ -3,7 +3,7 @@ * * This file is part of plptools. * - * Copyright (C) 1999-2001 Fritz Elfert + * Copyright (C) 1999-2002 Fritz Elfert * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,7 +23,9 @@ #ifndef _RPCS_H_ #define _RPCS_H_ +#include #include +#include #include #include @@ -31,6 +33,8 @@ class ppsocket; class bufferStore; class bufferArray; +typedef vector processList; + /** * Remote procedure call services via PLP * @@ -312,20 +316,32 @@ public: */ Enum quitServer(void); - // API different on SIBO and EPOC - virtual Enum queryDrive(const char, bufferArray &) = 0; + /** + * Retrieves a list of all running Programs. + * + * This function works with both SIBO and EPOC. + * + * @param ret The list of currently running processes is returned here. + * + * @returns A psion error code. 0 = Ok. + */ + Enum queryPrograms(processList &ret); + /** * Retrieves the command line of a running process. * - * This function works with EPOC only. Using it with SIBO - * machines, returns always an error code E_PSI_NOT_SIBO. + * This function works with both SIBO and EPOC. + * Note: @ref rfsv::getPrograms calls this method internally and sets + * the args member of @ref PsiProcess , so you usually don't have to call + * this method yourself. * * @param process Name of process. Format: processname.$pid * @param ret The program name and arguments are returned here. * * @return Psion error code. 0 = Ok. */ - virtual Enum getCmdLine(const char *process, bufferStore &ret) = 0; + virtual Enum getCmdLine(const char *process, string &ret) = 0; + /** * Retrieve general Information about the connected * machine. @@ -337,6 +353,7 @@ public: * @return Psion error code. 0 = Ok. */ virtual Enum getMachineInfo(machineInfo &) { return rfsv::E_PSI_NOT_SIBO;} + virtual Enum closeHandle(int) { return rfsv::E_PSI_NOT_SIBO;} virtual Enum regOpenIter(u_int32_t, char *, u_int16_t &) { return rfsv::E_PSI_NOT_SIBO;} virtual Enum regReadIter(u_int16_t) { return rfsv::E_PSI_NOT_SIBO;} @@ -393,6 +410,12 @@ protected: QUIT_SERVER = 0xff }; + /** + * Flag: getMachineType and getMachineInfo have been called and the + * machine is an S5mx. + */ + int mtCacheS5mx; + /** * Sends a command to the remote side. * diff --git a/lib/rpcs16.cc b/lib/rpcs16.cc index a65c937..ce13b4d 100644 --- a/lib/rpcs16.cc +++ b/lib/rpcs16.cc @@ -26,6 +26,7 @@ #endif #include +#include #include #include #include @@ -34,32 +35,30 @@ #include "rpcs16.h" #include "bufferstore.h" +#include "bufferarray.h" #include "ppsocket.h" rpcs16::rpcs16(ppsocket * _skt) { skt = _skt; + mtCacheS5mx = 0; reset(); } Enum rpcs16:: -queryDrive(char drive, bufferArray &ret) +getCmdLine(const char *process, string &ret) { bufferStore a; - a.addByte(drive); - if (!sendCommand(rpcs::QUERY_DRIVE, a)) + Enum res; + + a.addStringT(process); + if (!sendCommand(rpcs::GET_CMDLINE, a)) return rfsv::E_PSI_FILE_DISC; - Enum res = getResponse(a, true); - cout << dec << "qd: " << res << " " << a.getLen() << " a="<< a << endl; + if ((res = getResponse(a, true)) == rfsv::E_PSI_GEN_NONE) + ret = a.getString(0); return res; } -Enum rpcs16:: -getCmdLine(const char *process, bufferStore &ret) -{ - return rfsv::E_PSI_GEN_NONE; -} - /* * Local variables: * c-basic-offset: 4 diff --git a/lib/rpcs16.h b/lib/rpcs16.h index 91b0463..35c5a1c 100644 --- a/lib/rpcs16.h +++ b/lib/rpcs16.h @@ -4,7 +4,7 @@ * This file is part of plptools. * * Copyright (C) 1999 Philip Proudman - * Copyright (C) 1999-2001 Fritz Elfert + * Copyright (C) 1999-2002 Fritz Elfert * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -41,8 +41,7 @@ class rpcs16 : public rpcs { friend rpcsfactory; public: - Enum queryDrive(const char, bufferArray &); - Enum getCmdLine(const char *, bufferStore &); + Enum getCmdLine(const char *, string &); private: rpcs16(ppsocket *); diff --git a/lib/rpcs32.cc b/lib/rpcs32.cc index ebb4f9c..92132af 100644 --- a/lib/rpcs32.cc +++ b/lib/rpcs32.cc @@ -40,53 +40,12 @@ rpcs32::rpcs32(ppsocket * _skt) { skt = _skt; + mtCacheS5mx = 0; reset(); } Enum rpcs32:: -queryDrive(char drive, bufferArray &ret) -{ - bufferStore a; - Enum res; - - a.addByte(drive); - if (!sendCommand(rpcs::QUERY_DRIVE, a)) - return rfsv::E_PSI_FILE_DISC; - if ((res = getResponse(a, false)) != rfsv::E_PSI_GEN_NONE) - return res; - int l = a.getLen(); - ret.clear(); - while (l > 0) { - bufferStore b, c; - const char *s; - char *p; - int pid; - int sl; - - s = a.getString(0); - sl = strlen(s) + 1; - l -= sl; - a.discardFirstBytes(sl); - if ((p = strstr(s, ".$"))) { - *p = '\0'; p += 2; - sscanf(p, "%d", &pid); - } else - pid = 0; - b.addWord(pid); - b.addStringT(s); - s = a.getString(0); - sl = strlen(s) + 1; - l -= sl; - a.discardFirstBytes(sl); - c.addStringT(s); - ret.push(c); - ret.push(b); - } - return res; -} - -Enum rpcs32:: -getCmdLine(const char *process, bufferStore &ret) +getCmdLine(const char *process, string &ret) { bufferStore a; Enum res; @@ -94,8 +53,8 @@ getCmdLine(const char *process, bufferStore &ret) a.addStringT(process); if (!sendCommand(rpcs::GET_CMDLINE, a)) return rfsv::E_PSI_FILE_DISC; - res = getResponse(a, true); - ret = a; + if ((res = getResponse(a, true)) == rfsv::E_PSI_GEN_NONE) + ret = a.getString(0); return res; } @@ -163,6 +122,12 @@ getMachineInfo(machineInfo &mi) mi.externalPower = (a.getDWord(120) != 0); + mtCacheS5mx |= 8; + if (res == rfsv::E_PSI_GEN_NONE) { + if (!strcmp(mi.machineName, "SERIES5mx")) + mtCacheS5mx |= 2; + } + return res; } diff --git a/lib/rpcs32.h b/lib/rpcs32.h index 70644da..9fc9ebb 100644 --- a/lib/rpcs32.h +++ b/lib/rpcs32.h @@ -4,7 +4,7 @@ * This file is part of plptools. * * Copyright (C) 1999 Philip Proudman - * Copyright (C) 1999-2001 Fritz Elfert + * Copyright (C) 1999-2002 Fritz Elfert * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -40,8 +40,7 @@ class rpcs32 : public rpcs { friend rpcsfactory; public: - Enum queryDrive(const char, bufferArray &); - Enum getCmdLine(const char *, bufferStore &); + Enum getCmdLine(const char *, string &); Enum getMachineInfo(machineInfo &); Enum configOpen(void); Enum configRead(void); -- cgit v1.2.3