/* * 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 5.7 (Berkeley) 09/20/88"; #endif /* not lint */ #include #include #include #include #include #include #include #include #include #include /* * rsh - remote shell */ /* VARARGS */ int error(); 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; { int rem, pid; char *host, *cp, **ap, buf[BUFSIZ], *args, **argv = argv0, *user = 0; register int cc; int asrsh = 0; struct passwd *pwd; int readfrom, ready; int one = 1; struct servent *sp; int 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--; nflag++; 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); if (nflag == 0) { pid = fork(); if (pid < 0) { perror("fork"); exit(1); } } ioctl(rfd2, FIONBIO, &one); ioctl(rem, FIONBIO, &one); 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; bp = buf; rewrite: rembits = 1<