ls: reorder and rename functions. No code changes
[platform/upstream/busybox.git] / coreutils / readlink.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * Mini readlink implementation for busybox
4  *
5  * Copyright (C) 2000,2001 Matt Kraai <kraai@alumni.carnegiemellon.edu>
6  *
7  * Licensed under GPLv2 or later, see file LICENSE in this source tree.
8  */
9
10 //usage:#define readlink_trivial_usage
11 //usage:        IF_FEATURE_READLINK_FOLLOW("[-fnv] ") "FILE"
12 //usage:#define readlink_full_usage "\n\n"
13 //usage:       "Display the value of a symlink"
14 //usage:        IF_FEATURE_READLINK_FOLLOW( "\n"
15 //usage:     "\nOptions:"
16 //usage:     "\n        -f      Canonicalize by following all symlinks"
17 //usage:     "\n        -n      Don't add newline"
18 //usage:     "\n        -v      Verbose"
19 //usage:        )
20
21 #include "libbb.h"
22
23 /*
24  * # readlink --version
25  * readlink (GNU coreutils) 6.10
26  * # readlink --help
27  *   -f, --canonicalize
28  *      canonicalize by following every symlink in
29  *      every component of the given name recursively;
30  *      all but the last component must exist
31  *   -e, --canonicalize-existing
32  *      canonicalize by following every symlink in
33  *      every component of the given name recursively,
34  *      all components must exist
35  *   -m, --canonicalize-missing
36  *      canonicalize by following every symlink in
37  *      every component of the given name recursively,
38  *      without requirements on components existence
39  *   -n, --no-newline              do not output the trailing newline
40  *   -q, --quiet, -s, --silent     suppress most error messages
41  *   -v, --verbose                 report error messages
42  *
43  * bbox supports: -f -n -v (fully), -q -s (accepts but ignores)
44  */
45
46 int readlink_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
47 int readlink_main(int argc UNUSED_PARAM, char **argv)
48 {
49         char *buf;
50         char *fname;
51
52         IF_FEATURE_READLINK_FOLLOW(
53                 unsigned opt;
54                 /* We need exactly one non-option argument.  */
55                 opt_complementary = "=1";
56                 opt = getopt32(argv, "fnvsq");
57                 fname = argv[optind];
58         )
59         IF_NOT_FEATURE_READLINK_FOLLOW(
60                 const unsigned opt = 0;
61                 if (argc != 2) bb_show_usage();
62                 fname = argv[1];
63         )
64
65         /* compat: coreutils readlink reports errors silently via exit code */
66         if (!(opt & 4)) /* not -v */
67                 logmode = LOGMODE_NONE;
68
69         if (opt & 1) { /* -f */
70                 buf = xmalloc_realpath(fname);
71         } else {
72                 buf = xmalloc_readlink_or_warn(fname);
73         }
74
75         if (!buf)
76                 return EXIT_FAILURE;
77         printf((opt & 2) ? "%s" : "%s\n", buf);
78
79         if (ENABLE_FEATURE_CLEAN_UP)
80                 free(buf);
81
82         fflush_stdout_and_exit(EXIT_SUCCESS);
83 }