schroot-main-base.cc

Go to the documentation of this file.
00001 /* Copyright © 2005-2007  Roger Leigh <rleigh@debian.org>
00002  *
00003  * schroot is free software: you can redistribute it and/or modify it
00004  * under the terms of the GNU General Public License as published by
00005  * the Free Software Foundation, either version 3 of the License, or
00006  * (at your option) any later version.
00007  *
00008  * schroot is distributed in the hope that it will be useful, but
00009  * WITHOUT ANY WARRANTY; without even the implied warranty of
00010  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011  * General Public License for more details.
00012  *
00013  * You should have received a copy of the GNU General Public License
00014  * along with this program.  If not, see
00015  * <http://www.gnu.org/licenses/>.
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       // TRANSLATORS: %1% = comma-separated list of chroot names
00053       emap(main_base::CHROOTS_NOTFOUND,  N_("%1%: Chroots not found")),
00054       // TRANSLATORS: %4% = file
00055       emap(main_base::CHROOT_FILE,       N_("No chroots are defined in '%4%'")),
00056       // TRANSLATORS: %4% = file
00057       // TRANSLATORS: %5% = file
00058       emap(main_base::CHROOT_FILE2,      N_("No chroots are defined in '%4%' or '%5%'")),
00059       // TRANSLATORS: %1% = file
00060       emap(main_base::CHROOT_NOTDEFINED, N_("The specified chroots are not defined in '%1%'")),
00061       // TRANSLATORS: %1% = chroot name
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   /* The normal chroot list is used when starting a session or running
00162      any chroot type or session, or displaying chroot information. */
00163   if (this->options->load_chroots == true)
00164     this->config->add(SCHROOT_CONF, false);
00165   /* The session chroot list is used when running or ending an
00166      existing session, or displaying chroot information. */
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   /* Initialise chroot configuration. */
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   /* Print chroot list (including aliases). */
00206   if (this->options->action == options_base::ACTION_LIST)
00207     {
00208       action_list();
00209       return EXIT_SUCCESS;
00210     }
00211 
00212   /* Get list of chroots to use */
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           // If one of the --all options was used, then don't treat
00222           // the lack of chroots as an error.  TODO: Also check if any
00223           // additional chroots were specified with -c; this needs
00224           // changes in get_chroot_options.
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   /* Print chroot information for specified chroots. */
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   /* Create a session. */
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       /* Set up authentication timeouts. */
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       /* Run session. */
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 }

Generated on Mon Jan 21 00:38:29 2008 for schroot by  doxygen 1.5.4