summaryrefslogtreecommitdiff
authorbenmeyer <benmeyer>2002-09-30 14:26:33 (UTC)
committer benmeyer <benmeyer>2002-09-30 14:26:33 (UTC)
commit9965bd5c49ff2f22d640d132ac343fdec97b3fb4 (patch) (side-by-side diff)
tree45e8f1d1bf414530b637692ba43b730110611856
parent5db3af80f392f8f063f53cbbad67bbe7c5c6eb6d (diff)
downloadopie-9965bd5c49ff2f22d640d132ac343fdec97b3fb4.zip
opie-9965bd5c49ff2f22d640d132ac343fdec97b3fb4.tar.gz
opie-9965bd5c49ff2f22d640d132ac343fdec97b3fb4.tar.bz2
Initial commit
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/net/networksetup/TODO1
-rw-r--r--noncore/net/networksetup/addservice.ui154
-rw-r--r--noncore/net/networksetup/addserviceimp.cpp26
-rw-r--r--noncore/net/networksetup/addserviceimp.h26
-rw-r--r--noncore/net/networksetup/defaultmodule.h26
-rw-r--r--noncore/net/networksetup/interface.cpp236
-rw-r--r--noncore/net/networksetup/interface.h65
-rw-r--r--noncore/net/networksetup/interfaceadvanced.ui323
-rw-r--r--noncore/net/networksetup/interfaceedit.cpp141
-rw-r--r--noncore/net/networksetup/interfaceedit.h56
-rw-r--r--noncore/net/networksetup/interfaceinformation.ui317
-rw-r--r--noncore/net/networksetup/interfaceinformationimp.cpp94
-rw-r--r--noncore/net/networksetup/interfaceinformationimp.h31
-rw-r--r--noncore/net/networksetup/interfaces.cpp513
-rw-r--r--noncore/net/networksetup/interfaces.h70
-rw-r--r--noncore/net/networksetup/interfacesetup.ui274
-rw-r--r--noncore/net/networksetup/interfacesetupimp.cpp147
-rw-r--r--noncore/net/networksetup/interfacesetupimp.h30
-rw-r--r--noncore/net/networksetup/kprocctrl.cpp267
-rw-r--r--noncore/net/networksetup/kprocctrl.h120
-rw-r--r--noncore/net/networksetup/kprocess.cpp919
-rw-r--r--noncore/net/networksetup/kprocess.h804
-rw-r--r--noncore/net/networksetup/main.cpp13
-rw-r--r--noncore/net/networksetup/mainwindow.ui321
-rw-r--r--noncore/net/networksetup/mainwindowimp.cpp308
-rw-r--r--noncore/net/networksetup/mainwindowimp.h53
-rw-r--r--noncore/net/networksetup/module.h33
-rw-r--r--noncore/net/networksetup/networksetup.pro10
-rw-r--r--noncore/net/networksetup/systemadvanced.ui443
-rw-r--r--noncore/settings/networksettings/TODO1
-rw-r--r--noncore/settings/networksettings/addservice.ui154
-rw-r--r--noncore/settings/networksettings/addserviceimp.cpp26
-rw-r--r--noncore/settings/networksettings/addserviceimp.h26
-rw-r--r--noncore/settings/networksettings/defaultmodule.h26
-rw-r--r--noncore/settings/networksettings/interface.cpp236
-rw-r--r--noncore/settings/networksettings/interface.h65
-rw-r--r--noncore/settings/networksettings/interfaceadvanced.ui323
-rw-r--r--noncore/settings/networksettings/interfaceedit.cpp141
-rw-r--r--noncore/settings/networksettings/interfaceedit.h56
-rw-r--r--noncore/settings/networksettings/interfaceinformation.ui317
-rw-r--r--noncore/settings/networksettings/interfaceinformationimp.cpp94
-rw-r--r--noncore/settings/networksettings/interfaceinformationimp.h31
-rw-r--r--noncore/settings/networksettings/interfaces.cpp513
-rw-r--r--noncore/settings/networksettings/interfaces.h70
-rw-r--r--noncore/settings/networksettings/interfacesetup.ui274
-rw-r--r--noncore/settings/networksettings/interfacesetupimp.cpp147
-rw-r--r--noncore/settings/networksettings/interfacesetupimp.h30
-rw-r--r--noncore/settings/networksettings/kprocctrl.cpp267
-rw-r--r--noncore/settings/networksettings/kprocctrl.h120
-rw-r--r--noncore/settings/networksettings/kprocess.cpp919
-rw-r--r--noncore/settings/networksettings/kprocess.h804
-rw-r--r--noncore/settings/networksettings/main.cpp13
-rw-r--r--noncore/settings/networksettings/mainwindow.ui321
-rw-r--r--noncore/settings/networksettings/mainwindowimp.cpp308
-rw-r--r--noncore/settings/networksettings/mainwindowimp.h53
-rw-r--r--noncore/settings/networksettings/module.h33
-rw-r--r--noncore/settings/networksettings/networksetup.pro10
-rw-r--r--noncore/settings/networksettings/systemadvanced.ui443
58 files changed, 11642 insertions, 0 deletions
diff --git a/noncore/net/networksetup/TODO b/noncore/net/networksetup/TODO
new file mode 100644
index 0000000..9a1657a
--- a/dev/null
+++ b/noncore/net/networksetup/TODO
@@ -0,0 +1 @@
+Fix DHCP obtained and expoired info
diff --git a/noncore/net/networksetup/addservice.ui b/noncore/net/networksetup/addservice.ui
new file mode 100644
index 0000000..929f4fb
--- a/dev/null
+++ b/noncore/net/networksetup/addservice.ui
@@ -0,0 +1,154 @@
+<!DOCTYPE UI><UI>
+<class>AddService</class>
+<widget>
+ <class>QDialog</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>AddService</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>245</width>
+ <height>268</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>Add Network Service</string>
+ </property>
+ <grid>
+ <property stdset="1">
+ <name>margin</name>
+ <number>11</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget row="3" column="1" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cancelButton</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Cancel</string>
+ </property>
+ </widget>
+ <widget row="3" column="0" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>addButton</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Add</string>
+ </property>
+ </widget>
+ <widget row="0" column="0" rowspan="1" colspan="2" >
+ <class>QListView</class>
+ <column>
+ <property>
+ <name>text</name>
+ <string>Services</string>
+ </property>
+ <property>
+ <name>clickable</name>
+ <bool>true</bool>
+ </property>
+ <property>
+ <name>resizeable</name>
+ <bool>true</bool>
+ </property>
+ </column>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>registeredServicesList</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>3</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>minimumSize</name>
+ <size>
+ <width>0</width>
+ <height>75</height>
+ </size>
+ </property>
+ </widget>
+ <spacer row="2" column="1" >
+ <property>
+ <name>name</name>
+ <cstring>Spacer12</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Vertical</enum>
+ </property>
+ <property stdset="1">
+ <name>sizeType</name>
+ <enum>Expanding</enum>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget row="1" column="0" rowspan="1" colspan="2" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>help</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>4</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>LAN - TCP/IP
+For Local-area network connections through PC_CARD network interfdace cards.</string>
+ </property>
+ <property stdset="1">
+ <name>alignment</name>
+ <set>WordBreak|AlignTop|AlignLeft</set>
+ </property>
+ <property>
+ <name>vAlign</name>
+ </property>
+ <property>
+ <name>wordwrap</name>
+ </property>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>cancelButton</sender>
+ <signal>clicked()</signal>
+ <receiver>AddService</receiver>
+ <slot>reject()</slot>
+ </connection>
+ <connection>
+ <sender>addButton</sender>
+ <signal>clicked()</signal>
+ <receiver>AddService</receiver>
+ <slot>accept()</slot>
+ </connection>
+</connections>
+</UI>
diff --git a/noncore/net/networksetup/addserviceimp.cpp b/noncore/net/networksetup/addserviceimp.cpp
new file mode 100644
index 0000000..ac79d06
--- a/dev/null
+++ b/noncore/net/networksetup/addserviceimp.cpp
@@ -0,0 +1,26 @@
+#include "addserviceimp.h"
+#include <qpe/qlibrary.h>
+#include <qlistview.h>
+#include <qlist.h>
+
+void AddServiceImp::addServices(QList<QString> list){
+ list.setAutoDelete(true);
+
+ for(uint i = 0; i < list.count(); i++){
+ QString pluginFileName = "";
+ QLibrary *lib = new QLibrary(pluginFileName);
+ void *functionPointer = lib->resolve("info");
+ if( !functionPointer ){
+ qDebug(QString("AddServiceImp: File: %1 is not a plugin, but though was.").arg(pluginFileName).latin1());
+ delete lib;
+ break;
+ }
+
+ // Try to get an info.
+ QString info = ((QString (*)()) functionPointer)();
+ QListViewItem *newItem = new QListViewItem(registeredServicesList, info);
+ }
+}
+
+
+// addserviceimp.cpp
diff --git a/noncore/net/networksetup/addserviceimp.h b/noncore/net/networksetup/addserviceimp.h
new file mode 100644
index 0000000..7cacb97
--- a/dev/null
+++ b/noncore/net/networksetup/addserviceimp.h
@@ -0,0 +1,26 @@
+#ifndef ADDSERVICEIMP_H
+#define ADDSERVICEIMP_H
+
+#include "addservice.h"
+#include <qmap.h>
+#include <qlist.h>
+
+class QListViewItem;
+
+class AddServiceImp : public AddService {
+
+Q_OBJECT
+
+public:
+ AddServiceImp(QWidget *parent=0, const char *name=0, WFlags f=0):AddService(parent, name, f){};
+ void addServices(QList<QString> list);
+
+private:
+ QMap<QListViewItem*, QString> pluginInfo;
+
+};
+
+#endif
+
+// addserviceimp.h
+
diff --git a/noncore/net/networksetup/defaultmodule.h b/noncore/net/networksetup/defaultmodule.h
new file mode 100644
index 0000000..c7791d5
--- a/dev/null
+++ b/noncore/net/networksetup/defaultmodule.h
@@ -0,0 +1,26 @@
+#ifndef MODULE_H
+#define MODULE_H
+
+#include "module.h"
+
+class QWidget;
+
+class DefaultModule : Module{
+
+public:
+ DefaultModule(){};
+
+ virtual bool isOwner(Interface *i);
+ virtual QWidget *configure();
+ virtual QWidget *information()};
+ virtual QList<Interface> getInterfaces();
+ virtual QMap<QString, QString> possibleNewInterfaces();
+ virtual Interface *addNewInterface(QString name);
+ virtual bool remove(Interface* i);
+
+};
+
+#endif
+
+// module.h
+
diff --git a/noncore/net/networksetup/interface.cpp b/noncore/net/networksetup/interface.cpp
new file mode 100644
index 0000000..b9b09ad
--- a/dev/null
+++ b/noncore/net/networksetup/interface.cpp
@@ -0,0 +1,236 @@
+#include "interface.h"
+#include <qdatetime.h>
+#include <qfile.h>
+#include <qfileinfo.h>
+#include <qtextstream.h>
+
+#define IFCONFIG "/sbin/ifconfig"
+#define HDCP_INFO_DIR "/etc/dhcpc"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+Interface::Interface(QString name, bool newSatus): status(newSatus), attached(false), interfaceName(name), hardareName("Unknown"), moduleOwner("Default"), macAddress(""), ip("0.0.0.0"), broadcast(""), subnetMask("0.0.0.0"), dhcp(false){
+ refresh();
+}
+
+/**
+ * Try to start the interface.
+ * @return bool true if successfull.
+ */
+bool Interface::start(){
+ // check to see if we are already running.
+ if(status)
+ return false;
+
+ int ret = system(QString("%1 %2 up").arg(IFCONFIG).arg(interfaceName).latin1());
+ if(ret != 0)
+ return false;
+
+ status = true;
+ refresh();
+ return true;
+}
+
+/**
+ * Try to stop the interface.
+ * @return bool true if successfull.
+ */
+bool Interface::stop(){
+ // check to see if we are already stopped.
+ if(status == false)
+ return false;
+
+ int ret = system(QString("%1 %2 down").arg(IFCONFIG).arg(interfaceName).latin1());
+ if(ret != 0)
+ return false;
+
+ status = true;
+ refresh();
+ return true;
+}
+/**
+ * Try to restart the interface.
+ * @return bool true if successfull.
+ */
+bool Interface::restart(){
+ return (stop() && start());
+}
+
+/**
+ * Try to refresh the information about the interface.
+ * First call ifconfig, then check the dhcp-info file
+ * @return bool true if successfull.
+ */
+bool Interface::refresh(){
+ // See if we are up.
+ if(status == false){
+ macAddress = "";
+ ip = "0.0.0.0";
+ subnetMask = "0.0.0.0";
+ broadcast = "";
+ dhcp = false;
+ dhcpServerIp = "";
+ leaseObtained = "";
+ leaseExpires = "";
+ return true;
+ }
+
+ QString fileName = QString("/tmp/%1_ifconfig_info").arg(interfaceName);
+ int ret = system(QString("%1 %2 > %3").arg(IFCONFIG).arg(interfaceName).arg(fileName).latin1());
+ if(ret != 0){
+ qDebug(QString("Interface: Ifconfig return value: %1, is not 0").arg(ret).latin1());
+ return false;
+ }
+
+ QFile file(fileName);
+ if (!file.open(IO_ReadOnly)){
+ qDebug(QString("Interface: Can't open file: %1").arg(fileName).latin1());
+ return false;
+ }
+
+ // Set to the defaults
+ macAddress = "";
+ ip = "0.0.0.0";
+ subnetMask = "0.0.0.0";
+ broadcast = "";
+
+ QTextStream stream( &file );
+ QString line;
+ while ( !stream.eof() ) {
+ line = stream.readLine();
+ if(line.contains("HWaddr")){
+ int mac = line.find("HWaddr");
+ macAddress = line.mid(mac+7, line.length());
+ }
+ if(line.contains("inet addr")){
+ int ipl = line.find("inet addr");
+ int space = line.find(" ", ipl+10);
+ ip = line.mid(ipl+10, space-ipl-10);
+ }
+ if(line.contains("Mask")){
+ int mask = line.find("Mask");
+ subnetMask = line.mid(mask+5, line.length());
+ }
+ if(line.contains("Bcast")){
+ int mask = line.find("Bcast");
+ int space = line.find(" ", mask+6);
+ broadcast = line.mid(mask+6, space-mask-6);
+ }
+ }
+ file.close();
+ QFile::remove(fileName);
+
+ // DHCP TESTING
+ // reset DHCP info
+ dhcpServerIp = "";
+ leaseObtained = "";
+ leaseExpires = "";
+ dhcp = false;
+
+ // See if we have
+ QString dhcpFile(QString(HDCP_INFO_DIR "/dhcpcd-%1.info").arg(interfaceName));
+ // If there is no DHCP information then exit now with no errors.
+ if(!QFile::exists(dhcpFile)){
+ return true;
+ }
+
+ file.setName(dhcpFile);
+ if (!file.open(IO_ReadOnly)){
+ qDebug(QString("Interface: Can't open file: %1").arg(dhcpFile).latin1());
+ return false;
+ }
+
+ // leaseTime and renewalTime and used if pid and deamon exe can be accessed.
+ int leaseTime = 0;
+ int renewalTime = 0;
+
+ stream.setDevice( &file );
+ while ( !stream.eof() ) {
+ line = stream.readLine();
+ if(line.contains("DHCPSID="))
+ dhcpServerIp = line.mid(8, line.length());
+ if(line.contains("LEASETIME="))
+ leaseTime = line.mid(10, line.length()).toInt();
+ if(line.contains("RENEWALTIME="))
+ renewalTime = line.mid(12, line.length()).toInt();
+ }
+ file.close();
+ //qDebug(QString("Interface: leaseTime: %1").arg(leaseTime).latin1());
+ //qDebug(QString("Interface: renewalTime: %1").arg(renewalTime).latin1());
+
+ // Get the pid of the deamond
+ dhcpFile = (QString(HDCP_INFO_DIR "/dhcpcd-%1.pid").arg(interfaceName));
+ file.setName(dhcpFile);
+ if (!file.open(IO_ReadOnly)){
+ qDebug(QString("Interface: Can't open file: %1").arg(dhcpFile).latin1());
+ return false;
+ }
+
+ int pid = -1;
+ stream.setDevice( &file );
+ while ( !stream.eof() ) {
+ line = stream.readLine();
+ pid = line.toInt();
+ }
+ file.close();
+
+ if( pid == -1){
+ qDebug("Interface: Could not get pid of dhcpc deamon.");
+ return false;
+ }
+
+ // Get the start running time of the deamon
+ fileName = (QString("/proc/%1/stat").arg(pid));
+ file.setName(fileName);
+ stream.setDevice( &file );
+ if (!file.open(IO_ReadOnly)){
+ qDebug(QString("Interface: Can't open file: %1").arg(fileName).latin1());
+ return false;
+ }
+ while ( !stream.eof() ) {
+ line = stream.readLine();
+ }
+ file.close();
+ long time = 0;
+ // Grab the start time
+ // pid com state ppid pgrp session tty_nr tpgid flags
+ int r = sscanf(line.latin1(), "%*d %*s %*c %*d %*d %*d %*d %*d %*u "
+ // minflt cminflt majflt cmajflt utime stime cutime cstime priority
+ "%*u %*u %*u %*u %*u %*u %*d %*d %*d "
+ // nice 0 itrealvalue starttime
+ "%*d %*d %*d %lu", (long*) &time);
+ time = time/100;
+
+ QDateTime datetime(QDateTime::currentDateTime());
+
+ // Get the uptime of the computer.
+ QFile f("/proc/uptime");
+ if ( f.open(IO_ReadOnly) ) { // file opened successfully
+ QTextStream t( &f ); // use a text stream
+ int sec = 0;
+ t >> sec;
+ datetime = datetime.addSecs((-1*sec));
+ f.close();
+ }
+ else{
+ qDebug("Interface: Can't open /proc/uptime to retrive uptime.");
+ return false;
+ }
+
+ datetime = datetime.addSecs(time);
+ //qDebug(QString("Interface: %1 %2").arg(datetime.toString()).arg(pid).latin1());
+
+ // Calculate the start and renew times
+ leaseObtained = datetime.toString();
+
+ // Calculate the start and renew times
+ datetime = datetime.addSecs(leaseTime);
+ leaseExpires = datetime.toString();
+
+ dhcp = true;
+ return true;
+}
+
+// interface.cpp
+
diff --git a/noncore/net/networksetup/interface.h b/noncore/net/networksetup/interface.h
new file mode 100644
index 0000000..1ad71eb
--- a/dev/null
+++ b/noncore/net/networksetup/interface.h
@@ -0,0 +1,65 @@
+#ifndef INTERFACE_H
+#define INTERFACE_H
+
+#include <qstring.h>
+
+class Interface {
+
+public:
+ Interface(QString name = "unknown", bool status = false);
+ virtual ~Interface(){};
+
+ virtual bool getStatus(){ return status; };
+ virtual void setStatus(bool newSatus){ status = newSatus; refresh(); };
+
+ virtual bool isAttached(){ return attached; };
+ virtual void setAttached(bool isAttached=false){ attached = isAttached; };
+
+ virtual QString getInterfaceName(){ return interfaceName; };
+ virtual void setInterfaceName(QString name="unknown"){ interfaceName = name; };
+
+ virtual QString getHardwareName(){ return hardareName; };
+ virtual void setHardwareName(QString name="Unknown"){ hardareName = name; };
+
+ virtual QString getModuleOwner(){ return moduleOwner; };
+ virtual void setModuleOwner(QString owner="Default"){ moduleOwner = owner; };
+
+ // inet information.
+ QString getMacAddress(){ return macAddress; };
+ QString getIp(){ return ip; };
+ QString getSubnetMask(){ return subnetMask; };
+ QString getBroadcast(){ return broadcast; };
+ bool isDhcp(){ return dhcp; };
+ QString getDhcpServerIp(){ return dhcpServerIp; };
+ QString getLeaseObtained(){ return leaseObtained; };
+ QString getLeaseExpires(){ return leaseExpires; };
+
+ bool refresh();
+ bool start();
+ bool stop();
+ bool restart();
+
+private:
+ // Interface information
+ bool status;
+ bool attached;
+ QString interfaceName;
+ QString hardareName;
+ QString moduleOwner;
+
+ // Network information
+ QString macAddress;
+ QString ip;
+ QString broadcast;
+ QString subnetMask;
+ bool dhcp;
+ QString dhcpServerIp;
+ QString leaseObtained;
+ QString leaseExpires;
+
+};
+
+#endif
+
+// interface.h
+
diff --git a/noncore/net/networksetup/interfaceadvanced.ui b/noncore/net/networksetup/interfaceadvanced.ui
new file mode 100644
index 0000000..8ef0b29
--- a/dev/null
+++ b/noncore/net/networksetup/interfaceadvanced.ui
@@ -0,0 +1,323 @@
+<!DOCTYPE UI><UI>
+<class>InterfaceAdvanced</class>
+<widget>
+ <class>QWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>InterfaceAdvanced</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>197</width>
+ <height>253</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>Advanced Interface Information</string>
+ </property>
+ <grid>
+ <property stdset="1">
+ <name>margin</name>
+ <number>11</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget row="1" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel1</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>MAC Address</string>
+ </property>
+ </widget>
+ <widget row="0" column="1" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>interfaceName</cstring>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>Panel</enum>
+ </property>
+ <property stdset="1">
+ <name>frameShadow</name>
+ <enum>Sunken</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>eth0</string>
+ </property>
+ </widget>
+ <widget row="2" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel3</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>IP Address</string>
+ </property>
+ </widget>
+ <widget row="1" column="1" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>macAddressLabel</cstring>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>Panel</enum>
+ </property>
+ <property stdset="1">
+ <name>frameShadow</name>
+ <enum>Sunken</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>00:00:00:00:00:00</string>
+ </property>
+ </widget>
+ <widget row="0" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel7</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Interface</string>
+ </property>
+ </widget>
+ <widget row="8" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel9</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Lease Expires</string>
+ </property>
+ </widget>
+ <widget row="8" column="1" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>leaseExpiresLabel</cstring>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>Panel</enum>
+ </property>
+ <property stdset="1">
+ <name>frameShadow</name>
+ <enum>Sunken</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string></string>
+ </property>
+ </widget>
+ <widget row="7" column="1" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>leaseObtainedLabel</cstring>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>Panel</enum>
+ </property>
+ <property stdset="1">
+ <name>frameShadow</name>
+ <enum>Sunken</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string></string>
+ </property>
+ </widget>
+ <widget row="7" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel8</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Lease Obtained</string>
+ </property>
+ </widget>
+ <widget row="6" column="1" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>dhcpServerLabel</cstring>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>Panel</enum>
+ </property>
+ <property stdset="1">
+ <name>frameShadow</name>
+ <enum>Sunken</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>255.255.255.255</string>
+ </property>
+ </widget>
+ <widget row="6" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel6</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>DHCP Server</string>
+ </property>
+ </widget>
+ <widget row="4" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel4</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Subnet Mask</string>
+ </property>
+ </widget>
+ <widget row="2" column="1" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>ipAddressLabel</cstring>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>Panel</enum>
+ </property>
+ <property stdset="1">
+ <name>frameShadow</name>
+ <enum>Sunken</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>0.0.0.0</string>
+ </property>
+ </widget>
+ <widget row="4" column="1" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>subnetMaskLabel</cstring>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>Panel</enum>
+ </property>
+ <property stdset="1">
+ <name>frameShadow</name>
+ <enum>Sunken</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>0.0.0.0</string>
+ </property>
+ </widget>
+ <spacer row="9" column="1" >
+ <property>
+ <name>name</name>
+ <cstring>Spacer2</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Vertical</enum>
+ </property>
+ <property stdset="1">
+ <name>sizeType</name>
+ <enum>Expanding</enum>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget row="3" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel2</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Broadcast</string>
+ </property>
+ </widget>
+ <widget row="3" column="1" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>broadcastLabel</cstring>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>Panel</enum>
+ </property>
+ <property stdset="1">
+ <name>frameShadow</name>
+ <enum>Sunken</enum>
+ </property>
+ </widget>
+ <widget row="5" column="0" rowspan="1" colspan="2" >
+ <class>Line</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Line2</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ </grid>
+</widget>
+<customwidgets>
+ <customwidget>
+ <class>QWidget</class>
+ <header location="local">qwidget.h</header>
+ <sizehint>
+ <width>100</width>
+ <height>100</height>
+ </sizehint>
+ <container>0</container>
+ <sizepolicy>
+ <hordata>7</hordata>
+ <verdata>7</verdata>
+ </sizepolicy>
+ <pixmap>image0</pixmap>
+ </customwidget>
+</customwidgets>
+<images>
+ <image>
+ <name>image0</name>
+ <data format="XPM.GZ" length="45">789cd3d7528808f055d0d2e72a2e492cc94c5648ce482c52d04a29cdcdad8c8eb5ade6523250004143a55a6b2e0026630c4f</data>
+ </image>
+</images>
+</UI>
diff --git a/noncore/net/networksetup/interfaceedit.cpp b/noncore/net/networksetup/interfaceedit.cpp
new file mode 100644
index 0000000..25599ef
--- a/dev/null
+++ b/noncore/net/networksetup/interfaceedit.cpp
@@ -0,0 +1,141 @@
+/****************************************************************************
+** Form implementation generated from reading ui file 'interfaceedit.ui'
+**
+** Created: Mon Sep 23 12:18:55 2002
+** by: The User Interface Compiler (uic)
+**
+** WARNING! All changes made in this file will be lost!
+****************************************************************************/
+#include "interfaceedit.h"
+
+#include <qcheckbox.h>
+#include <qcombobox.h>
+#include <qframe.h>
+#include <qgroupbox.h>
+#include <qlabel.h>
+#include <qlineedit.h>
+#include <qpushbutton.h>
+#include <qspinbox.h>
+#include "qwidget.h"
+#include <qlayout.h>
+#include <qvariant.h>
+#include <qtooltip.h>
+#include <qwhatsthis.h>
+
+/*
+ * Constructs a InterfaceConfiguration which is a child of 'parent', with the
+ * name 'name' and widget flags set to 'f'
+ */
+InterfaceConfiguration::InterfaceConfiguration( QWidget* parent, const char* name, WFlags fl )
+ : QWidget( parent, name, fl )
+{
+ if ( !name )
+ setName( "InterfaceConfiguration" );
+ resize( 177, 306 );
+ setCaption( tr( "Interface Configuration" ) );
+ InterfaceConfigurationLayout = new QGridLayout( this );
+ InterfaceConfigurationLayout->setSpacing( 6 );
+ InterfaceConfigurationLayout->setMargin( 11 );
+
+ profile = new QComboBox( FALSE, this, "profile" );
+ profile->insertItem( tr( "All" ) );
+
+ InterfaceConfigurationLayout->addWidget( profile, 2, 1 );
+
+ TextLabel1 = new QLabel( this, "TextLabel1" );
+ TextLabel1->setText( tr( "Profile:" ) );
+
+ InterfaceConfigurationLayout->addWidget( TextLabel1, 2, 0 );
+
+ Line1 = new QFrame( this, "Line1" );
+ Line1->setFrameStyle( QFrame::HLine | QFrame::Sunken );
+
+ InterfaceConfigurationLayout->addMultiCellWidget( Line1, 1, 1, 0, 1 );
+
+ CheckBox3 = new QCheckBox( this, "CheckBox3" );
+ CheckBox3->setText( tr( "Automaticly bring up" ) );
+
+ InterfaceConfigurationLayout->addMultiCellWidget( CheckBox3, 0, 0, 0, 1 );
+
+ dhcpCheckBox = new QCheckBox( this, "dhcpCheckBox" );
+ dhcpCheckBox->setText( tr( "DHCP" ) );
+
+ InterfaceConfigurationLayout->addMultiCellWidget( dhcpCheckBox, 3, 3, 0, 1 );
+
+ TextLabel3_3_2 = new QLabel( this, "TextLabel3_3_2" );
+ TextLabel3_3_2->setText( tr( "Lease Hours" ) );
+
+ InterfaceConfigurationLayout->addWidget( TextLabel3_3_2, 4, 0 );
+
+ SpinBox1_2 = new QSpinBox( this, "SpinBox1_2" );
+ SpinBox1_2->setMaxValue( 336 );
+ SpinBox1_2->setMinValue( 1 );
+ SpinBox1_2->setValue( 24 );
+
+ InterfaceConfigurationLayout->addWidget( SpinBox1_2, 4, 1 );
+ QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding );
+ InterfaceConfigurationLayout->addItem( spacer, 11, 1 );
+
+ TextLabel4 = new QLabel( this, "TextLabel4" );
+ TextLabel4->setText( tr( "IP Address" ) );
+
+ InterfaceConfigurationLayout->addWidget( TextLabel4, 6, 0 );
+
+ ipAddressEdit = new QLineEdit( this, "ipAddressEdit" );
+
+ InterfaceConfigurationLayout->addWidget( ipAddressEdit, 6, 1 );
+
+ TextLabel5 = new QLabel( this, "TextLabel5" );
+ TextLabel5->setText( tr( "Subnet Mask" ) );
+
+ InterfaceConfigurationLayout->addWidget( TextLabel5, 7, 0 );
+
+ firstDNSLineEdit = new QLineEdit( this, "firstDNSLineEdit" );
+
+ InterfaceConfigurationLayout->addWidget( firstDNSLineEdit, 9, 1 );
+
+ TextLabel3 = new QLabel( this, "TextLabel3" );
+ TextLabel3->setText( tr( "Second DNS" ) );
+
+ InterfaceConfigurationLayout->addWidget( TextLabel3, 10, 0 );
+
+ subnetMaskEdit = new QLineEdit( this, "subnetMaskEdit" );
+
+ InterfaceConfigurationLayout->addWidget( subnetMaskEdit, 7, 1 );
+
+ gatewayEdit = new QLineEdit( this, "gatewayEdit" );
+
+ InterfaceConfigurationLayout->addWidget( gatewayEdit, 8, 1 );
+
+ TextLabel7 = new QLabel( this, "TextLabel7" );
+ TextLabel7->setText( tr( "Gateway" ) );
+
+ InterfaceConfigurationLayout->addWidget( TextLabel7, 8, 0 );
+
+ TextLabel2 = new QLabel( this, "TextLabel2" );
+ TextLabel2->setText( tr( "First DNS" ) );
+
+ InterfaceConfigurationLayout->addWidget( TextLabel2, 9, 0 );
+
+ secondDNSLineEdit = new QLineEdit( this, "secondDNSLineEdit" );
+
+ InterfaceConfigurationLayout->addWidget( secondDNSLineEdit, 10, 1 );
+
+ GroupBox2 = new QGroupBox( this, "GroupBox2" );
+ GroupBox2->setTitle( tr( "Static Ip Configuration" ) );
+
+ InterfaceConfigurationLayout->addMultiCellWidget( GroupBox2, 5, 5, 0, 1 );
+
+ // signals and slots connections
+ connect( dhcpCheckBox, SIGNAL( toggled(bool) ), SpinBox1_2, SLOT( setEnabled(bool) ) );
+ connect( dhcpCheckBox, SIGNAL( toggled(bool) ), GroupBox2, SLOT( setDisabled(bool) ) );
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+InterfaceConfiguration::~InterfaceConfiguration()
+{
+ // no need to delete child widgets, Qt does it all for us
+}
+
diff --git a/noncore/net/networksetup/interfaceedit.h b/noncore/net/networksetup/interfaceedit.h
new file mode 100644
index 0000000..a65c030
--- a/dev/null
+++ b/noncore/net/networksetup/interfaceedit.h
@@ -0,0 +1,56 @@
+/****************************************************************************
+** Form interface generated from reading ui file 'interfaceedit.ui'
+**
+** Created: Mon Sep 23 12:18:55 2002
+** by: The User Interface Compiler (uic)
+**
+** WARNING! All changes made in this file will be lost!
+****************************************************************************/
+#ifndef INTERFACECONFIGURATION_H
+#define INTERFACECONFIGURATION_H
+
+#include <qvariant.h>
+#include <qwidget.h>
+class QVBoxLayout;
+class QHBoxLayout;
+class QGridLayout;
+class QCheckBox;
+class QComboBox;
+class QFrame;
+class QGroupBox;
+class QLabel;
+class QLineEdit;
+class QSpinBox;
+
+class InterfaceConfiguration : public QWidget
+{
+ Q_OBJECT
+
+public:
+ InterfaceConfiguration( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );
+ ~InterfaceConfiguration();
+
+ QComboBox* profile;
+ QLabel* TextLabel1;
+ QFrame* Line1;
+ QCheckBox* CheckBox3;
+ QCheckBox* dhcpCheckBox;
+ QLabel* TextLabel3_3_2;
+ QSpinBox* SpinBox1_2;
+ QLabel* TextLabel4;
+ QLineEdit* ipAddressEdit;
+ QLabel* TextLabel5;
+ QLineEdit* firstDNSLineEdit;
+ QLabel* TextLabel3;
+ QLineEdit* subnetMaskEdit;
+ QLineEdit* gatewayEdit;
+ QLabel* TextLabel7;
+ QLabel* TextLabel2;
+ QLineEdit* secondDNSLineEdit;
+ QGroupBox* GroupBox2;
+
+protected:
+ QGridLayout* InterfaceConfigurationLayout;
+};
+
+#endif // INTERFACECONFIGURATION_H
diff --git a/noncore/net/networksetup/interfaceinformation.ui b/noncore/net/networksetup/interfaceinformation.ui
new file mode 100644
index 0000000..2a9b3fb
--- a/dev/null
+++ b/noncore/net/networksetup/interfaceinformation.ui
@@ -0,0 +1,317 @@
+<!DOCTYPE UI><UI>
+<class>InterfaceInformation</class>
+<widget>
+ <class>QWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>InterfaceInformation</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>191</width>
+ <height>241</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>Interface Information</string>
+ </property>
+ <grid>
+ <property stdset="1">
+ <name>margin</name>
+ <number>11</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget row="4" column="0" rowspan="1" colspan="2" >
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout1</cstring>
+ </property>
+ <grid>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget row="1" column="0" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>refreshButton</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Refresh</string>
+ </property>
+ </widget>
+ <widget row="0" column="1" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>stopButton</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Stop</string>
+ </property>
+ </widget>
+ <widget row="1" column="1" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>restartButton</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Restart</string>
+ </property>
+ </widget>
+ <widget row="0" column="0" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>startButton</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Start</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget row="0" column="0" >
+ <class>Line</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Line1</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ <spacer row="6" column="1" >
+ <property>
+ <name>name</name>
+ <cstring>Spacer18</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Vertical</enum>
+ </property>
+ <property stdset="1">
+ <name>sizeType</name>
+ <enum>Expanding</enum>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget row="5" column="0" rowspan="1" colspan="2" >
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout2</cstring>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <spacer>
+ <property>
+ <name>name</name>
+ <cstring>Spacer10</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Horizontal</enum>
+ </property>
+ <property stdset="1">
+ <name>sizeType</name>
+ <enum>Expanding</enum>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>advancedButton</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>View Advanced Information</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget row="0" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel22</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>IP Address</string>
+ </property>
+ </widget>
+ <widget row="1" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel23</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Subnet Mask</string>
+ </property>
+ </widget>
+ <widget row="2" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel21</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>MAC Address</string>
+ </property>
+ </widget>
+ <widget row="3" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel24</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Broadcast</string>
+ </property>
+ </widget>
+ <widget row="1" column="1" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>subnetMaskLabel</cstring>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>Panel</enum>
+ </property>
+ <property stdset="1">
+ <name>frameShadow</name>
+ <enum>Sunken</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>0.0.0.0</string>
+ </property>
+ </widget>
+ <widget row="2" column="1" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>macAddressLabel</cstring>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>Panel</enum>
+ </property>
+ <property stdset="1">
+ <name>frameShadow</name>
+ <enum>Sunken</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>00:00:00:00:00:00</string>
+ </property>
+ </widget>
+ <widget row="3" column="1" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>broadcastLabel</cstring>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>Panel</enum>
+ </property>
+ <property stdset="1">
+ <name>frameShadow</name>
+ <enum>Sunken</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string></string>
+ </property>
+ </widget>
+ <widget row="0" column="1" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>ipAddressLabel</cstring>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>Panel</enum>
+ </property>
+ <property stdset="1">
+ <name>frameShadow</name>
+ <enum>Sunken</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>0.0.0.0</string>
+ </property>
+ </widget>
+ </grid>
+</widget>
+<customwidgets>
+ <customwidget>
+ <class>QWidget</class>
+ <header location="local">qwidget.h</header>
+ <sizehint>
+ <width>100</width>
+ <height>100</height>
+ </sizehint>
+ <container>0</container>
+ <sizepolicy>
+ <hordata>7</hordata>
+ <verdata>7</verdata>
+ </sizepolicy>
+ <pixmap>image0</pixmap>
+ </customwidget>
+</customwidgets>
+<images>
+ <image>
+ <name>image0</name>
+ <data format="XPM.GZ" length="646">789c6dd2c10ac2300c00d07bbf2234b7229d1be245fc04c5a3201e4615f430059d0711ff5ddb2e6bb236ec90eed134cb5a19d8ef36602af5ecdbfeeac05dda0798d3abebde87e3faa374d3807fa0d633a52d38d8de6f679fe33fc776e196f53cd010188256a3600a292882096246517815ca99884606e18044a3a40d91824820924265a7923a2e8bcd05f33db1173e002913175f2a6be6d3294871a2d95fa00e8a94ee017b69d339d90df1e77c57ea072ede6758</data>
+ </image>
+</images>
+</UI>
diff --git a/noncore/net/networksetup/interfaceinformationimp.cpp b/noncore/net/networksetup/interfaceinformationimp.cpp
new file mode 100644
index 0000000..e37e0f8
--- a/dev/null
+++ b/noncore/net/networksetup/interfaceinformationimp.cpp
@@ -0,0 +1,94 @@
+#include "interfaceinformationimp.h"
+#include "interfaceadvanced.h"
+
+#include <qpushbutton.h>
+#include <qlabel.h>
+#include <assert.h>
+
+/**
+ * Constructor for the InterfaceInformationImp class. This class pretty much
+ * just display's information about the interface that is passed to it.
+ */
+InterfaceInformationImp::InterfaceInformationImp(QWidget *parent, const char *name, Interface *i, WFlags f):InterfaceInformation(parent, name, f){
+ assert(i);
+
+ interface = i;
+ updateInterface();
+ connect(startButton, SIGNAL(clicked()), this, SLOT(start()));
+ connect(stopButton, SIGNAL(clicked()), this, SLOT(stop()));
+ connect(restartButton, SIGNAL(clicked()), this, SLOT(restart()));
+ connect(refreshButton, SIGNAL(clicked()), this, SLOT(refresh()));
+ connect(advancedButton, SIGNAL(clicked()), this, SLOT(advanced()));
+
+}
+
+void InterfaceInformationImp::updateInterface(){
+ if(interface->getStatus()){
+ startButton->setEnabled(false);
+ stopButton->setEnabled(true);
+ restartButton->setEnabled(true);
+ }
+ else{
+ startButton->setEnabled(true);
+ stopButton->setEnabled(false);
+ restartButton->setEnabled(false);
+ }
+ macAddressLabel->setText(interface->getMacAddress());
+ ipAddressLabel->setText(interface->getIp());
+ subnetMaskLabel->setText(interface->getSubnetMask());
+ broadcastLabel->setText(interface->getBroadcast());
+}
+
+/**
+ * Start the interface. Update the information if successfull
+ */
+void InterfaceInformationImp::start(){
+ if(interface->start()){
+ updateInterface();
+ }
+}
+
+/**
+ * Stop the interface.
+ */
+void InterfaceInformationImp::stop(){
+ if(interface->stop()){
+ updateInterface();
+ }
+}
+
+/***
+ * Tell the interface to refresh its information.
+ **/
+void InterfaceInformationImp::refresh(){
+ if(interface->refresh())
+ updateInterface();
+}
+
+void InterfaceInformationImp::restart(){
+ if(interface->restart()){
+ updateInterface();
+ }
+}
+
+
+/**
+ * Create the advanced widget. Fill it with the current interface's information.
+ * Display it.
+ */
+void InterfaceInformationImp::advanced(){
+ InterfaceAdvanced *a = new InterfaceAdvanced(0, "InterfaceAdvanced");
+ a->interfaceName->setText(interface->getInterfaceName());
+ a->macAddressLabel->setText(interface->getMacAddress());
+ a->ipAddressLabel->setText(interface->getIp());
+ a->subnetMaskLabel->setText(interface->getSubnetMask());
+ a->broadcastLabel->setText(interface->getBroadcast());
+ a->dhcpServerLabel->setText(interface->getDhcpServerIp());
+ a->leaseObtainedLabel->setText(interface->getLeaseObtained());
+ a->leaseExpiresLabel->setText(interface->getLeaseExpires());
+ a->showMaximized();
+ a->show();
+}
+
+// infoimp.cpp
+
diff --git a/noncore/net/networksetup/interfaceinformationimp.h b/noncore/net/networksetup/interfaceinformationimp.h
new file mode 100644
index 0000000..6fc2384
--- a/dev/null
+++ b/noncore/net/networksetup/interfaceinformationimp.h
@@ -0,0 +1,31 @@
+#ifndef INTERFACEINFORMATIONIMP_H
+#define INTERFACEINFORMATIONIMP_H
+
+#include "interfaceinformation.h"
+#include "interface.h"
+
+class InterfaceInformationImp : public InterfaceInformation {
+
+Q_OBJECT
+
+public:
+ InterfaceInformationImp(QWidget *parent=0, const char *name=0, Interface *i=0, WFlags f=0);
+ ~InterfaceInformationImp(){};
+
+private slots:
+ void start();
+ void stop();
+ void refresh();
+ void restart();
+ void advanced();
+ Interface *interface;
+
+private:
+ void updateInterface();
+
+};
+
+#endif
+
+// addserviceimp.h
+
diff --git a/noncore/net/networksetup/interfaces.cpp b/noncore/net/networksetup/interfaces.cpp
new file mode 100644
index 0000000..b8a3e7f
--- a/dev/null
+++ b/noncore/net/networksetup/interfaces.cpp
@@ -0,0 +1,513 @@
+#include "interfaces.h"
+
+#include <qfile.h>
+#include <qtextstream.h>
+#include <qregexp.h>
+
+#define AUTO "auto"
+#define IFACE "iface"
+#define MAPPING "mapping"
+
+/**
+ * Constructor. Reads in the interfaces file and then split the file up by
+ * the \n for interfaces variable.
+ * @param useInterfacesFile if an interface file other then the default is
+ * desired to be used it should be passed in.
+ */
+Interfaces::Interfaces(QString useInterfacesFile){
+ acceptedFamily.append(INTERFACES_FAMILY_INET);
+ acceptedFamily.append(INTERFACES_FAMILY_IPX);
+ acceptedFamily.append(INTERFACES_FAMILY_INET6);
+
+ interfacesFile = useInterfacesFile;
+ QFile file(interfacesFile);
+ if (!file.open(IO_ReadOnly)){
+ qDebug(QString("Interfaces: Can't open file: %1 for reading.").arg(interfacesFile).latin1());
+ currentIface = interfaces.end();
+ currentMapping = interfaces.end();
+ return;
+ }
+ QTextStream stream( &file );
+ QString line;
+ while ( !stream.eof() ) {
+ line += stream.readLine();
+ line += "\n";
+ }
+ file.close();
+ interfaces = QStringList::split("\n", line, true);
+
+ currentIface = interfaces.end();
+ currentMapping = interfaces.end();
+}
+
+/**
+ * Find out if interface is in an "auto" group or not.
+ * Report any duplicates such as eth0 being in two differnt auto's
+ * @param
+ * @return true is interface is in auto
+ */
+bool Interfaces::isAuto(QString interface){
+ QStringList autoLines = interfaces.grep(QRegExp(AUTO));
+ QStringList awi = autoLines.grep(QRegExp(interface));
+ if(awi.count() > 1)
+ qDebug(QString("Interfaces: Found more then auto group with interface: %1.").arg(interface).latin1());
+ if(awi.count() < 1)
+ return false;
+ return true;
+}
+
+/**
+ * Attempt to set the auto option for interface to setAuto.
+ * @param interface the interface to set
+ * @param setAuto the value to set interface to.
+ * @return false if already set to setAuto.
+ * */
+bool Interfaces::setAuto(QString interface, bool setAuto){
+ // Don't need to set it if it is already set.
+ if(isAuto(interface) == setAuto)
+ return false;
+
+ bool changed = false;
+ for ( QStringList::Iterator it = interfaces.begin(); it != interfaces.end(); ++it ) {
+ if((*it).contains(AUTO)){
+ //We know that they are not in any group so let add to this auto.
+ if(setAuto){
+ (*it) = (*it) += " " + interface;
+ // Don't care to have such thins as: auto eth0 lo usb0
+ (*it) = (*it).simplifyWhiteSpace();
+ changed = true;
+ break;
+ }
+ else{
+ if((*it).contains(interface)){
+ (*it) = (*it).replace(QRegExp(interface), "");
+ // clean up
+ QString line = (*it).simplifyWhiteSpace();
+ line = line.replace(QRegExp(" "),"");
+ if(line == AUTO)
+ (*it) = "";
+ changed = true;
+ // Don't break because we want to make sure we remove all cases.
+ }
+ }
+ }
+ }
+ if(changed == false){
+ if(setAuto == true)
+ interfaces.append(QString(AUTO" %1").arg(interface));
+ else{
+ qDebug(QString("Interfaces: Can't set interface %1 auto to false sense it is already false.").arg(interface).latin1());
+ }
+ }
+ return true;
+}
+
+/**
+ * Set the current interface to interface. This needs to be done before you
+ * can call getFamily(), getMethod, and get/setOption().
+ * @param interface the name of the interface to set. All whitespace is
+ * removed from the interface name.
+ * @return bool true if it is successfull.
+ */
+bool Interfaces::setInterface(QString interface){
+ interface = interface.simplifyWhiteSpace();
+ interface = interface.replace(QRegExp(" "), "");
+ return setStanza(IFACE, interface, currentIface);
+}
+
+/**
+ * A quick helper funtion to see if the current interface is set.
+ * @return bool true if set, false otherwise.
+ */
+bool Interfaces::isInterfaceSet(){
+ return (currentIface != interfaces.end());
+}
+
+/**
+ * Add a new interface of with the settings - family and method
+ * @param interface the name of the interface to set. All whitespace is
+ * removed from the interface name.
+ * @param family the family of this interface inet or inet, ipx or inet6
+ * Must of one of the families defined in interfaces.h
+ * @param method for the family. see interfaces man page for family methods.
+ * @return true if successfull.
+ */
+bool Interfaces::addInterface(QString interface, QString family, QString method){
+ if(acceptedFamily.contains(family)==0)
+ return false;
+ interface = interface.simplifyWhiteSpace();
+ interface = interface.replace(QRegExp(" "), "");
+ interfaces.append("");
+ interfaces.append(QString(IFACE " %1 %2 %3").arg(interface).arg(family).arg(method));
+ return true;
+}
+
+/**
+ * Remove the currently selected interface and all of its options.
+ * @return bool if successfull or not.
+ */
+bool Interfaces::removeInterface(){
+ if(currentIface == interfaces.end())
+ return false;
+ (*currentIface) = "";
+ return removeAllInterfaceOptions();
+}
+
+/**
+ * Gets the hardware name of the interface that is currently selected.
+ * @return QString name of the hardware interface (eth0, usb2, wlan1...).
+ * @param error set to true if any error occurs, false otherwise.
+ */
+QString Interfaces::getInterfaceName(bool &error){
+ if(currentIface == interfaces.end()){
+ error = true;
+ return QString();
+ }
+ QString line = (*currentIface);
+ line = line.mid(QString(IFACE).length() +1, line.length());
+ line = line.simplifyWhiteSpace();
+ int findSpace = line.find(" ");
+ if( findSpace < 0){
+ error = true;
+ return QString();
+ }
+ error = false;
+ return line.mid(0, findSpace);
+}
+
+/**
+ * Gets the family name of the interface that is currently selected.
+ * @return QString name of the family (inet, inet6, ipx).
+ * @param error set to true if any error occurs, false otherwise.
+ */
+QString Interfaces::getInterfaceFamily(bool &error){
+ QString name = getInterfaceName(error);
+ if(error){
+ error = true;
+ return QString();
+ }
+ QString line = (*currentIface);
+ line = line.mid(QString(IFACE).length() +1, line.length());
+ line = line.mid(name.length()+1, line.length());
+ line = line.simplifyWhiteSpace();
+ int findSpace = line.find(" ");
+ if( findSpace < 0){
+ error = true;
+ return QString();
+ }
+ error = false;
+ return line.mid(0, findSpace);
+}
+
+/**
+ * Gets the method of the interface that is currently selected.
+ * @return QString name of the method such as staic or dhcp.
+ * See the man page of interfaces for possible methods depending on the family.
+ * @param error set to true if any error occurs, false otherwise.
+ */
+QString Interfaces::getInterfaceMethod(bool &error){
+ QString name = getInterfaceName(error);
+ if(error){
+ error = true;
+ return QString();
+ }
+ QString family = getInterfaceFamily(error);
+ if(error){
+ error = true;
+ return QString();
+ }
+ QString line = (*currentIface);
+ line = line.mid(QString(IFACE).length()+1, line.length());
+ line = line.mid(name.length()+1, line.length());
+ line = line.mid(family.length()+1, line.length());
+ line = line.simplifyWhiteSpace();
+ error = false;
+ return line;
+}
+
+/**
+ * Sets the interface name to newName.
+ * @param newName the new name of the interface. All whitespace is removed.
+ * @return bool true if successfull.
+ */
+bool Interfaces::setInterfaceName(QString newName){
+ if(currentIface == interfaces.end())
+ return false;
+ newName = newName.simplifyWhiteSpace();
+ newName = newName.replace(QRegExp(" "), "");
+ bool returnValue = false;
+ (*currentIface) = QString("iface %1 %2 %3").arg(newName).arg(getInterfaceFamily(returnValue)).arg(getInterfaceMethod(returnValue));
+ return !returnValue;
+}
+
+/**
+ * Sets the interface family to newName.
+ * @param newName the new name of the interface. Must be one of the families
+ * defined in the interfaces.h file.
+ * @return bool true if successfull.
+ */
+bool Interfaces::setInterfaceFamily(QString newName){
+ if(currentIface == interfaces.end())
+ return false;
+ if(acceptedFamily.contains(newName)==0)
+ return false;
+ bool returnValue = false;
+ (*currentIface) = QString("iface %1 %2 %3").arg(getInterfaceName(returnValue)).arg(newName).arg(getInterfaceMethod(returnValue));
+ return !returnValue;
+}
+
+/**
+ * Sets the interface method to newName
+ * @param newName the new name of the interface
+ * @return bool true if successfull.
+ */
+bool Interfaces::setInterfaceMethod(QString newName){
+ if(currentIface == interfaces.end())
+ return false;
+ bool returnValue = false;
+ (*currentIface) = QString("iface %1 %2 %3").arg(getInterfaceName(returnValue)).arg(getInterfaceFamily(returnValue)).arg(newName);
+ return !returnValue;
+}
+
+/**
+ * Get a value for an option in the currently selected interface. For example
+ * calling getInterfaceOption("address") on the following stanza would
+ * return 192.168.1.1.
+ * iface eth0 static
+ * address 192.168.1.1
+ * @param option the options to get the value.
+ * @param error set to true if any error occurs, false otherwise.
+ * @return QString the options value. QString::null if error == true
+ */
+QString Interfaces::getInterfaceOption(QString option, bool &error){
+ return getOption(currentIface, option, error);
+}
+
+/**
+ * Set a value for an option in the currently selected interface. If option
+ * doesn't exist then it is added along with the value. If value is set to an
+ * empty string then option is removed.
+ * @param option the options to set the value.
+ * @param value the value that option should be set to.
+ * @param error set to true if any error occurs, false otherwise.
+ * @return QString the options value. QString::null if error == true
+ */
+bool Interfaces::setInterfaceOption(QString option, QString value){
+ return setOption(currentIface, option, value);
+}
+
+/**
+ * Removes all of the options from the currently selected interface.
+ * @return bool error if if successfull
+ */
+bool Interfaces::removeAllInterfaceOptions(){
+ return removeAllOptions(currentIface);
+}
+
+/**
+ * Set the current map to interface's map. This needs to be done before you
+ * can call addMapping(), set/getMap(), and get/setScript().
+ * @param interface the name of the interface to set. All whitespace is
+ * removed from the interface name.
+ * @return bool true if it is successfull.
+ */
+bool Interfaces::setMapping(QString interface){
+ interface = interface.simplifyWhiteSpace();
+ interface = interface.replace(QRegExp(" "), "");
+ return setStanza(MAPPING, interface, currentMapping);
+}
+
+/**
+ * Adds a new Mapping to the interfaces file with interfaces.
+ * @param interface the name(s) of the interfaces to set to this mapping
+ */
+void Interfaces::addMapping(QString interfaces){
+ interfaces.append("");
+ interfaces.append(QString(MAPPING " %1").arg(interfaces));
+}
+
+/**
+ * Set a map option within a mapping.
+ * @param map map to use
+ * @param value value to go with map
+ * @return bool true if it is successfull.
+ */
+bool Interfaces::setMap(QString map, QString value){
+ return setOption(currentMapping, map, value);
+}
+
+/**
+ * Get a map value within a mapping.
+ * @param map map to get value of
+ * @param bool true if it is successfull.
+ * @return value that goes to the map
+ */
+QString Interfaces::getMap(QString map, bool &error){
+ return getOption(currentMapping, map, error);
+}
+
+/**
+ * Sets a script value of the current mapping to argument.
+ * @param argument the script name.
+ * @return true if successfull.
+ */
+bool Interfaces::setScript(QString argument){
+ return setOption(currentMapping, "script", argument);
+}
+
+/**
+ * @param error true if could not retrieve the current script argument.
+ * @return QString the argument of the script for the current mapping.
+ */
+QString Interfaces::getScript(bool &error){
+ return getOption(currentMapping, "script", error);
+}
+
+/**
+ * Helper function used to parse through the QStringList and put pointers in
+ * the correct place.
+ * @param stanza The stanza (auto, iface, mapping) to look for.
+ * @param option string that must be in the stanza's main line.
+ * @param interator interator to place at location of stanza if successfull.
+ * @return bool true if the stanza is found.
+ */
+bool Interfaces::setStanza(QString stanza, QString option, QStringList::Iterator &iterator){
+ bool found = false;
+ iterator = interfaces.end();
+ for ( QStringList::Iterator it = interfaces.begin(); it != interfaces.end(); ++it ) {
+ QString line = (*it).simplifyWhiteSpace();
+ if(line.contains(stanza) && line.contains(option)){
+ if(found == true){
+ qDebug(QString("Interfaces: Found multiple stanza's for search: %1 %2").arg(stanza).arg(option).latin1());
+ }
+ found = true;
+ iterator = it;
+ }
+ }
+ return !found;
+}
+
+/**
+ * Sets a value of an option in a stanza
+ * @param start the start of the stanza
+ * @param option the option to use when setting value.
+ * @return bool true if successfull, false otherwise.
+ */
+bool Interfaces::setOption(QStringList::Iterator start, QString option, QString value){
+ if(start == interfaces.end())
+ return false;
+
+ bool found = false;
+ for ( QStringList::Iterator it = start; it != interfaces.end(); ++it ) {
+ if(((*it).contains(IFACE) || (*it).contains(MAPPING) || (*it).contains(AUTO)) && it != start){
+ if(!found && value != ""){
+ // Got to the end of the stanza without finding it, so append it.
+ interfaces.insert(--it, QString("\t%1 %2").arg(option).arg(value));
+ }
+ break;
+ }
+ if((*it).contains(option)){
+ // Found it in stanza so replace it.
+ if(found)
+ qDebug(QString("Interfaces: Set Options found more then one value for option: %1 in stanza: %1").arg(option).arg((*start)).latin1());
+ found = true;
+ if(value == "")
+ (*it) = "";
+ else
+ (*it) = QString("\t%1 %2").arg(option).arg(value);
+ }
+ }
+ return true;
+}
+
+/**
+ * Removes all options in a stanza
+ * @param start the start of the stanza
+ * @return bool true if successfull, false otherwise.
+ */
+bool Interfaces::removeAllOptions(QStringList::Iterator start){
+ if(start == interfaces.end())
+ return false;
+
+ QStringList::Iterator it = start;
+ it = ++it;
+ for (it; it != interfaces.end(); ++it ) {
+ if(((*it).contains(IFACE) || (*it).contains(MAPPING) || (*it).contains(AUTO)) && it != start){
+ break;
+ }
+ it = interfaces.remove(it);
+ it = --it;
+ }
+ // Leave a space between this interface and the next.
+ interfaces.insert(it, QString(""));
+ return true;
+}
+
+/**
+ * Gets a value of an option in a stanza
+ * @param start the start of the stanza
+ * @param option the option to use when getting the value.
+ * @param bool true if errors false otherwise.
+ * @return QString the value of option QString::null() if error == true.
+ */
+QString Interfaces::getOption(QStringList::Iterator start, QString option, bool &error){
+ if(start == interfaces.end()){
+ error = false;
+ return QString();
+ }
+
+ QString value;
+ bool found = false;
+ for ( QStringList::Iterator it = start; it != interfaces.end(); ++it ) {
+ if(((*it).contains(IFACE) || (*it).contains(MAPPING) || (*it).contains(AUTO)) && it != start){
+ break;
+ }
+ if((*it).contains(option)){
+ if(found)
+ qDebug(QString("Interfaces: Get Options found more then one value: %1 for option: %2 in stanza %3").arg((*it)).arg(option).arg((*start)).latin1());
+ found = true;
+ QString line = (*it).simplifyWhiteSpace();
+ int space = line.find(" ", option.length());
+ if(space != -1)
+ value = line.mid(space+1, line.length());
+ else
+ qDebug(QString("Interfaces: Option %1 with no value").arg(option).latin1());
+ }
+ }
+ error = !found;
+ return value;
+}
+
+/**
+ * Write out the interfaces file to the file passed into the constructor.
+ * Removes any excess blank lines over 1 line long.
+ * @return bool true if successfull, false if not.
+ */
+bool Interfaces::write(){
+ QFile::remove(interfacesFile);
+ QFile file(interfacesFile);
+
+ if (!file.open(IO_ReadWrite)){
+ qDebug(QString("Interfaces: Can't open file: %1 for writing.").arg(interfacesFile).latin1());
+ return false;
+ }
+ QTextStream stream( &file );
+ int whiteSpaceCount = 0;
+ for ( QStringList::Iterator it = interfaces.begin(); it != interfaces.end(); ++it ) {
+ QString line = (*it).simplifyWhiteSpace();
+ line = line.replace(QRegExp(" "),"");
+ if(line.length() == 0)
+ whiteSpaceCount++;
+ else
+ whiteSpaceCount = 0;
+ if(whiteSpaceCount < 2){
+ qDebug((*it).latin1());
+ stream << (*it) << '\n';
+ }
+ }
+ file.close();
+ return true;
+}
+
+// interfaces.cpp
+
diff --git a/noncore/net/networksetup/interfaces.h b/noncore/net/networksetup/interfaces.h
new file mode 100644
index 0000000..2cc9689
--- a/dev/null
+++ b/noncore/net/networksetup/interfaces.h
@@ -0,0 +1,70 @@
+#ifndef INTERFACES_H
+#define INTERFACES_H
+
+#include <qstring.h>
+#include <qstringlist.h>
+
+#define INTERFACES_LOOPBACK "loopback"
+
+#define INTERFACES_FAMILY_INET "inet"
+#define INTERFACES_FAMILY_IPX "ipx"
+#define INTERFACES_FAMILY_INET6 "inet6"
+
+#define INTERFACES_METHOD_DHCP "dhcp"
+#define INTERFACES_METHOD_STATIC "static"
+#define INTERFACES_METHOD_PPP "ppp"
+
+/**
+ * This class provides a clean frontend for parsing the network interfaces file.
+ * It provides helper functions to minipulate the options within the file.
+ * See the interfaces man page for the syntax rules.
+ */
+class Interfaces {
+
+public:
+ Interfaces(QString useInterfacesFile = "/etc/network/interfaces");
+
+ bool isAuto(QString interface);
+ bool setAuto(QString interface, bool setAuto);
+
+ bool removeInterface();
+ bool addInterface(QString interface, QString family, QString method);
+ bool setInterface(QString interface);
+ bool isInterfaceSet();
+ QString getInterfaceName(bool &error);
+ bool setInterfaceName(QString newName);
+ QString getInterfaceFamily(bool &error);
+ bool setInterfaceFamily(QString newName);
+ QString getInterfaceMethod(bool &error);
+ bool setInterfaceMethod(QString newName);
+ QString getInterfaceOption(QString option, bool &error);
+ bool setInterfaceOption(QString option, QString value);
+ bool removeAllInterfaceOptions();
+
+ bool setMapping(QString interface);
+ void addMapping(QString interfaces);
+ bool setMap(QString map, QString value);
+ QString getMap(QString map, bool &error);
+ bool setScript(QString);
+ QString getScript(bool &error);
+
+ bool write();
+
+private:
+ bool setStanza(QString stanza, QString option,QStringList::Iterator &iterator);
+ bool setOption(QStringList::Iterator start, QString option, QString value);
+ QString getOption(QStringList::Iterator start, QString option, bool &error);
+ bool removeAllOptions(QStringList::Iterator start);
+
+ QString interfacesFile;
+ QStringList interfaces;
+ QStringList::Iterator currentIface;
+ QStringList::Iterator currentMapping;
+
+ QStringList acceptedFamily;
+};
+
+#endif
+
+// interfaces
+
diff --git a/noncore/net/networksetup/interfacesetup.ui b/noncore/net/networksetup/interfacesetup.ui
new file mode 100644
index 0000000..698422c
--- a/dev/null
+++ b/noncore/net/networksetup/interfacesetup.ui
@@ -0,0 +1,274 @@
+<!DOCTYPE UI><UI>
+<class>InterfaceSetup</class>
+<widget>
+ <class>QDialog</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>InterfaceSetup</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>193</width>
+ <height>310</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>Interface Configuration</string>
+ </property>
+ <grid>
+ <property stdset="1">
+ <name>margin</name>
+ <number>11</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget row="1" column="0" rowspan="1" colspan="2" >
+ <class>Line</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Line1</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ <widget row="6" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel4</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>IP Address</string>
+ </property>
+ </widget>
+ <widget row="0" column="0" rowspan="1" colspan="2" >
+ <class>QCheckBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>autoStart</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Automaticly bring up</string>
+ </property>
+ </widget>
+ <widget row="2" column="1" >
+ <class>QComboBox</class>
+ <item>
+ <property>
+ <name>text</name>
+ <string>All</string>
+ </property>
+ </item>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>profileCombo</cstring>
+ </property>
+ </widget>
+ <widget row="5" column="0" rowspan="1" colspan="2" >
+ <class>QGroupBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>staticGroupBox</cstring>
+ </property>
+ <property stdset="1">
+ <name>enabled</name>
+ <bool>false</bool>
+ </property>
+ <property stdset="1">
+ <name>title</name>
+ <string>Static Ip Configuration</string>
+ </property>
+ </widget>
+ <widget row="6" column="1" >
+ <class>QLineEdit</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>ipAddressEdit</cstring>
+ </property>
+ </widget>
+ <widget row="4" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>leaseHoursLabel</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Requested Lease</string>
+ </property>
+ </widget>
+ <widget row="3" column="0" rowspan="1" colspan="2" >
+ <class>QCheckBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>dhcpCheckBox</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>DHCP</string>
+ </property>
+ <property stdset="1">
+ <name>checked</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget row="7" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel5</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Subnet Mask</string>
+ </property>
+ </widget>
+ <widget row="2" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel1</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Profile:</string>
+ </property>
+ </widget>
+ <widget row="4" column="1" >
+ <class>QSpinBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>leaseTime</cstring>
+ </property>
+ <property stdset="1">
+ <name>suffix</name>
+ <string> hours</string>
+ </property>
+ <property stdset="1">
+ <name>maxValue</name>
+ <number>336</number>
+ </property>
+ <property stdset="1">
+ <name>minValue</name>
+ <number>1</number>
+ </property>
+ <property stdset="1">
+ <name>value</name>
+ <number>24</number>
+ </property>
+ </widget>
+ <spacer row="11" column="1" >
+ <property>
+ <name>name</name>
+ <cstring>Spacer9</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Vertical</enum>
+ </property>
+ <property stdset="1">
+ <name>sizeType</name>
+ <enum>Expanding</enum>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget row="10" column="1" >
+ <class>QLineEdit</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>secondDNSLineEdit</cstring>
+ </property>
+ </widget>
+ <widget row="10" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel3</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Second DNS</string>
+ </property>
+ </widget>
+ <widget row="9" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel2</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>First DNS</string>
+ </property>
+ </widget>
+ <widget row="9" column="1" >
+ <class>QLineEdit</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>firstDNSLineEdit</cstring>
+ </property>
+ </widget>
+ <widget row="8" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel1_2</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Gateway</string>
+ </property>
+ </widget>
+ <widget row="7" column="1" >
+ <class>QLineEdit</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>subnetMaskEdit</cstring>
+ </property>
+ </widget>
+ <widget row="8" column="1" >
+ <class>QLineEdit</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>gatewayEdit</cstring>
+ </property>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>dhcpCheckBox</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>leaseHoursLabel</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>dhcpCheckBox</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>leaseTime</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>dhcpCheckBox</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>staticGroupBox</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+</connections>
+</UI>
diff --git a/noncore/net/networksetup/interfacesetupimp.cpp b/noncore/net/networksetup/interfacesetupimp.cpp
new file mode 100644
index 0000000..6a8449d
--- a/dev/null
+++ b/noncore/net/networksetup/interfacesetupimp.cpp
@@ -0,0 +1,147 @@
+#include "interfacesetupimp.h"
+#include "interface.h"
+#include "interfaces.h"
+
+#include <qcombobox.h>
+#include <qcheckbox.h>
+#include <qlineedit.h>
+#include <qspinbox.h>
+#include <qgroupbox.h>
+#include <qlabel.h>
+
+#include <qmessagebox.h>
+
+#include <assert.h>
+
+#define INTERFACE_FILE "/home/ben/interfaces"
+#define DNSSCRIPT "interfacednsscript"
+
+/**
+ * Constuctor. Set up the connection and load the first profile.
+ */
+InterfaceSetupImp::InterfaceSetupImp(QWidget* parent, const char* name, Interface *i, bool modal, WFlags fl) : InterfaceSetup(parent, name, modal, fl){
+ assert(i);
+ interface = i;
+ interfaces = new Interfaces(INTERFACE_FILE);
+ changeProfile(profileCombo->currentText());
+ bool error = false;
+ if(interfaces->getInterfaceMethod(error) == INTERFACES_LOOPBACK){
+ staticGroupBox->hide();
+ dhcpCheckBox->hide();
+ leaseTime->hide();
+ leaseHoursLabel->hide();
+ }
+ connect(profileCombo, SIGNAL(highlighted(const QString &)), this, SLOT(changeProfile(const QString &)));
+}
+
+/**
+ * Save the current settings, then write out the interfaces file and close.
+ */
+void InterfaceSetupImp::accept(){
+ if(!saveSettings())
+ return;
+ interfaces->write();
+ close(true);
+}
+
+/**
+ * Save the settings for the current Interface.
+ * @return bool true if successfull, false otherwise
+ */
+bool InterfaceSetupImp::saveSettings(){
+ // eh can't really do anything about it other then return. :-D
+ if(!interfaces->isInterfaceSet())
+ return true;
+
+ bool error = false;
+ // Loopback case
+ if(interfaces->getInterfaceMethod(error) == INTERFACES_LOOPBACK){
+ interfaces->setAuto(interface->getInterfaceName(), autoStart->isChecked());
+ return true;
+ }
+
+ if(!dhcpCheckBox->isChecked() && (ipAddressEdit->text().isEmpty() || subnetMaskEdit->text().isEmpty() || firstDNSLineEdit->text().isEmpty())){
+ QMessageBox::information(this, "Empy Fields.", "Please fill in address, subnet,\n gateway and the first dns entries.", "Ok");
+ return false;
+ }
+ interfaces->removeAllInterfaceOptions();
+
+ // DHCP
+ if(dhcpCheckBox->isChecked()){
+ interfaces->setInterfaceMethod(INTERFACES_METHOD_DHCP);
+ interfaces->setInterfaceOption("leasehours", QString("%1").arg(leaseTime->value()));
+ interfaces->setInterfaceOption("leasetime", QString("%1").arg(leaseTime->value()*60*60));
+ }
+ else{
+ interfaces->setInterfaceMethod("static");
+ interfaces->setInterfaceOption("address", ipAddressEdit->text());
+ interfaces->setInterfaceOption("netmask", subnetMaskEdit->text());
+ interfaces->setInterfaceOption("gateway", gatewayEdit->text());
+ QString dns = firstDNSLineEdit->text() + " " + secondDNSLineEdit->text();
+ interfaces->setInterfaceOption("up "DNSSCRIPT" add ", dns);
+ interfaces->setInterfaceOption("down "DNSSCRIPT" remove ", dns);
+ }
+
+ // IP Information
+ interfaces->setAuto(interface->getInterfaceName(), autoStart->isChecked());
+ return true;
+}
+
+/**
+ * The Profile has changed.
+ * @profile the new profile.
+ */
+void InterfaceSetupImp::changeProfile(const QString &profile){
+ QString newInterfaceName;
+ if(profile.lower() == "all")
+ newInterfaceName = interface->getInterfaceName();
+ else
+ newInterfaceName = interface->getInterfaceName() + "_" + profile;
+ if(newInterfaceName == currentInterfaceName)
+ return;
+ else{
+ saveSettings();
+ currentInterfaceName = newInterfaceName;
+ }
+ bool error = interfaces->setInterface(currentInterfaceName);
+
+ // See if we have to make a interface.
+ if(error){
+ qDebug("InterfaceSetupImp: Adding a new interface from profile change.");
+ interfaces->addInterface(currentInterfaceName, INTERFACES_FAMILY_INET, INTERFACES_METHOD_DHCP);
+ error = interfaces->setInterface(currentInterfaceName);
+ if(error){
+ qDebug("InterfaceSetupImp: Added interface, but still can't set.");
+ return;
+ }
+ }
+
+ //qDebug( currentInterfaceName.latin1() );
+ // We must have a valid interface to get this far so read some settings.
+
+ // DHCP
+ if(interfaces->getInterfaceMethod(error) == INTERFACES_METHOD_DHCP)
+ dhcpCheckBox->setChecked(true);
+ else
+ dhcpCheckBox->setChecked(false);
+ leaseTime->setValue(interfaces->getInterfaceOption("leasehours", error).toInt());
+ if(error)
+ leaseTime->setValue(interfaces->getInterfaceOption("leasetime", error).toInt()/60/60);
+ if(error)
+ leaseTime->setValue(24);
+
+ // IP Information
+ autoStart->setChecked(interfaces->isAuto(interface->getInterfaceName()));
+ QString dns = interfaces->getInterfaceOption("up interfacednsscript add", error);
+ if(dns.contains(" ")){
+ firstDNSLineEdit->setText(dns.mid(0, dns.find(" ")));
+ secondDNSLineEdit->setText(dns.mid(dns.find(" ")+1, dns.length()));
+ }
+ ipAddressEdit->setText(interfaces->getInterfaceOption("address", error));
+ subnetMaskEdit->setText(interfaces->getInterfaceOption("netmask", error));
+ gatewayEdit->setText(interfaces->getInterfaceOption("gateway", error));
+}
+
+
+// interfacesetup.cpp
+
diff --git a/noncore/net/networksetup/interfacesetupimp.h b/noncore/net/networksetup/interfacesetupimp.h
new file mode 100644
index 0000000..6c34718
--- a/dev/null
+++ b/noncore/net/networksetup/interfacesetupimp.h
@@ -0,0 +1,30 @@
+#ifndef INTERFACESETUPIMP_H
+#define INTERFACESETUPIMP_H
+
+#include "interfacesetup.h"
+
+class Interface;
+class Interfaces;
+
+class InterfaceSetupImp : public InterfaceSetup {
+ Q_OBJECT
+
+public:
+ InterfaceSetupImp( QWidget* parent = 0, const char* name = 0, Interface *i=0, bool modal = FALSE, WFlags fl = 0);
+
+protected slots:
+ void accept();
+ void changeProfile(const QString &profile);
+
+private:
+ bool saveSettings();
+ Interfaces *interfaces;
+ Interface *interface;
+ QString currentInterfaceName;
+
+};
+
+#endif
+
+// interfacesetupimp.h
+
diff --git a/noncore/net/networksetup/kprocctrl.cpp b/noncore/net/networksetup/kprocctrl.cpp
new file mode 100644
index 0000000..cd8711a
--- a/dev/null
+++ b/noncore/net/networksetup/kprocctrl.cpp
@@ -0,0 +1,267 @@
+/* This file is part of the KDE libraries
+ Copyright (C) 1997 Christian Czezakte (e9025461@student.tuwien.ac.at)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+//
+// KPROCESSCONTROLLER -- A helper class for KProcess
+//
+// version 0.3.1, Jan, 8th 1997
+//
+// (C) Christian Czezatke
+// e9025461@student.tuwien.ac.at
+//
+
+//#include <config.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <assert.h>
+
+#include <qsocketnotifier.h>
+#include "kprocess.h"
+#include "kprocctrl.h"
+
+KProcessController *KProcessController::theKProcessController = 0;
+
+struct sigaction KProcessController::oldChildHandlerData;
+bool KProcessController::handlerSet = false;
+
+KProcessController::KProcessController()
+{
+ assert( theKProcessController == 0 );
+
+ if (0 > pipe(fd))
+ printf(strerror(errno));
+
+ notifier = new QSocketNotifier(fd[0], QSocketNotifier::Read);
+ notifier->setEnabled(true);
+ QObject::connect(notifier, SIGNAL(activated(int)),
+ this, SLOT(slotDoHousekeeping(int)));
+ connect( &delayedChildrenCleanupTimer, SIGNAL( timeout()),
+ SLOT( delayedChildrenCleanup()));
+
+ theKProcessController = this;
+
+ setupHandlers();
+}
+
+
+void KProcessController::setupHandlers()
+{
+ if( handlerSet )
+ return;
+ struct sigaction act;
+ act.sa_handler=theSigCHLDHandler;
+ sigemptyset(&(act.sa_mask));
+ sigaddset(&(act.sa_mask), SIGCHLD);
+ // Make sure we don't block this signal. gdb tends to do that :-(
+ sigprocmask(SIG_UNBLOCK, &(act.sa_mask), 0);
+
+ act.sa_flags = SA_NOCLDSTOP;
+
+ // CC: take care of SunOS which automatically restarts interrupted system
+ // calls (and thus does not have SA_RESTART)
+
+#ifdef SA_RESTART
+ act.sa_flags |= SA_RESTART;
+#endif
+
+ sigaction( SIGCHLD, &act, &oldChildHandlerData );
+
+ act.sa_handler=SIG_IGN;
+ sigemptyset(&(act.sa_mask));
+ sigaddset(&(act.sa_mask), SIGPIPE);
+ act.sa_flags = 0;
+ sigaction( SIGPIPE, &act, 0L);
+ handlerSet = true;
+}
+
+void KProcessController::resetHandlers()
+{
+ if( !handlerSet )
+ return;
+ sigaction( SIGCHLD, &oldChildHandlerData, 0 );
+ // there should be no problem with SIGPIPE staying SIG_IGN
+ handlerSet = false;
+}
+
+// block SIGCHLD handler, because it accesses processList
+void KProcessController::addKProcess( KProcess* p )
+{
+ sigset_t newset, oldset;
+ sigemptyset( &newset );
+ sigaddset( &newset, SIGCHLD );
+ sigprocmask( SIG_BLOCK, &newset, &oldset );
+ processList.append( p );
+ sigprocmask( SIG_SETMASK, &oldset, 0 );
+}
+
+void KProcessController::removeKProcess( KProcess* p )
+{
+ sigset_t newset, oldset;
+ sigemptyset( &newset );
+ sigaddset( &newset, SIGCHLD );
+ sigprocmask( SIG_BLOCK, &newset, &oldset );
+ processList.remove( p );
+ sigprocmask( SIG_SETMASK, &oldset, 0 );
+}
+
+//using a struct which contains both the pid and the status makes it easier to write
+//and read the data into the pipe
+//especially this solves a problem which appeared on my box where slotDoHouseKeeping() received
+//only 4 bytes (with some debug output around the write()'s it received all 8 bytes)
+//don't know why this happened, but when writing all 8 bytes at once it works here, aleXXX
+struct waitdata
+{
+ pid_t pid;
+ int status;
+};
+
+void KProcessController::theSigCHLDHandler(int arg)
+{
+ struct waitdata wd;
+// int status;
+// pid_t this_pid;
+ int saved_errno;
+
+ saved_errno = errno;
+ // since waitpid and write change errno, we have to save it and restore it
+ // (Richard Stevens, Advanced programming in the Unix Environment)
+
+ bool found = false;
+ if( theKProcessController != 0 ) {
+ // iterating the list doesn't perform any system call
+ for( QValueList<KProcess*>::ConstIterator it = theKProcessController->processList.begin();
+ it != theKProcessController->processList.end();
+ ++it )
+ {
+ if( !(*it)->isRunning())
+ continue;
+ wd.pid = waitpid( (*it)->pid(), &wd.status, WNOHANG );
+ if ( wd.pid > 0 ) {
+ ::write(theKProcessController->fd[1], &wd, sizeof(wd));
+ found = true;
+ }
+ }
+ }
+ if( !found && oldChildHandlerData.sa_handler != SIG_IGN
+ && oldChildHandlerData.sa_handler != SIG_DFL )
+ oldChildHandlerData.sa_handler( arg ); // call the old handler
+ // handle the rest
+ if( theKProcessController != 0 ) {
+ static const struct waitdata dwd = { 0, 0 }; // delayed waitpid()
+ ::write(theKProcessController->fd[1], &dwd, sizeof(dwd));
+ } else {
+ int dummy;
+ while( waitpid( -1, &dummy, WNOHANG ) > 0 )
+ ;
+ }
+
+ errno = saved_errno;
+}
+
+
+
+void KProcessController::slotDoHousekeeping(int )
+{
+ unsigned int bytes_read = 0;
+ unsigned int errcnt=0;
+ // read pid and status from the pipe.
+ struct waitdata wd;
+ while ((bytes_read < sizeof(wd)) && (errcnt < 50)) {
+ int r = ::read(fd[0], ((char *)&wd) + bytes_read, sizeof(wd) - bytes_read);
+ if (r > 0) bytes_read += r;
+ else if (r < 0) errcnt++;
+ }
+ if (errcnt >= 50) {
+ fprintf(stderr,
+ "Error: Max. error count for pipe read "
+ "exceeded in KProcessController::slotDoHousekeeping\n");
+ return; // it makes no sense to continue here!
+ }
+ if (bytes_read != sizeof(wd)) {
+ fprintf(stderr,
+ "Error: Could not read info from signal handler %d <> %d!\n",
+ bytes_read, sizeof(wd));
+ return; // it makes no sense to continue here!
+ }
+ if (wd.pid==0) { // special case, see delayedChildrenCleanup()
+ delayedChildrenCleanupTimer.start( 1000, true );
+ return;
+ }
+
+ for( QValueList<KProcess*>::ConstIterator it = processList.begin();
+ it != processList.end();
+ ++it ) {
+ KProcess* proc = *it;
+ if (proc->pid() == wd.pid) {
+ // process has exited, so do emit the respective events
+ if (proc->run_mode == KProcess::Block) {
+ // If the reads are done blocking then set the status in proc
+ // but do nothing else because KProcess will perform the other
+ // actions of processHasExited.
+ proc->status = wd.status;
+ proc->runs = false;
+ } else {
+ proc->processHasExited(wd.status);
+ }
+ return;
+ }
+ }
+}
+
+// this is needed e.g. for popen(), which calls waitpid() checking
+// for its forked child, if we did waitpid() directly in the SIGCHLD
+// handler, popen()'s waitpid() call would fail
+void KProcessController::delayedChildrenCleanup()
+{
+ struct waitdata wd;
+ while(( wd.pid = waitpid( -1, &wd.status, WNOHANG ) ) > 0 ) {
+ for( QValueList<KProcess*>::ConstIterator it = processList.begin();
+ it != processList.end();
+ ++it )
+ {
+ if( !(*it)->isRunning() || (*it)->pid() != wd.pid )
+ continue;
+ // it's KProcess, handle it
+ ::write(fd[1], &wd, sizeof(wd));
+ break;
+ }
+ }
+}
+
+KProcessController::~KProcessController()
+{
+ assert( theKProcessController == this );
+ resetHandlers();
+
+ notifier->setEnabled(false);
+
+ close(fd[0]);
+ close(fd[1]);
+
+ delete notifier;
+ theKProcessController = 0;
+}
+
+//#include "kprocctrl.moc"
diff --git a/noncore/net/networksetup/kprocctrl.h b/noncore/net/networksetup/kprocctrl.h
new file mode 100644
index 0000000..ac82b9d
--- a/dev/null
+++ b/noncore/net/networksetup/kprocctrl.h
@@ -0,0 +1,120 @@
+/* This file is part of the KDE libraries
+ Copyright (C) 1997 Christian Czezakte (e9025461@student.tuwien.ac.at)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+//
+// KPROCESSCONTROLLER -- A helper class for KProcess
+//
+// version 0.3.1, Jan 8th 1997
+//
+// (C) Christian Czezatke
+// e9025461@student.tuwien.ac.at
+//
+
+#ifndef __KPROCCTRL_H__
+#define __KPROCCTRL_H__
+
+#include <qvaluelist.h>
+#include <qtimer.h>
+
+#include "kprocess.h"
+
+class KProcessControllerPrivate;
+class QSocketNotifier;
+
+/**
+ * @short Used internally by @ref KProcess
+ * @internal
+ * @author Christian Czezakte <e9025461@student.tuwien.ac.at>
+ *
+ * A class for internal use by KProcess only. -- Exactly one instance
+ * of this class is generated by the first instance of KProcess that is
+ * created (a pointer to it gets stored in @ref theKProcessController ).
+ *
+ * This class takes care of the actual (UN*X) signal handling.
+*/
+class KProcessController : public QObject
+{
+ Q_OBJECT
+
+public:
+ KProcessController();
+ ~KProcessController();
+ //CC: WARNING! Destructor Not virtual (but you don't derive classes from this anyhow...)
+
+public:
+
+ /**
+ * Only a single instance of this class is allowed at a time,
+ * and this static variable is used to track the one instance.
+ */
+ static KProcessController *theKProcessController;
+
+ /**
+ * Automatically called upon SIGCHLD.
+ *
+ * Normally you do not need to do anything with this function but
+ * if your application needs to disable SIGCHLD for some time for
+ * reasons beyond your control, you should call this function afterwards
+ * to make sure that no SIGCHLDs where missed.
+ */
+ static void theSigCHLDHandler(int signal);
+ // handler for sigchld
+
+ /**
+ * @internal
+ */
+ static void setupHandlers();
+ /**
+ * @internal
+ */
+ static void resetHandlers();
+ /**
+ * @internal
+ */
+ void addKProcess( KProcess* );
+ /**
+ * @internal
+ */
+ void removeKProcess( KProcess* );
+ public slots:
+ /**
+ * @internal
+ */
+ void slotDoHousekeeping(int socket);
+
+ private slots:
+ void delayedChildrenCleanup();
+private:
+ int fd[2];
+ QSocketNotifier *notifier;
+ static struct sigaction oldChildHandlerData;
+ static bool handlerSet;
+ QValueList<KProcess*> processList;
+ QTimer delayedChildrenCleanupTimer;
+
+ // Disallow assignment and copy-construction
+ KProcessController( const KProcessController& );
+ KProcessController& operator= ( const KProcessController& );
+
+ KProcessControllerPrivate *d;
+};
+
+
+
+#endif
+
diff --git a/noncore/net/networksetup/kprocess.cpp b/noncore/net/networksetup/kprocess.cpp
new file mode 100644
index 0000000..193ec9b
--- a/dev/null
+++ b/noncore/net/networksetup/kprocess.cpp
@@ -0,0 +1,919 @@
+/*
+
+ $Id$
+
+ This file is part of the KDE libraries
+ Copyright (C) 1997 Christian Czezatke (e9025461@student.tuwien.ac.at)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+
+//
+// KPROCESS -- A class for handling child processes in KDE without
+// having to take care of Un*x specific implementation details
+//
+// version 0.3.1, Jan 8th 1998
+//
+// (C) Christian Czezatke
+// e9025461@student.tuwien.ac.at
+//
+// Changes:
+//
+// March 2nd, 1998: Changed parameter list for KShellProcess:
+// Arguments are now placed in a single string so that
+// <shell> -c <commandstring> is passed to the shell
+// to make the use of "operator<<" consistent with KProcess
+
+#include "kprocess.h"
+#define _MAY_INCLUDE_KPROCESSCONTROLLER_
+#include "kprocctrl.h"
+
+//#include <config.h>
+
+#include <qglobal.h>
+#include <qmap.h>
+#include <qfile.h>
+#include <qsocketnotifier.h>
+#include <qregexp.h>
+
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#ifdef HAVE_INITGROUPS
+#include <grp.h>
+#endif
+#include <pwd.h>
+
+#include <qapplication.h>
+//#include <kdebug.h>
+
+/////////////////////////////
+// public member functions //
+/////////////////////////////
+
+class KProcessPrivate {
+public:
+ KProcessPrivate() : useShell(false) { }
+
+ bool useShell;
+ QMap<QString,QString> env;
+ QString wd;
+ QCString shell;
+};
+
+#define Q_CHECK_PTR(a)
+
+KProcess::KProcess()
+ : QObject(),
+ run_mode(NotifyOnExit),
+ runs(false),
+ pid_(0),
+ status(0),
+ keepPrivs(false),
+ innot(0),
+ outnot(0),
+ errnot(0),
+ communication(NoCommunication),
+ input_data(0),
+ input_sent(0),
+ input_total(0),
+ d(0)
+{
+ if (0 == KProcessController::theKProcessController) {
+ (void) new KProcessController();
+ Q_CHECK_PTR(KProcessController::theKProcessController);
+ }
+
+ KProcessController::theKProcessController->addKProcess(this);
+ out[0] = out[1] = -1;
+ in[0] = in[1] = -1;
+ err[0] = err[1] = -1;
+}
+
+void
+KProcess::setEnvironment(const QString &name, const QString &value)
+{
+ if (!d)
+ d = new KProcessPrivate;
+ d->env.insert(name, value);
+}
+
+void
+KProcess::setWorkingDirectory(const QString &dir)
+{
+ if (!d)
+ d = new KProcessPrivate;
+ d->wd = dir;
+}
+
+void
+KProcess::setupEnvironment()
+{
+ if (d)
+ {
+ QMap<QString,QString>::Iterator it;
+ for(it = d->env.begin(); it != d->env.end(); ++it)
+ setenv(QFile::encodeName(it.key()).data(),
+ QFile::encodeName(it.data()).data(), 1);
+ if (!d->wd.isEmpty())
+ chdir(QFile::encodeName(d->wd).data());
+ }
+}
+
+void
+KProcess::setRunPrivileged(bool keepPrivileges)
+{
+ keepPrivs = keepPrivileges;
+}
+
+bool
+KProcess::runPrivileged() const
+{
+ return keepPrivs;
+}
+
+
+KProcess::~KProcess()
+{
+ // destroying the KProcess instance sends a SIGKILL to the
+ // child process (if it is running) after removing it from the
+ // list of valid processes (if the process is not started as
+ // "DontCare")
+
+ KProcessController::theKProcessController->removeKProcess(this);
+ // this must happen before we kill the child
+ // TODO: block the signal while removing the current process from the process list
+
+ if (runs && (run_mode != DontCare))
+ kill(SIGKILL);
+
+ // Clean up open fd's and socket notifiers.
+ closeStdin();
+ closeStdout();
+ closeStderr();
+
+ // TODO: restore SIGCHLD and SIGPIPE handler if this is the last KProcess
+ delete d;
+}
+
+void KProcess::detach()
+{
+ KProcessController::theKProcessController->removeKProcess(this);
+
+ runs = false;
+ pid_ = 0;
+
+ // Clean up open fd's and socket notifiers.
+ closeStdin();
+ closeStdout();
+ closeStderr();
+}
+
+bool KProcess::setExecutable(const QString& proc)
+{
+ if (runs) return false;
+
+ if (proc.isEmpty()) return false;
+
+ if (!arguments.isEmpty())
+ arguments.remove(arguments.begin());
+ arguments.prepend(QFile::encodeName(proc));
+
+ return true;
+}
+
+KProcess &KProcess::operator<<(const QStringList& args)
+{
+ QStringList::ConstIterator it = args.begin();
+ for ( ; it != args.end() ; ++it )
+ arguments.append(QFile::encodeName(*it));
+ return *this;
+}
+
+KProcess &KProcess::operator<<(const QCString& arg)
+{
+ return operator<< (arg.data());
+}
+
+KProcess &KProcess::operator<<(const char* arg)
+{
+ arguments.append(arg);
+ return *this;
+}
+
+KProcess &KProcess::operator<<(const QString& arg)
+{
+ arguments.append(QFile::encodeName(arg));
+ return *this;
+}
+
+void KProcess::clearArguments()
+{
+ arguments.clear();
+}
+
+bool KProcess::start(RunMode runmode, Communication comm)
+{
+ uint i;
+ uint n = arguments.count();
+ char **arglist;
+
+ if (runs || (0 == n)) {
+ return false; // cannot start a process that is already running
+ // or if no executable has been assigned
+ }
+ run_mode = runmode;
+ status = 0;
+
+ QCString shellCmd;
+ if (d && d->useShell)
+ {
+ if (d->shell.isEmpty())
+ {
+ //kdDebug() << "Could not find a valid shell\n" << endl;
+ return false;
+ }
+
+ arglist = static_cast<char **>(malloc( (4)*sizeof(char *)));
+ for (i=0; i < n; i++) {
+ shellCmd += arguments[i];
+ shellCmd += " "; // CC: to separate the arguments
+ }
+
+ arglist[0] = d->shell.data();
+ arglist[1] = (char *) "-c";
+ arglist[2] = shellCmd.data();
+ arglist[3] = 0;
+ }
+ else
+ {
+ arglist = static_cast<char **>(malloc( (n+1)*sizeof(char *)));
+ for (i=0; i < n; i++)
+ arglist[i] = arguments[i].data();
+ arglist[n]= 0;
+ }
+
+ setupCommunication(comm);
+ //)
+ //kdDebug() << "Could not setup Communication!\n";
+
+ // We do this in the parent because if we do it in the child process
+ // gdb gets confused when the application runs from gdb.
+ uid_t uid = getuid();
+ gid_t gid = getgid();
+#ifdef HAVE_INITGROUPS
+ struct passwd *pw = getpwuid(uid);
+#endif
+
+ int fd[2];
+ if (0 > pipe(fd))
+ {
+ fd[0] = fd[1] = 0; // Pipe failed.. continue
+ }
+
+ runs = true;
+
+ QApplication::flushX();
+
+ // WABA: Note that we use fork() and not vfork() because
+ // vfork() has unclear semantics and is not standardized.
+ pid_ = fork();
+
+ if (0 == pid_) {
+ if (fd[0])
+ close(fd[0]);
+ if (!runPrivileged())
+ {
+ setgid(gid);
+#if defined( HAVE_INITGROUPS)
+ if(pw)
+ initgroups(pw->pw_name, pw->pw_gid);
+#endif
+ setuid(uid);
+ }
+ // The child process
+ commSetupDoneC();
+ //)
+ //kdDebug() << "Could not finish comm setup in child!" << endl;
+
+ setupEnvironment();
+
+ // Matthias
+ if (run_mode == DontCare)
+ setpgid(0,0);
+ // restore default SIGPIPE handler (Harri)
+ struct sigaction act;
+ sigemptyset(&(act.sa_mask));
+ sigaddset(&(act.sa_mask), SIGPIPE);
+ act.sa_handler = SIG_DFL;
+ act.sa_flags = 0;
+ sigaction(SIGPIPE, &act, 0L);
+
+ // We set the close on exec flag.
+ // Closing of fd[1] indicates that the execvp succeeded!
+ if (fd[1])
+ fcntl(fd[1], F_SETFD, FD_CLOEXEC);
+ execvp(arglist[0], arglist);
+ char resultByte = 1;
+ if (fd[1])
+ write(fd[1], &resultByte, 1);
+ _exit(-1);
+ } else if (-1 == pid_) {
+ // forking failed
+
+ runs = false;
+ free(arglist);
+ return false;
+ } else {
+ if (fd[1])
+ close(fd[1]);
+ // the parent continues here
+
+ // Discard any data for stdin that might still be there
+ input_data = 0;
+
+ // Check whether client could be started.
+ if (fd[0]) for(;;)
+ {
+ char resultByte;
+ int n = ::read(fd[0], &resultByte, 1);
+ if (n == 1)
+ {
+ // Error
+ runs = false;
+ close(fd[0]);
+ free(arglist);
+ pid_ = 0;
+ return false;
+ }
+ if (n == -1)
+ {
+ if ((errno == ECHILD) || (errno == EINTR))
+ continue; // Ignore
+ }
+ break; // success
+ }
+ if (fd[0])
+ close(fd[0]);
+
+ if (!commSetupDoneP()){} // finish communication socket setup for the parent
+ //kdDebug() << "Could not finish comm setup in parent!" << endl;
+
+ if (run_mode == Block) {
+ commClose();
+
+ // The SIGCHLD handler of the process controller will catch
+ // the exit and set the status
+ while(runs)
+ {
+ KProcessController::theKProcessController->
+ slotDoHousekeeping(0);
+ }
+ runs = FALSE;
+ emit processExited(this);
+ }
+ }
+ free(arglist);
+ return true;
+}
+
+
+
+bool KProcess::kill(int signo)
+{
+ bool rv=false;
+
+ if (0 != pid_)
+ rv= (-1 != ::kill(pid_, signo));
+ // probably store errno somewhere...
+ return rv;
+}
+
+
+
+bool KProcess::isRunning() const
+{
+ return runs;
+}
+
+
+
+pid_t KProcess::pid() const
+{
+ return pid_;
+}
+
+
+
+bool KProcess::normalExit() const
+{
+ int _status = status;
+ return (pid_ != 0) && (!runs) && (WIFEXITED((_status)));
+}
+
+
+
+int KProcess::exitStatus() const
+{
+ int _status = status;
+ return WEXITSTATUS((_status));
+}
+
+
+
+bool KProcess::writeStdin(const char *buffer, int buflen)
+{
+ bool rv;
+
+ // if there is still data pending, writing new data
+ // to stdout is not allowed (since it could also confuse
+ // kprocess...
+ if (0 != input_data)
+ return false;
+
+ if (runs && (communication & Stdin)) {
+ input_data = buffer;
+ input_sent = 0;
+ input_total = buflen;
+ slotSendData(0);
+ innot->setEnabled(true);
+ rv = true;
+ } else
+ rv = false;
+ return rv;
+}
+
+void KProcess::suspend()
+{
+ if ((communication & Stdout) && outnot)
+ outnot->setEnabled(false);
+}
+
+void KProcess::resume()
+{
+ if ((communication & Stdout) && outnot)
+ outnot->setEnabled(true);
+}
+
+bool KProcess::closeStdin()
+{
+ bool rv;
+
+ if (communication & Stdin) {
+ communication = (Communication) (communication & ~Stdin);
+ delete innot;
+ innot = 0;
+ close(in[1]);
+ rv = true;
+ } else
+ rv = false;
+ return rv;
+}
+
+bool KProcess::closeStdout()
+{
+ bool rv;
+
+ if (communication & Stdout) {
+ communication = (Communication) (communication & ~Stdout);
+ delete outnot;
+ outnot = 0;
+ close(out[0]);
+ rv = true;
+ } else
+ rv = false;
+ return rv;
+}
+
+bool KProcess::closeStderr()
+{
+ bool rv;
+
+ if (communication & Stderr) {
+ communication = static_cast<Communication>(communication & ~Stderr);
+ delete errnot;
+ errnot = 0;
+ close(err[0]);
+ rv = true;
+ } else
+ rv = false;
+ return rv;
+}
+
+
+/////////////////////////////
+// protected slots //
+/////////////////////////////
+
+
+
+void KProcess::slotChildOutput(int fdno)
+{
+ if (!childOutput(fdno))
+ closeStdout();
+}
+
+
+void KProcess::slotChildError(int fdno)
+{
+ if (!childError(fdno))
+ closeStderr();
+}
+
+
+void KProcess::slotSendData(int)
+{
+ if (input_sent == input_total) {
+ innot->setEnabled(false);
+ input_data = 0;
+ emit wroteStdin(this);
+ } else
+ input_sent += ::write(in[1], input_data+input_sent, input_total-input_sent);
+}
+
+
+
+//////////////////////////////
+// private member functions //
+//////////////////////////////
+
+
+
+void KProcess::processHasExited(int state)
+{
+ if (runs)
+ {
+ runs = false;
+ status = state;
+
+ commClose(); // cleanup communication sockets
+
+ // also emit a signal if the process was run Blocking
+ if (DontCare != run_mode)
+ {
+ emit processExited(this);
+ }
+ }
+}
+
+
+
+int KProcess::childOutput(int fdno)
+{
+ if (communication & NoRead) {
+ int len = -1;
+ emit receivedStdout(fdno, len);
+ errno = 0; // Make sure errno doesn't read "EAGAIN"
+ return len;
+ }
+ else
+ {
+ char buffer[1024];
+ int len;
+
+ len = ::read(fdno, buffer, 1024);
+
+ if ( 0 < len) {
+ emit receivedStdout(this, buffer, len);
+ }
+ return len;
+ }
+}
+
+
+
+int KProcess::childError(int fdno)
+{
+ char buffer[1024];
+ int len;
+
+ len = ::read(fdno, buffer, 1024);
+
+ if ( 0 < len)
+ emit receivedStderr(this, buffer, len);
+ return len;
+}
+
+
+
+int KProcess::setupCommunication(Communication comm)
+{
+ int ok;
+
+ communication = comm;
+
+ ok = 1;
+ if (comm & Stdin)
+ ok &= socketpair(AF_UNIX, SOCK_STREAM, 0, in) >= 0;
+
+ if (comm & Stdout)
+ ok &= socketpair(AF_UNIX, SOCK_STREAM, 0, out) >= 0;
+
+ if (comm & Stderr)
+ ok &= socketpair(AF_UNIX, SOCK_STREAM, 0, err) >= 0;
+
+ return ok;
+}
+
+
+
+int KProcess::commSetupDoneP()
+{
+ int ok = 1;
+
+ if (communication != NoCommunication) {
+ if (communication & Stdin)
+ close(in[0]);
+ if (communication & Stdout)
+ close(out[1]);
+ if (communication & Stderr)
+ close(err[1]);
+
+ // Don't create socket notifiers and set the sockets non-blocking if
+ // blocking is requested.
+ if (run_mode == Block) return ok;
+
+ if (communication & Stdin) {
+// ok &= (-1 != fcntl(in[1], F_SETFL, O_NONBLOCK));
+ innot = new QSocketNotifier(in[1], QSocketNotifier::Write, this);
+ Q_CHECK_PTR(innot);
+ innot->setEnabled(false); // will be enabled when data has to be sent
+ QObject::connect(innot, SIGNAL(activated(int)),
+ this, SLOT(slotSendData(int)));
+ }
+
+ if (communication & Stdout) {
+// ok &= (-1 != fcntl(out[0], F_SETFL, O_NONBLOCK));
+ outnot = new QSocketNotifier(out[0], QSocketNotifier::Read, this);
+ Q_CHECK_PTR(outnot);
+ QObject::connect(outnot, SIGNAL(activated(int)),
+ this, SLOT(slotChildOutput(int)));
+ if (communication & NoRead)
+ suspend();
+ }
+
+ if (communication & Stderr) {
+// ok &= (-1 != fcntl(err[0], F_SETFL, O_NONBLOCK));
+ errnot = new QSocketNotifier(err[0], QSocketNotifier::Read, this );
+ Q_CHECK_PTR(errnot);
+ QObject::connect(errnot, SIGNAL(activated(int)),
+ this, SLOT(slotChildError(int)));
+ }
+ }
+ return ok;
+}
+
+
+
+int KProcess::commSetupDoneC()
+{
+ int ok = 1;
+ struct linger so;
+ memset(&so, 0, sizeof(so));
+
+ if (communication & Stdin)
+ close(in[1]);
+ if (communication & Stdout)
+ close(out[0]);
+ if (communication & Stderr)
+ close(err[0]);
+
+ if (communication & Stdin)
+ ok &= dup2(in[0], STDIN_FILENO) != -1;
+ else {
+ int null_fd = open( "/dev/null", O_RDONLY );
+ ok &= dup2( null_fd, STDIN_FILENO ) != -1;
+ close( null_fd );
+ }
+ if (communication & Stdout) {
+ ok &= dup2(out[1], STDOUT_FILENO) != -1;
+ ok &= !setsockopt(out[1], SOL_SOCKET, SO_LINGER, (char*)&so, sizeof(so));
+ }
+ else {
+ int null_fd = open( "/dev/null", O_WRONLY );
+ ok &= dup2( null_fd, STDOUT_FILENO ) != -1;
+ close( null_fd );
+ }
+ if (communication & Stderr) {
+ ok &= dup2(err[1], STDERR_FILENO) != -1;
+ ok &= !setsockopt(err[1], SOL_SOCKET, SO_LINGER, reinterpret_cast<char *>(&so), sizeof(so));
+ }
+ else {
+ int null_fd = open( "/dev/null", O_WRONLY );
+ ok &= dup2( null_fd, STDERR_FILENO ) != -1;
+ close( null_fd );
+ }
+ return ok;
+}
+
+
+
+void KProcess::commClose()
+{
+ if (NoCommunication != communication) {
+ bool b_in = (communication & Stdin);
+ bool b_out = (communication & Stdout);
+ bool b_err = (communication & Stderr);
+ if (b_in)
+ delete innot;
+
+ if (b_out || b_err) {
+ // If both channels are being read we need to make sure that one socket buffer
+ // doesn't fill up whilst we are waiting for data on the other (causing a deadlock).
+ // Hence we need to use select.
+
+ // Once one or other of the channels has reached EOF (or given an error) go back
+ // to the usual mechanism.
+
+ int fds_ready = 1;
+ fd_set rfds;
+
+ int max_fd = 0;
+ if (b_out) {
+ fcntl(out[0], F_SETFL, O_NONBLOCK);
+ if (out[0] > max_fd)
+ max_fd = out[0];
+ delete outnot;
+ outnot = 0;
+ }
+ if (b_err) {
+ fcntl(err[0], F_SETFL, O_NONBLOCK);
+ if (err[0] > max_fd)
+ max_fd = err[0];
+ delete errnot;
+ errnot = 0;
+ }
+
+
+ while (b_out || b_err) {
+ // * If the process is still running we block until we
+ // receive data. (p_timeout = 0, no timeout)
+ // * If the process has already exited, we only check
+ // the available data, we don't wait for more.
+ // (p_timeout = &timeout, timeout immediately)
+ struct timeval timeout;
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 0;
+ struct timeval *p_timeout = runs ? 0 : &timeout;
+
+ FD_ZERO(&rfds);
+ if (b_out)
+ FD_SET(out[0], &rfds);
+
+ if (b_err)
+ FD_SET(err[0], &rfds);
+
+ fds_ready = select(max_fd+1, &rfds, 0, 0, p_timeout);
+ if (fds_ready <= 0) break;
+
+ if (b_out && FD_ISSET(out[0], &rfds)) {
+ int ret = 1;
+ while (ret > 0) ret = childOutput(out[0]);
+ if ((ret == -1 && errno != EAGAIN) || ret == 0)
+ b_out = false;
+ }
+
+ if (b_err && FD_ISSET(err[0], &rfds)) {
+ int ret = 1;
+ while (ret > 0) ret = childError(err[0]);
+ if ((ret == -1 && errno != EAGAIN) || ret == 0)
+ b_err = false;
+ }
+ }
+ }
+
+ if (b_in) {
+ communication = (Communication) (communication & ~Stdin);
+ close(in[1]);
+ }
+ if (b_out) {
+ communication = (Communication) (communication & ~Stdout);
+ close(out[0]);
+ }
+ if (b_err) {
+ communication = (Communication) (communication & ~Stderr);
+ close(err[0]);
+ }
+ }
+}
+
+void KProcess::setUseShell(bool useShell, const char *shell)
+{
+ if (!d)
+ d = new KProcessPrivate;
+ d->useShell = useShell;
+ d->shell = shell;
+ if (d->shell.isEmpty())
+ d->shell = searchShell();
+}
+
+QString KProcess::quote(const QString &arg)
+{
+ QString res = arg;
+ res.replace(QRegExp(QString::fromLatin1("\'")),
+ QString::fromLatin1("'\"'\"'"));
+ res.prepend('\'');
+ res.append('\'');
+ return res;
+}
+
+QCString KProcess::searchShell()
+{
+ QCString tmpShell = QCString(getenv("SHELL")).stripWhiteSpace();
+ if (!isExecutable(tmpShell))
+ {
+ tmpShell = "/bin/sh";
+ }
+
+ return tmpShell;
+}
+
+bool KProcess::isExecutable(const QCString &filename)
+{
+ struct stat fileinfo;
+
+ if (filename.isEmpty()) return false;
+
+ // CC: we've got a valid filename, now let's see whether we can execute that file
+
+ if (-1 == stat(filename.data(), &fileinfo)) return false;
+ // CC: return false if the file does not exist
+
+ // CC: anyway, we cannot execute directories, block/character devices, fifos or sockets
+ if ( (S_ISDIR(fileinfo.st_mode)) ||
+ (S_ISCHR(fileinfo.st_mode)) ||
+ (S_ISBLK(fileinfo.st_mode)) ||
+#ifdef S_ISSOCK
+ // CC: SYSVR4 systems don't have that macro
+ (S_ISSOCK(fileinfo.st_mode)) ||
+#endif
+ (S_ISFIFO(fileinfo.st_mode)) ||
+ (S_ISDIR(fileinfo.st_mode)) ) {
+ return false;
+ }
+
+ // CC: now check for permission to execute the file
+ if (access(filename.data(), X_OK) != 0) return false;
+
+ // CC: we've passed all the tests...
+ return true;
+}
+
+void KProcess::virtual_hook( int, void* )
+{ /*BASE::virtual_hook( id, data );*/ }
+
+
+///////////////////////////
+// CC: Class KShellProcess
+///////////////////////////
+
+KShellProcess::KShellProcess(const char *shellname):
+ KProcess()
+{
+ setUseShell(true, shellname);
+}
+
+
+KShellProcess::~KShellProcess() {
+}
+
+QString KShellProcess::quote(const QString &arg)
+{
+ return KProcess::quote(arg);
+}
+
+bool KShellProcess::start(RunMode runmode, Communication comm)
+{
+ return KProcess::start(runmode, comm);
+}
+
+void KShellProcess::virtual_hook( int id, void* data )
+{ KProcess::virtual_hook( id, data ); }
+
+//#include "kprocess.moc"
diff --git a/noncore/net/networksetup/kprocess.h b/noncore/net/networksetup/kprocess.h
new file mode 100644
index 0000000..e70f7e7
--- a/dev/null
+++ b/noncore/net/networksetup/kprocess.h
@@ -0,0 +1,804 @@
+/* This file is part of the KDE libraries
+ Copyright (C) 1997 Christian Czezakte (e9025461@student.tuwien.ac.at)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+//
+// KPROCESS -- A class for handling child processes in KDE without
+// having to take care of Un*x specific implementation details
+//
+// version 0.3.1, Jan 8th 1998
+//
+// (C) Christian Czezatke
+// e9025461@student.tuwien.ac.at
+//
+
+#ifndef __kprocess_h__
+#define __kprocess_h__
+
+#include <sys/types.h> // for pid_t
+#include <sys/wait.h>
+#include <signal.h>
+#include <unistd.h>
+#include <qvaluelist.h>
+#include <qcstring.h>
+#include <qobject.h>
+
+class QSocketNotifier;
+class KProcessPrivate;
+
+/**
+ * Child process invocation, monitoring and control.
+ *
+ * @sect General usage and features
+ *
+ *This class allows a KDE application to start child processes without having
+ *to worry about UN*X signal handling issues and zombie process reaping.
+ *
+ *@see KProcIO
+ *
+ *Basically, this class distinguishes three different ways of running
+ *child processes:
+ *
+ *@li KProcess::DontCare -- The child process is invoked and both the child
+ *process and the parent process continue concurrently.
+ *
+ *Starting a DontCare child process means that the application is
+ *not interested in any notification to determine whether the
+ *child process has already exited or not.
+ *
+ *@li KProcess::NotifyOnExit -- The child process is invoked and both the
+ *child and the parent process run concurrently.
+ *
+ *When the child process exits, the KProcess instance
+ *corresponding to it emits the Qt signal @ref processExited().
+ *
+ *Since this signal is @em not emitted from within a UN*X
+ *signal handler, arbitrary function calls can be made.
+ *
+ *Be aware: When the KProcess objects gets destructed, the child
+ *process will be killed if it is still running!
+ *This means in particular, that you cannot use a KProcess on the stack
+ *with KProcess::NotifyOnExit.
+ *
+ *@li KProcess::Block -- The child process starts and the parent process
+ *is suspended until the child process exits. (@em Really not recommended
+ *for programs with a GUI.)
+ *
+ *KProcess also provides several functions for determining the exit status
+ *and the pid of the child process it represents.
+ *
+ *Furthermore it is possible to supply command-line arguments to the process
+ *in a clean fashion (no null -- terminated stringlists and such...)
+ *
+ *A small usage example:
+ *<pre>
+ *KProcess *proc = new KProcess;
+ *
+ **proc << "my_executable";
+ **proc << "These" << "are" << "the" << "command" << "line" << "args";
+ *QApplication::connect(proc, SIGNAL(processExited(KProcess *)),
+ * pointer_to_my_object, SLOT(my_objects_slot(KProcess *)));
+ *proc->start();
+ *</pre>
+ *
+ *This will start "my_executable" with the commandline arguments "These"...
+ *
+ *When the child process exits, the respective Qt signal will be emitted.
+ *
+ *@sect Communication with the child process
+ *
+ *KProcess supports communication with the child process through
+ *stdin/stdout/stderr.
+ *
+ *The following functions are provided for getting data from the child
+ *process or sending data to the child's stdin (For more information,
+ *have a look at the documentation of each function):
+ *
+ *@li bool @ref writeStdin(char *buffer, int buflen);
+ *@li -- Transmit data to the child process's stdin.
+ *
+ *@li bool @ref closeStdin();
+ *@li -- Closes the child process's stdin (which causes it to see an feof(stdin)).
+ *Returns false if you try to close stdin for a process that has been started
+ *without a communication channel to stdin.
+ *
+ *@li bool @ref closeStdout();
+ *@li -- Closes the child process's stdout.
+ *Returns false if you try to close stdout for a process that has been started
+ *without a communication channel to stdout.
+ *
+ *@li bool @ref closeStderr();
+ *@li -- Closes the child process's stderr.
+ *Returns false if you try to close stderr for a process that has been started
+ *without a communication channel to stderr.
+ *
+ *
+ *@sect QT signals:
+ *
+ *@li void @ref receivedStdout(KProcess *proc, char *buffer, int buflen);
+ *@li void @ref receivedStderr(KProcess *proc, char *buffer, int buflen);
+ *@li -- Indicates that new data has arrived from either the
+ *child process's stdout or stderr.
+ *
+ *@li void @ref wroteStdin(KProcess *proc);
+ *@li -- Indicates that all data that has been sent to the child process
+ *by a prior call to @ref writeStdin() has actually been transmitted to the
+ *client .
+ *
+ *@author Christian Czezakte e9025461@student.tuwien.ac.at
+ *
+ *
+ **/
+class KProcess : public QObject
+{
+ Q_OBJECT
+
+public:
+
+ /**
+ * Modes in which the communication channel can be opened.
+ *
+ * If communication for more than one channel is required,
+ * the values have to be or'ed together, for example to get
+ * communication with stdout as well as with stdin, you would
+ * specify @p Stdin @p | @p Stdout
+ *
+ * If @p NoRead is specified in conjunction with @p Stdout,
+ * no data is actually read from @p Stdout but only
+ * the signal @ref childOutput(int fd) is emitted.
+ */
+ enum Communication { NoCommunication = 0, Stdin = 1, Stdout = 2, Stderr = 4,
+ AllOutput = 6, All = 7,
+ NoRead };
+
+ /**
+ * Run-modes for a child process.
+ */
+ enum RunMode {
+ /**
+ * The application does not receive notifications from the subprocess when
+ * it is finished or aborted.
+ */
+ DontCare,
+ /**
+ * The application is notified when the subprocess dies.
+ */
+ NotifyOnExit,
+ /**
+ * The application is suspended until the started process is finished.
+ */
+ Block };
+
+ /**
+ * Constructor
+ */
+ KProcess();
+
+ /**
+ *Destructor:
+ *
+ * If the process is running when the destructor for this class
+ * is called, the child process is killed with a SIGKILL, but
+ * only if the run mode is not of type @p DontCare.
+ * Processes started as @p DontCare keep running anyway.
+ */
+ virtual ~KProcess();
+
+ /**
+ @deprecated
+
+ The use of this function is now deprecated. -- Please use the
+ "operator<<" instead of "setExecutable".
+
+ Sets the executable to be started with this KProcess object.
+ Returns false if the process is currently running (in that
+ case the executable remains unchanged.)
+
+ @see operator<<
+
+ */
+ bool setExecutable(const QString& proc);
+
+
+ /**
+ * Sets the executable and the command line argument list for this process.
+ *
+ * For example, doing an "ls -l /usr/local/bin" can be achieved by:
+ * <pre>
+ * KProcess p;
+ * ...
+ * p << "ls" << "-l" << "/usr/local/bin"
+ * </pre>
+ *
+ **/
+ KProcess &operator<<(const QString& arg);
+ /**
+ * Similar to previous method, takes a char *, supposed to be in locale 8 bit already.
+ */
+ KProcess &operator<<(const char * arg);
+ /**
+ * Similar to previous method, takes a QCString, supposed to be in locale 8 bit already.
+ */
+ KProcess &operator<<(const QCString & arg);
+
+ /**
+ * Sets the executable and the command line argument list for this process,
+ * in a single method call, or add a list of arguments.
+ **/
+ KProcess &operator<<(const QStringList& args);
+
+ /**
+ * Clear a command line argument list that has been set by using
+ * the "operator<<".
+ */
+ void clearArguments();
+
+ /**
+ * Starts the process.
+ * For a detailed description of the
+ * various run modes and communication semantics, have a look at the
+ * general description of the KProcess class.
+ *
+ * The following problems could cause this function to
+ * return false:
+ *
+ * @li The process is already running.
+ * @li The command line argument list is empty.
+ * @li The starting of the process failed (could not fork).
+ * @li The executable was not found.
+ *
+ * @param comm Specifies which communication links should be
+ * established to the child process (stdin/stdout/stderr). By default,
+ * no communication takes place and the respective communication
+ * signals will never get emitted.
+ *
+ * @return true on success, false on error
+ * (see above for error conditions)
+ **/
+ virtual bool start(RunMode runmode = NotifyOnExit,
+ Communication comm = NoCommunication);
+
+ /**
+ * Stop the process (by sending it a signal).
+ *
+ * @param signo The signal to send. The default is SIGTERM.
+ * @return @p true if the signal was delivered successfully.
+ */
+ virtual bool kill(int signo = SIGTERM);
+
+ /**
+ @return @p true if the process is (still) considered to be running
+ */
+ bool isRunning() const;
+
+ /** Returns the process id of the process.
+ *
+ * If it is called after
+ * the process has exited, it returns the process id of the last
+ * child process that was created by this instance of KProcess.
+ *
+ * Calling it before any child process has been started by this
+ * KProcess instance causes pid() to return 0.
+ **/
+ pid_t pid() const;
+
+ /**
+ * Use pid().
+ * @deprecated
+ */
+ pid_t getPid() const { return pid(); }
+
+ /**
+ * Suspend processing of data from stdout of the child process.
+ */
+ void suspend();
+
+ /**
+ * Resume processing of data from stdout of the child process.
+ */
+ void resume();
+
+ /**
+ * @return @p true if the process has already finished and has exited
+ * "voluntarily", ie: it has not been killed by a signal.
+ *
+ * Note that you should check @ref KProcess::exitStatus() to determine
+ * whether the process completed its task successful or not.
+ */
+ bool normalExit() const;
+
+ /**
+ * Returns the exit status of the process.
+ *
+ * Please use
+ * @ref KProcess::normalExit() to check whether the process has exited
+ * cleanly (i.e., @ref KProcess::normalExit() returns @p true) before calling
+ * this function because if the process did not exit normally,
+ * it does not have a valid exit status.
+ */
+ int exitStatus() const;
+
+
+ /**
+ * Transmit data to the child process's stdin.
+ *
+ * KProcess::writeStdin may return false in the following cases:
+ *
+ * @li The process is not currently running.
+ *
+ * @li Communication to stdin has not been requested in the @ref start() call.
+ *
+ * @li Transmission of data to the child process by a previous call to
+ * @ref writeStdin() is still in progress.
+ *
+ * Please note that the data is sent to the client asynchronously,
+ * so when this function returns, the data might not have been
+ * processed by the child process.
+ *
+ * If all the data has been sent to the client, the signal
+ * @ref wroteStdin() will be emitted.
+ *
+ * Please note that you must not free "buffer" or call @ref writeStdin()
+ * again until either a @ref wroteStdin() signal indicates that the
+ * data has been sent or a @ref processHasExited() signal shows that
+ * the child process is no longer alive...
+ **/
+ bool writeStdin(const char *buffer, int buflen);
+
+ /**
+ * This causes the stdin file descriptor of the child process to be
+ * closed indicating an "EOF" to the child.
+ *
+ * @return @p false if no communication to the process's stdin
+ * had been specified in the call to @ref start().
+ */
+ bool closeStdin();
+
+ /**
+ * This causes the stdout file descriptor of the child process to be
+ * closed.
+ *
+ * @return @p false if no communication to the process's stdout
+ * had been specified in the call to @ref start().
+ */
+ bool closeStdout();
+
+ /**
+ * This causes the stderr file descriptor of the child process to be
+ * closed.
+ *
+ * @return @p false if no communication to the process's stderr
+ * had been specified in the call to @ref start().
+ */
+ bool closeStderr();
+
+ /**
+ * Lets you see what your arguments are for debugging.
+ */
+
+ const QValueList<QCString> &args() { return arguments; }
+
+ /**
+ * Controls whether the started process should drop any
+ * setuid/segid privileges or whether it should keep them
+ *
+ * The default is @p false : drop privileges
+ */
+ void setRunPrivileged(bool keepPrivileges);
+
+ /**
+ * Returns whether the started process will drop any
+ * setuid/segid privileges or whether it will keep them
+ */
+ bool runPrivileged() const;
+
+ /**
+ * Modifies the environment of the process to be started.
+ * This function must be called before starting the process.
+ */
+ void setEnvironment(const QString &name, const QString &value);
+
+ /**
+ * Changes the current working directory (CWD) of the process
+ * to be started.
+ * This function must be called before starting the process.
+ */
+ void setWorkingDirectory(const QString &dir);
+
+ /**
+ * Specify whether to start the command via a shell or directly.
+ * The default is to start the command directly.
+ * If @p useShell is true @p shell will be used as shell, or
+ * if shell is empty, the standard shell is used.
+ * @p quote A flag indicating whether to quote the arguments.
+ *
+ * When using a shell, the caller should make sure that all filenames etc.
+ * are properly quoted when passed as argument.
+ * @see quote()
+ */
+ void setUseShell(bool useShell, const char *shell = 0);
+
+ /**
+ * This function can be used to quote an argument string such that
+ * the shell processes it properly. This is e. g. necessary for
+ * user-provided file names which may contain spaces or quotes.
+ * It also prevents expansion of wild cards and environment variables.
+ */
+ static QString quote(const QString &arg);
+
+ /**
+ * Detaches KProcess from child process. All communication is closed.
+ * No exit notification is emitted any more for the child process.
+ * Deleting the KProcess will no longer kill the child process.
+ * Note that the current process remains the parent process of the
+ * child process.
+ */
+ void detach();
+
+
+
+signals:
+
+ /**
+ * Emitted after the process has terminated when
+ * the process was run in the @p NotifyOnExit (==default option to
+ * @ref start()) or the @ref Block mode.
+ **/
+ void processExited(KProcess *proc);
+
+
+ /**
+ * Emitted, when output from the child process has
+ * been received on stdout.
+ *
+ * To actually get
+ * these signals, the respective communication link (stdout/stderr)
+ * has to be turned on in @ref start().
+ *
+ * @param buffer The data received.
+ * @param buflen The number of bytes that are available.
+ *
+ * You should copy the information contained in @p buffer to your private
+ * data structures before returning from this slot.
+ **/
+ void receivedStdout(KProcess *proc, char *buffer, int buflen);
+
+ /**
+ * Emitted when output from the child process has
+ * been received on stdout.
+ *
+ * To actually get these signals, the respective communications link
+ * (stdout/stderr) has to be turned on in @ref start() and the
+ * @p NoRead flag should have been passed.
+ *
+ * You will need to explicitly call resume() after your call to start()
+ * to begin processing data from the child process's stdout. This is
+ * to ensure that this signal is not emitted when no one is connected
+ * to it, otherwise this signal will not be emitted.
+ *
+ * The data still has to be read from file descriptor @p fd.
+ **/
+ void receivedStdout(int fd, int &len);
+
+
+ /**
+ * Emitted, when output from the child process has
+ * been received on stderr.
+ * To actually get
+ * these signals, the respective communication link (stdout/stderr)
+ * has to be turned on in @ref start().
+ *
+ * @param buffer The data received.
+ * @param buflen The number of bytes that are available.
+ *
+ * You should copy the information contained in @p buffer to your private
+ * data structures before returning from this slot.
+ */
+ void receivedStderr(KProcess *proc, char *buffer, int buflen);
+
+ /**
+ * Emitted after all the data that has been
+ * specified by a prior call to @ref writeStdin() has actually been
+ * written to the child process.
+ **/
+ void wroteStdin(KProcess *proc);
+
+
+protected slots:
+
+ /**
+ * This slot gets activated when data from the child's stdout arrives.
+ * It usually calls "childOutput"
+ */
+ void slotChildOutput(int fdno);
+
+ /**
+ * This slot gets activated when data from the child's stderr arrives.
+ * It usually calls "childError"
+ */
+ void slotChildError(int fdno);
+ /*
+ Slot functions for capturing stdout and stderr of the child
+ */
+
+ /**
+ * Called when another bulk of data can be sent to the child's
+ * stdin. If there is no more data to be sent to stdin currently
+ * available, this function must disable the QSocketNotifier "innot".
+ */
+ void slotSendData(int dummy);
+
+protected:
+
+ /**
+ * Sets up the environment according to the data passed via
+ * setEnvironment(...)
+ */
+ void setupEnvironment();
+
+ /**
+ * The list of the process' command line arguments. The first entry
+ * in this list is the executable itself.
+ */
+ QValueList<QCString> arguments;
+ /**
+ * How to run the process (Block, NotifyOnExit, DontCare). You should
+ * not modify this data member directly from derived classes.
+ */
+ RunMode run_mode;
+ /**
+ * true if the process is currently running. You should not
+ * modify this data member directly from derived classes. For
+ * reading the value of this data member, please use "isRunning()"
+ * since "runs" will probably be made private in later versions
+ * of KProcess.
+ */
+ bool runs;
+
+ /**
+ * The PID of the currently running process (see "getPid()").
+ * You should not modify this data member in derived classes.
+ * Please use "getPid()" instead of directly accessing this
+ * member function since it will probably be made private in
+ * later versions of KProcess.
+ */
+ pid_t pid_;
+
+ /**
+ * The process' exit status as returned by "waitpid". You should not
+ * modify the value of this data member from derived classes. You should
+ * rather use @ref exitStatus than accessing this data member directly
+ * since it will probably be made private in further versions of
+ * KProcess.
+ */
+ int status;
+
+
+ /**
+ * See setRunPrivileged()
+ */
+ bool keepPrivs;
+
+ /*
+ Functions for setting up the sockets for communication.
+ setupCommunication
+ -- is called from "start" before "fork"ing.
+ commSetupDoneP
+ -- completes communication socket setup in the parent
+ commSetupDoneC
+ -- completes communication setup in the child process
+ commClose
+ -- frees all allocated communication resources in the parent
+ after the process has exited
+ */
+
+ /**
+ * This function is called from "KProcess::start" right before a "fork" takes
+ * place. According to
+ * the "comm" parameter this function has to initialize the "in", "out" and
+ * "err" data member of KProcess.
+ *
+ * This function should return 0 if setting the needed communication channels
+ * was successful.
+ *
+ * The default implementation is to create UNIX STREAM sockets for the communication,
+ * but you could overload this function and establish a TCP/IP communication for
+ * network communication, for example.
+ */
+ virtual int setupCommunication(Communication comm);
+
+ /**
+ * Called right after a (successful) fork on the parent side. This function
+ * will usually do some communications cleanup, like closing the reading end
+ * of the "stdin" communication channel.
+ *
+ * Furthermore, it must also create the QSocketNotifiers "innot", "outnot" and
+ * "errnot" and connect their Qt slots to the respective KProcess member functions.
+ *
+ * For a more detailed explanation, it is best to have a look at the default
+ * implementation of "setupCommunication" in kprocess.cpp.
+ */
+ virtual int commSetupDoneP();
+
+ /**
+ * Called right after a (successful) fork, but before an "exec" on the child
+ * process' side. It usually just closes the unused communication ends of
+ * "in", "out" and "err" (like the writing end of the "in" communication
+ * channel.
+ */
+ virtual int commSetupDoneC();
+
+
+ /**
+ * Immediately called after a process has exited. This function normally
+ * calls commClose to close all open communication channels to this
+ * process and emits the "processExited" signal (if the process was
+ * not running in the "DontCare" mode).
+ */
+ virtual void processHasExited(int state);
+
+ /**
+ * Should clean up the communication links to the child after it has
+ * exited. Should be called from "processHasExited".
+ */
+ virtual void commClose();
+
+
+ /**
+ * the socket descriptors for stdin/stdout/stderr.
+ */
+ int out[2];
+ int in[2];
+ int err[2];
+
+ /**
+ * The socket notifiers for the above socket descriptors.
+ */
+ QSocketNotifier *innot;
+ QSocketNotifier *outnot;
+ QSocketNotifier *errnot;
+
+ /**
+ * Lists the communication links that are activated for the child
+ * process. Should not be modified from derived classes.
+ */
+ Communication communication;
+
+ /**
+ * Called by "slotChildOutput" this function copies data arriving from the
+ * child process's stdout to the respective buffer and emits the signal
+ * "@ref receivedStderr".
+ */
+ int childOutput(int fdno);
+
+ /**
+ * Called by "slotChildOutput" this function copies data arriving from the
+ * child process's stdout to the respective buffer and emits the signal
+ * "@ref receivedStderr"
+ */
+ int childError(int fdno);
+
+ // information about the data that has to be sent to the child:
+
+ const char *input_data; // the buffer holding the data
+ int input_sent; // # of bytes already transmitted
+ int input_total; // total length of input_data
+
+ /**
+ * @ref KProcessController is a friend of KProcess because it has to have
+ * access to various data members.
+ */
+ friend class KProcessController;
+
+
+private:
+ /**
+ * Searches for a valid shell.
+ * Here is the algorithm used for finding an executable shell:
+ *
+ * @li Try the executable pointed to by the "SHELL" environment
+ * variable with white spaces stripped off
+ *
+ * @li If your process runs with uid != euid or gid != egid, a shell
+ * not listed in /etc/shells will not used.
+ *
+ * @li If no valid shell could be found, "/bin/sh" is used as a last resort.
+ */
+ QCString searchShell();
+
+ /**
+ * Used by @ref searchShell in order to find out whether the shell found
+ * is actually executable at all.
+ */
+ bool isExecutable(const QCString &filename);
+
+ // Disallow assignment and copy-construction
+ KProcess( const KProcess& );
+ KProcess& operator= ( const KProcess& );
+
+protected:
+ virtual void virtual_hook( int id, void* data );
+private:
+ KProcessPrivate *d;
+};
+
+class KShellProcessPrivate;
+
+/**
+* @obsolete
+*
+* This class is obsolete. Use KProcess and KProcess::setUseShell(true)
+* instead.
+*
+* @short A class derived from @ref KProcess to start child
+* processes through a shell.
+* @author Christian Czezakte <e9025461@student.tuwien.ac.at>
+* @version $Id$
+*/
+class KShellProcess: public KProcess
+{
+ Q_OBJECT
+
+public:
+
+ /**
+ * Constructor
+ *
+ * By specifying the name of a shell (like "/bin/bash") you can override
+ * the mechanism for finding a valid shell as described in KProcess::searchShell()
+ */
+ KShellProcess(const char *shellname=0);
+
+ /**
+ * Destructor.
+ */
+ ~KShellProcess();
+
+ /**
+ * Starts up the process. -- For a detailed description
+ * have a look at the "start" member function and the detailed
+ * description of @ref KProcess .
+ */
+ virtual bool start(RunMode runmode = NotifyOnExit,
+ Communication comm = NoCommunication);
+
+ /**
+ * This function can be used to quote an argument string such that
+ * the shell processes it properly. This is e. g. necessary for
+ * user-provided file names which may contain spaces or quotes.
+ * It also prevents expansion of wild cards and environment variables.
+ */
+ static QString quote(const QString &arg);
+
+private:
+
+ QCString shell;
+
+ // Disallow assignment and copy-construction
+ KShellProcess( const KShellProcess& );
+ KShellProcess& operator= ( const KShellProcess& );
+
+protected:
+ virtual void virtual_hook( int id, void* data );
+private:
+ KShellProcessPrivate *d;
+};
+
+
+
+#endif
+
diff --git a/noncore/net/networksetup/main.cpp b/noncore/net/networksetup/main.cpp
new file mode 100644
index 0000000..52cb92b
--- a/dev/null
+++ b/noncore/net/networksetup/main.cpp
@@ -0,0 +1,13 @@
+#include "mainwindowimp.h"
+#include <qpe/qpeapplication.h>
+
+int main(int argc, char **argv)
+{
+ QPEApplication app(argc, argv);
+ MainWindowImp window;
+ window.showMaximized();
+ return app.exec();
+}
+
+// main.cpp
+
diff --git a/noncore/net/networksetup/mainwindow.ui b/noncore/net/networksetup/mainwindow.ui
new file mode 100644
index 0000000..b8c0675
--- a/dev/null
+++ b/noncore/net/networksetup/mainwindow.ui
@@ -0,0 +1,321 @@
+<!DOCTYPE UI><UI>
+<class>MainWindow</class>
+<widget>
+ <class>QWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>MainWindow</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>222</width>
+ <height>289</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>Network Setup</string>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QTabWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>tabWidget</cstring>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <widget>
+ <class>QWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Widget3</cstring>
+ </property>
+ <attribute>
+ <name>title</name>
+ <string>Interfaces</string>
+ </attribute>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QListView</class>
+ <column>
+ <property>
+ <name>text</name>
+ <string>i</string>
+ </property>
+ <property>
+ <name>clickable</name>
+ <bool>true</bool>
+ </property>
+ <property>
+ <name>resizeable</name>
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property>
+ <name>text</name>
+ <string>t</string>
+ </property>
+ <property>
+ <name>clickable</name>
+ <bool>true</bool>
+ </property>
+ <property>
+ <name>resizeable</name>
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property>
+ <name>text</name>
+ <string>Name</string>
+ </property>
+ <property>
+ <name>clickable</name>
+ <bool>true</bool>
+ </property>
+ <property>
+ <name>resizeable</name>
+ <bool>true</bool>
+ </property>
+ </column>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>serviceList</cstring>
+ </property>
+ <property stdset="1">
+ <name>allColumnsShowFocus</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout2</cstring>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <grid>
+ <property stdset="1">
+ <name>margin</name>
+ <number>5</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget row="1" column="0" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>addServiceButton</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&amp;Add</string>
+ </property>
+ </widget>
+ <widget row="0" column="0" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>informationServiceButton</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&amp;Information</string>
+ </property>
+ </widget>
+ <widget row="0" column="1" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>configureServiceButton</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&amp;Configure</string>
+ </property>
+ </widget>
+ <widget row="1" column="1" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>removeServiceButton</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&amp;Remove</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </vbox>
+ </widget>
+ <widget>
+ <class>QWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>tab</cstring>
+ </property>
+ <attribute>
+ <name>title</name>
+ <string>Profiles</string>
+ </attribute>
+ <grid>
+ <property stdset="1">
+ <name>margin</name>
+ <number>11</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget row="1" column="0" rowspan="1" colspan="2" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel3</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Change Profile To</string>
+ </property>
+ </widget>
+ <widget row="0" column="0" rowspan="1" colspan="2" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel1</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Current Profile</string>
+ </property>
+ </widget>
+ <widget row="0" column="2" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel2</cstring>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>Panel</enum>
+ </property>
+ <property stdset="1">
+ <name>frameShadow</name>
+ <enum>Sunken</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>All</string>
+ </property>
+ </widget>
+ <widget row="1" column="2" >
+ <class>QComboBox</class>
+ <item>
+ <property>
+ <name>text</name>
+ <string>All</string>
+ </property>
+ </item>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>ComboBox10</cstring>
+ </property>
+ </widget>
+ <widget row="2" column="1" rowspan="1" colspan="2" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>removeProfileButton</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&amp;Remove</string>
+ </property>
+ </widget>
+ <widget row="2" column="0" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>newProfileButton</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&amp;New</string>
+ </property>
+ </widget>
+ <spacer row="3" column="2" >
+ <property>
+ <name>name</name>
+ <cstring>Spacer16</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Vertical</enum>
+ </property>
+ <property stdset="1">
+ <name>sizeType</name>
+ <enum>Expanding</enum>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </grid>
+ </widget>
+ </widget>
+ </vbox>
+</widget>
+<customwidgets>
+ <customwidget>
+ <class>QWidget</class>
+ <header location="local">qwidget.h</header>
+ <sizehint>
+ <width>100</width>
+ <height>100</height>
+ </sizehint>
+ <container>0</container>
+ <sizepolicy>
+ <hordata>7</hordata>
+ <verdata>7</verdata>
+ </sizepolicy>
+ <pixmap>image0</pixmap>
+ </customwidget>
+</customwidgets>
+<images>
+ <image>
+ <name>image0</name>
+ <data format="XPM.GZ" length="646">789c6dd2c10ac2300c00d07bbf2234b7229d1be245fc04c5a3201e4615f430059d0711ff5ddb2e6bb236ec90eed134cb5a19d8ef36602af5ecdbfeeac05dda0798d3abebde87e3faa374d3807fa0d633a52d38d8de6f679fe33fc776e196f53cd010188256a3600a292882096246517815ca99884606e18044a3a40d91824820924265a7923a2e8bcd05f33db1173e002913175f2a6be6d3294871a2d95fa00e8a94ee017b69d339d90df1e77c57ea072ede6758</data>
+ </image>
+</images>
+</UI>
diff --git a/noncore/net/networksetup/mainwindowimp.cpp b/noncore/net/networksetup/mainwindowimp.cpp
new file mode 100644
index 0000000..3c13143
--- a/dev/null
+++ b/noncore/net/networksetup/mainwindowimp.cpp
@@ -0,0 +1,308 @@
+#include "mainwindowimp.h"
+#include "addserviceimp.h"
+#include "interfaceinformationimp.h"
+#include "interfacesetupimp.h"
+
+#include <qpushbutton.h>
+#include <qdir.h>
+#include <qtabwidget.h>
+#include <qmainwindow.h>
+#include <qmessagebox.h>
+#include <qlistbox.h>
+#include <qpe/config.h>
+#include <qpe/qlibrary.h>
+#include <qpe/resource.h>
+#include <qlist.h>
+
+#include <qfile.h>
+#include <qtextstream.h>
+#include <qlistview.h>
+#include <qheader.h>
+// For library loading.
+#include <dlfcn.h>
+
+#define TEMP_ALL "/tmp/ifconfig-a"
+#define TEMP_UP "/tmp/ifconfig"
+
+#define NO_SELECT_ERROR_AND_RETURN { \
+ QMessageBox::information(this, "Error","Please select an interface.", "Ok"); \
+ return; \
+}
+
+MainWindowImp::MainWindowImp(QWidget *parent, const char *name) : MainWindow(parent, name, true) {
+ connect(addServiceButton, SIGNAL(clicked()), this, SLOT(addClicked()));
+ connect(removeServiceButton, SIGNAL(clicked()), this, SLOT(removeClicked()));
+ connect(informationServiceButton, SIGNAL(clicked()), this, SLOT(informationClicked()));
+ connect(configureServiceButton, SIGNAL(clicked()), this, SLOT(configureClicked()));
+ // Make sure we have a plugin directory to scan.
+ QString DirStr = QDir::homeDirPath() + "/.networksetup/" ;
+ QDir pluginDir( DirStr );
+ pluginDir.mkdir( DirStr );
+ pluginDir.mkdir( ( DirStr + "plugins/" ) );
+ QString path = DirStr + "plugins";
+ pluginDir.setPath(path);
+ if(!pluginDir.exists()){
+ qDebug(QString("MainWindowImp: ERROR: %1 %2").arg(__FILE__).arg(__LINE__).latin1());
+ return;
+ }
+
+ // Load any saved services.
+ loadModules(path);
+ getInterfaceList();
+ serviceList->header()->hide();
+}
+
+/**
+ * Deconstructor. Unload libraries and save.
+ */
+MainWindowImp::~MainWindowImp(){
+}
+
+void MainWindowImp::loadModules(QString path){
+}
+
+/**
+ * Attempt to load a function and resolve a function.
+ * @param pluginFileName - the name of the file in which to attempt to load
+ * @param resolveString - function pointer to resolve
+ * @return pointer to the function with name resolveString or NULL
+ */
+Module* MainWindowImp::loadPlugin(QString pluginFileName, QString resolveString){
+ //qDebug(pluginFileName.latin1());
+ QLibrary *lib = new QLibrary(pluginFileName);
+ void *functionPointer = lib->resolve(resolveString);
+ if( !functionPointer ){
+ qDebug(QString("MainWindowImp: File: %1 is not a plugin, but though was.").arg(pluginFileName).latin1());
+ delete lib;
+ return NULL;
+ }
+
+ // Try to get an object.
+ Module *object = ((Module* (*)()) functionPointer)();
+ if(object == NULL){
+ qDebug("MainWindowImp: Couldn't create object, but did load library!");
+ delete lib;
+ return NULL;
+ }
+
+ // Store for reference
+ libraries.insert(object, lib);
+ return object;
+}
+
+/*
+QList<QString> MainWindowImp::retrieveUnloadedPluginList(){
+ QString DirStr = QDir::homeDirPath() + "/.networksetup/" ;
+ QString path = DirStr + "plugins";
+ QDir d(path);
+ d.setFilter( QDir::Files | QDir::Hidden );
+
+ QMap<QObject*, QLibrary*>::Iterator libraryIt;
+ QList<QString> rlist;
+ rlist.setAutoDelete(false);
+
+ const QFileInfoList *list = d.entryInfoList();
+ QFileInfoListIterator it( *list );
+ QFileInfo *fi;
+ while ( (fi=it.current()) ) {
+ if(fi->fileName().contains(".so")){
+ for( libraryIt = libraries.begin(); libraryIt != libraries.end(); ++libraryIt )
+ if((path + "/" + fi->fileName()) != (libraryIt.data())->library()){
+ QString *s = new QString(path + "/" + fi->fileName());
+ rlist.append(s);
+ }
+ }
+ ++it;
+ }
+ return rlist;
+}
+*/
+
+/**
+ * The Add button was clicked. Bring up the add dialog and if OK is hit
+ * load the plugin and append it to the list
+ */
+void MainWindowImp::addClicked(){
+ // Now that we have a list of all of the protocals, list them.
+ {
+ QMessageBox::information(this, "No Modules", "Nothing to add.", "Ok");
+ return;
+ }
+ AddServiceImp service(this, "AddService", true);
+ service.showMaximized();
+ service.exec();
+}
+
+/**
+ * Prompt the user to see if they really want to do this.
+ * If they do then remove from the list and unload.
+ */
+void MainWindowImp::removeClicked(){
+ QListViewItem *item = serviceList->currentItem();
+ if(item == NULL) NO_SELECT_ERROR_AND_RETURN
+
+ if(modules.find(interfaceItems[item]) == modules.end()){
+ QMessageBox::information(this, "Can't remove interface.", "Interface is built in.", "Ok");
+ }
+ else{
+ // Try to remove.
+ }
+
+}
+
+/**
+ * See if there is a configuration for the selected protocal.
+ * Prompt with errors.
+ */
+void MainWindowImp::configureClicked(){
+ QListViewItem *item = serviceList->currentItem();
+ if(item == NULL) NO_SELECT_ERROR_AND_RETURN
+
+ if(modules.find(interfaceItems[item]) == modules.end()){
+ InterfaceSetupImp *conf = new InterfaceSetupImp(0, "InterfaceConfiguration", interfaceItems[item]);
+ conf->showMaximized();
+ conf->show();
+ }
+ else{
+ InterfaceSetupImp *conf = new InterfaceSetupImp(this, "InterfaceConfiguration");
+ conf->show();
+ }
+}
+
+/**
+ * Pull up the information about the selected interface
+ * Report an error
+ */
+void MainWindowImp::informationClicked(){
+ QListViewItem *item = serviceList->currentItem();
+ if(item == NULL)NO_SELECT_ERROR_AND_RETURN
+
+ if(modules.find(interfaceItems[item]) == modules.end()){
+ InterfaceInformationImp *i = new InterfaceInformationImp(0, "InterfaceInformationImp", interfaceItems[item]);
+ i->showMaximized();
+ i->show();
+ }
+ else{
+ QTabWidget *t = new QTabWidget(this, "InterfaceInformationTAB");
+ InterfaceInformationImp *i = new InterfaceInformationImp(t, "TCPIPInformation", interfaceItems[item], true);
+ t->insertTab(i, "TCP/IP");
+ t->show();
+ }
+}
+
+/**
+ * Aquire the list of active interfaces from ifconfig
+ * Call ifconfig and ifconfig -a
+ */
+void MainWindowImp::getInterfaceList(){
+ KShellProcess *processAll = new KShellProcess();
+ *processAll << "/sbin/ifconfig" << "-a" << " > " TEMP_ALL;
+ connect(processAll, SIGNAL(processExited(KProcess *)),
+ this, SLOT(jobDone(KProcess *)));
+ threads.insert(processAll, TEMP_ALL);
+ processAll->start(KShellProcess::NotifyOnExit);
+
+ KShellProcess *process = new KShellProcess();
+ *process << "/sbin/ifconfig" << " > " TEMP_UP;
+ connect(process, SIGNAL(processExited(KProcess *)),
+ this, SLOT(jobDone(KProcess *)));
+ threads.insert(process, TEMP_UP);
+ process->start(KShellProcess::NotifyOnExit);
+}
+
+void MainWindowImp::jobDone(KProcess *process){
+ QString fileName = threads[process];
+ threads.remove(process);
+ delete process;
+
+ QFile file(fileName);
+ if (!file.open(IO_ReadOnly)){
+ qDebug(QString("MainWindowImp: Can't open file: %1").arg(fileName).latin1());
+ return;
+ }
+
+ QTextStream stream( &file );
+ QString line;
+ while ( !stream.eof() ) {
+ line = stream.readLine();
+ int space = line.find(" ");
+ if(space > 1){
+ // We have found an interface
+ QString interfaceName = line.mid(0, space);
+ Interface *i;
+ // See if we already have it
+ if(interfaceNames.find(interfaceName) == interfaceNames.end()){
+ if(fileName == TEMP_ALL)
+ i = new Interface(interfaceName, false);
+ else
+ i = new Interface(interfaceName, true);
+ }
+ else{
+ i = interfaceNames[interfaceName];
+ if(fileName != TEMP_ALL)
+ i->setStatus(true);
+ }
+
+ i->setAttached(true);
+ i->setInterfaceName(interfaceName);
+
+ QString hardName = "Ethernet";
+ int hardwareName = line.find("Link encap:");
+ int macAddress = line.find("HWaddr");
+ if(macAddress == -1)
+ macAddress = line.length();
+ if(hardwareName != -1)
+ i->setHardwareName(line.mid(hardwareName+11, macAddress-(hardwareName+11)));
+ // We have found an interface
+ //qDebug(QString("MainWindowImp: Found Interface: %1").arg(line).latin1());
+ interfaceNames.insert(i->getInterfaceName(), i);
+ updateInterface(i);
+ }
+ }
+ file.close();
+ QFile::remove(fileName);
+}
+
+void MainWindowImp::updateInterface(Interface *i){
+ QListViewItem *item = NULL;
+
+ // See if we already have it
+ if(items.find(i) == items.end()){
+ item = new QListViewItem(serviceList, "", "", "");
+ // See if you can't find a module owner for this interface
+ //EmployeeMap::Iterator it;
+ //for( it = map.begin(); it != map.end(); ++it )
+ // printf( "%s, %s earns %d\n", it.key().latin1(), it.data().name().latin1(), it.data().salary() );
+
+ items.insert(i, item);
+ interfaceItems.insert(item, i);
+ }
+ else
+ item = items[i];
+
+ QString statusImage = "down";
+ if(i->getStatus())
+ statusImage = "up";
+ QPixmap status = (Resource::loadPixmap(statusImage));
+ item->setPixmap(0, status);
+
+ QString typeName = "lan";
+ if(i->getHardwareName().contains("Local Loopback"))
+ typeName = "lo";
+ QPixmap type = (Resource::loadPixmap(typeName));
+ item->setPixmap(1, type);
+
+ item->setText(2, i->getHardwareName());
+
+}
+
+void MainWindowImp::addProfile(){
+
+}
+
+void MainWindowImp::removeProfile(){
+
+}
+
+// mainwindowimp.cpp
+
diff --git a/noncore/net/networksetup/mainwindowimp.h b/noncore/net/networksetup/mainwindowimp.h
new file mode 100644
index 0000000..95ec2a1
--- a/dev/null
+++ b/noncore/net/networksetup/mainwindowimp.h
@@ -0,0 +1,53 @@
+#ifndef MAINWINOWIMP_H
+#define MAINWINOWIMP_H
+
+#include "mainwindow.h"
+#include "module.h"
+#include "interface.h"
+#include "kprocess.h"
+#include <qmap.h>
+
+class QLibrary;
+
+class MainWindowImp : public MainWindow {
+ Q_OBJECT
+
+public:
+ MainWindowImp(QWidget *parent=0, const char *name=0);
+ ~MainWindowImp();
+
+private slots:
+ void addClicked();
+ void removeClicked();
+ void configureClicked();
+ void informationClicked();
+
+ void jobDone(KProcess *process);
+ void getInterfaceList();
+
+ void addProfile();
+ void removeProfile();
+
+ void updateInterface(Interface *i);
+
+private:
+ void loadModules(QString path);
+
+ Module* loadPlugin(QString pluginFileName,
+ QString resolveString = "create_plugin");
+
+ // For our local list of names
+ QMap<QString, Interface*> interfaceNames;
+
+ QMap<Module*, QLibrary*> libraries;
+ QMap<Interface*, Module*> modules;
+ QMap<Interface*, QListViewItem*> items;
+ QMap<QListViewItem*, Interface*> interfaceItems;
+
+ QMap<KProcess*, QString> threads;
+};
+
+#endif
+
+// mainwindowimp.h
+
diff --git a/noncore/net/networksetup/module.h b/noncore/net/networksetup/module.h
new file mode 100644
index 0000000..f146d8c
--- a/dev/null
+++ b/noncore/net/networksetup/module.h
@@ -0,0 +1,33 @@
+#ifndef MODULE_H
+#define MODULE_H
+
+#include <qobject.h>
+#include <qlist.h>
+#include <qmap.h>
+#include "interface.h"
+
+class QWidget;
+
+class Module : QObject{
+
+signals:
+ void updateInterface(Interface *i);
+
+public:
+ Module(){};
+
+ virtual bool isOwner(Interface *){ return false; };
+ virtual QWidget *configure(){ return NULL; } ;
+ virtual QWidget *information(){ return NULL; };
+ virtual QList<Interface> getInterfaces() = 0;
+ virtual QMap<QString, QString> possibleNewInterfaces() = 0;
+ virtual Interface *addNewInterface(QString name) = 0;
+ virtual bool remove(Interface* i) = 0;
+
+
+};
+
+#endif
+
+// module.h
+
diff --git a/noncore/net/networksetup/networksetup.pro b/noncore/net/networksetup/networksetup.pro
new file mode 100644
index 0000000..7d9918b
--- a/dev/null
+++ b/noncore/net/networksetup/networksetup.pro
@@ -0,0 +1,10 @@
+TEMPLATE = app
+CONFIG = qt warn_on debug
+#CONFIG = qt warn_on release
+HEADERS = mainwindowimp.h addserviceimp.h interface.h interfaceinformationimp.h interfacesetupimp.h interfaces.h defaultmodule.h kprocctrl.h module.h kprocess.h
+SOURCES = main.cpp mainwindowimp.cpp addserviceimp.cpp interface.cpp interfaceinformationimp.cpp interfacesetupimp.cpp kprocctrl.cpp kprocess.cpp interfaces.cpp
+INCLUDEPATH += $(QPEDIR)/include
+DEPENDPATH += $(QPEDIR)/include
+LIBS += -lqpe
+INTERFACES = mainwindow.ui addservice.ui interfaceinformation.ui interfaceadvanced.ui interfacesetup.ui
+TARGET = networksetup
diff --git a/noncore/net/networksetup/systemadvanced.ui b/noncore/net/networksetup/systemadvanced.ui
new file mode 100644
index 0000000..6ea192c
--- a/dev/null
+++ b/noncore/net/networksetup/systemadvanced.ui
@@ -0,0 +1,443 @@
+<!DOCTYPE UI><UI>
+<class>SystemNetworking</class>
+<widget>
+ <class>QWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>SystemNetworking</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>222</width>
+ <height>289</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>System Networking</string>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QTabWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>tabWidget</cstring>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <widget>
+ <class>QWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>tab</cstring>
+ </property>
+ <attribute>
+ <name>title</name>
+ <string>DNS</string>
+ </attribute>
+ <grid>
+ <property stdset="1">
+ <name>margin</name>
+ <number>11</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget row="0" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel6</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Hostname</string>
+ </property>
+ </widget>
+ <widget row="1" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel5</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>DNS</string>
+ </property>
+ <property stdset="1">
+ <name>alignment</name>
+ <set>AlignTop|AlignLeft</set>
+ </property>
+ <property>
+ <name>vAlign</name>
+ </property>
+ </widget>
+ <widget row="1" column="1" >
+ <class>QListBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>ListBox5</cstring>
+ </property>
+ </widget>
+ <widget row="0" column="1" >
+ <class>QLineEdit</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>LineEdit7</cstring>
+ </property>
+ </widget>
+ <widget row="3" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel7</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Hosts</string>
+ </property>
+ </widget>
+ <widget row="3" column="1" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel9</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>List here....</string>
+ </property>
+ </widget>
+ <widget row="2" column="0" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PushButton15</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&amp;Add</string>
+ </property>
+ </widget>
+ <widget row="2" column="1" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PushButton16</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&amp;Delete</string>
+ </property>
+ </widget>
+ <spacer row="4" column="1" >
+ <property>
+ <name>name</name>
+ <cstring>Spacer14</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Vertical</enum>
+ </property>
+ <property stdset="1">
+ <name>sizeType</name>
+ <enum>Expanding</enum>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </grid>
+ </widget>
+ <widget>
+ <class>QWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>tab</cstring>
+ </property>
+ <attribute>
+ <name>title</name>
+ <string>Routing</string>
+ </attribute>
+ <grid>
+ <property stdset="1">
+ <name>margin</name>
+ <number>11</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget row="0" column="0" rowspan="1" colspan="2" >
+ <class>QListView</class>
+ <column>
+ <property>
+ <name>text</name>
+ <string>Destination</string>
+ </property>
+ <property>
+ <name>clickable</name>
+ <bool>true</bool>
+ </property>
+ <property>
+ <name>resizeable</name>
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property>
+ <name>text</name>
+ <string>Gateway</string>
+ </property>
+ <property>
+ <name>clickable</name>
+ <bool>true</bool>
+ </property>
+ <property>
+ <name>resizeable</name>
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property>
+ <name>text</name>
+ <string>Genmask</string>
+ </property>
+ <property>
+ <name>clickable</name>
+ <bool>true</bool>
+ </property>
+ <property>
+ <name>resizeable</name>
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property>
+ <name>text</name>
+ <string>Flags</string>
+ </property>
+ <property>
+ <name>clickable</name>
+ <bool>true</bool>
+ </property>
+ <property>
+ <name>resizeable</name>
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property>
+ <name>text</name>
+ <string>Metric</string>
+ </property>
+ <property>
+ <name>clickable</name>
+ <bool>true</bool>
+ </property>
+ <property>
+ <name>resizeable</name>
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property>
+ <name>text</name>
+ <string>Ref</string>
+ </property>
+ <property>
+ <name>clickable</name>
+ <bool>true</bool>
+ </property>
+ <property>
+ <name>resizeable</name>
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property>
+ <name>text</name>
+ <string>Use</string>
+ </property>
+ <property>
+ <name>clickable</name>
+ <bool>true</bool>
+ </property>
+ <property>
+ <name>resizeable</name>
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property>
+ <name>text</name>
+ <string>Iface</string>
+ </property>
+ <property>
+ <name>clickable</name>
+ <bool>true</bool>
+ </property>
+ <property>
+ <name>resizeable</name>
+ <bool>true</bool>
+ </property>
+ </column>
+ <item>
+ <property>
+ <name>text</name>
+ <string>192.168.1.0</string>
+ </property>
+ <property>
+ <name>text</name>
+ <string>*</string>
+ </property>
+ <property>
+ <name>text</name>
+ <string>255.255.255.0</string>
+ </property>
+ <property>
+ <name>text</name>
+ <string>U</string>
+ </property>
+ <property>
+ <name>text</name>
+ <string>0</string>
+ </property>
+ <property>
+ <name>text</name>
+ <string>0</string>
+ </property>
+ <property>
+ <name>text</name>
+ <string>0</string>
+ </property>
+ <property>
+ <name>text</name>
+ <string>eth0</string>
+ </property>
+ <property>
+ <name>pixmap</name>
+ <pixmap></pixmap>
+ </property>
+ <property>
+ <name>pixmap</name>
+ <pixmap></pixmap>
+ </property>
+ <property>
+ <name>pixmap</name>
+ <pixmap></pixmap>
+ </property>
+ <property>
+ <name>pixmap</name>
+ <pixmap></pixmap>
+ </property>
+ <property>
+ <name>pixmap</name>
+ <pixmap></pixmap>
+ </property>
+ <property>
+ <name>pixmap</name>
+ <pixmap></pixmap>
+ </property>
+ <property>
+ <name>pixmap</name>
+ <pixmap></pixmap>
+ </property>
+ <property>
+ <name>pixmap</name>
+ <pixmap></pixmap>
+ </property>
+ </item>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>ListView4</cstring>
+ </property>
+ </widget>
+ <widget row="1" column="0" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PushButton17</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&amp;Add</string>
+ </property>
+ </widget>
+ <widget row="1" column="1" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PushButton18</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Remove</string>
+ </property>
+ </widget>
+ <spacer row="2" column="1" >
+ <property>
+ <name>name</name>
+ <cstring>Spacer15</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Vertical</enum>
+ </property>
+ <property stdset="1">
+ <name>sizeType</name>
+ <enum>Expanding</enum>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </grid>
+ </widget>
+ </widget>
+ </vbox>
+</widget>
+<customwidgets>
+ <customwidget>
+ <class>QWidget</class>
+ <header location="local">qwidget.h</header>
+ <sizehint>
+ <width>100</width>
+ <height>100</height>
+ </sizehint>
+ <container>0</container>
+ <sizepolicy>
+ <hordata>7</hordata>
+ <verdata>7</verdata>
+ </sizepolicy>
+ <pixmap>image0</pixmap>
+ </customwidget>
+</customwidgets>
+<images>
+ <image>
+ <name>image0</name>
+ <data format="XPM.GZ" length="646">789c6dd2c10ac2300c00d07bbf2234b7229d1be245fc04c5a3201e4615f430059d0711ff5ddb2e6bb236ec90eed134cb5a19d8ef36602af5ecdbfeeac05dda0798d3abebde87e3faa374d3807fa0d633a52d38d8de6f679fe33fc776e196f53cd010188256a3600a292882096246517815ca99884606e18044a3a40d91824820924265a7923a2e8bcd05f33db1173e002913175f2a6be6d3294871a2d95fa00e8a94ee017b69d339d90df1e77c57ea072ede6758</data>
+ </image>
+</images>
+</UI>
diff --git a/noncore/settings/networksettings/TODO b/noncore/settings/networksettings/TODO
new file mode 100644
index 0000000..9a1657a
--- a/dev/null
+++ b/noncore/settings/networksettings/TODO
@@ -0,0 +1 @@
+Fix DHCP obtained and expoired info
diff --git a/noncore/settings/networksettings/addservice.ui b/noncore/settings/networksettings/addservice.ui
new file mode 100644
index 0000000..929f4fb
--- a/dev/null
+++ b/noncore/settings/networksettings/addservice.ui
@@ -0,0 +1,154 @@
+<!DOCTYPE UI><UI>
+<class>AddService</class>
+<widget>
+ <class>QDialog</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>AddService</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>245</width>
+ <height>268</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>Add Network Service</string>
+ </property>
+ <grid>
+ <property stdset="1">
+ <name>margin</name>
+ <number>11</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget row="3" column="1" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cancelButton</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Cancel</string>
+ </property>
+ </widget>
+ <widget row="3" column="0" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>addButton</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Add</string>
+ </property>
+ </widget>
+ <widget row="0" column="0" rowspan="1" colspan="2" >
+ <class>QListView</class>
+ <column>
+ <property>
+ <name>text</name>
+ <string>Services</string>
+ </property>
+ <property>
+ <name>clickable</name>
+ <bool>true</bool>
+ </property>
+ <property>
+ <name>resizeable</name>
+ <bool>true</bool>
+ </property>
+ </column>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>registeredServicesList</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>3</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>minimumSize</name>
+ <size>
+ <width>0</width>
+ <height>75</height>
+ </size>
+ </property>
+ </widget>
+ <spacer row="2" column="1" >
+ <property>
+ <name>name</name>
+ <cstring>Spacer12</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Vertical</enum>
+ </property>
+ <property stdset="1">
+ <name>sizeType</name>
+ <enum>Expanding</enum>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget row="1" column="0" rowspan="1" colspan="2" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>help</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>4</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>LAN - TCP/IP
+For Local-area network connections through PC_CARD network interfdace cards.</string>
+ </property>
+ <property stdset="1">
+ <name>alignment</name>
+ <set>WordBreak|AlignTop|AlignLeft</set>
+ </property>
+ <property>
+ <name>vAlign</name>
+ </property>
+ <property>
+ <name>wordwrap</name>
+ </property>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>cancelButton</sender>
+ <signal>clicked()</signal>
+ <receiver>AddService</receiver>
+ <slot>reject()</slot>
+ </connection>
+ <connection>
+ <sender>addButton</sender>
+ <signal>clicked()</signal>
+ <receiver>AddService</receiver>
+ <slot>accept()</slot>
+ </connection>
+</connections>
+</UI>
diff --git a/noncore/settings/networksettings/addserviceimp.cpp b/noncore/settings/networksettings/addserviceimp.cpp
new file mode 100644
index 0000000..ac79d06
--- a/dev/null
+++ b/noncore/settings/networksettings/addserviceimp.cpp
@@ -0,0 +1,26 @@
+#include "addserviceimp.h"
+#include <qpe/qlibrary.h>
+#include <qlistview.h>
+#include <qlist.h>
+
+void AddServiceImp::addServices(QList<QString> list){
+ list.setAutoDelete(true);
+
+ for(uint i = 0; i < list.count(); i++){
+ QString pluginFileName = "";
+ QLibrary *lib = new QLibrary(pluginFileName);
+ void *functionPointer = lib->resolve("info");
+ if( !functionPointer ){
+ qDebug(QString("AddServiceImp: File: %1 is not a plugin, but though was.").arg(pluginFileName).latin1());
+ delete lib;
+ break;
+ }
+
+ // Try to get an info.
+ QString info = ((QString (*)()) functionPointer)();
+ QListViewItem *newItem = new QListViewItem(registeredServicesList, info);
+ }
+}
+
+
+// addserviceimp.cpp
diff --git a/noncore/settings/networksettings/addserviceimp.h b/noncore/settings/networksettings/addserviceimp.h
new file mode 100644
index 0000000..7cacb97
--- a/dev/null
+++ b/noncore/settings/networksettings/addserviceimp.h
@@ -0,0 +1,26 @@
+#ifndef ADDSERVICEIMP_H
+#define ADDSERVICEIMP_H
+
+#include "addservice.h"
+#include <qmap.h>
+#include <qlist.h>
+
+class QListViewItem;
+
+class AddServiceImp : public AddService {
+
+Q_OBJECT
+
+public:
+ AddServiceImp(QWidget *parent=0, const char *name=0, WFlags f=0):AddService(parent, name, f){};
+ void addServices(QList<QString> list);
+
+private:
+ QMap<QListViewItem*, QString> pluginInfo;
+
+};
+
+#endif
+
+// addserviceimp.h
+
diff --git a/noncore/settings/networksettings/defaultmodule.h b/noncore/settings/networksettings/defaultmodule.h
new file mode 100644
index 0000000..c7791d5
--- a/dev/null
+++ b/noncore/settings/networksettings/defaultmodule.h
@@ -0,0 +1,26 @@
+#ifndef MODULE_H
+#define MODULE_H
+
+#include "module.h"
+
+class QWidget;
+
+class DefaultModule : Module{
+
+public:
+ DefaultModule(){};
+
+ virtual bool isOwner(Interface *i);
+ virtual QWidget *configure();
+ virtual QWidget *information()};
+ virtual QList<Interface> getInterfaces();
+ virtual QMap<QString, QString> possibleNewInterfaces();
+ virtual Interface *addNewInterface(QString name);
+ virtual bool remove(Interface* i);
+
+};
+
+#endif
+
+// module.h
+
diff --git a/noncore/settings/networksettings/interface.cpp b/noncore/settings/networksettings/interface.cpp
new file mode 100644
index 0000000..b9b09ad
--- a/dev/null
+++ b/noncore/settings/networksettings/interface.cpp
@@ -0,0 +1,236 @@
+#include "interface.h"
+#include <qdatetime.h>
+#include <qfile.h>
+#include <qfileinfo.h>
+#include <qtextstream.h>
+
+#define IFCONFIG "/sbin/ifconfig"
+#define HDCP_INFO_DIR "/etc/dhcpc"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+Interface::Interface(QString name, bool newSatus): status(newSatus), attached(false), interfaceName(name), hardareName("Unknown"), moduleOwner("Default"), macAddress(""), ip("0.0.0.0"), broadcast(""), subnetMask("0.0.0.0"), dhcp(false){
+ refresh();
+}
+
+/**
+ * Try to start the interface.
+ * @return bool true if successfull.
+ */
+bool Interface::start(){
+ // check to see if we are already running.
+ if(status)
+ return false;
+
+ int ret = system(QString("%1 %2 up").arg(IFCONFIG).arg(interfaceName).latin1());
+ if(ret != 0)
+ return false;
+
+ status = true;
+ refresh();
+ return true;
+}
+
+/**
+ * Try to stop the interface.
+ * @return bool true if successfull.
+ */
+bool Interface::stop(){
+ // check to see if we are already stopped.
+ if(status == false)
+ return false;
+
+ int ret = system(QString("%1 %2 down").arg(IFCONFIG).arg(interfaceName).latin1());
+ if(ret != 0)
+ return false;
+
+ status = true;
+ refresh();
+ return true;
+}
+/**
+ * Try to restart the interface.
+ * @return bool true if successfull.
+ */
+bool Interface::restart(){
+ return (stop() && start());
+}
+
+/**
+ * Try to refresh the information about the interface.
+ * First call ifconfig, then check the dhcp-info file
+ * @return bool true if successfull.
+ */
+bool Interface::refresh(){
+ // See if we are up.
+ if(status == false){
+ macAddress = "";
+ ip = "0.0.0.0";
+ subnetMask = "0.0.0.0";
+ broadcast = "";
+ dhcp = false;
+ dhcpServerIp = "";
+ leaseObtained = "";
+ leaseExpires = "";
+ return true;
+ }
+
+ QString fileName = QString("/tmp/%1_ifconfig_info").arg(interfaceName);
+ int ret = system(QString("%1 %2 > %3").arg(IFCONFIG).arg(interfaceName).arg(fileName).latin1());
+ if(ret != 0){
+ qDebug(QString("Interface: Ifconfig return value: %1, is not 0").arg(ret).latin1());
+ return false;
+ }
+
+ QFile file(fileName);
+ if (!file.open(IO_ReadOnly)){
+ qDebug(QString("Interface: Can't open file: %1").arg(fileName).latin1());
+ return false;
+ }
+
+ // Set to the defaults
+ macAddress = "";
+ ip = "0.0.0.0";
+ subnetMask = "0.0.0.0";
+ broadcast = "";
+
+ QTextStream stream( &file );
+ QString line;
+ while ( !stream.eof() ) {
+ line = stream.readLine();
+ if(line.contains("HWaddr")){
+ int mac = line.find("HWaddr");
+ macAddress = line.mid(mac+7, line.length());
+ }
+ if(line.contains("inet addr")){
+ int ipl = line.find("inet addr");
+ int space = line.find(" ", ipl+10);
+ ip = line.mid(ipl+10, space-ipl-10);
+ }
+ if(line.contains("Mask")){
+ int mask = line.find("Mask");
+ subnetMask = line.mid(mask+5, line.length());
+ }
+ if(line.contains("Bcast")){
+ int mask = line.find("Bcast");
+ int space = line.find(" ", mask+6);
+ broadcast = line.mid(mask+6, space-mask-6);
+ }
+ }
+ file.close();
+ QFile::remove(fileName);
+
+ // DHCP TESTING
+ // reset DHCP info
+ dhcpServerIp = "";
+ leaseObtained = "";
+ leaseExpires = "";
+ dhcp = false;
+
+ // See if we have
+ QString dhcpFile(QString(HDCP_INFO_DIR "/dhcpcd-%1.info").arg(interfaceName));
+ // If there is no DHCP information then exit now with no errors.
+ if(!QFile::exists(dhcpFile)){
+ return true;
+ }
+
+ file.setName(dhcpFile);
+ if (!file.open(IO_ReadOnly)){
+ qDebug(QString("Interface: Can't open file: %1").arg(dhcpFile).latin1());
+ return false;
+ }
+
+ // leaseTime and renewalTime and used if pid and deamon exe can be accessed.
+ int leaseTime = 0;
+ int renewalTime = 0;
+
+ stream.setDevice( &file );
+ while ( !stream.eof() ) {
+ line = stream.readLine();
+ if(line.contains("DHCPSID="))
+ dhcpServerIp = line.mid(8, line.length());
+ if(line.contains("LEASETIME="))
+ leaseTime = line.mid(10, line.length()).toInt();
+ if(line.contains("RENEWALTIME="))
+ renewalTime = line.mid(12, line.length()).toInt();
+ }
+ file.close();
+ //qDebug(QString("Interface: leaseTime: %1").arg(leaseTime).latin1());
+ //qDebug(QString("Interface: renewalTime: %1").arg(renewalTime).latin1());
+
+ // Get the pid of the deamond
+ dhcpFile = (QString(HDCP_INFO_DIR "/dhcpcd-%1.pid").arg(interfaceName));
+ file.setName(dhcpFile);
+ if (!file.open(IO_ReadOnly)){
+ qDebug(QString("Interface: Can't open file: %1").arg(dhcpFile).latin1());
+ return false;
+ }
+
+ int pid = -1;
+ stream.setDevice( &file );
+ while ( !stream.eof() ) {
+ line = stream.readLine();
+ pid = line.toInt();
+ }
+ file.close();
+
+ if( pid == -1){
+ qDebug("Interface: Could not get pid of dhcpc deamon.");
+ return false;
+ }
+
+ // Get the start running time of the deamon
+ fileName = (QString("/proc/%1/stat").arg(pid));
+ file.setName(fileName);
+ stream.setDevice( &file );
+ if (!file.open(IO_ReadOnly)){
+ qDebug(QString("Interface: Can't open file: %1").arg(fileName).latin1());
+ return false;
+ }
+ while ( !stream.eof() ) {
+ line = stream.readLine();
+ }
+ file.close();
+ long time = 0;
+ // Grab the start time
+ // pid com state ppid pgrp session tty_nr tpgid flags
+ int r = sscanf(line.latin1(), "%*d %*s %*c %*d %*d %*d %*d %*d %*u "
+ // minflt cminflt majflt cmajflt utime stime cutime cstime priority
+ "%*u %*u %*u %*u %*u %*u %*d %*d %*d "
+ // nice 0 itrealvalue starttime
+ "%*d %*d %*d %lu", (long*) &time);
+ time = time/100;
+
+ QDateTime datetime(QDateTime::currentDateTime());
+
+ // Get the uptime of the computer.
+ QFile f("/proc/uptime");
+ if ( f.open(IO_ReadOnly) ) { // file opened successfully
+ QTextStream t( &f ); // use a text stream
+ int sec = 0;
+ t >> sec;
+ datetime = datetime.addSecs((-1*sec));
+ f.close();
+ }
+ else{
+ qDebug("Interface: Can't open /proc/uptime to retrive uptime.");
+ return false;
+ }
+
+ datetime = datetime.addSecs(time);
+ //qDebug(QString("Interface: %1 %2").arg(datetime.toString()).arg(pid).latin1());
+
+ // Calculate the start and renew times
+ leaseObtained = datetime.toString();
+
+ // Calculate the start and renew times
+ datetime = datetime.addSecs(leaseTime);
+ leaseExpires = datetime.toString();
+
+ dhcp = true;
+ return true;
+}
+
+// interface.cpp
+
diff --git a/noncore/settings/networksettings/interface.h b/noncore/settings/networksettings/interface.h
new file mode 100644
index 0000000..1ad71eb
--- a/dev/null
+++ b/noncore/settings/networksettings/interface.h
@@ -0,0 +1,65 @@
+#ifndef INTERFACE_H
+#define INTERFACE_H
+
+#include <qstring.h>
+
+class Interface {
+
+public:
+ Interface(QString name = "unknown", bool status = false);
+ virtual ~Interface(){};
+
+ virtual bool getStatus(){ return status; };
+ virtual void setStatus(bool newSatus){ status = newSatus; refresh(); };
+
+ virtual bool isAttached(){ return attached; };
+ virtual void setAttached(bool isAttached=false){ attached = isAttached; };
+
+ virtual QString getInterfaceName(){ return interfaceName; };
+ virtual void setInterfaceName(QString name="unknown"){ interfaceName = name; };
+
+ virtual QString getHardwareName(){ return hardareName; };
+ virtual void setHardwareName(QString name="Unknown"){ hardareName = name; };
+
+ virtual QString getModuleOwner(){ return moduleOwner; };
+ virtual void setModuleOwner(QString owner="Default"){ moduleOwner = owner; };
+
+ // inet information.
+ QString getMacAddress(){ return macAddress; };
+ QString getIp(){ return ip; };
+ QString getSubnetMask(){ return subnetMask; };
+ QString getBroadcast(){ return broadcast; };
+ bool isDhcp(){ return dhcp; };
+ QString getDhcpServerIp(){ return dhcpServerIp; };
+ QString getLeaseObtained(){ return leaseObtained; };
+ QString getLeaseExpires(){ return leaseExpires; };
+
+ bool refresh();
+ bool start();
+ bool stop();
+ bool restart();
+
+private:
+ // Interface information
+ bool status;
+ bool attached;
+ QString interfaceName;
+ QString hardareName;
+ QString moduleOwner;
+
+ // Network information
+ QString macAddress;
+ QString ip;
+ QString broadcast;
+ QString subnetMask;
+ bool dhcp;
+ QString dhcpServerIp;
+ QString leaseObtained;
+ QString leaseExpires;
+
+};
+
+#endif
+
+// interface.h
+
diff --git a/noncore/settings/networksettings/interfaceadvanced.ui b/noncore/settings/networksettings/interfaceadvanced.ui
new file mode 100644
index 0000000..8ef0b29
--- a/dev/null
+++ b/noncore/settings/networksettings/interfaceadvanced.ui
@@ -0,0 +1,323 @@
+<!DOCTYPE UI><UI>
+<class>InterfaceAdvanced</class>
+<widget>
+ <class>QWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>InterfaceAdvanced</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>197</width>
+ <height>253</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>Advanced Interface Information</string>
+ </property>
+ <grid>
+ <property stdset="1">
+ <name>margin</name>
+ <number>11</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget row="1" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel1</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>MAC Address</string>
+ </property>
+ </widget>
+ <widget row="0" column="1" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>interfaceName</cstring>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>Panel</enum>
+ </property>
+ <property stdset="1">
+ <name>frameShadow</name>
+ <enum>Sunken</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>eth0</string>
+ </property>
+ </widget>
+ <widget row="2" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel3</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>IP Address</string>
+ </property>
+ </widget>
+ <widget row="1" column="1" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>macAddressLabel</cstring>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>Panel</enum>
+ </property>
+ <property stdset="1">
+ <name>frameShadow</name>
+ <enum>Sunken</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>00:00:00:00:00:00</string>
+ </property>
+ </widget>
+ <widget row="0" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel7</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Interface</string>
+ </property>
+ </widget>
+ <widget row="8" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel9</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Lease Expires</string>
+ </property>
+ </widget>
+ <widget row="8" column="1" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>leaseExpiresLabel</cstring>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>Panel</enum>
+ </property>
+ <property stdset="1">
+ <name>frameShadow</name>
+ <enum>Sunken</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string></string>
+ </property>
+ </widget>
+ <widget row="7" column="1" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>leaseObtainedLabel</cstring>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>Panel</enum>
+ </property>
+ <property stdset="1">
+ <name>frameShadow</name>
+ <enum>Sunken</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string></string>
+ </property>
+ </widget>
+ <widget row="7" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel8</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Lease Obtained</string>
+ </property>
+ </widget>
+ <widget row="6" column="1" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>dhcpServerLabel</cstring>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>Panel</enum>
+ </property>
+ <property stdset="1">
+ <name>frameShadow</name>
+ <enum>Sunken</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>255.255.255.255</string>
+ </property>
+ </widget>
+ <widget row="6" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel6</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>DHCP Server</string>
+ </property>
+ </widget>
+ <widget row="4" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel4</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Subnet Mask</string>
+ </property>
+ </widget>
+ <widget row="2" column="1" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>ipAddressLabel</cstring>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>Panel</enum>
+ </property>
+ <property stdset="1">
+ <name>frameShadow</name>
+ <enum>Sunken</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>0.0.0.0</string>
+ </property>
+ </widget>
+ <widget row="4" column="1" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>subnetMaskLabel</cstring>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>Panel</enum>
+ </property>
+ <property stdset="1">
+ <name>frameShadow</name>
+ <enum>Sunken</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>0.0.0.0</string>
+ </property>
+ </widget>
+ <spacer row="9" column="1" >
+ <property>
+ <name>name</name>
+ <cstring>Spacer2</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Vertical</enum>
+ </property>
+ <property stdset="1">
+ <name>sizeType</name>
+ <enum>Expanding</enum>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget row="3" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel2</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Broadcast</string>
+ </property>
+ </widget>
+ <widget row="3" column="1" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>broadcastLabel</cstring>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>Panel</enum>
+ </property>
+ <property stdset="1">
+ <name>frameShadow</name>
+ <enum>Sunken</enum>
+ </property>
+ </widget>
+ <widget row="5" column="0" rowspan="1" colspan="2" >
+ <class>Line</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Line2</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ </grid>
+</widget>
+<customwidgets>
+ <customwidget>
+ <class>QWidget</class>
+ <header location="local">qwidget.h</header>
+ <sizehint>
+ <width>100</width>
+ <height>100</height>
+ </sizehint>
+ <container>0</container>
+ <sizepolicy>
+ <hordata>7</hordata>
+ <verdata>7</verdata>
+ </sizepolicy>
+ <pixmap>image0</pixmap>
+ </customwidget>
+</customwidgets>
+<images>
+ <image>
+ <name>image0</name>
+ <data format="XPM.GZ" length="45">789cd3d7528808f055d0d2e72a2e492cc94c5648ce482c52d04a29cdcdad8c8eb5ade6523250004143a55a6b2e0026630c4f</data>
+ </image>
+</images>
+</UI>
diff --git a/noncore/settings/networksettings/interfaceedit.cpp b/noncore/settings/networksettings/interfaceedit.cpp
new file mode 100644
index 0000000..25599ef
--- a/dev/null
+++ b/noncore/settings/networksettings/interfaceedit.cpp
@@ -0,0 +1,141 @@
+/****************************************************************************
+** Form implementation generated from reading ui file 'interfaceedit.ui'
+**
+** Created: Mon Sep 23 12:18:55 2002
+** by: The User Interface Compiler (uic)
+**
+** WARNING! All changes made in this file will be lost!
+****************************************************************************/
+#include "interfaceedit.h"
+
+#include <qcheckbox.h>
+#include <qcombobox.h>
+#include <qframe.h>
+#include <qgroupbox.h>
+#include <qlabel.h>
+#include <qlineedit.h>
+#include <qpushbutton.h>
+#include <qspinbox.h>
+#include "qwidget.h"
+#include <qlayout.h>
+#include <qvariant.h>
+#include <qtooltip.h>
+#include <qwhatsthis.h>
+
+/*
+ * Constructs a InterfaceConfiguration which is a child of 'parent', with the
+ * name 'name' and widget flags set to 'f'
+ */
+InterfaceConfiguration::InterfaceConfiguration( QWidget* parent, const char* name, WFlags fl )
+ : QWidget( parent, name, fl )
+{
+ if ( !name )
+ setName( "InterfaceConfiguration" );
+ resize( 177, 306 );
+ setCaption( tr( "Interface Configuration" ) );
+ InterfaceConfigurationLayout = new QGridLayout( this );
+ InterfaceConfigurationLayout->setSpacing( 6 );
+ InterfaceConfigurationLayout->setMargin( 11 );
+
+ profile = new QComboBox( FALSE, this, "profile" );
+ profile->insertItem( tr( "All" ) );
+
+ InterfaceConfigurationLayout->addWidget( profile, 2, 1 );
+
+ TextLabel1 = new QLabel( this, "TextLabel1" );
+ TextLabel1->setText( tr( "Profile:" ) );
+
+ InterfaceConfigurationLayout->addWidget( TextLabel1, 2, 0 );
+
+ Line1 = new QFrame( this, "Line1" );
+ Line1->setFrameStyle( QFrame::HLine | QFrame::Sunken );
+
+ InterfaceConfigurationLayout->addMultiCellWidget( Line1, 1, 1, 0, 1 );
+
+ CheckBox3 = new QCheckBox( this, "CheckBox3" );
+ CheckBox3->setText( tr( "Automaticly bring up" ) );
+
+ InterfaceConfigurationLayout->addMultiCellWidget( CheckBox3, 0, 0, 0, 1 );
+
+ dhcpCheckBox = new QCheckBox( this, "dhcpCheckBox" );
+ dhcpCheckBox->setText( tr( "DHCP" ) );
+
+ InterfaceConfigurationLayout->addMultiCellWidget( dhcpCheckBox, 3, 3, 0, 1 );
+
+ TextLabel3_3_2 = new QLabel( this, "TextLabel3_3_2" );
+ TextLabel3_3_2->setText( tr( "Lease Hours" ) );
+
+ InterfaceConfigurationLayout->addWidget( TextLabel3_3_2, 4, 0 );
+
+ SpinBox1_2 = new QSpinBox( this, "SpinBox1_2" );
+ SpinBox1_2->setMaxValue( 336 );
+ SpinBox1_2->setMinValue( 1 );
+ SpinBox1_2->setValue( 24 );
+
+ InterfaceConfigurationLayout->addWidget( SpinBox1_2, 4, 1 );
+ QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding );
+ InterfaceConfigurationLayout->addItem( spacer, 11, 1 );
+
+ TextLabel4 = new QLabel( this, "TextLabel4" );
+ TextLabel4->setText( tr( "IP Address" ) );
+
+ InterfaceConfigurationLayout->addWidget( TextLabel4, 6, 0 );
+
+ ipAddressEdit = new QLineEdit( this, "ipAddressEdit" );
+
+ InterfaceConfigurationLayout->addWidget( ipAddressEdit, 6, 1 );
+
+ TextLabel5 = new QLabel( this, "TextLabel5" );
+ TextLabel5->setText( tr( "Subnet Mask" ) );
+
+ InterfaceConfigurationLayout->addWidget( TextLabel5, 7, 0 );
+
+ firstDNSLineEdit = new QLineEdit( this, "firstDNSLineEdit" );
+
+ InterfaceConfigurationLayout->addWidget( firstDNSLineEdit, 9, 1 );
+
+ TextLabel3 = new QLabel( this, "TextLabel3" );
+ TextLabel3->setText( tr( "Second DNS" ) );
+
+ InterfaceConfigurationLayout->addWidget( TextLabel3, 10, 0 );
+
+ subnetMaskEdit = new QLineEdit( this, "subnetMaskEdit" );
+
+ InterfaceConfigurationLayout->addWidget( subnetMaskEdit, 7, 1 );
+
+ gatewayEdit = new QLineEdit( this, "gatewayEdit" );
+
+ InterfaceConfigurationLayout->addWidget( gatewayEdit, 8, 1 );
+
+ TextLabel7 = new QLabel( this, "TextLabel7" );
+ TextLabel7->setText( tr( "Gateway" ) );
+
+ InterfaceConfigurationLayout->addWidget( TextLabel7, 8, 0 );
+
+ TextLabel2 = new QLabel( this, "TextLabel2" );
+ TextLabel2->setText( tr( "First DNS" ) );
+
+ InterfaceConfigurationLayout->addWidget( TextLabel2, 9, 0 );
+
+ secondDNSLineEdit = new QLineEdit( this, "secondDNSLineEdit" );
+
+ InterfaceConfigurationLayout->addWidget( secondDNSLineEdit, 10, 1 );
+
+ GroupBox2 = new QGroupBox( this, "GroupBox2" );
+ GroupBox2->setTitle( tr( "Static Ip Configuration" ) );
+
+ InterfaceConfigurationLayout->addMultiCellWidget( GroupBox2, 5, 5, 0, 1 );
+
+ // signals and slots connections
+ connect( dhcpCheckBox, SIGNAL( toggled(bool) ), SpinBox1_2, SLOT( setEnabled(bool) ) );
+ connect( dhcpCheckBox, SIGNAL( toggled(bool) ), GroupBox2, SLOT( setDisabled(bool) ) );
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+InterfaceConfiguration::~InterfaceConfiguration()
+{
+ // no need to delete child widgets, Qt does it all for us
+}
+
diff --git a/noncore/settings/networksettings/interfaceedit.h b/noncore/settings/networksettings/interfaceedit.h
new file mode 100644
index 0000000..a65c030
--- a/dev/null
+++ b/noncore/settings/networksettings/interfaceedit.h
@@ -0,0 +1,56 @@
+/****************************************************************************
+** Form interface generated from reading ui file 'interfaceedit.ui'
+**
+** Created: Mon Sep 23 12:18:55 2002
+** by: The User Interface Compiler (uic)
+**
+** WARNING! All changes made in this file will be lost!
+****************************************************************************/
+#ifndef INTERFACECONFIGURATION_H
+#define INTERFACECONFIGURATION_H
+
+#include <qvariant.h>
+#include <qwidget.h>
+class QVBoxLayout;
+class QHBoxLayout;
+class QGridLayout;
+class QCheckBox;
+class QComboBox;
+class QFrame;
+class QGroupBox;
+class QLabel;
+class QLineEdit;
+class QSpinBox;
+
+class InterfaceConfiguration : public QWidget
+{
+ Q_OBJECT
+
+public:
+ InterfaceConfiguration( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );
+ ~InterfaceConfiguration();
+
+ QComboBox* profile;
+ QLabel* TextLabel1;
+ QFrame* Line1;
+ QCheckBox* CheckBox3;
+ QCheckBox* dhcpCheckBox;
+ QLabel* TextLabel3_3_2;
+ QSpinBox* SpinBox1_2;
+ QLabel* TextLabel4;
+ QLineEdit* ipAddressEdit;
+ QLabel* TextLabel5;
+ QLineEdit* firstDNSLineEdit;
+ QLabel* TextLabel3;
+ QLineEdit* subnetMaskEdit;
+ QLineEdit* gatewayEdit;
+ QLabel* TextLabel7;
+ QLabel* TextLabel2;
+ QLineEdit* secondDNSLineEdit;
+ QGroupBox* GroupBox2;
+
+protected:
+ QGridLayout* InterfaceConfigurationLayout;
+};
+
+#endif // INTERFACECONFIGURATION_H
diff --git a/noncore/settings/networksettings/interfaceinformation.ui b/noncore/settings/networksettings/interfaceinformation.ui
new file mode 100644
index 0000000..2a9b3fb
--- a/dev/null
+++ b/noncore/settings/networksettings/interfaceinformation.ui
@@ -0,0 +1,317 @@
+<!DOCTYPE UI><UI>
+<class>InterfaceInformation</class>
+<widget>
+ <class>QWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>InterfaceInformation</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>191</width>
+ <height>241</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>Interface Information</string>
+ </property>
+ <grid>
+ <property stdset="1">
+ <name>margin</name>
+ <number>11</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget row="4" column="0" rowspan="1" colspan="2" >
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout1</cstring>
+ </property>
+ <grid>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget row="1" column="0" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>refreshButton</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Refresh</string>
+ </property>
+ </widget>
+ <widget row="0" column="1" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>stopButton</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Stop</string>
+ </property>
+ </widget>
+ <widget row="1" column="1" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>restartButton</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Restart</string>
+ </property>
+ </widget>
+ <widget row="0" column="0" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>startButton</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Start</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget row="0" column="0" >
+ <class>Line</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Line1</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ <spacer row="6" column="1" >
+ <property>
+ <name>name</name>
+ <cstring>Spacer18</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Vertical</enum>
+ </property>
+ <property stdset="1">
+ <name>sizeType</name>
+ <enum>Expanding</enum>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget row="5" column="0" rowspan="1" colspan="2" >
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout2</cstring>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <spacer>
+ <property>
+ <name>name</name>
+ <cstring>Spacer10</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Horizontal</enum>
+ </property>
+ <property stdset="1">
+ <name>sizeType</name>
+ <enum>Expanding</enum>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>advancedButton</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>View Advanced Information</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget row="0" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel22</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>IP Address</string>
+ </property>
+ </widget>
+ <widget row="1" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel23</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Subnet Mask</string>
+ </property>
+ </widget>
+ <widget row="2" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel21</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>MAC Address</string>
+ </property>
+ </widget>
+ <widget row="3" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel24</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Broadcast</string>
+ </property>
+ </widget>
+ <widget row="1" column="1" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>subnetMaskLabel</cstring>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>Panel</enum>
+ </property>
+ <property stdset="1">
+ <name>frameShadow</name>
+ <enum>Sunken</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>0.0.0.0</string>
+ </property>
+ </widget>
+ <widget row="2" column="1" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>macAddressLabel</cstring>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>Panel</enum>
+ </property>
+ <property stdset="1">
+ <name>frameShadow</name>
+ <enum>Sunken</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>00:00:00:00:00:00</string>
+ </property>
+ </widget>
+ <widget row="3" column="1" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>broadcastLabel</cstring>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>Panel</enum>
+ </property>
+ <property stdset="1">
+ <name>frameShadow</name>
+ <enum>Sunken</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string></string>
+ </property>
+ </widget>
+ <widget row="0" column="1" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>ipAddressLabel</cstring>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>Panel</enum>
+ </property>
+ <property stdset="1">
+ <name>frameShadow</name>
+ <enum>Sunken</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>0.0.0.0</string>
+ </property>
+ </widget>
+ </grid>
+</widget>
+<customwidgets>
+ <customwidget>
+ <class>QWidget</class>
+ <header location="local">qwidget.h</header>
+ <sizehint>
+ <width>100</width>
+ <height>100</height>
+ </sizehint>
+ <container>0</container>
+ <sizepolicy>
+ <hordata>7</hordata>
+ <verdata>7</verdata>
+ </sizepolicy>
+ <pixmap>image0</pixmap>
+ </customwidget>
+</customwidgets>
+<images>
+ <image>
+ <name>image0</name>
+ <data format="XPM.GZ" length="646">789c6dd2c10ac2300c00d07bbf2234b7229d1be245fc04c5a3201e4615f430059d0711ff5ddb2e6bb236ec90eed134cb5a19d8ef36602af5ecdbfeeac05dda0798d3abebde87e3faa374d3807fa0d633a52d38d8de6f679fe33fc776e196f53cd010188256a3600a292882096246517815ca99884606e18044a3a40d91824820924265a7923a2e8bcd05f33db1173e002913175f2a6be6d3294871a2d95fa00e8a94ee017b69d339d90df1e77c57ea072ede6758</data>
+ </image>
+</images>
+</UI>
diff --git a/noncore/settings/networksettings/interfaceinformationimp.cpp b/noncore/settings/networksettings/interfaceinformationimp.cpp
new file mode 100644
index 0000000..e37e0f8
--- a/dev/null
+++ b/noncore/settings/networksettings/interfaceinformationimp.cpp
@@ -0,0 +1,94 @@
+#include "interfaceinformationimp.h"
+#include "interfaceadvanced.h"
+
+#include <qpushbutton.h>
+#include <qlabel.h>
+#include <assert.h>
+
+/**
+ * Constructor for the InterfaceInformationImp class. This class pretty much
+ * just display's information about the interface that is passed to it.
+ */
+InterfaceInformationImp::InterfaceInformationImp(QWidget *parent, const char *name, Interface *i, WFlags f):InterfaceInformation(parent, name, f){
+ assert(i);
+
+ interface = i;
+ updateInterface();
+ connect(startButton, SIGNAL(clicked()), this, SLOT(start()));
+ connect(stopButton, SIGNAL(clicked()), this, SLOT(stop()));
+ connect(restartButton, SIGNAL(clicked()), this, SLOT(restart()));
+ connect(refreshButton, SIGNAL(clicked()), this, SLOT(refresh()));
+ connect(advancedButton, SIGNAL(clicked()), this, SLOT(advanced()));
+
+}
+
+void InterfaceInformationImp::updateInterface(){
+ if(interface->getStatus()){
+ startButton->setEnabled(false);
+ stopButton->setEnabled(true);
+ restartButton->setEnabled(true);
+ }
+ else{
+ startButton->setEnabled(true);
+ stopButton->setEnabled(false);
+ restartButton->setEnabled(false);
+ }
+ macAddressLabel->setText(interface->getMacAddress());
+ ipAddressLabel->setText(interface->getIp());
+ subnetMaskLabel->setText(interface->getSubnetMask());
+ broadcastLabel->setText(interface->getBroadcast());
+}
+
+/**
+ * Start the interface. Update the information if successfull
+ */
+void InterfaceInformationImp::start(){
+ if(interface->start()){
+ updateInterface();
+ }
+}
+
+/**
+ * Stop the interface.
+ */
+void InterfaceInformationImp::stop(){
+ if(interface->stop()){
+ updateInterface();
+ }
+}
+
+/***
+ * Tell the interface to refresh its information.
+ **/
+void InterfaceInformationImp::refresh(){
+ if(interface->refresh())
+ updateInterface();
+}
+
+void InterfaceInformationImp::restart(){
+ if(interface->restart()){
+ updateInterface();
+ }
+}
+
+
+/**
+ * Create the advanced widget. Fill it with the current interface's information.
+ * Display it.
+ */
+void InterfaceInformationImp::advanced(){
+ InterfaceAdvanced *a = new InterfaceAdvanced(0, "InterfaceAdvanced");
+ a->interfaceName->setText(interface->getInterfaceName());
+ a->macAddressLabel->setText(interface->getMacAddress());
+ a->ipAddressLabel->setText(interface->getIp());
+ a->subnetMaskLabel->setText(interface->getSubnetMask());
+ a->broadcastLabel->setText(interface->getBroadcast());
+ a->dhcpServerLabel->setText(interface->getDhcpServerIp());
+ a->leaseObtainedLabel->setText(interface->getLeaseObtained());
+ a->leaseExpiresLabel->setText(interface->getLeaseExpires());
+ a->showMaximized();
+ a->show();
+}
+
+// infoimp.cpp
+
diff --git a/noncore/settings/networksettings/interfaceinformationimp.h b/noncore/settings/networksettings/interfaceinformationimp.h
new file mode 100644
index 0000000..6fc2384
--- a/dev/null
+++ b/noncore/settings/networksettings/interfaceinformationimp.h
@@ -0,0 +1,31 @@
+#ifndef INTERFACEINFORMATIONIMP_H
+#define INTERFACEINFORMATIONIMP_H
+
+#include "interfaceinformation.h"
+#include "interface.h"
+
+class InterfaceInformationImp : public InterfaceInformation {
+
+Q_OBJECT
+
+public:
+ InterfaceInformationImp(QWidget *parent=0, const char *name=0, Interface *i=0, WFlags f=0);
+ ~InterfaceInformationImp(){};
+
+private slots:
+ void start();
+ void stop();
+ void refresh();
+ void restart();
+ void advanced();
+ Interface *interface;
+
+private:
+ void updateInterface();
+
+};
+
+#endif
+
+// addserviceimp.h
+
diff --git a/noncore/settings/networksettings/interfaces.cpp b/noncore/settings/networksettings/interfaces.cpp
new file mode 100644
index 0000000..b8a3e7f
--- a/dev/null
+++ b/noncore/settings/networksettings/interfaces.cpp
@@ -0,0 +1,513 @@
+#include "interfaces.h"
+
+#include <qfile.h>
+#include <qtextstream.h>
+#include <qregexp.h>
+
+#define AUTO "auto"
+#define IFACE "iface"
+#define MAPPING "mapping"
+
+/**
+ * Constructor. Reads in the interfaces file and then split the file up by
+ * the \n for interfaces variable.
+ * @param useInterfacesFile if an interface file other then the default is
+ * desired to be used it should be passed in.
+ */
+Interfaces::Interfaces(QString useInterfacesFile){
+ acceptedFamily.append(INTERFACES_FAMILY_INET);
+ acceptedFamily.append(INTERFACES_FAMILY_IPX);
+ acceptedFamily.append(INTERFACES_FAMILY_INET6);
+
+ interfacesFile = useInterfacesFile;
+ QFile file(interfacesFile);
+ if (!file.open(IO_ReadOnly)){
+ qDebug(QString("Interfaces: Can't open file: %1 for reading.").arg(interfacesFile).latin1());
+ currentIface = interfaces.end();
+ currentMapping = interfaces.end();
+ return;
+ }
+ QTextStream stream( &file );
+ QString line;
+ while ( !stream.eof() ) {
+ line += stream.readLine();
+ line += "\n";
+ }
+ file.close();
+ interfaces = QStringList::split("\n", line, true);
+
+ currentIface = interfaces.end();
+ currentMapping = interfaces.end();
+}
+
+/**
+ * Find out if interface is in an "auto" group or not.
+ * Report any duplicates such as eth0 being in two differnt auto's
+ * @param
+ * @return true is interface is in auto
+ */
+bool Interfaces::isAuto(QString interface){
+ QStringList autoLines = interfaces.grep(QRegExp(AUTO));
+ QStringList awi = autoLines.grep(QRegExp(interface));
+ if(awi.count() > 1)
+ qDebug(QString("Interfaces: Found more then auto group with interface: %1.").arg(interface).latin1());
+ if(awi.count() < 1)
+ return false;
+ return true;
+}
+
+/**
+ * Attempt to set the auto option for interface to setAuto.
+ * @param interface the interface to set
+ * @param setAuto the value to set interface to.
+ * @return false if already set to setAuto.
+ * */
+bool Interfaces::setAuto(QString interface, bool setAuto){
+ // Don't need to set it if it is already set.
+ if(isAuto(interface) == setAuto)
+ return false;
+
+ bool changed = false;
+ for ( QStringList::Iterator it = interfaces.begin(); it != interfaces.end(); ++it ) {
+ if((*it).contains(AUTO)){
+ //We know that they are not in any group so let add to this auto.
+ if(setAuto){
+ (*it) = (*it) += " " + interface;
+ // Don't care to have such thins as: auto eth0 lo usb0
+ (*it) = (*it).simplifyWhiteSpace();
+ changed = true;
+ break;
+ }
+ else{
+ if((*it).contains(interface)){
+ (*it) = (*it).replace(QRegExp(interface), "");
+ // clean up
+ QString line = (*it).simplifyWhiteSpace();
+ line = line.replace(QRegExp(" "),"");
+ if(line == AUTO)
+ (*it) = "";
+ changed = true;
+ // Don't break because we want to make sure we remove all cases.
+ }
+ }
+ }
+ }
+ if(changed == false){
+ if(setAuto == true)
+ interfaces.append(QString(AUTO" %1").arg(interface));
+ else{
+ qDebug(QString("Interfaces: Can't set interface %1 auto to false sense it is already false.").arg(interface).latin1());
+ }
+ }
+ return true;
+}
+
+/**
+ * Set the current interface to interface. This needs to be done before you
+ * can call getFamily(), getMethod, and get/setOption().
+ * @param interface the name of the interface to set. All whitespace is
+ * removed from the interface name.
+ * @return bool true if it is successfull.
+ */
+bool Interfaces::setInterface(QString interface){
+ interface = interface.simplifyWhiteSpace();
+ interface = interface.replace(QRegExp(" "), "");
+ return setStanza(IFACE, interface, currentIface);
+}
+
+/**
+ * A quick helper funtion to see if the current interface is set.
+ * @return bool true if set, false otherwise.
+ */
+bool Interfaces::isInterfaceSet(){
+ return (currentIface != interfaces.end());
+}
+
+/**
+ * Add a new interface of with the settings - family and method
+ * @param interface the name of the interface to set. All whitespace is
+ * removed from the interface name.
+ * @param family the family of this interface inet or inet, ipx or inet6
+ * Must of one of the families defined in interfaces.h
+ * @param method for the family. see interfaces man page for family methods.
+ * @return true if successfull.
+ */
+bool Interfaces::addInterface(QString interface, QString family, QString method){
+ if(acceptedFamily.contains(family)==0)
+ return false;
+ interface = interface.simplifyWhiteSpace();
+ interface = interface.replace(QRegExp(" "), "");
+ interfaces.append("");
+ interfaces.append(QString(IFACE " %1 %2 %3").arg(interface).arg(family).arg(method));
+ return true;
+}
+
+/**
+ * Remove the currently selected interface and all of its options.
+ * @return bool if successfull or not.
+ */
+bool Interfaces::removeInterface(){
+ if(currentIface == interfaces.end())
+ return false;
+ (*currentIface) = "";
+ return removeAllInterfaceOptions();
+}
+
+/**
+ * Gets the hardware name of the interface that is currently selected.
+ * @return QString name of the hardware interface (eth0, usb2, wlan1...).
+ * @param error set to true if any error occurs, false otherwise.
+ */
+QString Interfaces::getInterfaceName(bool &error){
+ if(currentIface == interfaces.end()){
+ error = true;
+ return QString();
+ }
+ QString line = (*currentIface);
+ line = line.mid(QString(IFACE).length() +1, line.length());
+ line = line.simplifyWhiteSpace();
+ int findSpace = line.find(" ");
+ if( findSpace < 0){
+ error = true;
+ return QString();
+ }
+ error = false;
+ return line.mid(0, findSpace);
+}
+
+/**
+ * Gets the family name of the interface that is currently selected.
+ * @return QString name of the family (inet, inet6, ipx).
+ * @param error set to true if any error occurs, false otherwise.
+ */
+QString Interfaces::getInterfaceFamily(bool &error){
+ QString name = getInterfaceName(error);
+ if(error){
+ error = true;
+ return QString();
+ }
+ QString line = (*currentIface);
+ line = line.mid(QString(IFACE).length() +1, line.length());
+ line = line.mid(name.length()+1, line.length());
+ line = line.simplifyWhiteSpace();
+ int findSpace = line.find(" ");
+ if( findSpace < 0){
+ error = true;
+ return QString();
+ }
+ error = false;
+ return line.mid(0, findSpace);
+}
+
+/**
+ * Gets the method of the interface that is currently selected.
+ * @return QString name of the method such as staic or dhcp.
+ * See the man page of interfaces for possible methods depending on the family.
+ * @param error set to true if any error occurs, false otherwise.
+ */
+QString Interfaces::getInterfaceMethod(bool &error){
+ QString name = getInterfaceName(error);
+ if(error){
+ error = true;
+ return QString();
+ }
+ QString family = getInterfaceFamily(error);
+ if(error){
+ error = true;
+ return QString();
+ }
+ QString line = (*currentIface);
+ line = line.mid(QString(IFACE).length()+1, line.length());
+ line = line.mid(name.length()+1, line.length());
+ line = line.mid(family.length()+1, line.length());
+ line = line.simplifyWhiteSpace();
+ error = false;
+ return line;
+}
+
+/**
+ * Sets the interface name to newName.
+ * @param newName the new name of the interface. All whitespace is removed.
+ * @return bool true if successfull.
+ */
+bool Interfaces::setInterfaceName(QString newName){
+ if(currentIface == interfaces.end())
+ return false;
+ newName = newName.simplifyWhiteSpace();
+ newName = newName.replace(QRegExp(" "), "");
+ bool returnValue = false;
+ (*currentIface) = QString("iface %1 %2 %3").arg(newName).arg(getInterfaceFamily(returnValue)).arg(getInterfaceMethod(returnValue));
+ return !returnValue;
+}
+
+/**
+ * Sets the interface family to newName.
+ * @param newName the new name of the interface. Must be one of the families
+ * defined in the interfaces.h file.
+ * @return bool true if successfull.
+ */
+bool Interfaces::setInterfaceFamily(QString newName){
+ if(currentIface == interfaces.end())
+ return false;
+ if(acceptedFamily.contains(newName)==0)
+ return false;
+ bool returnValue = false;
+ (*currentIface) = QString("iface %1 %2 %3").arg(getInterfaceName(returnValue)).arg(newName).arg(getInterfaceMethod(returnValue));
+ return !returnValue;
+}
+
+/**
+ * Sets the interface method to newName
+ * @param newName the new name of the interface
+ * @return bool true if successfull.
+ */
+bool Interfaces::setInterfaceMethod(QString newName){
+ if(currentIface == interfaces.end())
+ return false;
+ bool returnValue = false;
+ (*currentIface) = QString("iface %1 %2 %3").arg(getInterfaceName(returnValue)).arg(getInterfaceFamily(returnValue)).arg(newName);
+ return !returnValue;
+}
+
+/**
+ * Get a value for an option in the currently selected interface. For example
+ * calling getInterfaceOption("address") on the following stanza would
+ * return 192.168.1.1.
+ * iface eth0 static
+ * address 192.168.1.1
+ * @param option the options to get the value.
+ * @param error set to true if any error occurs, false otherwise.
+ * @return QString the options value. QString::null if error == true
+ */
+QString Interfaces::getInterfaceOption(QString option, bool &error){
+ return getOption(currentIface, option, error);
+}
+
+/**
+ * Set a value for an option in the currently selected interface. If option
+ * doesn't exist then it is added along with the value. If value is set to an
+ * empty string then option is removed.
+ * @param option the options to set the value.
+ * @param value the value that option should be set to.
+ * @param error set to true if any error occurs, false otherwise.
+ * @return QString the options value. QString::null if error == true
+ */
+bool Interfaces::setInterfaceOption(QString option, QString value){
+ return setOption(currentIface, option, value);
+}
+
+/**
+ * Removes all of the options from the currently selected interface.
+ * @return bool error if if successfull
+ */
+bool Interfaces::removeAllInterfaceOptions(){
+ return removeAllOptions(currentIface);
+}
+
+/**
+ * Set the current map to interface's map. This needs to be done before you
+ * can call addMapping(), set/getMap(), and get/setScript().
+ * @param interface the name of the interface to set. All whitespace is
+ * removed from the interface name.
+ * @return bool true if it is successfull.
+ */
+bool Interfaces::setMapping(QString interface){
+ interface = interface.simplifyWhiteSpace();
+ interface = interface.replace(QRegExp(" "), "");
+ return setStanza(MAPPING, interface, currentMapping);
+}
+
+/**
+ * Adds a new Mapping to the interfaces file with interfaces.
+ * @param interface the name(s) of the interfaces to set to this mapping
+ */
+void Interfaces::addMapping(QString interfaces){
+ interfaces.append("");
+ interfaces.append(QString(MAPPING " %1").arg(interfaces));
+}
+
+/**
+ * Set a map option within a mapping.
+ * @param map map to use
+ * @param value value to go with map
+ * @return bool true if it is successfull.
+ */
+bool Interfaces::setMap(QString map, QString value){
+ return setOption(currentMapping, map, value);
+}
+
+/**
+ * Get a map value within a mapping.
+ * @param map map to get value of
+ * @param bool true if it is successfull.
+ * @return value that goes to the map
+ */
+QString Interfaces::getMap(QString map, bool &error){
+ return getOption(currentMapping, map, error);
+}
+
+/**
+ * Sets a script value of the current mapping to argument.
+ * @param argument the script name.
+ * @return true if successfull.
+ */
+bool Interfaces::setScript(QString argument){
+ return setOption(currentMapping, "script", argument);
+}
+
+/**
+ * @param error true if could not retrieve the current script argument.
+ * @return QString the argument of the script for the current mapping.
+ */
+QString Interfaces::getScript(bool &error){
+ return getOption(currentMapping, "script", error);
+}
+
+/**
+ * Helper function used to parse through the QStringList and put pointers in
+ * the correct place.
+ * @param stanza The stanza (auto, iface, mapping) to look for.
+ * @param option string that must be in the stanza's main line.
+ * @param interator interator to place at location of stanza if successfull.
+ * @return bool true if the stanza is found.
+ */
+bool Interfaces::setStanza(QString stanza, QString option, QStringList::Iterator &iterator){
+ bool found = false;
+ iterator = interfaces.end();
+ for ( QStringList::Iterator it = interfaces.begin(); it != interfaces.end(); ++it ) {
+ QString line = (*it).simplifyWhiteSpace();
+ if(line.contains(stanza) && line.contains(option)){
+ if(found == true){
+ qDebug(QString("Interfaces: Found multiple stanza's for search: %1 %2").arg(stanza).arg(option).latin1());
+ }
+ found = true;
+ iterator = it;
+ }
+ }
+ return !found;
+}
+
+/**
+ * Sets a value of an option in a stanza
+ * @param start the start of the stanza
+ * @param option the option to use when setting value.
+ * @return bool true if successfull, false otherwise.
+ */
+bool Interfaces::setOption(QStringList::Iterator start, QString option, QString value){
+ if(start == interfaces.end())
+ return false;
+
+ bool found = false;
+ for ( QStringList::Iterator it = start; it != interfaces.end(); ++it ) {
+ if(((*it).contains(IFACE) || (*it).contains(MAPPING) || (*it).contains(AUTO)) && it != start){
+ if(!found && value != ""){
+ // Got to the end of the stanza without finding it, so append it.
+ interfaces.insert(--it, QString("\t%1 %2").arg(option).arg(value));
+ }
+ break;
+ }
+ if((*it).contains(option)){
+ // Found it in stanza so replace it.
+ if(found)
+ qDebug(QString("Interfaces: Set Options found more then one value for option: %1 in stanza: %1").arg(option).arg((*start)).latin1());
+ found = true;
+ if(value == "")
+ (*it) = "";
+ else
+ (*it) = QString("\t%1 %2").arg(option).arg(value);
+ }
+ }
+ return true;
+}
+
+/**
+ * Removes all options in a stanza
+ * @param start the start of the stanza
+ * @return bool true if successfull, false otherwise.
+ */
+bool Interfaces::removeAllOptions(QStringList::Iterator start){
+ if(start == interfaces.end())
+ return false;
+
+ QStringList::Iterator it = start;
+ it = ++it;
+ for (it; it != interfaces.end(); ++it ) {
+ if(((*it).contains(IFACE) || (*it).contains(MAPPING) || (*it).contains(AUTO)) && it != start){
+ break;
+ }
+ it = interfaces.remove(it);
+ it = --it;
+ }
+ // Leave a space between this interface and the next.
+ interfaces.insert(it, QString(""));
+ return true;
+}
+
+/**
+ * Gets a value of an option in a stanza
+ * @param start the start of the stanza
+ * @param option the option to use when getting the value.
+ * @param bool true if errors false otherwise.
+ * @return QString the value of option QString::null() if error == true.
+ */
+QString Interfaces::getOption(QStringList::Iterator start, QString option, bool &error){
+ if(start == interfaces.end()){
+ error = false;
+ return QString();
+ }
+
+ QString value;
+ bool found = false;
+ for ( QStringList::Iterator it = start; it != interfaces.end(); ++it ) {
+ if(((*it).contains(IFACE) || (*it).contains(MAPPING) || (*it).contains(AUTO)) && it != start){
+ break;
+ }
+ if((*it).contains(option)){
+ if(found)
+ qDebug(QString("Interfaces: Get Options found more then one value: %1 for option: %2 in stanza %3").arg((*it)).arg(option).arg((*start)).latin1());
+ found = true;
+ QString line = (*it).simplifyWhiteSpace();
+ int space = line.find(" ", option.length());
+ if(space != -1)
+ value = line.mid(space+1, line.length());
+ else
+ qDebug(QString("Interfaces: Option %1 with no value").arg(option).latin1());
+ }
+ }
+ error = !found;
+ return value;
+}
+
+/**
+ * Write out the interfaces file to the file passed into the constructor.
+ * Removes any excess blank lines over 1 line long.
+ * @return bool true if successfull, false if not.
+ */
+bool Interfaces::write(){
+ QFile::remove(interfacesFile);
+ QFile file(interfacesFile);
+
+ if (!file.open(IO_ReadWrite)){
+ qDebug(QString("Interfaces: Can't open file: %1 for writing.").arg(interfacesFile).latin1());
+ return false;
+ }
+ QTextStream stream( &file );
+ int whiteSpaceCount = 0;
+ for ( QStringList::Iterator it = interfaces.begin(); it != interfaces.end(); ++it ) {
+ QString line = (*it).simplifyWhiteSpace();
+ line = line.replace(QRegExp(" "),"");
+ if(line.length() == 0)
+ whiteSpaceCount++;
+ else
+ whiteSpaceCount = 0;
+ if(whiteSpaceCount < 2){
+ qDebug((*it).latin1());
+ stream << (*it) << '\n';
+ }
+ }
+ file.close();
+ return true;
+}
+
+// interfaces.cpp
+
diff --git a/noncore/settings/networksettings/interfaces.h b/noncore/settings/networksettings/interfaces.h
new file mode 100644
index 0000000..2cc9689
--- a/dev/null
+++ b/noncore/settings/networksettings/interfaces.h
@@ -0,0 +1,70 @@
+#ifndef INTERFACES_H
+#define INTERFACES_H
+
+#include <qstring.h>
+#include <qstringlist.h>
+
+#define INTERFACES_LOOPBACK "loopback"
+
+#define INTERFACES_FAMILY_INET "inet"
+#define INTERFACES_FAMILY_IPX "ipx"
+#define INTERFACES_FAMILY_INET6 "inet6"
+
+#define INTERFACES_METHOD_DHCP "dhcp"
+#define INTERFACES_METHOD_STATIC "static"
+#define INTERFACES_METHOD_PPP "ppp"
+
+/**
+ * This class provides a clean frontend for parsing the network interfaces file.
+ * It provides helper functions to minipulate the options within the file.
+ * See the interfaces man page for the syntax rules.
+ */
+class Interfaces {
+
+public:
+ Interfaces(QString useInterfacesFile = "/etc/network/interfaces");
+
+ bool isAuto(QString interface);
+ bool setAuto(QString interface, bool setAuto);
+
+ bool removeInterface();
+ bool addInterface(QString interface, QString family, QString method);
+ bool setInterface(QString interface);
+ bool isInterfaceSet();
+ QString getInterfaceName(bool &error);
+ bool setInterfaceName(QString newName);
+ QString getInterfaceFamily(bool &error);
+ bool setInterfaceFamily(QString newName);
+ QString getInterfaceMethod(bool &error);
+ bool setInterfaceMethod(QString newName);
+ QString getInterfaceOption(QString option, bool &error);
+ bool setInterfaceOption(QString option, QString value);
+ bool removeAllInterfaceOptions();
+
+ bool setMapping(QString interface);
+ void addMapping(QString interfaces);
+ bool setMap(QString map, QString value);
+ QString getMap(QString map, bool &error);
+ bool setScript(QString);
+ QString getScript(bool &error);
+
+ bool write();
+
+private:
+ bool setStanza(QString stanza, QString option,QStringList::Iterator &iterator);
+ bool setOption(QStringList::Iterator start, QString option, QString value);
+ QString getOption(QStringList::Iterator start, QString option, bool &error);
+ bool removeAllOptions(QStringList::Iterator start);
+
+ QString interfacesFile;
+ QStringList interfaces;
+ QStringList::Iterator currentIface;
+ QStringList::Iterator currentMapping;
+
+ QStringList acceptedFamily;
+};
+
+#endif
+
+// interfaces
+
diff --git a/noncore/settings/networksettings/interfacesetup.ui b/noncore/settings/networksettings/interfacesetup.ui
new file mode 100644
index 0000000..698422c
--- a/dev/null
+++ b/noncore/settings/networksettings/interfacesetup.ui
@@ -0,0 +1,274 @@
+<!DOCTYPE UI><UI>
+<class>InterfaceSetup</class>
+<widget>
+ <class>QDialog</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>InterfaceSetup</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>193</width>
+ <height>310</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>Interface Configuration</string>
+ </property>
+ <grid>
+ <property stdset="1">
+ <name>margin</name>
+ <number>11</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget row="1" column="0" rowspan="1" colspan="2" >
+ <class>Line</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Line1</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ <widget row="6" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel4</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>IP Address</string>
+ </property>
+ </widget>
+ <widget row="0" column="0" rowspan="1" colspan="2" >
+ <class>QCheckBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>autoStart</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Automaticly bring up</string>
+ </property>
+ </widget>
+ <widget row="2" column="1" >
+ <class>QComboBox</class>
+ <item>
+ <property>
+ <name>text</name>
+ <string>All</string>
+ </property>
+ </item>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>profileCombo</cstring>
+ </property>
+ </widget>
+ <widget row="5" column="0" rowspan="1" colspan="2" >
+ <class>QGroupBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>staticGroupBox</cstring>
+ </property>
+ <property stdset="1">
+ <name>enabled</name>
+ <bool>false</bool>
+ </property>
+ <property stdset="1">
+ <name>title</name>
+ <string>Static Ip Configuration</string>
+ </property>
+ </widget>
+ <widget row="6" column="1" >
+ <class>QLineEdit</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>ipAddressEdit</cstring>
+ </property>
+ </widget>
+ <widget row="4" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>leaseHoursLabel</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Requested Lease</string>
+ </property>
+ </widget>
+ <widget row="3" column="0" rowspan="1" colspan="2" >
+ <class>QCheckBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>dhcpCheckBox</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>DHCP</string>
+ </property>
+ <property stdset="1">
+ <name>checked</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget row="7" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel5</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Subnet Mask</string>
+ </property>
+ </widget>
+ <widget row="2" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel1</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Profile:</string>
+ </property>
+ </widget>
+ <widget row="4" column="1" >
+ <class>QSpinBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>leaseTime</cstring>
+ </property>
+ <property stdset="1">
+ <name>suffix</name>
+ <string> hours</string>
+ </property>
+ <property stdset="1">
+ <name>maxValue</name>
+ <number>336</number>
+ </property>
+ <property stdset="1">
+ <name>minValue</name>
+ <number>1</number>
+ </property>
+ <property stdset="1">
+ <name>value</name>
+ <number>24</number>
+ </property>
+ </widget>
+ <spacer row="11" column="1" >
+ <property>
+ <name>name</name>
+ <cstring>Spacer9</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Vertical</enum>
+ </property>
+ <property stdset="1">
+ <name>sizeType</name>
+ <enum>Expanding</enum>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget row="10" column="1" >
+ <class>QLineEdit</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>secondDNSLineEdit</cstring>
+ </property>
+ </widget>
+ <widget row="10" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel3</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Second DNS</string>
+ </property>
+ </widget>
+ <widget row="9" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel2</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>First DNS</string>
+ </property>
+ </widget>
+ <widget row="9" column="1" >
+ <class>QLineEdit</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>firstDNSLineEdit</cstring>
+ </property>
+ </widget>
+ <widget row="8" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel1_2</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Gateway</string>
+ </property>
+ </widget>
+ <widget row="7" column="1" >
+ <class>QLineEdit</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>subnetMaskEdit</cstring>
+ </property>
+ </widget>
+ <widget row="8" column="1" >
+ <class>QLineEdit</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>gatewayEdit</cstring>
+ </property>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>dhcpCheckBox</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>leaseHoursLabel</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>dhcpCheckBox</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>leaseTime</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>dhcpCheckBox</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>staticGroupBox</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+</connections>
+</UI>
diff --git a/noncore/settings/networksettings/interfacesetupimp.cpp b/noncore/settings/networksettings/interfacesetupimp.cpp
new file mode 100644
index 0000000..6a8449d
--- a/dev/null
+++ b/noncore/settings/networksettings/interfacesetupimp.cpp
@@ -0,0 +1,147 @@
+#include "interfacesetupimp.h"
+#include "interface.h"
+#include "interfaces.h"
+
+#include <qcombobox.h>
+#include <qcheckbox.h>
+#include <qlineedit.h>
+#include <qspinbox.h>
+#include <qgroupbox.h>
+#include <qlabel.h>
+
+#include <qmessagebox.h>
+
+#include <assert.h>
+
+#define INTERFACE_FILE "/home/ben/interfaces"
+#define DNSSCRIPT "interfacednsscript"
+
+/**
+ * Constuctor. Set up the connection and load the first profile.
+ */
+InterfaceSetupImp::InterfaceSetupImp(QWidget* parent, const char* name, Interface *i, bool modal, WFlags fl) : InterfaceSetup(parent, name, modal, fl){
+ assert(i);
+ interface = i;
+ interfaces = new Interfaces(INTERFACE_FILE);
+ changeProfile(profileCombo->currentText());
+ bool error = false;
+ if(interfaces->getInterfaceMethod(error) == INTERFACES_LOOPBACK){
+ staticGroupBox->hide();
+ dhcpCheckBox->hide();
+ leaseTime->hide();
+ leaseHoursLabel->hide();
+ }
+ connect(profileCombo, SIGNAL(highlighted(const QString &)), this, SLOT(changeProfile(const QString &)));
+}
+
+/**
+ * Save the current settings, then write out the interfaces file and close.
+ */
+void InterfaceSetupImp::accept(){
+ if(!saveSettings())
+ return;
+ interfaces->write();
+ close(true);
+}
+
+/**
+ * Save the settings for the current Interface.
+ * @return bool true if successfull, false otherwise
+ */
+bool InterfaceSetupImp::saveSettings(){
+ // eh can't really do anything about it other then return. :-D
+ if(!interfaces->isInterfaceSet())
+ return true;
+
+ bool error = false;
+ // Loopback case
+ if(interfaces->getInterfaceMethod(error) == INTERFACES_LOOPBACK){
+ interfaces->setAuto(interface->getInterfaceName(), autoStart->isChecked());
+ return true;
+ }
+
+ if(!dhcpCheckBox->isChecked() && (ipAddressEdit->text().isEmpty() || subnetMaskEdit->text().isEmpty() || firstDNSLineEdit->text().isEmpty())){
+ QMessageBox::information(this, "Empy Fields.", "Please fill in address, subnet,\n gateway and the first dns entries.", "Ok");
+ return false;
+ }
+ interfaces->removeAllInterfaceOptions();
+
+ // DHCP
+ if(dhcpCheckBox->isChecked()){
+ interfaces->setInterfaceMethod(INTERFACES_METHOD_DHCP);
+ interfaces->setInterfaceOption("leasehours", QString("%1").arg(leaseTime->value()));
+ interfaces->setInterfaceOption("leasetime", QString("%1").arg(leaseTime->value()*60*60));
+ }
+ else{
+ interfaces->setInterfaceMethod("static");
+ interfaces->setInterfaceOption("address", ipAddressEdit->text());
+ interfaces->setInterfaceOption("netmask", subnetMaskEdit->text());
+ interfaces->setInterfaceOption("gateway", gatewayEdit->text());
+ QString dns = firstDNSLineEdit->text() + " " + secondDNSLineEdit->text();
+ interfaces->setInterfaceOption("up "DNSSCRIPT" add ", dns);
+ interfaces->setInterfaceOption("down "DNSSCRIPT" remove ", dns);
+ }
+
+ // IP Information
+ interfaces->setAuto(interface->getInterfaceName(), autoStart->isChecked());
+ return true;
+}
+
+/**
+ * The Profile has changed.
+ * @profile the new profile.
+ */
+void InterfaceSetupImp::changeProfile(const QString &profile){
+ QString newInterfaceName;
+ if(profile.lower() == "all")
+ newInterfaceName = interface->getInterfaceName();
+ else
+ newInterfaceName = interface->getInterfaceName() + "_" + profile;
+ if(newInterfaceName == currentInterfaceName)
+ return;
+ else{
+ saveSettings();
+ currentInterfaceName = newInterfaceName;
+ }
+ bool error = interfaces->setInterface(currentInterfaceName);
+
+ // See if we have to make a interface.
+ if(error){
+ qDebug("InterfaceSetupImp: Adding a new interface from profile change.");
+ interfaces->addInterface(currentInterfaceName, INTERFACES_FAMILY_INET, INTERFACES_METHOD_DHCP);
+ error = interfaces->setInterface(currentInterfaceName);
+ if(error){
+ qDebug("InterfaceSetupImp: Added interface, but still can't set.");
+ return;
+ }
+ }
+
+ //qDebug( currentInterfaceName.latin1() );
+ // We must have a valid interface to get this far so read some settings.
+
+ // DHCP
+ if(interfaces->getInterfaceMethod(error) == INTERFACES_METHOD_DHCP)
+ dhcpCheckBox->setChecked(true);
+ else
+ dhcpCheckBox->setChecked(false);
+ leaseTime->setValue(interfaces->getInterfaceOption("leasehours", error).toInt());
+ if(error)
+ leaseTime->setValue(interfaces->getInterfaceOption("leasetime", error).toInt()/60/60);
+ if(error)
+ leaseTime->setValue(24);
+
+ // IP Information
+ autoStart->setChecked(interfaces->isAuto(interface->getInterfaceName()));
+ QString dns = interfaces->getInterfaceOption("up interfacednsscript add", error);
+ if(dns.contains(" ")){
+ firstDNSLineEdit->setText(dns.mid(0, dns.find(" ")));
+ secondDNSLineEdit->setText(dns.mid(dns.find(" ")+1, dns.length()));
+ }
+ ipAddressEdit->setText(interfaces->getInterfaceOption("address", error));
+ subnetMaskEdit->setText(interfaces->getInterfaceOption("netmask", error));
+ gatewayEdit->setText(interfaces->getInterfaceOption("gateway", error));
+}
+
+
+// interfacesetup.cpp
+
diff --git a/noncore/settings/networksettings/interfacesetupimp.h b/noncore/settings/networksettings/interfacesetupimp.h
new file mode 100644
index 0000000..6c34718
--- a/dev/null
+++ b/noncore/settings/networksettings/interfacesetupimp.h
@@ -0,0 +1,30 @@
+#ifndef INTERFACESETUPIMP_H
+#define INTERFACESETUPIMP_H
+
+#include "interfacesetup.h"
+
+class Interface;
+class Interfaces;
+
+class InterfaceSetupImp : public InterfaceSetup {
+ Q_OBJECT
+
+public:
+ InterfaceSetupImp( QWidget* parent = 0, const char* name = 0, Interface *i=0, bool modal = FALSE, WFlags fl = 0);
+
+protected slots:
+ void accept();
+ void changeProfile(const QString &profile);
+
+private:
+ bool saveSettings();
+ Interfaces *interfaces;
+ Interface *interface;
+ QString currentInterfaceName;
+
+};
+
+#endif
+
+// interfacesetupimp.h
+
diff --git a/noncore/settings/networksettings/kprocctrl.cpp b/noncore/settings/networksettings/kprocctrl.cpp
new file mode 100644
index 0000000..cd8711a
--- a/dev/null
+++ b/noncore/settings/networksettings/kprocctrl.cpp
@@ -0,0 +1,267 @@
+/* This file is part of the KDE libraries
+ Copyright (C) 1997 Christian Czezakte (e9025461@student.tuwien.ac.at)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+//
+// KPROCESSCONTROLLER -- A helper class for KProcess
+//
+// version 0.3.1, Jan, 8th 1997
+//
+// (C) Christian Czezatke
+// e9025461@student.tuwien.ac.at
+//
+
+//#include <config.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <assert.h>
+
+#include <qsocketnotifier.h>
+#include "kprocess.h"
+#include "kprocctrl.h"
+
+KProcessController *KProcessController::theKProcessController = 0;
+
+struct sigaction KProcessController::oldChildHandlerData;
+bool KProcessController::handlerSet = false;
+
+KProcessController::KProcessController()
+{
+ assert( theKProcessController == 0 );
+
+ if (0 > pipe(fd))
+ printf(strerror(errno));
+
+ notifier = new QSocketNotifier(fd[0], QSocketNotifier::Read);
+ notifier->setEnabled(true);
+ QObject::connect(notifier, SIGNAL(activated(int)),
+ this, SLOT(slotDoHousekeeping(int)));
+ connect( &delayedChildrenCleanupTimer, SIGNAL( timeout()),
+ SLOT( delayedChildrenCleanup()));
+
+ theKProcessController = this;
+
+ setupHandlers();
+}
+
+
+void KProcessController::setupHandlers()
+{
+ if( handlerSet )
+ return;
+ struct sigaction act;
+ act.sa_handler=theSigCHLDHandler;
+ sigemptyset(&(act.sa_mask));
+ sigaddset(&(act.sa_mask), SIGCHLD);
+ // Make sure we don't block this signal. gdb tends to do that :-(
+ sigprocmask(SIG_UNBLOCK, &(act.sa_mask), 0);
+
+ act.sa_flags = SA_NOCLDSTOP;
+
+ // CC: take care of SunOS which automatically restarts interrupted system
+ // calls (and thus does not have SA_RESTART)
+
+#ifdef SA_RESTART
+ act.sa_flags |= SA_RESTART;
+#endif
+
+ sigaction( SIGCHLD, &act, &oldChildHandlerData );
+
+ act.sa_handler=SIG_IGN;
+ sigemptyset(&(act.sa_mask));
+ sigaddset(&(act.sa_mask), SIGPIPE);
+ act.sa_flags = 0;
+ sigaction( SIGPIPE, &act, 0L);
+ handlerSet = true;
+}
+
+void KProcessController::resetHandlers()
+{
+ if( !handlerSet )
+ return;
+ sigaction( SIGCHLD, &oldChildHandlerData, 0 );
+ // there should be no problem with SIGPIPE staying SIG_IGN
+ handlerSet = false;
+}
+
+// block SIGCHLD handler, because it accesses processList
+void KProcessController::addKProcess( KProcess* p )
+{
+ sigset_t newset, oldset;
+ sigemptyset( &newset );
+ sigaddset( &newset, SIGCHLD );
+ sigprocmask( SIG_BLOCK, &newset, &oldset );
+ processList.append( p );
+ sigprocmask( SIG_SETMASK, &oldset, 0 );
+}
+
+void KProcessController::removeKProcess( KProcess* p )
+{
+ sigset_t newset, oldset;
+ sigemptyset( &newset );
+ sigaddset( &newset, SIGCHLD );
+ sigprocmask( SIG_BLOCK, &newset, &oldset );
+ processList.remove( p );
+ sigprocmask( SIG_SETMASK, &oldset, 0 );
+}
+
+//using a struct which contains both the pid and the status makes it easier to write
+//and read the data into the pipe
+//especially this solves a problem which appeared on my box where slotDoHouseKeeping() received
+//only 4 bytes (with some debug output around the write()'s it received all 8 bytes)
+//don't know why this happened, but when writing all 8 bytes at once it works here, aleXXX
+struct waitdata
+{
+ pid_t pid;
+ int status;
+};
+
+void KProcessController::theSigCHLDHandler(int arg)
+{
+ struct waitdata wd;
+// int status;
+// pid_t this_pid;
+ int saved_errno;
+
+ saved_errno = errno;
+ // since waitpid and write change errno, we have to save it and restore it
+ // (Richard Stevens, Advanced programming in the Unix Environment)
+
+ bool found = false;
+ if( theKProcessController != 0 ) {
+ // iterating the list doesn't perform any system call
+ for( QValueList<KProcess*>::ConstIterator it = theKProcessController->processList.begin();
+ it != theKProcessController->processList.end();
+ ++it )
+ {
+ if( !(*it)->isRunning())
+ continue;
+ wd.pid = waitpid( (*it)->pid(), &wd.status, WNOHANG );
+ if ( wd.pid > 0 ) {
+ ::write(theKProcessController->fd[1], &wd, sizeof(wd));
+ found = true;
+ }
+ }
+ }
+ if( !found && oldChildHandlerData.sa_handler != SIG_IGN
+ && oldChildHandlerData.sa_handler != SIG_DFL )
+ oldChildHandlerData.sa_handler( arg ); // call the old handler
+ // handle the rest
+ if( theKProcessController != 0 ) {
+ static const struct waitdata dwd = { 0, 0 }; // delayed waitpid()
+ ::write(theKProcessController->fd[1], &dwd, sizeof(dwd));
+ } else {
+ int dummy;
+ while( waitpid( -1, &dummy, WNOHANG ) > 0 )
+ ;
+ }
+
+ errno = saved_errno;
+}
+
+
+
+void KProcessController::slotDoHousekeeping(int )
+{
+ unsigned int bytes_read = 0;
+ unsigned int errcnt=0;
+ // read pid and status from the pipe.
+ struct waitdata wd;
+ while ((bytes_read < sizeof(wd)) && (errcnt < 50)) {
+ int r = ::read(fd[0], ((char *)&wd) + bytes_read, sizeof(wd) - bytes_read);
+ if (r > 0) bytes_read += r;
+ else if (r < 0) errcnt++;
+ }
+ if (errcnt >= 50) {
+ fprintf(stderr,
+ "Error: Max. error count for pipe read "
+ "exceeded in KProcessController::slotDoHousekeeping\n");
+ return; // it makes no sense to continue here!
+ }
+ if (bytes_read != sizeof(wd)) {
+ fprintf(stderr,
+ "Error: Could not read info from signal handler %d <> %d!\n",
+ bytes_read, sizeof(wd));
+ return; // it makes no sense to continue here!
+ }
+ if (wd.pid==0) { // special case, see delayedChildrenCleanup()
+ delayedChildrenCleanupTimer.start( 1000, true );
+ return;
+ }
+
+ for( QValueList<KProcess*>::ConstIterator it = processList.begin();
+ it != processList.end();
+ ++it ) {
+ KProcess* proc = *it;
+ if (proc->pid() == wd.pid) {
+ // process has exited, so do emit the respective events
+ if (proc->run_mode == KProcess::Block) {
+ // If the reads are done blocking then set the status in proc
+ // but do nothing else because KProcess will perform the other
+ // actions of processHasExited.
+ proc->status = wd.status;
+ proc->runs = false;
+ } else {
+ proc->processHasExited(wd.status);
+ }
+ return;
+ }
+ }
+}
+
+// this is needed e.g. for popen(), which calls waitpid() checking
+// for its forked child, if we did waitpid() directly in the SIGCHLD
+// handler, popen()'s waitpid() call would fail
+void KProcessController::delayedChildrenCleanup()
+{
+ struct waitdata wd;
+ while(( wd.pid = waitpid( -1, &wd.status, WNOHANG ) ) > 0 ) {
+ for( QValueList<KProcess*>::ConstIterator it = processList.begin();
+ it != processList.end();
+ ++it )
+ {
+ if( !(*it)->isRunning() || (*it)->pid() != wd.pid )
+ continue;
+ // it's KProcess, handle it
+ ::write(fd[1], &wd, sizeof(wd));
+ break;
+ }
+ }
+}
+
+KProcessController::~KProcessController()
+{
+ assert( theKProcessController == this );
+ resetHandlers();
+
+ notifier->setEnabled(false);
+
+ close(fd[0]);
+ close(fd[1]);
+
+ delete notifier;
+ theKProcessController = 0;
+}
+
+//#include "kprocctrl.moc"
diff --git a/noncore/settings/networksettings/kprocctrl.h b/noncore/settings/networksettings/kprocctrl.h
new file mode 100644
index 0000000..ac82b9d
--- a/dev/null
+++ b/noncore/settings/networksettings/kprocctrl.h
@@ -0,0 +1,120 @@
+/* This file is part of the KDE libraries
+ Copyright (C) 1997 Christian Czezakte (e9025461@student.tuwien.ac.at)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+//
+// KPROCESSCONTROLLER -- A helper class for KProcess
+//
+// version 0.3.1, Jan 8th 1997
+//
+// (C) Christian Czezatke
+// e9025461@student.tuwien.ac.at
+//
+
+#ifndef __KPROCCTRL_H__
+#define __KPROCCTRL_H__
+
+#include <qvaluelist.h>
+#include <qtimer.h>
+
+#include "kprocess.h"
+
+class KProcessControllerPrivate;
+class QSocketNotifier;
+
+/**
+ * @short Used internally by @ref KProcess
+ * @internal
+ * @author Christian Czezakte <e9025461@student.tuwien.ac.at>
+ *
+ * A class for internal use by KProcess only. -- Exactly one instance
+ * of this class is generated by the first instance of KProcess that is
+ * created (a pointer to it gets stored in @ref theKProcessController ).
+ *
+ * This class takes care of the actual (UN*X) signal handling.
+*/
+class KProcessController : public QObject
+{
+ Q_OBJECT
+
+public:
+ KProcessController();
+ ~KProcessController();
+ //CC: WARNING! Destructor Not virtual (but you don't derive classes from this anyhow...)
+
+public:
+
+ /**
+ * Only a single instance of this class is allowed at a time,
+ * and this static variable is used to track the one instance.
+ */
+ static KProcessController *theKProcessController;
+
+ /**
+ * Automatically called upon SIGCHLD.
+ *
+ * Normally you do not need to do anything with this function but
+ * if your application needs to disable SIGCHLD for some time for
+ * reasons beyond your control, you should call this function afterwards
+ * to make sure that no SIGCHLDs where missed.
+ */
+ static void theSigCHLDHandler(int signal);
+ // handler for sigchld
+
+ /**
+ * @internal
+ */
+ static void setupHandlers();
+ /**
+ * @internal
+ */
+ static void resetHandlers();
+ /**
+ * @internal
+ */
+ void addKProcess( KProcess* );
+ /**
+ * @internal
+ */
+ void removeKProcess( KProcess* );
+ public slots:
+ /**
+ * @internal
+ */
+ void slotDoHousekeeping(int socket);
+
+ private slots:
+ void delayedChildrenCleanup();
+private:
+ int fd[2];
+ QSocketNotifier *notifier;
+ static struct sigaction oldChildHandlerData;
+ static bool handlerSet;
+ QValueList<KProcess*> processList;
+ QTimer delayedChildrenCleanupTimer;
+
+ // Disallow assignment and copy-construction
+ KProcessController( const KProcessController& );
+ KProcessController& operator= ( const KProcessController& );
+
+ KProcessControllerPrivate *d;
+};
+
+
+
+#endif
+
diff --git a/noncore/settings/networksettings/kprocess.cpp b/noncore/settings/networksettings/kprocess.cpp
new file mode 100644
index 0000000..193ec9b
--- a/dev/null
+++ b/noncore/settings/networksettings/kprocess.cpp
@@ -0,0 +1,919 @@
+/*
+
+ $Id$
+
+ This file is part of the KDE libraries
+ Copyright (C) 1997 Christian Czezatke (e9025461@student.tuwien.ac.at)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+
+//
+// KPROCESS -- A class for handling child processes in KDE without
+// having to take care of Un*x specific implementation details
+//
+// version 0.3.1, Jan 8th 1998
+//
+// (C) Christian Czezatke
+// e9025461@student.tuwien.ac.at
+//
+// Changes:
+//
+// March 2nd, 1998: Changed parameter list for KShellProcess:
+// Arguments are now placed in a single string so that
+// <shell> -c <commandstring> is passed to the shell
+// to make the use of "operator<<" consistent with KProcess
+
+#include "kprocess.h"
+#define _MAY_INCLUDE_KPROCESSCONTROLLER_
+#include "kprocctrl.h"
+
+//#include <config.h>
+
+#include <qglobal.h>
+#include <qmap.h>
+#include <qfile.h>
+#include <qsocketnotifier.h>
+#include <qregexp.h>
+
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#ifdef HAVE_INITGROUPS
+#include <grp.h>
+#endif
+#include <pwd.h>
+
+#include <qapplication.h>
+//#include <kdebug.h>
+
+/////////////////////////////
+// public member functions //
+/////////////////////////////
+
+class KProcessPrivate {
+public:
+ KProcessPrivate() : useShell(false) { }
+
+ bool useShell;
+ QMap<QString,QString> env;
+ QString wd;
+ QCString shell;
+};
+
+#define Q_CHECK_PTR(a)
+
+KProcess::KProcess()
+ : QObject(),
+ run_mode(NotifyOnExit),
+ runs(false),
+ pid_(0),
+ status(0),
+ keepPrivs(false),
+ innot(0),
+ outnot(0),
+ errnot(0),
+ communication(NoCommunication),
+ input_data(0),
+ input_sent(0),
+ input_total(0),
+ d(0)
+{
+ if (0 == KProcessController::theKProcessController) {
+ (void) new KProcessController();
+ Q_CHECK_PTR(KProcessController::theKProcessController);
+ }
+
+ KProcessController::theKProcessController->addKProcess(this);
+ out[0] = out[1] = -1;
+ in[0] = in[1] = -1;
+ err[0] = err[1] = -1;
+}
+
+void
+KProcess::setEnvironment(const QString &name, const QString &value)
+{
+ if (!d)
+ d = new KProcessPrivate;
+ d->env.insert(name, value);
+}
+
+void
+KProcess::setWorkingDirectory(const QString &dir)
+{
+ if (!d)
+ d = new KProcessPrivate;
+ d->wd = dir;
+}
+
+void
+KProcess::setupEnvironment()
+{
+ if (d)
+ {
+ QMap<QString,QString>::Iterator it;
+ for(it = d->env.begin(); it != d->env.end(); ++it)
+ setenv(QFile::encodeName(it.key()).data(),
+ QFile::encodeName(it.data()).data(), 1);
+ if (!d->wd.isEmpty())
+ chdir(QFile::encodeName(d->wd).data());
+ }
+}
+
+void
+KProcess::setRunPrivileged(bool keepPrivileges)
+{
+ keepPrivs = keepPrivileges;
+}
+
+bool
+KProcess::runPrivileged() const
+{
+ return keepPrivs;
+}
+
+
+KProcess::~KProcess()
+{
+ // destroying the KProcess instance sends a SIGKILL to the
+ // child process (if it is running) after removing it from the
+ // list of valid processes (if the process is not started as
+ // "DontCare")
+
+ KProcessController::theKProcessController->removeKProcess(this);
+ // this must happen before we kill the child
+ // TODO: block the signal while removing the current process from the process list
+
+ if (runs && (run_mode != DontCare))
+ kill(SIGKILL);
+
+ // Clean up open fd's and socket notifiers.
+ closeStdin();
+ closeStdout();
+ closeStderr();
+
+ // TODO: restore SIGCHLD and SIGPIPE handler if this is the last KProcess
+ delete d;
+}
+
+void KProcess::detach()
+{
+ KProcessController::theKProcessController->removeKProcess(this);
+
+ runs = false;
+ pid_ = 0;
+
+ // Clean up open fd's and socket notifiers.
+ closeStdin();
+ closeStdout();
+ closeStderr();
+}
+
+bool KProcess::setExecutable(const QString& proc)
+{
+ if (runs) return false;
+
+ if (proc.isEmpty()) return false;
+
+ if (!arguments.isEmpty())
+ arguments.remove(arguments.begin());
+ arguments.prepend(QFile::encodeName(proc));
+
+ return true;
+}
+
+KProcess &KProcess::operator<<(const QStringList& args)
+{
+ QStringList::ConstIterator it = args.begin();
+ for ( ; it != args.end() ; ++it )
+ arguments.append(QFile::encodeName(*it));
+ return *this;
+}
+
+KProcess &KProcess::operator<<(const QCString& arg)
+{
+ return operator<< (arg.data());
+}
+
+KProcess &KProcess::operator<<(const char* arg)
+{
+ arguments.append(arg);
+ return *this;
+}
+
+KProcess &KProcess::operator<<(const QString& arg)
+{
+ arguments.append(QFile::encodeName(arg));
+ return *this;
+}
+
+void KProcess::clearArguments()
+{
+ arguments.clear();
+}
+
+bool KProcess::start(RunMode runmode, Communication comm)
+{
+ uint i;
+ uint n = arguments.count();
+ char **arglist;
+
+ if (runs || (0 == n)) {
+ return false; // cannot start a process that is already running
+ // or if no executable has been assigned
+ }
+ run_mode = runmode;
+ status = 0;
+
+ QCString shellCmd;
+ if (d && d->useShell)
+ {
+ if (d->shell.isEmpty())
+ {
+ //kdDebug() << "Could not find a valid shell\n" << endl;
+ return false;
+ }
+
+ arglist = static_cast<char **>(malloc( (4)*sizeof(char *)));
+ for (i=0; i < n; i++) {
+ shellCmd += arguments[i];
+ shellCmd += " "; // CC: to separate the arguments
+ }
+
+ arglist[0] = d->shell.data();
+ arglist[1] = (char *) "-c";
+ arglist[2] = shellCmd.data();
+ arglist[3] = 0;
+ }
+ else
+ {
+ arglist = static_cast<char **>(malloc( (n+1)*sizeof(char *)));
+ for (i=0; i < n; i++)
+ arglist[i] = arguments[i].data();
+ arglist[n]= 0;
+ }
+
+ setupCommunication(comm);
+ //)
+ //kdDebug() << "Could not setup Communication!\n";
+
+ // We do this in the parent because if we do it in the child process
+ // gdb gets confused when the application runs from gdb.
+ uid_t uid = getuid();
+ gid_t gid = getgid();
+#ifdef HAVE_INITGROUPS
+ struct passwd *pw = getpwuid(uid);
+#endif
+
+ int fd[2];
+ if (0 > pipe(fd))
+ {
+ fd[0] = fd[1] = 0; // Pipe failed.. continue
+ }
+
+ runs = true;
+
+ QApplication::flushX();
+
+ // WABA: Note that we use fork() and not vfork() because
+ // vfork() has unclear semantics and is not standardized.
+ pid_ = fork();
+
+ if (0 == pid_) {
+ if (fd[0])
+ close(fd[0]);
+ if (!runPrivileged())
+ {
+ setgid(gid);
+#if defined( HAVE_INITGROUPS)
+ if(pw)
+ initgroups(pw->pw_name, pw->pw_gid);
+#endif
+ setuid(uid);
+ }
+ // The child process
+ commSetupDoneC();
+ //)
+ //kdDebug() << "Could not finish comm setup in child!" << endl;
+
+ setupEnvironment();
+
+ // Matthias
+ if (run_mode == DontCare)
+ setpgid(0,0);
+ // restore default SIGPIPE handler (Harri)
+ struct sigaction act;
+ sigemptyset(&(act.sa_mask));
+ sigaddset(&(act.sa_mask), SIGPIPE);
+ act.sa_handler = SIG_DFL;
+ act.sa_flags = 0;
+ sigaction(SIGPIPE, &act, 0L);
+
+ // We set the close on exec flag.
+ // Closing of fd[1] indicates that the execvp succeeded!
+ if (fd[1])
+ fcntl(fd[1], F_SETFD, FD_CLOEXEC);
+ execvp(arglist[0], arglist);
+ char resultByte = 1;
+ if (fd[1])
+ write(fd[1], &resultByte, 1);
+ _exit(-1);
+ } else if (-1 == pid_) {
+ // forking failed
+
+ runs = false;
+ free(arglist);
+ return false;
+ } else {
+ if (fd[1])
+ close(fd[1]);
+ // the parent continues here
+
+ // Discard any data for stdin that might still be there
+ input_data = 0;
+
+ // Check whether client could be started.
+ if (fd[0]) for(;;)
+ {
+ char resultByte;
+ int n = ::read(fd[0], &resultByte, 1);
+ if (n == 1)
+ {
+ // Error
+ runs = false;
+ close(fd[0]);
+ free(arglist);
+ pid_ = 0;
+ return false;
+ }
+ if (n == -1)
+ {
+ if ((errno == ECHILD) || (errno == EINTR))
+ continue; // Ignore
+ }
+ break; // success
+ }
+ if (fd[0])
+ close(fd[0]);
+
+ if (!commSetupDoneP()){} // finish communication socket setup for the parent
+ //kdDebug() << "Could not finish comm setup in parent!" << endl;
+
+ if (run_mode == Block) {
+ commClose();
+
+ // The SIGCHLD handler of the process controller will catch
+ // the exit and set the status
+ while(runs)
+ {
+ KProcessController::theKProcessController->
+ slotDoHousekeeping(0);
+ }
+ runs = FALSE;
+ emit processExited(this);
+ }
+ }
+ free(arglist);
+ return true;
+}
+
+
+
+bool KProcess::kill(int signo)
+{
+ bool rv=false;
+
+ if (0 != pid_)
+ rv= (-1 != ::kill(pid_, signo));
+ // probably store errno somewhere...
+ return rv;
+}
+
+
+
+bool KProcess::isRunning() const
+{
+ return runs;
+}
+
+
+
+pid_t KProcess::pid() const
+{
+ return pid_;
+}
+
+
+
+bool KProcess::normalExit() const
+{
+ int _status = status;
+ return (pid_ != 0) && (!runs) && (WIFEXITED((_status)));
+}
+
+
+
+int KProcess::exitStatus() const
+{
+ int _status = status;
+ return WEXITSTATUS((_status));
+}
+
+
+
+bool KProcess::writeStdin(const char *buffer, int buflen)
+{
+ bool rv;
+
+ // if there is still data pending, writing new data
+ // to stdout is not allowed (since it could also confuse
+ // kprocess...
+ if (0 != input_data)
+ return false;
+
+ if (runs && (communication & Stdin)) {
+ input_data = buffer;
+ input_sent = 0;
+ input_total = buflen;
+ slotSendData(0);
+ innot->setEnabled(true);
+ rv = true;
+ } else
+ rv = false;
+ return rv;
+}
+
+void KProcess::suspend()
+{
+ if ((communication & Stdout) && outnot)
+ outnot->setEnabled(false);
+}
+
+void KProcess::resume()
+{
+ if ((communication & Stdout) && outnot)
+ outnot->setEnabled(true);
+}
+
+bool KProcess::closeStdin()
+{
+ bool rv;
+
+ if (communication & Stdin) {
+ communication = (Communication) (communication & ~Stdin);
+ delete innot;
+ innot = 0;
+ close(in[1]);
+ rv = true;
+ } else
+ rv = false;
+ return rv;
+}
+
+bool KProcess::closeStdout()
+{
+ bool rv;
+
+ if (communication & Stdout) {
+ communication = (Communication) (communication & ~Stdout);
+ delete outnot;
+ outnot = 0;
+ close(out[0]);
+ rv = true;
+ } else
+ rv = false;
+ return rv;
+}
+
+bool KProcess::closeStderr()
+{
+ bool rv;
+
+ if (communication & Stderr) {
+ communication = static_cast<Communication>(communication & ~Stderr);
+ delete errnot;
+ errnot = 0;
+ close(err[0]);
+ rv = true;
+ } else
+ rv = false;
+ return rv;
+}
+
+
+/////////////////////////////
+// protected slots //
+/////////////////////////////
+
+
+
+void KProcess::slotChildOutput(int fdno)
+{
+ if (!childOutput(fdno))
+ closeStdout();
+}
+
+
+void KProcess::slotChildError(int fdno)
+{
+ if (!childError(fdno))
+ closeStderr();
+}
+
+
+void KProcess::slotSendData(int)
+{
+ if (input_sent == input_total) {
+ innot->setEnabled(false);
+ input_data = 0;
+ emit wroteStdin(this);
+ } else
+ input_sent += ::write(in[1], input_data+input_sent, input_total-input_sent);
+}
+
+
+
+//////////////////////////////
+// private member functions //
+//////////////////////////////
+
+
+
+void KProcess::processHasExited(int state)
+{
+ if (runs)
+ {
+ runs = false;
+ status = state;
+
+ commClose(); // cleanup communication sockets
+
+ // also emit a signal if the process was run Blocking
+ if (DontCare != run_mode)
+ {
+ emit processExited(this);
+ }
+ }
+}
+
+
+
+int KProcess::childOutput(int fdno)
+{
+ if (communication & NoRead) {
+ int len = -1;
+ emit receivedStdout(fdno, len);
+ errno = 0; // Make sure errno doesn't read "EAGAIN"
+ return len;
+ }
+ else
+ {
+ char buffer[1024];
+ int len;
+
+ len = ::read(fdno, buffer, 1024);
+
+ if ( 0 < len) {
+ emit receivedStdout(this, buffer, len);
+ }
+ return len;
+ }
+}
+
+
+
+int KProcess::childError(int fdno)
+{
+ char buffer[1024];
+ int len;
+
+ len = ::read(fdno, buffer, 1024);
+
+ if ( 0 < len)
+ emit receivedStderr(this, buffer, len);
+ return len;
+}
+
+
+
+int KProcess::setupCommunication(Communication comm)
+{
+ int ok;
+
+ communication = comm;
+
+ ok = 1;
+ if (comm & Stdin)
+ ok &= socketpair(AF_UNIX, SOCK_STREAM, 0, in) >= 0;
+
+ if (comm & Stdout)
+ ok &= socketpair(AF_UNIX, SOCK_STREAM, 0, out) >= 0;
+
+ if (comm & Stderr)
+ ok &= socketpair(AF_UNIX, SOCK_STREAM, 0, err) >= 0;
+
+ return ok;
+}
+
+
+
+int KProcess::commSetupDoneP()
+{
+ int ok = 1;
+
+ if (communication != NoCommunication) {
+ if (communication & Stdin)
+ close(in[0]);
+ if (communication & Stdout)
+ close(out[1]);
+ if (communication & Stderr)
+ close(err[1]);
+
+ // Don't create socket notifiers and set the sockets non-blocking if
+ // blocking is requested.
+ if (run_mode == Block) return ok;
+
+ if (communication & Stdin) {
+// ok &= (-1 != fcntl(in[1], F_SETFL, O_NONBLOCK));
+ innot = new QSocketNotifier(in[1], QSocketNotifier::Write, this);
+ Q_CHECK_PTR(innot);
+ innot->setEnabled(false); // will be enabled when data has to be sent
+ QObject::connect(innot, SIGNAL(activated(int)),
+ this, SLOT(slotSendData(int)));
+ }
+
+ if (communication & Stdout) {
+// ok &= (-1 != fcntl(out[0], F_SETFL, O_NONBLOCK));
+ outnot = new QSocketNotifier(out[0], QSocketNotifier::Read, this);
+ Q_CHECK_PTR(outnot);
+ QObject::connect(outnot, SIGNAL(activated(int)),
+ this, SLOT(slotChildOutput(int)));
+ if (communication & NoRead)
+ suspend();
+ }
+
+ if (communication & Stderr) {
+// ok &= (-1 != fcntl(err[0], F_SETFL, O_NONBLOCK));
+ errnot = new QSocketNotifier(err[0], QSocketNotifier::Read, this );
+ Q_CHECK_PTR(errnot);
+ QObject::connect(errnot, SIGNAL(activated(int)),
+ this, SLOT(slotChildError(int)));
+ }
+ }
+ return ok;
+}
+
+
+
+int KProcess::commSetupDoneC()
+{
+ int ok = 1;
+ struct linger so;
+ memset(&so, 0, sizeof(so));
+
+ if (communication & Stdin)
+ close(in[1]);
+ if (communication & Stdout)
+ close(out[0]);
+ if (communication & Stderr)
+ close(err[0]);
+
+ if (communication & Stdin)
+ ok &= dup2(in[0], STDIN_FILENO) != -1;
+ else {
+ int null_fd = open( "/dev/null", O_RDONLY );
+ ok &= dup2( null_fd, STDIN_FILENO ) != -1;
+ close( null_fd );
+ }
+ if (communication & Stdout) {
+ ok &= dup2(out[1], STDOUT_FILENO) != -1;
+ ok &= !setsockopt(out[1], SOL_SOCKET, SO_LINGER, (char*)&so, sizeof(so));
+ }
+ else {
+ int null_fd = open( "/dev/null", O_WRONLY );
+ ok &= dup2( null_fd, STDOUT_FILENO ) != -1;
+ close( null_fd );
+ }
+ if (communication & Stderr) {
+ ok &= dup2(err[1], STDERR_FILENO) != -1;
+ ok &= !setsockopt(err[1], SOL_SOCKET, SO_LINGER, reinterpret_cast<char *>(&so), sizeof(so));
+ }
+ else {
+ int null_fd = open( "/dev/null", O_WRONLY );
+ ok &= dup2( null_fd, STDERR_FILENO ) != -1;
+ close( null_fd );
+ }
+ return ok;
+}
+
+
+
+void KProcess::commClose()
+{
+ if (NoCommunication != communication) {
+ bool b_in = (communication & Stdin);
+ bool b_out = (communication & Stdout);
+ bool b_err = (communication & Stderr);
+ if (b_in)
+ delete innot;
+
+ if (b_out || b_err) {
+ // If both channels are being read we need to make sure that one socket buffer
+ // doesn't fill up whilst we are waiting for data on the other (causing a deadlock).
+ // Hence we need to use select.
+
+ // Once one or other of the channels has reached EOF (or given an error) go back
+ // to the usual mechanism.
+
+ int fds_ready = 1;
+ fd_set rfds;
+
+ int max_fd = 0;
+ if (b_out) {
+ fcntl(out[0], F_SETFL, O_NONBLOCK);
+ if (out[0] > max_fd)
+ max_fd = out[0];
+ delete outnot;
+ outnot = 0;
+ }
+ if (b_err) {
+ fcntl(err[0], F_SETFL, O_NONBLOCK);
+ if (err[0] > max_fd)
+ max_fd = err[0];
+ delete errnot;
+ errnot = 0;
+ }
+
+
+ while (b_out || b_err) {
+ // * If the process is still running we block until we
+ // receive data. (p_timeout = 0, no timeout)
+ // * If the process has already exited, we only check
+ // the available data, we don't wait for more.
+ // (p_timeout = &timeout, timeout immediately)
+ struct timeval timeout;
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 0;
+ struct timeval *p_timeout = runs ? 0 : &timeout;
+
+ FD_ZERO(&rfds);
+ if (b_out)
+ FD_SET(out[0], &rfds);
+
+ if (b_err)
+ FD_SET(err[0], &rfds);
+
+ fds_ready = select(max_fd+1, &rfds, 0, 0, p_timeout);
+ if (fds_ready <= 0) break;
+
+ if (b_out && FD_ISSET(out[0], &rfds)) {
+ int ret = 1;
+ while (ret > 0) ret = childOutput(out[0]);
+ if ((ret == -1 && errno != EAGAIN) || ret == 0)
+ b_out = false;
+ }
+
+ if (b_err && FD_ISSET(err[0], &rfds)) {
+ int ret = 1;
+ while (ret > 0) ret = childError(err[0]);
+ if ((ret == -1 && errno != EAGAIN) || ret == 0)
+ b_err = false;
+ }
+ }
+ }
+
+ if (b_in) {
+ communication = (Communication) (communication & ~Stdin);
+ close(in[1]);
+ }
+ if (b_out) {
+ communication = (Communication) (communication & ~Stdout);
+ close(out[0]);
+ }
+ if (b_err) {
+ communication = (Communication) (communication & ~Stderr);
+ close(err[0]);
+ }
+ }
+}
+
+void KProcess::setUseShell(bool useShell, const char *shell)
+{
+ if (!d)
+ d = new KProcessPrivate;
+ d->useShell = useShell;
+ d->shell = shell;
+ if (d->shell.isEmpty())
+ d->shell = searchShell();
+}
+
+QString KProcess::quote(const QString &arg)
+{
+ QString res = arg;
+ res.replace(QRegExp(QString::fromLatin1("\'")),
+ QString::fromLatin1("'\"'\"'"));
+ res.prepend('\'');
+ res.append('\'');
+ return res;
+}
+
+QCString KProcess::searchShell()
+{
+ QCString tmpShell = QCString(getenv("SHELL")).stripWhiteSpace();
+ if (!isExecutable(tmpShell))
+ {
+ tmpShell = "/bin/sh";
+ }
+
+ return tmpShell;
+}
+
+bool KProcess::isExecutable(const QCString &filename)
+{
+ struct stat fileinfo;
+
+ if (filename.isEmpty()) return false;
+
+ // CC: we've got a valid filename, now let's see whether we can execute that file
+
+ if (-1 == stat(filename.data(), &fileinfo)) return false;
+ // CC: return false if the file does not exist
+
+ // CC: anyway, we cannot execute directories, block/character devices, fifos or sockets
+ if ( (S_ISDIR(fileinfo.st_mode)) ||
+ (S_ISCHR(fileinfo.st_mode)) ||
+ (S_ISBLK(fileinfo.st_mode)) ||
+#ifdef S_ISSOCK
+ // CC: SYSVR4 systems don't have that macro
+ (S_ISSOCK(fileinfo.st_mode)) ||
+#endif
+ (S_ISFIFO(fileinfo.st_mode)) ||
+ (S_ISDIR(fileinfo.st_mode)) ) {
+ return false;
+ }
+
+ // CC: now check for permission to execute the file
+ if (access(filename.data(), X_OK) != 0) return false;
+
+ // CC: we've passed all the tests...
+ return true;
+}
+
+void KProcess::virtual_hook( int, void* )
+{ /*BASE::virtual_hook( id, data );*/ }
+
+
+///////////////////////////
+// CC: Class KShellProcess
+///////////////////////////
+
+KShellProcess::KShellProcess(const char *shellname):
+ KProcess()
+{
+ setUseShell(true, shellname);
+}
+
+
+KShellProcess::~KShellProcess() {
+}
+
+QString KShellProcess::quote(const QString &arg)
+{
+ return KProcess::quote(arg);
+}
+
+bool KShellProcess::start(RunMode runmode, Communication comm)
+{
+ return KProcess::start(runmode, comm);
+}
+
+void KShellProcess::virtual_hook( int id, void* data )
+{ KProcess::virtual_hook( id, data ); }
+
+//#include "kprocess.moc"
diff --git a/noncore/settings/networksettings/kprocess.h b/noncore/settings/networksettings/kprocess.h
new file mode 100644
index 0000000..e70f7e7
--- a/dev/null
+++ b/noncore/settings/networksettings/kprocess.h
@@ -0,0 +1,804 @@
+/* This file is part of the KDE libraries
+ Copyright (C) 1997 Christian Czezakte (e9025461@student.tuwien.ac.at)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+//
+// KPROCESS -- A class for handling child processes in KDE without
+// having to take care of Un*x specific implementation details
+//
+// version 0.3.1, Jan 8th 1998
+//
+// (C) Christian Czezatke
+// e9025461@student.tuwien.ac.at
+//
+
+#ifndef __kprocess_h__
+#define __kprocess_h__
+
+#include <sys/types.h> // for pid_t
+#include <sys/wait.h>
+#include <signal.h>
+#include <unistd.h>
+#include <qvaluelist.h>
+#include <qcstring.h>
+#include <qobject.h>
+
+class QSocketNotifier;
+class KProcessPrivate;
+
+/**
+ * Child process invocation, monitoring and control.
+ *
+ * @sect General usage and features
+ *
+ *This class allows a KDE application to start child processes without having
+ *to worry about UN*X signal handling issues and zombie process reaping.
+ *
+ *@see KProcIO
+ *
+ *Basically, this class distinguishes three different ways of running
+ *child processes:
+ *
+ *@li KProcess::DontCare -- The child process is invoked and both the child
+ *process and the parent process continue concurrently.
+ *
+ *Starting a DontCare child process means that the application is
+ *not interested in any notification to determine whether the
+ *child process has already exited or not.
+ *
+ *@li KProcess::NotifyOnExit -- The child process is invoked and both the
+ *child and the parent process run concurrently.
+ *
+ *When the child process exits, the KProcess instance
+ *corresponding to it emits the Qt signal @ref processExited().
+ *
+ *Since this signal is @em not emitted from within a UN*X
+ *signal handler, arbitrary function calls can be made.
+ *
+ *Be aware: When the KProcess objects gets destructed, the child
+ *process will be killed if it is still running!
+ *This means in particular, that you cannot use a KProcess on the stack
+ *with KProcess::NotifyOnExit.
+ *
+ *@li KProcess::Block -- The child process starts and the parent process
+ *is suspended until the child process exits. (@em Really not recommended
+ *for programs with a GUI.)
+ *
+ *KProcess also provides several functions for determining the exit status
+ *and the pid of the child process it represents.
+ *
+ *Furthermore it is possible to supply command-line arguments to the process
+ *in a clean fashion (no null -- terminated stringlists and such...)
+ *
+ *A small usage example:
+ *<pre>
+ *KProcess *proc = new KProcess;
+ *
+ **proc << "my_executable";
+ **proc << "These" << "are" << "the" << "command" << "line" << "args";
+ *QApplication::connect(proc, SIGNAL(processExited(KProcess *)),
+ * pointer_to_my_object, SLOT(my_objects_slot(KProcess *)));
+ *proc->start();
+ *</pre>
+ *
+ *This will start "my_executable" with the commandline arguments "These"...
+ *
+ *When the child process exits, the respective Qt signal will be emitted.
+ *
+ *@sect Communication with the child process
+ *
+ *KProcess supports communication with the child process through
+ *stdin/stdout/stderr.
+ *
+ *The following functions are provided for getting data from the child
+ *process or sending data to the child's stdin (For more information,
+ *have a look at the documentation of each function):
+ *
+ *@li bool @ref writeStdin(char *buffer, int buflen);
+ *@li -- Transmit data to the child process's stdin.
+ *
+ *@li bool @ref closeStdin();
+ *@li -- Closes the child process's stdin (which causes it to see an feof(stdin)).
+ *Returns false if you try to close stdin for a process that has been started
+ *without a communication channel to stdin.
+ *
+ *@li bool @ref closeStdout();
+ *@li -- Closes the child process's stdout.
+ *Returns false if you try to close stdout for a process that has been started
+ *without a communication channel to stdout.
+ *
+ *@li bool @ref closeStderr();
+ *@li -- Closes the child process's stderr.
+ *Returns false if you try to close stderr for a process that has been started
+ *without a communication channel to stderr.
+ *
+ *
+ *@sect QT signals:
+ *
+ *@li void @ref receivedStdout(KProcess *proc, char *buffer, int buflen);
+ *@li void @ref receivedStderr(KProcess *proc, char *buffer, int buflen);
+ *@li -- Indicates that new data has arrived from either the
+ *child process's stdout or stderr.
+ *
+ *@li void @ref wroteStdin(KProcess *proc);
+ *@li -- Indicates that all data that has been sent to the child process
+ *by a prior call to @ref writeStdin() has actually been transmitted to the
+ *client .
+ *
+ *@author Christian Czezakte e9025461@student.tuwien.ac.at
+ *
+ *
+ **/
+class KProcess : public QObject
+{
+ Q_OBJECT
+
+public:
+
+ /**
+ * Modes in which the communication channel can be opened.
+ *
+ * If communication for more than one channel is required,
+ * the values have to be or'ed together, for example to get
+ * communication with stdout as well as with stdin, you would
+ * specify @p Stdin @p | @p Stdout
+ *
+ * If @p NoRead is specified in conjunction with @p Stdout,
+ * no data is actually read from @p Stdout but only
+ * the signal @ref childOutput(int fd) is emitted.
+ */
+ enum Communication { NoCommunication = 0, Stdin = 1, Stdout = 2, Stderr = 4,
+ AllOutput = 6, All = 7,
+ NoRead };
+
+ /**
+ * Run-modes for a child process.
+ */
+ enum RunMode {
+ /**
+ * The application does not receive notifications from the subprocess when
+ * it is finished or aborted.
+ */
+ DontCare,
+ /**
+ * The application is notified when the subprocess dies.
+ */
+ NotifyOnExit,
+ /**
+ * The application is suspended until the started process is finished.
+ */
+ Block };
+
+ /**
+ * Constructor
+ */
+ KProcess();
+
+ /**
+ *Destructor:
+ *
+ * If the process is running when the destructor for this class
+ * is called, the child process is killed with a SIGKILL, but
+ * only if the run mode is not of type @p DontCare.
+ * Processes started as @p DontCare keep running anyway.
+ */
+ virtual ~KProcess();
+
+ /**
+ @deprecated
+
+ The use of this function is now deprecated. -- Please use the
+ "operator<<" instead of "setExecutable".
+
+ Sets the executable to be started with this KProcess object.
+ Returns false if the process is currently running (in that
+ case the executable remains unchanged.)
+
+ @see operator<<
+
+ */
+ bool setExecutable(const QString& proc);
+
+
+ /**
+ * Sets the executable and the command line argument list for this process.
+ *
+ * For example, doing an "ls -l /usr/local/bin" can be achieved by:
+ * <pre>
+ * KProcess p;
+ * ...
+ * p << "ls" << "-l" << "/usr/local/bin"
+ * </pre>
+ *
+ **/
+ KProcess &operator<<(const QString& arg);
+ /**
+ * Similar to previous method, takes a char *, supposed to be in locale 8 bit already.
+ */
+ KProcess &operator<<(const char * arg);
+ /**
+ * Similar to previous method, takes a QCString, supposed to be in locale 8 bit already.
+ */
+ KProcess &operator<<(const QCString & arg);
+
+ /**
+ * Sets the executable and the command line argument list for this process,
+ * in a single method call, or add a list of arguments.
+ **/
+ KProcess &operator<<(const QStringList& args);
+
+ /**
+ * Clear a command line argument list that has been set by using
+ * the "operator<<".
+ */
+ void clearArguments();
+
+ /**
+ * Starts the process.
+ * For a detailed description of the
+ * various run modes and communication semantics, have a look at the
+ * general description of the KProcess class.
+ *
+ * The following problems could cause this function to
+ * return false:
+ *
+ * @li The process is already running.
+ * @li The command line argument list is empty.
+ * @li The starting of the process failed (could not fork).
+ * @li The executable was not found.
+ *
+ * @param comm Specifies which communication links should be
+ * established to the child process (stdin/stdout/stderr). By default,
+ * no communication takes place and the respective communication
+ * signals will never get emitted.
+ *
+ * @return true on success, false on error
+ * (see above for error conditions)
+ **/
+ virtual bool start(RunMode runmode = NotifyOnExit,
+ Communication comm = NoCommunication);
+
+ /**
+ * Stop the process (by sending it a signal).
+ *
+ * @param signo The signal to send. The default is SIGTERM.
+ * @return @p true if the signal was delivered successfully.
+ */
+ virtual bool kill(int signo = SIGTERM);
+
+ /**
+ @return @p true if the process is (still) considered to be running
+ */
+ bool isRunning() const;
+
+ /** Returns the process id of the process.
+ *
+ * If it is called after
+ * the process has exited, it returns the process id of the last
+ * child process that was created by this instance of KProcess.
+ *
+ * Calling it before any child process has been started by this
+ * KProcess instance causes pid() to return 0.
+ **/
+ pid_t pid() const;
+
+ /**
+ * Use pid().
+ * @deprecated
+ */
+ pid_t getPid() const { return pid(); }
+
+ /**
+ * Suspend processing of data from stdout of the child process.
+ */
+ void suspend();
+
+ /**
+ * Resume processing of data from stdout of the child process.
+ */
+ void resume();
+
+ /**
+ * @return @p true if the process has already finished and has exited
+ * "voluntarily", ie: it has not been killed by a signal.
+ *
+ * Note that you should check @ref KProcess::exitStatus() to determine
+ * whether the process completed its task successful or not.
+ */
+ bool normalExit() const;
+
+ /**
+ * Returns the exit status of the process.
+ *
+ * Please use
+ * @ref KProcess::normalExit() to check whether the process has exited
+ * cleanly (i.e., @ref KProcess::normalExit() returns @p true) before calling
+ * this function because if the process did not exit normally,
+ * it does not have a valid exit status.
+ */
+ int exitStatus() const;
+
+
+ /**
+ * Transmit data to the child process's stdin.
+ *
+ * KProcess::writeStdin may return false in the following cases:
+ *
+ * @li The process is not currently running.
+ *
+ * @li Communication to stdin has not been requested in the @ref start() call.
+ *
+ * @li Transmission of data to the child process by a previous call to
+ * @ref writeStdin() is still in progress.
+ *
+ * Please note that the data is sent to the client asynchronously,
+ * so when this function returns, the data might not have been
+ * processed by the child process.
+ *
+ * If all the data has been sent to the client, the signal
+ * @ref wroteStdin() will be emitted.
+ *
+ * Please note that you must not free "buffer" or call @ref writeStdin()
+ * again until either a @ref wroteStdin() signal indicates that the
+ * data has been sent or a @ref processHasExited() signal shows that
+ * the child process is no longer alive...
+ **/
+ bool writeStdin(const char *buffer, int buflen);
+
+ /**
+ * This causes the stdin file descriptor of the child process to be
+ * closed indicating an "EOF" to the child.
+ *
+ * @return @p false if no communication to the process's stdin
+ * had been specified in the call to @ref start().
+ */
+ bool closeStdin();
+
+ /**
+ * This causes the stdout file descriptor of the child process to be
+ * closed.
+ *
+ * @return @p false if no communication to the process's stdout
+ * had been specified in the call to @ref start().
+ */
+ bool closeStdout();
+
+ /**
+ * This causes the stderr file descriptor of the child process to be
+ * closed.
+ *
+ * @return @p false if no communication to the process's stderr
+ * had been specified in the call to @ref start().
+ */
+ bool closeStderr();
+
+ /**
+ * Lets you see what your arguments are for debugging.
+ */
+
+ const QValueList<QCString> &args() { return arguments; }
+
+ /**
+ * Controls whether the started process should drop any
+ * setuid/segid privileges or whether it should keep them
+ *
+ * The default is @p false : drop privileges
+ */
+ void setRunPrivileged(bool keepPrivileges);
+
+ /**
+ * Returns whether the started process will drop any
+ * setuid/segid privileges or whether it will keep them
+ */
+ bool runPrivileged() const;
+
+ /**
+ * Modifies the environment of the process to be started.
+ * This function must be called before starting the process.
+ */
+ void setEnvironment(const QString &name, const QString &value);
+
+ /**
+ * Changes the current working directory (CWD) of the process
+ * to be started.
+ * This function must be called before starting the process.
+ */
+ void setWorkingDirectory(const QString &dir);
+
+ /**
+ * Specify whether to start the command via a shell or directly.
+ * The default is to start the command directly.
+ * If @p useShell is true @p shell will be used as shell, or
+ * if shell is empty, the standard shell is used.
+ * @p quote A flag indicating whether to quote the arguments.
+ *
+ * When using a shell, the caller should make sure that all filenames etc.
+ * are properly quoted when passed as argument.
+ * @see quote()
+ */
+ void setUseShell(bool useShell, const char *shell = 0);
+
+ /**
+ * This function can be used to quote an argument string such that
+ * the shell processes it properly. This is e. g. necessary for
+ * user-provided file names which may contain spaces or quotes.
+ * It also prevents expansion of wild cards and environment variables.
+ */
+ static QString quote(const QString &arg);
+
+ /**
+ * Detaches KProcess from child process. All communication is closed.
+ * No exit notification is emitted any more for the child process.
+ * Deleting the KProcess will no longer kill the child process.
+ * Note that the current process remains the parent process of the
+ * child process.
+ */
+ void detach();
+
+
+
+signals:
+
+ /**
+ * Emitted after the process has terminated when
+ * the process was run in the @p NotifyOnExit (==default option to
+ * @ref start()) or the @ref Block mode.
+ **/
+ void processExited(KProcess *proc);
+
+
+ /**
+ * Emitted, when output from the child process has
+ * been received on stdout.
+ *
+ * To actually get
+ * these signals, the respective communication link (stdout/stderr)
+ * has to be turned on in @ref start().
+ *
+ * @param buffer The data received.
+ * @param buflen The number of bytes that are available.
+ *
+ * You should copy the information contained in @p buffer to your private
+ * data structures before returning from this slot.
+ **/
+ void receivedStdout(KProcess *proc, char *buffer, int buflen);
+
+ /**
+ * Emitted when output from the child process has
+ * been received on stdout.
+ *
+ * To actually get these signals, the respective communications link
+ * (stdout/stderr) has to be turned on in @ref start() and the
+ * @p NoRead flag should have been passed.
+ *
+ * You will need to explicitly call resume() after your call to start()
+ * to begin processing data from the child process's stdout. This is
+ * to ensure that this signal is not emitted when no one is connected
+ * to it, otherwise this signal will not be emitted.
+ *
+ * The data still has to be read from file descriptor @p fd.
+ **/
+ void receivedStdout(int fd, int &len);
+
+
+ /**
+ * Emitted, when output from the child process has
+ * been received on stderr.
+ * To actually get
+ * these signals, the respective communication link (stdout/stderr)
+ * has to be turned on in @ref start().
+ *
+ * @param buffer The data received.
+ * @param buflen The number of bytes that are available.
+ *
+ * You should copy the information contained in @p buffer to your private
+ * data structures before returning from this slot.
+ */
+ void receivedStderr(KProcess *proc, char *buffer, int buflen);
+
+ /**
+ * Emitted after all the data that has been
+ * specified by a prior call to @ref writeStdin() has actually been
+ * written to the child process.
+ **/
+ void wroteStdin(KProcess *proc);
+
+
+protected slots:
+
+ /**
+ * This slot gets activated when data from the child's stdout arrives.
+ * It usually calls "childOutput"
+ */
+ void slotChildOutput(int fdno);
+
+ /**
+ * This slot gets activated when data from the child's stderr arrives.
+ * It usually calls "childError"
+ */
+ void slotChildError(int fdno);
+ /*
+ Slot functions for capturing stdout and stderr of the child
+ */
+
+ /**
+ * Called when another bulk of data can be sent to the child's
+ * stdin. If there is no more data to be sent to stdin currently
+ * available, this function must disable the QSocketNotifier "innot".
+ */
+ void slotSendData(int dummy);
+
+protected:
+
+ /**
+ * Sets up the environment according to the data passed via
+ * setEnvironment(...)
+ */
+ void setupEnvironment();
+
+ /**
+ * The list of the process' command line arguments. The first entry
+ * in this list is the executable itself.
+ */
+ QValueList<QCString> arguments;
+ /**
+ * How to run the process (Block, NotifyOnExit, DontCare). You should
+ * not modify this data member directly from derived classes.
+ */
+ RunMode run_mode;
+ /**
+ * true if the process is currently running. You should not
+ * modify this data member directly from derived classes. For
+ * reading the value of this data member, please use "isRunning()"
+ * since "runs" will probably be made private in later versions
+ * of KProcess.
+ */
+ bool runs;
+
+ /**
+ * The PID of the currently running process (see "getPid()").
+ * You should not modify this data member in derived classes.
+ * Please use "getPid()" instead of directly accessing this
+ * member function since it will probably be made private in
+ * later versions of KProcess.
+ */
+ pid_t pid_;
+
+ /**
+ * The process' exit status as returned by "waitpid". You should not
+ * modify the value of this data member from derived classes. You should
+ * rather use @ref exitStatus than accessing this data member directly
+ * since it will probably be made private in further versions of
+ * KProcess.
+ */
+ int status;
+
+
+ /**
+ * See setRunPrivileged()
+ */
+ bool keepPrivs;
+
+ /*
+ Functions for setting up the sockets for communication.
+ setupCommunication
+ -- is called from "start" before "fork"ing.
+ commSetupDoneP
+ -- completes communication socket setup in the parent
+ commSetupDoneC
+ -- completes communication setup in the child process
+ commClose
+ -- frees all allocated communication resources in the parent
+ after the process has exited
+ */
+
+ /**
+ * This function is called from "KProcess::start" right before a "fork" takes
+ * place. According to
+ * the "comm" parameter this function has to initialize the "in", "out" and
+ * "err" data member of KProcess.
+ *
+ * This function should return 0 if setting the needed communication channels
+ * was successful.
+ *
+ * The default implementation is to create UNIX STREAM sockets for the communication,
+ * but you could overload this function and establish a TCP/IP communication for
+ * network communication, for example.
+ */
+ virtual int setupCommunication(Communication comm);
+
+ /**
+ * Called right after a (successful) fork on the parent side. This function
+ * will usually do some communications cleanup, like closing the reading end
+ * of the "stdin" communication channel.
+ *
+ * Furthermore, it must also create the QSocketNotifiers "innot", "outnot" and
+ * "errnot" and connect their Qt slots to the respective KProcess member functions.
+ *
+ * For a more detailed explanation, it is best to have a look at the default
+ * implementation of "setupCommunication" in kprocess.cpp.
+ */
+ virtual int commSetupDoneP();
+
+ /**
+ * Called right after a (successful) fork, but before an "exec" on the child
+ * process' side. It usually just closes the unused communication ends of
+ * "in", "out" and "err" (like the writing end of the "in" communication
+ * channel.
+ */
+ virtual int commSetupDoneC();
+
+
+ /**
+ * Immediately called after a process has exited. This function normally
+ * calls commClose to close all open communication channels to this
+ * process and emits the "processExited" signal (if the process was
+ * not running in the "DontCare" mode).
+ */
+ virtual void processHasExited(int state);
+
+ /**
+ * Should clean up the communication links to the child after it has
+ * exited. Should be called from "processHasExited".
+ */
+ virtual void commClose();
+
+
+ /**
+ * the socket descriptors for stdin/stdout/stderr.
+ */
+ int out[2];
+ int in[2];
+ int err[2];
+
+ /**
+ * The socket notifiers for the above socket descriptors.
+ */
+ QSocketNotifier *innot;
+ QSocketNotifier *outnot;
+ QSocketNotifier *errnot;
+
+ /**
+ * Lists the communication links that are activated for the child
+ * process. Should not be modified from derived classes.
+ */
+ Communication communication;
+
+ /**
+ * Called by "slotChildOutput" this function copies data arriving from the
+ * child process's stdout to the respective buffer and emits the signal
+ * "@ref receivedStderr".
+ */
+ int childOutput(int fdno);
+
+ /**
+ * Called by "slotChildOutput" this function copies data arriving from the
+ * child process's stdout to the respective buffer and emits the signal
+ * "@ref receivedStderr"
+ */
+ int childError(int fdno);
+
+ // information about the data that has to be sent to the child:
+
+ const char *input_data; // the buffer holding the data
+ int input_sent; // # of bytes already transmitted
+ int input_total; // total length of input_data
+
+ /**
+ * @ref KProcessController is a friend of KProcess because it has to have
+ * access to various data members.
+ */
+ friend class KProcessController;
+
+
+private:
+ /**
+ * Searches for a valid shell.
+ * Here is the algorithm used for finding an executable shell:
+ *
+ * @li Try the executable pointed to by the "SHELL" environment
+ * variable with white spaces stripped off
+ *
+ * @li If your process runs with uid != euid or gid != egid, a shell
+ * not listed in /etc/shells will not used.
+ *
+ * @li If no valid shell could be found, "/bin/sh" is used as a last resort.
+ */
+ QCString searchShell();
+
+ /**
+ * Used by @ref searchShell in order to find out whether the shell found
+ * is actually executable at all.
+ */
+ bool isExecutable(const QCString &filename);
+
+ // Disallow assignment and copy-construction
+ KProcess( const KProcess& );
+ KProcess& operator= ( const KProcess& );
+
+protected:
+ virtual void virtual_hook( int id, void* data );
+private:
+ KProcessPrivate *d;
+};
+
+class KShellProcessPrivate;
+
+/**
+* @obsolete
+*
+* This class is obsolete. Use KProcess and KProcess::setUseShell(true)
+* instead.
+*
+* @short A class derived from @ref KProcess to start child
+* processes through a shell.
+* @author Christian Czezakte <e9025461@student.tuwien.ac.at>
+* @version $Id$
+*/
+class KShellProcess: public KProcess
+{
+ Q_OBJECT
+
+public:
+
+ /**
+ * Constructor
+ *
+ * By specifying the name of a shell (like "/bin/bash") you can override
+ * the mechanism for finding a valid shell as described in KProcess::searchShell()
+ */
+ KShellProcess(const char *shellname=0);
+
+ /**
+ * Destructor.
+ */
+ ~KShellProcess();
+
+ /**
+ * Starts up the process. -- For a detailed description
+ * have a look at the "start" member function and the detailed
+ * description of @ref KProcess .
+ */
+ virtual bool start(RunMode runmode = NotifyOnExit,
+ Communication comm = NoCommunication);
+
+ /**
+ * This function can be used to quote an argument string such that
+ * the shell processes it properly. This is e. g. necessary for
+ * user-provided file names which may contain spaces or quotes.
+ * It also prevents expansion of wild cards and environment variables.
+ */
+ static QString quote(const QString &arg);
+
+private:
+
+ QCString shell;
+
+ // Disallow assignment and copy-construction
+ KShellProcess( const KShellProcess& );
+ KShellProcess& operator= ( const KShellProcess& );
+
+protected:
+ virtual void virtual_hook( int id, void* data );
+private:
+ KShellProcessPrivate *d;
+};
+
+
+
+#endif
+
diff --git a/noncore/settings/networksettings/main.cpp b/noncore/settings/networksettings/main.cpp
new file mode 100644
index 0000000..52cb92b
--- a/dev/null
+++ b/noncore/settings/networksettings/main.cpp
@@ -0,0 +1,13 @@
+#include "mainwindowimp.h"
+#include <qpe/qpeapplication.h>
+
+int main(int argc, char **argv)
+{
+ QPEApplication app(argc, argv);
+ MainWindowImp window;
+ window.showMaximized();
+ return app.exec();
+}
+
+// main.cpp
+
diff --git a/noncore/settings/networksettings/mainwindow.ui b/noncore/settings/networksettings/mainwindow.ui
new file mode 100644
index 0000000..b8c0675
--- a/dev/null
+++ b/noncore/settings/networksettings/mainwindow.ui
@@ -0,0 +1,321 @@
+<!DOCTYPE UI><UI>
+<class>MainWindow</class>
+<widget>
+ <class>QWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>MainWindow</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>222</width>
+ <height>289</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>Network Setup</string>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QTabWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>tabWidget</cstring>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <widget>
+ <class>QWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Widget3</cstring>
+ </property>
+ <attribute>
+ <name>title</name>
+ <string>Interfaces</string>
+ </attribute>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QListView</class>
+ <column>
+ <property>
+ <name>text</name>
+ <string>i</string>
+ </property>
+ <property>
+ <name>clickable</name>
+ <bool>true</bool>
+ </property>
+ <property>
+ <name>resizeable</name>
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property>
+ <name>text</name>
+ <string>t</string>
+ </property>
+ <property>
+ <name>clickable</name>
+ <bool>true</bool>
+ </property>
+ <property>
+ <name>resizeable</name>
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property>
+ <name>text</name>
+ <string>Name</string>
+ </property>
+ <property>
+ <name>clickable</name>
+ <bool>true</bool>
+ </property>
+ <property>
+ <name>resizeable</name>
+ <bool>true</bool>
+ </property>
+ </column>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>serviceList</cstring>
+ </property>
+ <property stdset="1">
+ <name>allColumnsShowFocus</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout2</cstring>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <grid>
+ <property stdset="1">
+ <name>margin</name>
+ <number>5</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget row="1" column="0" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>addServiceButton</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&amp;Add</string>
+ </property>
+ </widget>
+ <widget row="0" column="0" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>informationServiceButton</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&amp;Information</string>
+ </property>
+ </widget>
+ <widget row="0" column="1" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>configureServiceButton</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&amp;Configure</string>
+ </property>
+ </widget>
+ <widget row="1" column="1" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>removeServiceButton</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&amp;Remove</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </vbox>
+ </widget>
+ <widget>
+ <class>QWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>tab</cstring>
+ </property>
+ <attribute>
+ <name>title</name>
+ <string>Profiles</string>
+ </attribute>
+ <grid>
+ <property stdset="1">
+ <name>margin</name>
+ <number>11</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget row="1" column="0" rowspan="1" colspan="2" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel3</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Change Profile To</string>
+ </property>
+ </widget>
+ <widget row="0" column="0" rowspan="1" colspan="2" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel1</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Current Profile</string>
+ </property>
+ </widget>
+ <widget row="0" column="2" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel2</cstring>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>Panel</enum>
+ </property>
+ <property stdset="1">
+ <name>frameShadow</name>
+ <enum>Sunken</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>All</string>
+ </property>
+ </widget>
+ <widget row="1" column="2" >
+ <class>QComboBox</class>
+ <item>
+ <property>
+ <name>text</name>
+ <string>All</string>
+ </property>
+ </item>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>ComboBox10</cstring>
+ </property>
+ </widget>
+ <widget row="2" column="1" rowspan="1" colspan="2" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>removeProfileButton</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&amp;Remove</string>
+ </property>
+ </widget>
+ <widget row="2" column="0" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>newProfileButton</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&amp;New</string>
+ </property>
+ </widget>
+ <spacer row="3" column="2" >
+ <property>
+ <name>name</name>
+ <cstring>Spacer16</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Vertical</enum>
+ </property>
+ <property stdset="1">
+ <name>sizeType</name>
+ <enum>Expanding</enum>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </grid>
+ </widget>
+ </widget>
+ </vbox>
+</widget>
+<customwidgets>
+ <customwidget>
+ <class>QWidget</class>
+ <header location="local">qwidget.h</header>
+ <sizehint>
+ <width>100</width>
+ <height>100</height>
+ </sizehint>
+ <container>0</container>
+ <sizepolicy>
+ <hordata>7</hordata>
+ <verdata>7</verdata>
+ </sizepolicy>
+ <pixmap>image0</pixmap>
+ </customwidget>
+</customwidgets>
+<images>
+ <image>
+ <name>image0</name>
+ <data format="XPM.GZ" length="646">789c6dd2c10ac2300c00d07bbf2234b7229d1be245fc04c5a3201e4615f430059d0711ff5ddb2e6bb236ec90eed134cb5a19d8ef36602af5ecdbfeeac05dda0798d3abebde87e3faa374d3807fa0d633a52d38d8de6f679fe33fc776e196f53cd010188256a3600a292882096246517815ca99884606e18044a3a40d91824820924265a7923a2e8bcd05f33db1173e002913175f2a6be6d3294871a2d95fa00e8a94ee017b69d339d90df1e77c57ea072ede6758</data>
+ </image>
+</images>
+</UI>
diff --git a/noncore/settings/networksettings/mainwindowimp.cpp b/noncore/settings/networksettings/mainwindowimp.cpp
new file mode 100644
index 0000000..3c13143
--- a/dev/null
+++ b/noncore/settings/networksettings/mainwindowimp.cpp
@@ -0,0 +1,308 @@
+#include "mainwindowimp.h"
+#include "addserviceimp.h"
+#include "interfaceinformationimp.h"
+#include "interfacesetupimp.h"
+
+#include <qpushbutton.h>
+#include <qdir.h>
+#include <qtabwidget.h>
+#include <qmainwindow.h>
+#include <qmessagebox.h>
+#include <qlistbox.h>
+#include <qpe/config.h>
+#include <qpe/qlibrary.h>
+#include <qpe/resource.h>
+#include <qlist.h>
+
+#include <qfile.h>
+#include <qtextstream.h>
+#include <qlistview.h>
+#include <qheader.h>
+// For library loading.
+#include <dlfcn.h>
+
+#define TEMP_ALL "/tmp/ifconfig-a"
+#define TEMP_UP "/tmp/ifconfig"
+
+#define NO_SELECT_ERROR_AND_RETURN { \
+ QMessageBox::information(this, "Error","Please select an interface.", "Ok"); \
+ return; \
+}
+
+MainWindowImp::MainWindowImp(QWidget *parent, const char *name) : MainWindow(parent, name, true) {
+ connect(addServiceButton, SIGNAL(clicked()), this, SLOT(addClicked()));
+ connect(removeServiceButton, SIGNAL(clicked()), this, SLOT(removeClicked()));
+ connect(informationServiceButton, SIGNAL(clicked()), this, SLOT(informationClicked()));
+ connect(configureServiceButton, SIGNAL(clicked()), this, SLOT(configureClicked()));
+ // Make sure we have a plugin directory to scan.
+ QString DirStr = QDir::homeDirPath() + "/.networksetup/" ;
+ QDir pluginDir( DirStr );
+ pluginDir.mkdir( DirStr );
+ pluginDir.mkdir( ( DirStr + "plugins/" ) );
+ QString path = DirStr + "plugins";
+ pluginDir.setPath(path);
+ if(!pluginDir.exists()){
+ qDebug(QString("MainWindowImp: ERROR: %1 %2").arg(__FILE__).arg(__LINE__).latin1());
+ return;
+ }
+
+ // Load any saved services.
+ loadModules(path);
+ getInterfaceList();
+ serviceList->header()->hide();
+}
+
+/**
+ * Deconstructor. Unload libraries and save.
+ */
+MainWindowImp::~MainWindowImp(){
+}
+
+void MainWindowImp::loadModules(QString path){
+}
+
+/**
+ * Attempt to load a function and resolve a function.
+ * @param pluginFileName - the name of the file in which to attempt to load
+ * @param resolveString - function pointer to resolve
+ * @return pointer to the function with name resolveString or NULL
+ */
+Module* MainWindowImp::loadPlugin(QString pluginFileName, QString resolveString){
+ //qDebug(pluginFileName.latin1());
+ QLibrary *lib = new QLibrary(pluginFileName);
+ void *functionPointer = lib->resolve(resolveString);
+ if( !functionPointer ){
+ qDebug(QString("MainWindowImp: File: %1 is not a plugin, but though was.").arg(pluginFileName).latin1());
+ delete lib;
+ return NULL;
+ }
+
+ // Try to get an object.
+ Module *object = ((Module* (*)()) functionPointer)();
+ if(object == NULL){
+ qDebug("MainWindowImp: Couldn't create object, but did load library!");
+ delete lib;
+ return NULL;
+ }
+
+ // Store for reference
+ libraries.insert(object, lib);
+ return object;
+}
+
+/*
+QList<QString> MainWindowImp::retrieveUnloadedPluginList(){
+ QString DirStr = QDir::homeDirPath() + "/.networksetup/" ;
+ QString path = DirStr + "plugins";
+ QDir d(path);
+ d.setFilter( QDir::Files | QDir::Hidden );
+
+ QMap<QObject*, QLibrary*>::Iterator libraryIt;
+ QList<QString> rlist;
+ rlist.setAutoDelete(false);
+
+ const QFileInfoList *list = d.entryInfoList();
+ QFileInfoListIterator it( *list );
+ QFileInfo *fi;
+ while ( (fi=it.current()) ) {
+ if(fi->fileName().contains(".so")){
+ for( libraryIt = libraries.begin(); libraryIt != libraries.end(); ++libraryIt )
+ if((path + "/" + fi->fileName()) != (libraryIt.data())->library()){
+ QString *s = new QString(path + "/" + fi->fileName());
+ rlist.append(s);
+ }
+ }
+ ++it;
+ }
+ return rlist;
+}
+*/
+
+/**
+ * The Add button was clicked. Bring up the add dialog and if OK is hit
+ * load the plugin and append it to the list
+ */
+void MainWindowImp::addClicked(){
+ // Now that we have a list of all of the protocals, list them.
+ {
+ QMessageBox::information(this, "No Modules", "Nothing to add.", "Ok");
+ return;
+ }
+ AddServiceImp service(this, "AddService", true);
+ service.showMaximized();
+ service.exec();
+}
+
+/**
+ * Prompt the user to see if they really want to do this.
+ * If they do then remove from the list and unload.
+ */
+void MainWindowImp::removeClicked(){
+ QListViewItem *item = serviceList->currentItem();
+ if(item == NULL) NO_SELECT_ERROR_AND_RETURN
+
+ if(modules.find(interfaceItems[item]) == modules.end()){
+ QMessageBox::information(this, "Can't remove interface.", "Interface is built in.", "Ok");
+ }
+ else{
+ // Try to remove.
+ }
+
+}
+
+/**
+ * See if there is a configuration for the selected protocal.
+ * Prompt with errors.
+ */
+void MainWindowImp::configureClicked(){
+ QListViewItem *item = serviceList->currentItem();
+ if(item == NULL) NO_SELECT_ERROR_AND_RETURN
+
+ if(modules.find(interfaceItems[item]) == modules.end()){
+ InterfaceSetupImp *conf = new InterfaceSetupImp(0, "InterfaceConfiguration", interfaceItems[item]);
+ conf->showMaximized();
+ conf->show();
+ }
+ else{
+ InterfaceSetupImp *conf = new InterfaceSetupImp(this, "InterfaceConfiguration");
+ conf->show();
+ }
+}
+
+/**
+ * Pull up the information about the selected interface
+ * Report an error
+ */
+void MainWindowImp::informationClicked(){
+ QListViewItem *item = serviceList->currentItem();
+ if(item == NULL)NO_SELECT_ERROR_AND_RETURN
+
+ if(modules.find(interfaceItems[item]) == modules.end()){
+ InterfaceInformationImp *i = new InterfaceInformationImp(0, "InterfaceInformationImp", interfaceItems[item]);
+ i->showMaximized();
+ i->show();
+ }
+ else{
+ QTabWidget *t = new QTabWidget(this, "InterfaceInformationTAB");
+ InterfaceInformationImp *i = new InterfaceInformationImp(t, "TCPIPInformation", interfaceItems[item], true);
+ t->insertTab(i, "TCP/IP");
+ t->show();
+ }
+}
+
+/**
+ * Aquire the list of active interfaces from ifconfig
+ * Call ifconfig and ifconfig -a
+ */
+void MainWindowImp::getInterfaceList(){
+ KShellProcess *processAll = new KShellProcess();
+ *processAll << "/sbin/ifconfig" << "-a" << " > " TEMP_ALL;
+ connect(processAll, SIGNAL(processExited(KProcess *)),
+ this, SLOT(jobDone(KProcess *)));
+ threads.insert(processAll, TEMP_ALL);
+ processAll->start(KShellProcess::NotifyOnExit);
+
+ KShellProcess *process = new KShellProcess();
+ *process << "/sbin/ifconfig" << " > " TEMP_UP;
+ connect(process, SIGNAL(processExited(KProcess *)),
+ this, SLOT(jobDone(KProcess *)));
+ threads.insert(process, TEMP_UP);
+ process->start(KShellProcess::NotifyOnExit);
+}
+
+void MainWindowImp::jobDone(KProcess *process){
+ QString fileName = threads[process];
+ threads.remove(process);
+ delete process;
+
+ QFile file(fileName);
+ if (!file.open(IO_ReadOnly)){
+ qDebug(QString("MainWindowImp: Can't open file: %1").arg(fileName).latin1());
+ return;
+ }
+
+ QTextStream stream( &file );
+ QString line;
+ while ( !stream.eof() ) {
+ line = stream.readLine();
+ int space = line.find(" ");
+ if(space > 1){
+ // We have found an interface
+ QString interfaceName = line.mid(0, space);
+ Interface *i;
+ // See if we already have it
+ if(interfaceNames.find(interfaceName) == interfaceNames.end()){
+ if(fileName == TEMP_ALL)
+ i = new Interface(interfaceName, false);
+ else
+ i = new Interface(interfaceName, true);
+ }
+ else{
+ i = interfaceNames[interfaceName];
+ if(fileName != TEMP_ALL)
+ i->setStatus(true);
+ }
+
+ i->setAttached(true);
+ i->setInterfaceName(interfaceName);
+
+ QString hardName = "Ethernet";
+ int hardwareName = line.find("Link encap:");
+ int macAddress = line.find("HWaddr");
+ if(macAddress == -1)
+ macAddress = line.length();
+ if(hardwareName != -1)
+ i->setHardwareName(line.mid(hardwareName+11, macAddress-(hardwareName+11)));
+ // We have found an interface
+ //qDebug(QString("MainWindowImp: Found Interface: %1").arg(line).latin1());
+ interfaceNames.insert(i->getInterfaceName(), i);
+ updateInterface(i);
+ }
+ }
+ file.close();
+ QFile::remove(fileName);
+}
+
+void MainWindowImp::updateInterface(Interface *i){
+ QListViewItem *item = NULL;
+
+ // See if we already have it
+ if(items.find(i) == items.end()){
+ item = new QListViewItem(serviceList, "", "", "");
+ // See if you can't find a module owner for this interface
+ //EmployeeMap::Iterator it;
+ //for( it = map.begin(); it != map.end(); ++it )
+ // printf( "%s, %s earns %d\n", it.key().latin1(), it.data().name().latin1(), it.data().salary() );
+
+ items.insert(i, item);
+ interfaceItems.insert(item, i);
+ }
+ else
+ item = items[i];
+
+ QString statusImage = "down";
+ if(i->getStatus())
+ statusImage = "up";
+ QPixmap status = (Resource::loadPixmap(statusImage));
+ item->setPixmap(0, status);
+
+ QString typeName = "lan";
+ if(i->getHardwareName().contains("Local Loopback"))
+ typeName = "lo";
+ QPixmap type = (Resource::loadPixmap(typeName));
+ item->setPixmap(1, type);
+
+ item->setText(2, i->getHardwareName());
+
+}
+
+void MainWindowImp::addProfile(){
+
+}
+
+void MainWindowImp::removeProfile(){
+
+}
+
+// mainwindowimp.cpp
+
diff --git a/noncore/settings/networksettings/mainwindowimp.h b/noncore/settings/networksettings/mainwindowimp.h
new file mode 100644
index 0000000..95ec2a1
--- a/dev/null
+++ b/noncore/settings/networksettings/mainwindowimp.h
@@ -0,0 +1,53 @@
+#ifndef MAINWINOWIMP_H
+#define MAINWINOWIMP_H
+
+#include "mainwindow.h"
+#include "module.h"
+#include "interface.h"
+#include "kprocess.h"
+#include <qmap.h>
+
+class QLibrary;
+
+class MainWindowImp : public MainWindow {
+ Q_OBJECT
+
+public:
+ MainWindowImp(QWidget *parent=0, const char *name=0);
+ ~MainWindowImp();
+
+private slots:
+ void addClicked();
+ void removeClicked();
+ void configureClicked();
+ void informationClicked();
+
+ void jobDone(KProcess *process);
+ void getInterfaceList();
+
+ void addProfile();
+ void removeProfile();
+
+ void updateInterface(Interface *i);
+
+private:
+ void loadModules(QString path);
+
+ Module* loadPlugin(QString pluginFileName,
+ QString resolveString = "create_plugin");
+
+ // For our local list of names
+ QMap<QString, Interface*> interfaceNames;
+
+ QMap<Module*, QLibrary*> libraries;
+ QMap<Interface*, Module*> modules;
+ QMap<Interface*, QListViewItem*> items;
+ QMap<QListViewItem*, Interface*> interfaceItems;
+
+ QMap<KProcess*, QString> threads;
+};
+
+#endif
+
+// mainwindowimp.h
+
diff --git a/noncore/settings/networksettings/module.h b/noncore/settings/networksettings/module.h
new file mode 100644
index 0000000..f146d8c
--- a/dev/null
+++ b/noncore/settings/networksettings/module.h
@@ -0,0 +1,33 @@
+#ifndef MODULE_H
+#define MODULE_H
+
+#include <qobject.h>
+#include <qlist.h>
+#include <qmap.h>
+#include "interface.h"
+
+class QWidget;
+
+class Module : QObject{
+
+signals:
+ void updateInterface(Interface *i);
+
+public:
+ Module(){};
+
+ virtual bool isOwner(Interface *){ return false; };
+ virtual QWidget *configure(){ return NULL; } ;
+ virtual QWidget *information(){ return NULL; };
+ virtual QList<Interface> getInterfaces() = 0;
+ virtual QMap<QString, QString> possibleNewInterfaces() = 0;
+ virtual Interface *addNewInterface(QString name) = 0;
+ virtual bool remove(Interface* i) = 0;
+
+
+};
+
+#endif
+
+// module.h
+
diff --git a/noncore/settings/networksettings/networksetup.pro b/noncore/settings/networksettings/networksetup.pro
new file mode 100644
index 0000000..7d9918b
--- a/dev/null
+++ b/noncore/settings/networksettings/networksetup.pro
@@ -0,0 +1,10 @@
+TEMPLATE = app
+CONFIG = qt warn_on debug
+#CONFIG = qt warn_on release
+HEADERS = mainwindowimp.h addserviceimp.h interface.h interfaceinformationimp.h interfacesetupimp.h interfaces.h defaultmodule.h kprocctrl.h module.h kprocess.h
+SOURCES = main.cpp mainwindowimp.cpp addserviceimp.cpp interface.cpp interfaceinformationimp.cpp interfacesetupimp.cpp kprocctrl.cpp kprocess.cpp interfaces.cpp
+INCLUDEPATH += $(QPEDIR)/include
+DEPENDPATH += $(QPEDIR)/include
+LIBS += -lqpe
+INTERFACES = mainwindow.ui addservice.ui interfaceinformation.ui interfaceadvanced.ui interfacesetup.ui
+TARGET = networksetup
diff --git a/noncore/settings/networksettings/systemadvanced.ui b/noncore/settings/networksettings/systemadvanced.ui
new file mode 100644
index 0000000..6ea192c
--- a/dev/null
+++ b/noncore/settings/networksettings/systemadvanced.ui
@@ -0,0 +1,443 @@
+<!DOCTYPE UI><UI>
+<class>SystemNetworking</class>
+<widget>
+ <class>QWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>SystemNetworking</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>222</width>
+ <height>289</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>System Networking</string>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QTabWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>tabWidget</cstring>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <widget>
+ <class>QWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>tab</cstring>
+ </property>
+ <attribute>
+ <name>title</name>
+ <string>DNS</string>
+ </attribute>
+ <grid>
+ <property stdset="1">
+ <name>margin</name>
+ <number>11</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget row="0" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel6</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Hostname</string>
+ </property>
+ </widget>
+ <widget row="1" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel5</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>DNS</string>
+ </property>
+ <property stdset="1">
+ <name>alignment</name>
+ <set>AlignTop|AlignLeft</set>
+ </property>
+ <property>
+ <name>vAlign</name>
+ </property>
+ </widget>
+ <widget row="1" column="1" >
+ <class>QListBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>ListBox5</cstring>
+ </property>
+ </widget>
+ <widget row="0" column="1" >
+ <class>QLineEdit</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>LineEdit7</cstring>
+ </property>
+ </widget>
+ <widget row="3" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel7</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Hosts</string>
+ </property>
+ </widget>
+ <widget row="3" column="1" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel9</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>List here....</string>
+ </property>
+ </widget>
+ <widget row="2" column="0" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PushButton15</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&amp;Add</string>
+ </property>
+ </widget>
+ <widget row="2" column="1" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PushButton16</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&amp;Delete</string>
+ </property>
+ </widget>
+ <spacer row="4" column="1" >
+ <property>
+ <name>name</name>
+ <cstring>Spacer14</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Vertical</enum>
+ </property>
+ <property stdset="1">
+ <name>sizeType</name>
+ <enum>Expanding</enum>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </grid>
+ </widget>
+ <widget>
+ <class>QWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>tab</cstring>
+ </property>
+ <attribute>
+ <name>title</name>
+ <string>Routing</string>
+ </attribute>
+ <grid>
+ <property stdset="1">
+ <name>margin</name>
+ <number>11</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget row="0" column="0" rowspan="1" colspan="2" >
+ <class>QListView</class>
+ <column>
+ <property>
+ <name>text</name>
+ <string>Destination</string>
+ </property>
+ <property>
+ <name>clickable</name>
+ <bool>true</bool>
+ </property>
+ <property>
+ <name>resizeable</name>
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property>
+ <name>text</name>
+ <string>Gateway</string>
+ </property>
+ <property>
+ <name>clickable</name>
+ <bool>true</bool>
+ </property>
+ <property>
+ <name>resizeable</name>
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property>
+ <name>text</name>
+ <string>Genmask</string>
+ </property>
+ <property>
+ <name>clickable</name>
+ <bool>true</bool>
+ </property>
+ <property>
+ <name>resizeable</name>
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property>
+ <name>text</name>
+ <string>Flags</string>
+ </property>
+ <property>
+ <name>clickable</name>
+ <bool>true</bool>
+ </property>
+ <property>
+ <name>resizeable</name>
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property>
+ <name>text</name>
+ <string>Metric</string>
+ </property>
+ <property>
+ <name>clickable</name>
+ <bool>true</bool>
+ </property>
+ <property>
+ <name>resizeable</name>
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property>
+ <name>text</name>
+ <string>Ref</string>
+ </property>
+ <property>
+ <name>clickable</name>
+ <bool>true</bool>
+ </property>
+ <property>
+ <name>resizeable</name>
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property>
+ <name>text</name>
+ <string>Use</string>
+ </property>
+ <property>
+ <name>clickable</name>
+ <bool>true</bool>
+ </property>
+ <property>
+ <name>resizeable</name>
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property>
+ <name>text</name>
+ <string>Iface</string>
+ </property>
+ <property>
+ <name>clickable</name>
+ <bool>true</bool>
+ </property>
+ <property>
+ <name>resizeable</name>
+ <bool>true</bool>
+ </property>
+ </column>
+ <item>
+ <property>
+ <name>text</name>
+ <string>192.168.1.0</string>
+ </property>
+ <property>
+ <name>text</name>
+ <string>*</string>
+ </property>
+ <property>
+ <name>text</name>
+ <string>255.255.255.0</string>
+ </property>
+ <property>
+ <name>text</name>
+ <string>U</string>
+ </property>
+ <property>
+ <name>text</name>
+ <string>0</string>
+ </property>
+ <property>
+ <name>text</name>
+ <string>0</string>
+ </property>
+ <property>
+ <name>text</name>
+ <string>0</string>
+ </property>
+ <property>
+ <name>text</name>
+ <string>eth0</string>
+ </property>
+ <property>
+ <name>pixmap</name>
+ <pixmap></pixmap>
+ </property>
+ <property>
+ <name>pixmap</name>
+ <pixmap></pixmap>
+ </property>
+ <property>
+ <name>pixmap</name>
+ <pixmap></pixmap>
+ </property>
+ <property>
+ <name>pixmap</name>
+ <pixmap></pixmap>
+ </property>
+ <property>
+ <name>pixmap</name>
+ <pixmap></pixmap>
+ </property>
+ <property>
+ <name>pixmap</name>
+ <pixmap></pixmap>
+ </property>
+ <property>
+ <name>pixmap</name>
+ <pixmap></pixmap>
+ </property>
+ <property>
+ <name>pixmap</name>
+ <pixmap></pixmap>
+ </property>
+ </item>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>ListView4</cstring>
+ </property>
+ </widget>
+ <widget row="1" column="0" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PushButton17</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&amp;Add</string>
+ </property>
+ </widget>
+ <widget row="1" column="1" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PushButton18</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Remove</string>
+ </property>
+ </widget>
+ <spacer row="2" column="1" >
+ <property>
+ <name>name</name>
+ <cstring>Spacer15</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Vertical</enum>
+ </property>
+ <property stdset="1">
+ <name>sizeType</name>
+ <enum>Expanding</enum>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </grid>
+ </widget>
+ </widget>
+ </vbox>
+</widget>
+<customwidgets>
+ <customwidget>
+ <class>QWidget</class>
+ <header location="local">qwidget.h</header>
+ <sizehint>
+ <width>100</width>
+ <height>100</height>
+ </sizehint>
+ <container>0</container>
+ <sizepolicy>
+ <hordata>7</hordata>
+ <verdata>7</verdata>
+ </sizepolicy>
+ <pixmap>image0</pixmap>
+ </customwidget>
+</customwidgets>
+<images>
+ <image>
+ <name>image0</name>
+ <data format="XPM.GZ" length="646">789c6dd2c10ac2300c00d07bbf2234b7229d1be245fc04c5a3201e4615f430059d0711ff5ddb2e6bb236ec90eed134cb5a19d8ef36602af5ecdbfeeac05dda0798d3abebde87e3faa374d3807fa0d633a52d38d8de6f679fe33fc776e196f53cd010188256a3600a292882096246517815ca99884606e18044a3a40d91824820924265a7923a2e8bcd05f33db1173e002913175f2a6be6d3294871a2d95fa00e8a94ee017b69d339d90df1e77c57ea072ede6758</data>
+ </image>
+</images>
+</UI>