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