summaryrefslogtreecommitdiff
path: root/login-utils
diff options
context:
space:
mode:
authorLaMont Jones <lamont@debian.org>2010-12-29 09:33:45 -0700
committerLaMont Jones <lamont@debian.org>2010-12-29 09:33:45 -0700
commit4f9e177060fb5ad6e574598aefdf2d5f50a8b54f (patch)
tree840ca668a45e389792ccebaa1c414211c59ff620 /login-utils
parent0d32820f872a43ef8c3021dc9b9741f2b8228b40 (diff)
parent6c6f2af9e3949197cf7a70255895a2f4451f2319 (diff)
downloadutil-linux-old-4f9e177060fb5ad6e574598aefdf2d5f50a8b54f.tar.gz
Merge remote branch 'origin/master'
Conflicts: login-utils/Makefile.am mount/lomount.c text-utils/od.1
Diffstat (limited to 'login-utils')
-rw-r--r--login-utils/.gitignore4
-rw-r--r--login-utils/Makefile.am36
-rw-r--r--login-utils/agetty.84
-rw-r--r--login-utils/agetty.c69
-rw-r--r--login-utils/checktty.c12
-rw-r--r--login-utils/chfn.14
-rw-r--r--login-utils/chfn.c129
-rw-r--r--login-utils/chsh.14
-rw-r--r--login-utils/chsh.c154
-rw-r--r--login-utils/fastboot.81
-rw-r--r--login-utils/fasthalt.81
-rw-r--r--login-utils/halt.81
-rw-r--r--login-utils/initctl.8110
-rw-r--r--login-utils/initctl.c217
-rw-r--r--login-utils/last.14
-rw-r--r--login-utils/last.c58
-rw-r--r--login-utils/login.14
-rw-r--r--login-utils/login.c137
-rw-r--r--login-utils/mesg.14
-rw-r--r--login-utils/mesg.c52
-rw-r--r--login-utils/newgrp.14
-rw-r--r--login-utils/newgrp.c47
-rw-r--r--login-utils/reboot.81
-rw-r--r--login-utils/shutdown.8169
-rw-r--r--login-utils/shutdown.c754
-rw-r--r--login-utils/simpleinit.8180
-rw-r--r--login-utils/simpleinit.c1246
-rw-r--r--login-utils/simpleinit.h28
-rw-r--r--login-utils/vipw.84
-rw-r--r--login-utils/vipw.c50
-rw-r--r--login-utils/wall.14
-rw-r--r--login-utils/wall.c90
32 files changed, 382 insertions, 3200 deletions
diff --git a/login-utils/.gitignore b/login-utils/.gitignore
index 8c771830..816d1139 100644
--- a/login-utils/.gitignore
+++ b/login-utils/.gitignore
@@ -7,7 +7,5 @@ chsh
login
newgrp
vipw
-initctl
last
-shutdown
-simpleinit
+mesg
diff --git a/login-utils/Makefile.am b/login-utils/Makefile.am
index a6c50922..c490999d 100644
--- a/login-utils/Makefile.am
+++ b/login-utils/Makefile.am
@@ -11,24 +11,12 @@ EXTRA_DIST = README.getty README.modems-with-agetty README.poeigl
if BUILD_AGETTY
sbin_PROGRAMS += agetty
dist_man_MANS += agetty.8
-agetty_LDADD = -lutil
+agetty_SOURCES = agetty.c
+if !HAVE_LANGINFO
+agetty_SOURCES += $(top_srcdir)/lib/langinfo.c
endif
-
-if BUILD_INIT
-
-sbin_PROGRAMS += simpleinit shutdown initctl
-dist_man_MANS += fastboot.8 fasthalt.8 halt.8 reboot.8 simpleinit.8 shutdown.8 \
- initctl.8
-
-simpleinit_SOURCES = simpleinit.c my_crypt.h simpleinit.h
-initctl_SOURCES = initctl.c simpleinit.h
-
-if NEED_LIBCRYPT
-simpleinit_LDADD = -lcrypt
endif
-endif # BUILD_INIT
-
if BUILD_LAST
usrbin_exec_PROGRAMS += last
dist_man_MANS += last.1
@@ -115,24 +103,6 @@ endif
endif
endif
-if BUILD_INIT
-
-install-exec-hook::
- cd $(DESTDIR)$(sbindir) && ln -sf shutdown reboot
- cd $(DESTDIR)$(sbindir) && ln -sf shutdown fastboot
- cd $(DESTDIR)$(sbindir) && ln -sf shutdown halt
- cd $(DESTDIR)$(sbindir) && ln -sf shutdown fasthalt
- cd $(DESTDIR)$(sbindir) && ln -sf initctl need
- cd $(DESTDIR)$(sbindir) && ln -sf initctl display-services
- cd $(DESTDIR)$(sbindir) && ln -sf initctl provide
-
-install-data-hook:
- cd $(DESTDIR)$(mandir)/man8 && ln -sf initctl.8 need.8
- cd $(DESTDIR)$(mandir)/man8 && ln -sf initctl.8 display-services.8
- cd $(DESTDIR)$(mandir)/man8 && ln -sf initctl.8 provide.8
-
-endif
-
noinst_PROGRAMS = checktty_test islocal_test
checktty_test_SOURCES = checktty.c login.h
checktty_test_CPPFLAGS = -DMAIN_TEST_CHECKTTY $(AM_CPPFLAGS)
diff --git a/login-utils/agetty.8 b/login-utils/agetty.8
index 084086fd..a7f3bd05 100644
--- a/login-utils/agetty.8
+++ b/login-utils/agetty.8
@@ -303,5 +303,5 @@ Eric Rasmussen <ear@usfirst.org>
Added \-f option to display custom login messages on different terminals.
.SH AVAILABILITY
-The agetty command is part of the util-linux-ng package and is available from
-ftp://ftp.kernel.org/pub/linux/utils/util-linux-ng/.
+The agetty command is part of the util-linux package and is available from
+ftp://ftp.kernel.org/pub/linux/utils/util-linux/.
diff --git a/login-utils/agetty.c b/login-utils/agetty.c
index 3d544fb9..e66b8a53 100644
--- a/login-utils/agetty.c
+++ b/login-utils/agetty.c
@@ -32,7 +32,7 @@
#include <sys/socket.h>
#include <netdb.h>
-#include "xstrncpy.h"
+#include "strutils.h"
#include "nls.h"
#include "pathnames.h"
@@ -364,7 +364,6 @@ main(argc, argv)
(void) execl(options.login, options.login, "--", logname, NULL);
error(_("%s: can't exec %s: %m"), options.tty, options.login);
- exit(0); /* quiet GCC */
}
/* parse-args - parse command-line arguments */
@@ -714,6 +713,13 @@ termio_init(tp, op)
struct termios *tp;
struct options *op;
{
+ speed_t ispeed, ospeed;
+
+ if (op->flags & F_KEEPSPEED) {
+ ispeed = cfgetispeed(tp); /* save the original setting */
+ ospeed = cfgetospeed(tp);
+ } else
+ ospeed = ispeed = op->speeds[FIRST_SPEED];
/*
* Initial termios settings: 8-bit characters, raw-mode, blocking i/o.
@@ -724,18 +730,21 @@ termio_init(tp, op)
/* flush input and output queues, important for modems! */
(void) tcflush(0, TCIOFLUSH);
+ tp->c_iflag = tp->c_lflag = tp->c_oflag = 0;
+
if (!(op->flags & F_KEEPCFLAGS))
tp->c_cflag = CS8 | HUPCL | CREAD | (tp->c_cflag & CLOCAL);
- if (!(op->flags & F_KEEPSPEED)) {
- cfsetispeed(tp, op->speeds[FIRST_SPEED]);
- cfsetospeed(tp, op->speeds[FIRST_SPEED]);
- }
+ /* Note that the speed is stored in the c_cflag termios field, so we have
+ * set the speed always when the cflag se reseted.
+ */
+ cfsetispeed(tp, ispeed);
+ cfsetospeed(tp, ospeed);
+
if (op->flags & F_LOCAL) {
tp->c_cflag |= CLOCAL;
}
- tp->c_iflag = tp->c_lflag = tp->c_oflag = 0;
#ifdef HAVE_STRUCT_TERMIOS_C_LINE
tp->c_line = 0;
#endif
@@ -911,12 +920,6 @@ do_prompt(op, tp)
case 'd':
case 't':
{
- /* TODO: use nl_langinfo() */
- char *weekday[] = { "Sun", "Mon", "Tue", "Wed", "Thu",
- "Fri", "Sat" };
- char *month[] = { "Jan", "Feb", "Mar", "Apr", "May",
- "Jun", "Jul", "Aug", "Sep", "Oct",
- "Nov", "Dec" };
time_t now;
struct tm *tm;
@@ -925,14 +928,14 @@ do_prompt(op, tp)
if (c == 'd')
(void) printf ("%s %s %d %d",
- weekday[tm->tm_wday], month[tm->tm_mon],
- tm->tm_mday,
+ nl_langinfo(ABDAY_1 + tm->tm_wday),
+ nl_langinfo(ABMON_1 + tm->tm_mon),
+ tm->tm_mday,
tm->tm_year < 70 ? tm->tm_year + 2000 :
tm->tm_year + 1900);
else
(void) printf ("%02d:%02d:%02d",
tm->tm_hour, tm->tm_min, tm->tm_sec);
-
break;
}
@@ -995,9 +998,18 @@ next_speed(tp, op)
struct termios *tp;
struct options *op;
{
- static int baud_index = FIRST_SPEED;/* current speed index */
+ static int baud_index = -1;
+
+ if (baud_index == -1)
+ /*
+ * if the F_KEEPSPEED flags is set then the FIRST_SPEED is not
+ * tested yet (see termio_init()).
+ */
+ baud_index = (op->flags & F_KEEPSPEED) ? FIRST_SPEED :
+ 1 % op->numspeed;
+ else
+ baud_index = (baud_index + 1) % op->numspeed;
- baud_index = (baud_index + 1) % op->numspeed;
cfsetispeed(tp, op->speeds[baud_index]);
cfsetospeed(tp, op->speeds[baud_index]);
(void) tcsetattr(0, TCSANOW, tp);
@@ -1048,13 +1060,13 @@ char *get_logname(op, cp, tp)
if (read(0, &c, 1) < 1) {
if (errno == EINTR || errno == EIO)
- exit(0);
+ exit(EXIT_SUCCESS);
error(_("%s: read: %m"), op->tty);
}
/* Do BREAK handling elsewhere. */
if ((c == 0) && op->numspeed > 1)
- return (0);
+ return EXIT_SUCCESS;
/* Do parity bit handling. */
if (op->eightbits) {
@@ -1091,7 +1103,7 @@ char *get_logname(op, cp, tp)
}
break;
case CTL('D'):
- exit(0);
+ exit(EXIT_SUCCESS);
default:
if (!isascii(ascval) || !isprint(ascval)) {
/* ignore garbage characters */ ;
@@ -1111,7 +1123,7 @@ char *get_logname(op, cp, tp)
if (isupper(*bp))
*bp = tolower(*bp); /* map name to lower case */
}
- return (logname);
+ return logname;
}
/* termio_final - set the final tty mode bits */
@@ -1199,11 +1211,11 @@ caps_lock(s)
for (capslock = 0; *s; s++) {
if (islower(*s))
- return (0);
+ return EXIT_SUCCESS;
if (capslock == 0)
capslock = isupper(*s);
}
- return (capslock);
+ return capslock;
}
/* bcode - convert speed string to speed code; return 0 on failure */
@@ -1216,17 +1228,16 @@ bcode(s)
for (sp = speedtab; sp->speed; sp++)
if (sp->speed == speed)
- return (sp->code);
- return (0);
+ return sp->code;
+ return 0;
}
/* usage - explain */
-void
-usage()
+void __attribute__((__noreturn__)) usage(void)
{
fprintf(stderr, _("Usage: %s [-8hiLmsUw] [-l login_program] [-t timeout] [-I initstring] [-H login_host] baud_rate,... line [termtype]\nor\t[-hiLmw] [-l login_program] [-t timeout] [-I initstring] [-H login_host] line baud_rate,... [termtype]\n"), progname);
- exit(1);
+ exit(EXIT_FAILURE);
}
/* error - report errors to console or syslog; only understands %s and %m */
diff --git a/login-utils/checktty.c b/login-utils/checktty.c
index c28ee833..0d1ec0ef 100644
--- a/login-utils/checktty.c
+++ b/login-utils/checktty.c
@@ -31,7 +31,7 @@
#include "pathnames.h"
#include "login.h"
-#include "xstrncpy.h"
+#include "strutils.h"
#ifndef TTY_MAJOR
#define TTY_MAJOR 4
@@ -321,13 +321,13 @@ main(int argc, char **argv)
if (getaddrinfo(item->ip, NULL, &hints, &info)==0 && info) {
if (info->ai_family == AF_INET) {
struct sockaddr_in *sa =
- (struct sockaddr_in *) info->ai_addr;
+ (struct sockaddr_in *) info->ai_addr;
memcpy(hostaddress, &(sa->sin_addr),
sizeof(sa->sin_addr));
}
else if (info->ai_family == AF_INET6) {
struct sockaddr_in6 *sa =
- (struct sockaddr_in6 *) info->ai_addr;
+ (struct sockaddr_in6 *) info->ai_addr;
memcpy(hostaddress, &(sa->sin6_addr),
sizeof(sa->sin6_addr));
}
@@ -340,7 +340,7 @@ main(int argc, char **argv)
printf("getaddrinfo() failed\n");
}
- return 0;
+ return EXIT_SUCCESS;
}
#endif /* MAIN_TEST_CHECKTTY */
@@ -553,7 +553,7 @@ checktty(const char *user, const char *tty, struct passwd *pwd)
/* there was a default rule, but user didn't match, reject! */
printf(_("Login on %s from %s denied by default.\n"), tty, hostname);
badlogin(user);
- sleepexit(1);
+ sleepexit(EXIT_FAILURE);
}
if (found_match) {
@@ -564,7 +564,7 @@ checktty(const char *user, const char *tty, struct passwd *pwd)
printf(_("Login on %s from %s denied.\n"), tty, hostname);
badlogin(user);
- sleepexit(1);
+ sleepexit(EXIT_FAILURE);
}
/* users not matched in /etc/usertty are by default allowed access
diff --git a/login-utils/chfn.1 b/login-utils/chfn.1
index b63ce683..b27bec41 100644
--- a/login-utils/chfn.1
+++ b/login-utils/chfn.1
@@ -78,5 +78,5 @@ Print version information and exit.
.SH AUTHOR
Salvatore Valente <svalente@mit.edu>
.SH AVAILABILITY
-The chfn command is part of the util-linux-ng package and is available from
-ftp://ftp.kernel.org/pub/linux/utils/util-linux-ng/.
+The chfn command is part of the util-linux package and is available from
+ftp://ftp.kernel.org/pub/linux/utils/util-linux/.
diff --git a/login-utils/chfn.c b/login-utils/chfn.c
index 691c4f6f..2e0c82b1 100644
--- a/login-utils/chfn.c
+++ b/login-utils/chfn.c
@@ -18,7 +18,6 @@
*
* 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL>
* - added Native Language Support
- *
*
*/
@@ -31,14 +30,17 @@
#include <unistd.h>
#include <pwd.h>
#include <errno.h>
+#include <err.h>
#include <ctype.h>
#include <getopt.h>
+
#include "my_crypt.h"
#include "islocal.h"
#include "setpwnam.h"
-#include "xstrncpy.h"
+#include "strutils.h"
#include "nls.h"
#include "env.h"
+#include "xalloc.h"
#ifdef HAVE_LIBSELINUX
#include <selinux/selinux.h>
@@ -55,7 +57,7 @@
if ((_rc) != PAM_SUCCESS) { \
fprintf(stderr, "\n%s\n", pam_strerror((_ph), (_rc))); \
pam_end((_ph), (_rc)); \
- exit(1); \
+ exit(EXIT_FAILURE); \
} \
} while(0)
@@ -80,20 +82,25 @@ struct finfo {
};
static boolean parse_argv (int argc, char *argv[], struct finfo *pinfo);
-static void usage (FILE *fp);
static void parse_passwd (struct passwd *pw, struct finfo *pinfo);
static void ask_info (struct finfo *oldfp, struct finfo *newfp);
static char *prompt (char *question, char *def_val);
static int check_gecos_string (char *msg, char *gecos);
static boolean set_changed_data (struct finfo *oldfp, struct finfo *newfp);
static int save_new_data (struct finfo *pinfo);
-static void *xmalloc (int bytes);
-
-#define memzero(ptr, size) memset((char *) ptr, 0, size)
/* we do not accept gecos field sizes longer than MAX_FIELD_SIZE */
#define MAX_FIELD_SIZE 256
+static void __attribute__((__noreturn__)) usage(FILE *fp)
+{
+ fprintf (fp, _("Usage: %s [ -f full-name ] [ -o office ] "), whoami);
+ fprintf (fp, _("[ -p office-phone ]\n [ -h home-phone ] "));
+ fprintf (fp, _("[ --help ] [ --version ]\n"));
+
+ exit(fp == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
+}
+
int main (int argc, char **argv) {
char *cp;
uid_t uid;
@@ -123,28 +130,24 @@ int main (int argc, char **argv) {
* specified for.
*/
uid = getuid ();
- memzero (&oldf, sizeof (oldf));
- memzero (&newf, sizeof (newf));
+ memset(&oldf, 0, sizeof(oldf));
+ memset(&newf, 0, sizeof (newf));
interactive = parse_argv (argc, argv, &newf);
if (! newf.username) {
parse_passwd (getpwuid (uid), &oldf);
- if (! oldf.username) {
- fprintf (stderr, _("%s: you (user %d) don't exist.\n"), whoami, uid);
- return (-1); }
+ if (! oldf.username)
+ errx(EXIT_FAILURE, _("%s: you (user %d) don't exist."), whoami, uid);
}
else {
parse_passwd (getpwnam (newf.username), &oldf);
- if (! oldf.username) {
- cp = newf.username;
- fprintf (stderr, _("%s: user \"%s\" does not exist.\n"), whoami, cp);
- return (-1); }
+ if (! oldf.username)
+ errx(EXIT_FAILURE, _("%s: user \"%s\" does not exist."),
+ whoami, newf.username);
}
- if (!(is_local(oldf.username))) {
- fprintf (stderr, _("%s: can only change local entries.\n"), whoami);
- exit(1);
- }
+ if (!(is_local(oldf.username)))
+ errx(EXIT_FAILURE, _("can only change local entries"));
#ifdef HAVE_LIBSELINUX
if (is_selinux_enabled() > 0) {
@@ -152,26 +155,23 @@ int main (int argc, char **argv) {
if (checkAccess(oldf.username,PASSWD__CHFN)!=0) {
security_context_t user_context;
if (getprevcon(&user_context) < 0)
- user_context=(security_context_t) strdup(_("Unknown user context"));
- fprintf(stderr, _("%s: %s is not authorized to change the finger info of %s\n"),
- whoami, user_context, oldf.username);
- freecon(user_context);
- exit(1);
+ user_context = NULL;
+
+ errx(EXIT_FAILURE, _("%s: %s is not authorized to change "
+ "the finger info of %s"),
+ whoami, user_context ? : _("Unknown user context"),
+ oldf.username);
}
}
- if (setupDefaultContext("/etc/passwd") != 0) {
- fprintf(stderr,_("%s: Can't set default context for /etc/passwd"),
- whoami);
- exit(1);
- }
+ if (setupDefaultContext("/etc/passwd"))
+ errx(EXIT_FAILURE, _("can't set default context for /etc/passwd"));
}
#endif
/* Reality check */
if (uid != 0 && uid != oldf.pw->pw_uid) {
errno = EACCES;
- perror (whoami);
- return (-1);
+ err(EXIT_FAILURE, NULL);
}
printf (_("Changing finger information for %s.\n"), oldf.username);
@@ -184,11 +184,9 @@ int main (int argc, char **argv) {
int retcode;
retcode = pam_start("chfn", oldf.username, &conv, &pamh);
- if(retcode != PAM_SUCCESS) {
- fprintf(stderr, _("%s: PAM failure, aborting: %s\n"),
+ if(retcode != PAM_SUCCESS)
+ errx(EXIT_FAILURE, _("%s: PAM failure, aborting: %s"),
whoami, pam_strerror(pamh, retcode));
- exit(1);
- }
retcode = pam_authenticate(pamh, 0);
PAM_FAIL_CHECK(pamh, retcode);
@@ -212,7 +210,7 @@ int main (int argc, char **argv) {
if(strncmp(oldf.pw->pw_passwd,
crypt(pwdstr, oldf.pw->pw_passwd), 13)) {
puts(_("Incorrect password."));
- exit(1);
+ exit(EXIT_FAILURE);
}
}
# endif /* HAVE_SECURITY_PAM_MISC_H */
@@ -223,7 +221,7 @@ int main (int argc, char **argv) {
if (! set_changed_data (&oldf, &newf)) {
printf (_("Finger information not changed.\n"));
- return 0;
+ return EXIT_SUCCESS;
}
status = save_new_data (&oldf);
return status;
@@ -260,17 +258,13 @@ static boolean parse_argv (argc, argv, pinfo)
/* version? output version and exit. */
if (c == 'v') {
printf ("%s\n", PACKAGE_STRING);
- exit (0);
+ exit (EXIT_SUCCESS);
}
- if (c == 'u') {
+ if (c == 'u')
usage (stdout);
- exit (0);
- }
/* all other options must have an argument. */
- if (! optarg) {
+ if (! optarg)
usage (stderr);
- exit (-1);
- }
/* ok, we were given an argument */
info_given = true;
status = 0;
@@ -302,34 +296,19 @@ static boolean parse_argv (argc, argv, pinfo)
break;
default:
usage (stderr);
- status = (-1);
}
if (status < 0) exit (status);
}
/* done parsing arguments. check for a username. */
if (optind < argc) {
- if (optind + 1 < argc) {
+ if (optind + 1 < argc)
usage (stderr);
- exit (-1);
- }
pinfo->username = argv[optind];
}
return (! info_given);
}
/*
- * usage () --
- * print out a usage message.
- */
-static void usage (fp)
- FILE *fp;
-{
- fprintf (fp, _("Usage: %s [ -f full-name ] [ -o office ] "), whoami);
- fprintf (fp, _("[ -p office-phone ]\n [ -h home-phone ] "));
- fprintf (fp, _("[ --help ] [ --version ]\n"));
-}
-
-/*
* parse_passwd () --
* take a struct password and fill in the fields of the
* struct finfo.
@@ -345,7 +324,7 @@ static void parse_passwd (pw, pinfo)
pinfo->pw = pw;
pinfo->username = pw->pw_name;
/* use pw_gecos - we take a copy since PAM destroys the original */
- gecos = strdup(pw->pw_gecos);
+ gecos = xstrdup(pw->pw_gecos);
cp = (gecos ? gecos : "");
pinfo->full_name = cp;
cp = strchr (cp, ',');
@@ -398,7 +377,7 @@ static char *prompt (question, def_val)
*buf = 0;
if (fgets (buf, sizeof (buf), stdin) == NULL) {
printf (_("\nAborted.\n"));
- exit (-1);
+ exit (EXIT_FAILURE);
}
/* remove the newline at the end of buf. */
ans = buf;
@@ -439,15 +418,15 @@ static int check_gecos_string (msg, gecos)
if (c == ',' || c == ':' || c == '=' || c == '"' || c == '\n') {
if (msg) printf ("%s: ", msg);
printf (_("'%c' is not allowed.\n"), c);
- return (-1);
+ return -1;
}
if (iscntrl (c)) {
if (msg) printf ("%s: ", msg);
printf (_("Control characters are not allowed.\n"));
- return (-1);
+ return -1;
}
}
- return (0);
+ return 0;
}
/*
@@ -509,24 +488,8 @@ static int save_new_data (pinfo)
if (setpwnam (pinfo->pw) < 0) {
perror ("setpwnam");
printf( _("Finger information *NOT* changed. Try again later.\n" ));
- return (-1);
+ return -1;
}
printf (_("Finger information changed.\n"));
return 0;
}
-
-/*
- * xmalloc () -- malloc that never fails.
- */
-static void *xmalloc (bytes)
- int bytes;
-{
- void *vp;
-
- vp = malloc (bytes);
- if (! vp && bytes > 0) {
- perror (_("malloc failed"));
- exit (-1);
- }
- return vp;
-}
diff --git a/login-utils/chsh.1 b/login-utils/chsh.1
index bc9bc432..90514b8f 100644
--- a/login-utils/chsh.1
+++ b/login-utils/chsh.1
@@ -61,5 +61,5 @@ Print version information and exit.
.SH AUTHOR
Salvatore Valente <svalente@mit.edu>
.SH AVAILABILITY
-The chsh command is part of the util-linux-ng package and is available from
-ftp://ftp.kernel.org/pub/linux/utils/util-linux-ng/.
+The chsh command is part of the util-linux package and is available from
+ftp://ftp.kernel.org/pub/linux/utils/util-linux/.
diff --git a/login-utils/chsh.c b/login-utils/chsh.c
index a893ef99..22b33506 100644
--- a/login-utils/chsh.c
+++ b/login-utils/chsh.c
@@ -22,11 +22,7 @@
*
*
*/
-
-#if 0
-#define _POSIX_SOURCE 1
-#endif
-
+#include <err.h>
#include <sys/types.h>
#include <stdio.h>
#include <string.h>
@@ -36,12 +32,15 @@
#include <errno.h>
#include <ctype.h>
#include <getopt.h>
+
+#include "c.h"
#include "my_crypt.h"
#include "islocal.h"
#include "setpwnam.h"
#include "nls.h"
#include "env.h"
#include "pathnames.h"
+#include "xalloc.h"
#if defined(REQUIRE_PASSWORD) && defined(HAVE_SECURITY_PAM_MISC_H)
#include <security/pam_appl.h>
@@ -52,7 +51,7 @@
if ((_rc) != PAM_SUCCESS) { \
fprintf(stderr, "\n%s\n", pam_strerror((_ph), (_rc))); \
pam_end((_ph), (_rc)); \
- exit(1); \
+ exit(EXIT_FAILURE); \
} \
} while(0)
@@ -71,24 +70,27 @@ typedef unsigned char boolean;
/* Only root is allowed to assign a luser a non-listed shell, by default */
#define ONLY_LISTED_SHELLS 1
-
static char *whoami;
-static char buf[FILENAME_MAX];
-
struct sinfo {
char *username;
char *shell;
};
static void parse_argv (int argc, char *argv[], struct sinfo *pinfo);
-static void usage (FILE *fp);
static char *prompt (char *question, char *def_val);
static int check_shell (char *shell);
static boolean get_shell_list (char *shell);
-static void *xmalloc (int bytes);
-#define memzero(ptr, size) memset((char *) ptr, 0, size)
+static void __attribute__((__noreturn__)) usage (FILE *fp)
+{
+ fprintf (fp,
+ _("Usage: %s [ -s shell ] [ --list-shells ] "
+ "[ --help ] [ --version ]\n"
+ " [ username ]\n"), whoami);
+
+ exit(fp == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
+}
int
main (int argc, char *argv[]) {
@@ -109,28 +111,24 @@ main (int argc, char *argv[]) {
if (*cp == '/') whoami = cp + 1;
uid = getuid ();
- memzero (&info, sizeof (info));
+ memset(&info, 0, sizeof(info));
parse_argv (argc, argv, &info);
pw = NULL;
if (! info.username) {
pw = getpwuid (uid);
- if (! pw) {
- fprintf (stderr, _("%s: you (user %d) don't exist.\n"), whoami, uid);
- return (-1); }
+ if (! pw)
+ errx(EXIT_FAILURE, _("%s: you (user %d) don't exist."), whoami, uid);
}
else {
pw = getpwnam (info.username);
- if (! pw) {
- cp = info.username;
- fprintf (stderr, _("%s: user \"%s\" does not exist.\n"), whoami, cp);
- return (-1); }
+ if (! pw)
+ errx(EXIT_FAILURE, _("%s: user \"%s\" does not exist."),
+ whoami, info.username);
}
- if (!(is_local(pw->pw_name))) {
- fprintf (stderr, _("%s: can only change local entries.\n"), whoami);
- exit(1);
- }
+ if (!(is_local(pw->pw_name)))
+ errx(EXIT_FAILURE, _("%s: can only change local entries."), whoami);
#ifdef HAVE_LIBSELINUX
if (is_selinux_enabled() > 0) {
@@ -138,18 +136,16 @@ main (int argc, char *argv[]) {
if (checkAccess(pw->pw_name,PASSWD__CHSH)!=0) {
security_context_t user_context;
if (getprevcon(&user_context) < 0)
- user_context=(security_context_t) strdup(_("Unknown user context"));
- fprintf(stderr, _("%s: %s is not authorized to change the shell of %s\n"),
- whoami, user_context, pw->pw_name);
- freecon(user_context);
- exit(1);
+ user_context = (security_context_t) NULL;
+
+ errx(EXIT_FAILURE, _("%s: %s is not authorized to change the shell of %s"),
+ whoami, user_context ? : _("Unknown user context"),
+ pw->pw_name);
}
}
- if (setupDefaultContext("/etc/passwd") != 0) {
- fprintf(stderr,_("%s: Can't set default context for /etc/passwd"),
+ if (setupDefaultContext("/etc/passwd") != 0)
+ errx(EXIT_FAILURE, _("%s: can't set default context for /etc/passwd"),
whoami);
- exit(1);
- }
}
#endif
@@ -160,15 +156,13 @@ main (int argc, char *argv[]) {
/* reality check */
if (uid != 0 && uid != pw->pw_uid) {
errno = EACCES;
- fprintf(stderr,_("%s: Running UID doesn't match UID of user we're "
- "altering, shell change denied\n"), whoami);
- return (-1);
+ err(EXIT_FAILURE, _("%s: running UID doesn't match UID of user we're "
+ "altering, shell change denied"), whoami);
}
if (uid != 0 && !get_shell_list(oldshell)) {
errno = EACCES;
- fprintf(stderr,_("%s: Your shell is not in /etc/shells, shell change"
- " denied\n"),whoami);
- return (-1);
+ err(EXIT_FAILURE, _("%s: your shell is not in /etc/shells, "
+ "shell change denied"), whoami);
}
shell = info.shell;
@@ -177,17 +171,15 @@ main (int argc, char *argv[]) {
#ifdef REQUIRE_PASSWORD
#ifdef HAVE_SECURITY_PAM_MISC_H
- if(uid != 0) {
+ if (uid != 0) {
pam_handle_t *pamh = NULL;
struct pam_conv conv = { misc_conv, NULL };
int retcode;
retcode = pam_start("chsh", pw->pw_name, &conv, &pamh);
- if(retcode != PAM_SUCCESS) {
- fprintf(stderr, _("%s: PAM failure, aborting: %s\n"),
+ if(retcode != PAM_SUCCESS)
+ errx(EXIT_FAILURE, _("%s: PAM failure, aborting: %s"),
whoami, pam_strerror(pamh, retcode));
- exit(1);
- }
retcode = pam_authenticate(pamh, 0);
PAM_FAIL_CHECK(pamh, retcode);
@@ -211,7 +203,7 @@ main (int argc, char *argv[]) {
if(strncmp(pw->pw_passwd,
crypt(pwdstr, pw->pw_passwd), 13)) {
puts(_("Incorrect password."));
- exit(1);
+ return EXIT_FAILURE;
}
}
#endif /* HAVE_SECURITY_PAM_MISC_H */
@@ -219,23 +211,25 @@ main (int argc, char *argv[]) {
if (! shell) {
shell = prompt (_("New shell"), oldshell);
- if (! shell) return 0;
+ if (! shell)
+ return EXIT_SUCCESS;
}
- if (check_shell (shell) < 0) return (-1);
+ if (check_shell (shell) < 0)
+ return EXIT_FAILURE;
if (! strcmp (pw->pw_shell, shell)) {
printf (_("Shell not changed.\n"));
- return 0;
+ return EXIT_SUCCESS;
}
pw->pw_shell = shell;
if (setpwnam (pw) < 0) {
- perror ("setpwnam");
+ warn(_("setpwnam failed"));
printf( _("Shell *NOT* changed. Try again later.\n") );
- return (-1);
+ return EXIT_FAILURE;
}
printf (_("Shell changed.\n"));
- return 0;
+ return EXIT_SUCCESS;
}
/*
@@ -263,46 +257,29 @@ parse_argv (int argc, char *argv[], struct sinfo *pinfo) {
break;
case 'v':
printf ("%s\n", PACKAGE_STRING);
- exit (0);
+ exit (EXIT_SUCCESS);
case 'u':
usage (stdout);
- exit (0);
case 'l':
get_shell_list (NULL);
- exit (0);
+ exit (EXIT_SUCCESS);
case 's':
- if (! optarg) {
+ if (! optarg)
usage (stderr);
- exit (-1);
- }
pinfo->shell = optarg;
break;
default:
usage (stderr);
- exit (-1);
}
}
/* done parsing arguments. check for a username. */
if (optind < argc) {
- if (optind + 1 < argc) {
+ if (optind + 1 < argc)
usage (stderr);
- exit (-1);
- }
pinfo->username = argv[optind];
}
}
-/*
- * usage () --
- * print out a usage message.
- */
-static void
-usage (FILE *fp) {
- fprintf (fp,
- _("Usage: %s [ -s shell ] [ --list-shells ] "
- "[ --help ] [ --version ]\n"
- " [ username ]\n"), whoami);
-}
/*
* prompt () --
@@ -312,13 +289,14 @@ static char *
prompt (char *question, char *def_val) {
int len;
char *ans, *cp;
+ char buf[BUFSIZ];
if (! def_val) def_val = "";
printf("%s [%s]: ", question, def_val);
*buf = 0;
if (fgets (buf, sizeof (buf), stdin) == NULL) {
printf (_("\nAborted.\n"));
- exit (-1);
+ exit (EXIT_FAILURE);
}
/* remove the newline at the end of buf. */
ans = buf;
@@ -342,30 +320,30 @@ check_shell (char *shell) {
int i, c;
if (!shell)
- return (-1);
+ return -1;
if (*shell != '/') {
printf (_("%s: shell must be a full path name.\n"), whoami);
- return (-1);
+ return -1;
}
if (access (shell, F_OK) < 0) {
printf (_("%s: \"%s\" does not exist.\n"), whoami, shell);
- return (-1);
+ return -1;
}
if (access (shell, X_OK) < 0) {
printf (_("%s: \"%s\" is not executable.\n"), whoami, shell);
- return (-1);
+ return -1;
}
/* keep /etc/passwd clean. */
for (i = 0; i < strlen (shell); i++) {
c = shell[i];
if (c == ',' || c == ':' || c == '=' || c == '"' || c == '\n') {
printf (_("%s: '%c' is not allowed.\n"), whoami, c);
- return (-1);
+ return -1;
}
if (iscntrl (c)) {
printf (_("%s: Control characters are not allowed.\n"), whoami);
- return (-1);
+ return -1;
}
}
#ifdef ONLY_LISTED_SHELLS
@@ -376,7 +354,7 @@ check_shell (char *shell) {
printf (_("%s: \"%s\" is not listed in /etc/shells.\n"),
whoami, shell);
printf( _("%s: Use -l option to see list.\n"), whoami );
- exit(1);
+ exit(EXIT_FAILURE);
}
}
#else
@@ -398,6 +376,7 @@ get_shell_list (char *shell_name) {
FILE *fp;
boolean found;
int len;
+ char buf[PATH_MAX];
found = false;
fp = fopen ("/etc/shells", "r");
@@ -425,18 +404,3 @@ get_shell_list (char *shell_name) {
fclose (fp);
return found;
}
-
-/*
- * xmalloc () -- malloc that never fails.
- */
-static void *
-xmalloc (int bytes) {
- void *vp;
-
- vp = malloc (bytes);
- if (! vp && bytes > 0) {
- perror (_("malloc failed"));
- exit (-1);
- }
- return vp;
-}
diff --git a/login-utils/fastboot.8 b/login-utils/fastboot.8
deleted file mode 100644
index 386d9715..00000000
--- a/login-utils/fastboot.8
+++ /dev/null
@@ -1 +0,0 @@
-.so man8/shutdown.8
diff --git a/login-utils/fasthalt.8 b/login-utils/fasthalt.8
deleted file mode 100644
index 386d9715..00000000
--- a/login-utils/fasthalt.8
+++ /dev/null
@@ -1 +0,0 @@
-.so man8/shutdown.8
diff --git a/login-utils/halt.8 b/login-utils/halt.8
deleted file mode 100644
index 386d9715..00000000
--- a/login-utils/halt.8
+++ /dev/null
@@ -1 +0,0 @@
-.so man8/shutdown.8
diff --git a/login-utils/initctl.8 b/login-utils/initctl.8
deleted file mode 100644
index 3dd26e30..00000000
--- a/login-utils/initctl.8
+++ /dev/null
@@ -1,110 +0,0 @@
-.\" Copyright (C) 2000-2001 Richard Gooch
-.\"
-.\" This program is free software; you can redistribute it and/or modify
-.\" it under the terms of the GNU General Public License as published by
-.\" the Free Software Foundation; either version 2 of the License, or
-.\" (at your option) any later version.
-.\"
-.\" This program is distributed in the hope that it will be useful,
-.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
-.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-.\" GNU General Public License for more details.
-.\"
-.\" You should have received a copy of the GNU General Public License
-.\" along with this program; if not, write to the Free Software
-.\" Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-.\"
-.\" Richard Gooch may be reached by email at rgooch@atnf.csiro.au
-.\" The postal address is:
-.\" Richard Gooch, c/o ATNF, P. O. Box 76, Epping, N.S.W., 2121, Australia.
-.\"
-.\" initctl.8 Richard Gooch 21-FEB-2001
-.\"
-.TH INITCTL 8 "21 Feb 2001" "Util-Linux Package"
-.SH NAME
-initctl \- utility to control simpleinit(8)
-.SH SYNOPSIS
-.B need
-.RB [ \-r ]
-.I service
-.br
-.B display-services
-.br
-.B provide
-.I service
-.SH OVERVIEW
-The \fBinitctl\fP programme is designed to help improve the
-robustness, scalability and readability of system boot scripts. It is
-now possible to write a modularised set of boot scripts without the
-complex and fragile numbered symlink scheme used in SysV-style boot
-scripts. Each script can simply declare, using \fBneed\fP(8), what
-must run before them.
-.SH DESCRIPTION for need
-The \fBneed\fP programme is a utility that tells \fBsimpleinit\fP(8)
-to start a \fIservice\fP (usually a script in \fI/sbin/init.d\fP) and
-will wait for the service to become available. If the service is
-already available, it will not be started again.
-
-The \fB-r\fP option is used to tell \fBsimpleinit\fP(8) to "roll back"
-(stop) services up to (but not including) \fIservice\fP. If
-\fIservice\fP is not specified, all services are stopped. The \fB-r\fP
-option thus allows the system to be partially or wholly shut down in
-an orderly fashion. The \fBshutdown\fP(8) programme still needs to be
-run.
-
-.SH DESCRIPTION for display-services
-When invoked as \fBdisplay-services\fP it will write the list of
-currently available services and the list of failed services to the
-standard output.
-
-.SH DESCRIPTION for provide
-When invoked as \fBprovide\fP it tells \fBsimpleinit\fP(8) that the
-parent (calling) process will be providing a service with name
-\fIservice\fP. If the calling process exits successfully (status 0)
-the service is deemed to be available. Only one instance of
-\fIservice\fP may be started, so alternate providers will block and
-may fail.
-
-Using \fBprovide\fP it is possible to have multiple potential
-providers for the same (generic) service (e.g. \fBsendmail\fP and
-\fBqmail\fP both provide a \fBmta\fP service), where only one actually
-provides the service. This may be used by service startup scripts
-which check for configuration files.
-.SH EXIT CODE
-The exit code from \fBneed\fP is 0 if the service was successfully
-started, 1 if the service failed badly, and 2 if the service is
-unavailable (i.e. disabled in configuration files). These exit codes
-reflect the exit codes from the service startup scripts.
-
-The exit code from \fBneed -r\fP is 0 if the service was successfully
-stopped, 1 if the service could not be stopped, and 2 if the service
-was not available to start with. The service shutdown scripts may only
-return 0 (for success) or 1 (for failure).
-
-The exit code from \fBprovide\fP is 0 if the service may be provided,
-1 if it may not, and 2 if the parent process is not a child of
-init. It may block waiting for another provider which is initialising
-the service.
-.SH SIGNALS
-\fBinitctl\fP(8) uses \fBSIGUSR1\fP, \fBSIGUSR2\fP and \fBSIGPOLL\fP
-for communication with \fBsimpleinit\fP(8). Don't send these signals
-to it.
-.SH FILES
-.PD 0
-.TP 20
-.BI /dev/initctl
-This is the control FIFO, created by \fBsimpleinit\fP(8), which
-\fBinitctl\fP(8) writes commands to.
-.SH SEE ALSO
-.BR simpleinit (8),
-.BR init (8)
-.PP
-A more complete discussion of the new boot script system, based on
-\fBneed\fP(8), is available from:
-http://www.atnf.csiro.au/~rgooch/linux/boot-scripts/
-.SH AUTHOR
-Richard Gooch (rgooch@atnf.csiro.au)
-
-.SH AVAILABILITY
-The initctl command is part of the util-linux-ng package and is available from
-ftp://ftp.kernel.org/pub/linux/utils/util-linux-ng/.
diff --git a/login-utils/initctl.c b/login-utils/initctl.c
deleted file mode 100644
index 3b38b496..00000000
--- a/login-utils/initctl.c
+++ /dev/null
@@ -1,217 +0,0 @@
-/* initctl.c
-
- Source file for initctl (init(8) control tool).
-
- Copyright (C) 2000 Richard Gooch
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- Richard Gooch may be reached by email at rgooch@atnf.csiro.au
- The postal address is:
- Richard Gooch, c/o ATNF, P. O. Box 76, Epping, N.S.W., 2121, Australia.
-*/
-
-/*
- This tool will send control messages to init(8). For example, it may
- request init(8) to start a service and will wait for that service to be
- available. If the service is already available, init(8) will not start it
- again.
- This tool may also be used to inspect the list of currently available
- services.
-
-
- Written by Richard Gooch 28-FEB-2000
-
- Updated by Richard Gooch 11-OCT-2000: Added provide support.
-
- Last updated by Richard Gooch 6-NOV-2000: Renamed to initctl.c
-
-
-*/
-#include <unistd.h>
-#include <stdio.h>
-#include <limits.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <string.h>
-#include "simpleinit.h"
-
-
-static void signal_handler (int sig);
-
-
-static int caught_signal = 0;
-
-
-int main (int argc, char **argv)
-{
- int fd, nbytes;
- struct sigaction sa;
- sigset_t ss;
- char *ptr;
- long *buffer;
- struct command_struct *command;
-
- buffer = calloc(COMMAND_SIZE / sizeof (long) + 1, sizeof(long));
- if (!buffer) {
- fprintf (stderr, "Unable allocate buffer for command\n");
- exit(1);
- }
- command = (struct command_struct *) buffer;
-
- sigemptyset (&ss);
- sigaddset (&ss, SIG_PRESENT);
- sigaddset (&ss, SIG_NOT_PRESENT);
- sigaddset (&ss, SIG_FAILED);
- sigprocmask (SIG_BLOCK, &ss, NULL);
- sigemptyset (&sa.sa_mask);
- sa.sa_flags = 0;
- sa.sa_handler = signal_handler;
- sigaction (SIG_PRESENT, &sa, NULL);
- sigaction (SIG_NOT_PRESENT, &sa, NULL);
- sigaction (SIG_FAILED, &sa, NULL);
- command->pid = getpid ();
- command->ppid = getppid ();
- if ( ( ptr = strrchr (argv[0], '/') ) == NULL ) ptr = argv[0];
- else ++ptr;
- /* First generate command number by looking at invocation name */
- if (strcmp (ptr, "display-services") == 0)
- command->command = COMMAND_DUMP_LIST;
- else if (strcmp (ptr, "need") == 0) command->command = COMMAND_NEED;
- else if (strcmp (ptr, "provide") == 0) command->command = COMMAND_PROVIDE;
- else command->command = COMMAND_TEST;
- /* Now check for switches */
- if ( (argc > 1) && (argv[1][0] == '-') )
- {
- switch (argv[1][1])
- {
- case 'n':
- command->command = COMMAND_NEED;
- break;
- case 'r':
- command->command = COMMAND_ROLLBACK;
- break;
- case 'd':
- command->command = COMMAND_DUMP_LIST;
- break;
- case 'p':
- command->command = COMMAND_PROVIDE;
- break;
- default:
- fprintf (stderr, "Illegal switch: \"%s\"\n", argv[1]);
- exit (1);
- /*break;*/
- }
- --argc;
- ++argv;
- }
- switch (command->command)
- {
- case COMMAND_NEED:
- case COMMAND_PROVIDE:
- if (argc < 2)
- {
- fprintf (stderr, "Usage:\tneed|provide programme\n");
- exit (1);
- }
- /* Fall through */
- case COMMAND_ROLLBACK:
- if (argc > 1) strcpy (command->name, argv[1]);
- else command->name[0] = '\0';
- break;
- case COMMAND_DUMP_LIST:
- if (tmpnam (command->name) == NULL)
- {
- fprintf (stderr, "Unable to create a unique filename\t%s\n",
- ERRSTRING);
- exit (1);
- }
- if (mkfifo (command->name, S_IRUSR) != 0)
- {
- fprintf (stderr, "Unable to create FIFO: \"%s\"\t%s\n",
- command->name, ERRSTRING);
- exit (1);
- }
- break;
- }
- if ( ( fd = open ("/dev/initctl", O_WRONLY, 0) ) < 0 )
- {
- fprintf (stderr, "Error opening\t%s\n", ERRSTRING);
- exit (1);
- }
- if (write (fd, buffer, COMMAND_SIZE) < COMMAND_SIZE)
- {
- fprintf (stderr, "Error writing\t%s\n", ERRSTRING);
- exit (1);
- }
- close (fd);
- if (command->command != COMMAND_DUMP_LIST)
- {
- sigemptyset (&ss);
- while (caught_signal == 0) sigsuspend (&ss);
- switch (command->command)
- {
- case COMMAND_PROVIDE:
- switch (caught_signal)
- {
- case SIG_PRESENT:
- return 1;
- case SIG_NOT_PRESENT:
- return 0;
- case SIG_NOT_CHILD:
- fprintf (stderr, "Error\n");
- return 2;
- default:
- return 3;
- }
- break;
- default:
- switch (caught_signal)
- {
- case SIG_PRESENT:
- return 0;
- case SIG_NOT_PRESENT:
- return 2;
- case SIG_FAILED:
- return 1;
- default:
- return 3;
- }
- break;
- }
- return 3;
- }
- /* Read back the data and display it */
- if ( ( fd = open (command->name, O_RDONLY, 0) ) < 0 )
- {
- fprintf (stderr, "Error opening:\"%s\"\t%s\n",
- command->name, ERRSTRING);
- exit (1);
- }
- unlink (command->name);
- fflush (stdout);
- while ( ( nbytes = read (fd, buffer, COMMAND_SIZE) ) > 0 )
- write (1, buffer, nbytes);
- close (fd);
- return (0);
-} /* End Function main */
-
-static void signal_handler (int sig)
-{
- caught_signal = sig;
-} /* End Function signal_handler */
diff --git a/login-utils/last.1 b/login-utils/last.1
index 314e5d9d..3e9faa40 100644
--- a/login-utils/last.1
+++ b/login-utils/last.1
@@ -58,5 +58,5 @@ Also report year of dates.
.SH FILES
/var/log/wtmp \(em login data base
.SH AVAILABILITY
-The last command is part of the util-linux-ng package and is available from
-ftp://ftp.kernel.org/pub/linux/utils/util-linux-ng/.
+The last command is part of the util-linux package and is available from
+ftp://ftp.kernel.org/pub/linux/utils/util-linux/.
diff --git a/login-utils/last.c b/login-utils/last.c
index 0c4c0a16..de733cd5 100644
--- a/login-utils/last.c
+++ b/login-utils/last.c
@@ -29,6 +29,7 @@
/*
* last
*/
+#include <err.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/file.h>
@@ -49,6 +50,7 @@
#include "pathnames.h"
#include "nls.h"
+#include "xalloc.h"
#define SECDAY (24*60*60) /* seconds in a day */
#define NO 0 /* false/no */
@@ -146,7 +148,7 @@ main(int argc, char **argv) {
case '?':
default:
fputs(_("usage: last [-#] [-f file] [-t tty] [-h hostname] [user ...]\n"), stderr);
- exit(1);
+ exit(EXIT_FAILURE);
}
for (argv += optind; *argv; ++argv) {
#define COMPATIBILITY
@@ -157,7 +159,8 @@ main(int argc, char **argv) {
addarg(USER_TYPE, *argv);
}
wtmp();
- exit(0);
+
+ return EXIT_SUCCESS;
}
static char *utmp_ctime(struct utmp *u)
@@ -234,13 +237,15 @@ wtmp(void) {
(void)signal(SIGQUIT, onintr);
if ((fd = open(file,O_RDONLY)) < 0)
- exit(1);
+ err(EXIT_FAILURE, _("%s: open failed"), file);
+
fstat(fd, &st);
utl_len = st.st_size;
utl = mmap(NULL, utl_len, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_FILE, fd, 0);
if (utl == NULL)
- exit(1);
+ err(EXIT_FAILURE, _("%s: mmap failed"), file);
+
listnr = utl_len/sizeof(struct utmp);
if(listnr)
@@ -344,28 +349,28 @@ want(struct utmp *bp, int check) {
bp->ut_line[4] = '\0';
}
if (!arglist)
- return(YES);
+ 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);
+ return YES;
break;
case TTY_TYPE:
if (!strncmp(step->name, bp->ut_line, LMAX))
- return(YES);
+ return YES;
break;
case USER_TYPE:
if (!strncmp(step->name, bp->ut_name, NMAX))
- return(YES);
+ return YES;
break;
case INET_TYPE:
if (bp->ut_addr == inet_addr(step->name))
- return(YES);
+ return YES;
break;
}
- return(NO);
+ return NO;
}
/*
@@ -376,10 +381,7 @@ static void
addarg(int type, char *arg) {
register ARG *cur;
- if (!(cur = (ARG *)malloc((unsigned int)sizeof(ARG)))) {
- fputs(_("last: malloc failure.\n"), stderr);
- exit(1);
- }
+ cur = xmalloc(sizeof(ARG));
cur->next = arglist;
cur->type = type;
cur->name = arg;
@@ -394,10 +396,7 @@ TTY *
addtty(char *ttyname) {
register TTY *cur;
- if (!(cur = (TTY *)malloc((unsigned int)sizeof(TTY)))) {
- fputs(_("last: malloc failure.\n"), stderr);
- exit(1);
- }
+ cur = xmalloc(sizeof(TTY));
cur->next = ttylist;
cur->logout = currentout;
memcpy(cur->tty, ttyname, LMAX);
@@ -421,10 +420,9 @@ hostconv(char *arg) {
return;
if (first) {
first = 0;
- if (gethostname(name, sizeof(name))) {
- perror(_("last: gethostname"));
- exit(1);
- }
+ if (gethostname(name, sizeof(name)))
+ err(EXIT_FAILURE, _("gethostname failed"));
+
hostdot = strchr(name, '.');
}
if (hostdot && !strcmp(hostdot, argdot))
@@ -445,21 +443,19 @@ ttyconv(char *arg) {
*/
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);
- }
+ mval = xmalloc(8);
if (!strcmp(arg, "co"))
(void)strcpy(mval, "console");
else {
(void)strcpy(mval, "tty");
(void)strcpy(mval + 3, arg);
}
- return(mval);
+ return mval;
}
if (!strncmp(arg, "/dev/", sizeof("/dev/") - 1))
- return(arg + 5);
- return(arg);
+ return arg + 5;
+
+ return arg;
}
/*
@@ -473,6 +469,6 @@ onintr(int signo) {
ct = utmp_ctime(&utmpbuf);
printf(_("\ninterrupted %10.10s %5.5s \n"), ct, ct + 11);
if (signo == SIGINT)
- exit(1);
- (void)fflush(stdout); /* fix required for rsh */
+ _exit(EXIT_FAILURE);
+ fflush(stdout); /* fix required for rsh */
}
diff --git a/login-utils/login.1 b/login-utils/login.1
index 12273815..2b4bea31 100644
--- a/login-utils/login.1
+++ b/login-utils/login.1
@@ -340,5 +340,5 @@ for HP-UX
.br
Ported to Linux 0.12: Peter Orbaek (poe@daimi.aau.dk)
.SH AVAILABILITY
-The login command is part of the util-linux-ng package and is available from
-ftp://ftp.kernel.org/pub/linux/utils/util-linux-ng/.
+The login command is part of the util-linux package and is available from
+ftp://ftp.kernel.org/pub/linux/utils/util-linux/.
diff --git a/login-utils/login.c b/login-utils/login.c
index 1550388c..ad2932d0 100644
--- a/login-utils/login.c
+++ b/login-utils/login.c
@@ -97,6 +97,7 @@
#include <sys/wait.h>
#include <signal.h>
#include <errno.h>
+#include <err.h>
#include <grp.h>
#include <pwd.h>
#include <utmp.h>
@@ -113,9 +114,9 @@
#include "pathnames.h"
#include "my_crypt.h"
#include "login.h"
-#include "xstrncpy.h"
+#include "strutils.h"
#include "nls.h"
-
+#include "xalloc.h"
#ifdef HAVE_SECURITY_PAM_MISC_H
# include <security/pam_appl.h>
@@ -124,7 +125,7 @@
# define PAM_FAIL_CHECK if (retcode != PAM_SUCCESS) { \
fprintf(stderr,"\n%s\n",pam_strerror(pamh, retcode)); \
syslog(LOG_ERR,"%s",pam_strerror(pamh, retcode)); \
- pam_end(pamh, retcode); exit(1); \
+ pam_end(pamh, retcode); exit(EXIT_FAILURE); \
}
# define PAM_END { \
pam_setcred(pamh, PAM_DELETE_CRED); \
@@ -196,15 +197,13 @@ opentty(const char * tty) {
if (fd == -1) {
syslog(LOG_ERR, _("FATAL: can't reopen tty: %s"),
strerror(errno));
- sleep(1);
- exit(1);
+ sleepexit(EXIT_FAILURE);
}
if (!isatty(fd)) {
close(fd);
syslog(LOG_ERR, _("FATAL: %s is not a terminal"), tty);
- sleep(1);
- exit(1);
+ sleepexit(EXIT_FAILURE);
}
flags = fcntl(fd, F_GETFL);
@@ -235,9 +234,9 @@ check_ttyname(char *ttyn) {
|| !S_ISCHR(statbuf.st_mode)
|| (statbuf.st_nlink > 1 && strncmp(ttyn, "/dev/", 5))
|| (access(ttyn, R_OK | W_OK) != 0)) {
+
syslog(LOG_ERR, _("FATAL: bad tty"));
- sleep(1);
- exit(1);
+ sleepexit(EXIT_FAILURE);
}
}
@@ -443,7 +442,7 @@ main(int argc, char **argv)
if (getuid()) {
fprintf(stderr,
_("login: -h for super-user only.\n"));
- exit(1);
+ exit(EXIT_FAILURE);
}
hflag = 1;
if (domain && (p = strchr(optarg, '.')) &&
@@ -486,7 +485,7 @@ main(int argc, char **argv)
default:
fprintf(stderr,
_("usage: login [-fp] [username]\n"));
- exit(1);
+ exit(EXIT_FAILURE);
}
argc -= optind;
argv += optind;
@@ -540,7 +539,10 @@ main(int argc, char **argv)
ttt.c_cflag &= ~HUPCL;
/* These can fail, e.g. with ttyn on a read-only filesystem */
- fchown(0, 0, 0);
+ if (fchown(0, 0, 0)) {
+ ; /* glibc warn_unused_result */
+ }
+
fchmod(0, TTY_MODE);
/* Kill processes left on this tty */
@@ -573,11 +575,10 @@ main(int argc, char **argv)
retcode = pam_start(hflag?"remote":"login",username, &conv, &pamh);
if(retcode != PAM_SUCCESS) {
- fprintf(stderr, _("%s: PAM failure, aborting: %s\n"),
- "login", pam_strerror(pamh, retcode));
+ warnx(_("PAM failure, aborting: %s"), pam_strerror(pamh, retcode));
syslog(LOG_ERR, _("Couldn't initialize PAM: %s"),
pam_strerror(pamh, retcode));
- exit(99);
+ exit(EXIT_FAILURE);
}
/* hostname & tty are either set to NULL or their correct values,
depending on how much we know */
@@ -661,7 +662,7 @@ main(int argc, char **argv)
fprintf(stderr,_("\nLogin incorrect\n"));
pam_end(pamh, retcode);
- exit(0);
+ exit(EXIT_SUCCESS);
}
}
@@ -687,18 +688,18 @@ main(int argc, char **argv)
PAM_FAIL_CHECK;
if (!username || !*username) {
- fprintf(stderr, _("\nSession setup problem, abort.\n"));
+ warnx(_("\nSession setup problem, abort."));
syslog(LOG_ERR, _("NULL user name in %s:%d. Abort."),
__FUNCTION__, __LINE__);
pam_end(pamh, PAM_SYSTEM_ERR);
- exit(1);
+ exit(EXIT_FAILURE);
}
if (!(pwd = getpwnam(username))) {
- fprintf(stderr, _("\nSession setup problem, abort.\n"));
+ warnx(_("\nSession setup problem, abort."));
syslog(LOG_ERR, _("Invalid user name \"%s\" in %s:%d. Abort."),
username, __FUNCTION__, __LINE__);
pam_end(pamh, PAM_SYSTEM_ERR);
- exit(1);
+ exit(EXIT_FAILURE);
}
/*
@@ -714,10 +715,10 @@ main(int argc, char **argv)
pwd->pw_shell = strdup(pwd->pw_shell);
if (!pwd->pw_name || !pwd->pw_passwd || !pwd->pw_gecos ||
!pwd->pw_dir || !pwd->pw_shell) {
- fprintf(stderr, _("login: Out of memory\n"));
+ warnx(_("out of memory"));
syslog(LOG_ERR, "Out of memory");
pam_end(pamh, PAM_SYSTEM_ERR);
- exit(1);
+ exit(EXIT_FAILURE);
}
username = pwd->pw_name;
@@ -728,9 +729,9 @@ main(int argc, char **argv)
*/
if (initgroups(username, pwd->pw_gid) < 0) {
syslog(LOG_ERR, "initgroups: %m");
- fprintf(stderr, _("\nSession setup problem, abort.\n"));
+ warnx(_("\nSession setup problem, abort."));
pam_end(pamh, PAM_SYSTEM_ERR);
- exit(1);
+ exit(EXIT_FAILURE);
}
retcode = pam_open_session(pamh, 0);
@@ -760,7 +761,7 @@ main(int argc, char **argv)
if (username[0] == '+') {
puts(_("Illegal username"));
badlogin(username);
- sleepexit(1);
+ sleepexit(EXIT_FAILURE);
}
/* (void)strcpy(tbuf, username); why was this here? */
@@ -800,8 +801,7 @@ main(int argc, char **argv)
* refuse the login attempt.
*/
if (pwd && pwd->pw_uid == 0 && !rootterm(tty_name)) {
- fprintf(stderr,
- _("%s login refused on this terminal.\n"),
+ warnx(_("%s login refused on this terminal."),
pwd->pw_name);
if (hostname)
@@ -871,7 +871,7 @@ main(int argc, char **argv)
/* we allow 10 tries, but after 3 we start backing off */
if (++cnt > 3) {
if (cnt >= 10) {
- sleepexit(1);
+ sleepexit(EXIT_FAILURE);
}
sleep((unsigned int)((cnt - 3) * 5));
}
@@ -1013,16 +1013,22 @@ Michael Riepe <michael@stud.uni-hannover.de>
logaudit(tty_name, username, hostname, pwd, 1);
dolastlog(quietlog);
- fchown(0, pwd->pw_uid,
- (gr = getgrnam(TTYGRPNAME)) ? gr->gr_gid : pwd->pw_gid);
+ if (fchown(0, pwd->pw_uid,
+ (gr = getgrnam(TTYGRPNAME)) ? gr->gr_gid : pwd->pw_gid))
+ warn(_("change terminal owner failed"));
+
fchmod(0, TTY_MODE);
#ifdef LOGIN_CHOWN_VCS
/* if tty is one of the VC's then change owner and mode of the
special /dev/vcs devices as well */
if (consoletty(0)) {
- chown(vcsn, pwd->pw_uid, (gr ? gr->gr_gid : pwd->pw_gid));
- chown(vcsan, pwd->pw_uid, (gr ? gr->gr_gid : pwd->pw_gid));
+
+ if (chown(vcsn, pwd->pw_uid, (gr ? gr->gr_gid : pwd->pw_gid)))
+ warn(_("change terminal owner failed"));
+ if (chown(vcsan, pwd->pw_uid, (gr ? gr->gr_gid : pwd->pw_gid)))
+ warn(_("change terminal owner failed"));
+
chmod(vcsn, TTY_MODE);
chmod(vcsan, TTY_MODE);
}
@@ -1170,11 +1176,10 @@ Michael Riepe <michael@stud.uni-hannover.de>
child_pid = fork();
if (child_pid < 0) {
- int errsv = errno;
/* error in fork() */
- fprintf(stderr, _("login: failure forking: %s"), strerror(errsv));
+ warn(_("failure forking"));
PAM_END;
- exit(0);
+ exit(EXIT_FAILURE);
}
if (child_pid) {
@@ -1191,7 +1196,7 @@ Michael Riepe <michael@stud.uni-hannover.de>
;
openlog("login", LOG_ODELAY, LOG_AUTHPRIV);
PAM_END;
- exit(0);
+ exit(EXIT_SUCCESS);
}
/* child */
@@ -1200,7 +1205,7 @@ Michael Riepe <michael@stud.uni-hannover.de>
sigaction(SIGHUP, &oldsa_hup, NULL);
sigaction(SIGTERM, &oldsa_term, NULL);
if(got_sig)
- exit(1);
+ exit(EXIT_FAILURE);
/*
* Problem: if the user's shell is a shell like ash that doesnt do
@@ -1226,26 +1231,21 @@ Michael Riepe <michael@stud.uni-hannover.de>
/* 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"));
- exit(1);
+ exit(EXIT_FAILURE);
}
/* wait until here to change directory! */
if (chdir(pwd->pw_dir) < 0) {
- printf(_("No directory %s!\n"), pwd->pw_dir);
+ warn(_("%s: change directory failed"), pwd->pw_dir);
if (chdir("/"))
- exit(0);
+ exit(EXIT_FAILURE);
pwd->pw_dir = "/";
printf(_("Logging in with home = \"/\".\n"));
}
/* if the shell field has a space: treat it like a shell script */
if (strchr(pwd->pw_shell, ' ')) {
- buff = malloc(strlen(pwd->pw_shell) + 6);
-
- if (!buff) {
- fprintf(stderr, _("login: no memory for shell script.\n"));
- exit(0);
- }
+ buff = xmalloc(strlen(pwd->pw_shell) + 6);
strcpy(buff, "exec ");
strcat(buff, pwd->pw_shell);
@@ -1270,12 +1270,11 @@ Michael Riepe <michael@stud.uni-hannover.de>
errsv = errno;
if (!strcmp(childArgv[0], "/bin/sh"))
- fprintf(stderr, _("login: couldn't exec shell script: %s.\n"),
- strerror(errsv));
+ warn(_("couldn't exec shell script"));
else
- fprintf(stderr, _("login: no shell: %s.\n"), strerror(errsv));
+ warn(_("no shell"));
- exit(0);
+ exit(EXIT_SUCCESS);
}
#ifndef HAVE_SECURITY_PAM_MISC_H
@@ -1292,22 +1291,20 @@ getloginname(void) {
for (p = nbuf; (ch = getchar()) != '\n'; ) {
if (ch == EOF) {
badlogin("EOF");
- exit(0);
+ exit(EXIT_FAILURE);
}
if (p < nbuf + UT_NAMESIZE)
*p++ = ch;
cnt++;
if (cnt > UT_NAMESIZE + 20) {
- fprintf(stderr, _("login name much too long.\n"));
badlogin(_("NAME too long"));
- exit(0);
+ errx(EXIT_FAILURE, _("login name much too long."));
}
}
if (p > nbuf) {
if (nbuf[0] == '-')
- fprintf(stderr,
- _("login names may not start with '-'.\n"));
+ warnx(_("login names may not start with '-'."));
else {
*p = '\0';
username = nbuf;
@@ -1317,9 +1314,8 @@ getloginname(void) {
cnt2++;
if (cnt2 > 50) {
- fprintf(stderr, _("too many bare linefeeds.\n"));
badlogin(_("EXCESSIVE linefeeds"));
- exit(0);
+ errx(EXIT_FAILURE, _("too many bare linefeeds."));
}
}
}
@@ -1343,14 +1339,14 @@ timedout2(int sig) {
tcgetattr(0, &ti);
ti.c_lflag |= ECHO;
tcsetattr(0, TCSANOW, &ti);
- exit(0); /* %% */
+ exit(EXIT_SUCCESS); /* %% */
}
static void
timedout(int sig) {
signal(SIGALRM, timedout2);
alarm(10);
- fprintf(stderr, _("Login timed out after %d seconds\n"), timeout);
+ warnx(_("timed out after %d seconds"), timeout);
signal(SIGALRM, SIG_IGN);
alarm(0);
timedout2(0);
@@ -1380,10 +1376,10 @@ rootterm(char * ttyn)
return 1;
} else
continue;
- } else {
+ } else {
close(fd);
return 0;
- }
+ }
}
}
#endif /* !HAVE_SECURITY_PAM_MISC_H */
@@ -1400,8 +1396,11 @@ motd(void) {
return;
oldint = signal(SIGINT, sigint);
if (setjmp(motdinterrupt) == 0)
- while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0)
- write(fileno(stdout), tbuf, nchars);
+ while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0) {
+ if (write(fileno(stdout), tbuf, nchars)) {
+ ; /* glibc warn_unused_result */
+ }
+ }
signal(SIGINT, oldint);
close(fd);
}
@@ -1418,10 +1417,13 @@ checknologin(void) {
char tbuf[8192];
if ((fd = open(_PATH_NOLOGIN, O_RDONLY, 0)) >= 0) {
- while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0)
- write(fileno(stdout), tbuf, nchars);
+ while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0) {
+ if (write(fileno(stdout), tbuf, nchars)) {
+ ; /* glibc warn_unused_result */
+ }
+ }
close(fd);
- sleepexit(0);
+ sleepexit(EXIT_SUCCESS);
}
}
#endif
@@ -1462,7 +1464,8 @@ dolastlog(int quiet) {
if (hostname)
xstrncpy(ll.ll_host, hostname, sizeof(ll.ll_host));
- write(fd, (char *)&ll, sizeof(ll));
+ if (write(fd, (char *)&ll, sizeof(ll)) < 0)
+ warn(_("write lastlog failed"));
close(fd);
}
}
diff --git a/login-utils/mesg.1 b/login-utils/mesg.1
index 38b57382..05c42e35 100644
--- a/login-utils/mesg.1
+++ b/login-utils/mesg.1
@@ -99,5 +99,5 @@ A
command appeared in Version 6 AT&T UNIX.
.SH AVAILABILITY
-The mesg command is part of the util-linux-ng package and is available from
-ftp://ftp.kernel.org/pub/linux/utils/util-linux-ng/.
+The mesg command is part of the util-linux package and is available from
+ftp://ftp.kernel.org/pub/linux/utils/util-linux/.
diff --git a/login-utils/mesg.c b/login-utils/mesg.c
index e0015bdb..c24a1092 100644
--- a/login-utils/mesg.c
+++ b/login-utils/mesg.c
@@ -42,24 +42,27 @@
* 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL>
* - added Native Language Support
*
- *
+ * 2010-12-01 Marek Polacek <mmpolacek@gmail.com>
+ * - cleanups
*/
-#include <sys/types.h>
-#include <sys/stat.h>
-
+#include <err.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-#include <err.h>
+#include <sys/types.h>
+#include <sys/stat.h>
#include "nls.h"
-int
-main(argc, argv)
- int argc;
- char *argv[];
+/* exit codes */
+
+#define IS_ALLOWED 0 /* Receiving messages is allowed. */
+#define IS_NOT_ALLOWED 1 /* Receiving messages is not allowed. */
+#define MESG_EXIT_FAILURE 2 /* An error occurred. */
+
+int main(int argc, char *argv[])
{
struct stat sb;
char *tty;
@@ -69,46 +72,47 @@ main(argc, argv)
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
-
while ((ch = getopt(argc, argv, "")) != -1)
switch (ch) {
case '?':
default:
goto usage;
}
+
argc -= optind;
argv += optind;
if ((tty = ttyname(STDERR_FILENO)) == NULL)
- err(1, "ttyname");
+ err(MESG_EXIT_FAILURE, _("ttyname failed"));
+
if (stat(tty, &sb) < 0)
- err(1, "%s", tty);
+ err(MESG_EXIT_FAILURE, _("stat %s failed"), tty);
- if (*argv == NULL) {
+ if (!*argv) {
if (sb.st_mode & (S_IWGRP | S_IWOTH)) {
- (void)fprintf(stdout, _("is y\n"));
- exit(0);
+ puts(_("is y"));
+ return IS_ALLOWED;
}
- (void)fprintf(stdout, _("is n\n"));
- exit(1);
+ puts(_("is n"));
+ return IS_NOT_ALLOWED;
}
switch (*argv[0]) {
case 'y':
#ifdef USE_TTY_GROUP
if (chmod(tty, sb.st_mode | S_IWGRP) < 0)
- err(1, "%s", tty);
#else
if (chmod(tty, sb.st_mode | S_IWGRP | S_IWOTH) < 0)
- err(1, "%s", tty);
#endif
- exit(0);
+ err(MESG_EXIT_FAILURE, _("change %s mode failed"), tty);
+ return IS_ALLOWED;
case 'n':
if (chmod(tty, sb.st_mode & ~(S_IWGRP|S_IWOTH)) < 0)
- err(1, "%s", tty);
- exit(1);
+ err(MESG_EXIT_FAILURE, _("change %s mode failed"), tty);
+ return IS_NOT_ALLOWED;
}
-usage: (void)fprintf(stderr, _("usage: mesg [y | n]\n"));
- exit(2);
+usage:
+ fprintf(stderr, _("Usage: %s [y | n]"), program_invocation_short_name);
+ return MESG_EXIT_FAILURE;
}
diff --git a/login-utils/newgrp.1 b/login-utils/newgrp.1
index fade125c..6226c15a 100644
--- a/login-utils/newgrp.1
+++ b/login-utils/newgrp.1
@@ -30,5 +30,5 @@ Originally by Michael Haardt. Currently maintained by
Peter Orbaek (poe@daimi.aau.dk).
.SH AVAILABILITY
-The newgrp command is part of the util-linux-ng package and is available from
-ftp://ftp.kernel.org/pub/linux/utils/util-linux-ng/.
+The newgrp command is part of the util-linux package and is available from
+ftp://ftp.kernel.org/pub/linux/utils/util-linux/.
diff --git a/login-utils/newgrp.c b/login-utils/newgrp.c
index 976a0493..6323af19 100644
--- a/login-utils/newgrp.c
+++ b/login-utils/newgrp.c
@@ -14,6 +14,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
+#include <err.h>
#include "c.h"
#include "pathnames.h"
@@ -54,7 +55,7 @@ get_gshadow_pwd(char *groupname)
}
static int
-allow_setgid(struct passwd *pe, struct group *ge)
+allow_setgid(struct passwd *pe, struct group *ge)
{
char **look;
int notfound = 1;
@@ -84,7 +85,7 @@ allow_setgid(struct passwd *pe, struct group *ge)
return FALSE; /* default to denial */
}
-int
+int
main(int argc, char *argv[])
{
struct passwd *pw_entry;
@@ -95,47 +96,37 @@ main(int argc, char *argv[])
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
- if (!(pw_entry = getpwuid(getuid()))) {
- perror(_("newgrp: Who are you?"));
- exit(1);
- }
+ if (!(pw_entry = getpwuid(getuid())))
+ err(EXIT_FAILURE, _("who are you?"));
shell = (pw_entry->pw_shell[0] ? pw_entry->pw_shell : _PATH_BSHELL);
if (argc < 2) {
- if(setgid(pw_entry->pw_gid) < 0) {
- perror(_("newgrp: setgid"));
- exit(1);
- }
+ if(setgid(pw_entry->pw_gid) < 0)
+ err(EXIT_FAILURE, _("setgid failed"));
} else {
errno = 0;
if (!(gr_entry = getgrnam(argv[1]))) {
if (errno)
- perror(_("newgrp: No such group.")); /* error */
+ err(EXIT_FAILURE, _("no such group"));
else
- fprintf(stderr, "%s\n", _("newgrp: No such group.")); /* no group */
- exit(1);
+ errx(EXIT_FAILURE, _("no such group")); /* No group */
} else {
- if(allow_setgid(pw_entry, gr_entry)) {
- if(setgid(gr_entry->gr_gid) < 0) {
- perror(_("newgrp: setgid"));
- exit(1);
- }
- } else {
- puts(_("newgrp: Permission denied"));
- exit(1);
- }
+ if (allow_setgid(pw_entry, gr_entry)) {
+ if (setgid(gr_entry->gr_gid) < 0)
+ err(EXIT_FAILURE, _("setgid failed"));
+ } else
+ errx(EXIT_FAILURE, _("permission denied"));
}
}
- if(setuid(getuid()) < 0) {
- perror(_("newgrp: setuid"));
- exit(1);
- }
+ if (setuid(getuid()) < 0)
+ err(EXIT_FAILURE, _("setuid failed"));
fflush(stdout); fflush(stderr);
execl(shell,shell,(char*)0);
- perror(_("No shell"));
+ warn(_("exec %s failed"), shell);
fflush(stderr);
- exit(1);
+
+ return EXIT_FAILURE;
}
diff --git a/login-utils/reboot.8 b/login-utils/reboot.8
deleted file mode 100644
index 386d9715..00000000
--- a/login-utils/reboot.8
+++ /dev/null
@@ -1 +0,0 @@
-.so man8/shutdown.8
diff --git a/login-utils/shutdown.8 b/login-utils/shutdown.8
deleted file mode 100644
index 371310b6..00000000
--- a/login-utils/shutdown.8
+++ /dev/null
@@ -1,169 +0,0 @@
-.\" Copyright 1992 Rickard E. Faith (faith@cs.unc.edu)
-.\" May be distributed under the GNU General Public License
-.\"
-.\"
-.TH SHUTDOWN 8 "2 March 2000" "Linux 2.0" "Linux Programmer's Manual"
-.SH NAME
-shutdown \- close down the system
-.SH SYNOPSIS
-.B shutdown
-.RB [ \-h | \-r ]
-.RB [ \-fqs ]
-.RB [ now | \fIhh\fP:\fIss\fP | +\fImins\fP ]
-.RI [ message ]
-.br
-.B reboot
-.RB [ \-h | \-r ]
-.RB [ \-fqs ]
-.RB [ now | \fIhh\fP:\fIss\fP | +\fImins\fP ]
-.RI [ message ]
-.br
-.B fastboot
-.RB [ \-h | \-r ]
-.RB [ \-fqs ]
-.RB [ now | \fIhh\fP:\fIss\fP | +\fImins\fP ]
-.RI [ message ]
-.br
-.B halt
-.RB [ \-h | \-r ]
-.RB [ \-fqs ]
-.RB [ now | \fIhh\fP:\fIss\fP | +\fImins\fP ]
-.RI [ message ]
-.br
-.B fasthalt
-.RB [ \-h | \-r ]
-.RB [ \-fqs ]
-.RB [ now | \fIhh\fP:\fIss\fP | +\fImins\fP ]
-.RI [ message ]
-.SH DESCRIPTION
-.\" " for emacs hilit19
-In general,
-.B shutdown
-prepares the system for a power down or reboot. A absolute or delta time
-can be given, and periodic messages will be sent to all users warning of
-the shutdown. If no message is specified on the command line,
-.B shutdown
-will ask for a message to be sent, unless the
-.B \-q
-option is set.
-
-.B halt
-is the same as
-.B "shutdown -h -q now"
-
-.B fasthalt
-is the same as
-.B "shutdown -h -q -f now"
-
-.B reboot
-is the same as
-.B "shutdown -r -q now"
-
-.B fastboot
-is the same as
-.B "shutdown -r -q -f now"
-
-The default delta time, if none is specified, is 2 minutes.
-
-Five minutes before shutdown (or immediately, if shutdown is less than five
-minutes away), the
-.I /etc/nologin
-file is created with a message stating that the system is going down and
-that logins are no longer permitted. The
-.BR login (1)
-program will not allow non-superusers to login during this period. A
-message will be sent to all users at this time.
-
-When the shutdown time arrives,
-.B shutdown
-notifies all users, tells
-.BR init (8)
-not to spawn more
-.BR getty (8)'s,
-writes the shutdown time into the
-.I /var/log/wtmp
-file, kills all other processes on the system,
-.BR sync (2)'s,
-unmounts all the disks,
-.BR sync (2)'s
-again, waits for a second, and then either terminates or reboots the
-system.
-
-Prior to unmounting all discs, the \fBSIGQUIT\fP signal is sent to the
-\fBinit\fP process, which will in turn exec \fBshutdown\fP(8). This
-allows for clean unmounting, even if the old inode for the \fBinit\fP
-process was unlinked. If the current process ID (PID) equals 1, then
-\fBshutdown\fP(8) will pause forever.
-.SH OPTIONS
-.TP
-.B \-h
-Halt the system. Do not reboot. This option is used when powering down
-the system.
-.TP
-.B \-r
-Reboot the system.
-.TP
-.B \-f
-Fast. When the system is rebooted, the file systems will not be checked.
-This is arranged by creating
-.IR /fastboot ,
-which
-.I /etc/rc
-must detect (and delete).
-.TP
-.B \-q
-Quiet. This uses a default broadcast message, and does not prompt the user
-for one.
-.TP
-.B \-s
-Reboot in single user mode. This is arranged by creating
-.IR /etc/singleboot ,
-which
-.BR simpleinit (8)
-detects (and deletes).
-.SH FILES
-.nf
-.I /etc/rc
-.I /fastboot
-.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),
-.BR reboot (2),
-.BR simpleinit (8),
-.BR init (8)
-.SH BUGS
-Unlike the BSD
-.BR shutdown ,
-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
-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
deleted file mode 100644
index f7bc0005..00000000
--- a/login-utils/shutdown.c
+++ /dev/null
@@ -1,754 +0,0 @@
-/* shutdown.c - shutdown a Linux system
- * Initially written by poe@daimi.aau.dk
- * Currently maintained at ftp://ftp.daimi.aau.dk/pub/Software/Linux/
- */
-
-/*
- * Modified by jrs@world.std.com to try to exec "umount -a" and if
- * that doesn't work, then umount filesystems ourselves in reverse
- * order. The old-way was in forward order. Also if the device
- * field of the mtab does not start with a "/" then give umount
- * the mount point instead. This is needed for the nfs and proc
- * filesystems and yet is compatible with older systems.
- *
- * We also use the mntent library interface to read the mtab file
- * instead of trying to parse it directly and no longer give a
- * warning about not being able to umount the root.
- *
- * The reason "umount -a" should be tried first is because it may do
- * special processing for some filesystems (such as informing an
- * nfs server about nfs umounts) that we don't want to cope with here.
- */
-
-/*
- * 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.
- *
- * 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL>
- * - added Native Language Support
- *
- * 2000-03-02 Richard Gooch <rgooch@atnf.csiro.au>
- * - pause forever if (pid == 1) and send SIGQUIT to pid = 1
- *
- * 2000-11-04 Richard Gooch <rgooch@atnf.csiro.au>
- * - continue reaping if (pid == 1)
- *
- * 2000-11-06 Richard Gooch <rgooch@atnf.csiro.au>
- * - shut down "finalprog" from /etc/inittab
- * - kill normal user (non-root and non-daemon) processes first with SIGTERM
- *
- * 2000-11-08 Richard Gooch <rgooch@atnf.csiro.au>
- * - rollback services
- * - do not unmount devfs (otherwise get harmless but annoying messages)
- * - created syncwait() for faster shutting down
- * - kill getty processes
- * 2001-05-12 Richard Gooch <rgooch@atnf.csiro.au>
- * - unblock all signals (sigmask from simpleinit(8) stopped sleep(3))
- * - close all files
- */
-
-#include <stdio.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <utmp.h>
-#include <time.h>
-#include <string.h>
-#include <ctype.h>
-#include <signal.h>
-#include <errno.h>
-#include <sys/param.h>
-#include <termios.h>
-#include <mntent.h>
-#include <sys/mount.h>
-#include <sys/wait.h>
-#include <syslog.h>
-#include <sys/resource.h>
-#include <sys/types.h>
-#include <dirent.h>
-#include <sys/stat.h>
-#include <sys/utsname.h>
-#include "linux_reboot.h"
-#include "pathnames.h"
-#include "xstrncpy.h"
-#include "nls.h"
-#include "usleep.h"
-
-static void usage(void), int_handler(int), write_user(struct utmp *);
-static void wall(void), write_wtmp(void), unmount_disks(void);
-static void unmount_disks_ourselves(void);
-static void swap_off(void), do_halt(char *);
-static void kill_mortals (int sig);
-static void stop_finalprog (void);
-static void syncwait (int timeval);
-
-
-char *prog; /* name of the program */
-int opt_reboot; /* true if -r option or reboot command */
-int timeout; /* number of seconds to shutdown */
-int opt_quiet; /* true if no message is wanted */
-int opt_fast; /* true if fast boot */
-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 WRCRLF write(fd, "\r\n", 2)
-#define ERRSTRING strerror(errno)
-
-#define UMOUNT_ARGS "umount", "-a", "-t", "nodevfs"
-#define SWAPOFF_ARGS "swapoff", "-a"
-
-void
-usage(void)
-{
- fprintf(stderr,
- _("Usage: shutdown [-h|-r] [-fqs] [now|hh:ss|+mins]\n"));
- exit(1);
-}
-
-static void
-my_puts(char *s)
-{
- /* Use a fresh stdout after forking */
- freopen(_PATH_CONSOLE, "w", stdout);
- puts(s);
- fflush(stdout);
-}
-
-void
-int_handler(int sig)
-{
- unlink(_PATH_NOLOGIN);
- signal(SIGINT, SIG_DFL);
- my_puts(_("Shutdown process aborted"));
- exit(1);
-}
-
-static int
-iswhitespace(int a) {
- return (a == ' ' || a == '\t');
-}
-
-int
-main(int argc, char *argv[])
-{
- int c, i, fd;
- char *ptr;
-
- i = getdtablesize ();
- for (fd = 3; fd < i; fd++) close (fd);
- if (getpid () == 1)
- {
- for (fd = 0; fd < 3; fd++) close (fd);
- while (1) wait (NULL); /* Grim reaper never stops */
- }
- sigsetmask (0); /* simpleinit(8) blocks all signals: undo for ALRM */
- for (i = 1; i < NSIG; i++) signal (i, SIG_DFL);
-
- setlocale(LC_ALL, "");
- bindtextdomain(PACKAGE, LOCALEDIR);
- textdomain(PACKAGE);
-
-#ifndef DEBUGGING
- if(setreuid (0, 0)) {
- fprintf(stderr, _("%s: Only root can shut a system down.\n"),
- argv[0]);
- exit(1);
- }
-#endif
-
- 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;
- opt_fast = 0;
- timeout = 0;
- } else if(!strcmp("fasthalt", prog)) {
- opt_reboot = 0;
- opt_quiet = 1;
- opt_fast = 1;
- timeout = 0;
- } else if(!strcmp("reboot", prog)) {
- opt_reboot = 1;
- opt_quiet = 1;
- opt_fast = 0;
- timeout = 0;
- } else if(!strcmp("fastboot", prog)) {
- opt_reboot = 1;
- opt_quiet = 1;
- opt_fast = 1;
- timeout = 0;
- } 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++) {
- switch(argv[c][i]) {
- 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();
- }
- }
- } 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();
-
- (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 {
- xstrncpy(message, argv[c], sizeof(message));
- 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 = strchr(line, '\n');
- if (p)
- *p = 0; /* strip final '\n' */
- p = line+11;
- while(iswhitespace(*p))
- p++;
- strcpy(halt_action, p);
- }
- fclose (fp);
- }
- }
-
- if(!opt_quiet && !opt_msgset) {
- /* now ask for message, gets() is insecure */
- int cnt = sizeof(message)-1;
- char *ptr;
-
- printf("Why? "); fflush(stdout);
-
- ptr = message;
- while(--cnt >= 0 && (*ptr = getchar()) && *ptr != '\n') {
- ptr++;
- }
- *ptr = '\0';
- } else if (!opt_msgset) {
- strcpy(message, _("for maintenance; bounce, bounce"));
- }
-
-#ifdef DEBUGGING
- printf("timeout = %d, quiet = %d, reboot = %d\n",
- timeout, opt_quiet, opt_reboot);
-#endif
-
- /* so much for option-processing, now begin termination... */
- if(!(whom = getlogin()) || !*whom) whom = "ghost";
- if(strlen(whom) > 40) whom[40] = 0; /* see write_user() */
-
- setpriority(PRIO_PROCESS, 0, PRIO_MIN);
- signal(SIGINT, int_handler);
- signal(SIGHUP, int_handler);
- signal(SIGQUIT, int_handler);
- signal(SIGTERM, int_handler);
-
- chdir("/");
-
- if(timeout > 5*60) {
- sleep(timeout - 5*60);
- timeout = 5*60;
- }
-
-
- if((fd = open(_PATH_NOLOGIN, O_WRONLY|O_CREAT, 0644)) >= 0) {
- /* keep xgettext happy and leave \r\n outside strings */
- WRCRLF;
- WR(_("The system is being shut down within 5 minutes"));
- WRCRLF;
- write(fd, message, strlen(message));
- WRCRLF;
- WR(_("Login is therefore prohibited."));
- WRCRLF;
- close(fd);
- }
-
- signal(SIGPIPE, SIG_IGN);
-
- if(timeout > 0) {
- wall();
- sleep(timeout);
- }
-
- timeout = 0;
- wall();
- sleep(3);
-
- /* now there's no turning back... */
- signal(SIGINT, SIG_IGN);
-
- /* do syslog message... */
- openlog(prog, LOG_CONS, LOG_AUTH);
- if (opt_reboot)
- syslog(LOG_NOTICE, _("rebooted by %s: %s"),
- whom, message);
- else
- syslog(LOG_NOTICE, _("halted by %s: %s"),
- whom, message);
- closelog();
-
- if(opt_fast)
- if((fd = open("/fastboot", O_WRONLY|O_CREAT, 0644)) >= 0)
- close(fd);
-
- kill(1, SIGTSTP); /* tell init not to spawn more getty's */
- write_wtmp();
- if(opt_single)
- if((fd = open(_PATH_SINGLE, O_CREAT|O_WRONLY, 0644)) >= 0)
- close(fd);
-
- sync();
-
- signal(SIGTERM, SIG_IGN);
- if(fork() > 0) sleep(1000); /* the parent will die soon... */
- setpgrp(); /* so the shell wont kill us in the fall */
-
-#ifndef DEBUGGING
- /* a gentle kill of all other processes except init */
- kill_mortals (SIGTERM);
- for (fd = 0; fd < 3; fd++) close (fd);
- stop_finalprog ();
- sleep (1); /* Time for saves to start */
- kill (1, SIGTERM); /* Tell init to kill spawned gettys */
- usleep (100000); /* Wait for gettys to die */
- my_puts (""); /* Get past the login prompt */
- system ("/sbin/initctl -r"); /* Roll back services */
- syncwait (1);
- my_puts ("Sending SIGTERM to all remaining processes...");
- kill (-1, SIGTERM);
- sleep (2); /* Default 2, some people need 5 */
-
- kill (-1, SIGKILL); /* Now use brute force... */
-
- /* turn off accounting */
- acct(NULL);
-#endif
- /* RedHat and SuSE like to remove /etc/nologin.
- Perhaps the usual sequence is
- touch nologin; shutdown -h; fiddle with hardware;
- boot; fiddle with software; rm nologin
- and removing it here will be counterproductive.
- Let us see whether people complain. */
- unlink(_PATH_NOLOGIN);
-
- /* Tell init(8) to exec so that the old inode may be freed cleanly if
- required. Need to sleep before remounting root read-only */
- kill (1, SIGQUIT);
-
- sleep (1); /* Time for processes to die and close files */
- syncwait (2);
-
- /* remove swap files and partitions using swapoff */
- swap_off();
-
- /* unmount disks... */
- unmount_disks();
- syncwait (1);
-
- if(opt_reboot) {
- my_reboot(LINUX_REBOOT_CMD_RESTART); /* RB_AUTOBOOT */
- my_puts(_("\nWhy am I still alive after reboot?"));
- } else {
- my_puts(_("\nNow you can turn off the power..."));
-
- /* allow C-A-D now, faith@cs.unc.edu, re-fixed 8-Jul-96 */
- my_reboot(LINUX_REBOOT_CMD_CAD_ON); /* RB_ENABLE_CAD */
- sleep (1); /* Wait for devices to finish writing to media */
- do_halt(halt_action);
- }
- /* NOTREACHED */
- exit(0); /* to quiet gcc */
-}
-
-/*** 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;
- int minutes, hours;
- char term[40] = {'/','d','e','v','/',0};
- char msg[100];
-
- minutes = timeout / 60;
- hours = minutes / 60;
- minutes %= 60;
-
- (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_WRONLY|O_NONBLOCK)) < 0)
- return;
-
- msg[0] = '\007'; /* gettext crashes on \a */
- sprintf(msg+1, _("URGENT: broadcast message from %s:"), whom);
- WRCRLF;
- WR(msg);
- WRCRLF;
-
- if (hours > 1)
- sprintf(msg, _("System going down in %d hours %d minutes"),
- hours, minutes);
- else if (hours == 1)
- sprintf(msg, _("System going down in 1 hour %d minutes"),
- minutes);
- else if (minutes > 1)
- sprintf(msg, _("System going down in %d minutes\n"),
- minutes);
- else if (minutes == 1)
- sprintf(msg, _("System going down in 1 minute\n"));
- else
- sprintf(msg, _("System going down IMMEDIATELY!\n"));
-
- WR(msg);
- WRCRLF;
-
- sprintf(msg, _("\t... %s ...\n"), message);
- WR(msg);
- WRCRLF;
-
- close(fd);
-}
-
-void
-wall(void)
-{
- /* write to all users, that the system is going down. */
- struct utmp *ut;
-
- utmpname(_PATH_UTMP);
- setutent();
-
- while((ut = getutent())) {
- if(ut->ut_type == USER_PROCESS)
- write_user(ut);
- }
- endutent();
-}
-
-void
-write_wtmp(void)
-{
- /* write in wtmp that we are dying */
- int fd;
- struct utmp ut;
-
- memset((char *)&ut, 0, sizeof(ut));
- strcpy(ut.ut_line, "~");
- memcpy(ut.ut_name, "shutdown", sizeof(ut.ut_name));
-
- time(&ut.ut_time);
- ut.ut_type = BOOT_TIME;
-
- if((fd = open(_PATH_WTMP, O_WRONLY|O_APPEND, 0644)) >= 0) {
- write(fd, (char *)&ut, sizeof(ut));
- close(fd);
- }
-}
-
-void
-swap_off(void)
-{
- /* swapoff esp. swap FILES so the underlying partition can be
- unmounted. It you don't have swapoff(1) or use mount to
- add swapspace, this may not be necessary, but I guess it
- won't hurt */
-
- int pid;
- int result;
- int status;
-
- sync();
- if ((pid = fork()) < 0) {
- my_puts(_("Cannot fork for swapoff. Shrug!"));
- return;
- }
- if (!pid) {
- execl("/sbin/swapoff", SWAPOFF_ARGS, NULL);
- execl("/etc/swapoff", SWAPOFF_ARGS, NULL);
- execl("/bin/swapoff", SWAPOFF_ARGS, NULL);
- execlp("swapoff", SWAPOFF_ARGS, NULL);
- my_puts(_("Cannot exec swapoff, "
- "hoping umount will do the trick."));
- exit(0);
- }
- while ((result = wait(&status)) != -1 && result != pid)
- ;
-}
-
-void
-unmount_disks(void)
-{
- /* better to use umount directly because it may be smarter than us */
-
- int pid;
- int result;
- int status;
-
- sync();
- if ((pid = fork()) < 0) {
- my_puts(_("Cannot fork for umount, trying manually."));
- unmount_disks_ourselves();
- return;
- }
- if (!pid) {
- execl(_PATH_UMOUNT, UMOUNT_ARGS, NULL);
-
- /* need my_printf instead of my_puts here */
- freopen(_PATH_CONSOLE, "w", stdout);
- printf(_("Cannot exec %s, trying umount.\n"), _PATH_UMOUNT);
- fflush(stdout);
-
- execlp("umount", UMOUNT_ARGS, NULL);
- my_puts(_("Cannot exec umount, giving up on umount."));
- exit(0);
- }
- while ((result = wait(&status)) != -1 && result != pid)
- ;
- my_puts(_("Unmounting any remaining filesystems..."));
- unmount_disks_ourselves();
-}
-
-void
-unmount_disks_ourselves(void)
-{
- /* unmount all disks */
-
- FILE *mtab;
- struct mntent *mnt;
- char *mntlist[128];
- int i;
- int n;
- char *filesys;
-
- sync();
- if (!(mtab = setmntent(_PATH_MOUNTED, "r"))) {
- my_puts("shutdown: Cannot open " _PATH_MOUNTED ".");
- return;
- }
- n = 0;
- while (n < 100 && (mnt = getmntent(mtab))) {
- /*
- * Neil Phillips: trying to unmount temporary / kernel
- * filesystems is pointless and may cause error messages;
- * /dev can be a ramfs managed by udev.
- */
- if (strcmp(mnt->mnt_type, "devfs") == 0 ||
- strcmp(mnt->mnt_type, "proc") == 0 ||
- strcmp(mnt->mnt_type, "sysfs") == 0 ||
- strcmp(mnt->mnt_type, "ramfs") == 0 ||
- strcmp(mnt->mnt_type, "tmpfs") == 0 ||
- strcmp(mnt->mnt_type, "devpts") == 0)
- continue;
- mntlist[n++] = strdup(mnt->mnt_dir);
- }
- endmntent(mtab);
-
- /* we are careful to do this in reverse order of the mtab file */
-
- for (i = n - 1; i >= 0; i--) {
- filesys = mntlist[i];
-#ifdef DEBUGGING
- printf("umount %s\n", filesys);
-#else
- if (umount(mntlist[i]) < 0)
- printf(_("shutdown: Couldn't umount %s: %s\n"),
- filesys, ERRSTRING);
-#endif
- }
-}
-
-static void kill_mortals (int sig)
-{
- int npids = 0;
- int index = 0;
- int pid;
- struct stat statbuf;
- DIR *dp;
- struct dirent *de;
- pid_t *pids = NULL;
- char path[256];
-
- if ( ( dp = opendir ("/proc") ) == NULL ) return;
- while ( ( de = readdir (dp) ) != NULL )
- {
- if ( !isdigit (de->d_name[0]) ) continue;
- pid = atoi (de->d_name);
- sprintf (path, "/proc/%d", pid);
- if (stat (path, &statbuf) != 0) continue;
- if (statbuf.st_uid < 100) continue;
- if (index <= npids)
- {
- pids = realloc (pids, npids + 16384);
- if (pids == NULL) return;
- npids += 16384;
- }
- pids[index++] = pid;
- }
- fputs ("Sending SIGTERM to mortals...", stderr);
- for (--index; index >= 0; --index) kill (pids[index], sig);
- free (pids);
- closedir (dp);
-} /* End Function kill_mortals */
-
-static void stop_finalprog (void)
-{
- char *p1, *p2;
- FILE *fp;
- char line[256];
-
- if ( ( fp = fopen (_PATH_INITTAB, "r") ) == NULL ) return;
- while (fgets (line, 256, fp) != NULL)
- {
- pid_t pid;
-
- line[strlen (line) - 1] = '\0';
- p1 = line;
- while ( isspace (*p1) ) ++p1;
- if (strncmp (p1, "finalprog", 9) != 0) continue;
- if ( ( p1 = strchr (p1 + 9, '=') ) == NULL ) continue;
- for (++p1; isspace (*p1); ++p1);
- if (*p1 == '\0') continue;
- for (p2 = p1; !isspace (*p2); ++p2);
- *p2 = '\0';
- switch ( pid = fork () )
- {
- case 0: /* Child */
- execl (p1, p1, "stop", NULL);
- break;
- case -1: /* Error */
- break;
- default: /* Parent */
- waitpid (pid, NULL, 0);
- break;
- }
- fclose (fp);
- return;
- }
- fclose (fp);
-} /* End Function stop_finalprog */
-
-static void syncwait (int timeval)
-{
- static int do_wait = 0;
- static int first_time = 1;
-
- sync ();
- /* Kernel version 1.3.20 and after are supposed to wait automatically */
- if (first_time)
- {
- struct utsname uts;
-
- first_time = 0;
- uname (&uts);
- if (uts.release[0] < '2') do_wait = 1;
- }
- if (do_wait) sleep (timeval);
-} /* End Function syncwait */
diff --git a/login-utils/simpleinit.8 b/login-utils/simpleinit.8
deleted file mode 100644
index cbaf093b..00000000
--- a/login-utils/simpleinit.8
+++ /dev/null
@@ -1,180 +0,0 @@
-.\" Copyright 1992, 1993 Rickard E. Faith (faith@cs.unc.edu)
-.\" May be distributed under the GNU General Public License
-.\" " for emacs's hilit19 mode :-)
-.TH SIMPLEINIT 8 "25 February 2001" "Linux 0.99" "Linux Programmer's Manual"
-.SH NAME
-simpleinit \- process control initialization
-.SH SYNOPSIS
-.B init
-.RB [ single ]
-.RI [ script ]
-.SH DESCRIPTION
-.B init
-is invoked as the last step in the Linux boot sequence. If the
-.B single
-option is used, or if the file
-.I /etc/singleboot
-exists, then single user mode will be entered, by starting
-.IR /bin/sh .
-If the file
-.I /etc/securesingle
-exists, then the root password will be required to start single user mode.
-If the root password does not exist, or if
-.I /etc/passwd
-does not exist, the checking of the password will be skipped.
-
-If the file
-.I /etc/TZ
-exists, then the contents of that file will be read, and used to set the TZ
-environment variable for each process started by
-.BR simpleinit .
-This "feature" is only available if it's configured at compile-time. It's
-not normally needed.
-
-After single user mode is terminated, the
-.I /etc/rc
-file is executed, and the information in
-.I /etc/inittab
-will be used to start processes. Alternatively, the \fI/etc/inittab\fP
-file may be configured to run a different boot script. See below for
-details.
-
-.SH "THE INITTAB FILE"
-Because of the number of init programs which are appearing in the Linux
-community, the documentation for the
-.I /etc/inittab
-file, which is usually found with the
-.BR inittab (5)
-man page, is presented here:
-
-The format is
-
-.RS
-.B bootprog=file
-
-.B fileprefix=string
-
-.B PATH=search path
-
-.B INIT_PATH=search path
-
-.B "ttyline:termcap-entry:getty-command"
-
-.B finalprog=path
-.RE
-
-An example is as follows:
-
-.nf
-.RS
-bootprog =
-fileprefix = /sbin/init.d/
-PATH = /usr/sbin:/usr/bin:/sbin:/bin
-INIT_PATH = /sbin/init.d
-
-tty1:linux:/sbin/getty 9600 tty1
-tty2:linux:/sbin/getty 9600 tty2
-tty3:linux:/sbin/getty 9600 tty3
-tty4:linux:/sbin/getty 9600 tty4
-# tty5:linux:/sbin/getty 9600 tty5
-# ttyS1:dumb:/sbin/getty 9600 ttyS1
-# ttyS2:dumb:/sbin/getty -m -t60 2400 ttyS2
-
-finalprog = /sbin/rc.xdm
-.RE
-.fi
-
-Lines beginning with the
-.B #
-character are treated as comments. Please see documentation for the
-.BR getty (8)
-command that you are using, since there are several of these in the Linux
-community at this time.
-
-The \fBbootprog\fP value is appended to the \fBfileprefix\fP value,
-and the result specifies the boot programme (script) to run. If
-unspecified, the default is \fI/etc/rc\fP. If the boot programme is a
-directory, then all scripts in that directory tree are executed, in
-parallel. See the \fBneed\fP(8) programme for details on how to
-elegantly control order of execution and manage dependencies.
-
-The \fBPATH\fP value is assigned to the PATH environment variable of
-child processes (boot scripts).
-
-The \fBINIT_PATH\fP value is used by simpleinit(8) itself to find the
-location of scripts to run (if an absolute path is not given). If
-unset and the boot programme is a directory, that directory is used.
-Finally, if the script cannot be found in this path, the standard
-\fBPATH\fP is used. This separation allows boot scripts to invoke
-programmes of the same name without conflict and without needing to
-specify absolute paths.
-
-The \fBfinalprog\fP value specifies the path of the programme to run
-after all \fBgetty\fP(8) instances are spawned. At bootup, it is
-passed a single argument: "start". At shutdown, it is called again,
-this time with the argument: "stop".
-.SH SIGNALS
-\fBsimpleinit\fP(8) responds to signals in a variety of ways:
-.TP
-.B SIGHUP
-The \fI/etc/inittab\fP configuration file will be read again.
-.TP
-.B SIGTSTP
-This flips a toggle, which controls whether more processes will be
-spawned.
-.TP
-.B SIGINT
-\fBsimpleinit\fP(8) will sync a few times, and try to start
-\fBreboot\fP(8). Failing this, it will execute the system
-\fBreboot\fP(2) call. Under Linux, it is possible to configure the
-Ctrl-Alt-Del sequence to send a signal to the \fBinit\fP process
-instead of rebooting the system (\fBsimpleinit\fP(8) does this by
-default).
-.TP
-.B SIGQUIT
-The \fBreboot\fP(8) programme is executed in place of the
-\fBsimpleinit\fP(8) programme. This allows \fBreboot\fP(8) to cleanly
-remount (read-only) the root filesystem, even if the old inode for the
-\fBinit\fP process was unlinked.
-.SH FILES
-.I /etc/inittab
-.br
-.I /etc/singleboot
-.br
-.I /etc/securesingle
-.br
-.I /etc/TZ
-.br
-.I /etc/passwd
-.br
-.I /etc/rc
-.SH "SEE ALSO"
-.BR inittab (5),
-.BR ctrlaltdel (8)
-.BR reboot (8),
-.BR termcap (5),
-.BR getty (8),
-.BR agetty (8),
-.BR shutdown (8),
-.BR initctl (8)
-.SH BUGS
-This program is called
-.B simpleinit
-to distinguish it from the System V compatible versions of init which are
-starting to appear in the Linux community.
-.B simpleinit
-should be linked to, or made identical with,
-.I init
-for correct functionality.
-.SH AUTHOR
-Peter Orbaek (poe@daimi.aau.dk)
-.br
-Version 1.20, with patches for singleuser mode by Werner Almesberger
-.br
-Richard Gooch <rgooch@atnf.csiro.au>
-.br
-Dependency support
-
-.SH AVAILABILITY
-The simpleinit command is part of the util-linux-ng package and is available from
-ftp://ftp.kernel.org/pub/linux/utils/util-linux-ng/.
diff --git a/login-utils/simpleinit.c b/login-utils/simpleinit.c
deleted file mode 100644
index 8cff848c..00000000
--- a/login-utils/simpleinit.c
+++ /dev/null
@@ -1,1246 +0,0 @@
-/* simpleinit.c - poe@daimi.aau.dk */
-/* Version 2.0.2 */
-
-/* 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL>
- * - added Native Language Support
- * 2001-01-25 Richard Gooch <rgooch@atnf.csiro.au>
- * - fixed bug with failed services so they may be later "reclaimed"
- * 2001-02-02 Richard Gooch <rgooch@atnf.csiro.au>
- * - fixed race when reading from pipe and reaping children
- * 2001-02-18 sam@quux.dropbear.id.au
- * - fixed bug in <get_path>: multiple INIT_PATH components did not work
- * 2001-02-21 Richard Gooch <rgooch@atnf.csiro.au>
- * - block signals in handlers, so that longjmp() doesn't kill context
- * 2001-02-25 Richard Gooch <rgooch@atnf.csiro.au>
- * - make default INIT_PATH the boot_prog (if it is a directory) - YECCH
- * 2002-11-20 patch from SuSE
- * - refuse initctl_fd if setting FD_CLOEXEC fails
- */
-
-#include <sys/types.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <fcntl.h>
-#include <string.h>
-#include <signal.h>
-#include <errno.h>
-#include <time.h>
-#include <pwd.h>
-#include <sys/file.h>
-#include <sys/wait.h>
-#include <sys/stat.h>
-#include <sys/sysmacros.h>
-#include <sys/time.h>
-#include <sys/ioctl.h>
-#include <dirent.h>
-#include <termios.h>
-#include <utmp.h>
-#include <setjmp.h>
-#include <sched.h>
-#ifdef SHADOW_PWD
-# include <shadow.h>
-#endif
-#include "my_crypt.h"
-#include "pathnames.h"
-#include "linux_reboot.h"
-#include "xstrncpy.h"
-#include "nls.h"
-#include "simpleinit.h"
-
-#define CMDSIZ 150 /* max size of a line in inittab */
-#define NUMCMD 30 /* max number of lines in inittab */
-#define NUMTOK 20 /* max number of tokens in inittab command */
-#define PATH_SIZE (CMDSIZ+CMDSIZ+1)
-
-#define MAX_RESPAWN_RATE 5 /* number of respawns per 100 seconds */
-
-#define TZFILE "/etc/TZ"
-char tzone[CMDSIZ];
-/* #define DEBUGGING */
-
-/* Define this if you want init to ignore the termcap field in inittab for
- console ttys. */
-/* #define SPECIAL_CONSOLE_TERM */
-
-#define ever (;;)
-
-struct initline {
- pid_t pid;
- char tty[10];
- char termcap[30];
- char *toks[NUMTOK];
- char line[CMDSIZ];
- struct timeval last_start;
- signed long rate;
-};
-
-struct initline inittab[NUMCMD];
-int numcmd;
-int stopped = 0; /* are we stopped */
-static char boot_prog[PATH_SIZE] = _PATH_RC;
-static char script_prefix[PATH_SIZE] = "\0";
-static char final_prog[PATH_SIZE] = "\0";
-static char init_path[PATH_SIZE] = "\0";
-static int caught_sigint = 0;
-static int no_reboot = 0;
-static pid_t rc_child = -1;
-static const char *initctl_name = "/dev/initctl";
-static int initctl_fd = -1;
-static volatile int do_longjmp = 0;
-static sigjmp_buf jmp_env;
-
-
-static void do_single (void);
-static int do_rc_tty (const char *path);
-static int process_path (const char *path, int (*func) (const char *path),
- int ignore_dangling_symlink);
-static int preload_file (const char *path);
-static int run_file (const char *path);
-static void spawn (int i), read_inittab (void);
-static void sighup_handler (int sig);
-static void sigtstp_handler (int sig);
-static void sigint_handler (int sig);
-static void sigchild_handler (int sig);
-static void sigquit_handler (int sig);
-static void sigterm_handler (int sig);
-#ifdef SET_TZ
-static void set_tz (void);
-#endif
-static void write_wtmp (void);
-static pid_t mywait (int *status);
-static int run_command (const char *file, const char *name, pid_t pid);
-
-
-static void err (char *s)
-{
- int fd;
-
- if((fd = open("/dev/console", O_WRONLY)) < 0) return;
-
- write(fd, "init: ", 6);
- write(fd, s, strlen(s));
- close(fd);
-}
-
-static void enter_single (void)
-{
- pid_t pid;
- int i;
-
- err(_("Booting to single user mode.\n"));
- if((pid = fork()) == 0) {
- /* the child */
- execl(_PATH_BSHELL, _PATH_BSHELL, NULL);
- err(_("exec of single user shell failed\n"));
- } else if(pid > 0) {
- while (waitpid (pid, &i, 0) != pid) /* Nothing */;
- } else if(pid < 0) {
- err(_("fork of single user shell failed\n"));
- }
- unlink(_PATH_SINGLE);
-}
-
-int main(int argc, char *argv[])
-{
- int vec, i;
- int want_single = 0;
- pid_t pid;
- struct sigaction sa;
-
-
-#ifdef SET_TZ
- set_tz();
-#endif
- sigfillset (&sa.sa_mask); /* longjmp and nested signals don't mix */
- sa.sa_flags = SA_ONESHOT;
- sa.sa_handler = sigint_handler;
- sigaction (SIGINT, &sa, NULL);
- sa.sa_flags = 0;
- sa.sa_handler = sigtstp_handler;
- sigaction (SIGTSTP, &sa, NULL);
- sa.sa_handler = sigterm_handler;
- sigaction (SIGTERM, &sa, NULL);
- sa.sa_handler = sigchild_handler;
- sigaction (SIGCHLD, &sa, NULL);
- sa.sa_handler = sigquit_handler;
- sigaction (SIGQUIT, &sa, NULL);
-
- setlocale(LC_ALL, "");
- bindtextdomain(PACKAGE, LOCALEDIR);
- textdomain(PACKAGE);
-
- my_reboot (LINUX_REBOOT_CMD_CAD_OFF);
- /* Find script to run. Command-line overrides config file overrides
- built-in default */
- for (i = 0; i < NUMCMD; i++) inittab[i].pid = -1;
- read_inittab ();
- for (i = 1; i < argc; i++) {
- if (strcmp (argv[i], "single") == 0)
- want_single = 1;
- else if (strcmp (argv[i], "-noreboot") == 0)
- no_reboot = 1;
- else if (strlen(script_prefix) + strlen(argv[i]) < PATH_SIZE) {
- char path[PATH_SIZE];
-
- strcpy (path, script_prefix);
- strcat (path, argv[i]);
- if (access (path, R_OK | X_OK) == 0)
- strcpy (boot_prog, path);
- }
- }
- if (init_path[0] == '\0')
- {
- struct stat statbuf;
-
- if ( (stat (boot_prog, &statbuf) == 0) && S_ISDIR (statbuf.st_mode) )
- {
- strcpy (init_path, boot_prog);
- i = strlen (init_path);
- if (init_path[i - 1] == '/') init_path[i - 1] = '\0';
- }
- }
-
- if ( ( initctl_fd = open (initctl_name, O_RDWR, 0) ) < 0 ) {
- mkfifo (initctl_name, S_IRUSR | S_IWUSR);
- if ( ( initctl_fd = open (initctl_name, O_RDWR, 0) ) < 0 )
- err ( _("error opening fifo\n") );
- }
-
- if (initctl_fd >= 0 && fcntl(initctl_fd, F_SETFD, FD_CLOEXEC) != 0) {
- err ( _("error setting close-on-exec on /dev/initctl") );
-
- /* Can the fcntl ever fail? If it does, and we leave
- the descriptor open in child processes, then any
- process on the system will be able to write to
- /dev/initctl and have us execute arbitrary commands
- as root. So let's refuse to use the fifo in this case. */
-
- close(initctl_fd);
- initctl_fd = -1;
- }
-
- if ( want_single || (access (_PATH_SINGLE, R_OK) == 0) ) do_single ();
-
- /*If we get a SIGTSTP before multi-user mode, do nothing*/
- while (stopped)
- pause();
-
- if ( do_rc_tty (boot_prog) ) do_single ();
-
- while (stopped) /* Also if /etc/rc fails & we get SIGTSTP */
- pause();
-
- write_wtmp(); /* write boottime record */
-#ifdef DEBUGGING
- for(i = 0; i < numcmd; i++) {
- char **p;
- p = inittab[i].toks;
- printf("toks= %s %s %s %s\n",p[0], p[1], p[2], p[3]);
- printf("tty= %s\n", inittab[i].tty);
- printf("termcap= %s\n", inittab[i].termcap);
- }
- exit(0);
-#endif
- signal (SIGHUP, sighup_handler); /* Better semantics with signal(2) */
-
- for (i = 0; i < getdtablesize (); i++)
- if (i != initctl_fd) close (i);
-
- for(i = 0; i < numcmd; i++)
- spawn(i);
-
- if (final_prog[0] != '\0') {
- switch ( fork () )
- {
- case 0: /* Child */
- execl (final_prog, final_prog, "start", NULL);
- err ( _("error running finalprog\n") );
- _exit (1);
- break;
- case -1: /* Error */
- err ( _("error forking finalprog\n") );
- break;
- default: /* Parent */
- break;
- }
- }
-
- for ever {
- pid = mywait (&vec);
- if (pid < 1) continue;
-
- /* clear utmp entry, and append to wtmp if possible */
- {
- struct utmp *ut;
- int ut_fd, lf;
-
- utmpname(_PATH_UTMP);
- setutent();
- while((ut = getutent())) {
- if(ut->ut_pid == pid) {
- time(&ut->ut_time);
- memset(&ut->ut_user, 0, UT_NAMESIZE);
- memset(&ut->ut_host, 0, sizeof(ut->ut_host));
- ut->ut_type = DEAD_PROCESS;
- ut->ut_pid = 0;
- ut->ut_addr = 0;
- /*endutent();*/
- pututline(ut);
-
- if ((lf = open(_PATH_WTMPLOCK, O_CREAT|O_WRONLY, 0660)) >= 0) {
- flock(lf, LOCK_EX|LOCK_NB);
- if((ut_fd = open(_PATH_WTMP, O_APPEND|O_WRONLY)) >= 0) {
- write(ut_fd, ut, sizeof(struct utmp));
- close(ut_fd);
- }
- flock(lf, LOCK_UN|LOCK_NB);
- close(lf);
- }
- break;
- }
- }
- endutent();
- }
-
- for(i = 0; i < numcmd; i++) {
- if(pid == inittab[i].pid || inittab[i].pid < 0) {
- if (stopped)
- inittab[i].pid = -1;
- else
- spawn(i);
- if (pid == inittab[i].pid)
- break;
- }
- }
- }
-}
-
-#define MAXTRIES 3 /* number of tries allowed when giving the password */
-
-/*
- * return true if singleuser mode is allowed.
- * If /etc/securesingle exists ask for root password, otherwise always OK.
- */
-static int check_single_ok (void)
-{
- char *pass, *rootpass = NULL;
- struct passwd *pwd;
- int i;
-
- if (access (_PATH_SECURE, R_OK) != 0) return 1;
- if ( ( pwd = getpwnam ("root") ) || ( pwd = getpwuid (0) ) )
- rootpass = pwd->pw_passwd;
- else
- return 1; /* a bad /etc/passwd should not lock out */
-
- for (i = 0; i < MAXTRIES; i++)
- {
- pass = getpass (_("Password: "));
- if (pass == NULL) continue;
-
- if ( !strcmp (crypt (pass, rootpass), rootpass) ) return 1;
-
- puts (_("\nWrong password.\n"));
- }
- return 0;
-}
-
-static void do_single (void)
-{
- char path[PATH_SIZE];
-
- if (caught_sigint) return;
- strcpy (path, script_prefix);
- strcat (path, "single");
- if (access (path, R_OK | X_OK) == 0)
- if (do_rc_tty (path) == 0) return;
- if ( check_single_ok () ) enter_single ();
-} /* End Function do_single */
-
-/*
- * run boot script(s). The environment is passed to the script(s), so the RC
- * environment variable can be used to decide what to do.
- * RC may be set from LILO.
- * [RETURNS] 0 on success (exit status convention), otherwise error.
- */
-static int do_rc_tty (const char *path)
-{
- int status;
- pid_t pid;
- sigset_t ss;
-
- if (caught_sigint) return 0;
- process_path (path, preload_file, 0);
- /* Launch off a subprocess to start a new session (required for frobbing
- the TTY) and capture control-C */
- switch ( rc_child = fork () )
- {
- case 0: /* Child */
- for (status = 1; status < NSIG; status++) signal (status, SIG_DFL);
- sigfillset (&ss);
- sigprocmask (SIG_UNBLOCK, &ss, NULL);
- sigdelset (&ss, SIGINT);
- sigdelset (&ss, SIGQUIT);
- setsid ();
- ioctl (0, TIOCSCTTY, 0); /* I want my control-C */
- sigsuspend (&ss); /* Should never return, should just be killed */
- break; /* No-one else is controlled by this TTY now */
- case -1: /* Error */
- return (1);
- /*break;*/
- default: /* Parent */
- break;
- }
- /* Parent */
- process_path (path, run_file, 0);
- while (1)
- {
- if ( ( pid = mywait (&status) ) == rc_child )
- return (WTERMSIG (status) == SIGINT) ? 0 : 1;
- if (pid < 0) break;
- }
- kill (rc_child, SIGKILL);
- while (waitpid (rc_child, NULL, 0) != rc_child) /* Nothing */;
- return 0;
-} /* End Function do_rc_tty */
-
-static int process_path (const char *path, int (*func) (const char *path),
- int ignore_dangling_symlink)
-{
- struct stat statbuf;
- DIR *dp;
- struct dirent *de;
-
- if (lstat (path, &statbuf) != 0)
- {
- err (_("lstat of path failed\n") );
- return 1;
- }
- if ( S_ISLNK (statbuf.st_mode) )
- {
- if (stat (path, &statbuf) != 0)
- {
- if ( (errno == ENOENT) && ignore_dangling_symlink ) return 0;
- err (_("stat of path failed\n") );
- return 1;
- }
- }
- if ( !( statbuf.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH) ) ) return 0;
- if ( !S_ISDIR (statbuf.st_mode) ) return (*func) (path);
- if ( ( dp = opendir (path) ) == NULL )
- {
- err (_("open of directory failed\n") );
- return 1;
- }
- while ( ( de = readdir (dp) ) != NULL )
- {
- int retval;
- char newpath[PATH_SIZE];
-
- if (de->d_name[0] == '.') continue;
- retval = snprintf (newpath, sizeof(newpath), "%s/%s", path, de->d_name);
- if (newpath[retval - 1] == '~') continue; /* Common mistake */
- if ( ( retval = process_path (newpath, func, 1) ) ) return retval;
- }
- closedir (dp);
- return 0;
-} /* End Function process_path */
-
-static int preload_file (const char *path)
-{
- int fd;
- char ch;
-
- if ( ( fd = open (path, O_RDONLY, 0) ) < 0) return 0;
- while (read (fd, &ch, 1) == 1) lseek (fd, 1024, SEEK_CUR);
- close (fd);
- return 0;
-} /* End Function preload_file */
-
-static int run_file (const char *path)
-{
- const char *ptr;
-
- if ( ( ptr = strrchr ( (char *) path, '/' ) ) == NULL ) ptr = path;
- else ++ptr;
- return (run_command (path, ptr, 0) == SIG_FAILED) ? 1 : 0;
-} /* End Function run_file */
-
-static void spawn (int i)
-{
- pid_t pid;
- int j;
- signed long ds_taken;
- struct timeval ct;
-
- if (inittab[i].toks[0] == NULL) return;
-
- /* Check if respawning too fast */
- gettimeofday (&ct, NULL);
- ds_taken = ct.tv_sec - inittab[i].last_start.tv_sec;
-
- /* On the first iteration last_start==0 and ds_taken
- may be very large. Avoid overflow. -- Denis Vlasenko */
- if (ds_taken > 10000)
- ds_taken = 10000;
-
- ds_taken *= 10;
- ds_taken += (ct.tv_usec - inittab[i].last_start.tv_usec) / 100000;
- if (ds_taken < 1)
- ds_taken = 1;
- inittab[i].rate = (9 * inittab[i].rate + 1000 / ds_taken) / 10;
- if (inittab[i].rate > MAX_RESPAWN_RATE) {
- char txt[256];
-
- inittab[i].toks[0] = NULL;
- inittab[i].pid = -1;
- inittab[i].rate = 0;
- snprintf (txt, sizeof(txt),
- _("respawning: \"%s\" too fast: quenching entry\n"),
- inittab[i].tty);
- err (txt);
- return;
- }
-
- if((pid = fork()) < 0) {
- inittab[i].pid = -1;
- err(_("fork failed\n"));
- return;
- }
- if(pid) {
- /* this is the parent */
- inittab[i].pid = pid;
- inittab[i].last_start = ct;
- sched_yield ();
- return;
- } else {
- /* this is the child */
- char term[40];
-#ifdef SET_TZ
- char tz[CMDSIZ];
-#endif
- char *env[3];
-
- setsid();
- for(j = 0; j < getdtablesize(); j++)
- (void) close(j);
-
- snprintf(term, sizeof(term), "TERM=%s", inittab[i].termcap);
- env[0] = term;
- env[1] = (char *)0;
-#ifdef SET_TZ
- snprintf(tz, sizeof(tz), "TZ=%s", tzone);
- env[1] = tz;
-#endif
- env[2] = (char *)0;
-
- execve(inittab[i].toks[0], inittab[i].toks, env);
- err(_("exec failed\n"));
- sleep(5);
- _exit(1);
- }
-}
-
-static void read_inittab (void)
-{
- FILE *f;
- char buf[CMDSIZ];
- int i,j,k;
- int has_prog = 0;
- char *ptr, *getty;
- char prog[PATH_SIZE];
-#ifdef SPECIAL_CONSOLE_TERM
- char tty[50];
- struct stat stb;
-#endif
- char *termenv;
-
- termenv = getenv("TERM"); /* set by kernel */
- /* termenv = "vt100"; */
-
- if(!(f = fopen(_PATH_INITTAB, "r"))) {
- err(_("cannot open inittab\n"));
- return;
- }
-
- prog[0] = '\0';
- i = 0;
- while(!feof(f) && i < NUMCMD - 2) {
- if(fgets(buf, CMDSIZ - 1, f) == 0) break;
- buf[CMDSIZ-1] = 0;
-
- for(k = 0; k < CMDSIZ && buf[k]; k++) {
- if ((buf[k] == '#') || (buf[k] == '\n')) {
- buf[k] = 0; break;
- }
- }
-
- if(buf[0] == 0 || buf[0] == '\n') continue;
- ptr = strchr (buf, '=');
- if (ptr) {
- ptr++;
- if ( !strncmp (buf, "bootprog", 8) ) {
- while ( isspace (*ptr) ) ++ptr;
- strcpy (prog, ptr);
- has_prog = 1;
- continue;
- }
- if ( !strncmp (buf, "fileprefix", 10) ) {
- while ( isspace (*ptr) ) ++ptr;
- strcpy (script_prefix, ptr);
- continue;
- }
- if ( !strncmp (buf, "PATH", 4) ) {
- while ( isspace (*ptr) ) ++ptr;
- setenv ("PATH", ptr, 1);
- continue;
- }
- if ( !strncmp (buf, "INIT_PATH", 9) ) {
- while ( isspace (*ptr) ) ++ptr;
- strcpy (init_path, ptr);
- continue;
- }
- if ( !strncmp (buf, "finalprog", 8) ) {
- while ( isspace (*ptr) ) ++ptr;
- strcpy (final_prog, ptr);
- continue;
- }
- }
-
-
- (void) strcpy(inittab[i].line, buf);
-
- (void) strtok(inittab[i].line, ":");
- xstrncpy(inittab[i].tty, inittab[i].line, 10);
- xstrncpy(inittab[i].termcap, strtok((char *)0, ":"), 30);
-
- getty = strtok((char *)0, ":");
- (void) strtok(getty, " \t\n");
- inittab[i].toks[0] = getty;
- j = 1;
- while((ptr = strtok((char *)0, " \t\n")))
- inittab[i].toks[j++] = ptr;
- inittab[i].toks[j] = (char *)0;
-
-#ifdef SPECIAL_CONSOLE_TERM
- /* special-case termcap for the console ttys */
- snprintf(tty, sizeof(tty), "/dev/%s", inittab[i].tty);
- if(!termenv || stat(tty, &stb) < 0) {
- err(_("no TERM or cannot stat tty\n"));
- } else {
- /* is it a console tty? */
- if(major(stb.st_rdev) == 4 && minor(stb.st_rdev) < 64)
- xstrncpy(inittab[i].termcap, termenv, 30);
- }
-#endif
-
- i++;
- }
- fclose(f);
- numcmd = i;
- if (has_prog) {
- int len;
- char path[PATH_SIZE];
-
- strcpy (path, script_prefix);
- strcat (path, prog);
- len = strlen (path);
- if (path[len - 1] == '/') path[len - 1] = '\0';
- if (access (path, R_OK | X_OK) == 0)
- strcpy (boot_prog, path);
- }
-} /* End Function read_inittab */
-
-static void sighup_handler (int sig)
-{
- int i,j;
- int oldnum;
- struct initline savetab[NUMCMD];
- int had_already;
-
- signal (SIGHUP, SIG_IGN);
- memcpy(savetab, inittab, NUMCMD * sizeof(struct initline));
- oldnum = numcmd;
- read_inittab ();
-
- for(i = 0; i < numcmd; i++) {
- had_already = 0;
- for(j = 0; j < oldnum; j++) {
- if(!strcmp(savetab[j].tty, inittab[i].tty)) {
- had_already = 1;
- if((inittab[i].pid = savetab[j].pid) < 0)
- spawn(i);
- }
- }
- if (!had_already) spawn (i);
- }
- signal (SIGHUP, sighup_handler);
-} /* End Function sighup_handler */
-
-static void sigtstp_handler (int sig)
-{
- stopped = ~stopped;
- if (!stopped) sighup_handler (sig);
-} /* End Function sigtstp_handler */
-
-static void sigterm_handler (int sig)
-{
- int i;
-
- for (i = 0; i < numcmd; i++)
- if (inittab[i].pid > 0) kill (inittab[i].pid, SIGTERM);
-} /* End Function sigterm_handler */
-
-static void sigint_handler (int sig)
-{
- pid_t pid;
-
- caught_sigint = 1;
- kill (rc_child, SIGKILL);
- if (no_reboot) _exit (1) /*kill (0, SIGKILL)*/;
- sync ();
- sync ();
- pid = fork ();
- if (pid > 0) return; /* Parent */
- if (pid == 0) /* Child: reboot properly... */
- execl (_PATH_REBOOT, _PATH_REBOOT, (char *) 0);
-
- /* fork or exec failed, try the hard way... */
- my_reboot (LINUX_REBOOT_CMD_RESTART);
-} /* End Function sigint_handler */
-
-static void sigchild_handler (int sig)
-{
- if (!do_longjmp) return;
- siglongjmp (jmp_env, 1);
-}
-
-static void sigquit_handler (int sig)
-{
- execl (_PATH_REBOOT, _PATH_REBOOT, NULL); /* It knows pid=1 must sleep */
-}
-
-#ifdef SET_TZ
-static void set_tz (void)
-{
- FILE *f;
- int len;
-
- if((f=fopen(TZFILE, "r")) == (FILE *)NULL) return;
- fgets(tzone, CMDSIZ-2, f);
- fclose(f);
- if((len=strlen(tzone)) < 2) return;
- tzone[len-1] = 0; /* get rid of the '\n' */
- setenv("TZ", tzone, 0);
-}
-#endif
-
-static void write_wtmp (void)
-{
- int fd, lf;
- struct utmp ut;
-
- memset((char *)&ut, 0, sizeof(ut));
- strcpy(ut.ut_line, "~");
- memset(ut.ut_name, 0, sizeof(ut.ut_name));
- time(&ut.ut_time);
- ut.ut_type = BOOT_TIME;
-
- if ((lf = open(_PATH_WTMPLOCK, O_CREAT|O_WRONLY, 0660)) >= 0) {
- flock(lf, LOCK_EX|LOCK_NB); /* make sure init won't hang */
- if((fd = open(_PATH_WTMP, O_WRONLY|O_APPEND)) >= 0) {
- write(fd, (char *)&ut, sizeof(ut));
- close(fd);
- }
- flock(lf, LOCK_UN|LOCK_NB);
- close(lf);
- }
-} /* End Function write_wtmp */
-
-
-struct needer_struct
-{
- struct needer_struct *next;
- pid_t pid;
-};
-
-struct service_struct
-{
- struct service_struct *prev, *next; /* Script services chain */
- struct needer_struct *needers; /* Needers waiting for service */
- struct script_struct *attempting_providers;
- int failed; /* TRUE if attempting provider failed badly */
- char name[1];
-};
-
-struct script_struct
-{
- pid_t pid;
- struct script_struct *prev, *next; /* For the list */
- struct service_struct *first_service, *last_service; /*First is true name*/
- struct script_struct *next_attempting_provider; /* Provider chain */
-};
-
-struct list_head
-{
- struct script_struct *first, *last;
- unsigned int num_entries;
-};
-
-
-static struct list_head available_list = {NULL, NULL, 0};
-static struct list_head starting_list = {NULL, NULL, 0};
-static struct service_struct *unavailable_services = NULL; /* For needers */
-static int num_needers = 0;
-
-
-static int process_pidstat (pid_t pid, int status);
-static void process_command (const struct command_struct *command);
-static struct service_struct *find_service_in_list (const char *name,
- struct service_struct *sv);
-static struct script_struct *find_script_byname
- (const char *name,struct list_head *head, struct service_struct **service);
-static struct script_struct *find_script_bypid (pid_t pid,
- struct list_head *head);
-static void insert_entry (struct list_head *head, struct script_struct *entry);
-static void remove_entry (struct list_head *head, struct script_struct *entry);
-static void signal_needers (struct service_struct *service, int sig);
-static void handle_nonworking (struct script_struct *script);
-static int force_progress (void);
-static void show_scripts (FILE *fp, const struct script_struct *script,
- const char *type);
-static const char *get_path (const char *file);
-
-
-static pid_t mywait (int *status)
-/* [RETURNS] The pid for a process to be reaped, 0 if no process is to be
- reaped, and less than 0 if the boot scripts appear to have finished.
-*/
-{
- pid_t pid;
- sigset_t ss;
- long buffer[COMMAND_SIZE / sizeof (long)];
- struct command_struct *command = (struct command_struct *) buffer;
-
- if (initctl_fd < 0) return wait (status);
- /* Some magic to avoid races which can result in lost signals */
- command->command = -1;
- if ( sigsetjmp (jmp_env, 1) )
- { /* Jump from signal handler */
- do_longjmp = 0;
- process_command (command);
- return 0;
- }
- sigemptyset (&ss); /* Block SIGCHLD so wait status cannot be lost */
- sigaddset (&ss, SIGCHLD);
- sigprocmask (SIG_BLOCK, &ss, NULL);
- if ( ( pid = waitpid (-1, status, WNOHANG) ) > 0 )
- {
- sigprocmask (SIG_UNBLOCK, &ss, NULL);
- return process_pidstat (pid, *status);
- }
- do_longjmp = 1; /* After this, SIGCHLD will cause a jump backwards */
- sigprocmask (SIG_UNBLOCK, &ss, NULL);
- read (initctl_fd, buffer, sizeof(buffer));
- do_longjmp = 0;
- process_command (command);
- return 0;
-} /* End Function mywait */
-
-static pid_t process_pidstat (pid_t pid, int status)
-/* [RETURNS] The pid for a process to be reaped, 0 if no process is to be
- reaped, and less than 0 if the boot scripts appear to have finished.
-*/
-{
- int failed;
- struct script_struct *script;
- struct service_struct *service;
-
- if ( ( script = find_script_bypid (pid, &starting_list) ) == NULL )
- return pid;
- remove_entry (&starting_list, script);
- if ( WIFEXITED (status) && (WEXITSTATUS (status) == 0) )
- {
- struct script_struct *provider;
-
- /* Notify needers and other providers */
- for (service = script->first_service; service != NULL;
- service = service->next)
- {
- signal_needers (service, SIG_PRESENT);
- for (provider = service->attempting_providers; provider != NULL;
- provider = provider->next_attempting_provider)
- kill (provider->pid, SIG_PRESENT);
- service->attempting_providers = NULL;
- }
- insert_entry (&available_list, script);
- return force_progress ();
- }
- failed = ( WIFEXITED (status) && (WEXITSTATUS (status) == 2) ) ? 0 : 1;
- for (service = script->first_service; service != NULL;
- service = service->next)
- service->failed = failed;
- handle_nonworking (script);
- return force_progress ();
-} /* End Function process_pidstat */
-
-static void process_command (const struct command_struct *command)
-{
- int ival;
- struct script_struct *script;
- struct service_struct *service;
-
- switch (command->command)
- {
- case COMMAND_TEST:
- kill (command->pid,
- (find_script_byname (command->name, &available_list,
- NULL) == NULL) ?
- SIG_NOT_PRESENT : SIG_PRESENT);
- break;
- case COMMAND_NEED:
- ival = run_command (command->name, command->name, command->pid);
- if (ival == 0)
- {
- ++num_needers;
- force_progress ();
- }
- else kill (command->pid, ival);
- break;
- case COMMAND_ROLLBACK:
- if (command->name[0] == '\0') script = NULL;
- else
- {
- if ( ( script = find_script_byname (command->name, &available_list,
- NULL) ) == NULL )
- {
- kill (command->pid, SIG_NOT_PRESENT);
- break;
- }
- }
- while (script != available_list.first)
- {
- pid_t pid;
- struct script_struct *victim = available_list.first;
- char txt[256];
-
- if ( ( pid = fork () ) == 0 ) /* Child */
- {
- for (ival = 1; ival < NSIG; ival++) signal (ival, SIG_DFL);
- open ("/dev/console", O_RDONLY, 0);
- open ("/dev/console", O_RDWR, 0);
- dup2 (1, 2);
- execlp (get_path (victim->first_service->name),
- victim->first_service->name, "stop", NULL);
- snprintf (txt, sizeof(txt),
- _("error at stopping service \"%s\"\n"),
- victim->first_service->name);
- err (txt);
- _exit (SIG_NOT_STOPPED);
- }
- else if (pid == -1) break; /* Error */
- else /* Parent */
- {
- while (waitpid (pid, &ival, 0) != pid) /* Nothing */;
- if ( WIFEXITED (ival) && (WEXITSTATUS (ival) == 0) )
- {
- snprintf (txt, sizeof(txt),
- _("Stopped service: %s\n"),
- victim->first_service->name);
- remove_entry (&available_list, victim);
- free (victim);
- err (txt);
- }
- else break;
- }
- }
- kill (command->pid,
- (script ==available_list.first) ? SIG_STOPPED : SIG_NOT_STOPPED);
- break;
- case COMMAND_DUMP_LIST:
- if (fork () == 0) /* Do it in a child process so pid=1 doesn't block */
- {
- FILE *fp;
-
- if ( ( fp = fopen (command->name, "w") ) == NULL ) _exit (1);
- show_scripts (fp, available_list.first, "AVAILABLE");
- show_scripts (fp, starting_list.first, "STARTING");
- fputs ("UNAVAILABLE SERVICES:\n", fp);
- for (service = unavailable_services; service != NULL;
- service = service->next)
- fprintf (fp, "%s (%s)\n", service->name,
- service->failed ? "FAILED" : "not configured");
- fclose (fp);
- _exit (0);
- }
- break;
- case COMMAND_PROVIDE:
- /* Sanity check */
- if ( ( script = find_script_bypid (command->ppid, &starting_list) )
- == NULL )
- {
- kill (command->pid, SIG_NOT_CHILD);
- break;
- }
- if (find_script_byname (command->name, &available_list, NULL) != NULL)
- {
- kill (command->pid, SIG_PRESENT);
- break;
- }
- if (find_script_byname (command->name, &starting_list, &service)
- != NULL)
- { /* Someone else is trying to provide */
- script->next_attempting_provider = service->attempting_providers;
- service->attempting_providers = script;
- break;
- }
- if ( ( service = find_service_in_list (command->name,
- unavailable_services) )
- == NULL )
- { /* We're the first to try and provide: create it */
- if ( ( service =
- calloc (1, strlen (command->name) + sizeof *service) )
- == NULL )
- {
- kill (command->pid, SIG_NOT_CHILD);
- break;
- }
- strcpy (service->name, command->name);
- }
- else
- { /* Orphaned service: unhook and grab it */
- if (service->prev == NULL) unavailable_services = service->next;
- else service->prev->next = service->next;
- if (service->next != NULL) service->next->prev = service->prev;
- service->next = NULL;
- }
- service->prev = script->last_service;
- script->last_service->next = service;
- script->last_service = service;
- kill (command->pid, SIG_NOT_PRESENT);
- break;
- case -1:
- default:
- break;
- }
-} /* End Function process_command */
-
-static int run_command (const char *file, const char *name, pid_t pid)
-{
- struct script_struct *script;
- struct needer_struct *needer = NULL;
- struct service_struct *service;
-
- if (find_script_byname (name, &available_list, NULL) != NULL)
- return SIG_PRESENT;
- if (pid != 0)
- {
- needer = calloc (1, sizeof *needer);
- if (needer == NULL) return SIG_FAILED;
- needer->pid = pid;
- }
- script = find_script_byname (name, &starting_list, &service);
- if (script == NULL)
- service = find_service_in_list (name, unavailable_services);
- if (service == NULL)
- {
- int i;
- char txt[1024];
-
- if ( ( script = calloc (1, sizeof *script) ) == NULL )
- {
- free (needer);
- return SIG_FAILED;
- }
- service = calloc (1, strlen (name) + sizeof *service);
- if (service == NULL)
- {
- free (script);
- return SIG_FAILED;
- }
- strcpy (service->name, name);
- switch ( script->pid = fork () )
- {
- case 0: /* Child */
- for (i = 1; i < NSIG; i++) signal (i, SIG_DFL);
- execlp (get_path (file), service->name, "start", NULL);
- snprintf (txt, sizeof(txt),
- _("error at starting service \"%s\"\n"), service->name);
- err (txt);
- _exit (SIG_FAILED);
- break;
- case -1: /* Error */
- service->next = unavailable_services;
- if (unavailable_services != NULL)
- unavailable_services->prev = service;
- unavailable_services = service;
- free (script);
- free (needer);
- return SIG_FAILED;
- /*break;*/
- default: /* Parent */
- script->first_service = service;
- script->last_service = service;
- insert_entry (&starting_list, script);
- sched_yield ();
- break;
- }
- }
- if (needer == NULL) return 0;
- needer->next = service->needers;
- service->needers = needer;
- return 0;
-} /* End Function run_command */
-
-static struct service_struct *find_service_in_list (const char *name,
- struct service_struct *sv)
-{
- for (; sv != NULL; sv = sv->next)
- if (strcmp (sv->name, name) == 0) return (sv);
- return NULL;
-} /* End Function find_service_in_list */
-
-static struct script_struct *find_script_byname (const char *name,
- struct list_head *head,
- struct service_struct **service)
-{
- struct script_struct *script;
-
- for (script = head->first; script != NULL; script = script->next)
- {
- struct service_struct *sv;
-
- if ( ( sv = find_service_in_list (name, script->first_service) )
- != NULL )
- {
- if (service != NULL) *service = sv;
- return (script);
- }
- }
- if (service != NULL) *service = NULL;
- return NULL;
-} /* End Function find_script_byname */
-
-static struct script_struct *find_script_bypid (pid_t pid,
- struct list_head *head)
-{
- struct script_struct *script;
-
- for (script = head->first; script != NULL; script = script->next)
- if (script->pid == pid) return (script);
- return NULL;
-} /* End Function find_script_bypid */
-
-static void insert_entry (struct list_head *head, struct script_struct *entry)
-{
- if (entry == NULL) return;
- entry->prev = NULL;
- entry->next = head->first;
- if (head->first != NULL) head->first->prev = entry;
- head->first = entry;
- if (head->last == NULL) head->last = entry;
- ++head->num_entries;
-} /* End Function insert_entry */
-
-static void remove_entry (struct list_head *head, struct script_struct *entry)
-{
- if (entry->prev == NULL) head->first = entry->next;
- else entry->prev->next = entry->next;
- if (entry->next == NULL) head->last = entry->prev;
- else entry->next->prev = entry->prev;
- --head->num_entries;
-} /* End Function remove_entry */
-
-static void signal_needers (struct service_struct *service, int sig)
-{
- struct needer_struct *needer, *next_needer;
-
- for (needer = service->needers; needer != NULL; needer = next_needer)
- {
- kill (needer->pid, sig);
- next_needer = needer->next;
- free (needer);
- --num_needers;
- }
- service->needers = NULL;
-} /* End Function signal_needers */
-
-static void handle_nonworking (struct script_struct *script)
-{
- struct service_struct *service, *next;
-
- for (service = script->first_service; service != NULL; service = next)
- {
- struct script_struct *provider = service->attempting_providers;
-
- next = service->next;
- if (provider == NULL)
- {
- service->prev = NULL;
- service->next = unavailable_services;
- if (unavailable_services != NULL)
- unavailable_services->prev = service;
- unavailable_services = service;
- continue;
- }
- service->attempting_providers = provider->next_attempting_provider;
- provider->last_service->next = service;
- service->prev = provider->last_service;
- provider->last_service = service;
- service->next = NULL;
- kill (provider->pid, SIG_NOT_PRESENT);
- }
- free (script);
-} /* End Function handle_nonworking */
-
-static int force_progress (void)
-/* [RETURNS] 0 if boot scripts are still running, else -1.
-*/
-{
- struct service_struct *service;
-
- if (starting_list.num_entries > num_needers) return 0;
- /* No progress can be made: signal needers */
- for (service = unavailable_services; service != NULL;
- service = service->next)
- signal_needers (service,
- service->failed ? SIG_FAILED : SIG_NOT_PRESENT);
- return (starting_list.num_entries < 1) ? -1 : 0;
-} /* End Function force_progress */
-
-static void show_scripts (FILE *fp, const struct script_struct *script,
- const char *type)
-{
- fprintf (fp, "%s SERVICES:\n", type);
- for (; script != NULL; script = script->next)
- {
- struct service_struct *service = script->first_service;
-
- fputs (service->name, fp);
- for (service = service->next; service != NULL; service = service->next)
- fprintf (fp, " (%s)", service->name);
- putc ('\n', fp);
- }
-} /* End Function show_scripts */
-
-static const char *get_path (const char *file)
-{
- char *p1, *p2;
- static char path[PATH_SIZE];
-
- if (file[0] == '/') return file;
- if (init_path[0] == '\0') return file;
- for (p1 = init_path; *p1 != '\0'; p1 = p2)
- {
- if ( ( p2 = strchr (p1, ':') ) == NULL )
- p2 = p1 + strlen (p1);
- strncpy (path, p1, p2 - p1);
- path[p2 - p1] = '/';
- strcpy (path + (p2 - p1) + 1, file);
- if (*p2 == ':') ++p2;
- if (access (path, X_OK) == 0) return path;
- }
- return file;
-} /* End Function get_path */
diff --git a/login-utils/simpleinit.h b/login-utils/simpleinit.h
deleted file mode 100644
index 1d876297..00000000
--- a/login-utils/simpleinit.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#include <limits.h>
-#include <errno.h>
-
-
-#define ERRSTRING strerror (errno)
-#define COMMAND_SIZE (PIPE_BUF - 4)
-
-
-#define COMMAND_TEST 0 /* No wait, signal */
-#define COMMAND_NEED 1 /* Wait, signal */
-#define COMMAND_ROLLBACK 2 /* Wait, signal */
-#define COMMAND_DUMP_LIST 3 /* No wait, no signal */
-#define COMMAND_PROVIDE 4 /* Wait, signal */
-
-#define SIG_PRESENT SIGUSR1 /* Service is available */
-#define SIG_STOPPED SIGUSR1 /* Service was stopped OK */
-#define SIG_NOT_PRESENT SIGUSR2 /* Not present, but that's OK */
-#define SIG_FAILED SIGPOLL /* Startup failed */
-#define SIG_NOT_STOPPED SIGPOLL /* Failed to stop */
-#define SIG_NOT_CHILD SIGPOLL /* Not a child of init */
-
-struct command_struct /* Must always be COMMAND_SIZE */
-{
- signed int command;
- pid_t pid;
- pid_t ppid;
- char name[1];
-};
diff --git a/login-utils/vipw.8 b/login-utils/vipw.8
index e9886832..6ed482d5 100644
--- a/login-utils/vipw.8
+++ b/login-utils/vipw.8
@@ -82,5 +82,5 @@ The
.Nm vigr
command appeared in Util-Linux 2.6.
.Sh AVAILABILITY
-The vigr and vipw commands are part of the util-linux-ng package and are available from
-ftp://ftp.kernel.org/pub/linux/utils/util-linux-ng/.
+The vigr and vipw commands are part of the util-linux package and are available from
+ftp://ftp.kernel.org/pub/linux/utils/util-linux/.
diff --git a/login-utils/vipw.c b/login-utils/vipw.c
index b3972f3b..5750e6f9 100644
--- a/login-utils/vipw.c
+++ b/login-utils/vipw.c
@@ -60,11 +60,12 @@ static char version_string[] = "vipw 1.4";
#include <signal.h>
#include <fcntl.h>
#include <errno.h>
+#include <err.h>
#include <paths.h>
#include <unistd.h>
#include "setpwnam.h"
-#include "xstrncpy.h"
+#include "strutils.h"
#include "nls.h"
#ifdef HAVE_LIBSELINUX
@@ -86,7 +87,7 @@ static void
copyfile(int from, int to) {
int nr, nw, off;
char buf[8*1024];
-
+
while ((nr = read(from, buf, sizeof(buf))) > 0)
for (off = 0; off < nr; nr -= nw, off += nw)
if ((nw = write(to, buf + off, nr)) < 0)
@@ -131,7 +132,7 @@ static int
pw_lock(void) {
int lockfd, fd, ret;
- /*
+ /*
* If the password file doesn't exist, the system is hosed.
* Might as well try to build one. Set the close-on-exec bit so
* that users can't get at the encrypted passwords while editing.
@@ -149,16 +150,14 @@ pw_lock(void) {
}
#endif
- if ((fd = open(tmptmp_file, O_WRONLY|O_CREAT, 0600)) == -1) {
- (void)fprintf(stderr,
- "%s: %s: %s\n", progname, tmptmp_file, strerror(errno));
- exit(1);
- }
+ if ((fd = open(tmptmp_file, O_WRONLY|O_CREAT, 0600)) == -1)
+ err(EXIT_FAILURE, _("%s: open failed"), tmptmp_file);
+
ret = link(tmptmp_file, tmp_file);
(void)unlink(tmptmp_file);
if (ret == -1) {
if (errno == EEXIST)
- (void)fprintf(stderr,
+ (void)fprintf(stderr,
_("%s: the %s file is busy (%s present)\n"),
progname,
program == VIPW ? "password" : "group",
@@ -168,7 +167,7 @@ pw_lock(void) {
(void)fprintf(stderr, _("%s: can't link %s: %s\n"), progname,
tmp_file, strerror(errsv));
}
- exit(1);
+ exit(EXIT_FAILURE);
}
lockfd = open(orig_file, O_RDONLY, 0);
@@ -177,13 +176,13 @@ pw_lock(void) {
(void)fprintf(stderr, "%s: %s: %s\n",
progname, orig_file, strerror(errno));
unlink(tmp_file);
- exit(1);
+ exit(EXIT_FAILURE);
}
copyfile(lockfd, fd);
(void)close(lockfd);
(void)close(fd);
- return(1);
+ return 1;
}
static void
@@ -192,7 +191,9 @@ pw_unlock(void) {
sprintf(tmp, "%s%s", orig_file, ".OLD");
unlink(tmp);
- link(orig_file, tmp);
+
+ if (link(orig_file, tmp))
+ warn(_("%s: create a link to %s failed"), orig_file, tmp);
#ifdef HAVE_LIBSELINUX
if (is_selinux_enabled() > 0) {
@@ -213,10 +214,10 @@ pw_unlock(void) {
if (rename(tmp_file, orig_file) == -1) {
int errsv = errno;
- fprintf(stderr,
- _("%s: can't unlock %s: %s (your changes are still in %s)\n"),
+ fprintf(stderr,
+ _("%s: can't unlock %s: %s (your changes are still in %s)\n"),
progname, orig_file, strerror(errsv), tmp_file);
- exit(1);
+ exit(EXIT_FAILURE);
}
unlink(tmp_file);
}
@@ -236,17 +237,18 @@ pw_edit(int notsetuid) {
p = editor;
pid = fork();
- if (pid < 0) {
- (void)fprintf(stderr, _("%s: Cannot fork\n"), progname);
- exit(1);
- }
+ if (pid < 0)
+ err(EXIT_FAILURE, _("fork failed"));
+
if (!pid) {
if (notsetuid) {
(void)setgid(getgid());
(void)setuid(getuid());
}
execlp(editor, p, tmp_file, NULL);
- _exit(1);
+
+ /* Shouldn't get here */
+ _exit(EXIT_FAILURE);
}
for (;;) {
pid = waitpid(pid, &pstat, WUNTRACED);
@@ -325,10 +327,10 @@ int main(int argc, char *argv[]) {
xstrncpy(tmptmp_file, PTMPTMP_FILE, sizeof(tmptmp_file));
}
- if ((argc > 1) &&
+ if ((argc > 1) &&
(!strcmp(argv[1], "-V") || !strcmp(argv[1], "--version"))) {
printf("%s\n", version_string);
- exit(0);
+ exit(EXIT_SUCCESS);
}
edit_file(0);
@@ -358,5 +360,5 @@ int main(int argc, char *argv[]) {
}
}
- exit(0);
+ exit(EXIT_SUCCESS);
}
diff --git a/login-utils/wall.1 b/login-utils/wall.1
index a767c7d4..1f85c409 100644
--- a/login-utils/wall.1
+++ b/login-utils/wall.1
@@ -67,5 +67,5 @@ A
command appeared in
.At v7 .
.Sh AVAILABILITY
-The wall command is part of the util-linux-ng package and is available from
-ftp://ftp.kernel.org/pub/linux/utils/util-linux-ng/.
+The wall command is part of the util-linux package and is available from
+ftp://ftp.kernel.org/pub/linux/utils/util-linux/.
diff --git a/login-utils/wall.c b/login-utils/wall.c
index 7b5f6718..2ecce126 100644
--- a/login-utils/wall.c
+++ b/login-utils/wall.c
@@ -47,6 +47,8 @@
#include <sys/time.h>
#include <sys/uio.h>
+#include <err.h>
+#include <errno.h>
#include <paths.h>
#include <ctype.h>
#include <pwd.h>
@@ -58,7 +60,8 @@
#include <utmp.h>
#include "nls.h"
-#include "xstrncpy.h"
+#include "xalloc.h"
+#include "strutils.h"
#include "ttymsg.h"
#include "pathnames.h"
#include "carefulputc.h"
@@ -79,8 +82,6 @@ int nobanner;
int mbufsize;
char *mbuf;
-char *progname = "wall";
-
int
main(int argc, char **argv) {
extern int optind;
@@ -94,12 +95,7 @@ main(int argc, char **argv) {
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
- progname = argv[0];
- p = strrchr(progname, '/');
- if (p)
- progname = p+1;
-
- while ((ch = getopt(argc, argv, "n")) != -1)
+ while ((ch = getopt(argc, argv, "n")) != -1) {
switch (ch) {
case 'n':
/* undoc option for shutdown: suppress banner */
@@ -109,9 +105,11 @@ main(int argc, char **argv) {
case '?':
default:
usage:
- (void)fprintf(stderr, _("usage: %s [file]\n"), progname);
- exit(1);
+ fprintf(stderr, _("usage: %s [file]\n"),
+ program_invocation_short_name);
+ exit(EXIT_FAILURE);
}
+ }
argc -= optind;
argv += optind;
if (argc > 1)
@@ -141,10 +139,10 @@ usage:
xstrncpy(line, utmpptr->ut_line, sizeof(utmpptr->ut_line));
if ((p = ttymsg(&iov, 1, line, 60*5)) != NULL)
- (void)fprintf(stderr, "%s: %s\n", progname, p);
+ warnx("%s", p);
}
endutent();
- exit(0);
+ exit(EXIT_SUCCESS);
}
void
@@ -162,12 +160,11 @@ makemsg(fname)
lbuf[MAXHOSTNAMELEN + 320],
tmpname[sizeof(_PATH_TMP) + 20];
- (void)sprintf(tmpname, "%s/wall.XXXXXX", _PATH_TMP);
- if (!(fd = mkstemp(tmpname)) || !(fp = fdopen(fd, "r+"))) {
- (void)fprintf(stderr, _("%s: can't open temporary file.\n"), progname);
- exit(1);
- }
- (void)unlink(tmpname);
+ sprintf(tmpname, "%s/wall.XXXXXX", _PATH_TMP);
+ if (!(fd = mkstemp(tmpname)) || !(fp = fdopen(fd, "r+")))
+ errx(EXIT_FAILURE, _("can't open temporary file"));
+
+ unlink(tmpname);
if (!nobanner) {
if (!(whom = getlogin()) || !*whom)
@@ -177,8 +174,8 @@ makemsg(fname)
where = ttyname(2);
if (!where || strlen(where) > 100)
where = "somewhere";
- (void)gethostname(hostname, sizeof(hostname));
- (void)time(&now);
+ gethostname(hostname, sizeof(hostname));
+ time(&now);
lt = localtime(&now);
/*
@@ -190,15 +187,15 @@ makemsg(fname)
*/
/* snprintf is not always available, but the sprintf's here
will not overflow as long as %d takes at most 100 chars */
- (void)fprintf(fp, "\r%79s\r\n", " ");
- (void)sprintf(lbuf, _("Broadcast Message from %s@%s"),
+ fprintf(fp, "\r%79s\r\n", " ");
+ sprintf(lbuf, _("Broadcast Message from %s@%s"),
whom, hostname);
- (void)fprintf(fp, "%-79.79s\007\007\r\n", lbuf);
- (void)sprintf(lbuf, " (%s) at %d:%02d ...",
+ fprintf(fp, "%-79.79s\007\007\r\n", lbuf);
+ sprintf(lbuf, " (%s) at %d:%02d ...",
where, lt->tm_hour, lt->tm_min);
- (void)fprintf(fp, "%-79.79s\r\n", lbuf);
+ fprintf(fp, "%-79.79s\r\n", lbuf);
}
- (void)fprintf(fp, "%79s\r\n", " ");
+ fprintf(fp, "%79s\r\n", " ");
if (fname) {
/*
@@ -208,16 +205,12 @@ makemsg(fname)
* instead of "wall file".
*/
int uid = getuid();
- if (uid && (uid != geteuid() || getgid() != getegid())) {
- fprintf(stderr, _("%s: will not read %s - use stdin.\n"),
- progname, fname);
- exit(1);
- }
- if (!freopen(fname, "r", stdin)) {
- fprintf(stderr, _("%s: can't read %s.\n"),
- progname, fname);
- exit(1);
- }
+ if (uid && (uid != geteuid() || getgid() != getegid()))
+ errx(EXIT_FAILURE, _("will not read %s - use stdin."),
+ fname);
+
+ if (!freopen(fname, "r", stdin))
+ errx(EXIT_FAILURE, _("can't read %s."), fname);
}
while (fgets(lbuf, sizeof(lbuf), stdin)) {
@@ -236,19 +229,14 @@ makemsg(fname)
fprintf(fp, "%79s\r\n", " ");
rewind(fp);
- if (fstat(fd, &sbuf)) {
- fprintf(stderr, _("%s: can't stat temporary file.\n"),
- progname);
- exit(1);
- }
+ if (fstat(fd, &sbuf))
+ err(EXIT_FAILURE, _("fstat failed"));
+
mbufsize = sbuf.st_size;
- if (!(mbuf = malloc((u_int)mbufsize))) {
- (void)fprintf(stderr, _("%s: Out of memory!\n"), progname);
- exit(1);
- }
- if (fread(mbuf, sizeof(*mbuf), mbufsize, fp) != mbufsize) {
- (void)fprintf(stderr, _("%s: can't read temporary file.\n"), progname);
- exit(1);
- }
- (void)close(fd);
+ mbuf = xmalloc(mbufsize);
+
+ if (fread(mbuf, sizeof(*mbuf), mbufsize, fp) != mbufsize)
+ err(EXIT_FAILURE, _("fread failed"));
+
+ close(fd);
}