From a418d8ca1e04fc4f216aa74e7827f755b02e0874 Mon Sep 17 00:00:00 2001 From: Niklas Date: Thu, 27 Oct 2011 19:58:45 +0200 Subject: disabled right click context menu, changed dialog button size (see css), changed customdhcp logger. it now sends all log messages through the socket --- src/networkdiscovery.cpp | 801 ++++++++++++++++++++++++----------------------- 1 file changed, 407 insertions(+), 394 deletions(-) (limited to 'src/networkdiscovery.cpp') diff --git a/src/networkdiscovery.cpp b/src/networkdiscovery.cpp index 13242c2..aba01b8 100644 --- a/src/networkdiscovery.cpp +++ b/src/networkdiscovery.cpp @@ -62,6 +62,7 @@ void NetworkDiscovery::initAndRun(QString serverIp, bool userChoice, bool autoUp _numberOfProcesses = 0; _ifUpCountdown = 10; + if (serverPath != DEFAULT_QTSOCKETADDRESS) { _dhcpcdArguments.append("-q"); _dhcpcdArguments.append(serverPath); @@ -74,9 +75,10 @@ void NetworkDiscovery::initAndRun(QString serverIp, bool userChoice, bool autoUp QFile::remove(serverPath); } + emit updateStatus("try to create server socket"); if (!_server->listen(serverPath)) { // emit signal to the gui that a critial error occoured - qxtLog->debug() << _tag << "Unable to start server: " + qxtLog->debug() << _tag << " Unable to start server: " << _server->errorString(); emit abortBoot("Unable to start server: " + _server->errorString()); @@ -84,6 +86,7 @@ void NetworkDiscovery::initAndRun(QString serverIp, bool userChoice, bool autoUp } // check if the path to the customdhcpcd file is correct + emit updateStatus("check if cdhcpcd is available"); QFileInfo fInfo(_pathToDhcpcdExe); if (!fInfo.exists()) { qxtLog->debug() << _tag @@ -100,256 +103,26 @@ void NetworkDiscovery::initAndRun(QString serverIp, bool userChoice, bool autoUp qxtLog->debug() << _tag << "added additional args"; _dhcpcdArguments.append(*args); } + emit updateStatus("start mainwork"); mainWork(); } -/** - * emits the addInterface signal for each interface name in _ifUpList - * and calls the runDHCPCD method. - * if the _ifUpList is empty, this method emits an abortBoot signal. - * connected to the readyForRun signal. - */ -void NetworkDiscovery::slotReadyForRun() { - if (_ifUpList.size() > 0) { - foreach(QString i, _ifUpList) { - qxtLog->debug() << _tag << "emit addInterface: " << i; - emit addInterface(i); - } - _numberOfProcesses = _ifUpList.size(); - runDHCPCD( _ifUpList); - } else { - qxtLog->debug() << _tag << "list is empty. Have not found usable interface."; - emit - abortBoot("Have not found usable interface"); - return; - } -} - - - -/** - * only called if autoUp == true. - * check the IsRunning flag of each interface in the _ifDownList. - * connected to the timeout signal of the timer. - */ -void NetworkDiscovery::checkForIsRunning() { - bool isRunning = false; - QList copyOfIfDownList(_ifDownList); - foreach(QString i, _ifDownList) { - QNetworkInterface networkInterface = QNetworkInterface::interfaceFromName(i); - isRunning = (networkInterface.flags() & QNetworkInterface::IsRunning); - if (isRunning) { - _ifUpList.append(i); - _ifDownList.removeAt(_ifDownList.indexOf(i)); - } - } - _ifUpCountdown--; - if ((_ifUpCountdown <= 0 ) || _ifDownList.isEmpty()) { - // shut down timer - _timer->stop(); - emit readyForRun(); - } -} - - - -/** - * replace the default route. sets af automatically to AF_INET - * - * @param ifName - * interface name - * - * @param gateway - * gateway address - * - * @param mss - * mss value (i think this is the metric. in most cases this value is 0) - */ -int NetworkDiscovery::ip4_replaceDefaultRoute(QString ifName, QString gateway, int mss) { - return _networkManager.replaceDefaultRoute(ifName, gateway, mss, AF_INET); -} - - - -/** - * replace the dhcp configuration with the manual config, entered by the user. - * if we can not establish a connection with the entered values, reset to the old - * dhcp values. - * - * @param result - * a json object formated string. - * - * @return - * 0 if everything ok - */ -int NetworkDiscovery::ip4_setManualConfiguration(QVariantMap result) { - QList dns; - dns.append(result["dns"].toString()); - _networkManager.ip4_setManualConfiguration(result["ifname"].toString(), - result["ipaddr"].toString(), - result["netmask"].toString(), - result["broadcast"].toString(), - result["gateway"].toString(), - 0, - AF_INET, - "/etc/", - dns); - - qxtLog->debug() << _tag << "set man conf. and check connectivity"; - - if (!checkConnectivityViaTcp(_serverIp)) { - qxtLog->debug() << _tag << "no connectivity. reset conf."; - interfaceconfiguration * ifc = _ifcMap.value(result["ifname"].toString(), NULL); - if(ifc != NULL) { - dns.clear(); - dns = ifc->getDnsservers().trimmed().split(" "); - _networkManager.ip4_setManualConfiguration(result["ifname"].toString(), - ifc->getIpAddress(), - ifc->getNetmask(), - ifc->getBroadcast(), - ifc->getGateway(), - 0, - AF_INET, - "/etc/", - dns); - } - - return 0; - } - emit continueBoot(result["ifname"].toString(), 0); - return 0; -} - - - -/** - * returns the gateway address, written into the dhcp config file. - * - * @param ifName - * name of the interface. - * - * @return - * gateway address as string. - */ -QString NetworkDiscovery::getGatewayForInterface(QString ifName) { - interfaceconfiguration * ifConf = _ifcMap.value(ifName); - return ifConf->getGateway(); -} - - - -/** - * reads the log file. - * - * @return the log file as one string. - */ -QString NetworkDiscovery::readLogFile() { - // path to log file is in _pathToLogFile. initialized in initAndRun(). - QString retval("the log file\n"); - QFile logFile(_pathToLogFile); - if (logFile.exists()) { - if (logFile.open(QIODevice::ReadOnly | QIODevice::Text)) { - while (!logFile.atEnd()) { - retval.append(logFile.readLine()); - } - return retval; - } - } - qxtLog->debug() << _tag << " could not open log file"; -} - - - -/* - *TODO: to be bug fixed - *TODO: do it with kill and not QProcess("killall cdhcpcd") - *TODO: still some bugs. if you press tryAgain it can happen that the app stops with the mainscreen. - *TODO: reproducible: start normal with user choice. plug out the cable. press continue. abort screen should appear. - *TODO: press tryAgain. - */ -void NetworkDiscovery::tryAgain() { - // kill all cdhcpcd processes - qxtLog->debug() << " kill cdhcpcd processes"; - QProcess * p = new QProcess(this); - p->start("killall cdhcpcd"); - p->waitForFinished(); - qxtLog->debug() << _tag << "[tryAgain]" << p->errorString(); - /* - foreach(Q_PID pid , _pidsList) { - if (kill(pid,SIGKILL) <= -1) - qDebug() << _tag << " error: trying to kill process: " << pid << " error: " << strerror(errno); - } - */ - // reset everything - _clients.clear(); - _clientProcessToIfNameMap.clear(); - _ifNameToClient.clear(); - _numberOfProcesses = 0; - _blocked = false; - _ifUpCountdown = 10; - _ifUpList.clear(); - _ifDownList.clear(); - _pidsList.clear(); - _ifcMap.clear(); - - // start again - mainWork(); - - //SIGK - //kill(); -} - - - -/**/ -QVariantMap NetworkDiscovery::getInterfaceConfig(QString ifName) { - QVariantMap jsonObj; - QList dns; - interfaceconfiguration * ifc = _ifcMap.value(ifName, NULL); - if (ifc != NULL) { - jsonObj.insert("ipaddr",ifc->getIpAddress()); - jsonObj.insert("netmask",ifc->getNetmask()); - jsonObj.insert("broadcast",ifc->getBroadcast()); - jsonObj.insert("gateway",ifc->getGateway()); - - dns.clear(); - dns = ifc->getDnsservers().trimmed().split(" "); - jsonObj.insert("dns",dns.first()); -// -// dns.clear(); -// dns = ifc->getDnsservers().trimmed().split(" "); -// -// //ifc->getIpAddress(), ifc->getNetmask(), ifc->getBroadcast(), -// //ifc->getGateway(), 0, AF_INET, "/etc/", dns); -// - } - return jsonObj; -} - - - -/** - * ================================================================================ - ********************************* Private Methods ******************************** - * ================================================================================ - **/ - - /**/ void NetworkDiscovery::mainWork() { if (_autoUp) { + emit updateStatus("search for usable interfaces (with auto Up)"); getListOfNetworkInterfacesWithAutoUp(); - _timer = new QTimer(this); - connect(_timer, SIGNAL(timeout()), this, SLOT(checkForIsRunning())); - _timer->start(1000); - } else { + emit updateStatus("search for usable interfaces"); getListOfNetworkInterfaces(); - emit readyForRun(); } + emit updateStatus("check if interfaces are in running state"); + _timer = new QTimer(this); + connect(_timer, SIGNAL(timeout()), this, SLOT(checkForIsRunning())); + _timer->start(1000); } @@ -368,19 +141,19 @@ void NetworkDiscovery::getListOfNetworkInterfacesWithAutoUp() { { qxtLog->debug() << _tag << "found Interface:" << nI.humanReadableName(); if ((nI.flags() & QNetworkInterface::CanBroadcast)) { - qxtLog->debug() << _tag << "flags: can broadcast"; + qxtLog->debug() << _tag << " flags: can broadcast "; } if ((nI.flags() & QNetworkInterface::IsLoopBack)) { - qxtLog->debug() << _tag << "flags: is LoopBack"; + qxtLog->debug() << _tag << " flags: is LoopBack "; } if ((nI.flags() & QNetworkInterface::IsPointToPoint)) { - qxtLog->debug() << _tag << "flags: is Point to Point"; + qxtLog->debug() << _tag << " flags: is Point to Point "; } if ((nI.flags() & QNetworkInterface::IsRunning)) { - qxtLog->debug() << _tag << "flags: is Running"; + qxtLog->debug() << _tag << " flags: is Running "; } if ((nI.flags() & QNetworkInterface::IsUp)) { - qxtLog->debug() << _tag << "flags: is Up"; + qxtLog->debug() << _tag << " flags: is Up "; } if (((!(nI.flags() & QNetworkInterface::CanBroadcast) @@ -394,7 +167,7 @@ void NetworkDiscovery::getListOfNetworkInterfacesWithAutoUp() { } else if (!(nI.flags() & QNetworkInterface::IsUp)) { _networkManager.bringInterfaceUP(nI.humanReadableName()); - qxtLog->debug() << _tag << " bring up .."; + qxtLog->debug() << _tag << " bring up: " << nI.humanReadableName() ; _ifDownList.append(nI.humanReadableName()); } else if (!(nI.flags() & QNetworkInterface::IsRunning)) { @@ -402,7 +175,7 @@ void NetworkDiscovery::getListOfNetworkInterfacesWithAutoUp() { } } } else { - qxtLog->debug() << _tag << "no interfaces found!"; + qxtLog->debug() << _tag << " no interfaces found! "; } } @@ -418,7 +191,23 @@ void NetworkDiscovery::getListOfNetworkInterfaces() { if (nIList.size() > 0) { foreach(QNetworkInterface nI, nIList) { - qxtLog->debug() << _tag << "found Interface:" << nI.humanReadableName(); + qxtLog->debug() << _tag << "found Interface:" + << nI.humanReadableName(); + if ((nI.flags() & QNetworkInterface::CanBroadcast)) { + qxtLog->debug() << _tag << " flags: can broadcast "; + } + if ((nI.flags() & QNetworkInterface::IsLoopBack)) { + qxtLog->debug() << _tag << " flags: is LoopBack "; + } + if ((nI.flags() & QNetworkInterface::IsPointToPoint)) { + qxtLog->debug() << _tag << " flags: is Point to Point "; + } + if ((nI.flags() & QNetworkInterface::IsRunning)) { + qxtLog->debug() << _tag << " flags: is Running "; + } + if ((nI.flags() & QNetworkInterface::IsUp)) { + qxtLog->debug() << _tag << " flags: is Up "; + } if (((!(nI.flags() & QNetworkInterface::CanBroadcast) || nI.flags() & QNetworkInterface::IsLoopBack) || nI.flags() & QNetworkInterface::IsPointToPoint) @@ -433,58 +222,59 @@ void NetworkDiscovery::getListOfNetworkInterfaces() { } } } else { - qxtLog->debug() << _tag << "no interfaces found!"; + qxtLog->debug() << _tag << " no interfaces found! "; } } /** - * not used so far. checks the carrier state using the sysfs library. - * if carrier = 1 ==> the interface is running. - * interfaces have to be up in order to get right results. - * - * @param interface - * name of the interface + * only called if autoUp == true. + * check the IsRunning flag of each interface in the _ifDownList. + * connected to the timeout signal of the timer. */ -bool NetworkDiscovery::checkCarrierState(QString interface) { +void NetworkDiscovery::checkForIsRunning() { + bool isRunning = false; + foreach(QString i, _ifDownList) { + QNetworkInterface networkInterface = QNetworkInterface::interfaceFromName(i); + isRunning = (networkInterface.flags() & QNetworkInterface::IsRunning); + if (isRunning) { + _ifUpList.append(i); + _ifDownList.removeAt(_ifDownList.indexOf(i)); + } + } + _ifUpCountdown--; + if ((_ifUpCountdown <= 0 ) || _ifDownList.isEmpty()) { + // shut down timer + _timer->stop(); + delete _timer; + emit readyForRun(); + } +} - qxtLog->debug() << _tag << "check carrier state for interface " << interface; - QByteArray ba = interface.toAscii(); - const char * iface = ba.data(); - struct sysfs_class_device *class_device = sysfs_open_class_device("net", - iface); - struct dlist *attrlist = sysfs_get_classdev_attributes(class_device); - if (attrlist != NULL) { - struct sysfs_attribute *attr = NULL; - dlist_for_each_data(attrlist, attr, struct sysfs_attribute) { - if (strcmp("carrier", attr->name) == 0) { - QString value(attr->value); - bool ok = false; - bool * pok = &ok; - int v = value.toInt(pok); - if (*pok) { - if (v == 1) { - qxtLog->debug() - << "carrier is 1. Cable is plugged. return true"; - return true; - } else { - qxtLog->debug() - << "carrier is 0. Cable is unplugged. return false"; - return false; - } - } else { - qxtLog->debug() << _tag << "conversion error"; - } - } + +/** + * emits the addInterface signal for each interface name in _ifUpList + * and calls the runDHCPCD method. + * if the _ifUpList is empty, this method emits an abortBoot signal. + * connected to the readyForRun signal. + */ +void NetworkDiscovery::slotReadyForRun() { + if (_ifUpList.size() > 0) { + foreach(QString i, _ifUpList) { + qxtLog->debug() << _tag << " emit addInterface : " << i; + emit addInterface(i); } + _numberOfProcesses = _ifUpList.size(); + emit updateStatus("start dhcp client for each interface"); + runDHCPCD( _ifUpList); } else { - qxtLog->debug() << _tag << "attrlist is Null"; + qxtLog->debug() << _tag << " list is empty. Have not found usable interface. "; + emit + abortBoot("Have not found usable interface"); + return; } - sysfs_close_class_device(class_device); - - return true; } @@ -511,11 +301,11 @@ void NetworkDiscovery::runDHCPCD(QList &interfaces) { * name of an interface. */ void NetworkDiscovery::runDHCPCD(QString interface) { - emit updateStatusLabel(interface, "start DHCP"); + emit updateIfStatus(interface, "start DHCP"); _dhcpcdArguments.append(interface); QProcess * p = new QProcess(this); - qxtLog->debug() << _tag << _dhcpcdArguments; + qxtLog->debug() << _tag << " start cdhcpcd with arguments: " << _dhcpcdArguments; _clientProcessToIfNameMap.insert(p, interface); p->start(_pathToDhcpcdExe, _dhcpcdArguments); @@ -527,6 +317,88 @@ void NetworkDiscovery::runDHCPCD(QString interface) { +/** + * This Method is called when a process is started. + * + * This Method is called when a process is started. + * It prints the message: "process started for interface: ". + */ +void NetworkDiscovery::handleProcessStarted() { + QProcess* p = qobject_cast (QObject::sender()); + QString ifName = _clientProcessToIfNameMap.value(p, "ifName"); + qxtLog->debug() << _tag << " process started for interface: " << ifName; +} + + + +/** + * This Method is called when a process is finished. + * + * This Method is called when a process is finished. This slot is connected + * with the signal finished() of the QProcess class. + * If the process finishes, it will be checked if the process exited normal + * or if an unexpected error occurred. For this, we determine the sender (which is a + * QProcess), get the corresponding interface (which is stored in a map), and check + * the exitCode. Further actions are taken according to the exitCode check. + * Normal exit: + * emit changeProgressBar() to 100% + * emit updateIfStatus() to check connection + * checkConnectivity() @see NetworkDiscovery::checkConnectivity() + * Unexpected exit: + * emit updateIfStatus() to process exited unexpected + * TODO:: the reason for the unexpected exit should be presented in the logfile. + * + * @param exitCode + * + * @param exitStatus + * + * @return bool + * returns true: if the interface name i starts with a letter in the blacklist. + * + * returns false: else + * + * @see NetworkDiscovery::getListOfNetworkInterfaces() + */ +void NetworkDiscovery::handleProcessFinished(int exitCode, + QProcess::ExitStatus exitStatus) { + + QProcess* p = qobject_cast (QObject::sender()); + QString ifName = _clientProcessToIfNameMap.value(p, "ifName"); + _numberOfProcesses = _numberOfProcesses - 1; + if (!_blocked) { //_blocked becomes true, if _userChoice is false and we already found a usable interface + if (ifName.compare("ifName") == 0) { + qxtLog->debug() << _tag << " haven't found process!"; + } else { + qxtLog->debug() << _tag << " process for interface " << ifName << " finished " + << " exit code: " << exitCode << " exit status " << exitStatus; + if (exitCode > 0) { + qxtLog->debug() << _tag << " process exited unexpected: " << p->errorString(); + emit updateIfStatus(ifName, "process exited unexpected" + p->errorString()); + } else { + qxtLog->debug() << _tag << " process normal exit "; + emit changeProgressBarValue(ifName, 100); + emit updateIfStatus(ifName, "check connectivity"); + checkConnectivity(ifName); + } + } + if (!_blocked) { //_blocked becomes true, if _userChoice is false and we found a usable interface + QLocalSocket *client = _ifNameToClient.value(ifName, 0); + if (client != 0) { + handleNewInput(client); + } + //_numberOfProcesses = _numberOfProcesses - 1; && _userChoice + if (_numberOfProcesses <= 0 ) { + emit allProcessesFinished(); + } + } + } else { + qxtLog->debug() << _tag << " already blocked"; + emit updateIfStatus(ifName, "finished DHCP"); + } +} + + + /** * checks the connectivity. tries to open a TCP connection to the * server (see _serverIp). For this it adjusts the routing table. @@ -557,9 +429,9 @@ bool NetworkDiscovery::checkConnectivity(QString ifName) { ifConf->getGateway(), mss, AF_INET); if (checkConnectivityViaTcp(_serverIp)) { - qxtLog->debug() << _tag << "internet: check passed! for interface" << ifName; + qxtLog->debug() << _tag << " passed connectivity check! for interface " << ifName; emit - updateStatusLabel(ifName, "connection possible"); + updateIfStatus(ifName, "connection possible"); if (!_userChoice) { // blockiere jeden weiteren check // emite continueBoot @@ -570,9 +442,9 @@ bool NetworkDiscovery::checkConnectivity(QString ifName) { } return true; } else { - qxtLog->debug() << _tag << "no internet connection with interface" << ifName; + qxtLog->debug() << _tag << " failed connectivity check! for interface " << ifName; emit - updateStatusLabel(ifName, "connection not possible"); + updateIfStatus(ifName, "connection not possible"); return false; } } @@ -603,41 +475,9 @@ bool NetworkDiscovery::checkConnectivityViaTcp(QString server) { if (!tcpSocket->waitForConnected(500)) { qxtLog->debug() << _tag << tcpSocket->errorString(); return false; - } else { - return true; - } -} - - - -/** - * connected to the new client arrived signal. - * connects the client readyRead signal with the handleNewInput slot. - */ -void NetworkDiscovery::handleNewConnection() { - qxtLog->debug() << _tag << "New Connection arrived"; - - /*QLocalSocket **/ - _client = _server ->nextPendingConnection(); - _clients.insert(_client, _client); - connect(_client, SIGNAL(disconnected()), this, - SLOT(handleClientDisconnect())); - connect(_client, SIGNAL(readyRead()), this, SLOT(handleNewInput())); -} - - - -/** - * called when a client disconnects. - */ -void NetworkDiscovery::handleClientDisconnect() { - QLocalSocket* socket = qobject_cast (QObject::sender()); - - QLocalSocket * client = _clients.value(socket); - - qxtLog->debug() << _tag << "disconnect client"; - handleNewInput(client); - client->deleteLater(); + } else { + return true; + } } @@ -675,12 +515,8 @@ void NetworkDiscovery::handleNewInput() { QLocalSocket * client = _clients.value(socket); QString data(client->read(DHCP_MESSAGE_SIZE)); - //client->write("ACK", ACK_SIZE); - //client->waitForBytesWritten(); data = data.trimmed(); - //qxtLog->debug() << _tag << data; QStringList lines = data.split("\n"); - for (int i = 0; i < lines.length(); i++) { handleNewInputLine(client, lines.at(i)); } @@ -772,17 +608,17 @@ void NetworkDiscovery::handleNewInputLine(QLocalSocket * client, QString data) { qxtLog->debug() << _tag << " " << interface << " exiting"; break; case DHCPCD_LOG: - + qxtLog->debug() << _tag << " received dhcpcd log: " << msg; default: - qxtLog->debug() << _tag << " received error:" << msg; + qxtLog->debug() << _tag << " received unknown substatus: " << msg; break; } break; case LOG_ERR: - qxtLog->debug() << _tag << " received error:" << msg; + qxtLog->debug() << _tag << " received error: " << msg; break; default: - qxtLog->debug() << _tag << logMsg; + qxtLog->debug() << _tag << " " << logMsg; break; } } @@ -790,83 +626,208 @@ void NetworkDiscovery::handleNewInputLine(QLocalSocket * client, QString data) { /** - * This Method is called when a process is finished. + * replace the default route. sets af automatically to AF_INET * - * This Method is called when a process is finished. This slot is connected - * with the signal finished() of the QProcess class. - * If the process finishes, it will be checked if the process exited normal - * or if an unexpected error occurred. For this, we determine the sender (which is a - * QProcess), get the corresponding interface (which is stored in a map), and check - * the exitCode. Further actions are taken according to the exitCode check. - * Normal exit: - * emit changeProgressBar() to 100% - * emit updateStatusLabel() to check connection - * checkConnectivity() @see NetworkDiscovery::checkConnectivity() - * Unexpected exit: - * emit updateStatusLabel() to process exited unexpected - * TODO:: the reason for the unexpected exit should be presented in the logfile. + * @param ifName + * interface name * - * @param exitCode + * @param gateway + * gateway address * - * @param exitStatus + * @param mss + * mss value (i think this is the metric. in most cases this value is 0) + */ +int NetworkDiscovery::ip4_replaceDefaultRoute(QString ifName, QString gateway, int mss) { + return _networkManager.replaceDefaultRoute(ifName, gateway, mss, AF_INET); +} + + + +/** + * replace the dhcp configuration with the manual config, entered by the user. + * if we can not establish a connection with the entered values, reset to the old + * dhcp values. * - * @return bool - * returns true: if the interface name i starts with a letter in the blacklist. + * @param result + * a json object formated string. * - * returns false: else + * @return + * 0 if everything ok + */ +int NetworkDiscovery::ip4_setManualConfiguration(QVariantMap result) { + QList dns; + dns.append(result["dns"].toString()); + _networkManager.ip4_setManualConfiguration(result["ifname"].toString(), + result["ipaddr"].toString(), result["netmask"].toString(), + result["broadcast"].toString(), result["gateway"].toString(), 0, + AF_INET, "/etc/", dns); + + qxtLog->debug() << _tag << "set man conf. and check connectivity"; + + if (!checkConnectivityViaTcp(_serverIp)) { + qxtLog->debug() << _tag << "no connectivity. reset conf."; + interfaceconfiguration * ifc = _ifcMap.value( + result["ifname"].toString(), NULL); + if (ifc != NULL) { + dns.clear(); + dns = ifc->getDnsservers().trimmed().split(" "); + _networkManager.ip4_setManualConfiguration( + result["ifname"].toString(), ifc->getIpAddress(), + ifc->getNetmask(), ifc->getBroadcast(), ifc->getGateway(), + 0, AF_INET, "/etc/", dns); + } + + return 0; + } emit + continueBoot(result["ifname"].toString(), 0); + return 0; +} + + + +/** + * returns the gateway address, written into the dhcp config file. * - * @see NetworkDiscovery::getListOfNetworkInterfaces() + * @param ifName + * name of the interface. + * + * @return + * gateway address as string. or empty string if no interface config was found. */ -void NetworkDiscovery::handleProcessFinished(int exitCode, - QProcess::ExitStatus exitStatus) { +QString NetworkDiscovery::getGatewayForInterface(QString ifName) { + interfaceconfiguration * ifConf = _ifcMap.value(ifName, NULL); + if (ifConf != NULL) + { + return ifConf->getGateway(); + } + else { + qxtLog->debug() << _tag << " could not find interface configuration"; + return ""; + } - QProcess* p = qobject_cast (QObject::sender()); - QString ifName = _clientProcessToIfNameMap.value(p, "ifName"); - _numberOfProcesses = _numberOfProcesses - 1; - if (!_blocked) { //_blocked becomes true, if _userChoice is false and we already found a usable interface - if (ifName.compare("ifName") == 0) { - qxtLog->debug() << _tag << "--- \t [NetworkDiscovery::handleProcessFinished] haven't found process!"; - } else { - qxtLog->debug() << _tag << " process for interface " << ifName << " finished " - << " exit code: " << exitCode << " exit status " << exitStatus; - if (exitCode > 0) { - qxtLog->debug() << _tag << "process exited unexpected"; - emit updateStatusLabel(ifName, "process exited unexpected"); - } else { - qxtLog->debug() << _tag << "process normal exit"; - emit changeProgressBarValue(ifName, 100); - emit updateStatusLabel(ifName, "check connectivity"); - checkConnectivity(ifName); +} + + + +/** + * reads the log file. + * + * @return the log file as one string. + */ +QString NetworkDiscovery::readLogFile() { + // path to log file is in _pathToLogFile. initialized in initAndRun(). + QString retval("the log file\n"); + QFile logFile(_pathToLogFile); + if (logFile.exists()) { + if (logFile.open(QIODevice::ReadOnly | QIODevice::Text)) { + while (!logFile.atEnd()) { + retval.append(logFile.readLine()); } } - if (!_blocked) { //_blocked becomes true, if _userChoice is false and we found a usable interface - QLocalSocket *client = _ifNameToClient.value(ifName, 0); - if (client != 0) { - handleNewInput(client); - } - //_numberOfProcesses = _numberOfProcesses - 1; && _userChoice - if (_numberOfProcesses <= 0 ) { - emit allProcessesFinished(); - } + else { + qxtLog->debug() << _tag << " could not open log file"; + retval = "could not open log file"; } - } else { - qxtLog->debug() << _tag << "already blocked"; - emit updateStatusLabel(ifName, "finished DHCP"); } + else { + qxtLog->debug() << _tag << " log file does not exist at: " << _pathToLogFile; + retval = " log file does not exist at: " + _pathToLogFile; + } + return retval; + +} + + + +/* + *TODO: to be bug fixed + *TODO: do it with kill and not QProcess("killall cdhcpcd") + *TODO: still some bugs. if you press tryAgain it can happen that the app stops with the mainscreen. + *TODO: reproducible: start normal with user choice. plug out the cable. press continue. abort screen should appear. + *TODO: press tryAgain. + */ +void NetworkDiscovery::tryAgain() { + // kill all cdhcpcd processes + qxtLog->debug() << " kill cdhcpcd processes"; + QProcess * p = new QProcess(this); + p->start("killall cdhcpcd"); + p->waitForFinished(); + if (p->exitCode() > 0) + qxtLog->debug() << _tag << "[tryAgain]" << p->errorString(); + + delete p; + /* + foreach(Q_PID pid , _pidsList) { + if (kill(pid,SIGKILL) <= -1) + qDebug() << _tag << " error: trying to kill process: " << pid << " error: " << strerror(errno); + } + */ + // reset everything + _clients.clear(); + _clientProcessToIfNameMap.clear(); + _ifNameToClient.clear(); + _numberOfProcesses = 0; + _blocked = false; + _ifUpCountdown = 10; + _ifUpList.clear(); + _ifDownList.clear(); + _pidsList.clear(); + _ifcMap.clear(); + + // start again + mainWork(); +} + + + +/**/ +QVariantMap NetworkDiscovery::getInterfaceConfig(QString ifName) { + QVariantMap jsonObj; + QList dns; + interfaceconfiguration * ifc = _ifcMap.value(ifName, NULL); + if (ifc != NULL) { + jsonObj.insert("ipaddr",ifc->getIpAddress()); + jsonObj.insert("netmask",ifc->getNetmask()); + jsonObj.insert("broadcast",ifc->getBroadcast()); + jsonObj.insert("gateway",ifc->getGateway()); + + dns.clear(); + dns = ifc->getDnsservers().trimmed().split(" "); + jsonObj.insert("dns",dns.first()); + } + return jsonObj; } /** - * This Method is called when a process is started. - * - * This Method is called when a process is started. - * It prints the message: "process started for interface: ". + * connected to the new client arrived signal. + * connects the client readyRead signal with the handleNewInput slot. */ -void NetworkDiscovery::handleProcessStarted() { - QProcess* p = qobject_cast (QObject::sender()); - QString ifName = _clientProcessToIfNameMap.value(p, "ifName"); - qxtLog->debug() << _tag << "process started for interface:" << ifName; +void NetworkDiscovery::handleNewConnection() { + qxtLog->debug() << _tag << "New Connection arrived"; + + /*QLocalSocket **/ + _client = _server->nextPendingConnection(); + _clients.insert(_client, _client); + connect(_client, SIGNAL(disconnected()), this, + SLOT(handleClientDisconnect())); + connect(_client, SIGNAL(readyRead()), this, SLOT(handleNewInput())); +} + + + +/** + * called when a client disconnects. + */ +void NetworkDiscovery::handleClientDisconnect() { + QLocalSocket* socket = qobject_cast (QObject::sender()); + + QLocalSocket * client = _clients.value(socket); + + qxtLog->debug() << _tag << "disconnect client"; + handleNewInput(client); + client->deleteLater(); } @@ -898,3 +859,55 @@ bool NetworkDiscovery::checkBlackList(QString i) { return false; } } + + + +////////////////////////////////////////////////////////////////////////////////////// + +/** + * not used so far. checks the carrier state using the sysfs library. + * if carrier = 1 ==> the interface is running. + * interfaces have to be up in order to get right results. + * + * @param interface + * name of the interface + */ +bool NetworkDiscovery::checkCarrierState(QString interface) { + + qxtLog->debug() << _tag << "check carrier state for interface " << interface; + QByteArray ba = interface.toAscii(); + const char * iface = ba.data(); + + struct sysfs_class_device *class_device = sysfs_open_class_device("net", + iface); + struct dlist *attrlist = sysfs_get_classdev_attributes(class_device); + if (attrlist != NULL) { + struct sysfs_attribute *attr = NULL; + dlist_for_each_data(attrlist, attr, struct sysfs_attribute) { + if (strcmp("carrier", attr->name) == 0) { + QString value(attr->value); + bool ok = false; + bool * pok = &ok; + int v = value.toInt(pok); + if (*pok) { + if (v == 1) { + qxtLog->debug() + << "carrier is 1. Cable is plugged. return true"; + return true; + } else { + qxtLog->debug() + << "carrier is 0. Cable is unplugged. return false"; + return false; + } + } else { + qxtLog->debug() << _tag << "conversion error"; + } + } + } + } else { + qxtLog->debug() << _tag << "attrlist is Null"; + } + sysfs_close_class_device(class_device); + + return true; +} -- cgit v1.2.3-55-g7522