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

Generated on Sun Jul 8 21:23:55 2007 for schroot by  doxygen 1.5.2