1 #include <apt-pkg/configuration.h>
2 #include <apt-pkg/fileutl.h>
3 #include <apt-pkg/iprogress.h>
4 #include <apt-pkg/strutl.h>
16 bool PackageManager::StatusChanged(std::string PackageName
,
17 unsigned int StepsDone
,
18 unsigned int TotalSteps
,
19 std::string HumanReadableAction
)
21 int reporting_steps
= _config
->FindI("DpkgPM::Reporting-Steps", 1);
22 percentage
= StepsDone
/(float)TotalSteps
* 100.0;
23 strprintf(progress_str
, _("Progress: [%3i%%]"), (int)percentage
);
25 if(percentage
< (last_reported_progress
+ reporting_steps
))
31 PackageManagerProgressFd::PackageManagerProgressFd(int progress_fd
)
33 OutStatusFd
= progress_fd
;
36 void PackageManagerProgressFd::WriteToStatusFd(std::string s
)
40 FileFd::Write(OutStatusFd
, s
.c_str(), s
.size());
43 void PackageManagerProgressFd::Start()
48 // FIXME: use SetCloseExec here once it taught about throwing
49 // exceptions instead of doing _exit(100) on failure
50 fcntl(OutStatusFd
,F_SETFD
,FD_CLOEXEC
);
52 // send status information that we are about to fork dpkg
53 std::ostringstream status
;
54 status
<< "pmstatus:dpkg-exec:"
55 << (StepsDone
/float(StepsTotal
)*100.0)
56 << ":" << _("Running dpkg")
58 WriteToStatusFd(status
.str());
61 void PackageManagerProgressFd::Stop()
63 // clear the Keep-Fd again
64 _config
->Clear("APT::Keep-Fds", OutStatusFd
);
67 void PackageManagerProgressFd::Error(std::string PackageName
,
68 unsigned int StepsDone
,
69 unsigned int TotalSteps
,
70 std::string ErrorMessage
)
72 std::ostringstream status
;
73 status
<< "pmerror:" << PackageName
74 << ":" << (StepsDone
/float(TotalSteps
)*100.0)
75 << ":" << ErrorMessage
77 WriteToStatusFd(status
.str());
80 void PackageManagerProgressFd::ConffilePrompt(std::string PackageName
,
81 unsigned int StepsDone
,
82 unsigned int TotalSteps
,
83 std::string ConfMessage
)
85 std::ostringstream status
;
86 status
<< "pmconffile:" << PackageName
87 << ":" << (StepsDone
/float(TotalSteps
)*100.0)
90 WriteToStatusFd(status
.str());
94 bool PackageManagerProgressFd::StatusChanged(std::string PackageName
,
95 unsigned int xStepsDone
,
96 unsigned int xTotalSteps
,
97 std::string pkg_action
)
99 StepsDone
= xStepsDone
;
100 StepsTotal
= xTotalSteps
;
102 // build the status str
103 std::ostringstream status
;
104 status
<< "pmstatus:" << StringSplit(PackageName
, ":")[0]
105 << ":" << (StepsDone
/float(StepsTotal
)*100.0)
108 WriteToStatusFd(status
.str());
112 void PackageManagerFancy::SetupTerminalScrollArea(int nr_rows
)
114 // scroll down a bit to avoid visual glitch when the screen
115 // area shrinks by one row
119 std::cout
<< "\033[s";
121 // set scroll region (this will place the cursor in the top left)
122 std::cout
<< "\033[1;" << nr_rows
- 1 << "r";
124 // restore cursor but ensure its inside the scrolling area
125 std::cout
<< "\033[u";
126 static const char *move_cursor_up
= "\033[1A";
127 std::cout
<< move_cursor_up
;
129 std::flush(std::cout
);
132 PackageManagerFancy::PackageManagerFancy()
133 : nr_terminal_rows(-1)
136 if(ioctl(STDOUT_FILENO
, TIOCGWINSZ
, (char *)&win
) == 0)
138 nr_terminal_rows
= win
.ws_row
;
142 void PackageManagerFancy::Start()
144 if (nr_terminal_rows
> 0)
145 SetupTerminalScrollArea(nr_terminal_rows
);
148 void PackageManagerFancy::Stop()
150 if (nr_terminal_rows
> 0)
152 SetupTerminalScrollArea(nr_terminal_rows
+ 1);
154 // override the progress line (sledgehammer)
155 static const char* clear_screen_below_cursor
= "\033[J";
156 std::cout
<< clear_screen_below_cursor
;
160 bool PackageManagerFancy::StatusChanged(std::string PackageName
,
161 unsigned int StepsDone
,
162 unsigned int TotalSteps
,
163 std::string HumanReadableAction
)
165 if (!PackageManager::StatusChanged(PackageName
, StepsDone
, TotalSteps
,
166 HumanReadableAction
))
169 int row
= nr_terminal_rows
;
171 static string save_cursor
= "\033[s";
172 static string restore_cursor
= "\033[u";
174 static string set_bg_color
= "\033[42m"; // green
175 static string set_fg_color
= "\033[30m"; // black
177 static string restore_bg
= "\033[49m";
178 static string restore_fg
= "\033[39m";
180 std::cout
<< save_cursor
181 // move cursor position to last row
182 << "\033[" << row
<< ";0f"
189 std::flush(std::cout
);
190 last_reported_progress
= percentage
;
195 bool PackageManagerText::StatusChanged(std::string PackageName
,
196 unsigned int StepsDone
,
197 unsigned int TotalSteps
,
198 std::string HumanReadableAction
)
200 if (!PackageManager::StatusChanged(PackageName
, StepsDone
, TotalSteps
, HumanReadableAction
))
203 std::cout
<< progress_str
<< "\r\n";
204 std::flush(std::cout
);
206 last_reported_progress
= percentage
;
212 }; // namespace progress