version 1.11, 1997/09/23 20:21:28 |
version 1.12, 1997/09/23 20:39:11 |
|
|
#include <limits.h> |
#include <limits.h> |
#include <errno.h> |
#include <errno.h> |
#include <stdio.h> |
#include <stdio.h> |
|
#include <stdlib.h> |
#include <string.h> |
#include <string.h> |
#include <unistd.h> |
#include <unistd.h> |
|
|
void canonicalize __P((const char *, char *)); |
|
|
|
int |
int |
main(argc, argv) |
main(argc, argv) |
int argc; |
int argc; |
|
|
PATH_MAX - 1); |
PATH_MAX - 1); |
|
|
if (fflag) |
if (fflag) |
canonicalize(argv[0], buf); |
realpath(argv[0], buf); |
else if ((n = readlink(argv[0], buf, PATH_MAX)) < 0) |
else if ((n = readlink(argv[0], buf, PATH_MAX)) < 0) |
exit(1); |
exit(1); |
|
|
|
|
if (!nflag) |
if (!nflag) |
putchar('\n'); |
putchar('\n'); |
exit(0); |
exit(0); |
} |
|
|
|
void |
|
canonicalize(path, newpath) |
|
const char *path; |
|
char *newpath; |
|
{ |
|
int n; |
|
char *p, *np, *lp, c ; |
|
char target[PATH_MAX]; |
|
|
|
strcpy(newpath, path); |
|
for (;;) { |
|
p = np = newpath; |
|
|
|
/* |
|
* If absolute path, skip the root slash now so we won't |
|
* think of this as a NULL component. |
|
*/ |
|
if (*p == '/') |
|
p++; |
|
|
|
/* |
|
* loop through all components of the path until a link is |
|
* found then expand it, if no link is found we are ready. |
|
*/ |
|
for (; *p; lp = ++p) { |
|
while (*p && *p != '/') |
|
p++; |
|
c = *p; |
|
*p = '\0'; |
|
n = readlink(newpath, target, PATH_MAX); |
|
*p = c; |
|
if (n > 0 || errno != EINVAL) |
|
break; |
|
} |
|
if (!*p && n < 0 && errno == EINVAL) |
|
break; |
|
if (n < 0) |
|
err(1, "%s", newpath); |
|
target[n] = '\0'; |
|
#ifdef DEBUG |
|
fprintf(stderr, "%.*s -> %s : ", p - newpath, newpath, target); |
|
#endif |
|
if (*target == '/') { |
|
bcopy(p, newpath + n, strlen(p) + 1); |
|
bcopy(target, newpath, n); |
|
} else { |
|
bcopy(p, lp + n, strlen(p) + 1); |
|
bcopy(target, lp, n); |
|
} |
|
#ifdef DEBUG |
|
fprintf(stderr, "%s\n", newpath); |
|
#endif |
|
strncpy(target, newpath, sizeof target-1); |
|
target[sizeof target-1] = '\0'; |
|
path = target; |
|
} |
|
} |
} |