X-Git-Url: https://git.rrq.au/?a=blobdiff_plain;f=binary_storage.c;h=e8eaba4564fba93768181f6a4c98d3e322715e34;hb=HEAD;hp=e3d620218cfb3927c8267cf98f2c3246d86497d5;hpb=a1613c893e478f011dbb7314449ae1b97ff16f98;p=rrq%2Ffuse_xattrs.git diff --git a/binary_storage.c b/binary_storage.c index e3d6202..e8eaba4 100644 --- a/binary_storage.c +++ b/binary_storage.c @@ -12,12 +12,21 @@ #include #include #include +#include +#include +#include #include "binary_storage.h" #include "utils.h" #include "fuse_xattrs_config.h" +#include "stringmem.h" +#include "xattrs_config.h" -#include +#include + +#ifndef ENOATTR + #define ENOATTR ENODATA +#endif struct on_memory_attr { u_int16_t name_size; @@ -37,17 +46,17 @@ void __print_on_memory_attr(struct on_memory_attr *attr) debug_print("value size: %zu\n", attr->value_size); debug_print("sanitized_value: '%s'\n", sanitized_value); debug_print("--------------\n"); - free(sanitized_value); + strfree(sanitized_value); #endif } void __free_on_memory_attr(struct on_memory_attr *attr) { if(attr->name != NULL) - free(attr->name); + strfree(attr->name); if(attr->value != NULL) - free(attr->value); + strfree(attr->value); free(attr); } @@ -113,7 +122,7 @@ char *__read_file_sidecar(const char *path, int *buffer_size) debug_print("path=%s sidecar_path=%s\n", path, sidecar_path); char *buffer = __read_file(sidecar_path, buffer_size); - free (sidecar_path); + strfree (sidecar_path); return buffer; } @@ -197,8 +206,8 @@ int __write_to_file(FILE *file, const char *name, const char *value, const size_ #ifdef DEBUG char *sanitized_value = sanitize_value(value, value_size); - debug_print("name=%s sanitized_value=%s value_size=%zu\n", name, sanitized_value, value_size); - free(sanitized_value); + debug_print("name='%s' name_size=%hu sanitized_value='%s' value_size=%zu\n", name, name_size, sanitized_value, value_size); + strfree(sanitized_value); #endif // write name @@ -213,13 +222,46 @@ int __write_to_file(FILE *file, const char *name, const char *value, const size_ if (fwrite(&value_size, sizeof(size_t), 1, file) != 1) { return -1; } - if (fwrite(value, value_size, 1, file) != 1) { - return -1; + // write value content only if we have something to write. + if (value_size > 0) { + if (fwrite(value, value_size, 1, file) != 1) { + return -1; + } } return 0; } +// Ensure existence of tail path from either source_dir or sidecar_dir +static int ensure_dirs(char *path) { + int n = strlen( path ); + char *p = stralloc( n+1 ); + memcpy( p, path, n+1 ); + char *e = p + 1; + if ( strncmp( path, xattrs_config.source_dir, + xattrs_config.source_dir_size ) == 0 ) { + e += xattrs_config.source_dir_size; + } else if ( strncmp( path, xattrs_config.sidecar_dir, + xattrs_config.sidecar_dir_size ) == 0 ) { + e += xattrs_config.sidecar_dir_size; + } + if ( e - p >= n ) { + return 0; + } + for ( ;; ) { + while ( *e && *e != '/' ) e++; + if ( *e ) { + *e = 0; + if ( access( p, F_OK ) && mkdir( p, 0777 ) ) { + return 1; + } + *(e++) = '/'; + } else { + return 0; + } + } +} + /** * * @param path - path to file. @@ -227,14 +269,14 @@ int __write_to_file(FILE *file, const char *name, const char *value, const size_ * @param value - attribute value. size < XATTR_SIZE_MAX * @param size * @param flags - XATTR_CREATE and/or XATTR_REPLACE - * @return On success, zero is returned. On failure, -errno is returnted. + * @return On success, zero is returned. On failure, -errno is returned. */ int binary_storage_write_key(const char *path, const char *name, const char *value, size_t size, int flags) { #ifdef DEBUG char *sanitized_value = sanitize_value(value, size); debug_print("path=%s name=%s sanitized_value=%s size=%zu flags=%d\n", path, name, sanitized_value, size, flags); - free(sanitized_value); + strfree(sanitized_value); #endif int buffer_size; @@ -242,7 +284,7 @@ int binary_storage_write_key(const char *path, const char *name, const char *val if (buffer == NULL && buffer_size == -ENOENT && flags & XATTR_REPLACE) { error_print("No xattr. (flag XATTR_REPLACE)"); - return -ENODATA; + return -ENOATTR; } if (buffer == NULL && buffer_size != -ENOENT) { @@ -251,15 +293,20 @@ int binary_storage_write_key(const char *path, const char *name, const char *val int status; char *sidecar_path = get_sidecar_path(path); + + if ( ensure_dirs( sidecar_path ) ) { + return -ENOATTR; + } + FILE *file = fopen(sidecar_path, "w"); - free(sidecar_path); + strfree(sidecar_path); if (buffer == NULL) { debug_print("new file, writing directly...\n"); status = __write_to_file(file, name, value, size); assert(status == 0); fclose(file); - free(buffer); + strfree(buffer); return 0; } assert(buffer_size >= 0); @@ -307,7 +354,7 @@ int binary_storage_write_key(const char *path, const char *name, const char *val } fclose(file); - free(buffer); + strfree(buffer); return res; } @@ -335,7 +382,7 @@ int binary_storage_read_key(const char *path, const char *name, char *value, siz { struct on_memory_attr *attr = __read_on_memory_attr(&offset, buffer, _buffer_size); if (attr == NULL) { - free(buffer); + strfree(buffer); return -EILSEQ; } @@ -351,13 +398,13 @@ int binary_storage_read_key(const char *path, const char *name, char *value, siz error_print("error, attr->value_size=%zu > size=%zu\n", attr->value_size, size); res = -ERANGE; } - free(buffer); + strfree(buffer); __free_on_memory_attr(attr); return res; } __free_on_memory_attr(attr); } - free(buffer); + strfree(buffer); return -ENOATTR; } @@ -388,7 +435,7 @@ int binary_storage_list_keys(const char *path, char *list, size_t size) { struct on_memory_attr *attr = __read_on_memory_attr(&offset, buffer, _buffer_size); if (attr == NULL) { - free(buffer); + strfree(buffer); return -EILSEQ; } @@ -397,7 +444,7 @@ int binary_storage_list_keys(const char *path, char *list, size_t size) error_print("Not enough memory allocated. allocated=%zu required=%ld\n", size, attr->name_size + res); __free_on_memory_attr(attr); - free(buffer); + strfree(buffer); return -ERANGE; } else { memcpy(list + res, attr->name, attr->name_size); @@ -408,11 +455,11 @@ int binary_storage_list_keys(const char *path, char *list, size_t size) } __free_on_memory_attr(attr); } - free(buffer); + strfree(buffer); if (size == 0 && res > XATTR_LIST_MAX) { // FIXME: we should return the size or an error ? - return -E2BIG; + return -ENOSPC; } return (int)res; @@ -432,7 +479,7 @@ int binary_storage_remove_key(const char *path, const char *name) char *sidecar_path = get_sidecar_path(path); FILE *file = fopen(sidecar_path, "w"); - free(sidecar_path); + strfree(sidecar_path); size_t offset = 0; size_t name_len = strlen(name) + 1; // null byte \0 @@ -469,6 +516,6 @@ int binary_storage_remove_key(const char *path, const char *name) } fclose(file); - free(buffer); + strfree(buffer); return res; -} \ No newline at end of file +}