JP Abgrall | e0ed740 | 2014-03-19 19:08:39 -0700 | [diff] [blame] | 1 | /* |
| 2 | * progress.c - Numeric progress meter |
| 3 | * |
| 4 | * Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, |
| 5 | * 2003, 2004, 2005 by Theodore Ts'o. |
| 6 | * |
| 7 | * %Begin-Header% |
| 8 | * This file may be redistributed under the terms of the GNU Public |
| 9 | * License. |
| 10 | * %End-Header% |
| 11 | */ |
| 12 | |
| 13 | #include "ext2fs.h" |
| 14 | #include "ext2fsP.h" |
| 15 | |
| 16 | #include <time.h> |
| 17 | |
| 18 | static char spaces[80], backspaces[80]; |
| 19 | static time_t last_update; |
| 20 | |
| 21 | static int int_log10(unsigned int arg) |
| 22 | { |
| 23 | int l; |
| 24 | |
| 25 | for (l=0; arg ; l++) |
| 26 | arg = arg / 10; |
| 27 | return l; |
| 28 | } |
| 29 | |
| 30 | void ext2fs_numeric_progress_init(ext2_filsys fs, |
| 31 | struct ext2fs_numeric_progress_struct * progress, |
| 32 | const char *label, __u64 max) |
| 33 | { |
| 34 | /* |
| 35 | * The PRINT_PROGRESS flag turns on or off ALL |
| 36 | * progress-related messages, whereas the SKIP_PROGRESS |
| 37 | * environment variable prints the start and end messages but |
| 38 | * not the numeric countdown in the middle. |
| 39 | */ |
| 40 | if (!(fs->flags & EXT2_FLAG_PRINT_PROGRESS)) |
| 41 | return; |
| 42 | |
| 43 | memset(spaces, ' ', sizeof(spaces)-1); |
| 44 | spaces[sizeof(spaces)-1] = 0; |
| 45 | memset(backspaces, '\b', sizeof(backspaces)-1); |
| 46 | backspaces[sizeof(backspaces)-1] = 0; |
| 47 | |
| 48 | memset(progress, 0, sizeof(*progress)); |
| 49 | if (getenv("E2FSPROGS_SKIP_PROGRESS")) |
| 50 | progress->skip_progress++; |
| 51 | |
| 52 | |
| 53 | /* |
| 54 | * Figure out how many digits we need |
| 55 | */ |
| 56 | progress->max = max; |
| 57 | progress->log_max = int_log10(max); |
| 58 | |
| 59 | if (label) { |
| 60 | fputs(label, stdout); |
| 61 | fflush(stdout); |
| 62 | } |
| 63 | last_update = 0; |
| 64 | } |
| 65 | |
| 66 | void ext2fs_numeric_progress_update(ext2_filsys fs, |
| 67 | struct ext2fs_numeric_progress_struct * progress, |
| 68 | __u64 val) |
| 69 | { |
| 70 | time_t now; |
| 71 | |
| 72 | if (!(fs->flags & EXT2_FLAG_PRINT_PROGRESS)) |
| 73 | return; |
| 74 | if (progress->skip_progress) |
| 75 | return; |
| 76 | now = time(0); |
| 77 | if (now == last_update) |
| 78 | return; |
| 79 | last_update = now; |
| 80 | |
| 81 | printf("%*llu/%*llu", progress->log_max, val, |
| 82 | progress->log_max, progress->max); |
| 83 | fprintf(stdout, "%.*s", (2*progress->log_max)+1, backspaces); |
| 84 | } |
| 85 | |
| 86 | void ext2fs_numeric_progress_close(ext2_filsys fs, |
| 87 | struct ext2fs_numeric_progress_struct * progress, |
| 88 | const char *message) |
| 89 | { |
| 90 | if (!(fs->flags & EXT2_FLAG_PRINT_PROGRESS)) |
| 91 | return; |
| 92 | fprintf(stdout, "%.*s", (2*progress->log_max)+1, spaces); |
| 93 | fprintf(stdout, "%.*s", (2*progress->log_max)+1, backspaces); |
| 94 | if (message) |
| 95 | fputs(message, stdout); |
| 96 | } |