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.


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