1*19843Sdist /* 2*19843Sdist * Copyright (c) 1980 Regents of the University of California. 3*19843Sdist * All rights reserved. The Berkeley software License Agreement 4*19843Sdist * specifies the terms and conditions for redistribution. 5*19843Sdist */ 6*19843Sdist 712678Ssam #ifndef lint 8*19843Sdist char copyright[] = 9*19843Sdist "@(#) Copyright (c) 1980 Regents of the University of California.\n\ 10*19843Sdist All rights reserved.\n"; 11*19843Sdist #endif not lint 1212678Ssam 13*19843Sdist #ifndef lint 14*19843Sdist static char sccsid[] = "@(#)login.c 5.1 (Berkeley) 04/30/85"; 15*19843Sdist #endif not lint 16*19843Sdist 171043Sbill /* 181043Sbill * login [ name ] 1912687Ssam * login -r hostname (for rlogind) 2012687Ssam * login -h hostname (for telnetd, etc.) 211043Sbill */ 221043Sbill 2312984Ssam #include <sys/param.h> 2412687Ssam #include <sys/quota.h> 2512687Ssam #include <sys/stat.h> 2612687Ssam #include <sys/time.h> 2712687Ssam #include <sys/resource.h> 2816453Sroot #include <sys/file.h> 2912687Ssam 301043Sbill #include <sgtty.h> 311043Sbill #include <utmp.h> 321043Sbill #include <signal.h> 331043Sbill #include <pwd.h> 341043Sbill #include <stdio.h> 351043Sbill #include <lastlog.h> 3612678Ssam #include <errno.h> 3716453Sroot #include <ttyent.h> 3816453Sroot #include <syslog.h> 391043Sbill 4016453Sroot #define SCMPN(a, b) strncmp(a, b, sizeof(a)) 412822Swnj #define SCPYN(a, b) strncpy(a, b, sizeof(a)) 422822Swnj 436197Sroot #define NMAX sizeof(utmp.ut_name) 441043Sbill 452822Swnj #define FALSE 0 462822Swnj #define TRUE -1 472822Swnj 482822Swnj char nolog[] = "/etc/nologin"; 492822Swnj char qlog[] = ".hushlogin"; 501043Sbill char maildir[30] = "/usr/spool/mail/"; 511043Sbill char lastlog[] = "/usr/adm/lastlog"; 529867Ssam struct passwd nouser = {"", "nope", -1, -1, -1, "", "", "", "" }; 531043Sbill struct sgttyb ttyb; 541043Sbill struct utmp utmp; 551043Sbill char minusnam[16] = "-"; 5618549Ssam char *envinit[] = { 0 }; /* now set by setenv calls */ 5712687Ssam /* 5812687Ssam * This bounds the time given to login. We initialize it here 5912687Ssam * so it can be patched on machines where it's too small. 6012687Ssam */ 6112687Ssam int timeout = 60; 626005Swnj 6318549Ssam char term[64]; 646005Swnj 651043Sbill struct passwd *pwd; 6618549Ssam char *strcat(), *rindex(), *index(), *malloc(), *realloc(); 6712687Ssam int timedout(); 681043Sbill char *ttyname(); 691043Sbill char *crypt(); 701043Sbill char *getpass(); 711043Sbill char *stypeof(); 721043Sbill extern char **environ; 7312678Ssam extern int errno; 741043Sbill 7513074Ssam struct tchars tc = { 7613074Ssam CINTR, CQUIT, CSTART, CSTOP, CEOT, CBRK 771365Sbill }; 7813074Ssam struct ltchars ltc = { 7913074Ssam CSUSP, CDSUSP, CRPRNT, CFLUSH, CWERASE, CLNEXT 8013074Ssam }; 811365Sbill 8218549Ssam struct winsize win = { 0, 0, 0, 0 }; 8318549Ssam 846005Swnj int rflag; 856197Sroot char rusername[NMAX+1], lusername[NMAX+1]; 866005Swnj char rpassword[NMAX+1]; 876878Smckusick char name[NMAX+1]; 886197Sroot char *rhost; 896005Swnj 901043Sbill main(argc, argv) 9112687Ssam char *argv[]; 921043Sbill { 931043Sbill register char *namep; 9418549Ssam int pflag = 0, hflag = 0, t, f, c; 9512687Ssam int invalid, quietlog; 962822Swnj FILE *nlfd; 9716453Sroot char *ttyn, *tty; 9818549Ssam int ldisc = 0, zero = 0, i; 9918549Ssam char **envnew; 1001043Sbill 10112687Ssam signal(SIGALRM, timedout); 10212687Ssam alarm(timeout); 1031043Sbill signal(SIGQUIT, SIG_IGN); 1041043Sbill signal(SIGINT, SIG_IGN); 10512687Ssam setpriority(PRIO_PROCESS, 0, 0); 10612678Ssam quota(Q_SETUID, 0, 0, 0); 10712687Ssam /* 10818549Ssam * -p is used by getty to tell login not to destroy the environment 10912687Ssam * -r is used by rlogind to cause the autologin protocol; 11012687Ssam * -h is used by other servers to pass the name of the 11112687Ssam * remote host to login so that it may be placed in utmp and wtmp 11212687Ssam */ 11312687Ssam if (argc > 1) { 11412687Ssam if (strcmp(argv[1], "-r") == 0) { 11512687Ssam rflag = doremotelogin(argv[2]); 11612687Ssam SCPYN(utmp.ut_host, argv[2]); 11712687Ssam argc = 0; 1186197Sroot } 11912687Ssam if (strcmp(argv[1], "-h") == 0 && getuid() == 0) { 12018549Ssam hflag = 1; 12112687Ssam SCPYN(utmp.ut_host, argv[2]); 12212687Ssam argc = 0; 1236197Sroot } 12418549Ssam if (strcmp(argv[1], "-p") == 0) { 12518549Ssam argc--; 12618549Ssam argv++; 12718549Ssam pflag = 1; 12818549Ssam } 1296005Swnj } 13013074Ssam ioctl(0, TIOCLSET, &zero); 1311547Sbill ioctl(0, TIOCNXCL, 0); 1326329Swnj ioctl(0, FIONBIO, &zero); 1336329Swnj ioctl(0, FIOASYNC, &zero); 13413074Ssam ioctl(0, TIOCGETP, &ttyb); 13512687Ssam /* 13612687Ssam * If talking to an rlogin process, 13712687Ssam * propagate the terminal type and 13812687Ssam * baud rate across the network. 13912687Ssam */ 14012687Ssam if (rflag) 14112687Ssam doremoteterm(term, &ttyb); 14213074Ssam ioctl(0, TIOCSLTC, <c); 14313074Ssam ioctl(0, TIOCSETC, &tc); 14413074Ssam ioctl(0, TIOCSETP, &ttyb); 14512687Ssam for (t = getdtablesize(); t > 3; t--) 1461043Sbill close(t); 1471043Sbill ttyn = ttyname(0); 14816453Sroot if (ttyn == (char *)0) 1491043Sbill ttyn = "/dev/tty??"; 15016453Sroot tty = rindex(ttyn, '/'); 15116453Sroot if (tty == NULL) 15216453Sroot tty = ttyn; 15316453Sroot else 15416453Sroot tty++; 15518549Ssam openlog("login", LOG_ODELAY, 0); 15616453Sroot t = 0; 1572822Swnj do { 1582822Swnj ldisc = 0; 1592822Swnj ioctl(0, TIOCSETD, &ldisc); 1602822Swnj invalid = FALSE; 1612822Swnj SCPYN(utmp.ut_name, ""); 16212687Ssam /* 16312687Ssam * Name specified, take it. 16412687Ssam */ 16512687Ssam if (argc > 1) { 1662822Swnj SCPYN(utmp.ut_name, argv[1]); 1672822Swnj argc = 0; 1681043Sbill } 16912687Ssam /* 17012687Ssam * If remote login take given name, 17112687Ssam * otherwise prompt user for something. 17212687Ssam */ 1736329Swnj if (rflag) { 1749867Ssam SCPYN(utmp.ut_name, lusername); 17512687Ssam /* autologin failed, prompt for passwd */ 1766329Swnj if (rflag == -1) 1776329Swnj rflag = 0; 17813470Ssam } else 17912687Ssam getloginname(&utmp); 1802822Swnj if (!strcmp(pwd->pw_shell, "/bin/csh")) { 1812822Swnj ldisc = NTTYDISC; 1822822Swnj ioctl(0, TIOCSETD, &ldisc); 1832822Swnj } 18412687Ssam /* 18512687Ssam * If no remote login authentication and 18612687Ssam * a password exists for this user, prompt 18712687Ssam * for one and verify it. 18812687Ssam */ 18912687Ssam if (!rflag && *pwd->pw_passwd != '\0') { 19012687Ssam char *pp; 19112687Ssam 19212687Ssam setpriority(PRIO_PROCESS, 0, -4); 19312687Ssam pp = getpass("Password:"); 19412687Ssam namep = crypt(pp, pwd->pw_passwd); 19512687Ssam setpriority(PRIO_PROCESS, 0, 0); 19612687Ssam if (strcmp(namep, pwd->pw_passwd)) 19712687Ssam invalid = TRUE; 1982822Swnj } 19912687Ssam /* 20012687Ssam * If user not super-user, check for logins disabled. 20112687Ssam */ 2022822Swnj if (pwd->pw_uid != 0 && (nlfd = fopen(nolog, "r")) > 0) { 2032822Swnj while ((c = getc(nlfd)) != EOF) 2042822Swnj putchar(c); 2052822Swnj fflush(stdout); 2062822Swnj sleep(5); 2072822Swnj exit(0); 2082822Swnj } 20912687Ssam /* 21012687Ssam * If valid so far and root is logging in, 21112687Ssam * see if root logins on this terminal are permitted. 21212687Ssam */ 21316453Sroot if (!invalid && pwd->pw_uid == 0 && !rootterm(tty)) { 21418549Ssam syslog(LOG_SECURITY, "ROOT LOGIN REFUSED %s", tty); 2152822Swnj invalid = TRUE; 2162822Swnj } 2172822Swnj if (invalid) { 2181043Sbill printf("Login incorrect\n"); 21916453Sroot if (++t >= 5) { 22018549Ssam syslog(LOG_SECURITY, 22116453Sroot "REPEATED LOGIN FAILURES %s, %s", 22216453Sroot tty, utmp.ut_name); 22316453Sroot ioctl(0, TIOCHPCL, (struct sgttyb *) 0); 22418549Ssam close(0), close(1), close(2); 22516453Sroot sleep(10); 22616453Sroot exit(1); 22716453Sroot } 2281043Sbill } 2292822Swnj if (*pwd->pw_shell == '\0') 2302822Swnj pwd->pw_shell = "/bin/sh"; 2312822Swnj if (chdir(pwd->pw_dir) < 0 && !invalid ) { 2322822Swnj if (chdir("/") < 0) { 2332822Swnj printf("No directory!\n"); 2342822Swnj invalid = TRUE; 2352822Swnj } else { 23612687Ssam printf("No directory! %s\n", 23712687Ssam "Logging in with home=/"); 2382822Swnj pwd->pw_dir = "/"; 2392822Swnj } 2401043Sbill } 24112687Ssam /* 24212687Ssam * Remote login invalid must have been because 24312687Ssam * of a restriction of some sort, no extra chances. 24412687Ssam */ 2456005Swnj if (rflag && invalid) 2466005Swnj exit(1); 2472822Swnj } while (invalid); 24812687Ssam /* committed to login turn off timeout */ 24912687Ssam alarm(0); 2501043Sbill 25112678Ssam if (quota(Q_SETUID, pwd->pw_uid, 0, 0) < 0) { 25212678Ssam if (errno == EUSERS) 25312678Ssam printf("%s.\n%s.\n", 25412678Ssam "Too many users logged on already", 25512678Ssam "Try again later"); 25612678Ssam else if (errno == EPROCLIM) 25712678Ssam printf("You have too many processes running.\n"); 25812678Ssam else 25917664Sserge perror("quota (Q_SETUID)"); 26012678Ssam sleep(5); 26112678Ssam exit(0); 26212678Ssam } 2631043Sbill time(&utmp.ut_time); 2641043Sbill t = ttyslot(); 26516453Sroot if (t > 0 && (f = open("/etc/utmp", O_WRONLY)) >= 0) { 2661043Sbill lseek(f, (long)(t*sizeof(utmp)), 0); 26716453Sroot SCPYN(utmp.ut_line, tty); 2681043Sbill write(f, (char *)&utmp, sizeof(utmp)); 2691043Sbill close(f); 2701043Sbill } 27116453Sroot if ((f = open("/usr/adm/wtmp", O_WRONLY|O_APPEND)) >= 0) { 2721043Sbill write(f, (char *)&utmp, sizeof(utmp)); 2731043Sbill close(f); 2741043Sbill } 27516453Sroot quietlog = access(qlog, F_OK) == 0; 27616453Sroot if ((f = open(lastlog, O_RDWR)) >= 0) { 2772822Swnj struct lastlog ll; 2782822Swnj 2792822Swnj lseek(f, (long)pwd->pw_uid * sizeof (struct lastlog), 0); 2802822Swnj if (read(f, (char *) &ll, sizeof ll) == sizeof ll && 28112687Ssam ll.ll_time != 0 && !quietlog) { 28212687Ssam printf("Last login: %.*s ", 28312687Ssam 24-5, (char *)ctime(&ll.ll_time)); 28412687Ssam if (*ll.ll_host != '\0') 28512687Ssam printf("from %.*s\n", 28612687Ssam sizeof (ll.ll_host), ll.ll_host); 28712687Ssam else 28812687Ssam printf("on %.*s\n", 28912687Ssam sizeof (ll.ll_line), ll.ll_line); 2902822Swnj } 2912822Swnj lseek(f, (long)pwd->pw_uid * sizeof (struct lastlog), 0); 2922822Swnj time(&ll.ll_time); 29316453Sroot SCPYN(ll.ll_line, tty); 29412687Ssam SCPYN(ll.ll_host, utmp.ut_host); 2952822Swnj write(f, (char *) &ll, sizeof ll); 2962822Swnj close(f); 2972822Swnj } 2981043Sbill chown(ttyn, pwd->pw_uid, pwd->pw_gid); 29918549Ssam if (!hflag) /* XXX */ 30018549Ssam ioctl(0, TIOCSWINSZ, &win); 3019867Ssam chmod(ttyn, 0622); 3021043Sbill setgid(pwd->pw_gid); 3036878Smckusick strncpy(name, utmp.ut_name, NMAX); 3046878Smckusick name[NMAX] = '\0'; 3059224Ssam initgroups(name, pwd->pw_gid); 30612678Ssam quota(Q_DOWARN, pwd->pw_uid, (dev_t)-1, 0); 3071043Sbill setuid(pwd->pw_uid); 30818549Ssam /* destroy environment unless user has asked to preserve it */ 30918549Ssam if (!pflag) 31018549Ssam environ = envinit; 31118549Ssam 31218549Ssam /* set up environment, this time without destruction */ 31318549Ssam /* copy the environment before setenving */ 31418549Ssam i = 0; 31518549Ssam while (environ[i] != NULL) 31618549Ssam i++; 31718549Ssam envnew = (char **) malloc(sizeof (char *) * (i + 1)); 31818549Ssam for (; i >= 0; i--) 31918549Ssam envnew[i] = environ[i]; 32018549Ssam environ = envnew; 32118549Ssam 32218549Ssam setenv("HOME=", pwd->pw_dir); 32318549Ssam setenv("SHELL=", pwd->pw_shell); 32418549Ssam if (term[0] == '\0') 32518549Ssam strncpy(term, stypeof(tty), sizeof(term)); 32618549Ssam setenv("TERM=", term); 32718549Ssam setenv("USER=", pwd->pw_name); 32818549Ssam setenv("PATH=", ":/usr/ucb:/bin:/usr/bin"); 32918549Ssam 3301043Sbill if ((namep = rindex(pwd->pw_shell, '/')) == NULL) 3311043Sbill namep = pwd->pw_shell; 3321043Sbill else 3331043Sbill namep++; 3341043Sbill strcat(minusnam, namep); 33516453Sroot if (tty[sizeof("tty")-1] == 'd') 33618549Ssam syslog(LOG_INFO, "DIALUP %s, %s", tty, pwd->pw_name); 33718549Ssam if (pwd->pw_uid == 0) 33818549Ssam syslog(LOG_SECURITY, "ROOT LOGIN %s", tty); 3396329Swnj if (!quietlog) { 34017664Sserge struct stat st; 34118549Ssam 3422822Swnj showmotd(); 3432822Swnj strcat(maildir, pwd->pw_name); 34417664Sserge if (stat(maildir, &st) == 0 && st.st_size != 0) 34517664Sserge printf("You have %smail.\n", 34618549Ssam (st.st_mtime > st.st_atime) ? "new " : ""); 3472822Swnj } 34812687Ssam signal(SIGALRM, SIG_DFL); 3491043Sbill signal(SIGQUIT, SIG_DFL); 3501043Sbill signal(SIGINT, SIG_DFL); 3513935Sroot signal(SIGTSTP, SIG_IGN); 3521043Sbill execlp(pwd->pw_shell, minusnam, 0); 3532822Swnj perror(pwd->pw_shell); 3541043Sbill printf("No shell\n"); 3551043Sbill exit(0); 3561043Sbill } 3571043Sbill 35812687Ssam getloginname(up) 35912687Ssam register struct utmp *up; 36012687Ssam { 36112687Ssam register char *namep; 36212712Ssam char c; 36312687Ssam 36412687Ssam while (up->ut_name[0] == '\0') { 36514897Sedward namep = up->ut_name; 36612712Ssam printf("login: "); 36712687Ssam while ((c = getchar()) != '\n') { 36812687Ssam if (c == ' ') 36912687Ssam c = '_'; 37012687Ssam if (c == EOF) 37112687Ssam exit(0); 37212687Ssam if (namep < up->ut_name+NMAX) 37312687Ssam *namep++ = c; 37412687Ssam } 37512687Ssam } 37614897Sedward strncpy(lusername, up->ut_name, NMAX); 37714897Sedward lusername[NMAX] = 0; 37814897Sedward if ((pwd = getpwnam(lusername)) == NULL) 37912687Ssam pwd = &nouser; 38012687Ssam } 38112687Ssam 38212687Ssam timedout() 38312687Ssam { 38412687Ssam 38512687Ssam printf("Login timed out after %d seconds\n", timeout); 38612687Ssam exit(0); 38712687Ssam } 38812687Ssam 3891043Sbill int stopmotd; 3901043Sbill catch() 3911043Sbill { 3926466Swnj 3931043Sbill signal(SIGINT, SIG_IGN); 3941043Sbill stopmotd++; 3951043Sbill } 3961043Sbill 3972822Swnj rootterm(tty) 3986466Swnj char *tty; 3992822Swnj { 40016453Sroot register struct ttyent *t; 4012822Swnj 40216453Sroot if ((t = getttynam(tty)) != NULL) { 40316453Sroot if (t->ty_status & TTY_SECURE) 40416453Sroot return (1); 4052822Swnj } 40616453Sroot return (0); 4072822Swnj } 4082822Swnj 4091043Sbill showmotd() 4101043Sbill { 4111043Sbill FILE *mf; 4121043Sbill register c; 4131043Sbill 4141043Sbill signal(SIGINT, catch); 41516453Sroot if ((mf = fopen("/etc/motd", "r")) != NULL) { 4162822Swnj while ((c = getc(mf)) != EOF && stopmotd == 0) 4171043Sbill putchar(c); 4181043Sbill fclose(mf); 4191043Sbill } 4201043Sbill signal(SIGINT, SIG_IGN); 4211043Sbill } 4221043Sbill 4232822Swnj #undef UNKNOWN 4241043Sbill #define UNKNOWN "su" 4251043Sbill 4261043Sbill char * 4271043Sbill stypeof(ttyid) 42812687Ssam char *ttyid; 4291043Sbill { 43016453Sroot register struct ttyent *t; 4311043Sbill 43216453Sroot if (ttyid == NULL || (t = getttynam(ttyid)) == NULL) 4331043Sbill return (UNKNOWN); 43416453Sroot return (t->ty_type); 4351043Sbill } 4366005Swnj 43712687Ssam doremotelogin(host) 43812687Ssam char *host; 43912687Ssam { 44012687Ssam FILE *hostf; 44112687Ssam int first = 1; 44212687Ssam 44312687Ssam getstr(rusername, sizeof (rusername), "remuser"); 44412687Ssam getstr(lusername, sizeof (lusername), "locuser"); 44518549Ssam getstr(term, sizeof(term), "Terminal type"); 44613470Ssam if (getuid()) { 44713470Ssam pwd = &nouser; 44812687Ssam goto bad; 44913470Ssam } 45012687Ssam pwd = getpwnam(lusername); 45113470Ssam if (pwd == NULL) { 45213470Ssam pwd = &nouser; 45312687Ssam goto bad; 45413470Ssam } 45512687Ssam hostf = pwd->pw_uid ? fopen("/etc/hosts.equiv", "r") : 0; 45612687Ssam again: 45712687Ssam if (hostf) { 45812687Ssam char ahost[32]; 45912687Ssam 46012687Ssam while (fgets(ahost, sizeof (ahost), hostf)) { 46118549Ssam register char *p; 46212687Ssam char *user; 46312687Ssam 46418549Ssam p = ahost; 46518549Ssam while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') 46618549Ssam p++; 46718549Ssam if (*p == ' ' || *p == '\t') { 46818549Ssam *p++ = '\0'; 46918549Ssam while (*p == ' ' || *p == '\t') 47018549Ssam p++; 47118549Ssam user = p; 47218549Ssam while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') 47318549Ssam p++; 47418549Ssam } else 47518549Ssam user = p; 47618549Ssam *p = '\0'; 47712687Ssam if (!strcmp(host, ahost) && 47818549Ssam !strcmp(rusername, *user ? user : lusername)) { 47912687Ssam fclose(hostf); 48012687Ssam return (1); 48112687Ssam } 48212687Ssam } 48312687Ssam fclose(hostf); 48412687Ssam } 48512687Ssam if (first == 1) { 48612687Ssam char *rhosts = ".rhosts"; 48712687Ssam struct stat sbuf; 48812687Ssam 48912687Ssam first = 0; 49012687Ssam if (chdir(pwd->pw_dir) < 0) 49112687Ssam goto again; 49212687Ssam if (lstat(rhosts, &sbuf) < 0) 49312687Ssam goto again; 49412687Ssam if ((sbuf.st_mode & S_IFMT) == S_IFLNK) { 49512687Ssam printf("login: .rhosts is a soft link.\r\n"); 49612687Ssam goto bad; 49712687Ssam } 49812687Ssam hostf = fopen(rhosts, "r"); 49912687Ssam fstat(fileno(hostf), &sbuf); 50012687Ssam if (sbuf.st_uid && sbuf.st_uid != pwd->pw_uid) { 50112687Ssam printf("login: Bad .rhosts ownership.\r\n"); 50212687Ssam fclose(hostf); 50312687Ssam goto bad; 50412687Ssam } 50512687Ssam goto again; 50612687Ssam } 50712687Ssam bad: 50812687Ssam return (-1); 50912687Ssam } 51012687Ssam 5116005Swnj getstr(buf, cnt, err) 5126005Swnj char *buf; 5136005Swnj int cnt; 5146005Swnj char *err; 5156005Swnj { 5166005Swnj char c; 5176005Swnj 5186005Swnj do { 5196005Swnj if (read(0, &c, 1) != 1) 5206005Swnj exit(1); 5216005Swnj if (--cnt < 0) { 5226005Swnj printf("%s too long\r\n", err); 5236005Swnj exit(1); 5246005Swnj } 5256005Swnj *buf++ = c; 5266005Swnj } while (c != 0); 5276005Swnj } 5286329Swnj 52912687Ssam char *speeds[] = 53012687Ssam { "0", "50", "75", "110", "134", "150", "200", "300", 53112687Ssam "600", "1200", "1800", "2400", "4800", "9600", "19200", "38400" }; 53212687Ssam #define NSPEEDS (sizeof (speeds) / sizeof (speeds[0])) 53312687Ssam 53412687Ssam doremoteterm(term, tp) 53512687Ssam char *term; 53612687Ssam struct sgttyb *tp; 53712687Ssam { 53818549Ssam register char *cp = index(term, '/'), **cpp; 53918549Ssam char *speed; 54018549Ssam struct winsize ws; 54112687Ssam 54212687Ssam if (cp) { 54318549Ssam *cp++ = '\0'; 54418549Ssam speed = cp; 54518549Ssam cp = index(speed, '/'); 54618549Ssam if (cp) 54718549Ssam *cp++ = '\0'; 54818549Ssam for (cpp = speeds; cpp < &speeds[NSPEEDS]; cpp++) 54918549Ssam if (strcmp(*cpp, speed) == 0) { 55018549Ssam tp->sg_ispeed = tp->sg_ospeed = cpp-speeds; 55112687Ssam break; 55212687Ssam } 55318549Ssam ws.ws_row = ws.ws_col = -1; 55418549Ssam ws.ws_xpixel = ws.ws_ypixel = -1; 55518549Ssam if (cp) { 55618550Skarels ws.ws_row = atoi(cp); 55718549Ssam cp = index(cp, ','); 55818549Ssam if (cp == 0) 55918549Ssam goto done; 56018549Ssam ws.ws_col = atoi(++cp); 56118549Ssam cp = index(cp, ','); 56218549Ssam if (cp == 0) 56318549Ssam goto done; 56418549Ssam ws.ws_xpixel = atoi(++cp); 56518549Ssam cp = index(cp, ','); 56618549Ssam if (cp == 0) 56718549Ssam goto done; 56818549Ssam ws.ws_ypixel = atoi(++cp); 56918549Ssam } 57018549Ssam done: 57118549Ssam if (ws.ws_row != -1 && ws.ws_col != -1 && 57218549Ssam ws.ws_xpixel != -1 && ws.ws_ypixel != -1) 57318549Ssam win = ws; 57412687Ssam } 57512687Ssam tp->sg_flags = ECHO|CRMOD|ANYP|XTABS; 57612687Ssam } 57718549Ssam 57818549Ssam /* 57918549Ssam * Set the value of var to be arg in the Unix 4.2 BSD environment env. 58018549Ssam * Var should end with '='. 58118549Ssam * (bindings are of the form "var=value") 58218549Ssam * This procedure assumes the memory for the first level of environ 58318549Ssam * was allocated using malloc. 58418549Ssam */ 58518549Ssam setenv(var, value) 58618549Ssam char *var, *value; 58718549Ssam { 58818549Ssam extern char **environ; 58918549Ssam int index = 0; 59018549Ssam int varlen = strlen(var); 59118549Ssam int vallen = strlen(value); 59218549Ssam 59318549Ssam for (index = 0; environ[index] != NULL; index++) { 59418549Ssam if (strncmp(environ[index], var, varlen) == 0) { 59518549Ssam /* found it */ 59618549Ssam environ[index] = malloc(varlen + vallen + 1); 59718549Ssam strcpy(environ[index], var); 59818549Ssam strcat(environ[index], value); 59918549Ssam return; 60018549Ssam } 60118549Ssam } 60218549Ssam environ = (char **) realloc(environ, sizeof (char *) * (index + 2)); 60318549Ssam if (environ == NULL) { 60418549Ssam fprintf(stderr, "login: malloc out of memory\n"); 60518549Ssam exit(1); 60618549Ssam } 60718549Ssam environ[index] = malloc(varlen + vallen + 1); 60818549Ssam strcpy(environ[index], var); 60918549Ssam strcat(environ[index], value); 61018549Ssam environ[++index] = NULL; 61118549Ssam } 612