Merge branch '2.94'

This commit is contained in:
Jesse Smith 2019-02-19 19:22:15 -04:00
commit 25191ff9aa
16 changed files with 572 additions and 70 deletions

View File

@ -1,3 +1,40 @@
sysvinit (2.94) unreleased; urgency=low
[ Jesse Smith ]
* When the halt command is called with the -p flag (or as poweroff)
the command now passes the "-h -P" flags to shutdown. This
in turn sets the INIT_HALT environment variable to POWEROFF.
Assuming this value is checked by initscripts during the
shutting down procedure, it should cause the system to
be powered off.
If halt is called without -p then the value of INIT_HALT
is not set and the default action (often set in /etc/defaut/halt)
is taken.
* Removed unnecessary malloc.h includes. Memory allocation
and freeing is now handled in stdlib.h
* Added defines for FreeBSD to make some components compile
on FreeBSD 11.
* Increased the size of the kernel command line buffer in bootlogd
from 256 characters to 4096. This size is defined in KERNEL_COMMAND_LENGTH
for easy modification downstream.
* Added logsave.c and logsave.8 manual page from e2fsprogs to make
sure logsave is available to initscripts.
* Updated src/Makefile to make sure bootlogd compiles with Clang.
* Use defined constants for password length in sulogin. Makes
it easier to update/patch later.
* Minor code fixes across multiple source files to avoid buffer
overflows, or uninitialized strings.
* Changed the way the "when" variable is used internally in shutdown.c.
It starts as a NULL pointer, then might get set as a pointer to optarg,
then it might get set to point to an argv parameter, then it might have
a string value copied into it, over-writing the original data. We should
not risk over-writing internal variables which might get used for something
else (it's rude and security risk). Set up "when" as its own buffer
that has data from optargs and/or argv copied into it.
* Fixed typo in init.8 manual page.
sysvinit (2.93) released; urgency=low
[ Jesse Smith ]
@ -5,6 +42,10 @@ sysvinit (2.93) released; urgency=low
* Fixed typo in pidof which would prevent the -o (omit PID)
flag from working.
Fixes Debian bug ##913394.
* Fixed error where pidof would not omit checking PIDs passed
to it when the -o flag was used.
Fixes Debian bug #913394.
sysvinit (2.92) released; urgency=low

View File

@ -276,7 +276,7 @@ On receipt of this signals, init closes and re-opens its control fifo,
.TP 0.5i
.B SIGUSR2
When init receives SIGUSR2, init closes and leaves the control fifo,
\fB/run/initctl\f\P, closed. This may be used to make sure init is not
\fB/run/initctl\fP, closed. This may be used to make sure init is not
holding open any files. However, it also prevents init from switching
runlevels. Which means commands like shutdown no longer work.
The fifo can be re-opened by sending init the SIGUSR1 signal.

61
man/logsave.8 Normal file
View File

@ -0,0 +1,61 @@
.\" -*- nroff -*-
.\" Copyright 2003 by Theodore Ts'o. All Rights Reserved.
.\" This file may be copied under the terms of the GNU Public License.
.\"
.TH LOGSAVE 8 "@E2FSPROGS_MONTH@ @E2FSPROGS_YEAR@" "E2fsprogs version @E2FSPROGS_VERSION@"
.SH NAME
logsave \- save the output of a command in a logfile
.SH SYNOPSIS
.B logsave
[
.B \-asv
]
.I logfile cmd_prog [ ... ]
.SH DESCRIPTION
The
.B logsave
program will execute
.I cmd_prog
with the specified argument(s), and save a copy of its output to
.IR logfile .
If the containing directory for
.I logfile
does not exist,
.B logsave
will accumulate the output in memory until it can be written out.
A copy of the output will also be written to standard output.
.PP
If
.I cmd_prog
is a single hyphen ('-'), then instead of executing a program,
.B logsave
will take its input from standard input and save it in
.I logfile
.PP
.B logsave
is useful for saving the output of initial boot scripts
until the /var partition is mounted, so the output can be written to
/var/log.
.SH OPTIONS
.TP
.B \-a
This option will cause the output to be appended to
.IR logfile ,
instead of replacing its current contents.
.TP
.B \-s
This option will cause
.B logsave
to skip writing to the log file text which is bracketed with a control-A
(ASCII 001 or Start of Header) and control-B (ASCII 002 or Start of
Text). This allows progress bar information to be visible to the user
on the console, while not being written to the log file.
.TP
.B \-v
This option will make
.B logsave
to be more verbose in its output to the user.
.SH AUTHOR
Theodore Ts'o (tytso@mit.edu)
.SH SEE ALSO
.BR fsck (8)

View File

@ -23,13 +23,13 @@ MNTPOINT=
# For some known distributions we do not build all programs, otherwise we do.
BIN =
SBIN = init halt shutdown runlevel killall5 fstab-decode
SBIN = init halt shutdown runlevel killall5 fstab-decode logsave
USRBIN = last mesg readbootlog
MAN1 = last.1 lastb.1 mesg.1 readbootlog.1
MAN5 = initscript.5 inittab.5 initctl.5
MAN8 = halt.8 init.8 killall5.8 pidof.8 poweroff.8 reboot.8 runlevel.8
MAN8 += shutdown.8 telinit.8 fstab-decode.8
MAN8 += shutdown.8 telinit.8 fstab-decode.8 logsave.8
ifeq ($(DISTRO),)
SBIN += sulogin bootlogd
@ -115,6 +115,9 @@ halt: halt.o ifdown.o hddown.o utmp.o runlevellog.o
last: LDLIBS += $(STATIC)
last: last.o
logsave: LDLIBS += $(STATIC)
logsave: logsave.o
mesg: LDLIBS += $(STATIC)
mesg: mesg.o
@ -137,10 +140,10 @@ shutdown: LDLIBS += $(STATIC)
shutdown: dowall.o shutdown.o utmp.o
bootlogd: LDLIBS += -lutil $(STATIC)
bootlogd: bootlogd.o bootlogd.h
bootlogd: bootlogd.o
readbootlog: LDLIBS += $(STATIC)
readbootlog: readbootlog.o bootlogd.h
readbootlog: readbootlog.o
fstab-decode: LDLIBS += $(STATIC)
fstab-decode: fstab-decode.o
@ -151,7 +154,7 @@ sulogin.o: sulogin.c
runlevellog.o: runlevellog.h runlevellog.c paths.h
init.o: CPPFLAGS += $(SELINUX_DEF)
init.o: init.c init.h initreq.h paths.h reboot.h runlevellog.h runlevellog.c set.h paths.h
init.o: init.c init.h initreq.h paths.h reboot.h runlevellog.h runlevellog.c set.h
utmp.o:
@ -159,6 +162,10 @@ init_utmp.o: CPPFLAGS += -DINIT_MAIN
init_utmp.o: utmp.c init.h initreq.h paths.h
$(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
bootlogd.o: bootlogd.c bootlogd.h
readbootlog.o: readbootlog.c
utmpdump.o: utmpdump.c oldutmp.h
shutdown.o: shutdown.c paths.h reboot.h initreq.h init.h
@ -167,6 +174,8 @@ halt.o: halt.c reboot.h paths.h runlevellog.c runlevellog.h
last.o: last.c oldutmp.h
logsave.o: logsave.c
consoles.o: consoles.c consoles.h
cleanobjs:

View File

@ -24,12 +24,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* *NOTE* *NOTE* *NOTE*
* This is a PROOF OF CONCEPT IMPLEMENTATION
*
* I have bigger plans for Debian, but for now
* this has to do ;)
*
*/
#include <sys/types.h>
@ -40,7 +34,6 @@
#include <time.h>
#include <stdio.h>
#include <errno.h>
#include <malloc.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
@ -48,7 +41,15 @@
#include <getopt.h>
#include <dirent.h>
#include <fcntl.h>
#ifdef __linux__
#include <pty.h>
#endif
#ifdef __FreeBSD__
#include <termios.h>
#include <libutil.h>
#endif
#include <ctype.h>
#ifdef __linux__
#include <sys/mount.h>
@ -56,6 +57,7 @@
#include "bootlogd.h"
#define MAX_CONSOLES 16
#define KERNEL_COMMAND_LENGTH 4096
char ringbuf[32768];
char *endptr = ringbuf + sizeof(ringbuf);
@ -250,7 +252,7 @@ int consolenames(struct real_cons *cons, int max_consoles)
/* This appears to be unused. unsigned int kdev; */
#endif
struct stat st, st2;
char buf[256];
char buf[KERNEL_COMMAND_LENGTH];
char *p;
int didmount = 0;
int n;
@ -279,17 +281,14 @@ int consolenames(struct real_cons *cons, int max_consoles)
perror("bootlogd: /proc/cmdline");
} else {
buf[0] = 0;
if ((n = read(fd, buf, sizeof(buf) - 1)) < 0)
if ((n = read(fd, buf, KERNEL_COMMAND_LENGTH - 1)) < 0)
perror("bootlogd: /proc/cmdline");
close(fd);
}
if (didmount) umount("/proc");
if (n < 0) return 0;
/*
* OK, so find console= in /proc/cmdline.
* Parse in reverse, opening as we go.

View File

@ -155,13 +155,15 @@ int get_runlevel(void)
/*
* Switch to another runlevel.
*/
void do_shutdown(char *fl, char *tm)
void do_shutdown(char *fl, int should_poweroff, char *tm)
{
char *args[8];
char *args[9];
int i = 0;
args[i++] = "shutdown";
args[i++] = fl;
if ( (! strcmp(fl, "-h") ) && (should_poweroff) )
args[i++] = "-P";
if (tm) {
args[i++] = "-t";
args[i++] = tm;
@ -259,7 +261,7 @@ int main(int argc, char **argv)
*/
c = get_runlevel();
if (c != '0' && c != '6')
do_shutdown(do_reboot ? "-r" : "-h", tm);
do_shutdown(do_reboot ? "-r" : "-h", do_poweroff, tm);
}
/*

View File

@ -13,11 +13,12 @@
Version information is not placed in the top-level Makefile by default
*/
#ifndef VERSION
#define VERSION "2.91"
#define VERSION "2.94"
#endif
/*
* This file is part of the sysvinit suite,
* Copyright (C) 1991-2004 Miquel van Smoorenburg.
* Copyright (C) 2017-2019 Jesse Smith
*
* 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
@ -52,7 +53,11 @@ Version information is not placed in the top-level Makefile by default
#include <string.h>
#include <signal.h>
#include <termios.h>
#ifdef __FreeBSD__
#include <utmpx.h>
#else
#include <utmp.h>
#endif
#include <ctype.h>
#include <stdarg.h>
#include <sys/ttydefaults.h>
@ -62,6 +67,9 @@ Version information is not placed in the top-level Makefile by default
#ifdef WITH_SELINUX
# include <selinux/selinux.h>
#endif
#ifdef __FreeBSD__
extern char **environ;
#endif
#ifdef __i386__
# ifdef __GLIBC__
@ -133,7 +141,7 @@ int wrote_wtmp_reboot = 1; /* Set when we wrote the reboot record */
int wrote_utmp_reboot = 1; /* Set when we wrote the reboot record */
int wrote_wtmp_rlevel = 1; /* Set when we wrote the runlevel record */
int wrote_utmp_rlevel = 1; /* Set when we wrote the runlevel record */
int sltime = WAIT_BETWEEN_SIGNALS; /* Sleep time between TERM and KILL */
int sleep_time = WAIT_BETWEEN_SIGNALS; /* Sleep time between TERM and KILL */
char *argv0; /* First arguments; show up in ps listing */
int maxproclen; /* Maximal length of argv[0] with \0 */
struct utmp utproto; /* Only used for sizeof(utproto.ut_id) */
@ -144,7 +152,7 @@ int main(int, char **);
/* Used by re-exec part */
int reload = 0; /* Should we do initialization stuff? */
char *myname="/sbin/init"; /* What should we exec */
char *myname=INIT; /* What should we exec */
int oops_error; /* Used by some of the re-exec code. */
const char *Signature = "12567362"; /* Signature for re-exec fd */
@ -288,7 +296,7 @@ void send_state(int fd)
fprintf(fp, "-SI%u\n", got_signals);
fprintf(fp, "-WR%d\n", wrote_wtmp_reboot);
fprintf(fp, "-WU%d\n", wrote_utmp_reboot);
fprintf(fp, "-ST%d\n", sltime);
fprintf(fp, "-ST%d\n", sleep_time);
fprintf(fp, "-DB%d\n", did_boot);
for (p = family; p; p = p->next) {
@ -416,7 +424,7 @@ static CHILD *get_record(FILE *f)
}
break;
case D_SLTIME:
if (fscanf(f, "%d\n", &sltime) == EOF && errno != 0) {
if (fscanf(f, "%d\n", &sleep_time) == EOF && errno != 0) {
fprintf(stderr, "%s (%d): %s\n", __FILE__, __LINE__, strerror(errno));
}
break;
@ -521,8 +529,12 @@ int receive_state(int fd)
* Set the process title.
*/
#ifdef __GNUC__
#ifndef __FreeBSD__
__attribute__ ((format (printf, 1, 2)))
#endif
#endif
/* This function already exists on FreeBSD. No need to delcare it. */
#ifndef __FreeBSD__
static int setproctitle(char *fmt, ...)
{
va_list ap;
@ -542,6 +554,7 @@ static int setproctitle(char *fmt, ...)
return len;
}
#endif
/*
* Set console_dev to a working console.
@ -1705,7 +1718,7 @@ void read_inittab(void)
/*
* Yup, but check every second if we still have children.
*/
for(f = 0; f < sltime; f++) {
for(f = 0; f < sleep_time; f++) {
for(ch = family; ch; ch = ch->next) {
if (!(ch->flags & KILLME)) continue;
if ((ch->flags & RUNNING) && !(ch->flags & ZOMBIE))
@ -1959,7 +1972,7 @@ int read_level(int arg)
foo = arg;
ok = 1;
}
if (ok == 2) sltime = st;
if (ok == 2) sleep_time = st;
#endif /* INITLVL */
@ -2160,9 +2173,11 @@ int make_pipe(int fd)
/*
* Attempt to re-exec.
* Renaming to my_re_exec since re_exec is now a common function name
* which conflicts.
*/
static
void re_exec(void)
void my_re_exec(void)
{
CHILD *ch;
sigset_t mask, oldset;
@ -2279,7 +2294,7 @@ void fifo_new_level(int level)
runlevel = read_level(level);
if (runlevel == 'U') {
runlevel = oldlevel;
re_exec();
my_re_exec();
} else {
if (oldlevel != 'S' && runlevel == 'S') console_stty();
if (runlevel == '6' || runlevel == '0' ||
@ -2460,22 +2475,22 @@ void check_init_fifo(void)
}
switch(request.cmd) {
case INIT_CMD_RUNLVL:
sltime = request.sleeptime;
sleep_time = request.sleeptime;
fifo_new_level(request.runlevel);
quit = 1;
break;
case INIT_CMD_POWERFAIL:
sltime = request.sleeptime;
sleep_time = request.sleeptime;
do_power_fail('F');
quit = 1;
break;
case INIT_CMD_POWERFAILNOW:
sltime = request.sleeptime;
sleep_time = request.sleeptime;
do_power_fail('L');
quit = 1;
break;
case INIT_CMD_POWEROK:
sltime = request.sleeptime;
sleep_time = request.sleeptime;
do_power_fail('O');
quit = 1;
break;
@ -2681,7 +2696,7 @@ void process_signals()
#endif
if (runlevel == 'U') {
runlevel = oldlevel;
re_exec();
my_re_exec();
} else {
if (oldlevel != 'S' && runlevel == 'S') console_stty();
if (runlevel == '6' || runlevel == '0' ||
@ -2902,7 +2917,7 @@ int telinit(char *progname, int argc, char **argv)
while ((f = getopt(argc, argv, "t:e:")) != EOF) switch(f) {
case 't':
sltime = atoi(optarg);
sleep_time = atoi(optarg);
break;
case 'e':
if (env == NULL)
@ -2935,7 +2950,7 @@ int telinit(char *progname, int argc, char **argv)
usage(progname);
request.cmd = INIT_CMD_RUNLVL;
request.runlevel = argv[optind][0];
request.sleeptime = sltime;
request.sleeptime = sleep_time;
}
/* Change to the root directory. */
@ -2977,7 +2992,7 @@ int telinit(char *progname, int argc, char **argv)
progname, INITLVL);
exit(1);
}
fprintf(fp, "%s %d", argv[optind], sltime);
fprintf(fp, "%s %d", argv[optind], sleep_time);
fclose(fp);
/* And tell init about the pending runlevel change. */

View File

@ -154,3 +154,12 @@ extern char prevlevel;
#define D_WROTE_WTMP_RLEVEL -16
#define D_WROTE_UTMP_RLEVEL -17
#ifdef __FreeBSD__
#define UTMP_FILE "/var/run/utmp"
#define RUN_LVL 1
struct utmp
{
char ut_id[4];
};
#endif

View File

@ -58,8 +58,6 @@
#include <sys/wait.h>
#include <unistd.h>
char *Version = "@(#)killall5 2.86 31-Jul-2004 miquels@cistron.nl";
#ifndef PATH_MAX
# ifdef MAXPATHLEN
# define PATH_MAX MAXPATHLEN
@ -435,7 +433,11 @@ int check4nfs(const char * path, char * real)
} while (1);
if (real) strcpy(real, curr);
if (real) /* real is defined elsewhere as being PATH_MAX + 1 */
{
memset(real, '\0', PATH_MAX + 1);
strncpy(real, curr, PATH_MAX);
}
if (errno == EINVAL) {
const size_t nlen = strlen(curr);

View File

@ -34,7 +34,6 @@
#include <ctype.h>
#include <utmp.h>
#include <errno.h>
#include <malloc.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
@ -49,6 +48,10 @@
# define SHUTDOWN_TIME 254
#endif
#ifndef PATH_MAX
#define PATH_MAX 2048
#endif
char *Version = "@(#) last 2.85 31-Apr-2004 miquels";
#define CHOP_DOMAIN 0 /* Define to chop off local domainname. */
@ -254,10 +257,11 @@ int uread(FILE *fp, struct utmp *u, int *quit)
#define BTMP_FILE getbtmp()
char *getbtmp()
{
static char btmp[128];
static char btmp[PATH_MAX + 5]; /* max path + btmp + null terminator */
char *p;
strcpy(btmp, WTMP_FILE);
memset(btmp, '\0', PATH_MAX + 5);
strncpy(btmp, WTMP_FILE, PATH_MAX);
if ((p = strrchr(btmp, '/')) == NULL)
p = btmp;
else
@ -842,7 +846,7 @@ int main(int argc, char **argv)
switch (ut.ut_type) {
case SHUTDOWN_TIME:
if (extended) {
strcpy(ut.ut_line, "system down");
strncpy(ut.ut_line, "system down", OLD_LINESIZE - 1);
quit = list(&ut, lastboot, R_NORMAL);
}
lastdown = lastrch = ut.ut_time;
@ -851,14 +855,14 @@ int main(int argc, char **argv)
case OLD_TIME:
case NEW_TIME:
if (extended) {
strcpy(ut.ut_line,
strncpy(ut.ut_line,
ut.ut_type == NEW_TIME ? "new time" :
"old time");
"old time", OLD_LINESIZE - 1);
quit = list(&ut, lastdown, R_TIMECHANGE);
}
break;
case BOOT_TIME:
strcpy(ut.ut_line, "system boot");
strncpy(ut.ut_line, "system boot", OLD_LINESIZE - 1);
quit = list(&ut, lastdown, R_REBOOT);
lastboot = ut.ut_time;
down = 1;

338
src/logsave.c Normal file
View File

@ -0,0 +1,338 @@
/*
* logsave.c --- A program which saves the output of a program until
* /var/log is mounted.
*
* Copyright (C) 2003 Theodore Ts'o.
*
* %Begin-Header%
* This file may be redistributed under the terms of the GNU Public
* License.
* %End-Header%
*/
#ifndef _XOPEN_SOURCE
#define _XOPEN_SOURCE 600 /* for inclusion of sa_handler in Solaris */
#endif
#ifndef HAVE_SIGNAL_H
#define HAVE_SIGNAL_H
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <time.h>
#include <errno.h>
#ifdef HAVE_SIGNAL_H
#include <signal.h>
#endif
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#else
extern char *optarg;
extern int optind;
#endif
static int outfd = -1;
static int outbufsize = 0;
static void *outbuf = 0;
static int verbose = 0;
static int do_skip = 0;
static int skip_mode = 0;
static pid_t child_pid = -1;
static void usage(char *progname)
{
printf("Usage: %s [-asv] logfile program\n", progname);
exit(1);
}
#define SEND_LOG 0x01
#define SEND_CONSOLE 0x02
#define SEND_BOTH 0x03
/*
* Helper function that does the right thing if write returns a
* partial write, or an EAGAIN/EINTR error.
*/
static int write_all(int fd, const char *buf, size_t count)
{
ssize_t ret;
int c = 0;
while (count > 0) {
ret = write(fd, buf, count);
if (ret < 0) {
if ((errno == EAGAIN) || (errno == EINTR))
continue;
return -1;
}
count -= ret;
buf += ret;
c += ret;
}
return c;
}
static void send_output(const char *buffer, int c, int flag)
{
const char *cp;
char *n;
int cnt, d, del;
if (c == 0)
c = strlen(buffer);
if (flag & SEND_CONSOLE) {
cnt = c;
cp = buffer;
while (cnt) {
del = 0;
for (d=0; d < cnt; d++) {
if (skip_mode &&
(cp[d] == '\001' || cp[d] == '\002')) {
del = 1;
break;
}
}
write_all(1, cp, d);
if (del)
d++;
cnt -= d;
cp += d;
}
}
if (!(flag & SEND_LOG))
return;
if (outfd > 0)
write_all(outfd, buffer, c);
else {
n = realloc(outbuf, outbufsize + c);
if (n) {
outbuf = n;
memcpy(((char *)outbuf)+outbufsize, buffer, c);
outbufsize += c;
}
}
}
static int do_read(int fd)
{
int c;
char buffer[4096], *cp, *sep;
c = read(fd, buffer, sizeof(buffer)-1);
if (c <= 0)
return c;
if (do_skip) {
send_output(buffer, c, SEND_CONSOLE);
buffer[c] = 0;
cp = buffer;
while (*cp) {
if (skip_mode) {
cp = strchr(cp, '\002');
if (!cp)
return 0;
cp++;
skip_mode = 0;
continue;
}
sep = strchr(cp, '\001');
if (sep)
*sep = 0;
send_output(cp, 0, SEND_LOG);
if (sep) {
cp = sep + 1;
skip_mode = 1;
} else
break;
}
} else
send_output(buffer, c, SEND_BOTH);
return c;
}
static void signal_term(int sig)
{
if (child_pid > 0)
kill(child_pid, sig);
}
static int run_program(char **argv)
{
int fds[2];
int status, rc, pid;
char buffer[80];
#ifdef HAVE_SIGNAL_H
struct sigaction sa;
#endif
if (pipe(fds) < 0) {
perror("pipe");
exit(1);
}
#ifdef HAVE_SIGNAL_H
memset(&sa, 0, sizeof(struct sigaction));
sa.sa_handler = signal_term;
sigaction(SIGINT, &sa, 0);
sigaction(SIGTERM, &sa, 0);
#ifdef SA_RESTART
sa.sa_flags = SA_RESTART;
#endif
#endif
pid = fork();
if (pid < 0) {
perror("vfork");
exit(1);
}
if (pid == 0) {
dup2(fds[1],1); /* fds[1] replaces stdout */
dup2(fds[1],2); /* fds[1] replaces stderr */
close(fds[0]); /* don't need this here */
close(fds[1]);
execvp(argv[0], argv);
perror(argv[0]);
exit(1);
}
child_pid = pid;
close(fds[1]);
while (!(waitpid(pid, &status, WNOHANG ))) {
do_read(fds[0]);
}
child_pid = -1;
do_read(fds[0]);
close(fds[0]);
if ( WIFEXITED(status) ) {
rc = WEXITSTATUS(status);
if (rc) {
send_output(argv[0], 0, SEND_BOTH);
sprintf(buffer, " exited with status code %d\n", rc);
send_output(buffer, 0, SEND_BOTH);
}
} else {
if (WIFSIGNALED(status)) {
send_output(argv[0], 0, SEND_BOTH);
sprintf(buffer, "died with signal %d\n",
WTERMSIG(status));
send_output(buffer, 0, SEND_BOTH);
return 1;
}
rc = 0;
}
return rc;
}
static int copy_from_stdin(void)
{
int c, bad_read = 0;
while (1) {
c = do_read(0);
if ((c == 0 ) ||
((c < 0) && ((errno == EAGAIN) || (errno == EINTR)))) {
if (bad_read++ > 3)
break;
continue;
}
if (c < 0) {
perror("read");
exit(1);
}
bad_read = 0;
}
return 0;
}
int main(int argc, char **argv)
{
int c, pid, rc;
char *outfn, **cpp;
int openflags = O_CREAT|O_WRONLY|O_TRUNC;
int send_flag = SEND_LOG;
int do_stdin;
time_t t;
while ((c = getopt(argc, argv, "+asv")) != EOF) {
switch (c) {
case 'a':
openflags &= ~O_TRUNC;
openflags |= O_APPEND;
break;
case 's':
do_skip = 1;
break;
case 'v':
verbose++;
send_flag |= SEND_CONSOLE;
break;
}
}
if (optind == argc || optind+1 == argc)
usage(argv[0]);
outfn = argv[optind];
optind++;
argv += optind;
/* argc -= optind; - this is not used */
outfd = open(outfn, openflags, 0644);
do_stdin = !strcmp(argv[0], "-");
send_output("Log of ", 0, send_flag);
if (do_stdin)
send_output("stdin", 0, send_flag);
else {
for (cpp = argv; *cpp; cpp++) {
send_output(*cpp, 0, send_flag);
send_output(" ", 0, send_flag);
}
}
send_output("\n", 0, send_flag);
t = time(0);
send_output(ctime(&t), 0, send_flag);
send_output("\n", 0, send_flag);
if (do_stdin)
rc = copy_from_stdin();
else
rc = run_program(argv);
send_output("\n", 0, send_flag);
t = time(0);
send_output(ctime(&t), 0, send_flag);
send_output("----------------\n", 0, send_flag);
if (outbuf) {
pid = fork();
if (pid < 0) {
perror("fork");
exit(1);
}
if (pid) {
if (verbose)
printf("Backgrounding to save %s later\n",
outfn);
exit(rc);
}
setsid(); /* To avoid getting killed by init */
while (outfd < 0) {
outfd = open(outfn, openflags, 0644);
sleep(1);
}
write_all(outfd, outbuf, outbufsize);
free(outbuf);
}
if (outfd >= 0)
close(outfd);
exit(rc);
}

View File

@ -32,6 +32,10 @@
#include <getopt.h>
#include <stdio.h>
#ifndef PATH_MAX
#define PATH_MAX 2048
#endif
int dostat(char *path, struct stat *st, int do_lstat, int quiet)
{
int n;
@ -105,7 +109,7 @@ void usage(void) {
int main(int argc, char **argv)
{
struct stat st, st2;
char buf[256];
char buf[PATH_MAX + 1];
char *path;
int quiet = 0;
int showdev = 0;
@ -163,7 +167,7 @@ int main(int argc, char **argv)
memset(buf, 0, sizeof(buf));
strncpy(buf, path, sizeof(buf) - 4);
strcat(buf, "/..");
strncat(buf, "/..", 3);
if (dostat(buf, &st2, 0, quiet) < 0)
return 1;

View File

@ -54,15 +54,24 @@
#include <signal.h>
#include <fcntl.h>
#include <stdarg.h>
#ifdef __FreeBSD__
#include <utmpx.h>
#else
#include <utmp.h>
#endif
#include <syslog.h>
#include "paths.h"
#include "reboot.h"
#include "initreq.h"
#include "init.h"
#ifdef __FreeBSD__
extern char **environ;
#endif
#define MESSAGELEN 256
#define STATELEN 64
#define WHEN_SIZE 64
/* Whether we should warn system is shutting down */
#define QUIET_FULL 2
@ -76,7 +85,7 @@ int fastboot = 0; /* Do a 'fast' reboot */
int forcefsck = 0; /* Force fsck on reboot */
char message[MESSAGELEN]; /* Warning message */
char *sltime = 0; /* Sleep time */
char newstate[64]; /* What are we gonna do */
char newstate[STATELEN]; /* What are we gonna do */
int doself = 0; /* Don't use init */
int got_alrm = 0;
@ -225,11 +234,11 @@ int init_setenv(char *name, char *value)
*/
void issue_warn(int mins)
{
char buf[MESSAGELEN + sizeof(newstate)];
char buf[MESSAGELEN + sizeof(newstate) + 1];
int len;
buf[0] = 0;
strncat(buf, message, sizeof(buf) - 1);
strncpy(buf, message, MESSAGELEN);
len = strlen(buf);
if (mins == 0)
@ -512,7 +521,7 @@ int main(int argc, char **argv)
char buf[128];
char term[UT_LINESIZE + 6];
char *sp;
char *when = NULL;
char when[WHEN_SIZE];
int c, i, wt;
int hours, mins;
int didnolog = 0;
@ -540,6 +549,7 @@ int main(int argc, char **argv)
}
strcpy(down_level, "1");
halttype = NULL;
memset(when, '\0', WHEN_SIZE);
/* Process the options. */
while((c = getopt(argc, argv, "HPacqQkrhnfFyt:g:i:")) != EOF) {
@ -586,7 +596,7 @@ int main(int argc, char **argv)
case 'y': /* Ignored for sysV compatibility */
break;
case 'g': /* sysv style to specify time. */
when = optarg;
strncpy(when, optarg, WHEN_SIZE - 1);
break;
case 'i': /* Level to go to. */
if (!strchr("0156aAbBcCsS", optarg[0])) {
@ -672,7 +682,7 @@ int main(int argc, char **argv)
/* Read remaining words, skip time if needed. */
message[0] = 0;
for(c = optind + (!cancel && !when); c < argc; c++) {
for(c = optind + (!cancel && !when[0]); c < argc; c++) {
if (strlen(message) + strlen(argv[c]) + 4 > MESSAGELEN)
break;
strcat(message, argv[c]);
@ -697,9 +707,9 @@ int main(int argc, char **argv)
}
/* Check syntax. */
if (when == NULL) {
if (when[0] == '\0') {
if (optind == argc) usage();
when = argv[optind++];
strncpy(when, argv[optind++], WHEN_SIZE - 1);
}
/* See if we are already running. */
@ -718,16 +728,16 @@ int main(int argc, char **argv)
/* Tell users what we're gonna do. */
switch(down_level[0]) {
case '0':
strcpy(newstate, "for system halt");
strncpy(newstate, "for system halt", STATELEN);
break;
case '6':
strcpy(newstate, "for reboot");
strncpy(newstate, "for reboot", STATELEN);
break;
case '1':
strcpy(newstate, "to maintenance mode");
strncpy(newstate, "to maintenance mode", STATELEN);
break;
default:
sprintf(newstate, "to runlevel %s", down_level);
snprintf(newstate, STATELEN, "to runlevel %s", down_level);
break;
}
@ -765,10 +775,11 @@ int main(int argc, char **argv)
/* Alias now and take care of old '+mins' notation. */
if (!strcmp(when, "now")) strcpy(when, "0");
if (when[0] == '+') when++;
sp = when;
if (when[0] == '+') sp++;
/* Decode shutdown time. */
for (sp = when; *sp; sp++) {
for ( ; *sp; sp++) {
if (*sp != ':' && (*sp < '0' || *sp > '9'))
usage();
}

View File

@ -72,6 +72,8 @@
# include <selinux/get_context_list.h>
#endif
#define PASSWORD_LENGTH 256
#include "consoles.h"
#define CONMAX 16
@ -418,8 +420,8 @@ struct passwd *getrootpwent(int try_manually)
struct passwd *pw;
struct spwd *spw;
FILE *fp;
static char line[256];
static char sline[256];
static char line[PASSWORD_LENGTH];
static char sline[PASSWORD_LENGTH];
char *p;
/*
@ -453,7 +455,7 @@ struct passwd *getrootpwent(int try_manually)
/*
* Find root in the password file.
*/
while((p = fgets(line, 256, fp)) != NULL) {
while((p = fgets(line, PASSWORD_LENGTH, fp)) != NULL) {
if (strncmp(line, "root:", 5) != 0)
continue;
p += 5;
@ -487,7 +489,7 @@ struct passwd *getrootpwent(int try_manually)
fprintf(stderr, "sulogin: %s: root password garbled\n\r", F_PASSWD);
return &pwd;
}
while((p = fgets(sline, 256, fp)) != NULL) {
while((p = fgets(sline, PASSWORD_LENGTH, fp)) != NULL) {
if (strncmp(sline, "root:", 5) != 0)
continue;
p += 5;

View File

@ -32,7 +32,11 @@
#include <time.h>
#include <fcntl.h>
#include <string.h>
#ifdef __FreeBSD__
#include <utmpx.h>
#else
#include <utmp.h>
#endif
#include "init.h"
#include "initreq.h"

View File

@ -34,12 +34,13 @@
#define MAXLEN 4096
#define LINE_SIZE 80
#define MAXLINES 20
int main(int argc, char **argv)
{
char buf[MAXLEN];
char line[83];
char line[LINE_SIZE + 3]; /* leave room for \r\n\0 */
int i, f, ch;
int len = 0;
int remote = 0;
@ -81,7 +82,7 @@ int main(int argc, char **argv)
if ((argc - optind) > 0) {
for(f = optind; f < argc; f++) {
len += strlen(argv[f]) + 1;
if (len >= MAXLEN-2) break;
if (len >= MAXLEN-4) break;
strcat(buf, argv[f]);
if (f < argc-1) strcat(buf, " ");
}