* Add support for the -a and -s options to logsave.

* Change e2fsck to bracket its progress bar output with ctrl-A and ctrl-B 
    characters, so that logsave -s can omit writing the progress bar output
    to the log file.
bitmap-optimize
Theodore Ts'o 2003-04-16 14:05:06 -04:00
parent b00bc4dc6d
commit bc34d6be65
6 changed files with 129 additions and 54 deletions

10
debian/changelog vendored
View File

@ -1,10 +1,14 @@
e2fsprogs (1.32+1.33-WIP-2003.04.14-1) unstable; urgency=low
* New upstream version
* Add new utility program, logsave, to capture the output of fsck
during the boot sequence
- Add new utility program, logsave, to capture the output of fsck
during the boot sequence
* Add support for the -a and -s options to logsave.
* Change e2fsck to bracket its progress bar output with ctrl-A and ctrl-B
characters, so that logsave -s can omit writing the progress bar output
to the log file.
-- Theodore Y. Ts'o <tytso@mit.edu> Wed, 16 Apr 2003 00:10:58 -0400
-- Theodore Y. Ts'o <tytso@mit.edu> Wed, 16 Apr 2003 14:02:36 -0400
e2fsprogs (1.32+1.33-WIP-2003.03.30-3) unstable; urgency=low

View File

@ -1,3 +1,10 @@
2003-04-16 Theodore Ts'o <tytso@mit.edu>
* unix.c: Bracket progress bar output with control-A and control-B
characters. These characters are used as in-band
signalling to allow a logging program to filter out the
progress bar.
2003-04-12 Theodore Ts'o <tytso@mit.edu>
* unix.c: Add #ifdef around #include <sys/ioctl.h>

View File

@ -328,7 +328,8 @@ extern void e2fsck_clear_progbar(e2fsck_t ctx)
if (!(ctx->flags & E2F_FLAG_PROG_BAR))
return;
printf("%s\r", spaces + (sizeof(spaces) - 80));
printf("\001%s\r\002", spaces + (sizeof(spaces) - 80));
fflush(stdout);
ctx->flags &= ~E2F_FLAG_PROG_BAR;
}
@ -379,16 +380,16 @@ int e2fsck_simple_progress(e2fsck_t ctx, char *label, float percent,
dpywidth -= 8;
i = ((percent * dpywidth) + 50) / 100;
printf("%s: |%s%s", label, bar + (sizeof(bar) - (i+1)),
printf("\001%s: |%s%s", label, bar + (sizeof(bar) - (i+1)),
spaces + (sizeof(spaces) - (dpywidth - i + 1)));
if (percent == 100.0)
fputc('|', stdout);
else
fputc(spinner[ctx->progress_pos & 3], stdout);
if (dpynum)
printf(" %4.1f%% %u\r", percent, dpynum);
printf(" %4.1f%% %u\r\002", percent, dpynum);
else
printf(" %4.1f%% \r", percent);
printf(" %4.1f%% \r\002", percent);
if (percent == 100.0)
e2fsck_clear_progbar(ctx);

View File

@ -1,3 +1,11 @@
2003-04-16 Theodore Ts'o <tytso@mit.edu>
* logsave.c: Add support for the -a option (only partially
implemented previously). Always log the command-line and
start and stop time to the log file. Add support for the
-s option, which skips text bracketed between control-A
and control-B characters.
2003-04-14 Theodore Ts'o <tytso@mit.edu>
* logsave.c: New program which saves the output of a command in a

View File

@ -8,15 +8,15 @@ logsave \- save the output of a command in a logfile
.SH SYNOPSIS
.B logsave
[
.B \-v
.B \-asv
]
.I logfile command [ ... ]
.I logfile cmd_prog [ ... ]
.SH DESCRIPTION
The
.B logsave
program will execute
.I command
with the specified argument, and save a copy of its output to
.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
@ -26,10 +26,11 @@ 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 command
.I cmd_prog
is a single hyphen ('-'), then instead of executing a program,
.B logsave
will take the input from standard input.
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
@ -40,12 +41,20 @@ until the /var partition is mounted, so the output can be written to
.B \-a
This option will cause the output to be appended to
.IR logfile ,
instead of replacing the current contents.
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
This option will make
.B logsave
more verbose.
to be more verbose in its output to the user.
.SH AUTHOR
Theodore Ts'o (tytso@mit.edu)
.SH SEE ALSO

View File

@ -30,6 +30,8 @@ int outfd = -1;
int outbufsize = 0;
void *outbuf = 0;
int verbose = 0;
int do_skip = 0;
int skip_mode = 0;
static void usage(char *progname)
{
@ -37,14 +39,21 @@ static void usage(char *progname)
exit(1);
}
static void process_output(const char *buffer, int c)
#define SEND_LOG 0x01
#define SEND_CONSOLE 0x02
#define SEND_BOTH 0x03
static void send_output(const char *buffer, int c, int flag)
{
char *n;
if (c == 0)
c = strlen(buffer);
write(1, buffer, c);
if (flag & SEND_CONSOLE)
write(1, buffer, c);
if (!(flag & SEND_LOG))
return;
if (outfd > 0)
write(outfd, buffer, c);
else {
@ -57,40 +66,53 @@ static void process_output(const char *buffer, int c)
}
}
static void do_read(int fd)
static int do_read(int fd)
{
int c;
char buffer[4096];
char buffer[4096], *cp, *sep;
c = read(fd, buffer, sizeof(buffer));
process_output(buffer, c);
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 int run_program(char **argv)
{
int fds[2];
char **cpp;
int status, rc, pid;
char buffer[80];
time_t t;
if (pipe(fds) < 0) {
perror("pipe");
exit(1);
}
if (verbose) {
process_output("Log of ", 0);
for (cpp = argv; *cpp; cpp++) {
process_output(*cpp, 0);
process_output(" ", 0);
}
process_output("\n", 0);
t = time(0);
process_output(ctime(&t), 0);
process_output("\n", 0);
}
pid = fork();
if (pid < 0) {
perror("vfork");
@ -116,16 +138,16 @@ static int run_program(char **argv)
if ( WIFEXITED(status) ) {
rc = WEXITSTATUS(status);
if (rc) {
process_output(argv[0], 0);
send_output(argv[0], 0, SEND_BOTH);
sprintf(buffer, " died with exit status %d", rc);
process_output(buffer, 0);
send_output(buffer, 0, SEND_BOTH);
}
} else {
if (WIFSIGNALED(status)) {
process_output(argv[0], 0);
send_output(argv[0], 0, SEND_BOTH);
sprintf(buffer, "died with signal %d",
WTERMSIG(status));
process_output(buffer, 0);
send_output(buffer, 0, SEND_BOTH);
rc = 1;
}
rc = 0;
@ -135,12 +157,10 @@ static int run_program(char **argv)
static int copy_from_stdin(void)
{
char buffer[4096];
int c;
int bad_read = 0;
int c, bad_read = 0;
while (1) {
c = read(0, buffer, sizeof(buffer));
c = do_read(0);
if ((c == 0 ) ||
((c < 0) && ((errno == EAGAIN) || (errno == EINTR)))) {
if (bad_read++ > 3)
@ -151,7 +171,6 @@ static int copy_from_stdin(void)
perror("read");
exit(1);
}
process_output(buffer, c);
bad_read = 0;
}
return 0;
@ -162,17 +181,24 @@ static int copy_from_stdin(void)
int main(int argc, char **argv)
{
int c, pid, rc;
char *outfn;
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, "+v")) != EOF) {
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;
}
}
@ -183,13 +209,33 @@ int main(int argc, char **argv)
argv += optind;
argc -= optind;
outfd = open(outfn, O_CREAT|O_WRONLY|O_TRUNC, 0644);
if (strcmp(argv[0], "-"))
rc = run_program(argv);
else
rc = copy_from_stdin();
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) {
@ -203,7 +249,7 @@ int main(int argc, char **argv)
exit(rc);
}
while (outfd < 0) {
outfd = open(outfn, O_CREAT|O_WRONLY|O_TRUNC, 0644);
outfd = open(outfn, openflags, 0644);
sleep(1);
}
write(outfd, outbuf, outbufsize);