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 user space configuration build system
[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: builder <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     // parse input
71     if (parse_config_input(cfg_input) == -1) {
72         printf("Error parsing configuration input\n");
73         return 1;
74     }
75
76
77
78
79     // write output
80
81     if (outfile == NULL) {
82         char * endptr = rindex(infile, '.');
83
84         outfile = malloc(strlen(infile) + strlen(".dat") + 1);
85
86         if (endptr) {
87             *endptr = '\0';
88         }
89
90         sprintf(outfile, "%s.dat", infile);
91     }
92
93
94     write_output(outfile, cfg_input);
95
96
97     return 0;
98 }
99
100 char * get_val(ezxml_t cfg, char * tag) {
101     char * attrib = (char *)ezxml_attr(cfg, tag);
102     ezxml_t txt = ezxml_child(cfg, tag);
103
104     if ((txt != NULL) && (attrib != NULL)) {
105         printf("Invalid Cfg file: Duplicate value for %s (attr=%s, txt=%s)\n", 
106                tag, attrib, ezxml_txt(txt));
107         exit(-1);
108     }
109
110     return (attrib == NULL) ? ezxml_txt(txt) : attrib;
111 }
112
113
114 int write_output(char * filename, ezxml_t cfg_output) {
115     FILE * data_file = fopen(filename, "w+");
116     char * new_cfg_str = ezxml_toxml(cfg_output);
117     unsigned int cfg_len = strlen(new_cfg_str);
118     unsigned long long zero = 0;
119     int i = 0;
120     unsigned long long offset = 0;
121     unsigned long long file_cnt = num_files;
122
123     fwrite("v3vee\0\0\0", 8, 1, data_file);
124     offset += 8;
125
126     //  printf("New config: \n%s\n", new_cfg_str);
127     
128     fwrite(&cfg_len, sizeof(unsigned int), 1, data_file);
129     offset += sizeof(unsigned int);
130
131     fwrite(new_cfg_str, cfg_len, 1, data_file);
132     offset += cfg_len;
133
134     fwrite(&zero, 1, 8, data_file);
135     offset += 8;
136
137     printf("setting number of files to %llu\n", file_cnt);
138     printf("sizeof(file_cnt)=%d \n", sizeof(file_cnt));
139
140     fwrite(&file_cnt, 8, 1, data_file);
141     offset += 8;
142
143     // each index entry is 16 bytes long plus end padding
144     offset += (16 * num_files) + 8;
145
146     for (i = 0; i < num_files; i++) {
147         fwrite(&i, 4, 1, data_file);
148         fwrite(&(files[i].size), 4, 1, data_file);
149         fwrite(&offset, 8, 1, data_file);
150
151         offset += files[i].size;
152     }
153
154     fwrite(&zero, 1, 8, data_file);
155
156     for (i = 0; i < num_files; i++) {
157         if (fwrite(files[i].data, 1, files[i].size, data_file) != files[i].size) {
158             printf("Error writing data file contents");
159             exit(-1);
160         }       
161     }
162     
163
164
165     fclose(data_file);
166
167     return 0;
168 }
169
170
171
172 int parse_config_input(ezxml_t cfg_input) {
173     ezxml_t file_tags = NULL;
174     ezxml_t tmp_file_tag = NULL;
175
176     // files are transformed into blobs that are slapped to the end of the file
177         
178     file_tags = ezxml_child(cfg_input, "files");
179
180     tmp_file_tag = ezxml_child(file_tags, "file");
181
182     while (tmp_file_tag) {
183         char * filename = get_val(tmp_file_tag, "filename");
184         struct stat file_stats;
185         FILE * data_file = NULL;
186         char * id = get_val(tmp_file_tag, "id");
187         char index_buf[256];
188
189         snprintf(index_buf, 256, "%d", num_files);
190
191
192         strncpy(files[num_files].id, ezxml_attr(tmp_file_tag, "id"), 256);
193
194         printf("file id=%s, name=%s\n", 
195                id,
196                filename);
197         
198
199         if (stat(filename, &file_stats) != 0) {
200             perror(filename);
201             exit(-1);
202         }
203
204         files[num_files].size = (unsigned int)file_stats.st_size;
205         printf("file size = %d\n", files[num_files].size);
206
207         files[num_files].data = malloc(files[num_files].size);
208
209         data_file = fopen(filename, "r");
210
211         if (fread(files[num_files].data, files[num_files].size, 1, data_file) == 0) {
212             printf("Error reading data file %s\n", filename);
213             exit(-1);
214         }
215
216         fclose(data_file);
217
218
219         ezxml_set_attr_d(tmp_file_tag, "index", index_buf);
220
221         num_files++;
222         tmp_file_tag = ezxml_next(tmp_file_tag);
223     }
224
225
226     return 0;
227 }