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 more error checking from on what is returned by ezXML to not generate image...
[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 #include <sys/ioctl.h>
10
11
12 #define MAX_FILES 256
13
14 struct file_info {
15     int size;
16     char filename[2048];
17     char id[256];
18 };
19
20 int num_files = 0;
21 struct file_info files[MAX_FILES];
22
23 #define STDIO_FD 1
24
25
26 int parse_config_input(ezxml_t cfg_input);
27 int write_output(char * filename, ezxml_t cfg_output);
28 int copy_file(int file_index, FILE * data_file);
29
30 void usage() {
31     printf("Usage: build_vm <infile> [-o outfile]\n");
32 }
33
34 int main(int argc, char ** argv) {
35     int c;
36     char * outfile = NULL;
37     char * infile = NULL;
38
39
40     memset((char *)files, 0, sizeof(files));
41
42     opterr = 0;
43
44     while ((c = getopt(argc, argv, "ho:")) != -1) {
45         switch (c) {
46             case 'o':
47                 outfile = optarg;
48                 break;
49             case 'h':
50                 usage();
51                 return 1;
52             default:
53                 abort();
54         }
55     }
56
57     if (optind >= argc) {
58         usage();
59         return 1;
60     }
61
62     infile = argv[optind];
63
64
65     if (outfile == NULL) {
66         char * endptr = rindex(infile, '.');
67
68         outfile = malloc(strlen(infile) + strlen(".dat") + 1);
69
70         strncpy(outfile, infile, endptr - infile);
71
72         sprintf(outfile, "%s.dat", outfile);
73     }
74
75
76
77     printf("Input: [%s] ==>>  Output: [%s]\n", infile, outfile);
78
79     ezxml_t cfg_input = ezxml_parse_file(infile);
80     if (strcmp("", ezxml_error(cfg_input)) != 0) {
81         printf("%s\n", ezxml_error(cfg_input));
82         return -1;
83     }
84
85     if (cfg_input == NULL) {
86         printf("Could not open configuration input file: %s\n", infile);
87         return 1;
88     }
89
90
91
92
93     // parse input
94     if (parse_config_input(cfg_input) == -1) {
95         printf("Error parsing configuration input\n");
96         return 1;
97     }
98
99     //  printf("xml : %s\n", ezxml_toxml(cfg_input));
100
101
102
103     // write output
104
105
106
107     write_output(outfile, cfg_input);
108
109
110     return 0;
111 }
112
113 char * get_val(ezxml_t cfg, char * tag) {
114     char * attrib = (char *)ezxml_attr(cfg, tag);
115     ezxml_t txt = ezxml_child(cfg, tag);
116
117     if ((txt != NULL) && (attrib != NULL)) {
118         printf("Invalid Cfg file: Duplicate value for %s (attr=%s, txt=%s)\n", 
119                tag, attrib, ezxml_txt(txt));
120         exit(-1);
121     }
122
123     return (attrib == NULL) ? ezxml_txt(txt) : attrib;
124 }
125
126
127
128 int parse_config_input(ezxml_t cfg_input) {
129     ezxml_t file_tags = NULL;
130     ezxml_t tmp_file_tag = NULL;
131
132     // files are transformed into blobs that are slapped to the end of the file
133         
134     file_tags = ezxml_child(cfg_input, "files");
135
136     tmp_file_tag = ezxml_child(file_tags, "file");
137
138     while (tmp_file_tag) {
139         char * filename = get_val(tmp_file_tag, "filename");
140         struct stat file_stats;
141         char * id = get_val(tmp_file_tag, "id");
142         char index_buf[256];
143
144
145         if (stat(filename, &file_stats) != 0) {
146             perror(filename);
147             exit(-1);
148         }
149
150         files[num_files].size = (unsigned int)file_stats.st_size;
151         strncpy(files[num_files].id, id, 256);
152         strncpy(files[num_files].filename, filename, 2048);
153
154         snprintf(index_buf, 256, "%d", num_files);
155         ezxml_set_attr_d(tmp_file_tag, "index", index_buf);
156
157         num_files++;
158         tmp_file_tag = ezxml_next(tmp_file_tag);
159     }
160
161
162     return 0;
163 }
164
165
166 int write_output(char * filename, ezxml_t cfg_output) {
167     FILE * data_file = fopen(filename, "w+");
168     char * new_cfg_str = ezxml_toxml(cfg_output);
169     unsigned int cfg_len = strlen(new_cfg_str);
170     unsigned long long zero = 0;
171     int i = 0;
172     unsigned long long offset = 0;
173     unsigned long long file_cnt = num_files;
174
175     fwrite("v3vee\0\0\0", 8, 1, data_file);
176     offset += 8;
177
178     //  printf("New config: \n%s\n", new_cfg_str);
179     
180     fwrite(&cfg_len, sizeof(unsigned int), 1, data_file);
181     offset += sizeof(unsigned int);
182
183     fwrite(new_cfg_str, cfg_len, 1, data_file);
184     offset += cfg_len;
185
186     fwrite(&zero, 1, 8, data_file);
187     offset += 8;
188
189     printf("Total number of files: %llu\n", file_cnt);
190
191     fwrite(&file_cnt, 8, 1, data_file);
192     offset += 8;
193
194     // each index entry is 16 bytes long plus end padding
195     offset += (16 * num_files) + 8;
196
197     for (i = 0; i < num_files; i++) {
198         fwrite(&i, 4, 1, data_file);
199         fwrite(&(files[i].size), 4, 1, data_file);
200         fwrite(&offset, 8, 1, data_file);
201
202         offset += files[i].size;
203     }
204
205     fwrite(&zero, 1, 8, data_file);
206
207     for (i = 0; i < num_files; i++) {
208
209         copy_file(i, data_file);
210         
211     }
212     
213
214
215     fclose(data_file);
216
217     return 0;
218 }
219
220
221 #define XFER_BLK_SIZE 4096
222
223 int copy_file(int file_index, FILE * data_file) {
224     char xfer_buf[XFER_BLK_SIZE];
225     int bytes_to_read = files[file_index].size;
226     int bytes_read = 0;
227     int xfer_len = XFER_BLK_SIZE;
228     FILE * in_file = NULL;
229     char * filename = files[file_index].filename;
230     struct winsize wsz;
231     char cons_line[256];
232     int prog_len = 0;
233     double ratio = 100;
234     int num_dots = 256;
235
236     printf("Copying [%d] -- %s \n",
237            file_index,     
238            filename);
239
240
241     if (ioctl(STDIO_FD, TIOCGWINSZ, &wsz) == -1) {
242         printf("ioctl error on STDIO\n");
243         return -1;
244     }
245
246
247     memset(cons_line, 0, 256);
248     snprintf(cons_line, 256, "\r(%s) [", files[file_index].id);
249     prog_len = wsz.ws_col - (strlen(cons_line) + 11);
250
251
252
253     in_file = fopen(filename, "r");
254
255     while (bytes_to_read > 0) {
256         struct winsize tmp_wsz;
257         int tmp_dots = 0;
258
259         if (ioctl(STDIO_FD, TIOCGWINSZ, &tmp_wsz) == -1) {
260             printf("ioctl error on STDIO\n");
261             return -1;
262         }
263
264         ratio = (double)bytes_read / (double)(files[file_index].size); 
265         tmp_dots = (int)(ratio * (double)prog_len);
266
267         if ((tmp_dots != num_dots) || (tmp_wsz.ws_col != wsz.ws_col)) {
268             int i = 0;
269             int num_blanks = 0;
270             
271             wsz = tmp_wsz;
272             num_dots = tmp_dots;
273             
274             num_blanks = prog_len - num_dots;
275
276             memset(cons_line, 0, 256);
277             snprintf(cons_line, 256, "\r(%s) [", files[file_index].id);
278             
279             for (i = 0; i <= num_dots; i++) {
280                 strcat(cons_line, "=");
281             }
282             
283             for (i = 0; i < num_blanks - 1; i++) {
284                 strcat(cons_line, " ");
285             }
286             
287             strcat(cons_line, "] ");
288
289             //  printf("console width = %d\n", wsz.ws_col);
290             write(STDIO_FD, cons_line, wsz.ws_col);
291         }
292         
293         
294         
295         if (xfer_len > bytes_to_read) {
296             xfer_len = bytes_to_read;
297         }
298         
299         if (fread(xfer_buf, xfer_len, 1, in_file) == 0) {
300             printf("Error reading data file %s\n", filename);
301             exit(-1);
302         }       
303         
304         if (fwrite(xfer_buf, xfer_len, 1, data_file) == 0) {
305             printf("Error writing data file contents");
306             exit(-1);
307         }
308
309
310         bytes_read += xfer_len;
311         bytes_to_read -= xfer_len;
312     }
313
314     strcat(cons_line, "Done\n");
315     write(STDIO_FD, cons_line, wsz.ws_col);
316
317
318     fclose(in_file);
319
320     return 0;
321 }