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