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
@@ -3,11 +3,8 @@
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>
@@ -28,8 +25,8 @@
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
@@ -46,10 +43,32 @@ MainWindowImp::MainWindowImp(QWidget *parent, const char *name) : MainWindow(par
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)
@@ -65,8 +84,8 @@ MainWindowImp::MainWindowImp(QWidget *parent, const char *name) : MainWindow(par
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();
@@ -100,6 +119,72 @@ MainWindowImp::~MainWindowImp(){
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
@@ -183,10 +268,10 @@ void MainWindowImp::addClicked(){
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 }
@@ -281,103 +366,6 @@ void MainWindowImp::informationClicked(){
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 */
@@ -495,7 +483,7 @@ void MainWindowImp::removeProfile(){
495 } 483 }
496 } 484 }
497 interfaces.write(); 485 interfaces.write();
498 break; 486 break;
499 } 487 }
500 } 488 }
501 } 489 }
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
@@ -18,14 +18,13 @@ public:
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();
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,9 +1,9 @@
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
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
@@ -3,11 +3,8 @@
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>
@@ -28,8 +25,8 @@
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
@@ -46,10 +43,32 @@ MainWindowImp::MainWindowImp(QWidget *parent, const char *name) : MainWindow(par
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)
@@ -65,8 +84,8 @@ MainWindowImp::MainWindowImp(QWidget *parent, const char *name) : MainWindow(par
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();
@@ -100,6 +119,72 @@ MainWindowImp::~MainWindowImp(){
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
@@ -183,10 +268,10 @@ void MainWindowImp::addClicked(){
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 }
@@ -281,103 +366,6 @@ void MainWindowImp::informationClicked(){
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 */
@@ -495,7 +483,7 @@ void MainWindowImp::removeProfile(){
495 } 483 }
496 } 484 }
497 interfaces.write(); 485 interfaces.write();
498 break; 486 break;
499 } 487 }
500 } 488 }
501 } 489 }
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
@@ -18,14 +18,13 @@ public:
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();
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,9 +1,9 @@
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
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>