dav/sync.c

changeset 361
b6f2462ee055
parent 347
b6ff6be7aa91
child 363
e9ed8e130ccf
equal deleted inserted replaced
355:5da2cf15eb44 361:b6f2462ee055
1 /* 1 /*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 * 3 *
4 * Copyright 2016 Olaf Wintermann. All rights reserved. 4 * Copyright 2018 Olaf Wintermann. All rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met: 7 * modification, are permitted provided that the following conditions are met:
8 * 8 *
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
47 #include "scfg.h" 47 #include "scfg.h"
48 #include "sopt.h" 48 #include "sopt.h"
49 #include "db.h" 49 #include "db.h"
50 #include "error.h" 50 #include "error.h"
51 #include "assistant.h" 51 #include "assistant.h"
52 52 #include "libxattr.h"
53 #include "tags.h"
53 #include "sync.h" 54 #include "sync.h"
54 #include "libidav/session.h" 55 #include "libidav/session.h"
55 56
56 #include <pthread.h> 57 #include <pthread.h>
57 58
342 locked = TRUE; 343 locked = TRUE;
343 locktokenfile = create_locktoken_file(dir->name, lock->token); 344 locktokenfile = create_locktoken_file(dir->name, lock->token);
344 } 345 }
345 346
346 int ret = 0; 347 int ret = 0;
347 DavResource *ls = dav_query(sn, "select D:getetag,idav:status from / with depth = infinity"); 348 DavResource *ls = dav_query(sn, "select D:getetag,idav:status,idav:tags from / with depth = infinity");
348 if(!ls) { 349 if(!ls) {
349 print_resource_error(sn, "/"); 350 print_resource_error(sn, "/");
350 if(locked) { 351 if(locked) {
351 if(dav_unlock(root)) { 352 if(dav_unlock(root)) {
352 print_resource_error(sn, "/"); 353 print_resource_error(sn, "/");
582 local = calloc(1, sizeof(LocalResource)); 583 local = calloc(1, sizeof(LocalResource));
583 local->path = util_concat_path(res->path, "/"); 584 local->path = util_concat_path(res->path, "/");
584 local->last_modified = 0; 585 local->last_modified = 0;
585 ucx_map_cstr_put(db->resources, local->path, local); 586 ucx_map_cstr_put(db->resources, local->path, local);
586 } 587 }
588
589 sync_store_tags(dir, local_path, local, res);
587 } 590 }
588 } else { 591 } else {
589 if(!tmp_path) { 592 if(!tmp_path) {
590 fprintf(stderr, "Cannot create tmp path for %s\n", local_path); 593 fprintf(stderr, "Cannot create tmp path for %s\n", local_path);
591 free(local_path); 594 free(local_path);
601 printf("get: %s\n", res->path); 604 printf("get: %s\n", res->path);
602 if(dav_get_content(res, out, (dav_write_func)fwrite)) { 605 if(dav_get_content(res, out, (dav_write_func)fwrite)) {
603 ret = -1; 606 ret = -1;
604 } 607 }
605 fclose(out); 608 fclose(out);
609
610 sync_store_tags(dir, tmp_path, local, res);
606 611
607 if(ret == 0) { 612 if(ret == 0) {
608 (*counter)++; 613 (*counter)++;
609 614
610 if(dir->trash && dir->backuppull) { 615 if(dir->trash && dir->backuppull) {
1232 } 1237 }
1233 1238
1234 1239
1235 int sync_set_status(DavResource *res, char *status) { 1240 int sync_set_status(DavResource *res, char *status) {
1236 DavResource *resource = dav_resource_new(res->session, res->path); 1241 DavResource *resource = dav_resource_new(res->session, res->path);
1237 dav_set_property(resource, "idav:status", status); 1242 dav_set_string_property(resource, "idav:status", status);
1238 int ret = dav_store(resource); 1243 int ret = dav_store(resource);
1239 dav_resource_free(resource); 1244 dav_resource_free(resource);
1240 return ret; 1245 return ret;
1241 } 1246 }
1242 1247
1244 DavResource *resource = dav_resource_new(res->session, res->path); 1249 DavResource *resource = dav_resource_new(res->session, res->path);
1245 dav_remove_property(resource, "idav:status"); 1250 dav_remove_property(resource, "idav:status");
1246 int ret = dav_store(resource); 1251 int ret = dav_store(resource);
1247 dav_resource_free(resource); 1252 dav_resource_free(resource);
1248 return ret; 1253 return ret;
1254 }
1255
1256 int sync_store_tags(SyncDirectory *dir, const char *path, LocalResource *local, DavResource *res) {
1257 if(!dir->tagconfig) {
1258 return 0;
1259 }
1260
1261 UcxList *tags = NULL;
1262 if(dir->tagconfig) {
1263 DavXmlNode *tagsprop = dav_get_property_ns(res, DAV_NS, "tags");
1264 if(tagsprop) {
1265 tags = parse_dav_xml_taglist(tagsprop);
1266 }
1267 }
1268
1269 if(!tags) {
1270 return 0;
1271 }
1272
1273 int ret = 0;
1274 if(dir->tagconfig->store == TAG_STORE_XATTR) {
1275 UcxBuffer *data = NULL;
1276 switch(dir->tagconfig->local_format) {
1277 default: break;
1278 case TAG_FORMAT_TEXT: {
1279 data = create_text_taglist(tags);
1280 break;
1281 }
1282 case TAG_FORMAT_CSV: {
1283 data = create_csv_taglist(tags);
1284 break;
1285 }
1286 }
1287
1288 if(data) {
1289 ret = xattr_set(path, "tags", data->space, data->pos);
1290 ucx_buffer_free(data);
1291 } else {
1292 ret = -1;
1293 }
1294 }
1295
1296 // TODO: free stuff
1297
1298 return ret;
1299 }
1300
1301 UcxList* sync_get_file_tags(SyncDirectory *dir, LocalResource *res) {
1302 UcxList *tags = NULL;
1303
1304 if(!dir->tagconfig) {
1305 return NULL;
1306 }
1307 if(dir->tagconfig->store == TAG_STORE_XATTR) {
1308 ssize_t tag_length = 0;
1309 char *local_path = util_concat_path(dir->path, res->path);
1310 char* tag_data = xattr_get(local_path, "tags", &tag_length);
1311 free(local_path);
1312
1313 if(tag_length > 0) {
1314 switch(dir->tagconfig->local_format) {
1315 default: break;
1316 case TAG_FORMAT_TEXT: {
1317 tags = parse_text_taglist(tag_data, tag_length);
1318 break;
1319 }
1320 case TAG_FORMAT_CSV: {
1321 tags = parse_csv_taglist(tag_data, tag_length);
1322 break;
1323 }
1324 }
1325 }
1326 }
1327
1328 return tags;
1249 } 1329 }
1250 1330
1251 int sync_put_resource( 1331 int sync_put_resource(
1252 SyncDirectory *dir, 1332 SyncDirectory *dir,
1253 DavResource *res, 1333 DavResource *res,
1270 free(local_path); 1350 free(local_path);
1271 return -1; 1351 return -1;
1272 } 1352 }
1273 1353
1274 dav_set_content(res, in, (dav_read_func)fread); 1354 dav_set_content(res, in, (dav_read_func)fread);
1355
1356 if(dir->tagconfig) {
1357 UcxList *tags = sync_get_file_tags(dir, local);
1358 DavXmlNode *prop = create_xml_taglist(tags);
1359 if(prop) {
1360 dav_set_property_ns(res, DAV_NS, "tags", prop);
1361 }
1362 }
1275 1363
1276 int ret = -1; 1364 int ret = -1;
1277 int created = 0; 1365 int created = 0;
1278 for(int i=0;i<=dir->max_retry;i++) { 1366 for(int i=0;i<=dir->max_retry;i++) {
1279 if(!created && dav_create(res)) { 1367 if(!created && dav_create(res)) {

mercurial