44 #define ENV_HOME getenv("USERPROFILE") |
44 #define ENV_HOME getenv("USERPROFILE") |
45 #else |
45 #else |
46 #define ENV_HOME getenv("HOME") |
46 #define ENV_HOME getenv("HOME") |
47 #endif /* _WIN32 */ |
47 #endif /* _WIN32 */ |
48 |
48 |
49 UcxMap* load_db(char *name) { |
49 SyncDatabase* load_db(char *name) { |
50 char *dav_dir = util_concat_path(ENV_HOME, ".dav"); |
50 char *dav_dir = util_concat_path(ENV_HOME, ".dav"); |
51 char *db_file = util_concat_path(dav_dir, name); |
51 char *db_file = util_concat_path(dav_dir, name); |
52 free(dav_dir); |
52 free(dav_dir); |
53 |
53 |
|
54 SyncDatabase *db = malloc(sizeof(SyncDatabase)); |
54 xmlTextReaderPtr reader = xmlReaderForFile(db_file, NULL, 0); |
55 xmlTextReaderPtr reader = xmlReaderForFile(db_file, NULL, 0); |
55 if(!reader) { |
56 if(!reader) { |
56 xmlDoc *doc = doc = xmlNewDoc(BAD_CAST "1.0"); |
57 xmlDoc *doc = doc = xmlNewDoc(BAD_CAST "1.0"); |
57 xmlNode *root = xmlNewNode(NULL, BAD_CAST "directory"); |
58 xmlNode *root = xmlNewNode(NULL, BAD_CAST "directory"); |
58 xmlDocSetRootElement(doc, root); |
59 xmlDocSetRootElement(doc, root); |
59 UcxMap *db = NULL; |
|
60 if(xmlSaveFormatFileEnc(db_file, doc, "UTF-8", 1) != -1) { |
60 if(xmlSaveFormatFileEnc(db_file, doc, "UTF-8", 1) != -1) { |
61 db = ucx_map_new(2048); |
61 db->resources = ucx_map_new(2048); |
|
62 db->remove = ucx_map_new(8); |
|
63 } else { |
|
64 free(db); |
|
65 db = NULL; |
62 } |
66 } |
63 xmlFreeDoc(doc); |
67 xmlFreeDoc(doc); |
64 free(db_file); |
68 free(db_file); |
65 return db; |
69 return db; |
66 } |
70 } |
67 free(db_file); |
71 free(db_file); |
68 |
72 |
69 UcxMap *map = ucx_map_new(2048); |
73 db->resources = ucx_map_new(2048); |
|
74 db->remove = ucx_map_new(16); |
70 int error = 0; |
75 int error = 0; |
71 while(xmlTextReaderRead(reader)) { |
76 while(xmlTextReaderRead(reader)) { |
72 int type = xmlTextReaderNodeType(reader); |
77 int type = xmlTextReaderNodeType(reader); |
73 const xmlChar *name = xmlTextReaderConstName(reader); |
78 const xmlChar *name = xmlTextReaderConstName(reader); |
74 |
79 |
75 if(type == XML_READER_TYPE_ELEMENT) { |
80 if(type == XML_READER_TYPE_ELEMENT) { |
76 if(xstreq(name, "resource")) { |
81 if(xstreq(name, "resource")) { |
77 LocalResource *res = process_resource(reader); |
82 LocalResource *res = process_resource(reader); |
78 if(res) { |
83 if(res) { |
79 ucx_map_cstr_put(map, res->path, res); |
84 ucx_map_cstr_put(db->resources, res->path, res); |
|
85 } else { |
|
86 error = 1; |
|
87 break; |
|
88 } |
|
89 } else if(xstreq(name, "remove")) { |
|
90 LocalResource *res = process_remove(reader); |
|
91 if(res) { |
|
92 ucx_map_cstr_put(db->remove, res->path, res); |
80 } else { |
93 } else { |
81 error = 1; |
94 error = 1; |
82 break; |
95 break; |
83 } |
96 } |
84 } |
97 } |
158 } else { |
171 } else { |
159 return res; |
172 return res; |
160 } |
173 } |
161 } |
174 } |
162 |
175 |
163 int store_db(UcxMap *db, char *name) { |
176 LocalResource* process_remove(xmlTextReaderPtr reader) { |
|
177 LocalResource *res = calloc(1, sizeof(LocalResource)); |
|
178 |
|
179 int path = 0; |
|
180 while(xmlTextReaderRead(reader)) { |
|
181 int type = xmlTextReaderNodeType(reader); |
|
182 const xmlChar *name = xmlTextReaderConstName(reader); |
|
183 |
|
184 if(type == XML_READER_TYPE_ELEMENT) { |
|
185 if(xstreq(name, "path")) { |
|
186 path = 1; |
|
187 } |
|
188 } else if(type == XML_READER_TYPE_TEXT && path) { |
|
189 const xmlChar *value = xmlTextReaderConstValue(reader); |
|
190 res->path = strdup((char*)value); |
|
191 } else if(XML_READER_TYPE_END_ELEMENT) { |
|
192 if(xstreq(name, "remove")) { |
|
193 break; |
|
194 } else { |
|
195 path = 0; |
|
196 } |
|
197 } |
|
198 } |
|
199 |
|
200 if(!res->path) { |
|
201 // TODO: free res |
|
202 return NULL; |
|
203 } else { |
|
204 return res; |
|
205 } |
|
206 } |
|
207 |
|
208 int store_db(SyncDatabase *db, char *name) { |
164 // open writer |
209 // open writer |
165 char *dav_dir = util_concat_path(ENV_HOME, ".dav"); |
210 char *dav_dir = util_concat_path(ENV_HOME, ".dav"); |
166 char *db_file = util_concat_path(dav_dir, name); |
211 char *db_file = util_concat_path(dav_dir, name); |
167 free(dav_dir); |
212 free(dav_dir); |
168 xmlTextWriterPtr writer = xmlNewTextWriterFilename(db_file, 0); |
213 xmlTextWriterPtr writer = xmlNewTextWriterFilename(db_file, 0); |
181 return -1; |
226 return -1; |
182 } |
227 } |
183 xmlTextWriterStartElement(writer, BAD_CAST "directory"); |
228 xmlTextWriterStartElement(writer, BAD_CAST "directory"); |
184 |
229 |
185 // write all resource entries |
230 // write all resource entries |
186 UcxMapIterator i = ucx_map_iterator(db); |
231 UcxMapIterator i = ucx_map_iterator(db->resources); |
187 LocalResource *res; |
232 LocalResource *res; |
188 UCX_MAP_FOREACH(key, res, i) { |
233 UCX_MAP_FOREACH(key, res, i) { |
189 // <resource> |
234 // <resource> |
190 xmlTextWriterStartElement(writer, BAD_CAST "resource"); |
235 xmlTextWriterStartElement(writer, BAD_CAST "resource"); |
191 |
236 |
235 |
280 |
236 // </resource> |
281 // </resource> |
237 xmlTextWriterEndElement(writer); |
282 xmlTextWriterEndElement(writer); |
238 } |
283 } |
239 |
284 |
|
285 // write all remove entries |
|
286 i = ucx_map_iterator(db->remove); |
|
287 UCX_MAP_FOREACH(key, res, i) { |
|
288 // <remove> |
|
289 xmlTextWriterStartElement(writer, BAD_CAST "remove"); |
|
290 |
|
291 xmlTextWriterWriteElement( |
|
292 writer, |
|
293 BAD_CAST "path", |
|
294 BAD_CAST res->path); |
|
295 |
|
296 // </remove> |
|
297 xmlTextWriterEndElement(writer); |
|
298 } |
|
299 |
240 // end |
300 // end |
241 xmlTextWriterEndElement(writer); |
301 xmlTextWriterEndElement(writer); |
242 r = xmlTextWriterEndDocument(writer); |
302 r = xmlTextWriterEndDocument(writer); |
243 if(r < 0) { |
303 if(r < 0) { |
244 xmlFreeTextWriter(writer); |
304 xmlFreeTextWriter(writer); |