Whamcloud - gitweb
build: use MKDIR_P instead of MKINSTALLDIRS
[tools/e2fsprogs.git] / lib / ext2fs / progress.c
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 }