minimal copy
[mizunara.git] / mizucp / main.c
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;
+}