#include "DataEntry.h"
#include "functions.h"
#include "paths.h"
#include <sstream>
#include <errno.h>
#include <sys/wait.h>
#include <iostream>
#include <string>
#include <boost/regex.hpp>
/* define MAX_LENGTH for string in getFolderName */
const int MAX_LENGTH = 200;
extern string env;
/** *************************************************************
* void runImage runs a (virtual machine) image using fork()
* calling runImage(DataEntry*)
***************************************************************/
void runImage(DataEntry dat)
{
string confxml;
/* printf("runImage called\n"); */
//if ( e == NULL ) {
// return;
//}
//DataEntry& dat = *((DataEntry*) e);
if(dat.imgtype == VMWARE || dat.imgtype == VBOX ) {
confxml = writeConfXml(dat);
}
pid_t pid;
// in case you want to wait hours on your thread
//int status;
char arg1[MAX_LENGTH];
strncpy(arg1, (char*) string("'\n\nStarte Image: ")
.append(dat.short_description)
.append("\n'").c_str(),MAX_LENGTH);
char* argv[] = { (char*) string(VMCHOOSER_PLUGIN_PATH).append("mesgdisp").c_str(),
arg1, NULL };
//printf("%s", arg1);
// TODO: only fork if we want to display a message (or maybe not fork at all?)
pid = fork();
switch( pid ) {
case -1:
// parent: creation of child process failed
//fltk::alert("Error occured during forking a thread of execution!");
return;
break;
case 0:
// child
// the only purpose of this child is to display a message
//mainwin->destroy();
//fltk::wait();
if(dat.imgtype == VMWARE || dat.imgtype == VBOX) {
//cout << "calling " << argv[1] << endl;
execvp(argv[0], argv);
}
break;
default:
// parent
// this is not really useful, as this
// blocks execution for about 5 seconds
// sometimes ;-)
//if( waitpid( pid, &status, 0 ) == -1 ) {
// cerr << "No child with this pid (" << pid << ")" << endl;
// fltk::alert("Failed to create child thread!");
// return;
//}
// TODO: find out what it does and restore this
saveSession(&dat);
runImage(dat, confxml);
break;
}
}
/**
* Helper-function for runImage(Widget, void)
* - runs the chosen virtualizer image
**/
void runImage(DataEntry& dat, string confxml)
{
if(! dat.command.empty() ) {
char* arg[] = { (char*) dat.command.c_str(), '\0' };
execvp((char*) dat.command.c_str(), arg);
}
char* arg[] = { (char *) string(VMCHOOSER_BIN_PATH).append("run-virt.sh").c_str(),
(char*)confxml.c_str(),
NULL };
execvp(string(VMCHOOSER_BIN_PATH).append("run-virt.sh").c_str(), arg);
}
/**
* Helper-Function: Get folder name
*/
char* getFolderName() {
/* Var for the folder name */
char* pname = (char*) malloc(MAX_LENGTH);
int result;
result = readlink("/proc/self/exe", pname, MAX_LENGTH);
if (result > 0) {
pname[result] = 0; /* add the NULL - not done by readlink */
}
int i=result-1;
while(pname[i] != '/' && i >= 0) {
pname[i] = '\0';
i--;
}
if(pname[i] == '/' ) {
pname[i] = '\0';
}
return pname;
}
string writeConfXml(DataEntry& dat) {
//char* pname = getFolderName();
string pname = VMCHOOSER_ETC_BASE_PATH;
xmlNodePtr cur = 0;
xmlNodePtr root = 0;
string pskript = pname +"/printer.sh";
cur = xmlDocGetRootElement(dat.xml);
if(cur == NULL) {
printf("Empty XML Document %s!", dat.xml_name.c_str());
return dat.xml_name.c_str();
}
// xmlNode "eintrag"
root = cur->children;
while(xmlStrcmp(root->name, (const xmlChar*)"eintrag") != 0) {
root = root->next;
}
if(xmlStrcmp(root->name, (const xmlChar *)"eintrag") != 0){
fprintf(stderr, "%s is not a valid xml file!", dat.xml_name.c_str());
return dat.xml_name.c_str();
}
// add "printers" and "scanners" - XML-Nodes
addPrinters(root, (char*)pskript.c_str());
pskript = pname + "/scanner.sh";
addScanners(root, (char*)pskript.c_str());
// add hostname and username information
addInfo(root, &dat);
// read the group configuration XML
readGroupXml(&dat, env);
srand(time(NULL));
string xmlfile;
ostringstream i;
i << "/tmp/run" << rand() << ".xml";
xmlfile = i.str();
//xmlSaveFile("-", dat.xml);
xmlSaveFile( (char*) xmlfile.c_str(), dat.xml);
return xmlfile;
}