2 * Copyright (c) 2000, 2001 Red Hat, Inc.
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.
9 * A copy of the GNU General Public License can be found at
12 * Written by DJ Delorie <dj@cygnus.com>
16 /* The purpose of this file is to run all the post-install scripts
17 in their various forms. */
24 #include "FindVisitor.h"
25 #include "package_db.h"
26 #include "package_meta.h"
29 #include "Exception.h"
30 #include "postinstallresults.h"
35 extern ThreeBarProgressPage Progress
;
36 extern PostInstallResultsPage PostInstallResults
;
38 // ---------------------------------------------------------------------------
40 // ---------------------------------------------------------------------------
42 class RunFindVisitor
: public FindVisitor
45 RunFindVisitor (std::vector
<Script
> *scripts
, const std::string
& stratum
= "")
49 virtual void visitFile(const std::string
& basePath
,
50 const WIN32_FIND_DATA
*theFile
)
52 std::string fn
= std::string("/etc/postinstall/") + theFile
->cFileName
;
54 if (script
.not_p(stratum
))
55 _scripts
->push_back(Script (fn
));
57 virtual ~ RunFindVisitor () {}
59 RunFindVisitor (RunFindVisitor
const &);
60 RunFindVisitor
& operator= (RunFindVisitor
const &);
62 std::vector
<Script
> *_scripts
;
63 const std::string stratum
;
66 class PerpetualFindVisitor
: public FindVisitor
69 PerpetualFindVisitor (std::vector
<Script
> *scripts
, const std::string
& stratum
)
73 virtual void visitFile(const std::string
& basePath
,
74 const WIN32_FIND_DATA
*theFile
)
76 std::string fn
= std::string("/etc/postinstall/") + theFile
->cFileName
;
78 if (script
.is_p(stratum
))
79 _scripts
->push_back(Script (fn
));
81 virtual ~ PerpetualFindVisitor () {}
83 PerpetualFindVisitor (PerpetualFindVisitor
const &);
84 PerpetualFindVisitor
& operator= (PerpetualFindVisitor
const &);
86 std::vector
<Script
> *_scripts
;
87 const std::string stratum
;
90 // ---------------------------------------------------------------------------
92 // ---------------------------------------------------------------------------
97 RunScript(const std::string
& name
, const std::vector
<Script
> &scripts
) : _name(name
), _scripts(scripts
), _cnt(0)
99 Progress
.SetText2 (name
.c_str());
100 Progress
.SetBar1 (0, _scripts
.size());
104 Progress
.SetText3 ("");
106 int run_one(Script
const &aScript
)
109 Progress
.SetText3 (aScript
.fullName().c_str());
110 retval
= aScript
.run();
112 Progress
.SetBar1 (_cnt
, _scripts
.size());
115 void run_all(std::string
&s
)
117 bool package_name_recorded
= FALSE
;
119 for (std::vector
<Script
>::const_iterator j
= _scripts
.begin();
123 int retval
= run_one(*j
);
125 if ((retval
!= 0) && (retval
!= -ERROR_INVALID_DATA
))
127 if (!package_name_recorded
)
129 s
= s
+ "Package: " + _name
+ "\r\n";
130 package_name_recorded
= TRUE
;
133 std::ostringstream fs
;
134 fs
<< "\t" << j
->baseName() << " exit code " << retval
<< "\r\n";
141 const std::vector
<Script
> &_scripts
;
146 do_postinstall_thread (HINSTANCE h
, HWND owner
)
148 Progress
.SetText1 (IDS_PROGRESS_POSTINSTALL
);
149 Progress
.SetText2 ("");
150 Progress
.SetText3 ("");
151 Progress
.SetBar1 (0, 1);
152 Progress
.SetBar2 (0, 1);
155 std::vector
<packagemeta
*> packages
;
156 PackageDBConnectedIterator i
= db
.connectedBegin ();
157 while (i
!= db
.connectedEnd ())
159 packagemeta
& pkg
= **i
;
161 packages
.push_back(&pkg
);
165 const std::string postinst
= cygpath ("/etc/postinstall");
166 const std::string
strata("0_z");
168 // iterate over all strata
169 for (std::string::const_iterator it
= strata
.begin(); it
!= strata
.end(); ++it
)
171 const std::string
sit(1, *it
);
172 // Look for any scripts in /etc/postinstall which should always be run
173 std::vector
<Script
> perpetual
;
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
180 RunScript
scriptRunner(sit
+ "/Perpetual", perpetual
);
181 scriptRunner
.run_all(s
);
183 // For each package we installed, we noted anything installed into /etc/postinstall.
184 // run those scripts now
185 int numpkg
= packages
.size() + 1;
187 for (std::vector
<packagemeta
*>::iterator i
= packages
.begin (); i
!= packages
.end (); ++i
)
189 packagemeta
& pkg
= **i
;
191 std::vector
<Script
> installed
= pkg
.scripts();
192 std::vector
<Script
> run
;
193 // extract non-perpetual scripts for the current stratum
194 for (std::vector
<Script
>::iterator j
= installed
.begin(); j
!= installed
.end(); j
++)
200 RunScript
scriptRunner(sit
+ "/" + pkg
.name
, run
);
201 scriptRunner
.run_all(s
);
203 Progress
.SetBar2 (++k
, numpkg
);
205 // Look for runnable non-perpetual scripts in /etc/postinstall.
206 // This happens when a script from a previous install failed to run.
207 std::vector
<Script
> scripts
;
208 RunFindVisitor
myVisitor (&scripts
, sit
);
209 Find (postinst
).accept (myVisitor
);
210 // Remove anything which we just tried to run (so we don't try twice)
211 for (std::vector
<packagemeta
*>::iterator i
= packages
.begin (); i
!= packages
.end (); ++i
)
213 packagemeta
& pkg
= **i
;
214 for (std::vector
<Script
>::const_iterator j
= pkg
.scripts().begin();
215 j
!= pkg
.scripts().end();
218 std::vector
<Script
>::iterator p
= find(scripts
.begin(), scripts
.end(), *j
);
219 if (p
!= scripts
.end())
225 // and try to run what's left...
227 RunScript
scriptRunner(sit
+ "/Unknown package", scripts
);
228 scriptRunner
.run_all(s
);
231 Progress
.SetBar2 (numpkg
, numpkg
);
238 do_postinstall_reflector (void *p
)
241 context
= (HANDLE
*) p
;
243 SetThreadUILanguage(langid
);
247 std::string s
= do_postinstall_thread ((HINSTANCE
) context
[0], (HWND
) context
[1]);
249 // Tell the postinstall results page the results string
250 PostInstallResults
.SetResultsString(s
);
252 // Tell the progress page that we're done running scripts
253 Progress
.PostMessageNow (WM_APP_POSTINSTALL_THREAD_COMPLETE
, 0,
254 s
.empty() ? IDD_DESKTOP
: IDD_POSTINSTALL
);
256 TOPLEVEL_CATCH((HWND
) context
[1], "postinstall");
261 static HANDLE context
[2];
264 do_postinstall (HINSTANCE h
, HWND owner
)
270 CreateThread (NULL
, 0, do_postinstall_reflector
, context
, 0, &threadID
);