]>
Commit | Line | Data |
---|---|---|
53e1b683 | 1 | /* SPDX-License-Identifier: LGPL-2.1+ */ |
020d5900 | 2 | |
cef8b073 | 3 | #include <getopt.h> |
3a67e927 | 4 | |
020d5900 | 5 | #include "sd-daemon.h" |
3f6fd1ba | 6 | |
c03a80c4 YW |
7 | #include "daemon-util.h" |
8 | #include "main-func.h" | |
c5fcf6e4 | 9 | #include "manager.h" |
294bf0c3 | 10 | #include "pretty-print.h" |
3f6fd1ba LP |
11 | #include "signal-util.h" |
12 | #include "strv.h" | |
cef8b073 TG |
13 | |
14 | static bool arg_quiet = false; | |
e56cdb7a | 15 | static usec_t arg_timeout = 120 * USEC_PER_SEC; |
cef8b073 | 16 | static char **arg_interfaces = NULL; |
79b1f37d | 17 | static char **arg_ignore = NULL; |
cef8b073 | 18 | |
c03a80c4 YW |
19 | STATIC_DESTRUCTOR_REGISTER(arg_interfaces, strv_freep); |
20 | STATIC_DESTRUCTOR_REGISTER(arg_ignore, strv_freep); | |
21 | ||
37ec0fdd LP |
22 | static int help(void) { |
23 | _cleanup_free_ char *link = NULL; | |
24 | int r; | |
25 | ||
26 | r = terminal_urlify_man("systemd-networkd-wait-online.service", "8", &link); | |
27 | if (r < 0) | |
28 | return log_oom(); | |
29 | ||
cef8b073 TG |
30 | printf("%s [OPTIONS...]\n\n" |
31 | "Block until network is configured.\n\n" | |
32 | " -h --help Show this help\n" | |
33 | " --version Print version string\n" | |
34 | " -q --quiet Do not show status information\n" | |
601185b4 | 35 | " -i --interface=INTERFACE Block until at least these interfaces have appeared\n" |
79b1f37d | 36 | " --ignore=INTERFACE Don't take these interfaces into account\n" |
e56cdb7a | 37 | " --timeout=SECS Maximum time to wait for network connectivity\n" |
37ec0fdd LP |
38 | "\nSee the %s for details.\n" |
39 | , program_invocation_short_name | |
40 | , link | |
41 | ); | |
42 | ||
43 | return 0; | |
cef8b073 TG |
44 | } |
45 | ||
46 | static int parse_argv(int argc, char *argv[]) { | |
47 | ||
48 | enum { | |
49 | ARG_VERSION = 0x100, | |
79b1f37d | 50 | ARG_IGNORE, |
e56cdb7a | 51 | ARG_TIMEOUT, |
cef8b073 TG |
52 | }; |
53 | ||
54 | static const struct option options[] = { | |
55 | { "help", no_argument, NULL, 'h' }, | |
56 | { "version", no_argument, NULL, ARG_VERSION }, | |
57 | { "quiet", no_argument, NULL, 'q' }, | |
58 | { "interface", required_argument, NULL, 'i' }, | |
79b1f37d | 59 | { "ignore", required_argument, NULL, ARG_IGNORE }, |
e56cdb7a | 60 | { "timeout", required_argument, NULL, ARG_TIMEOUT }, |
cef8b073 TG |
61 | {} |
62 | }; | |
63 | ||
e56cdb7a | 64 | int c, r; |
cef8b073 TG |
65 | |
66 | assert(argc >= 0); | |
67 | assert(argv); | |
68 | ||
baee30af | 69 | while ((c = getopt_long(argc, argv, "+hi:q", options, NULL)) >= 0) |
cef8b073 TG |
70 | |
71 | switch (c) { | |
72 | ||
73 | case 'h': | |
601185b4 ZJS |
74 | help(); |
75 | return 0; | |
cef8b073 TG |
76 | |
77 | case 'q': | |
78 | arg_quiet = true; | |
79 | break; | |
80 | ||
81 | case ARG_VERSION: | |
3f6fd1ba | 82 | return version(); |
cef8b073 TG |
83 | |
84 | case 'i': | |
85 | if (strv_extend(&arg_interfaces, optarg) < 0) | |
86 | return log_oom(); | |
87 | ||
88 | break; | |
89 | ||
79b1f37d TG |
90 | case ARG_IGNORE: |
91 | if (strv_extend(&arg_ignore, optarg) < 0) | |
92 | return log_oom(); | |
93 | ||
94 | break; | |
95 | ||
e56cdb7a TG |
96 | case ARG_TIMEOUT: |
97 | r = parse_sec(optarg, &arg_timeout); | |
98 | if (r < 0) | |
99 | return r; | |
100 | ||
101 | break; | |
102 | ||
cef8b073 TG |
103 | case '?': |
104 | return -EINVAL; | |
105 | ||
106 | default: | |
107 | assert_not_reached("Unhandled option"); | |
108 | } | |
cef8b073 TG |
109 | |
110 | return 1; | |
111 | } | |
020d5900 | 112 | |
c03a80c4 YW |
113 | static int run(int argc, char *argv[]) { |
114 | _cleanup_(notify_on_cleanup) const char *notify_message = NULL; | |
7de12ae7 TG |
115 | _cleanup_(manager_freep) Manager *m = NULL; |
116 | int r; | |
cef8b073 | 117 | |
6bf3c61c | 118 | log_setup_service(); |
020d5900 | 119 | |
7de12ae7 TG |
120 | umask(0022); |
121 | ||
cef8b073 TG |
122 | r = parse_argv(argc, argv); |
123 | if (r <= 0) | |
124 | return r; | |
020d5900 | 125 | |
cef8b073 TG |
126 | if (arg_quiet) |
127 | log_set_max_level(LOG_WARNING); | |
020d5900 | 128 | |
72c0a2c2 | 129 | assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, -1) >= 0); |
3a67e927 | 130 | |
e56cdb7a | 131 | r = manager_new(&m, arg_interfaces, arg_ignore, arg_timeout); |
c03a80c4 YW |
132 | if (r < 0) |
133 | return log_error_errno(r, "Could not create manager: %m"); | |
020d5900 | 134 | |
c03a80c4 YW |
135 | if (manager_all_configured(m)) |
136 | goto success; | |
020d5900 | 137 | |
c03a80c4 YW |
138 | notify_message = notify_start("READY=1\n" |
139 | "STATUS=Waiting for network connections...", | |
140 | "STATUS=Failed to wait for network connectivity..."); | |
020d5900 | 141 | |
3a67e927 | 142 | r = sd_event_loop(m->event); |
c03a80c4 YW |
143 | if (r < 0) |
144 | return log_error_errno(r, "Event loop failed: %m"); | |
e56cdb7a | 145 | |
c03a80c4 YW |
146 | success: |
147 | notify_message = "STATUS=All interfaces configured..."; | |
e56cdb7a | 148 | |
c03a80c4 | 149 | return 0; |
020d5900 | 150 | } |
c03a80c4 YW |
151 | |
152 | DEFINE_MAIN_FUNCTION(run); |