256 } |
256 } |
257 return 1; |
257 return 1; |
258 } |
258 } |
259 |
259 |
260 static int res_matches_tags(DavResource *res, SyncTagFilter *tagfilter) { |
260 static int res_matches_tags(DavResource *res, SyncTagFilter *tagfilter) { |
261 if(!tagfilter) { |
261 if(!tagfilter || tagfilter->mode == DAV_SYNC_TAGFILTER_OFF) { |
262 return 1; |
|
263 } |
|
264 |
|
265 if(tagfilter->mode == DAV_SYNC_TAGFILTER_OFF) { |
|
266 return 1; |
262 return 1; |
267 } |
263 } |
268 |
264 |
269 DavXmlNode *tagsprop = dav_get_property_ns(res, DAV_NS, "tags"); |
265 DavXmlNode *tagsprop = dav_get_property_ns(res, DAV_NS, "tags"); |
270 UcxList *res_tags = parse_dav_xml_taglist(tagsprop); |
266 UcxList *res_tags = parse_dav_xml_taglist(tagsprop); |
275 ucx_list_free(res_tags); |
271 ucx_list_free(res_tags); |
276 |
272 |
277 return ret; |
273 return ret; |
278 } |
274 } |
279 |
275 |
280 static int localres_matches_tags(LocalResource *res, SyncTagFilter *tagfilter) { |
276 static int localres_matches_tags( |
281 if(!tagfilter) { |
277 SyncDirectory *dir, |
|
278 LocalResource *res, |
|
279 SyncTagFilter *tagfilter) |
|
280 { |
|
281 if(!tagfilter || tagfilter->mode == DAV_SYNC_TAGFILTER_OFF) { |
282 return 1; |
282 return 1; |
283 } |
283 } |
284 |
284 |
285 // TODO: implement |
285 DavBool changed = 0; |
286 return 1; |
286 UcxList *res_tags = sync_get_file_tags(dir, res, &changed); |
|
287 |
|
288 int ret = matches_tagfilter(res_tags, tagfilter); |
|
289 UCX_FOREACH(elm, res_tags) { |
|
290 DavTag *t = elm->data; |
|
291 free_dav_tag(t); |
|
292 } |
|
293 ucx_list_free(res_tags); |
|
294 return ret; |
287 } |
295 } |
288 |
296 |
289 static DavSession* create_session(DavContext *ctx, Repository *repo, char *url) { |
297 static DavSession* create_session(DavContext *ctx, Repository *repo, char *url) { |
290 DavSession *sn = dav_session_new_auth( |
298 DavSession *sn = dav_session_new_auth( |
291 ctx, |
299 ctx, |
907 if(a->argc != 1) { |
915 if(a->argc != 1) { |
908 fprintf(stderr, "Too %s arguments\n", a->argc < 1 ? "few" : "many"); |
916 fprintf(stderr, "Too %s arguments\n", a->argc < 1 ? "few" : "many"); |
909 return -1; |
917 return -1; |
910 } |
918 } |
911 |
919 |
|
920 // if there are syntax errors in the command line, fail asap. |
|
921 SyncTagFilter* tagfilter = parse_tagfilter_string(cmd_getoption(a, "tags")); |
|
922 if (!tagfilter) { |
|
923 fprintf(stderr, "Malformed tag filter\n"); |
|
924 return -1; |
|
925 } |
|
926 |
912 SyncDirectory *dir = scfg_get_dir(a->argv[0]); |
927 SyncDirectory *dir = scfg_get_dir(a->argv[0]); |
913 if(!dir) { |
928 if(!dir) { |
914 fprintf(stderr, "Unknown sync dir: %s\n", a->argv[0]); |
929 fprintf(stderr, "Unknown sync dir: %s\n", a->argv[0]); |
915 return -1; |
930 return -1; |
916 } |
931 } |
992 |
1009 |
993 UcxMap *lclres = ucx_map_new(db->resources->count); |
1010 UcxMap *lclres = ucx_map_new(db->resources->count); |
994 int ret = 0; |
1011 int ret = 0; |
995 UCX_FOREACH(elm, resources) { |
1012 UCX_FOREACH(elm, resources) { |
996 LocalResource *local_res = elm->data; |
1013 LocalResource *local_res = elm->data; |
997 if (!res_matches_filter(dir, local_res->path+1)) { |
1014 int error = 0; |
|
1015 |
|
1016 if ( res_matches_filter(dir, local_res->path+1) |
|
1017 || !localres_matches_tags(dir, local_res, dir->tagfilter)) |
|
1018 { |
|
1019 local_res->keep = TRUE; |
|
1020 } else if (!localres_matches_tags(dir, local_res, tagfilter)) { |
|
1021 if(!remove_file) { |
|
1022 local_res->keep = TRUE; |
|
1023 } |
|
1024 } else { |
998 if(sync_shutdown) { |
1025 if(sync_shutdown) { |
999 LocalResource *lr = ucx_map_cstr_remove(db->resources, local_res->path); |
1026 LocalResource *lr = ucx_map_cstr_remove(db->resources, local_res->path); |
1000 if(lr) { |
1027 if(lr) { |
1001 local_res->size = lr->size; |
1028 local_res->size = lr->size; |
1002 local_res->last_modified = lr->last_modified; |
1029 local_res->last_modified = lr->last_modified; |
1014 sync_skipped++; |
1041 sync_skipped++; |
1015 continue; |
1042 continue; |
1016 } |
1043 } |
1017 |
1044 |
1018 // upload every changed file |
1045 // upload every changed file |
1019 int error = 0; |
|
1020 int is_changed = local_resource_is_changed(dir, db, local_res); |
1046 int is_changed = local_resource_is_changed(dir, db, local_res); |
1021 if (is_changed || local_res->tags_updated) { |
1047 if (is_changed || local_res->tags_updated) { |
1022 DavResource *res = dav_resource_new(sn, local_res->path); |
1048 DavResource *res = dav_resource_new(sn, local_res->path); |
1023 if(!res) { |
1049 if(!res) { |
1024 print_resource_error(sn, local_res->path); |
1050 print_resource_error(sn, local_res->path); |
1076 } |
1102 } |
1077 } |
1103 } |
1078 } |
1104 } |
1079 dav_resource_free(res); |
1105 dav_resource_free(res); |
1080 } |
1106 } |
1081 |
1107 } |
1082 // remove every locally available resource from db->resource |
1108 |
1083 // the remaining elements are all deleted files |
1109 // remove every locally available resource from db->resource |
1084 elm->data = NULL; |
1110 // the remaining elements are all deleted files |
1085 if(!error) { |
1111 elm->data = NULL; |
1086 ucx_map_cstr_put(lclres, local_res->path, local_res); |
1112 if(!error) { |
1087 } |
1113 ucx_map_cstr_put(lclres, local_res->path, local_res); |
1088 |
1114 } |
1089 LocalResource *lr = ucx_map_cstr_remove(db->resources, local_res->path); |
1115 |
1090 if(lr) { |
1116 LocalResource *lr = ucx_map_cstr_remove(db->resources, local_res->path); |
1091 local_resource_free(lr); |
1117 if(lr) { |
1092 } |
1118 local_resource_free(lr); |
1093 } |
1119 } |
1094 } |
1120 } |
1095 |
1121 |
1096 // delete all removed files |
1122 // delete all removed files |
1097 if(ret == 0 && !archive) { |
1123 if(ret == 0 && !archive) { |
1098 UcxMapIterator i = ucx_map_iterator(db->resources); |
1124 UcxMapIterator i = ucx_map_iterator(db->resources); |
1099 LocalResource *local; |
1125 LocalResource *local; |
1100 UCX_MAP_FOREACH(key, local, i) { |
1126 UCX_MAP_FOREACH(key, local, i) { |
1101 if (!res_matches_filter(dir, local->path+1)) { |
1127 if (!local->keep) { |
1102 if(sync_shutdown) { |
1128 if(sync_shutdown) { |
1103 ucx_map_cstr_put(lclres, local->path, local_resource_copy(local)); |
1129 ucx_map_cstr_put(lclres, local->path, local_resource_copy(local)); |
1104 } else if(sync_delete_remote_resource(sn, local, &sync_delete)) { |
1130 } else if(sync_delete_remote_resource(sn, local, &sync_delete)) { |
1105 ucx_map_cstr_put(lclres, local->path, local_resource_copy(local)); |
1131 ucx_map_cstr_put(lclres, local->path, local_resource_copy(local)); |
1106 if(sn->error != DAV_NOT_FOUND) { |
1132 if(sn->error != DAV_NOT_FOUND) { |