--- 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) { + +}