Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


added user space configuration build system
[palacios.git] / utils / guest_creator / main.c
diff --git a/utils/guest_creator/main.c b/utils/guest_creator/main.c
new file mode 100644 (file)
index 0000000..2316ea9
--- /dev/null
@@ -0,0 +1,227 @@
+#include "ezxml.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#define MAX_FILES 256
+
+struct file_info {
+    int size;
+    char id[256];
+    char * data;
+    unsigned long long * offset_ptr;
+};
+
+int num_files = 0;
+struct file_info files[MAX_FILES];
+
+
+int parse_config_input(ezxml_t cfg_input);
+int write_output(char * filename, ezxml_t cfg_output);
+
+void usage() {
+    printf("Usage: builder <infile> [-o outfile]\n");
+}
+
+int main(int argc, char ** argv) {
+    int c;
+    char * outfile = NULL;
+    char * infile = NULL;
+
+    memset((char *)files, 0, sizeof(files));
+
+    opterr = 0;
+
+    while ((c = getopt(argc, argv, "ho:")) != -1) {
+       switch (c) {
+           case 'o':
+               outfile = optarg;
+               break;
+           case 'h':
+               usage();
+               return 1;
+           default:
+               abort();
+       }
+    }
+
+    if (optind >= argc) {
+       usage();
+       return 1;
+    }
+
+    infile = argv[optind];
+
+
+    printf("Reading Input file: %s\n", infile);
+
+    ezxml_t cfg_input = ezxml_parse_file(infile);
+
+    if (cfg_input == NULL) {
+       printf("Could not open configuration input file: %s\n", infile);
+       return 1;
+    }
+
+
+    // parse input
+    if (parse_config_input(cfg_input) == -1) {
+       printf("Error parsing configuration input\n");
+       return 1;
+    }
+
+
+
+
+    // write output
+
+    if (outfile == NULL) {
+       char * endptr = rindex(infile, '.');
+
+       outfile = malloc(strlen(infile) + strlen(".dat") + 1);
+
+       if (endptr) {
+           *endptr = '\0';
+       }
+
+       sprintf(outfile, "%s.dat", infile);
+    }
+
+
+    write_output(outfile, cfg_input);
+
+
+    return 0;
+}
+
+char * get_val(ezxml_t cfg, char * tag) {
+    char * attrib = (char *)ezxml_attr(cfg, tag);
+    ezxml_t txt = ezxml_child(cfg, tag);
+
+    if ((txt != NULL) && (attrib != NULL)) {
+       printf("Invalid Cfg file: Duplicate value for %s (attr=%s, txt=%s)\n", 
+              tag, attrib, ezxml_txt(txt));
+       exit(-1);
+    }
+
+    return (attrib == NULL) ? ezxml_txt(txt) : attrib;
+}
+
+
+int write_output(char * filename, ezxml_t cfg_output) {
+    FILE * data_file = fopen(filename, "w+");
+    char * new_cfg_str = ezxml_toxml(cfg_output);
+    unsigned int cfg_len = strlen(new_cfg_str);
+    unsigned long long zero = 0;
+    int i = 0;
+    unsigned long long offset = 0;
+    unsigned long long file_cnt = num_files;
+
+    fwrite("v3vee\0\0\0", 8, 1, data_file);
+    offset += 8;
+
+    //  printf("New config: \n%s\n", new_cfg_str);
+    
+    fwrite(&cfg_len, sizeof(unsigned int), 1, data_file);
+    offset += sizeof(unsigned int);
+
+    fwrite(new_cfg_str, cfg_len, 1, data_file);
+    offset += cfg_len;
+
+    fwrite(&zero, 1, 8, data_file);
+    offset += 8;
+
+    printf("setting number of files to %llu\n", file_cnt);
+    printf("sizeof(file_cnt)=%d \n", sizeof(file_cnt));
+
+    fwrite(&file_cnt, 8, 1, data_file);
+    offset += 8;
+
+    // each index entry is 16 bytes long plus end padding
+    offset += (16 * num_files) + 8;
+
+    for (i = 0; i < num_files; i++) {
+       fwrite(&i, 4, 1, data_file);
+       fwrite(&(files[i].size), 4, 1, data_file);
+       fwrite(&offset, 8, 1, data_file);
+
+       offset += files[i].size;
+    }
+
+    fwrite(&zero, 1, 8, data_file);
+
+    for (i = 0; i < num_files; i++) {
+       if (fwrite(files[i].data, 1, files[i].size, data_file) != files[i].size) {
+           printf("Error writing data file contents");
+           exit(-1);
+       }       
+    }
+    
+
+
+    fclose(data_file);
+
+    return 0;
+}
+
+
+
+int parse_config_input(ezxml_t cfg_input) {
+    ezxml_t file_tags = NULL;
+    ezxml_t tmp_file_tag = NULL;
+
+    // files are transformed into blobs that are slapped to the end of the file
+        
+    file_tags = ezxml_child(cfg_input, "files");
+
+    tmp_file_tag = ezxml_child(file_tags, "file");
+
+    while (tmp_file_tag) {
+       char * filename = get_val(tmp_file_tag, "filename");
+       struct stat file_stats;
+       FILE * data_file = NULL;
+       char * id = get_val(tmp_file_tag, "id");
+       char index_buf[256];
+
+       snprintf(index_buf, 256, "%d", num_files);
+
+
+       strncpy(files[num_files].id, ezxml_attr(tmp_file_tag, "id"), 256);
+
+       printf("file id=%s, name=%s\n", 
+              id,
+              filename);
+       
+
+       if (stat(filename, &file_stats) != 0) {
+           perror(filename);
+           exit(-1);
+       }
+
+       files[num_files].size = (unsigned int)file_stats.st_size;
+       printf("file size = %d\n", files[num_files].size);
+
+       files[num_files].data = malloc(files[num_files].size);
+
+       data_file = fopen(filename, "r");
+
+       if (fread(files[num_files].data, files[num_files].size, 1, data_file) == 0) {
+           printf("Error reading data file %s\n", filename);
+           exit(-1);
+       }
+
+       fclose(data_file);
+
+
+       ezxml_set_attr_d(tmp_file_tag, "index", index_buf);
+
+       num_files++;
+       tmp_file_tag = ezxml_next(tmp_file_tag);
+    }
+
+
+    return 0;
+}