added usage info and some options

Fri, 11 Jul 2014 12:47:24 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Fri, 11 Jul 2014 12:47:24 +0200
changeset 53
ddc4efc9b0f8
parent 52
91517b874a86
child 54
fc34bd28a22a

added usage info and some options

dav/sopt.c file | annotate | diff | comparison | revisions
dav/sync.c file | annotate | diff | comparison | revisions
dav/sync.h file | annotate | diff | comparison | revisions
--- a/dav/sopt.c	Thu Jul 10 13:50:00 2014 +0200
+++ b/dav/sopt.c	Fri Jul 11 12:47:24 2014 +0200
@@ -56,6 +56,7 @@
                         cmd_args_free(a);
                         return NULL;
                     }
+                    /*
                     case 'k': {
                         if(!option) {
                             option = "key";
@@ -70,56 +71,13 @@
                         }
                         break;
                     }
-                    case 'p': {
-                        ucx_map_cstr_put(a->options, "plain", "");
-                        break;
-                    }
+                    */
                     case 'c': {
-                        ucx_map_cstr_put(a->options, "crypt", "");
-                        break;
-                    }
-                    case 'a': {
-                        ucx_map_cstr_put(a->options, "all", "");
-                        break;
-                    }
-                    case 'l': {
-                        ucx_map_cstr_put(a->options, "list", "");
-                        break;
-                    }
-                    case 't': {
-                        ucx_map_cstr_put(a->options, "type", "");
-                        break;
-                    }
-                    case 'R': {
-                        ucx_map_cstr_put(a->options, "recursive", "");
+                        ucx_map_cstr_put(a->options, "conflict", "");
                         break;
                     }
-                    case 'o': {
-                        if(!option) {
-                            option = "output";
-                            optchar = 'o';
-                        } else {
-                            fprintf(
-                                    stderr,
-                                    "Missing argument for option -%c\n",
-                                    optchar);
-                            cmd_args_free(a);
-                            return NULL;
-                        }
-                        break;
-                    }
-                    case 'u': {
-                        if(!option) {
-                            option = "update";
-                            optchar = 'u';
-                        } else {
-                            fprintf(
-                                    stderr,
-                                    "Missing argument for option -%c\n",
-                                    optchar);
-                            cmd_args_free(a);
-                            return NULL;
-                        }
+                    case 'r': {
+                        ucx_map_cstr_put(a->options, "read", "");
                         break;
                     }
                 }
--- a/dav/sync.c	Thu Jul 10 13:50:00 2014 +0200
+++ b/dav/sync.c	Fri Jul 11 12:47:24 2014 +0200
@@ -47,6 +47,7 @@
 #include "db.h"
 
 #include "sync.h"
+#include "ucx/properties.h"
 
 static DavContext *ctx;
 
@@ -89,7 +90,15 @@
 }
 
 void print_usage(char *cmd) {
+    fprintf(stderr, "Usage: %s command [options] arguments...\n\n", cmd);
     
+    fprintf(stderr, "Commands:\n");
+    fprintf(stderr, "        pull [-c] <directory>\n");
+    fprintf(stderr, "        push [-r] <directory>\n\n");
+    
+    fprintf(stderr, "Options:\n");
+    fprintf(stderr, "        -c         Disable conflict detection\n");
+    fprintf(stderr, "        -r         Read changes from stdin\n\n");
 }
 
 int cmd_pull(CmdArgs *a) {
@@ -145,7 +154,7 @@
          
         while(res) { 
             // download the resource
-            if(sync_get_resource(dir, res, db)) {
+            if(sync_get_resource(a, dir, res, db)) {
                 fprintf(stderr, "sync_get_resource failed for resource: %s\n", res->path);
             }
             
@@ -179,11 +188,12 @@
     return 0;
 }
 
-int sync_get_resource(SyncDirectory *dir, DavResource *res, SyncDatabase *db) {
+int sync_get_resource(CmdArgs *a, SyncDirectory *dir, DavResource *res, SyncDatabase *db) {
     LocalResource *removed = ucx_map_cstr_get(db->remove, res->path);
     if(removed) {
         return 0;
     }
+    int cdt = cmd_getoption(a, "conflict") ? 0 : 1;
     
     LocalResource *local = ucx_map_cstr_get(db->resources, res->path);
     char *local_path = util_concat_path(dir->path, res->path);
@@ -217,7 +227,7 @@
             }
         }
         
-        if(s.st_mtim.tv_sec != local->last_modified) {
+        if(cdt && s.st_mtim.tv_sec != local->last_modified) {
             // file modified on the server and on the client
             rename_local_file(dir, db, local->path);
         }
@@ -226,7 +236,7 @@
             if(errno != ENOENT) {
                 fprintf(stderr, "Cannot stat file: %s\n", local_path);
             }
-        } else if(!S_ISDIR(s.st_mode)) {
+        } else if(cdt && !S_ISDIR(s.st_mode)) {
             rename_local_file(dir, db, res->path);
         }
     }
@@ -366,7 +376,11 @@
     sn->key = dav_context_get_key(ctx, repo->default_key);
     
     // upload all changed files
-    UcxList *resources = local_scan(dir, db);
+    //UcxList *resources = local_scan(dir, db);
+    //UcxList *resources = read_changes(dir, db);
+    UcxList *resources = cmd_getoption(a, "read") ?
+            read_changes(dir, db) : local_scan(dir, db);
+    
     UCX_FOREACH(elm, resources) {
         char *path = elm->data;
         printf("put: %s\n", path);
@@ -434,51 +448,15 @@
                 }
                 
                 char *new_path = util_concat_path(p, ent->d_name);
-                char *file_path = util_concat_path(dir->path, new_path);
-                struct stat s;
-                if(stat(file_path, &s)) {
-                    fprintf(stderr, "Cannot stat file %s\n", file_path);
+                int isdir;
+                LocalResource *res = path_to_local_resource(dir, db, new_path, &isdir);
+                if(isdir) {
+                    stack = ucx_list_prepend(stack, new_path);
+                } else if(res) {
+                    resources = ucx_list_append(resources, strdup(res->path));
                     free(new_path);
-                    free(file_path);
-                    continue;
-                }
-                free(file_path);
-                
-                if(S_ISDIR(s.st_mode)) {
-                    stack = ucx_list_prepend(stack, new_path);
                 } else {
-                    LocalResource *res = ucx_map_cstr_get(
-                            db->resources,
-                            new_path);
-                    if(res) {
-                        // the file is already in the database
-                        // compare length and lastmodified date
-                        
-                        if(res->last_modified == s.st_mtim.tv_sec
-                                && res->size == s.st_size)
-                        {
-                            // skip this file
-                            free(new_path);
-                        } else {
-                            // add file to list
-                            resources = ucx_list_append(
-                                    resources,
-                                    new_path);
-                            
-                            // update db entries
-                            res->size = s.st_size;
-                            res->last_modified = s.st_mtim.tv_sec;
-                        }                       
-                    } else {
-                        // add file to list
-                        LocalResource *res = calloc(1, sizeof(LocalResource));
-                        res->path = strdup(new_path);
-                        res->etag = NULL;
-                        res->last_modified = s.st_mtim.tv_sec;
-                        res->size = s.st_size;
-                        ucx_map_cstr_put(db->resources, res->path, res);
-                        resources = ucx_list_append(resources, new_path);
-                    }
+                    free(new_path);
                 }
             }
             closedir(local_dir);
@@ -491,6 +469,104 @@
     return resources;
 }
 
+UcxList* read_changes(SyncDirectory *dir, SyncDatabase *db) {
+    UcxProperties *parser = ucx_properties_new();
+    parser->delimiter = ':';
+    
+    UcxList *resources = NULL;
+    sstr_t name;
+    sstr_t value;
+    
+    char buf[STDIN_BUF_SIZE];
+    size_t r;
+    while(!feof(stdin)) {
+        r = fread(buf, 1, STDIN_BUF_SIZE, stdin);
+        ucx_properties_fill(parser, buf, r);
+        while(ucx_properties_next(parser, &name, &value)) {
+            if(value.length == 0) {
+                fprintf(stderr, "Wrong input\n");
+                continue;
+            }
+            if(value.ptr[0] == '"'
+                    && value.length > 2
+                    && value.ptr[value.length - 1] == '"')
+            {
+                value.ptr[value.length - 1] = '\0';
+                value.ptr++;
+                value.length -= 2;
+            }
+            value = sstrdup(value);
+            
+            if(!sstrcmp(name, S("put"))) {
+                int isdir;
+                LocalResource *res = path_to_local_resource(dir, db, value.ptr, &isdir);
+                if(res) {
+                    resources = ucx_list_append(resources, strdup(res->path));
+                }
+            } else if(!sstrcmp(name, S("remove"))) {
+                int isdir;
+                //LocalResource *res = path_to_local_resource(dir, db, value.ptr, &isdir);
+                LocalResource *res = calloc(1, sizeof(LocalResource));
+                res->path = sstrdup(value).ptr;
+                if(res) {
+                    ucx_map_sstr_put(db->remove, value, res);
+                    ucx_map_sstr_remove(db->resources, value);
+                }
+                
+            }
+            
+            free(value.ptr);
+        }
+    }
+    ucx_properties_free(parser);    
+    
+    return resources;
+}
+
+LocalResource* path_to_local_resource(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)) {
+        fprintf(stderr, "Cannot stat file %s\n", file_path);
+        free(file_path);
+        return NULL;
+    }
+    free(file_path);
+
+    if(!S_ISDIR(s.st_mode)) {
+        *isdir = 0;
+        LocalResource *res = ucx_map_cstr_get(db->resources, path);
+        if(res) {
+            // the file is already in the database
+            // compare length and lastmodified date
+
+            if(res->last_modified == s.st_mtim.tv_sec
+                    && res->size == s.st_size)
+            {
+                // file unchanged
+                return NULL;
+            } else {
+                // update db entries
+                res->size = s.st_size;
+                res->last_modified = s.st_mtim.tv_sec;
+                
+                return res;
+            }                       
+        } else {
+            LocalResource *res = calloc(1, sizeof(LocalResource));
+            res->path = strdup(path);
+            res->etag = NULL;
+            res->last_modified = s.st_mtim.tv_sec;
+            res->size = s.st_size;
+            ucx_map_cstr_put(db->resources, res->path, res);
+            return res;
+        }
+    } else {
+        *isdir = 1;
+    }
+    return NULL;
+}
+
 int sync_put_resource(SyncDirectory *dir, DavResource *res, SyncDatabase *db) {
     char *local_path = util_concat_path(dir->path, res->path);
     FILE *in = fopen(local_path, "r");
--- a/dav/sync.h	Thu Jul 10 13:50:00 2014 +0200
+++ b/dav/sync.h	Fri Jul 11 12:47:24 2014 +0200
@@ -39,16 +39,20 @@
 extern "C" {
 #endif
 
+#define STDIN_BUF_SIZE 2048
+    
 void print_usage(char *cmd);
 
 int cmd_pull(CmdArgs *args);
 int cmd_push(CmdArgs *args);
 int cmd_sync(CmdArgs *args);
 
-int sync_get_resource(SyncDirectory *dir, DavResource *res, SyncDatabase *db);
+int sync_get_resource(CmdArgs *a, SyncDirectory *dir, DavResource *res, SyncDatabase *db);
 void sync_remove_resource(SyncDirectory *dir, LocalResource *res);
 void rename_local_file(SyncDirectory *dir, SyncDatabase *db, char *path);
 UcxList* local_scan(SyncDirectory *dir, SyncDatabase *db);
+UcxList* read_changes(SyncDirectory *dir, SyncDatabase *db);
+LocalResource* path_to_local_resource(SyncDirectory *dir, SyncDatabase *db, char *path, int *isdir);
 
 int sync_put_resource(SyncDirectory *dir, DavResource *res, SyncDatabase *db);
 

mercurial