1 /* $NetBSD: progress.c,v 1.4 2008/04/28 20:23:08 martin Exp $ */
4 * Copyright (c) 1997-2004 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Luke Mewburn; by Chris Gilbert; and by Jason R. Thorpe.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
33 #include <sys/cdefs.h>
34 __RCSID("$NetBSD: progress.c,v 1.4 2008/04/28 20:23:08 martin Exp $");
37 * File system independent fsck progress bar routines.
40 #include <sys/param.h>
42 #include <sys/ioctl.h>
50 static size_t ttywidth
= 80;
52 static int progress_onoff
;
53 static int progress_lowlim
;
54 static int progress_highlim
;
56 #define BUFLEFT (sizeof(buf) - len)
59 progress_switch(int onoff
)
61 progress_onoff
= onoff
;
67 progress_setrange(0, 100);
70 /* Set both low and high limit. */
72 progress_setrange(int lowlim
, int highlim
)
74 progress_lowlim
= lowlim
;
75 progress_highlim
= highlim
;
78 /* Previous high limit becomes new low limit; set new high limit. */
80 progress_sethighlim(int highlim
)
82 progress_setrange(progress_highlim
, highlim
);
86 * Display a progress bar, assuming that current/total represents a
87 * percentage in the range [progress_lowlim .. progress_highlim].
90 progress_bar(const char *dev
, const char *label
, off_t current
, off_t total
)
92 static int lastpercentage
= -1;
99 #define BAROVERHEAD 10 /* non-* portion of progress bar */
102 * stars should contain at least sizeof(buf) - BAROVERHEAD
105 static const char stars
[] =
106 "*****************************************************************************"
107 "*****************************************************************************"
108 "*****************************************************************************";
110 if (progress_onoff
== 0)
114 lengthextras
= strlen(dev
) + (label
!= NULL
? strlen(label
) : 0);
115 percentage
= progress_lowlim
+
116 (current
* (progress_highlim
- progress_lowlim
)) / total
;
117 percentage
= MAX(percentage
, 0);
118 percentage
= MIN(percentage
, 100);
120 if (percentage
== lastpercentage
)
122 lastpercentage
= percentage
;
124 len
+= snprintf(buf
+ len
, BUFLEFT
, "%s: ", dev
);
126 len
+= snprintf(buf
+ len
, BUFLEFT
, "%s ", label
);
128 barlength
= MIN(sizeof(buf
) - 1, ttywidth
) - BAROVERHEAD
- lengthextras
;
130 i
= barlength
* percentage
/ 100;
131 len
+= snprintf(buf
+ len
, BUFLEFT
,
132 "|%.*s%*s| ", i
, stars
, barlength
- i
, "");
134 len
+= snprintf(buf
+ len
, BUFLEFT
, "%3d%%\r", percentage
);
135 write(fileno(stdout
), buf
, len
);
144 if (progress_onoff
== 0)
147 len
= MIN(sizeof(buf
) - 2, ttywidth
);
148 memset(buf
, ' ', len
);
151 write(fileno(stdout
), buf
, len
+ 1);
155 progress_ttywidth(int a
)
157 struct winsize winsize
;
160 if (ioctl(fileno(stdout
), TIOCGWINSZ
, &winsize
) != -1 &&
162 ttywidth
= winsize
.ws_col
;