|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1983, 1990 The Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted provided ! 6: * that: (1) source distributions retain this entire copyright notice and ! 7: * comment, and (2) distributions including binaries display the following ! 8: * acknowledgement: ``This product includes software developed by the ! 9: * University of California, Berkeley and its contributors'' in the ! 10: * documentation or other materials provided with the distribution and in ! 11: * all advertising materials mentioning features or use of this software. ! 12: * Neither the name of the University nor the names of its contributors may ! 13: * be used to endorse or promote products derived from this software without ! 14: * specific prior written permission. ! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED ! 16: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF ! 17: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 18: */ ! 19: ! 20: #ifndef lint ! 21: char copyright[] = ! 22: "@(#) Copyright (c) 1983, 1990 The Regents of the University of California.\n\ ! 23: All rights reserved.\n"; ! 24: #endif /* not lint */ ! 25: ! 26: #ifndef lint ! 27: static char sccsid[] = "@(#)rlogin.c 5.29 (Berkeley) 6/27/90"; ! 28: #endif /* not lint */ ! 29: ! 30: /* ! 31: * $Source: mit/rlogin/RCS/rlogin.c,v $ ! 32: * $Header: mit/rlogin/RCS/rlogin.c,v 5.2 89/07/26 12:11:21 kfall ! 33: * Exp Locker: kfall $ ! 34: */ ! 35: ! 36: /* ! 37: * rlogin - remote login ! 38: */ ! 39: #include <sys/param.h> ! 40: #include <sys/file.h> ! 41: #include <sys/socket.h> ! 42: #include <sys/signal.h> ! 43: #include <sys/time.h> ! 44: #include <sys/resource.h> ! 45: #include <sys/wait.h> ! 46: ! 47: #include <netinet/in.h> ! 48: #include <netinet/in_systm.h> ! 49: #include <netinet/ip.h> ! 50: #include <netdb.h> ! 51: ! 52: #include <sgtty.h> ! 53: #include <setjmp.h> ! 54: #include <errno.h> ! 55: #include <varargs.h> ! 56: #include <pwd.h> ! 57: #include <stdio.h> ! 58: #include <unistd.h> ! 59: #include <string.h> ! 60: ! 61: #ifdef KERBEROS ! 62: #include <kerberosIV/des.h> ! 63: #include <kerberosIV/krb.h> ! 64: ! 65: CREDENTIALS cred; ! 66: Key_schedule schedule; ! 67: int use_kerberos = 1, encrypt; ! 68: char dst_realm_buf[REALM_SZ], *dest_realm = NULL; ! 69: extern char *krb_realmofhost(); ! 70: #endif ! 71: ! 72: #ifndef TIOCPKT_WINDOW ! 73: #define TIOCPKT_WINDOW 0x80 ! 74: #endif ! 75: ! 76: /* concession to Sun */ ! 77: #ifndef SIGUSR1 ! 78: #define SIGUSR1 30 ! 79: #endif ! 80: ! 81: extern int errno; ! 82: int eight, litout, rem; ! 83: char cmdchar; ! 84: char *speeds[] = { ! 85: "0", "50", "75", "110", "134", "150", "200", "300", "600", "1200", ! 86: "1800", "2400", "4800", "9600", "19200", "38400" ! 87: }; ! 88: ! 89: #ifdef sun ! 90: struct winsize { ! 91: unsigned short ws_row, ws_col; ! 92: unsigned short ws_xpixel, ws_ypixel; ! 93: }; ! 94: #endif ! 95: struct winsize winsize; ! 96: ! 97: #ifndef sun ! 98: #define get_window_size(fd, wp) ioctl(fd, TIOCGWINSZ, wp) ! 99: #endif ! 100: ! 101: void exit(); ! 102: ! 103: main(argc, argv) ! 104: int argc; ! 105: char **argv; ! 106: { ! 107: extern char *optarg; ! 108: extern int optind; ! 109: struct passwd *pw; ! 110: struct servent *sp; ! 111: struct sgttyb ttyb; ! 112: long omask; ! 113: int argoff, ch, dflag, one, uid; ! 114: char *host, *p, *user, term[1024]; ! 115: void lostpeer(); ! 116: char *getenv(); ! 117: ! 118: argoff = dflag = 0; ! 119: one = 1; ! 120: host = user = NULL; ! 121: cmdchar = '~'; ! 122: ! 123: if (p = rindex(argv[0], '/')) ! 124: ++p; ! 125: else ! 126: p = argv[0]; ! 127: ! 128: if (strcmp(p, "rlogin")) ! 129: host = p; ! 130: ! 131: /* handle "rlogin host flags" */ ! 132: if (!host && argc > 2 && argv[1][0] != '-') { ! 133: host = argv[1]; ! 134: argoff = 1; ! 135: } ! 136: ! 137: #ifdef KERBEROS ! 138: #define OPTIONS "8KLde:k:l:x" ! 139: #else ! 140: #define OPTIONS "8KLde:l:" ! 141: #endif ! 142: while ((ch = getopt(argc - argoff, argv + argoff, OPTIONS)) != EOF) ! 143: switch(ch) { ! 144: case '8': ! 145: eight = 1; ! 146: break; ! 147: case 'K': ! 148: #ifdef KERBEROS ! 149: use_kerberos = 0; ! 150: #endif ! 151: break; ! 152: case 'L': ! 153: litout = 1; ! 154: break; ! 155: case 'd': ! 156: dflag = 1; ! 157: break; ! 158: case 'e': ! 159: cmdchar = optarg[0]; ! 160: break; ! 161: #ifdef KERBEROS ! 162: case 'k': ! 163: dest_realm = dst_realm_buf; ! 164: (void)strncpy(dest_realm, optarg, REALM_SZ); ! 165: break; ! 166: #endif ! 167: case 'l': ! 168: user = optarg; ! 169: break; ! 170: #ifdef KERBEROS ! 171: case 'x': ! 172: encrypt = 1; ! 173: des_set_key(cred.session, schedule); ! 174: break; ! 175: #endif ! 176: case '?': ! 177: default: ! 178: usage(); ! 179: } ! 180: optind += argoff; ! 181: argc -= optind; ! 182: argv += optind; ! 183: ! 184: /* if haven't gotten a host yet, do so */ ! 185: if (!host && !(host = *argv++)) ! 186: usage(); ! 187: ! 188: if (*argv) ! 189: usage(); ! 190: ! 191: if (!(pw = getpwuid(uid = getuid()))) { ! 192: (void)fprintf(stderr, "rlogin: unknown user id.\n"); ! 193: exit(1); ! 194: } ! 195: if (!user) ! 196: user = pw->pw_name; ! 197: ! 198: sp = NULL; ! 199: #ifdef KERBEROS ! 200: if (use_kerberos) { ! 201: sp = getservbyname((encrypt ? "eklogin" : "klogin"), "tcp"); ! 202: if (sp == NULL) { ! 203: use_kerberos = 0; ! 204: warning("can't get entry for %s/tcp service", ! 205: encrypt ? "eklogin" : "klogin"); ! 206: } ! 207: } ! 208: #endif ! 209: if (sp == NULL) ! 210: sp = getservbyname("login", "tcp"); ! 211: if (sp == NULL) { ! 212: (void)fprintf(stderr, "rlogin: login/tcp: unknown service.\n"); ! 213: exit(1); ! 214: } ! 215: ! 216: (void)strcpy(term, (p = getenv("TERM")) ? p : "network"); ! 217: if (ioctl(0, TIOCGETP, &ttyb) == 0) { ! 218: (void)strcat(term, "/"); ! 219: (void)strcat(term, speeds[ttyb.sg_ospeed]); ! 220: } ! 221: ! 222: (void)get_window_size(0, &winsize); ! 223: ! 224: (void)signal(SIGPIPE, lostpeer); ! 225: /* will use SIGUSR1 for window size hack, so hold it off */ ! 226: omask = sigblock(sigmask(SIGURG) | sigmask(SIGUSR1)); ! 227: ! 228: #ifdef KERBEROS ! 229: try_connect: ! 230: if (use_kerberos) { ! 231: rem = KSUCCESS; ! 232: errno = 0; ! 233: if (dest_realm == NULL) ! 234: dest_realm = krb_realmofhost(host); ! 235: ! 236: if (encrypt) ! 237: rem = krcmd_mutual(&host, sp->s_port, user, term, 0, ! 238: dest_realm, &cred, schedule); ! 239: else ! 240: rem = krcmd(&host, sp->s_port, user, term, 0, ! 241: dest_realm); ! 242: if (rem < 0) { ! 243: use_kerberos = 0; ! 244: sp = getservbyname("login", "tcp"); ! 245: if (sp == NULL) { ! 246: (void)fprintf(stderr, ! 247: "rlogin: unknown service login/tcp.\n"); ! 248: exit(1); ! 249: } ! 250: if (errno == ECONNREFUSED) ! 251: warning("remote host doesn't support Kerberos"); ! 252: if (errno == ENOENT) ! 253: warning("can't provide Kerberos auth data"); ! 254: goto try_connect; ! 255: } ! 256: } else { ! 257: if (encrypt) { ! 258: (void)fprintf(stderr, ! 259: "rlogin: the -x flag requires Kerberos authentication.\n"); ! 260: exit(1); ! 261: } ! 262: rem = rcmd(&host, sp->s_port, pw->pw_name, user, term, 0); ! 263: } ! 264: #else ! 265: rem = rcmd(&host, sp->s_port, pw->pw_name, user, term, 0); ! 266: #endif ! 267: ! 268: if (rem < 0) ! 269: exit(1); ! 270: ! 271: if (dflag && ! 272: setsockopt(rem, SOL_SOCKET, SO_DEBUG, &one, sizeof(one)) < 0) ! 273: (void)fprintf(stderr, "rlogin: setsockopt: %s.\n", ! 274: strerror(errno)); ! 275: one = IPTOS_LOWDELAY; ! 276: if (setsockopt(rem, IPPROTO_IP, IP_TOS, (char *)&one, sizeof(int)) < 0) ! 277: perror("rlogin: setsockopt TOS (ignored)"); ! 278: ! 279: (void)setuid(uid); ! 280: doit(omask); ! 281: /*NOTREACHED*/ ! 282: } ! 283: ! 284: int child, defflags, deflflags, tabflag; ! 285: char deferase, defkill; ! 286: struct tchars deftc; ! 287: struct ltchars defltc; ! 288: struct tchars notc = { -1, -1, -1, -1, -1, -1 }; ! 289: struct ltchars noltc = { -1, -1, -1, -1, -1, -1 }; ! 290: ! 291: doit(omask) ! 292: long omask; ! 293: { ! 294: struct sgttyb sb; ! 295: void catch_child(), copytochild(), exit(), writeroob(); ! 296: ! 297: (void)ioctl(0, TIOCGETP, (char *)&sb); ! 298: defflags = sb.sg_flags; ! 299: tabflag = defflags & TBDELAY; ! 300: defflags &= ECHO | CRMOD; ! 301: deferase = sb.sg_erase; ! 302: defkill = sb.sg_kill; ! 303: (void)ioctl(0, TIOCLGET, (char *)&deflflags); ! 304: (void)ioctl(0, TIOCGETC, (char *)&deftc); ! 305: notc.t_startc = deftc.t_startc; ! 306: notc.t_stopc = deftc.t_stopc; ! 307: (void)ioctl(0, TIOCGLTC, (char *)&defltc); ! 308: (void)signal(SIGINT, SIG_IGN); ! 309: setsignal(SIGHUP, exit); ! 310: setsignal(SIGQUIT, exit); ! 311: child = fork(); ! 312: if (child == -1) { ! 313: (void)fprintf(stderr, "rlogin: fork: %s.\n", strerror(errno)); ! 314: done(1); ! 315: } ! 316: if (child == 0) { ! 317: mode(1); ! 318: if (reader(omask) == 0) { ! 319: msg("connection closed."); ! 320: exit(0); ! 321: } ! 322: sleep(1); ! 323: msg("\007connection closed."); ! 324: exit(1); ! 325: } ! 326: ! 327: /* ! 328: * We may still own the socket, and may have a pending SIGURG (or might ! 329: * receive one soon) that we really want to send to the reader. Set a ! 330: * trap that simply copies such signals to the child. ! 331: */ ! 332: (void)signal(SIGURG, copytochild); ! 333: (void)signal(SIGUSR1, writeroob); ! 334: (void)sigsetmask(omask); ! 335: (void)signal(SIGCHLD, catch_child); ! 336: writer(); ! 337: msg("closed connection."); ! 338: done(0); ! 339: } ! 340: ! 341: /* trap a signal, unless it is being ignored. */ ! 342: setsignal(sig, act) ! 343: int sig; ! 344: void (*act)(); ! 345: { ! 346: int omask = sigblock(sigmask(sig)); ! 347: ! 348: if (signal(sig, act) == SIG_IGN) ! 349: (void)signal(sig, SIG_IGN); ! 350: (void)sigsetmask(omask); ! 351: } ! 352: ! 353: done(status) ! 354: int status; ! 355: { ! 356: int w; ! 357: ! 358: mode(0); ! 359: if (child > 0) { ! 360: /* make sure catch_child does not snap it up */ ! 361: (void)signal(SIGCHLD, SIG_DFL); ! 362: if (kill(child, SIGKILL) >= 0) ! 363: while ((w = wait((union wait *)0)) > 0 && w != child); ! 364: } ! 365: exit(status); ! 366: } ! 367: ! 368: int dosigwinch; ! 369: ! 370: /* ! 371: * This is called when the reader process gets the out-of-band (urgent) ! 372: * request to turn on the window-changing protocol. ! 373: */ ! 374: void ! 375: writeroob() ! 376: { ! 377: void sigwinch(); ! 378: ! 379: if (dosigwinch == 0) { ! 380: sendwindow(); ! 381: (void)signal(SIGWINCH, sigwinch); ! 382: } ! 383: dosigwinch = 1; ! 384: } ! 385: ! 386: void ! 387: catch_child() ! 388: { ! 389: union wait status; ! 390: int pid; ! 391: ! 392: for (;;) { ! 393: pid = wait3(&status, WNOHANG|WUNTRACED, (struct rusage *)0); ! 394: if (pid == 0) ! 395: return; ! 396: /* if the child (reader) dies, just quit */ ! 397: if (pid < 0 || pid == child && !WIFSTOPPED(status)) ! 398: done((int)(status.w_termsig | status.w_retcode)); ! 399: } ! 400: /* NOTREACHED */ ! 401: } ! 402: ! 403: /* ! 404: * writer: write to remote: 0 -> line. ! 405: * ~. terminate ! 406: * ~^Z suspend rlogin process. ! 407: * ~^Y suspend rlogin process, but leave reader alone. ! 408: */ ! 409: writer() ! 410: { ! 411: char c; ! 412: register int bol, local, n; ! 413: ! 414: bol = 1; /* beginning of line */ ! 415: local = 0; ! 416: for (;;) { ! 417: n = read(STDIN_FILENO, &c, 1); ! 418: if (n <= 0) { ! 419: if (n < 0 && errno == EINTR) ! 420: continue; ! 421: break; ! 422: } ! 423: /* ! 424: * If we're at the beginning of the line and recognize a ! 425: * command character, then we echo locally. Otherwise, ! 426: * characters are echo'd remotely. If the command character ! 427: * is doubled, this acts as a force and local echo is ! 428: * suppressed. ! 429: */ ! 430: if (bol) { ! 431: bol = 0; ! 432: if (c == cmdchar) { ! 433: bol = 0; ! 434: local = 1; ! 435: continue; ! 436: } ! 437: } else if (local) { ! 438: local = 0; ! 439: if (c == '.' || c == deftc.t_eofc) { ! 440: echo(c); ! 441: break; ! 442: } ! 443: if (c == defltc.t_suspc || c == defltc.t_dsuspc) { ! 444: bol = 1; ! 445: echo(c); ! 446: stop(c); ! 447: continue; ! 448: } ! 449: if (c != cmdchar) { ! 450: #ifdef KERBEROS ! 451: if (encrypt) { ! 452: (void)des_write(rem, &cmdchar, 1); ! 453: } else ! 454: #endif ! 455: (void)write(rem, &cmdchar, 1); ! 456: } ! 457: } ! 458: ! 459: #ifdef KERBEROS ! 460: if (encrypt) { ! 461: if (des_write(rem, &c, 1) == 0) { ! 462: msg("line gone"); ! 463: break; ! 464: } ! 465: } else ! 466: #endif ! 467: if (write(rem, &c, 1) == 0) { ! 468: msg("line gone"); ! 469: break; ! 470: } ! 471: bol = c == defkill || c == deftc.t_eofc || ! 472: c == deftc.t_intrc || c == defltc.t_suspc || ! 473: c == '\r' || c == '\n'; ! 474: } ! 475: } ! 476: ! 477: echo(c) ! 478: register char c; ! 479: { ! 480: register char *p; ! 481: char buf[8]; ! 482: ! 483: p = buf; ! 484: c &= 0177; ! 485: *p++ = cmdchar; ! 486: if (c < ' ') { ! 487: *p++ = '^'; ! 488: *p++ = c + '@'; ! 489: } else if (c == 0177) { ! 490: *p++ = '^'; ! 491: *p++ = '?'; ! 492: } else ! 493: *p++ = c; ! 494: *p++ = '\r'; ! 495: *p++ = '\n'; ! 496: (void)write(1, buf, p - buf); ! 497: } ! 498: ! 499: stop(cmdc) ! 500: char cmdc; ! 501: { ! 502: mode(0); ! 503: (void)signal(SIGCHLD, SIG_IGN); ! 504: (void)kill(cmdc == defltc.t_suspc ? 0 : getpid(), SIGTSTP); ! 505: (void)signal(SIGCHLD, catch_child); ! 506: mode(1); ! 507: sigwinch(); /* check for size changes */ ! 508: } ! 509: ! 510: void ! 511: sigwinch() ! 512: { ! 513: struct winsize ws; ! 514: ! 515: if (dosigwinch && get_window_size(0, &ws) == 0 && ! 516: bcmp(&ws, &winsize, sizeof(ws))) { ! 517: winsize = ws; ! 518: sendwindow(); ! 519: } ! 520: } ! 521: ! 522: /* ! 523: * Send the window size to the server via the magic escape ! 524: */ ! 525: sendwindow() ! 526: { ! 527: struct winsize *wp; ! 528: char obuf[4 + sizeof (struct winsize)]; ! 529: ! 530: wp = (struct winsize *)(obuf+4); ! 531: obuf[0] = 0377; ! 532: obuf[1] = 0377; ! 533: obuf[2] = 's'; ! 534: obuf[3] = 's'; ! 535: wp->ws_row = htons(winsize.ws_row); ! 536: wp->ws_col = htons(winsize.ws_col); ! 537: wp->ws_xpixel = htons(winsize.ws_xpixel); ! 538: wp->ws_ypixel = htons(winsize.ws_ypixel); ! 539: ! 540: #ifdef KERBEROS ! 541: if(encrypt) ! 542: (void)des_write(rem, obuf, sizeof(obuf)); ! 543: else ! 544: #endif ! 545: (void)write(rem, obuf, sizeof(obuf)); ! 546: } ! 547: ! 548: /* ! 549: * reader: read from remote: line -> 1 ! 550: */ ! 551: #define READING 1 ! 552: #define WRITING 2 ! 553: ! 554: jmp_buf rcvtop; ! 555: int ppid, rcvcnt, rcvstate; ! 556: char rcvbuf[8 * 1024]; ! 557: ! 558: void ! 559: oob() ! 560: { ! 561: struct sgttyb sb; ! 562: int atmark, n, out, rcvd; ! 563: char waste[BUFSIZ], mark; ! 564: ! 565: out = O_RDWR; ! 566: rcvd = 0; ! 567: while (recv(rem, &mark, 1, MSG_OOB) < 0) ! 568: switch (errno) { ! 569: case EWOULDBLOCK: ! 570: /* ! 571: * Urgent data not here yet. It may not be possible ! 572: * to send it yet if we are blocked for output and ! 573: * our input buffer is full. ! 574: */ ! 575: if (rcvcnt < sizeof(rcvbuf)) { ! 576: n = read(rem, rcvbuf + rcvcnt, ! 577: sizeof(rcvbuf) - rcvcnt); ! 578: if (n <= 0) ! 579: return; ! 580: rcvd += n; ! 581: } else { ! 582: n = read(rem, waste, sizeof(waste)); ! 583: if (n <= 0) ! 584: return; ! 585: } ! 586: continue; ! 587: default: ! 588: return; ! 589: } ! 590: if (mark & TIOCPKT_WINDOW) { ! 591: /* Let server know about window size changes */ ! 592: (void)kill(ppid, SIGUSR1); ! 593: } ! 594: if (!eight && (mark & TIOCPKT_NOSTOP)) { ! 595: (void)ioctl(0, TIOCGETP, (char *)&sb); ! 596: sb.sg_flags &= ~CBREAK; ! 597: sb.sg_flags |= RAW; ! 598: (void)ioctl(0, TIOCSETN, (char *)&sb); ! 599: notc.t_stopc = -1; ! 600: notc.t_startc = -1; ! 601: (void)ioctl(0, TIOCSETC, (char *)¬c); ! 602: } ! 603: if (!eight && (mark & TIOCPKT_DOSTOP)) { ! 604: (void)ioctl(0, TIOCGETP, (char *)&sb); ! 605: sb.sg_flags &= ~RAW; ! 606: sb.sg_flags |= CBREAK; ! 607: (void)ioctl(0, TIOCSETN, (char *)&sb); ! 608: notc.t_stopc = deftc.t_stopc; ! 609: notc.t_startc = deftc.t_startc; ! 610: (void)ioctl(0, TIOCSETC, (char *)¬c); ! 611: } ! 612: if (mark & TIOCPKT_FLUSHWRITE) { ! 613: (void)ioctl(1, TIOCFLUSH, (char *)&out); ! 614: for (;;) { ! 615: if (ioctl(rem, SIOCATMARK, &atmark) < 0) { ! 616: (void)fprintf(stderr, "rlogin: ioctl: %s.\n", ! 617: strerror(errno)); ! 618: break; ! 619: } ! 620: if (atmark) ! 621: break; ! 622: n = read(rem, waste, sizeof (waste)); ! 623: if (n <= 0) ! 624: break; ! 625: } ! 626: /* ! 627: * Don't want any pending data to be output, so clear the recv ! 628: * buffer. If we were hanging on a write when interrupted, ! 629: * don't want it to restart. If we were reading, restart ! 630: * anyway. ! 631: */ ! 632: rcvcnt = 0; ! 633: longjmp(rcvtop, 1); ! 634: } ! 635: ! 636: /* oob does not do FLUSHREAD (alas!) */ ! 637: ! 638: /* ! 639: * If we filled the receive buffer while a read was pending, longjmp ! 640: * to the top to restart appropriately. Don't abort a pending write, ! 641: * however, or we won't know how much was written. ! 642: */ ! 643: if (rcvd && rcvstate == READING) ! 644: longjmp(rcvtop, 1); ! 645: } ! 646: ! 647: /* reader: read from remote: line -> 1 */ ! 648: reader(omask) ! 649: int omask; ! 650: { ! 651: void oob(); ! 652: ! 653: #if !defined(BSD) || BSD < 43 ! 654: int pid = -getpid(); ! 655: #else ! 656: int pid = getpid(); ! 657: #endif ! 658: int n, remaining; ! 659: char *bufp = rcvbuf; ! 660: ! 661: (void)signal(SIGTTOU, SIG_IGN); ! 662: (void)signal(SIGURG, oob); ! 663: ppid = getppid(); ! 664: (void)fcntl(rem, F_SETOWN, pid); ! 665: (void)setjmp(rcvtop); ! 666: (void)sigsetmask(omask); ! 667: for (;;) { ! 668: while ((remaining = rcvcnt - (bufp - rcvbuf)) > 0) { ! 669: rcvstate = WRITING; ! 670: n = write(1, bufp, remaining); ! 671: if (n < 0) { ! 672: if (errno != EINTR) ! 673: return(-1); ! 674: continue; ! 675: } ! 676: bufp += n; ! 677: } ! 678: bufp = rcvbuf; ! 679: rcvcnt = 0; ! 680: rcvstate = READING; ! 681: ! 682: #ifdef KERBEROS ! 683: if (encrypt) ! 684: rcvcnt = des_read(rem, rcvbuf, sizeof(rcvbuf)); ! 685: else ! 686: #endif ! 687: rcvcnt = read(rem, rcvbuf, sizeof (rcvbuf)); ! 688: if (rcvcnt == 0) ! 689: return (0); ! 690: if (rcvcnt < 0) { ! 691: if (errno == EINTR) ! 692: continue; ! 693: (void)fprintf(stderr, "rlogin: read: %s.\n", ! 694: strerror(errno)); ! 695: return(-1); ! 696: } ! 697: } ! 698: } ! 699: ! 700: mode(f) ! 701: { ! 702: struct ltchars *ltc; ! 703: struct sgttyb sb; ! 704: struct tchars *tc; ! 705: int lflags; ! 706: ! 707: (void)ioctl(0, TIOCGETP, (char *)&sb); ! 708: (void)ioctl(0, TIOCLGET, (char *)&lflags); ! 709: switch(f) { ! 710: case 0: ! 711: sb.sg_flags &= ~(CBREAK|RAW|TBDELAY); ! 712: sb.sg_flags |= defflags|tabflag; ! 713: tc = &deftc; ! 714: ltc = &defltc; ! 715: sb.sg_kill = defkill; ! 716: sb.sg_erase = deferase; ! 717: lflags = deflflags; ! 718: break; ! 719: case 1: ! 720: sb.sg_flags |= (eight ? RAW : CBREAK); ! 721: sb.sg_flags &= ~defflags; ! 722: /* preserve tab delays, but turn off XTABS */ ! 723: if ((sb.sg_flags & TBDELAY) == XTABS) ! 724: sb.sg_flags &= ~TBDELAY; ! 725: tc = ¬c; ! 726: ltc = &noltc; ! 727: sb.sg_kill = sb.sg_erase = -1; ! 728: if (litout) ! 729: lflags |= LLITOUT; ! 730: break; ! 731: default: ! 732: return; ! 733: } ! 734: (void)ioctl(0, TIOCSLTC, (char *)ltc); ! 735: (void)ioctl(0, TIOCSETC, (char *)tc); ! 736: (void)ioctl(0, TIOCSETN, (char *)&sb); ! 737: (void)ioctl(0, TIOCLSET, (char *)&lflags); ! 738: } ! 739: ! 740: void ! 741: lostpeer() ! 742: { ! 743: (void)signal(SIGPIPE, SIG_IGN); ! 744: msg("\007connection closed."); ! 745: done(1); ! 746: } ! 747: ! 748: /* copy SIGURGs to the child process. */ ! 749: void ! 750: copytochild() ! 751: { ! 752: (void)kill(child, SIGURG); ! 753: } ! 754: ! 755: msg(str) ! 756: char *str; ! 757: { ! 758: (void)fprintf(stderr, "rlogin: %s\r\n", str); ! 759: } ! 760: ! 761: #ifdef KERBEROS ! 762: /* VARARGS */ ! 763: warning(va_alist) ! 764: va_dcl ! 765: { ! 766: va_list ap; ! 767: char *fmt; ! 768: ! 769: (void)fprintf(stderr, "rlogin: warning, using standard rlogin: "); ! 770: va_start(ap); ! 771: fmt = va_arg(ap, char *); ! 772: vfprintf(stderr, fmt, ap); ! 773: va_end(ap); ! 774: (void)fprintf(stderr, ".\n"); ! 775: } ! 776: #endif ! 777: ! 778: usage() ! 779: { ! 780: (void)fprintf(stderr, ! 781: "usage: rlogin [ -%s]%s[-e char] [ -l username ] host\n", ! 782: #ifdef KERBEROS ! 783: "8Lx", " [-k realm] "); ! 784: #else ! 785: "8L", " "); ! 786: #endif ! 787: exit(1); ! 788: } ! 789: ! 790: /* ! 791: * The following routine provides compatibility (such as it is) between 4.2BSD ! 792: * Suns and others. Suns have only a `ttysize', so we convert it to a winsize. ! 793: */ ! 794: #ifdef sun ! 795: int ! 796: get_window_size(fd, wp) ! 797: int fd; ! 798: struct winsize *wp; ! 799: { ! 800: struct ttysize ts; ! 801: int error; ! 802: ! 803: if ((error = ioctl(0, TIOCGSIZE, &ts)) != 0) ! 804: return(error); ! 805: wp->ws_row = ts.ts_lines; ! 806: wp->ws_col = ts.ts_cols; ! 807: wp->ws_xpixel = 0; ! 808: wp->ws_ypixel = 0; ! 809: return(0); ! 810: } ! 811: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.