diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | configure.ac | 8 | ||||
-rw-r--r-- | openbsd-compat/realpath.c | 69 |
3 files changed, 60 insertions, 23 deletions
@@ -1,3 +1,7 @@ | |||
1 | 20050202 | ||
2 | - (dtucker) [configure.ac openbsd-compat/realpath.c] Sync up with realpath | ||
3 | rev 1.11 from OpenBSD and make it use fchdir if available. ok djm@ | ||
4 | |||
1 | 20050201 | 5 | 20050201 |
2 | - (dtucker) [log.c] Bug #973: force log_init() to open syslog, since on some | 6 | - (dtucker) [log.c] Bug #973: force log_init() to open syslog, since on some |
3 | platforms syslog will revert to its default values. This may result in | 7 | platforms syslog will revert to its default values. This may result in |
@@ -2051,4 +2055,4 @@ | |||
2051 | - (djm) Trim deprecated options from INSTALL. Mention UsePAM | 2055 | - (djm) Trim deprecated options from INSTALL. Mention UsePAM |
2052 | - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu | 2056 | - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu |
2053 | 2057 | ||
2054 | $Id: ChangeLog,v 1.3628 2005/02/01 08:16:45 dtucker Exp $ | 2058 | $Id: ChangeLog,v 1.3629 2005/02/01 23:43:59 dtucker Exp $ |
diff --git a/configure.ac b/configure.ac index d4151feb0..94d6b1e78 100644 --- a/configure.ac +++ b/configure.ac | |||
@@ -1,4 +1,4 @@ | |||
1 | # $Id: configure.ac,v 1.235 2005/01/18 01:05:18 dtucker Exp $ | 1 | # $Id: configure.ac,v 1.236 2005/02/01 23:44:00 dtucker Exp $ |
2 | # | 2 | # |
3 | # Copyright (c) 1999-2004 Damien Miller | 3 | # Copyright (c) 1999-2004 Damien Miller |
4 | # | 4 | # |
@@ -877,9 +877,9 @@ AC_ARG_WITH(libedit, | |||
877 | dnl Checks for library functions. Please keep in alphabetical order | 877 | dnl Checks for library functions. Please keep in alphabetical order |
878 | AC_CHECK_FUNCS(\ | 878 | AC_CHECK_FUNCS(\ |
879 | arc4random __b64_ntop b64_ntop __b64_pton b64_pton bcopy \ | 879 | arc4random __b64_ntop b64_ntop __b64_pton b64_pton bcopy \ |
880 | bindresvport_sa clock closefrom dirfd fchmod fchown freeaddrinfo \ | 880 | bindresvport_sa clock closefrom dirfd fchdir fchmod fchown \ |
881 | futimes getaddrinfo getcwd getgrouplist getnameinfo getopt \ | 881 | freeaddrinfo futimes getaddrinfo getcwd getgrouplist getnameinfo \ |
882 | getpeereid _getpty getrlimit getttyent glob inet_aton \ | 882 | getopt getpeereid _getpty getrlimit getttyent glob inet_aton \ |
883 | inet_ntoa inet_ntop innetgr login_getcapbool md5_crypt memmove \ | 883 | inet_ntoa inet_ntop innetgr login_getcapbool md5_crypt memmove \ |
884 | mkdtemp mmap ngetaddrinfo nsleep ogetaddrinfo openlog_r openpty \ | 884 | mkdtemp mmap ngetaddrinfo nsleep ogetaddrinfo openlog_r openpty \ |
885 | pstat prctl readpassphrase realpath recvmsg rresvport_af sendmsg \ | 885 | pstat prctl readpassphrase realpath recvmsg rresvport_af sendmsg \ |
diff --git a/openbsd-compat/realpath.c b/openbsd-compat/realpath.c index 218fbecb2..7f73bd998 100644 --- a/openbsd-compat/realpath.c +++ b/openbsd-compat/realpath.c | |||
@@ -37,7 +37,7 @@ | |||
37 | #if !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH) | 37 | #if !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH) |
38 | 38 | ||
39 | #if defined(LIBC_SCCS) && !defined(lint) | 39 | #if defined(LIBC_SCCS) && !defined(lint) |
40 | static char *rcsid = "$OpenBSD: realpath.c,v 1.10 2003/08/01 21:04:59 millert Exp $"; | 40 | static char *rcsid = "$OpenBSD: realpath.c,v 1.11 2004/11/30 15:12:59 millert Exp $"; |
41 | #endif /* LIBC_SCCS and not lint */ | 41 | #endif /* LIBC_SCCS and not lint */ |
42 | 42 | ||
43 | #include <sys/param.h> | 43 | #include <sys/param.h> |
@@ -67,17 +67,25 @@ char * | |||
67 | realpath(const char *path, char *resolved) | 67 | realpath(const char *path, char *resolved) |
68 | { | 68 | { |
69 | struct stat sb; | 69 | struct stat sb; |
70 | int fd, n, needslash, serrno = 0; | 70 | int fd, n, needslash, serrno; |
71 | char *p, *q, wbuf[MAXPATHLEN], start[MAXPATHLEN]; | 71 | char *p, *q, wbuf[MAXPATHLEN]; |
72 | int symlinks = 0; | 72 | int symlinks = 0; |
73 | 73 | ||
74 | /* Save the starting point. */ | 74 | /* Save the starting point. */ |
75 | getcwd(start,MAXPATHLEN); | 75 | #ifndef HAVE_FCHDIR |
76 | char start[MAXPATHLEN]; | ||
77 | /* this is potentially racy but without fchdir we have no option */ | ||
78 | if (getcwd(start, sizeof(start)) == NULL) { | ||
79 | resolved[0] = '.'; | ||
80 | resolved[1] = '\0'; | ||
81 | return (NULL); | ||
82 | } | ||
83 | #endif | ||
76 | if ((fd = open(".", O_RDONLY)) < 0) { | 84 | if ((fd = open(".", O_RDONLY)) < 0) { |
77 | (void)strlcpy(resolved, ".", MAXPATHLEN); | 85 | resolved[0] = '.'; |
86 | resolved[1] = '\0'; | ||
78 | return (NULL); | 87 | return (NULL); |
79 | } | 88 | } |
80 | close(fd); | ||
81 | 89 | ||
82 | /* Convert "." -> "" to optimize away a needless lstat() and chdir() */ | 90 | /* Convert "." -> "" to optimize away a needless lstat() and chdir() */ |
83 | if (path[0] == '.' && path[1] == '\0') | 91 | if (path[0] == '.' && path[1] == '\0') |
@@ -91,7 +99,10 @@ realpath(const char *path, char *resolved) | |||
91 | * if it is a directory, then change to that directory. | 99 | * if it is a directory, then change to that directory. |
92 | * get the current directory name and append the basename. | 100 | * get the current directory name and append the basename. |
93 | */ | 101 | */ |
94 | strlcpy(resolved, path, MAXPATHLEN); | 102 | if (strlcpy(resolved, path, MAXPATHLEN) >= MAXPATHLEN) { |
103 | serrno = ENAMETOOLONG; | ||
104 | goto err2; | ||
105 | } | ||
95 | loop: | 106 | loop: |
96 | q = strrchr(resolved, '/'); | 107 | q = strrchr(resolved, '/'); |
97 | if (q != NULL) { | 108 | if (q != NULL) { |
@@ -114,11 +125,10 @@ loop: | |||
114 | if (*p != '\0' && lstat(p, &sb) == 0) { | 125 | if (*p != '\0' && lstat(p, &sb) == 0) { |
115 | if (S_ISLNK(sb.st_mode)) { | 126 | if (S_ISLNK(sb.st_mode)) { |
116 | if (++symlinks > MAXSYMLINKS) { | 127 | if (++symlinks > MAXSYMLINKS) { |
117 | serrno = ELOOP; | 128 | errno = ELOOP; |
118 | goto err1; | 129 | goto err1; |
119 | } | 130 | } |
120 | n = readlink(p, resolved, MAXPATHLEN-1); | 131 | if ((n = readlink(p, resolved, MAXPATHLEN-1)) < 0) |
121 | if (n < 0) | ||
122 | goto err1; | 132 | goto err1; |
123 | resolved[n] = '\0'; | 133 | resolved[n] = '\0'; |
124 | goto loop; | 134 | goto loop; |
@@ -134,8 +144,11 @@ loop: | |||
134 | * Save the last component name and get the full pathname of | 144 | * Save the last component name and get the full pathname of |
135 | * the current directory. | 145 | * the current directory. |
136 | */ | 146 | */ |
137 | (void)strlcpy(wbuf, p, sizeof wbuf); | 147 | if (strlcpy(wbuf, p, sizeof(wbuf)) >= sizeof(wbuf)) { |
138 | if (getcwd(resolved, MAXPATHLEN) == 0) | 148 | errno = ENAMETOOLONG; |
149 | goto err1; | ||
150 | } | ||
151 | if (getcwd(resolved, MAXPATHLEN) == NULL) | ||
139 | goto err1; | 152 | goto err1; |
140 | 153 | ||
141 | /* | 154 | /* |
@@ -149,23 +162,43 @@ loop: | |||
149 | 162 | ||
150 | if (*wbuf) { | 163 | if (*wbuf) { |
151 | if (strlen(resolved) + strlen(wbuf) + needslash >= MAXPATHLEN) { | 164 | if (strlen(resolved) + strlen(wbuf) + needslash >= MAXPATHLEN) { |
152 | serrno = ENAMETOOLONG; | 165 | errno = ENAMETOOLONG; |
166 | goto err1; | ||
167 | } | ||
168 | if (needslash) { | ||
169 | if (strlcat(resolved, "/", MAXPATHLEN) >= MAXPATHLEN) { | ||
170 | errno = ENAMETOOLONG; | ||
171 | goto err1; | ||
172 | } | ||
173 | } | ||
174 | if (strlcat(resolved, wbuf, MAXPATHLEN) >= MAXPATHLEN) { | ||
175 | errno = ENAMETOOLONG; | ||
153 | goto err1; | 176 | goto err1; |
154 | } | 177 | } |
155 | if (needslash) | ||
156 | strlcat(resolved, "/", MAXPATHLEN); | ||
157 | strlcat(resolved, wbuf, MAXPATHLEN); | ||
158 | } | 178 | } |
159 | 179 | ||
160 | /* Go back to where we came from. */ | 180 | /* Go back to where we came from. */ |
181 | #ifdef HAVE_FCHDIR | ||
182 | if (fchdir(fd) < 0) { | ||
183 | #else | ||
161 | if (chdir(start) < 0) { | 184 | if (chdir(start) < 0) { |
185 | #endif | ||
162 | serrno = errno; | 186 | serrno = errno; |
163 | goto err2; | 187 | goto err2; |
164 | } | 188 | } |
189 | |||
190 | /* It's okay if the close fails, what's an fd more or less? */ | ||
191 | (void)close(fd); | ||
165 | return (resolved); | 192 | return (resolved); |
166 | 193 | ||
167 | err1: chdir(start); | 194 | err1: serrno = errno; |
168 | err2: errno = serrno; | 195 | #ifdef HAVE_FCHDIR |
196 | (void)fchdir(fd); | ||
197 | #else | ||
198 | chdir(start); | ||
199 | #endif | ||
200 | err2: (void)close(fd); | ||
201 | errno = serrno; | ||
169 | return (NULL); | 202 | return (NULL); |
170 | } | 203 | } |
171 | #endif /* !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH) */ | 204 | #endif /* !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH) */ |