dav/scfg.c

changeset 252
6b8e287269fc
parent 246
470f0c2e505e
child 253
1d2be1b31e70
equal deleted inserted replaced
251:7534cb97b9ab 252:6b8e287269fc
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 */
69 struct stat s; 78 struct stat s;
70 if(stat(file, &s)) { 79 if(stat(file, &s)) {
71 switch(errno) { 80 switch(errno) {
72 case ENOENT: { 81 case ENOENT: {
73 if(create_default_sync_config(file)) { 82 if(create_default_sync_config(file)) {
74 return -1; 83 /* this recursion is safe: ENOENT cannot occur again */
84 return load_sync_config();
75 } 85 }
76 break; 86 break;
77 } 87 }
78 default: { 88 default: {
79 perror("Cannot load sync.xml"); 89 perror("Cannot load sync.xml");
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 }

mercurial