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

Contents of /trunk/src/canonicalize.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 189 - (show annotations) (download) (as text)
Thu Dec 1 09:46:17 2005 UTC (9 years ago) by azarah
File MIME type: text/x-csrc
File size: 4838 byte(s)
Remove the SB_STATIC and including of getcwd.c, etc voodoo, as we new use a
symbol map, and all non-exported symbols are local.  Cleanup getcwd.c, as
the generic getcwd for older 2.4 kernels do not work properly anyhow, and
just makes things slower.  Some other warning fixes.

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