You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdeadmin/knetworkconf/knetworkconf/knetworkconfigparser.cpp

1240 lines
42 KiB

/***************************************************************************
knetworkconfigparser.cpp - description
-------------------
begin : Mon Jan 13 2003
copyright : (C) 2003 by Juan Luis Baptiste
email : jbaptiste@merlinux.org
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "knetworkconfigparser.h"
#include "knetworkconfigparser.moc"
KNetworkConfigParser::KNetworkConfigParser(){
networkInfo = new KNetworkInfo();
TQString platform;
bool askAgain = readAskAgain(platform);
if (!askAgain || platform.length() > 0)
runDetectionScript(platform);
else
runDetectionScript(TQString());
}
/** Runs the gst backend to get network values. You can pass to the script a specific platform to load using the platform parameter. */
void KNetworkConfigParser::runDetectionScript(TQString platform){
KDetectDistroDlg* dialog = new KDetectDistroDlg(0, 0);
dialog->show();
procDetect = new TQProcess(this);
TQString pathToProgram = locate("data",BACKEND_PATH);
if (pathToProgram.isEmpty())
{
KMessageBox::error(0,
i18n("Could not find the backend script for the network configuration detection. Something is wrong with your installation.\n Please check that \n{TDE_PATH}/%1 \nfile is present.").arg(BACKEND_PATH),
i18n("Could Not Find Network Configuration Backend Script"));
dialog->close();
//kapp->quit();
}
else
{
procDetect->addArgument( pathToProgram );
if (platform != TQString())
{
procDetect->addArgument( "--platform" );
procDetect->addArgument( platform );
}
procDetect->addArgument( "--get" );
connect( this, TQ_SIGNAL(readyLoadingNetworkInfo()), dialog, TQ_SLOT(close()) );
connect( this, TQ_SIGNAL(errorDetectingPlatform()), dialog, TQ_SLOT(close()) );
connect( procDetect, TQ_SIGNAL(processExited()), this, TQ_SLOT(readNetworkInfo()) );
connect( procDetect, TQ_SIGNAL(readyReadStdout()),this, TQ_SLOT(concatXMLOutputSlot()));
connect( procDetect, TQ_SIGNAL(readyReadStderr()),this, TQ_SLOT(readXMLErrSlot()));
if ( !procDetect->start() )
{
// error handling
KMessageBox::error(0,
i18n("Could not execute backend script for the network configuration detection. Something is wrong with your installation."),
i18n("Could Not Launch Network Configuration Backend Script"));
dialog->close();
}
}
}
/** runs gst to find out the state of network devices.It runs the command:
$knetworkconf_home/backends/networkconf [--platform platform] -d list_ifaces. */
void KNetworkConfigParser::listIfaces(const TQString &platform){
procDetect = new TQProcess(this);
procDetect->addArgument( locate("data",BACKEND_PATH) );
if (platform != TQString())
{
procDetect->addArgument( "--platform" );
procDetect->addArgument( platform );
}
//procDetect->addArgument( "--get" );
procDetect->addArgument( "-d" );
procDetect->addArgument( "list_ifaces" );
connect( procDetect, TQ_SIGNAL(processExited()), this, TQ_SLOT(readListIfacesSlot()) );
connect( procDetect, TQ_SIGNAL(readyReadStdout()),this, TQ_SLOT(concatXMLOutputSlot()));
connect( procDetect, TQ_SIGNAL(readyReadStderr()),this, TQ_SLOT(readXMLErrSlot()));
xmlOuput = "";
xmlErr = "";
if ( !procDetect->start() )
{
// error handling
KMessageBox::error(0,
i18n("Could not execute backend script for the network configuration detection. Something is wrong with your installation."),
i18n("Could Not Launch Network Configuration Backend Script"));
}
}
void KNetworkConfigParser::readListIfacesSlot(){
TQPtrList<KNetworkInterface> tempDeviceList;
//The gst backend puts a \n at the beginning of the xml output, so
//we have to erase it first before we parse it.
xmlOuput = xmlOuput.section('\n',1);
tqDebug("XML -d list_ifaces: %s",xmlOuput.latin1());
TQString err;
int x,y;
TQDomDocument doc( "network-ifaces");
if ( !doc.setContent( xmlOuput.utf8(),false,&err,&x,&y ) )
{
KMessageBox::error(0,
i18n("Could not parse the XML output from the network configuration backend."),
i18n("Error While Listing Network Interfaces"));
// tqDebug("error: %s %d,%d",err.latin1(),x,y);
}
TQDomElement root = doc.documentElement();
TQDomNode node = root.firstChild();
while( !node.isNull() )
{
if ( node.isElement() && node.nodeName() == "interface" )
{
TQDomElement interface = node.toElement();
KNetworkInterface *tempDevice = new KNetworkInterface();
tempDevice = getInterfaceInfo(interface,TQString());
if (tempDevice->getType().lower() != LOOPBACK_IFACE_TYPE)
{
KNetworkInterface *originalDevice = getDeviceInfo(tempDevice->getDeviceName());
if (originalDevice == NULL)
{
node = node.nextSibling();
continue;
}
originalDevice->setActive(tempDevice->isActive());
if (!tempDevice->getBroadcast().isEmpty())
originalDevice->setBroadcast(tempDevice->getBroadcast());
if (!tempDevice->getDescription().isEmpty())
originalDevice->setDescription(tempDevice->getDescription());
if (!tempDevice->getIpAddress().isEmpty())
originalDevice->setIpAddress(tempDevice->getIpAddress());
if (!tempDevice->getMacAddress().isEmpty())
originalDevice->setMacAddress(tempDevice->getMacAddress());
if (!tempDevice->getNetmask().isEmpty())
originalDevice->setNetmask(tempDevice->getNetmask());
if (!tempDevice->getNetwork().isEmpty())
originalDevice->setNetwork(tempDevice->getNetwork());
}
}
node = node.nextSibling();
}
//networkInfo->setDeviceList(deviceList);
//Tell to interested parties when the network info is ready.
emit readyLoadingNetworkInfo();
}
KNetworkConfigParser::~KNetworkConfigParser(){
}
/** return tyhe number of configured devices. */
unsigned KNetworkConfigParser::numDevices(){
return _numDevices;
}
void KNetworkConfigParser::setProgramVersion(TQString ver)
{
KNetworkConfigParser::programVersion = ver;
}
void KNetworkConfigParser::readIfconfigOutput(){
TQString s = proc->readStdout();
ifconfigOutput = s;
}
/**
Reads /proc/net/route looking for the default gateway.
NOTE:We should use the gateway reported by gst, but if there's a
gw in a config file and one of the network interfaces is
configured to use dhcp, gst returns the value of the config
file instead of the gw configured by dhcp.
*/
void KNetworkConfigParser::loadRoutingInfo( KRoutingInfo *routingInfo){
#ifndef Q_OS_FREEBSD
TQFile f( "/proc/net/route");
if ( !f.open(IO_ReadOnly) )
{
KMessageBox::error(0,
i18n("Could not open file /proc/net/route."),
i18n("Could Not Open File"));
}
else
{
TQTextStream t( &f ); // use a text stream
TQString s;
while (!t.eof())
{
s = t.readLine(); // line of text excluding '\n'
TQString interface = s.section('\t',0,0);
TQString destination = s.section('\t',1,1);
TQString gw = s.section('\t',2,2);
if (destination == "00000000")
{
routingInfo->setGateway(hexIPv4ToDecIPv4(gw));
routingInfo->setGatewayDevice(interface);
}
}
}
f.close();
#endif
}
TQString
KNetworkConfigParser::hexIPv4ToDecIPv4(const TQString &hex)
{
bool ok;
TQString dec = "";
TQString dec2 = "";
TQString temp = "";
TQString temp2 = "";
#if TQ_BYTE_ORDER == TQ_LITTLE_ENDIAN
temp = hex.mid(6,2);
temp2 = temp2.setNum(temp.toInt(&ok,16));
dec.append(temp2);
dec.append('.');
temp = hex.mid(4,2);
temp2 = temp2.setNum(temp.toInt(&ok,16));
dec.append(temp2);
dec.append('.');
temp = hex.mid(2,2);
temp2 = temp2.setNum(temp.toInt(&ok,16));
dec.append(temp2);
dec.append('.');
temp = hex.mid(0,2);
temp2 = temp2.setNum(temp.toInt(&ok,16));
dec.append(temp2);
#else
temp = hex.mid(0,2);
temp2 = temp2.setNum(temp.toInt(&ok,16));
dec.append(temp2);
dec.append('.');
temp = hex.mid(2,2);
temp2 = temp2.setNum(temp.toInt(&ok,16));
dec.append(temp2);
dec.append('.');
temp = hex.mid(4,2);
temp2 = temp2.setNum(temp.toInt(&ok,16));
dec.append(temp2);
dec.append('.');
temp = hex.mid(6,2);
temp2 = temp2.setNum(temp.toInt(&ok,16));
dec.append(temp2);
#endif
dec2 = dec;
if (ok)
return dec2;
else
return "";
}
void KNetworkConfigParser::saveNetworkInfo(KNetworkInfo *networkInfo)
{
this->networkInfo = networkInfo;
TQPtrList<KNetworkInterface> devList = networkInfo->getDeviceList();
TQPtrList<KNetworkInfo> profileList = networkInfo->getProfilesList();
dnsInfo = networkInfo->getDNSInfo();
routingInfo = networkInfo->getRoutingInfo();
//Start xml file
TQDomDocument doc( "network []" );
TQDomProcessingInstruction instr = doc.createProcessingInstruction("xml","version=\"1.0\" ");
doc.appendChild(instr);
TQDomElement root = doc.createElement( "network" );
doc.appendChild( root );
addRoutingInfoToXMLDoc(&doc, &root, routingInfo);
addDNSInfoToXMLDoc(&doc, &root, dnsInfo);
addNetworkInterfacesToXMLDoc(&doc, &root, devList);
addNetworkProfilesToXMLDoc(&doc, &root, profileList);
//If we don't add this comment to the end of the xml file, the gst process never exits!
TQDomComment endComment = doc.createComment(" GST: end of request ");
doc.appendChild( endComment );
TQString xml = doc.toString();
tqDebug("--set XML:\n%s",xml.latin1());
procSaveNetworkInfo = new TQProcess(this);
procSaveNetworkInfo->addArgument( locate("data",BACKEND_PATH) );
if (!networkInfo->getPlatformName().isEmpty())
{
procSaveNetworkInfo->addArgument( "--platform" );
procSaveNetworkInfo->addArgument( networkInfo->getPlatformName() );
}
procSaveNetworkInfo->addArgument( "--set" );
// KDetectDistroDlg* dialog = new KDetectDistroDlg(0, 0, true,TQDialog::WStyle_Customize|TQDialog::WStyle_NormalBorder|TQDialog::WStyle_Title|TQDialog::WStyle_SysMenu); //made it semi-modal
KDetectDistroDlg* dialog = new KDetectDistroDlg((TQWidget*)parent(), 0, true);
dialog->setCaption(i18n("Reloading Network"));
dialog->text->setText(i18n("%1Please wait while saving the network settings...%2").arg("<center>").arg("</center>"));
dialog->show();
xmlOuput = "";
connect( this, TQ_SIGNAL(readyLoadingNetworkInfo()), dialog, TQ_SLOT(close()) );
connect(procSaveNetworkInfo,TQ_SIGNAL(readyReadStdout()),this,TQ_SLOT(readFromStdoutSaveNetworkInfo()));
connect(procSaveNetworkInfo,TQ_SIGNAL(wroteToStdin()),this,TQ_SLOT(sendNetworkInfoSavedSignalSlot()));
connect(procSaveNetworkInfo,TQ_SIGNAL(processExited()),this,TQ_SLOT(listIfacesSlot()));
processRunning = true;
connect( procSaveNetworkInfo, TQ_SIGNAL(processExited()), this, TQ_SLOT(processExitedSlot()) );
if ( !procSaveNetworkInfo->start() )
{
KMessageBox::error(0,
i18n("Could not execute backend script for the network configuration detection. Something is wrong with your installation."),
i18n("Could Not Launch Network Configuration Backend Script"));
}
procSaveNetworkInfo->writeToStdin(xml);
//wait around until the process has finished, otherwise it becomes a zombie
while (processRunning) {
kapp->processEvents();
}
}
void KNetworkConfigParser::processExitedSlot() {
processRunning = false;
}
void KNetworkConfigParser::addNetworkProfilesToXMLDoc(TQDomDocument *doc, TQDomNode *root, TQPtrList<KNetworkInfo> profileList)
{
TQPtrListIterator<KNetworkInfo> profileIt(profileList);
KNetworkInfo *profile;
TQDomElement tag = doc->createElement( "profiledb" );
root->appendChild( tag );
while ( (profile = profileIt.current()) != 0)
{
++profileIt;
TQPtrList<KNetworkInterface> devList = profile->getDeviceList();
KDNSInfo *dnsInfo = profile->getDNSInfo();
KRoutingInfo *routingInfo = profile->getRoutingInfo();
TQDomElement profileTag = doc->createElement( "profile" );
tag.appendChild( profileTag );
TQDomElement innerTag = doc->createElement( "name" );
profileTag.appendChild( innerTag );
TQDomText t = doc->createTextNode( profile->getProfileName() );
innerTag.appendChild( t );
addRoutingInfoToXMLDoc(doc, &profileTag, routingInfo);
addDNSInfoToXMLDoc(doc, &profileTag, dnsInfo);
addNetworkInterfacesToXMLDoc(doc, &profileTag, devList);
}
}
void KNetworkConfigParser::addNetworkInterfacesToXMLDoc(TQDomDocument *doc, TQDomNode *root, TQPtrList<KNetworkInterface> devList)
{
KNetworkInterface *device;
TQPtrListIterator<KNetworkInterface> devIt(devList);
//Save in the configuration file the description of the interfaces as
//the backend no longer handles this
KSimpleConfig cfg("knetworkconfrc");
cfg.setGroup("Interfaces");
//Add the network interfaces list
while ( (device = devIt.current()) != 0 )
{
++devIt;
// if protocol is not specified, then should not have entry in config
if (device->getBootProto().isEmpty())
continue;
TQDomElement tag = doc->createElement( "interface" );
tag.setAttribute("type",device->getType());
root->appendChild( tag );
TQDomElement configurationTag;
configurationTag = doc->createElement( "configuration" );
tag.appendChild( configurationTag );
TQDomElement innerTag;
TQDomText t;
if ((device->getBootProto().lower() != "dhcp") && (device->getBootProto().lower() != "bootp"))
{
if (!device->getIpAddress().isEmpty())
{
innerTag = doc->createElement( "address" );
configurationTag.appendChild( innerTag );
t = doc->createTextNode( device->getIpAddress() );
innerTag.appendChild( t );
}
if (!device->getGateway().isEmpty())
{
innerTag = doc->createElement( "gateway" );
configurationTag.appendChild( innerTag );
t = doc->createTextNode( device->getGateway() );
innerTag.appendChild( t );
}
if (!device->getBroadcast().isEmpty())
{
innerTag = doc->createElement( "broadcast" );
configurationTag.appendChild( innerTag );
t = doc->createTextNode( device->getBroadcast() );
innerTag.appendChild( t );
}
if (!device->getNetmask().isEmpty())
{
innerTag = doc->createElement( "netmask" );
configurationTag.appendChild( innerTag );
t = doc->createTextNode( device->getNetmask() );
innerTag.appendChild( t );
}
if (!device->getNetwork().isEmpty())
{
innerTag = doc->createElement( "network" );
configurationTag.appendChild( innerTag );
t = doc->createTextNode( device->getNetwork() );
innerTag.appendChild( t );
}
}
innerTag = doc->createElement( "auto" );
configurationTag.appendChild( innerTag );
if (device->getOnBoot().lower() == "yes")
t = doc->createTextNode( "1" );
else
t = doc->createTextNode( "0" );
innerTag.appendChild( t );
innerTag = doc->createElement( "bootproto" );
configurationTag.appendChild( innerTag );
if (device->getBootProto().lower() == "manual")
t = doc->createTextNode( "none" );
else
t = doc->createTextNode( device->getBootProto().lower() );
innerTag.appendChild( t );
innerTag = doc->createElement( "file" );
configurationTag.appendChild( innerTag );
t = doc->createTextNode( device->getDeviceName() );
innerTag.appendChild( t );
innerTag = doc->createElement( "dev" );
tag.appendChild( innerTag );
t = doc->createTextNode( device->getDeviceName() );
innerTag.appendChild( t );
innerTag = doc->createElement( "enabled" );
tag.appendChild( innerTag );
if (device->isActive())
t = doc->createTextNode( "1" );
else
t = doc->createTextNode( "0" );
innerTag.appendChild( t );
innerTag = doc->createElement( "hwaddr" );
tag.appendChild( innerTag );
t = doc->createTextNode( device->getMacAddress() );
innerTag.appendChild( t );
//Wireless settings
if (device->getType() == WIRELESS_IFACE_TYPE)
{
KWirelessInterface *wifiDev = static_cast<KWirelessInterface*>(device);
if (!wifiDev->getEssid().isEmpty())
{
innerTag = doc->createElement( "essid" );
configurationTag.appendChild( innerTag );
t = doc->createTextNode( wifiDev->getEssid() );
innerTag.appendChild( t );
}
if (!wifiDev->getWepKey().isEmpty())
{
innerTag = doc->createElement( "key" );
configurationTag.appendChild( innerTag );
t = doc->createTextNode( wifiDev->getWepKey() );
innerTag.appendChild( t );
}
if (!wifiDev->getKeyType().isEmpty())
{
innerTag = doc->createElement( "key_type" );
configurationTag.appendChild( innerTag );
t = doc->createTextNode( wifiDev->getKeyType().lower() );
innerTag.appendChild( t );
}
}
if (!device->getDescription().isEmpty() && device->getDeviceName()!= "lo")
cfg.writeEntry(device->getDeviceName(),device->getDescription());
cfg.sync();
}
}
void KNetworkConfigParser::addDNSInfoToXMLDoc(TQDomDocument *doc, TQDomNode *root, KDNSInfo *dnsInfo)
{
TQStringList nameServerList = dnsInfo->getNameServers();
TQPtrList<KKnownHostInfo> knownHostsList = dnsInfo->getKnownHostsList();
TQPtrListIterator<KKnownHostInfo> knownHostsIt(knownHostsList);
KKnownHostInfo *host;
TQDomElement tag = doc->createElement( "hostname" );
root->appendChild( tag );
TQDomText t = doc->createTextNode( dnsInfo->getMachineName() );
tag.appendChild( t );
tag = doc->createElement( "domain" );
root->appendChild( tag );
t = doc->createTextNode( dnsInfo->getDomainName() );
tag.appendChild( t );
//Add the list of name servers
for ( TQStringList::Iterator it = nameServerList.begin(); it != nameServerList.end(); ++it ) {
tag = doc->createElement( "nameserver" );
root->appendChild( tag );
t = doc->createTextNode( *it );
tag.appendChild( t );
}
//Add the list of static hosts
while ( (host = knownHostsIt.current()) != 0 )
{
++knownHostsIt;
tag = doc->createElement( "statichost" );
root->appendChild( tag );
TQDomElement innerTag;
if (!host->getIpAddress().isEmpty())
{
innerTag = doc->createElement( "ip" );
tag.appendChild( innerTag );
t = doc->createTextNode( host->getIpAddress() );
innerTag.appendChild( t );
}
TQStringList aliases = host->getAliases();
for ( TQStringList::Iterator it = aliases.begin(); it != aliases.end(); ++it )
{
innerTag = doc->createElement( "alias" );
tag.appendChild( innerTag );
t = doc->createTextNode( *it );
innerTag.appendChild( t );
}
}
}
void KNetworkConfigParser::addRoutingInfoToXMLDoc(TQDomDocument *doc, TQDomNode *root, KRoutingInfo *routingInfo)
{
TQDomElement tag = doc->createElement( "gateway" );
root->appendChild( tag );
TQDomText t = doc->createTextNode( routingInfo->getGateway() );
tag.appendChild( t );
tag = doc->createElement( "gatewaydev" );
root->appendChild( tag );
t = doc->createTextNode( routingInfo->getGatewayDevice() );
tag.appendChild( t );
}
/** Loads the network info from a xml file generated by the gnome system tools
network backends that are included with this app. */
KNetworkInfo * KNetworkConfigParser::getNetworkInfo(){
return networkInfo;
}
/** Parses all of the <interface>...</interface> entries in the xml configuration file. Returns a KWirelessInterface
object that contains all the info of the wireless interface. */
KWirelessInterface * KNetworkConfigParser::getWirelessInterfaceInfo(TQDomElement interface, const TQString &type){
KWirelessInterface *wifiDevice = new KWirelessInterface();
KNetworkInterface *tempDevice = NULL;
//first we get the standard network information
tempDevice = getInterfaceInfo(interface,type);
//Then we copy the network interface info to the wireless object. I don't
//know why it doesn't work with static_cast, after doing the cast, I can't
//write to the KWirelessInterface memebers.
memcpy(wifiDevice,tempDevice,sizeof(KNetworkInterface));
//wifiDevice = static_cast<KWirelessInterface*>(tempDevice);
TQDomNode node = interface.firstChild();
while ( !node.isNull() )
{
if ( node.isElement() )
{
TQString nodeName =node.nodeName();
//Parsing --get interfaces configuration
if ( node.isElement() && node.nodeName() == "configuration" )
{
TQDomNode configNode = node.firstChild();
while ( !configNode.isNull() )
{
if ( configNode.isElement() )
{
TQString configNodeName =configNode.nodeName();
if ( configNodeName == "key" )
{
TQDomElement e = configNode.toElement();
wifiDevice->setWepKey(e.text());
}
else if ( configNodeName == "essid" )
{
TQDomElement e = configNode.toElement();
wifiDevice->setEssid(e.text());
}
else if ( configNodeName == "key_type" )
{
TQDomElement e = configNode.toElement();
wifiDevice->setKeyType(e.text());
}
configNode = configNode.nextSibling();
}
}
}
}
node = node.nextSibling();
}
return wifiDevice;
}
/** Parses all of the <interface>...</interface> entries in the xml configuration file. Returns a KNetworkInterface
object with all the info of the interface.*/
KNetworkInterface * KNetworkConfigParser::getInterfaceInfo(TQDomElement interface, const TQString &type){
TQDomNode node = interface.firstChild();
KNetworkInterface *tempDevice = new KNetworkInterface();
//tempDevice->setDescription(i18n("Ethernet Network Device"));
while ( !node.isNull() )
{
if ( node.isElement() )
{
TQString nodeName =node.nodeName();
//Parsing --get interfaces configuration
if ( node.isElement() && node.nodeName() == "configuration" )
{
TQDomNode configNode = node.firstChild();
while ( !configNode.isNull() )
{
if ( configNode.isElement() )
{
TQString configNodeName =configNode.nodeName();
if ( configNodeName == "auto" )
{
TQDomElement e = configNode.toElement();
if (e.text() == "1")
tempDevice->setOnBoot("yes");
else
tempDevice->setOnBoot("no");
}
else if ( configNodeName == "bootproto" )
{
TQDomElement e = configNode.toElement();
tempDevice->setBootProto(e.text());
}
if ( configNodeName == "address" || configNodeName == "addr")
{
TQDomElement e = configNode.toElement();
if (!e.text().isEmpty())
tempDevice->setIpAddress(e.text());
}
else if ( configNodeName == "gateway")
{
TQDomElement e = configNode.toElement();
if (!e.text().isEmpty())
tempDevice->setGateway(e.text());
}
else if ( configNodeName == "netmask" || configNodeName == "mask")
{
TQDomElement e = configNode.toElement();
if (!e.text().isEmpty())
tempDevice->setNetmask(e.text());
}
else if ( configNodeName == "network" )
{
TQDomElement e = configNode.toElement();
if (!e.text().isEmpty())
tempDevice->setNetwork(e.text());
}
else if ( configNodeName == "broadcast" || configNodeName == "bdcast")
{
TQDomElement e = configNode.toElement();
if (!e.text().isEmpty())
tempDevice->setBroadcast(e.text());
}
configNode = configNode.nextSibling();
}
}
}
//Parse -d list_ifaces interfaces configuration
if ( nodeName == "addr")
{
TQDomElement e = node.toElement();
if (!e.text().isEmpty())
tempDevice->setIpAddress(e.text());
}
else if ( nodeName == "mask")
{
TQDomElement e = node.toElement();
if (!e.text().isEmpty())
tempDevice->setNetmask(e.text());
}
else if ( nodeName == "bdcast")
{
TQDomElement e = node.toElement();
if (!e.text().isEmpty())
tempDevice->setBroadcast(e.text());
}
//These ones are common for both --get and -d list_ifaces
else if ( nodeName == "dev" )
{
TQDomElement e = node.toElement();
tempDevice->setDeviceName(e.text());
}
//we had to add the OR because the xml sintax when listing the interfaces
//is different than when loading the network info. ie.: enabled->active
//address->addr, etc...
else if ( nodeName == "enabled" || nodeName == "active")
{
TQDomElement e = node.toElement();
if (e.text() == "1")
tempDevice->setActive(true);
else
tempDevice->setActive(false);
}
else if ( nodeName == "hwaddr" )
{
TQDomElement e = node.toElement();
if (!e.text().isEmpty())
tempDevice->setMacAddress(e.text());
}
}
node = node.nextSibling();
}
if (type != TQString())
tempDevice->setType(type);
TQString description;
KSimpleConfig cfg("knetworkconfrc");
cfg.setGroup("Interfaces");
description = cfg.readEntry(tempDevice->getDeviceName());
if (!description.isEmpty())
tempDevice->setDescription(description);
else
{
if (tempDevice->getType() == ETHERNET_IFACE_TYPE)
tempDevice->setDescription(i18n("Ethernet Network Device"));
else if (tempDevice->getType() == WIRELESS_IFACE_TYPE)
tempDevice->setDescription(i18n("Wireless Network Device"));
}
//Clear IP address settings if boot protocol is dhcp or bootp, in case that they are
//setted in the config files.
if ((tempDevice->getBootProto().lower() == "dhcp") || (tempDevice->getBootProto().lower() == "bootp"))
{
tempDevice->setIpAddress("");
tempDevice->setNetmask("");
tempDevice->setNetwork("");
tempDevice->setBroadcast("");
}
return tempDevice;
}
/** Parses all of the <statichost>...</statichost> entries in the xml configuration file. */
KKnownHostInfo * KNetworkConfigParser::getStaticHostInfo(TQDomElement host)
{
TQDomNode node = host.firstChild();
KKnownHostInfo *tempHost = new KKnownHostInfo();
while ( !node.isNull() )
{
if ( node.isElement() )
{
TQString nodeName =node.nodeName();
if ( nodeName == "ip")
{
TQDomElement e = node.toElement();
if (!e.text().isEmpty())
tempHost->setIpAddress(e.text());
}
else if ( nodeName == "alias")
{
TQDomElement e = node.toElement();
if (!e.text().isEmpty())
tempHost->addAlias(e.text());
}
}
node = node.nextSibling();
}
return tempHost;
}
/** Reads the xml with the network info. */
void KNetworkConfigParser::readNetworkInfo()
{
TQPtrList<KNetworkInfo> profilesList;
//deviceList.clear();
//The gst backend puts a \n at the beginning of the xml output, so
//we have to erase it first before we can parse it.
xmlOuput = xmlOuput.section('\n',1);
tqDebug("--get XML:\n%s",xmlOuput.latin1());
//If the platform where knetworkconf is running isn't supported, show the
//user a dialog with all the supported platforms to choose.
if (xmlErr.contains("platform_unsup::"))
{
connect( this, TQ_SIGNAL(readyLoadingSupportedPlatforms()), this, TQ_SLOT(showSupportedPlatformsDialogSlot()) );
loadSupportedPlatforms();
emit errorDetectingPlatform();
}
else //parse the XML file
{
TQString err;
int x,y;
TQDomDocument doc( "network");
if ( !doc.setContent( xmlOuput.utf8(),false,&err,&x,&y ) )
{
KMessageBox::error(0,
i18n("Could not parse the XML output from the network configuration backend."),
i18n("Error Loading The Network Configuration"));
// tqDebug("error: %s %d,%d",err.latin1(),x,y);
}
TQDomElement root = doc.documentElement();
TQDomNode node = root.firstChild();
//Load first the network information
parseNetworkInfo(node, networkInfo, false);
//Then, load the network profiles
node = root.firstChild();
while( !node.isNull() )
{
if ( node.isElement())
{
TQString nodeName = node.nodeName();
if ( nodeName == "profiledb" )
{
TQDomNode profileNode = node.firstChild();
while( !profileNode.isNull() )
{
if ( profileNode.isElement())
{
TQString profileName = profileNode.nodeName();
if (profileNode.isElement() && profileName == "profile")
{
KNetworkInfo * networkProfile = new KNetworkInfo();
TQDomNode profileConfigurationNode = profileNode.firstChild();
parseNetworkInfo(profileConfigurationNode, networkProfile, true);
profilesList.append(networkProfile);
}
}
profileNode = profileNode.nextSibling();
}
}
}
node = node.nextSibling();
}
networkInfo->setProfilesList(profilesList);
}
}
void KNetworkConfigParser::parseNetworkInfo(TQDomNode node, KNetworkInfo *_networkInfo, bool isProfile){
TQPtrList<KNetworkInterface> deviceList;
KDNSInfo *_dnsInfo = new KDNSInfo();
KRoutingInfo *_routingInfo = new KRoutingInfo();
TQStringList serverList;
TQPtrList<KNetworkInterface> tempDeviceList;
TQPtrList<KKnownHostInfo> knownHostsList;
while( !node.isNull() )
{
if ( node.isElement())
{
TQString nodeName = node.nodeName();
//Get the gatway
if ( nodeName == "gateway" )
{
TQDomElement gateway = node.toElement();
_routingInfo->setGateway(gateway.text());
}
else if ( nodeName == "gatewaydev" )
{
TQDomElement gatewaydev = node.toElement();
_routingInfo->setGatewayDevice(gatewaydev.text());
}
//The name of the profile, in the case it's a profile ;)
else if ( nodeName == "name" && isProfile)
{
TQDomElement profileName = node.toElement();
_networkInfo->setProfileName(profileName.text());
}
//Get the network interfaces
else if ( nodeName == "interface" )
{
TQDomElement interface = node.toElement();
TQString attr = interface.attribute("type").lower();
//We have hardcoded to load only the supported interface types,
//for now, ethernet, loopback and wireless, thus loopback interfaces
//aren't shown.
if ( attr == ETHERNET_IFACE_TYPE || attr == LOOPBACK_IFACE_TYPE )
{
KNetworkInterface *tempDevice = NULL;
tempDevice = getInterfaceInfo(interface,attr);
deviceList.append(tempDevice);
}
else if (attr == WIRELESS_IFACE_TYPE)
{
KWirelessInterface *wifiDevice = NULL;
wifiDevice = getWirelessInterfaceInfo(interface,attr);
deviceList.append(wifiDevice);
}
}
//Get domain and host names
else if ( nodeName == "hostname" )
{
TQDomElement hostname = node.toElement();
_dnsInfo->setMachineName(hostname.text());
}
else if ( nodeName == "domain" )
{
TQDomElement domainname = node.toElement();
_dnsInfo->setDomainName(domainname.text());
}
//Get the nameServers
else if ( nodeName == "nameserver" )
{
TQDomElement nameserver = node.toElement();
serverList.append(nameserver.text());
}
//Get the static hosts
else if ( nodeName == "statichost" )
{
TQDomElement host = node.toElement();
KKnownHostInfo *tempHost = getStaticHostInfo(host);
knownHostsList.append(tempHost);
}
}
node = node.nextSibling();
}
_dnsInfo->setNameServers(serverList);
_dnsInfo->setKnownHostsList(knownHostsList);
_networkInfo->setDeviceList(deviceList);
loadRoutingInfo(_routingInfo);
_networkInfo->setRoutingInfo(_routingInfo);
_networkInfo->setDNSInfo(_dnsInfo);
//if we are loading a profile, don't try to find the IP address of DHCP
//interfaces and their states
if (!isProfile)
{
listIfaces(_networkInfo->getPlatformName());
}
//return _networkInfo;
}
void KNetworkConfigParser::readFromStdoutReloadScript(){
TQString s = procReloadNetwork->readStdout();
reloadScriptOutput.append(s);
}
/** emits a signal when the network changes have benn saved. */
void KNetworkConfigParser::sendNetworkInfoSavedSignalSlot(){
procSaveNetworkInfo->closeStdin();
}
/** Concatenates into a TQString the xml output of the network backend. */
void KNetworkConfigParser::concatXMLOutputSlot(){
xmlOuput.append(procDetect->readStdout());
}
void KNetworkConfigParser::readXMLErrSlot(){
xmlErr.append(procDetect->readStderr());
}
/** lists all platforms supported by GST. */
void KNetworkConfigParser::loadSupportedPlatforms(){
procDetect = new TQProcess(this);
procDetect->addArgument( locate("data",BACKEND_PATH) );
procDetect->addArgument( "-d" );
procDetect->addArgument( "platforms" );
connect( procDetect, TQ_SIGNAL(processExited()), this, TQ_SLOT(readSupportedPlatformsSlot()) );
xmlOuput = "";
connect( procDetect, TQ_SIGNAL(readyReadStdout()),this, TQ_SLOT(concatXMLOutputSlot()));
// connect( procDetect, TQ_SIGNAL(readyReadStderr()),this, TQ_SLOT(readXMLErrSlot()));
if ( !procDetect->start() )
{
// error handling
KMessageBox::error(0,
i18n("Could not execute backend script for the network configuration detection. Something is wrong with your installation."),
i18n("Could Not Launch Network Configuration Backend Script"));
}
}
/** Parses the xml ouput generated by GST that has all the supported platforms. */
void KNetworkConfigParser::readSupportedPlatformsSlot(){
//The gst backend puts a \n at the beginning of the xml output, so
//we have to erase it first before we parse it.
xmlOuput = xmlOuput.section('\n',1);
TQDomDocument doc( "platforms" );
if ( !doc.setContent( xmlOuput.utf8() ) )
{
KMessageBox::error(0,
i18n("Could not parse the list of supported platforms from the network configuration backend."),
i18n("Error Obtaining Supported Platforms List"));
}
TQDomElement root = doc.documentElement();
TQDomNode node = root.firstChild();
TQString s;
while( !node.isNull() )
{
if ( node.isElement() && node.nodeName() == "platform" )
{
TQDomElement platform = node.toElement();
s = getPlatformInfo(platform);
}
supportedPlatformsList << s;
node = node.nextSibling();
}
emit readyLoadingSupportedPlatforms();
}
/** Returns the info of a platform in the form of 'key:value' . */
TQString KNetworkConfigParser::getPlatformInfo(TQDomElement platform){
TQDomNode node = platform.firstChild();
TQString s;
while ( !node.isNull() )
{
if ( node.isElement() )
{
if ( node.nodeName() == "key" )
{
TQDomElement e = node.toElement();
s += e.text();
s += ":";
}
else if ( node.nodeName() == "name" )
{
TQDomElement e = node.toElement();
s += e.text();
}
}
node = node.nextSibling();
}
return s;
}
/** Shows the dialog with all the supported platforms by GST. */
void KNetworkConfigParser::showSupportedPlatformsDialogSlot(){
TDESelectDistroDlg* dialog = new TDESelectDistroDlg(0, 0);
for ( TQStringList::Iterator it = supportedPlatformsList.begin(); it != supportedPlatformsList.end(); ++it )
{
TQString key = (*it);
key = key.section(":",0,0);
TQString name = (*it);
name = name.section(":",1,1);
if (key.contains("debian"))
{
TQPixmap distroImg(locate("data","knetworkconf/pixmaps/debian.png"));
dialog->klbDistroList->insertItem(distroImg, name);
}
else if (key.contains("mandriva"))
{
TQPixmap distroImg(locate("data","knetworkconf/pixmaps/mandriva.png"));
dialog->klbDistroList->insertItem(distroImg, name);
}
else if (key.contains("conectiva"))
{
TQPixmap distroImg(locate("data","knetworkconf/pixmaps/conectiva.png"));
dialog->klbDistroList->insertItem(distroImg, name);
}
else if (key.contains("pld"))
{
TQPixmap distroImg(locate("data","knetworkconf/pixmaps/pld.png"));
dialog->klbDistroList->insertItem(distroImg, name);
}
else if (key.contains("redhat"))
{
TQPixmap distroImg(locate("data","knetworkconf/pixmaps/redhat.png"));
dialog->klbDistroList->insertItem(distroImg, name);
}
else if (key.contains("suse"))
{
TQPixmap distroImg(locate("data","knetworkconf/pixmaps/suse.png"));
dialog->klbDistroList->insertItem(distroImg, name);
}
else if (key.contains("turbolinux"))
{
TQPixmap distroImg(locate("data","knetworkconf/pixmaps/turbolinux.png"));
dialog->klbDistroList->insertItem(distroImg, name);
}
else if (key.contains("fedora"))
{
TQPixmap distroImg(locate("data","knetworkconf/pixmaps/fedora.png"));
dialog->klbDistroList->insertItem(distroImg, name);
}
else if (key.contains("openna"))
{
TQPixmap distroImg(locate("data","knetworkconf/pixmaps/openna.png"));
dialog->klbDistroList->insertItem(distroImg, name);
}
else if (key.contains("slackware"))
{
TQPixmap distroImg(locate("data","knetworkconf/pixmaps/slackware.png"));
dialog->klbDistroList->insertItem(distroImg, name);
}
else if (key.contains("freebsd"))
{
TQPixmap distroImg(locate("data","knetworkconf/pixmaps/freebsd.png"));
dialog->klbDistroList->insertItem(distroImg, name);
}
else if (key.contains("gentoo"))
{
TQPixmap distroImg(locate("data","knetworkconf/pixmaps/gentoo.png"));
dialog->klbDistroList->insertItem(distroImg, name);
}
else if (key.contains("blackpanther"))
{
TQPixmap distroImg(locate("data","knetworkconf/pixmaps/blackpanther.png"));
dialog->klbDistroList->insertItem(distroImg, name);
}
else if (key.contains("rpath"))
{
TQPixmap distroImg(locate("data","knetworkconf/pixmaps/rpath.png"));
dialog->klbDistroList->insertItem(distroImg, name);
}
else if (key.contains("vine"))
{
TQPixmap distroImg(locate("data","knetworkconf/pixmaps/vine.png"));
dialog->klbDistroList->insertItem(distroImg, name);
}
else if (key.contains("ubuntu"))
{
TQPixmap distroImg(locate("data","knetworkconf/pixmaps/kubuntu.png"));
dialog->klbDistroList->insertItem(distroImg, name);
}
else if (key.contains("yoper"))
{
TQPixmap distroImg(locate("data","knetworkconf/pixmaps/yoper.png"));
dialog->klbDistroList->insertItem(distroImg, name);
}
else if (key.contains("ark"))
{
TQPixmap distroImg(locate("data","knetworkconf/pixmaps/ark.png"));
dialog->klbDistroList->insertItem(distroImg, name);
}
}
if (!dialog->exec())
emit setReadOnly(true);
else
{
int i = 0;
TQStringList::Iterator it = supportedPlatformsList.begin();
while (i < dialog->klbDistroList->currentItem())
{
i++;
++it;
}
TQString key = (*it);
key = key.section(":",0,0);
//clean variables and run again the detection script but now don't
//auto-detect.
xmlErr = "";
xmlOuput = "";
networkInfo->setPlatformName(key);
runDetectionScript(key);
if (dialog->cbAskAgain->isChecked())
saveAskAgain(key,!dialog->cbAskAgain->isChecked());
}
}
void KNetworkConfigParser::saveAskAgain(const TQString &platform, bool askAgain)
{
KSimpleConfig cfg("knetworkconfrc");
cfg.setGroup("General");
cfg.writeEntry("detectedPlatform",platform);
cfg.writeEntry("askAgainPlatform",askAgain);
cfg.sync();
}
bool KNetworkConfigParser::readAskAgain(TQString &platform)
{
KSimpleConfig cfg("knetworkconfrc");
cfg.setGroup("General");
platform = cfg.readEntry("detectedPlatform");
return cfg.readBoolEntry("askAgainPlatform");
}
/** No descriptions */
void KNetworkConfigParser::readFromStdoutSaveNetworkInfo(){
xmlOuput.append(procSaveNetworkInfo->readStdout());
}
/** Calls runDetectionScript(). */
void KNetworkConfigParser::listIfacesSlot(){
listIfaces(networkInfo->getPlatformName());
}
/**Returns the info of the network device 'device or NULL if not found.'*/
KNetworkInterface * KNetworkConfigParser::getDeviceInfo(TQString device){
TQPtrList<KNetworkInterface> deviceList = networkInfo->getDeviceList();
TQPtrListIterator<KNetworkInterface> i(deviceList);
KNetworkInterface *temp;
while ((temp = i.current()) != 0)
{
if (temp->getDeviceName() == device)
{
return temp;
}
++i;
}
return NULL;
}