source: rtems/cpukit/libcsupport/src/sup_fs_eval_path.c @ 2563410

4.115
Last change on this file since 2563410 was 2563410, checked in by Sebastian Huber <sebastian.huber@…>, on 03/13/12 at 08:22:11

Filesystem: Rename defines

o Removed RTEMS_LIBIO_PERMS_SEARCH.
o Renamed RTEMS_LIBIO_PERMS_READ in RTEMS_FS_PERMS_READ.
o Renamed RTEMS_LIBIO_PERMS_WRITE in RTEMS_FS_PERMS_WRITE.
o Renamed RTEMS_LIBIO_PERMS_EXEC in RTEMS_FS_PERMS_EXEC.
o Renamed RTEMS_LIBIO_FOLLOW_HARD_LINK in RTEMS_FS_FOLLOW_HARD_LINK.
o Renamed RTEMS_LIBIO_FOLLOW_SYM_LINK in RTEMS_FS_FOLLOW_SYM_LINK.
o Renamed RTEMS_LIBIO_MAKE in RTEMS_FS_MAKE.
o Renamed RTEMS_LIBIO_EXCLUSIVE in RTEMS_FS_EXCLUSIVE.
o Renamed RTEMS_LIBIO_ACCEPT_RESIDUAL_DELIMITERS in

RTEMS_FS_ACCEPT_RESIDUAL_DELIMITERS.

o Renamed RTEMS_LIBIO_REJECT_TERMINAL_DOT in
RTEMS_FS_REJECT_TERMINAL_DOT.

  • Property mode set to 100644
File size: 7.9 KB
Line 
1/*
2 * Copyright (c) 2012 embedded brains GmbH.  All rights reserved.
3 *
4 *  embedded brains GmbH
5 *  Obere Lagerstr. 30
6 *  82178 Puchheim
7 *  Germany
8 *  <rtems@embedded-brains.de>
9 *
10 * The license and distribution terms for this file may be
11 * found in the file LICENSE in this distribution or at
12 * http://www.rtems.com/license/LICENSE.
13 */
14
15#if HAVE_CONFIG_H
16  #include "config.h"
17#endif
18
19#include <rtems/libio_.h>
20
21static size_t get_parentpathlen(const char *path, size_t pathlen)
22{
23  while (pathlen > 0) {
24    size_t i = pathlen - 1;
25
26    if (rtems_filesystem_is_delimiter(path [i])) {
27      return pathlen;
28    }
29
30    pathlen = i;
31  }
32
33  return 0;
34}
35
36static void set_startloc(
37  rtems_filesystem_eval_path_context_t *ctx,
38  rtems_filesystem_global_location_t *const *global_root_ptr,
39  rtems_filesystem_global_location_t *const *global_current_ptr
40)
41{
42  if (ctx->pathlen > 0) {
43    char c = ctx->path [0];
44
45    ctx->rootloc = rtems_filesystem_global_location_obtain(global_root_ptr);
46
47    if (rtems_filesystem_is_delimiter(c)) {
48      ++ctx->path;
49      --ctx->pathlen;
50      ctx->startloc = rtems_filesystem_global_location_obtain(
51        &ctx->rootloc
52      );
53    } else {
54      ctx->startloc = rtems_filesystem_global_location_obtain(
55        global_current_ptr
56      );
57    }
58  } else {
59    ctx->rootloc = rtems_filesystem_global_location_obtain_null();
60    ctx->startloc = rtems_filesystem_global_location_obtain_null();
61    errno = ENOENT;
62  }
63}
64
65static void check_access(
66  rtems_filesystem_eval_path_context_t *ctx,
67  int eval_flags
68)
69{
70  const rtems_filesystem_location_info_t *currentloc = &ctx->currentloc;
71  const rtems_filesystem_mount_table_entry_t *mt_entry = currentloc->mt_entry;
72
73  if ((eval_flags & RTEMS_FS_PERMS_WRITE) == 0 || mt_entry->writeable) {
74    struct stat st;
75    int rv;
76
77    st.st_mode = 0;
78    st.st_uid = 0;
79    st.st_gid = 0;
80    rv = (*currentloc->handlers->fstat_h)(currentloc, &st);
81    if (rv == 0) {
82      bool access_ok = rtems_filesystem_check_access(
83        eval_flags,
84        st.st_mode,
85        st.st_uid,
86        st.st_gid
87      );
88
89      if (!access_ok) {
90        rtems_filesystem_eval_path_error(ctx, EACCES);
91      }
92    } else {
93      rtems_filesystem_eval_path_error(ctx, 0);
94    }
95  } else {
96    rtems_filesystem_eval_path_error(ctx, EROFS);
97  }
98}
99
100void rtems_filesystem_eval_path_continue(
101  rtems_filesystem_eval_path_context_t *ctx
102)
103{
104  int eval_flags;
105
106  while (ctx->pathlen > 0) {
107    (*ctx->currentloc.ops->eval_path_h)(ctx);
108  }
109
110  eval_flags = rtems_filesystem_eval_path_get_flags(ctx);
111  if (rtems_filesystem_eval_path_has_token(ctx)) {
112    bool make = (eval_flags & RTEMS_FS_MAKE) != 0;
113
114    if (make) {
115      check_access(ctx, RTEMS_FS_PERMS_WRITE);
116    } else {
117      rtems_filesystem_eval_path_error(ctx, ENOENT);
118    }
119  } else {
120    bool exclusive = (eval_flags & RTEMS_FS_EXCLUSIVE) != 0;
121
122    if (!exclusive) {
123      check_access(ctx, ctx->flags);
124    } else {
125      rtems_filesystem_eval_path_error(ctx, EEXIST);
126    }
127  }
128}
129
130static rtems_filesystem_location_info_t *
131eval_path_start(
132  rtems_filesystem_eval_path_context_t *ctx,
133  const char *path,
134  size_t pathlen,
135  int eval_flags,
136  rtems_filesystem_global_location_t *const *global_root_ptr,
137  rtems_filesystem_global_location_t *const *global_current_ptr
138)
139{
140  memset(ctx, 0, sizeof(*ctx));
141
142  ctx->path = path;
143  ctx->pathlen = pathlen;
144  ctx->flags = eval_flags;
145
146  set_startloc(ctx, global_root_ptr, global_current_ptr);
147
148  rtems_filesystem_instance_lock(&ctx->startloc->location);
149
150  rtems_filesystem_location_clone(
151    &ctx->currentloc,
152    &ctx->startloc->location
153  );
154
155  rtems_filesystem_eval_path_continue(ctx);
156
157  return &ctx->currentloc;
158}
159
160rtems_filesystem_location_info_t *
161rtems_filesystem_eval_path_start_with_root_and_current(
162  rtems_filesystem_eval_path_context_t *ctx,
163  const char *path,
164  int eval_flags,
165  rtems_filesystem_global_location_t *const *global_root_ptr,
166  rtems_filesystem_global_location_t *const *global_current_ptr
167)
168{
169  return eval_path_start(
170    ctx,
171    path,
172    strlen(path),
173    eval_flags,
174    global_root_ptr,
175    global_current_ptr
176  );
177}
178
179rtems_filesystem_location_info_t *
180rtems_filesystem_eval_path_start(
181  rtems_filesystem_eval_path_context_t *ctx,
182  const char *path,
183  int eval_flags
184)
185{
186  return rtems_filesystem_eval_path_start_with_root_and_current(
187    ctx,
188    path,
189    eval_flags,
190    &rtems_filesystem_root,
191    &rtems_filesystem_current
192  );
193}
194
195rtems_filesystem_location_info_t *
196rtems_filesystem_eval_path_start_with_parent(
197  rtems_filesystem_eval_path_context_t *ctx,
198  const char *path,
199  int eval_flags,
200  rtems_filesystem_location_info_t *parentloc,
201  int parent_eval_flags
202)
203{
204  size_t pathlen = strlen(path);
205  const char *parentpath = path;
206  size_t parentpathlen = get_parentpathlen(path, pathlen);
207  const char *name = NULL;
208  size_t namelen = 0;
209  const rtems_filesystem_location_info_t *currentloc = NULL;
210
211  if (pathlen > 0) {
212    if (parentpathlen == 0) {
213      parentpath = ".";
214      parentpathlen = 1;
215      name = path;
216      namelen = pathlen;
217    } else {
218      name = path + parentpathlen;
219      namelen = pathlen - parentpathlen;
220    }
221  }
222
223  currentloc = eval_path_start(
224    ctx,
225    parentpath,
226    parentpathlen,
227    parent_eval_flags,
228    &rtems_filesystem_root,
229    &rtems_filesystem_current
230  );
231
232  rtems_filesystem_location_clone(parentloc, currentloc);
233
234  ctx->path = name;
235  ctx->pathlen = namelen;
236  ctx->flags = eval_flags;
237
238  rtems_filesystem_eval_path_continue(ctx);
239
240  return &ctx->currentloc;
241}
242
243void rtems_filesystem_eval_path_recursive(
244  rtems_filesystem_eval_path_context_t *ctx,
245  const char *path,
246  size_t pathlen
247)
248{
249  if (pathlen > 0) {
250    if (ctx->recursionlevel < RTEMS_FILESYSTEM_SYMLOOP_MAX) {
251      const char *saved_path = ctx->path;
252      size_t saved_pathlen = ctx->pathlen;
253
254      if (rtems_filesystem_is_delimiter(path [0])) {
255        rtems_filesystem_eval_path_restart(ctx, &ctx->rootloc);
256      }
257
258      ctx->path = path;
259      ctx->pathlen = pathlen;
260
261      ++ctx->recursionlevel;
262      while (ctx->pathlen > 0) {
263        (*ctx->currentloc.ops->eval_path_h)(ctx);
264      }
265      --ctx->recursionlevel;
266
267      ctx->path = saved_path;
268      ctx->pathlen = saved_pathlen;
269    } else {
270      rtems_filesystem_eval_path_error(ctx, ELOOP);
271    }
272  } else {
273    rtems_filesystem_eval_path_error(ctx, ENOENT);
274  }
275}
276
277void rtems_filesystem_eval_path_error(
278  rtems_filesystem_eval_path_context_t *ctx,
279  int eno
280)
281{
282  ctx->path = NULL;
283  ctx->pathlen = 0;
284  ctx->token = NULL;
285  ctx->tokenlen = 0;
286
287  if (!rtems_filesystem_location_is_null(&ctx->currentloc)) {
288    if (eno != 0) {
289      errno = eno;
290    }
291
292    rtems_filesystem_location_detach(&ctx->currentloc);
293  }
294}
295
296static void free_location(rtems_filesystem_location_info_t *loc)
297{
298  rtems_filesystem_mt_entry_declare_lock_context(lock_context);
299
300  (*loc->ops->freenod_h)(loc);
301
302  rtems_filesystem_mt_entry_lock(lock_context);
303  rtems_chain_extract_unprotected(&loc->mt_entry_node);
304  rtems_filesystem_mt_entry_unlock(lock_context);
305}
306
307void rtems_filesystem_eval_path_cleanup(
308  rtems_filesystem_eval_path_context_t *ctx
309)
310{
311  free_location(&ctx->currentloc);
312  rtems_filesystem_instance_unlock(&ctx->startloc->location);
313  rtems_filesystem_global_location_release(ctx->startloc);
314  rtems_filesystem_global_location_release(ctx->rootloc);
315}
316
317void rtems_filesystem_eval_path_cleanup_with_parent(
318  rtems_filesystem_eval_path_context_t *ctx,
319  rtems_filesystem_location_info_t *parentloc
320)
321{
322  free_location(parentloc);
323  rtems_filesystem_eval_path_cleanup(ctx);
324}
325
326void rtems_filesystem_eval_path_restart(
327  rtems_filesystem_eval_path_context_t *ctx,
328  rtems_filesystem_global_location_t **newstartloc_ptr
329)
330{
331  free_location(&ctx->currentloc);
332  rtems_filesystem_instance_unlock(&ctx->startloc->location);
333  rtems_filesystem_global_location_assign(
334    &ctx->startloc,
335    rtems_filesystem_global_location_obtain(newstartloc_ptr)
336  );
337  rtems_filesystem_instance_lock(&ctx->startloc->location);
338  rtems_filesystem_location_clone(&ctx->currentloc, &ctx->startloc->location);
339}
Note: See TracBrowser for help on using the repository browser.