schroot-main-base.cc

Go to the documentation of this file.
00001 /* Copyright © 2005-2006  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 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   schroot_base::main(program_name, program_usage,
00078                      std::tr1::static_pointer_cast<schroot_base::options>(options)),
00079   options(options)
00080 {
00081 }
00082 
00083 main_base::~main_base ()
00084 {
00085 }
00086 
00087 void
00088 main_base::action_info ()
00089 {
00090   this->config->print_chroot_info(this->chroots, std::cout);
00091 }
00092 
00093 void
00094 main_base::action_location ()
00095 {
00096   this->config->print_chroot_location(this->chroots, std::cout);
00097 }
00098 
00099 void
00100 main_base::compat_check ()
00101 {
00102 }
00103 
00104 sbuild::string_list
00105 main_base::get_chroot_options ()
00106 {
00107   sbuild::string_list ret;
00108 
00109   if (this->options->all_chroots == true ||
00110       this->options->all_sessions == true)
00111     {
00112       sbuild::chroot_config::chroot_list const& list =
00113         this->config->get_chroots();
00114 
00115       for (sbuild::chroot_config::chroot_list::const_iterator chroot =
00116              list.begin();
00117            chroot != list.end();
00118            ++chroot)
00119         {
00120           if (((*chroot)->get_active() == false &&
00121                this->options->all_chroots == false) ||
00122               ((*chroot)->get_active() == true &&
00123                this->options->all_sessions == false))
00124             continue;
00125           ret.push_back((*chroot)->get_name());
00126         }
00127     }
00128   else
00129     {
00130       sbuild::string_list invalid_chroots =
00131         this->config->validate_chroots(this->options->chroots);
00132 
00133       if (!invalid_chroots.empty())
00134         {
00135           std::string invalid_list;
00136           for (sbuild::string_list::const_iterator chroot =
00137                  invalid_chroots.begin();
00138                chroot != invalid_chroots.end();
00139                ++chroot)
00140             {
00141               invalid_list += *chroot;
00142               if (chroot + 1 != invalid_chroots.end())
00143                 invalid_list += ", ";
00144             }
00145           throw error(invalid_list,
00146                       (invalid_chroots.size() == 1)
00147                       ? CHROOT_NOTFOUND : CHROOTS_NOTFOUND);
00148         }
00149       ret = this->options->chroots;
00150     }
00151 
00152   return ret;
00153 }
00154 
00155 void
00156 main_base::load_config ()
00157 {
00158   this->config = sbuild::chroot_config::ptr(new sbuild::chroot_config);
00159   /* The normal chroot list is used when starting a session or running
00160      any chroot type or session, or displaying chroot information. */
00161   if (this->options->load_chroots == true)
00162     this->config->add(SCHROOT_CONF, false);
00163   /* The session chroot list is used when running or ending an
00164      existing session, or displaying chroot information. */
00165   if (this->options->load_sessions == true)
00166     this->config->add(SCHROOT_SESSION_DIR, true);
00167 }
00168 
00169 int
00170 main_base::run_impl ()
00171 {
00172   compat_check();
00173 
00174   if (this->options->action == options_base::ACTION_HELP)
00175     {
00176       action_help(std::cout);
00177       return EXIT_SUCCESS;
00178     }
00179 
00180   if (this->options->action == options_base::ACTION_VERSION)
00181     {
00182       action_version(std::cout);
00183       return EXIT_SUCCESS;
00184     }
00185 
00186   /* Initialise chroot configuration. */
00187   load_config();
00188 
00189   if (this->config->get_chroots().empty() && this->options->quiet == false)
00190     {
00191       if (this->options->load_chroots == true &&
00192           this->options->load_sessions == true)
00193         log_exception_warning
00194           (error(CHROOT_FILE2, SCHROOT_CONF, SCHROOT_SESSION_DIR));
00195       else
00196         {
00197           const char *cfile = (this->options->load_sessions)
00198             ? SCHROOT_SESSION_DIR : SCHROOT_CONF;
00199           log_exception_warning(error(CHROOT_FILE, cfile));
00200         }
00201     }
00202 
00203   /* Print chroot list (including aliases). */
00204   if (this->options->action == options_base::ACTION_LIST)
00205     {
00206       action_list();
00207       return EXIT_SUCCESS;
00208     }
00209 
00210   /* Get list of chroots to use */
00211   chroots = get_chroot_options();
00212   if (this->chroots.empty())
00213     throw error(SCHROOT_CONF, CHROOT_NOTDEFINED);
00214 
00215   /* Print chroot information for specified chroots. */
00216   if (this->options->action == options_base::ACTION_INFO)
00217     {
00218       action_info();
00219       return EXIT_SUCCESS;
00220     }
00221   if (this->options->action == options_base::ACTION_LOCATION)
00222     {
00223       action_location();
00224       return EXIT_SUCCESS;
00225     }
00226   if (this->options->action == options_base::ACTION_CONFIG)
00227     {
00228       action_config();
00229       return EXIT_SUCCESS;
00230     }
00231 
00232   /* Create a session. */
00233   sbuild::session::operation sess_op(sbuild::session::OPERATION_AUTOMATIC);
00234   if (this->options->action == options_base::ACTION_SESSION_BEGIN)
00235     sess_op = sbuild::session::OPERATION_BEGIN;
00236   else if (this->options->action == options_base::ACTION_SESSION_RECOVER)
00237     sess_op = sbuild::session::OPERATION_RECOVER;
00238   else if (this->options->action == options_base::ACTION_SESSION_RUN)
00239     sess_op = sbuild::session::OPERATION_RUN;
00240   else if (this->options->action == options_base::ACTION_SESSION_END)
00241     sess_op = sbuild::session::OPERATION_END;
00242 
00243   try
00244     {
00245       create_session(sess_op);
00246 
00247       if (!this->options->command.empty())
00248         this->session->set_command(this->options->command);
00249       if (!this->options->directory.empty())
00250         this->session->set_wd(this->options->directory);
00251       if (this->options->preserve)
00252         this->session->set_environment(environ);
00253       this->session->set_force(this->options->session_force);
00254       sbuild::auth::verbosity verbosity = sbuild::auth::VERBOSITY_NORMAL;
00255       if (this->options->quiet)
00256         verbosity = sbuild::auth::VERBOSITY_QUIET;
00257       else if (this->options->verbose)
00258         verbosity = sbuild::auth::VERBOSITY_VERBOSE;
00259       this->session->set_verbosity(verbosity);
00260 
00261       /* Set up authentication timeouts. */
00262       std::tr1::shared_ptr<sbuild::auth_conv>
00263         conv(new sbuild::auth_conv_tty);
00264       time_t curtime = 0;
00265       time(&curtime);
00266       conv->set_warning_timeout(curtime + 15);
00267       conv->set_fatal_timeout(curtime + 20);
00268       this->session->set_conv(conv);
00269 
00270       /* Run session. */
00271       this->session->run();
00272     }
00273   catch (std::runtime_error const& e)
00274     {
00275       if (!this->options->quiet)
00276         sbuild::log_exception_error(e);
00277     }
00278 
00279   if (this->session)
00280     return this->session->get_child_status();
00281   else
00282     return EXIT_FAILURE;
00283 }

Generated on Sat Jan 27 16:11:04 2007 for schroot by  doxygen 1.5.1