1*de1e4e89SAndroid Build Coastguard Worker /*
2*de1e4e89SAndroid Build Coastguard Worker * ip.c "ip" utility frontend.
3*de1e4e89SAndroid Build Coastguard Worker *
4*de1e4e89SAndroid Build Coastguard Worker * This program is free software; you can redistribute it and/or
5*de1e4e89SAndroid Build Coastguard Worker * modify it under the terms of the GNU General Public License
6*de1e4e89SAndroid Build Coastguard Worker * as published by the Free Software Foundation; either version
7*de1e4e89SAndroid Build Coastguard Worker * 2 of the License, or (at your option) any later version.
8*de1e4e89SAndroid Build Coastguard Worker *
9*de1e4e89SAndroid Build Coastguard Worker * Authors: Alexey Kuznetsov, <[email protected]>
10*de1e4e89SAndroid Build Coastguard Worker */
11*de1e4e89SAndroid Build Coastguard Worker
12*de1e4e89SAndroid Build Coastguard Worker #include <stdio.h>
13*de1e4e89SAndroid Build Coastguard Worker #include <stdlib.h>
14*de1e4e89SAndroid Build Coastguard Worker #include <unistd.h>
15*de1e4e89SAndroid Build Coastguard Worker #include <syslog.h>
16*de1e4e89SAndroid Build Coastguard Worker #include <fcntl.h>
17*de1e4e89SAndroid Build Coastguard Worker #include <sys/socket.h>
18*de1e4e89SAndroid Build Coastguard Worker #include <netinet/in.h>
19*de1e4e89SAndroid Build Coastguard Worker #include <string.h>
20*de1e4e89SAndroid Build Coastguard Worker #include <errno.h>
21*de1e4e89SAndroid Build Coastguard Worker
22*de1e4e89SAndroid Build Coastguard Worker #include "SNAPSHOT.h"
23*de1e4e89SAndroid Build Coastguard Worker #include "utils.h"
24*de1e4e89SAndroid Build Coastguard Worker #include "ip_common.h"
25*de1e4e89SAndroid Build Coastguard Worker #include "namespace.h"
26*de1e4e89SAndroid Build Coastguard Worker #include "color.h"
27*de1e4e89SAndroid Build Coastguard Worker
28*de1e4e89SAndroid Build Coastguard Worker int preferred_family = AF_UNSPEC;
29*de1e4e89SAndroid Build Coastguard Worker int human_readable;
30*de1e4e89SAndroid Build Coastguard Worker int use_iec;
31*de1e4e89SAndroid Build Coastguard Worker int show_stats;
32*de1e4e89SAndroid Build Coastguard Worker int show_details;
33*de1e4e89SAndroid Build Coastguard Worker int oneline;
34*de1e4e89SAndroid Build Coastguard Worker int brief;
35*de1e4e89SAndroid Build Coastguard Worker int json;
36*de1e4e89SAndroid Build Coastguard Worker int timestamp;
37*de1e4e89SAndroid Build Coastguard Worker const char *_SL_;
38*de1e4e89SAndroid Build Coastguard Worker int force;
39*de1e4e89SAndroid Build Coastguard Worker int max_flush_loops = 10;
40*de1e4e89SAndroid Build Coastguard Worker int batch_mode;
41*de1e4e89SAndroid Build Coastguard Worker bool do_all;
42*de1e4e89SAndroid Build Coastguard Worker
43*de1e4e89SAndroid Build Coastguard Worker struct rtnl_handle rth = { .fd = -1 };
44*de1e4e89SAndroid Build Coastguard Worker
45*de1e4e89SAndroid Build Coastguard Worker static void usage(void) __attribute__((noreturn));
46*de1e4e89SAndroid Build Coastguard Worker
usage(void)47*de1e4e89SAndroid Build Coastguard Worker static void usage(void)
48*de1e4e89SAndroid Build Coastguard Worker {
49*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr,
50*de1e4e89SAndroid Build Coastguard Worker "Usage: ip [ OPTIONS ] OBJECT { COMMAND | help }\n"
51*de1e4e89SAndroid Build Coastguard Worker " ip [ -force ] -batch filename\n"
52*de1e4e89SAndroid Build Coastguard Worker "where OBJECT := { link | address | addrlabel | route | rule | neigh | ntable |\n"
53*de1e4e89SAndroid Build Coastguard Worker " tunnel | tuntap | maddress | mroute | mrule | monitor | xfrm |\n"
54*de1e4e89SAndroid Build Coastguard Worker " netns | l2tp | fou | macsec | tcp_metrics | token | netconf | ila |\n"
55*de1e4e89SAndroid Build Coastguard Worker " vrf | sr }\n"
56*de1e4e89SAndroid Build Coastguard Worker " OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] | -r[esolve] |\n"
57*de1e4e89SAndroid Build Coastguard Worker " -h[uman-readable] | -iec |\n"
58*de1e4e89SAndroid Build Coastguard Worker " -f[amily] { inet | inet6 | ipx | dnet | mpls | bridge | link } |\n"
59*de1e4e89SAndroid Build Coastguard Worker " -4 | -6 | -I | -D | -B | -0 |\n"
60*de1e4e89SAndroid Build Coastguard Worker " -l[oops] { maximum-addr-flush-attempts } | -br[ief] |\n"
61*de1e4e89SAndroid Build Coastguard Worker " -o[neline] | -t[imestamp] | -ts[hort] | -b[atch] [filename] |\n"
62*de1e4e89SAndroid Build Coastguard Worker " -rc[vbuf] [size] | -n[etns] name | -a[ll] | -c[olor]}\n");
63*de1e4e89SAndroid Build Coastguard Worker exit(-1);
64*de1e4e89SAndroid Build Coastguard Worker }
65*de1e4e89SAndroid Build Coastguard Worker
do_help(int argc,char ** argv)66*de1e4e89SAndroid Build Coastguard Worker static int do_help(int argc, char **argv)
67*de1e4e89SAndroid Build Coastguard Worker {
68*de1e4e89SAndroid Build Coastguard Worker usage();
69*de1e4e89SAndroid Build Coastguard Worker return 0;
70*de1e4e89SAndroid Build Coastguard Worker }
71*de1e4e89SAndroid Build Coastguard Worker
72*de1e4e89SAndroid Build Coastguard Worker static const struct cmd {
73*de1e4e89SAndroid Build Coastguard Worker const char *cmd;
74*de1e4e89SAndroid Build Coastguard Worker int (*func)(int argc, char **argv);
75*de1e4e89SAndroid Build Coastguard Worker } cmds[] = {
76*de1e4e89SAndroid Build Coastguard Worker { "address", do_ipaddr },
77*de1e4e89SAndroid Build Coastguard Worker { "addrlabel", do_ipaddrlabel },
78*de1e4e89SAndroid Build Coastguard Worker { "maddress", do_multiaddr },
79*de1e4e89SAndroid Build Coastguard Worker { "route", do_iproute },
80*de1e4e89SAndroid Build Coastguard Worker { "rule", do_iprule },
81*de1e4e89SAndroid Build Coastguard Worker { "neighbor", do_ipneigh },
82*de1e4e89SAndroid Build Coastguard Worker { "neighbour", do_ipneigh },
83*de1e4e89SAndroid Build Coastguard Worker { "ntable", do_ipntable },
84*de1e4e89SAndroid Build Coastguard Worker { "ntbl", do_ipntable },
85*de1e4e89SAndroid Build Coastguard Worker { "link", do_iplink },
86*de1e4e89SAndroid Build Coastguard Worker { "l2tp", do_ipl2tp },
87*de1e4e89SAndroid Build Coastguard Worker { "fou", do_ipfou },
88*de1e4e89SAndroid Build Coastguard Worker { "ila", do_ipila },
89*de1e4e89SAndroid Build Coastguard Worker { "macsec", do_ipmacsec },
90*de1e4e89SAndroid Build Coastguard Worker { "tunnel", do_iptunnel },
91*de1e4e89SAndroid Build Coastguard Worker { "tunl", do_iptunnel },
92*de1e4e89SAndroid Build Coastguard Worker { "tuntap", do_iptuntap },
93*de1e4e89SAndroid Build Coastguard Worker { "tap", do_iptuntap },
94*de1e4e89SAndroid Build Coastguard Worker { "token", do_iptoken },
95*de1e4e89SAndroid Build Coastguard Worker { "tcpmetrics", do_tcp_metrics },
96*de1e4e89SAndroid Build Coastguard Worker { "tcp_metrics", do_tcp_metrics },
97*de1e4e89SAndroid Build Coastguard Worker { "monitor", do_ipmonitor },
98*de1e4e89SAndroid Build Coastguard Worker { "xfrm", do_xfrm },
99*de1e4e89SAndroid Build Coastguard Worker { "mroute", do_multiroute },
100*de1e4e89SAndroid Build Coastguard Worker { "mrule", do_multirule },
101*de1e4e89SAndroid Build Coastguard Worker { "netns", do_netns },
102*de1e4e89SAndroid Build Coastguard Worker { "netconf", do_ipnetconf },
103*de1e4e89SAndroid Build Coastguard Worker { "vrf", do_ipvrf},
104*de1e4e89SAndroid Build Coastguard Worker { "sr", do_seg6 },
105*de1e4e89SAndroid Build Coastguard Worker { "help", do_help },
106*de1e4e89SAndroid Build Coastguard Worker { 0 }
107*de1e4e89SAndroid Build Coastguard Worker };
108*de1e4e89SAndroid Build Coastguard Worker
do_cmd(const char * argv0,int argc,char ** argv)109*de1e4e89SAndroid Build Coastguard Worker static int do_cmd(const char *argv0, int argc, char **argv)
110*de1e4e89SAndroid Build Coastguard Worker {
111*de1e4e89SAndroid Build Coastguard Worker const struct cmd *c;
112*de1e4e89SAndroid Build Coastguard Worker
113*de1e4e89SAndroid Build Coastguard Worker for (c = cmds; c->cmd; ++c) {
114*de1e4e89SAndroid Build Coastguard Worker if (matches(argv0, c->cmd) == 0)
115*de1e4e89SAndroid Build Coastguard Worker return -(c->func(argc-1, argv+1));
116*de1e4e89SAndroid Build Coastguard Worker }
117*de1e4e89SAndroid Build Coastguard Worker
118*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "Object \"%s\" is unknown, try \"ip help\".\n", argv0);
119*de1e4e89SAndroid Build Coastguard Worker return EXIT_FAILURE;
120*de1e4e89SAndroid Build Coastguard Worker }
121*de1e4e89SAndroid Build Coastguard Worker
batch(const char * name)122*de1e4e89SAndroid Build Coastguard Worker static int batch(const char *name)
123*de1e4e89SAndroid Build Coastguard Worker {
124*de1e4e89SAndroid Build Coastguard Worker char *line = NULL;
125*de1e4e89SAndroid Build Coastguard Worker size_t len = 0;
126*de1e4e89SAndroid Build Coastguard Worker int ret = EXIT_SUCCESS;
127*de1e4e89SAndroid Build Coastguard Worker int orig_family = preferred_family;
128*de1e4e89SAndroid Build Coastguard Worker
129*de1e4e89SAndroid Build Coastguard Worker batch_mode = 1;
130*de1e4e89SAndroid Build Coastguard Worker
131*de1e4e89SAndroid Build Coastguard Worker if (name && strcmp(name, "-") != 0) {
132*de1e4e89SAndroid Build Coastguard Worker if (freopen(name, "r", stdin) == NULL) {
133*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr,
134*de1e4e89SAndroid Build Coastguard Worker "Cannot open file \"%s\" for reading: %s\n",
135*de1e4e89SAndroid Build Coastguard Worker name, strerror(errno));
136*de1e4e89SAndroid Build Coastguard Worker return EXIT_FAILURE;
137*de1e4e89SAndroid Build Coastguard Worker }
138*de1e4e89SAndroid Build Coastguard Worker }
139*de1e4e89SAndroid Build Coastguard Worker
140*de1e4e89SAndroid Build Coastguard Worker if (rtnl_open(&rth, 0) < 0) {
141*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "Cannot open rtnetlink\n");
142*de1e4e89SAndroid Build Coastguard Worker return EXIT_FAILURE;
143*de1e4e89SAndroid Build Coastguard Worker }
144*de1e4e89SAndroid Build Coastguard Worker
145*de1e4e89SAndroid Build Coastguard Worker cmdlineno = 0;
146*de1e4e89SAndroid Build Coastguard Worker while (getcmdline(&line, &len, stdin) != -1) {
147*de1e4e89SAndroid Build Coastguard Worker char *largv[100];
148*de1e4e89SAndroid Build Coastguard Worker int largc;
149*de1e4e89SAndroid Build Coastguard Worker
150*de1e4e89SAndroid Build Coastguard Worker preferred_family = orig_family;
151*de1e4e89SAndroid Build Coastguard Worker
152*de1e4e89SAndroid Build Coastguard Worker largc = makeargs(line, largv, 100);
153*de1e4e89SAndroid Build Coastguard Worker if (largc == 0)
154*de1e4e89SAndroid Build Coastguard Worker continue; /* blank line */
155*de1e4e89SAndroid Build Coastguard Worker
156*de1e4e89SAndroid Build Coastguard Worker if (do_cmd(largv[0], largc, largv)) {
157*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "Command failed %s:%d\n",
158*de1e4e89SAndroid Build Coastguard Worker name, cmdlineno);
159*de1e4e89SAndroid Build Coastguard Worker ret = EXIT_FAILURE;
160*de1e4e89SAndroid Build Coastguard Worker if (!force)
161*de1e4e89SAndroid Build Coastguard Worker break;
162*de1e4e89SAndroid Build Coastguard Worker }
163*de1e4e89SAndroid Build Coastguard Worker }
164*de1e4e89SAndroid Build Coastguard Worker if (line)
165*de1e4e89SAndroid Build Coastguard Worker free(line);
166*de1e4e89SAndroid Build Coastguard Worker
167*de1e4e89SAndroid Build Coastguard Worker rtnl_close(&rth);
168*de1e4e89SAndroid Build Coastguard Worker return ret;
169*de1e4e89SAndroid Build Coastguard Worker }
170*de1e4e89SAndroid Build Coastguard Worker
171*de1e4e89SAndroid Build Coastguard Worker
main(int argc,char ** argv)172*de1e4e89SAndroid Build Coastguard Worker int main(int argc, char **argv)
173*de1e4e89SAndroid Build Coastguard Worker {
174*de1e4e89SAndroid Build Coastguard Worker char *basename;
175*de1e4e89SAndroid Build Coastguard Worker char *batch_file = NULL;
176*de1e4e89SAndroid Build Coastguard Worker
177*de1e4e89SAndroid Build Coastguard Worker basename = strrchr(argv[0], '/');
178*de1e4e89SAndroid Build Coastguard Worker if (basename == NULL)
179*de1e4e89SAndroid Build Coastguard Worker basename = argv[0];
180*de1e4e89SAndroid Build Coastguard Worker else
181*de1e4e89SAndroid Build Coastguard Worker basename++;
182*de1e4e89SAndroid Build Coastguard Worker
183*de1e4e89SAndroid Build Coastguard Worker while (argc > 1) {
184*de1e4e89SAndroid Build Coastguard Worker char *opt = argv[1];
185*de1e4e89SAndroid Build Coastguard Worker
186*de1e4e89SAndroid Build Coastguard Worker if (strcmp(opt, "--") == 0) {
187*de1e4e89SAndroid Build Coastguard Worker argc--; argv++;
188*de1e4e89SAndroid Build Coastguard Worker break;
189*de1e4e89SAndroid Build Coastguard Worker }
190*de1e4e89SAndroid Build Coastguard Worker if (opt[0] != '-')
191*de1e4e89SAndroid Build Coastguard Worker break;
192*de1e4e89SAndroid Build Coastguard Worker if (opt[1] == '-')
193*de1e4e89SAndroid Build Coastguard Worker opt++;
194*de1e4e89SAndroid Build Coastguard Worker if (matches(opt, "-loops") == 0) {
195*de1e4e89SAndroid Build Coastguard Worker argc--;
196*de1e4e89SAndroid Build Coastguard Worker argv++;
197*de1e4e89SAndroid Build Coastguard Worker if (argc <= 1)
198*de1e4e89SAndroid Build Coastguard Worker usage();
199*de1e4e89SAndroid Build Coastguard Worker max_flush_loops = atoi(argv[1]);
200*de1e4e89SAndroid Build Coastguard Worker } else if (matches(opt, "-family") == 0) {
201*de1e4e89SAndroid Build Coastguard Worker argc--;
202*de1e4e89SAndroid Build Coastguard Worker argv++;
203*de1e4e89SAndroid Build Coastguard Worker if (argc <= 1)
204*de1e4e89SAndroid Build Coastguard Worker usage();
205*de1e4e89SAndroid Build Coastguard Worker if (strcmp(argv[1], "help") == 0)
206*de1e4e89SAndroid Build Coastguard Worker usage();
207*de1e4e89SAndroid Build Coastguard Worker else
208*de1e4e89SAndroid Build Coastguard Worker preferred_family = read_family(argv[1]);
209*de1e4e89SAndroid Build Coastguard Worker if (preferred_family == AF_UNSPEC)
210*de1e4e89SAndroid Build Coastguard Worker invarg("invalid protocol family", argv[1]);
211*de1e4e89SAndroid Build Coastguard Worker } else if (strcmp(opt, "-4") == 0) {
212*de1e4e89SAndroid Build Coastguard Worker preferred_family = AF_INET;
213*de1e4e89SAndroid Build Coastguard Worker } else if (strcmp(opt, "-6") == 0) {
214*de1e4e89SAndroid Build Coastguard Worker preferred_family = AF_INET6;
215*de1e4e89SAndroid Build Coastguard Worker } else if (strcmp(opt, "-0") == 0) {
216*de1e4e89SAndroid Build Coastguard Worker preferred_family = AF_PACKET;
217*de1e4e89SAndroid Build Coastguard Worker } else if (strcmp(opt, "-I") == 0) {
218*de1e4e89SAndroid Build Coastguard Worker preferred_family = AF_IPX;
219*de1e4e89SAndroid Build Coastguard Worker } else if (strcmp(opt, "-D") == 0) {
220*de1e4e89SAndroid Build Coastguard Worker preferred_family = AF_DECnet;
221*de1e4e89SAndroid Build Coastguard Worker } else if (strcmp(opt, "-M") == 0) {
222*de1e4e89SAndroid Build Coastguard Worker preferred_family = AF_MPLS;
223*de1e4e89SAndroid Build Coastguard Worker } else if (strcmp(opt, "-B") == 0) {
224*de1e4e89SAndroid Build Coastguard Worker preferred_family = AF_BRIDGE;
225*de1e4e89SAndroid Build Coastguard Worker } else if (matches(opt, "-human") == 0 ||
226*de1e4e89SAndroid Build Coastguard Worker matches(opt, "-human-readable") == 0) {
227*de1e4e89SAndroid Build Coastguard Worker ++human_readable;
228*de1e4e89SAndroid Build Coastguard Worker } else if (matches(opt, "-iec") == 0) {
229*de1e4e89SAndroid Build Coastguard Worker ++use_iec;
230*de1e4e89SAndroid Build Coastguard Worker } else if (matches(opt, "-stats") == 0 ||
231*de1e4e89SAndroid Build Coastguard Worker matches(opt, "-statistics") == 0) {
232*de1e4e89SAndroid Build Coastguard Worker ++show_stats;
233*de1e4e89SAndroid Build Coastguard Worker } else if (matches(opt, "-details") == 0) {
234*de1e4e89SAndroid Build Coastguard Worker ++show_details;
235*de1e4e89SAndroid Build Coastguard Worker } else if (matches(opt, "-resolve") == 0) {
236*de1e4e89SAndroid Build Coastguard Worker ++resolve_hosts;
237*de1e4e89SAndroid Build Coastguard Worker } else if (matches(opt, "-oneline") == 0) {
238*de1e4e89SAndroid Build Coastguard Worker ++oneline;
239*de1e4e89SAndroid Build Coastguard Worker } else if (matches(opt, "-timestamp") == 0) {
240*de1e4e89SAndroid Build Coastguard Worker ++timestamp;
241*de1e4e89SAndroid Build Coastguard Worker } else if (matches(opt, "-tshort") == 0) {
242*de1e4e89SAndroid Build Coastguard Worker ++timestamp;
243*de1e4e89SAndroid Build Coastguard Worker ++timestamp_short;
244*de1e4e89SAndroid Build Coastguard Worker #if 0
245*de1e4e89SAndroid Build Coastguard Worker } else if (matches(opt, "-numeric") == 0) {
246*de1e4e89SAndroid Build Coastguard Worker rtnl_names_numeric++;
247*de1e4e89SAndroid Build Coastguard Worker #endif
248*de1e4e89SAndroid Build Coastguard Worker } else if (matches(opt, "-Version") == 0) {
249*de1e4e89SAndroid Build Coastguard Worker printf("ip utility, iproute2-ss%s\n", SNAPSHOT);
250*de1e4e89SAndroid Build Coastguard Worker exit(0);
251*de1e4e89SAndroid Build Coastguard Worker } else if (matches(opt, "-force") == 0) {
252*de1e4e89SAndroid Build Coastguard Worker ++force;
253*de1e4e89SAndroid Build Coastguard Worker } else if (matches(opt, "-batch") == 0) {
254*de1e4e89SAndroid Build Coastguard Worker argc--;
255*de1e4e89SAndroid Build Coastguard Worker argv++;
256*de1e4e89SAndroid Build Coastguard Worker if (argc <= 1)
257*de1e4e89SAndroid Build Coastguard Worker usage();
258*de1e4e89SAndroid Build Coastguard Worker batch_file = argv[1];
259*de1e4e89SAndroid Build Coastguard Worker } else if (matches(opt, "-brief") == 0) {
260*de1e4e89SAndroid Build Coastguard Worker ++brief;
261*de1e4e89SAndroid Build Coastguard Worker } else if (matches(opt, "-json") == 0) {
262*de1e4e89SAndroid Build Coastguard Worker ++json;
263*de1e4e89SAndroid Build Coastguard Worker } else if (matches(opt, "-rcvbuf") == 0) {
264*de1e4e89SAndroid Build Coastguard Worker unsigned int size;
265*de1e4e89SAndroid Build Coastguard Worker
266*de1e4e89SAndroid Build Coastguard Worker argc--;
267*de1e4e89SAndroid Build Coastguard Worker argv++;
268*de1e4e89SAndroid Build Coastguard Worker if (argc <= 1)
269*de1e4e89SAndroid Build Coastguard Worker usage();
270*de1e4e89SAndroid Build Coastguard Worker if (get_unsigned(&size, argv[1], 0)) {
271*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "Invalid rcvbuf size '%s'\n",
272*de1e4e89SAndroid Build Coastguard Worker argv[1]);
273*de1e4e89SAndroid Build Coastguard Worker exit(-1);
274*de1e4e89SAndroid Build Coastguard Worker }
275*de1e4e89SAndroid Build Coastguard Worker rcvbuf = size;
276*de1e4e89SAndroid Build Coastguard Worker } else if (matches(opt, "-color") == 0) {
277*de1e4e89SAndroid Build Coastguard Worker enable_color();
278*de1e4e89SAndroid Build Coastguard Worker } else if (matches(opt, "-help") == 0) {
279*de1e4e89SAndroid Build Coastguard Worker usage();
280*de1e4e89SAndroid Build Coastguard Worker } else if (matches(opt, "-netns") == 0) {
281*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
282*de1e4e89SAndroid Build Coastguard Worker if (netns_switch(argv[1]))
283*de1e4e89SAndroid Build Coastguard Worker exit(-1);
284*de1e4e89SAndroid Build Coastguard Worker } else if (matches(opt, "-all") == 0) {
285*de1e4e89SAndroid Build Coastguard Worker do_all = true;
286*de1e4e89SAndroid Build Coastguard Worker } else {
287*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr,
288*de1e4e89SAndroid Build Coastguard Worker "Option \"%s\" is unknown, try \"ip -help\".\n",
289*de1e4e89SAndroid Build Coastguard Worker opt);
290*de1e4e89SAndroid Build Coastguard Worker exit(-1);
291*de1e4e89SAndroid Build Coastguard Worker }
292*de1e4e89SAndroid Build Coastguard Worker argc--; argv++;
293*de1e4e89SAndroid Build Coastguard Worker }
294*de1e4e89SAndroid Build Coastguard Worker
295*de1e4e89SAndroid Build Coastguard Worker _SL_ = oneline ? "\\" : "\n";
296*de1e4e89SAndroid Build Coastguard Worker
297*de1e4e89SAndroid Build Coastguard Worker if (json)
298*de1e4e89SAndroid Build Coastguard Worker check_if_color_enabled();
299*de1e4e89SAndroid Build Coastguard Worker
300*de1e4e89SAndroid Build Coastguard Worker if (batch_file)
301*de1e4e89SAndroid Build Coastguard Worker return batch(batch_file);
302*de1e4e89SAndroid Build Coastguard Worker
303*de1e4e89SAndroid Build Coastguard Worker if (rtnl_open(&rth, 0) < 0)
304*de1e4e89SAndroid Build Coastguard Worker exit(1);
305*de1e4e89SAndroid Build Coastguard Worker
306*de1e4e89SAndroid Build Coastguard Worker if (strlen(basename) > 2)
307*de1e4e89SAndroid Build Coastguard Worker return do_cmd(basename+2, argc, argv);
308*de1e4e89SAndroid Build Coastguard Worker
309*de1e4e89SAndroid Build Coastguard Worker if (argc > 1)
310*de1e4e89SAndroid Build Coastguard Worker return do_cmd(argv[1], argc-1, argv+1);
311*de1e4e89SAndroid Build Coastguard Worker
312*de1e4e89SAndroid Build Coastguard Worker rtnl_close(&rth);
313*de1e4e89SAndroid Build Coastguard Worker usage();
314*de1e4e89SAndroid Build Coastguard Worker }
315