📄 agetty.c
字号:
case 's': (void) printf ("%s", uts.sysname); break; case 'n': (void) printf ("%s", uts.nodename); break; case 'r': (void) printf ("%s", uts.release); break; case 'v': (void) printf ("%s", uts.version); break; case 'm': (void) printf ("%s", uts.machine); break; case 'o': { char domainname[256];#ifdef HAVE_getdomainname getdomainname(domainname, sizeof(domainname));#else strcpy(domainname, "unknown_domain");#endif domainname[sizeof(domainname)-1] = '\0'; printf ("%s", domainname); } break; case 'd': case 't': { char *weekday[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; char *month[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; time_t now; struct tm *tm; (void) time (&now); tm = localtime(&now); if (c == 'd') (void) printf ("%s %s %d %d", weekday[tm->tm_wday], month[tm->tm_mon], tm->tm_mday, tm->tm_year < 70 ? tm->tm_year + 2000 : tm->tm_year + 1900); else (void) printf ("%02d:%02d:%02d", tm->tm_hour, tm->tm_min, tm->tm_sec); break; } case 'l': (void) printf ("%s", op->tty); break; case 'b': { int i; for (i = 0; speedtab[i].speed; i++) { if (speedtab[i].code == (tp->c_cflag & CBAUD)) { printf("%ld", speedtab[i].speed); break; } } break; } case 'u': case 'U': { int users = 0; struct utmp *ut; setutent(); while ((ut = getutent())) if (ut->ut_type == USER_PROCESS) users++; endutent(); printf ("%d ", users); if (c == 'U') printf ((users == 1) ? _("user") : _("users")); break; } default: (void) putchar(c); } } else (void) putchar(c); } fflush(stdout); tp->c_oflag = oflag; /* restore settings */ (void) ioctl(0, TCSETAW, tp); /* wait till output is gone */ (void) fclose(fd); }#endif#ifdef __linux__ { char hn[MAXHOSTNAMELEN+1]; (void) gethostname(hn, MAXHOSTNAMELEN); write(1, hn, strlen(hn)); }#endif (void) write(1, LOGIN, sizeof(LOGIN) - 1); /* always show login prompt */}/* next_speed - select next baud rate */voidnext_speed(tp, op) struct termio *tp; struct options *op;{ static int baud_index = FIRST_SPEED;/* current speed index */ baud_index = (baud_index + 1) % op->numspeed; tp->c_cflag &= ~CBAUD; tp->c_cflag |= op->speeds[baud_index]; (void) ioctl(0, TCSETA, tp);}/* get_logname - get user name, establish parity, speed, erase, kill, eol */char *get_logname(op, cp, tp) struct options *op; struct chardata *cp; struct termio *tp;{ static char logname[BUFSIZ]; char *bp; char c; /* input character, full eight bits */ char ascval; /* low 7 bits of input character */ int bits; /* # of "1" bits per character */ int mask; /* mask with 1 bit up */ static char *erase[] = { /* backspace-space-backspace */ "\010\040\010", /* space parity */ "\010\040\010", /* odd parity */ "\210\240\210", /* even parity */ "\210\240\210", /* no parity */ }; /* Initialize kill, erase, parity etc. (also after switching speeds). */ *cp = init_chardata; /* Flush pending input (esp. after parsing or switching the baud rate). */ (void) sleep(1); (void) ioctl(0, TCFLSH, TCIFLUSH); /* Prompt for and read a login name. */ for (*logname = 0; *logname == 0; /* void */ ) { /* Write issue file and prompt, with "parity" bit == 0. */ do_prompt(op, tp); /* Read name, watch for break, parity, erase, kill, end-of-line. */ for (bp = logname, cp->eol = 0; cp->eol == 0; /* void */ ) { /* Do not report trivial EINTR/EIO errors. */ if (read(0, &c, 1) < 1) { if (errno == EINTR || errno == EIO) exit(0); error(_("%s: read: %m"), op->tty); } /* Do BREAK handling elsewhere. */ if ((c == 0) && op->numspeed > 1) return (0); /* Do parity bit handling. */ if (c != (ascval = (c & 0177))) { /* "parity" bit on ? */ for (bits = 1, mask = 1; mask & 0177; mask <<= 1) if (mask & ascval) bits++; /* count "1" bits */ cp->parity |= ((bits & 1) ? 1 : 2); } /* Do erase, kill and end-of-line processing. */ switch (ascval) { case CR: case NL: *bp = 0; /* terminate logname */ cp->eol = ascval; /* set end-of-line char */ break; case BS: case DEL: case '#': cp->erase = ascval; /* set erase character */ if (bp > logname) { (void) write(1, erase[cp->parity], 3); bp--; } break; case CTL('U'): case '@': cp->kill = ascval; /* set kill character */ while (bp > logname) { (void) write(1, erase[cp->parity], 3); bp--; } break; case CTL('D'): exit(0); default: if (!isascii(ascval) || !isprint(ascval)) { /* ignore garbage characters */ ; } else if (bp - logname >= sizeof(logname) - 1) { error(_("%s: input overrun"), op->tty); } else { (void) write(1, &c, 1); /* echo the character */ *bp++ = ascval; /* and store it */ } break; } } } /* Handle names with upper case and no lower case. */ if ((cp->capslock = caps_lock(logname))) { for (bp = logname; *bp; bp++) if (isupper(*bp)) *bp = tolower(*bp); /* map name to lower case */ } return (logname);}/* termio_final - set the final tty mode bits */voidtermio_final(op, tp, cp) struct options *op; struct termio *tp; struct chardata *cp;{ /* General terminal-independent stuff. */ tp->c_iflag |= IXON | IXOFF; /* 2-way flow control */ tp->c_lflag |= ICANON | ISIG | ECHO | ECHOE | ECHOK| ECHOKE; /* no longer| ECHOCTL | ECHOPRT*/ tp->c_oflag |= OPOST; /* tp->c_cflag = 0; */ tp->c_cc[VINTR] = DEF_INTR; /* default interrupt */ tp->c_cc[VQUIT] = DEF_QUIT; /* default quit */ tp->c_cc[VEOF] = DEF_EOF; /* default EOF character */ tp->c_cc[VEOL] = DEF_EOL;#ifdef __linux__ tp->c_cc[VSWTC] = DEF_SWITCH; /* default switch character */#else tp->c_cc[VSWTCH] = DEF_SWITCH; /* default switch character */#endif /* Account for special characters seen in input. */ if (cp->eol == CR) { tp->c_iflag |= ICRNL; /* map CR in input to NL */ tp->c_oflag |= ONLCR; /* map NL in output to CR-NL */ } tp->c_cc[VERASE] = cp->erase; /* set erase character */ tp->c_cc[VKILL] = cp->kill; /* set kill character */ /* Account for the presence or absence of parity bits in input. */ switch (cp->parity) { case 0: /* space (always 0) parity */ break; case 1: /* odd parity */ tp->c_cflag |= PARODD; /* FALLTHROUGH */ case 2: /* even parity */ tp->c_cflag |= PARENB; tp->c_iflag |= INPCK | ISTRIP; /* FALLTHROUGH */ case (1 | 2): /* no parity bit */ tp->c_cflag &= ~CSIZE; tp->c_cflag |= CS7; break; } /* Account for upper case without lower case. */ if (cp->capslock) { tp->c_iflag |= IUCLC; tp->c_lflag |= XCASE; tp->c_oflag |= OLCUC; } /* Optionally enable hardware flow control */#ifdef CRTSCTS if (op->flags & F_RTSCTS) tp->c_cflag |= CRTSCTS;#endif /* Finally, make the new settings effective */ if (ioctl(0, TCSETA, tp) < 0) error("%s: ioctl: TCSETA: %m", op->tty);}/* caps_lock - string contains upper case without lower case */intcaps_lock(s) char *s;{ int capslock; for (capslock = 0; *s; s++) { if (islower(*s)) return (0); if (capslock == 0) capslock = isupper(*s); } return (capslock);}/* bcode - convert speed string to speed code; return 0 on failure */intbcode(s) char *s;{ struct Speedtab *sp; long speed = atol(s); for (sp = speedtab; sp->speed; sp++) if (sp->speed == speed) return (sp->code); return (0);}/* usage - explain */voidusage(){ fprintf(stderr, _("Usage: %s [-hiLmw] [-l login_program] [-t timeout] [-I initstring] [-H login_host] baud_rate,... line [termtype]\nor\t[-hiLmw] [-l login_program] [-t timeout] [-I initstring] [-H login_host] line baud_rate,... [termtype]\n"), progname); exit(1);}/* error - report errors to console or syslog; only understands %s and %m */#define str2cpy(b,s1,s2) strcat(strcpy(b,s1),s2)voiderror(const char *fmt, ...) { va_list ap;#ifndef USE_SYSLOG int fd;#endif char buf[BUFSIZ]; char *bp; /* * If the diagnostic is reported via syslog(3), the process name is * automatically prepended to the message. If we write directly to * /dev/console, we must prepend the process name ourselves. */#ifdef USE_SYSLOG buf[0] = '\0'; bp = buf;#else (void) str2cpy(buf, progname, ": "); bp = buf + strlen(buf);#endif /* * %s expansion is done by hand. On a System V Release 2 system without * shared libraries and without syslog(3), linking with the the stdio * library would make the program three times as big... * * %m expansion is done here as well. Too bad syslog(3) does not have a * vsprintf() like interface. */ va_start(ap, fmt); while (*fmt && bp < &buf[BUFSIZ-1]) { if (strncmp(fmt, "%s", 2) == 0) { xstrncpy(bp, va_arg(ap, char *), &buf[BUFSIZ-1] - bp); bp += strlen(bp); fmt += 2; } else if (strncmp(fmt, "%m", 2) == 0) { xstrncpy(bp, strerror(errno), &buf[BUFSIZ-1] - bp); bp += strlen(bp); fmt += 2; } else { *bp++ = *fmt++; } } *bp = 0; va_end(ap); /* * Write the diagnostic directly to /dev/console if we do not use the * syslog(3) facility. */#ifdef USE_SYSLOG (void) openlog(progname, LOG_PID, LOG_AUTHPRIV); (void) syslog(LOG_ERR, "%s", buf); closelog();#else /* Terminate with CR-LF since the console mode is unknown. */ (void) strcat(bp, "\r\n"); if ((fd = open("/dev/console", 1)) >= 0) { (void) write(fd, buf, strlen(buf)); (void) close(fd); }#endif (void) sleep((unsigned) 10); /* be kind to init(8) */ exit(1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -