[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-core-devel
Subject:    Addition to kio-SlaveBase
From:       Bjoern Kahl <Bjoern.Kahl () kiel ! netsurf ! de>
Date:       2000-07-14 1:15:30
[Download RAW message or body]

This message is in MIME format

 Hallo !

 I have posted some weeks ago a suggestion about an Dialmanager.

 To allow kio-slaves to use that dialmanager and trigger a dialup,
 easily, I like to do some addition in Slavebase now.

 I plan to add some non-virtual functions and a few private
 datamember. You can find the changes in the attached file
 as a patch against cvs from 12-July, and in the file
 kio-patch.txt in kdenonbeta/NetManager2.


 I like to add these functions in any case, even if the DialManager
 itself doesn't make it in the next release (don't know why that
 should happen), because otherwise something like a dialmanager
 would have to wait until the next release of kiolib and slaves.
 With the changes in, the lib would be prepared for a dialmanager.
 If there is no dialmanager running, or a communication problem,
 then all things work like now.

 If you want to try out this, you should apply the patch in
 kdelibs/kio and do a make / make install in kdelibs/kio and
 kdenonbeta/NetManager2. (NetManager2 is not compiled by default.)
 This create a tryout installation which does not place any real
 phone-calls. (See the README-files.)

 Bjoern

-- 
+-----------------------------------------------------------------------+
| Björn Kahl ++ Max-Planck-Str.26 ++ 24211 Preetz ++ (ISDN) 04342 76882 |
+-----------------------------------------------------------------------+
 Weitergabe und/oder gewerbliche Nutzung meiner Adresse/TeleNr untersagt.

["kio-patch.txt" (kio-patch.txt)]

Index: slavebase.h
===================================================================
RCS file: /home/kde/kdelibs/kio/slavebase.h,v
retrieving revision 1.24
diff -u -r1.24 slavebase.h
--- slavebase.h	2000/06/30 01:02:39	1.24
+++ slavebase.h	2000/07/14 00:44:12
@@ -22,6 +22,7 @@
 
 #include <kurl.h>
 #include "kio/global.h"
+#include <dcopclient.h> // by kahl for dialmanager integration
 
 namespace KIO {
 
@@ -40,7 +41,8 @@
 {
 public:
     SlaveBase( const QCString &protocol, const QCString &pool_socket, const QCS
tring &app_socket);
-    virtual ~SlaveBase() { }
+    virtual ~SlaveBase(); // { } , by kahl : need a
+                          // slaveExiting()-call in destructor
 
     /**
      * @internal
@@ -398,6 +400,100 @@
     void cacheAuthentication(const KURL& url, const QString& user,
                              const QString& password, int auth_type);
 
+
+
+  /*
+    Next seven functions added by kahl, for communication with KNetMgr.
+    These are no-op if KNetMgr is not running.
+
+    A normal slave need only the first two, @ref requestNetwork and
+    @ref requestNetworkDone.
+  */
+ 
+    /**
+     * Used by the slave to check if it can connect
+     * to a given host. This should be called where the slave is ready
+     * to do a ::connect() on a socket. For each call to @ref
+     * requestNetwork must exist a matching call to
+     * @ref requestNetworkDone, or the system will stay online until
+     * KNetMgr gets closed (or the SlaveBase gets destructed)!
+     *
+     * If KNetMgr is not running, then this is a no-op.
+     *
+     * @param url url to connect to. this url should contain a
+     *            host-part. (Well actually we try to connect, so
+     *            better there is a host...)
+     * @return true in theorie, the host is reachable
+     *         false the system is offline and the host is in a remote network.
+     */
+    bool requestNetwork(QString& url);
+ 
+    /**
+     * Used by the slave to withdraw a connection requested by
+     * @ref requestNetwork. This function cancels the last call to
+     * @ref requestNetwork. If a client uses more than one internet
+     * connection, it must use requestNetworkDone(QString &url) to
+     * stop each request.
+     *
+     * If KNetMgr is not running, then this is a no-op.
+     *
+     * A slave should call this function every time it disconnect from a host.
+     * */
+    void requestNetworkDone(void);
+ 
+    /**
+     * Used by the slave to withdraw a connection requested by
+     * @ref requestNetwork. The host part of the url is used to
+     * identify the request to cancel, in case the slave has more than
+     * one request pending.
+     *
+     * If KNetMgr is not running, then this is a no-op.
+     *
+     * A slave should call this function every time it disconnect from a host.
+     *
+     * @param url url this slave was connected to. this url should contain a
+     *            host-part.
+     */
+    void requestNetworkDone(QString& url);
+ 
+    /**
+     * internal function. set the slaveid used in communication to KNetMgr
+     *
+     * Called in SlaveBase-constructor.
+     *
+     * A slave need this call only, if it supports more than one
+     * protocoll. Such a slave should call it when it switches to a
+     * new protocoll. (Is it possible to support more than one proto ?)
+     *
+     * @param proto id to use. typically the supported protocoll (ftp, http...)
+     *              this string gets the slave-PID added.  */
+    void setSID(const char *proto);
+ 
+    /**
+     * @internal
+     * get the slaveid used in communication to KNetMgr
+     * Used by other functions of the KNetMgr-Interface
+     *
+     * @param sid QString to fillin the id.
+     */
+  void getSID(QString &sid);
+
+   /**
+    * internal. Says good by to KNetMgr. Used in case of exit() etc.
+    * A Slave doing an abort() or exit() should call this too.
+    */
+   void slaveExiting(void);
+ 
+private:
+    /**
+     * @internal 
+     * Sets the name of the current App.
+     *
+     * @param app string describing app-socket. This function extracts
+     *            the app-name and save it in @ref lastAppName.
+     */
+  void setLastApp(const QString& app); 
+
 protected:
     /**
      * Name of the protocol supported by this slave
@@ -405,7 +501,47 @@
     QCString mProtocol;
 
     Connection * m_pConnection;
-    
+
+  //  next six added by kahl to communicate with KNetMgr.
+
+    /**
+     * @internal
+     * Name of last App that talked to us. Taken from socketname
+     * used for IPC.  Used in communication to KNetMgr.
+     */
+    QString lastAppName;
+
+    /**
+     * @internal
+     * last URL given to @ref requestNetwork.
+     * Used in communication to KNetMgr.
+     */
+    QString lastURL; /* for "requestNetworkDone(void);" */
+
+    /**
+     * @internal
+     * id of this slave. Used in communication to KNetMgr.
+     */
+    QString slaveid;
+
+    /**
+     * internal dcopobject used to communicate with KNetMgr.
+     */
+    DCOPClient client;
+
+    /**
+     * @internal
+     * flag if netmgr is enabled.
+     * this should be controlled via kcontrolcenter
+     */
+    bool isNetmgrEnabled;
+
+    /**
+     * flag if there was a communication error.
+     * if true, no further try to talk to KNetMgr will be done.
+     */
+    bool netmgrFailed;
+
 private:
     /**
      * Internal function to transmit meta data to the application.
@@ -422,6 +558,8 @@
     MetaData mOutgoingMetaData;
     MetaData mIncomingMetaData;
     bool mConnectedToApp;
+
+  // shouldn't get SlaveBase a private data pointer for BC ?
 };
 
 };
Index: slavebase.cpp
===================================================================
RCS file: /home/kde/kdelibs/kio/slavebase.cpp,v
retrieving revision 1.41
diff -u -r1.41 slavebase.cpp
--- slavebase.cpp	2000/07/10 20:14:37	1.41
+++ slavebase.cpp	2000/07/14 00:44:13
@@ -36,11 +36,13 @@
 #include <unistd.h>
 
 #include <qfile.h>
+#include <qtextstream.h> // by kahl
 
 #include <ksock.h>
 #include <kcrash.h>
 #include <kdesu/client.h>
 #include <kprotocolmanager.h>
+#include <kconfig.h> // by kahl
 
 #include "kio/slavebase.h"
 #include "kio/slaveinterface.h"
@@ -64,6 +66,9 @@
     KCrash::setCrashHandler( sigsegv_handler );
     signal( SIGPIPE, sigpipe_handler );
 
+    client.attach(); // by kahl for communication with KNetMgr
+    setSID(protocol);//     
+
     appconn = new Connection();
     listEntryCurrentSize = 0;
     struct timeval tp;
@@ -72,6 +77,22 @@
     listEntry_usec = tp.tv_usec;
     mConnectedToApp = true;
     connectSlave(mAppSocket);
+    /*
+     * for KNetMgr
+     */
+    /* this is stolen and adapted from http.cc */
+    KConfig *netmgrConfig = new KConfig("knetmgrrc", false, false);
+    if ( netmgrConfig->hasGroup("KIO") ) {
+      netmgrConfig->setGroup("KIO");
+      isNetmgrEnabled = netmgrConfig->readBoolEntry( "KIOEnable", false );
+      kdDebug(7019) << "SlaveBase-Config kioenabled = " << isNetmgrEnabled << e
ndl;
+    } else { 
+  	isNetmgrEnabled = false; // per default, NetMgr-support is disabled
+	kdDebug(7019) << "SlaveBase-Config could not read config" << endl;
+    }
+    delete netmgrConfig;
+    netmgrFailed = false;
+    setLastApp(mAppSocket);
 }
 
 void SlaveBase::dispatchLoop()
@@ -111,6 +132,9 @@
                      disconnectSlave();
                      mConnectedToApp = true;
                      connectSlave(app_socket);
+		     setLastApp(app_socket); // by kahl, for KNetMgr
+		     kdDebug(7019) << "new App: s = " << app_socket <<
+		       " , id = " << lastAppName << endl;
                   }
                   else
                   {
@@ -130,6 +154,7 @@
                   else
                   {
                      kdDebug(7019) << "slavewrapper: Communication with pool lo
st. Exiting." << endl;
+		     slaveExiting(); // by kahl for KNetMgr
                      exit(0);
                   }
                 }
@@ -138,6 +163,7 @@
         else if (retval == -1) // error
         {
           kdDebug(7019) << "slavewrapper: select returned error " << (errno==EB
ADF?"EBADF":errno==EINTR?"EINTR":errno==EINVAL?"EINVAL":errno==ENOMEM?"ENOMEM":"
unknown") << " (" << errno << ")" << endl;
+	  slaveExiting(); // by kahl for KNetMgr
           exit(0);
         }
     }
@@ -613,3 +639,217 @@
     client.setVar( (key + "-auth").utf8(), auth );
     client.setVar( (key + "-path").utf8(), path.utf8() );
 }
+
+/*
+  next seven functions added by kahl for communication with KNetMgr
+*/
+
+/**
+ * returns name of last app that talked to us.
+ * name is taken from the socketname used for IPC.
+ */
+void SlaveBase::setLastApp(const QString &app) {
+  int i;
+  i = app.find('.');
+  if (i > 0) {
+    lastAppName = app.left(i);
+  } else {
+    lastAppName = app;
+  }
+  kdDebug(7019) << "new App: s = " << app <<
+    " , id = " << lastAppName << endl; 
+  if (netmgrFailed) {
+    /*
+      Try to re-establish connection to KNetMgr.
+      I do this here, because a slave connects not so often to a new
+      App, so a failed DCOP-call wont kill performance. Testing every
+      time the slave tries to do something, might kill performance
+    */
+    QCString rapp("KNetMgr");
+    QCString robj("knetmgrKioInterface");
+    QCString rfun("kkiStatus(QString)");
+    
+    QByteArray mydata;
+    QDataStream arg( mydata, IO_WriteOnly );
+    arg << (int)0;
+    i = client.send(rapp, robj, rfun, mydata);
+    if (!i)
+      /* ok. */
+      netmgrFailed = false;
+  }
+}
+
+
+/**
+ * set the slaveid used in communication to KNetMgr
+ *
+ * @param proto id to use. typically the supported protocoll (ftp, http...)
+ * this string gets the slave-PID added.
+ */
+void SlaveBase::setSID(const char *proto) {
+  slaveid.sprintf("%s.%d", proto, getpid());
+}
+
+
+/**
+ * @internal
+ * get the slaveid used in communication to KNetMgr
+ * Used by other functions of the KNetMgr-Interface
+ *
+ * @param sid QString to fillin the id.
+ */
+void SlaveBase::getSID(QString &sid) {
+  if (slaveid.isEmpty()) {
+    sid.sprintf("%s.%d","kio",getpid()); // FIXME : better to use
+                                         // the protocoll
+                                         // (ftp, http ...) + pid
+  } else {
+    sid = slaveid;
+  }
+}
+
+
+/**
+ * request access to a networkresource.
+ * This and @ref requestNetworkDone are the main functions.
+ * A slave should call this function every time it wants to connect to a host.
+ *
+ * @param url QString-representation of the resource. At least a host
+ * must be provided. This url must be parse-able by @ref KURL
+ *
+ * @return true the host is reachable, either because it is in to
+ *         local network, or because the system currently connected to
+ *         the internet
+ *         false the host is on an remote site and the system is offline.
+ */
+bool SlaveBase::requestNetwork(QString &url) {
+  if (!isNetmgrEnabled || netmgrFailed)
+    return(true);
+
+  int resval;
+  bool res;
+  lastURL = url;
+
+  QString remapp = lastAppName;
+  if (remapp.isEmpty())
+    remapp.setLatin1("kioslave");
+
+  QString m_slaveid;
+  getSID(m_slaveid);
+
+  QCString rapp("KNetMgr");
+  QCString robj("knetmgrKioInterface");
+  QCString rfun("kkiIsOk(QString, QString, QString)");
+  QCString rret("bool");
+
+  QByteArray mydata, myreplyData;
+
+  QDataStream arg( mydata, IO_WriteOnly );
+  arg << remapp << url << m_slaveid;
+
+  kdDebug(7019) << "calling kkiIsOk:" << remapp << url << m_slaveid << endl;
+
+  resval = client.call(rapp, robj, rfun, mydata, rret, myreplyData);
+  if (resval == 0) {
+    // ok
+    QDataStream resarg(myreplyData,IO_ReadOnly);
+    resarg >> res;
+    kdDebug(7019) << " kkiIsOk - result:" << res << endl;
+    return(res);
+
+  } else {
+    // Error
+    QTextStream cerr ( stderr, IO_WriteOnly );
+    cerr << "requestNetwork (slave " << getpid() << ")\n DCOP-call failed. KNet
Mgr not running?\n";
+    // if something went wrong, we continue anyway. just like there is no KNetM
gr.
+    netmgrFailed = true;
+    return(true);
+  }
+}
+
+
+/**
+ * This and @ref requestNetwork are the main functions.
+ * A slave should call this function every time it disconnect from a host.
+ *
+ * @param url QString-representation of the resource. At least a host
+ *            must be provided. This url must be parse-able by @ref KURL
+ *
+ * The url is used to find the corresponding @ref requestNetwork call
+ * in KNetMgrs list of active requests
+ */
+void SlaveBase::requestNetworkDone(QString& url) {
+
+  if (!isNetmgrEnabled || netmgrFailed)
+    return;
+
+  int resval;
+  QString remapp = lastAppName;
+  if (remapp.isEmpty())
+    remapp.setLatin1("kioslave");
+
+  QString m_slaveid;
+  getSID(m_slaveid);
+
+  QCString rapp("KNetMgr");
+  QCString robj("knetmgrKioInterface");
+  QCString rfun("kkiDone(QString, QString, QString)");
+
+  QByteArray mydata;
+
+  QDataStream arg( mydata, IO_WriteOnly );
+  arg << remapp << url << m_slaveid;
+
+  kdDebug(7019) << "calling kkiDone:" << remapp << url << m_slaveid << endl;
+
+  resval = client.send(rapp, robj, rfun, mydata);
+  if (resval != 0) {
+    // DCOP failed
+    QTextStream cerr ( stderr, IO_WriteOnly );
+    cerr << "kkiDone (Slave " << getpid() << ") : DCOP-call failed. KNetMgr not
 running?\n";
+    netmgrFailed = true;
+  }
+  lastURL.truncate(0);
+}
+
+
+/**
+ * This and @ref requestNetwork are the main functions.
+ * A slave should call this function every time it disconnect from a host.
+ *
+ * This function does the same as the one above, but uses a saved copy
+ * of the url used in the last call to requestNetwork
+ */
+void SlaveBase::requestNetworkDone(void) {
+  if (!isNetmgrEnabled || netmgrFailed)
+    return;
+
+   if (! lastURL.isEmpty() )
+     requestNetworkDone(lastURL);
+}
+
+
+/**
+ * internal. Says good by to KNetMgr,
+ */
+void SlaveBase::slaveExiting(void) {
+  QString m_slaveid;
+  getSID(m_slaveid);
+
+  QCString rapp("KNetMgr");
+  QCString robj("knetmgrKioInterface");
+  QCString rfun("kkiDied(QString)");
+
+  QByteArray mydata;
+  QDataStream arg( mydata, IO_WriteOnly );
+  arg << m_slaveid;
+
+  kdDebug(7019) << "calling kkiDied:" << m_slaveid << endl;
+
+  client.send(rapp, robj, rfun, mydata);
+}
+
+SlaveBase::~SlaveBase() {
+  slaveExiting();
+}
+// end of addition by kahl
Index: ftp/ftp.cc
===================================================================
RCS file: /home/kde/kdelibs/kio/ftp/ftp.cc,v
retrieving revision 1.92
diff -u -r1.92 ftp.cc
--- ftp/ftp.cc	2000/07/10 20:14:37	1.92
+++ ftp/ftp.cc	2000/07/14 00:44:15
@@ -216,6 +216,8 @@
       free( nControl );
       ::close( sControl );
       sControl = 0;
+      // added by kahl for KNetMgr
+      requestNetworkDone();
     }
   }
 
@@ -292,6 +294,21 @@
   ksockaddr_in sin;
   struct servent *pse;
   int on = 1;
+
+  // added by kahl, for KNetMgr
+  //
+  KURL lastConnURL;
+  lastConnURL.setHost(host); // it would be nicer to have a real URL here ...
+  lastConnURL.setProtocol(QString::fromLatin1("ftp"));
+  //
+  QString lastConnURLString = lastConnURL.url();
+  if (!requestNetwork(lastConnURLString)) {
+    /* currently, this urls host is unreachable */
+    requestNetworkDone();
+    error(ERR_COULD_NOT_CONNECT, host );
+    return(false);
+  }
+  // end
 
   memset( &sin, 0, sizeof( sin ) );
 

End of MIME message


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic