summaryrefslogblamecommitdiffstats
path: root/src/addInfo.cpp
blob: 1eb22134f456a1aa614ed5d2742b8a4c2079249e (plain) (tree)
1
2
3
4
5
6
7
8
9

                      

                   
                  



                      

                               






                                  
 






                                                       
                                             



























































































































































                                                                                             










                                                     
                                    
                                           



















































































































































                                                                                                                     

 
#include "functions.h"
#include "paths.h"

#include <iostream>
#include <fstream>
#include <unistd.h>
#include <pwd.h>
#include <sys/types.h>

#include "boost/filesystem.hpp"

#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/xpath.h>

namespace bfs = boost::filesystem;

extern string env;

/******************************************
 * Adds user info and hostname to xml
 *
 * usernode: <username param="user" />
 * hostnamenode: <hostname param="host" />
 * computername: needed for bootpgm <computername .../>
 ******************************************/
void addInfo(xmlNode* node, DataEntry* dat) {

	if (node == NULL) {
		return;
	}

	bool user = false;
	bool host = false;

	const int MAX_LENGTH = 200;
	char hostname[MAX_LENGTH];
	uid_t id;
	passwd *pwd;

	string strline;
	xmlNodePtr cur = node->children;
	xmlNodePtr usernode = NULL;
	xmlNodePtr hostnamenode = NULL;
	xmlNodePtr compnamenode = NULL;
	xmlNodePtr filenamenode = NULL;
	xmlNodePtr firstchild = node->children;

	// just use some standard Linux functions here ...
	id = geteuid(); // gets effective user id
	pwd = getpwuid(id); // gets passwd struct (including username)
	gethostname(hostname, MAX_LENGTH - 1); // gets hostname

	// Get <username> node and add "username#param" attribute
	while (cur != NULL) {
		if (!xmlStrcmp(cur->name, (const xmlChar *) "username")) {
			user = true;
			usernode = cur;
			break;
		}
		cur = cur->next;
	}
	if (!user) {
		usernode = xmlNewNode(NULL, (const xmlChar*) "username");
		if (usernode != NULL) {
			xmlNewProp(usernode, (const xmlChar*) "param",
					(const xmlChar*) pwd->pw_name);
			xmlAddChild(node, usernode);
		} else {
			cerr << "<username> node could not be created!" << endl;
		}
	} else {
		// set param attribute in <username>
		xmlSetProp(usernode, (const xmlChar*) "param",
				(const xmlChar*) pwd->pw_name);
	}

	cur = node->children;

	// Get <hostname> node and add "hostname#param" attribute
	while (cur != NULL) {
		if (!xmlStrcmp(cur->name, (const xmlChar *) "hostname")) {
			host = true;
			hostnamenode = cur;
			break;
		}
		cur = cur->next;
	}
	if (!host) {
		hostnamenode = xmlNewNode(NULL, (const xmlChar*) "hostname");
		if (hostnamenode != NULL) {
			xmlNewProp(hostnamenode, (const xmlChar*) "param",
					(const xmlChar*) hostname);
			xmlAddChild(node, hostnamenode);
		} else {
			cerr << "<hostname> node could not be created!" << endl;
		}
	} else {
		// add param value to existant hostname-node
		xmlSetProp(hostnamenode, (const xmlChar*) "param", (xmlChar*) hostname);
	}

	// We need to add computername-node as the first node
	compnamenode = xmlNewNode(NULL, (const xmlChar*) "computername");
	if (compnamenode != NULL) {
		xmlNewProp(compnamenode, (const xmlChar*) "param",
				(const xmlChar*) hostname);
		// Add this node to the beginning of available children
		// -> that is because bootpgm only looks in the first 500 chars
		if (firstchild != NULL) {
			xmlAddPrevSibling(firstchild, compnamenode);
		}
		//xmlFreeNode(compnamenode);
	} else {
		cerr << "<computername> node could not be created!" << endl;
	}

	// We need to add the filename to the xml
	if (dat->xml_name.empty())
		return;
	bfs::path path(dat->xml_name);
	std::string folder = path.branch_path().string();
	folder.append("/");

	if (folder.empty())
		return;
	cur = node->children;

	// Get <hostname> node and add "hostname#param" attribute
	while (cur != NULL) {
		if (!xmlStrcmp(cur->name, (const xmlChar *) "image_name")) {
			filenamenode = cur;
			break;
		}
		cur = cur->next;
	}
	if (!filenamenode) {
		cerr << "There is no node called 'image_name'. " << endl;
	} else {
		// add param value to existant hostname-node
		xmlChar* bla = xmlGetProp(filenamenode, (const xmlChar*) "param");
		if (!bla) {
			cerr << "Could not read Attribute 'param' in 'image_name' node."
					<< endl;
			return;
		} else {
			xmlSetProp(filenamenode, (const xmlChar*) "param",
					(const xmlChar*) folder.append((char*) bla).c_str());
		}
	}

	return;
}




/**
 * read specific xml files for a group from
 *
 *   /etc/opt/openslx/vmchooser-[groupname].xml
 *
 * and add group specific informations like shared_folders,
 * printers and scanners
 *
 * @param dat - this is the DataEntry struct pointer
 * @param group - this is the group name to get informations from
 */
void readGroupXml(DataEntry* dat, string group) {

	xmlNodePtr envnode = 0,
		tnode = 0, tnode2=0, tnode3=0, // temporary nodes
		shared=0, // Node for shared folders
		printer=0, // Node for printers
		scanner=0; // Node for scanners

	xmlChar* xmlenv = 0;
	string t;

	// these variables are for xpath queries
	xmlXPathObjectPtr xpp;
	int size = 0;

	string grpXmlPath;

	grpXmlPath  = string(VMCHOOSER_ETC_BASE_PATH)
			.append("vmchooser-")
			.append(group)
			.append(".xml");

	if (!bfs::is_regular(grpXmlPath)) {
		return;
	}

	xmlDocPtr doc = xmlReadFile(
			grpXmlPath.c_str(),
			NULL,
			XML_PARSE_RECOVER|XML_PARSE_NOERROR
	);

	if(! doc ) return;


	envnode = xmlFirstElementChild(doc->children);
	if(envnode == 0) {
		return;
	}

	do {
		xmlenv = xmlGetProp(envnode, (const xmlChar*)"param");
		if(xmlStrlen(xmlenv) == 0
				|| string((const char*)envnode->name) != "environment")
		{
			continue;
		}
		if(group == (const char*)xmlenv) {
			tnode = xmlFirstElementChild(envnode);
			do {
				if(tnode->type != XML_ELEMENT_NODE) continue;
				t = (const char*)tnode->name;

				// Here we are looking for shared_folders,printers and scanners
				// respectively
				if(t == "shared_folders") {
					// There could be many shared folders in there
					shared = xmlFirstElementChild(tnode);
					do {
						if(shared->type != XML_ELEMENT_NODE) continue;
						xpp = evalXPath(dat->xml, "/settings/eintrag/shared_folders");
						size = (xpp->nodesetval) ? xpp->nodesetval->nodeNr: 0;

						if(size == 0) {
							// shared_folders node not found - add it
							tnode2 = xmlNewNode(NULL, (const xmlChar*) "shared_folders");
							xmlAddChild(tnode2, shared);
							xpp = evalXPath(dat->xml, "/settings/eintrag");
							size = (xpp->nodesetval) ? xpp->nodesetval->nodeNr: 0;

							for (int i= 0; i < size; i++) {
								tnode3 = xpp->nodesetval->nodeTab[i];
								if (tnode3->type == XML_ELEMENT_NODE ) {
									xmlAddChild(tnode3, tnode2);
								} else {
									continue;
								}
							}
						}
						else
						{
							// found shared_folders node - add children
							for (int i= 0; i < size; i++) {
								tnode2 = xpp->nodesetval->nodeTab[i];
								if (tnode2->type == XML_ELEMENT_NODE ) {
									xmlAddChild(tnode2, shared);
								} else {
									continue;
								}
							}
						}
					} while ( (shared = shared->next) );
				}
				else if(t == "printers") {
					// There could be many printer nodes in there
					printer = xmlFirstElementChild(tnode);
					do {
						if(printer->type != XML_ELEMENT_NODE) continue;
						xpp = evalXPath(dat->xml, "/settings/eintrag/printers");
						size = (xpp->nodesetval) ? xpp->nodesetval->nodeNr: 0;

						if(size == 0) {
							// shared_folders node not found - add it
							tnode2 = xmlNewNode(NULL, (const xmlChar*) "printers");
							xmlAddChild(tnode2, printer);
							xpp = evalXPath(dat->xml, "/settings/eintrag");
							size = (xpp->nodesetval) ? xpp->nodesetval->nodeNr: 0;

							for (int i= 0; i < size; i++) {
								tnode3 = xpp->nodesetval->nodeTab[i];
								if (tnode3->type == XML_ELEMENT_NODE ) {
									xmlAddChild(tnode3, tnode2);
								} else {
									continue;
								}
							}
						}
						else
						{
							// found shared_folders node - add children
							for (int i= 0; i < size; i++) {
								tnode2 = xpp->nodesetval->nodeTab[i];
								if (tnode2->type == XML_ELEMENT_NODE ) {
									xmlAddChild(tnode2, printer);
								} else {
									continue;
								}
							}
						}
					} while ( (printer = printer->next) );
				}
				else if(t == "scanners") {
					// There could be many printer nodes in there
					scanner = xmlFirstElementChild(tnode);
					do {
						if(scanner->type != XML_ELEMENT_NODE) continue;
						xpp = evalXPath(dat->xml, "/settings/eintrag/scanners");
						size = (xpp->nodesetval) ? xpp->nodesetval->nodeNr: 0;

						if(size == 0) {
							// scanners node not found - add it
							tnode2 = xmlNewNode(NULL, (const xmlChar*) "scanners");
							xmlAddChild(tnode2, scanner);
							xpp = evalXPath(dat->xml, "/settings/eintrag");
							size = (xpp->nodesetval) ? xpp->nodesetval->nodeNr: 0;

							for (int i= 0; i < size; i++) {
								tnode3 = xpp->nodesetval->nodeTab[i];
								if (tnode3->type == XML_ELEMENT_NODE ) {
									xmlAddChild(tnode3, tnode2);
								} else {
									continue;
								}
							}
						}
						else
						{
							// found scanners node - add children
							for (int i= 0; i < size; i++) {
								tnode2 = xpp->nodesetval->nodeTab[i];
								if (tnode2->type == XML_ELEMENT_NODE ) {
									xmlAddChild(tnode2, scanner);
								} else {
									continue;
								}
							}
						}
					} while ( (scanner = scanner->next) );
				}
			}
			while ( (tnode = tnode->next) );
		}
	}
	while ( (envnode = envnode->next) );


}