32 |
32 |
33 #include "db.h" |
33 #include "db.h" |
34 |
34 |
35 #include <libidav/utils.h> |
35 #include <libidav/utils.h> |
36 |
36 |
|
37 #include <libxml/encoding.h> |
|
38 #include <libxml/xmlwriter.h> |
|
39 |
37 |
40 |
38 #define xstreq(a,b) xmlStrEqual(BAD_CAST a, BAD_CAST b) |
41 #define xstreq(a,b) xmlStrEqual(BAD_CAST a, BAD_CAST b) |
39 |
42 |
40 #ifdef _WIN32 |
43 #ifdef _WIN32 |
41 #define ENV_HOME getenv("USERPROFILE") |
44 #define ENV_HOME getenv("USERPROFILE") |
48 char *db_file = util_concat_path(dav_dir, name); |
51 char *db_file = util_concat_path(dav_dir, name); |
49 free(dav_dir); |
52 free(dav_dir); |
50 |
53 |
51 xmlTextReaderPtr reader = xmlReaderForFile(db_file, NULL, 0); |
54 xmlTextReaderPtr reader = xmlReaderForFile(db_file, NULL, 0); |
52 if(!reader) { |
55 if(!reader) { |
53 fprintf(stderr, "Cannot open database file: %s\n", db_file); |
56 xmlDoc *doc = doc = xmlNewDoc(BAD_CAST "1.0"); |
|
57 xmlNode *root = xmlNewNode(NULL, BAD_CAST "directory"); |
|
58 xmlDocSetRootElement(doc, root); |
|
59 UcxMap *db = NULL; |
|
60 if(xmlSaveFormatFileEnc(db_file, doc, "UTF-8", 1) != -1) { |
|
61 db = ucx_map_new(2048); |
|
62 } |
|
63 xmlFreeDoc(doc); |
54 free(db_file); |
64 free(db_file); |
55 return NULL; |
65 return db; |
56 } |
66 } |
57 free(db_file); |
67 free(db_file); |
58 |
68 |
59 UcxMap *map = ucx_map_new(2048); |
69 UcxMap *map = ucx_map_new(2048); |
60 int error = 0; |
70 int error = 0; |
105 } else if(type == XML_READER_TYPE_TEXT) { |
115 } else if(type == XML_READER_TYPE_TEXT) { |
106 const xmlChar *value = xmlTextReaderConstValue(reader); |
116 const xmlChar *value = xmlTextReaderConstValue(reader); |
107 int b = 0; |
117 int b = 0; |
108 switch(field) { |
118 switch(field) { |
109 case 0: { |
119 case 0: { |
110 res->name = strdup((char*)value); |
120 res->path = strdup((char*)value); |
111 break; |
121 break; |
112 } |
122 } |
113 case 1: { |
123 case 1: { |
114 res->etag = strdup((char*)value); |
124 res->etag = strdup((char*)value); |
115 break; |
125 break; |
116 } |
126 } |
117 case 2: { |
127 case 2: { |
118 res->last_modified = util_parse_lastmodified((char*)value); |
128 //res->last_modified = util_parse_lastmodified((char*)value); |
|
129 //res->last_modified = atoi((char*)value); |
|
130 char *endptr = (char*)value; |
|
131 time_t t = strtoll((char*)value, &endptr, 10); |
|
132 if(endptr == (char*)value) { |
|
133 fprintf( |
|
134 stderr, |
|
135 "lastmodified contains not a number: %s\n", value); |
|
136 } else { |
|
137 res->last_modified = t; |
|
138 } |
119 break; |
139 break; |
120 } |
140 } |
121 case 3: { |
141 case 3: { |
122 res->size = atoi((char*)value); |
142 res->size = atoi((char*)value); |
123 break; |
143 break; |
130 field = -1; |
150 field = -1; |
131 } |
151 } |
132 } |
152 } |
133 } |
153 } |
134 |
154 |
135 if(!res->name || !res->path || res->last_modified == 0) { |
155 if(!res->path || res->last_modified == 0) { |
136 // TODO: free res |
156 // TODO: free res |
137 return NULL; |
157 return NULL; |
138 } else { |
158 } else { |
139 return res; |
159 return res; |
140 } |
160 } |
141 } |
161 } |
142 |
162 |
143 int store_db(UcxMap *db, char *name) { |
163 int store_db(UcxMap *db, char *name) { |
144 // TODO: |
164 // open writer |
145 |
165 char *dav_dir = util_concat_path(ENV_HOME, ".dav"); |
|
166 char *db_file = util_concat_path(dav_dir, name); |
|
167 free(dav_dir); |
|
168 xmlTextWriterPtr writer = xmlNewTextWriterFilename(db_file, 0); |
|
169 if(!writer) { |
|
170 fprintf(stderr, "Cannot write db file: %s\n", db_file); |
|
171 free(db_file); |
|
172 return -1; |
|
173 } |
|
174 free(db_file); |
|
175 |
|
176 // start document |
|
177 int r = 0; |
|
178 r = xmlTextWriterStartDocument(writer, NULL, "UTF-8", NULL); |
|
179 if(r < 0) { |
|
180 xmlFreeTextWriter(writer); |
|
181 return -1; |
|
182 } |
|
183 xmlTextWriterStartElement(writer, BAD_CAST "directory"); |
|
184 |
|
185 // write all resource entries |
|
186 UcxMapIterator i = ucx_map_iterator(db); |
|
187 LocalResource *res; |
|
188 UCX_MAP_FOREACH(key, res, i) { |
|
189 // <resource> |
|
190 xmlTextWriterStartElement(writer, BAD_CAST "resource"); |
|
191 |
|
192 r = xmlTextWriterWriteElement( |
|
193 writer, |
|
194 BAD_CAST "path", |
|
195 BAD_CAST res->path); |
|
196 if(r < 0) { |
|
197 fprintf(stderr, "Cannot write path: %s\n", res->path); |
|
198 xmlFreeTextWriter(writer); |
|
199 return -1; |
|
200 } |
|
201 |
|
202 if(res->etag) { |
|
203 r = xmlTextWriterWriteElement( |
|
204 writer, |
|
205 BAD_CAST "etag", |
|
206 BAD_CAST res->etag); |
|
207 if(r < 0) { |
|
208 fprintf(stderr, "Cannot write etag: %s\n", res->etag); |
|
209 xmlFreeTextWriter(writer); |
|
210 return -1; |
|
211 } |
|
212 } |
|
213 |
|
214 r = xmlTextWriterWriteFormatElement( |
|
215 writer, |
|
216 BAD_CAST "lastmodified", |
|
217 "%" PRId64, |
|
218 (int64_t)res->last_modified); |
|
219 if(r < 0) { |
|
220 fprintf(stderr, "Cannot write lastmodified\n"); |
|
221 xmlFreeTextWriter(writer); |
|
222 return -1; |
|
223 } |
|
224 |
|
225 r = xmlTextWriterWriteFormatElement( |
|
226 writer, |
|
227 BAD_CAST "size", |
|
228 "%" PRId64, |
|
229 (int64_t)res->size); |
|
230 if(r < 0) { |
|
231 fprintf(stderr, "Cannot write size\n"); |
|
232 xmlFreeTextWriter(writer); |
|
233 return -1; |
|
234 } |
|
235 |
|
236 // </resource> |
|
237 xmlTextWriterEndElement(writer); |
|
238 } |
|
239 |
|
240 // end |
|
241 xmlTextWriterEndElement(writer); |
|
242 r = xmlTextWriterEndDocument(writer); |
|
243 if(r < 0) { |
|
244 xmlFreeTextWriter(writer); |
|
245 return -1; |
|
246 } |
|
247 xmlFreeTextWriter(writer); |
|
248 return 0; |
146 } |
249 } |