]>
Commit | Line | Data |
---|---|---|
f57c332f | 1 | /* |
31324d15 | 2 | * Copyright (c) 2000, 2001 Red Hat, Inc. |
f57c332f DD |
3 | * |
4 | * This program is free software; you can redistribute it and/or modify | |
5 | * it under the terms of the GNU General Public License as published by | |
6 | * the Free Software Foundation; either version 2 of the License, or | |
7 | * (at your option) any later version. | |
8 | * | |
9 | * A copy of the GNU General Public License can be found at | |
10 | * http://www.gnu.org/ | |
11 | * | |
12 | * Written by DJ Delorie <dj@cygnus.com> | |
13 | * | |
14 | */ | |
15 | ||
16 | /* The purpose of this file is to run all the post-install scripts | |
17 | in their various forms. */ | |
18 | ||
f57c332f DD |
19 | #include "dialog.h" |
20 | #include "find.h" | |
a351e48c | 21 | #include "mount.h" |
8e9aa511 | 22 | #include "script.h" |
6dcfeb7d | 23 | #include "state.h" |
b401ef47 | 24 | #include "FindVisitor.h" |
ad646f43 RC |
25 | #include "package_db.h" |
26 | #include "package_meta.h" | |
39ba3555 MB |
27 | #include "resource.h" |
28 | #include "threebar.h" | |
072fb49a | 29 | #include "Exception.h" |
ff357472 | 30 | #include "postinstallresults.h" |
39ba3555 | 31 | |
287bd4b1 | 32 | #include <algorithm> |
ff357472 | 33 | #include <sstream> |
39ba3555 | 34 | |
39ba3555 | 35 | extern ThreeBarProgressPage Progress; |
ff357472 JT |
36 | extern PostInstallResultsPage PostInstallResults; |
37 | ||
38 | // --------------------------------------------------------------------------- | |
39 | // | |
40 | // --------------------------------------------------------------------------- | |
f57c332f | 41 | |
b401ef47 | 42 | class RunFindVisitor : public FindVisitor |
f57c332f | 43 | { |
b401ef47 | 44 | public: |
155eacb6 | 45 | RunFindVisitor (std::vector<Script> *scripts, const std::string& stratum = "") |
54978a88 AG |
46 | : _scripts(scripts), |
47 | stratum(stratum) | |
48 | {} | |
fd93eff9 MB |
49 | virtual void visitFile(const std::string& basePath, |
50 | const WIN32_FIND_DATA *theFile) | |
b401ef47 | 51 | { |
fd93eff9 | 52 | std::string fn = std::string("/etc/postinstall/") + theFile->cFileName; |
54978a88 AG |
53 | Script script(fn); |
54 | if (script.not_p(stratum)) | |
55 | _scripts->push_back(Script (fn)); | |
b401ef47 RC |
56 | } |
57 | virtual ~ RunFindVisitor () {} | |
58 | protected: | |
59 | RunFindVisitor (RunFindVisitor const &); | |
60 | RunFindVisitor & operator= (RunFindVisitor const &); | |
39ba3555 | 61 | private: |
155eacb6 | 62 | std::vector<Script> *_scripts; |
54978a88 AG |
63 | const std::string stratum; |
64 | }; | |
65 | ||
66 | class PerpetualFindVisitor : public FindVisitor | |
67 | { | |
68 | public: | |
155eacb6 | 69 | PerpetualFindVisitor (std::vector<Script> *scripts, const std::string& stratum) |
54978a88 AG |
70 | : _scripts(scripts), |
71 | stratum(stratum) | |
72 | {} | |
73 | virtual void visitFile(const std::string& basePath, | |
74 | const WIN32_FIND_DATA *theFile) | |
75 | { | |
76 | std::string fn = std::string("/etc/postinstall/") + theFile->cFileName; | |
77 | Script script(fn); | |
78 | if (script.is_p(stratum)) | |
79 | _scripts->push_back(Script (fn)); | |
80 | } | |
81 | virtual ~ PerpetualFindVisitor () {} | |
82 | protected: | |
83 | PerpetualFindVisitor (PerpetualFindVisitor const &); | |
84 | PerpetualFindVisitor & operator= (PerpetualFindVisitor const &); | |
85 | private: | |
155eacb6 | 86 | std::vector<Script> *_scripts; |
54978a88 | 87 | const std::string stratum; |
b401ef47 | 88 | }; |
39ba3555 | 89 | |
ff357472 JT |
90 | // --------------------------------------------------------------------------- |
91 | // | |
92 | // --------------------------------------------------------------------------- | |
93 | ||
94 | class RunScript | |
f57c332f | 95 | { |
39ba3555 | 96 | public: |
155eacb6 | 97 | RunScript(const std::string& name, const std::vector<Script> &scripts) : _name(name), _scripts(scripts), _cnt(0) |
39ba3555 | 98 | { |
d2a3615c | 99 | Progress.SetText2 (name.c_str()); |
ff357472 | 100 | Progress.SetBar1 (0, _scripts.size()); |
39ba3555 MB |
101 | } |
102 | virtual ~RunScript() | |
103 | { | |
104 | Progress.SetText3 (""); | |
105 | } | |
ff357472 | 106 | int run_one(Script const &aScript) |
39ba3555 | 107 | { |
534c25cc | 108 | int retval; |
d2a3615c | 109 | Progress.SetText3 (aScript.fullName().c_str()); |
534c25cc | 110 | retval = aScript.run(); |
39ba3555 | 111 | ++_cnt; |
ff357472 | 112 | Progress.SetBar1 (_cnt, _scripts.size()); |
534c25cc | 113 | return retval; |
39ba3555 | 114 | } |
ff357472 JT |
115 | void run_all(std::string &s) |
116 | { | |
117 | bool package_name_recorded = FALSE; | |
118 | ||
119 | for (std::vector <Script>::const_iterator j = _scripts.begin(); | |
120 | j != _scripts.end(); | |
121 | j++) | |
122 | { | |
123 | int retval = run_one(*j); | |
124 | ||
125 | if ((retval != 0) && (retval != -ERROR_INVALID_DATA)) | |
126 | { | |
127 | if (!package_name_recorded) | |
128 | { | |
129 | s = s + "Package: " + _name + "\r\n"; | |
130 | package_name_recorded = TRUE; | |
131 | } | |
132 | ||
133 | std::ostringstream fs; | |
134 | fs << "\t" << j->baseName() << " exit code " << retval << "\r\n"; | |
135 | s = s + fs.str(); | |
136 | } | |
137 | } | |
138 | } | |
39ba3555 | 139 | private: |
ff357472 | 140 | std::string _name; |
155eacb6 | 141 | const std::vector<Script> &_scripts; |
39ba3555 MB |
142 | int _cnt; |
143 | }; | |
144 | ||
ff357472 | 145 | static std::string |
39ba3555 MB |
146 | do_postinstall_thread (HINSTANCE h, HWND owner) |
147 | { | |
b3cc8ab6 | 148 | Progress.SetText1 (IDS_PROGRESS_POSTINSTALL); |
39ba3555 MB |
149 | Progress.SetText2 (""); |
150 | Progress.SetText3 (""); | |
151 | Progress.SetBar1 (0, 1); | |
152 | Progress.SetBar2 (0, 1); | |
153 | ||
ad646f43 | 154 | packagedb db; |
155eacb6 | 155 | std::vector<packagemeta*> packages; |
ad646f43 RC |
156 | PackageDBConnectedIterator i = db.connectedBegin (); |
157 | while (i != db.connectedEnd ()) | |
158 | { | |
159 | packagemeta & pkg = **i; | |
160 | if (pkg.installed) | |
39ba3555 | 161 | packages.push_back(&pkg); |
ad646f43 RC |
162 | ++i; |
163 | } | |
ff357472 | 164 | |
54978a88 AG |
165 | const std::string postinst = cygpath ("/etc/postinstall"); |
166 | const std::string strata("0_z"); | |
ff357472 | 167 | std::string s = ""; |
54978a88 AG |
168 | // iterate over all strata |
169 | for (std::string::const_iterator it = strata.begin(); it != strata.end(); ++it) | |
170 | { | |
171 | const std::string sit(1, *it); | |
172 | // Look for any scripts in /etc/postinstall which should always be run | |
155eacb6 | 173 | std::vector<Script> perpetual; |
54978a88 AG |
174 | PerpetualFindVisitor myPerpetualVisitor (&perpetual, sit); |
175 | Find (postinst).accept (myPerpetualVisitor); | |
176 | // sort the list alphabetically, assumes ASCII names only | |
177 | sort (perpetual.begin(), perpetual.end()); | |
178 | // and try to run what we've found | |
179 | { | |
180 | RunScript scriptRunner(sit + "/Perpetual", perpetual); | |
181 | scriptRunner.run_all(s); | |
182 | } | |
ff357472 JT |
183 | // For each package we installed, we noted anything installed into /etc/postinstall. |
184 | // run those scripts now | |
39ba3555 MB |
185 | int numpkg = packages.size() + 1; |
186 | int k = 0; | |
155eacb6 | 187 | for (std::vector <packagemeta *>::iterator i = packages.begin (); i != packages.end (); ++i) |
39ba3555 MB |
188 | { |
189 | packagemeta & pkg = **i; | |
6dcfeb7d | 190 | |
155eacb6 AG |
191 | std::vector<Script> installed = pkg.scripts(); |
192 | std::vector<Script> run; | |
54978a88 | 193 | // extract non-perpetual scripts for the current stratum |
155eacb6 | 194 | for (std::vector <Script>::iterator j = installed.begin(); j != installed.end(); j++) |
54978a88 AG |
195 | { |
196 | if ((*j).not_p(sit)) | |
197 | run.push_back(*j); | |
198 | } | |
199 | ||
200 | RunScript scriptRunner(sit + "/" + pkg.name, run); | |
ff357472 | 201 | scriptRunner.run_all(s); |
6dcfeb7d | 202 | |
54978a88 | 203 | Progress.SetBar2 (++k, numpkg); |
39ba3555 | 204 | } |
54978a88 AG |
205 | // Look for runnable non-perpetual scripts in /etc/postinstall. |
206 | // This happens when a script from a previous install failed to run. | |
155eacb6 | 207 | std::vector<Script> scripts; |
54978a88 | 208 | RunFindVisitor myVisitor (&scripts, sit); |
f4a981ab | 209 | Find (postinst).accept (myVisitor); |
41d8d0f4 | 210 | // Remove anything which we just tried to run (so we don't try twice) |
155eacb6 | 211 | for (std::vector <packagemeta *>::iterator i = packages.begin (); i != packages.end (); ++i) |
41d8d0f4 JT |
212 | { |
213 | packagemeta & pkg = **i; | |
621df5b3 JT |
214 | for (std::vector<Script>::const_iterator j = pkg.scripts().begin(); |
215 | j != pkg.scripts().end(); | |
41d8d0f4 JT |
216 | j++) |
217 | { | |
218 | std::vector<Script>::iterator p = find(scripts.begin(), scripts.end(), *j); | |
219 | if (p != scripts.end()) | |
220 | { | |
221 | scripts.erase(p); | |
222 | } | |
223 | } | |
224 | } | |
41d8d0f4 | 225 | // and try to run what's left... |
ff357472 | 226 | { |
54978a88 | 227 | RunScript scriptRunner(sit + "/Unknown package", scripts); |
ff357472 JT |
228 | scriptRunner.run_all(s); |
229 | } | |
230 | ||
39ba3555 | 231 | Progress.SetBar2 (numpkg, numpkg); |
ff357472 | 232 | |
54978a88 | 233 | } |
ff357472 | 234 | return s; |
39ba3555 MB |
235 | } |
236 | ||
237 | static DWORD WINAPI | |
238 | do_postinstall_reflector (void *p) | |
239 | { | |
240 | HANDLE *context; | |
241 | context = (HANDLE *) p; | |
242 | ||
069cfbb4 JT |
243 | SetThreadUILanguage(langid); |
244 | ||
072fb49a MB |
245 | try |
246 | { | |
ff357472 JT |
247 | std::string s = do_postinstall_thread ((HINSTANCE) context[0], (HWND) context[1]); |
248 | ||
249 | // Tell the postinstall results page the results string | |
250 | PostInstallResults.SetResultsString(s); | |
39ba3555 | 251 | |
072fb49a | 252 | // Tell the progress page that we're done running scripts |
6ab6abae | 253 | Progress.PostMessageNow (WM_APP_POSTINSTALL_THREAD_COMPLETE, 0, |
ff357472 | 254 | s.empty() ? IDD_DESKTOP : IDD_POSTINSTALL); |
072fb49a | 255 | } |
703f1a44 | 256 | TOPLEVEL_CATCH((HWND) context[1], "postinstall"); |
39ba3555 MB |
257 | |
258 | ExitThread(0); | |
f57c332f | 259 | } |
39ba3555 MB |
260 | |
261 | static HANDLE context[2]; | |
262 | ||
263 | void | |
264 | do_postinstall (HINSTANCE h, HWND owner) | |
265 | { | |
266 | context[0] = h; | |
267 | context[1] = owner; | |
268 | ||
269 | DWORD threadID; | |
270 | CreateThread (NULL, 0, do_postinstall_reflector, context, 0, &threadID); | |
271 | } |