# 2.11BSD#431 - /usr/src/ucb/rsh.c

##### Functions

    main              X
    sendsig           X

##### Variables

    copyright         X
    errno             X
    options           X
    rfd2              X

##### Macros

    mask              X

       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) (1L << ((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:     long readfrom, ready;
      56:     long one = 1;
      57:     struct servent *sp;
      58:     long 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; long rembits; int 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 = 1L<<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 & (1L<<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 = (1L<<rfd2) | (1L<<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 & (1L<<rfd2)) {
     215:             errno = 0;
     216:             cc = read(rfd2, buf, sizeof buf);
     217:             if (cc <= 0) {
     218:                 if (errno != EWOULDBLOCK)
     219:                     readfrom &= ~(1L<<rfd2);
     220:             } else
     221:                 (void) write(2, buf, cc);
     222:         }
     223:         if (ready & (1L<<rem)) {
     224:             errno = 0;
     225:             cc = read(rem, buf, sizeof buf);
     226:             if (cc <= 0) {
     227:                 if (errno != EWOULDBLOCK)
     228:                     readfrom &= ~(1L<<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

- in line 42, 157-161(3)

#### Defined variables

copyright defined in line 8; never used
errno defined in line 39; used 8 times

- in line 173, 181, 191, 208, 215-218(2), 224-227(2)

options defined in line 40; used 2 times

- in line 85, 148

rfd2 defined in line 41; used 10 times

- in line 141-144(2), 151, 167-171(2), 204, 214-219(3), 245

sccsid defined in line 14; never used

#### Defined macros

mask defined in line 44; used 3 times

- in line 155(3)

Last modified: 1987-08-14 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 819 |