You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2021/09/12 13:14:12 UTC
[incubator-nuttx] branch master updated: libc/rexec/rexec_af:
support remote execution
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new 2438403 libc/rexec/rexec_af: support remote execution
2438403 is described below
commit 2438403f23f685728e2aa83be7c51f01f022e22e
Author: Jiuzhu Dong <do...@xiaomi.com>
AuthorDate: Tue Aug 17 17:33:45 2021 +0800
libc/rexec/rexec_af: support remote execution
Signed-off-by: Jiuzhu Dong <do...@xiaomi.com>
---
include/netdb.h | 6 ++
libs/libc/netdb/Make.defs | 2 +-
libs/libc/netdb/lib_rexec.c | 212 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 219 insertions(+), 1 deletion(-)
diff --git a/include/netdb.h b/include/netdb.h
index 5c953ca..7cb5b3a 100644
--- a/include/netdb.h
+++ b/include/netdb.h
@@ -277,6 +277,12 @@ EXTERN int h_errno;
* Public Function Prototypes
****************************************************************************/
+int rexec(FAR char **ahost, int inport, FAR const char *user,
+ FAR const char *passwd, FAR const char *cmd, FAR int *fd2p);
+int rexec_af(FAR char **ahost, int inport, FAR const char *user,
+ FAR const char *passwd, FAR const char *cmd, FAR int *fd2p,
+ sa_family_t af);
+
#ifdef CONFIG_LIBC_NETDB
#if 0 /* None of these are yet supported */
diff --git a/libs/libc/netdb/Make.defs b/libs/libc/netdb/Make.defs
index d85cd6c..dfabc3f 100644
--- a/libs/libc/netdb/Make.defs
+++ b/libs/libc/netdb/Make.defs
@@ -29,7 +29,7 @@ CSRCS += lib_gethostbyaddr.c lib_gethostbyaddrr.c
CSRCS += lib_getservbyname.c lib_getservbynamer.c
CSRCS += lib_getservbyport.c lib_getservbyportr.c
CSRCS += lib_gaistrerror.c lib_freeaddrinfo.c lib_getaddrinfo.c
-CSRCS += lib_getnameinfo.c
+CSRCS += lib_getnameinfo.c lib_rexec.c
# Add host file support
diff --git a/libs/libc/netdb/lib_rexec.c b/libs/libc/netdb/lib_rexec.c
new file mode 100644
index 0000000..960f8e6
--- /dev/null
+++ b/libs/libc/netdb/lib_rexec.c
@@ -0,0 +1,212 @@
+/****************************************************************************
+ * libs/libc/netdb/lib_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 <netinet/in.h>
+
+#include <errno.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: rexec_af
+ *
+ * Description:
+ * The rexec() function works over IPv4 (AF_INET). By contrast,
+ * the rexec_af() function provides an extra argument, af, that allows
+ * the caller to select the protocol. This argument can be specified
+ * as AF_INET, AF_INET6, or AF_UNSPEC (to allow the implementation to
+ * select the protocol).
+ *
+ * Input Parameters:
+ *
+ * Returned Value:
+ * OK on success; -1 on failure with the errno variable set appropriately.
+ *
+ ****************************************************************************/
+
+int rexec_af(FAR char **ahost, int inport, FAR const char *user,
+ FAR const char *passwd, FAR const char *cmd,
+ FAR int *fd2p, sa_family_t af)
+{
+ FAR struct addrinfo *res;
+ struct addrinfo hints;
+ char port_str[12];
+ int sock;
+ int ret;
+
+ if (!cmd || !ahost)
+ {
+ set_errno(EINVAL);
+ return -1;
+ }
+
+ snprintf(port_str, sizeof(port_str), "%d", ntohs(inport));
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = af;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = AI_CANONNAME;
+
+ ret = getaddrinfo(*ahost, port_str, &hints, &res);
+ if (ret < 0)
+ {
+ return -1;
+ }
+
+ if (res->ai_canonname)
+ {
+ *ahost = strdup(res->ai_canonname);
+ if (*ahost == NULL)
+ {
+ set_errno(ENOMEM);
+ goto addr_out;
+ }
+ }
+ else
+ {
+ *ahost = NULL;
+ set_errno(ENOENT);
+ goto addr_out;
+ }
+
+ sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+ if (sock < 0)
+ {
+ goto sock_out;
+ }
+
+ if (connect(sock, res->ai_addr, res->ai_addrlen) < 0)
+ {
+ goto conn_out;
+ }
+
+ /* ignore second connection(fd2p always is NULL) */
+
+ write(sock, "", 1);
+
+ /* Send username */
+
+ if (user)
+ {
+ ret = write(sock, user, strlen(user) + 1);
+ }
+ else
+ {
+ ret = write(sock, "", 1);
+ }
+
+ if (ret < 0)
+ {
+ goto conn_out;
+ }
+
+ /* Send passwd */
+
+ if (passwd)
+ {
+ ret = write(sock, passwd, strlen(passwd) + 1);
+ }
+ else
+ {
+ ret = write(sock, "", 1);
+ }
+
+ if (ret < 0)
+ {
+ goto conn_out;
+ }
+
+ /* Send command */
+
+ ret = write(sock, cmd, strlen(cmd) + 1);
+ if (ret < 0)
+ {
+ goto conn_out;
+ }
+
+ freeaddrinfo(res);
+ return sock;
+
+conn_out:
+ close(sock);
+sock_out:
+ free(ahost);
+addr_out:
+ freeaddrinfo(res);
+ return -1;
+}
+
+/****************************************************************************
+ * Name: rexec
+ *
+ * Description:
+ * The rexec() function looks up the host *ahost using gethostbyname(),
+ * returning -1 if the host does not exist. Otherwise, *ahost is set to
+ * standard name of the host. If a username and password are both
+ * specified, then these are used to authenticate to the foreign host;
+ * otherwise the environment and then the .netrc file in user's home
+ * direcotry are searched for appropiate information. If all the fails,
+ * the user is prompted for the information.
+ *
+ * The port inport specifies which well-known DARPA Internet port to
+ * use for the connection; the call getservbyname("exec", "tcp") will
+ * return a pointer to a structure that contains the necessary port.
+ * The protocol for connection is described in detail in rexecd(8).
+ *
+ * If the connection succeeds, a socket in the Internet domain of type
+ * SOCK_STREAM is returned to the caller, and given to the remote
+ * command as stdin and stdout. If fd2p is nonzero, then an auxiliary
+ * channel to a control process will be setup, and a file descriptor for
+ * it will be placed in *fd2p. The control process will return diagnostic
+ * output from the command on this channel, and will also
+ * accept bytes on this channel as being UNIX signal numbers, to be
+ * forwarded to the process group of the command. The diagnostic
+ * information returned does not include remote authorization failure,
+ * as the secondary connection is set up after authorization has been
+ * verified. If fd2p is 0, then the stderr (unit2 of the remote command)
+ * will be made the same as the stdout and no provision is made for
+ * sending arbitrary signals to the remote process, although you may
+ * be able to get its attention by using out-of-band data.
+ *
+ * The rexec() function works over IPv4 (AF_INET).
+ *
+ * Input Parameters:
+ *
+ * Returned Value:
+ * OK on success; -1 on failure with the errno variable set appropriately.
+ *
+ ****************************************************************************/
+
+int rexec(FAR char **ahost, int inport, FAR const char *user,
+ FAR const char *passwd, FAR const char *cmd, FAR int *fd2p)
+{
+ return rexec_af(ahost, inport, user, passwd, cmd, fd2p, AF_INET);
+}