1: /*
   2:  * Copyright (c) 1983 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  */
   6: 
   7: #ifndef lint
   8: char copyright[] =
   9: "@(#) Copyright (c) 1983 Regents of the University of California.\n\
  10:  All rights reserved.\n";
  11: #endif not lint
  12: 
  13: #ifndef lint
  14: static char sccsid[] = "@(#)rsh.c	5.4 (Berkeley) 8/28/85";
  15: #endif not lint
  16: 
  17: #include <sys/types.h>
  18: #include <sys/socket.h>
  19: #include <sys/ioctl.h>
  20: #include <sys/file.h>
  21: 
  22: #include <netinet/in.h>
  23: 
  24: #include <stdio.h>
  25: #include <errno.h>
  26: #include <signal.h>
  27: #include <pwd.h>
  28: #include <netdb.h>
  29: 
  30: /*
  31:  * rsh - remote shell
  32:  */
  33: /* VARARGS */
  34: int error();
  35: char    *index(), *rindex(), *malloc(), *getpass(), *sprintf(), *strcpy();
  36: 
  37: struct  passwd *getpwuid();
  38: 
  39: int errno;
  40: int options;
  41: int rfd2;
  42: int sendsig();
  43: 
  44: #define mask(s) (1 << ((s) - 1))
  45: 
  46: main(argc, argv0)
  47:     int argc;
  48:     char **argv0;
  49: {
  50:     int rem, pid;
  51:     char *host, *cp, **ap, buf[BUFSIZ], *args, **argv = argv0, *user = 0;
  52:     register int cc;
  53:     int asrsh = 0;
  54:     struct passwd *pwd;
  55:     int readfrom, ready;
  56:     int one = 1;
  57:     struct servent *sp;
  58:     int omask;
  59: 
  60:     host = rindex(argv[0], '/');
  61:     if (host)
  62:         host++;
  63:     else
  64:         host = argv[0];
  65:     argv++, --argc;
  66:     if (!strcmp(host, "rsh")) {
  67:         host = *argv++, --argc;
  68:         asrsh = 1;
  69:     }
  70: another:
  71:     if (argc > 0 && !strcmp(*argv, "-l")) {
  72:         argv++, argc--;
  73:         if (argc > 0)
  74:             user = *argv++, argc--;
  75:         goto another;
  76:     }
  77:     if (argc > 0 && !strcmp(*argv, "-n")) {
  78:         argv++, argc--;
  79:         (void) close(0);
  80:         (void) open("/dev/null", 0);
  81:         goto another;
  82:     }
  83:     if (argc > 0 && !strcmp(*argv, "-d")) {
  84:         argv++, argc--;
  85:         options |= SO_DEBUG;
  86:         goto another;
  87:     }
  88:     /*
  89: 	 * Ignore the -L, -w, -e and -8 flags to allow aliases with rlogin
  90: 	 * to work
  91: 	 *
  92: 	 * There must be a better way to do this! -jmb
  93: 	 */
  94:     if (argc > 0 && !strncmp(*argv, "-L", 2)) {
  95:         argv++, argc--;
  96:         goto another;
  97:     }
  98:     if (argc > 0 && !strncmp(*argv, "-w", 2)) {
  99:         argv++, argc--;
 100:         goto another;
 101:     }
 102:     if (argc > 0 && !strncmp(*argv, "-e", 2)) {
 103:         argv++, argc--;
 104:         goto another;
 105:     }
 106:     if (argc > 0 && !strncmp(*argv, "-8", 2)) {
 107:         argv++, argc--;
 108:         goto another;
 109:     }
 110:     if (host == 0)
 111:         goto usage;
 112:     if (argv[0] == 0) {
 113:         if (asrsh)
 114:             *argv0 = "rlogin";
 115:         execv("/usr/ucb/rlogin", argv0);
 116:         perror("/usr/ucb/rlogin");
 117:         exit(1);
 118:     }
 119:     pwd = getpwuid(getuid());
 120:     if (pwd == 0) {
 121:         fprintf(stderr, "who are you?\n");
 122:         exit(1);
 123:     }
 124:     cc = 0;
 125:     for (ap = argv; *ap; ap++)
 126:         cc += strlen(*ap) + 1;
 127:     cp = args = malloc(cc);
 128:     for (ap = argv; *ap; ap++) {
 129:         (void) strcpy(cp, *ap);
 130:         while (*cp)
 131:             cp++;
 132:         if (ap[1])
 133:             *cp++ = ' ';
 134:     }
 135:     sp = getservbyname("shell", "tcp");
 136:     if (sp == 0) {
 137:         fprintf(stderr, "rsh: shell/tcp: unknown service\n");
 138:         exit(1);
 139:     }
 140:         rem = rcmd(&host, sp->s_port, pwd->pw_name,
 141:         user ? user : pwd->pw_name, args, &rfd2);
 142:         if (rem < 0)
 143:                 exit(1);
 144:     if (rfd2 < 0) {
 145:         fprintf(stderr, "rsh: can't establish stderr\n");
 146:         exit(2);
 147:     }
 148:     if (options & SO_DEBUG) {
 149:         if (setsockopt(rem, SOL_SOCKET, SO_DEBUG, &one, sizeof (one)) < 0)
 150:             perror("setsockopt (stdin)");
 151:         if (setsockopt(rfd2, SOL_SOCKET, SO_DEBUG, &one, sizeof (one)) < 0)
 152:             perror("setsockopt (stderr)");
 153:     }
 154:     (void) setuid(getuid());
 155:     omask = sigblock(mask(SIGINT)|mask(SIGQUIT)|mask(SIGTERM));
 156:     if (signal(SIGINT, SIG_IGN) != SIG_IGN)
 157:         signal(SIGINT, sendsig);
 158:     if (signal(SIGQUIT, SIG_IGN) != SIG_IGN)
 159:         signal(SIGQUIT, sendsig);
 160:     if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
 161:         signal(SIGTERM, sendsig);
 162:         pid = fork();
 163:         if (pid < 0) {
 164:         perror("fork");
 165:                 exit(1);
 166:         }
 167:     ioctl(rfd2, FIONBIO, &one);
 168:     ioctl(rem, FIONBIO, &one);
 169:         if (pid == 0) {
 170:         char *bp; int rembits, wc;
 171:         (void) close(rfd2);
 172:     reread:
 173:         errno = 0;
 174:         cc = read(0, buf, sizeof buf);
 175:         if (cc <= 0)
 176:             goto done;
 177:         bp = buf;
 178:     rewrite:
 179:         rembits = 1<<rem;
 180:         if (select(16, 0, &rembits, 0, 0) < 0) {
 181:             if (errno != EINTR) {
 182:                 perror("select");
 183:                 exit(1);
 184:             }
 185:             goto rewrite;
 186:         }
 187:         if ((rembits & (1<<rem)) == 0)
 188:             goto rewrite;
 189:         wc = write(rem, bp, cc);
 190:         if (wc < 0) {
 191:             if (errno == EWOULDBLOCK)
 192:                 goto rewrite;
 193:             goto done;
 194:         }
 195:         cc -= wc; bp += wc;
 196:         if (cc == 0)
 197:             goto reread;
 198:         goto rewrite;
 199:     done:
 200:         (void) shutdown(rem, 1);
 201:         exit(0);
 202:     }
 203:     sigsetmask(omask);
 204:     readfrom = (1<<rfd2) | (1<<rem);
 205:     do {
 206:         ready = readfrom;
 207:         if (select(16, &ready, 0, 0, 0) < 0) {
 208:             if (errno != EINTR) {
 209:                 perror("select");
 210:                 exit(1);
 211:             }
 212:             continue;
 213:         }
 214:         if (ready & (1<<rfd2)) {
 215:             errno = 0;
 216:             cc = read(rfd2, buf, sizeof buf);
 217:             if (cc <= 0) {
 218:                 if (errno != EWOULDBLOCK)
 219:                     readfrom &= ~(1<<rfd2);
 220:             } else
 221:                 (void) write(2, buf, cc);
 222:         }
 223:         if (ready & (1<<rem)) {
 224:             errno = 0;
 225:             cc = read(rem, buf, sizeof buf);
 226:             if (cc <= 0) {
 227:                 if (errno != EWOULDBLOCK)
 228:                     readfrom &= ~(1<<rem);
 229:             } else
 230:                 (void) write(1, buf, cc);
 231:         }
 232:         } while (readfrom);
 233:         (void) kill(pid, SIGKILL);
 234:     exit(0);
 235: usage:
 236:     fprintf(stderr,
 237:         "usage: rsh host [ -l login ] [ -n ] command\n");
 238:     exit(1);
 239: }
 240: 
 241: sendsig(signo)
 242:     char signo;
 243: {
 244: 
 245:     (void) write(rfd2, &signo, 1);
 246: }

Defined functions

main defined in line 46; never used
sendsig defined in line 241; used 4 times

Defined variables

copyright defined in line 8; never used
errno defined in line 39; used 21 times
options defined in line 40; used 2 times
rfd2 defined in line 41; used 10 times
sccsid defined in line 14; never used

Defined macros

mask defined in line 44; used 3 times
  • in line 155(3)
Last modified: 1985-08-30
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1416
Valid CSS Valid XHTML 1.0 Strict