summaryrefslogtreecommitdiffstats
path: root/login-utils
diff options
context:
space:
mode:
authorKarel Zak2006-12-07 00:25:37 +0100
committerKarel Zak2006-12-07 00:25:37 +0100
commit5c36a0eb7cdb0360f9afd5d747c321f423b35984 (patch)
tree147599a77eaff2b5fbc0d389e89d2b51602326c0 /login-utils
parentImported from util-linux-2.8 tarball. (diff)
downloadkernel-qcow2-util-linux-5c36a0eb7cdb0360f9afd5d747c321f423b35984.tar.gz
kernel-qcow2-util-linux-5c36a0eb7cdb0360f9afd5d747c321f423b35984.tar.xz
kernel-qcow2-util-linux-5c36a0eb7cdb0360f9afd5d747c321f423b35984.zip
Imported from util-linux-2.9i tarball.
Diffstat (limited to 'login-utils')
-rw-r--r--login-utils/Makefile51
-rw-r--r--login-utils/agetty.c8
-rw-r--r--login-utils/checktty.c24
-rw-r--r--login-utils/chfn.c17
-rw-r--r--login-utils/chsh.14
-rw-r--r--login-utils/chsh.c5
-rw-r--r--login-utils/last.1.orig49
-rw-r--r--login-utils/last.c26
-rw-r--r--login-utils/last.c.orig381
-rw-r--r--login-utils/login.16
-rw-r--r--login-utils/login.c141
-rw-r--r--login-utils/passwd.19
-rw-r--r--login-utils/passwd.c19
-rw-r--r--login-utils/shutdown.832
-rw-r--r--login-utils/shutdown.c239
-rw-r--r--login-utils/simpleinit.c18
-rw-r--r--login-utils/vipw.c5
17 files changed, 386 insertions, 648 deletions
diff --git a/login-utils/Makefile b/login-utils/Makefile
index 9f41fcd19..f4bbc5a99 100644
--- a/login-utils/Makefile
+++ b/login-utils/Makefile
@@ -82,54 +82,53 @@ all-misc: $(USRBIN.MISC)
# Rules for everything else
-agetty.o: $(BSD)/pathnames.h
+agetty.o: $(LIB)/pathnames.h
agetty: agetty.o
chfn: chfn.o islocal.o setpwnam.o
- $(CC) -o $@ $^ $(CRYPT) $(PAM)
+ $(CC) $(LDFLAGS) -o $@ $^ $(CRYPT) $(PAM)
chsh: chsh.o islocal.o setpwnam.o
- $(CC) -o $@ $^ $(CRYPT) $(PAM)
-islocal.o: $(BSD)/pathnames.h
-last.o: $(BSD)/pathnames.h
-last: last.o $(BSD)/getopt.o
+ $(CC) $(LDFLAGS) -o $@ $^ $(CRYPT) $(PAM)
+islocal.o: $(LIB)/pathnames.h
+last.o: $(LIB)/pathnames.h
+last: last.o
ifeq "$(HAVE_PAM)" "yes"
-login: login.o
- $(CC) -o $@ $^ $(CRYPT) $(PAM)
+login: login.o $(LIB)/setproctitle.o
+ $(CC) $(LDFLAGS) -o $@ $^ $(CRYPT) $(PAM)
else
-login: login.o checktty.o
- $(CC) -o $@ $^ $(CRYPT)
+login: login.o $(LIB)/setproctitle.o checktty.o
+ $(CC) $(LDFLAGS) -o $@ $^ $(CRYPT)
endif
-mesg: mesg.o $(BSD)/getopt.o $(BSD)/err.o
+mesg: mesg.o $(ERR_O)
newgrp: newgrp.o
- $(CC) -o $@ $^ $(CRYPT) $(PAM)
-setpwnam.o: $(BSD)/pathnames.h
-shutdown.o: $(BSD)/pathnames.h
-shutdown: shutdown.o
-simpleinit.o: $(BSD)/pathnames.h
-simpleinit: simpleinit.o $(CRYPT)
-vipw.o: $(BSD)/pathnames.h
+ $(CC) $(LDFLAGS) -o $@ $^ $(CRYPT) $(PAM)
+setpwnam.o: $(LIB)/pathnames.h
+shutdown.o: $(LIB)/pathnames.h $(LIB)/linux_reboot.h
+shutdown: shutdown.o $(LIB)/my_reboot.o
+simpleinit.o: $(LIB)/pathnames.h $(LIB)/linux_reboot.h
+simpleinit: simpleinit.o $(LIB)/my_reboot.o
+vipw.o: $(LIB)/pathnames.h
vipw: vipw.o
-newgrp.o: $(BSD)/pathnames.h
+newgrp.o: $(LIB)/pathnames.h
$(CC) -c $(CFLAGS) $(PAMFL) newgrp.c
wall: wall.o ttymsg.o
ifeq "$(USE_TTY_GROUP)" "yes"
-login.o: login.c $(BSD)/pathnames.h
+login.o: login.c $(LIB)/pathnames.h $(LIB)/setproctitle.c $(LIB)/setproctitle.h
$(CC) -c $(CFLAGS) $(PAMFL) -DUSE_TTY_GROUP login.c
-mesg.o: mesg.c $(BSD)/err.h
+mesg.o: mesg.c $(LIB)/err.h
$(CC) -c $(CFLAGS) -DUSE_TTY_GROUP mesg.c
else
-login.o: $(BSD)/pathnames.h
+login.o: $(LIB)/pathnames.h
$(CC) -c $(CFLAGS) $(PAMFL) login.c
-mesg.o: $(BSD)/err.h
+mesg.o: $(LIB)/err.h
endif
-passwd: passwd.o islocal.o setpwnam.o $(CRYPT)
-passwd.o: passwd.c
- $(CC) -c $(CFLAGS) passwd.c
+passwd: passwd.o islocal.o setpwnam.o
+ $(CC) $(LDFLAGS) -o $@ $^ $(CRYPT)
ifeq "$(REQUIRE_PASSWORD)" "yes"
CHSH_FLAGS:=$(CHSH_FLAGS) -DREQUIRE_PASSWORD
diff --git a/login-utils/agetty.c b/login-utils/agetty.c
index 039589591..96d7b38d0 100644
--- a/login-utils/agetty.c
+++ b/login-utils/agetty.c
@@ -545,6 +545,9 @@ update_utmp(line)
endutent();
{
+#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1)
+ updwtmp(_PATH_WTMP, &ut);
+#else
int lf;
if ((lf = open(_PATH_WTMPLOCK, O_CREAT|O_WRONLY, 0660)) >= 0) {
@@ -556,8 +559,9 @@ update_utmp(line)
flock(lf, LOCK_UN);
close(lf);
}
+#endif
}
-#else
+#else /* not __linux__ */
if ((ut_fd = open(UTMP_FILE, 2)) < 0) {
error("%s: open for update: %m", UTMP_FILE);
} else {
@@ -769,7 +773,7 @@ do_prompt(op, tp)
#ifdef ISSUE
FILE *fd;
int oflag;
- char c;
+ int c;
struct utsname uts;
(void) uname(&uts);
diff --git a/login-utils/checktty.c b/login-utils/checktty.c
index f01d0ee82..15873aa44 100644
--- a/login-utils/checktty.c
+++ b/login-utils/checktty.c
@@ -135,6 +135,8 @@ add_to_class(struct ttyclass *tc, char *tty)
/* return true if tty is a pty. Very linux dependent */
+/* Note that the new dynamic ptys (say /dev/pty/0 etc) have major in 128-135 */
+/* We might try TIOCGPTN or so to recognise these new ones, if desired */
static int
isapty(const char *tty)
{
@@ -146,20 +148,18 @@ isapty(const char *tty)
return 0;
sprintf(devname, "/dev/%s", tty);
-#if defined(__linux__) && defined(PTY_SLAVE_MAJOR)
- /* this is for linux 1.3 and newer */
- if((stat(devname, &stb) >= 0)
- && major(stb.st_rdev) == PTY_SLAVE_MAJOR) {
- return 1;
- }
+#if defined(__linux__)
+ if((stat(devname, &stb) >= 0) && S_ISCHR(stb.st_mode)) {
+
+#if defined(PTY_SLAVE_MAJOR)
+ /* this is for linux 1.3 and newer */
+ if(major(stb.st_rdev) == PTY_SLAVE_MAJOR)
+ return 1;
#endif
-#if defined(__linux__)
- /* this is for linux versions before 1.3, backward compat. */
- if((stat(devname, &stb) >= 0)
- && major(stb.st_rdev) == TTY_MAJOR
- && minor(stb.st_rdev) >= 192) {
- return 1;
+ /* this is for linux versions before 1.3, backward compat. */
+ if(major(stb.st_rdev) == TTY_MAJOR && minor(stb.st_rdev) >= 192)
+ return 1;
}
#endif
return 0;
diff --git a/login-utils/chfn.c b/login-utils/chfn.c
index 8e962db05..3da2360f1 100644
--- a/login-utils/chfn.c
+++ b/login-utils/chfn.c
@@ -14,9 +14,6 @@
* patches from Zefram <A.Main@dcs.warwick.ac.uk>
*
* Hacked by Peter Breitenlohner, peb@mppmu.mpg.de,
- * to allow peaceful coexistence with yp: using the changes by
- * Alvaro Martinez Echevarria, alvaro@enano.etsit.upm.es, from
- * passwd.c (now moved to setpwnam.c);
* to remove trailing empty fields. Oct 5, 96.
*
*/
@@ -32,6 +29,7 @@
#include <errno.h>
#include <ctype.h>
#include <getopt.h>
+#include <locale.h>
#include "my_crypt.h"
#include "../version.h"
@@ -81,6 +79,9 @@ extern int setpwnam P((struct passwd *pwd));
#define memzero(ptr, size) memset((char *) ptr, 0, size)
+/* we do not accept gecos field sizes lengther than MAX_FIELD_SIZE */
+#define MAX_FIELD_SIZE 256
+
int main (argc, argv)
int argc;
char *argv[];
@@ -103,6 +104,9 @@ int main (argc, argv)
for (cp = whoami; *cp; cp++)
if (*cp == '/') whoami = cp + 1;
+ /* iscntrl() below should not reject actual names */
+ setlocale(LC_ALL,"");
+
/*
* "oldf" contains the users original finger information.
* "newf" contains the changed finger information, and contains NULL
@@ -393,6 +397,13 @@ static int check_gecos_string (msg, gecos)
{
int i, c;
+ if (strlen(gecos) > MAX_FIELD_SIZE) {
+ if (msg != NULL)
+ printf("%s: ", msg);
+ printf("field is too long.\n");
+ return -1;
+ }
+
for (i = 0; i < strlen (gecos); i++) {
c = gecos[i];
if (c == ',' || c == ':' || c == '=' || c == '"' || c == '\n') {
diff --git a/login-utils/chsh.1 b/login-utils/chsh.1
index 57ded2902..42e87ca60 100644
--- a/login-utils/chsh.1
+++ b/login-utils/chsh.1
@@ -10,7 +10,7 @@
.\" $Revision: 1.1 $
.\" $Date: 1995/03/12 01:28:58 $
.\"
-.TH CHSH 1 "October 13 1994" "chsh" "Linux Reference Manual"
+.TH CHSH 1 "7 October 1998" "chsh" "Linux Reference Manual"
.SH NAME
chsh \- change your login shell
.SH SYNOPSIS
@@ -28,6 +28,8 @@ will accept the full pathname of any executable file on the system.
However, it will issue a warning if the shell is not listed in the
.I /etc/shells
file.
+On the other hand, it can also be configured such that it will
+only accept shells listed in this file, unless you are root.
.SH OPTIONS
.TP
.I "\-s, \-\-shell"
diff --git a/login-utils/chsh.c b/login-utils/chsh.c
index f64cd0b78..8e8a51bc0 100644
--- a/login-utils/chsh.c
+++ b/login-utils/chsh.c
@@ -17,11 +17,6 @@
* suggestion from Zefram. Disallowing users with shells not in /etc/shells
* from changing their shell.
*
- * Hacked by Peter Breitenlohner, peb@mppmu.mpg.de,
- * to allow peaceful coexistence with yp: using the changes by
- * Alvaro Martinez Echevarria, alvaro@enano.etsit.upm.es, from
- * passwd.c (now moved to setpwnam.c). Oct 5, 96.
- *
*/
#if 0
diff --git a/login-utils/last.1.orig b/login-utils/last.1.orig
deleted file mode 100644
index 4d0deb882..000000000
--- a/login-utils/last.1.orig
+++ /dev/null
@@ -1,49 +0,0 @@
-.TH LAST 1 "20 March 1992"
-.SH NAME
-last \(em indicate last logins by user or terminal
-.SH SYNOPSIS
-.ad l
-.B last
-.RB [ \-\fP\fInumber\fP ]
-.RB [ \-f
-.IR filename ]
-.RB [ \-t
-.IR tty ]
-.RB [ \-h
-.IR hostname ]
-.RI [ name ...]
-.ad b
-.SH DESCRIPTION
-\fBLast\fP looks back in the \fBwtmp\fP file which records all logins
-and logouts for information about a user, a teletype or any group of
-users and teletypes. Arguments specify names of users or teletypes of
-interest. If multiple arguments are given, the information which
-applies to any of the arguments is printed. For example ``\fBlast root
-console\fP'' would list all of root's sessions as well as all sessions
-on the console terminal. \fBLast\fP displays the sessions of the
-specified users and teletypes, most recent first, indicating the times
-at which the session began, the duration of the session, and the
-teletype which the session took place on. If the session is still
-continuing or was cut short by a reboot, \fBlast\fP so indicates.
-.LP
-The pseudo-user \fBreboot\fP logs in at reboots of the system.
-.LP
-\fBLast\fP with no arguments displays a record of all logins and
-logouts, in reverse order.
-.LP
-If \fBlast\fP is interrupted, it indicates how far the search has
-progressed in \fBwtmp\fP. If interrupted with a quit signal \fBlast\fP
-indicates how far the search has progressed so far, and the search
-continues.
-.SH OPTIONS
-.IP \fB\-\fP\fInumber\fP
-limit the number of entries displayed to that specified by \fInumber\fP.
-.IP "\fB\-\fP \fIfilename\fP"
-Use \fIfilename\fP as the name of the accounting file instead of
-.BR /etc/wtmp .
-.IP "\fB\-t\fP \fItty\fP"
-List only logins on \fItty\fP.
-.IP "\fB\-h\fP \fIhostname\fP"
-List only logins from \fhostname\fP.
-.SH FILES
-/etc/wtmp \(em login data base
diff --git a/login-utils/last.c b/login-utils/last.c
index 98ffef38f..cf59b8ea6 100644
--- a/login-utils/last.c
+++ b/login-utils/last.c
@@ -45,6 +45,16 @@ static struct utmp buf[1024]; /* utmp read buffer */
#define LMAX (int)sizeof(buf[0].ut_line) /* size of utmp tty field */
#define NMAX (int)sizeof(buf[0].ut_name) /* size of utmp name field */
+#ifndef MIN
+#define MIN(a,b) (((a) < (b)) ? (a) : (b))
+#endif
+
+/* maximum sizes used for printing */
+/* probably we want a two-pass version that computes the right length */
+int hmax = MIN(HMAX, 16);
+int lmax = MIN(LMAX, 8);
+int nmax = MIN(NMAX, 16);
+
typedef struct arg {
char *name; /* argument */
#define HOST_TYPE -2
@@ -142,19 +152,19 @@ print_partial_line(bp)
char *ct;
ct = ctime(&bp->ut_time);
- printf("%-*.*s %-*.*s ", NMAX, NMAX, bp->ut_name,
- LMAX, LMAX, bp->ut_line);
+ printf("%-*.*s %-*.*s ", nmax, nmax, bp->ut_name,
+ lmax, lmax, bp->ut_line);
if (dolong) {
if (bp->ut_addr) {
struct in_addr foo;
foo.s_addr = bp->ut_addr;
- printf("%-*.*s ", HMAX, HMAX, inet_ntoa(foo));
+ printf("%-*.*s ", hmax, hmax, inet_ntoa(foo));
} else {
- printf("%-*.*s ", HMAX, HMAX, "");
+ printf("%-*.*s ", hmax, hmax, "");
}
} else {
- printf("%-*.*s ", HMAX, HMAX, bp->ut_host);
+ printf("%-*.*s ", hmax, hmax, bp->ut_host);
}
if (doyear) {
@@ -178,7 +188,7 @@ wtmp()
lseek(), time();
int bytes, wfd;
void onintr();
- char *ct, *crmsg;
+ char *ct, *crmsg = NULL;
if ((wfd = open(file, O_RDONLY, 0)) < 0 || fstat(wfd, &stb) == -1) {
perror(file);
@@ -191,7 +201,7 @@ wtmp()
(void)signal(SIGQUIT, onintr);
while (--bl >= 0) {
- if (lseek(wfd, (long)(bl * sizeof(buf)), L_SET) == -1 ||
+ if (lseek(wfd, (long)(bl * sizeof(buf)), SEEK_SET) == -1 ||
(bytes = read(wfd, (char *)buf, sizeof(buf))) == -1) {
fprintf(stderr, "last: %s: ", file);
perror((char *)NULL);
@@ -206,7 +216,7 @@ wtmp()
/*
* utmp(5) also mentions that the user
* name should be 'shutdown' or 'reboot'.
- * Not checking the name causes i.e. runlevel
+ * Not checking the name causes e.g. runlevel
* changes to be displayed as 'crash'. -thaele
*/
if (!strncmp(bp->ut_user, "reboot", NMAX) ||
diff --git a/login-utils/last.c.orig b/login-utils/last.c.orig
deleted file mode 100644
index 788aa66a0..000000000
--- a/login-utils/last.c.orig
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- * Copyright (c) 1987 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef lint
-char copyright[] =
-"@(#) Copyright (c) 1987 Regents of the University of California.\n\
- All rights reserved.\n";
-#endif /* not lint */
-
-#ifndef lint
-static char sccsid[] = "@(#)last.c 5.11 (Berkeley) 6/29/88";
-#endif /* not lint */
-
-/*
- * last
- */
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <sys/file.h>
-#include <signal.h>
-#include <string.h>
-#include <time.h>
-#include <utmp.h>
-#include <stdio.h>
-#include <getopt.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include "pathnames.h"
-
-#define SECDAY (24*60*60) /* seconds in a day */
-#define NO 0 /* false/no */
-#define YES 1 /* true/yes */
-
-static struct utmp buf[1024]; /* utmp read buffer */
-
-#define HMAX (int)sizeof(buf[0].ut_host) /* size of utmp host field */
-#define LMAX (int)sizeof(buf[0].ut_line) /* size of utmp tty field */
-#define NMAX (int)sizeof(buf[0].ut_name) /* size of utmp name field */
-
-typedef struct arg {
- 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;
-ARG *arglist; /* head of linked list */
-
-typedef struct ttytab {
- long logout; /* log out time */
- char tty[LMAX + 1]; /* terminal name */
- struct ttytab *next; /* linked list pointer */
-} TTY;
-TTY *ttylist; /* head of linked list */
-
-static long currentout, /* current logout value */
- maxrec; /* records to display */
-static char *file = _PATH_WTMP; /* wtmp file */
-
-static void wtmp(), addarg(), hostconv();
-static int want();
-TTY *addtty();
-static char *ttyconv();
-
-int
-main(argc, argv)
- int argc;
- char **argv;
-{
- extern int optind;
- extern char *optarg;
- int ch;
-
- while ((ch = getopt(argc, argv, "0123456789f:h:t:")) != EOF)
- switch((char)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)
- maxrec = atol(argv[optind - 1] + 1);
- break;
- case 'f':
- file = optarg;
- break;
- case 'h':
- hostconv(optarg);
- addarg(HOST_TYPE, optarg);
- break;
- case 't':
- addarg(TTY_TYPE, ttyconv(optarg));
- break;
- case '?':
- default:
- fputs("usage: last [-#] [-f file] [-t tty] [-h hostname] [user ...]\n", stderr);
- exit(1);
- }
- 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);
- }
- wtmp();
- exit(0);
-}
-
-/*
- * wtmp --
- * read through the wtmp file
- */
-static void
-wtmp()
-{
- register struct utmp *bp; /* current structure */
- register TTY *T; /* tty list entry */
- struct stat stb; /* stat of file for size */
- long bl, delta, /* time difference */
- lseek(), time();
- int bytes, wfd;
- void onintr();
- char *ct, *crmsg;
-
- if ((wfd = open(file, O_RDONLY, 0)) < 0 || fstat(wfd, &stb) == -1) {
- perror(file);
- exit(1);
- }
- bl = (stb.st_size + sizeof(buf) - 1) / sizeof(buf);
-
- (void)time(&buf[0].ut_time);
- (void)signal(SIGINT, onintr);
- (void)signal(SIGQUIT, onintr);
-
- while (--bl >= 0) {
- if (lseek(wfd, (long)(bl * sizeof(buf)), L_SET) == -1 ||
- (bytes = read(wfd, (char *)buf, sizeof(buf))) == -1) {
- fprintf(stderr, "last: %s: ", file);
- perror((char *)NULL);
- exit(1);
- }
- for (bp = &buf[bytes / sizeof(buf[0]) - 1]; bp >= buf; --bp) {
- /*
- * if the terminal line is '~', the machine stopped.
- * see utmp(5) for more info.
- */
- if (!strncmp(bp->ut_line, "~", LMAX)) {
- /* everybody just logged out */
- for (T = ttylist; T; T = T->next)
- T->logout = -bp->ut_time;
- currentout = -bp->ut_time;
- crmsg = strncmp(bp->ut_name, "shutdown", NMAX) ? "crash" : "down ";
- if (!bp->ut_name[0])
- (void)strcpy(bp->ut_name, "reboot");
- if (want(bp, NO)) {
- ct = ctime(&bp->ut_time);
- if(bp->ut_type != LOGIN_PROCESS)
- printf("%-*.*s %-*.*s %-*.*s %10.10s %5.5s \n", NMAX, NMAX, bp->ut_name, LMAX, LMAX, bp->ut_line, HMAX, HMAX, bp->ut_host, ct, ct + 11);
- if (maxrec && !--maxrec)
- return;
- }
- continue;
- }
- /* find associated tty */
- for (T = ttylist;; T = T->next) {
- if (!T) {
- /* add new one */
- T = addtty(bp->ut_line);
- break;
- }
- if (!strncmp(T->tty, bp->ut_line, LMAX))
- break;
- }
- if (bp->ut_name[0] && bp->ut_type != LOGIN_PROCESS
- && want(bp, YES)) {
- ct = ctime(&bp->ut_time);
- printf("%-*.*s %-*.*s %-*.*s %10.10s %5.5s ", NMAX, NMAX, bp->ut_name, LMAX, LMAX, bp->ut_line, HMAX, HMAX, bp->ut_host, ct, ct + 11);
- if (!T->logout)
- puts(" still logged in");
- else {
- if (T->logout < 0) {
- T->logout = -T->logout;
- printf("- %s", crmsg);
- }
- else
- printf("- %5.5s", ctime(&T->logout)+11);
- delta = T->logout - bp->ut_time;
- if (delta < SECDAY)
- printf(" (%5.5s)\n", asctime(gmtime(&delta))+11);
- else
- printf(" (%ld+%5.5s)\n", delta / SECDAY, asctime(gmtime(&delta))+11);
- }
- if (maxrec != -1 && !--maxrec)
- return;
- }
- T->logout = bp->ut_time;
- }
- }
- ct = ctime(&buf[0].ut_time);
- printf("\nwtmp begins %10.10s %5.5s \n", ct, ct + 11);
-}
-
-/*
- * want --
- * see if want this entry
- */
-static int
-want(bp, check)
- register struct utmp *bp;
- int check;
-{
- register 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 (!strncmp(step->name, bp->ut_host, HMAX))
- return(YES);
- break;
- case TTY_TYPE:
- if (!strncmp(step->name, bp->ut_line, LMAX))
- return(YES);
- break;
- case USER_TYPE:
- if (!strncmp(step->name, bp->ut_name, NMAX))
- return(YES);
- break;
- }
- return(NO);
-}
-
-/*
- * addarg --
- * add an entry to a linked list of arguments
- */
-static void
-addarg(type, arg)
- int type;
- char *arg;
-{
- register ARG *cur;
-
- if (!(cur = (ARG *)malloc((unsigned int)sizeof(ARG)))) {
- fputs("last: malloc failure.\n", stderr);
- exit(1);
- }
- cur->next = arglist;
- cur->type = type;
- cur->name = arg;
- arglist = cur;
-}
-
-/*
- * addtty --
- * add an entry to a linked list of ttys
- */
-TTY *
-addtty(ttyname)
- char *ttyname;
-{
- register TTY *cur;
-
- if (!(cur = (TTY *)malloc((unsigned int)sizeof(TTY)))) {
- fputs("last: malloc failure.\n", stderr);
- exit(1);
- }
- cur->next = ttylist;
- cur->logout = currentout;
- memcpy(cur->tty, ttyname, LMAX);
- 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(arg)
- char *arg;
-{
- static int first = 1;
- static char *hostdot,
- name[MAXHOSTNAMELEN];
- char *argdot;
-
- if (!(argdot = strchr(arg, '.')))
- return;
- if (first) {
- first = 0;
- if (gethostname(name, sizeof(name))) {
- perror("last: gethostname");
- exit(1);
- }
- hostdot = strchr(name, '.');
- }
- if (hostdot && !strcmp(hostdot, argdot))
- *argdot = '\0';
-}
-
-/*
- * ttyconv --
- * convert tty to correct name.
- */
-static char *
-ttyconv(arg)
- char *arg;
-{
- char *mval;
-
- /*
- * kludge -- we assume that all tty's end with
- * a two character suffix.
- */
- if (strlen(arg) == 2) {
- /* either 6 for "ttyxx" or 8 for "console" */
- if (!(mval = malloc((unsigned int)8))) {
- fputs("last: malloc failure.\n", stderr);
- exit(1);
- }
- if (!strcmp(arg, "co"))
- (void)strcpy(mval, "console");
- else {
- (void)strcpy(mval, "tty");
- (void)strcpy(mval + 3, arg);
- }
- return(mval);
- }
- if (!strncmp(arg, "/dev/", sizeof("/dev/") - 1))
- return(arg + 5);
- return(arg);
-}
-
-/*
- * onintr --
- * on interrupt, we inform the user how far we've gotten
- */
-void
-onintr(signo)
- int signo;
-{
- char *ct;
-
- ct = ctime(&buf[0].ut_time);
- printf("\ninterrupted %10.10s %5.5s \n", ct, ct + 11);
- if (signo == SIGINT)
- exit(1);
- (void)fflush(stdout); /* fix required for rsh */
-}
diff --git a/login-utils/login.1 b/login-utils/login.1
index 92a082c67..a2acbd9f7 100644
--- a/login-utils/login.1
+++ b/login-utils/login.1
@@ -243,8 +243,7 @@ the user to for example run the command: xterm -e /bin/login.
.PP
.IP o
A domain name suffix such as @.some.dom, meaning that the user may
-rlogin/telnet from any host whose domain name has the suffix
-.some.dom.
+rlogin/telnet from any host whose domain name has the suffix .some.dom.
.PP
.IP o
A range of IPv4 addresses, written @x.x.x.x/y.y.y.y where x.x.x.x is
@@ -303,9 +302,6 @@ are allowed to log in from anywhere as is standard behavior.
.BR shutdown (8)
.SH BUGS
-Linux, unlike other draconian operating systems, does not check
-quotas.
-
The undocumented BSD
.B \-r
option is not supported. This may be required by some
diff --git a/login-utils/login.c b/login-utils/login.c
index ebb0a22da..c742af75c 100644
--- a/login-utils/login.c
+++ b/login-utils/login.c
@@ -148,6 +148,14 @@
#define SLEEP_EXIT_TIMEOUT 5
+#ifdef __linux__
+#define DO_PS_FIDDLING
+#endif
+
+#ifdef DO_PS_FIDDLING
+#include "setproctitle.h"
+#endif
+
#if 0
/* from before we had a lastlog.h file in linux */
struct lastlog
@@ -260,9 +268,7 @@ consoletty(int fd)
int
-main(argc, argv)
- int argc;
- char **argv;
+main(int argc, char **argv)
{
extern int errno, optind;
extern char *optarg, **environ;
@@ -270,8 +276,8 @@ main(argc, argv)
register int ch;
register char *p;
int ask, fflag, hflag, pflag, cnt;
- int quietlog, passwd_req, ioctlval;
- char *domain, *salt, *ttyn, *pp;
+ int quietlog, passwd_req;
+ char *domain, *ttyn;
char tbuf[MAXPATHLEN + 2], tname[sizeof(_PATH_TTY) + 10];
char *ctime(), *ttyname(), *stypeof();
time_t time();
@@ -286,7 +292,12 @@ main(argc, argv)
pam_handle_t *pamh = NULL;
struct pam_conv conv = { misc_conv, NULL };
pid_t childPid;
- int childStatus;
+ void (*oldSigHandler) ();
+#else
+ char *salt, *pp;
+#endif
+#ifndef __linux__
+ int ioctlval;
#endif
signal(SIGALRM, timedout);
@@ -298,6 +309,9 @@ main(argc, argv)
#ifdef HAVE_QUOTA
quota(Q_SETUID, 0, 0, 0);
#endif
+#ifdef DO_PS_FIDDLING
+ initproctitle(argc, argv);
+#endif
/*
* -p is used by getty to tell login not to destroy the environment
@@ -313,6 +327,7 @@ main(argc, argv)
username = tty = hostname = NULL;
fflag = hflag = pflag = 0;
passwd_req = 1;
+
while ((ch = getopt(argc, argv, "fh:p")) != EOF)
switch (ch) {
case 'f':
@@ -353,8 +368,13 @@ main(argc, argv)
argc -= optind;
argv += optind;
if (*argv) {
- username = *argv;
+ char *p = *argv;
+ username = strdup(p);
ask = 0;
+ /* wipe name - some people mistype their password here */
+ /* (of course we are too late, but perhaps this helps a little ..) */
+ while(*p)
+ *p++ = ' ';
} else
ask = 1;
@@ -377,7 +397,7 @@ main(argc, argv)
*/
ioctlval = 0;
ioctl(0, FIOSNBIO, &ioctlval);
-#endif
+#endif /* ! __linux__ */
for (cnt = getdtablesize(); cnt > 2; cnt--)
close(cnt);
@@ -472,7 +492,7 @@ main(argc, argv)
(retcode == PAM_AUTHINFO_UNAVAIL))) {
pam_get_item(pamh, PAM_USER, (const void **) &username);
syslog(LOG_NOTICE,"FAILED LOGIN %d FROM %s FOR %s, %s",
- failcount, hostname,username,pam_strerror(pamh, retcode));
+ failcount, hostname, username, pam_strerror(pamh, retcode));
fprintf(stderr,"Login incorrect\n\n");
pam_set_item(pamh,PAM_USER,NULL);
retcode = pam_authenticate(pamh, 0);
@@ -520,8 +540,8 @@ main(argc, argv)
#else /* ! USE_PAM */
for (cnt = 0;; ask = 1) {
- ioctlval = 0;
# ifndef __linux__
+ ioctlval = 0;
ioctl(0, TIOCSETD, &ioctlval);
# endif
@@ -770,7 +790,7 @@ main(argc, argv)
utmp.ut_line[sizeof(utmp.ut_line)-1] = 0;
login(&utmp);
}
-#else
+#else /* __linux__ defined */
/* for linux, write entries in utmp and wtmp */
{
struct utmp ut;
@@ -781,8 +801,19 @@ main(argc, argv)
utmpname(_PATH_UTMP);
setutent();
- while ((utp = getutent())
- && !(utp->ut_pid == mypid)) /* nothing */;
+
+ /* Find mypid in utmp.
+login sometimes overwrites the runlevel entry in /var/run/utmp,
+confusing sysvinit. I added a test for the entry type, and the problem
+was gone. (In a runlevel entry, st_pid is not really a pid but some number
+calculated from the previous and current runlevel).
+Michael Riepe <michael@stud.uni-hannover.de>
+ */
+ while ((utp = getutent()))
+ if (utp->ut_pid == mypid
+ && utp->ut_type >= INIT_PROCESS
+ && utp->ut_type <= DEAD_PROCESS)
+ break;
if (utp) {
memcpy(&ut, utp, sizeof(ut));
@@ -813,7 +844,20 @@ main(argc, argv)
pututline(&ut);
endutent();
-
+
+#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1)
+ updwtmp(_PATH_WTMP, &ut);
+#else
+#if 0
+ /* The O_APPEND open() flag should be enough to guarantee
+ atomic writes at end of file. */
+ if((wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY)) >= 0) {
+ write(wtmp, (char *)&ut, sizeof(ut));
+ close(wtmp);
+ }
+#else
+ /* Probably all this locking below is just nonsense,
+ and the short version is OK as well. */
{
int lf;
if ((lf = open(_PATH_WTMPLOCK, O_CREAT|O_WRONLY, 0660)) >= 0) {
@@ -826,8 +870,10 @@ main(argc, argv)
close(lf);
}
}
- }
#endif
+#endif /* __GLIBC__ */
+ }
+#endif /* __linux__ */
dolastlog(quietlog);
@@ -903,7 +949,8 @@ main(argc, argv)
setenv("TERM", termenv, 1);
/* mailx will give a funny error msg if you forget this one */
- { char tmp[MAXPATHLEN];
+ {
+ char tmp[MAXPATHLEN];
/* avoid snprintf */
if (sizeof(_PATH_MAILDIR) + strlen(pwd->pw_name) + 1 < MAXPATHLEN) {
sprintf(tmp, "%s/%s", _PATH_MAILDIR, pwd->pw_name);
@@ -932,6 +979,10 @@ main(argc, argv)
}
}
#endif
+
+#ifdef DO_PS_FIDDLING
+ setproctitle("login", username);
+#endif
if (tty[sizeof("tty")-1] == 'S')
syslog(LOG_INFO, "DIALUP AT %s BY %s", tty, pwd->pw_name);
@@ -956,41 +1007,53 @@ main(argc, argv)
if (!quietlog) {
struct stat st;
+ char *mail;
motd();
- /* avoid snprintf */
- if (sizeof(_PATH_MAILDIR) + strlen(pwd->pw_name) + 1 < sizeof(tbuf)) {
- sprintf(tbuf, "%s/%s", _PATH_MAILDIR, pwd->pw_name);
- if (stat(tbuf, &st) == 0 && st.st_size != 0)
- printf("You have %smail.\n",
- (st.st_mtime > st.st_atime) ? "new " : "");
+ mail = getenv("MAIL");
+ if (mail && stat(mail, &st) == 0 && st.st_size != 0) {
+ printf("You have %smail.\n",
+ (st.st_mtime > st.st_atime) ? "new " : "");
}
}
signal(SIGALRM, SIG_DFL);
signal(SIGQUIT, SIG_DFL);
- signal(SIGINT, SIG_DFL);
signal(SIGTSTP, SIG_IGN);
signal(SIGHUP, SIG_DFL);
+
+#ifdef USE_PAM
+ /* We must fork before setuid() because we need to call
+ * pam_close_session() as root.
+ */
+ signal(SIGINT, SIG_IGN);
+ childPid = fork();
+ if (childPid < 0) {
+ /* error in fork() */
+ fprintf(stderr,"login: failure forking: %s", strerror(errno));
+ PAM_END;
+ exit(0);
+ } else if (childPid) {
+ /* parent - wait for child to finish, then cleanup session */
+ wait(NULL);
+ PAM_END;
+ exit(0);
+ }
+ /* child */
+#endif
+ signal(SIGINT, SIG_DFL);
/* discard permissions last so can't get killed and drop core */
if(setuid(pwd->pw_uid) < 0 && pwd->pw_uid) {
syslog(LOG_ALERT, "setuid() failed");
-#ifdef USE_PAM
- PAM_END;
-#endif
exit(1);
}
/* wait until here to change directory! */
if (chdir(pwd->pw_dir) < 0) {
printf("No directory %s!\n", pwd->pw_dir);
- if (chdir("/")) {
-#ifdef USE_PAM
- PAM_END;
-#endif
+ if (chdir("/"))
exit(0);
- }
pwd->pw_dir = "/";
printf("Logging in with home = \"/\".\n");
}
@@ -1023,15 +1086,6 @@ main(argc, argv)
childArgv[childArgc++] = NULL;
-#ifdef USE_PAM
- /* There was some junk with fork()/exec()/signal()/wait() here
- that was incorrect, and util-linux-2.7-11.src.rpm contains
- a patch that makes the fork entirely useless.
- If you introduce one again, please document in the source
- what its purpose is. - aeb */
- PAM_END;
-#endif /* USE_PAM */
-
execvp(childArgv[0], childArgv + 1);
if (!strcmp(childArgv[0], "/bin/sh"))
@@ -1070,7 +1124,7 @@ getloginname()
exit(0);
}
}
- if (p > nbuf)
+ if (p > nbuf) {
if (nbuf[0] == '-')
fprintf(stderr,
"login names may not start with '-'.\n");
@@ -1079,6 +1133,7 @@ getloginname()
username = nbuf;
break;
}
+ }
cnt2++;
if (cnt2 > 50) {
@@ -1190,7 +1245,7 @@ dolastlog(quiet)
int fd;
if ((fd = open(_PATH_LASTLOG, O_RDWR, 0)) >= 0) {
- lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), L_SET);
+ lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), SEEK_SET);
if (!quiet) {
if (read(fd, (char *)&ll, sizeof(ll)) == sizeof(ll) &&
ll.ll_time != 0) {
@@ -1204,7 +1259,7 @@ dolastlog(quiet)
printf("on %.*s\n",
(int)sizeof(ll.ll_line), ll.ll_line);
}
- lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), L_SET);
+ lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), SEEK_SET);
}
memset((char *)&ll, 0, sizeof(ll));
time(&ll.ll_time);
diff --git a/login-utils/passwd.1 b/login-utils/passwd.1
index db44aa8e9..b6a25a3f6 100644
--- a/login-utils/passwd.1
+++ b/login-utils/passwd.1
@@ -34,10 +34,8 @@ reasons to choose a non-conformant password.
The two argument form gives the
.IR user " the " password
-stated as the second argument. This may be useful when giving many
-users an initial generated password. But it can also be extremely
-dangerous. A simple script bug might change to root password to
-something unknown.
+stated as the second argument. Note that this password will
+be visible to people doing `ps' or so. Avoid this form.
Giving an empty string as the second argument erases the password for the
user, but only in combination with the
@@ -111,6 +109,3 @@ Peter Orbaek (poe@daimi.aau.dk).
.br
Martin Schulze (joey@infodrom.north.de) with extensive rewriting and
improving done.
-.br
-.SH MAINTAINER
-Nicolai Langfeldt (janl@math.uio.no)
diff --git a/login-utils/passwd.c b/login-utils/passwd.c
index 4ed1b74d7..0057a283b 100644
--- a/login-utils/passwd.c
+++ b/login-utils/passwd.c
@@ -3,17 +3,12 @@
*
* Initially written for Linux by Peter Orbaek <poe@daimi.aau.dk>
* Currently maintained at ftp://ftp.daimi.aau.dk/pub/linux/poe/
-
- Hacked by Alvaro Martinez Echevarria, alvaro@enano.etsit.upm.es,
- to allow peaceful coexistence with yp. Nov 94.
-
- Hacked to allow root to set passwd from command line.
- by Arpad Magossanyi (mag@tas.vein.hu)
-
- Hacked by Peter Breitenlohner, peb@mppmu.mpg.de,
- moved Alvaro's changes to setpwnam.c (so they get used
- by chsh and chfn as well). Oct 5, 96.
-
+ *
+ * Hacked by Alvaro Martinez Echevarria, alvaro@enano.etsit.upm.es,
+ * to allow peaceful coexistence with yp. Nov 94.
+ *
+ * Hacked to allow root to set passwd from command line.
+ * by Arpad Magossanyi (mag@tas.vein.hu)
*/
/*
@@ -26,7 +21,7 @@
or running a background job that just collects all command lines)
* work and second I wanted simplicity checks to be done for
- * root, too. Only root can turn this of using the -f
+ * root, too. Only root can turn this off using the -f
* switch. Okay, I started with this to support -V version
* information, but one thing comes to the next. *sigh*
* In a later step perhaps we'll be able to support shadow
diff --git a/login-utils/shutdown.8 b/login-utils/shutdown.8
index 443acc2af..961579bdc 100644
--- a/login-utils/shutdown.8
+++ b/login-utils/shutdown.8
@@ -1,6 +1,8 @@
.\" Copyright 1992 Rickard E. Faith (faith@cs.unc.edu)
.\" May be distributed under the GNU General Public License
-.TH SHUTDOWN 8 "20 November 1993" "Linux 1.2" "Linux Programmer's Manual"
+.\"
+.\"
+.TH SHUTDOWN 8 "24 July 1998" "Linux 2.0" "Linux Programmer's Manual"
.SH NAME
shutdown \- close down the system
.SH SYNOPSIS
@@ -98,7 +100,29 @@ detects (and deletes).
.I /etc/singleboot
.I /etc/nologin
.I /var/log/wtmp
+.I /etc/shutdown.conf
.fi
+.SH CONFIG
+The configuration file \fI/etc/shutdown.conf\fP is used to determine
+the action to take when halting the machine. The currently supported
+file format is extremely primitive. The first line must contain two
+strings separated by whitespace. The first string must be
+\fBHALT_ACTION\fP and the second specifies the action you wish to take
+on halt. The options allowed are:
+.TP
+.B halt
+This will simply halt the system. This is the default behaviour.
+Note also that this is the fallback if another option fails.
+.TP
+.B power_off
+This will use the kernel power shutdown facility. This is usually only
+available on machines with Advanced Power Management (APM).
+.TP
+.I programname
+This specifies a command to run to shut down the power. The first
+character must be a "/". Bear in mind that this command will be run
+with only the root filesystem mounted (and it will be read-only), and
+no daemons running.
.SH "SEE ALSO"
.BR umount (8),
.BR login (1),
@@ -112,6 +136,6 @@ users are notified of shutdown only once or twice, instead of many times,
and at shorter and shorter intervals as "apocalypse approaches."
Some would construe this as a feature.
.SH AUTHOR
-Peter Orbaek (poe@daimi.aau.dk)
-.br
-Modified by jrs@world.std.com
+This page documents the version of
+.B shutdown
+originally written by Peter Orbaek (poe@daimi.aau.dk).
diff --git a/login-utils/shutdown.c b/login-utils/shutdown.c
index a63cbd6e9..8ba13b647 100644
--- a/login-utils/shutdown.c
+++ b/login-utils/shutdown.c
@@ -1,6 +1,6 @@
/* shutdown.c - shutdown a Linux system
* Initially written by poe@daimi.aau.dk
- * Currently maintained at ftp://ftp.daimi.aau.dk/pub/linux/poe/
+ * Currently maintained at ftp://ftp.daimi.aau.dk/pub/Software/Linux/
*/
/*
@@ -24,6 +24,9 @@
* Various changes and additions to resemble SunOS 4 shutdown/reboot/halt(8)
* more closely by Scott Telford (s.telford@ed.ac.uk) 93/05/18.
* (I butchered Scotts patches somewhat. - poe)
+ *
+ * Changes by Richard Gooch <rgooch@atnf.csiro.au> (butchered by aeb)
+ * introducing shutdown.conf.
*/
#include <stdio.h>
@@ -35,6 +38,7 @@
#include <string.h>
#include <ctype.h>
#include <signal.h>
+#include <errno.h>
#include <sys/param.h>
#include <termios.h>
#include <mntent.h>
@@ -42,11 +46,12 @@
#include <sys/wait.h>
#include <syslog.h>
#include <sys/resource.h>
+#include "linux_reboot.h"
#include "pathnames.h"
-void usage(), int_handler(), write_user(struct utmp *);
-void wall(), write_wtmp(), unmount_disks(), unmount_disks_ourselves();
-void swap_off();
+static void usage(), int_handler(), write_user(struct utmp *);
+static void wall(), write_wtmp(), unmount_disks(), unmount_disks_ourselves();
+static void swap_off(), do_halt(char *);
char *prog; /* name of the program */
int opt_reboot; /* true if -r option or reboot command */
@@ -57,10 +62,15 @@ char message[90]; /* reason for shutdown if any... */
int opt_single = 0; /* true is we want to boot singleuser */
char *whom; /* who is shutting the system down */
int opt_msgset = 0; /* message set on command line */
+ /* change 1 to 0 if no file is to be used by default */
+int opt_use_config_file = 1; /* read _PATH_SHUTDOWN_CONF */
+char halt_action[256]; /* to find out what to do upon halt */
/* #define DEBUGGING */
#define WR(s) write(fd, s, strlen(s))
+#define ERRSTRING sys_errlist[errno]
+
void
usage()
@@ -70,19 +80,31 @@ usage()
exit(1);
}
+void
+my_puts(char *s)
+{
+ /* Use a fresh stdout after forking */
+ freopen(_PATH_CONSOLE, "w", stdout);
+ puts(s);
+ fflush(stdout);
+}
+
void
int_handler()
{
unlink(_PATH_NOLOGIN);
signal(SIGINT, SIG_DFL);
- puts("Shutdown process aborted\n");
+ my_puts("Shutdown process aborted");
exit(1);
}
int
-main(argc, argv)
- int argc;
- char *argv[];
+iswhitespace(int a) {
+ return (a == ' ' || a == '\t');
+}
+
+int
+main(int argc, char *argv[])
{
int c,i;
int fd;
@@ -90,7 +112,8 @@ main(argc, argv)
#ifndef DEBUGGING
if(geteuid()) {
- fprintf(stderr, "%s: Only root can shut a system down.\n", argv[0]);
+ fprintf(stderr, "%s: Only root can shut a system down.\n",
+ argv[0]);
exit(1);
}
#endif
@@ -98,7 +121,10 @@ main(argc, argv)
if(*argv[0] == '-') argv[0]++; /* allow shutdown as login shell */
prog = argv[0];
if((ptr = strrchr(argv[0], '/'))) prog = ++ptr;
-
+
+ /* All names (halt, reboot, fasthalt, fastboot, shutdown)
+ refer to the same program with the same options,
+ only the defaults differ. */
if(!strcmp("halt", prog)) {
opt_reboot = 0;
opt_quiet = 1;
@@ -114,78 +140,105 @@ main(argc, argv)
opt_quiet = 1;
opt_fast = 0;
timeout = 0;
- if(argc > 1 && !strcmp(argv[1], "-s")) opt_single = 1;
} else if(!strcmp("fastboot", prog)) {
opt_reboot = 1;
opt_quiet = 1;
opt_fast = 1;
timeout = 0;
- if(argc > 1 && !strcmp(argv[1], "-s")) opt_single = 1;
} else {
/* defaults */
opt_reboot = 0;
opt_quiet = 0;
opt_fast = 0;
timeout = 2*60;
+ }
- c = 0;
- while(++c < argc) {
- if(argv[c][0] == '-') {
- for(i = 1; argv[c][i]; i++) {
+ c = 0;
+ while(++c < argc) {
+ if(argv[c][0] == '-') {
+ for(i = 1; argv[c][i]; i++) {
switch(argv[c][i]) {
- case 'h':
- opt_reboot = 0;
- break;
- case 'r':
- opt_reboot = 1;
- break;
- case 'f':
- opt_fast = 1;
- break;
- case 'q':
- opt_quiet = 1;
- break;
- case 's':
- opt_single = 1;
- break;
+ case 'C':
+ opt_use_config_file = 1;
+ break;
+ case 'h':
+ opt_reboot = 0;
+ break;
+ case 'r':
+ opt_reboot = 1;
+ break;
+ case 'f':
+ opt_fast = 1;
+ break;
+ case 'q':
+ opt_quiet = 1;
+ break;
+ case 's':
+ opt_single = 1;
+ break;
- default:
- usage();
+ default:
+ usage();
}
- }
- } else if(!strcmp("now", argv[c])) {
- timeout = 0;
- } else if(argv[c][0] == '+') {
- timeout = 60 * atoi(&argv[c][1]);
- } else if (isdigit(argv[c][0])) {
- char *colon;
- int hour = 0;
- int minute = 0;
- time_t tics;
- struct tm *tt;
- int now, then;
+ }
+ } else if(!strcmp("now", argv[c])) {
+ timeout = 0;
+ } else if(argv[c][0] == '+') {
+ timeout = 60 * atoi(&argv[c][1]);
+ } else if (isdigit(argv[c][0])) {
+ char *colon;
+ int hour = 0;
+ int minute = 0;
+ time_t tics;
+ struct tm *tt;
+ int now, then;
- if((colon = strchr(argv[c], ':'))) {
- *colon = '\0';
- hour = atoi(argv[c]);
- minute = atoi(++colon);
- } else usage();
+ if((colon = strchr(argv[c], ':'))) {
+ *colon = '\0';
+ hour = atoi(argv[c]);
+ minute = atoi(++colon);
+ } else usage();
- (void) time(&tics);
- tt = localtime(&tics);
+ (void) time(&tics);
+ tt = localtime(&tics);
- now = 3600 * tt->tm_hour + 60 * tt->tm_min;
- then = 3600 * hour + 60 * minute;
- timeout = then - now;
- if(timeout < 0) {
- fprintf(stderr, "That must be tomorrow, can't you wait till then?\n");
- exit(1);
- }
- } else {
- strncpy(message, argv[c], sizeof(message));
- message[sizeof(message)-1] = '\0';
- opt_msgset = 1;
+ now = 3600 * tt->tm_hour + 60 * tt->tm_min;
+ then = 3600 * hour + 60 * minute;
+ timeout = then - now;
+ if(timeout < 0) {
+ fprintf(stderr, "That must be tomorrow, "
+ "can't you wait till then?\n");
+ exit(1);
+ }
+ } else {
+ strncpy(message, argv[c], sizeof(message));
+ message[sizeof(message)-1] = '\0';
+ opt_msgset = 1;
+ }
+ }
+
+ halt_action[0] = 0;
+
+ /* No doubt we shall want to extend this some day
+ and register a series of commands to be executed
+ at various points during the shutdown sequence,
+ and to define the number of milliseconds to sleep, etc. */
+ if (opt_use_config_file) {
+ char line[256], *p;
+ FILE *fp;
+
+ /* Read and parse the config file */
+ halt_action[0] = '\0';
+ if ((fp = fopen (_PATH_SHUTDOWN_CONF, "r")) != NULL) {
+ if (fgets (line, sizeof(line), fp) != NULL &&
+ strncasecmp (line, "HALT_ACTION", 11) == 0 &&
+ iswhitespace(line[11])) {
+ p = line+11;
+ while(iswhitespace(*p))
+ p++;
+ strcpy(halt_action, p);
}
+ fclose (fp);
}
}
@@ -212,6 +265,7 @@ main(argc, argv)
/* so much for option-processing, now begin termination... */
if(!(whom = getlogin())) whom = "ghost";
+ if(strlen(whom) > 40) whom[40] = 0; /* see write_user() */
setpriority(PRIO_PROCESS, 0, PRIO_MIN);
signal(SIGINT, int_handler);
@@ -261,7 +315,8 @@ main(argc, argv)
kill(1, SIGTSTP); /* tell init not to spawn more getty's */
write_wtmp();
if(opt_single)
- close(open(_PATH_SINGLE, O_CREAT|O_WRONLY, 0644));
+ if((fd = open(_PATH_SINGLE, O_CREAT|O_WRONLY, 0644)) >= 0)
+ close(fd);
sync();
@@ -272,7 +327,7 @@ main(argc, argv)
#ifndef DEBUGGING
/* a gentle kill of all other processes except init */
kill(-1, SIGTERM);
- sleep(2);
+ sleep(2); /* default 2, some people need 5 */
/* now use brute force... */
kill(-1, SIGKILL);
@@ -292,14 +347,14 @@ main(argc, argv)
sleep(1);
if(opt_reboot) {
- reboot(0xfee1dead, 672274793, 0x1234567);
+ my_reboot(LINUX_REBOOT_CMD_RESTART); /* RB_AUTOBOOT */
+ my_puts("\nWhy am I still alive after reboot?");
} else {
- freopen(_PATH_CONSOLE, "w", stdout);
- printf("\nNow you can turn off the power...\n");
- fflush(stdout);
+ my_puts("\nNow you can turn off the power...");
+
/* allow C-A-D now, faith@cs.unc.edu, re-fixed 8-Jul-96 */
- reboot(0xfee1dead, 672274793, 0x89abcdef);
- reboot(0xfee1dead, 672274793, 0xcdef0123);
+ my_reboot(LINUX_REBOOT_CMD_CAD_ON); /* RB_ENABLE_CAD */
+ do_halt(halt_action);
}
/* NOTREACHED */
exit(0); /* to quiet gcc */
@@ -308,6 +363,31 @@ main(argc, argv)
/*** end of main() ***/
void
+do_halt(char *action) {
+ if (strcasecmp (action, "power_off") == 0) {
+ printf("Calling kernel power-off facility...\n");
+ fflush(stdout);
+ my_reboot(LINUX_REBOOT_CMD_POWER_OFF);
+ printf("Error powering off\t%s\n", ERRSTRING);
+ fflush(stdout);
+ sleep (2);
+ } else
+
+ /* This should be improved; e.g. Mike Jagdis wants "/sbin/mdstop -a" */
+ /* Maybe we should also fork and wait */
+ if (action[0] == '/') {
+ printf("Executing the program \"%s\" ...\n", action);
+ fflush(stdout);
+ execl(action, action, NULL);
+ printf("Error executing\t%s\n", ERRSTRING);
+ fflush(stdout);
+ sleep (2);
+ }
+
+ my_reboot(LINUX_REBOOT_CMD_HALT); /* RB_HALT_SYSTEM */
+}
+
+void
write_user(struct utmp *ut)
{
int fd;
@@ -319,7 +399,7 @@ write_user(struct utmp *ut)
(void) strncat(term, ut->ut_line, sizeof(ut->ut_line));
/* try not to get stuck on a mangled ut_line entry... */
- if((fd = open(term, O_RDWR|O_NONBLOCK)) < 0)
+ if((fd = open(term, O_WRONLY|O_NONBLOCK)) < 0)
return;
sprintf(msg, "\007\r\nURGENT: broadcast message from %s:\r\n", whom);
@@ -393,7 +473,7 @@ swap_off()
sync();
if ((pid = fork()) < 0) {
- printf("Cannot fork for swapoff. Shrug!\n");
+ my_puts("Cannot fork for swapoff. Shrug!");
return;
}
if (!pid) {
@@ -401,7 +481,8 @@ swap_off()
execl("/etc/swapoff", SWAPOFF_ARGS, NULL);
execl("/bin/swapoff", SWAPOFF_ARGS, NULL);
execlp("swapoff", SWAPOFF_ARGS, NULL);
- puts("Cannot exec swapoff, hoping umount will do the trick.");
+ my_puts("Cannot exec swapoff, "
+ "hoping umount will do the trick.");
exit(0);
}
while ((result = wait(&status)) != -1 && result != pid)
@@ -419,20 +500,20 @@ unmount_disks()
sync();
if ((pid = fork()) < 0) {
- printf("Cannot fork for umount, trying manually.\n");
+ my_puts("Cannot fork for umount, trying manually.");
unmount_disks_ourselves();
return;
}
if (!pid) {
execl(_PATH_UMOUNT, UMOUNT_ARGS, NULL);
- printf("Cannot exec %s, trying umount.\n", _PATH_UMOUNT);
+ my_puts("Cannot exec " _PATH_UMOUNT ", trying umount.");
execlp("umount", UMOUNT_ARGS, NULL);
- puts("Cannot exec umount, giving up on umount.");
+ my_puts("Cannot exec umount, giving up on umount.");
exit(0);
}
while ((result = wait(&status)) != -1 && result != pid)
;
- puts("Unmounting any remaining filesystems...");
+ my_puts("Unmounting any remaining filesystems...");
unmount_disks_ourselves();
}
@@ -450,7 +531,7 @@ unmount_disks_ourselves()
sync();
if (!(mtab = setmntent(_PATH_MTAB, "r"))) {
- printf("shutdown: Cannot open %s.\n", _PATH_MTAB);
+ my_puts("shutdown: Cannot open " _PATH_MTAB ".");
return;
}
n = 0;
diff --git a/login-utils/simpleinit.c b/login-utils/simpleinit.c
index 14d8cfad2..1664404c3 100644
--- a/login-utils/simpleinit.c
+++ b/login-utils/simpleinit.c
@@ -16,10 +16,11 @@
#include <sys/sysmacros.h>
#include <utmp.h>
#ifdef SHADOW_PWD
-#include <shadow.h>
+# include <shadow.h>
#endif
-
+#include "my_crypt.h"
#include "pathnames.h"
+#include "linux_reboot.h"
#define CMDSIZ 150 /* max size of a line in inittab */
#define NUMCMD 30 /* max number of lines in inittab */
@@ -411,13 +412,14 @@ void int_handler()
sync();
sync();
- if((pid = fork()) == 0) {
- /* reboot properly... */
+ pid = fork();
+ if (pid > 0)
+ return;
+ if (pid == 0) /* reboot properly... */
execl(_PATH_REBOOT, _PATH_REBOOT, (char *)0);
- reboot(0xfee1dead, 672274793, 0x1234567);
- } else if(pid < 0)
- /* fork failed, try the hard way... */
- reboot(0xfee1dead, 672274793, 0x1234567);
+
+ /* fork or exec failed, try the hard way... */
+ my_reboot(LINUX_REBOOT_CMD_RESTART);
}
void set_tz()
diff --git a/login-utils/vipw.c b/login-utils/vipw.c
index a5763b105..50270a6e3 100644
--- a/login-utils/vipw.c
+++ b/login-utils/vipw.c
@@ -190,15 +190,14 @@ pw_unlock()
void
-pw_edit(notsetuid)
- int notsetuid;
+pw_edit(int notsetuid)
{
int pstat;
pid_t pid;
char *p, *editor;
if (!(editor = getenv("EDITOR")))
- editor = _PATH_VI;
+ editor = strdup(_PATH_VI); /* adia@egnatia.ee.auth.gr */
if ((p = strrchr(strtok(editor," \t"), '/')) != NULL)
++p;
else