Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:15

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  *  @file
0005  *
0006  *  @brief RTEMS File System Eval Generic Path
0007  *  @ingroup LibIOInternal
0008  */
0009 
0010 /*
0011  * Copyright (c) 2012 embedded brains GmbH & Co. KG
0012  *
0013  * Redistribution and use in source and binary forms, with or without
0014  * modification, are permitted provided that the following conditions
0015  * are met:
0016  * 1. Redistributions of source code must retain the above copyright
0017  *    notice, this list of conditions and the following disclaimer.
0018  * 2. Redistributions in binary form must reproduce the above copyright
0019  *    notice, this list of conditions and the following disclaimer in the
0020  *    documentation and/or other materials provided with the distribution.
0021  *
0022  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0023  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0024  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0025  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0026  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0027  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0028  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0029  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0030  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0031  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0032  * POSSIBILITY OF SUCH DAMAGE.
0033  */
0034 
0035 #ifdef HAVE_CONFIG_H
0036 #include "config.h"
0037 #endif
0038 
0039 #include <rtems/libio_.h>
0040 
0041 static bool is_fs_root( const rtems_filesystem_location_info_t *loc )
0042 {
0043   const rtems_filesystem_mount_table_entry_t *mt_entry = loc->mt_entry;
0044   const rtems_filesystem_location_info_t *mt_fs_root =
0045     &mt_entry->mt_fs_root->location;
0046 
0047   return (*mt_entry->ops->are_nodes_equal_h)( loc, mt_fs_root );
0048 }
0049 
0050 static bool is_eval_path_root(
0051   const rtems_filesystem_eval_path_context_t *ctx,
0052   const rtems_filesystem_location_info_t *loc
0053 )
0054 {
0055   const rtems_filesystem_mount_table_entry_t *mt_entry = loc->mt_entry;
0056   const rtems_filesystem_location_info_t *rootloc = &ctx->rootloc->location;
0057 
0058   return mt_entry == rootloc->mt_entry
0059     && (*mt_entry->ops->are_nodes_equal_h)( loc, rootloc );
0060 }
0061 
0062 void rtems_filesystem_eval_path_generic(
0063   rtems_filesystem_eval_path_context_t *ctx,
0064   void *arg,
0065   const rtems_filesystem_eval_path_generic_config *config
0066 )
0067 {
0068   rtems_filesystem_eval_path_generic_status status =
0069     RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_CONTINUE;
0070 
0071   while (status == RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_CONTINUE) {
0072     const char *token;
0073     size_t tokenlen;
0074 
0075     rtems_filesystem_eval_path_get_next_token(ctx, &token, &tokenlen);
0076 
0077     if (tokenlen > 0) {
0078       if ((*config->is_directory)(ctx, arg)) {
0079         if (rtems_filesystem_is_current_directory(token, tokenlen)) {
0080           if (rtems_filesystem_eval_path_has_path(ctx)) {
0081             status = (*config->eval_token)(ctx, arg, ".", 1);
0082           } else {
0083             int eval_flags = rtems_filesystem_eval_path_get_flags(ctx);
0084 
0085             if ((eval_flags & RTEMS_FS_REJECT_TERMINAL_DOT) == 0) {
0086               status = (*config->eval_token)(ctx, arg, ".", 1);
0087             } else {
0088               rtems_filesystem_eval_path_error(ctx, EINVAL);
0089               status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_DONE;
0090             }
0091           }
0092         } else if (rtems_filesystem_is_parent_directory(token, tokenlen)) {
0093           rtems_filesystem_location_info_t *currentloc =
0094             rtems_filesystem_eval_path_get_currentloc( ctx );
0095 
0096           if (is_eval_path_root(ctx, currentloc)) {
0097             /* This prevents the escape from a chroot() environment */
0098             status = (*config->eval_token)(ctx, arg, ".", 1);
0099           } else if (is_fs_root(currentloc)) {
0100             if (currentloc->mt_entry->mt_point_node != NULL) {
0101               rtems_filesystem_eval_path_put_back_token(ctx);
0102               rtems_filesystem_eval_path_restart(
0103                 ctx,
0104                 &currentloc->mt_entry->mt_point_node
0105               );
0106               status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_DONE;
0107             } else {
0108               /* This is the root file system */
0109               status = (*config->eval_token)(ctx, arg, ".", 1);
0110             }
0111           } else {
0112             status = (*config->eval_token)(ctx, arg, "..", 2);
0113           }
0114         } else {
0115           status = (*config->eval_token)(ctx, arg, token, tokenlen);
0116         }
0117 
0118         if (status == RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_NO_ENTRY) {
0119           if (rtems_filesystem_eval_path_has_path(ctx)) {
0120             int eval_flags;
0121 
0122             rtems_filesystem_eval_path_eat_delimiter(ctx);
0123             eval_flags = rtems_filesystem_eval_path_get_flags(ctx);
0124             if (
0125               (eval_flags & RTEMS_FS_ACCEPT_RESIDUAL_DELIMITERS) == 0
0126                 || rtems_filesystem_eval_path_has_path(ctx)
0127             ) {
0128               rtems_filesystem_eval_path_error(ctx, ENOENT);
0129             }
0130           }
0131         }
0132       } else {
0133         rtems_filesystem_eval_path_error(ctx, ENOTDIR);
0134         status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_DONE;
0135       }
0136     } else {
0137       status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_DONE;
0138     }
0139   }
0140 }