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

Contents of /trunk/canonicalize.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 29 - (show annotations) (download) (as text)
Wed Mar 2 09:01:36 2005 UTC (12 years, 11 months ago) by azarah
File MIME type: text/x-csrc
File size: 4780 byte(s)
Fix inverse test logic in canonicalize.c, use a strncpy.  Fix gcc warning in
getcwd.c.  Add symbols.in and logic to Makefile.am to generate symbol versions
for glibc and other libc's that use this.  Update libsandbox.c to use these
symbol versions if available.  Fix exec wrapper to re-export LD_PRELOAD if the
process unset it.

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 /*
21 * $Header$
22 */
23
24 #include <stdlib.h>
25 #include <string.h>
26 #include <unistd.h>
27 #include <limits.h>
28 #include <sys/param.h>
29 #include <sys/stat.h>
30 #include <errno.h>
31 #include <stddef.h>
32
33 #include "config.h"
34 #include "localdecls.h"
35
36 #ifndef __set_errno
37 # define __set_errno(val) errno = (val)
38 #endif
39
40 /* Return the canonical absolute name of file NAME. A canonical name
41 does not contain any `.', `..' components nor any repeated path
42 separators ('/') or symlinks. All path components must exist. If
43 RESOLVED is null, the result is malloc'd; otherwise, if the
44 canonical name is SB_PATH_MAX chars or more, returns null with `errno'
45 set to ENAMETOOLONG; if the name fits in fewer than SB_PATH_MAX chars,
46 returns the name in RESOLVED. If the name cannot be resolved and
47 RESOLVED is non-NULL, it contains the path of the first component
48 that cannot be resolved. If the path can be resolved, RESOLVED
49 holds the same value as the value returned. */
50
51 /* Modified: 19 Aug 2002; Martin Schlemmer <azarah@gentoo.org>
52 *
53 * Cleaned up unneeded stuff, and change so that it will not
54 * resolve symlinks. Also prepended a 'e' to functions that
55 * I did not rip out.
56 *
57 */
58
59 char *
60 erealpath(const char *name, char *resolved)
61 {
62 char *rpath, *dest;
63 const char *start, *end, *rpath_limit;
64 long int path_max;
65
66 if (name == NULL) {
67 /* As per Single Unix Specification V2 we must return an error if
68 either parameter is a null pointer. We extend this to allow
69 the RESOLVED parameter to be NULL in case the we are expected to
70 allocate the room for the return value. */
71 __set_errno(EINVAL);
72 return NULL;
73 }
74
75 if (name[0] == '\0') {
76 /* As per Single Unix Specification V2 we must return an error if
77 the name argument points to an empty string. */
78 __set_errno(ENOENT);
79 return NULL;
80 }
81 #ifdef SB_PATH_MAX
82 path_max = SB_PATH_MAX;
83 #else
84 path_max = pathconf(name, _PC_PATH_MAX);
85 if (path_max <= 0)
86 path_max = 1024;
87 #endif
88
89 if (resolved == NULL) {
90 rpath = malloc(path_max);
91 if (rpath == NULL)
92 return NULL;
93 } else
94 rpath = resolved;
95 rpath_limit = rpath + path_max;
96
97 if (name[0] != '/') {
98 if (!egetcwd(rpath, path_max)) {
99 rpath[0] = '\0';
100 goto error;
101 }
102 dest = strchr(rpath, '\0');
103 } else {
104 rpath[0] = '/';
105 dest = rpath + 1;
106 }
107
108 for (start = end = name; *start; start = end) {
109 /* Skip sequence of multiple path-separators. */
110 while (*start == '/')
111 ++start;
112
113 /* Find end of path component. */
114 for (end = start; *end && *end != '/'; ++end)
115 /* Nothing. */ ;
116
117 if (end - start == 0)
118 break;
119 else if (end - start == 1 && start[0] == '.')
120 /* nothing */ ;
121 else if (end - start == 2 && start[0] == '.' && start[1] == '.') {
122 /* Back up to previous component, ignore if at root already. */
123 if (dest > rpath + 1)
124 while ((--dest)[-1] != '/') ;
125 } else {
126 size_t new_size;
127
128 if (dest[-1] != '/')
129 *dest++ = '/';
130
131 if (dest + (end - start) >= rpath_limit) {
132 ptrdiff_t dest_offset = dest - rpath;
133 char *new_rpath;
134
135 if (resolved) {
136 __set_errno(ENAMETOOLONG);
137 if (dest > rpath + 1)
138 dest--;
139 *dest = '\0';
140 goto error;
141 }
142 new_size = rpath_limit - rpath;
143 if (end - start + 1 > path_max)
144 new_size += end - start + 1;
145 else
146 new_size += path_max;
147 new_rpath = (char *) realloc(rpath, new_size);
148 if (new_rpath == NULL)
149 goto error;
150 rpath = new_rpath;
151 rpath_limit = rpath + new_size;
152
153 dest = rpath + dest_offset;
154 }
155
156 dest = __mempcpy(dest, start, end - start);
157 *dest = '\0';
158 }
159 }
160 #if 1
161 if (dest > rpath + 1 && dest[-1] == '/')
162 --dest;
163 #endif
164 *dest = '\0';
165
166 return resolved ? rpath : memcpy(resolved, rpath, dest - rpath + 1);
167
168 error:
169 if (resolved)
170 strncpy(resolved, rpath, path_max - 1);
171 else
172 free(rpath);
173 return NULL;
174 }
175
176 // 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