diff --git a/netutils/rexec/Kconfig b/netutils/rexec/Kconfig new file mode 100644 index 000000000..050145d2d --- /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 000000000..8a921362a --- /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 000000000..98d7f5e33 --- /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 000000000..6c1933862 --- /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 +#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; + 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 000000000..eabe853c1 --- /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 000000000..7ffa7a3f1 --- /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 000000000..c39d9ca65 --- /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 000000000..bcdad50a2 --- /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 +#include +#include +#include +#include +#include +#include + +/**************************************************************************** + * 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; +}