]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/wait-online/wait-online.c
Add SPDX license identifiers to source files under the LGPL
[thirdparty/systemd.git] / src / network / wait-online / wait-online.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
020d5900
TG
2
3/***
4 This file is part of systemd.
5
6 Copyright 2013 Tom Gundersen <teg@jklm.no>
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
cef8b073 22#include <getopt.h>
3a67e927 23
020d5900 24#include "sd-daemon.h"
3f6fd1ba 25
c5fcf6e4 26#include "manager.h"
3f6fd1ba
LP
27#include "signal-util.h"
28#include "strv.h"
cef8b073
TG
29
30static bool arg_quiet = false;
e56cdb7a 31static usec_t arg_timeout = 120 * USEC_PER_SEC;
cef8b073 32static char **arg_interfaces = NULL;
79b1f37d 33static char **arg_ignore = NULL;
cef8b073 34
601185b4 35static void help(void) {
cef8b073
TG
36 printf("%s [OPTIONS...]\n\n"
37 "Block until network is configured.\n\n"
38 " -h --help Show this help\n"
39 " --version Print version string\n"
40 " -q --quiet Do not show status information\n"
601185b4 41 " -i --interface=INTERFACE Block until at least these interfaces have appeared\n"
79b1f37d 42 " --ignore=INTERFACE Don't take these interfaces into account\n"
e56cdb7a 43 " --timeout=SECS Maximum time to wait for network connectivity\n"
601185b4 44 , program_invocation_short_name);
cef8b073
TG
45}
46
47static int parse_argv(int argc, char *argv[]) {
48
49 enum {
50 ARG_VERSION = 0x100,
79b1f37d 51 ARG_IGNORE,
e56cdb7a 52 ARG_TIMEOUT,
cef8b073
TG
53 };
54
55 static const struct option options[] = {
56 { "help", no_argument, NULL, 'h' },
57 { "version", no_argument, NULL, ARG_VERSION },
58 { "quiet", no_argument, NULL, 'q' },
59 { "interface", required_argument, NULL, 'i' },
79b1f37d 60 { "ignore", required_argument, NULL, ARG_IGNORE },
e56cdb7a 61 { "timeout", required_argument, NULL, ARG_TIMEOUT },
cef8b073
TG
62 {}
63 };
64
e56cdb7a 65 int c, r;
cef8b073
TG
66
67 assert(argc >= 0);
68 assert(argv);
69
baee30af 70 while ((c = getopt_long(argc, argv, "+hi:q", options, NULL)) >= 0)
cef8b073
TG
71
72 switch (c) {
73
74 case 'h':
601185b4
ZJS
75 help();
76 return 0;
cef8b073
TG
77
78 case 'q':
79 arg_quiet = true;
80 break;
81
82 case ARG_VERSION:
3f6fd1ba 83 return version();
cef8b073
TG
84
85 case 'i':
86 if (strv_extend(&arg_interfaces, optarg) < 0)
87 return log_oom();
88
89 break;
90
79b1f37d
TG
91 case ARG_IGNORE:
92 if (strv_extend(&arg_ignore, optarg) < 0)
93 return log_oom();
94
95 break;
96
e56cdb7a
TG
97 case ARG_TIMEOUT:
98 r = parse_sec(optarg, &arg_timeout);
99 if (r < 0)
100 return r;
101
102 break;
103
cef8b073
TG
104 case '?':
105 return -EINVAL;
106
107 default:
108 assert_not_reached("Unhandled option");
109 }
cef8b073
TG
110
111 return 1;
112}
020d5900 113
020d5900 114int main(int argc, char *argv[]) {
7de12ae7
TG
115 _cleanup_(manager_freep) Manager *m = NULL;
116 int r;
cef8b073 117
7de12ae7 118 log_set_target(LOG_TARGET_AUTO);
020d5900
TG
119 log_parse_environment();
120 log_open();
121
7de12ae7
TG
122 umask(0022);
123
cef8b073
TG
124 r = parse_argv(argc, argv);
125 if (r <= 0)
126 return r;
020d5900 127
cef8b073
TG
128 if (arg_quiet)
129 log_set_max_level(LOG_WARNING);
020d5900 130
72c0a2c2 131 assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, -1) >= 0);
3a67e927 132
e56cdb7a 133 r = manager_new(&m, arg_interfaces, arg_ignore, arg_timeout);
020d5900 134 if (r < 0) {
da927ba9 135 log_error_errno(r, "Could not create manager: %m");
7de12ae7 136 goto finish;
020d5900
TG
137 }
138
7de12ae7 139 if (manager_all_configured(m)) {
020d5900 140 r = 0;
7de12ae7 141 goto finish;
020d5900
TG
142 }
143
144 sd_notify(false,
145 "READY=1\n"
b6b8adbf 146 "STATUS=Waiting for network connections...");
020d5900 147
3a67e927 148 r = sd_event_loop(m->event);
020d5900 149 if (r < 0) {
da927ba9 150 log_error_errno(r, "Event loop failed: %m");
7de12ae7 151 goto finish;
020d5900
TG
152 }
153
7de12ae7 154finish:
79b1f37d
TG
155 strv_free(arg_interfaces);
156 strv_free(arg_ignore);
157
e56cdb7a
TG
158 if (r >= 0) {
159 sd_notify(false, "STATUS=All interfaces configured...");
160
161 return EXIT_SUCCESS;
162 } else {
163 sd_notify(false, "STATUS=Failed waiting for network connectivity...");
164
165 return EXIT_FAILURE;
166 }
020d5900 167}