00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <config.h>
00020
00021 #include "schroot-main-base.h"
00022
00023 #include <sbuild/sbuild-auth-conv.h>
00024 #include <sbuild/sbuild-auth-conv-tty.h>
00025
00026 #include <cstdlib>
00027 #include <ctime>
00028 #include <iostream>
00029 #include <locale>
00030
00031 #include <termios.h>
00032 #include <unistd.h>
00033
00034 #include <boost/format.hpp>
00035
00036 using std::endl;
00037 using boost::format;
00038 using sbuild::N_;
00039 using namespace schroot;
00040
00041 namespace
00042 {
00043
00044 typedef std::pair<main_base::error_code,const char *> emap;
00045
00050 emap init_errors[] =
00051 {
00052
00053 emap(main_base::CHROOTS_NOTFOUND, N_("%1%: Chroots not found")),
00054
00055 emap(main_base::CHROOT_FILE, N_("No chroots are defined in '%4%'")),
00056
00057
00058 emap(main_base::CHROOT_FILE2, N_("No chroots are defined in '%4%' or '%5%'")),
00059
00060 emap(main_base::CHROOT_NOTDEFINED, N_("The specified chroots are not defined in '%1%'")),
00061
00062 emap(main_base::CHROOT_NOTFOUND, N_("%1%: Chroot not found"))
00063 };
00064
00065 }
00066
00068 template<>
00069 sbuild::error<main_base::error_code>::map_type
00070 sbuild::error<main_base::error_code>::error_strings
00071 (init_errors,
00072 init_errors + (sizeof(init_errors) / sizeof(init_errors[0])));
00073
00074 main_base::main_base (std::string const& program_name,
00075 std::string const& program_usage,
00076 options_base::ptr& options,
00077 bool use_syslog):
00078 schroot_base::main(program_name, program_usage,
00079 std::tr1::static_pointer_cast<schroot_base::options>(options),
00080 use_syslog),
00081 options(options)
00082 {
00083 }
00084
00085 main_base::~main_base ()
00086 {
00087 }
00088
00089 void
00090 main_base::action_info ()
00091 {
00092 this->config->print_chroot_info(this->chroots, std::cout);
00093 }
00094
00095 void
00096 main_base::action_location ()
00097 {
00098 this->config->print_chroot_location(this->chroots, std::cout);
00099 }
00100
00101 void
00102 main_base::compat_check ()
00103 {
00104 }
00105
00106 sbuild::string_list
00107 main_base::get_chroot_options ()
00108 {
00109 sbuild::string_list ret;
00110
00111 if (this->options->all_chroots == true ||
00112 this->options->all_sessions == true)
00113 {
00114 sbuild::chroot_config::chroot_list const& list =
00115 this->config->get_chroots();
00116
00117 for (sbuild::chroot_config::chroot_list::const_iterator chroot =
00118 list.begin();
00119 chroot != list.end();
00120 ++chroot)
00121 {
00122 if (((*chroot)->get_active() == false &&
00123 this->options->all_chroots == false) ||
00124 ((*chroot)->get_active() == true &&
00125 this->options->all_sessions == false))
00126 continue;
00127 ret.push_back((*chroot)->get_name());
00128 }
00129 }
00130 else
00131 {
00132 sbuild::string_list invalid_chroots =
00133 this->config->validate_chroots(this->options->chroots);
00134
00135 if (!invalid_chroots.empty())
00136 {
00137 std::string invalid_list;
00138 for (sbuild::string_list::const_iterator chroot =
00139 invalid_chroots.begin();
00140 chroot != invalid_chroots.end();
00141 ++chroot)
00142 {
00143 invalid_list += *chroot;
00144 if (chroot + 1 != invalid_chroots.end())
00145 invalid_list += ", ";
00146 }
00147 throw error(invalid_list,
00148 (invalid_chroots.size() == 1)
00149 ? CHROOT_NOTFOUND : CHROOTS_NOTFOUND);
00150 }
00151 ret = this->options->chroots;
00152 }
00153
00154 return ret;
00155 }
00156
00157 void
00158 main_base::load_config ()
00159 {
00160 this->config = sbuild::chroot_config::ptr(new sbuild::chroot_config);
00161
00162
00163 if (this->options->load_chroots == true)
00164 this->config->add(SCHROOT_CONF, false);
00165
00166
00167 if (this->options->load_sessions == true)
00168 this->config->add(SCHROOT_SESSION_DIR, true);
00169 }
00170
00171 int
00172 main_base::run_impl ()
00173 {
00174 compat_check();
00175
00176 if (this->options->action == options_base::ACTION_HELP)
00177 {
00178 action_help(std::cout);
00179 return EXIT_SUCCESS;
00180 }
00181
00182 if (this->options->action == options_base::ACTION_VERSION)
00183 {
00184 action_version(std::cout);
00185 return EXIT_SUCCESS;
00186 }
00187
00188
00189 load_config();
00190
00191 if (this->config->get_chroots().empty() && this->options->quiet == false)
00192 {
00193 if (this->options->load_chroots == true &&
00194 this->options->load_sessions == true)
00195 log_exception_warning
00196 (error(CHROOT_FILE2, SCHROOT_CONF, SCHROOT_SESSION_DIR));
00197 else
00198 {
00199 const char *cfile = (this->options->load_sessions)
00200 ? SCHROOT_SESSION_DIR : SCHROOT_CONF;
00201 log_exception_warning(error(CHROOT_FILE, cfile));
00202 }
00203 }
00204
00205
00206 if (this->options->action == options_base::ACTION_LIST)
00207 {
00208 action_list();
00209 return EXIT_SUCCESS;
00210 }
00211
00212
00213 chroots = get_chroot_options();
00214 if (this->chroots.empty())
00215 {
00216 if (!(this->options->all_chroots == true ||
00217 this->options->all_sessions == true))
00218 throw error(SCHROOT_CONF, CHROOT_NOTDEFINED);
00219 else
00220 {
00221
00222
00223
00224
00225 log_exception_warning(error((this->options->all_chroots == true) ?
00226 SCHROOT_CONF : SCHROOT_SESSION_DIR,
00227 CHROOT_NOTDEFINED));
00228 return EXIT_SUCCESS;
00229 }
00230 }
00231
00232
00233 if (this->options->action == options_base::ACTION_INFO)
00234 {
00235 action_info();
00236 return EXIT_SUCCESS;
00237 }
00238 if (this->options->action == options_base::ACTION_LOCATION)
00239 {
00240 action_location();
00241 return EXIT_SUCCESS;
00242 }
00243 if (this->options->action == options_base::ACTION_CONFIG)
00244 {
00245 action_config();
00246 return EXIT_SUCCESS;
00247 }
00248
00249
00250 sbuild::session::operation sess_op(sbuild::session::OPERATION_AUTOMATIC);
00251 if (this->options->action == options_base::ACTION_SESSION_BEGIN)
00252 sess_op = sbuild::session::OPERATION_BEGIN;
00253 else if (this->options->action == options_base::ACTION_SESSION_RECOVER)
00254 sess_op = sbuild::session::OPERATION_RECOVER;
00255 else if (this->options->action == options_base::ACTION_SESSION_RUN)
00256 sess_op = sbuild::session::OPERATION_RUN;
00257 else if (this->options->action == options_base::ACTION_SESSION_END)
00258 sess_op = sbuild::session::OPERATION_END;
00259
00260 try
00261 {
00262 create_session(sess_op);
00263
00264 if (!this->options->command.empty())
00265 this->session->set_command(this->options->command);
00266 if (!this->options->directory.empty())
00267 this->session->set_wd(this->options->directory);
00268 if (this->options->preserve)
00269 this->session->set_environment(environ);
00270 this->session->set_session_id(this->options->session_name);
00271 this->session->set_force(this->options->session_force);
00272 sbuild::auth::verbosity verbosity = sbuild::auth::VERBOSITY_NORMAL;
00273 if (this->options->quiet)
00274 verbosity = sbuild::auth::VERBOSITY_QUIET;
00275 else if (this->options->verbose)
00276 verbosity = sbuild::auth::VERBOSITY_VERBOSE;
00277 this->session->set_verbosity(verbosity);
00278
00279
00280 std::tr1::shared_ptr<sbuild::auth_conv>
00281 conv(new sbuild::auth_conv_tty);
00282 time_t curtime = 0;
00283 time(&curtime);
00284 conv->set_warning_timeout(curtime + 15);
00285 conv->set_fatal_timeout(curtime + 20);
00286 this->session->set_conv(conv);
00287
00288
00289 this->session->run();
00290 }
00291 catch (std::runtime_error const& e)
00292 {
00293 if (!this->options->quiet)
00294 sbuild::log_exception_error(e);
00295 }
00296
00297 if (this->session)
00298 return this->session->get_child_status();
00299 else
00300 return EXIT_FAILURE;
00301 }