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

List:       kde-core-devel
Subject:    Re: Addition to kio-SlaveBase (V. II)
From:       Bjoern Kahl <Bjoern.Kahl () kiel ! netsurf ! de>
Date:       2000-07-14 23:58:48
[Download RAW message or body]

This message is in MIME format

 Hallo !

On 14-Jul-00 Stephan Kulow wrote:
>  Bjoern Kahl wrote:

> >  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.
  (A new revision is attached to this mail and in the named file.)

>  Well, could you make this a bit more the way the other members are?
>  For example use const QString& for the protocol, KURL for urls and
>  return values instead of references?

 I have changed it.

>  And I don't like functions named kkkiDied in an interface - don't you
>  have something more descriptive?

 I thought, it was descriptive. "kki" is a praefix "KnetmgrKioInterface"
 and "Died" ... well, Slave has gone, let it rest in peace. (May be I
 stumpled over my english here, it tried to use the past participle 
 of "to die" (in german: "gestorben").)

>  
>  Besides that I don't object - I just would like to know what a
>  "normal slave" is from your documentation.

 Each slave that implement only one protocoll and is connected
 to only one host at a time.
 Probably all slaves, but I tried to make it as open as possible.
 I think I remove the word from the documentation.

>  I guess KNetMngr decides if it has to dial if you access a
>  host in your local network, right? And how does it know
>  without dialing for the DNS server?

 The KNetMgr builds a list of known host. Every time a host is
 unknown it asks the user. Typically, a user would enter the 
 names of local hosts and networks, and then set the default
 location to "remote". That way the KNetMgr knows what to do
 (KNetMgr doesn't ask, if it can find the host in its list, or a
 default location is given).


 If there are no more objections,
 I will commit the patch Sunday morning.


 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 23:55:45
@@ -22,11 +22,14 @@
 
 #include <kurl.h>
 #include "kio/global.h"
+#include <dcopclient.h> // by kahl for dialmanager integration
 
 namespace KIO {
 
 class Connection;
 
+class SlaveBasePrivate; // dummy for BC private data pointer (by kahl)
+
 /**
  * There are two classes that specifies the protocol between application (job)
  * and kioslave. SlaveInterface is the class to use on the application end,
@@ -40,7 +43,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 +402,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(KURL& 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(KURL& 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 QCString &proto);
+ 
+    /**
+     * @internal
+     * get the slaveid used in communication to KNetMgr
+     * Used by other functions of the KNetMgr-Interface
+     *
+     * @return QString with the id.
+     */
+  QString getSID(void);
+
+   /**
+    * 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 +503,53 @@
     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.
+     */
+    KURL 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;
+
+    /**
+     * @internal
+     * BC data pointer
+     */
+    SlaveBasePrivate *bc_d;
+
 private:
     /**
      * Internal function to transmit meta data to the application.
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 23:55:45
@@ -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 QCString &proto) {
+  slaveid.sprintf("%s.%d", (const char *)proto, getpid());
+  kdDebug(7019) << "new Slaveid " << slaveid << endl;
+}
+
+
+/**
+ * @internal
+ * get the slaveid used in communication to KNetMgr
+ * Used by other functions of the KNetMgr-Interface
+ *
+ * @return QString with slave id.
+ */
+QString SlaveBase::getSID(void) {
+  QString sid;
+  if (slaveid.isEmpty()) {
+    sid.sprintf("%s.%d","kio",getpid()); // FIXME : better to use
+                                         // the protocoll
+                                         // (ftp, http ...) + pid
+  } else {
+    sid = slaveid;
+  }
+  return(sid);
+}
+
+
+/**
+ * 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(KURL &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();
+
+  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.url() << m_slaveid;
+
+  kdDebug(7019) << "calling kkiIsOk:" << remapp << url.url() << m_slaveid << en
dl;
+
+  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(KURL& url) {
+
+  if (!isNetmgrEnabled || netmgrFailed)
+    return;
+
+  int resval;
+  QString remapp = lastAppName;
+  if (remapp.isEmpty())
+    remapp.setLatin1("kioslave");
+
+  QString m_slaveid = getSID();
+
+  QCString rapp("KNetMgr");
+  QCString robj("knetmgrKioInterface");
+  QCString rfun("kkiDone(QString, QString, QString)");
+
+  QByteArray mydata;
+
+  QDataStream arg( mydata, IO_WriteOnly );
+  arg << remapp << url.url() << m_slaveid;
+
+  kdDebug(7019) << "calling kkiDone:" << remapp << url.url() << m_slaveid << en
dl;
+
+  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 = KURL(); // "";
+}
+
+
+/**
+ * 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();
+
+  QCString rapp("KNetMgr");
+  QCString robj("knetmgrKioInterface");
+  QCString rfun("kkiSlaveDied(QString)");
+
+  QByteArray mydata;
+  QDataStream arg( mydata, IO_WriteOnly );
+  arg << m_slaveid;
+
+  kdDebug(7019) << "calling kkiSlaveDied:" << m_slaveid << endl;
+
+  client.send(rapp, robj, rfun, mydata);
+}
+
+SlaveBase::~SlaveBase() {
+  slaveExiting();
+}
+// end of addition by kahl

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