dav/sync.c

changeset 368
11797f33bc24
parent 367
4a6a59f89f9f
child 369
4322b8953bd5
equal deleted inserted replaced
367:4a6a59f89f9f 368:11797f33bc24
972 } 972 }
973 973
974 if(dir->tagconfig && local_res->tags_updated && !abort) { 974 if(dir->tagconfig && local_res->tags_updated && !abort) {
975 // get tags from tagstore (xattr or something else) 975 // get tags from tagstore (xattr or something else)
976 // and store it in resource property 976 // and store it in resource property
977 UcxList *tags = sync_get_file_tags(dir, local_res); 977 UcxList *tags = sync_get_file_tags(dir, local_res, NULL);
978 DavXmlNode *prop = create_xml_taglist(tags); 978 DavXmlNode *prop = create_xml_taglist(tags);
979 if(prop) { 979 if(prop) {
980 dav_set_property_ns(res, DAV_NS, "tags", prop); 980 dav_set_property_ns(res, DAV_NS, "tags", prop);
981 printf("update: %s\n", local_res->path); 981 printf("update: %s\n", local_res->path);
982 if(dav_store(res)) { 982 if(dav_store(res)) {
1246 res->tags_updated = db_res->tags_updated; 1246 res->tags_updated = db_res->tags_updated;
1247 if(db_res->etag) { 1247 if(db_res->etag) {
1248 res->etag = strdup(db_res->etag); 1248 res->etag = strdup(db_res->etag);
1249 } 1249 }
1250 1250
1251 if(dir->tagconfig && dir->tagconfig->scan && !res->tags_updated) { 1251 if(dir->tagconfig && dir->tagconfig->detect_changes && !res->tags_updated) {
1252 UcxBuffer *tags = sync_get_file_tag_data(dir, res); 1252 UcxBuffer *tags = sync_get_file_tag_data(dir, res);
1253 if(tags) { 1253 if(tags) {
1254 if(db_res->tags_hash) { 1254 if(db_res->tags_hash) {
1255 char *hash = dav_create_hash(tags->space, tags->size); 1255 char *hash = dav_create_hash(tags->space, tags->size);
1256 if(strcmp(hash, db_res->tags_hash)) { 1256 if(strcmp(hash, db_res->tags_hash)) {
1328 if(tagsprop) { 1328 if(tagsprop) {
1329 tags = parse_dav_xml_taglist(tagsprop); 1329 tags = parse_dav_xml_taglist(tagsprop);
1330 } 1330 }
1331 } 1331 }
1332 1332
1333 if(!tags) { 1333 DavBool store_empty_tags = FALSE;
1334 if(dir->tagconfig->conflict != TAG_NO_CONFLICT) {
1335 DavBool tags_changed = FALSE;
1336 UcxList *local_tags = sync_get_file_tags(dir, local, &tags_changed);
1337 if(tags_changed) {
1338 switch(dir->tagconfig->conflict) {
1339 case TAG_KEEP_LOCAL: {
1340 store_empty_tags = TRUE;
1341 tags = local_tags;
1342 // TODO: free tags
1343 break;
1344 }
1345 case TAG_KEEP_REMOTE: break;
1346 case TAG_MERGE: {
1347 // this map is used to check the existence of tags
1348 UcxMap *tag_map = ucx_map_new(32);
1349 // merged taglist
1350 UcxList *new_tags = NULL;
1351
1352 // add all local tags
1353 UCX_FOREACH(elm, local_tags) {
1354 DavTag *t = elm->data;
1355 ucx_map_cstr_put(tag_map, t->name, t);
1356 DavTag *newt = calloc(1, sizeof(DavTag));
1357 newt->color = t->color ? strdup(t->color) : NULL;
1358 newt->name = strdup(t->name);
1359 new_tags = ucx_list_append(new_tags, newt);
1360 }
1361 // check if a remote tag is already in the map
1362 // and if not add it to the new taglist
1363 UCX_FOREACH(elm, tags) {
1364 DavTag *t = elm->data;
1365 if(!ucx_map_cstr_get(tag_map, t->name)) {
1366 DavTag *newt = calloc(1, sizeof(DavTag));
1367 newt->color = t->color ? strdup(t->color) : NULL;
1368 newt->name = strdup(t->name);
1369 new_tags = ucx_list_append(new_tags, newt);
1370 }
1371 }
1372
1373 ucx_map_free(tag_map);
1374 // TODO: free tags and local_tags
1375
1376 tags = new_tags;
1377
1378 store_empty_tags = TRUE;
1379
1380 break;
1381 }
1382 }
1383 } else {
1384 // TODO: free local_tags
1385 }
1386 }
1387
1388 if(!tags && !store_empty_tags) {
1334 return 0; 1389 return 0;
1335 } 1390 }
1336 1391
1337 int ret = 0; 1392 int ret = 0;
1338 if(dir->tagconfig->store == TAG_STORE_XATTR) { 1393 if(dir->tagconfig->store == TAG_STORE_XATTR) {
1339 UcxBuffer *data = NULL; 1394 UcxBuffer *data = NULL;
1340 switch(dir->tagconfig->local_format) { 1395 if(tags) {
1341 default: break; 1396 switch(dir->tagconfig->local_format) {
1342 case TAG_FORMAT_TEXT: { 1397 default: break;
1343 data = create_text_taglist(tags); 1398 case TAG_FORMAT_TEXT: {
1344 break; 1399 data = create_text_taglist(tags);
1345 } 1400 break;
1346 case TAG_FORMAT_CSV: { 1401 }
1347 data = create_csv_taglist(tags); 1402 case TAG_FORMAT_CSV: {
1348 break; 1403 data = create_csv_taglist(tags);
1349 } 1404 break;
1350 case TAG_FORMAT_MACOS: { 1405 }
1351 data = create_macos_taglist(tags); 1406 case TAG_FORMAT_MACOS: {
1352 break; 1407 data = create_macos_taglist(tags);
1353 } 1408 break;
1354 } 1409 }
1355 1410 }
1356 if(data) { 1411
1357 ret = xattr_set(path, "tags", data->space, data->pos); 1412 if(data) {
1358 ucx_buffer_free(data); 1413 ret = xattr_set(path, dir->tagconfig->xattr_name, data->space, data->pos);
1414 ucx_buffer_free(data);
1415 } else {
1416 ret = -1;
1417 }
1359 } else { 1418 } else {
1360 ret = -1; 1419 // TODO: relete xattr
1420 //ret = xattr_remove(path, dir->tagconfig->xattr_name);
1361 } 1421 }
1362 } 1422 }
1363 1423
1364 // TODO: free stuff 1424 // TODO: free stuff
1365 1425
1374 if(dir->tagconfig->store == TAG_STORE_XATTR) { 1434 if(dir->tagconfig->store == TAG_STORE_XATTR) {
1375 ssize_t tag_length = 0; 1435 ssize_t tag_length = 0;
1376 char *local_path = util_concat_path(dir->path, res->path); 1436 char *local_path = util_concat_path(dir->path, res->path);
1377 char* tag_data = xattr_get( 1437 char* tag_data = xattr_get(
1378 local_path, 1438 local_path,
1379 dir->tagconfig->local_format == TAG_FORMAT_MACOS ? MACOS_TAG_XATTR : "tags", 1439 dir->tagconfig->xattr_name,
1380 &tag_length); 1440 &tag_length);
1381 free(local_path); 1441 free(local_path);
1382 1442
1383 if(tag_length > 0) { 1443 if(tag_length > 0) {
1384 buf = ucx_buffer_new(tag_data, (size_t)tag_length, UCX_BUFFER_AUTOFREE); 1444 buf = ucx_buffer_new(tag_data, (size_t)tag_length, UCX_BUFFER_AUTOFREE);
1386 } 1446 }
1387 } 1447 }
1388 return buf; 1448 return buf;
1389 } 1449 }
1390 1450
1391 UcxList* sync_get_file_tags(SyncDirectory *dir, LocalResource *res) { 1451 UcxList* sync_get_file_tags(SyncDirectory *dir, LocalResource *res, DavBool *changed) {
1452 if(changed) *changed = FALSE;
1453
1392 UcxList *tags = NULL; 1454 UcxList *tags = NULL;
1393 1455
1394 if(!dir->tagconfig) { 1456 if(!dir->tagconfig) {
1395 return NULL; 1457 return NULL;
1396 } 1458 }
1398 UcxBuffer *tag_buf = res->cached_tags ? 1460 UcxBuffer *tag_buf = res->cached_tags ?
1399 res->cached_tags : 1461 res->cached_tags :
1400 sync_get_file_tag_data(dir, res); 1462 sync_get_file_tag_data(dir, res);
1401 1463
1402 if(tag_buf) { 1464 if(tag_buf) {
1403 res->tags_hash = dav_create_hash(tag_buf->space, tag_buf->size); 1465 char *newhash = dav_create_hash(tag_buf->space, tag_buf->size);
1466 if(res->tags_hash) {
1467 if(changed && strcmp(res->tags_hash, newhash)) {
1468 *changed = TRUE;
1469 }
1470 free(res->tags_hash);
1471 } else {
1472 if(changed) *changed = TRUE;
1473 }
1474 res->tags_hash = newhash;
1404 1475
1405 switch(dir->tagconfig->local_format) { 1476 switch(dir->tagconfig->local_format) {
1406 default: break; 1477 default: break;
1407 case TAG_FORMAT_TEXT: { 1478 case TAG_FORMAT_TEXT: {
1408 tags = parse_text_taglist(tag_buf->space, tag_buf->size); 1479 tags = parse_text_taglist(tag_buf->space, tag_buf->size);
1419 } 1490 }
1420 if(!res->cached_tags) { 1491 if(!res->cached_tags) {
1421 // we created the buffer therefore we destroy it 1492 // we created the buffer therefore we destroy it
1422 ucx_buffer_free(tag_buf); 1493 ucx_buffer_free(tag_buf);
1423 } 1494 }
1495 } else if(res->tags_hash) {
1496 if(changed) *changed = TRUE;
1424 } 1497 }
1425 } 1498 }
1426 1499
1427 return tags; 1500 return tags;
1428 } 1501 }
1451 } 1524 }
1452 1525
1453 dav_set_content(res, in, (dav_read_func)fread); 1526 dav_set_content(res, in, (dav_read_func)fread);
1454 1527
1455 if(dir->tagconfig) { 1528 if(dir->tagconfig) {
1456 UcxList *tags = sync_get_file_tags(dir, local); 1529 UcxList *tags = sync_get_file_tags(dir, local, NULL); // TODO: check remote tags
1457 DavXmlNode *prop = create_xml_taglist(tags); 1530 DavXmlNode *prop = create_xml_taglist(tags);
1458 if(prop) { 1531 if(prop) {
1459 dav_set_property_ns(res, DAV_NS, "tags", prop); 1532 dav_set_property_ns(res, DAV_NS, "tags", prop);
1460 } 1533 }
1461 } 1534 }

mercurial