diff --git a/debian/changelog b/debian/changelog index fd1c9623..103c8dea 100644 --- a/debian/changelog +++ b/debian/changelog @@ -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 Wed, 16 Apr 2003 00:10:58 -0400 + -- Theodore Y. Ts'o Wed, 16 Apr 2003 14:02:36 -0400 e2fsprogs (1.32+1.33-WIP-2003.03.30-3) unstable; urgency=low diff --git a/e2fsck/ChangeLog b/e2fsck/ChangeLog index bb800dc0..b986a582 100644 --- a/e2fsck/ChangeLog +++ b/e2fsck/ChangeLog @@ -1,3 +1,10 @@ +2003-04-16 Theodore Ts'o + + * 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 * unix.c: Add #ifdef around #include diff --git a/e2fsck/unix.c b/e2fsck/unix.c index 3c3acad2..2675c1cd 100644 --- a/e2fsck/unix.c +++ b/e2fsck/unix.c @@ -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); diff --git a/misc/ChangeLog b/misc/ChangeLog index 90518b2e..f7d9ae44 100644 --- a/misc/ChangeLog +++ b/misc/ChangeLog @@ -1,3 +1,11 @@ +2003-04-16 Theodore Ts'o + + * 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 * logsave.c: New program which saves the output of a command in a diff --git a/misc/logsave.8.in b/misc/logsave.8.in index 0455cd07..f0fbe412 100644 --- a/misc/logsave.8.in +++ b/misc/logsave.8.in @@ -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 diff --git a/misc/logsave.c b/misc/logsave.c index dd2e286f..97900470 100644 --- a/misc/logsave.c +++ b/misc/logsave.c @@ -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);