1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
14 * The Original Code is the Netscape security libraries.
16 * The Initial Developer of the Original Code is
17 * Netscape Communications Corporation.
18 * Portions created by the Initial Developer are Copyright (C) 1994-2000
19 * the Initial Developer. All Rights Reserved.
23 * Alternatively, the contents of this file may be used under the terms of
24 * either the GNU General Public License Version 2 or later (the "GPL"), or
25 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26 * in which case the provisions of the GPL or the LGPL are applicable instead
27 * of those above. If you wish to allow use of your version of this file only
28 * under the terms of either the GPL or the LGPL, and not to allow others to
29 * use your version of this file under the terms of the MPL, indicate your
30 * decision by deleting the provisions above and replace them with the notice
31 * and other provisions required by the GPL or the LGPL. If you do not delete
32 * the provisions above, a recipient may use your version of this file under
33 * the terms of any one of the MPL, the GPL or the LGPL.
35 * ***** END LICENSE BLOCK ***** */
38 ** Pathname subroutines.
41 #if defined(FREEBSD) || defined(BSDI) || defined(DARWIN)
42 #include <sys/types.h>
51 #include <sys/types.h>
54 #ifdef USE_REENTRANT_LIBC
56 #endif /* USE_REENTRANT_LIBC */
61 fail(char *format
, ...)
66 #ifdef USE_REENTRANT_LIBC
71 fprintf(stderr
, "%s: ", program
);
73 vfprintf(stderr
, format
, ap
);
77 #ifdef USE_REENTRANT_LIBC
79 fprintf(stderr
, ": %s", r_strerror_r
);
81 fprintf(stderr
, ": %s", strerror(errno
));
91 getcomponent(char *path
, char *name
)
100 } while (*path
!= '/' && *path
!= '\0');
109 /* The static buffer in Unixware's readdir is too small. */
110 struct dirent
* readdir(DIR *d
)
112 static struct dirent
*buf
= NULL
;
113 #define MAX_PATH_LEN 1024
116 buf
= (struct dirent
*)xmalloc(sizeof(struct dirent
) + MAX_PATH_LEN
) ;
117 return readdir_r(d
, buf
);
121 /* APPARENT BUG - ignores argument "dir", uses ".." instead. */
123 ino2name(ino_t ino
, char *dir
)
129 dp
= opendir(".."); /* XXX */
131 fail("cannot read parent directory");
133 if (!(ep
= readdir(dp
)))
134 fail("cannot find current directory");
135 if (ep
->d_ino
== ino
)
138 name
= xstrdup(ep
->d_name
);
149 fail("attempted to allocate %u bytes", size
);
152 fail("cannot allocate %u bytes", size
);
160 fail("Null pointer or empty string passed to xstrdup()");
161 return strcpy((char*)xmalloc(strlen(s
) + 1), s
);
165 xbasename(char *path
)
169 if (!path
|| !path
[0])
170 fail("Null pointer or empty string passed to xbasename()");
171 while ((cp
= strrchr(path
, '/')) && cp
[1] == '\0')
173 if (!cp
) return path
;
181 fail("Null pointer or empty string passed to xchdir()");
183 fail("cannot change directory to %s", dir
);
187 relatepaths(char *from
, char *to
, char *outpath
)
193 assert(*from
== '/' && *to
== '/');
194 if (!from
|| *from
!= '/')
195 fail("relatepaths: from path does not start with /");
196 if (!to
|| *to
!= '/')
197 fail("relatepaths: to path does not start with /");
199 for (cp
= to
, cp2
= from
; *cp
== *cp2
; cp
++, cp2
++)
202 while (cp
[-1] != '/')
205 /* closest common ancestor is /, so use full pathname */
206 len
= strlen(strcpy(outpath
, to
));
207 if (outpath
[len
] != '/') {
208 outpath
[len
++] = '/';
213 while ((cp2
= getcomponent(cp2
, buf
)) != 0) {
214 strcpy(outpath
+ len
, "../");
217 while ((cp
= getcomponent(cp
, buf
)) != 0) {
218 sprintf(outpath
+ len
, "%s/", buf
);
219 len
+= strlen(outpath
+ len
);
226 reversepath(char *inpath
, char *name
, int len
, char *outpath
)
232 cp
= strcpy(outpath
+ PATH_MAX
- (len
+ 1), name
);
234 while ((cp2
= getcomponent(cp2
, buf
)) != 0) {
235 if (strcmp(buf
, ".") == 0)
237 if (strcmp(buf
, "..") == 0) {
238 if (stat(".", &sb
) < 0)
239 fail("cannot stat current directory");
240 name
= ino2name(sb
.st_ino
, "..");
249 strncpy(cp
, "../", 3);
257 diagnosePath(const char * path
)
265 if (!path
|| !path
[0])
266 fail("Null pointer or empty string passed to mkdirs()");
267 myPath
= strdup(path
);
269 fail("strdup() failed!");
271 rv
= lstat(myPath
, &sb
);
274 } else if (S_ISLNK(sb
.st_mode
)) {
275 rv
= readlink(myPath
, buf
, sizeof buf
);
282 fprintf(stderr
, "%s is a link to %s\n", myPath
, buf
);
283 } else if (S_ISDIR(sb
.st_mode
)) {
284 fprintf(stderr
, "%s is a directory\n", myPath
);
285 rv
= access(myPath
, X_OK
);
287 fprintf(stderr
, "%s: no search permission\n", myPath
);
290 fprintf(stderr
, "%s is a file !?!\n", myPath
);
291 rv
= access(myPath
, F_OK
);
293 fprintf(stderr
, "%s does not exist\n", myPath
);
297 /* chop path off one level. */
298 slash
= strrchr(myPath
, '/');
300 slash
= strrchr(myPath
, '\\');