~ubuntu-branches/ubuntu/intrepid/schroot/intrepid

« back to all changes in this revision

Viewing changes to schroot/schroot.cc

  • Committer: Bazaar Package Importer
  • Author(s): Reinhard Tartler
  • Date: 2006-07-08 18:33:28 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20060708183328-rlo4mpldmyoda55q
Tags: 0.99.2-2ubuntu1
* remerge ubuntu changes:
  + debian/control: libpam-dev (>> 0.79-3ubuntu6)

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
 
20
20
#include <config.h>
21
21
 
 
22
#include "schroot-main.h"
 
23
#include "schroot-options.h"
 
24
 
22
25
#include <cstdlib>
23
 
#include <iostream>
24
 
#include <locale>
25
 
 
26
 
#include <termios.h>
27
 
#include <unistd.h>
28
26
 
29
27
#include <boost/format.hpp>
30
28
 
31
29
#include <syslog.h>
32
30
 
33
 
#include "sbuild.h"
34
 
 
35
 
#include "schroot-options.h"
36
 
 
37
 
#ifdef SBUILD_DCHROOT_COMPAT
38
 
#include "dchroot-chroot-config.h"
39
 
#include "dchroot-session.h"
40
 
#endif
41
 
 
42
31
using std::endl;
43
32
using boost::format;
44
33
using namespace schroot;
45
34
 
46
 
#ifdef SBUILD_DCHROOT_COMPAT
47
 
#define DCHROOT_CONF "/etc/dchroot.conf"
48
 
#endif
49
 
 
50
 
/**
51
 
 * Print version information.
52
 
 *
53
 
 * @param stream the stream to output to.
54
 
 * @param options the command line options.
55
 
 */
56
 
void
57
 
print_version (std::ostream&     stream,
58
 
               schroot::options& options)
59
 
{
60
 
  stream << format(_("%1% (Debian sbuild) %2%\n"))
61
 
    % (options.dchroot_compat ? "dchroot" : "schroot")
62
 
    % VERSION
63
 
         << _("Written by Roger Leigh\n\n")
64
 
         << _("Copyright (C) 2004-2006 Roger Leigh\n")
65
 
         << _("This is free software; see the source for copying conditions.  There is NO\n"
66
 
              "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n")
67
 
         << std::flush;
68
 
}
69
 
 
70
 
/**
71
 
 * Get a list of chroots based on the specified options (--all, --chroot).
72
 
 *
73
 
 * @param config the chroot configuration
74
 
 * @param options the command-line options
75
 
 *
76
 
 * @returns a list of chroots.
77
 
 */
78
 
sbuild::string_list
79
 
get_chroot_options (std::tr1::shared_ptr<sbuild::chroot_config>& config,
80
 
                    schroot::options&                     options)
81
 
{
82
 
  sbuild::string_list ret;
83
 
 
84
 
  if (options.all_chroots == true || options.all_sessions == true)
85
 
    {
86
 
      sbuild::chroot_config::chroot_list const& list = config->get_chroots();
87
 
 
88
 
      for (sbuild::chroot_config::chroot_list::const_iterator chroot = list.begin();
89
 
           chroot != list.end();
90
 
           ++chroot)
91
 
        {
92
 
          if (((*chroot)->get_active() == false && options.all_chroots == false) ||
93
 
              ((*chroot)->get_active() == true && options.all_sessions == false))
94
 
            continue;
95
 
          ret.push_back((*chroot)->get_name());
96
 
        }
97
 
    }
98
 
  else
99
 
    {
100
 
      sbuild::string_list invalid_chroots =
101
 
        config->validate_chroots(options.chroots);
102
 
 
103
 
      if (!invalid_chroots.empty())
104
 
        {
105
 
          for (sbuild::string_list::const_iterator chroot = invalid_chroots.begin();
106
 
               chroot != invalid_chroots.end();
107
 
               ++chroot)
108
 
            sbuild::log_error() << format(_("%1%: No such chroot")) % *chroot
109
 
                                << endl;
110
 
          exit(EXIT_FAILURE);
111
 
        }
112
 
      ret = options.chroots;
113
 
    }
114
 
 
115
 
  return ret;
116
 
}
117
 
 
118
35
/**
119
36
 * Main routine.
120
37
 *
128
45
main (int   argc,
129
46
      char *argv[])
130
47
{
131
 
  struct termios saved_termios;
132
 
  bool termios_ok = false;
133
 
 
134
48
  try
135
49
    {
136
 
      // Set up locale.
137
 
      std::locale::global(std::locale(""));
138
 
      std::cout.imbue(std::locale());
139
 
      std::cerr.imbue(std::locale());
140
 
 
141
 
      // Save terminal state.
142
 
      if (isatty(STDIN_FILENO))
143
 
        {
144
 
          if (tcgetattr(STDIN_FILENO, &saved_termios) < 0)
145
 
            {
146
 
              termios_ok = false;
147
 
              sbuild::log_warning()
148
 
                << _("Error saving terminal settings")
149
 
                << endl;
150
 
            }
151
 
          else
152
 
            termios_ok = true;
153
 
        }
154
 
 
155
 
      bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
156
 
      textdomain (GETTEXT_PACKAGE);
157
 
 
158
 
#ifdef SBUILD_DEBUG
159
 
      sbuild::debug_level = sbuild::DEBUG_NOTICE;
160
 
#else
161
 
      sbuild::debug_level = sbuild::DEBUG_NONE;
162
 
#endif
163
 
 
164
 
      openlog("schroot", LOG_PID|LOG_NDELAY, LOG_AUTHPRIV);
165
 
 
166
 
      /* Parse command-line options into opt structure. */
167
 
      options options(argc, argv);
168
 
 
169
 
      if (options.dchroot_compat && options.verbose)
170
 
        {
171
 
          sbuild::log_warning()
172
 
            << _("Running schroot in dchroot compatibility mode")
173
 
            << endl;
174
 
          sbuild::log_info()
175
 
            << _("Run 'schroot' for full capability")
176
 
            << endl;
177
 
        }
178
 
 
179
 
      if (options.action == options::ACTION_VERSION)
180
 
        {
181
 
          print_version(std::cout, options);
182
 
          exit(EXIT_SUCCESS);
183
 
        }
184
 
 
185
 
      /* Initialise chroot configuration. */
186
 
#ifdef SBUILD_DCHROOT_COMPAT
187
 
      bool use_dchroot_conf = false;
188
 
      if (options.dchroot_compat)
189
 
        {
190
 
          struct stat statbuf;
191
 
          if (stat(DCHROOT_CONF, &statbuf) == 0 && !S_ISDIR(statbuf.st_mode))
192
 
            {
193
 
              use_dchroot_conf = true;
194
 
 
195
 
              if (options.verbose)
196
 
                {
197
 
                  sbuild::log_warning()
198
 
                    << _("Using dchroot configuration file: ") << DCHROOT_CONF
199
 
                    << endl;
200
 
                  sbuild::log_info()
201
 
                    << format(_("Run '%1%'"))
202
 
                    % "dchroot --config >> " SCHROOT_CONF
203
 
                    << endl;
204
 
                  sbuild::log_info()
205
 
                    << _("to migrate to a schroot configuration.")
206
 
                    << endl;
207
 
                  sbuild::log_info()
208
 
                    << format(_("Edit '%1%' to add appropriate group access."))
209
 
                    % SCHROOT_CONF
210
 
                    << endl;
211
 
                  sbuild::log_info()
212
 
                    << format(_("Remove '%1%' to use the new configuration."))
213
 
                    % DCHROOT_CONF
214
 
                    << endl;
215
 
                }
216
 
            }
217
 
        }
218
 
#endif
219
 
 
220
 
      sbuild::chroot_config::ptr config;
221
 
#ifdef SBUILD_DCHROOT_COMPAT
222
 
      if (options.dchroot_compat && use_dchroot_conf)
223
 
        {
224
 
          config = sbuild::chroot_config::ptr(new dchroot::chroot_config);
225
 
          if (options.load_chroots == true)
226
 
            config->add(DCHROOT_CONF, false);
227
 
        }
228
 
      else
229
 
#endif
230
 
        {
231
 
          config = sbuild::chroot_config::ptr(new sbuild::chroot_config);
232
 
          /* The normal chroot list is used when starting a session or running
233
 
             any chroot type or session, or displaying chroot information. */
234
 
          if (options.load_chroots == true)
235
 
            config->add(SCHROOT_CONF, false);
236
 
          /* The session chroot list is used when running or ending an
237
 
             existing session, or displaying chroot information. */
238
 
          if (options.load_sessions == true)
239
 
            config->add(SCHROOT_SESSION_DIR, true);
240
 
        }
241
 
 
242
 
      if (config->get_chroots().empty() && options.quiet == false)
243
 
        {
244
 
          if (options.load_chroots == true && options.load_sessions == true)
245
 
            sbuild::log_warning()
246
 
              << format(_("No chroots are defined in %1% or %2%"))
247
 
              % SCHROOT_CONF % SCHROOT_SESSION_DIR
248
 
              << endl;
249
 
          else
250
 
            {
251
 
              const char *cfile = (options.load_sessions) ? SCHROOT_CONF : SCHROOT_SESSION_DIR;
252
 
            sbuild::log_warning()
253
 
              << format(_("No chroots are defined in %1%")) % cfile
254
 
              << endl;
255
 
            }
256
 
        }
257
 
 
258
 
      /* Print chroot list (including aliases). */
259
 
      if (options.action == options::ACTION_LIST)
260
 
        {
261
 
          if (options.dchroot_compat)
262
 
            config->print_chroot_list_simple(std::cout);
263
 
          else
264
 
            config->print_chroot_list(std::cout);
265
 
          exit(EXIT_SUCCESS);
266
 
        }
267
 
 
268
 
      /* Get list of chroots to use */
269
 
      sbuild::string_list const& chroots = get_chroot_options(config, options);
270
 
      if (chroots.empty())
271
 
        {
272
 
          sbuild::log_error()
273
 
            << format(_("The specified chroots are not defined in %1%"))
274
 
            % SCHROOT_CONF
275
 
            << endl;
276
 
          exit (EXIT_FAILURE);
277
 
        }
278
 
 
279
 
      /* Print chroot information for specified chroots. */
280
 
      if (options.action == options::ACTION_INFO)
281
 
        {
282
 
          config->print_chroot_info(chroots, std::cout);
283
 
          exit (EXIT_SUCCESS);
284
 
        }
285
 
      if (options.action == options::ACTION_LOCATION)
286
 
        {
287
 
          if (options.dchroot_compat)
288
 
            {
289
 
              sbuild::string_list chroot;
290
 
              chroot.push_back(options.chroot_path);
291
 
              config->print_chroot_location(chroot, std::cout);
292
 
            }
293
 
          else
294
 
            {
295
 
              config->print_chroot_location(chroots, std::cout);
296
 
            }
297
 
          exit (EXIT_SUCCESS);
298
 
        }
299
 
      if (options.action == options::ACTION_CONFIG)
300
 
        {
301
 
          std::cout << "# "
302
 
                    << format(_("schroot configuration generated by %1% %2%"))
303
 
            % (options.dchroot_compat ? "dchroot" : "schroot")
304
 
            % VERSION
305
 
                    << endl;
306
 
#ifdef SBUILD_DCHROOT_COMPAT
307
 
          // Help text at head of new config.
308
 
          std::cout << "# " << endl
309
 
                    << "# "
310
 
                    << _("To allow users access to the chroots, add their groups to the groups keys.") << endl;
311
 
          std::cout << "# "
312
 
                    << _("To allow passwordless root access, add their groups to the root-groups keys.") << endl;
313
 
          std::cout << "# "
314
 
                    << format(_("Remove '%1%' to use the new configuration."))
315
 
            % DCHROOT_CONF
316
 
                    << endl;
317
 
#endif
318
 
            std::cout << endl;
319
 
          config->print_chroot_config(chroots, std::cout);
320
 
          exit (EXIT_SUCCESS);
321
 
        }
322
 
 
323
 
      if (options.action == options::ACTION_SESSION_BEGIN &&
324
 
          chroots.size() != 1)
325
 
        {
326
 
          sbuild::log_error()
327
 
            << _("Only one chroot may be specified when beginning a session")
328
 
            << endl;
329
 
          exit (EXIT_FAILURE);
330
 
        }
331
 
 
332
 
      /* Create a session. */
333
 
      sbuild::session::operation sess_op(sbuild::session::OPERATION_AUTOMATIC);
334
 
      if (options.action == options::ACTION_SESSION_BEGIN)
335
 
        sess_op = sbuild::session::OPERATION_BEGIN;
336
 
      else if (options.action == options::ACTION_SESSION_RECOVER)
337
 
        sess_op = sbuild::session::OPERATION_RECOVER;
338
 
      else if (options.action == options::ACTION_SESSION_RUN)
339
 
        sess_op = sbuild::session::OPERATION_RUN;
340
 
      else if (options.action == options::ACTION_SESSION_END)
341
 
        sess_op = sbuild::session::OPERATION_END;
342
 
 
343
 
      // Using dchroot.conf implies using dchroot_session, which does
344
 
      // not require group access.  If loading schroot.conf, we always
345
 
      // want normal session management.
346
 
      sbuild::session::ptr session;
347
 
#ifdef SBUILD_DCHROOT_COMPAT
348
 
      if (options.dchroot_compat && use_dchroot_conf)
349
 
        session = sbuild::session::ptr
350
 
          (new dchroot::session("schroot", config, sess_op, chroots));
351
 
      else
352
 
#endif
353
 
        session = sbuild::session::ptr
354
 
          (new sbuild::session("schroot", config, sess_op, chroots));
355
 
 
356
 
      try
357
 
        {
358
 
          if (!options.user.empty() && !options.dchroot_compat)
359
 
            session->set_user(options.user);
360
 
          if (!options.command.empty())
361
 
            session->set_command(options.command);
362
 
          if (options.preserve)
363
 
            session->set_environment(environ);
364
 
          session->set_force(options.session_force);
365
 
          sbuild::auth::verbosity verbosity = sbuild::auth::VERBOSITY_NORMAL;
366
 
          if (options.quiet)
367
 
            verbosity = sbuild::auth::VERBOSITY_QUIET;
368
 
          else if (options.verbose)
369
 
            verbosity = sbuild::auth::VERBOSITY_VERBOSE;
370
 
          session->set_verbosity(verbosity);
371
 
 
372
 
          /* Set up authentication timeouts. */
373
 
          std::tr1::shared_ptr<sbuild::auth_conv>
374
 
            conv(new sbuild::auth_conv_tty);
375
 
          time_t curtime = 0;
376
 
          time(&curtime);
377
 
          conv->set_warning_timeout(curtime + 15);
378
 
          conv->set_fatal_timeout(curtime + 20);
379
 
          session->set_conv(conv);
380
 
 
381
 
          /* Run session. */
382
 
          session->run();
383
 
        }
384
 
      catch (std::runtime_error& e)
385
 
        {
386
 
          if (!options.quiet)
387
 
            sbuild::log_error()
388
 
              << format(_("Session failure: %1%")) % e.what() << endl;
389
 
        }
390
 
 
391
 
      closelog();
392
 
 
393
 
      if (isatty(STDIN_FILENO) && termios_ok)
394
 
        {
395
 
          if (tcsetattr(STDIN_FILENO, TCSANOW, &saved_termios) < 0)
396
 
            sbuild::log_warning()
397
 
              << _("Error restoring terminal settings")
398
 
              << endl;
399
 
        }
400
 
 
401
 
      exit(session->get_child_status());
 
50
      schroot::options::ptr opts(new schroot::options);
 
51
      schroot::main kit(opts);
 
52
      exit (kit.run(argc, argv));
402
53
    }
403
54
  catch (std::exception const& e)
404
55
    {
405
56
      sbuild::log_error() << e.what() << endl;
406
 
 
407
 
      closelog();
408
 
 
409
 
      if (isatty(STDIN_FILENO) && termios_ok)
410
 
        {
411
 
          if (tcsetattr(STDIN_FILENO, TCSANOW, &saved_termios) < 0)
412
 
            sbuild::log_warning()
413
 
              << _("Error restoring terminal settings")
414
 
              << endl;
415
 
        }
416
 
 
 
57
      exit(EXIT_FAILURE);
 
58
    }
 
59
  catch (...)
 
60
    {
 
61
      sbuild::log_error() << _("An unknown exception occured") << endl;
417
62
      exit(EXIT_FAILURE);
418
63
    }
419
64
}