X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=utils%2Fguest_creator%2Fmain.c;fp=utils%2Fguest_creator%2Fmain.c;h=2316ea9b7fef41f7db01f42ee8ab11fd7a9417d8;hb=3cf3fcc643f04aaa516da88a8ef3726cddfbbc0b;hp=0000000000000000000000000000000000000000;hpb=45050b17f19868689ef5437ced5810044dd57768;p=palacios.git diff --git a/utils/guest_creator/main.c b/utils/guest_creator/main.c new file mode 100644 index 0000000..2316ea9 --- /dev/null +++ b/utils/guest_creator/main.c @@ -0,0 +1,227 @@ +#include "ezxml.h" +#include +#include +#include +#include +#include +#include +#include + +#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 [-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; +}