summaryrefslogblamecommitdiffstats
path: root/cpukit/libfs/src/rfs/rtems-rfs-rtems-utils.c
blob: 44c8885bbeeb36e6502af7b992923fc70f6412f5 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
















                                                           



                   


















                                                                     
 






                             
 

















                                                                     
 



































































































                                                                      
                 






















                    
 






































                                                                       
 










                                             
/*
 *  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