source: rtems/cpukit/libcsupport/src/sup_fs_eval_path_generic.c @ 1c6926c1

5
Last change on this file since 1c6926c1 was c499856, checked in by Chris Johns <chrisj@…>, on 03/20/14 at 21:10:47

Change all references of rtems.com to rtems.org.

  • Property mode set to 100644
File size: 4.1 KB
Line 
1/**
2 *  @file
3 *
4 *  @brief RTEMS File System Eval Generic Path
5 *  @ingroup LibIOInternal
6 */
7
8/*
9 * Copyright (c) 2012 embedded brains GmbH.  All rights reserved.
10 *
11 *  embedded brains GmbH
12 *  Obere Lagerstr. 30
13 *  82178 Puchheim
14 *  Germany
15 *  <rtems@embedded-brains.de>
16 *
17 * The license and distribution terms for this file may be
18 * found in the file LICENSE in this distribution or at
19 * http://www.rtems.org/license/LICENSE.
20 */
21
22#if HAVE_CONFIG_H
23  #include "config.h"
24#endif
25
26#include <rtems/libio_.h>
27
28static bool is_fs_root( const rtems_filesystem_location_info_t *loc )
29{
30  const rtems_filesystem_mount_table_entry_t *mt_entry = loc->mt_entry;
31  const rtems_filesystem_location_info_t *mt_fs_root =
32    &mt_entry->mt_fs_root->location;
33
34  return (*mt_entry->ops->are_nodes_equal_h)( loc, mt_fs_root );
35}
36
37static bool is_eval_path_root(
38  const rtems_filesystem_eval_path_context_t *ctx,
39  const rtems_filesystem_location_info_t *loc
40)
41{
42  const rtems_filesystem_mount_table_entry_t *mt_entry = loc->mt_entry;
43  const rtems_filesystem_location_info_t *rootloc = &ctx->rootloc->location;
44
45  return mt_entry == rootloc->mt_entry
46    && (*mt_entry->ops->are_nodes_equal_h)( loc, rootloc );
47}
48
49void rtems_filesystem_eval_path_generic(
50  rtems_filesystem_eval_path_context_t *ctx,
51  void *arg,
52  const rtems_filesystem_eval_path_generic_config *config
53)
54{
55  rtems_filesystem_eval_path_generic_status status =
56    RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_CONTINUE;
57
58  while (status == RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_CONTINUE) {
59    const char *token;
60    size_t tokenlen;
61
62    rtems_filesystem_eval_path_get_next_token(ctx, &token, &tokenlen);
63
64    if (tokenlen > 0) {
65      if ((*config->is_directory)(ctx, arg)) {
66        if (rtems_filesystem_is_current_directory(token, tokenlen)) {
67          if (rtems_filesystem_eval_path_has_path(ctx)) {
68            status = (*config->eval_token)(ctx, arg, ".", 1);
69          } else {
70            int eval_flags = rtems_filesystem_eval_path_get_flags(ctx);
71
72            if ((eval_flags & RTEMS_FS_REJECT_TERMINAL_DOT) == 0) {
73              status = (*config->eval_token)(ctx, arg, ".", 1);
74            } else {
75              rtems_filesystem_eval_path_error(ctx, EINVAL);
76              status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_DONE;
77            }
78          }
79        } else if (rtems_filesystem_is_parent_directory(token, tokenlen)) {
80          rtems_filesystem_location_info_t *currentloc =
81            rtems_filesystem_eval_path_get_currentloc( ctx );
82
83          if (is_eval_path_root(ctx, currentloc)) {
84            /* This prevents the escape from a chroot() environment */
85            status = (*config->eval_token)(ctx, arg, ".", 1);
86          } else if (is_fs_root(currentloc)) {
87            if (currentloc->mt_entry->mt_point_node != NULL) {
88              rtems_filesystem_eval_path_put_back_token(ctx);
89              rtems_filesystem_eval_path_restart(
90                ctx,
91                &currentloc->mt_entry->mt_point_node
92              );
93              status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_DONE;
94            } else {
95              /* This is the root file system */
96              status = (*config->eval_token)(ctx, arg, ".", 1);
97            }
98          } else {
99            status = (*config->eval_token)(ctx, arg, "..", 2);
100          }
101        } else {
102          status = (*config->eval_token)(ctx, arg, token, tokenlen);
103        }
104
105        if (status == RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_NO_ENTRY) {
106          if (rtems_filesystem_eval_path_has_path(ctx)) {
107            int eval_flags;
108
109            rtems_filesystem_eval_path_eat_delimiter(ctx);
110            eval_flags = rtems_filesystem_eval_path_get_flags(ctx);
111            if (
112              (eval_flags & RTEMS_FS_ACCEPT_RESIDUAL_DELIMITERS) == 0
113                || rtems_filesystem_eval_path_has_path(ctx)
114            ) {
115              rtems_filesystem_eval_path_error(ctx, ENOENT);
116            }
117          }
118        }
119      } else {
120        rtems_filesystem_eval_path_error(ctx, ENOTDIR);
121        status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_DONE;
122      }
123    } else {
124      status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_DONE;
125    }
126  }
127}
Note: See TracBrowser for help on using the repository browser.