3234 ret = 1; |
3234 ret = 1; |
3235 } |
3235 } |
3236 } |
3236 } |
3237 } |
3237 } |
3238 |
3238 |
3239 DavXmlNode *xattr_prop = dav_get_property_ns(res, DAV_PROPS_NS, "xattributes"); |
3239 if((dir->metadata & FINFO_XATTR) == FINFO_XATTR) { |
3240 if(xattr_prop) { |
3240 DavXmlNode *xattr_prop = dav_get_property_ns(res, DAV_PROPS_NS, "xattributes"); |
3241 XAttributes *xattr = xml_get_attributes(xattr_prop); |
3241 XAttributes *xattr = NULL; |
3242 if(xattr) { |
3242 if(xattr_prop) { |
3243 if(!sync_store_xattr(dir, path, xattr)) { |
3243 xattr = xml_get_attributes(xattr_prop); |
3244 if(local->xattr_hash) { |
3244 } |
3245 free(local->xattr_hash); |
3245 if(!sync_store_xattr(dir, path, xattr)) { |
3246 } |
3246 if(local->xattr_hash) { |
3247 local->xattr_hash = xattr->hash; |
3247 free(local->xattr_hash); |
3248 } |
3248 } |
|
3249 local->xattr_hash = xattr ? xattr->hash : NULL; |
3249 } |
3250 } |
3250 } |
3251 } |
3251 |
3252 |
3252 if(sync_store_tags(dir, path, local, res)) { |
3253 if(sync_store_tags(dir, path, local, res)) { |
3253 ret = 1; |
3254 ret = 1; |
3255 |
3256 |
3256 return ret; |
3257 return ret; |
3257 } |
3258 } |
3258 |
3259 |
3259 int sync_store_xattr(SyncDirectory *dir, const char *path, XAttributes *xattr) { |
3260 int sync_store_xattr(SyncDirectory *dir, const char *path, XAttributes *xattr) { |
3260 for(int i=0;i<xattr->nattr;i++) { |
3261 // create a map of all currently available local attributes |
|
3262 ssize_t nelm = 0; |
|
3263 char **list = xattr_list(path, &nelm); |
|
3264 UcxMap *current_xattr = NULL; |
|
3265 if(nelm > 0) { |
|
3266 current_xattr = ucx_map_new(nelm + 8); |
|
3267 for(int i=0;i<nelm;i++) { |
|
3268 // use the xattr name as key and store any value |
|
3269 ucx_map_cstr_put(current_xattr, list[i], list[i]); |
|
3270 } |
|
3271 } |
|
3272 if(list) { |
|
3273 free(list); |
|
3274 } |
|
3275 |
|
3276 // store extended attributes |
|
3277 size_t nattr = xattr ? xattr->nattr : 0; |
|
3278 for(int i=0;i<nattr;i++) { |
3261 sstr_t value = xattr->values[i]; |
3279 sstr_t value = xattr->values[i]; |
3262 if(xattr_set(path, xattr->names[i], value.ptr, value.length)) { |
3280 if(xattr_set(path, xattr->names[i], value.ptr, value.length)) { |
3263 fprintf( |
3281 fprintf(stderr, |
3264 stderr, |
|
3265 "Cannot store xattr '%s' for file: %s\n", |
3282 "Cannot store xattr '%s' for file: %s\n", |
3266 xattr->names[i], |
3283 xattr->names[i], |
3267 path); |
3284 path); |
3268 } |
3285 } |
3269 } |
3286 |
|
3287 if(current_xattr) { |
|
3288 // to detect which xattributes are removed, we remove all new |
|
3289 // attributes from the map and all remaining attributes must |
|
3290 // be removed with xattr_remove |
|
3291 char *value = ucx_map_cstr_remove(current_xattr, xattr->names[i]); |
|
3292 if(value) { |
|
3293 free(value); |
|
3294 } |
|
3295 } |
|
3296 } |
|
3297 |
|
3298 if(current_xattr) { |
|
3299 UcxMapIterator i = ucx_map_iterator(current_xattr); |
|
3300 char *value = NULL; |
|
3301 UCX_MAP_FOREACH(key, value, i) { |
|
3302 (void)xattr_remove(path, value); // don't print error |
|
3303 free(value); |
|
3304 } |
|
3305 ucx_map_free(current_xattr); |
|
3306 } |
|
3307 |
3270 return 0; |
3308 return 0; |
3271 } |
3309 } |
3272 |
3310 |
3273 int sync_store_tags(SyncDirectory *dir, const char *path, LocalResource *local, DavResource *res) { |
3311 int sync_store_tags(SyncDirectory *dir, const char *path, LocalResource *local, DavResource *res) { |
3274 if(!dir->tagconfig) { |
3312 if(!dir->tagconfig) { |
3626 } |
3664 } |
3627 return 0; |
3665 return 0; |
3628 } |
3666 } |
3629 |
3667 |
3630 static void update_metadata_hashes(LocalResource *local, MetadataHashes hashes) { |
3668 static void update_metadata_hashes(LocalResource *local, MetadataHashes hashes) { |
3631 if(hashes.tags) { |
3669 if(hashes.update_tags) { |
3632 if(local->tags_hash) { |
3670 if(local->tags_hash) { |
3633 free(local->tags_hash); |
3671 free(local->tags_hash); |
3634 local->tags_hash = NULL; |
3672 local->tags_hash = NULL; |
3635 } |
3673 } |
3636 local->tags_hash = hashes.tags; |
3674 local->tags_hash = hashes.tags; |
3637 } |
3675 } |
3638 if(hashes.tags_remote) { |
3676 if(hashes.update_tags_remote) { |
3639 if(local->remote_tags_hash) { |
3677 if(local->remote_tags_hash) { |
3640 free(local->remote_tags_hash); |
3678 free(local->remote_tags_hash); |
3641 } |
3679 } |
3642 local->remote_tags_hash = hashes.tags_remote; |
3680 local->remote_tags_hash = hashes.tags_remote; |
3643 } |
3681 } |
3644 if(hashes.xattr) { |
3682 if(hashes.update_xattr) { |
3645 if(local->xattr_hash) { |
3683 if(local->xattr_hash) { |
3646 free(local->xattr_hash); |
3684 free(local->xattr_hash); |
3647 } |
3685 } |
3648 local->xattr_hash = hashes.xattr; |
3686 local->xattr_hash = hashes.xattr; |
3649 } |
3687 } |
4194 SyncDirectory *dir, |
4232 SyncDirectory *dir, |
4195 DavSession *sn, |
4233 DavSession *sn, |
4196 DavResource *res, |
4234 DavResource *res, |
4197 LocalResource *local) |
4235 LocalResource *local) |
4198 { |
4236 { |
4199 MetadataHashes hashes = {NULL, NULL, NULL}; |
4237 MetadataHashes hashes = {NULL, NULL, NULL, 0, 0, 0}; |
4200 if(dir->tagconfig) { |
4238 if(dir->tagconfig) { |
4201 // get local tags |
4239 // get local tags |
4202 DavBool changed = 0; |
4240 DavBool changed = 0; |
4203 char *tags_hash = NULL; |
4241 char *tags_hash = NULL; |
4204 UcxList *tags = sync_get_file_tags(dir, local, &changed, &tags_hash); |
4242 UcxList *tags = sync_get_file_tags(dir, local, &changed, &tags_hash); |
4205 if(changed || local->tags_updated) { |
4243 if(changed || local->tags_updated) { |
4206 hashes.tags = tags_hash; |
4244 hashes.tags = tags_hash; |
|
4245 hashes.update_tags = 1; |
4207 |
4246 |
4208 DavBool store_tags = TRUE; |
4247 DavBool store_tags = TRUE; |
4209 // get remote tags |
4248 // get remote tags |
4210 UcxList *remote_tags = NULL; |
4249 UcxList *remote_tags = NULL; |
4211 DavXmlNode *tagsprop = dav_get_property_ns(res, DAV_PROPS_NS, "tags"); |
4250 DavXmlNode *tagsprop = dav_get_property_ns(res, DAV_PROPS_NS, "tags"); |
4266 } |
4305 } |
4267 |
4306 |
4268 if(local->xattr_updated) { |
4307 if(local->xattr_updated) { |
4269 if(local->xattr) { |
4308 if(local->xattr) { |
4270 resource_set_xattr(res, local->xattr); |
4309 resource_set_xattr(res, local->xattr); |
4271 hashes.xattr = strdup(local->xattr->hash); |
4310 hashes.xattr = local->xattr ? strdup(local->xattr->hash) : NULL; |
|
4311 hashes.update_xattr = 1; |
4272 } else { |
4312 } else { |
4273 dav_remove_property(res, "idavprops:xattributes"); |
4313 dav_remove_property(res, "idavprops:xattributes"); |
|
4314 if(local->xattr_hash) { |
|
4315 free(local->xattr_hash); |
|
4316 local->xattr_hash = NULL; |
|
4317 } |
4274 } |
4318 } |
4275 } |
4319 } |
4276 return hashes; |
4320 return hashes; |
4277 } |
4321 } |
4278 |
4322 |