]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/network/wait-online/wait-online.c
tree-wide: beautify remaining copyright statements
[thirdparty/systemd.git] / src / network / wait-online / wait-online.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2
3 /***
4 Copyright © 2013 Tom Gundersen <teg@jklm.no>
5 ***/
6
7 #include <getopt.h>
8
9 #include "sd-daemon.h"
10
11 #include "manager.h"
12 #include "signal-util.h"
13 #include "strv.h"
14
15 static bool arg_quiet = false;
16 static usec_t arg_timeout = 120 * USEC_PER_SEC;
17 static char **arg_interfaces = NULL;
18 static char **arg_ignore = NULL;
19
20 static void help(void) {
21 printf("%s [OPTIONS...]\n\n"
22 "Block until network is configured.\n\n"
23 " -h --help Show this help\n"
24 " --version Print version string\n"
25 " -q --quiet Do not show status information\n"
26 " -i --interface=INTERFACE Block until at least these interfaces have appeared\n"
27 " --ignore=INTERFACE Don't take these interfaces into account\n"
28 " --timeout=SECS Maximum time to wait for network connectivity\n"
29 , program_invocation_short_name);
30 }
31
32 static int parse_argv(int argc, char *argv[]) {
33
34 enum {
35 ARG_VERSION = 0x100,
36 ARG_IGNORE,
37 ARG_TIMEOUT,
38 };
39
40 static const struct option options[] = {
41 { "help", no_argument, NULL, 'h' },
42 { "version", no_argument, NULL, ARG_VERSION },
43 { "quiet", no_argument, NULL, 'q' },
44 { "interface", required_argument, NULL, 'i' },
45 { "ignore", required_argument, NULL, ARG_IGNORE },
46 { "timeout", required_argument, NULL, ARG_TIMEOUT },
47 {}
48 };
49
50 int c, r;
51
52 assert(argc >= 0);
53 assert(argv);
54
55 while ((c = getopt_long(argc, argv, "+hi:q", options, NULL)) >= 0)
56
57 switch (c) {
58
59 case 'h':
60 help();
61 return 0;
62
63 case 'q':
64 arg_quiet = true;
65 break;
66
67 case ARG_VERSION:
68 return version();
69
70 case 'i':
71 if (strv_extend(&arg_interfaces, optarg) < 0)
72 return log_oom();
73
74 break;
75
76 case ARG_IGNORE:
77 if (strv_extend(&arg_ignore, optarg) < 0)
78 return log_oom();
79
80 break;
81
82 case ARG_TIMEOUT:
83 r = parse_sec(optarg, &arg_timeout);
84 if (r < 0)
85 return r;
86
87 break;
88
89 case '?':
90 return -EINVAL;
91
92 default:
93 assert_not_reached("Unhandled option");
94 }
95
96 return 1;
97 }
98
99 int main(int argc, char *argv[]) {
100 _cleanup_(manager_freep) Manager *m = NULL;
101 int r;
102
103 log_set_target(LOG_TARGET_AUTO);
104 log_parse_environment();
105 log_open();
106
107 umask(0022);
108
109 r = parse_argv(argc, argv);
110 if (r <= 0)
111 return r;
112
113 if (arg_quiet)
114 log_set_max_level(LOG_WARNING);
115
116 assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, -1) >= 0);
117
118 r = manager_new(&m, arg_interfaces, arg_ignore, arg_timeout);
119 if (r < 0) {
120 log_error_errno(r, "Could not create manager: %m");
121 goto finish;
122 }
123
124 if (manager_all_configured(m)) {
125 r = 0;
126 goto finish;
127 }
128
129 sd_notify(false,
130 "READY=1\n"
131 "STATUS=Waiting for network connections...");
132
133 r = sd_event_loop(m->event);
134 if (r < 0) {
135 log_error_errno(r, "Event loop failed: %m");
136 goto finish;
137 }
138
139 finish:
140 strv_free(arg_interfaces);
141 strv_free(arg_ignore);
142
143 if (r >= 0) {
144 sd_notify(false, "STATUS=All interfaces configured...");
145
146 return EXIT_SUCCESS;
147 } else {
148 sd_notify(false, "STATUS=Failed waiting for network connectivity...");
149
150 return EXIT_FAILURE;
151 }
152 }