521 |
522 |
522 // stat all files with unknown lastmodified date |
523 // stat all files with unknown lastmodified date |
523 UCX_FOREACH(elm, statls) { |
524 UCX_FOREACH(elm, statls) { |
524 LocalResource *l = elm->data; |
525 LocalResource *l = elm->data; |
525 char *local_path = util_concat_path(dir->path, l->path); |
526 char *local_path = util_concat_path(dir->path, l->path); |
526 struct stat s; |
527 SYS_STAT s; |
527 if(!stat(local_path, &s)) { |
528 if(!sys_stat(local_path, &s)) { |
528 l->last_modified = s.st_mtime; |
529 l->last_modified = s.st_mtime; |
529 } |
530 } |
530 free(local_path); |
531 free(local_path); |
531 } |
532 } |
532 ucx_list_free(statls); |
533 ucx_list_free(statls); |
608 |
609 |
609 LocalResource *local = ucx_map_cstr_get(db->resources, res->path); |
610 LocalResource *local = ucx_map_cstr_get(db->resources, res->path); |
610 char *local_path = util_concat_path(dir->path, res->path); |
611 char *local_path = util_concat_path(dir->path, res->path); |
611 |
612 |
612 char *etag = dav_get_string_property(res, "D:getetag"); |
613 char *etag = dav_get_string_property(res, "D:getetag"); |
613 struct stat s; |
614 SYS_STAT s; |
614 memset(&s, 0, sizeof(struct stat)); |
615 memset(&s, 0, sizeof(SYS_STAT)); |
615 if(local && !res->iscollection) { |
616 if(local && !res->iscollection) { |
616 int exists = 1; |
617 int exists = 1; |
617 if(stat(local_path, &s)) { |
618 if(sys_stat(local_path, &s)) { |
618 // Ignore the fact, that the file is locally removed. If the |
619 // Ignore the fact, that the file is locally removed. If the |
619 // server has an updated version, we read the file or the |
620 // server has an updated version, we read the file or the |
620 // next push will delete it on the server. |
621 // next push will delete it on the server. |
621 if(errno != ENOENT) { |
622 if(errno != ENOENT) { |
622 fprintf(stderr, "Cannot stat file: %s\n", local_path); |
623 fprintf(stderr, "Cannot stat file: %s\n", local_path); |
643 if(cdt && exists && s.st_mtime != local->last_modified) { |
644 if(cdt && exists && s.st_mtime != local->last_modified) { |
644 // file modified on the server and on the client |
645 // file modified on the server and on the client |
645 rename_conflict_file(dir, db, local->path); |
646 rename_conflict_file(dir, db, local->path); |
646 } |
647 } |
647 } else { |
648 } else { |
648 if(stat(local_path, &s)) { |
649 if(sys_stat(local_path, &s)) { |
649 if(errno != ENOENT) { |
650 if(errno != ENOENT) { |
650 fprintf(stderr, "Cannot stat file: %s\n", local_path); |
651 fprintf(stderr, "Cannot stat file: %s\n", local_path); |
651 } |
652 } |
652 } else if(S_ISDIR(s.st_mode)) { |
653 } else if(S_ISDIR(s.st_mode)) { |
653 //fprintf(stderr, "Error: file %s is a directory\n", local_path); |
654 //fprintf(stderr, "Error: file %s is a directory\n", local_path); |
684 if(!tmp_path) { |
685 if(!tmp_path) { |
685 fprintf(stderr, "Cannot create tmp path for %s\n", local_path); |
686 fprintf(stderr, "Cannot create tmp path for %s\n", local_path); |
686 free(local_path); |
687 free(local_path); |
687 return -1; |
688 return -1; |
688 } |
689 } |
689 FILE *out = fopen(tmp_path, "wb"); |
690 FILE *out = sys_fopen(tmp_path, "wb"); |
690 if(!out) { |
691 if(!out) { |
691 fprintf(stderr, "Cannot open output file: %s\n", local_path); |
692 fprintf(stderr, "Cannot open output file: %s\n", local_path); |
692 free(local_path); |
693 free(local_path); |
693 free(tmp_path); |
694 free(tmp_path); |
694 return -1; |
695 return -1; |
705 (*counter)++; |
706 (*counter)++; |
706 |
707 |
707 if(dir->trash && dir->backuppull) { |
708 if(dir->trash && dir->backuppull) { |
708 move_to_trash(dir, local_path); |
709 move_to_trash(dir, local_path); |
709 } |
710 } |
710 if(rename(tmp_path, local_path)) { |
711 if(sys_rename(tmp_path, local_path)) { |
711 fprintf( |
712 fprintf( |
712 stderr, |
713 stderr, |
713 "Cannot rename file %s to %s\n", |
714 "Cannot rename file %s to %s\n", |
714 tmp_path, |
715 tmp_path, |
715 local_path); |
716 local_path); |
751 return ret; |
752 return ret; |
752 } |
753 } |
753 |
754 |
754 int sync_remove_local_resource(SyncDirectory *dir, LocalResource *res) { |
755 int sync_remove_local_resource(SyncDirectory *dir, LocalResource *res) { |
755 char *local_path = util_concat_path(dir->path, res->path); |
756 char *local_path = util_concat_path(dir->path, res->path); |
756 struct stat s; |
757 SYS_STAT s; |
757 if(stat(local_path, &s)) { |
758 if(sys_stat(local_path, &s)) { |
758 free(local_path); |
759 free(local_path); |
759 return -2; |
760 return -2; |
760 } |
761 } |
761 |
762 |
762 if(S_ISDIR(s.st_mode)) { |
763 if(S_ISDIR(s.st_mode)) { |
797 void rename_conflict_file(SyncDirectory *dir, SyncDatabase *db, char *path) { |
798 void rename_conflict_file(SyncDirectory *dir, SyncDatabase *db, char *path) { |
798 char *local_path = util_concat_path(dir->path, path); |
799 char *local_path = util_concat_path(dir->path, path); |
799 char *parent = util_parent_path(local_path); |
800 char *parent = util_parent_path(local_path); |
800 |
801 |
801 int rev = 0; |
802 int rev = 0; |
802 struct stat s; |
803 SYS_STAT s; |
803 int loop = 1; |
804 int loop = 1; |
804 do { |
805 do { |
805 char *res_parent = util_parent_path(path); |
806 char *res_parent = util_parent_path(path); |
806 char *res_name = util_resource_name(path); |
807 char *res_name = util_resource_name(path); |
807 |
808 |
815 res_parent, |
816 res_parent, |
816 rev, |
817 rev, |
817 res_name); |
818 res_name); |
818 |
819 |
819 |
820 |
820 if(stat(new_path.ptr, &s)) { |
821 if(sys_stat(new_path.ptr, &s)) { |
821 if(errno == ENOENT) { |
822 if(errno == ENOENT) { |
822 loop = 0; |
823 loop = 0; |
823 printf("conflict: %s\n", local_path); |
824 printf("conflict: %s\n", local_path); |
824 if(rename(local_path, new_path.ptr)) { |
825 if(sys_rename(local_path, new_path.ptr)) { |
825 //printf("errno: %d\n", errno); |
826 //printf("errno: %d\n", errno); |
826 fprintf( |
827 fprintf( |
827 stderr, |
828 stderr, |
828 "Cannot rename file %s to %s\n", |
829 "Cannot rename file %s to %s\n", |
829 local_path, |
830 local_path, |
893 if(!new_path) { |
894 if(!new_path) { |
894 fprintf(stderr, "Cannot move file %s to trash.\n", path); |
895 fprintf(stderr, "Cannot move file %s to trash.\n", path); |
895 return; |
896 return; |
896 } |
897 } |
897 |
898 |
898 if(rename(path, new_path)) { |
899 if(sys_rename(path, new_path)) { |
899 //printf("errno: %d\n", errno); |
900 //printf("errno: %d\n", errno); |
900 fprintf( |
901 fprintf( |
901 stderr, |
902 stderr, |
902 "Cannot rename file %s to %s\n", |
903 "Cannot rename file %s to %s\n", |
903 path, |
904 path, |
1201 // if an entry is a directory, put it on the stack |
1202 // if an entry is a directory, put it on the stack |
1202 |
1203 |
1203 char *p = stack->data; |
1204 char *p = stack->data; |
1204 stack = ucx_list_remove(stack, stack); |
1205 stack = ucx_list_remove(stack, stack); |
1205 char *local_path = util_concat_path(dir->path, p); |
1206 char *local_path = util_concat_path(dir->path, p); |
1206 DIR *local_dir = opendir(local_path); |
1207 SYS_DIR local_dir = sys_opendir(local_path); |
1207 |
1208 |
1208 if(!local_dir) { |
1209 if(!local_dir) { |
1209 fprintf(stderr, "Cannot open directory %s\n", local_path); |
1210 fprintf(stderr, "Cannot open directory %s\n", local_path); |
1210 } else { |
1211 } else { |
1211 struct dirent *ent; |
1212 SysDirEnt *ent; |
1212 while((ent = readdir(local_dir)) != NULL) { |
1213 while((ent = sys_readdir(local_dir)) != NULL) { |
1213 if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) { |
1214 if(!strcmp(ent->name, ".") || !strcmp(ent->name, "..")) { |
1214 continue; |
1215 continue; |
1215 } |
1216 } |
1216 |
1217 |
1217 char *new_path = util_concat_path(p, ent->d_name); |
1218 char *new_path = util_concat_path(p, ent->name); |
1218 int isdir; |
1219 int isdir; |
1219 LocalResource *res = local_resource_new(dir, db, new_path, &isdir); |
1220 LocalResource *res = local_resource_new(dir, db, new_path, &isdir); |
1220 if(isdir) { |
1221 if(isdir) { |
1221 resources = ucx_list_append(resources, res); |
1222 resources = ucx_list_append(resources, res); |
1222 stack = ucx_list_prepend(stack, new_path); |
1223 stack = ucx_list_prepend(stack, new_path); |
1283 return resources; |
1284 return resources; |
1284 } |
1285 } |
1285 |
1286 |
1286 LocalResource* local_resource_new(SyncDirectory *dir, SyncDatabase *db, char *path, int *isdir) { |
1287 LocalResource* local_resource_new(SyncDirectory *dir, SyncDatabase *db, char *path, int *isdir) { |
1287 char *file_path = util_concat_path(dir->path, path); |
1288 char *file_path = util_concat_path(dir->path, path); |
1288 struct stat s; |
1289 SYS_STAT s; |
1289 if(stat(file_path, &s)) { |
1290 if(sys_stat(file_path, &s)) { |
1290 fprintf(stderr, "Cannot stat file %s\n", file_path); |
1291 fprintf(stderr, "Cannot stat file %s\n", file_path); |
1291 free(file_path); |
1292 free(file_path); |
1292 return NULL; |
1293 return NULL; |
1293 } |
1294 } |
1294 free(file_path); |
1295 free(file_path); |
1681 LocalResource *local, |
1682 LocalResource *local, |
1682 int *counter) |
1683 int *counter) |
1683 { |
1684 { |
1684 char *local_path = util_concat_path(dir->path, res->path); |
1685 char *local_path = util_concat_path(dir->path, res->path); |
1685 |
1686 |
1686 struct stat s; |
1687 SYS_STAT s; |
1687 if(stat(local_path, &s)) { |
1688 if(sys_stat(local_path, &s)) { |
1688 fprintf(stderr, "cannot stat file: %s\n", local_path); |
1689 fprintf(stderr, "cannot stat file: %s\n", local_path); |
1689 perror(""); |
1690 perror(""); |
1690 free(local_path); |
1691 free(local_path); |
1691 return -1; |
1692 return -1; |
1692 } |
1693 } |
1693 |
1694 |
1694 FILE *in = fopen(local_path, "rb"); |
1695 FILE *in = sys_fopen(local_path, "rb"); |
1695 if(!in) { |
1696 if(!in) { |
1696 fprintf(stderr, "Cannot open file %s\n", local_path); |
1697 fprintf(stderr, "Cannot open file %s\n", local_path); |
1697 free(local_path); |
1698 free(local_path); |
1698 return -1; |
1699 return -1; |
1699 } |
1700 } |
1875 |
1876 |
1876 UcxMapIterator i = ucx_map_iterator(db->conflict); |
1877 UcxMapIterator i = ucx_map_iterator(db->conflict); |
1877 LocalResource *res; |
1878 LocalResource *res; |
1878 UCX_MAP_FOREACH(key, res, i) { |
1879 UCX_MAP_FOREACH(key, res, i) { |
1879 char *path = util_concat_path(dir->path, res->path); |
1880 char *path = util_concat_path(dir->path, res->path); |
1880 struct stat s; |
1881 SYS_STAT s; |
1881 if(stat(path, &s)) { |
1882 if(sys_stat(path, &s)) { |
1882 if(errno == ENOENT) { |
1883 if(errno == ENOENT) { |
1883 dc[numdc] = res->path; |
1884 dc[numdc] = res->path; |
1884 numdc++; |
1885 numdc++; |
1885 } else { |
1886 } else { |
1886 fprintf(stderr, "Cannot stat file: %s\n", path); |
1887 fprintf(stderr, "Cannot stat file: %s\n", path); |
2118 if(!syncdir->trash) { |
2119 if(!syncdir->trash) { |
2119 printf("trash not configured for %s\n", syncdir->name); |
2120 printf("trash not configured for %s\n", syncdir->name); |
2120 return 0; |
2121 return 0; |
2121 } |
2122 } |
2122 |
2123 |
2123 DIR *dir = opendir(syncdir->trash); |
2124 SYS_DIR dir = sys_opendir(syncdir->trash); |
2124 if(!dir) { |
2125 if(!dir) { |
2125 fprintf(stderr, "cannot open trash directory: %s\n", syncdir->trash); |
2126 fprintf(stderr, "cannot open trash directory: %s\n", syncdir->trash); |
2126 perror("opendir"); |
2127 perror("opendir"); |
2127 return -1; |
2128 return -1; |
2128 } |
2129 } |
2129 |
2130 |
2130 uint64_t trashsize = 0; |
2131 uint64_t trashsize = 0; |
2131 int count = 0; |
2132 int count = 0; |
2132 struct dirent *ent; |
2133 SysDirEnt *ent; |
2133 while((ent = readdir(dir)) != NULL) { |
2134 while((ent = sys_readdir(dir)) != NULL) { |
2134 if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) { |
2135 if(!strcmp(ent->name, ".") || !strcmp(ent->name, "..")) { |
2135 continue; |
2136 continue; |
2136 } |
2137 } |
2137 |
2138 |
2138 char *path = util_concat_path(syncdir->trash, ent->d_name); |
2139 char *path = util_concat_path(syncdir->trash, ent->name); |
2139 |
2140 |
2140 struct stat s; |
2141 SYS_STAT s; |
2141 if(stat(path, &s)) { |
2142 if(sys_stat(path, &s)) { |
2142 perror("stat"); |
2143 perror("stat"); |
2143 } else { |
2144 } else { |
2144 trashsize += s.st_size; |
2145 trashsize += s.st_size; |
2145 } |
2146 } |
2146 count++; |
2147 count++; |
2147 |
2148 |
2148 free(path); |
2149 free(path); |
2149 } |
2150 } |
2150 closedir(dir); |
2151 sys_closedir(dir); |
2151 |
2152 |
2152 printf("path: %s\n", syncdir->trash); |
2153 printf("path: %s\n", syncdir->trash); |
2153 printf("%d %s\n", count, count == 1 ? "file" : "files"); |
2154 printf("%d %s\n", count, count == 1 ? "file" : "files"); |
2154 char *sizestr = size_str(trashsize); |
2155 char *sizestr = size_str(trashsize); |
2155 printf("%s\n", sizestr); |
2156 printf("%s\n", sizestr); |
2174 if(!syncdir->trash) { |
2175 if(!syncdir->trash) { |
2175 fprintf(stderr, "trash not configured for %s\n", syncdir->name); |
2176 fprintf(stderr, "trash not configured for %s\n", syncdir->name); |
2176 return -1; |
2177 return -1; |
2177 } |
2178 } |
2178 |
2179 |
2179 DIR *dir = opendir(syncdir->trash); |
2180 SYS_DIR dir = sys_opendir(syncdir->trash); |
2180 if(!dir) { |
2181 if(!dir) { |
2181 fprintf(stderr, "cannot open trash directory: %s\n", syncdir->trash); |
2182 fprintf(stderr, "cannot open trash directory: %s\n", syncdir->trash); |
2182 perror("opendir"); |
2183 perror("opendir"); |
2183 return -1; |
2184 return -1; |
2184 } |
2185 } |
2185 |
2186 |
2186 struct dirent *ent; |
2187 SysDirEnt *ent; |
2187 while((ent = readdir(dir)) != NULL) { |
2188 while((ent = sys_readdir(dir)) != NULL) { |
2188 if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) { |
2189 if(!strcmp(ent->name, ".") || !strcmp(ent->name, "..")) { |
2189 continue; |
2190 continue; |
2190 } |
2191 } |
2191 |
2192 |
2192 char *path = util_concat_path(syncdir->trash, ent->d_name); |
2193 char *path = util_concat_path(syncdir->trash, ent->name); |
2193 printf("delete: %s\n", path); |
2194 printf("delete: %s\n", path); |
2194 |
2195 |
2195 struct stat s; |
2196 SYS_STAT s; |
2196 if(stat(path, &s)) { |
2197 if(sys_stat(path, &s)) { |
2197 perror("stat"); |
2198 perror("stat"); |
2198 free(path); |
2199 free(path); |
2199 continue; |
2200 continue; |
2200 } |
2201 } |
2201 if(S_ISDIR(s.st_mode)) { |
2202 if(S_ISDIR(s.st_mode)) { |
2388 free(fullpath); |
2389 free(fullpath); |
2389 return 1; |
2390 return 1; |
2390 } |
2391 } |
2391 |
2392 |
2392 int sync_get_file(CmdArgs *args, const char *path, const char *dir, SyncFile *f) { |
2393 int sync_get_file(CmdArgs *args, const char *path, const char *dir, SyncFile *f) { |
2393 struct stat s; |
2394 SYS_STAT s; |
2394 if(stat(path, &s)) { |
2395 if(sys_stat(path, &s)) { |
2395 switch(errno) { |
2396 switch(errno) { |
2396 case EACCES: return 2; |
2397 case EACCES: return 2; |
2397 case ENOENT: return 1; |
2398 case ENOENT: return 1; |
2398 default: return 3; |
2399 default: return 3; |
2399 } |
2400 } |
2584 char* create_locktoken_file(const char *syncdirname, const char *locktoken) { |
2585 char* create_locktoken_file(const char *syncdirname, const char *locktoken) { |
2585 sstr_t fname = ucx_sprintf("locktoken-%s.txt", syncdirname); |
2586 sstr_t fname = ucx_sprintf("locktoken-%s.txt", syncdirname); |
2586 char *path = config_file_path(fname.ptr); |
2587 char *path = config_file_path(fname.ptr); |
2587 free(fname.ptr); |
2588 free(fname.ptr); |
2588 |
2589 |
2589 FILE *file = fopen(path, "w"); |
2590 FILE *file = sys_fopen(path, "w"); |
2590 if(file) { |
2591 if(file) { |
2591 fprintf(file, "%s\n", locktoken); |
2592 fprintf(file, "%s\n", locktoken); |
2592 fclose(file); |
2593 fclose(file); |
2593 return path; |
2594 return path; |
2594 } else { |
2595 } else { |