From 6117049617df720fb744a90773a3580b3450b005 Mon Sep 17 00:00:00 2001 From: Jan Darmochwal Date: Sat, 2 Oct 2010 18:50:09 +0200 Subject: Qt port is almost complete (at least it compiles) Major change: * struct DataEntry has become class Session with sub-classes XSession and VSession * functions from addInfo.cpp, addPrinters.cpp, addScanners.cpp, readLinSess.cpp, readXmlDir.cpp, runImage.cpp have been moved to XSession and VSession Several minor changes: * new files globals.h and globals.cpp for global variables (replaces constants.h and paths.h) * replaced (all) libxml2, (much) std:: and (most) boost:: stuff by Qt stuff Things left to do: * remove tons of debug printfs * show error messages on errors * tidy up anyoption stuff in main() * highlight session run previously * readGroupXml stuff * tree view (with "X Sessions" and "Virtual Sessions" sections) instead of list view for session selection --- src/vsession.cpp | 295 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 295 insertions(+) create mode 100644 src/vsession.cpp (limited to 'src/vsession.cpp') diff --git a/src/vsession.cpp b/src/vsession.cpp new file mode 100644 index 0000000..3fa385f --- /dev/null +++ b/src/vsession.cpp @@ -0,0 +1,295 @@ +#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() { + + 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; +} -- cgit v1.2.3-55-g7522