]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/networkd-wait-online.c
networkd-wait-online: use automatic cleanup
[thirdparty/systemd.git] / src / network / networkd-wait-online.c
CommitLineData
020d5900
TG
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
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
22#include "sd-event.h"
e1528e08 23#include "event-util.h"
020d5900
TG
24#include "sd-daemon.h"
25#include "sd-network.h"
e1528e08 26#include "network-util.h"
020d5900
TG
27
28#include "util.h"
29
30static bool all_configured(void) {
31 _cleanup_free_ unsigned *indices = NULL;
32 bool one_ready = false;
33 int r, n, i;
34
35 n = sd_network_get_ifindices(&indices);
36 if (n <= 0)
37 return false;
38
39 for (i = 0; i < n; i++) {
40 _cleanup_free_ char *state = NULL;
41
42 r = sd_network_get_link_state(indices[i], &state);
cb6fa44c
TG
43 if (r == -EUNATCH)
44 continue;
45 if (r < 0 || !streq(state, "configured"))
020d5900
TG
46 return false;
47
cb6fa44c 48 one_ready = true;
020d5900
TG
49 }
50
cb6fa44c 51 return one_ready;
020d5900
TG
52}
53
54static int event_handler(sd_event_source *s, int fd, uint32_t revents,
55 void *userdata) {
56 sd_event *event = userdata;
57
58 assert(event);
59
60 if (all_configured())
61 sd_event_exit(event, 0);
62
63 return 1;
64}
65
66int main(int argc, char *argv[]) {
e1528e08
TA
67 _cleanup_event_unref_ sd_event *event = NULL;
68 _cleanup_event_source_unref_ sd_event_source *event_source = NULL;
69 _cleanup_network_monitor_unref_ sd_network_monitor *monitor = NULL;
020d5900
TG
70 int r, fd, events;
71
72 log_set_target(LOG_TARGET_AUTO);
73 log_parse_environment();
74 log_open();
75
76 umask(0022);
77
78 if (argc != 1) {
79 log_error("This program takes no arguments.");
80 r = -EINVAL;
81 goto out;
82 }
83
84 r = sd_network_monitor_new(NULL, &monitor);
85 if (r < 0) {
86 log_error("Could not create monitor: %s", strerror(-r));
87 goto out;
88 }
89
90 r = sd_event_new(&event);
91 if (r < 0) {
92 log_error("Could not create event: %s", strerror(-r));
93 goto out;
94 }
95
96 fd = sd_network_monitor_get_fd(monitor);
97 if (fd < 0) {
98 log_error("Could not get monitor fd: %s", strerror(-r));
99 goto out;
100 }
101
102 events = sd_network_monitor_get_events(monitor);
103 if (events < 0) {
104 log_error("Could not get monitor events: %s", strerror(-r));
105 goto out;
106 }
107
108 r = sd_event_add_io(event, &event_source, fd, events, &event_handler,
109 event);
110 if (r < 0) {
111 log_error("Could not add io event source: %s", strerror(-r));
112 goto out;
113 }
114
115 if (all_configured()) {
116 r = 0;
117 goto out;
118 }
119
120 sd_notify(false,
121 "READY=1\n"
122 "STATUS=Waiting for network connecitons...");
123
124 r = sd_event_loop(event);
125 if (r < 0) {
126 log_error("Event loop failed: %s", strerror(-r));
127 goto out;
128 }
129
130out:
131 sd_notify(false,
132 "STATUS=All interfaces configured...");
133
020d5900
TG
134 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
135}