diff options
Diffstat (limited to 'cpukit/libfs/src/rfs/rtems-rfs-rtems-utils.c')
-rw-r--r-- | cpukit/libfs/src/rfs/rtems-rfs-rtems-utils.c | 244 |
1 files changed, 244 insertions, 0 deletions
diff --git a/cpukit/libfs/src/rfs/rtems-rfs-rtems-utils.c b/cpukit/libfs/src/rfs/rtems-rfs-rtems-utils.c new file mode 100644 index 0000000000..2c8ba591f2 --- /dev/null +++ b/cpukit/libfs/src/rfs/rtems-rfs-rtems-utils.c @@ -0,0 +1,244 @@ +/* + * COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ +/** + * @file + * + * @ingroup rtems-rfs + * + * Set of utility functions to support RTEMS RFS on RTEMS. + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <sys/types.h> +#include <sys/stat.h> +#include <stdlib.h> + +#include "rtems-rfs-rtems.h" + +bool +rtems_rfs_rtems_eval_perms (rtems_rfs_inode_handle* inode, int flags) +{ + uid_t st_uid; + gid_t st_gid; + uint16_t uid; + uint16_t gid; + uint16_t mode; + int flags_to_test; + + uid = rtems_rfs_inode_get_uid (inode); + gid = rtems_rfs_inode_get_gid (inode); + mode = rtems_rfs_inode_get_mode (inode); + +#if defined (RTEMS_POSIX_API) + st_uid = geteuid (); + st_gid = getegid (); +#else + st_uid = uid; + st_gid = gid; +#endif + + /* + * Check if I am owner or a group member or someone else. + */ + flags_to_test = flags; + + if ((st_uid == 0) || (st_uid == uid)) + flags_to_test |= flags << 6; + if ((st_uid == 0) || (st_gid == gid)) + flags_to_test |= flags << 3; + else + /* must be other - already set above */; + + if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_EVAL_PERMS)) + printf ("rtems-rfs: eval-perms: uid=%d gid=%d iuid=%d igid=%d " \ + "flags=%o flags_to_test=%o mode=%o (%o)\n", + st_uid, st_gid, uid, gid, + flags, flags_to_test, mode & 0777, + flags_to_test & (mode & 0777)); + + /* + * If all of the flags are set we have permission + * to do this. + */ + if ((flags_to_test & (mode & 0777)) != 0) + return true; + + if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_EVAL_PERMS)) + printf("rtems-rfs: eval-perms: perms failed\n"); + + return false; +} + +/* + * The following sets the handlers based on the type of inode. + */ + +bool +rtems_rfs_rtems_set_handlers (rtems_filesystem_location_info_t* loc, + rtems_rfs_inode_handle* inode) +{ + uint16_t mode = rtems_rfs_inode_get_mode (inode); + loc->handlers = NULL; + if (RTEMS_RFS_S_ISDIR (mode)) + loc->handlers = rtems_rfs_rtems_handlers (dir); + else if (RTEMS_RFS_S_ISCHR (mode) || RTEMS_RFS_S_ISBLK(mode)) + loc->handlers = rtems_rfs_rtems_handlers (device); + else if (RTEMS_RFS_S_ISLNK (mode)) + loc->handlers = rtems_rfs_rtems_handlers (link); + else if (RTEMS_RFS_S_ISREG (mode)) + loc->handlers = rtems_rfs_rtems_handlers (file); + else + { + printf ("rtems-rfs: mode type unknown: %04x\n", mode); + return false; + } + return true; +} + +uint16_t +rtems_rfs_rtems_imode (mode_t mode) +{ + /* + * Mapping matches RTEMS so no need to change. + */ + return mode; +} + +mode_t +rtems_rfs_rtems_mode (int imode) +{ + /* + * Mapping matches RTEMS so no need to change. + */ + return imode; +} + +/* + * Only provide if there is no macro version. + */ +#if !defined (rtems_rfs_rtems_error) +int +rtems_rfs_rtems_error (const char* mesg, int error) +{ + if (error) + printf ("rtems-rfs: %s: %d: %s\n", mesg, error, strerror (error)); + errno = error; + return error == 0 ? 0 : -1; +} +#endif + +#if RTEMS_RFS_RTEMS_TRACE +static uint32_t rtems_rfs_rtems_trace_mask; + +bool +rtems_rfs_rtems_trace (uint32_t mask) +{ + bool result = false; + if (mask & rtems_rfs_rtems_trace_mask) + result = true; + return result; +} + +void +rtems_rfs_trace_rtems_set_mask (uint32_t mask) +{ + rtems_rfs_rtems_trace_mask |= mask; +} + +void +rtems_rfs_trace_rtems_clear_mask (uint32_t mask) +{ + rtems_rfs_rtems_trace_mask &= ~mask; +} + +int +rtems_rfs_rtems_trace_shell_command (int argc, char *argv[]) +{ + const char* table[] = + { + "error-msgs", + "eval-path" + "eval-for-make", + "eval-perms", + "mknod", + "rmnod", + "link", + "unlink", + "chown", + "readlink", + "fchmod", + "stat", + "dir-rmnod", + "file-open", + "file-close", + "file-read", + "file-write", + "file-lseek", + "file-ftrunc" + }; + + bool set = true; + int arg; + int t; + + for (arg = 1; arg < argc; arg++) + { + if (argv[arg][0] == '-') + { + switch (argv[arg][1]) + { + case 'h': + printf ("usage: %s [-hl] [set/clear] [flags]\n", argv[0]); + return 0; + case 'l': + printf ("%s: valid flags to set or clear are:\n", argv[0]); + for (t = 0; t < (sizeof (table) / sizeof (const char*)); t++) + printf (" %s\n", table[t]); + return 0; + default: + printf ("error: unknown option\n"); + return 1; + } + } + else + { + uint32_t value = 0; + if (strcmp (argv[arg], "set") == 0) + set = true; + if (strcmp (argv[arg], "clear") == 0) + set = false; + else if (strcmp (argv[arg], "all") == 0) + value = RTEMS_RFS_RTEMS_DEBUG_ALL; + else + { + for (t = 0; t < (sizeof (table) / sizeof (const char*)); t++) + { + if (strcmp (argv[arg], table[t]) == 0) + { + value = 1 << t; + break; + } + } + } + + if (set) + rtems_rfs_rtems_trace_mask |= value; + else + rtems_rfs_rtems_trace_mask &= ~value; + } + } + + return 0; +} + +#endif |