using new io abstraction in dav-sync

Sun, 10 Jun 2018 12:35:00 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sun, 10 Jun 2018 12:35:00 +0200
changeset 411
a182e503617b
parent 410
0b9bea2d7283
child 412
dc74f736aea1

using new io abstraction in dav-sync

dav/sync.c file | annotate | diff | comparison | revisions
dav/system.c file | annotate | diff | comparison | revisions
dav/system.h file | annotate | diff | comparison | revisions
--- a/dav/sync.c	Fri Jun 08 19:58:17 2018 +0200
+++ b/dav/sync.c	Sun Jun 10 12:35:00 2018 +0200
@@ -55,6 +55,7 @@
 #include "libxattr.h"
 #include "tags.h"
 
+#include "system.h"
 
 #include <pthread.h>
 #include <ctype.h>
@@ -523,8 +524,8 @@
     UCX_FOREACH(elm, statls) {
         LocalResource *l = elm->data;
         char *local_path = util_concat_path(dir->path, l->path);
-        struct stat s;
-        if(!stat(local_path, &s)) {
+        SYS_STAT s;
+        if(!sys_stat(local_path, &s)) {
             l->last_modified = s.st_mtime;
         }
         free(local_path);
@@ -610,11 +611,11 @@
     char *local_path = util_concat_path(dir->path, res->path);
     
     char *etag = dav_get_string_property(res, "D:getetag");
-    struct stat s;
-    memset(&s, 0, sizeof(struct stat));
+    SYS_STAT s;
+    memset(&s, 0, sizeof(SYS_STAT));
     if(local && !res->iscollection) {
         int exists = 1;
-        if(stat(local_path, &s)) {
+        if(sys_stat(local_path, &s)) {
             // Ignore the fact, that the file is locally removed. If the
             // server has an updated version, we read the file or the
             // next push will delete it on the server.
@@ -645,7 +646,7 @@
             rename_conflict_file(dir, db, local->path);
         }
     } else {
-        if(stat(local_path, &s)) {
+        if(sys_stat(local_path, &s)) {
             if(errno != ENOENT) {
                 fprintf(stderr, "Cannot stat file: %s\n", local_path);
             }
@@ -686,7 +687,7 @@
             free(local_path);
             return -1;
         }
-        FILE *out = fopen(tmp_path, "wb");
+        FILE *out = sys_fopen(tmp_path, "wb");
         if(!out) {
             fprintf(stderr, "Cannot open output file: %s\n", local_path);
             free(local_path);
@@ -707,7 +708,7 @@
             if(dir->trash && dir->backuppull) {
                 move_to_trash(dir, local_path);
             }
-            if(rename(tmp_path, local_path)) {
+            if(sys_rename(tmp_path, local_path)) {
                 fprintf(
                         stderr,
                         "Cannot rename file %s to %s\n",
@@ -719,7 +720,7 @@
                 return -1;
             }
             
-            if(stat(local_path, &s)) {
+            if(sys_stat(local_path, &s)) {
                 fprintf(stderr, "Cannot stat file: %s\n", local_path);
                 perror("");
             }
@@ -753,8 +754,8 @@
 
 int sync_remove_local_resource(SyncDirectory *dir, LocalResource *res) {
     char *local_path = util_concat_path(dir->path, res->path);
-    struct stat s;
-    if(stat(local_path, &s)) {
+    SYS_STAT s;
+    if(sys_stat(local_path, &s)) {
         free(local_path);
         return -2;
     }
@@ -799,7 +800,7 @@
     char *parent = util_parent_path(local_path);
     
     int rev = 0;
-    struct stat s;
+    SYS_STAT s;
     int loop = 1;
     do {
         char *res_parent = util_parent_path(path);
@@ -817,11 +818,11 @@
             res_name);
         
         
-        if(stat(new_path.ptr, &s)) {
+        if(sys_stat(new_path.ptr, &s)) {
             if(errno == ENOENT) {
                 loop = 0;
                 printf("conflict: %s\n", local_path);
-                if(rename(local_path, new_path.ptr)) {
+                if(sys_rename(local_path, new_path.ptr)) {
                     //printf("errno: %d\n", errno);
                     fprintf(
                             stderr,
@@ -856,8 +857,8 @@
             i,
             util_resource_name(path));
         
-        struct stat s;
-        if(stat(np.ptr, &s)) {
+        SYS_STAT s;
+        if(sys_stat(np.ptr, &s)) {
             if(errno == ENOENT) {
                 new_path = np.ptr;
             }
@@ -880,8 +881,8 @@
             i,
             util_resource_name(path));
         
-        struct stat s;
-        if(stat(np.ptr, &s)) {
+        SYS_STAT s;
+        if(sys_stat(np.ptr, &s)) {
             if(errno == ENOENT) {
                 new_path = np.ptr;
             }
@@ -895,7 +896,7 @@
         return;
     }
     
-    if(rename(path, new_path)) {
+    if(sys_rename(path, new_path)) {
         //printf("errno: %d\n", errno);
         fprintf(
                 stderr,
@@ -1203,18 +1204,18 @@
         char *p = stack->data;
         stack = ucx_list_remove(stack, stack);
         char *local_path = util_concat_path(dir->path, p);
-        DIR *local_dir = opendir(local_path);
+        SYS_DIR local_dir = sys_opendir(local_path);
         
         if(!local_dir) {
             fprintf(stderr, "Cannot open directory %s\n", local_path);
         } else {
-            struct dirent *ent;
-            while((ent = readdir(local_dir)) != NULL) {
-                if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) {
+            SysDirEnt *ent;
+            while((ent = sys_readdir(local_dir)) != NULL) {
+                if(!strcmp(ent->name, ".") || !strcmp(ent->name, "..")) {
                     continue;
                 }
                 
-                char *new_path = util_concat_path(p, ent->d_name);
+                char *new_path = util_concat_path(p, ent->name);
                 int isdir;
                 LocalResource *res = local_resource_new(dir, db, new_path, &isdir);
                 if(isdir) {
@@ -1227,7 +1228,7 @@
                     free(new_path);
                 }
             }
-            closedir(local_dir);
+            sys_closedir(local_dir);
  
         }
         free(local_path);
@@ -1285,8 +1286,8 @@
 
 LocalResource* local_resource_new(SyncDirectory *dir, SyncDatabase *db, char *path, int *isdir) {
     char *file_path = util_concat_path(dir->path, path);
-    struct stat s;
-    if(stat(file_path, &s)) {
+    SYS_STAT s;
+    if(sys_stat(file_path, &s)) {
         fprintf(stderr, "Cannot stat file %s\n", file_path);
         free(file_path);
         return NULL;
@@ -1683,15 +1684,15 @@
 {
     char *local_path = util_concat_path(dir->path, res->path);
     
-    struct stat s;
-    if(stat(local_path, &s)) {
+    SYS_STAT s;
+    if(sys_stat(local_path, &s)) {
         fprintf(stderr, "cannot stat file: %s\n", local_path);
         perror("");
         free(local_path);
         return -1;
     }
     
-    FILE *in = fopen(local_path, "rb");
+    FILE *in = sys_fopen(local_path, "rb");
     if(!in) {
         fprintf(stderr, "Cannot open file %s\n", local_path);
         free(local_path);
@@ -1877,8 +1878,8 @@
     LocalResource *res;
     UCX_MAP_FOREACH(key, res, i) {
         char *path = util_concat_path(dir->path, res->path);
-        struct stat s;
-        if(stat(path, &s)) {
+        SYS_STAT s;
+        if(sys_stat(path, &s)) {
             if(errno == ENOENT) {
                 dc[numdc] = res->path;
                 numdc++;
@@ -2120,7 +2121,7 @@
         return 0;
     }
     
-    DIR *dir = opendir(syncdir->trash);
+    SYS_DIR dir = sys_opendir(syncdir->trash);
     if(!dir) {
         fprintf(stderr, "cannot open trash directory: %s\n", syncdir->trash);
         perror("opendir");
@@ -2129,16 +2130,16 @@
     
     uint64_t trashsize = 0;
     int count = 0;
-    struct dirent *ent;
-    while((ent = readdir(dir)) != NULL) {
-        if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) {
+    SysDirEnt *ent;
+    while((ent = sys_readdir(dir)) != NULL) {
+        if(!strcmp(ent->name, ".") || !strcmp(ent->name, "..")) {
             continue;
         }
         
-        char *path = util_concat_path(syncdir->trash, ent->d_name);
+        char *path = util_concat_path(syncdir->trash, ent->name);
         
-        struct stat s;
-        if(stat(path, &s)) {
+        SYS_STAT s;
+        if(sys_stat(path, &s)) {
             perror("stat");
         } else {
             trashsize += s.st_size;
@@ -2147,7 +2148,7 @@
         
         free(path);
     }
-    closedir(dir);
+    sys_closedir(dir);
     
     printf("path: %s\n", syncdir->trash);
     printf("%d %s\n", count, count == 1 ? "file" : "files");
@@ -2176,24 +2177,24 @@
         return -1;
     }
     
-    DIR *dir = opendir(syncdir->trash);
+    SYS_DIR dir = sys_opendir(syncdir->trash);
     if(!dir) {
         fprintf(stderr, "cannot open trash directory: %s\n", syncdir->trash);
         perror("opendir");
         return -1;
     }
     
-    struct dirent *ent;
-    while((ent = readdir(dir)) != NULL) {
-        if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) {
+    SysDirEnt *ent;
+    while((ent = sys_readdir(dir)) != NULL) {
+        if(!strcmp(ent->name, ".") || !strcmp(ent->name, "..")) {
             continue;
         }
         
-        char *path = util_concat_path(syncdir->trash, ent->d_name);
+        char *path = util_concat_path(syncdir->trash, ent->name);
         printf("delete: %s\n", path);
         
-        struct stat s;
-        if(stat(path, &s)) {
+        SYS_STAT s;
+        if(sys_stat(path, &s)) {
             perror("stat");
             free(path);
             continue;
@@ -2210,7 +2211,7 @@
         
         free(path);
     }
-    closedir(dir);
+    sys_closedir(dir);
     
     return 0;
 }
@@ -2390,8 +2391,8 @@
 }
 
 int sync_get_file(CmdArgs *args, const char *path, const char *dir, SyncFile *f) {
-    struct stat s;
-    if(stat(path, &s)) {
+    SYS_STAT s;
+    if(sys_stat(path, &s)) {
         switch(errno) {
             case EACCES: return 2;
             case ENOENT: return 1;
@@ -2586,7 +2587,7 @@
     char *path = config_file_path(fname.ptr);
     free(fname.ptr);
     
-    FILE *file = fopen(path, "w");
+    FILE *file = sys_fopen(path, "w");
     if(file) {
         fprintf(file, "%s\n", locktoken);
         fclose(file);
--- a/dav/system.c	Fri Jun 08 19:58:17 2018 +0200
+++ b/dav/system.c	Sun Jun 10 12:35:00 2018 +0200
@@ -42,21 +42,39 @@
 /* ---------- POSIX implementation ---------- */
 
 SYS_DIR sys_opendir(const char *path) {
-    return opendir(path);
+    DIR *dir = opendir(path);
+    if(!dir) {
+        return NULL;
+    }
+    SysDir *d = malloc(sizeof(SysDir));
+    d->dir = dir;
+    d->ent = NULL;
+    return d;
 }
 
 SysDirEnt* sys_readdir(SYS_DIR dir) {
-    struct dirent *ent = readdir(dir);
+    if(dir->ent) {
+        free(dir->ent->name);
+        free(dir->ent);
+        dir->ent = NULL;
+    }
+    struct dirent *ent = readdir(dir->dir);
     if(ent) {
         SysDirEnt *e = malloc(sizeof(SysDirEnt));
         e->name = strdup(ent->d_name);
+        dir->ent = e;
         return e;
     }
     return NULL;
 }
 
 void sys_closedir(SYS_DIR dir) {
-    closedir(dir);
+    closedir(dir->dir);
+    if(dir->ent) {
+        free(dir->ent->name);
+        free(dir->ent);
+    }
+    free(dir);
 }
 
 FILE* sys_fopen(const char *path, const char *mode) {
@@ -67,6 +85,10 @@
     return stat(path, s);
 }
 
+int sys_rename(const char *oldpath, const char *newpath) {
+    return rename(oldpath, newpath);
+}
+
 
 #else
 /* ---------- Windows implementation ---------- */
@@ -120,10 +142,16 @@
         free(dir);
         return NULL;
     }
+    dir->ent = NULL;
     return dir;
 }
 
 SysDirEnt* sys_readdir(SYS_DIR dir) {
+    if(dir->ent) {
+        free(dir->ent->name);
+        free(dir->ent);
+        dir->ent = NULL;
+    }
     if(dir->first) {
         dir->first = 0;
     } else {
@@ -148,6 +176,7 @@
         name[nlen] = 0;
         SysDirEnt *ent = malloc(sizeof(SysDirEnt));
         ent->name = name;
+        dir->ent = ent;
         return ent;
     } else {
         return NULL;
@@ -155,6 +184,10 @@
 }
 
 void sys_closedir(SYS_DIR dir) {
+    if(dir->ent) {
+        free(dir->ent->name);
+        free(dir->ent);
+    }
     FindClose(dir->handle);
     free(dir);
 }
@@ -180,4 +213,24 @@
     return ret;
 }
 
+int sys_rename(const char *oldpath, const char *newpath) {
+    wchar_t *o = path2winpath(oldpath, FALSE, NULL);
+    wchara_t *n = path2winpath(newpath, FALSE, NULL);
+    if(!o || !n) {
+        return -1;
+    }
+    
+    struct __stat64 s;
+    if(!_wstat64(n, &s)) {
+        if(_wunlink(n)) {
+            fprintf(stderr, "sys_rename: cannot delete existing file: %ls\n", n);
+        }
+    }
+    
+    int ret = _wrename(o, n);
+    free(o);
+    free(n);
+    return ret;
+}
+
 #endif
\ No newline at end of file
--- a/dav/system.h	Fri Jun 08 19:58:17 2018 +0200
+++ b/dav/system.h	Sun Jun 10 12:35:00 2018 +0200
@@ -37,17 +37,6 @@
 
 #ifdef _WIN32
 #include <Windows.h>
-struct WinDir {
-    int first;
-    HANDLE handle;
-    WIN32_FIND_DATAW finddata;
-};
-#define SYS_DIR struct WinDir*
-#define SYS_STAT struct __stat64
-
-#else
-#define SYS_DIR DIR*
-#define SYS_STAT struct stat
 #endif
 
 #ifdef __cplusplus
@@ -57,6 +46,27 @@
 typedef struct SysDirEnt {
     char *name;
 } SysDirEnt;
+    
+#ifdef _WIN32
+struct WinDir {
+    int first;
+    HANDLE handle;
+    WIN32_FIND_DATAW finddata;
+    SysDirEnt *ent;
+};
+#define SYS_DIR struct WinDir*
+#define SYS_STAT struct __stat64
+
+#else
+
+typedef struct SysDir {
+    DIR *dir;
+    SysDirEnt *ent;
+} SysDir;
+
+#define SYS_DIR SysDir*
+#define SYS_STAT struct stat
+#endif
 
 void sys_freedirent(SysDirEnt *ent);
 SYS_DIR sys_opendir(const char *path);
@@ -67,6 +77,8 @@
 
 int sys_stat(const char *path, SYS_STAT *s);
 
+int sys_rename(const char *oldpath, const char *newpath);
+
 #ifdef __cplusplus
 }
 #endif

mercurial