summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Kaivo <jkk@ung.org>2019-08-06 11:46:20 -0400
committerJakob Kaivo <jkk@ung.org>2019-08-06 11:46:20 -0400
commit8dcd4de6ba99556d994487cf0c8d99e467ab6757 (patch)
tree0dcdbc1e902548bd74f6156cca09e4ec80004bed
parent775b4bb0f74f8b7ebc79dd0ed9a48384e3aadc7f (diff)
make single item reuse ln() function
-rw-r--r--ln.c62
1 files changed, 20 insertions, 42 deletions
diff --git a/ln.c b/ln.c
index d6e8fbc..3ff367b 100644
--- a/ln.c
+++ b/ln.c
@@ -35,29 +35,33 @@
#define O_SEARCH 0
#endif
-static int ln(const char *path, int dirfd, int sym, int force, int flag)
+static int ln(const char *path, int dirfd, const char *target, int sym, int force, int flag)
{
+ if (!target) {
+ target = path;
+ }
+
struct stat st;
- if (fstatat(dirfd, path, &st, AT_SYMLINK_NOFOLLOW) == 0) {
+ if (fstatat(dirfd, target, &st, AT_SYMLINK_NOFOLLOW) == 0) {
if (!force) {
- fprintf(stderr, "ln: %s: %s\n", path, strerror(EEXIST));
+ fprintf(stderr, "ln: %s: %s\n", target, strerror(EEXIST));
return 1;
}
- if (unlinkat(dirfd, path, 0) != 0) {
- fprintf(stderr, "ln: %s: %s\n", path, strerror(errno));
+ if (unlinkat(dirfd, target, 0) != 0) {
+ fprintf(stderr, "ln: %s: %s\n", target, strerror(errno));
return 1;
}
}
if (sym) {
- if (symlinkat(path, dirfd, path) != 0) {
- fprintf(stderr, "ln: %s: %s\n", path, strerror(errno));
+ if (symlinkat(path, dirfd, target) != 0) {
+ fprintf(stderr, "ln: %s -> %s: %s\n", path, target, strerror(errno));
return 1;
}
} else {
- if (linkat(AT_FDCWD, path, dirfd, path, flag) != 0) {
- fprintf(stderr, "ln: %s: %s\n", path, strerror(errno));
+ if (linkat(AT_FDCWD, path, dirfd, target, flag) != 0) {
+ fprintf(stderr, "ln: %s -> %s: %s\n", path, target, strerror(errno));
return 1;
}
}
@@ -105,46 +109,20 @@ int main(int argc, char *argv[])
char *target = argv[argc - 1];
int dirfd = open(target, O_SEARCH | O_DIRECTORY);
- if (dirfd == -1) {
- if (errno == ENOTDIR) {
- /* not a directory */
- } else if (errno == ENOENT) {
- /* doesn't exist */
- } else {
- return 1;
- }
- }
-
if (argc - optind == 2) {
- struct stat st;
- if (stat(target, &st) == 0) {
- if (S_ISDIR(st.st_mode)) {
- return ln(argv[optind], dirfd, symbolic, force, flag);
- }
-
- if (!force) {
- fprintf(stderr, "ln: %s: %s\n", target, strerror(EEXIST));
- return 1;
- }
-
- if (unlink(target) != 0) {
- fprintf(stderr, "ln: %s: %s\n", target, strerror(errno));
- return 1;
- }
- }
-
- int r = symbolic ? symlink(argv[optind], target) :
- link(argv[optind], target);
- if (r != 0) {
- fprintf(stderr, "ln: %s -> %s: %s\n", argv[optind], target, strerror(errno));
+ if (dirfd == -1) {
+ dirfd = AT_FDCWD;
}
+ return ln(argv[optind], dirfd, target, symbolic, force, flag);
+ }
- return r;
+ if (dirfd == -1) {
+ fprintf(stderr, "ln: %s: %s\n", target, strerror(errno));
}
int r = 0;
do {
- r |= ln(argv[optind++], dirfd, symbolic, force, flag);
+ r |= ln(argv[optind++], dirfd, NULL, symbolic, force, flag);
} while (optind < argc - 1);
return r;
}