1
/* Copyright © 2005-2006 Roger Leigh <rleigh@debian.org>
3
* schroot is free software; you can redistribute it and/or modify it
4
* under the terms of the GNU General Public License as published by
5
* the Free Software Foundation; either version 2 of the License, or
6
* (at your option) any later version.
8
* schroot is distributed in the hope that it will be useful, but
9
* WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
* General Public License for more details.
13
* You should have received a copy of the GNU General Public License
14
* along with this program; if not, write to the Free Software
15
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
18
*********************************************************************/
22
#include "sbuild-dirstream.h"
23
#include "sbuild-run-parts.h"
24
#include "sbuild-util.h"
30
#include <boost/format.hpp>
31
#include <boost/regex.hpp>
35
using namespace sbuild;
40
typedef std::pair<sbuild::run_parts::error_code,const char *> emap;
43
* This is a list of the supported error codes. It's used to
44
* construct the real error codes map.
48
emap(run_parts::CHILD_FORK, N_("Failed to fork child")),
49
emap(run_parts::CHILD_WAIT, N_("Wait for child failed")),
50
emap(run_parts::EXEC, N_("Failed to execute"))
56
std::map<run_parts::error_code,const char *>
57
custom_error<run_parts::error_code>::error_strings
59
init_errors + (sizeof(init_errors) / sizeof(init_errors[0])));
61
run_parts::run_parts (std::string const& directory,
66
abort_on_error(abort_on_error),
74
dirstream stream(directory);
78
std::string name(de.name());
79
if (check_filename(name))
80
this->programs.insert(name);
84
run_parts::~run_parts ()
89
run_parts::get_verbose () const
95
run_parts::set_verbose (bool verbose)
97
this->verbose = verbose;
101
run_parts::get_reverse () const
103
return this->reverse;
107
run_parts::set_reverse (bool reverse)
109
this->reverse = reverse;
113
run_parts::run (string_list const& command,
114
environment const& env)
120
for (program_set::const_iterator pos = this->programs.begin();
121
pos != this->programs.end();
124
string_list real_command;
125
real_command.push_back(*pos);
126
for (string_list::const_iterator spos = command.begin();
127
spos != command.end();
129
real_command.push_back(*spos);
131
exit_status = run_child(*pos, real_command, env);
133
if (exit_status && this->abort_on_error)
139
for (program_set::const_reverse_iterator pos = this->programs.rbegin();
140
pos != this->programs.rend();
143
string_list real_command;
144
real_command.push_back(*pos);
145
for (string_list::const_iterator spos = command.begin();
146
spos != command.end();
148
real_command.push_back(*spos);
150
exit_status = run_child(*pos, real_command, env);
152
if (exit_status && this->abort_on_error)
161
run_parts::run_child (std::string const& file,
162
string_list const& command,
163
environment const& env)
168
if ((pid = fork()) == -1)
170
throw error(CHILD_FORK, errno);
175
log_info() << format(_("Executing %1%"))
176
% string_list_to_string(command, " ")
178
::umask(this->umask);
179
exec(this->directory + '/' + file, command, env);
180
error e(file, EXEC, errno);
181
log_error() << e.what() << std::endl;
186
wait_for_child(pid, exit_status);
193
run_parts::wait_for_child (pid_t pid,
196
child_status = EXIT_FAILURE; // Default exit status
202
if (wait(&status) != pid)
205
continue; // Wait again.
207
throw error(CHILD_WAIT, errno);
213
if (WIFEXITED(status))
214
child_status = WEXITSTATUS(status);
218
run_parts::check_filename (std::string const& name)
224
static regex lanana_namespace("^[a-z0-9]+$", boost::regex::basic);
225
static regex lsb_namespace("^_?([a-z0-9_.]+-)+[a-z0-9]+$",
226
boost::regex::basic);
227
static regex debian_cron_namespace("^[a-z0-9][a-z0-9-]*$",
228
boost::regex::basic);
229
static regex debian_dpkg_conffile_cruft("dpkg-(old|dist|new|tmp)$",
230
boost::regex::extended);
232
if ((regex_match(name, lanana_namespace) ||
233
regex_match(name, lsb_namespace) ||
234
regex_match(name, debian_cron_namespace)) &&
235
!regex_match(name, debian_dpkg_conffile_cruft))
240
static regex traditional_namespace("^[a-zA-Z0-9_-]$",
241
boost::regex::basic);
242
if (regex_match(name, traditional_namespace))