From 4aca87515a5083ae0e31ce3177189fd43b6d05ac Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Sat, 3 Jan 2015 13:58:15 +0100 Subject: patch to Vanilla Tomato 1.28 --- release/src/router/busybox/e2fsprogs/e2fs_lib.c | 226 ++++++++++++++++++++++++ 1 file changed, 226 insertions(+) create mode 100644 release/src/router/busybox/e2fsprogs/e2fs_lib.c (limited to 'release/src/router/busybox/e2fsprogs/e2fs_lib.c') diff --git a/release/src/router/busybox/e2fsprogs/e2fs_lib.c b/release/src/router/busybox/e2fsprogs/e2fs_lib.c new file mode 100644 index 00000000..3e8d9568 --- /dev/null +++ b/release/src/router/busybox/e2fsprogs/e2fs_lib.c @@ -0,0 +1,226 @@ +/* vi: set sw=4 ts=4: */ +/* + * See README for additional information + * + * Licensed under GPLv2, see file LICENSE in this tarball for details. + */ + +#include "libbb.h" +#include "e2fs_lib.h" + +#define HAVE_EXT2_IOCTLS 1 + +#if INT_MAX == LONG_MAX +#define IF_LONG_IS_SAME(...) __VA_ARGS__ +#define IF_LONG_IS_WIDER(...) +#else +#define IF_LONG_IS_SAME(...) +#define IF_LONG_IS_WIDER(...) __VA_ARGS__ +#endif + +static void close_silently(int fd) +{ + int e = errno; + close(fd); + errno = e; +} + + +/* Iterate a function on each entry of a directory */ +int iterate_on_dir(const char *dir_name, + int (*func)(const char *, struct dirent *, void *), + void * private) +{ + DIR *dir; + struct dirent *de, *dep; + int max_len, len; + + max_len = PATH_MAX + sizeof(struct dirent); + de = xmalloc(max_len+1); + memset(de, 0, max_len+1); + + dir = opendir(dir_name); + if (dir == NULL) { + free(de); + return -1; + } + while ((dep = readdir(dir))) { + len = sizeof(struct dirent); + if (len < dep->d_reclen) + len = dep->d_reclen; + if (len > max_len) + len = max_len; + memcpy(de, dep, len); + func(dir_name, de, private); + } + closedir(dir); + free(de); + return 0; +} + + +/* Get/set a file version on an ext2 file system */ +int fgetsetversion(const char *name, unsigned long *get_version, unsigned long set_version) +{ +#if HAVE_EXT2_IOCTLS + int fd, r; + IF_LONG_IS_WIDER(int ver;) + + fd = open(name, O_NONBLOCK); + if (fd == -1) + return -1; + if (!get_version) { + IF_LONG_IS_WIDER( + ver = (int) set_version; + r = ioctl(fd, EXT2_IOC_SETVERSION, &ver); + ) + IF_LONG_IS_SAME( + r = ioctl(fd, EXT2_IOC_SETVERSION, (void*)&set_version); + ) + } else { + IF_LONG_IS_WIDER( + r = ioctl(fd, EXT2_IOC_GETVERSION, &ver); + *get_version = ver; + ) + IF_LONG_IS_SAME( + r = ioctl(fd, EXT2_IOC_GETVERSION, (void*)get_version); + ) + } + close_silently(fd); + return r; +#else /* ! HAVE_EXT2_IOCTLS */ + errno = EOPNOTSUPP; + return -1; +#endif /* ! HAVE_EXT2_IOCTLS */ +} + + +/* Get/set a file flags on an ext2 file system */ +int fgetsetflags(const char *name, unsigned long *get_flags, unsigned long set_flags) +{ +#if HAVE_EXT2_IOCTLS + struct stat buf; + int fd, r; + IF_LONG_IS_WIDER(int f;) + + if (stat(name, &buf) == 0 /* stat is ok */ + && !S_ISREG(buf.st_mode) && !S_ISDIR(buf.st_mode) + ) { + goto notsupp; + } + fd = open(name, O_NONBLOCK); /* neither read nor write asked for */ + if (fd == -1) + return -1; + + if (!get_flags) { + IF_LONG_IS_WIDER( + f = (int) set_flags; + r = ioctl(fd, EXT2_IOC_SETFLAGS, &f); + ) + IF_LONG_IS_SAME( + r = ioctl(fd, EXT2_IOC_SETFLAGS, (void*)&set_flags); + ) + } else { + IF_LONG_IS_WIDER( + r = ioctl(fd, EXT2_IOC_GETFLAGS, &f); + *get_flags = f; + ) + IF_LONG_IS_SAME( + r = ioctl(fd, EXT2_IOC_GETFLAGS, (void*)get_flags); + ) + } + + close_silently(fd); + return r; + notsupp: +#endif /* HAVE_EXT2_IOCTLS */ + errno = EOPNOTSUPP; + return -1; +} + + +/* Print file attributes on an ext2 file system */ +const uint32_t e2attr_flags_value[] = { +#ifdef ENABLE_COMPRESSION + EXT2_COMPRBLK_FL, + EXT2_DIRTY_FL, + EXT2_NOCOMPR_FL, + EXT2_ECOMPR_FL, +#endif + EXT2_INDEX_FL, + EXT2_SECRM_FL, + EXT2_UNRM_FL, + EXT2_SYNC_FL, + EXT2_DIRSYNC_FL, + EXT2_IMMUTABLE_FL, + EXT2_APPEND_FL, + EXT2_NODUMP_FL, + EXT2_NOATIME_FL, + EXT2_COMPR_FL, + EXT3_JOURNAL_DATA_FL, + EXT2_NOTAIL_FL, + EXT2_TOPDIR_FL +}; + +const char e2attr_flags_sname[] = +#ifdef ENABLE_COMPRESSION + "BZXE" +#endif + "I" + "suSDiadAcjtT"; + +static const char e2attr_flags_lname[] = +#ifdef ENABLE_COMPRESSION + "Compressed_File" "\0" + "Compressed_Dirty_File" "\0" + "Compression_Raw_Access" "\0" + "Compression_Error" "\0" +#endif + "Indexed_directory" "\0" + "Secure_Deletion" "\0" + "Undelete" "\0" + "Synchronous_Updates" "\0" + "Synchronous_Directory_Updates" "\0" + "Immutable" "\0" + "Append_Only" "\0" + "No_Dump" "\0" + "No_Atime" "\0" + "Compression_Requested" "\0" + "Journaled_Data" "\0" + "No_Tailmerging" "\0" + "Top_of_Directory_Hierarchies" "\0" + /* Another trailing NUL is added by compiler */; + +void print_e2flags(FILE *f, unsigned long flags, unsigned options) +{ + const uint32_t *fv; + const char *fn; + + fv = e2attr_flags_value; + if (options & PFOPT_LONG) { + int first = 1; + fn = e2attr_flags_lname; + do { + if (flags & *fv) { + if (!first) + fputs(", ", f); + fputs(fn, f); + first = 0; + } + fv++; + fn += strlen(fn) + 1; + } while (*fn); + if (first) + fputs("---", f); + } else { + fn = e2attr_flags_sname; + do { + char c = '-'; + if (flags & *fv) + c = *fn; + fputc(c, f); + fv++; + fn++; + } while (*fn); + } +} -- cgit v1.2.3-54-g00ecf