int main(int argc, char *argv[]) { extern char **environ; int first_sleep = 1, first_time = 1; struct rlimit limit; int rval; signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN); openlog("getty", LOG_ODELAY|LOG_CONS|LOG_PID, LOG_AUTH); gethostname(hostname, sizeof(hostname) - 1); hostname[sizeof(hostname) - 1] = '\0'; if (hostname[0] == '\0') strcpy(hostname, "Amnesiac"); /* * Limit running time to deal with broken or dead lines. */ (void)signal(SIGXCPU, timeoverrun); limit.rlim_max = RLIM_INFINITY; limit.rlim_cur = GETTY_TIMEOUT; (void)setrlimit(RLIMIT_CPU, &limit); gettable("default", defent); gendefaults(); tname = "default"; if (argc > 1) tname = argv[1]; /* * The following is a work around for vhangup interactions * which cause great problems getting window systems started. * If the tty line is "-", we do the old style getty presuming * that the file descriptors are already set up for us. * J. Gettys - MIT Project Athena. */ if (argc <= 2 || strcmp(argv[2], "-") == 0) strcpy(ttyn, ttyname(STDIN_FILENO)); else { strcpy(ttyn, dev); strncat(ttyn, argv[2], sizeof(ttyn)-sizeof(dev)); if (strcmp(argv[0], "+") != 0) { chown(ttyn, 0, 0); chmod(ttyn, 0600); revoke(ttyn); /* * Do the first scan through gettytab. * Terminal mode parameters will be wrong until * defttymode() called, but they're irrelevant for * the initial setup of the terminal device. */ dogettytab(); /* * Init or answer modem sequence has been specified. */ if (IC || AC) { if (!opentty(ttyn, O_RDWR|O_NONBLOCK)) exit(1); defttymode(); setttymode(1); } if (IC) { if (getty_chat(IC, CT, DC) > 0) { syslog(LOG_ERR, "modem init problem on %s", ttyn); (void)tcsetattr(STDIN_FILENO, TCSANOW, &tmode); exit(1); } } if (AC) { int i, rfds; struct timeval to; rfds = 1 << 0; /* FD_SET */ to.tv_sec = RT; to.tv_usec = 0; i = select(32, (fd_set*)&rfds, (fd_set*)NULL, (fd_set*)NULL, RT ? &to : NULL); if (i < 0) { syslog(LOG_ERR, "select %s: %m", ttyn); } else if (i == 0) { syslog(LOG_NOTICE, "recycle tty %s", ttyn); (void)tcsetattr(STDIN_FILENO, TCSANOW, &tmode); exit(0); /* recycle for init */ } i = getty_chat(AC, CT, DC); if (i > 0) { syslog(LOG_ERR, "modem answer problem on %s", ttyn); (void)tcsetattr(STDIN_FILENO, TCSANOW, &tmode); exit(1); } } else { /* maybe blocking open */ if (!opentty(ttyn, O_RDWR | (NC ? O_NONBLOCK : 0 ))) exit(1); } } } defttymode(); for (;;) { /* * if a delay was specified then sleep for that * number of seconds before writing the initial prompt */ if (first_sleep && DE) { sleep(DE); /* remove any noise */ (void)tcflush(STDIN_FILENO, TCIOFLUSH); } first_sleep = 0; setttymode(0); if (AB) { tname = autobaud(); dogettytab(); continue; } if (PS) { tname = portselector(); dogettytab(); continue; } if (CL && *CL) putpad(CL); edithost(HE); /* if this is the first time through this, and an issue file has been given, then send it */ if (first_time && IF) { int fd; if ((fd = open(IF, O_RDONLY)) != -1) { char * cp; while ((cp = getline(fd)) != NULL) { putf(cp); } close(fd); } } first_time = 0; if (IM && *IM && !(PL && PP)) putf(IM); if (setjmp(timeout)) { cfsetispeed(&tmode, B0); cfsetospeed(&tmode, B0); (void)tcsetattr(STDIN_FILENO, TCSANOW, &tmode); exit(1); } if (TO) { signal(SIGALRM, dingdong); alarm(TO); } rval = 0; if (AL) { const char *p = AL; char *q = name; while (*p && q < &name[sizeof name - 1]) { if (isupper(*p)) upper = 1; else if (islower(*p)) lower = 1; else if (isdigit(*p)) digit = 1; *q++ = *p++; } } else if (!(PL && PP)) rval = getname(); if (rval == 2 || (PL && PP)) { oflush(); alarm(0); limit.rlim_max = RLIM_INFINITY; limit.rlim_cur = RLIM_INFINITY; (void)setrlimit(RLIMIT_CPU, &limit); execle(PP, "ppplogin", ttyn, (char *) 0, env); syslog(LOG_ERR, "%s: %m", PP); exit(1); } else if (rval || AL) { int i; oflush(); alarm(0); signal(SIGALRM, SIG_DFL); if (name[0] == '\0') continue; if (name[0] == '-') { puts("user names may not start with '-'."); continue; } if (!(upper || lower || digit)) { if (AL) { syslog(LOG_ERR, "invalid auto-login name: %s", AL); exit(1); } else continue; } set_flags(2); if (crmod) { tmode.c_iflag |= ICRNL; tmode.c_oflag |= ONLCR; } #if REALLY_OLD_TTYS if (upper || UC) tmode.sg_flags |= LCASE; if (lower || LC) tmode.sg_flags &= ~LCASE; #endif if (tcsetattr(STDIN_FILENO, TCSANOW, &tmode) < 0) { syslog(LOG_ERR, "tcsetattr %s: %m", ttyn); exit(1); } signal(SIGINT, SIG_DFL); for (i = 0; environ[i] != (char *)0; i++) env[i] = environ[i]; makeenv(&env[i]); limit.rlim_max = RLIM_INFINITY; limit.rlim_cur = RLIM_INFINITY; (void)setrlimit(RLIMIT_CPU, &limit); execle(LO, "login", AL ? "-fp" : "-p", name, (char *) 0, env); syslog(LOG_ERR, "%s: %m", LO); exit(1); } alarm(0); signal(SIGALRM, SIG_DFL); signal(SIGINT, SIG_IGN); if (NX && *NX) { tname = NX; dogettytab(); } } }
int main(int argc, char *argv[]) { extern char **environ; char *tname; int repcnt = 0, failopenlogged = 0; struct rlimit limit; int rval; signal(SIGINT, SIG_IGN); /* signal(SIGQUIT, SIG_DFL); */ openlog("getty", LOG_ODELAY|LOG_CONS|LOG_PID, LOG_AUTH); gethostname(hostname, sizeof(hostname)); if (hostname[0] == '\0') strlcpy(hostname, "Amnesiac", sizeof hostname); uname(&kerninfo); /* * Limit running time to deal with broken or dead lines. */ (void)signal(SIGXCPU, timeoverrun); limit.rlim_max = RLIM_INFINITY; limit.rlim_cur = GETTY_TIMEOUT; (void)setrlimit(RLIMIT_CPU, &limit); /* * The following is a work around for vhangup interactions * which cause great problems getting window systems started. * If the tty line is "-", we do the old style getty presuming * that the file descriptors are already set up for us. * J. Gettys - MIT Project Athena. */ if (argc <= 2 || strcmp(argv[2], "-") == 0) { snprintf(ttyn, sizeof ttyn, "%s", ttyname(0)); } else { int i; snprintf(ttyn, sizeof ttyn, "%s%s", dev, argv[2]); if (strcmp(argv[0], "+") != 0) { chown(ttyn, 0, 0); chmod(ttyn, 0600); revoke(ttyn); /* * Delay the open so DTR stays down long enough to be detected. */ sleep(2); while ((i = open(ttyn, O_RDWR)) == -1) { if ((repcnt % 10 == 0) && (errno != ENXIO || !failopenlogged)) { syslog(LOG_ERR, "%s: %m", ttyn); closelog(); failopenlogged = 1; } repcnt++; sleep(60); } login_tty(i); } } /* Start with default tty settings */ if (tcgetattr(0, &tmode) < 0) { syslog(LOG_ERR, "%s: %m", ttyn); exit(1); } omode = tmode; gettable("default", defent); gendefaults(); tname = "default"; if (argc > 1) tname = argv[1]; for (;;) { int off; gettable(tname, tabent); if (OPset || EPset || APset) APset++, OPset++, EPset++; setdefaults(); off = 0; (void)tcflush(0, TCIOFLUSH); /* clear out the crap */ ioctl(0, FIONBIO, &off); /* turn off non-blocking mode */ ioctl(0, FIOASYNC, &off); /* ditto for async mode */ if (IS) cfsetispeed(&tmode, IS); else if (SP) cfsetispeed(&tmode, SP); if (OS) cfsetospeed(&tmode, OS); else if (SP) cfsetospeed(&tmode, SP); setflags(0); setchars(); if (tcsetattr(0, TCSANOW, &tmode) < 0) { syslog(LOG_ERR, "%s: %m", ttyn); exit(1); } if (AB) { tname = autobaud(); continue; } if (PS) { tname = portselector(); continue; } if (CL && *CL) putpad(CL); edithost(HE); if (IM && *IM) putf(IM); if (TO) { signal(SIGALRM, dingdong); alarm(TO); } if ((rval = getname()) == 2) { oflush(); alarm(0); signal(SIGALRM, SIG_DFL); execle(PP, "ppplogin", ttyn, (char *) 0, env); syslog(LOG_ERR, "%s: %m", PP); exit(1); } else if (rval) { int i; oflush(); alarm(0); signal(SIGALRM, SIG_DFL); if (name[0] == '-') { xputs("user names may not start with '-'."); continue; } if (!(upper || lower || digit)) continue; setflags(2); if (crmod) { tmode.c_iflag |= ICRNL; tmode.c_oflag |= ONLCR; } if (upper || UC) { tmode.c_iflag |= IUCLC; tmode.c_oflag |= OLCUC; tmode.c_lflag |= XCASE; } if (lower || LC) { tmode.c_iflag &= ~IUCLC; tmode.c_oflag &= ~OLCUC; tmode.c_lflag &= ~XCASE; } if (tcsetattr(0, TCSANOW, &tmode) < 0) { syslog(LOG_ERR, "%s: %m", ttyn); exit(1); } signal(SIGINT, SIG_DFL); for (i = 0; environ[i] != (char *)0; i++) env[i] = environ[i]; makeenv(&env[i]); limit.rlim_max = RLIM_INFINITY; limit.rlim_cur = RLIM_INFINITY; (void)setrlimit(RLIMIT_CPU, &limit); execle(LO, "login", "-p", "--", name, (char *)0, env); syslog(LOG_ERR, "%s: %m", LO); exit(1); } alarm(0); signal(SIGALRM, SIG_DFL); signal(SIGINT, SIG_IGN); if (NX && *NX) tname = NX; } }