Branch data Line data Source code
1 : : /* SPDX-License-Identifier: LGPL-2.1+ */
2 : : #include <getopt.h>
3 : :
4 : : #include "fd-util.h"
5 : : #include "fs-util.h"
6 : : #include "log.h"
7 : : #include "main-func.h"
8 : :
9 : : static char *arg_root = NULL;
10 : : static int arg_flags = 0;
11 : :
12 : 0 : static int parse_argv(int argc, char *argv[]) {
13 : : enum {
14 : : ARG_ROOT = 0x1000,
15 : : };
16 : :
17 : : static const struct option options[] = {
18 : : { "help", no_argument, NULL, 'h' },
19 : : { "root", required_argument, NULL, ARG_ROOT },
20 : :
21 : : { "prefix-root", no_argument, NULL, CHASE_PREFIX_ROOT },
22 : : { "nonexistent", no_argument, NULL, CHASE_NONEXISTENT },
23 : : { "no_autofs", no_argument, NULL, CHASE_NO_AUTOFS },
24 : : { "safe", no_argument, NULL, CHASE_SAFE },
25 : : { "open", no_argument, NULL, CHASE_OPEN },
26 : : { "trail-slash", no_argument, NULL, CHASE_TRAIL_SLASH },
27 : : { "step", no_argument, NULL, CHASE_STEP },
28 : : { "nofollow", no_argument, NULL, CHASE_NOFOLLOW },
29 : : { "warn", no_argument, NULL, CHASE_WARN },
30 : : {}
31 : : };
32 : :
33 : : int c;
34 : :
35 [ # # ]: 0 : assert(argc >= 0);
36 [ # # ]: 0 : assert(argv);
37 : :
38 [ # # ]: 0 : while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
39 [ # # # # : 0 : switch (c) {
# ]
40 : :
41 : 0 : case 'h':
42 : 0 : printf("Syntax:\n"
43 : : " %s [OPTION...] path...\n"
44 : : "Options:\n"
45 : : , argv[0]);
46 [ # # ]: 0 : for (size_t i = 0; i < ELEMENTSOF(options) - 1; i++)
47 : 0 : printf(" --%s\n", options[i].name);
48 : 0 : return 0;
49 : :
50 : 0 : case ARG_ROOT:
51 : 0 : arg_root = optarg;
52 : 0 : break;
53 : :
54 : 0 : case CHASE_PREFIX_ROOT:
55 : : case CHASE_NONEXISTENT:
56 : : case CHASE_NO_AUTOFS:
57 : : case CHASE_SAFE:
58 : : case CHASE_OPEN:
59 : : case CHASE_TRAIL_SLASH:
60 : : case CHASE_STEP:
61 : : case CHASE_NOFOLLOW:
62 : : case CHASE_WARN:
63 : 0 : arg_flags |= c;
64 : 0 : break;
65 : :
66 : 0 : case '?':
67 : 0 : return -EINVAL;
68 : :
69 : 0 : default:
70 : 0 : assert_not_reached("Unhandled option");
71 : : }
72 : :
73 [ # # ]: 0 : if (optind == argc)
74 [ # # ]: 0 : return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "At least one argument is required.");
75 : :
76 : 0 : return 1;
77 : : }
78 : :
79 : 0 : static int run(int argc, char **argv) {
80 : : int r;
81 : :
82 : 0 : log_show_color(true);
83 : 0 : log_parse_environment();
84 : 0 : log_open();
85 : :
86 : 0 : r = parse_argv(argc, argv);
87 [ # # ]: 0 : if (r <= 0)
88 : 0 : return r;
89 : :
90 [ # # ]: 0 : for (int i = optind; i < argc; i++) {
91 : 0 : _cleanup_free_ char *p = NULL;
92 : :
93 : 0 : printf("%s ", argv[i]);
94 : 0 : fflush(stdout);
95 : :
96 : 0 : r = chase_symlinks(argv[i], arg_root, arg_flags, &p);
97 [ # # ]: 0 : if (r < 0)
98 [ # # ]: 0 : log_error_errno(r, "failed: %m");
99 : : else
100 [ # # ]: 0 : log_info("→ %s", p);
101 : :
102 [ # # ]: 0 : if (FLAGS_SET(arg_flags, CHASE_OPEN))
103 : 0 : safe_close(r);
104 : : }
105 : :
106 : 0 : return 0;
107 : : }
108 : :
109 : 0 : DEFINE_MAIN_FUNCTION(run);
|