43 #define ENV_HOME getenv("HOME") |
44 #define ENV_HOME getenv("HOME") |
44 #endif /* _WIN32 */ |
45 #endif /* _WIN32 */ |
45 |
46 |
46 static UcxMap *directories; |
47 static UcxMap *directories; |
47 |
48 |
|
49 static int create_default_sync_config(char *file) { |
|
50 FILE *out = fopen(file, "w"); |
|
51 if(!out) { |
|
52 perror("fopen"); |
|
53 return -1; |
|
54 } |
|
55 |
|
56 fputs("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n", out); |
|
57 fputs("<configuration>\n", out); |
|
58 fputs("</configuration>\n", out); |
|
59 fclose(out); |
|
60 |
|
61 return 0; |
|
62 } |
|
63 |
48 int load_sync_config() { |
64 int load_sync_config() { |
49 char *file = util_concat_path(ENV_HOME, ".dav/sync.xml"); |
65 char *file = util_concat_path(ENV_HOME, ".dav/sync.xml"); |
|
66 |
|
67 struct stat s; |
|
68 if(stat(file, &s)) { |
|
69 switch(errno) { |
|
70 case ENOENT: { |
|
71 if(create_default_sync_config(file)) { |
|
72 return -1; |
|
73 } |
|
74 break; |
|
75 } |
|
76 default: { |
|
77 perror("Cannot load sync.xml"); |
|
78 } |
|
79 } |
|
80 return 0; |
|
81 } |
|
82 |
50 xmlDoc *doc = xmlReadFile(file, NULL, 0); |
83 xmlDoc *doc = xmlReadFile(file, NULL, 0); |
51 if(!doc) { |
84 if(!doc) { |
52 fprintf(stderr, "Missing or broken configuration file\n"); |
85 fprintf(stderr, "Broken configuration file\n"); |
53 scfg_print_example(); |
|
54 return -1; |
86 return -1; |
55 } |
87 } |
56 |
88 |
57 directories = ucx_map_new(8); |
89 directories = ucx_map_new(8); |
58 |
90 |
198 ucx_map_cstr_put(directories, name, dir); |
230 ucx_map_cstr_put(directories, name, dir); |
199 |
231 |
200 return 0; |
232 return 0; |
201 } |
233 } |
202 |
234 |
203 void scfg_print_example() { |
|
204 fprintf(stderr, |
|
205 "example sync.xml\n\n" |
|
206 "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" |
|
207 "<configuration>\n" |
|
208 " <directory>\n" |
|
209 " <!-- identifier -->\n" |
|
210 " <name>documents</name>\n\n" |
|
211 " <!-- local path to the directory -->\n" |
|
212 " <path>/home/user/Documents</path>\n\n" |
|
213 " <!-- optional trash path -->\n" |
|
214 " <trash>.trash</trash>" |
|
215 " <!-- repository name specified in config.xml -->\n" |
|
216 " <repository>server</repository>\n\n" |
|
217 " <!-- collection to synchronize (optional) -->\n" |
|
218 " <collection>somecol</collection>\n\n" |
|
219 " <!-- database file name -->\n" |
|
220 " <database>documents-db.xml</database>\n" |
|
221 " </directory>\n" |
|
222 "</configuration>\n"); |
|
223 } |
|
224 |
|
225 SyncDirectory* scfg_get_dir(char *name) { |
235 SyncDirectory* scfg_get_dir(char *name) { |
226 return ucx_map_cstr_get(directories, name); |
236 return ucx_map_cstr_get(directories, name); |
|
237 } |
|
238 |
|
239 |
|
240 int add_directory(SyncDirectory *dir) { |
|
241 char *file = util_concat_path(ENV_HOME, ".dav/sync.xml"); |
|
242 xmlDoc *doc = xmlReadFile(file, NULL, 0); |
|
243 if(!doc) { |
|
244 free(file); |
|
245 fprintf(stderr, "Cannot load config.xml\n"); |
|
246 return 1; |
|
247 } |
|
248 |
|
249 xmlNode *root = xmlDocGetRootElement(doc); |
|
250 |
|
251 xmlNode *dirNode = xmlNewNode(NULL, BAD_CAST "directory"); |
|
252 xmlNodeAddContent(dirNode, BAD_CAST "\n\t\t"); |
|
253 |
|
254 xmlNewTextChild(dirNode, NULL, BAD_CAST "name", BAD_CAST dir->name); |
|
255 xmlNodeAddContent(dirNode, BAD_CAST "\n\t\t"); |
|
256 |
|
257 xmlNewTextChild(dirNode, NULL, BAD_CAST "path", BAD_CAST dir->path); |
|
258 xmlNodeAddContent(dirNode, BAD_CAST "\n\t\t"); |
|
259 |
|
260 xmlNewTextChild(dirNode, NULL, BAD_CAST "repository", BAD_CAST dir->repository); |
|
261 xmlNodeAddContent(dirNode, BAD_CAST "\n\t\t"); |
|
262 |
|
263 if(dir->trash) { |
|
264 xmlNewTextChild(dirNode, NULL, BAD_CAST "trash", BAD_CAST dir->trash); |
|
265 xmlNodeAddContent(dirNode, BAD_CAST "\n\t\t"); |
|
266 } |
|
267 xmlNewTextChild(dirNode, NULL, BAD_CAST "database", BAD_CAST dir->database); |
|
268 xmlNodeAddContent(dirNode, BAD_CAST "\n\t"); |
|
269 |
|
270 xmlNodeAddContent(root, BAD_CAST "\n\t"); |
|
271 xmlAddChild(root, dirNode); |
|
272 xmlNodeAddContent(root, BAD_CAST "\n"); |
|
273 |
|
274 int ret = 0; |
|
275 if(xmlSaveFormatFileEnc(file, doc, "UTF-8", 1) == -1) { |
|
276 ret = 1; |
|
277 } |
|
278 xmlFreeDoc(doc); |
|
279 free(file); |
|
280 |
|
281 return ret; |
227 } |
282 } |
228 |
283 |
229 int list_syncdirs() { |
284 int list_syncdirs() { |
230 UcxMapIterator i = ucx_map_iterator(directories); |
285 UcxMapIterator i = ucx_map_iterator(directories); |
231 SyncDirectory *dir; |
286 SyncDirectory *dir; |
232 UCX_MAP_FOREACH(key, dir, i) { |
287 UCX_MAP_FOREACH(key, dir, i) { |
233 printf("%s\n", dir->name); |
288 printf("%s\n", dir->name); |
234 } |
289 } |
235 return 0; |
290 return 0; |
236 } |
291 } |
|
292 |
|
293 char* generate_db_name(char *basename) { |
|
294 char *dbname = NULL; |
|
295 int count = -1; |
|
296 while(!dbname) { |
|
297 sstr_t name = count < 0 ? |
|
298 ucx_sprintf("%s-db.xml", basename) : |
|
299 ucx_sprintf("%s%d-db.xml", basename, count); |
|
300 count++; |
|
301 |
|
302 UcxMapIterator i = ucx_map_iterator(directories); |
|
303 SyncDirectory *dir; |
|
304 bool unique = true; |
|
305 UCX_MAP_FOREACH(key, dir, i) { |
|
306 if(!sstrcmp(name, sstr(dir->database))) { |
|
307 unique = false; |
|
308 break; |
|
309 } |
|
310 } |
|
311 if(unique) { |
|
312 dbname = name.ptr; |
|
313 break; |
|
314 } |
|
315 } |
|
316 return dbname; |
|
317 } |