|  | // 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; | 
|  | } |