This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GNU Inetutils ".
http://git.savannah.gnu.org/cgit/inetutils.git/commit/?id=21e83ddbb7f518d80618f5af212137cb60fcaed2 The branch, master has been updated via 21e83ddbb7f518d80618f5af212137cb60fcaed2 (commit) from 09cc6ce9657c85f9843c1c30279ec03ffbc6faf3 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 21e83ddbb7f518d80618f5af212137cb60fcaed2 Author: Giuseppe Scrivano <[email protected]> Date: Tue Jul 28 17:43:45 2009 +0200 rexec: new program ----------------------------------------------------------------------- Summary of changes: ChangeLog | 10 ++ Makefile.am | 2 +- configure.ac | 2 + doc/inetutils.texi | 38 +++++ {rexecd => rexec}/Makefile.am | 12 +- rexec/rexec.c | 323 +++++++++++++++++++++++++++++++++++++++++ 6 files changed, 380 insertions(+), 7 deletions(-) copy {rexecd => rexec}/Makefile.am (78%) create mode 100644 rexec/rexec.c diff --git a/ChangeLog b/ChangeLog index 0a01371..107bdd5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2009-08-20 Giuseppe Scrivano <[email protected]> + + rexec: new program. + + * configure.ac: Build rexec. + * Makefile.am: Ditto. + * doc/inetutils.texi: Document the new program. + * rexec/Makefile.am: New file. + * rexec/rexec.c: New file. + 2009-08-18 Sergey Poznyakoff <[email protected]> Fix possible array overflow in ping. diff --git a/Makefile.am b/Makefile.am index 061af2b..7d2d1b8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -25,7 +25,7 @@ EXTRA_DIST = README-alpha paths ChangeLog.0 SUBDIRS = lib headers libinetutils libtelnet \ hostname inetd telnetd libls ftpd rshd rlogind uucpd rexecd syslogd \ tftpd talkd telnet ftp rsh rcp rlogin tftp logger gwhois talk \ - libicmp ping doc ifconfig traceroute tests + libicmp ping doc ifconfig traceroute rexec tests DISTCLEANFILES = pathdefs.make paths.defs diff --git a/configure.ac b/configure.ac index fdff8d3..0b8ebb5 100644 --- a/configure.ac +++ b/configure.ac @@ -108,6 +108,7 @@ IU_ENABLE_CLIENT(hostname) IU_ENABLE_CLIENT(ping) IU_ENABLE_CLIENT(ping6) IU_ENABLE_CLIENT(rcp) +IU_ENABLE_CLIENT(rexec) IU_ENABLE_CLIENT(rlogin) IU_ENABLE_CLIENT(rsh) IU_ENABLE_CLIENT(logger) @@ -820,6 +821,7 @@ ftpd/Makefile hostname/Makefile inetd/Makefile rcp/Makefile +rexec/Makefile rexecd/Makefile rlogin/Makefile rlogind/Makefile diff --git a/doc/inetutils.texi b/doc/inetutils.texi index 86360fd..ec011ee 100644 --- a/doc/inetutils.texi +++ b/doc/inetutils.texi @@ -34,6 +34,7 @@ * logger: (inetutils)logger invocation. Send messages to the system log. * ping: (inetutils)ping invocation. Packets to network hosts. * rcp: (inetutils)rcp invocation. Remote copy +* rexec: (inetutils)rexec invocation. Remote execution client. * rexecd: (inetutils)rexecd invocation. Remote execution server. * rlogin: (inetutils)rlogin invocation. Remote login. * rlogind: (inetutils)rlogind invocation. Remote login server. @@ -107,6 +108,7 @@ Clients * tftp invocation:: TFTP client. * rsh invocation:: Remote shell. * rlogin invocation:: Remote login. +* rexec invocation:: Remote execution client. * rcp invocation:: Remote copy * talk invocation:: Talk client. * telnet invocation:: User interface to TELNET. @@ -1751,6 +1753,42 @@ The destination user and hostname may have to be specified as @samp{rhost.rname} when the destination machine is running the 4.2BSD version of @command{rcp}. +...@node rexec invocation +...@chapter @command{rexec}: a remote execution program +...@cindex rexec + +...@command{rexec} is a program that executes a program on another host. + +...@example +rexec --us...@var{login} --passwo...@var{pass} --ho...@var{host} \ + [OPTION] @var{command} +...@end example + +The command line arguments are as follows: + +...@table @var +...@item --error +Specify the TCP port to use for stderr redirection, in case it is not +specified a random port will be used. + +...@item --host +Specify the host where connect to. + +...@item --noerr +If specified, an error stream will not be created. + +...@item --password +Specify the password for logging-in. + +...@item --port +Specify to which port connect to, if it is not specified by default +use 512. + +...@item --user +Specify the user to log into the server. +...@end table + + @node talk invocation @chapter @command{talk}: a communication program @cindex talk diff --git a/rexecd/Makefile.am b/rexec/Makefile.am similarity index 78% copy from rexecd/Makefile.am copy to rexec/Makefile.am index 6c0d033..74d9d74 100644 --- a/rexecd/Makefile.am +++ b/rexec/Makefile.am @@ -1,4 +1,4 @@ -# Copyright (C) 2005, 2007 Free Software Foundation, Inc. +# Copyright (C) 2005, 2007, 2009 Free Software Foundation, Inc. # This file is part of GNU Inetutils. # # GNU Inetutils is free software; you can redistribute it and/or modify @@ -16,18 +16,18 @@ # to the Free Software Foundation, Inc., 51 Franklin Street, # Fifth Floor, Boston, MA 02110-1301 USA. -inetdaemondir = @inetdaemondir@ +bin_PROGRAMS = @rexec_BUILD@ -inetdaemon_PROGRAMS = @rexecd_BUILD@ +EXTRA_PROGRAMS = rexec -EXTRA_PROGRAMS = rexecd +rexec_SOURCES = rexec.c -rexecd_SOURCES = rexecd.c +noinst_HEADERS = @PATHDEFS_MAKE@ +INCLUDES = -I$(top_srcdir)/lib -I../lib -I$(top_srcdir)/libinetutils AM_CPPFLAGS = $(PATHDEF_DEFPATH) $(PATHDEF_BSHELL) -INCLUDES=-I$(top_srcdir)/lib -I../lib -I$(top_srcdir)/libinetutils LIBCRYPT = @LIBCRYPT@ diff --git a/rexec/rexec.c b/rexec/rexec.c new file mode 100644 index 0000000..9578ee8 --- /dev/null +++ b/rexec/rexec.c @@ -0,0 +1,323 @@ +/* + Copyright (C) 2009 Free Software Foundation, Inc. + + This file is part of GNU Inetutils. + + GNU Inetutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + GNU Inetutils is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +/* Written by Giuseppe Scrivano <[email protected]>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/ioctl.h> +#ifdef HAVE_SYS_FILIO_H +# include <sys/filio.h> +#endif +#include <sys/socket.h> + +#include <netinet/in.h> + +#include <errno.h> +#include <netdb.h> +#include <pwd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#ifdef HAVE_SYS_SELECT_H +# include <sys/select.h> +#endif + +#include <stdarg.h> +#include <progname.h> +#include <argp.h> +#include <error.h> +#include "libinetutils.h" + +#define MAX3(a, b, c) (MAX (MAX (a, b), c)) + +const char doc[] = "remote execution client"; +static char args_doc[] = "COMMAND"; + +const char *program_authors[] = + { + "Giuseppe Scrivano", + NULL + }; + +static struct argp_option options[] = { + {"user", 'u', "user", 0, "Specify the user"}, + {"host", 'h', "host", 0, "Specify the host"}, + {"password", 'p', "password", 0, "Specify the password"}, + {"port", 'P', "port", 0, "Specify the port to connect to"}, + {"noerr", 'n', NULL, 0, "Disable the stderr stream"}, + {"error", 'e', "error", 0, "Specify a TCP port to use for stderr"}, + { 0 } +}; + +struct arguments +{ + const char *host; + const char *user; + const char *password; + const char *command; + int port; + int use_err; + int err_port; +}; + +static error_t +parse_opt (int key, char *arg, struct argp_state *state) +{ + struct arguments *arguments = state->input; + + switch (key) + { + case 'u': + arguments->user = arg; + break; + case 'p': + arguments->password = arg; + break; + case 'P': + arguments->port = atoi (arg); + break; + case 'e': + arguments->err_port = atoi (arg); + break; + case 'h': + arguments->host = arg; + break; + case 'n': + arguments->use_err = 0; + break; + case ARGP_KEY_ARG: + arguments->command = arg; + state->next = state->argc; + } + + return 0; +} + +static struct argp argp = {options, parse_opt, args_doc, doc}; + +static void do_rexec (struct arguments *arguments); + +int +main (int argc, char **argv) +{ + struct arguments arguments; + + set_program_name (argv[0]); + + iu_argp_init ("rexec", program_authors); + + arguments.user = NULL; + arguments.password = NULL; + arguments.host = NULL; + arguments.command = NULL; + arguments.err_port = 0; + arguments.use_err = 1; + arguments.port = 512; + + argp_parse (&argp, argc, argv, ARGP_IN_ORDER, 0, &arguments); + + if (arguments.user == NULL) + error (EXIT_FAILURE, 0, "user not specified"); + + if (arguments.password == NULL) + error (EXIT_FAILURE, 0, "password not specified"); + + if (arguments.host == NULL) + error (EXIT_FAILURE, 0, "host not specified"); + + if (arguments.command == NULL) + error (EXIT_FAILURE, 0, "command not specified"); + + do_rexec (&arguments); + + exit (0); +} + +static void +safe_write (int socket, const char *str, size_t len) +{ + if (write (socket, str, len) < 0) + error (EXIT_FAILURE, errno, "error sending data"); +} + +void +do_rexec (struct arguments *arguments) +{ + int err; + char buffer[1024]; + int sock; + char port_str[6]; + struct sockaddr_in addr; + struct hostent *host; + int stdin = STDIN_FILENO; + int err_sock = -1; + + sock = socket (AF_INET, SOCK_STREAM, 0); + if (sock < 0) + error (EXIT_FAILURE, errno, "cannot open socket"); + + host = gethostbyname (arguments->host); + if (host == NULL) + error (EXIT_FAILURE, errno, "cannot find host %s", arguments->host); + + memset (&addr, 0, sizeof (addr)); + addr.sin_family = AF_INET; + memmove ((caddr_t) &addr.sin_addr, +#ifdef HAVE_STRUCT_HOSTENT_H_ADDR_LIST + host->h_addr_list[0], +#else + host->h_addr, +#endif + host->h_length); + + addr.sin_port = htons ((short)arguments->port); + + if (connect (sock, &addr, sizeof (addr)) < 0) + error (EXIT_FAILURE, errno, "cannot connect to the specified host"); + + if (!arguments->use_err) + { + port_str[0] = '0'; + port_str[1] = '\0'; + safe_write (sock, port_str, 2); + arguments->err_port = 0; + } + else + { + struct sockaddr_in serv_addr; + socklen_t len; + int serv_sock = socket (AF_INET, SOCK_STREAM, 0); + + if (serv_sock < 0) + error (EXIT_FAILURE, errno, "cannot open socket"); + + memset (&serv_addr, 0, sizeof (serv_addr)); + + serv_addr.sin_port = arguments->err_port; + if (bind (serv_sock, &serv_addr, sizeof (serv_addr)) < 0) + error (EXIT_FAILURE, errno, "cannot bind socket"); + + len = sizeof (serv_addr); + if (getsockname (serv_sock, &serv_addr, &len)) + error (EXIT_FAILURE, errno, "error reading socket port"); + + if (listen (serv_sock, 1)) + error (EXIT_FAILURE, errno, "error listening on socket"); + + arguments->err_port = ntohs (serv_addr.sin_port); + sprintf (port_str, "%i", arguments->err_port); + safe_write (sock, port_str, strlen (port_str) + 1); + + err_sock = accept (serv_sock, &serv_addr, &len); + if (err_sock < 0) + error (EXIT_FAILURE, errno, "error accepting connection"); + + shutdown (err_sock, SHUT_WR); + + close (serv_sock); + } + + safe_write (sock, arguments->user, strlen (arguments->user) + 1); + safe_write (sock, arguments->password, strlen (arguments->password) + 1); + safe_write (sock, arguments->command, strlen (arguments->command) + 1); + + while (1) + { + int ret; + fd_set rsocks; + + /* No other data to read. */ + if (sock < 0 && err_sock < 0) + break; + + FD_ZERO (&rsocks); + if (0 <= sock) + FD_SET (sock, &rsocks); + if (0 <= stdin) + FD_SET (stdin, &rsocks); + if (0 <= err_sock) + FD_SET (err_sock, &rsocks); + + ret = select (MAX3 (sock, stdin, err_sock) + 1, &rsocks, NULL, NULL, NULL); + if (ret == -1) + error (EXIT_FAILURE, errno, "error select"); + + if (0 <= stdin && FD_ISSET (stdin, &rsocks)) + { + err = read (stdin, buffer, 1024); + + if (err < 0) + error (EXIT_FAILURE, errno, "error reading stdin"); + + if (!err) + { + shutdown (sock, SHUT_WR); + close (stdin); + stdin = -1; + continue; + } + + if (write (STDOUT_FILENO, buffer, err) < 0) + error (EXIT_FAILURE, errno, "error writing"); + } + + if (0 <= sock && FD_ISSET (sock, &rsocks)) + { + err = read (sock, buffer, 1024); + + if (err < 0) + error (EXIT_FAILURE, errno, "error reading out stream"); + + if (!err) + { + close (sock); + sock = -1; + continue; + } + + if (write (STDOUT_FILENO, buffer, err) < 0) + error (EXIT_FAILURE, errno, "error writing"); + } + + if (0 <= err_sock && FD_ISSET (err_sock, &rsocks)) + { + err = read (err_sock, buffer, 1024); + + if (err < 0) + error (EXIT_FAILURE, errno, "error reading err stream"); + + if (!err) + { + close (err_sock); + err_sock = -1; + continue; + } + + if (write (STDERR_FILENO, buffer, err) < 0) + error (EXIT_FAILURE, errno, "error writing to stderr"); + } + } +} hooks/post-receive -- GNU Inetutils _______________________________________________ Commit-inetutils mailing list [email protected] http://lists.gnu.org/mailman/listinfo/commit-inetutils
