| // Copyright 2016 The Fuchsia Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include <errno.h> | |
| #include <fcntl.h> | |
| #include <stdint.h> | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <string.h> | |
| #include <unistd.h> | |
| #include <zircon/boot/netboot.h> | |
| #include "netprotocol.h" | |
| static const char* appname; | |
| static void usage(void) { | |
| fprintf(stderr, "usage: %s [options] <hostname> <command>\n", appname); | |
| netboot_usage(false); | |
| } | |
| int main(int argc, char** argv) { | |
| appname = argv[0]; | |
| int index = netboot_handle_getopt(argc, argv); | |
| if (index < 0) { | |
| usage(); | |
| return -1; | |
| } | |
| argv += index; | |
| argc -= index; | |
| if (argc < 2) { | |
| usage(); | |
| return -1; | |
| } | |
| const char* hostname = argv[0]; | |
| if (!strcmp(hostname, "-") || !strcmp(hostname, ":")) { | |
| hostname = "*"; | |
| } | |
| char cmd[MAXSIZE]; | |
| size_t cmd_len = 0; | |
| while (argc > 1) { | |
| size_t len = strlen(argv[1]); | |
| if (len > (MAXSIZE - cmd_len - 1)) { | |
| fprintf(stderr, "%s: command too long\n", appname); | |
| return -1; | |
| } | |
| memcpy(cmd + cmd_len, argv[1], len); | |
| cmd_len += len; | |
| cmd[cmd_len++] = ' '; | |
| argc--; | |
| argv++; | |
| } | |
| cmd[cmd_len - 1] = 0; | |
| int s; | |
| if ((s = netboot_open(hostname, NULL, NULL, true)) < 0) { | |
| if (errno == ETIMEDOUT) { | |
| fprintf(stderr, "%s: lookup timed out\n", appname); | |
| } | |
| return -1; | |
| } | |
| msg m; | |
| m.hdr.magic = NB_MAGIC; | |
| m.hdr.cookie = 0x11224455; | |
| m.hdr.cmd = NB_SHELL_CMD; | |
| m.hdr.arg = 0; | |
| memcpy(m.data, cmd, cmd_len); | |
| write(s, &m, sizeof(nbmsg) + cmd_len); | |
| close(s); | |
| return 0; | |
| } |