summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--configure.ac8
-rw-r--r--openbsd-compat/realpath.c69
3 files changed, 60 insertions, 23 deletions
diff --git a/ChangeLog b/ChangeLog
index 301921de1..eb897ec41 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
120050202
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
120050201 520050201
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,
877dnl Checks for library functions. Please keep in alphabetical order 877dnl Checks for library functions. Please keep in alphabetical order
878AC_CHECK_FUNCS(\ 878AC_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)
40static char *rcsid = "$OpenBSD: realpath.c,v 1.10 2003/08/01 21:04:59 millert Exp $"; 40static 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 *
67realpath(const char *path, char *resolved) 67realpath(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 }
95loop: 106loop:
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
167err1: chdir(start); 194err1: serrno = errno;
168err2: errno = serrno; 195#ifdef HAVE_FCHDIR
196 (void)fchdir(fd);
197#else
198 chdir(start);
199#endif
200err2: (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) */