/**************************************************************************** * apps/netutils/rexec/rexec.c * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. The * ASF licenses this file to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance with the * License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. * ****************************************************************************/ /**************************************************************************** * Included Files ****************************************************************************/ #include #include #include #include #include #include #include /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ #define REXEC_BUFSIZE 512 #define REXEC_SERVER_PORT 512 /**************************************************************************** * Private Types ****************************************************************************/ struct rexec_arg_s { FAR const char *password; FAR const char *command; FAR const char *user; FAR char *host; sa_family_t af; int port; }; /**************************************************************************** * Private Function Prototypes ****************************************************************************/ static int do_rexec(FAR struct rexec_arg_s *arg); /**************************************************************************** * Private Data ****************************************************************************/ /**************************************************************************** * Private Functions ****************************************************************************/ static void usage(FAR const char *progname) { fprintf(stderr, "Usage: %s [-u user] [-H host] [-p password] " "[-P port] [-4|-6|-r] command\n", progname); fprintf(stderr, "Remote Execution Client:\n" " -u, Specify the user, default is \\0\n" " -H, Specify the hostname\n" " -p, Specify the password, default is \\0\n" " -P, Specify the port to connect to, default is 512\n" " -4, Specify address family AF_INET(default)\n" " -6, Specify address family AF_INET6\n" " -r, Specify address family AF_RPMSG\n"); exit(EXIT_FAILURE); } static int do_rexec(FAR struct rexec_arg_s *arg) { char buffer[REXEC_BUFSIZE]; struct pollfd fds[2]; int sock; int ret; sock = rexec_af(&arg->host, arg->port, arg->user, arg->password, arg->command, NULL, arg->af); if (sock < 0) { return sock; } memset(fds, 0, sizeof(fds)); fds[0].fd = sock; fds[0].events = POLLIN; fds[1].fd = STDIN_FILENO; fds[1].events = POLLIN; while (1) { ret = poll(fds, 2, -1); if (ret <= 0) { continue; } if (fds[0].revents & POLLIN) { ret = read(sock, buffer, REXEC_BUFSIZE); if (ret <= 0) { break; } ret = write(STDOUT_FILENO, buffer, ret); if (ret < 0) { break; } } if (fds[1].revents & POLLIN) { ret = read(STDIN_FILENO, buffer, REXEC_BUFSIZE); if (ret <= 0) { break; } ret = write(sock, buffer, ret); if (ret < 0) { break; } } if (((fds[0].revents | fds[1].revents) & POLLHUP) && ((fds[0].revents | fds[1].revents) & POLLIN) == 0) { break; } } free(arg->host); close(sock); return ret; } int main(int argc, FAR char **argv) { char cmd[CONFIG_NSH_LINELEN]; struct rexec_arg_s arg; int option; int i; memset(&arg, 0, sizeof(arg)); /* The default port of rexec to connect rexecd */ arg.port = REXEC_SERVER_PORT; arg.af = AF_INET; while ((option = getopt(argc, argv, "u:H:p:P:46r")) != ERROR) { switch (option) { case 'u': arg.user = optarg; break; case 'H': arg.host = optarg; break; case 'p': arg.password = optarg; break; case 'P': arg.port = atoi(optarg); break; case '4': arg.af = AF_INET; break; case '6': arg.af = AF_INET6; break; case 'r': arg.af = AF_RPMSG; break; default: usage(argv[0]); } } if (optind == argc || !arg.host) { usage(argv[0]); } cmd[0] = '\0'; for (i = optind; i < argc; i++) { strlcat(cmd, argv[i], sizeof(cmd)); strlcat(cmd, " ", sizeof(cmd)); } arg.command = cmd; return do_rexec(&arg); }