1 // Copyright 2016 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "netprotocol.h"
6 
7 #include <fcntl.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <unistd.h>
12 
13 #include <errno.h>
14 #include <stdint.h>
15 
16 #include <zircon/boot/netboot.h>
17 
18 static const char* appname;
19 
usage(void)20 static void usage(void) {
21     fprintf(stderr, "usage: %s [options] <hostname> <command>\n", appname);
22     netboot_usage(false);
23 }
24 
main(int argc,char ** argv)25 int main(int argc, char** argv) {
26     appname = argv[0];
27 
28     int index = netboot_handle_getopt(argc, argv);
29     if (index < 0) {
30         usage();
31         return -1;
32     }
33     argv += index;
34     argc -= index;
35 
36     if (argc < 2) {
37         usage();
38         return -1;
39     }
40 
41     const char* hostname = argv[0];
42     if (!strcmp(hostname, "-") || !strcmp(hostname, ":")) {
43         hostname = "*";
44     }
45 
46     char cmd[MAXSIZE];
47     size_t cmd_len = 0;
48     while (argc > 1) {
49         size_t len = strlen(argv[1]);
50         if (len > (MAXSIZE - cmd_len - 1)) {
51             fprintf(stderr, "%s: command too long\n", appname);
52             return -1;
53         }
54         memcpy(cmd + cmd_len, argv[1], len);
55         cmd_len += len;
56         cmd[cmd_len++] = ' ';
57         argc--;
58         argv++;
59     }
60     cmd[cmd_len - 1] = 0;
61 
62     int s;
63     if ((s = netboot_open(hostname, NULL, NULL, true)) < 0) {
64         if (errno == ETIMEDOUT) {
65             fprintf(stderr, "%s: lookup timed out\n", appname);
66         }
67         return -1;
68     }
69 
70     msg m;
71     m.hdr.magic = NB_MAGIC;
72     m.hdr.cookie = 0x11224455;
73     m.hdr.cmd = NB_SHELL_CMD;
74     m.hdr.arg = 0;
75     memcpy(m.data, cmd, cmd_len);
76 
77     write(s, &m, sizeof(nbmsg) + cmd_len);
78     close(s);
79 
80     return 0;
81 }
82