]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/network/wait-online/wait-online.c
wait-online: define main through macro
[thirdparty/systemd.git] / src / network / wait-online / wait-online.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2
3 #include <getopt.h>
4
5 #include "sd-daemon.h"
6
7 #include "daemon-util.h"
8 #include "main-func.h"
9 #include "manager.h"
10 #include "pretty-print.h"
11 #include "signal-util.h"
12 #include "strv.h"
13
14 static bool arg_quiet = false;
15 static usec_t arg_timeout = 120 * USEC_PER_SEC;
16 static char **arg_interfaces = NULL;
17 static char **arg_ignore = NULL;
18
19 STATIC_DESTRUCTOR_REGISTER(arg_interfaces, strv_freep);
20 STATIC_DESTRUCTOR_REGISTER(arg_ignore, strv_freep);
21
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
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"
35 " -i --interface=INTERFACE Block until at least these interfaces have appeared\n"
36 " --ignore=INTERFACE Don't take these interfaces into account\n"
37 " --timeout=SECS Maximum time to wait for network connectivity\n"
38 "\nSee the %s for details.\n"
39 , program_invocation_short_name
40 , link
41 );
42
43 return 0;
44 }
45
46 static int parse_argv(int argc, char *argv[]) {
47
48 enum {
49 ARG_VERSION = 0x100,
50 ARG_IGNORE,
51 ARG_TIMEOUT,
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' },
59 { "ignore", required_argument, NULL, ARG_IGNORE },
60 { "timeout", required_argument, NULL, ARG_TIMEOUT },
61 {}
62 };
63
64 int c, r;
65
66 assert(argc >= 0);
67 assert(argv);
68
69 while ((c = getopt_long(argc, argv, "+hi:q", options, NULL)) >= 0)
70
71 switch (c) {
72
73 case 'h':
74 help();
75 return 0;
76
77 case 'q':
78 arg_quiet = true;
79 break;
80
81 case ARG_VERSION:
82 return version();
83
84 case 'i':
85 if (strv_extend(&arg_interfaces, optarg) < 0)
86 return log_oom();
87
88 break;
89
90 case ARG_IGNORE:
91 if (strv_extend(&arg_ignore, optarg) < 0)
92 return log_oom();
93
94 break;
95
96 case ARG_TIMEOUT:
97 r = parse_sec(optarg, &arg_timeout);
98 if (r < 0)
99 return r;
100
101 break;
102
103 case '?':
104 return -EINVAL;
105
106 default:
107 assert_not_reached("Unhandled option");
108 }
109
110 return 1;
111 }
112
113 static int run(int argc, char *argv[]) {
114 _cleanup_(notify_on_cleanup) const char *notify_message = NULL;
115 _cleanup_(manager_freep) Manager *m = NULL;
116 int r;
117
118 log_setup_service();
119
120 umask(0022);
121
122 r = parse_argv(argc, argv);
123 if (r <= 0)
124 return r;
125
126 if (arg_quiet)
127 log_set_max_level(LOG_WARNING);
128
129 assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, -1) >= 0);
130
131 r = manager_new(&m, arg_interfaces, arg_ignore, arg_timeout);
132 if (r < 0)
133 return log_error_errno(r, "Could not create manager: %m");
134
135 if (manager_all_configured(m))
136 goto success;
137
138 notify_message = notify_start("READY=1\n"
139 "STATUS=Waiting for network connections...",
140 "STATUS=Failed to wait for network connectivity...");
141
142 r = sd_event_loop(m->event);
143 if (r < 0)
144 return log_error_errno(r, "Event loop failed: %m");
145
146 success:
147 notify_message = "STATUS=All interfaces configured...";
148
149 return 0;
150 }
151
152 DEFINE_MAIN_FUNCTION(run);