minimal copy master
authorOlaf Wintermann <olaf.wintermann@gmail.com>
Wed, 16 Jun 2021 14:04:13 +0000 (16:04 +0200)
committerOlaf Wintermann <olaf.wintermann@gmail.com>
Wed, 16 Jun 2021 14:04:13 +0000 (16:04 +0200)
mizucp/main.c
mizucp/main.h

index 18aaf5a..5fb1e8b 100644 (file)
@@ -215,13 +215,12 @@ int mzcp_copy(CPSettings *settings) {
 
 
 int mzcp_start_scan(CPSettings *settings) {
-    struct stat s;
-    if(stat(settings->from, &s)) {
+    if(stat(settings->from, &settings->root_stat)) {
         // TODO: error
         return 1;
     }
     
-    if(!S_ISDIR(s.st_mode)) {
+    if(!S_ISDIR(settings->root_stat.st_mode)) {
         // queue single file
         queue_begin = queue_root_elm_new();
         if(!queue_begin) {
@@ -259,6 +258,7 @@ void* scan_run(void *data) {
     }
     file->path = root;
     file->isdir = 1;
+    file->mode = settings->root_stat.st_mode;
     if(enqueue_file(file)) {
         scan_complete = 1;
         // TODO: error
@@ -298,6 +298,7 @@ void* scan_run(void *data) {
             SrcFile *f = calloc(1, sizeof(SrcFile));
             f->path = util_concat_path(elm->path, name);
             f->isdir = S_ISDIR(s.st_mode);
+            f->mode = s.st_mode;
             f->depends_on = elm;
             
             if(enqueue_file(f)) {
@@ -399,17 +400,35 @@ static SrcFile* queue_get_file(void) {
 
 void* copy_run(void *data) {
     CPSettings *settings = data;
+    
+    char *buffer = malloc(MZ_COPY_BUFSIZE);
+    size_t bufsize = MZ_COPY_BUFSIZE;
+    
     for(;;) {
         SrcFile *file = queue_get_file();
         if(!file) {
             break;
         }
         
-        char *from = file->path ? util_concat_path(settings->from, file->path) : settings->from;
-        printf("src: %s\n", from);
-        
+        char *from = file->path ? util_concat_path(settings->from, file->path) : settings->from;  
         char *to = util_concat_path(settings->to, file->path ? file->path : util_resource_name(settings->from));
-        printf("dst: %s\n", to);
+        
+        size_t from_len = strlen(from);
+        size_t to_len = strlen(to);
+        
+        if(from[from_len-1] == '/') {
+            from[from_len-1] = 0;
+        }
+        if(to[to_len-1] == '/') {
+            to[to_len-1] = 0;
+        }
+        
+        int ret;
+        if(file->isdir) {
+            ret = mz_copy_dir(settings, file, from, to);
+        } else {
+            ret = mz_copy_file(settings, file, from, to, buffer, bufsize);
+        }
         
         free(to);
         if(from != settings->from) {
@@ -420,3 +439,37 @@ void* copy_run(void *data) {
     return NULL;
 }
 
+int mz_copy_dir(CPSettings *settings, SrcFile *file, const char *from, const char *to) {
+    printf("mkdir %s\n", to);
+    return mkdir(to, file->mode);
+}
+
+int mz_copy_file(CPSettings *settings, SrcFile *file, const char *from, const char *to, char *buffer, size_t bufsize) {
+    printf("cp %s %s\n", from, to);
+    int fin = open(from, O_RDONLY);
+    if(fin < 0) {
+        return 1;
+    }
+    
+    int ret = 0;
+    
+    int fout = open(to, O_WRONLY|O_CREAT, file->mode);
+    if(fout < 0) {
+        perror("open");
+        close(fin);
+        return 1;
+    }
+    
+    ssize_t r;
+    while((r = read(fin, buffer, bufsize)) > 0) {
+        if(write(fout, buffer, r) != r) {
+            ret = 1;
+            break;
+        }
+    }
+    
+    close(fin);
+    close(fout);
+    
+    return ret;
+}
index 872b06f..1c5f730 100644 (file)
@@ -24,6 +24,8 @@
 #define MAIN_H
 
 #include <stdlib.h>
+#include <unistd.h>
+#include <sys/stat.h>
 
 #include <ucx/string.h>
 
@@ -41,6 +43,7 @@ extern "C" {
 #define CLIENT_MSG_BUFSIZE 512
     
 #define MAX_COPY_THREADS 32
+#define MZ_COPY_BUFSIZE 4 * 1024 * 1024
     
 typedef char CPBool;
 
@@ -55,6 +58,7 @@ typedef struct {
     CPBool url;
     CPBool pause;
     CPBool printsocket;
+    struct stat root_stat;
 } CPSettings;
 
 struct MZLock {
@@ -79,6 +83,11 @@ struct SrcFile {
     CPBool finished;
     
     /*
+     * file mode
+     */
+    mode_t mode;
+    
+    /*
      * processing this file depends on another file (directory)
      */
     SrcFile *depends_on;
@@ -107,6 +116,8 @@ int enqueue_file(SrcFile *file);
 int mzcp_start_copy_threads(CPSettings *settings);
 void* copy_run(void *data);
 
+int mz_copy_dir(CPSettings *settings, SrcFile *file, const char *from, const char *to);
+int mz_copy_file(CPSettings *settings, SrcFile *file, const char *from, const char *to, char *buffer, size_t bufsize);
 
     
 #ifdef __cplusplus