summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/net/networksetup/kprocctrl.cpp267
-rw-r--r--noncore/net/networksetup/kprocctrl.h120
-rw-r--r--noncore/net/networksetup/kprocess.cpp919
-rw-r--r--noncore/net/networksetup/kprocess.h804
-rw-r--r--noncore/net/networksetup/mainwindowimp.cpp208
-rw-r--r--noncore/net/networksetup/mainwindowimp.h5
-rw-r--r--noncore/net/networksetup/networksetup.pro6
-rw-r--r--noncore/net/networksetup/ppp/.cvsignore23
-rw-r--r--noncore/net/networksetup/ppp/ppp.ui770
-rw-r--r--noncore/settings/networksettings/kprocctrl.cpp267
-rw-r--r--noncore/settings/networksettings/kprocctrl.h120
-rw-r--r--noncore/settings/networksettings/kprocess.cpp919
-rw-r--r--noncore/settings/networksettings/kprocess.h804
-rw-r--r--noncore/settings/networksettings/mainwindowimp.cpp208
-rw-r--r--noncore/settings/networksettings/mainwindowimp.h5
-rw-r--r--noncore/settings/networksettings/networksetup.pro6
-rw-r--r--noncore/settings/networksettings/ppp/.cvsignore23
-rw-r--r--noncore/settings/networksettings/ppp/ppp.ui770
18 files changed, 1792 insertions, 4452 deletions
diff --git a/noncore/net/networksetup/kprocctrl.cpp b/noncore/net/networksetup/kprocctrl.cpp
deleted file mode 100644
index cd8711a..0000000
--- a/noncore/net/networksetup/kprocctrl.cpp
+++ b/dev/null
@@ -1,267 +0,0 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 1997 Christian Czezakte (e9025461@student.tuwien.ac.at)
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA.
18*/
19//
20// KPROCESSCONTROLLER -- A helper class for KProcess
21//
22// version 0.3.1, Jan, 8th 1997
23//
24// (C) Christian Czezatke
25// e9025461@student.tuwien.ac.at
26//
27
28//#include <config.h>
29
30#include <sys/types.h>
31#include <sys/socket.h>
32
33#include <errno.h>
34#include <fcntl.h>
35#include <stdio.h>
36#include <string.h>
37#include <unistd.h>
38#include <assert.h>
39
40#include <qsocketnotifier.h>
41#include "kprocess.h"
42#include "kprocctrl.h"
43
44KProcessController *KProcessController::theKProcessController = 0;
45
46struct sigaction KProcessController::oldChildHandlerData;
47bool KProcessController::handlerSet = false;
48
49KProcessController::KProcessController()
50{
51 assert( theKProcessController == 0 );
52
53 if (0 > pipe(fd))
54 printf(strerror(errno));
55
56 notifier = new QSocketNotifier(fd[0], QSocketNotifier::Read);
57 notifier->setEnabled(true);
58 QObject::connect(notifier, SIGNAL(activated(int)),
59 this, SLOT(slotDoHousekeeping(int)));
60 connect( &delayedChildrenCleanupTimer, SIGNAL( timeout()),
61 SLOT( delayedChildrenCleanup()));
62
63 theKProcessController = this;
64
65 setupHandlers();
66}
67
68
69void KProcessController::setupHandlers()
70{
71 if( handlerSet )
72 return;
73 struct sigaction act;
74 act.sa_handler=theSigCHLDHandler;
75 sigemptyset(&(act.sa_mask));
76 sigaddset(&(act.sa_mask), SIGCHLD);
77 // Make sure we don't block this signal. gdb tends to do that :-(
78 sigprocmask(SIG_UNBLOCK, &(act.sa_mask), 0);
79
80 act.sa_flags = SA_NOCLDSTOP;
81
82 // CC: take care of SunOS which automatically restarts interrupted system
83 // calls (and thus does not have SA_RESTART)
84
85#ifdef SA_RESTART
86 act.sa_flags |= SA_RESTART;
87#endif
88
89 sigaction( SIGCHLD, &act, &oldChildHandlerData );
90
91 act.sa_handler=SIG_IGN;
92 sigemptyset(&(act.sa_mask));
93 sigaddset(&(act.sa_mask), SIGPIPE);
94 act.sa_flags = 0;
95 sigaction( SIGPIPE, &act, 0L);
96 handlerSet = true;
97}
98
99void KProcessController::resetHandlers()
100{
101 if( !handlerSet )
102 return;
103 sigaction( SIGCHLD, &oldChildHandlerData, 0 );
104 // there should be no problem with SIGPIPE staying SIG_IGN
105 handlerSet = false;
106}
107
108// block SIGCHLD handler, because it accesses processList
109void KProcessController::addKProcess( KProcess* p )
110{
111 sigset_t newset, oldset;
112 sigemptyset( &newset );
113 sigaddset( &newset, SIGCHLD );
114 sigprocmask( SIG_BLOCK, &newset, &oldset );
115 processList.append( p );
116 sigprocmask( SIG_SETMASK, &oldset, 0 );
117}
118
119void KProcessController::removeKProcess( KProcess* p )
120{
121 sigset_t newset, oldset;
122 sigemptyset( &newset );
123 sigaddset( &newset, SIGCHLD );
124 sigprocmask( SIG_BLOCK, &newset, &oldset );
125 processList.remove( p );
126 sigprocmask( SIG_SETMASK, &oldset, 0 );
127}
128
129//using a struct which contains both the pid and the status makes it easier to write
130//and read the data into the pipe
131//especially this solves a problem which appeared on my box where slotDoHouseKeeping() received
132//only 4 bytes (with some debug output around the write()'s it received all 8 bytes)
133//don't know why this happened, but when writing all 8 bytes at once it works here, aleXXX
134struct waitdata
135{
136 pid_t pid;
137 int status;
138};
139
140void KProcessController::theSigCHLDHandler(int arg)
141{
142 struct waitdata wd;
143// int status;
144// pid_t this_pid;
145 int saved_errno;
146
147 saved_errno = errno;
148 // since waitpid and write change errno, we have to save it and restore it
149 // (Richard Stevens, Advanced programming in the Unix Environment)
150
151 bool found = false;
152 if( theKProcessController != 0 ) {
153 // iterating the list doesn't perform any system call
154 for( QValueList<KProcess*>::ConstIterator it = theKProcessController->processList.begin();
155 it != theKProcessController->processList.end();
156 ++it )
157 {
158 if( !(*it)->isRunning())
159 continue;
160 wd.pid = waitpid( (*it)->pid(), &wd.status, WNOHANG );
161 if ( wd.pid > 0 ) {
162 ::write(theKProcessController->fd[1], &wd, sizeof(wd));
163 found = true;
164 }
165 }
166 }
167 if( !found && oldChildHandlerData.sa_handler != SIG_IGN
168 && oldChildHandlerData.sa_handler != SIG_DFL )
169 oldChildHandlerData.sa_handler( arg ); // call the old handler
170 // handle the rest
171 if( theKProcessController != 0 ) {
172 static const struct waitdata dwd = { 0, 0 }; // delayed waitpid()
173 ::write(theKProcessController->fd[1], &dwd, sizeof(dwd));
174 } else {
175 int dummy;
176 while( waitpid( -1, &dummy, WNOHANG ) > 0 )
177 ;
178 }
179
180 errno = saved_errno;
181}
182
183
184
185void KProcessController::slotDoHousekeeping(int )
186{
187 unsigned int bytes_read = 0;
188 unsigned int errcnt=0;
189 // read pid and status from the pipe.
190 struct waitdata wd;
191 while ((bytes_read < sizeof(wd)) && (errcnt < 50)) {
192 int r = ::read(fd[0], ((char *)&wd) + bytes_read, sizeof(wd) - bytes_read);
193 if (r > 0) bytes_read += r;
194 else if (r < 0) errcnt++;
195 }
196 if (errcnt >= 50) {
197 fprintf(stderr,
198 "Error: Max. error count for pipe read "
199 "exceeded in KProcessController::slotDoHousekeeping\n");
200 return; // it makes no sense to continue here!
201 }
202 if (bytes_read != sizeof(wd)) {
203 fprintf(stderr,
204 "Error: Could not read info from signal handler %d <> %d!\n",
205 bytes_read, sizeof(wd));
206 return; // it makes no sense to continue here!
207 }
208 if (wd.pid==0) { // special case, see delayedChildrenCleanup()
209 delayedChildrenCleanupTimer.start( 1000, true );
210 return;
211 }
212
213 for( QValueList<KProcess*>::ConstIterator it = processList.begin();
214 it != processList.end();
215 ++it ) {
216 KProcess* proc = *it;
217 if (proc->pid() == wd.pid) {
218 // process has exited, so do emit the respective events
219 if (proc->run_mode == KProcess::Block) {
220 // If the reads are done blocking then set the status in proc
221 // but do nothing else because KProcess will perform the other
222 // actions of processHasExited.
223 proc->status = wd.status;
224 proc->runs = false;
225 } else {
226 proc->processHasExited(wd.status);
227 }
228 return;
229 }
230 }
231}
232
233// this is needed e.g. for popen(), which calls waitpid() checking
234// for its forked child, if we did waitpid() directly in the SIGCHLD
235// handler, popen()'s waitpid() call would fail
236void KProcessController::delayedChildrenCleanup()
237{
238 struct waitdata wd;
239 while(( wd.pid = waitpid( -1, &wd.status, WNOHANG ) ) > 0 ) {
240 for( QValueList<KProcess*>::ConstIterator it = processList.begin();
241 it != processList.end();
242 ++it )
243 {
244 if( !(*it)->isRunning() || (*it)->pid() != wd.pid )
245 continue;
246 // it's KProcess, handle it
247 ::write(fd[1], &wd, sizeof(wd));
248 break;
249 }
250 }
251}
252
253KProcessController::~KProcessController()
254{
255 assert( theKProcessController == this );
256 resetHandlers();
257
258 notifier->setEnabled(false);
259
260 close(fd[0]);
261 close(fd[1]);
262
263 delete notifier;
264 theKProcessController = 0;
265}
266
267//#include "kprocctrl.moc"
diff --git a/noncore/net/networksetup/kprocctrl.h b/noncore/net/networksetup/kprocctrl.h
deleted file mode 100644
index ac82b9d..0000000
--- a/noncore/net/networksetup/kprocctrl.h
+++ b/dev/null
@@ -1,120 +0,0 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 1997 Christian Czezakte (e9025461@student.tuwien.ac.at)
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA.
18*/
19//
20// KPROCESSCONTROLLER -- A helper class for KProcess
21//
22// version 0.3.1, Jan 8th 1997
23//
24// (C) Christian Czezatke
25// e9025461@student.tuwien.ac.at
26//
27
28#ifndef __KPROCCTRL_H__
29#define __KPROCCTRL_H__
30
31#include <qvaluelist.h>
32#include <qtimer.h>
33
34#include "kprocess.h"
35
36class KProcessControllerPrivate;
37class QSocketNotifier;
38
39/**
40 * @short Used internally by @ref KProcess
41 * @internal
42 * @author Christian Czezakte <e9025461@student.tuwien.ac.at>
43 *
44 * A class for internal use by KProcess only. -- Exactly one instance
45 * of this class is generated by the first instance of KProcess that is
46 * created (a pointer to it gets stored in @ref theKProcessController ).
47 *
48 * This class takes care of the actual (UN*X) signal handling.
49*/
50class KProcessController : public QObject
51{
52 Q_OBJECT
53
54public:
55 KProcessController();
56 ~KProcessController();
57 //CC: WARNING! Destructor Not virtual (but you don't derive classes from this anyhow...)
58
59public:
60
61 /**
62 * Only a single instance of this class is allowed at a time,
63 * and this static variable is used to track the one instance.
64 */
65 static KProcessController *theKProcessController;
66
67 /**
68 * Automatically called upon SIGCHLD.
69 *
70 * Normally you do not need to do anything with this function but
71 * if your application needs to disable SIGCHLD for some time for
72 * reasons beyond your control, you should call this function afterwards
73 * to make sure that no SIGCHLDs where missed.
74 */
75 static void theSigCHLDHandler(int signal);
76 // handler for sigchld
77
78 /**
79 * @internal
80 */
81 static void setupHandlers();
82 /**
83 * @internal
84 */
85 static void resetHandlers();
86 /**
87 * @internal
88 */
89 void addKProcess( KProcess* );
90 /**
91 * @internal
92 */
93 void removeKProcess( KProcess* );
94 public slots:
95 /**
96 * @internal
97 */
98 void slotDoHousekeeping(int socket);
99
100 private slots:
101 void delayedChildrenCleanup();
102private:
103 int fd[2];
104 QSocketNotifier *notifier;
105 static struct sigaction oldChildHandlerData;
106 static bool handlerSet;
107 QValueList<KProcess*> processList;
108 QTimer delayedChildrenCleanupTimer;
109
110 // Disallow assignment and copy-construction
111 KProcessController( const KProcessController& );
112 KProcessController& operator= ( const KProcessController& );
113
114 KProcessControllerPrivate *d;
115};
116
117
118
119#endif
120
diff --git a/noncore/net/networksetup/kprocess.cpp b/noncore/net/networksetup/kprocess.cpp
deleted file mode 100644
index 193ec9b..0000000
--- a/noncore/net/networksetup/kprocess.cpp
+++ b/dev/null
@@ -1,919 +0,0 @@
1/*
2
3 $Id$
4
5 This file is part of the KDE libraries
6 Copyright (C) 1997 Christian Czezatke (e9025461@student.tuwien.ac.at)
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
17
18 You should have received a copy of the GNU Library General Public License
19 along with this library; see the file COPYING.LIB. If not, write to
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.
22*/
23
24
25//
26// KPROCESS -- A class for handling child processes in KDE without
27// having to take care of Un*x specific implementation details
28//
29// version 0.3.1, Jan 8th 1998
30//
31// (C) Christian Czezatke
32// e9025461@student.tuwien.ac.at
33//
34// Changes:
35//
36// March 2nd, 1998: Changed parameter list for KShellProcess:
37// Arguments are now placed in a single string so that
38// <shell> -c <commandstring> is passed to the shell
39// to make the use of "operator<<" consistent with KProcess
40
41#include "kprocess.h"
42#define _MAY_INCLUDE_KPROCESSCONTROLLER_
43#include "kprocctrl.h"
44
45//#include <config.h>
46
47#include <qglobal.h>
48#include <qmap.h>
49#include <qfile.h>
50#include <qsocketnotifier.h>
51#include <qregexp.h>
52
53#include <sys/time.h>
54#include <sys/types.h>
55#include <sys/stat.h>
56#include <sys/socket.h>
57
58#include <errno.h>
59#include <fcntl.h>
60#include <stdlib.h>
61#include <signal.h>
62#include <stdio.h>
63#include <string.h>
64#include <unistd.h>
65#ifdef HAVE_SYS_SELECT_H
66#include <sys/select.h>
67#endif
68#ifdef HAVE_INITGROUPS
69#include <grp.h>
70#endif
71#include <pwd.h>
72
73#include <qapplication.h>
74//#include <kdebug.h>
75
76/////////////////////////////
77// public member functions //
78/////////////////////////////
79
80class KProcessPrivate {
81public:
82 KProcessPrivate() : useShell(false) { }
83
84 bool useShell;
85 QMap<QString,QString> env;
86 QString wd;
87 QCString shell;
88};
89
90#define Q_CHECK_PTR(a)
91
92KProcess::KProcess()
93 : QObject(),
94 run_mode(NotifyOnExit),
95 runs(false),
96 pid_(0),
97 status(0),
98 keepPrivs(false),
99 innot(0),
100 outnot(0),
101 errnot(0),
102 communication(NoCommunication),
103 input_data(0),
104 input_sent(0),
105 input_total(0),
106 d(0)
107{
108 if (0 == KProcessController::theKProcessController) {
109 (void) new KProcessController();
110 Q_CHECK_PTR(KProcessController::theKProcessController);
111 }
112
113 KProcessController::theKProcessController->addKProcess(this);
114 out[0] = out[1] = -1;
115 in[0] = in[1] = -1;
116 err[0] = err[1] = -1;
117}
118
119void
120KProcess::setEnvironment(const QString &name, const QString &value)
121{
122 if (!d)
123 d = new KProcessPrivate;
124 d->env.insert(name, value);
125}
126
127void
128KProcess::setWorkingDirectory(const QString &dir)
129{
130 if (!d)
131 d = new KProcessPrivate;
132 d->wd = dir;
133}
134
135void
136KProcess::setupEnvironment()
137{
138 if (d)
139 {
140 QMap<QString,QString>::Iterator it;
141 for(it = d->env.begin(); it != d->env.end(); ++it)
142 setenv(QFile::encodeName(it.key()).data(),
143 QFile::encodeName(it.data()).data(), 1);
144 if (!d->wd.isEmpty())
145 chdir(QFile::encodeName(d->wd).data());
146 }
147}
148
149void
150KProcess::setRunPrivileged(bool keepPrivileges)
151{
152 keepPrivs = keepPrivileges;
153}
154
155bool
156KProcess::runPrivileged() const
157{
158 return keepPrivs;
159}
160
161
162KProcess::~KProcess()
163{
164 // destroying the KProcess instance sends a SIGKILL to the
165 // child process (if it is running) after removing it from the
166 // list of valid processes (if the process is not started as
167 // "DontCare")
168
169 KProcessController::theKProcessController->removeKProcess(this);
170 // this must happen before we kill the child
171 // TODO: block the signal while removing the current process from the process list
172
173 if (runs && (run_mode != DontCare))
174 kill(SIGKILL);
175
176 // Clean up open fd's and socket notifiers.
177 closeStdin();
178 closeStdout();
179 closeStderr();
180
181 // TODO: restore SIGCHLD and SIGPIPE handler if this is the last KProcess
182 delete d;
183}
184
185void KProcess::detach()
186{
187 KProcessController::theKProcessController->removeKProcess(this);
188
189 runs = false;
190 pid_ = 0;
191
192 // Clean up open fd's and socket notifiers.
193 closeStdin();
194 closeStdout();
195 closeStderr();
196}
197
198bool KProcess::setExecutable(const QString& proc)
199{
200 if (runs) return false;
201
202 if (proc.isEmpty()) return false;
203
204 if (!arguments.isEmpty())
205 arguments.remove(arguments.begin());
206 arguments.prepend(QFile::encodeName(proc));
207
208 return true;
209}
210
211KProcess &KProcess::operator<<(const QStringList& args)
212{
213 QStringList::ConstIterator it = args.begin();
214 for ( ; it != args.end() ; ++it )
215 arguments.append(QFile::encodeName(*it));
216 return *this;
217}
218
219KProcess &KProcess::operator<<(const QCString& arg)
220{
221 return operator<< (arg.data());
222}
223
224KProcess &KProcess::operator<<(const char* arg)
225{
226 arguments.append(arg);
227 return *this;
228}
229
230KProcess &KProcess::operator<<(const QString& arg)
231{
232 arguments.append(QFile::encodeName(arg));
233 return *this;
234}
235
236void KProcess::clearArguments()
237{
238 arguments.clear();
239}
240
241bool KProcess::start(RunMode runmode, Communication comm)
242{
243 uint i;
244 uint n = arguments.count();
245 char **arglist;
246
247 if (runs || (0 == n)) {
248 return false; // cannot start a process that is already running
249 // or if no executable has been assigned
250 }
251 run_mode = runmode;
252 status = 0;
253
254 QCString shellCmd;
255 if (d && d->useShell)
256 {
257 if (d->shell.isEmpty())
258 {
259 //kdDebug() << "Could not find a valid shell\n" << endl;
260 return false;
261 }
262
263 arglist = static_cast<char **>(malloc( (4)*sizeof(char *)));
264 for (i=0; i < n; i++) {
265 shellCmd += arguments[i];
266 shellCmd += " "; // CC: to separate the arguments
267 }
268
269 arglist[0] = d->shell.data();
270 arglist[1] = (char *) "-c";
271 arglist[2] = shellCmd.data();
272 arglist[3] = 0;
273 }
274 else
275 {
276 arglist = static_cast<char **>(malloc( (n+1)*sizeof(char *)));
277 for (i=0; i < n; i++)
278 arglist[i] = arguments[i].data();
279 arglist[n]= 0;
280 }
281
282 setupCommunication(comm);
283 //)
284 //kdDebug() << "Could not setup Communication!\n";
285
286 // We do this in the parent because if we do it in the child process
287 // gdb gets confused when the application runs from gdb.
288 uid_t uid = getuid();
289 gid_t gid = getgid();
290#ifdef HAVE_INITGROUPS
291 struct passwd *pw = getpwuid(uid);
292#endif
293
294 int fd[2];
295 if (0 > pipe(fd))
296 {
297 fd[0] = fd[1] = 0; // Pipe failed.. continue
298 }
299
300 runs = true;
301
302 QApplication::flushX();
303
304 // WABA: Note that we use fork() and not vfork() because
305 // vfork() has unclear semantics and is not standardized.
306 pid_ = fork();
307
308 if (0 == pid_) {
309 if (fd[0])
310 close(fd[0]);
311 if (!runPrivileged())
312 {
313 setgid(gid);
314#if defined( HAVE_INITGROUPS)
315 if(pw)
316 initgroups(pw->pw_name, pw->pw_gid);
317#endif
318 setuid(uid);
319 }
320 // The child process
321 commSetupDoneC();
322 //)
323 //kdDebug() << "Could not finish comm setup in child!" << endl;
324
325 setupEnvironment();
326
327 // Matthias
328 if (run_mode == DontCare)
329 setpgid(0,0);
330 // restore default SIGPIPE handler (Harri)
331 struct sigaction act;
332 sigemptyset(&(act.sa_mask));
333 sigaddset(&(act.sa_mask), SIGPIPE);
334 act.sa_handler = SIG_DFL;
335 act.sa_flags = 0;
336 sigaction(SIGPIPE, &act, 0L);
337
338 // We set the close on exec flag.
339 // Closing of fd[1] indicates that the execvp succeeded!
340 if (fd[1])
341 fcntl(fd[1], F_SETFD, FD_CLOEXEC);
342 execvp(arglist[0], arglist);
343 char resultByte = 1;
344 if (fd[1])
345 write(fd[1], &resultByte, 1);
346 _exit(-1);
347 } else if (-1 == pid_) {
348 // forking failed
349
350 runs = false;
351 free(arglist);
352 return false;
353 } else {
354 if (fd[1])
355 close(fd[1]);
356 // the parent continues here
357
358 // Discard any data for stdin that might still be there
359 input_data = 0;
360
361 // Check whether client could be started.
362 if (fd[0]) for(;;)
363 {
364 char resultByte;
365 int n = ::read(fd[0], &resultByte, 1);
366 if (n == 1)
367 {
368 // Error
369 runs = false;
370 close(fd[0]);
371 free(arglist);
372 pid_ = 0;
373 return false;
374 }
375 if (n == -1)
376 {
377 if ((errno == ECHILD) || (errno == EINTR))
378 continue; // Ignore
379 }
380 break; // success
381 }
382 if (fd[0])
383 close(fd[0]);
384
385 if (!commSetupDoneP()){} // finish communication socket setup for the parent
386 //kdDebug() << "Could not finish comm setup in parent!" << endl;
387
388 if (run_mode == Block) {
389 commClose();
390
391 // The SIGCHLD handler of the process controller will catch
392 // the exit and set the status
393 while(runs)
394 {
395 KProcessController::theKProcessController->
396 slotDoHousekeeping(0);
397 }
398 runs = FALSE;
399 emit processExited(this);
400 }
401 }
402 free(arglist);
403 return true;
404}
405
406
407
408bool KProcess::kill(int signo)
409{
410 bool rv=false;
411
412 if (0 != pid_)
413 rv= (-1 != ::kill(pid_, signo));
414 // probably store errno somewhere...
415 return rv;
416}
417
418
419
420bool KProcess::isRunning() const
421{
422 return runs;
423}
424
425
426
427pid_t KProcess::pid() const
428{
429 return pid_;
430}
431
432
433
434bool KProcess::normalExit() const
435{
436 int _status = status;
437 return (pid_ != 0) && (!runs) && (WIFEXITED((_status)));
438}
439
440
441
442int KProcess::exitStatus() const
443{
444 int _status = status;
445 return WEXITSTATUS((_status));
446}
447
448
449
450bool KProcess::writeStdin(const char *buffer, int buflen)
451{
452 bool rv;
453
454 // if there is still data pending, writing new data
455 // to stdout is not allowed (since it could also confuse
456 // kprocess...
457 if (0 != input_data)
458 return false;
459
460 if (runs && (communication & Stdin)) {
461 input_data = buffer;
462 input_sent = 0;
463 input_total = buflen;
464 slotSendData(0);
465 innot->setEnabled(true);
466 rv = true;
467 } else
468 rv = false;
469 return rv;
470}
471
472void KProcess::suspend()
473{
474 if ((communication & Stdout) && outnot)
475 outnot->setEnabled(false);
476}
477
478void KProcess::resume()
479{
480 if ((communication & Stdout) && outnot)
481 outnot->setEnabled(true);
482}
483
484bool KProcess::closeStdin()
485{
486 bool rv;
487
488 if (communication & Stdin) {
489 communication = (Communication) (communication & ~Stdin);
490 delete innot;
491 innot = 0;
492 close(in[1]);
493 rv = true;
494 } else
495 rv = false;
496 return rv;
497}
498
499bool KProcess::closeStdout()
500{
501 bool rv;
502
503 if (communication & Stdout) {
504 communication = (Communication) (communication & ~Stdout);
505 delete outnot;
506 outnot = 0;
507 close(out[0]);
508 rv = true;
509 } else
510 rv = false;
511 return rv;
512}
513
514bool KProcess::closeStderr()
515{
516 bool rv;
517
518 if (communication & Stderr) {
519 communication = static_cast<Communication>(communication & ~Stderr);
520 delete errnot;
521 errnot = 0;
522 close(err[0]);
523 rv = true;
524 } else
525 rv = false;
526 return rv;
527}
528
529
530/////////////////////////////
531// protected slots //
532/////////////////////////////
533
534
535
536void KProcess::slotChildOutput(int fdno)
537{
538 if (!childOutput(fdno))
539 closeStdout();
540}
541
542
543void KProcess::slotChildError(int fdno)
544{
545 if (!childError(fdno))
546 closeStderr();
547}
548
549
550void KProcess::slotSendData(int)
551{
552 if (input_sent == input_total) {
553 innot->setEnabled(false);
554 input_data = 0;
555 emit wroteStdin(this);
556 } else
557 input_sent += ::write(in[1], input_data+input_sent, input_total-input_sent);
558}
559
560
561
562//////////////////////////////
563// private member functions //
564//////////////////////////////
565
566
567
568void KProcess::processHasExited(int state)
569{
570 if (runs)
571 {
572 runs = false;
573 status = state;
574
575 commClose(); // cleanup communication sockets
576
577 // also emit a signal if the process was run Blocking
578 if (DontCare != run_mode)
579 {
580 emit processExited(this);
581 }
582 }
583}
584
585
586
587int KProcess::childOutput(int fdno)
588{
589 if (communication & NoRead) {
590 int len = -1;
591 emit receivedStdout(fdno, len);
592 errno = 0; // Make sure errno doesn't read "EAGAIN"
593 return len;
594 }
595 else
596 {
597 char buffer[1024];
598 int len;
599
600 len = ::read(fdno, buffer, 1024);
601
602 if ( 0 < len) {
603 emit receivedStdout(this, buffer, len);
604 }
605 return len;
606 }
607}
608
609
610
611int KProcess::childError(int fdno)
612{
613 char buffer[1024];
614 int len;
615
616 len = ::read(fdno, buffer, 1024);
617
618 if ( 0 < len)
619 emit receivedStderr(this, buffer, len);
620 return len;
621}
622
623
624
625int KProcess::setupCommunication(Communication comm)
626{
627 int ok;
628
629 communication = comm;
630
631 ok = 1;
632 if (comm & Stdin)
633 ok &= socketpair(AF_UNIX, SOCK_STREAM, 0, in) >= 0;
634
635 if (comm & Stdout)
636 ok &= socketpair(AF_UNIX, SOCK_STREAM, 0, out) >= 0;
637
638 if (comm & Stderr)
639 ok &= socketpair(AF_UNIX, SOCK_STREAM, 0, err) >= 0;
640
641 return ok;
642}
643
644
645
646int KProcess::commSetupDoneP()
647{
648 int ok = 1;
649
650 if (communication != NoCommunication) {
651 if (communication & Stdin)
652 close(in[0]);
653 if (communication & Stdout)
654 close(out[1]);
655 if (communication & Stderr)
656 close(err[1]);
657
658 // Don't create socket notifiers and set the sockets non-blocking if
659 // blocking is requested.
660 if (run_mode == Block) return ok;
661
662 if (communication & Stdin) {
663// ok &= (-1 != fcntl(in[1], F_SETFL, O_NONBLOCK));
664 innot = new QSocketNotifier(in[1], QSocketNotifier::Write, this);
665 Q_CHECK_PTR(innot);
666 innot->setEnabled(false); // will be enabled when data has to be sent
667 QObject::connect(innot, SIGNAL(activated(int)),
668 this, SLOT(slotSendData(int)));
669 }
670
671 if (communication & Stdout) {
672// ok &= (-1 != fcntl(out[0], F_SETFL, O_NONBLOCK));
673 outnot = new QSocketNotifier(out[0], QSocketNotifier::Read, this);
674 Q_CHECK_PTR(outnot);
675 QObject::connect(outnot, SIGNAL(activated(int)),
676 this, SLOT(slotChildOutput(int)));
677 if (communication & NoRead)
678 suspend();
679 }
680
681 if (communication & Stderr) {
682// ok &= (-1 != fcntl(err[0], F_SETFL, O_NONBLOCK));
683 errnot = new QSocketNotifier(err[0], QSocketNotifier::Read, this );
684 Q_CHECK_PTR(errnot);
685 QObject::connect(errnot, SIGNAL(activated(int)),
686 this, SLOT(slotChildError(int)));
687 }
688 }
689 return ok;
690}
691
692
693
694int KProcess::commSetupDoneC()
695{
696 int ok = 1;
697 struct linger so;
698 memset(&so, 0, sizeof(so));
699
700 if (communication & Stdin)
701 close(in[1]);
702 if (communication & Stdout)
703 close(out[0]);
704 if (communication & Stderr)
705 close(err[0]);
706
707 if (communication & Stdin)
708 ok &= dup2(in[0], STDIN_FILENO) != -1;
709 else {
710 int null_fd = open( "/dev/null", O_RDONLY );
711 ok &= dup2( null_fd, STDIN_FILENO ) != -1;
712 close( null_fd );
713 }
714 if (communication & Stdout) {
715 ok &= dup2(out[1], STDOUT_FILENO) != -1;
716 ok &= !setsockopt(out[1], SOL_SOCKET, SO_LINGER, (char*)&so, sizeof(so));
717 }
718 else {
719 int null_fd = open( "/dev/null", O_WRONLY );
720 ok &= dup2( null_fd, STDOUT_FILENO ) != -1;
721 close( null_fd );
722 }
723 if (communication & Stderr) {
724 ok &= dup2(err[1], STDERR_FILENO) != -1;
725 ok &= !setsockopt(err[1], SOL_SOCKET, SO_LINGER, reinterpret_cast<char *>(&so), sizeof(so));
726 }
727 else {
728 int null_fd = open( "/dev/null", O_WRONLY );
729 ok &= dup2( null_fd, STDERR_FILENO ) != -1;
730 close( null_fd );
731 }
732 return ok;
733}
734
735
736
737void KProcess::commClose()
738{
739 if (NoCommunication != communication) {
740 bool b_in = (communication & Stdin);
741 bool b_out = (communication & Stdout);
742 bool b_err = (communication & Stderr);
743 if (b_in)
744 delete innot;
745
746 if (b_out || b_err) {
747 // If both channels are being read we need to make sure that one socket buffer
748 // doesn't fill up whilst we are waiting for data on the other (causing a deadlock).
749 // Hence we need to use select.
750
751 // Once one or other of the channels has reached EOF (or given an error) go back
752 // to the usual mechanism.
753
754 int fds_ready = 1;
755 fd_set rfds;
756
757 int max_fd = 0;
758 if (b_out) {
759 fcntl(out[0], F_SETFL, O_NONBLOCK);
760 if (out[0] > max_fd)
761 max_fd = out[0];
762 delete outnot;
763 outnot = 0;
764 }
765 if (b_err) {
766 fcntl(err[0], F_SETFL, O_NONBLOCK);
767 if (err[0] > max_fd)
768 max_fd = err[0];
769 delete errnot;
770 errnot = 0;
771 }
772
773
774 while (b_out || b_err) {
775 // * If the process is still running we block until we
776 // receive data. (p_timeout = 0, no timeout)
777 // * If the process has already exited, we only check
778 // the available data, we don't wait for more.
779 // (p_timeout = &timeout, timeout immediately)
780 struct timeval timeout;
781 timeout.tv_sec = 0;
782 timeout.tv_usec = 0;
783 struct timeval *p_timeout = runs ? 0 : &timeout;
784
785 FD_ZERO(&rfds);
786 if (b_out)
787 FD_SET(out[0], &rfds);
788
789 if (b_err)
790 FD_SET(err[0], &rfds);
791
792 fds_ready = select(max_fd+1, &rfds, 0, 0, p_timeout);
793 if (fds_ready <= 0) break;
794
795 if (b_out && FD_ISSET(out[0], &rfds)) {
796 int ret = 1;
797 while (ret > 0) ret = childOutput(out[0]);
798 if ((ret == -1 && errno != EAGAIN) || ret == 0)
799 b_out = false;
800 }
801
802 if (b_err && FD_ISSET(err[0], &rfds)) {
803 int ret = 1;
804 while (ret > 0) ret = childError(err[0]);
805 if ((ret == -1 && errno != EAGAIN) || ret == 0)
806 b_err = false;
807 }
808 }
809 }
810
811 if (b_in) {
812 communication = (Communication) (communication & ~Stdin);
813 close(in[1]);
814 }
815 if (b_out) {
816 communication = (Communication) (communication & ~Stdout);
817 close(out[0]);
818 }
819 if (b_err) {
820 communication = (Communication) (communication & ~Stderr);
821 close(err[0]);
822 }
823 }
824}
825
826void KProcess::setUseShell(bool useShell, const char *shell)
827{
828 if (!d)
829 d = new KProcessPrivate;
830 d->useShell = useShell;
831 d->shell = shell;
832 if (d->shell.isEmpty())
833 d->shell = searchShell();
834}
835
836QString KProcess::quote(const QString &arg)
837{
838 QString res = arg;
839 res.replace(QRegExp(QString::fromLatin1("\'")),
840 QString::fromLatin1("'\"'\"'"));
841 res.prepend('\'');
842 res.append('\'');
843 return res;
844}
845
846QCString KProcess::searchShell()
847{
848 QCString tmpShell = QCString(getenv("SHELL")).stripWhiteSpace();
849 if (!isExecutable(tmpShell))
850 {
851 tmpShell = "/bin/sh";
852 }
853
854 return tmpShell;
855}
856
857bool KProcess::isExecutable(const QCString &filename)
858{
859 struct stat fileinfo;
860
861 if (filename.isEmpty()) return false;
862
863 // CC: we've got a valid filename, now let's see whether we can execute that file
864
865 if (-1 == stat(filename.data(), &fileinfo)) return false;
866 // CC: return false if the file does not exist
867
868 // CC: anyway, we cannot execute directories, block/character devices, fifos or sockets
869 if ( (S_ISDIR(fileinfo.st_mode)) ||
870 (S_ISCHR(fileinfo.st_mode)) ||
871 (S_ISBLK(fileinfo.st_mode)) ||
872#ifdef S_ISSOCK
873 // CC: SYSVR4 systems don't have that macro
874 (S_ISSOCK(fileinfo.st_mode)) ||
875#endif
876 (S_ISFIFO(fileinfo.st_mode)) ||
877 (S_ISDIR(fileinfo.st_mode)) ) {
878 return false;
879 }
880
881 // CC: now check for permission to execute the file
882 if (access(filename.data(), X_OK) != 0) return false;
883
884 // CC: we've passed all the tests...
885 return true;
886}
887
888void KProcess::virtual_hook( int, void* )
889{ /*BASE::virtual_hook( id, data );*/ }
890
891
892///////////////////////////
893// CC: Class KShellProcess
894///////////////////////////
895
896KShellProcess::KShellProcess(const char *shellname):
897 KProcess()
898{
899 setUseShell(true, shellname);
900}
901
902
903KShellProcess::~KShellProcess() {
904}
905
906QString KShellProcess::quote(const QString &arg)
907{
908 return KProcess::quote(arg);
909}
910
911bool KShellProcess::start(RunMode runmode, Communication comm)
912{
913 return KProcess::start(runmode, comm);
914}
915
916void KShellProcess::virtual_hook( int id, void* data )
917{ KProcess::virtual_hook( id, data ); }
918
919//#include "kprocess.moc"
diff --git a/noncore/net/networksetup/kprocess.h b/noncore/net/networksetup/kprocess.h
deleted file mode 100644
index e70f7e7..0000000
--- a/noncore/net/networksetup/kprocess.h
+++ b/dev/null
@@ -1,804 +0,0 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 1997 Christian Czezakte (e9025461@student.tuwien.ac.at)
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA.
18*/
19//
20// KPROCESS -- A class for handling child processes in KDE without
21// having to take care of Un*x specific implementation details
22//
23// version 0.3.1, Jan 8th 1998
24//
25// (C) Christian Czezatke
26// e9025461@student.tuwien.ac.at
27//
28
29#ifndef __kprocess_h__
30#define __kprocess_h__
31
32#include <sys/types.h> // for pid_t
33#include <sys/wait.h>
34#include <signal.h>
35#include <unistd.h>
36#include <qvaluelist.h>
37#include <qcstring.h>
38#include <qobject.h>
39
40class QSocketNotifier;
41class KProcessPrivate;
42
43/**
44 * Child process invocation, monitoring and control.
45 *
46 * @sect General usage and features
47 *
48 *This class allows a KDE application to start child processes without having
49 *to worry about UN*X signal handling issues and zombie process reaping.
50 *
51 *@see KProcIO
52 *
53 *Basically, this class distinguishes three different ways of running
54 *child processes:
55 *
56 *@li KProcess::DontCare -- The child process is invoked and both the child
57 *process and the parent process continue concurrently.
58 *
59 *Starting a DontCare child process means that the application is
60 *not interested in any notification to determine whether the
61 *child process has already exited or not.
62 *
63 *@li KProcess::NotifyOnExit -- The child process is invoked and both the
64 *child and the parent process run concurrently.
65 *
66 *When the child process exits, the KProcess instance
67 *corresponding to it emits the Qt signal @ref processExited().
68 *
69 *Since this signal is @em not emitted from within a UN*X
70 *signal handler, arbitrary function calls can be made.
71 *
72 *Be aware: When the KProcess objects gets destructed, the child
73 *process will be killed if it is still running!
74 *This means in particular, that you cannot use a KProcess on the stack
75 *with KProcess::NotifyOnExit.
76 *
77 *@li KProcess::Block -- The child process starts and the parent process
78 *is suspended until the child process exits. (@em Really not recommended
79 *for programs with a GUI.)
80 *
81 *KProcess also provides several functions for determining the exit status
82 *and the pid of the child process it represents.
83 *
84 *Furthermore it is possible to supply command-line arguments to the process
85 *in a clean fashion (no null -- terminated stringlists and such...)
86 *
87 *A small usage example:
88 *<pre>
89 *KProcess *proc = new KProcess;
90 *
91 **proc << "my_executable";
92 **proc << "These" << "are" << "the" << "command" << "line" << "args";
93 *QApplication::connect(proc, SIGNAL(processExited(KProcess *)),
94 * pointer_to_my_object, SLOT(my_objects_slot(KProcess *)));
95 *proc->start();
96 *</pre>
97 *
98 *This will start "my_executable" with the commandline arguments "These"...
99 *
100 *When the child process exits, the respective Qt signal will be emitted.
101 *
102 *@sect Communication with the child process
103 *
104 *KProcess supports communication with the child process through
105 *stdin/stdout/stderr.
106 *
107 *The following functions are provided for getting data from the child
108 *process or sending data to the child's stdin (For more information,
109 *have a look at the documentation of each function):
110 *
111 *@li bool @ref writeStdin(char *buffer, int buflen);
112 *@li -- Transmit data to the child process's stdin.
113 *
114 *@li bool @ref closeStdin();
115 *@li -- Closes the child process's stdin (which causes it to see an feof(stdin)).
116 *Returns false if you try to close stdin for a process that has been started
117 *without a communication channel to stdin.
118 *
119 *@li bool @ref closeStdout();
120 *@li -- Closes the child process's stdout.
121 *Returns false if you try to close stdout for a process that has been started
122 *without a communication channel to stdout.
123 *
124 *@li bool @ref closeStderr();
125 *@li -- Closes the child process's stderr.
126 *Returns false if you try to close stderr for a process that has been started
127 *without a communication channel to stderr.
128 *
129 *
130 *@sect QT signals:
131 *
132 *@li void @ref receivedStdout(KProcess *proc, char *buffer, int buflen);
133 *@li void @ref receivedStderr(KProcess *proc, char *buffer, int buflen);
134 *@li -- Indicates that new data has arrived from either the
135 *child process's stdout or stderr.
136 *
137 *@li void @ref wroteStdin(KProcess *proc);
138 *@li -- Indicates that all data that has been sent to the child process
139 *by a prior call to @ref writeStdin() has actually been transmitted to the
140 *client .
141 *
142 *@author Christian Czezakte e9025461@student.tuwien.ac.at
143 *
144 *
145 **/
146class KProcess : public QObject
147{
148 Q_OBJECT
149
150public:
151
152 /**
153 * Modes in which the communication channel can be opened.
154 *
155 * If communication for more than one channel is required,
156 * the values have to be or'ed together, for example to get
157 * communication with stdout as well as with stdin, you would
158 * specify @p Stdin @p | @p Stdout
159 *
160 * If @p NoRead is specified in conjunction with @p Stdout,
161 * no data is actually read from @p Stdout but only
162 * the signal @ref childOutput(int fd) is emitted.
163 */
164 enum Communication { NoCommunication = 0, Stdin = 1, Stdout = 2, Stderr = 4,
165 AllOutput = 6, All = 7,
166 NoRead };
167
168 /**
169 * Run-modes for a child process.
170 */
171 enum RunMode {
172 /**
173 * The application does not receive notifications from the subprocess when
174 * it is finished or aborted.
175 */
176 DontCare,
177 /**
178 * The application is notified when the subprocess dies.
179 */
180 NotifyOnExit,
181 /**
182 * The application is suspended until the started process is finished.
183 */
184 Block };
185
186 /**
187 * Constructor
188 */
189 KProcess();
190
191 /**
192 *Destructor:
193 *
194 * If the process is running when the destructor for this class
195 * is called, the child process is killed with a SIGKILL, but
196 * only if the run mode is not of type @p DontCare.
197 * Processes started as @p DontCare keep running anyway.
198 */
199 virtual ~KProcess();
200
201 /**
202 @deprecated
203
204 The use of this function is now deprecated. -- Please use the
205 "operator<<" instead of "setExecutable".
206
207 Sets the executable to be started with this KProcess object.
208 Returns false if the process is currently running (in that
209 case the executable remains unchanged.)
210
211 @see operator<<
212
213 */
214 bool setExecutable(const QString& proc);
215
216
217 /**
218 * Sets the executable and the command line argument list for this process.
219 *
220 * For example, doing an "ls -l /usr/local/bin" can be achieved by:
221 * <pre>
222 * KProcess p;
223 * ...
224 * p << "ls" << "-l" << "/usr/local/bin"
225 * </pre>
226 *
227 **/
228 KProcess &operator<<(const QString& arg);
229 /**
230 * Similar to previous method, takes a char *, supposed to be in locale 8 bit already.
231 */
232 KProcess &operator<<(const char * arg);
233 /**
234 * Similar to previous method, takes a QCString, supposed to be in locale 8 bit already.
235 */
236 KProcess &operator<<(const QCString & arg);
237
238 /**
239 * Sets the executable and the command line argument list for this process,
240 * in a single method call, or add a list of arguments.
241 **/
242 KProcess &operator<<(const QStringList& args);
243
244 /**
245 * Clear a command line argument list that has been set by using
246 * the "operator<<".
247 */
248 void clearArguments();
249
250 /**
251 * Starts the process.
252 * For a detailed description of the
253 * various run modes and communication semantics, have a look at the
254 * general description of the KProcess class.
255 *
256 * The following problems could cause this function to
257 * return false:
258 *
259 * @li The process is already running.
260 * @li The command line argument list is empty.
261 * @li The starting of the process failed (could not fork).
262 * @li The executable was not found.
263 *
264 * @param comm Specifies which communication links should be
265 * established to the child process (stdin/stdout/stderr). By default,
266 * no communication takes place and the respective communication
267 * signals will never get emitted.
268 *
269 * @return true on success, false on error
270 * (see above for error conditions)
271 **/
272 virtual bool start(RunMode runmode = NotifyOnExit,
273 Communication comm = NoCommunication);
274
275 /**
276 * Stop the process (by sending it a signal).
277 *
278 * @param signoThe signal to send. The default is SIGTERM.
279 * @return @p true if the signal was delivered successfully.
280 */
281 virtual bool kill(int signo = SIGTERM);
282
283 /**
284 @return @p true if the process is (still) considered to be running
285 */
286 bool isRunning() const;
287
288 /** Returns the process id of the process.
289 *
290 * If it is called after
291 * the process has exited, it returns the process id of the last
292 * child process that was created by this instance of KProcess.
293 *
294 * Calling it before any child process has been started by this
295 * KProcess instance causes pid() to return 0.
296 **/
297 pid_t pid() const;
298
299 /**
300 * Use pid().
301 * @deprecated
302 */
303 pid_t getPid() const { return pid(); }
304
305 /**
306 * Suspend processing of data from stdout of the child process.
307 */
308 void suspend();
309
310 /**
311 * Resume processing of data from stdout of the child process.
312 */
313 void resume();
314
315 /**
316 * @return @p true if the process has already finished and has exited
317 * "voluntarily", ie: it has not been killed by a signal.
318 *
319 * Note that you should check @ref KProcess::exitStatus() to determine
320 * whether the process completed its task successful or not.
321 */
322 bool normalExit() const;
323
324 /**
325 * Returns the exit status of the process.
326 *
327 * Please use
328 * @ref KProcess::normalExit() to check whether the process has exited
329 * cleanly (i.e., @ref KProcess::normalExit() returns @p true) before calling
330 * this function because if the process did not exit normally,
331 * it does not have a valid exit status.
332 */
333 int exitStatus() const;
334
335
336 /**
337 * Transmit data to the child process's stdin.
338 *
339 * KProcess::writeStdin may return false in the following cases:
340 *
341 * @li The process is not currently running.
342 *
343 * @li Communication to stdin has not been requested in the @ref start() call.
344 *
345 * @li Transmission of data to the child process by a previous call to
346 * @ref writeStdin() is still in progress.
347 *
348 * Please note that the data is sent to the client asynchronously,
349 * so when this function returns, the data might not have been
350 * processed by the child process.
351 *
352 * If all the data has been sent to the client, the signal
353 * @ref wroteStdin() will be emitted.
354 *
355 * Please note that you must not free "buffer" or call @ref writeStdin()
356 * again until either a @ref wroteStdin() signal indicates that the
357 * data has been sent or a @ref processHasExited() signal shows that
358 * the child process is no longer alive...
359 **/
360 bool writeStdin(const char *buffer, int buflen);
361
362 /**
363 * This causes the stdin file descriptor of the child process to be
364 * closed indicating an "EOF" to the child.
365 *
366 * @return @p false if no communication to the process's stdin
367 * had been specified in the call to @ref start().
368 */
369 bool closeStdin();
370
371 /**
372 * This causes the stdout file descriptor of the child process to be
373 * closed.
374 *
375 * @return @p false if no communication to the process's stdout
376 * had been specified in the call to @ref start().
377 */
378 bool closeStdout();
379
380 /**
381 * This causes the stderr file descriptor of the child process to be
382 * closed.
383 *
384 * @return @p false if no communication to the process's stderr
385 * had been specified in the call to @ref start().
386 */
387 bool closeStderr();
388
389 /**
390 * Lets you see what your arguments are for debugging.
391 */
392
393 const QValueList<QCString> &args() { return arguments; }
394
395 /**
396 * Controls whether the started process should drop any
397 * setuid/segid privileges or whether it should keep them
398 *
399 * The default is @p false : drop privileges
400 */
401 void setRunPrivileged(bool keepPrivileges);
402
403 /**
404 * Returns whether the started process will drop any
405 * setuid/segid privileges or whether it will keep them
406 */
407 bool runPrivileged() const;
408
409 /**
410 * Modifies the environment of the process to be started.
411 * This function must be called before starting the process.
412 */
413 void setEnvironment(const QString &name, const QString &value);
414
415 /**
416 * Changes the current working directory (CWD) of the process
417 * to be started.
418 * This function must be called before starting the process.
419 */
420 void setWorkingDirectory(const QString &dir);
421
422 /**
423 * Specify whether to start the command via a shell or directly.
424 * The default is to start the command directly.
425 * If @p useShell is true @p shell will be used as shell, or
426 * if shell is empty, the standard shell is used.
427 * @p quote A flag indicating whether to quote the arguments.
428 *
429 * When using a shell, the caller should make sure that all filenames etc.
430 * are properly quoted when passed as argument.
431 * @see quote()
432 */
433 void setUseShell(bool useShell, const char *shell = 0);
434
435 /**
436 * This function can be used to quote an argument string such that
437 * the shell processes it properly. This is e. g. necessary for
438 * user-provided file names which may contain spaces or quotes.
439 * It also prevents expansion of wild cards and environment variables.
440 */
441 static QString quote(const QString &arg);
442
443 /**
444 * Detaches KProcess from child process. All communication is closed.
445 * No exit notification is emitted any more for the child process.
446 * Deleting the KProcess will no longer kill the child process.
447 * Note that the current process remains the parent process of the
448 * child process.
449 */
450 void detach();
451
452
453
454signals:
455
456 /**
457 * Emitted after the process has terminated when
458 * the process was run in the @p NotifyOnExit (==default option to
459 * @ref start()) or the @ref Block mode.
460 **/
461 void processExited(KProcess *proc);
462
463
464 /**
465 * Emitted, when output from the child process has
466 * been received on stdout.
467 *
468 * To actually get
469 * these signals, the respective communication link (stdout/stderr)
470 * has to be turned on in @ref start().
471 *
472 * @param buffer The data received.
473 * @param buflen The number of bytes that are available.
474 *
475 * You should copy the information contained in @p buffer to your private
476 * data structures before returning from this slot.
477 **/
478 void receivedStdout(KProcess *proc, char *buffer, int buflen);
479
480 /**
481 * Emitted when output from the child process has
482 * been received on stdout.
483 *
484 * To actually get these signals, the respective communications link
485 * (stdout/stderr) has to be turned on in @ref start() and the
486 * @p NoRead flag should have been passed.
487 *
488 * You will need to explicitly call resume() after your call to start()
489 * to begin processing data from the child process's stdout. This is
490 * to ensure that this signal is not emitted when no one is connected
491 * to it, otherwise this signal will not be emitted.
492 *
493 * The data still has to be read from file descriptor @p fd.
494 **/
495 void receivedStdout(int fd, int &len);
496
497
498 /**
499 * Emitted, when output from the child process has
500 * been received on stderr.
501 * To actually get
502 * these signals, the respective communication link (stdout/stderr)
503 * has to be turned on in @ref start().
504 *
505 * @param buffer The data received.
506 * @param buflen The number of bytes that are available.
507 *
508 * You should copy the information contained in @p buffer to your private
509 * data structures before returning from this slot.
510 */
511 void receivedStderr(KProcess *proc, char *buffer, int buflen);
512
513 /**
514 * Emitted after all the data that has been
515 * specified by a prior call to @ref writeStdin() has actually been
516 * written to the child process.
517 **/
518 void wroteStdin(KProcess *proc);
519
520
521protected slots:
522
523 /**
524 * This slot gets activated when data from the child's stdout arrives.
525 * It usually calls "childOutput"
526 */
527 void slotChildOutput(int fdno);
528
529 /**
530 * This slot gets activated when data from the child's stderr arrives.
531 * It usually calls "childError"
532 */
533 void slotChildError(int fdno);
534 /*
535 Slot functions for capturing stdout and stderr of the child
536 */
537
538 /**
539 * Called when another bulk of data can be sent to the child's
540 * stdin. If there is no more data to be sent to stdin currently
541 * available, this function must disable the QSocketNotifier "innot".
542 */
543 void slotSendData(int dummy);
544
545protected:
546
547 /**
548 * Sets up the environment according to the data passed via
549 * setEnvironment(...)
550 */
551 void setupEnvironment();
552
553 /**
554 * The list of the process' command line arguments. The first entry
555 * in this list is the executable itself.
556 */
557 QValueList<QCString> arguments;
558 /**
559 * How to run the process (Block, NotifyOnExit, DontCare). You should
560 * not modify this data member directly from derived classes.
561 */
562 RunMode run_mode;
563 /**
564 * true if the process is currently running. You should not
565 * modify this data member directly from derived classes. For
566 * reading the value of this data member, please use "isRunning()"
567 * since "runs" will probably be made private in later versions
568 * of KProcess.
569 */
570 bool runs;
571
572 /**
573 * The PID of the currently running process (see "getPid()").
574 * You should not modify this data member in derived classes.
575 * Please use "getPid()" instead of directly accessing this
576 * member function since it will probably be made private in
577 * later versions of KProcess.
578 */
579 pid_t pid_;
580
581 /**
582 * The process' exit status as returned by "waitpid". You should not
583 * modify the value of this data member from derived classes. You should
584 * rather use @ref exitStatus than accessing this data member directly
585 * since it will probably be made private in further versions of
586 * KProcess.
587 */
588 int status;
589
590
591 /**
592 * See setRunPrivileged()
593 */
594 bool keepPrivs;
595
596 /*
597 Functions for setting up the sockets for communication.
598 setupCommunication
599 -- is called from "start" before "fork"ing.
600 commSetupDoneP
601 -- completes communication socket setup in the parent
602 commSetupDoneC
603 -- completes communication setup in the child process
604 commClose
605 -- frees all allocated communication resources in the parent
606 after the process has exited
607 */
608
609 /**
610 * This function is called from "KProcess::start" right before a "fork" takes
611 * place. According to
612 * the "comm" parameter this function has to initialize the "in", "out" and
613 * "err" data member of KProcess.
614 *
615 * This function should return 0 if setting the needed communication channels
616 * was successful.
617 *
618 * The default implementation is to create UNIX STREAM sockets for the communication,
619 * but you could overload this function and establish a TCP/IP communication for
620 * network communication, for example.
621 */
622 virtual int setupCommunication(Communication comm);
623
624 /**
625 * Called right after a (successful) fork on the parent side. This function
626 * will usually do some communications cleanup, like closing the reading end
627 * of the "stdin" communication channel.
628 *
629 * Furthermore, it must also create the QSocketNotifiers "innot", "outnot" and
630 * "errnot" and connect their Qt slots to the respective KProcess member functions.
631 *
632 * For a more detailed explanation, it is best to have a look at the default
633 * implementation of "setupCommunication" in kprocess.cpp.
634 */
635 virtual int commSetupDoneP();
636
637 /**
638 * Called right after a (successful) fork, but before an "exec" on the child
639 * process' side. It usually just closes the unused communication ends of
640 * "in", "out" and "err" (like the writing end of the "in" communication
641 * channel.
642 */
643 virtual int commSetupDoneC();
644
645
646 /**
647 * Immediately called after a process has exited. This function normally
648 * calls commClose to close all open communication channels to this
649 * process and emits the "processExited" signal (if the process was
650 * not running in the "DontCare" mode).
651 */
652 virtual void processHasExited(int state);
653
654 /**
655 * Should clean up the communication links to the child after it has
656 * exited. Should be called from "processHasExited".
657 */
658 virtual void commClose();
659
660
661 /**
662 * the socket descriptors for stdin/stdout/stderr.
663 */
664 int out[2];
665 int in[2];
666 int err[2];
667
668 /**
669 * The socket notifiers for the above socket descriptors.
670 */
671 QSocketNotifier *innot;
672 QSocketNotifier *outnot;
673 QSocketNotifier *errnot;
674
675 /**
676 * Lists the communication links that are activated for the child
677 * process. Should not be modified from derived classes.
678 */
679 Communication communication;
680
681 /**
682 * Called by "slotChildOutput" this function copies data arriving from the
683 * child process's stdout to the respective buffer and emits the signal
684 * "@ref receivedStderr".
685 */
686 int childOutput(int fdno);
687
688 /**
689 * Called by "slotChildOutput" this function copies data arriving from the
690 * child process's stdout to the respective buffer and emits the signal
691 * "@ref receivedStderr"
692 */
693 int childError(int fdno);
694
695 // information about the data that has to be sent to the child:
696
697 const char *input_data; // the buffer holding the data
698 int input_sent; // # of bytes already transmitted
699 int input_total; // total length of input_data
700
701 /**
702 * @ref KProcessController is a friend of KProcess because it has to have
703 * access to various data members.
704 */
705 friend class KProcessController;
706
707
708private:
709 /**
710 * Searches for a valid shell.
711 * Here is the algorithm used for finding an executable shell:
712 *
713 * @li Try the executable pointed to by the "SHELL" environment
714 * variable with white spaces stripped off
715 *
716 * @li If your process runs with uid != euid or gid != egid, a shell
717 * not listed in /etc/shells will not used.
718 *
719 * @li If no valid shell could be found, "/bin/sh" is used as a last resort.
720 */
721 QCString searchShell();
722
723 /**
724 * Used by @ref searchShell in order to find out whether the shell found
725 * is actually executable at all.
726 */
727 bool isExecutable(const QCString &filename);
728
729 // Disallow assignment and copy-construction
730 KProcess( const KProcess& );
731 KProcess& operator= ( const KProcess& );
732
733protected:
734 virtual void virtual_hook( int id, void* data );
735private:
736 KProcessPrivate *d;
737};
738
739class KShellProcessPrivate;
740
741/**
742* @obsolete
743*
744* This class is obsolete. Use KProcess and KProcess::setUseShell(true)
745* instead.
746*
747* @short A class derived from @ref KProcess to start child
748 * processes through a shell.
749* @author Christian Czezakte <e9025461@student.tuwien.ac.at>
750* @version $Id$
751*/
752class KShellProcess: public KProcess
753{
754 Q_OBJECT
755
756public:
757
758 /**
759 * Constructor
760 *
761 * By specifying the name of a shell (like "/bin/bash") you can override
762 * the mechanism for finding a valid shell as described in KProcess::searchShell()
763 */
764 KShellProcess(const char *shellname=0);
765
766 /**
767 * Destructor.
768 */
769 ~KShellProcess();
770
771 /**
772 * Starts up the process. -- For a detailed description
773 * have a look at the "start" member function and the detailed
774 * description of @ref KProcess .
775 */
776 virtual bool start(RunMode runmode = NotifyOnExit,
777 Communication comm = NoCommunication);
778
779 /**
780 * This function can be used to quote an argument string such that
781 * the shell processes it properly. This is e. g. necessary for
782 * user-provided file names which may contain spaces or quotes.
783 * It also prevents expansion of wild cards and environment variables.
784 */
785 static QString quote(const QString &arg);
786
787private:
788
789 QCString shell;
790
791 // Disallow assignment and copy-construction
792 KShellProcess( const KShellProcess& );
793 KShellProcess& operator= ( const KShellProcess& );
794
795protected:
796 virtual void virtual_hook( int id, void* data );
797private:
798 KShellProcessPrivate *d;
799};
800
801
802
803#endif
804
diff --git a/noncore/net/networksetup/mainwindowimp.cpp b/noncore/net/networksetup/mainwindowimp.cpp
index 7261c58..48ef9b3 100644
--- a/noncore/net/networksetup/mainwindowimp.cpp
+++ b/noncore/net/networksetup/mainwindowimp.cpp
@@ -1,537 +1,525 @@
1#include "mainwindowimp.h" 1#include "mainwindowimp.h"
2#include "addconnectionimp.h" 2#include "addconnectionimp.h"
3#include "interfaceinformationimp.h" 3#include "interfaceinformationimp.h"
4#include "interfacesetupimp.h" 4#include "interfacesetupimp.h"
5#include "interfaces.h" 5#include "interfaces.h"
6
7#include "module.h" 6#include "module.h"
8 7
9#include "kprocess.h"
10
11#include <qpushbutton.h> 8#include <qpushbutton.h>
12#include <qlistbox.h> 9#include <qlistbox.h>
13#include <qlineedit.h> 10#include <qlineedit.h>
14#include <qlistview.h> 11#include <qlistview.h>
15#include <qheader.h> 12#include <qheader.h>
16#include <qlabel.h> 13#include <qlabel.h>
17 14
18#include <qmainwindow.h> 15#include <qmainwindow.h>
19#include <qmessagebox.h> 16#include <qmessagebox.h>
20 17
21#include <qpe/config.h> 18#include <qpe/config.h>
22#include <qpe/qlibrary.h> 19#include <qpe/qlibrary.h>
23#include <qpe/resource.h> 20#include <qpe/resource.h>
24#include <qpe/qpeapplication.h> 21#include <qpe/qpeapplication.h>
25 22
26#include <qlist.h> 23#include <qlist.h>
27#include <qdir.h> 24#include <qdir.h>
28#include <qfile.h> 25#include <qfile.h>
29#include <qtextstream.h> 26#include <qtextstream.h>
30 27
31#define TEMP_ALL "/tmp/ifconfig-a" 28#include <net/if.h>
32#define TEMP_UP "/tmp/ifconfig" 29#include <sys/ioctl.h>
33 30
34#define DEFAULT_SCHEME "/var/lib/pcmcia/scheme" 31#define DEFAULT_SCHEME "/var/lib/pcmcia/scheme"
35 32
36MainWindowImp::MainWindowImp(QWidget *parent, const char *name) : MainWindow(parent, name, true), advancedUserMode(false){ 33MainWindowImp::MainWindowImp(QWidget *parent, const char *name) : MainWindow(parent, name, true), advancedUserMode(false){
37 connect(addConnectionButton, SIGNAL(clicked()), this, SLOT(addClicked())); 34 connect(addConnectionButton, SIGNAL(clicked()), this, SLOT(addClicked()));
38 connect(removeConnectionButton, SIGNAL(clicked()), this, SLOT(removeClicked())); 35 connect(removeConnectionButton, SIGNAL(clicked()), this, SLOT(removeClicked()));
39 connect(informationConnectionButton, SIGNAL(clicked()), this, SLOT(informationClicked())); 36 connect(informationConnectionButton, SIGNAL(clicked()), this, SLOT(informationClicked()));
40 connect(configureConnectionButton, SIGNAL(clicked()), this, SLOT(configureClicked())); 37 connect(configureConnectionButton, SIGNAL(clicked()), this, SLOT(configureClicked()));
41 38
42 connect(newProfileButton, SIGNAL(clicked()), this, SLOT(addProfile())); 39 connect(newProfileButton, SIGNAL(clicked()), this, SLOT(addProfile()));
43 connect(removeProfileButton, SIGNAL(clicked()), this, SLOT(removeProfile())); 40 connect(removeProfileButton, SIGNAL(clicked()), this, SLOT(removeProfile()));
44 connect(setCurrentProfileButton, SIGNAL(clicked()), this, SLOT(changeProfile())); 41 connect(setCurrentProfileButton, SIGNAL(clicked()), this, SLOT(changeProfile()));
45 42
46 connect(newProfile, SIGNAL(textChanged(const QString&)), this, SLOT(newProfileChanged(const QString&))); 43 connect(newProfile, SIGNAL(textChanged(const QString&)), this, SLOT(newProfileChanged(const QString&)));
47 // Load connections. 44 // Load connections.
48 loadModules(QPEApplication::qpeDir() + "/plugins/networksetup"); 45 loadModules(QPEApplication::qpeDir() + "/plugins/networksetup");
49 getInterfaceList(); 46 getAllInterfaces();
47
48 Interfaces i;
49 QStringList list = i.getInterfaceList();
50 QMap<QString, Interface*>::Iterator it;
51 for ( QStringList::Iterator ni = list.begin(); ni != list.end(); ++ni ) {
52 bool found = false;
53 for( it = interfaceNames.begin(); it != interfaceNames.end(); ++it ){
54 if(it.key() == (*ni))
55 found = true;
56 }
57 if(!found){
58 if(!(*ni).contains("_")){
59 Interface *i = new Interface(this, *ni, false);
60 i->setAttached(false);
61 i->setHardwareName("Disconnected");
62 interfaceNames.insert(i->getInterfaceName(), i);
63 updateInterface(i);
64 connect(i, SIGNAL(updateInterface(Interface *)), this, SLOT(updateInterface(Interface *)));
65 }
66 }
67 }
68
69 //getInterfaceList();
50 connectionList->header()->hide(); 70 connectionList->header()->hide();
51 71
52
53 Config cfg("NetworkSetup"); 72 Config cfg("NetworkSetup");
54 profiles = QStringList::split(" ", cfg.readEntry("Profiles", "All")); 73 profiles = QStringList::split(" ", cfg.readEntry("Profiles", "All"));
55 for ( QStringList::Iterator it = profiles.begin(); it != profiles.end(); ++it) 74 for ( QStringList::Iterator it = profiles.begin(); it != profiles.end(); ++it)
56 profilesList->insertItem((*it)); 75 profilesList->insertItem((*it));
57 currentProfileLabel->setText(cfg.readEntry("CurrentProfile", "All")); 76 currentProfileLabel->setText(cfg.readEntry("CurrentProfile", "All"));
58 advancedUserMode = cfg.readBoolEntry("AdvancedUserMode", false); 77 advancedUserMode = cfg.readBoolEntry("AdvancedUserMode", false);
59 scheme = cfg.readEntry("SchemeFile", DEFAULT_SCHEME); 78 scheme = cfg.readEntry("SchemeFile", DEFAULT_SCHEME);
60 79
61 QFile file(scheme); 80 QFile file(scheme);
62 if ( file.open(IO_ReadOnly) ) { // file opened successfully 81 if ( file.open(IO_ReadOnly) ) { // file opened successfully
63 QTextStream stream( &file ); // use a text stream 82 QTextStream stream( &file ); // use a text stream
64 while ( !stream.eof() ) { // until end of file... 83 while ( !stream.eof() ) { // until end of file...
65 QString line = stream.readLine(); // line of text excluding '\n' 84 QString line = stream.readLine(); // line of text excluding '\n'
66 if(line.contains("SCHEME")){ 85 if(line.contains("SCHEME")){
67 line = line.mid(7, line.length()); 86 line = line.mid(7, line.length());
68 currentProfileLabel->setText(line); 87 currentProfileLabel->setText(line);
69 break; 88 break;
70 } 89 }
71 } 90 }
72 file.close(); 91 file.close();
73 } 92 }
74} 93}
75 94
76/** 95/**
77 * Deconstructor. Save profiles. Delete loaded libraries. 96 * Deconstructor. Save profiles. Delete loaded libraries.
78 */ 97 */
79MainWindowImp::~MainWindowImp(){ 98MainWindowImp::~MainWindowImp(){
80 // Save profiles. 99 // Save profiles.
81 Config cfg("NetworkSetup"); 100 Config cfg("NetworkSetup");
82 cfg.setGroup("General"); 101 cfg.setGroup("General");
83 cfg.writeEntry("Profiles", profiles.join(" ")); 102 cfg.writeEntry("Profiles", profiles.join(" "));
84 103
85 // Delete all interfaces that don't have owners. 104 // Delete all interfaces that don't have owners.
86 QMap<Interface*, QListViewItem*>::Iterator iIt; 105 QMap<Interface*, QListViewItem*>::Iterator iIt;
87 for( iIt = items.begin(); iIt != items.end(); ++iIt ){ 106 for( iIt = items.begin(); iIt != items.end(); ++iIt ){
88 if(iIt.key()->getModuleOwner() == NULL) 107 if(iIt.key()->getModuleOwner() == NULL)
89 delete iIt.key(); 108 delete iIt.key();
90 } 109 }
91 110
92 // Delete Modules and Libraries 111 // Delete Modules and Libraries
93 QMap<Module*, QLibrary*>::Iterator it; 112 QMap<Module*, QLibrary*>::Iterator it;
94 for( it = libraries.begin(); it != libraries.end(); ++it ){ 113 for( it = libraries.begin(); it != libraries.end(); ++it ){
95 delete it.key(); 114 delete it.key();
96 // I wonder why I can't delete the libraries 115 // I wonder why I can't delete the libraries
97 // What fucking shit this is. 116 // What fucking shit this is.
98 //delete it.data(); 117 //delete it.data();
99 } 118 }
100} 119}
101 120
102/** 121/**
122 * Query the kernel for all of the interfaces.
123 */
124void MainWindowImp::getAllInterfaces(){
125 int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
126 if(sockfd == -1)
127 return;
128
129 char buf[8*1024];
130 struct ifconf ifc;
131 ifc.ifc_len = sizeof(buf);
132 ifc.ifc_req = (struct ifreq *) buf;
133 int result=ioctl(sockfd, SIOCGIFCONF, &ifc);
134
135 for (char* ptr = buf; ptr < buf + ifc.ifc_len; ){
136 struct ifreq *ifr =(struct ifreq *) ptr;
137 int len = sizeof(struct sockaddr);
138#ifdef HAVE_SOCKADDR_SA_LEN
139 if (ifr->ifr_addr.sa_len > len)
140 len = ifr->ifr_addr.sa_len; /* length > 16 */
141#endif
142 ptr += sizeof(ifr->ifr_name) + len; /* for next one in buffer */
143
144 int flags;
145 struct sockaddr_in *sinptr;
146 Interface *i = NULL;
147 switch (ifr->ifr_addr.sa_family){
148 case AF_INET:
149 sinptr = (struct sockaddr_in *) &ifr->ifr_addr;
150 flags=0;
151
152 struct ifreq ifcopy;
153 ifcopy=*ifr;
154 result=ioctl(sockfd,SIOCGIFFLAGS,&ifcopy);
155 flags=ifcopy.ifr_flags;
156 i = new Interface(this, ifr->ifr_name, false);
157 i->setAttached(true);
158 if ((flags & IFF_UP) == IFF_UP)
159 i->setStatus(true);
160 else
161 i->setStatus(false);
162
163 if ((flags & IFF_BROADCAST) == IFF_BROADCAST)
164 i->setHardwareName("Ethernet");
165 else if ((flags & IFF_POINTOPOINT) == IFF_POINTOPOINT)
166 i->setHardwareName("Point to Point");
167 else if ((flags & IFF_MULTICAST) == IFF_MULTICAST)
168 i->setHardwareName("Multicast");
169 else if ((flags & IFF_LOOPBACK) == IFF_LOOPBACK)
170 i->setHardwareName("Loopback");
171 else
172 i->setHardwareName("Unknown");
173
174 interfaceNames.insert(i->getInterfaceName(), i);
175 updateInterface(i);
176 connect(i, SIGNAL(updateInterface(Interface *)), this, SLOT(updateInterface(Interface *)));
177 break;
178
179 default:
180 qDebug(ifr->ifr_name);
181 qDebug(QString("%1").arg(ifr->ifr_addr.sa_family).latin1());
182 break;
183 }
184 }
185}
186
187/**
103 * Load all modules that are found in the path 188 * Load all modules that are found in the path
104 * @param path a directory that is scaned for any plugins that can be loaded 189 * @param path a directory that is scaned for any plugins that can be loaded
105 * and attempts to load them 190 * and attempts to load them
106 */ 191 */
107void MainWindowImp::loadModules(QString path){ 192void MainWindowImp::loadModules(QString path){
108 //qDebug(path.latin1()); 193 //qDebug(path.latin1());
109 QDir d(path); 194 QDir d(path);
110 if(!d.exists()) 195 if(!d.exists())
111 return; 196 return;
112 197
113 // Don't want sym links 198 // Don't want sym links
114 d.setFilter( QDir::Files | QDir::NoSymLinks ); 199 d.setFilter( QDir::Files | QDir::NoSymLinks );
115 const QFileInfoList *list = d.entryInfoList(); 200 const QFileInfoList *list = d.entryInfoList();
116 QFileInfoListIterator it( *list ); 201 QFileInfoListIterator it( *list );
117 QFileInfo *fi; 202 QFileInfo *fi;
118 while ( (fi=it.current()) ) { 203 while ( (fi=it.current()) ) {
119 if(fi->fileName().contains(".so")){ 204 if(fi->fileName().contains(".so")){
120 loadPlugin(path + "/" + fi->fileName()); 205 loadPlugin(path + "/" + fi->fileName());
121 } 206 }
122 ++it; 207 ++it;
123 } 208 }
124} 209}
125 210
126/** 211/**
127 * Attempt to load a function and resolve a function. 212 * Attempt to load a function and resolve a function.
128 * @param pluginFileName - the name of the file in which to attempt to load 213 * @param pluginFileName - the name of the file in which to attempt to load
129 * @param resolveString - function pointer to resolve 214 * @param resolveString - function pointer to resolve
130 * @return pointer to the function with name resolveString or NULL 215 * @return pointer to the function with name resolveString or NULL
131 */ 216 */
132Module* MainWindowImp::loadPlugin(QString pluginFileName, QString resolveString){ 217Module* MainWindowImp::loadPlugin(QString pluginFileName, QString resolveString){
133 //qDebug(QString("MainWindowImp::loadPlugin: %1").arg(pluginFileName).latin1()); 218 //qDebug(QString("MainWindowImp::loadPlugin: %1").arg(pluginFileName).latin1());
134 QLibrary *lib = new QLibrary(pluginFileName); 219 QLibrary *lib = new QLibrary(pluginFileName);
135 void *functionPointer = lib->resolve(resolveString); 220 void *functionPointer = lib->resolve(resolveString);
136 if( !functionPointer ){ 221 if( !functionPointer ){
137 qDebug(QString("MainWindowImp: File: %1 is not a plugin, but though was.").arg(pluginFileName).latin1()); 222 qDebug(QString("MainWindowImp: File: %1 is not a plugin, but though was.").arg(pluginFileName).latin1());
138 delete lib; 223 delete lib;
139 return NULL; 224 return NULL;
140 } 225 }
141 226
142 // Try to get an object. 227 // Try to get an object.
143 Module *object = ((Module* (*)()) functionPointer)(); 228 Module *object = ((Module* (*)()) functionPointer)();
144 if(object == NULL){ 229 if(object == NULL){
145 qDebug("MainWindowImp: Couldn't create object, but did load library!"); 230 qDebug("MainWindowImp: Couldn't create object, but did load library!");
146 delete lib; 231 delete lib;
147 return NULL; 232 return NULL;
148 } 233 }
149 234
150 // Store for deletion later 235 // Store for deletion later
151 libraries.insert(object, lib); 236 libraries.insert(object, lib);
152 return object; 237 return object;
153} 238}
154 239
155/** 240/**
156 * The Add button was clicked. Bring up the add dialog and if OK is hit 241 * The Add button was clicked. Bring up the add dialog and if OK is hit
157 * load the plugin and append it to the list 242 * load the plugin and append it to the list
158 */ 243 */
159void MainWindowImp::addClicked(){ 244void MainWindowImp::addClicked(){
160 QMap<Module*, QLibrary*>::Iterator it; 245 QMap<Module*, QLibrary*>::Iterator it;
161 QMap<QString, QString> list; 246 QMap<QString, QString> list;
162 QMap<QString, Module*> newInterfaceOwners; 247 QMap<QString, Module*> newInterfaceOwners;
163 //list.insert("USB (PPP) / (ADD_TEST)", "A dialup connection over the USB port"); 248 //list.insert("USB (PPP) / (ADD_TEST)", "A dialup connection over the USB port");
164 //list.insert("IrDa (PPP) / (ADD_TEST)", "A dialup connection over the IdDa port"); 249 //list.insert("IrDa (PPP) / (ADD_TEST)", "A dialup connection over the IdDa port");
165 for( it = libraries.begin(); it != libraries.end(); ++it ){ 250 for( it = libraries.begin(); it != libraries.end(); ++it ){
166 if(it.key()){ 251 if(it.key()){
167 (it.key())->possibleNewInterfaces(list); 252 (it.key())->possibleNewInterfaces(list);
168 } 253 }
169 } 254 }
170 // See if the list has anything that we can add. 255 // See if the list has anything that we can add.
171 if(list.count() == 0){ 256 if(list.count() == 0){
172 QMessageBox::information(this, "Sorry", "Nothing to add.", QMessageBox::Ok); 257 QMessageBox::information(this, "Sorry", "Nothing to add.", QMessageBox::Ok);
173 return; 258 return;
174 } 259 }
175 AddConnectionImp addNewConnection(this, "AddConnectionImp", true); 260 AddConnectionImp addNewConnection(this, "AddConnectionImp", true);
176 addNewConnection.addConnections(list); 261 addNewConnection.addConnections(list);
177 addNewConnection.showMaximized(); 262 addNewConnection.showMaximized();
178 if(QDialog::Accepted == addNewConnection.exec()){ 263 if(QDialog::Accepted == addNewConnection.exec()){
179 QListViewItem *item = addNewConnection.registeredServicesList->currentItem(); 264 QListViewItem *item = addNewConnection.registeredServicesList->currentItem();
180 if(!item) 265 if(!item)
181 return; 266 return;
182 267
183 for( it = libraries.begin(); it != libraries.end(); ++it ){ 268 for( it = libraries.begin(); it != libraries.end(); ++it ){
184 if(it.key()){ 269 if(it.key()){
185 Interface *i = (it.key())->addNewInterface(item->text(0)); 270 Interface *i = (it.key())->addNewInterface(item->text(0));
186 if(i){ 271 if(i){
187 interfaceNames.insert(i->getInterfaceName(), i); 272 interfaceNames.insert(i->getInterfaceName(), i);
188 updateInterface(i); 273 updateInterface(i);
189 } 274 }
190 } 275 }
191 } 276 }
192 } 277 }
193} 278}
194 279
195/** 280/**
196 * Prompt the user to see if they really want to do this. 281 * Prompt the user to see if they really want to do this.
197 * If they do then remove from the list and unload. 282 * If they do then remove from the list and unload.
198 */ 283 */
199void MainWindowImp::removeClicked(){ 284void MainWindowImp::removeClicked(){
200 QListViewItem *item = connectionList->currentItem(); 285 QListViewItem *item = connectionList->currentItem();
201 if(!item) { 286 if(!item) {
202 QMessageBox::information(this, "Sorry","Please select an interface First.", QMessageBox::Ok); 287 QMessageBox::information(this, "Sorry","Please select an interface First.", QMessageBox::Ok);
203 return; 288 return;
204 } 289 }
205 290
206 Interface *i = interfaceItems[item]; 291 Interface *i = interfaceItems[item];
207 if(i->getModuleOwner() == NULL){ 292 if(i->getModuleOwner() == NULL){
208 QMessageBox::information(this, "Can't remove interface.", "Interface is built in.", QMessageBox::Ok); 293 QMessageBox::information(this, "Can't remove interface.", "Interface is built in.", QMessageBox::Ok);
209 } 294 }
210 else{ 295 else{
211 if(!i->getModuleOwner()->remove(i)) 296 if(!i->getModuleOwner()->remove(i))
212 QMessageBox::information(this, "Error", "Unable to remove.", QMessageBox::Ok); 297 QMessageBox::information(this, "Error", "Unable to remove.", QMessageBox::Ok);
213 else{ 298 else{
214 QMessageBox::information(this, "Success", "Interface was removed.", QMessageBox::Ok); 299 QMessageBox::information(this, "Success", "Interface was removed.", QMessageBox::Ok);
215 // TODO memory managment.... 300 // TODO memory managment....
216 // who deletes the interface? 301 // who deletes the interface?
217 } 302 }
218 } 303 }
219} 304}
220 305
221/** 306/**
222 * Pull up the configure about the currently selected interface. 307 * Pull up the configure about the currently selected interface.
223 * Report an error if no interface is selected. 308 * Report an error if no interface is selected.
224 * If the interface has a module owner then request its configure. 309 * If the interface has a module owner then request its configure.
225 */ 310 */
226void MainWindowImp::configureClicked(){ 311void MainWindowImp::configureClicked(){
227 QListViewItem *item = connectionList->currentItem(); 312 QListViewItem *item = connectionList->currentItem();
228 if(!item){ 313 if(!item){
229 QMessageBox::information(this, "Sorry","Please select an interface first.", QMessageBox::Ok); 314 QMessageBox::information(this, "Sorry","Please select an interface first.", QMessageBox::Ok);
230 return; 315 return;
231 } 316 }
232 317
233 Interface *i = interfaceItems[item]; 318 Interface *i = interfaceItems[item];
234 if(i->getModuleOwner()){ 319 if(i->getModuleOwner()){
235 QWidget *moduleConfigure = i->getModuleOwner()->configure(i); 320 QWidget *moduleConfigure = i->getModuleOwner()->configure(i);
236 if(moduleConfigure != NULL){ 321 if(moduleConfigure != NULL){
237 moduleConfigure->showMaximized(); 322 moduleConfigure->showMaximized();
238 moduleConfigure->show(); 323 moduleConfigure->show();
239 return; 324 return;
240 } 325 }
241 } 326 }
242 327
243 InterfaceSetupImpDialog *configure = new InterfaceSetupImpDialog(0, "InterfaceSetupImp", i, true, Qt::WDestructiveClose); 328 InterfaceSetupImpDialog *configure = new InterfaceSetupImpDialog(0, "InterfaceSetupImp", i, true, Qt::WDestructiveClose);
244 QString currentProfileText = currentProfileLabel->text(); 329 QString currentProfileText = currentProfileLabel->text();
245 if(currentProfileText.upper() == "ALL"); 330 if(currentProfileText.upper() == "ALL");
246 currentProfileText = ""; 331 currentProfileText = "";
247 configure->setProfile(currentProfileText); 332 configure->setProfile(currentProfileText);
248 configure->showMaximized(); 333 configure->showMaximized();
249 configure->show(); 334 configure->show();
250} 335}
251 336
252/** 337/**
253 * Pull up the information about the currently selected interface. 338 * Pull up the information about the currently selected interface.
254 * Report an error if no interface is selected. 339 * Report an error if no interface is selected.
255 * If the interface has a module owner then request its configure. 340 * If the interface has a module owner then request its configure.
256 */ 341 */
257void MainWindowImp::informationClicked(){ 342void MainWindowImp::informationClicked(){
258 QListViewItem *item = connectionList->currentItem(); 343 QListViewItem *item = connectionList->currentItem();
259 if(!item){ 344 if(!item){
260 QMessageBox::information(this, "Sorry","Please select an interface First.", QMessageBox::Ok); 345 QMessageBox::information(this, "Sorry","Please select an interface First.", QMessageBox::Ok);
261 return; 346 return;
262 } 347 }
263 348
264 Interface *i = interfaceItems[item]; 349 Interface *i = interfaceItems[item];
265 if(!i->isAttached()){ 350 if(!i->isAttached()){
266 QMessageBox::information(this, "Sorry","No information about\na disconnected interface.", QMessageBox::Ok); 351 QMessageBox::information(this, "Sorry","No information about\na disconnected interface.", QMessageBox::Ok);
267 return; 352 return;
268 } 353 }
269 354
270 if(i->getModuleOwner()){ 355 if(i->getModuleOwner()){
271 QWidget *moduleInformation = i->getModuleOwner()->information(i); 356 QWidget *moduleInformation = i->getModuleOwner()->information(i);
272 if(moduleInformation != NULL){ 357 if(moduleInformation != NULL){
273 moduleInformation->showMaximized(); 358 moduleInformation->showMaximized();
274 moduleInformation->show(); 359 moduleInformation->show();
275 return; 360 return;
276 } 361 }
277 } 362 }
278 InterfaceInformationImp *information = new InterfaceInformationImp(0, "InterfaceSetupImp", i, true); 363 InterfaceInformationImp *information = new InterfaceInformationImp(0, "InterfaceSetupImp", i, true);
279 information->showMaximized(); 364 information->showMaximized();
280 information->show(); 365 information->show();
281} 366}
282 367
283/** 368/**
284 * Aquire the list of active interfaces from ifconfig
285 * Call ifconfig and ifconfig -a
286 */
287void MainWindowImp::getInterfaceList(){
288 KShellProcess *processAll = new KShellProcess();
289 *processAll << "/sbin/ifconfig" << "-a" << " > " TEMP_ALL;
290 connect(processAll, SIGNAL(processExited(KProcess *)),
291 this, SLOT(jobDone(KProcess *)));
292 threads.insert(processAll, TEMP_ALL);
293
294 KShellProcess *process = new KShellProcess();
295 *process << "/sbin/ifconfig" << " > " TEMP_UP;
296 connect(process, SIGNAL(processExited(KProcess *)),
297 this, SLOT(jobDone(KProcess *)));
298 threads.insert(process, TEMP_UP);
299
300 processAll->start(KShellProcess::NotifyOnExit);
301 process->start(KShellProcess::NotifyOnExit);
302}
303
304void MainWindowImp::jobDone(KProcess *process){
305 QString fileName = threads[process];
306 threads.remove(process);
307 delete process;
308
309 QFile file(fileName);
310 if (!file.open(IO_ReadOnly)){
311 qDebug(QString("MainWindowImp: Can't open file: %1").arg(fileName).latin1());
312 return;
313 }
314
315 QTextStream stream( &file );
316 QString line;
317 while ( !stream.eof() ) {
318 line = stream.readLine();
319 int space = line.find(" ");
320 if(space > 1){
321 // We have found an interface
322 QString interfaceName = line.mid(0, space);
323 Interface *i;
324 // We have found an interface
325 //qDebug(QString("MainWindowImp: Found Interface: %1").arg(line).latin1());
326 // See if we already have it
327 if(interfaceNames.find(interfaceName) == interfaceNames.end()){
328 if(fileName == TEMP_ALL)
329 i = new Interface(this, interfaceName, false);
330 else
331 i = new Interface(this, interfaceName, true);
332 i->setAttached(true);
333
334 QString hardName = "Ethernet";
335 int hardwareName = line.find("Link encap:");
336 int macAddress = line.find("HWaddr");
337 if(macAddress == -1)
338 macAddress = line.length();
339 if(hardwareName != -1)
340 i->setHardwareName(line.mid(hardwareName+11, macAddress-(hardwareName+11)) );
341
342 interfaceNames.insert(i->getInterfaceName(), i);
343 updateInterface(i);
344 connect(i, SIGNAL(updateInterface(Interface *)), this, SLOT(updateInterface(Interface *)));
345 }
346 // It was an interface we already had.
347 else{
348 if(fileName != TEMP_ALL)
349 (interfaceNames[interfaceName])->setStatus(true);
350 }
351 }
352 }
353 file.close();
354 QFile::remove(fileName);
355
356 if(threads.count() == 0){
357 Interfaces i;
358 QStringList list = i.getInterfaceList();
359 QMap<QString, Interface*>::Iterator it;
360 for ( QStringList::Iterator ni = list.begin(); ni != list.end(); ++ni ) {
361 bool found = false;
362 for( it = interfaceNames.begin(); it != interfaceNames.end(); ++it ){
363 if(it.key() == (*ni))
364 found = true;
365 }
366 if(!found){
367 if(!(*ni).contains("_")){
368 Interface *i = new Interface(this, *ni, false);
369 i->setAttached(false);
370 i->setHardwareName("Disconnected");
371 interfaceNames.insert(i->getInterfaceName(), i);
372 updateInterface(i);
373 connect(i, SIGNAL(updateInterface(Interface *)), this, SLOT(updateInterface(Interface *)));
374 }
375 }
376 }
377 }
378}
379
380/**
381 * Update this interface. If no QListViewItem exists create one. 369 * Update this interface. If no QListViewItem exists create one.
382 * @param Interface* pointer to the interface that needs to be updated. 370 * @param Interface* pointer to the interface that needs to be updated.
383 */ 371 */
384void MainWindowImp::updateInterface(Interface *i){ 372void MainWindowImp::updateInterface(Interface *i){
385 if(!advancedUserMode){ 373 if(!advancedUserMode){
386 if(i->getInterfaceName() == "lo") 374 if(i->getInterfaceName() == "lo")
387 return; 375 return;
388 } 376 }
389 377
390 QListViewItem *item = NULL; 378 QListViewItem *item = NULL;
391 379
392 // Find the interface, making it if needed. 380 // Find the interface, making it if needed.
393 if(items.find(i) == items.end()){ 381 if(items.find(i) == items.end()){
394 item = new QListViewItem(connectionList, "", "", ""); 382 item = new QListViewItem(connectionList, "", "", "");
395 // See if you can't find a module owner for this interface 383 // See if you can't find a module owner for this interface
396 QMap<Module*, QLibrary*>::Iterator it; 384 QMap<Module*, QLibrary*>::Iterator it;
397 for( it = libraries.begin(); it != libraries.end(); ++it ){ 385 for( it = libraries.begin(); it != libraries.end(); ++it ){
398 if(it.key()->isOwner(i)) 386 if(it.key()->isOwner(i))
399 i->setModuleOwner(it.key()); 387 i->setModuleOwner(it.key());
400 } 388 }
401 items.insert(i, item); 389 items.insert(i, item);
402 interfaceItems.insert(item, i); 390 interfaceItems.insert(item, i);
403 } 391 }
404 else 392 else
405 item = items[i]; 393 item = items[i];
406 394
407 // Update the icons and information 395 // Update the icons and information
408 item->setPixmap(0, (Resource::loadPixmap(i->getStatus() ? "up": "down"))); 396 item->setPixmap(0, (Resource::loadPixmap(i->getStatus() ? "up": "down")));
409 397
410 QString typeName = "lan"; 398 QString typeName = "lan";
411 if(i->getHardwareName().contains("Local Loopback")) 399 if(i->getHardwareName().contains("Local Loopback"))
412 typeName = "lo"; 400 typeName = "lo";
413 if(i->getInterfaceName().contains("irda")) 401 if(i->getInterfaceName().contains("irda"))
414 typeName = "irda"; 402 typeName = "irda";
415 if(i->getInterfaceName().contains("wlan")) 403 if(i->getInterfaceName().contains("wlan"))
416 typeName = "wlan"; 404 typeName = "wlan";
417 if(i->getInterfaceName().contains("usb")) 405 if(i->getInterfaceName().contains("usb"))
418 typeName = "usb"; 406 typeName = "usb";
419 407
420 if(!i->isAttached()) 408 if(!i->isAttached())
421 typeName = "connect_no"; 409 typeName = "connect_no";
422 // Actually try to use the Module 410 // Actually try to use the Module
423 if(i->getModuleOwner() != NULL) 411 if(i->getModuleOwner() != NULL)
424 typeName = i->getModuleOwner()->getPixmapName(i); 412 typeName = i->getModuleOwner()->getPixmapName(i);
425 413
426 item->setPixmap(1, (Resource::loadPixmap(typeName))); 414 item->setPixmap(1, (Resource::loadPixmap(typeName)));
427 item->setText(2, i->getHardwareName()); 415 item->setText(2, i->getHardwareName());
428 item->setText(3, QString("(%1)").arg(i->getInterfaceName())); 416 item->setText(3, QString("(%1)").arg(i->getInterfaceName()));
429 item->setText(4, (i->getStatus()) ? i->getIp() : QString("")); 417 item->setText(4, (i->getStatus()) ? i->getIp() : QString(""));
430} 418}
431 419
432void MainWindowImp::newProfileChanged(const QString& newText){ 420void MainWindowImp::newProfileChanged(const QString& newText){
433 if(newText.length() > 0) 421 if(newText.length() > 0)
434 newProfileButton->setEnabled(true); 422 newProfileButton->setEnabled(true);
435 else 423 else
436 newProfileButton->setEnabled(false); 424 newProfileButton->setEnabled(false);
437} 425}
438 426
439/** 427/**
440 * Adds a new profile to the list of profiles. 428 * Adds a new profile to the list of profiles.
441 * Don't add profiles that already exists. 429 * Don't add profiles that already exists.
442 * Appends to the list and QStringList 430 * Appends to the list and QStringList
443 */ 431 */
444void MainWindowImp::addProfile(){ 432void MainWindowImp::addProfile(){
445 QString newProfileName = newProfile->text(); 433 QString newProfileName = newProfile->text();
446 if(profiles.grep(newProfileName).count() > 0){ 434 if(profiles.grep(newProfileName).count() > 0){
447 QMessageBox::information(this, "Can't Add","Profile already exists.", QMessageBox::Ok); 435 QMessageBox::information(this, "Can't Add","Profile already exists.", QMessageBox::Ok);
448 return; 436 return;
449 } 437 }
450 profiles.append(newProfileName); 438 profiles.append(newProfileName);
451 profilesList->insertItem(newProfileName); 439 profilesList->insertItem(newProfileName);
452} 440}
453 441
454/** 442/**
455 * Removes the currently selected profile in the combo. 443 * Removes the currently selected profile in the combo.
456 * Doesn't delete if there are less then 2 profiles. 444 * Doesn't delete if there are less then 2 profiles.
457 */ 445 */
458void MainWindowImp::removeProfile(){ 446void MainWindowImp::removeProfile(){
459 if(profilesList->count() <= 1){ 447 if(profilesList->count() <= 1){
460 QMessageBox::information(this, "Can't remove.","At least one profile\nis needed.", QMessageBox::Ok); 448 QMessageBox::information(this, "Can't remove.","At least one profile\nis needed.", QMessageBox::Ok);
461 return; 449 return;
462 } 450 }
463 QString profileToRemove = profilesList->currentText(); 451 QString profileToRemove = profilesList->currentText();
464 if(profileToRemove == "All"){ 452 if(profileToRemove == "All"){
465 QMessageBox::information(this, "Can't remove.","Can't remove default.", QMessageBox::Ok); 453 QMessageBox::information(this, "Can't remove.","Can't remove default.", QMessageBox::Ok);
466 return; 454 return;
467 } 455 }
468 // Can't remove the curent profile 456 // Can't remove the curent profile
469 if(profileToRemove == currentProfileLabel->text()){ 457 if(profileToRemove == currentProfileLabel->text()){
470 QMessageBox::information(this, "Can't remove.",QString("%1 is the current profile.").arg(profileToRemove), QMessageBox::Ok); 458 QMessageBox::information(this, "Can't remove.",QString("%1 is the current profile.").arg(profileToRemove), QMessageBox::Ok);
471 return; 459 return;
472 460
473 } 461 }
474 462
475 if(QMessageBox::information(this, "Question",QString("Remove profile: %1").arg(profileToRemove), QMessageBox::Ok, QMessageBox::Cancel) == QMessageBox::Ok){ 463 if(QMessageBox::information(this, "Question",QString("Remove profile: %1").arg(profileToRemove), QMessageBox::Ok, QMessageBox::Cancel) == QMessageBox::Ok){
476 profiles = QStringList::split(" ", profiles.join(" ").replace(QRegExp(profileToRemove), "")); 464 profiles = QStringList::split(" ", profiles.join(" ").replace(QRegExp(profileToRemove), ""));
477 profilesList->clear(); 465 profilesList->clear();
478 for ( QStringList::Iterator it = profiles.begin(); it != profiles.end(); ++it) 466 for ( QStringList::Iterator it = profiles.begin(); it != profiles.end(); ++it)
479 profilesList->insertItem((*it)); 467 profilesList->insertItem((*it));
480 468
481 // Remove any interface settings and mappings. 469 // Remove any interface settings and mappings.
482 Interfaces interfaces; 470 Interfaces interfaces;
483 // Go through them one by one 471 // Go through them one by one
484 QMap<Interface*, QListViewItem*>::Iterator it; 472 QMap<Interface*, QListViewItem*>::Iterator it;
485 for( it = items.begin(); it != items.end(); ++it ){ 473 for( it = items.begin(); it != items.end(); ++it ){
486 QString interfaceName = it.key()->getInterfaceName(); 474 QString interfaceName = it.key()->getInterfaceName();
487 qDebug(interfaceName.latin1()); 475 qDebug(interfaceName.latin1());
488 if(interfaces.setInterface(interfaceName + "_" + profileToRemove)){ 476 if(interfaces.setInterface(interfaceName + "_" + profileToRemove)){
489 interfaces.removeInterface(); 477 interfaces.removeInterface();
490 if(interfaces.setMapping(interfaceName)){ 478 if(interfaces.setMapping(interfaceName)){
491 if(profilesList->count() == 1) 479 if(profilesList->count() == 1)
492 interfaces.removeMapping(); 480 interfaces.removeMapping();
493 else{ 481 else{
494 interfaces.removeMap("map", interfaceName + "_" + profileToRemove); 482 interfaces.removeMap("map", interfaceName + "_" + profileToRemove);
495 } 483 }
496 } 484 }
497 interfaces.write(); 485 interfaces.write();
498 break; 486 break;
499 } 487 }
500 } 488 }
501 } 489 }
502} 490}
503 491
504/** 492/**
505 * A new profile has been selected, change. 493 * A new profile has been selected, change.
506 * @param newProfile the new profile. 494 * @param newProfile the new profile.
507 */ 495 */
508void MainWindowImp::changeProfile(){ 496void MainWindowImp::changeProfile(){
509 if(profilesList->currentItem() == -1){ 497 if(profilesList->currentItem() == -1){
510 QMessageBox::information(this, "Can't Change.","Please select a profile.", QMessageBox::Ok); 498 QMessageBox::information(this, "Can't Change.","Please select a profile.", QMessageBox::Ok);
511 return; 499 return;
512 } 500 }
513 QString newProfile = profilesList->text(profilesList->currentItem()); 501 QString newProfile = profilesList->text(profilesList->currentItem());
514 if(newProfile != currentProfileLabel->text()){ 502 if(newProfile != currentProfileLabel->text()){
515 currentProfileLabel->setText(newProfile); 503 currentProfileLabel->setText(newProfile);
516 QFile::remove(scheme); 504 QFile::remove(scheme);
517 QFile file(scheme); 505 QFile file(scheme);
518 if ( file.open(IO_ReadWrite) ) { 506 if ( file.open(IO_ReadWrite) ) {
519 QTextStream stream( &file ); 507 QTextStream stream( &file );
520 stream << QString("SCHEME=%1").arg(newProfile); 508 stream << QString("SCHEME=%1").arg(newProfile);
521 file.close(); 509 file.close();
522 } 510 }
523 // restart all up devices? 511 // restart all up devices?
524 if(QMessageBox::information(this, "Question","Restart all running interfaces?", QMessageBox::Ok, QMessageBox::No) == QMessageBox::Ok){ 512 if(QMessageBox::information(this, "Question","Restart all running interfaces?", QMessageBox::Ok, QMessageBox::No) == QMessageBox::Ok){
525 // Go through them one by one 513 // Go through them one by one
526 QMap<Interface*, QListViewItem*>::Iterator it; 514 QMap<Interface*, QListViewItem*>::Iterator it;
527 for( it = items.begin(); it != items.end(); ++it ){ 515 for( it = items.begin(); it != items.end(); ++it ){
528 if(it.key()->getStatus() == true) 516 if(it.key()->getStatus() == true)
529 it.key()->restart(); 517 it.key()->restart();
530 } 518 }
531 } 519 }
532 } 520 }
533 // TODO change the profile in the modules 521 // TODO change the profile in the modules
534} 522}
535 523
536// mainwindowimp.cpp 524// mainwindowimp.cpp
537 525
diff --git a/noncore/net/networksetup/mainwindowimp.h b/noncore/net/networksetup/mainwindowimp.h
index e5284b4..382428c 100644
--- a/noncore/net/networksetup/mainwindowimp.h
+++ b/noncore/net/networksetup/mainwindowimp.h
@@ -1,59 +1,58 @@
1#ifndef MAINWINOWIMP_H 1#ifndef MAINWINOWIMP_H
2#define MAINWINOWIMP_H 2#define MAINWINOWIMP_H
3 3
4#include "mainwindow.h" 4#include "mainwindow.h"
5#include <qmap.h> 5#include <qmap.h>
6#include <qstringlist.h> 6#include <qstringlist.h>
7 7
8class Module; 8class Module;
9class Interface; 9class Interface;
10class QLibrary; 10class QLibrary;
11class KProcess; 11class KProcess;
12 12
13class MainWindowImp : public MainWindow { 13class MainWindowImp : public MainWindow {
14 Q_OBJECT 14 Q_OBJECT
15 15
16public: 16public:
17 MainWindowImp(QWidget *parent=0, const char *name=0); 17 MainWindowImp(QWidget *parent=0, const char *name=0);
18 ~MainWindowImp(); 18 ~MainWindowImp();
19 19
20private slots: 20private slots:
21 void getAllInterfaces();
22
21 void addClicked(); 23 void addClicked();
22 void removeClicked(); 24 void removeClicked();
23 void configureClicked(); 25 void configureClicked();
24 void informationClicked(); 26 void informationClicked();
25 27
26 void jobDone(KProcess *process);
27 void getInterfaceList();
28
29 void addProfile(); 28 void addProfile();
30 void removeProfile(); 29 void removeProfile();
31 void changeProfile(); 30 void changeProfile();
32 31
33 void updateInterface(Interface *i); 32 void updateInterface(Interface *i);
34 void newProfileChanged(const QString& newText); 33 void newProfileChanged(const QString& newText);
35 34
36private: 35private:
37 void loadModules(QString path); 36 void loadModules(QString path);
38 37
39 Module* loadPlugin(QString pluginFileName, 38 Module* loadPlugin(QString pluginFileName,
40 QString resolveString = "create_plugin"); 39 QString resolveString = "create_plugin");
41 40
42 // For our local list of names 41 // For our local list of names
43 QMap<QString, Interface*> interfaceNames; 42 QMap<QString, Interface*> interfaceNames;
44 43
45 QMap<Module*, QLibrary*> libraries; 44 QMap<Module*, QLibrary*> libraries;
46 QMap<Interface*, QListViewItem*> items; 45 QMap<Interface*, QListViewItem*> items;
47 QMap<QListViewItem*, Interface*> interfaceItems; 46 QMap<QListViewItem*, Interface*> interfaceItems;
48 47
49 QMap<KProcess*, QString> threads; 48 QMap<KProcess*, QString> threads;
50 QStringList profiles; 49 QStringList profiles;
51 50
52 bool advancedUserMode; 51 bool advancedUserMode;
53 QString scheme; 52 QString scheme;
54}; 53};
55 54
56#endif 55#endif
57 56
58// mainwindowimp.h 57// mainwindowimp.h
59 58
diff --git a/noncore/net/networksetup/networksetup.pro b/noncore/net/networksetup/networksetup.pro
index 6420924..cb517ce 100644
--- a/noncore/net/networksetup/networksetup.pro
+++ b/noncore/net/networksetup/networksetup.pro
@@ -1,11 +1,11 @@
1DESTDIR = $(OPIEDIR)/bin 1#DESTDIR = $(OPIEDIR)/bin
2TEMPLATE = app 2TEMPLATE = app
3#CONFIG = qt warn_on debug 3#CONFIG = qt warn_on debug
4CONFIG = qt warn_on release 4CONFIG = qt warn_on release
5HEADERS = mainwindowimp.h addconnectionimp.h defaultmodule.h kprocctrl.h module.h kprocess.h 5HEADERS = mainwindowimp.h addconnectionimp.h defaultmodule.h module.h
6SOURCES = main.cpp mainwindowimp.cpp addconnectionimp.cpp kprocctrl.cpp kprocess.cpp 6SOURCES = main.cpp mainwindowimp.cpp addconnectionimp.cpp
7INCLUDEPATH += $(OPIEDIR)/include interfaces/ 7INCLUDEPATH += $(OPIEDIR)/include interfaces/
8DEPENDPATH += $(OPIEDIR)/include interfaces/ wlan 8DEPENDPATH += $(OPIEDIR)/include interfaces/ wlan
9LIBS += -lqpe -L$(OPIEDIR)/plugins/networksetup -Linterfaces/ -linterfaces 9LIBS += -lqpe -L$(OPIEDIR)/plugins/networksetup -Linterfaces/ -linterfaces
10INTERFACES = mainwindow.ui addconnection.ui 10INTERFACES = mainwindow.ui addconnection.ui
11TARGET = networksetup 11TARGET = networksetup
diff --git a/noncore/net/networksetup/ppp/.cvsignore b/noncore/net/networksetup/ppp/.cvsignore
new file mode 100644
index 0000000..d753773
--- a/dev/null
+++ b/noncore/net/networksetup/ppp/.cvsignore
@@ -0,0 +1,23 @@
1.moc.cpp
2*.moc
3*.moc.o
4*.o
5moc_*.cpp
6.libs
7.deps
8.moc.o
9.o
10Makefile*
11networksetup
12addconnection.cpp
13addconnection.h
14interfaceadvanced.cpp
15interfaceadvanced.h
16interfaceinformation.cpp
17interfaceinformation.h
18interfacesetup.cpp
19interfacesetup.h
20mainwindow.cpp
21mainwindow.h
22systemadvanced.cpp
23systemadvanced.h
diff --git a/noncore/net/networksetup/ppp/ppp.ui b/noncore/net/networksetup/ppp/ppp.ui
new file mode 100644
index 0000000..d08eda0
--- a/dev/null
+++ b/noncore/net/networksetup/ppp/ppp.ui
@@ -0,0 +1,770 @@
1<!DOCTYPE UI><UI>
2<class>DialupBase</class>
3<widget>
4 <class>QDialog</class>
5 <property stdset="1">
6 <name>name</name>
7 <cstring>Form1</cstring>
8 </property>
9 <property stdset="1">
10 <name>geometry</name>
11 <rect>
12 <x>0</x>
13 <y>0</y>
14 <width>273</width>
15 <height>340</height>
16 </rect>
17 </property>
18 <property stdset="1">
19 <name>caption</name>
20 <string>Dial-up </string>
21 </property>
22 <property>
23 <name>layoutMargin</name>
24 </property>
25 <property>
26 <name>layoutSpacing</name>
27 </property>
28 <vbox>
29 <property stdset="1">
30 <name>margin</name>
31 <number>1</number>
32 </property>
33 <property stdset="1">
34 <name>spacing</name>
35 <number>0</number>
36 </property>
37 <widget>
38 <class>QTabWidget</class>
39 <property stdset="1">
40 <name>name</name>
41 <cstring>TabWidget2</cstring>
42 </property>
43 <property>
44 <name>layoutMargin</name>
45 </property>
46 <property>
47 <name>layoutSpacing</name>
48 </property>
49 <widget>
50 <class>QWidget</class>
51 <property stdset="1">
52 <name>name</name>
53 <cstring>tab</cstring>
54 </property>
55 <attribute>
56 <name>title</name>
57 <string>Account</string>
58 </attribute>
59 <grid>
60 <property stdset="1">
61 <name>margin</name>
62 <number>6</number>
63 </property>
64 <property stdset="1">
65 <name>spacing</name>
66 <number>4</number>
67 </property>
68 <widget row="3" column="1" >
69 <class>QLineEdit</class>
70 <property stdset="1">
71 <name>name</name>
72 <cstring>password</cstring>
73 </property>
74 <property stdset="1">
75 <name>echoMode</name>
76 <enum>Password</enum>
77 </property>
78 </widget>
79 <widget row="2" column="1" >
80 <class>QLineEdit</class>
81 <property stdset="1">
82 <name>name</name>
83 <cstring>username</cstring>
84 </property>
85 </widget>
86 <widget row="2" column="0" >
87 <class>QLabel</class>
88 <property stdset="1">
89 <name>name</name>
90 <cstring>TextLabel1</cstring>
91 </property>
92 <property stdset="1">
93 <name>text</name>
94 <string>Username</string>
95 </property>
96 </widget>
97 <widget row="3" column="0" >
98 <class>QLabel</class>
99 <property stdset="1">
100 <name>name</name>
101 <cstring>TextLabel2</cstring>
102 </property>
103 <property stdset="1">
104 <name>text</name>
105 <string>Password</string>
106 </property>
107 </widget>
108 <widget row="5" column="0" >
109 <class>QLabel</class>
110 <property stdset="1">
111 <name>name</name>
112 <cstring>TextLabel1_2_2</cstring>
113 </property>
114 <property stdset="1">
115 <name>text</name>
116 <string>Phone #</string>
117 </property>
118 </widget>
119 <widget row="5" column="1" >
120 <class>QLineEdit</class>
121 <property stdset="1">
122 <name>name</name>
123 <cstring>phone</cstring>
124 </property>
125 </widget>
126 <widget row="4" column="0" rowspan="1" colspan="2" >
127 <class>Line</class>
128 <property stdset="1">
129 <name>name</name>
130 <cstring>Line3</cstring>
131 </property>
132 <property stdset="1">
133 <name>orientation</name>
134 <enum>Horizontal</enum>
135 </property>
136 </widget>
137 <widget row="0" column="1" >
138 <class>QLineEdit</class>
139 <property stdset="1">
140 <name>name</name>
141 <cstring>acname</cstring>
142 </property>
143 </widget>
144 <widget row="0" column="0" >
145 <class>QLabel</class>
146 <property stdset="1">
147 <name>name</name>
148 <cstring>TextLabel1_2</cstring>
149 </property>
150 <property stdset="1">
151 <name>text</name>
152 <string>Name</string>
153 </property>
154 </widget>
155 <widget row="1" column="0" rowspan="1" colspan="2" >
156 <class>Line</class>
157 <property stdset="1">
158 <name>name</name>
159 <cstring>Line4</cstring>
160 </property>
161 <property stdset="1">
162 <name>orientation</name>
163 <enum>Horizontal</enum>
164 </property>
165 </widget>
166 <spacer row="9" column="1" >
167 <property>
168 <name>name</name>
169 <cstring>Spacer4</cstring>
170 </property>
171 <property stdset="1">
172 <name>orientation</name>
173 <enum>Vertical</enum>
174 </property>
175 <property stdset="1">
176 <name>sizeType</name>
177 <enum>Expanding</enum>
178 </property>
179 <property>
180 <name>sizeHint</name>
181 <size>
182 <width>20</width>
183 <height>20</height>
184 </size>
185 </property>
186 </spacer>
187 </grid>
188 </widget>
189 <widget>
190 <class>QWidget</class>
191 <property stdset="1">
192 <name>name</name>
193 <cstring>tab</cstring>
194 </property>
195 <attribute>
196 <name>title</name>
197 <string>Modem</string>
198 </attribute>
199 <grid>
200 <property stdset="1">
201 <name>margin</name>
202 <number>6</number>
203 </property>
204 <property stdset="1">
205 <name>spacing</name>
206 <number>4</number>
207 </property>
208 <widget row="0" column="0" >
209 <class>QLabel</class>
210 <property stdset="1">
211 <name>name</name>
212 <cstring>TextLabel3_2_2</cstring>
213 </property>
214 <property stdset="1">
215 <name>text</name>
216 <string>AT-dial</string>
217 </property>
218 </widget>
219 <widget row="0" column="1" rowspan="1" colspan="3" >
220 <class>QComboBox</class>
221 <item>
222 <property>
223 <name>text</name>
224 <string>ATDT</string>
225 </property>
226 </item>
227 <item>
228 <property>
229 <name>text</name>
230 <string>ATDP</string>
231 </property>
232 </item>
233 <property stdset="1">
234 <name>name</name>
235 <cstring>atdial</cstring>
236 </property>
237 <property stdset="1">
238 <name>editable</name>
239 <bool>true</bool>
240 </property>
241 </widget>
242 <widget row="1" column="0" >
243 <class>QLabel</class>
244 <property stdset="1">
245 <name>name</name>
246 <cstring>TextLabel1_4</cstring>
247 </property>
248 <property stdset="1">
249 <name>text</name>
250 <string>Speed</string>
251 </property>
252 </widget>
253 <widget row="1" column="1" rowspan="1" colspan="3" >
254 <class>QComboBox</class>
255 <item>
256 <property>
257 <name>text</name>
258 <string>4800</string>
259 </property>
260 </item>
261 <item>
262 <property>
263 <name>text</name>
264 <string>9600</string>
265 </property>
266 </item>
267 <item>
268 <property>
269 <name>text</name>
270 <string>19200</string>
271 </property>
272 </item>
273 <item>
274 <property>
275 <name>text</name>
276 <string>38400</string>
277 </property>
278 </item>
279 <item>
280 <property>
281 <name>text</name>
282 <string>57600</string>
283 </property>
284 </item>
285 <item>
286 <property>
287 <name>text</name>
288 <string>115200</string>
289 </property>
290 </item>
291 <property stdset="1">
292 <name>name</name>
293 <cstring>speed</cstring>
294 </property>
295 <property stdset="1">
296 <name>currentItem</name>
297 <number>5</number>
298 </property>
299 </widget>
300 <widget row="3" column="1" >
301 <class>QSlider</class>
302 <property stdset="1">
303 <name>name</name>
304 <cstring>connectdelay</cstring>
305 </property>
306 <property stdset="1">
307 <name>minValue</name>
308 <number>1</number>
309 </property>
310 <property stdset="1">
311 <name>maxValue</name>
312 <number>180</number>
313 </property>
314 <property stdset="1">
315 <name>value</name>
316 <number>6</number>
317 </property>
318 <property stdset="1">
319 <name>orientation</name>
320 <enum>Horizontal</enum>
321 </property>
322 </widget>
323 <widget row="3" column="0" >
324 <class>QLabel</class>
325 <property stdset="1">
326 <name>name</name>
327 <cstring>TextLabel1_3</cstring>
328 </property>
329 <property stdset="1">
330 <name>text</name>
331 <string>Wait time</string>
332 </property>
333 </widget>
334 <widget row="3" column="2" >
335 <class>QLabel</class>
336 <property stdset="1">
337 <name>name</name>
338 <cstring>connectdelay_text</cstring>
339 </property>
340 <property stdset="1">
341 <name>minimumSize</name>
342 <size>
343 <width>15</width>
344 <height>0</height>
345 </size>
346 </property>
347 <property stdset="1">
348 <name>text</name>
349 <string>1</string>
350 </property>
351 <property stdset="1">
352 <name>alignment</name>
353 <set>AlignVCenter|AlignRight</set>
354 </property>
355 <property>
356 <name>hAlign</name>
357 </property>
358 </widget>
359 <widget row="3" column="3" >
360 <class>QLabel</class>
361 <property stdset="1">
362 <name>name</name>
363 <cstring>TextLabel5</cstring>
364 </property>
365 <property stdset="1">
366 <name>text</name>
367 <string>sec</string>
368 </property>
369 </widget>
370 <widget row="2" column="0" >
371 <class>QLabel</class>
372 <property stdset="1">
373 <name>name</name>
374 <cstring>TextLabel3</cstring>
375 </property>
376 <property stdset="1">
377 <name>text</name>
378 <string>Flow control</string>
379 </property>
380 </widget>
381 <widget row="2" column="1" rowspan="1" colspan="3" >
382 <class>QCheckBox</class>
383 <property stdset="1">
384 <name>name</name>
385 <cstring>crtscts</cstring>
386 </property>
387 <property stdset="1">
388 <name>text</name>
389 <string>Hardware flow control</string>
390 </property>
391 <property stdset="1">
392 <name>checked</name>
393 <bool>true</bool>
394 </property>
395 </widget>
396 <spacer row="4" column="1" >
397 <property>
398 <name>name</name>
399 <cstring>Spacer5</cstring>
400 </property>
401 <property stdset="1">
402 <name>orientation</name>
403 <enum>Vertical</enum>
404 </property>
405 <property stdset="1">
406 <name>sizeType</name>
407 <enum>Expanding</enum>
408 </property>
409 <property>
410 <name>sizeHint</name>
411 <size>
412 <width>20</width>
413 <height>20</height>
414 </size>
415 </property>
416 </spacer>
417 <widget row="5" column="0" rowspan="1" colspan="4" >
418 <class>QButtonGroup</class>
419 <property stdset="1">
420 <name>name</name>
421 <cstring>dialmode</cstring>
422 </property>
423 <property stdset="1">
424 <name>title</name>
425 <string>Demand Dialing</string>
426 </property>
427 <grid>
428 <property stdset="1">
429 <name>margin</name>
430 <number>11</number>
431 </property>
432 <property stdset="1">
433 <name>spacing</name>
434 <number>6</number>
435 </property>
436 <widget row="0" column="0" rowspan="1" colspan="2" >
437 <class>QRadioButton</class>
438 <property stdset="1">
439 <name>name</name>
440 <cstring>dial_manual</cstring>
441 </property>
442 <property stdset="1">
443 <name>text</name>
444 <string>Manual connect and disconnect</string>
445 </property>
446 </widget>
447 <widget row="3" column="1" >
448 <class>QSpinBox</class>
449 <property stdset="1">
450 <name>name</name>
451 <cstring>idletime</cstring>
452 </property>
453 <property stdset="1">
454 <name>suffix</name>
455 <string> seconds</string>
456 </property>
457 <property stdset="1">
458 <name>maxValue</name>
459 <number>3600</number>
460 </property>
461 <property stdset="1">
462 <name>lineStep</name>
463 <number>30</number>
464 </property>
465 <property stdset="1">
466 <name>value</name>
467 <number>120</number>
468 </property>
469 </widget>
470 <widget row="3" column="0" >
471 <class>QLabel</class>
472 <property stdset="1">
473 <name>name</name>
474 <cstring>TextLabel1_5</cstring>
475 </property>
476 <property stdset="1">
477 <name>sizePolicy</name>
478 <sizepolicy>
479 <hsizetype>7</hsizetype>
480 <vsizetype>1</vsizetype>
481 </sizepolicy>
482 </property>
483 <property stdset="1">
484 <name>text</name>
485 <string>Idle timeout:</string>
486 </property>
487 <property stdset="1">
488 <name>alignment</name>
489 <set>AlignVCenter|AlignRight</set>
490 </property>
491 <property>
492 <name>hAlign</name>
493 </property>
494 </widget>
495 <widget row="2" column="0" rowspan="1" colspan="2" >
496 <class>QRadioButton</class>
497 <property stdset="1">
498 <name>name</name>
499 <cstring>dial_demand</cstring>
500 </property>
501 <property stdset="1">
502 <name>text</name>
503 <string>Automatic connect and disconnect</string>
504 </property>
505 <property stdset="1">
506 <name>checked</name>
507 <bool>true</bool>
508 </property>
509 <property stdset="1">
510 <name>buttonGroupId</name>
511 <number>2</number>
512 </property>
513 </widget>
514 <widget row="1" column="0" rowspan="1" colspan="2" >
515 <class>QRadioButton</class>
516 <property stdset="1">
517 <name>name</name>
518 <cstring>dial_idle</cstring>
519 </property>
520 <property stdset="1">
521 <name>text</name>
522 <string>Manual connect, automatic disconnect</string>
523 </property>
524 <property stdset="1">
525 <name>buttonGroupId</name>
526 <number>1</number>
527 </property>
528 </widget>
529 </grid>
530 </widget>
531 </grid>
532 </widget>
533 <widget>
534 <class>QWidget</class>
535 <property stdset="1">
536 <name>name</name>
537 <cstring>tab</cstring>
538 </property>
539 <attribute>
540 <name>title</name>
541 <string>Network</string>
542 </attribute>
543 <grid>
544 <property stdset="1">
545 <name>margin</name>
546 <number>6</number>
547 </property>
548 <property stdset="1">
549 <name>spacing</name>
550 <number>4</number>
551 </property>
552 <spacer row="4" column="1" >
553 <property>
554 <name>name</name>
555 <cstring>Spacer8</cstring>
556 </property>
557 <property stdset="1">
558 <name>orientation</name>
559 <enum>Vertical</enum>
560 </property>
561 <property stdset="1">
562 <name>sizeType</name>
563 <enum>Expanding</enum>
564 </property>
565 <property>
566 <name>sizeHint</name>
567 <size>
568 <width>20</width>
569 <height>20</height>
570 </size>
571 </property>
572 </spacer>
573 <widget row="2" column="0" >
574 <class>QCheckBox</class>
575 <property stdset="1">
576 <name>name</name>
577 <cstring>usepeerdns</cstring>
578 </property>
579 <property stdset="1">
580 <name>text</name>
581 <string>Auto-detect name servers</string>
582 </property>
583 <property stdset="1">
584 <name>checked</name>
585 <bool>true</bool>
586 </property>
587 </widget>
588 <widget row="1" column="0" rowspan="1" colspan="2" >
589 <class>QGroupBox</class>
590 <property stdset="1">
591 <name>name</name>
592 <cstring>gatewaybox</cstring>
593 </property>
594 <property stdset="1">
595 <name>enabled</name>
596 <bool>false</bool>
597 </property>
598 <property stdset="1">
599 <name>title</name>
600 <string></string>
601 </property>
602 <hbox>
603 <property stdset="1">
604 <name>margin</name>
605 <number>11</number>
606 </property>
607 <property stdset="1">
608 <name>spacing</name>
609 <number>6</number>
610 </property>
611 <widget>
612 <class>QLabel</class>
613 <property stdset="1">
614 <name>name</name>
615 <cstring>TextLabel4_2</cstring>
616 </property>
617 <property stdset="1">
618 <name>text</name>
619 <string>Gateway</string>
620 </property>
621 </widget>
622 <widget>
623 <class>QLineEdit</class>
624 <property stdset="1">
625 <name>name</name>
626 <cstring>gateway</cstring>
627 </property>
628 <property stdset="1">
629 <name>text</name>
630 <string></string>
631 </property>
632 </widget>
633 </hbox>
634 </widget>
635 <widget row="0" column="0" rowspan="1" colspan="2" >
636 <class>QCheckBox</class>
637 <property stdset="1">
638 <name>name</name>
639 <cstring>defaultroute</cstring>
640 </property>
641 <property stdset="1">
642 <name>text</name>
643 <string>Auto-detect routing</string>
644 </property>
645 <property stdset="1">
646 <name>checked</name>
647 <bool>true</bool>
648 </property>
649 </widget>
650 <widget row="3" column="0" rowspan="1" colspan="2" >
651 <class>QGroupBox</class>
652 <property stdset="1">
653 <name>name</name>
654 <cstring>dnsbox</cstring>
655 </property>
656 <property stdset="1">
657 <name>enabled</name>
658 <bool>false</bool>
659 </property>
660 <property stdset="1">
661 <name>title</name>
662 <string></string>
663 </property>
664 <grid>
665 <property stdset="1">
666 <name>margin</name>
667 <number>11</number>
668 </property>
669 <property stdset="1">
670 <name>spacing</name>
671 <number>6</number>
672 </property>
673 <widget row="0" column="1" >
674 <class>QLineEdit</class>
675 <property stdset="1">
676 <name>name</name>
677 <cstring>dns1</cstring>
678 </property>
679 <property stdset="1">
680 <name>text</name>
681 <string></string>
682 </property>
683 </widget>
684 <widget row="1" column="1" >
685 <class>QLineEdit</class>
686 <property stdset="1">
687 <name>name</name>
688 <cstring>dns2</cstring>
689 </property>
690 <property stdset="1">
691 <name>text</name>
692 <string></string>
693 </property>
694 </widget>
695 <widget row="0" column="0" >
696 <class>QLabel</class>
697 <property stdset="1">
698 <name>name</name>
699 <cstring>TextLabel1_2_3</cstring>
700 </property>
701 <property stdset="1">
702 <name>text</name>
703 <string>First DNS</string>
704 </property>
705 </widget>
706 <widget row="1" column="0" >
707 <class>QLabel</class>
708 <property stdset="1">
709 <name>name</name>
710 <cstring>TextLabel1_2_2_2</cstring>
711 </property>
712 <property stdset="1">
713 <name>text</name>
714 <string>Second DNS</string>
715 </property>
716 </widget>
717 </grid>
718 </widget>
719 </grid>
720 </widget>
721 </widget>
722 </vbox>
723</widget>
724<connections>
725 <connection>
726 <sender>defaultroute</sender>
727 <signal>toggled(bool)</signal>
728 <receiver>gatewaybox</receiver>
729 <slot>setDisabled(bool)</slot>
730 </connection>
731 <connection>
732 <sender>usepeerdns</sender>
733 <signal>toggled(bool)</signal>
734 <receiver>dnsbox</receiver>
735 <slot>setDisabled(bool)</slot>
736 </connection>
737 <connection>
738 <sender>connectdelay</sender>
739 <signal>valueChanged(int)</signal>
740 <receiver>connectdelay_text</receiver>
741 <slot>setNum(int)</slot>
742 </connection>
743 <connection>
744 <sender>dial_manual</sender>
745 <signal>toggled(bool)</signal>
746 <receiver>idletime</receiver>
747 <slot>setDisabled(bool)</slot>
748 </connection>
749</connections>
750<tabstops>
751 <tabstop>TabWidget2</tabstop>
752 <tabstop>acname</tabstop>
753 <tabstop>username</tabstop>
754 <tabstop>password</tabstop>
755 <tabstop>phone</tabstop>
756 <tabstop>atdial</tabstop>
757 <tabstop>speed</tabstop>
758 <tabstop>crtscts</tabstop>
759 <tabstop>connectdelay</tabstop>
760 <tabstop>dial_manual</tabstop>
761 <tabstop>dial_idle</tabstop>
762 <tabstop>dial_demand</tabstop>
763 <tabstop>idletime</tabstop>
764 <tabstop>defaultroute</tabstop>
765 <tabstop>gateway</tabstop>
766 <tabstop>usepeerdns</tabstop>
767 <tabstop>dns1</tabstop>
768 <tabstop>dns2</tabstop>
769</tabstops>
770</UI>
diff --git a/noncore/settings/networksettings/kprocctrl.cpp b/noncore/settings/networksettings/kprocctrl.cpp
deleted file mode 100644
index cd8711a..0000000
--- a/noncore/settings/networksettings/kprocctrl.cpp
+++ b/dev/null
@@ -1,267 +0,0 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 1997 Christian Czezakte (e9025461@student.tuwien.ac.at)
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA.
18*/
19//
20// KPROCESSCONTROLLER -- A helper class for KProcess
21//
22// version 0.3.1, Jan, 8th 1997
23//
24// (C) Christian Czezatke
25// e9025461@student.tuwien.ac.at
26//
27
28//#include <config.h>
29
30#include <sys/types.h>
31#include <sys/socket.h>
32
33#include <errno.h>
34#include <fcntl.h>
35#include <stdio.h>
36#include <string.h>
37#include <unistd.h>
38#include <assert.h>
39
40#include <qsocketnotifier.h>
41#include "kprocess.h"
42#include "kprocctrl.h"
43
44KProcessController *KProcessController::theKProcessController = 0;
45
46struct sigaction KProcessController::oldChildHandlerData;
47bool KProcessController::handlerSet = false;
48
49KProcessController::KProcessController()
50{
51 assert( theKProcessController == 0 );
52
53 if (0 > pipe(fd))
54 printf(strerror(errno));
55
56 notifier = new QSocketNotifier(fd[0], QSocketNotifier::Read);
57 notifier->setEnabled(true);
58 QObject::connect(notifier, SIGNAL(activated(int)),
59 this, SLOT(slotDoHousekeeping(int)));
60 connect( &delayedChildrenCleanupTimer, SIGNAL( timeout()),
61 SLOT( delayedChildrenCleanup()));
62
63 theKProcessController = this;
64
65 setupHandlers();
66}
67
68
69void KProcessController::setupHandlers()
70{
71 if( handlerSet )
72 return;
73 struct sigaction act;
74 act.sa_handler=theSigCHLDHandler;
75 sigemptyset(&(act.sa_mask));
76 sigaddset(&(act.sa_mask), SIGCHLD);
77 // Make sure we don't block this signal. gdb tends to do that :-(
78 sigprocmask(SIG_UNBLOCK, &(act.sa_mask), 0);
79
80 act.sa_flags = SA_NOCLDSTOP;
81
82 // CC: take care of SunOS which automatically restarts interrupted system
83 // calls (and thus does not have SA_RESTART)
84
85#ifdef SA_RESTART
86 act.sa_flags |= SA_RESTART;
87#endif
88
89 sigaction( SIGCHLD, &act, &oldChildHandlerData );
90
91 act.sa_handler=SIG_IGN;
92 sigemptyset(&(act.sa_mask));
93 sigaddset(&(act.sa_mask), SIGPIPE);
94 act.sa_flags = 0;
95 sigaction( SIGPIPE, &act, 0L);
96 handlerSet = true;
97}
98
99void KProcessController::resetHandlers()
100{
101 if( !handlerSet )
102 return;
103 sigaction( SIGCHLD, &oldChildHandlerData, 0 );
104 // there should be no problem with SIGPIPE staying SIG_IGN
105 handlerSet = false;
106}
107
108// block SIGCHLD handler, because it accesses processList
109void KProcessController::addKProcess( KProcess* p )
110{
111 sigset_t newset, oldset;
112 sigemptyset( &newset );
113 sigaddset( &newset, SIGCHLD );
114 sigprocmask( SIG_BLOCK, &newset, &oldset );
115 processList.append( p );
116 sigprocmask( SIG_SETMASK, &oldset, 0 );
117}
118
119void KProcessController::removeKProcess( KProcess* p )
120{
121 sigset_t newset, oldset;
122 sigemptyset( &newset );
123 sigaddset( &newset, SIGCHLD );
124 sigprocmask( SIG_BLOCK, &newset, &oldset );
125 processList.remove( p );
126 sigprocmask( SIG_SETMASK, &oldset, 0 );
127}
128
129//using a struct which contains both the pid and the status makes it easier to write
130//and read the data into the pipe
131//especially this solves a problem which appeared on my box where slotDoHouseKeeping() received
132//only 4 bytes (with some debug output around the write()'s it received all 8 bytes)
133//don't know why this happened, but when writing all 8 bytes at once it works here, aleXXX
134struct waitdata
135{
136 pid_t pid;
137 int status;
138};
139
140void KProcessController::theSigCHLDHandler(int arg)
141{
142 struct waitdata wd;
143// int status;
144// pid_t this_pid;
145 int saved_errno;
146
147 saved_errno = errno;
148 // since waitpid and write change errno, we have to save it and restore it
149 // (Richard Stevens, Advanced programming in the Unix Environment)
150
151 bool found = false;
152 if( theKProcessController != 0 ) {
153 // iterating the list doesn't perform any system call
154 for( QValueList<KProcess*>::ConstIterator it = theKProcessController->processList.begin();
155 it != theKProcessController->processList.end();
156 ++it )
157 {
158 if( !(*it)->isRunning())
159 continue;
160 wd.pid = waitpid( (*it)->pid(), &wd.status, WNOHANG );
161 if ( wd.pid > 0 ) {
162 ::write(theKProcessController->fd[1], &wd, sizeof(wd));
163 found = true;
164 }
165 }
166 }
167 if( !found && oldChildHandlerData.sa_handler != SIG_IGN
168 && oldChildHandlerData.sa_handler != SIG_DFL )
169 oldChildHandlerData.sa_handler( arg ); // call the old handler
170 // handle the rest
171 if( theKProcessController != 0 ) {
172 static const struct waitdata dwd = { 0, 0 }; // delayed waitpid()
173 ::write(theKProcessController->fd[1], &dwd, sizeof(dwd));
174 } else {
175 int dummy;
176 while( waitpid( -1, &dummy, WNOHANG ) > 0 )
177 ;
178 }
179
180 errno = saved_errno;
181}
182
183
184
185void KProcessController::slotDoHousekeeping(int )
186{
187 unsigned int bytes_read = 0;
188 unsigned int errcnt=0;
189 // read pid and status from the pipe.
190 struct waitdata wd;
191 while ((bytes_read < sizeof(wd)) && (errcnt < 50)) {
192 int r = ::read(fd[0], ((char *)&wd) + bytes_read, sizeof(wd) - bytes_read);
193 if (r > 0) bytes_read += r;
194 else if (r < 0) errcnt++;
195 }
196 if (errcnt >= 50) {
197 fprintf(stderr,
198 "Error: Max. error count for pipe read "
199 "exceeded in KProcessController::slotDoHousekeeping\n");
200 return; // it makes no sense to continue here!
201 }
202 if (bytes_read != sizeof(wd)) {
203 fprintf(stderr,
204 "Error: Could not read info from signal handler %d <> %d!\n",
205 bytes_read, sizeof(wd));
206 return; // it makes no sense to continue here!
207 }
208 if (wd.pid==0) { // special case, see delayedChildrenCleanup()
209 delayedChildrenCleanupTimer.start( 1000, true );
210 return;
211 }
212
213 for( QValueList<KProcess*>::ConstIterator it = processList.begin();
214 it != processList.end();
215 ++it ) {
216 KProcess* proc = *it;
217 if (proc->pid() == wd.pid) {
218 // process has exited, so do emit the respective events
219 if (proc->run_mode == KProcess::Block) {
220 // If the reads are done blocking then set the status in proc
221 // but do nothing else because KProcess will perform the other
222 // actions of processHasExited.
223 proc->status = wd.status;
224 proc->runs = false;
225 } else {
226 proc->processHasExited(wd.status);
227 }
228 return;
229 }
230 }
231}
232
233// this is needed e.g. for popen(), which calls waitpid() checking
234// for its forked child, if we did waitpid() directly in the SIGCHLD
235// handler, popen()'s waitpid() call would fail
236void KProcessController::delayedChildrenCleanup()
237{
238 struct waitdata wd;
239 while(( wd.pid = waitpid( -1, &wd.status, WNOHANG ) ) > 0 ) {
240 for( QValueList<KProcess*>::ConstIterator it = processList.begin();
241 it != processList.end();
242 ++it )
243 {
244 if( !(*it)->isRunning() || (*it)->pid() != wd.pid )
245 continue;
246 // it's KProcess, handle it
247 ::write(fd[1], &wd, sizeof(wd));
248 break;
249 }
250 }
251}
252
253KProcessController::~KProcessController()
254{
255 assert( theKProcessController == this );
256 resetHandlers();
257
258 notifier->setEnabled(false);
259
260 close(fd[0]);
261 close(fd[1]);
262
263 delete notifier;
264 theKProcessController = 0;
265}
266
267//#include "kprocctrl.moc"
diff --git a/noncore/settings/networksettings/kprocctrl.h b/noncore/settings/networksettings/kprocctrl.h
deleted file mode 100644
index ac82b9d..0000000
--- a/noncore/settings/networksettings/kprocctrl.h
+++ b/dev/null
@@ -1,120 +0,0 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 1997 Christian Czezakte (e9025461@student.tuwien.ac.at)
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA.
18*/
19//
20// KPROCESSCONTROLLER -- A helper class for KProcess
21//
22// version 0.3.1, Jan 8th 1997
23//
24// (C) Christian Czezatke
25// e9025461@student.tuwien.ac.at
26//
27
28#ifndef __KPROCCTRL_H__
29#define __KPROCCTRL_H__
30
31#include <qvaluelist.h>
32#include <qtimer.h>
33
34#include "kprocess.h"
35
36class KProcessControllerPrivate;
37class QSocketNotifier;
38
39/**
40 * @short Used internally by @ref KProcess
41 * @internal
42 * @author Christian Czezakte <e9025461@student.tuwien.ac.at>
43 *
44 * A class for internal use by KProcess only. -- Exactly one instance
45 * of this class is generated by the first instance of KProcess that is
46 * created (a pointer to it gets stored in @ref theKProcessController ).
47 *
48 * This class takes care of the actual (UN*X) signal handling.
49*/
50class KProcessController : public QObject
51{
52 Q_OBJECT
53
54public:
55 KProcessController();
56 ~KProcessController();
57 //CC: WARNING! Destructor Not virtual (but you don't derive classes from this anyhow...)
58
59public:
60
61 /**
62 * Only a single instance of this class is allowed at a time,
63 * and this static variable is used to track the one instance.
64 */
65 static KProcessController *theKProcessController;
66
67 /**
68 * Automatically called upon SIGCHLD.
69 *
70 * Normally you do not need to do anything with this function but
71 * if your application needs to disable SIGCHLD for some time for
72 * reasons beyond your control, you should call this function afterwards
73 * to make sure that no SIGCHLDs where missed.
74 */
75 static void theSigCHLDHandler(int signal);
76 // handler for sigchld
77
78 /**
79 * @internal
80 */
81 static void setupHandlers();
82 /**
83 * @internal
84 */
85 static void resetHandlers();
86 /**
87 * @internal
88 */
89 void addKProcess( KProcess* );
90 /**
91 * @internal
92 */
93 void removeKProcess( KProcess* );
94 public slots:
95 /**
96 * @internal
97 */
98 void slotDoHousekeeping(int socket);
99
100 private slots:
101 void delayedChildrenCleanup();
102private:
103 int fd[2];
104 QSocketNotifier *notifier;
105 static struct sigaction oldChildHandlerData;
106 static bool handlerSet;
107 QValueList<KProcess*> processList;
108 QTimer delayedChildrenCleanupTimer;
109
110 // Disallow assignment and copy-construction
111 KProcessController( const KProcessController& );
112 KProcessController& operator= ( const KProcessController& );
113
114 KProcessControllerPrivate *d;
115};
116
117
118
119#endif
120
diff --git a/noncore/settings/networksettings/kprocess.cpp b/noncore/settings/networksettings/kprocess.cpp
deleted file mode 100644
index 193ec9b..0000000
--- a/noncore/settings/networksettings/kprocess.cpp
+++ b/dev/null
@@ -1,919 +0,0 @@
1/*
2
3 $Id$
4
5 This file is part of the KDE libraries
6 Copyright (C) 1997 Christian Czezatke (e9025461@student.tuwien.ac.at)
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
17
18 You should have received a copy of the GNU Library General Public License
19 along with this library; see the file COPYING.LIB. If not, write to
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.
22*/
23
24
25//
26// KPROCESS -- A class for handling child processes in KDE without
27// having to take care of Un*x specific implementation details
28//
29// version 0.3.1, Jan 8th 1998
30//
31// (C) Christian Czezatke
32// e9025461@student.tuwien.ac.at
33//
34// Changes:
35//
36// March 2nd, 1998: Changed parameter list for KShellProcess:
37// Arguments are now placed in a single string so that
38// <shell> -c <commandstring> is passed to the shell
39// to make the use of "operator<<" consistent with KProcess
40
41#include "kprocess.h"
42#define _MAY_INCLUDE_KPROCESSCONTROLLER_
43#include "kprocctrl.h"
44
45//#include <config.h>
46
47#include <qglobal.h>
48#include <qmap.h>
49#include <qfile.h>
50#include <qsocketnotifier.h>
51#include <qregexp.h>
52
53#include <sys/time.h>
54#include <sys/types.h>
55#include <sys/stat.h>
56#include <sys/socket.h>
57
58#include <errno.h>
59#include <fcntl.h>
60#include <stdlib.h>
61#include <signal.h>
62#include <stdio.h>
63#include <string.h>
64#include <unistd.h>
65#ifdef HAVE_SYS_SELECT_H
66#include <sys/select.h>
67#endif
68#ifdef HAVE_INITGROUPS
69#include <grp.h>
70#endif
71#include <pwd.h>
72
73#include <qapplication.h>
74//#include <kdebug.h>
75
76/////////////////////////////
77// public member functions //
78/////////////////////////////
79
80class KProcessPrivate {
81public:
82 KProcessPrivate() : useShell(false) { }
83
84 bool useShell;
85 QMap<QString,QString> env;
86 QString wd;
87 QCString shell;
88};
89
90#define Q_CHECK_PTR(a)
91
92KProcess::KProcess()
93 : QObject(),
94 run_mode(NotifyOnExit),
95 runs(false),
96 pid_(0),
97 status(0),
98 keepPrivs(false),
99 innot(0),
100 outnot(0),
101 errnot(0),
102 communication(NoCommunication),
103 input_data(0),
104 input_sent(0),
105 input_total(0),
106 d(0)
107{
108 if (0 == KProcessController::theKProcessController) {
109 (void) new KProcessController();
110 Q_CHECK_PTR(KProcessController::theKProcessController);
111 }
112
113 KProcessController::theKProcessController->addKProcess(this);
114 out[0] = out[1] = -1;
115 in[0] = in[1] = -1;
116 err[0] = err[1] = -1;
117}
118
119void
120KProcess::setEnvironment(const QString &name, const QString &value)
121{
122 if (!d)
123 d = new KProcessPrivate;
124 d->env.insert(name, value);
125}
126
127void
128KProcess::setWorkingDirectory(const QString &dir)
129{
130 if (!d)
131 d = new KProcessPrivate;
132 d->wd = dir;
133}
134
135void
136KProcess::setupEnvironment()
137{
138 if (d)
139 {
140 QMap<QString,QString>::Iterator it;
141 for(it = d->env.begin(); it != d->env.end(); ++it)
142 setenv(QFile::encodeName(it.key()).data(),
143 QFile::encodeName(it.data()).data(), 1);
144 if (!d->wd.isEmpty())
145 chdir(QFile::encodeName(d->wd).data());
146 }
147}
148
149void
150KProcess::setRunPrivileged(bool keepPrivileges)
151{
152 keepPrivs = keepPrivileges;
153}
154
155bool
156KProcess::runPrivileged() const
157{
158 return keepPrivs;
159}
160
161
162KProcess::~KProcess()
163{
164 // destroying the KProcess instance sends a SIGKILL to the
165 // child process (if it is running) after removing it from the
166 // list of valid processes (if the process is not started as
167 // "DontCare")
168
169 KProcessController::theKProcessController->removeKProcess(this);
170 // this must happen before we kill the child
171 // TODO: block the signal while removing the current process from the process list
172
173 if (runs && (run_mode != DontCare))
174 kill(SIGKILL);
175
176 // Clean up open fd's and socket notifiers.
177 closeStdin();
178 closeStdout();
179 closeStderr();
180
181 // TODO: restore SIGCHLD and SIGPIPE handler if this is the last KProcess
182 delete d;
183}
184
185void KProcess::detach()
186{
187 KProcessController::theKProcessController->removeKProcess(this);
188
189 runs = false;
190 pid_ = 0;
191
192 // Clean up open fd's and socket notifiers.
193 closeStdin();
194 closeStdout();
195 closeStderr();
196}
197
198bool KProcess::setExecutable(const QString& proc)
199{
200 if (runs) return false;
201
202 if (proc.isEmpty()) return false;
203
204 if (!arguments.isEmpty())
205 arguments.remove(arguments.begin());
206 arguments.prepend(QFile::encodeName(proc));
207
208 return true;
209}
210
211KProcess &KProcess::operator<<(const QStringList& args)
212{
213 QStringList::ConstIterator it = args.begin();
214 for ( ; it != args.end() ; ++it )
215 arguments.append(QFile::encodeName(*it));
216 return *this;
217}
218
219KProcess &KProcess::operator<<(const QCString& arg)
220{
221 return operator<< (arg.data());
222}
223
224KProcess &KProcess::operator<<(const char* arg)
225{
226 arguments.append(arg);
227 return *this;
228}
229
230KProcess &KProcess::operator<<(const QString& arg)
231{
232 arguments.append(QFile::encodeName(arg));
233 return *this;
234}
235
236void KProcess::clearArguments()
237{
238 arguments.clear();
239}
240
241bool KProcess::start(RunMode runmode, Communication comm)
242{
243 uint i;
244 uint n = arguments.count();
245 char **arglist;
246
247 if (runs || (0 == n)) {
248 return false; // cannot start a process that is already running
249 // or if no executable has been assigned
250 }
251 run_mode = runmode;
252 status = 0;
253
254 QCString shellCmd;
255 if (d && d->useShell)
256 {
257 if (d->shell.isEmpty())
258 {
259 //kdDebug() << "Could not find a valid shell\n" << endl;
260 return false;
261 }
262
263 arglist = static_cast<char **>(malloc( (4)*sizeof(char *)));
264 for (i=0; i < n; i++) {
265 shellCmd += arguments[i];
266 shellCmd += " "; // CC: to separate the arguments
267 }
268
269 arglist[0] = d->shell.data();
270 arglist[1] = (char *) "-c";
271 arglist[2] = shellCmd.data();
272 arglist[3] = 0;
273 }
274 else
275 {
276 arglist = static_cast<char **>(malloc( (n+1)*sizeof(char *)));
277 for (i=0; i < n; i++)
278 arglist[i] = arguments[i].data();
279 arglist[n]= 0;
280 }
281
282 setupCommunication(comm);
283 //)
284 //kdDebug() << "Could not setup Communication!\n";
285
286 // We do this in the parent because if we do it in the child process
287 // gdb gets confused when the application runs from gdb.
288 uid_t uid = getuid();
289 gid_t gid = getgid();
290#ifdef HAVE_INITGROUPS
291 struct passwd *pw = getpwuid(uid);
292#endif
293
294 int fd[2];
295 if (0 > pipe(fd))
296 {
297 fd[0] = fd[1] = 0; // Pipe failed.. continue
298 }
299
300 runs = true;
301
302 QApplication::flushX();
303
304 // WABA: Note that we use fork() and not vfork() because
305 // vfork() has unclear semantics and is not standardized.
306 pid_ = fork();
307
308 if (0 == pid_) {
309 if (fd[0])
310 close(fd[0]);
311 if (!runPrivileged())
312 {
313 setgid(gid);
314#if defined( HAVE_INITGROUPS)
315 if(pw)
316 initgroups(pw->pw_name, pw->pw_gid);
317#endif
318 setuid(uid);
319 }
320 // The child process
321 commSetupDoneC();
322 //)
323 //kdDebug() << "Could not finish comm setup in child!" << endl;
324
325 setupEnvironment();
326
327 // Matthias
328 if (run_mode == DontCare)
329 setpgid(0,0);
330 // restore default SIGPIPE handler (Harri)
331 struct sigaction act;
332 sigemptyset(&(act.sa_mask));
333 sigaddset(&(act.sa_mask), SIGPIPE);
334 act.sa_handler = SIG_DFL;
335 act.sa_flags = 0;
336 sigaction(SIGPIPE, &act, 0L);
337
338 // We set the close on exec flag.
339 // Closing of fd[1] indicates that the execvp succeeded!
340 if (fd[1])
341 fcntl(fd[1], F_SETFD, FD_CLOEXEC);
342 execvp(arglist[0], arglist);
343 char resultByte = 1;
344 if (fd[1])
345 write(fd[1], &resultByte, 1);
346 _exit(-1);
347 } else if (-1 == pid_) {
348 // forking failed
349
350 runs = false;
351 free(arglist);
352 return false;
353 } else {
354 if (fd[1])
355 close(fd[1]);
356 // the parent continues here
357
358 // Discard any data for stdin that might still be there
359 input_data = 0;
360
361 // Check whether client could be started.
362 if (fd[0]) for(;;)
363 {
364 char resultByte;
365 int n = ::read(fd[0], &resultByte, 1);
366 if (n == 1)
367 {
368 // Error
369 runs = false;
370 close(fd[0]);
371 free(arglist);
372 pid_ = 0;
373 return false;
374 }
375 if (n == -1)
376 {
377 if ((errno == ECHILD) || (errno == EINTR))
378 continue; // Ignore
379 }
380 break; // success
381 }
382 if (fd[0])
383 close(fd[0]);
384
385 if (!commSetupDoneP()){} // finish communication socket setup for the parent
386 //kdDebug() << "Could not finish comm setup in parent!" << endl;
387
388 if (run_mode == Block) {
389 commClose();
390
391 // The SIGCHLD handler of the process controller will catch
392 // the exit and set the status
393 while(runs)
394 {
395 KProcessController::theKProcessController->
396 slotDoHousekeeping(0);
397 }
398 runs = FALSE;
399 emit processExited(this);
400 }
401 }
402 free(arglist);
403 return true;
404}
405
406
407
408bool KProcess::kill(int signo)
409{
410 bool rv=false;
411
412 if (0 != pid_)
413 rv= (-1 != ::kill(pid_, signo));
414 // probably store errno somewhere...
415 return rv;
416}
417
418
419
420bool KProcess::isRunning() const
421{
422 return runs;
423}
424
425
426
427pid_t KProcess::pid() const
428{
429 return pid_;
430}
431
432
433
434bool KProcess::normalExit() const
435{
436 int _status = status;
437 return (pid_ != 0) && (!runs) && (WIFEXITED((_status)));
438}
439
440
441
442int KProcess::exitStatus() const
443{
444 int _status = status;
445 return WEXITSTATUS((_status));
446}
447
448
449
450bool KProcess::writeStdin(const char *buffer, int buflen)
451{
452 bool rv;
453
454 // if there is still data pending, writing new data
455 // to stdout is not allowed (since it could also confuse
456 // kprocess...
457 if (0 != input_data)
458 return false;
459
460 if (runs && (communication & Stdin)) {
461 input_data = buffer;
462 input_sent = 0;
463 input_total = buflen;
464 slotSendData(0);
465 innot->setEnabled(true);
466 rv = true;
467 } else
468 rv = false;
469 return rv;
470}
471
472void KProcess::suspend()
473{
474 if ((communication & Stdout) && outnot)
475 outnot->setEnabled(false);
476}
477
478void KProcess::resume()
479{
480 if ((communication & Stdout) && outnot)
481 outnot->setEnabled(true);
482}
483
484bool KProcess::closeStdin()
485{
486 bool rv;
487
488 if (communication & Stdin) {
489 communication = (Communication) (communication & ~Stdin);
490 delete innot;
491 innot = 0;
492 close(in[1]);
493 rv = true;
494 } else
495 rv = false;
496 return rv;
497}
498
499bool KProcess::closeStdout()
500{
501 bool rv;
502
503 if (communication & Stdout) {
504 communication = (Communication) (communication & ~Stdout);
505 delete outnot;
506 outnot = 0;
507 close(out[0]);
508 rv = true;
509 } else
510 rv = false;
511 return rv;
512}
513
514bool KProcess::closeStderr()
515{
516 bool rv;
517
518 if (communication & Stderr) {
519 communication = static_cast<Communication>(communication & ~Stderr);
520 delete errnot;
521 errnot = 0;
522 close(err[0]);
523 rv = true;
524 } else
525 rv = false;
526 return rv;
527}
528
529
530/////////////////////////////
531// protected slots //
532/////////////////////////////
533
534
535
536void KProcess::slotChildOutput(int fdno)
537{
538 if (!childOutput(fdno))
539 closeStdout();
540}
541
542
543void KProcess::slotChildError(int fdno)
544{
545 if (!childError(fdno))
546 closeStderr();
547}
548
549
550void KProcess::slotSendData(int)
551{
552 if (input_sent == input_total) {
553 innot->setEnabled(false);
554 input_data = 0;
555 emit wroteStdin(this);
556 } else
557 input_sent += ::write(in[1], input_data+input_sent, input_total-input_sent);
558}
559
560
561
562//////////////////////////////
563// private member functions //
564//////////////////////////////
565
566
567
568void KProcess::processHasExited(int state)
569{
570 if (runs)
571 {
572 runs = false;
573 status = state;
574
575 commClose(); // cleanup communication sockets
576
577 // also emit a signal if the process was run Blocking
578 if (DontCare != run_mode)
579 {
580 emit processExited(this);
581 }
582 }
583}
584
585
586
587int KProcess::childOutput(int fdno)
588{
589 if (communication & NoRead) {
590 int len = -1;
591 emit receivedStdout(fdno, len);
592 errno = 0; // Make sure errno doesn't read "EAGAIN"
593 return len;
594 }
595 else
596 {
597 char buffer[1024];
598 int len;
599
600 len = ::read(fdno, buffer, 1024);
601
602 if ( 0 < len) {
603 emit receivedStdout(this, buffer, len);
604 }
605 return len;
606 }
607}
608
609
610
611int KProcess::childError(int fdno)
612{
613 char buffer[1024];
614 int len;
615
616 len = ::read(fdno, buffer, 1024);
617
618 if ( 0 < len)
619 emit receivedStderr(this, buffer, len);
620 return len;
621}
622
623
624
625int KProcess::setupCommunication(Communication comm)
626{
627 int ok;
628
629 communication = comm;
630
631 ok = 1;
632 if (comm & Stdin)
633 ok &= socketpair(AF_UNIX, SOCK_STREAM, 0, in) >= 0;
634
635 if (comm & Stdout)
636 ok &= socketpair(AF_UNIX, SOCK_STREAM, 0, out) >= 0;
637
638 if (comm & Stderr)
639 ok &= socketpair(AF_UNIX, SOCK_STREAM, 0, err) >= 0;
640
641 return ok;
642}
643
644
645
646int KProcess::commSetupDoneP()
647{
648 int ok = 1;
649
650 if (communication != NoCommunication) {
651 if (communication & Stdin)
652 close(in[0]);
653 if (communication & Stdout)
654 close(out[1]);
655 if (communication & Stderr)
656 close(err[1]);
657
658 // Don't create socket notifiers and set the sockets non-blocking if
659 // blocking is requested.
660 if (run_mode == Block) return ok;
661
662 if (communication & Stdin) {
663// ok &= (-1 != fcntl(in[1], F_SETFL, O_NONBLOCK));
664 innot = new QSocketNotifier(in[1], QSocketNotifier::Write, this);
665 Q_CHECK_PTR(innot);
666 innot->setEnabled(false); // will be enabled when data has to be sent
667 QObject::connect(innot, SIGNAL(activated(int)),
668 this, SLOT(slotSendData(int)));
669 }
670
671 if (communication & Stdout) {
672// ok &= (-1 != fcntl(out[0], F_SETFL, O_NONBLOCK));
673 outnot = new QSocketNotifier(out[0], QSocketNotifier::Read, this);
674 Q_CHECK_PTR(outnot);
675 QObject::connect(outnot, SIGNAL(activated(int)),
676 this, SLOT(slotChildOutput(int)));
677 if (communication & NoRead)
678 suspend();
679 }
680
681 if (communication & Stderr) {
682// ok &= (-1 != fcntl(err[0], F_SETFL, O_NONBLOCK));
683 errnot = new QSocketNotifier(err[0], QSocketNotifier::Read, this );
684 Q_CHECK_PTR(errnot);
685 QObject::connect(errnot, SIGNAL(activated(int)),
686 this, SLOT(slotChildError(int)));
687 }
688 }
689 return ok;
690}
691
692
693
694int KProcess::commSetupDoneC()
695{
696 int ok = 1;
697 struct linger so;
698 memset(&so, 0, sizeof(so));
699
700 if (communication & Stdin)
701 close(in[1]);
702 if (communication & Stdout)
703 close(out[0]);
704 if (communication & Stderr)
705 close(err[0]);
706
707 if (communication & Stdin)
708 ok &= dup2(in[0], STDIN_FILENO) != -1;
709 else {
710 int null_fd = open( "/dev/null", O_RDONLY );
711 ok &= dup2( null_fd, STDIN_FILENO ) != -1;
712 close( null_fd );
713 }
714 if (communication & Stdout) {
715 ok &= dup2(out[1], STDOUT_FILENO) != -1;
716 ok &= !setsockopt(out[1], SOL_SOCKET, SO_LINGER, (char*)&so, sizeof(so));
717 }
718 else {
719 int null_fd = open( "/dev/null", O_WRONLY );
720 ok &= dup2( null_fd, STDOUT_FILENO ) != -1;
721 close( null_fd );
722 }
723 if (communication & Stderr) {
724 ok &= dup2(err[1], STDERR_FILENO) != -1;
725 ok &= !setsockopt(err[1], SOL_SOCKET, SO_LINGER, reinterpret_cast<char *>(&so), sizeof(so));
726 }
727 else {
728 int null_fd = open( "/dev/null", O_WRONLY );
729 ok &= dup2( null_fd, STDERR_FILENO ) != -1;
730 close( null_fd );
731 }
732 return ok;
733}
734
735
736
737void KProcess::commClose()
738{
739 if (NoCommunication != communication) {
740 bool b_in = (communication & Stdin);
741 bool b_out = (communication & Stdout);
742 bool b_err = (communication & Stderr);
743 if (b_in)
744 delete innot;
745
746 if (b_out || b_err) {
747 // If both channels are being read we need to make sure that one socket buffer
748 // doesn't fill up whilst we are waiting for data on the other (causing a deadlock).
749 // Hence we need to use select.
750
751 // Once one or other of the channels has reached EOF (or given an error) go back
752 // to the usual mechanism.
753
754 int fds_ready = 1;
755 fd_set rfds;
756
757 int max_fd = 0;
758 if (b_out) {
759 fcntl(out[0], F_SETFL, O_NONBLOCK);
760 if (out[0] > max_fd)
761 max_fd = out[0];
762 delete outnot;
763 outnot = 0;
764 }
765 if (b_err) {
766 fcntl(err[0], F_SETFL, O_NONBLOCK);
767 if (err[0] > max_fd)
768 max_fd = err[0];
769 delete errnot;
770 errnot = 0;
771 }
772
773
774 while (b_out || b_err) {
775 // * If the process is still running we block until we
776 // receive data. (p_timeout = 0, no timeout)
777 // * If the process has already exited, we only check
778 // the available data, we don't wait for more.
779 // (p_timeout = &timeout, timeout immediately)
780 struct timeval timeout;
781 timeout.tv_sec = 0;
782 timeout.tv_usec = 0;
783 struct timeval *p_timeout = runs ? 0 : &timeout;
784
785 FD_ZERO(&rfds);
786 if (b_out)
787 FD_SET(out[0], &rfds);
788
789 if (b_err)
790 FD_SET(err[0], &rfds);
791
792 fds_ready = select(max_fd+1, &rfds, 0, 0, p_timeout);
793 if (fds_ready <= 0) break;
794
795 if (b_out && FD_ISSET(out[0], &rfds)) {
796 int ret = 1;
797 while (ret > 0) ret = childOutput(out[0]);
798 if ((ret == -1 && errno != EAGAIN) || ret == 0)
799 b_out = false;
800 }
801
802 if (b_err && FD_ISSET(err[0], &rfds)) {
803 int ret = 1;
804 while (ret > 0) ret = childError(err[0]);
805 if ((ret == -1 && errno != EAGAIN) || ret == 0)
806 b_err = false;
807 }
808 }
809 }
810
811 if (b_in) {
812 communication = (Communication) (communication & ~Stdin);
813 close(in[1]);
814 }
815 if (b_out) {
816 communication = (Communication) (communication & ~Stdout);
817 close(out[0]);
818 }
819 if (b_err) {
820 communication = (Communication) (communication & ~Stderr);
821 close(err[0]);
822 }
823 }
824}
825
826void KProcess::setUseShell(bool useShell, const char *shell)
827{
828 if (!d)
829 d = new KProcessPrivate;
830 d->useShell = useShell;
831 d->shell = shell;
832 if (d->shell.isEmpty())
833 d->shell = searchShell();
834}
835
836QString KProcess::quote(const QString &arg)
837{
838 QString res = arg;
839 res.replace(QRegExp(QString::fromLatin1("\'")),
840 QString::fromLatin1("'\"'\"'"));
841 res.prepend('\'');
842 res.append('\'');
843 return res;
844}
845
846QCString KProcess::searchShell()
847{
848 QCString tmpShell = QCString(getenv("SHELL")).stripWhiteSpace();
849 if (!isExecutable(tmpShell))
850 {
851 tmpShell = "/bin/sh";
852 }
853
854 return tmpShell;
855}
856
857bool KProcess::isExecutable(const QCString &filename)
858{
859 struct stat fileinfo;
860
861 if (filename.isEmpty()) return false;
862
863 // CC: we've got a valid filename, now let's see whether we can execute that file
864
865 if (-1 == stat(filename.data(), &fileinfo)) return false;
866 // CC: return false if the file does not exist
867
868 // CC: anyway, we cannot execute directories, block/character devices, fifos or sockets
869 if ( (S_ISDIR(fileinfo.st_mode)) ||
870 (S_ISCHR(fileinfo.st_mode)) ||
871 (S_ISBLK(fileinfo.st_mode)) ||
872#ifdef S_ISSOCK
873 // CC: SYSVR4 systems don't have that macro
874 (S_ISSOCK(fileinfo.st_mode)) ||
875#endif
876 (S_ISFIFO(fileinfo.st_mode)) ||
877 (S_ISDIR(fileinfo.st_mode)) ) {
878 return false;
879 }
880
881 // CC: now check for permission to execute the file
882 if (access(filename.data(), X_OK) != 0) return false;
883
884 // CC: we've passed all the tests...
885 return true;
886}
887
888void KProcess::virtual_hook( int, void* )
889{ /*BASE::virtual_hook( id, data );*/ }
890
891
892///////////////////////////
893// CC: Class KShellProcess
894///////////////////////////
895
896KShellProcess::KShellProcess(const char *shellname):
897 KProcess()
898{
899 setUseShell(true, shellname);
900}
901
902
903KShellProcess::~KShellProcess() {
904}
905
906QString KShellProcess::quote(const QString &arg)
907{
908 return KProcess::quote(arg);
909}
910
911bool KShellProcess::start(RunMode runmode, Communication comm)
912{
913 return KProcess::start(runmode, comm);
914}
915
916void KShellProcess::virtual_hook( int id, void* data )
917{ KProcess::virtual_hook( id, data ); }
918
919//#include "kprocess.moc"
diff --git a/noncore/settings/networksettings/kprocess.h b/noncore/settings/networksettings/kprocess.h
deleted file mode 100644
index e70f7e7..0000000
--- a/noncore/settings/networksettings/kprocess.h
+++ b/dev/null
@@ -1,804 +0,0 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 1997 Christian Czezakte (e9025461@student.tuwien.ac.at)
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA.
18*/
19//
20// KPROCESS -- A class for handling child processes in KDE without
21// having to take care of Un*x specific implementation details
22//
23// version 0.3.1, Jan 8th 1998
24//
25// (C) Christian Czezatke
26// e9025461@student.tuwien.ac.at
27//
28
29#ifndef __kprocess_h__
30#define __kprocess_h__
31
32#include <sys/types.h> // for pid_t
33#include <sys/wait.h>
34#include <signal.h>
35#include <unistd.h>
36#include <qvaluelist.h>
37#include <qcstring.h>
38#include <qobject.h>
39
40class QSocketNotifier;
41class KProcessPrivate;
42
43/**
44 * Child process invocation, monitoring and control.
45 *
46 * @sect General usage and features
47 *
48 *This class allows a KDE application to start child processes without having
49 *to worry about UN*X signal handling issues and zombie process reaping.
50 *
51 *@see KProcIO
52 *
53 *Basically, this class distinguishes three different ways of running
54 *child processes:
55 *
56 *@li KProcess::DontCare -- The child process is invoked and both the child
57 *process and the parent process continue concurrently.
58 *
59 *Starting a DontCare child process means that the application is
60 *not interested in any notification to determine whether the
61 *child process has already exited or not.
62 *
63 *@li KProcess::NotifyOnExit -- The child process is invoked and both the
64 *child and the parent process run concurrently.
65 *
66 *When the child process exits, the KProcess instance
67 *corresponding to it emits the Qt signal @ref processExited().
68 *
69 *Since this signal is @em not emitted from within a UN*X
70 *signal handler, arbitrary function calls can be made.
71 *
72 *Be aware: When the KProcess objects gets destructed, the child
73 *process will be killed if it is still running!
74 *This means in particular, that you cannot use a KProcess on the stack
75 *with KProcess::NotifyOnExit.
76 *
77 *@li KProcess::Block -- The child process starts and the parent process
78 *is suspended until the child process exits. (@em Really not recommended
79 *for programs with a GUI.)
80 *
81 *KProcess also provides several functions for determining the exit status
82 *and the pid of the child process it represents.
83 *
84 *Furthermore it is possible to supply command-line arguments to the process
85 *in a clean fashion (no null -- terminated stringlists and such...)
86 *
87 *A small usage example:
88 *<pre>
89 *KProcess *proc = new KProcess;
90 *
91 **proc << "my_executable";
92 **proc << "These" << "are" << "the" << "command" << "line" << "args";
93 *QApplication::connect(proc, SIGNAL(processExited(KProcess *)),
94 * pointer_to_my_object, SLOT(my_objects_slot(KProcess *)));
95 *proc->start();
96 *</pre>
97 *
98 *This will start "my_executable" with the commandline arguments "These"...
99 *
100 *When the child process exits, the respective Qt signal will be emitted.
101 *
102 *@sect Communication with the child process
103 *
104 *KProcess supports communication with the child process through
105 *stdin/stdout/stderr.
106 *
107 *The following functions are provided for getting data from the child
108 *process or sending data to the child's stdin (For more information,
109 *have a look at the documentation of each function):
110 *
111 *@li bool @ref writeStdin(char *buffer, int buflen);
112 *@li -- Transmit data to the child process's stdin.
113 *
114 *@li bool @ref closeStdin();
115 *@li -- Closes the child process's stdin (which causes it to see an feof(stdin)).
116 *Returns false if you try to close stdin for a process that has been started
117 *without a communication channel to stdin.
118 *
119 *@li bool @ref closeStdout();
120 *@li -- Closes the child process's stdout.
121 *Returns false if you try to close stdout for a process that has been started
122 *without a communication channel to stdout.
123 *
124 *@li bool @ref closeStderr();
125 *@li -- Closes the child process's stderr.
126 *Returns false if you try to close stderr for a process that has been started
127 *without a communication channel to stderr.
128 *
129 *
130 *@sect QT signals:
131 *
132 *@li void @ref receivedStdout(KProcess *proc, char *buffer, int buflen);
133 *@li void @ref receivedStderr(KProcess *proc, char *buffer, int buflen);
134 *@li -- Indicates that new data has arrived from either the
135 *child process's stdout or stderr.
136 *
137 *@li void @ref wroteStdin(KProcess *proc);
138 *@li -- Indicates that all data that has been sent to the child process
139 *by a prior call to @ref writeStdin() has actually been transmitted to the
140 *client .
141 *
142 *@author Christian Czezakte e9025461@student.tuwien.ac.at
143 *
144 *
145 **/
146class KProcess : public QObject
147{
148 Q_OBJECT
149
150public:
151
152 /**
153 * Modes in which the communication channel can be opened.
154 *
155 * If communication for more than one channel is required,
156 * the values have to be or'ed together, for example to get
157 * communication with stdout as well as with stdin, you would
158 * specify @p Stdin @p | @p Stdout
159 *
160 * If @p NoRead is specified in conjunction with @p Stdout,
161 * no data is actually read from @p Stdout but only
162 * the signal @ref childOutput(int fd) is emitted.
163 */
164 enum Communication { NoCommunication = 0, Stdin = 1, Stdout = 2, Stderr = 4,
165 AllOutput = 6, All = 7,
166 NoRead };
167
168 /**
169 * Run-modes for a child process.
170 */
171 enum RunMode {
172 /**
173 * The application does not receive notifications from the subprocess when
174 * it is finished or aborted.
175 */
176 DontCare,
177 /**
178 * The application is notified when the subprocess dies.
179 */
180 NotifyOnExit,
181 /**
182 * The application is suspended until the started process is finished.
183 */
184 Block };
185
186 /**
187 * Constructor
188 */
189 KProcess();
190
191 /**
192 *Destructor:
193 *
194 * If the process is running when the destructor for this class
195 * is called, the child process is killed with a SIGKILL, but
196 * only if the run mode is not of type @p DontCare.
197 * Processes started as @p DontCare keep running anyway.
198 */
199 virtual ~KProcess();
200
201 /**
202 @deprecated
203
204 The use of this function is now deprecated. -- Please use the
205 "operator<<" instead of "setExecutable".
206
207 Sets the executable to be started with this KProcess object.
208 Returns false if the process is currently running (in that
209 case the executable remains unchanged.)
210
211 @see operator<<
212
213 */
214 bool setExecutable(const QString& proc);
215
216
217 /**
218 * Sets the executable and the command line argument list for this process.
219 *
220 * For example, doing an "ls -l /usr/local/bin" can be achieved by:
221 * <pre>
222 * KProcess p;
223 * ...
224 * p << "ls" << "-l" << "/usr/local/bin"
225 * </pre>
226 *
227 **/
228 KProcess &operator<<(const QString& arg);
229 /**
230 * Similar to previous method, takes a char *, supposed to be in locale 8 bit already.
231 */
232 KProcess &operator<<(const char * arg);
233 /**
234 * Similar to previous method, takes a QCString, supposed to be in locale 8 bit already.
235 */
236 KProcess &operator<<(const QCString & arg);
237
238 /**
239 * Sets the executable and the command line argument list for this process,
240 * in a single method call, or add a list of arguments.
241 **/
242 KProcess &operator<<(const QStringList& args);
243
244 /**
245 * Clear a command line argument list that has been set by using
246 * the "operator<<".
247 */
248 void clearArguments();
249
250 /**
251 * Starts the process.
252 * For a detailed description of the
253 * various run modes and communication semantics, have a look at the
254 * general description of the KProcess class.
255 *
256 * The following problems could cause this function to
257 * return false:
258 *
259 * @li The process is already running.
260 * @li The command line argument list is empty.
261 * @li The starting of the process failed (could not fork).
262 * @li The executable was not found.
263 *
264 * @param comm Specifies which communication links should be
265 * established to the child process (stdin/stdout/stderr). By default,
266 * no communication takes place and the respective communication
267 * signals will never get emitted.
268 *
269 * @return true on success, false on error
270 * (see above for error conditions)
271 **/
272 virtual bool start(RunMode runmode = NotifyOnExit,
273 Communication comm = NoCommunication);
274
275 /**
276 * Stop the process (by sending it a signal).
277 *
278 * @param signoThe signal to send. The default is SIGTERM.
279 * @return @p true if the signal was delivered successfully.
280 */
281 virtual bool kill(int signo = SIGTERM);
282
283 /**
284 @return @p true if the process is (still) considered to be running
285 */
286 bool isRunning() const;
287
288 /** Returns the process id of the process.
289 *
290 * If it is called after
291 * the process has exited, it returns the process id of the last
292 * child process that was created by this instance of KProcess.
293 *
294 * Calling it before any child process has been started by this
295 * KProcess instance causes pid() to return 0.
296 **/
297 pid_t pid() const;
298
299 /**
300 * Use pid().
301 * @deprecated
302 */
303 pid_t getPid() const { return pid(); }
304
305 /**
306 * Suspend processing of data from stdout of the child process.
307 */
308 void suspend();
309
310 /**
311 * Resume processing of data from stdout of the child process.
312 */
313 void resume();
314
315 /**
316 * @return @p true if the process has already finished and has exited
317 * "voluntarily", ie: it has not been killed by a signal.
318 *
319 * Note that you should check @ref KProcess::exitStatus() to determine
320 * whether the process completed its task successful or not.
321 */
322 bool normalExit() const;
323
324 /**
325 * Returns the exit status of the process.
326 *
327 * Please use
328 * @ref KProcess::normalExit() to check whether the process has exited
329 * cleanly (i.e., @ref KProcess::normalExit() returns @p true) before calling
330 * this function because if the process did not exit normally,
331 * it does not have a valid exit status.
332 */
333 int exitStatus() const;
334
335
336 /**
337 * Transmit data to the child process's stdin.
338 *
339 * KProcess::writeStdin may return false in the following cases:
340 *
341 * @li The process is not currently running.
342 *
343 * @li Communication to stdin has not been requested in the @ref start() call.
344 *
345 * @li Transmission of data to the child process by a previous call to
346 * @ref writeStdin() is still in progress.
347 *
348 * Please note that the data is sent to the client asynchronously,
349 * so when this function returns, the data might not have been
350 * processed by the child process.
351 *
352 * If all the data has been sent to the client, the signal
353 * @ref wroteStdin() will be emitted.
354 *
355 * Please note that you must not free "buffer" or call @ref writeStdin()
356 * again until either a @ref wroteStdin() signal indicates that the
357 * data has been sent or a @ref processHasExited() signal shows that
358 * the child process is no longer alive...
359 **/
360 bool writeStdin(const char *buffer, int buflen);
361
362 /**
363 * This causes the stdin file descriptor of the child process to be
364 * closed indicating an "EOF" to the child.
365 *
366 * @return @p false if no communication to the process's stdin
367 * had been specified in the call to @ref start().
368 */
369 bool closeStdin();
370
371 /**
372 * This causes the stdout file descriptor of the child process to be
373 * closed.
374 *
375 * @return @p false if no communication to the process's stdout
376 * had been specified in the call to @ref start().
377 */
378 bool closeStdout();
379
380 /**
381 * This causes the stderr file descriptor of the child process to be
382 * closed.
383 *
384 * @return @p false if no communication to the process's stderr
385 * had been specified in the call to @ref start().
386 */
387 bool closeStderr();
388
389 /**
390 * Lets you see what your arguments are for debugging.
391 */
392
393 const QValueList<QCString> &args() { return arguments; }
394
395 /**
396 * Controls whether the started process should drop any
397 * setuid/segid privileges or whether it should keep them
398 *
399 * The default is @p false : drop privileges
400 */
401 void setRunPrivileged(bool keepPrivileges);
402
403 /**
404 * Returns whether the started process will drop any
405 * setuid/segid privileges or whether it will keep them
406 */
407 bool runPrivileged() const;
408
409 /**
410 * Modifies the environment of the process to be started.
411 * This function must be called before starting the process.
412 */
413 void setEnvironment(const QString &name, const QString &value);
414
415 /**
416 * Changes the current working directory (CWD) of the process
417 * to be started.
418 * This function must be called before starting the process.
419 */
420 void setWorkingDirectory(const QString &dir);
421
422 /**
423 * Specify whether to start the command via a shell or directly.
424 * The default is to start the command directly.
425 * If @p useShell is true @p shell will be used as shell, or
426 * if shell is empty, the standard shell is used.
427 * @p quote A flag indicating whether to quote the arguments.
428 *
429 * When using a shell, the caller should make sure that all filenames etc.
430 * are properly quoted when passed as argument.
431 * @see quote()
432 */
433 void setUseShell(bool useShell, const char *shell = 0);
434
435 /**
436 * This function can be used to quote an argument string such that
437 * the shell processes it properly. This is e. g. necessary for
438 * user-provided file names which may contain spaces or quotes.
439 * It also prevents expansion of wild cards and environment variables.
440 */
441 static QString quote(const QString &arg);
442
443 /**
444 * Detaches KProcess from child process. All communication is closed.
445 * No exit notification is emitted any more for the child process.
446 * Deleting the KProcess will no longer kill the child process.
447 * Note that the current process remains the parent process of the
448 * child process.
449 */
450 void detach();
451
452
453
454signals:
455
456 /**
457 * Emitted after the process has terminated when
458 * the process was run in the @p NotifyOnExit (==default option to
459 * @ref start()) or the @ref Block mode.
460 **/
461 void processExited(KProcess *proc);
462
463
464 /**
465 * Emitted, when output from the child process has
466 * been received on stdout.
467 *
468 * To actually get
469 * these signals, the respective communication link (stdout/stderr)
470 * has to be turned on in @ref start().
471 *
472 * @param buffer The data received.
473 * @param buflen The number of bytes that are available.
474 *
475 * You should copy the information contained in @p buffer to your private
476 * data structures before returning from this slot.
477 **/
478 void receivedStdout(KProcess *proc, char *buffer, int buflen);
479
480 /**
481 * Emitted when output from the child process has
482 * been received on stdout.
483 *
484 * To actually get these signals, the respective communications link
485 * (stdout/stderr) has to be turned on in @ref start() and the
486 * @p NoRead flag should have been passed.
487 *
488 * You will need to explicitly call resume() after your call to start()
489 * to begin processing data from the child process's stdout. This is
490 * to ensure that this signal is not emitted when no one is connected
491 * to it, otherwise this signal will not be emitted.
492 *
493 * The data still has to be read from file descriptor @p fd.
494 **/
495 void receivedStdout(int fd, int &len);
496
497
498 /**
499 * Emitted, when output from the child process has
500 * been received on stderr.
501 * To actually get
502 * these signals, the respective communication link (stdout/stderr)
503 * has to be turned on in @ref start().
504 *
505 * @param buffer The data received.
506 * @param buflen The number of bytes that are available.
507 *
508 * You should copy the information contained in @p buffer to your private
509 * data structures before returning from this slot.
510 */
511 void receivedStderr(KProcess *proc, char *buffer, int buflen);
512
513 /**
514 * Emitted after all the data that has been
515 * specified by a prior call to @ref writeStdin() has actually been
516 * written to the child process.
517 **/
518 void wroteStdin(KProcess *proc);
519
520
521protected slots:
522
523 /**
524 * This slot gets activated when data from the child's stdout arrives.
525 * It usually calls "childOutput"
526 */
527 void slotChildOutput(int fdno);
528
529 /**
530 * This slot gets activated when data from the child's stderr arrives.
531 * It usually calls "childError"
532 */
533 void slotChildError(int fdno);
534 /*
535 Slot functions for capturing stdout and stderr of the child
536 */
537
538 /**
539 * Called when another bulk of data can be sent to the child's
540 * stdin. If there is no more data to be sent to stdin currently
541 * available, this function must disable the QSocketNotifier "innot".
542 */
543 void slotSendData(int dummy);
544
545protected:
546
547 /**
548 * Sets up the environment according to the data passed via
549 * setEnvironment(...)
550 */
551 void setupEnvironment();
552
553 /**
554 * The list of the process' command line arguments. The first entry
555 * in this list is the executable itself.
556 */
557 QValueList<QCString> arguments;
558 /**
559 * How to run the process (Block, NotifyOnExit, DontCare). You should
560 * not modify this data member directly from derived classes.
561 */
562 RunMode run_mode;
563 /**
564 * true if the process is currently running. You should not
565 * modify this data member directly from derived classes. For
566 * reading the value of this data member, please use "isRunning()"
567 * since "runs" will probably be made private in later versions
568 * of KProcess.
569 */
570 bool runs;
571
572 /**
573 * The PID of the currently running process (see "getPid()").
574 * You should not modify this data member in derived classes.
575 * Please use "getPid()" instead of directly accessing this
576 * member function since it will probably be made private in
577 * later versions of KProcess.
578 */
579 pid_t pid_;
580
581 /**
582 * The process' exit status as returned by "waitpid". You should not
583 * modify the value of this data member from derived classes. You should
584 * rather use @ref exitStatus than accessing this data member directly
585 * since it will probably be made private in further versions of
586 * KProcess.
587 */
588 int status;
589
590
591 /**
592 * See setRunPrivileged()
593 */
594 bool keepPrivs;
595
596 /*
597 Functions for setting up the sockets for communication.
598 setupCommunication
599 -- is called from "start" before "fork"ing.
600 commSetupDoneP
601 -- completes communication socket setup in the parent
602 commSetupDoneC
603 -- completes communication setup in the child process
604 commClose
605 -- frees all allocated communication resources in the parent
606 after the process has exited
607 */
608
609 /**
610 * This function is called from "KProcess::start" right before a "fork" takes
611 * place. According to
612 * the "comm" parameter this function has to initialize the "in", "out" and
613 * "err" data member of KProcess.
614 *
615 * This function should return 0 if setting the needed communication channels
616 * was successful.
617 *
618 * The default implementation is to create UNIX STREAM sockets for the communication,
619 * but you could overload this function and establish a TCP/IP communication for
620 * network communication, for example.
621 */
622 virtual int setupCommunication(Communication comm);
623
624 /**
625 * Called right after a (successful) fork on the parent side. This function
626 * will usually do some communications cleanup, like closing the reading end
627 * of the "stdin" communication channel.
628 *
629 * Furthermore, it must also create the QSocketNotifiers "innot", "outnot" and
630 * "errnot" and connect their Qt slots to the respective KProcess member functions.
631 *
632 * For a more detailed explanation, it is best to have a look at the default
633 * implementation of "setupCommunication" in kprocess.cpp.
634 */
635 virtual int commSetupDoneP();
636
637 /**
638 * Called right after a (successful) fork, but before an "exec" on the child
639 * process' side. It usually just closes the unused communication ends of
640 * "in", "out" and "err" (like the writing end of the "in" communication
641 * channel.
642 */
643 virtual int commSetupDoneC();
644
645
646 /**
647 * Immediately called after a process has exited. This function normally
648 * calls commClose to close all open communication channels to this
649 * process and emits the "processExited" signal (if the process was
650 * not running in the "DontCare" mode).
651 */
652 virtual void processHasExited(int state);
653
654 /**
655 * Should clean up the communication links to the child after it has
656 * exited. Should be called from "processHasExited".
657 */
658 virtual void commClose();
659
660
661 /**
662 * the socket descriptors for stdin/stdout/stderr.
663 */
664 int out[2];
665 int in[2];
666 int err[2];
667
668 /**
669 * The socket notifiers for the above socket descriptors.
670 */
671 QSocketNotifier *innot;
672 QSocketNotifier *outnot;
673 QSocketNotifier *errnot;
674
675 /**
676 * Lists the communication links that are activated for the child
677 * process. Should not be modified from derived classes.
678 */
679 Communication communication;
680
681 /**
682 * Called by "slotChildOutput" this function copies data arriving from the
683 * child process's stdout to the respective buffer and emits the signal
684 * "@ref receivedStderr".
685 */
686 int childOutput(int fdno);
687
688 /**
689 * Called by "slotChildOutput" this function copies data arriving from the
690 * child process's stdout to the respective buffer and emits the signal
691 * "@ref receivedStderr"
692 */
693 int childError(int fdno);
694
695 // information about the data that has to be sent to the child:
696
697 const char *input_data; // the buffer holding the data
698 int input_sent; // # of bytes already transmitted
699 int input_total; // total length of input_data
700
701 /**
702 * @ref KProcessController is a friend of KProcess because it has to have
703 * access to various data members.
704 */
705 friend class KProcessController;
706
707
708private:
709 /**
710 * Searches for a valid shell.
711 * Here is the algorithm used for finding an executable shell:
712 *
713 * @li Try the executable pointed to by the "SHELL" environment
714 * variable with white spaces stripped off
715 *
716 * @li If your process runs with uid != euid or gid != egid, a shell
717 * not listed in /etc/shells will not used.
718 *
719 * @li If no valid shell could be found, "/bin/sh" is used as a last resort.
720 */
721 QCString searchShell();
722
723 /**
724 * Used by @ref searchShell in order to find out whether the shell found
725 * is actually executable at all.
726 */
727 bool isExecutable(const QCString &filename);
728
729 // Disallow assignment and copy-construction
730 KProcess( const KProcess& );
731 KProcess& operator= ( const KProcess& );
732
733protected:
734 virtual void virtual_hook( int id, void* data );
735private:
736 KProcessPrivate *d;
737};
738
739class KShellProcessPrivate;
740
741/**
742* @obsolete
743*
744* This class is obsolete. Use KProcess and KProcess::setUseShell(true)
745* instead.
746*
747* @short A class derived from @ref KProcess to start child
748 * processes through a shell.
749* @author Christian Czezakte <e9025461@student.tuwien.ac.at>
750* @version $Id$
751*/
752class KShellProcess: public KProcess
753{
754 Q_OBJECT
755
756public:
757
758 /**
759 * Constructor
760 *
761 * By specifying the name of a shell (like "/bin/bash") you can override
762 * the mechanism for finding a valid shell as described in KProcess::searchShell()
763 */
764 KShellProcess(const char *shellname=0);
765
766 /**
767 * Destructor.
768 */
769 ~KShellProcess();
770
771 /**
772 * Starts up the process. -- For a detailed description
773 * have a look at the "start" member function and the detailed
774 * description of @ref KProcess .
775 */
776 virtual bool start(RunMode runmode = NotifyOnExit,
777 Communication comm = NoCommunication);
778
779 /**
780 * This function can be used to quote an argument string such that
781 * the shell processes it properly. This is e. g. necessary for
782 * user-provided file names which may contain spaces or quotes.
783 * It also prevents expansion of wild cards and environment variables.
784 */
785 static QString quote(const QString &arg);
786
787private:
788
789 QCString shell;
790
791 // Disallow assignment and copy-construction
792 KShellProcess( const KShellProcess& );
793 KShellProcess& operator= ( const KShellProcess& );
794
795protected:
796 virtual void virtual_hook( int id, void* data );
797private:
798 KShellProcessPrivate *d;
799};
800
801
802
803#endif
804
diff --git a/noncore/settings/networksettings/mainwindowimp.cpp b/noncore/settings/networksettings/mainwindowimp.cpp
index 7261c58..48ef9b3 100644
--- a/noncore/settings/networksettings/mainwindowimp.cpp
+++ b/noncore/settings/networksettings/mainwindowimp.cpp
@@ -1,537 +1,525 @@
1#include "mainwindowimp.h" 1#include "mainwindowimp.h"
2#include "addconnectionimp.h" 2#include "addconnectionimp.h"
3#include "interfaceinformationimp.h" 3#include "interfaceinformationimp.h"
4#include "interfacesetupimp.h" 4#include "interfacesetupimp.h"
5#include "interfaces.h" 5#include "interfaces.h"
6
7#include "module.h" 6#include "module.h"
8 7
9#include "kprocess.h"
10
11#include <qpushbutton.h> 8#include <qpushbutton.h>
12#include <qlistbox.h> 9#include <qlistbox.h>
13#include <qlineedit.h> 10#include <qlineedit.h>
14#include <qlistview.h> 11#include <qlistview.h>
15#include <qheader.h> 12#include <qheader.h>
16#include <qlabel.h> 13#include <qlabel.h>
17 14
18#include <qmainwindow.h> 15#include <qmainwindow.h>
19#include <qmessagebox.h> 16#include <qmessagebox.h>
20 17
21#include <qpe/config.h> 18#include <qpe/config.h>
22#include <qpe/qlibrary.h> 19#include <qpe/qlibrary.h>
23#include <qpe/resource.h> 20#include <qpe/resource.h>
24#include <qpe/qpeapplication.h> 21#include <qpe/qpeapplication.h>
25 22
26#include <qlist.h> 23#include <qlist.h>
27#include <qdir.h> 24#include <qdir.h>
28#include <qfile.h> 25#include <qfile.h>
29#include <qtextstream.h> 26#include <qtextstream.h>
30 27
31#define TEMP_ALL "/tmp/ifconfig-a" 28#include <net/if.h>
32#define TEMP_UP "/tmp/ifconfig" 29#include <sys/ioctl.h>
33 30
34#define DEFAULT_SCHEME "/var/lib/pcmcia/scheme" 31#define DEFAULT_SCHEME "/var/lib/pcmcia/scheme"
35 32
36MainWindowImp::MainWindowImp(QWidget *parent, const char *name) : MainWindow(parent, name, true), advancedUserMode(false){ 33MainWindowImp::MainWindowImp(QWidget *parent, const char *name) : MainWindow(parent, name, true), advancedUserMode(false){
37 connect(addConnectionButton, SIGNAL(clicked()), this, SLOT(addClicked())); 34 connect(addConnectionButton, SIGNAL(clicked()), this, SLOT(addClicked()));
38 connect(removeConnectionButton, SIGNAL(clicked()), this, SLOT(removeClicked())); 35 connect(removeConnectionButton, SIGNAL(clicked()), this, SLOT(removeClicked()));
39 connect(informationConnectionButton, SIGNAL(clicked()), this, SLOT(informationClicked())); 36 connect(informationConnectionButton, SIGNAL(clicked()), this, SLOT(informationClicked()));
40 connect(configureConnectionButton, SIGNAL(clicked()), this, SLOT(configureClicked())); 37 connect(configureConnectionButton, SIGNAL(clicked()), this, SLOT(configureClicked()));
41 38
42 connect(newProfileButton, SIGNAL(clicked()), this, SLOT(addProfile())); 39 connect(newProfileButton, SIGNAL(clicked()), this, SLOT(addProfile()));
43 connect(removeProfileButton, SIGNAL(clicked()), this, SLOT(removeProfile())); 40 connect(removeProfileButton, SIGNAL(clicked()), this, SLOT(removeProfile()));
44 connect(setCurrentProfileButton, SIGNAL(clicked()), this, SLOT(changeProfile())); 41 connect(setCurrentProfileButton, SIGNAL(clicked()), this, SLOT(changeProfile()));
45 42
46 connect(newProfile, SIGNAL(textChanged(const QString&)), this, SLOT(newProfileChanged(const QString&))); 43 connect(newProfile, SIGNAL(textChanged(const QString&)), this, SLOT(newProfileChanged(const QString&)));
47 // Load connections. 44 // Load connections.
48 loadModules(QPEApplication::qpeDir() + "/plugins/networksetup"); 45 loadModules(QPEApplication::qpeDir() + "/plugins/networksetup");
49 getInterfaceList(); 46 getAllInterfaces();
47
48 Interfaces i;
49 QStringList list = i.getInterfaceList();
50 QMap<QString, Interface*>::Iterator it;
51 for ( QStringList::Iterator ni = list.begin(); ni != list.end(); ++ni ) {
52 bool found = false;
53 for( it = interfaceNames.begin(); it != interfaceNames.end(); ++it ){
54 if(it.key() == (*ni))
55 found = true;
56 }
57 if(!found){
58 if(!(*ni).contains("_")){
59 Interface *i = new Interface(this, *ni, false);
60 i->setAttached(false);
61 i->setHardwareName("Disconnected");
62 interfaceNames.insert(i->getInterfaceName(), i);
63 updateInterface(i);
64 connect(i, SIGNAL(updateInterface(Interface *)), this, SLOT(updateInterface(Interface *)));
65 }
66 }
67 }
68
69 //getInterfaceList();
50 connectionList->header()->hide(); 70 connectionList->header()->hide();
51 71
52
53 Config cfg("NetworkSetup"); 72 Config cfg("NetworkSetup");
54 profiles = QStringList::split(" ", cfg.readEntry("Profiles", "All")); 73 profiles = QStringList::split(" ", cfg.readEntry("Profiles", "All"));
55 for ( QStringList::Iterator it = profiles.begin(); it != profiles.end(); ++it) 74 for ( QStringList::Iterator it = profiles.begin(); it != profiles.end(); ++it)
56 profilesList->insertItem((*it)); 75 profilesList->insertItem((*it));
57 currentProfileLabel->setText(cfg.readEntry("CurrentProfile", "All")); 76 currentProfileLabel->setText(cfg.readEntry("CurrentProfile", "All"));
58 advancedUserMode = cfg.readBoolEntry("AdvancedUserMode", false); 77 advancedUserMode = cfg.readBoolEntry("AdvancedUserMode", false);
59 scheme = cfg.readEntry("SchemeFile", DEFAULT_SCHEME); 78 scheme = cfg.readEntry("SchemeFile", DEFAULT_SCHEME);
60 79
61 QFile file(scheme); 80 QFile file(scheme);
62 if ( file.open(IO_ReadOnly) ) { // file opened successfully 81 if ( file.open(IO_ReadOnly) ) { // file opened successfully
63 QTextStream stream( &file ); // use a text stream 82 QTextStream stream( &file ); // use a text stream
64 while ( !stream.eof() ) { // until end of file... 83 while ( !stream.eof() ) { // until end of file...
65 QString line = stream.readLine(); // line of text excluding '\n' 84 QString line = stream.readLine(); // line of text excluding '\n'
66 if(line.contains("SCHEME")){ 85 if(line.contains("SCHEME")){
67 line = line.mid(7, line.length()); 86 line = line.mid(7, line.length());
68 currentProfileLabel->setText(line); 87 currentProfileLabel->setText(line);
69 break; 88 break;
70 } 89 }
71 } 90 }
72 file.close(); 91 file.close();
73 } 92 }
74} 93}
75 94
76/** 95/**
77 * Deconstructor. Save profiles. Delete loaded libraries. 96 * Deconstructor. Save profiles. Delete loaded libraries.
78 */ 97 */
79MainWindowImp::~MainWindowImp(){ 98MainWindowImp::~MainWindowImp(){
80 // Save profiles. 99 // Save profiles.
81 Config cfg("NetworkSetup"); 100 Config cfg("NetworkSetup");
82 cfg.setGroup("General"); 101 cfg.setGroup("General");
83 cfg.writeEntry("Profiles", profiles.join(" ")); 102 cfg.writeEntry("Profiles", profiles.join(" "));
84 103
85 // Delete all interfaces that don't have owners. 104 // Delete all interfaces that don't have owners.
86 QMap<Interface*, QListViewItem*>::Iterator iIt; 105 QMap<Interface*, QListViewItem*>::Iterator iIt;
87 for( iIt = items.begin(); iIt != items.end(); ++iIt ){ 106 for( iIt = items.begin(); iIt != items.end(); ++iIt ){
88 if(iIt.key()->getModuleOwner() == NULL) 107 if(iIt.key()->getModuleOwner() == NULL)
89 delete iIt.key(); 108 delete iIt.key();
90 } 109 }
91 110
92 // Delete Modules and Libraries 111 // Delete Modules and Libraries
93 QMap<Module*, QLibrary*>::Iterator it; 112 QMap<Module*, QLibrary*>::Iterator it;
94 for( it = libraries.begin(); it != libraries.end(); ++it ){ 113 for( it = libraries.begin(); it != libraries.end(); ++it ){
95 delete it.key(); 114 delete it.key();
96 // I wonder why I can't delete the libraries 115 // I wonder why I can't delete the libraries
97 // What fucking shit this is. 116 // What fucking shit this is.
98 //delete it.data(); 117 //delete it.data();
99 } 118 }
100} 119}
101 120
102/** 121/**
122 * Query the kernel for all of the interfaces.
123 */
124void MainWindowImp::getAllInterfaces(){
125 int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
126 if(sockfd == -1)
127 return;
128
129 char buf[8*1024];
130 struct ifconf ifc;
131 ifc.ifc_len = sizeof(buf);
132 ifc.ifc_req = (struct ifreq *) buf;
133 int result=ioctl(sockfd, SIOCGIFCONF, &ifc);
134
135 for (char* ptr = buf; ptr < buf + ifc.ifc_len; ){
136 struct ifreq *ifr =(struct ifreq *) ptr;
137 int len = sizeof(struct sockaddr);
138#ifdef HAVE_SOCKADDR_SA_LEN
139 if (ifr->ifr_addr.sa_len > len)
140 len = ifr->ifr_addr.sa_len; /* length > 16 */
141#endif
142 ptr += sizeof(ifr->ifr_name) + len; /* for next one in buffer */
143
144 int flags;
145 struct sockaddr_in *sinptr;
146 Interface *i = NULL;
147 switch (ifr->ifr_addr.sa_family){
148 case AF_INET:
149 sinptr = (struct sockaddr_in *) &ifr->ifr_addr;
150 flags=0;
151
152 struct ifreq ifcopy;
153 ifcopy=*ifr;
154 result=ioctl(sockfd,SIOCGIFFLAGS,&ifcopy);
155 flags=ifcopy.ifr_flags;
156 i = new Interface(this, ifr->ifr_name, false);
157 i->setAttached(true);
158 if ((flags & IFF_UP) == IFF_UP)
159 i->setStatus(true);
160 else
161 i->setStatus(false);
162
163 if ((flags & IFF_BROADCAST) == IFF_BROADCAST)
164 i->setHardwareName("Ethernet");
165 else if ((flags & IFF_POINTOPOINT) == IFF_POINTOPOINT)
166 i->setHardwareName("Point to Point");
167 else if ((flags & IFF_MULTICAST) == IFF_MULTICAST)
168 i->setHardwareName("Multicast");
169 else if ((flags & IFF_LOOPBACK) == IFF_LOOPBACK)
170 i->setHardwareName("Loopback");
171 else
172 i->setHardwareName("Unknown");
173
174 interfaceNames.insert(i->getInterfaceName(), i);
175 updateInterface(i);
176 connect(i, SIGNAL(updateInterface(Interface *)), this, SLOT(updateInterface(Interface *)));
177 break;
178
179 default:
180 qDebug(ifr->ifr_name);
181 qDebug(QString("%1").arg(ifr->ifr_addr.sa_family).latin1());
182 break;
183 }
184 }
185}
186
187/**
103 * Load all modules that are found in the path 188 * Load all modules that are found in the path
104 * @param path a directory that is scaned for any plugins that can be loaded 189 * @param path a directory that is scaned for any plugins that can be loaded
105 * and attempts to load them 190 * and attempts to load them
106 */ 191 */
107void MainWindowImp::loadModules(QString path){ 192void MainWindowImp::loadModules(QString path){
108 //qDebug(path.latin1()); 193 //qDebug(path.latin1());
109 QDir d(path); 194 QDir d(path);
110 if(!d.exists()) 195 if(!d.exists())
111 return; 196 return;
112 197
113 // Don't want sym links 198 // Don't want sym links
114 d.setFilter( QDir::Files | QDir::NoSymLinks ); 199 d.setFilter( QDir::Files | QDir::NoSymLinks );
115 const QFileInfoList *list = d.entryInfoList(); 200 const QFileInfoList *list = d.entryInfoList();
116 QFileInfoListIterator it( *list ); 201 QFileInfoListIterator it( *list );
117 QFileInfo *fi; 202 QFileInfo *fi;
118 while ( (fi=it.current()) ) { 203 while ( (fi=it.current()) ) {
119 if(fi->fileName().contains(".so")){ 204 if(fi->fileName().contains(".so")){
120 loadPlugin(path + "/" + fi->fileName()); 205 loadPlugin(path + "/" + fi->fileName());
121 } 206 }
122 ++it; 207 ++it;
123 } 208 }
124} 209}
125 210
126/** 211/**
127 * Attempt to load a function and resolve a function. 212 * Attempt to load a function and resolve a function.
128 * @param pluginFileName - the name of the file in which to attempt to load 213 * @param pluginFileName - the name of the file in which to attempt to load
129 * @param resolveString - function pointer to resolve 214 * @param resolveString - function pointer to resolve
130 * @return pointer to the function with name resolveString or NULL 215 * @return pointer to the function with name resolveString or NULL
131 */ 216 */
132Module* MainWindowImp::loadPlugin(QString pluginFileName, QString resolveString){ 217Module* MainWindowImp::loadPlugin(QString pluginFileName, QString resolveString){
133 //qDebug(QString("MainWindowImp::loadPlugin: %1").arg(pluginFileName).latin1()); 218 //qDebug(QString("MainWindowImp::loadPlugin: %1").arg(pluginFileName).latin1());
134 QLibrary *lib = new QLibrary(pluginFileName); 219 QLibrary *lib = new QLibrary(pluginFileName);
135 void *functionPointer = lib->resolve(resolveString); 220 void *functionPointer = lib->resolve(resolveString);
136 if( !functionPointer ){ 221 if( !functionPointer ){
137 qDebug(QString("MainWindowImp: File: %1 is not a plugin, but though was.").arg(pluginFileName).latin1()); 222 qDebug(QString("MainWindowImp: File: %1 is not a plugin, but though was.").arg(pluginFileName).latin1());
138 delete lib; 223 delete lib;
139 return NULL; 224 return NULL;
140 } 225 }
141 226
142 // Try to get an object. 227 // Try to get an object.
143 Module *object = ((Module* (*)()) functionPointer)(); 228 Module *object = ((Module* (*)()) functionPointer)();
144 if(object == NULL){ 229 if(object == NULL){
145 qDebug("MainWindowImp: Couldn't create object, but did load library!"); 230 qDebug("MainWindowImp: Couldn't create object, but did load library!");
146 delete lib; 231 delete lib;
147 return NULL; 232 return NULL;
148 } 233 }
149 234
150 // Store for deletion later 235 // Store for deletion later
151 libraries.insert(object, lib); 236 libraries.insert(object, lib);
152 return object; 237 return object;
153} 238}
154 239
155/** 240/**
156 * The Add button was clicked. Bring up the add dialog and if OK is hit 241 * The Add button was clicked. Bring up the add dialog and if OK is hit
157 * load the plugin and append it to the list 242 * load the plugin and append it to the list
158 */ 243 */
159void MainWindowImp::addClicked(){ 244void MainWindowImp::addClicked(){
160 QMap<Module*, QLibrary*>::Iterator it; 245 QMap<Module*, QLibrary*>::Iterator it;
161 QMap<QString, QString> list; 246 QMap<QString, QString> list;
162 QMap<QString, Module*> newInterfaceOwners; 247 QMap<QString, Module*> newInterfaceOwners;
163 //list.insert("USB (PPP) / (ADD_TEST)", "A dialup connection over the USB port"); 248 //list.insert("USB (PPP) / (ADD_TEST)", "A dialup connection over the USB port");
164 //list.insert("IrDa (PPP) / (ADD_TEST)", "A dialup connection over the IdDa port"); 249 //list.insert("IrDa (PPP) / (ADD_TEST)", "A dialup connection over the IdDa port");
165 for( it = libraries.begin(); it != libraries.end(); ++it ){ 250 for( it = libraries.begin(); it != libraries.end(); ++it ){
166 if(it.key()){ 251 if(it.key()){
167 (it.key())->possibleNewInterfaces(list); 252 (it.key())->possibleNewInterfaces(list);
168 } 253 }
169 } 254 }
170 // See if the list has anything that we can add. 255 // See if the list has anything that we can add.
171 if(list.count() == 0){ 256 if(list.count() == 0){
172 QMessageBox::information(this, "Sorry", "Nothing to add.", QMessageBox::Ok); 257 QMessageBox::information(this, "Sorry", "Nothing to add.", QMessageBox::Ok);
173 return; 258 return;
174 } 259 }
175 AddConnectionImp addNewConnection(this, "AddConnectionImp", true); 260 AddConnectionImp addNewConnection(this, "AddConnectionImp", true);
176 addNewConnection.addConnections(list); 261 addNewConnection.addConnections(list);
177 addNewConnection.showMaximized(); 262 addNewConnection.showMaximized();
178 if(QDialog::Accepted == addNewConnection.exec()){ 263 if(QDialog::Accepted == addNewConnection.exec()){
179 QListViewItem *item = addNewConnection.registeredServicesList->currentItem(); 264 QListViewItem *item = addNewConnection.registeredServicesList->currentItem();
180 if(!item) 265 if(!item)
181 return; 266 return;
182 267
183 for( it = libraries.begin(); it != libraries.end(); ++it ){ 268 for( it = libraries.begin(); it != libraries.end(); ++it ){
184 if(it.key()){ 269 if(it.key()){
185 Interface *i = (it.key())->addNewInterface(item->text(0)); 270 Interface *i = (it.key())->addNewInterface(item->text(0));
186 if(i){ 271 if(i){
187 interfaceNames.insert(i->getInterfaceName(), i); 272 interfaceNames.insert(i->getInterfaceName(), i);
188 updateInterface(i); 273 updateInterface(i);
189 } 274 }
190 } 275 }
191 } 276 }
192 } 277 }
193} 278}
194 279
195/** 280/**
196 * Prompt the user to see if they really want to do this. 281 * Prompt the user to see if they really want to do this.
197 * If they do then remove from the list and unload. 282 * If they do then remove from the list and unload.
198 */ 283 */
199void MainWindowImp::removeClicked(){ 284void MainWindowImp::removeClicked(){
200 QListViewItem *item = connectionList->currentItem(); 285 QListViewItem *item = connectionList->currentItem();
201 if(!item) { 286 if(!item) {
202 QMessageBox::information(this, "Sorry","Please select an interface First.", QMessageBox::Ok); 287 QMessageBox::information(this, "Sorry","Please select an interface First.", QMessageBox::Ok);
203 return; 288 return;
204 } 289 }
205 290
206 Interface *i = interfaceItems[item]; 291 Interface *i = interfaceItems[item];
207 if(i->getModuleOwner() == NULL){ 292 if(i->getModuleOwner() == NULL){
208 QMessageBox::information(this, "Can't remove interface.", "Interface is built in.", QMessageBox::Ok); 293 QMessageBox::information(this, "Can't remove interface.", "Interface is built in.", QMessageBox::Ok);
209 } 294 }
210 else{ 295 else{
211 if(!i->getModuleOwner()->remove(i)) 296 if(!i->getModuleOwner()->remove(i))
212 QMessageBox::information(this, "Error", "Unable to remove.", QMessageBox::Ok); 297 QMessageBox::information(this, "Error", "Unable to remove.", QMessageBox::Ok);
213 else{ 298 else{
214 QMessageBox::information(this, "Success", "Interface was removed.", QMessageBox::Ok); 299 QMessageBox::information(this, "Success", "Interface was removed.", QMessageBox::Ok);
215 // TODO memory managment.... 300 // TODO memory managment....
216 // who deletes the interface? 301 // who deletes the interface?
217 } 302 }
218 } 303 }
219} 304}
220 305
221/** 306/**
222 * Pull up the configure about the currently selected interface. 307 * Pull up the configure about the currently selected interface.
223 * Report an error if no interface is selected. 308 * Report an error if no interface is selected.
224 * If the interface has a module owner then request its configure. 309 * If the interface has a module owner then request its configure.
225 */ 310 */
226void MainWindowImp::configureClicked(){ 311void MainWindowImp::configureClicked(){
227 QListViewItem *item = connectionList->currentItem(); 312 QListViewItem *item = connectionList->currentItem();
228 if(!item){ 313 if(!item){
229 QMessageBox::information(this, "Sorry","Please select an interface first.", QMessageBox::Ok); 314 QMessageBox::information(this, "Sorry","Please select an interface first.", QMessageBox::Ok);
230 return; 315 return;
231 } 316 }
232 317
233 Interface *i = interfaceItems[item]; 318 Interface *i = interfaceItems[item];
234 if(i->getModuleOwner()){ 319 if(i->getModuleOwner()){
235 QWidget *moduleConfigure = i->getModuleOwner()->configure(i); 320 QWidget *moduleConfigure = i->getModuleOwner()->configure(i);
236 if(moduleConfigure != NULL){ 321 if(moduleConfigure != NULL){
237 moduleConfigure->showMaximized(); 322 moduleConfigure->showMaximized();
238 moduleConfigure->show(); 323 moduleConfigure->show();
239 return; 324 return;
240 } 325 }
241 } 326 }
242 327
243 InterfaceSetupImpDialog *configure = new InterfaceSetupImpDialog(0, "InterfaceSetupImp", i, true, Qt::WDestructiveClose); 328 InterfaceSetupImpDialog *configure = new InterfaceSetupImpDialog(0, "InterfaceSetupImp", i, true, Qt::WDestructiveClose);
244 QString currentProfileText = currentProfileLabel->text(); 329 QString currentProfileText = currentProfileLabel->text();
245 if(currentProfileText.upper() == "ALL"); 330 if(currentProfileText.upper() == "ALL");
246 currentProfileText = ""; 331 currentProfileText = "";
247 configure->setProfile(currentProfileText); 332 configure->setProfile(currentProfileText);
248 configure->showMaximized(); 333 configure->showMaximized();
249 configure->show(); 334 configure->show();
250} 335}
251 336
252/** 337/**
253 * Pull up the information about the currently selected interface. 338 * Pull up the information about the currently selected interface.
254 * Report an error if no interface is selected. 339 * Report an error if no interface is selected.
255 * If the interface has a module owner then request its configure. 340 * If the interface has a module owner then request its configure.
256 */ 341 */
257void MainWindowImp::informationClicked(){ 342void MainWindowImp::informationClicked(){
258 QListViewItem *item = connectionList->currentItem(); 343 QListViewItem *item = connectionList->currentItem();
259 if(!item){ 344 if(!item){
260 QMessageBox::information(this, "Sorry","Please select an interface First.", QMessageBox::Ok); 345 QMessageBox::information(this, "Sorry","Please select an interface First.", QMessageBox::Ok);
261 return; 346 return;
262 } 347 }
263 348
264 Interface *i = interfaceItems[item]; 349 Interface *i = interfaceItems[item];
265 if(!i->isAttached()){ 350 if(!i->isAttached()){
266 QMessageBox::information(this, "Sorry","No information about\na disconnected interface.", QMessageBox::Ok); 351 QMessageBox::information(this, "Sorry","No information about\na disconnected interface.", QMessageBox::Ok);
267 return; 352 return;
268 } 353 }
269 354
270 if(i->getModuleOwner()){ 355 if(i->getModuleOwner()){
271 QWidget *moduleInformation = i->getModuleOwner()->information(i); 356 QWidget *moduleInformation = i->getModuleOwner()->information(i);
272 if(moduleInformation != NULL){ 357 if(moduleInformation != NULL){
273 moduleInformation->showMaximized(); 358 moduleInformation->showMaximized();
274 moduleInformation->show(); 359 moduleInformation->show();
275 return; 360 return;
276 } 361 }
277 } 362 }
278 InterfaceInformationImp *information = new InterfaceInformationImp(0, "InterfaceSetupImp", i, true); 363 InterfaceInformationImp *information = new InterfaceInformationImp(0, "InterfaceSetupImp", i, true);
279 information->showMaximized(); 364 information->showMaximized();
280 information->show(); 365 information->show();
281} 366}
282 367
283/** 368/**
284 * Aquire the list of active interfaces from ifconfig
285 * Call ifconfig and ifconfig -a
286 */
287void MainWindowImp::getInterfaceList(){
288 KShellProcess *processAll = new KShellProcess();
289 *processAll << "/sbin/ifconfig" << "-a" << " > " TEMP_ALL;
290 connect(processAll, SIGNAL(processExited(KProcess *)),
291 this, SLOT(jobDone(KProcess *)));
292 threads.insert(processAll, TEMP_ALL);
293
294 KShellProcess *process = new KShellProcess();
295 *process << "/sbin/ifconfig" << " > " TEMP_UP;
296 connect(process, SIGNAL(processExited(KProcess *)),
297 this, SLOT(jobDone(KProcess *)));
298 threads.insert(process, TEMP_UP);
299
300 processAll->start(KShellProcess::NotifyOnExit);
301 process->start(KShellProcess::NotifyOnExit);
302}
303
304void MainWindowImp::jobDone(KProcess *process){
305 QString fileName = threads[process];
306 threads.remove(process);
307 delete process;
308
309 QFile file(fileName);
310 if (!file.open(IO_ReadOnly)){
311 qDebug(QString("MainWindowImp: Can't open file: %1").arg(fileName).latin1());
312 return;
313 }
314
315 QTextStream stream( &file );
316 QString line;
317 while ( !stream.eof() ) {
318 line = stream.readLine();
319 int space = line.find(" ");
320 if(space > 1){
321 // We have found an interface
322 QString interfaceName = line.mid(0, space);
323 Interface *i;
324 // We have found an interface
325 //qDebug(QString("MainWindowImp: Found Interface: %1").arg(line).latin1());
326 // See if we already have it
327 if(interfaceNames.find(interfaceName) == interfaceNames.end()){
328 if(fileName == TEMP_ALL)
329 i = new Interface(this, interfaceName, false);
330 else
331 i = new Interface(this, interfaceName, true);
332 i->setAttached(true);
333
334 QString hardName = "Ethernet";
335 int hardwareName = line.find("Link encap:");
336 int macAddress = line.find("HWaddr");
337 if(macAddress == -1)
338 macAddress = line.length();
339 if(hardwareName != -1)
340 i->setHardwareName(line.mid(hardwareName+11, macAddress-(hardwareName+11)) );
341
342 interfaceNames.insert(i->getInterfaceName(), i);
343 updateInterface(i);
344 connect(i, SIGNAL(updateInterface(Interface *)), this, SLOT(updateInterface(Interface *)));
345 }
346 // It was an interface we already had.
347 else{
348 if(fileName != TEMP_ALL)
349 (interfaceNames[interfaceName])->setStatus(true);
350 }
351 }
352 }
353 file.close();
354 QFile::remove(fileName);
355
356 if(threads.count() == 0){
357 Interfaces i;
358 QStringList list = i.getInterfaceList();
359 QMap<QString, Interface*>::Iterator it;
360 for ( QStringList::Iterator ni = list.begin(); ni != list.end(); ++ni ) {
361 bool found = false;
362 for( it = interfaceNames.begin(); it != interfaceNames.end(); ++it ){
363 if(it.key() == (*ni))
364 found = true;
365 }
366 if(!found){
367 if(!(*ni).contains("_")){
368 Interface *i = new Interface(this, *ni, false);
369 i->setAttached(false);
370 i->setHardwareName("Disconnected");
371 interfaceNames.insert(i->getInterfaceName(), i);
372 updateInterface(i);
373 connect(i, SIGNAL(updateInterface(Interface *)), this, SLOT(updateInterface(Interface *)));
374 }
375 }
376 }
377 }
378}
379
380/**
381 * Update this interface. If no QListViewItem exists create one. 369 * Update this interface. If no QListViewItem exists create one.
382 * @param Interface* pointer to the interface that needs to be updated. 370 * @param Interface* pointer to the interface that needs to be updated.
383 */ 371 */
384void MainWindowImp::updateInterface(Interface *i){ 372void MainWindowImp::updateInterface(Interface *i){
385 if(!advancedUserMode){ 373 if(!advancedUserMode){
386 if(i->getInterfaceName() == "lo") 374 if(i->getInterfaceName() == "lo")
387 return; 375 return;
388 } 376 }
389 377
390 QListViewItem *item = NULL; 378 QListViewItem *item = NULL;
391 379
392 // Find the interface, making it if needed. 380 // Find the interface, making it if needed.
393 if(items.find(i) == items.end()){ 381 if(items.find(i) == items.end()){
394 item = new QListViewItem(connectionList, "", "", ""); 382 item = new QListViewItem(connectionList, "", "", "");
395 // See if you can't find a module owner for this interface 383 // See if you can't find a module owner for this interface
396 QMap<Module*, QLibrary*>::Iterator it; 384 QMap<Module*, QLibrary*>::Iterator it;
397 for( it = libraries.begin(); it != libraries.end(); ++it ){ 385 for( it = libraries.begin(); it != libraries.end(); ++it ){
398 if(it.key()->isOwner(i)) 386 if(it.key()->isOwner(i))
399 i->setModuleOwner(it.key()); 387 i->setModuleOwner(it.key());
400 } 388 }
401 items.insert(i, item); 389 items.insert(i, item);
402 interfaceItems.insert(item, i); 390 interfaceItems.insert(item, i);
403 } 391 }
404 else 392 else
405 item = items[i]; 393 item = items[i];
406 394
407 // Update the icons and information 395 // Update the icons and information
408 item->setPixmap(0, (Resource::loadPixmap(i->getStatus() ? "up": "down"))); 396 item->setPixmap(0, (Resource::loadPixmap(i->getStatus() ? "up": "down")));
409 397
410 QString typeName = "lan"; 398 QString typeName = "lan";
411 if(i->getHardwareName().contains("Local Loopback")) 399 if(i->getHardwareName().contains("Local Loopback"))
412 typeName = "lo"; 400 typeName = "lo";
413 if(i->getInterfaceName().contains("irda")) 401 if(i->getInterfaceName().contains("irda"))
414 typeName = "irda"; 402 typeName = "irda";
415 if(i->getInterfaceName().contains("wlan")) 403 if(i->getInterfaceName().contains("wlan"))
416 typeName = "wlan"; 404 typeName = "wlan";
417 if(i->getInterfaceName().contains("usb")) 405 if(i->getInterfaceName().contains("usb"))
418 typeName = "usb"; 406 typeName = "usb";
419 407
420 if(!i->isAttached()) 408 if(!i->isAttached())
421 typeName = "connect_no"; 409 typeName = "connect_no";
422 // Actually try to use the Module 410 // Actually try to use the Module
423 if(i->getModuleOwner() != NULL) 411 if(i->getModuleOwner() != NULL)
424 typeName = i->getModuleOwner()->getPixmapName(i); 412 typeName = i->getModuleOwner()->getPixmapName(i);
425 413
426 item->setPixmap(1, (Resource::loadPixmap(typeName))); 414 item->setPixmap(1, (Resource::loadPixmap(typeName)));
427 item->setText(2, i->getHardwareName()); 415 item->setText(2, i->getHardwareName());
428 item->setText(3, QString("(%1)").arg(i->getInterfaceName())); 416 item->setText(3, QString("(%1)").arg(i->getInterfaceName()));
429 item->setText(4, (i->getStatus()) ? i->getIp() : QString("")); 417 item->setText(4, (i->getStatus()) ? i->getIp() : QString(""));
430} 418}
431 419
432void MainWindowImp::newProfileChanged(const QString& newText){ 420void MainWindowImp::newProfileChanged(const QString& newText){
433 if(newText.length() > 0) 421 if(newText.length() > 0)
434 newProfileButton->setEnabled(true); 422 newProfileButton->setEnabled(true);
435 else 423 else
436 newProfileButton->setEnabled(false); 424 newProfileButton->setEnabled(false);
437} 425}
438 426
439/** 427/**
440 * Adds a new profile to the list of profiles. 428 * Adds a new profile to the list of profiles.
441 * Don't add profiles that already exists. 429 * Don't add profiles that already exists.
442 * Appends to the list and QStringList 430 * Appends to the list and QStringList
443 */ 431 */
444void MainWindowImp::addProfile(){ 432void MainWindowImp::addProfile(){
445 QString newProfileName = newProfile->text(); 433 QString newProfileName = newProfile->text();
446 if(profiles.grep(newProfileName).count() > 0){ 434 if(profiles.grep(newProfileName).count() > 0){
447 QMessageBox::information(this, "Can't Add","Profile already exists.", QMessageBox::Ok); 435 QMessageBox::information(this, "Can't Add","Profile already exists.", QMessageBox::Ok);
448 return; 436 return;
449 } 437 }
450 profiles.append(newProfileName); 438 profiles.append(newProfileName);
451 profilesList->insertItem(newProfileName); 439 profilesList->insertItem(newProfileName);
452} 440}
453 441
454/** 442/**
455 * Removes the currently selected profile in the combo. 443 * Removes the currently selected profile in the combo.
456 * Doesn't delete if there are less then 2 profiles. 444 * Doesn't delete if there are less then 2 profiles.
457 */ 445 */
458void MainWindowImp::removeProfile(){ 446void MainWindowImp::removeProfile(){
459 if(profilesList->count() <= 1){ 447 if(profilesList->count() <= 1){
460 QMessageBox::information(this, "Can't remove.","At least one profile\nis needed.", QMessageBox::Ok); 448 QMessageBox::information(this, "Can't remove.","At least one profile\nis needed.", QMessageBox::Ok);
461 return; 449 return;
462 } 450 }
463 QString profileToRemove = profilesList->currentText(); 451 QString profileToRemove = profilesList->currentText();
464 if(profileToRemove == "All"){ 452 if(profileToRemove == "All"){
465 QMessageBox::information(this, "Can't remove.","Can't remove default.", QMessageBox::Ok); 453 QMessageBox::information(this, "Can't remove.","Can't remove default.", QMessageBox::Ok);
466 return; 454 return;
467 } 455 }
468 // Can't remove the curent profile 456 // Can't remove the curent profile
469 if(profileToRemove == currentProfileLabel->text()){ 457 if(profileToRemove == currentProfileLabel->text()){
470 QMessageBox::information(this, "Can't remove.",QString("%1 is the current profile.").arg(profileToRemove), QMessageBox::Ok); 458 QMessageBox::information(this, "Can't remove.",QString("%1 is the current profile.").arg(profileToRemove), QMessageBox::Ok);
471 return; 459 return;
472 460
473 } 461 }
474 462
475 if(QMessageBox::information(this, "Question",QString("Remove profile: %1").arg(profileToRemove), QMessageBox::Ok, QMessageBox::Cancel) == QMessageBox::Ok){ 463 if(QMessageBox::information(this, "Question",QString("Remove profile: %1").arg(profileToRemove), QMessageBox::Ok, QMessageBox::Cancel) == QMessageBox::Ok){
476 profiles = QStringList::split(" ", profiles.join(" ").replace(QRegExp(profileToRemove), "")); 464 profiles = QStringList::split(" ", profiles.join(" ").replace(QRegExp(profileToRemove), ""));
477 profilesList->clear(); 465 profilesList->clear();
478 for ( QStringList::Iterator it = profiles.begin(); it != profiles.end(); ++it) 466 for ( QStringList::Iterator it = profiles.begin(); it != profiles.end(); ++it)
479 profilesList->insertItem((*it)); 467 profilesList->insertItem((*it));
480 468
481 // Remove any interface settings and mappings. 469 // Remove any interface settings and mappings.
482 Interfaces interfaces; 470 Interfaces interfaces;
483 // Go through them one by one 471 // Go through them one by one
484 QMap<Interface*, QListViewItem*>::Iterator it; 472 QMap<Interface*, QListViewItem*>::Iterator it;
485 for( it = items.begin(); it != items.end(); ++it ){ 473 for( it = items.begin(); it != items.end(); ++it ){
486 QString interfaceName = it.key()->getInterfaceName(); 474 QString interfaceName = it.key()->getInterfaceName();
487 qDebug(interfaceName.latin1()); 475 qDebug(interfaceName.latin1());
488 if(interfaces.setInterface(interfaceName + "_" + profileToRemove)){ 476 if(interfaces.setInterface(interfaceName + "_" + profileToRemove)){
489 interfaces.removeInterface(); 477 interfaces.removeInterface();
490 if(interfaces.setMapping(interfaceName)){ 478 if(interfaces.setMapping(interfaceName)){
491 if(profilesList->count() == 1) 479 if(profilesList->count() == 1)
492 interfaces.removeMapping(); 480 interfaces.removeMapping();
493 else{ 481 else{
494 interfaces.removeMap("map", interfaceName + "_" + profileToRemove); 482 interfaces.removeMap("map", interfaceName + "_" + profileToRemove);
495 } 483 }
496 } 484 }
497 interfaces.write(); 485 interfaces.write();
498 break; 486 break;
499 } 487 }
500 } 488 }
501 } 489 }
502} 490}
503 491
504/** 492/**
505 * A new profile has been selected, change. 493 * A new profile has been selected, change.
506 * @param newProfile the new profile. 494 * @param newProfile the new profile.
507 */ 495 */
508void MainWindowImp::changeProfile(){ 496void MainWindowImp::changeProfile(){
509 if(profilesList->currentItem() == -1){ 497 if(profilesList->currentItem() == -1){
510 QMessageBox::information(this, "Can't Change.","Please select a profile.", QMessageBox::Ok); 498 QMessageBox::information(this, "Can't Change.","Please select a profile.", QMessageBox::Ok);
511 return; 499 return;
512 } 500 }
513 QString newProfile = profilesList->text(profilesList->currentItem()); 501 QString newProfile = profilesList->text(profilesList->currentItem());
514 if(newProfile != currentProfileLabel->text()){ 502 if(newProfile != currentProfileLabel->text()){
515 currentProfileLabel->setText(newProfile); 503 currentProfileLabel->setText(newProfile);
516 QFile::remove(scheme); 504 QFile::remove(scheme);
517 QFile file(scheme); 505 QFile file(scheme);
518 if ( file.open(IO_ReadWrite) ) { 506 if ( file.open(IO_ReadWrite) ) {
519 QTextStream stream( &file ); 507 QTextStream stream( &file );
520 stream << QString("SCHEME=%1").arg(newProfile); 508 stream << QString("SCHEME=%1").arg(newProfile);
521 file.close(); 509 file.close();
522 } 510 }
523 // restart all up devices? 511 // restart all up devices?
524 if(QMessageBox::information(this, "Question","Restart all running interfaces?", QMessageBox::Ok, QMessageBox::No) == QMessageBox::Ok){ 512 if(QMessageBox::information(this, "Question","Restart all running interfaces?", QMessageBox::Ok, QMessageBox::No) == QMessageBox::Ok){
525 // Go through them one by one 513 // Go through them one by one
526 QMap<Interface*, QListViewItem*>::Iterator it; 514 QMap<Interface*, QListViewItem*>::Iterator it;
527 for( it = items.begin(); it != items.end(); ++it ){ 515 for( it = items.begin(); it != items.end(); ++it ){
528 if(it.key()->getStatus() == true) 516 if(it.key()->getStatus() == true)
529 it.key()->restart(); 517 it.key()->restart();
530 } 518 }
531 } 519 }
532 } 520 }
533 // TODO change the profile in the modules 521 // TODO change the profile in the modules
534} 522}
535 523
536// mainwindowimp.cpp 524// mainwindowimp.cpp
537 525
diff --git a/noncore/settings/networksettings/mainwindowimp.h b/noncore/settings/networksettings/mainwindowimp.h
index e5284b4..382428c 100644
--- a/noncore/settings/networksettings/mainwindowimp.h
+++ b/noncore/settings/networksettings/mainwindowimp.h
@@ -1,59 +1,58 @@
1#ifndef MAINWINOWIMP_H 1#ifndef MAINWINOWIMP_H
2#define MAINWINOWIMP_H 2#define MAINWINOWIMP_H
3 3
4#include "mainwindow.h" 4#include "mainwindow.h"
5#include <qmap.h> 5#include <qmap.h>
6#include <qstringlist.h> 6#include <qstringlist.h>
7 7
8class Module; 8class Module;
9class Interface; 9class Interface;
10class QLibrary; 10class QLibrary;
11class KProcess; 11class KProcess;
12 12
13class MainWindowImp : public MainWindow { 13class MainWindowImp : public MainWindow {
14 Q_OBJECT 14 Q_OBJECT
15 15
16public: 16public:
17 MainWindowImp(QWidget *parent=0, const char *name=0); 17 MainWindowImp(QWidget *parent=0, const char *name=0);
18 ~MainWindowImp(); 18 ~MainWindowImp();
19 19
20private slots: 20private slots:
21 void getAllInterfaces();
22
21 void addClicked(); 23 void addClicked();
22 void removeClicked(); 24 void removeClicked();
23 void configureClicked(); 25 void configureClicked();
24 void informationClicked(); 26 void informationClicked();
25 27
26 void jobDone(KProcess *process);
27 void getInterfaceList();
28
29 void addProfile(); 28 void addProfile();
30 void removeProfile(); 29 void removeProfile();
31 void changeProfile(); 30 void changeProfile();
32 31
33 void updateInterface(Interface *i); 32 void updateInterface(Interface *i);
34 void newProfileChanged(const QString& newText); 33 void newProfileChanged(const QString& newText);
35 34
36private: 35private:
37 void loadModules(QString path); 36 void loadModules(QString path);
38 37
39 Module* loadPlugin(QString pluginFileName, 38 Module* loadPlugin(QString pluginFileName,
40 QString resolveString = "create_plugin"); 39 QString resolveString = "create_plugin");
41 40
42 // For our local list of names 41 // For our local list of names
43 QMap<QString, Interface*> interfaceNames; 42 QMap<QString, Interface*> interfaceNames;
44 43
45 QMap<Module*, QLibrary*> libraries; 44 QMap<Module*, QLibrary*> libraries;
46 QMap<Interface*, QListViewItem*> items; 45 QMap<Interface*, QListViewItem*> items;
47 QMap<QListViewItem*, Interface*> interfaceItems; 46 QMap<QListViewItem*, Interface*> interfaceItems;
48 47
49 QMap<KProcess*, QString> threads; 48 QMap<KProcess*, QString> threads;
50 QStringList profiles; 49 QStringList profiles;
51 50
52 bool advancedUserMode; 51 bool advancedUserMode;
53 QString scheme; 52 QString scheme;
54}; 53};
55 54
56#endif 55#endif
57 56
58// mainwindowimp.h 57// mainwindowimp.h
59 58
diff --git a/noncore/settings/networksettings/networksetup.pro b/noncore/settings/networksettings/networksetup.pro
index 6420924..cb517ce 100644
--- a/noncore/settings/networksettings/networksetup.pro
+++ b/noncore/settings/networksettings/networksetup.pro
@@ -1,11 +1,11 @@
1DESTDIR = $(OPIEDIR)/bin 1#DESTDIR = $(OPIEDIR)/bin
2TEMPLATE = app 2TEMPLATE = app
3#CONFIG = qt warn_on debug 3#CONFIG = qt warn_on debug
4CONFIG = qt warn_on release 4CONFIG = qt warn_on release
5HEADERS = mainwindowimp.h addconnectionimp.h defaultmodule.h kprocctrl.h module.h kprocess.h 5HEADERS = mainwindowimp.h addconnectionimp.h defaultmodule.h module.h
6SOURCES = main.cpp mainwindowimp.cpp addconnectionimp.cpp kprocctrl.cpp kprocess.cpp 6SOURCES = main.cpp mainwindowimp.cpp addconnectionimp.cpp
7INCLUDEPATH += $(OPIEDIR)/include interfaces/ 7INCLUDEPATH += $(OPIEDIR)/include interfaces/
8DEPENDPATH += $(OPIEDIR)/include interfaces/ wlan 8DEPENDPATH += $(OPIEDIR)/include interfaces/ wlan
9LIBS += -lqpe -L$(OPIEDIR)/plugins/networksetup -Linterfaces/ -linterfaces 9LIBS += -lqpe -L$(OPIEDIR)/plugins/networksetup -Linterfaces/ -linterfaces
10INTERFACES = mainwindow.ui addconnection.ui 10INTERFACES = mainwindow.ui addconnection.ui
11TARGET = networksetup 11TARGET = networksetup
diff --git a/noncore/settings/networksettings/ppp/.cvsignore b/noncore/settings/networksettings/ppp/.cvsignore
new file mode 100644
index 0000000..d753773
--- a/dev/null
+++ b/noncore/settings/networksettings/ppp/.cvsignore
@@ -0,0 +1,23 @@
1.moc.cpp
2*.moc
3*.moc.o
4*.o
5moc_*.cpp
6.libs
7.deps
8.moc.o
9.o
10Makefile*
11networksetup
12addconnection.cpp
13addconnection.h
14interfaceadvanced.cpp
15interfaceadvanced.h
16interfaceinformation.cpp
17interfaceinformation.h
18interfacesetup.cpp
19interfacesetup.h
20mainwindow.cpp
21mainwindow.h
22systemadvanced.cpp
23systemadvanced.h
diff --git a/noncore/settings/networksettings/ppp/ppp.ui b/noncore/settings/networksettings/ppp/ppp.ui
new file mode 100644
index 0000000..d08eda0
--- a/dev/null
+++ b/noncore/settings/networksettings/ppp/ppp.ui
@@ -0,0 +1,770 @@
1<!DOCTYPE UI><UI>
2<class>DialupBase</class>
3<widget>
4 <class>QDialog</class>
5 <property stdset="1">
6 <name>name</name>
7 <cstring>Form1</cstring>
8 </property>
9 <property stdset="1">
10 <name>geometry</name>
11 <rect>
12 <x>0</x>
13 <y>0</y>
14 <width>273</width>
15 <height>340</height>
16 </rect>
17 </property>
18 <property stdset="1">
19 <name>caption</name>
20 <string>Dial-up </string>
21 </property>
22 <property>
23 <name>layoutMargin</name>
24 </property>
25 <property>
26 <name>layoutSpacing</name>
27 </property>
28 <vbox>
29 <property stdset="1">
30 <name>margin</name>
31 <number>1</number>
32 </property>
33 <property stdset="1">
34 <name>spacing</name>
35 <number>0</number>
36 </property>
37 <widget>
38 <class>QTabWidget</class>
39 <property stdset="1">
40 <name>name</name>
41 <cstring>TabWidget2</cstring>
42 </property>
43 <property>
44 <name>layoutMargin</name>
45 </property>
46 <property>
47 <name>layoutSpacing</name>
48 </property>
49 <widget>
50 <class>QWidget</class>
51 <property stdset="1">
52 <name>name</name>
53 <cstring>tab</cstring>
54 </property>
55 <attribute>
56 <name>title</name>
57 <string>Account</string>
58 </attribute>
59 <grid>
60 <property stdset="1">
61 <name>margin</name>
62 <number>6</number>
63 </property>
64 <property stdset="1">
65 <name>spacing</name>
66 <number>4</number>
67 </property>
68 <widget row="3" column="1" >
69 <class>QLineEdit</class>
70 <property stdset="1">
71 <name>name</name>
72 <cstring>password</cstring>
73 </property>
74 <property stdset="1">
75 <name>echoMode</name>
76 <enum>Password</enum>
77 </property>
78 </widget>
79 <widget row="2" column="1" >
80 <class>QLineEdit</class>
81 <property stdset="1">
82 <name>name</name>
83 <cstring>username</cstring>
84 </property>
85 </widget>
86 <widget row="2" column="0" >
87 <class>QLabel</class>
88 <property stdset="1">
89 <name>name</name>
90 <cstring>TextLabel1</cstring>
91 </property>
92 <property stdset="1">
93 <name>text</name>
94 <string>Username</string>
95 </property>
96 </widget>
97 <widget row="3" column="0" >
98 <class>QLabel</class>
99 <property stdset="1">
100 <name>name</name>
101 <cstring>TextLabel2</cstring>
102 </property>
103 <property stdset="1">
104 <name>text</name>
105 <string>Password</string>
106 </property>
107 </widget>
108 <widget row="5" column="0" >
109 <class>QLabel</class>
110 <property stdset="1">
111 <name>name</name>
112 <cstring>TextLabel1_2_2</cstring>
113 </property>
114 <property stdset="1">
115 <name>text</name>
116 <string>Phone #</string>
117 </property>
118 </widget>
119 <widget row="5" column="1" >
120 <class>QLineEdit</class>
121 <property stdset="1">
122 <name>name</name>
123 <cstring>phone</cstring>
124 </property>
125 </widget>
126 <widget row="4" column="0" rowspan="1" colspan="2" >
127 <class>Line</class>
128 <property stdset="1">
129 <name>name</name>
130 <cstring>Line3</cstring>
131 </property>
132 <property stdset="1">
133 <name>orientation</name>
134 <enum>Horizontal</enum>
135 </property>
136 </widget>
137 <widget row="0" column="1" >
138 <class>QLineEdit</class>
139 <property stdset="1">
140 <name>name</name>
141 <cstring>acname</cstring>
142 </property>
143 </widget>
144 <widget row="0" column="0" >
145 <class>QLabel</class>
146 <property stdset="1">
147 <name>name</name>
148 <cstring>TextLabel1_2</cstring>
149 </property>
150 <property stdset="1">
151 <name>text</name>
152 <string>Name</string>
153 </property>
154 </widget>
155 <widget row="1" column="0" rowspan="1" colspan="2" >
156 <class>Line</class>
157 <property stdset="1">
158 <name>name</name>
159 <cstring>Line4</cstring>
160 </property>
161 <property stdset="1">
162 <name>orientation</name>
163 <enum>Horizontal</enum>
164 </property>
165 </widget>
166 <spacer row="9" column="1" >
167 <property>
168 <name>name</name>
169 <cstring>Spacer4</cstring>
170 </property>
171 <property stdset="1">
172 <name>orientation</name>
173 <enum>Vertical</enum>
174 </property>
175 <property stdset="1">
176 <name>sizeType</name>
177 <enum>Expanding</enum>
178 </property>
179 <property>
180 <name>sizeHint</name>
181 <size>
182 <width>20</width>
183 <height>20</height>
184 </size>
185 </property>
186 </spacer>
187 </grid>
188 </widget>
189 <widget>
190 <class>QWidget</class>
191 <property stdset="1">
192 <name>name</name>
193 <cstring>tab</cstring>
194 </property>
195 <attribute>
196 <name>title</name>
197 <string>Modem</string>
198 </attribute>
199 <grid>
200 <property stdset="1">
201 <name>margin</name>
202 <number>6</number>
203 </property>
204 <property stdset="1">
205 <name>spacing</name>
206 <number>4</number>
207 </property>
208 <widget row="0" column="0" >
209 <class>QLabel</class>
210 <property stdset="1">
211 <name>name</name>
212 <cstring>TextLabel3_2_2</cstring>
213 </property>
214 <property stdset="1">
215 <name>text</name>
216 <string>AT-dial</string>
217 </property>
218 </widget>
219 <widget row="0" column="1" rowspan="1" colspan="3" >
220 <class>QComboBox</class>
221 <item>
222 <property>
223 <name>text</name>
224 <string>ATDT</string>
225 </property>
226 </item>
227 <item>
228 <property>
229 <name>text</name>
230 <string>ATDP</string>
231 </property>
232 </item>
233 <property stdset="1">
234 <name>name</name>
235 <cstring>atdial</cstring>
236 </property>
237 <property stdset="1">
238 <name>editable</name>
239 <bool>true</bool>
240 </property>
241 </widget>
242 <widget row="1" column="0" >
243 <class>QLabel</class>
244 <property stdset="1">
245 <name>name</name>
246 <cstring>TextLabel1_4</cstring>
247 </property>
248 <property stdset="1">
249 <name>text</name>
250 <string>Speed</string>
251 </property>
252 </widget>
253 <widget row="1" column="1" rowspan="1" colspan="3" >
254 <class>QComboBox</class>
255 <item>
256 <property>
257 <name>text</name>
258 <string>4800</string>
259 </property>
260 </item>
261 <item>
262 <property>
263 <name>text</name>
264 <string>9600</string>
265 </property>
266 </item>
267 <item>
268 <property>
269 <name>text</name>
270 <string>19200</string>
271 </property>
272 </item>
273 <item>
274 <property>
275 <name>text</name>
276 <string>38400</string>
277 </property>
278 </item>
279 <item>
280 <property>
281 <name>text</name>
282 <string>57600</string>
283 </property>
284 </item>
285 <item>
286 <property>
287 <name>text</name>
288 <string>115200</string>
289 </property>
290 </item>
291 <property stdset="1">
292 <name>name</name>
293 <cstring>speed</cstring>
294 </property>
295 <property stdset="1">
296 <name>currentItem</name>
297 <number>5</number>
298 </property>
299 </widget>
300 <widget row="3" column="1" >
301 <class>QSlider</class>
302 <property stdset="1">
303 <name>name</name>
304 <cstring>connectdelay</cstring>
305 </property>
306 <property stdset="1">
307 <name>minValue</name>
308 <number>1</number>
309 </property>
310 <property stdset="1">
311 <name>maxValue</name>
312 <number>180</number>
313 </property>
314 <property stdset="1">
315 <name>value</name>
316 <number>6</number>
317 </property>
318 <property stdset="1">
319 <name>orientation</name>
320 <enum>Horizontal</enum>
321 </property>
322 </widget>
323 <widget row="3" column="0" >
324 <class>QLabel</class>
325 <property stdset="1">
326 <name>name</name>
327 <cstring>TextLabel1_3</cstring>
328 </property>
329 <property stdset="1">
330 <name>text</name>
331 <string>Wait time</string>
332 </property>
333 </widget>
334 <widget row="3" column="2" >
335 <class>QLabel</class>
336 <property stdset="1">
337 <name>name</name>
338 <cstring>connectdelay_text</cstring>
339 </property>
340 <property stdset="1">
341 <name>minimumSize</name>
342 <size>
343 <width>15</width>
344 <height>0</height>
345 </size>
346 </property>
347 <property stdset="1">
348 <name>text</name>
349 <string>1</string>
350 </property>
351 <property stdset="1">
352 <name>alignment</name>
353 <set>AlignVCenter|AlignRight</set>
354 </property>
355 <property>
356 <name>hAlign</name>
357 </property>
358 </widget>
359 <widget row="3" column="3" >
360 <class>QLabel</class>
361 <property stdset="1">
362 <name>name</name>
363 <cstring>TextLabel5</cstring>
364 </property>
365 <property stdset="1">
366 <name>text</name>
367 <string>sec</string>
368 </property>
369 </widget>
370 <widget row="2" column="0" >
371 <class>QLabel</class>
372 <property stdset="1">
373 <name>name</name>
374 <cstring>TextLabel3</cstring>
375 </property>
376 <property stdset="1">
377 <name>text</name>
378 <string>Flow control</string>
379 </property>
380 </widget>
381 <widget row="2" column="1" rowspan="1" colspan="3" >
382 <class>QCheckBox</class>
383 <property stdset="1">
384 <name>name</name>
385 <cstring>crtscts</cstring>
386 </property>
387 <property stdset="1">
388 <name>text</name>
389 <string>Hardware flow control</string>
390 </property>
391 <property stdset="1">
392 <name>checked</name>
393 <bool>true</bool>
394 </property>
395 </widget>
396 <spacer row="4" column="1" >
397 <property>
398 <name>name</name>
399 <cstring>Spacer5</cstring>
400 </property>
401 <property stdset="1">
402 <name>orientation</name>
403 <enum>Vertical</enum>
404 </property>
405 <property stdset="1">
406 <name>sizeType</name>
407 <enum>Expanding</enum>
408 </property>
409 <property>
410 <name>sizeHint</name>
411 <size>
412 <width>20</width>
413 <height>20</height>
414 </size>
415 </property>
416 </spacer>
417 <widget row="5" column="0" rowspan="1" colspan="4" >
418 <class>QButtonGroup</class>
419 <property stdset="1">
420 <name>name</name>
421 <cstring>dialmode</cstring>
422 </property>
423 <property stdset="1">
424 <name>title</name>
425 <string>Demand Dialing</string>
426 </property>
427 <grid>
428 <property stdset="1">
429 <name>margin</name>
430 <number>11</number>
431 </property>
432 <property stdset="1">
433 <name>spacing</name>
434 <number>6</number>
435 </property>
436 <widget row="0" column="0" rowspan="1" colspan="2" >
437 <class>QRadioButton</class>
438 <property stdset="1">
439 <name>name</name>
440 <cstring>dial_manual</cstring>
441 </property>
442 <property stdset="1">
443 <name>text</name>
444 <string>Manual connect and disconnect</string>
445 </property>
446 </widget>
447 <widget row="3" column="1" >
448 <class>QSpinBox</class>
449 <property stdset="1">
450 <name>name</name>
451 <cstring>idletime</cstring>
452 </property>
453 <property stdset="1">
454 <name>suffix</name>
455 <string> seconds</string>
456 </property>
457 <property stdset="1">
458 <name>maxValue</name>
459 <number>3600</number>
460 </property>
461 <property stdset="1">
462 <name>lineStep</name>
463 <number>30</number>
464 </property>
465 <property stdset="1">
466 <name>value</name>
467 <number>120</number>
468 </property>
469 </widget>
470 <widget row="3" column="0" >
471 <class>QLabel</class>
472 <property stdset="1">
473 <name>name</name>
474 <cstring>TextLabel1_5</cstring>
475 </property>
476 <property stdset="1">
477 <name>sizePolicy</name>
478 <sizepolicy>
479 <hsizetype>7</hsizetype>
480 <vsizetype>1</vsizetype>
481 </sizepolicy>
482 </property>
483 <property stdset="1">
484 <name>text</name>
485 <string>Idle timeout:</string>
486 </property>
487 <property stdset="1">
488 <name>alignment</name>
489 <set>AlignVCenter|AlignRight</set>
490 </property>
491 <property>
492 <name>hAlign</name>
493 </property>
494 </widget>
495 <widget row="2" column="0" rowspan="1" colspan="2" >
496 <class>QRadioButton</class>
497 <property stdset="1">
498 <name>name</name>
499 <cstring>dial_demand</cstring>
500 </property>
501 <property stdset="1">
502 <name>text</name>
503 <string>Automatic connect and disconnect</string>
504 </property>
505 <property stdset="1">
506 <name>checked</name>
507 <bool>true</bool>
508 </property>
509 <property stdset="1">
510 <name>buttonGroupId</name>
511 <number>2</number>
512 </property>
513 </widget>
514 <widget row="1" column="0" rowspan="1" colspan="2" >
515 <class>QRadioButton</class>
516 <property stdset="1">
517 <name>name</name>
518 <cstring>dial_idle</cstring>
519 </property>
520 <property stdset="1">
521 <name>text</name>
522 <string>Manual connect, automatic disconnect</string>
523 </property>
524 <property stdset="1">
525 <name>buttonGroupId</name>
526 <number>1</number>
527 </property>
528 </widget>
529 </grid>
530 </widget>
531 </grid>
532 </widget>
533 <widget>
534 <class>QWidget</class>
535 <property stdset="1">
536 <name>name</name>
537 <cstring>tab</cstring>
538 </property>
539 <attribute>
540 <name>title</name>
541 <string>Network</string>
542 </attribute>
543 <grid>
544 <property stdset="1">
545 <name>margin</name>
546 <number>6</number>
547 </property>
548 <property stdset="1">
549 <name>spacing</name>
550 <number>4</number>
551 </property>
552 <spacer row="4" column="1" >
553 <property>
554 <name>name</name>
555 <cstring>Spacer8</cstring>
556 </property>
557 <property stdset="1">
558 <name>orientation</name>
559 <enum>Vertical</enum>
560 </property>
561 <property stdset="1">
562 <name>sizeType</name>
563 <enum>Expanding</enum>
564 </property>
565 <property>
566 <name>sizeHint</name>
567 <size>
568 <width>20</width>
569 <height>20</height>
570 </size>
571 </property>
572 </spacer>
573 <widget row="2" column="0" >
574 <class>QCheckBox</class>
575 <property stdset="1">
576 <name>name</name>
577 <cstring>usepeerdns</cstring>
578 </property>
579 <property stdset="1">
580 <name>text</name>
581 <string>Auto-detect name servers</string>
582 </property>
583 <property stdset="1">
584 <name>checked</name>
585 <bool>true</bool>
586 </property>
587 </widget>
588 <widget row="1" column="0" rowspan="1" colspan="2" >
589 <class>QGroupBox</class>
590 <property stdset="1">
591 <name>name</name>
592 <cstring>gatewaybox</cstring>
593 </property>
594 <property stdset="1">
595 <name>enabled</name>
596 <bool>false</bool>
597 </property>
598 <property stdset="1">
599 <name>title</name>
600 <string></string>
601 </property>
602 <hbox>
603 <property stdset="1">
604 <name>margin</name>
605 <number>11</number>
606 </property>
607 <property stdset="1">
608 <name>spacing</name>
609 <number>6</number>
610 </property>
611 <widget>
612 <class>QLabel</class>
613 <property stdset="1">
614 <name>name</name>
615 <cstring>TextLabel4_2</cstring>
616 </property>
617 <property stdset="1">
618 <name>text</name>
619 <string>Gateway</string>
620 </property>
621 </widget>
622 <widget>
623 <class>QLineEdit</class>
624 <property stdset="1">
625 <name>name</name>
626 <cstring>gateway</cstring>
627 </property>
628 <property stdset="1">
629 <name>text</name>
630 <string></string>
631 </property>
632 </widget>
633 </hbox>
634 </widget>
635 <widget row="0" column="0" rowspan="1" colspan="2" >
636 <class>QCheckBox</class>
637 <property stdset="1">
638 <name>name</name>
639 <cstring>defaultroute</cstring>
640 </property>
641 <property stdset="1">
642 <name>text</name>
643 <string>Auto-detect routing</string>
644 </property>
645 <property stdset="1">
646 <name>checked</name>
647 <bool>true</bool>
648 </property>
649 </widget>
650 <widget row="3" column="0" rowspan="1" colspan="2" >
651 <class>QGroupBox</class>
652 <property stdset="1">
653 <name>name</name>
654 <cstring>dnsbox</cstring>
655 </property>
656 <property stdset="1">
657 <name>enabled</name>
658 <bool>false</bool>
659 </property>
660 <property stdset="1">
661 <name>title</name>
662 <string></string>
663 </property>
664 <grid>
665 <property stdset="1">
666 <name>margin</name>
667 <number>11</number>
668 </property>
669 <property stdset="1">
670 <name>spacing</name>
671 <number>6</number>
672 </property>
673 <widget row="0" column="1" >
674 <class>QLineEdit</class>
675 <property stdset="1">
676 <name>name</name>
677 <cstring>dns1</cstring>
678 </property>
679 <property stdset="1">
680 <name>text</name>
681 <string></string>
682 </property>
683 </widget>
684 <widget row="1" column="1" >
685 <class>QLineEdit</class>
686 <property stdset="1">
687 <name>name</name>
688 <cstring>dns2</cstring>
689 </property>
690 <property stdset="1">
691 <name>text</name>
692 <string></string>
693 </property>
694 </widget>
695 <widget row="0" column="0" >
696 <class>QLabel</class>
697 <property stdset="1">
698 <name>name</name>
699 <cstring>TextLabel1_2_3</cstring>
700 </property>
701 <property stdset="1">
702 <name>text</name>
703 <string>First DNS</string>
704 </property>
705 </widget>
706 <widget row="1" column="0" >
707 <class>QLabel</class>
708 <property stdset="1">
709 <name>name</name>
710 <cstring>TextLabel1_2_2_2</cstring>
711 </property>
712 <property stdset="1">
713 <name>text</name>
714 <string>Second DNS</string>
715 </property>
716 </widget>
717 </grid>
718 </widget>
719 </grid>
720 </widget>
721 </widget>
722 </vbox>
723</widget>
724<connections>
725 <connection>
726 <sender>defaultroute</sender>
727 <signal>toggled(bool)</signal>
728 <receiver>gatewaybox</receiver>
729 <slot>setDisabled(bool)</slot>
730 </connection>
731 <connection>
732 <sender>usepeerdns</sender>
733 <signal>toggled(bool)</signal>
734 <receiver>dnsbox</receiver>
735 <slot>setDisabled(bool)</slot>
736 </connection>
737 <connection>
738 <sender>connectdelay</sender>
739 <signal>valueChanged(int)</signal>
740 <receiver>connectdelay_text</receiver>
741 <slot>setNum(int)</slot>
742 </connection>
743 <connection>
744 <sender>dial_manual</sender>
745 <signal>toggled(bool)</signal>
746 <receiver>idletime</receiver>
747 <slot>setDisabled(bool)</slot>
748 </connection>
749</connections>
750<tabstops>
751 <tabstop>TabWidget2</tabstop>
752 <tabstop>acname</tabstop>
753 <tabstop>username</tabstop>
754 <tabstop>password</tabstop>
755 <tabstop>phone</tabstop>
756 <tabstop>atdial</tabstop>
757 <tabstop>speed</tabstop>
758 <tabstop>crtscts</tabstop>
759 <tabstop>connectdelay</tabstop>
760 <tabstop>dial_manual</tabstop>
761 <tabstop>dial_idle</tabstop>
762 <tabstop>dial_demand</tabstop>
763 <tabstop>idletime</tabstop>
764 <tabstop>defaultroute</tabstop>
765 <tabstop>gateway</tabstop>
766 <tabstop>usepeerdns</tabstop>
767 <tabstop>dns1</tabstop>
768 <tabstop>dns2</tabstop>
769</tabstops>
770</UI>