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.


2255adf1784888a0dc95dbcf9ca475ef1623c715
[palacios.git] / utils / guest_creator / main.c
1 #include "ezxml.h"
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <getopt.h>
5 #include <unistd.h>
6 #include <string.h>
7 #include <sys/stat.h>
8 #include <sys/types.h>
9
10 #define MAX_FILES 256
11
12 struct file_info {
13     int size;
14     char id[256];
15     char * data;
16     unsigned long long * offset_ptr;
17 };
18
19 int num_files = 0;
20 struct file_info files[MAX_FILES];
21
22
23 int parse_config_input(ezxml_t cfg_input);
24 int write_output(char * filename, ezxml_t cfg_output);
25
26 void usage() {
27     printf("Usage: build_vm <infile> [-o outfile]\n");
28 }
29
30 int main(int argc, char ** argv) {
31     int c;
32     char * outfile = NULL;
33     char * infile = NULL;
34
35     memset((char *)files, 0, sizeof(files));
36
37     opterr = 0;
38
39     while ((c = getopt(argc, argv, "ho:")) != -1) {
40         switch (c) {
41             case 'o':
42                 outfile = optarg;
43                 break;
44             case 'h':
45                 usage();
46                 return 1;
47             default:
48                 abort();
49         }
50     }
51
52     if (optind >= argc) {
53         usage();
54         return 1;
55     }
56
57     infile = argv[optind];
58
59
60     printf("Reading Input file: %s\n", infile);
61
62     ezxml_t cfg_input = ezxml_parse_file(infile);
63
64     if (cfg_input == NULL) {
65         printf("Could not open configuration input file: %s\n", infile);
66         return 1;
67     }
68
69
70
71
72     // parse input
73     if (parse_config_input(cfg_input) == -1) {
74         printf("Error parsing configuration input\n");
75         return 1;
76     }
77
78     printf("xml : %s\n", ezxml_toxml(cfg_input));
79
80
81
82     // write output
83
84     if (outfile == NULL) {
85         char * endptr = rindex(infile, '.');
86
87         outfile = malloc(strlen(infile) + strlen(".dat") + 1);
88
89         if (endptr) {
90             *endptr = '\0';
91         }
92
93         sprintf(outfile, "%s.dat", infile);
94     }
95
96
97     write_output(outfile, cfg_input);
98
99
100     return 0;
101 }
102
103 char * get_val(ezxml_t cfg, char * tag) {
104     char * attrib = (char *)ezxml_attr(cfg, tag);
105     ezxml_t txt = ezxml_child(cfg, tag);
106
107     if ((txt != NULL) && (attrib != NULL)) {
108         printf("Invalid Cfg file: Duplicate value for %s (attr=%s, txt=%s)\n", 
109                tag, attrib, ezxml_txt(txt));
110         exit(-1);
111     }
112
113     return (attrib == NULL) ? ezxml_txt(txt) : attrib;
114 }
115
116
117 int write_output(char * filename, ezxml_t cfg_output) {
118     FILE * data_file = fopen(filename, "w+");
119     char * new_cfg_str = ezxml_toxml(cfg_output);
120     unsigned int cfg_len = strlen(new_cfg_str);
121     unsigned long long zero = 0;
122     int i = 0;
123     unsigned long long offset = 0;
124     unsigned long long file_cnt = num_files;
125
126     fwrite("v3vee\0\0\0", 8, 1, data_file);
127     offset += 8;
128
129     //  printf("New config: \n%s\n", new_cfg_str);
130     
131     fwrite(&cfg_len, sizeof(unsigned int), 1, data_file);
132     offset += sizeof(unsigned int);
133
134     fwrite(new_cfg_str, cfg_len, 1, data_file);
135     offset += cfg_len;
136
137     fwrite(&zero, 1, 8, data_file);
138     offset += 8;
139
140     printf("setting number of files to %llu\n", file_cnt);
141     printf("sizeof(file_cnt)=%d \n", sizeof(file_cnt));
142
143     fwrite(&file_cnt, 8, 1, data_file);
144     offset += 8;
145
146     // each index entry is 16 bytes long plus end padding
147     offset += (16 * num_files) + 8;
148
149     for (i = 0; i < num_files; i++) {
150         fwrite(&i, 4, 1, data_file);
151         fwrite(&(files[i].size), 4, 1, data_file);
152         fwrite(&offset, 8, 1, data_file);
153
154         offset += files[i].size;
155     }
156
157     fwrite(&zero, 1, 8, data_file);
158
159     for (i = 0; i < num_files; i++) {
160         if (fwrite(files[i].data, 1, files[i].size, data_file) != files[i].size) {
161             printf("Error writing data file contents");
162             exit(-1);
163         }       
164     }
165     
166
167
168     fclose(data_file);
169
170     return 0;
171 }
172
173
174
175 int parse_config_input(ezxml_t cfg_input) {
176     ezxml_t file_tags = NULL;
177     ezxml_t tmp_file_tag = NULL;
178
179     // files are transformed into blobs that are slapped to the end of the file
180         
181     file_tags = ezxml_child(cfg_input, "files");
182
183     tmp_file_tag = ezxml_child(file_tags, "file");
184
185     while (tmp_file_tag) {
186         char * filename = get_val(tmp_file_tag, "filename");
187         struct stat file_stats;
188         FILE * data_file = NULL;
189         char * id = get_val(tmp_file_tag, "id");
190         char index_buf[256];
191
192         snprintf(index_buf, 256, "%d", num_files);
193
194
195         strncpy(files[num_files].id, ezxml_attr(tmp_file_tag, "id"), 256);
196
197         printf("file id=%s, name=%s\n", 
198                id,
199                filename);
200         
201
202         if (stat(filename, &file_stats) != 0) {
203             perror(filename);
204             exit(-1);
205         }
206
207         files[num_files].size = (unsigned int)file_stats.st_size;
208         printf("file size = %d\n", files[num_files].size);
209
210         files[num_files].data = malloc(files[num_files].size);
211
212         data_file = fopen(filename, "r");
213
214         if (fread(files[num_files].data, files[num_files].size, 1, data_file) == 0) {
215             printf("Error reading data file %s\n", filename);
216             exit(-1);
217         }
218
219         fclose(data_file);
220
221
222         ezxml_set_attr_d(tmp_file_tag, "index", index_buf);
223
224         num_files++;
225         tmp_file_tag = ezxml_next(tmp_file_tag);
226     }
227
228
229     return 0;
230 }