dav/sync.c

changeset 49
c5759ac76c1b
parent 48
08d5544c92fb
child 50
9c486ea25161
equal deleted inserted replaced
48:08d5544c92fb 49:c5759ac76c1b
107 if(!repo) { 107 if(!repo) {
108 fprintf(stderr, "Unkown repository %s\n", dir->name); 108 fprintf(stderr, "Unkown repository %s\n", dir->name);
109 return -1; 109 return -1;
110 } 110 }
111 111
112 UcxMap *db = load_db(dir->database); 112 SyncDatabase *db = load_db(dir->database);
113 if(!db) { 113 if(!db) {
114 fprintf(stderr, "Cannot load database file: %s\n", dir->database); 114 fprintf(stderr, "Cannot load database file: %s\n", dir->database);
115 return -1; 115 return -1;
116 } 116 }
117 117
132 132
133 if(!ls->children) { 133 if(!ls->children) {
134 // TODO: free 134 // TODO: free
135 return 0; // empty repository 135 return 0; // empty repository
136 } 136 }
137 137
138 UcxList *stack = ucx_list_prepend(NULL, ls->children); 138 UcxList *stack = ucx_list_prepend(NULL, ls->children);
139 while(stack) { 139 while(stack) {
140 DavResource *res = stack->data; 140 DavResource *res = stack->data;
141 stack = ucx_list_remove(stack, stack); 141 stack = ucx_list_remove(stack, stack);
142 142
143 while(res) { 143 while(res) {
144 if(sync_get_resource(dir, res, db)) { 144 if(sync_get_resource(dir, res, db)) {
145 fprintf(stderr, "sync_get_resource failed for resource: %s\n", res->path); 145 fprintf(stderr, "sync_get_resource failed for resource: %s\n", res->path);
146 } 146 }
147 147
161 } 161 }
162 162
163 return 0; 163 return 0;
164 } 164 }
165 165
166 int sync_get_resource(SyncDirectory *dir, DavResource *res, UcxMap *db) { 166 int sync_get_resource(SyncDirectory *dir, DavResource *res, SyncDatabase *db) {
167 LocalResource *local = ucx_map_cstr_get(db, res->path); 167 LocalResource *local = ucx_map_cstr_get(db->resources, res->path);
168 char *local_path = util_concat_path(dir->path, res->path);
169
168 char *etag = dav_get_property(res, "D:getetag"); 170 char *etag = dav_get_property(res, "D:getetag");
171 struct stat s;
169 if(local) { 172 if(local) {
173 if(stat(local_path, &s)) {
174 if(errno == ENOENT) {
175 printf("removed %s\n", res->path);
176 // the file is in the database, but doesn't exists
177 // mark the file as removed to delete it on next push
178 ucx_map_cstr_remove(db->resources, local->path);
179 ucx_map_cstr_put(db->remove, local->path, local);
180 return 0;
181 } else {
182 fprintf(stderr, "stat failed: %s\n", local_path);
183 free(local_path);
184 return -1;
185 }
186 }
187
170 if(local->etag) { 188 if(local->etag) {
171 sstr_t e = sstr(etag); 189 sstr_t e = sstr(etag);
172 if(sstrprefix(e, S("W/"))) { 190 if(sstrprefix(e, S("W/"))) {
173 e = sstrsubs(e, 2); 191 e = sstrsubs(e, 2);
174 } 192 }
177 return 0; 195 return 0;
178 } 196 }
179 } 197 }
180 } 198 }
181 199
182 char *local_path = util_concat_path(dir->path, res->path);
183 int ret = 0; 200 int ret = 0;
184 if(res->iscollection) { 201 if(res->iscollection) {
185 mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; 202 mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
186 //printf("mkdir %s\n", local_path); 203 //printf("mkdir %s\n", local_path);
187 if(util_mkdir(local_path, mode) && errno != EEXIST) { 204 if(util_mkdir(local_path, mode) && errno != EEXIST) {
199 ret = -1; 216 ret = -1;
200 } 217 }
201 fclose(out); 218 fclose(out);
202 219
203 if(ret == 0) { 220 if(ret == 0) {
204 // get file informations for db update
205 struct stat s;
206 if(stat(local_path, &s)) {
207 fprintf(stderr, "stat failed: %s\n", local_path);
208 ret = -1;
209 }
210
211 if(!local) { 221 if(!local) {
222 // new local resource
212 local = calloc(1, sizeof(LocalResource)); 223 local = calloc(1, sizeof(LocalResource));
213 local->path = strdup(res->path); 224 local->path = strdup(res->path);
214 ucx_map_cstr_put(db, local->path, local); 225 ucx_map_cstr_put(db->resources, local->path, local);
215 } 226 }
216 227
217 if(local->etag) { 228 if(local->etag) {
218 free(local->etag); 229 free(local->etag);
219 } 230 }
231 // set metadata from stat
220 local->etag = etag; 232 local->etag = etag;
221 local->last_modified = s.st_mtim.tv_sec; 233 local->last_modified = s.st_mtim.tv_sec;
222 local->size = s.st_size; 234 local->size = s.st_size;
223 } 235 }
224 } 236 }
243 if(!repo) { 255 if(!repo) {
244 fprintf(stderr, "Unkown repository %s\n", dir->name); 256 fprintf(stderr, "Unkown repository %s\n", dir->name);
245 return -1; 257 return -1;
246 } 258 }
247 259
248 UcxMap *db = load_db(dir->database); 260 SyncDatabase *db = load_db(dir->database);
249 if(!db) { 261 if(!db) {
250 fprintf(stderr, "Cannot load database file: %s\n", dir->database); 262 fprintf(stderr, "Cannot load database file: %s\n", dir->database);
251 return -1; 263 return -1;
252 } 264 }
253 265
277 } 289 }
278 290
279 return 0; 291 return 0;
280 } 292 }
281 293
282 UcxList* local_scan(SyncDirectory *dir, UcxMap *db) { 294 UcxList* local_scan(SyncDirectory *dir, SyncDatabase *db) {
283 UcxList *resources = NULL; 295 UcxList *resources = NULL;
284 296
285 char *path = strdup("/"); 297 char *path = strdup("/");
286 UcxList *stack = ucx_list_prepend(NULL, path); 298 UcxList *stack = ucx_list_prepend(NULL, path);
287 while(stack) { 299 while(stack) {
320 free(file_path); 332 free(file_path);
321 333
322 if(S_ISDIR(s.st_mode)) { 334 if(S_ISDIR(s.st_mode)) {
323 stack = ucx_list_prepend(stack, new_path); 335 stack = ucx_list_prepend(stack, new_path);
324 } else { 336 } else {
325 LocalResource *res = ucx_map_cstr_get(db, new_path); 337 LocalResource *res = ucx_map_cstr_get(
338 db->resources,
339 new_path);
326 if(res) { 340 if(res) {
327 // the file is already in the database 341 // the file is already in the database
328 // compare length and lastmodified date 342 // compare length and lastmodified date
329 343
330 if(res->last_modified == s.st_mtim.tv_sec 344 if(res->last_modified == s.st_mtim.tv_sec
347 LocalResource *res = calloc(1, sizeof(LocalResource)); 361 LocalResource *res = calloc(1, sizeof(LocalResource));
348 res->path = strdup(new_path); 362 res->path = strdup(new_path);
349 res->etag = NULL; 363 res->etag = NULL;
350 res->last_modified = s.st_mtim.tv_sec; 364 res->last_modified = s.st_mtim.tv_sec;
351 res->size = s.st_size; 365 res->size = s.st_size;
352 ucx_map_cstr_put(db, res->path, res); 366 ucx_map_cstr_put(db->resources, res->path, res);
353 resources = ucx_list_append(resources, new_path); 367 resources = ucx_list_append(resources, new_path);
354 } 368 }
355 } 369 }
356 } 370 }
357 closedir(local_dir); 371 closedir(local_dir);
362 } 376 }
363 377
364 return resources; 378 return resources;
365 } 379 }
366 380
367 int sync_put_resource(SyncDirectory *dir, DavResource *res, UcxMap *db) { 381 int sync_put_resource(SyncDirectory *dir, DavResource *res, SyncDatabase *db) {
368 char *local_path = util_concat_path(dir->path, res->path); 382 char *local_path = util_concat_path(dir->path, res->path);
369 FILE *in = fopen(local_path, "r"); 383 FILE *in = fopen(local_path, "r");
370 if(!in) { 384 if(!in) {
371 fprintf(stderr, "Cannot open file %s\n", local_path); 385 fprintf(stderr, "Cannot open file %s\n", local_path);
372 free(local_path); 386 free(local_path);
387 ret = 0; 401 ret = 0;
388 break; 402 break;
389 } 403 }
390 404
391 if(ret == 0) { 405 if(ret == 0) {
392 LocalResource *local_res = ucx_map_cstr_get(db, res->path); 406 LocalResource *local_res = ucx_map_cstr_get(db->resources, res->path);
393 if(local_res->etag) { 407 if(local_res->etag) {
394 free(local_res->etag); 408 free(local_res->etag);
395 } 409 }
396 410
397 DavResource *up_res = dav_get(res->session, res->path, "D:getetag"); 411 DavResource *up_res = dav_get(res->session, res->path, "D:getetag");
398 char *etag_str = dav_get_property(up_res, "D:getetag"); 412 char *etag = dav_get_property(up_res, "D:getetag");
399 sstr_t etag; 413 if(etag) {
400 etag.ptr = NULL; 414 if(strlen(etag) > 2 && etag[0] == 'W' && etag[1] == '/') {
401 if(etag_str) { 415 etag = etag + 2;
402 etag = sstr(etag_str); 416 }
403 } 417 }
404 if(sstrprefix(etag, S("W/"))) { 418
405 etag = sstrsubs(etag, 2); 419
406 } 420 if(etag) {
407 421 local_res->etag = strdup(etag);
408
409 if(etag.ptr) {
410 local_res->etag = strdup(etag.ptr);
411 } else { 422 } else {
412 local_res->etag = NULL; 423 local_res->etag = NULL;
413 } 424 }
414 } 425 }
415 426

mercurial