big <utmp.h>-inspired netbsd switch
import/switch of: init, getty, reboot, halt, shutdown, wall, last changes: . change reboot() call to netbsd prototype and args . allows pristine <utmp.h> . use clean <sys/reboot.h> instead of <minix/reboot.h> . implement TIOCSCTTY for use by getty so getty can get controlling terminal from init's child(ren) . allow NULL envp for exec Change-Id: I5ca02cb4230857140c08794bbfeba7df982c58a3
This commit is contained in:
parent
fa06ff0ee3
commit
a06e2ab395
93 changed files with 8096 additions and 2465 deletions
|
@ -10,18 +10,18 @@ SUBDIR= add_route arp ash at backup btrace \
|
|||
dhrystone diff diskctl \
|
||||
eject factor fbdctl \
|
||||
find fix format fortune fsck.mfs \
|
||||
gcov-pull getty grep host \
|
||||
gcov-pull grep host \
|
||||
hostaddr ifconfig ifdef \
|
||||
intr ipcrm ipcs irdpd isoread last \
|
||||
intr ipcrm ipcs irdpd isoread \
|
||||
less loadkeys loadramdisk logger look lp \
|
||||
lpd lspci mail MAKEDEV \
|
||||
mined \
|
||||
mount mt netconf \
|
||||
nonamed patch \
|
||||
ping postinstall poweroff prep printroot \
|
||||
ping postinstall prep printroot \
|
||||
profile progressbar pr_routes ps pwdauth \
|
||||
ramdisk rarpd rawspeed rcp readclock \
|
||||
reboot remsync rget rlogin \
|
||||
remsync rget rlogin \
|
||||
rotate rsh rshd service setup shar \
|
||||
sleep slip spell sprofalyze sprofdiff srccrc \
|
||||
stty svclog svrctl swifi synctree sysenv \
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
PROG= getty
|
||||
BINDIR= /bin
|
||||
MAN=
|
||||
|
||||
.include <bsd.prog.mk>
|
|
@ -1,210 +0,0 @@
|
|||
/* getty - get tty speed Author: Fred van Kempen */
|
||||
|
||||
/*
|
||||
* GETTY - Initialize and serve a login-terminal for INIT.
|
||||
* Also, select the correct speed. The STTY() code
|
||||
* was taken from stty(1).c; which was written by
|
||||
* Andrew S. Tanenbaum.
|
||||
*
|
||||
* Usage: getty [speed]
|
||||
*
|
||||
* Version: 3.4 02/17/90
|
||||
*
|
||||
* Author: F. van Kempen, MicroWalt Corporation
|
||||
*
|
||||
* Modifications:
|
||||
* All the good stuff removed to get a minimal getty, because
|
||||
* many modems don't like all that fancy speed detection stuff.
|
||||
* 03/03/91 Kees J. Bot (kjb@cs.vu.nl)
|
||||
*
|
||||
* Uname(), termios. More nonsense removed. (The result has
|
||||
* only 10% of the original functionality, but a 10x chance of
|
||||
* working.)
|
||||
* 12/12/92 Kees J. Bot
|
||||
*
|
||||
* Customizable login banner.
|
||||
* 11/13/95 Kees J. Bot
|
||||
*
|
||||
* Suspend/resume signals removed.
|
||||
* 2001-04-04 Kees J. Bot
|
||||
*
|
||||
* Removed unused custom banner and returned speed option
|
||||
* functionality (by simply calling stty).
|
||||
* 2012-09-24 T. Veerman
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <stdio.h>
|
||||
|
||||
char LOGIN[] = "/usr/bin/login";
|
||||
char SHELL[] = "/bin/sh";
|
||||
|
||||
char *tty_name; /* name of the line */
|
||||
|
||||
/* Crude indication of a tty being physically secure: */
|
||||
#define securetty(dev) ((unsigned) ((dev) - 0x0400) < (unsigned) 8)
|
||||
|
||||
void std_out(const char *s)
|
||||
{
|
||||
write(1, s, strlen(s));
|
||||
}
|
||||
|
||||
/* Read one character from stdin.
|
||||
*/
|
||||
int readch(void)
|
||||
{
|
||||
int st;
|
||||
char ch1;
|
||||
|
||||
/* read character from TTY */
|
||||
st = read(0, &ch1, 1);
|
||||
if (st == 0) {
|
||||
std_out("\n");
|
||||
exit(0);
|
||||
}
|
||||
if (st < 0) {
|
||||
std_out("getty: ");
|
||||
std_out(tty_name);
|
||||
std_out(": read error\n");
|
||||
exit(1);
|
||||
}
|
||||
return(ch1 & 0xFF);
|
||||
}
|
||||
|
||||
|
||||
/* Handle the process of a GETTY.
|
||||
*/
|
||||
void do_getty(char *name, size_t len, char **args, const char *ttyname)
|
||||
{
|
||||
register char *np, *s, *s0;
|
||||
int ch;
|
||||
struct utsname utsname;
|
||||
char **banner, *t;
|
||||
static char *def_banner[] = { "%s/%p (%t)\n\n%n login: ", 0 };
|
||||
|
||||
/* Clean up tty name. */
|
||||
if((t = strrchr(ttyname, '/'))) ttyname = t + 1;
|
||||
|
||||
if (args[0] != NULL) {
|
||||
char cmd[5+6+1]; /* "stty " + "115200" + '\0' */
|
||||
int speed;
|
||||
speed = atoi(args[0]);
|
||||
snprintf(cmd, sizeof(cmd), "stty %d\n", speed);
|
||||
system(cmd);
|
||||
}
|
||||
|
||||
/* Display prompt. */
|
||||
ch = ' ';
|
||||
*name = '\0';
|
||||
while (ch != '\n') {
|
||||
/* Get data about this machine. */
|
||||
uname(&utsname);
|
||||
|
||||
/* Print the banner. */
|
||||
for (banner = def_banner; *banner != NULL; banner++) {
|
||||
std_out(banner == args ? "\n" : " ");
|
||||
s0 = *banner;
|
||||
for (s = *banner; *s != 0; s++) {
|
||||
if (*s == '\\') {
|
||||
write(1, s0, s-s0);
|
||||
s0 = s+2;
|
||||
switch (*++s) {
|
||||
case 'n': std_out("\n"); break;
|
||||
case 's': std_out(" "); break;
|
||||
case 't': std_out("\t"); break;
|
||||
case 0: goto leave;
|
||||
default: s0 = s;
|
||||
}
|
||||
} else
|
||||
if (*s == '%') {
|
||||
write(1, s0, s-s0);
|
||||
s0 = s+2;
|
||||
switch (*++s) {
|
||||
case 's': std_out(utsname.sysname); break;
|
||||
case 'n': std_out(utsname.nodename); break;
|
||||
case 'r': std_out(utsname.release); break;
|
||||
case 'v': std_out(utsname.version); break;
|
||||
case 'm': std_out(utsname.machine); break;
|
||||
case 'p': std_out(utsname.arch); break;
|
||||
case 't': std_out(ttyname); break;
|
||||
#if __minix_vmd
|
||||
case 'k': std_out(utsname.kernel); break;
|
||||
case 'h': std_out(utsname.hostname); break;
|
||||
case 'b': std_out(utsname.bus); break;
|
||||
#endif
|
||||
case 0: goto leave;
|
||||
default: s0 = s-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
leave:
|
||||
write(1, s0, s-s0);
|
||||
}
|
||||
|
||||
np = name;
|
||||
while ((ch = readch()) != '\n') {
|
||||
if (np < name + len) *np++ = ch;
|
||||
}
|
||||
*np = '\0';
|
||||
if (*name == '\0') ch = ' '; /* blank line typed! */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Execute the login(1) command with the current
|
||||
* username as its argument. It will reply to the
|
||||
* calling user by typing "Password: "...
|
||||
*/
|
||||
void do_login(char *name)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
execl(LOGIN, LOGIN, name, (char *) NULL);
|
||||
/* Failed to exec login. Impossible, but true. Try a shell, but only if
|
||||
* the terminal is more or less secure, because it will be a root shell.
|
||||
*/
|
||||
std_out("getty: can't exec ");
|
||||
std_out(LOGIN);
|
||||
std_out("\n");
|
||||
if (fstat(0, &st) == 0 && S_ISCHR(st.st_mode) && securetty(st.st_rdev)) {
|
||||
execl(SHELL, SHELL, (char *) NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char name[30];
|
||||
struct sigaction sa;
|
||||
|
||||
/* Don't let QUIT dump core. */
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_flags = 0;
|
||||
sa.sa_handler = exit;
|
||||
sigaction(SIGQUIT, &sa, NULL);
|
||||
|
||||
tty_name = ttyname(0);
|
||||
if (tty_name == NULL) {
|
||||
std_out("getty: tty name unknown\n");
|
||||
pause();
|
||||
return(1);
|
||||
}
|
||||
|
||||
chown(tty_name, 0, 0); /* set owner of TTY to root */
|
||||
chmod(tty_name, 0600); /* mode to max secure */
|
||||
|
||||
do_getty(name, sizeof(name), argv+1, tty_name); /* handle getty() */
|
||||
name[29] = '\0'; /* make sure the name fits! */
|
||||
|
||||
do_login(name); /* and call login(1) if OK */
|
||||
|
||||
return(1); /* never executed */
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
PROG= last
|
||||
MAN=
|
||||
|
||||
LINKS+= ${BINDIR}/last ${BINDIR}/uptime
|
||||
|
||||
.include <bsd.prog.mk>
|
|
@ -1,482 +0,0 @@
|
|||
/* last - display login history Author: Terrence W. Holm */
|
||||
|
||||
/* last- Display the user log-in history.
|
||||
* Last(1) searches backwards through the file of log-in
|
||||
* records (/usr/adm/wtmp), displaying the length of
|
||||
* log-in sessions as requested by the options:
|
||||
*
|
||||
* Usage: last [-r] [-count] [-f file] [name] [tty] ...
|
||||
*
|
||||
* -r Search backwards only until the last reboot
|
||||
* record.
|
||||
*
|
||||
* -count Only print out <count> records. Last(1) stops
|
||||
* when either -r or -count is satisfied, or at
|
||||
* the end of the file if neither is given.
|
||||
*
|
||||
* -f file Use "file" instead of "/usr/adm/wtmp".
|
||||
*
|
||||
* name Print records for the user "name".
|
||||
*
|
||||
* tty Print records for the terminal "tty". Actually,
|
||||
* a list of names may be given and all records
|
||||
* that match either the user or tty name are
|
||||
* printed. If no names are given then all records
|
||||
* are displayed.
|
||||
*
|
||||
* A sigquit (^\) causes last(1) to display how far it
|
||||
* has gone back in the log-in record file, it then
|
||||
* continues. This is used to check on the progress of
|
||||
* long running searches. A sigint will stop last(1).
|
||||
*
|
||||
* Author: Terrence W. Holm May 1988
|
||||
*
|
||||
* Revision:
|
||||
* Fred van Kempen, October 1989
|
||||
* -Adapted to MSS.
|
||||
* -Adapted to new utmp database.
|
||||
*
|
||||
* Fred van Kempen, December 1989
|
||||
* -Adapted to POSIX (MINIX 1.5)
|
||||
*
|
||||
* Fred van Kempen, January 1990
|
||||
* -Final edit for 1.5
|
||||
*
|
||||
* Philip Homburg, March 1992
|
||||
* -Include host in output
|
||||
*
|
||||
* Kees J. Bot, July 1997
|
||||
* -Approximate system uptime from last reboot record
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <utmp.h>
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <paths.h>
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
#define RLOGIN 1
|
||||
|
||||
#define BUFFER_SIZE 4096 /* Room for wtmp records */
|
||||
#define MAX_WTMP_COUNT ( BUFFER_SIZE / sizeof(struct utmp) )
|
||||
|
||||
#define min( a, b ) ( (a < b) ? a : b )
|
||||
#define max( a, b ) ( (a > b) ? a : b )
|
||||
|
||||
|
||||
typedef struct logout { /* A logout time record */
|
||||
char line[12]; /* The terminal name */
|
||||
long time; /* The logout time */
|
||||
struct logout *next; /* Next in linked list */
|
||||
} logout;
|
||||
|
||||
|
||||
static char *Version = "@(#) LAST 1.7 (10/24/92)";
|
||||
|
||||
|
||||
/* command-line option flags */
|
||||
char boot_limit = FALSE; /* stop on latest reboot */
|
||||
char count_limit = FALSE; /* stop after print_count */
|
||||
char tell_uptime = FALSE; /* tell uptime since last reboot */
|
||||
int print_count;
|
||||
char *prog; /* name of this program */
|
||||
int arg_count; /* used to select specific */
|
||||
char **args; /* users and ttys */
|
||||
|
||||
/* global variables */
|
||||
long boot_time = 0; /* Zero means no reboot yet */
|
||||
char *boot_down; /* "crash" or "down " flag */
|
||||
logout *first_link = NULL; /* List of logout times */
|
||||
int interrupt = FALSE; /* If sigint or sigquit occurs */
|
||||
|
||||
int main(int argc, char **argv);
|
||||
void Sigint(int sig);
|
||||
void Sigquit(int sig);
|
||||
void usage(void);
|
||||
void Process(struct utmp *wtmp);
|
||||
int Print_Record(struct utmp *wtmp);
|
||||
void Print_Duration(long from, long to);
|
||||
void Print_Uptime(void);
|
||||
void Record_Logout_Time(struct utmp *wtmp);
|
||||
|
||||
/* Sigint() and Sigquit() Flag occurrence of an interrupt. */
|
||||
void Sigint(sig)
|
||||
int sig;
|
||||
{
|
||||
interrupt = SIGINT;
|
||||
}
|
||||
|
||||
|
||||
void Sigquit(sig)
|
||||
int sig;
|
||||
{
|
||||
interrupt = SIGQUIT;
|
||||
}
|
||||
|
||||
|
||||
void usage()
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Usage: last [-r] [-u] [-count] [-f file] [name] [tty] ...\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
|
||||
/* A log-in record format file contains four types of records.
|
||||
*
|
||||
* [1] generated on a system reboot:
|
||||
*
|
||||
* line="~", name="reboot", host="", time=date()
|
||||
*
|
||||
*
|
||||
* [2] generated after a shutdown:
|
||||
*
|
||||
* line="~", name="shutdown", host="", time=date()
|
||||
*
|
||||
*
|
||||
* [3] generated on a successful login(1)
|
||||
*
|
||||
* line=ttyname(), name=cuserid(), host=, time=date()
|
||||
*
|
||||
*
|
||||
* [4] generated by init(8) on a logout
|
||||
*
|
||||
* line=ttyname(), name="", host="", time=date()
|
||||
*
|
||||
*
|
||||
* Note: This version of last(1) does not recognize the '|' and '}' time
|
||||
* change records. Last(1) pairs up line login's and logout's to
|
||||
* generate four types of output lines:
|
||||
*
|
||||
* [1] a system reboot or shutdown
|
||||
*
|
||||
* reboot ~ Mon May 16 14:16
|
||||
* shutdown ~ Mon May 16 14:15
|
||||
*
|
||||
* [2] a login with a matching logout
|
||||
*
|
||||
* edwin tty1 Thu May 26 20:05 - 20:32 (00:27)
|
||||
*
|
||||
* [3] a login followed by a reboot or shutdown
|
||||
*
|
||||
* root tty0 Mon May 16 13:57 - crash (00:19)
|
||||
* root tty1 Mon May 16 13:45 - down (00:30)
|
||||
*
|
||||
* [4] a login not followed by a logout or reboot
|
||||
*
|
||||
* terry tty0 Thu May 26 21:19 still logged in
|
||||
*/
|
||||
void Process(wtmp)
|
||||
struct utmp *wtmp;
|
||||
{
|
||||
logout *link;
|
||||
logout *next_link;
|
||||
char is_reboot;
|
||||
|
||||
/* suppress the job number on an "ftp" line */
|
||||
if (!strncmp(wtmp->ut_line, "ftp", (size_t)3)) strncpy(wtmp->ut_line, "ftp", (size_t)8);
|
||||
|
||||
if (!strcmp(wtmp->ut_line, "~")) {
|
||||
/* A reboot or shutdown record */
|
||||
if (boot_limit) exit(0);
|
||||
|
||||
if (Print_Record(wtmp)) putchar('\n');
|
||||
boot_time = wtmp->ut_time;
|
||||
|
||||
is_reboot = !strcmp(wtmp->ut_name, "reboot");
|
||||
if (is_reboot)
|
||||
boot_down = "crash";
|
||||
else
|
||||
boot_down = "down ";
|
||||
|
||||
if (tell_uptime) {
|
||||
if (!is_reboot) {
|
||||
fprintf(stderr,
|
||||
"%s: no reboot record added to wtmp file on system boot!\n",
|
||||
prog);
|
||||
exit(1);
|
||||
}
|
||||
Print_Uptime();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* remove any logout records */
|
||||
for (link = first_link; link != NULL; link = next_link) {
|
||||
next_link = link->next;
|
||||
free(link);
|
||||
}
|
||||
first_link = NULL;
|
||||
} else if (wtmp->ut_name[0] == '\0') {
|
||||
/* A logout record */
|
||||
Record_Logout_Time(wtmp);
|
||||
} else {
|
||||
/* A login record */
|
||||
for (link = first_link; link != NULL; link = link->next)
|
||||
if (!strncmp(link->line, wtmp->ut_line, (size_t)8)) {
|
||||
/* found corresponding logout record */
|
||||
if (Print_Record(wtmp)) {
|
||||
printf("- %.5s ", ctime(&link->time) + 11);
|
||||
Print_Duration(wtmp->ut_time, link->time);
|
||||
}
|
||||
/* record login time */
|
||||
link->time = wtmp->ut_time;
|
||||
return;
|
||||
}
|
||||
/* could not find a logout record for this login tty */
|
||||
if (Print_Record(wtmp))
|
||||
if (boot_time == 0) /* still on */
|
||||
printf(" still logged in\n");
|
||||
else { /* system crashed while on */
|
||||
printf("- %s ", boot_down);
|
||||
Print_Duration(wtmp->ut_time, boot_time);
|
||||
}
|
||||
Record_Logout_Time(wtmp); /* Needed in case of 2
|
||||
* consecutive logins */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Print_Record(wtmp) If the record was requested, then print out
|
||||
* the user name, terminal, host and time.
|
||||
*/
|
||||
int Print_Record(wtmp)
|
||||
struct utmp *wtmp;
|
||||
{
|
||||
int i;
|
||||
char print_flag = FALSE;
|
||||
|
||||
/* just interested in the uptime? */
|
||||
if (tell_uptime) return(FALSE);
|
||||
|
||||
/* check if we have already printed the requested number of records */
|
||||
if (count_limit && print_count == 0) exit(0);
|
||||
|
||||
for (i = 0; i < arg_count; ++i)
|
||||
if (!strncmp(args[i], wtmp->ut_name, sizeof(wtmp->ut_name)) ||
|
||||
!strncmp(args[i], wtmp->ut_line, sizeof(wtmp->ut_line)))
|
||||
print_flag = TRUE;
|
||||
|
||||
if (arg_count == 0 || print_flag) {
|
||||
#ifdef RLOGIN
|
||||
printf("%-8.8s %-8.8s %-16.16s %.16s ",
|
||||
wtmp->ut_name, wtmp->ut_line, wtmp->ut_host,
|
||||
ctime(&wtmp->ut_time));
|
||||
#else
|
||||
printf("%-8.8s %-8.8s %.16s ",
|
||||
wtmp->ut_name, wtmp->ut_line, ctime(&wtmp->ut_time));
|
||||
#endif
|
||||
--print_count;
|
||||
return(TRUE);
|
||||
}
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
|
||||
/* Print_Duration(from, to) Calculate and print the days and hh:mm between
|
||||
* the log-in and the log-out.
|
||||
*/
|
||||
void Print_Duration(from, to)
|
||||
long from;
|
||||
long to;
|
||||
{
|
||||
long delta, days, hours, minutes;
|
||||
|
||||
delta = max(to - from, 0);
|
||||
days = delta / (24L * 60L * 60L);
|
||||
delta = delta % (24L * 60L * 60L);
|
||||
hours = delta / (60L * 60L);
|
||||
delta = delta % (60L * 60L);
|
||||
minutes = delta / 60L;
|
||||
|
||||
if (days > 0)
|
||||
printf("(%ld+", days);
|
||||
else
|
||||
printf(" (");
|
||||
|
||||
printf("%02ld:%02ld)\n", hours, minutes);
|
||||
}
|
||||
|
||||
|
||||
/* Print_Uptime() Calculate and print the "uptime" between the last recorded
|
||||
* boot and the current time.
|
||||
*/
|
||||
void Print_Uptime()
|
||||
{
|
||||
#define NLOADS 3
|
||||
int nloads;
|
||||
double loads[NLOADS];
|
||||
char *utmp_file = _PATH_UTMP;
|
||||
unsigned nusers;
|
||||
struct utmp ut;
|
||||
FILE *uf;
|
||||
time_t now;
|
||||
struct tm *tm;
|
||||
unsigned long up;
|
||||
|
||||
/* Count the number of active users in the utmp file. */
|
||||
if ((uf = fopen(utmp_file, "r")) == NULL) {
|
||||
fprintf(stderr, "%s: %s: %s\n", prog, utmp_file, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
nusers = 0;
|
||||
while (fread(&ut, sizeof(ut), 1, uf) == 1) {
|
||||
#ifdef USER_PROCESS
|
||||
if (ut.ut_type == USER_PROCESS) nusers++;
|
||||
#else
|
||||
if (ut.ut_name[0] != 0 && ut.ut_line[0] != 0) nusers++;
|
||||
#endif
|
||||
}
|
||||
fclose(uf);
|
||||
|
||||
/* Current time. */
|
||||
now = time((time_t *) NULL);
|
||||
tm = localtime(&now);
|
||||
|
||||
/* Uptime. */
|
||||
up = now - boot_time;
|
||||
|
||||
printf(" %d:%02d up", tm->tm_hour, tm->tm_min);
|
||||
if (up >= 24 * 3600L) {
|
||||
unsigned long days = up / (24 * 3600L);
|
||||
printf(" %lu day%s,", days, days == 1 ? "" : "s");
|
||||
}
|
||||
printf(" %lu:%02lu,", (up % (24 * 3600L)) / 3600, (up % 3600) / 60);
|
||||
printf(" %u user%s", nusers, nusers == 1 ? "" : "s");
|
||||
if((nloads = getloadavg(loads, NLOADS)) > 0) {
|
||||
int i;
|
||||
printf(", load averages:");
|
||||
for(i = 0; i < nloads; i++)
|
||||
printf("%s %.2f", (i > 0) ? "," : "", loads[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
/* Record_Logout_Time(wtmp) A linked list of "last logout time" is kept.
|
||||
* Each element of the list is for one terminal.
|
||||
*/
|
||||
void Record_Logout_Time(wtmp)
|
||||
struct utmp *wtmp;
|
||||
{
|
||||
logout *link;
|
||||
|
||||
/* see if the terminal is already in the list */
|
||||
for (link = first_link; link != NULL; link = link->next)
|
||||
if (!strncmp(link->line, wtmp->ut_line, (size_t)8)) {
|
||||
link->time = wtmp->ut_time;
|
||||
return;
|
||||
}
|
||||
/* allocate a new logout record, for a tty not previously encountered */
|
||||
link = (logout *) malloc(sizeof(logout));
|
||||
if (link == NULL) {
|
||||
fprintf(stderr, "%s: malloc failure\n", prog);
|
||||
exit(1);
|
||||
}
|
||||
strncpy(link->line, wtmp->ut_line, (size_t)8);
|
||||
link->time = wtmp->ut_time;
|
||||
link->next = first_link;
|
||||
|
||||
first_link = link;
|
||||
}
|
||||
|
||||
|
||||
int main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
char *wtmp_file = _PATH_WTMP;
|
||||
FILE *f;
|
||||
long size; /* Number of wtmp records in the file */
|
||||
int wtmp_count; /* How many to read into wtmp_buffer */
|
||||
struct utmp wtmp_buffer[MAX_WTMP_COUNT];
|
||||
|
||||
if ((prog = strrchr(argv[0], '/')) == NULL) prog = argv[0]; else prog++;
|
||||
|
||||
--argc;
|
||||
++argv;
|
||||
|
||||
while (argc > 0 && *argv[0] == '-') {
|
||||
if (!strcmp(argv[0], "-r"))
|
||||
boot_limit = TRUE;
|
||||
else
|
||||
if (!strcmp(argv[0], "-u"))
|
||||
tell_uptime = TRUE;
|
||||
else if (argc > 1 && !strcmp(argv[0], "-f")) {
|
||||
wtmp_file = argv[1];
|
||||
--argc;
|
||||
++argv;
|
||||
} else if ((print_count = atoi(argv[0] + 1)) > 0)
|
||||
count_limit = TRUE;
|
||||
else
|
||||
usage();
|
||||
|
||||
--argc;
|
||||
++argv;
|
||||
}
|
||||
|
||||
arg_count = argc;
|
||||
args = argv;
|
||||
|
||||
if (!strcmp(prog, "uptime")) tell_uptime = TRUE;
|
||||
|
||||
if ((f = fopen(wtmp_file, "r")) == NULL) {
|
||||
perror(wtmp_file);
|
||||
exit(1);
|
||||
}
|
||||
if (fseek(f, 0L, 2) != 0 || (size = ftell(f)) % sizeof(struct utmp) != 0) {
|
||||
fprintf(stderr, "%s: invalid wtmp file\n", prog);
|
||||
exit(1);
|
||||
}
|
||||
if (signal(SIGINT, SIG_IGN) != SIG_IGN) {
|
||||
signal(SIGINT, Sigint);
|
||||
signal(SIGQUIT, Sigquit);
|
||||
}
|
||||
size /= sizeof(struct utmp); /* Number of records in wtmp */
|
||||
|
||||
if (size == 0) wtmp_buffer[0].ut_time = time((time_t *)0);
|
||||
|
||||
while (size > 0) {
|
||||
wtmp_count = (int) min(size, MAX_WTMP_COUNT);
|
||||
size -= (long) wtmp_count;
|
||||
|
||||
fseek(f, size * sizeof(struct utmp), 0);
|
||||
|
||||
|
||||
if (fread(&wtmp_buffer[0], sizeof(struct utmp), (size_t)wtmp_count, f)
|
||||
!= wtmp_count) {
|
||||
fprintf(stderr, "%s: read error on wtmp file\n", prog);
|
||||
exit(1);
|
||||
}
|
||||
while (--wtmp_count >= 0) {
|
||||
Process(&wtmp_buffer[wtmp_count]);
|
||||
if (interrupt) {
|
||||
printf("\ninterrupted %.16s \n",
|
||||
ctime(&wtmp_buffer[wtmp_count].ut_time));
|
||||
|
||||
if (interrupt == SIGINT) exit(2);
|
||||
|
||||
interrupt = FALSE;
|
||||
signal(SIGQUIT, Sigquit);
|
||||
}
|
||||
}
|
||||
|
||||
} /* end while(size > 0) */
|
||||
|
||||
if (tell_uptime) {
|
||||
fprintf(stderr,
|
||||
"%s: no reboot record in wtmp file to compute uptime from\n",
|
||||
prog);
|
||||
return(1);
|
||||
}
|
||||
|
||||
printf("\nwtmp begins %.16s \n", ctime(&wtmp_buffer[0].ut_time));
|
||||
return(0);
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
SCRIPTS= poweroff.sh
|
||||
MAN=
|
||||
|
||||
.include <bsd.prog.mk>
|
|
@ -1,13 +0,0 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# poweroff 1.0 - power off the system Author: David van Moolenbroek
|
||||
# 12 Jun 2009
|
||||
|
||||
if [ $# -gt 0 ]; then
|
||||
echo "usage: poweroff" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PATH=/usr/bin:$PATH
|
||||
|
||||
exec shutdown -p
|
|
@ -1,15 +0,0 @@
|
|||
# Makefile for shutdown / halt / reboot.
|
||||
|
||||
PROGS= shutdown halt
|
||||
SRCS.shutdown= shutdown.c sh_wall.c log.c
|
||||
SRCS.halt= halt.c log.c
|
||||
BINDIR=/bin
|
||||
BINMODE= 4754
|
||||
SYMLINKS+= ${BINDIR}/halt ${BINDIR}/reboot
|
||||
SYMLINKS+= ${BINDIR}/halt /usr/bin/halt
|
||||
SYMLINKS+= ${BINDIR}/shutdown /usr/bin/shutdown
|
||||
SYMLINKS+= ${BINDIR}/reboot /usr/bin/reboot
|
||||
MAN.shutdown=
|
||||
MAN.halt=
|
||||
|
||||
.include <bsd.prog.mk>
|
|
@ -1,52 +0,0 @@
|
|||
This a new implementation of a shutdown procedure. It allows
|
||||
the system to go down graciously with informing the
|
||||
users. This package contains 3 programs:
|
||||
|
||||
- halt = Immediately stop the system, no info to users
|
||||
- shutdown = Inform users, close down the system properly
|
||||
- wall = Vincent Archer's implementation of wall (Write all)
|
||||
|
||||
Installing
|
||||
|
||||
Shutdown and halt use a new systemcall, which I've added to
|
||||
MM. Therefor there are several diff's which should be applied:
|
||||
|
||||
callnr.hd - New callnr for reboot(2)
|
||||
Diff against /usr/include/minix/callnr.h.
|
||||
Those of you using a symlink package should
|
||||
change the number and mm/table.c into a free
|
||||
number. I used 54, LSTAT.
|
||||
param.hd - Defines reboot_flag as a part of the messages
|
||||
proto.hd - Add's prototype for do_reboot()
|
||||
table.cd - Interpretation of the systemcall to MM
|
||||
mm.cd - I have added the do_reboot code to mm/getset.c but
|
||||
I couldn't find a getset.c to create a useable diff :-(
|
||||
So you can add where you want it. It is pure code, no diff.
|
||||
|
||||
Now edit log.c and search for ``host''. Change this into your
|
||||
systemname or make it empty.
|
||||
|
||||
Shutdown and halt log their actions in /usr/adm/log, edit the
|
||||
makefile and undefine -DLOG if you don't want this (this at the end of
|
||||
the makefile). You can change SHUT_LOG in shutdown.c and log.c if you
|
||||
want it in another file.
|
||||
|
||||
Then type a `make'. This will take a minute or so (13 sec. with bcc :-).
|
||||
Remember to build a new image and update the ps_database.
|
||||
|
||||
Type `make install' to place the program's where I've got them.
|
||||
Use them, try them and let me now if you've got problems running
|
||||
something.
|
||||
|
||||
I have tested to sources both on 16-bits and 32-bits MINIX. I have compiled
|
||||
it with gcc, bcc and ACK, so that shouldn't really give a problem. Maybe
|
||||
the standard MINIX-make chokes on the makefile, atleast mine did.
|
||||
|
||||
NOTE:
|
||||
Make install does not place the man-pages somewhere. You should
|
||||
do this yourself.
|
||||
|
||||
--
|
||||
Edvard Tuinder ed@pulstar.NL.mugnet.org v892231@si.hhs.NL
|
||||
Student Computer Science
|
||||
Haagse Hogeschool, The Hague, The Netherlands
|
|
@ -1,126 +0,0 @@
|
|||
/* halt / reboot - halt or reboot system (depends on name)
|
||||
|
||||
halt - calling reboot() with RBT_HALT
|
||||
reboot - calling reboot() with RBT_REBOOT
|
||||
|
||||
author: Edvard Tuinder v892231@si.hhs.NL
|
||||
|
||||
This program calls the library function reboot(2) which performs
|
||||
the system-call do_reboot.
|
||||
|
||||
*/
|
||||
|
||||
#define _POSIX_SOURCE 1
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include <minix/reboot.h>
|
||||
|
||||
#include "wtmp.h"
|
||||
|
||||
void write_log( char *fn );
|
||||
void usage( void );
|
||||
int main( int argc, char *argv[] );
|
||||
|
||||
char *prog;
|
||||
|
||||
void
|
||||
usage()
|
||||
{
|
||||
fprintf(stderr, "Usage: %s [-hrRfpd]\n", prog);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
main(argc,argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int flag = -1; /* default action unknown */
|
||||
int fast = 0; /* fast halt/reboot, don't bother being nice. */
|
||||
int i;
|
||||
struct stat dummy;
|
||||
pid_t pid;
|
||||
|
||||
if ((prog = strrchr(argv[0],'/')) == NULL) prog = argv[0]; else prog++;
|
||||
|
||||
if (strcmp(prog, "halt") == 0) flag = RBT_HALT;
|
||||
if (strcmp(prog, "reboot") == 0) flag = RBT_REBOOT;
|
||||
|
||||
i = 1;
|
||||
while (i < argc && argv[i][0] == '-') {
|
||||
char *opt = argv[i++] + 1;
|
||||
|
||||
if (*opt == '-' && opt[1] == 0) break; /* -- */
|
||||
|
||||
while (*opt != 0) switch (*opt++) {
|
||||
case 'h': flag = RBT_HALT; break;
|
||||
case 'r': flag = RBT_REBOOT; break;
|
||||
case 'R': flag = RBT_RESET; break;
|
||||
case 'd': flag = RBT_DEFAULT; break;
|
||||
case 'p': flag = RBT_POWEROFF; break;
|
||||
case 'f': fast = 1; break;
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
|
||||
if (i != argc) usage();
|
||||
|
||||
if (flag == -1) {
|
||||
fprintf(stderr, "Don't know what to do when named '%s'\n", prog);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (stat("/usr/bin", &dummy) < 0) {
|
||||
/* It seems that /usr isn't present, let's assume "-f." */
|
||||
fast = 1;
|
||||
}
|
||||
|
||||
signal(SIGHUP, SIG_IGN);
|
||||
signal(SIGTERM, SIG_IGN);
|
||||
|
||||
/* Skip this part for fast shut down. */
|
||||
if (! fast) {
|
||||
/* Run the shutdown scripts. */
|
||||
switch ((pid = fork())) {
|
||||
case -1:
|
||||
fprintf(stderr, "%s: can't fork(): %s\n", prog, strerror(errno));
|
||||
exit(1);
|
||||
case 0:
|
||||
execl("/bin/sh", "sh", "/etc/rc", "down", (char *) NULL);
|
||||
fprintf(stderr, "%s: can't execute: /bin/sh: %s\n",
|
||||
prog, strerror(errno));
|
||||
exit(1);
|
||||
default:
|
||||
while (waitpid(pid, NULL, 0) != pid) {}
|
||||
}
|
||||
}
|
||||
|
||||
/* Tell init to stop spawning getty's. */
|
||||
kill(1, SIGTERM);
|
||||
|
||||
/* Extra sync for the case where SIGTERM causes deadlock */
|
||||
sync();
|
||||
|
||||
/* Give everybody a chance to die peacefully. */
|
||||
printf("Sending SIGTERM to all processes ...\n");
|
||||
kill(-1, SIGTERM);
|
||||
sleep(1);
|
||||
|
||||
write_log(STR_WTMP);
|
||||
write_log(STR_ROOT_WTMP);
|
||||
|
||||
sync();
|
||||
|
||||
reboot(flag);
|
||||
fprintf(stderr, "%s: reboot(): %s\n", prog, strerror(errno));
|
||||
return 1;
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
/*
|
||||
log - log the shutdown's and the halt's
|
||||
|
||||
Author: Edvard Tuinder <v892231@si.hhs.NL>
|
||||
|
||||
shutdown is logged in /usr/adm/wtmp and in /usr/adm/log (if desired)
|
||||
halt is logged only in /usr/adm/wtmp as `halt' to prevent last from
|
||||
reporting halt's as crashes.
|
||||
|
||||
*/
|
||||
|
||||
#define _POSIX_SOURCE 1
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <utmp.h>
|
||||
#include <pwd.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/utsname.h>
|
||||
|
||||
static char SHUT_LOG[] = "/usr/adm/log";
|
||||
|
||||
char who[8];
|
||||
extern char *prog;
|
||||
static char *month[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
|
||||
|
||||
void write_log(char *wtmpfile)
|
||||
{
|
||||
int fd;
|
||||
static struct utmp wtmp;
|
||||
static struct passwd *pwd;
|
||||
char mes[90];
|
||||
struct tm *tm;
|
||||
time_t now;
|
||||
struct utsname utsname;
|
||||
char *host = "localhost";
|
||||
|
||||
time(&now);
|
||||
tm = localtime(&now);
|
||||
|
||||
if (uname(&utsname) >= 0) host = utsname.nodename;
|
||||
|
||||
pwd = getpwuid(getuid());
|
||||
if (pwd == (struct passwd *)0)
|
||||
strcpy (who,"root");
|
||||
else
|
||||
strcpy (who,pwd->pw_name);
|
||||
fd = open(wtmpfile,O_APPEND|O_WRONLY|O_CREAT,1);
|
||||
if (fd) {
|
||||
if (strcmp(prog,"reboot"))
|
||||
strcpy (wtmp.ut_name, prog);
|
||||
else
|
||||
strcpy (wtmp.ut_name, "shutdown"); /* last ... */
|
||||
strcpy (wtmp.ut_id, "~~");
|
||||
strcpy (wtmp.ut_line, "~");
|
||||
wtmp.ut_pid = 0;
|
||||
wtmp.ut_type = BOOT_TIME;
|
||||
wtmp.ut_time = now;
|
||||
wtmp.ut_host[0]= '\0';
|
||||
write (fd, (char *) &wtmp,sizeof(struct utmp));
|
||||
close(fd);
|
||||
}
|
||||
fd = open(SHUT_LOG,O_APPEND|O_WRONLY,1);
|
||||
if (!fd)
|
||||
perror ("open");
|
||||
else {
|
||||
sprintf (mes,"%s %02d %02d:%02d:%02d %s: system %s by %s@%s\n",
|
||||
month[tm->tm_mon],tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,
|
||||
prog,prog,who,host);
|
||||
write (fd,mes,strlen(mes));
|
||||
close(fd);
|
||||
}
|
||||
return;
|
||||
}
|
|
@ -1,109 +0,0 @@
|
|||
/* wall - write to all logged in users Author: V. Archer */
|
||||
/*
|
||||
Edvard Tuinder v892231@si.hhs.NL
|
||||
Modified some things to include this with my shutdown/halt
|
||||
package
|
||||
*/
|
||||
|
||||
#define _POSIX_SOURCE 1
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <pwd.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <utmp.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <sys/stat.h>
|
||||
#undef UTMP
|
||||
|
||||
static char UTMP[] = "/etc/utmp"; /* Currently logged in users. */
|
||||
|
||||
void wall( char *when, char *extra );
|
||||
void crnlcat( char *message, char *more );
|
||||
|
||||
void
|
||||
wall(when, extra)
|
||||
char *when; /* When is shutdown */
|
||||
char *extra; /* If non-nil, why is the shutdown */
|
||||
{
|
||||
struct utmp utmp;
|
||||
char utmptty[5 + sizeof(utmp.ut_line) + 2];
|
||||
char message[1024];
|
||||
struct passwd *pw;
|
||||
int utmpfd, ttyfd;
|
||||
char *ourtty, *ourname;
|
||||
time_t now;
|
||||
struct utsname utsname;
|
||||
struct stat con_st, tty_st;
|
||||
|
||||
if ((ourtty = ttyname(1))) {
|
||||
if ((ourname = strrchr(ourtty, '/'))) ourtty = ourname+1;
|
||||
} else ourtty = "system task";
|
||||
if ((pw = getpwuid(getuid()))) ourname = pw->pw_name;
|
||||
else ourname = "unknown";
|
||||
|
||||
time(&now);
|
||||
if (uname(&utsname) != 0) strcpy(utsname.nodename, "?");
|
||||
sprintf(message, "\r\nBroadcast message from %s@%s (%s)\r\n%.24s...\r\n",
|
||||
ourname, utsname.nodename, ourtty, ctime(&now));
|
||||
|
||||
crnlcat(message, when);
|
||||
crnlcat(message, extra);
|
||||
|
||||
/* Search the UTMP database for all logged-in users. */
|
||||
|
||||
if ((utmpfd = open(UTMP, O_RDONLY)) < 0) {
|
||||
fprintf(stderr, "Cannot open utmp file\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* first the console */
|
||||
strcpy(utmptty, "/dev/console");
|
||||
if ((ttyfd = open(utmptty, O_WRONLY | O_NONBLOCK)) < 0) {
|
||||
perror(utmptty);
|
||||
} else {
|
||||
fstat(ttyfd, &con_st);
|
||||
write(ttyfd, message, strlen(message));
|
||||
close(ttyfd);
|
||||
}
|
||||
|
||||
while (read(utmpfd, (char *) &utmp, sizeof(utmp)) == sizeof(utmp)) {
|
||||
/* is this the user we are looking for? */
|
||||
if (utmp.ut_type != USER_PROCESS) continue;
|
||||
|
||||
strncpy(utmptty+5, utmp.ut_line, sizeof(utmp.ut_line));
|
||||
utmptty[5 + sizeof(utmp.ut_line) + 1] = 0;
|
||||
if ((ttyfd = open(utmptty, O_WRONLY | O_NONBLOCK)) < 0) {
|
||||
perror(utmptty);
|
||||
continue;
|
||||
}
|
||||
fstat(ttyfd, &tty_st);
|
||||
if (tty_st.st_rdev != con_st.st_rdev)
|
||||
write(ttyfd, message, strlen(message));
|
||||
close(ttyfd);
|
||||
}
|
||||
close(utmpfd);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
crnlcat(message, more)
|
||||
char *message, *more;
|
||||
{
|
||||
char *p = message;
|
||||
char *m = more;
|
||||
char *end = message + 1024 - 1;
|
||||
|
||||
while (p < end && *p != 0) p++;
|
||||
|
||||
while (p < end && *m != 0) {
|
||||
if (*m == '\n' && (p == message || p[-1] != '\n')) {
|
||||
*p++ = '\r';
|
||||
if (p == end) p--;
|
||||
}
|
||||
*p++ = *m++;
|
||||
}
|
||||
*p = 0;
|
||||
}
|
|
@ -1,393 +0,0 @@
|
|||
/*
|
||||
shutdown - close down the system graciously
|
||||
|
||||
Author: Edvard Tuinder <v892231@si.hhs.NL>
|
||||
|
||||
This program informs the users that the system is going
|
||||
down, when and why. After that a shutdown notice is written in
|
||||
both /usr/adm/wtmp and by syslog(3). Then reboot(2) is called
|
||||
to really close the system.
|
||||
|
||||
This actually is a ``nice'' halt(8).
|
||||
|
||||
Options are supposed to be as with BSD
|
||||
-h: shutdown and halt the system
|
||||
-r: shutdown and reboot
|
||||
-k: stop an already running shutdown
|
||||
-o: obsolete: not implemented
|
||||
|
||||
New Minix options:
|
||||
-C: crash check, i.e. is the last wtmp entry a shutdown entry?
|
||||
-R: reset the system
|
||||
-d: default CTRL-ALT-DEL shutdown for current bootloader
|
||||
*/
|
||||
|
||||
#define _POSIX_SOURCE 1
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <unistd.h>
|
||||
#include <utmp.h>
|
||||
#include <errno.h>
|
||||
#include <minix/reboot.h>
|
||||
|
||||
#include "wtmp.h"
|
||||
|
||||
static char SHUT_PID[] = "/usr/run/shutdown.pid";
|
||||
static char NOLOGIN[] = "/etc/nologin";
|
||||
|
||||
#ifndef __STDC__
|
||||
#define inform_user_time inf_time
|
||||
#define inform_user inf_user
|
||||
#endif
|
||||
|
||||
void usage( void );
|
||||
void write_pid( void );
|
||||
int inform_user_time( void );
|
||||
void inform_user( void );
|
||||
void terminate( void );
|
||||
void wall( char *when, char *extra );
|
||||
int crash_check( void );
|
||||
void parse_time( char *arg );
|
||||
void get_message( void );
|
||||
int main( int argc, char *argv[] );
|
||||
char *itoa( int n );
|
||||
|
||||
long wait_time=0L;
|
||||
char message[1024];
|
||||
char info[80];
|
||||
int reboot_flag='h'; /* default is halt */
|
||||
int info_min, info_hour;
|
||||
char *prog;
|
||||
|
||||
void parse_time (arg)
|
||||
char *arg;
|
||||
{
|
||||
char *p = arg;
|
||||
int hours, minutes;
|
||||
time_t now;
|
||||
struct tm *tm;
|
||||
int delta = 0;
|
||||
int bad = 0;
|
||||
|
||||
if (p[0] == '+') { delta = 1; p++; }
|
||||
|
||||
hours = strtoul(p, &p, 10);
|
||||
if (*p == 0 && delta) {
|
||||
minutes = hours;
|
||||
hours = 0;
|
||||
} else {
|
||||
if (*p != ':' && *p != '.')
|
||||
bad = 1;
|
||||
else
|
||||
p++;
|
||||
minutes = strtoul(p, &p, 10);
|
||||
if (*p != 0) bad = 1;
|
||||
}
|
||||
if (bad) {
|
||||
fprintf(stderr,"Invalid time specification `%s'\n",arg);
|
||||
usage();
|
||||
}
|
||||
|
||||
time(&now);
|
||||
tm = localtime(&now);
|
||||
|
||||
if (!delta) {
|
||||
hours -= tm->tm_hour;
|
||||
minutes -= tm->tm_min;
|
||||
}
|
||||
|
||||
if (minutes < 0) {
|
||||
minutes += 60;
|
||||
hours--;
|
||||
}
|
||||
if (hours < 0) hours += 24; /* Time after midnight. */
|
||||
|
||||
tm->tm_hour += hours;
|
||||
tm->tm_min += minutes;
|
||||
(void) mktime(tm);
|
||||
info_hour = tm->tm_hour;
|
||||
info_min = tm->tm_min;
|
||||
|
||||
sprintf(info,
|
||||
"The system will shutdown in %d hour%s and %d minute%s at %02d:%02d\n\n",
|
||||
hours,hours==1?"":"s",minutes,minutes==1?"":"s",info_hour,info_min);
|
||||
|
||||
wait_time += hours * 3600 + minutes * 60;
|
||||
return;
|
||||
}
|
||||
|
||||
int main(argc,argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
int i, now = 0, nologin = 0, want_terminate = 0, want_message = 0, check = 0;
|
||||
char *opt;
|
||||
int tty;
|
||||
static char HALT1[] = "-?";
|
||||
static char *HALT[] = { "shutdown", HALT1, NULL };
|
||||
|
||||
/* Parse options. */
|
||||
for (i = 1; i < argc && argv[i][0] == '-'; i++) {
|
||||
if (argv[i][1] == '-' && argv[i][2] == 0) {
|
||||
/* -- */
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
for (opt = argv[i] + 1; *opt != 0; opt++) {
|
||||
switch (*opt) {
|
||||
case 'k':
|
||||
want_terminate = 1;
|
||||
break;
|
||||
case 'h':
|
||||
case 'r':
|
||||
case 'p':
|
||||
case 'd':
|
||||
case 'R':
|
||||
reboot_flag = *opt;
|
||||
break;
|
||||
case 'm':
|
||||
want_message = 1;
|
||||
break;
|
||||
case 'C':
|
||||
check = 1;
|
||||
break;
|
||||
default:
|
||||
fprintf (stderr,"shutdown: invalid option '-%c'\n",*opt);
|
||||
usage();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((argc - i) > 2) usage();
|
||||
|
||||
if (check) exit(crash_check() ? 0 : 2);
|
||||
|
||||
if (i == argc) {
|
||||
/* No timespec, assume "now". */
|
||||
now = 1;
|
||||
} else {
|
||||
if (!strcmp(argv[i], "now"))
|
||||
now++;
|
||||
else
|
||||
parse_time(argv[i]);
|
||||
}
|
||||
|
||||
if ((argc - i) == 2) {
|
||||
/* One line message */
|
||||
strcat(message, argv[i+1]);
|
||||
strcat(message, "\n");
|
||||
}
|
||||
|
||||
if (want_terminate) terminate();
|
||||
if (want_message) get_message();
|
||||
|
||||
puts(info);
|
||||
|
||||
prog = strrchr(*argv,'/');
|
||||
if (prog == (char *)0)
|
||||
prog = *argv;
|
||||
else
|
||||
prog++;
|
||||
|
||||
if (!now) {
|
||||
/* Daemonize. */
|
||||
switch (fork()) {
|
||||
case 0:
|
||||
break;
|
||||
case -1:
|
||||
fprintf(stderr, "%s: can't fork\n", prog);
|
||||
exit(1);
|
||||
default:
|
||||
exit(0);
|
||||
}
|
||||
/* Detach from the terminal (if any). */
|
||||
if ((tty = open("/dev/tty", O_RDONLY)) != -1) {
|
||||
close(tty);
|
||||
setsid();
|
||||
}
|
||||
write_pid();
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
if (wait_time <= 5 * 60 && !nologin && !now) {
|
||||
close(creat(NOLOGIN,00644));
|
||||
nologin = 1;
|
||||
}
|
||||
if (wait_time <= 60) break;
|
||||
if(inform_user_time())
|
||||
inform_user();
|
||||
sleep (60);
|
||||
wait_time -= 60;
|
||||
}
|
||||
|
||||
if (!now) {
|
||||
inform_user();
|
||||
sleep (30); /* Last minute before shutdown */
|
||||
wait_time -= 30;
|
||||
inform_user();
|
||||
sleep (30); /* Last 30 seconds before shutdown */
|
||||
}
|
||||
wait_time = 0;
|
||||
inform_user();
|
||||
|
||||
unlink(SHUT_PID); /* No way of stopping anymore */
|
||||
unlink(NOLOGIN);
|
||||
|
||||
HALT[1][1] = reboot_flag;
|
||||
#if __minix_vmd
|
||||
execv("/usr/sbin/halt", HALT);
|
||||
#else
|
||||
execv("/usr/bin/halt", HALT);
|
||||
#endif
|
||||
if (errno != ENOENT)
|
||||
fprintf(stderr, "Can't execute 'halt': %s\n", strerror(errno));
|
||||
|
||||
sleep(2);
|
||||
reboot(RBT_HALT);
|
||||
fprintf(stderr, "Reboot call failed: %s\n", strerror(errno));
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
void usage()
|
||||
{
|
||||
fputs("Usage: shutdown [-hrRpmkd] [time [message]]\n", stderr);
|
||||
fputs(" -h -> halt system after shutdown\n", stderr);
|
||||
fputs(" -r -> reboot system after shutdown\n", stderr);
|
||||
fputs(" -R -> reset system after shutdown\n", stderr);
|
||||
fputs(" -p -> power system off after shutdown\n", stderr);
|
||||
fputs(" -d -> default CTRL-ALT-DEL shutdown for current bootloader\n", stderr);
|
||||
fputs(" -m -> read a shutdown message from standard input\n", stderr);
|
||||
fputs(" -k -> stop an already running shutdown\n", stderr);
|
||||
fputs(" time -> keyword ``now'', minutes before shutdown ``+5'',\n", stderr);
|
||||
fputs(" or absolute time specification ``11:20''\n", stderr);
|
||||
fputs(" message -> short shutdown message\n", stderr);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void terminate()
|
||||
{
|
||||
FILE *in;
|
||||
pid_t pid;
|
||||
char c_pid[5];
|
||||
|
||||
in = fopen(SHUT_PID,"r");
|
||||
if (in == (FILE *)0) {
|
||||
fputs ("Can't get pid of shutdown process, probably not running shutdown\n", stderr);
|
||||
exit(1);
|
||||
}
|
||||
fgets(c_pid,5,in);
|
||||
fclose(in);
|
||||
pid = atoi(c_pid);
|
||||
if (kill(pid,9) == -1)
|
||||
fputs("Can't kill the shutdown process, probably not running anymore\n",stderr);
|
||||
else
|
||||
puts("Shutdown process terminated");
|
||||
unlink(SHUT_PID);
|
||||
unlink(NOLOGIN);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void get_message()
|
||||
{
|
||||
char line[80];
|
||||
|
||||
puts ("Type your message. End with ^D at an empty line");
|
||||
fputs ("shutdown> ",stdout);fflush(stdout);
|
||||
while (fgets(line,80,stdin) != (char *)0) {
|
||||
strcat (message,line);
|
||||
bzero(line,strlen(line));
|
||||
fputs ("shutdown> ",stdout);fflush(stdout);
|
||||
}
|
||||
putc('\n',stdout);fflush(stdout);
|
||||
}
|
||||
|
||||
int inform_user_time()
|
||||
{
|
||||
int min;
|
||||
|
||||
min = wait_time /60;
|
||||
|
||||
if (min == 60 || min == 30 || min == 15 || min == 10 || min <= 5)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void inform_user()
|
||||
{
|
||||
int hour, minute;
|
||||
char mes[80];
|
||||
|
||||
hour = 0;
|
||||
minute = wait_time / 60;
|
||||
while (minute >= 60) {
|
||||
minute -= 60;
|
||||
hour++;
|
||||
}
|
||||
|
||||
if (hour)
|
||||
sprintf(mes,
|
||||
"\nThe system will shutdown in %d hour%s and %d minute%s at %.02d:%.02d\n\n",
|
||||
hour,hour==1?"":"s",minute,minute==1?"":"s",info_hour,info_min);
|
||||
else
|
||||
if (minute > 1)
|
||||
sprintf(mes,
|
||||
"\nThe system will shutdown in %d minutes at %.02d:%.02d\n\n",
|
||||
minute,info_hour,info_min);
|
||||
else
|
||||
if (wait_time > 1)
|
||||
sprintf(mes,
|
||||
"\nThe system will shutdown in %ld seconds\n\n",
|
||||
wait_time);
|
||||
else
|
||||
sprintf(mes,
|
||||
"\nThe system will shutdown NOW\n\n");
|
||||
|
||||
wall(mes,message);
|
||||
}
|
||||
|
||||
void write_pid()
|
||||
{
|
||||
char pid[5];
|
||||
int fd;
|
||||
|
||||
fd = creat(SHUT_PID,00600);
|
||||
if (!fd)
|
||||
return;
|
||||
strncpy (pid,itoa(getpid()), sizeof(pid));
|
||||
write (fd,pid,sizeof(pid));
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
int crash_check()
|
||||
{
|
||||
struct utmp last;
|
||||
int fd = -1, crashed;
|
||||
struct stat st;
|
||||
|
||||
if (stat(STR_ROOT_WTMP, &st) < 0 || st.st_size == 0) {
|
||||
if (stat(STR_WTMP, &st) < 0 || st.st_size == 0) {
|
||||
return 0;
|
||||
}
|
||||
if ((fd = open(STR_WTMP, O_RDONLY)) < 0) return 0;
|
||||
} else if ((fd = open(STR_ROOT_WTMP, O_RDONLY)) < 0) return 0;
|
||||
|
||||
crashed = (lseek(fd, - (off_t) sizeof(last), SEEK_END) == -1
|
||||
|| read(fd, (void *) &last, sizeof(last)) != sizeof(last)
|
||||
|| last.ut_line[0] != '~'
|
||||
|| (strncmp(last.ut_name, "shutdown", sizeof(last.ut_name))
|
||||
&& strncmp(last.ut_name, "halt", sizeof(last.ut_name)))
|
||||
);
|
||||
close(fd);
|
||||
return crashed;
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
|
||||
static char STR_WTMP[] = "/usr/adm/wtmp";
|
||||
static char STR_ROOT_WTMP[] = "/etc/wtmp";
|
|
@ -4,7 +4,7 @@
|
|||
#
|
||||
|
||||
PROG= in.telnetd
|
||||
SRCS= main.c telnet.c term.c pty.c wtmp.c
|
||||
SRCS= main.c telnet.c term.c pty.c
|
||||
MAN=
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
|
|
@ -45,7 +45,6 @@ int opt_d = 0; /* debugging output flag */
|
|||
|
||||
void usage(void);
|
||||
int main(int argc, char *argv[]);
|
||||
void wtmp(int type, int linenr, char *line, pid_t pid, char *host);
|
||||
|
||||
void usage()
|
||||
{
|
||||
|
@ -144,14 +143,10 @@ char *hostname;
|
|||
return(-1);
|
||||
}
|
||||
|
||||
wtmp(LOGIN_PROCESS, lineno, tty_name+5, pid, hostname);
|
||||
|
||||
term_inout(pty_fd);
|
||||
|
||||
(void) close(pty_fd);
|
||||
|
||||
wtmp(DEAD_PROCESS, lineno, tty_name+5, pid, hostname);
|
||||
|
||||
chown(tty_name, 0, 0);
|
||||
chmod(tty_name, 0666);
|
||||
|
||||
|
|
|
@ -1,112 +0,0 @@
|
|||
/*
|
||||
* TNET A server program for MINIX which implements the TCP/IP
|
||||
* suite of networking protocols. It is based on the
|
||||
* TCP/IP code written by Phil Karn et al, as found in
|
||||
* his NET package for Packet Radio communications.
|
||||
*
|
||||
* This file contains an implementation of the "server"
|
||||
* for the TELNET protocol. This protocol can be used to
|
||||
* remote-login on other systems, just like a normal TTY
|
||||
* session.
|
||||
*
|
||||
* Usage: telnetd [-dv]
|
||||
*
|
||||
* Version: @(#)telnetd.c 1.00 07/26/92
|
||||
*
|
||||
* Author: Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
|
||||
* Michael Temari, <temari@temari.ae.ge.com>
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <utmp.h>
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
#include "telnetd.h"
|
||||
|
||||
static char PATH_UTMP[] = "/etc/utmp";
|
||||
static char PATH_WTMP[] = "/usr/adm/wtmp";
|
||||
|
||||
void wtmp(int type, int linenr, char *line, pid_t pid, char *host);
|
||||
void report(char *label);
|
||||
|
||||
void wtmp(type, linenr, line, pid, host)
|
||||
int type; /* type of entry */
|
||||
int linenr; /* line number in ttytab */
|
||||
char *line; /* tty name (only good on login) */
|
||||
pid_t pid; /* pid of process */
|
||||
char *host; /* name of the remote host */
|
||||
{
|
||||
/* Log an event into the UTMP and WTMP files. */
|
||||
|
||||
struct utmp utmp; /* UTMP/WTMP User Accounting */
|
||||
int fd;
|
||||
|
||||
/* Clear the utmp record. */
|
||||
memset((void *) &utmp, 0, sizeof(utmp));
|
||||
|
||||
/* Fill in utmp. */
|
||||
switch (type) {
|
||||
case LOGIN_PROCESS:
|
||||
/* A new login, fill in line and host name. */
|
||||
strncpy(utmp.ut_line, line, sizeof(utmp.ut_line));
|
||||
strncpy(utmp.ut_host, host, sizeof(utmp.ut_host));
|
||||
break;
|
||||
|
||||
case DEAD_PROCESS:
|
||||
/* A logout. Use the current utmp entry, but make sure it is a
|
||||
* user process exiting, and not getty or login giving up.
|
||||
*/
|
||||
if ((fd = open(PATH_UTMP, O_RDONLY)) < 0) {
|
||||
if (errno != ENOENT) report(PATH_UTMP);
|
||||
return;
|
||||
}
|
||||
if (lseek(fd, (off_t) (linenr+1) * sizeof(utmp), SEEK_SET) == -1
|
||||
|| read(fd, &utmp, sizeof(utmp)) == -1
|
||||
) {
|
||||
report(PATH_UTMP);
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
close(fd);
|
||||
if (utmp.ut_type != USER_PROCESS) return;
|
||||
strncpy(utmp.ut_name, "", sizeof(utmp.ut_name));
|
||||
break;
|
||||
}
|
||||
|
||||
/* Finish new utmp entry. */
|
||||
utmp.ut_pid = pid;
|
||||
utmp.ut_type = type;
|
||||
utmp.ut_time = time((time_t *) 0);
|
||||
|
||||
/* Write new entry to utmp. */
|
||||
if ((fd = open(PATH_UTMP, O_WRONLY)) < 0
|
||||
|| lseek(fd, (off_t) (linenr+1) * sizeof(utmp), SEEK_SET) == -1
|
||||
|| write(fd, &utmp, sizeof(utmp)) == -1
|
||||
) {
|
||||
if (errno != ENOENT) report(PATH_UTMP);
|
||||
}
|
||||
if (fd != -1) close(fd);
|
||||
|
||||
if (type == DEAD_PROCESS) {
|
||||
/* Add new wtmp entry. */
|
||||
if ((fd = open(PATH_WTMP, O_WRONLY | O_APPEND)) < 0
|
||||
|| write(fd, &utmp, sizeof(utmp)) == -1
|
||||
) {
|
||||
if (errno != ENOENT) report(PATH_WTMP);
|
||||
}
|
||||
if (fd != -1) close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
void report(label)
|
||||
char *label;
|
||||
{
|
||||
char message[128];
|
||||
|
||||
sprintf(message, "telnetd: %i: %s\r\n", errno, strerror(errno));
|
||||
(void) write(1, message, strlen(message));
|
||||
}
|
|
@ -24,8 +24,8 @@
|
|||
./bin/expr minix-sys
|
||||
./bin/false minix-sys
|
||||
./bin/getopts minix-sys
|
||||
./bin/getty minix-sys
|
||||
./bin/halt minix-sys
|
||||
./bin/getty minix-sys obsolete
|
||||
./bin/halt minix-sys obsolete
|
||||
./bin/intr minix-sys
|
||||
./bin/kill minix-sys
|
||||
./bin/ksh minix-sys
|
||||
|
@ -42,14 +42,14 @@
|
|||
./bin/pwd minix-sys
|
||||
./bin/read minix-sys
|
||||
./bin/readclock minix-sys
|
||||
./bin/reboot minix-sys
|
||||
./bin/reboot minix-sys obsolete
|
||||
./bin/rm minix-sys
|
||||
./bin/rmdir minix-sys
|
||||
./bin/sed minix-sys
|
||||
./bin/service minix-sys
|
||||
./bin/setup minix-sys
|
||||
./bin/sh minix-sys
|
||||
./bin/shutdown minix-sys
|
||||
./bin/shutdown minix-sys obsolete
|
||||
./bin/sync minix-sys
|
||||
./bin/sysenv minix-sys
|
||||
./bin/tar minix-sys
|
||||
|
@ -117,6 +117,8 @@
|
|||
./etc/termcap minix-sys
|
||||
./etc/ttys minix-sys
|
||||
./etc/utmp minix-sys
|
||||
./etc/gettytab minix-sys
|
||||
./etc/rc.shutdown minix-sys
|
||||
./home minix-sys
|
||||
./home/ast minix-sys
|
||||
./home/ast/.exrc minix-sys
|
||||
|
@ -146,6 +148,8 @@
|
|||
./sbin/fsck_ext2fs minix-sys
|
||||
./sbin/fsck.mfs minix-sys
|
||||
./sbin/input minix-sys
|
||||
./sbin/halt minix-sys
|
||||
./sbin/init minix-sys
|
||||
./sbin/is minix-sys
|
||||
./sbin/isofs minix-sys
|
||||
./sbin/mfs minix-sys
|
||||
|
@ -155,8 +159,11 @@
|
|||
./sbin/newfs_ext2 minix-sys
|
||||
./sbin/newfs_ext2fs minix-sys
|
||||
./sbin/nologin minix-sys
|
||||
./sbin/poweroff minix-sys
|
||||
./sbin/procfs minix-sys
|
||||
./sbin/readclock.drv minix-sys
|
||||
./sbin/reboot minix-sys
|
||||
./sbin/shutdown minix-sys
|
||||
./sys minix-sys
|
||||
./tmp minix-sys
|
||||
./usr minix-sys
|
||||
|
@ -336,7 +343,7 @@
|
|||
./usr/bin/gzcat minix-sys
|
||||
./usr/bin/gzexe minix-sys
|
||||
./usr/bin/gzip minix-sys
|
||||
./usr/bin/halt minix-sys
|
||||
./usr/bin/halt minix-sys obsolete
|
||||
./usr/bin/head minix-sys
|
||||
./usr/bin/hexdump minix-sys
|
||||
./usr/bin/host minix-sys
|
||||
|
@ -437,7 +444,7 @@
|
|||
./usr/bin/pkgin_cd minix-sys
|
||||
./usr/bin/playwave minix-sys
|
||||
./usr/bin/postinstall minix-sys
|
||||
./usr/bin/poweroff minix-sys
|
||||
./usr/bin/poweroff minix-sys obsolete
|
||||
./usr/bin/pr minix-sys
|
||||
./usr/bin/prep minix-sys
|
||||
./usr/bin/printenv minix-sys
|
||||
|
@ -456,8 +463,8 @@
|
|||
./usr/bin/readall minix-sys obsolete
|
||||
./usr/bin/readelf minix-sys binutils
|
||||
./usr/bin/readlink minix-sys
|
||||
./usr/bin/reboot minix-sys
|
||||
./usr/bin/recwave minix-sys
|
||||
./usr/bin/reboot minix-sys obsolete
|
||||
./usr/bin/ref minix-sys obsolete
|
||||
./usr/bin/remsync minix-sys
|
||||
./usr/bin/repartition minix-sys
|
||||
|
@ -479,7 +486,7 @@
|
|||
./usr/bin/shar minix-sys
|
||||
./usr/bin/shlock minix-sys
|
||||
./usr/bin/shuffle minix-sys
|
||||
./usr/bin/shutdown minix-sys
|
||||
./usr/bin/shutdown minix-sys obsolete
|
||||
./usr/bin/size minix-sys binutils
|
||||
./usr/bin/sleep minix-sys
|
||||
./usr/bin/slip minix-sys
|
||||
|
@ -540,8 +547,8 @@
|
|||
./usr/bin/unxz minix-sys
|
||||
./usr/bin/unzip minix-sys
|
||||
./usr/bin/update minix-sys
|
||||
./usr/bin/uptime minix-sys
|
||||
./usr/bin/users minix-sys
|
||||
./usr/bin/uptime minix-sys obsolete
|
||||
./usr/bin/uud minix-sys
|
||||
./usr/bin/uudecode minix-sys
|
||||
./usr/bin/uue minix-sys
|
||||
|
@ -552,6 +559,7 @@
|
|||
./usr/bin/view minix-sys
|
||||
./usr/bin/vis minix-sys
|
||||
./usr/bin/vol minix-sys
|
||||
./usr/bin/wall minix-sys
|
||||
./usr/bin/wc minix-sys
|
||||
./usr/bin/what minix-sys
|
||||
./usr/bin/whatis minix-sys
|
||||
|
@ -1201,7 +1209,7 @@
|
|||
./usr/include/minix/procfs.h minix-sys
|
||||
./usr/include/minix/profile.h minix-sys
|
||||
./usr/include/minix/queryparam.h minix-sys
|
||||
./usr/include/minix/reboot.h minix-sys
|
||||
./usr/include/minix/reboot.h minix-sys obsolete
|
||||
./usr/include/minix/rs.h minix-sys
|
||||
./usr/include/minix/safecopies.h minix-sys
|
||||
./usr/include/minix/sched.h minix-sys
|
||||
|
@ -1938,6 +1946,7 @@
|
|||
./usr/libexec/atf-check minix-sys atf
|
||||
./usr/libexec/fingerd minix-sys
|
||||
./usr/libexec/ftpd minix-sys
|
||||
./usr/libexec/getty minix-sys
|
||||
./usr/libexec/kyua-atf-tester minix-sys kyua
|
||||
./usr/libexec/kyua-plain-tester minix-sys kyua
|
||||
./usr/libexec/ld.elf_so minix-sys
|
||||
|
@ -2282,6 +2291,7 @@
|
|||
./usr/man/man1/view.1 minix-sys
|
||||
./usr/man/man1/vis.1 minix-sys
|
||||
./usr/man/man1/vol.1 minix-sys
|
||||
./usr/man/man1/wall.1 minix-sys
|
||||
./usr/man/man1/wait.1 minix-sys
|
||||
./usr/man/man1/wc.1 minix-sys
|
||||
./usr/man/man1/what.1 minix-sys
|
||||
|
@ -4696,6 +4706,7 @@
|
|||
./usr/man/man5/ftpchroot.5 minix-sys
|
||||
./usr/man/man5/ftpd.conf.5 minix-sys
|
||||
./usr/man/man5/ftpusers.5 minix-sys
|
||||
./usr/man/man5/gettytab.5 minix-sys
|
||||
./usr/man/man5/group.5 minix-sys
|
||||
./usr/man/man5/hosts.5 minix-sys
|
||||
./usr/man/man5/httpd.conf.5 minix-sys
|
||||
|
@ -4724,6 +4735,7 @@
|
|||
./usr/man/man5/termcap.5 minix-sys
|
||||
./usr/man/man5/terminfo.5 minix-sys
|
||||
./usr/man/man5/texinfo.5 minix-sys
|
||||
./usr/man/man5/ttys.5 minix-sys
|
||||
./usr/man/man5/ttytab.5 minix-sys
|
||||
./usr/man/man5/TZ.5 minix-sys
|
||||
./usr/man/man5/tzfile.5 minix-sys
|
||||
|
@ -4863,7 +4875,7 @@
|
|||
./usr/sbin/groupmod minix-sys
|
||||
./usr/sbin/i2cscan minix-sys
|
||||
./usr/sbin/inet minix-sys
|
||||
./usr/sbin/init minix-sys
|
||||
./usr/sbin/init minix-sys obsolete
|
||||
./usr/sbin/installboot_nbsd minix-sys
|
||||
./usr/sbin/ipc minix-sys
|
||||
./usr/sbin/kernel minix-sys
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
#include <minix/i2c.h>
|
||||
#include <minix/i2cdriver.h>
|
||||
#include <minix/log.h>
|
||||
#include <minix/reboot.h>
|
||||
|
||||
#include <sys/signal.h>
|
||||
|
||||
/* Register Addresses */
|
||||
#define CHIPID_REG 0x00
|
||||
|
@ -155,7 +156,7 @@ enable_pwr_off(void)
|
|||
/* enable power off via the PWR_EN pin. just do the setup here.
|
||||
* the kernel will do the work to toggle the pin when the
|
||||
* system is ready to be powered off. Should be called during startup
|
||||
* so that shutdown(8) can do power-off with reboot(RBT_POWEROFF).
|
||||
* so that shutdown(8) can do power-off with reboot().
|
||||
*/
|
||||
r = i2creg_write8(bus_endpoint, address, STATUS_REG, PWR_OFF_MASK);
|
||||
if (r != OK) {
|
||||
|
@ -228,10 +229,8 @@ intr_handler(void)
|
|||
|
||||
if ((val & PBI_MASK) != 0) {
|
||||
log_info(&log, "Power Button Pressed\n");
|
||||
reboot(RBT_POWEROFF);
|
||||
log_warn(&log, "Failed to power off the system.");
|
||||
sys_irqenable(&irq_hook_kernel_id);
|
||||
return -1;
|
||||
kill(1, SIGUSR1); /* tell init to powerdwn */
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* re-enable interrupt */
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <sys/ioctl.h>
|
||||
#include <sys/kbdio.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/reboot.h>
|
||||
#include <sys/select.h>
|
||||
#include <termios.h>
|
||||
#include <signal.h>
|
||||
|
@ -18,7 +19,6 @@
|
|||
#include <minix/com.h>
|
||||
#include <minix/input.h>
|
||||
#include <minix/keymap.h>
|
||||
#include <minix/reboot.h>
|
||||
#include <minix/ds.h>
|
||||
#include <assert.h>
|
||||
#include "tty.h"
|
||||
|
@ -295,7 +295,7 @@ static unsigned make_break(int scode)
|
|||
{
|
||||
if (++CAD_count == 3) {
|
||||
cons_stop();
|
||||
sys_abort(RBT_DEFAULT);
|
||||
sys_abort(RB_AUTOBOOT);
|
||||
}
|
||||
sys_kill(INIT_PROC_NR, SIGABRT);
|
||||
rebooting = 1;
|
||||
|
|
|
@ -700,6 +700,10 @@ static int do_ioctl(devminor_t minor, unsigned long request, endpoint_t endpt,
|
|||
if (isconsole(tp)) r = con_loadfont(endpt, grant);
|
||||
break;
|
||||
|
||||
case TIOCSCTTY:
|
||||
tp->tty_pgrp = user_endpt;
|
||||
break;
|
||||
|
||||
/* These Posix functions are allowed to fail if _POSIX_JOB_CONTROL is
|
||||
* not defined.
|
||||
*/
|
||||
|
|
|
@ -97,7 +97,7 @@ BIN1+= boot.cfg.default \
|
|||
protocols rc rc.cd rc.subr \
|
||||
rc.daemons.dist rs.inet rs.single \
|
||||
services shells syslog.conf \
|
||||
termcap utmp
|
||||
termcap utmp gettytab rc.shutdown
|
||||
.else
|
||||
BIN1+= bootptab changelist csh.cshrc csh.login \
|
||||
csh.logout daily daily.conf dm.conf envsys.conf floppytab ftpchroot \
|
||||
|
|
154
etc/gettytab
Normal file
154
etc/gettytab
Normal file
|
@ -0,0 +1,154 @@
|
|||
# $NetBSD: gettytab,v 1.18 2006/01/08 22:23:46 dsl Exp $
|
||||
# from: @(#)gettytab 8.2 (Berkeley) 4/20/94
|
||||
#
|
||||
# Most of the table entries here are just copies of the old getty table,
|
||||
# it is by no means certain, or even likely, that any of them are optimal
|
||||
# for any purpose whatever. Nor is it likely that more than a couple are
|
||||
# even correct.
|
||||
#
|
||||
# The default gettytab entry, used to set defaults for all other
|
||||
# entries, and in cases where getty is called with no table name
|
||||
#
|
||||
default:\
|
||||
:ce:ck:np:im=\r\n%s/%m (%h) (%t)\r\n\r\n:
|
||||
|
||||
#
|
||||
# Fixed speed entries
|
||||
#
|
||||
# The "std.NNN" names are known to the special case
|
||||
# portselector code in getty, however they can
|
||||
# be assigned to any table desired.
|
||||
# The "NNN-baud" names are known to the special case
|
||||
# autobaud code in getty, and likewise can
|
||||
# be assigned to any table desired (hopefully the same speed).
|
||||
#
|
||||
std.110|110-baud:\
|
||||
:sp#110:
|
||||
std.300|300-baud:\
|
||||
:sp#300:
|
||||
std.600|600-baud:\
|
||||
:sp#600:
|
||||
std.1200|1200-baud:\
|
||||
:sp#1200:
|
||||
std.2400|2400-baud:\
|
||||
:sp#2400:
|
||||
std.4800|4800-baud:\
|
||||
:sp#4800:
|
||||
std.9600|9600-baud:\
|
||||
:sp#9600:
|
||||
std.19200|19200-baud:\
|
||||
:sp#19200:
|
||||
std.38400|38400-baud:\
|
||||
:sp#38400:
|
||||
std.57600|57600-baud:\
|
||||
:sp#57600:
|
||||
std.115200|115200-baud:\
|
||||
:sp#115200:
|
||||
|
||||
# PPP network link login
|
||||
#
|
||||
# these entries can be used by ISPs or others who want to be able
|
||||
# to offer both a "shell" and a PPP login on the same port. Setting
|
||||
# the "pp" attribute allows getty(8) to recognize a PPP link start
|
||||
# negotiation, and invoke the program listed, in addition to normal
|
||||
# login(1).
|
||||
#
|
||||
# N.B.: if PPP is recognized, this bypasses normal login/password
|
||||
# exchange; the expectation is that you'll configure pppd (or whatever)
|
||||
# to require a PAP or CHAP handshake for authentication after PPP is
|
||||
# started up.
|
||||
#
|
||||
# It is also recommended that you use hardware (CTS/RTS) flow control
|
||||
# on the port, and run the port as fast as possible, to allow modems
|
||||
# extra time to do data compression, if enabled.
|
||||
#
|
||||
ppp:np:ce:ck:pp=/usr/sbin/pppd:
|
||||
#
|
||||
ppp.19200|PPP-19200:sp#19200:tc=ppp:
|
||||
ppp.38400|PPP-38400:sp#38400:tc=ppp:
|
||||
ppp.57600|PPP-57600:sp#57600:tc=ppp:
|
||||
ppp.115200|PPP-115200:sp#115200:tc=ppp:
|
||||
ppp.230400|PPP-230400:sp#230400:tc=ppp:
|
||||
|
||||
#
|
||||
# Dial in rotary tables, speed selection via 'break'
|
||||
#
|
||||
d1200|Dial-1200:\
|
||||
:nx=d300:sp#1200:
|
||||
d300|Dial-300:\
|
||||
:nx=d1200:sp#300:
|
||||
|
||||
#
|
||||
# Fast dialup terminals, 2400/1200/300 rotary (can start either way)
|
||||
#
|
||||
D2400|d2400|Fast-Dial-2400:\
|
||||
:nx=D1200:tc=2400-baud:
|
||||
D1200|Fast-Dial-1200:\
|
||||
:nx=D300:tc=1200-baud:
|
||||
D300|Fast-Dial-300:\
|
||||
:nx=D2400:tc=300-baud:
|
||||
|
||||
#
|
||||
#telebit (19200)
|
||||
#
|
||||
t19200:\
|
||||
:nx=t2400:tc=19200-baud:
|
||||
t2400:\
|
||||
:nx=t1200:tc=2400-baud:
|
||||
t1200:\
|
||||
:nx=t19200:tc=1200-baud:
|
||||
|
||||
#
|
||||
#telebit (9600)
|
||||
#
|
||||
t9600:\
|
||||
:nx=t2400a:tc=19200-baud:
|
||||
t2400a:\
|
||||
:nx=t1200a:tc=2400-baud:
|
||||
t1200a:\
|
||||
:nx=t9600:tc=1200-baud:
|
||||
|
||||
#
|
||||
# Odd special case terminals
|
||||
#
|
||||
Console|Console Decwriter II:\
|
||||
:rw:tc=300-baud:
|
||||
|
||||
Console-1200|Console Decwriter III:\
|
||||
:rw:tc=1200-baud:
|
||||
|
||||
X|Xwindow|X window system:\
|
||||
:rw:sp#9600:
|
||||
|
||||
Pc|Pc console:\
|
||||
:np:ig:ht:
|
||||
|
||||
# 8 bit clean Sun console
|
||||
suncons|Sun Console:\
|
||||
:np:sp#9600:
|
||||
|
||||
#
|
||||
# Plugboard, and misc other terminals
|
||||
#
|
||||
plug-9600|Plugboard-9600:\
|
||||
:pf#1:tc=9600-baud:
|
||||
P9600|Plugboard-9600-rotary:\
|
||||
:pf#1:nx=P300:tc=9600-baud:
|
||||
P300|Plugboard-300:\
|
||||
:pf#1:nx=P1200:tc=300-baud:
|
||||
P1200|Plugboard-1200:\
|
||||
:pf#1:nx=P9600:tc=1200-baud:
|
||||
|
||||
#
|
||||
# XXXX Port selector
|
||||
#
|
||||
DSW|Port Selector:\
|
||||
:ps:sp#2400:
|
||||
|
||||
#
|
||||
# Auto-baud speed detect entry for Micom 600.
|
||||
# Special code in getty will switch this out
|
||||
# to one of the NNN-baud entries.
|
||||
#
|
||||
Auto-baud:\
|
||||
:ab:sp#2400:f0#040:
|
30
etc/rc
30
etc/rc
|
@ -21,7 +21,7 @@ ARCH="`sysenv arch`"
|
|||
|
||||
usage()
|
||||
{
|
||||
echo >&2 "Usage: $0 [-saf] start|stop|down"
|
||||
echo >&2 "Usage: $0 [-saf] autoboot|start|stop|down"
|
||||
exec intr sh
|
||||
}
|
||||
|
||||
|
@ -54,8 +54,12 @@ edit()
|
|||
service=$1
|
||||
shift
|
||||
|
||||
# Assume binaries are always in /usr/sbin
|
||||
service $opt edit /usr/sbin/$service -label $service "$@"
|
||||
# Assume binaries are always in /sbin or /usr/sbin
|
||||
binlocation=/usr/sbin/$service
|
||||
if [ ! -x $binlocation ]
|
||||
then binlocation=/sbin/$service
|
||||
fi
|
||||
service $opt edit $binlocation -label $service "$@"
|
||||
}
|
||||
|
||||
while getopts 'saf' opt
|
||||
|
@ -70,14 +74,14 @@ done
|
|||
shift `expr $OPTIND - 1`
|
||||
|
||||
case "$#:$1" in
|
||||
1:start|1:stop|1:down)
|
||||
1:start|1:stop|1:down|1:autoboot)
|
||||
action=$1
|
||||
;;
|
||||
*) usage
|
||||
esac
|
||||
|
||||
case $action in
|
||||
start)
|
||||
autoboot|start)
|
||||
|
||||
# National keyboard?
|
||||
test -f /etc/keymap && loadkeys /etc/keymap
|
||||
|
@ -104,8 +108,12 @@ start)
|
|||
up readclock.drv
|
||||
readclock -q || date 201301010000
|
||||
|
||||
# We are not shutting down.
|
||||
rm -f /etc/nologin
|
||||
|
||||
# Initialize files.
|
||||
>/etc/utmp # /etc/utmp keeps track of logins
|
||||
>/var/run/utmp # /etc/utmp keeps track of logins
|
||||
>/var/run/utmpx # /etc/utmpx keeps track of logins
|
||||
|
||||
# Use MFS binary only from kernel image?
|
||||
if [ "`sysenv bin_img`" = 1 ]
|
||||
|
@ -147,10 +155,6 @@ start)
|
|||
edit init
|
||||
fi
|
||||
|
||||
# This file is necessary for above 'shutdown -C' check.
|
||||
# (Silence stderr in case of running from cd.)
|
||||
touch /usr/adm/wtmp /etc/wtmp 2>/dev/null
|
||||
|
||||
if [ "$sflag" ]
|
||||
then
|
||||
echo "Single user. Press ^D to resume multiuser startup."
|
||||
|
@ -212,6 +216,10 @@ test -f /usr/etc/rc && sh /usr/etc/rc $action
|
|||
test -f /usr/local/etc/rc && sh /usr/local/etc/rc $action
|
||||
|
||||
# Any messages?
|
||||
test "$action" = start -a -f /etc/issue && cat /etc/issue
|
||||
if [ "$action" = start -o "$action" = autoboot ]
|
||||
then if [ -f /etc/issue ]
|
||||
then cat /etc/issue
|
||||
fi
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
|
3
etc/rc.shutdown
Normal file
3
etc/rc.shutdown
Normal file
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
sh /etc/rc stop
|
|
@ -638,7 +638,7 @@ service tda19988
|
|||
|
||||
service tps65217
|
||||
{
|
||||
uid 0; # needed for doing reboot(RBT_POWEROFF)
|
||||
uid 0; # needed for doing reboot()
|
||||
system IRQCTL PRIVCTL;
|
||||
irq 7; # NNMI pin on BeagleBone / BeagleBone Black
|
||||
ipc SYSTEM RS DS PM i2c;
|
||||
|
|
8
etc/ttys
8
etc/ttys
|
@ -3,10 +3,10 @@
|
|||
#
|
||||
# name getty type status comments
|
||||
#
|
||||
console getty minix on secure
|
||||
ttyc1 getty minix on secure
|
||||
ttyc2 getty minix on secure
|
||||
ttyc3 getty minix on secure
|
||||
console "/usr/libexec/getty default" minix on secure
|
||||
ttyc1 "/usr/libexec/getty default" minix on secure
|
||||
ttyc2 "/usr/libexec/getty default" minix on secure
|
||||
ttyc3 "/usr/libexec/getty default" minix on secure
|
||||
tty00 "" unknown off secure
|
||||
tty01 "" unknown off secure
|
||||
|
||||
|
|
|
@ -25,10 +25,13 @@ fi
|
|||
bootcd="`/bin/sysenv bootcd`"
|
||||
|
||||
case "$#:$1" in
|
||||
1:autoboot)
|
||||
action=start
|
||||
;;
|
||||
1:start|1:stop|1:down)
|
||||
action=$1
|
||||
;;
|
||||
*) echo >&2 "Usage: $0 start|stop|down"
|
||||
*) echo >&2 "Usage: $0 autoboot|start|stop|down"
|
||||
exit 1
|
||||
esac
|
||||
|
||||
|
@ -158,7 +161,7 @@ capemgr() {
|
|||
DAEMONS=/etc/rc.daemons
|
||||
|
||||
case $action in
|
||||
start)
|
||||
start|autoboot)
|
||||
# Select console font.
|
||||
test -f /etc/font && loadfont /etc/font </dev/console
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ INCS+= acpi.h audio_fw.h bitmap.h \
|
|||
keymap.h log.h mmio.h mount.h mthread.h minlib.h \
|
||||
netdriver.h optset.h padconf.h partition.h portio.h \
|
||||
priv.h procfs.h profile.h queryparam.h \
|
||||
reboot.h rs.h safecopies.h sched.h sef.h sffs.h \
|
||||
rs.h safecopies.h sched.h sef.h sffs.h \
|
||||
sound.h spin.h sys_config.h sysinfo.h \
|
||||
syslib.h sysutil.h termios.h timers.h type.h \
|
||||
u64.h usb.h usb_ch9.h vbox.h \
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
#ifndef _MINIX_REBOOT_H
|
||||
#define _MINIX_REBOOT_H
|
||||
|
||||
/* How to exit the system. */
|
||||
#define RBT_HALT 0 /* shut down the system */
|
||||
#define RBT_REBOOT 1 /* reboot the system */
|
||||
#define RBT_PANIC 2 /* the system panics */
|
||||
#define RBT_POWEROFF 3 /* power off, reset if not possible */
|
||||
#define RBT_RESET 4 /* hard reset the system */
|
||||
#define RBT_DEFAULT 5 /* perform the default action du jour */
|
||||
#define RBT_INVALID 6 /* first invalid reboot flag */
|
||||
|
||||
int reboot(int);
|
||||
|
||||
#endif /* _MINIX_REBOOT_H */
|
|
@ -152,6 +152,12 @@ int tcsetattr(int _filedes, int _opt_actions, const struct termios
|
|||
#define VLNEXT 12 /* cc_c[VLNEXT] (^V) */
|
||||
#define VDISCARD 13 /* cc_c[VDISCARD] (^O) */
|
||||
|
||||
/* Non-functional additions */
|
||||
#define VDSUSP 14
|
||||
#define VWERASE 15
|
||||
#define VSTATUS 16
|
||||
#define VEOL2 17
|
||||
|
||||
/* Extensions to baud rate settings. */
|
||||
#if defined(__minix) && defined(_NETBSD_SOURCE)
|
||||
#define B57600 0x0100 /* 57600 baud */
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#define TIOCSWINSZ _IOW('T', 17, struct winsize)
|
||||
#define TIOCGPGRP _IOW('T', 18, int)
|
||||
#define TIOCSPGRP _IOW('T', 19, int)
|
||||
#define TIOCSCTTY _IO ('T', 20) /* controlling tty */
|
||||
#define TIOCSFON _IOW_BIG(1, u8_t [8192])
|
||||
|
||||
/* Keyboard ioctls. */
|
||||
|
|
|
@ -376,8 +376,8 @@ int profil(char *, size_t, u_long, u_int);
|
|||
void psignal(int, const char *);
|
||||
#endif /* __PSIGNAL_DECLARED */
|
||||
int rcmd(char **, int, const char *, const char *, const char *, int *);
|
||||
#ifndef __minix
|
||||
int reboot(int, char *);
|
||||
#ifndef __minix
|
||||
int revoke(const char *);
|
||||
#endif
|
||||
int rresvport(int *);
|
||||
|
|
|
@ -39,26 +39,12 @@
|
|||
#ifndef _UTMP_H_
|
||||
#define _UTMP_H_
|
||||
|
||||
#ifdef __minix
|
||||
#define _PATH_UTMP "/etc/utmp"
|
||||
#define _PATH_WTMP "/usr/adm/wtmp"
|
||||
#define _PATH_BTMP "/usr/adm/btmp"
|
||||
#define _PATH_LASTLOG "/usr/adm/lastlog"
|
||||
#define UTMP _PATH_UTMP
|
||||
#define WTMP _PATH_WTMP
|
||||
#define BTMP _PATH_BTMP
|
||||
#else
|
||||
#define _PATH_UTMP "/var/run/utmp"
|
||||
#define _PATH_WTMP "/var/log/wtmp"
|
||||
#define _PATH_LASTLOG "/var/log/lastlog"
|
||||
#endif
|
||||
|
||||
#define UT_NAMESIZE 8
|
||||
#ifdef __minix
|
||||
#define UT_LINESIZE 12
|
||||
#else
|
||||
#define UT_LINESIZE 8
|
||||
#endif
|
||||
#define UT_HOSTSIZE 16
|
||||
|
||||
struct lastlog {
|
||||
|
@ -67,34 +53,12 @@ struct lastlog {
|
|||
char ll_host[UT_HOSTSIZE];
|
||||
};
|
||||
|
||||
#ifdef __minix
|
||||
struct utmp {
|
||||
char ut_name[UT_NAMESIZE]; /* user name */
|
||||
char ut_id[4]; /* /etc/inittab ID */
|
||||
char ut_line[UT_LINESIZE]; /* terminal name */
|
||||
char ut_host[UT_HOSTSIZE]; /* host name, when remote */
|
||||
short ut_pid; /* process id */
|
||||
short int ut_type; /* type of entry */
|
||||
time_t ut_time; /* login/logout time */
|
||||
};
|
||||
|
||||
/* Definitions for ut_type. */
|
||||
#define RUN_LVL 1 /* this is a RUN_LEVEL record */
|
||||
#define BOOT_TIME 2 /* this is a REBOOT record */
|
||||
#define INIT_PROCESS 5 /* this process was spawned by INIT */
|
||||
#define LOGIN_PROCESS 6 /* this is a 'getty' process waiting */
|
||||
#define USER_PROCESS 7 /* any other user process */
|
||||
#define DEAD_PROCESS 8 /* this process has died (wtmp only) */
|
||||
|
||||
#else /* !__minix */
|
||||
|
||||
struct utmp {
|
||||
char ut_line[UT_LINESIZE];
|
||||
char ut_name[UT_NAMESIZE];
|
||||
char ut_host[UT_HOSTSIZE];
|
||||
time_t ut_time;
|
||||
};
|
||||
#endif /* __minix */
|
||||
|
||||
__BEGIN_DECLS
|
||||
int utmpname(const char *);
|
||||
|
|
|
@ -9,8 +9,9 @@
|
|||
#include <machine/vm.h>
|
||||
#include <io.h>
|
||||
|
||||
#include <minix/reboot.h>
|
||||
#include <minix/board.h>
|
||||
#include <sys/reboot.h>
|
||||
|
||||
#include <minix/u64.h>
|
||||
|
||||
#include "archconst.h"
|
||||
|
@ -51,25 +52,23 @@ poweroff(void)
|
|||
__dead void
|
||||
arch_shutdown(int how)
|
||||
{
|
||||
switch (how) {
|
||||
case RBT_HALT:
|
||||
/* Hang */
|
||||
for (; ; ) halt_cpu();
|
||||
NOT_REACHABLE;
|
||||
|
||||
case RBT_POWEROFF:
|
||||
if((how & RB_POWERDOWN) == RB_POWERDOWN) {
|
||||
/* Power off if possible, hang otherwise */
|
||||
poweroff();
|
||||
NOT_REACHABLE;
|
||||
}
|
||||
|
||||
if(how & RB_HALT) {
|
||||
/* Hang */
|
||||
for (; ; ) halt_cpu();
|
||||
NOT_REACHABLE;
|
||||
}
|
||||
|
||||
default:
|
||||
case RBT_DEFAULT:
|
||||
case RBT_REBOOT:
|
||||
case RBT_RESET:
|
||||
/* Reset the system */
|
||||
reset();
|
||||
NOT_REACHABLE;
|
||||
}
|
||||
|
||||
while (1);
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#include <minix/com.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <minix/reboot.h>
|
||||
#include <sys/reboot.h>
|
||||
#include "string.h"
|
||||
#include "arch_proto.h"
|
||||
#include "direct_utils.h"
|
||||
|
@ -412,7 +412,7 @@ kinfo_t *pre_init(int argc, char **argv)
|
|||
* longer used and the "real" implementations are visible
|
||||
*/
|
||||
void send_diag_sig(void) { }
|
||||
void minix_shutdown(minix_timer_t *t) { arch_shutdown(RBT_PANIC); }
|
||||
void minix_shutdown(minix_timer_t *t) { arch_shutdown(0); }
|
||||
void busy_delay_ms(int x) { }
|
||||
int raise(int n) { panic("raise(%d)\n", n); }
|
||||
int kern_phys_map_ptr( phys_bytes base_address, vir_bytes io_size,
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#include <machine/cpu.h>
|
||||
#include <minix/portio.h>
|
||||
#include <minix/cpufeature.h>
|
||||
#include <minix/reboot.h>
|
||||
#include <sys/reboot.h>
|
||||
#include <assert.h>
|
||||
#include <signal.h>
|
||||
#include <machine/vm.h>
|
||||
|
@ -135,29 +135,23 @@ __dead void arch_shutdown(int how)
|
|||
reset();
|
||||
}
|
||||
|
||||
switch (how) {
|
||||
case RBT_HALT:
|
||||
/* Hang */
|
||||
for (; ; ) halt_cpu();
|
||||
NOT_REACHABLE;
|
||||
|
||||
case RBT_POWEROFF:
|
||||
if((how & RB_POWERDOWN) == RB_POWERDOWN) {
|
||||
/* Power off if possible, hang otherwise */
|
||||
poweroff();
|
||||
NOT_REACHABLE;
|
||||
}
|
||||
|
||||
if(how & RB_HALT) {
|
||||
/* Hang */
|
||||
for (; ; ) halt_cpu();
|
||||
NOT_REACHABLE;
|
||||
}
|
||||
|
||||
default:
|
||||
case RBT_DEFAULT:
|
||||
case RBT_REBOOT:
|
||||
case RBT_RESET:
|
||||
/* Reset the system by forcing a processor shutdown.
|
||||
* First stop the BIOS memory test by setting a soft
|
||||
* reset flag.
|
||||
*/
|
||||
reset();
|
||||
NOT_REACHABLE;
|
||||
}
|
||||
|
||||
NOT_REACHABLE;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#include <minix/com.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <minix/reboot.h>
|
||||
#include <sys/reboot.h>
|
||||
#include <machine/partition.h>
|
||||
#include "string.h"
|
||||
#include "arch_proto.h"
|
||||
|
@ -246,6 +246,6 @@ kinfo_t *pre_init(u32_t magic, u32_t ebx)
|
|||
}
|
||||
|
||||
void send_diag_sig(void) { }
|
||||
void minix_shutdown(minix_timer_t *t) { arch_shutdown(RBT_PANIC); }
|
||||
void minix_shutdown(minix_timer_t *t) { arch_shutdown(0); }
|
||||
void busy_delay_ms(int x) { }
|
||||
int raise(int sig) { panic("raise(%d)\n", sig); }
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include <minix/u64.h>
|
||||
#include <minix/board.h>
|
||||
#include <minix/type.h>
|
||||
#include <minix/reboot.h>
|
||||
#include <sys/reboot.h>
|
||||
#include "clock.h"
|
||||
#include "direct_utils.h"
|
||||
#include "hw_intr.h"
|
||||
|
@ -357,8 +357,7 @@ void prepare_shutdown(const int how)
|
|||
void minix_shutdown(minix_timer_t *tp)
|
||||
{
|
||||
/* This function is called from prepare_shutdown or stop_sequence to bring
|
||||
* down MINIX. How to shutdown is in the argument: RBT_HALT (return to the
|
||||
* monitor), RBT_RESET (hard reset).
|
||||
* down MINIX.
|
||||
*/
|
||||
int how;
|
||||
|
||||
|
@ -376,25 +375,17 @@ void minix_shutdown(minix_timer_t *tp)
|
|||
hw_intr_disable_all();
|
||||
stop_local_timer();
|
||||
|
||||
how = tp ? tmr_arg(tp)->ta_int : RBT_PANIC;
|
||||
how = tp ? tmr_arg(tp)->ta_int : 0;
|
||||
|
||||
/* Show shutdown message */
|
||||
direct_cls();
|
||||
switch(how) {
|
||||
case RBT_HALT:
|
||||
if((how & RB_POWERDOWN) == RB_POWERDOWN)
|
||||
direct_print("MINIX has halted and will now power off.\n");
|
||||
else if(how & RB_HALT)
|
||||
direct_print("MINIX has halted. "
|
||||
"It is safe to turn off your computer.\n");
|
||||
break;
|
||||
case RBT_POWEROFF:
|
||||
direct_print("MINIX has halted and will now power off.\n");
|
||||
break;
|
||||
case RBT_DEFAULT:
|
||||
case RBT_REBOOT:
|
||||
case RBT_RESET:
|
||||
default:
|
||||
else
|
||||
direct_print("MINIX will now reset.\n");
|
||||
break;
|
||||
}
|
||||
arch_shutdown(how);
|
||||
}
|
||||
|
||||
|
|
|
@ -355,20 +355,14 @@ updwtmpx(const char *file, const struct utmpx *utx)
|
|||
#else
|
||||
if ((fd = open(file, O_CREAT|O_WRONLY, 0644)) < 0)
|
||||
return -1;
|
||||
if (flock(fd, LOCK_EX) < 0)
|
||||
return -1;
|
||||
#endif
|
||||
(void)memset(&ut, 0, sizeof(ut));
|
||||
ut.ut_type = SIGNATURE;
|
||||
(void)memcpy(ut.ut_user, vers, sizeof(vers));
|
||||
if (write(fd, &ut, sizeof(ut)) == -1)
|
||||
goto failed;
|
||||
} else {
|
||||
#ifdef __minix
|
||||
if (flock(fd, LOCK_SH) < 0 )
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (write(fd, utx, sizeof(*utx)) == -1)
|
||||
goto failed;
|
||||
if (close(fd) == -1)
|
||||
|
@ -455,10 +449,6 @@ getlastlogx(const char *fname, uid_t uid, struct lastlogx *ll)
|
|||
|
||||
if (db == NULL)
|
||||
return NULL;
|
||||
#ifdef __minix
|
||||
if (flock(db->fd(db), LOCK_SH) < 0)
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
key.data = &uid;
|
||||
key.size = sizeof(uid);
|
||||
|
@ -503,10 +493,6 @@ updlastlogx(const char *fname, uid_t uid, struct lastlogx *ll)
|
|||
if (db == NULL)
|
||||
return -1;
|
||||
|
||||
#ifdef __minix
|
||||
if (flock(db->fd(db), LOCK_EX) < 0)
|
||||
return -1;
|
||||
#endif
|
||||
key.data = &uid;
|
||||
key.size = sizeof(uid);
|
||||
data.data = ll;
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#include <string.h>
|
||||
#include <sys/reboot.h>
|
||||
|
||||
int reboot(int how)
|
||||
int reboot(int how, char *bootstr)
|
||||
{
|
||||
message m;
|
||||
|
||||
|
|
|
@ -99,7 +99,7 @@ void minix_stack_params(const char *path, char * const *argv, char * const *envp
|
|||
(*argc)++;
|
||||
}
|
||||
|
||||
for (p = envp; *p != NULL; p++) {
|
||||
for (p = envp; p && *p != NULL; p++) {
|
||||
size_t const n = sizeof(*p) + strlen(*p) + 1;
|
||||
*stack_size += n;
|
||||
if (*stack_size < n) {
|
||||
|
@ -156,7 +156,7 @@ void minix_stack_fill(const char *path, int argc, char * const *argv,
|
|||
}
|
||||
*fpw++ = NULL;
|
||||
|
||||
for (p = envp; *p != NULL; p++) {
|
||||
for (p = envp; p && *p != NULL; p++) {
|
||||
size_t const n = strlen(*p) + 1;
|
||||
*fpw++= (char *)(*vsp + (fp - frame));
|
||||
memcpy(fp, *p, n);
|
||||
|
|
|
@ -244,7 +244,7 @@ MAN+= accept.2 access.2 acct.2 bind.2 brk.2 chdir.2 \
|
|||
mprotect.2 mremap.2 msgctl.2 msgget.2 msgrcv.2 msgsnd.2 msync.2 \
|
||||
munmap.2 nanosleep.2 nfssvc.2 ntp_adjtime.2 open.2 pathconf.2 pipe.2
|
||||
.else
|
||||
MAN+= adjtime.2 clock_settime.2 getvfsstat.2 pipe.2 getrusage.2
|
||||
MAN+= adjtime.2 clock_settime.2 getvfsstat.2 pipe.2 getrusage.2 reboot.2
|
||||
.endif # !defined(__MINIX)
|
||||
.if !defined(__MINIX)
|
||||
MAN+= pmc_control.2 poll.2 posix_fadvise.2 profil.2 ptrace.2 __quotactl.2 \
|
||||
|
|
|
@ -146,10 +146,11 @@ CPPFLAGS.${i}+= -I${LIBCDIR}/locale
|
|||
.for i in access.c brk.c close.c environ.c execve.c fork.c fsync.c \
|
||||
getgid.c getpid.c geteuid.c getuid.c gettimeofday.c getvfsstat.c \
|
||||
init.c link.c loadname.c lseek.c lseek64.c _mcontext.c mknod.c \
|
||||
mmap.c nanosleep.c open.c pread.c pwrite.c read.c reboot.c sbrk.c \
|
||||
mmap.c nanosleep.c open.c pread.c pwrite.c read.c sbrk.c \
|
||||
select.c setuid.c sigprocmask.c stack_utils.c stat.c stime.c \
|
||||
syscall.c _ucontext.c umask.c unlink.c waitpid.c write.c \
|
||||
brksize.S _do_kernel_call_intr.S get_minix_kerninfo.S _ipc.S ucontext.S
|
||||
brksize.S _do_kernel_call_intr.S get_minix_kerninfo.S _ipc.S ucontext.S \
|
||||
kill.c
|
||||
.PATH.c: ${LIBCDIR}/sys-minix
|
||||
.PATH.S: ${ARCHDIR}/sys-minix
|
||||
SRCS+= ${i}
|
||||
|
|
|
@ -42,7 +42,7 @@ SRCS+= efun.c \
|
|||
passwd.c pw_scan.c pidfile.c pidlock.c pty.c \
|
||||
raise_default_signal.c \
|
||||
secure_path.c stat_flags.c \
|
||||
strpct.c ttyaction.c \
|
||||
strpct.c ttyaction.c ttymsg.c \
|
||||
|
||||
MAN= efun.3 \
|
||||
getmntopts.3 \
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
|
||||
SUBDIR= \
|
||||
fingerd ftpd \
|
||||
ld.elf_so
|
||||
ld.elf_so \
|
||||
getty
|
||||
|
||||
.if defined(__MINIX)
|
||||
SUBDIR+= makewhatis
|
||||
|
|
12
libexec/getty/Makefile
Normal file
12
libexec/getty/Makefile
Normal file
|
@ -0,0 +1,12 @@
|
|||
# $NetBSD: Makefile,v 1.19 2010/02/03 15:34:43 roy Exp $
|
||||
# from: @(#)Makefile 8.1 (Berkeley) 6/4/93
|
||||
|
||||
WARNS?= 2 # XXX: many const & sign-compare issues
|
||||
|
||||
PROG= getty
|
||||
SRCS= main.c init.c subr.c
|
||||
DPADD+= ${LIBUTIL} ${LIBTERMINFO}
|
||||
LDADD+= -lutil -lterminfo
|
||||
MAN= getty.8 gettytab.5 ttys.5
|
||||
|
||||
.include <bsd.prog.mk>
|
52
libexec/getty/extern.h
Normal file
52
libexec/getty/extern.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
/* $NetBSD: extern.h,v 1.6 2003/08/07 09:46:41 agc Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)extern.h 8.1 (Berkeley) 6/4/93
|
||||
*/
|
||||
|
||||
struct delayval;
|
||||
|
||||
int adelay(int, struct delayval *);
|
||||
char *autobaud(void);
|
||||
int delaybits(void);
|
||||
void edithost(char *);
|
||||
void gendefaults(void);
|
||||
int getent(char *, char *);
|
||||
int getflag(char *);
|
||||
long getnum(char *);
|
||||
char *getstr(char *, char **);
|
||||
void gettable(char *, char *);
|
||||
void makeenv(char *[]);
|
||||
char *portselector(void);
|
||||
void set_ttydefaults(int);
|
||||
void setchars(void);
|
||||
void setdefaults(void);
|
||||
void setflags(int);
|
||||
int speed(int);
|
177
libexec/getty/getty.8
Normal file
177
libexec/getty/getty.8
Normal file
|
@ -0,0 +1,177 @@
|
|||
.\" $NetBSD: getty.8,v 1.17 2003/08/07 09:46:42 agc Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1980, 1991, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" from: @(#)getty.8 8.1 (Berkeley) 6/4/93
|
||||
.\"
|
||||
.Dd December 12, 1998
|
||||
.Dt GETTY 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm getty ,
|
||||
.Nm uugetty
|
||||
.Nd set terminal modes for system access
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Oo
|
||||
.Ar type
|
||||
.Op Ar tty
|
||||
.Oc
|
||||
.Nm uugetty
|
||||
.Oo
|
||||
.Ar type
|
||||
.Op Ar tty
|
||||
.Oc
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
program
|
||||
is called by
|
||||
.Xr init 8
|
||||
to open and initialize the tty line, read a login name, and invoke
|
||||
.Xr login 1 .
|
||||
The devices on which to run
|
||||
.Nm
|
||||
are normally determined by
|
||||
.Xr ttys 5 .
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
program can also recognize a Point to Point Protocol
|
||||
.Pq Tn PPP
|
||||
negotiation, and, if the
|
||||
.Sy pp
|
||||
attribute in
|
||||
.Xr gettytab 5
|
||||
is set, invoke the program given by that string, e.g.,
|
||||
.Xr pppd 8 ,
|
||||
instead of
|
||||
.Xr login 1 .
|
||||
This makes it possible to use a single serial port for either a
|
||||
.Qq shell
|
||||
account with command line interface, or a
|
||||
.Tn PPP
|
||||
network link.
|
||||
.Pp
|
||||
The argument
|
||||
.Ar tty
|
||||
is the special device file in
|
||||
.Pa /dev
|
||||
to open for the terminal
|
||||
.Po
|
||||
for example,
|
||||
.Qq ttyh0
|
||||
.Pc .
|
||||
If there is no argument or the argument is
|
||||
.Ql Fl ,
|
||||
the tty line is assumed to be open as file descriptor 0.
|
||||
.Pp
|
||||
The
|
||||
.Ar type
|
||||
argument can be used to make
|
||||
.Nm
|
||||
treat the terminal line specially.
|
||||
This argument is used as an index into the
|
||||
.Xr gettytab 5
|
||||
database, to determine the characteristics of the line.
|
||||
If there is no argument, or there is no such table, the
|
||||
.Em default
|
||||
table is used.
|
||||
If there is no
|
||||
.Pa /etc/gettytab
|
||||
a set of system defaults is used.
|
||||
If indicated by the table located,
|
||||
.Nm
|
||||
will clear the terminal screen,
|
||||
print a banner heading,
|
||||
and prompt for a login name.
|
||||
Usually either the banner or the login prompt will include
|
||||
the system hostname.
|
||||
.Pp
|
||||
.Nm
|
||||
uses the
|
||||
.Xr ttyaction 3
|
||||
facility with an action of
|
||||
.Qq getty
|
||||
and user
|
||||
.Qq root
|
||||
to execute site-specific commands when it starts.
|
||||
.Pp
|
||||
Most of the default actions of
|
||||
.Nm
|
||||
can be circumvented, or modified, by a suitable
|
||||
.Xr gettytab 5
|
||||
table.
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
program can be set to timeout after some interval,
|
||||
which will cause dial up lines to hang up
|
||||
if the login name is not entered reasonably quickly.
|
||||
.Pp
|
||||
The
|
||||
.Nm uugetty
|
||||
program is the same, except that it uses
|
||||
.Xr pidlock 3
|
||||
to respect the locks in
|
||||
.Pa /var/spool/lock
|
||||
of processes that dial out on that tty.
|
||||
.Sh FILES
|
||||
.Bl -tag -width /var/spool/lock/LCK..ttyXX -compact
|
||||
.It Pa /etc/gettytab
|
||||
.It Pa /etc/ttys
|
||||
.It Pa /var/spool/lock/LCK..ttyXX
|
||||
.El
|
||||
.Sh DIAGNOSTICS
|
||||
.Bl -diag
|
||||
.It "ttyxx: No such device or address."
|
||||
.It "ttyxx: No such file or address."
|
||||
A terminal which is turned on in the
|
||||
.Xr ttys 5
|
||||
file cannot be opened, likely because the requisite
|
||||
lines are either not configured into the system, the associated device
|
||||
was not attached during boot-time system configuration,
|
||||
or the special file in
|
||||
.Pa /dev
|
||||
does not exist.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr login 1 ,
|
||||
.Xr ioctl 2 ,
|
||||
.Xr pidlock 3 ,
|
||||
.Xr ttyaction 3 ,
|
||||
.Xr tty 4 ,
|
||||
.Xr gettytab 5 ,
|
||||
.Xr ttys 5 ,
|
||||
.Xr init 8 ,
|
||||
.Xr pppd 8
|
||||
.Sh HISTORY
|
||||
A
|
||||
.Nm
|
||||
program appeared in
|
||||
.At v6 .
|
423
libexec/getty/gettytab.5
Normal file
423
libexec/getty/gettytab.5
Normal file
|
@ -0,0 +1,423 @@
|
|||
.\" $NetBSD: gettytab.5,v 1.36 2012/04/21 12:27:28 roy Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1983, 1991, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" from: @(#)gettytab.5 8.4 (Berkeley) 4/19/94
|
||||
.\"
|
||||
.Dd April 5, 2012
|
||||
.Dt GETTYTAB 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm gettytab
|
||||
.Nd terminal configuration data base
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
file
|
||||
is a simplified version of the
|
||||
.Xr capfile 5
|
||||
data base
|
||||
used to describe terminal lines.
|
||||
The initial terminal login process
|
||||
.Xr getty 8
|
||||
accesses the
|
||||
.Nm
|
||||
file each time it starts, allowing simpler
|
||||
reconfiguration of terminal characteristics.
|
||||
Each entry in the data base
|
||||
is used to describe one class of terminals.
|
||||
.Pp
|
||||
Where to run
|
||||
.Xr getty 8
|
||||
processes is normally defined by
|
||||
.Xr ttys 5 .
|
||||
.Pp
|
||||
There is a default terminal class,
|
||||
.Em default ,
|
||||
that is used to set global defaults for all other classes.
|
||||
(That is, the
|
||||
.Em default
|
||||
entry is read, then the entry for the class required
|
||||
is used to override particular settings.)
|
||||
The
|
||||
.Em default
|
||||
entry is also normally read by other programs that present login prompts
|
||||
to the user, such as
|
||||
.Xr telnetd 8 ,
|
||||
in order to retrieve the values of the
|
||||
.Em he ,
|
||||
.Em hn ,
|
||||
.Em im ,
|
||||
and
|
||||
.Em if
|
||||
capabilities.
|
||||
.Sh CAPABILITIES
|
||||
Refer to
|
||||
.Xr capfile 5
|
||||
for a description of the file layout.
|
||||
The
|
||||
.Em default
|
||||
column below lists defaults obtained if there is
|
||||
no entry in the table obtained, nor one in the special
|
||||
.Em default
|
||||
table.
|
||||
.Bl -column Namexx /usr/bin/login Default
|
||||
.It Sy Name Type Default Description
|
||||
.It "ab bool false Auto-baud speed select mechanism for the Micom 600 portselector. Selection is done by looking at how the character `\er' is garbled at 300, 1200, 4800, and 9600 baud."
|
||||
.It "al str NULL user to auto-login instead of prompting"
|
||||
.It "ap bool false terminal uses any parity"
|
||||
.It "bk str 0377 alternative end of line character (input break)"
|
||||
.It "b2 str 0377 alternative end of line character (input break)"
|
||||
.It "c0 num unused tty control flags to write messages"
|
||||
.It "c1 num unused tty control flags to read login name"
|
||||
.It "c2 num unused tty control flags to leave terminal as"
|
||||
.It "ce bool false use crt erase algorithm"
|
||||
.It "ck bool false use crt kill algorithm"
|
||||
.It "cl str" Ta Dv NULL Ta
|
||||
.No "screen clear sequence"
|
||||
.It "co bool false console - add"
|
||||
.Ql \er\en
|
||||
after login prompt
|
||||
.It "cs bool false clear screen based on terminal type in /etc/ttys"
|
||||
.It "ds str" Ta So Li ^Y Sc Ta
|
||||
.No "delayed suspend character"
|
||||
.It "dx bool false set"
|
||||
.Dv DECCTLQ
|
||||
.It "ec bool false leave echo"
|
||||
.Tn OFF
|
||||
.It "ep bool false terminal uses even parity"
|
||||
.It "er str" Ta So Li ^? Sc Ta
|
||||
.No "erase character"
|
||||
.It "et str" Ta So Li ^D Sc Ta
|
||||
.No "end of text"
|
||||
.Pq Dv EOF
|
||||
character
|
||||
.It "ev str" Ta Dv NULL Ta
|
||||
.No "initial environment"
|
||||
.It "f0 num unused tty mode flags to write messages"
|
||||
.It "f1 num unused tty mode flags to read login name"
|
||||
.It "f2 num unused tty mode flags to leave terminal as"
|
||||
.It "fl str" Ta So Li ^O Sc Ta
|
||||
.No "output flush character"
|
||||
.It "hc bool false do"
|
||||
.Tn NOT
|
||||
hangup line on last close
|
||||
.It "he str" Ta Dv NULL Ta
|
||||
.No "hostname editing string"
|
||||
.It "hn str hostname hostname"
|
||||
.It "ht bool false terminal has real tabs"
|
||||
.It "i0 num unused tty input flags to write messages"
|
||||
.It "i1 num unused tty input flags to read login name"
|
||||
.It "i2 num unused tty input flags to leave terminal as"
|
||||
.It "if str NULL display named file before prompt, like /etc/issue"
|
||||
.It "ig bool false ignore garbage characters in login name"
|
||||
.It "im str" Ta Dv NULL Ta
|
||||
.No "initial (banner) message"
|
||||
.It "in str" Ta So Li ^C Sc Ta
|
||||
.No "interrupt character"
|
||||
.It "is num unused input speed"
|
||||
.It "kl str" Ta So Li ^U Sc Ta
|
||||
.No "kill character"
|
||||
.It "l0 num unused tty local flags to write messages"
|
||||
.It "l1 num unused tty local flags to read login name"
|
||||
.It "l2 num unused tty local flags to leave terminal as"
|
||||
.It "lc bool false terminal has lower case"
|
||||
.It "lm str login: login prompt"
|
||||
.It "ln str" Ta So Li ^V Sc Ta
|
||||
.No "``literal next'' character"
|
||||
.It "lo str" Ta Pa /usr/bin/login Ta
|
||||
.No "program to exec when name obtained"
|
||||
.It "mb bool false do flow control based on carrier"
|
||||
.It "nl bool false terminal has (or might have) a newline character"
|
||||
.It "nn bool false do not prompt for a login name"
|
||||
.It "np bool false terminal uses no parity (i.e. 8-bit characters)"
|
||||
.It "nx str default next table (for auto speed selection)"
|
||||
.It "o0 num unused tty output flags to write messages"
|
||||
.It "o1 num unused tty output flags to read login name"
|
||||
.It "o2 num unused tty output flags to leave terminal as"
|
||||
.It "op bool false terminal uses odd parity"
|
||||
.It "os num unused output speed"
|
||||
.It "pc str" Ta So Li \e0 Sc Ta
|
||||
.No "pad character"
|
||||
.It "pe bool false use printer (hard copy) erase algorithm"
|
||||
.It "pf num 0 delay"
|
||||
between first prompt and following flush (seconds)
|
||||
.It "pp str unused PPP authentication program"
|
||||
.It "ps bool false line connected to a"
|
||||
.Tn MICOM
|
||||
port selector
|
||||
.It "qu str" Ta So Li \&^\e Sc Ta
|
||||
.No "quit character"
|
||||
.It "rp str" Ta So Li ^R Sc Ta
|
||||
.No "line retype character"
|
||||
.It "rw bool false do"
|
||||
.Tn NOT
|
||||
use raw for input, use cbreak
|
||||
.It "sp num unused line speed (input and output)"
|
||||
.It "st str" Ta So Li ^T Sc Ta
|
||||
.No "status character"
|
||||
.It "su str" Ta So Li ^Z Sc Ta
|
||||
.No "suspend character"
|
||||
.It "tc str none table continuation"
|
||||
.It "to num 0 timeout (seconds)"
|
||||
.It "tt str" Ta Dv NULL Ta
|
||||
.No "terminal type (for environment)"
|
||||
.It "ub bool false do unbuffered output (of prompts etc)"
|
||||
.It "we str" Ta So Li ^W Sc Ta
|
||||
.No "word erase character"
|
||||
.It "xc bool false do"
|
||||
.Tn NOT
|
||||
echo control chars as
|
||||
.Ql ^X
|
||||
.It "xf str" Ta So Li ^S Sc Ta Dv XOFF
|
||||
(stop output) character
|
||||
.It "xn str" Ta So Li ^Q Sc Ta Dv XON
|
||||
(start output) character
|
||||
.El
|
||||
.Pp
|
||||
The following capabilities are no longer supported by
|
||||
.Xr getty 8 :
|
||||
.Bl -column Namexx /usr/bin/login Default
|
||||
.It "bd num 0 backspace delay"
|
||||
.It "cb bool false use crt backspace mode"
|
||||
.It "cd num 0 carriage-return delay"
|
||||
.It "fd num 0 form-feed (vertical motion) delay"
|
||||
.It "nd num 0 newline (line-feed) delay"
|
||||
.It "uc bool false terminal is known upper case only"
|
||||
.El
|
||||
.Pp
|
||||
If no line speed is specified, speed will not be altered
|
||||
from that which prevails when getty is entered.
|
||||
Specifying an input or output speed will override
|
||||
line speed for stated direction only.
|
||||
.Pp
|
||||
Terminal modes to be used for the output of the message,
|
||||
for input of the login name,
|
||||
and to leave the terminal set as upon completion,
|
||||
are derived from the boolean flags specified.
|
||||
If the derivation should prove inadequate,
|
||||
any (or all) of these three may be overridden
|
||||
with one of the
|
||||
.Em \&c0 ,
|
||||
.Em \&c1 ,
|
||||
.Em \&c2 ,
|
||||
.Em \&i0 ,
|
||||
.Em \&i1 ,
|
||||
.Em \&i2 ,
|
||||
.Em \&l0 ,
|
||||
.Em \&l1 ,
|
||||
.Em \&l2 ,
|
||||
.Em \&o0 ,
|
||||
.Em \&o1 ,
|
||||
or
|
||||
.Em \&o2
|
||||
numeric specifications, which can be used to specify
|
||||
(usually in octal, with a leading '0')
|
||||
the exact values of the flags.
|
||||
These flags correspond to the termios
|
||||
.Em c_cflag ,
|
||||
.Em c_iflag ,
|
||||
.Em c_lflag ,
|
||||
and
|
||||
.Em c_oflag
|
||||
fields, respectively.
|
||||
Each these sets must be completely specified to be effective.
|
||||
The
|
||||
.Em \&f0 ,
|
||||
.Em \&f1 ,
|
||||
and
|
||||
.Em \&f2
|
||||
are excepted for backwards compatibility with a previous incarnation of
|
||||
the TTY sub-system.
|
||||
In these flags the bottom 16 bits of the (32 bits) value contain the sgttyb
|
||||
.Em sg_flags
|
||||
field, while the top 16 bits represent the local mode word.
|
||||
.Pp
|
||||
Should
|
||||
.Xr getty 8
|
||||
receive a null character
|
||||
(presumed to indicate a line break)
|
||||
it will restart using the table indicated by the
|
||||
.Em nx
|
||||
entry.
|
||||
If there is none, it will re-use its original table.
|
||||
.Pp
|
||||
Delays are specified in milliseconds, the nearest possible
|
||||
delay available in the tty driver will be used.
|
||||
Should greater certainty be desired, delays
|
||||
with values 0, 1, 2, and 3 are interpreted as
|
||||
choosing that particular delay algorithm from the driver.
|
||||
.Pp
|
||||
The
|
||||
.Em \&cl
|
||||
screen clear string may be preceded by a (decimal) number
|
||||
of milliseconds of delay required (a la termcap).
|
||||
This delay is simulated by repeated use of the pad character
|
||||
.Em \&pc .
|
||||
.Pp
|
||||
The initial message, and login message,
|
||||
.Em \&im
|
||||
and
|
||||
.Em \&lm
|
||||
may include any of the following character sequences, which expand to
|
||||
information about the environment in which
|
||||
.Xr getty 8
|
||||
is running.
|
||||
.Pp
|
||||
.Bl -tag -width \&%xxx -compact
|
||||
.It \&%d
|
||||
The current date.
|
||||
.It \&%h
|
||||
The hostname of the machine, which is normally obtained from the
|
||||
system using
|
||||
.Xr gethostname 3 ,
|
||||
but may also be overridden by the
|
||||
.Em \&hn
|
||||
table entry.
|
||||
In either case it may be edited with the
|
||||
.Em \&he
|
||||
string.
|
||||
A '@' in the
|
||||
.Em \&he
|
||||
string causes one character from the real hostname to
|
||||
be copied to the final hostname.
|
||||
A '#' in the
|
||||
.Em \&he
|
||||
string causes the next character of the real hostname
|
||||
to be skipped.
|
||||
Each character that
|
||||
is neither '@' nor '#' is copied into the final hostname.
|
||||
Surplus '@' and '#' characters are ignored.
|
||||
.It \&%t
|
||||
The tty name.
|
||||
.It "\&%m, \&%r, \&%s, \&%v"
|
||||
The type of machine, release of the operating system, name of the
|
||||
operating system, and version of the kernel, respectively, as
|
||||
returned by
|
||||
.Xr uname 3 .
|
||||
.It \&%%
|
||||
A
|
||||
.Dq %
|
||||
character.
|
||||
.El
|
||||
.Pp
|
||||
When getty execs the login process, given
|
||||
in the
|
||||
.Em \&lo
|
||||
string (usually
|
||||
.Dq Pa /usr/bin/login ) ,
|
||||
it will have set
|
||||
the environment to include the terminal type, as indicated
|
||||
by the
|
||||
.Em \&tt
|
||||
string (if it exists).
|
||||
The
|
||||
.Em \&ev
|
||||
string, can be used to enter additional data into
|
||||
the environment.
|
||||
It is a list of comma separated strings, each of which
|
||||
will presumably be of the form
|
||||
.Em name=value .
|
||||
.Pp
|
||||
If a non-zero timeout is specified, with
|
||||
.Em \&to ,
|
||||
then getty will exit within the indicated
|
||||
number of seconds, either having
|
||||
received a login name and passed control
|
||||
to
|
||||
.Xr login 1 ,
|
||||
or having received an alarm signal, and exited.
|
||||
This may be useful to hangup dial in lines.
|
||||
.Pp
|
||||
Output from
|
||||
.Xr getty 8
|
||||
is even parity unless
|
||||
.Em \&op
|
||||
or
|
||||
.Em \&np
|
||||
is specified.
|
||||
The
|
||||
.Em \&op
|
||||
string
|
||||
may be specified with
|
||||
.Em \&ap
|
||||
to allow any parity on input, but generate odd parity output.
|
||||
Note: this only applies while getty is being run,
|
||||
terminal driver limitations prevent a more complete
|
||||
implementation.
|
||||
.Xr getty 8
|
||||
does not check parity of input characters in
|
||||
.Dv RAW
|
||||
mode.
|
||||
.Pp
|
||||
If
|
||||
.Em \&pp
|
||||
string is specified and a Point to Point Protocol
|
||||
.Pq Tn PPP
|
||||
link bringup sequence is recognized,
|
||||
.Xr getty 8
|
||||
will invoke the program referenced by the
|
||||
.Em \&pp
|
||||
string, e.g.
|
||||
.Xr pppd 8 .
|
||||
This can be used to handle incoming
|
||||
.Tn PPP
|
||||
calls.
|
||||
.Sh SEE ALSO
|
||||
.Xr login 1 ,
|
||||
.Xr gethostname 3 ,
|
||||
.Xr uname 3 ,
|
||||
.Xr capfile 5 ,
|
||||
.Xr ttys 5 ,
|
||||
.Xr getty 8 ,
|
||||
.Xr pppd 8 ,
|
||||
.Xr telnetd 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
file format appeared in
|
||||
.Bx 4.2 .
|
||||
.Sh BUGS
|
||||
The special characters (erase, kill, etc.) are reset to system defaults
|
||||
by
|
||||
.Xr login 1 .
|
||||
In
|
||||
.Em all
|
||||
cases, '#' or '^H' typed in a login name will be treated as
|
||||
an erase character, and '@' will be treated as a kill character.
|
||||
.Pp
|
||||
The delay stuff is a real crock.
|
||||
Apart from its general lack of flexibility, some
|
||||
of the delay algorithms are not implemented.
|
||||
The terminal driver should support sane delay settings.
|
||||
.Pp
|
||||
The
|
||||
.Em \&he
|
||||
capability is stupid.
|
173
libexec/getty/gettytab.h
Normal file
173
libexec/getty/gettytab.h
Normal file
|
@ -0,0 +1,173 @@
|
|||
/* $NetBSD: gettytab.h,v 1.16 2006/11/16 04:31:24 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1983, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)gettytab.h 8.2 (Berkeley) 3/30/94
|
||||
*/
|
||||
|
||||
/*
|
||||
* Getty description definitions.
|
||||
*/
|
||||
struct gettystrs {
|
||||
char *field; /* name to lookup in gettytab */
|
||||
char *defalt; /* value we find by looking in defaults */
|
||||
char *value; /* value that we find there */
|
||||
};
|
||||
|
||||
struct gettynums {
|
||||
char *field; /* name to lookup */
|
||||
long defalt; /* number we find in defaults */
|
||||
long value; /* number we find there */
|
||||
int set; /* we actually got this one */
|
||||
};
|
||||
|
||||
struct gettyflags {
|
||||
char *field; /* name to lookup */
|
||||
char invrt; /* name existing in gettytab --> false */
|
||||
char defalt; /* true/false in defaults */
|
||||
char value; /* true/false flag */
|
||||
char set; /* we found it */
|
||||
};
|
||||
|
||||
/*
|
||||
* See init.c for the arrays indexed by these values.
|
||||
*/
|
||||
|
||||
/*
|
||||
* String values.
|
||||
*/
|
||||
#define NX gettystrs[0].value
|
||||
#define CL gettystrs[1].value
|
||||
#define IM gettystrs[2].value
|
||||
#define LM gettystrs[3].value
|
||||
#define ER gettystrs[4].value
|
||||
#define KL gettystrs[5].value
|
||||
#define ET gettystrs[6].value
|
||||
#define PC gettystrs[7].value
|
||||
#define TT gettystrs[8].value
|
||||
#define EV gettystrs[9].value
|
||||
#define LO gettystrs[10].value
|
||||
#define HN gettystrs[11].value
|
||||
#define HE gettystrs[12].value
|
||||
#define IN gettystrs[13].value
|
||||
#define QU gettystrs[14].value
|
||||
#define XN gettystrs[15].value
|
||||
#define XF gettystrs[16].value
|
||||
#define BK gettystrs[17].value
|
||||
#define SU gettystrs[18].value
|
||||
#define DS gettystrs[19].value
|
||||
#define RP gettystrs[20].value
|
||||
#define FL gettystrs[21].value
|
||||
#define WE gettystrs[22].value
|
||||
#define LN gettystrs[23].value
|
||||
#define ST gettystrs[24].value
|
||||
#define B2 gettystrs[25].value
|
||||
#define PP gettystrs[26].value
|
||||
#define IF gettystrs[27].value
|
||||
#define AL gettystrs[28].value
|
||||
|
||||
/*
|
||||
* Numeric definitions.
|
||||
*/
|
||||
#define IS gettynums[0].value
|
||||
#define OS gettynums[1].value
|
||||
#define SP gettynums[2].value
|
||||
#define ND gettynums[3].value
|
||||
#define CD gettynums[4].value
|
||||
#define TD gettynums[5].value
|
||||
#define FD gettynums[6].value
|
||||
#define BD gettynums[7].value
|
||||
#define TO gettynums[8].value
|
||||
#define F0 gettynums[9].value
|
||||
#define F0set gettynums[9].set
|
||||
#define F1 gettynums[10].value
|
||||
#define F1set gettynums[10].set
|
||||
#define F2 gettynums[11].value
|
||||
#define F2set gettynums[11].set
|
||||
#define PF gettynums[12].value
|
||||
#define C0 gettynums[13].value
|
||||
#define C0set gettynums[13].set
|
||||
#define C1 gettynums[14].value
|
||||
#define C1set gettynums[14].set
|
||||
#define C2 gettynums[15].value
|
||||
#define C2set gettynums[15].set
|
||||
#define I0 gettynums[16].value
|
||||
#define I0set gettynums[16].set
|
||||
#define I1 gettynums[17].value
|
||||
#define I1set gettynums[17].set
|
||||
#define I2 gettynums[18].value
|
||||
#define I2set gettynums[18].set
|
||||
#define L0 gettynums[19].value
|
||||
#define L0set gettynums[19].set
|
||||
#define L1 gettynums[20].value
|
||||
#define L1set gettynums[20].set
|
||||
#define L2 gettynums[21].value
|
||||
#define L2set gettynums[21].set
|
||||
#define O0 gettynums[22].value
|
||||
#define O0set gettynums[22].set
|
||||
#define O1 gettynums[23].value
|
||||
#define O1set gettynums[23].set
|
||||
#define O2 gettynums[24].value
|
||||
#define O2set gettynums[24].set
|
||||
|
||||
/*
|
||||
* Boolean values.
|
||||
*/
|
||||
#define HT gettyflags[0].value
|
||||
#define NL gettyflags[1].value
|
||||
#define EP gettyflags[2].value
|
||||
#define EPset gettyflags[2].set
|
||||
#define OP gettyflags[3].value
|
||||
#define OPset gettyflags[3].set
|
||||
#define AP gettyflags[4].value
|
||||
#define APset gettyflags[4].set
|
||||
#define EC gettyflags[5].value
|
||||
#define CO gettyflags[6].value
|
||||
#define CB gettyflags[7].value
|
||||
#define CK gettyflags[8].value
|
||||
#define CE gettyflags[9].value
|
||||
#define PE gettyflags[10].value
|
||||
#define RW gettyflags[11].value
|
||||
#define XC gettyflags[12].value
|
||||
#define LC gettyflags[13].value
|
||||
#define UC gettyflags[14].value
|
||||
#define IG gettyflags[15].value
|
||||
#define PS gettyflags[16].value
|
||||
#define HC gettyflags[17].value
|
||||
#define UB gettyflags[18].value
|
||||
#define AB gettyflags[19].value
|
||||
#define DX gettyflags[20].value
|
||||
#define NP gettyflags[21].value
|
||||
#define MB gettyflags[22].value
|
||||
#define CS gettyflags[23].value
|
||||
#define NN gettyflags[24].value
|
||||
|
||||
extern struct gettyflags gettyflags[];
|
||||
extern struct gettynums gettynums[];
|
||||
extern struct gettystrs gettystrs[];
|
146
libexec/getty/init.c
Normal file
146
libexec/getty/init.c
Normal file
|
@ -0,0 +1,146 @@
|
|||
/* $NetBSD: init.c,v 1.17 2007/12/03 09:54:24 isaki Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "from: @(#)init.c 8.1 (Berkeley) 6/4/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: init.c,v 1.17 2007/12/03 09:54:24 isaki Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
/*
|
||||
* Getty table initializations.
|
||||
*
|
||||
* Melbourne getty.
|
||||
*/
|
||||
|
||||
#include <termios.h>
|
||||
|
||||
#include "gettytab.h"
|
||||
#include "pathnames.h"
|
||||
|
||||
extern struct termios tmode;
|
||||
extern char hostname[];
|
||||
|
||||
#define M(a) ((char *)&tmode.c_cc[a])
|
||||
|
||||
struct gettystrs gettystrs[] = {
|
||||
{ "nx" }, /* next table */
|
||||
{ "cl" }, /* screen clear characters */
|
||||
{ "im" }, /* initial message */
|
||||
{ "lm", "login: " }, /* login message */
|
||||
{ "er", M(VERASE) }, /* erase character */
|
||||
{ "kl", M(VKILL) }, /* kill character */
|
||||
{ "et", M(VEOF) }, /* eof chatacter (eot) */
|
||||
{ "pc", "" }, /* pad character */
|
||||
{ "tt" }, /* terminal type */
|
||||
{ "ev" }, /* environment */
|
||||
{ "lo", _PATH_LOGIN }, /* login program */
|
||||
{ "hn", hostname }, /* host name */
|
||||
{ "he" }, /* host name edit */
|
||||
{ "in", M(VINTR) }, /* interrupt char */
|
||||
{ "qu", M(VQUIT) }, /* quit char */
|
||||
{ "xn", M(VSTART) }, /* XON (start) char */
|
||||
{ "xf", M(VSTOP) }, /* XOFF (stop) char */
|
||||
{ "bk", M(VEOL) }, /* brk char (alt \n) */
|
||||
{ "su", M(VSUSP) }, /* suspend char */
|
||||
{ "ds", M(VDSUSP) }, /* delayed suspend */
|
||||
{ "rp", M(VREPRINT) }, /* reprint char */
|
||||
{ "fl", M(VDISCARD) }, /* flush output */
|
||||
{ "we", M(VWERASE) }, /* word erase */
|
||||
{ "ln", M(VLNEXT) }, /* literal next */
|
||||
{ "st", M(VSTATUS) }, /* status */
|
||||
{ "b2", M(VEOL2) }, /* alt brk char */
|
||||
{ "pp" }, /* ppp login program */
|
||||
{ "if" }, /* sysv-like 'issue' filename */
|
||||
{ "al" }, /* user to auto-login */
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
struct gettynums gettynums[] = {
|
||||
{ "is" }, /* input speed */
|
||||
{ "os" }, /* output speed */
|
||||
{ "sp" }, /* both speeds */
|
||||
{ "nd" }, /* newline delay */
|
||||
{ "cd" }, /* carriage-return delay */
|
||||
{ "td" }, /* tab delay */
|
||||
{ "fd" }, /* form-feed delay */
|
||||
{ "bd" }, /* backspace delay */
|
||||
{ "to" }, /* timeout */
|
||||
{ "f0" }, /* output flags */
|
||||
{ "f1" }, /* input flags */
|
||||
{ "f2" }, /* user mode flags */
|
||||
{ "pf" }, /* delay before flush at 1st prompt */
|
||||
{ "c0" }, /* output c_flags */
|
||||
{ "c1" }, /* input c_flags */
|
||||
{ "c2" }, /* user mode c_flags */
|
||||
{ "i0" }, /* output i_flags */
|
||||
{ "i1" }, /* input i_flags */
|
||||
{ "i2" }, /* user mode i_flags */
|
||||
{ "l0" }, /* output l_flags */
|
||||
{ "l1" }, /* input l_flags */
|
||||
{ "l2" }, /* user mode l_flags */
|
||||
{ "o0" }, /* output o_flags */
|
||||
{ "o1" }, /* input o_flags */
|
||||
{ "o2" }, /* user mode o_flags */
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
struct gettyflags gettyflags[] = {
|
||||
{ "ht", 0 }, /* has tabs */
|
||||
{ "nl", 1 }, /* has newline char */
|
||||
{ "ep", 0 }, /* even parity */
|
||||
{ "op", 0 }, /* odd parity */
|
||||
{ "ap", 0 }, /* any parity */
|
||||
{ "ec", 1 }, /* no echo */
|
||||
{ "co", 0 }, /* console special */
|
||||
{ "cb", 0 }, /* crt backspace */
|
||||
{ "ck", 0 }, /* crt kill */
|
||||
{ "ce", 0 }, /* crt erase */
|
||||
{ "pe", 0 }, /* printer erase */
|
||||
{ "rw", 1 }, /* don't use raw */
|
||||
{ "xc", 1 }, /* don't ^X ctl chars */
|
||||
{ "lc", 0 }, /* terminal las lower case */
|
||||
{ "uc", 0 }, /* terminal has no lower case */
|
||||
{ "ig", 0 }, /* ignore garbage */
|
||||
{ "ps", 0 }, /* do port selector speed select */
|
||||
{ "hc", 1 }, /* don't set hangup on close */
|
||||
{ "ub", 0 }, /* unbuffered output */
|
||||
{ "ab", 0 }, /* auto-baud detect with '\r' */
|
||||
{ "dx", 0 }, /* set decctlq */
|
||||
{ "np", 0 }, /* no parity at all (8bit chars) */
|
||||
{ "mb", 0 }, /* do MDMBUF flow control */
|
||||
{ "cs", 0 }, /* clear screen based on term type */
|
||||
{ "nn", 0 }, /* don't prompt for login name */
|
||||
{ 0 }
|
||||
};
|
707
libexec/getty/main.c
Normal file
707
libexec/getty/main.c
Normal file
|
@ -0,0 +1,707 @@
|
|||
/* $NetBSD: main.c,v 1.59 2012/06/28 08:55:10 roy Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1980, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#ifndef lint
|
||||
__COPYRIGHT("@(#) Copyright (c) 1980, 1993\
|
||||
The Regents of the University of California. All rights reserved.");
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "from: @(#)main.c 8.1 (Berkeley) 6/20/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: main.c,v 1.59 2012/06/28 08:55:10 roy Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <termios.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/utsname.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <pwd.h>
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include <term.h>
|
||||
#include <time.h>
|
||||
#include <ttyent.h>
|
||||
#include <unistd.h>
|
||||
#include <util.h>
|
||||
|
||||
#include "gettytab.h"
|
||||
#include "pathnames.h"
|
||||
#include "extern.h"
|
||||
|
||||
extern char editedhost[];
|
||||
|
||||
/*
|
||||
* Set the amount of running time that getty should accumulate
|
||||
* before deciding that something is wrong and exit.
|
||||
*/
|
||||
#define GETTY_TIMEOUT 60 /* seconds */
|
||||
|
||||
/* defines for auto detection of incoming PPP calls (->PAP/CHAP) */
|
||||
|
||||
#define PPP_FRAME 0x7e /* PPP Framing character */
|
||||
#define PPP_STATION 0xff /* "All Station" character */
|
||||
#define PPP_ESCAPE 0x7d /* Escape Character */
|
||||
#define PPP_CONTROL 0x03 /* PPP Control Field */
|
||||
#define PPP_CONTROL_ESCAPED 0x23 /* PPP Control Field, escaped */
|
||||
#define PPP_LCP_HI 0xc0 /* LCP protocol - high byte */
|
||||
#define PPP_LCP_LOW 0x21 /* LCP protocol - low byte */
|
||||
|
||||
struct termios tmode, omode;
|
||||
|
||||
int crmod, digit_or_punc, lower, upper;
|
||||
|
||||
char hostname[MAXHOSTNAMELEN + 1];
|
||||
struct utsname kerninfo;
|
||||
char name[LOGIN_NAME_MAX];
|
||||
char dev[] = _PATH_DEV;
|
||||
char ttyn[32];
|
||||
char lockfile[512];
|
||||
uid_t ttyowner;
|
||||
char *rawttyn;
|
||||
|
||||
#define OBUFSIZ 128
|
||||
#define TABBUFSIZ 512
|
||||
|
||||
char defent[TABBUFSIZ];
|
||||
char tabent[TABBUFSIZ];
|
||||
|
||||
char *env[128];
|
||||
|
||||
const unsigned char partab[] = {
|
||||
0001,0201,0201,0001,0201,0001,0001,0201,
|
||||
0202,0004,0003,0205,0005,0206,0201,0001,
|
||||
0201,0001,0001,0201,0001,0201,0201,0001,
|
||||
0001,0201,0201,0001,0201,0001,0001,0201,
|
||||
0200,0000,0000,0200,0000,0200,0200,0000,
|
||||
0000,0200,0200,0000,0200,0000,0000,0200,
|
||||
0000,0200,0200,0000,0200,0000,0000,0200,
|
||||
0200,0000,0000,0200,0000,0200,0200,0000,
|
||||
0200,0000,0000,0200,0000,0200,0200,0000,
|
||||
0000,0200,0200,0000,0200,0000,0000,0200,
|
||||
0000,0200,0200,0000,0200,0000,0000,0200,
|
||||
0200,0000,0000,0200,0000,0200,0200,0000,
|
||||
0000,0200,0200,0000,0200,0000,0000,0200,
|
||||
0200,0000,0000,0200,0000,0200,0200,0000,
|
||||
0200,0000,0000,0200,0000,0200,0200,0000,
|
||||
0000,0200,0200,0000,0200,0000,0000,0201
|
||||
};
|
||||
|
||||
#define ERASE tmode.c_cc[VERASE]
|
||||
#define KILL tmode.c_cc[VKILL]
|
||||
#define EOT tmode.c_cc[VEOF]
|
||||
|
||||
static void clearscreen(void);
|
||||
|
||||
jmp_buf timeout;
|
||||
|
||||
static void
|
||||
/*ARGSUSED*/
|
||||
dingdong(int signo)
|
||||
{
|
||||
|
||||
(void)alarm(0);
|
||||
(void)signal(SIGALRM, SIG_DFL);
|
||||
longjmp(timeout, 1);
|
||||
}
|
||||
|
||||
jmp_buf intrupt;
|
||||
|
||||
static void
|
||||
/*ARGSUSED*/
|
||||
interrupt(int signo)
|
||||
{
|
||||
|
||||
(void)signal(SIGINT, interrupt);
|
||||
longjmp(intrupt, 1);
|
||||
}
|
||||
|
||||
#ifndef __minix
|
||||
/*
|
||||
* Action to take when getty is running too long.
|
||||
*/
|
||||
static void
|
||||
/*ARGSUSED*/
|
||||
timeoverrun(int signo)
|
||||
{
|
||||
|
||||
syslog(LOG_ERR, "getty exiting due to excessive running time");
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int getname(void);
|
||||
static void oflush(void);
|
||||
static void prompt(void);
|
||||
static int putchr(int);
|
||||
static void putf(const char *);
|
||||
static void xputs(const char *);
|
||||
|
||||
#define putpad(s) tputs(s, 1, putchr)
|
||||
|
||||
int
|
||||
main(int argc, char *argv[], char *envp[])
|
||||
{
|
||||
const char *progname;
|
||||
char *tname;
|
||||
int repcnt = 0, failopenlogged = 0, uugetty = 0, first_time = 1;
|
||||
struct rlimit limit;
|
||||
struct passwd *pw;
|
||||
int rval;
|
||||
|
||||
(void)signal(SIGINT, SIG_IGN);
|
||||
openlog("getty", LOG_PID, LOG_AUTH);
|
||||
(void)gethostname(hostname, sizeof(hostname));
|
||||
hostname[sizeof(hostname) - 1] = '\0';
|
||||
if (hostname[0] == '\0')
|
||||
(void)strlcpy(hostname, "Amnesiac", sizeof(hostname));
|
||||
(void)uname(&kerninfo);
|
||||
|
||||
progname = getprogname();
|
||||
if (progname[0] == 'u' && progname[1] == 'u')
|
||||
uugetty = 1;
|
||||
|
||||
/*
|
||||
* Find id of uucp login (if present) so we can chown tty properly.
|
||||
*/
|
||||
if (uugetty && (pw = getpwnam("uucp")))
|
||||
ttyowner = pw->pw_uid;
|
||||
else
|
||||
ttyowner = 0;
|
||||
|
||||
/*
|
||||
* Limit running time to deal with broken or dead lines.
|
||||
*/
|
||||
#ifndef __minix
|
||||
(void)signal(SIGXCPU, timeoverrun);
|
||||
limit.rlim_max = RLIM_INFINITY;
|
||||
limit.rlim_cur = GETTY_TIMEOUT;
|
||||
(void)setrlimit(RLIMIT_CPU, &limit);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 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) {
|
||||
(void)strlcpy(ttyn, ttyname(0), sizeof(ttyn));
|
||||
}
|
||||
else {
|
||||
int i;
|
||||
|
||||
rawttyn = argv[2];
|
||||
(void)strlcpy(ttyn, dev, sizeof(ttyn));
|
||||
(void)strlcat(ttyn, argv[2], sizeof(ttyn));
|
||||
if (uugetty) {
|
||||
(void)chown(ttyn, ttyowner, 0);
|
||||
(void)strlcpy(lockfile, _PATH_LOCK,
|
||||
sizeof(lockfile));
|
||||
(void)strlcat(lockfile, argv[2],
|
||||
sizeof(lockfile));
|
||||
/*
|
||||
* wait for lockfiles to go away before we try
|
||||
* to open
|
||||
*/
|
||||
if (pidlock(lockfile, 0, 0, 0) != 0) {
|
||||
syslog(LOG_ERR,
|
||||
"%s: can't create lockfile", ttyn);
|
||||
exit(1);
|
||||
}
|
||||
(void)unlink(lockfile);
|
||||
}
|
||||
if (strcmp(argv[0], "+") != 0) {
|
||||
(void)chown(ttyn, ttyowner, 0);
|
||||
(void)chmod(ttyn, 0600);
|
||||
#ifndef __minix
|
||||
(void)revoke(ttyn);
|
||||
#endif
|
||||
if (ttyaction(ttyn, "getty", "root"))
|
||||
syslog(LOG_WARNING, "%s: ttyaction failed",
|
||||
ttyn);
|
||||
/*
|
||||
* Delay the open so DTR stays down long enough
|
||||
* to be detected.
|
||||
*/
|
||||
(void)sleep(2);
|
||||
while ((i = open(ttyn, O_RDWR)) == -1) {
|
||||
if ((repcnt % 10 == 0) &&
|
||||
(errno != ENXIO || !failopenlogged)) {
|
||||
syslog(LOG_WARNING, "%s: %m", ttyn);
|
||||
closelog();
|
||||
failopenlogged = 1;
|
||||
}
|
||||
repcnt++;
|
||||
(void)sleep(60);
|
||||
}
|
||||
if (uugetty && pidlock(lockfile, 0, 0, 0) != 0) {
|
||||
syslog(LOG_ERR, "%s: can't create lockfile",
|
||||
ttyn);
|
||||
exit(1);
|
||||
}
|
||||
if (uugetty)
|
||||
(void)chown(lockfile, ttyowner, 0);
|
||||
(void)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;
|
||||
|
||||
rval = 0;
|
||||
gettable(tname, tabent);
|
||||
if (OPset || EPset || APset)
|
||||
APset++, OPset++, EPset++;
|
||||
setdefaults();
|
||||
off = 0;
|
||||
(void)tcflush(0, TCIOFLUSH); /* clear out the crap */
|
||||
#ifndef __minix
|
||||
(void)ioctl(0, FIONBIO, &off); /* turn off non-blocking mode */
|
||||
(void)ioctl(0, FIOASYNC, &off); /* ditto for async mode */
|
||||
#endif
|
||||
|
||||
if (IS)
|
||||
(void)cfsetispeed(&tmode, (speed_t)IS);
|
||||
else if (SP)
|
||||
(void)cfsetispeed(&tmode, (speed_t)SP);
|
||||
if (OS)
|
||||
(void)cfsetospeed(&tmode, (speed_t)OS);
|
||||
else if (SP)
|
||||
(void)cfsetospeed(&tmode, (speed_t)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 (CS)
|
||||
clearscreen();
|
||||
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 != 0 && IF != NULL) {
|
||||
char buf[_POSIX2_LINE_MAX];
|
||||
FILE *fp;
|
||||
|
||||
if ((fp = fopen(IF, "r")) != NULL) {
|
||||
while (fgets(buf, sizeof(buf) - 1, fp) != NULL)
|
||||
putf(buf);
|
||||
(void)fclose(fp);
|
||||
}
|
||||
}
|
||||
first_time = 0;
|
||||
|
||||
if (IM && *IM)
|
||||
putf(IM);
|
||||
oflush();
|
||||
if (setjmp(timeout)) {
|
||||
tmode.c_ispeed = tmode.c_ospeed = 0;
|
||||
(void)tcsetattr(0, TCSANOW, &tmode);
|
||||
exit(1);
|
||||
}
|
||||
if (TO) {
|
||||
(void)signal(SIGALRM, dingdong);
|
||||
(void)alarm((unsigned int)TO);
|
||||
}
|
||||
if (NN) {
|
||||
name[0] = '\0';
|
||||
lower = 1;
|
||||
upper = digit_or_punc = 0;
|
||||
} else if (AL) {
|
||||
const char *p = AL;
|
||||
char *q = name;
|
||||
|
||||
while (*p && q < &name[sizeof name - 1]) {
|
||||
if (isupper((unsigned char)*p))
|
||||
upper = 1;
|
||||
else if (islower((unsigned char)*p))
|
||||
lower = 1;
|
||||
else if (isdigit((unsigned char)*p))
|
||||
digit_or_punc = 1;
|
||||
*q++ = *p++;
|
||||
}
|
||||
} else if ((rval = getname()) == 2) {
|
||||
setflags(2);
|
||||
(void)execle(PP, "ppplogin", ttyn, (char *) 0, env);
|
||||
syslog(LOG_ERR, "%s: %m", PP);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (rval || AL || NN) {
|
||||
int i;
|
||||
|
||||
oflush();
|
||||
(void)alarm(0);
|
||||
(void)signal(SIGALRM, SIG_DFL);
|
||||
if (name[0] == '-') {
|
||||
xputs("user names may not start with '-'.");
|
||||
continue;
|
||||
}
|
||||
if (!(upper || lower || digit_or_punc))
|
||||
continue;
|
||||
setflags(2);
|
||||
if (crmod) {
|
||||
tmode.c_iflag |= ICRNL;
|
||||
tmode.c_oflag |= ONLCR;
|
||||
}
|
||||
#if XXX
|
||||
if (upper || UC)
|
||||
tmode.sg_flags |= LCASE;
|
||||
if (lower || LC)
|
||||
tmode.sg_flags &= ~LCASE;
|
||||
#endif
|
||||
if (tcsetattr(0, TCSANOW, &tmode) < 0) {
|
||||
syslog(LOG_ERR, "%s: %m", ttyn);
|
||||
exit(1);
|
||||
}
|
||||
(void)signal(SIGINT, SIG_DFL);
|
||||
for (i = 0; envp[i] != NULL; i++)
|
||||
env[i] = envp[i];
|
||||
makeenv(&env[i]);
|
||||
|
||||
limit.rlim_max = RLIM_INFINITY;
|
||||
limit.rlim_cur = RLIM_INFINITY;
|
||||
#ifndef __minix
|
||||
(void)setrlimit(RLIMIT_CPU, &limit);
|
||||
#endif
|
||||
if (NN)
|
||||
(void)execle(LO, "login", AL ? "-fp" : "-p",
|
||||
NULL, env);
|
||||
else
|
||||
(void)execle(LO, "login", AL ? "-fp" : "-p",
|
||||
"--", name, NULL, env);
|
||||
syslog(LOG_ERR, "%s: %m", LO);
|
||||
exit(1);
|
||||
}
|
||||
(void)alarm(0);
|
||||
(void)signal(SIGALRM, SIG_DFL);
|
||||
(void)signal(SIGINT, SIG_IGN);
|
||||
if (NX && *NX)
|
||||
tname = NX;
|
||||
if (uugetty)
|
||||
(void)unlink(lockfile);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
getname(void)
|
||||
{
|
||||
int c;
|
||||
char *np;
|
||||
unsigned char cs;
|
||||
int ppp_state, ppp_connection;
|
||||
|
||||
/*
|
||||
* Interrupt may happen if we use CBREAK mode
|
||||
*/
|
||||
if (setjmp(intrupt)) {
|
||||
(void)signal(SIGINT, SIG_IGN);
|
||||
return (0);
|
||||
}
|
||||
(void)signal(SIGINT, interrupt);
|
||||
setflags(1);
|
||||
prompt();
|
||||
if (PF > 0) {
|
||||
oflush();
|
||||
(void)sleep((unsigned int)PF);
|
||||
PF = 0;
|
||||
}
|
||||
if (tcsetattr(0, TCSANOW, &tmode) < 0) {
|
||||
syslog(LOG_ERR, "%s: %m", ttyn);
|
||||
exit(1);
|
||||
}
|
||||
crmod = digit_or_punc = lower = upper = 0;
|
||||
ppp_state = ppp_connection = 0;
|
||||
np = name;
|
||||
for (;;) {
|
||||
oflush();
|
||||
if (read(STDIN_FILENO, &cs, 1) <= 0)
|
||||
exit(0);
|
||||
if ((c = cs&0177) == 0)
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* PPP detection state machine..
|
||||
* Look for sequences:
|
||||
* PPP_FRAME, PPP_STATION, PPP_ESCAPE, PPP_CONTROL_ESCAPED or
|
||||
* PPP_FRAME, PPP_STATION, PPP_CONTROL (deviant from RFC)
|
||||
* See RFC1662.
|
||||
* Derived from code from Michael Hancock <michaelh@cet.co.jp>
|
||||
* and Erik 'PPP' Olson <eriko@wrq.com>
|
||||
*/
|
||||
if (PP && cs == PPP_FRAME) {
|
||||
ppp_state = 1;
|
||||
} else if (ppp_state == 1 && cs == PPP_STATION) {
|
||||
ppp_state = 2;
|
||||
} else if (ppp_state == 2 && cs == PPP_ESCAPE) {
|
||||
ppp_state = 3;
|
||||
} else if ((ppp_state == 2 && cs == PPP_CONTROL) ||
|
||||
(ppp_state == 3 && cs == PPP_CONTROL_ESCAPED)) {
|
||||
ppp_state = 4;
|
||||
} else if (ppp_state == 4 && cs == PPP_LCP_HI) {
|
||||
ppp_state = 5;
|
||||
} else if (ppp_state == 5 && cs == PPP_LCP_LOW) {
|
||||
ppp_connection = 1;
|
||||
break;
|
||||
} else {
|
||||
ppp_state = 0;
|
||||
}
|
||||
|
||||
if (c == EOT)
|
||||
exit(1);
|
||||
if (c == '\r' || c == '\n' ||
|
||||
np >= &name[LOGIN_NAME_MAX - 1]) {
|
||||
*np = '\0';
|
||||
putf("\r\n");
|
||||
break;
|
||||
}
|
||||
if (islower(c))
|
||||
lower = 1;
|
||||
else if (isupper(c))
|
||||
upper = 1;
|
||||
else if (c == ERASE || c == '#' || c == '\b') {
|
||||
if (np > name) {
|
||||
np--;
|
||||
if (cfgetospeed(&tmode) >= 1200)
|
||||
xputs("\b \b");
|
||||
else
|
||||
putchr(cs);
|
||||
}
|
||||
continue;
|
||||
} else if (c == KILL || c == '@') {
|
||||
putchr(cs);
|
||||
putchr('\r');
|
||||
if (cfgetospeed(&tmode) < 1200)
|
||||
putchr('\n');
|
||||
/* this is the way they do it down under ... */
|
||||
else if (np > name)
|
||||
xputs(
|
||||
" \r");
|
||||
prompt();
|
||||
np = name;
|
||||
continue;
|
||||
} else if (isdigit(c) || c == '_')
|
||||
digit_or_punc = 1;
|
||||
if (IG && (c <= ' ' || c > 0176))
|
||||
continue;
|
||||
*np++ = c;
|
||||
putchr(cs);
|
||||
|
||||
/*
|
||||
* An MS-Windows direct connect PPP "client" won't send its
|
||||
* first PPP packet until we respond to its "CLIENT" poll
|
||||
* with a CRLF sequence. We cater to yet another broken
|
||||
* implementation of a previously-standard protocol...
|
||||
*/
|
||||
*np = '\0';
|
||||
if (strstr(name, "CLIENT"))
|
||||
putf("\r\n");
|
||||
}
|
||||
(void)signal(SIGINT, SIG_IGN);
|
||||
*np = 0;
|
||||
if (c == '\r')
|
||||
crmod = 1;
|
||||
if ((upper && !lower && !LC) || UC)
|
||||
for (np = name; *np; np++)
|
||||
*np = tolower((unsigned char)*np);
|
||||
return (1 + ppp_connection);
|
||||
}
|
||||
|
||||
static void
|
||||
xputs(const char *s)
|
||||
{
|
||||
while (*s)
|
||||
putchr(*s++);
|
||||
}
|
||||
|
||||
char outbuf[OBUFSIZ];
|
||||
size_t obufcnt = 0;
|
||||
|
||||
static int
|
||||
putchr(int cc)
|
||||
{
|
||||
unsigned char c;
|
||||
|
||||
c = cc;
|
||||
if (!NP) {
|
||||
c |= partab[c&0177] & 0200;
|
||||
if (OP)
|
||||
c ^= 0200;
|
||||
}
|
||||
if (!UB) {
|
||||
outbuf[obufcnt++] = c;
|
||||
if (obufcnt >= OBUFSIZ)
|
||||
oflush();
|
||||
return 1;
|
||||
}
|
||||
return write(STDOUT_FILENO, &c, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
oflush(void)
|
||||
{
|
||||
if (obufcnt)
|
||||
(void)write(STDOUT_FILENO, outbuf, obufcnt);
|
||||
obufcnt = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
prompt(void)
|
||||
{
|
||||
|
||||
putf(LM);
|
||||
if (CO)
|
||||
putchr('\n');
|
||||
}
|
||||
|
||||
static void
|
||||
putf(const char *cp)
|
||||
{
|
||||
time_t t;
|
||||
char *slash, db[100];
|
||||
|
||||
while (*cp) {
|
||||
if (*cp != '%') {
|
||||
putchr(*cp++);
|
||||
continue;
|
||||
}
|
||||
switch (*++cp) {
|
||||
|
||||
case 't':
|
||||
if ((slash = strstr(ttyn, "/pts/")) == NULL)
|
||||
slash = strrchr(ttyn, '/');
|
||||
if (slash == NULL)
|
||||
xputs(ttyn);
|
||||
else
|
||||
xputs(&slash[1]);
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
xputs(editedhost);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
(void)time(&t);
|
||||
(void)strftime(db, sizeof(db),
|
||||
"%l:%M%p on %A, %d %B %Y", localtime(&t));
|
||||
xputs(db);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
xputs(kerninfo.sysname);
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
xputs(kerninfo.machine);
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
xputs(kerninfo.release);
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
xputs(kerninfo.version);
|
||||
break;
|
||||
|
||||
case '%':
|
||||
putchr('%');
|
||||
break;
|
||||
}
|
||||
if (*cp)
|
||||
cp++;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clearscreen(void)
|
||||
{
|
||||
struct ttyent *typ;
|
||||
int err;
|
||||
|
||||
if (rawttyn == NULL)
|
||||
return;
|
||||
|
||||
typ = getttynam(rawttyn);
|
||||
|
||||
if ((typ == NULL) || (typ->ty_type == NULL) ||
|
||||
(typ->ty_type[0] == 0))
|
||||
return;
|
||||
|
||||
if (setupterm(typ->ty_type, 0, &err) == ERR)
|
||||
return;
|
||||
|
||||
if (clear_screen)
|
||||
putpad(clear_screen);
|
||||
|
||||
del_curterm(cur_term);
|
||||
cur_term = NULL;
|
||||
}
|
37
libexec/getty/pathnames.h
Normal file
37
libexec/getty/pathnames.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/* $NetBSD: pathnames.h,v 1.9 2008/02/04 15:27:20 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
~ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)pathnames.h 8.1 (Berkeley) 6/4/93
|
||||
*/
|
||||
|
||||
#include <paths.h>
|
||||
|
||||
#define _PATH_LOGIN "/usr/bin/login"
|
||||
#define _PATH_LOCK "/var/spool/lock/LCK.."
|
743
libexec/getty/subr.c
Normal file
743
libexec/getty/subr.c
Normal file
|
@ -0,0 +1,743 @@
|
|||
/* $NetBSD: subr.c,v 1.33 2006/11/16 04:31:24 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "from: @(#)subr.c 8.1 (Berkeley) 6/4/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: subr.c,v 1.33 2006/11/16 04:31:24 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
/*
|
||||
* Melbourne getty.
|
||||
*/
|
||||
#ifndef __minix
|
||||
#define COMPAT_43
|
||||
#endif
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#include <poll.h>
|
||||
|
||||
#include "extern.h"
|
||||
#include "gettytab.h"
|
||||
#include "pathnames.h"
|
||||
|
||||
extern struct termios tmode, omode;
|
||||
|
||||
#ifndef __minix
|
||||
static void compatflags(long);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Get a table entry.
|
||||
*/
|
||||
void
|
||||
gettable(char *name, char *buf)
|
||||
{
|
||||
struct gettystrs *sp;
|
||||
struct gettynums *np;
|
||||
struct gettyflags *fp;
|
||||
long n;
|
||||
const char *dba[2];
|
||||
dba[0] = _PATH_GETTYTAB;
|
||||
dba[1] = 0;
|
||||
|
||||
if (cgetent(&buf, dba, name) != 0)
|
||||
return;
|
||||
|
||||
for (sp = gettystrs; sp->field; sp++)
|
||||
(void)cgetstr(buf, sp->field, &sp->value);
|
||||
for (np = gettynums; np->field; np++) {
|
||||
if (cgetnum(buf, np->field, &n) == -1)
|
||||
np->set = 0;
|
||||
else {
|
||||
np->set = 1;
|
||||
np->value = n;
|
||||
}
|
||||
}
|
||||
for (fp = gettyflags; fp->field; fp++) {
|
||||
if (cgetcap(buf, fp->field, ':') == NULL)
|
||||
fp->set = 0;
|
||||
else {
|
||||
fp->set = 1;
|
||||
fp->value = 1 ^ fp->invrt;
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
printf("name=\"%s\", buf=\"%s\"\n", name, buf);
|
||||
for (sp = gettystrs; sp->field; sp++)
|
||||
printf("cgetstr: %s=%s\n", sp->field, sp->value);
|
||||
for (np = gettynums; np->field; np++)
|
||||
printf("cgetnum: %s=%d\n", np->field, np->value);
|
||||
for (fp = gettyflags; fp->field; fp++)
|
||||
printf("cgetflags: %s='%c' set='%c'\n", fp->field,
|
||||
fp->value + '0', fp->set + '0');
|
||||
exit(1);
|
||||
#endif /* DEBUG */
|
||||
}
|
||||
|
||||
void
|
||||
gendefaults(void)
|
||||
{
|
||||
struct gettystrs *sp;
|
||||
struct gettynums *np;
|
||||
struct gettyflags *fp;
|
||||
|
||||
for (sp = gettystrs; sp->field; sp++)
|
||||
if (sp->value)
|
||||
sp->defalt = sp->value;
|
||||
for (np = gettynums; np->field; np++)
|
||||
if (np->set)
|
||||
np->defalt = np->value;
|
||||
for (fp = gettyflags; fp->field; fp++)
|
||||
if (fp->set)
|
||||
fp->defalt = fp->value;
|
||||
else
|
||||
fp->defalt = fp->invrt;
|
||||
}
|
||||
|
||||
void
|
||||
setdefaults(void)
|
||||
{
|
||||
struct gettystrs *sp;
|
||||
struct gettynums *np;
|
||||
struct gettyflags *fp;
|
||||
|
||||
for (sp = gettystrs; sp->field; sp++)
|
||||
if (!sp->value)
|
||||
sp->value = sp->defalt;
|
||||
for (np = gettynums; np->field; np++)
|
||||
if (!np->set)
|
||||
np->value = np->defalt;
|
||||
for (fp = gettyflags; fp->field; fp++)
|
||||
if (!fp->set)
|
||||
fp->value = fp->defalt;
|
||||
}
|
||||
|
||||
static char **
|
||||
charnames[] = {
|
||||
&ER, &KL, &IN, &QU, &XN, &XF, &ET, &BK,
|
||||
&SU, &DS, &RP, &FL, &WE, &LN, &ST, &B2, 0
|
||||
};
|
||||
|
||||
static cc_t *
|
||||
charvars[] = {
|
||||
&tmode.c_cc[VERASE], &tmode.c_cc[VKILL], &tmode.c_cc[VINTR],
|
||||
&tmode.c_cc[VQUIT], &tmode.c_cc[VSTART], &tmode.c_cc[VSTOP],
|
||||
&tmode.c_cc[VEOF], &tmode.c_cc[VEOL], &tmode.c_cc[VSUSP],
|
||||
&tmode.c_cc[VDSUSP], &tmode.c_cc[VREPRINT], &tmode.c_cc[VDISCARD],
|
||||
&tmode.c_cc[VWERASE], &tmode.c_cc[VLNEXT], &tmode.c_cc[VSTATUS],
|
||||
&tmode.c_cc[VEOL2], 0
|
||||
};
|
||||
|
||||
void
|
||||
setchars(void)
|
||||
{
|
||||
int i;
|
||||
char *p;
|
||||
|
||||
for (i = 0; charnames[i]; i++) {
|
||||
p = *charnames[i];
|
||||
if (p && *p)
|
||||
*charvars[i] = *p;
|
||||
else
|
||||
*charvars[i] = _POSIX_VDISABLE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Macros to clear/set/test flags. */
|
||||
#define SET(t, f) (t) |= (f)
|
||||
#define CLR(t, f) (t) &= ~(f)
|
||||
#define ISSET(t, f) ((t) & (f))
|
||||
|
||||
void
|
||||
setflags(int n)
|
||||
{
|
||||
tcflag_t iflag, oflag, cflag, lflag;
|
||||
|
||||
#ifdef COMPAT_43
|
||||
switch (n) {
|
||||
case 0:
|
||||
if (F0set) {
|
||||
compatflags(F0);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (F1set) {
|
||||
compatflags(F1);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (F2set) {
|
||||
compatflags(F2);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (n) {
|
||||
case 0:
|
||||
if (C0set && I0set && L0set && O0set) {
|
||||
tmode.c_cflag = C0;
|
||||
tmode.c_iflag = I0;
|
||||
tmode.c_lflag = L0;
|
||||
tmode.c_oflag = O0;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (C1set && I1set && L1set && O1set) {
|
||||
tmode.c_cflag = C1;
|
||||
tmode.c_iflag = I1;
|
||||
tmode.c_lflag = L1;
|
||||
tmode.c_oflag = O1;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (C2set && I2set && L2set && O2set) {
|
||||
tmode.c_cflag = C2;
|
||||
tmode.c_iflag = I2;
|
||||
tmode.c_lflag = L2;
|
||||
tmode.c_oflag = O2;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
iflag = omode.c_iflag;
|
||||
oflag = omode.c_oflag;
|
||||
cflag = omode.c_cflag;
|
||||
lflag = omode.c_lflag;
|
||||
|
||||
if (NP) {
|
||||
CLR(cflag, CSIZE|PARENB);
|
||||
SET(cflag, CS8);
|
||||
CLR(iflag, ISTRIP|INPCK|IGNPAR);
|
||||
} else if (AP || EP || OP) {
|
||||
CLR(cflag, CSIZE);
|
||||
SET(cflag, CS7|PARENB);
|
||||
SET(iflag, ISTRIP);
|
||||
if (OP && !EP) {
|
||||
SET(iflag, INPCK|IGNPAR);
|
||||
SET(cflag, PARODD);
|
||||
if (AP)
|
||||
CLR(iflag, INPCK);
|
||||
} else if (EP && !OP) {
|
||||
SET(iflag, INPCK|IGNPAR);
|
||||
CLR(cflag, PARODD);
|
||||
if (AP)
|
||||
CLR(iflag, INPCK);
|
||||
} else if (AP || (EP && OP)) {
|
||||
CLR(iflag, INPCK|IGNPAR);
|
||||
CLR(cflag, PARODD);
|
||||
}
|
||||
} /* else, leave as is */
|
||||
|
||||
#if 0
|
||||
if (UC)
|
||||
f |= LCASE;
|
||||
#endif
|
||||
|
||||
if (HC)
|
||||
SET(cflag, HUPCL);
|
||||
else
|
||||
CLR(cflag, HUPCL);
|
||||
|
||||
#ifndef __minix
|
||||
if (MB)
|
||||
SET(cflag, MDMBUF);
|
||||
else
|
||||
CLR(cflag, MDMBUF);
|
||||
#endif
|
||||
|
||||
if (NL) {
|
||||
SET(iflag, ICRNL);
|
||||
SET(oflag, ONLCR|OPOST);
|
||||
} else {
|
||||
CLR(iflag, ICRNL);
|
||||
CLR(oflag, ONLCR);
|
||||
}
|
||||
|
||||
#ifndef __minix
|
||||
if (!HT)
|
||||
SET(oflag, OXTABS|OPOST);
|
||||
else
|
||||
CLR(oflag, OXTABS);
|
||||
#endif
|
||||
|
||||
#ifdef XXX_DELAY
|
||||
SET(f, delaybits());
|
||||
#endif
|
||||
|
||||
if (n == 1) { /* read mode flags */
|
||||
if (RW) {
|
||||
iflag = 0;
|
||||
CLR(oflag, OPOST);
|
||||
CLR(cflag, CSIZE|PARENB);
|
||||
SET(cflag, CS8);
|
||||
lflag = 0;
|
||||
} else {
|
||||
CLR(lflag, ICANON);
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (n == 0)
|
||||
goto out;
|
||||
|
||||
#if 0
|
||||
if (CB)
|
||||
SET(f, CRTBS);
|
||||
#endif
|
||||
|
||||
if (CE)
|
||||
SET(lflag, ECHOE);
|
||||
else
|
||||
CLR(lflag, ECHOE);
|
||||
|
||||
#ifndef __minix
|
||||
if (CK)
|
||||
SET(lflag, ECHOKE);
|
||||
else
|
||||
CLR(lflag, ECHOKE);
|
||||
|
||||
if (PE)
|
||||
SET(lflag, ECHOPRT);
|
||||
else
|
||||
CLR(lflag, ECHOPRT);
|
||||
#endif
|
||||
|
||||
if (EC)
|
||||
SET(lflag, ECHO);
|
||||
else
|
||||
CLR(lflag, ECHO);
|
||||
|
||||
#ifndef __minix
|
||||
if (XC)
|
||||
SET(lflag, ECHOCTL);
|
||||
else
|
||||
CLR(lflag, ECHOCTL);
|
||||
#endif
|
||||
|
||||
if (DX)
|
||||
SET(lflag, IXANY);
|
||||
else
|
||||
CLR(lflag, IXANY);
|
||||
|
||||
out:
|
||||
tmode.c_iflag = iflag;
|
||||
tmode.c_oflag = oflag;
|
||||
tmode.c_cflag = cflag;
|
||||
tmode.c_lflag = lflag;
|
||||
}
|
||||
|
||||
#ifdef COMPAT_43
|
||||
/*
|
||||
* Old TTY => termios, snatched from <sys/kern/tty_compat.c>
|
||||
*/
|
||||
void
|
||||
compatflags(long flags)
|
||||
{
|
||||
tcflag_t iflag, oflag, cflag, lflag;
|
||||
|
||||
iflag = BRKINT|ICRNL|IMAXBEL|IXON|IXANY;
|
||||
oflag = OPOST|ONLCR|OXTABS;
|
||||
cflag = CREAD;
|
||||
lflag = ICANON|ISIG|IEXTEN;
|
||||
|
||||
if (ISSET(flags, TANDEM))
|
||||
SET(iflag, IXOFF);
|
||||
else
|
||||
CLR(iflag, IXOFF);
|
||||
if (ISSET(flags, ECHO))
|
||||
SET(lflag, ECHO);
|
||||
else
|
||||
CLR(lflag, ECHO);
|
||||
if (ISSET(flags, CRMOD)) {
|
||||
SET(iflag, ICRNL);
|
||||
SET(oflag, ONLCR);
|
||||
} else {
|
||||
CLR(iflag, ICRNL);
|
||||
CLR(oflag, ONLCR);
|
||||
}
|
||||
if (ISSET(flags, XTABS))
|
||||
SET(oflag, OXTABS);
|
||||
else
|
||||
CLR(oflag, OXTABS);
|
||||
|
||||
|
||||
if (ISSET(flags, RAW)) {
|
||||
iflag &= IXOFF;
|
||||
CLR(lflag, ISIG|ICANON|IEXTEN);
|
||||
CLR(cflag, PARENB);
|
||||
} else {
|
||||
SET(iflag, BRKINT|IXON|IMAXBEL);
|
||||
SET(lflag, ISIG|IEXTEN);
|
||||
if (ISSET(flags, CBREAK))
|
||||
CLR(lflag, ICANON);
|
||||
else
|
||||
SET(lflag, ICANON);
|
||||
switch (ISSET(flags, ANYP)) {
|
||||
case 0:
|
||||
CLR(cflag, PARENB);
|
||||
break;
|
||||
case ANYP:
|
||||
SET(cflag, PARENB);
|
||||
CLR(iflag, INPCK);
|
||||
break;
|
||||
case EVENP:
|
||||
SET(cflag, PARENB);
|
||||
SET(iflag, INPCK);
|
||||
CLR(cflag, PARODD);
|
||||
break;
|
||||
case ODDP:
|
||||
SET(cflag, PARENB);
|
||||
SET(iflag, INPCK);
|
||||
SET(cflag, PARODD);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Nothing we can do with CRTBS. */
|
||||
if (ISSET(flags, PRTERA))
|
||||
SET(lflag, ECHOPRT);
|
||||
else
|
||||
CLR(lflag, ECHOPRT);
|
||||
if (ISSET(flags, CRTERA))
|
||||
SET(lflag, ECHOE);
|
||||
else
|
||||
CLR(lflag, ECHOE);
|
||||
#ifndef __minix
|
||||
/* Nothing we can do with TILDE. */
|
||||
if (ISSET(flags, MDMBUF))
|
||||
SET(cflag, MDMBUF);
|
||||
else
|
||||
CLR(cflag, MDMBUF);
|
||||
#endif
|
||||
if (ISSET(flags, NOHANG))
|
||||
CLR(cflag, HUPCL);
|
||||
else
|
||||
SET(cflag, HUPCL);
|
||||
|
||||
#ifndef __minix
|
||||
if (ISSET(flags, CRTKIL))
|
||||
SET(lflag, ECHOKE);
|
||||
else
|
||||
CLR(lflag, ECHOKE);
|
||||
#endif
|
||||
|
||||
if (ISSET(flags, CTLECH))
|
||||
SET(lflag, ECHOCTL);
|
||||
else
|
||||
CLR(lflag, ECHOCTL);
|
||||
if (!ISSET(flags, DECCTQ))
|
||||
SET(iflag, IXANY);
|
||||
else
|
||||
CLR(iflag, IXANY);
|
||||
CLR(lflag, TOSTOP|FLUSHO|PENDIN|NOFLSH);
|
||||
SET(lflag, ISSET(flags, TOSTOP|FLUSHO|PENDIN|NOFLSH));
|
||||
|
||||
if (ISSET(flags, RAW|LITOUT|PASS8)) {
|
||||
CLR(cflag, CSIZE);
|
||||
SET(cflag, CS8);
|
||||
if (!ISSET(flags, RAW|PASS8))
|
||||
SET(iflag, ISTRIP);
|
||||
else
|
||||
CLR(iflag, ISTRIP);
|
||||
if (!ISSET(flags, RAW|LITOUT))
|
||||
SET(oflag, OPOST);
|
||||
else
|
||||
CLR(oflag, OPOST);
|
||||
} else {
|
||||
CLR(cflag, CSIZE);
|
||||
SET(cflag, CS7);
|
||||
SET(iflag, ISTRIP);
|
||||
SET(oflag, OPOST);
|
||||
}
|
||||
|
||||
tmode.c_iflag = iflag;
|
||||
tmode.c_oflag = oflag;
|
||||
tmode.c_cflag = cflag;
|
||||
tmode.c_lflag = lflag;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef XXX_DELAY
|
||||
struct delayval {
|
||||
unsigned delay; /* delay in ms */
|
||||
int bits;
|
||||
};
|
||||
|
||||
/*
|
||||
* below are random guesses, I can't be bothered checking
|
||||
*/
|
||||
|
||||
struct delayval crdelay[] = {
|
||||
{ 1, CR1 },
|
||||
{ 2, CR2 },
|
||||
{ 3, CR3 },
|
||||
{ 83, CR1 },
|
||||
{ 166, CR2 },
|
||||
{ 0, CR3 },
|
||||
};
|
||||
|
||||
struct delayval nldelay[] = {
|
||||
{ 1, NL1 }, /* special, calculated */
|
||||
{ 2, NL2 },
|
||||
{ 3, NL3 },
|
||||
{ 100, NL2 },
|
||||
{ 0, NL3 },
|
||||
};
|
||||
|
||||
struct delayval bsdelay[] = {
|
||||
{ 1, BS1 },
|
||||
{ 0, 0 },
|
||||
};
|
||||
|
||||
struct delayval ffdelay[] = {
|
||||
{ 1, FF1 },
|
||||
{ 1750, FF1 },
|
||||
{ 0, FF1 },
|
||||
};
|
||||
|
||||
struct delayval tbdelay[] = {
|
||||
{ 1, TAB1 },
|
||||
{ 2, TAB2 },
|
||||
{ 3, XTABS }, /* this is expand tabs */
|
||||
{ 100, TAB1 },
|
||||
{ 0, TAB2 },
|
||||
};
|
||||
|
||||
int
|
||||
delaybits(void)
|
||||
{
|
||||
int f;
|
||||
|
||||
f = adelay(CD, crdelay);
|
||||
f |= adelay(ND, nldelay);
|
||||
f |= adelay(FD, ffdelay);
|
||||
f |= adelay(TD, tbdelay);
|
||||
f |= adelay(BD, bsdelay);
|
||||
return (f);
|
||||
}
|
||||
|
||||
int
|
||||
adelay(int ms, struct delayval *dp)
|
||||
{
|
||||
if (ms == 0)
|
||||
return (0);
|
||||
while (dp->delay && ms > dp->delay)
|
||||
dp++;
|
||||
return (dp->bits);
|
||||
}
|
||||
#endif
|
||||
|
||||
char editedhost[MAXHOSTNAMELEN];
|
||||
|
||||
void
|
||||
edithost(char *pat)
|
||||
{
|
||||
char *host = HN;
|
||||
char *res = editedhost;
|
||||
|
||||
if (!pat)
|
||||
pat = "";
|
||||
while (*pat) {
|
||||
switch (*pat) {
|
||||
|
||||
case '#':
|
||||
if (*host)
|
||||
host++;
|
||||
break;
|
||||
|
||||
case '@':
|
||||
if (*host)
|
||||
*res++ = *host++;
|
||||
break;
|
||||
|
||||
default:
|
||||
*res++ = *pat;
|
||||
break;
|
||||
|
||||
}
|
||||
if (res == &editedhost[sizeof editedhost - 1]) {
|
||||
*res = '\0';
|
||||
return;
|
||||
}
|
||||
pat++;
|
||||
}
|
||||
if (*host)
|
||||
(void)strncpy(res, host,
|
||||
sizeof editedhost - (res - editedhost) - 1);
|
||||
else
|
||||
*res = '\0';
|
||||
editedhost[sizeof editedhost - 1] = '\0';
|
||||
}
|
||||
|
||||
void
|
||||
makeenv(char *env[])
|
||||
{
|
||||
static char termbuf[128] = "TERM=";
|
||||
char *p, *q;
|
||||
char **ep;
|
||||
|
||||
ep = env;
|
||||
if (TT && *TT) {
|
||||
(void)strlcat(termbuf, TT, sizeof(termbuf));
|
||||
*ep++ = termbuf;
|
||||
}
|
||||
if ((p = EV) != NULL) {
|
||||
q = p;
|
||||
while ((q = strchr(q, ',')) != NULL) {
|
||||
*q++ = '\0';
|
||||
*ep++ = p;
|
||||
p = q;
|
||||
}
|
||||
if (*p)
|
||||
*ep++ = p;
|
||||
}
|
||||
*ep = (char *)0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This speed select mechanism is written for the Develcon DATASWITCH.
|
||||
* The Develcon sends a string of the form "B{speed}\n" at a predefined
|
||||
* baud rate. This string indicates the user's actual speed.
|
||||
* The routine below returns the terminal type mapped from derived speed.
|
||||
*/
|
||||
struct portselect {
|
||||
char *ps_baud;
|
||||
char *ps_type;
|
||||
} portspeeds[] = {
|
||||
{ "B110", "std.110" },
|
||||
{ "B134", "std.134" },
|
||||
{ "B150", "std.150" },
|
||||
{ "B300", "std.300" },
|
||||
{ "B600", "std.600" },
|
||||
{ "B1200", "std.1200" },
|
||||
{ "B2400", "std.2400" },
|
||||
{ "B4800", "std.4800" },
|
||||
{ "B9600", "std.9600" },
|
||||
{ "B19200", "std.19200" },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
char *
|
||||
portselector(void)
|
||||
{
|
||||
char c, baud[20], *type = "default";
|
||||
struct portselect *ps;
|
||||
int len;
|
||||
|
||||
(void)alarm(5*60);
|
||||
for (len = 0; len < sizeof (baud) - 1; len++) {
|
||||
if (read(STDIN_FILENO, &c, 1) <= 0)
|
||||
break;
|
||||
c &= 0177;
|
||||
if (c == '\n' || c == '\r')
|
||||
break;
|
||||
if (c == 'B')
|
||||
len = 0; /* in case of leading garbage */
|
||||
baud[len] = c;
|
||||
}
|
||||
baud[len] = '\0';
|
||||
for (ps = portspeeds; ps->ps_baud; ps++)
|
||||
if (strcmp(ps->ps_baud, baud) == 0) {
|
||||
type = ps->ps_type;
|
||||
break;
|
||||
}
|
||||
(void)sleep(2); /* wait for connection to complete */
|
||||
return (type);
|
||||
}
|
||||
|
||||
/*
|
||||
* This auto-baud speed select mechanism is written for the Micom 600
|
||||
* portselector. Selection is done by looking at how the character '\r'
|
||||
* is garbled at the different speeds.
|
||||
*/
|
||||
#include <sys/time.h>
|
||||
|
||||
char *
|
||||
autobaud(void)
|
||||
{
|
||||
struct pollfd set[1];
|
||||
struct timespec timeout;
|
||||
char c, *type = "9600-baud";
|
||||
|
||||
(void)tcflush(0, TCIOFLUSH);
|
||||
set[0].fd = STDIN_FILENO;
|
||||
set[0].events = POLLIN;
|
||||
if (poll(set, 1, 5000) <= 0)
|
||||
return (type);
|
||||
if (read(STDIN_FILENO, &c, 1) != 1)
|
||||
return (type);
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_nsec = 20000;
|
||||
(void)nanosleep(&timeout, NULL);
|
||||
(void)tcflush(0, TCIOFLUSH);
|
||||
switch (c & 0377) {
|
||||
|
||||
case 0200: /* 300-baud */
|
||||
type = "300-baud";
|
||||
break;
|
||||
|
||||
case 0346: /* 1200-baud */
|
||||
type = "1200-baud";
|
||||
break;
|
||||
|
||||
case 015: /* 2400-baud */
|
||||
case 0215:
|
||||
type = "2400-baud";
|
||||
break;
|
||||
|
||||
default: /* 4800-baud */
|
||||
type = "4800-baud";
|
||||
break;
|
||||
|
||||
case 0377: /* 9600-baud */
|
||||
type = "9600-baud";
|
||||
break;
|
||||
}
|
||||
return (type);
|
||||
}
|
227
libexec/getty/ttys.5
Normal file
227
libexec/getty/ttys.5
Normal file
|
@ -0,0 +1,227 @@
|
|||
.\" $NetBSD: ttys.5,v 1.18 2012/04/21 12:27:28 roy Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1985, 1991, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" from: @(#)ttys.5 8.1 (Berkeley) 6/4/93
|
||||
.\"
|
||||
.Dd April 5, 2012
|
||||
.Dt TTYS 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm ttys
|
||||
.Nd terminal initialization information
|
||||
.Sh DESCRIPTION
|
||||
The file
|
||||
.Nm
|
||||
contains information that is used by various routines to initialize
|
||||
and control the use of terminal special files.
|
||||
This information is read with the
|
||||
.Xr getttyent 3
|
||||
library routines.
|
||||
.Pp
|
||||
There is one line in the
|
||||
.Nm
|
||||
file per special device file.
|
||||
Fields are separated by tabs and/or spaces.
|
||||
Fields comprising more than one word should be enclosed in double
|
||||
quotes (``"'').
|
||||
Blank lines and comments may appear anywhere in the file; comments
|
||||
are delimited by hash marks (``#'') and new lines.
|
||||
Any unspecified fields will default to null.
|
||||
.Pp
|
||||
Each line in
|
||||
.Nm
|
||||
has the format:
|
||||
.Dl tty command type flags
|
||||
.Pp
|
||||
The first field is the
|
||||
name of the terminal special file as it is found in
|
||||
.Pa /dev .
|
||||
.Pp
|
||||
The second field of the file is the command to execute for the line,
|
||||
usually
|
||||
.Xr getty 8 ,
|
||||
which initializes and opens the line, setting the speed, waiting for
|
||||
a user name and executing the
|
||||
.Xr login 1
|
||||
program.
|
||||
However, it can be any desired command, for example the start up
|
||||
for a window system terminal emulator or some other daemon process,
|
||||
and can contain multiple words if quoted.
|
||||
.Pp
|
||||
The third field is the type of terminal usually connected to that
|
||||
tty line, normally the one found in the
|
||||
.Xr terminfo 5
|
||||
data base file.
|
||||
The environment variable
|
||||
.Dv TERM
|
||||
is initialized with the value by either
|
||||
.Xr getty 8
|
||||
or
|
||||
.Xr login 1 .
|
||||
.Pp
|
||||
The remaining fields set flags in the
|
||||
.Fa ty_status
|
||||
entry (see
|
||||
.Xr getttyent 3 )
|
||||
or specify a window system process that
|
||||
.Xr init 8
|
||||
will maintain for the terminal line
|
||||
or a key into a database of tty attributes (currently unused).
|
||||
.Pp
|
||||
.Bl -tag -width softcar
|
||||
.It Sy on No or Sy off
|
||||
.Xr init 8
|
||||
should (or should not) execute the command given in the second field.
|
||||
.It Sy secure
|
||||
If
|
||||
.Sy on
|
||||
is specified, allows users with a uid of 0
|
||||
.Pq e.g. Qq root
|
||||
to login on this line.
|
||||
.It Sy local
|
||||
Sets the
|
||||
.Dv TIOCFLAG_CLOCAL
|
||||
.Xr tty 4
|
||||
flag for the device.
|
||||
This will cause the
|
||||
.Xr termios 4
|
||||
.Dv CLOCAL
|
||||
flag to be set on every open and thus modem control signal lines will be
|
||||
ignored by default.
|
||||
.It Sy softcar
|
||||
Causes the driver to ignore hardware carrier on the line (by setting the
|
||||
.Dv TIOCFLAG_SOFTCAR
|
||||
.Xr tty 4
|
||||
flag).
|
||||
.It Sy rtscts
|
||||
Sets the
|
||||
.Dv TIOCFLAG_CRTSCTS
|
||||
.Xr tty 4
|
||||
flag for the device to enable
|
||||
.Tn RTS /
|
||||
.Tn CTS
|
||||
.Qq hardware
|
||||
flow control by default.
|
||||
.It Sy mdmbuf
|
||||
Sets the
|
||||
.Dv TIOCFLAG_MDMBUF
|
||||
.Xr tty 4
|
||||
flag for the device to enable
|
||||
.Tn DTR /
|
||||
.Tn DCD
|
||||
.Qq hardware
|
||||
flow control by default.
|
||||
.El
|
||||
.Pp
|
||||
The flags
|
||||
.Qq local ,
|
||||
.Qq rtscts ,
|
||||
.Qq mdmbuf ,
|
||||
and
|
||||
.Qq softcar
|
||||
modify the default behaviour of the terminal line, and their actions
|
||||
are device driver dependent.
|
||||
These flag fields should not be quoted.
|
||||
.Pp
|
||||
The string ``window='' may be followed by a quoted command
|
||||
string which
|
||||
.Xr init 8
|
||||
will execute
|
||||
.Em before
|
||||
starting the command specified by the second field.
|
||||
.Pp
|
||||
The string ``class='' may be followed by a quoted string used
|
||||
as a key into a database of attributes for that category of tty.
|
||||
See
|
||||
.Xr getttynam 3
|
||||
for more information on this feature.
|
||||
.Pp
|
||||
After changing the
|
||||
.Nm
|
||||
file a
|
||||
.Dv SIGHUP
|
||||
signal can be sent to
|
||||
.Xr init 8
|
||||
with the command
|
||||
.Dq Li "kill \-s HUP 1" .
|
||||
On receipt of this signal,
|
||||
.Xr init 8
|
||||
will re-read the
|
||||
.Nm
|
||||
file and spawn any necessary
|
||||
.Xr getty 8
|
||||
processes.
|
||||
.Pp
|
||||
.Sy Nota Bene :
|
||||
Sending
|
||||
.Dv SIGHUP
|
||||
to
|
||||
.Xr init 8
|
||||
does
|
||||
.Em not
|
||||
change the state of the various
|
||||
.Xr tty 4
|
||||
device flags listed above; the
|
||||
.Xr ttyflags 8
|
||||
program must be run for changes in those flags to take effect on the devices.
|
||||
.Sh FILES
|
||||
.Bl -tag -width /etc/ttys -compact
|
||||
.It Pa /etc/ttys
|
||||
.El
|
||||
.Sh EXAMPLES
|
||||
.Bd -literal
|
||||
# root login on console at 1200 baud
|
||||
console "/usr/libexec/getty std.1200" vt100 on secure
|
||||
# dialup at 1200 baud, no root logins
|
||||
ttyd0 "/usr/libexec/getty d1200" dialup on # 555-1234
|
||||
# Mike's terminal: hp2621
|
||||
ttyh0 "/usr/libexec/getty std.9600" hp2621-nl on # 457 Evans
|
||||
# John's terminal: vt100
|
||||
ttyh1 "/usr/libexec/getty std.9600" vt100 on # 459 Evans
|
||||
# terminal emulate/window system
|
||||
ttyv0 "/usr/new/xterm -L :0" vs100 on window="/usr/new/Xvs100 0"
|
||||
# Network pseudo ttys -- don't enable getty
|
||||
ttyp0 none network
|
||||
ttyp1 none network off
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.Xr login 1 ,
|
||||
.Xr getttyent 3 ,
|
||||
.Xr ttyslot 3 ,
|
||||
.Xr tty 4 ,
|
||||
.Xr gettytab 5 ,
|
||||
.Xr terminfo 5 ,
|
||||
.Xr getty 8 ,
|
||||
.Xr init 8 ,
|
||||
.Xr ttyflags 8
|
||||
.Sh HISTORY
|
||||
A
|
||||
.Nm
|
||||
file appeared in
|
||||
.At v6 .
|
|
@ -8,7 +8,7 @@ MAN= ash.1 at.1 \
|
|||
flexdoc.1 format.1 fortune.1 \
|
||||
fsck.mfs.1 host.1 hostaddr.1 ifdef.1 \
|
||||
isodir.1 isoinfo.1 isoread.1 \
|
||||
last.1 loadfont.1 loadkeys.1 logger.1 \
|
||||
loadfont.1 loadkeys.1 logger.1 \
|
||||
look.1 lp.1 lspci.1 mail.1 \
|
||||
mixer.1 \
|
||||
mkproto.1 mount.1 mt.1 \
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
.TH LAST 1
|
||||
.SH NAME
|
||||
last, uptime \- display recent on-line session records, show uptime
|
||||
.SH SYNOPSIS
|
||||
\fBlast\fR [\fB\-f \fIfile\fR]\fR [\fB\-r\fR] [\fB\-\fIn\fR] [\fIname\fR] [\fItty\fR] ...\fR
|
||||
.br
|
||||
\fBuptime\fR
|
||||
.br
|
||||
.de FL
|
||||
.TP
|
||||
\\fB\\$1\\fR
|
||||
\\$2
|
||||
..
|
||||
.de EX
|
||||
.TP 20
|
||||
\\fB\\$1\\fR
|
||||
# \\$2
|
||||
..
|
||||
.SH OPTIONS
|
||||
.TP 5
|
||||
.B \-f
|
||||
# Use \fIfile\fR instead of /usr/adm/wtmp
|
||||
.TP 5
|
||||
.B \-r
|
||||
# Search backwards only to last reboot
|
||||
.TP 5
|
||||
.B \-u
|
||||
# Print uptime since last reboot
|
||||
.TP 5
|
||||
.B \-\fIn\fP
|
||||
# Print a maximum of \fIn\fR lines
|
||||
.SH EXAMPLES
|
||||
.TP 20
|
||||
.B last reboot
|
||||
# When was the system last rebooted?
|
||||
.TP 20
|
||||
.B last ast
|
||||
# When was the last login for ast?
|
||||
.TP 20
|
||||
.B last \-10 tty00 tty01
|
||||
# Display last 10 logins on tty00 or tty01
|
||||
.TP 20
|
||||
.B uptime
|
||||
# Display uptime (likewise \fBlast \-u\fR)
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
.I Last
|
||||
Searches backward through the login administration file (default is
|
||||
\fI/usr/adm/wtmp\fR), printing information about previous logins and
|
||||
reboots.
|
||||
During a long search, the SIGQUIT signal (CTRL-\\) causes \fIlast\fR to
|
||||
display how far back it has gone; it then continues.
|
||||
.PP
|
||||
.IR Uptime ,
|
||||
an alias for
|
||||
.IR "last \-u" ,
|
||||
displays the time the system is running since the last reboot.
|
||||
.SH "SEE ALSO"
|
||||
.BR who (1),
|
||||
.BR utmp (5).
|
|
@ -4,7 +4,7 @@ MAN= accept.2 access.2 bind.2 brk.2 chdir.2 chmod.2 chown.2 \
|
|||
getpeername.2 getpid.2 getpriority.2 getsockname.2 getsockopt.2 \
|
||||
gettimeofday.2 getuid.2 intro.2 ioctl.2 kill.2 link.2 listen.2 \
|
||||
lseek.2 mkdir.2 mknod.2 mount.2 open.2 ptrace.2 \
|
||||
read.2 readlink.2 reboot.2 recv.2 recvfrom.2 recvmsg.2 rename.2 \
|
||||
read.2 readlink.2 recv.2 recvfrom.2 recvmsg.2 rename.2 \
|
||||
rmdir.2 select.2 send.2 sendmsg.2 sendto.2 setsid.2 \
|
||||
setsockopt.2 setuid.2 shutdown.2 sigaction.2 sigpending.2 \
|
||||
sigprocmask.2 sigsuspend.2 socket.2 socketpair.2 \
|
||||
|
|
|
@ -1,51 +0,0 @@
|
|||
.TH REBOOT 2
|
||||
.SH NAME
|
||||
reboot \- close down the system or reboot
|
||||
.SH SYNTAX
|
||||
.ft B
|
||||
.nf
|
||||
#include <minix/reboot.h>
|
||||
|
||||
int reboot(int \fIhow\fP)
|
||||
.fi
|
||||
.ft P
|
||||
.SH DESCRIPTION
|
||||
.B Reboot()
|
||||
is used to close down the system. It allows several ways of shutting
|
||||
down depending on
|
||||
.IR how :
|
||||
.PP
|
||||
.TP 5
|
||||
.BI "reboot(RBT_DEFAULT)"
|
||||
Default shut-down action, the same as used when CTRL+ALT+DEL is pressed
|
||||
on the keyboard.
|
||||
.TP
|
||||
.BI "reboot(RBT_HALT)"
|
||||
Halt the system.
|
||||
.TP
|
||||
.BI "reboot(RBT_PANIC)"
|
||||
Cause a system panic. This is not normally done from user mode.
|
||||
.TP
|
||||
.BI "reboot(RBT_POWEROFF)"
|
||||
Power off the system if possible, reset otherwise.
|
||||
.TP
|
||||
.BI "reboot(RBT_REBOOT)"
|
||||
Reboot the system with a software reset (currently not supported, so
|
||||
a hardware reset is used).
|
||||
.TP
|
||||
.BI "reboot(RBT_RESET)"
|
||||
Reboot the system with a hardware reset.
|
||||
.PP
|
||||
.B Reboot()
|
||||
may only be executed by the super-user.
|
||||
.SH DIAGNOSTICS
|
||||
If the call succeeds, it never returns. If something went wrong,
|
||||
the return value is -1 and an error is indicated by
|
||||
.BR errno .
|
||||
.SH SEE ALSO
|
||||
.BR shutdown (8),
|
||||
.BR reboot (8),
|
||||
.BR halt (8),
|
||||
.BR sync (2).
|
||||
.SH AUTHOR
|
||||
Edvard Tuinder (v892231@si.hhs.NL)
|
|
@ -5,8 +5,8 @@ MAN= add_route.8 backup.8 boot.8 btrace.8 \
|
|||
intr.8 irdpd.8 loadramdisk.8 \
|
||||
netconf.8 newroot.8 nonamed.8 \
|
||||
ossdevlinks.8 part.8 partition.8 \
|
||||
poweroff.8 printroot.8 pr_routes.8 pwdauth.8 rarpd.8 \
|
||||
readclock.8 reboot.8 repartition.8 \
|
||||
printroot.8 pr_routes.8 pwdauth.8 rarpd.8 \
|
||||
readclock.8 repartition.8 \
|
||||
rshd.8 screendump.8 serial-ip.8 \
|
||||
setup.8 shutdown.8 slip.8 srccrc.8 syslogd.8 tcpd.8 \
|
||||
unix.8 update.8 usage.8 vbfs.8
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
.TH POWEROFF 1
|
||||
.SH NAME
|
||||
poweroff \- power off the machine
|
||||
.SH SYNOPSIS
|
||||
.B poweroff
|
||||
.SH DESCRIPTION
|
||||
This command powers off the machine, by calling
|
||||
.B shutdown
|
||||
and passing the
|
||||
.I off
|
||||
directive to the boot monitor.
|
||||
.SH "SEE ALSO"
|
||||
.BR shutdown (8).
|
|
@ -1,49 +0,0 @@
|
|||
.TH REBOOT 8
|
||||
.SH NAME
|
||||
reboot \- reboot the system immediately
|
||||
.SH SYNOPSIS
|
||||
\fBreboot\fP [\fB\-f\fP]
|
||||
.SH DESCRIPTION
|
||||
.B Reboot
|
||||
can be used to reboot the system after installing a new kernel. It does
|
||||
not inform the users, but does log it's actions in
|
||||
.B /usr/adm/wtmp
|
||||
and
|
||||
.BR /usr/adm/log .
|
||||
The system is then rebooted with the
|
||||
.BR reboot (2)
|
||||
systemcall.
|
||||
.PP
|
||||
If the
|
||||
.B \-f
|
||||
flag is not given then all processes are sent terminate
|
||||
signals to give them a chance to die peacefully before the
|
||||
.B reboot()
|
||||
call.
|
||||
.PP
|
||||
If the wtmp file exists,
|
||||
.B reboot
|
||||
logs itself as if it were a shutdown. This is done to prevent
|
||||
.BR last (1)
|
||||
from talking about system-crashes.
|
||||
.B Reboot
|
||||
is registered as is in the log file.
|
||||
.PP
|
||||
.B Reboot
|
||||
can only be executed by the super-user. Any other caller will be
|
||||
refused, either by
|
||||
.BR reboot (8)
|
||||
or by
|
||||
.BR reboot (2).
|
||||
.SH "SEE ALSO"
|
||||
.BR reboot (2),
|
||||
.BR shutdown (8),
|
||||
.BR halt(8),
|
||||
.BR boot (8).
|
||||
.SH BUGS
|
||||
The error message's given by
|
||||
.B reboot
|
||||
are not always useful. There are several routines that can fail, but which
|
||||
are not fatal for the program.
|
||||
.SH AUTHOR
|
||||
Edvard Tuinder (v892231@si.hhs.NL)
|
|
@ -28,7 +28,7 @@ PROGRAMS+= ${PROGROOT}/drivers/tty/tty
|
|||
PROGRAMS+= ${PROGROOT}/servers/mfs/mfs
|
||||
PROGRAMS+= ${PROGROOT}/servers/vm/vm
|
||||
PROGRAMS+= ${PROGROOT}/servers/pfs/pfs
|
||||
PROGRAMS+= ${PROGROOT}/servers/init/init
|
||||
PROGRAMS+= ${PROGROOT}/sbin/init/init
|
||||
|
||||
usage:
|
||||
@echo " " >&2
|
||||
|
@ -68,10 +68,13 @@ kernel: libraries
|
|||
servers: libraries
|
||||
${MAKE} -C ../servers all install
|
||||
|
||||
sbin: libraries
|
||||
${MAKE} -C ../sbin all install
|
||||
|
||||
drivers: libraries servers
|
||||
${MAKE} -C ../drivers all install
|
||||
|
||||
services: kernel servers drivers
|
||||
services: kernel servers drivers sbin
|
||||
|
||||
.gitignore: Makefile
|
||||
echo ${GEN_FILES} | tr ' ' '\n' >.gitignore
|
||||
|
|
|
@ -178,11 +178,14 @@ ${CROSS_PREFIX}objcopy ${OBJ}/kernel/kernel -O binary ${OBJ}/kernel.bin
|
|||
|
||||
mcopy -bsp -i ${IMG_DIR}/fat.img ${OBJ}/kernel.bin ::kernel.bin
|
||||
|
||||
for f in vm rs pm sched vfs ds mfs pfs init
|
||||
for f in servers/vm/vm servers/rs/rs servers/pm/pm servers/sched/sched \
|
||||
servers/vfs/vfs servers/ds/ds servers/mfs/mfs servers/pfs/pfs \
|
||||
sbin/init/init
|
||||
do
|
||||
cp ${OBJ}/servers/${f}/${f} ${OBJ}/${f}.elf
|
||||
${CROSS_PREFIX}strip -s ${OBJ}/${f}.elf
|
||||
mcopy -bsp -i ${IMG_DIR}/fat.img ${OBJ}/${f}.elf ::${f}.elf
|
||||
fn=`basename $f`.elf
|
||||
cp ${OBJ}/${f} ${OBJ}/${fn}
|
||||
${CROSS_PREFIX}strip -s ${OBJ}/${fn}
|
||||
mcopy -bsp -i ${IMG_DIR}/fat.img ${OBJ}/${fn} ::${fn}
|
||||
done
|
||||
|
||||
for f in tty memory
|
||||
|
|
|
@ -73,6 +73,7 @@
|
|||
2012/10/17 12:00:00,include
|
||||
2013/05/31 12:00:00,libexec/fingerd
|
||||
2012/10/17 12:00:00,libexec/ftpd
|
||||
2012/10/17 12:00:00,libexec/getty
|
||||
2012/10/17 12:00:00,libexec/ld.elf_so
|
||||
2012/10/17 12:00:00,libexec/Makefile
|
||||
2012/10/17 12:00:00,libexec/Makefile.inc
|
||||
|
@ -97,6 +98,9 @@
|
|||
2012/10/17 12:00:00,Makefile
|
||||
2011/06/09 21:23:29,sbin/fsck
|
||||
2011/09/16 16:13:18,sbin/fsck_ext2fs
|
||||
2012/10/17 12:00:00,sbin/init
|
||||
2012/10/17 12:00:00,sbin/reboot
|
||||
2012/10/17 12:00:00,sbin/shutdown
|
||||
2012/10/17 12:00:00,sbin/Makefile
|
||||
2012/10/17 12:00:00,sbin/Makefile.inc
|
||||
2012/10/10 16:16:12,sbin/mknod
|
||||
|
@ -188,6 +192,7 @@
|
|||
2012/10/17 12:00:00,usr.bin/join
|
||||
2012/10/17 12:00:00,usr.bin/jot
|
||||
2012/10/17 12:00:00,usr.bin/lam
|
||||
2012/10/17 12:00:00,usr.bin/last
|
||||
2011/01/17 18:11:10,usr.bin/ldd
|
||||
2013/10/18 12:00:00,usr.bin/leave
|
||||
2012/10/17 12:00:00,usr.bin/lock
|
||||
|
@ -248,11 +253,12 @@
|
|||
2013/10/14 12:00:00,usr.bin/users
|
||||
2013/10/23 12:00:00,usr.bin/uuidgen
|
||||
2012/10/17 12:00:00,usr.bin/vis
|
||||
2012/10/17 12:00:00,usr.bin/wall
|
||||
2012/10/17 12:00:00,usr.bin/wc
|
||||
2012/10/17 12:00:00,usr.bin/what
|
||||
2013/03/22 12:00:00,usr.bin/whatis
|
||||
2013/03/15 12:00:00,usr.bin/who
|
||||
2012/10/17 12:00:00,usr.bin/whois
|
||||
2013/03/22 12:00:00,usr.bin/whatis
|
||||
2012/10/17 12:00:00,usr.bin/write
|
||||
2012/10/17 12:00:00,usr.bin/xinstall
|
||||
2012/10/17 12:00:00,usr.bin/xstr
|
||||
|
|
|
@ -9,7 +9,12 @@
|
|||
SUBDIR= \
|
||||
\
|
||||
fsck \
|
||||
mknod nologin
|
||||
mknod \
|
||||
nologin \
|
||||
mknod \
|
||||
init \
|
||||
reboot \
|
||||
shutdown
|
||||
|
||||
# support for various file systems
|
||||
SUBDIR+= newfs_ext2fs fsck_ext2fs
|
||||
|
|
18
sbin/init/Makefile
Normal file
18
sbin/init/Makefile
Normal file
|
@ -0,0 +1,18 @@
|
|||
# $NetBSD: Makefile,v 1.38 2009/04/11 07:58:12 lukem Exp $
|
||||
# @(#)Makefile 8.1 (Berkeley) 7/19/93
|
||||
|
||||
PROG= init
|
||||
MAN= init.8
|
||||
DPADD= ${LIBUTIL}
|
||||
LDADD= -lutil
|
||||
CPPFLAGS+= -DMFS_DEV_IF_NO_CONSOLE -DSUPPORT_UTMP -DSUPPORT_UTMPX
|
||||
|
||||
.ifdef SMALLPROG
|
||||
CPPFLAGS+= -DLETS_GET_SMALL
|
||||
.else
|
||||
CPPFLAGS+= -DALTSHELL -DSECURE -DCHROOT
|
||||
DPADD+= ${LIBCRYPT}
|
||||
LDADD+= -lcrypt
|
||||
.endif
|
||||
|
||||
.include <bsd.prog.mk>
|
119
sbin/init/NOTES
Normal file
119
sbin/init/NOTES
Normal file
|
@ -0,0 +1,119 @@
|
|||
$NetBSD: NOTES,v 1.3 2006/04/18 11:40:26 salo Exp $
|
||||
|
||||
POSIX and init:
|
||||
--------------
|
||||
|
||||
POSIX.1 does not define 'init' but it mentions it in a few places.
|
||||
|
||||
B.2.2.2, p205 line 873:
|
||||
|
||||
This is part of the extensive 'job control' glossary entry.
|
||||
This specific reference says that 'init' must by default provide
|
||||
protection from job control signals to jobs it starts --
|
||||
it sets SIGTSTP, SIGTTIN and SIGTTOU to SIG_IGN.
|
||||
|
||||
B.2.2.2, p206 line 889:
|
||||
|
||||
Here is a reference to 'vhangup'. It says, 'POSIX.1 does
|
||||
not specify how controlling terminal access is affected by
|
||||
a user logging out (that is, by a controlling process
|
||||
terminating).' vhangup() is recognized as one way to handle
|
||||
the problem. I'm not clear what happens in Reno; I have
|
||||
the impression that when the controlling process terminates,
|
||||
references to the controlling terminal are converted to
|
||||
references to a 'dead' vnode. I don't know whether vhangup()
|
||||
is required.
|
||||
|
||||
B.2.2.2, p206 line 921:
|
||||
|
||||
Orphaned process groups bear indirectly on this issue. A
|
||||
session leader's process group is considered to be orphaned;
|
||||
that is, it's immune to job control signals from the terminal.
|
||||
|
||||
B.2.2.2, p233 line 2055:
|
||||
|
||||
'Historically, the implementation-dependent process that
|
||||
inherits children whose parents have terminated without
|
||||
waiting on them is called "init" and has a process ID of 1.'
|
||||
|
||||
It goes on to note that it used to be the case that 'init'
|
||||
was responsible for sending SIGHUP to the foreground process
|
||||
group of a tty whose controlling process has exited, using
|
||||
vhangup(). It is now the responsibility of the kernel to
|
||||
do this when the controlling process calls _exit(). The
|
||||
kernel is also responsible for sending SIGCONT to stopped
|
||||
process groups that become orphaned. This is like old BSD
|
||||
but entire process groups are signaled instead of individual
|
||||
processes.
|
||||
|
||||
In general it appears that the kernel now automatically
|
||||
takes care of orphans, relieving 'init' of any responsibility.
|
||||
Specifics are listed on the _exit() page (p50).
|
||||
|
||||
On setsid():
|
||||
-----------
|
||||
|
||||
It appears that neither getty nor login call setsid(), so init must
|
||||
do this -- seems reasonable. B.4.3.2 p 248 implies that this is the
|
||||
way that 'init' should work; it says that setsid() should be called
|
||||
after forking.
|
||||
|
||||
Process group leaders cannot call setsid() -- another reason to
|
||||
fork! Of course setsid() causes the current process to become a
|
||||
process group leader, so we can only call setsid() once. Note that
|
||||
the controlling terminal acquires the session leader's process
|
||||
group when opened.
|
||||
|
||||
Controlling terminals:
|
||||
---------------------
|
||||
|
||||
B.7.1.1.3 p276: 'POSIX.1 does not specify a mechanism by which to
|
||||
allocate a controlling terminal. This is normally done by a system
|
||||
utility (such as 'getty') and is considered ... outside the scope
|
||||
of POSIX.1.' It goes on to say that historically the first open()
|
||||
of a tty in a session sets the controlling terminal. P130 has the
|
||||
full details; nothing particularly surprising.
|
||||
|
||||
The glossary p12 describes a 'controlling process' as the first
|
||||
process in a session that acquires a controlling terminal. Access
|
||||
to the terminal from the session is revoked if the controlling
|
||||
process exits (see p50, in the discussion of process termination).
|
||||
|
||||
Design notes:
|
||||
------------
|
||||
|
||||
your generic finite state machine
|
||||
we are fascist about which signals we elect to receive,
|
||||
even signals purportedly generated by hardware
|
||||
handle fatal errors gracefully if possible (we reboot if we goof!!)
|
||||
if we get a segmentation fault etc., print a message on the console
|
||||
and spin for a while before rebooting
|
||||
(this at least decreases the amount of paper consumed :-)
|
||||
apply hysteresis to rapidly exiting gettys
|
||||
check wait status of children we reap
|
||||
don't wait for stopped children
|
||||
don't use SIGCHILD, it's too expensive
|
||||
but it may close windows and avoid races, sigh
|
||||
look for EINTR in case we need to change state
|
||||
init is responsible for utmp and wtmp maintenance (ick)
|
||||
maybe now we can consider replacements? maintain them in parallel
|
||||
init only removes utmp and closes out wtmp entries...
|
||||
|
||||
necessary states and state transitions (gleaned from the man page):
|
||||
1: single user shell (with password checking?); on exit, go to 2
|
||||
2: run rc script, on exit 0 check if init.root sysctl != "/", if it
|
||||
differs then fork + chroot into the value of init.root and run
|
||||
/etc/rc inside the chroot: on exit 0, go to 3; on exit N (error),
|
||||
go to 1 (applies also to /etc/rc when init.root == "/")
|
||||
3: read ttys file: on completion, go to 4. If we did chroot in
|
||||
state 2, we chroot after forking each getty to the same dir
|
||||
(init.root is not re-read)
|
||||
4: multi-user operation: on SIGTERM, go to 7; on SIGHUP, go to 5;
|
||||
on SIGTSTP, go to 6
|
||||
5: clean up mode (re-read ttys file, killing off controlling processes
|
||||
on lines that are now 'off', starting them on lines newly 'on')
|
||||
on completion, go to 4
|
||||
6: boring mode (no new sessions); signals as in 4
|
||||
7: death: send SIGHUP to all controlling processes, reap for 30 seconds,
|
||||
then go to 1 (warn if not all processes died, i.e. wait blocks)
|
||||
Given the -s flag, we start at state 1; otherwise state 2
|
374
sbin/init/init.8
Normal file
374
sbin/init/init.8
Normal file
|
@ -0,0 +1,374 @@
|
|||
.\" $NetBSD: init.8,v 1.57 2009/05/18 14:17:31 wiz Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1980, 1991, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" This code is derived from software contributed to Berkeley by
|
||||
.\" Donn Seeley at Berkeley Software Design, Inc.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" @(#)init.8 8.6 (Berkeley) 5/26/95
|
||||
.\"
|
||||
.Dd November 10, 2008
|
||||
.Dt INIT 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm init
|
||||
.Nd process control initialization
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
program is the last stage of the boot process (after the kernel loads
|
||||
and initializes all the devices).
|
||||
It normally begins multi-user operation.
|
||||
.Pp
|
||||
The following table describes the state machine used by
|
||||
.Nm :
|
||||
.Bl -enum
|
||||
.It
|
||||
Single user shell.
|
||||
.Nm
|
||||
may be passed
|
||||
.Fl s
|
||||
from the boot program to prevent the system from going multi-user and
|
||||
to instead execute a single user shell without starting the normal
|
||||
daemons.
|
||||
If the kernel is in a secure mode,
|
||||
.Nm
|
||||
will downgrade it to securelevel 0 (insecure mode).
|
||||
The system is then quiescent for maintenance work and may
|
||||
later be made to go to state 2 (multi-user) by exiting the single-user
|
||||
shell (with ^D).
|
||||
.It
|
||||
Multi-user boot (default operation).
|
||||
Executes
|
||||
.Pa /etc/rc
|
||||
(see
|
||||
.Xr rc 8 ) .
|
||||
If this was the first state entered (as opposed to entering here after
|
||||
state 1), then
|
||||
.Pa /etc/rc
|
||||
will be invoked with its first argument being
|
||||
.Sq autoboot .
|
||||
If
|
||||
.Pa /etc/rc
|
||||
exits with a non-zero (error) exit code, commence single user
|
||||
operation by giving the super-user a shell on the console by going
|
||||
to state 1 (single user).
|
||||
Otherwise, proceed to state 3.
|
||||
.Pp
|
||||
If value of the
|
||||
.Dq init.root
|
||||
sysctl node is not equal to
|
||||
.Pa /
|
||||
at this point, the
|
||||
.Pa /etc/rc
|
||||
process will be run inside a
|
||||
.Xr chroot 2
|
||||
indicated by sysctl with the same error handling as above.
|
||||
.Pp
|
||||
If the administrator has not set the security level to \-1
|
||||
to indicate that the kernel should not run multiuser in secure
|
||||
mode, and the
|
||||
.Pa /etc/rc
|
||||
script has not set a higher level of security
|
||||
than level 1, then
|
||||
.Nm
|
||||
will put the kernel into securelevel mode 1.
|
||||
See
|
||||
.Xr rc.conf 5
|
||||
and
|
||||
.Xr secmodel_securelevel 9
|
||||
for more information.
|
||||
.It
|
||||
Set up ttys as specified in
|
||||
.Xr ttys 5 .
|
||||
See below for more information.
|
||||
On completion, continue to state 4.
|
||||
If we did chroot in state 2, each
|
||||
.Xr getty 8
|
||||
process will be run in the same
|
||||
.Xr chroot 2
|
||||
path as in 2 (that is, the value of
|
||||
.Dq init.root
|
||||
sysctl is not re-read).
|
||||
.It
|
||||
Multi-user operation.
|
||||
Depending upon the signal received, change state appropriately;
|
||||
on
|
||||
.Dv SIGTERM ,
|
||||
go to state 7;
|
||||
on
|
||||
.Dv SIGHUP ,
|
||||
go to state 5;
|
||||
on
|
||||
.Dv SIGTSTP ,
|
||||
go to state 6.
|
||||
.It
|
||||
Clean-up mode; re-read
|
||||
.Xr ttys 5 ,
|
||||
killing off the controlling processes on lines that are now
|
||||
.Sq off ,
|
||||
and starting processes that are newly
|
||||
.Sq on .
|
||||
On completion, go to state 4.
|
||||
.It
|
||||
.Sq Boring
|
||||
mode; no new sessions.
|
||||
Signals as per state 4.
|
||||
.It
|
||||
Shutdown mode.
|
||||
Send
|
||||
.Dv SIGHUP
|
||||
to all controlling processes, reap the processes for 30 seconds,
|
||||
and then go to state 1 (single user); warning if not all the processes died.
|
||||
.El
|
||||
.Pp
|
||||
If the
|
||||
.Sq console
|
||||
entry in the
|
||||
.Xr ttys 5
|
||||
file is marked
|
||||
.Dq insecure ,
|
||||
then
|
||||
.Nm
|
||||
will require that the superuser password be
|
||||
entered before the system will start a single-user shell.
|
||||
The password check is skipped if the
|
||||
.Sq console
|
||||
is marked as
|
||||
.Dq secure .
|
||||
.Pp
|
||||
It should be noted that while
|
||||
.Nm
|
||||
has the ability to start multi-user operation inside a
|
||||
.Xr chroot 2
|
||||
environment, the
|
||||
.Nm
|
||||
process itself will always run in the
|
||||
.Dq original root directory .
|
||||
This also implies that single-user mode is always started in the original
|
||||
root, giving the possibility to create multi-user sessions in different
|
||||
root directories over time.
|
||||
The
|
||||
.Dq init.root
|
||||
sysctl node is fabricated by
|
||||
.Nm
|
||||
at startup and re-created any time it's found to be missing.
|
||||
Type of the node is string capable of holding full pathname, and
|
||||
is only accessible by the superuser (unless explicitly destroyed
|
||||
and re-created with different specification).
|
||||
.Pp
|
||||
In multi-user operation,
|
||||
.Nm
|
||||
maintains
|
||||
processes for the terminal ports found in the file
|
||||
.Xr ttys 5 .
|
||||
.Nm
|
||||
reads this file, and executes the command found in the second field.
|
||||
This command is usually
|
||||
.Xr getty 8 ;
|
||||
it opens and initializes the tty line and executes the
|
||||
.Xr login 1
|
||||
program.
|
||||
The
|
||||
.Xr login 1
|
||||
program, when a valid user logs in, executes a shell for that user.
|
||||
When this shell dies, either because the user logged out or an
|
||||
abnormal termination occurred (a signal), the
|
||||
.Nm
|
||||
program wakes up, deletes the user from the
|
||||
.Xr utmp 5
|
||||
and
|
||||
.Xr utmpx 5
|
||||
files of current users and records the logout in the
|
||||
.Xr wtmp 5
|
||||
and
|
||||
.Xr wtmpx 5
|
||||
files.
|
||||
The cycle is
|
||||
then restarted by
|
||||
.Nm
|
||||
executing a new
|
||||
.Xr getty 8
|
||||
for the line.
|
||||
.Pp
|
||||
Line status (on, off, secure, getty, or window information)
|
||||
may be changed in the
|
||||
.Xr ttys 5
|
||||
file without a reboot by sending the signal
|
||||
.Dv SIGHUP
|
||||
to
|
||||
.Nm
|
||||
with the command
|
||||
.Dq Li "kill \-s HUP 1" .
|
||||
This is referenced in the table above as state 5.
|
||||
On receipt of this signal,
|
||||
.Nm
|
||||
re-reads the
|
||||
.Xr ttys 5
|
||||
file.
|
||||
When a line is turned off in
|
||||
.Xr ttys 5 ,
|
||||
.Nm
|
||||
will send a
|
||||
.Dv SIGHUP
|
||||
signal to the controlling process
|
||||
for the session associated with the line.
|
||||
For any lines that were previously turned off in the
|
||||
.Xr ttys 5
|
||||
file and are now on,
|
||||
.Nm
|
||||
executes a new
|
||||
.Xr getty 8
|
||||
to enable a new login.
|
||||
If the getty or window field for a line is changed,
|
||||
the change takes effect at the end of the current
|
||||
login session (e.g., the next time
|
||||
.Nm
|
||||
starts a process on the line).
|
||||
If a line is commented out or deleted from
|
||||
.Xr ttys 5 ,
|
||||
.Nm
|
||||
will not do anything at all to that line.
|
||||
However, it will complain that the relationship between lines
|
||||
in the
|
||||
.Xr ttys 5
|
||||
file and records in the
|
||||
.Xr utmp 5
|
||||
file is out of sync,
|
||||
so this practice is not recommended.
|
||||
.Pp
|
||||
.Nm
|
||||
will terminate multi-user operations and resume single-user mode
|
||||
if sent a terminate
|
||||
.Pq Dv TERM
|
||||
signal, for example,
|
||||
.Dq Li "kill \-s TERM 1" .
|
||||
If there are processes outstanding that are deadlocked (because of
|
||||
hardware or software failure),
|
||||
.Nm
|
||||
will not wait for them all to die (which might take forever), but
|
||||
will time out after 30 seconds and print a warning message.
|
||||
.Pp
|
||||
.Nm
|
||||
will cease creating new
|
||||
.Xr getty 8 Ns 's
|
||||
and allow the system to slowly die away, if it is sent a terminal stop
|
||||
.Pq Dv TSTP
|
||||
signal, i.e.
|
||||
.Dq Li "kill \-s TSTP 1" .
|
||||
A later hangup will resume full
|
||||
multi-user operations, or a terminate will start a single user shell.
|
||||
This hook is used by
|
||||
.Xr reboot 8
|
||||
and
|
||||
.Xr halt 8 .
|
||||
.Pp
|
||||
The role of
|
||||
.Nm
|
||||
is so critical that if it dies, the system will reboot itself
|
||||
automatically.
|
||||
If, at bootstrap time, the
|
||||
.Nm
|
||||
process cannot be located, or exits during its initialisation,
|
||||
the system will panic with the message
|
||||
.Dq panic: init died (signal %d, exit %d) .
|
||||
.Pp
|
||||
If
|
||||
.Pa /dev/console
|
||||
does not exist,
|
||||
.Nm
|
||||
will cd to
|
||||
.Pa /dev
|
||||
and run
|
||||
.Dq Li "MAKEDEV -MM init" .
|
||||
.Xr MAKEDEV 8
|
||||
will use
|
||||
.Xr mount_tmpfs 8
|
||||
or
|
||||
.Xr mount_mfs 8
|
||||
to create a memory file system mounted over
|
||||
.Pa /dev
|
||||
that contains the standard devices considered necessary to boot the system.
|
||||
.Sh FILES
|
||||
.Bl -tag -width /var/log/wtmp{,x} -compact
|
||||
.It Pa /dev/console
|
||||
System console device.
|
||||
.It Pa /dev/tty*
|
||||
Terminal ports found in
|
||||
.Xr ttys 5 .
|
||||
.It Pa /var/run/utmp{,x}
|
||||
Record of current users on the system.
|
||||
.It Pa /var/log/wtmp{,x}
|
||||
Record of all logins and logouts.
|
||||
.It Pa /etc/ttys
|
||||
The terminal initialization information file.
|
||||
.It Pa /etc/rc
|
||||
System startup commands.
|
||||
.El
|
||||
.Sh DIAGNOSTICS
|
||||
.Bl -diag
|
||||
.It "getty repeating too quickly on port %s, sleeping"
|
||||
A process being started to service a line is exiting quickly
|
||||
each time it is started.
|
||||
This is often caused by a ringing or noisy terminal line.
|
||||
.Em "Init will sleep for 10 seconds" ,
|
||||
.Em "then continue trying to start the process" .
|
||||
.Pp
|
||||
.It "some processes would not die; ps axl advised."
|
||||
A process is hung and could not be killed when the system was
|
||||
shutting down.
|
||||
This condition is usually caused by a process that is stuck in a
|
||||
device driver because of a persistent device error condition.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr config 1 ,
|
||||
.Xr kill 1 ,
|
||||
.Xr login 1 ,
|
||||
.Xr sh 1 ,
|
||||
.Xr options 4 ,
|
||||
.Xr ttys 5 ,
|
||||
.Xr getty 8 ,
|
||||
.Xr halt 8 ,
|
||||
.Xr MAKEDEV 8 ,
|
||||
.Xr MAKEDEV.local 8 ,
|
||||
.Xr mount_mfs 8 ,
|
||||
.Xr mount_tmpfs 8 ,
|
||||
.Xr rc 8 ,
|
||||
.Xr reboot 8 ,
|
||||
.Xr rescue 8 ,
|
||||
.Xr shutdown 8 ,
|
||||
.Xr sysctl 8 ,
|
||||
.Xr secmodel_bsd44 9 ,
|
||||
.Xr secmodel_securelevel 9
|
||||
.Sh HISTORY
|
||||
A
|
||||
.Nm
|
||||
command appeared in
|
||||
.At v6 .
|
1910
sbin/init/init.c
Normal file
1910
sbin/init/init.c
Normal file
File diff suppressed because it is too large
Load diff
40
sbin/init/pathnames.h
Normal file
40
sbin/init/pathnames.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
/* $NetBSD: pathnames.h,v 1.6 2003/08/07 10:04:25 agc Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Donn Seeley at Berkeley Software Design, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)pathnames.h 8.1 (Berkeley) 6/5/93
|
||||
*/
|
||||
|
||||
#include <paths.h>
|
||||
|
||||
#define _PATH_SLOGGER "/sbin/session_logger"
|
||||
#define _PATH_RUNCOM "/etc/rc"
|
14
sbin/reboot/Makefile
Normal file
14
sbin/reboot/Makefile
Normal file
|
@ -0,0 +1,14 @@
|
|||
# $NetBSD: Makefile,v 1.18 2002/08/02 15:05:57 wiz Exp $
|
||||
# @(#)Makefile 8.1 (Berkeley) 6/5/93
|
||||
|
||||
PROG= reboot
|
||||
DPADD= ${LIBUTIL}
|
||||
LDADD= -lutil
|
||||
CPPFLAGS+= -DSUPPORT_UTMP -DSUPPORT_UTMPX
|
||||
MAN= reboot.8
|
||||
MLINKS= reboot.8 halt.8 \
|
||||
reboot.8 poweroff.8
|
||||
LINKS= ${BINDIR}/reboot ${BINDIR}/halt \
|
||||
${BINDIR}/reboot ${BINDIR}/poweroff
|
||||
|
||||
.include <bsd.prog.mk>
|
168
sbin/reboot/reboot.8
Normal file
168
sbin/reboot/reboot.8
Normal file
|
@ -0,0 +1,168 @@
|
|||
.\" $NetBSD: reboot.8,v 1.29 2011/02/16 19:32:26 wiz Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1990, 1991, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" @(#)reboot.8 8.1 (Berkeley) 6/9/93
|
||||
.\"
|
||||
.Dd February 16, 2011
|
||||
.Dt REBOOT 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm reboot ,
|
||||
.Nm poweroff ,
|
||||
.Nm halt
|
||||
.Nd restarting, powering down and stopping the system
|
||||
.Sh SYNOPSIS
|
||||
.Nm halt
|
||||
.Op Fl dlnpqvxz
|
||||
.Nm poweroff
|
||||
.Op Fl dlnqvxz
|
||||
.Nm
|
||||
.Op Fl dlnqvxz
|
||||
.Op Ar arg ...
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm poweroff ,
|
||||
.Nm halt
|
||||
and
|
||||
.Nm
|
||||
utilities flush the file system cache to disk, send all running processes
|
||||
a
|
||||
.Dv SIGTERM ,
|
||||
wait for up to 30 seconds for them to die, send a
|
||||
.Dv SIGKILL
|
||||
to the survivors and, respectively, power down, halt or restart the system.
|
||||
The action is logged, including entering a shutdown record into the login
|
||||
accounting file and sending a message via
|
||||
.Xr syslog 3 .
|
||||
.Pp
|
||||
The options are as follows:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl d
|
||||
Create a dump before halting or restarting.
|
||||
This option is useful for debugging system dump procedures or
|
||||
capturing the state of a corrupted or misbehaving system.
|
||||
.It Fl l
|
||||
Suppress sending a message via
|
||||
.Xr syslog 3
|
||||
before halting or restarting.
|
||||
.It Fl n
|
||||
Do not flush the file system cache.
|
||||
This option should be used with extreme caution.
|
||||
It can be used if a disk or a processor is on fire.
|
||||
.It Fl p
|
||||
Attempt to powerdown the system.
|
||||
If the powerdown fails, or the system does not support
|
||||
software powerdown, the system will halt.
|
||||
This option is only valid for
|
||||
.Nm halt .
|
||||
.It Fl v
|
||||
To enable verbose messages on the console, pass the
|
||||
.Xr boothowto 9
|
||||
flag
|
||||
.Dv AB_VERBOSE
|
||||
to
|
||||
.Xr reboot 2 .
|
||||
.It Fl x
|
||||
To enable debugging messages on the console, pass the
|
||||
.Xr boothowto 9
|
||||
flag
|
||||
.Dv AB_DEBUG
|
||||
to
|
||||
.Xr reboot 2 .
|
||||
.It Fl z
|
||||
To silence some shutdown messages on the console, pass the
|
||||
.Xr boothowto 9
|
||||
flag
|
||||
.Dv AB_SILENT
|
||||
to
|
||||
.Xr reboot 2 .
|
||||
.It Fl q
|
||||
Do not give processes a chance to shut down before halting or restarting.
|
||||
This option should not normally be used.
|
||||
.El
|
||||
.Pp
|
||||
If there are any arguments passed to
|
||||
.Nm reboot
|
||||
they are concatenated with spaces and passed as
|
||||
.Fa bootstr
|
||||
to the
|
||||
.Xr reboot 2
|
||||
system call.
|
||||
The string is passed to the firmware on platforms that support it.
|
||||
.Pp
|
||||
Normally, the
|
||||
.Xr shutdown 8
|
||||
utility is used when the system needs to be halted or restarted, giving
|
||||
users advance warning of their impending doom.
|
||||
.Sh SEE ALSO
|
||||
.Xr reboot 2 ,
|
||||
.Xr syslog 3 ,
|
||||
.Xr utmp 5 ,
|
||||
.Xr boot 8 ,
|
||||
.Xr init 8 ,
|
||||
.Xr rescue 8 ,
|
||||
.Xr shutdown 8 ,
|
||||
.Xr sync 8
|
||||
.Sh HISTORY
|
||||
A
|
||||
.Nm
|
||||
command appeared in
|
||||
.At v6 .
|
||||
.Pp
|
||||
The
|
||||
.Nm poweroff
|
||||
command first appeared in
|
||||
.Nx 1.5 .
|
||||
.Sh CAVEATS
|
||||
Once the command has begun its work, stopping it before it completes
|
||||
will probably result in a system so crippled it must be
|
||||
physically reset.
|
||||
To prevent premature termination, the command
|
||||
blocks many signals early in its execution.
|
||||
However, nothing can defend against deliberate attempts to evade this.
|
||||
.Pp
|
||||
This command will stop the system without running any
|
||||
.Xr shutdown 8
|
||||
scripts.
|
||||
Amongst other things, this means that swapping will not be
|
||||
disabled so that
|
||||
.Xr raid 4
|
||||
can shutdown cleanly.
|
||||
You should normally use
|
||||
.Xr shutdown 8
|
||||
unless you are running in single user mode.
|
||||
.Sh BUGS
|
||||
The single user shell will ignore the
|
||||
.Dv SIGTERM
|
||||
signal.
|
||||
To avoid waiting for the timeout when
|
||||
rebooting or halting from the single user shell, you have to
|
||||
.Ic exec reboot
|
||||
or
|
||||
.Ic exec halt .
|
264
sbin/reboot/reboot.c
Normal file
264
sbin/reboot/reboot.c
Normal file
|
@ -0,0 +1,264 @@
|
|||
/* $NetBSD: reboot.c,v 1.39 2011/08/27 18:46:19 joerg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1980, 1986, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#ifndef lint
|
||||
__COPYRIGHT("@(#) Copyright (c) 1980, 1986, 1993\
|
||||
The Regents of the University of California. All rights reserved.");
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)reboot.c 8.1 (Berkeley) 6/5/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: reboot.c,v 1.39 2011/08/27 18:46:19 joerg Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/reboot.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <pwd.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include <unistd.h>
|
||||
#include <util.h>
|
||||
|
||||
__dead static void usage(void);
|
||||
|
||||
static int dohalt;
|
||||
static int dopoweroff;
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
const char *progname;
|
||||
/* int i; */
|
||||
struct passwd *pw;
|
||||
int ch, howto, lflag, nflag, qflag, sverrno, len;
|
||||
const char *user;
|
||||
char *bootstr, **av;
|
||||
|
||||
progname = getprogname();
|
||||
if (progname[0] == '-')
|
||||
progname++;
|
||||
if (strcmp(progname, "halt") == 0) {
|
||||
dohalt = 1;
|
||||
howto = RB_HALT;
|
||||
} else if (strcmp(progname, "poweroff") == 0) {
|
||||
dopoweroff = 1;
|
||||
howto = RB_HALT | RB_POWERDOWN;
|
||||
} else
|
||||
howto = 0;
|
||||
lflag = nflag = qflag = 0;
|
||||
while ((ch = getopt(argc, argv, "dlnpqvxz")) != -1)
|
||||
switch(ch) {
|
||||
case 'd':
|
||||
howto |= RB_DUMP;
|
||||
break;
|
||||
case 'l':
|
||||
lflag = 1;
|
||||
break;
|
||||
case 'n':
|
||||
nflag = 1;
|
||||
howto |= RB_NOSYNC;
|
||||
break;
|
||||
case 'p':
|
||||
if (dohalt == 0)
|
||||
usage();
|
||||
howto |= RB_POWERDOWN;
|
||||
break;
|
||||
case 'q':
|
||||
qflag = 1;
|
||||
break;
|
||||
case 'v':
|
||||
howto |= AB_VERBOSE;
|
||||
break;
|
||||
case 'x':
|
||||
howto |= AB_DEBUG;
|
||||
break;
|
||||
case 'z':
|
||||
howto |= AB_SILENT;
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc) {
|
||||
for (av = argv, len = 0; *av; av++)
|
||||
len += strlen(*av) + 1;
|
||||
bootstr = malloc(len + 1);
|
||||
*bootstr = '\0'; /* for first strcat */
|
||||
for (av = argv; *av; av++) {
|
||||
strcat(bootstr, *av);
|
||||
strcat(bootstr, " ");
|
||||
}
|
||||
bootstr[len - 1] = '\0'; /* to kill last space */
|
||||
howto |= RB_STRING;
|
||||
} else
|
||||
bootstr = NULL;
|
||||
|
||||
if (geteuid())
|
||||
errx(1, "%s", strerror(EPERM));
|
||||
|
||||
if (qflag) {
|
||||
reboot(howto, bootstr);
|
||||
err(1, "reboot");
|
||||
}
|
||||
|
||||
/* Log the reboot. */
|
||||
if (!lflag) {
|
||||
if ((user = getlogin()) == NULL)
|
||||
user = (pw = getpwuid(getuid())) ?
|
||||
pw->pw_name : "???";
|
||||
if (dohalt) {
|
||||
openlog("halt", LOG_CONS, LOG_AUTH);
|
||||
syslog(LOG_CRIT, "halted by %s", user);
|
||||
} else if (dopoweroff) {
|
||||
openlog("poweroff", LOG_CONS, LOG_AUTH);
|
||||
syslog(LOG_CRIT, "powered off by %s", user);
|
||||
} else {
|
||||
openlog("reboot", LOG_CONS, LOG_AUTH);
|
||||
if (bootstr)
|
||||
syslog(LOG_CRIT, "rebooted by %s: %s", user,
|
||||
bootstr);
|
||||
else
|
||||
syslog(LOG_CRIT, "rebooted by %s", user);
|
||||
}
|
||||
}
|
||||
#ifdef SUPPORT_UTMP
|
||||
logwtmp("~", "shutdown", "");
|
||||
#endif
|
||||
#ifdef SUPPORT_UTMPX
|
||||
logwtmpx("~", "shutdown", "", INIT_PROCESS, 0);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Do a sync early on, so disks start transfers while we're off
|
||||
* killing processes. Don't worry about writes done before the
|
||||
* processes die, the reboot system call syncs the disks.
|
||||
*/
|
||||
if (!nflag)
|
||||
sync();
|
||||
|
||||
/*
|
||||
* Ignore signals that we can get as a result of killing
|
||||
* parents, group leaders, etc.
|
||||
*/
|
||||
(void)signal(SIGHUP, SIG_IGN);
|
||||
(void)signal(SIGINT, SIG_IGN);
|
||||
(void)signal(SIGQUIT, SIG_IGN);
|
||||
(void)signal(SIGTERM, SIG_IGN);
|
||||
(void)signal(SIGTSTP, SIG_IGN);
|
||||
|
||||
/*
|
||||
* If we're running in a pipeline, we don't want to die
|
||||
* after killing whatever we're writing to.
|
||||
*/
|
||||
(void)signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
|
||||
/* Just stop init -- if we fail, we'll restart it. */
|
||||
#if 0 && defined(__minix)
|
||||
if (kill(1, SIGTERM) == -1)
|
||||
err(1, "SIGTERM init");
|
||||
#else
|
||||
if (kill(1, SIGTSTP) == -1)
|
||||
err(1, "SIGTSTP init");
|
||||
#endif
|
||||
|
||||
/* Send a SIGTERM first, a chance to save the buffers. */
|
||||
if (kill(-1, SIGTERM) == -1) {
|
||||
/*
|
||||
* If ESRCH, everything's OK: we're the only non-system
|
||||
* process! That can happen e.g. via 'exec reboot' in
|
||||
* single-user mode.
|
||||
*/
|
||||
if (errno != ESRCH) {
|
||||
warn("SIGTERM all processes");
|
||||
goto restart;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* After the processes receive the signal, start the rest of the
|
||||
* buffers on their way. Wait 5 seconds between the SIGTERM and
|
||||
* the SIGKILL to pretend to give everybody a chance.
|
||||
*/
|
||||
sleep(2);
|
||||
if (!nflag)
|
||||
sync();
|
||||
sleep(3);
|
||||
|
||||
#ifndef __minix
|
||||
for (i = 1;; ++i) {
|
||||
if (kill(-1, SIGKILL) == -1) {
|
||||
if (errno == ESRCH)
|
||||
break;
|
||||
warn("SIGKILL all processes");
|
||||
goto restart;
|
||||
}
|
||||
if (i > 5) {
|
||||
warnx("WARNING: some process(es) wouldn't die");
|
||||
break;
|
||||
}
|
||||
(void)sleep(2 * i);
|
||||
}
|
||||
#endif
|
||||
|
||||
reboot(howto, bootstr);
|
||||
warn("reboot()");
|
||||
/* FALLTHROUGH */
|
||||
|
||||
restart:
|
||||
sverrno = errno;
|
||||
errx(1, "%s%s", kill(1, SIGHUP) == -1 ? "(can't restart init): " : "",
|
||||
strerror(sverrno));
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
const char *pflag = dohalt ? "p" : "";
|
||||
|
||||
(void)fprintf(stderr, "usage: %s [-dln%sqvxz] [-- <boot string>]\n",
|
||||
getprogname(), pflag);
|
||||
exit(1);
|
||||
}
|
15
sbin/shutdown/Makefile
Normal file
15
sbin/shutdown/Makefile
Normal file
|
@ -0,0 +1,15 @@
|
|||
# $NetBSD: Makefile,v 1.11 2009/04/11 07:58:13 lukem Exp $
|
||||
# @(#)Makefile 8.1 (Berkeley) 6/5/93
|
||||
|
||||
USE_FORT?=yes # setuid
|
||||
PROG= shutdown
|
||||
MAN= shutdown.8
|
||||
BINOWN= root
|
||||
BINGRP= operator
|
||||
BINMODE=4554
|
||||
|
||||
.if defined(__MINIX)
|
||||
WARNS=2
|
||||
.endif
|
||||
|
||||
.include <bsd.prog.mk>
|
45
sbin/shutdown/pathnames.h
Normal file
45
sbin/shutdown/pathnames.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
/* $NetBSD: pathnames.h,v 1.9 2004/08/19 22:30:10 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)pathnames.h 8.1 (Berkeley) 6/5/93
|
||||
*/
|
||||
|
||||
#include <paths.h>
|
||||
|
||||
#define _PATH_FASTBOOT "/fastboot"
|
||||
#ifdef RESCUEDIR
|
||||
#define _PATH_HALT RESCUEDIR "/halt"
|
||||
#define _PATH_REBOOT RESCUEDIR "/reboot"
|
||||
#else
|
||||
#define _PATH_HALT "/sbin/halt"
|
||||
#define _PATH_REBOOT "/sbin/reboot"
|
||||
#endif
|
||||
#define _PATH_WALL "/usr/bin/wall"
|
||||
#define _PATH_RCSHUTDOWN "/etc/rc.shutdown"
|
243
sbin/shutdown/shutdown.8
Normal file
243
sbin/shutdown/shutdown.8
Normal file
|
@ -0,0 +1,243 @@
|
|||
.\" $NetBSD: shutdown.8,v 1.31 2011/10/04 07:25:34 dholland Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1988, 1991, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" @(#)shutdown.8 8.2 (Berkeley) 4/27/95
|
||||
.\"
|
||||
.Dd October 4, 2011
|
||||
.Dt SHUTDOWN 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm shutdown
|
||||
.Nd close down the system at a given time
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl Ddfhknprvxz
|
||||
.Op Fl b Ar bootstr
|
||||
.Ar time
|
||||
.Op Ar message ... | Ar -
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
provides an automated shutdown procedure for super-users
|
||||
to nicely notify users when the system is shutting down,
|
||||
saving them from system administrators, hackers, and gurus, who
|
||||
would otherwise not bother with such niceties.
|
||||
.Pp
|
||||
Available friendlinesses:
|
||||
.Bl -tag -width bootstr
|
||||
.It Fl b Ar bootstr
|
||||
The given
|
||||
.Ar bootstr
|
||||
is passed to
|
||||
.Xr reboot 8
|
||||
for the benefit of those systems that can pass boot arguments to the
|
||||
firmware.
|
||||
Currently, this only affects sun3 and sparc machines.
|
||||
.It Fl d
|
||||
.Nm
|
||||
will pass the
|
||||
.Fl d
|
||||
flag to
|
||||
.Xr reboot 8
|
||||
or
|
||||
.Xr halt 8
|
||||
to request a kernel core dump.
|
||||
If neither the
|
||||
.Fl h
|
||||
or
|
||||
.Fl r
|
||||
flags are specified, then
|
||||
.Fl d
|
||||
also implies
|
||||
.Fl r .
|
||||
.It Fl f
|
||||
.Nm
|
||||
arranges, in the manner of
|
||||
.Xr fastboot 8 ,
|
||||
for the file systems
|
||||
.Em not to be
|
||||
checked on reboot.
|
||||
.It Fl h
|
||||
The system is halted at the specified
|
||||
.Ar time ,
|
||||
using
|
||||
.Xr halt 8 .
|
||||
.It Fl k
|
||||
Kick everybody off.
|
||||
The
|
||||
.Fl k
|
||||
option
|
||||
does not actually halt the system, but leaves the
|
||||
system multi-user with logins disabled (for all but super-user).
|
||||
.It Fl n
|
||||
Prevent the normal
|
||||
.Xr sync 2
|
||||
before stopping.
|
||||
.It Fl p
|
||||
The system is powered down at the specified
|
||||
.Ar time ,
|
||||
using
|
||||
.Xr poweroff 8 .
|
||||
If the powerdown fails, or the system does not support software powerdown,
|
||||
the system will simply halt instead.
|
||||
.It Fl r
|
||||
The system is rebooted at the specified
|
||||
.Ar time ,
|
||||
using
|
||||
.Xr reboot 8 .
|
||||
.It Fl v
|
||||
To enable verbose messages on the console, pass
|
||||
.Fl v
|
||||
to
|
||||
.Xr reboot 8
|
||||
or
|
||||
.Xr halt 8 .
|
||||
.It Fl x
|
||||
To enable debugging messages on the console, pass
|
||||
.Fl x
|
||||
to
|
||||
.Xr reboot 8
|
||||
or
|
||||
.Xr halt 8 .
|
||||
.It Fl z
|
||||
To silence some shutdown messages on the console, pass
|
||||
.Fl z
|
||||
to
|
||||
.Xr reboot 8
|
||||
or
|
||||
.Xr halt 8 .
|
||||
.It Fl D
|
||||
Prevents
|
||||
.Nm
|
||||
from detaching from the tty with
|
||||
.Xr fork 2 Ns /
|
||||
.Xr exit 3 .
|
||||
.It Ar time
|
||||
.Ar Time
|
||||
is the time at which
|
||||
.Nm
|
||||
will bring the system down and
|
||||
may be the word
|
||||
.Ar now
|
||||
or a future time in one of two formats:
|
||||
.Ar +number ,
|
||||
or
|
||||
.Ar [[[[[cc]yy]mm]dd]hh]mm ,
|
||||
where the century, year, month, day, and hour may be defaulted
|
||||
to the current system values.
|
||||
The first form brings the system down
|
||||
.Ar number
|
||||
minutes from the current time; the second brings the system down at the
|
||||
absolute time specified.
|
||||
If the century is not specified, it defaults to 1900 for years between 69
|
||||
and 99, or 2000 for years between 0 and 68.
|
||||
A leading zero in the
|
||||
.Dq yy
|
||||
value is
|
||||
.Em not
|
||||
optional.
|
||||
.It Ar message ...
|
||||
Any other arguments comprise the warning message that is broadcast
|
||||
to users currently logged into the system.
|
||||
.It Ar -
|
||||
If
|
||||
.Ar -
|
||||
is supplied as the only argument after the time, the warning message is read
|
||||
from the standard input.
|
||||
.El
|
||||
.Sh BEHAVIOR
|
||||
.Pp
|
||||
At intervals, becoming more frequent as apocalypse approaches
|
||||
and starting at ten hours before shutdown, warning messages are displayed
|
||||
on the terminals of all users logged in.
|
||||
Five minutes before shutdown, or immediately if shutdown is in less
|
||||
than 5 minutes, logins are disabled by creating
|
||||
.Pa /etc/nologin
|
||||
and copying the warning message there.
|
||||
If this file exists when a user attempts to log in,
|
||||
.Xr login 1
|
||||
prints its contents and exits.
|
||||
The file is removed just before
|
||||
.Nm
|
||||
exits.
|
||||
.Pp
|
||||
At shutdown time, a message is written in the system log containing the
|
||||
time of shutdown, who initiated the shutdown, and the reason.
|
||||
Next a message is printed announcing the start of the system shutdown hooks.
|
||||
Then the shutdown hooks in
|
||||
.Pa /etc/rc.shutdown
|
||||
are run, and a message is printed indicating that they have completed.
|
||||
After a short delay,
|
||||
.Nm
|
||||
runs
|
||||
.Xr halt 8
|
||||
or
|
||||
.Xr reboot 8 ,
|
||||
or sends a terminate
|
||||
signal to
|
||||
.Xr init 8
|
||||
to bring the system down to single-user mode, depending on the choice
|
||||
of options.
|
||||
.Pp
|
||||
The time of the shutdown and the warning message are placed in
|
||||
.Pa /etc/nologin
|
||||
and should be used to tell the users why the system is
|
||||
going down, when it will be back up, and to share any other pertinent
|
||||
information.
|
||||
.Sh FILES
|
||||
.Bl -tag -width /etc/rc.shutdown -compact
|
||||
.It Pa /etc/nologin
|
||||
tells
|
||||
.Xr login 1
|
||||
not to let anyone log in
|
||||
.It Pa /fastboot
|
||||
tells
|
||||
.Xr rc 8
|
||||
not to run
|
||||
.Xr fsck 8
|
||||
when rebooting
|
||||
.It Pa /etc/rc.shutdown
|
||||
System shutdown commands
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr login 1 ,
|
||||
.Xr wall 1 ,
|
||||
.Xr fastboot 8 ,
|
||||
.Xr halt 8 ,
|
||||
.Xr init 8 ,
|
||||
.Xr poweroff 8 ,
|
||||
.Xr reboot 8 ,
|
||||
.Xr rescue 8
|
||||
.Sh BACKWARD COMPATIBILITY
|
||||
The hours and minutes in the second time format may be separated by
|
||||
a colon (``:'') for backward compatibility.
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
command appeared in
|
||||
.Bx 4.0 .
|
592
sbin/shutdown/shutdown.c
Normal file
592
sbin/shutdown/shutdown.c
Normal file
|
@ -0,0 +1,592 @@
|
|||
/* $NetBSD: shutdown.c,v 1.55 2011/08/27 18:54:39 joerg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1990, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__COPYRIGHT("@(#) Copyright (c) 1988, 1990, 1993\
|
||||
The Regents of the University of California. All rights reserved.");
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)shutdown.c 8.4 (Berkeley) 4/28/95";
|
||||
#else
|
||||
__RCSID("$NetBSD: shutdown.c,v 1.55 2011/08/27 18:54:39 joerg Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/syslog.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <pwd.h>
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <tzfile.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "pathnames.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#undef _PATH_NOLOGIN
|
||||
#define _PATH_NOLOGIN "./nologin"
|
||||
#undef _PATH_FASTBOOT
|
||||
#define _PATH_FASTBOOT "./fastboot"
|
||||
#endif
|
||||
|
||||
#define H *60*60
|
||||
#define M *60
|
||||
#define S *1
|
||||
#define NOLOG_TIME 5*60
|
||||
static const struct interval {
|
||||
time_t timeleft, timetowait;
|
||||
} tlist[] = {
|
||||
{ 10 H, 5 H }, { 5 H, 3 H }, { 2 H, 1 H }, { 1 H, 30 M },
|
||||
{ 30 M, 10 M }, { 20 M, 10 M }, { 10 M, 5 M }, { 5 M, 3 M },
|
||||
{ 2 M, 1 M }, { 1 M, 30 S }, { 30 S, 30 S },
|
||||
{ 0, 0 }
|
||||
};
|
||||
#undef H
|
||||
#undef M
|
||||
#undef S
|
||||
|
||||
static time_t offset, shuttime;
|
||||
static int dofast, dohalt, doreboot, killflg, nofork, nosync, dodump;
|
||||
static size_t mbuflen;
|
||||
static int dopowerdown;
|
||||
static int dodebug, dosilent, doverbose;
|
||||
static const char *whom;
|
||||
static char mbuf[BUFSIZ];
|
||||
static char *bootstr;
|
||||
|
||||
static void badtime(void) __dead;
|
||||
static void die_you_gravy_sucking_pig_dog(void) __dead;
|
||||
static void doitfast(void);
|
||||
static void dorcshutdown(void);
|
||||
static void finish(int) __dead;
|
||||
static void getoffset(char *);
|
||||
static void loop(void) __dead;
|
||||
static void nolog(void);
|
||||
static void timeout(int) __dead;
|
||||
static void timewarn(time_t);
|
||||
static void usage(void) __dead;
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
char *p, *endp;
|
||||
struct passwd *pw;
|
||||
size_t arglen, len;
|
||||
int ch;
|
||||
|
||||
(void)setprogname(argv[0]);
|
||||
#ifndef DEBUG
|
||||
if (geteuid())
|
||||
errx(1, "%s: Not super-user", strerror(EPERM));
|
||||
#endif
|
||||
while ((ch = getopt(argc, argv, "b:Ddfhknprvxz")) != -1)
|
||||
switch (ch) {
|
||||
case 'b':
|
||||
bootstr = optarg;
|
||||
break;
|
||||
case 'd':
|
||||
dodump = 1;
|
||||
break;
|
||||
case 'D':
|
||||
nofork = 1;
|
||||
break;
|
||||
case 'f':
|
||||
dofast = 1;
|
||||
break;
|
||||
case 'p':
|
||||
dopowerdown = 1;
|
||||
/* FALLTHROUGH */
|
||||
case 'h':
|
||||
dohalt = 1;
|
||||
break;
|
||||
case 'k':
|
||||
killflg = 1;
|
||||
break;
|
||||
case 'n':
|
||||
nosync = 1;
|
||||
break;
|
||||
case 'r':
|
||||
doreboot = 1;
|
||||
break;
|
||||
case 'v':
|
||||
doverbose = 1;
|
||||
break;
|
||||
case 'x':
|
||||
dodebug = 1;
|
||||
break;
|
||||
case 'z':
|
||||
dosilent = 1;
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc < 1)
|
||||
usage();
|
||||
|
||||
if (dodump && !dohalt && !doreboot)
|
||||
doreboot = 1;
|
||||
|
||||
if (dofast && nosync) {
|
||||
warnx("Incompatible options -f and -n");
|
||||
usage();
|
||||
}
|
||||
if (dohalt && doreboot) {
|
||||
const char *which_flag = dopowerdown ? "p" : "h";
|
||||
|
||||
warnx("Incompatible options -%s and -r", which_flag);
|
||||
usage();
|
||||
}
|
||||
|
||||
getoffset(*argv++);
|
||||
|
||||
if (argv[0]) {
|
||||
if (strcmp(argv[0], "-") || argv[1]) {
|
||||
for (p = mbuf, len = sizeof(mbuf); *argv; ++argv) {
|
||||
arglen = strlen(*argv);
|
||||
if ((len -= arglen) <= 2)
|
||||
break;
|
||||
if (p != mbuf)
|
||||
*p++ = ' ';
|
||||
(void)memmove(p, *argv, arglen);
|
||||
p += arglen;
|
||||
}
|
||||
*p = '\n';
|
||||
*++p = '\0';
|
||||
} else {
|
||||
p = mbuf;
|
||||
endp = mbuf + sizeof(mbuf) - 2;
|
||||
for (;;) {
|
||||
if (!fgets(p, endp - p + 1, stdin))
|
||||
break;
|
||||
for (; *p && p < endp; ++p);
|
||||
if (p == endp) {
|
||||
*p = '\n';
|
||||
*++p = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mbuflen = strlen(mbuf);
|
||||
|
||||
if (offset)
|
||||
(void)printf("Shutdown at %.24s.\n", ctime(&shuttime));
|
||||
else
|
||||
(void)printf("Shutdown NOW!\n");
|
||||
|
||||
if (!(whom = getlogin()))
|
||||
whom = (pw = getpwuid(getuid())) ? pw->pw_name : "???";
|
||||
|
||||
#ifdef DEBUG
|
||||
(void)putc('\n', stdout);
|
||||
#else
|
||||
(void)setpriority(PRIO_PROCESS, 0, PRIO_MIN);
|
||||
if (nofork == 0) {
|
||||
int forkpid;
|
||||
|
||||
forkpid = fork();
|
||||
if (forkpid == -1) {
|
||||
perror("shutdown: fork");
|
||||
exit(1);
|
||||
}
|
||||
if (forkpid) {
|
||||
(void)printf("shutdown: [pid %d]\n", forkpid);
|
||||
exit(0);
|
||||
}
|
||||
(void)setsid();
|
||||
}
|
||||
#endif
|
||||
openlog("shutdown", LOG_CONS, LOG_AUTH);
|
||||
loop();
|
||||
/* NOTREACHED */
|
||||
#ifdef __GNUC__
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
loop(void)
|
||||
{
|
||||
const struct interval *tp;
|
||||
u_int sltime;
|
||||
int logged;
|
||||
|
||||
if (offset <= NOLOG_TIME) {
|
||||
logged = 1;
|
||||
nolog();
|
||||
}
|
||||
else
|
||||
logged = 0;
|
||||
tp = tlist;
|
||||
if (tp->timeleft < offset)
|
||||
(void)sleep((u_int)(offset - tp->timeleft));
|
||||
else {
|
||||
while (offset < tp->timeleft)
|
||||
++tp;
|
||||
/*
|
||||
* Warn now, if going to sleep more than a fifth of
|
||||
* the next wait time.
|
||||
*/
|
||||
if ((sltime = offset - tp->timeleft) != 0) {
|
||||
if (sltime > tp->timetowait / 5)
|
||||
timewarn(offset);
|
||||
(void)sleep(sltime);
|
||||
}
|
||||
}
|
||||
for (;; ++tp) {
|
||||
timewarn(tp->timeleft);
|
||||
if (!logged && tp->timeleft <= NOLOG_TIME) {
|
||||
logged = 1;
|
||||
nolog();
|
||||
}
|
||||
(void)sleep((u_int)tp->timetowait);
|
||||
if (!tp->timeleft)
|
||||
break;
|
||||
}
|
||||
die_you_gravy_sucking_pig_dog();
|
||||
}
|
||||
|
||||
static jmp_buf alarmbuf;
|
||||
|
||||
static void
|
||||
timewarn(time_t timeleft)
|
||||
{
|
||||
static int first;
|
||||
static char hostname[MAXHOSTNAMELEN + 1];
|
||||
FILE *pf;
|
||||
char wcmd[MAXPATHLEN + 4];
|
||||
|
||||
if (!first++) {
|
||||
(void)gethostname(hostname, sizeof(hostname));
|
||||
hostname[sizeof(hostname) - 1] = '\0';
|
||||
}
|
||||
|
||||
/* undoc -n option to wall suppresses normal wall banner */
|
||||
(void)snprintf(wcmd, sizeof wcmd, "%s -n", _PATH_WALL);
|
||||
if ((pf = popen(wcmd, "w")) == NULL) {
|
||||
syslog(LOG_ERR, "%s: Can't find `%s' (%m)", getprogname(),
|
||||
_PATH_WALL);
|
||||
return;
|
||||
}
|
||||
|
||||
(void)fprintf(pf,
|
||||
"\007*** %sSystem shutdown message from %s@%s ***\007\n",
|
||||
timeleft ? "": "FINAL ", whom, hostname);
|
||||
|
||||
if (timeleft > 10*60)
|
||||
(void)fprintf(pf, "System going down at %5.5s\n\n",
|
||||
ctime(&shuttime) + 11);
|
||||
else if (timeleft > 59)
|
||||
(void)fprintf(pf, "System going down in %ld minute%s\n\n",
|
||||
(long)timeleft / 60, (timeleft > 60) ? "s" : "");
|
||||
else if (timeleft)
|
||||
(void)fprintf(pf, "System going down in 30 seconds\n\n");
|
||||
else
|
||||
(void)fprintf(pf, "System going down IMMEDIATELY\n\n");
|
||||
|
||||
if (mbuflen)
|
||||
(void)fwrite(mbuf, sizeof(*mbuf), mbuflen, pf);
|
||||
|
||||
/*
|
||||
* play some games, just in case wall doesn't come back
|
||||
* probably unnecessary, given that wall is careful.
|
||||
*/
|
||||
if (!setjmp(alarmbuf)) {
|
||||
(void)signal(SIGALRM, timeout);
|
||||
(void)alarm((u_int)30);
|
||||
(void)pclose(pf);
|
||||
(void)alarm((u_int)0);
|
||||
(void)signal(SIGALRM, SIG_DFL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
/*ARGSUSED*/
|
||||
timeout(int signo)
|
||||
{
|
||||
longjmp(alarmbuf, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
die_you_gravy_sucking_pig_dog(void)
|
||||
{
|
||||
const char *what;
|
||||
|
||||
if (doreboot) {
|
||||
what = "reboot";
|
||||
} else if (dohalt && dopowerdown) {
|
||||
what = "poweroff";
|
||||
} else if (dohalt) {
|
||||
what = "halt";
|
||||
} else {
|
||||
what = "shutdown";
|
||||
}
|
||||
|
||||
syslog(LOG_NOTICE, "%s by %s: %s", what, whom, mbuf);
|
||||
(void)sleep(2);
|
||||
|
||||
(void)printf("\r\nSystem shutdown time has arrived\007\007\r\n");
|
||||
if (killflg) {
|
||||
(void)printf("\rbut you'll have to do it yourself\r\n");
|
||||
finish(0);
|
||||
}
|
||||
if (dofast)
|
||||
doitfast();
|
||||
dorcshutdown();
|
||||
if (doreboot || dohalt) {
|
||||
const char *args[20];
|
||||
const char **arg, *path;
|
||||
#ifndef DEBUG
|
||||
int serrno;
|
||||
#endif
|
||||
|
||||
arg = &args[0];
|
||||
if (doreboot) {
|
||||
path = _PATH_REBOOT;
|
||||
*arg++ = "reboot";
|
||||
} else {
|
||||
path = _PATH_HALT;
|
||||
*arg++ = "halt";
|
||||
}
|
||||
if (doverbose)
|
||||
*arg++ = "-v";
|
||||
if (dodebug)
|
||||
*arg++ = "-x";
|
||||
if (dosilent)
|
||||
*arg++ = "-z";
|
||||
if (dodump)
|
||||
*arg++ = "-d";
|
||||
if (nosync)
|
||||
*arg++ = "-n";
|
||||
if (dopowerdown)
|
||||
*arg++ = "-p";
|
||||
*arg++ = "-l";
|
||||
if (bootstr)
|
||||
*arg++ = bootstr;
|
||||
*arg++ = 0;
|
||||
#ifndef DEBUG
|
||||
(void)unlink(_PATH_NOLOGIN);
|
||||
(void)execve(path, __UNCONST(args), NULL);
|
||||
serrno = errno;
|
||||
syslog(LOG_ERR, "Can't exec `%s' (%m)", path);
|
||||
errno = serrno;
|
||||
warn("Can't exec `%s'", path);
|
||||
#else
|
||||
printf("%s", path);
|
||||
for (arg = &args[0]; *arg; arg++)
|
||||
printf(" %s", *arg);
|
||||
printf("\n");
|
||||
#endif
|
||||
} else {
|
||||
#ifndef DEBUG
|
||||
(void)kill(1, SIGTERM); /* to single user */
|
||||
#else
|
||||
printf("kill 1\n");
|
||||
#endif
|
||||
}
|
||||
finish(0);
|
||||
}
|
||||
|
||||
#define ATOI2(s) ((s) += 2, ((s)[-2] - '0') * 10 + ((s)[-1] - '0'))
|
||||
|
||||
static void
|
||||
getoffset(char *timearg)
|
||||
{
|
||||
struct tm *lt;
|
||||
char *p;
|
||||
time_t now;
|
||||
int yearset;
|
||||
|
||||
(void)time(&now);
|
||||
if (!strcasecmp(timearg, "now")) { /* now */
|
||||
offset = 0;
|
||||
shuttime = now;
|
||||
return;
|
||||
}
|
||||
|
||||
if (*timearg == '+') { /* +minutes */
|
||||
if (!isdigit((unsigned char)*++timearg))
|
||||
badtime();
|
||||
offset = atoi(timearg) * 60;
|
||||
shuttime = now + offset;
|
||||
return;
|
||||
}
|
||||
|
||||
/* handle hh:mm by getting rid of the colon */
|
||||
for (p = timearg; *p; ++p)
|
||||
if (!isascii(*p) || !isdigit((unsigned char)*p)) {
|
||||
if (*p == ':' && strlen(p) == 3) {
|
||||
p[0] = p[1];
|
||||
p[1] = p[2];
|
||||
p[2] = '\0';
|
||||
}
|
||||
else
|
||||
badtime();
|
||||
}
|
||||
|
||||
(void)unsetenv("TZ"); /* OUR timezone */
|
||||
lt = localtime(&now); /* current time val */
|
||||
|
||||
lt->tm_sec = 0;
|
||||
|
||||
yearset = 0;
|
||||
switch (strlen(timearg)) {
|
||||
case 12:
|
||||
lt->tm_year = ATOI2(timearg) * 100 - TM_YEAR_BASE;
|
||||
yearset = 1;
|
||||
/* FALLTHROUGH */
|
||||
case 10:
|
||||
if (yearset) {
|
||||
lt->tm_year += ATOI2(timearg);
|
||||
} else {
|
||||
yearset = ATOI2(timearg);
|
||||
if (yearset < 69)
|
||||
lt->tm_year = yearset + 2000 - TM_YEAR_BASE;
|
||||
else
|
||||
lt->tm_year = yearset + 1900 - TM_YEAR_BASE;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case 8:
|
||||
lt->tm_mon = ATOI2(timearg);
|
||||
--lt->tm_mon;
|
||||
/* FALLTHROUGH */
|
||||
case 6:
|
||||
lt->tm_mday = ATOI2(timearg);
|
||||
/* FALLTHROUGH */
|
||||
case 4:
|
||||
lt->tm_hour = ATOI2(timearg);
|
||||
/* FALLTHROUGH */
|
||||
case 2:
|
||||
lt->tm_min = ATOI2(timearg);
|
||||
break;
|
||||
default:
|
||||
badtime();
|
||||
}
|
||||
|
||||
if ((shuttime = mktime(lt)) == -1)
|
||||
badtime();
|
||||
if ((offset = shuttime - now) < 0)
|
||||
errx(1, "time is already past");
|
||||
}
|
||||
|
||||
static void
|
||||
dorcshutdown(void)
|
||||
{
|
||||
(void)printf("\r\nAbout to run shutdown hooks...\r\n");
|
||||
#ifndef DEBUG
|
||||
(void)setuid(0);
|
||||
(void)system(". " _PATH_RCSHUTDOWN);
|
||||
#endif
|
||||
(void)sleep(5); /* Give operator a chance to abort this. */
|
||||
(void)printf("\r\nDone running shutdown hooks.\r\n");
|
||||
}
|
||||
|
||||
#define FSMSG "fastboot file for fsck\n"
|
||||
static void
|
||||
doitfast(void)
|
||||
{
|
||||
int fastfd;
|
||||
|
||||
if ((fastfd = open(_PATH_FASTBOOT, O_WRONLY|O_CREAT|O_TRUNC,
|
||||
0664)) >= 0) {
|
||||
(void)write(fastfd, FSMSG, sizeof(FSMSG) - 1);
|
||||
(void)close(fastfd);
|
||||
}
|
||||
}
|
||||
|
||||
#define NOMSG "\n\nNO LOGINS: System going down at "
|
||||
static void
|
||||
nolog(void)
|
||||
{
|
||||
int logfd;
|
||||
char *ct;
|
||||
|
||||
(void)unlink(_PATH_NOLOGIN); /* in case linked to another file */
|
||||
(void)signal(SIGINT, finish);
|
||||
(void)signal(SIGHUP, finish);
|
||||
(void)signal(SIGQUIT, finish);
|
||||
(void)signal(SIGTERM, finish);
|
||||
if ((logfd = open(_PATH_NOLOGIN, O_WRONLY|O_CREAT|O_TRUNC,
|
||||
0664)) >= 0) {
|
||||
(void)write(logfd, NOMSG, sizeof(NOMSG) - 1);
|
||||
ct = ctime(&shuttime);
|
||||
(void)write(logfd, ct + 11, 5);
|
||||
(void)write(logfd, "\n\n", 2);
|
||||
(void)write(logfd, mbuf, strlen(mbuf));
|
||||
(void)close(logfd);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
/*ARGSUSED*/
|
||||
finish(int signo)
|
||||
{
|
||||
|
||||
if (!killflg)
|
||||
(void)unlink(_PATH_NOLOGIN);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static void
|
||||
badtime(void)
|
||||
{
|
||||
|
||||
warnx("illegal time format");
|
||||
usage();
|
||||
}
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
|
||||
(void)fprintf(stderr,
|
||||
"Usage: %s [-Ddfhknprvxz] [-b bootstr] time [message ... | -]\n",
|
||||
getprogname());
|
||||
exit(1);
|
||||
}
|
|
@ -5,11 +5,11 @@
|
|||
|
||||
.if ${MKIMAGEONLY} == "yes"
|
||||
|
||||
SUBDIR= ds init input mfs pfs pm rs sched vfs vm
|
||||
SUBDIR= ds input mfs pfs pm rs sched vfs vm
|
||||
|
||||
.else
|
||||
|
||||
SUBDIR= ds ext2 inet init input ipc is iso9660fs \
|
||||
SUBDIR= ds ext2 inet input ipc is iso9660fs \
|
||||
mfs pfs pm procfs rs sched vfs vm devman
|
||||
|
||||
.if ${MACHINE_ARCH} == "i386"
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
# Makefile for the init program (INIT)
|
||||
.include <bsd.own.mk>
|
||||
|
||||
PROG= init
|
||||
SRCS= init.c
|
||||
|
||||
MAN=
|
||||
|
||||
BINDIR?= /usr/sbin
|
||||
|
||||
.include <bsd.prog.mk>
|
|
@ -1,475 +0,0 @@
|
|||
/* This process is the father (mother) of all Minix user processes. When
|
||||
* Minix comes up, this is process number 2, and has a pid of 1. It
|
||||
* executes the /etc/rc shell file, and then reads the /etc/ttytab file to
|
||||
* determine which terminals need a login process.
|
||||
*
|
||||
* If the files /usr/adm/wtmp and /etc/utmp exist and are writable, init
|
||||
* (with help from login) will maintain login accounting. Sending a
|
||||
* signal 1 (SIGHUP) to init will cause it to rescan /etc/ttytab and start
|
||||
* up new shell processes if necessary. It will not, however, kill off
|
||||
* login processes for lines that have been turned off; do this manually.
|
||||
* Signal 15 (SIGTERM) makes init stop spawning new processes, this is
|
||||
* used by shutdown and friends when they are about to close the system
|
||||
* down.
|
||||
*/
|
||||
|
||||
#include <minix/type.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/svrctl.h>
|
||||
#include <ttyent.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <utmp.h>
|
||||
#include <minix/reboot.h>
|
||||
|
||||
/* Different ttyent structure. */
|
||||
struct ttyent TT_REBOOT = { "console", "shutdown -d now CTRL-ALT_DEL", "-"};
|
||||
|
||||
char PATH_UTMP[] = "/etc/utmp"; /* current logins */
|
||||
char PATH_WTMP[] = "/usr/adm/wtmp"; /* login/logout history */
|
||||
char PATH_ROOT_WTMP[] = "/etc/wtmp"; /* wtmp for system up/down events */
|
||||
|
||||
#define PIDSLOTS 32 /* first this many ttys can be on */
|
||||
|
||||
struct slotent {
|
||||
int errct; /* error count */
|
||||
pid_t pid; /* pid of login process for this tty line */
|
||||
};
|
||||
|
||||
#define ERRCT_DISABLE 10 /* disable after this many errors */
|
||||
#define NO_PID 0 /* pid value indicating no process */
|
||||
|
||||
struct slotent slots[PIDSLOTS]; /* init table of ttys and pids */
|
||||
|
||||
int gothup = 0; /* flag, showing signal 1 was received */
|
||||
int gotabrt = 0; /* flag, showing signal 6 was received */
|
||||
int spawn = 1; /* flag, spawn processes only when set */
|
||||
|
||||
void tell(int fd, char *s);
|
||||
void report(int fd, char *label);
|
||||
void wtmp(int type, int linenr, char *line, pid_t pid);
|
||||
void startup(int linenr, struct ttyent *ttyp);
|
||||
int execute(char **cmd);
|
||||
char **construct_argv(char *cmd);
|
||||
void onhup(int sig);
|
||||
void onterm(int sig);
|
||||
void onabrt(int sig);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
pid_t pid; /* pid of child process */
|
||||
int fd; /* generally useful */
|
||||
int linenr; /* loop variable */
|
||||
int check; /* check if a new process must be spawned */
|
||||
int sn; /* signal number */
|
||||
struct slotent *slotp; /* slots[] pointer */
|
||||
struct ttyent *ttyp; /* ttytab entry */
|
||||
struct sigaction sa;
|
||||
struct stat stb;
|
||||
|
||||
#define OPENFDS \
|
||||
if (fstat(0, &stb) < 0) { \
|
||||
/* Open standard input, output & error. */ \
|
||||
(void) open("/dev/null", O_RDONLY); \
|
||||
(void) open("/dev/log", O_WRONLY); \
|
||||
dup(1); \
|
||||
}
|
||||
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_flags = 0;
|
||||
|
||||
/* Default: Ignore every signal (except those that follow). */
|
||||
sa.sa_handler = SIG_IGN;
|
||||
for (sn = 1; sn < _NSIG; sn++) {
|
||||
sigaction(sn, &sa, NULL);
|
||||
}
|
||||
|
||||
/* Hangup: Reexamine /etc/ttytab for newly enabled terminal lines. */
|
||||
sa.sa_handler = onhup;
|
||||
sigaction(SIGHUP, &sa, NULL);
|
||||
|
||||
/* Terminate: Stop spawning login processes, shutdown is near. */
|
||||
sa.sa_handler = onterm;
|
||||
sigaction(SIGTERM, &sa, NULL);
|
||||
|
||||
/* Abort: Sent by the kernel on CTRL-ALT-DEL; shut the system down. */
|
||||
sa.sa_handler = onabrt;
|
||||
sigaction(SIGABRT, &sa, NULL);
|
||||
|
||||
/* Execute the /etc/rc file. */
|
||||
if ((pid = fork()) != 0) {
|
||||
/* Parent just waits. */
|
||||
while (wait(NULL) != pid) {
|
||||
if (gotabrt) reboot(RBT_HALT);
|
||||
}
|
||||
} else {
|
||||
#if ! SYS_GETKENV
|
||||
struct sysgetenv sysgetenv;
|
||||
#endif
|
||||
char bootopts[16];
|
||||
static char *rc_command[] = { "sh", "/etc/rc", NULL, NULL, NULL };
|
||||
char **rcp = rc_command + 2;
|
||||
|
||||
/* Get the boot options from the boot environment. */
|
||||
sysgetenv.key = "bootopts";
|
||||
sysgetenv.keylen = 8+1;
|
||||
sysgetenv.val = bootopts;
|
||||
sysgetenv.vallen = sizeof(bootopts);
|
||||
if (svrctl(PMGETPARAM, &sysgetenv) == 0) *rcp++ = bootopts;
|
||||
*rcp = "start";
|
||||
|
||||
execute(rc_command);
|
||||
report(2, "sh /etc/rc");
|
||||
_exit(1); /* impossible, we hope */
|
||||
}
|
||||
|
||||
OPENFDS;
|
||||
|
||||
/* Clear /etc/utmp if it exists. */
|
||||
if ((fd = open(PATH_UTMP, O_WRONLY | O_TRUNC)) >= 0) close(fd);
|
||||
|
||||
/* Log system reboot. */
|
||||
wtmp(BOOT_TIME, 0, NULL, 0);
|
||||
|
||||
/* Main loop. If login processes have already been started up, wait for one
|
||||
* to terminate, or for a HUP signal to arrive. Start up new login processes
|
||||
* for all ttys which don't have them. Note that wait() also returns when
|
||||
* somebody's orphan dies, in which case ignore it. If the TERM signal is
|
||||
* sent then stop spawning processes, shutdown time is near.
|
||||
*/
|
||||
|
||||
check = 1;
|
||||
while (1) {
|
||||
while ((pid = waitpid(-1, NULL, check ? WNOHANG : 0)) > 0) {
|
||||
/* Search to see which line terminated. */
|
||||
for (linenr = 0; linenr < PIDSLOTS; linenr++) {
|
||||
slotp = &slots[linenr];
|
||||
if (slotp->pid == pid) {
|
||||
/* Record process exiting. */
|
||||
wtmp(DEAD_PROCESS, linenr, NULL, pid);
|
||||
slotp->pid = NO_PID;
|
||||
check = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If a signal 1 (SIGHUP) is received, simply reset error counts. */
|
||||
if (gothup) {
|
||||
gothup = 0;
|
||||
for (linenr = 0; linenr < PIDSLOTS; linenr++) {
|
||||
slots[linenr].errct = 0;
|
||||
}
|
||||
check = 1;
|
||||
}
|
||||
|
||||
/* Shut down on signal 6 (SIGABRT). */
|
||||
if (gotabrt) {
|
||||
gotabrt = 0;
|
||||
startup(0, &TT_REBOOT);
|
||||
}
|
||||
|
||||
if (spawn && check) {
|
||||
/* See which lines need a login process started up. */
|
||||
for (linenr = 0; linenr < PIDSLOTS; linenr++) {
|
||||
slotp = &slots[linenr];
|
||||
if ((ttyp = getttyent()) == NULL) break;
|
||||
|
||||
if (ttyp->ty_getty != NULL
|
||||
/* ty_getty is a string, and TTY_ON is
|
||||
* the way to check for enabled ternimanls. */
|
||||
&& (ttyp->ty_status & TTY_ON)
|
||||
&& slotp->pid == NO_PID
|
||||
&& slotp->errct < ERRCT_DISABLE)
|
||||
{
|
||||
startup(linenr, ttyp);
|
||||
}
|
||||
}
|
||||
endttyent();
|
||||
}
|
||||
check = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void onhup(int sig)
|
||||
{
|
||||
gothup = 1;
|
||||
spawn = 1;
|
||||
}
|
||||
|
||||
void onterm(int sig)
|
||||
{
|
||||
spawn = 0;
|
||||
}
|
||||
|
||||
void onabrt(int sig)
|
||||
{
|
||||
static int count = 0;
|
||||
|
||||
if (++count == 2) reboot(RBT_HALT);
|
||||
gotabrt = 1;
|
||||
}
|
||||
|
||||
void startup(int linenr, struct ttyent *ttyp)
|
||||
{
|
||||
/* Fork off a process for the indicated line. */
|
||||
|
||||
struct slotent *slotp; /* pointer to ttyslot */
|
||||
pid_t pid; /* new pid */
|
||||
int err[2]; /* error reporting pipe */
|
||||
char line[32]; /* tty device name */
|
||||
char **ty_getty_argv;
|
||||
|
||||
slotp = &slots[linenr];
|
||||
|
||||
/* Error channel for between fork and exec. */
|
||||
if (pipe(err) < 0) err[0] = err[1] = -1;
|
||||
|
||||
if ((pid = fork()) == -1 ) {
|
||||
report(2, "fork()");
|
||||
sleep(10);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pid == 0) {
|
||||
/* Child */
|
||||
close(err[0]);
|
||||
fcntl(err[1], F_SETFD, fcntl(err[1], F_GETFD) | FD_CLOEXEC);
|
||||
|
||||
/* A new session. */
|
||||
setsid();
|
||||
|
||||
/* Construct device name. */
|
||||
strcpy(line, "/dev/");
|
||||
strncat(line, ttyp->ty_name, sizeof(line) - 6);
|
||||
|
||||
/* Open the line for standard input and output. */
|
||||
close(0);
|
||||
close(1);
|
||||
if (open(line, O_RDWR) < 0 || dup(0) < 0) {
|
||||
write(err[1], &errno, sizeof(errno));
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
/* Redirect standard error too. */
|
||||
dup2(0, 2);
|
||||
|
||||
/* Construct argv for execute() */
|
||||
ty_getty_argv = construct_argv(ttyp->ty_getty);
|
||||
if (ty_getty_argv == NULL) {
|
||||
report(2, "construct_argv");
|
||||
} else {
|
||||
/* Execute the getty process. */
|
||||
execute(ty_getty_argv);
|
||||
}
|
||||
|
||||
/* Oops, disaster strikes. */
|
||||
fcntl(2, F_SETFL, fcntl(2, F_GETFL) | O_NONBLOCK);
|
||||
if (linenr != 0 && ty_getty_argv) report(2, ty_getty_argv[0]);
|
||||
write(err[1], &errno, sizeof(errno));
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
/* Parent */
|
||||
if (ttyp != &TT_REBOOT) slotp->pid = pid;
|
||||
|
||||
close(err[1]);
|
||||
if (read(err[0], &errno, sizeof(errno)) != 0) {
|
||||
/* If an errno value goes down the error pipe: Problems. */
|
||||
|
||||
switch (errno) {
|
||||
case ENOENT:
|
||||
case ENODEV:
|
||||
case ENXIO:
|
||||
/* Device nonexistent, no driver, or no minor device. */
|
||||
slotp->errct = ERRCT_DISABLE;
|
||||
close(err[0]);
|
||||
return;
|
||||
case 0:
|
||||
/* Error already reported. */
|
||||
break;
|
||||
default:
|
||||
/* Any other error on the line. */
|
||||
report(2, ttyp->ty_name);
|
||||
}
|
||||
close(err[0]);
|
||||
|
||||
if (++slotp->errct >= ERRCT_DISABLE) {
|
||||
tell(2, "init: ");
|
||||
tell(2, ttyp->ty_name);
|
||||
tell(2, ": excessive errors, shutting down\n");
|
||||
} else {
|
||||
sleep(5);
|
||||
}
|
||||
return;
|
||||
}
|
||||
close(err[0]);
|
||||
|
||||
if (ttyp != &TT_REBOOT) wtmp(LOGIN_PROCESS, linenr, ttyp->ty_name, pid);
|
||||
slotp->errct = 0;
|
||||
}
|
||||
|
||||
int execute(char **cmd)
|
||||
{
|
||||
/* Execute a command with a path search along /sbin:/bin:/usr/sbin:/usr/bin.
|
||||
*/
|
||||
static char *nullenv[] = { NULL };
|
||||
char command[128];
|
||||
char *path[] = { "/sbin", "/bin", "/usr/sbin", "/usr/bin" };
|
||||
int i;
|
||||
|
||||
if (cmd[0][0] == '/') {
|
||||
/* A full path. */
|
||||
return execve(cmd[0], cmd, nullenv);
|
||||
}
|
||||
|
||||
/* Path search. */
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (strlen(path[i]) + 1 + strlen(cmd[0]) + 1 > sizeof(command)) {
|
||||
errno= ENAMETOOLONG;
|
||||
return -1;
|
||||
}
|
||||
strcpy(command, path[i]);
|
||||
strcat(command, "/");
|
||||
strcat(command, cmd[0]);
|
||||
execve(command, cmd, nullenv);
|
||||
if (errno != ENOENT) break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void wtmp(type, linenr, line, pid)
|
||||
int type; /* type of entry */
|
||||
int linenr; /* line number in ttytab */
|
||||
char *line; /* tty name (only good on login) */
|
||||
pid_t pid; /* pid of process */
|
||||
{
|
||||
/* Log an event into the UTMP and WTMP files. */
|
||||
|
||||
struct utmp utmp; /* UTMP/WTMP User Accounting */
|
||||
int fd;
|
||||
|
||||
/* Clear the utmp record. */
|
||||
memset((void *) &utmp, 0, sizeof(utmp));
|
||||
|
||||
/* Fill in utmp. */
|
||||
switch (type) {
|
||||
case BOOT_TIME:
|
||||
/* Make a special reboot record. */
|
||||
strcpy(utmp.ut_name, "reboot");
|
||||
strcpy(utmp.ut_line, "~");
|
||||
break;
|
||||
|
||||
case LOGIN_PROCESS:
|
||||
/* A new login, fill in line name. */
|
||||
strncpy(utmp.ut_line, line, sizeof(utmp.ut_line));
|
||||
break;
|
||||
|
||||
case DEAD_PROCESS:
|
||||
/* A logout. Use the current utmp entry, but make sure it is a
|
||||
* user process exiting, and not getty or login giving up.
|
||||
*/
|
||||
if ((fd = open(PATH_UTMP, O_RDONLY)) < 0) {
|
||||
if (errno != ENOENT) report(2, PATH_UTMP);
|
||||
return;
|
||||
}
|
||||
if (lseek(fd, (off_t) (linenr+1) * sizeof(utmp), SEEK_SET) == -1
|
||||
|| read(fd, &utmp, sizeof(utmp)) == -1
|
||||
) {
|
||||
report(2, PATH_UTMP);
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
close(fd);
|
||||
if (utmp.ut_type != USER_PROCESS) return;
|
||||
strncpy(utmp.ut_name, "", sizeof(utmp.ut_name));
|
||||
break;
|
||||
}
|
||||
|
||||
/* Finish new utmp entry. */
|
||||
utmp.ut_pid = pid;
|
||||
utmp.ut_type = type;
|
||||
utmp.ut_time = time((time_t *) 0);
|
||||
|
||||
switch (type) {
|
||||
case LOGIN_PROCESS:
|
||||
case DEAD_PROCESS:
|
||||
/* Write new entry to utmp. */
|
||||
if ((fd = open(PATH_UTMP, O_WRONLY)) < 0
|
||||
|| lseek(fd, (off_t) (linenr+1) * sizeof(utmp), SEEK_SET) == -1
|
||||
|| write(fd, &utmp, sizeof(utmp)) == -1
|
||||
) {
|
||||
if (errno != ENOENT) report(2, PATH_UTMP);
|
||||
}
|
||||
if (fd != -1) close(fd);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case BOOT_TIME:
|
||||
/* Add new root wtmp entry. */
|
||||
if ((fd = open(PATH_ROOT_WTMP, O_WRONLY | O_APPEND)) < 0
|
||||
|| write(fd, &utmp, sizeof(utmp)) == -1
|
||||
) {
|
||||
if (errno != ENOENT) report(2, PATH_ROOT_WTMP);
|
||||
}
|
||||
if (fd != -1) close(fd);
|
||||
/* fall-through */
|
||||
case DEAD_PROCESS:
|
||||
/* Add new wtmp entry. */
|
||||
if ((fd = open(PATH_WTMP, O_WRONLY | O_APPEND)) < 0
|
||||
|| write(fd, &utmp, sizeof(utmp)) == -1
|
||||
) {
|
||||
if (errno != ENOENT) report(2, PATH_WTMP);
|
||||
}
|
||||
if (fd != -1) close(fd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
char **
|
||||
construct_argv(char *cmd)
|
||||
{
|
||||
int argc = 0;
|
||||
static const char sep[] = " \t";
|
||||
char **argv = malloc(((strlen(cmd) + 1) / 2 + 1) * sizeof (char *));
|
||||
|
||||
if (argv == NULL)
|
||||
return NULL;
|
||||
|
||||
if ((argv[argc++] = strtok(cmd, sep)) == 0) {
|
||||
free(argv);
|
||||
return NULL;
|
||||
}
|
||||
while ((argv[argc++] = strtok(NULL, sep)) != NULL)
|
||||
continue;
|
||||
return argv;
|
||||
}
|
||||
|
||||
void tell(fd, s)
|
||||
int fd;
|
||||
char *s;
|
||||
{
|
||||
write(fd, s, strlen(s));
|
||||
}
|
||||
|
||||
void report(fd, label)
|
||||
int fd;
|
||||
char *label;
|
||||
{
|
||||
int err = errno;
|
||||
|
||||
tell(fd, "init: ");
|
||||
tell(fd, label);
|
||||
tell(fd, ": ");
|
||||
tell(fd, strerror(err));
|
||||
tell(fd, "\n");
|
||||
errno= err;
|
||||
}
|
|
@ -258,9 +258,13 @@ int read_super(struct super_block *sp)
|
|||
|
||||
magic = sp->s_magic; /* determines file system type */
|
||||
|
||||
if(magic == SUPER_V2 || magic == SUPER_MAGIC) {
|
||||
printf("MFS: only supports V3 filesystems.\n");
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
/* Get file system version and type - only support v3. */
|
||||
if(magic != SUPER_V3) {
|
||||
printf("MFS: only supports V3 filesystems.\n");
|
||||
return EINVAL;
|
||||
}
|
||||
version = V3;
|
||||
|
|
|
@ -13,11 +13,11 @@
|
|||
#include <minix/callnr.h>
|
||||
#include <signal.h>
|
||||
#include <sys/svrctl.h>
|
||||
#include <sys/reboot.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <minix/com.h>
|
||||
#include <minix/config.h>
|
||||
#include <minix/reboot.h>
|
||||
#include <minix/sysinfo.h>
|
||||
#include <minix/type.h>
|
||||
#include <minix/ds.h>
|
||||
|
@ -213,10 +213,9 @@ int do_reboot()
|
|||
|
||||
/* See how the system should be aborted. */
|
||||
abort_flag = (unsigned) m_in.PM_REBOOT_HOW;
|
||||
if (abort_flag >= RBT_INVALID) return(EINVAL);
|
||||
|
||||
/* notify readclock (some arm systems power off via RTC alarms) */
|
||||
if (abort_flag == RBT_POWEROFF) {
|
||||
if (abort_flag & RB_POWERDOWN) {
|
||||
endpoint_t readclock_ep;
|
||||
if (ds_retrieve_label_endpt("readclock.drv", &readclock_ep) == OK) {
|
||||
message m; /* no params to set, nothing we can do if it fails */
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioc_tty.h>
|
||||
#include <minix/callnr.h>
|
||||
#include <minix/com.h>
|
||||
#include <minix/endpoint.h>
|
||||
|
@ -267,6 +268,13 @@ int cdev_io(
|
|||
if ((dp = cdev_get(dev, &minor_dev)) == NULL)
|
||||
return(EIO);
|
||||
|
||||
/* Handle TIOCSCTTY ioctl: set controlling tty.
|
||||
* TODO: cleaner implementation work in progress.
|
||||
*/
|
||||
if (op == CDEV_IOCTL && bytes == TIOCSCTTY && major(dev) == TTY_MAJOR) {
|
||||
fp->fp_tty = dev;
|
||||
}
|
||||
|
||||
/* Create a grant for the buffer provided by the user process. */
|
||||
gid = make_grant(dp->dmap_driver, proc_e, op, buf, bytes);
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ SUBDIR= asa \
|
|||
fsplit ftp genassym getopt \
|
||||
head hexdump id indent infocmp join jot \
|
||||
lam ldd leave \
|
||||
last \
|
||||
lock login logname lorder m4 \
|
||||
machine make man menuc mesg \
|
||||
mkdep mkfifo mkstr mktemp \
|
||||
|
@ -30,8 +31,9 @@ SUBDIR= asa \
|
|||
toproto \
|
||||
uniq units unvis unzip users \
|
||||
uuidgen vis \
|
||||
uniq uname units unzip users \
|
||||
wall wc what whatis who whois \
|
||||
\
|
||||
wc what who whois \
|
||||
write xargs xinstall xstr yes
|
||||
|
||||
.if !defined(__MINIX)
|
||||
|
|
10
usr.bin/last/Makefile
Normal file
10
usr.bin/last/Makefile
Normal file
|
@ -0,0 +1,10 @@
|
|||
# $NetBSD: Makefile,v 1.7 2004/11/19 21:41:25 christos Exp $
|
||||
# @(#)Makefile 8.1 (Berkeley) 6/6/93
|
||||
|
||||
PROG= last
|
||||
CPPFLAGS+=-DSUPPORT_UTMPX -DSUPPORT_UTMP
|
||||
|
||||
LDADD=-lutil
|
||||
DPADD=${LIBUTIL}
|
||||
|
||||
.include <bsd.prog.mk>
|
161
usr.bin/last/last.1
Normal file
161
usr.bin/last/last.1
Normal file
|
@ -0,0 +1,161 @@
|
|||
.\" $NetBSD: last.1,v 1.20 2012/05/12 14:52:57 reed Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1980, 1990, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" @(#)last.1 8.1 (Berkeley) 6/6/93
|
||||
.\"
|
||||
.Dd October 18, 2011
|
||||
.Dt LAST 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm last
|
||||
.Nd indicate last logins of users and ttys
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl Ns Ar n
|
||||
.Op Fl nTx
|
||||
.Op Fl f Ar file
|
||||
.Op Fl H Ar hostsize
|
||||
.Op Fl h Ar host
|
||||
.Op Fl L Ar linesize
|
||||
.Op Fl N Ar namesize
|
||||
.Op Fl t Ar tty
|
||||
.Op user ...
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
will list the sessions of specified
|
||||
.Ar users ,
|
||||
.Ar ttys ,
|
||||
and
|
||||
.Ar hosts ,
|
||||
in reverse time order.
|
||||
Each line of output contains
|
||||
the user name, the tty from which the session was conducted, any
|
||||
hostname, the start and stop times for the session, and the duration
|
||||
of the session.
|
||||
If the session is still continuing or was cut short by
|
||||
a crash or shutdown,
|
||||
.Nm
|
||||
will so indicate.
|
||||
.Pp
|
||||
The following options are available:
|
||||
.Pp
|
||||
.Bl -tag -width xHxhostsizexx
|
||||
.It Fl Ar n
|
||||
Limits the report to
|
||||
.Ar n
|
||||
lines.
|
||||
.It Fl f Ar file
|
||||
.Nm
|
||||
reads the file
|
||||
.Ar file
|
||||
instead of the default,
|
||||
.Pa /var/log/wtmpx
|
||||
or
|
||||
.Pa /var/log/wtmp .
|
||||
If the file ends with
|
||||
.Sq x ,
|
||||
it is treated as a
|
||||
.Xr utmpx 5
|
||||
format file, else it is treated as a
|
||||
.Xr utmp 5
|
||||
format file.
|
||||
If the file is ``-'', standard input is used.
|
||||
.It Fl H Ar hostsize
|
||||
Use the provided hostsize as the width to format the host name field.
|
||||
.It Fl h Ar host
|
||||
.Ar Host
|
||||
names may be names or internet numbers.
|
||||
.It Fl L Ar linesize
|
||||
Use the provided linesize as the width to format the tty field.
|
||||
.It Fl N Ar namesize
|
||||
Use the provided namesize as the width to format the login name field.
|
||||
.It Fl n
|
||||
Print host addresses numerically.
|
||||
This option works only on
|
||||
.Xr wtmpx 5
|
||||
entries,
|
||||
and prints nothing on
|
||||
.Xr wtmp 5
|
||||
entries.
|
||||
.It Fl T
|
||||
Display better time information, including the year and seconds.
|
||||
.It Fl t Ar tty
|
||||
Specify the
|
||||
.Ar tty .
|
||||
Tty names may be given fully or abbreviated, for example,
|
||||
.Dq Li "last -t 03"
|
||||
is equivalent to
|
||||
.Dq Li "last -t tty03" .
|
||||
.It Fl x
|
||||
Assume that the file given is in
|
||||
.Xr wtmpx 5
|
||||
format, even if the filename does not end with an
|
||||
.Sq x .
|
||||
Also useful when reading such format from standard input.
|
||||
.El
|
||||
.Pp
|
||||
If multiple arguments are given, the information which applies to any of the
|
||||
arguments is printed, e.g.,
|
||||
.Dq Li "last root -t console"
|
||||
would list all of
|
||||
.Dq Li root Ns 's
|
||||
sessions as well as all sessions on the console terminal.
|
||||
If no users, hostnames, or terminals are specified,
|
||||
.Nm
|
||||
prints a record of all logins and logouts.
|
||||
.Pp
|
||||
The pseudo-user
|
||||
.Ar reboot
|
||||
logs in at reboots of the system, thus
|
||||
.Dq Li last reboot
|
||||
will give an indication of mean time between reboot.
|
||||
.Pp
|
||||
If
|
||||
.Nm
|
||||
is interrupted, it indicates to what date the search has progressed.
|
||||
If interrupted with a quit signal
|
||||
.Nm
|
||||
indicates how far the search has progressed and then continues.
|
||||
.Sh FILES
|
||||
.Bl -tag -width /var/log/wtmpx -compact
|
||||
.It Pa /var/log/wtmp
|
||||
login data base
|
||||
.It Pa /var/log/wtmpx
|
||||
login data base
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr lastcomm 1 ,
|
||||
.Xr utmp 5 ,
|
||||
.Xr utmpx 5 ,
|
||||
.Xr ac 8 ,
|
||||
.Xr lastlogin 8
|
||||
.Sh HISTORY
|
||||
.Nm
|
||||
appeared in
|
||||
.Bx 1 .
|
405
usr.bin/last/last.c
Normal file
405
usr.bin/last/last.c
Normal file
|
@ -0,0 +1,405 @@
|
|||
/* $NetBSD: last.c,v 1.36 2012/03/15 03:04:05 dholland Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1987, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__COPYRIGHT("@(#) Copyright (c) 1987, 1993, 1994\
|
||||
The Regents of the University of California. All rights reserved.");
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)last.c 8.2 (Berkeley) 4/2/94";
|
||||
#endif
|
||||
__RCSID("$NetBSD: last.c,v 1.36 2012/03/15 03:04:05 dholland Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <paths.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <tzfile.h>
|
||||
#include <unistd.h>
|
||||
#include <arpa/inet.h>
|
||||
#ifdef SUPPORT_UTMPX
|
||||
#include <utmpx.h>
|
||||
#endif
|
||||
#ifdef SUPPORT_UTMP
|
||||
#include <utmp.h>
|
||||
#endif
|
||||
#include <util.h>
|
||||
|
||||
#ifndef UT_NAMESIZE
|
||||
#define UT_NAMESIZE 8
|
||||
#define UT_LINESIZE 8
|
||||
#define UT_HOSTSIZE 16
|
||||
#endif
|
||||
#ifndef SIGNATURE
|
||||
#define SIGNATURE -1
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define NO 0 /* false/no */
|
||||
#define YES 1 /* true/yes */
|
||||
|
||||
#define TBUFLEN 30 /* length of time string buffer */
|
||||
#define TFMT "%a %b %d %R" /* strftime format string */
|
||||
#define LTFMT "%a %b %d %Y %T" /* strftime long format string */
|
||||
#define TFMTS "%R" /* strftime format string - time only */
|
||||
#define LTFMTS "%T" /* strftime long format string - " */
|
||||
|
||||
/* fmttime() flags */
|
||||
#define FULLTIME 0x1 /* show year, seconds */
|
||||
#define TIMEONLY 0x2 /* show time only, not date */
|
||||
#define GMT 0x4 /* show time at GMT, for offsets only */
|
||||
|
||||
#define MAXUTMP 1024
|
||||
|
||||
typedef struct arg {
|
||||
const char *name; /* argument */
|
||||
#define HOST_TYPE -2
|
||||
#define TTY_TYPE -3
|
||||
#define USER_TYPE -4
|
||||
int type; /* type of arg */
|
||||
struct arg *next; /* linked list pointer */
|
||||
} ARG;
|
||||
static ARG *arglist; /* head of linked list */
|
||||
|
||||
typedef struct ttytab {
|
||||
time_t logout; /* log out time */
|
||||
char tty[128]; /* terminal name */
|
||||
struct ttytab *next; /* linked list pointer */
|
||||
} TTY;
|
||||
static TTY *ttylist; /* head of linked list */
|
||||
|
||||
static time_t currentout; /* current logout value */
|
||||
static long maxrec; /* records to display */
|
||||
static int fulltime = 0; /* Display seconds? */
|
||||
static int xflag; /* Assume file is wtmpx format */
|
||||
|
||||
static void addarg(int, const char *);
|
||||
static TTY *addtty(const char *);
|
||||
static void hostconv(char *);
|
||||
static const char *ttyconv(char *);
|
||||
#ifdef SUPPORT_UTMPX
|
||||
static void wtmpx(const char *, int, int, int, int);
|
||||
#endif
|
||||
#ifdef SUPPORT_UTMP
|
||||
static void wtmp(const char *, int, int, int, int);
|
||||
#endif
|
||||
static char *fmttime(time_t, int);
|
||||
__dead static void usage(void);
|
||||
|
||||
static
|
||||
void usage(void)
|
||||
{
|
||||
(void)fprintf(stderr, "usage: %s [-#%s] [-nTx] [-f file]"
|
||||
" [-H hostsize] [-h host] [-L linesize]\n"
|
||||
"\t [-N namesize] [-t tty] [user ...]\n", getprogname(),
|
||||
#ifdef NOTYET_SUPPORT_UTMPX
|
||||
"w"
|
||||
#else
|
||||
""
|
||||
#endif
|
||||
);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int ch;
|
||||
char *p;
|
||||
const char *file = NULL;
|
||||
int namesize = UT_NAMESIZE;
|
||||
int linesize = UT_LINESIZE;
|
||||
int hostsize = UT_HOSTSIZE;
|
||||
int numeric = 0;
|
||||
|
||||
maxrec = -1;
|
||||
|
||||
while ((ch = getopt(argc, argv, "0123456789f:H:h:L:nN:Tt:x")) != -1)
|
||||
switch (ch) {
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
/*
|
||||
* kludge: last was originally designed to take
|
||||
* a number after a dash.
|
||||
*/
|
||||
if (maxrec == -1) {
|
||||
p = argv[optind - 1];
|
||||
if (p[0] == '-' && p[1] == ch && !p[2])
|
||||
maxrec = atol(++p);
|
||||
else if (optind < argc)
|
||||
maxrec = atol(argv[optind] + 1);
|
||||
else
|
||||
usage();
|
||||
if (!maxrec)
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case 'f':
|
||||
file = optarg;
|
||||
if ('\0' == file[0])
|
||||
usage();
|
||||
break;
|
||||
case 'H':
|
||||
hostsize = atoi(optarg);
|
||||
if (hostsize < 1)
|
||||
usage();
|
||||
break;
|
||||
case 'h':
|
||||
hostconv(optarg);
|
||||
addarg(HOST_TYPE, optarg);
|
||||
break;
|
||||
case 'L':
|
||||
linesize = atoi(optarg);
|
||||
if (linesize < 1)
|
||||
usage();
|
||||
break;
|
||||
case 'N':
|
||||
namesize = atoi(optarg);
|
||||
if (namesize < 1)
|
||||
usage();
|
||||
break;
|
||||
case 'n':
|
||||
numeric = 1;
|
||||
break;
|
||||
case 'T':
|
||||
fulltime = 1;
|
||||
break;
|
||||
case 't':
|
||||
addarg(TTY_TYPE, ttyconv(optarg));
|
||||
break;
|
||||
case 'x':
|
||||
xflag = 1;
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
|
||||
if (argc) {
|
||||
setlinebuf(stdout);
|
||||
for (argv += optind; *argv; ++argv) {
|
||||
#define COMPATIBILITY
|
||||
#ifdef COMPATIBILITY
|
||||
/* code to allow "last p5" to work */
|
||||
addarg(TTY_TYPE, ttyconv(*argv));
|
||||
#endif
|
||||
addarg(USER_TYPE, *argv);
|
||||
}
|
||||
}
|
||||
if (file == NULL) {
|
||||
#ifdef SUPPORT_UTMPX
|
||||
if (access(_PATH_WTMPX, R_OK) == 0)
|
||||
file = _PATH_WTMPX;
|
||||
else
|
||||
#endif
|
||||
#ifdef SUPPORT_UTMP
|
||||
if (access(_PATH_WTMP, R_OK) == 0)
|
||||
file = _PATH_WTMP;
|
||||
#endif
|
||||
if (file == NULL)
|
||||
#if defined(SUPPORT_UTMPX) && defined(SUPPORT_UTMP)
|
||||
errx(EXIT_FAILURE, "Cannot access `%s' or `%s'", _PATH_WTMPX,
|
||||
_PATH_WTMP);
|
||||
#elif defined(SUPPORT_UTMPX)
|
||||
errx(EXIT_FAILURE, "Cannot access `%s'", _PATH_WTMPX);
|
||||
#elif defined(SUPPORT_UTMP)
|
||||
errx(EXIT_FAILURE, "Cannot access `%s'", _PATH_WTMP);
|
||||
#else
|
||||
errx(EXIT_FAILURE, "No utmp or utmpx support compiled in.");
|
||||
#endif
|
||||
}
|
||||
#if defined(SUPPORT_UTMPX) && defined(SUPPORT_UTMP)
|
||||
if (file[strlen(file) - 1] == 'x' || xflag)
|
||||
wtmpx(file, namesize, linesize, hostsize, numeric);
|
||||
else
|
||||
wtmp(file, namesize, linesize, hostsize, numeric);
|
||||
#elif defined(SUPPORT_UTMPX)
|
||||
wtmpx(file, namesize, linesize, hostsize, numeric);
|
||||
#elif defined(SUPPORT_UTMP)
|
||||
wtmp(file, namesize, linesize, hostsize, numeric);
|
||||
#else
|
||||
errx(EXIT_FAILURE, "No utmp or utmpx support compiled in.");
|
||||
#endif
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* addarg --
|
||||
* add an entry to a linked list of arguments
|
||||
*/
|
||||
static void
|
||||
addarg(int type, const char *arg)
|
||||
{
|
||||
ARG *cur;
|
||||
|
||||
if (!(cur = (ARG *)malloc(sizeof(ARG))))
|
||||
err(EXIT_FAILURE, "malloc failure");
|
||||
cur->next = arglist;
|
||||
cur->type = type;
|
||||
cur->name = arg;
|
||||
arglist = cur;
|
||||
}
|
||||
|
||||
/*
|
||||
* addtty --
|
||||
* add an entry to a linked list of ttys
|
||||
*/
|
||||
static TTY *
|
||||
addtty(const char *tty)
|
||||
{
|
||||
TTY *cur;
|
||||
|
||||
if (!(cur = (TTY *)malloc(sizeof(TTY))))
|
||||
err(EXIT_FAILURE, "malloc failure");
|
||||
cur->next = ttylist;
|
||||
cur->logout = currentout;
|
||||
memmove(cur->tty, tty, sizeof(cur->tty));
|
||||
return (ttylist = cur);
|
||||
}
|
||||
|
||||
/*
|
||||
* hostconv --
|
||||
* convert the hostname to search pattern; if the supplied host name
|
||||
* has a domain attached that is the same as the current domain, rip
|
||||
* off the domain suffix since that's what login(1) does.
|
||||
*/
|
||||
static void
|
||||
hostconv(char *arg)
|
||||
{
|
||||
static int first = 1;
|
||||
static char *hostdot, name[MAXHOSTNAMELEN + 1];
|
||||
char *argdot;
|
||||
|
||||
if (!(argdot = strchr(arg, '.')))
|
||||
return;
|
||||
if (first) {
|
||||
first = 0;
|
||||
if (gethostname(name, sizeof(name)))
|
||||
err(EXIT_FAILURE, "gethostname");
|
||||
name[sizeof(name) - 1] = '\0';
|
||||
hostdot = strchr(name, '.');
|
||||
}
|
||||
if (hostdot && !strcasecmp(hostdot, argdot))
|
||||
*argdot = '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
* ttyconv --
|
||||
* convert tty to correct name.
|
||||
*/
|
||||
static const char *
|
||||
ttyconv(char *arg)
|
||||
{
|
||||
char *mval;
|
||||
|
||||
if (!strcmp(arg, "co"))
|
||||
return ("console");
|
||||
/*
|
||||
* kludge -- we assume that all tty's end with
|
||||
* a two character suffix.
|
||||
*/
|
||||
if (strlen(arg) == 2) {
|
||||
if (asprintf(&mval, "tty%s", arg) == -1)
|
||||
err(EXIT_FAILURE, "malloc failure");
|
||||
return (mval);
|
||||
}
|
||||
if (!strncmp(arg, _PATH_DEV, sizeof(_PATH_DEV) - 1))
|
||||
return (&arg[sizeof(_PATH_DEV) - 1]);
|
||||
return (arg);
|
||||
}
|
||||
|
||||
/*
|
||||
* fmttime --
|
||||
* return pointer to (static) formatted time string.
|
||||
*/
|
||||
static char *
|
||||
fmttime(time_t t, int flags)
|
||||
{
|
||||
struct tm *tm;
|
||||
static char tbuf[TBUFLEN];
|
||||
|
||||
tm = (flags & GMT) ? gmtime(&t) : localtime(&t);
|
||||
if (tm == NULL) {
|
||||
strcpy(tbuf, "????");
|
||||
return tbuf;
|
||||
}
|
||||
strftime(tbuf, sizeof(tbuf),
|
||||
(flags & TIMEONLY)
|
||||
? (flags & FULLTIME ? LTFMTS : TFMTS)
|
||||
: (flags & FULLTIME ? LTFMT : TFMT),
|
||||
tm);
|
||||
return (tbuf);
|
||||
}
|
||||
|
||||
#ifdef SUPPORT_UTMP
|
||||
#define TYPE(a) 0
|
||||
#define NAMESIZE UT_NAMESIZE
|
||||
#define LINESIZE UT_LINESIZE
|
||||
#define HOSTSIZE UT_HOSTSIZE
|
||||
#define ut_timefld ut_time
|
||||
#define HAS_UT_SS 0
|
||||
#include "want.c"
|
||||
#undef TYPE /*(a)*/
|
||||
#undef NAMESIZE
|
||||
#undef LINESIZE
|
||||
#undef HOSTSIZE
|
||||
#undef ut_timefld
|
||||
#undef HAS_UT_SS
|
||||
#endif
|
||||
|
||||
#ifdef SUPPORT_UTMPX
|
||||
#define utmp utmpx
|
||||
#define want wantx
|
||||
#define wtmp wtmpx
|
||||
#define gethost gethostx
|
||||
#define buf bufx
|
||||
#define onintr onintrx
|
||||
#define TYPE(a) (a)->ut_type
|
||||
#define NAMESIZE UTX_USERSIZE
|
||||
#define LINESIZE UTX_LINESIZE
|
||||
#define HOSTSIZE UTX_HOSTSIZE
|
||||
#define ut_timefld ut_xtime
|
||||
#define HAS_UT_SS 1
|
||||
#include "want.c"
|
||||
#endif
|
318
usr.bin/last/want.c
Normal file
318
usr.bin/last/want.c
Normal file
|
@ -0,0 +1,318 @@
|
|||
/* $NetBSD: want.c,v 1.17 2012/03/15 03:04:05 dholland Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1987, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
static struct utmp *buf;
|
||||
static time_t seentime;
|
||||
|
||||
static void onintr(int);
|
||||
static int want(struct utmp *, int);
|
||||
static const char *gethost(struct utmp *, const char *, int);
|
||||
|
||||
static const char *
|
||||
/*ARGSUSED*/
|
||||
gethost(struct utmp *ut, const char *host, int numeric)
|
||||
{
|
||||
#if HAS_UT_SS == 0
|
||||
return numeric ? "" : host;
|
||||
#else
|
||||
if (numeric) {
|
||||
static char hbuf[512];
|
||||
hbuf[0] = '\0';
|
||||
(void)sockaddr_snprintf(hbuf, sizeof(hbuf), "%a",
|
||||
(struct sockaddr *)&ut->ut_ss);
|
||||
return hbuf;
|
||||
} else
|
||||
return host;
|
||||
#endif
|
||||
}
|
||||
|
||||
#define NULTERM(what) \
|
||||
if (check ## what) \
|
||||
(void)strlcpy(what ## p = what ## buf, bp->ut_ ## what, \
|
||||
sizeof(what ## buf)); \
|
||||
else \
|
||||
what ## p = bp->ut_ ## what
|
||||
|
||||
/*
|
||||
* wtmp --
|
||||
* read through the wtmp file
|
||||
*/
|
||||
static void
|
||||
wtmp(const char *file, int namesz, int linesz, int hostsz, int numeric)
|
||||
{
|
||||
struct utmp *bp; /* current structure */
|
||||
TTY *T; /* tty list entry */
|
||||
struct stat stb; /* stat of file for sz */
|
||||
off_t offset;
|
||||
int wfd;
|
||||
char *ct;
|
||||
const char *crmsg;
|
||||
size_t len = sizeof(*buf) * MAXUTMP;
|
||||
char namebuf[sizeof(bp->ut_name) + 1], *namep;
|
||||
char linebuf[sizeof(bp->ut_line) + 1], *linep;
|
||||
char hostbuf[sizeof(bp->ut_host) + 1], *hostp;
|
||||
int checkname = namesz > (int)sizeof(bp->ut_name);
|
||||
int checkline = linesz > (int)sizeof(bp->ut_line);
|
||||
int checkhost = hostsz > (int)sizeof(bp->ut_host);
|
||||
|
||||
if ((buf = malloc(len)) == NULL)
|
||||
err(EXIT_FAILURE, "Cannot allocate utmp buffer");
|
||||
|
||||
crmsg = NULL;
|
||||
|
||||
if (!strcmp(file, "-")) {
|
||||
wfd = STDIN_FILENO;
|
||||
file = "<stdin>";
|
||||
} else if ((wfd = open(file, O_RDONLY, 0)) < 0) {
|
||||
err(EXIT_FAILURE, "%s", file);
|
||||
}
|
||||
|
||||
if (lseek(wfd, 0, SEEK_CUR) < 0) {
|
||||
const char *dir;
|
||||
char *tfile;
|
||||
int tempfd;
|
||||
ssize_t tlen;
|
||||
|
||||
if (ESPIPE != errno) {
|
||||
err(EXIT_FAILURE, "lseek");
|
||||
}
|
||||
dir = getenv("TMPDIR");
|
||||
if (asprintf(&tfile, "%s/last.XXXXXX", dir ? dir : _PATH_TMP) == -1)
|
||||
err(EXIT_FAILURE, "asprintf");
|
||||
tempfd = mkstemp(tfile);
|
||||
if (tempfd < 0) {
|
||||
err(EXIT_FAILURE, "mkstemp");
|
||||
}
|
||||
unlink(tfile);
|
||||
for (;;) {
|
||||
tlen = read(wfd, buf, len);
|
||||
if (tlen < 0) {
|
||||
err(1, "%s: read", file);
|
||||
}
|
||||
if (tlen == 0) {
|
||||
break;
|
||||
}
|
||||
if (write(tempfd, buf, tlen) != tlen) {
|
||||
err(1, "%s: write", tfile);
|
||||
}
|
||||
}
|
||||
wfd = tempfd;
|
||||
}
|
||||
|
||||
if (fstat(wfd, &stb) == -1)
|
||||
err(EXIT_FAILURE, "%s: fstat", file);
|
||||
if (!S_ISREG(stb.st_mode))
|
||||
errx(EXIT_FAILURE, "%s: Not a regular file", file);
|
||||
|
||||
seentime = stb.st_mtime;
|
||||
(void)signal(SIGINT, onintr);
|
||||
(void)signal(SIGQUIT, onintr);
|
||||
|
||||
offset = stb.st_size;
|
||||
/* Ignore trailing garbage or partial record */
|
||||
offset -= offset % (off_t) sizeof(*buf);
|
||||
|
||||
while (offset >= (off_t) sizeof(*buf)) {
|
||||
ssize_t ret, i;
|
||||
size_t size;
|
||||
|
||||
size = MIN((off_t)len, offset);
|
||||
offset -= size; /* Always a multiple of sizeof(*buf) */
|
||||
ret = pread(wfd, buf, size, offset);
|
||||
if (ret < 0) {
|
||||
err(EXIT_FAILURE, "%s: pread", file);
|
||||
} else if ((size_t) ret < size) {
|
||||
err(EXIT_FAILURE, "%s: Unexpected end of file", file);
|
||||
}
|
||||
|
||||
for (i = ret / sizeof(*buf) - 1; i >= 0; i--) {
|
||||
bp = &buf[i];
|
||||
|
||||
NULTERM(name);
|
||||
NULTERM(line);
|
||||
NULTERM(host);
|
||||
|
||||
seentime = bp->ut_timefld;
|
||||
|
||||
/*
|
||||
* if the terminal line is '~', the machine stopped.
|
||||
* see utmp(5) for more info.
|
||||
*/
|
||||
if (linep[0] == '~' && !linep[1]) {
|
||||
/* everybody just logged out */
|
||||
for (T = ttylist; T; T = T->next)
|
||||
T->logout = -bp->ut_timefld;
|
||||
currentout = -bp->ut_timefld;
|
||||
crmsg = strncmp(namep, "shutdown",
|
||||
namesz) ? "crash" : "shutdown";
|
||||
if (want(bp, NO)) {
|
||||
ct = fmttime(bp->ut_timefld, fulltime);
|
||||
printf("%-*.*s %-*.*s %-*.*s %s\n",
|
||||
namesz, namesz, namep,
|
||||
linesz, linesz, linep,
|
||||
hostsz, hostsz,
|
||||
gethost(bp, hostp, numeric), ct);
|
||||
if (maxrec != -1 && !--maxrec)
|
||||
return;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* if the line is '{' or '|', date got set; see
|
||||
* utmp(5) for more info.
|
||||
*/
|
||||
if ((linep[0] == '{' || linep[0] == '|') && !linep[1]) {
|
||||
if (want(bp, NO)) {
|
||||
ct = fmttime(bp->ut_timefld, fulltime);
|
||||
printf("%-*.*s %-*.*s %-*.*s %s\n",
|
||||
namesz, namesz, namep,
|
||||
linesz, linesz, linep,
|
||||
hostsz, hostsz,
|
||||
gethost(bp, hostp, numeric),
|
||||
ct);
|
||||
if (maxrec && !--maxrec)
|
||||
return;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
/* find associated tty */
|
||||
for (T = ttylist;; T = T->next) {
|
||||
if (!T) {
|
||||
/* add new one */
|
||||
T = addtty(linep);
|
||||
break;
|
||||
}
|
||||
if (!strncmp(T->tty, linep, LINESIZE))
|
||||
break;
|
||||
}
|
||||
if (TYPE(bp) == SIGNATURE)
|
||||
continue;
|
||||
if (namep[0] && want(bp, YES)) {
|
||||
ct = fmttime(bp->ut_timefld, fulltime);
|
||||
printf("%-*.*s %-*.*s %-*.*s %s ",
|
||||
namesz, namesz, namep,
|
||||
linesz, linesz, linep,
|
||||
hostsz, hostsz,
|
||||
gethost(bp, hostp, numeric),
|
||||
ct);
|
||||
if (!T->logout)
|
||||
puts(" still logged in");
|
||||
else {
|
||||
time_t delta; /* time difference */
|
||||
|
||||
if (T->logout < 0) {
|
||||
T->logout = -T->logout;
|
||||
printf("- %s", crmsg);
|
||||
}
|
||||
else
|
||||
printf("- %s",
|
||||
fmttime(T->logout,
|
||||
fulltime | TIMEONLY));
|
||||
delta = T->logout - bp->ut_timefld;
|
||||
if (delta < SECSPERDAY)
|
||||
printf(" (%s)\n",
|
||||
fmttime(delta,
|
||||
fulltime | TIMEONLY | GMT));
|
||||
else
|
||||
printf(" (%lld+%s)\n",
|
||||
(long long)
|
||||
delta / SECSPERDAY,
|
||||
fmttime(delta,
|
||||
fulltime | TIMEONLY | GMT));
|
||||
}
|
||||
if (maxrec != -1 && !--maxrec)
|
||||
return;
|
||||
}
|
||||
T->logout = bp->ut_timefld;
|
||||
}
|
||||
}
|
||||
fulltime = 1; /* show full time */
|
||||
crmsg = fmttime(seentime, FULLTIME);
|
||||
if ((ct = strrchr(file, '/')) != NULL)
|
||||
ct++;
|
||||
printf("\n%s begins %s\n", ct ? ct : file, crmsg);
|
||||
}
|
||||
|
||||
/*
|
||||
* want --
|
||||
* see if want this entry
|
||||
*/
|
||||
static int
|
||||
want(struct utmp *bp, int check)
|
||||
{
|
||||
ARG *step;
|
||||
|
||||
if (check) {
|
||||
/*
|
||||
* when uucp and ftp log in over a network, the entry in
|
||||
* the utmp file is the name plus their process id. See
|
||||
* etc/ftpd.c and usr.bin/uucp/uucpd.c for more information.
|
||||
*/
|
||||
if (!strncmp(bp->ut_line, "ftp", sizeof("ftp") - 1))
|
||||
bp->ut_line[3] = '\0';
|
||||
else if (!strncmp(bp->ut_line, "uucp", sizeof("uucp") - 1))
|
||||
bp->ut_line[4] = '\0';
|
||||
}
|
||||
if (!arglist)
|
||||
return (YES);
|
||||
|
||||
for (step = arglist; step; step = step->next)
|
||||
switch(step->type) {
|
||||
case HOST_TYPE:
|
||||
if (!strncasecmp(step->name, bp->ut_host, HOSTSIZE))
|
||||
return (YES);
|
||||
break;
|
||||
case TTY_TYPE:
|
||||
if (!strncmp(step->name, bp->ut_line, LINESIZE))
|
||||
return (YES);
|
||||
break;
|
||||
case USER_TYPE:
|
||||
if (!strncmp(step->name, bp->ut_name, NAMESIZE))
|
||||
return (YES);
|
||||
break;
|
||||
}
|
||||
return (NO);
|
||||
}
|
||||
|
||||
/*
|
||||
* onintr --
|
||||
* on interrupt, we inform the user how far we've gotten
|
||||
*/
|
||||
static void
|
||||
onintr(int signo)
|
||||
{
|
||||
/* FIXME: None of this is allowed in a signal handler */
|
||||
printf("\ninterrupted %s\n", fmttime(seentime, FULLTIME));
|
||||
if (signo == SIGINT) {
|
||||
(void)raise_default_signal(signo);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
(void)fflush(stdout); /* fix required for rsh */
|
||||
}
|
18
usr.bin/wall/Makefile
Normal file
18
usr.bin/wall/Makefile
Normal file
|
@ -0,0 +1,18 @@
|
|||
# $NetBSD: Makefile,v 1.10 2007/05/28 12:06:32 tls Exp $
|
||||
# @(#)Makefile 8.1 (Berkeley) 6/6/93
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
USE_FORT?= yes # setuid
|
||||
PROG= wall
|
||||
SRCS= wall.c utmpentry.c term_chk.c
|
||||
BINGRP= tty
|
||||
BINMODE=2555
|
||||
DPADD+=${LIBUTIL}
|
||||
LDADD+=-lutil
|
||||
|
||||
.PATH.c: ${NETBSDSRCDIR}/usr.bin/who ${NETBSDSRCDIR}/usr.bin/write
|
||||
CPPFLAGS+=-I${NETBSDSRCDIR}/usr.bin/who -DSUPPORT_UTMPX -DSUPPORT_UTMP
|
||||
CPPFLAGS+=-I${NETBSDSRCDIR}/usr.bin/write
|
||||
|
||||
.include <bsd.prog.mk>
|
74
usr.bin/wall/wall.1
Normal file
74
usr.bin/wall/wall.1
Normal file
|
@ -0,0 +1,74 @@
|
|||
.\" $NetBSD: wall.1,v 1.7 2003/08/07 11:17:14 agc Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1989, 1990, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" @(#)wall.1 8.1 (Berkeley) 6/6/93
|
||||
.\"
|
||||
.Dd March 27, 2003
|
||||
.Dt WALL 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm wall
|
||||
.Nd write a message to users
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl g Ar group
|
||||
.Op Ar file
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
displays the contents of
|
||||
.Ar file
|
||||
or, by default, its standard input, on the terminals of all
|
||||
currently logged in users.
|
||||
.Pp
|
||||
Only the super-user can write on the
|
||||
terminals of users who have chosen
|
||||
to deny messages or are using a program which
|
||||
automatically denies messages.
|
||||
.Bl -tag -width indent
|
||||
.It Fl g
|
||||
Send messages to users in this group.
|
||||
This option may be specified multiple times, and any user in any of the
|
||||
specified groups will receive the message.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr mesg 1 ,
|
||||
.Xr talk 1 ,
|
||||
.Xr write 1 ,
|
||||
.Xr shutdown 8
|
||||
.Sh HISTORY
|
||||
A
|
||||
.Nm
|
||||
command appeared in
|
||||
.At v7 .
|
||||
Support for
|
||||
.Fl g
|
||||
was added in
|
||||
.Nx 2.0
|
||||
(from
|
||||
.Ox 2.0 ) .
|
276
usr.bin/wall/wall.c
Normal file
276
usr.bin/wall/wall.c
Normal file
|
@ -0,0 +1,276 @@
|
|||
/* $NetBSD: wall.c,v 1.29 2011/09/06 18:45:21 joerg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1990, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__COPYRIGHT("@(#) Copyright (c) 1988, 1990, 1993\
|
||||
The Regents of the University of California. All rights reserved.");
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)wall.c 8.2 (Berkeley) 11/16/93";
|
||||
#endif
|
||||
__RCSID("$NetBSD: wall.c,v 1.29 2011/09/06 18:45:21 joerg Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
/*
|
||||
* This program is not related to David Wall, whose Stanford Ph.D. thesis
|
||||
* is entitled "Mechanisms for Broadcast and Selective Broadcast".
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <grp.h>
|
||||
#include <errno.h>
|
||||
#include <paths.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <util.h>
|
||||
|
||||
#include "utmpentry.h"
|
||||
|
||||
#include "term_chk.h"
|
||||
|
||||
static void addgroup(char *);
|
||||
static void makemsg(const char *);
|
||||
__dead static void usage(void);
|
||||
|
||||
static struct wallgroup {
|
||||
gid_t gid;
|
||||
char *name;
|
||||
char **mem;
|
||||
struct wallgroup *next;
|
||||
} *grouplist;
|
||||
|
||||
static int nobanner;
|
||||
static size_t mbufsize;
|
||||
static char *mbuf;
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int ch;
|
||||
struct iovec iov;
|
||||
char *p, **mem;
|
||||
struct utmpentry *ep;
|
||||
gid_t egid;
|
||||
struct wallgroup *wg;
|
||||
struct passwd *pw;
|
||||
|
||||
setprogname(argv[0]);
|
||||
egid = getegid();
|
||||
if (setegid(getgid()) == -1)
|
||||
err(1, "setegid");
|
||||
pw = getpwnam("nobody");
|
||||
|
||||
(void)check_sender(NULL, getuid(), egid);
|
||||
|
||||
while ((ch = getopt(argc, argv, "g:n")) != -1)
|
||||
switch (ch) {
|
||||
case 'n':
|
||||
/* undoc option for shutdown: suppress banner */
|
||||
if (geteuid() == 0 || (pw && getuid() == pw->pw_uid))
|
||||
nobanner = 1;
|
||||
break;
|
||||
case 'g':
|
||||
addgroup(optarg);
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
if (argc > 1)
|
||||
usage();
|
||||
|
||||
makemsg(*argv);
|
||||
|
||||
iov.iov_base = mbuf;
|
||||
iov.iov_len = mbufsize;
|
||||
(void)getutentries(NULL, &ep);
|
||||
(void)setegid(egid);
|
||||
for (; ep; ep = ep->next) {
|
||||
if (grouplist) {
|
||||
int ingroup;
|
||||
|
||||
ingroup = 0;
|
||||
pw = getpwnam(ep->name);
|
||||
if (!pw)
|
||||
continue;
|
||||
for (wg = grouplist; wg && !ingroup; wg = wg->next) {
|
||||
if (wg->gid == pw->pw_gid)
|
||||
ingroup = 1;
|
||||
for (mem = wg->mem; *mem && !ingroup; mem++)
|
||||
if (strcmp(ep->name, *mem) == 0)
|
||||
ingroup = 1;
|
||||
}
|
||||
if (ingroup == 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* skip [xgk]dm/xserver entries (":0", ":1", etc.) */
|
||||
if (ep->line[0] == ':' && isdigit((unsigned char)ep->line[1]))
|
||||
continue;
|
||||
|
||||
if ((p = ttymsg(&iov, 1, ep->line, 60*5)) != NULL)
|
||||
warnx("%s", p);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static void
|
||||
addgroup(char *name)
|
||||
{
|
||||
int i;
|
||||
struct group *grp;
|
||||
struct wallgroup *g;
|
||||
|
||||
grp = getgrnam(name);
|
||||
if ((grp = getgrnam(name)) == NULL)
|
||||
errx(1, "unknown group `%s'", name);
|
||||
for (i = 0; grp->gr_mem[i]; i++)
|
||||
continue;
|
||||
|
||||
g = (struct wallgroup *)malloc(sizeof *g);
|
||||
if (g == NULL)
|
||||
err(1, "malloc");
|
||||
g->gid = grp->gr_gid;
|
||||
g->name = name;
|
||||
g->mem = (char **)malloc(i + 1);
|
||||
if (g->mem == NULL)
|
||||
err(1, "malloc");
|
||||
for (i = 0; grp->gr_mem[i] != NULL; i++) {
|
||||
g->mem[i] = strdup(grp->gr_mem[i]);
|
||||
if (g->mem[i] == NULL)
|
||||
err(1, "malloc");
|
||||
}
|
||||
g->mem[i] = NULL;
|
||||
g->next = grouplist;
|
||||
grouplist = g;
|
||||
}
|
||||
|
||||
static void
|
||||
makemsg(const char *fname)
|
||||
{
|
||||
int ch, cnt;
|
||||
struct tm *lt;
|
||||
struct passwd *pw;
|
||||
struct stat sbuf;
|
||||
time_t now;
|
||||
FILE *fp;
|
||||
int fd;
|
||||
const char *whom, *tty;
|
||||
char *p, tmpname[MAXPATHLEN], lbuf[100],
|
||||
hostname[MAXHOSTNAMELEN+1];
|
||||
|
||||
(void)snprintf(tmpname, sizeof tmpname, "%s/wall.XXXXXX", _PATH_TMP);
|
||||
if ((fd = mkstemp(tmpname)) == -1)
|
||||
err(1, "can't open temporary file");
|
||||
(void)unlink(tmpname);
|
||||
if (!(fp = fdopen(fd, "r+")))
|
||||
err(1, "can't open temporary file");
|
||||
|
||||
if (!nobanner) {
|
||||
if (!(whom = getlogin()))
|
||||
whom = (pw = getpwuid(getuid())) ? pw->pw_name : "???";
|
||||
(void)gethostname(hostname, sizeof(hostname));
|
||||
hostname[sizeof(hostname) - 1] = '\0';
|
||||
(void)time(&now);
|
||||
lt = localtime(&now);
|
||||
|
||||
/*
|
||||
* all this stuff is to blank out a square for the message;
|
||||
* we wrap message lines at column 79, not 80, because some
|
||||
* terminals wrap after 79, some do not, and we can't tell.
|
||||
* Which means that we may leave a non-blank character
|
||||
* in column 80, but that can't be helped.
|
||||
*/
|
||||
(void)fprintf(fp, "\r%79s\r\n", " ");
|
||||
(void)snprintf(lbuf, sizeof lbuf,
|
||||
"Broadcast Message from %s@%s", whom, hostname);
|
||||
(void)fprintf(fp, "%-79.79s\007\007\r\n", lbuf);
|
||||
tty = ttyname(STDERR_FILENO);
|
||||
if (tty == NULL)
|
||||
tty = "??";
|
||||
(void)snprintf(lbuf, sizeof lbuf,
|
||||
" (%s) at %d:%02d %s...", tty,
|
||||
lt->tm_hour, lt->tm_min, lt->tm_zone);
|
||||
(void)fprintf(fp, "%-79.79s\r\n", lbuf);
|
||||
}
|
||||
(void)fprintf(fp, "%79s\r\n", " ");
|
||||
|
||||
if (fname && !(freopen(fname, "r", stdin)))
|
||||
err(1, "can't read %s", fname);
|
||||
while (fgets(lbuf, sizeof(lbuf), stdin))
|
||||
for (cnt = 0, p = lbuf; (ch = *p) != '\0'; ++p, ++cnt) {
|
||||
if (cnt == 79 || ch == '\n') {
|
||||
for (; cnt < 79; ++cnt)
|
||||
putc(' ', fp);
|
||||
putc('\r', fp);
|
||||
putc('\n', fp);
|
||||
cnt = -1;
|
||||
}
|
||||
if (ch != '\n')
|
||||
putc(ch, fp);
|
||||
}
|
||||
(void)fprintf(fp, "%79s\r\n", " ");
|
||||
rewind(fp);
|
||||
|
||||
if (fstat(fd, &sbuf))
|
||||
err(1, "can't stat temporary file");
|
||||
if ((uint64_t)sbuf.st_size > SIZE_T_MAX)
|
||||
errx(1, "file too big");
|
||||
mbufsize = sbuf.st_size;
|
||||
if (!(mbuf = malloc(mbufsize)))
|
||||
err(1, "malloc");
|
||||
if (fread(mbuf, 1, mbufsize, fp) != mbufsize)
|
||||
err(1, "can't read temporary file");
|
||||
(void)fclose(fp);
|
||||
}
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
|
||||
(void)fprintf(stderr, "usage: %s [-g group] [file]\n", getprogname());
|
||||
exit(1);
|
||||
}
|
Loading…
Reference in a new issue