summaryrefslogtreecommitdiff
path: root/library/network.cpp
authorkergoth <kergoth>2002-01-25 22:14:26 (UTC)
committer kergoth <kergoth>2002-01-25 22:14:26 (UTC)
commit15318cad33835e4e2dc620d033e43cd930676cdd (patch) (unidiff)
treec2fa0399a2c47fda8e2cd0092c73a809d17f68eb /library/network.cpp
downloadopie-15318cad33835e4e2dc620d033e43cd930676cdd.zip
opie-15318cad33835e4e2dc620d033e43cd930676cdd.tar.gz
opie-15318cad33835e4e2dc620d033e43cd930676cdd.tar.bz2
Initial revision
Diffstat (limited to 'library/network.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--library/network.cpp436
1 files changed, 436 insertions, 0 deletions
diff --git a/library/network.cpp b/library/network.cpp
new file mode 100644
index 0000000..7d51016
--- a/dev/null
+++ b/library/network.cpp
@@ -0,0 +1,436 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "qpe/network.h"
22#include "qpe/networkinterface.h"
23#include "qpe/global.h"
24#include "qpe/config.h"
25#include "qpe/resource.h"
26#include "qpe/qpeapplication.h"
27#include <qpe/qcopenvelope_qws.h>
28#include <qpe/qlibrary.h>
29
30#include <qlistbox.h>
31#include <qdir.h>
32#include <qlayout.h>
33#include <qdict.h>
34#include <qtranslator.h>
35
36#include <stdlib.h>
37
38class NetworkEmitter : public QCopChannel {
39 Q_OBJECT
40public:
41 NetworkEmitter() : QCopChannel("QPE/Network",qApp)
42 {
43 }
44
45 void receive(const QCString &msg, const QByteArray&)
46 {
47 if ( msg == "choicesChanged()" )
48 emit changed();
49 }
50
51signals:
52 void changed();
53};
54
55/*!
56 \internal
57
58 Requests that the service \a choice be started. The \a password is
59 the password to use if required.
60*/
61void Network::start(const QString& choice, const QString& password)
62{
63 QCopEnvelope e("QPE/Network", "start(QString,QString)");
64 e << choice << password;
65}
66
67/*!
68 \class Network network.h
69 \brief The Network class provides network access functionality.
70*/
71
72// copy the proxy settings of the active config over to the Proxies.conf file
73/*!
74 \internal
75*/
76void Network::writeProxySettings( Config &cfg )
77{
78 Config proxy( Network::settingsDir() + "/Proxies.conf", Config::File );
79 proxy.setGroup("Properties");
80 cfg.setGroup("Proxy");
81 proxy.writeEntry("type", cfg.readEntry("type") );
82 proxy.writeEntry("autoconfig", cfg.readEntry("autoconfig") );
83 proxy.writeEntry("httphost", cfg.readEntry("httphost") );
84 proxy.writeEntry("httpport", cfg.readEntry("httpport") );
85 proxy.writeEntry("ftphost", cfg.readEntry("ftphost") );
86 proxy.writeEntry("ftpport", cfg.readEntry("ftpport") );
87 proxy.writeEntry("noproxies", cfg.readEntry("noproxies") );
88 cfg.setGroup("Properties");
89}
90
91
92
93/*!
94 \internal
95
96 Stops the current network service.
97*/
98void Network::stop()
99{
100 QCopEnvelope e("QPE/Network", "stop()");
101}
102
103static NetworkEmitter *emitter = 0;
104
105/*!
106 \internal
107*/
108void Network::connectChoiceChange(QObject* receiver, const char* slot)
109{
110 if ( !emitter )
111 emitter = new NetworkEmitter;
112 QObject::connect(emitter,SIGNAL(changed()),receiver,slot);
113}
114
115/*!
116 \internal
117*/
118QString Network::settingsDir()
119{
120 return Global::applicationFileName("Network", "modules");
121}
122
123/*!
124 \internal
125*/
126QStringList Network::choices(QListBox* lb, const QString& dir)
127{
128 QStringList list;
129
130 if ( lb )
131 lb->clear();
132
133 QString adir = dir.isEmpty() ? settingsDir() : dir;
134 QDir settingsdir(adir);
135 settingsdir.mkdir(adir);
136
137 QStringList files = settingsdir.entryList("*.conf");
138 for (QStringList::ConstIterator it=files.begin(); it!=files.end(); ++it ) {
139 QString filename = settingsdir.filePath(*it);
140 Config cfg(filename, Config::File);
141 cfg.setGroup("Info");
142 if ( lb )
143 lb->insertItem(Resource::loadPixmap("Network/" + cfg.readEntry("Type")),
144 cfg.readEntry("Name"));
145 list.append(filename);
146 }
147
148 return list;
149}
150
151class NetworkServer : public QCopChannel {
152 Q_OBJECT
153public:
154 NetworkServer(QObject* parent) : QCopChannel("QPE/Network",parent)
155 {
156 up = FALSE;
157 examineNetworks( TRUE );
158 QCopChannel* card = new QCopChannel("QPE/Card",parent);
159 connect(card,SIGNAL(received(const QCString &, const QByteArray&)),
160 this,SLOT(cardMessage(const QCString &, const QByteArray&)));
161 }
162
163 ~NetworkServer()
164 {
165 stop();
166 }
167
168 bool networkOnline() const
169 {
170 return up;
171 }
172
173private:
174 void receive(const QCString &msg, const QByteArray& data)
175 {
176 if ( msg == "start(QString,QString)" ) {
177 QDataStream stream(data,IO_ReadOnly);
178 QString file,password;
179 stream >> file >> password;
180 if ( file.isEmpty() ) {
181 QStringList l = Network::choices();
182 for (QStringList::ConstIterator i=l.begin(); i!=l.end(); ++i) {
183 Config cfg(*i,Config::File);
184 cfg.setGroup("Info");
185 QString type = cfg.readEntry("Type");
186 NetworkInterface* plugin = Network::loadPlugin(type);
187 cfg.setGroup("Properties");
188 if ( plugin && plugin->isAvailable(cfg) ) {
189 file = *i;
190 break;
191 }
192 }
193 if ( file.isEmpty() ) {
194 QCopEnvelope("QPE/Network", "failed()");
195 return;
196 }
197 }
198 start(file,password);
199 } else if ( msg == "stop()" ) {
200 stop();
201 } else if ( msg == "choicesChanged()" ) {
202 examineNetworks();
203 }
204 }
205
206private slots:
207 void cardMessage(const QCString &msg, const QByteArray&)
208 {
209 if ( msg == "stabChanged()" )
210 examineNetworks();
211 }
212
213private:
214 void examineNetworks( bool firstStart = FALSE )
215 {
216 QStringList l = Network::choices();
217 bool wasup = up; up=FALSE;
218 QStringList pavailable = available;
219 available.clear();
220 for (QStringList::ConstIterator it=l.begin(); it!=l.end(); ++it) {
221 Config cfg(*it,Config::File);
222 cfg.setGroup("Info");
223 QString type = cfg.readEntry("Type");
224 NetworkInterface* plugin = Network::loadPlugin(type);
225 cfg.setGroup("Properties");
226 if ( plugin ) {
227 if ( plugin->isActive(cfg) ) {
228 up = TRUE;
229 if ( firstStart )
230 plugin->start( cfg );
231 }
232 if ( plugin->isAvailable(cfg) )
233 available.append(*it);
234 }
235 }
236
237 // Try to work around unreproducible bug whereby
238 // the netmon applet shows wrong state.
239 bool reannounce = wait<0;
240
241 if ( available != pavailable || reannounce ) {
242 QCopEnvelope e("QPE/Network", "available(QStringList)");
243 e << available;
244 }
245 if ( up != wasup || reannounce ) {
246 QCopEnvelope("QPE/Network", up ? "up()" : "down()");
247 }
248 }
249
250 void start( const QString& file, const QString& password )
251 {
252 if ( !current.isEmpty() )
253 stop();
254 current = QString::null;
255 Config cfg(file, Config::File);
256 cfg.setGroup("Info");
257 QString type = cfg.readEntry("Type");
258 NetworkInterface* plugin = Network::loadPlugin(type);
259 bool started = FALSE;
260 if ( plugin ) {
261 cfg.setGroup("Properties");
262 if ( plugin->start(cfg,password) ) {
263 Network::writeProxySettings( cfg );
264 current = file;
265 wait=0;
266 startTimer(400);
267 started = TRUE;
268 }
269 }
270 if ( !started ) {
271 QCopEnvelope("QPE/Network", "failed()");
272 }
273 }
274
275 void stop()
276 {
277 bool stopped = FALSE;
278 if ( !current.isEmpty() ) {
279 Config cfg(current, Config::File);
280 cfg.setGroup("Info");
281 QString type = cfg.readEntry("Type");
282 NetworkInterface* plugin = Network::loadPlugin(type);
283 if ( plugin ) {
284 cfg.setGroup("Properties");
285 if ( plugin->stop(cfg) ) {
286 current = QString::null;
287 wait=0;
288 startTimer(400);
289 stopped = TRUE;
290 }
291 }
292 }
293 if ( !stopped ) {
294 QCopEnvelope("QPE/Network", "failed()");
295 }
296 }
297
298 void timerEvent(QTimerEvent*)
299 {
300 examineNetworks();
301 if ( wait >= 0 ) {
302 if ( up == !current.isNull() ) {
303 // done
304 killTimers();
305 if ( up ) {
306 startTimer(3000); // monitor link
307 wait = -1;
308 }
309 } else {
310 wait++;
311 if ( wait == 600 ) {
312 killTimers(); // forget about it after 240 s
313 QCopEnvelope("QPE/Network", "failed()");
314 up = !current.isNull();
315 }
316 }
317 } else if ( !up ) {
318 killTimers();
319 }
320 }
321
322private:
323 QStringList available;
324 QString current;
325 bool up;
326 int wait;
327};
328
329static NetworkServer* ns=0;
330
331/*!
332 \internal
333*/
334QString Network::serviceName(const QString& service)
335{
336 Config cfg(service, Config::File);
337 cfg.setGroup("Info");
338 return cfg.readEntry("Name");
339}
340
341/*!
342 \internal
343*/
344QString Network::serviceType(const QString& service)
345{
346 Config cfg(service, Config::File);
347 cfg.setGroup("Info");
348 return cfg.readEntry("Type");
349}
350
351/*!
352 \internal
353*/
354bool Network::serviceNeedsPassword(const QString& service)
355{
356 Config cfg(service,Config::File);
357 cfg.setGroup("Info");
358 QString type = cfg.readEntry("Type");
359 NetworkInterface* plugin = Network::loadPlugin(type);
360 cfg.setGroup("Properties");
361 return plugin ? plugin->needPassword(cfg) : FALSE;
362}
363
364/*!
365 \internal
366*/
367bool Network::networkOnline()
368{
369 return ns && ns->networkOnline();
370}
371
372/*!
373 \internal
374*/
375void Network::createServer(QObject* parent)
376{
377 ns = new NetworkServer(parent);
378}
379
380/*!
381 \internal
382*/
383int Network::addStateWidgets(QWidget* parent)
384{
385 int n=0;
386 QStringList l = Network::choices();
387 QVBoxLayout* vb = new QVBoxLayout(parent);
388 for (QStringList::ConstIterator it=l.begin(); it!=l.end(); ++it) {
389 Config cfg(*it,Config::File);
390 cfg.setGroup("Info");
391 QString type = cfg.readEntry("Type");
392 NetworkInterface* plugin = Network::loadPlugin(type);
393 cfg.setGroup("Properties");
394 if ( plugin ) {
395 QWidget* w;
396 if ( (w=plugin->addStateWidget(parent,cfg)) ) {
397 n++;
398 vb->addWidget(w);
399 }
400 }
401 }
402 return n;
403}
404
405static QDict<NetworkInterface> *ifaces;
406
407/*!
408 \internal
409*/
410NetworkInterface* Network::loadPlugin(const QString& type)
411{
412#ifndef QT_NO_COMPONENT
413 if ( !ifaces ) ifaces = new QDict<NetworkInterface>;
414 NetworkInterface *iface = ifaces->find(type);
415 if ( !iface ) {
416 QString libfile = QPEApplication::qpeDir() + "/plugins/network/lib" + type + ".so";
417 QLibrary lib(libfile);
418 if ( !lib.queryInterface( IID_Network, (QUnknownInterface**)&iface ) == QS_OK )
419 return 0;
420 ifaces->insert(type,iface);
421 QString lang = getenv( "LANG" );
422 QTranslator * trans = new QTranslator(qApp);
423 QString tfn = QPEApplication::qpeDir()+"/i18n/"+lang+"/lib"+type+".qm";
424 if ( trans->load( tfn ))
425 qApp->installTranslator( trans );
426 else
427 delete trans;
428
429 }
430 return iface;
431#else
432 return 0;
433#endif
434}
435
436#include "network.moc"