| /* |
| * progress.c - Numeric progress meter |
| * |
| * Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, |
| * 2003, 2004, 2005 by Theodore Ts'o. |
| * |
| * %Begin-Header% |
| * This file may be redistributed under the terms of the GNU Public |
| * License. |
| * %End-Header% |
| */ |
| |
| #include "config.h" |
| #include "ext2fs.h" |
| #include "ext2fsP.h" |
| |
| #include <time.h> |
| |
| static char spaces[80], backspaces[80]; |
| static time_t last_update; |
| |
| struct ext2fs_progress_ops ext2fs_numeric_progress_ops = { |
| .init = ext2fs_numeric_progress_init, |
| .update = ext2fs_numeric_progress_update, |
| .close = ext2fs_numeric_progress_close, |
| }; |
| |
| static int int_log10(unsigned int arg) |
| { |
| int l; |
| |
| for (l=0; arg ; l++) |
| arg = arg / 10; |
| return l; |
| } |
| |
| void ext2fs_numeric_progress_init(ext2_filsys fs, |
| struct ext2fs_numeric_progress_struct * progress, |
| const char *label, __u64 max) |
| { |
| /* |
| * The PRINT_PROGRESS flag turns on or off ALL |
| * progress-related messages, whereas the SKIP_PROGRESS |
| * environment variable prints the start and end messages but |
| * not the numeric countdown in the middle. |
| */ |
| if (!(fs->flags & EXT2_FLAG_PRINT_PROGRESS)) |
| return; |
| |
| memset(spaces, ' ', sizeof(spaces)-1); |
| spaces[sizeof(spaces)-1] = 0; |
| memset(backspaces, '\b', sizeof(backspaces)-1); |
| backspaces[sizeof(backspaces)-1] = 0; |
| |
| memset(progress, 0, sizeof(*progress)); |
| if (getenv("E2FSPROGS_SKIP_PROGRESS")) |
| progress->skip_progress++; |
| |
| |
| /* |
| * Figure out how many digits we need |
| */ |
| progress->max = max; |
| progress->log_max = int_log10(max); |
| |
| if (label) { |
| fputs(label, stdout); |
| fflush(stdout); |
| } |
| last_update = 0; |
| } |
| |
| void ext2fs_numeric_progress_update(ext2_filsys fs, |
| struct ext2fs_numeric_progress_struct * progress, |
| __u64 val) |
| { |
| time_t now; |
| |
| if (!(fs->flags & EXT2_FLAG_PRINT_PROGRESS)) |
| return; |
| if (progress->skip_progress) |
| return; |
| now = time(0); |
| if (now == last_update) |
| return; |
| last_update = now; |
| |
| printf("%*llu/%*llu", progress->log_max, val, |
| progress->log_max, progress->max); |
| fprintf(stdout, "%.*s", (2*progress->log_max)+1, backspaces); |
| } |
| |
| void ext2fs_numeric_progress_close(ext2_filsys fs, |
| struct ext2fs_numeric_progress_struct * progress, |
| const char *message) |
| { |
| if (!(fs->flags & EXT2_FLAG_PRINT_PROGRESS)) |
| return; |
| fprintf(stdout, "%.*s", (2*progress->log_max)+1, spaces); |
| fprintf(stdout, "%.*s", (2*progress->log_max)+1, backspaces); |
| if (message) |
| fputs(message, stdout); |
| } |