#include #include #include #include #if 0 #include // available since Qt 4.7 #endif #include // for HOST_NAME_MAX #include // for gethostname(), getuid() #include // for getuid, getpwuid #include // for getpwuid #include "globals.h" #include "vsession.h" bool VSession::init(const QString& xml, const QString& baseDirPath) { printf("VSession::init(xml, %s)\n", baseDirPath.toAscii().data()); //printf("xml = %s\n", xml.toAscii().data()); this->baseDirPath_ = baseDirPath; return this->doc_.setContent(xml); } void VSession::addNodeWithAttribute(const QString& nodeName, const QString& value, const QString& attribute, bool replace) { printf("VSession:addNodeWithAttribute(%s, %s, %s, %d)\n", nodeName.toUtf8().data(), value.toUtf8().data(), attribute.toUtf8().data(), replace); QDomElement node = this->doc_.namedItem("eintrag").namedItem(nodeName).toElement(); if (replace == false || node.isNull()) { printf(" creating new node\n"); // create a new node node = this->doc_.createElement(nodeName); this->doc_.namedItem("eintrag").appendChild(node); } printf(" setting attribute\n"); node.setAttribute(attribute, value); } QString VSession::toXml() const { return this->doc_.toString(); } QString VSession::getAttribute(const QString &nodeName, const QString &attribute) const { printf ("VSession::getAttribute(%s, %s)\n", nodeName.toAscii().data(), attribute.toAscii().data()); QDomDocument doc = this->doc_; //printf (" doc xml:\n%s\n", doc.toString().toAscii().data()); QDomNode n = doc.namedItem("eintrag").namedItem(nodeName); if (n.isNull()) { printf(" failed to find node\n"); } printf(" node name: %s\n", n.nodeName().toAscii().data()); printf(" node type: %d\n", n.nodeType()); printf(" node value: %s\n", n.nodeValue().toAscii().data()); printf(" attribute %s=%s\n", attribute.toUtf8().data(), this->doc_.namedItem("eintrag").namedItem(nodeName).toElement().attribute(attribute).toUtf8().data()); //printf (" --> %s\n", this->doc_.namedItem("eintrag").namedItem(nodeName).namedItem(attribute).toAttr().value()); return this->doc_.namedItem("eintrag").namedItem(nodeName).toElement().attribute(attribute); } QString VSession::getNodeText(const QString& nodeName) const { return this->doc_.namedItem(nodeName).toText().data(); } ImgType VSession::imgtype() const { QString s(getAttribute("virtualmachine")); if (s.compare("vmware") == 0) { return VMWARE; } else if (s.compare("virtualbox") == 0 || s.compare("vbox") == 0) { return VBOX; } else { return OTHER; } } bool VSession::isActive() const { // default to true return getAttribute("active").compare("false"); } bool VSession::isLocked() const { // default to false return getAttribute("locked").compare("true") == 0; } int VSession::priority() const { return getAttribute("priority").toInt(); } void VSession::addPrinters(const QString& script, const QString& type) { QDomElement printersNode = this->doc_.namedItem("eintrag").namedItem(type + "s").toElement(); if (printersNode.isNull()) { // create new printers node printersNode = this->doc_.createElement(type + "s"); this->doc_.namedItem("eintrag").appendChild(printersNode); } QProcess addPrintersScript; addPrintersScript.start(script, QIODevice::ReadOnly); while (! addPrintersScript.atEnd()) { QString line(addPrintersScript.readLine()); QStringList tokens(line.split("\t")); if (tokens.size() < 2 or tokens.size() > 3) { // TODO error message // invalid output of printerScript //printserver\tprinter\tprinter description continue; } // TODO: check return values, exceptions, ... QDomElement printerNode(doc_.createElement(type)); printerNode.setAttribute("name", tokens.at(1)); printerNode.setAttribute("path", "\\\\" + tokens.at(0) + "\\" + tokens.at(1)); if (tokens.size() == 3) { QDomText printerDescriptionNode(doc_.createTextNode(tokens.at(3))); printerNode.appendChild(printerDescriptionNode); } printersNode.appendChild(printerNode); } addPrintersScript.close(); return; } void VSession::addScanners(const QString& script) { addPrinters(script, "scanner"); } void VSession::addUserAndHostname() { printf("VSession::addUserAndHostname()\n"); QString username(getpwuid(geteuid())->pw_name); this->addNodeWithAttribute("username", username); // Qt >= 4.7 has //QString hostname(QHostInfo::localHostName()); char hname[HOST_NAME_MAX + 1]; gethostname(hname, HOST_NAME_MAX); QString hostname(hname); this->addNodeWithAttribute("hostname", hostname); QString image(this->getAttribute("image_name")); if (QFileInfo(image).isRelative()) { // make path to image absolute this->addNodeWithAttribute("image_name", this->baseDirPath_ + image); } // insert computername as the first child of // bootpgm needs computername within the first 500 bytes QDomElement computername(doc_.createElement("computername")); computername.setAttribute("param", hostname); this->doc_.namedItem("eintrag").insertBefore(computername, QDomNode()); } bool VSession::run() const { printf("VSession::run()\n"); QString command = getAttribute("command"); if (! command.isEmpty()) { if (QProcess::startDetached(command)) { // TODO: save session return true; } return false; } VSession session = *this; QString etcpath(VMCHOOSER_ETC_BASE_PATH); // TODO: put script names in (global?) constants session.addPrinters(etcpath + "printer.sh"); session.addScanners(etcpath + "scanner.sh"); session.addUserAndHostname(); // TODO: read the group configuration XML //session.readGroupXml(&dat, env); // write xml to temporary file QTemporaryFile tmpfile(QDir::tempPath() + "/vmchooser-XXXXXX.xml"); if (!tmpfile.open() || tmpfile.write(session.toXml().toUtf8()) == -1) { return false; } tmpfile.close(); tmpfile.setAutoRemove(false); // TODO: put script name in constant QString runVmScript(QString(VMCHOOSER_BIN_PATH) + "run-virt.sh"); if (QProcess::startDetached(runVmScript, QStringList(tmpfile.fileName()))) { // TODO: save session return true; } return false; } QList VSession::readXmlFile(const QString& filepath) { printf("VSession::readXmlFile(%s)\n", filepath.toAscii().data()); QList retval; QDomDocument doc; QFile file(filepath); if (!file.open(QIODevice::ReadOnly)) { // TODO: error message printf("error: cannot open file\n"); return retval; } if (!doc.setContent(&file)) { // TODO: error message printf("error: cannot parse file\n"); file.close(); return retval; } file.close(); // TODO: iterate over all child nodes? QString dirName(QFileInfo(filepath).dir().absolutePath()); QDomElement settingsNode = doc.firstChildElement("settings"); for (QDomElement el(settingsNode.firstChildElement("eintrag")); !el.isNull(); el = el.nextSiblingElement("eintrag")) { printf("reading %s node\n", el.tagName().toAscii().data()); QDomDocument dummy; dummy.appendChild(dummy.importNode(el, true)); VSession* e = new VSession; if (e->init(dummy.toString(), dirName)) { printf("appending node\n"); retval.append(e); } } return retval; } /** * - calls xmlfilter.sh to glob a folder for xmls * -> if no xmlfilter.sh is available, it globs for available xmls * - reads all xml files and creates for each its own VSession-struct */ QList VSession::readXmlDir(const QString& path) { printf("VSession::readXmlDir(%s)\n", path.toAscii().data()); QList retval; QDir appDir(QApplication::applicationDirPath()); if (QFile::exists(appDir.filePath(filterscript))) { // run filterscript // treat every output line as a filename and read it QProcess myFilterScript; myFilterScript.start(appDir.filePath(filterscript), QStringList(path), QIODevice::ReadOnly); while (! myFilterScript.atEnd()) { QString filename(myFilterScript.readLine()); if (QDir::isRelativePath(filename)) { filename.prepend(path + "/"); } retval.append(readXmlFile(filename)); } myFilterScript.close(); } else { // iterate over all .xml files in directory path and read them foreach (QFileInfo fi, QDir(path).entryInfoList(QStringList("*.xml"))) { retval.append(readXmlFile(fi.absoluteFilePath())); } } printf("VSession::readXmlDir(%s), read %d entries\n", path.toAscii().data(), retval.size()); return retval; } bool VSession::operator<(const Session& other) const { int p0 = this->priority(); int p1 = other.priority(); if (p0 < p1) return true; if (p0 == p1) { QString d0 = this->shortDescription(); QString d1 = other.shortDescription(); return d0.localeAwareCompare(d1) < 0; } return false; }