File indexing completed on 2025-05-11 08:24:17
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040 #ifdef HAVE_CONFIG_H
0041 #include "config.h"
0042 #endif
0043
0044 #include <rtems/imfs.h>
0045
0046 #include <string.h>
0047
0048 static bool IMFS_eval_is_directory(
0049 rtems_filesystem_eval_path_context_t *ctx,
0050 void *arg
0051 )
0052 {
0053 rtems_filesystem_location_info_t *currentloc =
0054 rtems_filesystem_eval_path_get_currentloc( ctx );
0055 IMFS_jnode_t *node = currentloc->node_access;
0056
0057 return IMFS_is_directory( node );
0058 }
0059
0060 static IMFS_jnode_t *IMFS_search_in_directory(
0061 IMFS_directory_t *dir,
0062 const char *token,
0063 size_t tokenlen
0064 )
0065 {
0066 if ( rtems_filesystem_is_current_directory( token, tokenlen ) ) {
0067 return &dir->Node;
0068 } else {
0069 if ( rtems_filesystem_is_parent_directory( token, tokenlen ) ) {
0070 return dir->Node.Parent;
0071 } else {
0072 rtems_chain_control *entries = &dir->Entries;
0073 rtems_chain_node *current = rtems_chain_first( entries );
0074 rtems_chain_node *tail = rtems_chain_tail( entries );
0075
0076 while ( current != tail ) {
0077 IMFS_jnode_t *entry = (IMFS_jnode_t *) current;
0078 bool match = entry->namelen == tokenlen
0079 && memcmp( entry->name, token, tokenlen ) == 0;
0080
0081 if ( match ) {
0082 return entry;
0083 }
0084
0085 current = rtems_chain_next( current );
0086 }
0087
0088 return NULL;
0089 }
0090 }
0091 }
0092
0093 static rtems_filesystem_global_location_t **IMFS_is_mount_point(
0094 IMFS_jnode_t *node,
0095 mode_t mode
0096 )
0097 {
0098 rtems_filesystem_global_location_t **fs_root_ptr = NULL;
0099
0100 if ( S_ISDIR( mode ) ) {
0101 IMFS_directory_t *dir = (IMFS_directory_t *) node;
0102
0103 if ( dir->mt_fs != NULL ) {
0104 fs_root_ptr = &dir->mt_fs->mt_fs_root;
0105 }
0106 }
0107
0108 return fs_root_ptr;
0109 }
0110
0111 static rtems_filesystem_eval_path_generic_status IMFS_eval_token(
0112 rtems_filesystem_eval_path_context_t *ctx,
0113 void *arg,
0114 const char *token,
0115 size_t tokenlen
0116 )
0117 {
0118 rtems_filesystem_eval_path_generic_status status =
0119 RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_DONE;
0120 rtems_filesystem_location_info_t *currentloc =
0121 rtems_filesystem_eval_path_get_currentloc( ctx );
0122 IMFS_directory_t *dir = currentloc->node_access;
0123 bool access_ok = rtems_filesystem_eval_path_check_access(
0124 ctx,
0125 RTEMS_FS_PERMS_EXEC,
0126 dir->Node.st_mode,
0127 dir->Node.st_uid,
0128 dir->Node.st_gid
0129 );
0130
0131 if ( access_ok ) {
0132 IMFS_jnode_t *entry = IMFS_search_in_directory( dir, token, tokenlen );
0133
0134 if ( entry != NULL ) {
0135 bool terminal = !rtems_filesystem_eval_path_has_path( ctx );
0136 int eval_flags = rtems_filesystem_eval_path_get_flags( ctx );
0137 bool follow_hard_link = (eval_flags & RTEMS_FS_FOLLOW_HARD_LINK) != 0;
0138 bool follow_sym_link = (eval_flags & RTEMS_FS_FOLLOW_SYM_LINK) != 0;
0139 mode_t mode = entry->st_mode;
0140
0141 rtems_filesystem_eval_path_clear_token( ctx );
0142
0143 if ( IMFS_is_hard_link( mode ) && ( follow_hard_link || !terminal ) ) {
0144 const IMFS_link_t *hard_link = (const IMFS_link_t *) entry;
0145
0146 entry = hard_link->link_node;
0147 }
0148
0149 if ( S_ISLNK( mode ) && ( follow_sym_link || !terminal ) ) {
0150 const IMFS_sym_link_t *sym_link = (const IMFS_sym_link_t *) entry;
0151 const char *target = sym_link->name;
0152
0153 rtems_filesystem_eval_path_recursive( ctx, target, strlen( target ) );
0154 } else {
0155 rtems_filesystem_global_location_t **fs_root_ptr =
0156 IMFS_is_mount_point( entry, mode );
0157
0158 if ( fs_root_ptr == NULL ) {
0159 --dir->Node.reference_count;
0160 ++entry->reference_count;
0161 currentloc->node_access = entry;
0162 currentloc->node_access_2 =
0163 IMFS_generic_get_context_by_node( entry );
0164 IMFS_Set_handlers( currentloc );
0165
0166 if ( !terminal ) {
0167 status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_CONTINUE;
0168 }
0169 } else {
0170 access_ok = rtems_filesystem_eval_path_check_access(
0171 ctx,
0172 RTEMS_FS_PERMS_EXEC,
0173 entry->st_mode,
0174 entry->st_uid,
0175 entry->st_gid
0176 );
0177 if ( access_ok ) {
0178 rtems_filesystem_eval_path_restart( ctx, fs_root_ptr );
0179 }
0180 }
0181 }
0182 } else {
0183 status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_NO_ENTRY;
0184 }
0185 }
0186
0187 return status;
0188 }
0189
0190 static const rtems_filesystem_eval_path_generic_config IMFS_eval_config = {
0191 .is_directory = IMFS_eval_is_directory,
0192 .eval_token = IMFS_eval_token
0193 };
0194
0195 void IMFS_eval_path( rtems_filesystem_eval_path_context_t *ctx )
0196 {
0197 rtems_filesystem_eval_path_generic( ctx, NULL, &IMFS_eval_config );
0198 }