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








                                                                 
 

                          


                          
                               
 
                  

                   
                  
 



                      
 
                                


                          
           

                      
                                                              

                                                        
                                  




                                                                              

                                                                                           
                                                                                                   

                                        

                            





                                           

                                                

                                                                                    
 






                                          

                                                     

                                                              










                                                                               



                                           
                                              










                                                                                                   

                                        












                                                              
         
                    

 


                                  
 
                                   

                                        
 
                                                              

                                              







                                                                     



                                                                   







                                                                
                                                              




                                        
                                                     




                                    
                                                   




                                  
                                                   




                                  
                                                        




                                    
                                                




                               
                                                     



                                    
 
 
                                                            
                             
                                                    
                                             
                                                             
                                           

                                        


                 

                                                             
                               
 


                     
                                                    

                                                                      




                                                      
         
                     
 
                                                    

                                                                      
         




                                   
                                                   




                                  
                                                 




                                
                                                      


                                           
              
                                 
         
                     
 








                                                  
                      

                  

 
 






                                                                      
                                             
 




                                

                                  

                     
                                      

   


                                                                   
                               

                                                    
                                                   







                                                                         
                                                                                              



















                                                                           
                                                                   



                                                                                                   
                                                          



                                                            
 






                                                                                
                                                                         
                   




                                     
   
 

              
                  


                        

                                                            
                                      
   

                                






                                                  
 




                                
                                                                      



                               
                                                                                    




                                                                                   


                                           
                
       



                                                                       

                     
                  



                  


 
 




                                                    
/**
 * author: Bastian Wissler
 * purpose: Scan a given folder for XML-Files and get information
 *	    about installed Images / SessionManagers
 */
#include <stdio.h>
#include <glob.h>
#include <sys/types.h>
#include <sys/stat.h>

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

#include <boost/regex.hpp>
#include <boost/filesystem.hpp>

#include <cstring>
#include <vector>
#include <iostream>
#include <fstream>

#include "constants.h"
#include "DataEntry.h"
#include "functions.h"
#include "paths.h"

namespace bfs=boost::filesystem;

#ifdef LIBXML_TREE_ENABLED

string env;
vector<string> xmlVec;

xmlXPathObjectPtr evalXPath(xmlDocPtr doc, const char* path) {
        printf("evalXPath(doc, %s)\n", path);
        xmlXPathContextPtr xp = xmlXPathNewContext(doc);
	string bla = string(path);
	if(xp == NULL) {
		fprintf(stderr,"Error: unable to create new XPath context\n");
		xmlFreeDoc(doc);
		return NULL;
	}
	xmlXPathObjectPtr result = xmlXPathEvalExpression((const xmlChar*)bla.c_str(), xp);
	if(result == NULL) {
		fprintf(stderr,"Error: unable to evaluate xpath expression \"%s\"\n", bla.c_str());
		xmlXPathFreeContext(xp);
		xmlFreeDoc(doc);
		return NULL;
	}
	xmlXPathFreeContext(xp);
	return result;
}

char* getAttribute(xmlDoc *doc, char* name)
{
        printf("getAttribute(doc, %s)\n", name);
        xmlNode* temp;
	string path = string("/settings/eintrag/")+ string(name)+ string("/@param");
	char* cpath = strdup(path.c_str());

	// Get Attribute via XPath
	xmlXPathObjectPtr xpp = evalXPath(
			doc,
			(const char*)cpath
		);
	free(cpath);

        //print_xpath_nodes(xpp->nodesetval, stdout);

	int size;
	size = (xpp->nodesetval) ? xpp->nodesetval->nodeNr: 0;
	for (int i= 0; i < size; i++) {
	temp = xpp->nodesetval->nodeTab[i];
			if (temp->type == XML_ATTRIBUTE_NODE ) {

					return (char*) temp->children->content;
			} else {
					continue;
			}
	}

	return NULL;
}

char* getNodeValue(xmlDoc *doc, char* name)
{
        printf("getNodeValue(doc, %s)", name);
        xmlNode* temp;
	xmlXPathContextPtr xp = xmlXPathNewContext(doc);
	string bla = string("/settings/eintrag/")+ string(name);
	if(xp == NULL) {
		fprintf(stderr,"Error: unable to create new XPath context\n");
		xmlFreeDoc(doc);
		return NULL;
	}
	xmlXPathObjectPtr xpp = xmlXPathEvalExpression((const xmlChar*)bla.c_str(), xp);
	if(xpp == NULL) {
		fprintf(stderr,"Error: unable to evaluate xpath expression \"%s\"\n", bla.c_str());
		xmlXPathFreeContext(xp);
		xmlFreeDoc(doc);
		return NULL;
	}

	//print_xpath_nodes(xpp->nodesetval, stdout);
	int size;
	size = (xpp->nodesetval) ? xpp->nodesetval->nodeNr: 0;
        for (int i= 0; i < size; i++) {
		temp = xpp->nodesetval->nodeTab[i];
                if (temp->type == XML_TEXT_NODE ) {
                        return (char*) temp->content;
                } else {
                        continue;
                }
        }
        return NULL;
}



DataEntry* get_entry(xmlDoc * doc)
{
        printf("get_entry(doc)\n");
        char *tempc = NULL;
        DataEntry* de = new DataEntry();

        tempc = getAttribute(doc,(char *)"short_description");
        if (tempc != NULL ) {
                de->short_description = tempc;
		// replace a substring
                std::string dest_string, dest1_string;
                boost::regex re("\n|\r");
                boost::regex_replace(std::back_inserter(dest_string),
                        de->short_description.begin(),
                        de->short_description.end(),
                        re,
                        " ");
            } else {
                // TODO: fix this
                de->short_description = "short_description failed";
            }
        tempc = NULL;

        if (de->short_description.empty()) {
                free(de);
                fprintf(stderr, "No short_description given\n");
                return NULL;
        }

        tempc = getAttribute(doc,(char *) "long_description");
        if (tempc != NULL ) {
                de->description = tempc;
        }
        tempc = NULL;

        tempc = getAttribute(doc,(char *) "creator");
        if (tempc != NULL ) {
                de->creator = tempc;
        }
        tempc = NULL;

        tempc = getAttribute(doc,(char *) "email");
        if (tempc != NULL ) {
                de->email = tempc;
        }
        tempc = NULL;

        tempc = getAttribute(doc,(char *) "phone");
        if (tempc != NULL ) {
                de->phone = tempc;
        }
        tempc = NULL;

        tempc = getAttribute(doc,(char *) "image_name");
        if (tempc != NULL ) {
                de->imgname = tempc;
        }
        tempc = NULL;

        tempc = getAttribute(doc,(char *) "os");
        if (tempc != NULL ) {
                de->os = tempc;
        }
        tempc = NULL;

        tempc = getAttribute(doc,(char *) "network");
        if (tempc != NULL ) {
                de->network = tempc;
        }
        tempc = NULL;


        tempc = getAttribute(doc,(char *) "virtualmachine");
        if (tempc != NULL ) {
                if ( strcmp(tempc,"vmware") == 0 ) {
                        de->imgtype = VMWARE;
                } else if (strcmp(tempc,"virtualbox") == 0) {
                        de->imgtype = VBOX;
                } else {
                    de->imgtype = OTHER;
                }
        }
        else {

          // Defaults to vmware - if the attribute is unknown
          de->imgtype = VMWARE;

        }
        tempc = NULL;

        tempc = getAttribute(doc,(char *) "active");
        if (tempc != NULL ) {
                de->active = (strstr(tempc,"true")!= NULL?true:false);
                // This has to be considered elsewhere
                //if(de->active == false) {
                //    delete de;
                //    return NULL;
                //}
        }
        tempc = NULL;

        tempc = getAttribute(doc,(char *) "locked");
        if (tempc != NULL ) {
                de->locked = (strstr(tempc,"true")!= NULL?true:false);
        }
        else {
                de->locked = false;
        }
        tempc = NULL;

        tempc = getAttribute(doc,(char *) "pools");
        if (tempc != NULL ) {
                de->pools = tempc;
        }
        tempc = NULL;

        tempc = getAttribute(doc,(char *) "xdm");
        if (tempc != NULL ) {
                de->xdm = tempc;
        }
        tempc = NULL;

        tempc = getAttribute(doc,(char *) "priority");
        if (tempc != NULL ) {
                de->priority = atoi(tempc);
        }
        else {
                de->priority = 5;
        }
        tempc = NULL;

        tempc = getAttribute(doc,(char *) "icon");
        if (tempc != NULL ) {
                de->icon = tempc;
        }
        else {
                de->icon = "vmware";
        }
        tempc = NULL;

        de->xml = doc;

        return de;
}


/**
 * The main function of this file:
 *
 * - 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 DataEntry-struct
 */
std::vector<DataEntry> readXmlDir(char* path)
{
  const int MAX_LENGTH = 256;
  char line[MAX_LENGTH];
  char* fpath = getFolderName();
  FILE* inp;

  printf("readXmlDir %s\n", path);

  LIBXML_TEST_VERSION
  if ( path== NULL) {
      return std::vector<DataEntry>();
  }

  bfs::path filter(string(fpath).append("/").append(filterscript));


  if(bfs::is_regular(filter)) {
	  if( (inp = popen(string(fpath).append("/")
	          .append(filterscript).append(" ")
	          .append(path).c_str(), "r" )) ) {
	      while(fgets(line, MAX_LENGTH, inp ) != NULL) {
	        xmlVec.push_back(string(line).substr(0,strlen(line)-1) );
	      }
	      pclose(inp);
	  }
  }
  else
  {
	  ifstream conffile(string(VMCHOOSER_ETC_BASE_PATH).append("vmchooser.conf").c_str());
	  if(conffile) {
		  int n = 255;
		  char buf[n];
		  string s = "";
		  while(!conffile.eof()) {
			  conffile.getline(buf, n);
			  s = buf;
			  if(s.substr(0,13) == "vmchooser_env") {
				  env = s.substr(15,s.length()-16);
			  }
		  }
	  }

	  glob_t globbuf;
	  glob(string(path).append("*.xml").c_str(), NULL, NULL, &globbuf);

	  xmlDocPtr tdoc = 0;
	  char* tstr = 0;

	  for(int c=0; c<globbuf.gl_pathc; c++) {
                  printf("reading file %s\n", globbuf.gl_pathv[c]);
		  tdoc = xmlReadFile(globbuf.gl_pathv[c],NULL,XML_PARSE_RECOVER|XML_PARSE_NOERROR);

		  if(!tdoc) {
			  cerr << "Error opening xml file " << globbuf.gl_pathv[c] << "!" << endl;
                          return std::vector<DataEntry>();
		  }

		  tstr = getAttribute(tdoc, (char*)"pools");


//		  if(tstr == 0) {
//			  xmlFreeDoc(tdoc);
//			  continue;
//		  }

//		  if(env == tstr) {
                          printf("xmlVec.push_back(%s)\n", globbuf.gl_pathv[c]);
			  xmlVec.push_back(string(globbuf.gl_pathv[c]) );
//		  }

		  xmlFreeDoc(tdoc);
		  tdoc = 0; tstr = 0;
	  }

  }

  free(fpath);

  xmlDoc *doc = 0;
  int c = 0;
  string::size_type loc;

  // We need to reserve the memory for all the pointers here
  if(xmlVec.size() == 0) {
      return std::vector<DataEntry>();
  }

  std::vector<DataEntry> result;

  for (unsigned int i=0; i < xmlVec.size(); i++) {
    loc = xmlVec[i].find( "Vorlage" );
    if( loc != string::npos ) {
      // FOUND Vorlage
      continue;
    }

    struct stat m;
    stat(xmlVec[i].c_str(), &m);


    /* DEBUG */
    printf("File: %s, COUNT: %d\n", xmlVec[i].c_str(), xmlVec.size());
    if ( S_ISDIR(m.st_mode) ) {
            continue;
    }

    doc = xmlReadFile(xmlVec[i].c_str(), NULL, XML_PARSE_RECOVER|XML_PARSE_NOERROR);
    if (doc == NULL) {
            fprintf(stderr, "error: could not parse file %s\n", xmlVec[i].c_str());
            continue;
    }

    result.push_back(*get_entry(doc));
    //if (result[c] != 0) {
            result[c].xml_name = xmlVec[i];
            c++;
    //}
    /* xmlDoc still needed to write back information for VMware etc. */
    // xmlFreeDoc(doc);
  }

  //result[c] = '\0';
  //if(c!= 0) {
    return result;
  //}
  //else {
  //  return NULL;
  //}

}


#else

#error "Tree Support for libxml2 must be available!"

#endif