dav/sync.c

changeset 379
cdaf5a3d3a50
parent 378
d64ecd8d6969
child 380
8a0c727aa409
equal deleted inserted replaced
378:d64ecd8d6969 379:cdaf5a3d3a50
175 fprintf(stderr, " trash-info <directory>\n"); 175 fprintf(stderr, " trash-info <directory>\n");
176 fprintf(stderr, " empty-trash <directory>\n"); 176 fprintf(stderr, " empty-trash <directory>\n");
177 fprintf(stderr, " add-tag [-s <syncdir>] <file> <tag>\n"); 177 fprintf(stderr, " add-tag [-s <syncdir>] <file> <tag>\n");
178 fprintf(stderr, " remove-tag [-s <syncdir>] <file> <tag>\n"); 178 fprintf(stderr, " remove-tag [-s <syncdir>] <file> <tag>\n");
179 fprintf(stderr, " update-tags [-s <syncdir>] <file> [tags]\n"); 179 fprintf(stderr, " update-tags [-s <syncdir>] <file> [tags]\n");
180 fprintf(stderr, " update-tags [-s <syncdir>] <file>\n\n"); 180 fprintf(stderr, " list-tags [-s <syncdir>] <file>\n\n");
181 181
182 fprintf(stderr, "Options:\n"); 182 fprintf(stderr, "Options:\n");
183 fprintf(stderr, " -c Disable conflict detection\n"); 183 fprintf(stderr, " -c Disable conflict detection\n");
184 fprintf(stderr, " -l Lock the repository before access\n"); 184 fprintf(stderr, " -l Lock the repository before access\n");
185 fprintf(stderr, " -d Don't lock the repository\n"); 185 fprintf(stderr, " -d Don't lock the repository\n");
1350 ucx_map_free(tag_map); 1350 ucx_map_free(tag_map);
1351 1351
1352 return new_tags; 1352 return new_tags;
1353 } 1353 }
1354 1354
1355 int sync_tags_equal(UcxList *tags1, UcxList *tags2) {
1356 if(!tags1) {
1357 return tags2 ? 0 : 1;
1358 }
1359 if(!tags2) {
1360 return tags1 ? 0 : 1;
1361 }
1362
1363 UcxMap *map1 = ucx_map_new(32);
1364 UCX_FOREACH(elm, tags1) {
1365 DavTag *t = elm->data;
1366 ucx_map_cstr_put(map1, t->name, t);
1367 }
1368
1369 int equal = 1;
1370 int i = 0;
1371 UCX_FOREACH(elm, tags2) {
1372 DavTag *t = elm->data;
1373 if(!ucx_map_cstr_get(map1, t->name)) {
1374 equal = 0;
1375 break;
1376 }
1377 i++;
1378 }
1379
1380 if(i != map1->count) {
1381 equal = 0;
1382 }
1383 ucx_map_free(map1);
1384 return equal;
1385 }
1386
1355 int sync_store_tags(SyncDirectory *dir, const char *path, LocalResource *local, DavResource *res) { 1387 int sync_store_tags(SyncDirectory *dir, const char *path, LocalResource *local, DavResource *res) {
1356 if(!dir->tagconfig) { 1388 if(!dir->tagconfig) {
1357 return 0; 1389 return 0;
1358 } 1390 }
1359 1391
1364 tags = parse_dav_xml_taglist(tagsprop); 1396 tags = parse_dav_xml_taglist(tagsprop);
1365 1397
1366 } 1398 }
1367 } 1399 }
1368 1400
1369 DavBool store_empty_tags = FALSE; 1401 DavBool store_tags = FALSE;
1370 if(dir->tagconfig->conflict != TAG_NO_CONFLICT) { 1402 DavBool tags_changed = FALSE;
1371 DavBool tags_changed = FALSE; 1403 UcxList *local_tags = sync_get_file_tags(dir, local, &tags_changed);
1372 UcxList *local_tags = sync_get_file_tags(dir, local, &tags_changed); 1404 if(tags_changed) {
1373 if(tags_changed) { 1405 switch(dir->tagconfig->conflict) {
1374 switch(dir->tagconfig->conflict) { 1406 case TAG_NO_CONFLICT:
1375 case TAG_NO_CONFLICT: 1407 case TAG_KEEP_LOCAL: {
1376 case TAG_KEEP_LOCAL: { 1408 store_tags = FALSE;
1377 store_empty_tags = TRUE; 1409 break;
1378 tags = local_tags; 1410 }
1379 // TODO: free tags 1411 case TAG_KEEP_REMOTE: {
1380 break; 1412 store_tags = TRUE;
1381 } 1413 local->tags_updated = FALSE;
1382 case TAG_KEEP_REMOTE: break; 1414 }
1383 case TAG_MERGE: { 1415 case TAG_MERGE: {
1384 UcxList *new_tags = sync_merge_tags(local_tags, tags); 1416 UcxList *new_tags = sync_merge_tags(local_tags, tags);
1385 // TODO: free tags and local_tags 1417 // TODO: free tags and local_tags
1386 tags = new_tags; 1418 tags = new_tags;
1387 store_empty_tags = TRUE; 1419 store_tags = TRUE;
1388 // make sure the merged tags will be pushed the next time 1420 // make sure the merged tags will be pushed the next time
1389 local->tags_updated = TRUE; 1421 local->tags_updated = TRUE;
1390 break; 1422 break;
1391 } 1423 }
1392 } 1424 }
1393 } else { 1425 } else {
1394 // TODO: free local_tags 1426 if(!sync_tags_equal(tags, local_tags)) {
1395 } 1427 store_tags = TRUE;
1396 } 1428 }
1397 1429 // TODO: free local_tags
1398 if(!tags && !store_empty_tags) { 1430 }
1431
1432 if(!store_tags) {
1399 return 0; 1433 return 0;
1400 } 1434 }
1401 1435
1402 int ret = sync_store_tags_local(dir, local, path, tags); 1436 int ret = sync_store_tags_local(dir, local, path, tags);
1403 1437
1431 char *data_hash = dav_create_hash(data->space, data->size); 1465 char *data_hash = dav_create_hash(data->space, data->size);
1432 int update = 1; 1466 int update = 1;
1433 if(local) { 1467 if(local) {
1434 if(!local->tags_hash || strcmp(data_hash, local->tags_hash)) { 1468 if(!local->tags_hash || strcmp(data_hash, local->tags_hash)) {
1435 printf("update: %s\n", local->path); 1469 printf("update: %s\n", local->path);
1436 // TODO: update hash in localres??
1437 } else { 1470 } else {
1438 update = 0; 1471 update = 0;
1439 } 1472 }
1440 } 1473 }
1441 if(update) { 1474 if(update) {
1442 ret = xattr_set(path, dir->tagconfig->xattr_name, data->space, data->pos); 1475 ret = xattr_set(path, dir->tagconfig->xattr_name, data->space, data->pos);
1476 if(local) {
1477 if(local->tags_hash) {
1478 free(local->tags_hash);
1479 }
1480 local->tags_hash = data_hash;
1481 }
1482 } else {
1483 free(data_hash);
1443 } 1484 }
1444 ucx_buffer_free(data); 1485 ucx_buffer_free(data);
1445 } else { 1486 } else {
1446 ret = -1; 1487 ret = -1;
1447 } 1488 }
1448 } else { 1489 } else {
1449 // TODO: delete xattr 1490 if(local) {
1450 //ret = xattr_remove(path, dir->tagconfig->xattr_name); 1491 printf("update: %s\n", local->path);
1492 }
1493 ret = xattr_remove(path, dir->tagconfig->xattr_name);
1451 } 1494 }
1452 } 1495 }
1453 1496
1454 return ret; 1497 return ret;
1455 } 1498 }
1489 return NULL; 1532 return NULL;
1490 } 1533 }
1491 1534
1492 if(!dir->tagconfig) { 1535 if(!dir->tagconfig) {
1493 return NULL; 1536 return NULL;
1537 }
1538 if(changed && res->tags_updated) {
1539 *changed = TRUE;
1494 } 1540 }
1495 if(dir->tagconfig->store == TAG_STORE_XATTR) { 1541 if(dir->tagconfig->store == TAG_STORE_XATTR) {
1496 UcxBuffer *tag_buf = res->cached_tags ? 1542 UcxBuffer *tag_buf = res->cached_tags ?
1497 res->cached_tags : 1543 res->cached_tags :
1498 sync_get_file_tag_data(dir, res); 1544 sync_get_file_tag_data(dir, res);
2178 if(sync_store_tags_local(file.dir, NULL, path, tags)) { 2224 if(sync_store_tags_local(file.dir, NULL, path, tags)) {
2179 fprintf(stderr, "Cannot store tags\n"); 2225 fprintf(stderr, "Cannot store tags\n");
2180 } 2226 }
2181 if(localres) { 2227 if(localres) {
2182 localres->tags_updated = TRUE; 2228 localres->tags_updated = TRUE;
2229 if(!tags) {
2230 if(localres->tags_hash) {
2231 free(localres->tags_hash);
2232 }
2233 localres->tags_hash = NULL;
2234 }
2183 } 2235 }
2184 } 2236 }
2185 2237
2186 // store db 2238 // store db
2187 if(store_db(db, file.dir->database)) { 2239 if(store_db(db, file.dir->database)) {

mercurial