89 ret = cmd_push(args); |
89 ret = cmd_push(args); |
90 } else if(!strcmp(cmd, "sync")) { |
90 } else if(!strcmp(cmd, "sync")) { |
91 ret = cmd_sync(args); |
91 ret = cmd_sync(args); |
92 } |
92 } |
93 |
93 |
|
94 // TODO: cleanup sync config (don't forget to call regfree for regex) |
|
95 |
94 return ret; |
96 return ret; |
95 } |
97 } |
96 |
98 |
97 void print_usage(char *cmd) { |
99 void print_usage(char *cmd) { |
98 fprintf(stderr, "Usage: %s command [options] arguments...\n\n", cmd); |
100 fprintf(stderr, "Usage: %s command [options] arguments...\n\n", cmd); |
102 fprintf(stderr, " push [-r] <directory>\n\n"); |
104 fprintf(stderr, " push [-r] <directory>\n\n"); |
103 |
105 |
104 fprintf(stderr, "Options:\n"); |
106 fprintf(stderr, "Options:\n"); |
105 fprintf(stderr, " -c Disable conflict detection\n"); |
107 fprintf(stderr, " -c Disable conflict detection\n"); |
106 fprintf(stderr, " -r Read changes from stdin\n\n"); |
108 fprintf(stderr, " -r Read changes from stdin\n\n"); |
|
109 } |
|
110 |
|
111 static int res_matches_filter(SyncDirectory *dir, char *res_path) { |
|
112 |
|
113 UCX_FOREACH(inc, dir->include) { |
|
114 regex_t* pattern = (regex_t*) inc->data; |
|
115 if (regexec(pattern, res_path, 0, NULL, 0)) { |
|
116 return 1; |
|
117 } |
|
118 } |
|
119 |
|
120 UCX_FOREACH(exc, dir->exclude) { |
|
121 regex_t* pattern = (regex_t*) exc->data; |
|
122 if (!regexec(pattern, res_path, 0, NULL, 0)) { |
|
123 return 1; |
|
124 } |
|
125 } |
|
126 |
|
127 return 0; |
107 } |
128 } |
108 |
129 |
109 int cmd_pull(CmdArgs *a) { |
130 int cmd_pull(CmdArgs *a) { |
110 if(a->argc != 1) { |
131 if(a->argc != 1) { |
111 fprintf(stderr, "Too %s arguments\n", a->argc < 1 ? "few" : "many"); |
132 fprintf(stderr, "Too %s arguments\n", a->argc < 1 ? "few" : "many"); |
162 UcxList *stack = ucx_list_prepend(NULL, ls->children); |
183 UcxList *stack = ucx_list_prepend(NULL, ls->children); |
163 while(stack) { |
184 while(stack) { |
164 DavResource *res = stack->data; |
185 DavResource *res = stack->data; |
165 stack = ucx_list_remove(stack, stack); |
186 stack = ucx_list_remove(stack, stack); |
166 |
187 |
167 while(res) { |
188 while(res) { |
|
189 if (res_matches_filter(dir, res->path)) { |
|
190 res = res->next; |
|
191 continue; |
|
192 } |
|
193 |
168 // download the resource |
194 // download the resource |
169 if(sync_get_resource(a, dir, res, db)) { |
195 if(sync_get_resource(a, dir, res, db)) { |
170 fprintf(stderr, "sync_get_resource failed for resource: %s\n", res->path); |
196 fprintf(stderr, "sync_get_resource failed for resource: %s\n", res->path); |
171 } |
197 } |
172 |
198 |
182 } |
208 } |
183 |
209 |
184 UcxMapIterator i = ucx_map_iterator(db->resources); |
210 UcxMapIterator i = ucx_map_iterator(db->resources); |
185 LocalResource *local; |
211 LocalResource *local; |
186 UCX_MAP_FOREACH(key, local, i) { |
212 UCX_MAP_FOREACH(key, local, i) { |
|
213 if (res_matches_filter(dir, local->path)) { |
|
214 continue; |
|
215 } |
187 sync_remove_resource(dir, local); |
216 sync_remove_resource(dir, local); |
188 } |
217 } |
189 ucx_map_free(db->resources); |
218 ucx_map_free(db->resources); |
190 db->resources = svrres; |
219 db->resources = svrres; |
191 |
220 |
192 // TODO: cleanup |
221 // TODO: cleanup - BUT DONT CLEANUP SYNC CONFIG (do this in main!) |
193 |
222 |
194 // store db |
223 // store db |
195 if(store_db(db, dir->database)) { |
224 if(store_db(db, dir->database)) { |
196 fprintf(stderr, "Cannot store sync db\n"); |
225 fprintf(stderr, "Cannot store sync db\n"); |
197 return -1; |
226 return -1; |
254 } |
283 } |
255 |
284 |
256 int ret = 0; |
285 int ret = 0; |
257 if(res->iscollection) { |
286 if(res->iscollection) { |
258 mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; |
287 mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; |
259 //printf("mkdir %s\n", local_path); |
|
260 if(util_mkdir(local_path, mode) && errno != EEXIST) { |
288 if(util_mkdir(local_path, mode) && errno != EEXIST) { |
261 ret = -1; |
289 ret = -1; |
262 } |
290 } |
263 } else { |
291 } else { |
264 FILE *out = fopen(local_path, "w"); |
292 FILE *out = fopen(local_path, "w"); |
393 } |
421 } |
394 dav_session_set_flags(sn, get_repository_flags(repo)); |
422 dav_session_set_flags(sn, get_repository_flags(repo)); |
395 sn->key = dav_context_get_key(ctx, repo->default_key); |
423 sn->key = dav_context_get_key(ctx, repo->default_key); |
396 |
424 |
397 // upload all changed files |
425 // upload all changed files |
398 //UcxList *resources = local_scan(dir, db); |
|
399 //UcxList *resources = read_changes(dir, db); |
|
400 UcxList *resources = cmd_getoption(a, "read") ? |
426 UcxList *resources = cmd_getoption(a, "read") ? |
401 read_changes(dir, db) : local_scan(dir, db); |
427 read_changes(dir, db) : local_scan(dir, db); |
402 |
428 |
403 UCX_FOREACH(elm, resources) { |
429 UCX_FOREACH(elm, resources) { |
404 LocalResource *local_res = elm->data; |
430 LocalResource *local_res = elm->data; |
405 printf("put: %s\n", local_res->path); |
431 if (!res_matches_filter(dir, local_res->path+1)) { |
406 DavResource *res = dav_resource_new(sn, local_res->path); |
432 printf("put: %s\n", local_res->path); |
407 if(!sync_put_resource(dir, res, db)) { |
|
408 ucx_map_cstr_put(db->resources, local_res->path, local_res); |
433 ucx_map_cstr_put(db->resources, local_res->path, local_res); |
409 } |
434 DavResource *res = dav_resource_new(sn, local_res->path); |
410 dav_resource_free(res); |
435 if(sync_put_resource(dir, res, db)) { |
|
436 ucx_map_cstr_remove(db->resources, local_res->path); |
|
437 } |
|
438 dav_resource_free(res); |
|
439 } |
411 } |
440 } |
412 ucx_list_free(resources); |
441 ucx_list_free(resources); |
413 |
442 |
414 // delete all removed files |
443 // delete all removed files |
415 UcxMapIterator i = ucx_map_iterator(db->remove); |
444 UcxMapIterator i = ucx_map_iterator(db->remove); |
517 LocalResource *res = path_to_local_resource(dir, db, value.ptr, &isdir); |
546 LocalResource *res = path_to_local_resource(dir, db, value.ptr, &isdir); |
518 if(res) { |
547 if(res) { |
519 resources = ucx_list_append(resources, res); |
548 resources = ucx_list_append(resources, res); |
520 } |
549 } |
521 } else if(!sstrcmp(name, S("remove"))) { |
550 } else if(!sstrcmp(name, S("remove"))) { |
522 int isdir; |
|
523 //LocalResource *res = path_to_local_resource(dir, db, value.ptr, &isdir); |
|
524 LocalResource *res = calloc(1, sizeof(LocalResource)); |
551 LocalResource *res = calloc(1, sizeof(LocalResource)); |
525 res->path = sstrdup(value).ptr; |
552 res->path = sstrdup(value).ptr; |
526 if(res) { |
553 if(res) { |
527 ucx_map_sstr_put(db->remove, value, res); |
554 ucx_map_sstr_put(db->remove, value, res); |
528 ucx_map_sstr_remove(db->resources, value); |
555 ucx_map_sstr_remove(db->resources, value); |
537 |
564 |
538 return resources; |
565 return resources; |
539 } |
566 } |
540 |
567 |
541 LocalResource* path_to_local_resource(SyncDirectory *dir, SyncDatabase *db, char *path, int *isdir) { |
568 LocalResource* path_to_local_resource(SyncDirectory *dir, SyncDatabase *db, char *path, int *isdir) { |
|
569 |
542 char *file_path = util_concat_path(dir->path, path); |
570 char *file_path = util_concat_path(dir->path, path); |
543 struct stat s; |
571 struct stat s; |
544 if(stat(file_path, &s)) { |
572 if(stat(file_path, &s)) { |
545 fprintf(stderr, "Cannot stat file %s\n", file_path); |
573 fprintf(stderr, "Cannot stat file %s\n", file_path); |
546 free(file_path); |
574 free(file_path); |
564 // update db entries |
592 // update db entries |
565 res->size = s.st_size; |
593 res->size = s.st_size; |
566 res->last_modified = s.st_mtime; |
594 res->last_modified = s.st_mtime; |
567 |
595 |
568 return res; |
596 return res; |
569 } |
597 } |
570 } else { |
598 } else { |
571 LocalResource *res = calloc(1, sizeof(LocalResource)); |
599 LocalResource *res = calloc(1, sizeof(LocalResource)); |
572 res->path = strdup(path); |
600 res->path = strdup(path); |
573 res->etag = NULL; |
601 res->etag = NULL; |
574 res->last_modified = s.st_mtime; |
602 res->last_modified = s.st_mtime; |
575 res->size = s.st_size; |
603 res->size = s.st_size; |
576 //ucx_map_cstr_put(db->resources, res->path, res); |
|
577 return res; |
604 return res; |
578 } |
605 } |
579 } else { |
606 } else { |
580 *isdir = 1; |
607 *isdir = 1; |
581 } |
608 } |