dav/finfo.c

changeset 520
da2b0cc44e4f
parent 519
ac5ac55b1b2e
child 522
46f96dcd6eab
--- a/dav/finfo.c	Tue Mar 12 09:35:04 2019 +0100
+++ b/dav/finfo.c	Wed Mar 13 12:52:24 2019 +0100
@@ -30,10 +30,15 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <unistd.h>
 #include <sys/stat.h>
 
 #include <ucx/string.h>
+#include <libidav/crypto.h>
+#include <libidav/utils.h>
+
+#include "libxattr.h"
 
 uint32_t parse_finfo(const char *str) {
     scstr_t s = scstr(str);
@@ -54,6 +59,8 @@
             finfo |= FINFO_OWNER;
         } else if(!sstrcasecmp(f, SC("mode"))) {
             finfo |= FINFO_MODE;
+        } else if(!sstrcasecmp(f, SC("xattr"))) {
+            finfo |= FINFO_XATTR;
         }
         free(f.ptr);
     }
@@ -114,3 +121,79 @@
     
     return 0;
 }
+
+XAttributes* file_get_attributes(const char *path) {
+    ssize_t nelm = 0;
+    char **attributes = xattr_list(path, &nelm);
+    if(nelm <= 0) {
+        return NULL;
+    }
+    
+    XAttributes *xattr = malloc(sizeof(XAttributes));
+    xattr->nattr = 0;
+    xattr->names = calloc(nelm, sizeof(char*));
+    xattr->values = calloc(nelm, sizeof(sstr_t));
+    
+    DAV_SHA_CTX *sha256 = dav_hash_init();
+    
+    size_t nattr = 0;
+    for(int i=0;i<nelm;i++) {
+        ssize_t valuelen = 0;
+        char *value = xattr_get(path, attributes[i], &valuelen);
+        if(valuelen >= 0) {
+            dav_hash_update(sha256, attributes[i], strlen(attributes[i]));
+            dav_hash_update(sha256, value, valuelen);
+            // add name and value
+            xattr->names[nattr] = attributes[i];
+            sstr_t v;
+            v.ptr = value;
+            v.length = valuelen;
+            xattr->values[nattr] = v;
+            nattr++;
+        } else {
+            // discard not readable attributes
+            free(attributes[i]);
+        }
+    }
+    
+    xattr->nattr = nattr;
+    
+    unsigned char hash[DAV_SHA256_DIGEST_LENGTH];
+    dav_hash_final(sha256, hash);
+    xattr->hash = util_hexstr(hash, DAV_SHA256_DIGEST_LENGTH);
+    
+    free(attributes);
+    
+    return xattr;
+}
+
+int resource_set_xattr(DavResource *res, XAttributes *xattr) {
+    if(!xattr || xattr->nattr == 0) {
+        return 0;
+    }
+    
+    DavXmlNode *content = dav_xml_createnode_with_text(DAV_NS, "hash", xattr->hash);
+    DavXmlNode *last = content;
+    
+    for(int i=0;i<xattr->nattr;i++) {
+        DavXmlNode *attr = dav_xml_createnode(DAV_NS, "xattr");
+        dav_xml_add_attr(attr, "name", xattr->names[i]);
+        last->next = attr;
+        last = attr;
+        
+        sstr_t value = xattr->values[i];
+        if(value.length > 0) {
+            char *encval = util_base64encode(value.ptr, value.length);
+            attr->children = dav_xml_createtextnode(encval);
+            free(encval);
+        }
+    }
+    
+    dav_set_property(res, "idav:xattributes", content);
+    
+    return 0;
+}
+
+void xattributes_free(XAttributes *xattr) {
+    
+}

mercurial