diff options
Diffstat (limited to 'ln.c')
-rw-r--r-- | ln.c | 51 |
1 files changed, 51 insertions, 0 deletions
@@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * Copyright (C) 2022, 2023 Ferass El Hafidi <vitali64pmemail@protonmail.com> + */ +#include <unistd.h> +#include <stdio.h> +#include <errno.h> +#include <string.h> + +#define REQ_PRINT_USAGE /* Require print_usage() from common.h */ +#define REQ_ERRPRINT /* Require errprint() from common.h */ +#define DESCRIPTION "Link files." +#define OPERANDS "[-fs] [-P|-L] source_file target_file" +#include "common.h" + +int getopt(int argc, char *const argv[], const char *optstring); + +#ifdef FASESBOX +int ln_main(int argc, char *argv[]) { +#else +int main(int argc, char *argv[]) { +#endif + int argument; + char param[256], *buffer = NULL, *argv0 = strdup(argv[0]); + + while ((argument = getopt(argc, argv, "fsPL")) != -1) { + if (argument == '?') { + print_usage(argv[0], DESCRIPTION, OPERANDS, VERSION); + return 1; + } + param[argument] = argument; + } argc -= optind; argv += optind; + if (argc != 2) { + print_usage(argv[0], DESCRIPTION, OPERANDS, VERSION); + return 1; + } + if (param['f']) remove(argv[1]); + if (errno && errno != ENOENT) return errprint(argv0, argv[0], errno); + errno = 0; /* Not reached if errno == ENOENT (no such file) */ + if (param['s']) symlink(argv[0], argv[1]); + /* The -P option is the default behavior (at least on musl), + * so no if statement. + */ + else if (param['L']) { + readlink(argv[0], buffer, strlen(buffer)); /* Read the link */ + if (errno) return errprint(argv0, argv[0], errno); + link(buffer, argv[1]); + } + else link(argv[0], argv[1]); + return errprint(argv0, argv[0], errno); +} |