source: rtems/cpukit/libfs/src/imfs/imfs_eval.c @ 2563410

4.115
Last change on this file since 2563410 was 2563410, checked in by Sebastian Huber <sebastian.huber@…>, on 03/13/12 at 08:22:11

Filesystem: Rename defines

o Removed RTEMS_LIBIO_PERMS_SEARCH.
o Renamed RTEMS_LIBIO_PERMS_READ in RTEMS_FS_PERMS_READ.
o Renamed RTEMS_LIBIO_PERMS_WRITE in RTEMS_FS_PERMS_WRITE.
o Renamed RTEMS_LIBIO_PERMS_EXEC in RTEMS_FS_PERMS_EXEC.
o Renamed RTEMS_LIBIO_FOLLOW_HARD_LINK in RTEMS_FS_FOLLOW_HARD_LINK.
o Renamed RTEMS_LIBIO_FOLLOW_SYM_LINK in RTEMS_FS_FOLLOW_SYM_LINK.
o Renamed RTEMS_LIBIO_MAKE in RTEMS_FS_MAKE.
o Renamed RTEMS_LIBIO_EXCLUSIVE in RTEMS_FS_EXCLUSIVE.
o Renamed RTEMS_LIBIO_ACCEPT_RESIDUAL_DELIMITERS in

RTEMS_FS_ACCEPT_RESIDUAL_DELIMITERS.

o Renamed RTEMS_LIBIO_REJECT_TERMINAL_DOT in
RTEMS_FS_REJECT_TERMINAL_DOT.

  • Property mode set to 100644
File size: 5.1 KB
Line 
1/*
2 *  Evaluation IMFS Node Support Routines
3 *
4 *  COPYRIGHT (c) 1989-1999.
5 *  On-Line Applications Research Corporation (OAR).
6 *
7 *  Modifications to support reference counting in the file system are
8 *  Copyright (c) 2012 embedded brains GmbH.
9 *
10 *  The license and distribution terms for this file may be
11 *  found in the file LICENSE in this distribution or at
12 *  http://www.rtems.com/license/LICENSE.
13 */
14
15#if HAVE_CONFIG_H
16  #include "config.h"
17#endif
18
19#include "imfs.h"
20
21void IMFS_Set_handlers( rtems_filesystem_location_info_t *loc )
22{
23  IMFS_jnode_t *node = loc->node_access;
24  IMFS_fs_info_t *fs_info = loc->mt_entry->fs_info;
25  const rtems_filesystem_file_handlers_r *handlers;
26
27  switch ( node->type ) {
28    case IMFS_DIRECTORY:
29      handlers = &IMFS_directory_handlers;
30      break;
31    case IMFS_DEVICE:
32      handlers = &IMFS_device_handlers;
33      break;
34    case IMFS_HARD_LINK:
35    case IMFS_SYM_LINK:
36      handlers = fs_info->link_handlers;
37      break;
38    case IMFS_MEMORY_FILE:
39    case IMFS_LINEAR_FILE:
40      handlers = &IMFS_memfile_handlers;
41      break;
42    case IMFS_FIFO:
43      handlers = fs_info->fifo_handlers;
44      break;
45    default:
46      IMFS_assert( 0 );
47      break;
48  }
49
50  loc->handlers = handlers;
51}
52
53static bool IMFS_is_directory(
54  rtems_filesystem_eval_path_context_t *ctx,
55  void *arg
56)
57{
58  rtems_filesystem_location_info_t *currentloc =
59    rtems_filesystem_eval_path_get_currentloc( ctx );
60  IMFS_jnode_t *node = currentloc->node_access;
61
62  return node->type == IMFS_DIRECTORY;
63}
64
65static IMFS_jnode_t *IMFS_search_in_directory(
66  IMFS_jnode_t *dir,
67  const char *token,
68  size_t tokenlen
69)
70{
71  if ( rtems_filesystem_is_current_directory( token, tokenlen ) ) {
72    return dir;
73  } else {
74    if ( rtems_filesystem_is_parent_directory( token, tokenlen ) ) {
75      return dir->Parent;
76    } else {
77      rtems_chain_control *entries = &dir->info.directory.Entries;
78      rtems_chain_node *current = rtems_chain_first( entries );
79      rtems_chain_node *tail = rtems_chain_tail( entries );
80
81      while ( current != tail ) {
82        IMFS_jnode_t *entry = (IMFS_jnode_t *) current;
83        bool match = strncmp( entry->name, token, tokenlen ) == 0
84          && entry->name [tokenlen] == '\0';
85
86        if ( match ) {
87          return entry;
88        }
89
90        current = rtems_chain_next( current );
91      }
92
93      return NULL;
94    }
95  }
96}
97
98static rtems_filesystem_global_location_t **IMFS_is_mount_point(
99  IMFS_jnode_t *node
100)
101{
102  rtems_filesystem_global_location_t **fs_root_ptr = NULL;
103
104  if ( node->type == IMFS_DIRECTORY ) {
105    if ( node->info.directory.mt_fs != NULL ) {
106      fs_root_ptr = &node->info.directory.mt_fs->mt_fs_root;
107    }
108  }
109
110  return fs_root_ptr;
111}
112
113static rtems_filesystem_eval_path_generic_status IMFS_eval_token(
114  rtems_filesystem_eval_path_context_t *ctx,
115  void *arg,
116  const char *token,
117  size_t tokenlen
118)
119{
120  rtems_filesystem_eval_path_generic_status status =
121    RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_DONE;
122  rtems_filesystem_location_info_t *currentloc =
123    rtems_filesystem_eval_path_get_currentloc( ctx );
124  IMFS_jnode_t *dir = currentloc->node_access;
125  bool access_ok = rtems_filesystem_eval_path_check_access(
126    ctx,
127    RTEMS_FS_PERMS_EXEC,
128    dir->st_mode,
129    dir->st_uid,
130    dir->st_gid
131  );
132
133  if ( access_ok ) {
134    IMFS_jnode_t *entry = IMFS_search_in_directory( dir, token, tokenlen );
135
136    if ( entry != NULL ) {
137      bool terminal = !rtems_filesystem_eval_path_has_path( ctx );
138      int eval_flags = rtems_filesystem_eval_path_get_flags( ctx );
139      bool follow_hard_link = (eval_flags & RTEMS_FS_FOLLOW_HARD_LINK) != 0;
140      bool follow_sym_link = (eval_flags & RTEMS_FS_FOLLOW_SYM_LINK) != 0;
141
142      rtems_filesystem_eval_path_clear_token( ctx );
143
144      if ( entry->type == IMFS_HARD_LINK && (follow_hard_link || !terminal)) {
145        entry = entry->info.hard_link.link_node;
146      }
147
148      if ( entry->type == IMFS_SYM_LINK && (follow_sym_link || !terminal)) {
149        const char *target = entry->info.sym_link.name;
150
151        rtems_filesystem_eval_path_recursive( ctx, target, strlen( target ) );
152      } else {
153        rtems_filesystem_global_location_t **fs_root_ptr =
154          IMFS_is_mount_point( entry );
155
156        if ( fs_root_ptr == NULL ) {
157          currentloc->node_access = entry;
158          IMFS_Set_handlers( currentloc );
159
160          if ( !terminal ) {
161            status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_CONTINUE;
162          }
163        } else {
164          access_ok = rtems_filesystem_eval_path_check_access(
165            ctx,
166            RTEMS_FS_PERMS_EXEC,
167            entry->st_mode,
168            entry->st_uid,
169            entry->st_gid
170          );
171          if ( access_ok ) {
172            rtems_filesystem_eval_path_restart( ctx, fs_root_ptr );
173          }
174        }
175      }
176    } else {
177      status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_NO_ENTRY;
178    }
179  }
180
181  return status;
182}
183
184static const rtems_filesystem_eval_path_generic_config IMFS_eval_config = {
185  .is_directory = IMFS_is_directory,
186  .eval_token = IMFS_eval_token
187};
188
189void IMFS_eval_path( rtems_filesystem_eval_path_context_t *ctx )
190{
191  rtems_filesystem_eval_path_generic( ctx, NULL, &IMFS_eval_config );
192}
Note: See TracBrowser for help on using the repository browser.