/*************************************************************************** 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, TQT_SIGNAL(readyLoadingNetworkInfo()), dialog, TQT_SLOT(close()) ); connect( this, TQT_SIGNAL(errorDetectingPlatform()), dialog, TQT_SLOT(close()) ); connect( procDetect, TQT_SIGNAL(processExited()), this, TQT_SLOT(readNetworkInfo()) ); connect( procDetect, TQT_SIGNAL(readyReadStdout()),this, TQT_SLOT(concatXMLOutputSlot())); connect( procDetect, TQT_SIGNAL(readyReadStderr()),this, TQT_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, TQT_SIGNAL(processExited()), this, TQT_SLOT(readListIfacesSlot()) ); connect( procDetect, TQT_SIGNAL(readyReadStdout()),this, TQT_SLOT(concatXMLOutputSlot())); connect( procDetect, TQT_SIGNAL(readyReadStderr()),this, TQT_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 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 Q_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 devList = networkInfo->getDeviceList(); TQPtrList 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("
").arg("
")); dialog->show(); xmlOuput = ""; connect( this, TQT_SIGNAL(readyLoadingNetworkInfo()), dialog, TQT_SLOT(close()) ); connect(procSaveNetworkInfo,TQT_SIGNAL(readyReadStdout()),this,TQT_SLOT(readFromStdoutSaveNetworkInfo())); connect(procSaveNetworkInfo,TQT_SIGNAL(wroteToStdin()),this,TQT_SLOT(sendNetworkInfoSavedSignalSlot())); connect(procSaveNetworkInfo,TQT_SIGNAL(processExited()),this,TQT_SLOT(listIfacesSlot())); processRunning = true; connect( procSaveNetworkInfo, TQT_SIGNAL(processExited()), this, TQT_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 profileList) { TQPtrListIterator profileIt(profileList); KNetworkInfo *profile; TQDomElement tag = doc->createElement( "profiledb" ); root->appendChild( tag ); while ( (profile = profileIt.current()) != 0) { ++profileIt; TQPtrList 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 devList) { KNetworkInterface *device; TQPtrListIterator 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(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 knownHostsList = dnsInfo->getKnownHostsList(); TQPtrListIterator 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 ... 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(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 ... 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 ... 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 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, TQT_SIGNAL(readyLoadingSupportedPlatforms()), this, TQT_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 deviceList; KDNSInfo *_dnsInfo = new KDNSInfo(); KRoutingInfo *_routingInfo = new KRoutingInfo(); TQStringList serverList; TQPtrList tempDeviceList; TQPtrList 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, TQT_SIGNAL(processExited()), this, TQT_SLOT(readSupportedPlatformsSlot()) ); xmlOuput = ""; connect( procDetect, TQT_SIGNAL(readyReadStdout()),this, TQT_SLOT(concatXMLOutputSlot())); // connect( procDetect, TQT_SIGNAL(readyReadStderr()),this, TQT_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(){ KSelectDistroDlg* dialog = new KSelectDistroDlg(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 deviceList = networkInfo->getDeviceList(); TQPtrListIterator i(deviceList); KNetworkInterface *temp; while ((temp = i.current()) != 0) { if (temp->getDeviceName() == device) { return temp; } ++i; } return NULL; }