]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/test/test-chase-symlinks.c
Merge pull request #16271 from yuwata/network-cleanups-around-link-get
[thirdparty/systemd.git] / src / test / test-chase-symlinks.c
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 static bool arg_open = false;
12
13 static int parse_argv(int argc, char *argv[]) {
14 enum {
15 ARG_ROOT = 0x1000,
16 ARG_OPEN,
17 };
18
19 static const struct option options[] = {
20 { "help", no_argument, NULL, 'h' },
21 { "root", required_argument, NULL, ARG_ROOT },
22 { "open", no_argument, NULL, ARG_OPEN },
23
24 { "prefix-root", no_argument, NULL, CHASE_PREFIX_ROOT },
25 { "nonexistent", no_argument, NULL, CHASE_NONEXISTENT },
26 { "no_autofs", no_argument, NULL, CHASE_NO_AUTOFS },
27 { "safe", no_argument, NULL, CHASE_SAFE },
28 { "trail-slash", no_argument, NULL, CHASE_TRAIL_SLASH },
29 { "step", no_argument, NULL, CHASE_STEP },
30 { "nofollow", no_argument, NULL, CHASE_NOFOLLOW },
31 { "warn", no_argument, NULL, CHASE_WARN },
32 {}
33 };
34
35 int c;
36
37 assert(argc >= 0);
38 assert(argv);
39
40 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
41 switch (c) {
42
43 case 'h':
44 printf("Syntax:\n"
45 " %s [OPTION...] path...\n"
46 "Options:\n"
47 , argv[0]);
48 for (size_t i = 0; i < ELEMENTSOF(options) - 1; i++)
49 printf(" --%s\n", options[i].name);
50 return 0;
51
52 case ARG_ROOT:
53 arg_root = optarg;
54 break;
55
56 case ARG_OPEN:
57 arg_open = true;
58 break;
59
60 case CHASE_PREFIX_ROOT:
61 case CHASE_NONEXISTENT:
62 case CHASE_NO_AUTOFS:
63 case CHASE_SAFE:
64 case CHASE_TRAIL_SLASH:
65 case CHASE_STEP:
66 case CHASE_NOFOLLOW:
67 case CHASE_WARN:
68 arg_flags |= c;
69 break;
70
71 case '?':
72 return -EINVAL;
73
74 default:
75 assert_not_reached("Unhandled option");
76 }
77
78 if (optind == argc)
79 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "At least one argument is required.");
80
81 return 1;
82 }
83
84 static int run(int argc, char **argv) {
85 int r;
86
87 log_setup_cli();
88
89 r = parse_argv(argc, argv);
90 if (r <= 0)
91 return r;
92
93 for (int i = optind; i < argc; i++) {
94 _cleanup_free_ char *p = NULL;
95 _cleanup_close_ int fd = -1;
96
97 printf("%s ", argv[i]);
98 fflush(stdout);
99
100 r = chase_symlinks(argv[i], arg_root, arg_flags, &p, arg_open ? &fd : NULL);
101 if (r < 0)
102 log_error_errno(r, "failed: %m");
103 else {
104 log_info("→ %s", p);
105 if (arg_open)
106 assert(fd >= 0);
107 else
108 assert(fd == -1);
109 }
110 }
111
112 return 0;
113 }
114
115 DEFINE_MAIN_FUNCTION(run);