diff options
author | Fritz Elfert <felfert@to.com> | 2001-03-01 00:22:23 +0000 |
---|---|---|
committer | Fritz Elfert <felfert@to.com> | 2001-03-01 00:22:23 +0000 |
commit | 75007da068aac10fed90fc5234ab2d50deed3e61 (patch) | |
tree | be0a8ebba9bad4ccab4600c60d9e7fcc21dc7837 | |
parent | d8ae774198cf180fcaa4a2512dd94b4dbfdfd72d (diff) | |
download | plptools-75007da068aac10fed90fc5234ab2d50deed3e61.tar.gz plptools-75007da068aac10fed90fc5234ab2d50deed3e61.tar.bz2 plptools-75007da068aac10fed90fc5234ab2d50deed3e61.zip |
Modified icons.
Started NLS support.
Added kpsion KDE2 application.
Unified file-headers.
100 files changed, 14690 insertions, 7948 deletions
diff --git a/Makefile.am b/Makefile.am index 9ab1ebf..2a302e2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -7,8 +7,8 @@ else KDESUB = endif -SUBDIRS = lib ncpd plpnfsd plpftp plpbackup $(KDESUB) doc -EXTRA_DIST = CHANGES COPYING README TODO INSTALL README.mjg include/*.h* etc/*magic etc/*.in patches +SUBDIRS = intl po lib ncpd plpnfsd plpftp plpbackup $(KDESUB) doc +EXTRA_DIST = CHANGES COPYING README TODO INSTALL README.mjg ABOUT-NLS include/*.h* etc/*magic etc/*.in patches DISTCLEANFILES = etc/psion AUTOMAKE_OPTIONS = foreign diff --git a/Makefile.cvs b/Makefile.cvs index 9f5035e..cdb8842 100644 --- a/Makefile.cvs +++ b/Makefile.cvs @@ -6,6 +6,10 @@ ACLOCAL = conf/aclocal.m4 all: @echo "Use make devel for development, make dist for distribution" +build: devel + ./configure --prefix=/usr --mandir=/usr/share/man --enable-debug --enable-kde + make + devel: $(LIBTOOLFILES) $(AUTOMAKEFILES) aclocal -I conf/m4/plptools -I conf/m4/kde autoheader @@ -12,6 +12,21 @@ /* Define if the C++ compiler supports BOOL */ #undef HAVE_BOOL +/* Define this, if you want NLS support */ +#undef ENABLE_NLS + +/* Define this, if you have catgets */ +#undef HAVE_CATGETS + +/* Define this, if you have gettext */ +#undef HAVE_GETTEXT + +/* Define this, if you have stpcpy */ +#undef HAVE_STPCPY + +/* Define this, if your locale.h defines LC_MESSAGES */ +#undef HAVE_LC_MESSAGES + /* The package version */ #undef VERSION diff --git a/configure.in b/configure.in index bbe1dd5..c781781 100644 --- a/configure.in +++ b/configure.in @@ -19,6 +19,10 @@ PLP_CHECK_COMPILERS AC_PROG_AWK AC_PATH_PROG(SED,sed) +dnl NLS support +ALL_LINGUAS="de" +AM_GNU_GETTEXT + dnl This is stupid for two resaons: dnl dnl 1. It doesn't save and restore CFLAGS if it's _not_ Sun's cc @@ -129,6 +133,42 @@ AC_TYPE_SIGNAL dnl checks for header files AC_CHECK_HEADERS(sys/ioctl.h sys/errno.h sys/ttold.h stdlib.h) +PLP_HELP_MSG([Debugging (developer only!):]) +LIBCCMALLOC= +AC_ARG_WITH(ccmalloc, + [ --with-ccmalloc=DIR link against ccmalloc leak-checking lib], + [ + search_dirs="/usr/lib /lib /usr/local/lib" + case "${withval}" in + yes) + ccmalloc_dirs=${search_dirs} + ;; + no) + ccmalloc_dirs= + ;; + *) + ccmalloc_dirs="${withval} ${search_dirs}" + ;; + esac + AC_MSG_CHECKING(for libccmalloc) + save_LIBS="$LIBS" + ccmalloc_found=NO + for d in ${ccmalloc_dirs} ; do + LIBS="-L$d -lccmalloc -ldl" + AC_TRY_LINK_FUNC(ccmalloc_report,ccmalloc_found=$d ; break) + done + LIBS="$save_LIBS" + if test "${ccmalloc_found}" = "NO" ; then + AC_MSG_RESULT(not found) + else + AC_MSG_RESULT(found) + LIBCCMALLOC="-L$ccmalloc_found -lccmalloc -ldl" + fi + ] +) +AC_SUBST(LIBCCMALLOC) + + dnl special options for customization PLP_HELP_MSG([Options for overriding builtin defaults:]) @@ -216,11 +256,14 @@ if test "x$ac_enable_kde" = "xyes" ; then AC_PATH_KDE AC_CHECK_KDEMAXPATHLEN KDE_CHECK_FINAL + AM_KDE_WITH_NLS AM_CONDITIONAL(BUILD_KDE, true) fi AC_OUTPUT( Makefile + intl/Makefile + po/Makefile.in lib/Makefile ncpd/Makefile plpftp/Makefile @@ -228,6 +271,9 @@ AC_OUTPUT( kde2/Makefile kde2/kioslave/Makefile kde2/plugins/Makefile + kde2/kpsion/Makefile + kde2/po/Makefile + kde2/po/de/Makefile kde2/mime/Makefile kde2/mime/icons/Makefile plpbackup/Makefile diff --git a/include/intl.h b/include/intl.h new file mode 100644 index 0000000..a4e0727 --- /dev/null +++ b/include/intl.h @@ -0,0 +1,33 @@ +#ifndef _INTL_H_ +#define _INTL_H_ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#ifndef HAVE_STPCPY +#include <string.h> + +extern inline stpcpy(char *dest, const char *src) { + char c; + do { + c = *dest++ = *src++; + } while (c) + return dest; +} +#endif + +#if defined(ENABLE_NLS) && defined(HAVE_GETTEXT) +# include <libintl.h> +# define N_(x) (x) +# define _(x) gettext(x) +#else +# define N_(x) (x) +# define _(x) (x) +#endif + +/* Define this, if you have gettext */ +#define HAVE_GETTEXT 1 + +#endif /* _INTL_H_ */ + diff --git a/kde2/Makefile.am b/kde2/Makefile.am index c1186d6..7e40266 100644 --- a/kde2/Makefile.am +++ b/kde2/Makefile.am @@ -1,8 +1,9 @@ # $Id$ # -SUBDIRS = kioslave plugins mime +SUBDIRS = kioslave plugins mime kpsion po +POFILES = # # remove all intermediate files that can be recreated using # Makefile.cvs @@ -11,4 +12,4 @@ maintainer-clean-local: rm -f Makefile.in am_edit: - perl ../conf/am_edit + perl ../conf/am_edit -v diff --git a/kde2/kioslave/kio_plp.cpp b/kde2/kioslave/kio_plp.cpp index ffa5c8a..ef9fe54 100644 --- a/kde2/kioslave/kio_plp.cpp +++ b/kde2/kioslave/kio_plp.cpp @@ -1,24 +1,26 @@ -/* - A KIOslave for KDE2 - - Copyright (C) 2001 Fritz Elfert <felfert@to.com> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. -*/ - +/*-*-c++-*- + * $Id$ + * + * This file is part of plptools. + * + * Copyright (C) 1999 Philip Proudman <philip.proudman@btinternet.com> + * Copyright (C) 2000, 2001 Fritz Elfert <felfert@to.com> + * + * 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 + * + */ #ifdef HAVE_CONFIG_H #include <config.h> #endif @@ -27,6 +29,8 @@ #include <iomanip> #include <stdio.h> +#include <pwd.h> +#include <grp.h> #include <sys/stat.h> #include <qfile.h> @@ -62,1031 +66,1168 @@ extern "C" { int kdemain( int argc, char **argv ) { - KInstance instance( "kio_nfs" ); + KInstance instance( "kio_nfs" ); - if (argc != 4) { - fprintf(stderr, "Usage: kio_nfs protocol domain-socket1 domain-socket2\n"); - exit(-1); - } - kdDebug(PLP_DEBUGAREA) << "PLP: kdemain: starting" << endl; + if (argc != 4) { + fprintf(stderr, "Usage: kio_plp protocol domain-socket1 domain-socket2\n"); + exit(-1); + } + kdDebug(PLP_DEBUGAREA) << "PLP: kdemain: starting" << endl; - PLPProtocol slave(argv[2], argv[3]); - slave.dispatchLoop(); - return 0; + PLPProtocol slave(argv[2], argv[3]); + slave.dispatchLoop(); + return 0; } static void stripTrailingSlash(QString& path) { - if (path=="/") - path=""; - else - if (path[path.length()-1]=='/') - path.truncate(path.length()-1); + if (path=="/") + path=""; + else + if (path[path.length()-1]=='/') + path.truncate(path.length()-1); } static QString baseName(const QString& path) { - return path.mid(path.findRev("/") + 1); + return path.mid(path.findRev("/") + 1); } static QString removeFirstPart(const QString& path, QString &removed) { - QString result(""); - if (path.isEmpty()) { - removed = ""; - return result; - } - result = path.mid(1); - int slashPos = result.find("/"); - if (slashPos == -1) { - removed = result; - result = ""; - } else { - removed = result.left(slashPos); - result = result.mid(slashPos); - } + QString result(""); + if (path.isEmpty()) { + removed = ""; return result; + } + result = path.mid(1); + int slashPos = result.find("/"); + if (slashPos == -1) { + removed = result; + result = ""; + } else { + removed = result.left(slashPos); + result = result.mid(slashPos); + } + return result; } PLPProtocol::PLPProtocol (const QCString &pool, const QCString &app) - :SlaveBase("psion", pool, app), plpRfsv(0), plpRfsvSocket(0) { - - kdDebug(PLP_DEBUGAREA) << "PLPProtocol::PLPProtocol(" << pool << "," - << app << ")" << endl; - - currentHost = ""; - struct servent *se = getservbyname("psion", "tcp"); - endservent(); - if (se != 0L) - currentPort = ntohs(se->s_port); - else - currentPort = DPORT; - - typedef QMap<QString,QString> UIDMap; - KConfig *cfg = new KConfig("kioslaverc"); - - UIDMap uids = cfg->entryMap("Psion/UIDmapping"); - if (uids.isEmpty()) { - cfg->setGroup("Psion/UIDmapping"); - // Builtin application types. - cfg->writeEntry("uid-10000037-1000006D-1000007F", - "application/x-psion-word"); - cfg->writeEntry("uid-10000037-1000006D-10000088", - "application/x-psion-sheet"); - cfg->writeEntry("uid-10000037-1000006D-1000006d", - "application/x-psion-record"); - cfg->writeEntry("uid-10000037-1000006D-1000007d", - "application/x-psion-sketch"); - cfg->writeEntry("uid-10000037-1000006D-10000085", - "application/x-psion-opl"); - cfg->writeEntry("uid-10000050-1000006D-10000084", - "application/x-psion-agenda"); - cfg->writeEntry("uid-10000050-1000006D-10000086", - "application/x-psion-data"); - cfg->sync(); - uids = cfg->entryMap("Psion/UIDmapping"); - } - for (UIDMap::Iterator uit = uids.begin(); uit != uids.end(); ++uit) { - long u1, u2, u3; - - sscanf(uit.key().data(), "uid-%08X-%08X-%08X", &u1, &u2, &u3); - puids.insert(PlpUID(u1, u2, u3), uit.data()); - } + :SlaveBase("psion", pool, app), plpRfsv(0), plpRfsvSocket(0) { + + kdDebug(PLP_DEBUGAREA) << "PLPProtocol::PLPProtocol(" << pool << "," + << app << ")" << endl; + + currentHost = ""; + struct servent *se = getservbyname("psion", "tcp"); + endservent(); + if (se != 0L) + currentPort = ntohs(se->s_port); + else + currentPort = DPORT; + + typedef QMap<QString,QString> UIDMap; + KConfig *cfg = new KConfig("kioslaverc"); + + UIDMap uids = cfg->entryMap("Psion/UIDmapping"); + if (uids.isEmpty()) { + cfg->setGroup("Psion/UIDmapping"); + // Builtin application types. + cfg->writeEntry("uid-10000037-1000006D-1000007F", + "application/x-psion-word"); + cfg->writeEntry("uid-10000037-1000006D-10000088", + "application/x-psion-sheet"); + cfg->writeEntry("uid-10000037-1000006D-1000006d", + "application/x-psion-record"); + cfg->writeEntry("uid-10000037-1000006D-1000007d", + "application/x-psion-sketch"); + cfg->writeEntry("uid-10000037-1000006D-10000085", + "application/x-psion-opl"); + cfg->writeEntry("uid-10000050-1000006D-10000084", + "application/x-psion-agenda"); + cfg->writeEntry("uid-10000050-1000006D-10000086", + "application/x-psion-data"); + cfg->sync(); + uids = cfg->entryMap("Psion/UIDmapping"); + } + for (UIDMap::Iterator uit = uids.begin(); uit != uids.end(); ++uit) { + long u1, u2, u3; + + sscanf(uit.key().data(), "uid-%08X-%08X-%08X", &u1, &u2, &u3); + puids.insert(PlpUID(u1, u2, u3), uit.data()); + } } PLPProtocol::~PLPProtocol() { - closeConnection(); + closeConnection(); } void PLPProtocol:: closeConnection() { - if (plpRfsv) - delete(plpRfsv); - if (plpRfsvSocket) - delete(plpRfsvSocket); - plpRfsv = 0; - plpRfsvSocket = 0; + if (plpRfsv) + delete(plpRfsv); + if (plpRfsvSocket) + delete(plpRfsvSocket); + plpRfsv = 0; + plpRfsvSocket = 0; } bool PLPProtocol:: isRoot(const QString& path) { - return (path.isEmpty() || (path=="/")); + return (path.isEmpty() || (path=="/")); } bool PLPProtocol:: isDrive(const QString& path) { - QString tmp = path; - stripTrailingSlash(tmp); - for (QStringList::Iterator it = drives.begin(); it != drives.end(); it++) { - QString cmp = "/" + *it; - if (cmp == tmp) - return true; - } - return false; + QString tmp = path; + stripTrailingSlash(tmp); + for (QStringList::Iterator it = drives.begin(); it != drives.end(); it++) { + QString cmp = "/" + *it; + if (cmp == tmp) + return true; + } + return false; } bool PLPProtocol:: isRomDrive(const QString& path) { - return (driveChar(path) == 'Z'); + return (driveChar(path) == 'Z'); } char PLPProtocol:: driveChar(const QString& path) { - QString vname; - QString dummy = removeFirstPart(path, vname); - if (drivechars.find(vname) != drivechars.end()) - return drivechars[vname]; - return '\0'; + QString vname; + QString dummy = removeFirstPart(path, vname); + if (drivechars.find(vname) != drivechars.end()) + return drivechars[vname]; + return '\0'; } int PLPProtocol:: checkSpecial(const QString& path) { - QString tmp = path.mid(1); - if (tmp == i18n("Owner")) - return PLP_FTYPE_OWNER; - if (tmp == i18n("Machine")) - return PLP_FTYPE_MACHINE; - if (tmp == i18n("Settings")) - return PLP_FTYPE_SETUP; - if (tmp == i18n("Backup")) - return PLP_FTYPE_BACKUP; - if (tmp == i18n("Restore")) - return PLP_FTYPE_RESTORE; - return 0; + QString tmp = path.mid(1); + if (tmp == i18n("Owner")) + return PLP_FTYPE_OWNER; + if (tmp == i18n("Machine")) + return PLP_FTYPE_MACHINE; + if (tmp == i18n("Settings")) + return PLP_FTYPE_SETUP; + if (tmp == i18n("Backup")) + return PLP_FTYPE_BACKUP; + if (tmp == i18n("Restore")) + return PLP_FTYPE_RESTORE; + return 0; } void PLPProtocol:: convertName(QString &path) { - kdDebug(PLP_DEBUGAREA) << "convert: in='" << path << "' out='"; - QString dummy; - QString drive; - - drive.sprintf("%c:", driveChar(path)); - path = drive + removeFirstPart(path, dummy); - path.replace(QRegExp("/"), "\\"); - kdDebug(PLP_DEBUGAREA) << path << "'" << endl; + kdDebug(PLP_DEBUGAREA) << "convert: in='" << path << "' out='"; + QString dummy; + QString drive; + + drive.sprintf("%c:", driveChar(path)); + path = drive + removeFirstPart(path, dummy); + path.replace(QRegExp("/"), "\\"); + kdDebug(PLP_DEBUGAREA) << path << "'" << endl; } void PLPProtocol:: openConnection() { - kdDebug(PLP_DEBUGAREA) << "PLP::openConnection" << endl; - closeConnection(); - - plpRfsvSocket = new ppsocket(); - QString estr = i18n("Could not connect to ncpd at %1:%2").arg(currentHost).arg(currentPort); - if (!plpRfsvSocket->connect((char *)(currentHost.data()), currentPort)) { - error(ERR_COULD_NOT_CONNECT, estr); - return; - } - rfsvfactory factory(plpRfsvSocket); - plpRfsv = factory.create(false); - if (plpRfsv == 0L) { - error(ERR_COULD_NOT_CONNECT, estr); - return; - } - - /* If we have a S5, get the Psion's Owner- and Mach- info. - * This implicitely sets the Timezone info of the Psion also. - */ - ppsocket rpcsSocket; - if (rpcsSocket.connect((char *)(currentHost.data()), currentPort)) { - rpcsfactory factory(&rpcsSocket); - rpcs *Rpcs = factory.create(false); - if (Rpcs != 0L) { - bufferArray b; - Enum <rfsv::errs> res; - if ((res = Rpcs->getOwnerInfo(b)) == rfsv::E_PSI_GEN_NONE) { - Rpcs->getMachineType(machType); - if (machType == rpcs::PSI_MACH_S5) - Rpcs->getMachineInfo(mi); - } + kdDebug(PLP_DEBUGAREA) << "PLP::openConnection" << endl; + closeConnection(); + + plpRfsvSocket = new ppsocket(); + QString estr = i18n("Could not connect to ncpd at %1:%2").arg(currentHost).arg(currentPort); + if (!plpRfsvSocket->connect((char *)(currentHost.data()), currentPort)) { + error(ERR_COULD_NOT_CONNECT, estr); + return; + } + rfsvfactory factory(plpRfsvSocket); + plpRfsv = factory.create(false); + if (plpRfsv == 0L) { + error(ERR_COULD_NOT_CONNECT, estr); + return; + } + + plpRpcsSocket = new ppsocket(); + if (!plpRpcsSocket->connect((char *)(currentHost.data()), currentPort)) { + error(ERR_COULD_NOT_CONNECT, estr); + return; + } + rpcsfactory factory2(plpRpcsSocket); + plpRpcs = factory2.create(false); + if (plpRpcs == 0L) { + error(ERR_COULD_NOT_CONNECT, estr); + return; + } + + /* If we have a S5, get the Psion's Owner- and Mach- info. + * This implicitely sets the Timezone info of the Psion also. + */ + bufferArray b; + Enum <rfsv::errs> res; + if ((res = plpRpcs->getOwnerInfo(b)) == rfsv::E_PSI_GEN_NONE) { + plpRpcs->getMachineType(machType); + if (machType == rpcs::PSI_MACH_S5) + plpRpcs->getMachineInfo(machInfo); + } + + u_int32_t devbits; + + if ((res = plpRfsv->devlist(devbits)) == rfsv::E_PSI_GEN_NONE) { + for (int i = 0; i < 26; i++) { + if ((devbits & 1) != 0) { + PlpDrive drive; + if (plpRfsv->devinfo(i, drive) == rfsv::E_PSI_GEN_NONE) { + string vname = drive.getName(); + QString name; + + if (!vname.empty()) + name = QString(vname.c_str()); + else + name.sprintf("%c", 'A' + i); + drives.append(name); + drivechars.insert(name, 'A' + i); } + } + devbits >>= 1; } - - u_int32_t devbits; - Enum<rfsv::errs> res; - - if ((res = plpRfsv->devlist(devbits)) == rfsv::E_PSI_GEN_NONE) { - for (int i = 0; i < 26; i++) { - if ((devbits & 1) != 0) { - PlpDrive drive; - if (plpRfsv->devinfo(i, drive) == rfsv::E_PSI_GEN_NONE) { - string vname = drive.getName(); - QString name; - - if (!vname.empty()) - name = QString(vname.c_str()); - else - name.sprintf("%c", 'A' + i); - drives.append(name); - drivechars.insert(name, 'A' + i); - } - } - devbits >>= 1; - } - } else { - error(ERR_COULD_NOT_CONNECT, i18n("Could not get drive list")); - return; - } - connected(); - kdDebug(PLP_DEBUGAREA) << "openConnection succeeded" << endl; + } else { + error(ERR_COULD_NOT_CONNECT, i18n("Could not get drive list")); + return; + } + connected(); + kdDebug(PLP_DEBUGAREA) << "openConnection succeeded" << endl; } bool PLPProtocol:: checkConnection() { - kdDebug(PLP_DEBUGAREA) << "PLP::checkConnection" << endl; - if (plpRfsv == 0) - openConnection(); - return (plpRfsv == 0); + kdDebug(PLP_DEBUGAREA) << "PLP::checkConnection" << endl; + if (plpRfsv == 0) + openConnection(); + return (plpRfsv == 0); } QString PLPProtocol:: uid2mime(PlpDirent &e) { - QString tmp; - PlpUID u = e.getUID(); - UidMap::Iterator it = puids.find(u); - - if (it != puids.end()) - tmp = it.data(); - else - tmp.sprintf("application/x-psion-uid-%08X-%08X-%08X", u[0], u[1], u[2]); - return tmp; + QString tmp; + PlpUID u = e.getUID(); + UidMap::Iterator it = puids.find(u); + + if (it != puids.end()) + tmp = it.data(); + else + tmp.sprintf("application/x-psion-uid-%08X-%08X-%08X", u[0], u[1], u[2]); + return tmp; } void PLPProtocol:: listDir(const KURL& _url) { - KURL url(_url); - QString path(QFile::encodeName(url.path())); + KURL url(_url); + QString path(QFile::encodeName(url.path(-1))); - if (path.isEmpty()) { - url.setPath("/"); - redirection(url); - finished(); - return; - } + if (path.isEmpty()) { + url.setPath("/"); + redirection(url); + finished(); + return; + } - if (checkConnection()) - return; + if (checkConnection()) + return; - if (isRoot(path)) { - kdDebug(PLP_DEBUGAREA) << "listing root" << endl; - totalSize(drives.count()/* + 5*/); - //in this case we don't need to do a real listdir - UDSEntry entry; - UDSAtom atom; - for (QStringList::Iterator it = drives.begin(); it != drives.end(); it++) { - entry.clear(); - atom.m_uds = KIO::UDS_NAME; - atom.m_str = (*it); - kdDebug(PLP_DEBUGAREA) << "listing " << (*it) << endl; - entry.append(atom); - createVirtualDirEntry(entry, drivechars[*it] == 'Z', PLP_FTYPE_DRIVE); - listEntry(entry, false); - } + if (isRoot(path)) { + kdDebug(PLP_DEBUGAREA) << "listing root" << endl; + totalSize(drives.count()/* + 5*/); + //in this case we don't need to do a real listdir + UDSEntry entry; + UDSAtom atom; + for (QStringList::Iterator it = drives.begin(); it != drives.end(); it++) { + entry.clear(); + atom.m_uds = KIO::UDS_NAME; + atom.m_str = (*it); + kdDebug(PLP_DEBUGAREA) << "listing " << (*it) << endl; + entry.append(atom); + createVirtualDirEntry(entry, drivechars[*it] == 'Z', PLP_FTYPE_DRIVE); + listEntry(entry, false); + } #if 0 - entry.clear(); - atom.m_uds = KIO::UDS_NAME; - atom.m_str = i18n("Owner"); - entry.append(atom); - createVirtualDirEntry(entry, false, PLP_FTYPE_OWNER); - listEntry(entry, false); - - entry.clear(); - atom.m_uds = KIO::UDS_NAME; - atom.m_str = i18n("Machine"); - entry.append(atom); - createVirtualDirEntry(entry, false, PLP_FTYPE_MACHINE); - listEntry(entry, false); - - entry.clear(); - atom.m_uds = KIO::UDS_NAME; - atom.m_str = i18n("Settings"); - entry.append(atom); - createVirtualDirEntry(entry, false, PLP_FTYPE_SETUP); - listEntry(entry, false); - - entry.clear(); - atom.m_uds = KIO::UDS_NAME; - atom.m_str = i18n("Backup"); - entry.append(atom); - createVirtualDirEntry(entry, false, PLP_FTYPE_BACKUP); - listEntry(entry, false); - - entry.clear(); - atom.m_uds = KIO::UDS_NAME; - atom.m_str = i18n("Restore"); - entry.append(atom); - createVirtualDirEntry(entry, false, PLP_FTYPE_RESTORE); - listEntry(entry, false); -#endif + entry.clear(); + atom.m_uds = KIO::UDS_NAME; + atom.m_str = i18n("Owner"); + entry.append(atom); + createVirtualDirEntry(entry, false, PLP_FTYPE_OWNER); + listEntry(entry, false); - listEntry(entry, true); - finished(); - return; - } + entry.clear(); + atom.m_uds = KIO::UDS_NAME; + atom.m_str = i18n("Machine"); + entry.append(atom); + createVirtualDirEntry(entry, false, PLP_FTYPE_MACHINE); + listEntry(entry, false); - kdDebug(PLP_DEBUGAREA) << "getting subdir -" << path << "-" << endl; - bool rom = isRomDrive(path); - convertName(path); - path += "\\"; + entry.clear(); + atom.m_uds = KIO::UDS_NAME; + atom.m_str = i18n("Settings"); + entry.append(atom); + createVirtualDirEntry(entry, false, PLP_FTYPE_SETUP); + listEntry(entry, false); - PlpDir files; - Enum<rfsv::errs> res = plpRfsv->dir(path, files); - if (checkForError(res, url.path())) - return; - totalSize(files.size()); - UDSEntry entry; - for (int i = 0; i < files.size(); i++) { - UDSAtom atom; + entry.clear(); + atom.m_uds = KIO::UDS_NAME; + atom.m_str = i18n("Backup"); + entry.append(atom); + createVirtualDirEntry(entry, false, PLP_FTYPE_BACKUP); + listEntry(entry, false); - PlpDirent e = files[i]; - long attr = e.getAttr(); + entry.clear(); + atom.m_uds = KIO::UDS_NAME; + atom.m_str = i18n("Restore"); + entry.append(atom); + createVirtualDirEntry(entry, false, PLP_FTYPE_RESTORE); + listEntry(entry, false); +#endif - entry.clear(); - atom.m_uds = KIO::UDS_NAME; - atom.m_str = e.getName(); - entry.append(atom); + listEntry(entry, true); + finished(); + return; + } + + kdDebug(PLP_DEBUGAREA) << "getting subdir -" << path << "-" << endl; + bool rom = isRomDrive(path); + convertName(path); + path += "\\"; + + PlpDir files; + Enum<rfsv::errs> res = plpRfsv->dir(path.latin1(), files); + if (checkForError(res, url.path())) + return; + totalSize(files.size()); + UDSEntry entry; + for (int i = 0; i < files.size(); i++) { + UDSAtom atom; - if ((attr & rfsv::PSI_A_DIR) == 0) { - atom.m_uds = KIO::UDS_MIME_TYPE; - atom.m_str = uid2mime(e); - entry.append(atom); - } + PlpDirent e = files[i]; + long attr = e.getAttr(); - completeUDSEntry(entry, e, rom); - listEntry(entry, false); + entry.clear(); + atom.m_uds = KIO::UDS_NAME; + atom.m_str = e.getName(); + entry.append(atom); + + if ((attr & rfsv::PSI_A_DIR) == 0) { + atom.m_uds = KIO::UDS_MIME_TYPE; + atom.m_str = uid2mime(e); + entry.append(atom); } - listEntry(entry, true); // ready - finished(); + + completeUDSEntry(entry, e, rom); + listEntry(entry, false); + } + listEntry(entry, true); // ready + finished(); } void PLPProtocol:: -createVirtualDirEntry(UDSEntry & entry, bool rdonly, int type) { - UDSAtom atom; +setOwner(UDSEntry & entry) { + UDSAtom atom; + struct passwd *pw = getpwuid(getuid()); + struct group *gr = getgrgid(getgid()); - atom.m_uds = KIO::UDS_ACCESS; - atom.m_long = S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; - if (!rdonly) - atom.m_long |= (S_IWUSR | S_IWGRP | S_IWOTH); - entry.append(atom); + atom.m_uds = KIO::UDS_USER; + atom.m_str = pw ? pw->pw_name : "root"; + entry.append(atom); - atom.m_uds = KIO::UDS_SIZE; - atom.m_long = 0; - entry.append(atom); + atom.m_uds = KIO::UDS_GROUP; + atom.m_str = gr ? gr->gr_name : "root"; + entry.append(atom); - switch (type) { - case PLP_FTYPE_ROOT: - //atom.m_uds = KIO::UDS_FILE_TYPE; - //atom.m_long = S_IFBLK; - //entry.append(atom); - // atom.m_uds = KIO::UDS_GUESSED_MIME_TYPE; - atom.m_uds = KIO::UDS_MIME_TYPE; - atom.m_str = QString("inode/x-psion-drive"); - entry.append(atom); - break; - case PLP_FTYPE_DRIVE: - atom.m_uds = KIO::UDS_FILE_TYPE; - atom.m_long = S_IFDIR; - entry.append(atom); - atom.m_uds = KIO::UDS_GUESSED_MIME_TYPE; - // atom.m_uds = KIO::UDS_MIME_TYPE; - atom.m_str = QString("inode/x-psion-drive"); - entry.append(atom); - break; - case PLP_FTYPE_OWNER: - atom.m_uds = KIO::UDS_FILE_TYPE; - atom.m_long = S_IFREG; - entry.append(atom); - atom.m_uds = KIO::UDS_MIME_TYPE; - atom.m_str = QString("application/x-psion-owner"); - entry.append(atom); - break; - case PLP_FTYPE_MACHINE: - atom.m_uds = KIO::UDS_FILE_TYPE; - atom.m_long = S_IFREG; - entry.append(atom); - atom.m_uds = KIO::UDS_MIME_TYPE; - atom.m_str = QString("application/x-psion-machine"); - entry.append(atom); - break; - case PLP_FTYPE_SETUP: - atom.m_uds = KIO::UDS_FILE_TYPE; - atom.m_long = S_IFREG; - entry.append(atom); - atom.m_uds = KIO::UDS_MIME_TYPE; - atom.m_str = QString("application/x-psion-setup"); - entry.append(atom); - break; - case PLP_FTYPE_BACKUP: - atom.m_uds = KIO::UDS_FILE_TYPE; - atom.m_long = S_IFREG; - entry.append(atom); - atom.m_uds = KIO::UDS_MIME_TYPE; - atom.m_str = QString("application/x-psion-backup"); - entry.append(atom); - break; - case PLP_FTYPE_RESTORE: - atom.m_uds = KIO::UDS_FILE_TYPE; - atom.m_long = S_IFREG; - entry.append(atom); - atom.m_uds = KIO::UDS_MIME_TYPE; - atom.m_str = QString("application/x-psion-restore"); - entry.append(atom); - break; - } + endgrent(); + endpwent(); +} + +void PLPProtocol:: +createVirtualDirEntry(UDSEntry & entry, bool rdonly, int type) { + UDSAtom atom; + + atom.m_uds = KIO::UDS_ACCESS; + atom.m_long = S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; + if (!rdonly) + atom.m_long |= (S_IWUSR | S_IWGRP | S_IWOTH); + entry.append(atom); + + atom.m_uds = KIO::UDS_SIZE; + atom.m_long = 0; + entry.append(atom); + + setOwner(entry); + + switch (type) { + case PLP_FTYPE_ROOT: + atom.m_uds = KIO::UDS_FILE_TYPE; + atom.m_long = S_IFDIR; + entry.append(atom); + atom.m_uds = KIO::UDS_GUESSED_MIME_TYPE; + atom.m_uds = KIO::UDS_MIME_TYPE; + atom.m_str = QString("inode/x-psion-drive"); + entry.append(atom); + break; + case PLP_FTYPE_DRIVE: + atom.m_uds = KIO::UDS_FILE_TYPE; + atom.m_long = S_IFDIR; + entry.append(atom); + atom.m_uds = KIO::UDS_GUESSED_MIME_TYPE; + atom.m_str = QString("inode/x-psion-drive"); + atom.m_uds = KIO::UDS_MIME_TYPE; + atom.m_str = QString("inode/x-psion-drive"); + entry.append(atom); + break; + case PLP_FTYPE_OWNER: + atom.m_uds = KIO::UDS_FILE_TYPE; + atom.m_long = S_IFREG; + entry.append(atom); + atom.m_uds = KIO::UDS_MIME_TYPE; + atom.m_str = QString("application/x-psion-owner"); + entry.append(atom); + break; + case PLP_FTYPE_MACHINE: + atom.m_uds = KIO::UDS_FILE_TYPE; + atom.m_long = S_IFREG; + entry.append(atom); + atom.m_uds = KIO::UDS_MIME_TYPE; + atom.m_str = QString("application/x-psion-machine"); + entry.append(atom); + break; + case PLP_FTYPE_SETUP: + atom.m_uds = KIO::UDS_FILE_TYPE; + atom.m_long = S_IFREG; + entry.append(atom); + atom.m_uds = KIO::UDS_MIME_TYPE; + atom.m_str = QString("application/x-psion-setup"); + entry.append(atom); + break; + case PLP_FTYPE_BACKUP: + atom.m_uds = KIO::UDS_FILE_TYPE; + atom.m_long = S_IFREG; + entry.append(atom); + atom.m_uds = KIO::UDS_MIME_TYPE; + atom.m_str = QString("application/x-psion-backup"); + entry.append(atom); + break; + case PLP_FTYPE_RESTORE: + atom.m_uds = KIO::UDS_FILE_TYPE; + atom.m_long = S_IFREG; + entry.append(atom); + atom.m_uds = KIO::UDS_MIME_TYPE; + atom.m_str = QString("application/x-psion-restore"); + entry.append(atom); + break; + } } bool PLPProtocol:: emitTotalSize(QString &name) { - PlpDirent e; + PlpDirent e; - Enum<rfsv::errs> res = plpRfsv->fgeteattr(name, e); - if (checkForError(res), &name) - return true; - totalSize(e.getSize()); - return false; + Enum<rfsv::errs> res = plpRfsv->fgeteattr(name.latin1(), e); + if (checkForError(res, name)) + return true; + totalSize(e.getSize()); + return false; } void PLPProtocol:: stat(const KURL & url) { - QString path(QFile::encodeName(url.path())); - UDSEntry entry; - UDSAtom atom; + QString path(QFile::encodeName(url.path(-1))); + UDSEntry entry; + UDSAtom atom; - if (checkConnection()) - return; - - kdDebug(PLP_DEBUGAREA) << "stat(" << path << ")" << endl; - stripTrailingSlash(path); - - if (isRoot(path) || isDrive(path)) { - atom.m_uds = KIO::UDS_NAME; - atom.m_str = path; - entry.append(atom); - if (isRoot(path)) - createVirtualDirEntry(entry, true, PLP_FTYPE_ROOT); - else - createVirtualDirEntry(entry, isRomDrive(path), PLP_FTYPE_DRIVE); - statEntry(entry); - finished(); - kdDebug(PLP_DEBUGAREA) << "succeeded" << endl; - return; - } - int ftype = checkSpecial(path); - if (ftype != 0) { - atom.m_uds = KIO::UDS_NAME; - atom.m_str = path; - entry.append(atom); - createVirtualDirEntry(entry, false, ftype); - statEntry(entry); - finished(); - kdDebug(PLP_DEBUGAREA) << "succeeded" << endl; - return; - } + if (checkConnection()) + return; - bool rom = isRomDrive(path); - QString fileName = baseName(path); - convertName(path); - - if (path.isEmpty()) { - error(ERR_DOES_NOT_EXIST, url.path()); - return; - } - - PlpDirent e; - - Enum<rfsv::errs> res = plpRfsv->fgeteattr(path, e); - if (checkForError(res, url.path())) - return; + kdDebug(PLP_DEBUGAREA) << "stat(" << path << ")" << endl; + stripTrailingSlash(path); + if (isRoot(path) || isDrive(path)) { atom.m_uds = KIO::UDS_NAME; - atom.m_str = fileName; + atom.m_str = path; entry.append(atom); - completeUDSEntry(entry, e, rom); + if (isRoot(path)) + createVirtualDirEntry(entry, true, PLP_FTYPE_ROOT); + else + createVirtualDirEntry(entry, isRomDrive(path), PLP_FTYPE_DRIVE); statEntry(entry); - finished(); -} + kdDebug(PLP_DEBUGAREA) << "succeeded" << endl; + return; + } + int ftype = checkSpecial(path); + if (ftype != 0) { + atom.m_uds = KIO::UDS_NAME; + atom.m_str = path; + entry.append(atom); + createVirtualDirEntry(entry, false, ftype); + statEntry(entry); + finished(); + kdDebug(PLP_DEBUGAREA) << "succeeded" << endl; + return; + } -void PLPProtocol:: -mimetype(const KURL & url) { - QString path(QFile::encodeName(url.path())); - UDSEntry entry; - UDSAtom atom; + bool rom = isRomDrive(path); + QString fileName = baseName(path); + convertName(path); - if (checkConnection()) - return; + if (path.isEmpty()) { + error(ERR_DOES_NOT_EXIST, url.path()); + return; + } - kdDebug(PLP_DEBUGAREA) << "mimetype(" << path << ")" << endl; - stripTrailingSlash(path); + PlpDirent e; - if (isRoot(path) || isDrive(path)) { - mimeType("inode/directory"); - finished(); - return; - } - convertName(path); + Enum<rfsv::errs> res = plpRfsv->fgeteattr(path.latin1(), e); + if (checkForError(res, url.path())) + return; - if (path.isEmpty()) { - error(ERR_DOES_NOT_EXIST, url.path()); - return; - } + atom.m_uds = KIO::UDS_NAME; + atom.m_str = fileName; + entry.append(atom); + completeUDSEntry(entry, e, rom); + statEntry(entry); - PlpDirent e; - Enum<rfsv::errs> res = plpRfsv->fgeteattr(path, e); - if (checkForError(res, url.path())) - return; - mimeType(uid2mime(e)); - finished(); + finished(); } void PLPProtocol:: -completeUDSEntry(UDSEntry& entry, PlpDirent &e, bool rom) { - UDSAtom atom; - long attr = e.getAttr(); - - if (rom) - attr |= rfsv::PSI_A_RDONLY; - - atom.m_uds = KIO::UDS_SIZE; - atom.m_long = e.getSize(); - entry.append(atom); - - if (attr & rfsv::PSI_A_DIR) - atom.m_uds = KIO::UDS_CREATION_TIME; - else - atom.m_uds = KIO::UDS_MODIFICATION_TIME; - atom.m_long = e.getPsiTime().getTime(); - entry.append(atom); +mimetype(const KURL & url) { + QString path(QFile::encodeName(url.path(-1))); + UDSEntry entry; + UDSAtom atom; - atom.m_uds = KIO::UDS_ACCESS; - atom.m_long = S_IRUSR | S_IRGRP | S_IROTH; - if (attr & rfsv::PSI_A_DIR) - atom.m_long |= S_IXUSR | S_IXGRP | S_IXOTH; - if (!(attr & rfsv::PSI_A_RDONLY)) - atom.m_long |= S_IWUSR | S_IWGRP | S_IWOTH; - entry.append(atom); + kdDebug(PLP_DEBUGAREA) << "mimetype(" << path << ")" << endl; + stripTrailingSlash(path); - atom.m_uds = KIO::UDS_FILE_TYPE; - atom.m_long = (attr & rfsv::PSI_A_DIR) ? S_IFDIR : S_IFREG; - entry.append(atom); + if (isRoot(path) || isDrive(path)) { + mimeType("inode/directory"); + finished(); + return; + } + convertName(path); + + if (path.isEmpty()) { + error(ERR_DOES_NOT_EXIST, url.path()); + return; + } + + PlpDirent e; + Enum<rfsv::errs> res = plpRfsv->fgeteattr(path.latin1(), e); + if (checkForError(res, url.path())) + return; + mimeType(uid2mime(e)); + finished(); +} -#if 0 - KIO::UDSEntry::ConstIterator it = entry.begin(); - for( ; it != entry.end(); it++ ) { - switch ((*it).m_uds) { - case KIO::UDS_FILE_TYPE: - kdDebug(PLP_DEBUGAREA) << "File Type : " << - (mode_t)((*it).m_long) << endl; - break; - case KIO::UDS_SIZE: - kdDebug(PLP_DEBUGAREA) << "File Size : " << - (long)((*it).m_long) << endl; - break; - case KIO::UDS_ACCESS: - kdDebug(PLP_DEBUGAREA) << "Access permissions : " << - (mode_t)((*it).m_long) << endl; - break; - case KIO::UDS_USER: - kdDebug(PLP_DEBUGAREA) << "User : " << - ((*it).m_str.ascii() ) << endl; - break; - case KIO::UDS_GROUP: - kdDebug(PLP_DEBUGAREA) << "Group : " << - ((*it).m_str.ascii() ) << endl; - break; - case KIO::UDS_NAME: - kdDebug(PLP_DEBUGAREA) << "Name : " << - ((*it).m_str.ascii() ) << endl; - //m_strText = decodeFileName( (*it).m_str ); - break; - case KIO::UDS_URL: - kdDebug(PLP_DEBUGAREA) << "URL : " << - ((*it).m_str.ascii() ) << endl; - break; - case KIO::UDS_MIME_TYPE: - kdDebug(PLP_DEBUGAREA) << "MimeType : " << - ((*it).m_str.ascii() ) << endl; - break; - case KIO::UDS_LINK_DEST: - kdDebug(PLP_DEBUGAREA) << "LinkDest : " << - ((*it).m_str.ascii() ) << endl; - break; - } - } +void PLPProtocol:: +completeUDSEntry(UDSEntry& entry, PlpDirent &e, bool rom) { + UDSAtom atom; + long attr = e.getAttr(); + + if (rom) + attr |= rfsv::PSI_A_RDONLY; + + atom.m_uds = KIO::UDS_SIZE; + atom.m_long = e.getSize(); + entry.append(atom); + + if (attr & rfsv::PSI_A_DIR) + atom.m_uds = KIO::UDS_CREATION_TIME; + else + atom.m_uds = KIO::UDS_MODIFICATION_TIME; + atom.m_long = e.getPsiTime().getTime(); + entry.append(atom); + + atom.m_uds = KIO::UDS_ACCESS; + atom.m_long = S_IRUSR | S_IRGRP | S_IROTH; + if (attr & rfsv::PSI_A_DIR) + atom.m_long |= S_IXUSR | S_IXGRP | S_IXOTH; + if (!(attr & rfsv::PSI_A_RDONLY)) + atom.m_long |= S_IWUSR | S_IWGRP | S_IWOTH; + entry.append(atom); + + atom.m_uds = KIO::UDS_FILE_TYPE; + atom.m_long = (attr & rfsv::PSI_A_DIR) ? S_IFDIR : S_IFREG; + entry.append(atom); + + setOwner(entry); + +#if 1 + KIO::UDSEntry::ConstIterator it = entry.begin(); + for( ; it != entry.end(); it++ ) { + switch ((*it).m_uds) { + case KIO::UDS_FILE_TYPE: + kdDebug(PLP_DEBUGAREA) << "File Type : " << + (mode_t)((*it).m_long) << endl; + break; + case KIO::UDS_SIZE: + kdDebug(PLP_DEBUGAREA) << "File Size : " << + (long)((*it).m_long) << endl; + break; + case KIO::UDS_ACCESS: + kdDebug(PLP_DEBUGAREA) << "Access permissions : " << + (mode_t)((*it).m_long) << endl; + break; + case KIO::UDS_USER: + kdDebug(PLP_DEBUGAREA) << "User : " << + ((*it).m_str.ascii() ) << endl; + break; + case KIO::UDS_GROUP: + kdDebug(PLP_DEBUGAREA) << "Group : " << + ((*it).m_str.ascii() ) << endl; + break; + case KIO::UDS_NAME: + kdDebug(PLP_DEBUGAREA) << "Name : " << + ((*it).m_str.ascii() ) << endl; + //m_strText = decodeFileName( (*it).m_str ); + break; + case KIO::UDS_URL: + kdDebug(PLP_DEBUGAREA) << "URL : " << + ((*it).m_str.ascii() ) << endl; + break; + case KIO::UDS_MIME_TYPE: + kdDebug(PLP_DEBUGAREA) << "MimeType : " << + ((*it).m_str.ascii() ) << endl; + break; + case KIO::UDS_LINK_DEST: + kdDebug(PLP_DEBUGAREA) << "LinkDest : " << + ((*it).m_str.ascii() ) << endl; + break; + } + } #endif } void PLPProtocol:: setHost(const QString& host, int port, const QString&, const QString&) { - kdDebug(PLP_DEBUGAREA) << "setHost(" << host << "," << port << ")" << endl; - QString tmphost = host; - if (host.isEmpty()) - tmphost = "localhost"; - if (port == 0) { - struct servent *se = getservbyname("psion", "tcp"); - endservent(); - if (se != 0L) - port = ntohs(se->s_port); - else - port = DPORT; - } - if ((tmphost == currentHost) && (port == currentPort)) - return; - currentHost = tmphost; - currentPort = port; - closeConnection(); + kdDebug(PLP_DEBUGAREA) << "setHost(" << host << "," << port << ")" << endl; + QString tmphost = host; + if (host.isEmpty()) + tmphost = "localhost"; + if (port == 0) { + struct servent *se = getservbyname("psion", "tcp"); + endservent(); + if (se != 0L) + port = ntohs(se->s_port); + else + port = DPORT; + } + if ((tmphost == currentHost) && (port == currentPort)) + return; + currentHost = tmphost; + currentPort = port; + closeConnection(); } void PLPProtocol:: mkdir(const KURL& url, int) { - kdDebug(PLP_DEBUGAREA) << "mkdir" << endl; - QString name(QFile::encodeName(url.path())); - - if (checkConnection()) - return; - kdDebug(PLP_DEBUGAREA) << "mkdir(" << name << ")" << endl; - if (isRomDrive(name)) { - error(ERR_ACCESS_DENIED, i18n("%1: read only filesystem").arg(url.path())); - return; - } - if (isRoot(name) || isDrive(name)) { - error(ERR_ACCESS_DENIED, i18n("%1: virtual directory").arg(url.path())); - return; - } - convertName(name); - Enum<rfsv::errs> res = plpRfsv->mkdir(name); - if (checkForError(res), url.path()) - return; - finished(); + kdDebug(PLP_DEBUGAREA) << "mkdir" << endl; + QString name(QFile::encodeName(url.path(-1))); + + if (checkConnection()) + return; + kdDebug(PLP_DEBUGAREA) << "mkdir(" << name << ")" << endl; + if (isRomDrive(name)) { + error(ERR_ACCESS_DENIED, i18n("%1: read only filesystem").arg(url.path())); + return; + } + if (isRoot(name) || isDrive(name)) { + error(ERR_ACCESS_DENIED, i18n("%1: virtual directory").arg(url.path())); + return; + } + convertName(name); + Enum<rfsv::errs> res = plpRfsv->mkdir(name.latin1()); + if (checkForError(res, url.path())) + return; + finished(); } bool PLPProtocol:: checkForError(Enum<rfsv::errs> res, QString n1, QString n2) { - if (res != rfsv::E_PSI_GEN_NONE) { - kdDebug(PLP_DEBUGAREA) << "plp error: " << res << endl; - QString reason(res.toString().data()); - QString text; - if (!!n1 && !!n2) - text = i18n("%1 or %2: %3").arg(n1).arg(n2).arg(reason); - else { - if (!!n1 || !!n2) - text = QString("%1: %2").arg(n1 ? n1 : n2).arg(reason); - else - text = reason; - } - switch (res) { - case rfsv::E_PSI_FILE_ACCESS: - error(ERR_ACCESS_DENIED, text); - break; - case rfsv::E_PSI_FILE_EXIST: - error(ERR_FILE_ALREADY_EXIST, text); - break; - case rfsv::E_PSI_FILE_NXIST: - error(ERR_DOES_NOT_EXIST, text); - break; - case rfsv::E_PSI_FILE_DIR: - error(ERR_IS_DIRECTORY, text); - break; - default: - error(ERR_UNKNOWN, text); - break; - } - return true; + if (res != rfsv::E_PSI_GEN_NONE) { + kdDebug(PLP_DEBUGAREA) << "plp error: " << res << endl; + QString reason(res); + QString text; + if (!!n1 && !!n2) + text = i18n("%1 or %2: %3").arg(n1).arg(n2).arg(reason); + else { + if (!!n1 || !!n2) + text = QString("%1: %2").arg(n1 ? n1 : n2).arg(reason); + else + text = reason; + } + switch (res) { + case rfsv::E_PSI_FILE_ACCESS: + error(ERR_ACCESS_DENIED, text); + break; + case rfsv::E_PSI_FILE_EXIST: + error(ERR_FILE_ALREADY_EXIST, text); + break; + case rfsv::E_PSI_FILE_NXIST: + error(ERR_DOES_NOT_EXIST, text); + break; + case rfsv::E_PSI_FILE_DIR: + error(ERR_IS_DIRECTORY, text); + break; + default: + error(ERR_UNKNOWN, text); + break; } - return false; + return true; + } + return false; } void PLPProtocol:: del( const KURL& url, bool isfile) { - kdDebug(PLP_DEBUGAREA) << "del" << endl; - QString name(QFile::encodeName(url.path())); - - if (checkConnection()) - return; - kdDebug(PLP_DEBUGAREA) << "del(" << name << ")" << endl; - if (isRomDrive(name)) { - error(ERR_ACCESS_DENIED, i18n("%1: read only filesystem").arg(url.path())); - return; - } - if (isRoot(name) || isDrive(name)) { - error(ERR_ACCESS_DENIED, i18n("%1: virtual directory").arg(url.path())); - return; - } - convertName(name); - - Enum<rfsv::errs> res = - (isfile) ? plpRfsv->remove(name) : plpRfsv->rmdir(name); - if (checkForError(res, url.path())) - return; - finished(); + kdDebug(PLP_DEBUGAREA) << "del" << endl; + QString name(QFile::encodeName(url.path(-1))); + + if (checkConnection()) + return; + kdDebug(PLP_DEBUGAREA) << "del(" << name << ")" << endl; + if (isRomDrive(name)) { + error(ERR_ACCESS_DENIED, i18n("%1: read only filesystem").arg(url.path())); + return; + } + if (isRoot(name) || isDrive(name)) { + error(ERR_ACCESS_DENIED, i18n("%1: virtual directory").arg(url.path())); + return; + } + convertName(name); + + Enum<rfsv::errs> res = + (isfile) ? plpRfsv->remove(name.latin1()) : plpRfsv->rmdir(name.latin1()); + if (checkForError(res, url.path())) + return; + finished(); } void PLPProtocol:: chmod( const KURL& url, int permissions ) { - kdDebug(PLP_DEBUGAREA) << "del" << endl; - QString name(QFile::encodeName(url.path())); - - if (checkConnection()) - return; - kdDebug(PLP_DEBUGAREA) << "chmod(" << name << ")" << endl; - if (isRomDrive(name)) { - error(ERR_ACCESS_DENIED, i18n("%1: read only filesystem").arg(url.path())); - return; - } - if (isRoot(name) || isDrive(name)) { - error(ERR_ACCESS_DENIED, i18n("%1: virtual directory").arg(url.path())); - return; - } - convertName(name); - long attr[2]; - attr[0] = attr[1] = 0; - Enum <rfsv::errs> res = plpRfsv->fsetattr(name, attr[0], attr[1]); - if (checkForError(res, url.path())) - return; - finished(); + kdDebug(PLP_DEBUGAREA) << "del" << endl; + QString name(QFile::encodeName(url.path(-1))); + + if (checkConnection()) + return; + kdDebug(PLP_DEBUGAREA) << "chmod(" << name << ")" << endl; + if (isRomDrive(name)) { + error(ERR_ACCESS_DENIED, i18n("%1: read only filesystem").arg(url.path())); + return; + } + if (isRoot(name) || isDrive(name)) { + error(ERR_ACCESS_DENIED, i18n("%1: virtual directory").arg(url.path())); + return; + } + convertName(name); + long attr[2]; + attr[0] = attr[1] = 0; + Enum <rfsv::errs> res = plpRfsv->fsetattr(name.latin1(), attr[0], attr[1]); + if (checkForError(res, url.path())) + return; + finished(); } void PLPProtocol:: get( const KURL& url ) { - kdDebug(PLP_DEBUGAREA) << "get" << endl; - QString name(QFile::encodeName(url.path())); - - if (checkConnection()) - return; - kdDebug(PLP_DEBUGAREA) << "get(" << name << ")" << endl; - if (isRoot(name) || isDrive(name)) { - error(ERR_ACCESS_DENIED, i18n("%1: virtual directory").arg(url.path())); - return; + kdDebug(PLP_DEBUGAREA) << "get" << endl; + QString name(QFile::encodeName(url.path(-1))); + + if (checkConnection()) + return; + kdDebug(PLP_DEBUGAREA) << "get(" << name << ")" << endl; + if (isRoot(name) || isDrive(name)) { + error(ERR_ACCESS_DENIED, i18n("%1: virtual directory").arg(url.path())); + return; + } + convertName(name); + + Enum<rfsv::errs> res; + u_int32_t handle; + u_int32_t len; + u_int32_t size; + u_int32_t total = 0; + + if (emitTotalSize(name)) + return; + res = plpRfsv->fopen(plpRfsv->opMode(rfsv::PSI_O_RDONLY), name.latin1(), handle); + if (checkForError(res, url.path())) + return; + + QByteArray a(RFSV_SENDLEN); + do { + if ((res = plpRfsv->fread(handle, (unsigned char *)(a.data()), + RFSV_SENDLEN, len)) == rfsv::E_PSI_GEN_NONE) { + if (len < RFSV_SENDLEN) + a.resize(len); + data(a); + total += len; + calcprogress(total); } - convertName(name); - - Enum<rfsv::errs> res; - u_int32_t handle; - u_int32_t len; - u_int32_t size; - u_int32_t total = 0; + } while ((len > 0) && (res == rfsv::E_PSI_GEN_NONE)); + plpRfsv->fclose(handle); + if (checkForError(res, url.path())) + return; + data(QByteArray()); - if (emitTotalSize(name)) - return; - res = plpRfsv->fopen(plpRfsv->opMode(rfsv::PSI_O_RDONLY), name, handle); - if (checkForError(res, url.path())) - return; - - QByteArray a(RFSV_SENDLEN); - do { - if ((res = plpRfsv->fread(handle, (unsigned char *)(a.data()), - RFSV_SENDLEN, len)) == rfsv::E_PSI_GEN_NONE) { - if (len < RFSV_SENDLEN) - a.resize(len); - data(a); - total += len; - calcprogress(total); - } - } while ((len > 0) && (res == rfsv::E_PSI_GEN_NONE)); - plpRfsv->fclose(handle); - if (checkForError(res, url.path())) - return; - data(QByteArray()); - - finished(); + finished(); } //TODO the partial putting thing is not yet implemented void PLPProtocol:: put( const KURL& url, int _mode, bool _overwrite, bool /*_resume*/ ) { - kdDebug(PLP_DEBUGAREA) << "get" << endl; - QString name(QFile::encodeName(url.path())); - - if (checkConnection()) - return; - kdDebug(PLP_DEBUGAREA) << "put(" << name << ")" << endl; - if (isRomDrive(name)) { - error(ERR_ACCESS_DENIED, i18n("%1: read only filesystem").arg(url.path())); - return; - } - if (isRoot(name) || isDrive(name)) { - error(ERR_ACCESS_DENIED, i18n("%1: virtual directory").arg(url.path())); - return; - } - convertName(name); - - Enum<rfsv::errs> res; - u_int32_t handle; - int result; - - res = plpRfsv->fcreatefile(plpRfsv->opMode(rfsv::PSI_O_RDWR), name, handle); - if ((res == rfsv::E_PSI_FILE_EXIST) && _overwrite) - res = plpRfsv->freplacefile(plpRfsv->opMode(rfsv::PSI_O_RDWR), name, handle); - if (checkForError(res, url.path())) - return; - - do { - QByteArray a; - dataReq(); - result = readData(a); - const unsigned char *data = (const unsigned char *)(a.data()); - long len = a.size(); - - if (result > 0) - do { - u_int32_t written; - u_int32_t count = (len > RFSV_SENDLEN) ? RFSV_SENDLEN : len; - res = plpRfsv->fwrite(handle, data, count, written); - if (checkForError(res, url.path())) { - plpRfsv->fclose(handle); - return; - } - len -= written; - data += written; - } while (len > 0); - } while (result > 0); - plpRfsv->fclose(handle); - finished(); + kdDebug(PLP_DEBUGAREA) << "get" << endl; + QString name(QFile::encodeName(url.path(-1))); + + if (checkConnection()) + return; + kdDebug(PLP_DEBUGAREA) << "put(" << name << ")" << endl; + if (isRomDrive(name)) { + error(ERR_ACCESS_DENIED, i18n("%1: read only filesystem").arg(url.path())); + return; + } + if (isRoot(name) || isDrive(name)) { + error(ERR_ACCESS_DENIED, i18n("%1: virtual directory").arg(url.path())); + return; + } + convertName(name); + + Enum<rfsv::errs> res; + u_int32_t handle; + int result; + + res = plpRfsv->fcreatefile(plpRfsv->opMode(rfsv::PSI_O_RDWR), name.latin1(), handle); + if ((res == rfsv::E_PSI_FILE_EXIST) && _overwrite) + res = plpRfsv->freplacefile(plpRfsv->opMode(rfsv::PSI_O_RDWR), name.latin1(), handle); + if (checkForError(res, url.path())) + return; + + do { + QByteArray a; + dataReq(); + result = readData(a); + const unsigned char *data = (const unsigned char *)(a.data()); + long len = a.size(); + + if (result > 0) + do { + u_int32_t written; + u_int32_t count = (len > RFSV_SENDLEN) ? RFSV_SENDLEN : len; + res = plpRfsv->fwrite(handle, data, count, written); + if (checkForError(res, url.path())) { + plpRfsv->fclose(handle); + return; + } + len -= written; + data += written; + } while (len > 0); + } while (result > 0); + plpRfsv->fclose(handle); + finished(); } void PLPProtocol:: rename(const KURL &src, const KURL &dest, bool _overwrite) { - QString from(QFile::encodeName(src.path())); - QString to(QFile::encodeName(dest.path())); - - if (checkConnection()) - return; - kdDebug(PLP_DEBUGAREA) << "rename(" << from << "," << to << ")" << endl; - if ((driveChar(from) != driveChar(to)) && (driveChar(to) != '\0')) { - error(ERR_ACCESS_DENIED, i18n("%1 or %2: virtual directory").arg(src.path()).arg(dest.path())); - kdDebug(PLP_DEBUGAREA) << "from FS != to FS" << endl; - return; - } - if (isRomDrive(from)) { - error(ERR_ACCESS_DENIED, i18n("%1: read only filesystem").arg(src.path())); - kdDebug(PLP_DEBUGAREA) << "from ROFS" << endl; - return; - } - if (isRoot(from)) { - error(ERR_ACCESS_DENIED, i18n("%1: virtual directory").arg(src.path())); - kdDebug(PLP_DEBUGAREA) << "from VFS" << endl; - return; - } - bool volRename = isDrive(from); - if (isRomDrive(to)) { - error(ERR_ACCESS_DENIED, i18n("%1: read only filesystem").arg(dest.path())); - kdDebug(PLP_DEBUGAREA) << "to ROFS" << endl; - return; - } - if (isRoot(to)) { - error(ERR_ACCESS_DENIED, i18n("%1: virtual directory").arg(dest.path())); - kdDebug(PLP_DEBUGAREA) << "to VFS" << endl; - return; + QString from(QFile::encodeName(src.path(-1))); + QString to(QFile::encodeName(dest.path(-1))); + + if (checkConnection()) + return; + kdDebug(PLP_DEBUGAREA) << "rename(" << from << "," << to << ")" << endl; + if ((driveChar(from) != driveChar(to)) && (driveChar(to) != '\0')) { + error(ERR_ACCESS_DENIED, i18n("%1 or %2: virtual directory").arg(src.path()).arg(dest.path())); + kdDebug(PLP_DEBUGAREA) << "from FS != to FS" << endl; + return; + } + if (isRomDrive(from)) { + error(ERR_ACCESS_DENIED, i18n("%1: read only filesystem").arg(src.path())); + kdDebug(PLP_DEBUGAREA) << "from ROFS" << endl; + return; + } + if (isRoot(from)) { + error(ERR_ACCESS_DENIED, i18n("%1: virtual directory").arg(src.path())); + kdDebug(PLP_DEBUGAREA) << "from VFS" << endl; + return; + } + bool volRename = isDrive(from); + if (isRomDrive(to)) { + error(ERR_ACCESS_DENIED, i18n("%1: read only filesystem").arg(dest.path())); + kdDebug(PLP_DEBUGAREA) << "to ROFS" << endl; + return; + } + if (isRoot(to)) { + error(ERR_ACCESS_DENIED, i18n("%1: virtual directory").arg(dest.path())); + kdDebug(PLP_DEBUGAREA) << "to VFS" << endl; + return; + } + + Enum <rfsv::errs> res; + kdDebug(PLP_DEBUGAREA) << "ren: from=" << from << " to=" << to << endl; + if (volRename) { + to = to.mid(1); + res = plpRfsv->setVolumeName(driveChar(from), to); + if (res == rfsv::E_PSI_GEN_NONE) { + char drvc = driveChar(from); + drivechars.remove(from); + drivechars.insert(to, drvc); } + } else { + convertName(from); + convertName(to); + if (!_overwrite) { + u_int32_t attr; + if ((res = plpRfsv->fgetattr(to.latin1(), attr)) == rfsv::E_PSI_GEN_NONE) { - Enum <rfsv::errs> res; - kdDebug(PLP_DEBUGAREA) << "ren: from=" << from << " to=" << to << endl; - if (volRename) { - to = to.mid(1); - res = plpRfsv->setVolumeName(driveChar(from), to); - if (res == rfsv::E_PSI_GEN_NONE) { - char drvc = driveChar(from); - drivechars.remove(from); - drivechars.insert(to, drvc); - } - } else { - convertName(from); - convertName(to); - if (!_overwrite) { - u_int32_t attr; - if ((res = plpRfsv->fgetattr(to, attr)) == rfsv::E_PSI_GEN_NONE) { - - error(ERR_FILE_ALREADY_EXIST, to); - return; - } - } - res = plpRfsv->rename(from, to); - } - if (checkForError(res, src.path(), dest.path())) + error(ERR_FILE_ALREADY_EXIST, to); return; - finished(); + } + } + res = plpRfsv->rename(from.latin1(), to.latin1()); + } + if (checkForError(res, src.path(), dest.path())) + return; + finished(); } extern "C" { -static int -progresswrapper(void *ptr, u_int32_t total) { - + static int + progresswrapper(void *ptr, u_int32_t total) { + ((PLPProtocol *)ptr)->calcprogress(total); return 1; -} + } } void PLPProtocol:: calcprogress(long total) { - time_t t = time(0); - if (t - t_last) { - processedSize(total); - speed(total / (t - t_start)); - t_last = t; - } + time_t t = time(0); + if (t - t_last) { + processedSize(total); + speed(total / (t - t_start)); + t_last = t; + } } void PLPProtocol:: copy( const KURL &src, const KURL &dest, int _mode, bool _overwrite ) { - QString from( QFile::encodeName(src.path())); - QString to( QFile::encodeName(dest.path())); + QString from( QFile::encodeName(src.path(-1))); + QString to( QFile::encodeName(dest.path(-1))); + + if (checkConnection()) + return; + kdDebug(PLP_DEBUGAREA) << "copy(" << from << "," << to << ")" << endl; + if (isRoot(from) || isDrive(from)) { + error(ERR_ACCESS_DENIED, i18n("%1 or %2: virtual directory").arg(src.path()).arg(dest.path())); + return; + } + convertName(from); + if (isRomDrive(to)) { + error(ERR_ACCESS_DENIED, i18n("%1: read only filesystem").arg(dest.path())); + return; + } + if (isRoot(to) || isDrive(to)) { + error(ERR_ACCESS_DENIED, i18n("%1: virtual directory").arg(dest.path())); + return; + } + convertName(to); + Enum <rfsv::errs> res; + if (!_overwrite) { + u_int32_t attr; + if ((res = plpRfsv->fgetattr(to.latin1(), attr)) == rfsv::E_PSI_GEN_NONE) { + error(ERR_FILE_ALREADY_EXIST, to); + return; + } + } + if (emitTotalSize(from)) + return; + t_last = t_start = time(0); + res = plpRfsv->copyOnPsion(from.latin1(), to.latin1(), (void *)this, progresswrapper); + if (checkForError(res, src.path(), dest.path())) + return; + finished(); +} + +void PLPProtocol:: +special(const QByteArray &a) { + kdDebug(PLP_DEBUGAREA) << "special()" << endl; + + QDataStream stream(a, IO_ReadOnly); + int cmd; + UDSEntry entry; + UDSAtom atom; + + if (checkConnection()) + return; + + stream >> cmd; - if (checkConnection()) + switch (cmd) { + case 1: { + kdDebug(PLP_DEBUGAREA) << "get DriveDetails" << endl; + QString param; + PlpDrive drive; + + Enum<rfsv::errs> res; + int drv; + + stream >> param; + cout << "p='" << param << "'" << endl; + if (param.isEmpty()) { + error(ERR_MALFORMED_URL, i18n("(empty)")); return; - kdDebug(PLP_DEBUGAREA) << "copy(" << from << "," << to << ")" << endl; - if (isRoot(from) || isDrive(from)) { - error(ERR_ACCESS_DENIED, i18n("%1 or %2: virtual directory").arg(src.path()).arg(dest.path())); + } + if (!isDrive(param)) { + error(ERR_PROTOCOL_IS_NOT_A_FILESYSTEM, param); return; - } - convertName(from); - if (isRomDrive(to)) { - error(ERR_ACCESS_DENIED, i18n("%1: read only filesystem").arg(dest.path())); + } + param = param.mid(1); + drv = drivechars[param] - 'A'; + res = plpRfsv->devinfo(drv, drive); + if (res != rfsv::E_PSI_GEN_NONE) { + error(ERR_COULD_NOT_STAT, param); return; + } + + string mtype; + drive.getMediaType(mtype); + + // DriveLetter + atom.m_uds = KIO::UDS_USER; + atom.m_str = QString("%1").arg(drivechars[param]); + entry.append(atom); + // TypeName + atom.m_uds = KIO::UDS_NAME; + atom.m_str = QString(mtype.c_str()); + entry.append(atom); + // Total capacity + atom.m_uds = KIO::UDS_SIZE; + atom.m_long = drive.getSize(); + entry.append(atom); + // Free capacity + atom.m_uds = KIO::UDS_MODIFICATION_TIME; + atom.m_long = drive.getSpace(); + entry.append(atom); + // UID + atom.m_uds = KIO::UDS_CREATION_TIME; + atom.m_long = drive.getUID(); + entry.append(atom); + + statEntry(entry); } - if (isRoot(to) || isDrive(to)) { - error(ERR_ACCESS_DENIED, i18n("%1: virtual directory").arg(dest.path())); + break; + case 2: { + kdDebug(PLP_DEBUGAREA) << "get Ownerinfo" << endl; + bufferArray b; + + Enum<rfsv::errs> res = plpRpcs->getOwnerInfo(b); + if (res != rfsv::E_PSI_GEN_NONE) { + error(ERR_COULD_NOT_STAT, "Owner"); return; + } + QString param = ""; + while (!b.empty()) { + param += b.pop().getString(); + param += "\n"; + } + // Owner-String + atom.m_uds = KIO::UDS_NAME; + atom.m_str = param; + entry.append(atom); + statEntry(entry); } - convertName(to); - Enum <rfsv::errs> res; - if (!_overwrite) { - u_int32_t attr; - if ((res = plpRfsv->fgetattr(to, attr)) == rfsv::E_PSI_GEN_NONE) { - error(ERR_FILE_ALREADY_EXIST, to); - return; - } - } - if (emitTotalSize(from)) - return; - t_last = t_start = time(0); - res = plpRfsv->copyOnPsion(from, to, (void *)this, progresswrapper); - if (checkForError(res, src.path(), dest.path())) + break; + case 3: { + kdDebug(PLP_DEBUGAREA) << "get Fileattribs" << endl; + + QString name; + PlpDirent e; + bool isRoFS; + + stream >> name; + + if (name.isEmpty()) { + error(ERR_MALFORMED_URL, i18n("(empty)")); return; - finished(); -} + } + if (isRoot(name) || isDrive(name)) { + error(ERR_ACCESS_DENIED, i18n("%1: virtual directory").arg(name)); + return; + } + isRoFS = isRomDrive(name); + convertName(name); + Enum<rfsv::errs> res = plpRfsv->fgeteattr(name.latin1(), e); + if (checkForError(res, name)) + return; + // Attributes + atom.m_uds = KIO::UDS_SIZE; + atom.m_long = e.getAttr(); + entry.append(atom); + // bool ReadonlyFS (for disabling checkboxes in attr dialog) + atom.m_uds = KIO::UDS_CREATION_TIME; + u_int32_t flags = (machType == rpcs::PSI_MACH_S5) ? 1 : 0; + flags |= (isRoFS) ? 2 : 0; + atom.m_long = flags; + entry.append(atom); + // Psion Path + atom.m_uds = KIO::UDS_NAME; + atom.m_str = name; + entry.append(atom); + + statEntry(entry); + kdDebug(PLP_DEBUGAREA) << "get Fileattribs done OK" << endl; + } + break; + case 4: { + kdDebug(PLP_DEBUGAREA) << "set Fileattribs" << endl; -void PLPProtocol:: -special(const QByteArray &a) { - kdDebug(PLP_DEBUGAREA) << "special()" << endl; + QString name; + u_int32_t seta, unseta; - QDataStream stream(a, IO_ReadOnly); - int tmp; - UDSEntry entry; - UDSAtom atom; + stream >> seta >> unseta >> name; - stream >> tmp; - - switch (tmp) { - case 1: { - QString param; - PlpDrive drive; - - Enum<rfsv::errs> res; - int drv; - - stream >> param; - - if (!isDrive(QString("/") + param)) { - error(ERR_PROTOCOL_IS_NOT_A_FILESYSTEM, param); - return; - } - drv = drivechars[param] - 'A'; - res = plpRfsv->devinfo(drv, drive); - if (res != rfsv::E_PSI_GEN_NONE) { - error(ERR_COULD_NOT_STAT, param); - return; - } - - string mtype; - drive.getMediaType(mtype); - - // DriveLetter - atom.m_uds = KIO::UDS_USER; - atom.m_str = QString("%1").arg(drivechars[param]); - entry.append(atom); - // TypeName - atom.m_uds = KIO::UDS_NAME; - atom.m_str = QString(mtype.c_str()); - entry.append(atom); - // Total capacity - atom.m_uds = KIO::UDS_SIZE; - atom.m_long = drive.getSize(); - entry.append(atom); - // Free capacity - atom.m_uds = KIO::UDS_MODIFICATION_TIME; - atom.m_long = drive.getSpace(); - entry.append(atom); - // UID - atom.m_uds = KIO::UDS_CREATION_TIME; - atom.m_long = drive.getUID(); - entry.append(atom); - statEntry(entry); - } - break; - default: - error(ERR_UNSUPPORTED_PROTOCOL, QString(i18n("Code: %1")).arg(tmp)); - return; + if (name.isEmpty()) { + error(ERR_MALFORMED_URL, i18n("(empty)")); + return; + } + if (isRoot(name) || isDrive(name)) { + error(ERR_ACCESS_DENIED, i18n("%1: virtual directory").arg(name)); + return; + } + if (isRomDrive(name)) { + error(ERR_ACCESS_DENIED, i18n("%1: read only filesystem").arg(name)); + return; + } + convertName(name); + Enum<rfsv::errs> res = plpRfsv->fsetattr(name.latin1(), seta, + unseta); + if (checkForError(res, name)) + return; } - finished(); + break; + case 5: { + kdDebug(PLP_DEBUGAREA) << "get machineInfo" << endl; + QByteArray a(sizeof(machInfo)); + a.duplicate((const char *)&machInfo, sizeof(machInfo)); + data(a); + data(QByteArray()); + } + break; + default: + error(ERR_UNSUPPORTED_PROTOCOL, QString(i18n("Code: %1")).arg(cmd)); + return; + } + finished(); } + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ diff --git a/kde2/kioslave/kio_plp.h b/kde2/kioslave/kio_plp.h index d5841bb..9119e6d 100644 --- a/kde2/kioslave/kio_plp.h +++ b/kde2/kioslave/kio_plp.h @@ -1,24 +1,27 @@ -/* This file is part of the KDE project - Copyright (C) 2000 Alexander Neundorf <neundorf@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. -*/ - -#ifndef KIO_PLP_H -#define KIO_PLP_H +/*-*-c++-*- + * $Id$ + * + * This file is part of plptools. + * + * Copyright (C) 2001 Fritz Elfert <felfert@to.com> + * + * 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 _KIO_PLP_H_ +#define _KIO_PLP_H_ #include <kio/slavebase.h> #include <kio/global.h> @@ -31,57 +34,66 @@ typedef QMap<PlpUID,QString> UidMap; -class PLPProtocol : public KIO::SlaveBase -{ +class PLPProtocol : public KIO::SlaveBase { public: - PLPProtocol (const QCString &pool, const QCString &app); - virtual ~PLPProtocol(); + PLPProtocol (const QCString &pool, const QCString &app); + virtual ~PLPProtocol(); - virtual void openConnection(); - virtual void closeConnection(); + virtual void openConnection(); + virtual void closeConnection(); + + virtual void setHost(const QString& host, int port, const QString&, const QString&); - virtual void setHost(const QString& host, int port, const QString&, const QString&); + virtual void put(const KURL& url, int _mode,bool _overwrite, bool _resume); + virtual void get(const KURL& url); + virtual void listDir(const KURL& url); + virtual void stat(const KURL & url); + virtual void mimetype(const KURL & url); + virtual void mkdir(const KURL& url, int permissions); + virtual void del(const KURL& url, bool isfile); + virtual void chmod(const KURL& url, int permissions); + virtual void rename(const KURL &src, const KURL &dest, bool overwrite); + virtual void copy(const KURL& src, const KURL &dest, int mode, bool overwrite ); + virtual void special(const QByteArray &a); - virtual void put(const KURL& url, int _mode,bool _overwrite, bool _resume); - virtual void get(const KURL& url); - virtual void listDir(const KURL& url); - virtual void stat(const KURL & url); - virtual void mimetype(const KURL & url); - virtual void mkdir(const KURL& url, int permissions); - virtual void del(const KURL& url, bool isfile); - virtual void chmod(const KURL& url, int permissions); - virtual void rename(const KURL &src, const KURL &dest, bool overwrite); - virtual void copy(const KURL& src, const KURL &dest, int mode, bool overwrite ); - virtual void special(const QByteArray &a); + void calcprogress(long total); - void calcprogress(long total); private: - bool checkConnection(); + bool checkConnection(); - char driveChar(const QString& path); + char driveChar(const QString& path); - void createVirtualDirEntry(KIO::UDSEntry & entry, bool rdonly, int type); - void completeUDSEntry(KIO::UDSEntry& entry, PlpDirent &e, bool rom); - bool checkForError(Enum<rfsv::errs> res, QString name1 = QString(0), QString name2 = QString(0)); - bool isRomDrive(const QString& path); - bool isDrive(const QString& path); - bool isRoot(const QString& path); - void convertName(QString &path); - bool emitTotalSize(QString &name); - QString uid2mime(PlpDirent &e); - int checkSpecial(const QString& path); + void createVirtualDirEntry(KIO::UDSEntry & entry, bool rdonly, int type); + void completeUDSEntry(KIO::UDSEntry& entry, PlpDirent &e, bool rom); + bool checkForError(Enum<rfsv::errs> res, QString name1 = QString(0), QString name2 = QString(0)); + bool isRomDrive(const QString& path); + bool isDrive(const QString& path); + bool isRoot(const QString& path); + void convertName(QString &path); + bool emitTotalSize(QString &name); + QString uid2mime(PlpDirent &e); + int checkSpecial(const QString& path); + void setOwner(KIO::UDSEntry & entry); - rfsv *plpRfsv; - ppsocket *plpRfsvSocket; - QStringList drives; - QMap<QString,char> drivechars; - UidMap puids; - QString currentHost; - int currentPort; - time_t t_last; - time_t t_start; - Enum<rpcs::machs> machType; - rpcs::machineInfo mi; + rfsv *plpRfsv; + rpcs *plpRpcs; + ppsocket *plpRfsvSocket; + ppsocket *plpRpcsSocket; + QStringList drives; + QMap<QString,char> drivechars; + UidMap puids; + QString currentHost; + int currentPort; + time_t t_last; + time_t t_start; + Enum<rpcs::machs> machType; + rpcs::machineInfo machInfo; }; #endif + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ diff --git a/kde2/kioslave/psion.protocol b/kde2/kioslave/psion.protocol index c77c486..5281723 100644 --- a/kde2/kioslave/psion.protocol +++ b/kde2/kioslave/psion.protocol @@ -4,7 +4,7 @@ protocol=psion input=none output=filesystem defaultMimetype=inode/directory -listing=Name,Type,Size,Date,Access +listing=Name,Type,Size,Date,Access,MimeType reading=true writing=true makedir=true diff --git a/kde2/kpsion/Makefile.am b/kde2/kpsion/Makefile.am new file mode 100644 index 0000000..85f70fa --- /dev/null +++ b/kde2/kpsion/Makefile.am @@ -0,0 +1,31 @@ +# $Id$ + +METASOURCES = AUTO + +KDE_ICON = AUTO + +INCLUDES = $(all_includes) -I$(top_srcdir)/lib + +DISTCLEANFILES = $(kpsion_METASOURCES) ./.deps/* ./.deps/.P + +lib_LTLIBRARIES = libkpsion.la +bin_PROGRAMS = kpsion + +libkpsion_la_LDFLAGS = $(LIBDEBUG) $(all_libraries) -module -version-info $(LIBVERSION) +libkpsion_la_SOURCES = kpsion.cpp setupdialog.cpp wizards.cpp +libkpsion_la_LIBADD = -L$(top_srcdir)/lib -lplp $(LIB_KFILE) + +kpsion_SOURCES = main.cpp +kpsion_LDFLAGS = $(KDE_RPATH) +kpsion_LDADD = libkpsion.la $(top_srcdir)/lib/libplp.la + +applnk_DATA = kpsion.desktop +applnkdir = $(kde_appsdir)/Utilities + +rcdir = $(kde_datadir)/kpsion +rc_DATA = kpsionui.rc + +noinst_HEADERS = kpsion.h setupdialog.h wizards.h + +messages: + $(XGETTEXT) -C -ki18n -kI18N_NOOP -ktranslate -kaliasLocale *.cpp *.h && mv messages.po ../po/kpsion.pot diff --git a/kde2/kpsion/kpsion.cpp b/kde2/kpsion/kpsion.cpp new file mode 100644 index 0000000..808ed1a --- /dev/null +++ b/kde2/kpsion/kpsion.cpp @@ -0,0 +1,1046 @@ +/*-*-c++-*- + * $Id$ + * + * This file is part of plptools. + * + * Copyright (C) 1999 Philip Proudman <philip.proudman@btinternet.com> + * Copyright (C) 2000, 2001 Fritz Elfert <felfert@to.com> + * + * 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 + * + */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "kpsion.h" +#include "wizards.h" + +#include <kapp.h> +#include <klocale.h> +#include <kaction.h> +#include <kstdaction.h> +#include <kconfig.h> +#include <kiconview.h> +#include <kmessagebox.h> +#include <kfileitem.h> + +#include <qwhatsthis.h> +#include <qtimer.h> +#include <qlayout.h> +#include <qiodevice.h> +#include <qdir.h> + +#include <ppsocket.h> +#include <rfsvfactory.h> +#include <rpcsfactory.h> +#include <bufferarray.h> + +#include <iomanip> +#include <strstream> + +// internal use for developing offline without +// having a Psion connected. +// !!!!! set to 0 for production code !!!!! +#define OFFLINE 0 + +#define STID_CONNECTION 1 + +void KPsionCheckListItem:: +init(bool myparent) { + setSelectable(false); + dontPropagate = false; + parentIsKPsionCheckListItem = myparent; +} + +void KPsionCheckListItem:: +setMetaData(int bType, time_t bWhen) { + backupType = bType; + when = bWhen; +} + +void KPsionCheckListItem:: +stateChange(bool state) { + QCheckListItem::stateChange(state); + + if (dontPropagate) + return; + if (parentIsKPsionCheckListItem) + ((KPsionCheckListItem *)parent())->propagateUp(state); + propagateDown(state); +} + +void KPsionCheckListItem:: +propagateDown(bool state) { + setOn(state); + KPsionCheckListItem *child = (KPsionCheckListItem *)firstChild(); + while (child) { + child->propagateDown(state); + child = (KPsionCheckListItem *)child->nextSibling(); + } +} + +void KPsionCheckListItem:: +propagateUp(bool state) { + bool deactivateThis = false; + + KPsionCheckListItem *child = (KPsionCheckListItem *)firstChild(); + while (child) { + if ((child->isOn() != state) || (!child->isEnabled())) { + deactivateThis = true; + break; + } + child = (KPsionCheckListItem *)child->nextSibling(); + } + dontPropagate = true; + if (deactivateThis) { + setOn(true); + setEnabled(false); + } else { + setEnabled(true); + setOn(state); + } + // Bug in QListView? It doesn't update, when + // enabled/disabled without activating. + // -> force it. + listView()->repaintItem(this); + dontPropagate = false; + if (parentIsKPsionCheckListItem) + ((KPsionCheckListItem *)parent())->propagateUp(state); +} + +KPsionBackupListView::KPsionBackupListView(QWidget *parent, const char *name) + : KListView(parent, name) { + + toRestore.clear(); + uid = QString::null; + KConfig *config = kapp->config(); + config->setGroup("Settings"); + backupDir = config->readEntry("BackupDir"); + addColumn(i18n("Available backups")); + setRootIsDecorated(true); +} + +void KPsionBackupListView:: +readBackups(QString uid) { + QString bdir(backupDir); + bdir += "/"; + bdir += uid; + QDir d(bdir); + const QFileInfoList *fil = + d.entryInfoList("*.tar.gz", QDir::Files|QDir::Readable, QDir::Name); + QFileInfoListIterator it(*fil); + QFileInfo *fi; + while ((fi = it.current())) { + bool isValid = false; + KTarGz tgz(fi->absFilePath()); + const KTarEntry *te; + QString bTypeName; + int bType; + QDateTime date; + + tgz.open(IO_ReadOnly); + te = tgz.directory()->entry("KPsionFullIndex"); + if (te && (!te->isDirectory())) { + date.setTime_t(te->date()); + bTypeName = i18n("Full"); + bType = FULL; + isValid = true; + } else { + te = tgz.directory()->entry("KPsionIncrementalIndex"); + if (te && (!te->isDirectory())) { + date.setTime_t(te->date()); + bTypeName = i18n("Incremental"); + bType = INCREMENTAL; + isValid = true; + } + } + + if (isValid) { + QString n = i18n("%1 backup, created at %2").arg(bTypeName).arg(date.toString()); + + KPsionCheckListItem *i = + new KPsionCheckListItem(this, n, + KPsionCheckListItem::CheckBox); + i->setMetaData(bType, te->date()); + i->setPixmap(0, KGlobal::iconLoader()->loadIcon("mime_empty", KIcon::Small)); + QStringList files = tgz.directory()->entries(); + for (QStringList::Iterator f = files.begin(); + f != files.end(); f++) + if ((*f != "KPsionFullIndex") && + (*f != "KPsionIncrementalIndex")) + listTree(i, tgz.directory()->entry(*f), 0); + } + tgz.close(); + ++it; + } +} + +void KPsionBackupListView:: +listTree(KPsionCheckListItem *cli, const KTarEntry *te, int level) { + KPsionCheckListItem *i = + new KPsionCheckListItem(cli, te->name(), + KPsionCheckListItem::CheckBox); + if (te->isDirectory()) { + if (level) + i->setPixmap(0, KGlobal::iconLoader()->loadIcon("folder", + KIcon::Small)); + else + i->setPixmap(0, KGlobal::iconLoader()->loadIcon("hdd_unmount", + KIcon::Small)); + KTarDirectory *td = (KTarDirectory *)te; + QStringList files = td->entries(); + for (QStringList::Iterator f = files.begin(); f != files.end(); f++) + listTree(i, td->entry(*f), level + 1); + } else + i->setPixmap(0, KGlobal::iconLoader()->loadIcon("mime_empty", + KIcon::Small)); +} + +PlpDir &KPsionBackupListView:: +getRestoreList() { + return toRestore; +} + +KPsionMainWindow::KPsionMainWindow() + : KMainWindow() { + setupActions(); + + statusBar()->insertItem(i18n("Idle"), STID_CONNECTION, 1); + statusBar()->setItemAlignment(STID_CONNECTION, + QLabel::AlignLeft|QLabel::AlignVCenter); + + backupRunning = false; + restoreRunning = false; + formatRunning = false; + + view = new KIconView(this, "iconview"); + view->setSelectionMode(KIconView::Multi); + view->setResizeMode(KIconView::Adjust); + view->setItemsMovable(false); + connect(view, SIGNAL(clicked(QIconViewItem *)), + SLOT(iconClicked(QIconViewItem *))); + connect(view, SIGNAL(onItem(QIconViewItem *)), + SLOT(iconOver(QIconViewItem *))); + KConfig *config = kapp->config(); + config->setGroup("Psion"); + QStringList uids = config->readListEntry("MachineUIDs"); + for (QStringList::Iterator it = uids.begin(); it != uids.end(); it++) { + QString tmp = QString::fromLatin1("Name_%1").arg(*it); + machines.insert(*it, config->readEntry(tmp)); + } + config->setGroup("Settings"); + backupDir = config->readEntry("BackupDir"); + config->setGroup("Connection"); + reconnectTime = config->readNumEntry("Retry"); + ncpdDevice = config->readEntry("Device", i18n("off")); + ncpdSpeed = config->readNumEntry("Speed", 115200); + + QWhatsThis::add(view, i18n( + "<qt>Here, you see your Psion's drives.<br/>" + "Every drive is represented by an Icon. If you " + "click on it, it gets selected for the next " + "operation. E.g.: backup, restore or format.<br/>" + "To unselect it, simply click on it again.<br/>" + "Select as many drives a you want, then choose " + "an operation.</qt>")); + setCentralWidget(view); + + rfsvSocket = 0L; + rpcsSocket = 0L; + plpRfsv = 0L; + plpRpcs = 0L; + + firstTry = true; + connected = false; + shuttingDown = false; + + tryConnect(); +} + +KPsionMainWindow::~KPsionMainWindow() { + shuttingDown = true; + if (plpRfsv) + delete plpRfsv; + if (plpRpcs) + delete plpRpcs; + if (rfsvSocket) + delete rfsvSocket; + if (rfsvSocket) + delete rpcsSocket; +} + +void KPsionMainWindow:: +setupActions() { + + KStdAction::quit(this, SLOT(close()), actionCollection()); + KStdAction::showToolbar(this, SLOT(slotToggleToolbar()), + actionCollection()); + KStdAction::showStatusbar(this, SLOT(slotToggleStatusbar()), + actionCollection()); + KStdAction::saveOptions(this, SLOT(slotSaveOptions()), + actionCollection()); + KStdAction::preferences(this, SLOT(slotPreferences()), + actionCollection()); + new KAction(i18n("Start &Format"), 0L, 0, this, + SLOT(slotStartFormat()), actionCollection(), "format"); + new KAction(i18n("Start Full &Backup"), "psion_backup", 0, this, + SLOT(slotStartFullBackup()), actionCollection(), + "fullbackup"); + new KAction(i18n("Start &Incremental Backup"), "psion_backup", 0, this, + SLOT(slotStartIncBackup()), actionCollection(), "incbackup"); + new KAction(i18n("Start &Restore"), "psion_restore", 0, this, + SLOT(slotStartRestore()), actionCollection(), "restore"); + createGUI(); + + actionCollection()->action("fullbackup")->setEnabled(false); + actionCollection()->action("incbackup")->setEnabled(false); +#if OFFLINE + actionCollection()->action("restore")->setEnabled(true); +#else + actionCollection()->action("restore")->setEnabled(false); +#endif + actionCollection()->action("format")->setEnabled(false); + + actionCollection()->action("fullbackup")-> + setToolTip(i18n("Full backup of selected drive(s)")); + actionCollection()->action("incbackup")-> + setToolTip(i18n("Incremental backup of selected drive(s)")); + actionCollection()->action("restore")-> + setToolTip(i18n("Restore selected drive(s)")); + actionCollection()->action("format")-> + setToolTip(i18n("Format selected drive(s)")); +} + +void KPsionMainWindow:: +iconOver(QIconViewItem *i) { + lastSelected = i->isSelected(); +} + +void KPsionMainWindow:: +switchActions() { + QIconViewItem *i; + bool rwSelected = false; + bool anySelected = false; + + if (backupRunning | restoreRunning | formatRunning) + view->setEnabled(false); + else { + for (i = view->firstItem(); i; i = i->nextItem()) { + if (i->isSelected()) { + anySelected = true; + if (i->key() != "Z") { + rwSelected = true; + break; + } + } + } + view->setEnabled(true); + } +#if OFFLINE + actionCollection()->action("restore")->setEnabled(true); +#else + actionCollection()->action("restore")->setEnabled(rwSelected); +#endif + actionCollection()->action("format")->setEnabled(rwSelected); + actionCollection()->action("fullbackup")->setEnabled(anySelected); + actionCollection()->action("incbackup")->setEnabled(anySelected); +} + +void KPsionMainWindow:: +iconClicked(QIconViewItem *i) { + if (i == 0L) + return; + lastSelected = !lastSelected; + i->setSelected(lastSelected); + switchActions(); +} + +void KPsionMainWindow:: +insertDrive(char letter, const char * const name) { + QString tmp; + + if (name && strlen(name)) + tmp = QString::fromLatin1("%1 (%2:)").arg(name).arg(letter); + else + tmp = QString::fromLatin1("%1:").arg(letter); + drives.insert(letter,tmp); + QIconViewItem *it = + new QIconViewItem(view, tmp, + KFileItem(KURL(), "inode/x-psion-drive", 0).pixmap(0)); + tmp = QString::fromLatin1("%1").arg(letter); + it->setKey(tmp); + it->setDropEnabled(false); + it->setDragEnabled(false); + it->setRenameEnabled(false); +} + +void KPsionMainWindow:: +queryPsion() { + u_int32_t devbits; + Enum <rfsv::errs> res; + + statusBar()->changeItem(i18n("Retrieving machine info ..."), + STID_CONNECTION); +#if OFFLINE + machineUID = 0x1000118a0c428fa3ULL; + S5mx = true; + insertDrive('C', "Intern"); + insertDrive('D', "Flash"); + insertDrive('Z', "RomDrive"); +#else + 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); +#endif + + QString uid = getMachineUID(); + bool machineFound = false; + KConfig *config = kapp->config(); + config->setGroup("Psion"); + machineName = i18n("an unknown machine"); + psionMap::Iterator it; + for (it = machines.begin(); it != machines.end(); it++) { + if (uid == it.key()) { + machineName = it.data(); + QString tmp = + QString::fromLatin1("BackupDrives_%1").arg(it.key()); + backupDrives = config->readListEntry(tmp); + machineFound = true; + } + } +#if (!(OFFLINE)) + drives.clear(); + statusBar()->changeItem(i18n("Retrieving drive list ..."), + STID_CONNECTION); + if ((res = plpRfsv->devlist(devbits)) != rfsv::E_PSI_GEN_NONE) { + QString msg = i18n("Could not get list of drives"); + statusBar()->changeItem(msg, STID_CONNECTION); + KMessageBox::error(this, msg); + return; + } + for (int i = 0; i < 26; i++) { + if ((devbits & 1) != 0) { + PlpDrive drive; + if (plpRfsv->devinfo(i, drive) == rfsv::E_PSI_GEN_NONE) + insertDrive('A' + i, drive.getName().c_str()); + } + devbits >>= 1; + } +#endif + if (!machineFound) { + NewPsionWizard *wiz = new NewPsionWizard(this, "newpsionwiz"); + wiz->exec(); + } + statusBar()->changeItem(i18n("Connected to %1").arg(machineName), + STID_CONNECTION); +} + +QString KPsionMainWindow:: +getMachineUID() { + // ??! None of QString's formatting methods knows about long long. + ostrstream s; + s << hex << setw(16) << machineUID; + QString ret = s.str(); + ret = ret.left(16); + return ret; +} + +bool KPsionMainWindow:: +queryClose() { + QString msg = 0L; + + if (backupRunning) + msg = i18n("A backup is running.\nDo you really want to quit?"); + if (restoreRunning) + msg = i18n("A restore is running.\nDo you really want to quit?"); + if (formatRunning) + msg = i18n("A format is running.\nDo you really want to quit?"); + + if ((!msg.isNull()) && + (KMessageBox::warningYesNo(this, msg) == KMessageBox::No)) + return false; + return true; +} + +void KPsionMainWindow:: +tryConnect() { +#if (!(OFFLINE)) + if (shuttingDown || connected) + return; + bool showMB = firstTry; + firstTry = false; + + if (plpRfsv) + delete plpRfsv; + if (plpRpcs) + delete plpRpcs; + if (rfsvSocket) + delete rfsvSocket; + if (rfsvSocket) + delete rpcsSocket; + + rfsvSocket = new ppsocket(); + statusBar()->changeItem(i18n("Connecting ..."), STID_CONNECTION); + if (!rfsvSocket->connect(NULL, 7501)) { + statusMsg = i18n("RFSV could not connect to ncpd at %1:%2. ").arg("localhost").arg(7501); + if (reconnectTime) { + nextTry = reconnectTime; + statusMsg += i18n(" (Retry in %1 seconds.)"); + QTimer::singleShot(1000, this, SLOT(slotUpdateTimer())); + } + statusBar()->changeItem(statusMsg.arg(reconnectTime), + STID_CONNECTION); + if (showMB) + KMessageBox::error(this, statusMsg.arg(reconnectTime)); + return; + } + rfsvfactory factory(rfsvSocket); + plpRfsv = factory.create(false); + if (plpRfsv == 0L) { + statusMsg = i18n("RFSV could not establish link: %1.").arg(factory.getError()); + delete rfsvSocket; + rfsvSocket = 0L; + if (reconnectTime) { + nextTry = reconnectTime; + statusMsg += i18n(" (Retry in %1 seconds.)"); + QTimer::singleShot(1000, this, SLOT(slotUpdateTimer())); + } + statusBar()->changeItem(statusMsg.arg(reconnectTime), + STID_CONNECTION); + if (showMB) + KMessageBox::error(this, statusMsg.arg(reconnectTime)); + return; + } + + rpcsSocket = new ppsocket(); + if (!rpcsSocket->connect(NULL, 7501)) { + statusMsg = i18n("RPCS could not connect to ncpd at %1:%2.").arg("localhost").arg(7501); + delete plpRfsv; + plpRfsv = 0L; + delete rfsvSocket; + rfsvSocket = 0L; + if (reconnectTime) { + nextTry = reconnectTime; + statusMsg += i18n(" (Retry in %1 seconds.)"); + QTimer::singleShot(1000, this, SLOT(slotUpdateTimer())); + } + statusBar()->changeItem(statusMsg.arg(reconnectTime), + STID_CONNECTION); + if (showMB) + KMessageBox::error(this, statusMsg.arg(reconnectTime)); + return; + } + rpcsfactory factory2(rpcsSocket); + plpRpcs = factory2.create(false); + if (plpRpcs == 0L) { + statusMsg = i18n("RPCS could not establish link: %1.").arg(factory.getError()); + delete plpRfsv; + plpRfsv = 0L; + delete rfsvSocket; + rfsvSocket = 0L; + delete rpcsSocket; + rpcsSocket = 0L; + if (reconnectTime) { + nextTry = reconnectTime; + statusMsg += i18n(" (Retry in %1 seconds.)"); + QTimer::singleShot(1000, this, SLOT(slotUpdateTimer())); + } + statusBar()->changeItem(statusMsg.arg(reconnectTime), + STID_CONNECTION); + if (showMB) + KMessageBox::error(this, statusMsg.arg(reconnectTime)); + return; + } +#endif + connected = true; + queryPsion(); +} + +void KPsionMainWindow:: +slotUpdateTimer() { + nextTry--; + if (nextTry <= 0) + tryConnect(); + else { + statusBar()->changeItem(statusMsg.arg(nextTry), STID_CONNECTION); + QTimer::singleShot(1000, this, SLOT(slotUpdateTimer())); + } +} + +void KPsionMainWindow:: +slotStartFullBackup() { + fullBackup = true; + doBackup(); +} + +void KPsionMainWindow:: +slotStartIncBackup() { + fullBackup = false; + doBackup(); +} + +void KPsionMainWindow:: +doBackup() { + backupRunning = true; + switchActions(); + toBackup.clear(); + KDialog *d = new KDialog(this, "backupDialog", false); + d->setCaption(i18n("Backup")); + QGridLayout *gl = new QGridLayout(d); + progressLabel = new KSqueezedTextLabel(d); + gl->addWidget(progressLabel, 1, 1); + progress = new KProgress(0, 100, 0, KProgress::Horizontal, d, + "backupProgress"); + + gl->addWidget(progress, 2, 1); + gl->addRowSpacing(0, KDialog::marginHint()); + gl->addRowSpacing(3, KDialog::marginHint()); + gl->addColSpacing(0, KDialog::marginHint()); + gl->addColSpacing(2, KDialog::marginHint()); + gl->setColStretch(1, 1); + gl->setRowStretch(1, 1); + d->setMinimumSize(250, 80); + d->show(); + + // Collect list of files to backup + backupSize = 0; + backupCount = 0; + progressTotal = 0; + for (QIconViewItem *i = view->firstItem(); i; i = i->nextItem()) { + if (i->isSelected()) { + QString drv = i->key(); + drv += ":"; + int drvNum = *(drv.data()) - 'A'; + PlpDrive drive; + if (plpRfsv->devinfo(drvNum, drive) != rfsv::E_PSI_GEN_NONE) { + KMessageBox::error(this, i18n("Could not retrieve drive details for drive %1").arg(drv)); + d->hide(); + delete d; + backupRunning = false; + switchActions(); + return; + } + progressLabel->setText(i18n("Scanning drive %1").arg(drv)); + + progressLocal = drive.getSize() - drive.getSpace(); + progressLocalCount = 0; + progressLocalPercent = -1; + progress->setValue(0); + collectFiles(drv); + } + } + progressLabel->setText(i18n("%1 files need backup").arg(backupSize)); + if (backupCount == 0) { + KMessageBox::information(this, i18n("No files need backup")); + d->hide(); + delete d; + backupRunning = false; + switchActions(); + return; + } + + statusBar()->message(i18n("Backup")); + progressCount = 0; + progressTotal = backupSize; + progressPercent = -1; + + // Create tgz with index file. + QString archiveName = backupDir; + if (archiveName.right(1) != "/") + archiveName += "/"; + archiveName += getMachineUID(); + QDir archiveDir(archiveName); + if (!archiveDir.exists()) + if (!archiveDir.mkdir(archiveName)) { + KMessageBox::error(this, i18n("Could not create backup folder %1").arg(archiveName)); + d->hide(); + delete d; + statusBar()->clear(); + backupRunning = false; + switchActions(); + return; + } + + archiveName += (fullBackup) ? "/F-" : "/I-"; + time_t now = time(0); + char tstr[30]; + strftime(tstr, sizeof(tstr), "%Y-%m-%d-%H-%M-%S.tar.gz", + localtime(&now)); + archiveName += tstr; + backupTgz = new KTarGz(archiveName); + backupTgz->open(IO_WriteOnly); + createIndex(); + + // Kill all running applications on the Psion + // and save their state. + killSave(); + + bool badBackup = false; + Enum<rfsv::errs> res; + // Now the real backup + for (int i = 0; i < toBackup.size(); i++) { + PlpDirent e = toBackup[i]; + const char *fn = e.getName(); + const char *p; + char *q; + char unixname[1024]; + + for (p = fn, q = unixname; *p; p++, q++) + switch (*p) { + case '%': + *q++ = '%'; + *q++ = '2'; + *q = '5'; + break; + case '/': + *q++ = '%'; + *q++ = '2'; + *q= 'f'; + break; + case '\\': + *q = '/'; + break; + default: + *q = *p; + } + *q = '\0'; + + ostrstream os; + + progressLabel->setText(i18n("Backing up %1").arg(fn)); + progressLocal = e.getSize(); + progressLocalCount = 0; + progressLocalPercent = -1; + progress->setValue(0); + + u_int32_t handle; + + kapp->processEvents(); + res = plpRfsv->fopen(plpRfsv->opMode(rfsv::PSI_O_RDONLY), fn, + handle); + if (res != rfsv::E_PSI_GEN_NONE) { + if (KMessageBox::warningYesNo(this, i18n("<QT>Could not open<BR/><B>%1</B></QT>").arg(fn)) == KMessageBox::No) { + badBackup = true; + break; + } else { + e.setName("!"); + continue; + } + } + unsigned char *buff = new unsigned char[RFSV_SENDLEN]; + u_int32_t len; + do { + if ((res = plpRfsv->fread(handle, buff, RFSV_SENDLEN, len)) == + rfsv::E_PSI_GEN_NONE) { + os.write(buff, len); + updateProgress(len); + } + kapp->processEvents(); + } while ((len > 0) && (res == rfsv::E_PSI_GEN_NONE)); + delete[]buff; + plpRfsv->fclose(handle); + if (res != rfsv::E_PSI_GEN_NONE) { + if (KMessageBox::warningYesNo(this, i18n("<QT>Could not read<BR/><B>%1</B></QT>").arg(fn)) == KMessageBox::No) { + badBackup = true; + break; + } else { + e.setName("!"); + continue; + } + } + backupTgz->writeFile(unixname, "root", "root", os.pcount(), + os.str()); + } + + if (!badBackup) { + // Reset archive attributes of all backuped files. + progressLabel->setText(i18n("Resetting archive attributes ...")); + progressLocal = backupSize; + progressLocalCount = 0; + progressLocalPercent = -1; + progress->setValue(0); + for (int i = 0; i < toBackup.size(); i++) { + PlpDirent e = toBackup[i]; + const char *fn = e.getName(); + if ((e.getAttr() & rfsv::PSI_A_ARCHIVE) && + (strcmp(fn, "!") != 0)) { + kapp->processEvents(); + res = plpRfsv->fsetattr(fn, 0, rfsv::PSI_A_ARCHIVE); + if (res != rfsv::E_PSI_GEN_NONE) { + if (KMessageBox::warningYesNo(this, i18n("<QT>Could not set attributes of<BR/><B>%1</B></QT>").arg(fn)) == KMessageBox::No) { + break; + } + } + } + updateProgress(e.getSize()); + } + } + // Restart previously running applications on the Psion + // from saved state info. + runRestore(); + + backupTgz->close(); + delete backupTgz; + if (badBackup) + unlink(archiveName.data()); + d->hide(); + delete d; + backupRunning = false; + switchActions(); + statusBar()->message(i18n("Backup done"), 2000); +} + +void KPsionMainWindow:: +slotStartRestore() { + restoreRunning = true; + switchActions(); + + KDialog *d = new KDialog(this, "restoreDialog", true); + d->setCaption(i18n("Restore")); + QGridLayout *gl = new QGridLayout(d); + //progressLabel = new KSqueezedTextLabel(d); + KPsionBackupListView *v = new KPsionBackupListView(d, "restoreSelector"); + gl->addWidget(v, 1, 1); + //progress = new KProgress(0, 100, 0, KProgress::Horizontal, d, "restoreProgress"); + + //gl->addWidget(progress, 2, 1); + gl->addRowSpacing(0, KDialog::marginHint()); + gl->addRowSpacing(3, KDialog::marginHint()); + gl->addColSpacing(0, KDialog::marginHint()); + gl->addColSpacing(2, KDialog::marginHint()); + gl->setColStretch(1, 1); + gl->setRowStretch(1, 1); + d->setMinimumSize(250, 80); + v->readBackups(getMachineUID()); + d->exec(); + + d->hide(); + delete d; + restoreRunning = false; + switchActions(); + statusBar()->message(i18n("Restore done"), 2000); +} + +void KPsionMainWindow:: +slotStartFormat() { + if (KMessageBox::warningYesNo(this, i18n( + "<QT>This erases <B>ALL</B> data " + "on the drive(s).<BR/>Do you really " + "want to proceed?" + )) == KMessageBox::No) + return; + formatRunning = true; + switchActions(); +} + +void KPsionMainWindow:: +slotToggleToolbar() { + if (toolBar()->isVisible()) + toolBar()->hide(); + else + toolBar()->show(); +} + +void KPsionMainWindow:: +slotToggleStatusbar() { + if (statusBar()->isVisible()) + statusBar()->hide(); + else + statusBar()->show(); +} + +void KPsionMainWindow:: +slotSaveOptions() { +} + +void KPsionMainWindow:: +slotPreferences() { +} + +void KPsionMainWindow:: +updateProgress(unsigned long amount) { + progressLocalCount += amount; + int lastPercent = progressLocalPercent; + if (progressLocal) + progressLocalPercent = progressLocalCount * 100 / progressLocal; + else + progressLocalPercent = 100; + if (progressLocalPercent != lastPercent) + progress->setValue(progressLocalPercent); + if (progressTotal > 0) { + progressCount += amount; + lastPercent = progressPercent; + if (progressTotal) + progressPercent = progressCount * 100 / progressTotal; + else + progressPercent = 100; + if (progressPercent != lastPercent) + statusBar()->message(i18n("Backup %1% complete").arg(progressPercent)); + } +} + +void KPsionMainWindow:: +collectFiles(QString dir) { + Enum<rfsv::errs> res; + PlpDir files; + QString tmp = dir; + + kapp->processEvents(); + tmp += "\\"; + if ((res = plpRfsv->dir(tmp.data(), files)) != rfsv::E_PSI_GEN_NONE) { + // messagebox "Couldn't get directory ...." + } else + for (int i = 0; i < files.size(); i++) { + PlpDirent e = files[i]; + + + long attr = e.getAttr(); + tmp = dir; + tmp += "\\"; + tmp += e.getName(); + if (attr & rfsv::PSI_A_DIR) { + collectFiles(tmp); + } else { + kapp->processEvents(); + updateProgress(e.getSize()); + if ((attr & rfsv::PSI_A_ARCHIVE) || fullBackup) { + backupCount++; + backupSize += e.getSize(); + e.setName(tmp.data()); + toBackup.push_back(e); + } + } + } +} + +void KPsionMainWindow:: +killSave() { + Enum<rfsv::errs> res; + bufferArray tmp; + + savedCommands.clear(); + if ((res = plpRpcs->queryDrive('C', 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; + } + progressLabel->setText(i18n("Stopping %1").arg(cmdargs.getString(0))); + kapp->processEvents(); + plpRpcs->stopProgram(pbuf); + } + } + return; +} + +void KPsionMainWindow:: +runRestore() { + Enum<rfsv::errs> res; + + for (QStringList::Iterator it = savedCommands.begin(); it != savedCommands.end(); it++) { + int firstBlank = (*it).find(' '); + QString cmd = (*it).left(firstBlank); + QString arg = (*it).mid(firstBlank + 1); + + if (!cmd.isEmpty()) { + // Workaround for broken programs like Backlite. + // These do not storethe full program path. + // In that case we try running the arg1 which + // results in starting the program via recog. facility. + progressLabel->setText(i18n("Starting %1").arg(cmd)); + kapp->processEvents(); + if ((arg.length() > 2) && (arg[1] == ':') && (arg[0] >= 'A') && + (arg[0] <= 'Z')) + res = plpRpcs->execProgram(arg.data(), ""); + else + res = plpRpcs->execProgram(cmd.data(), arg.data()); + if (res != rfsv::E_PSI_GEN_NONE) { + // If we got an error here, that happened probably because + // we have no path at all (e.g. Macro5) and the program is + // not registered in the Psion's path properly. Now try + // the ususal \System\Apps\<AppName>\<AppName>.app + // on all drives. + if (cmd.find('\\') == -1) { + driveMap::Iterator it; + for (it = drives.begin(); it != drives.end(); it++) { + QString newcmd = QString::fromLatin1("%1:\\System\\Apps\\%2\\%3").arg(it.key()).arg(cmd).arg(cmd); + res = plpRpcs->execProgram(newcmd.data(), ""); + if (res == rfsv::E_PSI_GEN_NONE) + break; + newcmd += ".app"; + res = plpRpcs->execProgram(newcmd.data(), ""); + if (res == rfsv::E_PSI_GEN_NONE) + break; + + } + } + } + } + } + return; +} + +void KPsionMainWindow:: +createIndex() { + ostrstream os; + os << "#plpbackup index " << + (fullBackup ? "F" : "I") << endl; + for (int i = 0; i < toBackup.size(); i++) { + PlpDirent e = toBackup[i]; + PsiTime t = e.getPsiTime(); + long attr = e.getAttr() & + ~rfsv::PSI_A_ARCHIVE; + os << hex + << setw(8) << setfill('0') << + t.getPsiTimeHi() << " " + << setw(8) << setfill('0') << + t.getPsiTimeLo() << " " + << setw(8) << setfill('0') << + e.getSize() << " " + << setw(8) << setfill('0') << + attr << " " + << setw(0) << e.getName() << endl; + kapp->processEvents(); + } + backupTgz->writeFile("Index", "root", "root", os.pcount(), os.str()); +} + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ diff --git a/kde2/kpsion/kpsion.desktop b/kde2/kpsion/kpsion.desktop new file mode 100644 index 0000000..e29bb73 --- /dev/null +++ b/kde2/kpsion/kpsion.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +DocPath=kpsion/index.html +Exec=kpsion +Terminal=0 +Type=Application +Icon=psion_desktop +Comment=My Psion PDA +Comment[de]=Mein Psion +Name=KPsion +Name[de]=KPsion diff --git a/kde2/kpsion/kpsion.h b/kde2/kpsion/kpsion.h new file mode 100644 index 0000000..86aeff4 --- /dev/null +++ b/kde2/kpsion/kpsion.h @@ -0,0 +1,165 @@ +#ifndef _KPSION_H_ +#define _KPSION_H_ + +#include "setupdialog.h" + +#include <kmainwindow.h> +#include <kiconview.h> +#include <kprogress.h> +#include <ksqueezedtextlabel.h> +#include <klistview.h> +#include <ktar.h> + +#include <rfsv.h> +#include <rpcs.h> +#include <ppsocket.h> + +typedef QMap<char,QString> driveMap; +typedef QMap<QString,QString> psionMap; + +class KPsionCheckListItem : public QCheckListItem { + public: + KPsionCheckListItem(KPsionCheckListItem *parent, const QString &text, + Type tt) + : QCheckListItem(parent, text, tt) { init(true); } + KPsionCheckListItem(QCheckListItem *parent, const QString &text, Type tt) + : QCheckListItem(parent, text, tt) { init(false); } + KPsionCheckListItem(QListViewItem *parent, const QString &text, Type tt) + : QCheckListItem(parent, text, tt) { init(false); } + KPsionCheckListItem(QListView *parent, const QString &text, Type tt) + : QCheckListItem(parent, text, tt) { init(false); } + KPsionCheckListItem(QListViewItem *parent, const QString &text, + const QPixmap &p) + : QCheckListItem(parent, text, p) { init(false); } + KPsionCheckListItem(QListView *parent, const QString &text, + const QPixmap &p) + : QCheckListItem(parent, text, p) { init(false); } + void setMetaData(int, time_t); + + protected: + virtual void stateChange(bool); + void propagateUp(bool); + void propagateDown(bool); + + private: + void init(bool); + + bool parentIsKPsionCheckListItem; + bool dontPropagate; + int backupType; + time_t when; +}; + +class KPsionBackupListView : public KListView { + Q_OBJECT + public: + enum backupTypes { + UNKNOWN = 0, + FULL = 1, + INCREMENTAL = 2, + }; + + KPsionBackupListView(QWidget *parent = 0, const char *name = 0); + void readBackups(QString uid); + PlpDir &getRestoreList(); + + private: + void listTree(KPsionCheckListItem *cli, const KTarEntry *te, int level); + + QString uid; + QString backupDir; + PlpDir toRestore; +}; + +class KPsionMainWindow : public KMainWindow { + Q_OBJECT + + public: + KPsionMainWindow(); + ~KPsionMainWindow(); + void setMachineName(QString &_name) { machineName = _name; } + QString getMachineUID(); + driveMap &getDrives() { return drives; } + psionMap &getMachines() { return machines; } + QString &getMachineName() { return machineName; } + QString &getBackupDir() { return backupDir; } + + public slots: + void slotStartRestore(); + void slotStartFullBackup(); + void slotStartIncBackup(); + void slotStartFormat(); + void slotToggleToolbar(); + void slotToggleStatusbar(); + void slotSaveOptions(); + void slotPreferences(); + + protected: + virtual bool queryClose(); + void setupActions(); + void switchActions(); + void queryPsion(); + void insertDrive(char letter, const char * const name); + + private slots: + void iconClicked(QIconViewItem *i); + void iconOver(QIconViewItem *i); + void slotUpdateTimer(); + + private: + void doBackup(); + void tryConnect(); + void updateProgress(unsigned long); + void collectFiles(QString dir); + void killSave(); + void runRestore(); + void createIndex(); + + rfsv *plpRfsv; + rpcs *plpRpcs; + ppsocket *rfsvSocket; + ppsocket *rpcsSocket; + SetupDialog *setupDialog; + KIconView *view; + KProgress *progress; + KSqueezedTextLabel *progressLabel; + KTarGz *backupTgz; + + driveMap drives; + psionMap machines; + QStringList backupDrives; + QStringList savedCommands; + QString backupDir; + QString machineName; + QString statusMsg; + QString ncpdDevice; + bool S5mx; + bool backupRunning; + bool restoreRunning; + bool formatRunning; + bool lastSelected; + bool connected; + bool firstTry; + bool shuttingDown; + bool fullBackup; + int reconnectTime; + int nextTry; + int ncpdSpeed; + unsigned long long machineUID; + PlpDir toBackup; + unsigned long backupSize; + unsigned long backupCount; + unsigned long progressTotal; + unsigned long progressLocal; + unsigned long progressCount; + unsigned long progressLocalCount; + int progressPercent; + int progressLocalPercent; +}; + +#endif +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ diff --git a/kde2/kpsion/kpsionui.rc b/kde2/kpsion/kpsionui.rc new file mode 100644 index 0000000..17302c5 --- /dev/null +++ b/kde2/kpsion/kpsionui.rc @@ -0,0 +1,15 @@ +<!DOCTYPE kpartgui> +<kpartgui name="kpsion"> + <MenuBar> + <Menu name="file"><text>&File</text> + <Action name="fullbackup"/> + <Action name="incbackup"/> + <Action name="restore"/> + <Action name="format"/> + </Menu> + </MenuBar> + <ToolBar fullWidth="true" name="mainToolBar"> + <Action name="fullbackup"/> + <Action name="restore"/> + </ToolBar> +</kpartgui> diff --git a/kde2/kpsion/lo16-action-psion_backup.png b/kde2/kpsion/lo16-action-psion_backup.png Binary files differnew file mode 100644 index 0000000..4d0f815 --- /dev/null +++ b/kde2/kpsion/lo16-action-psion_backup.png diff --git a/kde2/kpsion/lo16-action-psion_restore.png b/kde2/kpsion/lo16-action-psion_restore.png Binary files differnew file mode 100644 index 0000000..8f3103b --- /dev/null +++ b/kde2/kpsion/lo16-action-psion_restore.png diff --git a/kde2/kpsion/lo16-app-kpsion.png b/kde2/kpsion/lo16-app-kpsion.png Binary files differnew file mode 100644 index 0000000..2382c76 --- /dev/null +++ b/kde2/kpsion/lo16-app-kpsion.png diff --git a/kde2/kpsion/lo22-action-psion_backup.png b/kde2/kpsion/lo22-action-psion_backup.png Binary files differnew file mode 100644 index 0000000..b5ebd45 --- /dev/null +++ b/kde2/kpsion/lo22-action-psion_backup.png diff --git a/kde2/kpsion/lo22-action-psion_restore.png b/kde2/kpsion/lo22-action-psion_restore.png Binary files differnew file mode 100644 index 0000000..47780b8 --- /dev/null +++ b/kde2/kpsion/lo22-action-psion_restore.png diff --git a/kde2/kpsion/lo32-action-psion_backup.png b/kde2/kpsion/lo32-action-psion_backup.png Binary files differnew file mode 100644 index 0000000..4a99260 --- /dev/null +++ b/kde2/kpsion/lo32-action-psion_backup.png diff --git a/kde2/kpsion/lo32-action-psion_restore.png b/kde2/kpsion/lo32-action-psion_restore.png Binary files differnew file mode 100644 index 0000000..782e2d9 --- /dev/null +++ b/kde2/kpsion/lo32-action-psion_restore.png diff --git a/kde2/kpsion/lo32-app-kpsion.png b/kde2/kpsion/lo32-app-kpsion.png Binary files differnew file mode 100644 index 0000000..7285992 --- /dev/null +++ b/kde2/kpsion/lo32-app-kpsion.png diff --git a/kde2/kpsion/main.cpp b/kde2/kpsion/main.cpp new file mode 100644 index 0000000..df909ef --- /dev/null +++ b/kde2/kpsion/main.cpp @@ -0,0 +1,55 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "kpsion.h" +#include "wizards.h" +#include <kapp.h> +#include <klocale.h> +#include <kconfig.h> +#include <kcmdlineargs.h> +#include <kaboutdata.h> + +static KCmdLineOptions options[] = { + {"b", 0, 0}, + {"backup", I18N_NOOP("perform backup"), 0}, + {"r", 0, 0}, + {"restore", I18N_NOOP("perform restore"), 0}, + {"f", 0, 0}, + {"format", I18N_NOOP("format drive"), 0}, + {"+[DriveLetter]", I18N_NOOP("The drive letter to backup/restore or format."), 0}, + { 0, 0, 0}, +}; + +int main(int argc, char **argv) { + KAboutData *about = new KAboutData("kpsion", I18N_NOOP("KPsion"), + VERSION, I18N_NOOP("Psion connectivity utility"), + KAboutData::License_GPL, + "(C) 2001, Fritz Elfert", 0L, + "http://plptools.sourceforge.net", + "plptools-developers@sourceforge.net"); + about->addAuthor("Fritz Elfert", I18N_NOOP("Original Developer/Maintainer"), + "felfert@users.sourceforge.net", + "http://plptools.sourceforge.net"); + KCmdLineArgs::init(argc, argv, about); + KCmdLineArgs::addCmdLineOptions(options); + + KApplication a; + + KConfig *config = kapp->config(); + config->setGroup("Settings"); + QString backupDir = config->readEntry("BackupDir"); + + if (backupDir.isEmpty()) { + FirstTimeWizard *wiz = new FirstTimeWizard(0L, "firsttimewizard"); + wiz->exec(); + } + + KPsionMainWindow *w = new KPsionMainWindow(); + w->resize(300, 150); + a.setMainWidget(w); + w->show(); + return a.exec(); +} + + diff --git a/kde2/kpsion/setupdialog.cpp b/kde2/kpsion/setupdialog.cpp new file mode 100644 index 0000000..370bb30 --- /dev/null +++ b/kde2/kpsion/setupdialog.cpp @@ -0,0 +1,62 @@ +#include "setupdialog.h" + +#include <kapp.h> +#include <kconfig.h> +#include <klocale.h> +#include <knuminput.h> +#include <klineedit.h> +#include <kcombobox.h> + +#include <qlayout.h> +#include <qlabel.h> + +SetupDialog::SetupDialog(QWidget *parent, rfsv *plpRfsv, rpcs *plpRpcs) + : KDialogBase(Tabbed, "Settings", Ok|Apply|Default|Cancel, Ok, parent, + "settingsDialog", true, true) { + + enableLinkedHelp(true); + + KConfig *config = kapp->config(); + QFrame *page = addPage(i18n("&General")); + QGridLayout *gl = new QGridLayout(page, 4, 2, 15); + gl->addRowSpacing(0, 10); + QLabel *l; + + l = new QLabel(i18n("Backup &directory"), page, "backupDirLabel"); + gl->addWidget(l, 1, 0); + KLineEdit *bdiredit = new KLineEdit(page, "backupDirEdit"); + gl->addWidget(bdiredit, 1 , 1); + l->setBuddy(bdiredit); + QPushButton *bdirbutton = new QPushButton(i18n("Browse"), page, "backupDirButton"); + gl->addWidget(bdirbutton, 1 , 2); + + l = new QLabel(i18n("Backup &generations"), page, "backupGenLabel"); + gl->addMultiCellWidget(l, 2, 2, 0, 1); + KIntSpinBox *genspin = new KIntSpinBox(0, 10, 1, 3, 10, page, "backupGenSpin"); + gl->addWidget(genspin, 2, 2); + l->setBuddy(genspin); + + page = addPage(i18n("&Machines")); + gl = new QGridLayout(page, 4, 2, 15); + gl->addRowSpacing(0, 10); + + l = new QLabel(i18n("Machine &Name"), page, "NameLabel"); + gl->addWidget(l, 1, 0); + KLineEdit *nedit = new KLineEdit(page, "NameEdit"); + gl->addWidget(nedit, 1, 1); + l->setBuddy(nedit); + l = new QLabel(i18n("Machine &UID"), page, "UIDLabel"); + gl->addWidget(l, 2, 0); + KComboBox *uidcombo = new KComboBox(true, page, "UIDCombo"); + config->setGroup("Psion"); + uidcombo->insertStringList(config->readListEntry("MachineUIDs")); + gl->addWidget(uidcombo, 1, 1); + l->setBuddy(uidcombo); + + connect(this, SIGNAL(defaultClicked()), SLOT(slotDefaultClicked())); +} + +void SetupDialog:: +slotDefaultClicked() { + enableLinkedHelp(false); +} diff --git a/kde2/kpsion/setupdialog.h b/kde2/kpsion/setupdialog.h new file mode 100644 index 0000000..b385dce --- /dev/null +++ b/kde2/kpsion/setupdialog.h @@ -0,0 +1,17 @@ +#ifndef _SETUPDIALOGS_H_ +#define _SETUPDIALOGS_H_ + +#include <rfsv.h> +#include <rpcs.h> + +#include <kdialogbase.h> + +class SetupDialog : public KDialogBase { + public: + SetupDialog(QWidget *parent, rfsv *plpRfsv, rpcs *plpRpcs); + + private slots: + void slotDefaultClicked(); +}; + +#endif diff --git a/kde2/kpsion/wizards.cpp b/kde2/kpsion/wizards.cpp new file mode 100644 index 0000000..24cd121 --- /dev/null +++ b/kde2/kpsion/wizards.cpp @@ -0,0 +1,586 @@ +/*-*-c++-*- + * $Id$ + * + * This file is part of plptools. + * + * Copyright (C) 2001 Fritz Elfert <felfert@to.com> + * + * 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 + * + */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> +#include <sys/types.h> +#include <unistd.h> +#include <pwd.h> + +#include "wizards.h" + +#include <kapp.h> +#include <kdebug.h> +#include <kdialog.h> +#include <klocale.h> +#include <kfiledialog.h> +#include <kmessagebox.h> + +#include <qlayout.h> +#include <qwhatsthis.h> +#include <qheader.h> + +FirstTimeWizard::FirstTimeWizard(QWidget *parent, const char *name) + : KWizard(parent, name, true) { + + setCaption(i18n("KPsion Setup")); + QWhatsThis::add(nextButton(), + i18n("Click this button to continue with the next page.")); + QWhatsThis::add(backButton(), + i18n("Click this button, to go to a previous page.")); + QWhatsThis::add(cancelButton(), + i18n("<QT>If you click this button, the setup of <B>KPSion</B> will be aborted and next time you start <B>KPsion</B>, it will run this setup again.</QT>")); + + // Getting the users home directory from the passwd-entry is MUCH safer + // than getting it from $HOME !!! (Environments can be tweaked) + struct passwd *pw = getpwuid(getuid()); + bdirDefault = QString((pw) ? pw->pw_dir : 0L); + if (bdirDefault.isEmpty()) + bdirDefault = QDir::homeDirPath(); + bdirDefault += "/KPsionBackup"; + bdirCreated = ""; + + // Page 1 + page1 = new QWidget(this, "welcome"); + QGridLayout *grid = new QGridLayout(page1); + + QLabel *l = new QLabel(page1, "welcome message"); + l->setText(i18n( + "<QT>" + "<H2>Welcome to KPsion!</H2>" + "It looks like you started <B>KPsion</B> the first time. " + "At least, i could not find any valid configuration.</BR>" + "On the following pages, we will gather some information, " + "which is needed for working with <B>KPsion</B>.</BR>" + " </BR>" + "Have fun." + "</QT>" + )); + grid->addWidget(l, 1, 1, Qt::AlignTop); + grid->setColStretch(1, 1); + grid->setRowStretch(1, 1); + grid->addRowSpacing(0, KDialog::marginHint()); + grid->addRowSpacing(2, KDialog::marginHint()); + grid->addColSpacing(0, KDialog::marginHint()); + grid->addColSpacing(2, KDialog::marginHint()); + addPage(page1, i18n("<QT><BIG><B>Welcome<B></BIG></QT>")); + + // Page 2 + page2 = new QWidget(this, "step1"); + grid = new QGridLayout(page2); + + l = new QLabel(page2, "step1"); + l->setText(i18n( + "<QT>" + "First, we need a folder for storing backups of " + "your Psion. You probably don't want others to " + "have access to it, so it's best to choose a " + "location somewhere in your home directory. " + "Please browse through existing folders and select a suitable " + "location or simply accept the default shown below." + "</QT>" + )); + grid->addMultiCellWidget(l, 1, 1, 1, 2, Qt::AlignTop); + + bdirLabel = new QLabel(page2, "bdirLabel"); + bdirLabel->setText(bdirDefault); + bdirButton = new QPushButton(i18n("Browse"), page2); + + QWhatsThis::add(bdirLabel, + i18n("This is the name of the backup folder.")); + QWhatsThis::add(bdirButton, + i18n("Click here, for opening a dialog which lets you easily select the backup folder.")); + grid->addWidget(bdirLabel, 3, 1); + grid->addWidget(bdirButton, 3, 2); + + grid->setRowStretch(1, 1); + grid->setColStretch(1, 1); + + grid->addRowSpacing(2, KDialog::spacingHint()); + + grid->addRowSpacing(0, KDialog::marginHint()); + grid->addRowSpacing(4, KDialog::marginHint()); + grid->addColSpacing(0, KDialog::marginHint()); + grid->addColSpacing(3, KDialog::marginHint()); + + connect(bdirButton, SIGNAL(clicked()), SLOT(slotBdirBrowse())); + addPage(page2, i18n("<QT><BIG><B>Step 1</B></BIG> - Specify backup directory</QT>")); + // Page 3 + page3 = new QWidget(this, "step2"); + grid = new QGridLayout(page3); + + l = new QLabel(page3, "step2"); + l->setText(i18n( + "<QT>" + "Next, please specify some information regarding " + "backup policy:<UL><LI>How many generations of backups " + "do you want to keep?</LI><LI>Shall i remind you about " + "backups?</LI><LI>If yes, in what intervals do you want " + "to happen backups?</LI></UL>" + "</QT>" + )); + grid->addMultiCellWidget(l, 1, 1, 1, 2, Qt::AlignTop); + + l = new QLabel(i18n("&Incremental backup reminder"), page3, "iBackupIntLabel"); + grid->addWidget(l, 3, 1); + iIntCombo = new KComboBox(false, page3, "iIntCombo"); + iIntCombo->insertItem(i18n("none")); + iIntCombo->insertItem(i18n("daily")); + iIntCombo->insertItem(i18n("every 2 days")); + iIntCombo->insertItem(i18n("every 3 days")); + iIntCombo->insertItem(i18n("every 4 days")); + iIntCombo->insertItem(i18n("every 5 days")); + iIntCombo->insertItem(i18n("every 6 days")); + iIntCombo->insertItem(i18n("weekly")); + iIntCombo->insertItem(i18n("every 2 weeks")); + iIntCombo->insertItem(i18n("every 3 weeks")); + iIntCombo->insertItem(i18n("monthly")); + iIntCombo->setCurrentItem(1); + grid->addWidget(iIntCombo, 3, 2); + l->setBuddy(iIntCombo); + + l = new QLabel(i18n("&Full backup reminder"), page3, "fBackupIntLabel"); + grid->addWidget(l, 5, 1); + fIntCombo = new KComboBox(false, page3, "fIntCombo"); + fIntCombo->insertItem(i18n("none")); + fIntCombo->insertItem(i18n("daily")); + fIntCombo->insertItem(i18n("every 2 days")); + fIntCombo->insertItem(i18n("every 3 days")); + fIntCombo->insertItem(i18n("every 4 days")); + fIntCombo->insertItem(i18n("every 5 days")); + fIntCombo->insertItem(i18n("every 6 days")); + fIntCombo->insertItem(i18n("weekly")); + fIntCombo->insertItem(i18n("every 2 weeks")); + fIntCombo->insertItem(i18n("every 3 weeks")); + fIntCombo->insertItem(i18n("monthly")); + fIntCombo->setCurrentItem(7); + grid->addWidget(fIntCombo, 5, 2); + l->setBuddy(fIntCombo); + + l = new QLabel(i18n("Backup &generations"), page3, "backupGenLabel"); + grid->addWidget(l, 7, 1); + genSpin = new KIntSpinBox(0, 10, 1, 3, 10, page3, "backupGenSpin"); + grid->addWidget(genSpin, 7, 2); + l->setBuddy(genSpin); + + grid->setRowStretch(1, 1); + grid->setColStretch(1, 1); + + grid->addRowSpacing(2, KDialog::spacingHint()); + grid->addRowSpacing(4, KDialog::spacingHint()); + grid->addRowSpacing(6, KDialog::spacingHint()); + + grid->addRowSpacing(0, KDialog::marginHint()); + grid->addRowSpacing(8, KDialog::marginHint()); + grid->addColSpacing(0, KDialog::marginHint()); + grid->addColSpacing(3, KDialog::marginHint()); + + addPage(page3, i18n("<QT><BIG><B>Step 2</B></BIG> - Backup policy</QT>")); + + // Page 4 + page4 = new QWidget(this, "step3"); + grid = new QGridLayout(page4); + + l = new QLabel(page4, "step2"); + l->setText(i18n( + "<QT>" + "If no connection could be established on startup, " + "<B>KPsion</B> will attempt to connect in regular " + "intervals. Please specify the interval after which " + "a connection attempt should happen. If you don't want " + "automatic retry, set the interval to zero. Furthermore, " + "<B>KPsion</B> can try to start ncpd if it is not already " + "running. For that to work correctly, you need to" + "<UL><LI>specify the serial port to use.</LI>" + "<LI>specify the baud rate</LI>" + "<LI>have permission to use the specified port</LI></UL>" + "</QT>" + )); + grid->addMultiCellWidget(l, 1, 1, 1, 2, Qt::AlignTop); + + l = new QLabel(i18n("&Connection retry interval (sec.)"), page4, "rconLabel"); + grid->addWidget(l, 3, 1); + rconSpin = new KIntSpinBox(0, 600, 1, 30, 10, page4, "rconSpin"); + grid->addWidget(rconSpin, 3, 2); + l->setBuddy(rconSpin); + + l = new QLabel(i18n("Serial &device"), page4, "devLabel"); + grid->addWidget(l, 5, 1); + devCombo = new KComboBox(false, page4, "devCombo"); + devCombo->insertItem(i18n("off")); + devCombo->insertItem(i18n("/dev/ttyS0")); + devCombo->insertItem(i18n("/dev/ttyS1")); + devCombo->insertItem(i18n("/dev/ttyS2")); + devCombo->insertItem(i18n("/dev/ttyS3")); + devCombo->insertItem(i18n("/dev/ircomm0")); + devCombo->insertItem(i18n("/dev/ircomm1")); + devCombo->insertItem(i18n("/dev/ircomm2")); + devCombo->insertItem(i18n("/dev/ircomm3")); + devCombo->setCurrentItem(0); + grid->addWidget(devCombo, 5, 2); + l->setBuddy(devCombo); + + l = new QLabel(i18n("Serial &speed"), page4, "speedLabel"); + grid->addWidget(l, 7, 1); + speedCombo = new KComboBox(false, page4, "speedCombo"); + speedCombo->insertItem("9600"); + speedCombo->insertItem("19200"); + speedCombo->insertItem("38400"); + speedCombo->insertItem("57600"); + speedCombo->insertItem("115200"); + speedCombo->setCurrentItem(4); + grid->addWidget(speedCombo, 7, 2); + l->setBuddy(speedCombo); + + grid->setRowStretch(1, 1); + grid->setColStretch(1, 1); + + grid->addRowSpacing(2, KDialog::spacingHint()); + grid->addRowSpacing(4, KDialog::spacingHint()); + grid->addRowSpacing(6, KDialog::spacingHint()); + + grid->addRowSpacing(0, KDialog::marginHint()); + grid->addRowSpacing(8, KDialog::marginHint()); + grid->addColSpacing(0, KDialog::marginHint()); + grid->addColSpacing(3, KDialog::marginHint()); + + addPage(page4, i18n("<QT><BIG><B>Step 3</B></BIG> - Connection parameters</QT>")); + + // Page 5 + page5 = new QWidget(this, "step3"); + grid = new QGridLayout(page5); + + l = new QLabel(page5, "step2"); + l->setText(i18n( + "<QT>" + "That's it!<BR/>" + "Next, i will start <B>KPsion</B> and if your Psion is already " + "connected and it's communication turned on (use " + "<B>Ctrl-T</B> at system level), then <B>KPsion</B> will " + "bring up a similar Dialog like this which lets you assing a " + "Name for it. After that, i suggest performing a full " + "Backup.<BR/>Please click <B>Finish</B> now.</QT>" + )); + grid->addWidget(l, 1, 1, Qt::AlignTop); + + grid->setRowStretch(1, 1); + grid->setColStretch(1, 1); + + grid->addRowSpacing(0, KDialog::marginHint()); + grid->addRowSpacing(2, KDialog::marginHint()); + grid->addColSpacing(0, KDialog::marginHint()); + grid->addColSpacing(2, KDialog::marginHint()); + + addPage(page5, i18n("<QT><BIG><B>Finished</B></BIG></QT>")); + + setFinishEnabled(page5, true); +} + +void FirstTimeWizard:: +slotBdirBrowse() { + QString dir = KFileDialog::getExistingDirectory(bdirLabel->text(), this, + i18n("Backup folder")); + checkBackupDir(dir); +} + +void FirstTimeWizard:: +reject() { + // kapp->quit() and [QK]Application::exit(0) don't work here?! + // probably because we didn't call kapp->exec() yet? + // -> brute force + if (KMessageBox::questionYesNo(this, + i18n("<QT>You are about to abort the initial setup of <B>KPsion</B>. No configuration will be stored and you will have to repeat this procedure when you start <B>KPsion</B> next time.<BR/>Do you really want to exit now?</QT>")) == KMessageBox::Yes) { + if (!bdirCreated.isEmpty()) + ::rmdir(bdirCreated.data()); + ::exit(0); + } +} + +void FirstTimeWizard:: +accept() { + KConfig *config = kapp->config(); + config->setGroup("Settings"); + config->writeEntry("BackupDir", bdirLabel->text()); + config->writeEntry("BackupGenerations", genSpin->value()); + config->writeEntry("IncrementalInterval", iIntCombo->currentItem()); + config->writeEntry("FullInterval", fIntCombo->currentItem()); + config->setGroup("Connection"); + config->writeEntry("Retry", rconSpin->value()); + config->writeEntry("Device", devCombo->currentText()); + config->writeEntry("Speed", speedCombo->currentText()); + hide(); + setResult(Accepted); +} + +void FirstTimeWizard:: +next() { + for (int i = 0; i < pageCount(); i++) + if (currentPage() == page(i)) { + switch (i) { + case 1: + QString dir(bdirLabel->text()); + if (!checkBackupDir(dir)) + return; + } + break; + } + KWizard::next(); +} + +void FirstTimeWizard:: +closeEvent(QCloseEvent *e) { + reject(); +} + +bool FirstTimeWizard:: +checkBackupDir(QString &dir) { + if (!bdirCreated.isEmpty()) { + if (bdirCreated != dir) { + ::rmdir(bdirCreated.data()); + bdirCreated = ""; + } + } + if (!dir.isEmpty()) { + QDir d(dir); + if (!d.exists()) { + if (KMessageBox::questionYesNo(this, + i18n("<QT>The folder <B>%1</B> does <B>not</B> exist.<BR/>Shall it be created?</QT>").arg(dir)) == KMessageBox::No) { + bdirLabel->setText(bdirDefault); + return false; + } + if (mkdir(dir.data(), 0700) != 0) { + QString msg = i18n("<QT>The specified folder<BR/><B>%1</B><BR/>could <B>not</B> be created"); + switch (errno) { + case EACCES: + case EPERM: + case EROFS: + msg += i18n(", because you either don't have sufficient rights to do that, or the filesystem is readonly."); + // Insufficient permissions/ readonly FS + break; + case ENOSPC: + msg += i18n(", because the filesystem has not enough space."); + // No space + break; + case EEXIST: + // shouldn't happen, we checked already + // for existence. + msg += i18n(", because there already exists another object with the same name."); + break; + case EFAULT: + case ENOMEM: + case ENAMETOOLONG: + // shouldn't happen. + msg += "."; + break; + case ENOENT: + // propably dangling symlink + msg += i18n(", because you specified a path which probably contains a dangling symbolic link."); + break; + case ENOTDIR: + msg += i18n(", because you specified a path which contains an element which is not a folder."); + // path element not dir. + break; + case ELOOP: + msg += i18n(", because you specified a path which contains too many symbolic links."); + // Too many symlinks + break; + + + } + bdirLabel->setText(bdirDefault); + msg += i18n("<BR/>Please select another folder.</QT>"); + KMessageBox::error(this, msg.arg(dir)); + return false; + } + bdirCreated = dir; + } + bdirLabel->setText(dir); + return true; + } + bdirLabel->setText(bdirDefault); + return false; +} + +NewPsionWizard::NewPsionWizard(QWidget *parent, const char *name) + : KWizard(parent, name, true) { + + setCaption(i18n("New Psion detected")); + psion = (KPsionMainWindow *)parent; + + QWhatsThis::add(nextButton(), + i18n("Click this button to continue with the next page.")); + QWhatsThis::add(backButton(), + i18n("Click this button, to go to a previous page.")); + QWhatsThis::add(cancelButton(), + i18n("<QT>If you click this button, the setup for the new connected Psion will be aborted and next time you connect this Psion again, <B>KPsion</B> will run this setup again.</QT>")); + + // Page 1 + page1 = new QWidget(this, "newmachine"); + QGridLayout *grid = new QGridLayout(page1); + + QLabel *l = new QLabel(page1, "newmachmessage"); + uid = psion->getMachineUID(); + l->setText(i18n( + "<QT>" + "The Psion with the unique ID <B>%1</B> " + "is connected the first time. Please assign a name to it." + "</QT>").arg(uid)); + grid->addMultiCellWidget(l, 1, 1, 1, 2, Qt::AlignTop); + + l = new QLabel(page1, "nameLabel"); + l->setText(i18n("&Name of new Psion")); + nameEdit = new KLineEdit(page1, "nameEdit"); + nameEdit->setText(i18n("My new Psion")); + nameEdit->selectAll(); + nameEdit->setFocus(); + l->setBuddy(nameEdit); + grid->addWidget(l, 3, 1); + grid->addWidget(nameEdit, 3, 2); + + grid->setColStretch(1, 1); + grid->setRowStretch(1, 1); + + grid->addRowSpacing(2, KDialog::spacingHint()); + + grid->addRowSpacing(0, KDialog::marginHint()); + grid->addRowSpacing(4, KDialog::marginHint()); + grid->addColSpacing(0, KDialog::marginHint()); + grid->addColSpacing(2, KDialog::marginHint()); + + addPage(page1, i18n("<QT><BIG><B>New Psion detected<B></BIG></QT>")); + + // Page 2 + page2 = new QWidget(this, "bdrives"); + grid = new QGridLayout(page2); + + l = new QLabel(page2, "bdrivemessage"); + l->setText(i18n( + "<QT>" + "Please select the Drive(s), you want to be backed up when " + "running in unattended backup mode." + "</QT>" + )); + grid->addMultiCellWidget(l, 1, 1, 1, 3, Qt::AlignTop); + + backupListView = new KListView(page2, "bdriveListView"); + backupListView->addColumn(i18n("Available drives")); + driveMap dlist = psion->getDrives(); + driveMap::Iterator it; + int height = backupListView->header()->height(); + for (it = dlist.begin(); it != dlist.end(); it++) { + QCheckListItem *i = new QCheckListItem(backupListView, it.data(), + QCheckListItem::CheckBox); + height += i->height(); + i->setSelectable(false); + } + backupListView->setMaximumSize(backupListView->columnWidth(0) + 5, height + 5); + grid->addWidget(backupListView, 3, 2); + + grid->setColStretch(1, 1); + grid->setRowStretch(1, 1); + grid->setColStretch(3, 1); + + grid->addRowSpacing(2, KDialog::spacingHint()); + + grid->addRowSpacing(0, KDialog::marginHint()); + grid->addRowSpacing(4, KDialog::marginHint()); + grid->addColSpacing(0, KDialog::marginHint()); + grid->addColSpacing(4, KDialog::marginHint()); + + addPage(page2, i18n("<QT><BIG><B>Specify drives to backup<B></BIG></QT>")); + + setFinishEnabled(page2, true); +} + +void NewPsionWizard:: +next() { + for (int i = 0; i < pageCount(); i++) + if (currentPage() == page(i)) { + switch (i) { + case 0: + QString tmp(nameEdit->text()); + if (!checkPsionName(tmp)) + return; + } + break; + } + KWizard::next(); +} + +bool NewPsionWizard:: +checkPsionName(QString &name) { + KConfig *config = kapp->config(); + if (name.isEmpty()) { + KMessageBox::sorry(this, i18n("The name cannot be empty.")); + return false; + } + psionMap l = psion->getMachines(); + psionMap::Iterator it; + for (it = l.begin(); it != l.end(); it++) { + if (name == it.data()) { + KMessageBox::sorry(this, i18n("<QT>The name <B>%1</B> is already assigned to another machine.<BR/>Please choose a different name.</QT>")); + return false; + } + } + return true; +} + +void NewPsionWizard:: +accept() { + KConfig *config = kapp->config(); + config->setGroup("Psion"); + QStringList machines = config->readListEntry("MachineUIDs"); + machines += uid; + config->writeEntry("MachineUIDs", machines); + QString tmp = QString::fromLatin1("Name_%1").arg(uid); + config->writeEntry(tmp, nameEdit->text()); + tmp = nameEdit->text(); + psion->setMachineName(tmp); + QListViewItemIterator li(backupListView); + driveMap dlist = psion->getDrives(); + driveMap::Iterator di; + QStringList bdrives; + for (; li.current(); li++) { + QCheckListItem *qcli = (QCheckListItem *)(li.current()); + if (qcli->isOn()) { + tmp = qcli->text(); + for (di = dlist.begin(); di != dlist.end(); di++) + if (di.data() == tmp) { + QString drv = ""; + drv += di.key(); + bdrives += drv; + } + } + } + config->writeEntry("BackupDrives", bdrives); + hide(); + setResult(Accepted); +} + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ diff --git a/kde2/kpsion/wizards.h b/kde2/kpsion/wizards.h new file mode 100644 index 0000000..6edd8d9 --- /dev/null +++ b/kde2/kpsion/wizards.h @@ -0,0 +1,78 @@ +#ifndef _WIZARDS_H_ +#define _WIZARDS_H_ + +#include "kpsion.h" + +#include <kwizard.h> +#include <knuminput.h> +#include <kcombobox.h> +#include <klineedit.h> +#include <klistview.h> + +#include <qpushbutton.h> +#include <qcheckbox.h> +#include <qlabel.h> + +class FirstTimeWizard : public KWizard { + Q_OBJECT + public: + FirstTimeWizard(QWidget *parent = 0, const char *name = 0); + + protected: + virtual void closeEvent(QCloseEvent *e); + virtual void reject(); + virtual void accept(); + + protected slots: + virtual void next(); + + private slots: + void slotBdirBrowse(); + + private: + bool checkBackupDir(QString &); + + QWidget *page1; + QWidget *page2; + QWidget *page3; + QWidget *page4; + QWidget *page5; + QLabel *bdirLabel; + KIntSpinBox *genSpin; + KIntSpinBox *rconSpin; + QPushButton *bdirButton; + QCheckBox *remCheck; + KComboBox *iIntCombo; + KComboBox *fIntCombo; + KComboBox *devCombo; + KComboBox *speedCombo; + + QString bdirDefault; + QString bdirCreated; +}; + +class NewPsionWizard : public KWizard { + Q_OBJECT + + public: + NewPsionWizard(QWidget *parent = 0, const char *name = 0); + + protected: + virtual void accept(); + + protected slots: + virtual void next(); + + private: + bool checkPsionName(QString &); + + QWidget *page1; + QWidget *page2; + KPsionMainWindow *psion; + KLineEdit *nameEdit; + KListView *backupListView; + + QString uid; + QString machineName; +}; +#endif diff --git a/kde2/mime/icons/lo32-app-psion_backup.png b/kde2/mime/icons/lo32-app-psion_backup.png Binary files differindex 4a99260..1e98401 100644 --- a/kde2/mime/icons/lo32-app-psion_backup.png +++ b/kde2/mime/icons/lo32-app-psion_backup.png diff --git a/kde2/mime/icons/lo32-app-psion_desktop.png b/kde2/mime/icons/lo32-app-psion_desktop.png Binary files differindex 7285992..b3e1db4 100644 --- a/kde2/mime/icons/lo32-app-psion_desktop.png +++ b/kde2/mime/icons/lo32-app-psion_desktop.png diff --git a/kde2/mime/icons/lo32-app-psion_owner.png b/kde2/mime/icons/lo32-app-psion_owner.png Binary files differindex 515b105..00e44c6 100644 --- a/kde2/mime/icons/lo32-app-psion_owner.png +++ b/kde2/mime/icons/lo32-app-psion_owner.png diff --git a/kde2/mime/icons/lo32-app-psion_restore.png b/kde2/mime/icons/lo32-app-psion_restore.png Binary files differindex 782e2d9..2b0f5ee 100644 --- a/kde2/mime/icons/lo32-app-psion_restore.png +++ b/kde2/mime/icons/lo32-app-psion_restore.png diff --git a/kde2/mime/icons/lo32-app-psion_setup.png b/kde2/mime/icons/lo32-app-psion_setup.png Binary files differindex 7282e39..28203be 100644 --- a/kde2/mime/icons/lo32-app-psion_setup.png +++ b/kde2/mime/icons/lo32-app-psion_setup.png diff --git a/kde2/mime/icons/lo32-device-psion_drive.png b/kde2/mime/icons/lo32-device-psion_drive.png Binary files differindex e1494bf..48637fc 100644 --- a/kde2/mime/icons/lo32-device-psion_drive.png +++ b/kde2/mime/icons/lo32-device-psion_drive.png diff --git a/kde2/mime/icons/lo32-mime-x_psion_agenda.png b/kde2/mime/icons/lo32-mime-x_psion_agenda.png Binary files differindex 333ee4c..6eed655 100644 --- a/kde2/mime/icons/lo32-mime-x_psion_agenda.png +++ b/kde2/mime/icons/lo32-mime-x_psion_agenda.png diff --git a/kde2/mime/icons/lo32-mime-x_psion_backup.png b/kde2/mime/icons/lo32-mime-x_psion_backup.png Binary files differindex 420c112..13c0e5c 100644 --- a/kde2/mime/icons/lo32-mime-x_psion_backup.png +++ b/kde2/mime/icons/lo32-mime-x_psion_backup.png diff --git a/kde2/mime/icons/lo32-mime-x_psion_data.png b/kde2/mime/icons/lo32-mime-x_psion_data.png Binary files differindex b365f45..4f19555 100644 --- a/kde2/mime/icons/lo32-mime-x_psion_data.png +++ b/kde2/mime/icons/lo32-mime-x_psion_data.png diff --git a/kde2/mime/icons/lo32-mime-x_psion_encryptit.png b/kde2/mime/icons/lo32-mime-x_psion_encryptit.png Binary files differindex 105f784..d4ca041 100644 --- a/kde2/mime/icons/lo32-mime-x_psion_encryptit.png +++ b/kde2/mime/icons/lo32-mime-x_psion_encryptit.png diff --git a/kde2/mime/icons/lo32-mime-x_psion_opl.png b/kde2/mime/icons/lo32-mime-x_psion_opl.png Binary files differindex 064df0a..078cad6 100644 --- a/kde2/mime/icons/lo32-mime-x_psion_opl.png +++ b/kde2/mime/icons/lo32-mime-x_psion_opl.png diff --git a/kde2/mime/icons/lo32-mime-x_psion_opo.png b/kde2/mime/icons/lo32-mime-x_psion_opo.png Binary files differindex 916fa19..4850d33 100644 --- a/kde2/mime/icons/lo32-mime-x_psion_opo.png +++ b/kde2/mime/icons/lo32-mime-x_psion_opo.png diff --git a/kde2/mime/icons/lo32-mime-x_psion_opx.png b/kde2/mime/icons/lo32-mime-x_psion_opx.png Binary files differindex de90515..4741851 100644 --- a/kde2/mime/icons/lo32-mime-x_psion_opx.png +++ b/kde2/mime/icons/lo32-mime-x_psion_opx.png diff --git a/kde2/mime/icons/lo32-mime-x_psion_recorder.png b/kde2/mime/icons/lo32-mime-x_psion_recorder.png Binary files differindex b935808..174068c 100644 --- a/kde2/mime/icons/lo32-mime-x_psion_recorder.png +++ b/kde2/mime/icons/lo32-mime-x_psion_recorder.png diff --git a/kde2/mime/icons/lo32-mime-x_psion_sheet.png b/kde2/mime/icons/lo32-mime-x_psion_sheet.png Binary files differindex 336cb04..63626f7 100644 --- a/kde2/mime/icons/lo32-mime-x_psion_sheet.png +++ b/kde2/mime/icons/lo32-mime-x_psion_sheet.png diff --git a/kde2/mime/icons/lo32-mime-x_psion_sis.png b/kde2/mime/icons/lo32-mime-x_psion_sis.png Binary files differindex 1af15bb..649f258 100644 --- a/kde2/mime/icons/lo32-mime-x_psion_sis.png +++ b/kde2/mime/icons/lo32-mime-x_psion_sis.png diff --git a/kde2/mime/icons/lo32-mime-x_psion_unknown.png b/kde2/mime/icons/lo32-mime-x_psion_unknown.png Binary files differindex b70ac35..7b77048 100644 --- a/kde2/mime/icons/lo32-mime-x_psion_unknown.png +++ b/kde2/mime/icons/lo32-mime-x_psion_unknown.png diff --git a/kde2/mime/icons/lo32-mime-x_psion_word.png b/kde2/mime/icons/lo32-mime-x_psion_word.png Binary files differindex c677b70..808c17d 100644 --- a/kde2/mime/icons/lo32-mime-x_psion_word.png +++ b/kde2/mime/icons/lo32-mime-x_psion_word.png diff --git a/kde2/mime/psion-drive-actions.desktop b/kde2/mime/psion-drive-actions.desktop new file mode 100644 index 0000000..c9a1e39 --- /dev/null +++ b/kde2/mime/psion-drive-actions.desktop @@ -0,0 +1,16 @@ +[Desktop Entry] +ServiceTypes=inode/x-psion-drive +Actions=Backup;Restore;Format +Patterns= +[Desktop Action Backup] +Exec=kpsion backup %u +Name=backup this drive +Name[de]=Laufwerk sichern +[Desktop Action Format] +Exec=kpsion format %u +Name=format this drive +Name[de]=Laufwerk formatieren +[Desktop Action Restore] +Exec=kpsion restore %u +Name=restore this drive +Name[de]=Laufwerk rücksichern diff --git a/kde2/mime/x-psion-backup.desktop b/kde2/mime/x-psion-backup.desktop new file mode 100644 index 0000000..7d46250 --- /dev/null +++ b/kde2/mime/x-psion-backup.desktop @@ -0,0 +1,7 @@ +[Desktop Entry] +Comment=Psion Backup +Hidden=false +Icon=psion_backup +MimeType=application/x-psion-backup +Patterns= +Type=MimeType diff --git a/kde2/mime/x-psion-machine.desktop b/kde2/mime/x-psion-machine.desktop new file mode 100644 index 0000000..cc0310f --- /dev/null +++ b/kde2/mime/x-psion-machine.desktop @@ -0,0 +1,7 @@ +[Desktop Entry] +Comment=Psion Machine +Hidden=false +Icon=psion_desktop +MimeType=application/x-psion-machine +Patterns= +Type=MimeType diff --git a/kde2/mime/x-psion-owner.desktop b/kde2/mime/x-psion-owner.desktop new file mode 100644 index 0000000..9d1fe06 --- /dev/null +++ b/kde2/mime/x-psion-owner.desktop @@ -0,0 +1,7 @@ +[Desktop Entry] +Comment=Psion Owner +Hidden=false +Icon=psion_owner +MimeType=application/x-psion-owner +Patterns= +Type=MimeType diff --git a/kde2/mime/x-psion-restore.desktop b/kde2/mime/x-psion-restore.desktop new file mode 100644 index 0000000..c79c5dc --- /dev/null +++ b/kde2/mime/x-psion-restore.desktop @@ -0,0 +1,7 @@ +[Desktop Entry] +Comment=Psion Restore +Hidden=false +Icon=psion_restore +MimeType=application/x-psion-restore +Patterns= +Type=MimeType diff --git a/kde2/mime/x-psion-setup.desktop b/kde2/mime/x-psion-setup.desktop new file mode 100644 index 0000000..20d0f7c --- /dev/null +++ b/kde2/mime/x-psion-setup.desktop @@ -0,0 +1,7 @@ +[Desktop Entry] +Comment=Psion Settings +Hidden=false +Icon=psion_setup +MimeType=application/x-psion-setup +Patterns= +Type=MimeType diff --git a/kde2/plugins/Makefile.am b/kde2/plugins/Makefile.am index 9ef736d..35d3f27 100644 --- a/kde2/plugins/Makefile.am +++ b/kde2/plugins/Makefile.am @@ -2,7 +2,7 @@ AM_CPPFLAGS = -DQT_NO_CAST_ASCII INCLUDES = $(all_includes) -I$(top_srcdir)/lib -LDFLAGS = $(all_libraries) $(KDE_RPATH) +LDFLAGS = $(all_libraries) libplpprops_la_LDFLAGS = $(LIBDEBUG) $(all_libraries) -module -no-undefined -version-info $(LIBVERSION) diff --git a/kde2/plugins/plpprops.cc b/kde2/plugins/plpprops.cc index 1992e33..6db2c5b 100644 --- a/kde2/plugins/plpprops.cc +++ b/kde2/plugins/plpprops.cc @@ -1,65 +1,65 @@ +/*-*-c++-*- + * $Id$ + * + * This file is part of plptools. + * + * Copyright (C) 2001 Fritz Elfert <felfert@to.com> + * + * 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 + * + */ #ifdef HAVE_CONFIG_H #include <config.h> #endif -#include <stream.h> -#include <errno.h> -#include <assert.h> - -#include <qfile.h> -#include <qapplication.h> -#include <qdir.h> -#include <qlabel.h> -#include <qpushbutton.h> -#include <qcheckbox.h> -#include <qstrlist.h> -#include <qstringlist.h> -#include <qtextstream.h> -#include <qpainter.h> -#include <qlayout.h> -#include <qcombobox.h> -#include <qgroupbox.h> +#include "plpprops.h" +#include "pie3dwidget.h" -#include <kdialog.h> -#include <kdirsize.h> -#include <kdirwatch.h> #include <kdebug.h> -#include <kdesktopfile.h> -#include <kicondialog.h> -#include <kurl.h> -#include <kurlrequester.h> #include <klocale.h> -#include <kglobal.h> -#include <kglobalsettings.h> -#include <kstddirs.h> -#include <kio/job.h> -#include <kio/renamedlg.h> -#include <kfiledialog.h> -#include <kmimetype.h> -#include <kmessagebox.h> -#include <kservice.h> -#include <kglobal.h> -#include <kcompletion.h> -#include <klineedit.h> -//#include <klibloader.h> -//#include <ktrader.h> #include <kio/slaveinterface.h> +#include <krun.h> -#include "plpprops.h" -#include "pie3dwidget.h" - +#include <qlayout.h> +#include <qlabel.h> #include <qobjectlist.h> #include <qtabwidget.h> +#include <qcheckbox.h> +#include <qwhatsthis.h> + +#include <rfsv.h> +#include <rpcs.h> + +#include <strstream> +#include <iomanip> + +#define PLP_CMD_DRIVEINFO 1 +#define PLP_CMD_OWNERINFO 2 +#define PLP_CMD_GETATTR 3 +#define PLP_CMD_SETATTR 4 +#define PLP_CMD_MACHINFO 5 #define KIO_ARGS QByteArray packedArgs; \ QDataStream stream( packedArgs, IO_WriteOnly ); stream class PlpPropsPlugin::PlpPropsPluginPrivate { public: - PlpPropsPluginPrivate() { } - ~PlpPropsPluginPrivate() { } + PlpPropsPluginPrivate() { } + ~PlpPropsPluginPrivate() { } - QFrame *m_frame; + QFrame *frame; }; /* @@ -67,375 +67,908 @@ public: * the Properties dialog. */ static void -removePermsPage(QWidget *theDialog) { - QObject *qtabwidget = 0L; - QFrame *permframe = 0L; - - // - // First, find the QTabWidget in the dialog. - // This is easy, cause there's only one. - // - QObjectList *l = theDialog->queryList("QTabWidget"); +removeDialogPage(QWidget *theDialog, QString theLabel) { + QObject *qtabwidget = 0L; + QFrame *permframe = 0L; + + // + // First, find the QTabWidget in the dialog. + // Easy, cause there's only one. + // + QObjectList *l = theDialog->queryList("QTabWidget"); + QObjectListIt it(*l); + QObject * obj; + while ((obj=it.current()) != 0) { + ++it; + qtabwidget = obj; + } + delete l; + + // Now, walk thru all Childs of the QTabWidget which are + // inherited from class QFrame. For every found frame, + // compare the tabLabel against the required label (&Permissions). + // + if (qtabwidget != 0L) { + l = qtabwidget->queryList("QFrame"); QObjectListIt it(*l); - QObject * obj; - while ((obj=it.current()) != 0) { - ++it; - qtabwidget = obj; + + while ((obj = it.current()) != 0) { + if (theLabel == + ((QTabWidget *)qtabwidget)->tabLabel((QWidget*)obj)) { + permframe = (QFrame *)obj; + break; + } + ++it; } delete l; - // Now, walk thru all Childs of the QTabWidget which are - // inherited from class QFrame. - // - if (qtabwidget != 0L) { - l = qtabwidget->queryList("QFrame"); - QObjectListIt it(*l); - - while ((obj = it.current()) != 0) { - QObjectList *l2 = obj->queryList(); - QObjectListIt it2(*l2); - QObject *o2; - int qvbl, qgb, qgl, ql, qcb; - qvbl = qgb = qgl = ql = qcb = 0; - - // If we found a QFrame, count it's children - // by className. We must rely on the numbers, - // because not a single child has been given - // a name. - while ((o2 = it2.current()) != 0) { - if (o2->isA("QVBoxLayout")) - qvbl++; - if (o2->isA("QGroupBox")) - qgb++; - if (o2->isA("QGridLayout")) - qgl++; - if (o2->isA("QLabel")) - ql++; - if (o2->isA("QCheckBox")) - qcb++; - ++it2; - } - delete l2; - - // The PermissionsPage is build out of: - // - // 1 QVBoxLayout, 2 QGroupboxes, 2 QGridLayouts, - // 15 QLabels and 12 QCheckBoxes - // - if ((qvbl == 1) && - (qgb == 2) && - (qgl == 2) && - (ql == 15) && - (qcb == 12)) { - permframe = (QFrame *)obj; - break; - } - ++it; - } - delete l; - - // If we found it, remove it. - if (permframe != 0) - ((QTabWidget *)qtabwidget)->removePage(permframe); - } + // If we found it, remove it. + if (permframe != 0) + ((QTabWidget *)qtabwidget)->removePage(permframe); + } } PlpPropsPlugin::PlpPropsPlugin(KPropertiesDialog *_props) - : KPropsDlgPlugin( _props ) + : KPropsDlgPlugin( _props ) { - d = new PlpPropsPluginPrivate; - bool removePerms = false; - - if (!supports(properties->items())) - return; - - if (PlpFileAttrPage::supports(properties->items())) { - PlpFileAttrPage *p = new PlpFileAttrPage(_props); - removePerms = true; - } - if (PlpDriveAttrPage::supports(properties->items())) { - PlpDriveAttrPage *p = new PlpDriveAttrPage(_props); - removePerms = true; - } - if (PlpMachinePage::supports(properties->items())) { - PlpMachinePage *p = new PlpMachinePage(_props); - } - if (PlpOwnerPage::supports(properties->items())) { - PlpOwnerPage *p = new PlpOwnerPage(_props); - } - if (removePerms) - removePermsPage(properties->dialog()); + d = new PlpPropsPluginPrivate; + bool removePerms = false; + bool removeGeneral = false; + + if (!supports(properties->items())) + return; + + if (PlpFileAttrPage::supports(properties->items())) { + PlpFileAttrPage *p = new PlpFileAttrPage(_props); + connect(p, SIGNAL(changed()), SLOT(doChange())); + connect(this, SIGNAL(save()), p, SLOT(applyChanges())); + removePerms = true; + } + if (PlpDriveAttrPage::supports(properties->items())) { + PlpDriveAttrPage *p = new PlpDriveAttrPage(_props); + removePerms = true; + } + if (PlpMachinePage::supports(properties->items())) { + PlpMachinePage *p = new PlpMachinePage(_props); + removePerms = true; + removeGeneral = true; + } + if (PlpOwnerPage::supports(properties->items())) { + PlpOwnerPage *p = new PlpOwnerPage(_props); + removePerms = true; + removeGeneral = true; + } + if (removePerms) + removeDialogPage(properties->dialog(), i18n("&Permissions")); + if (removeGeneral) + removeDialogPage(properties->dialog(), i18n("&General")); } PlpPropsPlugin::~PlpPropsPlugin() { - delete d; + delete d; } bool PlpPropsPlugin::supports(KFileItemList _items) { - for (KFileItemListIterator it(_items); it.current(); ++it) { - KFileItem *fi = it.current(); + for (KFileItemListIterator it(_items); it.current(); ++it) { + KFileItem *fi = it.current(); - if (fi->url().protocol() != QString::fromLatin1("psion")) - return false; - } - return true; + if (fi->url().protocol() != QString::fromLatin1("psion")) + return false; + } + return true; } void PlpPropsPlugin::applyChanges() { - kdDebug(250) << "PlpFileAttrPlugin::applyChanges" << endl; + emit save(); } -void PlpPropsPlugin::postApplyChanges() { +void PlpPropsPlugin::doChange() { + emit changed(); } class PlpFileAttrPage::PlpFileAttrPagePrivate { + + typedef struct { + const char * const lbl; + const u_int32_t mask; + bool inverted; + bool direnabled; + bool s5enabled; + } UIelem; + public: - PlpFileAttrPagePrivate() { } - ~PlpFileAttrPagePrivate() { } - QFrame *m_frame; + PlpFileAttrPagePrivate(); + ~PlpFileAttrPagePrivate() {} + + KPropertiesDialog *props; + + bool jobReturned; + u_int32_t flags; + u_int32_t attr; + + const UIelem *generic; + const UIelem *s3; + const UIelem *s5; + + QFrame *frame; + QLabel *psiPath; + QCheckBox *genCb[5]; // MUST match initializers below!!! + QCheckBox *specCb[3]; // MUST match initializers below!!! }; -PlpFileAttrPage::PlpFileAttrPage(KPropertiesDialog *_props) - : KPropsDlgPlugin( _props ) { - d = new PlpFileAttrPagePrivate; - d->m_frame = properties->dialog()->addPage(i18n("Psion &Attributes")); +PlpFileAttrPage::PlpFileAttrPagePrivate::PlpFileAttrPagePrivate() { + int i; + + static const UIelem _generic[] = { + { "Readable", rfsv::PSI_A_READ, false, false, false }, // Fake for S5 + { "Writeable", rfsv::PSI_A_RDONLY, true, true, true }, + { "Hidden", rfsv::PSI_A_HIDDEN, false, true, true }, + { "System", rfsv::PSI_A_SYSTEM, false, false, true }, + { "Archive", rfsv::PSI_A_ARCHIVE, false, true, true }, + { 0L, 0L, false, false, true }, + }; + static const UIelem _s3[] = { + { "Executable", rfsv::PSI_A_EXEC, false, false, true }, + { "Stream", rfsv::PSI_A_STREAM, false, false, true }, + { "Text", rfsv::PSI_A_TEXT, false, false, true }, + { 0L, 0L, false, false, true }, + }; + static const UIelem _s5[] = { + { "Normal", rfsv::PSI_A_NORMAL, false, false, true }, + { "Temporary", rfsv::PSI_A_TEMP, false, false, true }, + { "Compressed", rfsv::PSI_A_COMPRESSED, false, false, true }, + { 0L, 0L, false, false, true }, + }; + generic = _generic; + s3 = _s3; + s5 = _s5; +} + +PlpFileAttrPage::PlpFileAttrPage(KPropertiesDialog *_props) { + QGridLayout *mgl; + QGridLayout *gl; + QGroupBox *gb; + QLabel *l; + int i; + + d = new PlpFileAttrPagePrivate; + d->props = _props; + d->frame = _props->dialog()->addPage(i18n("Psion &Attributes")); + + mgl = new QGridLayout(d->frame, 1, 1, KDialog::marginHint(), + KDialog::spacingHint(), "mainLayout"); + + l = new QLabel(i18n("Path on Psion:"), d->frame, "psiPathLabel"); + mgl->addWidget(l, 0, 0); + + d->psiPath = new QLabel(QString::fromLatin1("?"), d->frame, "psiPath"); + mgl->addWidget(d->psiPath, 0, 1); + mgl->setColStretch(1, 1); + + gb = new QGroupBox(i18n("Generic attributes"), d->frame, "genattrBox"); + mgl->addMultiCellWidget(gb, 1, 1, 0, 1); + gl = new QGridLayout (gb, 1, 1, KDialog::marginHint(), + KDialog::spacingHint(), "genattrLayout"); + for (i = 0; d->generic[i].lbl; i++) { + QString lbl = KGlobal::locale()->translate(d->generic[i].lbl); + d->genCb[i] = new QCheckBox(lbl, gb, d->generic[i].lbl); + d->genCb[i]->setEnabled(false); + connect(d->genCb[i], SIGNAL(toggled(bool)), SLOT(slotCbToggled(bool))); + gl->addWidget(d->genCb[i], 0, i); + } + + gb = new QGroupBox(i18n("Machine specific attributes"), d->frame, + "specattrBox"); + mgl->addMultiCellWidget(gb, 2, 2, 0, 1); + gl = new QGridLayout (gb, 1, 1, KDialog::marginHint(), + KDialog::spacingHint(), "specattrLayout"); + for (i = 0; d->s5[i].lbl; i++) { + QString lbl = KGlobal::locale()->translate(d->s5[i].lbl); + d->specCb[i] = new QCheckBox(lbl, gb, d->s5[i].lbl); + d->specCb[i]->setEnabled(false); + connect(d->specCb[i], SIGNAL(toggled(bool)), SLOT(slotCbToggled(bool))); + gl->addWidget(d->specCb[i], 0, i); + } + mgl->addRowSpacing(3, KDialog::marginHint()); + + d->jobReturned = false; + KIO_ARGS << int(PLP_CMD_GETATTR) << _props->item()->url().path(); + KIO::StatJob *job = new KIO::StatJob(KURL("psion:/"), KIO::CMD_SPECIAL, + packedArgs, false); + connect(job, SIGNAL(result(KIO::Job *)), + SLOT(slotGetSpecialFinished(KIO::Job *))); } PlpFileAttrPage::~PlpFileAttrPage() { - delete d; + delete d; } bool PlpFileAttrPage::supports(KFileItemList _items) { - for (KFileItemListIterator it(_items); it.current(); ++it) { - KFileItem *fi = it.current(); + for (KFileItemListIterator it(_items); it.current(); ++it) { + KFileItem *fi = it.current(); + + QString path = fi->url().path(-1); + if (path.contains('/') == 1) + return false; + } + return true; +} - QString path = fi->url().path(-1); - if (path.contains('/') == 1) - return false; +void PlpFileAttrPage::applyChanges() { + u_int32_t attr = 0; + bool isS5 = ((d->flags & 1) != 0); + bool val; + int i; + + for (i = 0; d->generic[i].lbl; i++) { + val = d->genCb[i]->isChecked(); + if (d->generic[i].inverted) + val = !val; + if (val) + attr |= d->generic[i].mask; + } + if (isS5) + for (i = 0; d->s5[i].lbl; i++) { + val = d->specCb[i]->isChecked(); + if (d->s5[i].inverted) + val = !val; + if (val) + attr |= d->s5[i].mask; + } + else + for (i = 0; d->s3[i].lbl; i++) { + val = d->specCb[i]->isChecked(); + if (d->s3[i].inverted) + val = !val; + if (val) + attr |= d->s3[i].mask; } - return true; + if (d->attr != attr) { + u_int32_t mask = d->attr ^ attr; + u_int32_t sattr = attr & mask; + u_int32_t dattr = ~sattr & mask; + cout << "apply: old=" << hex << d->attr << " new=" << attr << endl; + cout << "apply: m=" << hex << mask << " s=" << sattr << " d=" << dattr << endl; + + KIO_ARGS << int(PLP_CMD_SETATTR) << sattr << dattr + << d->props->item()->url().path(); + KIO::SimpleJob *sjob = new KIO::SimpleJob(KURL("psion:/"), + KIO::CMD_SPECIAL, packedArgs, + false); + connect(sjob, SIGNAL(result(KIO::Job *)), + SLOT(slotSetSpecialFinished(KIO::Job *))); + } } -void PlpFileAttrPage::applyChanges() { +void PlpFileAttrPage::slotCbToggled(bool) { + if (d->jobReturned) + emit changed(); +} + +void PlpFileAttrPage::slotSetSpecialFinished(KIO::Job *job) { + KIO::SimpleJob *sJob = static_cast<KIO::SimpleJob *>(job); + + if (sJob->error()) + job->showErrorDialog(d->props->dialog()); +} + +void PlpFileAttrPage::slotGetSpecialFinished(KIO::Job *job) { + KIO::StatJob *sJob = static_cast<KIO::StatJob *>(job); + + if (sJob->error()) + job->showErrorDialog(d->props->dialog()); + else { + KIO::UDSEntry e = sJob->statResult(); + bool attr_found = false; + bool flags_found = false; + u_int32_t flags; + u_int32_t attr; + + for (KIO::UDSEntry::ConstIterator it = e.begin(); it != e.end(); ++it) { + if ((*it).m_uds == KIO::UDS_SIZE) { + attr_found = true; + attr = (unsigned long)((*it).m_long); + } + if ((*it).m_uds == KIO::UDS_CREATION_TIME) { + flags_found = true; + flags = (unsigned long)((*it).m_long); + } + if ((*it).m_uds == KIO::UDS_NAME) + d->psiPath->setText((*it).m_str); + } + if (attr_found && flags_found) { + bool isS5 = ((flags & 1) != 0); + bool isRom = ((flags & 2) != 0); + bool noDir = ((attr & rfsv::PSI_A_DIR) == 0); + int i; + + d->attr = attr; + d->flags = flags; + for (i = 0; d->generic[i].lbl; i++) { + bool val = ((attr & d->generic[i].mask) != 0); + if (d->generic[i].inverted) + val = !val; + d->genCb[i]->setChecked(val); + if ((!isRom) && (d->generic[i].s5enabled) && + (noDir || d->generic[i].direnabled)) { + d->genCb[i]->setEnabled(true); + } + } + if (isS5) + for (i = 0; d->s5[i].lbl; i++) { + bool val = ((attr & d->s5[i].mask) != 0); + d->specCb[i]->setChecked(val); + if ((!isRom) && (noDir || d->s5[i].direnabled)) + d->specCb[i]->setEnabled(true); + } + else + for (i = 0; d->s3[i].lbl; i++) { + bool val = ((attr & d->s3[i].mask) != 0); + QString lbl = KGlobal::locale()->translate(d->s3[i].lbl); + d->specCb[i]->setText(lbl); + d->specCb[i]->setChecked(val); + if ((!isRom) && (noDir || d->s3[i].direnabled)) + d->specCb[i]->setEnabled(true); + } + } + } + d->jobReturned = true; } class PlpDriveAttrPage::PlpDriveAttrPagePrivate { public: - PlpDriveAttrPagePrivate() { } - ~PlpDriveAttrPagePrivate() { } - - QFrame *m_frame; + PlpDriveAttrPagePrivate() { } + ~PlpDriveAttrPagePrivate() { } + + QColor usedColor; + QColor freeColor; + QString driveLetter; + + KPropertiesDialog *props; + QFrame *frame; + QGroupBox *gb; + Pie3DWidget *pie; + QLabel *typeLabel; + QLabel *totalLabel; + QLabel *freeLabel; + QLabel *uidLabel; + QPushButton *restoreButton; + QPushButton *formatButton; }; -PlpDriveAttrPage::PlpDriveAttrPage(KPropertiesDialog *_props) - : KPropsDlgPlugin( _props ) { +PlpDriveAttrPage::PlpDriveAttrPage(KPropertiesDialog *_props) { + d = new PlpDriveAttrPagePrivate; + d->props = _props; + d->frame = _props->dialog()->addPage(i18n("Psion &Drive")); - d = new PlpDriveAttrPagePrivate; - d->m_frame = properties->dialog()->addPage(i18n("Psion &Drive")); + QBoxLayout *box = new QVBoxLayout(d->frame, KDialog::spacingHint()); + QLabel *l; + QGridLayout *gl; + QPushButton *b; + d->usedColor = QColor(219, 58, 197); + d->freeColor = QColor(39, 56, 167); + d->driveLetter = ""; - QBoxLayout *box = new QVBoxLayout( d->m_frame, KDialog::spacingHint() ); - QLabel *l; - QGridLayout *gl; - usedColor = QColor(219, 58, 197); - freeColor = QColor(39, 56, 167); + d->gb = new QGroupBox(i18n("Information"), d->frame, "driveinfo"); + box->addWidget(d->gb); - KIO_ARGS << int(1) << properties->item()->name(); - KIO::StatJob *job = new KIO::StatJob(KURL("psion:/"), KIO::CMD_SPECIAL, packedArgs, false); - connect(job, SIGNAL(result(KIO::Job *)), SLOT(slotSpecialFinished(KIO::Job *))); + gl = new QGridLayout(d->gb, 7, 4, 15); + gl->addRowSpacing(0, 10); - gb = new QGroupBox(i18n("Information"), d->m_frame); - box->addWidget(gb); + l = new QLabel(i18n("Type"), d->gb, "typeLabel"); + gl->addWidget(l, 1, 0); - gl = new QGridLayout(gb, 7, 4, 15); - gl->addRowSpacing(0, 10); + d->typeLabel = new QLabel(d->gb); + gl->addWidget(d->typeLabel, 2, 0); + QWhatsThis::add(d->typeLabel, + i18n("The type of the drive is shown here.")); - l = new QLabel(i18n("Type"), gb, "typeLabel"); - gl->addWidget(l, 1, 0); + l = new QLabel(i18n("Total capacity"), d->gb, "capacityLabel"); + gl->addWidget (l, 1, 1); - typeLabel = new QLabel(gb); - gl->addWidget(typeLabel, 2, 0); + d->totalLabel = new QLabel(i18n(" "), d->gb, "capacityValue"); + gl->addWidget(d->totalLabel, 2, 1); + QWhatsThis::add(d->totalLabel, + i18n("This shows the total capacity of the drive.")); - l = new QLabel(i18n("Total capacity"), gb, "capacityLabel"); - gl->addWidget (l, 1, 1); + l = new QLabel(i18n("Free space"), d->gb, "spaceLabel"); + gl->addWidget (l, 1, 2); - totalLabel = new QLabel(i18n(" "), gb, "capacityValue"); - gl->addWidget(totalLabel, 2, 1); + d->freeLabel = new QLabel(i18n(" "), d->gb, "spaceValue"); + gl->addWidget(d->freeLabel, 2, 2); + QWhatsThis::add(d->freeLabel, + i18n("This shows the available space of the drive.")); - l = new QLabel(i18n("Free space"), gb, "spaceLabel"); - gl->addWidget (l, 1, 2); + l = new QLabel(i18n("Unique ID"), d->gb, "uidLabel"); + gl->addWidget (l, 1, 3); - freeLabel = new QLabel(i18n(" "), gb, "spaceValue"); - gl->addWidget(freeLabel, 2, 2); + d->uidLabel = new QLabel(i18n(" "), d->gb, "uidValue"); + gl->addWidget(d->uidLabel, 2, 3); + QWhatsThis::add(d->freeLabel, + i18n("This shows unique ID of the drive. For ROM drives, this is always 0.")); - l = new QLabel(i18n("Unique ID"), gb, "uidLabel"); - gl->addWidget (l, 1, 3); + d->pie = new Pie3DWidget(d->gb, "pie"); - uidLabel = new QLabel(i18n(" "), gb, "uidValue"); - gl->addWidget(uidLabel, 2, 3); + gl->addMultiCellWidget(d->pie, 3, 4, 1, 2); - pie = new Pie3DWidget(gb, "pie"); + QHBoxLayout *blay = new QHBoxLayout(KDialog::spacingHint(), "buttons"); + gl->addMultiCellLayout(blay, 5, 6, 1, 3); + blay->setAlignment(AlignRight | AlignVCenter); - gl->addMultiCellWidget(pie, 3, 4, 1, 2); + b = new QPushButton(i18n("Backup"), d->gb, "backupButton"); + connect(b, SIGNAL(clicked()), SLOT(slotBackupClicked())); + blay->addWidget(b, 0); + QWhatsThis::add(b, + i18n("Click here, to do a backup of this drive. This launches KPsion to perform that task.")); - l = new QLabel(i18n("Used space:"), gb, "usedLgend"); - l->setAlignment(AlignRight | AlignVCenter); - gl->addWidget (l, 5, 2); - - l = new QLabel(i18n(" "), gb, "usedLegendColor"); - l->setBackgroundColor(usedColor); - gl->addWidget (l, 5, 3); + b = new QPushButton(i18n("Restore"), d->gb, "restoreButton"); + connect(b, SIGNAL(clicked()), SLOT(slotRestoreClicked())); + blay->addWidget(b, 0); + d->restoreButton = b; + QWhatsThis::add(b, + i18n("Click here, to do a restore of this drive. This launches KPsion to perform that task.")); - l = new QLabel(i18n("Free space:"), gb, "spaceLegend"); - l->setAlignment(AlignRight | AlignVCenter); - gl->addWidget (l, 6, 2); + b = new QPushButton(i18n("Format"), d->gb, "formatButton"); + connect(b, SIGNAL(clicked()), SLOT(slotFormatClicked())); + blay->addWidget(b, 0); + d->formatButton = b; + QWhatsThis::add(b, + i18n("Click here, to format this drive. This launches KPsion to perform that task.")); - l = new QLabel(i18n(" "), gb, "spaceLegendColor"); - l->setBackgroundColor(freeColor); + blay->addStretch(10); - gl->addWidget (l, 6, 3); + box->addStretch(10); + + KIO_ARGS << int(PLP_CMD_DRIVEINFO) << _props->item()->url().path(); + KIO::StatJob *job = new KIO::StatJob(KURL("psion:/"), KIO::CMD_SPECIAL, + packedArgs, false); + connect(job, SIGNAL(result(KIO::Job *)), + SLOT(slotSpecialFinished(KIO::Job *))); - box->addStretch(10); } PlpDriveAttrPage::~PlpDriveAttrPage() { - delete d; + delete d; } bool PlpDriveAttrPage::supports(KFileItemList _items) { - for (KFileItemListIterator it(_items); it.current(); ++it) { - KFileItem *fi = it.current(); + for (KFileItemListIterator it(_items); it.current(); ++it) { + KFileItem *fi = it.current(); + + QString path = fi->url().path(-1); + if (path.contains('/') != 1) + return false; + if (fi->url().path() == QString::fromLatin1("/")) + return false; + } + return true; +} - QString path = fi->url().path(-1); - if (path.contains('/') != 1) - return false; - } - return true; +void PlpDriveAttrPage::slotBackupClicked() { + if (!d->driveLetter.isEmpty()) + KRun::runCommand( + QString::fromLatin1("kpsion --backup %1").arg(d->driveLetter)); +} + +void PlpDriveAttrPage::slotRestoreClicked() { + if (!d->driveLetter.isEmpty()) + KRun::runCommand( + QString::fromLatin1("kpsion --restore %1").arg(d->driveLetter)); } -void PlpDriveAttrPage::applyChanges() { +void PlpDriveAttrPage::slotFormatClicked() { + if (!d->driveLetter.isEmpty()) + KRun::runCommand( + QString::fromLatin1("kpsion --format %1").arg(d->driveLetter)); } void PlpDriveAttrPage::slotSpecialFinished(KIO::Job *job) { - KIO::StatJob *sJob = static_cast<KIO::StatJob *>(job); - - if (sJob->error()) - job->showErrorDialog(properties->dialog()); - else { - KIO::UDSEntry e = sJob->statResult(); - bool total_found = false; - bool free_found = false; - - for (KIO::UDSEntry::ConstIterator it = e.begin(); it != e.end(); ++it) { - if ((*it).m_uds == KIO::UDS_SIZE) { - total_found = true; - total = (unsigned long)((*it).m_long); - } - if ((*it).m_uds == KIO::UDS_MODIFICATION_TIME) { - free_found = true; - unused = (unsigned long)((*it).m_long); - } - if ((*it).m_uds == KIO::UDS_CREATION_TIME) { - unsigned long uid = (unsigned long)((*it).m_long); - uidLabel->setText(QString::fromLatin1("%1").arg(uid, 8, 16)); - } - if ((*it).m_uds == KIO::UDS_NAME) { - QString name = ((*it).m_str); - typeLabel->setText(name); - } - if ((*it).m_uds == KIO::UDS_USER) { - QString name = ((*it).m_str); - gb->setTitle(QString(i18n("Information for Psion drive %1: (%2)")).arg(name).arg(properties->item()->name())); - } - } - if (total_found && free_found) { - totalLabel->setText(QString::fromLatin1("%1 (%2)").arg(KIO::convertSize(total)).arg(KGlobal::locale()->formatNumber(total, 0))); - freeLabel->setText(QString::fromLatin1("%1 (%2)").arg(KIO::convertSize(unused)).arg(KGlobal::locale()->formatNumber(unused, 0))); - pie->addPiece(total - unused, usedColor); - pie->addPiece(unused, freeColor); + KIO::StatJob *sJob = static_cast<KIO::StatJob *>(job); + + if (sJob->error()) + job->showErrorDialog(d->props->dialog()); + else { + KIO::UDSEntry e = sJob->statResult(); + bool total_found = false; + bool free_found = false; + u_int32_t total; + u_int32_t unused; + + for (KIO::UDSEntry::ConstIterator it = e.begin(); it != e.end(); ++it) { + if ((*it).m_uds == KIO::UDS_SIZE) { + total_found = true; + total = (unsigned long)((*it).m_long); + } + if ((*it).m_uds == KIO::UDS_MODIFICATION_TIME) { + free_found = true; + unused = (unsigned long)((*it).m_long); + } + if ((*it).m_uds == KIO::UDS_CREATION_TIME) { + unsigned long uid = (unsigned long)((*it).m_long); + d->uidLabel->setText(QString::fromLatin1("%1").arg(uid, 8, 16)); + } + if ((*it).m_uds == KIO::UDS_NAME) { + QString name = ((*it).m_str); + d->typeLabel->setText(name); + if (name == QString::fromLatin1("ROM")) { + d->restoreButton->setEnabled(false); + d->formatButton->setEnabled(false); + // Can't change anything + removeDialogPage(d->props->dialog(), i18n("&General")); } + } + if ((*it).m_uds == KIO::UDS_USER) { + d->driveLetter = ((*it).m_str); + d->gb->setTitle(QString(i18n("Information for Psion drive %1: (%2)")).arg(d->driveLetter).arg(d->props->item()->name())); + } } + if (total_found && free_found) { + d->totalLabel->setText(QString::fromLatin1("%1 (%2)").arg(KIO::convertSize(total)).arg(KGlobal::locale()->formatNumber(total, 0))); + d->freeLabel->setText(QString::fromLatin1("%1 (%2)").arg(KIO::convertSize(unused)).arg(KGlobal::locale()->formatNumber(unused, 0))); + d->pie->addPiece(total - unused, d->usedColor); + d->pie->addPiece(unused, d->freeColor); + } + } } class PlpMachinePage::PlpMachinePagePrivate { public: - PlpMachinePagePrivate() { } - ~PlpMachinePagePrivate() { } - - QFrame *m_frame; + PlpMachinePagePrivate() { } + ~PlpMachinePagePrivate() { } + + KPropertiesDialog *props; + + QFrame *f; + QGridLayout *g; + + QLabel *machType; + QLabel *machName; + QLabel *machUID; + QLabel *machLang; + + QLabel *romVersion; + QLabel *romSize; + QLabel *romProg; + + QLabel *ramSize; + QLabel *ramFree; + QLabel *ramMaxFree; + QLabel *ramDiskSz; + + QLabel *regSize; + QLabel *dispGeo; + QLabel *machTime; + QLabel *machUTCo; + QLabel *machDST; + + QLabel *mbattChanged; + QLabel *mbattUsage; + QLabel *mbattStatus; + QLabel *mbattPower; + QLabel *mbattCurrent; + QLabel *mbattVoltage; + QLabel *mbattMaxVoltage; + + QLabel *bbattStatus; + QLabel *bbattUsage; + QLabel *bbattVoltage; + QLabel *bbattMaxVoltage; + + rpcs::machineInfo mi; }; -PlpMachinePage::PlpMachinePage( KPropertiesDialog *_props ) - : KPropsDlgPlugin( _props ) { - - d = new PlpMachinePagePrivate; - d->m_frame = properties->dialog()->addPage(i18n("Psion &Machine")); - - QVBoxLayout * mainlayout = new QVBoxLayout( d->m_frame, KDialog::spacingHint()); - - // Now the widgets in the top layout - - QLabel* l; - l = new QLabel(d->m_frame, "Label_1" ); - l->setText( i18n("Machine UID:") ); - mainlayout->addWidget(l, 1); +QLabel *PlpMachinePage:: +makeEntry(QString text, QWidget *w, int y) { + QLabel *l = new QLabel(w); + d->g->addWidget(new QLabel(text, w), y, 0); + d->g->addWidget(l, y, 1); + return l; +} - mainlayout->addStretch(2); +PlpMachinePage::PlpMachinePage( KPropertiesDialog *_props ) { + d = new PlpMachinePagePrivate; + d->props = _props; + + QGroupBox *gb; + QBoxLayout *box; + + d->f = _props->dialog()->addPage(i18n("Psion &Machine")); + + box = new QVBoxLayout(d->f, KDialog::spacingHint()); + gb = new QGroupBox(i18n("General"), d->f, "genInfBox"); + box->addWidget(gb); + d->g = new QGridLayout(gb, 1, 1, KDialog::marginHint(), + KDialog::spacingHint()); + + d->machType = makeEntry(i18n("Machine type:"), gb, 1); + QWhatsThis::add(d->machType, + i18n("Here, the type of the connected device is shown.")); + d->machName = makeEntry(i18n("Model name:"), gb, 2); + QWhatsThis::add(d->machName, + i18n("Here, the model name of the connected device is shown.")); + d->machUID = makeEntry(i18n("Machine UID:"), gb, 3); + QWhatsThis::add(d->machUID, + i18n("Here, the unique ID of the connected device is shown.")); + d->machLang = makeEntry(i18n("UI language:"), gb, 4); + QWhatsThis::add(d->machLang, + i18n("Here, the user interface language of the connected device is shown.")); + d->dispGeo = makeEntry(i18n("Display geometry:"), gb, 5); + QWhatsThis::add(d->dispGeo, + i18n("Here, the display geometry of the connected device is shown.")); + d->regSize = makeEntry(i18n("Registry size:"), gb, 6); + QWhatsThis::add(d->regSize, + i18n("Here, the size of the registry data is shown.")); + d->g->addRowSpacing(0, KDialog::marginHint()); + d->g->setColStretch(1, 1); + + gb = new QGroupBox(i18n("Time"), d->f, "timeInfBox"); + box->addWidget(gb); + d->g = new QGridLayout(gb, 1, 1, KDialog::marginHint(), + KDialog::spacingHint()); + d->machTime = makeEntry(i18n("Date/Time:"), gb, 1); + QWhatsThis::add(d->machTime, + i18n("Here, the current time setting of the connected device is shown.")); + d->machUTCo = makeEntry(i18n("UTC offset"), gb, 2); + QWhatsThis::add(d->machUTCo, + i18n("Here, the offset of the connected device's time zone relative to GMT is shown.")); + d->machDST = makeEntry(i18n("Daylight saving"), gb, 3); + QWhatsThis::add(d->machDST, + i18n("Here, you can see, if daylight saving time is currently active on the connected device.")); + d->g->addRowSpacing(0, KDialog::marginHint()); + d->g->setColStretch(1, 1); + box->addStretch(10); + + d->f = _props->dialog()->addPage(i18n("Psion &Battery")); + box = new QVBoxLayout(d->f, KDialog::spacingHint()); + gb = new QGroupBox(i18n("Main battery"), d->f, "mbatInfBox"); + box->addWidget(gb); + d->g = new QGridLayout(gb, 1, 1, KDialog::marginHint(), + KDialog::spacingHint()); + d->mbattChanged = makeEntry(i18n("Changed at:"), gb, 1); + QWhatsThis::add(d->mbattChanged, + i18n("This shows the time of last battery change.")); + d->mbattUsage = makeEntry(i18n("Usage time:"), gb, 2); + QWhatsThis::add(d->mbattUsage, + i18n("This shows the accumulated time of running on battery power.")); + d->mbattStatus = makeEntry(i18n("Status:"), gb, 3); + QWhatsThis::add(d->mbattStatus, + i18n("This shows current status of the battery.")); + d->mbattPower = makeEntry(i18n("Total consumed power:"), gb, 4); + QWhatsThis::add(d->mbattPower, + i18n("This shows accumulated power consumtion of the device.")); + d->mbattCurrent = makeEntry(i18n("Current:"), gb, 5); + QWhatsThis::add(d->mbattCurrent, + i18n("This shows the current, drawn from power supply (battery or mains).")); + d->mbattVoltage = makeEntry(i18n("Voltage:"), gb, 6); + QWhatsThis::add(d->mbattVoltage, + i18n("This shows the current battery voltage.")); + d->mbattMaxVoltage = makeEntry(i18n("Max. voltage:"), gb, 7); + QWhatsThis::add(d->mbattMaxVoltage, + i18n("This shows the maximum battery voltage.")); + d->g->addRowSpacing(0, KDialog::marginHint()); + d->g->setColStretch(1, 1); + + gb = new QGroupBox(i18n("Backup battery"), d->f, "bbatInfBox"); + box->addWidget(gb); + d->g = new QGridLayout(gb, 1, 1, KDialog::marginHint(), + KDialog::spacingHint()); + d->bbattUsage = makeEntry(i18n("Usage time:"), gb, 1); + QWhatsThis::add(d->bbattUsage, + i18n("This shows the accumulated time of running on backup battery power.")); + d->bbattStatus = makeEntry(i18n("Status:"), gb, 2); + QWhatsThis::add(d->bbattStatus, + i18n("This shows current status of the backup battery.")); + d->bbattVoltage = makeEntry(i18n("Voltage:"), gb, 3); + QWhatsThis::add(d->bbattVoltage, + i18n("This shows the current backup battery voltage.")); + d->bbattMaxVoltage = makeEntry(i18n("Max. voltage:"), gb, 4); + QWhatsThis::add(d->bbattMaxVoltage, + i18n("This shows the maximum backup battery voltage.")); + d->g->addRowSpacing(0, KDialog::marginHint()); + d->g->setColStretch(1, 1); + box->addStretch(10); + + d->f = _props->dialog()->addPage(i18n("Psion M&emory")); + + box = new QVBoxLayout(d->f, KDialog::spacingHint()); + gb = new QGroupBox(i18n("ROM"), d->f, "romInfBox"); + box->addWidget(gb); + d->g = new QGridLayout(gb, 1, 1, KDialog::marginHint(), + KDialog::spacingHint()); + d->romVersion = makeEntry(i18n("Version:"), gb, 1); + QWhatsThis::add(d->romVersion, + i18n("This shows the firmware version.")); + d->romSize = makeEntry(i18n("Size:"), gb, 2); + QWhatsThis::add(d->romSize, + i18n("This shows the size of the ROM.")); + d->romProg = makeEntry(i18n("Programmable:"), gb, 3); + QWhatsThis::add(d->romProg, + i18n("This shows, whether the ROM is flashable or not.")); + d->g->addRowSpacing(0, KDialog::marginHint()); + d->g->setColStretch(1, 1); + + gb = new QGroupBox(i18n("RAM"), d->f, "ramInfBox"); + box->addWidget(gb); + d->g = new QGridLayout(gb, 1, 1, KDialog::marginHint(), + KDialog::spacingHint()); + d->ramSize = makeEntry(i18n("Size:"), gb, 1); + QWhatsThis::add(d->ramSize, + i18n("This shows the total capacity of the RAM.")); + d->ramFree = makeEntry(i18n("Free:"), gb, 2); + QWhatsThis::add(d->ramFree, + i18n("This shows the free capacity of the RAM.")); + d->ramMaxFree = makeEntry(i18n("Max. free:"), gb, 3); + QWhatsThis::add(d->ramMaxFree, + i18n("This shows the size of the largest free block of the RAM.")); + d->ramDiskSz = makeEntry(i18n("RAMDisk size:"), gb, 4); + QWhatsThis::add(d->ramMaxFree, + i18n("This shows, how much RAM is currently used for the RAMDisc.")); + d->g->addRowSpacing(0, KDialog::marginHint()); + d->g->setColStretch(1, 1); + box->addStretch(10); + + KIO_ARGS << int(PLP_CMD_MACHINFO); + PlpMachInfoJob *job = new PlpMachInfoJob(packedArgs); + connect(job, SIGNAL(result(KIO::Job *)), + SLOT(slotJobFinished(KIO::Job *))); + connect(job, SIGNAL(data(KIO::Job *, const QByteArray &)), + SLOT(slotJobData(KIO::Job *, const QByteArray &))); } PlpMachinePage::~PlpMachinePage() { - delete d; + delete d; } bool PlpMachinePage::supports(KFileItemList _items) { - for (KFileItemListIterator it(_items); it.current(); ++it) { - KFileItem *fi = it.current(); - - QString path = fi->url().path(-1); - if (path.contains('/') != 1) - return false; - if (fi->mimetype() != QString::fromLatin1("application/x-psion-machine")) - return false; - } - return true; + for (KFileItemListIterator it(_items); it.current(); ++it) { + KFileItem *fi = it.current(); + + if (fi->url().path() != QString::fromLatin1("/")) + return false; + } + return true; } -void PlpMachinePage::applyChanges() { +void PlpMachinePage::slotJobData(KIO::Job *job, const QByteArray &data) { + cout << "Mjdata" << endl; + if (data.size() == sizeof(d->mi)) { + memcpy((char *)&d->mi, data, sizeof(d->mi)); + cout << "got machInfo" << endl; + + d->machType->setText(KGlobal::locale()->translate(d->mi.machineType)); + d->machName->setText(QString::fromLatin1(d->mi.machineName)); + // ??! None of QString's formatting methods knows about long long. + ostrstream s; + s << hex << setw(16) << d->mi.machineUID << '\0'; + d->machUID->setText(QString::fromLatin1(s.str())); + d->machLang->setText(KGlobal::locale()->translate(d->mi.uiLanguage)); + d->dispGeo->setText(QString::fromLatin1("%1x%2").arg(d->mi.displayWidth).arg(d->mi.displayHeight)); + d->regSize->setText(QString::fromLatin1("%1 (%2)").arg(KIO::convertSize(d->mi.registrySize)).arg(KGlobal::locale()->formatNumber(d->mi.registrySize, 0))); + + QString rev; + rev.sprintf("%d.%02d(%d)", d->mi.romMajor, d->mi.romMinor, + d->mi.romBuild); + d->romVersion->setText(rev); + d->romSize->setText(QString::fromLatin1("%1 (%2)").arg(KIO::convertSize(d->mi.romSize)).arg(KGlobal::locale()->formatNumber(d->mi.romSize, 0))); + d->romProg->setText(d->mi.romProgrammable ? i18n("yes") : i18n("no")); + + d->ramSize->setText(QString::fromLatin1("%1 (%2)").arg(KIO::convertSize(d->mi.ramSize)).arg(KGlobal::locale()->formatNumber(d->mi.ramSize, 0))); + d->ramFree->setText(QString::fromLatin1("%1 (%2)").arg(KIO::convertSize(d->mi.ramFree)).arg(KGlobal::locale()->formatNumber(d->mi.ramFree, 0))); + d->ramMaxFree->setText(QString::fromLatin1("%1 (%2)").arg(KIO::convertSize(d->mi.ramMaxFree)).arg(KGlobal::locale()->formatNumber(d->mi.ramMaxFree, 0))); + d->ramDiskSz->setText(QString::fromLatin1("%1 (%2)").arg(KIO::convertSize(d->mi.ramDiskSize)).arg(KGlobal::locale()->formatNumber(d->mi.ramDiskSize, 0))); + + + PsiTime pt(&d->mi.time, &d->mi.tz); + QDateTime dt; + dt.setTime_t(pt.getTime()); + d->machTime->setText(KGlobal::locale()->formatDateTime(dt, false)); + d->machUTCo->setText(i18n("%1 seconds").arg(d->mi.tz.utc_offset)); + d->machDST->setText((d->mi.tz.dst_zones & PsiTime::PSI_TZ_HOME) ? i18n("yes") : i18n("no")); + + ostrstream mbs; + mbs << d->mi.mainBatteryUsedTime << '\0'; + d->mbattUsage->setText(QString::fromLatin1(mbs.str())); + pt.setPsiTime(&d->mi.mainBatteryInsertionTime); + dt.setTime_t(pt.getTime()); + d->mbattChanged->setText(KGlobal::locale()->formatDateTime(dt, false)); + d->mbattStatus->setText( + KGlobal::locale()->translate(d->mi.mainBatteryStatus)); + d->mbattPower->setText(QString::fromLatin1("%1 mAs").arg(KGlobal::locale()->formatNumber(d->mi.mainBatteryUsedPower, 0))); + d->mbattCurrent->setText(QString::fromLatin1("%1 mA").arg(KGlobal::locale()->formatNumber(d->mi.mainBatteryCurrent, 0))); + d->mbattVoltage->setText(QString::fromLatin1("%1 mV").arg(KGlobal::locale()->formatNumber(d->mi.mainBatteryVoltage, 0))); + d->mbattMaxVoltage->setText(QString::fromLatin1("%1 mV").arg(KGlobal::locale()->formatNumber(d->mi.mainBatteryMaxVoltage, 0))); + + ostrstream bbs; + bbs << d->mi.backupBatteryUsedTime << '\0'; + d->bbattUsage->setText(QString::fromLatin1(bbs.str())); + d->bbattStatus->setText( + KGlobal::locale()->translate(d->mi.backupBatteryStatus)); + d->bbattVoltage->setText(QString::fromLatin1("%1 mV").arg(KGlobal::locale()->formatNumber(d->mi.backupBatteryVoltage, 0))); + d->bbattMaxVoltage->setText(QString::fromLatin1("%1 mV").arg(KGlobal::locale()->formatNumber(d->mi.backupBatteryMaxVoltage, 0))); + } } +void PlpMachinePage::slotJobFinished(KIO::Job *job) { + PlpMachInfoJob *mJob = static_cast<PlpMachInfoJob *>(job); + + if (mJob->error()) + job->showErrorDialog(d->props->dialog()); +} class PlpOwnerPage::PlpOwnerPagePrivate { public: - PlpOwnerPagePrivate() { } - ~PlpOwnerPagePrivate() { } + PlpOwnerPagePrivate() { } + ~PlpOwnerPagePrivate() { } - QFrame *m_frame; + QFrame *frame; + KPropertiesDialog *props; + QMultiLineEdit *owneredit; }; -PlpOwnerPage::PlpOwnerPage( KPropertiesDialog *_props ) : KPropsDlgPlugin( _props ) { - d = new PlpOwnerPagePrivate; - d->m_frame = properties->dialog()->addPage(i18n("Psion &Owner")); +PlpOwnerPage::PlpOwnerPage( KPropertiesDialog *_props ) { + d = new PlpOwnerPagePrivate; + d->props = _props; + d->frame = _props->dialog()->addPage(i18n("Psion &Owner")); + QBoxLayout *box = new QVBoxLayout( d->frame, KDialog::spacingHint() ); + d->owneredit = new QMultiLineEdit(d->frame, "ownerinfo"); + d->owneredit->setReadOnly(true); + box->addWidget(d->owneredit); + QWhatsThis::add(d->owneredit, + i18n("This shows the owner's information of the connected device.")); + + KIO_ARGS << int(PLP_CMD_OWNERINFO); + KIO::StatJob *job = new KIO::StatJob(KURL("psion:/"), + KIO::CMD_SPECIAL, packedArgs, false); + connect(job, SIGNAL(result(KIO::Job *)), + SLOT(slotSpecialFinished(KIO::Job *))); + + box->addStretch(10); } PlpOwnerPage::~PlpOwnerPage() { - delete d; + delete d; } bool PlpOwnerPage::supports(KFileItemList _items) { - for (KFileItemListIterator it(_items); it.current(); ++it) { - KFileItem *fi = it.current(); - - QString path = fi->url().path(-1); - if (path.contains('/') != 1) - return false; - if (fi->mimetype() != QString::fromLatin1("application/x-psion-owner")) - return false; + for (KFileItemListIterator it(_items); it.current(); ++it) { + KFileItem *fi = it.current(); + + if (fi->url().path() != QString::fromLatin1("/")) + return false; + } + return true; +} + +void PlpOwnerPage::slotSpecialFinished(KIO::Job *job) { + KIO::StatJob *sJob = static_cast<KIO::StatJob *>(job); + + if (sJob->error()) + job->showErrorDialog(d->props->dialog()); + else { + KIO::UDSEntry e = sJob->statResult(); + for (KIO::UDSEntry::ConstIterator it = e.begin(); + it != e.end(); ++it) { + if ((*it).m_uds == KIO::UDS_NAME) + d->owneredit->setText((*it).m_str); } - return true; + } } -void PlpOwnerPage::applyChanges() { +PlpMachInfoJob::PlpMachInfoJob(const QByteArray &packedArgs) + : KIO::TransferJob(KURL("psion:/"), KIO::CMD_SPECIAL, + packedArgs, QByteArray(), false) { +} + +void PlpMachInfoJob:: +slotFinished() { + SimpleJob::slotFinished(); } #include "plpprops.moc" +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ diff --git a/kde2/plugins/plpprops.h b/kde2/plugins/plpprops.h index eeb3d4d..b7e23e0 100644 --- a/kde2/plugins/plpprops.h +++ b/kde2/plugins/plpprops.h @@ -1,146 +1,191 @@ -/* $Id$ +/*-*-c++-*- + * $Id$ + * + * This file is part of plptools. + * + * Copyright (C) 1999 Philip Proudman <philip.proudman@btinternet.com> + * Copyright (C) 1999-2001 Fritz Elfert <felfert@to.com> + * + * 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 * - * This file holds the definitions for all classes used to - * display a Psion related properties dialog. */ - #ifndef _PLPPROPS_H_ #define _PLPPROPS_H_ #include <qstring.h> #include <qlist.h> #include <qgroupbox.h> +#include <qmultilineedit.h> #include <kurl.h> #include <kfileitem.h> #include <kdialogbase.h> #include <kpropsdlg.h> +#include <krun.h> +#include <kio/job.h> #include "pie3dwidget.h" -namespace KIO { class Job; } +class PlpMachInfoJob : public KIO::TransferJob { + Q_OBJECT + +public: + PlpMachInfoJob(const QByteArray &packedArgs); + +protected slots: + virtual void slotFinished(); + +}; class PlpPropsPlugin : public KPropsDlgPlugin { - Q_OBJECT - public: - /** - * Constructor - */ - PlpPropsPlugin( KPropertiesDialog *_props ); - virtual ~PlpPropsPlugin(); - - /** - * Applies all changes made. - */ - virtual void applyChanges(); - - /** - * Tests whether the files specified by _items need a 'General' plugin. - */ - static bool supports(KFileItemList _items); - - /** - * Called after all plugins applied their changes - */ - void postApplyChanges(); - - private: - class PlpPropsPluginPrivate; - PlpPropsPluginPrivate *d; + Q_OBJECT + +public: + /** + * Constructor + */ + PlpPropsPlugin( KPropertiesDialog *_props ); + virtual ~PlpPropsPlugin(); + + /** + * Applies all changes made. + */ + virtual void applyChanges(); + + /** + * Tests whether the files specified by _items need a 'General' plugin. + */ + static bool supports(KFileItemList _items); + +signals: + void save(); + +private slots: + void doChange(); + +private: + class PlpPropsPluginPrivate; + PlpPropsPluginPrivate *d; }; -class PlpFileAttrPage : public KPropsDlgPlugin { - Q_OBJECT - public: - /** - * Constructor - */ - PlpFileAttrPage(KPropertiesDialog *_props); - virtual ~PlpFileAttrPage(); +class PlpFileAttrPage : public QObject { + Q_OBJECT + +public: + /** + * Constructor + */ + PlpFileAttrPage(KPropertiesDialog *_props); + virtual ~PlpFileAttrPage(); + + static bool supports(KFileItemList _items); - virtual void applyChanges(); +public slots: + void applyChanges(); - static bool supports(KFileItemList _items); +signals: + void changed(); - private: - class PlpFileAttrPagePrivate; - PlpFileAttrPagePrivate *d; +private slots: + void slotGetSpecialFinished(KIO::Job *job); + void slotSetSpecialFinished(KIO::Job *job); + void slotCbToggled(bool); + +private: + class PlpFileAttrPagePrivate; + PlpFileAttrPagePrivate *d; }; -class PlpDriveAttrPage : public KPropsDlgPlugin { - Q_OBJECT - public: - /** - * Constructor - */ - PlpDriveAttrPage(KPropertiesDialog *_props); - virtual ~PlpDriveAttrPage(); - - virtual void applyChanges(); - - static bool supports(KFileItemList _items); - - private slots: - void slotSpecialFinished(KIO::Job *job); - - private: - class PlpDriveAttrPagePrivate; - PlpDriveAttrPagePrivate *d; - - unsigned long total; - unsigned long unused; - - QGroupBox *gb; - QLabel *uidLabel; - QLabel *typeLabel; - QLabel *totalLabel; - QLabel *freeLabel; - QColor usedColor; - QColor freeColor; - Pie3DWidget *pie; +class PlpDriveAttrPage : public QObject { + Q_OBJECT + +public: + /** + * Constructor + */ + PlpDriveAttrPage(KPropertiesDialog *_props); + virtual ~PlpDriveAttrPage(); + + static bool supports(KFileItemList _items); + +private slots: + void slotSpecialFinished(KIO::Job *job); + void slotBackupClicked(); + void slotRestoreClicked(); + void slotFormatClicked(); + +private: + class PlpDriveAttrPagePrivate; + PlpDriveAttrPagePrivate *d; + }; /** - * Used to view/edit machine info. + * Used to view machine info. */ -class PlpMachinePage : public KPropsDlgPlugin { - Q_OBJECT - public: - /** - * Constructor - */ - PlpMachinePage(KPropertiesDialog *_props); - virtual ~PlpMachinePage(); - - virtual void applyChanges(); - - static bool supports(KFileItemList _items); - - private: - class PlpMachinePagePrivate; - PlpMachinePagePrivate *d; +class PlpMachinePage : public QObject { + Q_OBJECT + +public: + /** + * Constructor + */ + PlpMachinePage(KPropertiesDialog *_props); + virtual ~PlpMachinePage(); + + static bool supports(KFileItemList _items); + +private slots: + void slotJobData(KIO::Job *job, const QByteArray &data); + void slotJobFinished(KIO::Job *job); + +private: + class PlpMachinePagePrivate; + PlpMachinePagePrivate *d; + + QLabel *makeEntry(QString text, QWidget *w, int y); }; /** - * Used to view/edit owner info + * Used to view owner info */ -class PlpOwnerPage : public KPropsDlgPlugin { - Q_OBJECT - public: - /** - * Constructor - */ - PlpOwnerPage(KPropertiesDialog *_props); - virtual ~PlpOwnerPage(); - - virtual void applyChanges(); - - static bool supports(KFileItemList _items); - - private: - class PlpOwnerPagePrivate; - PlpOwnerPagePrivate *d; +class PlpOwnerPage : public QObject { + Q_OBJECT + +public: + /** + * Constructor + */ + PlpOwnerPage(KPropertiesDialog *_props); + virtual ~PlpOwnerPage(); + + static bool supports(KFileItemList _items); + +private slots: +void slotSpecialFinished(KIO::Job *job); + +private: + class PlpOwnerPagePrivate; + PlpOwnerPagePrivate *d; }; #endif + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ diff --git a/kde2/plugins/plppropsFactory.cc b/kde2/plugins/plppropsFactory.cc index 2c553cf..616b12b 100644 --- a/kde2/plugins/plppropsFactory.cc +++ b/kde2/plugins/plppropsFactory.cc @@ -1,3 +1,13 @@ +namespace LIBPLP { +extern "C" { +#include <intl.h> + void init_libplp_i18n() { + bind_textdomain_codeset(PACKAGE, "latin1"); + textdomain(PACKAGE); + } +}; +}; + #include "plppropsFactory.h" #include "plpprops.h" @@ -15,7 +25,8 @@ plppropsFactory::plppropsFactory(QObject *parent, const char *name) : KLibFactory(parent, name) { s_global = new KInstance("plpprops"); // Install the translations - //KGlobal::locale()->insertCatalogue("plpprops"); + KGlobal::locale()->insertCatalogue(QString::fromLatin1("plptools")); + LIBPLP::init_libplp_i18n(); } plppropsFactory::~plppropsFactory() { @@ -26,7 +37,6 @@ QObject* plppropsFactory::createObject(QObject* parent, const char *name, const QObject *obj = 0L; - cout << "plppropsFactory: name=" << name << " class=" << classname << endl; if ((strcmp(classname, "KPropsDlgPlugin") == 0) && parent && parent->inherits("KPropertiesDialog")) diff --git a/kde2/po/Makefile.am b/kde2/po/Makefile.am new file mode 100644 index 0000000..4504a98 --- /dev/null +++ b/kde2/po/Makefile.am @@ -0,0 +1,24 @@ + +SUBDIRS = de + +APPS = kpsion + +merge: + @apps='$(APPS)'; \ + langs='$(SUBDIRS)'; \ + for cat in $$apps; do \ + for lang in $$langs; do \ + if test -r $$lang/$$cat.po; then \ + echo $$cat; \ + msgmerge -o $$cat.new $$lang/$$cat.po $$cat.pot; \ + if test -s $$cat.new && diff $$lang/$$cat.po $$cat.new; then \ + rm $$cat.new; \ + else \ + mv $$cat.new $$lang/$$cat.po ; \ + fi; \ + fi ;\ + done ;\ + done + +messages: + diff --git a/kde2/po/de/Makefile.am b/kde2/po/de/Makefile.am new file mode 100644 index 0000000..62d74e6 --- /dev/null +++ b/kde2/po/de/Makefile.am @@ -0,0 +1,3 @@ +KDE_LANG = de + +POFILES = AUTO diff --git a/kde2/po/de/kpsion.po b/kde2/po/de/kpsion.po new file mode 100644 index 0000000..f145b98 --- /dev/null +++ b/kde2/po/de/kpsion.po @@ -0,0 +1,631 @@ +# Message catalog for KPsion. +# Copyright (C) 2001 Free Software Foundation, Inc. +# Fritz Elfert <felfert@to.com>, 2001. +# +msgid "" +msgstr "" +"Project-Id-Version: plptools 0.7\n" +"POT-Creation-Date: 2001-02-15 21:17+0100\n" +"PO-Revision-Date: 2001-02-15 22:13CET\n" +"Last-Translator: Fritz Elfert <felfert@to.com>\n" +"Language-Team: Deutsch <de@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 0.8\n" + +#: kpsion.cpp:37 +msgid "Idle" +msgstr "Bereit" + +#: kpsion.cpp:62 wizards.cpp:210 +msgid "off" +msgstr "aus" + +#: kpsion.cpp:66 +msgid "" +"<qt>Here, you see your Psion's drives.<br/>Every drive is represented by an " +"Icon. If you click on it, it gets selected for the next operation. E.g.: " +"backup, restore or format.<br/>To unselect it, simply click on it " +"again.<br/>Select as many drives a you want, then choose an operation.</qt>" +msgstr "" +"<qt>Hier sehen Sie die Laufwerke Ihres Psion.<br/>Jedes Laufwerk wird durch " +"ein Icon repräsentiert. Wenn Sie auf dieses klicken, wird es für die " +"nächste Operation angewählt. z.B.: Sicherung, Rücksicherung oder " +"Formatierung.<br/>Klicken Sie einfach nochmal, um es wieder " +"abzuwählen.<br/>Wählen Sie beliebig viele Laufwerke und dann eine " +"Operation.</qt>" + +#: kpsion.cpp:101 +msgid "Start &Format" +msgstr "Starte &Formatierung" + +#: kpsion.cpp:103 +msgid "Start Full &Backup" +msgstr "Starte &Komplett-Sicherung" + +#: kpsion.cpp:105 +msgid "Start &Incremental Backup" +msgstr "Starte &inkrementelle Sicherung" + +#: kpsion.cpp:107 +msgid "Start &Restore" +msgstr "Starte &Rücksicherung" + +#: kpsion.cpp:116 +msgid "Full backup of selected drive(s)" +msgstr "Komplett-Sicherung der ausgewählten Laufwerke" + +#: kpsion.cpp:117 +msgid "Incremental backup of selected drive(s)" +msgstr "Inkrementelle Sicherung der ausgewählten Laufwerke" + +#: kpsion.cpp:118 +msgid "Restore selected drive(s)" +msgstr "Sichere ausgewählte Laufwerke zurück" + +#: kpsion.cpp:119 +msgid "Format selected drive(s)" +msgstr "Formatiere ausgewählte Laufwerke" + +#: kpsion.cpp:187 +msgid "Retrieving machine info ..." +msgstr "Ermittle Geräte-Info ..." + +#: kpsion.cpp:190 +msgid "Could not get Psion machine info" +msgstr "Konnte Psion Geräteinfo nicht ermitteln" + +#: kpsion.cpp:202 +msgid "an unknown machine" +msgstr "einem unbekannten Gerät" + +#: kpsion.cpp:213 +msgid "Retrieving drive list ..." +msgstr "Ermittle Laufwerks-Liste ..." + +#: kpsion.cpp:215 +msgid "Could not get list of drives" +msgstr "Konnte Liste der Laufwerke nicht ermitteln" + +#: kpsion.cpp:233 +#, c-format +msgid "Connected to %1" +msgstr "Verbunden mit %1" + +#: kpsion.cpp:251 +msgid "" +"A backup is running.\n" +"Do you really want to quit?" +msgstr "" +"Eine Sicherung läuft.\n" +"Wollen Sie wirklich das Programm beenden?" + +#: kpsion.cpp:253 +msgid "" +"A restore is running.\n" +"Do you really want to quit?" +msgstr "" +"Eine Rücksicherung läuft.\n" +"Wollen Sie wirklich das Programm beenden?" + +#: kpsion.cpp:255 +msgid "" +"A format is running.\n" +"Do you really want to quit?" +msgstr "" +"Eine Formatierung läuft.\n" +"Wollen Sie wirklich das Programm beenden?" + +#: kpsion.cpp:280 +msgid "Connecting ..." +msgstr "Verbindungsaufbau ..." + +#: kpsion.cpp:282 +msgid "RFSV could not connect to ncpd at %1:%2. " +msgstr "RFSV konnte ncpd auf %1:%2 nicht erreichen. " + +#: kpsion.cpp:285 kpsion.cpp:301 kpsion.cpp:319 kpsion.cpp:339 +msgid " (Retry in %1 seconds.)" +msgstr " (Wiederholung in %1 Sekunden.)" + +#: kpsion.cpp:296 +#, c-format +msgid "RFSV could not establish link: %1." +msgstr "RFSV konnte keine Verbindung aufbauen: %1." + +#: kpsion.cpp:312 +msgid "RPCS could not connect to ncpd at %1:%2." +msgstr "RPCS konnte ncpd auf %1:%2 nicht erreichen." + +#: kpsion.cpp:330 +#, c-format +msgid "RPCS could not establish link: %1." +msgstr "RPCS konnte keine Verbindung aufbauen: %1." + +#: kpsion.cpp:380 kpsion.cpp:433 +msgid "Backup" +msgstr "Sicherung" + +#: kpsion.cpp:407 +#, c-format +msgid "Could not retrieve drive details for drive %1" +msgstr "Konnte Details des Laufwerks %1 nicht ermitteln." + +#: kpsion.cpp:414 +#, c-format +msgid "Scanning drive %1" +msgstr "Durchsuche Laufwerk %1" + +#: kpsion.cpp:423 +msgid "%1 files need backup" +msgstr "%1 Dateien müssen gesichert werden" + +#: kpsion.cpp:425 +msgid "No files need backup" +msgstr "Keine Dateien zu sichern" + +#: kpsion.cpp:446 +#, c-format +msgid "Could not create backup folder %1" +msgstr "Konnte Sicherungs-Ordner %1 nicht anlegen." + +#: kpsion.cpp:499 +#, c-format +msgid "Backing up %1" +msgstr "Sichere %1" + +#: kpsion.cpp:511 +msgid "<QT>Could not open<BR/><B>%1</B></QT>" +msgstr "<QT>Konnte<BR/><B>%1</B><BR/>nicht öffnen</QT>" + +#: kpsion.cpp:530 +msgid "<QT>Could not read<BR/><B>%1</B></QT>" +msgstr "<QT>Konnte<BR/><B>%1</B><BR/>nicht lesen</QT>" + +#: kpsion.cpp:551 +msgid "Backup done" +msgstr "Sicherung beendet" + +#: kpsion.cpp:563 +msgid "" +"<QT>This erases <B>ALL</B> data on the drive(s).<BR/>Do you really want to " +"proceed?" +msgstr "" +"<QT>Hierdurch werden <B>ALLE</B> Daten auf dem(den) Laufwerk(en) gelöscht.<BR/>" +"Wollen Sie wirklich fortfahren?</QT>" + +#: kpsion.cpp:611 +msgid "Backup %1% complete" +msgstr "Sicherung %1% erledigt" + +#: kpsion.cpp:676 +#, c-format +msgid "Stopping %1" +msgstr "Stoppe %1" + +#: kpsion.cpp:697 +#, c-format +msgid "Starting %1" +msgstr "Starte %1" + +#: kpsion.moc.cpp:43 kpsion.moc.cpp:48 +msgid "KPsionMainWindow" +msgstr "KPsionMainWindow" + +#: main.cpp:15 +msgid "perform backup" +msgstr "Führe Sicherung durch" + +#: main.cpp:17 +msgid "perform restore" +msgstr "Führe Rücksicherung durch" + +#: main.cpp:19 +msgid "format drive" +msgstr "Formatiere Laufwerk" + +#: main.cpp:20 +msgid "The drive letter to backup/restore or format." +msgstr "Der Buchstabe des zu bearbeitenden Laufwerks." + +#: main.cpp:25 +msgid "KPsion" +msgstr "KPsion" + +#: main.cpp:26 +msgid "Psion connectivity utility" +msgstr "Werkzeug für Psion PDA" + +#: main.cpp:31 +msgid "Original Developer/Maintainer" +msgstr "Original Entwickler/Betreuer" + +#: setupdialog.cpp:20 +msgid "&General" +msgstr "&Allgemein" + +#: setupdialog.cpp:25 +msgid "Backup &directory" +msgstr "&Ordner für Sicherungen" + +#: setupdialog.cpp:30 wizards.cpp:87 +msgid "Browse" +msgstr "Durchsuchen" + +#: setupdialog.cpp:33 wizards.cpp:160 +msgid "Backup &generations" +msgstr "Sicherungs-&Generationen" + +#: setupdialog.cpp:39 +msgid "&Machines" +msgstr "&Geräte" + +#: setupdialog.cpp:43 +msgid "Machine &Name" +msgstr "&Name des Geräts" + +#: setupdialog.cpp:48 +msgid "Machine &UID" +msgstr "&UID des Geräts" + +#: wizards.cpp:26 +msgid "KPsion Setup" +msgstr "KPsion Einstellungen" + +#: wizards.cpp:28 wizards.cpp:411 +msgid "Click this button to continue with the next page." +msgstr "Betätigen Sie diese Schaltfläche um mit der nächsten Seite fortzufahren." + +#: wizards.cpp:30 wizards.cpp:413 +msgid "Click this button, to go to a previous page." +msgstr "Betätigen Sie diese Schaltfläche, um zur vorigen Seite zu kommen." + +#: wizards.cpp:32 +msgid "" +"<QT>If you click this button, the setup of <B>KPSion</B> will be aborted and " +"next time you start <B>KPsion</B>, it will run this setup again.</QT>" +msgstr "" +"<QT>Wenn Sie diese Schaltfläche betätigen, wird die Konfiguration von " +"<B>KPsion</B> abgebrochen. Beim nächsten Start von <B>KPsion</B> wird dann " +"die Konfiguration erneut gestartet.</QT>" + +#: wizards.cpp:49 +msgid "" +"<QT><H2>Welcome to KPsion!</H2>It looks like you started <B>KPsion</B> the " +"first time. At least, i could not find any valid configuration.</BR>On the " +"following pages, we will gather some information, which is needed for " +"working with <B>KPsion</B>.</BR> </BR>Have fun.</QT>" +msgstr "" +"<QT><H2>Willkommen bei KPsion!</H2>Offensichtlich haben Sie <B>KPsion</B> " +"zum ersten Mal gestartet. Jedenfalls kann ich keine gültige Konfiguration " +"finden.</BR>Auf den folgenden Seiten werden wir einige Informationen " +"sammeln, die für die Arbeit mit <B>KPsion</B> nötig sind.</BR> </BR>Viel " +"Spaß.</QT>" + +#: wizards.cpp:66 +msgid "<QT><BIG><B>Welcome<B></BIG></QT>" +msgstr "<QT><BIG><B>Willkommen<B></BIG></QT>" + +#: wizards.cpp:74 +msgid "" +"<QT>First, we need a folder for storing backups of your Psion. You probably " +"don't want others to have access to it, so it's best to choose a location " +"somewhere in your home directory. Please browse through existing folders and " +"select a suitable location or simply accept the default shown below.</QT>" +msgstr "" +"<QT>Zuerst benötigen wir einen Ordner zum Speichern der Sicherungen Ihres " +"Psion. Sie wollen vielleicht nicht, daß Andere darauf Zugriff haben. Daher " +"ist es am Besten, wenn Sie einen Ordner in Ihrem persönlichen Verzeichnis " +"wählen. Bitte durchsuchen Sie existierende Ordner und wählen dabei eine " +"adäquate Stelle oder akzeptieren Sie einfach die unten angezeigte " +"Vorgabe.</QT>" + +#: wizards.cpp:90 +msgid "This is the name of the backup folder." +msgstr "Dies ist der Name des Sicherungs-Ordners." + +#: wizards.cpp:92 +msgid "" +"Click here, for opening a dialog which lets you easily select the backup " +"folder." +msgstr "" +"Aktivieren Sie diese Schaltfläche, um einen Dialog zu öffnen welcher es " +"Ihnen auf einfache Weise erlaubt, den Sicherungs-Ordner zu wählen." + +#: wizards.cpp:107 +msgid "<QT><BIG><B>Step 1</B></BIG> - Specify backup directory</QT>" +msgstr "<QT><BIG><B>Schritt 1</B></BIG> - Angabe des Sicherungs-Ordners</QT>" + +#: wizards.cpp:114 +msgid "" +"<QT>Next, please specify some information regarding backup " +"policy:<UL><LI>How many generations of backups do you want to " +"keep?</LI><LI>Shall i remind you about backups?</LI><LI>If yes, in what " +"intervals do you want to happen backups?</LI></UL></QT>" +msgstr "" +"<QT>Als nächstes geben Sie bitte einige Informationen zur " +"Sicherungs-Strategie an:<UL><LI>Wie viele Sicherungs-Generationen wollen Sie " +"aufheben?</LI><LI>Soll ich Sie an Sicherungen erinnern?</LI><LI>Wenn ja, in " +"welchen Intervallen?</LI></UL></QT>" + +#: wizards.cpp:124 +msgid "&Incremental backup reminder" +msgstr "Erinnerung an &inkrementelle Sicherung" + +#: wizards.cpp:127 wizards.cpp:145 +msgid "none" +msgstr "keine" + +#: wizards.cpp:128 wizards.cpp:146 +msgid "daily" +msgstr "täglich" + +#: wizards.cpp:129 wizards.cpp:147 +msgid "every 2 days" +msgstr "alle 2 Tage" + +#: wizards.cpp:130 wizards.cpp:148 +msgid "every 3 days" +msgstr "alle 3 Tage" + +#: wizards.cpp:131 wizards.cpp:149 +msgid "every 4 days" +msgstr "alle 4 Tage" + +#: wizards.cpp:132 wizards.cpp:150 +msgid "every 5 days" +msgstr "alle 5 Tage" + +#: wizards.cpp:133 wizards.cpp:151 +msgid "every 6 days" +msgstr "alle 6 Tage" + +#: wizards.cpp:134 wizards.cpp:152 +msgid "weekly" +msgstr "wöchentlich" + +#: wizards.cpp:135 wizards.cpp:153 +msgid "every 2 weeks" +msgstr "alle 2 Wochen" + +#: wizards.cpp:136 wizards.cpp:154 +msgid "every 3 weeks" +msgstr "alle 3 Wochen" + +#: wizards.cpp:137 wizards.cpp:155 +msgid "monthly" +msgstr "monatlich" + +#: wizards.cpp:142 +msgid "&Full backup reminder" +msgstr "Erinnerung an &Komplett-Sicherung" + +#: wizards.cpp:178 +msgid "<QT><BIG><B>Step 2</B></BIG> - Backup policy</QT>" +msgstr "<QT><BIG><B>Schritt 2</B></BIG> - Sicherungs-Strategie</QT>" + +#: wizards.cpp:186 +msgid "" +"<QT>If no connection could be established on startup, <B>KPsion</B> will " +"attempt to connect in regular intervals. Please specify the interval after " +"which a connection attempt should happen. If you don't want automatic retry, " +"set the interval to zero. Furthermore, <B>KPsion</B> can try to start ncpd " +"if it is not already running. For that to work correctly, you need " +"to<UL><LI>specify the serial port to use.</LI><LI>specify the baud " +"rate</LI><LI>have permission to use the specified port</LI></UL></QT>" +msgstr "" +"<QT>Wenn beim Programmstart keine Verbindung aufgebaut werden kann, wird <B>KPsion</B> " +"in regelmäßigen Abständen versuchen erneut eine Verbinung aufzubauen. Bitte geben Sie den" +"Zeitintervall an, nach dem ein erneuter Aufbau der Verbindung versucht werden soll. Wenn Sie " +"diese automatische Funktionalität nicht wünschen, dann setzen Sie bitte den Intervall auf 0. " +"Weiterhin kann <B>KPsion</B> versuchen, den hierzu benötigten Prozess ncpd zu starten falls " +"dieser nicht schon läuft. Um dies zu ermöglichen, müssen Sie" +"<UL><LI>den zu benutzenden seriellen Port angeben.</LI>" +"<LI>die Schnittstellengeschwindigkeit angeben</LI>" +"<LI>die Rechte zum Öffnen des angegebenen Ports besitzen</LI></UL></QT>" + +#: wizards.cpp:201 +msgid "&Connection retry interval (sec.)" +msgstr "&Verbindungsaufbau-Intervall (in sek.)" + +#: wizards.cpp:207 +msgid "Serial &device" +msgstr "&Serielle Schnittstelle" + +#: wizards.cpp:211 +msgid "/dev/ttyS0" +msgstr "/dev/ttyS0" + +#: wizards.cpp:212 +msgid "/dev/ttyS1" +msgstr "/dev/ttyS1" + +#: wizards.cpp:213 +msgid "/dev/ttyS2" +msgstr "/dev/ttyS2" + +#: wizards.cpp:214 +msgid "/dev/ttyS3" +msgstr "/dev/ttyS3" + +#: wizards.cpp:215 +msgid "/dev/ircomm0" +msgstr "/dev/ircomm0" + +#: wizards.cpp:216 +msgid "/dev/ircomm1" +msgstr "/dev/ircomm1" + +#: wizards.cpp:217 +msgid "/dev/ircomm2" +msgstr "/dev/ircomm2" + +#: wizards.cpp:218 +msgid "/dev/ircomm3" +msgstr "/dev/ircomm3" + +#: wizards.cpp:223 +msgid "Serial &speed" +msgstr "Schnittstellen-&Geschwindigkeit" + +#: wizards.cpp:247 +msgid "<QT><BIG><B>Step 3</B></BIG> - Connection parameters</QT>" +msgstr "<QT><BIG><B>Schritt 3</B></BIG> - Verbindungs-Parameter</QT>" + +#: wizards.cpp:255 +msgid "" +"<QT>That's it!<BR/>Next, i will start <B>KPsion</B> and if your Psion is " +"already connected and it's communication turned on (use <B>Ctrl-T</B> at " +"system level), then <B>KPsion</B> will bring up a similar Dialog like this " +"which lets you assing a Name for it. After that, i suggest performing a full " +"Backup.<BR/>Please click <B>Finish</B> now.</QT>" +msgstr "" +"<QT>Das war's!<BR/>Als nächstes wird <B>KPsion</B> gestartet und wenn Ihr Psion " +"schon angeschlossen ist und auch seine Kommunikation eingeschaltet ist (benutzen sie dazu " +"<B>Strg-T</B> auf Systemebene), dann wird <B>KPsion</B> einen weiteren Dialog ähnlich " +"wie Diesen zur Eingabe des Namens präsentieren. Hinterher empfehle ich, als Erstes eine " +"Komplett-Sicherung durchzuführen.<BR/>Bitte betätigen Sie nun die Schaltfläche " +"<B>Abschließen</B>.</QT>" + +#: wizards.cpp:274 +msgid "<QT><BIG><B>Finished</B></BIG></QT>" +msgstr "<QT><BIG><B>Fertig<B></BIG></QT>" + +#: wizards.cpp:282 +msgid "Backup folder" +msgstr "Sicherungs-Ordner" + +#: wizards.cpp:292 +msgid "" +"<QT>You are about to abort the initial setup of <B>KPsion</B>. No " +"configuration will be stored and you will have to repeat this procedure when " +"you start <B>KPsion</B> next time.<BR/>Do you really want to exit now?</QT>" +msgstr "" +"<QT>Sie sind im Begriff die erstmalige Konfiguration von <B>KPsion</B> " +"abzubrechen.Es werden keine Einstellungen gespeichert und sie werden diesen " +"Vorgang wiederholen müssen, wenn Sie <B>KPsion</B> das nächste Mal " +"starten.<BR/>Wollen Sie das Programm wirklich verlassen?</QT>" + +#: wizards.cpp:347 +msgid "<QT>The folder <B>%1</B> does <B>not</B> exist.<BR/>Shall it be created?</QT>" +msgstr "" +"<QT>Der Ordner <B>%1</B> existiert <B>nicht</B>.<BR/>Soll er angelegt " +"werden?</QT>" + +#: wizards.cpp:352 +msgid "<QT>The specified folder<BR/><B>%1</B><BR/>could <B>not</B> be created" +msgstr "<QT>Der angegebene Ordner<BR/><B>%1</B><BR/>konnte nicht angelegt werden" + +#: wizards.cpp:357 +msgid "" +", because you either don't have sufficient rights to do that, or the " +"filesystem is readonly." +msgstr "" +", weil Sie entweder nicht die nötigen Rechte besitzen, oder das Dateisystem " +"nur lesbar ist." + +#: wizards.cpp:361 +msgid ", because the filesystem has not enough space." +msgstr ", weil auf dem Dateisystem kein Platz mehr ist." + +#: wizards.cpp:367 +msgid ", because there already exists another object with the same name." +msgstr ", weil schon ein anderes Objekt mit dem selben Namen existiert." + +#: wizards.cpp:377 +msgid "" +", because you specified a path which probably contains a dangling symbolic " +"link." +msgstr "" +", weil Sie eine Pfad angegeben haben, der eine nicht aufgelöste symbolische " +"Verknüpfung enthält." + +#: wizards.cpp:380 +msgid "" +", because you specified a path which contains an element which is not a " +"folder." +msgstr "" +", weil Sie eine Pfad angegeben haben, der ein Element enthält, welches kein " +"Ordner ist." + +#: wizards.cpp:384 +msgid ", because you specified a path which contains too many symbolic links." +msgstr "" +", weil Sie eine Pfad angegeben haben, der zu viele symbolische " +"Verknüpfungen enthält." + +#: wizards.cpp:391 +msgid "<BR/>Please select another folder.</QT>" +msgstr "<BR/>Bitte wählen Sie einen anderen Ordner.</QT>" + +#: wizards.cpp:407 +msgid "New Psion detected" +msgstr "Neuer Psion erkannt" + +#: wizards.cpp:415 +msgid "" +"<QT>If you click this button, the setup for the new connected Psion will be " +"aborted and next time you connect this Psion again, <B>KPsion</B> will run " +"this setup again.</QT>" +msgstr "" +"<QT>Wenn Sie diese Schaltfläche betätigen, werden die Einstellungen für den neuen " +"Psion nicht gespeichert. Beim nächsten Verbindungsaufbau mit diesem Psion wird " +"<B>KPsion</B> dann erneut diesen Dialog präsentieren.</QT>" + +#: wizards.cpp:424 +msgid "" +"<QT>The Psion with the unique ID <B>%1</B> is connected the first time. " +"Please assign a name to it.</QT>" +msgstr "" +"<QT>Zum Psion mit der ID <B>%1</B> wurde erstmalig Verbindung aufgenommen. " +"Bitte weisen Sie diesem Gerät einen Namen zu.</QT>" + +#: wizards.cpp:431 +msgid "&Name of new Psion" +msgstr "&Name des neuen Psion" + +#: wizards.cpp:433 +msgid "My new Psion" +msgstr "Mein neuer Psion" + +#: wizards.cpp:450 +msgid "<QT><BIG><B>New Psion detected<B></BIG></QT>" +msgstr "<QT><BIG><B>Neuer Psion erkannt<B></BIG></QT>" + +#: wizards.cpp:458 +msgid "" +"<QT>Please select the Drive(s), you want to be backed up when running in " +"unattended backup mode.</QT>" +msgstr "" +"<QT>Bitte wählen sie die Laufwerke aus, die bei einer automatischen Sicherung gesichert" +"werden sollen.</QT>" + +#: wizards.cpp:466 +msgid "Available drives" +msgstr "Verfügbare Laufwerke" + +#: wizards.cpp:490 +msgid "<QT><BIG><B>Specify drives to backup<B></BIG></QT>" +msgstr "<QT><BIG><B>Wahl der zu sichernden Laufwerke<B></BIG></QT>" + +#: wizards.cpp:514 +msgid "The name cannot be empty." +msgstr "Der Name darf nicht leer sein." + +#: wizards.cpp:521 +msgid "" +"<QT>The name <B>%1</B> is already assigned to another machine.<BR/>Please " +"choose a different name.</QT>" +msgstr "" +"<QT>Der Name <B>%1</B> wurde bereits einem anderen Gerät zugewiesen.<BR/>Bitte " +"wählen Sie einen anderen Namen.</QT>" + +#: wizards.moc.cpp:43 wizards.moc.cpp:48 +msgid "FirstTimeWizard" +msgstr "FirstTimeWizard" + +#: wizards.moc.cpp:112 wizards.moc.cpp:117 +msgid "NewPsionWizard" +msgstr "NewPsionWizard" + diff --git a/kde2/po/kpsion.pot b/kde2/po/kpsion.pot new file mode 100644 index 0000000..fcb5025 --- /dev/null +++ b/kde2/po/kpsion.pot @@ -0,0 +1,559 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Free Software Foundation, Inc. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2001-02-15 21:17+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: ENCODING\n" + +#: kpsion.cpp:37 +msgid "Idle" +msgstr "" + +#: kpsion.cpp:62 wizards.cpp:210 +msgid "off" +msgstr "" + +#: kpsion.cpp:66 +msgid "" +"<qt>Here, you see your Psion's drives.<br/>Every drive is represented by an " +"Icon. If you click on it, it gets selected for the next operation. E.g.: " +"backup, restore or format.<br/>To unselect it, simply click on it " +"again.<br/>Select as many drives a you want, then choose an operation.</qt>" +msgstr "" + +#: kpsion.cpp:101 +msgid "Start &Format" +msgstr "" + +#: kpsion.cpp:103 +msgid "Start Full &Backup" +msgstr "" + +#: kpsion.cpp:105 +msgid "Start &Incremental Backup" +msgstr "" + +#: kpsion.cpp:107 +msgid "Start &Restore" +msgstr "" + +#: kpsion.cpp:116 +msgid "Full backup of selected drive(s)" +msgstr "" + +#: kpsion.cpp:117 +msgid "Incremental backup of selected drive(s)" +msgstr "" + +#: kpsion.cpp:118 +msgid "Restore selected drive(s)" +msgstr "" + +#: kpsion.cpp:119 +msgid "Format selected drive(s)" +msgstr "" + +#: kpsion.cpp:187 +msgid "Retrieving machine info ..." +msgstr "" + +#: kpsion.cpp:190 +msgid "Could not get Psion machine info" +msgstr "" + +#: kpsion.cpp:202 +msgid "an unknown machine" +msgstr "" + +#: kpsion.cpp:213 +msgid "Retrieving drive list ..." +msgstr "" + +#: kpsion.cpp:215 +msgid "Could not get list of drives" +msgstr "" + +#: kpsion.cpp:233 +#, c-format +msgid "Connected to %1" +msgstr "" + +#: kpsion.cpp:251 +msgid "" +"A backup is running.\n" +"Do you really want to quit?" +msgstr "" + +#: kpsion.cpp:253 +msgid "" +"A restore is running.\n" +"Do you really want to quit?" +msgstr "" + +#: kpsion.cpp:255 +msgid "" +"A format is running.\n" +"Do you really want to quit?" +msgstr "" + +#: kpsion.cpp:280 +msgid "Connecting ..." +msgstr "" + +#: kpsion.cpp:282 +msgid "RFSV could not connect to ncpd at %1:%2. " +msgstr "" + +#: kpsion.cpp:285 kpsion.cpp:301 kpsion.cpp:319 kpsion.cpp:339 +msgid " (Retry in %1 seconds.)" +msgstr "" + +#: kpsion.cpp:296 +#, c-format +msgid "RFSV could not establish link: %1." +msgstr "" + +#: kpsion.cpp:312 +msgid "RPCS could not connect to ncpd at %1:%2." +msgstr "" + +#: kpsion.cpp:330 +#, c-format +msgid "RPCS could not establish link: %1." +msgstr "" + +#: kpsion.cpp:380 kpsion.cpp:433 +msgid "Backup" +msgstr "" + +#: kpsion.cpp:407 +#, c-format +msgid "Could not retrieve drive details for drive %1" +msgstr "" + +#: kpsion.cpp:414 +#, c-format +msgid "Scanning drive %1" +msgstr "" + +#: kpsion.cpp:423 +msgid "%1 files need backup" +msgstr "" + +#: kpsion.cpp:425 +msgid "No files need backup" +msgstr "" + +#: kpsion.cpp:446 +#, c-format +msgid "Could not create backup folder %1" +msgstr "" + +#: kpsion.cpp:499 +#, c-format +msgid "Backing up %1" +msgstr "" + +#: kpsion.cpp:511 +msgid "<QT>Could not open<BR/><B>%1</B></QT>" +msgstr "" + +#: kpsion.cpp:530 +msgid "<QT>Could not read<BR/><B>%1</B></QT>" +msgstr "" + +#: kpsion.cpp:551 +msgid "Backup done" +msgstr "" + +#: kpsion.cpp:563 +msgid "" +"<QT>This erases <B>ALL</B> data on the drive(s).<BR/>Do you really want to " +"proceed?" +msgstr "" + +#: kpsion.cpp:611 +msgid "Backup %1% complete" +msgstr "" + +#: kpsion.cpp:676 +#, c-format +msgid "Stopping %1" +msgstr "" + +#: kpsion.cpp:697 +#, c-format +msgid "Starting %1" +msgstr "" + +#: kpsion.moc.cpp:43 kpsion.moc.cpp:48 +msgid "KPsionMainWindow" +msgstr "" + +#: main.cpp:15 +msgid "perform backup" +msgstr "" + +#: main.cpp:17 +msgid "perform restore" +msgstr "" + +#: main.cpp:19 +msgid "format drive" +msgstr "" + +#: main.cpp:20 +msgid "The drive letter to backup/restore or format." +msgstr "" + +#: main.cpp:25 +msgid "KPsion" +msgstr "" + +#: main.cpp:26 +msgid "Psion connectivity utility" +msgstr "" + +#: main.cpp:31 +msgid "Original Developer/Maintainer" +msgstr "" + +#: setupdialog.cpp:20 +msgid "&General" +msgstr "" + +#: setupdialog.cpp:25 +msgid "Backup &directory" +msgstr "" + +#: setupdialog.cpp:30 wizards.cpp:87 +msgid "Browse" +msgstr "" + +#: setupdialog.cpp:33 wizards.cpp:160 +msgid "Backup &generations" +msgstr "" + +#: setupdialog.cpp:39 +msgid "&Machines" +msgstr "" + +#: setupdialog.cpp:43 +msgid "Machine &Name" +msgstr "" + +#: setupdialog.cpp:48 +msgid "Machine &UID" +msgstr "" + +#: wizards.cpp:26 +msgid "KPsion Setup" +msgstr "" + +#: wizards.cpp:28 wizards.cpp:411 +msgid "Click this button to continue with the next page." +msgstr "" + +#: wizards.cpp:30 wizards.cpp:413 +msgid "Click this button, to go to a previous page." +msgstr "" + +#: wizards.cpp:32 +msgid "" +"<QT>If you click this button, the setup of <B>KPSion</B> will be aborted and " +"next time you start <B>KPsion</B>, it will run this setup again.</QT>" +msgstr "" + +#: wizards.cpp:49 +msgid "" +"<QT><H2>Welcome to KPsion!</H2>It looks like you started <B>KPsion</B> the " +"first time. At least, i could not find any valid configuration.</BR>On the " +"following pages, we will gather some information, which is needed for " +"working with <B>KPsion</B>.</BR> </BR>Have fun.</QT>" +msgstr "" + +#: wizards.cpp:66 +msgid "<QT><BIG><B>Welcome<B></BIG></QT>" +msgstr "" + +#: wizards.cpp:74 +msgid "" +"<QT>First, we need a folder for storing backups of your Psion. You probably " +"don't want others to have access to it, so it's best to choose a location " +"somewhere in your home directory. Please browse through existing folders and " +"select a suitable location or simply accept the default shown below.</QT>" +msgstr "" + +#: wizards.cpp:90 +msgid "This is the name of the backup folder." +msgstr "" + +#: wizards.cpp:92 +msgid "" +"Click here, for opening a dialog which lets you easily select the backup " +"folder." +msgstr "" + +#: wizards.cpp:107 +msgid "<QT><BIG><B>Step 1</B></BIG> - Specify backup directory</QT>" +msgstr "" + +#: wizards.cpp:114 +msgid "" +"<QT>Next, please specify some information regarding backup " +"policy:<UL><LI>How many generations of backups do you want to " +"keep?</LI><LI>Shall i remind you about backups?</LI><LI>If yes, in what " +"intervals do you want to happen backups?</LI></UL></QT>" +msgstr "" + +#: wizards.cpp:124 +msgid "&Incremental backup reminder" +msgstr "" + +#: wizards.cpp:127 wizards.cpp:145 +msgid "none" +msgstr "" + +#: wizards.cpp:128 wizards.cpp:146 +msgid "daily" +msgstr "" + +#: wizards.cpp:129 wizards.cpp:147 +msgid "every 2 days" +msgstr "" + +#: wizards.cpp:130 wizards.cpp:148 +msgid "every 3 days" +msgstr "" + +#: wizards.cpp:131 wizards.cpp:149 +msgid "every 4 days" +msgstr "" + +#: wizards.cpp:132 wizards.cpp:150 +msgid "every 5 days" +msgstr "" + +#: wizards.cpp:133 wizards.cpp:151 +msgid "every 6 days" +msgstr "" + +#: wizards.cpp:134 wizards.cpp:152 +msgid "weekly" +msgstr "" + +#: wizards.cpp:135 wizards.cpp:153 +msgid "every 2 weeks" +msgstr "" + +#: wizards.cpp:136 wizards.cpp:154 +msgid "every 3 weeks" +msgstr "" + +#: wizards.cpp:137 wizards.cpp:155 +msgid "monthly" +msgstr "" + +#: wizards.cpp:142 +msgid "&Full backup reminder" +msgstr "" + +#: wizards.cpp:178 +msgid "<QT><BIG><B>Step 2</B></BIG> - Backup policy</QT>" +msgstr "" + +#: wizards.cpp:186 +msgid "" +"<QT>If no connection could be established on startup, <B>KPsion</B> will " +"attempt to connect in regular intervals. Please specify the interval after " +"which a connection attempt should happen. If you don't want automatic retry, " +"set the interval to zero. Furthermore, <B>KPsion</B> can try to start ncpd " +"if it is not already running. For that to work correctly, you need " +"to<UL><LI>specify the serial port to use.</LI><LI>specify the baud " +"rate</LI><LI>have permission to use the specified port</LI></UL></QT>" +msgstr "" + +#: wizards.cpp:201 +msgid "&Connection retry interval (sec.)" +msgstr "" + +#: wizards.cpp:207 +msgid "Serial &device" +msgstr "" + +#: wizards.cpp:211 +msgid "/dev/ttyS0" +msgstr "" + +#: wizards.cpp:212 +msgid "/dev/ttyS1" +msgstr "" + +#: wizards.cpp:213 +msgid "/dev/ttyS2" +msgstr "" + +#: wizards.cpp:214 +msgid "/dev/ttyS3" +msgstr "" + +#: wizards.cpp:215 +msgid "/dev/ircomm0" +msgstr "" + +#: wizards.cpp:216 +msgid "/dev/ircomm1" +msgstr "" + +#: wizards.cpp:217 +msgid "/dev/ircomm2" +msgstr "" + +#: wizards.cpp:218 +msgid "/dev/ircomm3" +msgstr "" + +#: wizards.cpp:223 +msgid "Serial &speed" +msgstr "" + +#: wizards.cpp:247 +msgid "<QT><BIG><B>Step 3</B></BIG> - Connection parameters</QT>" +msgstr "" + +#: wizards.cpp:255 +msgid "" +"<QT>That's it!<BR/>Next, i will start <B>KPsion</B> and if your Psion is " +"already connected and it's communication turned on (use <B>Ctrl-T</B> at " +"system level), then <B>KPsion</B> will bring up a similar Dialog like this " +"which lets you assing a Name for it. After that, i suggest performing a full " +"Backup.<BR/>Please click <B>Finish</B> now.</QT>" +msgstr "" + +#: wizards.cpp:274 +msgid "<QT><BIG><B>Finished</B></BIG></QT>" +msgstr "" + +#: wizards.cpp:282 +msgid "Backup folder" +msgstr "" + +#: wizards.cpp:292 +msgid "" +"<QT>You are about to abort the initial setup of <B>KPsion</B>. No " +"configuration will be stored and you will have to repeat this procedure when " +"you start <B>KPsion</B> next time.<BR/>Do you really want to exit now?</QT>" +msgstr "" + +#: wizards.cpp:347 +msgid "" +"<QT>The folder <B>%1</B> does <B>not</B> exist.<BR/>Shall it be created?</QT>" +msgstr "" + +#: wizards.cpp:352 +msgid "<QT>The specified folder<BR/><B>%1</B><BR/>could <B>not</B> be created" +msgstr "" + +#: wizards.cpp:357 +msgid "" +", because you either don't have sufficient rights to do that, or the " +"filesystem is readonly." +msgstr "" + +#: wizards.cpp:361 +msgid ", because the filesystem has not enough space." +msgstr "" + +#: wizards.cpp:367 +msgid ", because there already exists another object with the same name." +msgstr "" + +#: wizards.cpp:377 +msgid "" +", because you specified a path which probably contains a dangling symbolic " +"link." +msgstr "" + +#: wizards.cpp:380 +msgid "" +", because you specified a path which contains an element which is not a " +"folder." +msgstr "" + +#: wizards.cpp:384 +msgid ", because you specified a path which contains too many symbolic links." +msgstr "" + +#: wizards.cpp:391 +msgid "<BR/>Please select another folder.</QT>" +msgstr "" + +#: wizards.cpp:407 +msgid "New Psion detected" +msgstr "" + +#: wizards.cpp:415 +msgid "" +"<QT>If you click this button, the setup for the new connected Psion will be " +"aborted and next time you connect this Psion again, <B>KPsion</B> will run " +"this setup again.</QT>" +msgstr "" + +#: wizards.cpp:424 +msgid "" +"<QT>The Psion with the unique ID <B>%1</B> is connected the first time. " +"Please assign a name to it.</QT>" +msgstr "" + +#: wizards.cpp:431 +msgid "&Name of new Psion" +msgstr "" + +#: wizards.cpp:433 +msgid "My new Psion" +msgstr "" + +#: wizards.cpp:450 +msgid "<QT><BIG><B>New Psion detected<B></BIG></QT>" +msgstr "" + +#: wizards.cpp:458 +msgid "" +"<QT>Please select the Drive(s), you want to be backed up when running in " +"unattended backup mode.</QT>" +msgstr "" + +#: wizards.cpp:466 +msgid "Available drives" +msgstr "" + +#: wizards.cpp:490 +msgid "<QT><BIG><B>Specify drives to backup<B></BIG></QT>" +msgstr "" + +#: wizards.cpp:514 +msgid "The name cannot be empty." +msgstr "" + +#: wizards.cpp:521 +msgid "" +"<QT>The name <B>%1</B> is already assigned to another machine.<BR/>Please " +"choose a different name.</QT>" +msgstr "" + +#: wizards.moc.cpp:43 wizards.moc.cpp:48 +msgid "FirstTimeWizard" +msgstr "" + +#: wizards.moc.cpp:112 wizards.moc.cpp:117 +msgid "NewPsionWizard" +msgstr "" diff --git a/lib/Enum.cc b/lib/Enum.cc index 8abce8b..74fc2e3 100644 --- a/lib/Enum.cc +++ b/lib/Enum.cc @@ -1,57 +1,75 @@ -/*--*-c++-*------------------------------------------------------------- - * $Id$ - *---------------------------------------------------------------------*/ - +/*-*-c++-*- + * $Id$ + * + * This file is part of plptools. + * + * Copyright (C) 2000 Henner Zeller <hzeller@to.com> + * + * 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 "Enum.h" void EnumBase::i2sMapper::add(long i, const char* s) { - stringMap.insert(pair<long, const char* const>(i, s)); + stringMap.insert(pair<long, const char* const>(i, s)); } string EnumBase::i2sMapper::lookup (long i) const { - i2s_map_t::const_iterator searchPtr = stringMap.find(i); + i2s_map_t::const_iterator searchPtr = stringMap.find(i); - if (searchPtr == stringMap.end()) - return "[OUT-OF-RANGE]"; - /* - * now combine the probably the multiple strings belonging to this - * integer - */ - string result; - for (i = stringMap.count(i); i > 0 ; --i, ++searchPtr) { - // this should be the case: - assert(searchPtr != stringMap.end()); - if (result.length() != 0) - result += string(","); - result += string(searchPtr->second); - } - return result; + if (searchPtr == stringMap.end()) + return "[OUT-OF-RANGE]"; + /* + * now combine the probably the multiple strings belonging to this + * integer + */ + string result; + for (i = stringMap.count(i); i > 0 ; --i, ++searchPtr) { + // this should be the case: + assert(searchPtr != stringMap.end()); + if (result.length() != 0) + result += string(","); + result += string(searchPtr->second); + } + return result; } long EnumBase::i2sMapper::lookup (const char *s) const { - /* - * lookup a specific string. - * Since speed does not matter, we just do an exhaustive - * search. - * Otherwise we would have to maintain another map - * mapping strings to ints .. but its not worth the memory - */ - i2s_map_t::const_iterator run = stringMap.begin(); - while (run != stringMap.end() && strcmp(s, run->second)) { - ++run; - } - if (run == stringMap.end()) - return -1; // FIXME .. maybe throw an exception ? - return run->first; + /* + * lookup a specific string. + * Since speed does not matter, we just do an exhaustive + * search. + * Otherwise we would have to maintain another map + * mapping strings to ints .. but its not worth the memory + */ + i2s_map_t::const_iterator run = stringMap.begin(); + while (run != stringMap.end() && strcmp(s, run->second)) { + ++run; + } + if (run == stringMap.end()) + return -1; // FIXME .. maybe throw an exception ? + return run->first; } bool EnumBase::i2sMapper::inRange (long i) const { - return (stringMap.find(i) != stringMap.end()); + return (stringMap.find(i) != stringMap.end()); } -/* +/* * Local variables: - * c-basic-offset: 8 + * c-basic-offset: 4 * End: */ @@ -1,10 +1,36 @@ -/*--*-c++-*------------------------------------------------------------- - * $Id$ - *---------------------------------------------------------------------*/ - +/*-*-c++-*- + * $Id$ + * + * This file is part of plptools. + * + * Copyright (C) 2000 Henner Zeller <hzeller@to.com> + * + * 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 _ENUM_H_ #define _ENUM_H_ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#ifdef HAVE_LIBINTL_H +#include <intl.h> +#endif + #include <map> #include <string> @@ -18,69 +44,69 @@ */ class EnumBase { protected: + /** + * maps integers (typically: enumeration values) to + * Strings. Takes care of the fact, that an Integer may map + * to multiple strings (sometimes multiple enumeration values + * represent the same integer). + * + * Provides a means to get the string representation of an + * integer and vice versa. + * + * @author Henner Zeller + */ + class i2sMapper { + private: /** - * maps integers (typically: enumeration values) to - * Strings. Takes care of the fact, that an Integer may map - * to multiple strings (sometimes multiple enumeration values - * represent the same integer). - * - * Provides a means to get the string representation of an - * integer and vice versa. - * - * @author Henner Zeller - */ - class i2sMapper { - private: - /** - * there can be one value, mapping to multiple - * strings. Therefore, we need a multimap. - */ - typedef multimap<long, const char*> i2s_map_t; - - /** - * just for the record. Mapping back a string to the - * Integer value in question. Since Symbols must be unique, - * there is only a 1:1 relation as opposed to i2s_map_t. So - * we can use a normal map here. - * - * Since in the usual application, mapping a string back - * to its value is not important performance wise (typically - * in a frontend), so it is implemented as exhaustive search, - * not as extra map. Saves some bits of memrory .. - */ - //typedef map<const char*, long> s2i_map_t; + * there can be one value, mapping to multiple + * strings. Therefore, we need a multimap. + */ + typedef multimap<long, const char*> i2s_map_t; - i2s_map_t stringMap; - public: - /** - * adds a new int -> string mapping - * Does NOT take over responsibility for the - * pointer (i.e. it is not freed), so it is save - * to add constant strings provided in the program code. - */ - void add(long, const char*); + /** + * just for the record. Mapping back a string to the + * Integer value in question. Since Symbols must be unique, + * there is only a 1:1 relation as opposed to i2s_map_t. So + * we can use a normal map here. + * + * Since in the usual application, mapping a string back + * to its value is not important performance wise (typically + * in a frontend), so it is implemented as exhaustive search, + * not as extra map. Saves some bits of memrory .. + */ + //typedef map<const char*, long> s2i_map_t; - /** - * returns the string representation for this integer. - * If there are multiple strings for this integer, - * return a comma delimited list. - */ - string lookup(long) const; + i2s_map_t stringMap; + public: + /** + * adds a new int -> string mapping + * Does NOT take over responsibility for the + * pointer (i.e. it is not freed), so it is save + * to add constant strings provided in the program code. + */ + void add(long, const char*); + + /** + * returns the string representation for this integer. + * If there are multiple strings for this integer, + * return a comma delimited list. + */ + string lookup(long) const; - /** - * returns the integer associated with the - * given string or -1 if the value - * is not found (XXX: this should throw - * an exception). - */ - long lookup (const char *) const; + /** + * returns the integer associated with the + * given string or -1 if the value + * is not found (XXX: this should throw + * an exception). + */ + long lookup (const char *) const; - /** - * returns true, if we have an representation for - * the given integer. - */ - bool inRange(long) const; - }; + /** + * returns true, if we have an representation for + * the given integer. + */ + bool inRange(long) const; + }; }; /** @@ -89,7 +115,7 @@ protected: * * The string representation capability is needed to provide a * generic input frontend for any Enumeration because text labels - * are needed in GUIs, and, of course, aids debugging, because you + * are needed in GUIs, and, of course, aids debugging, because you * can provide a readable presentation of an entry if something * goes wrong. * @@ -115,118 +141,124 @@ protected: template<typename E> class Enum : private EnumBase { private: - struct sdata { - /** - * The constructor of the static data part. - * You've to provide a constructor for each Enumeration - * you want to wrap with this class. Initializes - * the string Representation map, the readable name - * of this Enumeration and a default value. - * - * The constructor is called automatically on definition, - * so this makes sure, that the static part is initialized - * properly before the program starts. - */ - sdata(); - i2sMapper stringRep; - string name; - E defaultValue; - }; - static sdata staticData; - + struct sdata { /** - * The actual value hold by this instance + * The constructor of the static data part. + * You've to provide a constructor for each Enumeration + * you want to wrap with this class. Initializes + * the string Representation map, the readable name + * of this Enumeration and a default value. + * + * The constructor is called automatically on definition, + * so this makes sure, that the static part is initialized + * properly before the program starts. */ - E value; + sdata(); + i2sMapper stringRep; + string name; + E defaultValue; + }; + static sdata staticData; + + /** + * The actual value hold by this instance + */ + E value; public: - /** - * default constructor. - * Initialize with default value. - */ - Enum() : value(staticData.defaultValue) {} - - /** - * initialize with Enumeration given. - */ - Enum(E init) : value(init){ - // if this hits you and you're sure, that the - // value is right .. is this Enum proper - // initialized in the Enum<E>::sdata::sdata() ? - assert(inRange(init)); - } - - /** - * initialize with the string representation - * XXX: throw Exception if not found ? - */ - Enum(const string& s) : value(getValueFor(s)) { - assert(inRange(value)); - } + /** + * default constructor. + * Initialize with default value. + */ + Enum() : value(staticData.defaultValue) {} - /** - * assign an Enumeration of this type. In debug - * version, assert, that it is really in the Range of - * this Enumeration. - */ - inline Enum& operator = (E setval) { - value = setval; - assert(inRange(setval)); - return *this; - } + /** + * initialize with Enumeration given. + */ + Enum(E init) : value(init){ + // if this hits you and you're sure, that the + // value is right .. is this Enum proper + // initialized in the Enum<E>::sdata::sdata() ? + assert(inRange(init)); + } - /** - * returns the enumeration value hold with this - * enum. - */ - inline operator E () const { return value; } + /** + * initialize with the string representation + * XXX: throw Exception if not found ? + */ + Enum(const string& s) : value(getValueFor(s)) { + assert(inRange(value)); + } - /** - * returns the String representation for the value - * represented by this instance. - */ - string toString() const { return getStringFor(value); } + /** + * assign an Enumeration of this type. In debug + * version, assert, that it is really in the Range of + * this Enumeration. + */ + inline Enum& operator = (E setval) { + value = setval; + assert(inRange(setval)); + return *this; + } - /** - * This static member returns true, if the integer value - * given fits int the range of this Enumeration. Use this - * to verify input/output. - * Fitting in the range of Enumeration here means, that - * there actually exists a String representation for it, - * so this Enumeration is needed to be initialized properly - * in its Enum<E>::sdata::sdata() constructor, you've to - * provide. For convenience, use the ENUM_DEFINITION() macro - * for this. - */ - static bool inRange(long i) { - return (staticData.stringRep.inRange(i)); - } + /** + * returns the enumeration value hold with this + * enum. + */ + inline operator E () const { return value; } - /** - * returns the Name for this enumeration. Useful for - * error reporting. - */ - static string getEnumName() { return staticData.name; } - - /** - * gives the String represenatation of a specific - * value of this Enumeration. - */ - static string getStringFor(E e) { - return staticData.stringRep.lookup((long) e); - } - - /** - * returns the Value for a specific String. - * XXX: throw OutOfRangeException ? - */ - static E getValueFor(const string &s) { - return (E) staticData.stringRep.lookup(s.getCStr()); - } + /** + * returns the String representation for the value + * represented by this instance. + */ + string toString() const { return getStringFor(value); } + + /** + * returns the C string representation for the value + * represented by this instance. + */ + operator const char *() const { return toString().c_str(); } + + /** + * This static member returns true, if the integer value + * given fits int the range of this Enumeration. Use this + * to verify input/output. + * Fitting in the range of Enumeration here means, that + * there actually exists a String representation for it, + * so this Enumeration is needed to be initialized properly + * in its Enum<E>::sdata::sdata() constructor, you've to + * provide. For convenience, use the ENUM_DEFINITION() macro + * for this. + */ + static bool inRange(long i) { + return (staticData.stringRep.inRange(i)); + } + + /** + * returns the Name for this enumeration. Useful for + * error reporting. + */ + static string getEnumName() { return staticData.name; } + + /** + * gives the String represenatation of a specific + * value of this Enumeration. + */ + static string getStringFor(E e) { + return staticData.stringRep.lookup((long) e); + } + + /** + * returns the Value for a specific String. + * XXX: throw OutOfRangeException ? + */ + static E getValueFor(const string &s) { + return (E) staticData.stringRep.lookup(s.getCStr()); + } }; /** - * Helper macro to construct an enumeration wrapper Enum<E> for + * Helper macro to construct an enumeration wrapper Enum<E> for * a specific enum type. * * It defines the static variable holding the static @@ -237,7 +269,7 @@ public: * * usage example: * <pre> - * // declaration of enumeration; somewhere + * // declaration of enumeration; somewhere * class rfsv { * [...] * enum PSI_ERROR_CODES { E_PSI_GEN_NONE, E_PSI_GEN_FAIL, E_PSI_GEN_ARG }; @@ -260,30 +292,30 @@ public: * @author Henner Zeller */ #define ENUM_DEFINITION(EnumName, initWith) \ - /** \ +/** \ * The definition of the static variable holding the static \ * data for this Enumeration wrapper. \ */ \ - Enum<EnumName>::sdata Enum<EnumName>::staticData; \ - /** \ +Enum<EnumName>::sdata Enum<EnumName>::staticData; \ +/** \ * actual definition of the constructor for the static data. \ * This is called implicitly by the definition above. \ */ \ - Enum<EnumName>::sdata::sdata() : \ - name(#EnumName),defaultValue(initWith) +Enum<EnumName>::sdata::sdata() : \ +name(#EnumName),defaultValue(initWith) /** * Writes enumeration's string representation. */ template <typename E> inline ostream& operator << (ostream& out, const Enum<E> &e) { - return out << e.toString(); + return out << gettext(e.toString().c_str()); } -/* +#endif /* _ENUM_H_ */ + +/* * Local variables: - * c-basic-offset: 8 + * c-basic-offset: 4 * End: */ - -#endif /* _ENUM_H_ */ diff --git a/lib/Makefile.am b/lib/Makefile.am index 7e56949..505b19d 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -1,5 +1,7 @@ # $Id$ # +INCLUDES += -I$(top_srcdir)/intl + lib_LTLIBRARIES = libplp.la libplp_la_LDFLAGS = $(LIBDEBUG) -version-info $(LIBVERSION) diff --git a/lib/bufferarray.cc b/lib/bufferarray.cc index 953ec8f..65f2acf 100644 --- a/lib/bufferarray.cc +++ b/lib/bufferarray.cc @@ -1,25 +1,26 @@ -// -// PLP - An implementation of the PSION link protocol -// -// Copyright (C) 1999 Philip Proudman -// extensions Copyright (C) 2000 Fritz Elfert <felfert@to.com> -// -// 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 -// -// e-mail philip.proudman@btinternet.com - +/*-*-c++-*- + * $Id$ + * + * This file is part of plptools. + * + * Copyright (C) 1999 Philip Proudman <philip.proudman@btinternet.com> + * Copyright (C) 2000, 2001 Fritz Elfert <felfert@to.com> + * + * 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 <stream.h> #include <iomanip.h> @@ -29,136 +30,142 @@ bufferArray::bufferArray() { - len = 0; - lenAllocd = ALLOC_MIN; - buff = new bufferStore[lenAllocd]; + len = 0; + lenAllocd = ALLOC_MIN; + buff = new bufferStore[lenAllocd]; } bufferArray::bufferArray(const bufferArray & a) { - len = a.len; - lenAllocd = a.lenAllocd; - buff = new bufferStore[lenAllocd]; - for (int i = 0; i < len; i++) - buff[i] = a.buff[i]; + len = a.len; + lenAllocd = a.lenAllocd; + buff = new bufferStore[lenAllocd]; + for (int i = 0; i < len; i++) + buff[i] = a.buff[i]; } bufferArray::~bufferArray() { - delete []buff; + delete []buff; } bufferStore bufferArray:: pop() { - bufferStore ret; - if (len > 0) { - ret = buff[0]; - len--; - for (long i = 0; i < len; i++) { - buff[i] = buff[i + 1]; - } + bufferStore ret; + if (len > 0) { + ret = buff[0]; + len--; + for (long i = 0; i < len; i++) { + buff[i] = buff[i + 1]; } - return ret; + } + return ret; } void bufferArray:: append(const bufferStore & b) { - if (len == lenAllocd) { - lenAllocd += ALLOC_MIN; - bufferStore *nb = new bufferStore[lenAllocd]; - for (long i = 0; i < len; i++) { - nb[i] = buff[i]; - } - delete []buff; - buff = nb; + if (len == lenAllocd) { + lenAllocd += ALLOC_MIN; + bufferStore *nb = new bufferStore[lenAllocd]; + for (long i = 0; i < len; i++) { + nb[i] = buff[i]; } - buff[len++] = b; + delete []buff; + buff = nb; + } + buff[len++] = b; } void bufferArray:: push(const bufferStore & b) { - if (len == lenAllocd) - lenAllocd += ALLOC_MIN; - bufferStore *nb = new bufferStore[lenAllocd]; - for (long i = len; i > 0; i--) { - nb[i] = buff[i - 1]; - } - nb[0] = b; - delete[]buff; - buff = nb; - len++; + if (len == lenAllocd) + lenAllocd += ALLOC_MIN; + bufferStore *nb = new bufferStore[lenAllocd]; + for (long i = len; i > 0; i--) { + nb[i] = buff[i - 1]; + } + nb[0] = b; + delete[]buff; + buff = nb; + len++; } long bufferArray:: length(void) { - return len; + return len; } void bufferArray:: clear(void) { - len = 0; - lenAllocd = ALLOC_MIN; - delete []buff; - buff = new bufferStore[lenAllocd]; + len = 0; + lenAllocd = ALLOC_MIN; + delete []buff; + buff = new bufferStore[lenAllocd]; } bufferArray &bufferArray:: operator =(const bufferArray & a) { - delete []buff; - len = a.len; - lenAllocd = a.lenAllocd; - buff = new bufferStore[lenAllocd]; - for (int i = 0; i < len; i++) - buff[i] = a.buff[i]; - return *this; + delete []buff; + len = a.len; + lenAllocd = a.lenAllocd; + buff = new bufferStore[lenAllocd]; + for (int i = 0; i < len; i++) + buff[i] = a.buff[i]; + return *this; } bufferStore &bufferArray:: operator [](const unsigned long index) { - return buff[index]; + return buff[index]; } bufferArray bufferArray:: operator +(const bufferStore &s) { - bufferArray res = *this; - res += s; - return res; + bufferArray res = *this; + res += s; + return res; } bufferArray bufferArray:: operator +(const bufferArray &a) { - bufferArray res = *this; - res += a; - return res; + bufferArray res = *this; + res += a; + return res; } bufferArray &bufferArray:: operator +=(const bufferArray &a) { - lenAllocd += a.lenAllocd; - bufferStore *nb = new bufferStore[lenAllocd]; - for (int i = 0; i < len; i++) - nb[len + i] = buff[i]; - for (int i = 0; i < a.len; i++) - nb[len + i] = a.buff[i]; - len += a.len; - delete []buff; - buff = nb; - return *this; + lenAllocd += a.lenAllocd; + bufferStore *nb = new bufferStore[lenAllocd]; + for (int i = 0; i < len; i++) + nb[len + i] = buff[i]; + for (int i = 0; i < a.len; i++) + nb[len + i] = a.buff[i]; + len += a.len; + delete []buff; + buff = nb; + return *this; } bufferArray &bufferArray:: operator +=(const bufferStore &s) { - append(s); - return *this; + append(s); + return *this; } + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ diff --git a/lib/bufferarray.h b/lib/bufferarray.h index 358d428..59554e3 100644 --- a/lib/bufferarray.h +++ b/lib/bufferarray.h @@ -1,5 +1,28 @@ -#ifndef _bufferarray_h -#define _bufferarray_h +/*-*-c++-*- + * $Id$ + * + * This file is part of plptools. + * + * Copyright (C) 1999 Philip Proudman <philip.proudman@btinternet.com> + * Copyright (C) 1999-2001 Fritz Elfert <felfert@to.com> + * + * 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 _BUFFERARRAY_H_ +#define _BUFFERARRAY_H_ #ifdef HAVE_CONFIG_H #include <config.h> @@ -11,138 +34,144 @@ class bufferStore; */ class bufferArray { public: - /** - * constructs a new bufferArray. - * A minimum of @ref ALLOC_MIN - * elements is allocated. - */ - bufferArray(); - - /** - * Constructs a new bufferArray. - * - * @param a The initial contents for this array. - */ - bufferArray(const bufferArray &a); - - /** - * Destroys the bufferArray. - */ - ~bufferArray(); - - /** - * Copys the bufferArray. - */ - bufferArray &operator =(const bufferArray &a); - - /** - * Checks if this bufferArray is empty. - * - * @return true if the bufferArray is empty. - */ - bool empty() const; - - /** - * Retrieves the bufferStore at given index. - * - * @return The bufferStore at index. - */ - bufferStore &operator [](const unsigned long index); - - /** - * Appends a bufferStore to a bufferArray. - * - * @param s The bufferStore to be appended. - * - * @returns A new bufferArray with bufferStore appended to. - */ - bufferArray operator +(const bufferStore &s); - - /** - * Concatenates two bufferArrays. - * - * @param a The bufferArray to be appended. - * - * @returns A new bufferArray consisting with a appended. - */ - bufferArray operator +(const bufferArray &a); - - /** - * Appends a bufferStore to current instance. - * - * @param s The bufferStore to append. - * - * @returns A reference to the current instance with s appended. - */ - bufferArray &operator +=(const bufferStore &s); - - /** - * Appends a bufferArray to current instance. - * - * @param a The bufferArray to append. - * - * @returns A reference to the current instance with a appended. - */ - bufferArray &operator +=(const bufferArray &a); - - /** - * Removes the first bufferStore. - * - * @return The removed bufferStore. - */ - bufferStore pop(void); - - /** - * Inserts a bufferStore at index 0. - * - * @param b The bufferStore to be inserted. - */ - void push(const bufferStore& b); - - /** - * Appends a bufferStore. - * - * @param b The bufferStore to be appended. - */ - void append(const bufferStore& b); - - /** - * Evaluates the current length. - * - * @return The current number of bufferStores - */ - long length(void); - - /** - * Empties the bufferArray. - */ - void clear(void); + /** + * constructs a new bufferArray. + * A minimum of @ref ALLOC_MIN + * elements is allocated. + */ + bufferArray(); + + /** + * Constructs a new bufferArray. + * + * @param a The initial contents for this array. + */ + bufferArray(const bufferArray &a); + + /** + * Destroys the bufferArray. + */ + ~bufferArray(); + + /** + * Copys the bufferArray. + */ + bufferArray &operator =(const bufferArray &a); + + /** + * Checks if this bufferArray is empty. + * + * @return true if the bufferArray is empty. + */ + bool empty() const; + + /** + * Retrieves the bufferStore at given index. + * + * @return The bufferStore at index. + */ + bufferStore &operator [](const unsigned long index); + + /** + * Appends a bufferStore to a bufferArray. + * + * @param s The bufferStore to be appended. + * + * @returns A new bufferArray with bufferStore appended to. + */ + bufferArray operator +(const bufferStore &s); + + /** + * Concatenates two bufferArrays. + * + * @param a The bufferArray to be appended. + * + * @returns A new bufferArray consisting with a appended. + */ + bufferArray operator +(const bufferArray &a); + + /** + * Appends a bufferStore to current instance. + * + * @param s The bufferStore to append. + * + * @returns A reference to the current instance with s appended. + */ + bufferArray &operator +=(const bufferStore &s); + + /** + * Appends a bufferArray to current instance. + * + * @param a The bufferArray to append. + * + * @returns A reference to the current instance with a appended. + */ + bufferArray &operator +=(const bufferArray &a); + + /** + * Removes the first bufferStore. + * + * @return The removed bufferStore. + */ + bufferStore pop(void); + + /** + * Inserts a bufferStore at index 0. + * + * @param b The bufferStore to be inserted. + */ + void push(const bufferStore& b); + + /** + * Appends a bufferStore. + * + * @param b The bufferStore to be appended. + */ + void append(const bufferStore& b); + + /** + * Evaluates the current length. + * + * @return The current number of bufferStores + */ + long length(void); + + /** + * Empties the bufferArray. + */ + void clear(void); private: - /** - * Minimum number of bufferStores to - * allocate. - */ - static const long ALLOC_MIN = 5; - - /** - * The current number of bufferStores in - * this bufferArray. - */ - long len; - - /** - * The current number of bufferStores - * allocated. - */ - long lenAllocd; - - /** - * The content. - */ - bufferStore* buff; + /** + * Minimum number of bufferStores to + * allocate. + */ + static const long ALLOC_MIN = 5; + + /** + * The current number of bufferStores in + * this bufferArray. + */ + long len; + + /** + * The current number of bufferStores + * allocated. + */ + long lenAllocd; + + /** + * The content. + */ + bufferStore* buff; }; inline bool bufferArray::empty() const { return len == 0; } #endif + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ diff --git a/lib/bufferstore.cc b/lib/bufferstore.cc index 35bea26..8d7ed45 100644 --- a/lib/bufferstore.cc +++ b/lib/bufferstore.cc @@ -1,27 +1,30 @@ -// -// PLP - An implementation of the PSION link protocol -// -// Copyright (C) 1999 Philip Proudman -// -// 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 -// -// e-mail philip.proudman@btinternet.com - -#include <stream.h> -// That should be iostream.h, but it won't build on Sun WorkShop C++ 5.0 -#include <iomanip.h> +/*-*-c++-*- + * $Id$ + * + * This file is part of plptools. + * + * Copyright (C) 1999 Philip Proudman <philip.proudman@btinternet.com> + * Copyright (C) 2000, 2001 Fritz Elfert <felfert@to.com> + * + * 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 <stream.h> +// Should be iostream.h, but won't build on Sun WorkShop C++ 5.0 +#include <iomanip> #include <stdlib.h> #include <string.h> #include <ctype.h> @@ -29,158 +32,164 @@ #include "bufferstore.h" bufferStore::bufferStore() { - lenAllocd = 0; - buff = 0L; - len = 0; - start = 0; + lenAllocd = 0; + buff = 0L; + len = 0; + start = 0; } bufferStore::bufferStore(const bufferStore &a) { - lenAllocd = (a.getLen() > MIN_LEN) ? a.getLen() : MIN_LEN; - buff = (unsigned char *)malloc(lenAllocd); - len = a.getLen(); - memcpy(buff, a.getString(0), len); - start = 0; + lenAllocd = (a.getLen() > MIN_LEN) ? a.getLen() : MIN_LEN; + buff = (unsigned char *)malloc(lenAllocd); + len = a.getLen(); + memcpy(buff, a.getString(0), len); + start = 0; } bufferStore::bufferStore(const unsigned char *_buff, long _len) { - lenAllocd = (_len > MIN_LEN) ? _len : MIN_LEN; - buff = (unsigned char *)malloc(lenAllocd); - len = _len; - memcpy(buff, _buff, len); - start = 0; + lenAllocd = (_len > MIN_LEN) ? _len : MIN_LEN; + buff = (unsigned char *)malloc(lenAllocd); + len = _len; + memcpy(buff, _buff, len); + start = 0; } bufferStore &bufferStore::operator =(const bufferStore &a) { - checkAllocd(a.getLen()); - len = a.getLen(); - memcpy(buff, a.getString(0), len); - start = 0; - return *this; + checkAllocd(a.getLen()); + len = a.getLen(); + memcpy(buff, a.getString(0), len); + start = 0; + return *this; } void bufferStore::init() { - start = 0; - len = 0; + start = 0; + len = 0; } void bufferStore::init(const unsigned char *_buff, long _len) { - checkAllocd(_len); - start = 0; - len = _len; - memcpy(buff, _buff, len); + checkAllocd(_len); + start = 0; + len = _len; + memcpy(buff, _buff, len); } bufferStore::~bufferStore() { - if (buff != 0L) - free(buff); + if (buff != 0L) + free(buff); } unsigned long bufferStore::getLen() const { - return (start > len) ? 0 : len - start; + return (start > len) ? 0 : len - start; } unsigned char bufferStore::getByte(long pos) const { - return buff[pos+start]; + return buff[pos+start]; } u_int16_t bufferStore::getWord(long pos) const { - return buff[pos+start] + (buff[pos+start+1] << 8); + return buff[pos+start] + (buff[pos+start+1] << 8); } u_int32_t bufferStore::getDWord(long pos) const { - return buff[pos+start] + - (buff[pos+start+1] << 8) + - (buff[pos+start+2] << 16) + - (buff[pos+start+3] << 24); + return buff[pos+start] + + (buff[pos+start+1] << 8) + + (buff[pos+start+2] << 16) + + (buff[pos+start+3] << 24); } const char * bufferStore::getString(long pos) const { - return (const char *)buff + pos + start; + return (const char *)buff + pos + start; } ostream &operator<<(ostream &s, const bufferStore &m) { - // save stream flags - ostream::fmtflags old = s.flags(); + // save stream flags + ostream::fmtflags old = s.flags(); - for (int i = m.start; i < m.len; i++) - s << hex << setw(2) << setfill('0') << (int)m.buff[i] << " "; + for (int i = m.start; i < m.len; i++) + s << hex << setw(2) << setfill('0') << (int)m.buff[i] << " "; - // restore stream flags - s.flags(old); - s << "("; + // restore stream flags + s.flags(old); + s << "("; - for (int i = m.start; i < m.len; i++) { - unsigned char c = m.buff[i]; - s << (unsigned char)(isprint(c) ? c : '.'); - } + for (int i = m.start; i < m.len; i++) { + unsigned char c = m.buff[i]; + s << (unsigned char)(isprint(c) ? c : '.'); + } - return s << ")"; + return s << ")"; } void bufferStore::discardFirstBytes(int n) { - start += n; - if (start > len) start = len; + start += n; + if (start > len) start = len; } void bufferStore::checkAllocd(long newLen) { - if (newLen >= lenAllocd) { - do { - lenAllocd = (lenAllocd < MIN_LEN) ? MIN_LEN : (lenAllocd * 2); - } while (newLen >= lenAllocd); - buff = (unsigned char *)realloc(buff, lenAllocd); - } + if (newLen >= lenAllocd) { + do { + lenAllocd = (lenAllocd < MIN_LEN) ? MIN_LEN : (lenAllocd * 2); + } while (newLen >= lenAllocd); + buff = (unsigned char *)realloc(buff, lenAllocd); + } } void bufferStore::addByte(unsigned char cc) { - checkAllocd(len + 1); - buff[len++] = cc; + checkAllocd(len + 1); + buff[len++] = cc; } void bufferStore::addString(const char *s) { - int l = strlen(s); - checkAllocd(len + l); - memcpy(&buff[len], s, l); - len += l; + int l = strlen(s); + checkAllocd(len + l); + memcpy(&buff[len], s, l); + len += l; } void bufferStore::addStringT(const char *s) { - addString(s); - addByte(0); + addString(s); + addByte(0); } void bufferStore::addBytes(const unsigned char *s, int l) { - checkAllocd(len + l); - memcpy(&buff[len], s, l); - len += l; + checkAllocd(len + l); + memcpy(&buff[len], s, l); + len += l; } void bufferStore::addBuff(const bufferStore &s, long maxLen) { - long l = s.getLen(); - checkAllocd(len + l); - if ((maxLen >= 0) && (maxLen < l)) - l = maxLen; - if (l > 0) { - memcpy(&buff[len], s.getString(0), l); - len += l; - } + long l = s.getLen(); + checkAllocd(len + l); + if ((maxLen >= 0) && (maxLen < l)) + l = maxLen; + if (l > 0) { + memcpy(&buff[len], s.getString(0), l); + len += l; + } } void bufferStore::addWord(int a) { - checkAllocd(len + 2); - buff[len++] = a & 0xff; - buff[len++] = (a>>8) & 0xff; + checkAllocd(len + 2); + buff[len++] = a & 0xff; + buff[len++] = (a>>8) & 0xff; } void bufferStore::addDWord(long a) { - checkAllocd(len + 4); - buff[len++] = a & 0xff; - buff[len++] = (a>>8) & 0xff; - buff[len++] = (a>>16) & 0xff; - buff[len++] = (a>>24) & 0xff; + checkAllocd(len + 4); + buff[len++] = a & 0xff; + buff[len++] = (a>>8) & 0xff; + buff[len++] = (a>>16) & 0xff; + buff[len++] = (a>>24) & 0xff; } void bufferStore::truncate(long newLen) { - if (newLen < len) - len = newLen; + if (newLen < len) + len = newLen; } + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ diff --git a/lib/bufferstore.h b/lib/bufferstore.h index a018e81..3a69159 100644 --- a/lib/bufferstore.h +++ b/lib/bufferstore.h @@ -1,5 +1,28 @@ -#ifndef _bufferstore_h -#define _bufferstore_h +/*-*-c++-*- + * $Id$ + * + * This file is part of plptools. + * + * Copyright (C) 1999 Philip Proudman <philip.proudman@btinternet.com> + * Copyright (C) 1999-2001 Fritz Elfert <felfert@to.com> + * + * 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 _BUFFERSTORE_H_ +#define _BUFFERSTORE_H_ #include <sys/types.h> @@ -13,208 +36,214 @@ class ostream; */ class bufferStore { public: - /** - * Constructs a new bufferStore. - */ - bufferStore(); - - /** - * Constructs a new bufferStore and - * initializes its content. - * - * @param buf Pointer to data for initialization. - * @param len Length of data for initialization. - */ - bufferStore(const unsigned char *, long); - - /** - * Destroys a bufferStore instance. - */ - ~bufferStore(); - - /** - * Constructs a new bufferStore and - * initializes its content. - * - * @param b A bufferStore, whose content is - * used for initialization. - */ - bufferStore(const bufferStore &); - - /** - * Copies a bufferStore. - */ - bufferStore &operator =(const bufferStore &); - - /** - * Retrieves the length of a bufferStore. - * - * @returns The current length of the contents - * in bytes. - */ - unsigned long getLen() const; - - /** - * Retrieves the byte at index <em>pos</em>. - * - * @param pos The index of the byte to retrieve. - * - * @returns The value of the byte at index <em>pos</em> - */ - unsigned char getByte(long pos = 0) const; - - /** - * Retrieves the word at index <em>pos</em>. - * - * @param pos The index of the word to retrieve. - * - * @returns The value of the word at index <em>pos</em> - */ - u_int16_t getWord(long pos = 0) const; - - /** - * Retrieves the dword at index <em>pos</em>. - * - * @param pos The index of the dword to retrieve. - * - * @returns The value of the dword at index <em>pos</em> - */ - u_int32_t getDWord(long pos = 0) const; - - /** - * Retrieves the characters at index <em>pos</em>. - * - * @param pos The index of the characters to retrieve. - * - * @returns A pointer to characters at index <em>pos</em> - */ - const char * getString(long pos = 0) const; - - /** - * Removes bytes from the start of the buffer. - * - * @param len Number of bytes to remove. - */ - void discardFirstBytes(int len = 0); - - /** - * Prints a dump of the content. - * - * Mainly used for debugging purposes. - * - * @param s The stream to write to. - * @param b The bufferStore do be dumped. - * - * @returns The stream. - */ - friend ostream &operator<<(ostream &, const bufferStore &); - - /** - * Tests if the bufferStore is empty. - * - * @returns true, if the bufferStore is empty. - * false, if it contains data. - */ - bool empty() const; - - /** - * Initializes the bufferStore. - * - * All data is removed, the length is - * reset to 0. - */ - void init(); - - /** - * Initializes the bufferStore with - * a given data. - * - * @param buf Pointer to data to initialize from. - * @param len Length of data. - */ - void init(const unsigned char * buf, long len); - - /** - * Appends a byte to the content of this instance. - * - * @param c The byte to append. - */ - void addByte(unsigned char c); - - /** - * Appends a word to the content of this instance. - * - * @param w The word to append. - */ - void addWord(int); - - /** - * Appends a dword to the content of this instance. - * - * @param dw The dword to append. - */ - void addDWord(long dw); - - /** - * Appends a string to the content of this instance. - * - * The trailing zero byte is <em>not</em> copied - * to the content. - * - * @param s The string to append. - */ - void addString(const char *s); - - /** - * Appends a string to the content of this instance. - * - * The trailing zero byte <em>is</em> copied - * to the content. - * - * @param s The string to append. - */ - void addStringT(const char *s); - - /** - * Appends data to the content of this instance. - * - * @param buf The data to append. - * @param len Length of data. - */ - void addBytes(const unsigned char *buf, int len); - - /** - * Appends data to the content of this instance. - * - * @param b The bufferStore whose content to append. - * @param maxLen Length of content to append. If - * @p maxLen is less than 0 or greater than - * the current length of @p b , then the - * whole content of @p b is appended. - */ - void addBuff(const bufferStore &b, long maxLen = -1); + /** + * Constructs a new bufferStore. + */ + bufferStore(); + + /** + * Constructs a new bufferStore and + * initializes its content. + * + * @param buf Pointer to data for initialization. + * @param len Length of data for initialization. + */ + bufferStore(const unsigned char *, long); + + /** + * Destroys a bufferStore instance. + */ + ~bufferStore(); + + /** + * Constructs a new bufferStore and + * initializes its content. + * + * @param b A bufferStore, whose content is + * used for initialization. + */ + bufferStore(const bufferStore &); + + /** + * Copies a bufferStore. + */ + bufferStore &operator =(const bufferStore &); + + /** + * Retrieves the length of a bufferStore. + * + * @returns The current length of the contents + * in bytes. + */ + unsigned long getLen() const; + + /** + * Retrieves the byte at index <em>pos</em>. + * + * @param pos The index of the byte to retrieve. + * + * @returns The value of the byte at index <em>pos</em> + */ + unsigned char getByte(long pos = 0) const; + + /** + * Retrieves the word at index <em>pos</em>. + * + * @param pos The index of the word to retrieve. + * + * @returns The value of the word at index <em>pos</em> + */ + u_int16_t getWord(long pos = 0) const; + + /** + * Retrieves the dword at index <em>pos</em>. + * + * @param pos The index of the dword to retrieve. + * + * @returns The value of the dword at index <em>pos</em> + */ + u_int32_t getDWord(long pos = 0) const; + + /** + * Retrieves the characters at index <em>pos</em>. + * + * @param pos The index of the characters to retrieve. + * + * @returns A pointer to characters at index <em>pos</em> + */ + const char * getString(long pos = 0) const; + + /** + * Removes bytes from the start of the buffer. + * + * @param len Number of bytes to remove. + */ + void discardFirstBytes(int len = 0); + + /** + * Prints a dump of the content. + * + * Mainly used for debugging purposes. + * + * @param s The stream to write to. + * @param b The bufferStore do be dumped. + * + * @returns The stream. + */ + friend ostream &operator<<(ostream &, const bufferStore &); + + /** + * Tests if the bufferStore is empty. + * + * @returns true, if the bufferStore is empty. + * false, if it contains data. + */ + bool empty() const; + + /** + * Initializes the bufferStore. + * + * All data is removed, the length is + * reset to 0. + */ + void init(); + + /** + * Initializes the bufferStore with + * a given data. + * + * @param buf Pointer to data to initialize from. + * @param len Length of data. + */ + void init(const unsigned char * buf, long len); + + /** + * Appends a byte to the content of this instance. + * + * @param c The byte to append. + */ + void addByte(unsigned char c); + + /** + * Appends a word to the content of this instance. + * + * @param w The word to append. + */ + void addWord(int); + + /** + * Appends a dword to the content of this instance. + * + * @param dw The dword to append. + */ + void addDWord(long dw); + + /** + * Appends a string to the content of this instance. + * + * The trailing zero byte is <em>not</em> copied + * to the content. + * + * @param s The string to append. + */ + void addString(const char *s); + + /** + * Appends a string to the content of this instance. + * + * The trailing zero byte <em>is</em> copied + * to the content. + * + * @param s The string to append. + */ + void addStringT(const char *s); + + /** + * Appends data to the content of this instance. + * + * @param buf The data to append. + * @param len Length of data. + */ + void addBytes(const unsigned char *buf, int len); + + /** + * Appends data to the content of this instance. + * + * @param b The bufferStore whose content to append. + * @param maxLen Length of content to append. If + * @p maxLen is less than 0 or greater than + * the current length of @p b , then the + * whole content of @p b is appended. + */ + void addBuff(const bufferStore &b, long maxLen = -1); - /** - * Truncates the buffer. - * If the buffer is smaller, does nothing. - * - * @param newLen The new length of the buffer. - */ - void truncate(long newLen); + /** + * Truncates the buffer. + * If the buffer is smaller, does nothing. + * + * @param newLen The new length of the buffer. + */ + void truncate(long newLen); private: - void checkAllocd(long newLen); + void checkAllocd(long newLen); - long len; - long lenAllocd; - long start; - unsigned char * buff; + long len; + long lenAllocd; + long start; + unsigned char * buff; - enum c { MIN_LEN = 300 }; + enum c { MIN_LEN = 300 }; }; inline bool bufferStore::empty() const { - return (len - start) == 0; + return (len - start) == 0; } #endif + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ diff --git a/lib/iowatch.cc b/lib/iowatch.cc index e3c86fc..50c03a6 100644 --- a/lib/iowatch.cc +++ b/lib/iowatch.cc @@ -1,24 +1,26 @@ -// -// PLP - An implementation of the PSION link protocol -// -// Copyright (C) 1999 Philip Proudman -// -// 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 -// -// e-mail philip.proudman@btinternet.com - +/*-*-c++-*- + * $Id$ + * + * This file is part of plptools. + * + * Copyright (C) 1999 Philip Proudman <philip.proudman@btinternet.com> + * Copyright (C) 2000, 2001 Fritz Elfert <felfert@to.com> + * + * 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 <unistd.h> #include <stdio.h> #include <sys/time.h> @@ -29,46 +31,52 @@ #include "iowatch.h" IOWatch::IOWatch() { - num = 0; - io = new int [FD_SETSIZE]; + num = 0; + io = new int [FD_SETSIZE]; } IOWatch::~IOWatch() { - delete [] io; + delete [] io; } void IOWatch::addIO(const int fd) { - int pos; - for (pos = 0; pos < num && fd < io[pos]; pos++); - if (io[pos] == fd) - return; - for (int i = num; i > pos; i--) - io[i] = io[i-1]; - io[pos] = fd; - num++; + int pos; + for (pos = 0; pos < num && fd < io[pos]; pos++); + if (io[pos] == fd) + return; + for (int i = num; i > pos; i--) + io[i] = io[i-1]; + io[pos] = fd; + num++; } void IOWatch::remIO(const int fd) { - int pos; - for (pos = 0; pos < num && fd != io[pos]; pos++); - if (pos != num) { - num--; - for (int i = pos; i <num; i++) io[i] = io[i+1]; - } + int pos; + for (pos = 0; pos < num && fd != io[pos]; pos++); + if (pos != num) { + num--; + for (int i = pos; i <num; i++) io[i] = io[i+1]; + } } bool IOWatch::watch(const long secs, const long usecs) { - if (num > 0) { - fd_set iop; - FD_ZERO(&iop); - for (int i = 0; i < num; i++) - FD_SET(io[i], &iop); - struct timeval t; - t.tv_usec = usecs; - t.tv_sec = secs; - return (select(io[0]+1, &iop, NULL, NULL, &t) > 0); - } - sleep(secs); - usleep(usecs); - return false; + if (num > 0) { + fd_set iop; + FD_ZERO(&iop); + for (int i = 0; i < num; i++) + FD_SET(io[i], &iop); + struct timeval t; + t.tv_usec = usecs; + t.tv_sec = secs; + return (select(io[0]+1, &iop, NULL, NULL, &t) > 0); + } + sleep(secs); + usleep(usecs); + return false; } + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ diff --git a/lib/iowatch.h b/lib/iowatch.h index 12abb1f..0d025f3 100644 --- a/lib/iowatch.h +++ b/lib/iowatch.h @@ -1,5 +1,28 @@ -#ifndef _iowatch_h -#define _iowatch_h +/*-*-c++-*- + * $Id$ + * + * This file is part of plptools. + * + * Copyright (C) 1999 Philip Proudman <philip.proudman@btinternet.com> + * Copyright (C) 1999-2001 Fritz Elfert <felfert@to.com> + * + * 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 _IOWATCH_H_ +#define _IOWATCH_H_ /** * A simple wrapper for select() @@ -12,46 +35,52 @@ */ class IOWatch { public: - /** - * Creates a new instance. - */ - IOWatch(); + /** + * Creates a new instance. + */ + IOWatch(); - /** - * Destroys an instance. - */ - ~IOWatch(); + /** + * Destroys an instance. + */ + ~IOWatch(); - /** - * Adds a file descriptor to - * the set of descriptors. - * - * @param fd The file descriptor to add. - */ - void addIO(const int fd); + /** + * Adds a file descriptor to + * the set of descriptors. + * + * @param fd The file descriptor to add. + */ + void addIO(const int fd); - /** - * Removes a file descriptor from the - * set of descriptors. - * - * @param fd The file descriptor to remove. - */ - void remIO(const int fd); + /** + * Removes a file descriptor from the + * set of descriptors. + * + * @param fd The file descriptor to remove. + */ + void remIO(const int fd); - /** - * Performs a select() call. - * - * @param secs Number of seconds to wait. - * @param usecs Number of microseconds to wait. - * - * @return true, if any of the descriptors is - * readable. - */ - bool watch(const long secs, const long usecs); + /** + * Performs a select() call. + * + * @param secs Number of seconds to wait. + * @param usecs Number of microseconds to wait. + * + * @return true, if any of the descriptors is + * readable. + */ + bool watch(const long secs, const long usecs); private: - int num; - int *io; + int num; + int *io; }; #endif + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ @@ -1,23 +1,52 @@ +/*-*-c++-*- + * $Id$ + * + * This file is part of plptools. + * + * Copyright (C) 1999 Philip Proudman <philip.proudman@btinternet.com> + * Copyright (C) 1999-2001 Fritz Elfert <felfert@to.com> + * + * 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 "log.h" logbuf::logbuf(int _level) { - ptr = buf; - len = 0; - level = _level; + ptr = buf; + len = 0; + level = _level; } int logbuf::overflow(int c) { - if (c == '\n') { - *ptr++ = '\n'; - *ptr = '\0'; - syslog(level, buf); - ptr = buf; - len = 0; - return 0; - } - if ((len + 2) >= sizeof(buf)) - return EOF; - *ptr++ = c; - len++; + if (c == '\n') { + *ptr++ = '\n'; + *ptr = '\0'; + syslog(level, buf); + ptr = buf; + len = 0; return 0; + } + if ((len + 2) >= sizeof(buf)) + return EOF; + *ptr++ = c; + len++; + return 0; } + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ @@ -1,8 +1,28 @@ -/* $Id$ +/*-*-c++-*- + * $Id$ + * + * This file is part of plptools. + * + * Copyright (C) 1999 Philip Proudman <philip.proudman@btinternet.com> + * Copyright (C) 1999-2001 Fritz Elfert <felfert@to.com> + * + * 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 _log_h_ -#define _log_h_ +#ifndef _LOG_H_ +#define _LOG_H_ #include <ostream.h> #include <syslog.h> @@ -27,47 +47,53 @@ * </PRE> */ class logbuf : public streambuf { - public: +public: - /** - * Constructs a new instance. - * - * @param level The log level for this instance. - * see syslog(3) for symbolic names to use. - */ - logbuf(int level); + /** + * Constructs a new instance. + * + * @param level The log level for this instance. + * see syslog(3) for symbolic names to use. + */ + logbuf(int level); - /** - * Called by the associated - * ostream to write a character. - * Stores the character in a buffer - * and calls syslog(level, buffer) - * whenever a LF is seen. - */ - int overflow(int c = EOF); + /** + * Called by the associated + * ostream to write a character. + * Stores the character in a buffer + * and calls syslog(level, buffer) + * whenever a LF is seen. + */ + int overflow(int c = EOF); - private: +private: - /** - * Pointer to next char in buffer. - */ - char *ptr; + /** + * Pointer to next char in buffer. + */ + char *ptr; - /** - * Current length of buffer. - */ - unsigned int len; + /** + * Current length of buffer. + */ + unsigned int len; - /** - * The log level to use with syslog. - */ - int level; + /** + * The log level to use with syslog. + */ + int level; - /** - * The internal buffer for holding - * messages. - */ - char buf[1024]; + /** + * The internal buffer for holding + * messages. + */ + char buf[1024]; }; #endif + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ diff --git a/lib/plpdirent.cc b/lib/plpdirent.cc index 9695480..d78260c 100644 --- a/lib/plpdirent.cc +++ b/lib/plpdirent.cc @@ -1,87 +1,110 @@ +/*-*-c++-*- + * $Id$ + * + * This file is part of plptools. + * + * Copyright (C) 1999 Philip Proudman <philip.proudman@btinternet.com> + * Copyright (C) 1999-2001 Fritz Elfert <felfert@to.com> + * + * 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 <plpdirent.h> #include <stream.h> #include <iomanip> PlpUID::PlpUID() { - memset(uid, 0, sizeof(uid)); + memset(uid, 0, sizeof(uid)); } PlpUID::PlpUID(const long u1, const long u2, const long u3) { - uid[0] = u1; uid[1] = u2; uid[2] = u3; + uid[0] = u1; uid[1] = u2; uid[2] = u3; } long PlpUID:: operator[](int idx) { - assert ((idx > -1) && (idx < 3)); - return uid[idx]; + assert ((idx > -1) && (idx < 3)); + return uid[idx]; } PlpDirent::PlpDirent(const PlpDirent &e) { - size = e.size; - attr = e.attr; - time = e.time; - UID = e.UID; - name = e.name; - attrstr = e.attrstr; + size = e.size; + attr = e.attr; + time = e.time; + UID = e.UID; + name = e.name; + attrstr = e.attrstr; } long PlpDirent:: getSize() { - return size; + return size; } long PlpDirent:: getAttr() { - return attr; + return attr; } long PlpDirent:: getUID(int uididx) { - if ((uididx >= 0) && (uididx < 4)) - return UID[uididx]; - return 0; + if ((uididx >= 0) && (uididx < 4)) + return UID[uididx]; + return 0; } PlpUID &PlpDirent:: getUID() { - return UID; + return UID; } const char *PlpDirent:: getName() { - return name.c_str(); + return name.c_str(); } PsiTime PlpDirent:: getPsiTime() { - return time; + return time; } void PlpDirent:: setName(const char *str) { - name = str; + name = str; } PlpDirent &PlpDirent:: operator=(const PlpDirent &e) { - size = e.size; - attr = e.attr; - time = e.time; - UID = e.UID; - name = e.name; - attrstr = e.attrstr; - return *this; + size = e.size; + attr = e.attr; + time = e.time; + UID = e.UID; + name = e.name; + attrstr = e.attrstr; + return *this; } ostream & operator<<(ostream &o, const PlpDirent &e) { - ostream::fmtflags old = o.flags(); + ostream::fmtflags old = o.flags(); - o << e.attrstr << " " << dec << setw(10) - << setfill(' ') << e.size << " " << e.time - << " " << e.name; - o.flags(old); - return o; + o << e.attrstr << " " << dec << setw(10) + << setfill(' ') << e.size << " " << e.time + << " " << e.name; + o.flags(old); + return o; } PlpDrive::PlpDrive() { @@ -92,132 +115,138 @@ PlpDrive::PlpDrive(const PlpDrive &other) { void PlpDrive:: setMediaType(u_int32_t type) { - mediatype = type; + mediatype = type; } void PlpDrive:: setDriveAttribute(u_int32_t attr) { - driveattr = attr; + driveattr = attr; } void PlpDrive:: setMediaAttribute(u_int32_t attr) { - mediaattr = attr; + mediaattr = attr; } void PlpDrive:: setUID(u_int32_t attr) { - uid = attr; + uid = attr; } void PlpDrive:: setSize(u_int32_t sizeLo, u_int32_t sizeHi) { - size = ((unsigned long long)sizeHi << 32) + sizeLo; + 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; + space = ((unsigned long long)spaceHi << 32) + spaceLo; } void PlpDrive:: setName(char drive, const char * const volname) { - drivechar = drive; - name = ""; - name += volname; + drivechar = drive; + name = ""; + name += volname; } u_int32_t PlpDrive:: getMediaType() { - return mediatype; + return mediatype; } static const char * const media_types[] = { - "Not present", - "Unknown", - "Floppy", - "Disk", - "CD-ROM", - "RAM", - "Flash Disk", - "ROM", - "Remote", + N_("Not present"), + N_("Unknown"), + N_("Floppy"), + N_("Disk"), + N_("CD-ROM"), + N_("RAM"), + N_("Flash Disk"), + N_("ROM"), + N_("Remote"), }; void PlpDrive:: getMediaType(string &ret) { - ret = media_types[mediatype]; + ret = media_types[mediatype]; } u_int32_t PlpDrive:: getDriveAttribute() { - return driveattr; + return driveattr; } static void appendWithDelim(string &s1, const char * const s2) { - if (!s1.empty()) - s1 += ','; - s1 += 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"); + 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; + return mediaattr; } void PlpDrive:: getMediaAttribute(string &ret) { - 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"); + 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; + return uid; } u_int64_t PlpDrive:: getSize() { - return size; + return size; } u_int64_t PlpDrive:: getSpace() { - return space; + return space; } string PlpDrive:: getName() { - return name; + return name; } char PlpDrive:: getDrivechar() { - return drivechar; + return drivechar; } + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ diff --git a/lib/plpdirent.h b/lib/plpdirent.h index c567a9b..3c9fb40 100644 --- a/lib/plpdirent.h +++ b/lib/plpdirent.h @@ -1,5 +1,27 @@ -#ifndef _PLP_DIRENT_H_ -#define _PLP_DIRENT_H_ +/*-*-c++-*- + * $Id$ + * + * This file is part of plptools. + * + * Copyright (C) 1999-2001 Fritz Elfert <felfert@to.com> + * + * 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 _PLPDIRENT_H_ +#define _PLPDIRENT_H_ #include <string> #include "psitime.h" @@ -16,33 +38,33 @@ */ class PlpUID { - friend inline bool operator<(const PlpUID &u1, const PlpUID &u2); + friend inline bool operator<(const PlpUID &u1, const PlpUID &u2); public: - /** - * Default constructor. - */ - PlpUID(); - - /** - * Constructor. - * Create an instance, presetting all thre uid values. - */ - PlpUID(const long u1, const long u2, const long u3); - - /** - * Retrieve a UID value. - * - * @param idx The index of the desired UID. Range must be (0..2), - * otherwise an assertion is triggered. - */ - long operator[](int idx); + /** + * Default constructor. + */ + PlpUID(); + + /** + * Constructor. + * Create an instance, presetting all thre uid values. + */ + PlpUID(const long u1, const long u2, const long u3); + + /** + * Retrieve a UID value. + * + * @param idx The index of the desired UID. Range must be (0..2), + * otherwise an assertion is triggered. + */ + long operator[](int idx); private: - long uid[3]; + long uid[3]; }; inline bool operator<(const PlpUID &u1, const PlpUID &u2) { - return (memcmp(u1.uid, u2.uid, sizeof(u1.uid)) < 0); + return (memcmp(u1.uid, u2.uid, sizeof(u1.uid)) < 0); } /** @@ -54,108 +76,108 @@ inline bool operator<(const PlpUID &u1, const PlpUID &u2) { * @author Fritz Elfert <felfert@to.com> */ class PlpDirent { - friend class rfsv32; - friend class rfsv16; + friend class rfsv32; + friend class rfsv16; public: - /** - * Default constructor - */ - PlpDirent() : size(0), attr(0), name(""), time(0L), attrstr("") { }; - - /** - * A copy constructor. - * Mainly used by STL container classes. - * - * @param d The object to be used as initializer. - */ - PlpDirent(const PlpDirent &d); - - /** - * Default destructor. - */ - ~PlpDirent() {}; - - /** - * Retrieves the file size of a directory entry. - * - * @returns The file size in bytes. - */ - long getSize(); - - /** - * Retrieves the file attributes of a directory entry. - * - * @returns The generic attributes ( @ref rfsv:file_attribs ). - */ - long getAttr(); - - /** - * Retrieves the UIDs of a directory entry. - * This method returns always 0 with a Series3. - * - * @param uididx The index of the UID to retrieve (0 .. 2). - * - * @returns The selected UID or 0 if the index is out of range. - */ - long getUID(int uididx); - - /** - * Retrieves the @ref PlpUID object of a directory entry. - * - * @returns The PlpUID object. - */ - PlpUID &getUID(); - - /** - * Retrieve the file name of a directory entry. - * - * @returns The name of the file. - */ - const char *getName(); - - /** - * Retrieve the modification time of a directory entry. - * - * @returns A @ref PsiTime object, representing the time. - */ - PsiTime getPsiTime(); - - /** - * Set the file name of a directory entry. - * This is currently used in plpbackup only for - * changing the name to the full path. It does NOT - * change the name of the corresponding file on - * the Psion. - * - * @param str The new name of the file. - */ - void setName(const char *str); - - /** - * Assignment operator - * Mainly used by STL container classes. - * - * @param e The new value to assign. - * - * @returns The modified object. - */ - PlpDirent &operator=(const PlpDirent &e); - - /** - * Prints the object contents. - * The output is in human readable similar to the - * output of a "ls" command. - */ - friend ostream &operator<<(ostream &o, const PlpDirent &e); + /** + * Default constructor + */ + PlpDirent() : size(0), attr(0), name(""), time(0L), attrstr("") { }; + + /** + * A copy constructor. + * Mainly used by STL container classes. + * + * @param d The object to be used as initializer. + */ + PlpDirent(const PlpDirent &d); + + /** + * Default destructor. + */ + ~PlpDirent() {}; + + /** + * Retrieves the file size of a directory entry. + * + * @returns The file size in bytes. + */ + long getSize(); + + /** + * Retrieves the file attributes of a directory entry. + * + * @returns The generic attributes ( @ref rfsv:file_attribs ). + */ + long getAttr(); + + /** + * Retrieves the UIDs of a directory entry. + * This method returns always 0 with a Series3. + * + * @param uididx The index of the UID to retrieve (0 .. 2). + * + * @returns The selected UID or 0 if the index is out of range. + */ + long getUID(int uididx); + + /** + * Retrieves the @ref PlpUID object of a directory entry. + * + * @returns The PlpUID object. + */ + PlpUID &getUID(); + + /** + * Retrieve the file name of a directory entry. + * + * @returns The name of the file. + */ + const char *getName(); + + /** + * Retrieve the modification time of a directory entry. + * + * @returns A @ref PsiTime object, representing the time. + */ + PsiTime getPsiTime(); + + /** + * Set the file name of a directory entry. + * This is currently used in plpbackup only for + * changing the name to the full path. It does NOT + * change the name of the corresponding file on + * the Psion. + * + * @param str The new name of the file. + */ + void setName(const char *str); + + /** + * Assignment operator + * Mainly used by STL container classes. + * + * @param e The new value to assign. + * + * @returns The modified object. + */ + PlpDirent &operator=(const PlpDirent &e); + + /** + * Prints the object contents. + * The output is in human readable similar to the + * output of a "ls" command. + */ + friend ostream &operator<<(ostream &o, const PlpDirent &e); private: - long size; - long attr; - PlpUID UID; - PsiTime time; - string attrstr; - string name; + long size; + long attr; + PlpUID UID; + PsiTime time; + string attrstr; + string name; }; /** @@ -167,158 +189,165 @@ private: * @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; + 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 + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ diff --git a/lib/ppsocket.cc b/lib/ppsocket.cc index 9b0a33d..49e02be 100644 --- a/lib/ppsocket.cc +++ b/lib/ppsocket.cc @@ -1,24 +1,26 @@ -// -// PLP - An implementation of the PSION link protocol -// -// Copyright (C) 1999 Philip Proudman -// -// 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 -// -// e-mail philip.proudman@btinternet.com - +/*-*-c++-*- + * $Id$ + * + * This file is part of plptools. + * + * Copyright (C) 1999 Philip Proudman <philip.proudman@btinternet.com> + * Copyright (C) 1999-2001 Fritz Elfert <felfert@to.com> + * + * 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 + * + */ #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -45,563 +47,569 @@ ppsocket::ppsocket(const ppsocket & another) { - m_Socket = another.m_Socket; - m_HostAddr = another.m_HostAddr; - m_PeerAddr = another.m_PeerAddr; - m_Bound = another.m_Bound; - m_LastError = another.m_LastError; - myWatch = another.myWatch; + m_Socket = another.m_Socket; + m_HostAddr = another.m_HostAddr; + m_PeerAddr = another.m_PeerAddr; + m_Bound = another.m_Bound; + m_LastError = another.m_LastError; + myWatch = another.myWatch; } ppsocket::ppsocket() { - m_Socket = INVALID_SOCKET; + m_Socket = INVALID_SOCKET; - memset(&m_HostAddr, 0, sizeof(m_HostAddr)); - memset(&m_PeerAddr, 0, sizeof(m_PeerAddr)); + memset(&m_HostAddr, 0, sizeof(m_HostAddr)); + memset(&m_PeerAddr, 0, sizeof(m_PeerAddr)); - ((struct sockaddr_in *) &m_HostAddr)->sin_family = AF_INET; - ((struct sockaddr_in *) &m_PeerAddr)->sin_family = AF_INET; + ((struct sockaddr_in *) &m_HostAddr)->sin_family = AF_INET; + ((struct sockaddr_in *) &m_PeerAddr)->sin_family = AF_INET; - m_Bound = false; - m_LastError = 0; - myWatch = 0L; + m_Bound = false; + m_LastError = 0; + myWatch = 0L; } ppsocket::~ppsocket() { - if (m_Socket != INVALID_SOCKET) { - if (myWatch) - myWatch->remIO(m_Socket); - shutdown(m_Socket, SHUT_RDWR); - ::close(m_Socket); - } + if (m_Socket != INVALID_SOCKET) { + if (myWatch) + myWatch->remIO(m_Socket); + shutdown(m_Socket, SHUT_RDWR); + ::close(m_Socket); + } } void ppsocket:: setWatch(IOWatch *watch) { - if (watch) - myWatch = watch; + if (watch) + myWatch = watch; } bool ppsocket:: reconnect() { - if (m_Socket != INVALID_SOCKET) { - if (myWatch) - myWatch->remIO(m_Socket); - shutdown(m_Socket, SHUT_RDWR); - ::close(m_Socket); - } - m_Socket = INVALID_SOCKET; - if (!createSocket()) - return (false); - m_LastError = 0; - m_Bound = false; - if (::bind(m_Socket, &m_HostAddr, sizeof(m_HostAddr)) != 0) { - m_LastError = errno; - return (false); - } - if (::connect(m_Socket, &m_PeerAddr, sizeof(m_PeerAddr)) != 0) { - m_LastError = errno; - return (false); - } + if (m_Socket != INVALID_SOCKET) { if (myWatch) - myWatch->addIO(m_Socket); - return (true); + myWatch->remIO(m_Socket); + shutdown(m_Socket, SHUT_RDWR); + ::close(m_Socket); + } + m_Socket = INVALID_SOCKET; + if (!createSocket()) + return (false); + m_LastError = 0; + m_Bound = false; + if (::bind(m_Socket, &m_HostAddr, sizeof(m_HostAddr)) != 0) { + m_LastError = errno; + return (false); + } + if (::connect(m_Socket, &m_PeerAddr, sizeof(m_PeerAddr)) != 0) { + m_LastError = errno; + return (false); + } + if (myWatch) + myWatch->addIO(m_Socket); + return (true); } string ppsocket:: toString() { - string ret = ""; - char nbuf[10]; - char *tmp = 0L; - int port; - - tmp = inet_ntoa(((struct sockaddr_in *) &m_HostAddr)->sin_addr); - ret += tmp ? tmp : "none:none"; - if (tmp) { - ret += ':'; - sprintf(nbuf, "%d", ntohs(((struct sockaddr_in *) &m_HostAddr)->sin_port)); - ret += nbuf; - } - ret += " -> "; - tmp = inet_ntoa(((struct sockaddr_in *) &m_PeerAddr)->sin_addr); - ret += tmp ? tmp : "none:none"; - if (tmp) { - ret += ':'; - sprintf(nbuf, "%d", ntohs(((struct sockaddr_in *) &m_PeerAddr)->sin_port)); - ret += nbuf; - } - return ret; + string ret = ""; + char nbuf[10]; + char *tmp = 0L; + int port; + + tmp = inet_ntoa(((struct sockaddr_in *) &m_HostAddr)->sin_addr); + ret += tmp ? tmp : "none:none"; + if (tmp) { + ret += ':'; + sprintf(nbuf, "%d", ntohs(((struct sockaddr_in *) &m_HostAddr)->sin_port)); + ret += nbuf; + } + ret += " -> "; + tmp = inet_ntoa(((struct sockaddr_in *) &m_PeerAddr)->sin_addr); + ret += tmp ? tmp : "none:none"; + if (tmp) { + ret += ':'; + sprintf(nbuf, "%d", ntohs(((struct sockaddr_in *) &m_PeerAddr)->sin_port)); + ret += nbuf; + } + return ret; } bool ppsocket:: connect(const char * const Peer, int PeerPort, const char * const Host, int HostPort) { - //**************************************************** - //* If we aren't already bound set the host and bind * - //**************************************************** - - if (!bindSocket(Host, HostPort)) { - if (m_LastError != 0) { - return (false); - } - } - //**************** - //* Set the peer * - //**************** - if (!setPeer(Peer, PeerPort)) { - return (false); - } - //*********** - //* Connect * - //*********** - if (::connect(m_Socket, &m_PeerAddr, sizeof(m_PeerAddr)) != 0) { - m_LastError = errno; - return (false); + //**************************************************** + //* If we aren't already bound set the host and bind * + //**************************************************** + + if (!bindSocket(Host, HostPort)) { + if (m_LastError != 0) { + return (false); } - if (myWatch) - myWatch->addIO(m_Socket); - return (true); + } + //**************** + //* Set the peer * + //**************** + if (!setPeer(Peer, PeerPort)) { + return (false); + } + //*********** + //* Connect * + //*********** + if (::connect(m_Socket, &m_PeerAddr, sizeof(m_PeerAddr)) != 0) { + m_LastError = errno; + return (false); + } + if (myWatch) + myWatch->addIO(m_Socket); + return (true); } bool ppsocket:: listen(const char * const Host, int Port) { - //**************************************************** - //* If we aren't already bound set the host and bind * - //**************************************************** - - if (!bindSocket(Host, Port)) { - if (m_LastError != 0) { - return (false); - } - } - //********************** - //* Listen on the port * - //********************** + //**************************************************** + //* If we aren't already bound set the host and bind * + //**************************************************** - if (myWatch) - myWatch->addIO(m_Socket); - if (::listen(m_Socket, 5) != 0) { - m_LastError = errno; - return (false); + if (!bindSocket(Host, Port)) { + if (m_LastError != 0) { + return (false); } - // Our accept member function relies on non-blocking accepts, - // so set the flag here (rather than every time around the loop) - fcntl(m_Socket, F_SETFL, O_NONBLOCK); - return (true); + } + //********************** + //* Listen on the port * + //********************** + + if (myWatch) + myWatch->addIO(m_Socket); + if (::listen(m_Socket, 5) != 0) { + m_LastError = errno; + return (false); + } + // Our accept member function relies on non-blocking accepts, + // so set the flag here (rather than every time around the loop) + fcntl(m_Socket, F_SETFL, O_NONBLOCK); + return (true); } ppsocket *ppsocket:: accept(string *Peer) { #ifdef sun - int len; + int len; #else - socklen_t len; + socklen_t len; #endif - ppsocket *accepted; - char *peer; - - //***************************************************** - //* Allocate a new object to hold the accepted socket * - //***************************************************** - accepted = new ppsocket; - - if (!accepted) { - m_LastError = errno; - return NULL; - } - //*********************** - //* Accept a connection * - //*********************** - - len = sizeof(struct sockaddr); - accepted->m_Socket = ::accept(m_Socket, &accepted->m_PeerAddr, &len); - - if (accepted->m_Socket == INVALID_SOCKET) { - m_LastError = errno; - delete accepted; - return NULL; - } - //**************************************************** - //* Got a connection so fill in the other attributes * - //**************************************************** - - // Make sure the new socket hasn't inherited O_NONBLOCK - // from the accept socket - 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; - - //**************************************************** - //* If required get the name of the connected client * - //**************************************************** - if (Peer) { - peer = inet_ntoa(((struct sockaddr_in *) &accepted->m_PeerAddr)->sin_addr); - if (peer) - *Peer = peer; - } - if (accepted && myWatch) { - accepted->setWatch(myWatch); - myWatch->addIO(accepted->m_Socket); - } - return accepted; + ppsocket *accepted; + char *peer; + + //***************************************************** + //* Allocate a new object to hold the accepted socket * + //***************************************************** + accepted = new ppsocket; + + if (!accepted) { + m_LastError = errno; + return NULL; + } + //*********************** + //* Accept a connection * + //*********************** + + len = sizeof(struct sockaddr); + accepted->m_Socket = ::accept(m_Socket, &accepted->m_PeerAddr, &len); + + if (accepted->m_Socket == INVALID_SOCKET) { + m_LastError = errno; + delete accepted; + return NULL; + } + //**************************************************** + //* Got a connection so fill in the other attributes * + //**************************************************** + + // Make sure the new socket hasn't inherited O_NONBLOCK + // from the accept socket + 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; + + //**************************************************** + //* If required get the name of the connected client * + //**************************************************** + if (Peer) { + peer = inet_ntoa(((struct sockaddr_in *) &accepted->m_PeerAddr)->sin_addr); + if (peer) + *Peer = peer; + } + if (accepted && myWatch) { + accepted->setWatch(myWatch); + myWatch->addIO(accepted->m_Socket); + } + return accepted; } bool ppsocket:: dataToGet(int sec, int usec) const { - fd_set io; - FD_ZERO(&io); - FD_SET(m_Socket, &io); - struct timeval t; - t.tv_usec = usec; - t.tv_sec = sec; - return (select(m_Socket + 1, &io, NULL, NULL, &t) != 0) ? true : false; + fd_set io; + FD_ZERO(&io); + FD_SET(m_Socket, &io); + struct timeval t; + t.tv_usec = usec; + t.tv_sec = sec; + return (select(m_Socket + 1, &io, NULL, NULL, &t) != 0) ? true : false; } int ppsocket:: getBufferStore(bufferStore & a, bool wait) { - /* Returns a 0 for for no message, - * 1 for message OK, and -1 for socket problem - */ - - u_int32_t l; - long count = 0; - unsigned char *buff; - unsigned char *bp; - if (!wait && !dataToGet(0, 0)) - return 0; - a.init(); - 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, MSG_NOSIGNAL); - if (j == SOCKET_ERROR || j == 0) { - delete[]buff; - return -1; - } - count += j; - l -= j; - bp += j; - }; - a.init(buff, count); - delete[]buff; - return (a.getLen() == 0) ? 0 : 1; + /* Returns a 0 for for no message, + * 1 for message OK, and -1 for socket problem + */ + + u_int32_t l; + long count = 0; + unsigned char *buff; + unsigned char *bp; + if (!wait && !dataToGet(0, 0)) + return 0; + a.init(); + if (recv(&l, sizeof(l), MSG_NOSIGNAL) != sizeof(l)) { +// cerr << "gBS: e=" << strerror(errno) << endl; + return -1; + } + l = ntohl(l); + bp = buff = new unsigned char[l]; + while (l > 0) { + int j = recv(bp, l, MSG_NOSIGNAL); + if (j == SOCKET_ERROR || j == 0) { +// cerr << "gBS: j=" << j << " e=" << strerror(errno) << endl; + delete[]buff; + return -1; + } + count += j; + l -= j; + bp += j; + }; + a.init(buff, count); + delete[]buff; + return (a.getLen() == 0) ? 0 : 1; } bool ppsocket:: sendBufferStore(const bufferStore & a) { - long l = a.getLen(); - u_int32_t hl = htonl(l); - long sent = 0; - int retries = 0; - int i; - - 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 *)b.getString(sent), l, MSG_NOSIGNAL); - if (i == SOCKET_ERROR || i == 0) - return (false); - sent += i; - l -= i; - if (++retries > 5) { - m_LastError = 0; - return (false); - } + long l = a.getLen(); + u_int32_t hl = htonl(l); + long sent = 0; + int retries = 0; + int i; + + bufferStore b; + b.addDWord(hl); + b.addBuff(a); + l += 4; + while (l > 0) { + i = send((const char *)b.getString(sent), l, MSG_NOSIGNAL); + if (i == SOCKET_ERROR || i == 0) + return (false); + sent += i; + l -= i; + if (++retries > 5) { + m_LastError = 0; + return (false); } - return true; + } + return true; } int ppsocket:: recv(void *buf, int len, int flags) { - int i = ::recv(m_Socket, buf, len, flags); + int i = ::recv(m_Socket, buf, len, flags); - if (i < 0) - m_LastError = errno; + if (i < 0) + m_LastError = errno; - return (i); + return (i); } int ppsocket:: send(const void * const buf, int len, int flags) { - int i = ::send(m_Socket, buf, len, flags); + int i = ::send(m_Socket, buf, len, flags); - if (i < 0) - m_LastError = errno; + if (i < 0) + m_LastError = errno; - return (i); + return (i); } bool ppsocket:: closeSocket(void) { - if (myWatch) - myWatch->remIO(m_Socket); - shutdown(m_Socket, SHUT_RDWR); - if (::close(m_Socket) != 0) { - m_LastError = errno; - return false; - } - m_Socket = INVALID_SOCKET; - return true; + if (myWatch) + myWatch->remIO(m_Socket); + shutdown(m_Socket, SHUT_RDWR); + if (::close(m_Socket) != 0) { + m_LastError = errno; + return false; + } + m_Socket = INVALID_SOCKET; + return true; } bool ppsocket:: bindSocket(const char * const Host, int Port) { - // If we are already bound return false but with no last error - if (m_Bound) { - m_LastError = 0; - return false; - } + // If we are already bound return false but with no last error + if (m_Bound) { + m_LastError = 0; + return false; + } - // If the socket hasn't been created create it now + // If the socket hasn't been created create it now - if (m_Socket == INVALID_SOCKET) { - if (!createSocket()) - return false; - } + if (m_Socket == INVALID_SOCKET) { + if (!createSocket()) + return false; + } - // Set SO_REUSEADDR - int one = 1; - if (setsockopt(m_Socket, SOL_SOCKET, SO_REUSEADDR, - (const char *)&one, sizeof(int)) < 0) - cerr << "Warning: Unable to set SO_REUSEADDR option\n"; + // Set SO_REUSEADDR + int one = 1; + if (setsockopt(m_Socket, SOL_SOCKET, SO_REUSEADDR, + (const char *)&one, sizeof(int)) < 0) + cerr << "Warning: Unable to set SO_REUSEADDR option\n"; - // If a host name was supplied then use it - if (!setHost(Host, Port)) - return false; + // If a host name was supplied then use it + if (!setHost(Host, Port)) + return false; - // Now bind the socket - if (::bind(m_Socket, &m_HostAddr, sizeof(m_HostAddr)) != 0) { - m_LastError = errno; - return false; - } + // Now bind the socket + if (::bind(m_Socket, &m_HostAddr, sizeof(m_HostAddr)) != 0) { + m_LastError = errno; + return false; + } - m_Bound = true; - return true; + m_Bound = true; + return true; } bool ppsocket:: bindInRange(const char * const Host, int Low, int High, int Retries) { - int port; - int i; + int port; + int i; - // If we are already bound return false but with no last error - if (m_Bound) { - m_LastError = 0; - return (false); - } + // If we are already bound return false but with no last error + if (m_Bound) { + m_LastError = 0; + return (false); + } - // If the socket hasn't been created create it now - if (m_Socket == INVALID_SOCKET) { - if (!createSocket()) - return false; + // If the socket hasn't been created create it now + if (m_Socket == INVALID_SOCKET) { + if (!createSocket()) + return false; + } + + // If the number of retries is greater than the range then work + // through the range sequentially. + if (Retries > High - Low) { + for (port = Low; port <= High; port++) { + if (!setHost(Host, port)) + return false; + if (::bind(m_Socket, &m_HostAddr, sizeof(m_HostAddr)) == 0) + break; } - - // If the number of retries is greater than the range then work - // through the range sequentially. - if (Retries > High - Low) { - for (port = Low; port <= High; port++) { - if (!setHost(Host, port)) - return false; - if (::bind(m_Socket, &m_HostAddr, sizeof(m_HostAddr)) == 0) - break; - } - if (port > High) { - m_LastError = errno; - return false; - } - } else { - for (i = 0; i < Retries; i++) { - port = Low + (rand() % (High - Low)); - if (!setHost(Host, port)) - return false; - if (::bind(m_Socket, &m_HostAddr, sizeof(m_HostAddr)) == 0) - break; - } - if (i >= Retries) { - m_LastError = errno; - return false; - } + if (port > High) { + m_LastError = errno; + return false; } - m_Bound = true; - return true; + } else { + for (i = 0; i < Retries; i++) { + port = Low + (rand() % (High - Low)); + if (!setHost(Host, port)) + return false; + if (::bind(m_Socket, &m_HostAddr, sizeof(m_HostAddr)) == 0) + break; + } + if (i >= Retries) { + m_LastError = errno; + return false; + } + } + m_Bound = true; + return true; } bool ppsocket:: linger(bool LingerOn, int LingerTime) { - int i; - struct linger l; - - // If the socket hasn't been created create it now - if (m_Socket == INVALID_SOCKET) { - if (!createSocket()) - return false; - } + int i; + struct linger l; - // Set the lingering - if (LingerOn) { - l.l_onoff = 1; - l.l_linger = LingerTime; - } else { - l.l_onoff = 0; - l.l_linger = 0; - } - i = setsockopt(m_Socket, SOL_SOCKET, SO_LINGER, (const char *) &l, sizeof(l)); - // Check for errors - if (i != 0) { - m_LastError = errno; - return false; - } - return true; + // If the socket hasn't been created create it now + if (m_Socket == INVALID_SOCKET) { + if (!createSocket()) + return false; + } + + // Set the lingering + if (LingerOn) { + l.l_onoff = 1; + l.l_linger = LingerTime; + } else { + l.l_onoff = 0; + l.l_linger = 0; + } + i = setsockopt(m_Socket, SOL_SOCKET, SO_LINGER, (const char *) &l, sizeof(l)); + // Check for errors + if (i != 0) { + m_LastError = errno; + return false; + } + return true; } bool ppsocket:: createSocket(void) { - // If the socket has already been created just return true - if (m_Socket != INVALID_SOCKET) - return true; + // If the socket has already been created just return true + if (m_Socket != INVALID_SOCKET) + return true; - // Create the socket - m_Socket = ::socket(PF_INET, SOCK_STREAM, 0); - if (m_Socket == INVALID_SOCKET) { - m_LastError = errno; - return false; - } + // Create the socket + m_Socket = ::socket(PF_INET, SOCK_STREAM, 0); + if (m_Socket == INVALID_SOCKET) { + m_LastError = errno; + return false; + } - // By default set no lingering - linger(false); + // By default set no lingering + linger(false); - // Return indicating success - return true; + // Return indicating success + return true; } bool ppsocket:: setPeer(const char * const Peer, int Port) { - struct hostent *he = NULL; - - // If a peer name was supplied then use it - if (Peer) { - if (!isdigit(Peer[0])) - // RFC1035 specifies that hostnames must not start - // with a digit. So we can speed up things here. - he = gethostbyname(Peer); - if (!he) { - struct in_addr ipaddr; - - if (!inet_aton(Peer, &ipaddr)) { - m_LastError = errno; - return false; - } - he = gethostbyaddr((const char *)&ipaddr.s_addr, sizeof(ipaddr.s_addr), PF_INET); - if (!he) { - m_LastError = errno; - return (false); - } - } - memcpy(&((struct sockaddr_in *)&m_PeerAddr)->sin_addr, he->h_addr_list[0], - sizeof(((struct sockaddr_in *)&m_PeerAddr)->sin_addr)); + struct hostent *he = NULL; + + // If a peer name was supplied then use it + if (Peer) { + if (!isdigit(Peer[0])) + // RFC1035 specifies that hostnames must not start + // with a digit. So we can speed up things here. + he = gethostbyname(Peer); + if (!he) { + struct in_addr ipaddr; + + if (!inet_aton(Peer, &ipaddr)) { + m_LastError = errno; + return false; + } + he = gethostbyaddr((const char *)&ipaddr.s_addr, sizeof(ipaddr.s_addr), PF_INET); + if (!he) { + m_LastError = errno; + return (false); + } } - // If a port name was supplied use it - if (Port > 0) - ((struct sockaddr_in *)&m_PeerAddr)->sin_port = htons(Port); - return true; + memcpy(&((struct sockaddr_in *)&m_PeerAddr)->sin_addr, he->h_addr_list[0], + sizeof(((struct sockaddr_in *)&m_PeerAddr)->sin_addr)); + } + // If a port name was supplied use it + if (Port > 0) + ((struct sockaddr_in *)&m_PeerAddr)->sin_port = htons(Port); + return true; } bool ppsocket:: getPeer(string *Peer, int *Port) { - char *peer; - - if (Peer) { - peer = inet_ntoa(((struct sockaddr_in *) &m_PeerAddr)->sin_addr); - if (!peer) { - m_LastError = errno; - return (false); - } - *Peer = peer; + char *peer; + + if (Peer) { + peer = inet_ntoa(((struct sockaddr_in *) &m_PeerAddr)->sin_addr); + if (!peer) { + m_LastError = errno; + return (false); } - if (Port) - *Port = ntohs(((struct sockaddr_in *) &m_PeerAddr)->sin_port); - return false; + *Peer = peer; + } + if (Port) + *Port = ntohs(((struct sockaddr_in *) &m_PeerAddr)->sin_port); + return false; } bool ppsocket:: setHost(const char * const Host, int Port) { - struct hostent *he; - - // If a host name was supplied then use it - if (Host) { - if (!isdigit(Host[0])) - // RFC1035 specifies that hostnames must not start - // with a digit. So we can speed up things here. - he = gethostbyname(Host); - he = gethostbyname(Host); - if (!he) { - struct in_addr ipaddr; - - if (!inet_aton(Host, &ipaddr)) { - m_LastError = errno; - return false; - } - he = gethostbyaddr((const char *)&ipaddr.s_addr, sizeof(ipaddr.s_addr), PF_INET); - if (!he) { - m_LastError = errno; - return false; - } - } - memcpy(&((struct sockaddr_in *)&m_HostAddr)->sin_addr, he->h_addr_list[0], - sizeof(((struct sockaddr_in *)&m_HostAddr)->sin_addr)); + struct hostent *he; + + // If a host name was supplied then use it + if (Host) { + if (!isdigit(Host[0])) + // RFC1035 specifies that hostnames must not start + // with a digit. So we can speed up things here. + he = gethostbyname(Host); + he = gethostbyname(Host); + if (!he) { + struct in_addr ipaddr; + + if (!inet_aton(Host, &ipaddr)) { + m_LastError = errno; + return false; + } + he = gethostbyaddr((const char *)&ipaddr.s_addr, sizeof(ipaddr.s_addr), PF_INET); + if (!he) { + m_LastError = errno; + return false; + } } - - // If a port name was supplied use it - if (Port > 0) - ((struct sockaddr_in *)&m_HostAddr)->sin_port = htons(Port); - return true; + memcpy(&((struct sockaddr_in *)&m_HostAddr)->sin_addr, he->h_addr_list[0], + sizeof(((struct sockaddr_in *)&m_HostAddr)->sin_addr)); + } + + // If a port name was supplied use it + if (Port > 0) + ((struct sockaddr_in *)&m_HostAddr)->sin_port = htons(Port); + return true; } bool ppsocket:: getHost(string *Host, int *Port) { - char *host; - - if (Host) { - host = inet_ntoa(((struct sockaddr_in *)&m_HostAddr)->sin_addr); - if (!host) { - m_LastError = errno; - return false; - } - *Host = host; + char *host; + + if (Host) { + host = inet_ntoa(((struct sockaddr_in *)&m_HostAddr)->sin_addr); + if (!host) { + m_LastError = errno; + return false; } - if (Port) - *Port = ntohs(((struct sockaddr_in *)&m_HostAddr)->sin_port); - return true; + *Host = host; + } + if (Port) + *Port = ntohs(((struct sockaddr_in *)&m_HostAddr)->sin_port); + return true; } + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ diff --git a/lib/ppsocket.h b/lib/ppsocket.h index b8f7ebe..05593d3 100644 --- a/lib/ppsocket.h +++ b/lib/ppsocket.h @@ -1,3 +1,26 @@ +/*-*-c++-*- + * $Id$ + * + * This file is part of plptools. + * + * Copyright (C) 1999 Philip Proudman <philip.proudman@btinternet.com> + * Copyright (C) 1999-2001 Fritz Elfert <felfert@to.com> + * + * 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 _PPSOCKET_H_ #define _PPSOCKET_H_ @@ -17,189 +40,195 @@ class ppsocket { public: - /** - * Constructs a ppsocket - */ - ppsocket(); - - /** - * Copy constructor - */ - ppsocket(const ppsocket&); - - /** - * Destructor - */ - virtual ~ppsocket(); + /** + * Constructs a ppsocket + */ + ppsocket(); + + /** + * Copy constructor + */ + ppsocket(const ppsocket&); + + /** + * Destructor + */ + virtual ~ppsocket(); - /** - * Connects to a given host. - * - * @param Peer The Host to connect to (name or dotquad-string). - * @param PeerPort The port to connect to. - * @param Host The local address to bind to. - * @param HostPort The local port to bind to. - * - * @returns true on success, false otherwise. - */ - virtual bool connect(const char * const Peer, int PeerPort, const char * const Host = NULL, int HostPort = 0); - - /** - * Reopens the connection after closing it. - * - * @returns true on success, false otherwise. - */ - virtual bool reconnect(); - - /** - * Retrieve a string representation of the ppsocket. - * - * @returns a string in the form "<host>:<hostport> -> <peer>:<peerport>" - * where elements not known, are replaced by "???" and none-existing - * elements are represented by the word "none". - */ - virtual string toString(); - - /** - * Starts listening. - * - * @param Host The local address to bind to. - * @param Port The local port to listen on. - * - * @returns true on success, false otherwise. - */ - virtual bool listen(const char * const Host, int Port); - - /** - * Accept a connection. - * - * @param Peer If non-Null, the peer's name is returned here. - * - * @returns A pointer to a new instance for the accepted connection or NULL - * if an error happened. - */ - ppsocket *accept(string *Peer); - - /** - * 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(int sec, int usec) const; - - /** - * Receive data into a @ref bufferStore . - * - * @param a The bufferStore to fill with received data. - * @param wait If true, wait until something is received, else return - * if no data is available. - * @returns 1 if a bufferStore received, 0, if no bufferStore received, -1 - * on error. - */ - int getBufferStore(bufferStore &a, bool wait = true); - - /** - * Sends data from a @ref bufferStore . - * - * @param a The bufferStore to send. - * @returns true on success, false otherwise. - */ - bool sendBufferStore(const bufferStore &a); - - /** - * Closes the connection. - * - * @returns true on success, false otherwise. - */ - bool closeSocket(void); - - /** - * Binds to a local address and port. - * - * @param Host The local address to bind to. - * @param Port The local port to listen on. - * - * @returns true on success, false otherwise. - */ - bool bindSocket(const char * const Host, int Port); - - /** - * Tries repeated binds to a local address and port. - * If @p Retries is <= @p High - @p Low, then - * the port to bind is randomly chosen in the given range. - * Otherwise, all ports starting from @p High up to @p Low - * are tried in sequence. - * - * @param Host The local address to bind to. - * @param Low The lowest local port to listen on. - * @param High The highest local port to listen on. - * @param Retries The number of retries until giving up. - * - * @returns true on success, false otherwise. - */ - bool bindInRange(const char * const Host, int Low, int High, int Retries); - - /** - * Sets the linger parameter of the socket. - * - * @param LingerOn true, if lingering should be on. - * @param LingerTime If lingering is on, the linger-time. - * - * @returns true on success, false otherwise. - */ - bool linger(bool LingerOn, int LingerTime = 0); - - /** - * Retrieves peer information. - * - * @param Peer The peers name is returned here. - * @param Port The peers port is returned here. - * - * @returns true on success, false otherwise. - */ - bool getPeer(string *Peer, int *Port); - - /** - * Retrieves local information. - * - * @param Host The local name is returned here. - * @param Port The local port is returned here. - * - * @returns true on success, false otherwise. - */ - bool getHost(string *Host, int *Port); - - /** - * Registers an @ref IOWatch for this socket. - * This IOWatch gets the socket added/removed - * automatically. - * - * @param watch The IOWatch to register. - */ - void setWatch(IOWatch *watch); + /** + * Connects to a given host. + * + * @param Peer The Host to connect to (name or dotquad-string). + * @param PeerPort The port to connect to. + * @param Host The local address to bind to. + * @param HostPort The local port to bind to. + * + * @returns true on success, false otherwise. + */ + virtual bool connect(const char * const Peer, int PeerPort, const char * const Host = NULL, int HostPort = 0); + + /** + * Reopens the connection after closing it. + * + * @returns true on success, false otherwise. + */ + virtual bool reconnect(); + + /** + * Retrieve a string representation of the ppsocket. + * + * @returns a string in the form "<host>:<hostport> -> <peer>:<peerport>" + * where elements not known, are replaced by "???" and none-existing + * elements are represented by the word "none". + */ + virtual string toString(); + + /** + * Starts listening. + * + * @param Host The local address to bind to. + * @param Port The local port to listen on. + * + * @returns true on success, false otherwise. + */ + virtual bool listen(const char * const Host, int Port); + + /** + * Accept a connection. + * + * @param Peer If non-Null, the peer's name is returned here. + * + * @returns A pointer to a new instance for the accepted connection or NULL + * if an error happened. + */ + ppsocket *accept(string *Peer); + + /** + * 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(int sec, int usec) const; + + /** + * Receive data into a @ref bufferStore . + * + * @param a The bufferStore to fill with received data. + * @param wait If true, wait until something is received, else return + * if no data is available. + * @returns 1 if a bufferStore received, 0, if no bufferStore received, -1 + * on error. + */ + int getBufferStore(bufferStore &a, bool wait = true); + + /** + * Sends data from a @ref bufferStore . + * + * @param a The bufferStore to send. + * @returns true on success, false otherwise. + */ + bool sendBufferStore(const bufferStore &a); + + /** + * Closes the connection. + * + * @returns true on success, false otherwise. + */ + bool closeSocket(void); + + /** + * Binds to a local address and port. + * + * @param Host The local address to bind to. + * @param Port The local port to listen on. + * + * @returns true on success, false otherwise. + */ + bool bindSocket(const char * const Host, int Port); + + /** + * Tries repeated binds to a local address and port. + * If @p Retries is <= @p High - @p Low, then + * the port to bind is randomly chosen in the given range. + * Otherwise, all ports starting from @p High up to @p Low + * are tried in sequence. + * + * @param Host The local address to bind to. + * @param Low The lowest local port to listen on. + * @param High The highest local port to listen on. + * @param Retries The number of retries until giving up. + * + * @returns true on success, false otherwise. + */ + bool bindInRange(const char * const Host, int Low, int High, int Retries); + + /** + * Sets the linger parameter of the socket. + * + * @param LingerOn true, if lingering should be on. + * @param LingerTime If lingering is on, the linger-time. + * + * @returns true on success, false otherwise. + */ + bool linger(bool LingerOn, int LingerTime = 0); + + /** + * Retrieves peer information. + * + * @param Peer The peers name is returned here. + * @param Port The peers port is returned here. + * + * @returns true on success, false otherwise. + */ + bool getPeer(string *Peer, int *Port); + + /** + * Retrieves local information. + * + * @param Host The local name is returned here. + * @param Port The local port is returned here. + * + * @returns true on success, false otherwise. + */ + bool getHost(string *Host, int *Port); + + /** + * Registers an @ref IOWatch for this socket. + * This IOWatch gets the socket added/removed + * automatically. + * + * @param watch The IOWatch to register. + */ + void setWatch(IOWatch *watch); - private: - /** - * Creates the socket. - */ - virtual bool createSocket(void); - - int getLastError(void) { return(m_LastError); } - bool setPeer(const char * const Peer, int Port); - bool setHost(const char * const Host, int Port); - int recv(void *buf, int len, int flags); - int send(const void * const buf, int len, int flags); +private: + /** + * Creates the socket. + */ + virtual bool createSocket(void); + + int getLastError(void) { return(m_LastError); } + bool setPeer(const char * const Peer, int Port); + bool setHost(const char * const Host, int Port); + int recv(void *buf, int len, int flags); + int send(const void * const buf, int len, int flags); - struct sockaddr m_HostAddr; - struct sockaddr m_PeerAddr; - int m_Socket; - int m_Port; - bool m_Bound; - int m_LastError; - IOWatch *myWatch; + struct sockaddr m_HostAddr; + struct sockaddr m_PeerAddr; + int m_Socket; + int m_Port; + bool m_Bound; + int m_LastError; + IOWatch *myWatch; }; #endif + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ diff --git a/lib/psitime.cc b/lib/psitime.cc index d79ca80..f239fe6 100644 --- a/lib/psitime.cc +++ b/lib/psitime.cc @@ -1,140 +1,161 @@ - +/*-*-c++-*- + * $Id$ + * + * This file is part of plptools. + * + * Copyright (C) 2000-2001 Fritz Elfert <felfert@to.com> + * + * 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 "psitime.h" #include <stdlib.h> PsiTime::PsiTime(void) { - ptzValid = false; - tryPsiZone(); - setUnixNow(); + ptzValid = false; + tryPsiZone(); + setUnixNow(); } PsiTime::PsiTime(time_t time) { - ptzValid = false; - gettimeofday(NULL, &utz); - setUnixTime(time); + ptzValid = false; + gettimeofday(NULL, &utz); + setUnixTime(time); } PsiTime::PsiTime(psi_timeval *_ptv, psi_timezone *_ptz) { - if (_ptv != 0L) - ptv = *_ptv; - if (_ptz != 0L) { - ptz = *_ptz; - ptzValid = true; - } else { - ptzValid = false; - tryPsiZone(); - } - /* get our own timezone */ - gettimeofday(NULL, &utz); - psi2unix(); + if (_ptv != 0L) + ptv = *_ptv; + if (_ptz != 0L) { + ptz = *_ptz; + ptzValid = true; + } else { + ptzValid = false; + tryPsiZone(); + } + /* get our own timezone */ + gettimeofday(NULL, &utz); + psi2unix(); } PsiTime::PsiTime(const unsigned long _ptvHi, const unsigned long _ptvLo) { - ptv.tv_high = _ptvHi; - ptv.tv_low = _ptvLo; - ptzValid = false; - tryPsiZone(); - /* get our own timezone */ - gettimeofday(NULL, &utz); - psi2unix(); + ptv.tv_high = _ptvHi; + ptv.tv_low = _ptvLo; + ptzValid = false; + tryPsiZone(); + /* get our own timezone */ + gettimeofday(NULL, &utz); + psi2unix(); } PsiTime::PsiTime(struct timeval *_utv = 0L, struct timezone *_utz = 0L) { - if (_utv != 0L) - utv = *_utv; - if (_utz != 0L) - utz = *_utz; - tryPsiZone(); - unix2psi(); + if (_utv != 0L) + utv = *_utv; + if (_utz != 0L) + utz = *_utz; + tryPsiZone(); + unix2psi(); } PsiTime::PsiTime(const PsiTime &t) { - utv = t.utv; - utz = t.utz; - ptv = t.ptv; - ptz = t.ptz; - ptzValid = t.ptzValid; - tryPsiZone(); + utv = t.utv; + utz = t.utz; + ptv = t.ptv; + ptz = t.ptz; + ptzValid = t.ptzValid; + tryPsiZone(); } PsiTime::~PsiTime() { - tryPsiZone(); + tryPsiZone(); } void PsiTime::setUnixTime(struct timeval *_utv) { - if (_utv != 0L) - utv = *_utv; - unix2psi(); + if (_utv != 0L) + utv = *_utv; + unix2psi(); } void PsiTime::setUnixTime(time_t time) { - utv.tv_sec = time; - utv.tv_usec = 0; - unix2psi(); + utv.tv_sec = time; + utv.tv_usec = 0; + unix2psi(); } void PsiTime::setUnixNow(void) { - gettimeofday(&utv, &utz); - unix2psi(); + gettimeofday(&utv, &utz); + unix2psi(); } void PsiTime::setPsiTime(psi_timeval *_ptv) { - if (_ptv != 0L) - ptv = *_ptv; - psi2unix(); + if (_ptv != 0L) + ptv = *_ptv; + psi2unix(); } void PsiTime::setPsiTime(const unsigned long _ptvHi, const unsigned long _ptvLo) { - ptv.tv_high = _ptvHi; - ptv.tv_low = _ptvLo; - psi2unix(); + ptv.tv_high = _ptvHi; + ptv.tv_low = _ptvLo; + psi2unix(); } void PsiTime::setPsiZone(psi_timezone *_ptz) { - if (_ptz != 0L) { - ptz = *_ptz; - ptzValid = true; - } - psi2unix(); + if (_ptz != 0L) { + ptz = *_ptz; + ptzValid = true; + } + psi2unix(); } struct timeval &PsiTime::getTimeval(void) { - return utv; + return utv; } time_t PsiTime::getTime(void) { - return utv.tv_sec; + return utv.tv_sec; } psi_timeval &PsiTime::getPsiTimeval(void) { - return ptv; + return ptv; } const unsigned long PsiTime::getPsiTimeLo(void) { - return ptv.tv_low; + return ptv.tv_low; } const unsigned long PsiTime::getPsiTimeHi(void) { - return ptv.tv_high; + return ptv.tv_high; } PsiTime &PsiTime::operator=(const PsiTime &t) { - utv = t.utv; - utz = t.utz; - ptv = t.ptv; - ptz = t.ptz; - ptzValid = t.ptzValid; - tryPsiZone(); - return *this; + utv = t.utv; + utz = t.utz; + ptv = t.ptv; + ptz = t.ptz; + ptzValid = t.ptzValid; + tryPsiZone(); + return *this; } ostream &operator<<(ostream &s, const PsiTime &t) { - const char *fmt = "%c"; - char buf[100]; - strftime(buf, sizeof(buf), fmt, localtime(&t.utv.tv_sec)); - s << buf; - return s; + const char *fmt = "%c"; + char buf[100]; + strftime(buf, sizeof(buf), fmt, localtime(&t.utv.tv_sec)); + s << buf; + return s; } /** @@ -147,93 +168,99 @@ ostream &operator<<(ostream &s, const PsiTime &t) { static unsigned long long evalOffset(psi_timezone ptz, time_t time, bool valid) { - unsigned long long offset = 0; - - if (valid) { - offset = ptz.utc_offset; - if (!(ptz.dst_zones & 0x40000000) || (ptz.dst_zones & ptz.home_zone)) - offset += 3600; + unsigned long long offset = 0; + + if (valid) { + offset = ptz.utc_offset; + if (!(ptz.dst_zones & 0x40000000) || (ptz.dst_zones & ptz.home_zone)) + offset += 3600; + } else { + /** + * Fallback. If no Psion zone given, use + * environment variable PSI_TZ + */ + const char *offstr = getenv("PSI_TZ"); + if (offstr != 0L) { + char *err = 0L; + offset = strtoul(offstr, &err, 0); + if (err != 0L && *err != '\0') + offset = 0; } else { - /** - * Fallback. If no Psion zone given, use - * environment variable PSI_TZ - */ - const char *offstr = getenv("PSI_TZ"); - if (offstr != 0L) { - char *err = 0L; - offset = strtoul(offstr, &err, 0); - if (err != 0L && *err != '\0') - offset = 0; - } else { - /** - * Fallback. If PSI_TZ is not set, - * use the local timezone. This assumes, - * that both Psion and local machine are - * configured for the same timezone and - * daylight saving. - */ - struct tm *tm = localtime(&time); - offset = timezone; - if (tm->tm_isdst) - offset += 3600; - } + /** + * Fallback. If PSI_TZ is not set, + * use the local timezone. This assumes, + * that both Psion and local machine are + * configured for the same timezone and + * daylight saving. + */ + struct tm *tm = localtime(&time); + offset = timezone; + if (tm->tm_isdst) + offset += 3600; } - offset *= 1000000; - return offset; + } + offset *= 1000000; + return offset; } void PsiTime::psi2unix(void) { - unsigned long long micro = ptv.tv_high; - micro = (micro << 32) | ptv.tv_low; + unsigned long long micro = ptv.tv_high; + micro = (micro << 32) | ptv.tv_low; - /* Substract Psion's idea of UTC offset */ - micro -= EPOCH_DIFF; - micro -= evalOffset(ptz, micro / 1000000, ptzValid); + /* Substract Psion's idea of UTC offset */ + micro -= EPOCH_DIFF; + micro -= evalOffset(ptz, micro / 1000000, ptzValid); - utv.tv_sec = micro / 1000000; - utv.tv_usec = micro % 1000000; + utv.tv_sec = micro / 1000000; + utv.tv_usec = micro % 1000000; } void PsiTime::unix2psi(void) { - unsigned long long micro = utv.tv_sec * 1000000 + utv.tv_usec; + unsigned long long micro = utv.tv_sec * 1000000 + utv.tv_usec; - /* Add Psion's idea of UTC offset */ - micro += evalOffset(ptz, utv.tv_sec, ptzValid); - micro += EPOCH_DIFF; + /* Add Psion's idea of UTC offset */ + micro += evalOffset(ptz, utv.tv_sec, ptzValid); + micro += EPOCH_DIFF; - ptv.tv_low = micro & 0x0ffffffff; - ptv.tv_high = (micro >> 32) & 0x0ffffffff; + ptv.tv_low = micro & 0x0ffffffff; + ptv.tv_high = (micro >> 32) & 0x0ffffffff; } void PsiTime::tryPsiZone() { - if (ptzValid) - return; - if (PsiZone::getInstance().getZone(ptz)) - ptzValid = true; + if (ptzValid) + return; + if (PsiZone::getInstance().getZone(ptz)) + ptzValid = true; } PsiZone *PsiZone::_instance = 0L; PsiZone &PsiZone:: getInstance() { - if (_instance == 0L) - _instance = new PsiZone(); - return *_instance; + if (_instance == 0L) + _instance = new PsiZone(); + return *_instance; } PsiZone::PsiZone() { - _ptzValid = false; + _ptzValid = false; } void PsiZone:: setZone(psi_timezone &ptz) { - _ptz = ptz; - _ptzValid = true; + _ptz = ptz; + _ptzValid = true; } bool PsiZone:: getZone(psi_timezone &ptz) { - if (_ptzValid) - ptz = _ptz; - return _ptzValid; + if (_ptzValid) + ptz = _ptz; + return _ptzValid; } + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ diff --git a/lib/psitime.h b/lib/psitime.h index 2b26379..a6c4f4f 100644 --- a/lib/psitime.h +++ b/lib/psitime.h @@ -1,10 +1,37 @@ +/*-*-c++-*- + * $Id$ + * + * This file is part of plptools. + * + * Copyright (C) 2000-2001 Fritz Elfert <felfert@to.com> + * + * 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 _PSITIME_H_ #define _PSITIME_H_ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + #include <sys/time.h> #include <unistd.h> #include <ostream.h> +#include <intl.h> /** * Holds a Psion time value. @@ -13,63 +40,63 @@ * since 01.01.0001 in microseconds. */ typedef struct psi_timeval_t { - /** - * Prints a psi_timeval in human readable format. - */ - friend ostream &operator<<(ostream &o, const psi_timeval_t &ptv) { - ostream::fmtflags old = o.flags(); - unsigned long long micro = ptv.tv_high; - micro = (micro << 32) | ptv.tv_low; - micro /= 1000000; - int s = micro % 60; - micro /= 60; - int m = micro % 60; - micro /= 60; - int h = micro % 24; - micro /= 24; - int d = micro % 365; - micro /= 365; - int y = micro; - o << dec; - if (y > 0) - o << y << " year" << ((y > 1) ? "s " : " "); - if (d > 0) - o << d << " day" << ((d > 1) ? "s " : " "); - if (h > 0) - o << h << " hour" << ((h != 1) ? "s " : " "); - if (m > 0) - o << m << " minute" << ((m != 1) ? "s " : " "); - o << s << " second" << ((s != 1) ? "s" : ""); - o.flags(old); - return o; - } - /** - * The lower 32 bits - */ - unsigned long tv_low; - /** - * The upper 32 bits - */ - unsigned long tv_high; + /** + * Prints a psi_timeval in human readable format. + */ + friend ostream &operator<<(ostream &o, const psi_timeval_t &ptv) { + ostream::fmtflags old = o.flags(); + unsigned long long micro = ptv.tv_high; + micro = (micro << 32) | ptv.tv_low; + micro /= 1000000; + int s = micro % 60; + micro /= 60; + int m = micro % 60; + micro /= 60; + int h = micro % 24; + micro /= 24; + int d = micro % 365; + micro /= 365; + int y = micro; + o << dec; + if (y > 0) + o << y << ((y > 1) ? _(" years ") : _(" year ")); + if (d > 0) + o << d << ((d > 1) ? _(" days ") : _(" day ")); + if (h > 0) + o << h << ((h != 1) ? _(" hours ") : _(" hour ")); + if (m > 0) + o << m << ((m != 1) ? _(" minutes ") : _(" minute ")); + o << s << ((s != 1) ? _(" seconds") : _(" second")); + o.flags(old); + return o; + } + /** + * The lower 32 bits + */ + unsigned long tv_low; + /** + * The upper 32 bits + */ + unsigned long tv_high; } psi_timeval; /** * holds a Psion time zone description. */ typedef struct psi_timezone_t { - friend ostream &operator<<(ostream &s, const psi_timezone_t &ptz) { - ostream::fmtflags old = s.flags(); - int h = ptz.utc_offset / 3600; - int m = ptz.utc_offset % 3600; - s << "offs: " << dec << h << "h"; - if (m != 0) - s << ", " << m << "m"; - s.flags(old); - return s; - } - unsigned long utc_offset; - unsigned long dst_zones; - unsigned long home_zone; + friend ostream &operator<<(ostream &s, const psi_timezone_t &ptz) { + ostream::fmtflags old = s.flags(); + int h = ptz.utc_offset / 3600; + int m = ptz.utc_offset % 3600; + s << "offs: " << dec << h << "h"; + if (m != 0) + s << ", " << m << "m"; + s.flags(old); + return s; + } + unsigned long utc_offset; + unsigned long dst_zones; + unsigned long home_zone; } psi_timezone; /** @@ -98,169 +125,171 @@ typedef struct psi_timezone_t { */ class PsiTime { public: - /** - * Contructs a new instance. - * - * @param _utv A Unix time value for initialization. - * @param _utz A Unix timezone for initialization. - */ - PsiTime(struct timeval *_utv, struct timezone *_utz = 0L); - - /** - * Contructs a new instance. - * - * @param time A Unix time value for initialization. - */ - PsiTime(time_t time); - - /** - * Contructs a new instance. - * - * @param _ptv A Psion time value for initialization. - * @param _ptz A Psion timezone for initialization. - */ - PsiTime(psi_timeval *_ptv, psi_timezone *_ptz = 0L); - - /** - * Contructs a new instance. - * - * @param _ptvHi The high 16 bits of a Psion time value for initialization. - * @param _ptvLo The low 16 bits of a Psion time value for initialization. - */ - PsiTime(const unsigned long _ptvHi, const unsigned long _ptvLo); - - /** - * Constructs a new instance, initializing to now. - */ - PsiTime(void); - - /** - * A copy-constructor - */ - PsiTime(const PsiTime &t); - - /** - * Destroys the instance. - */ - ~PsiTime(); - - /** - * Modifies the value of this instance. - * - * @param _ptv The new Psion time representation. - */ - void setPsiTime(psi_timeval *_ptv); - - /** - * Modifies the value of this instance. - * - * @param _ptvHi The high 32 bits of a Psion time. - * @param _ptvLo The low 32 bits of a Psion time. - */ - void setPsiTime(const unsigned long _ptvHi, const unsigned long _ptvLo); - - /** - * Sets the Psion time zone of this instance. - * - * @param _ptz The new Psion time zone. - */ - void setPsiZone(psi_timezone *_ptz); - - /** - * Sets the value of this instance. - * - * @param _utv The new Unix time representation. - */ - void setUnixTime(struct timeval *_utv); - - /** - * Sets the value of this instance. - * - * @param _utv The new Unix time representation. - */ - void setUnixTime(time_t time); - - /** - * Sets the value of this instance to the - * current time of the Unix machine. - */ - void setUnixNow(void); - - /** - * Retrieves the instance's current value - * in Unix time format. - * - * @returns The instance's current time as Unix struct timeval. - */ - struct timeval &getTimeval(void); - - /** - * Retrieves the instance's current value - * in Unix time format. - * - * @returns The instance's current time as Unix time_t. - */ - time_t getTime(void); - - /** - * Retrieves the instance's current value - * in Psion time format. - * - * @returns The instance's current time a Psion struct psi_timeval_t. - */ - psi_timeval &getPsiTimeval(void); - - /** - * Retrieves the instance's current value - * in Psion time format, high 32 bits. - * - * @returns The instance's current time as lower 32 bits of a Psion struct psi_timeval_t. - */ - const unsigned long getPsiTimeLo(void); - - /** - * Retrieves the instance's current value - * in Psion time format, low 32 bits. - * - * @returns The instance's current time as upper 32 bits of a Psion struct psi_timeval_t. - */ - const unsigned long getPsiTimeHi(void); - - /** - * Prints the instance's value in human readable format. - * This function uses the current locale setting for - * formatting the time. - * - * @param s The stream to be written. - * @param t The instance whose value should be displayed. - * - * @returns The stream. - */ - friend ostream &operator<<(ostream &s, const PsiTime &t); - - /** - * Assignment operator - */ - PsiTime &operator=(const PsiTime &t); - - enum zone { - PSI_TZ_NONE = 0, - PSI_TZ_EUROPEAN = 1, - PSI_TZ_NORTHERN = 2, - PSI_TZ_SOUTHERN = 4, - PSI_TZ_HOME = 0x40000000, - }; + /** + * Contructs a new instance. + * + * @param _utv A Unix time value for initialization. + * @param _utz A Unix timezone for initialization. + */ + PsiTime(struct timeval *_utv, struct timezone *_utz = 0L); + + /** + * Contructs a new instance. + * + * @param time A Unix time value for initialization. + */ + PsiTime(time_t time); + + /** + * Contructs a new instance. + * + * @param _ptv A Psion time value for initialization. + * @param _ptz A Psion timezone for initialization. + */ + PsiTime(psi_timeval *_ptv, psi_timezone *_ptz = 0L); + + /** + * Contructs a new instance. + * + * @param _ptvHi The high 16 bits of a Psion time value for initialization. + * @param _ptvLo The low 16 bits of a Psion time value for initialization. + */ + PsiTime(const unsigned long _ptvHi, const unsigned long _ptvLo); + + /** + * Constructs a new instance, initializing to now. + */ + PsiTime(void); + + /** + * A copy-constructor + */ + PsiTime(const PsiTime &t); + + /** + * Destroys the instance. + */ + ~PsiTime(); + + /** + * Modifies the value of this instance. + * + * @param _ptv The new Psion time representation. + */ + void setPsiTime(psi_timeval *_ptv); + + /** + * Modifies the value of this instance. + * + * @param _ptvHi The high 32 bits of a Psion time. + * @param _ptvLo The low 32 bits of a Psion time. + */ + void setPsiTime(const unsigned long _ptvHi, const unsigned long _ptvLo); + + /** + * Sets the Psion time zone of this instance. + * + * @param _ptz The new Psion time zone. + */ + void setPsiZone(psi_timezone *_ptz); + + /** + * Sets the value of this instance. + * + * @param _utv The new Unix time representation. + */ + void setUnixTime(struct timeval *_utv); + + /** + * Sets the value of this instance. + * + * @param _utv The new Unix time representation. + */ + void setUnixTime(time_t time); + + /** + * Sets the value of this instance to the + * current time of the Unix machine. + */ + void setUnixNow(void); + + /** + * Retrieves the instance's current value + * in Unix time format. + * + * @returns The instance's current time as Unix struct timeval. + */ + struct timeval &getTimeval(void); + + /** + * Retrieves the instance's current value + * in Unix time format. + * + * @returns The instance's current time as Unix time_t. + */ + time_t getTime(void); + + /** + * Retrieves the instance's current value + * in Psion time format. + * + * @returns The instance's current time a Psion struct psi_timeval_t. + */ + psi_timeval &getPsiTimeval(void); + + /** + * Retrieves the instance's current value + * in Psion time format, high 32 bits. + * + * @returns The instance's current time as lower 32 bits of + * a Psion struct psi_timeval_t. + */ + const unsigned long getPsiTimeLo(void); + + /** + * Retrieves the instance's current value + * in Psion time format, low 32 bits. + * + * @returns The instance's current time as upper 32 bits of + * a Psion struct psi_timeval_t. + */ + const unsigned long getPsiTimeHi(void); + + /** + * Prints the instance's value in human readable format. + * This function uses the current locale setting for + * formatting the time. + * + * @param s The stream to be written. + * @param t The instance whose value should be displayed. + * + * @returns The stream. + */ + friend ostream &operator<<(ostream &s, const PsiTime &t); + + /** + * Assignment operator + */ + PsiTime &operator=(const PsiTime &t); + + enum zone { + PSI_TZ_NONE = 0, + PSI_TZ_EUROPEAN = 1, + PSI_TZ_NORTHERN = 2, + PSI_TZ_SOUTHERN = 4, + PSI_TZ_HOME = 0x40000000, + }; private: - void psi2unix(void); - void unix2psi(void); - void tryPsiZone(); - - psi_timeval ptv; - psi_timezone ptz; - struct timeval utv; - struct timezone utz; - bool ptzValid; + void psi2unix(void); + void unix2psi(void); + void tryPsiZone(); + + psi_timeval ptv; + psi_timezone ptz; + struct timeval utv; + struct timezone utz; + bool ptzValid; }; /** @@ -274,39 +303,45 @@ private: * @author Fritz Elfert <felfert@to.com> */ class PsiZone { - friend class rpcs32; + friend class rpcs32; public: - /** - * Retrieve the singleton object. - * If it does not exist, it is created. - */ - static PsiZone &getInstance(); - - /** - * Retrieve the Psion's time zone. - * - * @param ptz The time zone is returned here. - * - * @returns false, if the time zone is not - * known (yet). - */ - bool getZone(psi_timezone &ptz); + /** + * Retrieve the singleton object. + * If it does not exist, it is created. + */ + static PsiZone &getInstance(); + + /** + * Retrieve the Psion time zone. + * + * @param ptz The time zone is returned here. + * + * @returns false, if the time zone is not + * known (yet). + */ + bool getZone(psi_timezone &ptz); private: - /** - * This objects instance (singleton) - */ - static PsiZone *_instance; + /** + * This objects instance (singleton) + */ + static PsiZone *_instance; - /** - * Private constructor. - */ - PsiZone(); + /** + * Private constructor. + */ + PsiZone(); - void setZone(psi_timezone &ptz); + void setZone(psi_timezone &ptz); - bool _ptzValid; - psi_timezone _ptz; + bool _ptzValid; + psi_timezone _ptz; }; #endif + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ diff --git a/lib/rfsv.cc b/lib/rfsv.cc index 30fd502..f9f2075 100644 --- a/lib/rfsv.cc +++ b/lib/rfsv.cc @@ -1,150 +1,175 @@ +/*-*-c++-*- + * $Id$ + * + * This file is part of plptools. + * + * Copyright (C) 1999 Philip Proudman <philip.proudman@btinternet.com> + * Copyright (C) 1999 Matt J. Gumbley <matt@gumbley.demon.co.uk> + * Copyright (C) 1999-2001 Fritz Elfert <felfert@to.com> + * + * 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 "rfsv.h" #include "ppsocket.h" #include "bufferstore.h" #include "Enum.h" ENUM_DEFINITION(rfsv::errs, rfsv::E_PSI_GEN_NONE) { - stringRep.add(rfsv::E_PSI_GEN_NONE, "no error"); - stringRep.add(rfsv::E_PSI_GEN_FAIL, "general"); - stringRep.add(rfsv::E_PSI_GEN_ARG, "bad argument"); - stringRep.add(rfsv::E_PSI_GEN_OS, "OS error"); - stringRep.add(rfsv::E_PSI_GEN_NSUP, "not supported"); - stringRep.add(rfsv::E_PSI_GEN_UNDER, "numeric underflow"); - stringRep.add(rfsv::E_PSI_GEN_OVER, "numeric overflow"); - stringRep.add(rfsv::E_PSI_GEN_RANGE, "numeric exception"); - stringRep.add(rfsv::E_PSI_GEN_INUSE, "in use"); - stringRep.add(rfsv::E_PSI_GEN_NOMEMORY, "out of memory"); - stringRep.add(rfsv::E_PSI_GEN_NOSEGMENTS, "out of segments"); - stringRep.add(rfsv::E_PSI_GEN_NOSEM, "out of semaphores"); - stringRep.add(rfsv::E_PSI_GEN_NOPROC, "out of processes"); - stringRep.add(rfsv::E_PSI_GEN_OPEN, "already open"); - stringRep.add(rfsv::E_PSI_GEN_NOTOPEN, "not open"); - stringRep.add(rfsv::E_PSI_GEN_IMAGE, "bad image"); - stringRep.add(rfsv::E_PSI_GEN_RECEIVER, "receiver error"); - stringRep.add(rfsv::E_PSI_GEN_DEVICE, "device error"); - stringRep.add(rfsv::E_PSI_GEN_FSYS, "no filesystem"); - stringRep.add(rfsv::E_PSI_GEN_START, "not ready"); - stringRep.add(rfsv::E_PSI_GEN_NOFONT, "no font"); - stringRep.add(rfsv::E_PSI_GEN_TOOWIDE, "too wide"); - stringRep.add(rfsv::E_PSI_GEN_TOOMANY, "too many"); - stringRep.add(rfsv::E_PSI_FILE_EXIST, "file already exists"); - stringRep.add(rfsv::E_PSI_FILE_NXIST, "no such file"); - stringRep.add(rfsv::E_PSI_FILE_WRITE, "write error"); - stringRep.add(rfsv::E_PSI_FILE_READ, "read error"); - stringRep.add(rfsv::E_PSI_FILE_EOF, "end of file"); - stringRep.add(rfsv::E_PSI_FILE_FULL, "disk/serial read buffer full"); - stringRep.add(rfsv::E_PSI_FILE_NAME, "invalid name"); - stringRep.add(rfsv::E_PSI_FILE_ACCESS, "access denied"); - stringRep.add(rfsv::E_PSI_FILE_LOCKED, "ressource locked"); - stringRep.add(rfsv::E_PSI_FILE_DEVICE, "no such device"); - stringRep.add(rfsv::E_PSI_FILE_DIR, "no such directory"); - stringRep.add(rfsv::E_PSI_FILE_RECORD, "no such record"); - stringRep.add(rfsv::E_PSI_FILE_RDONLY, "file is read-only"); - stringRep.add(rfsv::E_PSI_FILE_INV, "invalid I/O operation"); - stringRep.add(rfsv::E_PSI_FILE_PENDING, "I/O pending (not yet completed)"); - stringRep.add(rfsv::E_PSI_FILE_VOLUME, "invalid volume name"); - stringRep.add(rfsv::E_PSI_FILE_CANCEL, "cancelled"); - stringRep.add(rfsv::E_PSI_FILE_ALLOC, "no memory for control block"); - stringRep.add(rfsv::E_PSI_FILE_DISC, "unit disconnected"); - stringRep.add(rfsv::E_PSI_FILE_CONNECT, "already connected"); - stringRep.add(rfsv::E_PSI_FILE_RETRAN, "retransmission threshold exceeded"); - stringRep.add(rfsv::E_PSI_FILE_LINE, "physical link failure"); - stringRep.add(rfsv::E_PSI_FILE_INACT, "inactivity timer expired"); - stringRep.add(rfsv::E_PSI_FILE_PARITY, "serial parity error"); - stringRep.add(rfsv::E_PSI_FILE_FRAME, "serial framing error"); - stringRep.add(rfsv::E_PSI_FILE_OVERRUN, "serial overrun error"); - stringRep.add(rfsv::E_PSI_MDM_CONFAIL, "modem cannot connect to remote modem"); - stringRep.add(rfsv::E_PSI_MDM_BUSY, "remote modem busy"); - stringRep.add(rfsv::E_PSI_MDM_NOANS, "remote modem did not answer"); - stringRep.add(rfsv::E_PSI_MDM_BLACKLIST, "number blacklisted by the modem"); - stringRep.add(rfsv::E_PSI_FILE_NOTREADY, "drive not ready"); - stringRep.add(rfsv::E_PSI_FILE_UNKNOWN, "unknown media"); - stringRep.add(rfsv::E_PSI_FILE_DIRFULL, "directory full"); - stringRep.add(rfsv::E_PSI_FILE_PROTECT, "write-protected"); - stringRep.add(rfsv::E_PSI_FILE_CORRUPT, "media corrupt"); - stringRep.add(rfsv::E_PSI_FILE_ABORT, "aborted operation"); - stringRep.add(rfsv::E_PSI_FILE_ERASE, "failed to erase flash media"); - stringRep.add(rfsv::E_PSI_FILE_INVALID, "invalid file for DBF system"); - stringRep.add(rfsv::E_PSI_GEN_POWER, "power failure"); - stringRep.add(rfsv::E_PSI_FILE_TOOBIG, "too big"); - stringRep.add(rfsv::E_PSI_GEN_DESCR, "bad descriptor"); - stringRep.add(rfsv::E_PSI_GEN_LIB, "bad entry point"); - stringRep.add(rfsv::E_PSI_FILE_NDISC, "could not diconnect"); - stringRep.add(rfsv::E_PSI_FILE_DRIVER, "bad driver"); - stringRep.add(rfsv::E_PSI_FILE_COMPLETION, "operation not completed"); - stringRep.add(rfsv::E_PSI_GEN_BUSY, "server busy"); - stringRep.add(rfsv::E_PSI_GEN_TERMINATED, "terminated"); - stringRep.add(rfsv::E_PSI_GEN_DIED, "died"); - stringRep.add(rfsv::E_PSI_FILE_HANDLE, "bad handle"); - stringRep.add(rfsv::E_PSI_NOT_SIBO, "invalid operation for RFSV16"); - stringRep.add(rfsv::E_PSI_INTERNAL, "libplp internal error"); + stringRep.add(rfsv::E_PSI_GEN_NONE, N_("no error")); + stringRep.add(rfsv::E_PSI_GEN_FAIL, N_("general")); + stringRep.add(rfsv::E_PSI_GEN_ARG, N_("bad argument")); + stringRep.add(rfsv::E_PSI_GEN_OS, N_("OS error")); + stringRep.add(rfsv::E_PSI_GEN_NSUP, N_("not supported")); + stringRep.add(rfsv::E_PSI_GEN_UNDER, N_("numeric underflow")); + stringRep.add(rfsv::E_PSI_GEN_OVER, N_("numeric overflow")); + stringRep.add(rfsv::E_PSI_GEN_RANGE, N_("numeric exception")); + stringRep.add(rfsv::E_PSI_GEN_INUSE, N_("in use")); + stringRep.add(rfsv::E_PSI_GEN_NOMEMORY, N_("out of memory")); + stringRep.add(rfsv::E_PSI_GEN_NOSEGMENTS, N_("out of segments")); + stringRep.add(rfsv::E_PSI_GEN_NOSEM, N_("out of semaphores")); + stringRep.add(rfsv::E_PSI_GEN_NOPROC, N_("out of processes")); + stringRep.add(rfsv::E_PSI_GEN_OPEN, N_("already open")); + stringRep.add(rfsv::E_PSI_GEN_NOTOPEN, N_("not open")); + stringRep.add(rfsv::E_PSI_GEN_IMAGE, N_("bad image")); + stringRep.add(rfsv::E_PSI_GEN_RECEIVER, N_("receiver error")); + stringRep.add(rfsv::E_PSI_GEN_DEVICE, N_("device error")); + stringRep.add(rfsv::E_PSI_GEN_FSYS, N_("no filesystem")); + stringRep.add(rfsv::E_PSI_GEN_START, N_("not ready")); + stringRep.add(rfsv::E_PSI_GEN_NOFONT, N_("no font")); + stringRep.add(rfsv::E_PSI_GEN_TOOWIDE, N_("too wide")); + stringRep.add(rfsv::E_PSI_GEN_TOOMANY, N_("too many")); + stringRep.add(rfsv::E_PSI_FILE_EXIST, N_("file already exists")); + stringRep.add(rfsv::E_PSI_FILE_NXIST, N_("no such file")); + stringRep.add(rfsv::E_PSI_FILE_WRITE, N_("write error")); + stringRep.add(rfsv::E_PSI_FILE_READ, N_("read error")); + stringRep.add(rfsv::E_PSI_FILE_EOF, N_("end of file")); + stringRep.add(rfsv::E_PSI_FILE_FULL, N_("disk/serial read buffer full")); + stringRep.add(rfsv::E_PSI_FILE_NAME, N_("invalid name")); + stringRep.add(rfsv::E_PSI_FILE_ACCESS, N_("access denied")); + stringRep.add(rfsv::E_PSI_FILE_LOCKED, N_("ressource locked")); + stringRep.add(rfsv::E_PSI_FILE_DEVICE, N_("no such device")); + stringRep.add(rfsv::E_PSI_FILE_DIR, N_("no such directory")); + stringRep.add(rfsv::E_PSI_FILE_RECORD, N_("no such record")); + stringRep.add(rfsv::E_PSI_FILE_RDONLY, N_("file is read-only")); + stringRep.add(rfsv::E_PSI_FILE_INV, N_("invalid I/O operation")); + stringRep.add(rfsv::E_PSI_FILE_PENDING, N_("I/O pending (not yet completed)")); + stringRep.add(rfsv::E_PSI_FILE_VOLUME, N_("invalid volume name")); + stringRep.add(rfsv::E_PSI_FILE_CANCEL, N_("cancelled")); + stringRep.add(rfsv::E_PSI_FILE_ALLOC, N_("no memory for control block")); + stringRep.add(rfsv::E_PSI_FILE_DISC, N_("unit disconnected")); + stringRep.add(rfsv::E_PSI_FILE_CONNECT, N_("already connected")); + stringRep.add(rfsv::E_PSI_FILE_RETRAN, N_("retransmission threshold exceeded")); + stringRep.add(rfsv::E_PSI_FILE_LINE, N_("physical link failure")); + stringRep.add(rfsv::E_PSI_FILE_INACT, N_("inactivity timer expired")); + stringRep.add(rfsv::E_PSI_FILE_PARITY, N_("serial parity error")); + stringRep.add(rfsv::E_PSI_FILE_FRAME, N_("serial framing error")); + stringRep.add(rfsv::E_PSI_FILE_OVERRUN, N_("serial overrun error")); + stringRep.add(rfsv::E_PSI_MDM_CONFAIL, N_("modem cannot connect to remote modem")); + stringRep.add(rfsv::E_PSI_MDM_BUSY, N_("remote modem busy")); + stringRep.add(rfsv::E_PSI_MDM_NOANS, N_("remote modem did not answer")); + stringRep.add(rfsv::E_PSI_MDM_BLACKLIST, N_("number blacklisted by the modem")); + stringRep.add(rfsv::E_PSI_FILE_NOTREADY, N_("drive not ready")); + stringRep.add(rfsv::E_PSI_FILE_UNKNOWN, N_("unknown media")); + stringRep.add(rfsv::E_PSI_FILE_DIRFULL, N_("directory full")); + stringRep.add(rfsv::E_PSI_FILE_PROTECT, N_("write-protected")); + stringRep.add(rfsv::E_PSI_FILE_CORRUPT, N_("media corrupt")); + stringRep.add(rfsv::E_PSI_FILE_ABORT, N_("aborted operation")); + stringRep.add(rfsv::E_PSI_FILE_ERASE, N_("failed to erase flash media")); + stringRep.add(rfsv::E_PSI_FILE_INVALID, N_("invalid file for DBF system")); + stringRep.add(rfsv::E_PSI_GEN_POWER, N_("power failure")); + stringRep.add(rfsv::E_PSI_FILE_TOOBIG, N_("too big")); + stringRep.add(rfsv::E_PSI_GEN_DESCR, N_("bad descriptor")); + stringRep.add(rfsv::E_PSI_GEN_LIB, N_("bad entry point")); + stringRep.add(rfsv::E_PSI_FILE_NDISC, N_("could not diconnect")); + stringRep.add(rfsv::E_PSI_FILE_DRIVER, N_("bad driver")); + stringRep.add(rfsv::E_PSI_FILE_COMPLETION, N_("operation not completed")); + stringRep.add(rfsv::E_PSI_GEN_BUSY, N_("server busy")); + stringRep.add(rfsv::E_PSI_GEN_TERMINATED, N_("terminated")); + stringRep.add(rfsv::E_PSI_GEN_DIED, N_("died")); + stringRep.add(rfsv::E_PSI_FILE_HANDLE, N_("bad handle")); + stringRep.add(rfsv::E_PSI_NOT_SIBO, N_("invalid operation for RFSV16")); + stringRep.add(rfsv::E_PSI_INTERNAL, N_("libplp internal error")); } const char *rfsv::getConnectName(void) { - return "SYS$RFSV"; + return "SYS$RFSV"; } rfsv::~rfsv() { - bufferStore a; - a.addStringT("Close"); - if (status == E_PSI_GEN_NONE) - skt->sendBufferStore(a); - skt->closeSocket(); + skt->closeSocket(); } void rfsv::reconnect(void) { - skt->closeSocket(); - skt->reconnect(); - serNum = 0; - reset(); + //skt->closeSocket(); + skt->reconnect(); + serNum = 0; + reset(); } void rfsv::reset(void) { - bufferStore a; - status = E_PSI_FILE_DISC; - a.addStringT(getConnectName()); - if (skt->sendBufferStore(a)) { - if (skt->getBufferStore(a) == 1) { - if (!strcmp(a.getString(0), "Ok")) - status = E_PSI_GEN_NONE; - } + bufferStore a; + status = E_PSI_FILE_DISC; + a.addStringT(getConnectName()); + if (skt->sendBufferStore(a)) { + if (skt->getBufferStore(a) == 1) { + if (!strcmp(a.getString(0), "Ok")) + status = E_PSI_GEN_NONE; } + } } Enum<rfsv::errs> rfsv::getStatus(void) { - return status; + return status; } string rfsv:: convertSlash(const string &name) { - string tmp = ""; - for (const char *p = name.c_str(); *p; p++) - tmp += (*p == '/') ? '\\' : *p; - return tmp; + string tmp = ""; + for (const char *p = name.c_str(); *p; p++) + tmp += (*p == '/') ? '\\' : *p; + return tmp; } string rfsv:: attr2String(const u_int32_t attr) { - string tmp = ""; - tmp += ((attr & PSI_A_DIR) ? 'd' : '-'); - tmp += ((attr & PSI_A_READ) ? 'r' : '-'); - tmp += ((attr & PSI_A_RDONLY) ? '-' : 'w'); - tmp += ((attr & PSI_A_HIDDEN) ? 'h' : '-'); - tmp += ((attr & PSI_A_SYSTEM) ? 's' : '-'); - tmp += ((attr & PSI_A_ARCHIVE) ? 'a' : '-'); - tmp += ((attr & PSI_A_VOLUME) ? 'v' : '-'); + string tmp = ""; + tmp += ((attr & PSI_A_DIR) ? 'd' : '-'); + tmp += ((attr & PSI_A_READ) ? 'r' : '-'); + tmp += ((attr & PSI_A_RDONLY) ? '-' : 'w'); + tmp += ((attr & PSI_A_HIDDEN) ? 'h' : '-'); + tmp += ((attr & PSI_A_SYSTEM) ? 's' : '-'); + tmp += ((attr & PSI_A_ARCHIVE) ? 'a' : '-'); + tmp += ((attr & PSI_A_VOLUME) ? 'v' : '-'); - // EPOC - tmp += ((attr & PSI_A_NORMAL) ? 'n' : '-'); - tmp += ((attr & PSI_A_TEMP) ? 't' : '-'); - tmp += ((attr & PSI_A_COMPRESSED) ? 'c' : '-'); - // SIBO - tmp[7] = ((attr & PSI_A_EXEC) ? 'x' : tmp[7]); - tmp[8] = ((attr & PSI_A_STREAM) ? 'b' : tmp[8]); - tmp[9] = ((attr & PSI_A_TEXT) ? 't' : tmp[9]); - return tmp; + // EPOC + tmp += ((attr & PSI_A_NORMAL) ? 'n' : '-'); + tmp += ((attr & PSI_A_TEMP) ? 't' : '-'); + tmp += ((attr & PSI_A_COMPRESSED) ? 'c' : '-'); + // SIBO + tmp[7] = ((attr & PSI_A_EXEC) ? 'x' : tmp[7]); + tmp[8] = ((attr & PSI_A_STREAM) ? 'b' : tmp[8]); + tmp[9] = ((attr & PSI_A_TEXT) ? 't' : tmp[9]); + return tmp; } +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ @@ -1,5 +1,28 @@ -#ifndef _rfsv_h_ -#define _rfsv_h_ +/*-*-c++-*- + * $Id$ + * + * This file is part of plptools. + * + * Copyright (C) 1999 Philip Proudman <philip.proudman@btinternet.com> + * Copyright (C) 1999-2001 Fritz Elfert <felfert@to.com> + * + * 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 _RFSV_H_ +#define _RFSV_H_ #include <deque> #include <string> @@ -30,12 +53,12 @@ class rfsv32; * @internal */ class rfsvDirhandle { - friend rfsv16; - friend rfsv32; + friend rfsv16; + friend rfsv32; - private: - u_int32_t h; - bufferStore b; +private: + u_int32_t h; + bufferStore b; }; /** @@ -52,534 +75,538 @@ class rfsvDirhandle { * currently connected. */ class rfsv { - public: - /** - * The kown modes for seek. - */ - enum seek_mode { - PSI_SEEK_SET = 1, - PSI_SEEK_CUR = 2, - PSI_SEEK_END = 3 - }; - - /** - * The known modes for file open. - */ - enum open_flags { - PSI_O_RDONLY = 0000, - PSI_O_WRONLY = 0001, - PSI_O_RDWR = 0002, - }; - - /** - * The known modes for file creation. - */ - enum open_mode { - PSI_O_CREAT = 00100, - PSI_O_EXCL = 00200, - PSI_O_TRUNC = 01000, - PSI_O_APPEND = 02000, - }; - - /** - * The known error codes. - */ - enum errs { - E_PSI_GEN_NONE = 0, - E_PSI_GEN_FAIL = -1, - E_PSI_GEN_ARG = -2, - E_PSI_GEN_OS = -3, - E_PSI_GEN_NSUP = -4, - E_PSI_GEN_UNDER = -5, - E_PSI_GEN_OVER = -6, - E_PSI_GEN_RANGE = -7, - E_PSI_GEN_DIVIDE = -8, - E_PSI_GEN_INUSE = -9, - E_PSI_GEN_NOMEMORY = - 10, - E_PSI_GEN_NOSEGMENTS = -11, - E_PSI_GEN_NOSEM = -12, - E_PSI_GEN_NOPROC = -13, - E_PSI_GEN_OPEN = -14, - E_PSI_GEN_NOTOPEN = -15, - E_PSI_GEN_IMAGE = -16, - E_PSI_GEN_RECEIVER = -17, - E_PSI_GEN_DEVICE = -18, - E_PSI_GEN_FSYS = -19, - E_PSI_GEN_START = -20, - E_PSI_GEN_NOFONT = -21, - E_PSI_GEN_TOOWIDE = -22, - E_PSI_GEN_TOOMANY = -23, - E_PSI_FILE_EXIST = -32, - E_PSI_FILE_NXIST = -33, - E_PSI_FILE_WRITE = -34, - E_PSI_FILE_READ = -35, - E_PSI_FILE_EOF = -36, - E_PSI_FILE_FULL = -37, - E_PSI_FILE_NAME = -38, - E_PSI_FILE_ACCESS = -39, - E_PSI_FILE_LOCKED = -40, - E_PSI_FILE_DEVICE = -41, - E_PSI_FILE_DIR = -42, - E_PSI_FILE_RECORD = -43, - E_PSI_FILE_RDONLY = -44, - E_PSI_FILE_INV = -45, - E_PSI_FILE_PENDING = -46, - E_PSI_FILE_VOLUME = -47, - E_PSI_FILE_CANCEL = -48, - E_PSI_FILE_ALLOC = -49, - E_PSI_FILE_DISC = -50, - E_PSI_FILE_CONNECT = -51, - E_PSI_FILE_RETRAN = -52, - E_PSI_FILE_LINE = -53, - E_PSI_FILE_INACT = -54, - E_PSI_FILE_PARITY = -55, - E_PSI_FILE_FRAME = -56, - E_PSI_FILE_OVERRUN = -57, - E_PSI_MDM_CONFAIL = -58, - E_PSI_MDM_BUSY = -59, - E_PSI_MDM_NOANS = -60, - E_PSI_MDM_BLACKLIST = -61, - E_PSI_FILE_NOTREADY = -62, - E_PSI_FILE_UNKNOWN = -63, - E_PSI_FILE_DIRFULL = -64, - E_PSI_FILE_PROTECT = -65, - E_PSI_FILE_CORRUPT = -66, - E_PSI_FILE_ABORT = -67, - E_PSI_FILE_ERASE = -68, - E_PSI_FILE_INVALID = -69, - E_PSI_GEN_POWER = -100, - E_PSI_FILE_TOOBIG = -101, - E_PSI_GEN_DESCR = -102, - E_PSI_GEN_LIB = -103, - E_PSI_FILE_NDISC = -104, - E_PSI_FILE_DRIVER = -105, - E_PSI_FILE_COMPLETION = -106, - E_PSI_GEN_BUSY = -107, - E_PSI_GEN_TERMINATED = -108, - E_PSI_GEN_DIED = -109, - E_PSI_FILE_HANDLE = -110, - - // Special error code for "Operation not permitted in RFSV16" - E_PSI_NOT_SIBO = -200, - // Special error code for "internal library error" - E_PSI_INTERNAL = -201 - }; - - /** - * The known file attributes - */ - enum file_attribs { - /** Attributes, valid on both <em>EPOC</em> and <em>SIBO</em>. */ - PSI_A_RDONLY = 0x0001, - PSI_A_HIDDEN = 0x0002, - PSI_A_SYSTEM = 0x0004, - PSI_A_DIR = 0x0008, - PSI_A_ARCHIVE = 0x0010, - PSI_A_VOLUME = 0x0020, - - /** Attributes, valid on EPOC <em>only</em>. */ - PSI_A_NORMAL = 0x0040, - PSI_A_TEMP = 0x0080, - PSI_A_COMPRESSED = 0x0100, - - /** Attributes, valid on SIBO <em>only</em>. */ - PSI_A_READ = 0x0200, - PSI_A_EXEC = 0x0400, - PSI_A_STREAM = 0x0800, - PSI_A_TEXT = 0x1000, - }; - - virtual ~rfsv(); - void reset(); - void reconnect(); - - /** - * Retrieves the current connection status. - * - * @returns The status of the connection. - */ - Enum<errs> getStatus(); - - /** - * Opens a file. - * - * @param attr The open mode. Use @ref opMode to convert a combination of @ref open_flags - * and @ref open_mode to the machine-specific representation. - * @param name The name of the file to open. - * @param handle The handle for usage with @ref fread , - * @ref fwrite , @ref fseek or @ref fclose is returned here. - * - * @returns A Psion error code (One of enum @ref #errs ). - */ - virtual Enum<errs> fopen(const u_int32_t attr, const char * const name, u_int32_t &handle) = 0; - - /** - * Creates a unique temporary file. - * The file is opened for reading and writing. - * - * @param handle The handle for usage with @ref fread , - * @ref fwrite , @ref fseek or @ref fclose is returned here. - * @param name The name of the temporary file is returned here. - * - * @returns A Psion error code (One of enum @ref #errs ). - */ - virtual Enum<errs> mktemp(u_int32_t &handle, string &name) = 0; - - /** - * Creates a named file. - * - * @param attr The open mode. Use @ref opMode to convert a combination of @ref open_flags - * and @ref open_mode to the machine-specific representation. - * @param name The name of the file to create. - * @param handle The handle for usage with @ref fread , - * @ref fwrite , @ref fseek or @ref fclose is returned here. - * - * @returns A Psion error code (One of enum @ref #errs ). - */ - virtual Enum<errs> fcreatefile(const u_int32_t attr, const char * const name, u_int32_t &handle) = 0; - - /** - * Creates an named file, overwriting an existing file. - * - * @param attr The open mode. Use @ref opMode to convert a combination of @ref open_flags - * and @ref open_mode to the machine-specific representation. - * @param name The name of the file to create. - * @param handle The handle for usage with @ref fread , - * @ref fwrite , @ref fseek or @ref fclose is returned here. - * - * @returns A Psion error code (One of enum @ref #errs ). - */ - virtual Enum<errs> freplacefile(const u_int32_t attr, const char * const name, u_int32_t &handle) = 0; - - /** - * Close a file on the Psion whih was previously opened/created by using - * @ref fopen , @ref fcreatefile , @ref freplacefile or @ref mktemp . - * - * @param handle A valid file handle. - */ - virtual Enum<errs> fclose(const u_int32_t handle) = 0; - - /** - * Reads a directory on the Psion. - * The returned STL deque of @ref PlpDirent contains all - * requested directory entries. - * - * @param name The name of the directory - * @param ret An STL deque of @ref PlpDirent entries. - * - * @returns A Psion error code (One of enum @ref rfsv::errs ). - */ - virtual Enum<errs> dir(const char * const name, PlpDir &ret) = 0; - - /** - * Retrieves the modification time of a file on the Psion. - * - * @param name Name of the file. - * @param mtime Modification time is returned here. - * - * @returns A Psion error code (One of enum @ref #errs ). - */ - virtual Enum<errs> fgetmtime(const char * const name, PsiTime &mtime) = 0; - - /** - * Sets the modification time of a file on the Psion. - * - * @param name Name of the file whose modification time should be set. - * @param mtime The desired modification time. - * - * @returns A Psion error code (One of enum @ref #errs ). - */ - virtual Enum<errs> fsetmtime(const char * const name, const PsiTime mtime) = 0; - - /** - * Retrieves attributes of a file on the Psion. - * - * @param name Name of the file whose attributes ar to be retrieved. - * @param attr The file's attributes are returned here. - * - * @returns A Psion error code (One of enum @ref #errs ). - */ - virtual Enum<errs> fgetattr(const char * const name, u_int32_t &attr) = 0; - - /** - * Retrieves attributes, size and modification time of a file on the Psion. - * - * @param name The name of the file. - * @param e @ref PlpDirent object, filled with the information on return. - * - * @returns A Psion error code (One of enum @ref #errs ). - */ - virtual Enum<errs> fgeteattr(const char * const name, PlpDirent &e) =0; - - /** - * @param name - * - * @returns A Psion error code (One of enum @ref #errs ). - */ - virtual Enum<errs> fsetattr(const char * const name, const u_int32_t seta, const u_int32_t unseta) = 0; - - /** - * Counts number of entries in a directory. - * - * @param name The directory whose entries are to be counted. - * @param count The number of entries is returned here. - * - * @returns A Psion error code (One of enum @ref #errs ). - */ - virtual Enum<errs> dircount(const char * const name, u_int32_t &count) = 0; - - /** - * Retrieves available drives on the Psion. - * - * @param devbits On return, for every exiting drive, a bit is set in this - * variable. The lowest bit represents drive A:. - * - * @returns A Psion error code (One of enum @ref #errs ). - */ - virtual Enum<errs> devlist(u_int32_t &devbits) = 0; - - /** - * Retrieves details about a drive. - * - * @param dev An integer, representing the drive to get details from. - * (0 represents A:, 1 is B: and so on ...) - * @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, PlpDrive &drive) = 0; - - /** - * Reads from a file on the Psion. - * - * @param handle Handle of the file to read from. - * @param buffer The area where to store the data read. - * @param len The number of bytes to read. - * @param count The number of bytes actually read is returned here. - * - * @returns A Psion error code (One of enum @ref #errs ). - */ - virtual Enum<errs> fread(const u_int32_t handle, unsigned char * const buffer, const u_int32_t len, u_int32_t &count) = 0; - - /** - * Write to a file on the Psion. - * - * @param handle Handle of the file to read from. - * @param buffer The area to be written. - * @param len The number of bytes to write. - * @param count The number of bytes actually written is returned here. - * - * @returns A Psion error code (One of enum @ref #errs ). - */ - virtual Enum<errs> fwrite(const u_int32_t handle, const unsigned char * const buffer, const u_int32_t len, u_int32_t &count) = 0; - - /** - * Copies a file from the Psion to the local machine. - * - * @param from Name of the file on the Psion to be copied. - * @param to Name of the destination file on the local machine. - * @param func Pointer to a function which gets called on every read. - * This function can be used to show some progress etc. May be set - * to NULL, where no callback is performed. - * - * @returns A Psion error code (One of enum @ref #errs ). - */ - virtual Enum<errs> copyFromPsion(const char *from, const char *to, void *, cpCallback_t func) = 0; - - /** - * Copies a file from local machine to the Psion. - * - * @param from Name of the file on the local machine to be copied. - * @param to Name of the destination file on the Psion. - * @param func Pointer to a function which gets called on every read. - * This function can be used to show some progress etc. May be set - * to NULL, where no callback is performed. - * - * @returns A Psion error code (One of enum @ref #errs ). - */ - virtual Enum<errs> copyToPsion(const char * const from, const char * const to, void *, cpCallback_t func) = 0; - - /** - * Copies a file from the Psion to the Psion. - * On the EPOC variants, this runs much faster than reading - * data from the Psion and then writing it back to the Psion, since - * data transfer is handled locally on the Psion. - * - * @param from Name of the file to be copied. - * @param to Name of the destination file. - * @param func Pointer to a function which gets called on every read. - * This function can be used to show some progress etc. May be set - * to NULL, where no callback is performed. - * - * @returns A Psion error code (One of enum @ref #errs ). - */ - virtual Enum<errs> copyOnPsion(const char * const from, const char * const to, void *, cpCallback_t func) = 0; - - /** - * Resizes an open file on the Psion. - * If the new size is greater than the file's - * current size, the contents of the added - * data is undefined. If The new size is smaller, - * the file is truncated. - * - * @param handle Handle of the file to be resized. - * @param size New size for that file. - * - * @returns A Psion error code (One of enum @ref #errs ). - */ - virtual Enum<errs> fsetsize(const u_int32_t handle, const u_int32_t size) = 0; - - /** - * Sets the current file position of a file on the Psion. - * - * @param handle The file handle. - * @param offset Position to be seeked to. - * @param mode The mode for seeking. - * @param resultpos The final file position after seeking is returned here. - * - * @returns A Psion error code (One of enum @ref #errs ). - */ - virtual Enum<errs> fseek(const u_int32_t handle, const int32_t offset, const u_int32_t mode, u_int32_t &resultpos) = 0; - - /** - * Creates a directory on the Psion. - * - * @param name Name of the directory to be created. - * - * @returns A Psion error code (One of enum @ref #errs ). - */ - virtual Enum<errs> mkdir(const char * const name) = 0; - - /** - * Removes a directory on the Psion. - * - * @param name Name of the directory to be removed. - * - * @returns A Psion error code (One of enum @ref #errs ). - */ - virtual Enum<errs> rmdir(const char * const name) = 0; - - /** - * Renames a file on the Psion. - * - * @param oldname Name of the file to be renamed. - * @param newname New Name for that file. - * - * @returns A Psion error code (One of enum @ref #errs ). - */ - virtual Enum<errs> rename(const char * const oldname, const char * const newname) = 0; - - /** - * Removes a file on the Psion. - * - * @param name Name of the file to be removed. - * - * @returns A Psion error code (One of enum @ref #errs ). - */ - virtual Enum<errs> remove(const char * const name) = 0; - - /** - * Open a directory for reading with readdir. - * - * @param attr A combination of PSI_A_.. flags, representing the desired types - * of entries to be returned when calling @ref readdir . - * @param name The name of the directory - * @param handle A handle to be used with @ref readdir and @ref closedir . - * - * @returns A Psion error code (One of enum @ref #errs ). - */ - virtual Enum<errs> opendir(const u_int32_t attr, const char * const name, rfsvDirhandle &handle) = 0; - - /** - * Read directory entries. - * This method reads entries of a directory, previously - * opened with @ref opendir . - * - * @param handle A handle, obtained by calling @ref opendir . - * @param entry The entry information is returned here. - * - * @returns A Psion error code (One of enum @ref #errs ). - */ - virtual Enum<errs> readdir(rfsvDirhandle &handle, PlpDirent &entry) = 0; - - /** - * Close a directory, previously opened with @ref opendir. - * - * @param handle A handle, obtained by calling @ref opendir . - * - * @returns A Psion error code (One of enum @ref #errs ). - */ - virtual Enum<errs> closedir(rfsvDirhandle &handle) = 0; - - /** - * Set the name of a Psion Volume (Drive). - * - * @param drive The drive character of the Volume, whose name should be set. - * @param name The new name for that drive. - * - * @returns A Psion error code (One of enum @ref #errs ). - */ - virtual Enum<errs> setVolumeName(const char drive, const char * const name) = 0; - - /** - * Converts a file attribute @ref rfsv::file_attribs to - * human readable format, usable for showing them in directory - * listings. The first 7 characters are common to all - * machine types: - * <pre> - * Char Nr. Value - * 0 'd' if a directory, '-' otherwise. - * 1 'r' if file is readable, '-' otherwise. - * 2 'w' if file is writeable, '-' otherwise. - * 3 'h' if file is hidden, '-' otherwise. - * 4 's' if file is a system file, '-' otherwise. - * 5 'a' if file is modified (archive flag), '-' otherwise. - * 6 'v' if file is a volume name, '-' otherwise. - * </pre> - * The rest (3 characters) are machine specific: - * <pre> - * Char Nr. EPOC Value SIBO Value - * 7 'n' if normal, 'x' if executable, '-' otherwise. - * 8 't' if temporary, 'b' if a stream, '-' otherwise. - * 8 'c' if compressed, 't' if a textfile, '-' otherwise. - * </pre> - * - * @param attr the generic file attribute. - * - * @returns Pointer to static textual representation of file attributes. - * - */ - string attr2String(const u_int32_t attr); - - /** - * Converts an open-mode (A combination of the PSI_O_ constants.) - * from generic representation to the machine-specific representation. - * - * @param mode The generic open mode. - * - * @returns The machine specific representation for use with - * @ref fopen , @ref fcreatefile and @freplacefile. - */ - virtual u_int32_t opMode(const u_int32_t mode) = 0; - - /** - * Utility method, converts '/' to '\'. - */ - static string convertSlash(const string &name); +public: + /** + * The kown modes for seek. + */ + enum seek_mode { + PSI_SEEK_SET = 1, + PSI_SEEK_CUR = 2, + PSI_SEEK_END = 3 + }; + + /** + * The known modes for file open. + */ + enum open_flags { + PSI_O_RDONLY = 0000, + PSI_O_WRONLY = 0001, + PSI_O_RDWR = 0002, + }; + + /** + * The known modes for file creation. + */ + enum open_mode { + PSI_O_CREAT = 00100, + PSI_O_EXCL = 00200, + PSI_O_TRUNC = 01000, + PSI_O_APPEND = 02000, + }; + + /** + * The known error codes. + */ + enum errs { + E_PSI_GEN_NONE = 0, + E_PSI_GEN_FAIL = -1, + E_PSI_GEN_ARG = -2, + E_PSI_GEN_OS = -3, + E_PSI_GEN_NSUP = -4, + E_PSI_GEN_UNDER = -5, + E_PSI_GEN_OVER = -6, + E_PSI_GEN_RANGE = -7, + E_PSI_GEN_DIVIDE = -8, + E_PSI_GEN_INUSE = -9, + E_PSI_GEN_NOMEMORY = - 10, + E_PSI_GEN_NOSEGMENTS = -11, + E_PSI_GEN_NOSEM = -12, + E_PSI_GEN_NOPROC = -13, + E_PSI_GEN_OPEN = -14, + E_PSI_GEN_NOTOPEN = -15, + E_PSI_GEN_IMAGE = -16, + E_PSI_GEN_RECEIVER = -17, + E_PSI_GEN_DEVICE = -18, + E_PSI_GEN_FSYS = -19, + E_PSI_GEN_START = -20, + E_PSI_GEN_NOFONT = -21, + E_PSI_GEN_TOOWIDE = -22, + E_PSI_GEN_TOOMANY = -23, + E_PSI_FILE_EXIST = -32, + E_PSI_FILE_NXIST = -33, + E_PSI_FILE_WRITE = -34, + E_PSI_FILE_READ = -35, + E_PSI_FILE_EOF = -36, + E_PSI_FILE_FULL = -37, + E_PSI_FILE_NAME = -38, + E_PSI_FILE_ACCESS = -39, + E_PSI_FILE_LOCKED = -40, + E_PSI_FILE_DEVICE = -41, + E_PSI_FILE_DIR = -42, + E_PSI_FILE_RECORD = -43, + E_PSI_FILE_RDONLY = -44, + E_PSI_FILE_INV = -45, + E_PSI_FILE_PENDING = -46, + E_PSI_FILE_VOLUME = -47, + E_PSI_FILE_CANCEL = -48, + E_PSI_FILE_ALLOC = -49, + E_PSI_FILE_DISC = -50, + E_PSI_FILE_CONNECT = -51, + E_PSI_FILE_RETRAN = -52, + E_PSI_FILE_LINE = -53, + E_PSI_FILE_INACT = -54, + E_PSI_FILE_PARITY = -55, + E_PSI_FILE_FRAME = -56, + E_PSI_FILE_OVERRUN = -57, + E_PSI_MDM_CONFAIL = -58, + E_PSI_MDM_BUSY = -59, + E_PSI_MDM_NOANS = -60, + E_PSI_MDM_BLACKLIST = -61, + E_PSI_FILE_NOTREADY = -62, + E_PSI_FILE_UNKNOWN = -63, + E_PSI_FILE_DIRFULL = -64, + E_PSI_FILE_PROTECT = -65, + E_PSI_FILE_CORRUPT = -66, + E_PSI_FILE_ABORT = -67, + E_PSI_FILE_ERASE = -68, + E_PSI_FILE_INVALID = -69, + E_PSI_GEN_POWER = -100, + E_PSI_FILE_TOOBIG = -101, + E_PSI_GEN_DESCR = -102, + E_PSI_GEN_LIB = -103, + E_PSI_FILE_NDISC = -104, + E_PSI_FILE_DRIVER = -105, + E_PSI_FILE_COMPLETION = -106, + E_PSI_GEN_BUSY = -107, + E_PSI_GEN_TERMINATED = -108, + E_PSI_GEN_DIED = -109, + E_PSI_FILE_HANDLE = -110, + + // Special error code for "Operation not permitted in RFSV16" + E_PSI_NOT_SIBO = -200, + // Special error code for "internal library error" + E_PSI_INTERNAL = -201 + }; + + /** + * The known file attributes + */ + enum file_attribs { + /** Attributes, valid on both <em>EPOC</em> and <em>SIBO</em>. */ + PSI_A_RDONLY = 0x0001, + PSI_A_HIDDEN = 0x0002, + PSI_A_SYSTEM = 0x0004, + PSI_A_DIR = 0x0008, + PSI_A_ARCHIVE = 0x0010, + PSI_A_VOLUME = 0x0020, + + /** Attributes, valid on EPOC <em>only</em>. */ + PSI_A_NORMAL = 0x0040, + PSI_A_TEMP = 0x0080, + PSI_A_COMPRESSED = 0x0100, + + /** Attributes, valid on SIBO <em>only</em>. */ + PSI_A_READ = 0x0200, + PSI_A_EXEC = 0x0400, + PSI_A_STREAM = 0x0800, + PSI_A_TEXT = 0x1000, + }; + + virtual ~rfsv(); + void reset(); + void reconnect(); + + /** + * Retrieves the current connection status. + * + * @returns The status of the connection. + */ + Enum<errs> getStatus(); + + /** + * Opens a file. + * + * @param attr The open mode. Use @ref opMode to convert a combination of @ref open_flags + * and @ref open_mode to the machine-specific representation. + * @param name The name of the file to open. + * @param handle The handle for usage with @ref fread , + * @ref fwrite , @ref fseek or @ref fclose is returned here. + * + * @returns A Psion error code (One of enum @ref #errs ). + */ + virtual Enum<errs> fopen(const u_int32_t attr, const char * const name, u_int32_t &handle) = 0; + + /** + * Creates a unique temporary file. + * The file is opened for reading and writing. + * + * @param handle The handle for usage with @ref fread , + * @ref fwrite , @ref fseek or @ref fclose is returned here. + * @param name The name of the temporary file is returned here. + * + * @returns A Psion error code (One of enum @ref #errs ). + */ + virtual Enum<errs> mktemp(u_int32_t &handle, string &name) = 0; + + /** + * Creates a named file. + * + * @param attr The open mode. Use @ref opMode to convert a combination of @ref open_flags + * and @ref open_mode to the machine-specific representation. + * @param name The name of the file to create. + * @param handle The handle for usage with @ref fread , + * @ref fwrite , @ref fseek or @ref fclose is returned here. + * + * @returns A Psion error code (One of enum @ref #errs ). + */ + virtual Enum<errs> fcreatefile(const u_int32_t attr, const char * const name, u_int32_t &handle) = 0; + + /** + * Creates an named file, overwriting an existing file. + * + * @param attr The open mode. Use @ref opMode to convert a combination of @ref open_flags + * and @ref open_mode to the machine-specific representation. + * @param name The name of the file to create. + * @param handle The handle for usage with @ref fread , + * @ref fwrite , @ref fseek or @ref fclose is returned here. + * + * @returns A Psion error code (One of enum @ref #errs ). + */ + virtual Enum<errs> freplacefile(const u_int32_t attr, const char * const name, u_int32_t &handle) = 0; + + /** + * Close a file on the Psion whih was previously opened/created by using + * @ref fopen , @ref fcreatefile , @ref freplacefile or @ref mktemp . + * + * @param handle A valid file handle. + */ + virtual Enum<errs> fclose(const u_int32_t handle) = 0; + + /** + * Reads a directory on the Psion. + * The returned STL deque of @ref PlpDirent contains all + * requested directory entries. + * + * @param name The name of the directory + * @param ret An STL deque of @ref PlpDirent entries. + * + * @returns A Psion error code (One of enum @ref rfsv::errs ). + */ + virtual Enum<errs> dir(const char * const name, PlpDir &ret) = 0; + + /** + * Retrieves the modification time of a file on the Psion. + * + * @param name Name of the file. + * @param mtime Modification time is returned here. + * + * @returns A Psion error code (One of enum @ref #errs ). + */ + virtual Enum<errs> fgetmtime(const char * const name, PsiTime &mtime) = 0; + + /** + * Sets the modification time of a file on the Psion. + * + * @param name Name of the file whose modification time should be set. + * @param mtime The desired modification time. + * + * @returns A Psion error code (One of enum @ref #errs ). + */ + virtual Enum<errs> fsetmtime(const char * const name, const PsiTime mtime) = 0; + + /** + * Retrieves attributes of a file on the Psion. + * + * @param name Name of the file whose attributes ar to be retrieved. + * @param attr The file's attributes are returned here. + * + * @returns A Psion error code (One of enum @ref #errs ). + */ + virtual Enum<errs> fgetattr(const char * const name, u_int32_t &attr) = 0; + + /** + * Retrieves attributes, size and modification time of a file on the Psion. + * + * @param name The name of the file. + * @param e @ref PlpDirent object, filled with the information on return. + * + * @returns A Psion error code (One of enum @ref #errs ). + */ + virtual Enum<errs> fgeteattr(const char * const name, PlpDirent &e) =0; + + /** + * @param name + * + * @returns A Psion error code (One of enum @ref #errs ). + */ + virtual Enum<errs> fsetattr(const char * const name, const u_int32_t seta, const u_int32_t unseta) = 0; + + /** + * Counts number of entries in a directory. + * + * @param name The directory whose entries are to be counted. + * @param count The number of entries is returned here. + * + * @returns A Psion error code (One of enum @ref #errs ). + */ + virtual Enum<errs> dircount(const char * const name, u_int32_t &count) = 0; + + /** + * Retrieves available drives on the Psion. + * @p devbits On return, for every exiting drive, a bit is set in this + * variable. The lowest bit represents drive A:. + * + * @returns A Psion error code (One of enum @ref #errs ). + */ + virtual Enum<errs> devlist(u_int32_t &devbits) = 0; + + /** + * Retrieves details about a drive. + * + * @param dev An integer, representing the drive to get details from. + * (0 represents A:, 1 is B: and so on ...) + * @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, PlpDrive &drive) = 0; + + /** + * Reads from a file on the Psion. + * + * @param handle Handle of the file to read from. + * @param buffer The area where to store the data read. + * @param len The number of bytes to read. + * @param count The number of bytes actually read is returned here. + * + * @returns A Psion error code (One of enum @ref #errs ). + */ + virtual Enum<errs> fread(const u_int32_t handle, unsigned char * const buffer, const u_int32_t len, u_int32_t &count) = 0; + + /** + * Write to a file on the Psion. + * + * @param handle Handle of the file to read from. + * @param buffer The area to be written. + * @param len The number of bytes to write. + * @param count The number of bytes actually written is returned here. + * + * @returns A Psion error code (One of enum @ref #errs ). + */ + virtual Enum<errs> fwrite(const u_int32_t handle, const unsigned char * const buffer, const u_int32_t len, u_int32_t &count) = 0; + + /** + * Copies a file from the Psion to the local machine. + * + * @param from Name of the file on the Psion to be copied. + * @param to Name of the destination file on the local machine. + * @param func Pointer to a function which gets called on every read. + * This function can be used to show some progress etc. May be set + * to NULL, where no callback is performed. + * + * @returns A Psion error code (One of enum @ref #errs ). + */ + virtual Enum<errs> copyFromPsion(const char *from, const char *to, void *, cpCallback_t func) = 0; + + /** + * Copies a file from local machine to the Psion. + * + * @param from Name of the file on the local machine to be copied. + * @param to Name of the destination file on the Psion. + * @param func Pointer to a function which gets called on every read. + * This function can be used to show some progress etc. May be set + * to NULL, where no callback is performed. + * + * @returns A Psion error code (One of enum @ref #errs ). + */ + virtual Enum<errs> copyToPsion(const char * const from, const char * const to, void *, cpCallback_t func) = 0; + + /** + * Copies a file from the Psion to the Psion. + * On the EPOC variants, this runs much faster than reading + * data from the Psion and then writing it back to the Psion, since + * data transfer is handled locally on the Psion. + * + * @param from Name of the file to be copied. + * @param to Name of the destination file. + * @param func Pointer to a function which gets called on every read. + * This function can be used to show some progress etc. May be set + * to NULL, where no callback is performed. + * + * @returns A Psion error code (One of enum @ref #errs ). + */ + virtual Enum<errs> copyOnPsion(const char * const from, const char * const to, void *, cpCallback_t func) = 0; + + /** + * Resizes an open file on the Psion. + * If the new size is greater than the file's + * current size, the contents of the added + * data is undefined. If The new size is smaller, + * the file is truncated. + * + * @param handle Handle of the file to be resized. + * @param size New size for that file. + * + * @returns A Psion error code (One of enum @ref #errs ). + */ + virtual Enum<errs> fsetsize(const u_int32_t handle, const u_int32_t size) = 0; + + /** + * Sets the current file position of a file on the Psion. + * + * @param handle The file handle. + * @param offset Position to be seeked to. + * @param mode The mode for seeking. + * @param resultpos The final file position after seeking is returned here. + * + * @returns A Psion error code (One of enum @ref #errs ). + */ + virtual Enum<errs> fseek(const u_int32_t handle, const int32_t offset, const u_int32_t mode, u_int32_t &resultpos) = 0; + + /** + * Creates a directory on the Psion. + * + * @param name Name of the directory to be created. + * + * @returns A Psion error code (One of enum @ref #errs ). + */ + virtual Enum<errs> mkdir(const char * const name) = 0; + + /** + * Removes a directory on the Psion. + * + * @param name Name of the directory to be removed. + * + * @returns A Psion error code (One of enum @ref #errs ). + */ + virtual Enum<errs> rmdir(const char * const name) = 0; + + /** + * Renames a file on the Psion. + * + * @param oldname Name of the file to be renamed. + * @param newname New Name for that file. + * + * @returns A Psion error code (One of enum @ref #errs ). + */ + virtual Enum<errs> rename(const char * const oldname, const char * const newname) = 0; + + /** + * Removes a file on the Psion. + * + * @param name Name of the file to be removed. + * + * @returns A Psion error code (One of enum @ref #errs ). + */ + virtual Enum<errs> remove(const char * const name) = 0; + + /** + * Open a directory for reading with readdir. + * + * @param attr A combination of PSI_A_.. flags, representing the desired types + * of entries to be returned when calling @ref readdir . + * @param name The name of the directory + * @param handle A handle to be used with @ref readdir and @ref closedir . + * + * @returns A Psion error code (One of enum @ref #errs ). + */ + virtual Enum<errs> opendir(const u_int32_t attr, const char * const name, rfsvDirhandle &handle) = 0; + + /** + * Read directory entries. + * This method reads entries of a directory, previously + * opened with @ref opendir . + * + * @param handle A handle, obtained by calling @ref opendir . + * @param entry The entry information is returned here. + * + * @returns A Psion error code (One of enum @ref #errs ). + */ + virtual Enum<errs> readdir(rfsvDirhandle &handle, PlpDirent &entry) = 0; + + /** + * Close a directory, previously opened with @ref opendir. + * + * @param handle A handle, obtained by calling @ref opendir . + * + * @returns A Psion error code (One of enum @ref #errs ). + */ + virtual Enum<errs> closedir(rfsvDirhandle &handle) = 0; + + /** + * Set the name of a Psion Volume (Drive). + * + * @param drive The drive character of the Volume, whose name should be set. + * @param name The new name for that drive. + * + * @returns A Psion error code (One of enum @ref #errs ). + */ + virtual Enum<errs> setVolumeName(const char drive, const char * const name) = 0; + + /** + * Converts a file attribute @ref rfsv::file_attribs to + * human readable format, usable for showing them in directory + * listings. The first 7 characters are common to all + * machine types: + * <pre> + * Char Nr. Value + * 0 'd' if a directory, '-' otherwise. + * 1 'r' if file is readable, '-' otherwise. + * 2 'w' if file is writeable, '-' otherwise. + * 3 'h' if file is hidden, '-' otherwise. + * 4 's' if file is a system file, '-' otherwise. + * 5 'a' if file is modified (archive flag), '-' otherwise. + * 6 'v' if file is a volume name, '-' otherwise. + * </pre> + * The rest (3 characters) are machine specific: + * <pre> + * Char Nr. EPOC Value SIBO Value + * 7 'n' if normal, 'x' if executable, '-' otherwise. + * 8 't' if temporary, 'b' if a stream, '-' otherwise. + * 8 'c' if compressed, 't' if a textfile, '-' otherwise. + * </pre> + * + * @param attr the generic file attribute. + * + * @returns Pointer to static textual representation of file attributes. + * + */ + string attr2String(const u_int32_t attr); + + /** + * Converts an open-mode (A combination of the PSI_O_ constants.) + * from generic representation to the machine-specific representation. + * + * @param mode The generic open mode. + * + * @returns The machine specific representation for use with + * @ref fopen , @ref fcreatefile and @freplacefile. + */ + virtual u_int32_t opMode(const u_int32_t mode) = 0; + + /** + * Utility method, converts '/' to '\'. + */ + static string convertSlash(const string &name); protected: - /** - * Retrieves the PLP protocol name. Mainly internal use. - * - * @returns The connection name always "SYS$RFSV" - */ - const char *getConnectName(); - - ppsocket *skt; - Enum<errs> status; - int32_t serNum; + /** + * Retrieves the PLP protocol name. Mainly internal use. + * + * @returns The connection name always "SYS$RFSV" + */ + const char *getConnectName(); + + ppsocket *skt; + Enum<errs> status; + int32_t serNum; }; #endif +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ diff --git a/lib/rfsv16.cc b/lib/rfsv16.cc index f98816c..30c3673 100644 --- a/lib/rfsv16.cc +++ b/lib/rfsv16.cc @@ -1,28 +1,27 @@ -// -// RFSV16 - An implementation of the PSION SIBO RFSV Client protocol -// -// Copyright (C) 1999 Philip Proudman -// Modifications for plptools: -// Copyright (C) 1999 Matt J. Gumbley <matt@gumbley.demon.co.uk> -// Sources: rfsv32.cc by Fritz Elfert, and rfsv16.cc by Philip Proudman -// Descriptions of the RFSV16 protocol by Michael Pieper, Olaf Flebbe & Me. -// -// 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 -// -// e-mail philip.proudman@btinternet.com - +/*-*-c++-*- + * $Id$ + * + * This file is part of plptools. + * + * Copyright (C) 1999 Philip Proudman <philip.proudman@btinternet.com> + * Copyright (C) 1999 Matt J. Gumbley <matt@gumbley.demon.co.uk> + * Copyright (C) 1999-2001 Fritz Elfert <felfert@to.com> + * + * 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 + * + */ #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -43,678 +42,678 @@ rfsv16::rfsv16(ppsocket *_skt) { - serNum = 0; - status = rfsv::E_PSI_FILE_DISC; - skt = _skt; - reset(); + serNum = 0; + status = rfsv::E_PSI_FILE_DISC; + skt = _skt; + reset(); } Enum<rfsv::errs> rfsv16:: fopen(u_int32_t attr, const char *name, u_int32_t &handle) -{ - bufferStore a; - string realName = convertSlash(name); - - a.addWord(attr & 0xFFFF); - a.addStringT(realName.c_str()); - if (!sendCommand(FOPEN, a)) - return E_PSI_FILE_DISC; - - Enum<rfsv::errs> res = getResponse(a); - if (res == 0) { - handle = (long)a.getWord(0); - return E_PSI_GEN_NONE; - } - return res; +{ + bufferStore a; + string realName = convertSlash(name); + + a.addWord(attr & 0xFFFF); + a.addStringT(realName.c_str()); + if (!sendCommand(FOPEN, a)) + return E_PSI_FILE_DISC; + + Enum<rfsv::errs> res = getResponse(a); + if (res == 0) { + handle = (long)a.getWord(0); + return E_PSI_GEN_NONE; + } + return res; } // internal Enum<rfsv::errs> rfsv16:: mktemp(u_int32_t &handle, string &tmpname) { - bufferStore a; + bufferStore a; - a.addWord(P_FUNIQUE); - a.addStringT("TMP"); - if (!sendCommand(OPENUNIQUE, a)) - return E_PSI_FILE_DISC; - - Enum<rfsv::errs> res = getResponse(a); - if (res == E_PSI_GEN_NONE) { - handle = a.getWord(0); - tmpname = a.getString(2); - return res; - } + a.addWord(P_FUNIQUE); + a.addStringT("TMP"); + if (!sendCommand(OPENUNIQUE, a)) + return E_PSI_FILE_DISC; + + Enum<rfsv::errs> res = getResponse(a); + if (res == E_PSI_GEN_NONE) { + handle = a.getWord(0); + tmpname = a.getString(2); return res; + } + return res; } // internal and external Enum<rfsv::errs> rfsv16:: fcreatefile(u_int32_t attr, const char *name, u_int32_t &handle) { - return fopen(attr | P_FCREATE, name, handle); + return fopen(attr | P_FCREATE, name, handle); } // this is internal - not used by plpnfsd, unlike fcreatefile Enum<rfsv::errs> rfsv16:: freplacefile(u_int32_t attr, const char *name, u_int32_t &handle) { - return fopen(attr | P_FREPLACE, name, handle); + return fopen(attr | P_FREPLACE, name, handle); } Enum<rfsv::errs> rfsv16:: fopendir(const char * const name, u_int32_t &handle) { - return fopen(P_FDIR, name, handle); + return fopen(P_FDIR, name, handle); } Enum<rfsv::errs> rfsv16:: fclose(u_int32_t fileHandle) { - bufferStore a; - a.addWord(fileHandle & 0xFFFF); - if (!sendCommand(FCLOSE, a)) - return E_PSI_FILE_DISC; - return getResponse(a); + bufferStore a; + a.addWord(fileHandle & 0xFFFF); + if (!sendCommand(FCLOSE, a)) + return E_PSI_FILE_DISC; + return getResponse(a); } Enum<rfsv::errs> rfsv16:: opendir(const u_int32_t attr, const char *name, rfsvDirhandle &dH) { - u_int32_t handle; - Enum<rfsv::errs> res = fopendir(name, handle); - dH.h = handle; - dH.b.init(); - return res; + u_int32_t handle; + Enum<rfsv::errs> res = fopendir(name, handle); + dH.h = handle; + dH.b.init(); + return res; } Enum<rfsv::errs> rfsv16:: closedir(rfsvDirhandle &dH) { - return fclose(dH.h); + return fclose(dH.h); } Enum<rfsv::errs> rfsv16:: readdir(rfsvDirhandle &dH, PlpDirent &e) { - Enum<rfsv::errs> res = E_PSI_GEN_NONE; - - if (dH.b.getLen() < 17) { - dH.b.init(); - dH.b.addWord(dH.h & 0xFFFF); - if (!sendCommand(FDIRREAD, dH.b)) - return E_PSI_FILE_DISC; - res = getResponse(dH.b); - dH.b.discardFirstBytes(2); // Don't know what these mean! - } - if ((res == E_PSI_GEN_NONE) && (dH.b.getLen() > 16)) { - u_int16_t version = dH.b.getWord(0); - if (version != 2) { - cerr << "dir: not version 2" << endl; - 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.name = dH.b.getString(16); - // e.UID = PlpUID(0,0,0); - e.attrstr = attr2String(e.attr); - - dH.b.discardFirstBytes(17 + e.name.length()); + Enum<rfsv::errs> res = E_PSI_GEN_NONE; + if (dH.b.getLen() < 17) { + dH.b.init(); + dH.b.addWord(dH.h & 0xFFFF); + if (!sendCommand(FDIRREAD, dH.b)) + return E_PSI_FILE_DISC; + res = getResponse(dH.b); + dH.b.discardFirstBytes(2); // Don't know what these mean! + } + if ((res == E_PSI_GEN_NONE) && (dH.b.getLen() > 16)) { + u_int16_t version = dH.b.getWord(0); + if (version != 2) { + cerr << "dir: not version 2" << endl; + return E_PSI_GEN_FAIL; } - return res; + 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.name = dH.b.getString(16); + // e.UID = PlpUID(0,0,0); + e.attrstr = attr2String(e.attr); + + dH.b.discardFirstBytes(17 + e.name.length()); + + } + return res; } Enum<rfsv::errs> rfsv16:: dir(const char *name, PlpDir &files) { - rfsvDirhandle h; - files.clear(); - Enum<rfsv::errs> 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) - files.push_back(e); - } - closedir(h); - if (res == E_PSI_FILE_EOF) - res = E_PSI_GEN_NONE; - return res; + rfsvDirhandle h; + files.clear(); + Enum<rfsv::errs> 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) + files.push_back(e); + } + closedir(h); + if (res == E_PSI_FILE_EOF) + res = E_PSI_GEN_NONE; + return res; } u_int32_t rfsv16:: opMode(u_int32_t mode) { - u_int32_t ret = 0; + u_int32_t ret = 0; - ret |= ((mode & 03) == PSI_O_RDONLY) ? 0 : P_FUPDATE; - ret |= (mode & PSI_O_TRUNC) ? P_FREPLACE : 0; - ret |= (mode & PSI_O_CREAT) ? P_FCREATE : 0; - ret |= (mode & PSI_O_APPEND) ? P_FAPPEND : 0; - if ((mode & 03) == PSI_O_RDONLY) - ret |= (mode & PSI_O_EXCL) ? 0 : P_FSHARE; - return ret; + ret |= ((mode & 03) == PSI_O_RDONLY) ? 0 : P_FUPDATE; + ret |= (mode & PSI_O_TRUNC) ? P_FREPLACE : 0; + ret |= (mode & PSI_O_CREAT) ? P_FCREATE : 0; + ret |= (mode & PSI_O_APPEND) ? P_FAPPEND : 0; + if ((mode & 03) == PSI_O_RDONLY) + ret |= (mode & PSI_O_EXCL) ? 0 : P_FSHARE; + return ret; } Enum<rfsv::errs> 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<rfsv::errs> res = getResponse(a); - if (res != E_PSI_GEN_NONE) { - cerr << "fgetmtime: Error " << res << " on file " << name << endl; - return res; - } - else if (a.getLen() == 16) { - mtime.setUnixTime(a.getDWord(8)); - return res; - } - cerr << "fgetmtime: Unknown response (" << name << ") " << a <<endl; - return E_PSI_GEN_FAIL; + 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<rfsv::errs> res = getResponse(a); + if (res != E_PSI_GEN_NONE) { + cerr << "fgetmtime: Error " << res << " on file " << name << endl; + return res; + } + else if (a.getLen() == 16) { + mtime.setUnixTime(a.getDWord(8)); + return res; + } + cerr << "fgetmtime: Unknown response (" << name << ") " << a <<endl; + return E_PSI_GEN_FAIL; } Enum<rfsv::errs> rfsv16:: fsetmtime(const char *name, PsiTime mtime) { -cerr << "rfsv16::fsetmtime ***" << endl; - // I don't think there's a protocol frame that allows us to set the - // modification time. SFDATE allows setting of creation time... - return E_PSI_NOT_SIBO; + cerr << "rfsv16::fsetmtime ***" << endl; + // I don't think there's a protocol frame that allows us to set the + // modification time. SFDATE allows setting of creation time... + return E_PSI_NOT_SIBO; } Enum<rfsv::errs> 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<rfsv::errs> res = getResponse(a); - if (res != 0) { - cerr << "fgetattr: Error " << res << " on file " << name << endl; - return res; - } - else if (a.getLen() == 16) { - attr = attr2std((long)a.getWord(2)); - return res; - } - cerr << "fgetattr: Unknown response (" << name << ") " << a <<endl; - return E_PSI_GEN_FAIL; + // 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<rfsv::errs> res = getResponse(a); + if (res != 0) { + cerr << "fgetattr: Error " << res << " on file " << name << endl; + return res; + } + else if (a.getLen() == 16) { + attr = attr2std((long)a.getWord(2)); + return res; + } + cerr << "fgetattr: Unknown response (" << name << ") " << a <<endl; + return E_PSI_GEN_FAIL; } Enum<rfsv::errs> rfsv16:: fgeteattr(const char * const name, PlpDirent &e) { - bufferStore a; - string realName = convertSlash(name); - a.addStringT(realName.c_str()); - if (!sendCommand(FINFO, a)) - return E_PSI_FILE_DISC; - Enum<rfsv::errs> res = getResponse(a); - if (res != 0) { - cerr << "fgeteattr: Error " << res << " on file " << name << endl; - return res; - } - else if (a.getLen() == 16) { - const char *p = strrchr(realName.c_str(), '\\'); - if (p) - p++; - else - p = realName.c_str(); - e.name = p; - e.attr = a.getWord(2); - e.size = a.getDWord(4); - e.time = PsiTime(a.getDWord(8)); - e.UID = PlpUID(0,0,0); - return res; - } - cerr << "fgeteattr: Unknown response (" << name << ") " << a <<endl; - return E_PSI_GEN_FAIL; + bufferStore a; + string realName = convertSlash(name); + a.addStringT(realName.c_str()); + if (!sendCommand(FINFO, a)) + return E_PSI_FILE_DISC; + Enum<rfsv::errs> res = getResponse(a); + if (res != 0) { + cerr << "fgeteattr: Error " << res << " on file " << name << endl; + return res; + } + else if (a.getLen() == 16) { + const char *p = strrchr(realName.c_str(), '\\'); + if (p) + p++; + else + p = realName.c_str(); + e.name = p; + e.attr = a.getWord(2); + e.size = a.getDWord(4); + e.time = PsiTime(a.getDWord(8)); + e.UID = PlpUID(0,0,0); + return res; + } + cerr << "fgeteattr: Unknown response (" << name << ") " << a <<endl; + return E_PSI_GEN_FAIL; } Enum<rfsv::errs> 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); + 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); } Enum<rfsv::errs> rfsv16:: dircount(const char * const name, u_int32_t &count) { - u_int32_t fileHandle; - Enum<rfsv::errs> res; - count = 0; + u_int32_t fileHandle; + Enum<rfsv::errs> res; + count = 0; + + res = fopen(P_FDIR, name, fileHandle); + if (res != E_PSI_GEN_NONE) + return res; - res = fopen(P_FDIR, name, fileHandle); + 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) - 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)); - count++; - } + 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)); + count++; } - if (res == E_PSI_FILE_EOF) - res = E_PSI_GEN_NONE; - fclose(fileHandle); - return res; + } + if (res == E_PSI_FILE_EOF) + res = E_PSI_GEN_NONE; + fclose(fileHandle); + return res; } Enum<rfsv::errs> rfsv16:: devlist(u_int32_t &devbits) { - Enum<rfsv::errs> res; - u_int32_t fileHandle; - devbits = 0; + Enum<rfsv::errs> res; + u_int32_t fileHandle; + devbits = 0; + + // The following is taken from a trace between a Series 3c and PsiWin. + // Hope it works! We PARSE to find the correct node, then FOPEN + // (P_FDEVICE) this, FDEVICEREAD each entry, setting the appropriate + // drive-letter-bit in devbits, then FCLOSE. + + bufferStore a; + a.init(); + a.addByte(0x00); // no Name 1 + a.addByte(0x00); // no Name 2 + a.addByte(0x00); // no Name 3 + if (!sendCommand(PARSE, a)) + return E_PSI_FILE_DISC; + res = getResponse(a); + if (res != E_PSI_GEN_NONE) + return res; - // The following is taken from a trace between a Series 3c and PsiWin. - // Hope it works! We PARSE to find the correct node, then FOPEN - // (P_FDEVICE) this, FDEVICEREAD each entry, setting the appropriate - // drive-letter-bit in devbits, then FCLOSE. + // Find the drive to FOPEN + char name[4] = { 'x', ':', '\\', '\0' } ; + a.discardFirstBytes(6); // Result, fsys, dev, path, file, file, ending, flag + /* This leaves R E M : : M : \ */ + name[0] = (char) a.getByte(5); // the M + res = fopen(P_FDEVICE, name, fileHandle); + if (res != E_PSI_GEN_NONE) + return status; + while (1) { bufferStore a; a.init(); - a.addByte(0x00); // no Name 1 - a.addByte(0x00); // no Name 2 - a.addByte(0x00); // no Name 3 - if (!sendCommand(PARSE, a)) - return E_PSI_FILE_DISC; + a.addWord(fileHandle & 0xFFFF); + if (!sendCommand(FDEVICEREAD, a)) + return E_PSI_FILE_DISC; res = getResponse(a); - if (res != E_PSI_GEN_NONE) - return res; - - // Find the drive to FOPEN - char name[4] = { 'x', ':', '\\', '\0' } ; - a.discardFirstBytes(6); // Result, fsys, dev, path, file, file, ending, flag - /* This leaves R E M : : M : \ */ - name[0] = (char) a.getByte(5); // the M - res = fopen(P_FDEVICE, name, fileHandle); - if (res != E_PSI_GEN_NONE) - return status; - - while (1) { - bufferStore a; - a.init(); - a.addWord(fileHandle & 0xFFFF); - if (!sendCommand(FDEVICEREAD, a)) - return E_PSI_FILE_DISC; - res = getResponse(a); - if (res) - break; - u_int16_t version = a.getWord(0); - if (version != 2) { - cerr << "devlist: not version 2" << endl; - fclose(fileHandle); - return E_PSI_GEN_FAIL; // FIXME - } - char drive = a.getByte(64); - if (drive >= 'A' && drive <= 'Z') { - int shift = (drive - 'A'); - devbits |= (long) ( 1 << shift ); - } - else { - cerr << "devlist: non-alphabetic drive letter (" - << drive << ")" << endl; - } + if (res) + break; + u_int16_t version = a.getWord(0); + if (version != 2) { + cerr << "devlist: not version 2" << endl; + fclose(fileHandle); + return E_PSI_GEN_FAIL; // FIXME } - if (res == E_PSI_FILE_EOF) - res = E_PSI_GEN_NONE; - fclose(fileHandle); - return res; + char drive = a.getByte(64); + if (drive >= 'A' && drive <= 'Z') { + int shift = (drive - 'A'); + devbits |= (long) ( 1 << shift ); + } + else { + cerr << "devlist: non-alphabetic drive letter (" + << drive << ")" << endl; + } + } + if (res == E_PSI_FILE_EOF) + res = E_PSI_GEN_NONE; + fclose(fileHandle); + return res; } static int sibo_dattr[] = { - 1, // Unknown - 2, // Floppy - 3, // Disk - 6, // Flash - 5, // RAM - 7, // ROM - 7, // write-protected == ROM ? + 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, PlpDrive &drive) { - bufferStore a; - Enum<rfsv::errs> 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 - // (which we ignore), then do a STATUSDEVICE to get the info. - - a.init(); - a.addByte((char) (devnum + 'A')); // Name 1 - a.addByte(':'); - a.addByte(0x00); - a.addByte(0x00); // No name 2 - 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; - return res; - } - - a.init(); - a.addByte((char) (devnum + 'A')); // Name 1 - a.addByte(':'); - a.addByte('\\'); - 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; - return res; - } + bufferStore a; + Enum<rfsv::errs> 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 + // (which we ignore), then do a STATUSDEVICE to get the info. + + a.init(); + a.addByte((char) (devnum + 'A')); // Name 1 + a.addByte(':'); + a.addByte(0x00); + a.addByte(0x00); // No name 2 + 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; + return res; + } + + a.init(); + a.addByte((char) (devnum + 'A')); // Name 1 + a.addByte(':'); + a.addByte('\\'); + 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; + return res; + } - int attr = a.getWord(2); - attr = sibo_dattr[a.getWord(2) & 0xff]; - drive.setMediaType(attr); + int attr = a.getWord(2); + attr = sibo_dattr[a.getWord(2) & 0xff]; + drive.setMediaType(attr); - attr = a.getWord(2); - int changeable = a.getWord(4) ? 32 : 0; - int internal = (attr & 0x2000) ? 16 : 0; + attr = a.getWord(2); + int changeable = a.getWord(4) ? 32 : 0; + int internal = (attr & 0x2000) ? 16 : 0; - drive.setDriveAttribute(changeable | internal); + 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; + 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.setMediaAttribute(variable|dualdens|formattable|protect); - drive.setUID(0); - drive.setSize(a.getDWord(6), 0); - drive.setSpace(a.getDWord(10), 0); + drive.setUID(0); + drive.setSize(a.getDWord(6), 0); + drive.setSpace(a.getDWord(10), 0); - drive.setName('A' + devnum, a.getString(14)); + drive.setName('A' + devnum, a.getString(14)); - return res; + return res; } bool rfsv16:: sendCommand(enum commands cc, bufferStore & data) { - if (status == E_PSI_FILE_DISC) { - reconnect(); - if (status == E_PSI_FILE_DISC) - return false; - } - - bool result; - bufferStore a; - a.addWord(cc); - a.addWord(data.getLen()); - a.addBuff(data); + if (status == E_PSI_FILE_DISC) { + reconnect(); + if (status == E_PSI_FILE_DISC) + return false; + } + + bool result; + bufferStore a; + a.addWord(cc); + a.addWord(data.getLen()); + a.addBuff(data); + result = skt->sendBufferStore(a); + if (!result) { + reconnect(); result = skt->sendBufferStore(a); - if (!result) { - reconnect(); - result = skt->sendBufferStore(a); if (!result) - status = E_PSI_FILE_DISC; - } - return result; + status = E_PSI_FILE_DISC; + } + return result; } Enum<rfsv::errs> rfsv16:: getResponse(bufferStore & data) { - // getWord(2) is the size field - // which is the body of the response not counting the command (002a) and - // the size word. - if (skt->getBufferStore(data) != 1) { - cerr << "rfsv16::getResponse: duff response. " - "getBufferStore failed." << endl; - } else if (data.getWord(0) == 0x2a && - data.getWord(2) == data.getLen()-4) { - Enum<errs> ret = (enum errs)data.getWord(4); - data.discardFirstBytes(6); - return ret; - } else { + // getWord(2) is the size field + // which is the body of the response not counting the command (002a) and + // the size word. + if (skt->getBufferStore(data) != 1) { + cerr << "rfsv16::getResponse: duff response. " + "getBufferStore failed." << endl; + } else if (data.getWord(0) == 0x2a && + data.getWord(2) == data.getLen()-4) { + Enum<errs> ret = (enum errs)data.getWord(4); + data.discardFirstBytes(6); + return ret; + } else { cerr << "rfsv16::getResponse: duff response. Size field:" << - data.getWord(2) << " Frame size:" << - data.getLen()-4 << " Result field:" << - data.getWord(4) << endl; - } - status = E_PSI_FILE_DISC; - return status; + data.getWord(2) << " Frame size:" << + data.getLen()-4 << " Result field:" << + data.getWord(4) << endl; + } + status = E_PSI_FILE_DISC; + return status; } Enum<rfsv::errs> rfsv16:: fread(const u_int32_t handle, unsigned char * const buf, const u_int32_t len, u_int32_t &count) { - Enum<rfsv::errs> res; - unsigned char *p = buf; - - count = 0; - while (count < len) { - bufferStore a; - - // Read in blocks of 291 bytes; the maximum payload for - // an RFSV frame. ( As seen in traces ) - this isn't optimal: - // RFSV can handle fragmentation of frames, where only the - // first FREAD RESPONSE frame has a RESPONSE (00 2A), SIZE - // and RESULT field. Every subsequent frame - // just has data, 297 bytes (or less) of it. - // - a.addWord(handle); - a.addWord((len - count) > RFSV16_MAXDATALEN - ? RFSV16_MAXDATALEN - : (len - count)); - if (!sendCommand(FREAD, a)) - return E_PSI_FILE_DISC; - if ((res = getResponse(a)) != E_PSI_GEN_NONE) { - if (res == E_PSI_FILE_EOF) - return E_PSI_GEN_NONE; - return res; - } - long l = a.getLen(); - memcpy(buf, a.getString(), l); - count += l; - p += l; + Enum<rfsv::errs> res; + unsigned char *p = buf; + + count = 0; + while (count < len) { + bufferStore a; + + // Read in blocks of 291 bytes; the maximum payload for + // an RFSV frame. ( As seen in traces ) - this isn't optimal: + // RFSV can handle fragmentation of frames, where only the + // first FREAD RESPONSE frame has a RESPONSE (00 2A), SIZE + // and RESULT field. Every subsequent frame + // just has data, 297 bytes (or less) of it. + // + a.addWord(handle); + a.addWord((len - count) > RFSV16_MAXDATALEN + ? RFSV16_MAXDATALEN + : (len - count)); + if (!sendCommand(FREAD, a)) + return E_PSI_FILE_DISC; + if ((res = getResponse(a)) != E_PSI_GEN_NONE) { + if (res == E_PSI_FILE_EOF) + return E_PSI_GEN_NONE; + return res; } - return res; + long l = a.getLen(); + memcpy(buf, a.getString(), l); + count += l; + p += l; + } + return res; } Enum<rfsv::errs> rfsv16:: fwrite(const u_int32_t handle, const unsigned char * const buf, const u_int32_t len, u_int32_t &count) { - Enum<rfsv::errs> res; - const unsigned char *p = buf; - - count = 0; - while (count < len) { - bufferStore a; - int nbytes; - - // Write in blocks of 291 bytes; the maximum payload for - // an RFSV frame. ( As seen in traces ) - this isn't optimal: - // RFSV can handle fragmentation of frames, where only the - // first FREAD RESPONSE frame has a RESPONSE (00 2A), SIZE - // and RESULT field. Every subsequent frame - // just has data, 297 bytes (or less) of it. - nbytes = (len - count) > RFSV16_MAXDATALEN - ? RFSV16_MAXDATALEN - : (len - count); - a.addWord(handle); - a.addBytes(p, nbytes); - if (!sendCommand(FWRITE, a)) - return E_PSI_FILE_DISC; - if ((res = getResponse(a)) != E_PSI_GEN_NONE) - return res; - - count += nbytes; - p += nbytes; - } - return res; + Enum<rfsv::errs> res; + const unsigned char *p = buf; + + count = 0; + while (count < len) { + bufferStore a; + int nbytes; + + // Write in blocks of 291 bytes; the maximum payload for + // an RFSV frame. ( As seen in traces ) - this isn't optimal: + // RFSV can handle fragmentation of frames, where only the + // first FREAD RESPONSE frame has a RESPONSE (00 2A), SIZE + // and RESULT field. Every subsequent frame + // just has data, 297 bytes (or less) of it. + nbytes = (len - count) > RFSV16_MAXDATALEN + ? RFSV16_MAXDATALEN + : (len - count); + a.addWord(handle); + a.addBytes(p, nbytes); + if (!sendCommand(FWRITE, a)) + return E_PSI_FILE_DISC; + if ((res = getResponse(a)) != E_PSI_GEN_NONE) + return res; + + count += nbytes; + p += nbytes; + } + return res; } Enum<rfsv::errs> rfsv16:: copyFromPsion(const char *from, const char *to, void *ptr, cpCallback_t cb) { - Enum<rfsv::errs> res; - u_int32_t handle; - u_int32_t len; - u_int32_t total = 0; + Enum<rfsv::errs> res; + u_int32_t handle; + u_int32_t len; + u_int32_t total = 0; - if ((res = fopen(P_FSHARE | P_FSTREAM, from, handle)) != E_PSI_GEN_NONE) - return res; - ofstream op(to); - if (!op) { - fclose(handle); - return E_PSI_GEN_FAIL; + if ((res = fopen(P_FSHARE | P_FSTREAM, from, handle)) != E_PSI_GEN_NONE) + return res; + ofstream op(to); + if (!op) { + fclose(handle); + return E_PSI_GEN_FAIL; + } + do { + unsigned char buf[RFSV_SENDLEN]; + if ((res = fread(handle, buf, sizeof(buf), len)) == E_PSI_GEN_NONE) { + if (len > 0) + op.write(buf, len); + total += len; + if (cb && !cb(ptr, total)) + res = E_PSI_FILE_CANCEL; } - do { - unsigned char buf[RFSV_SENDLEN]; - if ((res = fread(handle, buf, sizeof(buf), len)) == E_PSI_GEN_NONE) { - if (len > 0) - op.write(buf, len); - total += len; - if (cb && !cb(ptr, total)) - res = E_PSI_FILE_CANCEL; - } - } while (len > 0 && (res == E_PSI_GEN_NONE)); + } while (len > 0 && (res == E_PSI_GEN_NONE)); - fclose(handle); - op.close(); - if (res == E_PSI_FILE_EOF) - res = E_PSI_GEN_NONE; - return res; + fclose(handle); + op.close(); + if (res == E_PSI_FILE_EOF) + res = E_PSI_GEN_NONE; + return res; } Enum<rfsv::errs> rfsv16:: copyToPsion(const char *from, const char *to, void *ptr, cpCallback_t cb) { - u_int32_t handle; - u_int32_t len = 0; - u_int32_t total = 0; - Enum<rfsv::errs> res; - - ifstream ip(from); - if (!ip) - return E_PSI_FILE_NXIST; - res = fcreatefile(P_FSTREAM | P_FUPDATE, to, handle); - if (res != E_PSI_GEN_NONE) { - res = freplacefile(P_FSTREAM | P_FUPDATE, to, handle); - if (res != E_PSI_GEN_NONE) - return res; - } - unsigned char *buff = new unsigned char[RFSV_SENDLEN]; - while (res == E_PSI_GEN_NONE && ip && !ip.eof()) { - ip.read(buff, RFSV_SENDLEN); - if ((res = fwrite(handle, buff, ip.gcount(), len)) == E_PSI_GEN_NONE) { - total += len; - if (cb && !cb(ptr, total)) - res = E_PSI_FILE_CANCEL; - } + u_int32_t handle; + u_int32_t len = 0; + u_int32_t total = 0; + Enum<rfsv::errs> res; + + ifstream ip(from); + if (!ip) + return E_PSI_FILE_NXIST; + res = fcreatefile(P_FSTREAM | P_FUPDATE, to, handle); + if (res != E_PSI_GEN_NONE) { + res = freplacefile(P_FSTREAM | P_FUPDATE, to, handle); + if (res != E_PSI_GEN_NONE) + return res; + } + unsigned char *buff = new unsigned char[RFSV_SENDLEN]; + while (res == E_PSI_GEN_NONE && ip && !ip.eof()) { + ip.read(buff, RFSV_SENDLEN); + if ((res = fwrite(handle, buff, ip.gcount(), len)) == E_PSI_GEN_NONE) { + total += len; + if (cb && !cb(ptr, total)) + res = E_PSI_FILE_CANCEL; } - delete[]buff; - fclose(handle); - ip.close(); - return res; + } + delete[]buff; + fclose(handle); + ip.close(); + return res; } Enum<rfsv::errs> rfsv16:: copyOnPsion(const char *from, const char *to, void *ptr, cpCallback_t cb) { - u_int32_t handle_from; - u_int32_t handle_to; - u_int32_t len; - u_int32_t wlen; - u_int32_t total = 0; - Enum<rfsv::errs> res; - - if ((res = fopen(P_FSHARE | P_FSTREAM, from, handle_from)) != E_PSI_GEN_NONE) - return res; - res = fcreatefile(P_FSTREAM | P_FUPDATE, to, handle_to); - if (res != E_PSI_GEN_NONE) { - res = freplacefile(P_FSTREAM | P_FUPDATE, to, handle_to); - if (res != E_PSI_GEN_NONE) - return res; - } - do { - unsigned char buf[RFSV_SENDLEN]; - if ((res = fread(handle_from, buf, sizeof(buf), len)) == E_PSI_GEN_NONE) { - if (len > 0) { - if ((res = fwrite(handle_to, buf, len, wlen)) == E_PSI_GEN_NONE) { - total += wlen; - if (cb && !cb(ptr, total)) - res = E_PSI_FILE_CANCEL; - } - } - } - } while (len > 0 && wlen > 0 && (res == E_PSI_GEN_NONE)); - fclose(handle_from); - fclose(handle_to); - if (res == E_PSI_FILE_EOF) - res = E_PSI_GEN_NONE; + u_int32_t handle_from; + u_int32_t handle_to; + u_int32_t len; + u_int32_t wlen; + u_int32_t total = 0; + Enum<rfsv::errs> res; + + if ((res = fopen(P_FSHARE | P_FSTREAM, from, handle_from)) != E_PSI_GEN_NONE) return res; + res = fcreatefile(P_FSTREAM | P_FUPDATE, to, handle_to); + if (res != E_PSI_GEN_NONE) { + res = freplacefile(P_FSTREAM | P_FUPDATE, to, handle_to); + if (res != E_PSI_GEN_NONE) + return res; + } + do { + unsigned char buf[RFSV_SENDLEN]; + if ((res = fread(handle_from, buf, sizeof(buf), len)) == E_PSI_GEN_NONE) { + if (len > 0) { + if ((res = fwrite(handle_to, buf, len, wlen)) == E_PSI_GEN_NONE) { + total += wlen; + if (cb && !cb(ptr, total)) + res = E_PSI_FILE_CANCEL; + } + } + } + } while (len > 0 && wlen > 0 && (res == E_PSI_GEN_NONE)); + fclose(handle_from); + fclose(handle_to); + if (res == E_PSI_FILE_EOF) + res = E_PSI_GEN_NONE; + return res; } Enum<rfsv::errs> rfsv16:: fsetsize(u_int32_t handle, u_int32_t size) { - bufferStore a; - a.addWord(handle & 0xffff); - a.addDWord(size); - if (!sendCommand(FSETEOF, a)) - return E_PSI_FILE_DISC; - return getResponse(a); + bufferStore a; + a.addWord(handle & 0xffff); + a.addDWord(size); + if (!sendCommand(FSETEOF, a)) + return E_PSI_FILE_DISC; + return getResponse(a); } /* @@ -725,14 +724,14 @@ fsetsize(u_int32_t handle, u_int32_t size) Enum<rfsv::errs> rfsv16:: fseek(const u_int32_t handle, const int32_t pos, const u_int32_t mode, u_int32_t &resultpos) { - bufferStore a; - Enum<rfsv::errs> res; - u_int32_t savpos = 0; - u_int32_t realpos; - u_int32_t calcpos = 0; + bufferStore a; + Enum<rfsv::errs> res; + u_int32_t savpos = 0; + u_int32_t realpos; + u_int32_t calcpos = 0; /* - seek-parameter for psion: + seek-parameter for psion: dword position dword handle dword mode @@ -742,150 +741,150 @@ fseek(const u_int32_t handle, const int32_t pos, const u_int32_t mode, u_int32_t ??no more?? 4 = sense recpos ??no more?? 5 = set recpos ??no more?? 6 = text-rewind - */ +*/ - if ((mode < PSI_SEEK_SET) || (mode > PSI_SEEK_END)) - return E_PSI_GEN_ARG; - - if ((mode == PSI_SEEK_CUR) && (pos >= 0)) { - /* get and save current position */ - a.init(); - a.addWord(handle); - a.addDWord(0); - a.addWord(PSI_SEEK_CUR); - if (!sendCommand(FSEEK, a)) - return E_PSI_FILE_DISC; - if ((res = getResponse(a)) != E_PSI_GEN_NONE) - return res; - savpos = a.getDWord(0); - if (pos == 0) { - resultpos = savpos; - return res; - } + if ((mode < PSI_SEEK_SET) || (mode > PSI_SEEK_END)) + return E_PSI_GEN_ARG; + + if ((mode == PSI_SEEK_CUR) && (pos >= 0)) { + /* get and save current position */ + a.init(); + a.addWord(handle); + a.addDWord(0); + a.addWord(PSI_SEEK_CUR); + if (!sendCommand(FSEEK, a)) + return E_PSI_FILE_DISC; + if ((res = getResponse(a)) != E_PSI_GEN_NONE) + return res; + savpos = a.getDWord(0); + if (pos == 0) { + resultpos = savpos; + return res; } - if ((mode == PSI_SEEK_END) && (pos >= 0)) { - /* get and save end position */ - a.init(); - a.addWord(handle); - a.addDWord(0); - a.addWord(PSI_SEEK_END); - if (!sendCommand(FSEEK, a)) - return E_PSI_FILE_DISC; - if ((res = getResponse(a)) != E_PSI_GEN_NONE) - return res; - savpos = a.getDWord(0); - if (pos == 0) { - resultpos = savpos; - return res; - } + } + if ((mode == PSI_SEEK_END) && (pos >= 0)) { + /* get and save end position */ + a.init(); + a.addWord(handle); + a.addDWord(0); + a.addWord(PSI_SEEK_END); + if (!sendCommand(FSEEK, a)) + return E_PSI_FILE_DISC; + if ((res = getResponse(a)) != E_PSI_GEN_NONE) + return res; + savpos = a.getDWord(0); + if (pos == 0) { + resultpos = savpos; + return res; } - /* Now the real seek */ + } + /* Now the real seek */ + a.addWord(handle); + a.addDWord(pos); + a.addWord(mode); + if (!sendCommand(FSEEK, a)) + return E_PSI_FILE_DISC; + if ((res = getResponse(a)) != 0) + return res; + realpos = a.getDWord(0); + switch (mode) { + case PSI_SEEK_SET: + calcpos = pos; + break; + case PSI_SEEK_CUR: + calcpos = savpos + pos; + break; + case PSI_SEEK_END: + resultpos = realpos; + return res; + break; + } + if (calcpos > realpos) { + /* Beyond end of file */ + res = fsetsize(handle, calcpos); + if (res != E_PSI_GEN_NONE) + return res; + a.init(); a.addWord(handle); - a.addDWord(pos); - a.addWord(mode); + a.addDWord(calcpos); + a.addWord(PSI_SEEK_SET); if (!sendCommand(FSEEK, a)) - return E_PSI_FILE_DISC; + return E_PSI_FILE_DISC; if ((res = getResponse(a)) != 0) - return res; + return res; realpos = a.getDWord(0); - switch (mode) { - case PSI_SEEK_SET: - calcpos = pos; - break; - case PSI_SEEK_CUR: - calcpos = savpos + pos; - break; - case PSI_SEEK_END: - resultpos = realpos; - return res; - break; - } - if (calcpos > realpos) { - /* Beyond end of file */ - res = fsetsize(handle, calcpos); - if (res != E_PSI_GEN_NONE) - return res; - a.init(); - a.addWord(handle); - a.addDWord(calcpos); - a.addWord(PSI_SEEK_SET); - if (!sendCommand(FSEEK, a)) - return E_PSI_FILE_DISC; - if ((res = getResponse(a)) != 0) - return res; - realpos = a.getDWord(0); - } - resultpos = realpos; - return res; + } + resultpos = realpos; + return res; } Enum<rfsv::errs> rfsv16:: mkdir(const char* dirName) { - string realName = convertSlash(dirName); - bufferStore a; - a.addStringT(realName.c_str()); - sendCommand(MKDIR, a); - Enum<rfsv::errs> res = getResponse(a); - if (res == E_PSI_GEN_NONE) { - // Correct response - return res; - } - cerr << "Unknown response from mkdir "<< res <<endl; - return E_PSI_GEN_FAIL; + string realName = convertSlash(dirName); + bufferStore a; + a.addStringT(realName.c_str()); + sendCommand(MKDIR, a); + Enum<rfsv::errs> res = getResponse(a); + if (res == E_PSI_GEN_NONE) { + // Correct response + return res; + } + cerr << "Unknown response from mkdir "<< res <<endl; + return E_PSI_GEN_FAIL; } Enum<rfsv::errs> rfsv16:: rmdir(const char *dirName) { - // There doesn't seem to be an RMDIR command, but DELETE works. We - // should probably check to see if the file is a directory first! - return remove(dirName); + // There doesn't seem to be an RMDIR command, but DELETE works. We + // should probably check to see if the file is a directory first! + return remove(dirName); } Enum<rfsv::errs> 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<rfsv::errs> res = getResponse(a); - if (res == E_PSI_GEN_NONE) { - // Correct response - return res; - } - cerr << "Unknown response from rename "<< res <<endl; - return E_PSI_GEN_FAIL; + 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<rfsv::errs> res = getResponse(a); + if (res == E_PSI_GEN_NONE) { + // Correct response + return res; + } + cerr << "Unknown response from rename "<< res <<endl; + return E_PSI_GEN_FAIL; } Enum<rfsv::errs> rfsv16:: remove(const char* psionName) { - Enum<rfsv::errs> 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 <<endl; - return E_PSI_GEN_FAIL; + Enum<rfsv::errs> 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 <<endl; + return E_PSI_GEN_FAIL; } Enum<rfsv::errs> rfsv16:: setVolumeName(const char drive , const char * const name) { -// Not yet ... - return E_PSI_GEN_FAIL; +// Not yet ... + return E_PSI_GEN_FAIL; } /* @@ -894,36 +893,36 @@ setVolumeName(const char drive , const char * const name) u_int32_t rfsv16:: attr2std(u_int32_t attr) { - u_int32_t res = 0; - - // Common attributes - if (!(attr & P_FAWRITE)) - res |= PSI_A_RDONLY; - if (attr & P_FAHIDDEN) - res |= PSI_A_HIDDEN; - if (attr & P_FASYSTEM) - res |= PSI_A_SYSTEM; - if (attr & P_FADIR) - res |= PSI_A_DIR; - if (attr & P_FAMOD) - res |= PSI_A_ARCHIVE; - if (attr & P_FAVOLUME) - res |= PSI_A_VOLUME; - - // SIBO-specific - if (attr & P_FAREAD) - res |= PSI_A_READ; - if (attr & P_FAEXEC) - res |= PSI_A_EXEC; - if (attr & P_FASTREAM) - res |= PSI_A_STREAM; - if (attr & P_FATEXT) - res |= PSI_A_TEXT; - - // Do what we can for EPOC - res |= PSI_A_NORMAL; - - return res; + u_int32_t res = 0; + + // Common attributes + if (!(attr & P_FAWRITE)) + res |= PSI_A_RDONLY; + if (attr & P_FAHIDDEN) + res |= PSI_A_HIDDEN; + if (attr & P_FASYSTEM) + res |= PSI_A_SYSTEM; + if (attr & P_FADIR) + res |= PSI_A_DIR; + if (attr & P_FAMOD) + res |= PSI_A_ARCHIVE; + if (attr & P_FAVOLUME) + res |= PSI_A_VOLUME; + + // SIBO-specific + if (attr & P_FAREAD) + res |= PSI_A_READ; + if (attr & P_FAEXEC) + res |= PSI_A_EXEC; + if (attr & P_FASTREAM) + res |= PSI_A_STREAM; + if (attr & P_FATEXT) + res |= PSI_A_TEXT; + + // Do what we can for EPOC + res |= PSI_A_NORMAL; + + return res; } /* @@ -932,31 +931,37 @@ attr2std(u_int32_t attr) u_int32_t rfsv16:: std2attr(const u_int32_t attr) { - u_int32_t res = 0; - - // Common attributes - if (!(attr & PSI_A_RDONLY)) - res |= P_FAWRITE; - if (attr & PSI_A_HIDDEN) - res |= P_FAHIDDEN; - if (attr & PSI_A_SYSTEM) - res |= P_FASYSTEM; - if (attr & PSI_A_DIR) - res |= P_FADIR; - if (attr & PSI_A_ARCHIVE) - res |= P_FAMOD; - if (attr & PSI_A_VOLUME) - res |= P_FAVOLUME; - - // SIBO-specific - if (attr & PSI_A_READ) - res |= P_FAREAD; - if (attr & PSI_A_EXEC) - res |= P_FAEXEC; - if (attr & PSI_A_STREAM) - res |= P_FASTREAM; - if (attr & PSI_A_TEXT) - res |= P_FATEXT; - - return res; + u_int32_t res = 0; + + // Common attributes + if (!(attr & PSI_A_RDONLY)) + res |= P_FAWRITE; + if (attr & PSI_A_HIDDEN) + res |= P_FAHIDDEN; + if (attr & PSI_A_SYSTEM) + res |= P_FASYSTEM; + if (attr & PSI_A_DIR) + res |= P_FADIR; + if (attr & PSI_A_ARCHIVE) + res |= P_FAMOD; + if (attr & PSI_A_VOLUME) + res |= P_FAVOLUME; + + // SIBO-specific + if (attr & PSI_A_READ) + res |= P_FAREAD; + if (attr & PSI_A_EXEC) + res |= P_FAEXEC; + if (attr & PSI_A_STREAM) + res |= P_FASTREAM; + if (attr & PSI_A_TEXT) + res |= P_FATEXT; + + return res; } + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ diff --git a/lib/rfsv16.h b/lib/rfsv16.h index 42661f8..2cd4393 100644 --- a/lib/rfsv16.h +++ b/lib/rfsv16.h @@ -1,5 +1,28 @@ -#ifndef _rfsv16_h_ -#define _rfsv16_h_ +/*-*-c++-*- + * $Id$ + * + * This file is part of plptools. + * + * Copyright (C) 1999 Philip Proudman <philip.proudman@btinternet.com> + * Copyright (C) 1999-2001 Fritz Elfert <felfert@to.com> + * + * 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 _RFSV16_H_ +#define _RFSV16_H_ #include "rfsv.h" @@ -13,113 +36,123 @@ class rfsvfactory; * @ref rfsv . For a complete documentation, see @ref rfsv . */ class rfsv16 : public rfsv { - friend rfsvfactory; + + /** + * rfsvfactory may call our constructor. + */ + 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 &); - Enum<rfsv::errs> freplacefile(const u_int32_t, const char * const, u_int32_t &); - Enum<rfsv::errs> fclose(const u_int32_t); - Enum<rfsv::errs> dir(const char * const, PlpDir &); - Enum<rfsv::errs> fgetmtime(const char * const, PsiTime &); - Enum<rfsv::errs> fsetmtime(const char * const, const PsiTime); - Enum<rfsv::errs> fgetattr(const char * const, u_int32_t &); - Enum<rfsv::errs> fgeteattr(const char * const, PlpDirent &); - 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, 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); - Enum<rfsv::errs> copyToPsion(const char * const, const char * const, void *, cpCallback_t); - Enum<rfsv::errs> copyOnPsion(const char *, const char *, void *, cpCallback_t); - Enum<rfsv::errs> fsetsize(const u_int32_t, const u_int32_t); - Enum<rfsv::errs> fseek(const u_int32_t, const int32_t, const u_int32_t, u_int32_t &); - Enum<rfsv::errs> mkdir(const char * const); - Enum<rfsv::errs> rmdir(const char * const); - Enum<rfsv::errs> rename(const char * const, const char * const); - Enum<rfsv::errs> remove(const char * const); - Enum<rfsv::errs> opendir(const u_int32_t, const char * const, rfsvDirhandle &); - Enum<rfsv::errs> readdir(rfsvDirhandle &, PlpDirent &); - Enum<rfsv::errs> closedir(rfsvDirhandle &); - Enum<rfsv::errs> setVolumeName(const char, const char * const); + 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 &); + Enum<rfsv::errs> freplacefile(const u_int32_t, const char * const, u_int32_t &); + Enum<rfsv::errs> fclose(const u_int32_t); + Enum<rfsv::errs> dir(const char * const, PlpDir &); + Enum<rfsv::errs> fgetmtime(const char * const, PsiTime &); + Enum<rfsv::errs> fsetmtime(const char * const, const PsiTime); + Enum<rfsv::errs> fgetattr(const char * const, u_int32_t &); + Enum<rfsv::errs> fgeteattr(const char * const, PlpDirent &); + 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, 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); + Enum<rfsv::errs> copyToPsion(const char * const, const char * const, void *, cpCallback_t); + Enum<rfsv::errs> copyOnPsion(const char *, const char *, void *, cpCallback_t); + Enum<rfsv::errs> fsetsize(const u_int32_t, const u_int32_t); + Enum<rfsv::errs> fseek(const u_int32_t, const int32_t, const u_int32_t, u_int32_t &); + Enum<rfsv::errs> mkdir(const char * const); + Enum<rfsv::errs> rmdir(const char * const); + Enum<rfsv::errs> rename(const char * const, const char * const); + Enum<rfsv::errs> remove(const char * const); + Enum<rfsv::errs> opendir(const u_int32_t, const char * const, rfsvDirhandle &); + Enum<rfsv::errs> readdir(rfsvDirhandle &, PlpDirent &); + Enum<rfsv::errs> closedir(rfsvDirhandle &); + Enum<rfsv::errs> setVolumeName(const char, const char * const); - u_int32_t opMode(const u_int32_t); + u_int32_t opMode(const u_int32_t); private: - enum commands { - FOPEN = 0, // File Open - FCLOSE = 2, // File Close - FREAD = 4, // File Read - FDIRREAD = 6, // Read Directory entries - FDEVICEREAD = 8, // Device Information - FWRITE = 10, // File Write - FSEEK = 12, // File Seek - FFLUSH = 14, // Flush - FSETEOF = 16, - RENAME = 18, - DELETE = 20, - FINFO = 22, - SFSTAT = 24, - PARSE = 26, - MKDIR = 28, - OPENUNIQUE = 30, - STATUSDEVICE = 32, - PATHTEST = 34, - STATUSSYSTEM = 36, - CHANGEDIR = 38, - SFDATE = 40, - RESPONSE = 42 - }; + enum commands { + FOPEN = 0, // File Open + FCLOSE = 2, // File Close + FREAD = 4, // File Read + FDIRREAD = 6, // Read Directory entries + FDEVICEREAD = 8, // Device Information + FWRITE = 10, // File Write + FSEEK = 12, // File Seek + FFLUSH = 14, // Flush + FSETEOF = 16, + RENAME = 18, + DELETE = 20, + FINFO = 22, + SFSTAT = 24, + PARSE = 26, + MKDIR = 28, + OPENUNIQUE = 30, + STATUSDEVICE = 32, + PATHTEST = 34, + STATUSSYSTEM = 36, + CHANGEDIR = 38, + SFDATE = 40, + RESPONSE = 42 + }; - enum fopen_attrib { - P_FOPEN = 0x0000, /* Open file */ - P_FCREATE = 0x0001, /* Create file */ - P_FREPLACE = 0x0002, /* Replace file */ - P_FAPPEND = 0x0003, /* Append records */ - P_FUNIQUE = 0x0004, /* Unique file open */ - P_FSTREAM = 0x0000, /* Stream access to a binary file */ - P_FSTREAM_TEXT = 0x0010, /* Stream access to a text file */ - P_FTEXT = 0x0020, /* Record access to a text file */ - P_FDIR = 0x0030, /* Record access to a directory file */ - P_FFORMAT = 0x0040, /* Format a device */ - P_FDEVICE = 0x0050, /* Record access to device name list */ - P_FNODE = 0x0060, /* Record access to node name list */ - P_FUPDATE = 0x0100, /* Read and write access */ - P_FRANDOM = 0x0200, /* Random access */ - P_FSHARE = 0x0400 /* File can be shared */ - }; + enum fopen_attrib { + P_FOPEN = 0x0000, /* Open file */ + P_FCREATE = 0x0001, /* Create file */ + P_FREPLACE = 0x0002, /* Replace file */ + P_FAPPEND = 0x0003, /* Append records */ + P_FUNIQUE = 0x0004, /* Unique file open */ + P_FSTREAM = 0x0000, /* Stream access to a binary file */ + P_FSTREAM_TEXT = 0x0010, /* Stream access to a text file */ + P_FTEXT = 0x0020, /* Record access to a text file */ + P_FDIR = 0x0030, /* Record access to a directory file */ + P_FFORMAT = 0x0040, /* Format a device */ + P_FDEVICE = 0x0050, /* Record access to device name list */ + P_FNODE = 0x0060, /* Record access to node name list */ + P_FUPDATE = 0x0100, /* Read and write access */ + P_FRANDOM = 0x0200, /* Random access */ + P_FSHARE = 0x0400 /* File can be shared */ + }; - enum status_enum { - P_FAWRITE = 0x0001, /* can the file be written to? */ - P_FAHIDDEN = 0x0002, /* set if file is hidden */ - P_FASYSTEM = 0x0004, /* set if file is a system file */ - P_FAVOLUME = 0x0008, /* set if the name is a volume name */ - P_FADIR = 0x0010, /* set if file is a directory file */ - P_FAMOD = 0x0020, /* has the file been modified? */ - P_FAREAD = 0x0100, /* can the file be read? */ - P_FAEXEC = 0x0200, /* is the file executable? */ - P_FASTREAM = 0x0400, /* is the file a byte stream file? */ - P_FATEXT = 0x0800, /* is it a text file? */ - P_FAMASK = 0x0f3f /* All of the above */ - }; + enum status_enum { + P_FAWRITE = 0x0001, /* can the file be written to? */ + P_FAHIDDEN = 0x0002, /* set if file is hidden */ + P_FASYSTEM = 0x0004, /* set if file is a system file */ + P_FAVOLUME = 0x0008, /* set if the name is a volume name */ + P_FADIR = 0x0010, /* set if file is a directory file */ + P_FAMOD = 0x0020, /* has the file been modified? */ + P_FAREAD = 0x0100, /* can the file be read? */ + P_FAEXEC = 0x0200, /* is the file executable? */ + P_FASTREAM = 0x0400, /* is the file a byte stream file? */ + P_FATEXT = 0x0800, /* is it a text file? */ + P_FAMASK = 0x0f3f /* All of the above */ + }; - /** - * Private constructor. Shall be called by - * rfsvfactory only. - */ - rfsv16(ppsocket *); + /** + * Private constructor. Shall be called by + * rfsvfactory only. + */ + rfsv16(ppsocket *); - // Miscellaneous - Enum<rfsv::errs> fopendir(const char * const, u_int32_t &); - u_int32_t attr2std(const u_int32_t); - u_int32_t std2attr(const u_int32_t); + // Miscellaneous + Enum<rfsv::errs> fopendir(const char * const, u_int32_t &); + u_int32_t attr2std(const u_int32_t); + u_int32_t std2attr(const u_int32_t); - // Communication - bool sendCommand(enum commands, bufferStore &); - Enum<rfsv::errs> getResponse(bufferStore &); + // Communication + bool sendCommand(enum commands, bufferStore &); + Enum<rfsv::errs> getResponse(bufferStore &); }; #endif + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ diff --git a/lib/rfsv32.cc b/lib/rfsv32.cc index 0e6fd47..2dc5fbb 100644 --- a/lib/rfsv32.cc +++ b/lib/rfsv32.cc @@ -1,24 +1,26 @@ -// -// PLP - An implementation of the PSION link protocol -// -// Copyright (C) 1999 Philip Proudman -// -// 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 -// -// e-mail philip.proudman@btinternet.com - +/*-*-c++-*- + * $Id$ + * + * This file is part of plptools. + * + * Copyright (C) 1999 Philip Proudman <philip.proudman@btinternet.com> + * Copyright (C) 1999-2001 Fritz Elfert <felfert@to.com> + * + * 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 + * + */ #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -38,561 +40,561 @@ rfsv32::rfsv32(ppsocket * _skt) { - skt = _skt; - serNum = 0; - status = rfsv::E_PSI_FILE_DISC; - reset(); + skt = _skt; + serNum = 0; + status = rfsv::E_PSI_FILE_DISC; + reset(); } Enum<rfsv::errs> rfsv32:: fopen(u_int32_t attr, const char *name, u_int32_t &handle) { - bufferStore a; - string n = convertSlash(name); - a.addDWord(attr); - a.addWord(n.size()); - a.addString(n.c_str()); - if (!sendCommand(OPEN_FILE, a)) - return E_PSI_FILE_DISC; - Enum<rfsv::errs> res = getResponse(a); - if (res == E_PSI_GEN_NONE && a.getLen() == 4) { - handle = a.getDWord(0); - return E_PSI_GEN_NONE; - } - return res; + bufferStore a; + string n = convertSlash(name); + a.addDWord(attr); + a.addWord(n.size()); + a.addString(n.c_str()); + if (!sendCommand(OPEN_FILE, a)) + return E_PSI_FILE_DISC; + Enum<rfsv::errs> res = getResponse(a); + if (res == E_PSI_GEN_NONE && a.getLen() == 4) { + handle = a.getDWord(0); + return E_PSI_GEN_NONE; + } + return res; } Enum<rfsv::errs> rfsv32:: mktemp(u_int32_t &handle, string &tmpname) { - bufferStore a; - if (!sendCommand(TEMP_FILE, a)) - return E_PSI_FILE_DISC; - Enum<rfsv::errs> res = getResponse(a); - if (res == E_PSI_GEN_NONE) { - handle = a.getDWord(0); - tmpname = a.getString(6); - } - return res; + bufferStore a; + if (!sendCommand(TEMP_FILE, a)) + return E_PSI_FILE_DISC; + Enum<rfsv::errs> res = getResponse(a); + if (res == E_PSI_GEN_NONE) { + handle = a.getDWord(0); + tmpname = a.getString(6); + } + return res; } Enum<rfsv::errs> rfsv32:: fcreatefile(u_int32_t attr, const char *name, u_int32_t &handle) { - bufferStore a; - string n = convertSlash(name); - a.addDWord(attr); - a.addWord(n.size()); - a.addString(n.c_str()); - if (!sendCommand(CREATE_FILE, a)) - return E_PSI_FILE_DISC; - Enum<rfsv::errs> res = getResponse(a); - if (res == E_PSI_GEN_NONE && a.getLen() == 4) - handle = a.getDWord(0); - return res; + bufferStore a; + string n = convertSlash(name); + a.addDWord(attr); + a.addWord(n.size()); + a.addString(n.c_str()); + if (!sendCommand(CREATE_FILE, a)) + return E_PSI_FILE_DISC; + Enum<rfsv::errs> res = getResponse(a); + if (res == E_PSI_GEN_NONE && a.getLen() == 4) + handle = a.getDWord(0); + return res; } Enum<rfsv::errs> rfsv32:: freplacefile(const u_int32_t attr, const char * const name, u_int32_t &handle) { - bufferStore a; - string n = convertSlash(name); - a.addDWord(attr); - a.addWord(n.size()); - a.addString(n.c_str()); - if (!sendCommand(REPLACE_FILE, a)) - return E_PSI_FILE_DISC; - Enum<rfsv::errs> res = getResponse(a); - if (res == E_PSI_GEN_NONE && a.getLen() == 4) - handle = a.getDWord(0); - return res; + bufferStore a; + string n = convertSlash(name); + a.addDWord(attr); + a.addWord(n.size()); + a.addString(n.c_str()); + if (!sendCommand(REPLACE_FILE, a)) + return E_PSI_FILE_DISC; + Enum<rfsv::errs> res = getResponse(a); + if (res == E_PSI_GEN_NONE && a.getLen() == 4) + handle = a.getDWord(0); + return res; } Enum<rfsv::errs> rfsv32:: fopendir(const u_int32_t attr, const char * const name, u_int32_t &handle) { - bufferStore a; - string n = convertSlash(name); - a.addDWord(attr | EPOC_ATTR_GETUID); - a.addWord(n.size()); - a.addString(n.c_str()); - if (!sendCommand(OPEN_DIR, a)) - return E_PSI_FILE_DISC; - Enum<rfsv::errs> res = getResponse(a); - if (!res && a.getLen() == 4) - handle = a.getDWord(0); - return res; + bufferStore a; + string n = convertSlash(name); + a.addDWord(attr | EPOC_ATTR_GETUID); + a.addWord(n.size()); + a.addString(n.c_str()); + if (!sendCommand(OPEN_DIR, a)) + return E_PSI_FILE_DISC; + Enum<rfsv::errs> res = getResponse(a); + if (!res && a.getLen() == 4) + handle = a.getDWord(0); + return res; } Enum<rfsv::errs> rfsv32:: fclose(u_int32_t handle) { - bufferStore a; - a.addDWord(handle); - if (!sendCommand(CLOSE_HANDLE, a)) - return E_PSI_FILE_DISC; - return getResponse(a); + bufferStore a; + a.addDWord(handle); + if (!sendCommand(CLOSE_HANDLE, a)) + return E_PSI_FILE_DISC; + return getResponse(a); } Enum<rfsv::errs> rfsv32:: opendir(const u_int32_t attr, const char *name, rfsvDirhandle &dH) { - u_int32_t handle; - Enum<rfsv::errs> res = fopendir(std2attr(attr), name, handle); - dH.h = handle; - dH.b.init(); - return res; + u_int32_t handle; + Enum<rfsv::errs> res = fopendir(std2attr(attr), name, handle); + dH.h = handle; + dH.b.init(); + return res; } Enum<rfsv::errs> rfsv32:: closedir(rfsvDirhandle &dH) { - return fclose(dH.h); + return fclose(dH.h); } Enum<rfsv::errs> rfsv32:: readdir(rfsvDirhandle &dH, PlpDirent &e) { - Enum<rfsv::errs> res = E_PSI_GEN_NONE; - - if (dH.b.getLen() < 17) { - dH.b.init(); - dH.b.addDWord(dH.h); - if (!sendCommand(READ_DIR, dH.b)) - return E_PSI_FILE_DISC; - res = getResponse(dH.b); - } - if ((res == E_PSI_GEN_NONE) && (dH.b.getLen() > 16)) { - long shortLen = dH.b.getDWord(0); - long longLen = dH.b.getDWord(32); - - e.attr = attr2std(dH.b.getDWord(4)); - e.size = dH.b.getDWord(8); - e.UID = PlpUID(dH.b.getDWord(20), dH.b.getDWord(24), dH.b.getDWord(28)); - e.time = PsiTime(dH.b.getDWord(16), dH.b.getDWord(12)); - e.name = ""; - e.attrstr = string(attr2String(e.attr)); - - int d = 36; - for (int i = 0; i < longLen; i++, d++) - e.name += dH.b.getByte(d); - while (d % 4) - d++; - d += shortLen; - while (d % 4) - d++; - dH.b.discardFirstBytes(d); - } - return res; + Enum<rfsv::errs> res = E_PSI_GEN_NONE; + + if (dH.b.getLen() < 17) { + dH.b.init(); + dH.b.addDWord(dH.h); + if (!sendCommand(READ_DIR, dH.b)) + return E_PSI_FILE_DISC; + res = getResponse(dH.b); + } + if ((res == E_PSI_GEN_NONE) && (dH.b.getLen() > 16)) { + long shortLen = dH.b.getDWord(0); + long longLen = dH.b.getDWord(32); + + e.attr = attr2std(dH.b.getDWord(4)); + e.size = dH.b.getDWord(8); + e.UID = PlpUID(dH.b.getDWord(20), dH.b.getDWord(24), dH.b.getDWord(28)); + e.time = PsiTime(dH.b.getDWord(16), dH.b.getDWord(12)); + e.name = ""; + e.attrstr = string(attr2String(e.attr)); + + int d = 36; + for (int i = 0; i < longLen; i++, d++) + e.name += dH.b.getByte(d); + while (d % 4) + d++; + d += shortLen; + while (d % 4) + d++; + dH.b.discardFirstBytes(d); + } + return res; } Enum<rfsv::errs> rfsv32:: dir(const char *name, PlpDir &files) { - rfsvDirhandle h; - files.clear(); - Enum<rfsv::errs> 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) - files.push_back(e); - } - closedir(h); - if (res == E_PSI_FILE_EOF) - res = E_PSI_GEN_NONE; - return res; + rfsvDirhandle h; + files.clear(); + Enum<rfsv::errs> 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) + files.push_back(e); + } + closedir(h); + if (res == E_PSI_FILE_EOF) + res = E_PSI_GEN_NONE; + return res; } u_int32_t rfsv32:: opMode(const u_int32_t mode) { - u_int32_t ret = 0; + u_int32_t ret = 0; - ret |= (((mode & 03) == PSI_O_RDONLY) ? 0 : EPOC_OMODE_READ_WRITE); - if (!ret) - ret |= (mode & PSI_O_EXCL) ? 0 : EPOC_OMODE_SHARE_READERS; - return ret; + ret |= (((mode & 03) == PSI_O_RDONLY) ? 0 : EPOC_OMODE_READ_WRITE); + if (!ret) + ret |= (mode & PSI_O_EXCL) ? 0 : EPOC_OMODE_SHARE_READERS; + return ret; } Enum<rfsv::errs> rfsv32:: fgetmtime(const char * const name, PsiTime &mtime) { - bufferStore a; - string n = convertSlash(name); - a.addWord(n.size()); - a.addString(n.c_str()); - if (!sendCommand(MODIFIED, a)) - return E_PSI_FILE_DISC; - Enum<rfsv::errs> res = getResponse(a); - if (res != E_PSI_GEN_NONE) - return res; - mtime.setPsiTime(a.getDWord(4), a.getDWord(0)); + bufferStore a; + string n = convertSlash(name); + a.addWord(n.size()); + a.addString(n.c_str()); + if (!sendCommand(MODIFIED, a)) + return E_PSI_FILE_DISC; + Enum<rfsv::errs> res = getResponse(a); + if (res != E_PSI_GEN_NONE) return res; + mtime.setPsiTime(a.getDWord(4), a.getDWord(0)); + return res; } Enum<rfsv::errs> rfsv32:: fsetmtime(const char * const name, PsiTime mtime) { - bufferStore a; - string n = convertSlash(name); - a.addDWord(mtime.getPsiTimeLo()); - a.addDWord(mtime.getPsiTimeHi()); - a.addWord(n.size()); - a.addString(n.c_str()); - if (!sendCommand(SET_MODIFIED, a)) - return E_PSI_FILE_DISC; - return getResponse(a); + bufferStore a; + string n = convertSlash(name); + a.addDWord(mtime.getPsiTimeLo()); + a.addDWord(mtime.getPsiTimeHi()); + a.addWord(n.size()); + a.addString(n.c_str()); + if (!sendCommand(SET_MODIFIED, a)) + return E_PSI_FILE_DISC; + return getResponse(a); } Enum<rfsv::errs> rfsv32:: fgetattr(const char * const name, u_int32_t &attr) { - bufferStore a; - string n = convertSlash(name); - a.addWord(n.size()); - a.addString(n.c_str()); - if (!sendCommand(ATT, a)) - return E_PSI_FILE_DISC; - Enum<rfsv::errs> res = getResponse(a); - if (res != E_PSI_GEN_NONE) - return res; - attr = attr2std(a.getDWord(0)); + bufferStore a; + string n = convertSlash(name); + a.addWord(n.size()); + a.addString(n.c_str()); + if (!sendCommand(ATT, a)) + return E_PSI_FILE_DISC; + Enum<rfsv::errs> res = getResponse(a); + if (res != E_PSI_GEN_NONE) return res; + attr = attr2std(a.getDWord(0)); + return res; } Enum<rfsv::errs> rfsv32:: fgeteattr(const char * const name, PlpDirent &e) { - bufferStore a; - string n = convertSlash(name); - a.addWord(n.size()); - a.addString(n.c_str()); - const char *p = strrchr(n.c_str(), '\\'); - if (p) - p++; - else - p = n.c_str(); - e.name = p; - - if (!sendCommand(REMOTE_ENTRY, a)) - return E_PSI_FILE_DISC; - Enum<rfsv::errs> res = getResponse(a); - if (res != E_PSI_GEN_NONE) - return res; - // long shortLen = a.getDWord(0); - // long longLen = a.getDWord(32); + bufferStore a; + string n = convertSlash(name); + a.addWord(n.size()); + a.addString(n.c_str()); + const char *p = strrchr(n.c_str(), '\\'); + if (p) + p++; + else + p = n.c_str(); + e.name = p; + + if (!sendCommand(REMOTE_ENTRY, a)) + return E_PSI_FILE_DISC; + Enum<rfsv::errs> res = getResponse(a); + if (res != E_PSI_GEN_NONE) + return res; + // long shortLen = a.getDWord(0); + // long longLen = a.getDWord(32); - e.attr = attr2std(a.getDWord(4)); - e.size = a.getDWord(8); - e.UID = PlpUID(a.getDWord(20), a.getDWord(24), a.getDWord(28)); - e.time = PsiTime(a.getDWord(16), a.getDWord(12)); - e.attrstr = string(attr2String(e.attr)); + e.attr = attr2std(a.getDWord(4)); + e.size = a.getDWord(8); + e.UID = PlpUID(a.getDWord(20), a.getDWord(24), a.getDWord(28)); + e.time = PsiTime(a.getDWord(16), a.getDWord(12)); + e.attrstr = string(attr2String(e.attr)); - return res; + return res; } Enum<rfsv::errs> rfsv32:: fsetattr(const char * const name, const u_int32_t seta, const u_int32_t unseta) { - bufferStore a; - string n = convertSlash(name); - a.addDWord(std2attr(seta)); - a.addDWord(std2attr(unseta)); - a.addWord(n.size()); - a.addString(n.c_str()); - if (!sendCommand(SET_ATT, a)) - return E_PSI_FILE_DISC; - return getResponse(a); + bufferStore a; + string n = convertSlash(name); + a.addDWord(std2attr(seta)); + a.addDWord(std2attr(unseta)); + a.addWord(n.size()); + a.addString(n.c_str()); + if (!sendCommand(SET_ATT, a)) + return E_PSI_FILE_DISC; + return getResponse(a); } Enum<rfsv::errs> rfsv32:: dircount(const char * const name, u_int32_t &count) { - u_int32_t handle; - Enum<rfsv::errs> res = fopendir(EPOC_ATTR_HIDDEN | EPOC_ATTR_SYSTEM | EPOC_ATTR_DIRECTORY, name, handle); - count = 0; - if (res != E_PSI_GEN_NONE) - return res; + u_int32_t handle; + Enum<rfsv::errs> res = fopendir(EPOC_ATTR_HIDDEN | EPOC_ATTR_SYSTEM | EPOC_ATTR_DIRECTORY, name, handle); + count = 0; + if (res != E_PSI_GEN_NONE) + return res; - while (1) { - bufferStore a; - a.addDWord(handle); - if (!sendCommand(READ_DIR, a)) - return E_PSI_FILE_DISC; - res = getResponse(a); - if (res != E_PSI_GEN_NONE) - break; - while (a.getLen() > 16) { - int d = 36 + a.getDWord(32); - while (d % 4) - d++; - d += a.getDWord(0); - while (d % 4) - d++; - a.discardFirstBytes(d); - count++; - } + while (1) { + bufferStore a; + a.addDWord(handle); + if (!sendCommand(READ_DIR, a)) + return E_PSI_FILE_DISC; + res = getResponse(a); + if (res != E_PSI_GEN_NONE) + break; + while (a.getLen() > 16) { + int d = 36 + a.getDWord(32); + while (d % 4) + d++; + d += a.getDWord(0); + while (d % 4) + d++; + a.discardFirstBytes(d); + count++; } - fclose(handle); - if (res == E_PSI_FILE_EOF) - res = E_PSI_GEN_NONE; - return res; + } + fclose(handle); + if (res == E_PSI_FILE_EOF) + res = E_PSI_GEN_NONE; + return res; } Enum<rfsv::errs> rfsv32:: devlist(u_int32_t &devbits) { - bufferStore a; - Enum<rfsv::errs> res; - - if (!sendCommand(GET_DRIVE_LIST, a)) - return E_PSI_FILE_DISC; - res = getResponse(a); - devbits = 0; - if ((res == E_PSI_GEN_NONE) && (a.getLen() == 26)) { - for (int i = 25; i >= 0; i--) { - devbits <<= 1; - if (a.getByte(i) != 0) - devbits |= 1; - } + bufferStore a; + Enum<rfsv::errs> res; + + if (!sendCommand(GET_DRIVE_LIST, a)) + return E_PSI_FILE_DISC; + res = getResponse(a); + devbits = 0; + if ((res == E_PSI_GEN_NONE) && (a.getLen() == 26)) { + for (int i = 25; i >= 0; i--) { + devbits <<= 1; + if (a.getByte(i) != 0) + devbits |= 1; } - return res; + } + return res; } Enum<rfsv::errs> rfsv32:: devinfo(const u_int32_t dev, PlpDrive &drive) { - bufferStore a; - Enum<rfsv::errs> res; - - a.addDWord(dev); - if (!sendCommand(DRIVE_INFO, a)) - return E_PSI_FILE_DISC; - res = getResponse(a); - if (res == E_PSI_GEN_NONE) { - 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); - drive.setName('A' + dev, a.getString(40)); - } - return res; + bufferStore a; + Enum<rfsv::errs> res; + + a.addDWord(dev); + if (!sendCommand(DRIVE_INFO, a)) + return E_PSI_FILE_DISC; + res = getResponse(a); + if (res == E_PSI_GEN_NONE) { + 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); + drive.setName('A' + dev, a.getString(40)); + } + return res; } bool rfsv32:: sendCommand(enum commands cc, bufferStore & data) { - if (status == E_PSI_FILE_DISC) { - reconnect(); - if (status == E_PSI_FILE_DISC) - return false; - } - bool result; - bufferStore a; - a.addWord(cc); - a.addWord(serNum); - if (serNum < 0xffff) - serNum++; - else - serNum = 0; - a.addBuff(data); + if (status == E_PSI_FILE_DISC) { + reconnect(); + if (status == E_PSI_FILE_DISC) + return false; + } + bool result; + bufferStore a; + a.addWord(cc); + a.addWord(serNum); + if (serNum < 0xffff) + serNum++; + else + serNum = 0; + a.addBuff(data); + result = skt->sendBufferStore(a); + if (!result) { + reconnect(); result = skt->sendBufferStore(a); - if (!result) { - reconnect(); - result = skt->sendBufferStore(a); if (!result) - status = E_PSI_FILE_DISC; - } - return result; + status = E_PSI_FILE_DISC; + } + return result; } Enum<rfsv::errs> rfsv32:: getResponse(bufferStore & data) { - if (skt->getBufferStore(data) == 1 && - data.getWord(0) == 0x11) { - int32_t ret = data.getDWord(4); - data.discardFirstBytes(8); - return err2psierr(ret); - } else - status = E_PSI_FILE_DISC; - return status; + if (skt->getBufferStore(data) == 1 && + data.getWord(0) == 0x11) { + int32_t ret = data.getDWord(4); + data.discardFirstBytes(8); + return err2psierr(ret); + } else + status = E_PSI_FILE_DISC; + return status; } Enum<rfsv::errs> rfsv32:: fread(const u_int32_t handle, unsigned char * const buf, const u_int32_t len, u_int32_t &count) { - Enum<rfsv::errs> res; - count = 0; - long l; - unsigned char *p = buf; - - do { - bufferStore a; - a.addDWord(handle); - a.addDWord(((len - count) > RFSV_SENDLEN)?RFSV_SENDLEN:(len - count)); - if (!sendCommand(READ_FILE, a)) - return E_PSI_FILE_DISC; - if ((res = getResponse(a)) != E_PSI_GEN_NONE) - return res; - if ((l = a.getLen()) > 0) { - memcpy(p, a.getString(), l); - count += l; - p += res; - } - } while ((count < len) && (l > 0)); - return res; + Enum<rfsv::errs> res; + count = 0; + long l; + unsigned char *p = buf; + + do { + bufferStore a; + a.addDWord(handle); + a.addDWord(((len - count) > RFSV_SENDLEN)?RFSV_SENDLEN:(len - count)); + if (!sendCommand(READ_FILE, a)) + return E_PSI_FILE_DISC; + if ((res = getResponse(a)) != E_PSI_GEN_NONE) + return res; + if ((l = a.getLen()) > 0) { + memcpy(p, a.getString(), l); + count += l; + p += res; + } + } while ((count < len) && (l > 0)); + return res; } Enum<rfsv::errs> rfsv32:: fwrite(const u_int32_t handle, const unsigned char * const buf, const u_int32_t len, u_int32_t &count) { - Enum<rfsv::errs> res; - const unsigned char *p = buf; - long l; - - count = 0; - do { - l = ((len - count) > RFSV_SENDLEN)?RFSV_SENDLEN:(len - count); - if (l > 0) { - bufferStore a; - bufferStore tmp(p, l); - a.addDWord(handle); - a.addBuff(tmp); - if (!sendCommand(WRITE_FILE, a)) - return E_PSI_FILE_DISC; - if ((res = getResponse(a)) != E_PSI_GEN_NONE) - return res; - count += l; - p += l; - } - } while ((count < len) && (l > 0)); - return res; + Enum<rfsv::errs> res; + const unsigned char *p = buf; + long l; + + count = 0; + do { + l = ((len - count) > RFSV_SENDLEN)?RFSV_SENDLEN:(len - count); + if (l > 0) { + bufferStore a; + bufferStore tmp(p, l); + a.addDWord(handle); + a.addBuff(tmp); + if (!sendCommand(WRITE_FILE, a)) + return E_PSI_FILE_DISC; + if ((res = getResponse(a)) != E_PSI_GEN_NONE) + return res; + count += l; + p += l; + } + } while ((count < len) && (l > 0)); + return res; } Enum<rfsv::errs> rfsv32:: copyFromPsion(const char *from, const char *to, void *ptr, cpCallback_t cb) { - Enum<rfsv::errs> res; - u_int32_t handle; - u_int32_t len; - u_int32_t total = 0; + Enum<rfsv::errs> res; + u_int32_t handle; + u_int32_t len; + u_int32_t total = 0; - if ((res = fopen(EPOC_OMODE_SHARE_READERS | EPOC_OMODE_BINARY, from, handle)) != E_PSI_GEN_NONE) - return res; - ofstream op(to); - if (!op) { - fclose(handle); - return E_PSI_GEN_FAIL; - } - unsigned char *buff = new unsigned char[RFSV_SENDLEN]; - do { - if ((res = fread(handle, buff, RFSV_SENDLEN, len)) == E_PSI_GEN_NONE) { - op.write(buff, len); - total += len; - if (cb && !cb(ptr, total)) - res = E_PSI_FILE_CANCEL; - } - } while ((len > 0) && (res == E_PSI_GEN_NONE)); - delete[]buff; - fclose(handle); - op.close(); + if ((res = fopen(EPOC_OMODE_SHARE_READERS | EPOC_OMODE_BINARY, from, handle)) != E_PSI_GEN_NONE) return res; + ofstream op(to); + if (!op) { + fclose(handle); + return E_PSI_GEN_FAIL; + } + unsigned char *buff = new unsigned char[RFSV_SENDLEN]; + do { + if ((res = fread(handle, buff, RFSV_SENDLEN, len)) == E_PSI_GEN_NONE) { + op.write(buff, len); + total += len; + if (cb && !cb(ptr, total)) + res = E_PSI_FILE_CANCEL; + } + } while ((len > 0) && (res == E_PSI_GEN_NONE)); + delete[]buff; + fclose(handle); + op.close(); + return res; } Enum<rfsv::errs> rfsv32:: copyToPsion(const char *from, const char *to, void *ptr, cpCallback_t cb) { - u_int32_t handle; - Enum<rfsv::errs> res; + u_int32_t handle; + Enum<rfsv::errs> res; - ifstream ip(from); - if (!ip) - return E_PSI_FILE_NXIST; - res = fcreatefile(EPOC_OMODE_BINARY | EPOC_OMODE_SHARE_EXCLUSIVE | EPOC_OMODE_READ_WRITE, to, handle); - if (res != E_PSI_GEN_NONE) { - res = freplacefile(EPOC_OMODE_BINARY | EPOC_OMODE_SHARE_EXCLUSIVE | EPOC_OMODE_READ_WRITE, to, handle); - if (res != E_PSI_GEN_NONE) - return res; - } - unsigned char *buff = new unsigned char[RFSV_SENDLEN]; - u_int32_t total = 0; - while (ip && !ip.eof() && (res == E_PSI_GEN_NONE)) { - u_int32_t len; - ip.read(buff, RFSV_SENDLEN); - if ((res = fwrite(handle, buff, ip.gcount(), len)) == E_PSI_GEN_NONE) { - total += len; - if (cb && !cb(ptr, total)) - res = E_PSI_FILE_CANCEL; - } + ifstream ip(from); + if (!ip) + return E_PSI_FILE_NXIST; + res = fcreatefile(EPOC_OMODE_BINARY | EPOC_OMODE_SHARE_EXCLUSIVE | EPOC_OMODE_READ_WRITE, to, handle); + if (res != E_PSI_GEN_NONE) { + res = freplacefile(EPOC_OMODE_BINARY | EPOC_OMODE_SHARE_EXCLUSIVE | EPOC_OMODE_READ_WRITE, to, handle); + if (res != E_PSI_GEN_NONE) + return res; + } + unsigned char *buff = new unsigned char[RFSV_SENDLEN]; + u_int32_t total = 0; + while (ip && !ip.eof() && (res == E_PSI_GEN_NONE)) { + u_int32_t len; + ip.read(buff, RFSV_SENDLEN); + if ((res = fwrite(handle, buff, ip.gcount(), len)) == E_PSI_GEN_NONE) { + total += len; + if (cb && !cb(ptr, total)) + res = E_PSI_FILE_CANCEL; } - fclose(handle); - ip.close(); - delete[]buff; - return res; + } + fclose(handle); + ip.close(); + delete[]buff; + return res; } Enum<rfsv::errs> rfsv32:: copyOnPsion(const char *from, const char *to, void *ptr, cpCallback_t cb) { - u_int32_t handle_from; - u_int32_t handle_to; - PlpDirent from_e; - Enum<rfsv::errs> res; + u_int32_t handle_from; + u_int32_t handle_to; + PlpDirent from_e; + Enum<rfsv::errs> res; - if ((res = fgeteattr(from, from_e)) != E_PSI_GEN_NONE) - return res; - if ((res = fopen(EPOC_OMODE_SHARE_READERS | EPOC_OMODE_BINARY, from, handle_from)) - != E_PSI_GEN_NONE) - return res; - res = fcreatefile(EPOC_OMODE_BINARY | EPOC_OMODE_SHARE_EXCLUSIVE | EPOC_OMODE_READ_WRITE, to, handle_to); + if ((res = fgeteattr(from, from_e)) != E_PSI_GEN_NONE) + return res; + if ((res = fopen(EPOC_OMODE_SHARE_READERS | EPOC_OMODE_BINARY, from, handle_from)) + != E_PSI_GEN_NONE) + return res; + res = fcreatefile(EPOC_OMODE_BINARY | EPOC_OMODE_SHARE_EXCLUSIVE | EPOC_OMODE_READ_WRITE, to, handle_to); + if (res != E_PSI_GEN_NONE) { + res = freplacefile(EPOC_OMODE_BINARY | EPOC_OMODE_SHARE_EXCLUSIVE | EPOC_OMODE_READ_WRITE, to, handle_to); if (res != E_PSI_GEN_NONE) { - res = freplacefile(EPOC_OMODE_BINARY | EPOC_OMODE_SHARE_EXCLUSIVE | EPOC_OMODE_READ_WRITE, to, handle_to); - if (res != E_PSI_GEN_NONE) { - fclose(handle_from); - return res; - } + fclose(handle_from); + return res; } - - u_int32_t total = 0; - while (res == E_PSI_GEN_NONE) { - bufferStore b; - b.addDWord(RFSV_SENDLEN * 10); - b.addDWord(handle_to); - b.addDWord(handle_from); - if (!sendCommand(READ_WRITE_FILE, b)) - return E_PSI_FILE_DISC; - res = getResponse(b); - if (res != E_PSI_GEN_NONE) - break; - if (b.getLen() != 4) { - res = E_PSI_GEN_FAIL; - break; - } - u_int32_t len = b.getDWord(0); - total += len; - if (cb && !cb(ptr, total)) - res = E_PSI_FILE_CANCEL; - if (len != (RFSV_SENDLEN * 10)) - break; - } - fclose(handle_from); - fclose(handle_to); + } + + u_int32_t total = 0; + while (res == E_PSI_GEN_NONE) { + bufferStore b; + b.addDWord(RFSV_SENDLEN * 10); + b.addDWord(handle_to); + b.addDWord(handle_from); + if (!sendCommand(READ_WRITE_FILE, b)) + return E_PSI_FILE_DISC; + res = getResponse(b); if (res != E_PSI_GEN_NONE) - remove(to); - return res; + break; + if (b.getLen() != 4) { + res = E_PSI_GEN_FAIL; + break; + } + u_int32_t len = b.getDWord(0); + total += len; + if (cb && !cb(ptr, total)) + res = E_PSI_FILE_CANCEL; + if (len != (RFSV_SENDLEN * 10)) + break; + } + fclose(handle_from); + fclose(handle_to); + if (res != E_PSI_GEN_NONE) + remove(to); + return res; } Enum<rfsv::errs> rfsv32:: fsetsize(u_int32_t handle, u_int32_t size) { - bufferStore a; - a.addDWord(handle); - a.addDWord(size); - if (!sendCommand(SET_SIZE, a)) - return E_PSI_FILE_DISC; - return getResponse(a); + bufferStore a; + a.addDWord(handle); + a.addDWord(size); + if (!sendCommand(SET_SIZE, a)) + return E_PSI_FILE_DISC; + return getResponse(a); } /* @@ -603,15 +605,15 @@ fsetsize(u_int32_t handle, u_int32_t size) Enum<rfsv::errs> rfsv32:: fseek(const u_int32_t handle, const int32_t pos, const u_int32_t mode, u_int32_t &resultpos) { - bufferStore a; - Enum<rfsv::errs> res; - u_int32_t savpos = 0; - u_int32_t calcpos = 0; - int32_t mypos = pos; - u_int32_t realpos; + bufferStore a; + Enum<rfsv::errs> res; + u_int32_t savpos = 0; + u_int32_t calcpos = 0; + int32_t mypos = pos; + u_int32_t realpos; /* - seek-parameter for psion: + seek-parameter for psion: dword position dword handle dword mode @@ -621,218 +623,218 @@ fseek(const u_int32_t handle, const int32_t pos, const u_int32_t mode, u_int32_t ??no more?? 4 = sense recpos ??no more?? 5 = set recpos ??no more?? 6 = text-rewind - */ +*/ - if ((mode < PSI_SEEK_SET) || (mode > PSI_SEEK_END)) - return E_PSI_GEN_ARG; - - if ((mode == PSI_SEEK_CUR) && (mypos >= 0)) { - /* get and save current position */ - a.addDWord(0); - a.addDWord(handle); - a.addDWord(PSI_SEEK_CUR); - if (!sendCommand(SEEK_FILE, a)) - return E_PSI_FILE_DISC; - if ((res = getResponse(a)) != E_PSI_GEN_NONE) - return res; - savpos = a.getDWord(0); - if (mypos == 0) { - resultpos = savpos; - return res; - } - a.init(); - } - if ((mode == PSI_SEEK_END) && (mypos >= 0)) { - /* get and save end position */ - a.addDWord(0); - a.addDWord(handle); - a.addDWord(PSI_SEEK_END); - if (!sendCommand(SEEK_FILE, a)) - return E_PSI_FILE_DISC; - if ((res = getResponse(a)) != E_PSI_GEN_NONE) - return res; - savpos = a.getDWord(0); - if (mypos == 0) { - resultpos = savpos; - return res; - } - /* Expand file */ - a.init(); - a.addDWord(handle); - a.addDWord(savpos + mypos); - if (!sendCommand(SET_SIZE, a)) - return E_PSI_FILE_DISC; - if ((res = getResponse(a)) != E_PSI_GEN_NONE) - return res; - mypos = 0; - a.init(); - } - /* Now the real seek */ - a.addDWord(mypos); + if ((mode < PSI_SEEK_SET) || (mode > PSI_SEEK_END)) + return E_PSI_GEN_ARG; + + if ((mode == PSI_SEEK_CUR) && (mypos >= 0)) { + /* get and save current position */ + a.addDWord(0); a.addDWord(handle); - a.addDWord(mode); + a.addDWord(PSI_SEEK_CUR); if (!sendCommand(SEEK_FILE, a)) - return E_PSI_FILE_DISC; + return E_PSI_FILE_DISC; if ((res = getResponse(a)) != E_PSI_GEN_NONE) - return res; - realpos = a.getDWord(0); - switch (mode) { - case PSI_SEEK_SET: - calcpos = mypos; - break; - case PSI_SEEK_CUR: - calcpos = savpos + mypos; - break; - case PSI_SEEK_END: - resultpos = realpos; - return res; - break; + return res; + savpos = a.getDWord(0); + if (mypos == 0) { + resultpos = savpos; + return res; } - if (calcpos > realpos) { - /* Beyond end of file */ - a.init(); - a.addDWord(handle); - a.addDWord(calcpos); - if (!sendCommand(SET_SIZE, a)) - return E_PSI_FILE_DISC; - if ((res = getResponse(a)) != E_PSI_GEN_NONE) - return res; - a.addDWord(calcpos); - a.addDWord(handle); - a.addDWord(PSI_SEEK_SET); - if (!sendCommand(SEEK_FILE, a)) - return E_PSI_FILE_DISC; - if ((res = getResponse(a)) != E_PSI_GEN_NONE) - return res; - realpos = a.getDWord(0); + a.init(); + } + if ((mode == PSI_SEEK_END) && (mypos >= 0)) { + /* get and save end position */ + a.addDWord(0); + a.addDWord(handle); + a.addDWord(PSI_SEEK_END); + if (!sendCommand(SEEK_FILE, a)) + return E_PSI_FILE_DISC; + if ((res = getResponse(a)) != E_PSI_GEN_NONE) + return res; + savpos = a.getDWord(0); + if (mypos == 0) { + resultpos = savpos; + return res; } - resultpos = realpos; + /* Expand file */ + a.init(); + a.addDWord(handle); + a.addDWord(savpos + mypos); + if (!sendCommand(SET_SIZE, a)) + return E_PSI_FILE_DISC; + if ((res = getResponse(a)) != E_PSI_GEN_NONE) + return res; + mypos = 0; + a.init(); + } + /* Now the real seek */ + a.addDWord(mypos); + a.addDWord(handle); + a.addDWord(mode); + if (!sendCommand(SEEK_FILE, a)) + return E_PSI_FILE_DISC; + if ((res = getResponse(a)) != E_PSI_GEN_NONE) return res; + realpos = a.getDWord(0); + switch (mode) { + case PSI_SEEK_SET: + calcpos = mypos; + break; + case PSI_SEEK_CUR: + calcpos = savpos + mypos; + break; + case PSI_SEEK_END: + resultpos = realpos; + return res; + break; + } + if (calcpos > realpos) { + /* Beyond end of file */ + a.init(); + a.addDWord(handle); + a.addDWord(calcpos); + if (!sendCommand(SET_SIZE, a)) + return E_PSI_FILE_DISC; + if ((res = getResponse(a)) != E_PSI_GEN_NONE) + return res; + a.addDWord(calcpos); + a.addDWord(handle); + a.addDWord(PSI_SEEK_SET); + if (!sendCommand(SEEK_FILE, a)) + return E_PSI_FILE_DISC; + if ((res = getResponse(a)) != E_PSI_GEN_NONE) + return res; + realpos = a.getDWord(0); + } + resultpos = realpos; + return res; } Enum<rfsv::errs> rfsv32:: mkdir(const char *name) { - bufferStore a; - string n = convertSlash(name); - if (n.find_last_of('\\') != (n.size() - 1)) - n += '\\'; - a.addWord(n.size()); - a.addString(n.c_str()); - if (!sendCommand(MK_DIR_ALL, a)) - return E_PSI_FILE_DISC; - return getResponse(a); + bufferStore a; + string n = convertSlash(name); + if (n.find_last_of('\\') != (n.size() - 1)) + n += '\\'; + a.addWord(n.size()); + a.addString(n.c_str()); + if (!sendCommand(MK_DIR_ALL, a)) + return E_PSI_FILE_DISC; + return getResponse(a); } Enum<rfsv::errs> rfsv32:: rmdir(const char *name) { - bufferStore a; - string n = convertSlash(name); - if (n.find_last_of('\\') != (n.size() - 1)) - n += '\\'; - a.addWord(n.size()); - a.addString(n.c_str()); - if (!sendCommand(RM_DIR, a)) - return E_PSI_FILE_DISC; - return getResponse(a); + bufferStore a; + string n = convertSlash(name); + if (n.find_last_of('\\') != (n.size() - 1)) + n += '\\'; + a.addWord(n.size()); + a.addString(n.c_str()); + if (!sendCommand(RM_DIR, a)) + return E_PSI_FILE_DISC; + return getResponse(a); } Enum<rfsv::errs> rfsv32:: rename(const char *oldname, const char *newname) { - bufferStore a; - string on = convertSlash(oldname); - string nn = convertSlash(newname); - a.addWord(on.size()); - a.addString(on.c_str()); - a.addWord(nn.size()); - a.addString(nn.c_str()); - if (!sendCommand(RENAME, a)) - return E_PSI_FILE_DISC; - return getResponse(a); + bufferStore a; + string on = convertSlash(oldname); + string nn = convertSlash(newname); + a.addWord(on.size()); + a.addString(on.c_str()); + a.addWord(nn.size()); + a.addString(nn.c_str()); + if (!sendCommand(RENAME, a)) + return E_PSI_FILE_DISC; + return getResponse(a); } Enum<rfsv::errs> rfsv32:: remove(const char *name) { - bufferStore a; - string n = convertSlash(name); - a.addWord(n.size()); - a.addString(n.c_str()); - if (!sendCommand(DELETE, a)) - return E_PSI_FILE_DISC; - return getResponse(a); + bufferStore a; + string n = convertSlash(name); + a.addWord(n.size()); + a.addString(n.c_str()); + if (!sendCommand(DELETE, a)) + return E_PSI_FILE_DISC; + return getResponse(a); } Enum<rfsv::errs> rfsv32:: setVolumeName(const char drive , const char * const name) { - bufferStore a; - a.addDWord(drive - 'A'); - a.addWord(strlen(name)); - a.addStringT(name); - if (!sendCommand(SET_VOLUME_LABEL, a)) - return E_PSI_FILE_DISC; - return getResponse(a); + bufferStore a; + a.addDWord(drive - 'A'); + a.addWord(strlen(name)); + a.addStringT(name); + if (!sendCommand(SET_VOLUME_LABEL, a)) + return E_PSI_FILE_DISC; + return getResponse(a); } static enum rfsv::errs e2psi[] = { - rfsv::E_PSI_FILE_DIRFULL, // -43 - rfsv::E_PSI_GEN_POWER, // -42 - rfsv::E_PSI_GEN_DIVIDE, // -41 - rfsv::E_PSI_FILE_TOOBIG, // -40 - rfsv::E_PSI_FILE_ABORT, // -39 - rfsv::E_PSI_GEN_DESCR, // -38 - rfsv::E_PSI_GEN_LIB, // -37 - rfsv::E_PSI_FILE_NDISC, // -36 - rfsv::E_PSI_FILE_DISC, // -35 - rfsv::E_PSI_FILE_CONNECT, // -34 - rfsv::E_PSI_FILE_RETRAN, // -33 - rfsv::E_PSI_FILE_PARITY, // -32 - rfsv::E_PSI_FILE_OVERRUN, // -31 - rfsv::E_PSI_FILE_FRAME, // -30 - rfsv::E_PSI_FILE_LINE, // -29 - rfsv::E_PSI_FILE_NAME, // -28 - rfsv::E_PSI_FILE_DRIVER, // -27 - rfsv::E_PSI_FILE_FULL, // -26 - rfsv::E_PSI_FILE_EOF, // -25 - rfsv::E_PSI_GEN_FSYS, // -24 - rfsv::E_PSI_FILE_WRITE, // -23 - rfsv::E_PSI_FILE_LOCKED, // -22 - rfsv::E_PSI_FILE_ACCESS, // -21 - rfsv::E_PSI_FILE_CORRUPT, // -20 - rfsv::E_PSI_FILE_UNKNOWN, // -19 - rfsv::E_PSI_FILE_NOTREADY, // -18 - rfsv::E_PSI_FILE_COMPLETION, // -17 - rfsv::E_PSI_GEN_BUSY, // -16 - rfsv::E_PSI_GEN_TERMINATED, // -15 - rfsv::E_PSI_GEN_INUSE, // -14 - rfsv::E_PSI_GEN_DIED, // -13 - rfsv::E_PSI_FILE_DIR, // -12 - rfsv::E_PSI_FILE_EXIST, // -11 - rfsv::E_PSI_GEN_UNDER, // -10 - rfsv::E_PSI_GEN_OVER, // -9 - rfsv::E_PSI_FILE_HANDLE, // -8 - rfsv::E_PSI_GEN_RANGE, // -7 - rfsv::E_PSI_GEN_ARG, // -6 - rfsv::E_PSI_GEN_NSUP, // -5 - rfsv::E_PSI_GEN_NOMEMORY, // -4 - rfsv::E_PSI_FILE_CANCEL, // -3 - rfsv::E_PSI_GEN_FAIL, // -2 - rfsv::E_PSI_FILE_NXIST, // -1 - rfsv::E_PSI_GEN_NONE // 0 + rfsv::E_PSI_FILE_DIRFULL, // -43 + rfsv::E_PSI_GEN_POWER, // -42 + rfsv::E_PSI_GEN_DIVIDE, // -41 + rfsv::E_PSI_FILE_TOOBIG, // -40 + rfsv::E_PSI_FILE_ABORT, // -39 + rfsv::E_PSI_GEN_DESCR, // -38 + rfsv::E_PSI_GEN_LIB, // -37 + rfsv::E_PSI_FILE_NDISC, // -36 + rfsv::E_PSI_FILE_DISC, // -35 + rfsv::E_PSI_FILE_CONNECT, // -34 + rfsv::E_PSI_FILE_RETRAN, // -33 + rfsv::E_PSI_FILE_PARITY, // -32 + rfsv::E_PSI_FILE_OVERRUN, // -31 + rfsv::E_PSI_FILE_FRAME, // -30 + rfsv::E_PSI_FILE_LINE, // -29 + rfsv::E_PSI_FILE_NAME, // -28 + rfsv::E_PSI_FILE_DRIVER, // -27 + rfsv::E_PSI_FILE_FULL, // -26 + rfsv::E_PSI_FILE_EOF, // -25 + rfsv::E_PSI_GEN_FSYS, // -24 + rfsv::E_PSI_FILE_WRITE, // -23 + rfsv::E_PSI_FILE_LOCKED, // -22 + rfsv::E_PSI_FILE_ACCESS, // -21 + rfsv::E_PSI_FILE_CORRUPT, // -20 + rfsv::E_PSI_FILE_UNKNOWN, // -19 + rfsv::E_PSI_FILE_NOTREADY, // -18 + rfsv::E_PSI_FILE_COMPLETION, // -17 + rfsv::E_PSI_GEN_BUSY, // -16 + rfsv::E_PSI_GEN_TERMINATED, // -15 + rfsv::E_PSI_GEN_INUSE, // -14 + rfsv::E_PSI_GEN_DIED, // -13 + rfsv::E_PSI_FILE_DIR, // -12 + rfsv::E_PSI_FILE_EXIST, // -11 + rfsv::E_PSI_GEN_UNDER, // -10 + rfsv::E_PSI_GEN_OVER, // -9 + rfsv::E_PSI_FILE_HANDLE, // -8 + rfsv::E_PSI_GEN_RANGE, // -7 + rfsv::E_PSI_GEN_ARG, // -6 + rfsv::E_PSI_GEN_NSUP, // -5 + rfsv::E_PSI_GEN_NOMEMORY, // -4 + rfsv::E_PSI_FILE_CANCEL, // -3 + rfsv::E_PSI_GEN_FAIL, // -2 + rfsv::E_PSI_FILE_NXIST, // -1 + rfsv::E_PSI_GEN_NONE // 0 }; Enum<rfsv::errs> rfsv32:: err2psierr(int32_t status) { - if ((status > E_EPOC_NONE) || (status < E_EPOC_DIR_FULL)) { - cerr << "FATAL: inavlid error-code" << endl; - cerr << "status: " << status << " " << hex << status << endl; - return E_PSI_INTERNAL; - } - return e2psi[status - E_EPOC_DIR_FULL]; + if ((status > E_EPOC_NONE) || (status < E_EPOC_DIR_FULL)) { + cerr << "FATAL: inavlid error-code" << endl; + cerr << "status: " << status << " " << hex << status << endl; + return E_PSI_INTERNAL; + } + return e2psi[status - E_EPOC_DIR_FULL]; } @@ -842,34 +844,34 @@ err2psierr(int32_t status) u_int32_t rfsv32:: attr2std(const u_int32_t attr) { - long res = 0; - - // Common attributes - if (attr & EPOC_ATTR_RONLY) - res |= PSI_A_RDONLY; - if (attr & EPOC_ATTR_HIDDEN) - res |= PSI_A_HIDDEN; - if (attr & EPOC_ATTR_SYSTEM) - res |= PSI_A_SYSTEM; - if (attr & EPOC_ATTR_DIRECTORY) - res |= PSI_A_DIR; - if (attr & EPOC_ATTR_ARCHIVE) - res |= PSI_A_ARCHIVE; - if (attr & EPOC_ATTR_VOLUME) - res |= PSI_A_VOLUME; - - // EPOC-specific - if (attr & EPOC_ATTR_NORMAL) - res |= PSI_A_NORMAL; - if (attr & EPOC_ATTR_TEMPORARY) - res |= PSI_A_TEMP; - if (attr & EPOC_ATTR_COMPRESSED) - res |= PSI_A_COMPRESSED; - - // Do what we can for SIBO - res |= PSI_A_READ; + long res = 0; - return res; + // Common attributes + if (attr & EPOC_ATTR_RONLY) + res |= PSI_A_RDONLY; + if (attr & EPOC_ATTR_HIDDEN) + res |= PSI_A_HIDDEN; + if (attr & EPOC_ATTR_SYSTEM) + res |= PSI_A_SYSTEM; + if (attr & EPOC_ATTR_DIRECTORY) + res |= PSI_A_DIR; + if (attr & EPOC_ATTR_ARCHIVE) + res |= PSI_A_ARCHIVE; + if (attr & EPOC_ATTR_VOLUME) + res |= PSI_A_VOLUME; + + // EPOC-specific + if (attr & EPOC_ATTR_NORMAL) + res |= PSI_A_NORMAL; + if (attr & EPOC_ATTR_TEMPORARY) + res |= PSI_A_TEMP; + if (attr & EPOC_ATTR_COMPRESSED) + res |= PSI_A_COMPRESSED; + + // Do what we can for SIBO + res |= PSI_A_READ; + + return res; } /* @@ -878,28 +880,34 @@ attr2std(const u_int32_t attr) u_int32_t rfsv32:: std2attr(const u_int32_t attr) { - long res = 0; - // Common attributes - if (attr & PSI_A_RDONLY) - res |= EPOC_ATTR_RONLY; - if (attr & PSI_A_HIDDEN) - res |= EPOC_ATTR_HIDDEN; - if (attr & PSI_A_SYSTEM) - res |= EPOC_ATTR_SYSTEM; - if (attr & PSI_A_DIR) - res |= EPOC_ATTR_DIRECTORY; - if (attr & PSI_A_ARCHIVE) - res |= EPOC_ATTR_ARCHIVE; - if (attr & PSI_A_VOLUME) - res |= EPOC_ATTR_VOLUME; - - // EPOC-specific - if (attr & PSI_A_NORMAL) - res |= EPOC_ATTR_NORMAL; - if (attr & PSI_A_TEMP) - res |= EPOC_ATTR_TEMPORARY; - if (attr & PSI_A_COMPRESSED) - res |= EPOC_ATTR_COMPRESSED; - - return res; + long res = 0; + // Common attributes + if (attr & PSI_A_RDONLY) + res |= EPOC_ATTR_RONLY; + if (attr & PSI_A_HIDDEN) + res |= EPOC_ATTR_HIDDEN; + if (attr & PSI_A_SYSTEM) + res |= EPOC_ATTR_SYSTEM; + if (attr & PSI_A_DIR) + res |= EPOC_ATTR_DIRECTORY; + if (attr & PSI_A_ARCHIVE) + res |= EPOC_ATTR_ARCHIVE; + if (attr & PSI_A_VOLUME) + res |= EPOC_ATTR_VOLUME; + + // EPOC-specific + if (attr & PSI_A_NORMAL) + res |= EPOC_ATTR_NORMAL; + if (attr & PSI_A_TEMP) + res |= EPOC_ATTR_TEMPORARY; + if (attr & PSI_A_COMPRESSED) + res |= EPOC_ATTR_COMPRESSED; + + return res; } + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ diff --git a/lib/rfsv32.h b/lib/rfsv32.h index 4afb95a..9baefaa 100644 --- a/lib/rfsv32.h +++ b/lib/rfsv32.h @@ -1,5 +1,29 @@ -#ifndef _rfsv32_h_ -#define _rfsv32_h_ +/*-*-c++-*- + * $Id$ + * + * This file is part of plptools. + * + * Copyright (C) 1999 Philip Proudman <philip.proudman@btinternet.com> + * Copyright (C) 1999-2001 Fritz Elfert <felfert@to.com> + * + * 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 _RFSV32_H_ +#define _RFSV32_H_ #include "rfsv.h" #include "plpdirent.h" @@ -14,165 +38,175 @@ class rfsvfactory; * @ref rfsv . For a complete documentation, see @ref rfsv . */ class rfsv32 : public rfsv { - friend rfsvfactory; + + /** + * rfsvfactory may call our constructor. + */ + friend rfsvfactory; public: - 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); - Enum<rfsv::errs> copyToPsion(const char * const, const char * const, void *, cpCallback_t); - Enum<rfsv::errs> copyOnPsion(const char * const, const char * const, void *, cpCallback_t); - Enum<rfsv::errs> mkdir(const char * const); - Enum<rfsv::errs> rmdir(const char * const); - Enum<rfsv::errs> remove(const char * const); - Enum<rfsv::errs> rename(const char * const, const char * const); - Enum<rfsv::errs> mktemp(u_int32_t &, string &); - Enum<rfsv::errs> fgeteattr(const char * const, PlpDirent &); - Enum<rfsv::errs> fgetattr(const char * const, u_int32_t &); - Enum<rfsv::errs> fsetattr(const char * const, const u_int32_t, const u_int32_t); - Enum<rfsv::errs> fgetmtime(const char * const, PsiTime &); - Enum<rfsv::errs> fsetmtime(const char * const, PsiTime const); - Enum<rfsv::errs> fopen(const u_int32_t, const char * const, u_int32_t &); - Enum<rfsv::errs> fcreatefile(const u_int32_t, const char * const, u_int32_t &); - Enum<rfsv::errs> freplacefile(const u_int32_t, const char * const, u_int32_t &); - Enum<rfsv::errs> fseek(const u_int32_t, const int32_t, const u_int32_t, u_int32_t &); - 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> fsetsize(u_int32_t, u_int32_t); - Enum<rfsv::errs> fclose(const u_int32_t); - - Enum<rfsv::errs> devlist(u_int32_t &); - 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 &); - Enum<rfsv::errs> setVolumeName(const char, const char * const); - u_int32_t opMode(const u_int32_t); + 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); + Enum<rfsv::errs> copyToPsion(const char * const, const char * const, void *, cpCallback_t); + Enum<rfsv::errs> copyOnPsion(const char * const, const char * const, void *, cpCallback_t); + Enum<rfsv::errs> mkdir(const char * const); + Enum<rfsv::errs> rmdir(const char * const); + Enum<rfsv::errs> remove(const char * const); + Enum<rfsv::errs> rename(const char * const, const char * const); + Enum<rfsv::errs> mktemp(u_int32_t &, string &); + Enum<rfsv::errs> fgeteattr(const char * const, PlpDirent &); + Enum<rfsv::errs> fgetattr(const char * const, u_int32_t &); + Enum<rfsv::errs> fsetattr(const char * const, const u_int32_t, const u_int32_t); + Enum<rfsv::errs> fgetmtime(const char * const, PsiTime &); + Enum<rfsv::errs> fsetmtime(const char * const, PsiTime const); + Enum<rfsv::errs> fopen(const u_int32_t, const char * const, u_int32_t &); + Enum<rfsv::errs> fcreatefile(const u_int32_t, const char * const, u_int32_t &); + Enum<rfsv::errs> freplacefile(const u_int32_t, const char * const, u_int32_t &); + Enum<rfsv::errs> fseek(const u_int32_t, const int32_t, const u_int32_t, u_int32_t &); + 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> fsetsize(u_int32_t, u_int32_t); + Enum<rfsv::errs> fclose(const u_int32_t); + + Enum<rfsv::errs> devlist(u_int32_t &); + 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 &); + Enum<rfsv::errs> setVolumeName(const char, const char * const); + u_int32_t opMode(const u_int32_t); private: - enum file_attrib { - EPOC_ATTR_RONLY = 0x0001, - EPOC_ATTR_HIDDEN = 0x0002, - EPOC_ATTR_SYSTEM = 0x0004, - EPOC_ATTR_DIRECTORY = 0x0010, - EPOC_ATTR_ARCHIVE = 0x0020, - EPOC_ATTR_VOLUME = 0x0040, - EPOC_ATTR_NORMAL = 0x0080, - EPOC_ATTR_TEMPORARY = 0x0100, - EPOC_ATTR_COMPRESSED = 0x0800, - EPOC_ATTR_MASK = 0x09f7, /* All of the above */ - EPOC_ATTR_GETUID = 0x10000000 /* Deliver UIDs on dir listing */ - }; - - enum open_mode { - EPOC_OMODE_SHARE_EXCLUSIVE = 0x0000, - EPOC_OMODE_SHARE_READERS = 0x0001, - EPOC_OMODE_SHARE_ANY = 0x0002, - EPOC_OMODE_BINARY = 0x0000, - EPOC_OMODE_TEXT = 0x0020, - EPOC_OMODE_READ_WRITE = 0x0200 - }; - - enum epoc_errs { - E_EPOC_NONE = 0, - E_EPOC_NOT_FOUND = -1, - E_EPOC_GENERAL = -2, - E_EPOC_CANCEL = -3, - E_EPOC_NO_MEMORY = -4, - E_EPOC_NOT_SUPPORTED = -5, - E_EPOC_ARGUMENT = -6, - E_EPOC_TOTAL_LOSS_OF_PRECISION = -7, - E_EPOC_BAD_HANDLE = -8, - E_EPOC_OVERFLOW = -9, - E_EPOC_UNDERFLOW = -10, - E_EPOC_ALREADY_EXISTS = -11, - E_EPOC_PATH_NOT_FOUND = -12, - E_EPOC_DIED = -13, - E_EPOC_IN_USE = -14, - E_EPOC_SERVER_TERMINATED = -15, - E_EPOC_SERVER_BUSY = -16, - E_EPOC_COMPLETION = -17, - E_EPOC_NOT_READY = -18, - E_EPOC_UNKNOWN = -19, - E_EPOC_CORRUPT = -20, - E_EPOC_ACCESS_DENIED = -21, - E_EPOC_LOCKED = -22, - E_EPOC_WRITE = -23, - E_EPOC_DISMOUNTED = -24, - E_EPOC_EoF = -25, - E_EPOC_DISK_FULL = -26, - E_EPOC_BAD_DRIVER = -27, - E_EPOC_BAD_NAME = -28, - E_EPOC_COMMS_LINE_FAIL = -29, - E_EPOC_COMMS_FRAME = -30, - E_EPOC_COMMS_OVERRUN = -31, - E_EPOC_COMMS_PARITY = -32, - E_EPOC_TIMEOUT = -33, - E_EPOC_COULD_NOT_CONNECT = -34, - E_EPOC_COULD_NOT_DISCONNECT = -35, - E_EPOC_DISCONNECTED = -36, - E_EPOC_BAD_LIBRARY_ENTRY_POINT = -37, - E_EPOC_BAD_DESCRIPTOR = -38, - E_EPOC_ABORT = -39, - E_EPOC_TOO_BIG = -40, - E_EPOC_DIVIDE_BY_ZERO = -41, - E_EPOC_BAD_POWER = -42, - E_EPOC_DIR_FULL = -43 - }; - - enum commands { - CLOSE_HANDLE = 0x01, - OPEN_DIR = 0x10, - READ_DIR = 0x12, - GET_DRIVE_LIST = 0x13, - DRIVE_INFO = 0x14, - SET_VOLUME_LABEL = 0x15, - OPEN_FILE = 0x16, - TEMP_FILE = 0x17, - READ_FILE = 0x18, - WRITE_FILE = 0x19, - SEEK_FILE = 0x1a, - DELETE = 0x1b, - REMOTE_ENTRY = 0x1c, - FLUSH = 0x1d, - SET_SIZE = 0x1e, - RENAME = 0x1f, - MK_DIR_ALL = 0x20, - RM_DIR = 0x21, - SET_ATT = 0x22, - ATT = 0x23, - SET_MODIFIED = 0x24, - MODIFIED = 0x25, - SET_SESSION_PATH = 0x26, - SESSION_PATH = 0x27, - READ_WRITE_FILE = 0x28, - CREATE_FILE = 0x29, - REPLACE_FILE = 0x2a, - PATH_TEST = 0x2b, - LOCK = 0x2d, - UNLOCK = 0x2e, - OPEN_DIR_UID = 0x2f, - DRIVE_NAME = 0x30, - SET_DRIVE_NAME = 0x31, - 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); - u_int32_t std2attr(const u_int32_t); - - - // Communication - bool sendCommand(enum commands, bufferStore &); - Enum<rfsv::errs> getResponse(bufferStore &); + enum file_attrib { + EPOC_ATTR_RONLY = 0x0001, + EPOC_ATTR_HIDDEN = 0x0002, + EPOC_ATTR_SYSTEM = 0x0004, + EPOC_ATTR_DIRECTORY = 0x0010, + EPOC_ATTR_ARCHIVE = 0x0020, + EPOC_ATTR_VOLUME = 0x0040, + EPOC_ATTR_NORMAL = 0x0080, + EPOC_ATTR_TEMPORARY = 0x0100, + EPOC_ATTR_COMPRESSED = 0x0800, + EPOC_ATTR_MASK = 0x09f7, /* All of the above */ + EPOC_ATTR_GETUID = 0x10000000 /* Deliver UIDs on dir listing */ + }; + + enum open_mode { + EPOC_OMODE_SHARE_EXCLUSIVE = 0x0000, + EPOC_OMODE_SHARE_READERS = 0x0001, + EPOC_OMODE_SHARE_ANY = 0x0002, + EPOC_OMODE_BINARY = 0x0000, + EPOC_OMODE_TEXT = 0x0020, + EPOC_OMODE_READ_WRITE = 0x0200 + }; + + enum epoc_errs { + E_EPOC_NONE = 0, + E_EPOC_NOT_FOUND = -1, + E_EPOC_GENERAL = -2, + E_EPOC_CANCEL = -3, + E_EPOC_NO_MEMORY = -4, + E_EPOC_NOT_SUPPORTED = -5, + E_EPOC_ARGUMENT = -6, + E_EPOC_TOTAL_LOSS_OF_PRECISION = -7, + E_EPOC_BAD_HANDLE = -8, + E_EPOC_OVERFLOW = -9, + E_EPOC_UNDERFLOW = -10, + E_EPOC_ALREADY_EXISTS = -11, + E_EPOC_PATH_NOT_FOUND = -12, + E_EPOC_DIED = -13, + E_EPOC_IN_USE = -14, + E_EPOC_SERVER_TERMINATED = -15, + E_EPOC_SERVER_BUSY = -16, + E_EPOC_COMPLETION = -17, + E_EPOC_NOT_READY = -18, + E_EPOC_UNKNOWN = -19, + E_EPOC_CORRUPT = -20, + E_EPOC_ACCESS_DENIED = -21, + E_EPOC_LOCKED = -22, + E_EPOC_WRITE = -23, + E_EPOC_DISMOUNTED = -24, + E_EPOC_EoF = -25, + E_EPOC_DISK_FULL = -26, + E_EPOC_BAD_DRIVER = -27, + E_EPOC_BAD_NAME = -28, + E_EPOC_COMMS_LINE_FAIL = -29, + E_EPOC_COMMS_FRAME = -30, + E_EPOC_COMMS_OVERRUN = -31, + E_EPOC_COMMS_PARITY = -32, + E_EPOC_TIMEOUT = -33, + E_EPOC_COULD_NOT_CONNECT = -34, + E_EPOC_COULD_NOT_DISCONNECT = -35, + E_EPOC_DISCONNECTED = -36, + E_EPOC_BAD_LIBRARY_ENTRY_POINT = -37, + E_EPOC_BAD_DESCRIPTOR = -38, + E_EPOC_ABORT = -39, + E_EPOC_TOO_BIG = -40, + E_EPOC_DIVIDE_BY_ZERO = -41, + E_EPOC_BAD_POWER = -42, + E_EPOC_DIR_FULL = -43 + }; + + enum commands { + CLOSE_HANDLE = 0x01, + OPEN_DIR = 0x10, + READ_DIR = 0x12, + GET_DRIVE_LIST = 0x13, + DRIVE_INFO = 0x14, + SET_VOLUME_LABEL = 0x15, + OPEN_FILE = 0x16, + TEMP_FILE = 0x17, + READ_FILE = 0x18, + WRITE_FILE = 0x19, + SEEK_FILE = 0x1a, + DELETE = 0x1b, + REMOTE_ENTRY = 0x1c, + FLUSH = 0x1d, + SET_SIZE = 0x1e, + RENAME = 0x1f, + MK_DIR_ALL = 0x20, + RM_DIR = 0x21, + SET_ATT = 0x22, + ATT = 0x23, + SET_MODIFIED = 0x24, + MODIFIED = 0x25, + SET_SESSION_PATH = 0x26, + SESSION_PATH = 0x27, + READ_WRITE_FILE = 0x28, + CREATE_FILE = 0x29, + REPLACE_FILE = 0x2a, + PATH_TEST = 0x2b, + LOCK = 0x2d, + UNLOCK = 0x2e, + OPEN_DIR_UID = 0x2f, + DRIVE_NAME = 0x30, + SET_DRIVE_NAME = 0x31, + 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); + u_int32_t std2attr(const u_int32_t); + + + // Communication + bool sendCommand(enum commands, bufferStore &); + Enum<rfsv::errs> getResponse(bufferStore &); }; #endif + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ diff --git a/lib/rfsvfactory.cc b/lib/rfsvfactory.cc index 3699903..3a142da 100644 --- a/lib/rfsvfactory.cc +++ b/lib/rfsvfactory.cc @@ -1,23 +1,25 @@ -// -// RFSVFACTORY - factory object that creates an appropriate RFSV object -// based on whatever the NCP daemon discovered in the INFO exchange. -// -// Copyright (C) 1999 Matt J. Gumbley <matt@gumbley.demon.co.uk> -// -// 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 - +/*-*-c++-*- + * $Id$ + * + * This file is part of plptools. + * + * Copyright (C) 1999 Matt J. Gumbley <matt@gumbley.demon.co.uk> + * + * 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 + * + */ #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -38,62 +40,68 @@ #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"); + stringRep.add(rfsvfactory::FACERR_NONE, N_("no error")); + stringRep.add(rfsvfactory::FACERR_COULD_NOT_SEND, N_("could not send version request")); + stringRep.add(rfsvfactory::FACERR_AGAIN, N_("try again")); + stringRep.add(rfsvfactory::FACERR_NOPSION, N_("no psion connected")); + stringRep.add(rfsvfactory::FACERR_PROTVERSION, N_("wrong protocol version")); + stringRep.add(rfsvfactory::FACERR_NORESPONSE, N_("no response from ncpd")); } rfsvfactory::rfsvfactory(ppsocket *_skt) : serNum(0) { - err = FACERR_NONE; - skt = _skt; + err = FACERR_NONE; + skt = _skt; } rfsv * rfsvfactory::create(bool reconnect) { - // skt is connected to the ncp daemon, which will have (hopefully) seen - // an INFO exchange, where the protocol version of the remote Psion was - // sent, and noted. We have to ask the ncp daemon which protocol it saw, - // 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. + // skt is connected to the ncp daemon, which will have (hopefully) seen + // an INFO exchange, where the protocol version of the remote Psion was + // sent, and noted. We have to ask the ncp daemon which protocol it saw, + // 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; + bufferStore a; - err = FACERR_NONE; - a.addStringT("NCP$INFO"); - if (!skt->sendBufferStore(a)) { - if (!reconnect) - err = FACERR_COULD_NOT_SEND; - else { - skt->closeSocket(); - serNum = 0; - skt->reconnect(); - err = FACERR_AGAIN; - } - return NULL; + err = FACERR_NONE; + a.addStringT("NCP$INFO"); + if (!skt->sendBufferStore(a)) { + if (!reconnect) + err = FACERR_COULD_NOT_SEND; + else { + skt->closeSocket(); + serNum = 0; + skt->reconnect(); + err = FACERR_AGAIN; } - if (skt->getBufferStore(a) == 1) { - if (a.getLen() > 8 && !strncmp(a.getString(), "Series 3", 8)) { - return new rfsv16(skt); - } - else if (a.getLen() > 8 && !strncmp(a.getString(), "Series 5", 8)) { - return new rfsv32(skt); - } - if ((a.getLen() > 8) && !strncmp(a.getString(), "No Psion", 8)) { - skt->closeSocket(); - serNum = 0; - skt->reconnect(); - err = FACERR_NOPSION; - return NULL; - } - // Invalid protocol version - err = FACERR_PROTVERSION; - } else - err = FACERR_NORESPONSE; - return NULL; + } + if (skt->getBufferStore(a) == 1) { + if (a.getLen() > 8 && !strncmp(a.getString(), "Series 3", 8)) { + return new rfsv16(skt); + } + else if (a.getLen() > 8 && !strncmp(a.getString(), "Series 5", 8)) { + return new rfsv32(skt); + } + if ((a.getLen() > 8) && !strncmp(a.getString(), "No Psion", 8)) { + skt->closeSocket(); + serNum = 0; + skt->reconnect(); + err = FACERR_NOPSION; + return NULL; + } + // Invalid protocol version + err = FACERR_PROTVERSION; + } else + err = FACERR_NORESPONSE; + + return NULL; } + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ diff --git a/lib/rfsvfactory.h b/lib/rfsvfactory.h index 8af4575..04117fd 100644 --- a/lib/rfsvfactory.h +++ b/lib/rfsvfactory.h @@ -1,5 +1,29 @@ -#ifndef _rfsvfactory_h_ -#define _rfsvfactory_h_ +/*-*-c++-*- + * $Id$ + * + * This file is part of plptools. + * + * Copyright (C) 1999 Philip Proudman <philip.proudman@btinternet.com> + * Copyright (C) 1999 Matt J. Gumbley <matt@gumbley.demon.co.uk> + * Copyright (C) 1999-2001 Fritz Elfert <felfert@to.com> + * + * 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 _RFSVFACTORY_H_ +#define _RFSVFACTORY_H_ #include "rfsv.h" @@ -10,56 +34,62 @@ 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 - * to the ncpd daemon. - */ - rfsvfactory(ppsocket * skt); +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 + * to the ncpd daemon. + */ + rfsvfactory(ppsocket * skt); - /** - * Creates a new @ref rfsv instance. - * - * @param reconnect Set to true, if automatic reconnect - * should be performed on failure. - * - * @returns A pointer to a newly created rfsv instance or - * NULL on failure. - */ - virtual rfsv * create(bool); + /** + * Creates a new @ref rfsv instance. + * + * @param reconnect Set to true, if automatic reconnect + * should be performed on failure. + * + * @returns A pointer to a newly created rfsv instance or + * NULL on failure. + */ + 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; } + /** + * 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; - int serNum; - Enum<errs> err; +private: + /** + * The socket to be used for connecting to the + * ncpd daemon. + */ + ppsocket *skt; + int serNum; + Enum<errs> err; }; #endif +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ + diff --git a/lib/rpcs.cc b/lib/rpcs.cc index 837f235..2e1288d 100644 --- a/lib/rpcs.cc +++ b/lib/rpcs.cc @@ -1,19 +1,25 @@ -// -// 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 -// - +/*-*-c++-*- + * $Id$ + * + * This file is part of plptools. + * + * Copyright (C) 1999-2001 Fritz Elfert <felfert@to.com> + * + * 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 + * + */ #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -32,56 +38,61 @@ #include "Enum.h" ENUM_DEFINITION(rpcs::machs, rpcs::PSI_MACH_UNKNOWN) { - stringRep.add(rpcs::PSI_MACH_UNKNOWN, "Unknown device"); - stringRep.add(rpcs::PSI_MACH_PC, "PC"); - stringRep.add(rpcs::PSI_MACH_MC, "MC"); - stringRep.add(rpcs::PSI_MACH_HC, "HC"); - stringRep.add(rpcs::PSI_MACH_S3, "Series 3"); - stringRep.add(rpcs::PSI_MACH_S3A, "Series 3a, 3c or 3mx"); - stringRep.add(rpcs::PSI_MACH_WORKABOUT, "Workabout"); - stringRep.add(rpcs::PSI_MACH_SIENNA, "Sienna"); - stringRep.add(rpcs::PSI_MACH_S3C, "Series 3c"); - stringRep.add(rpcs::PSI_MACH_S5, "Series 5"); - stringRep.add(rpcs::PSI_MACH_WINC, "WinC"); + stringRep.add(rpcs::PSI_MACH_UNKNOWN, N_("Unknown device")); + stringRep.add(rpcs::PSI_MACH_PC, N_("PC")); + stringRep.add(rpcs::PSI_MACH_MC, N_("MC")); + stringRep.add(rpcs::PSI_MACH_HC, N_("HC")); + stringRep.add(rpcs::PSI_MACH_S3, N_("Series 3")); + stringRep.add(rpcs::PSI_MACH_S3A, N_("Series 3a, 3c or 3mx")); + stringRep.add(rpcs::PSI_MACH_WORKABOUT, N_("Workabout")); + stringRep.add(rpcs::PSI_MACH_SIENNA, N_("Sienna")); + stringRep.add(rpcs::PSI_MACH_S3C, N_("Series 3c")); + stringRep.add(rpcs::PSI_MACH_S5, N_("Series 5")); + stringRep.add(rpcs::PSI_MACH_WINC, N_("WinC")); } ENUM_DEFINITION(rpcs::batterystates, rpcs::PSI_BATT_DEAD) { - stringRep.add(rpcs::PSI_BATT_DEAD, "Empty"); - stringRep.add(rpcs::PSI_BATT_VERYLOW, "Very Low"); - stringRep.add(rpcs::PSI_BATT_LOW, "Low"); - stringRep.add(rpcs::PSI_BATT_GOOD, "Good"); + stringRep.add(rpcs::PSI_BATT_DEAD, N_("Empty")); + stringRep.add(rpcs::PSI_BATT_VERYLOW, N_("Very Low")); + stringRep.add(rpcs::PSI_BATT_LOW, N_("Low")); + stringRep.add(rpcs::PSI_BATT_GOOD, N_("Good")); } ENUM_DEFINITION(rpcs::languages, rpcs::PSI_LANG_TEST) { - stringRep.add(rpcs::PSI_LANG_TEST, "Test"); - stringRep.add(rpcs::PSI_LANG_en_GB, "English"); - stringRep.add(rpcs::PSI_LANG_de_DE, "German"); - stringRep.add(rpcs::PSI_LANG_fr_FR, "French"); - stringRep.add(rpcs::PSI_LANG_es_ES, "Spanish"); - stringRep.add(rpcs::PSI_LANG_it_IT, "Italian"); - stringRep.add(rpcs::PSI_LANG_sv_SE, "Swedish"); - stringRep.add(rpcs::PSI_LANG_da_DK, "Danish"); - stringRep.add(rpcs::PSI_LANG_no_NO, "Norwegian"); - stringRep.add(rpcs::PSI_LANG_fi_FI, "Finnish"); - stringRep.add(rpcs::PSI_LANG_en_US, "American"); - stringRep.add(rpcs::PSI_LANG_fr_CH, "Swiss French"); - stringRep.add(rpcs::PSI_LANG_de_CH, "Swiss German"); - stringRep.add(rpcs::PSI_LANG_pt_PT, "Portugese"); - stringRep.add(rpcs::PSI_LANG_tr_TR, "Turkish"); - stringRep.add(rpcs::PSI_LANG_is_IS, "Icelandic"); - stringRep.add(rpcs::PSI_LANG_ru_RU, "Russian"); - stringRep.add(rpcs::PSI_LANG_hu_HU, "Hungarian"); - stringRep.add(rpcs::PSI_LANG_nl_NL, "Dutch"); - stringRep.add(rpcs::PSI_LANG_nl_BE, "Belgian Flemish"); - stringRep.add(rpcs::PSI_LANG_en_AU, "Australian"); - stringRep.add(rpcs::PSI_LANG_fr_BE, "Belgish French"); - stringRep.add(rpcs::PSI_LANG_de_AT, "Austrian"); - stringRep.add(rpcs::PSI_LANG_en_NZ, "New Zealand"); // FIXME: not shure about ISO code - stringRep.add(rpcs::PSI_LANG_fr_CA, "International French"); // FIXME: not shure about ISO code - stringRep.add(rpcs::PSI_LANG_cs_CZ, "Czech"); - stringRep.add(rpcs::PSI_LANG_sk_SK, "Slovak"); - stringRep.add(rpcs::PSI_LANG_pl_PL, "Polish"); - stringRep.add(rpcs::PSI_LANG_sl_SI, "Slovenian"); + stringRep.add(rpcs::PSI_LANG_TEST, N_("Test")); + stringRep.add(rpcs::PSI_LANG_en_GB, N_("English")); + stringRep.add(rpcs::PSI_LANG_de_DE, N_("German")); + stringRep.add(rpcs::PSI_LANG_fr_FR, N_("French")); + stringRep.add(rpcs::PSI_LANG_es_ES, N_("Spanish")); + stringRep.add(rpcs::PSI_LANG_it_IT, N_("Italian")); + stringRep.add(rpcs::PSI_LANG_sv_SE, N_("Swedish")); + stringRep.add(rpcs::PSI_LANG_da_DK, N_("Danish")); + stringRep.add(rpcs::PSI_LANG_no_NO, N_("Norwegian")); + stringRep.add(rpcs::PSI_LANG_fi_FI, N_("Finnish")); + stringRep.add(rpcs::PSI_LANG_en_US, N_("American")); + stringRep.add(rpcs::PSI_LANG_fr_CH, N_("Swiss French")); + stringRep.add(rpcs::PSI_LANG_de_CH, N_("Swiss German")); + stringRep.add(rpcs::PSI_LANG_pt_PT, N_("Portugese")); + stringRep.add(rpcs::PSI_LANG_tr_TR, N_("Turkish")); + stringRep.add(rpcs::PSI_LANG_is_IS, N_("Icelandic")); + stringRep.add(rpcs::PSI_LANG_ru_RU, N_("Russian")); + stringRep.add(rpcs::PSI_LANG_hu_HU, N_("Hungarian")); + stringRep.add(rpcs::PSI_LANG_nl_NL, N_("Dutch")); + stringRep.add(rpcs::PSI_LANG_nl_BE, N_("Belgian Flemish")); + stringRep.add(rpcs::PSI_LANG_en_AU, N_("Australian")); + stringRep.add(rpcs::PSI_LANG_fr_BE, N_("Belgish French")); + stringRep.add(rpcs::PSI_LANG_de_AT, N_("Austrian")); + stringRep.add(rpcs::PSI_LANG_en_NZ, N_("New Zealand")); // FIXME: not shure about ISO code + stringRep.add(rpcs::PSI_LANG_fr_CA, N_("International French")); // FIXME: not shure about ISO code + stringRep.add(rpcs::PSI_LANG_cs_CZ, N_("Czech")); + stringRep.add(rpcs::PSI_LANG_sk_SK, N_("Slovak")); + stringRep.add(rpcs::PSI_LANG_pl_PL, N_("Polish")); + stringRep.add(rpcs::PSI_LANG_sl_SI, N_("Slovenian")); +} + +rpcs::~rpcs() +{ + skt->closeSocket(); } // @@ -90,35 +101,35 @@ ENUM_DEFINITION(rpcs::languages, rpcs::PSI_LANG_TEST) { void rpcs:: reconnect(void) { - skt->closeSocket(); - skt->reconnect(); - reset(); + //skt->closeSocket(); + skt->reconnect(); + reset(); } void rpcs:: reset(void) { - bufferStore a; - status = rfsv::E_PSI_FILE_DISC; - a.addStringT(getConnectName()); - if (skt->sendBufferStore(a)) { - if (skt->getBufferStore(a) == 1) { - if (!strcmp(a.getString(0), "Ok")) - status = rfsv::E_PSI_GEN_NONE; - } + bufferStore a; + status = rfsv::E_PSI_FILE_DISC; + a.addStringT(getConnectName()); + if (skt->sendBufferStore(a)) { + if (skt->getBufferStore(a) == 1) { + if (!strcmp(a.getString(0), "Ok")) + status = rfsv::E_PSI_GEN_NONE; } + } } Enum<rfsv::errs> rpcs:: getStatus(void) { - return status; + return status; } const char *rpcs:: getConnectName(void) { - return "SYS$RPCS"; + return "SYS$RPCS"; } // @@ -127,45 +138,45 @@ getConnectName(void) bool rpcs:: sendCommand(enum commands cc, bufferStore & data) { - if (status == rfsv::E_PSI_FILE_DISC) { - reconnect(); - if (status == rfsv::E_PSI_FILE_DISC) - return false; - } - bool result; - bufferStore a; - a.addByte(cc); - a.addBuff(data); + if (status == rfsv::E_PSI_FILE_DISC) { + reconnect(); + if (status == rfsv::E_PSI_FILE_DISC) + return false; + } + bool result; + bufferStore a; + a.addByte(cc); + a.addBuff(data); + result = skt->sendBufferStore(a); + if (!result) { + reconnect(); result = skt->sendBufferStore(a); - if (!result) { - reconnect(); - result = skt->sendBufferStore(a); - if (!result) - status = rfsv::E_PSI_FILE_DISC; - } - return result; + if (!result) + status = rfsv::E_PSI_FILE_DISC; + } + return result; } Enum<rfsv::errs> rpcs:: getResponse(bufferStore & data, bool statusIsFirstByte) { - Enum<rfsv::errs> ret; - if (skt->getBufferStore(data) == 1) { - if (statusIsFirstByte) { - ret = (enum rfsv::errs)((char)data.getByte(0)); - data.discardFirstBytes(1); - } else { - int l = data.getLen(); - if (l > 0) { - ret = (enum rfsv::errs)((char)data.getByte(data.getLen() - 1)); - data.init((const unsigned char *)data.getString(), l - 1); - } else - ret = rfsv::E_PSI_GEN_FAIL; - } - return ret; - } else - status = rfsv::E_PSI_FILE_DISC; - return status; + Enum<rfsv::errs> ret; + if (skt->getBufferStore(data) == 1) { + if (statusIsFirstByte) { + ret = (enum rfsv::errs)((char)data.getByte(0)); + data.discardFirstBytes(1); + } else { + int l = data.getLen(); + if (l > 0) { + ret = (enum rfsv::errs)((char)data.getByte(data.getLen() - 1)); + data.init((const unsigned char *)data.getString(), l - 1); + } else + ret = rfsv::E_PSI_GEN_FAIL; + } + return ret; + } else + status = rfsv::E_PSI_FILE_DISC; + return status; } // @@ -174,184 +185,190 @@ getResponse(bufferStore & data, bool statusIsFirstByte) Enum<rfsv::errs> rpcs:: getNCPversion(int &major, int &minor) { - Enum<rfsv::errs> res; - bufferStore a; - - if (!sendCommand(QUERY_NCP, a)) - return rfsv::E_PSI_FILE_DISC; - if ((res = getResponse(a, true)) != rfsv::E_PSI_GEN_NONE) - return res; - if (a.getLen() != 2) - return rfsv::E_PSI_GEN_FAIL; - major = a.getByte(0); - minor = a.getByte(1); + Enum<rfsv::errs> res; + bufferStore a; + + if (!sendCommand(QUERY_NCP, a)) + return rfsv::E_PSI_FILE_DISC; + if ((res = getResponse(a, true)) != rfsv::E_PSI_GEN_NONE) return res; + if (a.getLen() != 2) + return rfsv::E_PSI_GEN_FAIL; + major = a.getByte(0); + minor = a.getByte(1); + return res; } Enum<rfsv::errs> rpcs:: execProgram(const char *program, const char *args) { - bufferStore a; - - a.addStringT(program); - int l = strlen(program); - for (int i = 127; i > l; i--) - a.addByte(0); - - /** - * This is a hack for the jotter app on mx5 pro. (and probably others) - * Jotter seems to read it's arguments one char past normal apps. - * 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(' '); - - a.addStringT(args); - if (!sendCommand(EXEC_PROG, a)) - return rfsv::E_PSI_FILE_DISC; - return getResponse(a, true); + bufferStore a; + + a.addStringT(program); + int l = strlen(program); + for (int i = 127; i > l; i--) + a.addByte(0); + + /** + * This is a hack for the jotter app on mx5 pro. (and probably others) + * Jotter seems to read it's arguments one char past normal apps. + * 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(' '); + + a.addStringT(args); + if (!sendCommand(EXEC_PROG, a)) + return rfsv::E_PSI_FILE_DISC; + return getResponse(a, true); } Enum<rfsv::errs> rpcs:: stopProgram(const char *program) { - bufferStore a; + bufferStore a; - a.addStringT(program); - if (!sendCommand(STOP_PROG, a)) - return rfsv::E_PSI_FILE_DISC; - return getResponse(a, true); + a.addStringT(program); + if (!sendCommand(STOP_PROG, a)) + return rfsv::E_PSI_FILE_DISC; + return getResponse(a, true); } Enum<rfsv::errs> rpcs:: queryProgram(const char *program) { - bufferStore a; + bufferStore a; - a.addStringT(program); - if (!sendCommand(QUERY_PROG, a)) - return rfsv::E_PSI_FILE_DISC; - return getResponse(a, true); + a.addStringT(program); + if (!sendCommand(QUERY_PROG, a)) + return rfsv::E_PSI_FILE_DISC; + return getResponse(a, true); } Enum<rfsv::errs> rpcs:: formatOpen(const char *drive, int &handle, int &count) { - Enum<rfsv::errs> res; - bufferStore a; - - a.addStringT(drive); - if (!sendCommand(FORMAT_OPEN, a)) - return rfsv::E_PSI_FILE_DISC; - if ((res = getResponse(a, true)) != rfsv::E_PSI_GEN_NONE) - return res; - if (a.getLen() != 4) - return rfsv::E_PSI_GEN_FAIL; - handle = a.getWord(0); - count = a.getWord(2); + Enum<rfsv::errs> res; + bufferStore a; + + a.addStringT(drive); + if (!sendCommand(FORMAT_OPEN, a)) + return rfsv::E_PSI_FILE_DISC; + if ((res = getResponse(a, true)) != rfsv::E_PSI_GEN_NONE) return res; + if (a.getLen() != 4) + return rfsv::E_PSI_GEN_FAIL; + handle = a.getWord(0); + count = a.getWord(2); + return res; } Enum<rfsv::errs> rpcs:: formatRead(int handle) { - bufferStore a; + bufferStore a; - a.addWord(handle); - if (!sendCommand(FORMAT_READ, a)) - return rfsv::E_PSI_FILE_DISC; - return getResponse(a, true); + a.addWord(handle); + if (!sendCommand(FORMAT_READ, a)) + return rfsv::E_PSI_FILE_DISC; + return getResponse(a, true); } Enum<rfsv::errs> rpcs:: getUniqueID(const char *device, long &id) { - Enum<rfsv::errs> res; - bufferStore a; - - a.addStringT(device); - if (!sendCommand(GET_UNIQUEID, a)) - return rfsv::E_PSI_FILE_DISC; - if ((res = getResponse(a, true)) != rfsv::E_PSI_GEN_NONE) - return res; - if (a.getLen() != 4) - return rfsv::E_PSI_GEN_FAIL; - id = a.getDWord(0); + Enum<rfsv::errs> res; + bufferStore a; + + a.addStringT(device); + if (!sendCommand(GET_UNIQUEID, a)) + return rfsv::E_PSI_FILE_DISC; + if ((res = getResponse(a, true)) != rfsv::E_PSI_GEN_NONE) return res; + if (a.getLen() != 4) + return rfsv::E_PSI_GEN_FAIL; + id = a.getDWord(0); + return res; } Enum<rfsv::errs> rpcs:: getOwnerInfo(bufferArray &owner) { - Enum<rfsv::errs> res; - bufferStore a; + Enum<rfsv::errs> res; + bufferStore a; - if (!sendCommand(GET_OWNERINFO, a)) - return rfsv::E_PSI_FILE_DISC; - if ((res = (enum rfsv::errs)getResponse(a, true)) != rfsv::E_PSI_GEN_NONE) - return res; - a.addByte(0); - int l = a.getLen(); - char *s = (char *)a.getString(0); - for (int i = 0; i < l; i++) - if (s[i] == 6) - s[i] = 0; - owner.clear(); - while (l > 0) { - if (*s != '\0') { - bufferStore b; - b.addStringT(s); - owner += b; - l -= (strlen(s) + 1); - s += (strlen(s) + 1); - } else { - l--; - s++; - } - } + if (!sendCommand(GET_OWNERINFO, a)) + return rfsv::E_PSI_FILE_DISC; + if ((res = (enum rfsv::errs)getResponse(a, true)) != rfsv::E_PSI_GEN_NONE) return res; + a.addByte(0); + int l = a.getLen(); + char *s = (char *)a.getString(0); + for (int i = 0; i < l; i++) + if (s[i] == 6) + s[i] = 0; + owner.clear(); + while (l > 0) { + if (*s != '\0') { + bufferStore b; + b.addStringT(s); + owner += b; + l -= (strlen(s) + 1); + s += (strlen(s) + 1); + } else { + l--; + s++; + } + } + return res; } Enum<rfsv::errs> rpcs:: getMachineType(Enum<machs> &type) { - Enum<rfsv::errs> res; - bufferStore a; - - if (!sendCommand(GET_MACHINETYPE, a)) - return rfsv::E_PSI_FILE_DISC; - if ((res = getResponse(a, true)) != rfsv::E_PSI_GEN_NONE) - return res; - if (a.getLen() != 2) - return rfsv::E_PSI_GEN_FAIL; - type = (enum machs)a.getWord(0); + Enum<rfsv::errs> res; + bufferStore a; + + if (!sendCommand(GET_MACHINETYPE, a)) + return rfsv::E_PSI_FILE_DISC; + if ((res = getResponse(a, true)) != rfsv::E_PSI_GEN_NONE) return res; + if (a.getLen() != 2) + return rfsv::E_PSI_GEN_FAIL; + type = (enum machs)a.getWord(0); + return res; } Enum<rfsv::errs> rpcs:: fuser(const char *name, char *buf, int maxlen) { - Enum<rfsv::errs> res; - bufferStore a; - char *p; - - a.addStringT(name); - if (!sendCommand(FUSER, a)) - return rfsv::E_PSI_FILE_DISC; - if ((res = getResponse(a, true)) != rfsv::E_PSI_GEN_NONE) - return res; - strncpy(buf, a.getString(0), maxlen - 1); - while ((p = strchr(buf, 6))) - *p = '\0'; + Enum<rfsv::errs> res; + bufferStore a; + char *p; + + a.addStringT(name); + if (!sendCommand(FUSER, a)) + return rfsv::E_PSI_FILE_DISC; + if ((res = getResponse(a, true)) != rfsv::E_PSI_GEN_NONE) return res; + strncpy(buf, a.getString(0), maxlen - 1); + while ((p = strchr(buf, 6))) + *p = '\0'; + return res; } Enum<rfsv::errs> rpcs:: quitServer(void) { - bufferStore a; - if (!sendCommand(QUIT_SERVER, a)) - return rfsv::E_PSI_FILE_DISC; - return getResponse(a, true); + bufferStore a; + if (!sendCommand(QUIT_SERVER, a)) + return rfsv::E_PSI_FILE_DISC; + return getResponse(a, true); } + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ @@ -1,5 +1,27 @@ -#ifndef _rpcs_h_ -#define _rpcs_h_ +/*-*-c++-*- + * $Id$ + * + * This file is part of plptools. + * + * Copyright (C) 1999-2001 Fritz Elfert <felfert@to.com> + * + * 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 _RPCS_H_ +#define _RPCS_H_ #include "psitime.h" #include "rfsv.h" @@ -25,343 +47,349 @@ class bufferArray; * @author Fritz Elfert <felfert@to.com> */ class rpcs { - public: - /** - * The known machine types. - */ - enum machs { - PSI_MACH_UNKNOWN = 0, - PSI_MACH_PC = 1, - PSI_MACH_MC = 2, - PSI_MACH_HC = 3, - PSI_MACH_S3 = 4, - PSI_MACH_S3A = 5, - PSI_MACH_WORKABOUT = 6, - PSI_MACH_SIENNA = 7, - PSI_MACH_S3C = 8, - PSI_MACH_S5 = 32, - PSI_MACH_WINC = 33, - // TODO: Code for 5mx - }; - - /** - * The known interface languages. - */ - enum languages { - PSI_LANG_TEST = 0, - PSI_LANG_en_GB = 1, - PSI_LANG_fr_FR = 2, - PSI_LANG_de_DE = 3, - PSI_LANG_es_ES = 4, - PSI_LANG_it_IT = 5, - PSI_LANG_sv_SE = 6, - PSI_LANG_da_DK = 7, - PSI_LANG_no_NO = 8, - PSI_LANG_fi_FI = 9, - PSI_LANG_en_US = 10, - PSI_LANG_fr_CH = 11, - PSI_LANG_de_CH = 12, - PSI_LANG_pt_PT = 13, - PSI_LANG_tr_TR = 14, - PSI_LANG_is_IS = 15, - PSI_LANG_ru_RU = 16, - PSI_LANG_hu_HU = 17, - PSI_LANG_nl_NL = 18, - PSI_LANG_nl_BE = 19, - PSI_LANG_en_AU = 20, - PSI_LANG_fr_BE = 21, - PSI_LANG_de_AT = 22, - PSI_LANG_en_NZ = 23, - PSI_LANG_fr_CA = 24, - PSI_LANG_cs_CZ = 25, - PSI_LANG_sk_SK = 26, - PSI_LANG_pl_PL = 27, - PSI_LANG_sl_SI = 28, - }; - - /** - * The known battery states. - */ - enum batterystates { - PSI_BATT_DEAD = 0, - PSI_BATT_VERYLOW = 1, - PSI_BATT_LOW = 2, - PSI_BATT_GOOD = 3, - }; - - /** - * This struct holds the data returned - * by @ref rpcs::getMachineInfo. - */ - typedef struct machineInfo_t { - Enum<machs> machineType; - char machineName[17]; - unsigned long long machineUID; - unsigned long countryCode; - Enum<languages> uiLanguage; - - unsigned short romMajor; - unsigned short romMinor; - unsigned short romBuild; - unsigned long romSize; - bool romProgrammable; - - unsigned long ramSize; - unsigned long ramFree; - unsigned long ramMaxFree; - unsigned long ramDiskSize; - - unsigned long registrySize; - unsigned long displayWidth; - unsigned long displayHeight; - - psi_timeval time; - psi_timezone tz; - - psi_timeval mainBatteryInsertionTime; - Enum<batterystates> mainBatteryStatus; - psi_timeval mainBatteryUsedTime; - unsigned long mainBatteryCurrent; - unsigned long mainBatteryUsedPower; - unsigned long mainBatteryVoltage; - unsigned long mainBatteryMaxVoltage; - - Enum<batterystates> backupBatteryStatus; - unsigned long backupBatteryVoltage; - unsigned long backupBatteryMaxVoltage; - psi_timeval backupBatteryUsedTime; - - bool externalPower; - } machineInfo; - - /** - * Provides a virtual destructor. - */ - virtual ~rpcs() {}; - - /** - * Initializes a connection to the remote - * machine. - */ - void reset(); - - /** - * Attempts to re-establish a remote - * connection by first closing the socket, - * then connecting again to the ncpd daemon - * and finally calling @ref reset. - */ - void reconnect(); - - /** - * Retrieves the current status of the - * connection. - * - * @returns The connection status. - */ - Enum<rfsv::errs> getStatus(); - - /** - * Retrieves the version of the NCP protocol - * on the remote side. - * - * This function is working with both SIBO and EPOC - * devices. - * - * @param major The major part of the NCP version. - * Valid only if returned with no error. - * @param minor The minor part of the NCP version. - * Valid only if returned with no error. - * - * @returns A psion error code. 0 = Ok. - */ - Enum<rfsv::errs> getNCPversion(int &major, int &minor); - - /** - * Starts execution of a program on the remote machine. - * - * This function is working with both SIBO and EPOC - * devices. - * - * @param program The full path of the executable - * on the remote machine - * @param args The arguments for this program, separated - * by space. - * - * @returns A psion error code. 0 = Ok. - */ - Enum<rfsv::errs> execProgram(const char *program, const char *args); - - /** - * Requests termination of a program running on the - * remote machine. - * - * This function is working with both SIBO and EPOC - * devices. - * - * @param program - * - * @returns A psion error code. 0 = Ok. - */ - Enum<rfsv::errs> stopProgram(const char *); - - Enum<rfsv::errs> queryProgram(const char *); - Enum<rfsv::errs> formatOpen(const char *, int &, int &); - Enum<rfsv::errs> formatRead(int); - Enum<rfsv::errs> getUniqueID(const char *, long &); - - /** - * Retrieve owner information of the remote machine. - * - * This function is working with both SIBO and EPOC - * devices. - * - * @param owner A bufferArray, containing the lines - * of the owner info upon return. - * - * @returns A psion error code. 0 = Ok. - */ - Enum<rfsv::errs> getOwnerInfo(bufferArray &); - - /** - * Retrieves the type of machine on the remote side - * as defined in @ref #machs. - * - * This function is working with both SIBO and EPOC - * devices - * - * @param type The code describing the type of machine - * on the remote side is stored here on return. - * - * @returns A psion error code. 0 = Ok. - */ - Enum<rfsv::errs> getMachineType(Enum<machs> &type); - - /** - * Retrieves the name of a process, having a - * given file opened on the remote side. - * - * This function is working with both SIBO and EPOC - * devices - * - * @param name The full path of a file to be checked - * for beeing used by a program. - * @param buf A buffer which gets filled with the - * program's name. - * @param maxlen The maximum capacity of the buffer. - */ - Enum<rfsv::errs> fuser(const char *name, char *buf, int maxlen); - - /** - * Requests the remote server to terminate. - * - * This function is working with both SIBO and EPOC - * devices. There is usually no need to call this - * function, because the remote server is automatically - * stopped on disconnect. - * - * @returns A psion error code. 0 = Ok. - */ - Enum<rfsv::errs> quitServer(void); - - // API different on SIBO and EPOC - virtual Enum<rfsv::errs> queryDrive(const char, bufferArray &) = 0; - /** - * 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. - * - * @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<rfsv::errs> getCmdLine(const char *process, bufferStore &ret) = 0; - /** - * Retrieve general Information about the connected - * machine. - * - * This function works with EPOC only. Using it with SIBO - * machines, returns always an error code E_PSI_NOT_SIBO. - * - * @param machineInfo The struct holding all information on return. - * @return Psion error code. 0 = Ok. - */ - virtual Enum<rfsv::errs> getMachineInfo(machineInfo &) { return rfsv::E_PSI_NOT_SIBO;} - virtual Enum<rfsv::errs> closeHandle(int) { return rfsv::E_PSI_NOT_SIBO;} - virtual Enum<rfsv::errs> regOpenIter(void) { return rfsv::E_PSI_NOT_SIBO;} - virtual Enum<rfsv::errs> regReadIter(void) { return rfsv::E_PSI_NOT_SIBO;} - virtual Enum<rfsv::errs> regWrite(void) { return rfsv::E_PSI_NOT_SIBO;} - virtual Enum<rfsv::errs> regRead(void) { return rfsv::E_PSI_NOT_SIBO;} - virtual Enum<rfsv::errs> regDelete(void) { return rfsv::E_PSI_NOT_SIBO;} - virtual Enum<rfsv::errs> setTime(void) { return rfsv::E_PSI_NOT_SIBO;} - virtual Enum<rfsv::errs> configOpen(void) { return rfsv::E_PSI_NOT_SIBO;} - virtual Enum<rfsv::errs> configRead(void) { return rfsv::E_PSI_NOT_SIBO;} - virtual Enum<rfsv::errs> configWrite(void) { return rfsv::E_PSI_NOT_SIBO;} - virtual Enum<rfsv::errs> queryOpen(void) { return rfsv::E_PSI_NOT_SIBO;} - virtual Enum<rfsv::errs> queryRead(void) { return rfsv::E_PSI_NOT_SIBO;} - - protected: - /** - * The socket, used for communication - * with ncpd. - */ - ppsocket *skt; - - /** - * The current status of the connection. - */ - Enum<rfsv::errs> status; - - /** - * The possible commands. - */ - enum commands { - QUERY_NCP = 0x00, - EXEC_PROG = 0x01, - QUERY_DRIVE = 0x02, - STOP_PROG = 0x03, - QUERY_PROG = 0x04, - FORMAT_OPEN = 0x05, - FORMAT_READ = 0x06, - GET_UNIQUEID = 0x07, - GET_OWNERINFO = 0x08, - GET_MACHINETYPE = 0x09, - GET_CMDLINE = 0x0a, - FUSER = 0x0b, - GET_MACHINE_INFO = 0x64, - REG_OPEN_ITER = 0x66, - REG_READ_ITER = 0x67, - REG_WRITE = 0x68, - REG_READ = 0x69, - REG_DELETE = 0x6a, - SET_TIME = 0x6b, - CONFIG_OPEN = 0x6c, - CONFIG_READ = 0x6d, - CONFIG_WRITE = 0x6e, - QUERY_OPEN = 0x6f, - QUERY_READ = 0x70, - QUIT_SERVER = 0xff - }; - - /** - * Sends a command to the remote side. - * - * If communication fails, a reconnect is triggered - * and a second attempt to transmit the request - * is attempted. If that second attempt fails, - * the function returns an error an sets rpcs::status - * to E_PSI_FILE_DISC. - * - * @param cc The command to execute on the remote side. - * @param data Additional data for this command. - * - * @returns true on success, false on failure. - */ - bool sendCommand(enum commands cc, bufferStore &data); - Enum<rfsv::errs> getResponse(bufferStore &data, bool statusIsFirstByte); - const char *getConnectName(); +public: + /** + * The known machine types. + */ + enum machs { + PSI_MACH_UNKNOWN = 0, + PSI_MACH_PC = 1, + PSI_MACH_MC = 2, + PSI_MACH_HC = 3, + PSI_MACH_S3 = 4, + PSI_MACH_S3A = 5, + PSI_MACH_WORKABOUT = 6, + PSI_MACH_SIENNA = 7, + PSI_MACH_S3C = 8, + PSI_MACH_S5 = 32, + PSI_MACH_WINC = 33, + // TODO: Code for 5mx + }; + + /** + * The known interface languages. + */ + enum languages { + PSI_LANG_TEST = 0, + PSI_LANG_en_GB = 1, + PSI_LANG_fr_FR = 2, + PSI_LANG_de_DE = 3, + PSI_LANG_es_ES = 4, + PSI_LANG_it_IT = 5, + PSI_LANG_sv_SE = 6, + PSI_LANG_da_DK = 7, + PSI_LANG_no_NO = 8, + PSI_LANG_fi_FI = 9, + PSI_LANG_en_US = 10, + PSI_LANG_fr_CH = 11, + PSI_LANG_de_CH = 12, + PSI_LANG_pt_PT = 13, + PSI_LANG_tr_TR = 14, + PSI_LANG_is_IS = 15, + PSI_LANG_ru_RU = 16, + PSI_LANG_hu_HU = 17, + PSI_LANG_nl_NL = 18, + PSI_LANG_nl_BE = 19, + PSI_LANG_en_AU = 20, + PSI_LANG_fr_BE = 21, + PSI_LANG_de_AT = 22, + PSI_LANG_en_NZ = 23, + PSI_LANG_fr_CA = 24, + PSI_LANG_cs_CZ = 25, + PSI_LANG_sk_SK = 26, + PSI_LANG_pl_PL = 27, + PSI_LANG_sl_SI = 28, + }; + + /** + * The known battery states. + */ + enum batterystates { + PSI_BATT_DEAD = 0, + PSI_BATT_VERYLOW = 1, + PSI_BATT_LOW = 2, + PSI_BATT_GOOD = 3, + }; + + /** + * This struct holds the data returned + * by @ref rpcs::getMachineInfo. + */ + typedef struct machineInfo_t { + Enum<machs> machineType; + char machineName[17]; + unsigned long long machineUID; + unsigned long countryCode; + Enum<languages> uiLanguage; + + unsigned short romMajor; + unsigned short romMinor; + unsigned short romBuild; + unsigned long romSize; + bool romProgrammable; + + unsigned long ramSize; + unsigned long ramFree; + unsigned long ramMaxFree; + unsigned long ramDiskSize; + + unsigned long registrySize; + unsigned long displayWidth; + unsigned long displayHeight; + + psi_timeval time; + psi_timezone tz; + + psi_timeval mainBatteryInsertionTime; + Enum<batterystates> mainBatteryStatus; + psi_timeval mainBatteryUsedTime; + unsigned long mainBatteryCurrent; + unsigned long mainBatteryUsedPower; + unsigned long mainBatteryVoltage; + unsigned long mainBatteryMaxVoltage; + + Enum<batterystates> backupBatteryStatus; + unsigned long backupBatteryVoltage; + unsigned long backupBatteryMaxVoltage; + psi_timeval backupBatteryUsedTime; + + bool externalPower; + } machineInfo; + + /** + * Virtual destructor. + */ + virtual ~rpcs(); + + /** + * Initializes a connection to the remote + * machine. + */ + void reset(); + + /** + * Attempts to re-establish a remote + * connection by first closing the socket, + * then connecting again to the ncpd daemon + * and finally calling @ref reset. + */ + void reconnect(); + + /** + * Retrieves the current status of the + * connection. + * + * @returns The connection status. + */ + Enum<rfsv::errs> getStatus(); + + /** + * Retrieves the version of the NCP protocol + * on the remote side. + * + * This function is working with both SIBO and EPOC + * devices. + * + * @param major The major part of the NCP version. + * Valid only if returned with no error. + * @param minor The minor part of the NCP version. + * Valid only if returned with no error. + * + * @returns A psion error code. 0 = Ok. + */ + Enum<rfsv::errs> getNCPversion(int &major, int &minor); + + /** + * Starts execution of a program on the remote machine. + * + * This function is working with both SIBO and EPOC + * devices. + * + * @param program The full path of the executable + * on the remote machine + * @param args The arguments for this program, separated + * by space. + * + * @returns A psion error code. 0 = Ok. + */ + Enum<rfsv::errs> execProgram(const char *program, const char *args); + + /** + * Requests termination of a program running on the + * remote machine. + * + * This function is working with both SIBO and EPOC + * devices. + * + * @param program + * + * @returns A psion error code. 0 = Ok. + */ + Enum<rfsv::errs> stopProgram(const char *); + + Enum<rfsv::errs> queryProgram(const char *); + Enum<rfsv::errs> formatOpen(const char *, int &, int &); + Enum<rfsv::errs> formatRead(int); + Enum<rfsv::errs> getUniqueID(const char *, long &); + + /** + * Retrieve owner information of the remote machine. + * + * This function is working with both SIBO and EPOC + * devices. + * + * @param owner A bufferArray, containing the lines + * of the owner info upon return. + * + * @returns A psion error code. 0 = Ok. + */ + Enum<rfsv::errs> getOwnerInfo(bufferArray &); + + /** + * Retrieves the type of machine on the remote side + * as defined in @ref #machs. + * + * This function is working with both SIBO and EPOC + * devices + * + * @param type The code describing the type of machine + * on the remote side is stored here on return. + * + * @returns A psion error code. 0 = Ok. + */ + Enum<rfsv::errs> getMachineType(Enum<machs> &type); + + /** + * Retrieves the name of a process, having a + * given file opened on the remote side. + * + * This function is working with both SIBO and EPOC + * devices + * + * @param name The full path of a file to be checked + * for beeing used by a program. + * @param buf A buffer which gets filled with the + * program's name. + * @param maxlen The maximum capacity of the buffer. + */ + Enum<rfsv::errs> fuser(const char *name, char *buf, int maxlen); + + /** + * Requests the remote server to terminate. + * + * This function is working with both SIBO and EPOC + * devices. There is usually no need to call this + * function, because the remote server is automatically + * stopped on disconnect. + * + * @returns A psion error code. 0 = Ok. + */ + Enum<rfsv::errs> quitServer(void); + + // API different on SIBO and EPOC + virtual Enum<rfsv::errs> queryDrive(const char, bufferArray &) = 0; + /** + * 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. + * + * @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<rfsv::errs> getCmdLine(const char *process, bufferStore &ret) = 0; + /** + * Retrieve general Information about the connected + * machine. + * + * This function works with EPOC only. Using it with SIBO + * machines, returns always an error code E_PSI_NOT_SIBO. + * + * @param machineInfo The struct holding all information on return. + * @return Psion error code. 0 = Ok. + */ + virtual Enum<rfsv::errs> getMachineInfo(machineInfo &) { return rfsv::E_PSI_NOT_SIBO;} + virtual Enum<rfsv::errs> closeHandle(int) { return rfsv::E_PSI_NOT_SIBO;} + virtual Enum<rfsv::errs> regOpenIter(void) { return rfsv::E_PSI_NOT_SIBO;} + virtual Enum<rfsv::errs> regReadIter(void) { return rfsv::E_PSI_NOT_SIBO;} + virtual Enum<rfsv::errs> regWrite(void) { return rfsv::E_PSI_NOT_SIBO;} + virtual Enum<rfsv::errs> regRead(void) { return rfsv::E_PSI_NOT_SIBO;} + virtual Enum<rfsv::errs> regDelete(void) { return rfsv::E_PSI_NOT_SIBO;} + virtual Enum<rfsv::errs> setTime(void) { return rfsv::E_PSI_NOT_SIBO;} + virtual Enum<rfsv::errs> configOpen(void) { return rfsv::E_PSI_NOT_SIBO;} + virtual Enum<rfsv::errs> configRead(void) { return rfsv::E_PSI_NOT_SIBO;} + virtual Enum<rfsv::errs> configWrite(void) { return rfsv::E_PSI_NOT_SIBO;} + virtual Enum<rfsv::errs> queryOpen(void) { return rfsv::E_PSI_NOT_SIBO;} + virtual Enum<rfsv::errs> queryRead(void) { return rfsv::E_PSI_NOT_SIBO;} + +protected: + /** + * The socket, used for communication + * with ncpd. + */ + ppsocket *skt; + + /** + * The current status of the connection. + */ + Enum<rfsv::errs> status; + + /** + * The possible commands. + */ + enum commands { + QUERY_NCP = 0x00, + EXEC_PROG = 0x01, + QUERY_DRIVE = 0x02, + STOP_PROG = 0x03, + QUERY_PROG = 0x04, + FORMAT_OPEN = 0x05, + FORMAT_READ = 0x06, + GET_UNIQUEID = 0x07, + GET_OWNERINFO = 0x08, + GET_MACHINETYPE = 0x09, + GET_CMDLINE = 0x0a, + FUSER = 0x0b, + GET_MACHINE_INFO = 0x64, + REG_OPEN_ITER = 0x66, + REG_READ_ITER = 0x67, + REG_WRITE = 0x68, + REG_READ = 0x69, + REG_DELETE = 0x6a, + SET_TIME = 0x6b, + CONFIG_OPEN = 0x6c, + CONFIG_READ = 0x6d, + CONFIG_WRITE = 0x6e, + QUERY_OPEN = 0x6f, + QUERY_READ = 0x70, + QUIT_SERVER = 0xff + }; + + /** + * Sends a command to the remote side. + * + * If communication fails, a reconnect is triggered + * and a second attempt to transmit the request + * is attempted. If that second attempt fails, + * the function returns an error an sets rpcs::status + * to E_PSI_FILE_DISC. + * + * @param cc The command to execute on the remote side. + * @param data Additional data for this command. + * + * @returns true on success, false on failure. + */ + bool sendCommand(enum commands cc, bufferStore &data); + Enum<rfsv::errs> getResponse(bufferStore &data, bool statusIsFirstByte); + const char *getConnectName(); }; #endif + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ diff --git a/lib/rpcs16.cc b/lib/rpcs16.cc index 0a3121b..a65c937 100644 --- a/lib/rpcs16.cc +++ b/lib/rpcs16.cc @@ -1,19 +1,26 @@ -// -// 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 -// - +/*-*-c++-*- + * $Id$ + * + * This file is part of plptools. + * + * Copyright (C) 1999 Matt J. Gumbley <matt@gumbley.demon.co.uk> + * Copyright (C) 1999-2001 Fritz Elfert <felfert@to.com> + * + * 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 + * + */ #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -31,33 +38,30 @@ rpcs16::rpcs16(ppsocket * _skt) { - skt = _skt; - reset(); -} - -rpcs16::~rpcs16() -{ - bufferStore a; - a.addStringT("Close"); - if (status == rfsv::E_PSI_GEN_NONE) - skt->sendBufferStore(a); - skt->closeSocket(); + skt = _skt; + reset(); } Enum<rfsv::errs> rpcs16:: queryDrive(char drive, bufferArray &ret) { - bufferStore a; - a.addByte(drive); - if (!sendCommand(rpcs::QUERY_DRIVE, a)) - return rfsv::E_PSI_FILE_DISC; - Enum<rfsv::errs> res = getResponse(a, true); -cout << dec << "qd: " << res << " " << a.getLen() << " a="<< a << endl; - return res; + bufferStore a; + a.addByte(drive); + if (!sendCommand(rpcs::QUERY_DRIVE, a)) + return rfsv::E_PSI_FILE_DISC; + Enum<rfsv::errs> res = getResponse(a, true); + cout << dec << "qd: " << res << " " << a.getLen() << " a="<< a << endl; + return res; } Enum<rfsv::errs> rpcs16:: getCmdLine(const char *process, bufferStore &ret) { - return rfsv::E_PSI_GEN_NONE; + return rfsv::E_PSI_GEN_NONE; } + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ diff --git a/lib/rpcs16.h b/lib/rpcs16.h index cc4d601..24fcc6e 100644 --- a/lib/rpcs16.h +++ b/lib/rpcs16.h @@ -1,5 +1,28 @@ -#ifndef _rpcs16_h_ -#define _rpcs16_h_ +/*-*-c++-*- + * $Id$ + * + * This file is part of plptools. + * + * Copyright (C) 1999 Philip Proudman <philip.proudman@btinternet.com> + * Copyright (C) 1999-2001 Fritz Elfert <felfert@to.com> + * + * 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 _RPCS16_H_ +#define _RPCS16_H_ #include "rpcs.h" @@ -15,15 +38,20 @@ class rpcsfactory; * @ref rpcs . For a complete documentation, see @ref rpcs . */ class rpcs16 : public rpcs { - friend rpcsfactory; + friend rpcsfactory; public: - ~rpcs16(); - - Enum<rfsv::errs> queryDrive(const char, bufferArray &); - Enum<rfsv::errs> getCmdLine(const char *, bufferStore &); + Enum<rfsv::errs> queryDrive(const char, bufferArray &); + Enum<rfsv::errs> getCmdLine(const char *, bufferStore &); + private: - rpcs16(ppsocket *); + rpcs16(ppsocket *); }; #endif + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ diff --git a/lib/rpcs32.cc b/lib/rpcs32.cc index 772dea6..38d7933 100644 --- a/lib/rpcs32.cc +++ b/lib/rpcs32.cc @@ -1,19 +1,25 @@ -// -// 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 -// - +/*-*-c++-*- + * $Id$ + * + * This file is part of plptools. + * + * Copyright (C) 1999-2001 Fritz Elfert <felfert@to.com> + * + * 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 + * + */ #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -33,140 +39,131 @@ rpcs32::rpcs32(ppsocket * _skt) { - skt = _skt; - reset(); -} - -rpcs32::~rpcs32() -{ - bufferStore a; - a.addStringT("Close"); - if (status == rfsv::E_PSI_GEN_NONE) - skt->sendBufferStore(a); - skt->closeSocket(); + skt = _skt; + reset(); } Enum<rfsv::errs> rpcs32:: queryDrive(char drive, bufferArray &ret) { - bufferStore a; - Enum<rfsv::errs> 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); - } + bufferStore a; + Enum<rfsv::errs> 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<rfsv::errs> rpcs32:: getCmdLine(const char *process, bufferStore &ret) { - bufferStore a; - Enum<rfsv::errs> res; - - a.addStringT(process); - if (!sendCommand(rpcs::GET_CMDLINE, a)) - return rfsv::E_PSI_FILE_DISC; - res = getResponse(a, true); - ret = a; - return res; + bufferStore a; + Enum<rfsv::errs> res; + + a.addStringT(process); + if (!sendCommand(rpcs::GET_CMDLINE, a)) + return rfsv::E_PSI_FILE_DISC; + res = getResponse(a, true); + ret = a; + return res; } Enum<rfsv::errs> rpcs32:: getMachineInfo(machineInfo &mi) { - bufferStore a; - Enum<rfsv::errs> res; - - if (!sendCommand(rpcs::GET_MACHINE_INFO, a)) - return rfsv::E_PSI_FILE_DISC; - if ((res = getResponse(a, true)) != rfsv::E_PSI_GEN_NONE) - return res; - if (a.getLen() != 256) - return rfsv::E_PSI_GEN_FAIL; - mi.machineType = (enum rpcs::machs)a.getDWord(0); - strncpy(mi.machineName, a.getString(16), 16); - mi.machineName[16] = '\0'; - mi.machineUID = a.getDWord(44); - mi.machineUID <<= 32; - mi.machineUID |= a.getDWord(40); - mi.countryCode = a.getDWord(56); - mi.uiLanguage = (enum rpcs::languages)a.getDWord(164); - - mi.romMajor = a.getByte(4); - mi.romMinor = a.getByte(5); - mi.romBuild = a.getWord(6); - mi.romSize = a.getDWord(140); - - mi.ramSize = a.getDWord(136); - mi.ramMaxFree = a.getDWord(144); - mi.ramFree = a.getDWord(148); - mi.ramDiskSize = a.getDWord(152); - - mi.registrySize = a.getDWord(156); - mi.romProgrammable = (a.getDWord(160) != 0); - - mi.displayWidth = a.getDWord(32); - mi.displayHeight = a.getDWord(36); - - mi.time.tv_low = a.getDWord(48); - mi.time.tv_high = a.getDWord(52); - - mi.tz.utc_offset = a.getDWord(60); - mi.tz.dst_zones = a.getDWord(64); - mi.tz.home_zone = a.getDWord(68); - - PsiZone::getInstance().setZone(mi.tz); - - mi.mainBatteryInsertionTime.tv_low = a.getDWord(72); - mi.mainBatteryInsertionTime.tv_high = a.getDWord(76); - mi.mainBatteryStatus = (enum rpcs::batterystates)a.getDWord(80); - mi.mainBatteryUsedTime.tv_low = a.getDWord(84); - mi.mainBatteryUsedTime.tv_high = a.getDWord(88); - mi.mainBatteryCurrent = a.getDWord(92); - mi.mainBatteryUsedPower = a.getDWord(96); - mi.mainBatteryVoltage = a.getDWord(100); - mi.mainBatteryMaxVoltage = a.getDWord(104); - - mi.backupBatteryStatus = (enum rpcs::batterystates)a.getDWord(108); - mi.backupBatteryVoltage = a.getDWord(112); - mi.backupBatteryMaxVoltage = a.getDWord(116); - mi.backupBatteryUsedTime.tv_low = a.getDWord(124); - mi.backupBatteryUsedTime.tv_high = a.getDWord(128); - - mi.externalPower = (a.getDWord(120) != 0); + bufferStore a; + Enum<rfsv::errs> res; + if (!sendCommand(rpcs::GET_MACHINE_INFO, a)) + return rfsv::E_PSI_FILE_DISC; + if ((res = getResponse(a, true)) != rfsv::E_PSI_GEN_NONE) return res; + if (a.getLen() != 256) + return rfsv::E_PSI_GEN_FAIL; + mi.machineType = (enum rpcs::machs)a.getDWord(0); + strncpy(mi.machineName, a.getString(16), 16); + mi.machineName[16] = '\0'; + mi.machineUID = a.getDWord(44); + mi.machineUID <<= 32; + mi.machineUID |= a.getDWord(40); + mi.countryCode = a.getDWord(56); + mi.uiLanguage = (enum rpcs::languages)a.getDWord(164); + + mi.romMajor = a.getByte(4); + mi.romMinor = a.getByte(5); + mi.romBuild = a.getWord(6); + mi.romSize = a.getDWord(140); + + mi.ramSize = a.getDWord(136); + mi.ramMaxFree = a.getDWord(144); + mi.ramFree = a.getDWord(148); + mi.ramDiskSize = a.getDWord(152); + + mi.registrySize = a.getDWord(156); + mi.romProgrammable = (a.getDWord(160) != 0); + + mi.displayWidth = a.getDWord(32); + mi.displayHeight = a.getDWord(36); + + mi.time.tv_low = a.getDWord(48); + mi.time.tv_high = a.getDWord(52); + + mi.tz.utc_offset = a.getDWord(60); + mi.tz.dst_zones = a.getDWord(64); + mi.tz.home_zone = a.getDWord(68); + + PsiZone::getInstance().setZone(mi.tz); + + mi.mainBatteryInsertionTime.tv_low = a.getDWord(72); + mi.mainBatteryInsertionTime.tv_high = a.getDWord(76); + mi.mainBatteryStatus = (enum rpcs::batterystates)a.getDWord(80); + mi.mainBatteryUsedTime.tv_low = a.getDWord(84); + mi.mainBatteryUsedTime.tv_high = a.getDWord(88); + mi.mainBatteryCurrent = a.getDWord(92); + mi.mainBatteryUsedPower = a.getDWord(96); + mi.mainBatteryVoltage = a.getDWord(100); + mi.mainBatteryMaxVoltage = a.getDWord(104); + + mi.backupBatteryStatus = (enum rpcs::batterystates)a.getDWord(108); + mi.backupBatteryVoltage = a.getDWord(112); + mi.backupBatteryMaxVoltage = a.getDWord(116); + mi.backupBatteryUsedTime.tv_low = a.getDWord(124); + mi.backupBatteryUsedTime.tv_high = a.getDWord(128); + + mi.externalPower = (a.getDWord(120) != 0); + + return res; } static unsigned long hhh; @@ -174,55 +171,61 @@ static unsigned long hhh; Enum<rfsv::errs> rpcs32:: regOpenIter(void) { - bufferStore a; - Enum<rfsv::errs> res; - - a.addStringT("HKLM\\"); - if (!sendCommand(rpcs::REG_OPEN_ITER, a)) - return rfsv::E_PSI_FILE_DISC; - res = getResponse(a, true); - cout << "ro: r=" << res << " a=" << a << endl; - if (a.getLen() > 0) - hhh = a.getDWord(0); - return rfsv::E_PSI_GEN_NONE; + bufferStore a; + Enum<rfsv::errs> res; + + a.addStringT("HKLM\\"); + if (!sendCommand(rpcs::REG_OPEN_ITER, a)) + return rfsv::E_PSI_FILE_DISC; + res = getResponse(a, true); + cout << "ro: r=" << res << " a=" << a << endl; + if (a.getLen() > 0) + hhh = a.getDWord(0); + return rfsv::E_PSI_GEN_NONE; } Enum<rfsv::errs> rpcs32:: configOpen(void) { - bufferStore a; - Enum<rfsv::errs> res; - - if (!sendCommand(rpcs::CONFIG_OPEN, a)) - return rfsv::E_PSI_FILE_DISC; - res = getResponse(a, true); - cout << "co: r=" << res << " a=" << a << endl; - if (a.getLen() > 0) - hhh = a.getDWord(0); - return rfsv::E_PSI_GEN_NONE; + bufferStore a; + Enum<rfsv::errs> res; + + if (!sendCommand(rpcs::CONFIG_OPEN, a)) + return rfsv::E_PSI_FILE_DISC; + res = getResponse(a, true); + cout << "co: r=" << res << " a=" << a << endl; + if (a.getLen() > 0) + hhh = a.getDWord(0); + return rfsv::E_PSI_GEN_NONE; } Enum<rfsv::errs> rpcs32:: configRead(void) { - bufferStore a; - Enum<rfsv::errs> res; - int l; - FILE *f; - - f = fopen("blah", "w"); - do { - a.init(); - a.addDWord(hhh); - if (!sendCommand(rpcs::CONFIG_READ, a)) - return rfsv::E_PSI_FILE_DISC; - if ((res = getResponse(a, true)) != rfsv::E_PSI_GEN_NONE) - return res; - l = a.getLen(); - cout << "cr: " << l << endl; - fwrite(a.getString(0), 1, l, f); - } while (l > 0); - fclose(f); + bufferStore a; + Enum<rfsv::errs> res; + int l; + FILE *f; + + f = fopen("blah", "w"); + do { + a.init(); + a.addDWord(hhh); + if (!sendCommand(rpcs::CONFIG_READ, a)) + return rfsv::E_PSI_FILE_DISC; + if ((res = getResponse(a, true)) != rfsv::E_PSI_GEN_NONE) + return res; + l = a.getLen(); + cout << "cr: " << l << endl; + fwrite(a.getString(0), 1, l, f); + } while (l > 0); + fclose(f); //cout << "cr: r=" << res << " a=" << a << endl; - return rfsv::E_PSI_GEN_NONE; + return rfsv::E_PSI_GEN_NONE; } + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ diff --git a/lib/rpcs32.h b/lib/rpcs32.h index 5230247..5b56a4c 100644 --- a/lib/rpcs32.h +++ b/lib/rpcs32.h @@ -1,5 +1,28 @@ -#ifndef _rpcs32_h_ -#define _rpcs32_h_ +/*-*-c++-*- + * $Id$ + * + * This file is part of plptools. + * + * Copyright (C) 1999 Philip Proudman <philip.proudman@btinternet.com> + * Copyright (C) 1999-2001 Fritz Elfert <felfert@to.com> + * + * 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 _RPCS32_H_ +#define _RPCS32_H_ #include "rpcs.h" @@ -14,35 +37,39 @@ class rpcsfactory; * @ref rpcs . For a complete documentation, see @ref rpcs . */ class rpcs32 : public rpcs { - friend rpcsfactory; + friend rpcsfactory; 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); + 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 *); + rpcs32(ppsocket *); }; #endif + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ diff --git a/lib/rpcsfactory.cc b/lib/rpcsfactory.cc index bd3b77d..0861c2c 100644 --- a/lib/rpcsfactory.cc +++ b/lib/rpcsfactory.cc @@ -1,24 +1,25 @@ -// -// RPCSFACTORY - factory object that creates an appropriate RPCS object -// based on whatever the NCP daemon discovered in the INFO exchange. -// Derived from rfsvfactory by Matt J. Gumbley <matt@gumbley.demon.co.uk> -// -// Copyright (C) 2000 Fritz Elfert <felfert@to.com> -// -// 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 - +/*-*-c++-*- + * $Id$ + * + * This file is part of plptools. + * + * Copyright (C) 2000-2001 Fritz Elfert <felfert@to.com> + * + * 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 + * + */ #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -39,62 +40,67 @@ #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"); + stringRep.add(rpcsfactory::FACERR_NONE, N_("no error")); + stringRep.add(rpcsfactory::FACERR_COULD_NOT_SEND, N_("could not send version request")); + stringRep.add(rpcsfactory::FACERR_AGAIN, N_("try again")); + stringRep.add(rpcsfactory::FACERR_NOPSION, N_("no psion connected")); + stringRep.add(rpcsfactory::FACERR_PROTVERSION, N_("wrong protocol version")); + stringRep.add(rpcsfactory::FACERR_NORESPONSE, N_("no response from ncpd")); } rpcsfactory::rpcsfactory(ppsocket *_skt) { - err = FACERR_NONE; - skt = _skt; + err = FACERR_NONE; + skt = _skt; } rpcs * rpcsfactory::create(bool reconnect) { - // skt is connected to the ncp daemon, which will have (hopefully) seen - // an INFO exchange, where the protocol version of the remote Psion was - // sent, and noted. We have to ask the ncp daemon which protocol it saw, - // 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. + // skt is connected to the ncp daemon, which will have (hopefully) seen + // an INFO exchange, where the protocol version of the remote Psion was + // sent, and noted. We have to ask the ncp daemon which protocol it saw, + // 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; + bufferStore a; - err = FACERR_NONE; - a.addStringT("NCP$INFO"); - if (!skt->sendBufferStore(a)) { - if (!reconnect) - err = FACERR_COULD_NOT_SEND; - else { - skt->closeSocket(); - skt->reconnect(); - err = FACERR_AGAIN; - } - return NULL; + err = FACERR_NONE; + a.addStringT("NCP$INFO"); + if (!skt->sendBufferStore(a)) { + if (!reconnect) + err = FACERR_COULD_NOT_SEND; + else { + skt->closeSocket(); + skt->reconnect(); + err = FACERR_AGAIN; } - if (skt->getBufferStore(a) == 1) { - if (a.getLen() > 8 && !strncmp(a.getString(), "Series 3", 8)) { - return new rpcs16(skt); - } - else if (a.getLen() > 8 && !strncmp(a.getString(), "Series 5", 8)) { - return new rpcs32(skt); - } - if ((a.getLen() > 8) && !strncmp(a.getString(), "No Psion", 8)) { - skt->closeSocket(); - skt->reconnect(); - err = FACERR_NOPSION; - return NULL; - } - // Invalid protocol version - err = FACERR_PROTVERSION; - } else - err = FACERR_NORESPONSE; - - // No message returned. return NULL; + } + if (skt->getBufferStore(a) == 1) { + if (a.getLen() > 8 && !strncmp(a.getString(), "Series 3", 8)) { + return new rpcs16(skt); + } + else if (a.getLen() > 8 && !strncmp(a.getString(), "Series 5", 8)) { + return new rpcs32(skt); + } + if ((a.getLen() > 8) && !strncmp(a.getString(), "No Psion", 8)) { + skt->closeSocket(); + skt->reconnect(); + err = FACERR_NOPSION; + return NULL; + } + // Invalid protocol version + err = FACERR_PROTVERSION; + } else + err = FACERR_NORESPONSE; + + // No message returned. + return NULL; } +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ diff --git a/lib/rpcsfactory.h b/lib/rpcsfactory.h index cc36f0d..c08800a 100644 --- a/lib/rpcsfactory.h +++ b/lib/rpcsfactory.h @@ -1,5 +1,28 @@ -#ifndef _rpcsfactory_h_ -#define _rpcsfactory_h_ +/*-*-c++-*- + * $Id$ + * + * This file is part of plptools. + * + * Copyright (C) 1999 Philip Proudman <philip.proudman@btinternet.com> + * Copyright (C) 1999-2001 Fritz Elfert <felfert@to.com> + * + * 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 _RPCSFACTORY_H_ +#define _RPCSFACTORY_H_ #include "rpcs.h" @@ -12,53 +35,58 @@ 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, - }; + /** + * 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. - * - * @param skt The socket to be used for connecting - * to the ncpd daemon. - */ - rpcsfactory(ppsocket * skt); + /** + * Constructs a rpcsfactory. + * + * @param skt The socket to be used for connecting + * to the ncpd daemon. + */ + rpcsfactory(ppsocket * skt); - /** - * Creates a new rpcs instance. - * - * @param reconnect Set to true, if automatic reconnect - * should be performed on failure. - * - * @returns A pointer to a newly created rpcs instance or - * NULL on failure. - */ - virtual rpcs * create(bool reconnect); + /** + * Creates a new rpcs instance. + * + * @param reconnect Set to true, if automatic reconnect + * should be performed on failure. + * + * @returns A pointer to a newly created rpcs instance or + * NULL on failure. + */ + 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; } + /** + * 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; + /** + * The socket to be used for connecting to the + * ncpd daemon. + */ + ppsocket *skt; + Enum<errs> err; }; #endif +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ diff --git a/ncpd/Makefile.am b/ncpd/Makefile.am index 6fc303c..8885fee 100644 --- a/ncpd/Makefile.am +++ b/ncpd/Makefile.am @@ -4,7 +4,7 @@ INCLUDES=-I$(top_srcdir)/lib sbin_PROGRAMS = ncpd -ncpd_LDADD = $(top_srcdir)/lib/libplp.la +ncpd_LDADD = $(top_srcdir)/lib/libplp.la $(LIBCCMALLOC) ncpd_SOURCES = channel.cc link.cc linkchan.cc main.cc \ ncp.cc packet.cc socketchan.cc mp_serial.c EXTRA_DIST = channel.h link.h linkchan.h mp_serial.h ncp.h packet.h socketchan.h diff --git a/ncpd/socketchan.cc b/ncpd/socketchan.cc index 06b3da2..fa1a40f 100644 --- a/ncpd/socketchan.cc +++ b/ncpd/socketchan.cc @@ -130,10 +130,11 @@ ncpConnectAck() void socketChan:: ncpConnectTerminate() { - bufferStore a; +// bufferStore a; connectTry = 0; - a.addStringT("Close"); - skt->sendBufferStore(a); +// a.addStringT("Close"); +// skt->sendBufferStore(a); + skt->closeSocket(); terminateWhenAsked(); } @@ -202,13 +203,14 @@ socketPoll() int res = skt->getBufferStore(a, false); if (res == -1) { ncpDisconnect(); + skt->closeSocket(); } else if (res == 1) { - if (a.getLen() > 5 && - !strncmp(a.getString(), "Close", 5)) { - ncpDisconnect(); - } else { +// if (a.getLen() > 4 && +// !strncmp(a.getString(), "Close", 5)) { +// ncpDisconnect(); +// } else { ncpSend(a); - } +// } } } } diff --git a/plpftp/Makefile.am b/plpftp/Makefile.am index ba8e40c..e9ee682 100644 --- a/plpftp/Makefile.am +++ b/plpftp/Makefile.am @@ -1,6 +1,6 @@ # $Id$ # -INCLUDES=-I$(top_srcdir)/lib +INCLUDES = -I$(top_srcdir)/lib -I$(top_srcdir)/intl if HAVE_LIBREADLINE if ADD_LIBCURSES @@ -14,7 +14,7 @@ LIBHISTORY=-lhistory endif bin_PROGRAMS = plpftp -plpftp_LDADD = $(top_srcdir)/lib/libplp.la $(LIBREADLINE) $(LIBHISTORY) +plpftp_LDADD = $(top_srcdir)/lib/libplp.la $(LIBREADLINE) $(LIBHISTORY) $(LIBCCMALLOC) $(INTLLIBS) plpftp_SOURCES = ftp.cc main.cc rlcrap.c EXTRA_DIST = ftp.h rlcrap.h diff --git a/plpftp/ftp.cc b/plpftp/ftp.cc index efe4f82..013a063 100644 --- a/plpftp/ftp.cc +++ b/plpftp/ftp.cc @@ -1,27 +1,26 @@ -// $Id$ -// -// PLP - An implementation of the PSION link protocol -// -// Copyright (C) 1999 Philip Proudman -// Modifications for plptools: -// Copyright (C) 1999 Fritz Elfert <felfert@to.com> -// -// 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 -// -// e-mail philip.proudman@btinternet.com - +/*-*-c++-*- + * $Id$ + * + * This file is part of plptools. + * + * Copyright (C) 1999 Philip Proudman <philip.proudman@btinternet.com> + * Copyright (C) 1999-2001 Fritz Elfert <felfert@to.com> + * + * 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 + * + */ #define EXPERIMENTAL #ifdef HAVE_CONFIG_H @@ -42,6 +41,7 @@ #include <sys/stat.h> #include <signal.h> +#include "intl.h" #include "ftp.h" #include "rfsv.h" #include "rpcs.h" @@ -67,13 +67,13 @@ static int continueRunning; void ftp:: resetUnixPwd() { - getcwd(localDir, 500); - strcat(localDir, "/"); + getcwd(localDir, 500); + strcat(localDir, "/"); } ftp::ftp() { - resetUnixPwd(); + resetUnixPwd(); } ftp::~ftp() @@ -81,40 +81,40 @@ ftp::~ftp() } void ftp::usage() { - cout << "Known FTP commands:" << endl << endl; - cout << " pwd" << endl; - cout << " ren <oldname> <newname>" << endl; - cout << " touch <psionfile>" << endl; - cout << " gtime <psionfile>" << endl; - cout << " test <psionfile>" << endl; - cout << " gattr <psionfile>" << endl; - cout << " sattr [[-|+]rwhsa] <psionfile>" << endl; - cout << " devs" << endl; - cout << " dir|ls" << endl; - cout << " dircnt" << endl; - cout << " cd <dir>" << endl; - cout << " lcd <dir>" << endl; - cout << " !<system command>" << endl; - cout << " get <psionfile>" << endl; - cout << " put <unixfile>" << endl; - cout << " mget <shellpattern>" << endl; - cout << " mput <shellpattern>" << endl; - cout << " cp <psionfile> <psionfile>" << endl; - cout << " del|rm <psionfile>" << endl; - cout << " mkdir <psiondir>" << endl; - cout << " rmdir <psiondir>" << endl; - cout << " volname <drive> <name>" << endl; - cout << " prompt" << endl; - cout << " hash" << endl; - cout << " bye" << endl; - cout << endl << "Known RPC commands:" << endl << endl; - cout << " ps" << endl; - cout << " kill <pid|'all'>" << endl; - cout << " run <psionfile> [args]" << endl; - cout << " killsave <unixfile>" << endl; - cout << " runrestore <unixfile>" << endl; - cout << " machinfo" << endl; - cout << " ownerinfo" << endl; + cout << _("Known FTP commands:") << endl << endl; + cout << " pwd" << endl; + cout << " ren <oldname> <newname>" << endl; + cout << " touch <psionfile>" << endl; + cout << " gtime <psionfile>" << endl; + cout << " test <psionfile>" << endl; + cout << " gattr <psionfile>" << endl; + cout << " sattr [[-|+]rwhsa] <psionfile>" << endl; + cout << " devs" << endl; + cout << " dir|ls" << endl; + cout << " dircnt" << endl; + cout << " cd <dir>" << endl; + cout << " lcd <dir>" << endl; + cout << " !<system command>" << endl; + cout << " get <psionfile>" << endl; + cout << " put <unixfile>" << endl; + cout << " mget <shellpattern>" << endl; + cout << " mput <shellpattern>" << endl; + cout << " cp <psionfile> <psionfile>" << endl; + cout << " del|rm <psionfile>" << endl; + cout << " mkdir <psiondir>" << endl; + cout << " rmdir <psiondir>" << endl; + cout << " volname <drive> <name>" << endl; + cout << " prompt" << endl; + cout << " hash" << endl; + cout << " bye" << endl; + cout << endl << _("Known RPC commands:") << endl << endl; + cout << " ps" << endl; + cout << " kill <pid|'all'>" << endl; + cout << " run <psionfile> [args]" << endl; + cout << " killsave <unixfile>" << endl; + cout << " runrestore <unixfile>" << endl; + cout << " machinfo" << endl; + cout << " ownerinfo" << endl; } static int Wildmat(const char *s, char *p); @@ -122,868 +122,868 @@ static int Wildmat(const char *s, char *p); static int Star(const char *s, char *p) { - while (Wildmat(s, p) == 0) - if (*++s == '\0') - return 0; - return 1; + while (Wildmat(s, p) == 0) + if (*++s == '\0') + return 0; + return 1; } static int Wildmat(const char *s, char *p) { - register int last; - register int matched; - register int reverse; + register int last; + register int matched; + register int reverse; - for (; *p; s++, p++) - switch (*p) { - case '\\': - /* - * Literal match with following character, - * fall through. - */ - p++; - default: - if (*s != *p) - return (0); - continue; - case '?': - /* Match anything. */ - if (*s == '\0') - return (0); - continue; - case '*': - /* Trailing star matches everything. */ - return (*++p ? Star(s, p) : 1); - case '[': - /* [^....] means inverse character class. */ - if ((reverse = (p[1] == '^'))) - p++; - for (last = 0, matched = 0; *++p && (*p != ']'); last = *p) - /* This next line requires a good C compiler. */ - if (*p == '-' ? *s <= *++p && *s >= last : *s == *p) - matched = 1; - if (matched == reverse) - return (0); - continue; - } - return (*s == '\0'); + for (; *p; s++, p++) + switch (*p) { + case '\\': + /* + * Literal match with following character, + * fall through. + */ + p++; + default: + if (*s != *p) + return (0); + continue; + case '?': + /* Match anything. */ + if (*s == '\0') + return (0); + continue; + case '*': + /* Trailing star matches everything. */ + return (*++p ? Star(s, p) : 1); + case '[': + /* [^....] means inverse character class. */ + if ((reverse = (p[1] == '^'))) + p++; + for (last = 0, matched = 0; *++p && (*p != ']'); last = *p) + /* This next line requires a good C compiler. */ + if (*p == '-' ? *s <= *++p && *s >= last : *s == *p) + matched = 1; + if (matched == reverse) + return (0); + continue; + } + return (*s == '\0'); } static int checkAbortNoHash(void *, u_int32_t) { - return continueRunning; + return continueRunning; } static int checkAbortHash(void *, u_int32_t) { - if (continueRunning) { - printf("#"); fflush(stdout); - } - return continueRunning; + if (continueRunning) { + printf("#"); fflush(stdout); + } + return continueRunning; } static RETSIGTYPE sigint_handler(int i) { - continueRunning = 0; - signal(SIGINT, sigint_handler); + continueRunning = 0; + signal(SIGINT, sigint_handler); } static RETSIGTYPE sigint_handler2(int i) { - continueRunning = 0; - fclose(stdin); - signal(SIGINT, sigint_handler2); + continueRunning = 0; + fclose(stdin); + signal(SIGINT, sigint_handler2); } int ftp:: session(rfsv & a, rpcs & r, int xargc, char **xargv) { - int argc; - char *argv[10]; - char f1[256]; - char f2[256]; - Enum<rfsv::errs> res; - bool prompt = true; - bool hash = false; - bool S5mx = false; - cpCallback_t cab = checkAbortNoHash; - bool once = false; + int argc; + char *argv[10]; + char f1[256]; + char f2[256]; + Enum<rfsv::errs> res; + bool prompt = true; + bool hash = false; + bool S5mx = false; + cpCallback_t cab = checkAbortNoHash; + bool once = false; + + if (xargc > 1) { + once = true; + argc = (xargc<11)?xargc-1:10; + for (int i = 0; i < argc; i++) + argv[i] = xargv[i+1]; + } + { + Enum<rpcs::machs> machType; + bufferArray b; + if ((res = r.getOwnerInfo(b)) == rfsv::E_PSI_GEN_NONE) { + r.getMachineType(machType); + if (!once) { + cout << _("Connected to a ") << machType << _(", OwnerInfo:") << endl; + while (!b.empty()) + 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; + } + + if (!strcmp(DDRIVE, "AUTO")) { + u_int32_t devbits; + int i; - if (xargc > 1) { - once = true; - argc = (xargc<11)?xargc-1:10; - for (int i = 0; i < argc; i++) - argv[i] = xargv[i+1]; + strcpy(defDrive, "::"); + if (a.devlist(devbits) == rfsv::E_PSI_GEN_NONE) { + + for (i = 0; i < 26; i++) { + PlpDrive drive; + if ((devbits & 1) && a.devinfo(i, drive) == rfsv::E_PSI_GEN_NONE) { + defDrive[0] = 'A' + i; + break; + } + devbits >>= 1; + } } - { - Enum<rpcs::machs> machType; - bufferArray b; - if ((res = r.getOwnerInfo(b)) == rfsv::E_PSI_GEN_NONE) { - r.getMachineType(machType); - if (!once) { - cout << "Connected to a " << machType << ", OwnerInfo:" << endl; - while (!b.empty()) - 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; + if (!strcmp(defDrive, "::")) { + cerr << _("FATAL: Couln't find default Drive") << endl; + return -1; } + } else + strcpy(defDrive, DDRIVE); + strcpy(psionDir, defDrive); + strcat(psionDir, DBASEDIR); + comp_a = &a; + if (!once) { + cout << _("Psion dir is: \"") << psionDir << "\"" << endl; + initReadline(); + } + continueRunning = 1; + signal(SIGINT, sigint_handler); + do { + if (!once) + getCommand(argc, argv); - if (!strcmp(DDRIVE, "AUTO")) { - u_int32_t devbits; - int i; + if (!strcmp(argv[0], "help")) { + usage(); + continue; + } + if (!strcmp(argv[0], "prompt")) { + prompt = !prompt; + cout << _("Prompting now ") << (prompt? _("on") : _("off")) << endl; + continue; + } + if (!strcmp(argv[0], "hash")) { + hash = !hash; + cout << _("Hash printing now ") << (hash? _("on") : _("off")) << endl; + cab = (hash) ? checkAbortHash : checkAbortNoHash; + continue; + } + if (!strcmp(argv[0], "pwd")) { + cout << _("Local dir: \"") << localDir << "\"" << endl; + cout << _("Psion dir: \"") << psionDir << "\"" << endl; + continue; + } + if (!strcmp(argv[0], "volname") && (argc == 3) && (strlen(argv[1]) == 1)) { + if ((res = a.setVolumeName(toupper(argv[1][0]), argv[2])) != rfsv::E_PSI_GEN_NONE) + cerr << _("Error: ") << res << endl; + continue; - strcpy(defDrive, "::"); - if (a.devlist(devbits) == rfsv::E_PSI_GEN_NONE) { + } + if (!strcmp(argv[0], "ren") && (argc == 3)) { + strcpy(f1, psionDir); + strcat(f1, argv[1]); + strcpy(f2, psionDir); + strcat(f2, argv[2]); + if ((res = a.rename(f1, f2)) != rfsv::E_PSI_GEN_NONE) + cerr << _("Error: ") << res << endl; + continue; + } + if (!strcmp(argv[0], "cp") && (argc == 3)) { + strcpy(f1, psionDir); + strcat(f1, argv[1]); + strcpy(f2, psionDir); + strcat(f2, argv[2]); + if ((res = a.copyOnPsion(f1, f2, NULL, cab)) != rfsv::E_PSI_GEN_NONE) + cerr << _("Error: ") << res << endl; + continue; + } + if (!strcmp(argv[0], "touch") && (argc == 2)) { + strcpy(f1, psionDir); + strcat(f1, argv[1]); + PsiTime pt; + if ((res = a.fsetmtime(f1, pt)) != rfsv::E_PSI_GEN_NONE) + cerr << _("Error: ") << res << endl; + continue; + } + if (!strcmp(argv[0], "test") && (argc == 2)) { + PlpDirent e; + strcpy(f1, psionDir); + strcat(f1, argv[1]); + if ((res = a.fgeteattr(f1, e)) != rfsv::E_PSI_GEN_NONE) + cerr << _("Error: ") << res << endl; + else + cout << e << endl; + continue; + } + if (!strcmp(argv[0], "gattr") && (argc == 2)) { + u_int32_t attr; + strcpy(f1, psionDir); + strcat(f1, argv[1]); + if ((res = a.fgetattr(f1, attr)) != rfsv::E_PSI_GEN_NONE) + cerr << _("Error: ") << res << endl; + else { + cout << hex << setw(4) << setfill('0') << attr; + cout << " (" << a.attr2String(attr) << ")" << endl; + } + continue; + } + if (!strcmp(argv[0], "gtime") && (argc == 2)) { + PsiTime mtime; + strcpy(f1, psionDir); + strcat(f1, argv[1]); + if ((res = a.fgetmtime(f1, mtime)) != rfsv::E_PSI_GEN_NONE) + cerr << _("Error: ") << res << endl; + else + cout << mtime << endl; + continue; + } + if (!strcmp(argv[0], "sattr") && (argc == 3)) { + long attr[2]; + int aidx = 0; + char *p = argv[1]; - for (i = 0; i < 26; i++) { - PlpDrive drive; - if ((devbits & 1) && a.devinfo(i, drive) == rfsv::E_PSI_GEN_NONE) { - defDrive[0] = 'A' + i; - break; - } - devbits >>= 1; - } - } - if (!strcmp(defDrive, "::")) { - cerr << "FATAL: Couln't find default Drive" << endl; - return -1; + strcpy(f1, psionDir); + strcat(f1, argv[2]); + + attr[0] = attr[1] = 0; + while (*p) { + switch (*p) { + case '+': + aidx = 0; + break; + case '-': + aidx = 1; + break; + case 'r': + attr[aidx] |= rfsv::PSI_A_READ; + attr[aidx] &= ~rfsv::PSI_A_READ; + break; + case 'w': + attr[1 - aidx] |= rfsv::PSI_A_RDONLY; + attr[aidx] &= ~rfsv::PSI_A_RDONLY; + break; + case 'h': + attr[aidx] |= rfsv::PSI_A_HIDDEN; + attr[1 - aidx] &= ~rfsv::PSI_A_HIDDEN; + break; + case 's': + attr[aidx] |= rfsv::PSI_A_SYSTEM; + attr[1 - aidx] &= ~rfsv::PSI_A_SYSTEM; + break; + case 'a': + attr[aidx] |= rfsv::PSI_A_ARCHIVE; + attr[1 - aidx] &= ~rfsv::PSI_A_ARCHIVE; + break; } - } else - strcpy(defDrive, DDRIVE); - strcpy(psionDir, defDrive); - strcat(psionDir, DBASEDIR); - comp_a = &a; - if (!once) { - cout << "Psion dir is: \"" << psionDir << "\"" << endl; - initReadline(); + p++; + } + if ((res = a.fsetattr(f1, attr[0], attr[1])) != rfsv::E_PSI_GEN_NONE) + cerr << _("Error: ") << res << endl; + continue; } - continueRunning = 1; - signal(SIGINT, sigint_handler); - do { - if (!once) - getCommand(argc, argv); + if (!strcmp(argv[0], "dircnt")) { + u_int32_t cnt; + if ((res = a.dircount(psionDir, cnt)) != rfsv::E_PSI_GEN_NONE) + cerr << _("Error: ") << res << endl; + else + cout << cnt << _(" Entries") << endl; + continue; + } + if (!strcmp(argv[0], "devs")) { + u_int32_t devbits; + if ((res = a.devlist(devbits)) == rfsv::E_PSI_GEN_NONE) { + cout << _("Drive Type Volname Total Free UniqueID") << endl; + for (int i = 0; i < 26; i++) { + PlpDrive drive; - if (!strcmp(argv[0], "help")) { - usage(); - continue; - } - if (!strcmp(argv[0], "prompt")) { - prompt = !prompt; - cout << "Prompting now " << (prompt?"on":"off") << endl; - continue; - } - if (!strcmp(argv[0], "hash")) { - hash = !hash; - cout << "Hash printing now " << (hash?"on":"off") << endl; - cab = (hash) ? checkAbortHash : checkAbortNoHash; - continue; - } - if (!strcmp(argv[0], "pwd")) { - cout << "Local dir: \"" << localDir << "\"" << endl; - cout << "Psion dir: \"" << psionDir << "\"" << endl; - continue; - } - if (!strcmp(argv[0], "volname") && (argc == 3) && (strlen(argv[1]) == 1)) { - if ((res = a.setVolumeName(toupper(argv[1][0]), argv[2])) != rfsv::E_PSI_GEN_NONE) - cerr << "Error: " << res << endl; - continue; - - } - if (!strcmp(argv[0], "ren") && (argc == 3)) { - strcpy(f1, psionDir); - strcat(f1, argv[1]); - strcpy(f2, psionDir); - strcat(f2, argv[2]); - if ((res = a.rename(f1, f2)) != rfsv::E_PSI_GEN_NONE) - cerr << "Error: " << res << endl; - continue; + if ((devbits & 1) != 0) { + if (a.devinfo(i, 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() << resetiosflags(ios::left) << dec << setw(9) << + drive.getSize() << setw(9) << drive.getSpace() << " " << setw(8) << setfill('0') << hex << + drive.getUID() << endl; + } + devbits >>= 1; } - if (!strcmp(argv[0], "cp") && (argc == 3)) { - strcpy(f1, psionDir); - strcat(f1, argv[1]); - strcpy(f2, psionDir); - strcat(f2, argv[2]); - if ((res = a.copyOnPsion(f1, f2, NULL, cab)) != rfsv::E_PSI_GEN_NONE) - cerr << "Error: " << res << endl; - continue; + } else + cerr << _("Error: ") << res << endl; + continue; + } + if (!strcmp(argv[0], "ls") || !strcmp(argv[0], "dir")) { + PlpDir files; + if ((res = a.dir(psionDir, files)) != rfsv::E_PSI_GEN_NONE) + cerr << _("Error: ") << res << endl; + else + while (!files.empty()) { + cout << files[0] << endl; + files.pop_front(); } - if (!strcmp(argv[0], "touch") && (argc == 2)) { + continue; + } + if (!strcmp(argv[0], "lcd")) { + if (argc == 1) + resetUnixPwd(); + else { + if (chdir(argv[1]) == 0) { + getcwd(localDir, sizeof(localDir)); + strcat(localDir, "/"); + } else + cerr << _("No such directory") << endl + << _("Keeping original directory \"") << localDir << "\"" << endl; + } + continue; + } + if (!strcmp(argv[0], "cd")) { + if (argc == 1) { + strcpy(psionDir, defDrive); + strcat(psionDir, DBASEDIR); + } else { + u_int32_t tmp; + if (!strcmp(argv[1], "..")) { + strcpy(f1, psionDir); + char *p = f1 + strlen(f1); + if (p > f1) + p--; + *p = '\0'; + while ((p > f1) && (*p != '/') && (*p != '\\')) + p--; + *(++p) = '\0'; + if (strlen(f1) < 3) { strcpy(f1, psionDir); - strcat(f1, argv[1]); - PsiTime pt; - if ((res = a.fsetmtime(f1, pt)) != rfsv::E_PSI_GEN_NONE) - cerr << "Error: " << res << endl; - continue; - } - if (!strcmp(argv[0], "test") && (argc == 2)) { - PlpDirent e; + f1[3] = '\0'; + } + } else { + if ((argv[1][0] != '/') && (argv[1][0] != '\\') && + (argv[1][1] != ':')) { strcpy(f1, psionDir); strcat(f1, argv[1]); - if ((res = a.fgeteattr(f1, e)) != rfsv::E_PSI_GEN_NONE) - cerr << "Error: " << res << endl; - else - cout << e << endl; - continue; + } else + strcpy(f1, argv[1]); } - if (!strcmp(argv[0], "gattr") && (argc == 2)) { - u_int32_t attr; - strcpy(f1, psionDir); - strcat(f1, argv[1]); - if ((res = a.fgetattr(f1, attr)) != rfsv::E_PSI_GEN_NONE) - cerr << "Error: " << res << endl; - else { - cout << hex << setw(4) << setfill('0') << attr; - cout << " (" << a.attr2String(attr) << ")" << endl; - } - continue; + if ((f1[strlen(f1) -1] != '/') && (f1[strlen(f1) -1] != '\\')) + strcat(f1,"\\"); + if ((res = a.dircount(f1, tmp)) == rfsv::E_PSI_GEN_NONE) { + for (char *p = f1; *p; p++) + if (*p == '/') + *p = '\\'; + strcpy(psionDir, f1); } - if (!strcmp(argv[0], "gtime") && (argc == 2)) { - PsiTime mtime; - strcpy(f1, psionDir); - strcat(f1, argv[1]); - if ((res = a.fgetmtime(f1, mtime)) != rfsv::E_PSI_GEN_NONE) - cerr << "Error: " << res << endl; - else - cout << mtime << endl; - continue; + else { + cerr << _("Error: ") << res << endl; + cerr << _("Keeping original directory \"") << psionDir << "\"" << endl; } - if (!strcmp(argv[0], "sattr") && (argc == 3)) { - long attr[2]; - int aidx = 0; - char *p = argv[1]; - - strcpy(f1, psionDir); - strcat(f1, argv[2]); + } + continue; + } + if ((!strcmp(argv[0], "get")) && (argc > 1)) { + struct timeval stime; + struct timeval etime; + struct stat stbuf; - attr[0] = attr[1] = 0; - while (*p) { - switch (*p) { - case '+': - aidx = 0; - break; - case '-': - aidx = 1; - break; - case 'r': - attr[aidx] |= rfsv::PSI_A_READ; - attr[aidx] &= ~rfsv::PSI_A_READ; - break; - case 'w': - attr[1 - aidx] |= rfsv::PSI_A_RDONLY; - attr[aidx] &= ~rfsv::PSI_A_RDONLY; - break; - case 'h': - attr[aidx] |= rfsv::PSI_A_HIDDEN; - attr[1 - aidx] &= ~rfsv::PSI_A_HIDDEN; - break; - case 's': - attr[aidx] |= rfsv::PSI_A_SYSTEM; - attr[1 - aidx] &= ~rfsv::PSI_A_SYSTEM; - break; - case 'a': - attr[aidx] |= rfsv::PSI_A_ARCHIVE; - attr[1 - aidx] &= ~rfsv::PSI_A_ARCHIVE; - break; - } - p++; - } - if ((res = a.fsetattr(f1, attr[0], attr[1])) != rfsv::E_PSI_GEN_NONE) - cerr << "Error: " << res << endl; - continue; - } - if (!strcmp(argv[0], "dircnt")) { - u_int32_t cnt; - if ((res = a.dircount(psionDir, cnt)) != rfsv::E_PSI_GEN_NONE) - cerr << "Error: " << res << endl; - else - cout << cnt << " Entries" << endl; - continue; + strcpy(f1, psionDir); + strcat(f1, argv[1]); + strcpy(f2, localDir); + if (argc == 2) + strcat(f2, argv[1]); + else + strcat(f2, argv[2]); + gettimeofday(&stime, 0L); + if ((res = a.copyFromPsion(f1, f2, NULL, cab)) != rfsv::E_PSI_GEN_NONE) { + if (hash) + cout << endl; + continueRunning = 1; + cerr << _("Error: ") << res << endl; + } else { + if (hash) + cout << endl; + gettimeofday(&etime, 0L); + long dsec = etime.tv_sec - stime.tv_sec; + long dhse = (etime.tv_usec / 10000) - + (stime.tv_usec /10000); + if (dhse < 0) { + dsec--; + dhse = 100 + dhse; } - if (!strcmp(argv[0], "devs")) { - u_int32_t devbits; - if ((res = a.devlist(devbits)) == rfsv::E_PSI_GEN_NONE) { - cout << "Drive Type Volname Total Free UniqueID" << endl; - for (int i = 0; i < 26; i++) { - PlpDrive drive; + float dt = dhse; + dt /= 100.0; + dt += dsec; + stat(f2, &stbuf); + float cps = (float)(stbuf.st_size) / dt; + cout << _("Transfer complete, (") << stbuf.st_size + << _(" bytes in ") << dsec << "." + << dhse << _(" secs = ") << cps << " cps)\n"; + } + continue; + } else if ((!strcmp(argv[0], "mget")) && (argc == 2)) { + char *pattern = argv[1]; + PlpDir files; + if ((res = a.dir(psionDir, files)) != rfsv::E_PSI_GEN_NONE) { + cerr << _("Error: ") << res << endl; + continue; + } + for (int i = 0; i < files.size(); i++) { + PlpDirent e = files[i]; + char temp[100]; + long attr = e.getAttr(); - if ((devbits & 1) != 0) { - if (a.devinfo(i, 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() << resetiosflags(ios::left) << dec << setw(9) << - drive.getSize() << setw(9) << drive.getSpace() << " " << setw(8) << setfill('0') << hex << - drive.getUID() << endl; - } - devbits >>= 1; - } - } else - cerr << "Error: " << res << endl; - continue; + if (attr & (rfsv::PSI_A_DIR | rfsv::PSI_A_VOLUME)) + continue; + if (!Wildmat(e.getName(), pattern)) + continue; + do { + cout << _("Get \"") << e.getName() << "\" (y,n): "; + if (prompt) { + cout.flush(); + cin.getline(temp, 100); + } else { + temp[0] = 'y'; + temp[1] = 0; + cout << "y "; + cout.flush(); + } + } while (temp[1] != 0 || (temp[0] != 'y' && temp[0] != 'n')); + if (temp[0] != 'n') { + strcpy(f1, psionDir); + strcat(f1, e.getName()); + strcpy(f2, localDir); + strcat(f2, e.getName()); + if (temp[0] == 'l') { + for (char *p = f2; *p; p++) + *p = tolower(*p); + } + if ((res = a.copyFromPsion(f1, f2, NULL, cab)) != rfsv::E_PSI_GEN_NONE) { + if (hash) + cout << endl; + continueRunning = 1; + cerr << _("Error: ") << res << endl; + break; + } else { + if (hash) + cout << endl; + cout << _("Transfer complete\n"); + } } - if (!strcmp(argv[0], "ls") || !strcmp(argv[0], "dir")) { - PlpDir files; - if ((res = a.dir(psionDir, files)) != rfsv::E_PSI_GEN_NONE) - cerr << "Error: " << res << endl; - else - while (!files.empty()) { - cout << files[0] << endl; - files.pop_front(); - } - continue; - } - if (!strcmp(argv[0], "lcd")) { - if (argc == 1) - resetUnixPwd(); - else { - if (chdir(argv[1]) == 0) { - getcwd(localDir, sizeof(localDir)); - strcat(localDir, "/"); - } else - cerr << "No such directory" << endl - << "Keeping original directory \"" << localDir << "\"" << endl; - } - continue; - } - if (!strcmp(argv[0], "cd")) { - if (argc == 1) { - strcpy(psionDir, defDrive); - strcat(psionDir, DBASEDIR); - } else { - u_int32_t tmp; - if (!strcmp(argv[1], "..")) { - strcpy(f1, psionDir); - char *p = f1 + strlen(f1); - if (p > f1) - p--; - *p = '\0'; - while ((p > f1) && (*p != '/') && (*p != '\\')) - p--; - *(++p) = '\0'; - if (strlen(f1) < 3) { - strcpy(f1, psionDir); - f1[3] = '\0'; - } - } else { - if ((argv[1][0] != '/') && (argv[1][0] != '\\') && - (argv[1][1] != ':')) { - strcpy(f1, psionDir); - strcat(f1, argv[1]); - } else - strcpy(f1, argv[1]); - } - if ((f1[strlen(f1) -1] != '/') && (f1[strlen(f1) -1] != '\\')) - strcat(f1,"\\"); - if ((res = a.dircount(f1, tmp)) == rfsv::E_PSI_GEN_NONE) { - for (char *p = f1; *p; p++) - if (*p == '/') - *p = '\\'; - strcpy(psionDir, f1); - } - else { - cerr << "Error: " << res << endl; - cerr << "Keeping original directory \"" << psionDir << "\"" << endl; - } - } - continue; - } - if ((!strcmp(argv[0], "get")) && (argc > 1)) { - struct timeval stime; - struct timeval etime; - struct stat stbuf; - - strcpy(f1, psionDir); - strcat(f1, argv[1]); - strcpy(f2, localDir); - if (argc == 2) - strcat(f2, argv[1]); - else - strcat(f2, argv[2]); - gettimeofday(&stime, 0L); - if ((res = a.copyFromPsion(f1, f2, NULL, cab)) != rfsv::E_PSI_GEN_NONE) { - if (hash) - cout << endl; - continueRunning = 1; - cerr << "Error: " << res << endl; - } else { - if (hash) - cout << endl; - gettimeofday(&etime, 0L); - long dsec = etime.tv_sec - stime.tv_sec; - long dhse = (etime.tv_usec / 10000) - - (stime.tv_usec /10000); - if (dhse < 0) { - dsec--; - dhse = 100 + dhse; - } - float dt = dhse; - dt /= 100.0; - dt += dsec; - stat(f2, &stbuf); - float cps = (float)(stbuf.st_size) / dt; - cout << "Transfer complete, (" << stbuf.st_size - << " bytes in " << dsec << "." - << dhse << " secs = " << cps << " cps)\n"; - } - continue; - } else if ((!strcmp(argv[0], "mget")) && (argc == 2)) { - char *pattern = argv[1]; - PlpDir files; - if ((res = a.dir(psionDir, files)) != rfsv::E_PSI_GEN_NONE) { - cerr << "Error: " << res << endl; - continue; - } - for (int i = 0; i < files.size(); i++) { - PlpDirent e = files[i]; - char temp[100]; - long attr = e.getAttr(); + } + continue; + } + if (!strcmp(argv[0], "put") && (argc >= 2)) { + struct timeval stime; + struct timeval etime; + struct stat stbuf; - if (attr & (rfsv::PSI_A_DIR | rfsv::PSI_A_VOLUME)) - continue; - if (!Wildmat(e.getName(), pattern)) - continue; - do { - cout << "Get \"" << e.getName() << "\" (y,n): "; - if (prompt) { - cout.flush(); - cin.getline(temp, 100); - } else { - temp[0] = 'y'; - temp[1] = 0; - cout << "y "; - cout.flush(); - } - } while (temp[1] != 0 || (temp[0] != 'y' && temp[0] != 'n')); - if (temp[0] != 'n') { - strcpy(f1, psionDir); - strcat(f1, e.getName()); - strcpy(f2, localDir); - strcat(f2, e.getName()); - if (temp[0] == 'l') { - for (char *p = f2; *p; p++) - *p = tolower(*p); - } - if ((res = a.copyFromPsion(f1, f2, NULL, cab)) != rfsv::E_PSI_GEN_NONE) { - if (hash) - cout << endl; - continueRunning = 1; - cerr << "Error: " << res << endl; - break; - } else { - if (hash) - cout << endl; - cout << "Transfer complete\n"; - } - } - } - continue; + strcpy(f1, localDir); + strcat(f1, argv[1]); + strcpy(f2, psionDir); + if (argc == 2) + strcat(f2, argv[1]); + else + strcat(f2, argv[2]); + gettimeofday(&stime, 0L); + if ((res = a.copyToPsion(f1, f2, NULL, cab)) != rfsv::E_PSI_GEN_NONE) { + if (hash) + cout << endl; + continueRunning = 1; + cerr << _("Error: ") << res << endl; + } else { + if (hash) + cout << endl; + gettimeofday(&etime, 0L); + long dsec = etime.tv_sec - stime.tv_sec; + long dhse = (etime.tv_usec / 10000) - + (stime.tv_usec /10000); + if (dhse < 0) { + dsec--; + dhse = 100 + dhse; } - if (!strcmp(argv[0], "put") && (argc >= 2)) { - struct timeval stime; - struct timeval etime; - struct stat stbuf; + float dt = dhse; + dt /= 100.0; + dt += dsec; + stat(f1, &stbuf); + float cps = (float)(stbuf.st_size) / dt; + cout << _("Transfer complete, (") << stbuf.st_size + << _(" bytes in ") << dsec << "." + << dhse << _(" secs = ") << cps << " cps)\n"; + } + continue; + } + if ((!strcmp(argv[0], "mput")) && (argc == 2)) { + char *pattern = argv[1]; + DIR *d = opendir(localDir); + if (d) { + struct dirent *de; + do { + de = readdir(d); + if (de) { + char temp[100]; + struct stat st; + if (!Wildmat(de->d_name, pattern)) + continue; strcpy(f1, localDir); - strcat(f1, argv[1]); - strcpy(f2, psionDir); - if (argc == 2) - strcat(f2, argv[1]); - else - strcat(f2, argv[2]); - gettimeofday(&stime, 0L); - if ((res = a.copyToPsion(f1, f2, NULL, cab)) != rfsv::E_PSI_GEN_NONE) { + strcat(f1, de->d_name); + if (stat(f1, &st) != 0) + continue; + if (!S_ISREG(st.st_mode)) + continue; + do { + cout << _("Put \"") << de->d_name << "\" y,n: "; + if (prompt) { + cout.flush(); + cin.getline(temp, 100); + } else { + temp[0] = 'y'; + temp[1] = 0; + cout << "y "; + cout.flush(); + } + } while (temp[1] != 0 || (temp[0] != 'y' && temp[0] != 'n')); + if (temp[0] == 'y') { + strcpy(f2, psionDir); + strcat(f2, de->d_name); + if ((res = a.copyToPsion(f1, f2, NULL, cab)) != rfsv::E_PSI_GEN_NONE) { if (hash) - cout << endl; + cout << endl; continueRunning = 1; - cerr << "Error: " << res << endl; - } else { + cerr << _("Error: ") << res << endl; + break; + } else { if (hash) - cout << endl; - gettimeofday(&etime, 0L); - long dsec = etime.tv_sec - stime.tv_sec; - long dhse = (etime.tv_usec / 10000) - - (stime.tv_usec /10000); - if (dhse < 0) { - dsec--; - dhse = 100 + dhse; - } - float dt = dhse; - dt /= 100.0; - dt += dsec; - stat(f1, &stbuf); - float cps = (float)(stbuf.st_size) / dt; - cout << "Transfer complete, (" << stbuf.st_size - << " bytes in " << dsec << "." - << dhse << " secs = " << cps << " cps)\n"; + cout << endl; + cout << _("Transfer complete\n"); + } } - continue; - } - if ((!strcmp(argv[0], "mput")) && (argc == 2)) { - char *pattern = argv[1]; - DIR *d = opendir(localDir); - if (d) { - struct dirent *de; - do { - de = readdir(d); - if (de) { - char temp[100]; - struct stat st; - - if (!Wildmat(de->d_name, pattern)) - continue; - strcpy(f1, localDir); - strcat(f1, de->d_name); - if (stat(f1, &st) != 0) - continue; - if (!S_ISREG(st.st_mode)) - continue; - do { - cout << "Put \"" << de->d_name << "\" y,n: "; - if (prompt) { - cout.flush(); - cin.getline(temp, 100); - } else { - temp[0] = 'y'; - temp[1] = 0; - cout << "y "; - cout.flush(); - } - } while (temp[1] != 0 || (temp[0] != 'y' && temp[0] != 'n')); - if (temp[0] == 'y') { - strcpy(f2, psionDir); - strcat(f2, de->d_name); - if ((res = a.copyToPsion(f1, f2, NULL, cab)) != rfsv::E_PSI_GEN_NONE) { - if (hash) - cout << endl; - continueRunning = 1; - cerr << "Error: " << res << endl; - break; - } else { - if (hash) - cout << endl; - cout << "Transfer complete\n"; - } - } - } - } while (de); - closedir(d); - } else - cerr << "Error in directory name \"" << localDir << "\"\n"; - continue; - } - if ((!strcmp(argv[0], "del") || - !strcmp(argv[0], "rm")) && (argc == 2)) { - strcpy(f1, psionDir); - strcat(f1, argv[1]); - if ((res = a.remove(f1)) != rfsv::E_PSI_GEN_NONE) - cerr << "Error: " << res << endl; - continue; - } - if (!strcmp(argv[0], "mkdir") && (argc == 2)) { - strcpy(f1, psionDir); - strcat(f1, argv[1]); - if ((res = a.mkdir(f1)) != rfsv::E_PSI_GEN_NONE) - cerr << "Error: " << res << endl; - continue; - } - if (!strcmp(argv[0], "rmdir") && (argc == 2)) { - strcpy(f1, psionDir); - strcat(f1, argv[1]); - if ((res = a.rmdir(f1)) != rfsv::E_PSI_GEN_NONE) - cerr << "Error: " << res << endl; - continue; - } - if (argv[0][0] == '!') { - char cmd[1024]; - strcpy(cmd, &argv[0][1]); - for (int i=1; i<argc; i++) { - strcat(cmd, " "); - strcat(cmd, argv[i]); - } - if (strlen(cmd)) - system(cmd); - else { - char *sh; - cout << "Starting subshell ...\n"; - sh = getenv("SHELL"); - if (!sh) - sh = "/bin/sh"; - system(sh); - } - continue; - } - // RPCS commands + } + } while (de); + closedir(d); + } else + cerr << _("Error in directory name \"") << localDir << "\"\n"; + continue; + } + if ((!strcmp(argv[0], "del") || + !strcmp(argv[0], "rm")) && (argc == 2)) { + strcpy(f1, psionDir); + strcat(f1, argv[1]); + if ((res = a.remove(f1)) != rfsv::E_PSI_GEN_NONE) + cerr << _("Error: ") << res << endl; + continue; + } + if (!strcmp(argv[0], "mkdir") && (argc == 2)) { + strcpy(f1, psionDir); + strcat(f1, argv[1]); + if ((res = a.mkdir(f1)) != rfsv::E_PSI_GEN_NONE) + cerr << _("Error: ") << res << endl; + continue; + } + if (!strcmp(argv[0], "rmdir") && (argc == 2)) { + strcpy(f1, psionDir); + strcat(f1, argv[1]); + if ((res = a.rmdir(f1)) != rfsv::E_PSI_GEN_NONE) + cerr << _("Error: ") << res << endl; + continue; + } + if (argv[0][0] == '!') { + char cmd[1024]; + strcpy(cmd, &argv[0][1]); + for (int i=1; i<argc; i++) { + strcat(cmd, " "); + strcat(cmd, argv[i]); + } + if (strlen(cmd)) + system(cmd); + else { + char *sh; + cout << _("Starting subshell ...\n"); + sh = getenv("SHELL"); + if (!sh) + sh = "/bin/sh"; + system(sh); + } + continue; + } + // RPCS commands #ifdef EXPERIMENTAL - if (!strcmp(argv[0], "x")) { - r.regOpenIter(); - continue; - } - if (!strcmp(argv[0], "y")) { - r.configRead(); - continue; - } + if (!strcmp(argv[0], "x")) { + r.regOpenIter(); + continue; + } + if (!strcmp(argv[0], "y")) { + r.configRead(); + continue; + } #endif - if (!strcmp(argv[0], "run") && (argc >= 2)) { - char argbuf[1024]; - char cmdbuf[1024]; - - argbuf[0] = 0; - for (int i = 2; i < argc; i++) { - if (i > 2) { - strcat(argbuf, " "); - strcat(argbuf, argv[i]); - } else - strcpy(argbuf, argv[i]); - } - if (argv[1][1] != ':') { - strcpy(cmdbuf, psionDir); - strcat(cmdbuf, argv[1]); - } else - strcpy(cmdbuf, argv[1]); - r.execProgram(cmdbuf, argbuf); - continue; - } - if (!strcmp(argv[0], "ownerinfo")) { - bufferArray b; - if ((res = r.getOwnerInfo(b)) != rfsv::E_PSI_GEN_NONE) { - cerr << "Error: " << res << endl; - continue; - } - while (!b.empty()) - cout << " " << b.pop().getString() << endl; - continue; - } - if (!strcmp(argv[0], "machinfo")) { - rpcs::machineInfo mi; - if ((res = r.getMachineInfo(mi)) != rfsv::E_PSI_GEN_NONE) { - cerr << "Error: " << res << endl; - continue; - } + if (!strcmp(argv[0], "run") && (argc >= 2)) { + char argbuf[1024]; + char cmdbuf[1024]; - cout << "General:" << endl; - cout << " Machine Type: " << mi.machineType << endl; - cout << " Machine Name: " << mi.machineName << endl; - cout << " Machine UID: " << hex << mi.machineUID << dec << endl; - cout << " UI Language: " << mi.uiLanguage << endl; - cout << "ROM:" << endl; - cout << " Version: " << mi.romMajor << "." << setw(2) << setfill('0') << - mi.romMinor << "(" << mi.romBuild << ")" << endl; - cout << " Size: " << mi.romSize / 1024 << "k" << endl; - cout << " Programmable: " << - (mi.romProgrammable ? "yes" : "no") << endl; - cout << "RAM:" << endl; - cout << " Size: " << mi.ramSize / 1024 << "k" << endl; - cout << " Free: " << mi.ramFree / 1024 << "k" << endl; - cout << " Free max: " << mi.ramMaxFree / 1024 << "k" << endl; - cout << "RAM disk size: " << mi.ramDiskSize / 1024 << "k" << endl; - cout << "Registry size: " << mi.registrySize << endl; - cout << "Display size: " << mi.displayWidth << "x" << - mi.displayHeight << endl; - cout << "Time:" << endl; - PsiTime pt(&mi.time, &mi.tz); - cout << " Current time: " << pt << endl; - cout << " UTC offset: " << mi.tz.utc_offset << " seconds" << endl; - cout << " DST: " << - (mi.tz.dst_zones & PsiTime::PSI_TZ_HOME ? "yes" : "no") << endl; - cout << " Timezone: " << mi.tz.home_zone << endl; - cout << " Country Code: " << mi.countryCode << endl; - cout << "Main battery:" << endl; - pt.setPsiTime(&mi.mainBatteryInsertionTime); - cout << " Changed at: " << pt << endl; - cout << " Used for: " << mi.mainBatteryUsedTime << endl; - cout << " Status: " << mi.mainBatteryStatus << endl; - cout << " Current: " << mi.mainBatteryCurrent << " mA" << endl; - cout << " UsedPower: " << mi.mainBatteryUsedPower << " mAs" << endl; - cout << " Voltage: " << mi.mainBatteryVoltage << " mV" << endl; - cout << " Max. voltage: " << mi.mainBatteryMaxVoltage << " mV" << endl; - cout << "Backup battery:" << endl; - cout << " Status: " << mi.backupBatteryStatus << endl; - cout << " Voltage: " << mi.backupBatteryVoltage << " mV" << endl; - cout << " Max. voltage: " << mi.backupBatteryMaxVoltage << " mV" << endl; - cout << " Used for: " << mi.backupBatteryUsedTime << endl; - continue; - } - if (!strcmp(argv[0], "runrestore") && (argc == 2)) { - ifstream ip(argv[1]); - char cmd[512]; - char arg[512]; + argbuf[0] = 0; + for (int i = 2; i < argc; i++) { + if (i > 2) { + strcat(argbuf, " "); + strcat(argbuf, argv[i]); + } else + strcpy(argbuf, argv[i]); + } + if (argv[1][1] != ':') { + strcpy(cmdbuf, psionDir); + strcat(cmdbuf, argv[1]); + } else + strcpy(cmdbuf, argv[1]); + r.execProgram(cmdbuf, argbuf); + continue; + } + if (!strcmp(argv[0], "ownerinfo")) { + bufferArray b; + if ((res = r.getOwnerInfo(b)) != rfsv::E_PSI_GEN_NONE) { + cerr << _("Error: ") << res << endl; + continue; + } + while (!b.empty()) + cout << " " << b.pop().getString() << endl; + continue; + } + if (!strcmp(argv[0], "machinfo")) { + rpcs::machineInfo mi; + if ((res = r.getMachineInfo(mi)) != rfsv::E_PSI_GEN_NONE) { + cerr << _("Error: ") << res << endl; + continue; + } - if (!ip) { - cerr << "Could not read processlist " << argv[1] << endl; - continue; - } - ip >> cmd >> arg; - - if (strcmp(cmd, "#plpftp") || strcmp(arg, "processlist")) { - ip.close(); - cerr << "Error: " << argv[1] << - " is not a process list saved with killsave" << endl; - continue; - } - while (!ip.eof()) { - ip >> cmd >> arg; - ip.get(&arg[strlen(arg)], sizeof(arg) - strlen(arg), '\n'); - // cout << "cmd=\"" << cmd << "\" arg=\"" << arg << "\"" << endl; - if (strlen(cmd) > 0) { - // Workaround for broken programs like Backlite. These do not store - // the full program path. In that case we try running the arg1 which - // results in starting the program via recog. facility. - if ((strlen(arg) > 2) && (arg[1] == ':') && (arg[0] >= 'A') && - (arg[0] <= 'Z')) - res = r.execProgram(arg, ""); - else - res = r.execProgram(cmd, arg); - if (res != rfsv::E_PSI_GEN_NONE) { - // If we got an error here, that happened probably because - // we have no path at all (e.g. Macro5) and the program is not - // registered in the Psion's path properly. Now try the ususal - // \System\Apps\<AppName>\<AppName>.app on all drives. - if (strchr(cmd, '\\') == NULL) { - u_int32_t devbits; - char tmp[512]; - if ((res = a.devlist(devbits)) == rfsv::E_PSI_GEN_NONE) { - int i; - for (i = 0; i < 26; i++) { - if (devbits & 1) { - sprintf(tmp, - "%c:\\System\\Apps\\%s\\%s.app", - 'A' + i, cmd, cmd); - res = r.execProgram(tmp, ""); - } - if (res == rfsv::E_PSI_GEN_NONE) - break; - } - } - } - } - if (res != rfsv::E_PSI_GEN_NONE) { - cerr << "Could not start " << cmd << " " << arg << endl; - cerr << "Error: " << res << endl; - } + cout << _("General:") << endl; + cout << _(" Machine Type: ") << mi.machineType << endl; + cout << _(" Machine Name: ") << mi.machineName << endl; + cout << _(" Machine UID: ") << hex << mi.machineUID << dec << endl; + cout << _(" UI Language: ") << mi.uiLanguage << endl; + cout << _("ROM:") << endl; + cout << _(" Version: ") << mi.romMajor << "." << setw(2) << setfill('0') << + mi.romMinor << "(" << mi.romBuild << ")" << endl; + cout << _(" Size: ") << mi.romSize / 1024 << "k" << endl; + cout << _(" Programmable: ") << + (mi.romProgrammable ? _("yes") : _("no")) << endl; + cout << _("RAM:") << endl; + cout << _(" Size: ") << mi.ramSize / 1024 << "k" << endl; + cout << _(" Free: ") << mi.ramFree / 1024 << "k" << endl; + cout << _(" Free max: ") << mi.ramMaxFree / 1024 << "k" << endl; + cout << _("RAM disk size: ") << mi.ramDiskSize / 1024 << "k" << endl; + cout << _("Registry size: ") << mi.registrySize << endl; + cout << _("Display size: ") << mi.displayWidth << "x" << + mi.displayHeight << endl; + cout << _("Time:") << endl; + PsiTime pt(&mi.time, &mi.tz); + cout << _(" Current time: ") << pt << endl; + cout << _(" UTC offset: ") << mi.tz.utc_offset << _(" seconds") << endl; + cout << _(" DST: ") << + (mi.tz.dst_zones & PsiTime::PSI_TZ_HOME ? _("yes") : _("no")) << endl; + cout << _(" Timezone: ") << mi.tz.home_zone << endl; + cout << _(" Country Code: ") << mi.countryCode << endl; + cout << _("Main battery:") << endl; + pt.setPsiTime(&mi.mainBatteryInsertionTime); + cout << _(" Changed at: ") << pt << endl; + cout << _(" Used for: ") << mi.mainBatteryUsedTime << endl; + cout << _(" Status: ") << mi.mainBatteryStatus << endl; + cout << _(" Current: ") << mi.mainBatteryCurrent << " mA" << endl; + cout << _(" UsedPower: ") << mi.mainBatteryUsedPower << " mAs" << endl; + cout << _(" Voltage: ") << mi.mainBatteryVoltage << " mV" << endl; + cout << _(" Max. voltage: ") << mi.mainBatteryMaxVoltage << " mV" << endl; + cout << _("Backup battery:") << endl; + cout << _(" Status: ") << mi.backupBatteryStatus << endl; + cout << _(" Voltage: ") << mi.backupBatteryVoltage << " mV" << endl; + cout << _(" Max. voltage: ") << mi.backupBatteryMaxVoltage << " mV" << endl; + cout << _(" Used for: ") << mi.backupBatteryUsedTime << endl; + continue; + } + if (!strcmp(argv[0], "runrestore") && (argc == 2)) { + ifstream ip(argv[1]); + char cmd[512]; + char arg[512]; + + if (!ip) { + cerr << _("Could not read processlist ") << argv[1] << endl; + continue; + } + ip >> cmd >> arg; + + if (strcmp(cmd, "#plpftp") || strcmp(arg, "processlist")) { + ip.close(); + cerr << _("Error: ") << argv[1] << + _(" is not a process list saved with killsave") << endl; + continue; + } + while (!ip.eof()) { + ip >> cmd >> arg; + ip.get(&arg[strlen(arg)], sizeof(arg) - strlen(arg), '\n'); + // cout << "cmd=\"" << cmd << "\" arg=\"" << arg << "\"" << endl; + if (strlen(cmd) > 0) { + // Workaround for broken programs like Backlite. These do not store + // the full program path. In that case we try running the arg1 which + // results in starting the program via recog. facility. + if ((strlen(arg) > 2) && (arg[1] == ':') && (arg[0] >= 'A') && + (arg[0] <= 'Z')) + res = r.execProgram(arg, ""); + else + res = r.execProgram(cmd, arg); + if (res != rfsv::E_PSI_GEN_NONE) { + // If we got an error here, that happened probably because + // we have no path at all (e.g. Macro5) and the program is not + // registered in the Psion's path properly. Now try the ususal + // \System\Apps\<AppName>\<AppName>.app on all drives. + if (strchr(cmd, '\\') == NULL) { + u_int32_t devbits; + char tmp[512]; + if ((res = a.devlist(devbits)) == rfsv::E_PSI_GEN_NONE) { + int i; + for (i = 0; i < 26; i++) { + if (devbits & 1) { + sprintf(tmp, + "%c:\\System\\Apps\\%s\\%s.app", + 'A' + i, cmd, cmd); + res = r.execProgram(tmp, ""); + } + if (res == rfsv::E_PSI_GEN_NONE) + break; } + } } - ip.close(); - continue; + } + if (res != rfsv::E_PSI_GEN_NONE) { + cerr << _("Could not start ") << cmd << " " << arg << endl; + cerr << _("Error: ") << res << endl; + } } - if (!strcmp(argv[0], "killsave") && (argc == 2)) { - bufferArray tmp; - if ((res = r.queryDrive('C', tmp)) != rfsv::E_PSI_GEN_NONE) - cerr << "Error: " << res << endl; - else { - ofstream op(argv[1]); - if (!op) { - cerr << "Could not write processlist " << argv[1] << endl; - 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); - } - op.close(); - } - continue; + } + ip.close(); + continue; + } + if (!strcmp(argv[0], "killsave") && (argc == 2)) { + bufferArray tmp; + if ((res = r.queryDrive('C', tmp)) != rfsv::E_PSI_GEN_NONE) + cerr << _("Error: ") << res << endl; + else { + ofstream op(argv[1]); + if (!op) { + cerr << _("Could not write processlist ") << argv[1] << endl; + continue; } - if (!strcmp(argv[0], "kill") && (argc >= 2)) { - bufferArray tmp, tmp2; - bool anykilled = false; - if ((res = r.queryDrive('C', 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); - anykilled = true; - } - } - if (kpid == -1) - break; - } - if (!anykilled) - cerr << "no such process" << endl; + 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); + } + op.close(); + } + continue; + } + if (!strcmp(argv[0], "kill") && (argc >= 2)) { + bufferArray tmp, tmp2; + bool anykilled = false; + if ((res = r.queryDrive('C', 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); + anykilled = true; } - continue; + } + if (kpid == -1) + break; } - if (!strcmp(argv[0], "ps")) { - bufferArray tmp; - if ((res = r.queryDrive('C', 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(); + if (!anykilled) + cerr << _("no such process") << endl; + } + continue; + } + if (!strcmp(argv[0], "ps")) { + bufferArray tmp; + if ((res = r.queryDrive('C', 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); - } - } - continue; + printf("%5d %-12s %s\n", pid, proc, arg); } - if (strcmp(argv[0], "bye") && strcmp(argv[0], "quit")) - cerr << "syntax error. Try \"help\"" << endl; - } while (strcmp(argv[0], "bye") && strcmp(argv[0], "quit") && !once && - continueRunning); - return a.getStatus(); + } + continue; + } + if (strcmp(argv[0], "bye") && strcmp(argv[0], "quit")) + cerr << _("syntax error. Try \"help\"") << endl; + } while (strcmp(argv[0], "bye") && strcmp(argv[0], "quit") && !once && + continueRunning); + return a.getStatus(); } #if HAVE_LIBREADLINE static char *all_commands[] = { - "pwd", "ren", "touch", "gtime", "test", "gattr", "sattr", "devs", - "dir", "ls", "dircnt", "cd", "lcd", "get", "put", "mget", "mput", - "del", "rm", "mkdir", "rmdir", "prompt", "bye", "cp", "volname", - "ps", "kill", "killsave", "runrestore", "run", "machinfo", - "ownerinfo", NULL + "pwd", "ren", "touch", "gtime", "test", "gattr", "sattr", "devs", + "dir", "ls", "dircnt", "cd", "lcd", "get", "put", "mget", "mput", + "del", "rm", "mkdir", "rmdir", "prompt", "bye", "cp", "volname", + "ps", "kill", "killsave", "runrestore", "run", "machinfo", + "ownerinfo", NULL }; static char *localfile_commands[] = { - "lcd ", "put ", "mput ", "killsave ", "runrestore ", NULL + "lcd ", "put ", "mput ", "killsave ", "runrestore ", NULL }; static char *remote_dir_commands[] = { - "cd ", "rmdir ", NULL + "cd ", "rmdir ", NULL }; static PlpDir comp_files; @@ -993,102 +993,102 @@ static char cplPath[1024]; static char* filename_generator(char *text, int state) { - static int len; - string tmp; + static int len; + string tmp; - if (!state) { - Enum<rfsv::errs> res; - len = strlen(text); - tmp = psionDir; - tmp += cplPath; - tmp = rfsv::convertSlash(tmp); - if ((res = comp_a->dir(tmp.c_str(), comp_files)) != rfsv::E_PSI_GEN_NONE) { - cerr << "Error: " << res << endl; - return NULL; - } + if (!state) { + Enum<rfsv::errs> res; + len = strlen(text); + tmp = psionDir; + tmp += cplPath; + tmp = rfsv::convertSlash(tmp); + if ((res = comp_a->dir(tmp.c_str(), comp_files)) != rfsv::E_PSI_GEN_NONE) { + cerr << _("Error: ") << res << endl; + return NULL; } - while (!comp_files.empty()) { - PlpDirent e = comp_files.front(); - long attr = e.getAttr(); + } + while (!comp_files.empty()) { + PlpDirent e = comp_files.front(); + long attr = e.getAttr(); - comp_files.pop_front(); - if ((attr & maskAttr) == 0) - continue; - tmp = cplPath; - tmp += e.getName(); - if (!(strncmp(tmp.c_str(), text, len))) { - if (attr & rfsv::PSI_A_DIR) { - rl_completion_append_character = '\0'; - tmp += '/'; - } - return (strdup(tmp.c_str())); - } + comp_files.pop_front(); + if ((attr & maskAttr) == 0) + continue; + tmp = cplPath; + tmp += e.getName(); + if (!(strncmp(tmp.c_str(), text, len))) { + if (attr & rfsv::PSI_A_DIR) { + rl_completion_append_character = '\0'; + tmp += '/'; + } + return (strdup(tmp.c_str())); } - return NULL; + } + return NULL; } static char * command_generator(char *text, int state) { - static int idx, len; - char *name; + static int idx, len; + char *name; - if (!state) { - idx = 0; - len = strlen(text); - } - while ((name = all_commands[idx])) { - idx++; - if (!strncmp(name, text, len)) - return (strdup(name)); - } - return NULL; + if (!state) { + idx = 0; + len = strlen(text); + } + while ((name = all_commands[idx])) { + idx++; + if (!strncmp(name, text, len)) + return (strdup(name)); + } + return NULL; } -static int +static int null_completion() { - return 0; + return 0; } static char ** do_completion(char *text, int start, int end) { - char **matches = NULL; + char **matches = NULL; - rl_completion_entry_function = (Function *)null_completion; - rl_completion_append_character = ' '; - if (start == 0) - matches = completion_matches(text, cmdgen_ptr); - else { - int idx = 0; - char *name; - char *p; + rl_completion_entry_function = (Function *)null_completion; + rl_completion_append_character = ' '; + if (start == 0) + matches = completion_matches(text, cmdgen_ptr); + else { + int idx = 0; + char *name; + char *p; - rl_filename_quoting_desired = 1; - while ((name = localfile_commands[idx])) { - idx++; - if (!strncmp(name, rl_line_buffer, strlen(name))) { - rl_completion_entry_function = NULL; - return NULL; - } - } - maskAttr = 0xffff; - idx = 0; - strcpy(cplPath, text); - p = strrchr(cplPath, '/'); - if (p) - *(++p) = '\0'; - else - cplPath[0] = '\0'; - while ((name = remote_dir_commands[idx])) { - idx++; - if (!strncmp(name, rl_line_buffer, strlen(name))) - maskAttr = rfsv::PSI_A_DIR; - } - - matches = completion_matches(text, fnmgen_ptr); + rl_filename_quoting_desired = 1; + while ((name = localfile_commands[idx])) { + idx++; + if (!strncmp(name, rl_line_buffer, strlen(name))) { + rl_completion_entry_function = NULL; + return NULL; + } } - return matches; + maskAttr = 0xffff; + idx = 0; + strcpy(cplPath, text); + p = strrchr(cplPath, '/'); + if (p) + *(++p) = '\0'; + else + cplPath[0] = '\0'; + while ((name = remote_dir_commands[idx])) { + idx++; + if (!strncmp(name, rl_line_buffer, strlen(name))) + maskAttr = rfsv::PSI_A_DIR; + } + + matches = completion_matches(text, fnmgen_ptr); + } + return matches; } #endif @@ -1096,74 +1096,74 @@ void ftp:: initReadline(void) { #if HAVE_LIBREADLINE - rl_readline_name = "plpftp"; - rl_completion_entry_function = (Function *)null_completion; - rl_attempted_completion_function = (CPPFunction *)do_completion; - rlcrap_setpointers(command_generator, filename_generator); + rl_readline_name = "plpftp"; + rl_completion_entry_function = (Function *)null_completion; + rl_attempted_completion_function = (CPPFunction *)do_completion; + rlcrap_setpointers(command_generator, filename_generator); #endif } void ftp:: getCommand(int &argc, char **argv) { - int ws, quote; + int ws, quote; - static char buf[1024]; + static char buf[1024]; - buf[0] = 0; argc = 0; - while (!strlen(buf) && continueRunning) { - signal(SIGINT, sigint_handler2); + buf[0] = 0; argc = 0; + while (!strlen(buf) && continueRunning) { + signal(SIGINT, sigint_handler2); #if HAVE_LIBREADLINE - char *bp = readline("> "); - if (!bp) { - strcpy(buf, "bye"); - cout << buf << endl; - } else { - strcpy(buf, bp); + char *bp = readline("> "); + if (!bp) { + strcpy(buf, "bye"); + cout << buf << endl; + } else { + strcpy(buf, bp); #if HAVE_LIBHISTORY - add_history(buf); + add_history(buf); #endif - free(bp); - } + free(bp); + } #else - cout << "> "; - cout.flush(); - cin.getline(buf, 1023); - if (cin.eof()) { - strcpy(buf, "bye"); - cout << buf << endl; - } -#endif - signal(SIGINT, sigint_handler); + cout << "> "; + cout.flush(); + cin.getline(buf, 1023); + if (cin.eof()) { + strcpy(buf, "bye"); + cout << buf << endl; } - ws = 1; quote = 0; - for (char *p = buf; *p; p++) - switch (*p) { - case ' ': - case '\t': - if (!quote) { - ws = 1; - *p = 0; - } - break; - case '"': - quote = 1 - quote; - if (!quote) - *p = 0; - break; - default: - if (ws) { - argv[argc++] = p; - } - ws = 0; +#endif + signal(SIGINT, sigint_handler); + } + ws = 1; quote = 0; + for (char *p = buf; *p; p++) + switch (*p) { + case ' ': + case '\t': + if (!quote) { + ws = 1; + *p = 0; } + break; + case '"': + quote = 1 - quote; + if (!quote) + *p = 0; + break; + default: + if (ws) { + argv[argc++] = p; + } + ws = 0; + } } - // Unix utilities +// Unix utilities bool ftp:: unixDirExists(const char *dir) { - return false; + return false; } void ftp:: @@ -1174,40 +1174,46 @@ getUnixDir(bufferArray & files) void ftp:: cd(const char *source, const char *cdto, char *dest) { - if (cdto[0] == '/' || cdto[0] == '\\' || cdto[1] == ':') { - strcpy(dest, cdto); - char cc = dest[strlen(dest) - 1]; - if (cc != '/' && cc != '\\') - strcat(dest, "/"); - } else { - char start[200]; - strcpy(start, source); + if (cdto[0] == '/' || cdto[0] == '\\' || cdto[1] == ':') { + strcpy(dest, cdto); + char cc = dest[strlen(dest) - 1]; + if (cc != '/' && cc != '\\') + strcat(dest, "/"); + } else { + char start[200]; + strcpy(start, source); - while (*cdto) { - char bit[200]; - int j; - for (j = 0; cdto[j] && cdto[j] != '/' && cdto[j] != '\\'; j++) - bit[j] = cdto[j]; - bit[j] = 0; - cdto += j; - if (*cdto) - cdto++; + while (*cdto) { + char bit[200]; + int j; + for (j = 0; cdto[j] && cdto[j] != '/' && cdto[j] != '\\'; j++) + bit[j] = cdto[j]; + bit[j] = 0; + cdto += j; + if (*cdto) + cdto++; - if (!strcmp(bit, "..")) { - strcpy(dest, start); - int i; - for (i = strlen(dest) - 2; i >= 0; i--) { - if (dest[i] == '/' || dest[i] == '\\') { - dest[i + 1] = 0; - break; - } - } - } else { - strcpy(dest, start); - strcat(dest, bit); - strcat(dest, "/"); - } - strcpy(start, dest); + if (!strcmp(bit, "..")) { + strcpy(dest, start); + int i; + for (i = strlen(dest) - 2; i >= 0; i--) { + if (dest[i] == '/' || dest[i] == '\\') { + dest[i + 1] = 0; + break; + } } + } else { + strcpy(dest, start); + strcat(dest, bit); + strcat(dest, "/"); + } + strcpy(start, dest); } + } } + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ diff --git a/plpftp/main.cc b/plpftp/main.cc index 8c23311..2c58e83 100644 --- a/plpftp/main.cc +++ b/plpftp/main.cc @@ -1,27 +1,26 @@ -// $Id$ -// -// PLP - An implementation of the PSION link protocol -// -// Copyright (C) 1999 Philip Proudman -// Modifications for plptools: -// Copyright (C) 1999 Fritz Elfert <felfert@to.com> -// -// 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 -// -// e-mail philip.proudman@btinternet.com - +/*-*-c++-*- + * $Id$ + * + * This file is part of plptools. + * + * Copyright (C) 1999 Philip Proudman <philip.proudman@btinternet.com> + * Copyright (C) 1999-2001 Fritz Elfert <felfert@to.com> + * + * 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 + * + */ #ifdef HAVE_CONFIG_H #include <config.h> #endif @@ -42,71 +41,83 @@ void usage() { - cout << "Version " << VERSION << endl; - cout << "Usage : plpftp -p <port> [ftpcommand parameters]\n"; + cout << _("Version ") << VERSION << endl; + cout << _("Usage : plpftp -p <port> [ftpcommand parameters]") << endl; } void ftpHeader() { - cout << "PLPFTP Version " << VERSION; - cout << " Copyright (C) 1999 Philip Proudman" << endl; - cout << " Additions Copyright (C) 1999 Fritz Elfert <felfert@to.com>" << endl; - cout << " & (C) 1999 Matt Gumbley <matt@gumbley.demon.co.uk>" << endl; - cout << "PLP comes with ABSOLUTELY NO WARRANTY;" << endl; - cout << "This is free software, and you are welcome to redistribute it" << endl; - cout << "under GPL conditions; see the COPYING file in the distribution." << endl; - cout << endl; - cout << "FTP like interface started. Type \"?\" for help." << endl; + cout << _("PLPFTP Version ") << VERSION; + cout << _(" Copyright (C) 1999 Philip Proudman") << endl; + cout << _(" Additions Copyright (C) 1999-2001 Fritz Elfert <felfert@to.com>") << endl; + cout << _(" & (C) 1999 Matt Gumbley <matt@gumbley.demon.co.uk>") << endl; + cout << _("PLPFTP comes with ABSOLUTELY NO WARRANTY.") << endl; + cout << _("This is free software, and you are welcome to redistribute it") << endl; + cout << _("under GPL conditions; see the COPYING file in the distribution.") << endl; + cout << endl; + cout << _("FTP like interface started. Type \"?\" for help.") << endl; } int main(int argc, char **argv) { - ppsocket *skt; - ppsocket *skt2; - rfsv *a; - rpcs *r; - ftp f; - int status = 0; - int sockNum = DPORT; + ppsocket *skt; + ppsocket *skt2; + rfsv *a; + rpcs *r; + ftp f; + int status = 0; + int sockNum = DPORT; - struct servent *se = getservbyname("psion", "tcp"); - endservent(); - if (se != 0L) - sockNum = ntohs(se->s_port); + bind_textdomain_codeset(PACKAGE, "latin1"); + textdomain(PACKAGE); + struct servent *se = getservbyname("psion", "tcp"); + endservent(); + if (se != 0L) + sockNum = ntohs(se->s_port); - // Command line parameter processing - if ((argc > 2) && !strcmp(argv[1], "-p")) { - sockNum = atoi(argv[2]); - argc -= 2; - for (int i = 1; i < argc; i++) - argv[i] = argv[i + 2]; - } + // Command line parameter processing + if ((argc > 2) && !strcmp(argv[1], "-p")) { + sockNum = atoi(argv[2]); + argc -= 2; + for (int i = 1; i < argc; i++) + argv[i] = argv[i + 2]; + } - if (argc < 2) - ftpHeader(); - skt = new ppsocket(); - if (!skt->connect(NULL, sockNum)) { - cout << "plpftp: could not connect to ncpd" << endl; - return 1; - } - skt2 = new ppsocket(); - if (!skt2->connect(NULL, sockNum)) { - cout << "plpftp: could not connect to ncpd" << endl; - return 1; - } - rfsvfactory *rf = new rfsvfactory(skt); - rpcsfactory *rp = new rpcsfactory(skt2); - a = rf->create(false); - r = rp->create(false); - if ((a != NULL) && (r != NULL)) { - status = f.session(*a, *r, argc, argv); - delete r; - delete a; - } else { - cerr << "plpftp: " << rf->getError() << endl; - status = 1; - } - return status; + if (argc < 2) + ftpHeader(); + skt = new ppsocket(); + if (!skt->connect(NULL, sockNum)) { + cout << _("plpftp: could not connect to ncpd") << endl; + return 1; + } + skt2 = new ppsocket(); + if (!skt2->connect(NULL, sockNum)) { + cout << _("plpftp: could not connect to ncpd") << endl; + return 1; + } + rfsvfactory *rf = new rfsvfactory(skt); + rpcsfactory *rp = new rpcsfactory(skt2); + a = rf->create(false); + r = rp->create(false); + if ((a != NULL) && (r != NULL)) { + status = f.session(*a, *r, argc, argv); + delete r; + delete a; + delete skt; + delete skt2; + } else { + cerr << "plpftp: " << gettext(rf->getError()) << endl; + status = 1; + } + delete rf; + delete rp; + return status; } + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ diff --git a/po/POTFILES.in b/po/POTFILES.in new file mode 100644 index 0000000..2beda20 --- /dev/null +++ b/po/POTFILES.in @@ -0,0 +1,9 @@ +lib/rfsv.cc +lib/rpcs.cc +lib/psitime.h +lib/rpcsfactory.cc +lib/plpdirent.cc +lib/rfsvfactory.cc + +plpftp/main.cc +plpftp/ftp.cc diff --git a/po/de.po b/po/de.po new file mode 100644 index 0000000..77fd188 --- /dev/null +++ b/po/de.po @@ -0,0 +1,928 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Free Software Foundation, Inc. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2001-02-28 02:15+0100\n" +"PO-Revision-Date: 2001-02-28 02:44CET\n" +"Last-Translator: Fritz Elfert <felfert@to.com>\n" +"Language-Team: Deutsch <de@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 0.8\n" + +#: lib/rfsv.cc:31 lib/rfsvfactory.cc:43 lib/rpcsfactory.cc:43 +msgid "no error" +msgstr "kein Fehler" + +#: lib/rfsv.cc:32 +msgid "general" +msgstr "allgemein" + +#: lib/rfsv.cc:33 +msgid "bad argument" +msgstr "fehlerhaftes Argument" + +#: lib/rfsv.cc:34 +msgid "OS error" +msgstr "BS Fehler" + +#: lib/rfsv.cc:35 +msgid "not supported" +msgstr "nicht unterstützt" + +#: lib/rfsv.cc:36 +msgid "numeric underflow" +msgstr "numerischer Unterlauf" + +#: lib/rfsv.cc:37 +msgid "numeric overflow" +msgstr "numerischer Überlauf" + +#: lib/rfsv.cc:38 +msgid "numeric exception" +msgstr "numerische Ausnahme" + +#: lib/rfsv.cc:39 +msgid "in use" +msgstr "in Verwendung" + +#: lib/rfsv.cc:40 +msgid "out of memory" +msgstr "kein Speicher" + +#: lib/rfsv.cc:41 +msgid "out of segments" +msgstr "keine Segmente" + +#: lib/rfsv.cc:42 +msgid "out of semaphores" +msgstr "keine Semaphoren" + +#: lib/rfsv.cc:43 +msgid "out of processes" +msgstr "keine Prozesse" + +#: lib/rfsv.cc:44 +msgid "already open" +msgstr "bereits geöffnet" + +#: lib/rfsv.cc:45 +msgid "not open" +msgstr "nicht geöffnet" + +#: lib/rfsv.cc:46 +msgid "bad image" +msgstr "fehlerhaftes Abbild" + +#: lib/rfsv.cc:47 +msgid "receiver error" +msgstr "Empfangsfehler" + +#: lib/rfsv.cc:48 +msgid "device error" +msgstr "Gerätefehler" + +#: lib/rfsv.cc:49 +msgid "no filesystem" +msgstr "kein Dateisystem" + +#: lib/rfsv.cc:50 +msgid "not ready" +msgstr "nicht bereit" + +#: lib/rfsv.cc:51 +msgid "no font" +msgstr "kein Zeichensatz" + +#: lib/rfsv.cc:52 +msgid "too wide" +msgstr "zu breit" + +#: lib/rfsv.cc:53 +msgid "too many" +msgstr "zu viele" + +#: lib/rfsv.cc:54 +msgid "file already exists" +msgstr "Datei existiert bereits" + +#: lib/rfsv.cc:55 +msgid "no such file" +msgstr "keine solche Datei" + +#: lib/rfsv.cc:56 +msgid "write error" +msgstr "Schreibfehler" + +#: lib/rfsv.cc:57 +msgid "read error" +msgstr "Lesefehler" + +#: lib/rfsv.cc:58 +msgid "end of file" +msgstr "Ende der Datei" + +#: lib/rfsv.cc:59 +msgid "disk/serial read buffer full" +msgstr "Platte/serieller Lesepuffer voll" + +#: lib/rfsv.cc:60 +msgid "invalid name" +msgstr "ungültiger Name" + +#: lib/rfsv.cc:61 +msgid "access denied" +msgstr "Zugriff verweigert" + +#: lib/rfsv.cc:62 +msgid "ressource locked" +msgstr "Ressource gesperrt" + +#: lib/rfsv.cc:63 +msgid "no such device" +msgstr "Kein solches Gerät" + +#: lib/rfsv.cc:64 +msgid "no such directory" +msgstr "Kein solcher Ordner" + +#: lib/rfsv.cc:65 +msgid "no such record" +msgstr "Kein solcher Datensatz" + +#: lib/rfsv.cc:66 +msgid "file is read-only" +msgstr "Datei ist nur lesbar" + +#: lib/rfsv.cc:67 +msgid "invalid I/O operation" +msgstr "ungültige E/A-Operation" + +#: lib/rfsv.cc:68 +msgid "I/O pending (not yet completed)" +msgstr "E/A anstehend (noch nicht beendet)" + +#: lib/rfsv.cc:69 +msgid "invalid volume name" +msgstr "ungültiger Einheitenname" + +#: lib/rfsv.cc:70 +msgid "cancelled" +msgstr "abgebrochen" + +#: lib/rfsv.cc:71 +msgid "no memory for control block" +msgstr "kein Speicher für Kontrollblock" + +#: lib/rfsv.cc:72 +msgid "unit disconnected" +msgstr "Einheit nicht verbunden" + +#: lib/rfsv.cc:73 +msgid "already connected" +msgstr "bereits verbunden" + +#: lib/rfsv.cc:74 +msgid "retransmission threshold exceeded" +msgstr "Anzahl der Übertragungsversuche überschritten" + +#: lib/rfsv.cc:75 +msgid "physical link failure" +msgstr "physikalischer Verbindungsfehler" + +#: lib/rfsv.cc:76 +msgid "inactivity timer expired" +msgstr "Zeitlimit für Inaktivität abgelaufen" + +#: lib/rfsv.cc:77 +msgid "serial parity error" +msgstr "Serieller Paritätsfehler" + +#: lib/rfsv.cc:78 +msgid "serial framing error" +msgstr "Serieller Rahmenfehler" + +#: lib/rfsv.cc:79 +msgid "serial overrun error" +msgstr "Serieller Überlauf" + +#: lib/rfsv.cc:80 +msgid "modem cannot connect to remote modem" +msgstr "Modem kann nicht zu entferntem Modem verbinden" + +#: lib/rfsv.cc:81 +msgid "remote modem busy" +msgstr "Entferntes Modem besetzt" + +#: lib/rfsv.cc:82 +msgid "remote modem did not answer" +msgstr "Entferntes Modem antwortet nicht" + +#: lib/rfsv.cc:83 +msgid "number blacklisted by the modem" +msgstr "Rufnummer durch Modem gesperrt" + +#: lib/rfsv.cc:84 +msgid "drive not ready" +msgstr "Laufwerk nicht bereit" + +#: lib/rfsv.cc:85 +msgid "unknown media" +msgstr "Unbekanntes Medium" + +#: lib/rfsv.cc:86 +msgid "directory full" +msgstr "Ordner voll" + +#: lib/rfsv.cc:87 +msgid "write-protected" +msgstr "Schreibgeschützt" + +#: lib/rfsv.cc:88 +msgid "media corrupt" +msgstr "Medium beschädigt" + +#: lib/rfsv.cc:89 +msgid "aborted operation" +msgstr "abgebrochene Operation" + +#: lib/rfsv.cc:90 +msgid "failed to erase flash media" +msgstr "Löschen des Flash-Mediums gescheitert" + +#: lib/rfsv.cc:91 +msgid "invalid file for DBF system" +msgstr "Ungültige Datei für DBF-System" + +#: lib/rfsv.cc:92 +msgid "power failure" +msgstr "Stromversorgung ausgefallen" + +#: lib/rfsv.cc:93 +msgid "too big" +msgstr "zu groß" + +#: lib/rfsv.cc:94 +msgid "bad descriptor" +msgstr "fehlerhafter Deskriptor" + +#: lib/rfsv.cc:95 +msgid "bad entry point" +msgstr "fehlerhafter Einstiegspunkt" + +#: lib/rfsv.cc:96 +msgid "could not diconnect" +msgstr "Konnte Verbindung nicht beenden" + +#: lib/rfsv.cc:97 +msgid "bad driver" +msgstr "fehlerhafter Treiber" + +#: lib/rfsv.cc:98 +msgid "operation not completed" +msgstr "Operation nicht abgeschlossen" + +#: lib/rfsv.cc:99 +msgid "server busy" +msgstr "Server beschäftigt" + +#: lib/rfsv.cc:100 +msgid "terminated" +msgstr "beendet" + +#: lib/rfsv.cc:101 +msgid "died" +msgstr "abgestürtzt" + +#: lib/rfsv.cc:102 +msgid "bad handle" +msgstr "fehlerhafte Referenz" + +#: lib/rfsv.cc:103 +msgid "invalid operation for RFSV16" +msgstr "Ungültige Operation für RFSV16" + +#: lib/rfsv.cc:104 +msgid "libplp internal error" +msgstr "Interner libplp Fehler" + +#: lib/rpcs.cc:41 +msgid "Unknown device" +msgstr "Unbekanntes Gerät" + +#: lib/rpcs.cc:42 +msgid "PC" +msgstr "PC" + +#: lib/rpcs.cc:43 +msgid "MC" +msgstr "MC" + +#: lib/rpcs.cc:44 +msgid "HC" +msgstr "HC" + +#: lib/rpcs.cc:45 +msgid "Series 3" +msgstr "Serie 3" + +#: lib/rpcs.cc:46 +msgid "Series 3a, 3c or 3mx" +msgstr "Serie 3a; 3c oder 3mx" + +#: lib/rpcs.cc:47 +msgid "Workabout" +msgstr "Workabout" + +#: lib/rpcs.cc:48 +msgid "Sienna" +msgstr "Sienna" + +#: lib/rpcs.cc:49 +msgid "Series 3c" +msgstr "Serie 3c" + +#: lib/rpcs.cc:50 +msgid "Series 5" +msgstr "Serie 5" + +#: lib/rpcs.cc:51 +msgid "WinC" +msgstr "WinC" + +#: lib/rpcs.cc:55 +msgid "Empty" +msgstr "Leer" + +#: lib/rpcs.cc:56 +msgid "Very Low" +msgstr "Sehr verbraucht" + +#: lib/rpcs.cc:57 +msgid "Low" +msgstr "Verbraucht" + +#: lib/rpcs.cc:58 +msgid "Good" +msgstr "Gut" + +#: lib/rpcs.cc:62 +msgid "Test" +msgstr "Test" + +#: lib/rpcs.cc:63 +msgid "English" +msgstr "Englisch" + +#: lib/rpcs.cc:64 +msgid "German" +msgstr "Deutsch" + +#: lib/rpcs.cc:65 +msgid "French" +msgstr "Französisch" + +#: lib/rpcs.cc:66 +msgid "Spanish" +msgstr "Spanisch" + +#: lib/rpcs.cc:67 +msgid "Italian" +msgstr "Italienisch" + +#: lib/rpcs.cc:68 +msgid "Swedish" +msgstr "Schwedisch" + +#: lib/rpcs.cc:69 +msgid "Danish" +msgstr "Dänisch" + +#: lib/rpcs.cc:70 +msgid "Norwegian" +msgstr "Norwegisch" + +#: lib/rpcs.cc:71 +msgid "Finnish" +msgstr "Finnisch" + +#: lib/rpcs.cc:72 +msgid "American" +msgstr "Amerikanisch" + +#: lib/rpcs.cc:73 +msgid "Swiss French" +msgstr "Schweizer Französisch" + +#: lib/rpcs.cc:74 +msgid "Swiss German" +msgstr "Schweizer Deutsch" + +#: lib/rpcs.cc:75 +msgid "Portugese" +msgstr "Potugiesisch" + +#: lib/rpcs.cc:76 +msgid "Turkish" +msgstr "Türkisch" + +#: lib/rpcs.cc:77 +msgid "Icelandic" +msgstr "Isländisch" + +#: lib/rpcs.cc:78 +msgid "Russian" +msgstr "Russisch" + +#: lib/rpcs.cc:79 +msgid "Hungarian" +msgstr "Ungarisch" + +#: lib/rpcs.cc:80 +msgid "Dutch" +msgstr "Holländisch" + +#: lib/rpcs.cc:81 +msgid "Belgian Flemish" +msgstr "Belgisch Flämisch" + +#: lib/rpcs.cc:82 +msgid "Australian" +msgstr "Australisch" + +#: lib/rpcs.cc:83 +msgid "Belgish French" +msgstr "Belgisch Französisch" + +#: lib/rpcs.cc:84 +msgid "Austrian" +msgstr "Österreichisch" + +#: lib/rpcs.cc:85 +msgid "New Zealand" +msgstr "Neu-Seeländisch" + +#. FIXME: not shure about ISO code +#: lib/rpcs.cc:86 +msgid "International French" +msgstr "Internationales Französisch" + +#. FIXME: not shure about ISO code +#: lib/rpcs.cc:87 +msgid "Czech" +msgstr "Tschechisch" + +#: lib/rpcs.cc:88 +msgid "Slovak" +msgstr "Slowakisch" + +#: lib/rpcs.cc:89 +msgid "Polish" +msgstr "Polnisch" + +#: lib/rpcs.cc:90 +msgid "Slovenian" +msgstr "Slowenisch" + +#: lib/psitime.h:62 +msgid " years " +msgstr " Jahre " + +#: lib/psitime.h:62 +msgid " year " +msgstr " Jahr " + +#: lib/psitime.h:64 +msgid " days " +msgstr " Tage " + +#: lib/psitime.h:64 +msgid " day " +msgstr " Tag " + +#: lib/psitime.h:66 +msgid " hours " +msgstr " Stunden " + +#: lib/psitime.h:66 +msgid " hour " +msgstr " Stunde " + +#: lib/psitime.h:68 +msgid " minutes " +msgstr " Minuten " + +#: lib/psitime.h:68 +msgid " minute " +msgstr " Minute " + +#: lib/psitime.h:69 plpftp/ftp.cc:797 +msgid " seconds" +msgstr " Sekunden" + +#: lib/psitime.h:69 +msgid " second" +msgstr " Sekunde" + +#: lib/rfsvfactory.cc:44 lib/rpcsfactory.cc:44 +msgid "could not send version request" +msgstr "Konnte Versions-Anforderung nicht versenden" + +#: lib/rfsvfactory.cc:45 lib/rpcsfactory.cc:45 +msgid "try again" +msgstr "Erneut versuchen" + +#: lib/rfsvfactory.cc:46 lib/rpcsfactory.cc:46 +msgid "no psion connected" +msgstr "Kein Psion angeschlossen" + +#: lib/rfsvfactory.cc:47 lib/rpcsfactory.cc:47 +msgid "wrong protocol version" +msgstr "Falsche Protokoll-Version" + +#: lib/rfsvfactory.cc:48 lib/rpcsfactory.cc:48 +msgid "no response from ncpd" +msgstr "Keine Antwort vom ncpd" + +#: lib/plpdirent.cc:159 +msgid "Not present" +msgstr "Nicht vorhanden" + +#: lib/plpdirent.cc:160 +msgid "Unknown" +msgstr "Unbekannt" + +#: lib/plpdirent.cc:161 +msgid "Floppy" +msgstr "Diskette" + +#: lib/plpdirent.cc:162 +msgid "Disk" +msgstr "Platte" + +#: lib/plpdirent.cc:163 +msgid "CD-ROM" +msgstr "CD-ROM" + +#: lib/plpdirent.cc:164 +msgid "RAM" +msgstr "RAM" + +#: lib/plpdirent.cc:165 +msgid "Flash Disk" +msgstr "Flash Disk" + +#: lib/plpdirent.cc:166 lib/plpdirent.cc:193 +msgid "ROM" +msgstr "ROM" + +#: lib/plpdirent.cc:167 +msgid "Remote" +msgstr "Netzlaufwerk" + +#: lib/plpdirent.cc:191 +msgid "local" +msgstr "Lokal" + +#: lib/plpdirent.cc:195 +msgid "redirected" +msgstr "Umgeleitet" + +#: lib/plpdirent.cc:197 +msgid "substituted" +msgstr "Ersetzt" + +#: lib/plpdirent.cc:199 +msgid "internal" +msgstr "Intern" + +#: lib/plpdirent.cc:201 +msgid "removable" +msgstr "Wechselmedium" + +#: lib/plpdirent.cc:214 +msgid "variable size" +msgstr "Variable Größe" + +#: lib/plpdirent.cc:216 +msgid "dual density" +msgstr "Doppelte Dichte" + +#: lib/plpdirent.cc:218 +msgid "formattable" +msgstr "Formatierbar" + +#: lib/plpdirent.cc:220 +msgid "write protected" +msgstr "Schreibgeschützt" + +#: plpftp/main.cc:44 +msgid "Version " +msgstr "Version" + +#: plpftp/main.cc:45 +msgid "Usage : plpftp -p <port> [ftpcommand parameters]" +msgstr "Anwendung : plpftp -p <port> [FTP-Kommando Parameter]" + +#: plpftp/main.cc:51 +msgid "PLPFTP Version " +msgstr "PLPFTP Version " + +#: plpftp/main.cc:52 +msgid " Copyright (C) 1999 Philip Proudman" +msgstr " Copyright (C) 1999 Philip Proudman" + +#: plpftp/main.cc:53 +msgid " Additions Copyright (C) 1999-2001 Fritz Elfert <felfert@to.com>" +msgstr " Erweiterungen Copyright (C) 1999-2001 Fritz Elfert <felfert@to.com>" + +#: plpftp/main.cc:54 +msgid " & (C) 1999 Matt Gumbley <matt@gumbley.demon.co.uk>" +msgstr " & (C) 1999 Matt Gumbley <matt@gumbley.demon.co.uk>" + +#: plpftp/main.cc:55 +msgid "PLPFTP comes with ABSOLUTELY NO WARRANTY." +msgstr "PLPFTP kommt mit ABSOLUT KEINER GARANTIE" + +#: plpftp/main.cc:56 +msgid "This is free software, and you are welcome to redistribute it" +msgstr "Dies ist freie Software. Sie können Sie unter den Bedingungen" + +#: plpftp/main.cc:57 +msgid "under GPL conditions; see the COPYING file in the distribution." +msgstr "der GPL weitergeben. Siehe die Datei COPYING im Packet." + +#: plpftp/main.cc:59 +msgid "FTP like interface started. Type \"?\" for help." +msgstr "FTP Oberfläche gestartet. Geben Sie \"?\" ein, um Hilfe zu bekommen." + +#: plpftp/main.cc:92 plpftp/main.cc:97 +msgid "plpftp: could not connect to ncpd" +msgstr "plpftp: Konnte ncpd nicht kontaktieren." + +#: plpftp/ftp.cc:84 +msgid "Known FTP commands:" +msgstr "Bekannte FTP Kommandos:" + +#: plpftp/ftp.cc:110 +msgid "Known RPC commands:" +msgstr "Bekannte RPC Kommandos:" + +#: plpftp/ftp.cc:227 +msgid "Connected to a " +msgstr "Verbunden mit einem " + +#: plpftp/ftp.cc:227 +msgid ", OwnerInfo:" +msgstr ", Benutzerinfo:" + +#: plpftp/ftp.cc:240 +msgid "OwnerInfo returned error " +msgstr "OwnerInfo lieferte Fehler " + +#: plpftp/ftp.cc:260 +msgid "FATAL: Couln't find default Drive" +msgstr "FATAL: Konnte Standard-Laufwerk nicht ermitteln" + +#: plpftp/ftp.cc:269 +msgid "Psion dir is: \"" +msgstr "Psion Ordner ist: \"" + +#: plpftp/ftp.cc:284 +msgid "Prompting now " +msgstr "Prompt ist nun " + +#: plpftp/ftp.cc:284 plpftp/ftp.cc:289 +msgid "on" +msgstr "an" + +#: plpftp/ftp.cc:284 plpftp/ftp.cc:289 +msgid "off" +msgstr "aus" + +#: plpftp/ftp.cc:289 +msgid "Hash printing now " +msgstr "Fortschrittsanzeige ist nun " + +#: plpftp/ftp.cc:294 +msgid "Local dir: \"" +msgstr "Lokaler Ordner: \"" + +#: plpftp/ftp.cc:295 +msgid "Psion dir: \"" +msgstr "Psion Orner: \"" + +#: plpftp/ftp.cc:300 plpftp/ftp.cc:310 plpftp/ftp.cc:319 plpftp/ftp.cc:327 +#: plpftp/ftp.cc:335 plpftp/ftp.cc:345 plpftp/ftp.cc:357 plpftp/ftp.cc:403 +#: plpftp/ftp.cc:409 plpftp/ftp.cc:433 plpftp/ftp.cc:439 plpftp/ftp.cc:496 +#: plpftp/ftp.cc:519 plpftp/ftp.cc:545 plpftp/ftp.cc:582 plpftp/ftp.cc:610 +#: plpftp/ftp.cc:671 plpftp/ftp.cc:691 plpftp/ftp.cc:698 plpftp/ftp.cc:705 +#: plpftp/ftp.cc:761 plpftp/ftp.cc:771 plpftp/ftp.cc:831 plpftp/ftp.cc:873 +#: plpftp/ftp.cc:883 plpftp/ftp.cc:914 plpftp/ftp.cc:950 plpftp/ftp.cc:1006 +msgid "Error: " +msgstr "Fehler: " + +#: plpftp/ftp.cc:411 +msgid " Entries" +msgstr " Einträge" + +#: plpftp/ftp.cc:417 +msgid "Drive Type Volname Total Free UniqueID" +msgstr "LW Typ Vol.Name Total Frei Eind.ID" + +#: plpftp/ftp.cc:455 +msgid "No such directory" +msgstr "Kein solcher Ordner" + +#: plpftp/ftp.cc:456 plpftp/ftp.cc:497 +msgid "Keeping original directory \"" +msgstr "Behalte ursprünglichen Ordner \"" + +#: plpftp/ftp.cc:536 plpftp/ftp.cc:627 +msgid "Transfer complete, (" +msgstr "Übertragung abgeschlossen, (" + +#: plpftp/ftp.cc:537 plpftp/ftp.cc:628 +msgid " bytes in " +msgstr " bytes in " + +#: plpftp/ftp.cc:538 plpftp/ftp.cc:629 +msgid " secs = " +msgstr " sek. = " + +#: plpftp/ftp.cc:558 +msgid "Get \"" +msgstr "Hole \"" + +#: plpftp/ftp.cc:587 plpftp/ftp.cc:676 +msgid "Transfer complete\n" +msgstr "Übertragung abgeschlossen\n" + +#: plpftp/ftp.cc:653 +msgid "Put \"" +msgstr "Sende \"" + +#: plpftp/ftp.cc:683 +msgid "Error in directory name \"" +msgstr "Fehler in Ordner-Namen \"" + +#: plpftp/ftp.cc:719 +msgid "Starting subshell ...\n" +msgstr "Starte Sub-Shell ...\n" + +#: plpftp/ftp.cc:775 +msgid "General:" +msgstr "Allgemein:" + +#: plpftp/ftp.cc:776 +msgid " Machine Type: " +msgstr " Geräte Typ:" + +#: plpftp/ftp.cc:777 +msgid " Machine Name: " +msgstr " Modell Name: " + +#: plpftp/ftp.cc:778 +msgid " Machine UID: " +msgstr " Geräte-ID: " + +#: plpftp/ftp.cc:779 +msgid " UI Language: " +msgstr " UI-Sprache: " + +#: plpftp/ftp.cc:780 +msgid "ROM:" +msgstr "ROM:" + +#: plpftp/ftp.cc:781 +msgid " Version: " +msgstr " Version: " + +#: plpftp/ftp.cc:783 plpftp/ftp.cc:787 +msgid " Size: " +msgstr " Größe: " + +#: plpftp/ftp.cc:784 +msgid " Programmable: " +msgstr " Programmierbar: " + +#: plpftp/ftp.cc:785 plpftp/ftp.cc:799 +msgid "yes" +msgstr "ja" + +#: plpftp/ftp.cc:785 plpftp/ftp.cc:799 +msgid "no" +msgstr "nein" + +#: plpftp/ftp.cc:786 +msgid "RAM:" +msgstr "RAM:" + +#: plpftp/ftp.cc:788 +msgid " Free: " +msgstr " Frei: " + +#: plpftp/ftp.cc:789 +msgid " Free max: " +msgstr " Max frei: " + +#: plpftp/ftp.cc:790 +msgid "RAM disk size: " +msgstr "RAM Disk Größe: " + +#: plpftp/ftp.cc:791 +msgid "Registry size: " +msgstr "Registry-Größe: " + +#: plpftp/ftp.cc:792 +msgid "Display size: " +msgstr "Anzeige-Größe: " + +#: plpftp/ftp.cc:794 +msgid "Time:" +msgstr "Zeit:" + +#: plpftp/ftp.cc:796 +msgid " Current time: " +msgstr " Aktuelle Zeit: " + +#: plpftp/ftp.cc:797 +msgid " UTC offset: " +msgstr " UTC-Abweichung: " + +#: plpftp/ftp.cc:798 +msgid " DST: " +msgstr " Sommerzeit: " + +#: plpftp/ftp.cc:800 +msgid " Timezone: " +msgstr " Zeitzone: " + +#: plpftp/ftp.cc:801 +msgid " Country Code: " +msgstr " Länder-Code: " + +#: plpftp/ftp.cc:802 +msgid "Main battery:" +msgstr "Hauptbatterie:" + +#: plpftp/ftp.cc:804 +msgid " Changed at: " +msgstr " Gewechselt am: " + +#: plpftp/ftp.cc:805 plpftp/ftp.cc:815 +msgid " Used for: " +msgstr " Benutzt: " + +#: plpftp/ftp.cc:806 plpftp/ftp.cc:812 +msgid " Status: " +msgstr " Status: " + +#: plpftp/ftp.cc:807 +msgid " Current: " +msgstr " Strom: " + +#: plpftp/ftp.cc:808 +msgid " UsedPower: " +msgstr " Verbrauch: " + +#: plpftp/ftp.cc:809 plpftp/ftp.cc:813 +msgid " Voltage: " +msgstr " Spannung: " + +#: plpftp/ftp.cc:810 plpftp/ftp.cc:814 +msgid " Max. voltage: " +msgstr " Max. Spannung: " + +#: plpftp/ftp.cc:811 +msgid "Backup battery:" +msgstr "Sicherungs-Batterie:" + +#: plpftp/ftp.cc:824 +msgid "Could not read processlist " +msgstr "Konnte Prozessliste nicht lesen " + +#: plpftp/ftp.cc:832 +msgid " is not a process list saved with killsave" +msgstr " ist keine mit killsave gespeicherte Prozessliste" + +#: plpftp/ftp.cc:872 +msgid "Could not start " +msgstr "Konnte nicht starten: " + +#: plpftp/ftp.cc:887 +msgid "Could not write processlist " +msgstr "Konnte Prozessliste nicht schreiben " + +#: plpftp/ftp.cc:943 +msgid "no such process" +msgstr "Kein solcher Prozess" + +#: plpftp/ftp.cc:966 +msgid "syntax error. Try \"help\"" +msgstr "Syntaxfehler. Probieren Sie \"help\"" + diff --git a/po/plptools.pot b/po/plptools.pot new file mode 100644 index 0000000..9d69a54 --- /dev/null +++ b/po/plptools.pot @@ -0,0 +1,927 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Free Software Foundation, Inc. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2001-02-28 03:12+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: ENCODING\n" + +#: lib/rfsv.cc:31 lib/rfsvfactory.cc:43 lib/rpcsfactory.cc:43 +msgid "no error" +msgstr "" + +#: lib/rfsv.cc:32 +msgid "general" +msgstr "" + +#: lib/rfsv.cc:33 +msgid "bad argument" +msgstr "" + +#: lib/rfsv.cc:34 +msgid "OS error" +msgstr "" + +#: lib/rfsv.cc:35 +msgid "not supported" +msgstr "" + +#: lib/rfsv.cc:36 +msgid "numeric underflow" +msgstr "" + +#: lib/rfsv.cc:37 +msgid "numeric overflow" +msgstr "" + +#: lib/rfsv.cc:38 +msgid "numeric exception" +msgstr "" + +#: lib/rfsv.cc:39 +msgid "in use" +msgstr "" + +#: lib/rfsv.cc:40 +msgid "out of memory" +msgstr "" + +#: lib/rfsv.cc:41 +msgid "out of segments" +msgstr "" + +#: lib/rfsv.cc:42 +msgid "out of semaphores" +msgstr "" + +#: lib/rfsv.cc:43 +msgid "out of processes" +msgstr "" + +#: lib/rfsv.cc:44 +msgid "already open" +msgstr "" + +#: lib/rfsv.cc:45 +msgid "not open" +msgstr "" + +#: lib/rfsv.cc:46 +msgid "bad image" +msgstr "" + +#: lib/rfsv.cc:47 +msgid "receiver error" +msgstr "" + +#: lib/rfsv.cc:48 +msgid "device error" +msgstr "" + +#: lib/rfsv.cc:49 +msgid "no filesystem" +msgstr "" + +#: lib/rfsv.cc:50 +msgid "not ready" +msgstr "" + +#: lib/rfsv.cc:51 +msgid "no font" +msgstr "" + +#: lib/rfsv.cc:52 +msgid "too wide" +msgstr "" + +#: lib/rfsv.cc:53 +msgid "too many" +msgstr "" + +#: lib/rfsv.cc:54 +msgid "file already exists" +msgstr "" + +#: lib/rfsv.cc:55 +msgid "no such file" +msgstr "" + +#: lib/rfsv.cc:56 +msgid "write error" +msgstr "" + +#: lib/rfsv.cc:57 +msgid "read error" +msgstr "" + +#: lib/rfsv.cc:58 +msgid "end of file" +msgstr "" + +#: lib/rfsv.cc:59 +msgid "disk/serial read buffer full" +msgstr "" + +#: lib/rfsv.cc:60 +msgid "invalid name" +msgstr "" + +#: lib/rfsv.cc:61 +msgid "access denied" +msgstr "" + +#: lib/rfsv.cc:62 +msgid "ressource locked" +msgstr "" + +#: lib/rfsv.cc:63 +msgid "no such device" +msgstr "" + +#: lib/rfsv.cc:64 +msgid "no such directory" +msgstr "" + +#: lib/rfsv.cc:65 +msgid "no such record" +msgstr "" + +#: lib/rfsv.cc:66 +msgid "file is read-only" +msgstr "" + +#: lib/rfsv.cc:67 +msgid "invalid I/O operation" +msgstr "" + +#: lib/rfsv.cc:68 +msgid "I/O pending (not yet completed)" +msgstr "" + +#: lib/rfsv.cc:69 +msgid "invalid volume name" +msgstr "" + +#: lib/rfsv.cc:70 +msgid "cancelled" +msgstr "" + +#: lib/rfsv.cc:71 +msgid "no memory for control block" +msgstr "" + +#: lib/rfsv.cc:72 +msgid "unit disconnected" +msgstr "" + +#: lib/rfsv.cc:73 +msgid "already connected" +msgstr "" + +#: lib/rfsv.cc:74 +msgid "retransmission threshold exceeded" +msgstr "" + +#: lib/rfsv.cc:75 +msgid "physical link failure" +msgstr "" + +#: lib/rfsv.cc:76 +msgid "inactivity timer expired" +msgstr "" + +#: lib/rfsv.cc:77 +msgid "serial parity error" +msgstr "" + +#: lib/rfsv.cc:78 +msgid "serial framing error" +msgstr "" + +#: lib/rfsv.cc:79 +msgid "serial overrun error" +msgstr "" + +#: lib/rfsv.cc:80 +msgid "modem cannot connect to remote modem" +msgstr "" + +#: lib/rfsv.cc:81 +msgid "remote modem busy" +msgstr "" + +#: lib/rfsv.cc:82 +msgid "remote modem did not answer" +msgstr "" + +#: lib/rfsv.cc:83 +msgid "number blacklisted by the modem" +msgstr "" + +#: lib/rfsv.cc:84 +msgid "drive not ready" +msgstr "" + +#: lib/rfsv.cc:85 +msgid "unknown media" +msgstr "" + +#: lib/rfsv.cc:86 +msgid "directory full" +msgstr "" + +#: lib/rfsv.cc:87 +msgid "write-protected" +msgstr "" + +#: lib/rfsv.cc:88 +msgid "media corrupt" +msgstr "" + +#: lib/rfsv.cc:89 +msgid "aborted operation" +msgstr "" + +#: lib/rfsv.cc:90 +msgid "failed to erase flash media" +msgstr "" + +#: lib/rfsv.cc:91 +msgid "invalid file for DBF system" +msgstr "" + +#: lib/rfsv.cc:92 +msgid "power failure" +msgstr "" + +#: lib/rfsv.cc:93 +msgid "too big" +msgstr "" + +#: lib/rfsv.cc:94 +msgid "bad descriptor" +msgstr "" + +#: lib/rfsv.cc:95 +msgid "bad entry point" +msgstr "" + +#: lib/rfsv.cc:96 +msgid "could not diconnect" +msgstr "" + +#: lib/rfsv.cc:97 +msgid "bad driver" +msgstr "" + +#: lib/rfsv.cc:98 +msgid "operation not completed" +msgstr "" + +#: lib/rfsv.cc:99 +msgid "server busy" +msgstr "" + +#: lib/rfsv.cc:100 +msgid "terminated" +msgstr "" + +#: lib/rfsv.cc:101 +msgid "died" +msgstr "" + +#: lib/rfsv.cc:102 +msgid "bad handle" +msgstr "" + +#: lib/rfsv.cc:103 +msgid "invalid operation for RFSV16" +msgstr "" + +#: lib/rfsv.cc:104 +msgid "libplp internal error" +msgstr "" + +#: lib/rpcs.cc:41 +msgid "Unknown device" +msgstr "" + +#: lib/rpcs.cc:42 +msgid "PC" +msgstr "" + +#: lib/rpcs.cc:43 +msgid "MC" +msgstr "" + +#: lib/rpcs.cc:44 +msgid "HC" +msgstr "" + +#: lib/rpcs.cc:45 +msgid "Series 3" +msgstr "" + +#: lib/rpcs.cc:46 +msgid "Series 3a, 3c or 3mx" +msgstr "" + +#: lib/rpcs.cc:47 +msgid "Workabout" +msgstr "" + +#: lib/rpcs.cc:48 +msgid "Sienna" +msgstr "" + +#: lib/rpcs.cc:49 +msgid "Series 3c" +msgstr "" + +#: lib/rpcs.cc:50 +msgid "Series 5" +msgstr "" + +#: lib/rpcs.cc:51 +msgid "WinC" +msgstr "" + +#: lib/rpcs.cc:55 +msgid "Empty" +msgstr "" + +#: lib/rpcs.cc:56 +msgid "Very Low" +msgstr "" + +#: lib/rpcs.cc:57 +msgid "Low" +msgstr "" + +#: lib/rpcs.cc:58 +msgid "Good" +msgstr "" + +#: lib/rpcs.cc:62 +msgid "Test" +msgstr "" + +#: lib/rpcs.cc:63 +msgid "English" +msgstr "" + +#: lib/rpcs.cc:64 +msgid "German" +msgstr "" + +#: lib/rpcs.cc:65 +msgid "French" +msgstr "" + +#: lib/rpcs.cc:66 +msgid "Spanish" +msgstr "" + +#: lib/rpcs.cc:67 +msgid "Italian" +msgstr "" + +#: lib/rpcs.cc:68 +msgid "Swedish" +msgstr "" + +#: lib/rpcs.cc:69 +msgid "Danish" +msgstr "" + +#: lib/rpcs.cc:70 +msgid "Norwegian" +msgstr "" + +#: lib/rpcs.cc:71 +msgid "Finnish" +msgstr "" + +#: lib/rpcs.cc:72 +msgid "American" +msgstr "" + +#: lib/rpcs.cc:73 +msgid "Swiss French" +msgstr "" + +#: lib/rpcs.cc:74 +msgid "Swiss German" +msgstr "" + +#: lib/rpcs.cc:75 +msgid "Portugese" +msgstr "" + +#: lib/rpcs.cc:76 +msgid "Turkish" +msgstr "" + +#: lib/rpcs.cc:77 +msgid "Icelandic" +msgstr "" + +#: lib/rpcs.cc:78 +msgid "Russian" +msgstr "" + +#: lib/rpcs.cc:79 +msgid "Hungarian" +msgstr "" + +#: lib/rpcs.cc:80 +msgid "Dutch" +msgstr "" + +#: lib/rpcs.cc:81 +msgid "Belgian Flemish" +msgstr "" + +#: lib/rpcs.cc:82 +msgid "Australian" +msgstr "" + +#: lib/rpcs.cc:83 +msgid "Belgish French" +msgstr "" + +#: lib/rpcs.cc:84 +msgid "Austrian" +msgstr "" + +#: lib/rpcs.cc:85 +msgid "New Zealand" +msgstr "" + +#. FIXME: not shure about ISO code +#: lib/rpcs.cc:86 +msgid "International French" +msgstr "" + +#. FIXME: not shure about ISO code +#: lib/rpcs.cc:87 +msgid "Czech" +msgstr "" + +#: lib/rpcs.cc:88 +msgid "Slovak" +msgstr "" + +#: lib/rpcs.cc:89 +msgid "Polish" +msgstr "" + +#: lib/rpcs.cc:90 +msgid "Slovenian" +msgstr "" + +#: lib/psitime.h:62 +msgid " years " +msgstr "" + +#: lib/psitime.h:62 +msgid " year " +msgstr "" + +#: lib/psitime.h:64 +msgid " days " +msgstr "" + +#: lib/psitime.h:64 +msgid " day " +msgstr "" + +#: lib/psitime.h:66 +msgid " hours " +msgstr "" + +#: lib/psitime.h:66 +msgid " hour " +msgstr "" + +#: lib/psitime.h:68 +msgid " minutes " +msgstr "" + +#: lib/psitime.h:68 +msgid " minute " +msgstr "" + +#: lib/psitime.h:69 plpftp/ftp.cc:797 +msgid " seconds" +msgstr "" + +#: lib/psitime.h:69 +msgid " second" +msgstr "" + +#: lib/rfsvfactory.cc:44 lib/rpcsfactory.cc:44 +msgid "could not send version request" +msgstr "" + +#: lib/rfsvfactory.cc:45 lib/rpcsfactory.cc:45 +msgid "try again" +msgstr "" + +#: lib/rfsvfactory.cc:46 lib/rpcsfactory.cc:46 +msgid "no psion connected" +msgstr "" + +#: lib/rfsvfactory.cc:47 lib/rpcsfactory.cc:47 +msgid "wrong protocol version" +msgstr "" + +#: lib/rfsvfactory.cc:48 lib/rpcsfactory.cc:48 +msgid "no response from ncpd" +msgstr "" + +#: lib/plpdirent.cc:159 +msgid "Not present" +msgstr "" + +#: lib/plpdirent.cc:160 +msgid "Unknown" +msgstr "" + +#: lib/plpdirent.cc:161 +msgid "Floppy" +msgstr "" + +#: lib/plpdirent.cc:162 +msgid "Disk" +msgstr "" + +#: lib/plpdirent.cc:163 +msgid "CD-ROM" +msgstr "" + +#: lib/plpdirent.cc:164 +msgid "RAM" +msgstr "" + +#: lib/plpdirent.cc:165 +msgid "Flash Disk" +msgstr "" + +#: lib/plpdirent.cc:166 lib/plpdirent.cc:193 +msgid "ROM" +msgstr "" + +#: lib/plpdirent.cc:167 +msgid "Remote" +msgstr "" + +#: lib/plpdirent.cc:191 +msgid "local" +msgstr "" + +#: lib/plpdirent.cc:195 +msgid "redirected" +msgstr "" + +#: lib/plpdirent.cc:197 +msgid "substituted" +msgstr "" + +#: lib/plpdirent.cc:199 +msgid "internal" +msgstr "" + +#: lib/plpdirent.cc:201 +msgid "removable" +msgstr "" + +#: lib/plpdirent.cc:214 +msgid "variable size" +msgstr "" + +#: lib/plpdirent.cc:216 +msgid "dual density" +msgstr "" + +#: lib/plpdirent.cc:218 +msgid "formattable" +msgstr "" + +#: lib/plpdirent.cc:220 +msgid "write protected" +msgstr "" + +#: plpftp/main.cc:44 +msgid "Version " +msgstr "" + +#: plpftp/main.cc:45 +msgid "Usage : plpftp -p <port> [ftpcommand parameters]" +msgstr "" + +#: plpftp/main.cc:51 +msgid "PLPFTP Version " +msgstr "" + +#: plpftp/main.cc:52 +msgid " Copyright (C) 1999 Philip Proudman" +msgstr "" + +#: plpftp/main.cc:53 +msgid " Additions Copyright (C) 1999-2001 Fritz Elfert <felfert@to.com>" +msgstr "" + +#: plpftp/main.cc:54 +msgid " & (C) 1999 Matt Gumbley <matt@gumbley.demon.co.uk>" +msgstr "" + +#: plpftp/main.cc:55 +msgid "PLPFTP comes with ABSOLUTELY NO WARRANTY." +msgstr "" + +#: plpftp/main.cc:56 +msgid "This is free software, and you are welcome to redistribute it" +msgstr "" + +#: plpftp/main.cc:57 +msgid "under GPL conditions; see the COPYING file in the distribution." +msgstr "" + +#: plpftp/main.cc:59 +msgid "FTP like interface started. Type \"?\" for help." +msgstr "" + +#: plpftp/main.cc:92 plpftp/main.cc:97 +msgid "plpftp: could not connect to ncpd" +msgstr "" + +#: plpftp/ftp.cc:84 +msgid "Known FTP commands:" +msgstr "" + +#: plpftp/ftp.cc:110 +msgid "Known RPC commands:" +msgstr "" + +#: plpftp/ftp.cc:227 +msgid "Connected to a " +msgstr "" + +#: plpftp/ftp.cc:227 +msgid ", OwnerInfo:" +msgstr "" + +#: plpftp/ftp.cc:240 +msgid "OwnerInfo returned error " +msgstr "" + +#: plpftp/ftp.cc:260 +msgid "FATAL: Couln't find default Drive" +msgstr "" + +#: plpftp/ftp.cc:269 +msgid "Psion dir is: \"" +msgstr "" + +#: plpftp/ftp.cc:284 +msgid "Prompting now " +msgstr "" + +#: plpftp/ftp.cc:284 plpftp/ftp.cc:289 +msgid "on" +msgstr "" + +#: plpftp/ftp.cc:284 plpftp/ftp.cc:289 +msgid "off" +msgstr "" + +#: plpftp/ftp.cc:289 +msgid "Hash printing now " +msgstr "" + +#: plpftp/ftp.cc:294 +msgid "Local dir: \"" +msgstr "" + +#: plpftp/ftp.cc:295 +msgid "Psion dir: \"" +msgstr "" + +#: plpftp/ftp.cc:300 plpftp/ftp.cc:310 plpftp/ftp.cc:319 plpftp/ftp.cc:327 +#: plpftp/ftp.cc:335 plpftp/ftp.cc:345 plpftp/ftp.cc:357 plpftp/ftp.cc:403 +#: plpftp/ftp.cc:409 plpftp/ftp.cc:433 plpftp/ftp.cc:439 plpftp/ftp.cc:496 +#: plpftp/ftp.cc:519 plpftp/ftp.cc:545 plpftp/ftp.cc:582 plpftp/ftp.cc:610 +#: plpftp/ftp.cc:671 plpftp/ftp.cc:691 plpftp/ftp.cc:698 plpftp/ftp.cc:705 +#: plpftp/ftp.cc:761 plpftp/ftp.cc:771 plpftp/ftp.cc:831 plpftp/ftp.cc:873 +#: plpftp/ftp.cc:883 plpftp/ftp.cc:914 plpftp/ftp.cc:950 plpftp/ftp.cc:1006 +msgid "Error: " +msgstr "" + +#: plpftp/ftp.cc:411 +msgid " Entries" +msgstr "" + +#: plpftp/ftp.cc:417 +msgid "Drive Type Volname Total Free UniqueID" +msgstr "" + +#: plpftp/ftp.cc:455 +msgid "No such directory" +msgstr "" + +#: plpftp/ftp.cc:456 plpftp/ftp.cc:497 +msgid "Keeping original directory \"" +msgstr "" + +#: plpftp/ftp.cc:536 plpftp/ftp.cc:627 +msgid "Transfer complete, (" +msgstr "" + +#: plpftp/ftp.cc:537 plpftp/ftp.cc:628 +msgid " bytes in " +msgstr "" + +#: plpftp/ftp.cc:538 plpftp/ftp.cc:629 +msgid " secs = " +msgstr "" + +#: plpftp/ftp.cc:558 +msgid "Get \"" +msgstr "" + +#: plpftp/ftp.cc:587 plpftp/ftp.cc:676 +msgid "Transfer complete\n" +msgstr "" + +#: plpftp/ftp.cc:653 +msgid "Put \"" +msgstr "" + +#: plpftp/ftp.cc:683 +msgid "Error in directory name \"" +msgstr "" + +#: plpftp/ftp.cc:719 +msgid "Starting subshell ...\n" +msgstr "" + +#: plpftp/ftp.cc:775 +msgid "General:" +msgstr "" + +#: plpftp/ftp.cc:776 +msgid " Machine Type: " +msgstr "" + +#: plpftp/ftp.cc:777 +msgid " Machine Name: " +msgstr "" + +#: plpftp/ftp.cc:778 +msgid " Machine UID: " +msgstr "" + +#: plpftp/ftp.cc:779 +msgid " UI Language: " +msgstr "" + +#: plpftp/ftp.cc:780 +msgid "ROM:" +msgstr "" + +#: plpftp/ftp.cc:781 +msgid " Version: " +msgstr "" + +#: plpftp/ftp.cc:783 plpftp/ftp.cc:787 +msgid " Size: " +msgstr "" + +#: plpftp/ftp.cc:784 +msgid " Programmable: " +msgstr "" + +#: plpftp/ftp.cc:785 plpftp/ftp.cc:799 +msgid "yes" +msgstr "" + +#: plpftp/ftp.cc:785 plpftp/ftp.cc:799 +msgid "no" +msgstr "" + +#: plpftp/ftp.cc:786 +msgid "RAM:" +msgstr "" + +#: plpftp/ftp.cc:788 +msgid " Free: " +msgstr "" + +#: plpftp/ftp.cc:789 +msgid " Free max: " +msgstr "" + +#: plpftp/ftp.cc:790 +msgid "RAM disk size: " +msgstr "" + +#: plpftp/ftp.cc:791 +msgid "Registry size: " +msgstr "" + +#: plpftp/ftp.cc:792 +msgid "Display size: " +msgstr "" + +#: plpftp/ftp.cc:794 +msgid "Time:" +msgstr "" + +#: plpftp/ftp.cc:796 +msgid " Current time: " +msgstr "" + +#: plpftp/ftp.cc:797 +msgid " UTC offset: " +msgstr "" + +#: plpftp/ftp.cc:798 +msgid " DST: " +msgstr "" + +#: plpftp/ftp.cc:800 +msgid " Timezone: " +msgstr "" + +#: plpftp/ftp.cc:801 +msgid " Country Code: " +msgstr "" + +#: plpftp/ftp.cc:802 +msgid "Main battery:" +msgstr "" + +#: plpftp/ftp.cc:804 +msgid " Changed at: " +msgstr "" + +#: plpftp/ftp.cc:805 plpftp/ftp.cc:815 +msgid " Used for: " +msgstr "" + +#: plpftp/ftp.cc:806 plpftp/ftp.cc:812 +msgid " Status: " +msgstr "" + +#: plpftp/ftp.cc:807 +msgid " Current: " +msgstr "" + +#: plpftp/ftp.cc:808 +msgid " UsedPower: " +msgstr "" + +#: plpftp/ftp.cc:809 plpftp/ftp.cc:813 +msgid " Voltage: " +msgstr "" + +#: plpftp/ftp.cc:810 plpftp/ftp.cc:814 +msgid " Max. voltage: " +msgstr "" + +#: plpftp/ftp.cc:811 +msgid "Backup battery:" +msgstr "" + +#: plpftp/ftp.cc:824 +msgid "Could not read processlist " +msgstr "" + +#: plpftp/ftp.cc:832 +msgid " is not a process list saved with killsave" +msgstr "" + +#: plpftp/ftp.cc:872 +msgid "Could not start " +msgstr "" + +#: plpftp/ftp.cc:887 +msgid "Could not write processlist " +msgstr "" + +#: plpftp/ftp.cc:943 +msgid "no such process" +msgstr "" + +#: plpftp/ftp.cc:966 +msgid "syntax error. Try \"help\"" +msgstr "" |