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 \
|
dhrystone diff diskctl \
|
||||||
eject factor fbdctl \
|
eject factor fbdctl \
|
||||||
find fix format fortune fsck.mfs \
|
find fix format fortune fsck.mfs \
|
||||||
gcov-pull getty grep host \
|
gcov-pull grep host \
|
||||||
hostaddr ifconfig ifdef \
|
hostaddr ifconfig ifdef \
|
||||||
intr ipcrm ipcs irdpd isoread last \
|
intr ipcrm ipcs irdpd isoread \
|
||||||
less loadkeys loadramdisk logger look lp \
|
less loadkeys loadramdisk logger look lp \
|
||||||
lpd lspci mail MAKEDEV \
|
lpd lspci mail MAKEDEV \
|
||||||
mined \
|
mined \
|
||||||
mount mt netconf \
|
mount mt netconf \
|
||||||
nonamed patch \
|
nonamed patch \
|
||||||
ping postinstall poweroff prep printroot \
|
ping postinstall prep printroot \
|
||||||
profile progressbar pr_routes ps pwdauth \
|
profile progressbar pr_routes ps pwdauth \
|
||||||
ramdisk rarpd rawspeed rcp readclock \
|
ramdisk rarpd rawspeed rcp readclock \
|
||||||
reboot remsync rget rlogin \
|
remsync rget rlogin \
|
||||||
rotate rsh rshd service setup shar \
|
rotate rsh rshd service setup shar \
|
||||||
sleep slip spell sprofalyze sprofdiff srccrc \
|
sleep slip spell sprofalyze sprofdiff srccrc \
|
||||||
stty svclog svrctl swifi synctree sysenv \
|
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
|
PROG= in.telnetd
|
||||||
SRCS= main.c telnet.c term.c pty.c wtmp.c
|
SRCS= main.c telnet.c term.c pty.c
|
||||||
MAN=
|
MAN=
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
.include <bsd.prog.mk>
|
||||||
|
|
|
@ -45,7 +45,6 @@ int opt_d = 0; /* debugging output flag */
|
||||||
|
|
||||||
void usage(void);
|
void usage(void);
|
||||||
int main(int argc, char *argv[]);
|
int main(int argc, char *argv[]);
|
||||||
void wtmp(int type, int linenr, char *line, pid_t pid, char *host);
|
|
||||||
|
|
||||||
void usage()
|
void usage()
|
||||||
{
|
{
|
||||||
|
@ -144,14 +143,10 @@ char *hostname;
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
wtmp(LOGIN_PROCESS, lineno, tty_name+5, pid, hostname);
|
|
||||||
|
|
||||||
term_inout(pty_fd);
|
term_inout(pty_fd);
|
||||||
|
|
||||||
(void) close(pty_fd);
|
(void) close(pty_fd);
|
||||||
|
|
||||||
wtmp(DEAD_PROCESS, lineno, tty_name+5, pid, hostname);
|
|
||||||
|
|
||||||
chown(tty_name, 0, 0);
|
chown(tty_name, 0, 0);
|
||||||
chmod(tty_name, 0666);
|
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/expr minix-sys
|
||||||
./bin/false minix-sys
|
./bin/false minix-sys
|
||||||
./bin/getopts minix-sys
|
./bin/getopts minix-sys
|
||||||
./bin/getty minix-sys
|
./bin/getty minix-sys obsolete
|
||||||
./bin/halt minix-sys
|
./bin/halt minix-sys obsolete
|
||||||
./bin/intr minix-sys
|
./bin/intr minix-sys
|
||||||
./bin/kill minix-sys
|
./bin/kill minix-sys
|
||||||
./bin/ksh minix-sys
|
./bin/ksh minix-sys
|
||||||
|
@ -42,14 +42,14 @@
|
||||||
./bin/pwd minix-sys
|
./bin/pwd minix-sys
|
||||||
./bin/read minix-sys
|
./bin/read minix-sys
|
||||||
./bin/readclock minix-sys
|
./bin/readclock minix-sys
|
||||||
./bin/reboot minix-sys
|
./bin/reboot minix-sys obsolete
|
||||||
./bin/rm minix-sys
|
./bin/rm minix-sys
|
||||||
./bin/rmdir minix-sys
|
./bin/rmdir minix-sys
|
||||||
./bin/sed minix-sys
|
./bin/sed minix-sys
|
||||||
./bin/service minix-sys
|
./bin/service minix-sys
|
||||||
./bin/setup minix-sys
|
./bin/setup minix-sys
|
||||||
./bin/sh minix-sys
|
./bin/sh minix-sys
|
||||||
./bin/shutdown minix-sys
|
./bin/shutdown minix-sys obsolete
|
||||||
./bin/sync minix-sys
|
./bin/sync minix-sys
|
||||||
./bin/sysenv minix-sys
|
./bin/sysenv minix-sys
|
||||||
./bin/tar minix-sys
|
./bin/tar minix-sys
|
||||||
|
@ -117,6 +117,8 @@
|
||||||
./etc/termcap minix-sys
|
./etc/termcap minix-sys
|
||||||
./etc/ttys minix-sys
|
./etc/ttys minix-sys
|
||||||
./etc/utmp minix-sys
|
./etc/utmp minix-sys
|
||||||
|
./etc/gettytab minix-sys
|
||||||
|
./etc/rc.shutdown minix-sys
|
||||||
./home minix-sys
|
./home minix-sys
|
||||||
./home/ast minix-sys
|
./home/ast minix-sys
|
||||||
./home/ast/.exrc minix-sys
|
./home/ast/.exrc minix-sys
|
||||||
|
@ -146,6 +148,8 @@
|
||||||
./sbin/fsck_ext2fs minix-sys
|
./sbin/fsck_ext2fs minix-sys
|
||||||
./sbin/fsck.mfs minix-sys
|
./sbin/fsck.mfs minix-sys
|
||||||
./sbin/input minix-sys
|
./sbin/input minix-sys
|
||||||
|
./sbin/halt minix-sys
|
||||||
|
./sbin/init minix-sys
|
||||||
./sbin/is minix-sys
|
./sbin/is minix-sys
|
||||||
./sbin/isofs minix-sys
|
./sbin/isofs minix-sys
|
||||||
./sbin/mfs minix-sys
|
./sbin/mfs minix-sys
|
||||||
|
@ -155,8 +159,11 @@
|
||||||
./sbin/newfs_ext2 minix-sys
|
./sbin/newfs_ext2 minix-sys
|
||||||
./sbin/newfs_ext2fs minix-sys
|
./sbin/newfs_ext2fs minix-sys
|
||||||
./sbin/nologin minix-sys
|
./sbin/nologin minix-sys
|
||||||
|
./sbin/poweroff minix-sys
|
||||||
./sbin/procfs minix-sys
|
./sbin/procfs minix-sys
|
||||||
./sbin/readclock.drv minix-sys
|
./sbin/readclock.drv minix-sys
|
||||||
|
./sbin/reboot minix-sys
|
||||||
|
./sbin/shutdown minix-sys
|
||||||
./sys minix-sys
|
./sys minix-sys
|
||||||
./tmp minix-sys
|
./tmp minix-sys
|
||||||
./usr minix-sys
|
./usr minix-sys
|
||||||
|
@ -336,7 +343,7 @@
|
||||||
./usr/bin/gzcat minix-sys
|
./usr/bin/gzcat minix-sys
|
||||||
./usr/bin/gzexe minix-sys
|
./usr/bin/gzexe minix-sys
|
||||||
./usr/bin/gzip 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/head minix-sys
|
||||||
./usr/bin/hexdump minix-sys
|
./usr/bin/hexdump minix-sys
|
||||||
./usr/bin/host minix-sys
|
./usr/bin/host minix-sys
|
||||||
|
@ -437,7 +444,7 @@
|
||||||
./usr/bin/pkgin_cd minix-sys
|
./usr/bin/pkgin_cd minix-sys
|
||||||
./usr/bin/playwave minix-sys
|
./usr/bin/playwave minix-sys
|
||||||
./usr/bin/postinstall 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/pr minix-sys
|
||||||
./usr/bin/prep minix-sys
|
./usr/bin/prep minix-sys
|
||||||
./usr/bin/printenv minix-sys
|
./usr/bin/printenv minix-sys
|
||||||
|
@ -456,8 +463,8 @@
|
||||||
./usr/bin/readall minix-sys obsolete
|
./usr/bin/readall minix-sys obsolete
|
||||||
./usr/bin/readelf minix-sys binutils
|
./usr/bin/readelf minix-sys binutils
|
||||||
./usr/bin/readlink minix-sys
|
./usr/bin/readlink minix-sys
|
||||||
./usr/bin/reboot minix-sys
|
|
||||||
./usr/bin/recwave minix-sys
|
./usr/bin/recwave minix-sys
|
||||||
|
./usr/bin/reboot minix-sys obsolete
|
||||||
./usr/bin/ref minix-sys obsolete
|
./usr/bin/ref minix-sys obsolete
|
||||||
./usr/bin/remsync minix-sys
|
./usr/bin/remsync minix-sys
|
||||||
./usr/bin/repartition minix-sys
|
./usr/bin/repartition minix-sys
|
||||||
|
@ -479,7 +486,7 @@
|
||||||
./usr/bin/shar minix-sys
|
./usr/bin/shar minix-sys
|
||||||
./usr/bin/shlock minix-sys
|
./usr/bin/shlock minix-sys
|
||||||
./usr/bin/shuffle 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/size minix-sys binutils
|
||||||
./usr/bin/sleep minix-sys
|
./usr/bin/sleep minix-sys
|
||||||
./usr/bin/slip minix-sys
|
./usr/bin/slip minix-sys
|
||||||
|
@ -540,8 +547,8 @@
|
||||||
./usr/bin/unxz minix-sys
|
./usr/bin/unxz minix-sys
|
||||||
./usr/bin/unzip minix-sys
|
./usr/bin/unzip minix-sys
|
||||||
./usr/bin/update minix-sys
|
./usr/bin/update minix-sys
|
||||||
./usr/bin/uptime minix-sys
|
|
||||||
./usr/bin/users minix-sys
|
./usr/bin/users minix-sys
|
||||||
|
./usr/bin/uptime minix-sys obsolete
|
||||||
./usr/bin/uud minix-sys
|
./usr/bin/uud minix-sys
|
||||||
./usr/bin/uudecode minix-sys
|
./usr/bin/uudecode minix-sys
|
||||||
./usr/bin/uue minix-sys
|
./usr/bin/uue minix-sys
|
||||||
|
@ -552,6 +559,7 @@
|
||||||
./usr/bin/view minix-sys
|
./usr/bin/view minix-sys
|
||||||
./usr/bin/vis minix-sys
|
./usr/bin/vis minix-sys
|
||||||
./usr/bin/vol minix-sys
|
./usr/bin/vol minix-sys
|
||||||
|
./usr/bin/wall minix-sys
|
||||||
./usr/bin/wc minix-sys
|
./usr/bin/wc minix-sys
|
||||||
./usr/bin/what minix-sys
|
./usr/bin/what minix-sys
|
||||||
./usr/bin/whatis minix-sys
|
./usr/bin/whatis minix-sys
|
||||||
|
@ -1201,7 +1209,7 @@
|
||||||
./usr/include/minix/procfs.h minix-sys
|
./usr/include/minix/procfs.h minix-sys
|
||||||
./usr/include/minix/profile.h minix-sys
|
./usr/include/minix/profile.h minix-sys
|
||||||
./usr/include/minix/queryparam.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/rs.h minix-sys
|
||||||
./usr/include/minix/safecopies.h minix-sys
|
./usr/include/minix/safecopies.h minix-sys
|
||||||
./usr/include/minix/sched.h minix-sys
|
./usr/include/minix/sched.h minix-sys
|
||||||
|
@ -1938,6 +1946,7 @@
|
||||||
./usr/libexec/atf-check minix-sys atf
|
./usr/libexec/atf-check minix-sys atf
|
||||||
./usr/libexec/fingerd minix-sys
|
./usr/libexec/fingerd minix-sys
|
||||||
./usr/libexec/ftpd minix-sys
|
./usr/libexec/ftpd minix-sys
|
||||||
|
./usr/libexec/getty minix-sys
|
||||||
./usr/libexec/kyua-atf-tester minix-sys kyua
|
./usr/libexec/kyua-atf-tester minix-sys kyua
|
||||||
./usr/libexec/kyua-plain-tester minix-sys kyua
|
./usr/libexec/kyua-plain-tester minix-sys kyua
|
||||||
./usr/libexec/ld.elf_so minix-sys
|
./usr/libexec/ld.elf_so minix-sys
|
||||||
|
@ -2282,6 +2291,7 @@
|
||||||
./usr/man/man1/view.1 minix-sys
|
./usr/man/man1/view.1 minix-sys
|
||||||
./usr/man/man1/vis.1 minix-sys
|
./usr/man/man1/vis.1 minix-sys
|
||||||
./usr/man/man1/vol.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/wait.1 minix-sys
|
||||||
./usr/man/man1/wc.1 minix-sys
|
./usr/man/man1/wc.1 minix-sys
|
||||||
./usr/man/man1/what.1 minix-sys
|
./usr/man/man1/what.1 minix-sys
|
||||||
|
@ -4696,6 +4706,7 @@
|
||||||
./usr/man/man5/ftpchroot.5 minix-sys
|
./usr/man/man5/ftpchroot.5 minix-sys
|
||||||
./usr/man/man5/ftpd.conf.5 minix-sys
|
./usr/man/man5/ftpd.conf.5 minix-sys
|
||||||
./usr/man/man5/ftpusers.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/group.5 minix-sys
|
||||||
./usr/man/man5/hosts.5 minix-sys
|
./usr/man/man5/hosts.5 minix-sys
|
||||||
./usr/man/man5/httpd.conf.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/termcap.5 minix-sys
|
||||||
./usr/man/man5/terminfo.5 minix-sys
|
./usr/man/man5/terminfo.5 minix-sys
|
||||||
./usr/man/man5/texinfo.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/ttytab.5 minix-sys
|
||||||
./usr/man/man5/TZ.5 minix-sys
|
./usr/man/man5/TZ.5 minix-sys
|
||||||
./usr/man/man5/tzfile.5 minix-sys
|
./usr/man/man5/tzfile.5 minix-sys
|
||||||
|
@ -4863,7 +4875,7 @@
|
||||||
./usr/sbin/groupmod minix-sys
|
./usr/sbin/groupmod minix-sys
|
||||||
./usr/sbin/i2cscan minix-sys
|
./usr/sbin/i2cscan minix-sys
|
||||||
./usr/sbin/inet 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/installboot_nbsd minix-sys
|
||||||
./usr/sbin/ipc minix-sys
|
./usr/sbin/ipc minix-sys
|
||||||
./usr/sbin/kernel minix-sys
|
./usr/sbin/kernel minix-sys
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
#include <minix/i2c.h>
|
#include <minix/i2c.h>
|
||||||
#include <minix/i2cdriver.h>
|
#include <minix/i2cdriver.h>
|
||||||
#include <minix/log.h>
|
#include <minix/log.h>
|
||||||
#include <minix/reboot.h>
|
|
||||||
|
#include <sys/signal.h>
|
||||||
|
|
||||||
/* Register Addresses */
|
/* Register Addresses */
|
||||||
#define CHIPID_REG 0x00
|
#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.
|
/* 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
|
* the kernel will do the work to toggle the pin when the
|
||||||
* system is ready to be powered off. Should be called during startup
|
* 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);
|
r = i2creg_write8(bus_endpoint, address, STATUS_REG, PWR_OFF_MASK);
|
||||||
if (r != OK) {
|
if (r != OK) {
|
||||||
|
@ -228,10 +229,8 @@ intr_handler(void)
|
||||||
|
|
||||||
if ((val & PBI_MASK) != 0) {
|
if ((val & PBI_MASK) != 0) {
|
||||||
log_info(&log, "Power Button Pressed\n");
|
log_info(&log, "Power Button Pressed\n");
|
||||||
reboot(RBT_POWEROFF);
|
kill(1, SIGUSR1); /* tell init to powerdwn */
|
||||||
log_warn(&log, "Failed to power off the system.");
|
return OK;
|
||||||
sys_irqenable(&irq_hook_kernel_id);
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* re-enable interrupt */
|
/* re-enable interrupt */
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <sys/kbdio.h>
|
#include <sys/kbdio.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
#include <sys/reboot.h>
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
@ -18,7 +19,6 @@
|
||||||
#include <minix/com.h>
|
#include <minix/com.h>
|
||||||
#include <minix/input.h>
|
#include <minix/input.h>
|
||||||
#include <minix/keymap.h>
|
#include <minix/keymap.h>
|
||||||
#include <minix/reboot.h>
|
|
||||||
#include <minix/ds.h>
|
#include <minix/ds.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "tty.h"
|
#include "tty.h"
|
||||||
|
@ -295,7 +295,7 @@ static unsigned make_break(int scode)
|
||||||
{
|
{
|
||||||
if (++CAD_count == 3) {
|
if (++CAD_count == 3) {
|
||||||
cons_stop();
|
cons_stop();
|
||||||
sys_abort(RBT_DEFAULT);
|
sys_abort(RB_AUTOBOOT);
|
||||||
}
|
}
|
||||||
sys_kill(INIT_PROC_NR, SIGABRT);
|
sys_kill(INIT_PROC_NR, SIGABRT);
|
||||||
rebooting = 1;
|
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);
|
if (isconsole(tp)) r = con_loadfont(endpt, grant);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TIOCSCTTY:
|
||||||
|
tp->tty_pgrp = user_endpt;
|
||||||
|
break;
|
||||||
|
|
||||||
/* These Posix functions are allowed to fail if _POSIX_JOB_CONTROL is
|
/* These Posix functions are allowed to fail if _POSIX_JOB_CONTROL is
|
||||||
* not defined.
|
* not defined.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -97,7 +97,7 @@ BIN1+= boot.cfg.default \
|
||||||
protocols rc rc.cd rc.subr \
|
protocols rc rc.cd rc.subr \
|
||||||
rc.daemons.dist rs.inet rs.single \
|
rc.daemons.dist rs.inet rs.single \
|
||||||
services shells syslog.conf \
|
services shells syslog.conf \
|
||||||
termcap utmp
|
termcap utmp gettytab rc.shutdown
|
||||||
.else
|
.else
|
||||||
BIN1+= bootptab changelist csh.cshrc csh.login \
|
BIN1+= bootptab changelist csh.cshrc csh.login \
|
||||||
csh.logout daily daily.conf dm.conf envsys.conf floppytab ftpchroot \
|
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()
|
usage()
|
||||||
{
|
{
|
||||||
echo >&2 "Usage: $0 [-saf] start|stop|down"
|
echo >&2 "Usage: $0 [-saf] autoboot|start|stop|down"
|
||||||
exec intr sh
|
exec intr sh
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,8 +54,12 @@ edit()
|
||||||
service=$1
|
service=$1
|
||||||
shift
|
shift
|
||||||
|
|
||||||
# Assume binaries are always in /usr/sbin
|
# Assume binaries are always in /sbin or /usr/sbin
|
||||||
service $opt edit /usr/sbin/$service -label $service "$@"
|
binlocation=/usr/sbin/$service
|
||||||
|
if [ ! -x $binlocation ]
|
||||||
|
then binlocation=/sbin/$service
|
||||||
|
fi
|
||||||
|
service $opt edit $binlocation -label $service "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
while getopts 'saf' opt
|
while getopts 'saf' opt
|
||||||
|
@ -70,14 +74,14 @@ done
|
||||||
shift `expr $OPTIND - 1`
|
shift `expr $OPTIND - 1`
|
||||||
|
|
||||||
case "$#:$1" in
|
case "$#:$1" in
|
||||||
1:start|1:stop|1:down)
|
1:start|1:stop|1:down|1:autoboot)
|
||||||
action=$1
|
action=$1
|
||||||
;;
|
;;
|
||||||
*) usage
|
*) usage
|
||||||
esac
|
esac
|
||||||
|
|
||||||
case $action in
|
case $action in
|
||||||
start)
|
autoboot|start)
|
||||||
|
|
||||||
# National keyboard?
|
# National keyboard?
|
||||||
test -f /etc/keymap && loadkeys /etc/keymap
|
test -f /etc/keymap && loadkeys /etc/keymap
|
||||||
|
@ -104,8 +108,12 @@ start)
|
||||||
up readclock.drv
|
up readclock.drv
|
||||||
readclock -q || date 201301010000
|
readclock -q || date 201301010000
|
||||||
|
|
||||||
|
# We are not shutting down.
|
||||||
|
rm -f /etc/nologin
|
||||||
|
|
||||||
# Initialize files.
|
# 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?
|
# Use MFS binary only from kernel image?
|
||||||
if [ "`sysenv bin_img`" = 1 ]
|
if [ "`sysenv bin_img`" = 1 ]
|
||||||
|
@ -147,10 +155,6 @@ start)
|
||||||
edit init
|
edit init
|
||||||
fi
|
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" ]
|
if [ "$sflag" ]
|
||||||
then
|
then
|
||||||
echo "Single user. Press ^D to resume multiuser startup."
|
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
|
test -f /usr/local/etc/rc && sh /usr/local/etc/rc $action
|
||||||
|
|
||||||
# Any messages?
|
# 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
|
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
|
service tps65217
|
||||||
{
|
{
|
||||||
uid 0; # needed for doing reboot(RBT_POWEROFF)
|
uid 0; # needed for doing reboot()
|
||||||
system IRQCTL PRIVCTL;
|
system IRQCTL PRIVCTL;
|
||||||
irq 7; # NNMI pin on BeagleBone / BeagleBone Black
|
irq 7; # NNMI pin on BeagleBone / BeagleBone Black
|
||||||
ipc SYSTEM RS DS PM i2c;
|
ipc SYSTEM RS DS PM i2c;
|
||||||
|
|
8
etc/ttys
8
etc/ttys
|
@ -3,10 +3,10 @@
|
||||||
#
|
#
|
||||||
# name getty type status comments
|
# name getty type status comments
|
||||||
#
|
#
|
||||||
console getty minix on secure
|
console "/usr/libexec/getty default" minix on secure
|
||||||
ttyc1 getty minix on secure
|
ttyc1 "/usr/libexec/getty default" minix on secure
|
||||||
ttyc2 getty minix on secure
|
ttyc2 "/usr/libexec/getty default" minix on secure
|
||||||
ttyc3 getty minix on secure
|
ttyc3 "/usr/libexec/getty default" minix on secure
|
||||||
tty00 "" unknown off secure
|
tty00 "" unknown off secure
|
||||||
tty01 "" unknown off secure
|
tty01 "" unknown off secure
|
||||||
|
|
||||||
|
|
|
@ -25,10 +25,13 @@ fi
|
||||||
bootcd="`/bin/sysenv bootcd`"
|
bootcd="`/bin/sysenv bootcd`"
|
||||||
|
|
||||||
case "$#:$1" in
|
case "$#:$1" in
|
||||||
|
1:autoboot)
|
||||||
|
action=start
|
||||||
|
;;
|
||||||
1:start|1:stop|1:down)
|
1:start|1:stop|1:down)
|
||||||
action=$1
|
action=$1
|
||||||
;;
|
;;
|
||||||
*) echo >&2 "Usage: $0 start|stop|down"
|
*) echo >&2 "Usage: $0 autoboot|start|stop|down"
|
||||||
exit 1
|
exit 1
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
@ -158,7 +161,7 @@ capemgr() {
|
||||||
DAEMONS=/etc/rc.daemons
|
DAEMONS=/etc/rc.daemons
|
||||||
|
|
||||||
case $action in
|
case $action in
|
||||||
start)
|
start|autoboot)
|
||||||
# Select console font.
|
# Select console font.
|
||||||
test -f /etc/font && loadfont /etc/font </dev/console
|
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 \
|
keymap.h log.h mmio.h mount.h mthread.h minlib.h \
|
||||||
netdriver.h optset.h padconf.h partition.h portio.h \
|
netdriver.h optset.h padconf.h partition.h portio.h \
|
||||||
priv.h procfs.h profile.h queryparam.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 \
|
sound.h spin.h sys_config.h sysinfo.h \
|
||||||
syslib.h sysutil.h termios.h timers.h type.h \
|
syslib.h sysutil.h termios.h timers.h type.h \
|
||||||
u64.h usb.h usb_ch9.h vbox.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 VLNEXT 12 /* cc_c[VLNEXT] (^V) */
|
||||||
#define VDISCARD 13 /* cc_c[VDISCARD] (^O) */
|
#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. */
|
/* Extensions to baud rate settings. */
|
||||||
#if defined(__minix) && defined(_NETBSD_SOURCE)
|
#if defined(__minix) && defined(_NETBSD_SOURCE)
|
||||||
#define B57600 0x0100 /* 57600 baud */
|
#define B57600 0x0100 /* 57600 baud */
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#define TIOCSWINSZ _IOW('T', 17, struct winsize)
|
#define TIOCSWINSZ _IOW('T', 17, struct winsize)
|
||||||
#define TIOCGPGRP _IOW('T', 18, int)
|
#define TIOCGPGRP _IOW('T', 18, int)
|
||||||
#define TIOCSPGRP _IOW('T', 19, int)
|
#define TIOCSPGRP _IOW('T', 19, int)
|
||||||
|
#define TIOCSCTTY _IO ('T', 20) /* controlling tty */
|
||||||
#define TIOCSFON _IOW_BIG(1, u8_t [8192])
|
#define TIOCSFON _IOW_BIG(1, u8_t [8192])
|
||||||
|
|
||||||
/* Keyboard ioctls. */
|
/* Keyboard ioctls. */
|
||||||
|
|
|
@ -376,8 +376,8 @@ int profil(char *, size_t, u_long, u_int);
|
||||||
void psignal(int, const char *);
|
void psignal(int, const char *);
|
||||||
#endif /* __PSIGNAL_DECLARED */
|
#endif /* __PSIGNAL_DECLARED */
|
||||||
int rcmd(char **, int, const char *, const char *, const char *, int *);
|
int rcmd(char **, int, const char *, const char *, const char *, int *);
|
||||||
#ifndef __minix
|
|
||||||
int reboot(int, char *);
|
int reboot(int, char *);
|
||||||
|
#ifndef __minix
|
||||||
int revoke(const char *);
|
int revoke(const char *);
|
||||||
#endif
|
#endif
|
||||||
int rresvport(int *);
|
int rresvport(int *);
|
||||||
|
|
|
@ -39,26 +39,12 @@
|
||||||
#ifndef _UTMP_H_
|
#ifndef _UTMP_H_
|
||||||
#define _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_UTMP "/var/run/utmp"
|
||||||
#define _PATH_WTMP "/var/log/wtmp"
|
#define _PATH_WTMP "/var/log/wtmp"
|
||||||
#define _PATH_LASTLOG "/var/log/lastlog"
|
#define _PATH_LASTLOG "/var/log/lastlog"
|
||||||
#endif
|
|
||||||
|
|
||||||
#define UT_NAMESIZE 8
|
#define UT_NAMESIZE 8
|
||||||
#ifdef __minix
|
|
||||||
#define UT_LINESIZE 12
|
|
||||||
#else
|
|
||||||
#define UT_LINESIZE 8
|
#define UT_LINESIZE 8
|
||||||
#endif
|
|
||||||
#define UT_HOSTSIZE 16
|
#define UT_HOSTSIZE 16
|
||||||
|
|
||||||
struct lastlog {
|
struct lastlog {
|
||||||
|
@ -67,34 +53,12 @@ struct lastlog {
|
||||||
char ll_host[UT_HOSTSIZE];
|
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 {
|
struct utmp {
|
||||||
char ut_line[UT_LINESIZE];
|
char ut_line[UT_LINESIZE];
|
||||||
char ut_name[UT_NAMESIZE];
|
char ut_name[UT_NAMESIZE];
|
||||||
char ut_host[UT_HOSTSIZE];
|
char ut_host[UT_HOSTSIZE];
|
||||||
time_t ut_time;
|
time_t ut_time;
|
||||||
};
|
};
|
||||||
#endif /* __minix */
|
|
||||||
|
|
||||||
__BEGIN_DECLS
|
__BEGIN_DECLS
|
||||||
int utmpname(const char *);
|
int utmpname(const char *);
|
||||||
|
|
|
@ -9,8 +9,9 @@
|
||||||
#include <machine/vm.h>
|
#include <machine/vm.h>
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
|
|
||||||
#include <minix/reboot.h>
|
|
||||||
#include <minix/board.h>
|
#include <minix/board.h>
|
||||||
|
#include <sys/reboot.h>
|
||||||
|
|
||||||
#include <minix/u64.h>
|
#include <minix/u64.h>
|
||||||
|
|
||||||
#include "archconst.h"
|
#include "archconst.h"
|
||||||
|
@ -51,25 +52,23 @@ poweroff(void)
|
||||||
__dead void
|
__dead void
|
||||||
arch_shutdown(int how)
|
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 */
|
/* Power off if possible, hang otherwise */
|
||||||
poweroff();
|
poweroff();
|
||||||
NOT_REACHABLE;
|
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 the system */
|
||||||
reset();
|
reset();
|
||||||
NOT_REACHABLE;
|
NOT_REACHABLE;
|
||||||
}
|
|
||||||
while (1);
|
while (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#include <minix/com.h>
|
#include <minix/com.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <minix/reboot.h>
|
#include <sys/reboot.h>
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "arch_proto.h"
|
#include "arch_proto.h"
|
||||||
#include "direct_utils.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
|
* longer used and the "real" implementations are visible
|
||||||
*/
|
*/
|
||||||
void send_diag_sig(void) { }
|
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) { }
|
void busy_delay_ms(int x) { }
|
||||||
int raise(int n) { panic("raise(%d)\n", n); }
|
int raise(int n) { panic("raise(%d)\n", n); }
|
||||||
int kern_phys_map_ptr( phys_bytes base_address, vir_bytes io_size,
|
int kern_phys_map_ptr( phys_bytes base_address, vir_bytes io_size,
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include <machine/cpu.h>
|
#include <machine/cpu.h>
|
||||||
#include <minix/portio.h>
|
#include <minix/portio.h>
|
||||||
#include <minix/cpufeature.h>
|
#include <minix/cpufeature.h>
|
||||||
#include <minix/reboot.h>
|
#include <sys/reboot.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <machine/vm.h>
|
#include <machine/vm.h>
|
||||||
|
@ -135,29 +135,23 @@ __dead void arch_shutdown(int how)
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (how) {
|
if((how & RB_POWERDOWN) == RB_POWERDOWN) {
|
||||||
case RBT_HALT:
|
|
||||||
/* Hang */
|
|
||||||
for (; ; ) halt_cpu();
|
|
||||||
NOT_REACHABLE;
|
|
||||||
|
|
||||||
case RBT_POWEROFF:
|
|
||||||
/* Power off if possible, hang otherwise */
|
/* Power off if possible, hang otherwise */
|
||||||
poweroff();
|
poweroff();
|
||||||
NOT_REACHABLE;
|
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.
|
/* Reset the system by forcing a processor shutdown.
|
||||||
* First stop the BIOS memory test by setting a soft
|
* First stop the BIOS memory test by setting a soft
|
||||||
* reset flag.
|
* reset flag.
|
||||||
*/
|
*/
|
||||||
reset();
|
reset();
|
||||||
NOT_REACHABLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
NOT_REACHABLE;
|
NOT_REACHABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#include <minix/com.h>
|
#include <minix/com.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <minix/reboot.h>
|
#include <sys/reboot.h>
|
||||||
#include <machine/partition.h>
|
#include <machine/partition.h>
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "arch_proto.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 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) { }
|
void busy_delay_ms(int x) { }
|
||||||
int raise(int sig) { panic("raise(%d)\n", sig); }
|
int raise(int sig) { panic("raise(%d)\n", sig); }
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
#include <minix/u64.h>
|
#include <minix/u64.h>
|
||||||
#include <minix/board.h>
|
#include <minix/board.h>
|
||||||
#include <minix/type.h>
|
#include <minix/type.h>
|
||||||
#include <minix/reboot.h>
|
#include <sys/reboot.h>
|
||||||
#include "clock.h"
|
#include "clock.h"
|
||||||
#include "direct_utils.h"
|
#include "direct_utils.h"
|
||||||
#include "hw_intr.h"
|
#include "hw_intr.h"
|
||||||
|
@ -357,8 +357,7 @@ void prepare_shutdown(const int how)
|
||||||
void minix_shutdown(minix_timer_t *tp)
|
void minix_shutdown(minix_timer_t *tp)
|
||||||
{
|
{
|
||||||
/* This function is called from prepare_shutdown or stop_sequence to bring
|
/* 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
|
* down MINIX.
|
||||||
* monitor), RBT_RESET (hard reset).
|
|
||||||
*/
|
*/
|
||||||
int how;
|
int how;
|
||||||
|
|
||||||
|
@ -376,25 +375,17 @@ void minix_shutdown(minix_timer_t *tp)
|
||||||
hw_intr_disable_all();
|
hw_intr_disable_all();
|
||||||
stop_local_timer();
|
stop_local_timer();
|
||||||
|
|
||||||
how = tp ? tmr_arg(tp)->ta_int : RBT_PANIC;
|
how = tp ? tmr_arg(tp)->ta_int : 0;
|
||||||
|
|
||||||
/* Show shutdown message */
|
/* Show shutdown message */
|
||||||
direct_cls();
|
direct_cls();
|
||||||
switch(how) {
|
if((how & RB_POWERDOWN) == RB_POWERDOWN)
|
||||||
case RBT_HALT:
|
direct_print("MINIX has halted and will now power off.\n");
|
||||||
|
else if(how & RB_HALT)
|
||||||
direct_print("MINIX has halted. "
|
direct_print("MINIX has halted. "
|
||||||
"It is safe to turn off your computer.\n");
|
"It is safe to turn off your computer.\n");
|
||||||
break;
|
else
|
||||||
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:
|
|
||||||
direct_print("MINIX will now reset.\n");
|
direct_print("MINIX will now reset.\n");
|
||||||
break;
|
|
||||||
}
|
|
||||||
arch_shutdown(how);
|
arch_shutdown(how);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -355,20 +355,14 @@ updwtmpx(const char *file, const struct utmpx *utx)
|
||||||
#else
|
#else
|
||||||
if ((fd = open(file, O_CREAT|O_WRONLY, 0644)) < 0)
|
if ((fd = open(file, O_CREAT|O_WRONLY, 0644)) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
if (flock(fd, LOCK_EX) < 0)
|
|
||||||
return -1;
|
|
||||||
#endif
|
#endif
|
||||||
(void)memset(&ut, 0, sizeof(ut));
|
(void)memset(&ut, 0, sizeof(ut));
|
||||||
ut.ut_type = SIGNATURE;
|
ut.ut_type = SIGNATURE;
|
||||||
(void)memcpy(ut.ut_user, vers, sizeof(vers));
|
(void)memcpy(ut.ut_user, vers, sizeof(vers));
|
||||||
if (write(fd, &ut, sizeof(ut)) == -1)
|
if (write(fd, &ut, sizeof(ut)) == -1)
|
||||||
goto failed;
|
goto failed;
|
||||||
} else {
|
|
||||||
#ifdef __minix
|
|
||||||
if (flock(fd, LOCK_SH) < 0 )
|
|
||||||
return -1;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (write(fd, utx, sizeof(*utx)) == -1)
|
if (write(fd, utx, sizeof(*utx)) == -1)
|
||||||
goto failed;
|
goto failed;
|
||||||
if (close(fd) == -1)
|
if (close(fd) == -1)
|
||||||
|
@ -455,10 +449,6 @@ getlastlogx(const char *fname, uid_t uid, struct lastlogx *ll)
|
||||||
|
|
||||||
if (db == NULL)
|
if (db == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
#ifdef __minix
|
|
||||||
if (flock(db->fd(db), LOCK_SH) < 0)
|
|
||||||
return NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
key.data = &uid;
|
key.data = &uid;
|
||||||
key.size = sizeof(uid);
|
key.size = sizeof(uid);
|
||||||
|
@ -503,10 +493,6 @@ updlastlogx(const char *fname, uid_t uid, struct lastlogx *ll)
|
||||||
if (db == NULL)
|
if (db == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
#ifdef __minix
|
|
||||||
if (flock(db->fd(db), LOCK_EX) < 0)
|
|
||||||
return -1;
|
|
||||||
#endif
|
|
||||||
key.data = &uid;
|
key.data = &uid;
|
||||||
key.size = sizeof(uid);
|
key.size = sizeof(uid);
|
||||||
data.data = ll;
|
data.data = ll;
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/reboot.h>
|
#include <sys/reboot.h>
|
||||||
|
|
||||||
int reboot(int how)
|
int reboot(int how, char *bootstr)
|
||||||
{
|
{
|
||||||
message m;
|
message m;
|
||||||
|
|
||||||
|
|
|
@ -99,7 +99,7 @@ void minix_stack_params(const char *path, char * const *argv, char * const *envp
|
||||||
(*argc)++;
|
(*argc)++;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (p = envp; *p != NULL; p++) {
|
for (p = envp; p && *p != NULL; p++) {
|
||||||
size_t const n = sizeof(*p) + strlen(*p) + 1;
|
size_t const n = sizeof(*p) + strlen(*p) + 1;
|
||||||
*stack_size += n;
|
*stack_size += n;
|
||||||
if (*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;
|
*fpw++ = NULL;
|
||||||
|
|
||||||
for (p = envp; *p != NULL; p++) {
|
for (p = envp; p && *p != NULL; p++) {
|
||||||
size_t const n = strlen(*p) + 1;
|
size_t const n = strlen(*p) + 1;
|
||||||
*fpw++= (char *)(*vsp + (fp - frame));
|
*fpw++= (char *)(*vsp + (fp - frame));
|
||||||
memcpy(fp, *p, n);
|
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 \
|
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
|
munmap.2 nanosleep.2 nfssvc.2 ntp_adjtime.2 open.2 pathconf.2 pipe.2
|
||||||
.else
|
.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)
|
.endif # !defined(__MINIX)
|
||||||
.if !defined(__MINIX)
|
.if !defined(__MINIX)
|
||||||
MAN+= pmc_control.2 poll.2 posix_fadvise.2 profil.2 ptrace.2 __quotactl.2 \
|
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 \
|
.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 \
|
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 \
|
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 \
|
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 \
|
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.c: ${LIBCDIR}/sys-minix
|
||||||
.PATH.S: ${ARCHDIR}/sys-minix
|
.PATH.S: ${ARCHDIR}/sys-minix
|
||||||
SRCS+= ${i}
|
SRCS+= ${i}
|
||||||
|
|
|
@ -42,7 +42,7 @@ SRCS+= efun.c \
|
||||||
passwd.c pw_scan.c pidfile.c pidlock.c pty.c \
|
passwd.c pw_scan.c pidfile.c pidlock.c pty.c \
|
||||||
raise_default_signal.c \
|
raise_default_signal.c \
|
||||||
secure_path.c stat_flags.c \
|
secure_path.c stat_flags.c \
|
||||||
strpct.c ttyaction.c \
|
strpct.c ttyaction.c ttymsg.c \
|
||||||
|
|
||||||
MAN= efun.3 \
|
MAN= efun.3 \
|
||||||
getmntopts.3 \
|
getmntopts.3 \
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
|
|
||||||
SUBDIR= \
|
SUBDIR= \
|
||||||
fingerd ftpd \
|
fingerd ftpd \
|
||||||
ld.elf_so
|
ld.elf_so \
|
||||||
|
getty
|
||||||
|
|
||||||
.if defined(__MINIX)
|
.if defined(__MINIX)
|
||||||
SUBDIR+= makewhatis
|
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 \
|
flexdoc.1 format.1 fortune.1 \
|
||||||
fsck.mfs.1 host.1 hostaddr.1 ifdef.1 \
|
fsck.mfs.1 host.1 hostaddr.1 ifdef.1 \
|
||||||
isodir.1 isoinfo.1 isoread.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 \
|
look.1 lp.1 lspci.1 mail.1 \
|
||||||
mixer.1 \
|
mixer.1 \
|
||||||
mkproto.1 mount.1 mt.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 \
|
getpeername.2 getpid.2 getpriority.2 getsockname.2 getsockopt.2 \
|
||||||
gettimeofday.2 getuid.2 intro.2 ioctl.2 kill.2 link.2 listen.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 \
|
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 \
|
rmdir.2 select.2 send.2 sendmsg.2 sendto.2 setsid.2 \
|
||||||
setsockopt.2 setuid.2 shutdown.2 sigaction.2 sigpending.2 \
|
setsockopt.2 setuid.2 shutdown.2 sigaction.2 sigpending.2 \
|
||||||
sigprocmask.2 sigsuspend.2 socket.2 socketpair.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 \
|
intr.8 irdpd.8 loadramdisk.8 \
|
||||||
netconf.8 newroot.8 nonamed.8 \
|
netconf.8 newroot.8 nonamed.8 \
|
||||||
ossdevlinks.8 part.8 partition.8 \
|
ossdevlinks.8 part.8 partition.8 \
|
||||||
poweroff.8 printroot.8 pr_routes.8 pwdauth.8 rarpd.8 \
|
printroot.8 pr_routes.8 pwdauth.8 rarpd.8 \
|
||||||
readclock.8 reboot.8 repartition.8 \
|
readclock.8 repartition.8 \
|
||||||
rshd.8 screendump.8 serial-ip.8 \
|
rshd.8 screendump.8 serial-ip.8 \
|
||||||
setup.8 shutdown.8 slip.8 srccrc.8 syslogd.8 tcpd.8 \
|
setup.8 shutdown.8 slip.8 srccrc.8 syslogd.8 tcpd.8 \
|
||||||
unix.8 update.8 usage.8 vbfs.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/mfs/mfs
|
||||||
PROGRAMS+= ${PROGROOT}/servers/vm/vm
|
PROGRAMS+= ${PROGROOT}/servers/vm/vm
|
||||||
PROGRAMS+= ${PROGROOT}/servers/pfs/pfs
|
PROGRAMS+= ${PROGROOT}/servers/pfs/pfs
|
||||||
PROGRAMS+= ${PROGROOT}/servers/init/init
|
PROGRAMS+= ${PROGROOT}/sbin/init/init
|
||||||
|
|
||||||
usage:
|
usage:
|
||||||
@echo " " >&2
|
@echo " " >&2
|
||||||
|
@ -68,10 +68,13 @@ kernel: libraries
|
||||||
servers: libraries
|
servers: libraries
|
||||||
${MAKE} -C ../servers all install
|
${MAKE} -C ../servers all install
|
||||||
|
|
||||||
|
sbin: libraries
|
||||||
|
${MAKE} -C ../sbin all install
|
||||||
|
|
||||||
drivers: libraries servers
|
drivers: libraries servers
|
||||||
${MAKE} -C ../drivers all install
|
${MAKE} -C ../drivers all install
|
||||||
|
|
||||||
services: kernel servers drivers
|
services: kernel servers drivers sbin
|
||||||
|
|
||||||
.gitignore: Makefile
|
.gitignore: Makefile
|
||||||
echo ${GEN_FILES} | tr ' ' '\n' >.gitignore
|
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
|
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
|
do
|
||||||
cp ${OBJ}/servers/${f}/${f} ${OBJ}/${f}.elf
|
fn=`basename $f`.elf
|
||||||
${CROSS_PREFIX}strip -s ${OBJ}/${f}.elf
|
cp ${OBJ}/${f} ${OBJ}/${fn}
|
||||||
mcopy -bsp -i ${IMG_DIR}/fat.img ${OBJ}/${f}.elf ::${f}.elf
|
${CROSS_PREFIX}strip -s ${OBJ}/${fn}
|
||||||
|
mcopy -bsp -i ${IMG_DIR}/fat.img ${OBJ}/${fn} ::${fn}
|
||||||
done
|
done
|
||||||
|
|
||||||
for f in tty memory
|
for f in tty memory
|
||||||
|
|
|
@ -73,6 +73,7 @@
|
||||||
2012/10/17 12:00:00,include
|
2012/10/17 12:00:00,include
|
||||||
2013/05/31 12:00:00,libexec/fingerd
|
2013/05/31 12:00:00,libexec/fingerd
|
||||||
2012/10/17 12:00:00,libexec/ftpd
|
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/ld.elf_so
|
||||||
2012/10/17 12:00:00,libexec/Makefile
|
2012/10/17 12:00:00,libexec/Makefile
|
||||||
2012/10/17 12:00:00,libexec/Makefile.inc
|
2012/10/17 12:00:00,libexec/Makefile.inc
|
||||||
|
@ -97,6 +98,9 @@
|
||||||
2012/10/17 12:00:00,Makefile
|
2012/10/17 12:00:00,Makefile
|
||||||
2011/06/09 21:23:29,sbin/fsck
|
2011/06/09 21:23:29,sbin/fsck
|
||||||
2011/09/16 16:13:18,sbin/fsck_ext2fs
|
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
|
||||||
2012/10/17 12:00:00,sbin/Makefile.inc
|
2012/10/17 12:00:00,sbin/Makefile.inc
|
||||||
2012/10/10 16:16:12,sbin/mknod
|
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/join
|
||||||
2012/10/17 12:00:00,usr.bin/jot
|
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/lam
|
||||||
|
2012/10/17 12:00:00,usr.bin/last
|
||||||
2011/01/17 18:11:10,usr.bin/ldd
|
2011/01/17 18:11:10,usr.bin/ldd
|
||||||
2013/10/18 12:00:00,usr.bin/leave
|
2013/10/18 12:00:00,usr.bin/leave
|
||||||
2012/10/17 12:00:00,usr.bin/lock
|
2012/10/17 12:00:00,usr.bin/lock
|
||||||
|
@ -248,11 +253,12 @@
|
||||||
2013/10/14 12:00:00,usr.bin/users
|
2013/10/14 12:00:00,usr.bin/users
|
||||||
2013/10/23 12:00:00,usr.bin/uuidgen
|
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/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/wc
|
||||||
2012/10/17 12:00:00,usr.bin/what
|
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
|
2013/03/15 12:00:00,usr.bin/who
|
||||||
2012/10/17 12:00:00,usr.bin/whois
|
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/write
|
||||||
2012/10/17 12:00:00,usr.bin/xinstall
|
2012/10/17 12:00:00,usr.bin/xinstall
|
||||||
2012/10/17 12:00:00,usr.bin/xstr
|
2012/10/17 12:00:00,usr.bin/xstr
|
||||||
|
|
|
@ -9,7 +9,12 @@
|
||||||
SUBDIR= \
|
SUBDIR= \
|
||||||
\
|
\
|
||||||
fsck \
|
fsck \
|
||||||
mknod nologin
|
mknod \
|
||||||
|
nologin \
|
||||||
|
mknod \
|
||||||
|
init \
|
||||||
|
reboot \
|
||||||
|
shutdown
|
||||||
|
|
||||||
# support for various file systems
|
# support for various file systems
|
||||||
SUBDIR+= newfs_ext2fs fsck_ext2fs
|
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"
|
.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
|
.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
|
mfs pfs pm procfs rs sched vfs vm devman
|
||||||
|
|
||||||
.if ${MACHINE_ARCH} == "i386"
|
.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 */
|
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. */
|
/* Get file system version and type - only support v3. */
|
||||||
if(magic != SUPER_V3) {
|
if(magic != SUPER_V3) {
|
||||||
printf("MFS: only supports V3 filesystems.\n");
|
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
version = V3;
|
version = V3;
|
||||||
|
|
|
@ -13,11 +13,11 @@
|
||||||
#include <minix/callnr.h>
|
#include <minix/callnr.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <sys/svrctl.h>
|
#include <sys/svrctl.h>
|
||||||
|
#include <sys/reboot.h>
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
#include <sys/utsname.h>
|
#include <sys/utsname.h>
|
||||||
#include <minix/com.h>
|
#include <minix/com.h>
|
||||||
#include <minix/config.h>
|
#include <minix/config.h>
|
||||||
#include <minix/reboot.h>
|
|
||||||
#include <minix/sysinfo.h>
|
#include <minix/sysinfo.h>
|
||||||
#include <minix/type.h>
|
#include <minix/type.h>
|
||||||
#include <minix/ds.h>
|
#include <minix/ds.h>
|
||||||
|
@ -213,10 +213,9 @@ int do_reboot()
|
||||||
|
|
||||||
/* See how the system should be aborted. */
|
/* See how the system should be aborted. */
|
||||||
abort_flag = (unsigned) m_in.PM_REBOOT_HOW;
|
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) */
|
/* notify readclock (some arm systems power off via RTC alarms) */
|
||||||
if (abort_flag == RBT_POWEROFF) {
|
if (abort_flag & RB_POWERDOWN) {
|
||||||
endpoint_t readclock_ep;
|
endpoint_t readclock_ep;
|
||||||
if (ds_retrieve_label_endpt("readclock.drv", &readclock_ep) == OK) {
|
if (ds_retrieve_label_endpt("readclock.drv", &readclock_ep) == OK) {
|
||||||
message m; /* no params to set, nothing we can do if it fails */
|
message m; /* no params to set, nothing we can do if it fails */
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/ioc_tty.h>
|
||||||
#include <minix/callnr.h>
|
#include <minix/callnr.h>
|
||||||
#include <minix/com.h>
|
#include <minix/com.h>
|
||||||
#include <minix/endpoint.h>
|
#include <minix/endpoint.h>
|
||||||
|
@ -267,6 +268,13 @@ int cdev_io(
|
||||||
if ((dp = cdev_get(dev, &minor_dev)) == NULL)
|
if ((dp = cdev_get(dev, &minor_dev)) == NULL)
|
||||||
return(EIO);
|
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. */
|
/* Create a grant for the buffer provided by the user process. */
|
||||||
gid = make_grant(dp->dmap_driver, proc_e, op, buf, bytes);
|
gid = make_grant(dp->dmap_driver, proc_e, op, buf, bytes);
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ SUBDIR= asa \
|
||||||
fsplit ftp genassym getopt \
|
fsplit ftp genassym getopt \
|
||||||
head hexdump id indent infocmp join jot \
|
head hexdump id indent infocmp join jot \
|
||||||
lam ldd leave \
|
lam ldd leave \
|
||||||
|
last \
|
||||||
lock login logname lorder m4 \
|
lock login logname lorder m4 \
|
||||||
machine make man menuc mesg \
|
machine make man menuc mesg \
|
||||||
mkdep mkfifo mkstr mktemp \
|
mkdep mkfifo mkstr mktemp \
|
||||||
|
@ -30,8 +31,9 @@ SUBDIR= asa \
|
||||||
toproto \
|
toproto \
|
||||||
uniq units unvis unzip users \
|
uniq units unvis unzip users \
|
||||||
uuidgen vis \
|
uuidgen vis \
|
||||||
|
uniq uname units unzip users \
|
||||||
|
wall wc what whatis who whois \
|
||||||
\
|
\
|
||||||
wc what who whois \
|
|
||||||
write xargs xinstall xstr yes
|
write xargs xinstall xstr yes
|
||||||
|
|
||||||
.if !defined(__MINIX)
|
.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