36 |
36 |
37 #include "scfg.h" |
37 #include "scfg.h" |
38 |
38 |
39 #define xstreq(a,b) xmlStrEqual(BAD_CAST a, BAD_CAST b) |
39 #define xstreq(a,b) xmlStrEqual(BAD_CAST a, BAD_CAST b) |
40 |
40 |
|
41 |
|
42 #define print_error(...) \ |
|
43 do {\ |
|
44 fprintf(stderr, "Error (sync.xml): " __VA_ARGS__); \ |
|
45 fprintf(stderr, "Abort.\n"); \ |
|
46 } while(0); |
|
47 #define print_warning(...) \ |
|
48 fprintf(stderr, "Warning (sync.xml): " __VA_ARGS__); |
|
49 |
41 #ifdef _WIN32 |
50 #ifdef _WIN32 |
42 #define ENV_HOME getenv("USERPROFILE") |
51 #define ENV_HOME getenv("USERPROFILE") |
43 #else |
52 #else |
44 #define ENV_HOME getenv("HOME") |
53 #define ENV_HOME getenv("HOME") |
45 #endif /* _WIN32 */ |
54 #endif /* _WIN32 */ |
83 return 0; |
93 return 0; |
84 } |
94 } |
85 |
95 |
86 xmlDoc *doc = xmlReadFile(file, NULL, 0); |
96 xmlDoc *doc = xmlReadFile(file, NULL, 0); |
87 if(!doc) { |
97 if(!doc) { |
88 fprintf(stderr, "Broken configuration file\n"); |
98 fprintf(stderr, "Cannot load sync.xml\n"); |
89 free(file); |
99 free(file); |
90 return -1; |
100 return -1; |
91 } |
101 } |
92 |
102 |
93 int ret = 0; |
103 int ret = 0; |
94 xmlNode *node = xmlDocGetRootElement(doc)->children; |
104 xmlNode *node = xmlDocGetRootElement(doc)->children; |
95 while(node) { |
105 while(node && !ret) { |
96 if(node->type == XML_ELEMENT_NODE) { |
106 if(node->type == XML_ELEMENT_NODE) { |
97 if(xstreq(node->name, "directory")) { |
107 if(xstreq(node->name, "directory")) { |
98 if(scfg_load_directory(node)) { |
108 ret = scfg_load_directory(node); |
99 ret = 1; |
109 } else { |
100 ucx_map_free(directories); |
110 print_error("unknown config element: %s\n", node->name); |
101 break; |
111 ret = 1; |
102 } |
|
103 } |
112 } |
104 } |
113 } |
105 node = node->next; |
114 node = node->next; |
106 } |
115 } |
107 |
116 |
124 node = node->children; |
133 node = node->children; |
125 |
134 |
126 while(node) { |
135 while(node) { |
127 if(node->type == XML_ELEMENT_NODE) { |
136 if(node->type == XML_ELEMENT_NODE) { |
128 char *value = util_xml_get_text(node); |
137 char *value = util_xml_get_text(node); |
|
138 if(xstreq(node->name, "include")) { |
|
139 if(value) { |
|
140 *include = add_regex_pattern(*include, value); |
|
141 } |
|
142 } else if(xstreq(node->name, "exclude")) { |
|
143 if(value) { |
|
144 *exclude = add_regex_pattern(*exclude, value); |
|
145 } |
|
146 } else { |
|
147 print_error("unknown filter config element: %s\n", node->name); |
|
148 return 1; |
|
149 } |
129 if(!value) { |
150 if(!value) { |
|
151 print_error("missing value for filter: %s\n", node->name); |
130 return 1; |
152 return 1; |
131 } else if(xstreq(node->name, "include")) { |
|
132 *include = add_regex_pattern(*include, value); |
|
133 } else if(xstreq(node->name, "exclude")) { |
|
134 *exclude = add_regex_pattern(*exclude, value); |
|
135 } |
153 } |
136 } |
154 } |
137 |
155 |
138 node = node->next; |
156 node = node->next; |
139 } |
157 } |
157 |
175 |
158 node = node->children; |
176 node = node->children; |
159 while(node) { |
177 while(node) { |
160 if(node->type == XML_ELEMENT_NODE) { |
178 if(node->type == XML_ELEMENT_NODE) { |
161 char *value = util_xml_get_text(node); |
179 char *value = util_xml_get_text(node); |
|
180 /* every key needs a value */ |
162 if(!value) { |
181 if(!value) { |
163 // next |
182 /* TODO: maybe this should only be reported, if the key is valid |
164 } else if(xstreq(node->name, "name")) { |
183 * But this makes the code very ugly. |
|
184 */ |
|
185 print_error("missing value for directory element: %s\n", |
|
186 node->name); |
|
187 return 1; |
|
188 } |
|
189 if(xstreq(node->name, "name")) { |
165 name = value; |
190 name = value; |
166 } else if(xstreq(node->name, "path")) { |
191 } else if(xstreq(node->name, "path")) { |
167 path = value; |
192 path = value; |
168 } else if(xstreq(node->name, "trash")) { |
193 } else if(xstreq(node->name, "trash")) { |
169 trash = value; |
194 trash = value; |
171 collection = value; |
196 collection = value; |
172 } else if(xstreq(node->name, "repository")) { |
197 } else if(xstreq(node->name, "repository")) { |
173 repository = value; |
198 repository = value; |
174 } else if(xstreq(node->name, "filter")) { |
199 } else if(xstreq(node->name, "filter")) { |
175 if(scfg_load_filter(node, &include, &exclude)) { |
200 if(scfg_load_filter(node, &include, &exclude)) { |
176 return -1; |
201 return 1; |
177 } |
202 } |
178 } else if(xstreq(node->name, "database")) { |
203 } else if(xstreq(node->name, "database")) { |
179 database = value; |
204 database = value; |
180 } else if(xstreq(node->name, "max-retry")) { |
205 } else if(xstreq(node->name, "max-retry")) { |
181 int64_t i; |
206 int64_t i; |
182 if(util_strtoint(value, &i) && i >= 0) { |
207 if(util_strtoint(value, &i) && i >= 0) { |
183 max_retry = (int)i; |
208 max_retry = (int)i; |
184 } else { |
209 } else { |
185 fprintf(stderr, "Warning: sync.xml: unsigned integer value " |
210 print_warning("unsigned integer value " |
186 "expected in <max-retry> element\n"); |
211 "expected in <max-retry> element\n"); |
187 } |
212 } |
188 } else if(xstreq(node->name, "backup-on-pull")) { |
213 } else if(xstreq(node->name, "backup-on-pull")) { |
189 backuppull = util_getboolean(value); |
214 backuppull = util_getboolean(value); |
190 } else if(xstreq(node->name, "lock-pull")) { |
215 } else if(xstreq(node->name, "lock-pull")) { |
191 lockpull = util_getboolean(value); |
216 lockpull = util_getboolean(value); |
192 } else if(xstreq(node->name, "lock-push")) { |
217 } else if(xstreq(node->name, "lock-push")) { |
193 lockpush = util_getboolean(value); |
218 lockpush = util_getboolean(value); |
|
219 } else { |
|
220 print_error("unknown directory config element: %s\n", |
|
221 node->name); |
|
222 return 1; |
194 } |
223 } |
195 } |
224 } |
196 node = node->next; |
225 node = node->next; |
197 } |
226 } |
198 |
227 |
199 if(!name) { |
228 if(!name) { |
200 fprintf(stderr, "Missing name element for directory\n"); |
229 print_error("missing name element for directory\n"); |
201 return -1; |
230 return 1; |
202 } |
231 } |
203 if(!path) { |
232 if(!path) { |
204 fprintf(stderr, "Missing path element for directory\n"); |
233 print_error("missing path element for directory %s\n", name); |
205 return -1; |
234 return 1; |
206 } |
235 } |
207 if(!repository) { |
236 if(!repository) { |
208 fprintf(stderr, "Missing repository element for directory\n"); |
237 print_error("missing repository element for directory %s\n", name); |
209 return -1; |
238 return 1; |
210 } |
239 } |
211 if(!database) { |
240 if(!database) { |
212 fprintf(stderr, "Missing database element for directory\n"); |
241 print_error("missing database element for directory %s\n", name); |
213 return -1; |
242 return 1; |
214 } |
243 } |
215 |
244 |
216 SyncDirectory *dir = malloc(sizeof(SyncDirectory)); |
245 SyncDirectory *dir = malloc(sizeof(SyncDirectory)); |
217 dir->name = strdup(name); |
246 dir->name = strdup(name); |
218 dir->path = scfg_create_path(path); |
247 dir->path = scfg_create_path(path); |
424 return dbname; |
453 return dbname; |
425 } |
454 } |
426 |
455 |
427 |
456 |
428 void free_sync_config() { |
457 void free_sync_config() { |
429 UcxMapIterator i = ucx_map_iterator(directories); |
458 if(directories) { |
430 SyncDirectory *dir; |
459 UcxMapIterator i = ucx_map_iterator(directories); |
431 UCX_MAP_FOREACH(elm, dir, i) { |
460 SyncDirectory *dir; |
432 free(dir->name); |
461 UCX_MAP_FOREACH(elm, dir, i) { |
433 free(dir->path); |
462 free(dir->name); |
434 free(dir->repository); |
463 free(dir->path); |
435 free(dir->database); |
464 free(dir->repository); |
436 |
465 free(dir->database); |
437 if(dir->collection) { |
466 |
438 free(dir->collection); |
467 if(dir->collection) { |
439 } |
468 free(dir->collection); |
440 if(dir->trash) { |
469 } |
441 free(dir->trash); |
470 if(dir->trash) { |
442 } |
471 free(dir->trash); |
443 |
472 } |
444 UCX_FOREACH(elm, dir->include) { |
473 |
445 regfree(elm->data); |
474 UCX_FOREACH(elm, dir->include) { |
446 free(elm->data); |
475 regfree(elm->data); |
447 } |
476 free(elm->data); |
448 ucx_list_free(dir->include); |
477 } |
449 UCX_FOREACH(elm, dir->exclude) { |
478 ucx_list_free(dir->include); |
450 regfree(elm->data); |
479 UCX_FOREACH(elm, dir->exclude) { |
451 free(elm->data); |
480 regfree(elm->data); |
452 } |
481 free(elm->data); |
453 ucx_list_free(dir->exclude); |
482 } |
454 |
483 ucx_list_free(dir->exclude); |
455 free(dir); |
484 |
456 } |
485 free(dir); |
457 |
486 } |
458 ucx_map_free(directories); |
487 |
459 } |
488 ucx_map_free(directories); |
|
489 } |
|
490 } |