/* * Copyright (c) 1983 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */ #ifndef lint char copyright[] = "@(#) Copyright (c) 1983 Regents of the University of California.\n\ All rights reserved.\n"; #endif not lint #ifndef lint static char sccsid[] = "@(#)rsh.c 5.4 (Berkeley) 8/28/85"; #endif not lint #include #include #include #include #include #include #include #include #include #include /* * rsh - remote shell */ /* VARARGS */ int error(); char *index(), *rindex(), *malloc(), *getpass(), *sprintf(), *strcpy(); struct passwd *getpwuid(); int errno; int options; int rfd2; int sendsig(); #define mask(s) (1L << ((s) - 1)) main(argc, argv0) int argc; char **argv0; { int rem, pid; char *host, *cp, **ap, buf[BUFSIZ], *args, **argv = argv0, *user = 0; register int cc; int asrsh = 0; struct passwd *pwd; long readfrom, ready; long one = 1; struct servent *sp; long omask; host = rindex(argv[0], '/'); if (host) host++; else host = argv[0]; argv++, --argc; if (!strcmp(host, "rsh")) { host = *argv++, --argc; asrsh = 1; } another: if (argc > 0 && !strcmp(*argv, "-l")) { argv++, argc--; if (argc > 0) user = *argv++, argc--; goto another; } if (argc > 0 && !strcmp(*argv, "-n")) { argv++, argc--; (void) close(0); (void) open("/dev/null", 0); goto another; } 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 (asrsh) *argv0 = "rlogin"; execv("/usr/ucb/rlogin", argv0); perror("/usr/ucb/rlogin"); exit(1); } pwd = getpwuid(getuid()); if (pwd == 0) { fprintf(stderr, "who are you?\n"); exit(1); } cc = 0; for (ap = argv; *ap; ap++) cc += strlen(*ap) + 1; cp = args = malloc(cc); for (ap = argv; *ap; ap++) { (void) strcpy(cp, *ap); while (*cp) cp++; if (ap[1]) *cp++ = ' '; } 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()); 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); pid = fork(); if (pid < 0) { perror("fork"); exit(1); } ioctl(rfd2, FIONBIO, &one); ioctl(rem, FIONBIO, &one); if (pid == 0) { char *bp; long rembits; int wc; (void) close(rfd2); reread: errno = 0; cc = read(0, buf, sizeof buf); if (cc <= 0) goto done; bp = buf; rewrite: rembits = 1L<