+/*
+ * Copyright (c) 1983 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley. The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1983 The Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
#ifndef lint
-static char sccsid[] = "@(#)rsh.c 4.2 82/11/14";
-#endif
+static char sccsid[] = "@(#)rsh.c 5.7 (Berkeley) %G%";
+#endif /* not lint */
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <signal.h>
#include <pwd.h>
+#include <netdb.h>
/*
* rsh - remote shell
*/
/* VARARGS */
int error();
-char *index(), *rindex(), *malloc(), *getpass(), *sprintf(), *strcpy();
+char *index(), *rindex(), *malloc(), *getpass(), *strcpy();
struct passwd *getpwuid();
int errno;
int options;
int rfd2;
+int nflag;
int sendsig();
+#define mask(s) (1 << ((s) - 1))
+
main(argc, argv0)
int argc;
char **argv0;
struct passwd *pwd;
int readfrom, ready;
int one = 1;
+ struct servent *sp;
+ int omask;
host = rindex(argv[0], '/');
if (host)
asrsh = 1;
}
another:
- if (!strcmp(*argv, "-l")) {
+ if (argc > 0 && !strcmp(*argv, "-l")) {
argv++, argc--;
if (argc > 0)
user = *argv++, argc--;
goto another;
}
- if (!strcmp(*argv, "-n")) {
+ if (argc > 0 && !strcmp(*argv, "-n")) {
argv++, argc--;
- (void) close(0);
- (void) open("/dev/null", 0);
+ nflag++;
goto another;
}
- if (!strcmp(*argv, "-d")) {
+ if (argc > 0 && !strcmp(*argv, "-d")) {
argv++, argc--;
options |= SO_DEBUG;
goto another;
}
+ /*
+ * Ignore the -L, -w, -e and -8 flags to allow aliases with rlogin
+ * to work
+ *
+ * There must be a better way to do this! -jmb
+ */
+ if (argc > 0 && !strncmp(*argv, "-L", 2)) {
+ argv++, argc--;
+ goto another;
+ }
+ if (argc > 0 && !strncmp(*argv, "-w", 2)) {
+ argv++, argc--;
+ goto another;
+ }
+ if (argc > 0 && !strncmp(*argv, "-e", 2)) {
+ argv++, argc--;
+ goto another;
+ }
+ if (argc > 0 && !strncmp(*argv, "-8", 2)) {
+ argv++, argc--;
+ goto another;
+ }
if (host == 0)
goto usage;
if (argv[0] == 0) {
if (ap[1])
*cp++ = ' ';
}
- rem = rcmd(&host, IPPORT_CMDSERVER, pwd->pw_name,
+ sp = getservbyname("shell", "tcp");
+ if (sp == 0) {
+ fprintf(stderr, "rsh: shell/tcp: unknown service\n");
+ exit(1);
+ }
+ rem = rcmd(&host, sp->s_port, pwd->pw_name,
user ? user : pwd->pw_name, args, &rfd2);
if (rem < 0)
exit(1);
+ if (rfd2 < 0) {
+ fprintf(stderr, "rsh: can't establish stderr\n");
+ exit(2);
+ }
+ if (options & SO_DEBUG) {
+ if (setsockopt(rem, SOL_SOCKET, SO_DEBUG, &one, sizeof (one)) < 0)
+ perror("setsockopt (stdin)");
+ if (setsockopt(rfd2, SOL_SOCKET, SO_DEBUG, &one, sizeof (one)) < 0)
+ perror("setsockopt (stderr)");
+ }
(void) setuid(getuid());
- sigacts(SIG_HOLD);
- pid = fork();
- if (pid < 0) {
- perror("fork");
- exit(1);
- }
+ omask = sigblock(mask(SIGINT)|mask(SIGQUIT)|mask(SIGTERM));
+ if (signal(SIGINT, SIG_IGN) != SIG_IGN)
+ signal(SIGINT, sendsig);
+ if (signal(SIGQUIT, SIG_IGN) != SIG_IGN)
+ signal(SIGQUIT, sendsig);
+ if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
+ signal(SIGTERM, sendsig);
+ if (nflag == 0) {
+ pid = fork();
+ if (pid < 0) {
+ perror("fork");
+ exit(1);
+ }
+ }
ioctl(rfd2, FIONBIO, &one);
ioctl(rem, FIONBIO, &one);
- if (pid == 0) {
+ if (nflag == 0 && pid == 0) {
char *bp; int rembits, wc;
(void) close(rfd2);
reread:
+ errno = 0;
cc = read(0, buf, sizeof buf);
if (cc <= 0)
goto done;
goto reread;
goto rewrite;
done:
- { int flags = 1; ioctl(rem, SIOCDONE, &flags); }
+ (void) shutdown(rem, 1);
exit(0);
}
- sigacts(sendsig);
+ sigsetmask(omask);
readfrom = (1<<rfd2) | (1<<rem);
do {
ready = readfrom;
(void) write(1, buf, cc);
}
} while (readfrom);
- (void) kill(pid, SIGKILL);
+ if (nflag == 0)
+ (void) kill(pid, SIGKILL);
exit(0);
usage:
fprintf(stderr,
- "usage: rsh host [ -l login ] [ -p passwd ] command\n");
+ "usage: rsh host [ -l login ] [ -n ] command\n");
exit(1);
}
-sigacts(state)
- int (*state)();
-{
-
- sigset(SIGINT, state);
- sigset(SIGQUIT, state);
- sigset(SIGTERM, state);
-}
-
sendsig(signo)
- int signo;
+ char signo;
{
- (void) write(rfd2, (char *)&signo, 1);
+ (void) write(rfd2, &signo, 1);
}