Esempio n. 1
0
void rtems_filesystem_eval_path_recursive(
  rtems_filesystem_eval_path_context_t *ctx,
  const char *path,
  size_t pathlen
)
{
  if (pathlen > 0) {
    if (ctx->recursionlevel < RTEMS_FILESYSTEM_SYMLOOP_MAX) {
      const char *saved_path = ctx->path;
      size_t saved_pathlen = ctx->pathlen;

      if (rtems_filesystem_is_delimiter(path [0])) {
        rtems_filesystem_eval_path_restart(ctx, &ctx->rootloc);
      }

      ctx->path = path;
      ctx->pathlen = pathlen;

      ++ctx->recursionlevel;
      while (ctx->pathlen > 0) {
        (*ctx->currentloc.mt_entry->ops->eval_path_h)(ctx);
      }
      --ctx->recursionlevel;

      ctx->path = saved_path;
      ctx->pathlen = saved_pathlen;
    } else {
      rtems_filesystem_eval_path_error(ctx, ELOOP);
    }
  } else {
    rtems_filesystem_eval_path_error(ctx, ENOENT);
  }
}
Esempio n. 2
0
static rtems_filesystem_eval_path_generic_status IMFS_eval_token(
  rtems_filesystem_eval_path_context_t *ctx,
  void *arg,
  const char *token,
  size_t tokenlen
)
{
  rtems_filesystem_eval_path_generic_status status =
    RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_DONE;
  rtems_filesystem_location_info_t *currentloc =
    rtems_filesystem_eval_path_get_currentloc( ctx );
  IMFS_jnode_t *dir = currentloc->node_access;
  bool access_ok = rtems_filesystem_eval_path_check_access(
    ctx,
    RTEMS_FS_PERMS_EXEC,
    dir->st_mode,
    dir->st_uid,
    dir->st_gid
  );

  if ( access_ok ) {
    IMFS_jnode_t *entry = IMFS_search_in_directory( dir, token, tokenlen );

    if ( entry != NULL ) {
      bool terminal = !rtems_filesystem_eval_path_has_path( ctx );
      int eval_flags = rtems_filesystem_eval_path_get_flags( ctx );
      bool follow_hard_link = (eval_flags & RTEMS_FS_FOLLOW_HARD_LINK) != 0;
      bool follow_sym_link = (eval_flags & RTEMS_FS_FOLLOW_SYM_LINK) != 0;
      IMFS_jnode_types_t type = IMFS_type( entry );

      rtems_filesystem_eval_path_clear_token( ctx );

      if ( type == IMFS_HARD_LINK && (follow_hard_link || !terminal)) {
        entry = entry->info.hard_link.link_node;
      }

      if ( type == IMFS_SYM_LINK && (follow_sym_link || !terminal)) {
        const char *target = entry->info.sym_link.name;

        rtems_filesystem_eval_path_recursive( ctx, target, strlen( target ) );
      } else {
        rtems_filesystem_global_location_t **fs_root_ptr =
          IMFS_is_mount_point( entry, type );

        if ( fs_root_ptr == NULL ) {
          --dir->reference_count;
          ++entry->reference_count;
          currentloc->node_access = entry;
          currentloc->node_access_2 =
            IMFS_generic_get_context_by_node( entry );
          IMFS_Set_handlers( currentloc );

          if ( !terminal ) {
            status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_CONTINUE;
          }
        } else {
          access_ok = rtems_filesystem_eval_path_check_access(
            ctx,
            RTEMS_FS_PERMS_EXEC,
            entry->st_mode,
            entry->st_uid,
            entry->st_gid
          );
          if ( access_ok ) {
            rtems_filesystem_eval_path_restart( ctx, fs_root_ptr );
          }
        }
      }
    } else {
      status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_NO_ENTRY;
    }
  }

  return status;
}