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.


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