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 --- kde2/kpsion/Makefile.am | 2 +- kde2/kpsion/kpsion.cpp | 112 +++++++++++++++++++++++++++---------- 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 +- plpbackup/plpbackup.cc | 31 ++--------- plpftp/ftp.cc | 96 +++++++++++--------------------- plpnfsd/main.cc | 19 +++---- 18 files changed, 571 insertions(+), 311 deletions(-) create mode 100644 lib/psiprocess.cc create mode 100644 lib/psiprocess.h diff --git a/kde2/kpsion/Makefile.am b/kde2/kpsion/Makefile.am index 1ec1da4..c34a60f 100644 --- a/kde2/kpsion/Makefile.am +++ b/kde2/kpsion/Makefile.am @@ -23,7 +23,7 @@ libkpsion_la_SOURCES = kpsion.cpp setupdialog.cpp wizards.cpp \ statusbarprogress.cpp kpsionconfig.cpp kpsionbackuplistview.cpp \ kpsionrestoredialog.cpp -libkpsion_la_LIBADD = -L$(top_srcdir)/lib -lplp $(LIB_KFILE) +libkpsion_la_LIBADD = $(top_srcdir)/lib/libplp.la $(LIB_KFILE) kpsion_SOURCES = main.cpp kpsion_LDFLAGS = $(KDE_RPATH) diff --git a/kde2/kpsion/kpsion.cpp b/kde2/kpsion/kpsion.cpp index 6ba36a7..f7e011f 100644 --- a/kde2/kpsion/kpsion.cpp +++ b/kde2/kpsion/kpsion.cpp @@ -3,8 +3,7 @@ * * This file is part of plptools. * - * Copyright (C) 1999 Philip Proudman - * 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 @@ -51,6 +50,7 @@ #include #include #include +#include #define STID_CONNECTION 1 @@ -292,15 +292,84 @@ queryPsion() { statusBar()->changeItem(i18n("Retrieving machine info ..."), STID_CONNECTION); - rpcs::machineInfo mi; - if ((res = plpRpcs->getMachineInfo(mi)) != rfsv::E_PSI_GEN_NONE) { - QString msg = i18n("Could not get Psion machine info"); + + Enum machType; + if (plpRpcs->getMachineType(machType) != rfsv::E_PSI_GEN_NONE) { + QString msg = i18n("Could not get Psion machine type"); statusBar()->changeItem(msg, STID_CONNECTION); KMessageBox::error(this, msg); return; } - machineUID = mi.machineUID; - S5mx = (strcmp(mi.machineName, "SERIES5mx") == 0); + if (machType == rpcs::PSI_MACH_S5) { + rpcs::machineInfo mi; + if ((res = plpRpcs->getMachineInfo(mi)) != rfsv::E_PSI_GEN_NONE) { + QString msg = i18n("Could not get Psion machine info"); + statusBar()->changeItem(msg, STID_CONNECTION); + KMessageBox::error(this, msg); + return; + } + machineUID = mi.machineUID; + S5mx = (strcmp(mi.machineName, "SERIES5mx") == 0); + } else { + // On a SIBO, first check for a file 'SYS$PT.CFG' on the default + // directory. If it exists, read the UID from it. Otherwise + // calculate a virtual machine UID from the OwnerInfo data and + // write it to that file. + bufferArray b; + u_int32_t handle; + u_int32_t count; + + res = plpRfsv->fopen(plpRfsv->opMode(rfsv::PSI_O_RDONLY), + "SYS$PT.CFG", handle); + if (res == rfsv::E_PSI_GEN_NONE) { + res = plpRfsv->fread(handle, (unsigned char *)&machineUID, + sizeof(machineUID), count); + plpRfsv->fclose(handle); + if ((res != rfsv::E_PSI_GEN_NONE) || (count != sizeof(machineUID))) { + QString msg = i18n("Could not read SIBO UID file"); + statusBar()->changeItem(msg, STID_CONNECTION); + KMessageBox::error(this, msg); + return; + } + } else { + if ((res = plpRpcs->getOwnerInfo(b)) != rfsv::E_PSI_GEN_NONE) { + QString msg = i18n("Could not get Psion owner info"); + statusBar()->changeItem(msg, STID_CONNECTION); + KMessageBox::error(this, msg); + return; + } + machineUID = 0; + string oi = ""; + while (!b.empty()) { + oi += b.pop().getString(); + oi += "\n"; + } + const char *p = oi.c_str(); + unsigned long long z; + int i = 0; + + while (*p) { + z = *p; + machineUID ^= (z << i); + p++; i++; + i &= ((sizeof(machineUID) * 8) - 1); + } + res = plpRfsv->fcreatefile(plpRfsv->opMode(rfsv::PSI_O_RDWR), + "SYS$PT.CFG", handle); + if (res == rfsv::E_PSI_GEN_NONE) { + res = plpRfsv->fwrite(handle, (const unsigned char *)&machineUID, + sizeof(machineUID), count); + plpRfsv->fclose(handle); + } + if (res != rfsv::E_PSI_GEN_NONE) { + QString msg = i18n("Could not write SIBO UID file %1").arg((const char *)res); + statusBar()->changeItem(msg, STID_CONNECTION); + KMessageBox::error(this, msg); + return; + } + } + S5mx = false; + } QString uid = getMachineUID(); bool machineFound = false; @@ -1603,33 +1672,18 @@ collectFiles(QString dir) { void KPsionMainWindow:: killSave() { Enum res; - bufferArray tmp; + processList tmp; savedCommands.clear(); - if ((res = plpRpcs->queryDrive('C', tmp)) != rfsv::E_PSI_GEN_NONE) { + if ((res = plpRpcs->queryPrograms(tmp)) != rfsv::E_PSI_GEN_NONE) { cerr << "Could not get process list, Error: " << res << endl; return; } else { - while (!tmp.empty()) { - QString pbuf; - bufferStore cmdargs; - bufferStore bs = tmp.pop(); - int pid = bs.getWord(0); - const char *proc = bs.getString(2); - if (S5mx) - pbuf.sprintf("%s.$%02d", proc, pid); - else - pbuf.sprintf("%s.$%d", proc, pid); - bs = tmp.pop(); - if (plpRpcs->getCmdLine(pbuf.data(), cmdargs) == 0) { - QString cmdline(cmdargs.getString(0)); - cmdline += " "; - cmdline += bs.getString(0); - savedCommands += cmdline; - } - emit setProgressText(i18n("Stopping %1").arg(cmdargs.getString(0))); + for (processList::iterator i = tmp.begin(); i != tmp.end(); i++) { + savedCommands += i->getArgs(); + emit setProgressText(i18n("Stopping %1").arg(i->getName())); kapp->processEvents(); - plpRpcs->stopProgram(pbuf); + plpRpcs->stopProgram(i->getProcId()); } } time_t tstart = time(0) + 5; @@ -1637,7 +1691,7 @@ killSave() { kapp->processEvents(); usleep(100000); kapp->processEvents(); - if ((res = plpRpcs->queryDrive('C', tmp)) != rfsv::E_PSI_GEN_NONE) { + if ((res = plpRpcs->queryPrograms(tmp)) != rfsv::E_PSI_GEN_NONE) { cerr << "Could not get process list, Error: " << res << endl; return; } 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); diff --git a/plpbackup/plpbackup.cc b/plpbackup/plpbackup.cc index cbd211c..4c111a7 100644 --- a/plpbackup/plpbackup.cc +++ b/plpbackup/plpbackup.cc @@ -160,43 +160,24 @@ checkAbort() static int stopPrograms() { Enum res; - bufferArray tmp; + processList tmp; if (verbose > 0) cout << _("Stopping programs ...") << endl; - if ((res = Rpcs->queryDrive('C', tmp)) != rfsv::E_PSI_GEN_NONE) { + if ((res = Rpcs->queryPrograms(tmp)) != rfsv::E_PSI_GEN_NONE) { cerr << _("plpbackup: Could not get process list: ") << res << endl; return 1; } else { - while (!tmp.empty()) { - ostrstream pbuf; - bufferStore cmdargs; - bufferStore bs = tmp.pop(); - int pid = bs.getWord(0); - - pbuf << bs.getString(2) << ".$"; - if (S5mx) - pbuf << dec << setw(2) << setfill(0) << pid; - else - pbuf << dec << pid; - pbuf << '\0'; - bs = tmp.pop(); - if (Rpcs->getCmdLine(pbuf.str(), cmdargs) == 0) { - string cmdline = cmdargs.getString(0); - cmdline += " "; - cmdline += bs.getString(0); - savedCommands.push_back(cmdline); - if (verbose > 1) - cout << cmdline << endl; - } - Rpcs->stopProgram(pbuf.str()); + for (processList::iterator i = tmp.begin(); i != tmp.end(); i++) { + savedCommands.push_back(i->getArgs()); + Rpcs->stopProgram(i->getProcId()); } time_t tstart = time(0) + 5; while (true) { usleep(100000); if (checkAbort()) return 1; - if ((res = Rpcs->queryDrive('C', tmp)) != rfsv::E_PSI_GEN_NONE) { + if ((res = Rpcs->queryPrograms(tmp)) != rfsv::E_PSI_GEN_NONE) { cerr << "Could not get process list, Error: " << res << endl; return 1; } diff --git a/plpftp/ftp.cc b/plpftp/ftp.cc index c94afc4..1b0545a 100644 --- a/plpftp/ftp.cc +++ b/plpftp/ftp.cc @@ -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 @@ -208,7 +208,6 @@ session(rfsv & a, rpcs & r, int xargc, char **xargv) Enum res; bool prompt = true; bool hash = false; - bool S5mx = false; cpCallback_t cab = checkAbortNoHash; bool once = false; @@ -231,13 +230,6 @@ session(rfsv & a, rpcs & r, int xargc, char **xargv) cout << " " << b.pop().getString() << endl; cout << endl; } - if (machType == rpcs::PSI_MACH_S5) { - rpcs::machineInfo mi; - if ((res = r.getMachineInfo(mi)) == rfsv::E_PSI_GEN_NONE) { - if (!strcmp(mi.machineName, "SERIES5mx")) - S5mx = true; - } - } } else cerr << _("OwnerInfo returned error ") << res << endl; } @@ -426,12 +418,16 @@ session(rfsv & a, rpcs & r, int xargc, char **xargv) if ((devbits & 1) != 0) { if (a.devinfo(i + 'A', drive) == rfsv::E_PSI_GEN_NONE) - cout << (char) ('A' + i) << " " << - hex << setw(4) << setfill('0') << drive.getMediaType() << " " << - setw(12) << setfill(' ') << setiosflags(ios::left) << - drive.getName().c_str() << resetiosflags(ios::left) << dec << setw(9) << - drive.getSize() << setw(9) << drive.getSpace() << " " << setw(8) << setfill('0') << hex << - drive.getUID() << endl; + cout << (char) ('A' + i) << " " << hex + << setw(4) << setfill('0') + << drive.getMediaType() << " " << setw(12) + << setfill(' ') << setiosflags(ios::left) + << drive.getName().c_str() + << resetiosflags(ios::left) << dec << setw(9) + << drive.getSize() << setw(9) + << drive.getSpace() << " " << setw(8) + << setfill('0') << hex << drive.getUID() + << dec << endl; } devbits >>= 1; } @@ -476,7 +472,7 @@ session(rfsv & a, rpcs & r, int xargc, char **xargv) strcpy(dtmp, f1); dname = dtmp; } - + if ((res = a.dir(dname, files)) != rfsv::E_PSI_GEN_NONE) cerr << _("Error: ") << res << endl; else @@ -575,7 +571,7 @@ session(rfsv & a, rpcs & r, int xargc, char **xargv) dt += dsec; stat(f2, &stbuf); float cps = (float)(stbuf.st_size) / dt; - cout << _("Transfer complete, (") << stbuf.st_size + cout << _("Transfer complete, (") << dec << stbuf.st_size << _(" bytes in ") << dsec << "." << dhse << _(" secs = ") << cps << " cps)\n"; } @@ -666,7 +662,7 @@ session(rfsv & a, rpcs & r, int xargc, char **xargv) dt += dsec; stat(f1, &stbuf); float cps = (float)(stbuf.st_size) / dt; - cout << _("Transfer complete, (") << stbuf.st_size + cout << _("Transfer complete, (") << dec << stbuf.st_size << _(" bytes in ") << dsec << "." << dhse << _(" secs = ") << cps << " cps)\n"; } @@ -771,7 +767,8 @@ session(rfsv & a, rpcs & r, int xargc, char **xargv) #ifdef EXPERIMENTAL if (!strcmp(argv[0], "x")) { u_int16_t hhh; - if (r.regOpenIter(-1, "%PDF-", hhh) == rfsv::E_PSI_GEN_NONE) { + if (r.regOpenIter((u_int32_t)-1, "%PDF-", hhh) + == rfsv::E_PSI_GEN_NONE) { Enum res; while ((res = r.regReadIter(hhh)) == rfsv::E_PSI_GEN_NONE) ;; @@ -795,7 +792,7 @@ session(rfsv & a, rpcs & r, int xargc, char **xargv) } else strcpy(argbuf, argv[i]); } - if (argv[1][1] != ':') { + if (!strchr(argv[1], ':')) { strcpy(cmdbuf, psionDir); strcat(cmdbuf, argv[1]); } else @@ -926,8 +923,8 @@ session(rfsv & a, rpcs & r, int xargc, char **xargv) continue; } if (!strcmp(argv[0], "killsave") && (argc == 2)) { - bufferArray tmp; - if ((res = r.queryDrive('C', tmp)) != rfsv::E_PSI_GEN_NONE) + processList tmp; + if ((res = r.queryPrograms(tmp)) != rfsv::E_PSI_GEN_NONE) cerr << _("Error: ") << res << endl; else { ofstream op(argv[1]); @@ -936,51 +933,31 @@ session(rfsv & a, rpcs & r, int xargc, char **xargv) continue; } op << "#plpftp processlist" << endl; - while (!tmp.empty()) { - char pbuf[128]; - bufferStore cmdargs; - bufferStore bs = tmp.pop(); - int pid = bs.getWord(0); - const char *proc = bs.getString(2); - if (S5mx) - sprintf(pbuf, "%s.$%02d", proc, pid); - else - sprintf(pbuf, "%s.$%d", proc, pid); - bs = tmp.pop(); - if (r.getCmdLine(pbuf, cmdargs) == 0) - op << cmdargs.getString(0) << " " << bs.getString(0) << endl; - r.stopProgram(pbuf); + processList::iterator i; + for (i = tmp.begin(); i != tmp.end(); i++) { + op << i->getArgs() << endl; + r.stopProgram(i->getProcId()); } op.close(); } continue; } if (!strcmp(argv[0], "kill") && (argc >= 2)) { - bufferArray tmp, tmp2; + processList tmp; bool anykilled = false; - if ((res = r.queryDrive('C', tmp)) != rfsv::E_PSI_GEN_NONE) + if ((res = r.queryPrograms(tmp)) != rfsv::E_PSI_GEN_NONE) cerr << _("Error: ") << res << endl; else { - tmp2 = tmp; for (int i = 1; i < argc; i++) { int kpid; - tmp = tmp2; if (!strcmp(argv[i], "all")) kpid = -1; else sscanf(argv[i], "%d", &kpid); - while (!tmp.empty()) { - bufferStore bs = tmp.pop(); - tmp.pop(); - int pid = bs.getWord(0); - const char *proc = bs.getString(2); - if (kpid == -1 || kpid == pid) { - char pbuf[128]; - if (S5mx) - sprintf(pbuf, "%s.$%02d", proc, pid); - else - sprintf(pbuf, "%s.$%d", proc, pid); - r.stopProgram(pbuf); + processList::iterator j; + for (j = tmp.begin(); j != tmp.end(); j++) { + if (kpid == -1 || kpid == j->getPID()) { + r.stopProgram(j->getProcId()); anykilled = true; } } @@ -993,20 +970,13 @@ session(rfsv & a, rpcs & r, int xargc, char **xargv) continue; } if (!strcmp(argv[0], "ps")) { - bufferArray tmp; - if ((res = r.queryDrive('C', tmp)) != rfsv::E_PSI_GEN_NONE) + processList tmp; + if ((res = r.queryPrograms(tmp)) != rfsv::E_PSI_GEN_NONE) cerr << _("Error: ") << res << endl; else { cout << "PID CMD ARGS" << endl; - while (!tmp.empty()) { - bufferStore bs = tmp.pop(); - bufferStore bs2 = tmp.pop(); - int pid = bs.getWord(0); - const char *proc = bs.getString(2); - const char *arg = bs2.getString(); - - printf("%5d %-12s %s\n", pid, proc, arg); - } + for (processList::iterator i = tmp.begin(); i != tmp.end(); i++) + cout << *i << endl; } continue; } diff --git a/plpnfsd/main.cc b/plpnfsd/main.cc index b7f6740..882168f 100644 --- a/plpnfsd/main.cc +++ b/plpnfsd/main.cc @@ -116,23 +116,22 @@ static long psread(builtin_node *node, char *buf, unsigned long offset, long len long rpcs_ps() { Enum res; - bufferArray psbuf; + processList psbuf; if (!rpcs_isalive()) return -1; - res = r->queryDrive('C', psbuf); + res = r->queryPrograms(psbuf); if (res != rfsv::E_PSI_GEN_NONE) return -1; - while (!psbuf.empty()) { + processList::iterator i; + for (i = psbuf.begin(); i != psbuf.end(); i++) { builtin_node *dn; builtin_node *fn1; builtin_node *fn2; builtin_node *bn; char bname[40]; - bufferStore bs = psbuf.pop(); - bufferStore bs2 = psbuf.pop(); - sprintf(bname, "%d", bs.getWord(0)); + sprintf(bname, "%d", i->getPID()); dn = (builtin_node *)malloc(sizeof(builtin_node)); if (!dn) @@ -163,7 +162,7 @@ long rpcs_ps() { fn1->name = "cmd"; fn1->attr = PSI_A_READ | PSI_A_RDONLY; - fn1->private_data = (char *)malloc(strlen(bs.getString(2))+2); + fn1->private_data = (char *)malloc(strlen(i->getName())+2); if (!fn1->private_data) { free(fn1); free(fn2); @@ -171,12 +170,12 @@ long rpcs_ps() { return -1; } fn1->read = psread; - sprintf(fn1->private_data, "%s\n", bs.getString(2)); + sprintf(fn1->private_data, "%s\n", i->getName()); fn1->size = strlen(fn1->private_data); fn2->name = "args"; fn2->attr = PSI_A_READ | PSI_A_RDONLY; - fn2->private_data = (char *)malloc(strlen(bs2.getString())+2); + fn2->private_data = (char *)malloc(strlen(i->getArgs())+2); if (!fn2->private_data) { free(fn1->private_data); free(fn1); @@ -185,7 +184,7 @@ long rpcs_ps() { return -1; } fn2->read = psread; - sprintf(fn2->private_data, "%s\n", bs2.getString()); + sprintf(fn2->private_data, "%s\n", i->getArgs()); fn2->size = strlen(fn2->private_data); if (!(bn = register_builtin("proc", dn))) { -- cgit v1.2.3