-rw-r--r-- | noncore/net/networksetup/kprocctrl.cpp | 267 | ||||
-rw-r--r-- | noncore/net/networksetup/kprocctrl.h | 120 | ||||
-rw-r--r-- | noncore/net/networksetup/kprocess.cpp | 919 | ||||
-rw-r--r-- | noncore/net/networksetup/kprocess.h | 804 | ||||
-rw-r--r-- | noncore/net/networksetup/mainwindowimp.cpp | 208 | ||||
-rw-r--r-- | noncore/net/networksetup/mainwindowimp.h | 5 | ||||
-rw-r--r-- | noncore/net/networksetup/networksetup.pro | 6 | ||||
-rw-r--r-- | noncore/net/networksetup/ppp/.cvsignore | 23 | ||||
-rw-r--r-- | noncore/net/networksetup/ppp/ppp.ui | 770 | ||||
-rw-r--r-- | noncore/settings/networksettings/kprocctrl.cpp | 267 | ||||
-rw-r--r-- | noncore/settings/networksettings/kprocctrl.h | 120 | ||||
-rw-r--r-- | noncore/settings/networksettings/kprocess.cpp | 919 | ||||
-rw-r--r-- | noncore/settings/networksettings/kprocess.h | 804 | ||||
-rw-r--r-- | noncore/settings/networksettings/mainwindowimp.cpp | 208 | ||||
-rw-r--r-- | noncore/settings/networksettings/mainwindowimp.h | 5 | ||||
-rw-r--r-- | noncore/settings/networksettings/networksetup.pro | 6 | ||||
-rw-r--r-- | noncore/settings/networksettings/ppp/.cvsignore | 23 | ||||
-rw-r--r-- | noncore/settings/networksettings/ppp/ppp.ui | 770 |
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 | |||
44 | KProcessController *KProcessController::theKProcessController = 0; | ||
45 | |||
46 | struct sigaction KProcessController::oldChildHandlerData; | ||
47 | bool KProcessController::handlerSet = false; | ||
48 | |||
49 | KProcessController::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 | |||
69 | void 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 | |||
99 | void 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 | ||
109 | void 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 | |||
119 | void 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 | ||
134 | struct waitdata | ||
135 | { | ||
136 | pid_t pid; | ||
137 | int status; | ||
138 | }; | ||
139 | |||
140 | void 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 | |||
185 | void 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 | ||
236 | void 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 | |||
253 | KProcessController::~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 | |||
36 | class KProcessControllerPrivate; | ||
37 | class 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 | */ | ||
50 | class KProcessController : public QObject | ||
51 | { | ||
52 | Q_OBJECT | ||
53 | |||
54 | public: | ||
55 | KProcessController(); | ||
56 | ~KProcessController(); | ||
57 | //CC: WARNING! Destructor Not virtual (but you don't derive classes from this anyhow...) | ||
58 | |||
59 | public: | ||
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(); | ||
102 | private: | ||
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 | |||
80 | class KProcessPrivate { | ||
81 | public: | ||
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 | |||
92 | KProcess::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 | |||
119 | void | ||
120 | KProcess::setEnvironment(const QString &name, const QString &value) | ||
121 | { | ||
122 | if (!d) | ||
123 | d = new KProcessPrivate; | ||
124 | d->env.insert(name, value); | ||
125 | } | ||
126 | |||
127 | void | ||
128 | KProcess::setWorkingDirectory(const QString &dir) | ||
129 | { | ||
130 | if (!d) | ||
131 | d = new KProcessPrivate; | ||
132 | d->wd = dir; | ||
133 | } | ||
134 | |||
135 | void | ||
136 | KProcess::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 | |||
149 | void | ||
150 | KProcess::setRunPrivileged(bool keepPrivileges) | ||
151 | { | ||
152 | keepPrivs = keepPrivileges; | ||
153 | } | ||
154 | |||
155 | bool | ||
156 | KProcess::runPrivileged() const | ||
157 | { | ||
158 | return keepPrivs; | ||
159 | } | ||
160 | |||
161 | |||
162 | KProcess::~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 | |||
185 | void 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 | |||
198 | bool 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 | |||
211 | KProcess &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 | |||
219 | KProcess &KProcess::operator<<(const QCString& arg) | ||
220 | { | ||
221 | return operator<< (arg.data()); | ||
222 | } | ||
223 | |||
224 | KProcess &KProcess::operator<<(const char* arg) | ||
225 | { | ||
226 | arguments.append(arg); | ||
227 | return *this; | ||
228 | } | ||
229 | |||
230 | KProcess &KProcess::operator<<(const QString& arg) | ||
231 | { | ||
232 | arguments.append(QFile::encodeName(arg)); | ||
233 | return *this; | ||
234 | } | ||
235 | |||
236 | void KProcess::clearArguments() | ||
237 | { | ||
238 | arguments.clear(); | ||
239 | } | ||
240 | |||
241 | bool 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 | |||
408 | bool 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 | |||
420 | bool KProcess::isRunning() const | ||
421 | { | ||
422 | return runs; | ||
423 | } | ||
424 | |||
425 | |||
426 | |||
427 | pid_t KProcess::pid() const | ||
428 | { | ||
429 | return pid_; | ||
430 | } | ||
431 | |||
432 | |||
433 | |||
434 | bool KProcess::normalExit() const | ||
435 | { | ||
436 | int _status = status; | ||
437 | return (pid_ != 0) && (!runs) && (WIFEXITED((_status))); | ||
438 | } | ||
439 | |||
440 | |||
441 | |||
442 | int KProcess::exitStatus() const | ||
443 | { | ||
444 | int _status = status; | ||
445 | return WEXITSTATUS((_status)); | ||
446 | } | ||
447 | |||
448 | |||
449 | |||
450 | bool 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 | |||
472 | void KProcess::suspend() | ||
473 | { | ||
474 | if ((communication & Stdout) && outnot) | ||
475 | outnot->setEnabled(false); | ||
476 | } | ||
477 | |||
478 | void KProcess::resume() | ||
479 | { | ||
480 | if ((communication & Stdout) && outnot) | ||
481 | outnot->setEnabled(true); | ||
482 | } | ||
483 | |||
484 | bool 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 | |||
499 | bool 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 | |||
514 | bool 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 | |||
536 | void KProcess::slotChildOutput(int fdno) | ||
537 | { | ||
538 | if (!childOutput(fdno)) | ||
539 | closeStdout(); | ||
540 | } | ||
541 | |||
542 | |||
543 | void KProcess::slotChildError(int fdno) | ||
544 | { | ||
545 | if (!childError(fdno)) | ||
546 | closeStderr(); | ||
547 | } | ||
548 | |||
549 | |||
550 | void 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 | |||
568 | void 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 | |||
587 | int 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 | |||
611 | int 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 | |||
625 | int 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 | |||
646 | int 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 | |||
694 | int 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 | |||
737 | void 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 | |||
826 | void 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 | |||
836 | QString 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 | |||
846 | QCString 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 | |||
857 | bool 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 | |||
888 | void KProcess::virtual_hook( int, void* ) | ||
889 | { /*BASE::virtual_hook( id, data );*/ } | ||
890 | |||
891 | |||
892 | /////////////////////////// | ||
893 | // CC: Class KShellProcess | ||
894 | /////////////////////////// | ||
895 | |||
896 | KShellProcess::KShellProcess(const char *shellname): | ||
897 | KProcess() | ||
898 | { | ||
899 | setUseShell(true, shellname); | ||
900 | } | ||
901 | |||
902 | |||
903 | KShellProcess::~KShellProcess() { | ||
904 | } | ||
905 | |||
906 | QString KShellProcess::quote(const QString &arg) | ||
907 | { | ||
908 | return KProcess::quote(arg); | ||
909 | } | ||
910 | |||
911 | bool KShellProcess::start(RunMode runmode, Communication comm) | ||
912 | { | ||
913 | return KProcess::start(runmode, comm); | ||
914 | } | ||
915 | |||
916 | void 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 | |||
40 | class QSocketNotifier; | ||
41 | class 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 | **/ | ||
146 | class KProcess : public QObject | ||
147 | { | ||
148 | Q_OBJECT | ||
149 | |||
150 | public: | ||
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 | |||
454 | signals: | ||
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 | |||
521 | protected 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 | |||
545 | protected: | ||
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 | |||
708 | private: | ||
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 | |||
733 | protected: | ||
734 | virtual void virtual_hook( int id, void* data ); | ||
735 | private: | ||
736 | KProcessPrivate *d; | ||
737 | }; | ||
738 | |||
739 | class 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 | */ | ||
752 | class KShellProcess: public KProcess | ||
753 | { | ||
754 | Q_OBJECT | ||
755 | |||
756 | public: | ||
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 | |||
787 | private: | ||
788 | |||
789 | QCString shell; | ||
790 | |||
791 | // Disallow assignment and copy-construction | ||
792 | KShellProcess( const KShellProcess& ); | ||
793 | KShellProcess& operator= ( const KShellProcess& ); | ||
794 | |||
795 | protected: | ||
796 | virtual void virtual_hook( int id, void* data ); | ||
797 | private: | ||
798 | KShellProcessPrivate *d; | ||
799 | }; | ||
800 | |||
801 | |||
802 | |||
803 | #endif | ||
804 | |||
diff --git a/noncore/net/networksetup/mainwindowimp.cpp b/noncore/net/networksetup/mainwindowimp.cpp index 7261c58..48ef9b3 100644 --- a/noncore/net/networksetup/mainwindowimp.cpp +++ b/noncore/net/networksetup/mainwindowimp.cpp | |||
@@ -1,537 +1,525 @@ | |||
1 | #include "mainwindowimp.h" | 1 | #include "mainwindowimp.h" |
2 | #include "addconnectionimp.h" | 2 | #include "addconnectionimp.h" |
3 | #include "interfaceinformationimp.h" | 3 | #include "interfaceinformationimp.h" |
4 | #include "interfacesetupimp.h" | 4 | #include "interfacesetupimp.h" |
5 | #include "interfaces.h" | 5 | #include "interfaces.h" |
6 | |||
7 | #include "module.h" | 6 | #include "module.h" |
8 | 7 | ||
9 | #include "kprocess.h" | ||
10 | |||
11 | #include <qpushbutton.h> | 8 | #include <qpushbutton.h> |
12 | #include <qlistbox.h> | 9 | #include <qlistbox.h> |
13 | #include <qlineedit.h> | 10 | #include <qlineedit.h> |
14 | #include <qlistview.h> | 11 | #include <qlistview.h> |
15 | #include <qheader.h> | 12 | #include <qheader.h> |
16 | #include <qlabel.h> | 13 | #include <qlabel.h> |
17 | 14 | ||
18 | #include <qmainwindow.h> | 15 | #include <qmainwindow.h> |
19 | #include <qmessagebox.h> | 16 | #include <qmessagebox.h> |
20 | 17 | ||
21 | #include <qpe/config.h> | 18 | #include <qpe/config.h> |
22 | #include <qpe/qlibrary.h> | 19 | #include <qpe/qlibrary.h> |
23 | #include <qpe/resource.h> | 20 | #include <qpe/resource.h> |
24 | #include <qpe/qpeapplication.h> | 21 | #include <qpe/qpeapplication.h> |
25 | 22 | ||
26 | #include <qlist.h> | 23 | #include <qlist.h> |
27 | #include <qdir.h> | 24 | #include <qdir.h> |
28 | #include <qfile.h> | 25 | #include <qfile.h> |
29 | #include <qtextstream.h> | 26 | #include <qtextstream.h> |
30 | 27 | ||
31 | #define TEMP_ALL "/tmp/ifconfig-a" | 28 | #include <net/if.h> |
32 | #define TEMP_UP "/tmp/ifconfig" | 29 | #include <sys/ioctl.h> |
33 | 30 | ||
34 | #define DEFAULT_SCHEME "/var/lib/pcmcia/scheme" | 31 | #define DEFAULT_SCHEME "/var/lib/pcmcia/scheme" |
35 | 32 | ||
36 | MainWindowImp::MainWindowImp(QWidget *parent, const char *name) : MainWindow(parent, name, true), advancedUserMode(false){ | 33 | MainWindowImp::MainWindowImp(QWidget *parent, const char *name) : MainWindow(parent, name, true), advancedUserMode(false){ |
37 | connect(addConnectionButton, SIGNAL(clicked()), this, SLOT(addClicked())); | 34 | connect(addConnectionButton, SIGNAL(clicked()), this, SLOT(addClicked())); |
38 | connect(removeConnectionButton, SIGNAL(clicked()), this, SLOT(removeClicked())); | 35 | connect(removeConnectionButton, SIGNAL(clicked()), this, SLOT(removeClicked())); |
39 | connect(informationConnectionButton, SIGNAL(clicked()), this, SLOT(informationClicked())); | 36 | connect(informationConnectionButton, SIGNAL(clicked()), this, SLOT(informationClicked())); |
40 | connect(configureConnectionButton, SIGNAL(clicked()), this, SLOT(configureClicked())); | 37 | connect(configureConnectionButton, SIGNAL(clicked()), this, SLOT(configureClicked())); |
41 | 38 | ||
42 | connect(newProfileButton, SIGNAL(clicked()), this, SLOT(addProfile())); | 39 | connect(newProfileButton, SIGNAL(clicked()), this, SLOT(addProfile())); |
43 | connect(removeProfileButton, SIGNAL(clicked()), this, SLOT(removeProfile())); | 40 | connect(removeProfileButton, SIGNAL(clicked()), this, SLOT(removeProfile())); |
44 | connect(setCurrentProfileButton, SIGNAL(clicked()), this, SLOT(changeProfile())); | 41 | connect(setCurrentProfileButton, SIGNAL(clicked()), this, SLOT(changeProfile())); |
45 | 42 | ||
46 | connect(newProfile, SIGNAL(textChanged(const QString&)), this, SLOT(newProfileChanged(const QString&))); | 43 | connect(newProfile, SIGNAL(textChanged(const QString&)), this, SLOT(newProfileChanged(const QString&))); |
47 | // Load connections. | 44 | // Load connections. |
48 | loadModules(QPEApplication::qpeDir() + "/plugins/networksetup"); | 45 | loadModules(QPEApplication::qpeDir() + "/plugins/networksetup"); |
49 | getInterfaceList(); | 46 | getAllInterfaces(); |
47 | |||
48 | Interfaces i; | ||
49 | QStringList list = i.getInterfaceList(); | ||
50 | QMap<QString, Interface*>::Iterator it; | ||
51 | for ( QStringList::Iterator ni = list.begin(); ni != list.end(); ++ni ) { | ||
52 | bool found = false; | ||
53 | for( it = interfaceNames.begin(); it != interfaceNames.end(); ++it ){ | ||
54 | if(it.key() == (*ni)) | ||
55 | found = true; | ||
56 | } | ||
57 | if(!found){ | ||
58 | if(!(*ni).contains("_")){ | ||
59 | Interface *i = new Interface(this, *ni, false); | ||
60 | i->setAttached(false); | ||
61 | i->setHardwareName("Disconnected"); | ||
62 | interfaceNames.insert(i->getInterfaceName(), i); | ||
63 | updateInterface(i); | ||
64 | connect(i, SIGNAL(updateInterface(Interface *)), this, SLOT(updateInterface(Interface *))); | ||
65 | } | ||
66 | } | ||
67 | } | ||
68 | |||
69 | //getInterfaceList(); | ||
50 | connectionList->header()->hide(); | 70 | connectionList->header()->hide(); |
51 | 71 | ||
52 | |||
53 | Config cfg("NetworkSetup"); | 72 | Config cfg("NetworkSetup"); |
54 | profiles = QStringList::split(" ", cfg.readEntry("Profiles", "All")); | 73 | profiles = QStringList::split(" ", cfg.readEntry("Profiles", "All")); |
55 | for ( QStringList::Iterator it = profiles.begin(); it != profiles.end(); ++it) | 74 | for ( QStringList::Iterator it = profiles.begin(); it != profiles.end(); ++it) |
56 | profilesList->insertItem((*it)); | 75 | profilesList->insertItem((*it)); |
57 | currentProfileLabel->setText(cfg.readEntry("CurrentProfile", "All")); | 76 | currentProfileLabel->setText(cfg.readEntry("CurrentProfile", "All")); |
58 | advancedUserMode = cfg.readBoolEntry("AdvancedUserMode", false); | 77 | advancedUserMode = cfg.readBoolEntry("AdvancedUserMode", false); |
59 | scheme = cfg.readEntry("SchemeFile", DEFAULT_SCHEME); | 78 | scheme = cfg.readEntry("SchemeFile", DEFAULT_SCHEME); |
60 | 79 | ||
61 | QFile file(scheme); | 80 | QFile file(scheme); |
62 | if ( file.open(IO_ReadOnly) ) { // file opened successfully | 81 | if ( file.open(IO_ReadOnly) ) { // file opened successfully |
63 | QTextStream stream( &file ); // use a text stream | 82 | QTextStream stream( &file ); // use a text stream |
64 | while ( !stream.eof() ) { // until end of file... | 83 | while ( !stream.eof() ) { // until end of file... |
65 | QString line = stream.readLine(); // line of text excluding '\n' | 84 | QString line = stream.readLine(); // line of text excluding '\n' |
66 | if(line.contains("SCHEME")){ | 85 | if(line.contains("SCHEME")){ |
67 | line = line.mid(7, line.length()); | 86 | line = line.mid(7, line.length()); |
68 | currentProfileLabel->setText(line); | 87 | currentProfileLabel->setText(line); |
69 | break; | 88 | break; |
70 | } | 89 | } |
71 | } | 90 | } |
72 | file.close(); | 91 | file.close(); |
73 | } | 92 | } |
74 | } | 93 | } |
75 | 94 | ||
76 | /** | 95 | /** |
77 | * Deconstructor. Save profiles. Delete loaded libraries. | 96 | * Deconstructor. Save profiles. Delete loaded libraries. |
78 | */ | 97 | */ |
79 | MainWindowImp::~MainWindowImp(){ | 98 | MainWindowImp::~MainWindowImp(){ |
80 | // Save profiles. | 99 | // Save profiles. |
81 | Config cfg("NetworkSetup"); | 100 | Config cfg("NetworkSetup"); |
82 | cfg.setGroup("General"); | 101 | cfg.setGroup("General"); |
83 | cfg.writeEntry("Profiles", profiles.join(" ")); | 102 | cfg.writeEntry("Profiles", profiles.join(" ")); |
84 | 103 | ||
85 | // Delete all interfaces that don't have owners. | 104 | // Delete all interfaces that don't have owners. |
86 | QMap<Interface*, QListViewItem*>::Iterator iIt; | 105 | QMap<Interface*, QListViewItem*>::Iterator iIt; |
87 | for( iIt = items.begin(); iIt != items.end(); ++iIt ){ | 106 | for( iIt = items.begin(); iIt != items.end(); ++iIt ){ |
88 | if(iIt.key()->getModuleOwner() == NULL) | 107 | if(iIt.key()->getModuleOwner() == NULL) |
89 | delete iIt.key(); | 108 | delete iIt.key(); |
90 | } | 109 | } |
91 | 110 | ||
92 | // Delete Modules and Libraries | 111 | // Delete Modules and Libraries |
93 | QMap<Module*, QLibrary*>::Iterator it; | 112 | QMap<Module*, QLibrary*>::Iterator it; |
94 | for( it = libraries.begin(); it != libraries.end(); ++it ){ | 113 | for( it = libraries.begin(); it != libraries.end(); ++it ){ |
95 | delete it.key(); | 114 | delete it.key(); |
96 | // I wonder why I can't delete the libraries | 115 | // I wonder why I can't delete the libraries |
97 | // What fucking shit this is. | 116 | // What fucking shit this is. |
98 | //delete it.data(); | 117 | //delete it.data(); |
99 | } | 118 | } |
100 | } | 119 | } |
101 | 120 | ||
102 | /** | 121 | /** |
122 | * Query the kernel for all of the interfaces. | ||
123 | */ | ||
124 | void MainWindowImp::getAllInterfaces(){ | ||
125 | int sockfd = socket(AF_INET, SOCK_DGRAM, 0); | ||
126 | if(sockfd == -1) | ||
127 | return; | ||
128 | |||
129 | char buf[8*1024]; | ||
130 | struct ifconf ifc; | ||
131 | ifc.ifc_len = sizeof(buf); | ||
132 | ifc.ifc_req = (struct ifreq *) buf; | ||
133 | int result=ioctl(sockfd, SIOCGIFCONF, &ifc); | ||
134 | |||
135 | for (char* ptr = buf; ptr < buf + ifc.ifc_len; ){ | ||
136 | struct ifreq *ifr =(struct ifreq *) ptr; | ||
137 | int len = sizeof(struct sockaddr); | ||
138 | #ifdef HAVE_SOCKADDR_SA_LEN | ||
139 | if (ifr->ifr_addr.sa_len > len) | ||
140 | len = ifr->ifr_addr.sa_len; /* length > 16 */ | ||
141 | #endif | ||
142 | ptr += sizeof(ifr->ifr_name) + len; /* for next one in buffer */ | ||
143 | |||
144 | int flags; | ||
145 | struct sockaddr_in *sinptr; | ||
146 | Interface *i = NULL; | ||
147 | switch (ifr->ifr_addr.sa_family){ | ||
148 | case AF_INET: | ||
149 | sinptr = (struct sockaddr_in *) &ifr->ifr_addr; | ||
150 | flags=0; | ||
151 | |||
152 | struct ifreq ifcopy; | ||
153 | ifcopy=*ifr; | ||
154 | result=ioctl(sockfd,SIOCGIFFLAGS,&ifcopy); | ||
155 | flags=ifcopy.ifr_flags; | ||
156 | i = new Interface(this, ifr->ifr_name, false); | ||
157 | i->setAttached(true); | ||
158 | if ((flags & IFF_UP) == IFF_UP) | ||
159 | i->setStatus(true); | ||
160 | else | ||
161 | i->setStatus(false); | ||
162 | |||
163 | if ((flags & IFF_BROADCAST) == IFF_BROADCAST) | ||
164 | i->setHardwareName("Ethernet"); | ||
165 | else if ((flags & IFF_POINTOPOINT) == IFF_POINTOPOINT) | ||
166 | i->setHardwareName("Point to Point"); | ||
167 | else if ((flags & IFF_MULTICAST) == IFF_MULTICAST) | ||
168 | i->setHardwareName("Multicast"); | ||
169 | else if ((flags & IFF_LOOPBACK) == IFF_LOOPBACK) | ||
170 | i->setHardwareName("Loopback"); | ||
171 | else | ||
172 | i->setHardwareName("Unknown"); | ||
173 | |||
174 | interfaceNames.insert(i->getInterfaceName(), i); | ||
175 | updateInterface(i); | ||
176 | connect(i, SIGNAL(updateInterface(Interface *)), this, SLOT(updateInterface(Interface *))); | ||
177 | break; | ||
178 | |||
179 | default: | ||
180 | qDebug(ifr->ifr_name); | ||
181 | qDebug(QString("%1").arg(ifr->ifr_addr.sa_family).latin1()); | ||
182 | break; | ||
183 | } | ||
184 | } | ||
185 | } | ||
186 | |||
187 | /** | ||
103 | * Load all modules that are found in the path | 188 | * Load all modules that are found in the path |
104 | * @param path a directory that is scaned for any plugins that can be loaded | 189 | * @param path a directory that is scaned for any plugins that can be loaded |
105 | * and attempts to load them | 190 | * and attempts to load them |
106 | */ | 191 | */ |
107 | void MainWindowImp::loadModules(QString path){ | 192 | void MainWindowImp::loadModules(QString path){ |
108 | //qDebug(path.latin1()); | 193 | //qDebug(path.latin1()); |
109 | QDir d(path); | 194 | QDir d(path); |
110 | if(!d.exists()) | 195 | if(!d.exists()) |
111 | return; | 196 | return; |
112 | 197 | ||
113 | // Don't want sym links | 198 | // Don't want sym links |
114 | d.setFilter( QDir::Files | QDir::NoSymLinks ); | 199 | d.setFilter( QDir::Files | QDir::NoSymLinks ); |
115 | const QFileInfoList *list = d.entryInfoList(); | 200 | const QFileInfoList *list = d.entryInfoList(); |
116 | QFileInfoListIterator it( *list ); | 201 | QFileInfoListIterator it( *list ); |
117 | QFileInfo *fi; | 202 | QFileInfo *fi; |
118 | while ( (fi=it.current()) ) { | 203 | while ( (fi=it.current()) ) { |
119 | if(fi->fileName().contains(".so")){ | 204 | if(fi->fileName().contains(".so")){ |
120 | loadPlugin(path + "/" + fi->fileName()); | 205 | loadPlugin(path + "/" + fi->fileName()); |
121 | } | 206 | } |
122 | ++it; | 207 | ++it; |
123 | } | 208 | } |
124 | } | 209 | } |
125 | 210 | ||
126 | /** | 211 | /** |
127 | * Attempt to load a function and resolve a function. | 212 | * Attempt to load a function and resolve a function. |
128 | * @param pluginFileName - the name of the file in which to attempt to load | 213 | * @param pluginFileName - the name of the file in which to attempt to load |
129 | * @param resolveString - function pointer to resolve | 214 | * @param resolveString - function pointer to resolve |
130 | * @return pointer to the function with name resolveString or NULL | 215 | * @return pointer to the function with name resolveString or NULL |
131 | */ | 216 | */ |
132 | Module* MainWindowImp::loadPlugin(QString pluginFileName, QString resolveString){ | 217 | Module* MainWindowImp::loadPlugin(QString pluginFileName, QString resolveString){ |
133 | //qDebug(QString("MainWindowImp::loadPlugin: %1").arg(pluginFileName).latin1()); | 218 | //qDebug(QString("MainWindowImp::loadPlugin: %1").arg(pluginFileName).latin1()); |
134 | QLibrary *lib = new QLibrary(pluginFileName); | 219 | QLibrary *lib = new QLibrary(pluginFileName); |
135 | void *functionPointer = lib->resolve(resolveString); | 220 | void *functionPointer = lib->resolve(resolveString); |
136 | if( !functionPointer ){ | 221 | if( !functionPointer ){ |
137 | qDebug(QString("MainWindowImp: File: %1 is not a plugin, but though was.").arg(pluginFileName).latin1()); | 222 | qDebug(QString("MainWindowImp: File: %1 is not a plugin, but though was.").arg(pluginFileName).latin1()); |
138 | delete lib; | 223 | delete lib; |
139 | return NULL; | 224 | return NULL; |
140 | } | 225 | } |
141 | 226 | ||
142 | // Try to get an object. | 227 | // Try to get an object. |
143 | Module *object = ((Module* (*)()) functionPointer)(); | 228 | Module *object = ((Module* (*)()) functionPointer)(); |
144 | if(object == NULL){ | 229 | if(object == NULL){ |
145 | qDebug("MainWindowImp: Couldn't create object, but did load library!"); | 230 | qDebug("MainWindowImp: Couldn't create object, but did load library!"); |
146 | delete lib; | 231 | delete lib; |
147 | return NULL; | 232 | return NULL; |
148 | } | 233 | } |
149 | 234 | ||
150 | // Store for deletion later | 235 | // Store for deletion later |
151 | libraries.insert(object, lib); | 236 | libraries.insert(object, lib); |
152 | return object; | 237 | return object; |
153 | } | 238 | } |
154 | 239 | ||
155 | /** | 240 | /** |
156 | * The Add button was clicked. Bring up the add dialog and if OK is hit | 241 | * The Add button was clicked. Bring up the add dialog and if OK is hit |
157 | * load the plugin and append it to the list | 242 | * load the plugin and append it to the list |
158 | */ | 243 | */ |
159 | void MainWindowImp::addClicked(){ | 244 | void MainWindowImp::addClicked(){ |
160 | QMap<Module*, QLibrary*>::Iterator it; | 245 | QMap<Module*, QLibrary*>::Iterator it; |
161 | QMap<QString, QString> list; | 246 | QMap<QString, QString> list; |
162 | QMap<QString, Module*> newInterfaceOwners; | 247 | QMap<QString, Module*> newInterfaceOwners; |
163 | //list.insert("USB (PPP) / (ADD_TEST)", "A dialup connection over the USB port"); | 248 | //list.insert("USB (PPP) / (ADD_TEST)", "A dialup connection over the USB port"); |
164 | //list.insert("IrDa (PPP) / (ADD_TEST)", "A dialup connection over the IdDa port"); | 249 | //list.insert("IrDa (PPP) / (ADD_TEST)", "A dialup connection over the IdDa port"); |
165 | for( it = libraries.begin(); it != libraries.end(); ++it ){ | 250 | for( it = libraries.begin(); it != libraries.end(); ++it ){ |
166 | if(it.key()){ | 251 | if(it.key()){ |
167 | (it.key())->possibleNewInterfaces(list); | 252 | (it.key())->possibleNewInterfaces(list); |
168 | } | 253 | } |
169 | } | 254 | } |
170 | // See if the list has anything that we can add. | 255 | // See if the list has anything that we can add. |
171 | if(list.count() == 0){ | 256 | if(list.count() == 0){ |
172 | QMessageBox::information(this, "Sorry", "Nothing to add.", QMessageBox::Ok); | 257 | QMessageBox::information(this, "Sorry", "Nothing to add.", QMessageBox::Ok); |
173 | return; | 258 | return; |
174 | } | 259 | } |
175 | AddConnectionImp addNewConnection(this, "AddConnectionImp", true); | 260 | AddConnectionImp addNewConnection(this, "AddConnectionImp", true); |
176 | addNewConnection.addConnections(list); | 261 | addNewConnection.addConnections(list); |
177 | addNewConnection.showMaximized(); | 262 | addNewConnection.showMaximized(); |
178 | if(QDialog::Accepted == addNewConnection.exec()){ | 263 | if(QDialog::Accepted == addNewConnection.exec()){ |
179 | QListViewItem *item = addNewConnection.registeredServicesList->currentItem(); | 264 | QListViewItem *item = addNewConnection.registeredServicesList->currentItem(); |
180 | if(!item) | 265 | if(!item) |
181 | return; | 266 | return; |
182 | 267 | ||
183 | for( it = libraries.begin(); it != libraries.end(); ++it ){ | 268 | for( it = libraries.begin(); it != libraries.end(); ++it ){ |
184 | if(it.key()){ | 269 | if(it.key()){ |
185 | Interface *i = (it.key())->addNewInterface(item->text(0)); | 270 | Interface *i = (it.key())->addNewInterface(item->text(0)); |
186 | if(i){ | 271 | if(i){ |
187 | interfaceNames.insert(i->getInterfaceName(), i); | 272 | interfaceNames.insert(i->getInterfaceName(), i); |
188 | updateInterface(i); | 273 | updateInterface(i); |
189 | } | 274 | } |
190 | } | 275 | } |
191 | } | 276 | } |
192 | } | 277 | } |
193 | } | 278 | } |
194 | 279 | ||
195 | /** | 280 | /** |
196 | * Prompt the user to see if they really want to do this. | 281 | * Prompt the user to see if they really want to do this. |
197 | * If they do then remove from the list and unload. | 282 | * If they do then remove from the list and unload. |
198 | */ | 283 | */ |
199 | void MainWindowImp::removeClicked(){ | 284 | void MainWindowImp::removeClicked(){ |
200 | QListViewItem *item = connectionList->currentItem(); | 285 | QListViewItem *item = connectionList->currentItem(); |
201 | if(!item) { | 286 | if(!item) { |
202 | QMessageBox::information(this, "Sorry","Please select an interface First.", QMessageBox::Ok); | 287 | QMessageBox::information(this, "Sorry","Please select an interface First.", QMessageBox::Ok); |
203 | return; | 288 | return; |
204 | } | 289 | } |
205 | 290 | ||
206 | Interface *i = interfaceItems[item]; | 291 | Interface *i = interfaceItems[item]; |
207 | if(i->getModuleOwner() == NULL){ | 292 | if(i->getModuleOwner() == NULL){ |
208 | QMessageBox::information(this, "Can't remove interface.", "Interface is built in.", QMessageBox::Ok); | 293 | QMessageBox::information(this, "Can't remove interface.", "Interface is built in.", QMessageBox::Ok); |
209 | } | 294 | } |
210 | else{ | 295 | else{ |
211 | if(!i->getModuleOwner()->remove(i)) | 296 | if(!i->getModuleOwner()->remove(i)) |
212 | QMessageBox::information(this, "Error", "Unable to remove.", QMessageBox::Ok); | 297 | QMessageBox::information(this, "Error", "Unable to remove.", QMessageBox::Ok); |
213 | else{ | 298 | else{ |
214 | QMessageBox::information(this, "Success", "Interface was removed.", QMessageBox::Ok); | 299 | QMessageBox::information(this, "Success", "Interface was removed.", QMessageBox::Ok); |
215 | // TODO memory managment.... | 300 | // TODO memory managment.... |
216 | // who deletes the interface? | 301 | // who deletes the interface? |
217 | } | 302 | } |
218 | } | 303 | } |
219 | } | 304 | } |
220 | 305 | ||
221 | /** | 306 | /** |
222 | * Pull up the configure about the currently selected interface. | 307 | * Pull up the configure about the currently selected interface. |
223 | * Report an error if no interface is selected. | 308 | * Report an error if no interface is selected. |
224 | * If the interface has a module owner then request its configure. | 309 | * If the interface has a module owner then request its configure. |
225 | */ | 310 | */ |
226 | void MainWindowImp::configureClicked(){ | 311 | void MainWindowImp::configureClicked(){ |
227 | QListViewItem *item = connectionList->currentItem(); | 312 | QListViewItem *item = connectionList->currentItem(); |
228 | if(!item){ | 313 | if(!item){ |
229 | QMessageBox::information(this, "Sorry","Please select an interface first.", QMessageBox::Ok); | 314 | QMessageBox::information(this, "Sorry","Please select an interface first.", QMessageBox::Ok); |
230 | return; | 315 | return; |
231 | } | 316 | } |
232 | 317 | ||
233 | Interface *i = interfaceItems[item]; | 318 | Interface *i = interfaceItems[item]; |
234 | if(i->getModuleOwner()){ | 319 | if(i->getModuleOwner()){ |
235 | QWidget *moduleConfigure = i->getModuleOwner()->configure(i); | 320 | QWidget *moduleConfigure = i->getModuleOwner()->configure(i); |
236 | if(moduleConfigure != NULL){ | 321 | if(moduleConfigure != NULL){ |
237 | moduleConfigure->showMaximized(); | 322 | moduleConfigure->showMaximized(); |
238 | moduleConfigure->show(); | 323 | moduleConfigure->show(); |
239 | return; | 324 | return; |
240 | } | 325 | } |
241 | } | 326 | } |
242 | 327 | ||
243 | InterfaceSetupImpDialog *configure = new InterfaceSetupImpDialog(0, "InterfaceSetupImp", i, true, Qt::WDestructiveClose); | 328 | InterfaceSetupImpDialog *configure = new InterfaceSetupImpDialog(0, "InterfaceSetupImp", i, true, Qt::WDestructiveClose); |
244 | QString currentProfileText = currentProfileLabel->text(); | 329 | QString currentProfileText = currentProfileLabel->text(); |
245 | if(currentProfileText.upper() == "ALL"); | 330 | if(currentProfileText.upper() == "ALL"); |
246 | currentProfileText = ""; | 331 | currentProfileText = ""; |
247 | configure->setProfile(currentProfileText); | 332 | configure->setProfile(currentProfileText); |
248 | configure->showMaximized(); | 333 | configure->showMaximized(); |
249 | configure->show(); | 334 | configure->show(); |
250 | } | 335 | } |
251 | 336 | ||
252 | /** | 337 | /** |
253 | * Pull up the information about the currently selected interface. | 338 | * Pull up the information about the currently selected interface. |
254 | * Report an error if no interface is selected. | 339 | * Report an error if no interface is selected. |
255 | * If the interface has a module owner then request its configure. | 340 | * If the interface has a module owner then request its configure. |
256 | */ | 341 | */ |
257 | void MainWindowImp::informationClicked(){ | 342 | void MainWindowImp::informationClicked(){ |
258 | QListViewItem *item = connectionList->currentItem(); | 343 | QListViewItem *item = connectionList->currentItem(); |
259 | if(!item){ | 344 | if(!item){ |
260 | QMessageBox::information(this, "Sorry","Please select an interface First.", QMessageBox::Ok); | 345 | QMessageBox::information(this, "Sorry","Please select an interface First.", QMessageBox::Ok); |
261 | return; | 346 | return; |
262 | } | 347 | } |
263 | 348 | ||
264 | Interface *i = interfaceItems[item]; | 349 | Interface *i = interfaceItems[item]; |
265 | if(!i->isAttached()){ | 350 | if(!i->isAttached()){ |
266 | QMessageBox::information(this, "Sorry","No information about\na disconnected interface.", QMessageBox::Ok); | 351 | QMessageBox::information(this, "Sorry","No information about\na disconnected interface.", QMessageBox::Ok); |
267 | return; | 352 | return; |
268 | } | 353 | } |
269 | 354 | ||
270 | if(i->getModuleOwner()){ | 355 | if(i->getModuleOwner()){ |
271 | QWidget *moduleInformation = i->getModuleOwner()->information(i); | 356 | QWidget *moduleInformation = i->getModuleOwner()->information(i); |
272 | if(moduleInformation != NULL){ | 357 | if(moduleInformation != NULL){ |
273 | moduleInformation->showMaximized(); | 358 | moduleInformation->showMaximized(); |
274 | moduleInformation->show(); | 359 | moduleInformation->show(); |
275 | return; | 360 | return; |
276 | } | 361 | } |
277 | } | 362 | } |
278 | InterfaceInformationImp *information = new InterfaceInformationImp(0, "InterfaceSetupImp", i, true); | 363 | InterfaceInformationImp *information = new InterfaceInformationImp(0, "InterfaceSetupImp", i, true); |
279 | information->showMaximized(); | 364 | information->showMaximized(); |
280 | information->show(); | 365 | information->show(); |
281 | } | 366 | } |
282 | 367 | ||
283 | /** | 368 | /** |
284 | * Aquire the list of active interfaces from ifconfig | ||
285 | * Call ifconfig and ifconfig -a | ||
286 | */ | ||
287 | void 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 | |||
304 | void 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 | */ |
384 | void MainWindowImp::updateInterface(Interface *i){ | 372 | void MainWindowImp::updateInterface(Interface *i){ |
385 | if(!advancedUserMode){ | 373 | if(!advancedUserMode){ |
386 | if(i->getInterfaceName() == "lo") | 374 | if(i->getInterfaceName() == "lo") |
387 | return; | 375 | return; |
388 | } | 376 | } |
389 | 377 | ||
390 | QListViewItem *item = NULL; | 378 | QListViewItem *item = NULL; |
391 | 379 | ||
392 | // Find the interface, making it if needed. | 380 | // Find the interface, making it if needed. |
393 | if(items.find(i) == items.end()){ | 381 | if(items.find(i) == items.end()){ |
394 | item = new QListViewItem(connectionList, "", "", ""); | 382 | item = new QListViewItem(connectionList, "", "", ""); |
395 | // See if you can't find a module owner for this interface | 383 | // See if you can't find a module owner for this interface |
396 | QMap<Module*, QLibrary*>::Iterator it; | 384 | QMap<Module*, QLibrary*>::Iterator it; |
397 | for( it = libraries.begin(); it != libraries.end(); ++it ){ | 385 | for( it = libraries.begin(); it != libraries.end(); ++it ){ |
398 | if(it.key()->isOwner(i)) | 386 | if(it.key()->isOwner(i)) |
399 | i->setModuleOwner(it.key()); | 387 | i->setModuleOwner(it.key()); |
400 | } | 388 | } |
401 | items.insert(i, item); | 389 | items.insert(i, item); |
402 | interfaceItems.insert(item, i); | 390 | interfaceItems.insert(item, i); |
403 | } | 391 | } |
404 | else | 392 | else |
405 | item = items[i]; | 393 | item = items[i]; |
406 | 394 | ||
407 | // Update the icons and information | 395 | // Update the icons and information |
408 | item->setPixmap(0, (Resource::loadPixmap(i->getStatus() ? "up": "down"))); | 396 | item->setPixmap(0, (Resource::loadPixmap(i->getStatus() ? "up": "down"))); |
409 | 397 | ||
410 | QString typeName = "lan"; | 398 | QString typeName = "lan"; |
411 | if(i->getHardwareName().contains("Local Loopback")) | 399 | if(i->getHardwareName().contains("Local Loopback")) |
412 | typeName = "lo"; | 400 | typeName = "lo"; |
413 | if(i->getInterfaceName().contains("irda")) | 401 | if(i->getInterfaceName().contains("irda")) |
414 | typeName = "irda"; | 402 | typeName = "irda"; |
415 | if(i->getInterfaceName().contains("wlan")) | 403 | if(i->getInterfaceName().contains("wlan")) |
416 | typeName = "wlan"; | 404 | typeName = "wlan"; |
417 | if(i->getInterfaceName().contains("usb")) | 405 | if(i->getInterfaceName().contains("usb")) |
418 | typeName = "usb"; | 406 | typeName = "usb"; |
419 | 407 | ||
420 | if(!i->isAttached()) | 408 | if(!i->isAttached()) |
421 | typeName = "connect_no"; | 409 | typeName = "connect_no"; |
422 | // Actually try to use the Module | 410 | // Actually try to use the Module |
423 | if(i->getModuleOwner() != NULL) | 411 | if(i->getModuleOwner() != NULL) |
424 | typeName = i->getModuleOwner()->getPixmapName(i); | 412 | typeName = i->getModuleOwner()->getPixmapName(i); |
425 | 413 | ||
426 | item->setPixmap(1, (Resource::loadPixmap(typeName))); | 414 | item->setPixmap(1, (Resource::loadPixmap(typeName))); |
427 | item->setText(2, i->getHardwareName()); | 415 | item->setText(2, i->getHardwareName()); |
428 | item->setText(3, QString("(%1)").arg(i->getInterfaceName())); | 416 | item->setText(3, QString("(%1)").arg(i->getInterfaceName())); |
429 | item->setText(4, (i->getStatus()) ? i->getIp() : QString("")); | 417 | item->setText(4, (i->getStatus()) ? i->getIp() : QString("")); |
430 | } | 418 | } |
431 | 419 | ||
432 | void MainWindowImp::newProfileChanged(const QString& newText){ | 420 | void MainWindowImp::newProfileChanged(const QString& newText){ |
433 | if(newText.length() > 0) | 421 | if(newText.length() > 0) |
434 | newProfileButton->setEnabled(true); | 422 | newProfileButton->setEnabled(true); |
435 | else | 423 | else |
436 | newProfileButton->setEnabled(false); | 424 | newProfileButton->setEnabled(false); |
437 | } | 425 | } |
438 | 426 | ||
439 | /** | 427 | /** |
440 | * Adds a new profile to the list of profiles. | 428 | * Adds a new profile to the list of profiles. |
441 | * Don't add profiles that already exists. | 429 | * Don't add profiles that already exists. |
442 | * Appends to the list and QStringList | 430 | * Appends to the list and QStringList |
443 | */ | 431 | */ |
444 | void MainWindowImp::addProfile(){ | 432 | void MainWindowImp::addProfile(){ |
445 | QString newProfileName = newProfile->text(); | 433 | QString newProfileName = newProfile->text(); |
446 | if(profiles.grep(newProfileName).count() > 0){ | 434 | if(profiles.grep(newProfileName).count() > 0){ |
447 | QMessageBox::information(this, "Can't Add","Profile already exists.", QMessageBox::Ok); | 435 | QMessageBox::information(this, "Can't Add","Profile already exists.", QMessageBox::Ok); |
448 | return; | 436 | return; |
449 | } | 437 | } |
450 | profiles.append(newProfileName); | 438 | profiles.append(newProfileName); |
451 | profilesList->insertItem(newProfileName); | 439 | profilesList->insertItem(newProfileName); |
452 | } | 440 | } |
453 | 441 | ||
454 | /** | 442 | /** |
455 | * Removes the currently selected profile in the combo. | 443 | * Removes the currently selected profile in the combo. |
456 | * Doesn't delete if there are less then 2 profiles. | 444 | * Doesn't delete if there are less then 2 profiles. |
457 | */ | 445 | */ |
458 | void MainWindowImp::removeProfile(){ | 446 | void MainWindowImp::removeProfile(){ |
459 | if(profilesList->count() <= 1){ | 447 | if(profilesList->count() <= 1){ |
460 | QMessageBox::information(this, "Can't remove.","At least one profile\nis needed.", QMessageBox::Ok); | 448 | QMessageBox::information(this, "Can't remove.","At least one profile\nis needed.", QMessageBox::Ok); |
461 | return; | 449 | return; |
462 | } | 450 | } |
463 | QString profileToRemove = profilesList->currentText(); | 451 | QString profileToRemove = profilesList->currentText(); |
464 | if(profileToRemove == "All"){ | 452 | if(profileToRemove == "All"){ |
465 | QMessageBox::information(this, "Can't remove.","Can't remove default.", QMessageBox::Ok); | 453 | QMessageBox::information(this, "Can't remove.","Can't remove default.", QMessageBox::Ok); |
466 | return; | 454 | return; |
467 | } | 455 | } |
468 | // Can't remove the curent profile | 456 | // Can't remove the curent profile |
469 | if(profileToRemove == currentProfileLabel->text()){ | 457 | if(profileToRemove == currentProfileLabel->text()){ |
470 | QMessageBox::information(this, "Can't remove.",QString("%1 is the current profile.").arg(profileToRemove), QMessageBox::Ok); | 458 | QMessageBox::information(this, "Can't remove.",QString("%1 is the current profile.").arg(profileToRemove), QMessageBox::Ok); |
471 | return; | 459 | return; |
472 | 460 | ||
473 | } | 461 | } |
474 | 462 | ||
475 | if(QMessageBox::information(this, "Question",QString("Remove profile: %1").arg(profileToRemove), QMessageBox::Ok, QMessageBox::Cancel) == QMessageBox::Ok){ | 463 | if(QMessageBox::information(this, "Question",QString("Remove profile: %1").arg(profileToRemove), QMessageBox::Ok, QMessageBox::Cancel) == QMessageBox::Ok){ |
476 | profiles = QStringList::split(" ", profiles.join(" ").replace(QRegExp(profileToRemove), "")); | 464 | profiles = QStringList::split(" ", profiles.join(" ").replace(QRegExp(profileToRemove), "")); |
477 | profilesList->clear(); | 465 | profilesList->clear(); |
478 | for ( QStringList::Iterator it = profiles.begin(); it != profiles.end(); ++it) | 466 | for ( QStringList::Iterator it = profiles.begin(); it != profiles.end(); ++it) |
479 | profilesList->insertItem((*it)); | 467 | profilesList->insertItem((*it)); |
480 | 468 | ||
481 | // Remove any interface settings and mappings. | 469 | // Remove any interface settings and mappings. |
482 | Interfaces interfaces; | 470 | Interfaces interfaces; |
483 | // Go through them one by one | 471 | // Go through them one by one |
484 | QMap<Interface*, QListViewItem*>::Iterator it; | 472 | QMap<Interface*, QListViewItem*>::Iterator it; |
485 | for( it = items.begin(); it != items.end(); ++it ){ | 473 | for( it = items.begin(); it != items.end(); ++it ){ |
486 | QString interfaceName = it.key()->getInterfaceName(); | 474 | QString interfaceName = it.key()->getInterfaceName(); |
487 | qDebug(interfaceName.latin1()); | 475 | qDebug(interfaceName.latin1()); |
488 | if(interfaces.setInterface(interfaceName + "_" + profileToRemove)){ | 476 | if(interfaces.setInterface(interfaceName + "_" + profileToRemove)){ |
489 | interfaces.removeInterface(); | 477 | interfaces.removeInterface(); |
490 | if(interfaces.setMapping(interfaceName)){ | 478 | if(interfaces.setMapping(interfaceName)){ |
491 | if(profilesList->count() == 1) | 479 | if(profilesList->count() == 1) |
492 | interfaces.removeMapping(); | 480 | interfaces.removeMapping(); |
493 | else{ | 481 | else{ |
494 | interfaces.removeMap("map", interfaceName + "_" + profileToRemove); | 482 | interfaces.removeMap("map", interfaceName + "_" + profileToRemove); |
495 | } | 483 | } |
496 | } | 484 | } |
497 | interfaces.write(); | 485 | interfaces.write(); |
498 | break; | 486 | break; |
499 | } | 487 | } |
500 | } | 488 | } |
501 | } | 489 | } |
502 | } | 490 | } |
503 | 491 | ||
504 | /** | 492 | /** |
505 | * A new profile has been selected, change. | 493 | * A new profile has been selected, change. |
506 | * @param newProfile the new profile. | 494 | * @param newProfile the new profile. |
507 | */ | 495 | */ |
508 | void MainWindowImp::changeProfile(){ | 496 | void MainWindowImp::changeProfile(){ |
509 | if(profilesList->currentItem() == -1){ | 497 | if(profilesList->currentItem() == -1){ |
510 | QMessageBox::information(this, "Can't Change.","Please select a profile.", QMessageBox::Ok); | 498 | QMessageBox::information(this, "Can't Change.","Please select a profile.", QMessageBox::Ok); |
511 | return; | 499 | return; |
512 | } | 500 | } |
513 | QString newProfile = profilesList->text(profilesList->currentItem()); | 501 | QString newProfile = profilesList->text(profilesList->currentItem()); |
514 | if(newProfile != currentProfileLabel->text()){ | 502 | if(newProfile != currentProfileLabel->text()){ |
515 | currentProfileLabel->setText(newProfile); | 503 | currentProfileLabel->setText(newProfile); |
516 | QFile::remove(scheme); | 504 | QFile::remove(scheme); |
517 | QFile file(scheme); | 505 | QFile file(scheme); |
518 | if ( file.open(IO_ReadWrite) ) { | 506 | if ( file.open(IO_ReadWrite) ) { |
519 | QTextStream stream( &file ); | 507 | QTextStream stream( &file ); |
520 | stream << QString("SCHEME=%1").arg(newProfile); | 508 | stream << QString("SCHEME=%1").arg(newProfile); |
521 | file.close(); | 509 | file.close(); |
522 | } | 510 | } |
523 | // restart all up devices? | 511 | // restart all up devices? |
524 | if(QMessageBox::information(this, "Question","Restart all running interfaces?", QMessageBox::Ok, QMessageBox::No) == QMessageBox::Ok){ | 512 | if(QMessageBox::information(this, "Question","Restart all running interfaces?", QMessageBox::Ok, QMessageBox::No) == QMessageBox::Ok){ |
525 | // Go through them one by one | 513 | // Go through them one by one |
526 | QMap<Interface*, QListViewItem*>::Iterator it; | 514 | QMap<Interface*, QListViewItem*>::Iterator it; |
527 | for( it = items.begin(); it != items.end(); ++it ){ | 515 | for( it = items.begin(); it != items.end(); ++it ){ |
528 | if(it.key()->getStatus() == true) | 516 | if(it.key()->getStatus() == true) |
529 | it.key()->restart(); | 517 | it.key()->restart(); |
530 | } | 518 | } |
531 | } | 519 | } |
532 | } | 520 | } |
533 | // TODO change the profile in the modules | 521 | // TODO change the profile in the modules |
534 | } | 522 | } |
535 | 523 | ||
536 | // mainwindowimp.cpp | 524 | // mainwindowimp.cpp |
537 | 525 | ||
diff --git a/noncore/net/networksetup/mainwindowimp.h b/noncore/net/networksetup/mainwindowimp.h index e5284b4..382428c 100644 --- a/noncore/net/networksetup/mainwindowimp.h +++ b/noncore/net/networksetup/mainwindowimp.h | |||
@@ -1,59 +1,58 @@ | |||
1 | #ifndef MAINWINOWIMP_H | 1 | #ifndef MAINWINOWIMP_H |
2 | #define MAINWINOWIMP_H | 2 | #define MAINWINOWIMP_H |
3 | 3 | ||
4 | #include "mainwindow.h" | 4 | #include "mainwindow.h" |
5 | #include <qmap.h> | 5 | #include <qmap.h> |
6 | #include <qstringlist.h> | 6 | #include <qstringlist.h> |
7 | 7 | ||
8 | class Module; | 8 | class Module; |
9 | class Interface; | 9 | class Interface; |
10 | class QLibrary; | 10 | class QLibrary; |
11 | class KProcess; | 11 | class KProcess; |
12 | 12 | ||
13 | class MainWindowImp : public MainWindow { | 13 | class MainWindowImp : public MainWindow { |
14 | Q_OBJECT | 14 | Q_OBJECT |
15 | 15 | ||
16 | public: | 16 | public: |
17 | MainWindowImp(QWidget *parent=0, const char *name=0); | 17 | MainWindowImp(QWidget *parent=0, const char *name=0); |
18 | ~MainWindowImp(); | 18 | ~MainWindowImp(); |
19 | 19 | ||
20 | private slots: | 20 | private slots: |
21 | void getAllInterfaces(); | ||
22 | |||
21 | void addClicked(); | 23 | void addClicked(); |
22 | void removeClicked(); | 24 | void removeClicked(); |
23 | void configureClicked(); | 25 | void configureClicked(); |
24 | void informationClicked(); | 26 | void informationClicked(); |
25 | 27 | ||
26 | void jobDone(KProcess *process); | ||
27 | void getInterfaceList(); | ||
28 | |||
29 | void addProfile(); | 28 | void addProfile(); |
30 | void removeProfile(); | 29 | void removeProfile(); |
31 | void changeProfile(); | 30 | void changeProfile(); |
32 | 31 | ||
33 | void updateInterface(Interface *i); | 32 | void updateInterface(Interface *i); |
34 | void newProfileChanged(const QString& newText); | 33 | void newProfileChanged(const QString& newText); |
35 | 34 | ||
36 | private: | 35 | private: |
37 | void loadModules(QString path); | 36 | void loadModules(QString path); |
38 | 37 | ||
39 | Module* loadPlugin(QString pluginFileName, | 38 | Module* loadPlugin(QString pluginFileName, |
40 | QString resolveString = "create_plugin"); | 39 | QString resolveString = "create_plugin"); |
41 | 40 | ||
42 | // For our local list of names | 41 | // For our local list of names |
43 | QMap<QString, Interface*> interfaceNames; | 42 | QMap<QString, Interface*> interfaceNames; |
44 | 43 | ||
45 | QMap<Module*, QLibrary*> libraries; | 44 | QMap<Module*, QLibrary*> libraries; |
46 | QMap<Interface*, QListViewItem*> items; | 45 | QMap<Interface*, QListViewItem*> items; |
47 | QMap<QListViewItem*, Interface*> interfaceItems; | 46 | QMap<QListViewItem*, Interface*> interfaceItems; |
48 | 47 | ||
49 | QMap<KProcess*, QString> threads; | 48 | QMap<KProcess*, QString> threads; |
50 | QStringList profiles; | 49 | QStringList profiles; |
51 | 50 | ||
52 | bool advancedUserMode; | 51 | bool advancedUserMode; |
53 | QString scheme; | 52 | QString scheme; |
54 | }; | 53 | }; |
55 | 54 | ||
56 | #endif | 55 | #endif |
57 | 56 | ||
58 | // mainwindowimp.h | 57 | // mainwindowimp.h |
59 | 58 | ||
diff --git a/noncore/net/networksetup/networksetup.pro b/noncore/net/networksetup/networksetup.pro index 6420924..cb517ce 100644 --- a/noncore/net/networksetup/networksetup.pro +++ b/noncore/net/networksetup/networksetup.pro | |||
@@ -1,11 +1,11 @@ | |||
1 | DESTDIR = $(OPIEDIR)/bin | 1 | #DESTDIR = $(OPIEDIR)/bin |
2 | TEMPLATE = app | 2 | TEMPLATE = app |
3 | #CONFIG = qt warn_on debug | 3 | #CONFIG = qt warn_on debug |
4 | CONFIG = qt warn_on release | 4 | CONFIG = qt warn_on release |
5 | HEADERS = mainwindowimp.h addconnectionimp.h defaultmodule.h kprocctrl.h module.h kprocess.h | 5 | HEADERS = mainwindowimp.h addconnectionimp.h defaultmodule.h module.h |
6 | SOURCES = main.cpp mainwindowimp.cpp addconnectionimp.cpp kprocctrl.cpp kprocess.cpp | 6 | SOURCES = main.cpp mainwindowimp.cpp addconnectionimp.cpp |
7 | INCLUDEPATH += $(OPIEDIR)/include interfaces/ | 7 | INCLUDEPATH += $(OPIEDIR)/include interfaces/ |
8 | DEPENDPATH += $(OPIEDIR)/include interfaces/ wlan | 8 | DEPENDPATH += $(OPIEDIR)/include interfaces/ wlan |
9 | LIBS += -lqpe -L$(OPIEDIR)/plugins/networksetup -Linterfaces/ -linterfaces | 9 | LIBS += -lqpe -L$(OPIEDIR)/plugins/networksetup -Linterfaces/ -linterfaces |
10 | INTERFACES = mainwindow.ui addconnection.ui | 10 | INTERFACES = mainwindow.ui addconnection.ui |
11 | TARGET = networksetup | 11 | TARGET = networksetup |
diff --git a/noncore/net/networksetup/ppp/.cvsignore b/noncore/net/networksetup/ppp/.cvsignore new file mode 100644 index 0000000..d753773 --- a/dev/null +++ b/noncore/net/networksetup/ppp/.cvsignore | |||
@@ -0,0 +1,23 @@ | |||
1 | .moc.cpp | ||
2 | *.moc | ||
3 | *.moc.o | ||
4 | *.o | ||
5 | moc_*.cpp | ||
6 | .libs | ||
7 | .deps | ||
8 | .moc.o | ||
9 | .o | ||
10 | Makefile* | ||
11 | networksetup | ||
12 | addconnection.cpp | ||
13 | addconnection.h | ||
14 | interfaceadvanced.cpp | ||
15 | interfaceadvanced.h | ||
16 | interfaceinformation.cpp | ||
17 | interfaceinformation.h | ||
18 | interfacesetup.cpp | ||
19 | interfacesetup.h | ||
20 | mainwindow.cpp | ||
21 | mainwindow.h | ||
22 | systemadvanced.cpp | ||
23 | systemadvanced.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 | |||
44 | KProcessController *KProcessController::theKProcessController = 0; | ||
45 | |||
46 | struct sigaction KProcessController::oldChildHandlerData; | ||
47 | bool KProcessController::handlerSet = false; | ||
48 | |||
49 | KProcessController::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 | |||
69 | void 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 | |||
99 | void 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 | ||
109 | void 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 | |||
119 | void 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 | ||
134 | struct waitdata | ||
135 | { | ||
136 | pid_t pid; | ||
137 | int status; | ||
138 | }; | ||
139 | |||
140 | void 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 | |||
185 | void 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 | ||
236 | void 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 | |||
253 | KProcessController::~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 | |||
36 | class KProcessControllerPrivate; | ||
37 | class 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 | */ | ||
50 | class KProcessController : public QObject | ||
51 | { | ||
52 | Q_OBJECT | ||
53 | |||
54 | public: | ||
55 | KProcessController(); | ||
56 | ~KProcessController(); | ||
57 | //CC: WARNING! Destructor Not virtual (but you don't derive classes from this anyhow...) | ||
58 | |||
59 | public: | ||
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(); | ||
102 | private: | ||
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 | |||
80 | class KProcessPrivate { | ||
81 | public: | ||
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 | |||
92 | KProcess::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 | |||
119 | void | ||
120 | KProcess::setEnvironment(const QString &name, const QString &value) | ||
121 | { | ||
122 | if (!d) | ||
123 | d = new KProcessPrivate; | ||
124 | d->env.insert(name, value); | ||
125 | } | ||
126 | |||
127 | void | ||
128 | KProcess::setWorkingDirectory(const QString &dir) | ||
129 | { | ||
130 | if (!d) | ||
131 | d = new KProcessPrivate; | ||
132 | d->wd = dir; | ||
133 | } | ||
134 | |||
135 | void | ||
136 | KProcess::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 | |||
149 | void | ||
150 | KProcess::setRunPrivileged(bool keepPrivileges) | ||
151 | { | ||
152 | keepPrivs = keepPrivileges; | ||
153 | } | ||
154 | |||
155 | bool | ||
156 | KProcess::runPrivileged() const | ||
157 | { | ||
158 | return keepPrivs; | ||
159 | } | ||
160 | |||
161 | |||
162 | KProcess::~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 | |||
185 | void 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 | |||
198 | bool 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 | |||
211 | KProcess &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 | |||
219 | KProcess &KProcess::operator<<(const QCString& arg) | ||
220 | { | ||
221 | return operator<< (arg.data()); | ||
222 | } | ||
223 | |||
224 | KProcess &KProcess::operator<<(const char* arg) | ||
225 | { | ||
226 | arguments.append(arg); | ||
227 | return *this; | ||
228 | } | ||
229 | |||
230 | KProcess &KProcess::operator<<(const QString& arg) | ||
231 | { | ||
232 | arguments.append(QFile::encodeName(arg)); | ||
233 | return *this; | ||
234 | } | ||
235 | |||
236 | void KProcess::clearArguments() | ||
237 | { | ||
238 | arguments.clear(); | ||
239 | } | ||
240 | |||
241 | bool 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 | |||
408 | bool 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 | |||
420 | bool KProcess::isRunning() const | ||
421 | { | ||
422 | return runs; | ||
423 | } | ||
424 | |||
425 | |||
426 | |||
427 | pid_t KProcess::pid() const | ||
428 | { | ||
429 | return pid_; | ||
430 | } | ||
431 | |||
432 | |||
433 | |||
434 | bool KProcess::normalExit() const | ||
435 | { | ||
436 | int _status = status; | ||
437 | return (pid_ != 0) && (!runs) && (WIFEXITED((_status))); | ||
438 | } | ||
439 | |||
440 | |||
441 | |||
442 | int KProcess::exitStatus() const | ||
443 | { | ||
444 | int _status = status; | ||
445 | return WEXITSTATUS((_status)); | ||
446 | } | ||
447 | |||
448 | |||
449 | |||
450 | bool 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 | |||
472 | void KProcess::suspend() | ||
473 | { | ||
474 | if ((communication & Stdout) && outnot) | ||
475 | outnot->setEnabled(false); | ||
476 | } | ||
477 | |||
478 | void KProcess::resume() | ||
479 | { | ||
480 | if ((communication & Stdout) && outnot) | ||
481 | outnot->setEnabled(true); | ||
482 | } | ||
483 | |||
484 | bool 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 | |||
499 | bool 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 | |||
514 | bool 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 | |||
536 | void KProcess::slotChildOutput(int fdno) | ||
537 | { | ||
538 | if (!childOutput(fdno)) | ||
539 | closeStdout(); | ||
540 | } | ||
541 | |||
542 | |||
543 | void KProcess::slotChildError(int fdno) | ||
544 | { | ||
545 | if (!childError(fdno)) | ||
546 | closeStderr(); | ||
547 | } | ||
548 | |||
549 | |||
550 | void 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 | |||
568 | void 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 | |||
587 | int 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 | |||
611 | int 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 | |||
625 | int 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 | |||
646 | int 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 | |||
694 | int 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 | |||
737 | void 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 | |||
826 | void 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 | |||
836 | QString 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 | |||
846 | QCString 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 | |||
857 | bool 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 | |||
888 | void KProcess::virtual_hook( int, void* ) | ||
889 | { /*BASE::virtual_hook( id, data );*/ } | ||
890 | |||
891 | |||
892 | /////////////////////////// | ||
893 | // CC: Class KShellProcess | ||
894 | /////////////////////////// | ||
895 | |||
896 | KShellProcess::KShellProcess(const char *shellname): | ||
897 | KProcess() | ||
898 | { | ||
899 | setUseShell(true, shellname); | ||
900 | } | ||
901 | |||
902 | |||
903 | KShellProcess::~KShellProcess() { | ||
904 | } | ||
905 | |||
906 | QString KShellProcess::quote(const QString &arg) | ||
907 | { | ||
908 | return KProcess::quote(arg); | ||
909 | } | ||
910 | |||
911 | bool KShellProcess::start(RunMode runmode, Communication comm) | ||
912 | { | ||
913 | return KProcess::start(runmode, comm); | ||
914 | } | ||
915 | |||
916 | void 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 | |||
40 | class QSocketNotifier; | ||
41 | class 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 | **/ | ||
146 | class KProcess : public QObject | ||
147 | { | ||
148 | Q_OBJECT | ||
149 | |||
150 | public: | ||
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 | |||
454 | signals: | ||
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 | |||
521 | protected 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 | |||
545 | protected: | ||
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 | |||
708 | private: | ||
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 | |||
733 | protected: | ||
734 | virtual void virtual_hook( int id, void* data ); | ||
735 | private: | ||
736 | KProcessPrivate *d; | ||
737 | }; | ||
738 | |||
739 | class 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 | */ | ||
752 | class KShellProcess: public KProcess | ||
753 | { | ||
754 | Q_OBJECT | ||
755 | |||
756 | public: | ||
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 | |||
787 | private: | ||
788 | |||
789 | QCString shell; | ||
790 | |||
791 | // Disallow assignment and copy-construction | ||
792 | KShellProcess( const KShellProcess& ); | ||
793 | KShellProcess& operator= ( const KShellProcess& ); | ||
794 | |||
795 | protected: | ||
796 | virtual void virtual_hook( int id, void* data ); | ||
797 | private: | ||
798 | KShellProcessPrivate *d; | ||
799 | }; | ||
800 | |||
801 | |||
802 | |||
803 | #endif | ||
804 | |||
diff --git a/noncore/settings/networksettings/mainwindowimp.cpp b/noncore/settings/networksettings/mainwindowimp.cpp index 7261c58..48ef9b3 100644 --- a/noncore/settings/networksettings/mainwindowimp.cpp +++ b/noncore/settings/networksettings/mainwindowimp.cpp | |||
@@ -1,537 +1,525 @@ | |||
1 | #include "mainwindowimp.h" | 1 | #include "mainwindowimp.h" |
2 | #include "addconnectionimp.h" | 2 | #include "addconnectionimp.h" |
3 | #include "interfaceinformationimp.h" | 3 | #include "interfaceinformationimp.h" |
4 | #include "interfacesetupimp.h" | 4 | #include "interfacesetupimp.h" |
5 | #include "interfaces.h" | 5 | #include "interfaces.h" |
6 | |||
7 | #include "module.h" | 6 | #include "module.h" |
8 | 7 | ||
9 | #include "kprocess.h" | ||
10 | |||
11 | #include <qpushbutton.h> | 8 | #include <qpushbutton.h> |
12 | #include <qlistbox.h> | 9 | #include <qlistbox.h> |
13 | #include <qlineedit.h> | 10 | #include <qlineedit.h> |
14 | #include <qlistview.h> | 11 | #include <qlistview.h> |
15 | #include <qheader.h> | 12 | #include <qheader.h> |
16 | #include <qlabel.h> | 13 | #include <qlabel.h> |
17 | 14 | ||
18 | #include <qmainwindow.h> | 15 | #include <qmainwindow.h> |
19 | #include <qmessagebox.h> | 16 | #include <qmessagebox.h> |
20 | 17 | ||
21 | #include <qpe/config.h> | 18 | #include <qpe/config.h> |
22 | #include <qpe/qlibrary.h> | 19 | #include <qpe/qlibrary.h> |
23 | #include <qpe/resource.h> | 20 | #include <qpe/resource.h> |
24 | #include <qpe/qpeapplication.h> | 21 | #include <qpe/qpeapplication.h> |
25 | 22 | ||
26 | #include <qlist.h> | 23 | #include <qlist.h> |
27 | #include <qdir.h> | 24 | #include <qdir.h> |
28 | #include <qfile.h> | 25 | #include <qfile.h> |
29 | #include <qtextstream.h> | 26 | #include <qtextstream.h> |
30 | 27 | ||
31 | #define TEMP_ALL "/tmp/ifconfig-a" | 28 | #include <net/if.h> |
32 | #define TEMP_UP "/tmp/ifconfig" | 29 | #include <sys/ioctl.h> |
33 | 30 | ||
34 | #define DEFAULT_SCHEME "/var/lib/pcmcia/scheme" | 31 | #define DEFAULT_SCHEME "/var/lib/pcmcia/scheme" |
35 | 32 | ||
36 | MainWindowImp::MainWindowImp(QWidget *parent, const char *name) : MainWindow(parent, name, true), advancedUserMode(false){ | 33 | MainWindowImp::MainWindowImp(QWidget *parent, const char *name) : MainWindow(parent, name, true), advancedUserMode(false){ |
37 | connect(addConnectionButton, SIGNAL(clicked()), this, SLOT(addClicked())); | 34 | connect(addConnectionButton, SIGNAL(clicked()), this, SLOT(addClicked())); |
38 | connect(removeConnectionButton, SIGNAL(clicked()), this, SLOT(removeClicked())); | 35 | connect(removeConnectionButton, SIGNAL(clicked()), this, SLOT(removeClicked())); |
39 | connect(informationConnectionButton, SIGNAL(clicked()), this, SLOT(informationClicked())); | 36 | connect(informationConnectionButton, SIGNAL(clicked()), this, SLOT(informationClicked())); |
40 | connect(configureConnectionButton, SIGNAL(clicked()), this, SLOT(configureClicked())); | 37 | connect(configureConnectionButton, SIGNAL(clicked()), this, SLOT(configureClicked())); |
41 | 38 | ||
42 | connect(newProfileButton, SIGNAL(clicked()), this, SLOT(addProfile())); | 39 | connect(newProfileButton, SIGNAL(clicked()), this, SLOT(addProfile())); |
43 | connect(removeProfileButton, SIGNAL(clicked()), this, SLOT(removeProfile())); | 40 | connect(removeProfileButton, SIGNAL(clicked()), this, SLOT(removeProfile())); |
44 | connect(setCurrentProfileButton, SIGNAL(clicked()), this, SLOT(changeProfile())); | 41 | connect(setCurrentProfileButton, SIGNAL(clicked()), this, SLOT(changeProfile())); |
45 | 42 | ||
46 | connect(newProfile, SIGNAL(textChanged(const QString&)), this, SLOT(newProfileChanged(const QString&))); | 43 | connect(newProfile, SIGNAL(textChanged(const QString&)), this, SLOT(newProfileChanged(const QString&))); |
47 | // Load connections. | 44 | // Load connections. |
48 | loadModules(QPEApplication::qpeDir() + "/plugins/networksetup"); | 45 | loadModules(QPEApplication::qpeDir() + "/plugins/networksetup"); |
49 | getInterfaceList(); | 46 | getAllInterfaces(); |
47 | |||
48 | Interfaces i; | ||
49 | QStringList list = i.getInterfaceList(); | ||
50 | QMap<QString, Interface*>::Iterator it; | ||
51 | for ( QStringList::Iterator ni = list.begin(); ni != list.end(); ++ni ) { | ||
52 | bool found = false; | ||
53 | for( it = interfaceNames.begin(); it != interfaceNames.end(); ++it ){ | ||
54 | if(it.key() == (*ni)) | ||
55 | found = true; | ||
56 | } | ||
57 | if(!found){ | ||
58 | if(!(*ni).contains("_")){ | ||
59 | Interface *i = new Interface(this, *ni, false); | ||
60 | i->setAttached(false); | ||
61 | i->setHardwareName("Disconnected"); | ||
62 | interfaceNames.insert(i->getInterfaceName(), i); | ||
63 | updateInterface(i); | ||
64 | connect(i, SIGNAL(updateInterface(Interface *)), this, SLOT(updateInterface(Interface *))); | ||
65 | } | ||
66 | } | ||
67 | } | ||
68 | |||
69 | //getInterfaceList(); | ||
50 | connectionList->header()->hide(); | 70 | connectionList->header()->hide(); |
51 | 71 | ||
52 | |||
53 | Config cfg("NetworkSetup"); | 72 | Config cfg("NetworkSetup"); |
54 | profiles = QStringList::split(" ", cfg.readEntry("Profiles", "All")); | 73 | profiles = QStringList::split(" ", cfg.readEntry("Profiles", "All")); |
55 | for ( QStringList::Iterator it = profiles.begin(); it != profiles.end(); ++it) | 74 | for ( QStringList::Iterator it = profiles.begin(); it != profiles.end(); ++it) |
56 | profilesList->insertItem((*it)); | 75 | profilesList->insertItem((*it)); |
57 | currentProfileLabel->setText(cfg.readEntry("CurrentProfile", "All")); | 76 | currentProfileLabel->setText(cfg.readEntry("CurrentProfile", "All")); |
58 | advancedUserMode = cfg.readBoolEntry("AdvancedUserMode", false); | 77 | advancedUserMode = cfg.readBoolEntry("AdvancedUserMode", false); |
59 | scheme = cfg.readEntry("SchemeFile", DEFAULT_SCHEME); | 78 | scheme = cfg.readEntry("SchemeFile", DEFAULT_SCHEME); |
60 | 79 | ||
61 | QFile file(scheme); | 80 | QFile file(scheme); |
62 | if ( file.open(IO_ReadOnly) ) { // file opened successfully | 81 | if ( file.open(IO_ReadOnly) ) { // file opened successfully |
63 | QTextStream stream( &file ); // use a text stream | 82 | QTextStream stream( &file ); // use a text stream |
64 | while ( !stream.eof() ) { // until end of file... | 83 | while ( !stream.eof() ) { // until end of file... |
65 | QString line = stream.readLine(); // line of text excluding '\n' | 84 | QString line = stream.readLine(); // line of text excluding '\n' |
66 | if(line.contains("SCHEME")){ | 85 | if(line.contains("SCHEME")){ |
67 | line = line.mid(7, line.length()); | 86 | line = line.mid(7, line.length()); |
68 | currentProfileLabel->setText(line); | 87 | currentProfileLabel->setText(line); |
69 | break; | 88 | break; |
70 | } | 89 | } |
71 | } | 90 | } |
72 | file.close(); | 91 | file.close(); |
73 | } | 92 | } |
74 | } | 93 | } |
75 | 94 | ||
76 | /** | 95 | /** |
77 | * Deconstructor. Save profiles. Delete loaded libraries. | 96 | * Deconstructor. Save profiles. Delete loaded libraries. |
78 | */ | 97 | */ |
79 | MainWindowImp::~MainWindowImp(){ | 98 | MainWindowImp::~MainWindowImp(){ |
80 | // Save profiles. | 99 | // Save profiles. |
81 | Config cfg("NetworkSetup"); | 100 | Config cfg("NetworkSetup"); |
82 | cfg.setGroup("General"); | 101 | cfg.setGroup("General"); |
83 | cfg.writeEntry("Profiles", profiles.join(" ")); | 102 | cfg.writeEntry("Profiles", profiles.join(" ")); |
84 | 103 | ||
85 | // Delete all interfaces that don't have owners. | 104 | // Delete all interfaces that don't have owners. |
86 | QMap<Interface*, QListViewItem*>::Iterator iIt; | 105 | QMap<Interface*, QListViewItem*>::Iterator iIt; |
87 | for( iIt = items.begin(); iIt != items.end(); ++iIt ){ | 106 | for( iIt = items.begin(); iIt != items.end(); ++iIt ){ |
88 | if(iIt.key()->getModuleOwner() == NULL) | 107 | if(iIt.key()->getModuleOwner() == NULL) |
89 | delete iIt.key(); | 108 | delete iIt.key(); |
90 | } | 109 | } |
91 | 110 | ||
92 | // Delete Modules and Libraries | 111 | // Delete Modules and Libraries |
93 | QMap<Module*, QLibrary*>::Iterator it; | 112 | QMap<Module*, QLibrary*>::Iterator it; |
94 | for( it = libraries.begin(); it != libraries.end(); ++it ){ | 113 | for( it = libraries.begin(); it != libraries.end(); ++it ){ |
95 | delete it.key(); | 114 | delete it.key(); |
96 | // I wonder why I can't delete the libraries | 115 | // I wonder why I can't delete the libraries |
97 | // What fucking shit this is. | 116 | // What fucking shit this is. |
98 | //delete it.data(); | 117 | //delete it.data(); |
99 | } | 118 | } |
100 | } | 119 | } |
101 | 120 | ||
102 | /** | 121 | /** |
122 | * Query the kernel for all of the interfaces. | ||
123 | */ | ||
124 | void MainWindowImp::getAllInterfaces(){ | ||
125 | int sockfd = socket(AF_INET, SOCK_DGRAM, 0); | ||
126 | if(sockfd == -1) | ||
127 | return; | ||
128 | |||
129 | char buf[8*1024]; | ||
130 | struct ifconf ifc; | ||
131 | ifc.ifc_len = sizeof(buf); | ||
132 | ifc.ifc_req = (struct ifreq *) buf; | ||
133 | int result=ioctl(sockfd, SIOCGIFCONF, &ifc); | ||
134 | |||
135 | for (char* ptr = buf; ptr < buf + ifc.ifc_len; ){ | ||
136 | struct ifreq *ifr =(struct ifreq *) ptr; | ||
137 | int len = sizeof(struct sockaddr); | ||
138 | #ifdef HAVE_SOCKADDR_SA_LEN | ||
139 | if (ifr->ifr_addr.sa_len > len) | ||
140 | len = ifr->ifr_addr.sa_len; /* length > 16 */ | ||
141 | #endif | ||
142 | ptr += sizeof(ifr->ifr_name) + len; /* for next one in buffer */ | ||
143 | |||
144 | int flags; | ||
145 | struct sockaddr_in *sinptr; | ||
146 | Interface *i = NULL; | ||
147 | switch (ifr->ifr_addr.sa_family){ | ||
148 | case AF_INET: | ||
149 | sinptr = (struct sockaddr_in *) &ifr->ifr_addr; | ||
150 | flags=0; | ||
151 | |||
152 | struct ifreq ifcopy; | ||
153 | ifcopy=*ifr; | ||
154 | result=ioctl(sockfd,SIOCGIFFLAGS,&ifcopy); | ||
155 | flags=ifcopy.ifr_flags; | ||
156 | i = new Interface(this, ifr->ifr_name, false); | ||
157 | i->setAttached(true); | ||
158 | if ((flags & IFF_UP) == IFF_UP) | ||
159 | i->setStatus(true); | ||
160 | else | ||
161 | i->setStatus(false); | ||
162 | |||
163 | if ((flags & IFF_BROADCAST) == IFF_BROADCAST) | ||
164 | i->setHardwareName("Ethernet"); | ||
165 | else if ((flags & IFF_POINTOPOINT) == IFF_POINTOPOINT) | ||
166 | i->setHardwareName("Point to Point"); | ||
167 | else if ((flags & IFF_MULTICAST) == IFF_MULTICAST) | ||
168 | i->setHardwareName("Multicast"); | ||
169 | else if ((flags & IFF_LOOPBACK) == IFF_LOOPBACK) | ||
170 | i->setHardwareName("Loopback"); | ||
171 | else | ||
172 | i->setHardwareName("Unknown"); | ||
173 | |||
174 | interfaceNames.insert(i->getInterfaceName(), i); | ||
175 | updateInterface(i); | ||
176 | connect(i, SIGNAL(updateInterface(Interface *)), this, SLOT(updateInterface(Interface *))); | ||
177 | break; | ||
178 | |||
179 | default: | ||
180 | qDebug(ifr->ifr_name); | ||
181 | qDebug(QString("%1").arg(ifr->ifr_addr.sa_family).latin1()); | ||
182 | break; | ||
183 | } | ||
184 | } | ||
185 | } | ||
186 | |||
187 | /** | ||
103 | * Load all modules that are found in the path | 188 | * Load all modules that are found in the path |
104 | * @param path a directory that is scaned for any plugins that can be loaded | 189 | * @param path a directory that is scaned for any plugins that can be loaded |
105 | * and attempts to load them | 190 | * and attempts to load them |
106 | */ | 191 | */ |
107 | void MainWindowImp::loadModules(QString path){ | 192 | void MainWindowImp::loadModules(QString path){ |
108 | //qDebug(path.latin1()); | 193 | //qDebug(path.latin1()); |
109 | QDir d(path); | 194 | QDir d(path); |
110 | if(!d.exists()) | 195 | if(!d.exists()) |
111 | return; | 196 | return; |
112 | 197 | ||
113 | // Don't want sym links | 198 | // Don't want sym links |
114 | d.setFilter( QDir::Files | QDir::NoSymLinks ); | 199 | d.setFilter( QDir::Files | QDir::NoSymLinks ); |
115 | const QFileInfoList *list = d.entryInfoList(); | 200 | const QFileInfoList *list = d.entryInfoList(); |
116 | QFileInfoListIterator it( *list ); | 201 | QFileInfoListIterator it( *list ); |
117 | QFileInfo *fi; | 202 | QFileInfo *fi; |
118 | while ( (fi=it.current()) ) { | 203 | while ( (fi=it.current()) ) { |
119 | if(fi->fileName().contains(".so")){ | 204 | if(fi->fileName().contains(".so")){ |
120 | loadPlugin(path + "/" + fi->fileName()); | 205 | loadPlugin(path + "/" + fi->fileName()); |
121 | } | 206 | } |
122 | ++it; | 207 | ++it; |
123 | } | 208 | } |
124 | } | 209 | } |
125 | 210 | ||
126 | /** | 211 | /** |
127 | * Attempt to load a function and resolve a function. | 212 | * Attempt to load a function and resolve a function. |
128 | * @param pluginFileName - the name of the file in which to attempt to load | 213 | * @param pluginFileName - the name of the file in which to attempt to load |
129 | * @param resolveString - function pointer to resolve | 214 | * @param resolveString - function pointer to resolve |
130 | * @return pointer to the function with name resolveString or NULL | 215 | * @return pointer to the function with name resolveString or NULL |
131 | */ | 216 | */ |
132 | Module* MainWindowImp::loadPlugin(QString pluginFileName, QString resolveString){ | 217 | Module* MainWindowImp::loadPlugin(QString pluginFileName, QString resolveString){ |
133 | //qDebug(QString("MainWindowImp::loadPlugin: %1").arg(pluginFileName).latin1()); | 218 | //qDebug(QString("MainWindowImp::loadPlugin: %1").arg(pluginFileName).latin1()); |
134 | QLibrary *lib = new QLibrary(pluginFileName); | 219 | QLibrary *lib = new QLibrary(pluginFileName); |
135 | void *functionPointer = lib->resolve(resolveString); | 220 | void *functionPointer = lib->resolve(resolveString); |
136 | if( !functionPointer ){ | 221 | if( !functionPointer ){ |
137 | qDebug(QString("MainWindowImp: File: %1 is not a plugin, but though was.").arg(pluginFileName).latin1()); | 222 | qDebug(QString("MainWindowImp: File: %1 is not a plugin, but though was.").arg(pluginFileName).latin1()); |
138 | delete lib; | 223 | delete lib; |
139 | return NULL; | 224 | return NULL; |
140 | } | 225 | } |
141 | 226 | ||
142 | // Try to get an object. | 227 | // Try to get an object. |
143 | Module *object = ((Module* (*)()) functionPointer)(); | 228 | Module *object = ((Module* (*)()) functionPointer)(); |
144 | if(object == NULL){ | 229 | if(object == NULL){ |
145 | qDebug("MainWindowImp: Couldn't create object, but did load library!"); | 230 | qDebug("MainWindowImp: Couldn't create object, but did load library!"); |
146 | delete lib; | 231 | delete lib; |
147 | return NULL; | 232 | return NULL; |
148 | } | 233 | } |
149 | 234 | ||
150 | // Store for deletion later | 235 | // Store for deletion later |
151 | libraries.insert(object, lib); | 236 | libraries.insert(object, lib); |
152 | return object; | 237 | return object; |
153 | } | 238 | } |
154 | 239 | ||
155 | /** | 240 | /** |
156 | * The Add button was clicked. Bring up the add dialog and if OK is hit | 241 | * The Add button was clicked. Bring up the add dialog and if OK is hit |
157 | * load the plugin and append it to the list | 242 | * load the plugin and append it to the list |
158 | */ | 243 | */ |
159 | void MainWindowImp::addClicked(){ | 244 | void MainWindowImp::addClicked(){ |
160 | QMap<Module*, QLibrary*>::Iterator it; | 245 | QMap<Module*, QLibrary*>::Iterator it; |
161 | QMap<QString, QString> list; | 246 | QMap<QString, QString> list; |
162 | QMap<QString, Module*> newInterfaceOwners; | 247 | QMap<QString, Module*> newInterfaceOwners; |
163 | //list.insert("USB (PPP) / (ADD_TEST)", "A dialup connection over the USB port"); | 248 | //list.insert("USB (PPP) / (ADD_TEST)", "A dialup connection over the USB port"); |
164 | //list.insert("IrDa (PPP) / (ADD_TEST)", "A dialup connection over the IdDa port"); | 249 | //list.insert("IrDa (PPP) / (ADD_TEST)", "A dialup connection over the IdDa port"); |
165 | for( it = libraries.begin(); it != libraries.end(); ++it ){ | 250 | for( it = libraries.begin(); it != libraries.end(); ++it ){ |
166 | if(it.key()){ | 251 | if(it.key()){ |
167 | (it.key())->possibleNewInterfaces(list); | 252 | (it.key())->possibleNewInterfaces(list); |
168 | } | 253 | } |
169 | } | 254 | } |
170 | // See if the list has anything that we can add. | 255 | // See if the list has anything that we can add. |
171 | if(list.count() == 0){ | 256 | if(list.count() == 0){ |
172 | QMessageBox::information(this, "Sorry", "Nothing to add.", QMessageBox::Ok); | 257 | QMessageBox::information(this, "Sorry", "Nothing to add.", QMessageBox::Ok); |
173 | return; | 258 | return; |
174 | } | 259 | } |
175 | AddConnectionImp addNewConnection(this, "AddConnectionImp", true); | 260 | AddConnectionImp addNewConnection(this, "AddConnectionImp", true); |
176 | addNewConnection.addConnections(list); | 261 | addNewConnection.addConnections(list); |
177 | addNewConnection.showMaximized(); | 262 | addNewConnection.showMaximized(); |
178 | if(QDialog::Accepted == addNewConnection.exec()){ | 263 | if(QDialog::Accepted == addNewConnection.exec()){ |
179 | QListViewItem *item = addNewConnection.registeredServicesList->currentItem(); | 264 | QListViewItem *item = addNewConnection.registeredServicesList->currentItem(); |
180 | if(!item) | 265 | if(!item) |
181 | return; | 266 | return; |
182 | 267 | ||
183 | for( it = libraries.begin(); it != libraries.end(); ++it ){ | 268 | for( it = libraries.begin(); it != libraries.end(); ++it ){ |
184 | if(it.key()){ | 269 | if(it.key()){ |
185 | Interface *i = (it.key())->addNewInterface(item->text(0)); | 270 | Interface *i = (it.key())->addNewInterface(item->text(0)); |
186 | if(i){ | 271 | if(i){ |
187 | interfaceNames.insert(i->getInterfaceName(), i); | 272 | interfaceNames.insert(i->getInterfaceName(), i); |
188 | updateInterface(i); | 273 | updateInterface(i); |
189 | } | 274 | } |
190 | } | 275 | } |
191 | } | 276 | } |
192 | } | 277 | } |
193 | } | 278 | } |
194 | 279 | ||
195 | /** | 280 | /** |
196 | * Prompt the user to see if they really want to do this. | 281 | * Prompt the user to see if they really want to do this. |
197 | * If they do then remove from the list and unload. | 282 | * If they do then remove from the list and unload. |
198 | */ | 283 | */ |
199 | void MainWindowImp::removeClicked(){ | 284 | void MainWindowImp::removeClicked(){ |
200 | QListViewItem *item = connectionList->currentItem(); | 285 | QListViewItem *item = connectionList->currentItem(); |
201 | if(!item) { | 286 | if(!item) { |
202 | QMessageBox::information(this, "Sorry","Please select an interface First.", QMessageBox::Ok); | 287 | QMessageBox::information(this, "Sorry","Please select an interface First.", QMessageBox::Ok); |
203 | return; | 288 | return; |
204 | } | 289 | } |
205 | 290 | ||
206 | Interface *i = interfaceItems[item]; | 291 | Interface *i = interfaceItems[item]; |
207 | if(i->getModuleOwner() == NULL){ | 292 | if(i->getModuleOwner() == NULL){ |
208 | QMessageBox::information(this, "Can't remove interface.", "Interface is built in.", QMessageBox::Ok); | 293 | QMessageBox::information(this, "Can't remove interface.", "Interface is built in.", QMessageBox::Ok); |
209 | } | 294 | } |
210 | else{ | 295 | else{ |
211 | if(!i->getModuleOwner()->remove(i)) | 296 | if(!i->getModuleOwner()->remove(i)) |
212 | QMessageBox::information(this, "Error", "Unable to remove.", QMessageBox::Ok); | 297 | QMessageBox::information(this, "Error", "Unable to remove.", QMessageBox::Ok); |
213 | else{ | 298 | else{ |
214 | QMessageBox::information(this, "Success", "Interface was removed.", QMessageBox::Ok); | 299 | QMessageBox::information(this, "Success", "Interface was removed.", QMessageBox::Ok); |
215 | // TODO memory managment.... | 300 | // TODO memory managment.... |
216 | // who deletes the interface? | 301 | // who deletes the interface? |
217 | } | 302 | } |
218 | } | 303 | } |
219 | } | 304 | } |
220 | 305 | ||
221 | /** | 306 | /** |
222 | * Pull up the configure about the currently selected interface. | 307 | * Pull up the configure about the currently selected interface. |
223 | * Report an error if no interface is selected. | 308 | * Report an error if no interface is selected. |
224 | * If the interface has a module owner then request its configure. | 309 | * If the interface has a module owner then request its configure. |
225 | */ | 310 | */ |
226 | void MainWindowImp::configureClicked(){ | 311 | void MainWindowImp::configureClicked(){ |
227 | QListViewItem *item = connectionList->currentItem(); | 312 | QListViewItem *item = connectionList->currentItem(); |
228 | if(!item){ | 313 | if(!item){ |
229 | QMessageBox::information(this, "Sorry","Please select an interface first.", QMessageBox::Ok); | 314 | QMessageBox::information(this, "Sorry","Please select an interface first.", QMessageBox::Ok); |
230 | return; | 315 | return; |
231 | } | 316 | } |
232 | 317 | ||
233 | Interface *i = interfaceItems[item]; | 318 | Interface *i = interfaceItems[item]; |
234 | if(i->getModuleOwner()){ | 319 | if(i->getModuleOwner()){ |
235 | QWidget *moduleConfigure = i->getModuleOwner()->configure(i); | 320 | QWidget *moduleConfigure = i->getModuleOwner()->configure(i); |
236 | if(moduleConfigure != NULL){ | 321 | if(moduleConfigure != NULL){ |
237 | moduleConfigure->showMaximized(); | 322 | moduleConfigure->showMaximized(); |
238 | moduleConfigure->show(); | 323 | moduleConfigure->show(); |
239 | return; | 324 | return; |
240 | } | 325 | } |
241 | } | 326 | } |
242 | 327 | ||
243 | InterfaceSetupImpDialog *configure = new InterfaceSetupImpDialog(0, "InterfaceSetupImp", i, true, Qt::WDestructiveClose); | 328 | InterfaceSetupImpDialog *configure = new InterfaceSetupImpDialog(0, "InterfaceSetupImp", i, true, Qt::WDestructiveClose); |
244 | QString currentProfileText = currentProfileLabel->text(); | 329 | QString currentProfileText = currentProfileLabel->text(); |
245 | if(currentProfileText.upper() == "ALL"); | 330 | if(currentProfileText.upper() == "ALL"); |
246 | currentProfileText = ""; | 331 | currentProfileText = ""; |
247 | configure->setProfile(currentProfileText); | 332 | configure->setProfile(currentProfileText); |
248 | configure->showMaximized(); | 333 | configure->showMaximized(); |
249 | configure->show(); | 334 | configure->show(); |
250 | } | 335 | } |
251 | 336 | ||
252 | /** | 337 | /** |
253 | * Pull up the information about the currently selected interface. | 338 | * Pull up the information about the currently selected interface. |
254 | * Report an error if no interface is selected. | 339 | * Report an error if no interface is selected. |
255 | * If the interface has a module owner then request its configure. | 340 | * If the interface has a module owner then request its configure. |
256 | */ | 341 | */ |
257 | void MainWindowImp::informationClicked(){ | 342 | void MainWindowImp::informationClicked(){ |
258 | QListViewItem *item = connectionList->currentItem(); | 343 | QListViewItem *item = connectionList->currentItem(); |
259 | if(!item){ | 344 | if(!item){ |
260 | QMessageBox::information(this, "Sorry","Please select an interface First.", QMessageBox::Ok); | 345 | QMessageBox::information(this, "Sorry","Please select an interface First.", QMessageBox::Ok); |
261 | return; | 346 | return; |
262 | } | 347 | } |
263 | 348 | ||
264 | Interface *i = interfaceItems[item]; | 349 | Interface *i = interfaceItems[item]; |
265 | if(!i->isAttached()){ | 350 | if(!i->isAttached()){ |
266 | QMessageBox::information(this, "Sorry","No information about\na disconnected interface.", QMessageBox::Ok); | 351 | QMessageBox::information(this, "Sorry","No information about\na disconnected interface.", QMessageBox::Ok); |
267 | return; | 352 | return; |
268 | } | 353 | } |
269 | 354 | ||
270 | if(i->getModuleOwner()){ | 355 | if(i->getModuleOwner()){ |
271 | QWidget *moduleInformation = i->getModuleOwner()->information(i); | 356 | QWidget *moduleInformation = i->getModuleOwner()->information(i); |
272 | if(moduleInformation != NULL){ | 357 | if(moduleInformation != NULL){ |
273 | moduleInformation->showMaximized(); | 358 | moduleInformation->showMaximized(); |
274 | moduleInformation->show(); | 359 | moduleInformation->show(); |
275 | return; | 360 | return; |
276 | } | 361 | } |
277 | } | 362 | } |
278 | InterfaceInformationImp *information = new InterfaceInformationImp(0, "InterfaceSetupImp", i, true); | 363 | InterfaceInformationImp *information = new InterfaceInformationImp(0, "InterfaceSetupImp", i, true); |
279 | information->showMaximized(); | 364 | information->showMaximized(); |
280 | information->show(); | 365 | information->show(); |
281 | } | 366 | } |
282 | 367 | ||
283 | /** | 368 | /** |
284 | * Aquire the list of active interfaces from ifconfig | ||
285 | * Call ifconfig and ifconfig -a | ||
286 | */ | ||
287 | void 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 | |||
304 | void 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 | */ |
384 | void MainWindowImp::updateInterface(Interface *i){ | 372 | void MainWindowImp::updateInterface(Interface *i){ |
385 | if(!advancedUserMode){ | 373 | if(!advancedUserMode){ |
386 | if(i->getInterfaceName() == "lo") | 374 | if(i->getInterfaceName() == "lo") |
387 | return; | 375 | return; |
388 | } | 376 | } |
389 | 377 | ||
390 | QListViewItem *item = NULL; | 378 | QListViewItem *item = NULL; |
391 | 379 | ||
392 | // Find the interface, making it if needed. | 380 | // Find the interface, making it if needed. |
393 | if(items.find(i) == items.end()){ | 381 | if(items.find(i) == items.end()){ |
394 | item = new QListViewItem(connectionList, "", "", ""); | 382 | item = new QListViewItem(connectionList, "", "", ""); |
395 | // See if you can't find a module owner for this interface | 383 | // See if you can't find a module owner for this interface |
396 | QMap<Module*, QLibrary*>::Iterator it; | 384 | QMap<Module*, QLibrary*>::Iterator it; |
397 | for( it = libraries.begin(); it != libraries.end(); ++it ){ | 385 | for( it = libraries.begin(); it != libraries.end(); ++it ){ |
398 | if(it.key()->isOwner(i)) | 386 | if(it.key()->isOwner(i)) |
399 | i->setModuleOwner(it.key()); | 387 | i->setModuleOwner(it.key()); |
400 | } | 388 | } |
401 | items.insert(i, item); | 389 | items.insert(i, item); |
402 | interfaceItems.insert(item, i); | 390 | interfaceItems.insert(item, i); |
403 | } | 391 | } |
404 | else | 392 | else |
405 | item = items[i]; | 393 | item = items[i]; |
406 | 394 | ||
407 | // Update the icons and information | 395 | // Update the icons and information |
408 | item->setPixmap(0, (Resource::loadPixmap(i->getStatus() ? "up": "down"))); | 396 | item->setPixmap(0, (Resource::loadPixmap(i->getStatus() ? "up": "down"))); |
409 | 397 | ||
410 | QString typeName = "lan"; | 398 | QString typeName = "lan"; |
411 | if(i->getHardwareName().contains("Local Loopback")) | 399 | if(i->getHardwareName().contains("Local Loopback")) |
412 | typeName = "lo"; | 400 | typeName = "lo"; |
413 | if(i->getInterfaceName().contains("irda")) | 401 | if(i->getInterfaceName().contains("irda")) |
414 | typeName = "irda"; | 402 | typeName = "irda"; |
415 | if(i->getInterfaceName().contains("wlan")) | 403 | if(i->getInterfaceName().contains("wlan")) |
416 | typeName = "wlan"; | 404 | typeName = "wlan"; |
417 | if(i->getInterfaceName().contains("usb")) | 405 | if(i->getInterfaceName().contains("usb")) |
418 | typeName = "usb"; | 406 | typeName = "usb"; |
419 | 407 | ||
420 | if(!i->isAttached()) | 408 | if(!i->isAttached()) |
421 | typeName = "connect_no"; | 409 | typeName = "connect_no"; |
422 | // Actually try to use the Module | 410 | // Actually try to use the Module |
423 | if(i->getModuleOwner() != NULL) | 411 | if(i->getModuleOwner() != NULL) |
424 | typeName = i->getModuleOwner()->getPixmapName(i); | 412 | typeName = i->getModuleOwner()->getPixmapName(i); |
425 | 413 | ||
426 | item->setPixmap(1, (Resource::loadPixmap(typeName))); | 414 | item->setPixmap(1, (Resource::loadPixmap(typeName))); |
427 | item->setText(2, i->getHardwareName()); | 415 | item->setText(2, i->getHardwareName()); |
428 | item->setText(3, QString("(%1)").arg(i->getInterfaceName())); | 416 | item->setText(3, QString("(%1)").arg(i->getInterfaceName())); |
429 | item->setText(4, (i->getStatus()) ? i->getIp() : QString("")); | 417 | item->setText(4, (i->getStatus()) ? i->getIp() : QString("")); |
430 | } | 418 | } |
431 | 419 | ||
432 | void MainWindowImp::newProfileChanged(const QString& newText){ | 420 | void MainWindowImp::newProfileChanged(const QString& newText){ |
433 | if(newText.length() > 0) | 421 | if(newText.length() > 0) |
434 | newProfileButton->setEnabled(true); | 422 | newProfileButton->setEnabled(true); |
435 | else | 423 | else |
436 | newProfileButton->setEnabled(false); | 424 | newProfileButton->setEnabled(false); |
437 | } | 425 | } |
438 | 426 | ||
439 | /** | 427 | /** |
440 | * Adds a new profile to the list of profiles. | 428 | * Adds a new profile to the list of profiles. |
441 | * Don't add profiles that already exists. | 429 | * Don't add profiles that already exists. |
442 | * Appends to the list and QStringList | 430 | * Appends to the list and QStringList |
443 | */ | 431 | */ |
444 | void MainWindowImp::addProfile(){ | 432 | void MainWindowImp::addProfile(){ |
445 | QString newProfileName = newProfile->text(); | 433 | QString newProfileName = newProfile->text(); |
446 | if(profiles.grep(newProfileName).count() > 0){ | 434 | if(profiles.grep(newProfileName).count() > 0){ |
447 | QMessageBox::information(this, "Can't Add","Profile already exists.", QMessageBox::Ok); | 435 | QMessageBox::information(this, "Can't Add","Profile already exists.", QMessageBox::Ok); |
448 | return; | 436 | return; |
449 | } | 437 | } |
450 | profiles.append(newProfileName); | 438 | profiles.append(newProfileName); |
451 | profilesList->insertItem(newProfileName); | 439 | profilesList->insertItem(newProfileName); |
452 | } | 440 | } |
453 | 441 | ||
454 | /** | 442 | /** |
455 | * Removes the currently selected profile in the combo. | 443 | * Removes the currently selected profile in the combo. |
456 | * Doesn't delete if there are less then 2 profiles. | 444 | * Doesn't delete if there are less then 2 profiles. |
457 | */ | 445 | */ |
458 | void MainWindowImp::removeProfile(){ | 446 | void MainWindowImp::removeProfile(){ |
459 | if(profilesList->count() <= 1){ | 447 | if(profilesList->count() <= 1){ |
460 | QMessageBox::information(this, "Can't remove.","At least one profile\nis needed.", QMessageBox::Ok); | 448 | QMessageBox::information(this, "Can't remove.","At least one profile\nis needed.", QMessageBox::Ok); |
461 | return; | 449 | return; |
462 | } | 450 | } |
463 | QString profileToRemove = profilesList->currentText(); | 451 | QString profileToRemove = profilesList->currentText(); |
464 | if(profileToRemove == "All"){ | 452 | if(profileToRemove == "All"){ |
465 | QMessageBox::information(this, "Can't remove.","Can't remove default.", QMessageBox::Ok); | 453 | QMessageBox::information(this, "Can't remove.","Can't remove default.", QMessageBox::Ok); |
466 | return; | 454 | return; |
467 | } | 455 | } |
468 | // Can't remove the curent profile | 456 | // Can't remove the curent profile |
469 | if(profileToRemove == currentProfileLabel->text()){ | 457 | if(profileToRemove == currentProfileLabel->text()){ |
470 | QMessageBox::information(this, "Can't remove.",QString("%1 is the current profile.").arg(profileToRemove), QMessageBox::Ok); | 458 | QMessageBox::information(this, "Can't remove.",QString("%1 is the current profile.").arg(profileToRemove), QMessageBox::Ok); |
471 | return; | 459 | return; |
472 | 460 | ||
473 | } | 461 | } |
474 | 462 | ||
475 | if(QMessageBox::information(this, "Question",QString("Remove profile: %1").arg(profileToRemove), QMessageBox::Ok, QMessageBox::Cancel) == QMessageBox::Ok){ | 463 | if(QMessageBox::information(this, "Question",QString("Remove profile: %1").arg(profileToRemove), QMessageBox::Ok, QMessageBox::Cancel) == QMessageBox::Ok){ |
476 | profiles = QStringList::split(" ", profiles.join(" ").replace(QRegExp(profileToRemove), "")); | 464 | profiles = QStringList::split(" ", profiles.join(" ").replace(QRegExp(profileToRemove), "")); |
477 | profilesList->clear(); | 465 | profilesList->clear(); |
478 | for ( QStringList::Iterator it = profiles.begin(); it != profiles.end(); ++it) | 466 | for ( QStringList::Iterator it = profiles.begin(); it != profiles.end(); ++it) |
479 | profilesList->insertItem((*it)); | 467 | profilesList->insertItem((*it)); |
480 | 468 | ||
481 | // Remove any interface settings and mappings. | 469 | // Remove any interface settings and mappings. |
482 | Interfaces interfaces; | 470 | Interfaces interfaces; |
483 | // Go through them one by one | 471 | // Go through them one by one |
484 | QMap<Interface*, QListViewItem*>::Iterator it; | 472 | QMap<Interface*, QListViewItem*>::Iterator it; |
485 | for( it = items.begin(); it != items.end(); ++it ){ | 473 | for( it = items.begin(); it != items.end(); ++it ){ |
486 | QString interfaceName = it.key()->getInterfaceName(); | 474 | QString interfaceName = it.key()->getInterfaceName(); |
487 | qDebug(interfaceName.latin1()); | 475 | qDebug(interfaceName.latin1()); |
488 | if(interfaces.setInterface(interfaceName + "_" + profileToRemove)){ | 476 | if(interfaces.setInterface(interfaceName + "_" + profileToRemove)){ |
489 | interfaces.removeInterface(); | 477 | interfaces.removeInterface(); |
490 | if(interfaces.setMapping(interfaceName)){ | 478 | if(interfaces.setMapping(interfaceName)){ |
491 | if(profilesList->count() == 1) | 479 | if(profilesList->count() == 1) |
492 | interfaces.removeMapping(); | 480 | interfaces.removeMapping(); |
493 | else{ | 481 | else{ |
494 | interfaces.removeMap("map", interfaceName + "_" + profileToRemove); | 482 | interfaces.removeMap("map", interfaceName + "_" + profileToRemove); |
495 | } | 483 | } |
496 | } | 484 | } |
497 | interfaces.write(); | 485 | interfaces.write(); |
498 | break; | 486 | break; |
499 | } | 487 | } |
500 | } | 488 | } |
501 | } | 489 | } |
502 | } | 490 | } |
503 | 491 | ||
504 | /** | 492 | /** |
505 | * A new profile has been selected, change. | 493 | * A new profile has been selected, change. |
506 | * @param newProfile the new profile. | 494 | * @param newProfile the new profile. |
507 | */ | 495 | */ |
508 | void MainWindowImp::changeProfile(){ | 496 | void MainWindowImp::changeProfile(){ |
509 | if(profilesList->currentItem() == -1){ | 497 | if(profilesList->currentItem() == -1){ |
510 | QMessageBox::information(this, "Can't Change.","Please select a profile.", QMessageBox::Ok); | 498 | QMessageBox::information(this, "Can't Change.","Please select a profile.", QMessageBox::Ok); |
511 | return; | 499 | return; |
512 | } | 500 | } |
513 | QString newProfile = profilesList->text(profilesList->currentItem()); | 501 | QString newProfile = profilesList->text(profilesList->currentItem()); |
514 | if(newProfile != currentProfileLabel->text()){ | 502 | if(newProfile != currentProfileLabel->text()){ |
515 | currentProfileLabel->setText(newProfile); | 503 | currentProfileLabel->setText(newProfile); |
516 | QFile::remove(scheme); | 504 | QFile::remove(scheme); |
517 | QFile file(scheme); | 505 | QFile file(scheme); |
518 | if ( file.open(IO_ReadWrite) ) { | 506 | if ( file.open(IO_ReadWrite) ) { |
519 | QTextStream stream( &file ); | 507 | QTextStream stream( &file ); |
520 | stream << QString("SCHEME=%1").arg(newProfile); | 508 | stream << QString("SCHEME=%1").arg(newProfile); |
521 | file.close(); | 509 | file.close(); |
522 | } | 510 | } |
523 | // restart all up devices? | 511 | // restart all up devices? |
524 | if(QMessageBox::information(this, "Question","Restart all running interfaces?", QMessageBox::Ok, QMessageBox::No) == QMessageBox::Ok){ | 512 | if(QMessageBox::information(this, "Question","Restart all running interfaces?", QMessageBox::Ok, QMessageBox::No) == QMessageBox::Ok){ |
525 | // Go through them one by one | 513 | // Go through them one by one |
526 | QMap<Interface*, QListViewItem*>::Iterator it; | 514 | QMap<Interface*, QListViewItem*>::Iterator it; |
527 | for( it = items.begin(); it != items.end(); ++it ){ | 515 | for( it = items.begin(); it != items.end(); ++it ){ |
528 | if(it.key()->getStatus() == true) | 516 | if(it.key()->getStatus() == true) |
529 | it.key()->restart(); | 517 | it.key()->restart(); |
530 | } | 518 | } |
531 | } | 519 | } |
532 | } | 520 | } |
533 | // TODO change the profile in the modules | 521 | // TODO change the profile in the modules |
534 | } | 522 | } |
535 | 523 | ||
536 | // mainwindowimp.cpp | 524 | // mainwindowimp.cpp |
537 | 525 | ||
diff --git a/noncore/settings/networksettings/mainwindowimp.h b/noncore/settings/networksettings/mainwindowimp.h index e5284b4..382428c 100644 --- a/noncore/settings/networksettings/mainwindowimp.h +++ b/noncore/settings/networksettings/mainwindowimp.h | |||
@@ -1,59 +1,58 @@ | |||
1 | #ifndef MAINWINOWIMP_H | 1 | #ifndef MAINWINOWIMP_H |
2 | #define MAINWINOWIMP_H | 2 | #define MAINWINOWIMP_H |
3 | 3 | ||
4 | #include "mainwindow.h" | 4 | #include "mainwindow.h" |
5 | #include <qmap.h> | 5 | #include <qmap.h> |
6 | #include <qstringlist.h> | 6 | #include <qstringlist.h> |
7 | 7 | ||
8 | class Module; | 8 | class Module; |
9 | class Interface; | 9 | class Interface; |
10 | class QLibrary; | 10 | class QLibrary; |
11 | class KProcess; | 11 | class KProcess; |
12 | 12 | ||
13 | class MainWindowImp : public MainWindow { | 13 | class MainWindowImp : public MainWindow { |
14 | Q_OBJECT | 14 | Q_OBJECT |
15 | 15 | ||
16 | public: | 16 | public: |
17 | MainWindowImp(QWidget *parent=0, const char *name=0); | 17 | MainWindowImp(QWidget *parent=0, const char *name=0); |
18 | ~MainWindowImp(); | 18 | ~MainWindowImp(); |
19 | 19 | ||
20 | private slots: | 20 | private slots: |
21 | void getAllInterfaces(); | ||
22 | |||
21 | void addClicked(); | 23 | void addClicked(); |
22 | void removeClicked(); | 24 | void removeClicked(); |
23 | void configureClicked(); | 25 | void configureClicked(); |
24 | void informationClicked(); | 26 | void informationClicked(); |
25 | 27 | ||
26 | void jobDone(KProcess *process); | ||
27 | void getInterfaceList(); | ||
28 | |||
29 | void addProfile(); | 28 | void addProfile(); |
30 | void removeProfile(); | 29 | void removeProfile(); |
31 | void changeProfile(); | 30 | void changeProfile(); |
32 | 31 | ||
33 | void updateInterface(Interface *i); | 32 | void updateInterface(Interface *i); |
34 | void newProfileChanged(const QString& newText); | 33 | void newProfileChanged(const QString& newText); |
35 | 34 | ||
36 | private: | 35 | private: |
37 | void loadModules(QString path); | 36 | void loadModules(QString path); |
38 | 37 | ||
39 | Module* loadPlugin(QString pluginFileName, | 38 | Module* loadPlugin(QString pluginFileName, |
40 | QString resolveString = "create_plugin"); | 39 | QString resolveString = "create_plugin"); |
41 | 40 | ||
42 | // For our local list of names | 41 | // For our local list of names |
43 | QMap<QString, Interface*> interfaceNames; | 42 | QMap<QString, Interface*> interfaceNames; |
44 | 43 | ||
45 | QMap<Module*, QLibrary*> libraries; | 44 | QMap<Module*, QLibrary*> libraries; |
46 | QMap<Interface*, QListViewItem*> items; | 45 | QMap<Interface*, QListViewItem*> items; |
47 | QMap<QListViewItem*, Interface*> interfaceItems; | 46 | QMap<QListViewItem*, Interface*> interfaceItems; |
48 | 47 | ||
49 | QMap<KProcess*, QString> threads; | 48 | QMap<KProcess*, QString> threads; |
50 | QStringList profiles; | 49 | QStringList profiles; |
51 | 50 | ||
52 | bool advancedUserMode; | 51 | bool advancedUserMode; |
53 | QString scheme; | 52 | QString scheme; |
54 | }; | 53 | }; |
55 | 54 | ||
56 | #endif | 55 | #endif |
57 | 56 | ||
58 | // mainwindowimp.h | 57 | // mainwindowimp.h |
59 | 58 | ||
diff --git a/noncore/settings/networksettings/networksetup.pro b/noncore/settings/networksettings/networksetup.pro index 6420924..cb517ce 100644 --- a/noncore/settings/networksettings/networksetup.pro +++ b/noncore/settings/networksettings/networksetup.pro | |||
@@ -1,11 +1,11 @@ | |||
1 | DESTDIR = $(OPIEDIR)/bin | 1 | #DESTDIR = $(OPIEDIR)/bin |
2 | TEMPLATE = app | 2 | TEMPLATE = app |
3 | #CONFIG = qt warn_on debug | 3 | #CONFIG = qt warn_on debug |
4 | CONFIG = qt warn_on release | 4 | CONFIG = qt warn_on release |
5 | HEADERS = mainwindowimp.h addconnectionimp.h defaultmodule.h kprocctrl.h module.h kprocess.h | 5 | HEADERS = mainwindowimp.h addconnectionimp.h defaultmodule.h module.h |
6 | SOURCES = main.cpp mainwindowimp.cpp addconnectionimp.cpp kprocctrl.cpp kprocess.cpp | 6 | SOURCES = main.cpp mainwindowimp.cpp addconnectionimp.cpp |
7 | INCLUDEPATH += $(OPIEDIR)/include interfaces/ | 7 | INCLUDEPATH += $(OPIEDIR)/include interfaces/ |
8 | DEPENDPATH += $(OPIEDIR)/include interfaces/ wlan | 8 | DEPENDPATH += $(OPIEDIR)/include interfaces/ wlan |
9 | LIBS += -lqpe -L$(OPIEDIR)/plugins/networksetup -Linterfaces/ -linterfaces | 9 | LIBS += -lqpe -L$(OPIEDIR)/plugins/networksetup -Linterfaces/ -linterfaces |
10 | INTERFACES = mainwindow.ui addconnection.ui | 10 | INTERFACES = mainwindow.ui addconnection.ui |
11 | TARGET = networksetup | 11 | TARGET = networksetup |
diff --git a/noncore/settings/networksettings/ppp/.cvsignore b/noncore/settings/networksettings/ppp/.cvsignore new file mode 100644 index 0000000..d753773 --- a/dev/null +++ b/noncore/settings/networksettings/ppp/.cvsignore | |||
@@ -0,0 +1,23 @@ | |||
1 | .moc.cpp | ||
2 | *.moc | ||
3 | *.moc.o | ||
4 | *.o | ||
5 | moc_*.cpp | ||
6 | .libs | ||
7 | .deps | ||
8 | .moc.o | ||
9 | .o | ||
10 | Makefile* | ||
11 | networksetup | ||
12 | addconnection.cpp | ||
13 | addconnection.h | ||
14 | interfaceadvanced.cpp | ||
15 | interfaceadvanced.h | ||
16 | interfaceinformation.cpp | ||
17 | interfaceinformation.h | ||
18 | interfacesetup.cpp | ||
19 | interfacesetup.h | ||
20 | mainwindow.cpp | ||
21 | mainwindow.h | ||
22 | systemadvanced.cpp | ||
23 | systemadvanced.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> | ||