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/13 01:00:26 UTC

[incubator-nuttx-apps] 01/02: netutils: support rexec and rexecd

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-apps.git

commit 00e7be92dc3c230e81abef6c98cd7cb7bee3234e
Author: Jiuzhu Dong <do...@xiaomi.com>
AuthorDate: Tue Aug 31 22:50:41 2021 +0800

    netutils: support rexec and rexecd
    
    Signed-off-by: Jiuzhu Dong <do...@xiaomi.com>
---
 netutils/rexec/Kconfig    |  22 +++++
 netutils/rexec/Make.defs  |  22 +++++
 netutils/rexec/Makefile   |  34 +++++++
 netutils/rexec/rexec.c    | 160 ++++++++++++++++++++++++++++++
 netutils/rexecd/Kconfig   |  22 +++++
 netutils/rexecd/Make.defs |  22 +++++
 netutils/rexecd/Makefile  |  34 +++++++
 netutils/rexecd/rexecd.c  | 242 ++++++++++++++++++++++++++++++++++++++++++++++
 8 files changed, 558 insertions(+)

diff --git a/netutils/rexec/Kconfig b/netutils/rexec/Kconfig
new file mode 100644
index 0000000..050145d
--- /dev/null
+++ b/netutils/rexec/Kconfig
@@ -0,0 +1,22 @@
+#
+# For a description of the syntax of this configuration file,
+# see the file kconfig-language.txt in the NuttX tools repository.
+#
+
+config NETUTILS_REXEC
+	tristate "Remote execution client"
+	default n
+	---help---
+		Enable support for the remote execution client.
+
+if NETUTILS_REXEC
+
+config NETUTILS_REXEC_PRIORITY
+	int "Remote execution client task priority"
+	default 100
+
+config NETUTILS_REXEC_STACKSIZE
+	int "Remote execution client stack size"
+	default DEFAULT_TASK_STACKSIZE
+
+endif
diff --git a/netutils/rexec/Make.defs b/netutils/rexec/Make.defs
new file mode 100644
index 0000000..8a92136
--- /dev/null
+++ b/netutils/rexec/Make.defs
@@ -0,0 +1,22 @@
+# apps/netutils/rexec/Make.defs
+#
+# 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.
+#
+############################################################################
+
+ifneq ($(CONFIG_NETUTILS_REXEC),)
+CONFIGURED_APPS += $(APPDIR)/netutils/rexec
+endif
diff --git a/netutils/rexec/Makefile b/netutils/rexec/Makefile
new file mode 100644
index 0000000..98d7f5e
--- /dev/null
+++ b/netutils/rexec/Makefile
@@ -0,0 +1,34 @@
+############################################################################
+# apps/netutils/rexec/Makefile
+#
+# 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.
+#
+############################################################################
+
+include $(APPDIR)/Make.defs
+
+# rexec example! built-in application info
+
+PROGNAME  = rexec
+PRIORITY  = $(CONFIG_NETUTILS_REXEC_PRIORITY)
+STACKSIZE = $(CONFIG_NETUTILS_REXEC_STACKSIZE)
+MODULE    = $(CONFIG_NETUTILS_REXEC)
+
+# rexec Example
+
+MAINSRC = rexec.c
+
+include $(APPDIR)/Application.mk
diff --git a/netutils/rexec/rexec.c b/netutils/rexec/rexec.c
new file mode 100644
index 0000000..6c19338
--- /dev/null
+++ b/netutils/rexec/rexec.c
@@ -0,0 +1,160 @@
+/****************************************************************************
+ * 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 <getopt.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+/****************************************************************************
+ * 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;
+  int port;
+  int af;
+};
+
+/****************************************************************************
+ * 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] 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");
+  exit(EXIT_FAILURE);
+}
+
+static int do_rexec(FAR struct rexec_arg_s *arg)
+{
+  char buffer[REXEC_BUFSIZE];
+  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;
+    }
+
+  while (1)
+    {
+      ret = read(sock, buffer, REXEC_BUFSIZE);
+      if (ret <= 0)
+        {
+          break;
+        }
+
+      ret = write(STDOUT_FILENO, buffer, ret);
+      if (ret < 0)
+        {
+          break;
+        }
+    }
+
+  free(arg->host);
+  close(sock);
+  return ret;
+}
+
+int main(int argc, FAR char **argv)
+{
+  struct rexec_arg_s arg;
+  int option;
+
+  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:46")) != 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;
+          default:
+            usage(argv[0]);
+        }
+    }
+
+  if (optind == argc || !arg.host)
+    {
+      usage(argv[0]);
+    }
+
+  arg.command = argv[optind];
+  return do_rexec(&arg);
+}
diff --git a/netutils/rexecd/Kconfig b/netutils/rexecd/Kconfig
new file mode 100644
index 0000000..eabe853
--- /dev/null
+++ b/netutils/rexecd/Kconfig
@@ -0,0 +1,22 @@
+#
+# For a description of the syntax of this configuration file,
+# see the file kconfig-language.txt in the NuttX tools repository.
+#
+
+config NETUTILS_REXECD
+	tristate "Remote Execution Server"
+	default n
+	---help---
+		Enable support for the Remote Execution server.
+
+if NETUTILS_REXECD
+
+config NETUTILS_REXECD_PRIORITY
+	int "Remote execution server task priority"
+	default 100
+
+config NETUTILS_REXECD_STACKSIZE
+	int "Remote execution server task stack size"
+	default DEFAULT_TASK_STACKSIZE
+
+endif
diff --git a/netutils/rexecd/Make.defs b/netutils/rexecd/Make.defs
new file mode 100644
index 0000000..7ffa7a3
--- /dev/null
+++ b/netutils/rexecd/Make.defs
@@ -0,0 +1,22 @@
+# apps/netutils/rexecd/Make.defs
+#
+# 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.
+#
+############################################################################
+
+ifneq ($(CONFIG_NETUTILS_REXECD),)
+CONFIGURED_APPS += $(APPDIR)/netutils/rexecd
+endif
diff --git a/netutils/rexecd/Makefile b/netutils/rexecd/Makefile
new file mode 100644
index 0000000..c39d9ca
--- /dev/null
+++ b/netutils/rexecd/Makefile
@@ -0,0 +1,34 @@
+############################################################################
+# apps/netutils/rexecd/Makefile
+#
+# 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.
+#
+############################################################################
+
+include $(APPDIR)/Make.defs
+
+# rexecd example! built-in application info
+
+PROGNAME  = rexecd
+PRIORITY  = $(CONFIG_NETUTILS_REXECD_PRIORITY)
+STACKSIZE = $(CONFIG_NETUTILS_REXECD_STACKSIZE)
+MODULE    = $(CONFIG_NETUTILS_REXECD)
+
+# rexec Example
+
+MAINSRC = rexecd.c
+
+include $(APPDIR)/Application.mk
diff --git a/netutils/rexecd/rexecd.c b/netutils/rexecd/rexecd.c
new file mode 100644
index 0000000..bcdad50
--- /dev/null
+++ b/netutils/rexecd/rexecd.c
@@ -0,0 +1,242 @@
+/****************************************************************************
+ * apps/netutils/rexecd/rexecd.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 <errno.h>
+#include <netdb.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <poll.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define REXECD_PORT    512
+#define REXECD_BUFSIZE 512
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static FAR void *doit(pthread_addr_t pvarg);
+static int getstr(int fd, FAR char *buf);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int getstr(int fd, FAR char *buf)
+{
+  FAR char *end = buf;
+  int ret;
+
+  do
+    {
+      ret = read(fd, end, 1);
+      if (ret <= 0)
+        {
+          return ret;
+        }
+
+      end += ret;
+    }
+  while (*(end - 1));
+
+  return ret;
+}
+
+static FAR void *doit(pthread_addr_t pvarg)
+{
+  char buf[REXECD_BUFSIZE];
+  FAR FILE *fp;
+  int sock = (int)pvarg;
+  int ret;
+  int len;
+
+  /* we need to read err_sock, user and passwd, but ignore them */
+
+  getstr(sock, buf);
+  getstr(sock, buf);
+  getstr(sock, buf);
+
+  /* we need to read command */
+
+  getstr(sock, buf);
+  fp = popen(buf, "r");
+  if (!fp)
+    {
+      goto errout;
+    }
+
+  while (1)
+    {
+      ret = fread(buf, 1, REXECD_BUFSIZE, fp);
+      if (ret <= 0)
+        {
+          break;
+        }
+
+      do
+        {
+          len = write(sock, buf, ret);
+          if (len <= 0)
+            {
+              break;
+            }
+
+          ret -= len;
+        }
+      while (ret > 0);
+    }
+
+  pclose(fp);
+errout:
+  close(sock);
+  return NULL;
+}
+
+static void usage(FAR const char *progname)
+{
+  fprintf(stderr, "Usage: %s [-4|-6]\n", progname);
+  fprintf(stderr, "Remote Execution Deamon:\n"
+                  " -4, Specify address family to AF_INET(default)\n"
+                  " -6, Specify address family to AF_INET6\n");
+  exit(EXIT_FAILURE);
+}
+
+int main(int argc, FAR char **argv)
+{
+  struct sockaddr_storage addr;
+  pthread_attr_t attr;
+  pthread_t tid;
+  int family;
+  int option;
+  int serv;
+  int sock;
+  int ret;
+
+  family = AF_INET;
+  while ((option = getopt(argc, argv, "46")) != ERROR)
+    {
+      switch (option)
+        {
+          case '4':
+            family = AF_INET;
+            break;
+          case '6':
+            family = AF_INET6;
+            break;
+          default:
+            usage(argv[0]);
+        }
+    }
+
+  serv = socket(family, SOCK_STREAM, 0);
+  if (serv < 0)
+    {
+      return serv;
+    }
+
+  switch (family)
+    {
+      case AF_INET:
+        ((FAR struct sockaddr_in *)&addr)->sin_family = AF_INET;
+        ((FAR struct sockaddr_in *)&addr)->sin_port = REXECD_PORT;
+        ret = sizeof(struct sockaddr_in);
+        break;
+      case AF_INET6:
+        ((FAR struct sockaddr_in6 *)&addr)->sin6_family = AF_INET6;
+        ((FAR struct sockaddr_in6 *)&addr)->sin6_port = REXECD_PORT;
+        ret = sizeof(struct sockaddr_in6);
+    }
+
+  ret = bind(serv, (FAR struct sockaddr *)&addr, ret);
+  if (ret < 0)
+    {
+      goto err_out;
+    }
+
+  ret = listen(serv, 5);
+  if (ret < 0)
+    {
+      goto err_out;
+    }
+
+  ret = pthread_attr_init(&attr);
+  if (ret != 0)
+    {
+      goto err_out;
+    }
+
+  ret = pthread_attr_setstacksize(&attr, CONFIG_NETUTILS_REXECD_STACKSIZE);
+  if (ret != 0)
+    {
+      goto attr_out;
+    }
+
+  ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+  if (ret != 0)
+    {
+      goto attr_out;
+    }
+
+  while (1)
+    {
+      sock = accept(serv, NULL, 0);
+      if (sock < 0)
+        {
+          if (errno == EINTR)
+            {
+              continue;
+            }
+          else
+            {
+              ret = sock;
+              goto attr_out;
+            }
+        }
+
+      ret = pthread_create(&tid, &attr, doit, (pthread_addr_t)sock);
+      if (ret < 0)
+        {
+          close(sock);
+        }
+    }
+
+attr_out:
+  pthread_attr_destroy(&attr);
+err_out:
+  close(serv);
+  return ret;
+}