From: Ralph Ronnquist Date: Thu, 11 Nov 2021 06:34:45 +0000 (+1100) Subject: adding string heap and sroot=%s option X-Git-Url: https://git.rrq.au/?a=commitdiff_plain;h=186796e391585f79f86d4aebc274dcaa78f58769;p=rrq%2Ffuse_xattrs.git adding string heap and sroot=%s option --- diff --git a/CMakeLists.txt b/CMakeLists.txt index bcefc8e..0caddcf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,6 +61,7 @@ if(ENABLE_CODECOVERAGE) endif(ENABLE_CODECOVERAGE) set(SOURCE_FILES + stringmem.c fuse_xattrs.c passthrough.c binary_storage.c diff --git a/binary_storage.c b/binary_storage.c index c782d86..0a4321e 100644 --- a/binary_storage.c +++ b/binary_storage.c @@ -16,6 +16,7 @@ #include "binary_storage.h" #include "utils.h" #include "fuse_xattrs_config.h" +#include "stringmem.h" #include @@ -41,17 +42,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); } @@ -202,7 +203,7 @@ 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' name_size=%hu sanitized_value='%s' value_size=%zu\n", name, name_size, sanitized_value, value_size); - free(sanitized_value); + strfree(sanitized_value); #endif // write name @@ -241,7 +242,7 @@ int binary_storage_write_key(const char *path, const char *name, const char *val #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; @@ -259,14 +260,14 @@ int binary_storage_write_key(const char *path, const char *name, const char *val int status; char *sidecar_path = get_sidecar_path(path); 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); @@ -314,7 +315,7 @@ int binary_storage_write_key(const char *path, const char *name, const char *val } fclose(file); - free(buffer); + strfree(buffer); return res; } @@ -342,7 +343,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; } @@ -358,13 +359,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; } @@ -395,7 +396,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; } @@ -404,7 +405,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); @@ -415,7 +416,7 @@ 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 ? @@ -439,7 +440,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 @@ -476,6 +477,6 @@ int binary_storage_remove_key(const char *path, const char *name) } fclose(file); - free(buffer); + strfree(buffer); return res; } diff --git a/fuse_xattrs.c b/fuse_xattrs.c index fe56370..01d4d26 100644 --- a/fuse_xattrs.c +++ b/fuse_xattrs.c @@ -35,7 +35,7 @@ #include "xattrs_config.h" #include "utils.h" #include "passthrough.h" - +#include "stringmem.h" #include "binary_storage.h" struct xattrs_config xattrs_config; @@ -66,11 +66,11 @@ static int xmp_setxattr(const char *path, const char *name, const char *value, s debug_print("path=%s name=%s value=%s size=%zu XATTR_CREATE=%d XATTR_REPLACE=%d\n", _path, name, sanitized_value, size, flags & XATTR_CREATE, flags & XATTR_REPLACE); - free(sanitized_value); + strfree(sanitized_value); #endif int rtval = binary_storage_write_key(_path, name, value, size, flags); - free(_path); + strfree(_path); return rtval; } @@ -93,7 +93,7 @@ static int xmp_getxattr(const char *path, const char *name, char *value, size_t char *_path = prepend_source_directory(path); debug_print("path=%s name=%s size=%zu\n", _path, name, size); int rtval = binary_storage_read_key(_path, name, value, size); - free(_path); + strfree(_path); return rtval; } @@ -124,7 +124,7 @@ static int xmp_listxattr(const char *path, char *list, size_t size) char *_path = prepend_source_directory(path); debug_print("path=%s size=%zu\n", _path, size); int rtval = binary_storage_list_keys(_path, list, size); - free(_path); + strfree(_path); return rtval; } @@ -147,11 +147,13 @@ static int xmp_removexattr(const char *path, const char *name) char *_path = prepend_source_directory(path); debug_print("path=%s name=%s\n", _path, name); int rtval = binary_storage_remove_key(_path, name); - free(_path); + strfree(_path); return rtval; } +extern int xmp_utimens(const char *path, const struct timespec ts[2]); + static struct fuse_operations xmp_oper = { .getattr = xmp_getattr, .access = xmp_access, @@ -226,7 +228,7 @@ const char *sanitized_source_directory(const char *path) { absolute_path[len-2] = '/'; if (is_directory(absolute_path) == -1) { - free(absolute_path); + strfree(absolute_path); return NULL; } @@ -243,6 +245,7 @@ enum { static struct fuse_opt xattrs_opts[] = { FUSE_XATTRS_OPT("show_sidecar", show_sidecar, 1), FUSE_XATTRS_OPT("enable_namespaces", enable_namespaces, 1), + FUSE_XATTRS_OPT("sroot=%s", sidecar_dir, 0 ), FUSE_OPT_KEY("-V", KEY_VERSION), FUSE_OPT_KEY("--version", KEY_VERSION), @@ -298,6 +301,12 @@ int main(int argc, char *argv[]) { exit(1); } + if ( xattrs_config.sidecar_dir ) { + xattrs_config.sidecar_dir = + sanitized_source_directory( xattrs_config.sidecar_dir ); + return 0; + } + if (!xattrs_config.source_dir) { fprintf(stderr, "missing source directory\n"); fprintf(stderr, "see `%s -h' for usage\n", argv[0]); diff --git a/passthrough.c b/passthrough.c index b827da9..6d00593 100644 --- a/passthrough.c +++ b/passthrough.c @@ -29,6 +29,7 @@ #include "xattrs_config.h" #include "utils.h" +#include "stringmem.h" int xmp_getattr(const char *path, struct stat *stbuf) { int res; @@ -39,7 +40,7 @@ int xmp_getattr(const char *path, struct stat *stbuf) { char *_path = prepend_source_directory(path); res = lstat(_path, stbuf); - free(_path); + strfree(_path); if (res == -1) return -errno; @@ -55,7 +56,7 @@ int xmp_access(const char *path, int mask) { char *_path = prepend_source_directory(path); res = access(_path, mask); - free(_path); + strfree(_path); if (res == -1) return -errno; @@ -71,7 +72,7 @@ int xmp_readlink(const char *path, char *buf, size_t size) { char *_path = prepend_source_directory(path); res = readlink(_path, buf, size - 1); - free(_path); + strfree(_path); if (res == -1) return -errno; @@ -93,7 +94,7 @@ int xmp_readdir(const char *path, void *buf, fuse_fill_dir_t filler, } else { char *_path = prepend_source_directory(path); dp = opendir(_path); - free(_path); + strfree(_path); } if (dp == NULL) @@ -135,7 +136,7 @@ int xmp_mknod(const char *path, mode_t mode, dev_t rdev) { else res = mknod(_path, mode, rdev); - free(_path); + strfree(_path); if (res == -1) return -errno; @@ -150,7 +151,7 @@ int xmp_mkdir(const char *path, mode_t mode) { char *_path = prepend_source_directory(path); res = mkdir(_path, mode); - free(_path); + strfree(_path); if (res == -1) return -errno; @@ -168,7 +169,7 @@ int xmp_unlink(const char *path) { res = unlink(_path); if (res == -1) { - free(_path); + strfree(_path); return -errno; } @@ -178,8 +179,8 @@ int xmp_unlink(const char *path) { error_print("Error removing sidecar file: %s\n", sidecar_path); } } - free(sidecar_path); - free(_path); + strfree(sidecar_path); + strfree(_path); return 0; } @@ -193,7 +194,7 @@ int xmp_rmdir(const char *path) { char *_path = prepend_source_directory(path); res = rmdir(_path); - free(_path); + strfree(_path); if (res == -1) return -errno; @@ -211,7 +212,7 @@ int xmp_symlink(const char *from, const char *to) { char *_to = prepend_source_directory(to); res = symlink(from, _to); - free(_to); + strfree(_to); if (res == -1) return -errno; @@ -232,8 +233,8 @@ int xmp_rename(const char *from, const char *to) { res = rename(_from, _to); if (res == -1) { - free(_from); - free(_to); + strfree(_from); + strfree(_to); return -errno; } @@ -246,11 +247,11 @@ int xmp_rename(const char *from, const char *to) { error_print("Error renaming sidecar. from: %s to: %s\n", from_sidecar_path, to_sidecar_path); } } - free(from_sidecar_path); - free(to_sidecar_path); + strfree(from_sidecar_path); + strfree(to_sidecar_path); - free(_from); - free(_to); + strfree(_from); + strfree(_to); return 0; } @@ -267,8 +268,8 @@ int xmp_link(const char *from, const char *to) { char *_from = prepend_source_directory(from); char *_to = prepend_source_directory(to); res = link(_from, _to); - free(_from); - free(_to); + strfree(_from); + strfree(_to); if (res == -1) return -errno; @@ -284,7 +285,7 @@ int xmp_chmod(const char *path, mode_t mode) { char *_path = prepend_source_directory(path); res = chmod(_path, mode); - free(_path); + strfree(_path); if (res == -1) return -errno; @@ -300,7 +301,7 @@ int xmp_chown(const char *path, uid_t uid, gid_t gid) { char *_path = prepend_source_directory(path); res = lchown(_path, uid, gid); - free(_path); + strfree(_path); if (res == -1) return -errno; @@ -316,7 +317,7 @@ int xmp_truncate(const char *path, off_t size) { char *_path = prepend_source_directory(path); res = truncate(_path, size); - free(_path); + strfree(_path); if (res == -1) return -errno; @@ -325,20 +326,17 @@ int xmp_truncate(const char *path, off_t size) { } #ifdef HAVE_UTIMENSAT -int xmp_utimens(const char *path, const struct timespec ts[2], -struct fuse_file_info *fi) -{ +int xmp_utimens(const char *path, const struct timespec ts[2]) { if (xattrs_config.show_sidecar == 0 && filename_is_sidecar(path) == 1) { return -ENOENT; } - (void) fi; int res; char *_path = prepend_source_directory(path); /* don't use utime/utimes since they follow symlinks */ res = utimensat(0, _path, ts, AT_SYMLINK_NOFOLLOW); - free(_path); + strfree(_path); if (res == -1) return -errno; @@ -354,7 +352,7 @@ int xmp_open(const char *path, struct fuse_file_info *fi) { char *_path = prepend_source_directory(path); fd = open(_path, fi->flags); - free(_path); + strfree(_path); if (fd == -1) return -errno; @@ -401,7 +399,7 @@ int xmp_statfs(const char *path, struct statvfs *stbuf) { char *_path = prepend_source_directory(path); res = statvfs(_path, stbuf); - free(_path); + strfree(_path); if (res == -1) return -errno; diff --git a/passthrough.h b/passthrough.h index 928ec4a..ebc9a1b 100644 --- a/passthrough.h +++ b/passthrough.h @@ -29,7 +29,7 @@ int xmp_link(const char *from, const char *to); int xmp_chmod(const char *path, mode_t mode); int xmp_chown(const char *path, uid_t uid, gid_t gid); int xmp_truncate(const char *path, off_t size); -int xmp_utimens(const char *path, const struct timespec ts[2], struct fuse_file_info *fi); +int xmp_utimens(const char *path, const struct timespec ts[2]); int xmp_open(const char *path, struct fuse_file_info *fi); int xmp_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi); int xmp_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi); diff --git a/stringmem.c b/stringmem.c new file mode 100644 index 0000000..303add7 --- /dev/null +++ b/stringmem.c @@ -0,0 +1,55 @@ +#include +#include +#include + +#define BIGSTRING 1048576 +#define STRINGSPACE ( BIGSTRING * 20 ) + +static struct { + char *base; + char *current; + char *end; +} heap; + +char *strjoin(const char *first,...) { + va_list ap; + if ( heap.base == 0 ) { + heap.base = (char*) malloc( STRINGSPACE ); + heap.current = heap.base; + heap.end = heap.base + STRINGSPACE; + } + char *start = heap.current; + const char *p = first; + size_t size = strlen( first ) + 1; + va_start( ap, first ); + while ( ( p = va_arg( ap, const char* ) ) ) { + size += strlen( p ); + } + va_end( ap ); + if ( size > BIGSTRING ) { + start = (char*) malloc( size ); + } else { + if ( heap.current + size > heap.end ) { + heap.current = heap.base; + } + start = heap.current; + heap.current += size; + } + char *current = start; + strcpy( current, first ); + current += strlen( first ); + va_start( ap, first ); + while ( ( p = va_arg( ap, const char* ) ) ) { + strcpy( current, p ); + current += strlen( p ); + } + va_end( ap ); + *current = 0; + return start; +} + +void strfree(char *p) { + if ( p < heap.base || p >= heap.end ) { + free( p ); + } +} diff --git a/stringmem.h b/stringmem.h new file mode 100644 index 0000000..c25218f --- /dev/null +++ b/stringmem.h @@ -0,0 +1,6 @@ + +// Concatenate strigns onto the heap if possible, or malloc new. +extern char *strjoin(const char *first,...); + +// Dispose memory possibly within the string heap +extern void strfree(char *p); diff --git a/utils.c b/utils.c index 2f935ab..a6a8b75 100644 --- a/utils.c +++ b/utils.c @@ -15,18 +15,11 @@ #include "utils.h" #include "fuse_xattrs_config.h" #include "xattrs_config.h" +#include "stringmem.h" /* TODO: re-use memory to avoid calling malloc every time */ char *prepend_source_directory(const char *b) { - const size_t b_size = strlen(b); - const size_t dst_len = xattrs_config.source_dir_size + b_size + 1; - char *dst = (char*) malloc(sizeof(char) * dst_len); - - memcpy(dst, xattrs_config.source_dir, xattrs_config.source_dir_size); - memcpy(dst+xattrs_config.source_dir_size, b, b_size + 1); // include '\0' - //sprintf(dst, "%s%s", a, b); - - return dst; + return strjoin( xattrs_config.source_dir, b, 0 ); } int is_directory(const char *path) { @@ -59,15 +52,15 @@ int is_regular_file(const char *path) { char *get_sidecar_path(const char *path) { - const size_t path_len = strlen(path); - const size_t sidecar_ext_len = strlen(BINARY_SIDECAR_EXT); // this can be optimized - const size_t sidecar_path_len = path_len + sidecar_ext_len + 1; - char *sidecar_path = (char *) malloc(sidecar_path_len); - memset(sidecar_path, '\0', sidecar_path_len); - memcpy(sidecar_path, path, path_len); - memcpy(sidecar_path + path_len, BINARY_SIDECAR_EXT, sidecar_ext_len); - - return sidecar_path; +#define CFG xattrs_config + if ( strncmp( path, CFG.source_dir, CFG.source_dir_size ) == 0 ) { + const char *p = path + CFG.source_dir_size; + if ( CFG.sidecar_dir ) { + return strjoin( CFG.sidecar_dir, p, BINARY_SIDECAR_EXT, 0 ); + } + } + return strjoin( path, BINARY_SIDECAR_EXT, 0 ); +#undef CFG } // TODO: make it work for binary data diff --git a/xattrs_config.h b/xattrs_config.h index 347a61c..6d8be2a 100644 --- a/xattrs_config.h +++ b/xattrs_config.h @@ -13,9 +13,9 @@ extern struct xattrs_config { const int show_sidecar; const int enable_namespaces; + const char *sidecar_dir; const char *source_dir; size_t source_dir_size; - } xattrs_config;