diff --git a/dist/plugins-cfg/plugins.def.cfg b/dist/plugins-cfg/plugins.def.cfg index f220ed84e8..18ac49f727 100644 --- a/dist/plugins-cfg/plugins.def.cfg +++ b/dist/plugins-cfg/plugins.def.cfg @@ -232,6 +232,7 @@ io.winkd io.winedbg io.zip io.xalz +io.xattr io.r2k io.ar io.fd diff --git a/libr/include/r_io.h b/libr/include/r_io.h index 881f2a863f..426a0cbc95 100644 --- a/libr/include/r_io.h +++ b/libr/include/r_io.h @@ -585,6 +585,7 @@ extern RIOPlugin r_io_plugin_winedbg; extern RIOPlugin r_io_plugin_gprobe; extern RIOPlugin r_io_plugin_fd; extern RIOPlugin r_io_plugin_socket; +extern RIOPlugin r_io_plugin_xattr; extern RIOPlugin r_io_plugin_isotp; extern RIOPlugin r_io_plugin_xalz; diff --git a/libr/io/io_memory.c b/libr/io/io_memory.c index e4ebf7dbf8..94da7ed2b5 100644 --- a/libr/io/io_memory.c +++ b/libr/io/io_memory.c @@ -1,19 +1,15 @@ -/* radare - LGPL - Copyright 2008-2021 - pancake */ +/* radare - LGPL - Copyright 2008-2022 - pancake */ #include "io_memory.h" static inline ut32 _io_malloc_sz(RIODesc *desc) { - if (!desc) { - return 0; - } + r_return_val_if_fail (desc, 0); RIOMalloc *mal = (RIOMalloc*)desc->data; return mal? mal->size: 0; } static inline ut8* _io_malloc_buf(RIODesc *desc) { - if (!desc) { - return NULL; - } + r_return_val_if_fail (desc, NULL); RIOMalloc *mal = (RIOMalloc*)desc->data; return mal->buf; } @@ -29,23 +25,20 @@ static inline ut8* _io_malloc_set_buf(RIODesc *desc, ut8* buf) { #endif static inline ut64 _io_malloc_off(RIODesc *desc) { - if (!desc) { - return 0; - } + r_return_val_if_fail (desc, 0); RIOMalloc *mal = (RIOMalloc*)desc->data; return mal->offset; } static inline void _io_malloc_set_off(RIODesc *desc, ut64 off) { - if (!desc) { - return; - } + r_return_if_fail (desc); RIOMalloc *mal = (RIOMalloc*)desc->data; mal->offset = off; } int io_memory_write(RIO *io, RIODesc *fd, const ut8 *buf, int count) { - if (!fd || !buf || count < 0 || !fd->data) { + r_return_val_if_fail (io && fd && buf, -1); + if (count < 0 || !fd->data) { return -1; } if (_io_malloc_off (fd) > _io_malloc_sz (fd)) { @@ -63,7 +56,8 @@ int io_memory_write(RIO *io, RIODesc *fd, const ut8 *buf, int count) { } bool io_memory_resize(RIO *io, RIODesc *fd, ut64 count) { - if (!fd || !fd->data || count == 0) { + r_return_val_if_fail (io && fd, false); + if (count == 0) { // TODO: why cant truncate to 0 bytes return false; } ut32 mallocsz = _io_malloc_sz (fd); @@ -84,8 +78,9 @@ bool io_memory_resize(RIO *io, RIODesc *fd, ut64 count) { } int io_memory_read(RIO *io, RIODesc *fd, ut8 *buf, int count) { + r_return_val_if_fail (io && fd && buf, -1); memset (buf, 0xff, count); - if (!fd || !fd->data) { + if (!fd->data) { return -1; } ut32 mallocsz = _io_malloc_sz (fd); @@ -101,17 +96,17 @@ int io_memory_read(RIO *io, RIODesc *fd, ut8 *buf, int count) { } bool io_memory_close(RIODesc *fd) { - RIOMalloc *riom; if (!fd || !fd->data) { return false; } - riom = fd->data; + RIOMalloc *riom = fd->data; R_FREE (riom->buf); R_FREE (fd->data); return true; } ut64 io_memory_lseek(RIO* io, RIODesc *fd, ut64 offset, int whence) { + r_return_val_if_fail (io && fd, offset); ut64 r_offset = offset; if (!fd || !fd->data) { return offset; diff --git a/libr/io/meson.build b/libr/io/meson.build index 5ae429f683..152f618a49 100644 --- a/libr/io/meson.build +++ b/libr/io/meson.build @@ -26,6 +26,7 @@ r_io_sources = [ 'p/io_ihex.c', 'p/io_mach.c', 'p/io_malloc.c', + 'p/io_xattr.c', 'p/io_xalz.c', 'p/io_mmap.c', 'p/io_null.c', diff --git a/libr/io/p/io_gzip.c b/libr/io/p/io_gzip.c index 599f622a88..af056b6172 100644 --- a/libr/io/p/io_gzip.c +++ b/libr/io/p/io_gzip.c @@ -127,7 +127,7 @@ static bool __close(RIODesc *fd) { } RIOGzip *riom = fd->data; if (riom->has_changed) { - eprintf ("TODO: Writing changes into gzipped files is not yet supported\n"); + R_LOG_ERROR ("TODO: Writing changes into gzipped files is not yet supported"); } R_FREE (riom->buf); R_FREE (fd->data); diff --git a/libr/io/p/io_xattr.c b/libr/io/p/io_xattr.c new file mode 100644 index 0000000000..2d0338452c --- /dev/null +++ b/libr/io/p/io_xattr.c @@ -0,0 +1,148 @@ +/* radare - LGPL - Copyright 2022 - pancake */ + +#include +#include +#include "../io_memory.h" + +#if 0 +#define HAS_XATTR 0 +#elif __APPLE__ +#define HAS_XATTR 1 +# define r_listxattr(x,y,z) listxattr(x,y,z,0) +# define r_getxattr(x,y,z,u) getxattr(x,y,z,u,0,0) +# define r_setxattr(x,y,z,u,v) setxattr(x,y,z,u,v,0) +#elif __linux__ +#define HAS_XATTR 1 +# define r_listxattr listxattr +# define r_getxattr getxattr +# define r_setxattr setxattr +#else +#define HAS_XATTR 0 +#endif + +#if HAS_XATTR + +#include + +static bool __check(RIO *io, const char *pathname, bool many) { + return r_str_startswith (pathname, "xattr://"); +} + +static void list_xattr(const char *path) { + int total = r_listxattr (path, NULL, -1); + if (total < 1) { + return; + } + char *namebuf = malloc (total); + if (!namebuf) { + return; + } + int i, res = r_listxattr (path, namebuf, total); + for (i = 0; i < res; i++) { + const char *n = namebuf + i; + printf ("%s\n", n); + i += strlen (n); + } + free (namebuf); +} + +static bool write_xattr(const char *path, const char *attrname, const ut8 *data, size_t size) { + return r_setxattr (path, attrname, data, size, 0) == 0; +} + +static char *read_xattr(const char *path, const char *attrname, int *osize) { + int size = r_getxattr (path, attrname, NULL, -1); + if (size < 1) { + return NULL; + } + char *buf = calloc (size, 1); + r_getxattr (path, attrname, buf, size); + *osize = size; + return buf; +} + +static RIODesc *__open(RIO *io, const char *pathname, int rw, int mode) { + if (!__check (io, pathname, 0)) { + return NULL; + } + char *path = strdup (pathname + 8); + char *attrname = strstr (path, "//"); + if (!attrname) { + list_xattr (path); + free (path); + return NULL; + } + *attrname = 0; + attrname += 2; + + int size = 0; + char *attrvalue = read_xattr (path, attrname, &size); + free (path); + if (!attrvalue || size < 1) { + return NULL; + } + + RIOMalloc *mal = R_NEW0 (RIOMalloc); + if (!mal) { + return NULL; + } + mal->size = size; + mal->buf = (ut8*)attrvalue; + mal->offset = 0; + if (mal->buf) { + return r_io_desc_new (io, &r_io_plugin_xattr, pathname, R_PERM_RW | rw, mode, mal); + } + R_LOG_ERROR ("Cannot allocate %d bytes for %s", mal->size, pathname); + free (mal); + return NULL; +} + +static bool __close(RIODesc *fd) { + RIOMalloc *riom = fd->data; + const char *pathname = fd->name; + char *path = strdup (pathname + 8); + char *attrname = strstr (path, "//"); + if (!attrname) { + // should never happen, but just in case + return NULL; + } + *attrname = 0; + attrname += 2; + write_xattr (path, attrname, (const ut8*)riom->buf, riom->size); + free (path); + io_memory_close (fd); + return true; +} + +RIOPlugin r_io_plugin_xattr = { + .name = "xattr", + .desc = "access extended file attribute", + .author = "pancake", + .uris = "xattr://", + .license = "LGPL3", + .open = __open, + .close = __close, + .read = io_memory_read, + .check = __check, + .seek = io_memory_lseek, + .write = io_memory_write, + .resize = io_memory_resize, +}; + +#else // HAS_XATTR + +RIOPlugin r_io_plugin_xattr = { + .name = "xattr", + .desc = "access extended file attribute (not supported)", + .uris = "xattr://", + .license = "LGPL3", +}; +#endif + +#ifndef R2_PLUGIN_INCORE +R_API RLibStruct radare_plugin = { + .type = R_LIB_TYPE_IO, + .data = &r_io_plugin_xattr, + .version = R2_VERSION +}; +#endif diff --git a/libr/io/p/xattr.mk b/libr/io/p/xattr.mk new file mode 100644 index 0000000000..e49ee500b3 --- /dev/null +++ b/libr/io/p/xattr.mk @@ -0,0 +1,17 @@ +OBJ_XATTR=io_xattr.o + +STATIC_OBJ+=${OBJ_XATTR} +TARGET_XATTR=io_xattr.${EXT_SO} +ALL_TARGETS+=${TARGET_XATTR} + +ifeq (${WITHPIC},0) +LINKFLAGS+=../../util/libr_util.a +LINKFLAGS+=../../io/libr_io.a +else +LINKFLAGS+=-L../../util -lr_util +LINKFLAGS+=-L.. -lr_io +endif + +${TARGET_XATTR}: ${OBJ_XATTR} + ${CC_LIB} $(call libname,io_xattr) ${CFLAGS} -o ${TARGET_XATTR} \ + ${LDFLAGS} ${OBJ_XATTR} ${LINKFLAGS} diff --git a/libr/meson.build b/libr/meson.build index 52eb915cb7..15552a4850 100644 --- a/libr/meson.build +++ b/libr/meson.build @@ -8,7 +8,7 @@ anal_plugins = [ 'null' ] bin_plugins = [ 'any' ] bin_ldr_plugins = [ 'ldr_linux' ] bin_xtr_plugins = [ 'xtr_sep64' ] -io_plugins = [ 'malloc', 'fd', 'default', 'null', 'rbuf', 'r2pipe' , 'r2pipe'] +io_plugins = [ 'malloc', 'xattr', 'fd', 'default', 'null', 'rbuf', 'r2pipe' , 'r2pipe'] fs_plugins = [ 'r2', 'posix', 'io' ] bp_plugins = [ 'bf' ] crypto_plugins = [ 'xor', 'punycode' ]