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 "config.h" 14 #include "ext2fs.h" 15 #include "ext2fsP.h" 16 17 #include <time.h> 18 19 static char spaces[80], backspaces[80]; 20 static time_t last_update; 21 22 struct ext2fs_progress_ops ext2fs_numeric_progress_ops = { 23 .init = ext2fs_numeric_progress_init, 24 .update = ext2fs_numeric_progress_update, 25 .close = ext2fs_numeric_progress_close, 26 }; 27 28 static int int_log10(unsigned int arg) 29 { 30 int l; 31 32 for (l=0; arg ; l++) 33 arg = arg / 10; 34 return l; 35 } 36 37 void ext2fs_numeric_progress_init(ext2_filsys fs, 38 struct ext2fs_numeric_progress_struct * progress, 39 const char *label, __u64 max) 40 { 41 /* 42 * The PRINT_PROGRESS flag turns on or off ALL 43 * progress-related messages, whereas the SKIP_PROGRESS 44 * environment variable prints the start and end messages but 45 * not the numeric countdown in the middle. 46 */ 47 if (!(fs->flags & EXT2_FLAG_PRINT_PROGRESS)) 48 return; 49 50 memset(spaces, ' ', sizeof(spaces)-1); 51 spaces[sizeof(spaces)-1] = 0; 52 memset(backspaces, '\b', sizeof(backspaces)-1); 53 backspaces[sizeof(backspaces)-1] = 0; 54 55 memset(progress, 0, sizeof(*progress)); 56 if (getenv("E2FSPROGS_SKIP_PROGRESS")) 57 progress->skip_progress++; 58 59 60 /* 61 * Figure out how many digits we need 62 */ 63 progress->max = max; 64 progress->log_max = int_log10(max); 65 66 if (label) { 67 fputs(label, stdout); 68 fflush(stdout); 69 } 70 last_update = 0; 71 } 72 73 void ext2fs_numeric_progress_update(ext2_filsys fs, 74 struct ext2fs_numeric_progress_struct * progress, 75 __u64 val) 76 { 77 time_t now; 78 79 if (!(fs->flags & EXT2_FLAG_PRINT_PROGRESS)) 80 return; 81 if (progress->skip_progress) 82 return; 83 now = time(0); 84 if (now == last_update) 85 return; 86 last_update = now; 87 88 printf("%*llu/%*llu", progress->log_max, val, 89 progress->log_max, progress->max); 90 fprintf(stdout, "%.*s", (2*progress->log_max)+1, backspaces); 91 } 92 93 void ext2fs_numeric_progress_close(ext2_filsys fs, 94 struct ext2fs_numeric_progress_struct * progress, 95 const char *message) 96 { 97 if (!(fs->flags & EXT2_FLAG_PRINT_PROGRESS)) 98 return; 99 fprintf(stdout, "%.*s", (2*progress->log_max)+1, spaces); 100 fprintf(stdout, "%.*s", (2*progress->log_max)+1, backspaces); 101 if (message) 102 fputs(message, stdout); 103 } 104