static void rtems_rfs_rtems_eval_path (rtems_filesystem_eval_path_context_t *ctx) { rtems_filesystem_location_info_t *currentloc = rtems_filesystem_eval_path_get_currentloc (ctx); rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (currentloc); rtems_rfs_ino ino = rtems_rfs_rtems_get_pathloc_ino (currentloc); rtems_rfs_inode_handle inode; int rc; rc = rtems_rfs_inode_open (fs, ino, &inode, true); if (rc == 0) { rtems_filesystem_eval_path_generic ( ctx, &inode, &rtems_rfs_rtems_eval_config ); rc = rtems_rfs_inode_close (fs, &inode); if (rc != 0) { rtems_filesystem_eval_path_error ( ctx, rtems_rfs_rtems_error ("eval_path: closing inode", rc) ); } } else { rtems_filesystem_eval_path_error ( ctx, rtems_rfs_rtems_error ("eval_path: opening inode", rc) ); } }
static void create_regular_file( rtems_filesystem_eval_path_context_t *ctx, mode_t mode ) { int rv = 0; const rtems_filesystem_location_info_t *currentloc = rtems_filesystem_eval_path_get_currentloc( ctx ); const char *token = rtems_filesystem_eval_path_get_token( ctx ); size_t tokenlen = rtems_filesystem_eval_path_get_tokenlen( ctx ); rv = rtems_filesystem_mknod( currentloc, token, tokenlen, S_IFREG | mode, 0 ); if ( rv == 0 ) { /* The mode only applies to future accesses of the newly created file */ rtems_filesystem_eval_path_set_flags( ctx, 0 ); rtems_filesystem_eval_path_set_path( ctx, token, tokenlen ); rtems_filesystem_eval_path_continue( ctx ); } else { rtems_filesystem_eval_path_error( ctx, 0 ); } }
static void rtems_ftpfs_eval_path( rtems_filesystem_eval_path_context_t *self ) { rtems_filesystem_eval_path_eat_delimiter(self); if (rtems_filesystem_eval_path_has_path(self)) { const char *path = rtems_filesystem_eval_path_get_path(self); size_t pathlen = rtems_filesystem_eval_path_get_pathlen(self); char *pathdup = malloc(pathlen + 1); rtems_filesystem_eval_path_clear_path(self); if (pathdup != NULL) { rtems_filesystem_location_info_t *currentloc = rtems_filesystem_eval_path_get_currentloc(self); memcpy(pathdup, path, pathlen); pathdup [pathlen] = '\0'; currentloc->node_access = pathdup; currentloc->handlers = &rtems_ftpfs_handlers; } else { rtems_filesystem_eval_path_error(self, ENOMEM); } } }
static rtems_filesystem_eval_path_generic_status msdos_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; if (rtems_filesystem_is_current_directory(token, tokenlen)) { rtems_filesystem_eval_path_clear_token(ctx); status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_CONTINUE; } else { rtems_filesystem_location_info_t *currentloc = rtems_filesystem_eval_path_get_currentloc(ctx); int rc = msdos_find_name(currentloc, token, tokenlen); if (rc == RC_OK) { rtems_filesystem_eval_path_clear_token(ctx); msdos_set_handlers(currentloc); if (rtems_filesystem_eval_path_has_path(ctx)) { status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_CONTINUE; } } else if (rc == MSDOS_NAME_NOT_FOUND_ERR) { status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_NO_ENTRY; } else { rtems_filesystem_eval_path_error(ctx, 0); } } return status; }
static bool rtems_jffs2_eval_is_directory( rtems_filesystem_eval_path_context_t *ctx, void *arg ) { rtems_filesystem_location_info_t *currentloc = rtems_filesystem_eval_path_get_currentloc(ctx); struct _inode *inode = rtems_jffs2_get_inode_by_location(currentloc); return S_ISDIR(inode->i_mode); }
static bool IMFS_eval_is_directory( rtems_filesystem_eval_path_context_t *ctx, void *arg ) { rtems_filesystem_location_info_t *currentloc = rtems_filesystem_eval_path_get_currentloc( ctx ); IMFS_jnode_t *node = currentloc->node_access; return IMFS_is_directory( node ); }
static bool msdos_is_directory( rtems_filesystem_eval_path_context_t *ctx, void *arg ) { rtems_filesystem_location_info_t *currentloc = rtems_filesystem_eval_path_get_currentloc( ctx ); fat_file_fd_t *fat_fd = currentloc->node_access; return fat_fd->fat_file_type == MSDOS_DIRECTORY; }
static void rtems_tfs_eval_path(rtems_filesystem_eval_path_context_t *self) { int eval_flags = rtems_filesystem_eval_path_get_flags(self); if ((eval_flags & RTEMS_FS_MAKE) == 0) { int rw = RTEMS_FS_PERMS_READ | RTEMS_FS_PERMS_WRITE; if ((eval_flags & rw) != rw) { rtems_filesystem_location_info_t *currentloc = rtems_filesystem_eval_path_get_currentloc(self); char *current = currentloc->node_access; size_t currentlen = strlen(current); const char *path = rtems_filesystem_eval_path_get_path(self); size_t pathlen = rtems_filesystem_eval_path_get_pathlen(self); size_t len = currentlen + pathlen; rtems_filesystem_eval_path_clear_path(self); current = realloc(current, len + 1); if (current != NULL) { memcpy(current + currentlen, path, pathlen); current [len] = '\0'; if (!rtems_tfs_is_directory(current, len)) { fixPath (current); } currentloc->node_access = current; } else { rtems_filesystem_eval_path_error(self, ENOMEM); } } else { rtems_filesystem_eval_path_error(self, EINVAL); } } else { rtems_filesystem_eval_path_error(self, EIO); } }
static rtems_filesystem_eval_path_generic_status rtems_jffs2_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); struct _inode *dir_i = rtems_jffs2_get_inode_by_location(currentloc); bool access_ok = rtems_filesystem_eval_path_check_access( ctx, RTEMS_FS_PERMS_EXEC, dir_i->i_mode, dir_i->i_uid, dir_i->i_gid ); if (access_ok) { struct _inode *entry_i; if (rtems_filesystem_is_current_directory(token, tokenlen)) { entry_i = dir_i; ++entry_i->i_count; } else if (rtems_filesystem_is_parent_directory(token, tokenlen)) { entry_i = dir_i->i_parent; ++entry_i->i_count; } else { entry_i = jffs2_lookup(dir_i, token, (int) tokenlen); } if (IS_ERR(entry_i)) { rtems_filesystem_eval_path_error(ctx, PTR_ERR(entry_i)); } else if (entry_i != NULL) { bool terminal = !rtems_filesystem_eval_path_has_path(ctx); int eval_flags = rtems_filesystem_eval_path_get_flags(ctx); bool follow_sym_link = (eval_flags & RTEMS_FS_FOLLOW_SYM_LINK) != 0; rtems_filesystem_eval_path_clear_token(ctx); if (S_ISLNK(entry_i->i_mode) && (follow_sym_link || !terminal)) { struct jffs2_inode_info *f = JFFS2_INODE_INFO(entry_i); const char *target = f->target; rtems_filesystem_eval_path_recursive(ctx, target, strlen(target)); jffs2_iput(entry_i); } else { if (S_ISDIR(entry_i->i_mode) && entry_i->i_parent == NULL) { entry_i->i_parent = dir_i; ++dir_i->i_count; } jffs2_iput(dir_i); rtems_jffs2_set_location(currentloc, entry_i); if (rtems_filesystem_eval_path_has_path(ctx)) { status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_CONTINUE; } } } else { status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_NO_ENTRY; } } return status; }
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; }
static rtems_filesystem_eval_path_generic_status rtems_rfs_rtems_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_rfs_inode_handle* inode = arg; bool access_ok = rtems_rfs_rtems_eval_perms (ctx, RTEMS_FS_PERMS_EXEC, inode); if (access_ok) { if (rtems_filesystem_is_current_directory (token, tokenlen)) { rtems_filesystem_eval_path_clear_token (ctx); } else { rtems_filesystem_location_info_t *currentloc = rtems_filesystem_eval_path_get_currentloc( ctx ); rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (currentloc); rtems_rfs_ino entry_ino; uint32_t entry_doff; int rc = rtems_rfs_dir_lookup_ino ( fs, inode, token, tokenlen, &entry_ino, &entry_doff ); if (rc == 0) { rc = rtems_rfs_inode_close (fs, inode); if (rc == 0) { rc = rtems_rfs_inode_open (fs, entry_ino, inode, true); } if (rc != 0) { /* * This prevents the rtems_rfs_inode_close() from doing something in * rtems_rfs_rtems_eval_path(). */ memset (inode, 0, sizeof(*inode)); } } else { status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_NO_ENTRY; rc = -1; } if (rc == 0) { bool is_sym_link = rtems_rfs_rtems_node_type_by_inode (inode) == RTEMS_FILESYSTEM_SYM_LINK; int eval_flags = rtems_filesystem_eval_path_get_flags (ctx); bool follow_sym_link = (eval_flags & RTEMS_FS_FOLLOW_SYM_LINK) != 0; bool terminal = !rtems_filesystem_eval_path_has_path (ctx); rtems_filesystem_eval_path_clear_token (ctx); if (is_sym_link && (follow_sym_link || !terminal)) { rtems_rfs_rtems_follow_link (ctx, fs, entry_ino); } else { rc = rtems_rfs_rtems_set_handlers (currentloc, inode) ? 0 : EIO; if (rc == 0) { rtems_rfs_rtems_set_pathloc_ino (currentloc, entry_ino); rtems_rfs_rtems_set_pathloc_doff (currentloc, entry_doff); if (!terminal) { status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_CONTINUE; } } else { rtems_filesystem_eval_path_error ( ctx, rtems_rfs_rtems_error ("eval_path: set handlers", rc) ); } } } } } return status; }
static int do_open( rtems_libio_t *iop, const char *path, int oflag, mode_t mode ) { int rv = 0; int fd = rtems_libio_iop_to_descriptor( iop ); int rwflag = oflag + 1; bool read_access = (rwflag & _FREAD) == _FREAD; bool write_access = (rwflag & _FWRITE) == _FWRITE; bool make = (oflag & O_CREAT) == O_CREAT; bool exclusive = (oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL); bool truncate = (oflag & O_TRUNC) == O_TRUNC; int eval_flags = RTEMS_FS_FOLLOW_LINK | (read_access ? RTEMS_FS_PERMS_READ : 0) | (write_access ? RTEMS_FS_PERMS_WRITE : 0) | (make ? RTEMS_FS_MAKE : 0) | (exclusive ? RTEMS_FS_EXCLUSIVE : 0); rtems_filesystem_eval_path_context_t ctx; rtems_filesystem_eval_path_start( &ctx, path, eval_flags ); if ( rtems_filesystem_eval_path_has_token( &ctx ) ) { create_regular_file( &ctx, mode ); } if ( write_access ) { const rtems_filesystem_location_info_t *currentloc = rtems_filesystem_eval_path_get_currentloc( &ctx ); mode_t type = rtems_filesystem_location_type( currentloc ); if ( S_ISDIR( type ) ) { rtems_filesystem_eval_path_error( &ctx, EISDIR ); } } iop->flags |= rtems_libio_fcntl_flags( oflag ); rtems_filesystem_eval_path_extract_currentloc( &ctx, &iop->pathinfo ); rtems_filesystem_eval_path_cleanup( &ctx ); rv = (*iop->pathinfo.handlers->open_h)( iop, path, oflag, mode ); if ( rv == 0 ) { if ( truncate ) { rv = ftruncate( fd, 0 ); if ( rv != 0 ) { (*iop->pathinfo.handlers->close_h)( iop ); } } if ( rv == 0 ) { rv = fd; } else { rv = -1; } } if ( rv < 0 ) { rtems_libio_free( iop ); } return rv; }