adds option to store a file info property

Thu, 07 Mar 2019 11:47:44 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Thu, 07 Mar 2019 11:47:44 +0100
changeset 517
8531b63accae
parent 516
39f5f17c3bc3
child 518
cca3e7aa30ed

adds option to store a file info property

dav/Makefile file | annotate | diff | comparison | revisions
dav/finfo.c file | annotate | diff | comparison | revisions
dav/finfo.h file | annotate | diff | comparison | revisions
dav/main.c file | annotate | diff | comparison | revisions
dav/main.h file | annotate | diff | comparison | revisions
dav/optparser.c file | annotate | diff | comparison | revisions
libidav/methods.c file | annotate | diff | comparison | revisions
--- a/dav/Makefile	Tue Feb 26 12:10:16 2019 +0100
+++ b/dav/Makefile	Thu Mar 07 11:47:44 2019 +0100
@@ -38,6 +38,8 @@
 DAV_SRC += tar.c
 DAV_SRC += system.c
 DAV_SRC += pwd.c
+DAV_SRC += libxattr.c
+DAV_SRC += finfo.c
 
 SYNC_SRC  = sync.c
 SYNC_SRC += config.c
@@ -47,6 +49,7 @@
 SYNC_SRC += error.c
 SYNC_SRC += assistant.c
 SYNC_SRC += libxattr.c
+SYNC_SRC += finfo.c
 SYNC_SRC += tags.c
 SYNC_SRC += system.c
 SYNC_SRC += pwd.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dav/finfo.c	Thu Mar 07 11:47:44 2019 +0100
@@ -0,0 +1,112 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2019 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "finfo.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+#include <ucx/string.h>
+
+uint32_t parse_finfo(const char *str) {
+    scstr_t s = scstr(str);
+    
+    if(!sstrcmp(s, SC("*")) || !sstrcmp(s, SC("a")) || !sstrcmp(s, SC("all"))) {
+        return FINFO_DATE|FINFO_OWNER|FINFO_MODE;
+    }
+    
+    size_t count = 0;
+    sstr_t *fs = sstrsplit(s, SC(","), &count);
+    
+    uint32_t finfo = 0;
+    for(int i=0;i<count;i++) {
+        sstr_t f = fs[i];
+        if(!sstrcasecmp(f, SC("date"))) {
+            finfo |= FINFO_DATE;
+        } else if(!sstrcasecmp(f, SC("owner"))) {
+            finfo |= FINFO_OWNER;
+        } else if(!sstrcasecmp(f, SC("mode"))) {
+            finfo |= FINFO_MODE;
+        }
+        free(f.ptr);
+    }
+    
+    free(fs);
+    return finfo;
+}
+
+int resource_set_finfo(const char *path, DavResource *res, uint32_t finfo) {
+    if(!path || finfo == 0) {
+        return 0;
+    }
+    
+    struct stat s;
+    if(stat(path, &s)) {
+        fprintf(stderr, "failed to stat: %s\n", path);
+        return 1;
+    }
+    return resource_set_finfo_s(&s, res, finfo);
+}
+
+static int buf_write_date(UcxBuffer *buf, time_t t) {
+    struct tm *date = gmtime(&t);
+    char str[32];
+    size_t len = strftime(str, 32, "%a, %d %b %Y %H:%M:%S GMT", date);
+    return ucx_buffer_write(str, 1, len, buf);
+}
+
+int resource_set_finfo_s(struct stat *s, DavResource *res, uint32_t finfo) {
+    if(finfo == 0) {
+        return 0;
+    }
+    
+    DavXmlNode *content = NULL;
+    
+    if(finfo & FINFO_DATE == FINFO_DATE) {
+        char str[32];
+        struct tm *date = gmtime(&s->st_mtime);
+        strftime(str, 32, "%a, %d %b %Y %H:%M:%S GMT", date);
+        DavXmlNode *mtime = dav_xml_createnode_with_text(DAV_NS, "mtime", str);
+        content = mtime;
+    }
+#ifndef _WIN32
+    if(finfo & FINFO_OWNER == FINFO_OWNER) {
+        // TODO
+    }
+    if(finfo & FINFO_MODE == FINFO_MODE) {
+        // TODO
+    }
+#endif
+    
+    
+    dav_set_property(res, "idav:finfo", content);;
+    
+    return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dav/finfo.h	Thu Mar 07 11:47:44 2019 +0100
@@ -0,0 +1,55 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2019 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef FINFO_H
+#define FINFO_H
+
+#include <libidav/webdav.h>
+#include <inttypes.h>
+#include <sys/stat.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define FINFO_DATE  1
+#define FINFO_OWNER 2
+#define FINFO_MODE  4
+
+uint32_t parse_finfo(const char *str);
+    
+int resource_set_finfo(const char *path, DavResource *res, uint32_t finfo);
+int resource_set_finfo_s(struct stat *s, DavResource *res, uint32_t finfo);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* FINFO_H */
+
--- a/dav/main.c	Tue Feb 26 12:10:16 2019 +0100
+++ b/dav/main.c	Thu Mar 07 11:47:44 2019 +0100
@@ -47,6 +47,7 @@
 #include "assistant.h"
 #include "system.h"
 #include "pwd.h"
+#include "finfo.h"
 #include "main.h"
 
 static DavContext *ctx;
@@ -76,6 +77,8 @@
         print_usage(argv[0]);
         return -1;
     }
+    
+    putenv("LC_TIME=C");
        
     char *cmd = argv[1];
     CmdArgs *args = cmd_parse_args(argc - 2, argv + 2);
@@ -1253,6 +1256,11 @@
         printfile = TRUE;
     }
     
+    char *finfo_str = cmd_getoption(a, "finfo");
+    uint32_t finfo = 0;
+    if(finfo_str) {
+        finfo = parse_finfo(finfo_str);
+    }
     
     int ret;
     for(int i=1;i<a->argc;i++) {
@@ -1260,7 +1268,7 @@
         if(!import) {
             if(!strcmp(file, "-")) {
                 FILE *in = stdin;
-                ret = put_file(repo, a, sn, path, "stdin", in, 0);
+                ret = put_file(repo, a, sn, path, "stdin", 0, NULL, in, 0);
             } else {
                 ret = put_entry(
                         repo,
@@ -1268,6 +1276,7 @@
                         sn,
                         path,
                         file,
+                        finfo,
                         TRUE,
                         printfile,
                         ignoredirerr); 
@@ -1291,6 +1300,7 @@
         DavSession *sn,
         char *path,
         char *file,
+        uint32_t finfo,
         DavBool root,
         DavBool printfile,
         DavBool ignoredirerr)
@@ -1340,6 +1350,7 @@
                     sn,
                     entry_path,
                     entry_file,
+                    finfo,
                     FALSE,
                     printfile,
                     ignoredirerr);
@@ -1370,9 +1381,6 @@
             printf("put: %s\n", file);
         }
         
-        /*
-         * use stdin if the input file is -
-         */
         FILE *in = fopen(file, "rb");
         if(!in) {
             fprintf(stderr, "cannot open input file\n");
@@ -1380,7 +1388,7 @@
         }
         char *filename = util_resource_name(file);
         //path = util_concat_path(path, filename);
-        ret = put_file(repo, a, sn, path, filename, in, s.st_size);
+        ret = put_file(repo, a, sn, path, filename, finfo, file, in, s.st_size);
         //free(path);
         fclose(in);
     }
@@ -1469,7 +1477,17 @@
     return ret == 0 ? CURL_SEEKFUNC_OK : CURL_SEEKFUNC_CANTSEEK;
 }
 
-int put_file(Repository *repo, CmdArgs *a, DavSession *sn, char *path, char *name, FILE *in, off_t len) {
+int put_file(
+        Repository *repo,
+        CmdArgs *a,
+        DavSession *sn,
+        char *path,
+        char *name,
+        uint32_t finfo,
+        const char *fpath,
+        FILE *in,
+        off_t len)
+{
     DavResource *res = dav_query(sn, "select - from %s", path);
     
     if(!res) {
@@ -1497,11 +1515,15 @@
         
         path = newpath;
         res = dav_resource_new(sn, path);
+        int ret = put_file(repo, a, sn, res->path, NULL, finfo, fpath, in, len);
+        // TODO: free res
         free(newpath);
-        int ret = put_file(repo, a, sn, res->path, NULL, in, len);
-        // TODO: free res
         return ret;
     }
+       
+    if(resource_set_finfo(fpath, res, finfo)) {
+        fprintf(stderr, "Cannot set finfo: %s.\n", strerror(errno));
+    }
     
     dav_set_content(res, in, (dav_read_func)fread, (dav_seek_func)file_seek);
     if(len > 0 && len < 0x7d000000) {
--- a/dav/main.h	Tue Feb 26 12:10:16 2019 +0100
+++ b/dav/main.h	Thu Mar 07 11:47:44 2019 +0100
@@ -80,11 +80,21 @@
         DavSession *sn,
         char *path,
         char *file,
+        uint32_t finfo,
         DavBool root,
         DavBool printfile,
         DavBool ignoredirerr);
 int put_tar(Repository *repo, CmdArgs *a, DavSession *sn, char *tarfile, char *path);
-int put_file(Repository *repo, CmdArgs *a, DavSession *sn, char *path, char *name, FILE *in, off_t len);
+int put_file(
+        Repository *repo,
+        CmdArgs *a,
+        DavSession *sn,
+        char *path,
+        char *name,
+        uint32_t finfo,
+        const char *fpath,
+        FILE *in,
+        off_t len);
 
 int cmd_remove(CmdArgs *args);
 int cmd_mkdir(CmdArgs *args);
--- a/dav/optparser.c	Tue Feb 26 12:10:16 2019 +0100
+++ b/dav/optparser.c	Thu Mar 07 11:47:44 2019 +0100
@@ -126,6 +126,11 @@
                         ucx_map_cstr_put(a->options, "xml", NOARG);
                         break;
                     }
+                    case 'F': {
+                        option = "finfo";
+                        optchar = 'F';
+                        break;
+                    }
                     case 'S': {
                         // undocumented hidden feature
                         ucx_map_cstr_put(a->options, "structure", NOARG);
@@ -160,11 +165,13 @@
                         optchar = 'T';
                         break;
                     }
-                    case 'F': {
+                    /*
+                    case 'P': {
                         option = "progressfile";
                         optchar = 'F';
                         break;
                     }
+                    */
                     case 'V': {
                         option = "version";
                         optchar = 'V';
--- a/libidav/methods.c	Tue Feb 26 12:10:16 2019 +0100
+++ b/libidav/methods.c	Thu Mar 07 11:47:44 2019 +0100
@@ -719,7 +719,7 @@
         char *lock,
         UcxBuffer *request,
         UcxBuffer *response)
-{  
+{    
     CURL *handle = sn->handle;
     curl_easy_setopt(handle, CURLOPT_CUSTOMREQUEST, "PROPPATCH");
     

mercurial