diff options
| author | Fritz Elfert <felfert@to.com> | 2001-02-06 01:01:46 +0000 | 
|---|---|---|
| committer | Fritz Elfert <felfert@to.com> | 2001-02-06 01:01:46 +0000 | 
| commit | a9fe8f28a4a9aaf1d9b84dbc6907849ace87f66e (patch) | |
| tree | 0dd290cdf04cfd17a4ab4d0eb86bcb48137a02cb | |
| parent | a8787d39b2bf1851cdea64a5e0eccc2aff7f15de (diff) | |
| download | plptools-a9fe8f28a4a9aaf1d9b84dbc6907849ace87f66e.tar.gz plptools-a9fe8f28a4a9aaf1d9b84dbc6907849ace87f66e.tar.bz2 plptools-a9fe8f28a4a9aaf1d9b84dbc6907849ace87f66e.zip | |
- Added KDE2 PropsDialog Plugin (incomplete)
- Fixed some KDE related autoconf stuff
- Added PlpDrive class for returning results from rfsv:devinfo
- Added auto-watch in ppsocket and finally got rid of the nasty
    SIGPIPE bug. Now it's no more necessary to ignore SIGPIPE in
    applications.
- Made constructors of rfsv16, rfsv32, rpcs16 and rpcs32 private to
    enforce use of the factories.
- Removed error output in the factories and replaced that by error codes
    which can be retrieved and evaluated by an application.
47 files changed, 1741 insertions, 194 deletions
| diff --git a/Makefile.cvs b/Makefile.cvs index 753682a..9f5035e 100644 --- a/Makefile.cvs +++ b/Makefile.cvs @@ -15,13 +15,13 @@ devel: $(LIBTOOLFILES) $(AUTOMAKEFILES)  	touch include/stamp-h.in  dist: $(LIBTOOLFILES) $(AUTOMAKEFILES) -	aclocal -I conf/m4/plptools conf/m4/kde +	aclocal -I conf/m4/plptools -I conf/m4/kde  	autoheader  	automake --include-deps  	make -C kde2 -f Makefile.am am_edit  	autoconf  	touch include/stamp-h.in -	./configure +	./configure --enable-kde  	$(MAKE) dist  $(ACLOCAL): diff --git a/conf/m4/kde/KDE_CHECK_FINAL.m4 b/conf/m4/kde/KDE_CHECK_FINAL.m4 new file mode 100644 index 0000000..0624149 --- /dev/null +++ b/conf/m4/kde/KDE_CHECK_FINAL.m4 @@ -0,0 +1,30 @@ +AC_DEFUN(KDE_CHECK_FINAL, +[ +  AC_ARG_ENABLE(final, [  --enable-final          build size optimized apps (needs lots of memory)], +	kde_use_final=yes, kde_use_final=no, kde_use_final=no) + +  if test "x$kde_use_final" = "xyes"; then +      KDE_USE_FINAL_TRUE="" +      KDE_USE_FINAL_FALSE="#" +      KDE_CHECK_REPO +   else +      KDE_USE_FINAL_TRUE="#" +      KDE_USE_FINAL_FALSE="" +  fi +  AC_SUBST(KDE_USE_FINAL_TRUE) +  AC_SUBST(KDE_USE_FINAL_FALSE) + +  AC_ARG_ENABLE(closure, [  --disable-closure       don't delay template instantiation], +  	kde_use_closure=$enableval, kde_use_closure=yes) + +  if test "x$kde_use_closure" = "xyes"; then +       KDE_USE_CLOSURE_TRUE="" +       KDE_USE_CLOSURE_FALSE="#" +#       CXXFLAGS="$CXXFLAGS $REPO" +  else +       KDE_USE_CLOSURE_TRUE="#" +       KDE_USE_CLOSURE_FALSE="" +  fi +  AC_SUBST(KDE_USE_CLOSURE_TRUE) +  AC_SUBST(KDE_USE_CLOSURE_FALSE) +]) diff --git a/conf/m4/plptools/PLP_CHECK_COMPILERS.m4 b/conf/m4/plptools/PLP_CHECK_COMPILERS.m4 index bd61ed2..40eb216 100644 --- a/conf/m4/plptools/PLP_CHECK_COMPILERS.m4 +++ b/conf/m4/plptools/PLP_CHECK_COMPILERS.m4 @@ -79,11 +79,13 @@ dnl this was AC_PROG_CC. I had to include it manualy, since I had to patch it    if test "$ac_use_debug_code" = "no"; then    	if test -z "$LDFLAGS" && test "$GCC" = "yes"; then  		LDFLAGS="-s" +		LIBDEBUG=""  	fi    else    	AC_DEFINE_UNQUOTED(DEBUG) +	LIBDEBUG="--debug"    fi - +  AC_SUBST(LIB_DEBUG)  dnl this is AC_PROG_CPP. I had to include it here, since autoconf checks  dnl dependecies between AC_PROG_CPP and AC_PROG_CC (or is it automake?) diff --git a/conf/m4/plptools/PLP_SET_LIBVERSION.m4 b/conf/m4/plptools/PLP_SET_LIBVERSION.m4 new file mode 100644 index 0000000..8c03f03 --- /dev/null +++ b/conf/m4/plptools/PLP_SET_LIBVERSION.m4 @@ -0,0 +1,9 @@ +AC_DEFUN(PLP_SET_LIBVERSION, +	[ +		AC_REQUIRE([AM_INIT_AUTOMAKE]) +		maj=$(echo ${VERSION} | cut -d. -f1) +		min=$(echo ${VERSION} | cut -d. -f2) +		LIBVERSION=${maj}:${min}:${maj} +		AC_SUBST(LIBVERSION) +	] +) diff --git a/configure.in b/configure.in index b391e48..bbe1dd5 100644 --- a/configure.in +++ b/configure.in @@ -6,6 +6,7 @@ AC_CANONICAL_SYSTEM  AM_CONFIG_HEADER(include/config.h)  AM_INIT_AUTOMAKE(plptools, 0.7)  AM_PROG_LIBTOOL +PLP_SET_LIBVERSION  dnl Enable Maintainer stuff  AM_MAINTAINER_MODE @@ -214,6 +215,7 @@ PLP_HELP_MSG([Options, only needed when building KDE2 stuff:])  if test "x$ac_enable_kde" = "xyes" ; then  	AC_PATH_KDE  	AC_CHECK_KDEMAXPATHLEN +	KDE_CHECK_FINAL  	AM_CONDITIONAL(BUILD_KDE, true)  fi @@ -225,6 +227,9 @@ AC_OUTPUT(  	plpnfsd/Makefile  	kde2/Makefile  	kde2/kioslave/Makefile +	kde2/plugins/Makefile +	kde2/mime/Makefile +	kde2/mime/icons/Makefile  	plpbackup/Makefile  	doc/Makefile  	doc/api/Makefile diff --git a/kde2/Makefile.am b/kde2/Makefile.am index fe79aad..c1186d6 100644 --- a/kde2/Makefile.am +++ b/kde2/Makefile.am @@ -1,9 +1,8 @@  # $Id$  # -SUBDIRS = kioslave +SUBDIRS = kioslave plugins mime -TMPDEST=  #  # remove all intermediate files that can be recreated using  # Makefile.cvs diff --git a/kde2/kioslave/Makefile.am b/kde2/kioslave/Makefile.am index 1b573d9..b527f09 100644 --- a/kde2/kioslave/Makefile.am +++ b/kde2/kioslave/Makefile.am @@ -1,26 +1,18 @@ -## Makefile.am of kdebase/kioslave/plp +# $Id$  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) +kio_plp_la_LDFLAGS = -module -avoid-version  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 +kio_plp_la_LIBADD = -L$(top_srcdir)/lib -lplp $(LIB_KIO) -METASOURCES = AUTO +noinst_HEADERS = kio_plp.h -bin_SCRIPTS =  +services_DATA = psion.protocol +servicesdir = $(kde_servicesdir) -endif +EXTRA_DIST = $(services_DATA) diff --git a/kde2/kioslave/kio_plp.cpp b/kde2/kioslave/kio_plp.cpp index e0464bd..4b9fb49 100644 --- a/kde2/kioslave/kio_plp.cpp +++ b/kde2/kioslave/kio_plp.cpp @@ -144,14 +144,6 @@ PLPProtocol::PLPProtocol (const QCString &pool, const QCString &app)  		sscanf(uit.key().data(), "uid-%08X-%08X-%08X", &u1, &u2, &u3);  		puids.insert(PlpUID(u1, u2, u3), uit.data());  	} -#if 0 -	cout << "uids:" << endl; -	for (UidMap::Iterator it = puids.begin(); it != puids.end(); it++) { -		cout << "UID: " << hex << setw(8) << setfill('0') << it.key().uid[0] -		     << it.key().uid[1] << it.key().uid[2] << dec << "->" << -			 it.data() << endl; -	} -#endif  }  PLPProtocol::~PLPProtocol() { @@ -218,20 +210,20 @@ openConnection() {  	plpRfsvSocket = new ppsocket();  	if (!plpRfsvSocket->connect((char *)(currentHost.data()), currentPort)) { -		error(ERR_COULD_NOT_CONNECT, i18n("Could not connect to ncpd")); +		QString tmp = i18n("Could not connect to ncpd at %1:%2").arg(currentHost).arg(currentPort); +		error(ERR_COULD_NOT_CONNECT, tmp);  		return;  	}  	rfsvfactory factory(plpRfsvSocket);  	plpRfsv = factory.create(false); -	if (plpRfsv == 0) { -		error(ERR_COULD_NOT_CONNECT, i18n("Could not read version info")); +	if (plpRfsv == 0L) { +		error(ERR_COULD_NOT_CONNECT, i18n("Could not read version info."));  		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); @@ -252,12 +244,10 @@ openConnection() {  	if ((res = plpRfsv->devlist(devbits)) == rfsv::E_PSI_GEN_NONE) {  		for (int i = 0; i < 26; i++) { -			string vname; -			u_int32_t vtotal, vfree, vattr, vuniqueid; -  			if ((devbits & 1) != 0) { -				if (plpRfsv->devinfo(i, vfree, vtotal, vattr, vuniqueid, -						     vname) == rfsv::E_PSI_GEN_NONE) { +				PlpDrive drive; +				if (plpRfsv->devinfo(i, drive) == rfsv::E_PSI_GEN_NONE) { +					string vname = drive.getName();  					QString name;  					if (!vname.empty()) @@ -374,17 +364,21 @@ createVirtualDirEntry(UDSEntry & entry, bool rdonly) {  	atom.m_uds = KIO::UDS_FILE_TYPE;  	atom.m_long = S_IFDIR; -	entry.append( atom ); +	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 ); +	entry.append(atom);  	atom.m_uds = KIO::UDS_SIZE;  	atom.m_long = 0; -	entry.append( atom ); +	entry.append(atom); + +	//atom.m_uds = KIO::UDS_MIME_TYPE; +	//atom.m_str = QString("inode/x-psion-drive"); +	//entry.append(atom);  }  bool PLPProtocol:: @@ -506,7 +500,7 @@ completeUDSEntry(UDSEntry& entry, PlpDirent &e, bool rom) {  	atom.m_long = (attr & rfsv::PSI_A_DIR) ? S_IFDIR : S_IFREG;  	entry.append(atom); -#if 1 +#if 0  	KIO::UDSEntry::ConstIterator it = entry.begin();  	for( ; it != entry.end(); it++ ) {  		switch ((*it).m_uds) { @@ -891,3 +885,68 @@ copy( const KURL &src, const KURL &dest, int _mode, bool _overwrite ) {  		return;  	finished();  } + +void PLPProtocol:: +special(const QByteArray &a) { +	kdDebug(PLP_DEBUGAREA) << "special()" << endl; + +	QDataStream stream(a, IO_ReadOnly); +	int tmp; +	UDSEntry entry; +	UDSAtom atom; + +	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; +	} +	finished(); +} diff --git a/kde2/kioslave/kio_plp.h b/kde2/kioslave/kio_plp.h index c17436e..6768e10 100644 --- a/kde2/kioslave/kio_plp.h +++ b/kde2/kioslave/kio_plp.h @@ -52,6 +52,7 @@ public:  	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);  private: diff --git a/kde2/mime/Makefile.am b/kde2/mime/Makefile.am new file mode 100644 index 0000000..4f52cb1 --- /dev/null +++ b/kde2/mime/Makefile.am @@ -0,0 +1,27 @@ +# $Id$ +# + +SUBDIRS = icons + +EXTRA_DIST = $(wildcard *.desktop) + +maintainer-clean-local: +	rm -f Makefile.in + +devmimedir = $(kde_mimedir)/inode +devmime_DATA = x-psion-drive.desktop + +appmimedir = $(kde_mimedir)/application +appmime_DATA = \ +	x-psion-agenda.desktop \ +	x-psion-backlite.desktop \ +	x-psion-comms.desktop \ +	x-psion-data.desktop \ +	x-psion-encryptit.desktop \ +	x-psion-opl.desktop \ +	x-psion-opo.desktop \ +	x-psion-record.desktop \ +	x-psion-record2.desktop \ +	x-psion-sheet.desktop \ +	x-psion-sketch.desktop \ +	x-psion-word.desktop diff --git a/kde2/mime/icons/Makefile.am b/kde2/mime/icons/Makefile.am index 2dffabc..1f5f243 100644 --- a/kde2/mime/icons/Makefile.am +++ b/kde2/mime/icons/Makefile.am @@ -5,3 +5,5 @@ maintainer-clean-local:  	rm -f Makefile.in  KDE_ICON = AUTO + +EXTRA_DIST = $(wildcard *.png) diff --git a/kde2/mime/x-psion-drive.desktop b/kde2/mime/x-psion-drive.desktop new file mode 100644 index 0000000..d3b350c --- /dev/null +++ b/kde2/mime/x-psion-drive.desktop @@ -0,0 +1,7 @@ +[Desktop Entry] +Comment=Psion Drive +Comment[de]=Psion Laufwerk +Icon=psion_drive +Type=MimeType +MimeType=inode/x-psion-drive +Patterns= diff --git a/kde2/plugins/.cvsignore b/kde2/plugins/.cvsignore new file mode 100644 index 0000000..fcada82 --- /dev/null +++ b/kde2/plugins/.cvsignore @@ -0,0 +1,4 @@ +*.closure +*.moc +Makefile.in +Makefile diff --git a/kde2/plugins/Makefile.am b/kde2/plugins/Makefile.am new file mode 100644 index 0000000..9ef736d --- /dev/null +++ b/kde2/plugins/Makefile.am @@ -0,0 +1,26 @@ + +AM_CPPFLAGS = -DQT_NO_CAST_ASCII + +INCLUDES = $(all_includes) -I$(top_srcdir)/lib +LDFLAGS  = $(all_libraries) $(KDE_RPATH) + +libplpprops_la_LDFLAGS = $(LIBDEBUG) $(all_libraries) -module -no-undefined -version-info $(LIBVERSION) + +METASOURCES = AUTO + +lib_LTLIBRARIES = libplpprops.la + +libplpprops_la_SOURCES = plpprops.cc plppropsFactory.cc pie3dpiece.cpp \ +	pie3dwidget.cpp +libplpprops_la_LIBADD = -L$(top_srcdir)/lib -lplp $(LIB_KIO) $(LIB_KFILE) +noinst_HEADERS = plpprops.h plppropsFactory.h pie3dpiece.h pie3dwidget.h + +services_DATA = plpprops.desktop +servicesdir = $(kde_servicesdir) + +# +# remove all intermediate files that can be recreated using +# Makefile.cvs +# +maintainer-clean-local: +	rm -f Makefile.in *.closure diff --git a/kde2/plugins/pie3dpiece.cpp b/kde2/plugins/pie3dpiece.cpp new file mode 100644 index 0000000..19c98b9 --- /dev/null +++ b/kde2/plugins/pie3dpiece.cpp @@ -0,0 +1,30 @@ +/* + *  This file is part of the KDE System Control Tool, + *  Copyright (C)1999 Thorsten Westheider <twesthei@physik.uni-bielefeld.de> + * + *  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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + ****************************************************************************/ + +#include "pie3dpiece.h" + + +Pie3DPiece::Pie3DPiece(int size, const QColor& color) : _size(size), +							_color(color) +{ + +} + + diff --git a/kde2/plugins/pie3dpiece.h b/kde2/plugins/pie3dpiece.h new file mode 100644 index 0000000..b64fe2a --- /dev/null +++ b/kde2/plugins/pie3dpiece.h @@ -0,0 +1,45 @@ +/* + *  This file is part of the KDE System Control Tool, + *  Copyright (C)1999 Thorsten Westheider <twesthei@physik.uni-bielefeld.de> + * + *  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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + ****************************************************************************/ + +#ifndef __PIE3DPIECE_H +#define __PIE3DPIECE_H + +#include <qcolor.h> + + +class Pie3DPiece +{ +  public: +   +    Pie3DPiece(int size, const QColor&); +    Pie3DPiece() {} +     +          int      size()  const { return _size;  } +    const QColor&  color() const { return _color; } +     +  private: +   +    int     _size; +    QColor  _color; +}; + + +#endif + diff --git a/kde2/plugins/pie3dwidget.cpp b/kde2/plugins/pie3dwidget.cpp new file mode 100644 index 0000000..72a4578 --- /dev/null +++ b/kde2/plugins/pie3dwidget.cpp @@ -0,0 +1,120 @@ +/* + *  This file is part of the KDE System Control Tool, + *  Copyright (C)1999 Thorsten Westheider <twesthei@physik.uni-bielefeld.de> + * + *  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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *  Pie3DWidget was inspired by Christian Poulter's KDiskFree + *  + ****************************************************************************/ + +#include <qpainter.h> + +#include "pie3dwidget.h" + + +Pie3DWidget::Pie3DWidget(QWidget *parent, const char *name) : QWidget(parent, name), +                         				      _totalsize(0) +{ +  _piecelist.setAutoDelete(true); +  _piecelist.clear(); +} + + +void  Pie3DWidget::addPiece(int size, const QColor& color) +{ +  _totalsize += size; + +  _piecelist.append(new Pie3DPiece(size, color)); +   +  repaint(); +}  + + +int  Pie3DWidget::heightForWidth(int w) const +{ +  return (int) (w*0.6); +} + + +QSize  Pie3DWidget::minimumSizeHint() const +{ +  return QSize(60, 40); +} + + +QSize  Pie3DWidget::sizeHint() const +{ +  return QSize(width(), width()*0.6); +} + + +/* + * Protected methods + ********************/ +  +void  Pie3DWidget::paintEvent(QPaintEvent *ev) +{ +  QPainter  p; +  QColor    widgetbg = palette().normal().background(); +  QColor    black    = QColor(black); +  int       w        = width(); +  int       h        = height(); +  int       pieh     = h/4; +  int       halfrot  = 180*16; +  int       fullrot  = 360*16; +  int       bowpos   = 0; +  int       i, bowlen, bowcut; +   +  if (_piecelist.isEmpty()) return; +   +  p.begin(this); +  p.setClipRegion(ev->region()); +   +  for (Pie3DPiece *piece = _piecelist.first(); piece; piece = _piecelist.next()) +  { +    QPalette  piecepal(piece->color(), widgetbg); + +    bowlen = (int) (((double) piece->size())/_totalsize*fullrot); +     +    p.setPen((_piecelist.count() > 1) ? black : _piecelist.first()->color()); +    p.setBrush(piecepal.normal().button()); +    p.drawPie(0, 0, w, h-pieh, bowpos, bowlen); +     +    if (bowpos+bowlen >= halfrot)	// Part of the footer is visible +    { +      bowcut  = (bowpos < halfrot) ? halfrot-bowpos : 0; +      bowpos += bowcut; +      bowlen -= bowcut; +       +      p.setPen(piecepal.normal().mid()); +     +      for (i = 0; i < pieh; i++) p.drawArc(0, i, w, h-pieh, bowpos, bowlen); +    } +     +    bowpos += bowlen; +  } +    +  p.setPen(black);   +     +  p.drawArc(0,    0,          w,   h-pieh, 0,  fullrot);   +  p.drawArc(0,    pieh-1,     w,   h-pieh, 0, -halfrot);   +   +  p.drawLine(0,   (h-pieh)/2, 0,   (h+pieh)/2-1);    +  p.drawLine(w-1, (h-pieh)/2, w-1, (h+pieh)/2-1);    +   +  p.end(); +} + diff --git a/kde2/plugins/pie3dwidget.h b/kde2/plugins/pie3dwidget.h new file mode 100644 index 0000000..cda0868 --- /dev/null +++ b/kde2/plugins/pie3dwidget.h @@ -0,0 +1,56 @@ +/* + *  This file is part of the KDE System Control Tool, + *  Copyright (C)1999 Thorsten Westheider <twesthei@physik.uni-bielefeld.de> + * + *  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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *  Pie3DWidget was inspired by Christian Poulter's KDiskFree + *  + ****************************************************************************/ + +#ifndef __PIE3DWIDGET_H +#define __PIE3DWIDGET_H + +#include <qwidget.h> +#include <qlist.h> + +#include "pie3dpiece.h" + + +class Pie3DWidget : public QWidget +{ +  public: +   +    Pie3DWidget(QWidget *parent = 0L, const char *name = 0L); +    ~Pie3DWidget() {} +     +            void   addPiece(int size, const QColor&); +             +    virtual int    heightForWidth(int w) const; +    virtual QSize  minimumSizeHint()     const; +    virtual QSize  sizeHint()            const; +   +  protected: +   +    virtual void   paintEvent(QPaintEvent *); +     +  private: +   +    int                _totalsize; +    QList<Pie3DPiece>  _piecelist; +}; + + +#endif diff --git a/kde2/plugins/plpprops.cc b/kde2/plugins/plpprops.cc new file mode 100644 index 0000000..bd4a2f5 --- /dev/null +++ b/kde2/plugins/plpprops.cc @@ -0,0 +1,441 @@ +#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 <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 "plpprops.h" +#include "pie3dwidget.h" + +#include <qobjectlist.h> +#include <qtabwidget.h> + +#define KIO_ARGS QByteArray packedArgs; \ +QDataStream stream( packedArgs, IO_WriteOnly ); stream + +class PlpPropsPlugin::PlpPropsPluginPrivate { +public: +	PlpPropsPluginPrivate() { } +	~PlpPropsPluginPrivate() { } + +	QFrame *m_frame; +}; + +/* + * A VERY UGLY HACK for removing the Permissions-Page from + * 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"); +	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. +	// +	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); +	} +} + +PlpPropsPlugin::PlpPropsPlugin(KPropertiesDialog *_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()); +} + +PlpPropsPlugin::~PlpPropsPlugin() { +	delete d; +} + +bool PlpPropsPlugin::supports(KFileItemList _items) { +	for (KFileItemListIterator it(_items); it.current(); ++it) { +		KFileItem *fi = it.current(); + +		if (fi->url().protocol() != QString::fromLatin1("psion")) +			return false; +	} +	return true; +} + +void PlpPropsPlugin::applyChanges() { +	kdDebug(250) << "PlpFileAttrPlugin::applyChanges" << endl; +} + +void PlpPropsPlugin::postApplyChanges() { +} + +class PlpFileAttrPage::PlpFileAttrPagePrivate { +public: +	PlpFileAttrPagePrivate() { } +	~PlpFileAttrPagePrivate() { } + +	QFrame *m_frame; +}; + +PlpFileAttrPage::PlpFileAttrPage(KPropertiesDialog *_props) +	: KPropsDlgPlugin( _props ) { +	d = new PlpFileAttrPagePrivate; +	d->m_frame = properties->dialog()->addPage(i18n("Psion &Attributes")); +} + +PlpFileAttrPage::~PlpFileAttrPage() { +	delete d; +} + +bool PlpFileAttrPage::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; +	} +	return true; +} + +void PlpFileAttrPage::applyChanges() { +} + +class PlpDriveAttrPage::PlpDriveAttrPagePrivate { +public: +	PlpDriveAttrPagePrivate() { } +	~PlpDriveAttrPagePrivate() { } + +	QFrame *m_frame; +}; + +PlpDriveAttrPage::PlpDriveAttrPage(KPropertiesDialog *_props) +	: KPropsDlgPlugin( _props ) { + +	d = new PlpDriveAttrPagePrivate; +	d->m_frame = properties->dialog()->addPage(i18n("Psion &Drive")); + +	QBoxLayout *box = new QVBoxLayout( d->m_frame, KDialog::spacingHint() ); +	QLabel *l; +	QGridLayout *gl; + +	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 *))); + + +	long total = 33267; +	long free = 12345; + +	gb = new QGroupBox(i18n("Information"), d->m_frame); +	box->addWidget(gb); + +	gl = new QGridLayout(gb, 7, 4, 15); +	gl->addRowSpacing(0, 10); + +	l = new QLabel(i18n("Type"), gb); +	gl->addWidget(l, 1, 0); + +	typeLabel = new QLabel(gb); +	gl->addWidget(typeLabel, 2, 0); + +	l = new QLabel(i18n("Total capacity"), gb); +	gl->addWidget (l, 1, 1); + +	totalLabel = new QLabel(gb); +	gl->addWidget(totalLabel, 2, 1); + +	l = new QLabel(i18n("Free space"), gb); +	gl->addWidget (l, 1, 2); + +	freeLabel = new QLabel(gb); +	gl->addWidget(freeLabel, 2, 2); + +	l = new QLabel(i18n("Unique ID"), gb); +	gl->addWidget (l, 1, 3); + +	uidLabel = new QLabel(gb); +	gl->addWidget(uidLabel, 2, 3); + +	pie = new Pie3DWidget(gb, "pie"); + +	gl->addMultiCellWidget(pie, 3, 4, 1, 2); + +	l = new QLabel(i18n("Used space"), gb); +	gl->addWidget (l, 5, 2); +	 +	l = new QLabel(i18n(" "), gb); +	l->setBackgroundColor(QColor(219, 58, 197)); +	gl->addWidget (l, 5, 3); + +	l = new QLabel(i18n("Free space"), gb); +	gl->addWidget (l, 6, 2); + +	l = new QLabel(i18n(" "), gb); +	l->setBackgroundColor(QColor(39, 56, 167)); + +	gl->addWidget (l, 6, 3); + +	box->addStretch(10); +} + +PlpDriveAttrPage::~PlpDriveAttrPage() { +	delete d; +} + +bool PlpDriveAttrPage::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; +	} +	return true; +} + +void PlpDriveAttrPage::applyChanges() { +} + +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, QColor(219, 58, 197)); +			pie->addPiece(unused, QColor(39, 56, 167)); +		} +	} +} + +class PlpMachinePage::PlpMachinePagePrivate { +public: +	PlpMachinePagePrivate() { } +	~PlpMachinePagePrivate() { } + +	QFrame *m_frame; +}; + +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); + +	mainlayout->addStretch(2); +} + +PlpMachinePage::~PlpMachinePage() { +	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; +} + +void PlpMachinePage::applyChanges() { +} + + +class PlpOwnerPage::PlpOwnerPagePrivate +{ +public: +	PlpOwnerPagePrivate()	{ } +	~PlpOwnerPagePrivate() { } + +	QFrame *m_frame; +}; + +PlpOwnerPage::PlpOwnerPage( KPropertiesDialog *_props ) : KPropsDlgPlugin( _props ) { +	d = new PlpOwnerPagePrivate; +	d->m_frame = properties->dialog()->addPage(i18n("Psion &Owner")); +} + +PlpOwnerPage::~PlpOwnerPage() { +	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; +	} +	return true; +} + +void PlpOwnerPage::applyChanges() { +} + +#include "plpprops.moc" diff --git a/kde2/plugins/plpprops.desktop b/kde2/plugins/plpprops.desktop new file mode 100644 index 0000000..9fc8b2f --- /dev/null +++ b/kde2/plugins/plpprops.desktop @@ -0,0 +1,40 @@ +[Desktop Entry] +Type=Service +X-KDE-Library=libplpprops +Name=Psion Property Dialog Plugin +ServiceTypes=KPropsDlg/Plugin,all/all +Comment=Plugin for the Properties Dialog +Comment[ca]=Endollat pel diàleg de propietats +Comment[cs]=Modul pro dialog vlastností +Comment[da]=Plugin til egenskabsdialog +Comment[de]=Plugin für den Eigenschaften-Dialog +Comment[el]=Πρόσθετο για το Διάλογο Ιδιοτήτων +Comment[eo]=Internaĵo por la Eco-dialogo +Comment[es]=Plugin para el Diálogo de Propiedades +Comment[et]=Plugina omaduste dialoog +Comment[fi]=Sovelma asetusikkunalle +Comment[fr]=Module pour la boîte de dialogue des Propriétés +Comment[gl]=Plugin para o Diálogo de Propiedades +Comment[he]=םינייפאמה חיש-ודל עקת ןקתה +Comment[hu]=Beépülő modul a tulajdonságok párbeszédablakhoz +Comment[is]=Íhlutur fyrir stillingarforritið +Comment[it]=Plugin per la finestra delle proprietà +Comment[ja]=設定ダイアログプラグイン +Comment[mk]=Плагин за дијалогот за параметри +Comment[nl]=Plugin voor het 'Eigenschappen'dialoog +Comment[no]=Plugginn for egenskaper-dialogen +Comment[no_NY]=Tillegg til eigenskapar-dialogen +Comment[pl]=Wtyczka do Dialogu Właściwości +Comment[pt]='Plugin' para o diálogo de propriedades +Comment[pt_BR]=Plug-in para a janela de Propriedades +Comment[ro]=Modul pentru dialogul de proprietăţi +Comment[ru]=Модуль для диалога настроек +Comment[sk]=Zásuvný modul pre panel Nastavení +Comment[sl]=Vstavek za pogovorno okno z lastnostmi +Comment[sr]=Plugin za dijalog sa svojstvima +Comment[sv]=Insticksprogram för egenskapsdialogen +Comment[ta]=¦º¡òÐì¸û ¯¨Ã¡¼Öì¸¡É ¦ºÕ¸ø +Comment[tr]=Özellikler İletişim Kutusu İçin Eklenti +Comment[uk]=Додаток для діалогу властивостей +Comment[zh_CN.GB2312]=属性对话的插件 +Comment[zh_TW.Big5]=外掛內容對話框 diff --git a/kde2/plugins/plpprops.h b/kde2/plugins/plpprops.h new file mode 100644 index 0000000..86f3514 --- /dev/null +++ b/kde2/plugins/plpprops.h @@ -0,0 +1,144 @@ +/* $Id$ + * + * 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 <kurl.h> +#include <kfileitem.h> +#include <kdialogbase.h> +#include <kpropsdlg.h> + +#include "pie3dwidget.h" + +namespace KIO { class Job; } + +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; +}; + +class PlpFileAttrPage : public KPropsDlgPlugin { +	Q_OBJECT + public: +	/** +	 * Constructor +	 */ +	PlpFileAttrPage(KPropertiesDialog *_props); +	virtual ~PlpFileAttrPage(); + +	virtual void applyChanges(); + +	static bool supports(KFileItemList _items); + + 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; +	Pie3DWidget *pie; +}; + + +/** + * Used to view/edit 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; +}; + +/** + * Used to view/edit 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; +}; + +#endif diff --git a/kde2/plugins/plppropsFactory.cc b/kde2/plugins/plppropsFactory.cc new file mode 100644 index 0000000..2c553cf --- /dev/null +++ b/kde2/plugins/plppropsFactory.cc @@ -0,0 +1,37 @@ +#include "plppropsFactory.h" +#include "plpprops.h" + +#include <stream.h> +#include <kdebug.h> +#include <klocale.h> + +extern "C" { +	void *init_libplpprops() { +		return new plppropsFactory(); +	} +}; + +plppropsFactory::plppropsFactory(QObject *parent, const char *name) +	: KLibFactory(parent, name) { +	s_global = new KInstance("plpprops"); +	// Install the translations +	//KGlobal::locale()->insertCatalogue("plpprops"); +} + +plppropsFactory::~plppropsFactory() { +	delete s_global; +} + +QObject* plppropsFactory::createObject(QObject* parent, const char *name, const char *classname, const QStringList & ) { + +	QObject *obj = 0L; + +	cout << "plppropsFactory: name=" << name << " class=" << classname << endl; +	if ((strcmp(classname, "KPropsDlgPlugin") == 0) && +	    parent && +	    parent->inherits("KPropertiesDialog")) +		obj = new PlpPropsPlugin(static_cast<KPropertiesDialog *>(parent)); +	return obj; +} + +#include <plppropsFactory.moc> diff --git a/kde2/plugins/plppropsFactory.h b/kde2/plugins/plppropsFactory.h new file mode 100644 index 0000000..1226560 --- /dev/null +++ b/kde2/plugins/plppropsFactory.h @@ -0,0 +1,19 @@ +#ifndef _PLPPROPSFACTORY_H_ +#define _PLPPROPSFACTORY_H_ + +#include <klibloader.h> + +class plppropsFactory : public KLibFactory { +	Q_OBJECT + public: +	plppropsFactory(QObject *parent = 0, const char *name = 0); +	virtual ~plppropsFactory(); + +	virtual QObject* createObject(QObject* parent = 0, const char* name = 0, const char* classname = "QObject", const QStringList &args = QStringList()); + + private: +	KInstance *s_global; + +}; + +#endif diff --git a/lib/Makefile.am b/lib/Makefile.am index 367fbb7..7e56949 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -2,7 +2,8 @@  #  lib_LTLIBRARIES = libplp.la -libplp_la_LDFLAGS = --debug -version-info 1:1:0 +libplp_la_LDFLAGS = $(LIBDEBUG) -version-info $(LIBVERSION) +  libplp_la_SOURCES = bufferarray.cc  bufferstore.cc iowatch.cc ppsocket.cc \  	rfsv16.cc rfsv32.cc rfsvfactory.cc log.cc rfsv.cc rpcs32.cc rpcs16.cc \  	rpcs.cc rpcsfactory.cc psitime.cc Enum.cc plpdirent.cc diff --git a/lib/plpdirent.cc b/lib/plpdirent.cc index 33e1a78..9695480 100644 --- a/lib/plpdirent.cc +++ b/lib/plpdirent.cc @@ -83,3 +83,141 @@ operator<<(ostream &o, const PlpDirent &e) {  	o.flags(old);  	return o;  } + +PlpDrive::PlpDrive() { +} + +PlpDrive::PlpDrive(const PlpDrive &other) { +} + +void PlpDrive:: +setMediaType(u_int32_t type) { +	mediatype = type; +} + +void PlpDrive:: +setDriveAttribute(u_int32_t attr) { +	driveattr = attr; +} + +void PlpDrive:: +setMediaAttribute(u_int32_t attr) { +	mediaattr = attr; +} + +void PlpDrive:: +setUID(u_int32_t attr) { +	uid = attr; +} + +void PlpDrive:: +setSize(u_int32_t sizeLo, u_int32_t sizeHi) { +	size = ((unsigned long long)sizeHi << 32) + sizeLo; +} + +void PlpDrive:: +setSpace(u_int32_t spaceLo, u_int32_t spaceHi) { +	space = ((unsigned long long)spaceHi << 32) + spaceLo; +} + +void PlpDrive:: +setName(char drive, const char * const volname) { +	drivechar = drive; +	name = ""; +	name += volname; +} + +u_int32_t PlpDrive:: +getMediaType() { +	return mediatype; +} + +static const char * const media_types[] = { +	"Not present", +	"Unknown", +	"Floppy", +	"Disk", +	"CD-ROM", +	"RAM", +	"Flash Disk", +	"ROM", +	"Remote", +}; + +void PlpDrive:: +getMediaType(string &ret) { +	ret = media_types[mediatype]; +} + +u_int32_t PlpDrive:: +getDriveAttribute() { +	return driveattr; +} + +static void +appendWithDelim(string &s1, const char * const s2) { +	if (!s1.empty()) +		s1 += ','; +	s1 += s2; +} + +void PlpDrive:: +getDriveAttribute(string &ret) { +	ret = ""; +	if (driveattr & 1) +		appendWithDelim(ret, "local"); +	if (driveattr & 2) +		appendWithDelim(ret, "ROM"); +	if (driveattr & 4) +		appendWithDelim(ret, "redirected"); +	if (driveattr & 8) +		appendWithDelim(ret, "substituted"); +	if (driveattr & 16) +		appendWithDelim(ret, "internal"); +	if (driveattr & 32) +		appendWithDelim(ret, "removable"); +} + +u_int32_t PlpDrive:: +getMediaAttribute() { +	return mediaattr; +} + +void PlpDrive:: +getMediaAttribute(string &ret) { +	ret = ""; + +	if (mediaattr & 1) +		appendWithDelim(ret, "variable size"); +	if (mediaattr & 2) +		appendWithDelim(ret, "dual density"); +	if (mediaattr & 4) +		appendWithDelim(ret, "formattable"); +	if (mediaattr & 8) +		appendWithDelim(ret, "write protected"); +} + +u_int32_t PlpDrive:: +getUID() { +	return uid; +} + +u_int64_t PlpDrive:: +getSize() { +	return size; +} + +u_int64_t PlpDrive:: +getSpace() { +	return space; +} + +string PlpDrive:: +getName() { +	return name; +} + +char PlpDrive:: +getDrivechar() { +	return drivechar; +} diff --git a/lib/plpdirent.h b/lib/plpdirent.h index 9a25a67..c567a9b 100644 --- a/lib/plpdirent.h +++ b/lib/plpdirent.h @@ -157,4 +157,168 @@ private:  	string  attrstr;  	string  name;  }; + +/** + * A class representing information about + * a Disk drive on the psion. An Object of this type + * is used by @ref rfsv::devinfo for returning the + * information of the probed drive. + * + * @author Fritz Elfert <felfert@to.com> + */ +class PlpDrive { +	friend rfsv32; +	friend rfsv16; + + public: +	/** +	 * Default constructor. +	 */ +	PlpDrive(); + +	/** +	 * Copy constructor +	 */ +	PlpDrive(const PlpDrive &other); + +	/** +	 * Retrieve the media type of the drive. +	 * +	 * @returns The media type of the probed drive. +	 * <pre> +	 * Media types are encoded by a number +         * in the range 0 .. 8 with the following +	 * meaning: +	 * +	 *   0 = Not present +	 *   1 = Unknown +	 *   2 = Floppy +	 *   3 = Disk +	 *   4 = CD-ROM +	 *   5 = RAM +	 *   6 = Flash Disk +	 *   7 = ROM +	 *   8 = Remote +	 * </pre> +	 */ +	u_int32_t getMediaType(); + +	/** +	 * Retrieve the media type of the drive. +	 * Just like the above function, but returns +	 * the media type as human readable string. +	 * +	 * @param ret The string is returned here. +	 */ +	void getMediaType(string &ret); + +	/** +	 * Retrieve the attributes of the drive. +	 * +	 * @returns The attributes of the probed drive. +	 * <pre> +	 * Drive attributes are encoded by a number +	 * in the range 0 .. 63. The bits have the +	 * the following meaning: +	 * +	 *   bit 0 = local +	 *   bit 1 = ROM +	 *   bit 2 = redirected +	 *   bit 3 = substituted +	 *   bit 4 = internal +	 *   bit 5 = removable +	 * </pre> +	 */ +	u_int32_t getDriveAttribute(); + +	/** +	 * Retrieve the attributes of the drive. +	 * Just like the above function, but returns +	 * the attributes as human readable string. +	 * +	 * @param ret The string is returned here. +	 */ +	void getDriveAttribute(string &ret); + +	/** +	 * Retrieve the attributes of the media. +	 * +	 * @returns The attributes of the probed media. +	 * <pre> +	 * Media attributes are encoded by a number +	 * in the range 0 .. 15. The bits have the +	 * following meaning: +	 * +	 *   bit 0 = variable size +	 *   bit 1 = dual density +	 *   bit 2 = formattable +	 *   bit 3 = write protected +	 * </pre> +	 */ +	u_int32_t getMediaAttribute(); + +	/** +	 * Retrieve the attributes of the media. +	 * Just like the above function, but returns +	 * the attributes as human readable string. +	 * +	 * @param ret The string is returned here. +	 */ +	void getMediaAttribute(string &ret); + +	/** +	 * Retrieve the UID of the drive. +	 * Each drive, except the ROM drive on a Psion has +	 * a unique ID which can be retrieved here. +	 * +	 * @returns The UID of the probed drive. +	 */ +	u_int32_t getUID(); + +	/** +	 * Retrieve the total capacity of the drive. +	 * +	 * @returns The capacity of the probed drive in bytes. +	 */ +	u_int64_t getSize(); + +	/** +	 * Retrieve the free capacity on the drive. +	 * +	 * @returns The free space on the probed drive in bytes. +	 */ +	u_int64_t getSpace(); + +	/** +	 * Retrieve the volume name of the drive. +	 * +	 * returns The volume name of the drive. +	 */ +	string getName(); + +	/** +	 * Retrieve the drive letter of the drive. +	 * +	 * returns The letter of the probed drive. +	 */ +	char getDrivechar(); + + private: +	void setMediaType(u_int32_t type); +	void setDriveAttribute(u_int32_t attr); +	void setMediaAttribute(u_int32_t attr); +	void setUID(u_int32_t uid); +	void setSize(u_int32_t sizeLo, u_int32_t sizeHi); +	void setSpace(u_int32_t spaceLo, u_int32_t spaceHi); +	void setName(char drive, const char * const volname); + +	u_int32_t mediatype; +	u_int32_t driveattr; +	u_int32_t mediaattr; +	u_int32_t uid; +	u_int64_t size; +	u_int64_t space; +	char drivechar; +	string name; +};  #endif diff --git a/lib/ppsocket.cc b/lib/ppsocket.cc index a482ae5..9b0a33d 100644 --- a/lib/ppsocket.cc +++ b/lib/ppsocket.cc @@ -38,6 +38,7 @@  #include "bufferstore.h"  #include "ppsocket.h" +#include "iowatch.h"  #define  INVALID_SOCKET	-1  #define  SOCKET_ERROR	-1 @@ -49,6 +50,7 @@ ppsocket::ppsocket(const ppsocket & another)  	m_PeerAddr = another.m_PeerAddr;  	m_Bound = another.m_Bound;  	m_LastError = another.m_LastError; +	myWatch = another.myWatch;  } @@ -64,21 +66,32 @@ ppsocket::ppsocket()  	m_Bound = false;  	m_LastError = 0; +	myWatch = 0L;  }  ppsocket::~ppsocket()  {  	if (m_Socket != INVALID_SOCKET) { -		shutdown(m_Socket, 3); +		if (myWatch) +			myWatch->remIO(m_Socket); +		shutdown(m_Socket, SHUT_RDWR);  		::close(m_Socket);  	}  } +void ppsocket:: +setWatch(IOWatch *watch) { +	if (watch) +		myWatch = watch; +} +  bool ppsocket::  reconnect()  {  	if (m_Socket != INVALID_SOCKET) { -		shutdown(m_Socket, 3); +		if (myWatch) +			myWatch->remIO(m_Socket); +		shutdown(m_Socket, SHUT_RDWR);  		::close(m_Socket);  	}  	m_Socket = INVALID_SOCKET; @@ -94,6 +107,8 @@ reconnect()  		m_LastError = errno;  		return (false);  	} +	if (myWatch) +		myWatch->addIO(m_Socket);  	return (true);  } @@ -148,6 +163,8 @@ connect(const char * const Peer, int PeerPort, const char * const Host, int Host  		m_LastError = errno;  		return (false);  	} +	if (myWatch) +		myWatch->addIO(m_Socket);  	return (true);  } @@ -167,6 +184,8 @@ listen(const char * const Host, int Port)  	//* Listen on the port *  	//********************** +	if (myWatch) +		myWatch->addIO(m_Socket);  	if (::listen(m_Socket, 5) != 0) {  		m_LastError = errno;  		return (false); @@ -215,11 +234,9 @@ accept(string *Peer)  	// Make sure the new socket hasn't inherited O_NONBLOCK  	// from the accept socket -	int flags = fcntl( accepted->m_Socket, F_GETFL, 0 ); -	if( flags >= 0 ) { -		flags &= ~O_NONBLOCK; -		fcntl( accepted->m_Socket, F_SETFL, flags); -	} +	int flags = fcntl(accepted->m_Socket, F_GETFL, 0); +	flags &= ~O_NONBLOCK; +	fcntl(accepted->m_Socket, F_SETFL, flags);  	accepted->m_HostAddr = m_HostAddr;  	accepted->m_Bound = true; @@ -232,18 +249,22 @@ accept(string *Peer)  		if (peer)  			*Peer = peer;  	} +	if (accepted && myWatch) { +		accepted->setWatch(myWatch); +		myWatch->addIO(accepted->m_Socket); +	}  	return accepted;  }  bool ppsocket:: -dataToGet() const +dataToGet(int sec, int usec) const  {  	fd_set io;  	FD_ZERO(&io);  	FD_SET(m_Socket, &io);  	struct timeval t; -	t.tv_usec = 0; -	t.tv_sec = 0; +	t.tv_usec = usec; +	t.tv_sec = sec;  	return (select(m_Socket + 1, &io, NULL, NULL, &t) != 0) ? true : false;  } @@ -258,16 +279,15 @@ getBufferStore(bufferStore & a, bool wait)  	long count = 0;  	unsigned char *buff;  	unsigned char *bp; -	if (!wait && !dataToGet()) +	if (!wait && !dataToGet(0, 0))  		return 0;  	a.init(); - -	if (recv(&l, sizeof(l), 0) != sizeof(l)) +	if (recv(&l, sizeof(l), MSG_NOSIGNAL) != sizeof(l))  		return -1;  	l = ntohl(l);  	bp = buff = new unsigned char[l];  	while (l > 0) { -		int j = recv(bp, l, 0); +		int j = recv(bp, l, MSG_NOSIGNAL);  		if (j == SOCKET_ERROR || j == 0) {  			delete[]buff;  			return -1; @@ -290,11 +310,15 @@ sendBufferStore(const bufferStore & a)  	int retries = 0;  	int i; -	i = send((char *) &hl, sizeof(hl), 0); -	if (i != sizeof(hl)) -		return false; +	bufferStore b; +	b.addDWord(hl); +	b.addBuff(a); +//	i = send((char *)&hl, sizeof(hl), MSG_NOSIGNAL); +//	if (i != sizeof(hl)) +//		return false; +	l += 4;  	while (l > 0) { -		i = send((const char *)a.getString(sent), l, 0); +		i = send((const char *)b.getString(sent), l, MSG_NOSIGNAL);  		if (i == SOCKET_ERROR || i == 0)  			return (false);  		sent += i; @@ -332,7 +356,9 @@ send(const void * const buf, int len, int flags)  bool ppsocket::  closeSocket(void)  { -	shutdown(m_Socket, 3); +	if (myWatch) +		myWatch->remIO(m_Socket); +	shutdown(m_Socket, SHUT_RDWR);  	if (::close(m_Socket) != 0) {  		m_LastError = errno;  		return false; diff --git a/lib/ppsocket.h b/lib/ppsocket.h index 57cc788..b8f7ebe 100644 --- a/lib/ppsocket.h +++ b/lib/ppsocket.h @@ -8,6 +8,7 @@  #include <arpa/inet.h>  class bufferStore; +class IOWatch;  /**   * A class for dealing with sockets. @@ -80,11 +81,14 @@ public:  	ppsocket *accept(string *Peer);  	/** -	 * Check for incoming data. +	 * Check and optionally wait for incoming data. +	 * +	 * @param sec Timeout in seconds +	 * @param usec Timeout in microseconds  	 *  	 * @returns true if data is available, false otherwise.  	 */ -	bool dataToGet() const; +	bool dataToGet(int sec, int usec) const;  	/**  	 * Receive data into a @ref bufferStore . @@ -169,11 +173,13 @@ public:  	bool getHost(string *Host, int *Port);  	/** -	 * Retrieves the socket number. +	 * Registers an @ref IOWatch for this socket. +	 * This IOWatch gets the socket added/removed +	 * automatically.  	 * -	 * @returns the socket number. +	 * @param watch The IOWatch to register.  	 */ -	inline int socket(void) const { return(m_Socket); } +	void setWatch(IOWatch *watch);   private:  	/** @@ -193,6 +199,7 @@ public:  	int m_Port;  	bool m_Bound;  	int m_LastError; +	IOWatch *myWatch;  };  #endif @@ -10,6 +10,7 @@  typedef deque<class PlpDirent> PlpDir;  class ppsocket; +class PlpDrive;  const int RFSV_SENDLEN = 2000; @@ -19,8 +20,20 @@ const int RFSV_SENDLEN = 2000;   */  typedef int (*cpCallback_t)(void *, u_int32_t); +class rfsv16; +class rfsv32; + +/** + * A helper class for storing + * intermediate internal information in rfsv16 and + * rfsv32 . + * @internal + */  class rfsvDirhandle { - public: +	friend rfsv16; +	friend rfsv32; + + private:  	u_int32_t h;  	bufferStore b;  }; @@ -330,15 +343,12 @@ class rfsv {  		 *  		 * @param dev   An integer, representing the drive to get details from.  		 *              (0 represents A:, 1 is B: and so on ...) -		 * @param free     On return, the free space in bytes is returned here. -		 * @param total    On return, the total capacity in bytes is returned here. -		 * @param attr     On return, the attributes of the drive are returned here. -		 * @param uniqueid On return, the unique Id of the drive is returned here. -		 * @param name     On return, the volume name returned here. +		 * @param drive A @ref PlpDrive object which is filled with the drive's +		 *              information upon return.  		 *  		 * @returns A Psion error code (One of enum @ref #errs ).  		 */ -		virtual Enum<errs> devinfo(const u_int32_t dev, u_int32_t &free, u_int32_t &total, u_int32_t &attr, u_int32_t &uniqueid, string &name) = 0; +		virtual Enum<errs> devinfo(const u_int32_t dev, PlpDrive &drive) = 0;  		/**  		 * Reads from a file on the Psion. diff --git a/lib/rfsv16.cc b/lib/rfsv16.cc index 2b474cb..f98816c 100644 --- a/lib/rfsv16.cc +++ b/lib/rfsv16.cc @@ -413,8 +413,18 @@ devlist(u_int32_t &devbits)  	return res;  } +static int sibo_dattr[] = { +	1, // Unknown +	2, // Floppy +	3, // Disk +	6, // Flash +	5, // RAM +	7, // ROM +	7, // write-protected == ROM ? +}; +  Enum<rfsv::errs> rfsv16:: -devinfo(const u_int32_t devnum, u_int32_t &free, u_int32_t &size, u_int32_t &attr, u_int32_t &uniqueid, string &name) +devinfo(const u_int32_t devnum, PlpDrive &drive)  {  	bufferStore a;  	Enum<rfsv::errs> res; @@ -448,16 +458,31 @@ devinfo(const u_int32_t devnum, u_int32_t &free, u_int32_t &size, u_int32_t &att  		// cerr << "devinfo STATUSDEVICE res is " << dec << (signed short int) res << endl;  		return res;  	} + +	int attr = a.getWord(2); +	attr = sibo_dattr[a.getWord(2) & 0xff]; +	drive.setMediaType(attr); +  	attr = a.getWord(2); -	// int changeable = a.getWord(4); -	size = a.getDWord(6); -	free = a.getDWord(10); -	// const char *volume = a.getString(14); -	// int battery = a.getWord(30); -	// const char *devicename = a.getString(62); -	uniqueid = 0; -	name = ""; -	name += (char)(devnum + 'A'); +	int changeable = a.getWord(4) ? 32 : 0; +	int internal = (attr & 0x2000) ? 16 : 0; + +	drive.setDriveAttribute(changeable | internal); + +	int variable = (attr & 0x4000) ? 1 : 0; +	int dualdens = (attr & 0x1000) ? 2 : 0; +	int formattable = (attr & 0x0800) ? 4 : 0; +	int protect = ((attr & 0xff) == 6) ? 8 : 0; + +	drive.setMediaAttribute(variable|dualdens|formattable|protect); + +	drive.setUID(0); +	drive.setSize(a.getDWord(6), 0); +	drive.setSpace(a.getDWord(10), 0); + +	drive.setName('A' + devnum, a.getString(14)); + +  	return res;  } diff --git a/lib/rfsv16.h b/lib/rfsv16.h index a94aa5f..42661f8 100644 --- a/lib/rfsv16.h +++ b/lib/rfsv16.h @@ -3,15 +3,19 @@  #include "rfsv.h" +class rfsvfactory; +  /**   * This is the implementation of the @ref rfsv protocol for - * Psion series 3 (SIBO) variant. - * For a complete documentation, see @ref rfsv . + * Psion series 3 (SIBO) variant. You normally never create + * objects of this class directly. Thus the constructor is + * private. Use @ref rfsvfactory for creating an instance of + * @ref rfsv . For a complete documentation, see @ref rfsv .   */  class rfsv16 : public rfsv { -public: -	rfsv16(ppsocket *); +	friend rfsvfactory; +public:  	Enum<rfsv::errs> fopen(const u_int32_t, const char * const, u_int32_t &);  	Enum<rfsv::errs> mktemp(u_int32_t &, string &);  	Enum<rfsv::errs> fcreatefile(const u_int32_t, const char * const, u_int32_t &); @@ -25,7 +29,7 @@ public:  	Enum<rfsv::errs> fsetattr(const char * const, const u_int32_t seta, const u_int32_t unseta);  	Enum<rfsv::errs> dircount(const char * const, u_int32_t &);  	Enum<rfsv::errs> devlist(u_int32_t &); -	Enum<rfsv::errs> devinfo(const u_int32_t, u_int32_t &, u_int32_t &, u_int32_t &, u_int32_t &, string &); +	Enum<rfsv::errs> devinfo(const u_int32_t, PlpDrive &);  	Enum<rfsv::errs> fread(const u_int32_t, unsigned char * const, const u_int32_t, u_int32_t &);  	Enum<rfsv::errs> fwrite(const u_int32_t, const unsigned char * const, const u_int32_t, u_int32_t &);  	Enum<rfsv::errs> copyFromPsion(const char * const, const char * const, void *, cpCallback_t); @@ -102,6 +106,11 @@ private:  		P_FAMASK   = 0x0f3f  /* All of the above */  	}; +	/** +	 * Private constructor. Shall be called by +	 * rfsvfactory only. +	 */ +	rfsv16(ppsocket *);  	// Miscellaneous  	Enum<rfsv::errs> fopendir(const char * const, u_int32_t &); diff --git a/lib/rfsv32.cc b/lib/rfsv32.cc index 74a1959..0b6f120 100644 --- a/lib/rfsv32.cc +++ b/lib/rfsv32.cc @@ -358,7 +358,7 @@ devlist(u_int32_t &devbits)  }  Enum<rfsv::errs> rfsv32:: -devinfo(const u_int32_t dev, u_int32_t &free, u_int32_t &total, u_int32_t &attr, u_int32_t &uniqueid, string &name) +devinfo(const u_int32_t dev, PlpDrive &drive)  {  	bufferStore a;  	Enum<rfsv::errs> res; @@ -368,13 +368,14 @@ devinfo(const u_int32_t dev, u_int32_t &free, u_int32_t &total, u_int32_t &attr,  		return E_PSI_FILE_DISC;  	res = getResponse(a);  	if (res == E_PSI_GEN_NONE) { -		attr = a.getDWord(0); -		uniqueid = a.getDWord(16); -		total = a.getDWord(20); -		free = a.getDWord(28); -		// vnamelen = a.getDWord(36); +		drive.setMediaType(a.getDWord(0)); +		drive.setDriveAttribute(a.getDWord(8)); +		drive.setMediaAttribute(a.getDWord(12)); +		drive.setUID(a.getDWord(16)); +		drive.setSize(a.getDWord(20), a.getDWord(24)); +		drive.setSpace(a.getDWord(28), a.getDWord(32));  		a.addByte(0); -		name = a.getString(40); +		drive.setName('A' + dev, a.getString(40));  	}  	return res;  } diff --git a/lib/rfsv32.h b/lib/rfsv32.h index abbc6ad..4afb95a 100644 --- a/lib/rfsv32.h +++ b/lib/rfsv32.h @@ -4,16 +4,19 @@  #include "rfsv.h"  #include "plpdirent.h" +class rfsvfactory; +  /**   * This is the implementation of the @ref rfsv protocol for - * Psion series 5 (EPOC) variant. - * For a complete documentation, see @ref rfsv . + * Psion series 5 (EPOC) variant. You normally never create + * objects of this class directly. Thus the constructor is + * private. Use @ref rfsvfactory for creating an instance of + * @ref rfsv . For a complete documentation, see @ref rfsv .   */  class rfsv32 : public rfsv { +	friend rfsvfactory;  public: -	rfsv32(ppsocket *); -  	Enum<rfsv::errs> dir(const char * const, PlpDir &);  	Enum<rfsv::errs> dircount(const char * const, u_int32_t &);  	Enum<rfsv::errs> copyFromPsion(const char * const, const char * const, void *, cpCallback_t); @@ -39,7 +42,7 @@ public:  	Enum<rfsv::errs> fclose(const u_int32_t);  	Enum<rfsv::errs> devlist(u_int32_t &); -	Enum<rfsv::errs> devinfo(const u_int32_t, u_int32_t &, u_int32_t &, u_int32_t &, u_int32_t &, string &); +	Enum<rfsv::errs> devinfo(const u_int32_t, PlpDrive&);  	Enum<rfsv::errs> opendir(const u_int32_t, const char * const, rfsvDirhandle &);  	Enum<rfsv::errs> readdir(rfsvDirhandle &, PlpDirent &);  	Enum<rfsv::errs> closedir(rfsvDirhandle &); @@ -155,6 +158,12 @@ private:  		REPLACE          = 0x32  	}; +	/** +	 * Private constructor. Shall be called by +	 * rfsvfactory only. +	 */ +	rfsv32(ppsocket *); +  	Enum<rfsv::errs> err2psierr(int32_t);  	Enum<rfsv::errs> fopendir(const u_int32_t, const char *, u_int32_t &);  	u_int32_t attr2std(const u_int32_t); diff --git a/lib/rfsvfactory.cc b/lib/rfsvfactory.cc index 12bd623..3699903 100644 --- a/lib/rfsvfactory.cc +++ b/lib/rfsvfactory.cc @@ -35,10 +35,20 @@  #include "rfsvfactory.h"  #include "bufferstore.h"  #include "ppsocket.h" -#include "bufferarray.h" +#include "Enum.h" + +ENUM_DEFINITION(rfsvfactory::errs, rfsvfactory::FACERR_NONE) { +	stringRep.add(rfsvfactory::FACERR_NONE,           "no error"); +	stringRep.add(rfsvfactory::FACERR_COULD_NOT_SEND, "could not send version request"); +	stringRep.add(rfsvfactory::FACERR_AGAIN,          "try again"); +	stringRep.add(rfsvfactory::FACERR_NOPSION,        "no psion connected"); +	stringRep.add(rfsvfactory::FACERR_PROTVERSION,    "wrong protocol version"); +	stringRep.add(rfsvfactory::FACERR_NORESPONSE,     "no response from ncpd"); +}  rfsvfactory::rfsvfactory(ppsocket *_skt) : serNum(0)  { +	err = FACERR_NONE;  	skt = _skt;  } @@ -50,15 +60,19 @@ rfsv * rfsvfactory::create(bool reconnect)  	// so we can instantiate the correct RFSV protocol handler for the  	// caller. We announce ourselves to the NCP daemon, and the relevant  	// RFSV module will also announce itself. +  	bufferStore a; -	a.init(); + +	err = FACERR_NONE;  	a.addStringT("NCP$INFO");  	if (!skt->sendBufferStore(a)) {  		if (!reconnect) -			cerr << "rfsvfactory::create couldn't send version request" << endl;		else { +			err = FACERR_COULD_NOT_SEND; +		else {  			skt->closeSocket();  			serNum = 0;  			skt->reconnect(); +			err = FACERR_AGAIN;  		}  		return NULL;  	} @@ -73,16 +87,13 @@ rfsv * rfsvfactory::create(bool reconnect)  			skt->closeSocket();  			serNum = 0;  			skt->reconnect(); +			err = FACERR_NOPSION;  			return NULL;  		}  		// Invalid protocol version -		cerr << "rfsvfactory::create received odd protocol version from -ncpd! (" << a << ")" << endl; -	} else { -		cerr << "rfsvfactory::create sent, response not 1" << endl; -	} +		err = FACERR_PROTVERSION; +	} else +		err = FACERR_NORESPONSE; -	// No message returned.  	return NULL;  } - diff --git a/lib/rfsvfactory.h b/lib/rfsvfactory.h index 99136e3..8af4575 100644 --- a/lib/rfsvfactory.h +++ b/lib/rfsvfactory.h @@ -10,8 +10,21 @@ class ppsocket;   * @ref rfsv protocol variant depending on the connected Psion.   */  class rfsvfactory { +	   public:  	/** +	 * The known errors which can happen during @ref create . +	 */ +	enum errs { +		FACERR_NONE = 0, +		FACERR_COULD_NOT_SEND = 1, +		FACERR_AGAIN = 2, +		FACERR_NOPSION = 3, +		FACERR_PROTVERSION = 4, +		FACERR_NORESPONSE = 5, +	}; + +	/**  	 * Constructs a rfsvfactory.  	 *  	 * @param skt The socket to be used for connecting @@ -30,6 +43,14 @@ class rfsvfactory {  	 */  	virtual rfsv * create(bool); +	/** +	 * Retrieve an error code. +	 * +	 * @returns The error code, in case @ref create has +	 * failed, 0 otherwise. +	 */ +	virtual Enum<errs> getError() { return err; } +   private:  	/**  	 * The socket to be used for connecting to the @@ -37,6 +58,7 @@ class rfsvfactory {  	 */  	ppsocket *skt;  	int serNum; +	Enum<errs> err;  };  #endif diff --git a/lib/rpcs16.h b/lib/rpcs16.h index 7085939..cc4d601 100644 --- a/lib/rpcs16.h +++ b/lib/rpcs16.h @@ -5,19 +5,25 @@  class ppsocket;  class bufferStore; +class rpcsfactory;  /**   * This is the implementation of the @ref rpcs protocol for - * Psion series 3 (SIBO) variant. - * For a complete documentation, see @ref rpcs . + * Psion series 3 (SIBO) variant.  You normally never create + * objects of this class directly. Thus the constructor is + * private. Use @ref rpcsfactory for creating an instance of + * @ref rpcs . For a complete documentation, see @ref rpcs .   */  class rpcs16 : public rpcs { +	friend rpcsfactory; +   public: -	rpcs16(ppsocket *);  	~rpcs16();  	Enum<rfsv::errs> queryDrive(const char, bufferArray &);  	Enum<rfsv::errs> getCmdLine(const char *, bufferStore &);  + private: +	rpcs16(ppsocket *);  };  #endif diff --git a/lib/rpcs32.h b/lib/rpcs32.h index 0cab1b2..5230247 100644 --- a/lib/rpcs32.h +++ b/lib/rpcs32.h @@ -4,40 +4,45 @@  #include "rpcs.h"  class ppsocket; +class rpcsfactory;  /**   * This is the implementation of the @ref rpcs protocol for - * Psion series 5 (EPOC) variant. - * For a complete documentation, see @ref rpcs . + * Psion series 5 (EPOC) variant. You normally never create + * objects of this class directly. Thus the constructor is + * private. Use @ref rpcsfactory for creating an instance of + * @ref rpcs . For a complete documentation, see @ref rpcs .   */  class rpcs32 : public rpcs { -	public: -		rpcs32(ppsocket *); -		~rpcs32(); +	friend rpcsfactory; -		Enum<rfsv::errs> queryDrive(const char, bufferArray &); -		Enum<rfsv::errs> getCmdLine(const char *, bufferStore &);  -		Enum<rfsv::errs> getMachineInfo(machineInfo &); -		Enum<rfsv::errs> configOpen(void); -		Enum<rfsv::errs> configRead(void); + public: +	~rpcs32(); + +	Enum<rfsv::errs> queryDrive(const char, bufferArray &); +	Enum<rfsv::errs> getCmdLine(const char *, bufferStore &);  +	Enum<rfsv::errs> getMachineInfo(machineInfo &); +	Enum<rfsv::errs> configOpen(void); +	Enum<rfsv::errs> configRead(void);  #if 0 -		Enum<rfsv::errs> closeHandle(int); +	Enum<rfsv::errs> closeHandle(int);  #endif -		Enum<rfsv::errs> regOpenIter(void); +	Enum<rfsv::errs> regOpenIter(void);  #if 0 -		Enum<rfsv::errs> regReadIter(void); -		Enum<rfsv::errs> regWrite(void); -		Enum<rfsv::errs> regRead(void); -		Enum<rfsv::errs> regDelete(void); -		Enum<rfsv::errs> setTime(void); -		Enum<rfsv::errs> configOpen(void); -		Enum<rfsv::errs> configRead(void); -		Enum<rfsv::errs> configWrite(void); -		Enum<rfsv::errs> queryOpen(void); -		Enum<rfsv::errs> queryRead(void); -		Enum<rfsv::errs> quitServer(void); +	Enum<rfsv::errs> regReadIter(void); +	Enum<rfsv::errs> regWrite(void); +	Enum<rfsv::errs> regRead(void); +	Enum<rfsv::errs> regDelete(void); +	Enum<rfsv::errs> setTime(void); +	Enum<rfsv::errs> configOpen(void); +	Enum<rfsv::errs> configRead(void); +	Enum<rfsv::errs> configWrite(void); +	Enum<rfsv::errs> queryOpen(void); +	Enum<rfsv::errs> queryRead(void); +	Enum<rfsv::errs> quitServer(void);  #endif - + private: +	rpcs32(ppsocket *);  };  #endif diff --git a/lib/rpcsfactory.cc b/lib/rpcsfactory.cc index 091f12a..bd3b77d 100644 --- a/lib/rpcsfactory.cc +++ b/lib/rpcsfactory.cc @@ -36,8 +36,20 @@  #include "bufferstore.h"  #include "ppsocket.h" +#include "Enum.h" + +ENUM_DEFINITION(rpcsfactory::errs, rpcsfactory::FACERR_NONE) { +	stringRep.add(rpcsfactory::FACERR_NONE,           "no error"); +	stringRep.add(rpcsfactory::FACERR_COULD_NOT_SEND, "could not send version request"); +	stringRep.add(rpcsfactory::FACERR_AGAIN,          "try again"); +	stringRep.add(rpcsfactory::FACERR_NOPSION,        "no psion connected"); +	stringRep.add(rpcsfactory::FACERR_PROTVERSION,    "wrong protocol version"); +	stringRep.add(rpcsfactory::FACERR_NORESPONSE,     "no response from ncpd"); +} +  rpcsfactory::rpcsfactory(ppsocket *_skt)  { +	err = FACERR_NONE;  	skt = _skt;  } @@ -49,15 +61,18 @@ rpcs * rpcsfactory::create(bool reconnect)  	// so we can instantiate the correct rpcs protocol handler for the  	// caller. We announce ourselves to the NCP daemon, and the relevant  	// rpcs module will also announce itself. +  	bufferStore a; -	a.init(); + +	err = FACERR_NONE;  	a.addStringT("NCP$INFO");  	if (!skt->sendBufferStore(a)) {  		if (!reconnect) -			cerr << "rpcsfactory::create couldn't send version request" << endl; +			err = FACERR_COULD_NOT_SEND;  		else {  			skt->closeSocket();  			skt->reconnect(); +			err = FACERR_AGAIN;  		}  		return NULL;  	} @@ -71,13 +86,13 @@ rpcs * rpcsfactory::create(bool reconnect)  		if ((a.getLen() > 8) && !strncmp(a.getString(), "No Psion", 8)) {  			skt->closeSocket();  			skt->reconnect(); +			err = FACERR_NOPSION;  			return NULL;  		}  		// Invalid protocol version -		cerr << "rpcsfactory::create received odd protocol version from ncpd! (" << a << ")" << endl; -	} else { -		cerr << "rpcsfactory::create sent, response not 1" << endl; -	} +		err = FACERR_PROTVERSION; +	} else +		err = FACERR_NORESPONSE;  	// No message returned.  	return NULL; diff --git a/lib/rpcsfactory.h b/lib/rpcsfactory.h index d57eb29..cc36f0d 100644 --- a/lib/rpcsfactory.h +++ b/lib/rpcsfactory.h @@ -11,6 +11,19 @@ class ppsocket;   */  class rpcsfactory {   public: + +	/** +	 * The known errors which can happen during @ref create . +	 */ +	enum errs { +		FACERR_NONE = 0, +		FACERR_COULD_NOT_SEND = 1, +		FACERR_AGAIN = 2, +		FACERR_NOPSION = 3, +		FACERR_PROTVERSION = 4, +		FACERR_NORESPONSE = 5, +	}; +  	/**  	 * Constructs a rpcsfactory.  	 * @@ -30,12 +43,21 @@ class rpcsfactory {  	 */  	virtual rpcs * create(bool reconnect); +	/** +	 * Retrieve an error code. +	 * +	 * @returns The error code, in case @ref create has +	 * failed, 0 otherwise. +	 */ +	virtual Enum<errs> getError() { return err; } +   private:  	/**  	 * The socket to be used for connecting to the  	 * ncpd daemon.  	 */  	ppsocket *skt; +	Enum<errs> err;  };  #endif diff --git a/ncpd/main.cc b/ncpd/main.cc index 76d0bb2..d8a28ed 100644 --- a/ncpd/main.cc +++ b/ncpd/main.cc @@ -63,7 +63,7 @@ int_handler(int)  };  void -checkForNewSocketConnection(ppsocket & skt, int &numScp, socketChan ** scp, ncp * a, IOWatch & iow) +checkForNewSocketConnection(ppsocket & skt, int &numScp, socketChan ** scp, ncp * a, IOWatch &iow)  {  	string peer;  	ppsocket *next = skt.accept(&peer); @@ -73,11 +73,17 @@ checkForNewSocketConnection(ppsocket & skt, int &numScp, socketChan ** scp, ncp  			cout << "New socket connection from " << peer << endl;  		if ((numScp == 7) || (!a->gotLinkChannel())) {  			bufferStore a; + +			// Give the client time to send it's version request. +			next->dataToGet(1,0); +			next->getBufferStore(a, false); + +			a.init();  			a.addStringT("No Psion Connected\n");  			next->sendBufferStore(a);  			next->closeSocket();  		} else -			scp[numScp++] = new socketChan(next, a, iow); +			scp[numScp++] = new socketChan(next, a);  	}  } @@ -126,7 +132,6 @@ main(int argc, char **argv)  		sockNum = ntohs(se->s_port);  	// Command line parameter processing -	signal(SIGPIPE, SIG_IGN);  	for (int i = 1; i < argc; i++) {  		if (!strcmp(argv[i], "-p") && i + 1 < argc) {  			sockNum = atoi(argv[++i]); @@ -187,6 +192,7 @@ main(int argc, char **argv)  		case 0:  			signal(SIGTERM, term_handler);  			signal(SIGINT, int_handler); +			skt.setWatch(&iow);  			if (!skt.listen("127.0.0.1", sockNum))  				cerr << "listen on port " << sockNum << ": " << strerror(errno) << endl;  			else { @@ -209,7 +215,6 @@ main(int argc, char **argv)  				a->setVerbose(nverbose);  				a->setLinkVerbose(lverbose);  				a->setPktVerbose(pverbose); -				iow.addIO(skt.socket());  				while (active) {  					// sockets  					pollSocketConnections(numScp, scp); diff --git a/ncpd/socketchan.cc b/ncpd/socketchan.cc index 1e3fd08..06b3da2 100644 --- a/ncpd/socketchan.cc +++ b/ncpd/socketchan.cc @@ -33,22 +33,18 @@  #include "socketchan.h"  #include "ncp.h"  #include "ppsocket.h" -#include "iowatch.h" -socketChan:: socketChan(ppsocket * _skt, ncp * _ncpController, IOWatch & _iow): -channel(_ncpController), -iow(_iow) +socketChan:: socketChan(ppsocket * _skt, ncp * _ncpController): +	channel(_ncpController)  {  	skt = _skt;  	connectName = 0;  	connectTry = 0; -	iow.addIO(skt->socket());  	connected = false;  }  socketChan::~socketChan()  { -	iow.remIO(skt->socket());  	skt->closeSocket();  	delete skt;  	if (connectName) diff --git a/ncpd/socketchan.h b/ncpd/socketchan.h index 15645dd..7dde472 100644 --- a/ncpd/socketchan.h +++ b/ncpd/socketchan.h @@ -30,11 +30,10 @@  #endif  #include "channel.h"  class ppsocket; -class IOWatch;  class socketChan : public channel {  public: -  socketChan(ppsocket* comms, ncp* ncpController, IOWatch &iow); +  socketChan(ppsocket* comms, ncp* ncpController);    virtual ~socketChan();    void ncpDataCallback(bufferStore& a); @@ -51,7 +50,6 @@ private:    enum protocolVersionType { PV_SERIES_5 = 6, PV_SERIES_3 = 3 };    bool ncpCommand(bufferStore &a);    ppsocket* skt; -  IOWatch &iow;    char* connectName;    bool connected;    int connectTry; diff --git a/plpbackup/plpbackup.cc b/plpbackup/plpbackup.cc index 48e3202..adf8742 100644 --- a/plpbackup/plpbackup.cc +++ b/plpbackup/plpbackup.cc @@ -31,7 +31,6 @@  #include <stdlib.h>  #include <iomanip.h>  #include <unistd.h> -#include <signal.h>  #include <sys/time.h>  #include <sys/stat.h>  #include <errno.h> @@ -292,11 +291,6 @@ main(int argc, char **argv)  	int op;  	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(); @@ -417,13 +411,12 @@ main(int argc, char **argv)  		} else {  			char drive[3];  			u_int32_t devbits; -			u_int32_t vtotal, vfree, vattr, vuniqueid;  			if (a->devlist(devbits) == rfsv::E_PSI_GEN_NONE) {  				for (i = 0; i < 26; i++) { -					string n; -					if ((devbits & 1) && a->devinfo(i, vfree, vtotal, vattr, vuniqueid, n) == rfsv::E_PSI_GEN_NONE) { -						if (vattr != 7) { +					PlpDrive psidr; +					if ((devbits & 1) && a->devinfo(i, psidr) == rfsv::E_PSI_GEN_NONE) { +						if (psidr.getMediaType() != 7) {  							sprintf(drive, "%c:\0", 'A' + i);  							if (verbose > 0)  								cout << "Scanning Drive " << drive << " ..." << endl; diff --git a/plpftp/ftp.cc b/plpftp/ftp.cc index aad6187..efe4f82 100644 --- a/plpftp/ftp.cc +++ b/plpftp/ftp.cc @@ -242,15 +242,14 @@ session(rfsv & a, rpcs & r, int xargc, char **xargv)  	if (!strcmp(DDRIVE, "AUTO")) {  		u_int32_t devbits; -		u_int32_t vtotal, vfree, vattr, vuniqueid;  		int i;  		strcpy(defDrive, "::");  		if (a.devlist(devbits) == rfsv::E_PSI_GEN_NONE) {  			for (i = 0; i < 26; i++) { -				string n; -				if ((devbits & 1) && a.devinfo(i, vfree, vtotal, vattr, vuniqueid, n) == rfsv::E_PSI_GEN_NONE) { +				PlpDrive drive; +				if ((devbits & 1) && a.devinfo(i, drive) == rfsv::E_PSI_GEN_NONE) {  					defDrive[0] = 'A' + i;  					break;  				} @@ -417,17 +416,16 @@ session(rfsv & a, rpcs & r, int xargc, char **xargv)  			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++) { -					string vname; -					u_int32_t vtotal, vfree, vattr, vuniqueid; +					PlpDrive drive;  					if ((devbits & 1) != 0) { -						if (a.devinfo(i, vfree, vtotal, vattr, vuniqueid, vname) == rfsv::E_PSI_GEN_NONE) +						if (a.devinfo(i, drive) == rfsv::E_PSI_GEN_NONE)  							cout << (char) ('A' + i) << "     " << -							    hex << setw(4) << setfill('0') << vattr << " " << +							    hex << setw(4) << setfill('0') << drive.getMediaType() << " " <<  							    setw(12) << setfill(' ') << setiosflags(ios::left) <<  -							    vname << resetiosflags(ios::left) << dec << setw(9) << -							    vtotal << setw(9) << vfree << "  " << setw(8) << setfill('0') << hex << -							    vuniqueid << endl; +							    drive.getName() << resetiosflags(ios::left) << dec << setw(9) << +							    drive.getSize() << setw(9) << drive.getSpace() << "  " << setw(8) << setfill('0') << hex << +							    drive.getUID() << endl;  					}  					devbits >>= 1;  				} diff --git a/plpftp/main.cc b/plpftp/main.cc index 1755f38..ca3bcaa 100644 --- a/plpftp/main.cc +++ b/plpftp/main.cc @@ -30,7 +30,6 @@  #include <string.h>  #include <stdlib.h>  #include <stdio.h> -#include <signal.h>  #include "ppsocket.h"  #include "rfsv.h" @@ -71,11 +70,6 @@ main(int argc, char **argv)  	ftp f;  	int status = 0;  	int sockNum = DPORT; -	sigset_t sigset; - -	sigemptyset(&sigset); -	sigaddset(&sigset, SIGPIPE); -	sigprocmask(SIG_BLOCK, &sigset, 0L);  	struct servent *se = getservbyname("psion", "tcp");  	endservent(); diff --git a/plpnfsd/main.cc b/plpnfsd/main.cc index 81e7176..e7e3640 100644 --- a/plpnfsd/main.cc +++ b/plpnfsd/main.cc @@ -405,13 +405,12 @@ long rfsv_getattr(const char *name, long *attr, long *size, long *time) {  }  long rfsv_statdev(char letter) { -	u_int32_t vfree, vtotal, vattr, vuniqueid; +	PlpDrive drive;  	u_int32_t devnum = letter - 'A'; -	string n;  	if (!a)  		return -1; -	return (a->devinfo(devnum, vfree, vtotal, vattr, vuniqueid, n) != rfsv::E_PSI_GEN_NONE); +	return (a->devinfo(devnum, drive) != rfsv::E_PSI_GEN_NONE);  }  long rfsv_rename(const char *oldname, const char *newname) { @@ -431,19 +430,19 @@ long rfsv_drivelist(int *cnt, device **dlist) {  	ret = a->devlist(devbits);  	if (ret == 0)  		for (i = 0; i<26; i++) { -			string name; -			u_int32_t vtotal, vfree, vattr, vuniqueid; +			PlpDrive drive;  			if ((devbits & 1) && -			    ((a->devinfo(i, vfree, vtotal, vattr, vuniqueid, name) == rfsv::E_PSI_GEN_NONE))) { +			    ((a->devinfo(i, drive) == rfsv::E_PSI_GEN_NONE))) { +  				device *next = *dlist;  				*dlist = (device *)malloc(sizeof(device));  				(*dlist)->next = next; -				(*dlist)->name = strdup(name.c_str()); -				(*dlist)->total = vtotal; -				(*dlist)->free = vfree; +				(*dlist)->name = strdup(drive.getName().c_str()); +				(*dlist)->total = drive.getSize(); +				(*dlist)->free = drive.getSpace();  				(*dlist)->letter = 'A' + i; -				(*dlist)->attrib = vattr; +				(*dlist)->attrib = drive.getMediaType();  				(*cnt)++;  			}  			devbits >>= 1; @@ -489,7 +488,6 @@ int main(int argc, char**argv) {  			usage();  	} -	signal(SIGPIPE, SIG_IGN);  	skt = new ppsocket();  	if (!skt->connect(NULL, sockNum)) {  		cerr << "plpnfsd: could not connect to ncpd" << endl; diff --git a/plpnfsd/mp_mount.c b/plpnfsd/mp_mount.c index 6f9d203..39c3493 100644 --- a/plpnfsd/mp_mount.c +++ b/plpnfsd/mp_mount.c @@ -576,7 +576,6 @@ mount_and_run(char *dir, void (*proc)(), nfs_fh *root_fh)  	signal(SIGUSR1, usr1_handler);  	signal(SIGHUP, hup_handler);  	signal(SIGTERM, term_handler); -	signal(SIGPIPE, SIG_IGN);  	for (;;) {  		fd_set readfd; | 
