summaryrefslogtreecommitdiffstats
path: root/cpukit/libcsupport/src/eval.c
blob: 5a9118d3e180ad9bb28fd3ef7541af0b38ae9a65 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/*
 *  rtems_filesystem_evaluate_path()
 *
 *  Routine to seed the evaluate path routine.
 *
 *  COPYRIGHT (c) 1989-2010.
 *  On-Line Applications Research Corporation (OAR).
 *
 *  The license and distribution terms for this file may be
 *  found in the file LICENSE in this distribution or at
 *  http://www.rtems.com/license/LICENSE.
 *
 *  $Id$
 */

#if HAVE_CONFIG_H
#include "config.h"
#endif

#include <rtems.h>
#include <rtems/libio_.h>
#include <rtems/seterr.h>

int rtems_filesystem_evaluate_relative_path(
  const char                        *pathname,
  size_t                             pathnamelen,
  int                                flags,
  rtems_filesystem_location_info_t  *pathloc,
  int                                follow_link
)
{
  int                           result;
  rtems_filesystem_node_types_t type;

  #if defined(RTEMS_DEBUG)
    /*
     * Verify Input parameters that should never be bad unless someone
     * is implementing a new filesystem and has bugs.
     */
    if ( !pathname )
      rtems_set_errno_and_return_minus_one( EFAULT );

    if ( !pathloc )
      rtems_set_errno_and_return_minus_one( EIO );
  #endif

  result = (*pathloc->ops->evalpath_h)( pathname, pathnamelen, flags, pathloc );

  /*
   * Get the Node type and determine if you need to follow the link or
   * not.
   */

  if ( (result == 0) && follow_link ) {

    type = (*pathloc->ops->node_type_h)( pathloc );

    if ( ( type == RTEMS_FILESYSTEM_HARD_LINK ) ||
         ( type == RTEMS_FILESYSTEM_SYM_LINK ) ) {

        /* what to do with the valid node pathloc points to
         * if eval_link_h fails?
         * Let the FS implementation deal with this case.  It
         * should probably free pathloc in either case:
         *  - if the link evaluation fails, it must free the
         *    original (valid) pathloc because we are going
         *    to return -1 and hence the FS generics won't
         *    cleanup pathloc.
         *  - if the link evaluation is successful, the updated
         *    pathloc will be passed up (and eventually released).
         *    Hence, the (valid) originial node that we submit to
         *    eval_link_h() should be released by the handler.
         */

        result =  (*pathloc->ops->eval_link_h)( pathloc, flags );
    }
  }

  return result;
}

int rtems_filesystem_evaluate_path(
  const char                        *pathname,
  size_t                             pathnamelen,
  int                                flags,
  rtems_filesystem_location_info_t  *pathloc,
  int                                follow_link
)
{
  int                           i = 0;

  #if defined(RTEMS_DEBUG)
    /*
     * Verify Input parameters that should never be bad unless someone
     * is implementing a new filesystem and has bugs.
     */
    if ( !pathname )
      rtems_set_errno_and_return_minus_one( EFAULT );

    if ( !pathloc )
      rtems_set_errno_and_return_minus_one( EIO );
  #endif

  /*
   * Evaluate the path using the optable evalpath.
   */

  rtems_filesystem_get_start_loc( pathname, &i, pathloc );

  /*
   * We evaluation the path relative to the start location we get got.
   */
  return rtems_filesystem_evaluate_relative_path( &pathname[i],
                                                  pathnamelen - i,
                                                  flags,
                                                  pathloc,
                                                  follow_link );
}

int rtems_filesystem_dirname(
  const char  *pathname
)
{
  int len = strlen( pathname );

  while ( len ) {
    len--;
    if ( rtems_filesystem_is_separator( pathname[len] ) )
      break;
  }

  return len;
}

int rtems_filesystem_prefix_separators(
  const char  *pathname,
  int          pathnamelen
)
{
  /*
   * Eat any separators at start of the path.
   */
  int stripped = 0;
  while ( *pathname && pathnamelen && rtems_filesystem_is_separator( *pathname ) )
  {
    pathname++;
    pathnamelen--;
    stripped++;
  }
  return stripped;
}