aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kde2/.cvsignore2
-rw-r--r--kde2/Makefile.am12
-rw-r--r--kde2/kioslave/.cvsignore6
-rw-r--r--kde2/kioslave/Makefile.am26
-rw-r--r--kde2/kioslave/README3
-rw-r--r--kde2/kioslave/kio_plp.cpp781
-rw-r--r--kde2/kioslave/kio_plp.h77
-rw-r--r--kde2/kioslave/psion.protocol11
-rw-r--r--plpbackup/.cvsignore5
-rw-r--r--plpbackup/Makefile.am10
-rw-r--r--plpbackup/plpbackup.cc530
11 files changed, 1463 insertions, 0 deletions
diff --git a/kde2/.cvsignore b/kde2/.cvsignore
new file mode 100644
index 0000000..3dda729
--- /dev/null
+++ b/kde2/.cvsignore
@@ -0,0 +1,2 @@
+Makefile.in
+Makefile
diff --git a/kde2/Makefile.am b/kde2/Makefile.am
new file mode 100644
index 0000000..4c8fb84
--- /dev/null
+++ b/kde2/Makefile.am
@@ -0,0 +1,12 @@
+# $Id$
+#
+
+SUBDIRS = kioslave
+
+TMPDEST=
+#
+# remove all intermediate files that can be recreated using
+# Makefile.cvs
+#
+maintainer-clean-local:
+ rm -f Makefile.in
diff --git a/kde2/kioslave/.cvsignore b/kde2/kioslave/.cvsignore
new file mode 100644
index 0000000..b9f26ab
--- /dev/null
+++ b/kde2/kioslave/.cvsignore
@@ -0,0 +1,6 @@
+Makefile.in
+Makefile
+*.la
+*.lo
+.libs
+.deps
diff --git a/kde2/kioslave/Makefile.am b/kde2/kioslave/Makefile.am
new file mode 100644
index 0000000..1b573d9
--- /dev/null
+++ b/kde2/kioslave/Makefile.am
@@ -0,0 +1,26 @@
+## Makefile.am of kdebase/kioslave/plp
+
+INCLUDES = $(all_includes) -I$(top_srcdir)/lib
+LDFLAGS = $(all_libraries) $(KDE_RPATH)
+
+####### Files
+
+kio_plp_la_LDFLAGS = -module -avoid-version -no-undefined
+
+if BUILD_KDE
+
+myprotodir = $(kde_servicesdir)
+
+lib_LTLIBRARIES = kio_plp.la
+
+kio_plp_la_SOURCES = kio_plp.cpp
+kio_plp_la_LIBADD = -L$(top_srcdir)/lib -lplp -lkio
+noinst_HEADERS = kio_plp.h
+
+myproto_DATA = psion.protocol
+
+METASOURCES = AUTO
+
+bin_SCRIPTS =
+
+endif
diff --git a/kde2/kioslave/README b/kde2/kioslave/README
new file mode 100644
index 0000000..7402231
--- /dev/null
+++ b/kde2/kioslave/README
@@ -0,0 +1,3 @@
+this is an ioslave for KDE 2 for PLP.
+
+Fritz
diff --git a/kde2/kioslave/kio_plp.cpp b/kde2/kioslave/kio_plp.cpp
new file mode 100644
index 0000000..8cf76c7
--- /dev/null
+++ b/kde2/kioslave/kio_plp.cpp
@@ -0,0 +1,781 @@
+/*
+ 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.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "kio_plp.h"
+
+#include <stdio.h>
+#include <sys/stat.h>
+
+#include <qfile.h>
+
+#include <kinstance.h>
+#include <kdebug.h>
+#include <klocale.h>
+
+#include <rfsvfactory.h>
+#include <bufferarray.h>
+
+#include <string>
+
+using namespace KIO;
+
+static int PLP_DEBUGAREA = 7999;
+// until we get an offical assignment
+#define kdDebug(PLP_DEBUGAREA) cout
+
+extern "C" {
+ int kdemain(int argc, char **argv);
+}
+
+int
+kdemain( int argc, char **argv ) {
+ 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;
+
+ 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);
+}
+
+static QString
+baseName(const QString& path) {
+ 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);
+ }
+ return result;
+}
+
+PLPProtocol::PLPProtocol (const QCString &pool, const QCString &app)
+ :SlaveBase("psion", pool, app), plpRfsv(0), plpRfsvSocket(0) {
+ currentHost = "";
+ struct servent *se = getservbyname("psion", "tcp");
+ endservent();
+ if (se != 0L)
+ currentPort = ntohs(se->s_port);
+ else
+ currentPort = DPORT;
+ kdDebug(PLP_DEBUGAREA) << "PLP::PLP: -" << pool << "-" << endl;
+}
+
+PLPProtocol::~PLPProtocol() {
+ closeConnection();
+}
+
+void PLPProtocol::
+closeConnection() {
+ if (plpRfsv)
+ delete(plpRfsv);
+ if (plpRfsvSocket)
+ delete(plpRfsvSocket);
+ plpRfsv = 0;
+ plpRfsvSocket = 0;
+}
+
+bool PLPProtocol::
+isRoot(const QString& 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;
+}
+
+bool PLPProtocol::
+isRomDrive(const QString& path) {
+ 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';
+}
+
+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;
+}
+
+void PLPProtocol::
+openConnection() {
+ kdDebug(PLP_DEBUGAREA) << "PLP::openConnection" << endl;
+ closeConnection();
+
+ plpRfsvSocket = new ppsocket();
+ if (!plpRfsvSocket->connect((char *)(currentHost.data()), currentPort)) {
+ error(ERR_COULD_NOT_CONNECT, i18n("Could not connect to ncpd"));
+ return;
+ }
+ rfsvfactory factory(plpRfsvSocket);
+ plpRfsv = factory.create(false);
+ if (plpRfsv == 0) {
+ error(ERR_COULD_NOT_CONNECT, i18n("Could not read version info"));
+ return;
+ }
+ long devbits;
+ Enum<rfsv::errs> res;
+
+ if ((res = plpRfsv->devlist(devbits)) == rfsv::E_PSI_GEN_NONE) {
+ for (int i = 0; i < 26; i++) {
+ char vname[256];
+ long vtotal, vfree, vattr, vuniqueid;
+
+ if ((devbits & 1) != 0) {
+ if (plpRfsv->devinfo(i, vfree, vtotal, vattr, vuniqueid,
+ vname) == rfsv::E_PSI_GEN_NONE) {
+ QString name;
+
+ if (strlen(vname))
+ name = QString(vname);
+ 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;
+}
+
+bool PLPProtocol::
+checkConnection() {
+ if (plpRfsv == 0)
+ openConnection();
+ return (plpRfsv == 0);
+}
+
+void PLPProtocol::
+listDir(const KURL& _url) {
+ KURL url(_url);
+ QString path(QFile::encodeName(url.path()));
+
+ if (path.isEmpty()) {
+ url.setPath("/");
+ redirection(url);
+ finished();
+ return;
+ }
+
+ if (checkConnection())
+ return;
+
+ if (isRoot(path)) {
+ kdDebug(PLP_DEBUGAREA) << "listing root" << endl;
+ totalSize(drives.count());
+ //in this case we don't need to do a real listdir
+ UDSEntry entry;
+ for (QStringList::Iterator it = drives.begin(); it != drives.end(); it++) {
+ UDSAtom atom;
+ 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');
+ listEntry(entry, false);
+ }
+ listEntry(entry, true);
+ finished();
+ return;
+ }
+
+ kdDebug(PLP_DEBUGAREA) << "getting subdir -" << path << "-" << endl;
+ bool rom = isRomDrive(path);
+ convertName(path);
+ path += "\\";
+
+ bufferArray files;
+ Enum<rfsv::errs> res = plpRfsv->dir(path, files);
+ if (checkForError(res))
+ return;
+ totalSize(files.length());
+ UDSEntry entry;
+ while (!files.empty()) {
+ UDSAtom atom;
+ bufferStore s = files.pop();
+ PsiTime *date = (PsiTime *)s.getDWord(0);
+ long size = s.getDWord(4);
+ long attr = s.getDWord(8);
+ entry.clear();
+
+ atom.m_uds = KIO::UDS_NAME;
+ atom.m_str = s.getString(12);
+ entry.append(atom);
+
+ if (rom)
+ attr |= rfsv::PSI_A_RDONLY;
+ completeUDSEntry(entry, attr, size, date);
+ listEntry(entry, false);
+ }
+ listEntry(entry, true); // ready
+ finished();
+}
+
+void PLPProtocol::
+createVirtualDirEntry(UDSEntry & entry, bool rdonly) {
+ UDSAtom atom;
+
+ atom.m_uds = KIO::UDS_FILE_TYPE;
+ atom.m_long = S_IFDIR;
+ entry.append( 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 );
+}
+
+bool PLPProtocol::
+emitTotalSize(QString &name) {
+ long attr;
+ long size;
+ bool err;
+ PsiTime time;
+
+ Enum<rfsv::errs> res = plpRfsv->fgeteattr(name, attr, size, time);
+ if (checkForError(res))
+ return true;
+ totalSize(size);
+ return false;
+}
+
+void PLPProtocol::
+stat( const KURL & url) {
+ QString path(QFile::encodeName(url.path()));
+ 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);
+ createVirtualDirEntry(entry, isRoot(path) || isRomDrive(path));
+ statEntry(entry);
+ finished();
+ kdDebug(PLP_DEBUGAREA) << "succeeded" << endl;
+ return;
+ }
+
+ bool rom = isRomDrive(path);
+ QString fileName = baseName(path);
+ convertName(path);
+
+ if (path.isEmpty()) {
+ error(ERR_DOES_NOT_EXIST, fileName);
+ return;
+ }
+
+ long attr, size;
+ PsiTime time;
+ Enum<rfsv::errs> res = plpRfsv->fgeteattr(path, attr, size, time);
+ if (checkForError(res))
+ return;
+ if (rom)
+ attr |= rfsv::PSI_A_RDONLY;
+
+ atom.m_uds = KIO::UDS_NAME;
+ atom.m_str = fileName;
+ entry.append(atom);
+ completeUDSEntry(entry, attr, size, &time);
+ statEntry(entry);
+
+ finished();
+}
+
+void PLPProtocol::
+completeUDSEntry(UDSEntry& entry, const long attr, const long size, PsiTime *date) {
+ UDSAtom atom;
+
+ atom.m_uds = KIO::UDS_SIZE;
+ atom.m_long = size;
+ entry.append(atom);
+
+ atom.m_uds = KIO::UDS_MODIFICATION_TIME;
+ atom.m_long = date->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);
+
+#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;
+ }
+ }
+#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();
+}
+
+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("read only filesystem"));
+ return;
+ }
+ if (isRoot(name) || isDrive(name)) {
+ error(ERR_ACCESS_DENIED, i18n("Virtual directory"));
+ return;
+ }
+ convertName(name);
+ Enum<rfsv::errs> res = plpRfsv->mkdir(name);
+ if (checkForError(res))
+ return;
+ finished();
+}
+
+bool PLPProtocol::
+checkForError(Enum<rfsv::errs> res) {
+ if (res != rfsv::E_PSI_GEN_NONE) {
+ kdDebug(PLP_DEBUGAREA) << "plp error: " << res << endl;
+ QString text(res.toString().data());
+ 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;
+ }
+ 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("read only filesystem"));
+ return;
+ }
+ if (isRoot(name) || isDrive(name)) {
+ error(ERR_ACCESS_DENIED, i18n("Virtual directory"));
+ return;
+ }
+ convertName(name);
+
+ Enum<rfsv::errs> res =
+ (isfile) ? plpRfsv->remove(name) : plpRfsv->rmdir(name);
+ if (checkForError(res))
+ 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("read only filesystem"));
+ return;
+ }
+ if (isRoot(name) || isDrive(name)) {
+ error(ERR_ACCESS_DENIED, i18n("Virtual directory"));
+ 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))
+ 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("Virtual directory"));
+ return;
+ }
+ convertName(name);
+
+ Enum<rfsv::errs> res;
+ long handle;
+ long len;
+ long size;
+ long total = 0;
+
+ if (emitTotalSize(name))
+ return;
+ res = plpRfsv->fopen(plpRfsv->opMode(rfsv::PSI_O_RDONLY), name, handle);
+ if (checkForError(res))
+ 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))
+ return;
+ data(QByteArray());
+
+ 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("read only filesystem"));
+ return;
+ }
+ if (isRoot(name) || isDrive(name)) {
+ error(ERR_ACCESS_DENIED, i18n("Virtual directory"));
+ return;
+ }
+ convertName(name);
+
+ Enum<rfsv::errs> res;
+ long 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))
+ 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 {
+ long written;
+ int count = (len > RFSV_SENDLEN) ? RFSV_SENDLEN : len;
+ res = plpRfsv->fwrite(handle, data, count, written);
+ if (checkForError(res)) {
+ 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("Virtual directory"));
+ kdDebug(PLP_DEBUGAREA) << "from FS != to FS" << endl;
+ return;
+ }
+ if (isRomDrive(from)) {
+ error(ERR_ACCESS_DENIED, i18n("read only filesystem"));
+ kdDebug(PLP_DEBUGAREA) << "from ROFS" << endl;
+ return;
+ }
+ if (isRoot(from)) {
+ error(ERR_ACCESS_DENIED, i18n("Virtual directory"));
+ kdDebug(PLP_DEBUGAREA) << "from VFS" << endl;
+ return;
+ }
+ bool volRename = isDrive(from);
+ if (isRomDrive(to)) {
+ error(ERR_ACCESS_DENIED, i18n("read only filesystem"));
+ kdDebug(PLP_DEBUGAREA) << "to ROFS" << endl;
+ return;
+ }
+ if (isRoot(to)) {
+ error(ERR_ACCESS_DENIED, i18n("Virtual directory"));
+ 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) {
+ long 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))
+ return;
+ finished();
+}
+
+extern "C" {
+static int
+progresswrapper(void *ptr, long 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;
+ }
+}
+
+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()));
+
+ if (checkConnection())
+ return;
+ kdDebug(PLP_DEBUGAREA) << "copy(" << from << "," << to << ")" << endl;
+ if (isRoot(from) || isDrive(from)) {
+ error(ERR_ACCESS_DENIED, i18n("Virtual directory"));
+ return;
+ }
+ convertName(from);
+ if (isRomDrive(to)) {
+ error(ERR_ACCESS_DENIED, i18n("read only filesystem"));
+ return;
+ }
+ if (isRoot(to) || isDrive(to)) {
+ error(ERR_ACCESS_DENIED, i18n("Virtual directory"));
+ return;
+ }
+ convertName(to);
+ Enum <rfsv::errs> res;
+ if (!_overwrite) {
+ long 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))
+ return;
+ finished();
+}
diff --git a/kde2/kioslave/kio_plp.h b/kde2/kioslave/kio_plp.h
new file mode 100644
index 0000000..4f1bc23
--- /dev/null
+++ b/kde2/kioslave/kio_plp.h
@@ -0,0 +1,77 @@
+/* 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
+
+#include <kio/slavebase.h>
+#include <kio/global.h>
+#include <qstring.h>
+#include <qstringlist.h>
+#include <qmap.h>
+#include <rfsv.h>
+#include <ppsocket.h>
+
+class PLPProtocol : public KIO::SlaveBase
+{
+ public:
+ PLPProtocol (const QCString &pool, const QCString &app );
+ virtual ~PLPProtocol();
+
+ virtual void openConnection();
+ virtual void closeConnection();
+
+ virtual void setHost( const QString& host, int port, const QString& user, const QString& pass );
+
+ 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 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 );
+
+ void calcprogress(long total);
+ private:
+ bool checkConnection();
+
+ char driveChar(const QString& path);
+
+ void createVirtualDirEntry(KIO::UDSEntry & entry, bool rdonly);
+ void completeUDSEntry(KIO::UDSEntry& entry, const long attr, const long size, PsiTime *date);
+ bool checkForError(Enum<rfsv::errs> res);
+ bool isRomDrive(const QString& path);
+ bool isDrive(const QString& path);
+ bool isRoot(const QString& path);
+ void convertName(QString &path);
+ bool emitTotalSize(QString &name);
+
+ rfsv *plpRfsv;
+ ppsocket *plpRfsvSocket;
+ QStringList drives;
+ QMap<QString,char> drivechars;
+ QString currentHost;
+ int currentPort;
+ time_t t_last;
+ time_t t_start;
+};
+
+#endif
diff --git a/kde2/kioslave/psion.protocol b/kde2/kioslave/psion.protocol
new file mode 100644
index 0000000..6e14b80
--- /dev/null
+++ b/kde2/kioslave/psion.protocol
@@ -0,0 +1,11 @@
+[Protocol]
+exec=kio_plp
+protocol=psion
+input=none
+output=filesystem
+listing=Name,Type,Size,Date,Access
+reading=true
+writing=true
+makedir=true
+deleting=true
+moving=true
diff --git a/plpbackup/.cvsignore b/plpbackup/.cvsignore
new file mode 100644
index 0000000..9e9544d
--- /dev/null
+++ b/plpbackup/.cvsignore
@@ -0,0 +1,5 @@
+Makefile.in
+Makefile
+plpbackup
+.libs
+.deps
diff --git a/plpbackup/Makefile.am b/plpbackup/Makefile.am
new file mode 100644
index 0000000..a1a859b
--- /dev/null
+++ b/plpbackup/Makefile.am
@@ -0,0 +1,10 @@
+# $Id$
+#
+INCLUDES=-I$(top_srcdir)/lib
+
+bin_PROGRAMS = plpbackup
+plpbackup_LDADD = $(top_srcdir)/lib/libplp.la
+plpbackup_SOURCES = plpbackup.cc
+
+maintainer-clean-local:
+ rm -f Makefile.in
diff --git a/plpbackup/plpbackup.cc b/plpbackup/plpbackup.cc
new file mode 100644
index 0000000..ebc77e5
--- /dev/null
+++ b/plpbackup/plpbackup.cc
@@ -0,0 +1,530 @@
+// $Id$
+//
+// plpbackup - A backup program for Psion.
+//
+// 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
+//
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <dirent.h>
+#include <fstream.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <iomanip.h>
+#include <unistd.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <pwd.h>
+
+#include "bool.h"
+#include "ppsocket.h"
+#include "rfsv.h"
+#include "rfsvfactory.h"
+#include "rpcs.h"
+#include "rpcsfactory.h"
+#include "bufferstore.h"
+#include "bufferarray.h"
+#include "Enum.h"
+
+void
+usage(ostream *hlp)
+{
+ *hlp << "Usage : plpbackup [-p <port>] [-v] [-f] [drive1:] [drive2:] ..." << endl;
+ *hlp << endl;
+ *hlp << " Options:" << endl;
+ *hlp << " -h Print this message and exit." << endl;
+ *hlp << " -V Print version and exit." << endl;
+ *hlp << " -p <port> Connect to ncpd using given port." << endl;
+ *hlp << " -v Increase verbosity." << endl;
+ *hlp << " -f Do a full backup. (Incremental otherwise)" << endl;
+ *hlp << " <drive> A drive character. If none given, scan all drives" << endl;
+}
+
+bool full;
+int verbose = 0;
+bufferArray toBackup;
+unsigned long backupSize = 0;
+unsigned long totalBytes = 0;
+unsigned long fileSize = 0;
+char home[1024];
+
+static int
+killsave(rpcs *r, bool S5mx) {
+ Enum<rfsv::errs> res;
+ bufferArray tmp;
+ char psfile[1024];
+
+ sprintf(psfile, "%s/.plpbackup.%d", home, getpid());
+ if ((res = r->queryDrive('C', tmp)) != rfsv::E_PSI_GEN_NONE) {
+ cerr << "Could not get process list, Error: " << res << endl;
+ return 1;
+ } else {
+ ofstream op(psfile);
+ if (!op) {
+ cerr << "Could not write processlist " << psfile << endl;
+ return 1;
+ }
+ op << "#plpbackup 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;
+ if (verbose > 1)
+ cout << cmdargs.getString(0) << " " << bs.getString(0) << endl;
+ r->stopProgram(pbuf);
+ }
+ op.close();
+ }
+ return 0;
+}
+
+static int
+runrestore(rfsv *a, rpcs *r) {
+ Enum<rfsv::errs> res;
+ bufferArray tmp;
+ char psfile[1024];
+
+ sprintf(psfile, "%s/.plpbackup.%d", home, getpid());
+ ifstream ip(psfile);
+ char cmd[512];
+ char arg[512];
+
+ if (!ip) {
+ cerr << "Could not read processlist " << psfile << endl;
+ return 1;
+ }
+ ip >> cmd >> arg;
+
+ if (strcmp(cmd, "#plpbackup") || strcmp(arg, "processlist")) {
+ ip.close();
+ cerr << "Error: " << psfile <<
+ " is not a process list saved with plpbackup" << endl;
+ return 1;
+ }
+ while (!ip.eof()) {
+ ip >> cmd >> arg;
+ ip.get(&arg[strlen(arg)], sizeof(arg) - strlen(arg), '\n');
+ 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 (verbose > 1)
+ cout << cmd << " " << arg << endl;
+ 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) {
+ long 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;
+ }
+ }
+ }
+ ip.close();
+ unlink(psfile);
+ return 0;
+}
+
+static void
+collectFiles(rfsv *a, char *dir) {
+ Enum<rfsv::errs> res;
+ bufferArray files;
+ char tmp[1024];
+
+ strcpy(tmp, dir);
+ strcat(tmp, "\\");
+ if ((res = a->dir(tmp, files)) != rfsv::E_PSI_GEN_NONE)
+ cerr << "Error: " << res << endl;
+ else
+ while (!files.empty()) {
+ bufferStore s;
+
+ s = files.pop();
+ long size = s.getDWord(4);
+ long attr = s.getDWord(8);
+ strcpy(tmp, dir);
+ strcat(tmp, "\\");
+ strcat(tmp, s.getString(12));
+ if (attr & rfsv::PSI_A_DIR) {
+ collectFiles(a, tmp);
+ } else {
+ if ((attr & rfsv::PSI_A_ARCHIVE) || full) {
+ s.truncate(12);
+ s.addStringT(tmp);
+ toBackup += s;
+ }
+ }
+ }
+}
+
+static int
+reportProgress(void *, long size)
+{
+ unsigned long percent;
+ char pstr[10];
+ char bstr[10];
+
+ switch (verbose) {
+ case 0:
+ return 1;
+ case 1:
+ percent = (totalBytes + size) * 100 / backupSize;
+ break;
+ case 2:
+ percent = size * 100 / fileSize;
+ break;
+ }
+ sprintf(pstr, " %3d%%", percent);
+ memset(bstr, 8, sizeof(bstr));
+ bstr[strlen(pstr)] = '\0';
+ printf("%s%s", pstr, bstr);
+ fflush(stdout);
+ return 1;
+}
+
+int
+mkdirp(char *path) {
+ char *p = strchr(path, '/');
+ while (p) {
+ char csave = *(++p);
+ *p = '\0';
+ switch (mkdir(path, S_IRWXU|S_IRWXG)) {
+ struct stat stbuf;
+
+ case 0:
+ break;
+ default:
+ if (errno != EEXIST) {
+ perror(path);
+ return 1;
+ }
+ stat(path, &stbuf);
+ if (!S_ISDIR(stbuf.st_mode)) {
+ perror(path);
+ return 1;
+ }
+ break;
+ }
+ *p++ = csave;
+ p = strchr(p, '/');
+ }
+ return 0;
+}
+
+int
+main(int argc, char **argv)
+{
+ ppsocket *skt;
+ ppsocket *skt2;
+ rfsv *a;
+ rpcs *r;
+ cpCallback_t cab = reportProgress;
+ int status = 0;
+ int sockNum = DPORT;
+ char dstPath[1024];
+ struct passwd *pw;
+ sigset_t sigset;
+
+ sigemptyset(&sigset);
+ sigaddset(&sigset, SIGPIPE);
+ sigprocmask(SIG_BLOCK, &sigset, 0L);
+
+ struct servent *se = getservbyname("psion", "tcp");
+ endservent();
+ if (se != 0L)
+ sockNum = ntohs(se->s_port);
+
+ // Command line parameter processing
+ bool parmFound;
+ do {
+ parmFound = false;
+ if ((argc > 1) && !strcmp(argv[1], "-V")) {
+ cout << "plpbackup version " << VERSION << endl;
+ exit(0);
+ }
+ if ((argc > 1) && !strcmp(argv[1], "-h")) {
+ usage(&cout);
+ exit(0);
+ }
+ if ((argc > 2) && !strcmp(argv[1], "-p")) {
+ sockNum = atoi(argv[2]);
+ argc -= 2;
+ parmFound = true;
+ for (int i = 1; i < argc; i++)
+ argv[i] = argv[i + 2];
+ }
+ if ((argc > 1) && !strcmp(argv[1], "-v")) {
+ verbose++;
+ argc -= 1;
+ parmFound = true;
+ for (int i = 1; i < argc; i++)
+ argv[i] = argv[i + 1];
+ }
+ if ((argc > 1) && !strcmp(argv[1], "-f")) {
+ full = true;
+ argc -= 1;
+ parmFound = true;
+ for (int i = 1; i < argc; i++)
+ argv[i] = argv[i + 1];
+ }
+ } while (parmFound);
+
+ pw = getpwuid(getuid());
+ if (pw && pw->pw_dir && strlen(pw->pw_dir)) {
+ time_t now = time(0);
+ char tstr[80];
+ strcpy(home, pw->pw_dir);
+ strftime(tstr, sizeof(tstr), "%Y-%m-%d-%H-%M-%S",
+ localtime(&now));
+ sprintf(dstPath, "%s/plpbackup-%s/", home, tstr);
+ } else {
+ cerr << "Could not get user's home directory from /etc/passwd" << endl;
+ exit(-1);
+ }
+
+ skt = new ppsocket();
+ if (!skt->connect(NULL, sockNum)) {
+ cerr << "plpbackup: could not connect to ncpd" << endl;
+ return 1;
+ }
+ skt2 = new ppsocket();
+ if (!skt2->connect(NULL, sockNum)) {
+ cerr << "plpbackup: 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)) {
+ Enum<rfsv::errs> res;
+ Enum<rpcs::machs> machType;
+ bool S5mx = false;
+ bool bErr = false;
+ int i;
+ unsigned long backupCount = 0;
+ char dest[1024];
+
+ r->getMachineType(machType);
+ 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;
+ }
+ }
+ if (verbose) {
+ cout << "Performing " << (full ? "Full" : "Incremental") <<
+ " backup to " << dstPath << endl;
+ cout << "Stopping programs ..." << endl;
+ }
+ killsave(r, S5mx);
+ if (argc > 1) {
+ for (i = 1; i < argc; i++) {
+ if ((strlen(argv[i]) != 2) || (argv[i][1] != ':')) {
+ usage(&cerr);
+ exit(1);
+ runrestore(a, r);
+ }
+ if (verbose)
+ cout << "Scanning Drive " << argv[i] << " ..." << endl;
+ collectFiles(a, argv[i]);
+ }
+ } else {
+ char drive[3];
+ long devbits;
+ long vtotal, vfree, vattr, vuniqueid;
+
+ if (a->devlist(devbits) == rfsv::E_PSI_GEN_NONE) {
+ for (i = 0; i < 26; i++) {
+ if ((devbits & 1) && a->devinfo(i, vfree, vtotal, vattr, vuniqueid, NULL) == rfsv::E_PSI_GEN_NONE) {
+ if (vattr != 7) {
+ sprintf(drive, "%c:\0", 'A' + i);
+ if (verbose)
+ cout << "Scanning Drive " << drive << " ..." << endl;
+ collectFiles(a, drive);
+ }
+ }
+ devbits >>= 1;
+ }
+ } else
+ cerr << "Couldn't get Drive list" << endl;
+ }
+ for (i = 0; i < toBackup.length(); i++) {
+ bufferStore s = toBackup[i];
+ backupSize += s.getDWord(4);
+ backupCount++;
+ }
+ if (verbose)
+ cout << "Size of backup: " << backupSize << " bytes in " <<
+ backupCount << " files." << endl;
+ if (backupCount == 0)
+ cerr << "Nothing to backup" << endl;
+ else {
+ for (i = 0; i < toBackup.length(); i++) {
+ bufferStore s = toBackup[i];
+ const char *fn = s.getString(12);
+ const char *p;
+ char *q;
+ char tmp[1024];
+
+ for (p = fn, q = tmp; *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';
+ strcpy(dest, dstPath);
+ strcat(dest, tmp);
+ fileSize = s.getDWord(4);
+ if (verbose > 1)
+ cout << "Backing up " << fn << flush;
+ if (mkdirp(dest) != 0) {
+ bErr = true;
+ break;
+ }
+ res = a->copyFromPsion(fn, dest, NULL, cab);
+ if (verbose > 1)
+ cout << endl;
+ totalBytes += fileSize;
+ if (res != rfsv::E_PSI_GEN_NONE) {
+ cerr << "Error during backup of " <<
+ fn << ": " << res << endl;
+ bErr = true;
+ break;
+ }
+ }
+ if (!bErr) {
+ if (verbose)
+ cout << "Writing index ..." << endl;
+ strcpy(dest, dstPath);
+ strcat(dest, ".index");
+ ofstream op(dest);
+ if (op) {
+ op << "#plpbackup index" << endl;
+ for (i = 0; i < toBackup.length(); i++) {
+ bufferStore s = toBackup[i];
+ PsiTime *t = (PsiTime *)s.getDWord(0);
+ long size = s.getDWord(4);
+ long attr = s.getDWord(8);
+ const char *fn = s.getString(12);
+ attr &= ~rfsv::PSI_A_ARCHIVE;
+ op << hex
+ << setw(8) << setfill('0') <<
+ t->getPsiTimeHi() << " "
+ << setw(8) << setfill('0') <<
+ t->getPsiTimeLo() << " "
+ << setw(8) << setfill('0') <<
+ size << " "
+ << setw(8) << setfill('0') <<
+ attr << " "
+ << setw(0) << fn << endl;
+ }
+ op.close();
+ } else {
+ cerr << "Could not write index " << dest << endl;
+ bErr = true;
+ }
+ }
+ if (!bErr) {
+ if (verbose)
+ cout << "Resetting archive attributes ..." << endl;
+ for (i = 0; i < toBackup.length(); i++) {
+ bufferStore s = toBackup[i];
+ long attr = s.getDWord(8);
+ const char *fn = s.getString(12);
+ if (attr & rfsv::PSI_A_ARCHIVE) {
+ res = a->fsetattr(fn, 0,
+ rfsv::PSI_A_ARCHIVE);
+ if (res != rfsv::E_PSI_GEN_NONE) {
+ bErr = true;
+ break;
+ }
+ }
+ }
+ }
+ }
+ if (bErr)
+ cerr << "Backup aborted due to error" << endl;
+ if (verbose)
+ cout << "Restarting programs ..." << endl;
+ runrestore(a, r);
+ delete r;
+ delete a;
+ } else {
+ if (!a)
+ cerr << "plpbackup: could not create rfsv object" << endl;
+ if (!r)
+ cerr << "plpbackup: could not create rpcs object" << endl;
+ exit(1);
+ }
+ return 0;
+}