/[path-sandbox]/trunk/libsandbox/canonicalize.c
Gentoo

Contents of /trunk/libsandbox/canonicalize.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 370 - (show annotations) (download) (as text)
Sun Nov 9 10:29:58 2008 UTC (6 years ago) by vapier
File MIME type: text/x-csrc
File size: 4627 byte(s)
consolidate all random system includes into headers.h
1 /* Return the canonical absolute name of a given file.
2 Copyright (C) 1996-2001, 2002 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 02111-1307 USA. */
19
20 #include "headers.h"
21 #include "sbutil.h"
22 #include "libsandbox.h"
23
24 #ifndef __set_errno
25 # define __set_errno(val) errno = (val)
26 #endif
27
28 /* Return the canonical absolute name of file NAME. A canonical name
29 does not contain any `.', `..' components nor any repeated path
30 separators ('/') or symlinks. All path components must exist. If
31 RESOLVED is null, the result is malloc'd; otherwise, if the
32 canonical name is SB_PATH_MAX chars or more, returns null with `errno'
33 set to ENAMETOOLONG; if the name fits in fewer than SB_PATH_MAX chars,
34 returns the name in RESOLVED. If the name cannot be resolved and
35 RESOLVED is non-NULL, it contains the path of the first component
36 that cannot be resolved. If the path can be resolved, RESOLVED
37 holds the same value as the value returned. */
38
39 /* Modified: 19 Aug 2002; Martin Schlemmer <azarah@gentoo.org>
40 *
41 * Cleaned up unneeded stuff, and change so that it will not
42 * resolve symlinks. Also prepended a 'e' to functions that
43 * I did not rip out.
44 *
45 */
46
47 char *
48 erealpath(const char *name, char *resolved)
49 {
50 char *rpath, *dest;
51 const char *start, *end, *rpath_limit;
52 long int path_max;
53
54 if (name == NULL) {
55 /* As per Single Unix Specification V2 we must return an error if
56 either parameter is a null pointer. We extend this to allow
57 the RESOLVED parameter to be NULL in case the we are expected to
58 allocate the room for the return value. */
59 __set_errno(EINVAL);
60 return NULL;
61 }
62
63 if (name[0] == '\0') {
64 /* As per Single Unix Specification V2 we must return an error if
65 the name argument points to an empty string. */
66 __set_errno(ENOENT);
67 return NULL;
68 }
69 #ifdef SB_PATH_MAX
70 path_max = SB_PATH_MAX;
71 #else
72 path_max = pathconf(name, _PC_PATH_MAX);
73 if (path_max <= 0)
74 path_max = 1024;
75 #endif
76
77 if (resolved == NULL) {
78 rpath = malloc(path_max);
79 if (rpath == NULL)
80 return NULL;
81 } else
82 rpath = resolved;
83 rpath_limit = rpath + path_max;
84
85 if (name[0] != '/') {
86 if (!egetcwd(rpath, path_max)) {
87 rpath[0] = '\0';
88 goto error;
89 }
90 dest = strchr(rpath, '\0');
91 } else {
92 rpath[0] = '/';
93 dest = rpath + 1;
94 }
95
96 for (start = end = name; *start; start = end) {
97 /* Skip sequence of multiple path-separators. */
98 while (*start == '/')
99 ++start;
100
101 /* Find end of path component. */
102 for (end = start; *end && *end != '/'; ++end)
103 /* Nothing. */ ;
104
105 if (end - start == 0)
106 break;
107 else if (end - start == 1 && start[0] == '.')
108 /* nothing */ ;
109 else if (end - start == 2 && start[0] == '.' && start[1] == '.') {
110 /* Back up to previous component, ignore if at root already. */
111 if (dest > rpath + 1)
112 while ((--dest)[-1] != '/') ;
113 } else {
114 size_t new_size;
115
116 if (dest[-1] != '/')
117 *dest++ = '/';
118
119 if (dest + (end - start) >= rpath_limit) {
120 ptrdiff_t dest_offset = dest - rpath;
121 char *new_rpath;
122
123 if (resolved) {
124 __set_errno(ENAMETOOLONG);
125 if (dest > rpath + 1)
126 dest--;
127 *dest = '\0';
128 goto error;
129 }
130 new_size = rpath_limit - rpath;
131 if (end - start + 1 > path_max)
132 new_size += end - start + 1;
133 else
134 new_size += path_max;
135 new_rpath = (char *) realloc(rpath, new_size);
136 if (new_rpath == NULL)
137 goto error;
138 rpath = new_rpath;
139 rpath_limit = rpath + new_size;
140
141 dest = rpath + dest_offset;
142 }
143
144 memcpy(dest, start, end - start);
145 dest += end - start;
146 *dest = '\0';
147 }
148 }
149 #if 1
150 if (dest > rpath + 1 && dest[-1] == '/')
151 --dest;
152 #endif
153 *dest = '\0';
154
155 return resolved ? rpath : memcpy(resolved, rpath, dest - rpath + 1);
156
157 error:
158 if (resolved)
159 snprintf(resolved, path_max, "%s", rpath);
160 else
161 free(rpath);
162 return NULL;
163 }
164
165 // vim:noexpandtab noai:cindent ai

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.20