121174Sdist /* 2*39249Smarc * Copyright (c) 1983, 1988 The Regents of the University of California. 335441Sbostic * All rights reserved. 435441Sbostic * 535441Sbostic * Redistribution and use in source and binary forms are permitted 635441Sbostic * provided that the above copyright notice and this paragraph are 735441Sbostic * duplicated in all such forms and that any documentation, 835441Sbostic * advertising materials, and other materials related to such 935441Sbostic * distribution and use acknowledge that the software was developed 1035441Sbostic * by the University of California, Berkeley. The name of the 1135441Sbostic * University may not be used to endorse or promote products derived 1235441Sbostic * from this software without specific prior written permission. 1335441Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1435441Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1535441Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1621174Sdist */ 1721174Sdist 186446Swnj #ifndef lint 1921174Sdist char copyright[] = 20*39249Smarc "@(#) Copyright (c) 1983, 1988 The Regents of the University of California.\n\ 2121174Sdist All rights reserved.\n"; 2235441Sbostic #endif /* not lint */ 236446Swnj 2421174Sdist #ifndef lint 25*39249Smarc static char sccsid[] = "@(#)rlogind.c 5.22.1.8 (Berkeley) 10/02/89"; 2635441Sbostic #endif /* not lint */ 2721174Sdist 2816369Skarels /* 2916369Skarels * remote login server: 3036453Skfall * \0 3116369Skarels * remuser\0 3216369Skarels * locuser\0 3336453Skfall * terminal_type/speed\0 3436518Skarels * data 35*39249Smarc * 36*39249Smarc * Automatic login protocol is done here, using login -f upon success, 37*39249Smarc * unless OLD_LOGIN is defined (then done in login, ala 4.2/4.3BSD). 3816369Skarels */ 3916369Skarels 40*39249Smarc #include <stdio.h> 4137290Sbostic #include <sys/param.h> 426446Swnj #include <sys/stat.h> 436446Swnj #include <sys/socket.h> 4413554Ssam #include <sys/wait.h> 4518357Ssam #include <sys/file.h> 4637290Sbostic #include <sys/ioctl.h> 47*39249Smarc #if BSD > 43 4837290Sbostic #include <sys/termios.h> 49*39249Smarc #endif 509208Ssam 519208Ssam #include <netinet/in.h> 529208Ssam 536446Swnj #include <errno.h> 546446Swnj #include <pwd.h> 55*39249Smarc #include <signal.h> 56*39249Smarc #include <stdio.h> 578380Ssam #include <netdb.h> 5817187Sralph #include <syslog.h> 5918357Ssam #include <strings.h> 606446Swnj 6136518Skarels #ifndef TIOCPKT_WINDOW 6236518Skarels #define TIOCPKT_WINDOW 0x80 6336518Skarels #endif 6436518Skarels 6536518Skarels char *env[2]; 6636518Skarels #define NMAX 30 6736517Skarels char lusername[NMAX+1], rusername[NMAX+1]; 6836517Skarels static char term[64] = "TERM="; 6936517Skarels #define ENVSIZE (sizeof("TERM=")-1) /* skip null for concatenation */ 7036517Skarels int keepalive = 1; 7139058Skarels int check_all = 0; 7236453Skfall 7336453Skfall #define SUPERUSER(pwd) ((pwd)->pw_uid == 0) 7436453Skfall 7534424Sbostic extern int errno; 7610417Ssam int reapchild(); 7736453Skfall struct passwd *getpwnam(), *pwd; 7824723Smckusick char *malloc(); 7916369Skarels 806446Swnj main(argc, argv) 816446Swnj int argc; 826446Swnj char **argv; 836446Swnj { 84*39249Smarc extern int opterr, optind, _check_rhosts_file; 8536319Sbostic int ch; 8634424Sbostic int on = 1, fromlen; 876446Swnj struct sockaddr_in from; 886446Swnj 8936625Skfall openlog("rlogind", LOG_PID | LOG_CONS, LOG_AUTH); 9036319Sbostic 9136319Sbostic opterr = 0; 92*39249Smarc while ((ch = getopt(argc, argv, "aln")) != EOF) 9336517Skarels switch (ch) { 9439058Skarels case 'a': 9539058Skarels check_all = 1; 9639058Skarels break; 9736319Sbostic case 'l': 9836319Sbostic _check_rhosts_file = 0; 9936319Sbostic break; 10036517Skarels case 'n': 10136517Skarels keepalive = 0; 10236517Skarels break; 10336319Sbostic case '?': 10436319Sbostic default: 105*39249Smarc syslog(LOG_ERR, "usage: rlogind [-a] [-l] [-n]"); 10636319Sbostic break; 10736319Sbostic } 10836319Sbostic argc -= optind; 10936319Sbostic argv += optind; 11036319Sbostic 11116369Skarels fromlen = sizeof (from); 11216369Skarels if (getpeername(0, &from, &fromlen) < 0) { 113*39249Smarc syslog(LOG_ERR, "Couldn't get peer name of remote host: %m"); 114*39249Smarc fatalperror("Can't get peer name of remote host"); 1158380Ssam } 11636517Skarels if (keepalive && 11736517Skarels setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof (on)) < 0) 11817187Sralph syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m"); 11916369Skarels doit(0, &from); 1206446Swnj } 1216446Swnj 1226446Swnj int child; 1236446Swnj int cleanup(); 1246446Swnj int netf; 1256446Swnj char *line; 12624724Smckusick extern char *inet_ntoa(); 1276446Swnj 12824889Smckusick struct winsize win = { 0, 0, 0, 0 }; 12924723Smckusick 13024889Smckusick 1316446Swnj doit(f, fromp) 1326446Swnj int f; 1336446Swnj struct sockaddr_in *fromp; 1346446Swnj { 13518357Ssam int i, p, t, pid, on = 1; 136*39249Smarc #ifndef OLD_LOGIN 13736631Skarels int authenticated = 0, hostok = 0; 138*39249Smarc char remotehost[2 * MAXHOSTNAMELEN + 1]; 139*39249Smarc #endif 14039119Skarels register struct hostent *hp; 14124724Smckusick struct hostent hostent; 1428380Ssam char c; 1436446Swnj 1446446Swnj alarm(60); 1456446Swnj read(f, &c, 1); 146*39249Smarc if (c != 0) 14736715Skfall exit(1); 14836453Skfall 1496446Swnj alarm(0); 15016227Skarels fromp->sin_port = ntohs((u_short)fromp->sin_port); 1518380Ssam hp = gethostbyaddr(&fromp->sin_addr, sizeof (struct in_addr), 1528380Ssam fromp->sin_family); 15311345Ssam if (hp == 0) { 15424724Smckusick /* 15524724Smckusick * Only the name is used below. 15624724Smckusick */ 15724724Smckusick hp = &hostent; 15824724Smckusick hp->h_name = inet_ntoa(fromp->sin_addr); 159*39249Smarc #ifndef OLD_LOGIN 16036635Skarels hostok++; 161*39249Smarc #endif 162*39249Smarc } 163*39249Smarc #ifndef OLD_LOGIN 164*39249Smarc else if (check_all || local_domain(hp->h_name)) { 16536635Skarels /* 16636635Skarels * If name returned by gethostbyaddr is in our domain, 16736635Skarels * attempt to verify that we haven't been fooled by someone 16836635Skarels * in a remote net; look up the name and check that this 16936635Skarels * address corresponds to the name. 17036635Skarels */ 17136635Skarels strncpy(remotehost, hp->h_name, sizeof(remotehost) - 1); 17236635Skarels remotehost[sizeof(remotehost) - 1] = 0; 17336635Skarels hp = gethostbyname(remotehost); 17436635Skarels if (hp) 175*39249Smarc #ifdef h_addr /* 4.2 hack */ 17636635Skarels for (; hp->h_addr_list[0]; hp->h_addr_list++) 17736635Skarels if (!bcmp(hp->h_addr_list[0], (caddr_t)&fromp->sin_addr, 17836635Skarels sizeof(fromp->sin_addr))) { 17936635Skarels hostok++; 18036635Skarels break; 18136635Skarels } 182*39249Smarc #else 183*39249Smarc if (!bcmp(hp->h_addr, (caddr_t)&fromp->sin_addr, 184*39249Smarc sizeof(fromp->sin_addr))) 185*39249Smarc hostok++; 186*39249Smarc #endif 18736633Skarels } else 18836635Skarels hostok++; 189*39249Smarc #endif /* OLD_LOGIN */ 19036711Skfall 191*39249Smarc if (fromp->sin_family != AF_INET || 192*39249Smarc fromp->sin_port >= IPPORT_RESERVED || 193*39249Smarc fromp->sin_port < IPPORT_RESERVED/2) { 194*39249Smarc syslog(LOG_NOTICE, "Connection from %s on illegal port", 195*39249Smarc inet_ntoa(fromp->sin_addr)); 196*39249Smarc fatal(f, "Permission denied"); 197*39249Smarc } 19836702Skarels #ifdef IP_OPTIONS 199*39249Smarc { 200*39249Smarc u_char optbuf[BUFSIZ/3], *cp; 201*39249Smarc char lbuf[BUFSIZ], *lp; 202*39249Smarc int optsize = sizeof(optbuf), ipproto; 203*39249Smarc struct protoent *ip; 20436702Skarels 205*39249Smarc if ((ip = getprotobyname("ip")) != NULL) 206*39249Smarc ipproto = ip->p_proto; 207*39249Smarc else 208*39249Smarc ipproto = IPPROTO_IP; 209*39249Smarc if (getsockopt(0, ipproto, IP_OPTIONS, (char *)optbuf, &optsize) == 0 && 210*39249Smarc optsize != 0) { 211*39249Smarc lp = lbuf; 212*39249Smarc for (cp = optbuf; optsize > 0; cp++, optsize--, lp += 3) 213*39249Smarc sprintf(lp, " %2.2x", *cp); 214*39249Smarc syslog(LOG_NOTICE, 215*39249Smarc "Connection received using IP options (ignored):%s", lbuf); 216*39249Smarc if (setsockopt(0, ipproto, IP_OPTIONS, 217*39249Smarc (char *)NULL, &optsize) != 0) { 218*39249Smarc syslog(LOG_ERR, "setsockopt IP_OPTIONS NULL: %m"); 219*39249Smarc exit(1); 220*39249Smarc } 221*39249Smarc } 222*39249Smarc } 22336702Skarels #endif 224*39249Smarc write(f, "", 1); 225*39249Smarc #ifndef OLD_LOGIN 226*39249Smarc if (do_rlogin(hp->h_name) == 0) { 227*39249Smarc if (hostok) 228*39249Smarc authenticated++; 229*39249Smarc else 230*39249Smarc write(f, "rlogind: Host address mismatch.\r\n", 231*39249Smarc sizeof("rlogind: Host address mismatch.\r\n") - 1); 23236631Skarels } 233*39249Smarc #endif 23436636Skarels 2356446Swnj for (c = 'p'; c <= 's'; c++) { 2366446Swnj struct stat stb; 2376446Swnj line = "/dev/ptyXX"; 2386446Swnj line[strlen("/dev/pty")] = c; 2396446Swnj line[strlen("/dev/ptyp")] = '0'; 2406446Swnj if (stat(line, &stb) < 0) 2416446Swnj break; 2426446Swnj for (i = 0; i < 16; i++) { 24334424Sbostic line[sizeof("/dev/ptyp") - 1] = "0123456789abcdef"[i]; 24434424Sbostic p = open(line, O_RDWR); 2456446Swnj if (p > 0) 2466446Swnj goto gotpty; 2476446Swnj } 2486446Swnj } 249*39249Smarc fatal(f, "Out of ptys"); 2509242Ssam /*NOTREACHED*/ 2516446Swnj gotpty: 25224889Smckusick (void) ioctl(p, TIOCSWINSZ, &win); 25316227Skarels netf = f; 254*39249Smarc line[strlen("/dev/")] = 't'; 25534424Sbostic t = open(line, O_RDWR); 25634424Sbostic if (t < 0) 257*39249Smarc fatalperror(f, line); 25834424Sbostic if (fchmod(t, 0)) 259*39249Smarc fatalperror(f, line); 26034424Sbostic (void)signal(SIGHUP, SIG_IGN); 26134424Sbostic vhangup(); 26234424Sbostic (void)signal(SIGHUP, SIG_DFL); 26334424Sbostic t = open(line, O_RDWR); 26434424Sbostic if (t < 0) 265*39249Smarc fatalperror(f, line); 26636453Skfall setup_term(t); 267*39249Smarc #ifdef DEBUG 268*39249Smarc { 269*39249Smarc int tt = open("/dev/tty", O_RDWR); 270*39249Smarc if (tt > 0) { 271*39249Smarc (void)ioctl(tt, TIOCNOTTY, 0); 272*39249Smarc (void)close(tt); 273*39249Smarc } 274*39249Smarc } 275*39249Smarc #endif 2769242Ssam pid = fork(); 2779242Ssam if (pid < 0) 278*39249Smarc fatalperror(f, ""); 27918357Ssam if (pid == 0) { 280*39249Smarc #if BSD > 43 28136711Skfall if (setsid() < 0) 282*39249Smarc fatalperror(f, "setsid"); 28336711Skfall if (ioctl(t, TIOCSCTTY, 0) < 0) 284*39249Smarc fatalperror(f, "ioctl(sctty)"); 285*39249Smarc #endif 286*39249Smarc close(f), close(p); 287*39249Smarc dup2(t, 0), dup2(t, 1), dup2(t, 2); 288*39249Smarc close(t); 289*39249Smarc #ifdef OLD_LOGIN 290*39249Smarc execl("/bin/login", "login", "-r", hp->h_name, 0); 291*39249Smarc #else /* OLD_LOGIN */ 29236631Skarels if (authenticated) 293*39249Smarc execl("/bin/login", "login", "-p", "-h", hp->h_name, 294*39249Smarc "-f", lusername, 0); 29536525Skfall else 296*39249Smarc execl("/bin/login", "login", "-p", "-h", hp->h_name, 297*39249Smarc lusername, 0); 298*39249Smarc #endif /* OLD_LOGIN */ 299*39249Smarc fatalperror(2, "/bin/login"); 30018357Ssam /*NOTREACHED*/ 30118357Ssam } 30218357Ssam close(t); 30336453Skfall 304*39249Smarc ioctl(f, FIONBIO, &on); 30518357Ssam ioctl(p, FIONBIO, &on); 30618357Ssam ioctl(p, TIOCPKT, &on); 30718357Ssam signal(SIGTSTP, SIG_IGN); 30818357Ssam signal(SIGCHLD, cleanup); 30924724Smckusick setpgrp(0, 0); 31018357Ssam protocol(f, p); 31130600Smckusick signal(SIGCHLD, SIG_IGN); 31218357Ssam cleanup(); 31318357Ssam } 3149242Ssam 31518357Ssam char magic[2] = { 0377, 0377 }; 31625423Skarels char oobdata[] = {TIOCPKT_WINDOW}; 31718357Ssam 31818357Ssam /* 31918357Ssam * Handle a "control" request (signaled by magic being present) 32018357Ssam * in the data stream. For now, we are only willing to handle 32118357Ssam * window size changes. 32218357Ssam */ 32318357Ssam control(pty, cp, n) 32418357Ssam int pty; 32518357Ssam char *cp; 32618357Ssam int n; 32718357Ssam { 32828705Smckusick struct winsize w; 32918357Ssam 33028705Smckusick if (n < 4+sizeof (w) || cp[2] != 's' || cp[3] != 's') 33118357Ssam return (0); 33225423Skarels oobdata[0] &= ~TIOCPKT_WINDOW; /* we know he heard */ 33328705Smckusick bcopy(cp+4, (char *)&w, sizeof(w)); 33428705Smckusick w.ws_row = ntohs(w.ws_row); 33528705Smckusick w.ws_col = ntohs(w.ws_col); 33628705Smckusick w.ws_xpixel = ntohs(w.ws_xpixel); 33728705Smckusick w.ws_ypixel = ntohs(w.ws_ypixel); 33828705Smckusick (void)ioctl(pty, TIOCSWINSZ, &w); 33928705Smckusick return (4+sizeof (w)); 34018357Ssam } 34118357Ssam 34218357Ssam /* 34318357Ssam * rlogin "protocol" machine. 34418357Ssam */ 34518357Ssam protocol(f, p) 346*39249Smarc int f, p; 34718357Ssam { 34818357Ssam char pibuf[1024], fibuf[1024], *pbp, *fbp; 34918357Ssam register pcc = 0, fcc = 0; 350*39249Smarc int cc, nfd, pmask, fmask; 35125740Skarels char cntl; 35218357Ssam 35318482Ssam /* 35418484Ssam * Must ignore SIGTTOU, otherwise we'll stop 35518484Ssam * when we try and set slave pty's window shape 35625423Skarels * (our controlling tty is the master pty). 35718482Ssam */ 35818484Ssam (void) signal(SIGTTOU, SIG_IGN); 35925423Skarels send(f, oobdata, 1, MSG_OOB); /* indicate new rlogin */ 36036517Skarels if (f > p) 36136517Skarels nfd = f + 1; 36236517Skarels else 36336517Skarels nfd = p + 1; 364*39249Smarc fmask = 1 << f; 365*39249Smarc pmask = 1 << p; 36618357Ssam for (;;) { 367*39249Smarc int ibits, obits, ebits; 36818357Ssam 369*39249Smarc ibits = 0; 370*39249Smarc obits = 0; 37118357Ssam if (fcc) 372*39249Smarc obits |= pmask; 37318357Ssam else 374*39249Smarc ibits |= fmask; 37518357Ssam if (pcc >= 0) 37618357Ssam if (pcc) 377*39249Smarc obits |= fmask; 3789242Ssam else 379*39249Smarc ibits |= pmask; 380*39249Smarc ebits = pmask; 381*39249Smarc if (select(nfd, &ibits, obits ? &obits : (int *)NULL, 382*39249Smarc &ebits, 0) < 0) { 38318357Ssam if (errno == EINTR) 3846446Swnj continue; 385*39249Smarc fatalperror(f, "select"); 38618357Ssam } 387*39249Smarc if (ibits == 0 && obits == 0 && ebits == 0) { 38818357Ssam /* shouldn't happen... */ 38918357Ssam sleep(5); 39018357Ssam continue; 39118357Ssam } 39225740Skarels #define pkcontrol(c) ((c)&(TIOCPKT_FLUSHWRITE|TIOCPKT_NOSTOP|TIOCPKT_DOSTOP)) 393*39249Smarc if (ebits & pmask) { 39425740Skarels cc = read(p, &cntl, 1); 39525740Skarels if (cc == 1 && pkcontrol(cntl)) { 39625740Skarels cntl |= oobdata[0]; 39725740Skarels send(f, &cntl, 1, MSG_OOB); 39825740Skarels if (cntl & TIOCPKT_FLUSHWRITE) { 39925740Skarels pcc = 0; 400*39249Smarc ibits &= ~pmask; 40125740Skarels } 40225740Skarels } 40325740Skarels } 404*39249Smarc if (ibits & fmask) { 405*39249Smarc fcc = read(f, fibuf, sizeof(fibuf)); 40618357Ssam if (fcc < 0 && errno == EWOULDBLOCK) 40718357Ssam fcc = 0; 40818357Ssam else { 40918357Ssam register char *cp; 41018357Ssam int left, n; 41118357Ssam 41218357Ssam if (fcc <= 0) 41316227Skarels break; 41418357Ssam fbp = fibuf; 41524723Smckusick 41618357Ssam top: 41725423Skarels for (cp = fibuf; cp < fibuf+fcc-1; cp++) 41818357Ssam if (cp[0] == magic[0] && 41918357Ssam cp[1] == magic[1]) { 42018357Ssam left = fcc - (cp-fibuf); 42118357Ssam n = control(p, cp, left); 42218357Ssam if (n) { 42318357Ssam left -= n; 42418357Ssam if (left > 0) 42525423Skarels bcopy(cp+n, cp, left); 42618357Ssam fcc -= n; 42718357Ssam goto top; /* n^2 */ 42825423Skarels } 42925423Skarels } 430*39249Smarc obits |= pmask; /* try write */ 43125423Skarels } 43225423Skarels } 43324723Smckusick 434*39249Smarc if ((obits & pmask) && fcc > 0) { 43525423Skarels cc = write(p, fbp, fcc); 43624723Smckusick if (cc > 0) { 43724723Smckusick fcc -= cc; 43824723Smckusick fbp += cc; 4396446Swnj } 44018357Ssam } 44124723Smckusick 442*39249Smarc if (ibits & pmask) { 44318357Ssam pcc = read(p, pibuf, sizeof (pibuf)); 44418357Ssam pbp = pibuf; 44518357Ssam if (pcc < 0 && errno == EWOULDBLOCK) 44618357Ssam pcc = 0; 44718357Ssam else if (pcc <= 0) 44818357Ssam break; 44936517Skarels else if (pibuf[0] == 0) { 45018357Ssam pbp++, pcc--; 451*39249Smarc obits |= fmask; /* try a write */ 45236517Skarels } else { 45318357Ssam if (pkcontrol(pibuf[0])) { 45425423Skarels pibuf[0] |= oobdata[0]; 45518357Ssam send(f, &pibuf[0], 1, MSG_OOB); 45616227Skarels } 45718357Ssam pcc = 0; 4586446Swnj } 45918357Ssam } 460*39249Smarc if ((obits & fmask) && pcc > 0) { 461*39249Smarc cc = write(f, pbp, pcc); 46225423Skarels if (cc < 0 && errno == EWOULDBLOCK) { 46325423Skarels /* also shouldn't happen */ 46425423Skarels sleep(5); 46525423Skarels continue; 46625423Skarels } 46718357Ssam if (cc > 0) { 46818357Ssam pcc -= cc; 46918357Ssam pbp += cc; 47018357Ssam } 4716446Swnj } 4726446Swnj } 4736446Swnj } 4746446Swnj 4756446Swnj cleanup() 4766446Swnj { 47735440Sbostic char *p; 47835440Sbostic 479*39249Smarc p = line + sizeof("/dev/") - 1; 48035440Sbostic if (logout(p)) 48135440Sbostic logwtmp(p, "", ""); 48235440Sbostic (void)chmod(line, 0666); 48335440Sbostic (void)chown(line, 0, 0); 48435440Sbostic *p = 'p'; 48535440Sbostic (void)chmod(line, 0666); 48635440Sbostic (void)chown(line, 0, 0); 48710192Ssam shutdown(netf, 2); 4886446Swnj exit(1); 4896446Swnj } 4906446Swnj 491*39249Smarc fatal(f, msg) 492*39249Smarc int f; 4939242Ssam char *msg; 4949242Ssam { 4959242Ssam char buf[BUFSIZ]; 4969242Ssam 4979242Ssam buf[0] = '\01'; /* error indicator */ 498*39249Smarc (void) sprintf(buf + 1, "rlogind: %s.\r\n", msg); 499*39249Smarc (void) write(f, buf, strlen(buf)); 5009242Ssam exit(1); 5019242Ssam } 5029242Ssam 503*39249Smarc fatalperror(f, msg) 504*39249Smarc int f; 505*39249Smarc char *msg; 506*39249Smarc { 507*39249Smarc char buf[BUFSIZ]; 508*39249Smarc extern int sys_nerr; 509*39249Smarc extern char *sys_errlist[]; 510*39249Smarc 511*39249Smarc if ((unsigned)errno < sys_nerr) 512*39249Smarc (void) sprintf(buf, "%s: %s", msg, sys_errlist[errno]); 513*39249Smarc else 514*39249Smarc (void) sprintf(buf, "%s: Error %d", msg, errno); 515*39249Smarc fatal(f, buf); 516*39249Smarc } 517*39249Smarc 518*39249Smarc #ifndef OLD_LOGIN 51936453Skfall do_rlogin(host) 52036518Skarels char *host; 52136453Skfall { 522*39249Smarc 52336518Skarels getstr(rusername, sizeof(rusername), "remuser too long"); 52436518Skarels getstr(lusername, sizeof(lusername), "locuser too long"); 52536518Skarels getstr(term+ENVSIZE, sizeof(term)-ENVSIZE, "Terminal type too long"); 52636518Skarels 52736518Skarels if (getuid()) 52836453Skfall return(-1); 52936453Skfall pwd = getpwnam(lusername); 53036518Skarels if (pwd == NULL) 53136453Skfall return(-1); 53236453Skfall return(ruserok(host, SUPERUSER(pwd), rusername, lusername)); 53336453Skfall } 53436453Skfall 53536453Skfall 53636518Skarels getstr(buf, cnt, errmsg) 53736518Skarels char *buf; 53836518Skarels int cnt; 53936518Skarels char *errmsg; 54036453Skfall { 54136518Skarels char c; 54236518Skarels 54336453Skfall do { 54436518Skarels if (read(0, &c, 1) != 1) 54536453Skfall exit(1); 54636518Skarels if (--cnt < 0) 547*39249Smarc fatal(1, errmsg); 54836453Skfall *buf++ = c; 54936518Skarels } while (c != 0); 55036453Skfall } 55136453Skfall 55236518Skarels extern char **environ; 55336453Skfall 554*39249Smarc char *speeds[] = { 555*39249Smarc "0", "50", "75", "110", "134", "150", "200", "300", "600", 556*39249Smarc "1200", "1800", "2400", "4800", "9600", "19200", "38400", 557*39249Smarc }; 558*39249Smarc #define NSPEEDS (sizeof(speeds) / sizeof(speeds[0])) 559*39249Smarc 56036519Skarels setup_term(fd) 56136519Skarels int fd; 56236519Skarels { 563*39249Smarc register char *cp = index(term, '/'), **cpp; 56436519Skarels char *speed; 565*39249Smarc #if BSD > 43 56639118Skarels struct termios tt; 56736519Skarels 56836711Skfall tcgetattr(fd, &tt); 56936519Skarels if (cp) { 57036519Skarels *cp++ = '\0'; 57136519Skarels speed = cp; 57236519Skarels cp = index(speed, '/'); 57336519Skarels if (cp) 57436519Skarels *cp++ = '\0'; 57536711Skfall cfsetspeed(&tt, atoi(speed)); 57636519Skarels } 57738710Skfall 57839118Skarels tt.c_iflag = TTYDEF_IFLAG; 57939118Skarels tt.c_oflag = TTYDEF_OFLAG; 58039118Skarels tt.c_lflag = TTYDEF_LFLAG; 58139118Skarels tcsetattr(fd, TCSADFLUSH, &tt); 58239118Skarels #else 583*39249Smarc struct sgttyb sgttyb; 584*39249Smarc 585*39249Smarc (void)ioctl(fd, TIOCGETP, &sgttyb); 58639118Skarels if (cp) { 58739118Skarels *cp++ = '\0'; 58839118Skarels speed = cp; 58939118Skarels cp = index(speed, '/'); 59039118Skarels if (cp) 59139118Skarels *cp++ = '\0'; 592*39249Smarc for (cpp = speeds; cpp < &speeds[NSPEEDS]; cpp++) 593*39249Smarc if (strcmp(*cpp, speed) == 0) { 594*39249Smarc sgttyb.sg_ispeed = sgttyb.sg_ospeed = cpp - speeds; 595*39249Smarc break; 596*39249Smarc } 59738710Skfall } 598*39249Smarc sgttyb.sg_flags = ECHO|CRMOD|ANYP|XTABS; 599*39249Smarc (void)ioctl(fd, TIOCSETP, &sgttyb); 60038710Skfall #endif 60136519Skarels 60236519Skarels env[0] = term; 60336519Skarels env[1] = 0; 60436519Skarels environ = env; 60536519Skarels } 60636609Skfall 60736609Skfall /* 60836631Skarels * Check whether host h is in our local domain, 60939058Skarels * defined as sharing the last two components of the domain part, 61039058Skarels * or the entire domain part if the local domain has only one component. 61136631Skarels * If either name is unqualified (contains no '.'), 61236631Skarels * assume that the host is local, as it will be 61336631Skarels * interpreted as such. 61436631Skarels */ 61536631Skarels local_domain(h) 61636631Skarels char *h; 61736625Skfall { 61836631Skarels char localhost[MAXHOSTNAMELEN]; 61939058Skarels char *p1, *p2, *topdomain(); 62036631Skarels 62139058Skarels localhost[0] = 0; 62236631Skarels (void) gethostname(localhost, sizeof(localhost)); 62339058Skarels p1 = topdomain(localhost); 62439058Skarels p2 = topdomain(h); 62536631Skarels if (p1 == NULL || p2 == NULL || !strcasecmp(p1, p2)) 62636625Skfall return(1); 62736625Skfall return(0); 62836625Skfall } 62939058Skarels 63039058Skarels char * 63139058Skarels topdomain(h) 63239058Skarels char *h; 63339058Skarels { 63439058Skarels register char *p; 63539058Skarels char *maybe = NULL; 63639058Skarels int dots = 0; 63739058Skarels 63839058Skarels for (p = h + strlen(h); p >= h; p--) { 63939058Skarels if (*p == '.') { 64039058Skarels if (++dots == 2) 64139058Skarels return (p); 64239058Skarels maybe = p; 64339058Skarels } 64439058Skarels } 64539058Skarels return (maybe); 64639058Skarels } 647*39249Smarc #endif /* OLD_LOGIN */ 648