From 9e983c05f35058ca013ae590455b6d21a11e6760 Mon Sep 17 00:00:00 2001 From: Roger Leigh Date: Fri, 23 Jun 2006 23:39:58 +0000 Subject: * Move sbuild sources into an sbuild subdirectory, dchroot sources into a dchroot subdirectory and dchroot-dsa sources into a dchroot-dsa subdirectory. --- ChangeLog | 6 + Makefile.am | 2 +- configure.ac | 13 +- dchroot-dsa/Makefile.am | 60 ++ dchroot-dsa/dchroot-dsa-chroot-config.cc | 124 ++++ dchroot-dsa/dchroot-dsa-chroot-config.h | 74 ++ dchroot-dsa/dchroot-dsa-main.cc | 157 ++++ dchroot-dsa/dchroot-dsa-main.h | 72 ++ dchroot-dsa/dchroot-dsa-options.cc | 103 +++ dchroot-dsa/dchroot-dsa-options.h | 64 ++ dchroot-dsa/dchroot-dsa-session.cc | 139 ++++ dchroot-dsa/dchroot-dsa-session.h | 89 +++ dchroot-dsa/dchroot-dsa.1.in | 245 +++++++ dchroot-dsa/dchroot-dsa.cc | 77 ++ dchroot/Makefile.am | 69 ++ dchroot/dchroot-chroot-config.cc | 155 ++++ dchroot/dchroot-chroot-config.h | 74 ++ dchroot/dchroot-main.cc | 163 +++++ dchroot/dchroot-main.h | 75 ++ dchroot/dchroot-options.cc | 129 ++++ dchroot/dchroot-options.h | 63 ++ dchroot/dchroot-session-base.cc | 96 +++ dchroot/dchroot-session-base.h | 102 +++ dchroot/dchroot-session.cc | 123 ++++ dchroot/dchroot-session.h | 88 +++ dchroot/dchroot.1.in | 258 +++++++ dchroot/dchroot.cc | 77 ++ doc/schroot.dox.in | 2 +- po/POTFILES.in | 59 +- po/en_GB.po | 835 ++++++++++++--------- po/sv.po | 858 ++++++++++++---------- po/vi.po | 867 ++++++++++++---------- sbuild/Makefile.am | 93 +++ sbuild/sbuild-auth-conv-tty.cc | 320 ++++++++ sbuild/sbuild-auth-conv-tty.h | 133 ++++ sbuild/sbuild-auth-conv.cc | 38 + sbuild/sbuild-auth-conv.h | 120 +++ sbuild/sbuild-auth-message.cc | 42 ++ sbuild/sbuild-auth-message.h | 85 +++ sbuild/sbuild-auth.cc | 692 ++++++++++++++++++ sbuild/sbuild-auth.h | 478 ++++++++++++ sbuild/sbuild-chroot-block-device.cc | 225 ++++++ sbuild/sbuild-chroot-block-device.h | 142 ++++ sbuild/sbuild-chroot-config.cc | 490 +++++++++++++ sbuild/sbuild-chroot-config.h | 276 +++++++ sbuild/sbuild-chroot-file.cc | 185 +++++ sbuild/sbuild-chroot-file.h | 107 +++ sbuild/sbuild-chroot-lvm-snapshot.cc | 248 +++++++ sbuild/sbuild-chroot-lvm-snapshot.h | 130 ++++ sbuild/sbuild-chroot-plain.cc | 148 ++++ sbuild/sbuild-chroot-plain.h | 98 +++ sbuild/sbuild-chroot-source.cc | 175 +++++ sbuild/sbuild-chroot-source.h | 172 +++++ sbuild/sbuild-chroot.cc | 622 ++++++++++++++++ sbuild/sbuild-chroot.h | 619 ++++++++++++++++ sbuild/sbuild-config.h.in | 51 ++ sbuild/sbuild-custom-error.h | 239 ++++++ sbuild/sbuild-custom-error.tcc | 121 ++++ sbuild/sbuild-environment.cc | 153 ++++ sbuild/sbuild-environment.h | 301 ++++++++ sbuild/sbuild-error.h | 58 ++ sbuild/sbuild-format-detail.cc | 38 + sbuild/sbuild-format-detail.h | 149 ++++ sbuild/sbuild-i18n.h | 38 + sbuild/sbuild-keyfile.cc | 385 ++++++++++ sbuild/sbuild-keyfile.h | 736 +++++++++++++++++++ sbuild/sbuild-lock.cc | 300 ++++++++ sbuild/sbuild-lock.h | 200 +++++ sbuild/sbuild-log.cc | 61 ++ sbuild/sbuild-log.h | 84 +++ sbuild/sbuild-nostream.cc | 28 + sbuild/sbuild-nostream.h | 86 +++ sbuild/sbuild-parse-error.cc | 242 +++++++ sbuild/sbuild-parse-error.h | 227 ++++++ sbuild/sbuild-parse-value.cc | 61 ++ sbuild/sbuild-parse-value.h | 119 +++ sbuild/sbuild-personality.cc | 189 +++++ sbuild/sbuild-personality.h | 163 +++++ sbuild/sbuild-session.cc | 1162 ++++++++++++++++++++++++++++++ sbuild/sbuild-session.h | 402 +++++++++++ sbuild/sbuild-types.h | 117 +++ sbuild/sbuild-util.cc | 232 ++++++ sbuild/sbuild-util.h | 133 ++++ schroot/Makefile.am | 125 +--- schroot/dchroot-chroot-config.cc | 154 ---- schroot/dchroot-chroot-config.h | 74 -- schroot/dchroot-dsa-chroot-config.cc | 123 ---- schroot/dchroot-dsa-chroot-config.h | 74 -- schroot/dchroot-dsa-main.cc | 155 ---- schroot/dchroot-dsa-main.h | 72 -- schroot/dchroot-dsa-options.cc | 103 --- schroot/dchroot-dsa-options.h | 64 -- schroot/dchroot-dsa-session.cc | 139 ---- schroot/dchroot-dsa-session.h | 89 --- schroot/dchroot-dsa.1.in | 245 ------- schroot/dchroot-dsa.cc | 77 -- schroot/dchroot-main.cc | 161 ----- schroot/dchroot-main.h | 75 -- schroot/dchroot-options.cc | 129 ---- schroot/dchroot-options.h | 63 -- schroot/dchroot-session-base.cc | 96 --- schroot/dchroot-session-base.h | 102 --- schroot/dchroot-session.cc | 123 ---- schroot/dchroot-session.h | 88 --- schroot/dchroot.1.in | 258 ------- schroot/dchroot.cc | 77 -- schroot/sbuild-auth-conv-tty.cc | 320 -------- schroot/sbuild-auth-conv-tty.h | 133 ---- schroot/sbuild-auth-conv.cc | 38 - schroot/sbuild-auth-conv.h | 120 --- schroot/sbuild-auth-message.cc | 42 -- schroot/sbuild-auth-message.h | 85 --- schroot/sbuild-auth.cc | 692 ------------------ schroot/sbuild-auth.h | 478 ------------ schroot/sbuild-chroot-block-device.cc | 225 ------ schroot/sbuild-chroot-block-device.h | 142 ---- schroot/sbuild-chroot-config.cc | 490 ------------- schroot/sbuild-chroot-config.h | 276 ------- schroot/sbuild-chroot-file.cc | 185 ----- schroot/sbuild-chroot-file.h | 107 --- schroot/sbuild-chroot-lvm-snapshot.cc | 248 ------- schroot/sbuild-chroot-lvm-snapshot.h | 130 ---- schroot/sbuild-chroot-plain.cc | 148 ---- schroot/sbuild-chroot-plain.h | 98 --- schroot/sbuild-chroot-source.cc | 175 ----- schroot/sbuild-chroot-source.h | 172 ----- schroot/sbuild-chroot.cc | 622 ---------------- schroot/sbuild-chroot.h | 619 ---------------- schroot/sbuild-config.h.in | 51 -- schroot/sbuild-custom-error.h | 239 ------ schroot/sbuild-custom-error.tcc | 121 ---- schroot/sbuild-environment.cc | 153 ---- schroot/sbuild-environment.h | 301 -------- schroot/sbuild-error.h | 58 -- schroot/sbuild-format-detail.cc | 38 - schroot/sbuild-format-detail.h | 149 ---- schroot/sbuild-i18n.h | 38 - schroot/sbuild-keyfile.cc | 385 ---------- schroot/sbuild-keyfile.h | 736 ------------------- schroot/sbuild-lock.cc | 300 -------- schroot/sbuild-lock.h | 200 ----- schroot/sbuild-log.cc | 61 -- schroot/sbuild-log.h | 84 --- schroot/sbuild-nostream.cc | 28 - schroot/sbuild-nostream.h | 86 --- schroot/sbuild-parse-error.cc | 242 ------- schroot/sbuild-parse-error.h | 227 ------ schroot/sbuild-parse-value.cc | 61 -- schroot/sbuild-parse-value.h | 119 --- schroot/sbuild-personality.cc | 189 ----- schroot/sbuild-personality.h | 163 ----- schroot/sbuild-session.cc | 1162 ------------------------------ schroot/sbuild-session.h | 402 ----------- schroot/sbuild-types.h | 117 --- schroot/sbuild-util.cc | 232 ------ schroot/sbuild-util.h | 133 ---- schroot/schroot-listmounts-options.cc | 2 +- schroot/schroot-listmounts.cc | 10 +- schroot/schroot-main.cc | 4 +- schroot/schroot-main.h | 2 +- schroot/schroot-options-base.h | 4 +- schroot/schroot-options.h | 2 +- schroot/schroot-releaselock-options.cc | 2 +- schroot/schroot-releaselock.cc | 6 +- test/Makefile.am | 2 +- test/sbuild-chroot-block-device.cc | 6 +- test/sbuild-chroot-config.cc | 6 +- test/sbuild-chroot-file.cc | 10 +- test/sbuild-chroot-lvm-snapshot.cc | 12 +- test/sbuild-chroot-plain.cc | 10 +- test/sbuild-chroot.cc | 10 +- test/sbuild-environment.cc | 6 +- test/sbuild-keyfile.cc | 4 +- test/sbuild-lock.cc | 6 +- test/sbuild-log.cc | 4 +- test/sbuild-nostream.cc | 4 +- test/sbuild-parse-value.cc | 4 +- test/sbuild-personality.cc | 4 +- test/sbuild-util.cc | 4 +- test/test-helpers.h | 4 +- test/test-sbuild-chroot.h | 4 +- test/testmain.cc | 4 +- 182 files changed, 15992 insertions(+), 15461 deletions(-) create mode 100644 dchroot-dsa/Makefile.am create mode 100644 dchroot-dsa/dchroot-dsa-chroot-config.cc create mode 100644 dchroot-dsa/dchroot-dsa-chroot-config.h create mode 100644 dchroot-dsa/dchroot-dsa-main.cc create mode 100644 dchroot-dsa/dchroot-dsa-main.h create mode 100644 dchroot-dsa/dchroot-dsa-options.cc create mode 100644 dchroot-dsa/dchroot-dsa-options.h create mode 100644 dchroot-dsa/dchroot-dsa-session.cc create mode 100644 dchroot-dsa/dchroot-dsa-session.h create mode 100644 dchroot-dsa/dchroot-dsa.1.in create mode 100644 dchroot-dsa/dchroot-dsa.cc create mode 100644 dchroot/Makefile.am create mode 100644 dchroot/dchroot-chroot-config.cc create mode 100644 dchroot/dchroot-chroot-config.h create mode 100644 dchroot/dchroot-main.cc create mode 100644 dchroot/dchroot-main.h create mode 100644 dchroot/dchroot-options.cc create mode 100644 dchroot/dchroot-options.h create mode 100644 dchroot/dchroot-session-base.cc create mode 100644 dchroot/dchroot-session-base.h create mode 100644 dchroot/dchroot-session.cc create mode 100644 dchroot/dchroot-session.h create mode 100644 dchroot/dchroot.1.in create mode 100644 dchroot/dchroot.cc create mode 100644 sbuild/Makefile.am create mode 100644 sbuild/sbuild-auth-conv-tty.cc create mode 100644 sbuild/sbuild-auth-conv-tty.h create mode 100644 sbuild/sbuild-auth-conv.cc create mode 100644 sbuild/sbuild-auth-conv.h create mode 100644 sbuild/sbuild-auth-message.cc create mode 100644 sbuild/sbuild-auth-message.h create mode 100644 sbuild/sbuild-auth.cc create mode 100644 sbuild/sbuild-auth.h create mode 100644 sbuild/sbuild-chroot-block-device.cc create mode 100644 sbuild/sbuild-chroot-block-device.h create mode 100644 sbuild/sbuild-chroot-config.cc create mode 100644 sbuild/sbuild-chroot-config.h create mode 100644 sbuild/sbuild-chroot-file.cc create mode 100644 sbuild/sbuild-chroot-file.h create mode 100644 sbuild/sbuild-chroot-lvm-snapshot.cc create mode 100644 sbuild/sbuild-chroot-lvm-snapshot.h create mode 100644 sbuild/sbuild-chroot-plain.cc create mode 100644 sbuild/sbuild-chroot-plain.h create mode 100644 sbuild/sbuild-chroot-source.cc create mode 100644 sbuild/sbuild-chroot-source.h create mode 100644 sbuild/sbuild-chroot.cc create mode 100644 sbuild/sbuild-chroot.h create mode 100644 sbuild/sbuild-config.h.in create mode 100644 sbuild/sbuild-custom-error.h create mode 100644 sbuild/sbuild-custom-error.tcc create mode 100644 sbuild/sbuild-environment.cc create mode 100644 sbuild/sbuild-environment.h create mode 100644 sbuild/sbuild-error.h create mode 100644 sbuild/sbuild-format-detail.cc create mode 100644 sbuild/sbuild-format-detail.h create mode 100644 sbuild/sbuild-i18n.h create mode 100644 sbuild/sbuild-keyfile.cc create mode 100644 sbuild/sbuild-keyfile.h create mode 100644 sbuild/sbuild-lock.cc create mode 100644 sbuild/sbuild-lock.h create mode 100644 sbuild/sbuild-log.cc create mode 100644 sbuild/sbuild-log.h create mode 100644 sbuild/sbuild-nostream.cc create mode 100644 sbuild/sbuild-nostream.h create mode 100644 sbuild/sbuild-parse-error.cc create mode 100644 sbuild/sbuild-parse-error.h create mode 100644 sbuild/sbuild-parse-value.cc create mode 100644 sbuild/sbuild-parse-value.h create mode 100644 sbuild/sbuild-personality.cc create mode 100644 sbuild/sbuild-personality.h create mode 100644 sbuild/sbuild-session.cc create mode 100644 sbuild/sbuild-session.h create mode 100644 sbuild/sbuild-types.h create mode 100644 sbuild/sbuild-util.cc create mode 100644 sbuild/sbuild-util.h delete mode 100644 schroot/dchroot-chroot-config.cc delete mode 100644 schroot/dchroot-chroot-config.h delete mode 100644 schroot/dchroot-dsa-chroot-config.cc delete mode 100644 schroot/dchroot-dsa-chroot-config.h delete mode 100644 schroot/dchroot-dsa-main.cc delete mode 100644 schroot/dchroot-dsa-main.h delete mode 100644 schroot/dchroot-dsa-options.cc delete mode 100644 schroot/dchroot-dsa-options.h delete mode 100644 schroot/dchroot-dsa-session.cc delete mode 100644 schroot/dchroot-dsa-session.h delete mode 100644 schroot/dchroot-dsa.1.in delete mode 100644 schroot/dchroot-dsa.cc delete mode 100644 schroot/dchroot-main.cc delete mode 100644 schroot/dchroot-main.h delete mode 100644 schroot/dchroot-options.cc delete mode 100644 schroot/dchroot-options.h delete mode 100644 schroot/dchroot-session-base.cc delete mode 100644 schroot/dchroot-session-base.h delete mode 100644 schroot/dchroot-session.cc delete mode 100644 schroot/dchroot-session.h delete mode 100644 schroot/dchroot.1.in delete mode 100644 schroot/dchroot.cc delete mode 100644 schroot/sbuild-auth-conv-tty.cc delete mode 100644 schroot/sbuild-auth-conv-tty.h delete mode 100644 schroot/sbuild-auth-conv.cc delete mode 100644 schroot/sbuild-auth-conv.h delete mode 100644 schroot/sbuild-auth-message.cc delete mode 100644 schroot/sbuild-auth-message.h delete mode 100644 schroot/sbuild-auth.cc delete mode 100644 schroot/sbuild-auth.h delete mode 100644 schroot/sbuild-chroot-block-device.cc delete mode 100644 schroot/sbuild-chroot-block-device.h delete mode 100644 schroot/sbuild-chroot-config.cc delete mode 100644 schroot/sbuild-chroot-config.h delete mode 100644 schroot/sbuild-chroot-file.cc delete mode 100644 schroot/sbuild-chroot-file.h delete mode 100644 schroot/sbuild-chroot-lvm-snapshot.cc delete mode 100644 schroot/sbuild-chroot-lvm-snapshot.h delete mode 100644 schroot/sbuild-chroot-plain.cc delete mode 100644 schroot/sbuild-chroot-plain.h delete mode 100644 schroot/sbuild-chroot-source.cc delete mode 100644 schroot/sbuild-chroot-source.h delete mode 100644 schroot/sbuild-chroot.cc delete mode 100644 schroot/sbuild-chroot.h delete mode 100644 schroot/sbuild-config.h.in delete mode 100644 schroot/sbuild-custom-error.h delete mode 100644 schroot/sbuild-custom-error.tcc delete mode 100644 schroot/sbuild-environment.cc delete mode 100644 schroot/sbuild-environment.h delete mode 100644 schroot/sbuild-error.h delete mode 100644 schroot/sbuild-format-detail.cc delete mode 100644 schroot/sbuild-format-detail.h delete mode 100644 schroot/sbuild-i18n.h delete mode 100644 schroot/sbuild-keyfile.cc delete mode 100644 schroot/sbuild-keyfile.h delete mode 100644 schroot/sbuild-lock.cc delete mode 100644 schroot/sbuild-lock.h delete mode 100644 schroot/sbuild-log.cc delete mode 100644 schroot/sbuild-log.h delete mode 100644 schroot/sbuild-nostream.cc delete mode 100644 schroot/sbuild-nostream.h delete mode 100644 schroot/sbuild-parse-error.cc delete mode 100644 schroot/sbuild-parse-error.h delete mode 100644 schroot/sbuild-parse-value.cc delete mode 100644 schroot/sbuild-parse-value.h delete mode 100644 schroot/sbuild-personality.cc delete mode 100644 schroot/sbuild-personality.h delete mode 100644 schroot/sbuild-session.cc delete mode 100644 schroot/sbuild-session.h delete mode 100644 schroot/sbuild-types.h delete mode 100644 schroot/sbuild-util.cc delete mode 100644 schroot/sbuild-util.h diff --git a/ChangeLog b/ChangeLog index 1dec4ff5..4898d4d1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2006-06-24 Roger Leigh + + * Move sbuild sources into an sbuild subdirectory, dchroot sources + into a dchroot subdirectory and dchroot-dsa sources into a + dchroot-dsa subdirectory. + 2006-06-23 Roger Leigh * The include order of all includes has been reviewed. Local diff --git a/Makefile.am b/Makefile.am index 7b0d05fd..2358e609 100644 --- a/Makefile.am +++ b/Makefile.am @@ -20,7 +20,7 @@ # ##################################################################### -SUBDIRS = schroot test doc po +SUBDIRS = sbuild schroot dchroot dchroot-dsa test doc po # Remove junk from the generated tarball. dist-hook: diff --git a/configure.ac b/configure.ac index 040716da..f04d282d 100644 --- a/configure.ac +++ b/configure.ac @@ -25,12 +25,12 @@ dnl bug-reporting address. AC_INIT([schroot], [0.99.1], [buildd-tools-devel@lists.alioth.debian.org]) dnl For safety, check we are in the right directory by dnl checking for a known unique file. -AC_CONFIG_SRCDIR([schroot/sbuild-session.cc]) +AC_CONFIG_SRCDIR([sbuild/sbuild-session.cc]) dnl Place auxilliary scripts here. AC_CONFIG_AUX_DIR([scripts]) dnl Put macro definitions here. AC_CONFIG_HEADER([config.h]) -AC_CONFIG_HEADER([schroot/sbuild-config.h]) +AC_CONFIG_HEADER([sbuild/sbuild-config.h]) dnl Initialise automake stuff. AM_INIT_AUTOMAKE([1.9 gnu check-news dist-bzip2 no-dist-gzip tar-ustar]) @@ -62,6 +62,8 @@ AC_ARG_ENABLE([dchroot-dsa], [AS_HELP_STRING([--enable-dchroot], [Enable dchroot esac]) AC_MSG_RESULT([$enable_dchroot_dsa_compat]) AM_CONDITIONAL([BUILD_DCHROOT_DSA], [test "$enable_dchroot_dsa_compat" = "yes"]) +AM_CONDITIONAL([BUILD_LIBDCHROOT], [test "$enable_dchroot_compat" = "yes" || test "$enable_dchroot_dsa_compat" = "yes"]) + AC_MSG_CHECKING([whether to enable debugging messages]) enable_debug="no" @@ -312,15 +314,18 @@ dnl Configure which files to generate. AC_CONFIG_FILES([doc/Makefile]) AC_CONFIG_FILES([doc/schroot.dox]) AC_CONFIG_FILES([po/Makefile.in]) +AC_CONFIG_FILES([sbuild/Makefile]) AC_CONFIG_FILES([schroot/Makefile]) AC_CONFIG_FILES([schroot/pam/Makefile]) AC_CONFIG_FILES([schroot/exec/Makefile]) AC_CONFIG_FILES([schroot/setup/Makefile]) -AC_CONFIG_FILES([schroot/dchroot.1]) -AC_CONFIG_FILES([schroot/dchroot-dsa.1]) AC_CONFIG_FILES([schroot/schroot.1]) AC_CONFIG_FILES([schroot/schroot-setup.5]) AC_CONFIG_FILES([schroot/schroot.conf.5]) +AC_CONFIG_FILES([dchroot/Makefile]) +AC_CONFIG_FILES([dchroot/dchroot.1]) +AC_CONFIG_FILES([dchroot-dsa/Makefile]) +AC_CONFIG_FILES([dchroot-dsa/dchroot-dsa.1]) AC_CONFIG_FILES([test/Makefile]) AC_CONFIG_FILES([Makefile]) dnl Output the generated config.status script. diff --git a/dchroot-dsa/Makefile.am b/dchroot-dsa/Makefile.am new file mode 100644 index 00000000..ad82f717 --- /dev/null +++ b/dchroot-dsa/Makefile.am @@ -0,0 +1,60 @@ +# schroot Makefile template +# +# +# Copyright © 2004-2006 Roger Leigh +# +# schroot is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# schroot is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +##################################################################### + +localedir = $(datadir)/locale +pkglibexecdir = $(SCHROOT_LIBEXEC_DIR) + +AM_CXXFLAGS = $(SCHROOT_CFLAGS) -pedantic -Wall -Wcast-align -Wwrite-strings -Wswitch-default -Wcast-qual -Wunused-variable -Wredundant-decls -Wctor-dtor-privacy -Wnon-virtual-dtor -Wreorder -Wold-style-cast -Woverloaded-virtual -fstrict-aliasing +# -Weffc++ causes too many warnings in standard headers; -Wextra is not +# supported by GCC 3.4. + +DEFS = -DGETTEXT_PACKAGE=\"schroot\" -DLOCALEDIR=\"$(localedir)\" -D_GNU_SOURCE + +if BUILD_DCHROOT_DSA +dchroot_dsa = dchroot-dsa +endif + +bin_PROGRAMS = $(dchroot_dsa) + +dchroot_dsa_SOURCES = \ + dchroot-dsa-chroot-config.h \ + dchroot-dsa-chroot-config.cc \ + dchroot-dsa-session.h \ + dchroot-dsa-session.cc \ + dchroot-dsa-options.h \ + dchroot-dsa-options.cc \ + dchroot-dsa-main.h \ + dchroot-dsa-main.cc \ + dchroot-dsa.cc +dchroot_dsa_LDADD = $(top_builddir)/dchroot/libdchroot.la + +if BUILD_DCHROOT_DSA +dchroot_dsa_mans = dchroot-dsa.1 +endif + +man_MANS = $(dchroot_dsa_mans) + +install-exec-hook: +# Install setuid root. + if [ -f "$(DESTDIR)$(bindir)/dchroot-dsa" ]; then \ + chmod 4755 "$(DESTDIR)$(bindir)/dchroot-dsa"; \ + fi diff --git a/dchroot-dsa/dchroot-dsa-chroot-config.cc b/dchroot-dsa/dchroot-dsa-chroot-config.cc new file mode 100644 index 00000000..79fc2651 --- /dev/null +++ b/dchroot-dsa/dchroot-dsa-chroot-config.cc @@ -0,0 +1,124 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#include + +#include +#include + +#include "dchroot-dsa-chroot-config.h" + +#include +#include +#include +#include + +#include + +using std::endl; +using sbuild::parse_error; +using boost::format; +using namespace dchroot_dsa; + +chroot_config::chroot_config (): + sbuild::chroot_config() +{ +} + +chroot_config::chroot_config (std::string const& file, + bool active): + sbuild::chroot_config(file, active) +{ +} + +chroot_config::~chroot_config () +{ +} + +void +chroot_config::parse_data (std::istream& stream, + bool active) +{ + active = false; // dchroot does not support sessions. + + size_t linecount = 0; + std::string line; + std::string chroot_name; + std::string chroot_location; + + while (std::getline(stream, line)) + { + linecount++; + + if (line[0] == '#') + { + // Comment line; do nothing. + } + else if (line.length() == 0) + { + // Empty line; do nothing. + } + else // Item + { + static const char *whitespace = " \t:;,"; + + // Get chroot name + std::string::size_type cstart = line.find_first_not_of(whitespace); + std::string::size_type cend = line.find_first_of(whitespace, cstart); + + // Get chroot location + std::string::size_type lstart = line.find_first_not_of(whitespace, + cend); + std::string::size_type lend = line.find_first_of(whitespace, lstart); + + if (cstart == std::string::npos || + cend == std::string::npos || + lstart == std::string::npos) + { + throw parse_error(linecount, parse_error::INVALID_LINE, line); + } + + std::string chroot_name = line.substr(cstart, cend - cstart); + std::string location = line.substr(lstart, lend - lstart); + + /* DSA dchroot parses valid users. */ + sbuild::string_list users; + if (lend != std::string::npos) + users = sbuild::split_string(line.substr(lend), whitespace); + + /* Create chroot object. */ + sbuild::chroot::ptr chroot = sbuild::chroot::create("plain"); + chroot->set_active(active); + chroot->set_name(chroot_name); + + format fmt(_("%1% chroot (dchroot-dsa compatibility)")); + fmt % chroot_name; + chroot->set_description(fmt.str()); + + /* DSA dchroot set valid users in the user list. */ + chroot->set_users(users); + + sbuild::chroot_plain *plain = + dynamic_cast(chroot.get()); + plain->set_location(location); + + add(chroot); + } + } +} diff --git a/dchroot-dsa/dchroot-dsa-chroot-config.h b/dchroot-dsa/dchroot-dsa-chroot-config.h new file mode 100644 index 00000000..f0addb78 --- /dev/null +++ b/dchroot-dsa/dchroot-dsa-chroot-config.h @@ -0,0 +1,74 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#ifndef DCHROOT_DSA_CHROOT_CONFIG_H +#define DCHROOT_DSA_CHROOT_CONFIG_H + +#include + +#include +#include +#include +#include + +namespace dchroot_dsa +{ + + /** + * Chroot configuration for dchroot-dsa compatibility. + * + * This class provides all the functionality of chroot_config, but + * parses the dchroot-dsa configuration file format, rather than the + * schroot format. + */ + class chroot_config : public sbuild::chroot_config + { + public: + /// The constructor. + chroot_config (); + + /** + * The constructor. + * + * @param file initialise using a configuration file or a whole + * directory containing configuration files. + * @param active true if the chroots in the configuration file are + * active sessions, otherwise false. + */ + chroot_config (std::string const& file, + bool active); + + /// The destructor. + virtual ~chroot_config (); + + private: + virtual void + parse_data (std::istream& stream, + bool active); + }; + +} + +#endif /* DCHROOT_DSA_CHROOT_CONFIG_H */ + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/dchroot-dsa/dchroot-dsa-main.cc b/dchroot-dsa/dchroot-dsa-main.cc new file mode 100644 index 00000000..aff3bc8b --- /dev/null +++ b/dchroot-dsa/dchroot-dsa-main.cc @@ -0,0 +1,157 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#include + +#include "dchroot-dsa-main.h" +#include "dchroot-dsa-chroot-config.h" +#include "dchroot-dsa-session.h" + +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include + +using std::endl; +using boost::format; +using namespace dchroot_dsa; + +main::main (schroot::options_base::ptr& options): + schroot::main(options), + use_dchroot_conf(false) +{ + this->program_name = "dchroot-dsa"; +} + +main::~main () +{ +} + +void +main::action_config () +{ + std::cout << "# " + << format(_("schroot configuration generated by %1% %2%")) + % this->program_name % VERSION + << endl; + // Help text at head of new config. + std::cout << "# " << endl + << "# " + << _("To allow users access to the chroots, use the users or groups keys.") << endl; + std::cout << "# " + << _("To allow passwordless root access, use the root-users or root-groups keys.") << endl; + std::cout << "# " + << format(_("Remove '%1%' to use the new configuration.")) + % DCHROOT_CONF + << endl; + std::cout << endl; + this->config->print_chroot_config(this->chroots, std::cout); +} + +void +main::action_list () +{ + this->config->print_chroot_list_simple(std::cout); +} + +void +main::compat_check () +{ + if (this->options->verbose) + { + sbuild::log_warning() + << _("Running schroot in dchroot compatibility mode") + << endl; + sbuild::log_info() + << _("Run 'schroot' for full capabilities") + << endl; + } +} + +void +main::load_config () +{ + this->use_dchroot_conf = false; + + struct stat statbuf; + if (stat(DCHROOT_CONF, &statbuf) == 0 && !S_ISDIR(statbuf.st_mode)) + { + this->use_dchroot_conf = true; + + if (this->options->verbose) + { + sbuild::log_warning() + << format(_("Using %1% configuration file: ")) + % this->program_name + << DCHROOT_CONF + << endl; + sbuild::log_info() + << format(_("Run '%1%'")) + % "dchroot --config >> " SCHROOT_CONF + << endl; + sbuild::log_info() + << _("to migrate to a schroot configuration.") + << endl; + sbuild::log_info() + << format(_("Edit '%1%' to add appropriate group access.")) + % SCHROOT_CONF + << endl; + sbuild::log_info() + << format(_("Remove '%1%' to use the new configuration.")) + % DCHROOT_CONF + << endl; + } + } + + if (this->use_dchroot_conf) + { + this->config = + sbuild::chroot_config::ptr(new dchroot_dsa::chroot_config); + if (this->options->load_chroots == true) + this->config->add(DCHROOT_CONF, false); + } + else + { + schroot::main::load_config(); + } +} + +void +main::create_session(sbuild::session::operation sess_op) +{ + sbuild::log_debug(sbuild::DEBUG_INFO) + << "Creating dchroot-dsa session" << endl; + + // Using dchroot.conf implies using dchroot_session_base, which does + // not require user or group access. + this->session = sbuild::session::ptr + (new dchroot_dsa::session("schroot", + this->config, + sess_op, + this->chroots, + this->use_dchroot_conf)); +} diff --git a/dchroot-dsa/dchroot-dsa-main.h b/dchroot-dsa/dchroot-dsa-main.h new file mode 100644 index 00000000..57849982 --- /dev/null +++ b/dchroot-dsa/dchroot-dsa-main.h @@ -0,0 +1,72 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#ifndef DCHROOT_DSA_MAIN_H +#define DCHROOT_DSA_MAIN_H + +#include + +namespace dchroot_dsa +{ + + /** + * Frontend for dchroot-dsa. This class is used to "run" dchroot-dsa. + */ + class main : public schroot::main + { + public: + /** + * The constructor. + * + * @param options the command-line options to use. + */ + main (schroot::options_base::ptr& options); + + /// The destructor. + virtual ~main (); + + protected: + virtual void + compat_check (); + + virtual void + load_config(); + + virtual void + action_config (); + + virtual void + action_list (); + + virtual void + create_session (sbuild::session::operation sess_op); + + private: + bool use_dchroot_conf; + }; + +} + +#endif /* DCHROOT_DSA_MAIN_H */ + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/dchroot-dsa/dchroot-dsa-options.cc b/dchroot-dsa/dchroot-dsa-options.cc new file mode 100644 index 00000000..e5f04323 --- /dev/null +++ b/dchroot-dsa/dchroot-dsa-options.cc @@ -0,0 +1,103 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#include + +#include "dchroot-dsa-options.h" + +#include +#include + +#include +#include + +using std::endl; +using boost::format; +namespace opt = boost::program_options; +using namespace dchroot_dsa; + +options::options (int argc, + char *argv[]): + schroot::options_base(argc, argv) +{ + add_options(); + parse_options(argc, argv); + check_options(); + check_actions(); +} + +options::~options () +{ +} + +void +options::add_options () +{ + schroot::options_base::add_options(); + + general.add_options() + ("listpaths,p", + _("Print paths to available chroots")); + + chroot.add_options() + ("all,a", + _("Select all chroots")); +} + +void +options::check_options () +{ + if (vm.count("help")) + { + std::cout + << _("Usage:") << "\n " + << "dchroot-dsa" + << " " + << _("[OPTION...] chroot [COMMAND] - run command or shell in a chroot") + << '\n'; + std::cout << visible << std::flush; + exit(EXIT_SUCCESS); + } + + schroot::options_base::check_options(); + + if (vm.count("listpaths")) + set_action(ACTION_LOCATION); + + if (vm.count("all")) + { + this->all = false; + this->all_chroots = true; + this->all_sessions = false; + } + + // Always preserve environment. + this->preserve = true; + + // If no chroots specified, use the first non-option. + if (this->chroots.empty() && !this->command.empty()) + { + this->chroots.push_back(this->command[0]); + this->command.erase(this->command.begin()); + } + + // dchroot-dsa only allows one command. + if (this->command.size() > 1) + throw opt::validation_error(_("Only one command may be specified")); +} diff --git a/dchroot-dsa/dchroot-dsa-options.h b/dchroot-dsa/dchroot-dsa-options.h new file mode 100644 index 00000000..cde1e7e4 --- /dev/null +++ b/dchroot-dsa/dchroot-dsa-options.h @@ -0,0 +1,64 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#ifndef DCHROOT_DSA_OPTIONS_H +#define DCHROOT_DSA_OPTIONS_H + +#include + +namespace dchroot_dsa +{ + + /** + * dchroot-dsa command-line options. + */ + class options : public schroot::options_base + { + public: + + /** + * The constructor. + * + * @param argc the number of arguments. + * @param argv the list of arguments. + */ + options (int argc, + char *argv[]); + + /// The destructor. + virtual ~options (); + + protected: + virtual void + add_options (); + + virtual void + check_options (); + }; + +} + +#endif /* DCHROOT_DSA_OPTIONS_H */ + +/* + * Local Variables: + * mode:C++ + * End: + */ + diff --git a/dchroot-dsa/dchroot-dsa-session.cc b/dchroot-dsa/dchroot-dsa-session.cc new file mode 100644 index 00000000..31fe7b14 --- /dev/null +++ b/dchroot-dsa/dchroot-dsa-session.cc @@ -0,0 +1,139 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#include + +#include "dchroot-dsa-session.h" + +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include + +#include + +using std::cout; +using std::endl; +using boost::format; +using sbuild::string_list; +using namespace dchroot_dsa; + +session::session (std::string const& service, + config_ptr& config, + operation operation, + string_list const& chroots, + bool compat): + dchroot::session_base(service, config, operation, chroots, compat) +{ +} + +session::~session () +{ +} + +sbuild::auth::status +session::get_chroot_auth_status (sbuild::auth::status status, + sbuild::chroot::ptr const& chroot) const +{ + /* DSA dchroot checks for a valid user in the groups list, unless + the groups lists is empty in which case there are no + restrictions. This only applies if not switching users (dchroot + does not support user switching) */ + + if (get_compat() == true) + { + string_list const& users = chroot->get_users(); + string_list const& groups = chroot->get_groups(); + + if (this->get_ruid() == this->get_uid() && + users.empty() && groups.empty()) + status = change_auth(status, auth::STATUS_NONE); + else + status = change_auth(status, + sbuild::session::get_chroot_auth_status(status, + chroot)); + } + else // schroot compatibility + { + status = change_auth(status, + sbuild::session::get_chroot_auth_status(status, + chroot)); + } + + return status; +} + +string_list +session::get_login_directories () const +{ + string_list ret; + + ret.push_back(get_home()); + + // Final fallback to root. + if (std::find(ret.begin(), ret.end(), "/") == ret.end()) + ret.push_back("/"); + + return ret; +} + +void +session::get_user_command (sbuild::chroot::ptr& session_chroot, + std::string& file, + string_list& command) const +{ + std::string programstring = command[0]; + file = programstring; + + if (file.empty() || + (file.size() >= 1 && file[0] != '/')) + { + sbuild::log_error() + << format(_("%1%: Command must have an absolute path")) + % file + << endl; + exit (EXIT_FAILURE); + } + + + std::string commandstring = sbuild::string_list_to_string(command, " "); + sbuild::log_debug(sbuild::DEBUG_NOTICE) + << format("Running command: %1%") % commandstring << endl; + syslog(LOG_USER|LOG_NOTICE, "[%s chroot] (%s->%s) Running command: \"%s\"", + session_chroot->get_name().c_str(), get_ruser().c_str(), get_user().c_str(), commandstring.c_str()); + + if (get_verbosity() != auth::VERBOSITY_QUIET) + { + std::string format_string; + format_string = (_("[%1% chroot] Running command: \"%2%\"")); + + format fmt(format_string); + fmt % session_chroot->get_name() + % programstring; + sbuild::log_info() << fmt << endl; + } +} diff --git a/dchroot-dsa/dchroot-dsa-session.h b/dchroot-dsa/dchroot-dsa-session.h new file mode 100644 index 00000000..c8f5abd0 --- /dev/null +++ b/dchroot-dsa/dchroot-dsa-session.h @@ -0,0 +1,89 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#ifndef DCHROOT_DSA_SESSION_H +#define DCHROOT_DSA_SESSION_H + +#include + +#include + +#include +#include +#include +#include +#include + +namespace dchroot_dsa +{ + + /** + * Session handler for dchroot-dsa sessions. + * + * This class provides the session handling for dchroot-dsa + * compatibility. It overrides the normal authentication checks to + * allow all users to access the service, but enforce dchroot-dsa + * user access controls when present, and it specialises the session + * behaviour to be compatible with the chdir and command execution + * behaviour of dchroot-dsa. + */ + class session : public dchroot::session_base + { + public: + /** + * The constructor. + * + * @param service the PAM service name. + * @param config a shared_ptr to the chroot configuration. + * @param operation the session operation to perform. + * @param chroots the chroots to act upon. + * @param compat true to enable full dchroot compatibility, or + * false to enable schroot compatiblity (permissions checks). + */ + session (std::string const& service, + config_ptr& config, + operation operation, + sbuild::string_list const& chroots, + bool compat); + + /// The destructor. + virtual ~session (); + + virtual sbuild::auth::status + get_chroot_auth_status (sbuild::auth::status status, + sbuild::chroot::ptr const& chroot) const; + + virtual sbuild::string_list + get_login_directories () const; + + virtual void + get_user_command (sbuild::chroot::ptr& session_chroot, + std::string& file, + sbuild::string_list& command) const; + }; + +} + +#endif /* DCHROOT_DSA_SESSION_H */ + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/dchroot-dsa/dchroot-dsa.1.in b/dchroot-dsa/dchroot-dsa.1.in new file mode 100644 index 00000000..ebb207ae --- /dev/null +++ b/dchroot-dsa/dchroot-dsa.1.in @@ -0,0 +1,245 @@ +.\" Copyright © 2005-2006 Roger Leigh +.\" +.\" schroot is free software; you can redistribute it and/or modify it +.\" under the terms of the GNU General Public License as published by +.\" the Free Software Foundation; either version 2 of the License, or +.\" (at your option) any later version. +.\" +.\" schroot is distributed in the hope that it will be useful, but +.\" WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +.\" General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program; if not, write to the Free Software +.\" Foundation, Inc., 59 Temple Place, Suite 330, Boston, +.\" MA 02111-1307 USA +.TH DCHROOT-DSA 1 "@RELEASE_DATE@" "Version @VERSION@" "Debian sbuild" +.SH NAME +dchroot\-dsa \- enter a chroot environment +.SH SYNOPSIS +.B dchroot\-dsa +[\fIOPTION\fP]... [chroot] [\fICOMMAND\fP] +.SH DESCRIPTION +\fBdchroot\-dsa\fP allows the user to run a command or a login shell in a +chroot environment. If no command is specified, a login shell will be started +in the user's home directory inside the chroot. +.PP +The user's environment will be preserved inside the chroot. +.PP +The command is a single argument which must be an absolute path to the program. +Additional options are not permitted. +.PP +The login shell or command will run in the user's home directory inside the +chroot, or / if the home directory is not available. +.PP +This version of \fBdchroot\-dsa\fP is a compatibility wrapper around the +.BR schroot (1) +program. It is provided for backward compatibility with the \fBdchroot\-dsa\fP +command-line options, but \fBschroot\fP is recommended for future use. See the +section \[lq]\fIMigration\fP\[rq] below for help migrating your existing +\fBdchroot\-dsa\fP configuration to \fBschroot\fP. See the section +\[lq]\fIIncompatibilities\fP\[rq] below for known incompatibilities with +\fBdchroot\-dsa\fP. +.PP +.SH OPTIONS +\fBdchroot\-dsa\fP accepts the following options: +.SS Basic options +.TP +.B \-h, \-\-help +Show help summary. +.TP +.B \-a, \-\-all +Select all chroots. Note that the original \fBdchroot\-dsa\fP did not include +this option. +.TP +.B \-c, \-\-chroot=\fIchroot\fP +Specify a chroot to use. This option may be used multiple times to specify +more than one chroot, in which case its effect is similar to \fB\-\-all\fP. If +this option is not used, the first non-option argument specified the chroot to +use. Note that the original \fBdchroot\-dsa\fP did not include this option. +.TP +.B \-l, \-\-list +List all available chroots. +.TP +.B \-i, \-\-info +Print detailed information about the available chroots. Note that the original +\fBdchroot\-dsa\fP did not include this option. +.TP +.B \-p, \-\-listpaths +Print absolute locations (paths) of the available chroots. +.TP +.B \-\-config +Print configuration of the available chroots. This is useful for testing that +the configuration in use is the same as the configuration file. Any comments +in the original file will be missing. Note that the original +\fBdchroot\-dsa\fP did not include this option. +.TP +.B \-q, \-\-quiet +Print only essential messages. Note that the original \fBdchroot\-dsa\fP did +not include this option. +.TP +.B \-v, \-\-verbose +Print all messages. Note that the original \fBdchroot\-dsa\fP did not include +this option. +.TP +.B \-V, \-\-version +Print version information. +.SH CONFIGURATION +The original \fBdchroot\-dsa\fP configuration file, \fI@DCHROOT_CONF@\fP has +the following format: +.IP \[bu] +\[oq]#\[cq] starts a comment line. +.IP \[bu] +Blank lines are ignored. +.IP \[bu] +Chroot definitions are a single line containing an \fIidentifier\fP, +\fIpath\fP, and an optional \fIuser list\fP separated by whitespace (space and +tab), or a colon (\[oq]:\[cq]), semicolon (\[oq];\[cq]), or comma +(\[oq],\[cq]). +.PP +An example file: +.PP +.RS +\f[CR]# Example comment\fP +.br +\f[CR]\fP +.br +\f[CR]sarge /srv/chroot/sarge\fP +.br +\f[CR]sid /srv/chroot/sid rleigh,fred\fP +.br +.RE +.PP +This file defines a chroot called \[oq]sarge\[cq], located at +\fI/srv/chroot/sarge\fP, and a second chroot called \[oq]sid\[cq], located at +\fI/srv/chroot/sid\fP. The second chroot specifies that it may only be used by +the users \[lq]rleigh\[rq] and \[lq]fred\[rq]. +.SH INCOMPATIBILITIES +.SS DSA dchroot +.IP \[bu] +Log messages are worded and formatted differently. +.IP \[bu] +\fBdchroot\-dsa\fP provides a restricted subset of the functionality +implemented by \fBschroot\fP, but is still \fBschroot\fP underneath. Thus +\fBdchroot\-dsa\fP is still subject to \fBschroot\fP security checking, +including PAM authentication and authorisation, and session management, for +example, and hence may behave slightly differently to the original +\fBdchroot\-dsa\fP in some circumstances. +.IP \[bu] +The command argument in this version may be absolute or relative, and may +contain as many options as desired. The original version only allowed a single +absolute program name and no options. +.SS Debian dchroot +A \fBdchroot\fP package provides an alternative \fBdchroot\fP implementation. +.IP \[bu] +All the above incompatibilities apply. +.IP \[bu] +This version of dchroot has incompatible command-line options, and while some +of those options are supported or have equivalent options by a different name, +the \fI\-c\fP option is required to specify a chroot. It also allows a shell +script to be used as the option instead of a single absolute path. +.IP \[bu] +This version of dchroot has an incompatible format for \fIdchroot.conf\fP. +While the first two fields are the same, the third field is a optional +personality, instead of the list of users permitted to access the chroot +allowed by this version. If personality support is needed, please use +\fIschroot.conf\fP and add the allowed users there, as shown in +\[lq]\fIMigration\fP\[rq] below. +.SH MIGRATION +To migrate an existing \fBdchroot\-dsa\fP configuration to \fBschroot\fP, +perform the following steps: +.IP 1 +Dump the \fBdchroot\-dsa\fP configuration in \fBschroot\fP keyfile format to +\fI@SCHROOT_CONF@\fP. +.PP +.RS +\f[CR]# \f[CB]dchroot\-dsa --config >> @SCHROOT_CONF@ +.br +.RE +.PP +.IP 2 +Edit \fI@SCHROOT_CONF@\fP to add access to the groups who are to be allowed to +access the chroots, and make any other desired changes to the configuration. +See +.BR schroot.conf (5). +.IP 3 +Remove \fI@DCHROOT_CONF@\fP, so that \fBdchroot\-dsa\fP will subsequently use +\fI@SCHROOT_CONF@\fP for its configuration. If the \fBdchroot\fP package is +still installed, purge it, or else delete the file. +.SH EXAMPLES +\f[CR]$ dchroot\-dsa -l\fP +.br +\f[CR]Available chroots: sarge, sid\fP +.br +\f[CR]\fP +.br +\f[CR]$ dchroot\-dsa \-\-listpaths\fP +.br +\f[CR]/srv/chroot/sarge\fP +.br +\f[CR]/srv/chroot/sid\fP +.br +\f[CR]\fP +.br +\f[CR]$ dchroot\-dsa \-q sid \-\- /bin/uname\fP +.br +\f[CR]Linux\fP +.br +\f[CR]\fP +.br +\f[CR]$ dchroot\-dsa sid\fP +.br +\f[CR]I: [sid chroot] Running login shell: \[lq]/bin/bash\[rq]\fP +.br +\f[CR]$ \fP +.br +.LP +Use \fB\-\-\fP to allow options beginning with \[oq]\-\[cq] or \[oq]\-\-\[cq] +in the command to run in the chroot. This prevents them being interpreted as +options for \fBschroot\fP itself. Note that the top line was echoed to +standard error, and the remaining lines to standard output. This is +intentional, so that program output from commands run in the chroot may be +piped and redirected as required; the data will be the same as if the command +was run directly on the host system. +.SH BUGS +None known at this time. +.SH FILES +.TP +.I @DCHROOT_CONF@ +The system-wide \fBdchroot\-dsa\fP chroot definition file. This file must be +owned by the root user, and not be writable by other. If present, this file +will be used in preference to @SCHROOT_CONF@. +.TP +.I @SCHROOT_CONF@ +The system-wide \fBschroot\fP definition file. This file must be owned by the +root user, and not be writable by other. It is recommended that this file be +used in preference to \fI@DCHROOT_CONF@\fP, because the chroots can be used +interchangeably with \fBschroot\fP, and the group security policies provided by +\fBschroot\fP are also enforced. +.SH AUTHORS +Roger Leigh. +.PP +This implementation of \fBdchroot\-dsa\fP uses the same command-line options as +the original \fBdchroot\-dsa\fP found on machines run by the Debian System +Administrators for the Debian Project have a \fBdchroot-dsa\fP source package +which also provides a \fBdchroot\-dsa\fP package. +.SH COPYRIGHT +Copyright \(co 2005-2006 Roger Leigh +.PP +This program is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your option) +any later version. +.SH SEE ALSO +.BR schroot (1), +.BR sbuild (1), +.BR chroot (2), +.BR schroot-setup (5), +.BR schroot.conf (5). +.\"# +.\"# The following sets edit modes for GNU EMACS +.\"# Local Variables: +.\"# mode:nroff +.\"# fill-column:79 +.\"# End: diff --git a/dchroot-dsa/dchroot-dsa.cc b/dchroot-dsa/dchroot-dsa.cc new file mode 100644 index 00000000..737a8eb9 --- /dev/null +++ b/dchroot-dsa/dchroot-dsa.cc @@ -0,0 +1,77 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#include + +#include "dchroot-dsa-main.h" +#include "dchroot-dsa-options.h" + +#include +#include +#include + +#include + +#include + +using std::endl; +using boost::format; +using namespace schroot; + +/** + * Main routine. + * + * @param argc the number of arguments + * @param argv argument vector + * + * @returns 0 on success, 1 on failure or the exit status of the + * chroot command. + */ +int +main (int argc, + char *argv[]) +{ + try + { + // Set up locale. + std::locale::global(std::locale("")); + std::cout.imbue(std::locale()); + std::cerr.imbue(std::locale()); + + dchroot_dsa::options::ptr opts(new dchroot_dsa::options(argc, argv)); + dchroot_dsa::main kit(opts); + exit (kit.run()); + } + catch (std::exception const& e) + { + sbuild::log_error() << e.what() << endl; + exit(EXIT_FAILURE); + } + catch (...) + { + sbuild::log_error() << _("An unknown exception occured") << endl; + exit(EXIT_FAILURE); + } +} + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/dchroot/Makefile.am b/dchroot/Makefile.am new file mode 100644 index 00000000..5bc36cb9 --- /dev/null +++ b/dchroot/Makefile.am @@ -0,0 +1,69 @@ +# schroot Makefile template +# +# +# Copyright © 2004-2006 Roger Leigh +# +# schroot is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# schroot is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +##################################################################### + +localedir = $(datadir)/locale +pkglibexecdir = $(SCHROOT_LIBEXEC_DIR) + +AM_CXXFLAGS = $(SCHROOT_CFLAGS) -pedantic -Wall -Wcast-align -Wwrite-strings -Wswitch-default -Wcast-qual -Wunused-variable -Wredundant-decls -Wctor-dtor-privacy -Wnon-virtual-dtor -Wreorder -Wold-style-cast -Woverloaded-virtual -fstrict-aliasing +# -Weffc++ causes too many warnings in standard headers; -Wextra is not +# supported by GCC 3.4. + +DEFS = -DGETTEXT_PACKAGE=\"schroot\" -DLOCALEDIR=\"$(localedir)\" -D_GNU_SOURCE + +if BUILD_LIBDCHROOT +noinst_LTLIBRARIES = libdchroot.la +endif + +if BUILD_DCHROOT +dchroot = dchroot +endif + +bin_PROGRAMS = $(dchroot) + +libdchroot_la_SOURCES = \ + dchroot-session-base.h \ + dchroot-session-base.cc +libdchroot_la_LIBADD = $(top_builddir)/schroot/libschroot.la + +dchroot_SOURCES = \ + dchroot-chroot-config.h \ + dchroot-chroot-config.cc \ + dchroot-session.h \ + dchroot-session.cc \ + dchroot-options.h \ + dchroot-options.cc \ + dchroot-main.h \ + dchroot-main.cc \ + dchroot.cc +dchroot_LDADD = libdchroot.la + +if BUILD_DCHROOT +dchroot_mans = dchroot.1 +endif + +man_MANS = $(dchroot_mans) + +install-exec-hook: +# Install setuid root. + if [ -f "$(DESTDIR)$(bindir)/dchroot" ]; then \ + chmod 4755 "$(DESTDIR)$(bindir)/dchroot"; \ + fi diff --git a/dchroot/dchroot-chroot-config.cc b/dchroot/dchroot-chroot-config.cc new file mode 100644 index 00000000..3a3a16b2 --- /dev/null +++ b/dchroot/dchroot-chroot-config.cc @@ -0,0 +1,155 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#include + +#include +#include + +#include "dchroot-chroot-config.h" + +#include +#include +#include +#include + +#include + +using std::endl; +using sbuild::parse_error; +using boost::format; +using namespace dchroot; + +chroot_config::chroot_config (): + sbuild::chroot_config() +{ +} + +chroot_config::chroot_config (std::string const& file, + bool active): + sbuild::chroot_config(file, active) +{ +} + +chroot_config::~chroot_config () +{ +} + +void +chroot_config::parse_data (std::istream& stream, + bool active) +{ + active = false; // dchroot does not support sessions. + + size_t linecount = 0; + std::string line; + std::string chroot_name; + std::string chroot_location; + bool default_set = false; + + while (std::getline(stream, line)) + { + linecount++; + + if (line[0] == '#') + { + // Comment line; do nothing. + } + else if (line.length() == 0) + { + // Empty line; do nothing. + } + else // Item + { + static const char *whitespace = " \t"; + + // Get chroot name + std::string::size_type cstart = line.find_first_not_of(whitespace); + std::string::size_type cend = line.find_first_of(whitespace, cstart); + + // Get chroot location + std::string::size_type lstart = line.find_first_not_of(whitespace, + cend); + std::string::size_type lend = line.find_first_of(whitespace, lstart); + + // Get chroot personality + std::string::size_type pstart = line.find_first_not_of(whitespace, + lend); + std::string::size_type pend = line.find_first_of(whitespace, pstart); + + // Check for trailing non-whitespace. + std::string::size_type tstart = line.find_first_not_of(whitespace, + pend); + if (cstart == std::string::npos || + cend == std::string::npos || + lstart == std::string::npos) + { + throw parse_error(linecount, parse_error::INVALID_LINE, line); + } + + if (tstart != std::string::npos) + { + throw parse_error(linecount, parse_error::INVALID_LINE, line); + } + + std::string chroot_name = line.substr(cstart, cend - cstart); + std::string location = line.substr(lstart, lend - lstart); + + std::string personality; + if (pstart != std::string::npos) + personality = line.substr(pstart, pend - pstart); + + /* Create chroot object. */ + sbuild::chroot::ptr chroot = sbuild::chroot::create("plain"); + chroot->set_active(active); + chroot->set_name(chroot_name); + + format fmt(_("%1% chroot (dchroot compatibility)")); + fmt % chroot_name; + chroot->set_description(fmt.str()); + + if (pstart != std::string::npos) + chroot->set_persona(sbuild::personality(personality)); + + sbuild::chroot_plain *plain = + dynamic_cast(chroot.get()); + plain->set_location(location); + + if (chroot_name == "default") + default_set = true; + + // Set default chroot. + if (!default_set) + { + sbuild::string_list aliases; + aliases.push_back("default"); + chroot->set_aliases(aliases); + default_set = true; + } + + add(chroot); + } + } +} + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/dchroot/dchroot-chroot-config.h b/dchroot/dchroot-chroot-config.h new file mode 100644 index 00000000..f36c72ed --- /dev/null +++ b/dchroot/dchroot-chroot-config.h @@ -0,0 +1,74 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#ifndef DCHROOT_CHROOT_CONFIG_H +#define DCHROOT_CHROOT_CONFIG_H + +#include + +#include +#include +#include +#include + +namespace dchroot +{ + + /** + * Chroot configuration for dchroot compatibility. + * + * This class provides all the functionality of chroot_config, but + * parses the dchroot configuration file format, rather than the + * schroot format. + */ + class chroot_config : public sbuild::chroot_config + { + public: + /// The constructor. + chroot_config (); + + /** + * The constructor. + * + * @param file initialise using a configuration file or a whole + * directory containing configuration files. + * @param active true if the chroots in the configuration file are + * active sessions, otherwise false. + */ + chroot_config (std::string const& file, + bool active); + + /// The destructor. + virtual ~chroot_config (); + + private: + virtual void + parse_data (std::istream& stream, + bool active); + }; + +} + +#endif /* DCHROOT_CHROOT_CONFIG_H */ + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/dchroot/dchroot-main.cc b/dchroot/dchroot-main.cc new file mode 100644 index 00000000..cbcc1f4c --- /dev/null +++ b/dchroot/dchroot-main.cc @@ -0,0 +1,163 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#include + +#include "dchroot-main.h" +#include "dchroot-chroot-config.h" +#include "dchroot-session.h" + +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include + +using std::endl; +using boost::format; +using schroot::options_base; +using namespace dchroot; + +main::main (options_base::ptr& options): + schroot::main(options), + use_dchroot_conf(false) +{ + this->program_name = "dchroot"; +} + +main::~main () +{ +} + +void +main::action_config () +{ + std::cout << "# " + << format(_("schroot configuration generated by %1% %2%")) + % this->program_name % VERSION + << endl; + // Help text at head of new config. + std::cout << "# " << endl + << "# " + << _("To allow users access to the chroots, use the users or groups keys.") << endl; + std::cout << "# " + << _("To allow passwordless root access, use the root-users or root-groups keys.") << endl; + std::cout << "# " + << format(_("Remove '%1%' to use the new configuration.")) + % DCHROOT_CONF + << endl; + std::cout << endl; + this->config->print_chroot_config(this->chroots, std::cout); +} + +void +main::action_list () +{ + this->config->print_chroot_list_simple(std::cout); +} + +void +main::action_location () +{ + sbuild::string_list chroot; + chroot.push_back(this->options->chroot_path); + this->config->print_chroot_location(chroot, std::cout); +} + +void +main::compat_check () +{ + if (this->options->verbose) + { + sbuild::log_warning() + << _("Running schroot in dchroot compatibility mode") + << endl; + sbuild::log_info() + << _("Run 'schroot' for full capabilities") + << endl; + } +} + +void +main::load_config () +{ + this->use_dchroot_conf = false; + struct stat statbuf; + if (stat(DCHROOT_CONF, &statbuf) == 0 && !S_ISDIR(statbuf.st_mode)) + { + this->use_dchroot_conf = true; + + if (this->options->verbose) + { + sbuild::log_warning() + << format(_("Using %1% configuration file: ")) + % this->program_name + << DCHROOT_CONF + << endl; + sbuild::log_info() + << format(_("Run '%1%'")) + % "dchroot --config >> " SCHROOT_CONF + << endl; + sbuild::log_info() + << _("to migrate to a schroot configuration.") + << endl; + sbuild::log_info() + << format(_("Edit '%1%' to add appropriate group access.")) + % SCHROOT_CONF + << endl; + sbuild::log_info() + << format(_("Remove '%1%' to use the new configuration.")) + % DCHROOT_CONF + << endl; + } + } + + if (this->use_dchroot_conf) + { + this->config = sbuild::chroot_config::ptr(new dchroot::chroot_config); + if (this->options->load_chroots == true) + this->config->add(DCHROOT_CONF, false); + } + else + { + schroot::main::load_config(); + } +} + +void +main::create_session (sbuild::session::operation sess_op) +{ + sbuild::log_debug(sbuild::DEBUG_INFO) << "Creating dchroot session" << endl; + + // Using dchroot.conf implies using dchroot_session_base, which does + // not require user or group access. + this->session = sbuild::session::ptr + (new dchroot::session("schroot", + this->config, + sess_op, + this->chroots, + this->use_dchroot_conf)); +} diff --git a/dchroot/dchroot-main.h b/dchroot/dchroot-main.h new file mode 100644 index 00000000..8e5ab155 --- /dev/null +++ b/dchroot/dchroot-main.h @@ -0,0 +1,75 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#ifndef DCHROOT_MAIN_H +#define DCHROOT_MAIN_H + +#include + +namespace dchroot +{ + + /** + * Frontend for dchroot. This class is used to "run" dchroot. + */ + class main : public schroot::main + { + public: + /** + * The constructor. + * + * @param options the command-line options to use. + */ + main (schroot::options_base::ptr& options); + + /// The destructor. + virtual ~main (); + + protected: + virtual void + compat_check (); + + virtual void + load_config(); + + virtual void + action_config (); + + virtual void + action_list (); + + virtual void + action_location (); + + virtual void + create_session (sbuild::session::operation sess_op); + + private: + bool use_dchroot_conf; + }; + +} + +#endif /* DCHROOT_MAIN_H */ + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/dchroot/dchroot-options.cc b/dchroot/dchroot-options.cc new file mode 100644 index 00000000..998e257a --- /dev/null +++ b/dchroot/dchroot-options.cc @@ -0,0 +1,129 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#include + +#include "dchroot-options.h" + +#include +#include + +#include +#include + +using std::endl; +using boost::format; +namespace opt = boost::program_options; +using namespace dchroot; + +options::options (int argc, + char *argv[]): + schroot::options_base(argc, argv) +{ + add_options(); + parse_options(argc, argv); + check_options(); + check_actions(); +} + +options::~options () +{ +} + +void +options::add_options () +{ + schroot::options_base::add_options(); + + general.add_options() + ("path,p", opt::value(&this->chroot_path), + _("Print path to selected chroot")); + + chroot.add_options() + ("all,a", + _("Select all chroots")); + + chrootenv.add_options() + ("preserve-environment,d", + _("Preserve user environment")); +} + +void +options::check_options () +{ + if (vm.count("help")) + { + std::cout + << _("Usage:") << "\n " + << "dchroot" + << " " + << _("[OPTION...] [COMMAND] - run command or shell in a chroot") + << '\n'; + std::cout << visible << std::flush; + exit(EXIT_SUCCESS); + } + + schroot::options_base::check_options(); + + if (vm.count("path")) + set_action(ACTION_LOCATION); + + if (vm.count("all")) + { + this->all = false; + this->all_chroots = true; + this->all_sessions = false; + } + + if (vm.count("preserve-environment")) + this->preserve = true; + + // dchroot only allows one command. + if (this->command.size() > 1) + throw opt::validation_error(_("Only one command may be specified")); + + if (this->quiet && this->verbose) + { + sbuild::log_warning() + << _("--quiet and --verbose may not be used at the same time") + << endl; + sbuild::log_info() << _("Using verbose output") << endl; + } + + if (!this->chroots.empty() && all_used()) + { + sbuild::log_warning() + << _("--chroot and --all may not be used at the same time") + << endl; + sbuild::log_info() << _("Using --chroots only") << endl; + this->all = this->all_chroots = this->all_sessions = false; + } + + if (this->all == true) + { + this->all_chroots = true; + this->all_sessions = true; + } +} + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/dchroot/dchroot-options.h b/dchroot/dchroot-options.h new file mode 100644 index 00000000..51da9555 --- /dev/null +++ b/dchroot/dchroot-options.h @@ -0,0 +1,63 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#ifndef DCHROOT_OPTIONS_H +#define DCHROOT_OPTIONS_H + +#include + +namespace dchroot +{ + + /** + * dchroot command-line options. + */ + class options : public schroot::options_base + { + public: + /** + * The constructor. + * + * @param argc the number of arguments. + * @param argv the list of arguments. + */ + options (int argc, + char *argv[]); + + /// The destructor. + virtual ~options (); + + protected: + virtual void + add_options (); + + virtual void + check_options (); + }; + +} + +#endif /* DCHROOT_OPTIONS_H */ + +/* + * Local Variables: + * mode:C++ + * End: + */ + diff --git a/dchroot/dchroot-session-base.cc b/dchroot/dchroot-session-base.cc new file mode 100644 index 00000000..01fca798 --- /dev/null +++ b/dchroot/dchroot-session-base.cc @@ -0,0 +1,96 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#include + +#include "dchroot-session-base.h" + +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include + +#include + +using std::cout; +using std::endl; +using boost::format; +using sbuild::string_list; +using namespace dchroot; + +session_base::session_base (std::string const& service, + config_ptr& config, + operation operation, + string_list const& chroots, + bool compat): + sbuild::session(service, config, operation, chroots), + compat(compat) +{ +} + +session_base::~session_base () +{ +} + +bool +session_base::get_compat () const +{ + return this->compat; +} + +void +session_base::set_compat (bool state) +{ + this->compat = state; +} + +void +session_base::run_impl () +{ + if (get_ruid() != get_uid()) + { + format fmt(_("(%1%->%2%): dchroot sessions do not support user switching")); + fmt % get_ruser().c_str() % get_user().c_str(); + throw error(fmt.str(), USER_SWITCH, _("dchroot session restriction")); + } + + sbuild::session::run_impl(); +} + +string_list +session_base::get_command_directories () const +{ + // dchroot does not treat logins differently from commands with + // respect to the cwd inside the chroot. + return get_login_directories(); +} + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/dchroot/dchroot-session-base.h b/dchroot/dchroot-session-base.h new file mode 100644 index 00000000..cd442518 --- /dev/null +++ b/dchroot/dchroot-session-base.h @@ -0,0 +1,102 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#ifndef DCHROOT_SESSION_BASE_H +#define DCHROOT_SESSION_BASE_H + +#include + +#include + +#include +#include +#include +#include +#include + +namespace dchroot +{ + + /** + * Basic session handler for dchroot sessions. + * + * This class provides common session functionality for dchroot and + * dchroot-dsa, such as providing a schroot compatibility mode. It + * also prevents user switching when running sessions, which is + * forbidden. + */ + class session_base : public sbuild::session + { + public: + /** + * The constructor. + * + * @param service the PAM service name. + * @param config a shared_ptr to the chroot configuration. + * @param operation the session operation to perform. + * @param chroots the chroots to act upon. + * @param compat true to enable full dchroot compatibility, or + * false to enable schroot compatiblity (permissions checks). + */ + session_base (std::string const& service, + config_ptr& config, + operation operation, + sbuild::string_list const& chroots, + bool compat); + + /// The destructor. + virtual ~session_base (); + + /** + * Get the dchroot compatibility state. + * + * @returns the state. + */ + bool + get_compat () const; + + /** + * Set the dchroot compatibility state. + * + * @param state the dchroot compatibility state. + */ + void + set_compat (bool state); + + protected: + virtual void + run_impl (); + + virtual sbuild::string_list + get_command_directories () const; + + private: + /// dchroot compatibility enabled? + bool compat; + }; + +} + +#endif /* DCHROOT_SESSION_BASE_H */ + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/dchroot/dchroot-session.cc b/dchroot/dchroot-session.cc new file mode 100644 index 00000000..09c5e8aa --- /dev/null +++ b/dchroot/dchroot-session.cc @@ -0,0 +1,123 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#include + +#include "dchroot-session.h" + +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include + +#include + +using std::cout; +using std::endl; +using boost::format; +using sbuild::string_list; +using namespace dchroot; + +session::session (std::string const& service, + config_ptr& config, + operation operation, + string_list const& chroots, + bool compat): + session_base(service, config, operation, chroots, compat) +{ +} + +session::~session () +{ +} + +sbuild::auth::status +session::get_chroot_auth_status (sbuild::auth::status status, + sbuild::chroot::ptr const& chroot) const +{ + if (get_compat() == true) + status = change_auth(status, auth::STATUS_NONE); + else + status = change_auth(status, + sbuild::session::get_chroot_auth_status(status, + chroot)); + + return status; +} + +string_list +session::get_login_directories () const +{ + string_list ret; + + // Set current working directory only if preserving environment. + // Only change to home if not preserving the environment. + if (!get_environment().empty()) + ret.push_back(this->sbuild::session::cwd); + else + ret.push_back(get_home()); + + // Final fallback to root. + if (std::find(ret.begin(), ret.end(), "/") == ret.end()) + ret.push_back("/"); + + return ret; +} + +void +session::get_user_command (sbuild::chroot::ptr& session_chroot, + std::string& file, + string_list& command) const +{ + std::string programstring = command[0]; + + command.clear(); + command.push_back(get_shell()); + command.push_back("-c"); + command.push_back(programstring); + + file = command[0]; + + sbuild::log_debug(sbuild::DEBUG_NOTICE) << "file=" << file << endl; + + std::string commandstring = sbuild::string_list_to_string(command, " "); + sbuild::log_debug(sbuild::DEBUG_NOTICE) + << format("Running command: %1%") % commandstring << endl; + syslog(LOG_USER|LOG_NOTICE, "[%s chroot] (%s->%s) Running command: \"%s\"", + session_chroot->get_name().c_str(), get_ruser().c_str(), get_user().c_str(), commandstring.c_str()); + + if (get_verbosity() != auth::VERBOSITY_QUIET) + { + std::string format_string; + format_string = (_("[%1% chroot] Running command: \"%2%\"")); + + format fmt(format_string); + fmt % session_chroot->get_name() + % programstring; + sbuild::log_info() << fmt << endl; + } +} diff --git a/dchroot/dchroot-session.h b/dchroot/dchroot-session.h new file mode 100644 index 00000000..5953b833 --- /dev/null +++ b/dchroot/dchroot-session.h @@ -0,0 +1,88 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#ifndef DCHROOT_SESSION_H +#define DCHROOT_SESSION_H + +#include + +#include + +#include +#include +#include +#include +#include + +namespace dchroot +{ + + /** + * Session handler for dchroot sessions. + * + * This class provides the session handling for dchroot + * compatibility. It overrides the normal authentication checks to + * allow all users to access the service, and it specialises the + * session behaviour to be compatible with the chdir and command + * execution behaviour of dchroot. + */ + class session : public session_base + { + public: + /** + * The constructor. + * + * @param service the PAM service name. + * @param config a shared_ptr to the chroot configuration. + * @param operation the session operation to perform. + * @param chroots the chroots to act upon. + * @param compat true to enable full dchroot compatibility, or + * false to enable schroot compatiblity (permissions checks). + */ + session (std::string const& service, + config_ptr& config, + operation operation, + sbuild::string_list const& chroots, + bool compat); + + /// The destructor. + virtual ~session (); + + virtual sbuild::auth::status + get_chroot_auth_status (sbuild::auth::status status, + sbuild::chroot::ptr const& chroot) const; + + virtual sbuild::string_list + get_login_directories () const; + + virtual void + get_user_command (sbuild::chroot::ptr& session_chroot, + std::string& file, + sbuild::string_list& command) const; + }; + +} + +#endif /* DCHROOT_SESSION_H */ + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/dchroot/dchroot.1.in b/dchroot/dchroot.1.in new file mode 100644 index 00000000..247a29b5 --- /dev/null +++ b/dchroot/dchroot.1.in @@ -0,0 +1,258 @@ +.\" Copyright © 2005-2006 Roger Leigh +.\" +.\" schroot is free software; you can redistribute it and/or modify it +.\" under the terms of the GNU General Public License as published by +.\" the Free Software Foundation; either version 2 of the License, or +.\" (at your option) any later version. +.\" +.\" schroot is distributed in the hope that it will be useful, but +.\" WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +.\" General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program; if not, write to the Free Software +.\" Foundation, Inc., 59 Temple Place, Suite 330, Boston, +.\" MA 02111-1307 USA +.TH DCHROOT 1 "@RELEASE_DATE@" "Version @VERSION@" "Debian sbuild" +.SH NAME +dchroot \- enter a chroot environment +.SH SYNOPSIS +.B dchroot +[\fIOPTION\fP]... [\fICOMMAND\fP] +.SH DESCRIPTION +\fBdchroot\fP allows the user to run a command or a login shell in a chroot +environment. If no command is specified, a login shell will be started in the +user's home directory inside the chroot. +.PP +The command is a single argument which will be run in the user's default shell +using its \[lq]\-c\[rq] option. As a result, shell code may be embedded in +this argument. +.PP +Unless the \fI-d\fP option is used to preserve the environment, the login shell +or command will run in the user's home directory inside the chroot, or / if the +home directory is not available. When the \fI-d\fP option is used, it will +attempt to use the current working directory inside the chroot, again falling +back to / if it is not accessible. +.PP +This version of \fBdchroot\fP is a compatibility wrapper around the +.BR schroot (1) +program. It is provided for backward compatibility with the \fBdchroot\fP +command-line options, but \fBschroot\fP is recommended for future use. See the +section \[lq]\fIMigration\fP\[rq] below for help migrating an existing +\fBdchroot\fP configuration to \fBschroot\fP. See the section +\[lq]\fIIncompatibilities\fP\[rq] below for known incompatibilities with +\fBdchroot\fP. +.PP +If no chroot is specified, the chroot name or alias \fBdefault\fP will be used +as a fallback. If using the configuration in \fI@DCHROOT_CONF@\fP, the first +chroot in the file is the default. +.SH OPTIONS +Note that the original \fBdchroot\fP did not provide long options. +\fBdchroot\fP accepts the following options: +.SS Basic options +.TP +.B \-h, \-\-help +Show help summary. +.TP +.B \-a, \-\-all +Select all chroots. +.TP +.B \-c, \-\-chroot=\fIchroot\fP +Specify a chroot to use. This option may be used multiple times to specify +more than one chroot, in which case its effect is similar to \fB\-\-all\fP. +.TP +.B \-l, \-\-list +List all available chroots. +.TP +.B \-i, \-\-info +Print detailed information about the specified chroots. Note that the original +\fBdchroot\fP did not include this option. +.TP +.B \-p, \-\-path +Print location (path) of the specified chroots. +.TP +.B \-\-config +Print configuration of the specified chroots. This is useful for testing that +the configuration in use is the same as the configuration file. Any comments +in the original file will be missing. Note that the original \fBdchroot\fP did +not include this option. +.TP +.B \-d, \-\-preserve\-environment +Preserve the user's environment inside the chroot environment. The default is +to use a clean environment; this option copies the entire user environment and +sets it in the session. +.TP +.B \-q, \-\-quiet +Print only essential messages. +.TP +.B \-v, \-\-verbose +Print all messages. Note that the original \fBdchroot\fP did not include this +option. +.TP +.B \-V, \-\-version +Print version information. +.SH CONFIGURATION +The original \fBdchroot\fP configuration file, \fI@DCHROOT_CONF@\fP has the +following format: +.IP \[bu] +\[oq]#\[cq] starts a comment line. +.IP \[bu] +Blank lines are ignored. +.IP \[bu] +Chroot definitions are a single line containing an \fIidentifier\fP, +\fIpath\fP, and an optional \fIpersonality\fP separated by whitespace. The +first chroot is also the default. +.PP +An example file: +.PP +.RS +\f[CR]# Example comment\fP +.br +\f[CR]\fP +.br +\f[CR]sarge /srv/chroot/sarge\fP +.br +\f[CR]sid /srv/chroot/sid linux32\fP +.br +.RE +.PP +This file defines a chroot called \[oq]sarge\[cq], located at +\fI/srv/chroot/sarge\fP, and a second chroot called \[oq]sid\[cq], located at +\fI/srv/chroot/sid\fP. The second chroot uses the \[lq]linux32\[rq] +personality, which allows a 32-bit chroot to be used on a 64-bit system. +\[oq]sarge\[cq] is the default chroot, because it was listed first, which means +if the \fI\-c\fP option is omitted, this chroot will be used. +.SH INCOMPATIBILITIES +.SS Debian dchroot prior to version 0.99. +.IP \[bu] +Log messages are worded and formatted differently. +.IP \[bu] +The parsing of \fI@DCHROOT_CONF@\fP uses a smaller list of allowed whitespace +characters (space and tab), which may cause a parse error during tokenising if +the file contains odd characters as separators, such as carriage returns, +vertical tabs and form feeds. +.IP \[bu] +su is no longer used to run commands in the chroot. This is done by dchroot +internally. This change may cause subtle differences. If you find an +incompatibility, please report it so it can be corrected. +.IP \[bu] +\fBdchroot\fP provides a restricted subset of the functionality implemented by +\fBschroot\fP, but is still \fBschroot\fP underneath. Thus \fBdchroot\fP is +still subject to \fBschroot\fP security checking, including PAM authentication +and authorisation, and session management, for example, and hence may behave +slightly differently to the older \fBdchroot\fP in some circumstances. +.SS DSA dchroot +Machines run by the Debian System Administrators for the Debian Project have a +\fBdchroot-dsa\fP package which provides an alternate \fBdchroot\fP +implementation. +.IP \[bu] +All the above incompatibilities apply. +.IP \[bu] +This version of dchroot has incompatible command-line options, and while some +of those options are supported or have equivalent options by a different name, +the \fI\-c\fP option is not required to specify a chroot, and this version of +dchroot cannot implement this behaviour in a backward-compatible manner +(because if \fI\-c\fP is omitted, the default chroot is used). DSA dchroot +uses the first non-option as the chroot to use, only allowing one chroot to be +used at once. +.IP \[bu] +This version of dchroot has an incompatible format for \fIdchroot.conf\fP. +While the first two fields are the same, the remaining fields are an optional +list of users permitted to access the chroot, instead of the personality field +allowed by this version. If access restrictions are needed, please use +\fIschroot.conf\fP and add the allowed users there, as shown in +\[lq]\fIMigration\fP\[rq] below. +.SH MIGRATION +To migrate an existing \fBdchroot\fP configuration to \fBschroot\fP, perform +the following steps: +.IP 1 +Dump the \fBdchroot\fP configuration in \fBschroot\fP keyfile format to +\fI@SCHROOT_CONF@\fP. +.PP +.RS +\f[CR]# \f[CB]dchroot --config >> @SCHROOT_CONF@ +.br +.RE +.PP +.IP 2 +Edit \fI@SCHROOT_CONF@\fP to add access to the groups who are to be allowed to +access the chroots, and make any other desired changes to the configuration. +See +.BR schroot.conf (5). +.IP 3 +Remove \fI@DCHROOT_CONF@\fP, so that \fBdchroot\fP will subsequently use +\fI@SCHROOT_CONF@\fP for its configuration. +.SH EXAMPLES +\f[CR]$ dchroot \-l\fP +.br +\f[CR]Available chroots: sarge [default], sid\fP +.br +\f[CR]\fP +.br +\f[CR]$ dchroot \-p sid\fP +.br +\f[CR]/srv/chroot/sid\fP +.br +\f[CR]\fP +.br +\f[CR]$ dchroot \-q \-c sid \-\- "uname \-smr"\fP +.br +\f[CR]Linux 2.6.16.17 ppc\fP +.br +\f[CR]\fP +.br +\f[CR]$ dchroot \-c sid\fP +.br +\f[CR]I: [sid chroot] Running login shell: \[lq]/bin/bash\[rq]\fP +.br +\f[CR]$ \fP +.br +.LP +Use \fB\-\-\fP to allow options beginning with \[oq]\-\[cq] or \[oq]\-\-\[cq] +in the command to run in the chroot. This prevents them being interpreted as +options for \fBschroot\fP itself. Note that the top line was echoed to +standard error, and the remaining lines to standard output. This is +intentional, so that program output from commands run in the chroot may be +piped and redirected as required; the data will be the same as if the command +was run directly on the host system. +.SH BUGS +None known at this time. +.SH FILES +.TP +.I @DCHROOT_CONF@ +The system-wide \fBdchroot\fP chroot definition file. This file must be owned +by the root user, and not be writable by other. If present, this file will be +used in preference to @SCHROOT_CONF@. +.TP +.I @SCHROOT_CONF@ +The system-wide \fBschroot\fP definition file. This file must be owned by the +root user, and not be writable by other. It is recommended that this file be +used in preference to \fI@DCHROOT_CONF@\fP, because the chroots can be used +interchangeably with \fBschroot\fP, and the group security policies provided by +\fBschroot\fP are also enforced. +.SH AUTHORS +Roger Leigh. +.PP +This implementation of \fBdchroot\fP uses the same command-line options as the +original \fBdchroot\fP by David Kimdon , but is an +independent implementation. +.SH COPYRIGHT +Copyright \(co 2005-2006 Roger Leigh +.PP +This program is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your option) +any later version. +.SH SEE ALSO +.BR schroot (1), +.BR sbuild (1), +.BR chroot (2), +.BR schroot-setup (5), +.BR schroot.conf (5). +.\"# +.\"# The following sets edit modes for GNU EMACS +.\"# Local Variables: +.\"# mode:nroff +.\"# fill-column:79 +.\"# End: diff --git a/dchroot/dchroot.cc b/dchroot/dchroot.cc new file mode 100644 index 00000000..d7495849 --- /dev/null +++ b/dchroot/dchroot.cc @@ -0,0 +1,77 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#include + +#include "dchroot-main.h" +#include "dchroot-options.h" + +#include +#include +#include + +#include + +#include + +using std::endl; +using boost::format; +using namespace schroot; + +/** + * Main routine. + * + * @param argc the number of arguments + * @param argv argument vector + * + * @returns 0 on success, 1 on failure or the exit status of the + * chroot command. + */ +int +main (int argc, + char *argv[]) +{ + try + { + // Set up locale. + std::locale::global(std::locale("")); + std::cout.imbue(std::locale()); + std::cerr.imbue(std::locale()); + + dchroot::options::ptr opts(new dchroot::options(argc, argv)); + dchroot::main kit(opts); + exit (kit.run()); + } + catch (std::exception const& e) + { + sbuild::log_error() << e.what() << endl; + exit(EXIT_FAILURE); + } + catch (...) + { + sbuild::log_error() << _("An unknown exception occured") << endl; + exit(EXIT_FAILURE); + } +} + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/doc/schroot.dox.in b/doc/schroot.dox.in index 9d75579e..996a86ee 100644 --- a/doc/schroot.dox.in +++ b/doc/schroot.dox.in @@ -459,7 +459,7 @@ WARN_LOGFILE = schroot.log # directories like "/usr/src/myproject". Separate the files or directories # with spaces. -INPUT = @top_srcdir@/schroot +INPUT = @top_srcdir@/sbuild @top_srcdir@/schroot @top_srcdir@/dchroot @top_srcdir@/dchroot-dsa # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp diff --git a/po/POTFILES.in b/po/POTFILES.in index df2506b3..87ba54c5 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -1,30 +1,41 @@ -schroot/dchroot-chroot-config.cc -schroot/dchroot-session.cc -schroot/sbuild-auth.cc -schroot/sbuild-auth-conv.cc -schroot/sbuild-auth-conv-tty.cc -schroot/sbuild-auth-message.cc -schroot/sbuild-chroot-block-device.cc -schroot/sbuild-chroot.cc -schroot/sbuild-chroot-config.cc -schroot/sbuild-chroot-file.cc -schroot/sbuild-chroot-lvm-snapshot.cc -schroot/sbuild-chroot-plain.cc -schroot/sbuild-chroot-source.cc -schroot/sbuild-environment.cc -schroot/sbuild-format-detail.cc -schroot/sbuild-keyfile.cc -schroot/sbuild-lock.cc -schroot/sbuild-log.cc -schroot/sbuild-nostream.cc -schroot/sbuild-parse-error.cc -schroot/sbuild-parse-value.cc -schroot/sbuild-personality.cc -schroot/sbuild-session.cc -schroot/sbuild-util.cc +dchroot/dchroot.cc +dchroot/dchroot-chroot-config.cc +dchroot/dchroot-main.cc +dchroot/dchroot-options.cc +dchroot/dchroot-session-base.cc +dchroot/dchroot-session.cc +dchroot-dsa/dchroot-dsa.cc +dchroot-dsa/dchroot-dsa-chroot-config.cc +dchroot-dsa/dchroot-dsa-main.cc +dchroot-dsa/dchroot-dsa-options.cc +dchroot-dsa/dchroot-dsa-session.cc +sbuild/sbuild-auth.cc +sbuild/sbuild-auth-conv.cc +sbuild/sbuild-auth-conv-tty.cc +sbuild/sbuild-auth-message.cc +sbuild/sbuild-chroot-block-device.cc +sbuild/sbuild-chroot.cc +sbuild/sbuild-chroot-config.cc +sbuild/sbuild-chroot-file.cc +sbuild/sbuild-chroot-lvm-snapshot.cc +sbuild/sbuild-chroot-plain.cc +sbuild/sbuild-chroot-source.cc +sbuild/sbuild-environment.cc +sbuild/sbuild-format-detail.cc +sbuild/sbuild-keyfile.cc +sbuild/sbuild-lock.cc +sbuild/sbuild-log.cc +sbuild/sbuild-nostream.cc +sbuild/sbuild-parse-error.cc +sbuild/sbuild-parse-value.cc +sbuild/sbuild-personality.cc +sbuild/sbuild-session.cc +sbuild/sbuild-util.cc schroot/schroot.cc schroot/schroot-listmounts.cc schroot/schroot-listmounts-options.cc +schroot/schroot-main.cc +schroot/schroot-options-base.cc schroot/schroot-options.cc schroot/schroot-releaselock.cc schroot/schroot-releaselock-options.cc diff --git a/po/en_GB.po b/po/en_GB.po index 0c570e89..0491d0e0 100644 --- a/po/en_GB.po +++ b/po/en_GB.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: schroot 0.1.2\n" "Report-Msgid-Bugs-To: Roger Leigh \n" -"POT-Creation-Date: 2006-06-23 16:39+0100\n" +"POT-Creation-Date: 2006-06-24 00:38+0100\n" "PO-Revision-Date: 2006-06-23 16:45+0100\n" "Last-Translator: Roger Leigh \n" "Language-Team: English \n" @@ -14,669 +14,837 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: schroot/dchroot-chroot-config.cc:124 +#: dchroot/dchroot.cc:68 dchroot-dsa/dchroot-dsa.cc:68 schroot/schroot.cc:68 #, fuzzy +msgid "An unknown exception occured" +msgstr "Unknown action specified" + +#: dchroot/dchroot-chroot-config.cc:123 +#, fuzzy, boost-format msgid "%1% chroot (dchroot compatibility)" msgstr "Running schroot in dchroot compatibility mode" -#: schroot/dchroot-session.cc:118 +#: dchroot/dchroot-main.cc:59 dchroot-dsa/dchroot-dsa-main.cc:58 +#: schroot/schroot-main.cc:73 +#, boost-format +msgid "schroot configuration generated by %1% %2%" +msgstr "schroot configuration generated by %1% %2%" + +#: dchroot/dchroot-main.cc:65 dchroot-dsa/dchroot-dsa-main.cc:64 +msgid "To allow users access to the chroots, use the users or groups keys." +msgstr "To allow users access to the chroots, use the users or groups keys." + +#: dchroot/dchroot-main.cc:67 dchroot-dsa/dchroot-dsa-main.cc:66 +msgid "" +"To allow passwordless root access, use the root-users or root-groups keys." +msgstr "" +"To allow passwordless root access, use the root-users or root-groups keys." + +#: dchroot/dchroot-main.cc:69 dchroot/dchroot-main.cc:132 +#: dchroot-dsa/dchroot-dsa-main.cc:68 dchroot-dsa/dchroot-dsa-main.cc:124 +#, boost-format +msgid "Remove '%1%' to use the new configuration." +msgstr "Remove ‘%1%’ to use the new configuration." + +#: dchroot/dchroot-main.cc:96 dchroot-dsa/dchroot-dsa-main.cc:87 +#, fuzzy +msgid "Running schroot in dchroot compatibility mode" +msgstr "Running schroot in dchroot compatibility mode" + +#: dchroot/dchroot-main.cc:99 dchroot-dsa/dchroot-dsa-main.cc:90 +msgid "Run 'schroot' for full capabilities" +msgstr "Run ‘schroot’ for full capabilities" + +#: dchroot/dchroot-main.cc:116 dchroot-dsa/dchroot-dsa-main.cc:108 +#, fuzzy, boost-format +msgid "Using %1% configuration file: " +msgstr "Using dchroot configuration file: " + +#: dchroot/dchroot-main.cc:121 dchroot-dsa/dchroot-dsa-main.cc:113 +#, boost-format +msgid "Run '%1%'" +msgstr "Run ‘%1%’" + +#: dchroot/dchroot-main.cc:125 dchroot-dsa/dchroot-dsa-main.cc:117 +msgid "to migrate to a schroot configuration." +msgstr "to migrate to a schroot configuration." + +#: dchroot/dchroot-main.cc:128 dchroot-dsa/dchroot-dsa-main.cc:120 +#, boost-format +msgid "Edit '%1%' to add appropriate group access." +msgstr "Edit ‘%1%’ to add appropriate group access." + +#: dchroot/dchroot-options.cc:56 +msgid "Print path to selected chroot" +msgstr "Print path to selected chroot" + +#: dchroot/dchroot-options.cc:60 dchroot-dsa/dchroot-dsa-options.cc:60 +#: schroot/schroot-options.cc:62 +msgid "Select all chroots" +msgstr "Select all chroots" + +#: dchroot/dchroot-options.cc:64 schroot/schroot-options.cc:70 +msgid "Preserve user environment" +msgstr "Preserve user environment" + +#: dchroot/dchroot-options.cc:73 dchroot-dsa/dchroot-dsa-options.cc:69 +#: schroot/schroot-listmounts-options.cc:64 schroot/schroot-options.cc:92 +#: schroot/schroot-releaselock-options.cc:67 +msgid "Usage:" +msgstr "Usage:" + +#: dchroot/dchroot-options.cc:76 schroot/schroot-options.cc:95 +#, fuzzy +msgid "[OPTION...] [COMMAND] - run command or shell in a chroot" +msgstr " [OPTION...] [COMMAND] - run command or shell in a chroot" + +#: dchroot/dchroot-options.cc:99 dchroot-dsa/dchroot-dsa-options.cc:102 +#, fuzzy +msgid "Only one command may be specified" +msgstr "Only one action may be specified" + +#: dchroot/dchroot-options.cc:104 schroot/schroot-options-base.cc:157 +msgid "--quiet and --verbose may not be used at the same time" +msgstr "--quiet and --verbose may not be used at the same time" + +#: dchroot/dchroot-options.cc:106 schroot/schroot-options-base.cc:159 +msgid "Using verbose output" +msgstr "Using verbose output" + +#: dchroot/dchroot-options.cc:112 schroot/schroot-options-base.cc:165 +msgid "--chroot and --all may not be used at the same time" +msgstr "--chroot and --all may not be used at the same time" + +#: dchroot/dchroot-options.cc:114 schroot/schroot-options-base.cc:167 +msgid "Using --chroots only" +msgstr "Using --chroots only" + +#: dchroot/dchroot-session-base.cc:76 +#, boost-format +msgid "(%1%->%2%): dchroot sessions do not support user switching" +msgstr "(%1%->%2%): dchroot sessions do not support user switching" + +#: dchroot/dchroot-session-base.cc:78 +msgid "dchroot session restriction" +msgstr "dchroot session restriction" + +#: dchroot/dchroot-session.cc:116 dchroot-dsa/dchroot-dsa-session.cc:132 +#, boost-format msgid "[%1% chroot] Running command: \"%2%\"" msgstr "[%1% chroot] Running command: “%2%”" -#: schroot/sbuild-auth.cc:52 +#: dchroot-dsa/dchroot-dsa-chroot-config.cc:110 +#, fuzzy, boost-format +msgid "%1% chroot (dchroot-dsa compatibility)" +msgstr "Running schroot in dchroot compatibility mode" + +#: dchroot-dsa/dchroot-dsa-options.cc:56 +msgid "Print paths to available chroots" +msgstr "Print paths to available chroots" + +#: dchroot-dsa/dchroot-dsa-options.cc:72 +#, fuzzy +msgid "[OPTION...] chroot [COMMAND] - run command or shell in a chroot" +msgstr " [OPTION...] chroot [COMMAND] - run command or shell in a chroot" + +#: dchroot-dsa/dchroot-dsa-session.cc:116 +#, boost-format +msgid "%1%: Command must have an absolute path" +msgstr "" + +#: sbuild/sbuild-auth.cc:53 msgid "Failed to get hostname" msgstr "Failed to get hostname" -#: schroot/sbuild-auth.cc:53 +#: sbuild/sbuild-auth.cc:54 msgid "User not found" msgstr "User not found" -#: schroot/sbuild-auth.cc:54 +#: sbuild/sbuild-auth.cc:55 msgid "Access not authorised" msgstr "Access not authorised" -#: schroot/sbuild-auth.cc:55 +#: sbuild/sbuild-auth.cc:56 msgid "Authentication failed" msgstr "Authentication failed" -#: schroot/sbuild-auth.cc:56 +#: sbuild/sbuild-auth.cc:57 msgid "PAM is already initialised" msgstr "PAM is already initialised" -#: schroot/sbuild-auth.cc:57 +#: sbuild/sbuild-auth.cc:58 msgid "PAM error" msgstr "PAM error" -#: schroot/sbuild-auth.cc:420 +#: sbuild/sbuild-auth.cc:421 msgid "Set RUSER" msgstr "Set RUSER" -#: schroot/sbuild-auth.cc:436 +#: sbuild/sbuild-auth.cc:437 msgid "Set RHOST" msgstr "Set RHOST" -#: schroot/sbuild-auth.cc:449 +#: sbuild/sbuild-auth.cc:450 msgid "Set TTY" msgstr "Set TTY" -#: schroot/sbuild-auth.cc:461 +#: sbuild/sbuild-auth.cc:462 msgid "Set USER" msgstr "Set USER" -#: schroot/sbuild-auth.cc:479 +#: sbuild/sbuild-auth.cc:480 +#, boost-format msgid "You do not have permission to access the %1% service." msgstr "You do not have permission to access the %1% service." -#: schroot/sbuild-auth.cc:482 +#: sbuild/sbuild-auth.cc:483 msgid "This failure will be reported." msgstr "This failure will be reported." -#: schroot/sbuild-auth-conv-tty.cc:47 +#: sbuild/sbuild-auth-conv-tty.cc:48 msgid "Timed out" msgstr "Timed out" -#: schroot/sbuild-auth-conv-tty.cc:48 +#: sbuild/sbuild-auth-conv-tty.cc:49 msgid "Time is running out..." msgstr "Time is running out..." -#: schroot/sbuild-auth-conv-tty.cc:49 +#: sbuild/sbuild-auth-conv-tty.cc:50 msgid "Failed to get terminal settings" msgstr "Failed to get terminal settings" -#: schroot/sbuild-auth-conv-tty.cc:50 +#: sbuild/sbuild-auth-conv-tty.cc:51 msgid "Unsupported conversation type" msgstr "Unsupported conversation type" -#: schroot/sbuild-chroot-block-device.cc:176 +#: sbuild/sbuild-chroot-block-device.cc:179 msgid "Device" msgstr "Device" -#: schroot/sbuild-chroot-block-device.cc:178 +#: sbuild/sbuild-chroot-block-device.cc:181 msgid "Mount Options" msgstr "Mount Options" -#: schroot/sbuild-chroot.cc:47 +#: sbuild/sbuild-chroot.cc:58 msgid "Unknown chroot type" msgstr "Unknown chroot type" -#: schroot/sbuild-chroot.cc:48 +#: sbuild/sbuild-chroot.cc:59 msgid "Chroot creation failed" msgstr "Chroot creation failed" -#: schroot/sbuild-chroot.cc:49 +#: sbuild/sbuild-chroot.cc:60 msgid "Device name not set" msgstr "Device name not set" -#: schroot/sbuild-chroot.cc:50 +#: sbuild/sbuild-chroot.cc:61 msgid "Failed to write session file" msgstr "Failed to write session file" -#: schroot/sbuild-chroot.cc:51 +#: sbuild/sbuild-chroot.cc:62 msgid "Failed to unlink session file" msgstr "Failed to unlink session file" -#: schroot/sbuild-chroot.cc:52 schroot/sbuild-chroot-config.cc:56 +#: sbuild/sbuild-chroot.cc:63 sbuild/sbuild-chroot-config.cc:58 msgid "Failed to stat file" msgstr "Failed to stat file" -#: schroot/sbuild-chroot.cc:53 schroot/sbuild-chroot-config.cc:58 +#: sbuild/sbuild-chroot.cc:64 sbuild/sbuild-chroot-config.cc:60 msgid "File is not owned by user root" msgstr "File is not owned by user root" -#: schroot/sbuild-chroot.cc:54 schroot/sbuild-chroot-config.cc:59 +#: sbuild/sbuild-chroot.cc:65 sbuild/sbuild-chroot-config.cc:61 msgid "File has write permissions for others" msgstr "File has write permissions for others" -#: schroot/sbuild-chroot.cc:55 schroot/sbuild-chroot-config.cc:60 +#: sbuild/sbuild-chroot.cc:66 sbuild/sbuild-chroot-config.cc:62 msgid "File is not a regular file" msgstr "File is not a regular file" -#: schroot/sbuild-chroot.cc:56 +#: sbuild/sbuild-chroot.cc:67 msgid "Failed to acquire file lock" msgstr "Failed to acquire file lock" -#: schroot/sbuild-chroot.cc:57 +#: sbuild/sbuild-chroot.cc:68 msgid "Failed to discard file lock" msgstr "Failed to discard file lock" -#: schroot/sbuild-chroot.cc:58 +#: sbuild/sbuild-chroot.cc:69 msgid "Failed to stat device" msgstr "Failed to stat device" -#: schroot/sbuild-chroot.cc:59 +#: sbuild/sbuild-chroot.cc:70 msgid "File is not a block device" msgstr "File is not a block device" -#: schroot/sbuild-chroot.cc:60 +#: sbuild/sbuild-chroot.cc:71 msgid "Failed to lock device" msgstr "Failed to lock device" -#: schroot/sbuild-chroot.cc:61 +#: sbuild/sbuild-chroot.cc:72 msgid "Failed to unlock device" msgstr "Failed to unlock device" -#: schroot/sbuild-chroot.cc:403 +#: sbuild/sbuild-chroot.cc:414 #, fuzzy msgid "--- Session ---\n" msgstr " ——— Session ———\n" -#: schroot/sbuild-chroot.cc:405 +#: sbuild/sbuild-chroot.cc:416 #, fuzzy msgid "--- Chroot ---\n" msgstr " ——— Chroot ———\n" -#: schroot/sbuild-chroot.cc:406 +#: sbuild/sbuild-chroot.cc:417 msgid "Name" msgstr "Name" -#: schroot/sbuild-chroot.cc:407 +#: sbuild/sbuild-chroot.cc:418 msgid "Description" msgstr "Description" -#: schroot/sbuild-chroot.cc:408 +#: sbuild/sbuild-chroot.cc:419 msgid "Type" msgstr "Type" -#: schroot/sbuild-chroot.cc:409 +#: sbuild/sbuild-chroot.cc:420 msgid "Priority" msgstr "Priority" -#: schroot/sbuild-chroot.cc:410 +#: sbuild/sbuild-chroot.cc:421 msgid "Users" msgstr "Users" -#: schroot/sbuild-chroot.cc:411 +#: sbuild/sbuild-chroot.cc:422 msgid "Groups" msgstr "Groups" -#: schroot/sbuild-chroot.cc:412 +#: sbuild/sbuild-chroot.cc:423 msgid "Root Users" msgstr "Root Users" -#: schroot/sbuild-chroot.cc:413 +#: sbuild/sbuild-chroot.cc:424 msgid "Root Groups" msgstr "Root Groups" -#: schroot/sbuild-chroot.cc:414 +#: sbuild/sbuild-chroot.cc:425 msgid "Aliases" msgstr "Aliases" -#: schroot/sbuild-chroot.cc:415 +#: sbuild/sbuild-chroot.cc:426 msgid "Run Setup Scripts" msgstr "Run Setup Scripts" -#: schroot/sbuild-chroot.cc:416 +#: sbuild/sbuild-chroot.cc:427 msgid "Run Execution Scripts" msgstr "Run Execution Scripts" -#: schroot/sbuild-chroot.cc:418 +#: sbuild/sbuild-chroot.cc:429 msgid "Session Managed" msgstr "Session Managed" -#: schroot/sbuild-chroot.cc:423 +#: sbuild/sbuild-chroot.cc:434 msgid "Command Prefix" msgstr "Command Prefix" -#: schroot/sbuild-chroot.cc:425 +#: sbuild/sbuild-chroot.cc:436 msgid "Personality" msgstr "Personality" -#: schroot/sbuild-chroot.cc:429 +#: sbuild/sbuild-chroot.cc:440 msgid "Location" msgstr "Location" -#: schroot/sbuild-chroot.cc:432 +#: sbuild/sbuild-chroot.cc:443 msgid "Mount Location" msgstr "Mount Location" -#: schroot/sbuild-chroot.cc:435 +#: sbuild/sbuild-chroot.cc:446 msgid "Path" msgstr "Path" -#: schroot/sbuild-chroot.cc:438 +#: sbuild/sbuild-chroot.cc:449 msgid "Mount Device" msgstr "Mount Device" -#: schroot/sbuild-chroot.cc:597 +#: sbuild/sbuild-chroot.cc:608 +#, boost-format msgid "%1% chroot: personality \"%2%\" is unknown.\n" msgstr "%1% chroot: personality “%2%” is unknown.\n" -#: schroot/sbuild-chroot.cc:600 +#: sbuild/sbuild-chroot.cc:611 +#, boost-format msgid "Valid personalities: %1%\n" msgstr "Valid personalities: %1%\n" -#: schroot/sbuild-chroot-config.cc:55 +#: sbuild/sbuild-chroot-config.cc:57 msgid "Failed to open directory" msgstr "Failed to open directory" -#: schroot/sbuild-chroot-config.cc:57 +#: sbuild/sbuild-chroot-config.cc:59 msgid "Failed to open file" msgstr "Failed to open file" -#: schroot/sbuild-chroot-config.cc:180 -#, fuzzy +#: sbuild/sbuild-chroot-config.cc:182 +#, fuzzy, boost-format msgid "%1% chroot: Alias '%2%' already associated with '%3%' chroot" msgstr "%1% chroot: alias ‘%2%’ already associated with ‘%3%’ chroot" -#: schroot/sbuild-chroot-config.cc:188 -#, fuzzy +#: sbuild/sbuild-chroot-config.cc:190 +#, fuzzy, boost-format msgid "%1% chroot: Alias '%2%' already associated with another chroot" msgstr "%1% chroot: alias ‘%2%’ already associated with another chroot" -#: schroot/sbuild-chroot-config.cc:198 -#, fuzzy +#: sbuild/sbuild-chroot-config.cc:200 +#, fuzzy, boost-format msgid "%1% chroot: A chroot or alias already exists by this name" msgstr "%1% chroot: a chroot or alias already exists by this name" -#: schroot/sbuild-chroot-config.cc:201 -#, fuzzy +#: sbuild/sbuild-chroot-config.cc:203 +#, fuzzy, boost-format msgid "%1% chroot: Duplicate names are not allowed" msgstr "%1% chroot: duplicate names are not allowed" -#: schroot/sbuild-chroot-config.cc:280 +#: sbuild/sbuild-chroot-config.cc:282 msgid "Available chroots: " msgstr "Available chroots: " -#: schroot/sbuild-chroot-config.cc:325 schroot/sbuild-chroot-config.cc:344 -#: schroot/sbuild-chroot-config.cc:367 +#: sbuild/sbuild-chroot-config.cc:327 sbuild/sbuild-chroot-config.cc:346 +#: sbuild/sbuild-chroot-config.cc:369 schroot/schroot-main.cc:138 +#, boost-format msgid "%1%: No such chroot" msgstr "%1%: No such chroot" -#: schroot/sbuild-chroot-file.cc:143 +#: sbuild/sbuild-chroot-file.cc:146 msgid "File" msgstr "File" -#: schroot/sbuild-chroot-file.cc:144 +#: sbuild/sbuild-chroot-file.cc:147 msgid "File Repack" msgstr "File Repack" -#: schroot/sbuild-chroot-lvm-snapshot.cc:201 +#: sbuild/sbuild-chroot-lvm-snapshot.cc:203 msgid "LVM Snapshot Device" msgstr "LVM Snapshot Device" -#: schroot/sbuild-chroot-lvm-snapshot.cc:204 +#: sbuild/sbuild-chroot-lvm-snapshot.cc:206 msgid "LVM Snapshot Options" msgstr "LVM Snapshot Options" -#: schroot/sbuild-chroot-source.cc:45 +#: sbuild/sbuild-chroot-source.cc:47 #, fuzzy msgid "(source chroot)" msgstr " (source chroot)" -#: schroot/sbuild-chroot-source.cc:115 +#: sbuild/sbuild-chroot-source.cc:117 msgid "Source Users" msgstr "Source Users" -#: schroot/sbuild-chroot-source.cc:116 +#: sbuild/sbuild-chroot-source.cc:118 msgid "Source Groups" msgstr "Source Groups" -#: schroot/sbuild-chroot-source.cc:117 +#: sbuild/sbuild-chroot-source.cc:119 msgid "Source Root Users" msgstr "Source Root Users" -#: schroot/sbuild-chroot-source.cc:118 +#: sbuild/sbuild-chroot-source.cc:120 msgid "Source Root Groups" msgstr "Source Root Groups" -#: schroot/sbuild-format-detail.cc:34 +#: sbuild/sbuild-format-detail.cc:34 msgid "true" msgstr "true" -#: schroot/sbuild-format-detail.cc:36 +#: sbuild/sbuild-format-detail.cc:36 msgid "false" msgstr "false" -#: schroot/sbuild-keyfile.cc:363 +#: sbuild/sbuild-keyfile.cc:363 +#, boost-format msgid "%1% chroot: A deprecated parameter \"%2%\" has been specified." msgstr "%1% chroot: A deprecated parameter “%2%” has been specified." -#: schroot/sbuild-keyfile.cc:367 +#: sbuild/sbuild-keyfile.cc:367 msgid "This option will be removed in the future." msgstr "This option will be removed in the future." -#: schroot/sbuild-keyfile.cc:371 +#: sbuild/sbuild-keyfile.cc:371 +#, boost-format msgid "%1% chroot: An obsolete parameter \"%2%\" has been specified." msgstr "%1% chroot: An obsolete parameter “%2%” has been specified." -#: schroot/sbuild-keyfile.cc:375 +#: sbuild/sbuild-keyfile.cc:375 msgid "This option has been removed, and no longer has any effect." msgstr "This option has been removed, and no longer has any effect." -#: schroot/sbuild-lock.cc:48 +#: sbuild/sbuild-lock.cc:49 msgid "Failed to set timeout handler" msgstr "Failed to set timeout handler" -#: schroot/sbuild-lock.cc:49 +#: sbuild/sbuild-lock.cc:50 msgid "Failed to set timeout" msgstr "Failed to set timeout" -#: schroot/sbuild-lock.cc:50 +#: sbuild/sbuild-lock.cc:51 msgid "Failed to cancel timeout" msgstr "Failed to cancel timeout" -#: schroot/sbuild-lock.cc:51 +#: sbuild/sbuild-lock.cc:52 msgid "Failed to acquire lock (timed out)" msgstr "Failed to acquire lock (timed out)" -#: schroot/sbuild-lock.cc:52 +#: sbuild/sbuild-lock.cc:53 msgid "Failed to acquire lock" msgstr "Failed to acquire lock" -#: schroot/sbuild-lock.cc:53 +#: sbuild/sbuild-lock.cc:54 msgid "Failed to acquire device lock" msgstr "Failed to acquire device lock" -#: schroot/sbuild-lock.cc:54 +#: sbuild/sbuild-lock.cc:55 msgid "Failed to acquire device lock (timed out)" msgstr "Failed to acquire device lock (timed out)" -#: schroot/sbuild-lock.cc:55 +#: sbuild/sbuild-lock.cc:56 msgid "Failed to test device lock" msgstr "Failed to test device lock" -#: schroot/sbuild-lock.cc:56 +#: sbuild/sbuild-lock.cc:57 msgid "Failed to release device lock" msgstr "Failed to release device lock" -#: schroot/sbuild-lock.cc:57 +#: sbuild/sbuild-lock.cc:58 msgid "Failed to release device lock (timed out)" msgstr "Failed to release device lock (timed out)" -#: schroot/sbuild-lock.cc:274 +#: sbuild/sbuild-lock.cc:275 +#, boost-format msgid "lock held by pid %1%" msgstr "lock held by pid %1%" -#: schroot/sbuild-parse-error.cc:41 +#: sbuild/sbuild-parse-error.cc:41 #, fuzzy msgid "No error" msgstr "no error" -#: schroot/sbuild-parse-error.cc:42 +#: sbuild/sbuild-parse-error.cc:42 #, fuzzy msgid "Can't open file" msgstr "can't open file" -#: schroot/sbuild-parse-error.cc:43 +#: sbuild/sbuild-parse-error.cc:43 #, fuzzy msgid "Could not parse value" msgstr "could not parse value" -#: schroot/sbuild-parse-error.cc:44 +#: sbuild/sbuild-parse-error.cc:44 #, fuzzy msgid "Invalid line" msgstr "invalid line" -#: schroot/sbuild-parse-error.cc:45 +#: sbuild/sbuild-parse-error.cc:45 #, fuzzy msgid "No group specified" msgstr "no group specified" -#: schroot/sbuild-parse-error.cc:46 +#: sbuild/sbuild-parse-error.cc:46 #, fuzzy msgid "Invalid group" msgstr "invalid group" -#: schroot/sbuild-parse-error.cc:47 +#: sbuild/sbuild-parse-error.cc:47 #, fuzzy msgid "Duplicate group" msgstr "duplicate group" -#: schroot/sbuild-parse-error.cc:48 +#: sbuild/sbuild-parse-error.cc:48 #, fuzzy msgid "No key specified" msgstr "no key specified" -#: schroot/sbuild-parse-error.cc:49 +#: sbuild/sbuild-parse-error.cc:49 #, fuzzy msgid "Duplicate key" msgstr "duplicate key" -#: schroot/sbuild-parse-error.cc:50 +#: sbuild/sbuild-parse-error.cc:50 #, fuzzy msgid "Required key is missing" msgstr "required key is missing" -#: schroot/sbuild-parse-error.cc:51 +#: sbuild/sbuild-parse-error.cc:51 #, fuzzy msgid "Disallowed key used" msgstr "disallowed key used" -#: schroot/sbuild-parse-error.cc:116 +#: sbuild/sbuild-parse-error.cc:116 #, fuzzy msgid "Unknown error" msgstr "unknown error" -#: schroot/sbuild-parse-error.cc:127 +#: sbuild/sbuild-parse-error.cc:127 +#, boost-format msgid "%1% \"%2%\"" msgstr "%1% “%2%”\"" -#: schroot/sbuild-parse-error.cc:143 +#: sbuild/sbuild-parse-error.cc:143 +#, boost-format msgid "line %1%: %3%" msgstr "line %1%: %3%" -#: schroot/sbuild-parse-error.cc:144 +#: sbuild/sbuild-parse-error.cc:144 +#, boost-format msgid "line %1%: %2% \"%3%\"" msgstr "line %1%: %2% “%3%”" -#: schroot/sbuild-parse-error.cc:150 +#: sbuild/sbuild-parse-error.cc:150 +#, boost-format msgid "line %1%: %2%" msgstr "line %1%: %2%" -#: schroot/sbuild-parse-error.cc:165 +#: sbuild/sbuild-parse-error.cc:165 +#, boost-format msgid "line %1% [%2%]: %4%" msgstr "line %1% [%2%]: %4%" -#: schroot/sbuild-parse-error.cc:166 +#: sbuild/sbuild-parse-error.cc:166 +#, boost-format msgid "line %1% [%2%]: %3% \"%4%\"" msgstr "line %1% [%2%]: %3% “%4%”" -#: schroot/sbuild-parse-error.cc:172 +#: sbuild/sbuild-parse-error.cc:172 +#, boost-format msgid "line %1% [%2%]: %3%" msgstr "line %1% [%2%]: %3%" -#: schroot/sbuild-parse-error.cc:188 +#: sbuild/sbuild-parse-error.cc:188 +#, boost-format msgid "line %1% [%2%] %3%: %5%" msgstr "line %1% [%2%] %3%: %5%" -#: schroot/sbuild-parse-error.cc:189 +#: sbuild/sbuild-parse-error.cc:189 +#, boost-format msgid "line %1% [%2%] %3%: %4% \"%5%\"" msgstr "line %1% [%2%] %3%: %4% “%5%”" -#: schroot/sbuild-parse-error.cc:195 +#: sbuild/sbuild-parse-error.cc:195 +#, boost-format msgid "line %1% [%2%] %3%: %4%" msgstr "line %1% [%2%] %3%: %4%" -#: schroot/sbuild-parse-error.cc:209 +#: sbuild/sbuild-parse-error.cc:209 +#, boost-format msgid "[%1%]: %3%" msgstr "[%1%]: %3%" -#: schroot/sbuild-parse-error.cc:210 +#: sbuild/sbuild-parse-error.cc:210 +#, boost-format msgid "[%1%]: %2% \"%3%\"" msgstr "[%1%]: %2% “%3%”" -#: schroot/sbuild-parse-error.cc:216 +#: sbuild/sbuild-parse-error.cc:216 +#, boost-format msgid "[%1%]: %2%" msgstr "[%1%]: %2%" -#: schroot/sbuild-parse-error.cc:231 +#: sbuild/sbuild-parse-error.cc:231 +#, boost-format msgid "[%1%] %2%: %4%" msgstr "[%1%] %2%: %4%" -#: schroot/sbuild-parse-error.cc:232 +#: sbuild/sbuild-parse-error.cc:232 +#, boost-format msgid "[%1%] %2%: %3% \"%4%\"" msgstr "[%1%] %2%: %3% “%4%”" -#: schroot/sbuild-parse-error.cc:238 +#: sbuild/sbuild-parse-error.cc:238 +#, boost-format msgid "[%1%] %2%: %3%" msgstr "[%1%] %2%: %3%" -#: schroot/sbuild-personality.cc:48 +#: sbuild/sbuild-personality.cc:48 msgid "Failed to set personality" msgstr "Failed to set personality" -#: schroot/sbuild-session.cc:57 +#: sbuild/sbuild-session.cc:59 msgid "Failed to find chroot" msgstr "Failed to find chroot" -#: schroot/sbuild-session.cc:58 +#: sbuild/sbuild-session.cc:60 msgid "Failed to lock chroot" msgstr "Failed to lock chroot" -#: schroot/sbuild-session.cc:59 +#: sbuild/sbuild-session.cc:61 msgid "Failed to unlock chroot" msgstr "Failed to unlock chroot" -#: schroot/sbuild-session.cc:60 +#: sbuild/sbuild-session.cc:62 msgid "Chroot setup failed" msgstr "Chroot setup failed" -#: schroot/sbuild-session.cc:61 +#: sbuild/sbuild-session.cc:63 msgid "Failed to set hangup signal handler" msgstr "Failed to set hangup signal handler" -#: schroot/sbuild-session.cc:62 +#: sbuild/sbuild-session.cc:64 msgid "Caught hangup signal" msgstr "Caught hangup signal" -#: schroot/sbuild-session.cc:63 +#: sbuild/sbuild-session.cc:65 msgid "Failed to fork child" msgstr "Failed to fork child" -#: schroot/sbuild-session.cc:64 +#: sbuild/sbuild-session.cc:66 msgid "Wait for child failed" msgstr "Wait for child failed" -#: schroot/sbuild-session.cc:65 +#: sbuild/sbuild-session.cc:67 msgid "Child terminated by signal" msgstr "Child terminated by signal" -#: schroot/sbuild-session.cc:66 +#: sbuild/sbuild-session.cc:68 msgid "Child dumped core" msgstr "Child dumped core" -#: schroot/sbuild-session.cc:67 +#: sbuild/sbuild-session.cc:69 msgid "Child exited abnormally (reason unknown; not a signal or core dump)" msgstr "Child exited abnormally (reason unknown; not a signal or core dump)" -#: schroot/sbuild-session.cc:68 +#: sbuild/sbuild-session.cc:70 msgid "User switching is not permitted" msgstr "User switching is not permitted" -#: schroot/sbuild-session.cc:106 +#: sbuild/sbuild-session.cc:108 +#, boost-format msgid "%1%: Group not found" msgstr "%1%: Group not found" -#: schroot/sbuild-session.cc:108 +#: sbuild/sbuild-session.cc:110 +#, boost-format msgid "%1%: Group not found: %2%" msgstr "%1%: Group not found: %2%" -#: schroot/sbuild-session.cc:124 +#: sbuild/sbuild-session.cc:126 +#, boost-format msgid "Can't get supplementary group count: %1%" msgstr "Can't get supplementary group count: %1%" -#: schroot/sbuild-session.cc:134 +#: sbuild/sbuild-session.cc:136 +#, boost-format msgid "Can't get supplementary groups: %1%" msgstr "Can't get supplementary groups: %1%" -#: schroot/sbuild-session.cc:364 +#: sbuild/sbuild-session.cc:366 +#, boost-format msgid "No chroot found matching alias '%1%'" msgstr "No chroot found matching alias ‘%1%’" -#: schroot/sbuild-session.cc:571 +#: sbuild/sbuild-session.cc:573 +#, boost-format msgid "%1%: Shell not available: %2%" msgstr "%1%: Shell not available: %2%" -#: schroot/sbuild-session.cc:574 -#, fuzzy +#: sbuild/sbuild-session.cc:576 +#, fuzzy, boost-format msgid "Falling back to %1%" msgstr "Falling back to ‘%1%’" -#: schroot/sbuild-session.cc:640 -#, fuzzy +#: sbuild/sbuild-session.cc:642 +#, fuzzy, boost-format msgid "[%1% chroot] Running login shell: \"%4%\"" msgstr "[%1% chroot] Running login shell: “%2%”" -#: schroot/sbuild-session.cc:642 -#, fuzzy +#: sbuild/sbuild-session.cc:644 +#, fuzzy, boost-format msgid "[%1% chroot] Running shell: \"%4%\"" msgstr "[%1% chroot] Running shell: “%2%”" -#: schroot/sbuild-session.cc:648 +#: sbuild/sbuild-session.cc:650 +#, boost-format msgid "[%1% chroot] (%2%->%3%) Running login shell: \"%4%\"" msgstr "[%1% chroot] (%2%→%3%) Running login shell: “%4%”" -#: schroot/sbuild-session.cc:650 +#: sbuild/sbuild-session.cc:652 +#, boost-format msgid "[%1% chroot] (%2%->%3%) Running shell: \"%4%\"" msgstr "[%1% chroot] (%2%→%3%) Running shell: “%4%”" -#: schroot/sbuild-session.cc:685 -#, fuzzy +#: sbuild/sbuild-session.cc:687 +#, fuzzy, boost-format msgid "[%1% chroot] Running command: \"%4%\"" msgstr "[%1% chroot] Running command: “%2%”" -#: schroot/sbuild-session.cc:687 +#: sbuild/sbuild-session.cc:689 +#, boost-format msgid "[%1% chroot] (%2%->%3%) Running command: \"%4%\"" msgstr "[%1% chroot] (%2%→%3%) Running command: “%4%”" -#: schroot/sbuild-session.cc:809 +#: sbuild/sbuild-session.cc:811 +#, boost-format msgid "Invalid verbosity level: %1%, falling back to \"normal\"" msgstr "Invalid verbosity level: %1%, falling back to “normal”" -#: schroot/sbuild-session.cc:845 schroot/sbuild-session.cc:1020 +#: sbuild/sbuild-session.cc:847 sbuild/sbuild-session.cc:1022 +#, boost-format msgid "Could not exec \"%1%\": %2%" msgstr "Could not exec “%1%”: %2%" -#: schroot/sbuild-session.cc:871 +#: sbuild/sbuild-session.cc:873 +#, boost-format msgid "stage=%1%" msgstr "stage=%1%" -#: schroot/sbuild-session.cc:900 +#: sbuild/sbuild-session.cc:902 +#, boost-format msgid "PAM error: %1%" msgstr "PAM error: %1%" -#: schroot/sbuild-session.cc:908 +#: sbuild/sbuild-session.cc:910 +#, boost-format msgid "Could not set gid to '%1%'" msgstr "Could not set gid to ‘%1%’" -#: schroot/sbuild-session.cc:914 +#: sbuild/sbuild-session.cc:916 msgid "Could not set supplementary group IDs" msgstr "Could not set supplementary group IDs" -#: schroot/sbuild-session.cc:932 schroot/sbuild-session.cc:980 +#: sbuild/sbuild-session.cc:934 sbuild/sbuild-session.cc:982 +#, boost-format msgid "Could not chdir to '%1%': %2%" msgstr "Could not chdir to ‘%1%’: %2%" -#: schroot/sbuild-session.cc:939 +#: sbuild/sbuild-session.cc:941 +#, boost-format msgid "Could not chroot to '%1%': %2%" msgstr "Could not chroot to ‘%1%’: %2%" -#: schroot/sbuild-session.cc:948 +#: sbuild/sbuild-session.cc:950 +#, boost-format msgid "Could not set uid to '%1%'" msgstr "Could not set uid to ‘%1%’" -#: schroot/sbuild-session.cc:954 +#: sbuild/sbuild-session.cc:956 msgid "Failed to drop root permissions." msgstr "Failed to drop root permissions." -#: schroot/sbuild-session.cc:987 +#: sbuild/sbuild-session.cc:989 +#, boost-format msgid "Falling back to '%1%'" msgstr "Falling back to ‘%1%’" -#: schroot/sbuild-session.cc:1042 +#: sbuild/sbuild-session.cc:1044 msgid "Caught hangup signal, terminating..." msgstr "Caught hangup signal, terminating..." -#: schroot/schroot.cc:68 -#, fuzzy -msgid "An unknown exception occured" -msgstr "Unknown action specified" +#: schroot/schroot-listmounts.cc:61 schroot/schroot-main.cc:58 +#: schroot/schroot-releaselock.cc:56 +#, fuzzy, boost-format +msgid "%1% (Debian sbuild) %2% (%3%)\n" +msgstr "%1% (Debian sbuild) %2%\n" -#: schroot/schroot-listmounts.cc:57 -msgid "schroot-listmounts (Debian sbuild) %1%\n" -msgstr "schroot-listmounts (Debian sbuild) %1%\n" - -#: schroot/schroot-listmounts.cc:58 schroot/schroot-releaselock.cc:55 +#: schroot/schroot-listmounts.cc:65 schroot/schroot-main.cc:62 +#: schroot/schroot-releaselock.cc:60 msgid "" "Written by Roger Leigh\n" "\n" @@ -684,11 +852,13 @@ msgstr "" "Written by Roger Leigh\n" "\n" -#: schroot/schroot-listmounts.cc:59 schroot/schroot-releaselock.cc:56 +#: schroot/schroot-listmounts.cc:66 schroot/schroot-main.cc:63 +#: schroot/schroot-releaselock.cc:61 msgid "Copyright (C) 2004-2006 Roger Leigh\n" msgstr "Copyright © 2004-2006 Roger Leigh\n" -#: schroot/schroot-listmounts.cc:60 schroot/schroot-releaselock.cc:57 +#: schroot/schroot-listmounts.cc:67 schroot/schroot-main.cc:64 +#: schroot/schroot-releaselock.cc:62 msgid "" "This is free software; see the source for copying conditions. There is NO\n" "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" @@ -696,147 +866,225 @@ msgstr "" "This is free software; see the source for copying conditions. There is NO\n" "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" -#: schroot/schroot-listmounts.cc:82 +#: schroot/schroot-listmounts.cc:89 +#, boost-format msgid "%1%: Failed to open: %2%" msgstr "%1%: failed to open directory: %2%" -#: schroot/schroot-listmounts.cc:105 +#: schroot/schroot-listmounts.cc:112 +#, boost-format msgid "%1%: Failed to close: %2%" msgstr "%1%: Failed to close: %2%" -#: schroot/schroot-listmounts.cc:151 +#: schroot/schroot-listmounts.cc:158 msgid "No mountpoint specified" msgstr "No mountpoint specified" -#: schroot/schroot-listmounts-options.cc:43 -#: schroot/schroot-releaselock-options.cc:44 +#: schroot/schroot-listmounts-options.cc:42 schroot/schroot-options-base.cc:48 +#: schroot/schroot-releaselock-options.cc:43 msgid "General options" msgstr "General options" -#: schroot/schroot-listmounts-options.cc:45 -#: schroot/schroot-releaselock-options.cc:46 +#: schroot/schroot-listmounts-options.cc:44 schroot/schroot-options-base.cc:69 +#: schroot/schroot-releaselock-options.cc:45 msgid "Show help options" msgstr "Show help options" -#: schroot/schroot-listmounts-options.cc:47 -#: schroot/schroot-releaselock-options.cc:48 +#: schroot/schroot-listmounts-options.cc:46 schroot/schroot-options-base.cc:71 +#: schroot/schroot-releaselock-options.cc:47 msgid "Print version information" msgstr "Print version information" -#: schroot/schroot-listmounts-options.cc:49 -#: schroot/schroot-releaselock-options.cc:50 +#: schroot/schroot-listmounts-options.cc:48 +#: schroot/schroot-releaselock-options.cc:49 msgid "Lock options" msgstr "Lock options" -#: schroot/schroot-listmounts-options.cc:52 +#: schroot/schroot-listmounts-options.cc:51 msgid "Mountpoint to check (full path)" msgstr "Mountpoint to check (full path)" -#: schroot/schroot-listmounts-options.cc:65 schroot/schroot-options.cc:95 -#: schroot/schroot-releaselock-options.cc:68 -msgid "Usage:" -msgstr "Usage:" - -#: schroot/schroot-listmounts-options.cc:66 +#: schroot/schroot-listmounts-options.cc:65 #, fuzzy msgid "schroot-listmounts [OPTION...] - list mounts" msgstr " schroot-listmounts [OPTION...] - list mounts" -#: schroot/schroot-options.cc:59 +#: schroot/schroot-main.cc:194 +msgid "Error saving terminal settings" +msgstr "Error saving terminal settings" + +#: schroot/schroot-main.cc:226 +#, boost-format +msgid "No chroots are defined in %1% or %2%" +msgstr "No chroots are defined in %1% or %2%" + +#: schroot/schroot-main.cc:234 +#, boost-format +msgid "No chroots are defined in %1%" +msgstr "No chroots are defined in %1%" + +#: schroot/schroot-main.cc:251 +#, boost-format +msgid "The specified chroots are not defined in %1%" +msgstr "The specified chroots are not defined in %1%" + +#: schroot/schroot-main.cc:278 +msgid "Only one chroot may be specified when beginning a session" +msgstr "Only one chroot may be specified when beginning a session" + +#: schroot/schroot-main.cc:335 schroot/schroot-main.cc:351 +msgid "Error restoring terminal settings" +msgstr "Error restoring terminal settings" + +#: schroot/schroot-options-base.cc:49 +msgid "Chroot selection" +msgstr "Chroot selection" + +#: schroot/schroot-options-base.cc:50 +msgid "Chroot environment" +msgstr "Chroot environment" + +#: schroot/schroot-options-base.cc:51 +msgid "Session management" +msgstr "Session management" + +#: schroot/schroot-options-base.cc:52 +msgid "Hidden options" +msgstr "Hidden options" + +#: schroot/schroot-options-base.cc:73 +msgid "Show less output" +msgstr "Show less output" + +#: schroot/schroot-options-base.cc:75 +msgid "Show more output" +msgstr "Show more output" + +#: schroot/schroot-options-base.cc:77 +msgid "List available chroots" +msgstr "List available chroots" + +#: schroot/schroot-options-base.cc:79 +msgid "Show information about selected chroots" +msgstr "Show information about selected chroots" + +#: schroot/schroot-options-base.cc:81 +msgid "Dump configuration of selected chroots" +msgstr "Dump configuration of selected chroots" + +#: schroot/schroot-options-base.cc:85 +msgid "Use specified chroot" +msgstr "Use specified chroot" + +#: schroot/schroot-options-base.cc:89 +msgid "Command to run" +msgstr "Command to run" + +#: schroot/schroot-options-base.cc:91 +msgid "Enable debugging messages" +msgstr "" + +#: schroot/schroot-options-base.cc:190 +msgid "" +"Only one chroot may be specified when recovering, running or ending a session" +msgstr "" +"Only one chroot may be specified when recovering, running or ending a session" + +#: schroot/schroot-options-base.cc:215 +msgid "--chroot may not be used with --list" +msgstr "--chroot may not be used with --list" + +#: schroot/schroot-options-base.cc:237 +#, fuzzy +msgid "Unknown action specified" +msgstr "Only one action may be specified" + +#: schroot/schroot-options-base.cc:245 +msgid "Only one action may be specified" +msgstr "Only one action may be specified" + +#: schroot/schroot-options.cc:56 msgid "Print location of selected chroots" msgstr "Print location of selected chroots" -#: schroot/schroot-options.cc:63 +#: schroot/schroot-options.cc:60 msgid "Select all chroots and active sessions" msgstr "Select all chroots and active sessions" -#: schroot/schroot-options.cc:65 -msgid "Select all chroots" -msgstr "Select all chroots" - -#: schroot/schroot-options.cc:67 +#: schroot/schroot-options.cc:64 msgid "Select all active sessions" msgstr "Select all active sessions" -#: schroot/schroot-options.cc:71 +#: schroot/schroot-options.cc:68 msgid "Username (default current user)" msgstr "Username (default current user)" -#: schroot/schroot-options.cc:73 -msgid "Preserve user environment" -msgstr "Preserve user environment" - -#: schroot/schroot-options.cc:77 +#: schroot/schroot-options.cc:74 msgid "Begin a session; returns a session ID" msgstr "Begin a session; returns a session ID" -#: schroot/schroot-options.cc:79 +#: schroot/schroot-options.cc:76 msgid "Recover an existing session" msgstr "Recover an existing session" -#: schroot/schroot-options.cc:81 +#: schroot/schroot-options.cc:78 msgid "Run an existing session" msgstr "Run an existing session" -#: schroot/schroot-options.cc:83 +#: schroot/schroot-options.cc:80 msgid "End an existing session" msgstr "End an existing session" -#: schroot/schroot-options.cc:85 +#: schroot/schroot-options.cc:82 msgid "Force operation, even if it fails" msgstr "Force operation, even if it fails" -#: schroot/schroot-options.cc:98 -#, fuzzy -msgid "[OPTION...] [COMMAND] - run command or shell in a chroot" -msgstr " [OPTION...] [COMMAND] - run command or shell in a chroot" - -#: schroot/schroot-releaselock.cc:54 -msgid "schroot-releaselock (Debian sbuild) %1%\n" -msgstr "schroot-releaselock (Debian sbuild) %1%\n" - -#: schroot/schroot-releaselock.cc:100 +#: schroot/schroot-releaselock.cc:105 msgid "No device specified" msgstr "No device specified" -#: schroot/schroot-releaselock.cc:106 +#: schroot/schroot-releaselock.cc:111 msgid "No pid specified; forcing release of lock" msgstr "No pid specified; forcing release of lock" -#: schroot/schroot-releaselock.cc:115 +#: schroot/schroot-releaselock.cc:120 +#, boost-format msgid "Failed to stat device %1%: %2%" msgstr "Failed to stat device %1%: %2%" -#: schroot/schroot-releaselock.cc:123 +#: schroot/schroot-releaselock.cc:128 +#, boost-format msgid "%1% is not a block device" msgstr "%1% is not a block device" -#: schroot/schroot-releaselock.cc:131 +#: schroot/schroot-releaselock.cc:136 +#, boost-format msgid "%1%: failed to release device lock" msgstr "%1%: failed to release device lock" -#: schroot/schroot-releaselock.cc:138 +#: schroot/schroot-releaselock.cc:143 +#, boost-format msgid "%1%: failed to release device lock owned by pid %2%" msgstr "%1%: failed to release device lock owned by pid %2%" -#: schroot/schroot-releaselock-options.cc:53 +#: schroot/schroot-releaselock-options.cc:52 msgid "Device to unlock (full path)" msgstr "Device to unlock (full path)" -#: schroot/schroot-releaselock-options.cc:55 +#: schroot/schroot-releaselock-options.cc:54 msgid "Process ID owning the lock" msgstr "Process ID owning the lock" -#: schroot/schroot-releaselock-options.cc:69 +#: schroot/schroot-releaselock-options.cc:68 #, fuzzy msgid "schroot-releaselock [OPTION...] - release a device lock" msgstr " schroot-releaselock [OPTION...] - release a device lock" -#~ msgid "(%1%->%2%): dchroot sessions do not support user switching" -#~ msgstr "(%1%->%2%): dchroot sessions do not support user switching" +#~ msgid "schroot-listmounts (Debian sbuild) %1%\n" +#~ msgstr "schroot-listmounts (Debian sbuild) %1%\n" -#~ msgid "dchroot session restriction" -#~ msgstr "dchroot session restriction" +#~ msgid "schroot-releaselock (Debian sbuild) %1%\n" +#~ msgstr "schroot-releaselock (Debian sbuild) %1%\n" #~ msgid "%1%: not a regular file" #~ msgstr "%1%: not a regular file" @@ -844,122 +1092,5 @@ msgstr " schroot-releaselock [OPTION...] - release a device lock" #~ msgid "Falling back to home directory '%1%'" #~ msgstr "Falling back to home directory ‘%1%’" -#~ msgid "%1% (Debian sbuild) %2%\n" -#~ msgstr "%1% (Debian sbuild) %2%\n" - -#~ msgid "Error saving terminal settings" -#~ msgstr "Error saving terminal settings" - -#~ msgid "Run 'schroot' for full capabilities" -#~ msgstr "Run ‘schroot’ for full capabilities" - -#~ msgid "Using dchroot configuration file: " -#~ msgstr "Using dchroot configuration file: " - -#~ msgid "Run '%1%'" -#~ msgstr "Run ‘%1%’" - -#~ msgid "to migrate to a schroot configuration." -#~ msgstr "to migrate to a schroot configuration." - -#~ msgid "Edit '%1%' to add appropriate group access." -#~ msgstr "Edit ‘%1%’ to add appropriate group access." - -#~ msgid "Remove '%1%' to use the new configuration." -#~ msgstr "Remove ‘%1%’ to use the new configuration." - -#~ msgid "No chroots are defined in %1% or %2%" -#~ msgstr "No chroots are defined in %1% or %2%" - -#~ msgid "No chroots are defined in %1%" -#~ msgstr "No chroots are defined in %1%" - -#~ msgid "The specified chroots are not defined in %1%" -#~ msgstr "The specified chroots are not defined in %1%" - -#~ msgid "schroot configuration generated by %1% %2%" -#~ msgstr "schroot configuration generated by %1% %2%" - -#~ msgid "To allow users access to the chroots, use the users or groups keys." -#~ msgstr "To allow users access to the chroots, use the users or groups keys." - -#~ msgid "" -#~ "To allow passwordless root access, use the root-users or root-groups keys." -#~ msgstr "" -#~ "To allow passwordless root access, use the root-users or root-groups keys." - -#~ msgid "Only one chroot may be specified when beginning a session" -#~ msgstr "Only one chroot may be specified when beginning a session" - #~ msgid "Session failure: %1%" #~ msgstr "Session failure: %1%" - -#~ msgid "Error restoring terminal settings" -#~ msgstr "Error restoring terminal settings" - -#~ msgid "Show less output" -#~ msgstr "Show less output" - -#~ msgid "Show more output" -#~ msgstr "Show more output" - -#~ msgid "List available chroots" -#~ msgstr "List available chroots" - -#~ msgid "Show information about selected chroots" -#~ msgstr "Show information about selected chroots" - -#~ msgid "Print path to selected chroot" -#~ msgstr "Print path to selected chroot" - -#~ msgid "Print paths to available chroots" -#~ msgstr "Print paths to available chroots" - -#~ msgid "Dump configuration of selected chroots" -#~ msgstr "Dump configuration of selected chroots" - -#~ msgid "Chroot selection" -#~ msgstr "Chroot selection" - -#~ msgid "Use specified chroot" -#~ msgstr "Use specified chroot" - -#~ msgid "Chroot environment" -#~ msgstr "Chroot environment" - -#~ msgid "Session management" -#~ msgstr "Session management" - -#~ msgid "Hidden options" -#~ msgstr "Hidden options" - -#~ msgid "Command to run" -#~ msgstr "Command to run" - -#~ msgid " [OPTION...] chroot [COMMAND] - run command or shell in a chroot" -#~ msgstr " [OPTION...] chroot [COMMAND] - run command or shell in a chroot" - -#~ msgid "--quiet and --verbose may not be used at the same time" -#~ msgstr "--quiet and --verbose may not be used at the same time" - -#~ msgid "Using verbose output" -#~ msgstr "Using verbose output" - -#~ msgid "--chroot and --all may not be used at the same time" -#~ msgstr "--chroot and --all may not be used at the same time" - -#~ msgid "Using --chroots only" -#~ msgstr "Using --chroots only" - -#~ msgid "" -#~ "Only one chroot may be specified when recovering, running or ending a " -#~ "session" -#~ msgstr "" -#~ "Only one chroot may be specified when recovering, running or ending a " -#~ "session" - -#~ msgid "--chroot may not be used with --list" -#~ msgstr "--chroot may not be used with --list" - -#~ msgid "Only one action may be specified" -#~ msgstr "Only one action may be specified" diff --git a/po/sv.po b/po/sv.po index 821c5665..11a1530f 100644 --- a/po/sv.po +++ b/po/sv.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: schroot\n" "Report-Msgid-Bugs-To: Roger Leigh \n" -"POT-Creation-Date: 2006-06-23 16:39+0100\n" +"POT-Creation-Date: 2006-06-24 00:38+0100\n" "PO-Revision-Date: 2006-06-17 22:13+0100\n" "Last-Translator: Daniel Nylander \n" "Language-Team: Swedish \n" @@ -15,727 +15,898 @@ msgstr "" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -#: schroot/dchroot-chroot-config.cc:124 +#: dchroot/dchroot.cc:68 dchroot-dsa/dchroot-dsa.cc:68 schroot/schroot.cc:68 #, fuzzy +msgid "An unknown exception occured" +msgstr "Okänd åtgärd angiven" + +#: dchroot/dchroot-chroot-config.cc:123 +#, fuzzy, boost-format msgid "%1% chroot (dchroot compatibility)" msgstr "Kör schroot i dchroot-kompatibelt läge" -#: schroot/dchroot-session.cc:118 +#: dchroot/dchroot-main.cc:59 dchroot-dsa/dchroot-dsa-main.cc:58 +#: schroot/schroot-main.cc:73 +#, boost-format +msgid "schroot configuration generated by %1% %2%" +msgstr "schroot-konfiguration genererad av %1% %2%" + +#: dchroot/dchroot-main.cc:65 dchroot-dsa/dchroot-dsa-main.cc:64 +#, fuzzy +msgid "To allow users access to the chroots, use the users or groups keys." +msgstr "" +"För att tillåta användare att komma åt chrootmiljöerna, lägg till deras " +"grupper till gruppnycklarna." + +#: dchroot/dchroot-main.cc:67 dchroot-dsa/dchroot-dsa-main.cc:66 +#, fuzzy +msgid "" +"To allow passwordless root access, use the root-users or root-groups keys." +msgstr "" +"För att tillåta lösenordslös rotåtkomst, lägg till deras grupper till " +"rotgruppsnycklarna." + +#: dchroot/dchroot-main.cc:69 dchroot/dchroot-main.cc:132 +#: dchroot-dsa/dchroot-dsa-main.cc:68 dchroot-dsa/dchroot-dsa-main.cc:124 +#, boost-format +msgid "Remove '%1%' to use the new configuration." +msgstr "Ta bort \"%1%\" för att använda den nya konfigurationen." + +#: dchroot/dchroot-main.cc:96 dchroot-dsa/dchroot-dsa-main.cc:87 +#, fuzzy +msgid "Running schroot in dchroot compatibility mode" +msgstr "Kör schroot i dchroot-kompatibelt läge" + +#: dchroot/dchroot-main.cc:99 dchroot-dsa/dchroot-dsa-main.cc:90 +#, fuzzy +msgid "Run 'schroot' for full capabilities" +msgstr "Kör \"schroot\" för fullständiga färdigheter" + +#: dchroot/dchroot-main.cc:116 dchroot-dsa/dchroot-dsa-main.cc:108 +#, fuzzy, boost-format +msgid "Using %1% configuration file: " +msgstr "Använder dchroots konfigurationsfil: " + +#: dchroot/dchroot-main.cc:121 dchroot-dsa/dchroot-dsa-main.cc:113 +#, boost-format +msgid "Run '%1%'" +msgstr "Kör \"%1%\"" + +#: dchroot/dchroot-main.cc:125 dchroot-dsa/dchroot-dsa-main.cc:117 +msgid "to migrate to a schroot configuration." +msgstr "för att migrera till en schroot-konfiguration." + +#: dchroot/dchroot-main.cc:128 dchroot-dsa/dchroot-dsa-main.cc:120 +#, boost-format +msgid "Edit '%1%' to add appropriate group access." +msgstr "Redigera \"%1%\" för att lägga till lämplig gruppåtkomst." + +#: dchroot/dchroot-options.cc:56 +msgid "Print path to selected chroot" +msgstr "Skriv ut sökvägen till valda chroot" + +#: dchroot/dchroot-options.cc:60 dchroot-dsa/dchroot-dsa-options.cc:60 +#: schroot/schroot-options.cc:62 +msgid "Select all chroots" +msgstr "Välj alla chroot" + +#: dchroot/dchroot-options.cc:64 schroot/schroot-options.cc:70 +msgid "Preserve user environment" +msgstr "Behåll användarens miljövariabler" + +#: dchroot/dchroot-options.cc:73 dchroot-dsa/dchroot-dsa-options.cc:69 +#: schroot/schroot-listmounts-options.cc:64 schroot/schroot-options.cc:92 +#: schroot/schroot-releaselock-options.cc:67 +msgid "Usage:" +msgstr "Användning:" + +#: dchroot/dchroot-options.cc:76 schroot/schroot-options.cc:95 +#, fuzzy +msgid "[OPTION...] [COMMAND] - run command or shell in a chroot" +msgstr " [FLAGGA...] [KOMMANDO] - kör kommando eller skal i ett chroot" + +#: dchroot/dchroot-options.cc:99 dchroot-dsa/dchroot-dsa-options.cc:102 +#, fuzzy +msgid "Only one command may be specified" +msgstr "Endast en åtgärd får anges" + +#: dchroot/dchroot-options.cc:104 schroot/schroot-options-base.cc:157 +msgid "--quiet and --verbose may not be used at the same time" +msgstr "--quiet och --verbose får inte användas samtidigt" + +#: dchroot/dchroot-options.cc:106 schroot/schroot-options-base.cc:159 +msgid "Using verbose output" +msgstr "Använder informativ utskrift" + +#: dchroot/dchroot-options.cc:112 schroot/schroot-options-base.cc:165 +msgid "--chroot and --all may not be used at the same time" +msgstr "--chroot och --all kan inte användas samtidigt" + +#: dchroot/dchroot-options.cc:114 schroot/schroot-options-base.cc:167 +msgid "Using --chroots only" +msgstr "Använder endast --chroots" + +#: dchroot/dchroot-session-base.cc:76 +#, boost-format +msgid "(%1%->%2%): dchroot sessions do not support user switching" +msgstr "(%1%->%2%): dchroot-sessioner har inte stöd för byte av användare" + +#: dchroot/dchroot-session-base.cc:78 +#, fuzzy +msgid "dchroot session restriction" +msgstr "Val av chroot" + +#: dchroot/dchroot-session.cc:116 dchroot-dsa/dchroot-dsa-session.cc:132 +#, boost-format msgid "[%1% chroot] Running command: \"%2%\"" msgstr "[%1% chroot] Kör kommando: \"%2%\"" -#: schroot/sbuild-auth.cc:52 +#: dchroot-dsa/dchroot-dsa-chroot-config.cc:110 +#, fuzzy, boost-format +msgid "%1% chroot (dchroot-dsa compatibility)" +msgstr "Kör schroot i dchroot-kompatibelt läge" + +#: dchroot-dsa/dchroot-dsa-options.cc:56 +#, fuzzy +msgid "Print paths to available chroots" +msgstr "Lista tillgängliga chroot" + +#: dchroot-dsa/dchroot-dsa-options.cc:72 +#, fuzzy +msgid "[OPTION...] chroot [COMMAND] - run command or shell in a chroot" +msgstr " [FLAGGA...] [KOMMANDO] - kör kommando eller skal i ett chroot" + +#: dchroot-dsa/dchroot-dsa-session.cc:116 +#, boost-format +msgid "%1%: Command must have an absolute path" +msgstr "" + +#: sbuild/sbuild-auth.cc:53 #, fuzzy msgid "Failed to get hostname" msgstr "Misslyckades med att hämta värdnamn: %1%" -#: schroot/sbuild-auth.cc:53 +#: sbuild/sbuild-auth.cc:54 #, fuzzy msgid "User not found" msgstr "%1%: användaren hittades inte: %2%" -#: schroot/sbuild-auth.cc:54 +#: sbuild/sbuild-auth.cc:55 #, fuzzy msgid "Access not authorised" msgstr "tillgång inte auktoriserad" -#: schroot/sbuild-auth.cc:55 +#: sbuild/sbuild-auth.cc:56 #, fuzzy msgid "Authentication failed" msgstr "Autentisering via PAM misslyckades: %1%" -#: schroot/sbuild-auth.cc:56 +#: sbuild/sbuild-auth.cc:57 #, fuzzy msgid "PAM is already initialised" msgstr "PAM-fel: PAM är redan initierad" -#: schroot/sbuild-auth.cc:57 +#: sbuild/sbuild-auth.cc:58 #, fuzzy msgid "PAM error" msgstr "PAM-fel: %1%" -#: schroot/sbuild-auth.cc:420 +#: sbuild/sbuild-auth.cc:421 msgid "Set RUSER" msgstr "" -#: schroot/sbuild-auth.cc:436 +#: sbuild/sbuild-auth.cc:437 msgid "Set RHOST" msgstr "" -#: schroot/sbuild-auth.cc:449 +#: sbuild/sbuild-auth.cc:450 msgid "Set TTY" msgstr "" -#: schroot/sbuild-auth.cc:461 +#: sbuild/sbuild-auth.cc:462 msgid "Set USER" msgstr "" -#: schroot/sbuild-auth.cc:479 +#: sbuild/sbuild-auth.cc:480 +#, boost-format msgid "You do not have permission to access the %1% service." msgstr "Du har inte behörighet att komma åt %1%-tjänsten." -#: schroot/sbuild-auth.cc:482 +#: sbuild/sbuild-auth.cc:483 msgid "This failure will be reported." msgstr "Det här felet kommer att rapporteras." -#: schroot/sbuild-auth-conv-tty.cc:47 +#: sbuild/sbuild-auth-conv-tty.cc:48 msgid "Timed out" msgstr "Tidsgräns överstigen" -#: schroot/sbuild-auth-conv-tty.cc:48 +#: sbuild/sbuild-auth-conv-tty.cc:49 msgid "Time is running out..." msgstr "Tiden rinner iväg..." -#: schroot/sbuild-auth-conv-tty.cc:49 +#: sbuild/sbuild-auth-conv-tty.cc:50 msgid "Failed to get terminal settings" msgstr "Misslyckades med att få tag på terminalinställningar" -#: schroot/sbuild-auth-conv-tty.cc:50 +#: sbuild/sbuild-auth-conv-tty.cc:51 #, fuzzy msgid "Unsupported conversation type" msgstr "Konversationstypen %1% stöds ej" -#: schroot/sbuild-chroot-block-device.cc:176 +#: sbuild/sbuild-chroot-block-device.cc:179 msgid "Device" msgstr "Enhet" -#: schroot/sbuild-chroot-block-device.cc:178 +#: sbuild/sbuild-chroot-block-device.cc:181 msgid "Mount Options" msgstr "Monteringsflaggor" -#: schroot/sbuild-chroot.cc:47 +#: sbuild/sbuild-chroot.cc:58 #, fuzzy msgid "Unknown chroot type" msgstr "okänd chroot-typ \"%1%\"" -#: schroot/sbuild-chroot.cc:48 +#: sbuild/sbuild-chroot.cc:59 #, fuzzy msgid "Chroot creation failed" msgstr "skapandet av chroot misslyckades" -#: schroot/sbuild-chroot.cc:49 +#: sbuild/sbuild-chroot.cc:60 #, fuzzy msgid "Device name not set" msgstr "%1% chroot: enhetsnamn ej inställt" -#: schroot/sbuild-chroot.cc:50 +#: sbuild/sbuild-chroot.cc:61 #, fuzzy msgid "Failed to write session file" msgstr "%1%: misslyckades med att skapa sessionsfil: %2%\n" -#: schroot/sbuild-chroot.cc:51 +#: sbuild/sbuild-chroot.cc:62 #, fuzzy msgid "Failed to unlink session file" msgstr "%1%: misslyckades med att avlänka sessionsfil: %2%\n" -#: schroot/sbuild-chroot.cc:52 schroot/sbuild-chroot-config.cc:56 +#: sbuild/sbuild-chroot.cc:63 sbuild/sbuild-chroot-config.cc:58 #, fuzzy msgid "Failed to stat file" msgstr "misslyckades med att läsa status på fil: %1%" -#: schroot/sbuild-chroot.cc:53 schroot/sbuild-chroot-config.cc:58 +#: sbuild/sbuild-chroot.cc:64 sbuild/sbuild-chroot-config.cc:60 #, fuzzy msgid "File is not owned by user root" msgstr "ägs inte av användaren root" -#: schroot/sbuild-chroot.cc:54 schroot/sbuild-chroot-config.cc:59 +#: sbuild/sbuild-chroot.cc:65 sbuild/sbuild-chroot-config.cc:61 #, fuzzy msgid "File has write permissions for others" msgstr "andra har skrivrättighet" -#: schroot/sbuild-chroot.cc:55 schroot/sbuild-chroot-config.cc:60 +#: sbuild/sbuild-chroot.cc:66 sbuild/sbuild-chroot-config.cc:62 #, fuzzy msgid "File is not a regular file" msgstr "inte en vanlig fil" -#: schroot/sbuild-chroot.cc:56 +#: sbuild/sbuild-chroot.cc:67 #, fuzzy msgid "Failed to acquire file lock" msgstr "misslyckades med att skaffa ett enhetslås" -#: schroot/sbuild-chroot.cc:57 +#: sbuild/sbuild-chroot.cc:68 #, fuzzy msgid "Failed to discard file lock" msgstr "misslyckades med att testa enhetslås" -#: schroot/sbuild-chroot.cc:58 +#: sbuild/sbuild-chroot.cc:69 #, fuzzy msgid "Failed to stat device" msgstr "Misslyckades med att läsa status på enhet %1%: %2%" -#: schroot/sbuild-chroot.cc:59 +#: sbuild/sbuild-chroot.cc:70 #, fuzzy msgid "File is not a block device" msgstr "%1% är inte en blockenhet" -#: schroot/sbuild-chroot.cc:60 +#: sbuild/sbuild-chroot.cc:71 #, fuzzy msgid "Failed to lock device" msgstr "%1%: misslyckades med att låsa enhet: %2%" -#: schroot/sbuild-chroot.cc:61 +#: sbuild/sbuild-chroot.cc:72 #, fuzzy msgid "Failed to unlock device" msgstr "%1%: misslyckades med att låsa upp enhet: %2%" -#: schroot/sbuild-chroot.cc:403 +#: sbuild/sbuild-chroot.cc:414 #, fuzzy msgid "--- Session ---\n" msgstr " --- Session ---\n" -#: schroot/sbuild-chroot.cc:405 +#: sbuild/sbuild-chroot.cc:416 #, fuzzy msgid "--- Chroot ---\n" msgstr " --- Chroot ---\n" -#: schroot/sbuild-chroot.cc:406 +#: sbuild/sbuild-chroot.cc:417 msgid "Name" msgstr "Namn" -#: schroot/sbuild-chroot.cc:407 +#: sbuild/sbuild-chroot.cc:418 msgid "Description" msgstr "Beskrivning" -#: schroot/sbuild-chroot.cc:408 +#: sbuild/sbuild-chroot.cc:419 msgid "Type" msgstr "Typ" -#: schroot/sbuild-chroot.cc:409 +#: sbuild/sbuild-chroot.cc:420 msgid "Priority" msgstr "Prioritet" -#: schroot/sbuild-chroot.cc:410 +#: sbuild/sbuild-chroot.cc:421 msgid "Users" msgstr "" -#: schroot/sbuild-chroot.cc:411 +#: sbuild/sbuild-chroot.cc:422 msgid "Groups" msgstr "Grupper" -#: schroot/sbuild-chroot.cc:412 +#: sbuild/sbuild-chroot.cc:423 #, fuzzy msgid "Root Users" msgstr "Rotgrupper" -#: schroot/sbuild-chroot.cc:413 +#: sbuild/sbuild-chroot.cc:424 msgid "Root Groups" msgstr "Rotgrupper" -#: schroot/sbuild-chroot.cc:414 +#: sbuild/sbuild-chroot.cc:425 msgid "Aliases" msgstr "Alias" -#: schroot/sbuild-chroot.cc:415 +#: sbuild/sbuild-chroot.cc:426 msgid "Run Setup Scripts" msgstr "Kör konfigurationsskript" # Borde det bli "Kör körskript"? Kaka på kaka? -#: schroot/sbuild-chroot.cc:416 +#: sbuild/sbuild-chroot.cc:427 msgid "Run Execution Scripts" msgstr "Kör skript" -#: schroot/sbuild-chroot.cc:418 +#: sbuild/sbuild-chroot.cc:429 msgid "Session Managed" msgstr "Session hanterad" -#: schroot/sbuild-chroot.cc:423 +#: sbuild/sbuild-chroot.cc:434 msgid "Command Prefix" msgstr "Kommandoprefix" -#: schroot/sbuild-chroot.cc:425 +#: sbuild/sbuild-chroot.cc:436 msgid "Personality" msgstr "Personlighet" -#: schroot/sbuild-chroot.cc:429 +#: sbuild/sbuild-chroot.cc:440 msgid "Location" msgstr "Plats" -#: schroot/sbuild-chroot.cc:432 +#: sbuild/sbuild-chroot.cc:443 msgid "Mount Location" msgstr "Montera plats" -#: schroot/sbuild-chroot.cc:435 +#: sbuild/sbuild-chroot.cc:446 msgid "Path" msgstr "Sökväg" -#: schroot/sbuild-chroot.cc:438 +#: sbuild/sbuild-chroot.cc:449 msgid "Mount Device" msgstr "Montera enhet" -#: schroot/sbuild-chroot.cc:597 +#: sbuild/sbuild-chroot.cc:608 +#, boost-format msgid "%1% chroot: personality \"%2%\" is unknown.\n" msgstr "%1% chroot: personligheten \"%2%\" är okänd.\n" -#: schroot/sbuild-chroot.cc:600 +#: sbuild/sbuild-chroot.cc:611 +#, boost-format msgid "Valid personalities: %1%\n" msgstr "Giltiga personligheter: %1%\n" -#: schroot/sbuild-chroot-config.cc:55 +#: sbuild/sbuild-chroot-config.cc:57 #, fuzzy msgid "Failed to open directory" msgstr "%1%: misslyckades med att öppna katalog: %2%" -#: schroot/sbuild-chroot-config.cc:57 +#: sbuild/sbuild-chroot-config.cc:59 #, fuzzy msgid "Failed to open file" msgstr "kan inte öppna fil" -#: schroot/sbuild-chroot-config.cc:180 -#, fuzzy +#: sbuild/sbuild-chroot-config.cc:182 +#, fuzzy, boost-format msgid "%1% chroot: Alias '%2%' already associated with '%3%' chroot" msgstr "%1% chroot: alias \"%2%\" är redan associerat med chroot \"%3%\"" -#: schroot/sbuild-chroot-config.cc:188 -#, fuzzy +#: sbuild/sbuild-chroot-config.cc:190 +#, fuzzy, boost-format msgid "%1% chroot: Alias '%2%' already associated with another chroot" msgstr "%1% chroot: alias \"%2%\" är redan associerat med ett annat chroot" -#: schroot/sbuild-chroot-config.cc:198 -#, fuzzy +#: sbuild/sbuild-chroot-config.cc:200 +#, fuzzy, boost-format msgid "%1% chroot: A chroot or alias already exists by this name" msgstr "%1% chroot: ett chroot eller alias existerar redan med det här namnet" -#: schroot/sbuild-chroot-config.cc:201 -#, fuzzy +#: sbuild/sbuild-chroot-config.cc:203 +#, fuzzy, boost-format msgid "%1% chroot: Duplicate names are not allowed" msgstr "%1% chroot: dubbletta namn tillåts inte" -#: schroot/sbuild-chroot-config.cc:280 +#: sbuild/sbuild-chroot-config.cc:282 msgid "Available chroots: " msgstr "Tillgängliga chroot: " -#: schroot/sbuild-chroot-config.cc:325 schroot/sbuild-chroot-config.cc:344 -#: schroot/sbuild-chroot-config.cc:367 +#: sbuild/sbuild-chroot-config.cc:327 sbuild/sbuild-chroot-config.cc:346 +#: sbuild/sbuild-chroot-config.cc:369 schroot/schroot-main.cc:138 +#, boost-format msgid "%1%: No such chroot" msgstr "%1%: Inget sådant chroot" -#: schroot/sbuild-chroot-file.cc:143 +#: sbuild/sbuild-chroot-file.cc:146 msgid "File" msgstr "Fil" -#: schroot/sbuild-chroot-file.cc:144 +#: sbuild/sbuild-chroot-file.cc:147 msgid "File Repack" msgstr "Filompackning" -#: schroot/sbuild-chroot-lvm-snapshot.cc:201 +#: sbuild/sbuild-chroot-lvm-snapshot.cc:203 msgid "LVM Snapshot Device" msgstr "Enhet för LVM-snapshot" # Finns det ett svenskt ord för snapshot? -#: schroot/sbuild-chroot-lvm-snapshot.cc:204 +#: sbuild/sbuild-chroot-lvm-snapshot.cc:206 msgid "LVM Snapshot Options" msgstr "Flaggor för LVM-snapshot" -#: schroot/sbuild-chroot-source.cc:45 +#: sbuild/sbuild-chroot-source.cc:47 #, fuzzy msgid "(source chroot)" msgstr " (käll-chroot)" -#: schroot/sbuild-chroot-source.cc:115 +#: sbuild/sbuild-chroot-source.cc:117 #, fuzzy msgid "Source Users" msgstr "Källgrupper" -#: schroot/sbuild-chroot-source.cc:116 +#: sbuild/sbuild-chroot-source.cc:118 msgid "Source Groups" msgstr "Källgrupper" -#: schroot/sbuild-chroot-source.cc:117 +#: sbuild/sbuild-chroot-source.cc:119 #, fuzzy msgid "Source Root Users" msgstr "Källrotgrupper" -#: schroot/sbuild-chroot-source.cc:118 +#: sbuild/sbuild-chroot-source.cc:120 msgid "Source Root Groups" msgstr "Källrotgrupper" -#: schroot/sbuild-format-detail.cc:34 +#: sbuild/sbuild-format-detail.cc:34 msgid "true" msgstr "sant" -#: schroot/sbuild-format-detail.cc:36 +#: sbuild/sbuild-format-detail.cc:36 msgid "false" msgstr "falskt" -#: schroot/sbuild-keyfile.cc:363 +#: sbuild/sbuild-keyfile.cc:363 +#, boost-format msgid "%1% chroot: A deprecated parameter \"%2%\" has been specified." msgstr "%1% chroot: En gammal parameter \"%2%\" har angivits." -#: schroot/sbuild-keyfile.cc:367 +#: sbuild/sbuild-keyfile.cc:367 msgid "This option will be removed in the future." msgstr "Den här flaggan kommer att tas bort i framtiden." -#: schroot/sbuild-keyfile.cc:371 +#: sbuild/sbuild-keyfile.cc:371 +#, boost-format msgid "%1% chroot: An obsolete parameter \"%2%\" has been specified." msgstr "%1% chroot: En föråldrad parameter \"%2%\" har angivits." -#: schroot/sbuild-keyfile.cc:375 +#: sbuild/sbuild-keyfile.cc:375 msgid "This option has been removed, and no longer has any effect." msgstr "Den här flaggan har tagits bort och har inte längre någon effekt." -#: schroot/sbuild-lock.cc:48 +#: sbuild/sbuild-lock.cc:49 #, fuzzy msgid "Failed to set timeout handler" msgstr "misslyckades med att ställa in tidsgränshandtag: %1%" -#: schroot/sbuild-lock.cc:49 +#: sbuild/sbuild-lock.cc:50 #, fuzzy msgid "Failed to set timeout" msgstr "misslyckades med att ställa in tidsgräns: %1%" -#: schroot/sbuild-lock.cc:50 +#: sbuild/sbuild-lock.cc:51 #, fuzzy msgid "Failed to cancel timeout" msgstr "misslyckades med att ta bort tidsgräns: %1%" -#: schroot/sbuild-lock.cc:51 +#: sbuild/sbuild-lock.cc:52 #, fuzzy msgid "Failed to acquire lock (timed out)" msgstr "misslyckades med att skaffa ett lås (tidsgräns är %1% sekunder)" -#: schroot/sbuild-lock.cc:52 +#: sbuild/sbuild-lock.cc:53 #, fuzzy msgid "Failed to acquire lock" msgstr "misslyckades med att skaffa ett lås: %1%" -#: schroot/sbuild-lock.cc:53 +#: sbuild/sbuild-lock.cc:54 #, fuzzy msgid "Failed to acquire device lock" msgstr "misslyckades med att skaffa ett enhetslås" -#: schroot/sbuild-lock.cc:54 +#: sbuild/sbuild-lock.cc:55 #, fuzzy msgid "Failed to acquire device lock (timed out)" msgstr "misslyckades med att skaffa ett enhetslås" -#: schroot/sbuild-lock.cc:55 +#: sbuild/sbuild-lock.cc:56 #, fuzzy msgid "Failed to test device lock" msgstr "misslyckades med att testa enhetslås" -#: schroot/sbuild-lock.cc:56 +#: sbuild/sbuild-lock.cc:57 #, fuzzy msgid "Failed to release device lock" msgstr "misslyckades med att släppa enhetslås" -#: schroot/sbuild-lock.cc:57 +#: sbuild/sbuild-lock.cc:58 #, fuzzy msgid "Failed to release device lock (timed out)" msgstr "misslyckades med att släppa enhetslås" -#: schroot/sbuild-lock.cc:274 +#: sbuild/sbuild-lock.cc:275 +#, boost-format msgid "lock held by pid %1%" msgstr "" -#: schroot/sbuild-parse-error.cc:41 +#: sbuild/sbuild-parse-error.cc:41 #, fuzzy msgid "No error" msgstr "inga fel" -#: schroot/sbuild-parse-error.cc:42 +#: sbuild/sbuild-parse-error.cc:42 #, fuzzy msgid "Can't open file" msgstr "kan inte öppna fil" -#: schroot/sbuild-parse-error.cc:43 +#: sbuild/sbuild-parse-error.cc:43 #, fuzzy msgid "Could not parse value" msgstr "kunde inte tolka värde" -#: schroot/sbuild-parse-error.cc:44 +#: sbuild/sbuild-parse-error.cc:44 #, fuzzy msgid "Invalid line" msgstr "ogiltig rad" -#: schroot/sbuild-parse-error.cc:45 +#: sbuild/sbuild-parse-error.cc:45 #, fuzzy msgid "No group specified" msgstr "ingen grupp angiven" -#: schroot/sbuild-parse-error.cc:46 +#: sbuild/sbuild-parse-error.cc:46 #, fuzzy msgid "Invalid group" msgstr "ogiltig grupp" -#: schroot/sbuild-parse-error.cc:47 +#: sbuild/sbuild-parse-error.cc:47 #, fuzzy msgid "Duplicate group" msgstr "dubblett av grupp" -#: schroot/sbuild-parse-error.cc:48 +#: sbuild/sbuild-parse-error.cc:48 #, fuzzy msgid "No key specified" msgstr "ingen nyckel angiven" -#: schroot/sbuild-parse-error.cc:49 +#: sbuild/sbuild-parse-error.cc:49 #, fuzzy msgid "Duplicate key" msgstr "dubblett av nyckel" -#: schroot/sbuild-parse-error.cc:50 +#: sbuild/sbuild-parse-error.cc:50 #, fuzzy msgid "Required key is missing" msgstr "nödvändig nyckel saknas" -#: schroot/sbuild-parse-error.cc:51 +#: sbuild/sbuild-parse-error.cc:51 #, fuzzy msgid "Disallowed key used" msgstr "ej tillåten nyckel användes" -#: schroot/sbuild-parse-error.cc:116 +#: sbuild/sbuild-parse-error.cc:116 #, fuzzy msgid "Unknown error" msgstr "okänt fel" -#: schroot/sbuild-parse-error.cc:127 +#: sbuild/sbuild-parse-error.cc:127 +#, boost-format msgid "%1% \"%2%\"" msgstr "%1% \"%2%\"" -#: schroot/sbuild-parse-error.cc:143 +#: sbuild/sbuild-parse-error.cc:143 +#, boost-format msgid "line %1%: %3%" msgstr "rad %1%: %3%" -#: schroot/sbuild-parse-error.cc:144 +#: sbuild/sbuild-parse-error.cc:144 +#, boost-format msgid "line %1%: %2% \"%3%\"" msgstr "rad %1%: %2% \"%3%\"" -#: schroot/sbuild-parse-error.cc:150 +#: sbuild/sbuild-parse-error.cc:150 +#, boost-format msgid "line %1%: %2%" msgstr "rad %1%: %2%" -#: schroot/sbuild-parse-error.cc:165 +#: sbuild/sbuild-parse-error.cc:165 +#, boost-format msgid "line %1% [%2%]: %4%" msgstr "rad %1% [%2%]: %4%" -#: schroot/sbuild-parse-error.cc:166 +#: sbuild/sbuild-parse-error.cc:166 +#, boost-format msgid "line %1% [%2%]: %3% \"%4%\"" msgstr "rad %1% [%2%]: %3% \"%4%\"" -#: schroot/sbuild-parse-error.cc:172 +#: sbuild/sbuild-parse-error.cc:172 +#, boost-format msgid "line %1% [%2%]: %3%" msgstr "rad %1% [%2%]: %3%" -#: schroot/sbuild-parse-error.cc:188 +#: sbuild/sbuild-parse-error.cc:188 +#, boost-format msgid "line %1% [%2%] %3%: %5%" msgstr "rad %1% [%2%] %3%: %5%" -#: schroot/sbuild-parse-error.cc:189 +#: sbuild/sbuild-parse-error.cc:189 +#, boost-format msgid "line %1% [%2%] %3%: %4% \"%5%\"" msgstr "rad %1% [%2%] %3%: %4% \"%5%\"" -#: schroot/sbuild-parse-error.cc:195 +#: sbuild/sbuild-parse-error.cc:195 +#, boost-format msgid "line %1% [%2%] %3%: %4%" msgstr "rad %1% [%2%] %3%: %4%" -#: schroot/sbuild-parse-error.cc:209 +#: sbuild/sbuild-parse-error.cc:209 +#, boost-format msgid "[%1%]: %3%" msgstr "[%1%]: %3%" -#: schroot/sbuild-parse-error.cc:210 +#: sbuild/sbuild-parse-error.cc:210 +#, boost-format msgid "[%1%]: %2% \"%3%\"" msgstr "[%1%]: %2% \"%3%\"" -#: schroot/sbuild-parse-error.cc:216 +#: sbuild/sbuild-parse-error.cc:216 +#, boost-format msgid "[%1%]: %2%" msgstr "[%1%]: %2%" -#: schroot/sbuild-parse-error.cc:231 +#: sbuild/sbuild-parse-error.cc:231 +#, boost-format msgid "[%1%] %2%: %4%" msgstr "[%1%] %2%: %4%" -#: schroot/sbuild-parse-error.cc:232 +#: sbuild/sbuild-parse-error.cc:232 +#, boost-format msgid "[%1%] %2%: %3% \"%4%\"" msgstr "[%1%] %2%: %3% \"%4%\"" -#: schroot/sbuild-parse-error.cc:238 +#: sbuild/sbuild-parse-error.cc:238 +#, boost-format msgid "[%1%] %2%: %3%" msgstr "[%1%] %2%: %3%" -#: schroot/sbuild-personality.cc:48 +#: sbuild/sbuild-personality.cc:48 #, fuzzy msgid "Failed to set personality" msgstr "Misslyckades med att få tag på terminalinställningar" -#: schroot/sbuild-session.cc:57 +#: sbuild/sbuild-session.cc:59 #, fuzzy msgid "Failed to find chroot" msgstr "%1%: Misslyckades med att hitta chroot" -#: schroot/sbuild-session.cc:58 +#: sbuild/sbuild-session.cc:60 #, fuzzy msgid "Failed to lock chroot" msgstr "%1%: Misslyckades med att hitta chroot" -#: schroot/sbuild-session.cc:59 +#: sbuild/sbuild-session.cc:61 #, fuzzy msgid "Failed to unlock chroot" msgstr "%1%: Misslyckades med att hitta chroot" -#: schroot/sbuild-session.cc:60 +#: sbuild/sbuild-session.cc:62 #, fuzzy msgid "Chroot setup failed" msgstr "skapandet av chroot misslyckades" -#: schroot/sbuild-session.cc:61 +#: sbuild/sbuild-session.cc:63 #, fuzzy msgid "Failed to set hangup signal handler" msgstr "misslyckades med att ställa in påläggningshanterare: %1%" -#: schroot/sbuild-session.cc:62 +#: sbuild/sbuild-session.cc:64 #, fuzzy msgid "Caught hangup signal" msgstr "fångade påläggningssignal, terminerar..." -#: schroot/sbuild-session.cc:63 +#: sbuild/sbuild-session.cc:65 #, fuzzy msgid "Failed to fork child" msgstr "Misslyckades med att grena process: %1%" -#: schroot/sbuild-session.cc:64 +#: sbuild/sbuild-session.cc:66 #, fuzzy msgid "Wait for child failed" msgstr "väntan på barnprocess misslyckades: %1%" -#: schroot/sbuild-session.cc:65 +#: sbuild/sbuild-session.cc:67 #, fuzzy msgid "Child terminated by signal" msgstr "Barnprocess terminerades av signal \"%1%\"" -#: schroot/sbuild-session.cc:66 +#: sbuild/sbuild-session.cc:68 msgid "Child dumped core" msgstr "Barnprocess dumpade minnet" # coredump? Bättre ord? -#: schroot/sbuild-session.cc:67 +#: sbuild/sbuild-session.cc:69 msgid "Child exited abnormally (reason unknown; not a signal or core dump)" msgstr "" "Barnprocess avslutades onormalt (anledning är okänd; inte en signal eller " "minnesdump)" -#: schroot/sbuild-session.cc:68 +#: sbuild/sbuild-session.cc:70 msgid "User switching is not permitted" msgstr "" -#: schroot/sbuild-session.cc:106 -#, fuzzy +#: sbuild/sbuild-session.cc:108 +#, fuzzy, boost-format msgid "%1%: Group not found" msgstr "%1%: grupp hittades inte" -#: schroot/sbuild-session.cc:108 -#, fuzzy +#: sbuild/sbuild-session.cc:110 +#, fuzzy, boost-format msgid "%1%: Group not found: %2%" msgstr "%1%: grupp hittades inte: %2%" -#: schroot/sbuild-session.cc:124 -#, fuzzy +#: sbuild/sbuild-session.cc:126 +#, fuzzy, boost-format msgid "Can't get supplementary group count: %1%" msgstr "kan inte hämta antalet tilläggsgrupper: %1%" -#: schroot/sbuild-session.cc:134 -#, fuzzy +#: sbuild/sbuild-session.cc:136 +#, fuzzy, boost-format msgid "Can't get supplementary groups: %1%" msgstr "kan inte hämta tilläggsgrupper: %1%" -#: schroot/sbuild-session.cc:364 +#: sbuild/sbuild-session.cc:366 +#, boost-format msgid "No chroot found matching alias '%1%'" msgstr "Inget chroot hittades som matchar alias \"%1%\"" -#: schroot/sbuild-session.cc:571 -#, fuzzy +#: sbuild/sbuild-session.cc:573 +#, fuzzy, boost-format msgid "%1%: Shell not available: %2%" msgstr "%1%: misslyckades med att läsa status på fil: %2%" -#: schroot/sbuild-session.cc:574 -#, fuzzy +#: sbuild/sbuild-session.cc:576 +#, fuzzy, boost-format msgid "Falling back to %1%" msgstr "Faller tillbaka på \"%1%\"" -#: schroot/sbuild-session.cc:640 -#, fuzzy +#: sbuild/sbuild-session.cc:642 +#, fuzzy, boost-format msgid "[%1% chroot] Running login shell: \"%4%\"" msgstr "[%1% chroot] Kör inloggningsskal: \"%2%\"" -#: schroot/sbuild-session.cc:642 -#, fuzzy +#: sbuild/sbuild-session.cc:644 +#, fuzzy, boost-format msgid "[%1% chroot] Running shell: \"%4%\"" msgstr "[%1% chroot] Kör skal: \"%2%\"" -#: schroot/sbuild-session.cc:648 +#: sbuild/sbuild-session.cc:650 +#, boost-format msgid "[%1% chroot] (%2%->%3%) Running login shell: \"%4%\"" msgstr "[%1% chroot] (%2%->%3%) Kör inloggningsskal: \"%4%\"" -#: schroot/sbuild-session.cc:650 +#: sbuild/sbuild-session.cc:652 +#, boost-format msgid "[%1% chroot] (%2%->%3%) Running shell: \"%4%\"" msgstr "[%1% chroot] (%2%->%3%) Kör skal: \"%4%\"" -#: schroot/sbuild-session.cc:685 -#, fuzzy +#: sbuild/sbuild-session.cc:687 +#, fuzzy, boost-format msgid "[%1% chroot] Running command: \"%4%\"" msgstr "[%1% chroot] Kör kommando: \"%2%\"" -#: schroot/sbuild-session.cc:687 +#: sbuild/sbuild-session.cc:689 +#, boost-format msgid "[%1% chroot] (%2%->%3%) Running command: \"%4%\"" msgstr "[%1% chroot] (%2%->%3%) Kör kommando: \"%4%\"" -#: schroot/sbuild-session.cc:809 +#: sbuild/sbuild-session.cc:811 +#, boost-format msgid "Invalid verbosity level: %1%, falling back to \"normal\"" msgstr "Ogiltig informationsnivå: %1%, faller tillbaka till \"normal\"" -#: schroot/sbuild-session.cc:845 schroot/sbuild-session.cc:1020 +#: sbuild/sbuild-session.cc:847 sbuild/sbuild-session.cc:1022 +#, boost-format msgid "Could not exec \"%1%\": %2%" msgstr "Kunde inte starta \"%1%\": %2%" -#: schroot/sbuild-session.cc:871 +#: sbuild/sbuild-session.cc:873 +#, boost-format msgid "stage=%1%" msgstr "" -#: schroot/sbuild-session.cc:900 +#: sbuild/sbuild-session.cc:902 +#, boost-format msgid "PAM error: %1%" msgstr "PAM-fel: %1%" -#: schroot/sbuild-session.cc:908 +#: sbuild/sbuild-session.cc:910 +#, boost-format msgid "Could not set gid to '%1%'" msgstr "Kunde inte sätta gid till \"%1%\"" -#: schroot/sbuild-session.cc:914 +#: sbuild/sbuild-session.cc:916 msgid "Could not set supplementary group IDs" msgstr "Kunde inte sätta id för tilläggsgrupper" -#: schroot/sbuild-session.cc:932 schroot/sbuild-session.cc:980 +#: sbuild/sbuild-session.cc:934 sbuild/sbuild-session.cc:982 +#, boost-format msgid "Could not chdir to '%1%': %2%" msgstr "Kunde inte byta katalog till \"%1%\": %2%" -#: schroot/sbuild-session.cc:939 +#: sbuild/sbuild-session.cc:941 +#, boost-format msgid "Could not chroot to '%1%': %2%" msgstr "Kunde inte chroot till \"%1%\": %2%" -#: schroot/sbuild-session.cc:948 +#: sbuild/sbuild-session.cc:950 +#, boost-format msgid "Could not set uid to '%1%'" msgstr "Kunde inte sätta uid till \"%1%\"" -#: schroot/sbuild-session.cc:954 +#: sbuild/sbuild-session.cc:956 msgid "Failed to drop root permissions." msgstr "Misslyckades med att släppa root-rättigheter." -#: schroot/sbuild-session.cc:987 +#: sbuild/sbuild-session.cc:989 +#, boost-format msgid "Falling back to '%1%'" msgstr "Faller tillbaka på \"%1%\"" -#: schroot/sbuild-session.cc:1042 +#: sbuild/sbuild-session.cc:1044 #, fuzzy msgid "Caught hangup signal, terminating..." msgstr "fångade påläggningssignal, terminerar..." -#: schroot/schroot.cc:68 -#, fuzzy -msgid "An unknown exception occured" -msgstr "Okänd åtgärd angiven" - -#: schroot/schroot-listmounts.cc:57 -msgid "schroot-listmounts (Debian sbuild) %1%\n" -msgstr "schroot-listmounts (Debian sbuild) %1%\n" +#: schroot/schroot-listmounts.cc:61 schroot/schroot-main.cc:58 +#: schroot/schroot-releaselock.cc:56 +#, fuzzy, boost-format +msgid "%1% (Debian sbuild) %2% (%3%)\n" +msgstr "%1% (Debian sbuild) %2%\n" -#: schroot/schroot-listmounts.cc:58 schroot/schroot-releaselock.cc:55 +#: schroot/schroot-listmounts.cc:65 schroot/schroot-main.cc:62 +#: schroot/schroot-releaselock.cc:60 msgid "" "Written by Roger Leigh\n" "\n" @@ -743,11 +914,13 @@ msgstr "" "Skriven av Roger Leigh\n" "\n" -#: schroot/schroot-listmounts.cc:59 schroot/schroot-releaselock.cc:56 +#: schroot/schroot-listmounts.cc:66 schroot/schroot-main.cc:63 +#: schroot/schroot-releaselock.cc:61 msgid "Copyright (C) 2004-2006 Roger Leigh\n" msgstr "Copyright © 2004-2005 Roger Leigh\n" -#: schroot/schroot-listmounts.cc:60 schroot/schroot-releaselock.cc:57 +#: schroot/schroot-listmounts.cc:67 schroot/schroot-main.cc:64 +#: schroot/schroot-releaselock.cc:62 msgid "" "This is free software; see the source for copying conditions. There is NO\n" "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" @@ -756,148 +929,226 @@ msgstr "" "INGEN GARANTI;\n" "inte ens för SÄLJBARHET eller LÄMPLIGHET FÖR NÅGOT SPECIELLT ÄNDAMÅL.\n" -#: schroot/schroot-listmounts.cc:82 +#: schroot/schroot-listmounts.cc:89 +#, boost-format msgid "%1%: Failed to open: %2%" msgstr "%1%: Misslyckades med att öppna: %2%" -#: schroot/schroot-listmounts.cc:105 +#: schroot/schroot-listmounts.cc:112 +#, boost-format msgid "%1%: Failed to close: %2%" msgstr "%1%: Misslyckades med att stänga: %2%" -#: schroot/schroot-listmounts.cc:151 +#: schroot/schroot-listmounts.cc:158 msgid "No mountpoint specified" msgstr "Ingen monteringspunkt angiven" -#: schroot/schroot-listmounts-options.cc:43 -#: schroot/schroot-releaselock-options.cc:44 +#: schroot/schroot-listmounts-options.cc:42 schroot/schroot-options-base.cc:48 +#: schroot/schroot-releaselock-options.cc:43 msgid "General options" msgstr "Allmänna flaggor" -#: schroot/schroot-listmounts-options.cc:45 -#: schroot/schroot-releaselock-options.cc:46 +#: schroot/schroot-listmounts-options.cc:44 schroot/schroot-options-base.cc:69 +#: schroot/schroot-releaselock-options.cc:45 msgid "Show help options" msgstr "Visa hjälpflaggor" -#: schroot/schroot-listmounts-options.cc:47 -#: schroot/schroot-releaselock-options.cc:48 +#: schroot/schroot-listmounts-options.cc:46 schroot/schroot-options-base.cc:71 +#: schroot/schroot-releaselock-options.cc:47 msgid "Print version information" msgstr "Skriv ut versionsinformation" -#: schroot/schroot-listmounts-options.cc:49 -#: schroot/schroot-releaselock-options.cc:50 +#: schroot/schroot-listmounts-options.cc:48 +#: schroot/schroot-releaselock-options.cc:49 msgid "Lock options" msgstr "Låsflaggor" -#: schroot/schroot-listmounts-options.cc:52 +#: schroot/schroot-listmounts-options.cc:51 msgid "Mountpoint to check (full path)" msgstr "Monteringspunkt att kontrollera (fullständig sökväg)" -#: schroot/schroot-listmounts-options.cc:65 schroot/schroot-options.cc:95 -#: schroot/schroot-releaselock-options.cc:68 -msgid "Usage:" -msgstr "Användning:" - -#: schroot/schroot-listmounts-options.cc:66 +#: schroot/schroot-listmounts-options.cc:65 #, fuzzy msgid "schroot-listmounts [OPTION...] - list mounts" msgstr " schroot-listmounts [FLAGGA...] - lista monteringar" -#: schroot/schroot-options.cc:59 +#: schroot/schroot-main.cc:194 +msgid "Error saving terminal settings" +msgstr "Fel vid sparandet av terminalinställningar" + +#: schroot/schroot-main.cc:226 +#, boost-format +msgid "No chroots are defined in %1% or %2%" +msgstr "Inga chroot angivna i %1% eller %2%" + +#: schroot/schroot-main.cc:234 +#, boost-format +msgid "No chroots are defined in %1%" +msgstr "Inga chroot angivna i %1%" + +#: schroot/schroot-main.cc:251 +#, boost-format +msgid "The specified chroots are not defined in %1%" +msgstr "De angivna chroot finns inte angivna i %1%" + +#: schroot/schroot-main.cc:278 +msgid "Only one chroot may be specified when beginning a session" +msgstr "Endast en chroot får anges vid början av en session" + +#: schroot/schroot-main.cc:335 schroot/schroot-main.cc:351 +msgid "Error restoring terminal settings" +msgstr "Fel vid återställandet av terminalinställningar" + +#: schroot/schroot-options-base.cc:49 +msgid "Chroot selection" +msgstr "Val av chroot" + +#: schroot/schroot-options-base.cc:50 +msgid "Chroot environment" +msgstr "Chroot-miljö" + +#: schroot/schroot-options-base.cc:51 +msgid "Session management" +msgstr "Sessionshantering" + +#: schroot/schroot-options-base.cc:52 +msgid "Hidden options" +msgstr "Dolda flaggor" + +#: schroot/schroot-options-base.cc:73 +msgid "Show less output" +msgstr "Visa mindre utdata" + +#: schroot/schroot-options-base.cc:75 +msgid "Show more output" +msgstr "Visa mer utdata" + +#: schroot/schroot-options-base.cc:77 +msgid "List available chroots" +msgstr "Lista tillgängliga chroot" + +#: schroot/schroot-options-base.cc:79 +msgid "Show information about selected chroots" +msgstr "Visa information om valda chroot" + +#: schroot/schroot-options-base.cc:81 +msgid "Dump configuration of selected chroots" +msgstr "Dumpa konfigurationen för valda chroot" + +#: schroot/schroot-options-base.cc:85 +msgid "Use specified chroot" +msgstr "Använd angiven chroot" + +#: schroot/schroot-options-base.cc:89 +msgid "Command to run" +msgstr "Kommando att köra" + +#: schroot/schroot-options-base.cc:91 +msgid "Enable debugging messages" +msgstr "" + +#: schroot/schroot-options-base.cc:190 +msgid "" +"Only one chroot may be specified when recovering, running or ending a session" +msgstr "" +"Endast ett chroot får anges vid återhämtning, körning eller avslutning av en " +"session" + +#: schroot/schroot-options-base.cc:215 +msgid "--chroot may not be used with --list" +msgstr "--chroot får inte användas med --list" + +#: schroot/schroot-options-base.cc:237 +#, fuzzy +msgid "Unknown action specified" +msgstr "Endast en åtgärd får anges" + +#: schroot/schroot-options-base.cc:245 +msgid "Only one action may be specified" +msgstr "Endast en åtgärd får anges" + +#: schroot/schroot-options.cc:56 msgid "Print location of selected chroots" msgstr "Skriv ut platsen för valda chroot" -#: schroot/schroot-options.cc:63 +#: schroot/schroot-options.cc:60 msgid "Select all chroots and active sessions" msgstr "Välj alla chroot och aktiva sessioner" -#: schroot/schroot-options.cc:65 -msgid "Select all chroots" -msgstr "Välj alla chroot" - -#: schroot/schroot-options.cc:67 +#: schroot/schroot-options.cc:64 msgid "Select all active sessions" msgstr "Välj alla aktiva sessioner" -#: schroot/schroot-options.cc:71 +#: schroot/schroot-options.cc:68 msgid "Username (default current user)" msgstr "Användarnamn (förval är nuvarande användare)" -#: schroot/schroot-options.cc:73 -msgid "Preserve user environment" -msgstr "Behåll användarens miljövariabler" - -#: schroot/schroot-options.cc:77 +#: schroot/schroot-options.cc:74 msgid "Begin a session; returns a session ID" msgstr "Börja en session; returnerar ett sessions-id" -#: schroot/schroot-options.cc:79 +#: schroot/schroot-options.cc:76 msgid "Recover an existing session" msgstr "Återhämta en existerande session" -#: schroot/schroot-options.cc:81 +#: schroot/schroot-options.cc:78 msgid "Run an existing session" msgstr "Kör en existerande session" -#: schroot/schroot-options.cc:83 +#: schroot/schroot-options.cc:80 msgid "End an existing session" msgstr "Avsluta en existerande session" -#: schroot/schroot-options.cc:85 +#: schroot/schroot-options.cc:82 msgid "Force operation, even if it fails" msgstr "Tvinga operation, även om den misslyckas" -#: schroot/schroot-options.cc:98 -#, fuzzy -msgid "[OPTION...] [COMMAND] - run command or shell in a chroot" -msgstr " [FLAGGA...] [KOMMANDO] - kör kommando eller skal i ett chroot" - -#: schroot/schroot-releaselock.cc:54 -msgid "schroot-releaselock (Debian sbuild) %1%\n" -msgstr "schroot-releaselock (Debian sbuild) %1%\n" - -#: schroot/schroot-releaselock.cc:100 +#: schroot/schroot-releaselock.cc:105 msgid "No device specified" msgstr "Ingen enhet angiven" -#: schroot/schroot-releaselock.cc:106 +#: schroot/schroot-releaselock.cc:111 msgid "No pid specified; forcing release of lock" msgstr "Ingen pid angiven; tvingar släpp av lås" -#: schroot/schroot-releaselock.cc:115 +#: schroot/schroot-releaselock.cc:120 +#, boost-format msgid "Failed to stat device %1%: %2%" msgstr "Misslyckades med att läsa status på enhet %1%: %2%" -#: schroot/schroot-releaselock.cc:123 +#: schroot/schroot-releaselock.cc:128 +#, boost-format msgid "%1% is not a block device" msgstr "%1% är inte en blockenhet" -#: schroot/schroot-releaselock.cc:131 +#: schroot/schroot-releaselock.cc:136 +#, boost-format msgid "%1%: failed to release device lock" msgstr "%1%: misslyckades med att släppa enhetslås" -#: schroot/schroot-releaselock.cc:138 +#: schroot/schroot-releaselock.cc:143 +#, boost-format msgid "%1%: failed to release device lock owned by pid %2%" msgstr "%1%: misslyckades med att släppa enhetslås som ägs av pid %2%" -#: schroot/schroot-releaselock-options.cc:53 +#: schroot/schroot-releaselock-options.cc:52 msgid "Device to unlock (full path)" msgstr "Enhet att låsa upp (full sökväg)" -#: schroot/schroot-releaselock-options.cc:55 +#: schroot/schroot-releaselock-options.cc:54 msgid "Process ID owning the lock" msgstr "Process-id som äger låset" -#: schroot/schroot-releaselock-options.cc:69 +#: schroot/schroot-releaselock-options.cc:68 #, fuzzy msgid "schroot-releaselock [OPTION...] - release a device lock" msgstr " schroot-releaselock [FLAGGA...] - släpp ett enhetslås" -#~ msgid "(%1%->%2%): dchroot sessions do not support user switching" -#~ msgstr "(%1%->%2%): dchroot-sessioner har inte stöd för byte av användare" +#~ msgid "schroot-listmounts (Debian sbuild) %1%\n" +#~ msgstr "schroot-listmounts (Debian sbuild) %1%\n" -#, fuzzy -#~ msgid "dchroot session restriction" -#~ msgstr "Val av chroot" +#~ msgid "schroot-releaselock (Debian sbuild) %1%\n" +#~ msgstr "schroot-releaselock (Debian sbuild) %1%\n" #~ msgid "%1%: not a regular file" #~ msgstr "%1%: inte en vanlig fil" @@ -905,134 +1156,9 @@ msgstr " schroot-releaselock [FLAGGA...] - släpp ett enhetslås" #~ msgid "Falling back to home directory '%1%'" #~ msgstr "Faller tillbaka på hemkatalogen \"%1%\"" -#~ msgid "%1% (Debian sbuild) %2%\n" -#~ msgstr "%1% (Debian sbuild) %2%\n" - -#~ msgid "Error saving terminal settings" -#~ msgstr "Fel vid sparandet av terminalinställningar" - -#, fuzzy -#~ msgid "Run 'schroot' for full capabilities" -#~ msgstr "Kör \"schroot\" för fullständiga färdigheter" - -#~ msgid "Using dchroot configuration file: " -#~ msgstr "Använder dchroots konfigurationsfil: " - -#~ msgid "Run '%1%'" -#~ msgstr "Kör \"%1%\"" - -#~ msgid "to migrate to a schroot configuration." -#~ msgstr "för att migrera till en schroot-konfiguration." - -#~ msgid "Edit '%1%' to add appropriate group access." -#~ msgstr "Redigera \"%1%\" för att lägga till lämplig gruppåtkomst." - -#~ msgid "Remove '%1%' to use the new configuration." -#~ msgstr "Ta bort \"%1%\" för att använda den nya konfigurationen." - -#~ msgid "No chroots are defined in %1% or %2%" -#~ msgstr "Inga chroot angivna i %1% eller %2%" - -#~ msgid "No chroots are defined in %1%" -#~ msgstr "Inga chroot angivna i %1%" - -#~ msgid "The specified chroots are not defined in %1%" -#~ msgstr "De angivna chroot finns inte angivna i %1%" - -#~ msgid "schroot configuration generated by %1% %2%" -#~ msgstr "schroot-konfiguration genererad av %1% %2%" - -#, fuzzy -#~ msgid "To allow users access to the chroots, use the users or groups keys." -#~ msgstr "" -#~ "För att tillåta användare att komma åt chrootmiljöerna, lägg till deras " -#~ "grupper till gruppnycklarna." - -#, fuzzy -#~ msgid "" -#~ "To allow passwordless root access, use the root-users or root-groups keys." -#~ msgstr "" -#~ "För att tillåta lösenordslös rotåtkomst, lägg till deras grupper till " -#~ "rotgruppsnycklarna." - -#~ msgid "Only one chroot may be specified when beginning a session" -#~ msgstr "Endast en chroot får anges vid början av en session" - #~ msgid "Session failure: %1%" #~ msgstr "Sessionsfel: %1%" -#~ msgid "Error restoring terminal settings" -#~ msgstr "Fel vid återställandet av terminalinställningar" - -#~ msgid "Show less output" -#~ msgstr "Visa mindre utdata" - -#~ msgid "Show more output" -#~ msgstr "Visa mer utdata" - -#~ msgid "List available chroots" -#~ msgstr "Lista tillgängliga chroot" - -#~ msgid "Show information about selected chroots" -#~ msgstr "Visa information om valda chroot" - -#~ msgid "Print path to selected chroot" -#~ msgstr "Skriv ut sökvägen till valda chroot" - -#, fuzzy -#~ msgid "Print paths to available chroots" -#~ msgstr "Lista tillgängliga chroot" - -#~ msgid "Dump configuration of selected chroots" -#~ msgstr "Dumpa konfigurationen för valda chroot" - -#~ msgid "Chroot selection" -#~ msgstr "Val av chroot" - -#~ msgid "Use specified chroot" -#~ msgstr "Använd angiven chroot" - -#~ msgid "Chroot environment" -#~ msgstr "Chroot-miljö" - -#~ msgid "Session management" -#~ msgstr "Sessionshantering" - -#~ msgid "Hidden options" -#~ msgstr "Dolda flaggor" - -#~ msgid "Command to run" -#~ msgstr "Kommando att köra" - -#, fuzzy -#~ msgid " [OPTION...] chroot [COMMAND] - run command or shell in a chroot" -#~ msgstr " [FLAGGA...] [KOMMANDO] - kör kommando eller skal i ett chroot" - -#~ msgid "--quiet and --verbose may not be used at the same time" -#~ msgstr "--quiet och --verbose får inte användas samtidigt" - -#~ msgid "Using verbose output" -#~ msgstr "Använder informativ utskrift" - -#~ msgid "--chroot and --all may not be used at the same time" -#~ msgstr "--chroot och --all kan inte användas samtidigt" - -#~ msgid "Using --chroots only" -#~ msgstr "Använder endast --chroots" - -#~ msgid "" -#~ "Only one chroot may be specified when recovering, running or ending a " -#~ "session" -#~ msgstr "" -#~ "Endast ett chroot får anges vid återhämtning, körning eller avslutning av " -#~ "en session" - -#~ msgid "--chroot may not be used with --list" -#~ msgstr "--chroot får inte användas med --list" - -#~ msgid "Only one action may be specified" -#~ msgstr "Endast en åtgärd får anges" - #~ msgid "line %1%: invalid line: %2%" #~ msgstr "rad %1%: ogiltig rad: %2%" diff --git a/po/vi.po b/po/vi.po index fb1b61ec..e49ac913 100644 --- a/po/vi.po +++ b/po/vi.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: schroot-0.99.0-1\n" "Report-Msgid-Bugs-To: Roger Leigh \n" -"POT-Creation-Date: 2006-06-23 16:39+0100\n" +"POT-Creation-Date: 2006-06-24 00:38+0100\n" "PO-Revision-Date: 2006-06-22 23:06+0930\n" "Last-Translator: Clytie Siddall \n" "Language-Team: Vietnamese \n" @@ -16,725 +16,900 @@ msgstr "" "Plural-Forms: nplurals=1; plural=0\n" "X-Generator: LocFactoryEditor 1.6a7\n" -#: schroot/dchroot-chroot-config.cc:124 +#: dchroot/dchroot.cc:68 dchroot-dsa/dchroot-dsa.cc:68 schroot/schroot.cc:68 #, fuzzy +msgid "An unknown exception occured" +msgstr "Đã ghi rõ một hành động không rõ" + +#: dchroot/dchroot-chroot-config.cc:123 +#, fuzzy, boost-format msgid "%1% chroot (dchroot compatibility)" msgstr "Đang chạy schroot trong chế độ tương thích" -#: schroot/dchroot-session.cc:118 +#: dchroot/dchroot-main.cc:59 dchroot-dsa/dchroot-dsa-main.cc:58 +#: schroot/schroot-main.cc:73 +#, boost-format +msgid "schroot configuration generated by %1% %2%" +msgstr "Cấu hình schroot được tạo ra bởi %1% %2%" + +#: dchroot/dchroot-main.cc:65 dchroot-dsa/dchroot-dsa-main.cc:64 +#, fuzzy +msgid "To allow users access to the chroots, use the users or groups keys." +msgstr "" +"Để cho phép người dùng truy cập những chroot này, hãy thêm các nhóm của họ " +"vào những khoá nhóm (groups)." + +#: dchroot/dchroot-main.cc:67 dchroot-dsa/dchroot-dsa-main.cc:66 +#, fuzzy +msgid "" +"To allow passwordless root access, use the root-users or root-groups keys." +msgstr "" +"Để cho phép việc truy cập kiểu người chủ mà không cần mật khẩu, hãy thêm các " +"nhóm của họ vào khoá nhóm chủ (root-groups)." + +#: dchroot/dchroot-main.cc:69 dchroot/dchroot-main.cc:132 +#: dchroot-dsa/dchroot-dsa-main.cc:68 dchroot-dsa/dchroot-dsa-main.cc:124 +#, boost-format +msgid "Remove '%1%' to use the new configuration." +msgstr "Gỡ bỏ « %1% » để sử dụng cấu hình mới." + +#: dchroot/dchroot-main.cc:96 dchroot-dsa/dchroot-dsa-main.cc:87 +#, fuzzy +msgid "Running schroot in dchroot compatibility mode" +msgstr "Đang chạy schroot trong chế độ tương thích" + +#: dchroot/dchroot-main.cc:99 dchroot-dsa/dchroot-dsa-main.cc:90 +#, fuzzy +msgid "Run 'schroot' for full capabilities" +msgstr "Chạy « schroot » để có khả năng đầy đủ" + +#: dchroot/dchroot-main.cc:116 dchroot-dsa/dchroot-dsa-main.cc:108 +#, fuzzy, boost-format +msgid "Using %1% configuration file: " +msgstr "Đang dùng tập tin cấu hình dchroot: " + +#: dchroot/dchroot-main.cc:121 dchroot-dsa/dchroot-dsa-main.cc:113 +#, boost-format +msgid "Run '%1%'" +msgstr "Chạy « %1% »" + +#: dchroot/dchroot-main.cc:125 dchroot-dsa/dchroot-dsa-main.cc:117 +msgid "to migrate to a schroot configuration." +msgstr "để nâng cấp lên một cấu hình schroot." + +#: dchroot/dchroot-main.cc:128 dchroot-dsa/dchroot-dsa-main.cc:120 +#, boost-format +msgid "Edit '%1%' to add appropriate group access." +msgstr "Hiệu chỉnh « %1% » để thêm cách truy cập nhóm thích hợp." + +#: dchroot/dchroot-options.cc:56 +msgid "Print path to selected chroot" +msgstr "In ra đường dẫn đến chroot đã chọn" + +#: dchroot/dchroot-options.cc:60 dchroot-dsa/dchroot-dsa-options.cc:60 +#: schroot/schroot-options.cc:62 +msgid "Select all chroots" +msgstr "Chọn mọi chroot" + +#: dchroot/dchroot-options.cc:64 schroot/schroot-options.cc:70 +msgid "Preserve user environment" +msgstr "Bảo tồn môi trường người dùng" + +#: dchroot/dchroot-options.cc:73 dchroot-dsa/dchroot-dsa-options.cc:69 +#: schroot/schroot-listmounts-options.cc:64 schroot/schroot-options.cc:92 +#: schroot/schroot-releaselock-options.cc:67 +msgid "Usage:" +msgstr "Cách sử dụng:" + +#: dchroot/dchroot-options.cc:76 schroot/schroot-options.cc:95 +#, fuzzy +msgid "[OPTION...] [COMMAND] - run command or shell in a chroot" +msgstr " [TÙY_CHỌN...] [LỆNH] — chạy lệnh hoặc hệ vỏ trong một chroot" + +#: dchroot/dchroot-options.cc:99 dchroot-dsa/dchroot-dsa-options.cc:102 +#, fuzzy +msgid "Only one command may be specified" +msgstr "Có thể ghi rõ chỉ một hành động thôi" + +#: dchroot/dchroot-options.cc:104 schroot/schroot-options-base.cc:157 +msgid "--quiet and --verbose may not be used at the same time" +msgstr "" +"Không cho phép sử dụng tùy chọn cả « --quiet » (xuất ít hơn) lẫn « --verbose " +"» (xuất nhiều hơn) đều đồng thời." + +#: dchroot/dchroot-options.cc:106 schroot/schroot-options-base.cc:159 +msgid "Using verbose output" +msgstr "Đang xuất nhiều hơn" + +#: dchroot/dchroot-options.cc:112 schroot/schroot-options-base.cc:165 +msgid "--chroot and --all may not be used at the same time" +msgstr "" +"Không cho phép sử dụng tùy chọn cả « --chroot » lẫn « --all » (tất cả) đều " +"đồng thời." + +#: dchroot/dchroot-options.cc:114 schroot/schroot-options-base.cc:167 +msgid "Using --chroots only" +msgstr "Đang dùng chỉ tùy chọn « --chroots » thôi" + +#: dchroot/dchroot-session-base.cc:76 +#, boost-format +msgid "(%1%->%2%): dchroot sessions do not support user switching" +msgstr "" +"(%1% → %2%): phiên chạy dchroot không hỗ trợ khả năng chuyển đổi người dùng." + +#: dchroot/dchroot-session-base.cc:78 +#, fuzzy +msgid "dchroot session restriction" +msgstr "Chọn chroot" + +#: dchroot/dchroot-session.cc:116 dchroot-dsa/dchroot-dsa-session.cc:132 +#, boost-format msgid "[%1% chroot] Running command: \"%2%\"" msgstr "[%1% chroot] Đang chạy lệnh: « %2% »" -#: schroot/sbuild-auth.cc:52 +#: dchroot-dsa/dchroot-dsa-chroot-config.cc:110 +#, fuzzy, boost-format +msgid "%1% chroot (dchroot-dsa compatibility)" +msgstr "Đang chạy schroot trong chế độ tương thích" + +#: dchroot-dsa/dchroot-dsa-options.cc:56 +#, fuzzy +msgid "Print paths to available chroots" +msgstr "Liệt kê các chroot sẵn sàng" + +#: dchroot-dsa/dchroot-dsa-options.cc:72 +#, fuzzy +msgid "[OPTION...] chroot [COMMAND] - run command or shell in a chroot" +msgstr " [TÙY_CHỌN...] [LỆNH] — chạy lệnh hoặc hệ vỏ trong một chroot" + +#: dchroot-dsa/dchroot-dsa-session.cc:116 +#, boost-format +msgid "%1%: Command must have an absolute path" +msgstr "" + +#: sbuild/sbuild-auth.cc:53 #, fuzzy msgid "Failed to get hostname" msgstr "Việc lấy tên máy bị lỗi: %1%" -#: schroot/sbuild-auth.cc:53 +#: sbuild/sbuild-auth.cc:54 #, fuzzy msgid "User not found" msgstr "%1%: không tìm thấy người dùng: %2%" -#: schroot/sbuild-auth.cc:54 +#: sbuild/sbuild-auth.cc:55 #, fuzzy msgid "Access not authorised" msgstr "không xác thực truy cập" -#: schroot/sbuild-auth.cc:55 +#: sbuild/sbuild-auth.cc:56 #, fuzzy msgid "Authentication failed" msgstr "Việc xác thực kiểu PAM bị lỗi: %1%" -#: schroot/sbuild-auth.cc:56 +#: sbuild/sbuild-auth.cc:57 #, fuzzy msgid "PAM is already initialised" msgstr "Lỗi PAM: PAM đã được sở khởi" -#: schroot/sbuild-auth.cc:57 +#: sbuild/sbuild-auth.cc:58 #, fuzzy msgid "PAM error" msgstr "Lỗi PAM: %1%" -#: schroot/sbuild-auth.cc:420 +#: sbuild/sbuild-auth.cc:421 msgid "Set RUSER" msgstr "" -#: schroot/sbuild-auth.cc:436 +#: sbuild/sbuild-auth.cc:437 msgid "Set RHOST" msgstr "" -#: schroot/sbuild-auth.cc:449 +#: sbuild/sbuild-auth.cc:450 msgid "Set TTY" msgstr "" -#: schroot/sbuild-auth.cc:461 +#: sbuild/sbuild-auth.cc:462 msgid "Set USER" msgstr "" -#: schroot/sbuild-auth.cc:479 +#: sbuild/sbuild-auth.cc:480 +#, boost-format msgid "You do not have permission to access the %1% service." msgstr "Bạn không có quyền truy cập dịch vụ %1%." -#: schroot/sbuild-auth.cc:482 +#: sbuild/sbuild-auth.cc:483 msgid "This failure will be reported." msgstr "Sự thất bại này sẽ được thông báo." -#: schroot/sbuild-auth-conv-tty.cc:47 +#: sbuild/sbuild-auth-conv-tty.cc:48 msgid "Timed out" msgstr "Quá giờ" -#: schroot/sbuild-auth-conv-tty.cc:48 +#: sbuild/sbuild-auth-conv-tty.cc:49 msgid "Time is running out..." msgstr "Gần thời hạn..." -#: schroot/sbuild-auth-conv-tty.cc:49 +#: sbuild/sbuild-auth-conv-tty.cc:50 msgid "Failed to get terminal settings" msgstr "Việc lấy thiết lập thiết bị cuối bị lỗi" -#: schroot/sbuild-auth-conv-tty.cc:50 +#: sbuild/sbuild-auth-conv-tty.cc:51 #, fuzzy msgid "Unsupported conversation type" msgstr "Kiểu chuyển đổi không được hỗ trợ %1%" -#: schroot/sbuild-chroot-block-device.cc:176 +#: sbuild/sbuild-chroot-block-device.cc:179 msgid "Device" msgstr "Thiết bị" -#: schroot/sbuild-chroot-block-device.cc:178 +#: sbuild/sbuild-chroot-block-device.cc:181 msgid "Mount Options" msgstr "Tùy chọn lắp" -#: schroot/sbuild-chroot.cc:47 +#: sbuild/sbuild-chroot.cc:58 #, fuzzy msgid "Unknown chroot type" msgstr "không biết kiểu chroot « %1% »" -#: schroot/sbuild-chroot.cc:48 +#: sbuild/sbuild-chroot.cc:59 #, fuzzy msgid "Chroot creation failed" msgstr "việc tạo chroot bị lỗi" -#: schroot/sbuild-chroot.cc:49 +#: sbuild/sbuild-chroot.cc:60 #, fuzzy msgid "Device name not set" msgstr "%1% chroot: chưa lập tên thiết bị" -#: schroot/sbuild-chroot.cc:50 +#: sbuild/sbuild-chroot.cc:61 #, fuzzy msgid "Failed to write session file" msgstr "%1%: việc tạo tập tin phiên chạy bị lỗi: %2%\n" -#: schroot/sbuild-chroot.cc:51 +#: sbuild/sbuild-chroot.cc:62 #, fuzzy msgid "Failed to unlink session file" msgstr "%1%: việc bỏ liên kết tập tin phiên chạy bị lỗi: %2%\n" -#: schroot/sbuild-chroot.cc:52 schroot/sbuild-chroot-config.cc:56 +#: sbuild/sbuild-chroot.cc:63 sbuild/sbuild-chroot-config.cc:58 #, fuzzy msgid "Failed to stat file" msgstr "việc lấy các thông tin về tập tin bị lỗi: %1%" -#: schroot/sbuild-chroot.cc:53 schroot/sbuild-chroot-config.cc:58 +#: sbuild/sbuild-chroot.cc:64 sbuild/sbuild-chroot-config.cc:60 #, fuzzy msgid "File is not owned by user root" msgstr "người dùng chủ không sở hữu" -#: schroot/sbuild-chroot.cc:54 schroot/sbuild-chroot-config.cc:59 +#: sbuild/sbuild-chroot.cc:65 sbuild/sbuild-chroot-config.cc:61 #, fuzzy msgid "File has write permissions for others" msgstr "người khác có quyền ghi" -#: schroot/sbuild-chroot.cc:55 schroot/sbuild-chroot-config.cc:60 +#: sbuild/sbuild-chroot.cc:66 sbuild/sbuild-chroot-config.cc:62 #, fuzzy msgid "File is not a regular file" msgstr "không phải là tập tin chuẩn" -#: schroot/sbuild-chroot.cc:56 +#: sbuild/sbuild-chroot.cc:67 #, fuzzy msgid "Failed to acquire file lock" msgstr "không lấy khoá thiết bị được" -#: schroot/sbuild-chroot.cc:57 +#: sbuild/sbuild-chroot.cc:68 #, fuzzy msgid "Failed to discard file lock" msgstr "không kiểm tra khoá thiết bị được" -#: schroot/sbuild-chroot.cc:58 +#: sbuild/sbuild-chroot.cc:69 #, fuzzy msgid "Failed to stat device" msgstr "Việc lấy các thông tin về thiết bị %1% bị lỗi: %2%" -#: schroot/sbuild-chroot.cc:59 +#: sbuild/sbuild-chroot.cc:70 #, fuzzy msgid "File is not a block device" msgstr "%1% không phải là thiết bị khối" -#: schroot/sbuild-chroot.cc:60 +#: sbuild/sbuild-chroot.cc:71 #, fuzzy msgid "Failed to lock device" msgstr "%1%: không khoá thiết bị được: %2%" -#: schroot/sbuild-chroot.cc:61 +#: sbuild/sbuild-chroot.cc:72 #, fuzzy msgid "Failed to unlock device" msgstr "%1%: không mở khoá thiết bị được: %2%" -#: schroot/sbuild-chroot.cc:403 +#: sbuild/sbuild-chroot.cc:414 #, fuzzy msgid "--- Session ---\n" msgstr " ━━━Phiên chạy ━━━\n" -#: schroot/sbuild-chroot.cc:405 +#: sbuild/sbuild-chroot.cc:416 #, fuzzy msgid "--- Chroot ---\n" msgstr " ━━━ Chroot ━━━\n" -#: schroot/sbuild-chroot.cc:406 +#: sbuild/sbuild-chroot.cc:417 msgid "Name" msgstr "Tên" -#: schroot/sbuild-chroot.cc:407 +#: sbuild/sbuild-chroot.cc:418 msgid "Description" msgstr "Mô tả" -#: schroot/sbuild-chroot.cc:408 +#: sbuild/sbuild-chroot.cc:419 msgid "Type" msgstr "Kiểu" -#: schroot/sbuild-chroot.cc:409 +#: sbuild/sbuild-chroot.cc:420 msgid "Priority" msgstr "Ưu tiên" -#: schroot/sbuild-chroot.cc:410 +#: sbuild/sbuild-chroot.cc:421 msgid "Users" msgstr "" -#: schroot/sbuild-chroot.cc:411 +#: sbuild/sbuild-chroot.cc:422 msgid "Groups" msgstr "Nhóm" -#: schroot/sbuild-chroot.cc:412 +#: sbuild/sbuild-chroot.cc:423 #, fuzzy msgid "Root Users" msgstr "Nhóm chủ" -#: schroot/sbuild-chroot.cc:413 +#: sbuild/sbuild-chroot.cc:424 msgid "Root Groups" msgstr "Nhóm chủ" -#: schroot/sbuild-chroot.cc:414 +#: sbuild/sbuild-chroot.cc:425 msgid "Aliases" msgstr "Biệt hiệu" -#: schroot/sbuild-chroot.cc:415 +#: sbuild/sbuild-chroot.cc:426 msgid "Run Setup Scripts" msgstr "Chạy các tập lệnh thiết lập" -#: schroot/sbuild-chroot.cc:416 +#: sbuild/sbuild-chroot.cc:427 msgid "Run Execution Scripts" msgstr "Chạy các tập lệnh thực hiện" -#: schroot/sbuild-chroot.cc:418 +#: sbuild/sbuild-chroot.cc:429 msgid "Session Managed" msgstr "Phiên chạy đã quản lý" -#: schroot/sbuild-chroot.cc:423 +#: sbuild/sbuild-chroot.cc:434 msgid "Command Prefix" msgstr "Tiền tố lệnh" -#: schroot/sbuild-chroot.cc:425 +#: sbuild/sbuild-chroot.cc:436 msgid "Personality" msgstr "Cá tính" -#: schroot/sbuild-chroot.cc:429 +#: sbuild/sbuild-chroot.cc:440 msgid "Location" msgstr "Địa điểm" -#: schroot/sbuild-chroot.cc:432 +#: sbuild/sbuild-chroot.cc:443 msgid "Mount Location" msgstr "Địa điểm lắp" -#: schroot/sbuild-chroot.cc:435 +#: sbuild/sbuild-chroot.cc:446 msgid "Path" msgstr "Đường dẫn" -#: schroot/sbuild-chroot.cc:438 +#: sbuild/sbuild-chroot.cc:449 msgid "Mount Device" msgstr "Thiết bị lắp" -#: schroot/sbuild-chroot.cc:597 +#: sbuild/sbuild-chroot.cc:608 +#, boost-format msgid "%1% chroot: personality \"%2%\" is unknown.\n" msgstr "%1% chroot: không biết cá tính « %2% ».\n" -#: schroot/sbuild-chroot.cc:600 +#: sbuild/sbuild-chroot.cc:611 +#, boost-format msgid "Valid personalities: %1%\n" msgstr "Cá tính hợp lệ: %1%\n" -#: schroot/sbuild-chroot-config.cc:55 +#: sbuild/sbuild-chroot-config.cc:57 #, fuzzy msgid "Failed to open directory" msgstr "%1%: việc mở thư mục bị lỗi: %2%" -#: schroot/sbuild-chroot-config.cc:57 +#: sbuild/sbuild-chroot-config.cc:59 #, fuzzy msgid "Failed to open file" msgstr "không thể mở tập tin" -#: schroot/sbuild-chroot-config.cc:180 -#, fuzzy +#: sbuild/sbuild-chroot-config.cc:182 +#, fuzzy, boost-format msgid "%1% chroot: Alias '%2%' already associated with '%3%' chroot" msgstr "%1% chroot: biệt hiệu %2% đã tương ứng với chroot %3%" -#: schroot/sbuild-chroot-config.cc:188 -#, fuzzy +#: sbuild/sbuild-chroot-config.cc:190 +#, fuzzy, boost-format msgid "%1% chroot: Alias '%2%' already associated with another chroot" msgstr "%1% chroot: biệt hiệu %2% đã tương ứng với chroot khác" -#: schroot/sbuild-chroot-config.cc:198 -#, fuzzy +#: sbuild/sbuild-chroot-config.cc:200 +#, fuzzy, boost-format msgid "%1% chroot: A chroot or alias already exists by this name" msgstr "%1% chroot: một chroot hay biệt hiệu tên này đã có" -#: schroot/sbuild-chroot-config.cc:201 -#, fuzzy +#: sbuild/sbuild-chroot-config.cc:203 +#, fuzzy, boost-format msgid "%1% chroot: Duplicate names are not allowed" msgstr "%1% chroot: không cho phép tên trùng" -#: schroot/sbuild-chroot-config.cc:280 +#: sbuild/sbuild-chroot-config.cc:282 msgid "Available chroots: " msgstr "Các chroot sẵn sàng: " -#: schroot/sbuild-chroot-config.cc:325 schroot/sbuild-chroot-config.cc:344 -#: schroot/sbuild-chroot-config.cc:367 +#: sbuild/sbuild-chroot-config.cc:327 sbuild/sbuild-chroot-config.cc:346 +#: sbuild/sbuild-chroot-config.cc:369 schroot/schroot-main.cc:138 +#, boost-format msgid "%1%: No such chroot" msgstr "%1%: Không có chroot như vậy" -#: schroot/sbuild-chroot-file.cc:143 +#: sbuild/sbuild-chroot-file.cc:146 msgid "File" msgstr "Tập tin" -#: schroot/sbuild-chroot-file.cc:144 +#: sbuild/sbuild-chroot-file.cc:147 msgid "File Repack" msgstr "Nén lại tập tin" -#: schroot/sbuild-chroot-lvm-snapshot.cc:201 +#: sbuild/sbuild-chroot-lvm-snapshot.cc:203 msgid "LVM Snapshot Device" msgstr "Thiết bị hiện trạng Bộ Quản lý Khối tin Hợp lý" -#: schroot/sbuild-chroot-lvm-snapshot.cc:204 +#: sbuild/sbuild-chroot-lvm-snapshot.cc:206 msgid "LVM Snapshot Options" msgstr "Tùy chọn hiện trạng Bộ Quản lý Khối tin Hợp lý" -#: schroot/sbuild-chroot-source.cc:45 +#: sbuild/sbuild-chroot-source.cc:47 #, fuzzy msgid "(source chroot)" msgstr " (chroot nguồn)" -#: schroot/sbuild-chroot-source.cc:115 +#: sbuild/sbuild-chroot-source.cc:117 #, fuzzy msgid "Source Users" msgstr "Nhóm nguồn" -#: schroot/sbuild-chroot-source.cc:116 +#: sbuild/sbuild-chroot-source.cc:118 msgid "Source Groups" msgstr "Nhóm nguồn" -#: schroot/sbuild-chroot-source.cc:117 +#: sbuild/sbuild-chroot-source.cc:119 #, fuzzy msgid "Source Root Users" msgstr "Nhóm chủ nguồn" -#: schroot/sbuild-chroot-source.cc:118 +#: sbuild/sbuild-chroot-source.cc:120 msgid "Source Root Groups" msgstr "Nhóm chủ nguồn" -#: schroot/sbuild-format-detail.cc:34 +#: sbuild/sbuild-format-detail.cc:34 msgid "true" msgstr "đúng" -#: schroot/sbuild-format-detail.cc:36 +#: sbuild/sbuild-format-detail.cc:36 msgid "false" msgstr "sai" -#: schroot/sbuild-keyfile.cc:363 +#: sbuild/sbuild-keyfile.cc:363 +#, boost-format msgid "%1% chroot: A deprecated parameter \"%2%\" has been specified." msgstr "%1% chroot: một tham số bị phản đối « %2% » đã được ghi rõ." -#: schroot/sbuild-keyfile.cc:367 +#: sbuild/sbuild-keyfile.cc:367 msgid "This option will be removed in the future." msgstr "Tùy chọn này sẽ bị gỡ bỏ trong tương lai." -#: schroot/sbuild-keyfile.cc:371 +#: sbuild/sbuild-keyfile.cc:371 +#, boost-format msgid "%1% chroot: An obsolete parameter \"%2%\" has been specified." msgstr "%1% chroot: một tham số cũ « %2% » đã được ghi rõ." -#: schroot/sbuild-keyfile.cc:375 +#: sbuild/sbuild-keyfile.cc:375 msgid "This option has been removed, and no longer has any effect." msgstr "Tùy chọn này đã bị gỡ bỏ nên không còn có tác động nào lại." -#: schroot/sbuild-lock.cc:48 +#: sbuild/sbuild-lock.cc:49 #, fuzzy msgid "Failed to set timeout handler" msgstr "việc lập bộ quản lý thời hạn bị lỗi: %1%" -#: schroot/sbuild-lock.cc:49 +#: sbuild/sbuild-lock.cc:50 #, fuzzy msgid "Failed to set timeout" msgstr "việc lập thời hạn bị lỗi: %1%" -#: schroot/sbuild-lock.cc:50 +#: sbuild/sbuild-lock.cc:51 #, fuzzy msgid "Failed to cancel timeout" msgstr "việc bỏ lập thời hạn bị lỗi: %1%" -#: schroot/sbuild-lock.cc:51 +#: sbuild/sbuild-lock.cc:52 #, fuzzy msgid "Failed to acquire lock (timed out)" msgstr "việc lấy khoá bị lỗi (quá thời sau %1% giây)" -#: schroot/sbuild-lock.cc:52 +#: sbuild/sbuild-lock.cc:53 #, fuzzy msgid "Failed to acquire lock" msgstr "việc lấy khoá bị lỗi: %1%" -#: schroot/sbuild-lock.cc:53 +#: sbuild/sbuild-lock.cc:54 #, fuzzy msgid "Failed to acquire device lock" msgstr "không lấy khoá thiết bị được" -#: schroot/sbuild-lock.cc:54 +#: sbuild/sbuild-lock.cc:55 #, fuzzy msgid "Failed to acquire device lock (timed out)" msgstr "không lấy khoá thiết bị được" -#: schroot/sbuild-lock.cc:55 +#: sbuild/sbuild-lock.cc:56 #, fuzzy msgid "Failed to test device lock" msgstr "không kiểm tra khoá thiết bị được" -#: schroot/sbuild-lock.cc:56 +#: sbuild/sbuild-lock.cc:57 #, fuzzy msgid "Failed to release device lock" msgstr "không nhả khoá thiết bị được" -#: schroot/sbuild-lock.cc:57 +#: sbuild/sbuild-lock.cc:58 #, fuzzy msgid "Failed to release device lock (timed out)" msgstr "không nhả khoá thiết bị được" -#: schroot/sbuild-lock.cc:274 +#: sbuild/sbuild-lock.cc:275 +#, boost-format msgid "lock held by pid %1%" msgstr "" -#: schroot/sbuild-parse-error.cc:41 +#: sbuild/sbuild-parse-error.cc:41 #, fuzzy msgid "No error" msgstr "không có lỗi" -#: schroot/sbuild-parse-error.cc:42 +#: sbuild/sbuild-parse-error.cc:42 #, fuzzy msgid "Can't open file" msgstr "không thể mở tập tin" -#: schroot/sbuild-parse-error.cc:43 +#: sbuild/sbuild-parse-error.cc:43 #, fuzzy msgid "Could not parse value" msgstr "không thể phân tách giá trị" -#: schroot/sbuild-parse-error.cc:44 +#: sbuild/sbuild-parse-error.cc:44 #, fuzzy msgid "Invalid line" msgstr "dòng không hợp lệ" -#: schroot/sbuild-parse-error.cc:45 +#: sbuild/sbuild-parse-error.cc:45 #, fuzzy msgid "No group specified" msgstr "chưa xác định nhóm" -#: schroot/sbuild-parse-error.cc:46 +#: sbuild/sbuild-parse-error.cc:46 #, fuzzy msgid "Invalid group" msgstr "nhóm không hợp lệ" -#: schroot/sbuild-parse-error.cc:47 +#: sbuild/sbuild-parse-error.cc:47 #, fuzzy msgid "Duplicate group" msgstr "nhóm trùng" -#: schroot/sbuild-parse-error.cc:48 +#: sbuild/sbuild-parse-error.cc:48 #, fuzzy msgid "No key specified" msgstr "chưa xác định khoá" -#: schroot/sbuild-parse-error.cc:49 +#: sbuild/sbuild-parse-error.cc:49 #, fuzzy msgid "Duplicate key" msgstr "khoá trùng" -#: schroot/sbuild-parse-error.cc:50 +#: sbuild/sbuild-parse-error.cc:50 #, fuzzy msgid "Required key is missing" msgstr "thiếu khoá cần thiết" -#: schroot/sbuild-parse-error.cc:51 +#: sbuild/sbuild-parse-error.cc:51 #, fuzzy msgid "Disallowed key used" msgstr "dùng khoá bị cấm" -#: schroot/sbuild-parse-error.cc:116 +#: sbuild/sbuild-parse-error.cc:116 #, fuzzy msgid "Unknown error" msgstr "lỗi không rõ" -#: schroot/sbuild-parse-error.cc:127 +#: sbuild/sbuild-parse-error.cc:127 +#, boost-format msgid "%1% \"%2%\"" msgstr "%1% \"%2%\"" -#: schroot/sbuild-parse-error.cc:143 +#: sbuild/sbuild-parse-error.cc:143 +#, boost-format msgid "line %1%: %3%" msgstr "dòng %1%: %3%" -#: schroot/sbuild-parse-error.cc:144 +#: sbuild/sbuild-parse-error.cc:144 +#, boost-format msgid "line %1%: %2% \"%3%\"" msgstr "dòng %1%: %2% \"%3%\"" -#: schroot/sbuild-parse-error.cc:150 +#: sbuild/sbuild-parse-error.cc:150 +#, boost-format msgid "line %1%: %2%" msgstr "dòng %1%: %2%" -#: schroot/sbuild-parse-error.cc:165 +#: sbuild/sbuild-parse-error.cc:165 +#, boost-format msgid "line %1% [%2%]: %4%" msgstr "dòng %1% [%2%]: %4%" -#: schroot/sbuild-parse-error.cc:166 +#: sbuild/sbuild-parse-error.cc:166 +#, boost-format msgid "line %1% [%2%]: %3% \"%4%\"" msgstr "dòng %1% [%2%]: %3% \"%4%\"" -#: schroot/sbuild-parse-error.cc:172 +#: sbuild/sbuild-parse-error.cc:172 +#, boost-format msgid "line %1% [%2%]: %3%" msgstr "dòng %1% [%2%]: %3%" -#: schroot/sbuild-parse-error.cc:188 +#: sbuild/sbuild-parse-error.cc:188 +#, boost-format msgid "line %1% [%2%] %3%: %5%" msgstr "dòng %1% [%2%] %3%: %5%" -#: schroot/sbuild-parse-error.cc:189 +#: sbuild/sbuild-parse-error.cc:189 +#, boost-format msgid "line %1% [%2%] %3%: %4% \"%5%\"" msgstr "dòng %1% [%2%] %3%: %4% \"%5%\"" -#: schroot/sbuild-parse-error.cc:195 +#: sbuild/sbuild-parse-error.cc:195 +#, boost-format msgid "line %1% [%2%] %3%: %4%" msgstr "dòng %1% [%2%] %3%: %4%" -#: schroot/sbuild-parse-error.cc:209 +#: sbuild/sbuild-parse-error.cc:209 +#, boost-format msgid "[%1%]: %3%" msgstr "[%1%]: %3%" -#: schroot/sbuild-parse-error.cc:210 +#: sbuild/sbuild-parse-error.cc:210 +#, boost-format msgid "[%1%]: %2% \"%3%\"" msgstr "[%1%]: %2% \"%3%\"" -#: schroot/sbuild-parse-error.cc:216 +#: sbuild/sbuild-parse-error.cc:216 +#, boost-format msgid "[%1%]: %2%" msgstr "[%1%]: %2%" -#: schroot/sbuild-parse-error.cc:231 +#: sbuild/sbuild-parse-error.cc:231 +#, boost-format msgid "[%1%] %2%: %4%" msgstr "[%1%] %2%: %4%" -#: schroot/sbuild-parse-error.cc:232 +#: sbuild/sbuild-parse-error.cc:232 +#, boost-format msgid "[%1%] %2%: %3% \"%4%\"" msgstr "[%1%] %2%: %3% \"%4%\"" -#: schroot/sbuild-parse-error.cc:238 +#: sbuild/sbuild-parse-error.cc:238 +#, boost-format msgid "[%1%] %2%: %3%" msgstr "[%1%] %2%: %3%" -#: schroot/sbuild-personality.cc:48 +#: sbuild/sbuild-personality.cc:48 #, fuzzy msgid "Failed to set personality" msgstr "Việc lấy thiết lập thiết bị cuối bị lỗi" -#: schroot/sbuild-session.cc:57 +#: sbuild/sbuild-session.cc:59 #, fuzzy msgid "Failed to find chroot" msgstr "%1%: việc tìm chroot bị lỗi" -#: schroot/sbuild-session.cc:58 +#: sbuild/sbuild-session.cc:60 #, fuzzy msgid "Failed to lock chroot" msgstr "%1%: việc tìm chroot bị lỗi" -#: schroot/sbuild-session.cc:59 +#: sbuild/sbuild-session.cc:61 #, fuzzy msgid "Failed to unlock chroot" msgstr "%1%: việc tìm chroot bị lỗi" -#: schroot/sbuild-session.cc:60 +#: sbuild/sbuild-session.cc:62 #, fuzzy msgid "Chroot setup failed" msgstr "việc tạo chroot bị lỗi" -#: schroot/sbuild-session.cc:61 +#: sbuild/sbuild-session.cc:63 #, fuzzy msgid "Failed to set hangup signal handler" msgstr "lỗi lập bộ quản lý ngừng nói : %1%" -#: schroot/sbuild-session.cc:62 +#: sbuild/sbuild-session.cc:64 #, fuzzy msgid "Caught hangup signal" msgstr "mới bắt tín hiệu ngừng nói nên kết thúc..." -#: schroot/sbuild-session.cc:63 +#: sbuild/sbuild-session.cc:65 #, fuzzy msgid "Failed to fork child" msgstr "Việc tạo tiến trình con của điều con bị lỗi: %1%" -#: schroot/sbuild-session.cc:64 +#: sbuild/sbuild-session.cc:66 #, fuzzy msgid "Wait for child failed" msgstr "việc đợi tiến trình con bị lỗi: %1%" -#: schroot/sbuild-session.cc:65 +#: sbuild/sbuild-session.cc:67 #, fuzzy msgid "Child terminated by signal" msgstr "Tiến trình con bị chấm dứt do tín hiệu « %1% »" -#: schroot/sbuild-session.cc:66 +#: sbuild/sbuild-session.cc:68 msgid "Child dumped core" msgstr "Tiến trình con đã đổ lõi" -#: schroot/sbuild-session.cc:67 +#: sbuild/sbuild-session.cc:69 msgid "Child exited abnormally (reason unknown; not a signal or core dump)" msgstr "" "Tiến trình con đã thoát bất thường (chưa biết sao ; không phải là việc đổ " "tín hiệu hay lõi)" -#: schroot/sbuild-session.cc:68 +#: sbuild/sbuild-session.cc:70 msgid "User switching is not permitted" msgstr "" -#: schroot/sbuild-session.cc:106 -#, fuzzy +#: sbuild/sbuild-session.cc:108 +#, fuzzy, boost-format msgid "%1%: Group not found" msgstr "%1%: không tìm thấy nhóm" -#: schroot/sbuild-session.cc:108 -#, fuzzy +#: sbuild/sbuild-session.cc:110 +#, fuzzy, boost-format msgid "%1%: Group not found: %2%" msgstr "%1%: không tìm thấy nhóm: %2%" -#: schroot/sbuild-session.cc:124 -#, fuzzy +#: sbuild/sbuild-session.cc:126 +#, fuzzy, boost-format msgid "Can't get supplementary group count: %1%" msgstr "không thể lấy số đếm nhóm phụ : %1%" -#: schroot/sbuild-session.cc:134 -#, fuzzy +#: sbuild/sbuild-session.cc:136 +#, fuzzy, boost-format msgid "Can't get supplementary groups: %1%" msgstr "không thể lấy các nhóm phụ : %1%" -#: schroot/sbuild-session.cc:364 +#: sbuild/sbuild-session.cc:366 +#, boost-format msgid "No chroot found matching alias '%1%'" msgstr "Không tìm thấy chroot khớp với biệt hiệu « %1% »" -#: schroot/sbuild-session.cc:571 -#, fuzzy +#: sbuild/sbuild-session.cc:573 +#, fuzzy, boost-format msgid "%1%: Shell not available: %2%" msgstr "%1%: việc lấy các thông tin về tập tin bị lỗi: %2%" -#: schroot/sbuild-session.cc:574 -#, fuzzy +#: sbuild/sbuild-session.cc:576 +#, fuzzy, boost-format msgid "Falling back to %1%" msgstr "Đang dự trữ về « %1 »" -#: schroot/sbuild-session.cc:640 -#, fuzzy +#: sbuild/sbuild-session.cc:642 +#, fuzzy, boost-format msgid "[%1% chroot] Running login shell: \"%4%\"" msgstr "[%1% chroot] Đang chạy hệ vỏ đăng nhập: « %2% »" -#: schroot/sbuild-session.cc:642 -#, fuzzy +#: sbuild/sbuild-session.cc:644 +#, fuzzy, boost-format msgid "[%1% chroot] Running shell: \"%4%\"" msgstr "[%1% chroot] Đang chạy hệ vỏ đăng nhập: « %2% »" -#: schroot/sbuild-session.cc:648 +#: sbuild/sbuild-session.cc:650 +#, boost-format msgid "[%1% chroot] (%2%->%3%) Running login shell: \"%4%\"" msgstr "[%1% chroot] (%2%->%3%) Đang chạy hệ vỏ đăng nhập: « %4% »" -#: schroot/sbuild-session.cc:650 +#: sbuild/sbuild-session.cc:652 +#, boost-format msgid "[%1% chroot] (%2%->%3%) Running shell: \"%4%\"" msgstr "[%1% chroot] (%2%->%3%) Đang chạy hệ vỏ đăng nhập: « %4% »" -#: schroot/sbuild-session.cc:685 -#, fuzzy +#: sbuild/sbuild-session.cc:687 +#, fuzzy, boost-format msgid "[%1% chroot] Running command: \"%4%\"" msgstr "[%1% chroot] Đang chạy lệnh: « %2% »" -#: schroot/sbuild-session.cc:687 +#: sbuild/sbuild-session.cc:689 +#, boost-format msgid "[%1% chroot] (%2%->%3%) Running command: \"%4%\"" msgstr "[%1% chroot] (%2%->%3%) Đang chạy lệnh: « %4% »" -#: schroot/sbuild-session.cc:809 +#: sbuild/sbuild-session.cc:811 +#, boost-format msgid "Invalid verbosity level: %1%, falling back to \"normal\"" msgstr "Cấp chi tiết không hợp lệ: %1%, nên dùng « normal » (chuẩn)" -#: schroot/sbuild-session.cc:845 schroot/sbuild-session.cc:1020 +#: sbuild/sbuild-session.cc:847 sbuild/sbuild-session.cc:1022 +#, boost-format msgid "Could not exec \"%1%\": %2%" msgstr "Không thể thực hiện « %1% »: %2%" -#: schroot/sbuild-session.cc:871 +#: sbuild/sbuild-session.cc:873 +#, boost-format msgid "stage=%1%" msgstr "" -#: schroot/sbuild-session.cc:900 +#: sbuild/sbuild-session.cc:902 +#, boost-format msgid "PAM error: %1%" msgstr "Lỗi PAM: %1%" -#: schroot/sbuild-session.cc:908 +#: sbuild/sbuild-session.cc:910 +#, boost-format msgid "Could not set gid to '%1%'" msgstr "Không thể lập GID thành « %1% »" -#: schroot/sbuild-session.cc:914 +#: sbuild/sbuild-session.cc:916 msgid "Could not set supplementary group IDs" msgstr "Không thể lập các ID nhóm phụ" -#: schroot/sbuild-session.cc:932 schroot/sbuild-session.cc:980 +#: sbuild/sbuild-session.cc:934 sbuild/sbuild-session.cc:982 +#, boost-format msgid "Could not chdir to '%1%': %2%" msgstr "Không thể chdir (chuyển đổi thư mục) sang « %1% »: %2%" -#: schroot/sbuild-session.cc:939 +#: sbuild/sbuild-session.cc:941 +#, boost-format msgid "Could not chroot to '%1%': %2%" msgstr "Không thể chroot tới « %1% »: %2%" -#: schroot/sbuild-session.cc:948 +#: sbuild/sbuild-session.cc:950 +#, boost-format msgid "Could not set uid to '%1%'" msgstr "Không thể lập UID thành « %1% »" -#: schroot/sbuild-session.cc:954 +#: sbuild/sbuild-session.cc:956 msgid "Failed to drop root permissions." msgstr "Việc bỏ quyền chủ bị lỗi." -#: schroot/sbuild-session.cc:987 +#: sbuild/sbuild-session.cc:989 +#, fuzzy, boost-format msgid "Falling back to '%1%'" msgstr "Đang dự trữ về « %1 »" -#: schroot/sbuild-session.cc:1042 +#: sbuild/sbuild-session.cc:1044 #, fuzzy msgid "Caught hangup signal, terminating..." msgstr "mới bắt tín hiệu ngừng nói nên kết thúc..." -#: schroot/schroot.cc:68 -#, fuzzy -msgid "An unknown exception occured" -msgstr "Đã ghi rõ một hành động không rõ" - -# Literal: don't translate / Nghĩa chữ: đừng dịch -#: schroot/schroot-listmounts.cc:57 -msgid "schroot-listmounts (Debian sbuild) %1%\n" -msgstr "schroot-listmounts (Debian sbuild) %1%\n" +#: schroot/schroot-listmounts.cc:61 schroot/schroot-main.cc:58 +#: schroot/schroot-releaselock.cc:56 +#, fuzzy, boost-format +msgid "%1% (Debian sbuild) %2% (%3%)\n" +msgstr "%1% (Debian sbuild) %2%\n" -#: schroot/schroot-listmounts.cc:58 schroot/schroot-releaselock.cc:55 +#: schroot/schroot-listmounts.cc:65 schroot/schroot-main.cc:62 +#: schroot/schroot-releaselock.cc:60 msgid "" "Written by Roger Leigh\n" "\n" @@ -742,11 +917,13 @@ msgstr "" "Do Roger Leigh tạo\n" "\n" -#: schroot/schroot-listmounts.cc:59 schroot/schroot-releaselock.cc:56 +#: schroot/schroot-listmounts.cc:66 schroot/schroot-main.cc:63 +#: schroot/schroot-releaselock.cc:61 msgid "Copyright (C) 2004-2006 Roger Leigh\n" msgstr "Bản quyền © năm 2004-2006 Roger Leigh\n" -#: schroot/schroot-listmounts.cc:60 schroot/schroot-releaselock.cc:57 +#: schroot/schroot-listmounts.cc:67 schroot/schroot-main.cc:64 +#: schroot/schroot-releaselock.cc:62 msgid "" "This is free software; see the source for copying conditions. There is NO\n" "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" @@ -754,151 +931,233 @@ msgstr "" "Đây là phần mềm tự do; hãy xem mã nguồn để tìm thấy điều kiện sao chép.\n" "• Không bảo đảm gì cả, dù khă nang bán hay khả năng làm việc dứt khoát. •\n" -#: schroot/schroot-listmounts.cc:82 +#: schroot/schroot-listmounts.cc:89 +#, boost-format msgid "%1%: Failed to open: %2%" msgstr "%1%: việc mở bị lỗi: %2%" -#: schroot/schroot-listmounts.cc:105 +#: schroot/schroot-listmounts.cc:112 +#, boost-format msgid "%1%: Failed to close: %2%" msgstr "%1%: việc đóng bị lỗi: %2%" -#: schroot/schroot-listmounts.cc:151 +#: schroot/schroot-listmounts.cc:158 msgid "No mountpoint specified" msgstr "Chưa xác định điểm lắp" -#: schroot/schroot-listmounts-options.cc:43 -#: schroot/schroot-releaselock-options.cc:44 +#: schroot/schroot-listmounts-options.cc:42 schroot/schroot-options-base.cc:48 +#: schroot/schroot-releaselock-options.cc:43 msgid "General options" msgstr "Tùy chọn chung" -#: schroot/schroot-listmounts-options.cc:45 -#: schroot/schroot-releaselock-options.cc:46 +#: schroot/schroot-listmounts-options.cc:44 schroot/schroot-options-base.cc:69 +#: schroot/schroot-releaselock-options.cc:45 msgid "Show help options" msgstr "Hiện tùy chọn trợ giúp" -#: schroot/schroot-listmounts-options.cc:47 -#: schroot/schroot-releaselock-options.cc:48 +#: schroot/schroot-listmounts-options.cc:46 schroot/schroot-options-base.cc:71 +#: schroot/schroot-releaselock-options.cc:47 msgid "Print version information" msgstr "In ra thông tin phiên bản" -#: schroot/schroot-listmounts-options.cc:49 -#: schroot/schroot-releaselock-options.cc:50 +#: schroot/schroot-listmounts-options.cc:48 +#: schroot/schroot-releaselock-options.cc:49 msgid "Lock options" msgstr "Tùy chọn khoá" -#: schroot/schroot-listmounts-options.cc:52 +#: schroot/schroot-listmounts-options.cc:51 msgid "Mountpoint to check (full path)" msgstr "Điểm lắp cần kiểm tra (đường dẫn đầy đủ)" -#: schroot/schroot-listmounts-options.cc:65 schroot/schroot-options.cc:95 -#: schroot/schroot-releaselock-options.cc:68 -msgid "Usage:" -msgstr "Cách sử dụng:" - -#: schroot/schroot-listmounts-options.cc:66 +#: schroot/schroot-listmounts-options.cc:65 #, fuzzy msgid "schroot-listmounts [OPTION...] - list mounts" msgstr " schroot-listmounts [TÙY_CHỌN...] — liệt kê các sự gắn kết" -#: schroot/schroot-options.cc:59 +#: schroot/schroot-main.cc:194 +msgid "Error saving terminal settings" +msgstr "Gặp lỗi khi lưu thiết lập thiết bị cuối" + +#: schroot/schroot-main.cc:226 +#, boost-format +msgid "No chroots are defined in %1% or %2%" +msgstr "Chưa định nghĩa chroot trong %1% hay trong %2%" + +#: schroot/schroot-main.cc:234 +#, boost-format +msgid "No chroots are defined in %1%" +msgstr "Chưa định nghĩa chroot trong %1%" + +#: schroot/schroot-main.cc:251 +#, boost-format +msgid "The specified chroots are not defined in %1%" +msgstr "Chưa định nghĩa những chroot đã ghi rõ trong %1%" + +#: schroot/schroot-main.cc:278 +msgid "Only one chroot may be specified when beginning a session" +msgstr "Có thể ghi rõ chỉ một chroot khi khởi chạy phiên" + +#: schroot/schroot-main.cc:335 schroot/schroot-main.cc:351 +msgid "Error restoring terminal settings" +msgstr "Gặp lỗi khi phục hồi thiết lập thiết bị cuối" + +#: schroot/schroot-options-base.cc:49 +msgid "Chroot selection" +msgstr "Chọn chroot" + +#: schroot/schroot-options-base.cc:50 +msgid "Chroot environment" +msgstr "Môi trường chroot" + +#: schroot/schroot-options-base.cc:51 +msgid "Session management" +msgstr "Quản lý phiên chạy" + +#: schroot/schroot-options-base.cc:52 +msgid "Hidden options" +msgstr "Tùy chọn bị ẩn" + +#: schroot/schroot-options-base.cc:73 +msgid "Show less output" +msgstr "Xuất ít hơn" + +#: schroot/schroot-options-base.cc:75 +msgid "Show more output" +msgstr "Xuất nhiều hơn" + +#: schroot/schroot-options-base.cc:77 +msgid "List available chroots" +msgstr "Liệt kê các chroot sẵn sàng" + +#: schroot/schroot-options-base.cc:79 +msgid "Show information about selected chroots" +msgstr "Hiện thông tin về các chroot được chọn" + +#: schroot/schroot-options-base.cc:81 +msgid "Dump configuration of selected chroots" +msgstr "Đổ cấu hình của các chroot đã chọn" + +#: schroot/schroot-options-base.cc:85 +msgid "Use specified chroot" +msgstr "Dùng chroot đã xác định" + +#: schroot/schroot-options-base.cc:89 +msgid "Command to run" +msgstr "Lệnh cần chạy" + +#: schroot/schroot-options-base.cc:91 +msgid "Enable debugging messages" +msgstr "" + +#: schroot/schroot-options-base.cc:190 +msgid "" +"Only one chroot may be specified when recovering, running or ending a session" +msgstr "" +"Có thể ghi rõ chỉ một chroot khi phục hồi, chạy hoặc kết thúc một phiên chạy" + +#: schroot/schroot-options-base.cc:215 +msgid "--chroot may not be used with --list" +msgstr "" +"Không cho phép sử dụng tùy chọn cả « --chroot » lẫn « --list » (liệt kê) đều " +"đồng thời." + +#: schroot/schroot-options-base.cc:237 +#, fuzzy +msgid "Unknown action specified" +msgstr "Có thể ghi rõ chỉ một hành động thôi" + +#: schroot/schroot-options-base.cc:245 +msgid "Only one action may be specified" +msgstr "Có thể ghi rõ chỉ một hành động thôi" + +#: schroot/schroot-options.cc:56 msgid "Print location of selected chroots" msgstr "In ra địa điểm của các chroot đã chọn" -#: schroot/schroot-options.cc:63 +#: schroot/schroot-options.cc:60 msgid "Select all chroots and active sessions" msgstr "Chọn mọi chroot và phiên chạy hoạt động đều" -#: schroot/schroot-options.cc:65 -msgid "Select all chroots" -msgstr "Chọn mọi chroot" - -#: schroot/schroot-options.cc:67 +#: schroot/schroot-options.cc:64 msgid "Select all active sessions" msgstr "Chọn mọi phiên chạy hoạt động" -#: schroot/schroot-options.cc:71 +#: schroot/schroot-options.cc:68 msgid "Username (default current user)" msgstr "Tên người dùng (người dùng hiện thời mặc định)" -#: schroot/schroot-options.cc:73 -msgid "Preserve user environment" -msgstr "Bảo tồn môi trường người dùng" - -#: schroot/schroot-options.cc:77 +#: schroot/schroot-options.cc:74 msgid "Begin a session; returns a session ID" msgstr "Khởi chạy phiên; gởi trả một mã nhận diện phiên chạy" -#: schroot/schroot-options.cc:79 +#: schroot/schroot-options.cc:76 msgid "Recover an existing session" msgstr "Phục hồi một phiên chạy đã có" -#: schroot/schroot-options.cc:81 +#: schroot/schroot-options.cc:78 msgid "Run an existing session" msgstr "Chạy một phiên chạy đã có" -#: schroot/schroot-options.cc:83 +#: schroot/schroot-options.cc:80 msgid "End an existing session" msgstr "Kết thúc một phiên chạy đã có" -#: schroot/schroot-options.cc:85 +#: schroot/schroot-options.cc:82 msgid "Force operation, even if it fails" msgstr "Ép buộc thao tác, thậm chí nếu nó bị lỗi" -#: schroot/schroot-options.cc:98 -#, fuzzy -msgid "[OPTION...] [COMMAND] - run command or shell in a chroot" -msgstr " [TÙY_CHỌN...] [LỆNH] — chạy lệnh hoặc hệ vỏ trong một chroot" - -# Literal: don't translate / Nghĩa chữ: đừng dịch -#: schroot/schroot-releaselock.cc:54 -msgid "schroot-releaselock (Debian sbuild) %1%\n" -msgstr "schroot-releaselock (Debian sbuild) %1%\n" - -#: schroot/schroot-releaselock.cc:100 +#: schroot/schroot-releaselock.cc:105 msgid "No device specified" msgstr "Chưa ghi rõ thiết bị" -#: schroot/schroot-releaselock.cc:106 +#: schroot/schroot-releaselock.cc:111 msgid "No pid specified; forcing release of lock" msgstr "Chưa ghi rõ PID (mã nhận diện tiến trình) nên đang ép buộc nhả khoá" -#: schroot/schroot-releaselock.cc:115 +#: schroot/schroot-releaselock.cc:120 +#, boost-format msgid "Failed to stat device %1%: %2%" msgstr "Việc lấy các thông tin về thiết bị %1% bị lỗi: %2%" -#: schroot/schroot-releaselock.cc:123 +#: schroot/schroot-releaselock.cc:128 +#, boost-format msgid "%1% is not a block device" msgstr "%1% không phải là thiết bị khối" -#: schroot/schroot-releaselock.cc:131 +#: schroot/schroot-releaselock.cc:136 +#, boost-format msgid "%1%: failed to release device lock" msgstr "%1%: không nhả khoá thiết bị được" -#: schroot/schroot-releaselock.cc:138 +#: schroot/schroot-releaselock.cc:143 +#, boost-format msgid "%1%: failed to release device lock owned by pid %2%" msgstr "%1%: việc nhả khoá thiết bị do PID %2% sở hữư bị lỗi" -#: schroot/schroot-releaselock-options.cc:53 +#: schroot/schroot-releaselock-options.cc:52 msgid "Device to unlock (full path)" msgstr "Thiết bị cần bỏ khoá (đường dẫn đầy đủ)" -#: schroot/schroot-releaselock-options.cc:55 +#: schroot/schroot-releaselock-options.cc:54 msgid "Process ID owning the lock" msgstr "Mã nhận diện tiến trình mà sở hữu khoá đó" -#: schroot/schroot-releaselock-options.cc:69 +#: schroot/schroot-releaselock-options.cc:68 #, fuzzy msgid "schroot-releaselock [OPTION...] - release a device lock" msgstr " schroot-releaselock [TÙY_CHỌN...] — nhả khoá thiết bị" +# Literal: don't translate / Nghĩa chữ: đừng dịch +#~ msgid "schroot-listmounts (Debian sbuild) %1%\n" +#~ msgstr "schroot-listmounts (Debian sbuild) %1%\n" + +# Literal: don't translate / Nghĩa chữ: đừng dịch +#~ msgid "schroot-releaselock (Debian sbuild) %1%\n" +#~ msgstr "schroot-releaselock (Debian sbuild) %1%\n" + #~ msgid "line %1%: invalid line: %2%" #~ msgstr "dòng %1%: dòng không hợp lệ: %2%" -#~ msgid "(%1%->%2%): dchroot sessions do not support user switching" -#~ msgstr "" -#~ "(%1% → %2%): phiên chạy dchroot không hỗ trợ khả năng chuyển đổi người " -#~ "dùng." - #~ msgid "PAM set RUSER error: %1%" #~ msgstr "Lỗi « PAM set RUSER » (lập máy ở xa): %1%" @@ -969,131 +1228,9 @@ msgstr " schroot-releaselock [TÙY_CHỌN...] — nhả khoá thiết bị" #~ msgid "Child exited abnormally with status '%1%'" #~ msgstr "Tiến trình con đã thoát bất thường với trạng thái « %1% »" -#~ msgid "%1% (Debian sbuild) %2%\n" -#~ msgstr "%1% (Debian sbuild) %2%\n" - -#~ msgid "Error saving terminal settings" -#~ msgstr "Gặp lỗi khi lưu thiết lập thiết bị cuối" - -#~ msgid "Run 'schroot' for full capability" -#~ msgstr "Chạy « schroot » để có khả năng đầy đủ" - -#~ msgid "Using dchroot configuration file: " -#~ msgstr "Đang dùng tập tin cấu hình dchroot: " - -#~ msgid "Run '%1%'" -#~ msgstr "Chạy « %1% »" - -#~ msgid "to migrate to a schroot configuration." -#~ msgstr "để nâng cấp lên một cấu hình schroot." - -#~ msgid "Edit '%1%' to add appropriate group access." -#~ msgstr "Hiệu chỉnh « %1% » để thêm cách truy cập nhóm thích hợp." - -#~ msgid "Remove '%1%' to use the new configuration." -#~ msgstr "Gỡ bỏ « %1% » để sử dụng cấu hình mới." - -#~ msgid "No chroots are defined in %1% or %2%" -#~ msgstr "Chưa định nghĩa chroot trong %1% hay trong %2%" - -#~ msgid "No chroots are defined in %1%" -#~ msgstr "Chưa định nghĩa chroot trong %1%" - -#~ msgid "The specified chroots are not defined in %1%" -#~ msgstr "Chưa định nghĩa những chroot đã ghi rõ trong %1%" - -#~ msgid "schroot configuration generated by %1% %2%" -#~ msgstr "Cấu hình schroot được tạo ra bởi %1% %2%" - -#~ msgid "" -#~ "To allow users access to the chroots, add their groups to the groups keys." -#~ msgstr "" -#~ "Để cho phép người dùng truy cập những chroot này, hãy thêm các nhóm của " -#~ "họ vào những khoá nhóm (groups)." - -#~ msgid "" -#~ "To allow passwordless root access, add their groups to the root-groups " -#~ "keys." -#~ msgstr "" -#~ "Để cho phép việc truy cập kiểu người chủ mà không cần mật khẩu, hãy thêm " -#~ "các nhóm của họ vào khoá nhóm chủ (root-groups)." - -#~ msgid "Only one chroot may be specified when beginning a session" -#~ msgstr "Có thể ghi rõ chỉ một chroot khi khởi chạy phiên" - #~ msgid "Session failure: %1%" #~ msgstr "Phiên bản bị lỗi: %1%" -#~ msgid "Error restoring terminal settings" -#~ msgstr "Gặp lỗi khi phục hồi thiết lập thiết bị cuối" - -#~ msgid "Show less output" -#~ msgstr "Xuất ít hơn" - -#~ msgid "Show more output" -#~ msgstr "Xuất nhiều hơn" - -#~ msgid "List available chroots" -#~ msgstr "Liệt kê các chroot sẵn sàng" - -#~ msgid "Show information about selected chroots" -#~ msgstr "Hiện thông tin về các chroot được chọn" - -#~ msgid "Print path to selected chroot" -#~ msgstr "In ra đường dẫn đến chroot đã chọn" - -#~ msgid "Dump configuration of selected chroots" -#~ msgstr "Đổ cấu hình của các chroot đã chọn" - -#~ msgid "Chroot selection" -#~ msgstr "Chọn chroot" - -#~ msgid "Use specified chroot" -#~ msgstr "Dùng chroot đã xác định" - -#~ msgid "Chroot environment" -#~ msgstr "Môi trường chroot" - -#~ msgid "Session management" -#~ msgstr "Quản lý phiên chạy" - -#~ msgid "Hidden options" -#~ msgstr "Tùy chọn bị ẩn" - -#~ msgid "Command to run" -#~ msgstr "Lệnh cần chạy" - -#~ msgid "--quiet and --verbose may not be used at the same time" -#~ msgstr "" -#~ "Không cho phép sử dụng tùy chọn cả « --quiet » (xuất ít hơn) lẫn « --" -#~ "verbose » (xuất nhiều hơn) đều đồng thời." - -#~ msgid "Using verbose output" -#~ msgstr "Đang xuất nhiều hơn" - -#~ msgid "--chroot and --all may not be used at the same time" -#~ msgstr "" -#~ "Không cho phép sử dụng tùy chọn cả « --chroot » lẫn « --all » (tất cả) " -#~ "đều đồng thời." - -#~ msgid "Using --chroots only" -#~ msgstr "Đang dùng chỉ tùy chọn « --chroots » thôi" - -#~ msgid "" -#~ "Only one chroot may be specified when recovering, running or ending a " -#~ "session" -#~ msgstr "" -#~ "Có thể ghi rõ chỉ một chroot khi phục hồi, chạy hoặc kết thúc một phiên " -#~ "chạy" - -#~ msgid "--chroot may not be used with --list" -#~ msgstr "" -#~ "Không cho phép sử dụng tùy chọn cả « --chroot » lẫn « --list » (liệt kê) " -#~ "đều đồng thời." - -#~ msgid "Only one action may be specified" -#~ msgstr "Có thể ghi rõ chỉ một hành động thôi" - #~ msgid "Can't open configuration file %1%" #~ msgstr "Không thể mở tập tin cấu hình %1%" diff --git a/sbuild/Makefile.am b/sbuild/Makefile.am new file mode 100644 index 00000000..3ad981bb --- /dev/null +++ b/sbuild/Makefile.am @@ -0,0 +1,93 @@ +# schroot Makefile template +# +# +# Copyright © 2004-2006 Roger Leigh +# +# schroot is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# schroot is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +##################################################################### + +localedir = $(datadir)/locale + +AM_CXXFLAGS = $(SCHROOT_CFLAGS) -pedantic -Wall -Wcast-align -Wwrite-strings -Wswitch-default -Wcast-qual -Wunused-variable -Wredundant-decls -Wctor-dtor-privacy -Wnon-virtual-dtor -Wreorder -Wold-style-cast -Woverloaded-virtual -fstrict-aliasing +# -Weffc++ causes too many warnings in standard headers; -Wextra is not +# supported by GCC 3.4. + +DEFS = -DGETTEXT_PACKAGE=\"schroot\" -DLOCALEDIR=\"$(localedir)\" -D_GNU_SOURCE + +noinst_LTLIBRARIES = libsbuild.la + +sbuild_public_h_sources = \ + sbuild-auth.h \ + sbuild-auth-conv.h \ + sbuild-auth-conv-tty.h \ + sbuild-auth-message.h \ + sbuild-chroot.h \ + sbuild-chroot-block-device.h \ + sbuild-chroot-file.h \ + sbuild-chroot-lvm-snapshot.h \ + sbuild-chroot-plain.h \ + sbuild-chroot-source.h \ + sbuild-chroot-config.h \ + sbuild-custom-error.h \ + sbuild-custom-error.tcc \ + sbuild-environment.h \ + sbuild-error.h \ + sbuild-format-detail.h \ + sbuild-i18n.h \ + sbuild-keyfile.h \ + sbuild-lock.h \ + sbuild-log.h \ + sbuild-nostream.h \ + sbuild-parse-error.h \ + sbuild-parse-value.h \ + sbuild-personality.h \ + sbuild-session.h \ + sbuild-types.h \ + sbuild-util.h + +sbuild_public_cc_sources = \ + sbuild-auth.cc \ + sbuild-auth-conv.cc \ + sbuild-auth-conv-tty.cc \ + sbuild-auth-message.cc \ + sbuild-chroot.cc \ + sbuild-chroot-block-device.cc \ + sbuild-chroot-file.cc \ + sbuild-chroot-lvm-snapshot.cc \ + sbuild-chroot-plain.cc \ + sbuild-chroot-source.cc \ + sbuild-chroot-config.cc \ + sbuild-environment.cc \ + sbuild-format-detail.cc \ + sbuild-keyfile.cc \ + sbuild-lock.cc \ + sbuild-log.cc \ + sbuild-nostream.cc \ + sbuild-parse-error.cc \ + sbuild-parse-value.cc \ + sbuild-personality.cc \ + sbuild-session.cc \ + sbuild-util.cc + +libsbuild_la_SOURCES = \ + $(sbuild_public_h_sources) \ + $(sbuild_public_cc_sources) + +nodist_libsbuild_la_SOURCES = \ + sbuild-config.h + +libsbuild_la_LIBADD = $(UUID_LIBS) $(PAM_LIBS) $(LOCKDEV_LIBS) $(BOOST_LIBS) $(LIBINTL) diff --git a/sbuild/sbuild-auth-conv-tty.cc b/sbuild/sbuild-auth-conv-tty.cc new file mode 100644 index 00000000..7701fdde --- /dev/null +++ b/sbuild/sbuild-auth-conv-tty.cc @@ -0,0 +1,320 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#include + +#include "sbuild-auth-conv-tty.h" +#include "sbuild-log.h" + +#include + +#include +#include + +#include + +using std::cerr; +using std::endl; +using boost::format; +using namespace sbuild; + +namespace +{ + + typedef std::pair emap; + + /** + * This is a list of the supported error codes. It's used to + * construct the real error codes map. + */ + emap init_errors[] = + { + emap(auth_conv_tty::TIMEOUT, N_("Timed out")), + emap(auth_conv_tty::TIMEOUT_PENDING, N_("Time is running out...")), + emap(auth_conv_tty::TERMIOS, N_("Failed to get terminal settings")), + emap(auth_conv_tty::CONV_TYPE, N_("Unsupported conversation type")) + }; + + volatile sig_atomic_t timer_expired = false; + + /** + * Disable the alarm and signal handler. + * + * @param orig_sa the signal handler to restore. + */ + void + reset_alarm (struct sigaction *orig_sa) + { + // Stop alarm + alarm (0); + // Restore original handler + sigaction (SIGALRM, orig_sa, NULL); + } + + /** + * Handle the SIGALRM signal. + * + * @param ignore the signal number (unused). + */ + void + alarm_handler (int ignore) + { + timer_expired = true; + } + + /** + * Set the SIGALARM handler, and set the timeout to delay seconds. + * The old signal handler is stored in orig_sa. + * + * @param delay the delay (in seconds) before SIGALRM is raised. + * @param orig_sa the location to store the original signal handler. + * @returns true on success, false on failure. + */ + bool + set_alarm (int delay, + struct sigaction *orig_sa) + { + struct sigaction new_sa; + sigemptyset(&new_sa.sa_mask); + new_sa.sa_flags = 0; + new_sa.sa_handler = alarm_handler; + + if (sigaction(SIGALRM, &new_sa, orig_sa) != 0) + { + return false; + } + if (alarm(delay) != 0) + { + sigaction(SIGALRM, orig_sa, NULL); + return false; + } + + return true; + } + +} + +template<> +custom_error::map_type +custom_error::error_strings +(init_errors, + init_errors + (sizeof(init_errors) / sizeof(init_errors[0]))); + +auth_conv_tty::auth_conv_tty (): + warning_timeout(0), + fatal_timeout(0), + start_time(0) +{ +} + +auth_conv_tty::~auth_conv_tty () +{ +} + +time_t +auth_conv_tty::get_warning_timeout () +{ + return this->warning_timeout; +} + +void +auth_conv_tty::set_warning_timeout (time_t timeout) +{ + this->warning_timeout = timeout; +} + +time_t +auth_conv_tty::get_fatal_timeout () +{ + return this->fatal_timeout; +} + +void +auth_conv_tty::set_fatal_timeout (time_t timeout) +{ + this->fatal_timeout = timeout; +} + +int +auth_conv_tty::get_delay () +{ + timer_expired = 0; + time (&this->start_time); + + if (this->fatal_timeout != 0 && + this->start_time >= this->fatal_timeout) + throw error(TIMEOUT); + + if (this->warning_timeout != 0 && + this->start_time >= this->warning_timeout) + { + error e(TIMEOUT_PENDING); + log_warning() << e.what() << endl; + return (this->fatal_timeout ? + this->fatal_timeout - this->start_time : 0); + } + + if (this->warning_timeout != 0) + return this->warning_timeout - this->start_time; + else if (this->fatal_timeout != 0) + return this->fatal_timeout - this->start_time; + else + return 0; +} + +std::string +auth_conv_tty::read_string (std::string message, + bool echo) +{ + struct termios orig_termios, noecho_termios; + struct sigaction saved_signals; + sigset_t old_sigs, new_sigs; + bool use_termios = false; + std::string retval; + + if (isatty(STDIN_FILENO)) + { + use_termios = true; + + if (tcgetattr(STDIN_FILENO, &orig_termios) != 0) + throw error(TERMIOS); + + memcpy(&noecho_termios, &orig_termios, sizeof(struct termios)); + + if (echo == false) + noecho_termios.c_lflag &= ~(ECHO); + + sigemptyset(&new_sigs); + sigaddset(&new_sigs, SIGINT); + sigaddset(&new_sigs, SIGTSTP); + sigprocmask(SIG_BLOCK, &new_sigs, &old_sigs); + } + + char input[PAM_MAX_MSG_SIZE]; + + int delay = get_delay(); + + while (delay >= 0) + { + cerr << message; + + if (use_termios == true) + tcsetattr(STDIN_FILENO, TCSAFLUSH, &noecho_termios); + + if (delay > 0 && set_alarm(delay, &saved_signals) == false) + break; + else + { + int nchars = read(STDIN_FILENO, input, PAM_MAX_MSG_SIZE - 1); + if (use_termios) + { + tcsetattr(STDIN_FILENO, TCSADRAIN, &orig_termios); + if (echo == false && timer_expired == true) + cerr << endl; + } + if (delay > 0) + reset_alarm(&saved_signals); + if (timer_expired == true) + { + delay = get_delay(); + } + else if (nchars > 0) + { + if (echo == false) + cerr << endl; + + if (input[nchars-1] == '\n') + input[--nchars] = '\0'; + else + input[nchars] = '\0'; + + retval = input; + break; + } + else if (nchars == 0) + { + if (echo == false) + cerr << endl; + + retval = ""; + break; + } + } + } + + memset(input, 0, sizeof(input)); + + if (use_termios == true) + { + sigprocmask(SIG_SETMASK, &old_sigs, NULL); + tcsetattr(STDIN_FILENO, TCSADRAIN, &orig_termios); + } + + return retval; +} + +bool +auth_conv_tty::conversation (message_list& messages) +{ + try + { + for (std::vector::iterator cur = messages.begin(); + cur != messages.end(); + ++cur) + { + switch (cur->message_type) + { + case auth_message::MESSAGE_PROMPT_NOECHO: + cur->response = read_string(cur->message, false); + break; + case auth_message::MESSAGE_PROMPT_ECHO: + cur->response = read_string(cur->message, true); + break; + case auth_message::MESSAGE_ERROR: + cerr << cur->message << endl; + break; + case auth_message::MESSAGE_INFO: + cerr << cur->message << endl; + break; + default: + { + format fmt("%1%"); + fmt % cur->message_type; + error e(fmt.str(), CONV_TYPE); + log_error() << e.what() << endl; + return false; + } + break; + } + } + } + catch (error const& e) + { + log_error() << e.what() << std::endl; + return false; + } + + return true; +} + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/sbuild/sbuild-auth-conv-tty.h b/sbuild/sbuild-auth-conv-tty.h new file mode 100644 index 00000000..79cf8b8b --- /dev/null +++ b/sbuild/sbuild-auth-conv-tty.h @@ -0,0 +1,133 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#ifndef SBUILD_AUTH_CONV_TTY_H +#define SBUILD_AUTH_CONV_TTY_H + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +namespace sbuild +{ + /** + * @brief Authentication conversation handler for terminal devices. + * + * This class is an implementation of the auth_conv interface, and + * is used to interact with the user on a terminal (TTY) interface. + * + * In order to implement timeouts, this class uses alarm(2). This + * has some important implications. Global state is modified by the + * object, so only one may be used at once in a single process. In + * addition, no other part of the process may set or unset the + * SIGALRM handlers and the alarm(2) timer during the time PAM + * authentication is proceeding. + */ + class auth_conv_tty : public auth_conv + { + public: + /// Error codes. + enum error_code + { + TIMEOUT, ///< Timed out. + TIMEOUT_PENDING, ///< Time is running out... + TERMIOS, ///< Failed to get terminal settings. + CONV_TYPE ///< Unsupported conversation type. + }; + + /// Exception type. + typedef custom_error error; + + /// The constructor. + auth_conv_tty (); + /// The destructor. + virtual ~auth_conv_tty (); + + virtual time_t + get_warning_timeout (); + + virtual void + set_warning_timeout (time_t timeout); + + virtual time_t + get_fatal_timeout (); + + virtual void + set_fatal_timeout (time_t timeout); + + virtual bool + conversation (message_list& messages); + + private: + /** + * @brief Get the time delay before the next SIGALRM signal. + * + * If either the warning timeout or the fatal timeout have + * expired, a message to notify the user is printed to stderr. If + * the fatal timeout is reached, an exception is thrown. + * + * @returns the delay in seconds, or 0 if no delay is set. + */ + int get_delay (); + + /** + * @brief Read user input from standard input. + * + * The prompt message is printed to prompt the user for input. If + * echo is true, the user input it echoed back to the terminal, + * but if false, echoing is suppressed using termios(3). + * + * If the SIGALRM timer expires while waiting for input, this is + * handled by re-checking the delay time which will warn the user + * or cause the input routine to terminate if the fatal timeout + * has expired. + * + * @param message the message to prompt the user for input. + * @param echo echo user input to screen. + * @returns a string, which is empty on failure. + */ + std::string + read_string (std::string message, + bool echo); + + /// The time to warn at. + time_t warning_timeout; + /// The time to end at. + time_t fatal_timeout; + /// The time the current delay was obtained at. + time_t start_time; + }; + +} + +#endif /* SBUILD_AUTH_CONV_TTY_H */ + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/sbuild/sbuild-auth-conv.cc b/sbuild/sbuild-auth-conv.cc new file mode 100644 index 00000000..f2314d84 --- /dev/null +++ b/sbuild/sbuild-auth-conv.cc @@ -0,0 +1,38 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#include + +#include "sbuild-auth-conv.h" + +using namespace sbuild; + +auth_conv::auth_conv () +{ +} + +auth_conv::~auth_conv () +{ +} + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/sbuild/sbuild-auth-conv.h b/sbuild/sbuild-auth-conv.h new file mode 100644 index 00000000..13d290ee --- /dev/null +++ b/sbuild/sbuild-auth-conv.h @@ -0,0 +1,120 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#ifndef SBUILD_AUTH_CONV_H +#define SBUILD_AUTH_CONV_H + +#include +#include + +#include + +namespace sbuild +{ + + /** + * @brief Authentication conversation handler interface. + * + * This interface should be implemented by objects which handle + * interaction with the user during authentication. + * + * This is a wrapper around the struct pam_conv PAM conversation + * interface, and is used by auth when interacting with the user + * during authentication. + * + * A simple implementation is provided in the form of auth_conv_tty. + * However, more complex implementations might hook into an event + * loop for GUI widget system. + * + * The interface allows the setting of optional warning timeout and + * fatal timeout values, which should default to 0 (not enabled). + * This is an absolute time after which a warning is displayed or + * the conversation ends with an error. + */ + class auth_conv + { + public: + /// A list of messages. + typedef std::vector message_list; + + /// The constructor. + auth_conv (); + /// The destructor. + virtual ~auth_conv (); + + /** + * @brief Get the time at which the user will be warned. + * + * @returns the time. + */ + virtual time_t + get_warning_timeout () = 0; + + /** + * @brief Set the time at which the user will be warned. + * + * @param timeout the time to set. + */ + virtual void + set_warning_timeout (time_t timeout) = 0; + + /** + * @brief Get the time at which the conversation will be + * terminated with an error. + * + * @returns the time. + */ + virtual time_t + get_fatal_timeout () = 0; + + /** + * @brief Set the time at which the conversation will be + * terminated with an error. + * + * @param timeout the time to set. + */ + virtual void + set_fatal_timeout (time_t timeout) = 0; + + /** + * @brief Hold a conversation with the user. + * + * Each of the messages detailed in messages should be displayed + * to the user, asking for input where required. The type of + * message is indicated in the auth_message::message_type field of + * the auth_message. The auth_message::response field of the + * auth_message should be filled in if input is required. + * + * @param messages the messages to display to the user, and + * responses to return to the caller. + * @returns true on success, false on failure. + */ + virtual bool + conversation (message_list& messages) = 0; + }; + +} + +#endif /* SBUILD_AUTH_CONV_H */ + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/sbuild/sbuild-auth-message.cc b/sbuild/sbuild-auth-message.cc new file mode 100644 index 00000000..732f4ee7 --- /dev/null +++ b/sbuild/sbuild-auth-message.cc @@ -0,0 +1,42 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#include + +#include "sbuild-auth-message.h" + +using namespace sbuild; + +auth_message::auth_message (auth_message::type type, + std::string const& message): + message_type(type), + message(message), + response() +{ +} + +auth_message::~auth_message () +{ +} + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/sbuild/sbuild-auth-message.h b/sbuild/sbuild-auth-message.h new file mode 100644 index 00000000..a5c23532 --- /dev/null +++ b/sbuild/sbuild-auth-message.h @@ -0,0 +1,85 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#ifndef SBUILD_AUTH_MESSAGE_H +#define SBUILD_AUTH_MESSAGE_H + +#include +#include + +#include + +namespace sbuild +{ + + /** + * Authentication messages. + * + * When auth needs to interact with the user, it does this by + * sending a list of auth_message objects to an AuthConv + * conversation object. These messages tell the conversation object + * how to display the message to the user, and if necessary, whether + * or not to ask the user for some input. They also store the + * user's input, if required. + */ + class auth_message + { + public: + /// Message type + enum type + { + /// Display a prompt, with no echoing of user input. + MESSAGE_PROMPT_NOECHO = PAM_PROMPT_ECHO_OFF, + /// Display a prompt, echoing user input. + MESSAGE_PROMPT_ECHO = PAM_PROMPT_ECHO_ON, + /// Display an error message. + MESSAGE_ERROR = PAM_ERROR_MSG, + /// Display an informational message. + MESSAGE_INFO = PAM_TEXT_INFO + }; + + /** + * The constructor. + * + * @param message_type the type of message. + * @param message the message to display. + */ + auth_message (type message_type, + std::string const& message); + + /// The destructor. + virtual ~auth_message (); + + /// The type of message. + type message_type; + /// The message to display. + std::string message; + /// The user's response (if any). + std::string response; + }; + +} + +#endif /* SBUILD_AUTH_MESSAGE_H */ + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/sbuild/sbuild-auth.cc b/sbuild/sbuild-auth.cc new file mode 100644 index 00000000..83c9fb86 --- /dev/null +++ b/sbuild/sbuild-auth.cc @@ -0,0 +1,692 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#include + +#include "sbuild-auth.h" +#include "sbuild-auth-conv.h" +#include "sbuild-auth-conv-tty.h" + +#include +#include +#include +#include +#include +#include + +#include + +#include + +using std::cerr; +using std::endl; +using boost::format; +using namespace sbuild; + +namespace +{ + + typedef std::pair emap; + + /** + * This is a list of the supported error codes. It's used to + * construct the real error codes map. + */ + emap init_errors[] = + { + emap(auth::HOSTNAME, N_("Failed to get hostname")), + emap(auth::USER, N_("User not found")), + emap(auth::AUTHENTICATION, N_("Access not authorised")), + emap(auth::AUTHORISATION, N_("Authentication failed")), + emap(auth::PAM_DOUBLE_INIT, N_("PAM is already initialised")), + emap(auth::PAM, N_("PAM error")) + }; + +} + +template<> +custom_error::map_type +custom_error::error_strings +(init_errors, + init_errors + (sizeof(init_errors) / sizeof(init_errors[0]))); + +namespace +{ + + /* This is the glue to link PAM user interaction with auth_conv. */ + int + auth_conv_hook (int num_msg, + const struct pam_message **msgm, + struct pam_response **response, + void *appdata_ptr) + { + if (appdata_ptr == 0) + return PAM_CONV_ERR; + + auth_conv *conv = static_cast(appdata_ptr); + assert (conv != 0); + + /* Construct a message vector */ + auth_conv::message_list messages; + for (int i = 0; i < num_msg; ++i) + { + const struct pam_message *source = msgm[i]; + + auth_message + message(static_cast(source->msg_style), + source->msg); + messages.push_back(message); + } + + /* Do the conversation */ + bool status = conv->conversation(messages); + + if (status == true) + { + /* Copy response into **reponse */ + struct pam_response *reply = + static_cast + (malloc(sizeof(struct pam_response) * num_msg)); + + for (int i = 0; i < num_msg; ++i) + { + reply[i].resp_retcode = 0; + reply[i].resp = strdup(messages[i].response.c_str()); + } + + *response = reply; + reply = 0; + + return PAM_SUCCESS; + } + else + return PAM_CONV_ERR; + } + +} + + +auth::auth (std::string const& service_name): + pam(), + service(service_name), + uid(0), + gid(0), + user(), + command(), + home(), + shell(), + user_environment(), + ruid(), + ruser(), + conv(dynamic_cast(new auth_conv_tty)), + message_verbosity(VERBOSITY_NORMAL) +{ + this->ruid = getuid(); + struct passwd *pwent = getpwuid(this->ruid); + if (pwent == 0) + { + // TODO: Convert to using a lexical cast. + std::ostringstream str; + str << this->ruid; + throw error(str.str(), USER, errno); + } + this->ruser = pwent->pw_name; + + /* By default, the auth user is the same as the remote user. */ + set_user(this->ruser); +} + +auth::~auth () +{ + // Shutdown PAM. + try + { + stop(); + } + catch (...) + { + } +} + +std::string const& +auth::get_service () const +{ + return this->service; +} + +uid_t +auth::get_uid () const +{ + return this->uid; +} + +gid_t +auth::get_gid () const +{ + return this->gid; +} + +std::string const& +auth::get_user () const +{ + return this->user; +} + +void +auth::set_user (std::string const& user) +{ + this->uid = 0; + this->gid = 0; + this->home = "/"; + this->shell = "/bin/false"; + + this->user = user; + + struct passwd *pwent = getpwnam(this->user.c_str()); + if (pwent == 0) + { + throw error(user, USER, errno); + } + this->uid = pwent->pw_uid; + this->gid = pwent->pw_gid; + this->home = pwent->pw_dir; + this->shell = pwent->pw_shell; + log_debug(DEBUG_INFO) + << format("auth uid = %1%, gid = %2%") % this->uid % this->gid + << endl; +} + +string_list const& +auth::get_command () const +{ + return this->command; +} + +void +auth::set_command (string_list const& command) +{ + this->command = command; +} + +std::string const& +auth::get_home () const +{ + return this->home; +} + +std::string const& +auth::get_shell () const +{ + return this->shell; +} + +environment const& +auth::get_environment () const +{ + return this->user_environment; +} + +void +auth::set_environment (char **environment) +{ + set_environment(sbuild::environment(environment)); +} + +void +auth::set_environment (environment const& environment) +{ + this->user_environment = environment; +} + +environment +auth::get_pam_environment () const +{ + return environment(pam_getenvlist(this->pam)); +} + +uid_t +auth::get_ruid () const +{ + return this->ruid; +} + +std::string const& +auth::get_ruser () const +{ + return this->ruser; +} + +auth::verbosity +auth::get_verbosity () const +{ + return this->message_verbosity; +} + +void +auth::set_verbosity (auth::verbosity verbosity) +{ + this->message_verbosity = verbosity; +} + +auth::conv_ptr& +auth::get_conv () +{ + return this->conv; +} + +void +auth::set_conv (conv_ptr& conv) +{ + this->conv = conv; +} + +void +auth::run () +{ + try + { + start(); + authenticate(); + setupenv(); + account(); + try + { + cred_establish(); + + const char *authuser = 0; + const void *tmpcast = static_cast(authuser); + pam_get_item(this->pam, PAM_USER, &tmpcast); + log_debug(DEBUG_INFO) + << format("PAM authentication succeeded for user %1%") % authuser + << endl; + + run_impl(); + + /* The session is now finished, either + successfully or not. All PAM operations are + now for cleanup and shutdown, and we must + clean up whether or not errors were raised at + any previous point. This means only the + first error is reported back to the user. */ + + /* Don't cope with failure, since we are now + already bailing out, and an error may already + have been raised */ + } + catch (error const& e) + { + try + { + cred_delete(); + } + catch (error const& discard) + { + } + throw; + } + } + catch (error const& e) + { + try + { + /* Don't cope with failure, since we are now already bailing out, + and an error may already have been raised */ + stop(); + } + catch (error const& discard) + { + } + throw; + } +} + +void +auth::start () +{ + assert(!this->user.empty()); + + if (this->pam != 0) + { + log_debug(DEBUG_CRITICAL) + << "pam_start FAIL (already initialised)" << endl; + throw error("Init PAM", PAM_DOUBLE_INIT); + } + + struct pam_conv conv_hook = + { + auth_conv_hook, + static_cast(this->conv.get()) + }; + + int pam_status; + + if ((pam_status = + pam_start(this->service.c_str(), this->user.c_str(), + &conv_hook, &this->pam)) != PAM_SUCCESS) + { + log_debug(DEBUG_WARNING) << "pam_start FAIL" << endl; + throw error(PAM, pam_strerror(pam_status)); + } + + log_debug(DEBUG_NOTICE) << "pam_start OK" << endl; +} + +void +auth::stop () +{ + if (this->pam); // PAM must be initialised + { + int pam_status; + + if ((pam_status = + pam_end(this->pam, PAM_SUCCESS)) != PAM_SUCCESS) + { + log_debug(DEBUG_WARNING) << "pam_end FAIL" << endl; + throw error(PAM, pam_strerror(pam_status)); + } + + this->pam = 0; + log_debug(DEBUG_NOTICE) << "pam_end OK" << endl; + } +} + +void +auth::authenticate () +{ + assert(!this->user.empty()); + assert(this->pam != 0); // PAM must be initialised + + int pam_status; + + if ((pam_status = + pam_set_item(this->pam, PAM_RUSER, this->ruser.c_str())) != PAM_SUCCESS) + { + log_debug(DEBUG_WARNING) << "pam_set_item (PAM_RUSER) FAIL" << endl; + throw error(_("Set RUSER"), PAM, pam_strerror(pam_status)); + } + + long hl = 256; /* sysconf(_SC_HOST_NAME_MAX); BROKEN with Debian libc6 2.3.2.ds1-22 */ + + char *hostname = new char[hl]; + if (gethostname(hostname, hl) != 0) + { + log_debug(DEBUG_CRITICAL) << "gethostname FAIL" << endl; + throw error(HOSTNAME, errno); + } + + if ((pam_status = + pam_set_item(this->pam, PAM_RHOST, hostname)) != PAM_SUCCESS) + { + log_debug(DEBUG_WARNING) << "pam_set_item (PAM_RHOST) FAIL" << endl; + throw error(_("Set RHOST"), PAM, pam_strerror(pam_status)); + } + + delete[] hostname; + hostname = 0; + + const char *tty = ttyname(STDIN_FILENO); + if (tty) + { + if ((pam_status = + pam_set_item(this->pam, PAM_TTY, tty)) != PAM_SUCCESS) + { + log_debug(DEBUG_WARNING) << "pam_set_item (PAM_TTY) FAIL" << endl; + throw error(_("Set TTY"), PAM, pam_strerror(pam_status)); + } + } + + /* Authenticate as required. */ + switch (get_auth_status()) + { + case STATUS_NONE: + if ((pam_status = pam_set_item(this->pam, PAM_USER, this->user.c_str())) + != PAM_SUCCESS) + { + log_debug(DEBUG_WARNING) << "pam_set_item (PAM_USER) FAIL" << endl; + throw error(_("Set USER"), PAM, pam_strerror(pam_status)); + } + break; + + case STATUS_USER: + if ((pam_status = pam_authenticate(this->pam, 0)) != PAM_SUCCESS) + { + log_debug(DEBUG_INFO) << "pam_authenticate FAIL" << endl; + syslog(LOG_AUTH|LOG_WARNING, "%s->%s Authentication failure", + this->ruser.c_str(), this->user.c_str()); + throw error(AUTHENTICATION, pam_strerror(pam_status)); + } + log_debug(DEBUG_NOTICE) << "pam_authenticate OK" << endl; + break; + + case STATUS_FAIL: + { + log_debug(DEBUG_INFO) << "PAM auth premature FAIL" << endl; + cerr << format(_("You do not have permission to access the %1% service.")) + % this->service + << '\n' + << _("This failure will be reported.") + << endl; + syslog(LOG_AUTH|LOG_WARNING, + "%s->%s Unauthorised", + this->ruser.c_str(), this->user.c_str()); + throw error(AUTHORISATION); + } + default: + break; + } +} + +void +auth::setupenv () +{ + assert(this->pam != 0); // PAM must be initialised + + int pam_status; + + environment environment; + if (!this->user_environment.empty()) + environment = this->user_environment; + + // For security, PATH is always set to a sane state for root, but + // only set in other cases if not preserving the environment. + if (this->uid == 0) + environment.add(std::make_pair("PATH", "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11")); + else if (this->user_environment.empty()) + environment.add(std::make_pair("PATH", "/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games")); + + if (this->user_environment.empty()) + { + if (!this->home.empty() ) + environment.add(std::make_pair("HOME", this->home)); + else + environment.add(std::make_pair("HOME", "/")); + if (!this->user.empty()) + { + environment.add(std::make_pair("LOGNAME", this->user)); + environment.add(std::make_pair("USER", this->user)); + } + { + const char *term = getenv("TERM"); + if (term) + environment.add(std::make_pair("TERM", term)); + } + if (!this->shell.empty()) + environment.add(std::make_pair("SHELL", this->shell)); + } + + // Sanitise environment. + environment.remove("BASH_ENV"); + environment.remove("CDPATH"); + environment.remove("ENV"); + environment.remove("HOSTALIASES"); + environment.remove("IFS"); + environment.remove("KRB5_CONFIG"); + environment.remove("KRBCONFDIR"); + environment.remove("KRBTKFILE"); + environment.remove("KRB_CONF"); + environment.remove("LOCALDOMAIN"); + environment.remove("NLSPATH"); + environment.remove("PATH_LOCALE"); + environment.remove("RES_OPTIONS"); + environment.remove("TERMINFO"); + environment.remove("TERMINFO_DIRS"); + environment.remove("TERMPATH"); + + // Find and remove LD_.*, + string_list ldvars; + for (environment::const_iterator cur = environment.begin(); + cur != environment.end();) + { + environment::const_iterator next = cur; + next++; + + if (cur->first.substr(0,3) == "LD_") + environment.remove(cur->first); + + cur = next; + } + + // Move into PAM environment. + for (environment::const_iterator cur = environment.begin(); + cur != environment.end(); + ++cur) + { + std::string env_string = cur->first + "=" + cur->second; + if ((pam_status = + pam_putenv(this->pam, env_string.c_str())) != PAM_SUCCESS) + { + log_debug(DEBUG_WARNING) << "pam_putenv FAIL" << endl; + throw error(PAM, pam_strerror(pam_status)); + } + log_debug(DEBUG_INFO) + << format("pam_putenv: set %1%=%2%") % cur->first % cur->second + << endl; + } + + log_debug(DEBUG_NOTICE) << "pam_putenv OK" << endl; +} + +void +auth::account () +{ + assert(this->pam != 0); // PAM must be initialised + + int pam_status; + + if ((pam_status = + pam_acct_mgmt(this->pam, 0)) != PAM_SUCCESS) + { + /* We don't handle changing expired passwords here, since we are + not login or ssh. */ + log_debug(DEBUG_WARNING) << "pam_acct_mgmt FAIL" << endl; + throw error(PAM, pam_strerror(pam_status)); + } + + log_debug(DEBUG_NOTICE) << "pam_acct_mgmt OK" << endl; +} + +void +auth::cred_establish () +{ + assert(this->pam != 0); // PAM must be initialised + + int pam_status; + + if ((pam_status = + pam_setcred(this->pam, PAM_ESTABLISH_CRED)) != PAM_SUCCESS) + { + log_debug(DEBUG_WARNING) << "pam_setcred FAIL" << endl; + throw error(PAM, pam_strerror(pam_status)); + } + + log_debug(DEBUG_NOTICE) << "pam_setcred OK" << endl; +} + +void +auth::cred_delete () +{ + assert(this->pam != 0); // PAM must be initialised + + int pam_status; + + if ((pam_status = + pam_setcred(this->pam, PAM_DELETE_CRED)) != PAM_SUCCESS) + { + log_debug(DEBUG_WARNING) << "pam_setcred (delete) FAIL" << endl; + throw error(PAM, pam_strerror(pam_status)); + } + + log_debug(DEBUG_NOTICE) << "pam_setcred (delete) OK" << endl; +} + +void +auth::open_session () +{ + assert(this->pam != 0); // PAM must be initialised + + int pam_status; + + if ((pam_status = + pam_open_session(this->pam, 0)) != PAM_SUCCESS) + { + log_debug(DEBUG_WARNING) << "pam_open_session FAIL" << endl; + throw error(PAM, pam_strerror(pam_status)); + } + + log_debug(DEBUG_NOTICE) << "pam_open_session OK" << endl; +} + +void +auth::close_session () +{ + assert(this->pam != 0); // PAM must be initialised + + int pam_status; + + if ((pam_status = + pam_close_session(this->pam, 0)) != PAM_SUCCESS) + { + log_debug(DEBUG_WARNING) << "pam_close_session FAIL" << endl; + throw error(PAM, pam_strerror(pam_status)); + } + + log_debug(DEBUG_NOTICE) << "pam_close_session OK" << endl; +} + +auth::status +auth::get_auth_status () const +{ + status authtype = STATUS_NONE; + + authtype = change_auth(authtype, STATUS_USER); + + return authtype; +} + +const char * +auth::pam_strerror (int pam_error) +{ + return ::pam_strerror (this->pam, pam_error); +} + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/sbuild/sbuild-auth.h b/sbuild/sbuild-auth.h new file mode 100644 index 00000000..9bea0c4f --- /dev/null +++ b/sbuild/sbuild-auth.h @@ -0,0 +1,478 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#ifndef SBUILD_AUTH_H +#define SBUILD_AUTH_H + +#include +#include +#include +#include +#include + +#include +#include + +#ifdef HAVE_TR1_MEMORY +#include +#elif HAVE_BOOST_SHARED_PTR_HPP +#include +namespace std { namespace tr1 { using boost::shared_ptr; } } +#else +#error A shared_ptr implementation is not available +#endif + +#include +#include +#include +#include +#include + +#include + +namespace sbuild +{ + + /** + * @brief Authentication handler. + * + * auth handles user authentication, authorisation and session + * management using the Pluggable authentication Modules (PAM) + * library. It is essentially an object-oriented wrapper around PAM. + * + * In order to use PAM correctly, it is important to call several of + * the methods in the correct order. For example, it is not possible + * to authorise a user before authenticating a user, and a session may + * not be started before either of these have occured. + * + * The correct order is + * - start + * - authenticate + * - setupenv + * - account + * - cred_establish + * - open_session + * + * After the session has finished, or if an error occured, the + * corresponding cleanup methods should be called + * - close_session + * - sbuild + * - cred_delete + * - stop + * + * The run method will handle all this. The run_impl virtual + * function should be used to provide a session handler to open and + * close the session for the user. open_session and close_session + * must still be used. + */ + class auth + { + public: + /// Authentication status + enum status + { + STATUS_NONE, ///< Authentication is not required. + STATUS_USER, ///< Authentication is required by the user. + STATUS_FAIL ///< Authentication has failed. + }; + + /// Message verbosity + enum verbosity + { + VERBOSITY_QUIET, ///< Only print essential messages. + VERBOSITY_NORMAL, ///< Print messages (the default). + VERBOSITY_VERBOSE ///< Print all messages. + }; + + /// Error codes. + enum error_code + { + HOSTNAME, ///< Failed to get hostname. + USER, ///< User not found. + AUTHENTICATION, ///< Authentication failed. + AUTHORISATION, ///< Authorisation failed. + PAM_DOUBLE_INIT, ///< PAM was already initialised. + PAM ///< PAM error. + }; + + /// Exception type. + typedef custom_error error; + + /// A shared_ptr to an auth_conv object. + typedef std::tr1::shared_ptr conv_ptr; + + /** + * The constructor. + * + * @param service_name the PAM service name. This should be a + * hard-coded constant string literal for safety and security. + * This is passed to pam_start() when initialising PAM, and is + * used to load the correct configuration file from /etc/pam.d. + */ + auth (std::string const& service_name); + + /** + * The destructor. + */ + virtual ~auth (); + + /** + * Get the PAM service name. + * + * @returns the service name. + */ + std::string const& + get_service () const; + + /** + * Get the uid of the user. This is the uid to run as in the * + * session. + * + * @returns a uid. This will be 0 if no user was set, or the user + * is uid 0. + */ + uid_t + get_uid () const; + + /** + * Get the gid of the user. This is the gid to run as in the + * session. + * + * @returns a gid. This will be 0 if no user was set, or the user + * is gid 0. + */ + gid_t + get_gid () const; + + /** + * Get the name of the user. This is the user to run as in the + * session. + * + * @returns the user's name. + */ + std::string const& + get_user () const; + + /** + * Set the name of the user. This is the user to run as in the + * session. + * + * As a side effect, the uid, gid, home and shell member variables + * will also be set, so calling the corresponding get methods will + * now return meaningful values. + * + * @param user the name to set. + */ + void + set_user (std::string const& user); + + /** + * Get the command to run in the session. + * + * @returns the command as string list, each item being a separate + * argument. If no command has been specified, the list will be + * empty. + */ + string_list const& + get_command () const; + + /** + * Set the command to run in the session. + * + * @param command the command to run. This is a string list, each + * item being a separate argument. + */ + void + set_command (string_list const& command); + + /** + * Get the home directory. This is the $HOME to set in the session, + * if the user environment is not being preserved. + * + * @returns the home directory. + */ + std::string const& + get_home () const; + + /** + * Get the name of the shell. This is the shell to run in the + * session. + * + * @returns the shell. This is typically a full pathname, though + * the executable name only should also work (the caller will have + * to search for it). + */ + std::string const& + get_shell () const; + + /** + * Get the environment to use in the session. + * + * @returns an environment list (a list of key-value pairs). + */ + environment const& + get_environment () const; + + /** + * Set the environment to use in the session. + * + * @param environment an environ- or envp-like string vector + * containing key=value pairs. + */ + void + set_environment (char **environment); + + /** + * Set the environment to use in the session. + * + * @param environment an environment list. + */ + void + set_environment (environment const& environment); + + /** + * Get the PAM environment. This is the environment as set by PAM + * modules. + * + * @returns an environment list. + */ + environment + get_pam_environment () const; + + /** + * Get the "remote uid" of the user. This is the uid which is + * requesting authentication. + * + * @returns a uid. + */ + uid_t + get_ruid () const; + + /** + * Get the "remote" name of the user. This is the user which is + * requesting authentication. + * + * @returns a user name. + */ + std::string const& + get_ruser () const; + + /** + * Get the message verbosity. + * + * Returns the verbosity level. + */ + verbosity + get_verbosity () const; + + /** + * Set the message verbosity. + * + * @param verbosity the verbosity level. + */ + void + set_verbosity (verbosity verbosity); + + /** + * Get the conversation handler. + * + * @returns a shared_ptr to the handler. + */ + conv_ptr& + get_conv (); + + /** + * Set the conversation handler. + * + * @param conv a shared_ptr to the handler. + */ + void + set_conv (conv_ptr& conv); + + /** + * Run a session. The user will be asked for authentication if + * required, and then the run_impl virtual method will be called. + * + * An error will be thrown on failure. + */ + void + run (); + + /** + * Start the PAM system. No other PAM functions may be called before + * calling this function. + * + * An error will be thrown on failure. + */ + void + start (); + + /** + * Stop the PAM system. No other PAM functions may be used after + * calling this function. + * + * An error will be thrown on failure. + */ + void + stop (); + + /** + * Perform PAM authentication. If required, the user will be + * prompted to authenticate themselves. + * + * An error will be thrown on failure. + */ + void + authenticate (); + + /** + * Import the user environment into PAM. If no environment was + * specified with set_environment, a minimal environment will be + * created containing HOME, LOGNAME, PATH, TERM and LOGNAME. + * + * An error will be thrown on failure. + */ + void + setupenv (); + + /** + * Do PAM account management (authorisation). + * + * An error will be thrown on failure. + */ + void + account (); + + /** + * Use PAM to establish credentials. + * + * An error will be thrown on failure. + */ + void + cred_establish (); + + /** + * Use PAM to delete credentials. + * + * An error will be thrown on failure. + */ + void + cred_delete (); + + /** + * Open a PAM session. + * + * An error will be thrown on failure. + */ + void + open_session (); + + /** + * Close a PAM session. + * + * An error will be thrown on failure. + */ + void + close_session (); + +protected: + /** + * Check if authentication is required. This default + * implementation always requires authentication. + */ + virtual status + get_auth_status () const; + + /** + * Run session. The code to run when authentication and + * authorisation have been completed. + */ + virtual void + run_impl () = 0; + + public: + /** + * Set new authentication status. If newauth > oldauth, newauth + * is returned, otherwise oldauth is returned. This is to ensure + * the authentication status can never be decreased (relaxed). + * + * @param oldauth the current authentication status. + * @param newauth the new authentication status. + * @returns the new authentication status. + */ + status + change_auth (status oldauth, + status newauth) const + { + /* Ensure auth level always escalates. */ + if (newauth > oldauth) + return newauth; + else + return oldauth; + } + + protected: + /// The PAM handle. + pam_handle_t *pam; + + /** + * Get a description of a PAM error. + * + * @param pam_error the PAM error number. + * @returns the description. + */ + const char * + pam_strerror (int pam_error); + + private: + /// The PAM service name. + const std::string service; + /// The uid to run as. + uid_t uid; + /// The gid to run as. + gid_t gid; + /// The user name to run as. + std::string user; + /// The command to run. + string_list command; + /// The home directory to run in. + std::string home; + /// The user shell to run. + std::string shell; + /// The user environment to set. + environment user_environment; + /// The uid requesting authentication. + uid_t ruid; + /// The user name requesting authentication. + std::string ruser; + /// The PAM conversation handler. + conv_ptr conv; + /// The message verbosity. + verbosity message_verbosity; + }; + +} + +#endif /* SBUILD_AUTH_H */ + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/sbuild/sbuild-chroot-block-device.cc b/sbuild/sbuild-chroot-block-device.cc new file mode 100644 index 00000000..0fca8020 --- /dev/null +++ b/sbuild/sbuild-chroot-block-device.cc @@ -0,0 +1,225 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#include + +#include "sbuild-chroot-block-device.h" +#include "sbuild-format-detail.h" +#include "sbuild-lock.h" + +#include +#include + +#include +#include +#include +#include + +#include + +using boost::format; +using namespace sbuild; + +chroot_block_device::chroot_block_device (): + chroot(), + device(), + mount_options() +{ +} + +chroot_block_device::~chroot_block_device () +{ +} + +sbuild::chroot::ptr +chroot_block_device::clone () const +{ + return ptr(new chroot_block_device(*this)); +} + +std::string const& +chroot_block_device::get_device () const +{ + return this->device; +} + +void +chroot_block_device::set_device (std::string const& device) +{ + this->device = device; +} + +std::string const& +chroot_block_device::get_mount_device () const +{ + return this->device; +} + +std::string const& +chroot_block_device::get_mount_options () const +{ + return this->mount_options; +} + +void +chroot_block_device::set_mount_options (std::string const& mount_options) +{ + this->mount_options = mount_options; +} + +std::string const& +chroot_block_device::get_location () const +{ + return chroot::get_location(); +} + +void +chroot_block_device::set_location (std::string const& location) +{ + chroot::set_location(location); +} + +std::string const& +chroot_block_device::get_chroot_type () const +{ + static const std::string type("block-device"); + + return type; +} + +void +chroot_block_device::setup_env (environment& env) +{ + this->chroot::setup_env(env); + + env.add("CHROOT_DEVICE", get_device()); + env.add("CHROOT_MOUNT_OPTIONS", get_mount_options()); +} + +void +chroot_block_device::setup_lock (setup_type type, + bool lock, + int status) +{ + struct stat statbuf; + + /* Only lock during setup, not run. */ + if (type == EXEC_START || type == EXEC_STOP) + return; + + /* Lock is preserved through the entire session. */ + if ((type == SETUP_START && lock == false) || + (type == SETUP_STOP && lock == true)) + return; + + if (stat(this->device.c_str(), &statbuf) == -1) + { + throw error(get_device(), DEVICE_STAT, errno); + } + else if (!S_ISBLK(statbuf.st_mode)) + { + throw error(get_device(), DEVICE_NOTBLOCK); + } + else + { + sbuild::device_lock dlock(this->device); + if (lock) + { + try + { + dlock.set_lock(lock::LOCK_EXCLUSIVE, 15); + } + catch (sbuild::lock::error const& e) + { + throw error(get_device(), DEVICE_LOCK, e.what()); + } + } + else + { + try + { + dlock.unset_lock(); + } + catch (sbuild::lock::error const& e) + { + throw error(get_device(), DEVICE_UNLOCK, e.what()); + } + } + } +} + +sbuild::chroot::session_flags +chroot_block_device::get_session_flags () const +{ + return static_cast(0); +} + +void +chroot_block_device::print_details (std::ostream& stream) const +{ + this->chroot::print_details(stream); + + if (!this->device.empty()) + stream << format_details(_("Device"), get_device()); + if (!this->mount_options.empty()) + stream << format_details(_("Mount Options"), get_mount_options()); + stream << std::flush; +} + +void +chroot_block_device::get_keyfile (keyfile& keyfile) const +{ + chroot::get_keyfile(keyfile); + + keyfile.set_value(get_name(), "device", + get_device()); + + keyfile.set_value(get_name(), "mount-options", + get_mount_options()); + + keyfile.set_value(get_name(), "location", + get_location()); +} + +void +chroot_block_device::set_keyfile (keyfile const& keyfile) +{ + chroot::set_keyfile(keyfile); + + std::string device; + if (keyfile.get_value(get_name(), "device", + keyfile::PRIORITY_REQUIRED, device)) + set_device(device); + + std::string mount_options; + if (keyfile.get_value(get_name(), "mount-options", + keyfile::PRIORITY_OPTIONAL, mount_options)) + set_mount_options(mount_options); + + std::string location; + if (keyfile.get_value(get_name(), "location", + keyfile::PRIORITY_OPTIONAL, location)) + set_location(location); +} + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/sbuild/sbuild-chroot-block-device.h b/sbuild/sbuild-chroot-block-device.h new file mode 100644 index 00000000..7cb8bbe6 --- /dev/null +++ b/sbuild/sbuild-chroot-block-device.h @@ -0,0 +1,142 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#ifndef SBUILD_CHROOT_BLOCK_DEVICE_H +#define SBUILD_CHROOT_BLOCK_DEVICE_H + +#include + +namespace sbuild +{ + + /** + * A chroot stored on an unmounted block device. The device will be + * mounted on demand. + */ + class chroot_block_device : virtual public chroot + { + protected: + /// The constructor. + chroot_block_device (); + + friend class chroot; + + public: + /// The destructor. + virtual ~chroot_block_device (); + + virtual chroot::ptr + clone () const; + + /** + * Get the block device of the chroot. + * + * @returns the device. + */ + std::string const& + get_device () const; + + /** + * Set the block device of the chroot. This is the "source" device. + * It may be the case that the real device is different (for + * example, an LVM snapshot PV), but by default will be the device + * to mount. + * + * @param device the device. + */ + void + set_device (std::string const& device); + + virtual std::string const& + get_mount_device () const; + + /** + * Get the filesystem mount_options of the chroot block device. + * + * @returns the mount options. + */ + std::string const& + get_mount_options () const; + + /** + * Set the filesystem mount_options of the chroot block device. + * + * @param mount_options the mount options. + */ + void + set_mount_options (std::string const& mount_options); + + /** + * Get the location. This is a path to the chroot directory + * inside the LV (absolute path from the LV root). + * + * @returns the location. + */ + virtual std::string const& + get_location () const; + + /** + * Set the location. This is a path to the chroot directory + * inside the LV (absolute path from the LV root). + * + * @param location the location. + */ + virtual void + set_location (std::string const& location); + + virtual std::string const& + get_chroot_type () const; + + virtual void + setup_env (environment& env); + + virtual session_flags + get_session_flags () const; + + protected: + virtual void + setup_lock (setup_type type, + bool lock, + int status); + + virtual void + print_details (std::ostream& stream) const; + + virtual void + get_keyfile (keyfile& keyfile) const; + + virtual void + set_keyfile (keyfile const& keyfile); + + private: + /// The block device to use. + std::string device; + /// The options to mount the device with. + std::string mount_options; + }; + +} + +#endif /* SBUILD_CHROOT_BLOCK_DEVICE_H */ + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/sbuild/sbuild-chroot-config.cc b/sbuild/sbuild-chroot-config.cc new file mode 100644 index 00000000..653c5027 --- /dev/null +++ b/sbuild/sbuild-chroot-config.cc @@ -0,0 +1,490 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#include + +#include "sbuild-chroot.h" +#include "sbuild-chroot-source.h" +#include "sbuild-chroot-config.h" +#include "sbuild-lock.h" + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include + +using std::endl; +using boost::format; +using namespace sbuild; + +namespace +{ + + typedef std::pair emap; + + /** + * This is a list of the supported error codes. It's used to + * construct the real error codes map. + */ + emap init_errors[] = + { + emap(chroot_config::DIR_OPEN, N_("Failed to open directory")), + emap(chroot_config::FILE_STAT, N_("Failed to stat file")), + emap(chroot_config::FILE_OPEN, N_("Failed to open file")), + emap(chroot_config::FILE_OWNER, N_("File is not owned by user root")), + emap(chroot_config::FILE_PERMS, N_("File has write permissions for others")), + emap(chroot_config::FILE_NOTREG, N_("File is not a regular file")) + }; + + bool chroot_alphasort (sbuild::chroot::ptr const& c1, + sbuild::chroot::ptr const& c2) + { + return c1->get_name() < c2->get_name(); + } + +} + +template<> +custom_error::map_type +custom_error::error_strings +(init_errors, + init_errors + (sizeof(init_errors) / sizeof(init_errors[0]))); + +chroot_config::chroot_config (): + chroots() +{ +} + +chroot_config::chroot_config (std::string const& file, + bool active): + chroots() +{ + add(file, active); +} + +chroot_config::~chroot_config () +{ +} + +void +chroot_config::add (std::string const& location, + bool active) +{ + struct stat statbuf; + if (stat(location.c_str(), &statbuf) == 0 && S_ISDIR(statbuf.st_mode)) + add_config_directory(location, active); + else + add_config_file(location, active); +} + +void +chroot_config::add_config_file (std::string const& file, + bool active) +{ + load_data(file, active); +} + +void +chroot_config::add_config_directory (std::string const& dir, + bool active) +{ + if (dir.empty()) + return; + + DIR *d = opendir(dir.c_str()); + if (d == NULL) + { + throw error(dir, DIR_OPEN, errno); + } + + struct dirent *de = NULL; + while ((de = readdir(d)) != NULL) + { + std::string filename = dir + "/" + de->d_name; + + struct stat statbuf; + if (stat(filename.c_str(), &statbuf) < 0) + { + error e(filename, FILE_STAT, errno); + log_warning() << e.what() << endl; + continue; + } + + if (!S_ISREG(statbuf.st_mode)) + { + if (!(strcmp(de->d_name, ".") == 0 || + strcmp(de->d_name, "..") == 0)) + { + error e (filename, FILE_NOTREG); + log_warning() << e.what() << endl; + } + continue; + } + + load_data(filename, active); + } +} + +void +chroot_config::add (chroot::ptr& chroot) +{ + // Make sure insertion will succeed. + if (this->chroots.find(chroot->get_name()) == this->chroots.end() && + this->aliases.find(chroot->get_name()) == this->aliases.end()) + { + // Set up chroot. + this->chroots.insert(std::make_pair(chroot->get_name(), chroot)); + this->aliases.insert(std::make_pair(chroot->get_name(), + chroot->get_name())); + + // Set up aliases. + string_list const& aliases = chroot->get_aliases(); + for (string_list::const_iterator pos = aliases.begin(); + pos != aliases.end(); + ++pos) + { + if (this->aliases.insert + (std::make_pair(*pos, chroot->get_name())) + .second == false) + { + string_map::const_iterator dup = this->aliases.find(*pos); + // Don't warn if alias is for chroot of same name. + if (dup != this->aliases.end()) + { + if (chroot->get_name() != dup->first) + log_warning() << + format(_("%1% chroot: " + "Alias '%2%' already associated with " + "'%3%' chroot")) + % chroot->get_name() % dup->first % dup->second + << endl; + } + else + log_warning() << + format(_("%1% chroot: " + "Alias '%2%' already associated with " + "another chroot")) + % chroot->get_name() % *pos + << endl; + } + } + } + else + { + log_warning() << format(_("%1% chroot: A chroot or alias already exists by this name")) + % chroot->get_name() + << endl; + log_warning() << format(_("%1% chroot: Duplicate names are not allowed")) + % chroot->get_name() + << endl; + } +} + +chroot_config::chroot_list +chroot_config::get_chroots () const +{ + chroot_list ret; + + for (chroot_map::const_iterator pos = this->chroots.begin(); + pos != this->chroots.end(); + ++pos) + ret.push_back(pos->second); + + std::sort(ret.begin(), ret.end(), chroot_alphasort); + + return ret; +} + +const sbuild::chroot::ptr +chroot_config::find_chroot (std::string const& name) const +{ + chroot_map::const_iterator pos = this->chroots.find(name); + + if (pos != this->chroots.end()) + return pos->second; + else + { + chroot *null_chroot = 0; + return chroot::ptr(null_chroot); + } +} + +const sbuild::chroot::ptr +chroot_config::find_alias (std::string const& name) const +{ + string_map::const_iterator pos = this->aliases.find(name); + + if (pos != this->aliases.end()) + return find_chroot(pos->second); + else + { + chroot *null_chroot = 0; + return chroot::ptr(null_chroot); + } +} + +string_list +chroot_config::get_chroot_list () const +{ + string_list ret; + + for (string_map::const_iterator pos = this->aliases.begin(); + pos != this->aliases.end(); + ++pos) + ret.push_back(pos->first); + + std::sort(ret.begin(), ret.end()); + + return ret; +} + +void +chroot_config::print_chroot_list (std::ostream& stream) const +{ + string_list chroots = get_chroot_list(); + + for (string_list::const_iterator pos = chroots.begin(); + pos != chroots.end(); + ++pos) + stream << *pos << "\n"; + stream << std::flush; +} + +void +chroot_config::print_chroot_list_simple (std::ostream& stream) const +{ + stream << _("Available chroots: "); + + for (chroot_map::const_iterator pos = this->chroots.begin(); + pos != this->chroots.end(); + ++pos) + { + stream << pos->second->get_name(); + string_list const& aliases = pos->second->get_aliases(); + if (!aliases.empty()) + { + stream << " ["; + for (string_list::const_iterator alias = aliases.begin(); + alias != aliases.end(); + ++alias) + { + stream << *alias; + if (alias + 1 != aliases.end()) + stream << ", "; + } + stream << ']'; + } + chroot_map::const_iterator is_end(pos); + if ((++is_end) != chroots.end()) + stream << ", "; + } + + stream << endl; +} + +void +chroot_config::print_chroot_info (string_list const& chroots, + std::ostream& stream) const +{ + for (string_list::const_iterator pos = chroots.begin(); + pos != chroots.end(); + ++pos) + { + const chroot::ptr chroot = find_alias(*pos); + if (chroot) + { + stream << chroot; + if (pos + 1 != chroots.end()) + stream << '\n'; + } + else + log_error() << format(_("%1%: No such chroot")) % *pos + << endl; + } +} + +void +chroot_config::print_chroot_location (string_list const& chroots, + std::ostream& stream) const +{ + for (string_list::const_iterator pos = chroots.begin(); + pos != chroots.end(); + ++pos) + { + const chroot::ptr chroot = find_alias(*pos); + if (chroot) + { + stream << chroot->get_path() << '\n'; + } + else + log_error() << format(_("%1%: No such chroot")) % *pos + << endl; + } + + stream << std::flush; +} + +void +chroot_config::print_chroot_config (string_list const& chroots, + std::ostream& stream) const +{ + keyfile info; + + for (string_list::const_iterator pos = chroots.begin(); + pos != chroots.end(); + ++pos) + { + const chroot::ptr chroot = find_alias(*pos); + if (chroot) + { + info << chroot; + } + else + log_error() << format(_("%1%: No such chroot")) % *pos + << endl; + } + + stream << info; +} + +string_list +chroot_config::validate_chroots (string_list const& chroots) const +{ + string_list bad_chroots; + + for (string_list::const_iterator pos = chroots.begin(); + pos != chroots.end(); + ++pos) + { + const chroot::ptr chroot = find_alias(*pos); + if (!chroot) + bad_chroots.push_back(*pos); + } + + return bad_chroots; +} + +void +chroot_config::load_data (std::string const& file, + bool active) +{ + /* Use a UNIX fd, for security (no races) */ + int fd = open(file.c_str(), O_RDONLY|O_NOFOLLOW); + if (fd < 0) + throw error(file, FILE_OPEN, errno); + + sbuild::file_lock lock(fd); + try + { + lock.set_lock(lock::LOCK_SHARED, 2); + } + catch (lock::error const& e) + { + throw error(file, e.what()); + } + + struct stat statbuf; + if (fstat(fd, &statbuf) < 0) + throw error(file, FILE_STAT, errno); + + if (statbuf.st_uid != 0) + throw error(file, FILE_OWNER); + if (statbuf.st_mode & S_IWOTH) + throw error(file, FILE_PERMS); + if (!S_ISREG(statbuf.st_mode)) + throw error(file, FILE_NOTREG); + + /* Now create an IO Channel and read in the data */ +#ifdef SCHROOT_FILEBUF_OLD + __gnu_cxx::stdio_filebuf fdbuf(fd, std::ios::in, true, BUFSIZ); +#else + __gnu_cxx::stdio_filebuf fdbuf(fd, std::ios::in); +#endif + std::istream input(&fdbuf); + input.imbue(std::locale("C")); + + try + { + parse_data(input, active); + } + catch (runtime_error const& e) + { + throw error(file, e.what()); + } + try + { + lock.unset_lock(); + } + catch (lock::error const& e) + { + throw error(file, e.what()); + } +} + +void +chroot_config::parse_data (std::istream& stream, + bool active) +{ + /* Create key file */ + keyfile kconfig(stream); + + /* Create chroot objects from key file */ + string_list const& groups = kconfig.get_groups(); + for (string_list::const_iterator group = groups.begin(); + group != groups.end(); + ++group) + { + // Set the active property for chroot creation, and create + // the chroot. + kconfig.set_value(*group, "active", active); + std::string type = "plain"; // "plain" is the default type. + kconfig.get_value(*group, "type", type); + chroot::ptr chroot = chroot::create(type); + chroot->set_name(*group); + kconfig >> chroot; + + add(chroot); + + { + chroot_source *source = dynamic_cast(chroot.get()); + if (source != 0 && !chroot->get_active()) + { + chroot::ptr source_chroot = source->clone_source(); + if (source_chroot) + add(source_chroot); + } + } + } +} + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/sbuild/sbuild-chroot-config.h b/sbuild/sbuild-chroot-config.h new file mode 100644 index 00000000..cd1cc31b --- /dev/null +++ b/sbuild/sbuild-chroot-config.h @@ -0,0 +1,276 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#ifndef SBUILD_CHROOT_CONFIG_H +#define SBUILD_CHROOT_CONFIG_H + +#include +#include + +#include +#include +#include +#include + +namespace sbuild +{ + + /** + * Chroot configuration. + * + * This class holds the configuration details from the configuration + * file. Conceptually, it's an opaque container of chroot objects. + * + * Methods are provided to query the available chroots and find + * specific chroots. + */ + class chroot_config + { + public: + /// A list of chroots. + typedef std::vector chroot_list; + /// A map between key-value string pairs. + typedef std::map string_map; + /// A map between a chroot name and a chroot object. + typedef std::map chroot_map; + + /// Error codes. + enum error_code + { + DIR_OPEN, ///< Failed to open directory. + FILE_STAT, ///< Failed to stat file. + FILE_OPEN, ///< Failed to open file. + FILE_OWNER, ///< File is not owned by user root. + FILE_PERMS, ///< File has write permissions for others. + FILE_NOTREG ///< File is not a regular file. + }; + + /// Exception type. + typedef custom_error error; + + /// A shared_ptr to a chroot_config object. + typedef std::tr1::shared_ptr ptr; + + /// The constructor. + chroot_config (); + + /** + * The constructor. + * + * @param file initialise using a configuration file or a whole + * directory containing configuration files. + * @param active true if the chroots in the configuration file are + * active sessions, otherwise false. + */ + chroot_config (std::string const& file, + bool active); + + /// The destructor. + virtual ~chroot_config (); + + /** + * Add a configuration file or directory. The configuration file + * or directory specified will be loaded. + * + * @param location initialise using a configuration file or a + * whole directory containing configuration files. + * @param active true if the chroots in the configuration file are + * active sessions, otherwise false. + */ + void + add (std::string const& location, + bool active); + + private: + /** + * Add a configuration file. The configuration file specified + * will be loaded. + * + * @param file the file to load. + * @param active true if the chroots in the configuration file are + * active sessions, otherwise false. + */ + void + add_config_file (std::string const& file, + bool active); + + /** + * Add a configuration directory. The configuration files in the + * directory specified will all be loaded. + * + * @param dir the directory containing the files to load. + * @param active true if the chroots in the configuration file are + * active sessions, otherwise false. + */ + void + add_config_directory (std::string const& dir, + bool active); + + protected: + /** + * Add a chroot. The lists of chroots and aliases will be + * updated. If a chroot or alias by the same name exists, the + * chroot will not be added, and a warning will be logged. Af any + * of the aliases already exist, a warning will be logged, and the + * alias will not be added. + * + * @param chroot the chroot to add. + */ + void + add (chroot::ptr& chroot); + + public: + /** + * Get a list of available chroots. + * + * @returns a list of available chroots. The list will be empty + * if no chroots are available. + */ + chroot_list + get_chroots () const; + + /** + * Find a chroot by its name. + * + * @param name the chroot name + * @returns the chroot if found, otherwise 0. + */ + const chroot::ptr + find_chroot (std::string const& name) const; + + /** + * Find a chroot by its name or an alias. + * + * @param name the chroot name or alias. + * @returns the chroot if found, otherwise 0. + */ + const chroot::ptr + find_alias (std::string const& name) const; + + /** + * Get the names (including aliases) of all the available chroots, + * sorted in alphabetical order. + * + * @returns the list. The list will be empty if no chroots are + * available. + */ + string_list + get_chroot_list () const; + + /** + * Print all the available chroots to the specified stream. + * + * @param stream the stream to output to. + */ + void + print_chroot_list (std::ostream& stream) const; + + /** + * Print a single line of all the available chroots to the + * specified stream. + * + * @param stream the stream to output to. + */ + void + print_chroot_list_simple (std::ostream& stream) const; + + /** + * Print information about the specified chroots to the specified + * stream. + * + * @param chroots a list of chroots to print. + * @param stream the stream to output to. + */ + void + print_chroot_info (string_list const& chroots, + std::ostream& stream) const; + + /** + * Print location information about the specified chroots to the + * specified stream. + * + * @param chroots a list of chroots to print. + * @param stream the stream to output to. + */ + void + print_chroot_location (string_list const& chroots, + std::ostream& stream) const; + + /** + * Print configuration of the specified chroots to the specified + * stream. + * + * @param chroots a list of chroots to print. + * @param stream the stream to output to. + */ + void + print_chroot_config (string_list const& chroots, + std::ostream& stream) const; + + /** + * Check that all the chroots specified exist. + * + * @param chroots a list of chroots to validate. + * @returns a list of invalid chroots. The list will be empty if + * all chroots are valid. + */ + string_list + validate_chroots (string_list const& chroots) const; + + private: + /** + * Load a configuration file. If there are problems with the + * configuration file, an error will be thrown. The file must be + * owned by root, not writable by other, and be a regular file. + * + * @param file the file to load. + * @param active true if the chroots in the configuration file are + * active sessions, otherwise false. + */ + void + load_data (std::string const& file, + bool active); + + /** + * Parse a loaded configuration file. If there are problems with + * the configuration file, an error will be thrown. + * + * @param stream the data stream to parse. + * @param active true if the chroots in the configuration file are + * active sessions, otherwise false. + */ + virtual void + parse_data (std::istream& stream, + bool active); + + /// A list of chroots (name->chroot mapping). + chroot_map chroots; + /// A list of aliases (alias->name mapping). + string_map aliases; + }; + +} + +#endif /* SBUILD_CHROOT_CONFIG_H */ + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/sbuild/sbuild-chroot-file.cc b/sbuild/sbuild-chroot-file.cc new file mode 100644 index 00000000..27b6601a --- /dev/null +++ b/sbuild/sbuild-chroot-file.cc @@ -0,0 +1,185 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#include + +#include "sbuild-chroot-file.h" +#include "sbuild-format-detail.h" +#include "sbuild-lock.h" + +#include +#include + +#include +#include +#include +#include + +#include + +using boost::format; +using namespace sbuild; + +chroot_file::chroot_file (): + chroot(), + chroot_source(), + file(), + repack(false) +{ + set_run_setup_scripts(true); + set_run_exec_scripts(true); +} + +chroot_file::~chroot_file () +{ +} + +sbuild::chroot::ptr +chroot_file::clone () const +{ + return ptr(new chroot_file(*this)); +} + +sbuild::chroot::ptr +chroot_file::clone_source () const +{ + chroot_file *clone_file = new chroot_file(*this); + ptr clone(clone_file); + + chroot_source::clone_source_setup(clone); + clone_file->repack = true; + + return clone; +} + +std::string const& +chroot_file::get_file () const +{ + return this->file; +} + +void +chroot_file::set_file (std::string const& file) +{ + this->file = file; +} + +std::string const& +chroot_file::get_chroot_type () const +{ + static const std::string type("file"); + + return type; +} + +void +chroot_file::setup_env (environment& env) +{ + chroot::setup_env(env); + chroot_source::setup_env(env); + + env.add("CHROOT_FILE", get_file()); + env.add("CHROOT_FILE_REPACK", this->repack); +} + +void +chroot_file::setup_lock (setup_type type, + bool lock, + int status) +{ + // Check ownership and permissions. + if (type == SETUP_START && lock == true) + { + struct stat statbuf; + if (stat(this->file.c_str(), &statbuf) < 0) + throw error(this->file, FILE_STAT, errno); + + // NOTE: taken from chroot_config::check_security. + if (statbuf.st_uid != 0) + throw error(this->file, FILE_OWNER); + if (statbuf.st_mode & S_IWOTH) + throw error(this->file, FILE_PERMS); + if (!S_ISREG(statbuf.st_mode)) + throw error(this->file, FILE_NOTREG); + } + + /* By default, file chroots do no locking. */ + /* Create or unlink session information. */ + if ((type == SETUP_START && lock == true) || + (type == SETUP_STOP && lock == false && status == 0)) + { + + bool start = (type == SETUP_START); + setup_session_info(start); + } +} + +sbuild::chroot::session_flags +chroot_file::get_session_flags () const +{ + return SESSION_CREATE; +} + +void +chroot_file::print_details (std::ostream& stream) const +{ + chroot::print_details(stream); + chroot_source::print_details(stream); + + if (!this->file.empty()) + stream << format_details(_("File"), get_file()); + stream << format_details(_("File Repack"), this->repack); + stream << std::flush; +} + +void +chroot_file::get_keyfile (keyfile& keyfile) const +{ + chroot::get_keyfile(keyfile); + chroot_source::get_keyfile(keyfile); + + keyfile.set_value(get_name(), "file", + get_file()); + + keyfile.set_value(get_name(), "file-repack", + this->repack); +} + +void +chroot_file::set_keyfile (keyfile const& keyfile) +{ + chroot::set_keyfile(keyfile); + chroot_source::set_keyfile(keyfile); + + std::string file; + if (keyfile.get_value(get_name(), "file", + keyfile::PRIORITY_REQUIRED, file)) + set_file(file); + + keyfile.get_value(get_name(), "file-repack", + get_active() ? + keyfile::PRIORITY_REQUIRED : keyfile::PRIORITY_DISALLOWED, + this->repack); +} + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/sbuild/sbuild-chroot-file.h b/sbuild/sbuild-chroot-file.h new file mode 100644 index 00000000..8c398075 --- /dev/null +++ b/sbuild/sbuild-chroot-file.h @@ -0,0 +1,107 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#ifndef SBUILD_CHROOT_FILE_H +#define SBUILD_CHROOT_FILE_H + +#include +#include + +namespace sbuild +{ + + /** + * A chroot stored in a file archive (tar or zip). The archive will + * be unpacked on demand. + */ + class chroot_file : virtual public chroot, + public chroot_source + { + protected: + /// The constructor. + chroot_file (); + + friend class chroot; + + public: + /// The destructor. + virtual ~chroot_file (); + + virtual chroot::ptr + clone () const; + + virtual chroot::ptr + clone_source () const; + + /** + * Get the file used by the chroot. + * + * @returns the file. + */ + std::string const& + get_file () const; + + /** + * Set the file used by the chroot. + * + * @param file the file. + */ + void + set_file (std::string const& file); + + virtual std::string const& + get_chroot_type () const; + + virtual void + setup_env (environment& env); + + virtual session_flags + get_session_flags () const; + + protected: + virtual void + setup_lock (setup_type type, + bool lock, + int status); + + virtual void + print_details (std::ostream& stream) const; + + virtual void + get_keyfile (keyfile& keyfile) const; + + virtual void + set_keyfile (keyfile const& keyfile); + + private: + /// The file to use. + std::string file; + /// Should the chroot be repacked? + bool repack; + }; + +} + +#endif /* SBUILD_CHROOT_FILE_H */ + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/sbuild/sbuild-chroot-lvm-snapshot.cc b/sbuild/sbuild-chroot-lvm-snapshot.cc new file mode 100644 index 00000000..b7bca908 --- /dev/null +++ b/sbuild/sbuild-chroot-lvm-snapshot.cc @@ -0,0 +1,248 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#include + +#include "sbuild-chroot-lvm-snapshot.h" +#include "sbuild-format-detail.h" +#include "sbuild-lock.h" + +#include +#include + +#include +#include +#include +#include + +#include + +using std::endl; +using boost::format; +using namespace sbuild; + +chroot_lvm_snapshot::chroot_lvm_snapshot (): + chroot_block_device(), + chroot_source(), + snapshot_device(), + snapshot_options() +{ + set_run_setup_scripts(true); + set_run_exec_scripts(true); +} + +chroot_lvm_snapshot::~chroot_lvm_snapshot () +{ +} + +sbuild::chroot::ptr +chroot_lvm_snapshot::clone () const +{ + return ptr(new chroot_lvm_snapshot(*this)); +} + +sbuild::chroot::ptr +chroot_lvm_snapshot::clone_source () const +{ + ptr clone(new chroot_block_device(*this)); + + chroot_source::clone_source_setup(clone); + + return clone; +} + +std::string const& +chroot_lvm_snapshot::get_snapshot_device () const +{ + return this->snapshot_device; +} + +void +chroot_lvm_snapshot::set_snapshot_device (std::string const& snapshot_device) +{ + this->snapshot_device = snapshot_device; +} + +std::string const& +chroot_lvm_snapshot::get_mount_device () const +{ + return this->snapshot_device; +} + +std::string const& +chroot_lvm_snapshot::get_snapshot_options () const +{ + return this->snapshot_options; +} + +void +chroot_lvm_snapshot::set_snapshot_options (std::string const& snapshot_options) +{ + this->snapshot_options = snapshot_options; +} + +std::string const& +chroot_lvm_snapshot::get_chroot_type () const +{ + static const std::string type("lvm-snapshot"); + + return type; +} + +void +chroot_lvm_snapshot::setup_env (environment& env) +{ + chroot_block_device::setup_env(env); + chroot_source::setup_env(env); + + env.add("CHROOT_LVM_SNAPSHOT_NAME", sbuild::basename(get_snapshot_device())); + env.add("CHROOT_LVM_SNAPSHOT_DEVICE", get_snapshot_device()); + env.add("CHROOT_LVM_SNAPSHOT_OPTIONS", get_snapshot_options()); +} + +void +chroot_lvm_snapshot::setup_lock (setup_type type, + bool lock, + int status) +{ + std::string device; + struct stat statbuf; + + /* Lock is removed by setup script on setup stop. Unlocking here + would fail: the LVM snapshot device no longer exists. */ + if (!(type == SETUP_STOP && lock == false)) + { + if (type == SETUP_START) + device = get_device(); + else + device = get_snapshot_device(); + + if (device.empty()) + { + throw error(CHROOT_DEVICE); + } + else if (stat(device.c_str(), &statbuf) == -1) + { + throw error(get_device(), DEVICE_STAT, errno); + } + else if (!S_ISBLK(statbuf.st_mode)) + { + throw error(get_device(), DEVICE_NOTBLOCK); + } + else + { + /* Lock is preserved while running a command. */ + if ((type == EXEC_START && lock == false) || + (type == EXEC_STOP && lock == true)) + return; + + sbuild::device_lock dlock(device); + if (lock) + { + try + { + dlock.set_lock(lock::LOCK_EXCLUSIVE, 15); + } + catch (sbuild::lock::error const& e) + { + throw error(get_device(), DEVICE_LOCK, e.what()); + } + } + else + { + try + { + dlock.unset_lock(); + } + catch (sbuild::lock::error const& e) + { + throw error(get_device(), DEVICE_UNLOCK, e.what()); + } + } + } + } + + /* Create or unlink session information. */ + if ((type == SETUP_START && lock == true) || + (type == SETUP_STOP && lock == false && status == 0)) + { + bool start = (type == SETUP_START); + setup_session_info(start); + } +} + +sbuild::chroot::session_flags +chroot_lvm_snapshot::get_session_flags () const +{ + return SESSION_CREATE; +} + +void +chroot_lvm_snapshot::print_details (std::ostream& stream) const +{ + chroot_block_device::print_details(stream); + chroot_source::print_details(stream); + + if (!this->snapshot_device.empty()) + stream << format_details(_("LVM Snapshot Device"), + get_snapshot_device()); + if (!this->snapshot_options.empty()) + stream << format_details(_("LVM Snapshot Options"), + get_snapshot_options()); + stream << std::flush; +} + +void +chroot_lvm_snapshot::get_keyfile (keyfile& keyfile) const +{ + chroot_block_device::get_keyfile(keyfile); + chroot_source::get_keyfile(keyfile); + + keyfile.set_value(get_name(), "lvm-snapshot-device", + get_snapshot_device()); + + keyfile.set_value(get_name(), "lvm-snapshot-options", + get_snapshot_options()); +} + +void +chroot_lvm_snapshot::set_keyfile (keyfile const& keyfile) +{ + chroot_block_device::set_keyfile(keyfile); + chroot_source::set_keyfile(keyfile); + + std::string snapshot_device; + if (keyfile.get_value(get_name(), "lvm-snapshot-device", + get_active() ? + keyfile::PRIORITY_REQUIRED : + keyfile::PRIORITY_DISALLOWED, + snapshot_device)) + set_snapshot_device(snapshot_device); + + std::string snapshot_options; + if (keyfile.get_value(get_name(), "lvm-snapshot-options", + keyfile::PRIORITY_REQUIRED, snapshot_options)) + set_snapshot_options(snapshot_options); +} + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/sbuild/sbuild-chroot-lvm-snapshot.h b/sbuild/sbuild-chroot-lvm-snapshot.h new file mode 100644 index 00000000..6340c54a --- /dev/null +++ b/sbuild/sbuild-chroot-lvm-snapshot.h @@ -0,0 +1,130 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#ifndef SBUILD_CHROOT_LVM_SNAPSHOT_H +#define SBUILD_CHROOT_LVM_SNAPSHOT_H + +#include +#include + +namespace sbuild +{ + + /** + * A chroot stored on an LVM logical volume (LV). A snapshot LV + * will be created and mounted on demand. + */ + class chroot_lvm_snapshot : public chroot_block_device, + public chroot_source + { + protected: + /// The constructor. + chroot_lvm_snapshot (); + + friend class chroot; + + public: + /// The destructor. + virtual ~chroot_lvm_snapshot (); + + virtual chroot::ptr + clone () const; + + virtual chroot::ptr + clone_source () const; + + /** + * Get the logical volume snapshot device name. This is used by + * lvcreate. + * + * @returns the device name. + */ + std::string const& + get_snapshot_device () const; + + /** + * Set the logical volume snapshot device name. This is used by + * lvcreate. + * + * @param snapshot_device the device name. + */ + void + set_snapshot_device (std::string const& snapshot_device); + + virtual std::string const& + get_mount_device () const; + + /** + * Get the logical volume snapshot options. These are used by + * lvcreate. + * + * @returns the options. + */ + std::string const& + get_snapshot_options () const; + + /** + * Set the logical volume snapshot options. These are used by + * lvcreate. + * + * @param snapshot_options the options. + */ + void + set_snapshot_options (std::string const& snapshot_options); + + virtual std::string const& + get_chroot_type () const; + + virtual void + setup_env (environment& env); + + virtual session_flags + get_session_flags () const; + + protected: + virtual void + setup_lock (setup_type type, + bool lock, + int status); + + virtual void + print_details (std::ostream& stream) const; + + virtual void + get_keyfile (keyfile& keyfile) const; + + virtual void + set_keyfile (keyfile const& keyfile); + + private: + /// LVM snapshot device name for lvcreate. + std::string snapshot_device; + /// LVM snapshot options for lvcreate. + std::string snapshot_options; + }; + +} + +#endif /* SBUILD_CHROOT_LVM_SNAPSHOT_H */ + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/sbuild/sbuild-chroot-plain.cc b/sbuild/sbuild-chroot-plain.cc new file mode 100644 index 00000000..37d25296 --- /dev/null +++ b/sbuild/sbuild-chroot-plain.cc @@ -0,0 +1,148 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#include + +#include "sbuild-chroot-plain.h" +#include "sbuild-format-detail.h" +#include "sbuild-lock.h" + +#include + +#include +#include +#include +#include + +using namespace sbuild; + +chroot_plain::chroot_plain (): + chroot() +{ +} + +chroot_plain::~chroot_plain () +{ +} + +sbuild::chroot::ptr +chroot_plain::clone () const +{ + return ptr(new chroot_plain(*this)); +} + +std::string const& +chroot_plain::get_location () const +{ + return chroot::get_location(); +} + +void +chroot_plain::set_location (std::string const& location) +{ + chroot::set_location(location); +} + +std::string +chroot_plain::get_path () const +{ + // When running setup scripts, we are session-capable, so the path + // is the bind-mounted location, rather than the original location. + if (get_run_setup_scripts() == true) + return get_mount_location(); + else + return get_location(); +} + +std::string const& +chroot_plain::get_chroot_type () const +{ + static const std::string type("plain"); + + return type; +} + +void +chroot_plain::setup_env (environment& env) +{ + this->chroot::setup_env(env); + + env.add("CHROOT_LOCATION", get_location()); +} + +void +chroot_plain::setup_lock (setup_type type, + bool lock, + int status) +{ + /* By default, plain chroots do no locking. */ + /* Create or unlink session information. */ + if (get_run_setup_scripts() == true) + { + if ((type == SETUP_START && lock == true) || + (type == SETUP_STOP && lock == false && status == 0)) + { + bool start = (type == SETUP_START); + setup_session_info(start); + } + } +} + +sbuild::chroot::session_flags +chroot_plain::get_session_flags () const +{ + if (get_run_setup_scripts() == true) + return SESSION_CREATE; + else + return static_cast(0); +} + +void +chroot_plain::print_details (std::ostream& stream) const +{ + this->chroot::print_details(stream); + + stream << std::flush; +} + +void +chroot_plain::get_keyfile (keyfile& keyfile) const +{ + chroot::get_keyfile(keyfile); + + keyfile.set_value(get_name(), "location", + get_location()); +} + +void +chroot_plain::set_keyfile (keyfile const& keyfile) +{ + chroot::set_keyfile(keyfile); + + std::string location; + if (keyfile.get_value(get_name(), "location", + keyfile::PRIORITY_REQUIRED, location)) + set_location(location); +} + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/sbuild/sbuild-chroot-plain.h b/sbuild/sbuild-chroot-plain.h new file mode 100644 index 00000000..5d4546a0 --- /dev/null +++ b/sbuild/sbuild-chroot-plain.h @@ -0,0 +1,98 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#ifndef SBUILD_CHROOT_PLAIN_H +#define SBUILD_CHROOT_PLAIN_H + +#include + +namespace sbuild +{ + + /** + * A chroot located on a mounted filesystem. + */ + class chroot_plain : virtual public chroot + { + protected: + /// The constructor. + chroot_plain (); + + friend class chroot; + + public: + /// The destructor. + virtual ~chroot_plain (); + + virtual chroot::ptr + clone () const; + + /** + * Get the directory location of the chroot. + * + * @returns the location. + */ + virtual std::string const& + get_location () const; + + /** + * Set the directory location of the chroot. + * + * @param location the location. + */ + virtual void + set_location (std::string const& location); + + virtual std::string + get_path () const; + + virtual std::string const& + get_chroot_type () const; + + virtual void + setup_env (environment& env); + + virtual session_flags + get_session_flags () const; + + protected: + virtual void + setup_lock (setup_type type, + bool lock, + int status); + + virtual void + print_details (std::ostream& stream) const; + + virtual void + get_keyfile (keyfile& keyfile) const; + + virtual void + set_keyfile (keyfile const& keyfile); + }; + +} + +#endif /* SBUILD_CHROOT_PLAIN_H */ + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/sbuild/sbuild-chroot-source.cc b/sbuild/sbuild-chroot-source.cc new file mode 100644 index 00000000..beb96774 --- /dev/null +++ b/sbuild/sbuild-chroot-source.cc @@ -0,0 +1,175 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#include + +#include "sbuild-chroot-source.h" +#include "sbuild-format-detail.h" +#include "sbuild-lock.h" + +#include + +#include + +using boost::format; +using namespace sbuild; + +chroot_source::chroot_source (): + chroot() +{ +} + +chroot_source::~chroot_source () +{ +} + +void +chroot_source::clone_source_setup (chroot::ptr& clone) const +{ + clone->set_name(clone->get_name() + "-source"); + clone->set_description + (clone->get_description() + ' ' + _("(source chroot)")); + clone->set_users(this->get_source_users()); + clone->set_groups(this->get_source_groups()); + clone->set_root_users(this->get_source_root_users()); + clone->set_root_groups(this->get_source_root_groups()); + string_list const& aliases = clone->get_aliases(); + string_list source_aliases; + for (string_list::const_iterator alias = aliases.begin(); + alias != aliases.end(); + ++alias) + source_aliases.push_back(*alias + "-source"); + clone->set_aliases(source_aliases); +} + +string_list const& +chroot_source::get_source_users () const +{ + return this->source_users; +} + +void +chroot_source::set_source_users (string_list const& source_users) +{ + this->source_users = source_users; +} + +string_list const& +chroot_source::get_source_groups () const +{ + return this->source_groups; +} + +void +chroot_source::set_source_groups (string_list const& source_groups) +{ + this->source_groups = source_groups; +} + +string_list const& +chroot_source::get_source_root_users () const +{ + return this->source_root_users; +} + +void +chroot_source::set_source_root_users (string_list const& users) +{ + this->source_root_users = users; +} + +string_list const& +chroot_source::get_source_root_groups () const +{ + return this->source_root_groups; +} + +void +chroot_source::set_source_root_groups (string_list const& groups) +{ + this->source_root_groups = groups; +} + +void +chroot_source::setup_env (environment& env) +{ +} + +void +chroot_source::print_details (std::ostream& stream) const +{ + stream << format_details(_("Source Users"), get_source_users()) + << format_details(_("Source Groups"), get_source_groups()) + << format_details(_("Source Root Users"), get_source_root_users()) + << format_details(_("Source Root Groups"), get_source_root_groups()); +} + +void +chroot_source::get_keyfile (keyfile& keyfile) const +{ + string_list const& source_users = get_source_users(); + keyfile.set_list_value(get_name(), "source-users", + source_users.begin(), source_users.end()); + + string_list const& source_groups = get_source_groups(); + keyfile.set_list_value(get_name(), "source-groups", + source_groups.begin(), source_groups.end()); + + string_list const& source_root_groups = get_source_root_groups(); + keyfile.set_list_value(get_name(), "source-root-groups", + source_root_groups.begin(), source_root_groups.end()); + + string_list const& source_root_users = get_source_root_users(); + keyfile.set_list_value(get_name(), "source-root-users", + source_root_users.begin(), source_root_users.end()); +} + +void +chroot_source::set_keyfile (keyfile const& keyfile) +{ + string_list source_users; + if (keyfile.get_list_value(get_name(), "source-users", + keyfile::PRIORITY_OPTIONAL, + source_users)) + set_source_users(source_users); + + string_list source_groups; + if (keyfile.get_list_value(get_name(), "source-groups", + keyfile::PRIORITY_OPTIONAL, + source_groups)) + set_source_groups(source_groups); + + string_list source_root_users; + if (keyfile.get_list_value(get_name(), "source-root-users", + keyfile::PRIORITY_OPTIONAL, + source_root_users)) + set_source_root_users(source_root_users); + + string_list source_root_groups; + if (keyfile.get_list_value(get_name(), "source-root-groups", + keyfile::PRIORITY_OPTIONAL, + source_root_groups)) + set_source_root_groups(source_root_groups); +} + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/sbuild/sbuild-chroot-source.h b/sbuild/sbuild-chroot-source.h new file mode 100644 index 00000000..3436e9c3 --- /dev/null +++ b/sbuild/sbuild-chroot-source.h @@ -0,0 +1,172 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#ifndef SBUILD_CHROOT_SOURCE_H +#define SBUILD_CHROOT_SOURCE_H + +#include + +namespace sbuild +{ + + /** + * A chroot may offer a "source" chroot in addition to its normal + * "session" copy, to allow for maintenence of the source data. + * This interface may be implemented by any chroot wishing to + * provide such functionality. + * + * While this is effectively an interface, in practice this derives + * from sbuild::chroot, to allow setting and getting of data from a + * keyfile, including storing the keyfile options. + * + * Chroot types implementing chroot_source should, at a minimum, + * implement clone_source(). This should create and return a source + * chroot, and must call clone_source_setup() to set up the source + * chroot. + */ + class chroot_source : virtual public chroot + { + protected: + /// The constructor. + chroot_source (); + + friend class chroot; + + public: + /// The destructor. + virtual ~chroot_source (); + + virtual chroot::ptr + clone_source () const = 0; + + protected: + /** + * Set the defaults in the cloned source chroot. + * + * @param clone the chroot to set up. + */ + void + clone_source_setup (chroot::ptr& clone) const; + + public: + /** + * Get the users allowed to access the source chroot. + * + * @returns a list of users. + */ + virtual string_list const& + get_source_users () const; + + /** + * Set the users allowed to access the source chroot. + * + * @param users a list of users. + */ + virtual void + set_source_users (string_list const& users); + + /** + * Get the groups allowed to access the source chroot. + * + * @returns a list of groups. + */ + virtual string_list const& + get_source_groups () const; + + /** + * Set the groups allowed to access the source chroot. + * + * @param groups a list of groups. + */ + virtual void + set_source_groups (string_list const& groups); + + /** + * Get the users allowed to access the source chroot as root. + * Mmebers of these users can switch to root without + * authenticating themselves. + * + * @returns a list of users. + */ + virtual string_list const& + get_source_root_users () const; + + /** + * Set the users allowed to access the source chroot as root. + * Mmebers of these users can switch to root without + * authenticating themselves. + * + * @param users a list of users. + */ + virtual void + set_source_root_users (string_list const& users); + + /** + * Get the groups allowed to access the source chroot as root. + * Mmebers of these groups can switch to root without + * authenticating themselves. + * + * @returns a list of groups. + */ + virtual string_list const& + get_source_root_groups () const; + + /** + * Set the groups allowed to access the source chroot as root. + * Mmebers of these groups can switch to root without + * authenticating themselves. + * + * @param groups a list of groups. + */ + virtual void + set_source_root_groups (string_list const& groups); + + void + setup_env (environment& env); + + protected: + void + print_details (std::ostream& stream) const; + + void + get_keyfile (keyfile& keyfile) const; + + void + set_keyfile (keyfile const& keyfile); + + private: + /// Users allowed to access the source chroot. + string_list source_users; + /// Groups allowed to access the source chroot. + string_list source_groups; + /// Users allowed to access the source chroot as root. + string_list source_root_users; + /// Groups allowed to access the source chroot as root. + string_list source_root_groups; + }; + +} + +#endif /* SBUILD_CHROOT_SOURCE_H */ + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/sbuild/sbuild-chroot.cc b/sbuild/sbuild-chroot.cc new file mode 100644 index 00000000..27d5ae69 --- /dev/null +++ b/sbuild/sbuild-chroot.cc @@ -0,0 +1,622 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#include + +#include "sbuild-chroot.h" +#include "sbuild-chroot-plain.h" +#include "sbuild-chroot-file.h" +#include "sbuild-chroot-block-device.h" +#include "sbuild-chroot-lvm-snapshot.h" +#include "sbuild-format-detail.h" +#include "sbuild-lock.h" + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include + +using boost::format; +using namespace sbuild; + +namespace +{ + + typedef std::pair emap; + + /** + * This is a list of the supported error codes. It's used to + * construct the real error codes map. + */ + emap init_errors[] = + { + emap(sbuild::chroot::CHROOT_TYPE, N_("Unknown chroot type")), + emap(sbuild::chroot::CHROOT_CREATE, N_("Chroot creation failed")), + emap(sbuild::chroot::CHROOT_DEVICE, N_("Device name not set")), + emap(sbuild::chroot::SESSION_WRITE, N_("Failed to write session file")), + emap(sbuild::chroot::SESSION_UNLINK, N_("Failed to unlink session file")), + emap(sbuild::chroot::FILE_STAT, N_("Failed to stat file")), + emap(sbuild::chroot::FILE_OWNER, N_("File is not owned by user root")), + emap(sbuild::chroot::FILE_PERMS, N_("File has write permissions for others")), + emap(sbuild::chroot::FILE_NOTREG, N_("File is not a regular file")), + emap(sbuild::chroot::FILE_LOCK, N_("Failed to acquire file lock")), + emap(sbuild::chroot::FILE_UNLOCK, N_("Failed to discard file lock")), + emap(sbuild::chroot::DEVICE_STAT, N_("Failed to stat device")), + emap(sbuild::chroot::DEVICE_NOTBLOCK, N_("File is not a block device")), + emap(sbuild::chroot::DEVICE_LOCK, N_("Failed to lock device")), + emap(sbuild::chroot::DEVICE_UNLOCK, N_("Failed to unlock device")) + }; + +} + +template<> +custom_error::map_type +custom_error::error_strings +(init_errors, + init_errors + (sizeof(init_errors) / sizeof(init_errors[0]))); + +sbuild::chroot::chroot (): + name(), + description(), + priority(0), + users(), + groups(), + root_users(), + root_groups(), + aliases(), + mount_location(), + location(), + mount_device(), + active(false), + run_setup_scripts(false), + run_exec_scripts(false), + command_prefix(), + persona( +#ifdef __linux__ + personality("linux") +#else + personality("undefined") +#endif + ) +{ +} + +sbuild::chroot::~chroot () +{ +} + +sbuild::chroot::ptr +sbuild::chroot::create (std::string const& type) +{ + chroot *new_chroot = 0; + + if (type == "plain") + new_chroot = new chroot_plain(); + else if (type == "file") + new_chroot = new chroot_file(); + else if (type == "block-device") + new_chroot = new chroot_block_device(); + else if (type == "lvm-snapshot") + new_chroot = new chroot_lvm_snapshot(); + else + throw error(type, CHROOT_TYPE); + + if (new_chroot == 0) + throw error(CHROOT_CREATE); + + return ptr(new_chroot); +} + +std::string const& +sbuild::chroot::get_name () const +{ + return this->name; +} + +void +sbuild::chroot::set_name (std::string const& name) +{ + this->name = name; +} + +std::string const& +sbuild::chroot::get_description () const +{ + return this->description; +} + +void +sbuild::chroot::set_description (std::string const& description) +{ + this->description = description; +} + +std::string const& +sbuild::chroot::get_mount_location () const +{ + return this->mount_location; +} + +void +sbuild::chroot::set_mount_location (std::string const& location) +{ + this->mount_location = location; +} + +std::string const& +sbuild::chroot::get_location () const +{ + return this->location; +} + +void +sbuild::chroot::set_location (std::string const& location) +{ + this->location = location; +} + +std::string +sbuild::chroot::get_path () const +{ + return get_mount_location() + get_location(); +} + +std::string const& +sbuild::chroot::get_mount_device () const +{ + return this->mount_device; +} + +void +sbuild::chroot::set_mount_device (std::string const& device) +{ + this->mount_device = device; +} + +unsigned int +sbuild::chroot::get_priority () const +{ + return this->priority; +} + +void +sbuild::chroot::set_priority (unsigned int priority) +{ + this->priority = priority; +} + +string_list const& +sbuild::chroot::get_users () const +{ + return this->users; +} + +void +sbuild::chroot::set_users (string_list const& users) +{ + this->users = users; +} + +string_list const& +sbuild::chroot::get_groups () const +{ + return this->groups; +} + +void +sbuild::chroot::set_groups (string_list const& groups) +{ + this->groups = groups; +} + +string_list const& +sbuild::chroot::get_root_users () const +{ + return this->root_users; +} + +void +sbuild::chroot::set_root_users (string_list const& users) +{ + this->root_users = users; +} + +string_list const& +sbuild::chroot::get_root_groups () const +{ + return this->root_groups; +} + +void +sbuild::chroot::set_root_groups (string_list const& groups) +{ + this->root_groups = groups; +} + +string_list const& +sbuild::chroot::get_aliases () const +{ + return this->aliases; +} + +void +sbuild::chroot::set_aliases (string_list const& aliases) +{ + this->aliases = aliases; +} + +bool +sbuild::chroot::get_active () const +{ + return this->active; +} + +void +sbuild::chroot::set_active (bool active) +{ + this->active = active; +} + +bool +sbuild::chroot::get_run_setup_scripts () const +{ + return this->run_setup_scripts; +} + +void +sbuild::chroot::set_run_setup_scripts (bool run_setup_scripts) +{ + this->run_setup_scripts = run_setup_scripts; +} + +bool +sbuild::chroot::get_run_exec_scripts () const +{ + return this->run_exec_scripts; +} + +void +sbuild::chroot::set_run_exec_scripts (bool run_exec_scripts) +{ + this->run_exec_scripts = run_exec_scripts; +} + +string_list const& +sbuild::chroot::get_command_prefix () const +{ + return this->command_prefix; +} + +void +sbuild::chroot::set_command_prefix (string_list const& command_prefix) +{ + this->command_prefix = command_prefix; +} + +personality const& +sbuild::chroot::get_persona () const +{ + return this->persona; +} + +void +sbuild::chroot::set_persona (personality const& persona) +{ + this->persona = persona; +} + +void +sbuild::chroot::setup_env (environment& env) +{ + env.add("CHROOT_TYPE", get_chroot_type()); + env.add("CHROOT_NAME", get_name()); + env.add("CHROOT_DESCRIPTION", get_description()); + env.add("CHROOT_LOCATION", get_location()); + env.add("CHROOT_MOUNT_LOCATION", get_mount_location()); + env.add("CHROOT_PATH", get_path()); + env.add("CHROOT_MOUNT_DEVICE", get_mount_device()); +} + +void +sbuild::chroot::setup_session_info (bool start) +{ + /* Create or unlink session information. */ + std::string file = std::string(SCHROOT_SESSION_DIR) + "/" + get_name(); + + if (start) + { + int fd = open(file.c_str(), O_CREAT|O_EXCL|O_WRONLY, 0664); + if (fd < 0) + throw error(file, SESSION_WRITE, errno); + + // Create a stream buffer from the file descriptor. The fd will + // be closed when the buffer is destroyed. +#ifdef SCHROOT_FILEBUF_OLD + __gnu_cxx::stdio_filebuf fdbuf(fd, std::ios::out, true, BUFSIZ); +#else + __gnu_cxx::stdio_filebuf fdbuf(fd, std::ios::out); +#endif + std::ostream output(&fdbuf); + output.imbue(std::locale("C")); + + sbuild::file_lock lock(fd); + try + { + lock.set_lock(lock::LOCK_EXCLUSIVE, 2); + } + catch (lock::error const& e) + { + throw error(file, FILE_LOCK, e.what()); + } + + keyfile details; + get_keyfile(details); + output << details; + + try + { + lock.unset_lock(); + } + catch (lock::error const& e) + { + throw error(file, FILE_UNLOCK, e.what()); + } + } + else /* start == false */ + { + if (unlink(file.c_str()) != 0) + throw error(file, SESSION_UNLINK, errno); + } +} + +void +sbuild::chroot::lock (setup_type type) +{ + setup_lock(type, true, 0); +} + +void +sbuild::chroot::unlock (setup_type type, + int status) +{ + setup_lock(type, false, status); +} + +void +sbuild::chroot::print_details (std::ostream& stream) const +{ + if (this->active == true) + stream << " " << _("--- Session ---\n"); + else + stream << " " << _("--- Chroot ---\n"); + stream << format_details(_("Name"), get_name()) + << format_details(_("Description"), get_description()) + << format_details(_("Type"), get_chroot_type()) + << format_details(_("Priority"), get_priority()) + << format_details(_("Users"), get_users()) + << format_details(_("Groups"), get_groups()) + << format_details(_("Root Users"), get_root_users()) + << format_details(_("Root Groups"), get_root_groups()) + << format_details(_("Aliases"), get_aliases()) + << format_details(_("Run Setup Scripts"), get_run_setup_scripts()) + << format_details(_("Run Execution Scripts"), + get_run_exec_scripts()) + << format_details(_("Session Managed"), + static_cast(get_session_flags() & + chroot::SESSION_CREATE)); + + if (!get_command_prefix().empty()) + stream << format_details(_("Command Prefix"), get_command_prefix()); + + stream << format_details(_("Personality"), get_persona().get_name()); + + /* Non user-settable properties are listed last. */ + if (!get_location().empty()) + stream << format_details(_("Location"), + get_location()); + if (!get_mount_location().empty()) + stream << format_details(_("Mount Location"), + get_mount_location()); + if (!get_path().empty()) + stream << format_details(_("Path"), + get_path()); + if (!get_mount_device().empty()) + stream << format_details(_("Mount Device"), get_mount_device()); +} + +void +sbuild::chroot::get_keyfile (keyfile& keyfile) const +{ + keyfile.remove_group(this->name); + + keyfile.set_value(this->name, "type", + get_chroot_type()); + + keyfile.set_value(this->name, "active", + get_active()); + + keyfile.set_value(this->name, "run-setup-scripts", + get_run_setup_scripts()); + + keyfile.set_value(this->name, "run-exec-scripts", + get_run_exec_scripts()); + + keyfile.set_value(this->name, "priority", + get_priority()); + + string_list const& aliases = get_aliases(); + keyfile.set_list_value(this->name, "aliases", + aliases.begin(), aliases.end()); + + keyfile.set_value(this->name, "description", + get_description()); + + string_list const& groups = get_groups(); + keyfile.set_list_value(this->name, "groups", + groups.begin(), groups.end()); + + string_list const& users = get_users(); + keyfile.set_list_value(this->name, "users", + users.begin(), users.end()); + + string_list const& root_users = get_root_users(); + keyfile.set_list_value(this->name, "root-users", + root_users.begin(), root_users.end()); + + string_list const& root_groups = get_root_groups(); + keyfile.set_list_value(this->name, "root-groups", + root_groups.begin(), root_groups.end()); + + if (get_active()) + keyfile.set_value(this->name, "mount-location", + get_mount_location()); + + if (get_active()) + keyfile.set_value(this->name, "mount-device", + get_mount_device()); + + string_list const& command_prefix = get_command_prefix(); + keyfile.set_list_value(this->name, "command-prefix", + command_prefix.begin(), command_prefix.end()); + + keyfile.set_value(this->name, "personality", + get_persona().get_name()); +} + +void +sbuild::chroot::set_keyfile (keyfile const& keyfile) +{ + // This is set not in the configuration file, but set in the keyfile + // manually. The user must not have the ability to set this option. + bool active(false); + if (keyfile.get_value(this->name, "active", + keyfile::PRIORITY_REQUIRED, active)) + set_active(active); + + bool run_setup_scripts(false); + if (keyfile.get_value(this->name, "run-setup-scripts", + keyfile::PRIORITY_OPTIONAL, run_setup_scripts)) + set_run_setup_scripts(run_setup_scripts); + + bool run_exec_scripts(false); + if (keyfile.get_value(this->name, "run-session-scripts", + keyfile::PRIORITY_DEPRECATED, run_exec_scripts)) + set_run_exec_scripts(run_exec_scripts); + if (keyfile.get_value(this->name, "run-exec-scripts", + keyfile::PRIORITY_OPTIONAL, run_exec_scripts)) + set_run_exec_scripts(run_exec_scripts); + + int priority(0); + if (keyfile.get_value(this->name, "priority", + keyfile::PRIORITY_OPTIONAL, priority)) + set_priority(priority); + + string_list aliases; + if (keyfile.get_list_value(this->name, "aliases", + keyfile::PRIORITY_OPTIONAL, + aliases)) + set_aliases(aliases); + + std::string description; + if (keyfile.get_locale_string(this->name, "description", + keyfile::PRIORITY_OPTIONAL, description)) + set_description(description); + + string_list users; + if (keyfile.get_list_value(this->name, "users", + keyfile::PRIORITY_OPTIONAL, + users)) + set_users(users); + + string_list groups; + if (keyfile.get_list_value(this->name, "groups", + keyfile::PRIORITY_OPTIONAL, + groups)) + set_groups(groups); + + string_list root_users; + if (keyfile.get_list_value(this->name, "root-users", + keyfile::PRIORITY_OPTIONAL, + root_users)) + set_root_users(root_users); + + string_list root_groups; + if (keyfile.get_list_value(this->name, "root-groups", + keyfile::PRIORITY_OPTIONAL, + root_groups)) + set_root_groups(root_groups); + + std::string mount_location; + if (keyfile.get_value(this->name, "mount-location", + get_active() ? + keyfile::PRIORITY_REQUIRED : keyfile::PRIORITY_DISALLOWED, + mount_location)) + set_mount_location(mount_location); + + std::string mount_device; + if (keyfile.get_value(this->name, "mount-device", + get_active() ? + keyfile::PRIORITY_OPTIONAL : keyfile::PRIORITY_DISALLOWED, + mount_device)) + set_mount_device(mount_device); + + string_list command_prefix; + if (keyfile.get_list_value(this->name, "command-prefix", + keyfile::PRIORITY_OPTIONAL, + command_prefix)) + set_command_prefix(command_prefix); + + std::string persona_name; + if (keyfile.get_value(this->name, "personality", + keyfile::PRIORITY_OPTIONAL, + persona_name)) + { + personality persona (persona_name); + + if (persona.get_name() == "undefined" && + persona.get_name() != persona_name) + { + std::ostringstream plist; + personality::print_personalities(plist); + + log_warning() + << format(_("%1% chroot: personality \"%2%\" is unknown.\n")) + % this->name % persona_name; + log_info() + << format(_("Valid personalities: %1%\n")) % plist.str(); + } + + set_persona(persona); + } +} + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/sbuild/sbuild-chroot.h b/sbuild/sbuild-chroot.h new file mode 100644 index 00000000..fd8a1778 --- /dev/null +++ b/sbuild/sbuild-chroot.h @@ -0,0 +1,619 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#ifndef SBUILD_CHROOT_H +#define SBUILD_CHROOT_H + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifdef HAVE_TR1_MEMORY +#include +#elif HAVE_BOOST_SHARED_PTR_HPP +#include +namespace std { namespace tr1 { using boost::shared_ptr; } } +#else +#error A shared_ptr implementation is not available +#endif + +namespace sbuild +{ + + /** + * Common chroot data. This class contains all of the metadata + * associated with a single chroot, for all chroot types. This is + * the in-core representation of a chroot definition in the + * configuration file, and may be initialised directly from an open + * keyfile. + */ + class chroot + { + public: + /// Type of setup to perform. + enum setup_type + { + SETUP_START, ///< Activate a chroot. + SETUP_RECOVER, ///< Reactivate a chroot. + SETUP_STOP, ///< Deactivate a chroot. + EXEC_START, ///< Start executing a command in an active chroot. + EXEC_STOP ///< End executing a command in an active chroot. + }; + + /// Chroot session properties + enum session_flags + { + SESSION_CREATE = 1 << 0 ///< The chroot supports session creation. + }; + + /// Error codes. + enum error_code + { + CHROOT_TYPE, ///< Unknown chroot type. + CHROOT_CREATE, ///< Chroot creation failed. + CHROOT_DEVICE, ///< Chroot device name not set. + SESSION_WRITE, ///< Failed to write session file. + SESSION_UNLINK, ///< Failed to unlink session file. + FILE_STAT, ///< Failed to stat file. + FILE_OWNER, ///< File is not owned by user root. + FILE_PERMS, ///< File has write permissions for others. + FILE_NOTREG, ///< File is not a regular file. + FILE_LOCK, ///< Failed to acquire lock. + FILE_UNLOCK, ///< Failed to discard lock. + DEVICE_STAT, ///< Failed to stat device. + DEVICE_NOTBLOCK, ///< File is not a block device. + DEVICE_LOCK, ///< Failed to lock device. + DEVICE_UNLOCK ///< Failed to unlock device. + }; + + /// Exception type. + typedef custom_error error; + + /// A shared_ptr to a chroot object. + typedef std::tr1::shared_ptr ptr; + + protected: + /// The constructor. + chroot (); + + public: + /// The destructor. + virtual ~chroot (); + + /** + * Create a chroot. This is a factory function. + * + * @param type the type of chroot to create. + * @returns a shared_ptr to the new chroot. + */ + static ptr + create (std::string const& type); + + /** + * Copy the chroot. This is a virtual copy constructor. + * + * @returns a shared_ptr to the new copy of the chroot. + */ + virtual ptr + clone () const = 0; + + /** + * Get the name of the chroot. + * + * @returns the name. + */ + std::string const& + get_name () const; + + /** + * Set the name of the chroot. + * + * @param name the name. + */ + void + set_name (std::string const& name); + + /** + * Get the description of the chroot. + * + * @returns the description. + */ + std::string const& + get_description () const; + + /** + * Set the description of the chroot. + * + * @param description the description. + */ + void + set_description (std::string const& description); + + /** + * Get the mount location of the chroot. + * + * @returns the mount location. + */ + virtual std::string const& + get_mount_location () const; + + /** + * Set the mount location of the chroot. + * + * @param location the mount location. + */ + void + set_mount_location (std::string const& location); + + /** + * Get the location of the chroot. This is the path to the root + * of the chroot, and is typically the same as the mount location, + * but is overridden by the chroot type if required. + * + * @returns the mount location. + */ + virtual std::string const& + get_location () const; + + protected: + /** + * Set the location of the chroot. This is the path to the root + * of the chroot, and is typically the same as the mount location, + * but is overridden by the chroot type if required. + * + * @returns the mount location. + */ + virtual void + set_location (std::string const& location); + + public: + /** + * Get the path to the chroot. This is the absolute path to the + * root of the chroot, and is typically the same as the mount + * location and location concatenated together, but is overridden + * by the chroot type if required. + * + * @returns the path. + */ + virtual std::string + get_path () const; + + /** + * Get the mount device of the chroot. + * + * @returns the device. + */ + virtual std::string const& + get_mount_device () const; + + /** + * Set the mount device of the chroot. + * + * @param device the device. + */ + void + set_mount_device (std::string const& device); + + /** + * Get the priority of the chroot. This is a number indicating + * whether than a ditribution is older than another. + * + * @returns the priority. + */ + unsigned int + get_priority () const; + + /** + * Set the priority of a chroot. This is a number indicating + * whether a distribution is older than another. For example, + * "oldstable" and "oldstable-security" might be 0, while "stable" + * and "stable-security" 1, "testing" 2 and "unstable" 3. The + * values are not important, but the difference between them is. + * + * @param priority the priority. + */ + void + set_priority (unsigned int priority); + + /** + * Get the users allowed to access the chroot. + * + * @returns a list of users. + */ + string_list const& + get_users () const; + + /** + * Set the users allowed to access the chroot. + * + * @param users a list of users. + */ + void + set_users (string_list const& users); + + /** + * Get the groups allowed to access the chroot. + * + * @returns a list of groups. + */ + string_list const& + get_groups () const; + + /** + * Set the users allowed to access the chroot. + * + * @param groups a list of groups. + */ + void + set_groups (string_list const& groups); + + /** + * Get the users allowed to access the chroot as root. Mmebers + * of these users can switch to root without authenticating + * themselves. + * + * @returns a list of users. + */ + string_list const& + get_root_users () const; + + /** + * Set the users allowed to access the chroot as root. Mmebers + * of these users can switch to root without authenticating + * themselves. + * + * @param users a list of users. + */ + void + set_root_users (string_list const& users); + + /** + * Get the groups allowed to access the chroot as root. Mmebers + * of these groups can switch to root without authenticating + * themselves. + * + * @returns a list of groups. + */ + string_list const& + get_root_groups () const; + + /** + * Set the groups allowed to access the chroot as root. Mmebers + * of these groups can switch to root without authenticating + * themselves. + * + * @param groups a list of groups. + */ + void + set_root_groups (string_list const& groups); + + /** + * Get the aliases of the chroot. These are alternative names for + * the chroot. + * + * @returns a list of names. + */ + string_list const& + get_aliases () const; + + /** + * Set the aliases of the chroot. These are alternative names for + * the chroot. + * + * @param aliases a list of names. + */ + void + set_aliases (string_list const& aliases); + + /** + * Get the activity status of the chroot. + * + * @returns true if active, false if inactive + */ + bool + get_active () const; + + /** + * Set the activity status of the chroot. + * + * @param active true if active, false if inactive + */ + void + set_active (bool active); + + /** + * Check if chroot setup scripts will be run. + * + * @returns true if setup scripts will be run, otherwise false. + */ + bool + get_run_setup_scripts () const; + + /** + * Set whether chroot setup scripts will be run. + * + * @param run_setup_scripts true if setup scripts will be run, + * otherwise false. + */ + void + set_run_setup_scripts (bool run_setup_scripts); + + /** + * Check if chroot exec scripts will be run. + * + * @returns true if exec scripts will be run, otherwise false. + */ + bool + get_run_exec_scripts () const; + + /** + * Set whether chroot exec scripts will be run. + * + * @param run_exec_scripts true if exec scripts will be run, + * otherwise false. + */ + void + set_run_exec_scripts (bool run_exec_scripts); + + /** + * Get the command_prefix for the chroot. This is a command to + * prefix to any command run in the chroot. + * + * @returns the command prefix. + */ + string_list const& + get_command_prefix () const; + + /** + * Set the command_prefix for the chroot. This is a command to + * prefix to any command run in the chroot. + * + * @param command_prefix the command prefix. + */ + void + set_command_prefix (string_list const& command_prefix); + + /** + * Get the process execution domain for the chroot. + * + * @returns the command prefix. + */ + personality const& + get_persona () const; + + /** + * Set the process execution domain for the chroot. + * + * @param persona the command prefix. + */ + void + set_persona (personality const& persona); + + /** + * Get the type of the chroot. + * + * @returns the chroot type. + */ + virtual std::string const& + get_chroot_type () const = 0; + + /** + * Set environment. Set the environment that the setup scripts + * will see during execution. + * + * @param env the environment to set. + */ + virtual void + setup_env (environment& env); + + /** + * Lock a chroot during setup. The locking technique (if any) may + * vary depending upon the chroot type and setup stage. For + * example, during creation of an LVM snapshot a block device + * might require locking, but afterwards this will change to the + * new block device. + * + * An error will be thrown on failure. + * + * @param type the type of setup being performed + */ + void + lock (setup_type type); + + /** + * Unlock a chroot during setup. The locking technique (if any) may + * vary depending upon the chroot type and setup stage. For + * example, during creation of an LVM snapshot a block device + * might require locking, but afterwards this will change to the + * new block device. + * + * An error will be thrown on failure. + * + * @param type the type of setup being performed + * @param status the exit status of the setup commands (0 for + * success, nonzero for failure). + */ + void + unlock (setup_type type, + int status); + + protected: + /** + * Set up persistent session information. + * + * @param start true if startion, or false if ending a session. + */ + virtual void + setup_session_info (bool start); + + /** + * Unlock a chroot during setup. The locking technique (if any) may + * vary depending upon the chroot type and setup stage. For + * example, during creation of an LVM snapshot a block device + * might require locking, but afterwards this will change to the + * new block device. + * + * An error will be thrown on failure. + * + * @param type the type of setup being performed + * @param lock true to lock, false to unlock + * @param status the exit status of the setup commands (0 for + * success, nonzero for failure). + */ + virtual void + setup_lock(setup_type type, + bool lock, + int status) = 0; + + public: + /** + * Get the session flags of the chroot. These determine how the + * Session controlling the chroot will operate. + * + * @returns the session flags. + */ + virtual session_flags + get_session_flags () const = 0; + + /** + * Print detailed information about the chroot to a stream. The + * information is printed in plain text with one line per + * property. + * + * @param stream the stream to output to. + * @param rhs the chroot to output. + * @returns the stream. + */ + friend std::ostream& + operator << (std::ostream& stream, + ptr const& rhs) + { + rhs->print_details(stream); + return stream; + } + + /** + * Chroot initialisation from a keyfile. + */ + friend + keyfile const& + operator >> (keyfile const& keyfile, + ptr& rhs) + { + rhs->set_keyfile(keyfile); + return keyfile; + } + + /** + * Chroot serialisation to a keyfile. + */ + friend + keyfile& + operator << (keyfile& keyfile, + ptr const& rhs) + { + rhs->get_keyfile(keyfile); + return keyfile; + } + + + protected: + /** + * Print detailed information about the chroot to a stream. The + * information is printed in plain text with one line per + * property. + * + * @param stream the stream to output to. + */ + virtual void + print_details (std::ostream& stream) const; + + /** + * Copy the chroot properties into a keyfile. The keyfile group + * with the name of the chroot will be set; if it already exists, + * it will be removed before setting it. + * + * @param keyfile the keyfile to use. + */ + virtual void + get_keyfile (keyfile& keyfile) const; + + /** + * Set the chroot properties from a keyfile. The chroot name must + * have previously been set, so that the correct keyfile group may + * be determined. + * + * @param keyfile the keyfile to get the properties from. + */ + virtual void + set_keyfile (keyfile const& keyfile); + + private: + /// Chroot name. + std::string name; + /// Chroot description. + std::string description; + /// Chroot prioroty. + unsigned int priority; + /// Users allowed to access the chroot. + string_list users; + /// Groups allowed to access the chroot. + string_list groups; + /// Users allowed to access the chroot as root. + string_list root_users; + /// Groups allowed to access the chroot as root. + string_list root_groups; + /// Alternative names for the chroot. + string_list aliases; + /// Location to mount chroot in the filesystem (if any). + std::string mount_location; + /// Location inside the mount location root. + std::string location; + /// Block device to mount (if any). + std::string mount_device; + /// Chroot activity status. + bool active; + /// Run chroot setup scripts? + bool run_setup_scripts; + /// Run chroot exec scripts? + bool run_exec_scripts; + /// Command prefix. + string_list command_prefix; + /// Process execution domain (Linux only). + personality persona; + }; + +} + +#endif /* SBUILD_CHROOT_H */ + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/sbuild/sbuild-config.h.in b/sbuild/sbuild-config.h.in new file mode 100644 index 00000000..ff4de033 --- /dev/null +++ b/sbuild/sbuild-config.h.in @@ -0,0 +1,51 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#ifndef SBUILD_CONFIG_H +#define SBUILD_CONFIG_H + +/* This header contains configuration macros which determine the + correct library to use. This depends upon the libraries found at + configure time. */ + +/* Define to 1 if you have the header file. */ +#undef HAVE_BOOST_FORMAT_HPP + +/* Define to 1 if you have the header file. */ +#undef HAVE_BOOST_PROGRAM_OPTIONS_HPP + +/* Define to 1 if you have the header file. */ +#undef HAVE_BOOST_SHARED_PTR_HPP + +/* Define to 1 if you have the header file. */ +#undef HAVE_BOOST_TUPLE_TUPLE_HPP + +/* Define to 1 if you have the header file. */ +#undef HAVE_TR1_MEMORY + +/* Define to 1 if you have the header file. */ +#undef HAVE_TR1_TUPLE + +#endif /* SBUILD_H */ + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/sbuild/sbuild-custom-error.h b/sbuild/sbuild-custom-error.h new file mode 100644 index 00000000..0bb077d1 --- /dev/null +++ b/sbuild/sbuild-custom-error.h @@ -0,0 +1,239 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#ifndef SBUILD_CUSTOM_ERROR_H +#define SBUILD_CUSTOM_ERROR_H + +#include + +#include +#include + +#include + +namespace sbuild +{ + + /** + * Custom error. + */ + template + class custom_error : public runtime_error + { + public: + typedef T error_type; + typedef std::map map_type; + + /** + * The constructor. + * + * @param error the error code. + */ + custom_error (error_type error): + runtime_error(format_error(std::string(), error)) + { + } + + /** + * The constructor. + * + * @param detail the details of the error. + * @param error the error code. + */ + custom_error (std::string const& detail, + error_type error): + runtime_error(format_error(detail, error)) + { + } + + /** + * The constructor. + * + * @param detail the details of the error. + */ + custom_error (std::string const& detail): + runtime_error(detail) + { + } + + /** + * The constructor. + * + * @param error the error code. + * @param error_number the error number. + */ + custom_error (error_type error, + int error_number): + runtime_error(format_error(std::string(), error, error_number)) + { + } + + /** + * The constructor. + * + * @param detail the details of the error. + * @param error the error code. + * @param error_number the error number. + */ + custom_error (std::string const& detail, + error_type error, + int error_number): + runtime_error(format_error(detail, error, error_number)) + { + } + + /** + * The constructor. + * + * @param detail the details of the error. + * @param error_number the error number. + */ + custom_error (std::string const& detail, + int error_number): + runtime_error(format_error(detail, error_number)) + { + } + + /** + * The constructor. + * + * @param error the error code. + * @param error_string the error string. + */ + custom_error (error_type error, + std::string const& error_string): + runtime_error(format_error(std::string(), error, error_string)) + { + } + + /** + * The constructor. + * + * @param detail the details of the error. + * @param error the error code. + * @param error_string the error string. + */ + custom_error (std::string const& detail, + error_type error, + std::string const& error_string): + runtime_error(format_error(detail, error, error_string)) + { + } + + /** + * The constructor. + * + * @param detail the details of the error. + * @param error_string the error string. + */ + custom_error (std::string const& detail, + std::string const& error_string): + runtime_error(format_error(detail, error_string)) + { + } + + /// The destructor. + virtual ~custom_error () throw () + {} + + private: + /// Mapping between error code and string. + static map_type error_strings; + + /** + * Get a translated error string. + * + * @param error the error code. + * @returns a translated error string. + */ + static const char * + get_error (error_type error); + + /** + * Format an error message. + * + * @param error the error code. + * @param detail the details of the error. + * @returns a translated error message. + */ + static std::string + format_error (std::string const& detail, + error_type error); + + /** + * Format an error message. + * + * @param detail the details of the error. + * @param error the error code. + * @param error_number the error number. + * @returns a translated error message. + */ + static std::string + format_error (std::string const& detail, + error_type error, + int error_number); + + /** + * Format an error message. + * + * @param detail the details of the error. + * @param error_number the error number. + * @returns a translated error message. + */ + static std::string + format_error (std::string const& detail, + int error_number); + + /** + * Format an error message. + * + * @param detail the details of the error. + * @param error the error code. + * @param error_string the error string. + * @returns a translated error message. + */ + static std::string + format_error (std::string const& detail, + error_type error, + std::string const& error_string); + + /** + * Format an error message. + * + * @param detail the details of the error. + * @param error_string the error string. + * @returns a translated error message. + */ + static std::string + format_error (std::string const& detail, + std::string const& error_string); + }; + + +} + +#include "sbuild-custom-error.tcc" + +#endif /* SBUILD_CUSTOM_ERROR_H */ + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/sbuild/sbuild-custom-error.tcc b/sbuild/sbuild-custom-error.tcc new file mode 100644 index 00000000..37e5ba8b --- /dev/null +++ b/sbuild/sbuild-custom-error.tcc @@ -0,0 +1,121 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#ifndef SBUILD_CUSTOM_ERROR_TCC +#define SBUILD_CUSTOM_ERROR_TCC + +#include "sbuild-i18n.h" +#include "sbuild-custom-error.h" + +#include + +template +const char * +sbuild::custom_error::get_error (error_type error) +{ + typename map_type::const_iterator pos = error_strings.find(error); + + if (pos != error_strings.end()) + return gettext(pos->second); + + // Untranslated: it's a programming error to get this message. + return "unknown error"; +} + +template +std::string +sbuild::custom_error::format_error (std::string const& detail, + error_type error) +{ + if (detail.length() > 0) + { + boost::format fmt("%1%: %2%"); + fmt % detail % get_error(error); + return fmt.str(); + } + else + return get_error(error); +} + +template +std::string +sbuild::custom_error::format_error (std::string const& detail, + error_type error, + int error_number) +{ + return format_error(detail, error, std::string(strerror(error_number))); +} + +template +std::string +sbuild::custom_error::format_error (std::string const& detail, + int error_number) +{ + return format_error(detail, std::string(strerror(error_number))); +} + +template +std::string +sbuild::custom_error::format_error (std::string const& detail, + std::string const& error_string) +{ + if (detail.length() > 0) + { + boost::format fmt("%1%: %2%"); + fmt % detail % error_string; + return fmt.str(); + } + else + { + boost::format fmt("%1%"); + fmt % error_string; + return fmt.str(); + } +} + +template +std::string +sbuild::custom_error::format_error (std::string const& detail, + error_type error, + std::string const& error_string) +{ + if (detail.length() > 0) + { + boost::format fmt("%1%: %2%: %3%"); + fmt % detail + % get_error(error) + % error_string; + return fmt.str(); + } + else + { + boost::format fmt("%1%: %2%"); + fmt % get_error(error) + % error_string; + return fmt.str(); + } +} + +#endif /* SBUILD_CUSTOM_ERROR_TCC */ + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/sbuild/sbuild-environment.cc b/sbuild/sbuild-environment.cc new file mode 100644 index 00000000..ea51724a --- /dev/null +++ b/sbuild/sbuild-environment.cc @@ -0,0 +1,153 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#include + +#include "sbuild-environment.h" + +using boost::format; +using namespace sbuild; + +environment::environment (): + std::map() +{ +} + +environment::environment (char **environment): + std::map() +{ + add(environment); +} + +environment::~environment () +{ +} + +void +environment::add (char **environment) +{ + if (environment) + { + for (char **ev = environment; ev != 0 && *ev != 0; ++ev) + add(std::string(*ev)); + } +} + +void +environment::add (environment const& environment) +{ + for (const_iterator pos = environment.begin(); + pos != environment.end(); + ++pos) + add(*pos); +} + +void +environment::add (std::string const& value) +{ + std::string::size_type pos = value.find('='); + if (pos != std::string::npos && pos != 0) + { + std::string key = value.substr(0, pos); + std::string val; + if (pos < value.length()) + val = value.substr(pos + 1); + add(std::make_pair(key, val)); + } + else + { + add(std::make_pair(value, std::string())); + } +} + +void +environment::add (value_type const& value) +{ + remove(value); + if (!value.second.empty()) + insert(value); +} + +void +environment::remove (char **environment) +{ + if (environment) + { + for (char **ev = environment; ev != 0 && *ev != 0; ++ev) + remove(std::string(*ev)); + } +} + +void +environment::remove (environment const& environment) +{ + for (const_iterator pos = environment.begin(); + pos != environment.end(); + ++pos) + remove(*pos); +} + +void +environment::remove (std::string const& value) +{ + std::string::size_type pos = value.find('='); + if (pos != std::string::npos && pos != 0) + { + std::string key = value.substr(0, pos); + std::string val; + if (pos < value.length()) + val = value.substr(pos + 1); + remove(std::make_pair(key, val)); + } + else + { + remove(std::make_pair(value, std::string())); + } +} + +void +environment::remove (value_type const& value) +{ + iterator pos = find(value.first); + if (pos != end()) + erase(pos); +} + +char ** +environment::get_strv () const +{ + char **ret = new char *[size() + 1]; + + size_type idx = 0; + for (const_iterator pos = begin(); pos != end(); ++pos, ++idx) + { + std::string envitem = pos->first + "=" + pos->second; + ret[idx] = new char[envitem.length() + 1]; + std::strcpy(ret[idx], envitem.c_str()); + } + ret[size()] = 0; + + return ret; +} + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/sbuild/sbuild-environment.h b/sbuild/sbuild-environment.h new file mode 100644 index 00000000..56b8b9c8 --- /dev/null +++ b/sbuild/sbuild-environment.h @@ -0,0 +1,301 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#ifndef SBUILD_ENVIRONMENT_H +#define SBUILD_ENVIRONMENT_H + +#include +#include + +#include +#include +#include + +#include + +namespace sbuild +{ + + /** + * Container of environment variables. + */ + class environment : public std::map + { + public: + using std::map::value_type; + + /// The constructor. + environment (); + + /** + * The constructor. + * + * @param environment the environment to set. + */ + environment (char **environment); + + /// The destructor. + ~environment (); + + /** + * Add environment variables. Any existing variables sharing the + * name of a new value will be replaced. + * + * @param environment the environment variables to add. This is a + * null-terminated array of pointers to char. + */ + void + add (char **environment); + + /** + * Add environment variables. Any existing variables sharing the + * name of a new value will be replaced. + * + * @param environment the environment variables to add. + */ + void + add (environment const& environment); + + /** + * Add environment variable. Any existing variable sharing the + * name will be replaced. + * + * @param value the environment variable to add. + */ + void + add (value_type const& value); + + /** + * Add environment variable. Any existing variable sharing the + * name will be replaced. + * + * @param name the environment variable name + * @param value the environment variable value to add. + */ + void + add (std::string const& name, + std::string const& value) + { + add(std::make_pair(name, value)); + } + + /** + * Add environment variable. Any existing variable sharing the + * name will be replaced. + * + * @param name the environment variable name + * @param value the environment variable value to add. + */ + template + void + add (std::string const& name, + T const& value) + { + std::ostringstream varstring; + varstring.imbue(std::locale("C")); + varstring << std::boolalpha << value; + add(std::make_pair(name, varstring.str())); + } + + /** + * Add environment variable. Any existing variable sharing the + * name will be replaced. + * + * @param value the environment variable to add. This is a string + * in the form key=value. + */ + void + add (std::string const& value); + + /** + * Remove environment variables. Any variables sharing the names + * of a specified value will be removed. + * + * @param environment the environment variables to remove. This + * is a null-terminated array of pointers to char. + */ + void + remove (char **environment); + + /** + * Remove environment variables. Any variables sharing the names + * of a specified value will be removed. + * + * @param environment the environment variables to remove. + */ + void + remove (environment const& environment); + + /** + * Remove environment variable. Any variable sharing the name + * of the specified value will be removed. + * + * @param value the environment variable to remove. + */ + void + remove (std::string const& value); + + /** + * Remove environment variable. Any variable sharing the name + * of the specified value will be removed. + * + * @param value the environment variable to remove. + */ + void + remove (value_type const& value); + + /** + * Get the value of an environment variable. + * + * @param name the name of the environment variable. + * @param value the variable to store the value in on success. + * @returns true on success, false if the variable does not exist, + * or there is a parse error. + */ + template + bool + get (std::string const& name, + T& value) + { + log_debug(DEBUG_INFO) << "Getting environment variable=" << name + << std::endl; + iterator pos = find(name); + if (pos != end()) + { + try + { + value = static_cast(parse_value(pos->second)); + return true; + } + catch (parse_value::error const& e) + { + log_warning() << boost::format("%1%: %2%\n") + % name % e.what(); + return false; + } + } + log_debug(DEBUG_NOTICE) << "name not found: " << name << std::endl; + return false; + } + + /** + * Get the evironment variables as a string vector. This form is + * suitable for use as an envp argument with execve, for example. + * + * @returns a newly-allocated string vector. This is allocated + * with new, and should be freed with strv_delete(). + */ + char ** + get_strv () const; + + /** + * Add variables to the environment. + * + * @param rhs the values to add. + * @returns the modified environment. + */ + template + environment& + operator += (T& rhs) + { + add(rhs); + return *this; + } + + /** + * Remove variables from the environment. + * + * @param rhs the values to remove. + * @returns the modified environment. + */ + template + environment& + operator -= (T& rhs) + { + remove(rhs); + return *this; + } + + /** + * Add variables to the environment. + * + * @param lhs the environment to add to. + * @param rhs the values to add. + * @returns the new environment. + */ + template + friend environment + operator + (environment const& lhs, + T const& rhs) + { + environment ret(lhs); + ret += rhs; + return ret; + } + + /** + * Remove variables from the environment. + * + * @param lhs the environment to remove from. + * @param rhs the values to remove. + * @returns the new environment. + */ + template + friend environment + operator - (environment const& lhs, + T const& rhs) + { + environment ret(lhs); + ret -= rhs; + return ret; + } + + /** + * Output the environment to an ostream. + * + * @param stream the stream to output to. + * @param rhs the environment to output. + * @returns the stream. + */ + template + friend + std::basic_ostream& + operator << (std::basic_ostream& stream, + environment const& rhs) + { + for (environment::const_iterator pos = rhs.begin(); + pos != rhs.end(); + ++pos) + { + stream << pos->first << '=' << pos->second << '\n'; + } + + return stream; + } + }; + +} + +#endif /* SBUILD_ENVIRONMENT_H */ + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/sbuild/sbuild-error.h b/sbuild/sbuild-error.h new file mode 100644 index 00000000..a8609c03 --- /dev/null +++ b/sbuild/sbuild-error.h @@ -0,0 +1,58 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#ifndef SBUILD_ERROR_H +#define SBUILD_ERROR_H + +#include + +#include + +namespace sbuild +{ + + /** + * Generic runtime error. + */ + class runtime_error : public std::runtime_error + { + public: + /** + * The constructor. + * + * @param error the error message. + */ + runtime_error (std::string const& error): + std::runtime_error(error) + {} + + /// The destructor. + virtual ~runtime_error () throw () + {} + }; + +} + +#endif /* SBUILD_ERROR_H */ + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/sbuild/sbuild-format-detail.cc b/sbuild/sbuild-format-detail.cc new file mode 100644 index 00000000..7f186087 --- /dev/null +++ b/sbuild/sbuild-format-detail.cc @@ -0,0 +1,38 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#include + +#include "sbuild-format-detail.h" +#include "sbuild-i18n.h" + +using namespace sbuild; + +template<> +std::ostream& +sbuild::operator << (std::ostream& stream, + format_detail const& rhs) +{ + const char *desc = 0; + if (rhs.value) + desc = _("true"); + else + desc = _("false"); + return stream << format_detail(rhs.name, desc); +} diff --git a/sbuild/sbuild-format-detail.h b/sbuild/sbuild-format-detail.h new file mode 100644 index 00000000..7239624d --- /dev/null +++ b/sbuild/sbuild-format-detail.h @@ -0,0 +1,149 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#ifndef SBUILD_FORMAT_DETAIL_H +#define SBUILD_FORMAT_DETAIL_H + +#include +#include +#include + +#include +#include +#include + +namespace sbuild +{ + + /** + * Format names and values for output. + */ + template + class format_detail; + + /** + * Output the formatted detail to an ostream. + * + * @param stream the stream to output to. + * @param rhs the formatted detail to output. + * @returns the stream. + */ + template std::ostream& + operator << (std::ostream& stream, + format_detail const& rhs); + + /** + * Output the formatted detail to an ostream. This is a special + * case for boolean values. + * + * @param stream the stream to output to. + * @param rhs the formatted detail to output. + * @returns the stream. + */ + template<> std::ostream& + operator << (std::ostream& stream, + format_detail const& rhs); + + /** + * Output the formatted detail to an ostream. This is a special + * case for string_list values. + * + * @param stream the stream to output to. + * @param rhs the formatted detail to output. + * @returns the stream. + */ + template<> std::ostream& + operator << (std::ostream& stream, + format_detail const& rhs); + + /** + * Helper to perform formatting of chroot details. + */ + template + class format_detail + { + /** + * The constructor. + * + * @param name the name of the property to format. + * @param value the value of the property to format. The value + * type must support output to an ostream. + */ + public: + format_detail (std::string const& name, + T const& value): + name(name), + value(value) + {} + + friend std::ostream& + operator << <>(std::ostream&, format_detail const&); + + private: + /// The name of the property. + std::string const& name; + /// The value of the property. + T const& value; + }; + + template + inline std::ostream& + operator << (std::ostream& stream, + format_detail const& rhs) + { + return stream << " " + << std::setw(21) << std::left << rhs.name + << ' ' << rhs.value << '\n'; + } + + template<> + inline std::ostream& + operator << (std::ostream& stream, + format_detail const& rhs) + { + return stream << + format_detail(rhs.name, + string_list_to_string(rhs.value, " ")); + } + + /** + * Format a name-value pair for output. This is a convenience + * wrapper to construct a format_detail of the appropriate type. + * + * @param name the name to output. + * @param value the value to output. + * @returns a format_detail of the appropriate type. + */ + template + inline format_detail + format_details (std::string const& name, + T const& value) + { + return format_detail(name, value); + } + +} + +#endif /* SBUILD_FORMAT_DETAIL_H */ + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/sbuild/sbuild-i18n.h b/sbuild/sbuild-i18n.h new file mode 100644 index 00000000..3bed0ffb --- /dev/null +++ b/sbuild/sbuild-i18n.h @@ -0,0 +1,38 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#ifndef SBUILD_I18N_H +#define SBUILD_I18N_H + +#include + +#define _(String) gettext (String) +#ifdef gettext_noop +#define N_(String) gettext_noop (String) +#else +#define N_(String) (String) +#endif + +#endif /* SBUILD_I18N_H */ + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/sbuild/sbuild-keyfile.cc b/sbuild/sbuild-keyfile.cc new file mode 100644 index 00000000..f1e7a9db --- /dev/null +++ b/sbuild/sbuild-keyfile.cc @@ -0,0 +1,385 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#include + +#include "sbuild-keyfile.h" + +#include + +#include + +using boost::format; +using namespace sbuild; + +keyfile::keyfile (): + groups(), + separator(',') +{ +} + +keyfile::keyfile (std::string const& file): + groups(), + separator(',') +{ + std::ifstream fs(file.c_str()); + if (fs) + { + fs.imbue(std::locale("C")); + fs >> *this; + } + else + { + throw error(parse_error::BAD_FILE, file); + } +} + +keyfile::keyfile (std::istream& stream): + groups(), + separator(',') +{ + stream >> *this; +} + +keyfile::~keyfile() +{ +} + +string_list +keyfile::get_groups () const +{ + string_list ret; + + for (group_map_type::const_iterator pos = this->groups.begin(); + pos != this->groups.end(); + ++pos) + ret.push_back(pos->first); + + return ret; +} + +string_list +keyfile::get_keys (std::string const& group) const +{ + string_list ret; + + const group_type *found_group = find_group(group); + if (found_group) + { + item_map_type const& items(std::tr1::get<1>(*found_group)); + for (item_map_type::const_iterator pos = items.begin(); + pos != items.end(); + ++pos) + ret.push_back(pos->first); + } + + return ret; +} + +bool +keyfile::has_group (std::string const& group) const +{ + return (find_group(group) != 0); +} + +bool +keyfile::has_key (std::string const& group, + std::string const& key) const +{ + return (find_item(group, key) != 0); +} + +void +keyfile::set_group (std::string const& group, + std::string const& comment) +{ + if (!has_group(group)) + this->groups.insert + (group_map_type::value_type(group, + group_type(group, + item_map_type(), + comment))); +} + +std::string +keyfile::get_comment (std::string const& group) const +{ + const keyfile::group_type *found_group = find_group(group); + if (found_group) + return std::tr1::get<2>(*found_group); + else + return std::string(); +} + +std::string +keyfile::get_comment (std::string const& group, + std::string const& key) const +{ + const item_type *found_item = find_item(group, key); + if (found_item) + return std::tr1::get<2>(*found_item); + else + return std::string(); +} + +bool +keyfile::get_locale_string (std::string const& group, + std::string const& key, + std::string& value) const +{ + std::string localename = std::locale("").name(); + std::string::size_type pos; + bool status = false; + + // Strip off any charset. + if ((pos = localename.find_first_of('.')) != std::string::npos) + localename = localename.substr(0, pos); + status = get_locale_string(group, key, localename, value); + + // Strip off territory. + if (status == false && + (pos = localename.find_first_of('_')) != std::string::npos) + { + localename = localename.substr(0, pos); + status = get_locale_string(group, key, localename, value); + } + + // Fall back to non-localised version. + if (status == false) + status = get_value(group, key, value); + + return status; +} + +bool +keyfile::get_locale_string (std::string const& group, + std::string const& key, + priority priority, + std::string& value) const +{ + bool status = get_locale_string(group, key, value); + check_priority(group, key, priority, status); + return status; +} + +bool +keyfile::get_locale_string (std::string const& group, + std::string const& key, + std::string const& locale, + std::string& value) const +{ + std::string lkey = key + '[' + locale + ']'; + return get_value(group, lkey, value); +} + +bool +keyfile::get_locale_string (std::string const& group, + std::string const& key, + std::string const& locale, + priority priority, + std::string& value) const +{ + bool status = get_locale_string(group, key, locale, value); + check_priority(group, key, priority, status); + return status; +} + +void +keyfile::remove_group (std::string const& group) +{ + group_map_type::iterator pos = this->groups.find(group); + if (pos != this->groups.end()) + this->groups.erase(pos); +} + +void +keyfile::remove_key (std::string const& group, + std::string const& key) +{ + group_type *found_group = find_group(group); + if (found_group) + { + item_map_type& items = std::tr1::get<1>(*found_group); + item_map_type::iterator pos = items.find(key); + if (pos != items.end()) + items.erase(pos); + } +} + +keyfile& +keyfile::operator += (keyfile const& rhs) +{ + for (group_map_type::const_iterator gp = rhs.groups.begin(); + gp != rhs.groups.end(); + ++gp) + { + group_type const& group = gp->second; + std::string const& groupname = std::tr1::get<0>(group); + std::string const& comment = std::tr1::get<2>(group); + set_group(groupname, comment); + + item_map_type const& items(std::tr1::get<1>(group)); + for (item_map_type::const_iterator it = items.begin(); + it != items.end(); + ++it) + { + item_type const& item = it->second; + std::string const& key(std::tr1::get<0>(item)); + std::string const& value(std::tr1::get<1>(item)); + std::string const& comment(std::tr1::get<2>(item)); + set_value(groupname, key, value, comment); + } + } + return *this; +} + +keyfile +operator + (keyfile const& lhs, + keyfile const& rhs) +{ + keyfile ret(lhs); + ret += rhs; + return ret; +} + +const keyfile::group_type * +keyfile::find_group (std::string const& group) const +{ + group_map_type::const_iterator pos = this->groups.find(group); + if (pos != this->groups.end()) + return &pos->second; + + return 0; +} + +keyfile::group_type * +keyfile::find_group (std::string const& group) +{ + group_map_type::iterator pos = this->groups.find(group); + if (pos != this->groups.end()) + return &pos->second; + + return 0; +} + +const keyfile::item_type * +keyfile::find_item (std::string const& group, + std::string const& key) const +{ + const group_type *found_group = find_group(group); + if (found_group) + { + item_map_type const& items = std::tr1::get<1>(*found_group); + item_map_type::const_iterator pos = items.find(key); + if (pos != items.end()) + return &pos->second; + } + + return 0; +} + +keyfile::item_type * +keyfile::find_item (std::string const& group, + std::string const& key) +{ + group_type *found_group = find_group(group); + if (found_group) + { + item_map_type& items = std::tr1::get<1>(*found_group); + item_map_type::iterator pos = items.find(key); + if (pos != items.end()) + return &pos->second; + } + + return 0; +} + +void +keyfile::print_comment (std::string const& comment, + std::ostream& stream) +{ + std::string::size_type last_pos = 0; + std::string::size_type pos = comment.find_first_of('\n', last_pos); + + while (1) + { + if (last_pos == pos) + stream << "#\n"; + else + stream << '#' << comment.substr(last_pos, pos - last_pos) << '\n'; + + // Find next + if (pos < comment.length() - 1) + { + last_pos = pos + 1; + pos = comment.find_first_of('\n', last_pos); + } + else + break; + } +} + +void +keyfile::check_priority (std::string const& group, + std::string const& key, + priority priority, + bool valid) const +{ + if (valid == false) + { + switch (priority) + { + case PRIORITY_REQUIRED: + { + throw error(group, parse_error::MISSING_KEY, key); + } + break; + default: + break; + } + } + else + { + switch (priority) + { + case PRIORITY_DEPRECATED: + log_warning() + << format(_("%1% chroot: A deprecated parameter \"%2%\" has been specified.")) + % group % key + << std::endl; + log_info() + << _("This option will be removed in the future.") << std::endl; + break; + case PRIORITY_OBSOLETE: + log_warning() + << format(_("%1% chroot: An obsolete parameter \"%2%\" has been specified.")) + % group % key + << std::endl; + log_info() + << _("This option has been removed, and no longer has any effect.") << std::endl; + case PRIORITY_DISALLOWED: + { + throw error(group, parse_error::DISALLOWED_KEY, key); + } + break; + default: + break; + } + } +} diff --git a/sbuild/sbuild-keyfile.h b/sbuild/sbuild-keyfile.h new file mode 100644 index 00000000..cc09ecc3 --- /dev/null +++ b/sbuild/sbuild-keyfile.h @@ -0,0 +1,736 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#ifndef SBUILD_KEYFILE_H +#define SBUILD_KEYFILE_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#ifdef HAVE_TR1_TUPLE +#include +#elif HAVE_BOOST_TUPLE_TUPLE_HPP +#include +namespace std { namespace tr1 { using boost::tuple; using boost::get; } } +#else +#error A shared_ptr implementation is not available +#endif + +#include + +namespace sbuild +{ + + /** + * Configuration file parser. This class loads an INI-style + * configuration file from a file or stream. The format is + * documented in schroot.conf(5). It is based upon the Glib + * GKeyFile class, which it is intended to replace. + */ + class keyfile + { + private: + /// Key-value-comment tuple. + typedef std::tr1::tuple item_type; + + /// Map between key name and key-value-comment tuple. + typedef std::map item_map_type; + + /// Group-items-comment tuple. + typedef std::tr1::tuple group_type; + + /// Map between group name and group-items-comment tuple. + typedef std::map group_map_type; + + public: + /// Configuration parameter priority. + enum priority + { + PRIORITY_OPTIONAL, ///< The parameter is optional. + PRIORITY_REQUIRED, ///< The parameter is required. + PRIORITY_DISALLOWED, ///< The parameter is not allowed in this context. + PRIORITY_DEPRECATED, ///< The parameter is deprecated, but functional. + PRIORITY_OBSOLETE ///< The parameter is obsolete, and not functional. + }; + + /// Exception type. + typedef parse_error error; + + /// The constructor. + keyfile (); + + /** + * The constructor. + * + * @param file the file to load the configuration from. + */ + keyfile (std::string const& file); + + /** + * The constructor. + * + * @param stream the stream to load the configuration from. + */ + keyfile (std::istream& stream); + + /// The destructor. + virtual ~keyfile (); + + /** + * Get a list of groups. + * + * @returns a list of groups in the keyfile. If no groups exist, + * the list will be empty. + */ + string_list + get_groups () const; + + /** + * Get a list of keys in a group. + * + * @param group the group to use. + * @returns a list of keys in a group. If no keys exist in the + * group, or the group does not exist, the list will be empty. + */ + string_list + get_keys (std::string const& group) const; + + /** + * Check if a group exists. + * + * @param group the group to check for. + * @returns true if the group exists, otherwise false. + */ + bool + has_group (std::string const& group) const; + + /** + * Check if a key exists. + * + * @param group the group the key is in. + * @param key the key to check for. + * @returns true if the key exists, otherwise false. + */ + bool + has_key (std::string const& group, + std::string const& key) const; + + /** + * Set a group. The group will be created (and the comment set) + * only if the group does not already exist. + * + * @param group the group to set. + * @param comment the comment to set. + */ + void + set_group (std::string const& group, + std::string const& comment); + + /** + * Get a group comment. + * + * @param group the group to find. + * @returns the comment. + */ + std::string + get_comment (std::string const& group) const; + + /** + * Get a key comment. + * + * @param group the group to find. + * @param key the key to find. + * @returns the comment. + */ + std::string + get_comment (std::string const& group, + std::string const& key) const; + + /** + * Get a key value. + * + * @param group the group the key is in. + * @param key the key to get. + * @param value the value to store the key's value in. This must + * be settable from an istream and be copyable. + * @returns true if the key was found, otherwise false (in which + * case value will be unchanged). + */ + template + bool + get_value (std::string const& group, + std::string const& key, + T& value) const + { + log_debug(DEBUG_INFO) << "Getting keyfile group=" << group + << ", key=" << key << std::endl; + const item_type *found_item = find_item(group, key); + if (found_item) + { + std::string const& strval(std::tr1::get<1>(*found_item)); + try + { + value = static_cast(parse_value(strval)); + return true; + } + catch (parse_value::error const& e) + { + error ep(group, key, parse_error::NONE, e.what()); + log_warning() << ep.what() << std::endl; + return false; + } + } + log_debug(DEBUG_NOTICE) << "key not found" << std::endl; + return false; + } + + /** + * Get a key value. If the value does not exist, is deprecated or + * obsolete, warn appropriately. + * + * @param group the group the key is in. + * @param key the key to get. + * @param priority the priority of the option. + * @param value the value to store the key's value in. This must + * be settable from an istream and be copyable. + * @returns true if the key was found, otherwise false (in which + * case value will be unchanged). + */ + template + bool + get_value (std::string const& group, + std::string const& key, + priority priority, + T& value) const + { + bool status = get_value(group, key, value); + check_priority(group, key, priority, status); + return status; + } + + /** + * Get a localised key string value. + * + * @param group the group the key is in. + * @param key the key to get. + * @param value the string to store the key's localised value in. + * @returns true if the key was found, otherwise false (in which + * case value will be unchanged). + */ + bool + get_locale_string (std::string const& group, + std::string const& key, + std::string& value) const; + + /** + * Get a localised key string value. If the value does not exist, + * is deprecated or obsolete, warn appropriately. + * + * @param group the group the key is in. + * @param key the key to get. + * @param priority the priority of the option. + * @param value the string to store the key's localised value in. + * @returns true if the key was found, otherwise false (in which + * case value will be unchanged). + */ + bool + get_locale_string (std::string const& group, + std::string const& key, + priority priority, + std::string& value) const; + + /** + * Get a localised key string value for a specific locale. + * + * @param group the group the key is in. + * @param key the key to get. + * @param locale the locale to use. + * @param value the string to store the key's localised value in. + * @returns true if the key was found, otherwise false (in which + * case value will be unchanged). + */ + bool + get_locale_string (std::string const& group, + std::string const& key, + std::string const& locale, + std::string& value) const; + + /** + * Get a localised key string value for a specific locale. If the + * value does not exist, is deprecated or obsolete, warn + * appropriately. + * + * @param group the group the key is in. + * @param key the key to get. + * @param locale the locale to use. + * @param priority the priority of the option. + * @param value the string to store the key's localised value in. + * @returns true if the key was found, otherwise false (in which + * case value will be unchanged). + */ + bool + get_locale_string (std::string const& group, + std::string const& key, + std::string const& locale, + priority priority, + std::string& value) const; + + /** + * Get a key value as a list. + * + * @param group the group the key is in. + * @param key the key to get. + * @param container the container to store the key's value in. + * The value type must be settable from an istream and be + * copyable. The list must be a container with a standard insert + * method. + * @returns true if the key was found, otherwise false (in which + * case value will be undefined). + */ + template + bool + get_list_value (std::string const& group, + std::string const& key, + C& container) const + { + std::string item_value; + if (get_value(group, key, item_value)) + { + string_list items = split_string(item_value, + std::string(1, this->separator)); + for (string_list::const_iterator pos = items.begin(); + pos != items.end(); + ++pos + ) + { + container.push_back(static_cast(parse_value(*pos))); + } + return true; + } + return false; + } + + /** + * Get a key value as a list. If the value does not exist, is + * deprecated or obsolete, warn appropriately. + * + * @param group the group the key is in. + * @param key the key to get. + * @param priority the priority of the option. + * @param container the container to store the key's value in. + * The value type must be settable from an istream and be + * copyable. The list must be a container with a standard insert + * method. + * @returns true if the key was found, otherwise false (in which + * case value will be undefined). + */ + template + bool + get_list_value (std::string const& group, + std::string const& key, + priority priority, + C& container) const + { + bool status = get_list_value(group, key, container); + check_priority(group, key, priority, status); + return status; + } + + /** + * Set a key value. + * + * @param group the group the key is in. + * @param key the key to set. + * @param value the value to get the key's value from. This must + * allow output to an ostream. + */ + template + void + set_value (std::string const& group, + std::string const& key, + T const& value) + { + set_value(group, key, value, std::string()); + } + + /** + * Set a key value. + * + * @param group the group the key is in. + * @param key the key to set. + * @param value the value to get the key's value from. This must + * @param comment the comment for this key. + * allow output to an ostream. + */ + template + void + set_value (std::string const& group, + std::string const& key, + T const& value, + std::string const& comment) + { + std::ostringstream os; + os.imbue(std::locale("C")); + os << std::boolalpha << value; + + set_group(group, ""); + group_type *found_group = find_group(group); + assert (found_group != 0); // should not fail + + item_map_type& items = std::tr1::get<1>(*found_group); + + item_map_type::iterator pos = items.find(key); + if (pos != items.end()) + items.erase(pos); + + items.insert + (item_map_type::value_type(key, + item_type(key, os.str(), comment))); + } + + /** + * Set a key value from a list. + * + * @param group the group the key is in. + * @param key the key to set. + * @param begin an iterator referring to the start of the + * list. The value type must allow output to an ostream. + * @param end an iterator referring to the end of the list. + */ + template + void + set_list_value (std::string const& group, + std::string const& key, + I begin, + I end) + { + set_list_value(group, key, begin, end, std::string()); + } + + /** + * Set a key value from a list. + * + * @param group the group the key is in. + * @param key the key to set. + * @param begin an iterator referring to the start of the + * list. The value type must allow output to an ostream. + * @param end an iterator referring to the end of the list. + * @param comment the comment for this key. + */ + template + void + set_list_value (std::string const& group, + std::string const& key, + I begin, + I end, + std::string const& comment) + { + std::string strval; + + for (I pos = begin; pos != end; ++ pos) + { + std::ostringstream os; + os.imbue(std::locale("C")); + os << std::boolalpha << *pos; + if (os) + { + strval += os.str(); + if (pos + 1 != end) + strval += this->separator; + } + } + + set_value (group, key, strval, comment); + } + + /** + * Remove a group. + * + * @param group the group to remove. + */ + void + remove_group (std::string const& group); + + /** + * Remove a key. + * + * @param group the group the key is in. + * @param key the key to remove. + */ + void + remove_key (std::string const& group, + std::string const& key); + + /** + * Add a keyfile to the keyfile. + * + * @param rhs the keyfile to add. + * @returns the modified keyfile. + */ + keyfile& + operator += (keyfile const& rhs); + + /** + * Add a keyfile to the keyfile. + * + * @param lhs the keyfile to add to. + * @param rhs the values to add. + * @returns the new keyfile. + */ + friend keyfile + operator + (keyfile const& lhs, + keyfile const& rhs); + + /** + * keyfile initialisation from an istream. + */ + template + friend + std::basic_istream& + operator >> (std::basic_istream& stream, + keyfile& kf) + { + keyfile tmp; + size_t linecount = 0; + std::string line; + std::string group; + std::string comment; + std::string key; + std::string value; + + while (std::getline(stream, line)) + { + linecount++; + + if (line.length() == 0) + { + // Empty line; do nothing. + } + else if (line[0] == '#') // Comment line + { + if (!comment.empty()) + comment += '\n'; + comment += line.substr(1); + } + else if (line[0] == '[') // Group + { + std::string::size_type fpos = line.find_first_of(']'); + std::string::size_type lpos = line.find_last_of(']'); + if (fpos == std::string::npos || lpos == std::string::npos || + fpos != lpos) + { + throw error(linecount, parse_error::INVALID_GROUP, line); + } + group = line.substr(1, fpos - 1); + + if (group.length() == 0) + { + throw error(linecount, parse_error::INVALID_GROUP, line); + } + + // Insert group + if (tmp.has_group(group)) + { + error e(linecount, parse_error::DUPLICATE_GROUP, group); + log_warning() << e.what() << std::endl; + } + else + tmp.set_group(group, comment); + comment.clear(); + } + else // Item + { + std::string::size_type pos = line.find_first_of('='); + if (pos == std::string::npos) + { + throw error(linecount, parse_error::INVALID_LINE, line); + } + if (pos == 0) + { + throw error(linecount, parse_error::NO_KEY, line); + } + key = line.substr(0, pos); + if (pos == line.length() - 1) + value = ""; + else + value = line.substr(pos + 1); + + // No group specified + if (group.empty()) + { + throw error(linecount, parse_error::NO_GROUP, line); + } + + // Insert item + if (tmp.has_key(group, key)) + { + error e(linecount, group, parse_error::DUPLICATE_KEY, key); + log_warning() << e.what() << std::endl; + } + else + tmp.set_value(group, key, value, comment); + comment.clear(); + } + } + + kf += tmp; + + return stream; + } + + /** + * keyfile output to an ostream. + */ + template + friend + std::basic_ostream& + operator << (std::basic_ostream& stream, + keyfile const& kf) + { + unsigned int group_count = 0; + + for (group_map_type::const_iterator gp = kf.groups.begin(); + gp != kf.groups.end(); + ++gp, ++group_count) + { + if (group_count > 0) + stream << '\n'; + + group_type const& group = gp->second; + std::string const& groupname = std::tr1::get<0>(group); + std::string const& comment = std::tr1::get<2>(group); + + if (comment.length() > 0) + print_comment(comment, stream); + + stream << '[' << groupname << ']' << '\n'; + + item_map_type const& items(std::tr1::get<1>(group)); + for (item_map_type::const_iterator it = items.begin(); + it != items.end(); + ++it) + { + item_type const& item = it->second; + std::string const& key(std::tr1::get<0>(item)); + std::string const& value(std::tr1::get<1>(item)); + std::string const& comment(std::tr1::get<2>(item)); + + if (comment.length() > 0) + print_comment(comment, stream); + + stream << key << '=' << value << '\n'; + } + } + + return stream; + } + + private: + /** + * Find a group by it's name. + * + * @param group the group to find. + * @returns the group, or 0 if not found. + */ + const group_type * + find_group (std::string const& group) const; + + /** + * Find a group by it's name. + * + * @param group the group to find. + * @returns the group, or 0 if not found. + */ + group_type * + find_group (std::string const& group); + + /** + * Find a key by it's group and name. + * + * @param group the group the key is in. + * @param key the key to find + * @returns the key, or 0 if not found. + */ + const item_type * + find_item (std::string const& group, + std::string const& key) const; + + /** + * Find a key by it's group and name. + * + * @param group the group the key is in. + * @param key the key to find + * @returns the key, or 0 if not found. + */ + item_type * + find_item (std::string const& group, + std::string const& key); + + /** + * Check if a key is missing or present when not permitted. + * + * @param group the group the key is in. + * @param key the key to get. + * @param priority the key priority. + * @param valid true if key exists, false if not existing. + */ + void + check_priority (std::string const& group, + std::string const& key, + priority priority, + bool valid) const; + + /** + * Print a comment to a stream. The comment will have hash ('#') + * marks printed at the start of each line. + * + * @param comment the comment to print. + * @param stream the stream to output to. + */ + static void + print_comment (std::string const& comment, + std::ostream& stream); + + /// The top-level groups. + group_map_type groups; + /// The separator used as a list item delimiter. + char separator; + }; + +} + +#endif /* SBUILD_KEYFILE_H */ + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/sbuild/sbuild-lock.cc b/sbuild/sbuild-lock.cc new file mode 100644 index 00000000..aa0bba84 --- /dev/null +++ b/sbuild/sbuild-lock.cc @@ -0,0 +1,300 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#include + +#include "sbuild-lock.h" + +#include +#include + +#include +#include +#include + +#include + +#include + +using boost::format; +using namespace sbuild; + +namespace +{ + + typedef std::pair emap; + + /** + * This is a list of the supported error codes. It's used to + * construct the real error codes map. + */ + emap init_errors[] = + { + emap(lock::TIMEOUT_HANDLER, N_("Failed to set timeout handler")), + emap(lock::TIMEOUT_SET, N_("Failed to set timeout")), + emap(lock::TIMEOUT_CANCEL, N_("Failed to cancel timeout")), + emap(lock::LOCK, N_("Failed to acquire lock (timed out)")), + emap(lock::LOCK_TIMEOUT, N_("Failed to acquire lock")), + emap(lock::DEVICE_LOCK, N_("Failed to acquire device lock")), + emap(lock::DEVICE_LOCK_TIMEOUT, N_("Failed to acquire device lock (timed out)")), + emap(lock::DEVICE_TEST, N_("Failed to test device lock")), + emap(lock::DEVICE_RELEASE, N_("Failed to release device lock")), + emap(lock::DEVICE_RELEASE_TIMEOUT, N_("Failed to release device lock (timed out)")) + }; + +} + +template<> +custom_error::map_type +custom_error::error_strings +(init_errors, + init_errors + (sizeof(init_errors) / sizeof(init_errors[0]))); + +namespace +{ + + volatile bool lock_timeout = false; + + /** + * Handle the SIGALRM signal. + * + * @param ignore the signal number. + */ + void + alarm_handler (int ignore) + { + /* This exists so that system calls get interrupted. */ + /* lock_timeout is used for polling for a timeout, rather than + interruption. */ + lock_timeout = true; + } +} + +lock::lock (): + saved_signals() +{ +} + +lock::~lock () +{ +} + +void +lock::set_alarm () +{ + struct sigaction new_sa; + sigemptyset(&new_sa.sa_mask); + new_sa.sa_flags = 0; + new_sa.sa_handler = alarm_handler; + + if (sigaction(SIGALRM, &new_sa, &this->saved_signals) != 0) + throw error(TIMEOUT_HANDLER, errno); +} + +void +lock::clear_alarm () +{ + /* Restore original handler */ + sigaction (SIGALRM, &this->saved_signals, NULL); +} + +void +lock::set_timer(struct itimerval const& timer) +{ + set_alarm(); + + if (setitimer(ITIMER_REAL, &timer, NULL) == -1) + { + clear_alarm(); + throw error(TIMEOUT_SET, errno); + } +} + +void +lock::unset_timer () +{ + struct itimerval disable_timer; + disable_timer.it_interval.tv_sec = disable_timer.it_interval.tv_usec = 0; + disable_timer.it_value.tv_sec = disable_timer.it_value.tv_usec = 0; + + if (setitimer(ITIMER_REAL, &disable_timer, NULL) == -1) + { + clear_alarm(); + throw error(TIMEOUT_CANCEL, errno); + } + + clear_alarm(); +} + +file_lock::file_lock (int fd): + lock(), + fd(fd) +{ +} + +file_lock::~file_lock () +{ +} + +void +file_lock::set_lock (type lock_type, + unsigned int timeout) +{ + try + { + struct itimerval timeout_timer; + timeout_timer.it_interval.tv_sec = timeout_timer.it_interval.tv_usec = 0; + timeout_timer.it_value.tv_sec = timeout; + timeout_timer.it_value.tv_usec = 0; + set_timer(timeout_timer); + + /* Now the signal handler and itimer are set, the function can't + return without stopping the timer and restoring the signal + handler to its original state. */ + + /* Wait on lock until interrupted by a signal if a timeout was set, + otherwise return immediately. */ + struct flock read_lock = + { + lock_type, + SEEK_SET, + 0, + 0, // Lock entire file + 0 + }; + + if (fcntl(this->fd, + (timeout != 0) ? F_SETLKW : F_SETLK, + &read_lock) == -1) + { + if (errno == EINTR) + throw error(LOCK_TIMEOUT); + else + throw error(LOCK, errno); + } + unset_timer(); + } + catch (error const& e) + { + unset_timer(); + throw; + } +} + +void +file_lock::unset_lock () +{ + set_lock(LOCK_NONE, 0); +} + +device_lock::device_lock (std::string const& device): + lock(), + device(device) +{ +} + +device_lock::~device_lock () +{ +} + +void +device_lock::set_lock (type lock_type, + unsigned int timeout) +{ + try + { + lock_timeout = false; + + struct itimerval timeout_timer; + timeout_timer.it_interval.tv_sec = timeout_timer.it_interval.tv_usec = 0; + timeout_timer.it_value.tv_sec = timeout; + timeout_timer.it_value.tv_usec = 0; + set_timer(timeout_timer); + + /* Now the signal handler and itimer are set, the function can't + return without stopping the timer and restoring the signal + handler to its original state. */ + + /* Wait on lock until interrupted by a signal if a timeout was set, + otherwise return immediately. */ + pid_t status = 0; + while (lock_timeout == false) + { + if (lock_type == LOCK_SHARED || lock_type == LOCK_EXCLUSIVE) + { + status = dev_lock(this->device.c_str()); + if (status == 0) // Success + break; + else if (status < 0) // Failure + { + throw error(DEVICE_LOCK); + } + } + else + { + pid_t cur_lock_pid = dev_testlock(this->device.c_str()); + if (cur_lock_pid < 0) // Test failure + { + throw error(DEVICE_TEST); + } + else if (cur_lock_pid > 0 && cur_lock_pid != getpid()) + { + // Another process owns the lock, so we successfully + // "drop" our nonexistent lock. + break; + } + status = dev_unlock(this->device.c_str(), getpid()); + if (status == 0) // Success + break; + else if (status < 0) // Failure + { + throw error(DEVICE_RELEASE); + } + } + } + + if (lock_timeout) + { + + format fmt(_("lock held by pid %1%")); + fmt % status; + throw error(((lock_type == LOCK_SHARED || lock_type == LOCK_EXCLUSIVE) + ? DEVICE_LOCK_TIMEOUT : DEVICE_RELEASE_TIMEOUT), + fmt.str()); + } + unset_timer(); + } + catch (error const& e) + { + unset_timer(); + throw; + } +} + +void +device_lock::unset_lock () +{ + set_lock(LOCK_NONE, 0); +} + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/sbuild/sbuild-lock.h b/sbuild/sbuild-lock.h new file mode 100644 index 00000000..71503b78 --- /dev/null +++ b/sbuild/sbuild-lock.h @@ -0,0 +1,200 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#ifndef SBUILD_LOCK_H +#define SBUILD_LOCK_H + +#include + +#include + +#include +#include +#include +#include + +namespace sbuild +{ + + /** + * Advisory locking. This class defines a simple interface for + * shared and exclusive locks. + */ + class lock + { + public: + /// Lock type. + enum type + { + LOCK_SHARED = F_RDLCK, ///< A shared (read) lock. + LOCK_EXCLUSIVE = F_WRLCK, ///< An exclusive (write) lock. + LOCK_NONE = F_UNLCK ///< No lock. + }; + + /// Error codes. + enum error_code + { + TIMEOUT_HANDLER, ///< Failed to set timeout handler. + TIMEOUT_SET, ///< Failed to set timeout. + TIMEOUT_CANCEL, ///< Failed to cancel timeout. + LOCK, ///< Failed to acquire lock (timed out). + LOCK_TIMEOUT, ///< Failed to acquire lock. + DEVICE_LOCK, ///< Failed to acquire device lock. + DEVICE_LOCK_TIMEOUT, ///< Failed to acquire device lock (timed out). + DEVICE_TEST, ///< Failed to test device lock. + DEVICE_RELEASE, ///< Failed to release device lock. + DEVICE_RELEASE_TIMEOUT ///< Failed to release device lock (timed out) + }; + + /// Exception type. + typedef custom_error error; + + /** + * Acquire a lock. + * + * @param lock_type the type of lock to acquire. + * @param timeout the time in seconds to wait on the lock. + */ + virtual void + set_lock (type lock_type, + unsigned int timeout) = 0; + + /** + * Release a lock. This is equivalent to set_lock with a + * lock_type of LOCK_NONE and a timeout of 0. + */ + virtual void + unset_lock () = 0; + + protected: + /// The constructor. + lock (); + /// The destructor. + virtual ~lock (); + + /** + * Set the SIGALARM handler. + * + * An error will be thrown on failure. + */ + void + set_alarm (); + + /** + * Restore the state of SIGALRM prior to starting lock + * acquisition. + */ + void + clear_alarm (); + + /** + * Set up an itimer for future expiry. This is used to interrupt + * system calls. This will set a handler for SIGALRM as a side + * effect (using set_alarm). + * + * An error will be thrown on failure. + * + * @param timer the timeout to set. + */ + void + set_timer (struct itimerval const& timer); + + /** + * Remove any itimer currently set up. This will clear any + * SIGALRM handler (using clear_alarm). + * + * An error will be thrown on failure. + */ + void + unset_timer (); + + private: + /// Signals saved during timeout. + struct sigaction saved_signals; + }; + + /** + * File lock. Simple whole-file shared and exclusive advisory + * locking based upon POSIX fcntl byte region locks. + */ + class file_lock : public lock + { + public: + /** + * The constructor. + * + * @param fd the file descriptor to lock. + */ + file_lock (int fd); + + /// The destructor. + virtual ~file_lock (); + + void + set_lock (type lock_type, + unsigned int timeout); + + void + unset_lock (); + + private: + /// The file descriptor to lock. + int fd; + }; + + /** + * Device lock. Set an advisory lock on a device. The lock is + * acquired using liblockdev lock_dev(). Note that a lock_type of + * LOCK_SHARED is equivalent to LOCK_EXCLUSIVE, because this lock + * type does not support shared locks. + */ + class device_lock : public lock + { + public: + /** + * The constructor. + * + * @param device the device to lock (full pathname). + */ + device_lock (std::string const& device); + + /// The destructor. + virtual ~device_lock (); + + void + set_lock (type lock_type, + unsigned int timeout); + + void + unset_lock (); + + private: + /// The device to lock. + std::string device; + }; + +} + +#endif /* SBUILD_LOCK_H */ + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/sbuild/sbuild-log.cc b/sbuild/sbuild-log.cc new file mode 100644 index 00000000..af6c8c05 --- /dev/null +++ b/sbuild/sbuild-log.cc @@ -0,0 +1,61 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#include + +#include "sbuild-log.h" +#include "sbuild-nostream.h" + +#include + +std::ostream& +sbuild::log_info () +{ + return std::cerr << "I: "; +} + +std::ostream& +sbuild::log_warning () +{ + return std::cerr << "W: "; +} + +std::ostream& +sbuild::log_error () +{ + return std::cerr << "E: "; +} + +std::ostream& +sbuild::log_debug (sbuild::DebugLevel level) +{ + if (debug_level > 0 && + level >= debug_level) + return std::cerr << "D(" << level << "): "; + else + return sbuild::cnull; +} + +sbuild::DebugLevel sbuild::debug_level = sbuild::DEBUG_NONE; + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/sbuild/sbuild-log.h b/sbuild/sbuild-log.h new file mode 100644 index 00000000..ef314959 --- /dev/null +++ b/sbuild/sbuild-log.h @@ -0,0 +1,84 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#ifndef SBUILD_LOG_H +#define SBUILD_LOG_H + +#include + +namespace sbuild +{ + + /// Debugging level. + enum DebugLevel + { + DEBUG_NONE = -1, ///< No debugging. + DEBUG_NOTICE = 1, ///< Notification messages. + DEBUG_INFO = 2, ///< Informational messages. + DEBUG_WARNING = 3, ///< Warning messages. + DEBUG_CRITICAL = 4 ///< Critical messages. + }; + + /** + * Log an informational message. + * + * @returns an ostream. + */ + std::ostream& + log_info (); + + /** + * Log a warning message. + * + * @returns an ostream. + */ + std::ostream& + log_warning (); + + /** + * Log an error message. + * + * @returns an ostream. + */ + std::ostream& + log_error (); + + /** + * Log a debug message. + * + * @param level the debug level of the message being logged. + * @returns an ostream. This will be a valid stream if level is + * greater or equal to debug_level, or else a null stream will be + * returned, resulting in no output. + */ + std::ostream& + log_debug (DebugLevel level); + + /// The debugging level in use. + extern DebugLevel debug_level; + +} + +#endif /* SBUILD_LOG_H */ + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/sbuild/sbuild-nostream.cc b/sbuild/sbuild-nostream.cc new file mode 100644 index 00000000..e6b34742 --- /dev/null +++ b/sbuild/sbuild-nostream.cc @@ -0,0 +1,28 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#include "sbuild-nostream.h" + +sbuild::nostream sbuild::cnull; + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/sbuild/sbuild-nostream.h b/sbuild/sbuild-nostream.h new file mode 100644 index 00000000..b233a7b4 --- /dev/null +++ b/sbuild/sbuild-nostream.h @@ -0,0 +1,86 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#ifndef SBUILD_NOSTREAM_H +#define SBUILD_NOSTREAM_H + +#include +#include + +namespace sbuild +{ + + /** + * Null stream buffer. This stream buffer acts as a bit-bucket, + * discarding all input. + */ + template > + class basic_nbuf: public std::basic_streambuf + { + /** + * Output buffer. EOF is never returned. + * + * @param c the character to output. + * @returns traits::not_eof is always returned, never traits::eof. + */ + typename traits::int_type + overflow (typename traits::int_type c) + { + return traits::not_eof(c); // indicate success + } + }; + + /** + * Null output stream. This ostream discards all input, because it + * uses a basic_nbuf stream buffer. + */ + template > + class basic_nostream: public std::basic_ostream + { + public: + /// The constructor. + basic_nostream (): + std::basic_ios(&nbuf), + std::basic_ostream(&nbuf) + { + init(&nbuf); + } + + private: + /// The stream buffer. + basic_nbuf nbuf; + }; + + /// A null ostream. + typedef basic_nostream nostream; + /// A wide null ostream. + typedef basic_nostream wnostream; + + /// A null ostream. + extern nostream cnull; + +} + +#endif /* SBUILD_NOSTREAM_H */ + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/sbuild/sbuild-parse-error.cc b/sbuild/sbuild-parse-error.cc new file mode 100644 index 00000000..5045be20 --- /dev/null +++ b/sbuild/sbuild-parse-error.cc @@ -0,0 +1,242 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#include + +#include "sbuild-i18n.h" +#include "sbuild-parse-error.h" + +#include + +using namespace sbuild; +using boost::format; + +namespace +{ + + typedef std::pair emap; + + /** + * This is a list of the supported error codes. It's used to + * construct the real error codes map. + */ + emap init_errors[] = + { + emap(parse_error::NONE, N_("No error")), + emap(parse_error::BAD_FILE, N_("Can't open file")), + emap(parse_error::BAD_VALUE, N_("Could not parse value")), + emap(parse_error::INVALID_LINE, N_("Invalid line")), + emap(parse_error::NO_GROUP, N_("No group specified")), + emap(parse_error::INVALID_GROUP, N_("Invalid group")), + emap(parse_error::DUPLICATE_GROUP, N_("Duplicate group")), + emap(parse_error::NO_KEY, N_("No key specified")), + emap(parse_error::DUPLICATE_KEY, N_("Duplicate key")), + emap(parse_error::MISSING_KEY, N_("Required key is missing")), + emap(parse_error::DISALLOWED_KEY, N_("Disallowed key used")) + }; + +} + +std::map +parse_error::error_strings +(init_errors, + init_errors + (sizeof(init_errors) / sizeof(init_errors[0]))); + + +parse_error::parse_error (type error, + std::string const& detail): + runtime_error(format_error(error, detail)) +{ +} + +parse_error::parse_error (size_t line, + type error, + std::string const& detail): + runtime_error(format_error(line, error, detail)) +{ +} + +parse_error::parse_error (size_t line, + std::string const& group, + type error, + std::string const& detail): + runtime_error(format_error(line, group, error, detail)) +{ +} + +parse_error::parse_error (size_t line, + std::string const& group, + std::string const& key, + type error, + std::string const& detail): + runtime_error(format_error(line, group, key, error, detail)) +{ +} + +parse_error::parse_error (std::string const& group, + type error, + std::string const& detail): + runtime_error(format_error(group, error, detail)) +{ +} + +parse_error::parse_error (std::string const& group, + std::string const& key, + type error, + std::string const& detail): + runtime_error(format_error(group, key, error, detail)) +{ +} + +const char * +parse_error::get_error (type error) +{ + std::map::const_iterator pos = + error_strings.find(error); + + if (pos != error_strings.end()) + return gettext(pos->second); + + return _("Unknown error"); +} + +std::string +parse_error::format_error (type error, + std::string const& detail) +{ + if (detail.length() > 0) + { + format fmt((error == NONE + ? "%2%" + : _("%1% \"%2%\""))); + fmt % get_error(error) % detail; + return fmt.str(); + } + else + return get_error(error); +} + +std::string +parse_error::format_error (size_t line, + type error, + std::string const& detail) +{ + if (detail.length() > 0) + { + format fmt((error == NONE + ? _("line %1%: %3%") + : _("line %1%: %2% \"%3%\""))); + fmt % line % get_error(error) % detail; + return fmt.str(); + } + else + { + format fmt(_("line %1%: %2%")); + fmt % line % get_error(error); + return fmt.str(); + } +} + +std::string +parse_error::format_error (size_t line, + std::string const& group, + type error, + std::string const& detail) +{ + if (detail.length() > 0) + { + format fmt((error == NONE + ? _("line %1% [%2%]: %4%") + : _("line %1% [%2%]: %3% \"%4%\""))); + fmt % line % group % get_error(error) % detail; + return fmt.str(); + } + else + { + format fmt(_("line %1% [%2%]: %3%")); + fmt % line % group % get_error(error); + return fmt.str(); + } +} + +std::string +parse_error::format_error (size_t line, + std::string const& group, + std::string const& key, + type error, + std::string const& detail) +{ + if (detail.length() > 0) + { + format fmt((error == NONE + ? _("line %1% [%2%] %3%: %5%") + : _("line %1% [%2%] %3%: %4% \"%5%\""))); + fmt % line % group % key % get_error(error) % detail; + return fmt.str(); + } + else + { + format fmt(_("line %1% [%2%] %3%: %4%")); + fmt % line % group % key % get_error(error); + return fmt.str(); + } +} + +std::string +parse_error::format_error (std::string const& group, + type error, + std::string const& detail) +{ + if (detail.length() > 0) + { + format fmt((error == NONE + ? _("[%1%]: %3%") + : _("[%1%]: %2% \"%3%\""))); + fmt % group % get_error(error) % detail; + return fmt.str(); + } + else + { + format fmt(_("[%1%]: %2%")); + fmt % group % get_error(error); + return fmt.str(); + } +} + +std::string +parse_error::format_error (std::string const& group, + std::string const& key, + type error, + std::string const& detail) +{ + if (detail.length() > 0) + { + format fmt((error == NONE + ? _("[%1%] %2%: %4%") + : _("[%1%] %2%: %3% \"%4%\""))); + fmt % group % key % get_error(error) % detail; + return fmt.str(); + } + else + { + format fmt(_("[%1%] %2%: %3%")); + fmt % group % key % get_error(error); + return fmt.str(); + } +} diff --git a/sbuild/sbuild-parse-error.h b/sbuild/sbuild-parse-error.h new file mode 100644 index 00000000..b0be9713 --- /dev/null +++ b/sbuild/sbuild-parse-error.h @@ -0,0 +1,227 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#ifndef SBUILD_PARSE_ERROR_H +#define SBUILD_PARSE_ERROR_H + +#include +#include + +#include +#include + +#include + +namespace sbuild +{ + + /** + * Parse error. + */ + class parse_error : public runtime_error + { + public: + enum type + { + NONE, ///< No error occured. Used for detail only. + BAD_FILE, ///< The file to parse couldn't be opened. + BAD_VALUE, ///< The value could not be parsed. + INVALID_LINE, ///< The line is invalid. + NO_GROUP, ///< No group was specified. + INVALID_GROUP, ///< The group is invalid. + DUPLICATE_GROUP, ///< The group is a duplicate. + NO_KEY, ///< No key was specified. + DUPLICATE_KEY, ///< The key is a duplicate. + MISSING_KEY, ///< The key is missing. + DISALLOWED_KEY ///< The key is not allowed. + }; + + /** + * The constructor. + * + * @param error the error code. + * @param detail the details of the error. + */ + parse_error (type error, + std::string const& detail); + + /** + * The constructor. + * + * @param line the line the error occured on. + * @param error the error code. + * @param detail the details of the error. + */ + parse_error (size_t line, + type error, + std::string const& detail); + + /** + * The constructor. + * + * @param line the line the error occured on. + * @param group the group the error occured within. + * @param error the error code. + * @param detail the details of the error. + */ + parse_error (size_t line, + std::string const& group, + type error, + std::string const& detail); + + /** + * The constructor. + * + * @param line the line the error occured on. + * @param group the group the error occured within. + * @param key the key the error occured within. + * @param error the error code. + * @param detail the details of the error. + */ + parse_error (size_t line, + std::string const& group, + std::string const& key, + type error, + std::string const& detail); + + /** + * The constructor. + * + * @param group the group the error occured within. + * @param error the error code. + * @param detail the details of the error. + */ + parse_error (std::string const& group, + type error, + std::string const& detail); + + /** + * The constructor. + * + * @param group the group the error occured within. + * @param key the key the error occured within. + * @param error the error code. + * @param detail the details of the error. + */ + parse_error (std::string const& group, + std::string const& key, + type error, + std::string const& detail); + + private: + /// Mapping between error code and string. + static std::map error_strings; + + /** + * Get a translated error string. + * + * @param error the error code. + * @returns a translated error string. + */ + static const char * + get_error (type error); + + /** + * Format an error message. + * + * @param error the error code. + * @param detail the details of the error. + */ + static std::string + format_error (type error, + std::string const& detail); + + /** + * Format an error message. + * + * @param line the line the error occured on. + * @param error the error code. + * @param detail the details of the error. + */ + static std::string + format_error (size_t line, + type error, + std::string const& detail); + + /** + * Format an error message. + * + * @param line the line the error occured on. + * @param group the group the error occured within. + * @param error the error code. + * @param detail the details of the error. + */ + static std::string + format_error (size_t line, + std::string const& group, + type error, + std::string const& detail); + + /** + * Format an error message. + * + * @param line the line the error occured on. + * @param group the group the error occured within. + * @param key the key the error occured within. + * @param error the error code. + * @param detail the details of the error. + */ + static std::string + format_error (size_t line, + std::string const& group, + std::string const& key, + type error, + std::string const& detail); + + /** + * Format an error message. + * + * @param group the group the error occured within. + * @param error the error code. + * @param detail the details of the error. + */ + static std::string + format_error (std::string const& group, + type error, + std::string const& detail); + + /** + * Format an error message. + * + * @param group the group the error occured within. + * @param key the key the error occured within. + * @param error the error code. + * @param detail the details of the error. + */ + static std::string + format_error (std::string const& group, + std::string const& key, + type error, + std::string const& detail); + }; + +} + +#endif /* SBUILD_PARSE_ERROR_H */ + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/sbuild/sbuild-parse-value.cc b/sbuild/sbuild-parse-value.cc new file mode 100644 index 00000000..74aa04fb --- /dev/null +++ b/sbuild/sbuild-parse-value.cc @@ -0,0 +1,61 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#include + +#include "sbuild-parse-value.h" + +using namespace sbuild; + +parse_value::parse_value (std::string const& value): + value(value) +{ +} + +parse_value::~parse_value () +{ +} + +bool +parse_value::parse (bool& parsed_value) const +{ + if (this->value == "true" || this->value == "yes" || this->value == "1") + parsed_value = true; + else if (this->value == "false" || this->value == "no" || this->value == "0") + parsed_value = false; + else + return false; + + log_debug(DEBUG_NOTICE) << "value=" << parsed_value << std::endl; + return true; +} + +bool +parse_value::parse (std::string& parsed_value) const +{ + parsed_value = this->value; + log_debug(DEBUG_NOTICE) << "value=" << parsed_value << std::endl; + return true; +} + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/sbuild/sbuild-parse-value.h b/sbuild/sbuild-parse-value.h new file mode 100644 index 00000000..16b5491f --- /dev/null +++ b/sbuild/sbuild-parse-value.h @@ -0,0 +1,119 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#ifndef SBUILD_PARSE_VALUE_H +#define SBUILD_PARSE_VALUE_H + +#include +#include + +#include +#include + +namespace sbuild +{ + + /** + * Parse a text string value. This is a wrapper around a string + * value, to convert it into any desired type. + */ + class parse_value + { + public: + /// Exception type. + typedef parse_error error; + + /** + * The constructor. + * @param value the value to parse. + */ + parse_value (std::string const& value); + + /// The destructor. + virtual ~parse_value (); + + /** + * Convert object into any type T. + * @returns an object of type T; an exception will be thrown on + * parse failure. + */ + template + operator T (void) + { + T tmp; + + if (parse(tmp) == false) + { + throw error(parse_error::BAD_VALUE, this->value); + } + + return tmp; + } + + private: + /** + * Parse a boolean value. + * @param parsed_value the variable to store the parsed value. + * @returns true on success, false on failure. + */ + bool + parse (bool& parsed_value) const; + + /** + * Parse a string value. + * @param parsed_value the variable to store the parsed value. + * @returns true on success, false on failure. + */ + bool + parse (std::string& parsed_value) const; + + /** + * Parse a value of type T. + * @param parsed_value the variable to store the parsed value. + * @returns true on success, false on failure. + */ + template + bool + parse (T& parsed_value) const + { + std::istringstream is(this->value); + is.imbue(std::locale("C")); + T tmpval; + if (is >> tmpval) + { + parsed_value = tmpval; + log_debug(DEBUG_NOTICE) << "value=" << parsed_value << std::endl; + return true; + } + log_debug(DEBUG_NOTICE) << "parse error" << std::endl; + return false; + } + + std::string value; + }; + +} + +#endif /* SBUILD_PARSE_VALUE_H */ + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/sbuild/sbuild-personality.cc b/sbuild/sbuild-personality.cc new file mode 100644 index 00000000..7d420a88 --- /dev/null +++ b/sbuild/sbuild-personality.cc @@ -0,0 +1,189 @@ +/* Copyright © 2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#include + +#include "sbuild-personality.h" + +#include +#include +#include + +#ifdef __linux__ +#include +#endif + +#include + +using boost::format; +using namespace sbuild; + +namespace +{ + + typedef std::pair emap; + + /** + * This is a list of the supported error codes. It's used to + * construct the real error codes map. + */ + emap init_errors[] = + { + emap(sbuild::personality::SET, N_("Failed to set personality")) + }; + + typedef std::pair pmap; + + /** + * This is a list of the supported personalities. It's used to + * construct the real personalities map. + */ + pmap initial_personalities[] = + { + pmap("undefined", 0xffffffff), +#ifdef __linux__ + pmap("linux", PER_LINUX), + pmap("linux_32bit", PER_LINUX_32BIT), + pmap("svr4", PER_SVR4), + pmap("scorvr3", PER_SCOSVR3), + pmap("osr5", PER_OSR5), + pmap("wysev386", PER_WYSEV386), + pmap("iscr4", PER_ISCR4), + pmap("bsd", PER_BSD), + pmap("sunos", PER_SUNOS), + pmap("xenix", PER_XENIX), + pmap("linux32", PER_LINUX32), + pmap("irix32", PER_IRIX32), + pmap("irixn32", PER_IRIXN32), + pmap("irix64", PER_IRIX64), + pmap("riscos", PER_RISCOS), + pmap("solaris", PER_SOLARIS), + pmap("uw7", PER_UW7), + pmap("hpux", PER_HPUX), + pmap("osf4", PER_OSF4), +#endif + }; + +} + +template<> +std::map +custom_error::error_strings +(init_errors, + init_errors + (sizeof(init_errors) / sizeof(init_errors[0]))); + +std::map +sbuild::personality::personalities(initial_personalities, + initial_personalities + (sizeof(initial_personalities) / sizeof(initial_personalities[0]))); + +sbuild::personality::personality (): + persona( +#ifdef __linux__ + ::personality(0xffffffff) +#else + 0xffffffff +#endif + ) +{ +} + +sbuild::personality::personality (type persona): + persona(persona) +{ +} + +sbuild::personality::personality (std::string const& persona): + persona(find_personality(persona)) +{ +} + +sbuild::personality::~personality () +{ +} + +sbuild::personality::type +sbuild::personality::find_personality (std::string const& persona) +{ + std::map::const_iterator pos = + personalities.find(persona); + + if (pos != personalities.end()) + return pos->second; + + return 0xffffffff; +} + +std::string const& +sbuild::personality::find_personality (type persona) +{ + static const std::string unknown("unknown"); + + for (std::map::const_iterator pos = personalities.begin(); + pos != personalities.end(); + ++pos) + if (pos->second == persona) + return pos->first; + + return unknown; +} + +std::string const& +sbuild::personality::get_name () const +{ + return find_personality(this->persona); +} + +sbuild::personality::type +sbuild::personality::get () const +{ + return this->persona; +} + +void +sbuild::personality::set () const +{ +#ifdef __linux__ + /* Set the process execution domain using personality(2). */ + if (this->persona != 0xffffffff && + ::personality (this->persona) < 0) + { + throw error(get_name(), SET, errno); + } +#endif +} + +void +sbuild::personality::print_personalities (std::ostream& stream) +{ + for (std::map::const_iterator pos = personalities.begin(); + pos != personalities.end(); + ++pos) + { + stream << pos->first; + std::map::const_iterator stpos = pos; + if (++stpos != personalities.end()) + stream << ", "; + } +} + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/sbuild/sbuild-personality.h b/sbuild/sbuild-personality.h new file mode 100644 index 00000000..500e091b --- /dev/null +++ b/sbuild/sbuild-personality.h @@ -0,0 +1,163 @@ +/* Copyright © 2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#ifndef SBUILD_PERSONALITY_H +#define SBUILD_PERSONALITY_H + +#include +#include + +#include +#include +#include + +namespace sbuild +{ + + /** + * Chroot personality. A chroot may have a personality (also knows + * as a process execution domain) which is used to run non-native + * binaries. For example, running 32-bit Linux binaries on a 64-bit + * Linux system, or an SVR4 binary on a 32-bit Linux system. This + * is currently a Linux only feature; it does nothing on non-Linux + * systems. This is a wrapper around the personality(2) system + * call. + */ + class personality + { + public: + /// Personality type. + typedef unsigned long type; + + /// Error codes. + enum error_code + { + SET ///< Could not set personality. + }; + + /// Exception type. + typedef custom_error error; + + /** + * The constructor. On Linux systems, this is initialised with + * the current process' personality. On non-Linux systems, it is + * initialised as "undefined". + */ + personality (); + + /** + * The constructor. + * + * @param persona the persona to set. + */ + personality (type persona); + + /** + * The constructor. + * + * @param persona the persona to set. + */ + personality (std::string const& persona); + + ///* The destructor. + ~personality (); + + /** + * Get the name of the personality. + * + * @returns the personality name. + */ + std::string const& get_name () const; + + /** + * Get the personality. + * + * @returns the personality. + */ + type + get () const; + + /** + * Set the process personality. This sets the personality (if valid) using + * the personality(2) system call. If setting the personality + * fails, an error is thown. + */ + void + set () const; + + /** + * Print a list of the available personalities. + * + * @param stream the stream to output to. + */ + static void + print_personalities (std::ostream& stream); + + /** + * Print the personality name to a stream. + * + * @param stream the stream to output to. + * @param rhs the personality to output. + * @returns the stream. + */ + friend std::ostream& + operator << (std::ostream& stream, + personality const& rhs) + { + return stream << find_personality(rhs.persona); + } + + private: + /** + * Find a personality by name. + * + * @param persona the personality to find. + * @returns the personality type; this is -1 if the personality + * was undefined, or -2 if the personality was unknown (not + * found). + */ + static type + find_personality (std::string const& persona); + + /** + * Find a personality by number. + * + * @param persona the personality to find. + * @returns the personality name, "undefined" if the personality was + * not defined, or "unknown" if the personality was not found. + */ + static std::string const& + find_personality (type persona); + + /// The personality type. + type persona; + + /// Mapping between personality name and type. + static std::map personalities; + }; + +} + +#endif /* SBUILD_PERSONALITY_H */ + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/sbuild/sbuild-session.cc b/sbuild/sbuild-session.cc new file mode 100644 index 00000000..4940a3c9 --- /dev/null +++ b/sbuild/sbuild-session.cc @@ -0,0 +1,1162 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#include + +#include "sbuild-chroot-plain.h" +#include "sbuild-chroot-lvm-snapshot.h" +#include "sbuild-session.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include + +#include + +using std::cout; +using std::endl; +using boost::format; +using namespace sbuild; + +namespace +{ + + typedef std::pair emap; + + /** + * This is a list of the supported error codes. It's used to + * construct the real error codes map. + */ + emap init_errors[] = + { + emap(session::CHROOT_UNKNOWN, N_("Failed to find chroot")), + emap(session::CHROOT_LOCK, N_("Failed to lock chroot")), + emap(session::CHROOT_UNLOCK, N_("Failed to unlock chroot")), + emap(session::CHROOT_SETUP, N_("Chroot setup failed")), + emap(session::SIGHUP_SET, N_("Failed to set hangup signal handler")), + emap(session::SIGHUP_CATCH, N_("Caught hangup signal")), + emap(session::CHILD_FORK, N_("Failed to fork child")), + emap(session::CHILD_WAIT, N_("Wait for child failed")), + emap(session::CHILD_SIGNAL, N_("Child terminated by signal")), + emap(session::CHILD_CORE, N_("Child dumped core")), + emap(session::CHILD_FAIL, N_("Child exited abnormally (reason unknown; not a signal or core dump)")), + emap(session::USER_SWITCH, N_("User switching is not permitted")) + }; + + /** + * Get the current working directory. If it can't be found, fall + * back to root. + * + * @returns the current working directory. + */ + std::string + getcwd () + { + std::string cwd; + + char *raw_cwd = ::getcwd (NULL, 0); + if (raw_cwd) + cwd = raw_cwd; + else + cwd = "/"; + free(raw_cwd); + + return cwd; + } + + /** + * Check group membership. + * + * @param group the group to check for. + * @returns true if the user is a member of group, otherwise false. + */ + bool + is_group_member (std::string const& group) + { + errno = 0; + struct group *groupbuf = getgrnam(group.c_str()); + if (groupbuf == NULL) + { + if (errno == 0) + log_error() << format(_("%1%: Group not found")) % group << endl; + else + log_error() << format(_("%1%: Group not found: %2%")) + % group % strerror(errno) + << endl; + exit (EXIT_FAILURE); + } + + bool group_member = false; + if (groupbuf->gr_gid == getgid()) + { + group_member = true; + } + else + { + int supp_group_count = getgroups(0, NULL); + if (supp_group_count < 0) + { + log_error() << format(_("Can't get supplementary group count: %1%")) + % strerror(errno) + << endl; + exit (EXIT_FAILURE); + } + if (supp_group_count > 0) + { + gid_t *supp_groups = new gid_t[supp_group_count]; + if (getgroups(supp_group_count, supp_groups) < 1) + { + log_error() << format(_("Can't get supplementary groups: %1%")) + % strerror(errno) + << endl; + exit (EXIT_FAILURE); + } + + for (int i = 0; i < supp_group_count; ++i) + { + if (groupbuf->gr_gid == supp_groups[i]) + group_member = true; + } + delete[] supp_groups; + } + } + + return group_member; + } + + volatile bool sighup_called = false; + + /** + * Handle the SIGALRM signal. + * + * @param ignore the signal number. + */ + void + sighup_handler (int ignore) + { + /* This exists so that system calls get interrupted. */ + sighup_called = true; + } + +#ifdef SBUILD_DEBUG + volatile bool child_wait = true; +#endif + +} + +template<> +std::map +custom_error::error_strings +(init_errors, + init_errors + (sizeof(init_errors) / sizeof(init_errors[0]))); + +session::session (std::string const& service, + config_ptr& config, + operation operation, + sbuild::string_list const& chroots): + auth(service), + config(config), + chroots(chroots), + chroot_status(true), + child_status(0), + session_operation(operation), + session_id(), + force(false), + saved_signals(), + cwd(getcwd()) +{ +} + +session::~session () +{ +} + +session::config_ptr const& +session::get_config () const +{ + return this->config; +} + +void +session::set_config (config_ptr& config) +{ + this->config = config; +} + +string_list const& +session::get_chroots () const +{ + return this->chroots; +} + +void +session::set_chroots (string_list const& chroots) +{ + this->chroots = chroots; +} + +session::operation +session::get_operation () const +{ + return this->session_operation; +} + +void +session::set_operation (operation operation) +{ + this->session_operation = operation; +} + +std::string const& +session::get_session_id () const +{ + return this->session_id; +} + +void +session::set_session_id (std::string const& session_id) +{ + this->session_id = session_id; +} + +bool +session::get_force () const +{ + return this->force; +} + +void +session::set_force (bool force) +{ + this->force = force; +} + +int +session::get_child_status () const +{ + return this->child_status; +} + +auth::status +session::get_chroot_auth_status (auth::status status, + chroot::ptr const& chroot) const +{ + string_list const& users = chroot->get_users(); + string_list const& root_users = chroot->get_root_users(); + string_list const& groups = chroot->get_groups(); + string_list const& root_groups = chroot->get_root_groups(); + + bool in_users = false; + bool in_root_users = false; + bool in_groups = false; + bool in_root_groups = false; + + sbuild::string_list::const_iterator upos = + find(users.begin(), users.end(), get_ruser()); + if (upos != users.end()) + in_users = true; + + sbuild::string_list::const_iterator rupos = + find(root_users.begin(), root_users.end(), get_ruser()); + if (rupos != root_users.end()) + in_root_users = true; + + if (!groups.empty()) + { + for (string_list::const_iterator gp = groups.begin(); + gp != groups.end(); + ++gp) + if (is_group_member(*gp)) + in_groups = true; + } + + if (!root_groups.empty()) + { + for (string_list::const_iterator gp = root_groups.begin(); + gp != root_groups.end(); + ++gp) + if (is_group_member(*gp)) + in_root_groups = true; + } + + /* + * No auth required if in root users or root groups and + * changing to root, or if the uid is not changing. If not + * in user or group, authentication fails immediately. + */ + if ((in_users == true || in_groups == true || + in_root_users == true || in_root_groups == true) && + this->get_ruid() == this->get_uid()) + { + status = change_auth(status, auth::STATUS_NONE); + } + else if ((in_root_users == true || in_root_groups == true) && + this->get_uid() == 0) + { + status = change_auth(status, auth::STATUS_NONE); + } + else if (in_users == true || in_groups == true) + // Auth required if not in root group + { + status = change_auth(status, auth::STATUS_USER); + } + else // Not in any groups + { + if (this->get_ruid() == 0) + status = change_auth(status, auth::STATUS_USER); + else + status = change_auth(status, auth::STATUS_FAIL); + } + + return status; +} + +auth::status +session::get_auth_status () const +{ + assert(!this->chroots.empty()); + if (this->config.get() == 0) return auth::STATUS_FAIL; + + /* + * Note that the root user can't escape authentication. This is + * because pam_rootok.so should be used in the PAM configuration if + * root should automatically be granted access. The only exception + * is that the root group doesn't need to be added to the groups or + * root groups lists. + */ + + auth::status status = auth::STATUS_NONE; + + /* @todo Use set difference rather than iteration and + is_group_member. */ + for (string_list::const_iterator cur = this->chroots.begin(); + cur != this->chroots.end(); + ++cur) + { + const chroot::ptr chroot = this->config->find_alias(*cur); + if (!chroot) // Should never happen, but cater for it anyway. + { + log_warning() << format(_("No chroot found matching alias '%1%'")) + % *cur + << endl; + status = change_auth(status, auth::STATUS_FAIL); + } + + status = change_auth(status, get_chroot_auth_status(status, chroot)); + } + + return status; +} + +void +session::run_impl () +{ + assert(this->config.get() != NULL); + assert(!this->chroots.empty()); + +try + { + sighup_called = false; + set_sighup_handler(); + + for (string_list::const_iterator cur = this->chroots.begin(); + cur != this->chroots.end(); + ++cur) + { + log_debug(DEBUG_NOTICE) + << format("Running session in %1% chroot:") % *cur + << endl; + + const chroot::ptr ch = this->config->find_alias(*cur); + if (!ch) // Should never happen, but cater for it anyway. + { + throw error(*cur, CHROOT_UNKNOWN); + } + + chroot::ptr chroot(ch->clone()); + + /* If restoring a session, set the session ID from the + chroot name, or else generate it. Only chroots which + support session creation append a UUID to the session + ID. */ + if (chroot->get_active() || + !(chroot->get_session_flags() & chroot::SESSION_CREATE)) + { + set_session_id(chroot->get_name()); + } + else + { + uuid_t uuid; + char uuid_str[37]; + uuid_generate(uuid); + uuid_unparse(uuid, uuid_str); + uuid_clear(uuid); + std::string session_id(chroot->get_name() + "-" + uuid_str); + set_session_id(session_id); + } + + /* Activate chroot. */ + chroot->set_active(true); + + /* If a chroot mount location has not yet been set, and the + chroot is not a plain chroot, set a mount location with the + session id. */ + { + chroot_plain *plain = dynamic_cast(chroot.get()); + if (chroot->get_mount_location().empty() && + (plain == 0 || plain->get_run_setup_scripts() == true)) + { + std::string location(std::string(SCHROOT_MOUNT_DIR) + "/" + + this->session_id); + chroot->set_mount_location(location); + } + } + + /* Chroot types which create a session (e.g. LVM devices) + need the chroot name respecifying. */ + if (chroot->get_session_flags() & chroot::SESSION_CREATE) + { + chroot->set_name(this->session_id); + chroot->set_aliases(string_list()); + } + + /* LVM devices need the snapshot device name specifying. */ + chroot_lvm_snapshot *snapshot = 0; + if ((snapshot = dynamic_cast(chroot.get())) != 0) + { + std::string dir(dirname(snapshot->get_device(), '/')); + std::string device(dir + "/" + this->session_id); + snapshot->set_snapshot_device(device); + } + + try + { + /* Run setup-start chroot setup scripts. */ + setup_chroot(chroot, chroot::SETUP_START); + if (this->session_operation == OPERATION_BEGIN) + cout << this->session_id << endl; + + /* Run recover scripts. */ + setup_chroot(chroot, chroot::SETUP_RECOVER); + + try + { + /* Run exec-start scripts. */ + setup_chroot(chroot, chroot::EXEC_START); + + /* Run session if setup succeeded. */ + if (this->session_operation == OPERATION_AUTOMATIC || + this->session_operation == OPERATION_RUN) + run_chroot(chroot); + + /* Run exec-stop scripts whether or not there was an + error. */ + setup_chroot(chroot, chroot::EXEC_STOP); + } + catch (error const& e) + { + setup_chroot(chroot, chroot::EXEC_STOP); + throw; + } + + } + catch (error const& e) + { + try + { + setup_chroot(chroot, chroot::SETUP_STOP); + } + catch (error const& discard) + { + } + chroot->set_active(false); + throw; + } + + /* Run setup-stop chroot setup scripts whether or not there + was an error. */ + setup_chroot(chroot, chroot::SETUP_STOP); + + /* Deactivate chroot. */ + chroot->set_active(false); + } + + clear_sighup_handler(); + } +catch (error const& e) + { + clear_sighup_handler(); + + /* If a command was not run, but something failed, the exit + status still needs setting. */ + if (this->child_status == 0) + this->child_status = EXIT_FAILURE; + throw; + } +} + +string_list +session::get_login_directories () const +{ + string_list ret; + + // Set current working directory. + ret.push_back(this->cwd); + + // Set $HOME. + environment env = get_pam_environment(); + std::string home; + if (env.get("HOME", home) && + std::find(ret.begin(), ret.end(), home) == ret.end()) + ret.push_back(home); + + // Set passwd home. + if (std::find(ret.begin(), ret.end(), get_home()) == ret.end()) + ret.push_back(get_home()); + + // Final fallback to root. + if (std::find(ret.begin(), ret.end(), "/") == ret.end()) + ret.push_back("/"); + + return ret; +} + +string_list +session::get_command_directories () const +{ + string_list ret; + + // Set current working directory. + ret.push_back(this->cwd); + + return ret; +} + +std::string +session::get_shell () const +{ + assert (!auth::get_shell().empty()); + std::string shell = auth::get_shell(); + + struct stat statbuf; + if (stat(shell.c_str(), &statbuf) < 0) + { + if (shell != "/bin/sh") + { + log_warning() << format(_("%1%: Shell not available: %2%")) + % shell % strerror(errno) << endl; + shell = "/bin/sh"; + log_warning() << format(_("Falling back to %1%")) + % shell << endl; + } + } + + return shell; +} + +void +session::get_command (sbuild::chroot::ptr& session_chroot, + std::string& file, + string_list& command) const +{ + /* Run login shell */ + if (command.empty() || + command[0].empty()) // No command + get_login_command(session_chroot, file, command); + else + get_user_command(session_chroot, file, command); +} + +void +session::get_login_command (sbuild::chroot::ptr& session_chroot, + std::string& file, + string_list& command) const +{ + command.clear(); + + std::string shell = get_shell(); + file = shell; + + if (get_environment().empty() && + session_chroot->get_command_prefix().empty()) + // Not keeping environment and can setup argv correctly; login shell + { + std::string shellbase = basename(shell, '/'); + std::string loginshell = "-" + shellbase; + command.push_back(loginshell); + + log_debug(DEBUG_NOTICE) + << format("Running login shell: %1%") % shell << endl; + syslog(LOG_USER|LOG_NOTICE, + "[%s chroot] (%s->%s) Running login shell: \"%s\"", + session_chroot->get_name().c_str(), + get_ruser().c_str(), get_user().c_str(), + shell.c_str()); + } + else + { + command.push_back(shell); + log_debug(DEBUG_NOTICE) + << format("Running shell: %1%") % shell << endl; + syslog(LOG_USER|LOG_NOTICE, + "[%s chroot] (%s->%s) Running shell: \"%s\"", + session_chroot->get_name().c_str(), + get_ruser().c_str(), get_user().c_str(), + shell.c_str()); + } + + if (get_verbosity() != auth::VERBOSITY_QUIET) + { + std::string format_string; + if (get_ruid() == get_uid()) + { + if (get_environment().empty() && + session_chroot->get_command_prefix().empty()) + format_string = _("[%1% chroot] Running login shell: \"%4%\""); + else + format_string = _("[%1% chroot] Running shell: \"%4%\""); + } + else + { + if (get_environment().empty() && + session_chroot->get_command_prefix().empty()) + format_string = _("[%1% chroot] (%2%->%3%) Running login shell: \"%4%\""); + else + format_string = _("[%1% chroot] (%2%->%3%) Running shell: \"%4%\""); + } + + format fmt(format_string); + fmt % session_chroot->get_name() + % get_ruser() % get_user() + % shell; + log_info() << fmt << endl; + } +} + +void +session::get_user_command (sbuild::chroot::ptr& session_chroot, + std::string& file, + string_list& command) const +{ + /* Search for program in path. */ + environment env = get_pam_environment(); + std::string path; + if (!env.get("PATH", path)) + path.clear(); + + file = find_program_in_path(command[0], path, ""); + if (file.empty()) + file = command[0]; + std::string commandstring = string_list_to_string(command, " "); + log_debug(DEBUG_NOTICE) + << format("Running command: %1%") % commandstring << endl; + syslog(LOG_USER|LOG_NOTICE, "[%s chroot] (%s->%s) Running command: \"%s\"", + session_chroot->get_name().c_str(), get_ruser().c_str(), get_user().c_str(), commandstring.c_str()); + + if (get_verbosity() != auth::VERBOSITY_QUIET) + { + std::string format_string; + if (get_ruid() == get_uid()) + format_string = _("[%1% chroot] Running command: \"%4%\""); + else + format_string = (_("[%1% chroot] (%2%->%3%) Running command: \"%4%\"")); + + format fmt(format_string); + fmt % session_chroot->get_name() + % get_ruser() % get_user() + % commandstring; + log_info() << fmt << endl; + } +} + +void +session::setup_chroot (sbuild::chroot::ptr& session_chroot, + sbuild::chroot::setup_type setup_type) +{ + assert(!session_chroot->get_name().empty()); + + if (!((this->session_operation == OPERATION_BEGIN && + setup_type == chroot::SETUP_START) || + (this->session_operation == OPERATION_RECOVER && + setup_type == chroot::SETUP_RECOVER) || + (this->session_operation == OPERATION_END && + setup_type == chroot::SETUP_STOP) || + (this->session_operation == OPERATION_RUN && + (setup_type == chroot::EXEC_START || + setup_type == chroot::EXEC_STOP)) || + (this->session_operation == OPERATION_AUTOMATIC && + (setup_type == chroot::SETUP_START || + setup_type == chroot::SETUP_STOP || + setup_type == chroot::EXEC_START || + setup_type == chroot::EXEC_STOP)))) + return; + + if (((setup_type == chroot::SETUP_START || + setup_type == chroot::SETUP_RECOVER || + setup_type == chroot::SETUP_STOP) && + session_chroot->get_run_setup_scripts() == false) || + ((setup_type == chroot::EXEC_START || + setup_type == chroot::EXEC_STOP) && + session_chroot->get_run_exec_scripts() == false)) + return; + + if (setup_type == chroot::SETUP_START) + this->chroot_status = true; + + try + { + session_chroot->lock(setup_type); + } + catch (chroot::error const& e) + { + this->chroot_status = false; + try + { + // Release lock, which also removes session metadata. + session_chroot->unlock(setup_type, 0); + } + catch (chroot::error const& ignore) + { + } + throw error(session_chroot->get_name(), CHROOT_LOCK, e.what()); + } + + std::string setup_type_string; + if (setup_type == chroot::SETUP_START) + setup_type_string = "setup-start"; + else if (setup_type == chroot::SETUP_RECOVER) + setup_type_string = "setup-recover"; + else if (setup_type == chroot::SETUP_STOP) + setup_type_string = "setup-stop"; + else if (setup_type == chroot::EXEC_START) + setup_type_string = "exec-start"; + else if (setup_type == chroot::EXEC_STOP) + setup_type_string = "exec-stop"; + + std::string chroot_status_string; + if (this->chroot_status) + chroot_status_string = "ok"; + else + chroot_status_string = "fail"; + + string_list arg_list; + arg_list.push_back(RUN_PARTS); // Run run-parts(8) + if (get_verbosity() == auth::VERBOSITY_VERBOSE) + arg_list.push_back("--verbose"); + arg_list.push_back("--lsbsysinit"); + arg_list.push_back("--exit-on-error"); + if (setup_type == chroot::SETUP_STOP || + setup_type == chroot::EXEC_STOP) + arg_list.push_back("--reverse"); + format arg_fmt1("--arg=%1%"); + arg_fmt1 % setup_type_string; + arg_list.push_back(arg_fmt1.str()); + format arg_fmt2("--arg=%1%"); + arg_fmt2 % chroot_status_string; + arg_list.push_back(arg_fmt2.str()); + if (setup_type == chroot::SETUP_START || + setup_type == chroot::SETUP_RECOVER || + setup_type == chroot::SETUP_STOP) + arg_list.push_back(SCHROOT_CONF_SETUP_D); // Setup directory + else + arg_list.push_back(SCHROOT_CONF_EXEC_D); // Run directory + + /* Get a complete list of environment variables to set. We need to + query the chroot here, since this can vary depending upon the + chroot type. */ + environment env; + session_chroot->setup_env(env); + env.add("AUTH_USER", get_user()); + { + const char *verbosity = NULL; + switch (get_verbosity()) + { + case auth::VERBOSITY_QUIET: + verbosity = "quiet"; + break; + case auth::VERBOSITY_NORMAL: + verbosity = "normal"; + break; + case auth::VERBOSITY_VERBOSE: + verbosity = "verbose"; + break; + default: + log_debug(DEBUG_CRITICAL) << format(_("Invalid verbosity level: %1%, falling back to \"normal\"")) + % static_cast(get_verbosity()) + << endl; + verbosity = "normal"; + break; + } + env.add("AUTH_VERBOSITY", verbosity); + } + + env.add("MOUNT_DIR", SCHROOT_MOUNT_DIR); + env.add("LIBEXEC_DIR", SCHROOT_LIBEXEC_DIR); + env.add("PID", getpid()); + env.add("SESSION_ID", this->session_id); + + int exit_status = 0; + pid_t pid; + + if ((pid = fork()) == -1) + { + this->chroot_status = false; + throw error(session_chroot->get_name(), CHILD_FORK, errno); + } + else if (pid == 0) + { + // The setup scripts don't use our syslog fd. + closelog(); + + chdir("/"); + /* This is required to ensure the scripts run with uid=0 and gid=0, + otherwise setuid programs such as mount(8) will fail. This + should always succeed, because our euid=0 and egid=0.*/ + setuid(0); + setgid(0); + initgroups("root", 0); + if (exec (arg_list[0], arg_list, env)) + { + log_error() << format(_("Could not exec \"%1%\": %2%")) + % arg_list[0] % strerror(errno) + << endl; + exit (EXIT_FAILURE); + } + exit (EXIT_FAILURE); /* Should never be reached. */ + } + else + { + wait_for_child(pid, exit_status); + } + + try + { + session_chroot->unlock(setup_type, exit_status); + } + catch (chroot::error const& e) + { + this->chroot_status = false; + throw error(session_chroot->get_name(), CHROOT_UNLOCK, e.what()); + } + + if (exit_status != 0) + { + this->chroot_status = false; + + format fmt(_("stage=%1%")); + fmt % setup_type_string; + throw error(session_chroot->get_name(), CHROOT_SETUP, fmt.str()); + } +} + +void +session::run_child (sbuild::chroot::ptr& session_chroot) +{ + assert(!session_chroot->get_name().empty()); + + assert(!get_user().empty()); + assert(!get_shell().empty()); + assert(auth::pam != NULL); // PAM must be initialised + + // Store before chroot call. + this->cwd = getcwd(); + + std::string location(session_chroot->get_path()); + + /* Child errors result in immediate exit(). Errors are not + propagated back via an exception, because there is no longer any + higher-level handler to catch them. */ + try + { + open_session(); + } + catch (auth::error const& e) + { + log_error() << format(_("PAM error: %1%")) % e.what() + << endl; + exit (EXIT_FAILURE); + } + + /* Set group ID and supplementary groups */ + if (setgid (get_gid())) + { + log_error() << format(_("Could not set gid to '%1%'")) % get_gid() + << endl; + exit (EXIT_FAILURE); + } + if (initgroups (get_user().c_str(), get_gid())) + { + log_error() << _("Could not set supplementary group IDs") << endl; + exit (EXIT_FAILURE); + } + + /* Set the process execution domain. */ + try + { + session_chroot->get_persona().set(); + } + catch (personality::error const& e) + { + log_error() << e.what() << endl; + exit (EXIT_FAILURE); + } + + /* Enter the chroot */ + if (chdir (location.c_str())) + { + log_error() << format(_("Could not chdir to '%1%': %2%")) + % location % strerror(errno) + << endl; + exit (EXIT_FAILURE); + } + if (::chroot (location.c_str())) + { + log_error() << format(_("Could not chroot to '%1%': %2%")) + % location % strerror(errno) + << endl; + exit (EXIT_FAILURE); + } + + /* Set uid and check we are not still root */ + if (setuid (get_uid())) + { + log_error() << format(_("Could not set uid to '%1%'")) % get_uid() + << endl; + exit (EXIT_FAILURE); + } + if (!setuid (0) && get_uid()) + { + log_error() << _("Failed to drop root permissions.") + << endl; + exit (EXIT_FAILURE); + } + + std::string file; + string_list command(auth::get_command()); + + string_list dlist; + if (command.empty() || + command[0].empty()) // No command + dlist = get_login_directories(); + else + dlist = get_command_directories(); + log_debug(DEBUG_NOTICE) + << format("Directory fallbacks: %1%") % string_list_to_string(dlist, ", ") << endl; + + /* Attempt to chdir to current directory. */ + bool dir_changed = false; + for (string_list::const_iterator dpos = dlist.begin(); + dpos != dlist.end(); + ++dpos) + { + if (chdir ((*dpos).c_str()) < 0) + { + ((dpos + 1 == dlist.end()) ? log_error() : log_warning()) + << format(_("Could not chdir to '%1%': %2%")) + % *dpos % strerror(errno) + << endl; + } + else + { + if (dpos != dlist.begin()) + log_warning() << format(_("Falling back to '%1%'")) + % *dpos + << endl; + dir_changed = true; + break; + } + } + + if (dir_changed == false) + exit (EXIT_FAILURE); // Warning already logged. + + /* Fix up the command for exec. */ + get_command(session_chroot, file, command); + + /* Set up environment */ + environment env = get_pam_environment(); + log_debug(DEBUG_INFO) << "Set environment:\n" << env; + + // The user's command does not use our syslog fd. + closelog(); + + // Add command prefix. + string_list full_command(session_chroot->get_command_prefix()); + if (full_command.size() > 0) + file = full_command[0]; + for (string_list::const_iterator pos = command.begin(); + pos != command.end(); + ++pos) + full_command.push_back(*pos); + + /* Execute */ + if (exec (file, full_command, env)) + { + log_error() << format(_("Could not exec \"%1%\": %2%")) + % file % strerror(errno) + << endl; + exit (EXIT_FAILURE); + } + /* This should never be reached */ + exit(EXIT_FAILURE); +} + +void +session::wait_for_child (int pid, + int& child_status) +{ + child_status = EXIT_FAILURE; // Default exit status + + int status; + bool child_killed = false; + + while (1) + { + if (sighup_called && !child_killed) + { + log_error() << _("Caught hangup signal, terminating...") + << endl; + kill(pid, SIGHUP); + this->chroot_status = false; + child_killed = true; + } + + if (wait(&status) != pid) + { + if (errno == EINTR && sighup_called) + continue; // Kill child and wait again. + else + { + throw error(CHILD_WAIT, errno); + } + } + else if (sighup_called) + { + sighup_called = false; + throw error(SIGHUP_CATCH); + } + else + break; + } + + try + { + close_session(); + } + catch (auth::error const& e) + { + // TODO: rethrow or don't catch. + throw error(e.what()); + } + + if (!WIFEXITED(status)) + { + if (WIFSIGNALED(status)) + { + throw error(CHILD_SIGNAL, strsignal(WTERMSIG(status))); + } + else if (WCOREDUMP(status)) + throw error(CHILD_CORE); + else + throw error(CHILD_FAIL); + } + + child_status = WEXITSTATUS(status); +} + +void +session::run_chroot (sbuild::chroot::ptr& session_chroot) +{ + assert(!session_chroot->get_name().empty()); + + pid_t pid; + if ((pid = fork()) == -1) + { + throw error(CHILD_FORK, errno); + } + else if (pid == 0) + { +#ifdef SBUILD_DEBUG + while (child_wait) + ; +#endif + run_child(session_chroot); + exit (EXIT_FAILURE); /* Should never be reached. */ + } + else + { + wait_for_child(pid, this->child_status); + } +} + +int +session::exec (std::string const& file, + string_list const& command, + environment const& env) +{ + char **argv = string_list_to_strv(command); + char **envp = env.get_strv(); + int status; + + if ((status = execve(file.c_str(), argv, envp)) != 0) + { + strv_delete(argv); + strv_delete(envp); + } + + return status; +} + +void +session::set_sighup_handler () +{ + struct sigaction new_sa; + sigemptyset(&new_sa.sa_mask); + new_sa.sa_flags = 0; + new_sa.sa_handler = sighup_handler; + + if (sigaction(SIGHUP, &new_sa, &this->saved_signals) != 0) + { + throw error(SIGHUP_SET, errno); + } +} + +void +session::clear_sighup_handler () +{ + /* Restore original handler */ + sigaction (SIGHUP, &this->saved_signals, NULL); +} + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/sbuild/sbuild-session.h b/sbuild/sbuild-session.h new file mode 100644 index 00000000..2d333f98 --- /dev/null +++ b/sbuild/sbuild-session.h @@ -0,0 +1,402 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#ifndef SBUILD_SESSION_H +#define SBUILD_SESSION_H + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +namespace sbuild +{ + + /** + * Session handler. + * + * This class provides the session handling for schroot. It derives + * from auth, which performs all the necessary PAM actions, + * specialising it by overriding its virtual functions. This allows + * more sophisticated handling of user authorisation (users, groups, + * root-users and root-groups membership in the configuration file) + * and session management (setting up the session, entering the + * chroot and running the requested command or shell). + */ + class session : public auth + { + public: + /// Session operations. + enum operation + { + OPERATION_AUTOMATIC, ///< Begin, end and run a session automatically. + OPERATION_BEGIN, ///< Begin a session. + OPERATION_RECOVER, ///< Recover an existing (but inactive) session. + OPERATION_END, ///< End a session. + OPERATION_RUN ///< Run a command in an existing session. + }; + + /// Error codes. + enum error_code + { + CHROOT_UNKNOWN, ///< Failed to find chroot. + CHROOT_LOCK, ///< Failed to lock chroot. + CHROOT_UNLOCK, ///< Failed to unlock chroot. + CHROOT_SETUP, ///< Setup failed. + SIGHUP_SET, ///< Failed to set SIGHUP handler. + SIGHUP_CATCH, ///< Hangup signal caught. + CHILD_FORK, ///< Failed to fork child. + CHILD_WAIT, ///< Wait for child failed. + CHILD_SIGNAL, ///< Child terminated by signal. + CHILD_CORE, ///< Child dumped core. + CHILD_FAIL, ///< Child exited abnormally (reason unknown) + USER_SWITCH ///< User switching is not permitted. + }; + + /// Exception type. + typedef custom_error error; + + /// A shared_ptr to a chroot_config object. + typedef std::tr1::shared_ptr config_ptr; + + /// A shared_ptr to a session object. + typedef std::tr1::shared_ptr ptr; + + /** + * The constructor. + * + * @param service the PAM service name. + * @param config a shared_ptr to the chroot configuration. + * @param operation the session operation to perform. + * @param chroots the chroots to act upon. + */ + session (std::string const& service, + config_ptr& config, + operation operation, + string_list const& chroots); + + /// The destructor. + virtual ~session (); + + /** + * Get the configuration associated with this session. + * + * @returns a shared_ptr to the configuration. + */ + config_ptr const& + get_config () const; + + /** + * Set the configuration associated with this session. + * + * @param config a shared_ptr to the configuration. + */ + void + set_config (config_ptr& config); + + /** + * Get the chroots to use in this session. + * + * @returns a list of chroots. + */ + string_list const& + get_chroots () const; + + /** + * Set the chroots to use in this session. + * + * @param chroots a list of chroots. + */ + void + set_chroots (string_list const& chroots); + + /** + * Get the operation this session will perform. + * + * @returns the operation. + */ + operation + get_operation () const; + + /** + * Set the operation this session will perform. + * + * @param operation the operation. + */ + void + set_operation (operation operation); + + /** + * Get the session identifier. The session identifier is a unique + * string to identify a session. + * + * @returns the session id. + */ + std::string const& + get_session_id () const; + + /** + * Set the session identifier. The session identifier is a unique + * string to identify a session. + * + * @param session_id the session id. + */ + void + set_session_id (std::string const& session_id); + + /** + * Get the force status of this session. + * + * @returns true if operation will be forced, otherwise false. + */ + bool + get_force () const; + + /** + * Set the force status of this session. + * + * @param force true to force operation, otherwise false. + */ + void + set_force (bool force); + + /** + * Get the exit (wait) status of the last child process to run in this + * session. + * + * @returns the exit status. + */ + int + get_child_status () const; + + protected: + /** + * Check if authentication is required for a single chroot, taking + * users, groups, root-users and root-groups membership into + * account. + */ + virtual auth::status + get_chroot_auth_status (auth::status status, + chroot::ptr const& chroot) const; + + public: + /** + * Check if authentication is required, taking users, groups, + * root-users and root-groups membership of all chroots specified + * into account. + */ + virtual sbuild::auth::status + get_auth_status () const; + + protected: + /** + * Run a session. If a command has been specified, this will be + * run in each of the specified chroots. If no command has been + * specified, a login shell will run in the specified chroot. + * + * An error will be thrown on failure. + */ + virtual void + run_impl (); + + /** + * Get a list of directories to change to when running a login + * shell. Multiple directories are used as fallbacks. + * + * @returns a list of directories + */ + virtual string_list + get_login_directories () const; + + /** + * Get a list of directories to change to when running a command + * Multiple directories are used as fallbacks. + * + * @returns a list of directories + */ + virtual string_list + get_command_directories () const; + + /** + * Get the shell to run. This finds a suitable shell to run in + * the chroot, falling back to /bin/sh if necessary. Note that it + * assumes it is inside the chroot when called. + * + * @returns the shell. + */ + virtual std::string + get_shell () const; + + /** + * Get the command to run. + * + * @param session_chroot the chroot to setup. This must be + * present in the chroot list and the chroot configuration object. + * @param file the filename to pass to execve(2). + * @param command the argv to pass to execve(2). + */ + virtual void + get_command (chroot::ptr& session_chroot, + std::string& file, + string_list& command) const; + + /** + * Get the command to run a login shell. + * + * @param session_chroot the chroot to setup. This must be + * present in the chroot list and the chroot configuration object. + * @param file the filename to pass to execve(2). + * @param command the argv to pass to execve(2). + */ + virtual void + get_login_command (chroot::ptr& session_chroot, + std::string& file, + string_list& command) const; + + /** + * Get the command to run a user command. + * + * @param session_chroot the chroot to setup. This must be + * present in the chroot list and the chroot configuration object. + * @param file the filename to pass to execve(2). + * @param command the argv to pass to execve(2). + */ + virtual void + get_user_command (chroot::ptr& session_chroot, + std::string& file, + string_list& command) const; + + private: + /** + * execve wrapper. Run the command specified by file (an absolute + * pathname), using command and env as the argv and environment, + * respectively. + * + * @param file the program to execute. + * @param command the arguments to pass to the executable. + * @param env the environment. + * @returns the return value of the execve system call on failure. + */ + int + exec (std::string const& file, + string_list const& command, + environment const& env); + /** + * Setup a chroot. This runs all of the commands in setup.d or run.d. + * + * The environment variables CHROOT_NAME, CHROOT_DESCRIPTION, + * CHROOT_LOCATION, AUTH_USER and AUTH_VERBOSITY are set for use in + * setup scripts. See schroot-setup(5) for a complete list. + * + * An error will be thrown on failure. + * + * @param session_chroot the chroot to setup. This must be + * present in the chroot list and the chroot configuration object. + * @param setup_type the type of setup to perform. + */ + void + setup_chroot (chroot::ptr& session_chroot, + chroot::setup_type setup_type); + + /** + * Run command or login shell in the specified chroot. + * + * An error will be thrown on failure. + * + * @param session_chroot the chroot to setup. This must be + * present in the chroot list and the chroot configuration object. + */ + void + run_chroot (chroot::ptr& session_chroot); + + /** + * Run a command or login shell as a child process in the + * specified chroot. This method is only ever to be run in a + * child process, and will never return. + * + * @param session_chroot the chroot to setup. This must be + * present in the chroot list and the chroot configuration object. + */ + void + run_child (chroot::ptr& session_chroot); + + /** + * Wait for a child process to complete, and check its exit status. + * + * An error will be thrown on failure. + * + * @param pid the pid to wait for. + * @param child_status the place to store the child exit status. + */ + void + wait_for_child (int pid, + int& child_status); + + /** + * Set the SIGHUP handler. + * + * An error will be thrown on failure. + */ + void + set_sighup_handler (); + + /** + * Restore the state of SIGHUP prior to setting the handler. + */ + void + clear_sighup_handler (); + + /// The chroot configuration. + config_ptr config; + /// The chroots to run the session operation in. + string_list chroots; + /// The current chroot status. + int chroot_status; + /// The child exit status. + int child_status; + /// The session operation to perform. + operation session_operation; + /// The session identifier. + std::string session_id; + /// The session force status. + bool force; + /// Signals saved while sighup handler is set. + struct sigaction saved_signals; + + protected: + /// Current working directory. + std::string cwd; + }; + +} + +#endif /* SBUILD_SESSION_H */ + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/sbuild/sbuild-types.h b/sbuild/sbuild-types.h new file mode 100644 index 00000000..f5f6d6fe --- /dev/null +++ b/sbuild/sbuild-types.h @@ -0,0 +1,117 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#ifndef SBUILD_TYPES_H +#define SBUILD_TYPES_H + +#include +#include +#include +#include +#include + +namespace sbuild +{ + + /// A string vector. + typedef std::vector string_list; + + /// A date representation. + class date + { + public: + date (time_t unix_time): + unix_time(unix_time) + {} + + ~date () + {} + + template + friend + std::basic_ostream& + operator << (std::basic_ostream& stream, + date const& dt) + { + std::ios_base::iostate err = std::ios_base::goodbit; + + std::tm dtm; + if (gmtime_r(&dt.unix_time, &dtm) == 0) + { + err = std::ios_base::badbit; + } + else + { + try + { + typename std::basic_ostream::sentry sentry(stream); + if (sentry) + { + const char nfmt[] = "%d %b %Y"; + charT wfmt[sizeof(nfmt)/sizeof(nfmt[0])]; + std::use_facet >(stream.getloc()) + .widen(nfmt, nfmt + (sizeof(nfmt)/sizeof(nfmt[0])) - 1, wfmt); + + typedef std::time_put > + time_type; + if (std::use_facet(stream.getloc()) + .put(stream, stream, stream.fill(), + &dtm, wfmt + 0, wfmt + sizeof(wfmt)/sizeof(wfmt[0]) - 1) + .failed()) + { + err = std::ios_base::badbit; + } + stream.width(0); + } + } + catch (...) + { + bool flag = false; + try + { + stream.setstate(std::ios::failbit); + } + catch (std::ios_base::failure) + { + flag = true; + } + if (flag) + throw; + } + } + + if (err) + stream.setstate(err); + + return stream; + } + + private: + time_t unix_time; + }; + +} + +#endif /* SBUILD_TYPES_H */ + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/sbuild/sbuild-util.cc b/sbuild/sbuild-util.cc new file mode 100644 index 00000000..58aeff51 --- /dev/null +++ b/sbuild/sbuild-util.cc @@ -0,0 +1,232 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#include + +#include "sbuild-util.h" + +#include +#include +#include + +using namespace sbuild; + +namespace +{ + + /** + * Remove duplicate adjacent characters from a string. + * + * @param str the string to check. + * @param dup the duplicate character to check for. + * @returns a string with any duplicates removed. + */ + std::string remove_duplicates (std::string const& str, + char dup) + { + std::string ret; + + for (std::string::size_type pos = 0; + pos < str.length(); + ++pos) + { + ret += str[pos]; + if (str[pos] == dup) + { + while (pos + 1 < str.length() && + str[pos + 1] == dup) + ++pos; + } + } + + return ret; + } + +} + +std::string +sbuild::basename (std::string name, + char separator) +{ + // Remove trailing separators + std::string::size_type cur = name.length(); + while (cur - 1 != 0 && name[cur - 1] == separator) + --cur; + name.resize(cur); + + // Find last separator + std::string::size_type pos = name.rfind(separator); + + std::string ret; + if (pos == std::string::npos) + ret = name; // No separators + else if (pos == 0 && name.length() == 1 && name[0] == separator) + ret = separator; // Only separators + else + ret = name.substr(pos + 1); // Basename only + + return remove_duplicates(ret, separator); +} + +std::string +sbuild::dirname (std::string name, + char separator) +{ + // Remove trailing separators + std::string::size_type cur = name.length(); + while (cur - 1 != 0 && name[cur - 1] == separator) + --cur; + name.resize(cur); + + // Find last separator + std::string::size_type pos = name.rfind(separator); + + std::string ret; + if (pos == std::string::npos) + ret = "."; // No directory components + else if (pos == 0) + ret = separator; + else + ret = name.substr(0, pos); // Dirname part + + return remove_duplicates(ret, separator); +} + +std::string +sbuild::normalname (std::string name, + char separator) +{ + // Remove trailing separators + std::string::size_type cur = name.length(); + while (cur - 1 != 0 && name[cur - 1] == separator) + --cur; + name.resize(cur); + + return remove_duplicates(name, separator); +} + +std::string +sbuild::string_list_to_string (sbuild::string_list const& list, + std::string const& separator) +{ + std::string ret; + + for (string_list::const_iterator cur = list.begin(); + cur != list.end(); + ++cur) + { + ret += *cur; + if (cur + 1 != list.end()) + ret += separator; + } + + return ret; +} + +string_list +sbuild::split_string (std::string const& value, + std::string const& separator) +{ + string_list ret; + + // Skip any separators at the start + std::string::size_type last_pos = + value.find_first_not_of(separator, 0); + // Find first separator. + std::string::size_type pos = value.find_first_of(separator, last_pos); + + while (pos !=std::string::npos || last_pos != std::string::npos) + { + // Add to list + ret.push_back(value.substr(last_pos, pos - last_pos)); + // Find next + last_pos = value.find_first_not_of(separator, pos); + pos = value.find_first_of(separator, last_pos); + } + + return ret; +} + +std::string +sbuild::find_program_in_path (std::string const& program, + std::string const& path, + std::string const& prefix) +{ + if (program.find_first_of('/') != std::string::npos) + return program; + + string_list dirs = split_string(path, std::string(1, ':')); + + for (string_list::const_iterator dir = dirs.begin(); + dir != dirs.end(); + ++dir) + { + std::string realname = *dir + '/' + program; + std::string absname; + if (prefix.length() > 0) + { + absname = prefix; + if (dir->length() > 0 && (*dir)[0] != '/') + absname += '/'; + } + absname += realname; + + struct stat statbuf; + if (stat(absname.c_str(), &statbuf) == 0) + { + if (S_ISREG(statbuf.st_mode) && + access (absname.c_str(), X_OK) == 0) + return realname; + } + } + + return ""; +} + +char ** +sbuild::string_list_to_strv (string_list const& str) +{ + char **ret = new char *[str.size() + 1]; + + for (string_list::size_type i = 0; + i < str.size(); + ++i) + { + ret[i] = new char[str[i].length() + 1]; + std::strcpy(ret[i], str[i].c_str()); + } + ret[str.size()] = 0; + + return ret; +} + + +void +sbuild::strv_delete (char **strv) +{ + for (char **pos = strv; pos != 0 && *pos != 0; ++pos) + delete *pos; + delete[] strv; +} + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/sbuild/sbuild-util.h b/sbuild/sbuild-util.h new file mode 100644 index 00000000..caaac966 --- /dev/null +++ b/sbuild/sbuild-util.h @@ -0,0 +1,133 @@ +/* Copyright © 2005-2006 Roger Leigh + * + * schroot is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + *********************************************************************/ + +#ifndef SBUILD_UTIL_H +#define SBUILD_UTIL_H + +#include + +#include + +namespace sbuild +{ + + /** + * Strip the directory path from a filename. This is similar to + * basename(3). + * + * @param name the filename to strip of its path. + * @param separator the separation delimiting directories. + * @returns the base name. + */ + std::string + basename (std::string name, + char separator = '/'); + + /** + * Strip the fileame from a pathname. This is similar to + * dirname(3). + * + * @param name the path to strip of its filename. + * @param separator the separation delimiting directories. + * @returns the directory name. + */ + std::string + dirname (std::string name, + char separator = '/'); + + /** + * Normalise a pathname. This strips all trailing separators, and + * duplicate separators within a path. + * + * @param name the path to normalise. + * @param separator the separation delimiting directories. + * @returns the normalised name. + */ + std::string + normalname (std::string name, + char separator = '/'); + + /** + * Convert a string_list into a string. The strings are + * concatenated using separator as a delimiter. + * + * @param list the list to concatenate. + * @param separator the delimiting character. + * @returns a string. + */ + std::string + string_list_to_string (string_list const& list, + std::string const& separator); + + /** + * Split a string into a string_list. The string is split using + * separator as a delimiter. + * + * @param value the string to split. + * @param separator the delimiting character or characters. + * @returns a string_list. + */ + string_list + split_string (std::string const& value, + std::string const& separator); + + /** + * Find a program in the PATH search path. + * + * @param program the program to search for. + * @param path the search path; typically the value of $PATH. + * @param prefix a directory prefix the add to the search path. + * This may be left empty to search the root filesystem. + * @returns the absolute path of the program, or an empty string if + * the program could not be found. + */ + std::string + find_program_in_path (std::string const& program, + std::string const& path, + std::string const& prefix); + + /** + * Create a string vector from a string_list. The strings in the + * vector, as well as the vector itself, are allocated with new, and + * should be freed as a whole with strv_delete. + * + * @param str the string_list to use. + */ + char ** + string_list_to_strv (string_list const& str); + + /** + * Delete a string vector. The strings in the vector, as well as + * the vector itself, must have been previously allocated with new, + * for example sbuild::environment::get_strv. + * + * @param strv the string vector to delete. + */ + void + strv_delete (char **strv); + +} + +#endif /* SBUILD_UTIL_H */ + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/schroot/Makefile.am b/schroot/Makefile.am index 78f3e57d..1d0727e9 100644 --- a/schroot/Makefile.am +++ b/schroot/Makefile.am @@ -31,92 +31,17 @@ AM_CXXFLAGS = $(SCHROOT_CFLAGS) -pedantic -Wall -Wcast-align -Wwrite-strings -Ws DEFS = -DGETTEXT_PACKAGE=\"schroot\" -DLOCALEDIR=\"$(localedir)\" -D_GNU_SOURCE -noinst_LTLIBRARIES = libsbuild.la libschroot.la libdchroot.la +noinst_LTLIBRARIES = libschroot.la -if BUILD_DCHROOT -dchroot = dchroot -endif - -if BUILD_DCHROOT_DSA -dchroot_dsa = dchroot-dsa -endif - -bin_PROGRAMS = $(dchroot) $(dchroot_dsa) schroot +bin_PROGRAMS = schroot pkglibexec_PROGRAMS = schroot-releaselock schroot-listmounts -sbuild_public_h_sources = \ - sbuild-auth.h \ - sbuild-auth-conv.h \ - sbuild-auth-conv-tty.h \ - sbuild-auth-message.h \ - sbuild-chroot.h \ - sbuild-chroot-block-device.h \ - sbuild-chroot-file.h \ - sbuild-chroot-lvm-snapshot.h \ - sbuild-chroot-plain.h \ - sbuild-chroot-source.h \ - sbuild-chroot-config.h \ - sbuild-custom-error.h \ - sbuild-custom-error.tcc \ - sbuild-environment.h \ - sbuild-error.h \ - sbuild-format-detail.h \ - sbuild-i18n.h \ - sbuild-keyfile.h \ - sbuild-lock.h \ - sbuild-log.h \ - sbuild-nostream.h \ - sbuild-parse-error.h \ - sbuild-parse-value.h \ - sbuild-personality.h \ - sbuild-session.h \ - sbuild-types.h \ - sbuild-util.h - -sbuild_public_cc_sources = \ - sbuild-auth.cc \ - sbuild-auth-conv.cc \ - sbuild-auth-conv-tty.cc \ - sbuild-auth-message.cc \ - sbuild-chroot.cc \ - sbuild-chroot-block-device.cc \ - sbuild-chroot-file.cc \ - sbuild-chroot-lvm-snapshot.cc \ - sbuild-chroot-plain.cc \ - sbuild-chroot-source.cc \ - sbuild-chroot-config.cc \ - sbuild-environment.cc \ - sbuild-format-detail.cc \ - sbuild-keyfile.cc \ - sbuild-lock.cc \ - sbuild-log.cc \ - sbuild-nostream.cc \ - sbuild-parse-error.cc \ - sbuild-parse-value.cc \ - sbuild-personality.cc \ - sbuild-session.cc \ - sbuild-util.cc - -libsbuild_la_SOURCES = \ - $(sbuild_public_h_sources) \ - $(sbuild_public_cc_sources) - -nodist_libsbuild_la_SOURCES = \ - sbuild-config.h - -libsbuild_la_LIBADD = $(UUID_LIBS) $(PAM_LIBS) $(LOCKDEV_LIBS) $(BOOST_LIBS) $(LIBINTL) - libschroot_la_SOURCES = \ schroot-options-base.h \ schroot-options-base.cc \ schroot-main.h \ schroot-main.cc -libschroot_la_LIBADD = libsbuild.la - -libdchroot_la_SOURCES = \ - dchroot-session-base.h \ - dchroot-session-base.cc -libdchroot_la_LIBADD = libschroot.la +libschroot_la_LIBADD = $(top_builddir)/sbuild/libsbuild.la schroot_SOURCES = \ schroot-options.h \ @@ -124,67 +49,29 @@ schroot_SOURCES = \ schroot.cc schroot_LDADD = libschroot.la -dchroot_SOURCES = \ - dchroot-chroot-config.h \ - dchroot-chroot-config.cc \ - dchroot-session.h \ - dchroot-session.cc \ - dchroot-options.h \ - dchroot-options.cc \ - dchroot-main.h \ - dchroot-main.cc \ - dchroot.cc -dchroot_LDADD = libdchroot.la - -dchroot_dsa_SOURCES = \ - dchroot-dsa-chroot-config.h \ - dchroot-dsa-chroot-config.cc \ - dchroot-dsa-session.h \ - dchroot-dsa-session.cc \ - dchroot-dsa-options.h \ - dchroot-dsa-options.cc \ - dchroot-dsa-main.h \ - dchroot-dsa-main.cc \ - dchroot-dsa.cc -dchroot_dsa_LDADD = libdchroot.la - schroot_releaselock_SOURCES = \ schroot-releaselock-options.h \ schroot-releaselock-options.cc \ schroot-releaselock.cc -schroot_releaselock_LDADD = libsbuild.la +schroot_releaselock_LDADD = $(top_builddir)/sbuild/libsbuild.la schroot_listmounts_SOURCES = \ schroot-listmounts-options.h \ schroot-listmounts-options.cc \ schroot-listmounts.cc -schroot_listmounts_LDADD = libsbuild.la +schroot_listmounts_LDADD = $(top_builddir)/sbuild/libsbuild.la pkgsysconfdir = $(PACKAGE_SYSCONF_DIR) pkgsysconf_DATA = schroot.conf -if BUILD_DCHROOT -dchroot_mans = dchroot.1 -endif - -if BUILD_DCHROOT_DSA -dchroot_dsa_mans = dchroot-dsa.1 -endif - -man_MANS = $(dchroot_mans) $(dchroot_dsa_mans) schroot.1 schroot-setup.5 schroot.conf.5 +man_MANS = schroot.1 schroot-setup.5 schroot.conf.5 EXTRA_DIST = \ $(pkgsysconf_DATA) install-exec-hook: # Install setuid root. - if [ -f "$(DESTDIR)$(bindir)/dchroot" ]; then \ - chmod 4755 "$(DESTDIR)$(bindir)/dchroot"; \ - fi - if [ -f "$(DESTDIR)$(bindir)/dchroot-dsa" ]; then \ - chmod 4755 "$(DESTDIR)$(bindir)/dchroot-dsa"; \ - fi chmod 4755 "$(DESTDIR)$(bindir)/schroot" install-data-hook: diff --git a/schroot/dchroot-chroot-config.cc b/schroot/dchroot-chroot-config.cc deleted file mode 100644 index 769159fe..00000000 --- a/schroot/dchroot-chroot-config.cc +++ /dev/null @@ -1,154 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#include - -#include "sbuild-parse-error.h" - -#include "dchroot-chroot-config.h" - -#include -#include -#include -#include - -#include - -using std::endl; -using sbuild::parse_error; -using boost::format; -using namespace dchroot; - -chroot_config::chroot_config (): - sbuild::chroot_config() -{ -} - -chroot_config::chroot_config (std::string const& file, - bool active): - sbuild::chroot_config(file, active) -{ -} - -chroot_config::~chroot_config () -{ -} - -void -chroot_config::parse_data (std::istream& stream, - bool active) -{ - active = false; // dchroot does not support sessions. - - size_t linecount = 0; - std::string line; - std::string chroot_name; - std::string chroot_location; - bool default_set = false; - - while (std::getline(stream, line)) - { - linecount++; - - if (line[0] == '#') - { - // Comment line; do nothing. - } - else if (line.length() == 0) - { - // Empty line; do nothing. - } - else // Item - { - static const char *whitespace = " \t"; - - // Get chroot name - std::string::size_type cstart = line.find_first_not_of(whitespace); - std::string::size_type cend = line.find_first_of(whitespace, cstart); - - // Get chroot location - std::string::size_type lstart = line.find_first_not_of(whitespace, - cend); - std::string::size_type lend = line.find_first_of(whitespace, lstart); - - // Get chroot personality - std::string::size_type pstart = line.find_first_not_of(whitespace, - lend); - std::string::size_type pend = line.find_first_of(whitespace, pstart); - - // Check for trailing non-whitespace. - std::string::size_type tstart = line.find_first_not_of(whitespace, - pend); - if (cstart == std::string::npos || - cend == std::string::npos || - lstart == std::string::npos) - { - throw parse_error(linecount, parse_error::INVALID_LINE, line); - } - - if (tstart != std::string::npos) - { - throw parse_error(linecount, parse_error::INVALID_LINE, line); - } - - std::string chroot_name = line.substr(cstart, cend - cstart); - std::string location = line.substr(lstart, lend - lstart); - - std::string personality; - if (pstart != std::string::npos) - personality = line.substr(pstart, pend - pstart); - - /* Create chroot object. */ - sbuild::chroot::ptr chroot = sbuild::chroot::create("plain"); - chroot->set_active(active); - chroot->set_name(chroot_name); - - format fmt(_("%1% chroot (dchroot compatibility)")); - fmt % chroot_name; - chroot->set_description(fmt.str()); - - if (pstart != std::string::npos) - chroot->set_persona(sbuild::personality(personality)); - - sbuild::chroot_plain *plain = - dynamic_cast(chroot.get()); - plain->set_location(location); - - if (chroot_name == "default") - default_set = true; - - // Set default chroot. - if (!default_set) - { - sbuild::string_list aliases; - aliases.push_back("default"); - chroot->set_aliases(aliases); - default_set = true; - } - - add(chroot); - } - } -} - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/dchroot-chroot-config.h b/schroot/dchroot-chroot-config.h deleted file mode 100644 index e5dbec9d..00000000 --- a/schroot/dchroot-chroot-config.h +++ /dev/null @@ -1,74 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#ifndef DCHROOT_CHROOT_CONFIG_H -#define DCHROOT_CHROOT_CONFIG_H - -#include "sbuild-chroot-config.h" - -#include -#include -#include -#include - -namespace dchroot -{ - - /** - * Chroot configuration for dchroot compatibility. - * - * This class provides all the functionality of chroot_config, but - * parses the dchroot configuration file format, rather than the - * schroot format. - */ - class chroot_config : public sbuild::chroot_config - { - public: - /// The constructor. - chroot_config (); - - /** - * The constructor. - * - * @param file initialise using a configuration file or a whole - * directory containing configuration files. - * @param active true if the chroots in the configuration file are - * active sessions, otherwise false. - */ - chroot_config (std::string const& file, - bool active); - - /// The destructor. - virtual ~chroot_config (); - - private: - virtual void - parse_data (std::istream& stream, - bool active); - }; - -} - -#endif /* DCHROOT_CHROOT_CONFIG_H */ - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/dchroot-dsa-chroot-config.cc b/schroot/dchroot-dsa-chroot-config.cc deleted file mode 100644 index 6cac3420..00000000 --- a/schroot/dchroot-dsa-chroot-config.cc +++ /dev/null @@ -1,123 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#include - -#include "sbuild-parse-error.h" - -#include "dchroot-dsa-chroot-config.h" - -#include -#include -#include -#include - -#include - -using std::endl; -using sbuild::parse_error; -using boost::format; -using namespace dchroot_dsa; - -chroot_config::chroot_config (): - sbuild::chroot_config() -{ -} - -chroot_config::chroot_config (std::string const& file, - bool active): - sbuild::chroot_config(file, active) -{ -} - -chroot_config::~chroot_config () -{ -} - -void -chroot_config::parse_data (std::istream& stream, - bool active) -{ - active = false; // dchroot does not support sessions. - - size_t linecount = 0; - std::string line; - std::string chroot_name; - std::string chroot_location; - - while (std::getline(stream, line)) - { - linecount++; - - if (line[0] == '#') - { - // Comment line; do nothing. - } - else if (line.length() == 0) - { - // Empty line; do nothing. - } - else // Item - { - static const char *whitespace = " \t:;,"; - - // Get chroot name - std::string::size_type cstart = line.find_first_not_of(whitespace); - std::string::size_type cend = line.find_first_of(whitespace, cstart); - - // Get chroot location - std::string::size_type lstart = line.find_first_not_of(whitespace, - cend); - std::string::size_type lend = line.find_first_of(whitespace, lstart); - - if (cstart == std::string::npos || - cend == std::string::npos || - lstart == std::string::npos) - { - throw parse_error(linecount, parse_error::INVALID_LINE, line); - } - - std::string chroot_name = line.substr(cstart, cend - cstart); - std::string location = line.substr(lstart, lend - lstart); - - /* DSA dchroot parses valid users. */ - sbuild::string_list users; - if (lend != std::string::npos) - users = sbuild::split_string(line.substr(lend), whitespace); - - /* Create chroot object. */ - sbuild::chroot::ptr chroot = sbuild::chroot::create("plain"); - chroot->set_active(active); - chroot->set_name(chroot_name); - - format fmt(_("%1% chroot (dchroot-dsa compatibility)")); - fmt % chroot_name; - chroot->set_description(fmt.str()); - - /* DSA dchroot set valid users in the user list. */ - chroot->set_users(users); - - sbuild::chroot_plain *plain = - dynamic_cast(chroot.get()); - plain->set_location(location); - - add(chroot); - } - } -} diff --git a/schroot/dchroot-dsa-chroot-config.h b/schroot/dchroot-dsa-chroot-config.h deleted file mode 100644 index b9d05c42..00000000 --- a/schroot/dchroot-dsa-chroot-config.h +++ /dev/null @@ -1,74 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#ifndef DCHROOT_DSA_CHROOT_CONFIG_H -#define DCHROOT_DSA_CHROOT_CONFIG_H - -#include "sbuild-chroot-config.h" - -#include -#include -#include -#include - -namespace dchroot_dsa -{ - - /** - * Chroot configuration for dchroot-dsa compatibility. - * - * This class provides all the functionality of chroot_config, but - * parses the dchroot-dsa configuration file format, rather than the - * schroot format. - */ - class chroot_config : public sbuild::chroot_config - { - public: - /// The constructor. - chroot_config (); - - /** - * The constructor. - * - * @param file initialise using a configuration file or a whole - * directory containing configuration files. - * @param active true if the chroots in the configuration file are - * active sessions, otherwise false. - */ - chroot_config (std::string const& file, - bool active); - - /// The destructor. - virtual ~chroot_config (); - - private: - virtual void - parse_data (std::istream& stream, - bool active); - }; - -} - -#endif /* DCHROOT_DSA_CHROOT_CONFIG_H */ - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/dchroot-dsa-main.cc b/schroot/dchroot-dsa-main.cc deleted file mode 100644 index 11e82367..00000000 --- a/schroot/dchroot-dsa-main.cc +++ /dev/null @@ -1,155 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#include - -#include "dchroot-dsa-main.h" -#include "dchroot-dsa-chroot-config.h" -#include "dchroot-dsa-session.h" - -#include -#include -#include - -#include -#include - -#include - -#include - -using std::endl; -using boost::format; -using namespace dchroot_dsa; - -main::main (schroot::options_base::ptr& options): - schroot::main(options), - use_dchroot_conf(false) -{ - this->program_name = "dchroot-dsa"; -} - -main::~main () -{ -} - -void -main::action_config () -{ - std::cout << "# " - << format(_("schroot configuration generated by %1% %2%")) - % this->program_name % VERSION - << endl; - // Help text at head of new config. - std::cout << "# " << endl - << "# " - << _("To allow users access to the chroots, use the users or groups keys.") << endl; - std::cout << "# " - << _("To allow passwordless root access, use the root-users or root-groups keys.") << endl; - std::cout << "# " - << format(_("Remove '%1%' to use the new configuration.")) - % DCHROOT_CONF - << endl; - std::cout << endl; - this->config->print_chroot_config(this->chroots, std::cout); -} - -void -main::action_list () -{ - this->config->print_chroot_list_simple(std::cout); -} - -void -main::compat_check () -{ - if (this->options->verbose) - { - sbuild::log_warning() - << _("Running schroot in dchroot compatibility mode") - << endl; - sbuild::log_info() - << _("Run 'schroot' for full capabilities") - << endl; - } -} - -void -main::load_config () -{ - this->use_dchroot_conf = false; - - struct stat statbuf; - if (stat(DCHROOT_CONF, &statbuf) == 0 && !S_ISDIR(statbuf.st_mode)) - { - this->use_dchroot_conf = true; - - if (this->options->verbose) - { - sbuild::log_warning() - << format(_("Using %1% configuration file: ")) - % this->program_name - << DCHROOT_CONF - << endl; - sbuild::log_info() - << format(_("Run '%1%'")) - % "dchroot --config >> " SCHROOT_CONF - << endl; - sbuild::log_info() - << _("to migrate to a schroot configuration.") - << endl; - sbuild::log_info() - << format(_("Edit '%1%' to add appropriate group access.")) - % SCHROOT_CONF - << endl; - sbuild::log_info() - << format(_("Remove '%1%' to use the new configuration.")) - % DCHROOT_CONF - << endl; - } - } - - if (this->use_dchroot_conf) - { - this->config = - sbuild::chroot_config::ptr(new dchroot_dsa::chroot_config); - if (this->options->load_chroots == true) - this->config->add(DCHROOT_CONF, false); - } - else - { - schroot::main::load_config(); - } -} - -void -main::create_session(sbuild::session::operation sess_op) -{ - sbuild::log_debug(sbuild::DEBUG_INFO) - << "Creating dchroot-dsa session" << endl; - - // Using dchroot.conf implies using dchroot_session_base, which does - // not require user or group access. - this->session = sbuild::session::ptr - (new dchroot_dsa::session("schroot", - this->config, - sess_op, - this->chroots, - this->use_dchroot_conf)); -} diff --git a/schroot/dchroot-dsa-main.h b/schroot/dchroot-dsa-main.h deleted file mode 100644 index 9664bcd2..00000000 --- a/schroot/dchroot-dsa-main.h +++ /dev/null @@ -1,72 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#ifndef DCHROOT_DSA_MAIN_H -#define DCHROOT_DSA_MAIN_H - -#include "schroot-main.h" - -namespace dchroot_dsa -{ - - /** - * Frontend for dchroot-dsa. This class is used to "run" dchroot-dsa. - */ - class main : public schroot::main - { - public: - /** - * The constructor. - * - * @param options the command-line options to use. - */ - main (schroot::options_base::ptr& options); - - /// The destructor. - virtual ~main (); - - protected: - virtual void - compat_check (); - - virtual void - load_config(); - - virtual void - action_config (); - - virtual void - action_list (); - - virtual void - create_session (sbuild::session::operation sess_op); - - private: - bool use_dchroot_conf; - }; - -} - -#endif /* DCHROOT_DSA_MAIN_H */ - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/dchroot-dsa-options.cc b/schroot/dchroot-dsa-options.cc deleted file mode 100644 index e5f04323..00000000 --- a/schroot/dchroot-dsa-options.cc +++ /dev/null @@ -1,103 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#include - -#include "dchroot-dsa-options.h" - -#include -#include - -#include -#include - -using std::endl; -using boost::format; -namespace opt = boost::program_options; -using namespace dchroot_dsa; - -options::options (int argc, - char *argv[]): - schroot::options_base(argc, argv) -{ - add_options(); - parse_options(argc, argv); - check_options(); - check_actions(); -} - -options::~options () -{ -} - -void -options::add_options () -{ - schroot::options_base::add_options(); - - general.add_options() - ("listpaths,p", - _("Print paths to available chroots")); - - chroot.add_options() - ("all,a", - _("Select all chroots")); -} - -void -options::check_options () -{ - if (vm.count("help")) - { - std::cout - << _("Usage:") << "\n " - << "dchroot-dsa" - << " " - << _("[OPTION...] chroot [COMMAND] - run command or shell in a chroot") - << '\n'; - std::cout << visible << std::flush; - exit(EXIT_SUCCESS); - } - - schroot::options_base::check_options(); - - if (vm.count("listpaths")) - set_action(ACTION_LOCATION); - - if (vm.count("all")) - { - this->all = false; - this->all_chroots = true; - this->all_sessions = false; - } - - // Always preserve environment. - this->preserve = true; - - // If no chroots specified, use the first non-option. - if (this->chroots.empty() && !this->command.empty()) - { - this->chroots.push_back(this->command[0]); - this->command.erase(this->command.begin()); - } - - // dchroot-dsa only allows one command. - if (this->command.size() > 1) - throw opt::validation_error(_("Only one command may be specified")); -} diff --git a/schroot/dchroot-dsa-options.h b/schroot/dchroot-dsa-options.h deleted file mode 100644 index 41352cf2..00000000 --- a/schroot/dchroot-dsa-options.h +++ /dev/null @@ -1,64 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#ifndef DCHROOT_DSA_OPTIONS_H -#define DCHROOT_DSA_OPTIONS_H - -#include "schroot-options-base.h" - -namespace dchroot_dsa -{ - - /** - * dchroot-dsa command-line options. - */ - class options : public schroot::options_base - { - public: - - /** - * The constructor. - * - * @param argc the number of arguments. - * @param argv the list of arguments. - */ - options (int argc, - char *argv[]); - - /// The destructor. - virtual ~options (); - - protected: - virtual void - add_options (); - - virtual void - check_options (); - }; - -} - -#endif /* DCHROOT_DSA_OPTIONS_H */ - -/* - * Local Variables: - * mode:C++ - * End: - */ - diff --git a/schroot/dchroot-dsa-session.cc b/schroot/dchroot-dsa-session.cc deleted file mode 100644 index 31fe7b14..00000000 --- a/schroot/dchroot-dsa-session.cc +++ /dev/null @@ -1,139 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#include - -#include "dchroot-dsa-session.h" - -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include - -#include - -using std::cout; -using std::endl; -using boost::format; -using sbuild::string_list; -using namespace dchroot_dsa; - -session::session (std::string const& service, - config_ptr& config, - operation operation, - string_list const& chroots, - bool compat): - dchroot::session_base(service, config, operation, chroots, compat) -{ -} - -session::~session () -{ -} - -sbuild::auth::status -session::get_chroot_auth_status (sbuild::auth::status status, - sbuild::chroot::ptr const& chroot) const -{ - /* DSA dchroot checks for a valid user in the groups list, unless - the groups lists is empty in which case there are no - restrictions. This only applies if not switching users (dchroot - does not support user switching) */ - - if (get_compat() == true) - { - string_list const& users = chroot->get_users(); - string_list const& groups = chroot->get_groups(); - - if (this->get_ruid() == this->get_uid() && - users.empty() && groups.empty()) - status = change_auth(status, auth::STATUS_NONE); - else - status = change_auth(status, - sbuild::session::get_chroot_auth_status(status, - chroot)); - } - else // schroot compatibility - { - status = change_auth(status, - sbuild::session::get_chroot_auth_status(status, - chroot)); - } - - return status; -} - -string_list -session::get_login_directories () const -{ - string_list ret; - - ret.push_back(get_home()); - - // Final fallback to root. - if (std::find(ret.begin(), ret.end(), "/") == ret.end()) - ret.push_back("/"); - - return ret; -} - -void -session::get_user_command (sbuild::chroot::ptr& session_chroot, - std::string& file, - string_list& command) const -{ - std::string programstring = command[0]; - file = programstring; - - if (file.empty() || - (file.size() >= 1 && file[0] != '/')) - { - sbuild::log_error() - << format(_("%1%: Command must have an absolute path")) - % file - << endl; - exit (EXIT_FAILURE); - } - - - std::string commandstring = sbuild::string_list_to_string(command, " "); - sbuild::log_debug(sbuild::DEBUG_NOTICE) - << format("Running command: %1%") % commandstring << endl; - syslog(LOG_USER|LOG_NOTICE, "[%s chroot] (%s->%s) Running command: \"%s\"", - session_chroot->get_name().c_str(), get_ruser().c_str(), get_user().c_str(), commandstring.c_str()); - - if (get_verbosity() != auth::VERBOSITY_QUIET) - { - std::string format_string; - format_string = (_("[%1% chroot] Running command: \"%2%\"")); - - format fmt(format_string); - fmt % session_chroot->get_name() - % programstring; - sbuild::log_info() << fmt << endl; - } -} diff --git a/schroot/dchroot-dsa-session.h b/schroot/dchroot-dsa-session.h deleted file mode 100644 index 23ab0170..00000000 --- a/schroot/dchroot-dsa-session.h +++ /dev/null @@ -1,89 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#ifndef DCHROOT_DSA_SESSION_H -#define DCHROOT_DSA_SESSION_H - -#include "dchroot-session-base.h" - -#include - -#include -#include -#include -#include -#include - -namespace dchroot_dsa -{ - - /** - * Session handler for dchroot-dsa sessions. - * - * This class provides the session handling for dchroot-dsa - * compatibility. It overrides the normal authentication checks to - * allow all users to access the service, but enforce dchroot-dsa - * user access controls when present, and it specialises the session - * behaviour to be compatible with the chdir and command execution - * behaviour of dchroot-dsa. - */ - class session : public dchroot::session_base - { - public: - /** - * The constructor. - * - * @param service the PAM service name. - * @param config a shared_ptr to the chroot configuration. - * @param operation the session operation to perform. - * @param chroots the chroots to act upon. - * @param compat true to enable full dchroot compatibility, or - * false to enable schroot compatiblity (permissions checks). - */ - session (std::string const& service, - config_ptr& config, - operation operation, - sbuild::string_list const& chroots, - bool compat); - - /// The destructor. - virtual ~session (); - - virtual sbuild::auth::status - get_chroot_auth_status (sbuild::auth::status status, - sbuild::chroot::ptr const& chroot) const; - - virtual sbuild::string_list - get_login_directories () const; - - virtual void - get_user_command (sbuild::chroot::ptr& session_chroot, - std::string& file, - sbuild::string_list& command) const; - }; - -} - -#endif /* DCHROOT_DSA_SESSION_H */ - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/dchroot-dsa.1.in b/schroot/dchroot-dsa.1.in deleted file mode 100644 index ebb207ae..00000000 --- a/schroot/dchroot-dsa.1.in +++ /dev/null @@ -1,245 +0,0 @@ -.\" Copyright © 2005-2006 Roger Leigh -.\" -.\" schroot is free software; you can redistribute it and/or modify it -.\" under the terms of the GNU General Public License as published by -.\" the Free Software Foundation; either version 2 of the License, or -.\" (at your option) any later version. -.\" -.\" schroot is distributed in the hope that it will be useful, but -.\" WITHOUT ANY WARRANTY; without even the implied warranty of -.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -.\" General Public License for more details. -.\" -.\" You should have received a copy of the GNU General Public License -.\" along with this program; if not, write to the Free Software -.\" Foundation, Inc., 59 Temple Place, Suite 330, Boston, -.\" MA 02111-1307 USA -.TH DCHROOT-DSA 1 "@RELEASE_DATE@" "Version @VERSION@" "Debian sbuild" -.SH NAME -dchroot\-dsa \- enter a chroot environment -.SH SYNOPSIS -.B dchroot\-dsa -[\fIOPTION\fP]... [chroot] [\fICOMMAND\fP] -.SH DESCRIPTION -\fBdchroot\-dsa\fP allows the user to run a command or a login shell in a -chroot environment. If no command is specified, a login shell will be started -in the user's home directory inside the chroot. -.PP -The user's environment will be preserved inside the chroot. -.PP -The command is a single argument which must be an absolute path to the program. -Additional options are not permitted. -.PP -The login shell or command will run in the user's home directory inside the -chroot, or / if the home directory is not available. -.PP -This version of \fBdchroot\-dsa\fP is a compatibility wrapper around the -.BR schroot (1) -program. It is provided for backward compatibility with the \fBdchroot\-dsa\fP -command-line options, but \fBschroot\fP is recommended for future use. See the -section \[lq]\fIMigration\fP\[rq] below for help migrating your existing -\fBdchroot\-dsa\fP configuration to \fBschroot\fP. See the section -\[lq]\fIIncompatibilities\fP\[rq] below for known incompatibilities with -\fBdchroot\-dsa\fP. -.PP -.SH OPTIONS -\fBdchroot\-dsa\fP accepts the following options: -.SS Basic options -.TP -.B \-h, \-\-help -Show help summary. -.TP -.B \-a, \-\-all -Select all chroots. Note that the original \fBdchroot\-dsa\fP did not include -this option. -.TP -.B \-c, \-\-chroot=\fIchroot\fP -Specify a chroot to use. This option may be used multiple times to specify -more than one chroot, in which case its effect is similar to \fB\-\-all\fP. If -this option is not used, the first non-option argument specified the chroot to -use. Note that the original \fBdchroot\-dsa\fP did not include this option. -.TP -.B \-l, \-\-list -List all available chroots. -.TP -.B \-i, \-\-info -Print detailed information about the available chroots. Note that the original -\fBdchroot\-dsa\fP did not include this option. -.TP -.B \-p, \-\-listpaths -Print absolute locations (paths) of the available chroots. -.TP -.B \-\-config -Print configuration of the available chroots. This is useful for testing that -the configuration in use is the same as the configuration file. Any comments -in the original file will be missing. Note that the original -\fBdchroot\-dsa\fP did not include this option. -.TP -.B \-q, \-\-quiet -Print only essential messages. Note that the original \fBdchroot\-dsa\fP did -not include this option. -.TP -.B \-v, \-\-verbose -Print all messages. Note that the original \fBdchroot\-dsa\fP did not include -this option. -.TP -.B \-V, \-\-version -Print version information. -.SH CONFIGURATION -The original \fBdchroot\-dsa\fP configuration file, \fI@DCHROOT_CONF@\fP has -the following format: -.IP \[bu] -\[oq]#\[cq] starts a comment line. -.IP \[bu] -Blank lines are ignored. -.IP \[bu] -Chroot definitions are a single line containing an \fIidentifier\fP, -\fIpath\fP, and an optional \fIuser list\fP separated by whitespace (space and -tab), or a colon (\[oq]:\[cq]), semicolon (\[oq];\[cq]), or comma -(\[oq],\[cq]). -.PP -An example file: -.PP -.RS -\f[CR]# Example comment\fP -.br -\f[CR]\fP -.br -\f[CR]sarge /srv/chroot/sarge\fP -.br -\f[CR]sid /srv/chroot/sid rleigh,fred\fP -.br -.RE -.PP -This file defines a chroot called \[oq]sarge\[cq], located at -\fI/srv/chroot/sarge\fP, and a second chroot called \[oq]sid\[cq], located at -\fI/srv/chroot/sid\fP. The second chroot specifies that it may only be used by -the users \[lq]rleigh\[rq] and \[lq]fred\[rq]. -.SH INCOMPATIBILITIES -.SS DSA dchroot -.IP \[bu] -Log messages are worded and formatted differently. -.IP \[bu] -\fBdchroot\-dsa\fP provides a restricted subset of the functionality -implemented by \fBschroot\fP, but is still \fBschroot\fP underneath. Thus -\fBdchroot\-dsa\fP is still subject to \fBschroot\fP security checking, -including PAM authentication and authorisation, and session management, for -example, and hence may behave slightly differently to the original -\fBdchroot\-dsa\fP in some circumstances. -.IP \[bu] -The command argument in this version may be absolute or relative, and may -contain as many options as desired. The original version only allowed a single -absolute program name and no options. -.SS Debian dchroot -A \fBdchroot\fP package provides an alternative \fBdchroot\fP implementation. -.IP \[bu] -All the above incompatibilities apply. -.IP \[bu] -This version of dchroot has incompatible command-line options, and while some -of those options are supported or have equivalent options by a different name, -the \fI\-c\fP option is required to specify a chroot. It also allows a shell -script to be used as the option instead of a single absolute path. -.IP \[bu] -This version of dchroot has an incompatible format for \fIdchroot.conf\fP. -While the first two fields are the same, the third field is a optional -personality, instead of the list of users permitted to access the chroot -allowed by this version. If personality support is needed, please use -\fIschroot.conf\fP and add the allowed users there, as shown in -\[lq]\fIMigration\fP\[rq] below. -.SH MIGRATION -To migrate an existing \fBdchroot\-dsa\fP configuration to \fBschroot\fP, -perform the following steps: -.IP 1 -Dump the \fBdchroot\-dsa\fP configuration in \fBschroot\fP keyfile format to -\fI@SCHROOT_CONF@\fP. -.PP -.RS -\f[CR]# \f[CB]dchroot\-dsa --config >> @SCHROOT_CONF@ -.br -.RE -.PP -.IP 2 -Edit \fI@SCHROOT_CONF@\fP to add access to the groups who are to be allowed to -access the chroots, and make any other desired changes to the configuration. -See -.BR schroot.conf (5). -.IP 3 -Remove \fI@DCHROOT_CONF@\fP, so that \fBdchroot\-dsa\fP will subsequently use -\fI@SCHROOT_CONF@\fP for its configuration. If the \fBdchroot\fP package is -still installed, purge it, or else delete the file. -.SH EXAMPLES -\f[CR]$ dchroot\-dsa -l\fP -.br -\f[CR]Available chroots: sarge, sid\fP -.br -\f[CR]\fP -.br -\f[CR]$ dchroot\-dsa \-\-listpaths\fP -.br -\f[CR]/srv/chroot/sarge\fP -.br -\f[CR]/srv/chroot/sid\fP -.br -\f[CR]\fP -.br -\f[CR]$ dchroot\-dsa \-q sid \-\- /bin/uname\fP -.br -\f[CR]Linux\fP -.br -\f[CR]\fP -.br -\f[CR]$ dchroot\-dsa sid\fP -.br -\f[CR]I: [sid chroot] Running login shell: \[lq]/bin/bash\[rq]\fP -.br -\f[CR]$ \fP -.br -.LP -Use \fB\-\-\fP to allow options beginning with \[oq]\-\[cq] or \[oq]\-\-\[cq] -in the command to run in the chroot. This prevents them being interpreted as -options for \fBschroot\fP itself. Note that the top line was echoed to -standard error, and the remaining lines to standard output. This is -intentional, so that program output from commands run in the chroot may be -piped and redirected as required; the data will be the same as if the command -was run directly on the host system. -.SH BUGS -None known at this time. -.SH FILES -.TP -.I @DCHROOT_CONF@ -The system-wide \fBdchroot\-dsa\fP chroot definition file. This file must be -owned by the root user, and not be writable by other. If present, this file -will be used in preference to @SCHROOT_CONF@. -.TP -.I @SCHROOT_CONF@ -The system-wide \fBschroot\fP definition file. This file must be owned by the -root user, and not be writable by other. It is recommended that this file be -used in preference to \fI@DCHROOT_CONF@\fP, because the chroots can be used -interchangeably with \fBschroot\fP, and the group security policies provided by -\fBschroot\fP are also enforced. -.SH AUTHORS -Roger Leigh. -.PP -This implementation of \fBdchroot\-dsa\fP uses the same command-line options as -the original \fBdchroot\-dsa\fP found on machines run by the Debian System -Administrators for the Debian Project have a \fBdchroot-dsa\fP source package -which also provides a \fBdchroot\-dsa\fP package. -.SH COPYRIGHT -Copyright \(co 2005-2006 Roger Leigh -.PP -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation; either version 2 of the License, or (at your option) -any later version. -.SH SEE ALSO -.BR schroot (1), -.BR sbuild (1), -.BR chroot (2), -.BR schroot-setup (5), -.BR schroot.conf (5). -.\"# -.\"# The following sets edit modes for GNU EMACS -.\"# Local Variables: -.\"# mode:nroff -.\"# fill-column:79 -.\"# End: diff --git a/schroot/dchroot-dsa.cc b/schroot/dchroot-dsa.cc deleted file mode 100644 index 737a8eb9..00000000 --- a/schroot/dchroot-dsa.cc +++ /dev/null @@ -1,77 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#include - -#include "dchroot-dsa-main.h" -#include "dchroot-dsa-options.h" - -#include -#include -#include - -#include - -#include - -using std::endl; -using boost::format; -using namespace schroot; - -/** - * Main routine. - * - * @param argc the number of arguments - * @param argv argument vector - * - * @returns 0 on success, 1 on failure or the exit status of the - * chroot command. - */ -int -main (int argc, - char *argv[]) -{ - try - { - // Set up locale. - std::locale::global(std::locale("")); - std::cout.imbue(std::locale()); - std::cerr.imbue(std::locale()); - - dchroot_dsa::options::ptr opts(new dchroot_dsa::options(argc, argv)); - dchroot_dsa::main kit(opts); - exit (kit.run()); - } - catch (std::exception const& e) - { - sbuild::log_error() << e.what() << endl; - exit(EXIT_FAILURE); - } - catch (...) - { - sbuild::log_error() << _("An unknown exception occured") << endl; - exit(EXIT_FAILURE); - } -} - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/dchroot-main.cc b/schroot/dchroot-main.cc deleted file mode 100644 index 9d53d979..00000000 --- a/schroot/dchroot-main.cc +++ /dev/null @@ -1,161 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#include - -#include "dchroot-main.h" -#include "dchroot-chroot-config.h" -#include "dchroot-session.h" - -#include -#include -#include - -#include -#include - -#include - -#include - -using std::endl; -using boost::format; -using schroot::options_base; -using namespace dchroot; - -main::main (options_base::ptr& options): - schroot::main(options), - use_dchroot_conf(false) -{ - this->program_name = "dchroot"; -} - -main::~main () -{ -} - -void -main::action_config () -{ - std::cout << "# " - << format(_("schroot configuration generated by %1% %2%")) - % this->program_name % VERSION - << endl; - // Help text at head of new config. - std::cout << "# " << endl - << "# " - << _("To allow users access to the chroots, use the users or groups keys.") << endl; - std::cout << "# " - << _("To allow passwordless root access, use the root-users or root-groups keys.") << endl; - std::cout << "# " - << format(_("Remove '%1%' to use the new configuration.")) - % DCHROOT_CONF - << endl; - std::cout << endl; - this->config->print_chroot_config(this->chroots, std::cout); -} - -void -main::action_list () -{ - this->config->print_chroot_list_simple(std::cout); -} - -void -main::action_location () -{ - sbuild::string_list chroot; - chroot.push_back(this->options->chroot_path); - this->config->print_chroot_location(chroot, std::cout); -} - -void -main::compat_check () -{ - if (this->options->verbose) - { - sbuild::log_warning() - << _("Running schroot in dchroot compatibility mode") - << endl; - sbuild::log_info() - << _("Run 'schroot' for full capabilities") - << endl; - } -} - -void -main::load_config () -{ - this->use_dchroot_conf = false; - struct stat statbuf; - if (stat(DCHROOT_CONF, &statbuf) == 0 && !S_ISDIR(statbuf.st_mode)) - { - this->use_dchroot_conf = true; - - if (this->options->verbose) - { - sbuild::log_warning() - << format(_("Using %1% configuration file: ")) - % this->program_name - << DCHROOT_CONF - << endl; - sbuild::log_info() - << format(_("Run '%1%'")) - % "dchroot --config >> " SCHROOT_CONF - << endl; - sbuild::log_info() - << _("to migrate to a schroot configuration.") - << endl; - sbuild::log_info() - << format(_("Edit '%1%' to add appropriate group access.")) - % SCHROOT_CONF - << endl; - sbuild::log_info() - << format(_("Remove '%1%' to use the new configuration.")) - % DCHROOT_CONF - << endl; - } - } - - if (this->use_dchroot_conf) - { - this->config = sbuild::chroot_config::ptr(new dchroot::chroot_config); - if (this->options->load_chroots == true) - this->config->add(DCHROOT_CONF, false); - } - else - { - schroot::main::load_config(); - } -} - -void -main::create_session (sbuild::session::operation sess_op) -{ - sbuild::log_debug(sbuild::DEBUG_INFO) << "Creating dchroot session" << endl; - - // Using dchroot.conf implies using dchroot_session_base, which does - // not require user or group access. - this->session = sbuild::session::ptr - (new dchroot::session("schroot", - this->config, - sess_op, - this->chroots, - this->use_dchroot_conf)); -} diff --git a/schroot/dchroot-main.h b/schroot/dchroot-main.h deleted file mode 100644 index 77912795..00000000 --- a/schroot/dchroot-main.h +++ /dev/null @@ -1,75 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#ifndef DCHROOT_MAIN_H -#define DCHROOT_MAIN_H - -#include "schroot-main.h" - -namespace dchroot -{ - - /** - * Frontend for dchroot. This class is used to "run" dchroot. - */ - class main : public schroot::main - { - public: - /** - * The constructor. - * - * @param options the command-line options to use. - */ - main (schroot::options_base::ptr& options); - - /// The destructor. - virtual ~main (); - - protected: - virtual void - compat_check (); - - virtual void - load_config(); - - virtual void - action_config (); - - virtual void - action_list (); - - virtual void - action_location (); - - virtual void - create_session (sbuild::session::operation sess_op); - - private: - bool use_dchroot_conf; - }; - -} - -#endif /* DCHROOT_MAIN_H */ - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/dchroot-options.cc b/schroot/dchroot-options.cc deleted file mode 100644 index 998e257a..00000000 --- a/schroot/dchroot-options.cc +++ /dev/null @@ -1,129 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#include - -#include "dchroot-options.h" - -#include -#include - -#include -#include - -using std::endl; -using boost::format; -namespace opt = boost::program_options; -using namespace dchroot; - -options::options (int argc, - char *argv[]): - schroot::options_base(argc, argv) -{ - add_options(); - parse_options(argc, argv); - check_options(); - check_actions(); -} - -options::~options () -{ -} - -void -options::add_options () -{ - schroot::options_base::add_options(); - - general.add_options() - ("path,p", opt::value(&this->chroot_path), - _("Print path to selected chroot")); - - chroot.add_options() - ("all,a", - _("Select all chroots")); - - chrootenv.add_options() - ("preserve-environment,d", - _("Preserve user environment")); -} - -void -options::check_options () -{ - if (vm.count("help")) - { - std::cout - << _("Usage:") << "\n " - << "dchroot" - << " " - << _("[OPTION...] [COMMAND] - run command or shell in a chroot") - << '\n'; - std::cout << visible << std::flush; - exit(EXIT_SUCCESS); - } - - schroot::options_base::check_options(); - - if (vm.count("path")) - set_action(ACTION_LOCATION); - - if (vm.count("all")) - { - this->all = false; - this->all_chroots = true; - this->all_sessions = false; - } - - if (vm.count("preserve-environment")) - this->preserve = true; - - // dchroot only allows one command. - if (this->command.size() > 1) - throw opt::validation_error(_("Only one command may be specified")); - - if (this->quiet && this->verbose) - { - sbuild::log_warning() - << _("--quiet and --verbose may not be used at the same time") - << endl; - sbuild::log_info() << _("Using verbose output") << endl; - } - - if (!this->chroots.empty() && all_used()) - { - sbuild::log_warning() - << _("--chroot and --all may not be used at the same time") - << endl; - sbuild::log_info() << _("Using --chroots only") << endl; - this->all = this->all_chroots = this->all_sessions = false; - } - - if (this->all == true) - { - this->all_chroots = true; - this->all_sessions = true; - } -} - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/dchroot-options.h b/schroot/dchroot-options.h deleted file mode 100644 index 592f24a8..00000000 --- a/schroot/dchroot-options.h +++ /dev/null @@ -1,63 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#ifndef DCHROOT_OPTIONS_H -#define DCHROOT_OPTIONS_H - -#include "schroot-options-base.h" - -namespace dchroot -{ - - /** - * dchroot command-line options. - */ - class options : public schroot::options_base - { - public: - /** - * The constructor. - * - * @param argc the number of arguments. - * @param argv the list of arguments. - */ - options (int argc, - char *argv[]); - - /// The destructor. - virtual ~options (); - - protected: - virtual void - add_options (); - - virtual void - check_options (); - }; - -} - -#endif /* DCHROOT_OPTIONS_H */ - -/* - * Local Variables: - * mode:C++ - * End: - */ - diff --git a/schroot/dchroot-session-base.cc b/schroot/dchroot-session-base.cc deleted file mode 100644 index 01fca798..00000000 --- a/schroot/dchroot-session-base.cc +++ /dev/null @@ -1,96 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#include - -#include "dchroot-session-base.h" - -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include - -#include - -using std::cout; -using std::endl; -using boost::format; -using sbuild::string_list; -using namespace dchroot; - -session_base::session_base (std::string const& service, - config_ptr& config, - operation operation, - string_list const& chroots, - bool compat): - sbuild::session(service, config, operation, chroots), - compat(compat) -{ -} - -session_base::~session_base () -{ -} - -bool -session_base::get_compat () const -{ - return this->compat; -} - -void -session_base::set_compat (bool state) -{ - this->compat = state; -} - -void -session_base::run_impl () -{ - if (get_ruid() != get_uid()) - { - format fmt(_("(%1%->%2%): dchroot sessions do not support user switching")); - fmt % get_ruser().c_str() % get_user().c_str(); - throw error(fmt.str(), USER_SWITCH, _("dchroot session restriction")); - } - - sbuild::session::run_impl(); -} - -string_list -session_base::get_command_directories () const -{ - // dchroot does not treat logins differently from commands with - // respect to the cwd inside the chroot. - return get_login_directories(); -} - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/dchroot-session-base.h b/schroot/dchroot-session-base.h deleted file mode 100644 index 59fdae43..00000000 --- a/schroot/dchroot-session-base.h +++ /dev/null @@ -1,102 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#ifndef DCHROOT_SESSION_BASE_H -#define DCHROOT_SESSION_BASE_H - -#include "sbuild-session.h" - -#include - -#include -#include -#include -#include -#include - -namespace dchroot -{ - - /** - * Basic session handler for dchroot sessions. - * - * This class provides common session functionality for dchroot and - * dchroot-dsa, such as providing a schroot compatibility mode. It - * also prevents user switching when running sessions, which is - * forbidden. - */ - class session_base : public sbuild::session - { - public: - /** - * The constructor. - * - * @param service the PAM service name. - * @param config a shared_ptr to the chroot configuration. - * @param operation the session operation to perform. - * @param chroots the chroots to act upon. - * @param compat true to enable full dchroot compatibility, or - * false to enable schroot compatiblity (permissions checks). - */ - session_base (std::string const& service, - config_ptr& config, - operation operation, - sbuild::string_list const& chroots, - bool compat); - - /// The destructor. - virtual ~session_base (); - - /** - * Get the dchroot compatibility state. - * - * @returns the state. - */ - bool - get_compat () const; - - /** - * Set the dchroot compatibility state. - * - * @param state the dchroot compatibility state. - */ - void - set_compat (bool state); - - protected: - virtual void - run_impl (); - - virtual sbuild::string_list - get_command_directories () const; - - private: - /// dchroot compatibility enabled? - bool compat; - }; - -} - -#endif /* DCHROOT_SESSION_BASE_H */ - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/dchroot-session.cc b/schroot/dchroot-session.cc deleted file mode 100644 index 09c5e8aa..00000000 --- a/schroot/dchroot-session.cc +++ /dev/null @@ -1,123 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#include - -#include "dchroot-session.h" - -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include - -#include - -using std::cout; -using std::endl; -using boost::format; -using sbuild::string_list; -using namespace dchroot; - -session::session (std::string const& service, - config_ptr& config, - operation operation, - string_list const& chroots, - bool compat): - session_base(service, config, operation, chroots, compat) -{ -} - -session::~session () -{ -} - -sbuild::auth::status -session::get_chroot_auth_status (sbuild::auth::status status, - sbuild::chroot::ptr const& chroot) const -{ - if (get_compat() == true) - status = change_auth(status, auth::STATUS_NONE); - else - status = change_auth(status, - sbuild::session::get_chroot_auth_status(status, - chroot)); - - return status; -} - -string_list -session::get_login_directories () const -{ - string_list ret; - - // Set current working directory only if preserving environment. - // Only change to home if not preserving the environment. - if (!get_environment().empty()) - ret.push_back(this->sbuild::session::cwd); - else - ret.push_back(get_home()); - - // Final fallback to root. - if (std::find(ret.begin(), ret.end(), "/") == ret.end()) - ret.push_back("/"); - - return ret; -} - -void -session::get_user_command (sbuild::chroot::ptr& session_chroot, - std::string& file, - string_list& command) const -{ - std::string programstring = command[0]; - - command.clear(); - command.push_back(get_shell()); - command.push_back("-c"); - command.push_back(programstring); - - file = command[0]; - - sbuild::log_debug(sbuild::DEBUG_NOTICE) << "file=" << file << endl; - - std::string commandstring = sbuild::string_list_to_string(command, " "); - sbuild::log_debug(sbuild::DEBUG_NOTICE) - << format("Running command: %1%") % commandstring << endl; - syslog(LOG_USER|LOG_NOTICE, "[%s chroot] (%s->%s) Running command: \"%s\"", - session_chroot->get_name().c_str(), get_ruser().c_str(), get_user().c_str(), commandstring.c_str()); - - if (get_verbosity() != auth::VERBOSITY_QUIET) - { - std::string format_string; - format_string = (_("[%1% chroot] Running command: \"%2%\"")); - - format fmt(format_string); - fmt % session_chroot->get_name() - % programstring; - sbuild::log_info() << fmt << endl; - } -} diff --git a/schroot/dchroot-session.h b/schroot/dchroot-session.h deleted file mode 100644 index 9a733e7a..00000000 --- a/schroot/dchroot-session.h +++ /dev/null @@ -1,88 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#ifndef DCHROOT_SESSION_H -#define DCHROOT_SESSION_H - -#include "dchroot-session-base.h" - -#include - -#include -#include -#include -#include -#include - -namespace dchroot -{ - - /** - * Session handler for dchroot sessions. - * - * This class provides the session handling for dchroot - * compatibility. It overrides the normal authentication checks to - * allow all users to access the service, and it specialises the - * session behaviour to be compatible with the chdir and command - * execution behaviour of dchroot. - */ - class session : public session_base - { - public: - /** - * The constructor. - * - * @param service the PAM service name. - * @param config a shared_ptr to the chroot configuration. - * @param operation the session operation to perform. - * @param chroots the chroots to act upon. - * @param compat true to enable full dchroot compatibility, or - * false to enable schroot compatiblity (permissions checks). - */ - session (std::string const& service, - config_ptr& config, - operation operation, - sbuild::string_list const& chroots, - bool compat); - - /// The destructor. - virtual ~session (); - - virtual sbuild::auth::status - get_chroot_auth_status (sbuild::auth::status status, - sbuild::chroot::ptr const& chroot) const; - - virtual sbuild::string_list - get_login_directories () const; - - virtual void - get_user_command (sbuild::chroot::ptr& session_chroot, - std::string& file, - sbuild::string_list& command) const; - }; - -} - -#endif /* DCHROOT_SESSION_H */ - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/dchroot.1.in b/schroot/dchroot.1.in deleted file mode 100644 index 247a29b5..00000000 --- a/schroot/dchroot.1.in +++ /dev/null @@ -1,258 +0,0 @@ -.\" Copyright © 2005-2006 Roger Leigh -.\" -.\" schroot is free software; you can redistribute it and/or modify it -.\" under the terms of the GNU General Public License as published by -.\" the Free Software Foundation; either version 2 of the License, or -.\" (at your option) any later version. -.\" -.\" schroot is distributed in the hope that it will be useful, but -.\" WITHOUT ANY WARRANTY; without even the implied warranty of -.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -.\" General Public License for more details. -.\" -.\" You should have received a copy of the GNU General Public License -.\" along with this program; if not, write to the Free Software -.\" Foundation, Inc., 59 Temple Place, Suite 330, Boston, -.\" MA 02111-1307 USA -.TH DCHROOT 1 "@RELEASE_DATE@" "Version @VERSION@" "Debian sbuild" -.SH NAME -dchroot \- enter a chroot environment -.SH SYNOPSIS -.B dchroot -[\fIOPTION\fP]... [\fICOMMAND\fP] -.SH DESCRIPTION -\fBdchroot\fP allows the user to run a command or a login shell in a chroot -environment. If no command is specified, a login shell will be started in the -user's home directory inside the chroot. -.PP -The command is a single argument which will be run in the user's default shell -using its \[lq]\-c\[rq] option. As a result, shell code may be embedded in -this argument. -.PP -Unless the \fI-d\fP option is used to preserve the environment, the login shell -or command will run in the user's home directory inside the chroot, or / if the -home directory is not available. When the \fI-d\fP option is used, it will -attempt to use the current working directory inside the chroot, again falling -back to / if it is not accessible. -.PP -This version of \fBdchroot\fP is a compatibility wrapper around the -.BR schroot (1) -program. It is provided for backward compatibility with the \fBdchroot\fP -command-line options, but \fBschroot\fP is recommended for future use. See the -section \[lq]\fIMigration\fP\[rq] below for help migrating an existing -\fBdchroot\fP configuration to \fBschroot\fP. See the section -\[lq]\fIIncompatibilities\fP\[rq] below for known incompatibilities with -\fBdchroot\fP. -.PP -If no chroot is specified, the chroot name or alias \fBdefault\fP will be used -as a fallback. If using the configuration in \fI@DCHROOT_CONF@\fP, the first -chroot in the file is the default. -.SH OPTIONS -Note that the original \fBdchroot\fP did not provide long options. -\fBdchroot\fP accepts the following options: -.SS Basic options -.TP -.B \-h, \-\-help -Show help summary. -.TP -.B \-a, \-\-all -Select all chroots. -.TP -.B \-c, \-\-chroot=\fIchroot\fP -Specify a chroot to use. This option may be used multiple times to specify -more than one chroot, in which case its effect is similar to \fB\-\-all\fP. -.TP -.B \-l, \-\-list -List all available chroots. -.TP -.B \-i, \-\-info -Print detailed information about the specified chroots. Note that the original -\fBdchroot\fP did not include this option. -.TP -.B \-p, \-\-path -Print location (path) of the specified chroots. -.TP -.B \-\-config -Print configuration of the specified chroots. This is useful for testing that -the configuration in use is the same as the configuration file. Any comments -in the original file will be missing. Note that the original \fBdchroot\fP did -not include this option. -.TP -.B \-d, \-\-preserve\-environment -Preserve the user's environment inside the chroot environment. The default is -to use a clean environment; this option copies the entire user environment and -sets it in the session. -.TP -.B \-q, \-\-quiet -Print only essential messages. -.TP -.B \-v, \-\-verbose -Print all messages. Note that the original \fBdchroot\fP did not include this -option. -.TP -.B \-V, \-\-version -Print version information. -.SH CONFIGURATION -The original \fBdchroot\fP configuration file, \fI@DCHROOT_CONF@\fP has the -following format: -.IP \[bu] -\[oq]#\[cq] starts a comment line. -.IP \[bu] -Blank lines are ignored. -.IP \[bu] -Chroot definitions are a single line containing an \fIidentifier\fP, -\fIpath\fP, and an optional \fIpersonality\fP separated by whitespace. The -first chroot is also the default. -.PP -An example file: -.PP -.RS -\f[CR]# Example comment\fP -.br -\f[CR]\fP -.br -\f[CR]sarge /srv/chroot/sarge\fP -.br -\f[CR]sid /srv/chroot/sid linux32\fP -.br -.RE -.PP -This file defines a chroot called \[oq]sarge\[cq], located at -\fI/srv/chroot/sarge\fP, and a second chroot called \[oq]sid\[cq], located at -\fI/srv/chroot/sid\fP. The second chroot uses the \[lq]linux32\[rq] -personality, which allows a 32-bit chroot to be used on a 64-bit system. -\[oq]sarge\[cq] is the default chroot, because it was listed first, which means -if the \fI\-c\fP option is omitted, this chroot will be used. -.SH INCOMPATIBILITIES -.SS Debian dchroot prior to version 0.99. -.IP \[bu] -Log messages are worded and formatted differently. -.IP \[bu] -The parsing of \fI@DCHROOT_CONF@\fP uses a smaller list of allowed whitespace -characters (space and tab), which may cause a parse error during tokenising if -the file contains odd characters as separators, such as carriage returns, -vertical tabs and form feeds. -.IP \[bu] -su is no longer used to run commands in the chroot. This is done by dchroot -internally. This change may cause subtle differences. If you find an -incompatibility, please report it so it can be corrected. -.IP \[bu] -\fBdchroot\fP provides a restricted subset of the functionality implemented by -\fBschroot\fP, but is still \fBschroot\fP underneath. Thus \fBdchroot\fP is -still subject to \fBschroot\fP security checking, including PAM authentication -and authorisation, and session management, for example, and hence may behave -slightly differently to the older \fBdchroot\fP in some circumstances. -.SS DSA dchroot -Machines run by the Debian System Administrators for the Debian Project have a -\fBdchroot-dsa\fP package which provides an alternate \fBdchroot\fP -implementation. -.IP \[bu] -All the above incompatibilities apply. -.IP \[bu] -This version of dchroot has incompatible command-line options, and while some -of those options are supported or have equivalent options by a different name, -the \fI\-c\fP option is not required to specify a chroot, and this version of -dchroot cannot implement this behaviour in a backward-compatible manner -(because if \fI\-c\fP is omitted, the default chroot is used). DSA dchroot -uses the first non-option as the chroot to use, only allowing one chroot to be -used at once. -.IP \[bu] -This version of dchroot has an incompatible format for \fIdchroot.conf\fP. -While the first two fields are the same, the remaining fields are an optional -list of users permitted to access the chroot, instead of the personality field -allowed by this version. If access restrictions are needed, please use -\fIschroot.conf\fP and add the allowed users there, as shown in -\[lq]\fIMigration\fP\[rq] below. -.SH MIGRATION -To migrate an existing \fBdchroot\fP configuration to \fBschroot\fP, perform -the following steps: -.IP 1 -Dump the \fBdchroot\fP configuration in \fBschroot\fP keyfile format to -\fI@SCHROOT_CONF@\fP. -.PP -.RS -\f[CR]# \f[CB]dchroot --config >> @SCHROOT_CONF@ -.br -.RE -.PP -.IP 2 -Edit \fI@SCHROOT_CONF@\fP to add access to the groups who are to be allowed to -access the chroots, and make any other desired changes to the configuration. -See -.BR schroot.conf (5). -.IP 3 -Remove \fI@DCHROOT_CONF@\fP, so that \fBdchroot\fP will subsequently use -\fI@SCHROOT_CONF@\fP for its configuration. -.SH EXAMPLES -\f[CR]$ dchroot \-l\fP -.br -\f[CR]Available chroots: sarge [default], sid\fP -.br -\f[CR]\fP -.br -\f[CR]$ dchroot \-p sid\fP -.br -\f[CR]/srv/chroot/sid\fP -.br -\f[CR]\fP -.br -\f[CR]$ dchroot \-q \-c sid \-\- "uname \-smr"\fP -.br -\f[CR]Linux 2.6.16.17 ppc\fP -.br -\f[CR]\fP -.br -\f[CR]$ dchroot \-c sid\fP -.br -\f[CR]I: [sid chroot] Running login shell: \[lq]/bin/bash\[rq]\fP -.br -\f[CR]$ \fP -.br -.LP -Use \fB\-\-\fP to allow options beginning with \[oq]\-\[cq] or \[oq]\-\-\[cq] -in the command to run in the chroot. This prevents them being interpreted as -options for \fBschroot\fP itself. Note that the top line was echoed to -standard error, and the remaining lines to standard output. This is -intentional, so that program output from commands run in the chroot may be -piped and redirected as required; the data will be the same as if the command -was run directly on the host system. -.SH BUGS -None known at this time. -.SH FILES -.TP -.I @DCHROOT_CONF@ -The system-wide \fBdchroot\fP chroot definition file. This file must be owned -by the root user, and not be writable by other. If present, this file will be -used in preference to @SCHROOT_CONF@. -.TP -.I @SCHROOT_CONF@ -The system-wide \fBschroot\fP definition file. This file must be owned by the -root user, and not be writable by other. It is recommended that this file be -used in preference to \fI@DCHROOT_CONF@\fP, because the chroots can be used -interchangeably with \fBschroot\fP, and the group security policies provided by -\fBschroot\fP are also enforced. -.SH AUTHORS -Roger Leigh. -.PP -This implementation of \fBdchroot\fP uses the same command-line options as the -original \fBdchroot\fP by David Kimdon , but is an -independent implementation. -.SH COPYRIGHT -Copyright \(co 2005-2006 Roger Leigh -.PP -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the Free -Software Foundation; either version 2 of the License, or (at your option) -any later version. -.SH SEE ALSO -.BR schroot (1), -.BR sbuild (1), -.BR chroot (2), -.BR schroot-setup (5), -.BR schroot.conf (5). -.\"# -.\"# The following sets edit modes for GNU EMACS -.\"# Local Variables: -.\"# mode:nroff -.\"# fill-column:79 -.\"# End: diff --git a/schroot/dchroot.cc b/schroot/dchroot.cc deleted file mode 100644 index d7495849..00000000 --- a/schroot/dchroot.cc +++ /dev/null @@ -1,77 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#include - -#include "dchroot-main.h" -#include "dchroot-options.h" - -#include -#include -#include - -#include - -#include - -using std::endl; -using boost::format; -using namespace schroot; - -/** - * Main routine. - * - * @param argc the number of arguments - * @param argv argument vector - * - * @returns 0 on success, 1 on failure or the exit status of the - * chroot command. - */ -int -main (int argc, - char *argv[]) -{ - try - { - // Set up locale. - std::locale::global(std::locale("")); - std::cout.imbue(std::locale()); - std::cerr.imbue(std::locale()); - - dchroot::options::ptr opts(new dchroot::options(argc, argv)); - dchroot::main kit(opts); - exit (kit.run()); - } - catch (std::exception const& e) - { - sbuild::log_error() << e.what() << endl; - exit(EXIT_FAILURE); - } - catch (...) - { - sbuild::log_error() << _("An unknown exception occured") << endl; - exit(EXIT_FAILURE); - } -} - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/sbuild-auth-conv-tty.cc b/schroot/sbuild-auth-conv-tty.cc deleted file mode 100644 index 7701fdde..00000000 --- a/schroot/sbuild-auth-conv-tty.cc +++ /dev/null @@ -1,320 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#include - -#include "sbuild-auth-conv-tty.h" -#include "sbuild-log.h" - -#include - -#include -#include - -#include - -using std::cerr; -using std::endl; -using boost::format; -using namespace sbuild; - -namespace -{ - - typedef std::pair emap; - - /** - * This is a list of the supported error codes. It's used to - * construct the real error codes map. - */ - emap init_errors[] = - { - emap(auth_conv_tty::TIMEOUT, N_("Timed out")), - emap(auth_conv_tty::TIMEOUT_PENDING, N_("Time is running out...")), - emap(auth_conv_tty::TERMIOS, N_("Failed to get terminal settings")), - emap(auth_conv_tty::CONV_TYPE, N_("Unsupported conversation type")) - }; - - volatile sig_atomic_t timer_expired = false; - - /** - * Disable the alarm and signal handler. - * - * @param orig_sa the signal handler to restore. - */ - void - reset_alarm (struct sigaction *orig_sa) - { - // Stop alarm - alarm (0); - // Restore original handler - sigaction (SIGALRM, orig_sa, NULL); - } - - /** - * Handle the SIGALRM signal. - * - * @param ignore the signal number (unused). - */ - void - alarm_handler (int ignore) - { - timer_expired = true; - } - - /** - * Set the SIGALARM handler, and set the timeout to delay seconds. - * The old signal handler is stored in orig_sa. - * - * @param delay the delay (in seconds) before SIGALRM is raised. - * @param orig_sa the location to store the original signal handler. - * @returns true on success, false on failure. - */ - bool - set_alarm (int delay, - struct sigaction *orig_sa) - { - struct sigaction new_sa; - sigemptyset(&new_sa.sa_mask); - new_sa.sa_flags = 0; - new_sa.sa_handler = alarm_handler; - - if (sigaction(SIGALRM, &new_sa, orig_sa) != 0) - { - return false; - } - if (alarm(delay) != 0) - { - sigaction(SIGALRM, orig_sa, NULL); - return false; - } - - return true; - } - -} - -template<> -custom_error::map_type -custom_error::error_strings -(init_errors, - init_errors + (sizeof(init_errors) / sizeof(init_errors[0]))); - -auth_conv_tty::auth_conv_tty (): - warning_timeout(0), - fatal_timeout(0), - start_time(0) -{ -} - -auth_conv_tty::~auth_conv_tty () -{ -} - -time_t -auth_conv_tty::get_warning_timeout () -{ - return this->warning_timeout; -} - -void -auth_conv_tty::set_warning_timeout (time_t timeout) -{ - this->warning_timeout = timeout; -} - -time_t -auth_conv_tty::get_fatal_timeout () -{ - return this->fatal_timeout; -} - -void -auth_conv_tty::set_fatal_timeout (time_t timeout) -{ - this->fatal_timeout = timeout; -} - -int -auth_conv_tty::get_delay () -{ - timer_expired = 0; - time (&this->start_time); - - if (this->fatal_timeout != 0 && - this->start_time >= this->fatal_timeout) - throw error(TIMEOUT); - - if (this->warning_timeout != 0 && - this->start_time >= this->warning_timeout) - { - error e(TIMEOUT_PENDING); - log_warning() << e.what() << endl; - return (this->fatal_timeout ? - this->fatal_timeout - this->start_time : 0); - } - - if (this->warning_timeout != 0) - return this->warning_timeout - this->start_time; - else if (this->fatal_timeout != 0) - return this->fatal_timeout - this->start_time; - else - return 0; -} - -std::string -auth_conv_tty::read_string (std::string message, - bool echo) -{ - struct termios orig_termios, noecho_termios; - struct sigaction saved_signals; - sigset_t old_sigs, new_sigs; - bool use_termios = false; - std::string retval; - - if (isatty(STDIN_FILENO)) - { - use_termios = true; - - if (tcgetattr(STDIN_FILENO, &orig_termios) != 0) - throw error(TERMIOS); - - memcpy(&noecho_termios, &orig_termios, sizeof(struct termios)); - - if (echo == false) - noecho_termios.c_lflag &= ~(ECHO); - - sigemptyset(&new_sigs); - sigaddset(&new_sigs, SIGINT); - sigaddset(&new_sigs, SIGTSTP); - sigprocmask(SIG_BLOCK, &new_sigs, &old_sigs); - } - - char input[PAM_MAX_MSG_SIZE]; - - int delay = get_delay(); - - while (delay >= 0) - { - cerr << message; - - if (use_termios == true) - tcsetattr(STDIN_FILENO, TCSAFLUSH, &noecho_termios); - - if (delay > 0 && set_alarm(delay, &saved_signals) == false) - break; - else - { - int nchars = read(STDIN_FILENO, input, PAM_MAX_MSG_SIZE - 1); - if (use_termios) - { - tcsetattr(STDIN_FILENO, TCSADRAIN, &orig_termios); - if (echo == false && timer_expired == true) - cerr << endl; - } - if (delay > 0) - reset_alarm(&saved_signals); - if (timer_expired == true) - { - delay = get_delay(); - } - else if (nchars > 0) - { - if (echo == false) - cerr << endl; - - if (input[nchars-1] == '\n') - input[--nchars] = '\0'; - else - input[nchars] = '\0'; - - retval = input; - break; - } - else if (nchars == 0) - { - if (echo == false) - cerr << endl; - - retval = ""; - break; - } - } - } - - memset(input, 0, sizeof(input)); - - if (use_termios == true) - { - sigprocmask(SIG_SETMASK, &old_sigs, NULL); - tcsetattr(STDIN_FILENO, TCSADRAIN, &orig_termios); - } - - return retval; -} - -bool -auth_conv_tty::conversation (message_list& messages) -{ - try - { - for (std::vector::iterator cur = messages.begin(); - cur != messages.end(); - ++cur) - { - switch (cur->message_type) - { - case auth_message::MESSAGE_PROMPT_NOECHO: - cur->response = read_string(cur->message, false); - break; - case auth_message::MESSAGE_PROMPT_ECHO: - cur->response = read_string(cur->message, true); - break; - case auth_message::MESSAGE_ERROR: - cerr << cur->message << endl; - break; - case auth_message::MESSAGE_INFO: - cerr << cur->message << endl; - break; - default: - { - format fmt("%1%"); - fmt % cur->message_type; - error e(fmt.str(), CONV_TYPE); - log_error() << e.what() << endl; - return false; - } - break; - } - } - } - catch (error const& e) - { - log_error() << e.what() << std::endl; - return false; - } - - return true; -} - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/sbuild-auth-conv-tty.h b/schroot/sbuild-auth-conv-tty.h deleted file mode 100644 index 98fc9f64..00000000 --- a/schroot/sbuild-auth-conv-tty.h +++ /dev/null @@ -1,133 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#ifndef SBUILD_AUTH_CONV_TTY_H -#define SBUILD_AUTH_CONV_TTY_H - -#include "sbuild-auth-conv.h" -#include "sbuild-custom-error.h" - -#include -#include -#include -#include -#include - -#include -#include - -namespace sbuild -{ - /** - * @brief Authentication conversation handler for terminal devices. - * - * This class is an implementation of the auth_conv interface, and - * is used to interact with the user on a terminal (TTY) interface. - * - * In order to implement timeouts, this class uses alarm(2). This - * has some important implications. Global state is modified by the - * object, so only one may be used at once in a single process. In - * addition, no other part of the process may set or unset the - * SIGALRM handlers and the alarm(2) timer during the time PAM - * authentication is proceeding. - */ - class auth_conv_tty : public auth_conv - { - public: - /// Error codes. - enum error_code - { - TIMEOUT, ///< Timed out. - TIMEOUT_PENDING, ///< Time is running out... - TERMIOS, ///< Failed to get terminal settings. - CONV_TYPE ///< Unsupported conversation type. - }; - - /// Exception type. - typedef custom_error error; - - /// The constructor. - auth_conv_tty (); - /// The destructor. - virtual ~auth_conv_tty (); - - virtual time_t - get_warning_timeout (); - - virtual void - set_warning_timeout (time_t timeout); - - virtual time_t - get_fatal_timeout (); - - virtual void - set_fatal_timeout (time_t timeout); - - virtual bool - conversation (message_list& messages); - - private: - /** - * @brief Get the time delay before the next SIGALRM signal. - * - * If either the warning timeout or the fatal timeout have - * expired, a message to notify the user is printed to stderr. If - * the fatal timeout is reached, an exception is thrown. - * - * @returns the delay in seconds, or 0 if no delay is set. - */ - int get_delay (); - - /** - * @brief Read user input from standard input. - * - * The prompt message is printed to prompt the user for input. If - * echo is true, the user input it echoed back to the terminal, - * but if false, echoing is suppressed using termios(3). - * - * If the SIGALRM timer expires while waiting for input, this is - * handled by re-checking the delay time which will warn the user - * or cause the input routine to terminate if the fatal timeout - * has expired. - * - * @param message the message to prompt the user for input. - * @param echo echo user input to screen. - * @returns a string, which is empty on failure. - */ - std::string - read_string (std::string message, - bool echo); - - /// The time to warn at. - time_t warning_timeout; - /// The time to end at. - time_t fatal_timeout; - /// The time the current delay was obtained at. - time_t start_time; - }; - -} - -#endif /* SBUILD_AUTH_CONV_TTY_H */ - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/sbuild-auth-conv.cc b/schroot/sbuild-auth-conv.cc deleted file mode 100644 index f2314d84..00000000 --- a/schroot/sbuild-auth-conv.cc +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#include - -#include "sbuild-auth-conv.h" - -using namespace sbuild; - -auth_conv::auth_conv () -{ -} - -auth_conv::~auth_conv () -{ -} - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/sbuild-auth-conv.h b/schroot/sbuild-auth-conv.h deleted file mode 100644 index c8760c89..00000000 --- a/schroot/sbuild-auth-conv.h +++ /dev/null @@ -1,120 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#ifndef SBUILD_AUTH_CONV_H -#define SBUILD_AUTH_CONV_H - -#include "sbuild-auth-message.h" -#include "sbuild-error.h" - -#include - -namespace sbuild -{ - - /** - * @brief Authentication conversation handler interface. - * - * This interface should be implemented by objects which handle - * interaction with the user during authentication. - * - * This is a wrapper around the struct pam_conv PAM conversation - * interface, and is used by auth when interacting with the user - * during authentication. - * - * A simple implementation is provided in the form of auth_conv_tty. - * However, more complex implementations might hook into an event - * loop for GUI widget system. - * - * The interface allows the setting of optional warning timeout and - * fatal timeout values, which should default to 0 (not enabled). - * This is an absolute time after which a warning is displayed or - * the conversation ends with an error. - */ - class auth_conv - { - public: - /// A list of messages. - typedef std::vector message_list; - - /// The constructor. - auth_conv (); - /// The destructor. - virtual ~auth_conv (); - - /** - * @brief Get the time at which the user will be warned. - * - * @returns the time. - */ - virtual time_t - get_warning_timeout () = 0; - - /** - * @brief Set the time at which the user will be warned. - * - * @param timeout the time to set. - */ - virtual void - set_warning_timeout (time_t timeout) = 0; - - /** - * @brief Get the time at which the conversation will be - * terminated with an error. - * - * @returns the time. - */ - virtual time_t - get_fatal_timeout () = 0; - - /** - * @brief Set the time at which the conversation will be - * terminated with an error. - * - * @param timeout the time to set. - */ - virtual void - set_fatal_timeout (time_t timeout) = 0; - - /** - * @brief Hold a conversation with the user. - * - * Each of the messages detailed in messages should be displayed - * to the user, asking for input where required. The type of - * message is indicated in the auth_message::message_type field of - * the auth_message. The auth_message::response field of the - * auth_message should be filled in if input is required. - * - * @param messages the messages to display to the user, and - * responses to return to the caller. - * @returns true on success, false on failure. - */ - virtual bool - conversation (message_list& messages) = 0; - }; - -} - -#endif /* SBUILD_AUTH_CONV_H */ - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/sbuild-auth-message.cc b/schroot/sbuild-auth-message.cc deleted file mode 100644 index 732f4ee7..00000000 --- a/schroot/sbuild-auth-message.cc +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#include - -#include "sbuild-auth-message.h" - -using namespace sbuild; - -auth_message::auth_message (auth_message::type type, - std::string const& message): - message_type(type), - message(message), - response() -{ -} - -auth_message::~auth_message () -{ -} - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/sbuild-auth-message.h b/schroot/sbuild-auth-message.h deleted file mode 100644 index a5c23532..00000000 --- a/schroot/sbuild-auth-message.h +++ /dev/null @@ -1,85 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#ifndef SBUILD_AUTH_MESSAGE_H -#define SBUILD_AUTH_MESSAGE_H - -#include -#include - -#include - -namespace sbuild -{ - - /** - * Authentication messages. - * - * When auth needs to interact with the user, it does this by - * sending a list of auth_message objects to an AuthConv - * conversation object. These messages tell the conversation object - * how to display the message to the user, and if necessary, whether - * or not to ask the user for some input. They also store the - * user's input, if required. - */ - class auth_message - { - public: - /// Message type - enum type - { - /// Display a prompt, with no echoing of user input. - MESSAGE_PROMPT_NOECHO = PAM_PROMPT_ECHO_OFF, - /// Display a prompt, echoing user input. - MESSAGE_PROMPT_ECHO = PAM_PROMPT_ECHO_ON, - /// Display an error message. - MESSAGE_ERROR = PAM_ERROR_MSG, - /// Display an informational message. - MESSAGE_INFO = PAM_TEXT_INFO - }; - - /** - * The constructor. - * - * @param message_type the type of message. - * @param message the message to display. - */ - auth_message (type message_type, - std::string const& message); - - /// The destructor. - virtual ~auth_message (); - - /// The type of message. - type message_type; - /// The message to display. - std::string message; - /// The user's response (if any). - std::string response; - }; - -} - -#endif /* SBUILD_AUTH_MESSAGE_H */ - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/sbuild-auth.cc b/schroot/sbuild-auth.cc deleted file mode 100644 index 83c9fb86..00000000 --- a/schroot/sbuild-auth.cc +++ /dev/null @@ -1,692 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#include - -#include "sbuild-auth.h" -#include "sbuild-auth-conv.h" -#include "sbuild-auth-conv-tty.h" - -#include -#include -#include -#include -#include -#include - -#include - -#include - -using std::cerr; -using std::endl; -using boost::format; -using namespace sbuild; - -namespace -{ - - typedef std::pair emap; - - /** - * This is a list of the supported error codes. It's used to - * construct the real error codes map. - */ - emap init_errors[] = - { - emap(auth::HOSTNAME, N_("Failed to get hostname")), - emap(auth::USER, N_("User not found")), - emap(auth::AUTHENTICATION, N_("Access not authorised")), - emap(auth::AUTHORISATION, N_("Authentication failed")), - emap(auth::PAM_DOUBLE_INIT, N_("PAM is already initialised")), - emap(auth::PAM, N_("PAM error")) - }; - -} - -template<> -custom_error::map_type -custom_error::error_strings -(init_errors, - init_errors + (sizeof(init_errors) / sizeof(init_errors[0]))); - -namespace -{ - - /* This is the glue to link PAM user interaction with auth_conv. */ - int - auth_conv_hook (int num_msg, - const struct pam_message **msgm, - struct pam_response **response, - void *appdata_ptr) - { - if (appdata_ptr == 0) - return PAM_CONV_ERR; - - auth_conv *conv = static_cast(appdata_ptr); - assert (conv != 0); - - /* Construct a message vector */ - auth_conv::message_list messages; - for (int i = 0; i < num_msg; ++i) - { - const struct pam_message *source = msgm[i]; - - auth_message - message(static_cast(source->msg_style), - source->msg); - messages.push_back(message); - } - - /* Do the conversation */ - bool status = conv->conversation(messages); - - if (status == true) - { - /* Copy response into **reponse */ - struct pam_response *reply = - static_cast - (malloc(sizeof(struct pam_response) * num_msg)); - - for (int i = 0; i < num_msg; ++i) - { - reply[i].resp_retcode = 0; - reply[i].resp = strdup(messages[i].response.c_str()); - } - - *response = reply; - reply = 0; - - return PAM_SUCCESS; - } - else - return PAM_CONV_ERR; - } - -} - - -auth::auth (std::string const& service_name): - pam(), - service(service_name), - uid(0), - gid(0), - user(), - command(), - home(), - shell(), - user_environment(), - ruid(), - ruser(), - conv(dynamic_cast(new auth_conv_tty)), - message_verbosity(VERBOSITY_NORMAL) -{ - this->ruid = getuid(); - struct passwd *pwent = getpwuid(this->ruid); - if (pwent == 0) - { - // TODO: Convert to using a lexical cast. - std::ostringstream str; - str << this->ruid; - throw error(str.str(), USER, errno); - } - this->ruser = pwent->pw_name; - - /* By default, the auth user is the same as the remote user. */ - set_user(this->ruser); -} - -auth::~auth () -{ - // Shutdown PAM. - try - { - stop(); - } - catch (...) - { - } -} - -std::string const& -auth::get_service () const -{ - return this->service; -} - -uid_t -auth::get_uid () const -{ - return this->uid; -} - -gid_t -auth::get_gid () const -{ - return this->gid; -} - -std::string const& -auth::get_user () const -{ - return this->user; -} - -void -auth::set_user (std::string const& user) -{ - this->uid = 0; - this->gid = 0; - this->home = "/"; - this->shell = "/bin/false"; - - this->user = user; - - struct passwd *pwent = getpwnam(this->user.c_str()); - if (pwent == 0) - { - throw error(user, USER, errno); - } - this->uid = pwent->pw_uid; - this->gid = pwent->pw_gid; - this->home = pwent->pw_dir; - this->shell = pwent->pw_shell; - log_debug(DEBUG_INFO) - << format("auth uid = %1%, gid = %2%") % this->uid % this->gid - << endl; -} - -string_list const& -auth::get_command () const -{ - return this->command; -} - -void -auth::set_command (string_list const& command) -{ - this->command = command; -} - -std::string const& -auth::get_home () const -{ - return this->home; -} - -std::string const& -auth::get_shell () const -{ - return this->shell; -} - -environment const& -auth::get_environment () const -{ - return this->user_environment; -} - -void -auth::set_environment (char **environment) -{ - set_environment(sbuild::environment(environment)); -} - -void -auth::set_environment (environment const& environment) -{ - this->user_environment = environment; -} - -environment -auth::get_pam_environment () const -{ - return environment(pam_getenvlist(this->pam)); -} - -uid_t -auth::get_ruid () const -{ - return this->ruid; -} - -std::string const& -auth::get_ruser () const -{ - return this->ruser; -} - -auth::verbosity -auth::get_verbosity () const -{ - return this->message_verbosity; -} - -void -auth::set_verbosity (auth::verbosity verbosity) -{ - this->message_verbosity = verbosity; -} - -auth::conv_ptr& -auth::get_conv () -{ - return this->conv; -} - -void -auth::set_conv (conv_ptr& conv) -{ - this->conv = conv; -} - -void -auth::run () -{ - try - { - start(); - authenticate(); - setupenv(); - account(); - try - { - cred_establish(); - - const char *authuser = 0; - const void *tmpcast = static_cast(authuser); - pam_get_item(this->pam, PAM_USER, &tmpcast); - log_debug(DEBUG_INFO) - << format("PAM authentication succeeded for user %1%") % authuser - << endl; - - run_impl(); - - /* The session is now finished, either - successfully or not. All PAM operations are - now for cleanup and shutdown, and we must - clean up whether or not errors were raised at - any previous point. This means only the - first error is reported back to the user. */ - - /* Don't cope with failure, since we are now - already bailing out, and an error may already - have been raised */ - } - catch (error const& e) - { - try - { - cred_delete(); - } - catch (error const& discard) - { - } - throw; - } - } - catch (error const& e) - { - try - { - /* Don't cope with failure, since we are now already bailing out, - and an error may already have been raised */ - stop(); - } - catch (error const& discard) - { - } - throw; - } -} - -void -auth::start () -{ - assert(!this->user.empty()); - - if (this->pam != 0) - { - log_debug(DEBUG_CRITICAL) - << "pam_start FAIL (already initialised)" << endl; - throw error("Init PAM", PAM_DOUBLE_INIT); - } - - struct pam_conv conv_hook = - { - auth_conv_hook, - static_cast(this->conv.get()) - }; - - int pam_status; - - if ((pam_status = - pam_start(this->service.c_str(), this->user.c_str(), - &conv_hook, &this->pam)) != PAM_SUCCESS) - { - log_debug(DEBUG_WARNING) << "pam_start FAIL" << endl; - throw error(PAM, pam_strerror(pam_status)); - } - - log_debug(DEBUG_NOTICE) << "pam_start OK" << endl; -} - -void -auth::stop () -{ - if (this->pam); // PAM must be initialised - { - int pam_status; - - if ((pam_status = - pam_end(this->pam, PAM_SUCCESS)) != PAM_SUCCESS) - { - log_debug(DEBUG_WARNING) << "pam_end FAIL" << endl; - throw error(PAM, pam_strerror(pam_status)); - } - - this->pam = 0; - log_debug(DEBUG_NOTICE) << "pam_end OK" << endl; - } -} - -void -auth::authenticate () -{ - assert(!this->user.empty()); - assert(this->pam != 0); // PAM must be initialised - - int pam_status; - - if ((pam_status = - pam_set_item(this->pam, PAM_RUSER, this->ruser.c_str())) != PAM_SUCCESS) - { - log_debug(DEBUG_WARNING) << "pam_set_item (PAM_RUSER) FAIL" << endl; - throw error(_("Set RUSER"), PAM, pam_strerror(pam_status)); - } - - long hl = 256; /* sysconf(_SC_HOST_NAME_MAX); BROKEN with Debian libc6 2.3.2.ds1-22 */ - - char *hostname = new char[hl]; - if (gethostname(hostname, hl) != 0) - { - log_debug(DEBUG_CRITICAL) << "gethostname FAIL" << endl; - throw error(HOSTNAME, errno); - } - - if ((pam_status = - pam_set_item(this->pam, PAM_RHOST, hostname)) != PAM_SUCCESS) - { - log_debug(DEBUG_WARNING) << "pam_set_item (PAM_RHOST) FAIL" << endl; - throw error(_("Set RHOST"), PAM, pam_strerror(pam_status)); - } - - delete[] hostname; - hostname = 0; - - const char *tty = ttyname(STDIN_FILENO); - if (tty) - { - if ((pam_status = - pam_set_item(this->pam, PAM_TTY, tty)) != PAM_SUCCESS) - { - log_debug(DEBUG_WARNING) << "pam_set_item (PAM_TTY) FAIL" << endl; - throw error(_("Set TTY"), PAM, pam_strerror(pam_status)); - } - } - - /* Authenticate as required. */ - switch (get_auth_status()) - { - case STATUS_NONE: - if ((pam_status = pam_set_item(this->pam, PAM_USER, this->user.c_str())) - != PAM_SUCCESS) - { - log_debug(DEBUG_WARNING) << "pam_set_item (PAM_USER) FAIL" << endl; - throw error(_("Set USER"), PAM, pam_strerror(pam_status)); - } - break; - - case STATUS_USER: - if ((pam_status = pam_authenticate(this->pam, 0)) != PAM_SUCCESS) - { - log_debug(DEBUG_INFO) << "pam_authenticate FAIL" << endl; - syslog(LOG_AUTH|LOG_WARNING, "%s->%s Authentication failure", - this->ruser.c_str(), this->user.c_str()); - throw error(AUTHENTICATION, pam_strerror(pam_status)); - } - log_debug(DEBUG_NOTICE) << "pam_authenticate OK" << endl; - break; - - case STATUS_FAIL: - { - log_debug(DEBUG_INFO) << "PAM auth premature FAIL" << endl; - cerr << format(_("You do not have permission to access the %1% service.")) - % this->service - << '\n' - << _("This failure will be reported.") - << endl; - syslog(LOG_AUTH|LOG_WARNING, - "%s->%s Unauthorised", - this->ruser.c_str(), this->user.c_str()); - throw error(AUTHORISATION); - } - default: - break; - } -} - -void -auth::setupenv () -{ - assert(this->pam != 0); // PAM must be initialised - - int pam_status; - - environment environment; - if (!this->user_environment.empty()) - environment = this->user_environment; - - // For security, PATH is always set to a sane state for root, but - // only set in other cases if not preserving the environment. - if (this->uid == 0) - environment.add(std::make_pair("PATH", "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11")); - else if (this->user_environment.empty()) - environment.add(std::make_pair("PATH", "/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games")); - - if (this->user_environment.empty()) - { - if (!this->home.empty() ) - environment.add(std::make_pair("HOME", this->home)); - else - environment.add(std::make_pair("HOME", "/")); - if (!this->user.empty()) - { - environment.add(std::make_pair("LOGNAME", this->user)); - environment.add(std::make_pair("USER", this->user)); - } - { - const char *term = getenv("TERM"); - if (term) - environment.add(std::make_pair("TERM", term)); - } - if (!this->shell.empty()) - environment.add(std::make_pair("SHELL", this->shell)); - } - - // Sanitise environment. - environment.remove("BASH_ENV"); - environment.remove("CDPATH"); - environment.remove("ENV"); - environment.remove("HOSTALIASES"); - environment.remove("IFS"); - environment.remove("KRB5_CONFIG"); - environment.remove("KRBCONFDIR"); - environment.remove("KRBTKFILE"); - environment.remove("KRB_CONF"); - environment.remove("LOCALDOMAIN"); - environment.remove("NLSPATH"); - environment.remove("PATH_LOCALE"); - environment.remove("RES_OPTIONS"); - environment.remove("TERMINFO"); - environment.remove("TERMINFO_DIRS"); - environment.remove("TERMPATH"); - - // Find and remove LD_.*, - string_list ldvars; - for (environment::const_iterator cur = environment.begin(); - cur != environment.end();) - { - environment::const_iterator next = cur; - next++; - - if (cur->first.substr(0,3) == "LD_") - environment.remove(cur->first); - - cur = next; - } - - // Move into PAM environment. - for (environment::const_iterator cur = environment.begin(); - cur != environment.end(); - ++cur) - { - std::string env_string = cur->first + "=" + cur->second; - if ((pam_status = - pam_putenv(this->pam, env_string.c_str())) != PAM_SUCCESS) - { - log_debug(DEBUG_WARNING) << "pam_putenv FAIL" << endl; - throw error(PAM, pam_strerror(pam_status)); - } - log_debug(DEBUG_INFO) - << format("pam_putenv: set %1%=%2%") % cur->first % cur->second - << endl; - } - - log_debug(DEBUG_NOTICE) << "pam_putenv OK" << endl; -} - -void -auth::account () -{ - assert(this->pam != 0); // PAM must be initialised - - int pam_status; - - if ((pam_status = - pam_acct_mgmt(this->pam, 0)) != PAM_SUCCESS) - { - /* We don't handle changing expired passwords here, since we are - not login or ssh. */ - log_debug(DEBUG_WARNING) << "pam_acct_mgmt FAIL" << endl; - throw error(PAM, pam_strerror(pam_status)); - } - - log_debug(DEBUG_NOTICE) << "pam_acct_mgmt OK" << endl; -} - -void -auth::cred_establish () -{ - assert(this->pam != 0); // PAM must be initialised - - int pam_status; - - if ((pam_status = - pam_setcred(this->pam, PAM_ESTABLISH_CRED)) != PAM_SUCCESS) - { - log_debug(DEBUG_WARNING) << "pam_setcred FAIL" << endl; - throw error(PAM, pam_strerror(pam_status)); - } - - log_debug(DEBUG_NOTICE) << "pam_setcred OK" << endl; -} - -void -auth::cred_delete () -{ - assert(this->pam != 0); // PAM must be initialised - - int pam_status; - - if ((pam_status = - pam_setcred(this->pam, PAM_DELETE_CRED)) != PAM_SUCCESS) - { - log_debug(DEBUG_WARNING) << "pam_setcred (delete) FAIL" << endl; - throw error(PAM, pam_strerror(pam_status)); - } - - log_debug(DEBUG_NOTICE) << "pam_setcred (delete) OK" << endl; -} - -void -auth::open_session () -{ - assert(this->pam != 0); // PAM must be initialised - - int pam_status; - - if ((pam_status = - pam_open_session(this->pam, 0)) != PAM_SUCCESS) - { - log_debug(DEBUG_WARNING) << "pam_open_session FAIL" << endl; - throw error(PAM, pam_strerror(pam_status)); - } - - log_debug(DEBUG_NOTICE) << "pam_open_session OK" << endl; -} - -void -auth::close_session () -{ - assert(this->pam != 0); // PAM must be initialised - - int pam_status; - - if ((pam_status = - pam_close_session(this->pam, 0)) != PAM_SUCCESS) - { - log_debug(DEBUG_WARNING) << "pam_close_session FAIL" << endl; - throw error(PAM, pam_strerror(pam_status)); - } - - log_debug(DEBUG_NOTICE) << "pam_close_session OK" << endl; -} - -auth::status -auth::get_auth_status () const -{ - status authtype = STATUS_NONE; - - authtype = change_auth(authtype, STATUS_USER); - - return authtype; -} - -const char * -auth::pam_strerror (int pam_error) -{ - return ::pam_strerror (this->pam, pam_error); -} - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/sbuild-auth.h b/schroot/sbuild-auth.h deleted file mode 100644 index fa6e0225..00000000 --- a/schroot/sbuild-auth.h +++ /dev/null @@ -1,478 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#ifndef SBUILD_AUTH_H -#define SBUILD_AUTH_H - -#include "sbuild-config.h" -#include "sbuild-auth-conv.h" -#include "sbuild-custom-error.h" -#include "sbuild-environment.h" -#include "sbuild-types.h" - -#include -#include - -#ifdef HAVE_TR1_MEMORY -#include -#elif HAVE_BOOST_SHARED_PTR_HPP -#include -namespace std { namespace tr1 { using boost::shared_ptr; } } -#else -#error A shared_ptr implementation is not available -#endif - -#include -#include -#include -#include -#include - -#include - -namespace sbuild -{ - - /** - * @brief Authentication handler. - * - * auth handles user authentication, authorisation and session - * management using the Pluggable authentication Modules (PAM) - * library. It is essentially an object-oriented wrapper around PAM. - * - * In order to use PAM correctly, it is important to call several of - * the methods in the correct order. For example, it is not possible - * to authorise a user before authenticating a user, and a session may - * not be started before either of these have occured. - * - * The correct order is - * - start - * - authenticate - * - setupenv - * - account - * - cred_establish - * - open_session - * - * After the session has finished, or if an error occured, the - * corresponding cleanup methods should be called - * - close_session - * - sbuild - * - cred_delete - * - stop - * - * The run method will handle all this. The run_impl virtual - * function should be used to provide a session handler to open and - * close the session for the user. open_session and close_session - * must still be used. - */ - class auth - { - public: - /// Authentication status - enum status - { - STATUS_NONE, ///< Authentication is not required. - STATUS_USER, ///< Authentication is required by the user. - STATUS_FAIL ///< Authentication has failed. - }; - - /// Message verbosity - enum verbosity - { - VERBOSITY_QUIET, ///< Only print essential messages. - VERBOSITY_NORMAL, ///< Print messages (the default). - VERBOSITY_VERBOSE ///< Print all messages. - }; - - /// Error codes. - enum error_code - { - HOSTNAME, ///< Failed to get hostname. - USER, ///< User not found. - AUTHENTICATION, ///< Authentication failed. - AUTHORISATION, ///< Authorisation failed. - PAM_DOUBLE_INIT, ///< PAM was already initialised. - PAM ///< PAM error. - }; - - /// Exception type. - typedef custom_error error; - - /// A shared_ptr to an auth_conv object. - typedef std::tr1::shared_ptr conv_ptr; - - /** - * The constructor. - * - * @param service_name the PAM service name. This should be a - * hard-coded constant string literal for safety and security. - * This is passed to pam_start() when initialising PAM, and is - * used to load the correct configuration file from /etc/pam.d. - */ - auth (std::string const& service_name); - - /** - * The destructor. - */ - virtual ~auth (); - - /** - * Get the PAM service name. - * - * @returns the service name. - */ - std::string const& - get_service () const; - - /** - * Get the uid of the user. This is the uid to run as in the * - * session. - * - * @returns a uid. This will be 0 if no user was set, or the user - * is uid 0. - */ - uid_t - get_uid () const; - - /** - * Get the gid of the user. This is the gid to run as in the - * session. - * - * @returns a gid. This will be 0 if no user was set, or the user - * is gid 0. - */ - gid_t - get_gid () const; - - /** - * Get the name of the user. This is the user to run as in the - * session. - * - * @returns the user's name. - */ - std::string const& - get_user () const; - - /** - * Set the name of the user. This is the user to run as in the - * session. - * - * As a side effect, the uid, gid, home and shell member variables - * will also be set, so calling the corresponding get methods will - * now return meaningful values. - * - * @param user the name to set. - */ - void - set_user (std::string const& user); - - /** - * Get the command to run in the session. - * - * @returns the command as string list, each item being a separate - * argument. If no command has been specified, the list will be - * empty. - */ - string_list const& - get_command () const; - - /** - * Set the command to run in the session. - * - * @param command the command to run. This is a string list, each - * item being a separate argument. - */ - void - set_command (string_list const& command); - - /** - * Get the home directory. This is the $HOME to set in the session, - * if the user environment is not being preserved. - * - * @returns the home directory. - */ - std::string const& - get_home () const; - - /** - * Get the name of the shell. This is the shell to run in the - * session. - * - * @returns the shell. This is typically a full pathname, though - * the executable name only should also work (the caller will have - * to search for it). - */ - std::string const& - get_shell () const; - - /** - * Get the environment to use in the session. - * - * @returns an environment list (a list of key-value pairs). - */ - environment const& - get_environment () const; - - /** - * Set the environment to use in the session. - * - * @param environment an environ- or envp-like string vector - * containing key=value pairs. - */ - void - set_environment (char **environment); - - /** - * Set the environment to use in the session. - * - * @param environment an environment list. - */ - void - set_environment (environment const& environment); - - /** - * Get the PAM environment. This is the environment as set by PAM - * modules. - * - * @returns an environment list. - */ - environment - get_pam_environment () const; - - /** - * Get the "remote uid" of the user. This is the uid which is - * requesting authentication. - * - * @returns a uid. - */ - uid_t - get_ruid () const; - - /** - * Get the "remote" name of the user. This is the user which is - * requesting authentication. - * - * @returns a user name. - */ - std::string const& - get_ruser () const; - - /** - * Get the message verbosity. - * - * Returns the verbosity level. - */ - verbosity - get_verbosity () const; - - /** - * Set the message verbosity. - * - * @param verbosity the verbosity level. - */ - void - set_verbosity (verbosity verbosity); - - /** - * Get the conversation handler. - * - * @returns a shared_ptr to the handler. - */ - conv_ptr& - get_conv (); - - /** - * Set the conversation handler. - * - * @param conv a shared_ptr to the handler. - */ - void - set_conv (conv_ptr& conv); - - /** - * Run a session. The user will be asked for authentication if - * required, and then the run_impl virtual method will be called. - * - * An error will be thrown on failure. - */ - void - run (); - - /** - * Start the PAM system. No other PAM functions may be called before - * calling this function. - * - * An error will be thrown on failure. - */ - void - start (); - - /** - * Stop the PAM system. No other PAM functions may be used after - * calling this function. - * - * An error will be thrown on failure. - */ - void - stop (); - - /** - * Perform PAM authentication. If required, the user will be - * prompted to authenticate themselves. - * - * An error will be thrown on failure. - */ - void - authenticate (); - - /** - * Import the user environment into PAM. If no environment was - * specified with set_environment, a minimal environment will be - * created containing HOME, LOGNAME, PATH, TERM and LOGNAME. - * - * An error will be thrown on failure. - */ - void - setupenv (); - - /** - * Do PAM account management (authorisation). - * - * An error will be thrown on failure. - */ - void - account (); - - /** - * Use PAM to establish credentials. - * - * An error will be thrown on failure. - */ - void - cred_establish (); - - /** - * Use PAM to delete credentials. - * - * An error will be thrown on failure. - */ - void - cred_delete (); - - /** - * Open a PAM session. - * - * An error will be thrown on failure. - */ - void - open_session (); - - /** - * Close a PAM session. - * - * An error will be thrown on failure. - */ - void - close_session (); - -protected: - /** - * Check if authentication is required. This default - * implementation always requires authentication. - */ - virtual status - get_auth_status () const; - - /** - * Run session. The code to run when authentication and - * authorisation have been completed. - */ - virtual void - run_impl () = 0; - - public: - /** - * Set new authentication status. If newauth > oldauth, newauth - * is returned, otherwise oldauth is returned. This is to ensure - * the authentication status can never be decreased (relaxed). - * - * @param oldauth the current authentication status. - * @param newauth the new authentication status. - * @returns the new authentication status. - */ - status - change_auth (status oldauth, - status newauth) const - { - /* Ensure auth level always escalates. */ - if (newauth > oldauth) - return newauth; - else - return oldauth; - } - - protected: - /// The PAM handle. - pam_handle_t *pam; - - /** - * Get a description of a PAM error. - * - * @param pam_error the PAM error number. - * @returns the description. - */ - const char * - pam_strerror (int pam_error); - - private: - /// The PAM service name. - const std::string service; - /// The uid to run as. - uid_t uid; - /// The gid to run as. - gid_t gid; - /// The user name to run as. - std::string user; - /// The command to run. - string_list command; - /// The home directory to run in. - std::string home; - /// The user shell to run. - std::string shell; - /// The user environment to set. - environment user_environment; - /// The uid requesting authentication. - uid_t ruid; - /// The user name requesting authentication. - std::string ruser; - /// The PAM conversation handler. - conv_ptr conv; - /// The message verbosity. - verbosity message_verbosity; - }; - -} - -#endif /* SBUILD_AUTH_H */ - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/sbuild-chroot-block-device.cc b/schroot/sbuild-chroot-block-device.cc deleted file mode 100644 index 0fca8020..00000000 --- a/schroot/sbuild-chroot-block-device.cc +++ /dev/null @@ -1,225 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#include - -#include "sbuild-chroot-block-device.h" -#include "sbuild-format-detail.h" -#include "sbuild-lock.h" - -#include -#include - -#include -#include -#include -#include - -#include - -using boost::format; -using namespace sbuild; - -chroot_block_device::chroot_block_device (): - chroot(), - device(), - mount_options() -{ -} - -chroot_block_device::~chroot_block_device () -{ -} - -sbuild::chroot::ptr -chroot_block_device::clone () const -{ - return ptr(new chroot_block_device(*this)); -} - -std::string const& -chroot_block_device::get_device () const -{ - return this->device; -} - -void -chroot_block_device::set_device (std::string const& device) -{ - this->device = device; -} - -std::string const& -chroot_block_device::get_mount_device () const -{ - return this->device; -} - -std::string const& -chroot_block_device::get_mount_options () const -{ - return this->mount_options; -} - -void -chroot_block_device::set_mount_options (std::string const& mount_options) -{ - this->mount_options = mount_options; -} - -std::string const& -chroot_block_device::get_location () const -{ - return chroot::get_location(); -} - -void -chroot_block_device::set_location (std::string const& location) -{ - chroot::set_location(location); -} - -std::string const& -chroot_block_device::get_chroot_type () const -{ - static const std::string type("block-device"); - - return type; -} - -void -chroot_block_device::setup_env (environment& env) -{ - this->chroot::setup_env(env); - - env.add("CHROOT_DEVICE", get_device()); - env.add("CHROOT_MOUNT_OPTIONS", get_mount_options()); -} - -void -chroot_block_device::setup_lock (setup_type type, - bool lock, - int status) -{ - struct stat statbuf; - - /* Only lock during setup, not run. */ - if (type == EXEC_START || type == EXEC_STOP) - return; - - /* Lock is preserved through the entire session. */ - if ((type == SETUP_START && lock == false) || - (type == SETUP_STOP && lock == true)) - return; - - if (stat(this->device.c_str(), &statbuf) == -1) - { - throw error(get_device(), DEVICE_STAT, errno); - } - else if (!S_ISBLK(statbuf.st_mode)) - { - throw error(get_device(), DEVICE_NOTBLOCK); - } - else - { - sbuild::device_lock dlock(this->device); - if (lock) - { - try - { - dlock.set_lock(lock::LOCK_EXCLUSIVE, 15); - } - catch (sbuild::lock::error const& e) - { - throw error(get_device(), DEVICE_LOCK, e.what()); - } - } - else - { - try - { - dlock.unset_lock(); - } - catch (sbuild::lock::error const& e) - { - throw error(get_device(), DEVICE_UNLOCK, e.what()); - } - } - } -} - -sbuild::chroot::session_flags -chroot_block_device::get_session_flags () const -{ - return static_cast(0); -} - -void -chroot_block_device::print_details (std::ostream& stream) const -{ - this->chroot::print_details(stream); - - if (!this->device.empty()) - stream << format_details(_("Device"), get_device()); - if (!this->mount_options.empty()) - stream << format_details(_("Mount Options"), get_mount_options()); - stream << std::flush; -} - -void -chroot_block_device::get_keyfile (keyfile& keyfile) const -{ - chroot::get_keyfile(keyfile); - - keyfile.set_value(get_name(), "device", - get_device()); - - keyfile.set_value(get_name(), "mount-options", - get_mount_options()); - - keyfile.set_value(get_name(), "location", - get_location()); -} - -void -chroot_block_device::set_keyfile (keyfile const& keyfile) -{ - chroot::set_keyfile(keyfile); - - std::string device; - if (keyfile.get_value(get_name(), "device", - keyfile::PRIORITY_REQUIRED, device)) - set_device(device); - - std::string mount_options; - if (keyfile.get_value(get_name(), "mount-options", - keyfile::PRIORITY_OPTIONAL, mount_options)) - set_mount_options(mount_options); - - std::string location; - if (keyfile.get_value(get_name(), "location", - keyfile::PRIORITY_OPTIONAL, location)) - set_location(location); -} - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/sbuild-chroot-block-device.h b/schroot/sbuild-chroot-block-device.h deleted file mode 100644 index 800a3034..00000000 --- a/schroot/sbuild-chroot-block-device.h +++ /dev/null @@ -1,142 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#ifndef SBUILD_CHROOT_BLOCK_DEVICE_H -#define SBUILD_CHROOT_BLOCK_DEVICE_H - -#include "sbuild-chroot.h" - -namespace sbuild -{ - - /** - * A chroot stored on an unmounted block device. The device will be - * mounted on demand. - */ - class chroot_block_device : virtual public chroot - { - protected: - /// The constructor. - chroot_block_device (); - - friend class chroot; - - public: - /// The destructor. - virtual ~chroot_block_device (); - - virtual chroot::ptr - clone () const; - - /** - * Get the block device of the chroot. - * - * @returns the device. - */ - std::string const& - get_device () const; - - /** - * Set the block device of the chroot. This is the "source" device. - * It may be the case that the real device is different (for - * example, an LVM snapshot PV), but by default will be the device - * to mount. - * - * @param device the device. - */ - void - set_device (std::string const& device); - - virtual std::string const& - get_mount_device () const; - - /** - * Get the filesystem mount_options of the chroot block device. - * - * @returns the mount options. - */ - std::string const& - get_mount_options () const; - - /** - * Set the filesystem mount_options of the chroot block device. - * - * @param mount_options the mount options. - */ - void - set_mount_options (std::string const& mount_options); - - /** - * Get the location. This is a path to the chroot directory - * inside the LV (absolute path from the LV root). - * - * @returns the location. - */ - virtual std::string const& - get_location () const; - - /** - * Set the location. This is a path to the chroot directory - * inside the LV (absolute path from the LV root). - * - * @param location the location. - */ - virtual void - set_location (std::string const& location); - - virtual std::string const& - get_chroot_type () const; - - virtual void - setup_env (environment& env); - - virtual session_flags - get_session_flags () const; - - protected: - virtual void - setup_lock (setup_type type, - bool lock, - int status); - - virtual void - print_details (std::ostream& stream) const; - - virtual void - get_keyfile (keyfile& keyfile) const; - - virtual void - set_keyfile (keyfile const& keyfile); - - private: - /// The block device to use. - std::string device; - /// The options to mount the device with. - std::string mount_options; - }; - -} - -#endif /* SBUILD_CHROOT_BLOCK_DEVICE_H */ - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/sbuild-chroot-config.cc b/schroot/sbuild-chroot-config.cc deleted file mode 100644 index 653c5027..00000000 --- a/schroot/sbuild-chroot-config.cc +++ /dev/null @@ -1,490 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#include - -#include "sbuild-chroot.h" -#include "sbuild-chroot-source.h" -#include "sbuild-chroot-config.h" -#include "sbuild-lock.h" - -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include - -#include - -using std::endl; -using boost::format; -using namespace sbuild; - -namespace -{ - - typedef std::pair emap; - - /** - * This is a list of the supported error codes. It's used to - * construct the real error codes map. - */ - emap init_errors[] = - { - emap(chroot_config::DIR_OPEN, N_("Failed to open directory")), - emap(chroot_config::FILE_STAT, N_("Failed to stat file")), - emap(chroot_config::FILE_OPEN, N_("Failed to open file")), - emap(chroot_config::FILE_OWNER, N_("File is not owned by user root")), - emap(chroot_config::FILE_PERMS, N_("File has write permissions for others")), - emap(chroot_config::FILE_NOTREG, N_("File is not a regular file")) - }; - - bool chroot_alphasort (sbuild::chroot::ptr const& c1, - sbuild::chroot::ptr const& c2) - { - return c1->get_name() < c2->get_name(); - } - -} - -template<> -custom_error::map_type -custom_error::error_strings -(init_errors, - init_errors + (sizeof(init_errors) / sizeof(init_errors[0]))); - -chroot_config::chroot_config (): - chroots() -{ -} - -chroot_config::chroot_config (std::string const& file, - bool active): - chroots() -{ - add(file, active); -} - -chroot_config::~chroot_config () -{ -} - -void -chroot_config::add (std::string const& location, - bool active) -{ - struct stat statbuf; - if (stat(location.c_str(), &statbuf) == 0 && S_ISDIR(statbuf.st_mode)) - add_config_directory(location, active); - else - add_config_file(location, active); -} - -void -chroot_config::add_config_file (std::string const& file, - bool active) -{ - load_data(file, active); -} - -void -chroot_config::add_config_directory (std::string const& dir, - bool active) -{ - if (dir.empty()) - return; - - DIR *d = opendir(dir.c_str()); - if (d == NULL) - { - throw error(dir, DIR_OPEN, errno); - } - - struct dirent *de = NULL; - while ((de = readdir(d)) != NULL) - { - std::string filename = dir + "/" + de->d_name; - - struct stat statbuf; - if (stat(filename.c_str(), &statbuf) < 0) - { - error e(filename, FILE_STAT, errno); - log_warning() << e.what() << endl; - continue; - } - - if (!S_ISREG(statbuf.st_mode)) - { - if (!(strcmp(de->d_name, ".") == 0 || - strcmp(de->d_name, "..") == 0)) - { - error e (filename, FILE_NOTREG); - log_warning() << e.what() << endl; - } - continue; - } - - load_data(filename, active); - } -} - -void -chroot_config::add (chroot::ptr& chroot) -{ - // Make sure insertion will succeed. - if (this->chroots.find(chroot->get_name()) == this->chroots.end() && - this->aliases.find(chroot->get_name()) == this->aliases.end()) - { - // Set up chroot. - this->chroots.insert(std::make_pair(chroot->get_name(), chroot)); - this->aliases.insert(std::make_pair(chroot->get_name(), - chroot->get_name())); - - // Set up aliases. - string_list const& aliases = chroot->get_aliases(); - for (string_list::const_iterator pos = aliases.begin(); - pos != aliases.end(); - ++pos) - { - if (this->aliases.insert - (std::make_pair(*pos, chroot->get_name())) - .second == false) - { - string_map::const_iterator dup = this->aliases.find(*pos); - // Don't warn if alias is for chroot of same name. - if (dup != this->aliases.end()) - { - if (chroot->get_name() != dup->first) - log_warning() << - format(_("%1% chroot: " - "Alias '%2%' already associated with " - "'%3%' chroot")) - % chroot->get_name() % dup->first % dup->second - << endl; - } - else - log_warning() << - format(_("%1% chroot: " - "Alias '%2%' already associated with " - "another chroot")) - % chroot->get_name() % *pos - << endl; - } - } - } - else - { - log_warning() << format(_("%1% chroot: A chroot or alias already exists by this name")) - % chroot->get_name() - << endl; - log_warning() << format(_("%1% chroot: Duplicate names are not allowed")) - % chroot->get_name() - << endl; - } -} - -chroot_config::chroot_list -chroot_config::get_chroots () const -{ - chroot_list ret; - - for (chroot_map::const_iterator pos = this->chroots.begin(); - pos != this->chroots.end(); - ++pos) - ret.push_back(pos->second); - - std::sort(ret.begin(), ret.end(), chroot_alphasort); - - return ret; -} - -const sbuild::chroot::ptr -chroot_config::find_chroot (std::string const& name) const -{ - chroot_map::const_iterator pos = this->chroots.find(name); - - if (pos != this->chroots.end()) - return pos->second; - else - { - chroot *null_chroot = 0; - return chroot::ptr(null_chroot); - } -} - -const sbuild::chroot::ptr -chroot_config::find_alias (std::string const& name) const -{ - string_map::const_iterator pos = this->aliases.find(name); - - if (pos != this->aliases.end()) - return find_chroot(pos->second); - else - { - chroot *null_chroot = 0; - return chroot::ptr(null_chroot); - } -} - -string_list -chroot_config::get_chroot_list () const -{ - string_list ret; - - for (string_map::const_iterator pos = this->aliases.begin(); - pos != this->aliases.end(); - ++pos) - ret.push_back(pos->first); - - std::sort(ret.begin(), ret.end()); - - return ret; -} - -void -chroot_config::print_chroot_list (std::ostream& stream) const -{ - string_list chroots = get_chroot_list(); - - for (string_list::const_iterator pos = chroots.begin(); - pos != chroots.end(); - ++pos) - stream << *pos << "\n"; - stream << std::flush; -} - -void -chroot_config::print_chroot_list_simple (std::ostream& stream) const -{ - stream << _("Available chroots: "); - - for (chroot_map::const_iterator pos = this->chroots.begin(); - pos != this->chroots.end(); - ++pos) - { - stream << pos->second->get_name(); - string_list const& aliases = pos->second->get_aliases(); - if (!aliases.empty()) - { - stream << " ["; - for (string_list::const_iterator alias = aliases.begin(); - alias != aliases.end(); - ++alias) - { - stream << *alias; - if (alias + 1 != aliases.end()) - stream << ", "; - } - stream << ']'; - } - chroot_map::const_iterator is_end(pos); - if ((++is_end) != chroots.end()) - stream << ", "; - } - - stream << endl; -} - -void -chroot_config::print_chroot_info (string_list const& chroots, - std::ostream& stream) const -{ - for (string_list::const_iterator pos = chroots.begin(); - pos != chroots.end(); - ++pos) - { - const chroot::ptr chroot = find_alias(*pos); - if (chroot) - { - stream << chroot; - if (pos + 1 != chroots.end()) - stream << '\n'; - } - else - log_error() << format(_("%1%: No such chroot")) % *pos - << endl; - } -} - -void -chroot_config::print_chroot_location (string_list const& chroots, - std::ostream& stream) const -{ - for (string_list::const_iterator pos = chroots.begin(); - pos != chroots.end(); - ++pos) - { - const chroot::ptr chroot = find_alias(*pos); - if (chroot) - { - stream << chroot->get_path() << '\n'; - } - else - log_error() << format(_("%1%: No such chroot")) % *pos - << endl; - } - - stream << std::flush; -} - -void -chroot_config::print_chroot_config (string_list const& chroots, - std::ostream& stream) const -{ - keyfile info; - - for (string_list::const_iterator pos = chroots.begin(); - pos != chroots.end(); - ++pos) - { - const chroot::ptr chroot = find_alias(*pos); - if (chroot) - { - info << chroot; - } - else - log_error() << format(_("%1%: No such chroot")) % *pos - << endl; - } - - stream << info; -} - -string_list -chroot_config::validate_chroots (string_list const& chroots) const -{ - string_list bad_chroots; - - for (string_list::const_iterator pos = chroots.begin(); - pos != chroots.end(); - ++pos) - { - const chroot::ptr chroot = find_alias(*pos); - if (!chroot) - bad_chroots.push_back(*pos); - } - - return bad_chroots; -} - -void -chroot_config::load_data (std::string const& file, - bool active) -{ - /* Use a UNIX fd, for security (no races) */ - int fd = open(file.c_str(), O_RDONLY|O_NOFOLLOW); - if (fd < 0) - throw error(file, FILE_OPEN, errno); - - sbuild::file_lock lock(fd); - try - { - lock.set_lock(lock::LOCK_SHARED, 2); - } - catch (lock::error const& e) - { - throw error(file, e.what()); - } - - struct stat statbuf; - if (fstat(fd, &statbuf) < 0) - throw error(file, FILE_STAT, errno); - - if (statbuf.st_uid != 0) - throw error(file, FILE_OWNER); - if (statbuf.st_mode & S_IWOTH) - throw error(file, FILE_PERMS); - if (!S_ISREG(statbuf.st_mode)) - throw error(file, FILE_NOTREG); - - /* Now create an IO Channel and read in the data */ -#ifdef SCHROOT_FILEBUF_OLD - __gnu_cxx::stdio_filebuf fdbuf(fd, std::ios::in, true, BUFSIZ); -#else - __gnu_cxx::stdio_filebuf fdbuf(fd, std::ios::in); -#endif - std::istream input(&fdbuf); - input.imbue(std::locale("C")); - - try - { - parse_data(input, active); - } - catch (runtime_error const& e) - { - throw error(file, e.what()); - } - try - { - lock.unset_lock(); - } - catch (lock::error const& e) - { - throw error(file, e.what()); - } -} - -void -chroot_config::parse_data (std::istream& stream, - bool active) -{ - /* Create key file */ - keyfile kconfig(stream); - - /* Create chroot objects from key file */ - string_list const& groups = kconfig.get_groups(); - for (string_list::const_iterator group = groups.begin(); - group != groups.end(); - ++group) - { - // Set the active property for chroot creation, and create - // the chroot. - kconfig.set_value(*group, "active", active); - std::string type = "plain"; // "plain" is the default type. - kconfig.get_value(*group, "type", type); - chroot::ptr chroot = chroot::create(type); - chroot->set_name(*group); - kconfig >> chroot; - - add(chroot); - - { - chroot_source *source = dynamic_cast(chroot.get()); - if (source != 0 && !chroot->get_active()) - { - chroot::ptr source_chroot = source->clone_source(); - if (source_chroot) - add(source_chroot); - } - } - } -} - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/sbuild-chroot-config.h b/schroot/sbuild-chroot-config.h deleted file mode 100644 index e50ffd1b..00000000 --- a/schroot/sbuild-chroot-config.h +++ /dev/null @@ -1,276 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#ifndef SBUILD_CHROOT_CONFIG_H -#define SBUILD_CHROOT_CONFIG_H - -#include "sbuild-chroot.h" -#include "sbuild-custom-error.h" - -#include -#include -#include -#include - -namespace sbuild -{ - - /** - * Chroot configuration. - * - * This class holds the configuration details from the configuration - * file. Conceptually, it's an opaque container of chroot objects. - * - * Methods are provided to query the available chroots and find - * specific chroots. - */ - class chroot_config - { - public: - /// A list of chroots. - typedef std::vector chroot_list; - /// A map between key-value string pairs. - typedef std::map string_map; - /// A map between a chroot name and a chroot object. - typedef std::map chroot_map; - - /// Error codes. - enum error_code - { - DIR_OPEN, ///< Failed to open directory. - FILE_STAT, ///< Failed to stat file. - FILE_OPEN, ///< Failed to open file. - FILE_OWNER, ///< File is not owned by user root. - FILE_PERMS, ///< File has write permissions for others. - FILE_NOTREG ///< File is not a regular file. - }; - - /// Exception type. - typedef custom_error error; - - /// A shared_ptr to a chroot_config object. - typedef std::tr1::shared_ptr ptr; - - /// The constructor. - chroot_config (); - - /** - * The constructor. - * - * @param file initialise using a configuration file or a whole - * directory containing configuration files. - * @param active true if the chroots in the configuration file are - * active sessions, otherwise false. - */ - chroot_config (std::string const& file, - bool active); - - /// The destructor. - virtual ~chroot_config (); - - /** - * Add a configuration file or directory. The configuration file - * or directory specified will be loaded. - * - * @param location initialise using a configuration file or a - * whole directory containing configuration files. - * @param active true if the chroots in the configuration file are - * active sessions, otherwise false. - */ - void - add (std::string const& location, - bool active); - - private: - /** - * Add a configuration file. The configuration file specified - * will be loaded. - * - * @param file the file to load. - * @param active true if the chroots in the configuration file are - * active sessions, otherwise false. - */ - void - add_config_file (std::string const& file, - bool active); - - /** - * Add a configuration directory. The configuration files in the - * directory specified will all be loaded. - * - * @param dir the directory containing the files to load. - * @param active true if the chroots in the configuration file are - * active sessions, otherwise false. - */ - void - add_config_directory (std::string const& dir, - bool active); - - protected: - /** - * Add a chroot. The lists of chroots and aliases will be - * updated. If a chroot or alias by the same name exists, the - * chroot will not be added, and a warning will be logged. Af any - * of the aliases already exist, a warning will be logged, and the - * alias will not be added. - * - * @param chroot the chroot to add. - */ - void - add (chroot::ptr& chroot); - - public: - /** - * Get a list of available chroots. - * - * @returns a list of available chroots. The list will be empty - * if no chroots are available. - */ - chroot_list - get_chroots () const; - - /** - * Find a chroot by its name. - * - * @param name the chroot name - * @returns the chroot if found, otherwise 0. - */ - const chroot::ptr - find_chroot (std::string const& name) const; - - /** - * Find a chroot by its name or an alias. - * - * @param name the chroot name or alias. - * @returns the chroot if found, otherwise 0. - */ - const chroot::ptr - find_alias (std::string const& name) const; - - /** - * Get the names (including aliases) of all the available chroots, - * sorted in alphabetical order. - * - * @returns the list. The list will be empty if no chroots are - * available. - */ - string_list - get_chroot_list () const; - - /** - * Print all the available chroots to the specified stream. - * - * @param stream the stream to output to. - */ - void - print_chroot_list (std::ostream& stream) const; - - /** - * Print a single line of all the available chroots to the - * specified stream. - * - * @param stream the stream to output to. - */ - void - print_chroot_list_simple (std::ostream& stream) const; - - /** - * Print information about the specified chroots to the specified - * stream. - * - * @param chroots a list of chroots to print. - * @param stream the stream to output to. - */ - void - print_chroot_info (string_list const& chroots, - std::ostream& stream) const; - - /** - * Print location information about the specified chroots to the - * specified stream. - * - * @param chroots a list of chroots to print. - * @param stream the stream to output to. - */ - void - print_chroot_location (string_list const& chroots, - std::ostream& stream) const; - - /** - * Print configuration of the specified chroots to the specified - * stream. - * - * @param chroots a list of chroots to print. - * @param stream the stream to output to. - */ - void - print_chroot_config (string_list const& chroots, - std::ostream& stream) const; - - /** - * Check that all the chroots specified exist. - * - * @param chroots a list of chroots to validate. - * @returns a list of invalid chroots. The list will be empty if - * all chroots are valid. - */ - string_list - validate_chroots (string_list const& chroots) const; - - private: - /** - * Load a configuration file. If there are problems with the - * configuration file, an error will be thrown. The file must be - * owned by root, not writable by other, and be a regular file. - * - * @param file the file to load. - * @param active true if the chroots in the configuration file are - * active sessions, otherwise false. - */ - void - load_data (std::string const& file, - bool active); - - /** - * Parse a loaded configuration file. If there are problems with - * the configuration file, an error will be thrown. - * - * @param stream the data stream to parse. - * @param active true if the chroots in the configuration file are - * active sessions, otherwise false. - */ - virtual void - parse_data (std::istream& stream, - bool active); - - /// A list of chroots (name->chroot mapping). - chroot_map chroots; - /// A list of aliases (alias->name mapping). - string_map aliases; - }; - -} - -#endif /* SBUILD_CHROOT_CONFIG_H */ - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/sbuild-chroot-file.cc b/schroot/sbuild-chroot-file.cc deleted file mode 100644 index 27b6601a..00000000 --- a/schroot/sbuild-chroot-file.cc +++ /dev/null @@ -1,185 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#include - -#include "sbuild-chroot-file.h" -#include "sbuild-format-detail.h" -#include "sbuild-lock.h" - -#include -#include - -#include -#include -#include -#include - -#include - -using boost::format; -using namespace sbuild; - -chroot_file::chroot_file (): - chroot(), - chroot_source(), - file(), - repack(false) -{ - set_run_setup_scripts(true); - set_run_exec_scripts(true); -} - -chroot_file::~chroot_file () -{ -} - -sbuild::chroot::ptr -chroot_file::clone () const -{ - return ptr(new chroot_file(*this)); -} - -sbuild::chroot::ptr -chroot_file::clone_source () const -{ - chroot_file *clone_file = new chroot_file(*this); - ptr clone(clone_file); - - chroot_source::clone_source_setup(clone); - clone_file->repack = true; - - return clone; -} - -std::string const& -chroot_file::get_file () const -{ - return this->file; -} - -void -chroot_file::set_file (std::string const& file) -{ - this->file = file; -} - -std::string const& -chroot_file::get_chroot_type () const -{ - static const std::string type("file"); - - return type; -} - -void -chroot_file::setup_env (environment& env) -{ - chroot::setup_env(env); - chroot_source::setup_env(env); - - env.add("CHROOT_FILE", get_file()); - env.add("CHROOT_FILE_REPACK", this->repack); -} - -void -chroot_file::setup_lock (setup_type type, - bool lock, - int status) -{ - // Check ownership and permissions. - if (type == SETUP_START && lock == true) - { - struct stat statbuf; - if (stat(this->file.c_str(), &statbuf) < 0) - throw error(this->file, FILE_STAT, errno); - - // NOTE: taken from chroot_config::check_security. - if (statbuf.st_uid != 0) - throw error(this->file, FILE_OWNER); - if (statbuf.st_mode & S_IWOTH) - throw error(this->file, FILE_PERMS); - if (!S_ISREG(statbuf.st_mode)) - throw error(this->file, FILE_NOTREG); - } - - /* By default, file chroots do no locking. */ - /* Create or unlink session information. */ - if ((type == SETUP_START && lock == true) || - (type == SETUP_STOP && lock == false && status == 0)) - { - - bool start = (type == SETUP_START); - setup_session_info(start); - } -} - -sbuild::chroot::session_flags -chroot_file::get_session_flags () const -{ - return SESSION_CREATE; -} - -void -chroot_file::print_details (std::ostream& stream) const -{ - chroot::print_details(stream); - chroot_source::print_details(stream); - - if (!this->file.empty()) - stream << format_details(_("File"), get_file()); - stream << format_details(_("File Repack"), this->repack); - stream << std::flush; -} - -void -chroot_file::get_keyfile (keyfile& keyfile) const -{ - chroot::get_keyfile(keyfile); - chroot_source::get_keyfile(keyfile); - - keyfile.set_value(get_name(), "file", - get_file()); - - keyfile.set_value(get_name(), "file-repack", - this->repack); -} - -void -chroot_file::set_keyfile (keyfile const& keyfile) -{ - chroot::set_keyfile(keyfile); - chroot_source::set_keyfile(keyfile); - - std::string file; - if (keyfile.get_value(get_name(), "file", - keyfile::PRIORITY_REQUIRED, file)) - set_file(file); - - keyfile.get_value(get_name(), "file-repack", - get_active() ? - keyfile::PRIORITY_REQUIRED : keyfile::PRIORITY_DISALLOWED, - this->repack); -} - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/sbuild-chroot-file.h b/schroot/sbuild-chroot-file.h deleted file mode 100644 index d324d331..00000000 --- a/schroot/sbuild-chroot-file.h +++ /dev/null @@ -1,107 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#ifndef SBUILD_CHROOT_FILE_H -#define SBUILD_CHROOT_FILE_H - -#include "sbuild-chroot.h" -#include "sbuild-chroot-source.h" - -namespace sbuild -{ - - /** - * A chroot stored in a file archive (tar or zip). The archive will - * be unpacked on demand. - */ - class chroot_file : virtual public chroot, - public chroot_source - { - protected: - /// The constructor. - chroot_file (); - - friend class chroot; - - public: - /// The destructor. - virtual ~chroot_file (); - - virtual chroot::ptr - clone () const; - - virtual chroot::ptr - clone_source () const; - - /** - * Get the file used by the chroot. - * - * @returns the file. - */ - std::string const& - get_file () const; - - /** - * Set the file used by the chroot. - * - * @param file the file. - */ - void - set_file (std::string const& file); - - virtual std::string const& - get_chroot_type () const; - - virtual void - setup_env (environment& env); - - virtual session_flags - get_session_flags () const; - - protected: - virtual void - setup_lock (setup_type type, - bool lock, - int status); - - virtual void - print_details (std::ostream& stream) const; - - virtual void - get_keyfile (keyfile& keyfile) const; - - virtual void - set_keyfile (keyfile const& keyfile); - - private: - /// The file to use. - std::string file; - /// Should the chroot be repacked? - bool repack; - }; - -} - -#endif /* SBUILD_CHROOT_FILE_H */ - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/sbuild-chroot-lvm-snapshot.cc b/schroot/sbuild-chroot-lvm-snapshot.cc deleted file mode 100644 index b7bca908..00000000 --- a/schroot/sbuild-chroot-lvm-snapshot.cc +++ /dev/null @@ -1,248 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#include - -#include "sbuild-chroot-lvm-snapshot.h" -#include "sbuild-format-detail.h" -#include "sbuild-lock.h" - -#include -#include - -#include -#include -#include -#include - -#include - -using std::endl; -using boost::format; -using namespace sbuild; - -chroot_lvm_snapshot::chroot_lvm_snapshot (): - chroot_block_device(), - chroot_source(), - snapshot_device(), - snapshot_options() -{ - set_run_setup_scripts(true); - set_run_exec_scripts(true); -} - -chroot_lvm_snapshot::~chroot_lvm_snapshot () -{ -} - -sbuild::chroot::ptr -chroot_lvm_snapshot::clone () const -{ - return ptr(new chroot_lvm_snapshot(*this)); -} - -sbuild::chroot::ptr -chroot_lvm_snapshot::clone_source () const -{ - ptr clone(new chroot_block_device(*this)); - - chroot_source::clone_source_setup(clone); - - return clone; -} - -std::string const& -chroot_lvm_snapshot::get_snapshot_device () const -{ - return this->snapshot_device; -} - -void -chroot_lvm_snapshot::set_snapshot_device (std::string const& snapshot_device) -{ - this->snapshot_device = snapshot_device; -} - -std::string const& -chroot_lvm_snapshot::get_mount_device () const -{ - return this->snapshot_device; -} - -std::string const& -chroot_lvm_snapshot::get_snapshot_options () const -{ - return this->snapshot_options; -} - -void -chroot_lvm_snapshot::set_snapshot_options (std::string const& snapshot_options) -{ - this->snapshot_options = snapshot_options; -} - -std::string const& -chroot_lvm_snapshot::get_chroot_type () const -{ - static const std::string type("lvm-snapshot"); - - return type; -} - -void -chroot_lvm_snapshot::setup_env (environment& env) -{ - chroot_block_device::setup_env(env); - chroot_source::setup_env(env); - - env.add("CHROOT_LVM_SNAPSHOT_NAME", sbuild::basename(get_snapshot_device())); - env.add("CHROOT_LVM_SNAPSHOT_DEVICE", get_snapshot_device()); - env.add("CHROOT_LVM_SNAPSHOT_OPTIONS", get_snapshot_options()); -} - -void -chroot_lvm_snapshot::setup_lock (setup_type type, - bool lock, - int status) -{ - std::string device; - struct stat statbuf; - - /* Lock is removed by setup script on setup stop. Unlocking here - would fail: the LVM snapshot device no longer exists. */ - if (!(type == SETUP_STOP && lock == false)) - { - if (type == SETUP_START) - device = get_device(); - else - device = get_snapshot_device(); - - if (device.empty()) - { - throw error(CHROOT_DEVICE); - } - else if (stat(device.c_str(), &statbuf) == -1) - { - throw error(get_device(), DEVICE_STAT, errno); - } - else if (!S_ISBLK(statbuf.st_mode)) - { - throw error(get_device(), DEVICE_NOTBLOCK); - } - else - { - /* Lock is preserved while running a command. */ - if ((type == EXEC_START && lock == false) || - (type == EXEC_STOP && lock == true)) - return; - - sbuild::device_lock dlock(device); - if (lock) - { - try - { - dlock.set_lock(lock::LOCK_EXCLUSIVE, 15); - } - catch (sbuild::lock::error const& e) - { - throw error(get_device(), DEVICE_LOCK, e.what()); - } - } - else - { - try - { - dlock.unset_lock(); - } - catch (sbuild::lock::error const& e) - { - throw error(get_device(), DEVICE_UNLOCK, e.what()); - } - } - } - } - - /* Create or unlink session information. */ - if ((type == SETUP_START && lock == true) || - (type == SETUP_STOP && lock == false && status == 0)) - { - bool start = (type == SETUP_START); - setup_session_info(start); - } -} - -sbuild::chroot::session_flags -chroot_lvm_snapshot::get_session_flags () const -{ - return SESSION_CREATE; -} - -void -chroot_lvm_snapshot::print_details (std::ostream& stream) const -{ - chroot_block_device::print_details(stream); - chroot_source::print_details(stream); - - if (!this->snapshot_device.empty()) - stream << format_details(_("LVM Snapshot Device"), - get_snapshot_device()); - if (!this->snapshot_options.empty()) - stream << format_details(_("LVM Snapshot Options"), - get_snapshot_options()); - stream << std::flush; -} - -void -chroot_lvm_snapshot::get_keyfile (keyfile& keyfile) const -{ - chroot_block_device::get_keyfile(keyfile); - chroot_source::get_keyfile(keyfile); - - keyfile.set_value(get_name(), "lvm-snapshot-device", - get_snapshot_device()); - - keyfile.set_value(get_name(), "lvm-snapshot-options", - get_snapshot_options()); -} - -void -chroot_lvm_snapshot::set_keyfile (keyfile const& keyfile) -{ - chroot_block_device::set_keyfile(keyfile); - chroot_source::set_keyfile(keyfile); - - std::string snapshot_device; - if (keyfile.get_value(get_name(), "lvm-snapshot-device", - get_active() ? - keyfile::PRIORITY_REQUIRED : - keyfile::PRIORITY_DISALLOWED, - snapshot_device)) - set_snapshot_device(snapshot_device); - - std::string snapshot_options; - if (keyfile.get_value(get_name(), "lvm-snapshot-options", - keyfile::PRIORITY_REQUIRED, snapshot_options)) - set_snapshot_options(snapshot_options); -} - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/sbuild-chroot-lvm-snapshot.h b/schroot/sbuild-chroot-lvm-snapshot.h deleted file mode 100644 index 743cba3e..00000000 --- a/schroot/sbuild-chroot-lvm-snapshot.h +++ /dev/null @@ -1,130 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#ifndef SBUILD_CHROOT_LVM_SNAPSHOT_H -#define SBUILD_CHROOT_LVM_SNAPSHOT_H - -#include "sbuild-chroot-block-device.h" -#include "sbuild-chroot-source.h" - -namespace sbuild -{ - - /** - * A chroot stored on an LVM logical volume (LV). A snapshot LV - * will be created and mounted on demand. - */ - class chroot_lvm_snapshot : public chroot_block_device, - public chroot_source - { - protected: - /// The constructor. - chroot_lvm_snapshot (); - - friend class chroot; - - public: - /// The destructor. - virtual ~chroot_lvm_snapshot (); - - virtual chroot::ptr - clone () const; - - virtual chroot::ptr - clone_source () const; - - /** - * Get the logical volume snapshot device name. This is used by - * lvcreate. - * - * @returns the device name. - */ - std::string const& - get_snapshot_device () const; - - /** - * Set the logical volume snapshot device name. This is used by - * lvcreate. - * - * @param snapshot_device the device name. - */ - void - set_snapshot_device (std::string const& snapshot_device); - - virtual std::string const& - get_mount_device () const; - - /** - * Get the logical volume snapshot options. These are used by - * lvcreate. - * - * @returns the options. - */ - std::string const& - get_snapshot_options () const; - - /** - * Set the logical volume snapshot options. These are used by - * lvcreate. - * - * @param snapshot_options the options. - */ - void - set_snapshot_options (std::string const& snapshot_options); - - virtual std::string const& - get_chroot_type () const; - - virtual void - setup_env (environment& env); - - virtual session_flags - get_session_flags () const; - - protected: - virtual void - setup_lock (setup_type type, - bool lock, - int status); - - virtual void - print_details (std::ostream& stream) const; - - virtual void - get_keyfile (keyfile& keyfile) const; - - virtual void - set_keyfile (keyfile const& keyfile); - - private: - /// LVM snapshot device name for lvcreate. - std::string snapshot_device; - /// LVM snapshot options for lvcreate. - std::string snapshot_options; - }; - -} - -#endif /* SBUILD_CHROOT_LVM_SNAPSHOT_H */ - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/sbuild-chroot-plain.cc b/schroot/sbuild-chroot-plain.cc deleted file mode 100644 index 37d25296..00000000 --- a/schroot/sbuild-chroot-plain.cc +++ /dev/null @@ -1,148 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#include - -#include "sbuild-chroot-plain.h" -#include "sbuild-format-detail.h" -#include "sbuild-lock.h" - -#include - -#include -#include -#include -#include - -using namespace sbuild; - -chroot_plain::chroot_plain (): - chroot() -{ -} - -chroot_plain::~chroot_plain () -{ -} - -sbuild::chroot::ptr -chroot_plain::clone () const -{ - return ptr(new chroot_plain(*this)); -} - -std::string const& -chroot_plain::get_location () const -{ - return chroot::get_location(); -} - -void -chroot_plain::set_location (std::string const& location) -{ - chroot::set_location(location); -} - -std::string -chroot_plain::get_path () const -{ - // When running setup scripts, we are session-capable, so the path - // is the bind-mounted location, rather than the original location. - if (get_run_setup_scripts() == true) - return get_mount_location(); - else - return get_location(); -} - -std::string const& -chroot_plain::get_chroot_type () const -{ - static const std::string type("plain"); - - return type; -} - -void -chroot_plain::setup_env (environment& env) -{ - this->chroot::setup_env(env); - - env.add("CHROOT_LOCATION", get_location()); -} - -void -chroot_plain::setup_lock (setup_type type, - bool lock, - int status) -{ - /* By default, plain chroots do no locking. */ - /* Create or unlink session information. */ - if (get_run_setup_scripts() == true) - { - if ((type == SETUP_START && lock == true) || - (type == SETUP_STOP && lock == false && status == 0)) - { - bool start = (type == SETUP_START); - setup_session_info(start); - } - } -} - -sbuild::chroot::session_flags -chroot_plain::get_session_flags () const -{ - if (get_run_setup_scripts() == true) - return SESSION_CREATE; - else - return static_cast(0); -} - -void -chroot_plain::print_details (std::ostream& stream) const -{ - this->chroot::print_details(stream); - - stream << std::flush; -} - -void -chroot_plain::get_keyfile (keyfile& keyfile) const -{ - chroot::get_keyfile(keyfile); - - keyfile.set_value(get_name(), "location", - get_location()); -} - -void -chroot_plain::set_keyfile (keyfile const& keyfile) -{ - chroot::set_keyfile(keyfile); - - std::string location; - if (keyfile.get_value(get_name(), "location", - keyfile::PRIORITY_REQUIRED, location)) - set_location(location); -} - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/sbuild-chroot-plain.h b/schroot/sbuild-chroot-plain.h deleted file mode 100644 index f7c9e753..00000000 --- a/schroot/sbuild-chroot-plain.h +++ /dev/null @@ -1,98 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#ifndef SBUILD_CHROOT_PLAIN_H -#define SBUILD_CHROOT_PLAIN_H - -#include "sbuild-chroot.h" - -namespace sbuild -{ - - /** - * A chroot located on a mounted filesystem. - */ - class chroot_plain : virtual public chroot - { - protected: - /// The constructor. - chroot_plain (); - - friend class chroot; - - public: - /// The destructor. - virtual ~chroot_plain (); - - virtual chroot::ptr - clone () const; - - /** - * Get the directory location of the chroot. - * - * @returns the location. - */ - virtual std::string const& - get_location () const; - - /** - * Set the directory location of the chroot. - * - * @param location the location. - */ - virtual void - set_location (std::string const& location); - - virtual std::string - get_path () const; - - virtual std::string const& - get_chroot_type () const; - - virtual void - setup_env (environment& env); - - virtual session_flags - get_session_flags () const; - - protected: - virtual void - setup_lock (setup_type type, - bool lock, - int status); - - virtual void - print_details (std::ostream& stream) const; - - virtual void - get_keyfile (keyfile& keyfile) const; - - virtual void - set_keyfile (keyfile const& keyfile); - }; - -} - -#endif /* SBUILD_CHROOT_PLAIN_H */ - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/sbuild-chroot-source.cc b/schroot/sbuild-chroot-source.cc deleted file mode 100644 index beb96774..00000000 --- a/schroot/sbuild-chroot-source.cc +++ /dev/null @@ -1,175 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#include - -#include "sbuild-chroot-source.h" -#include "sbuild-format-detail.h" -#include "sbuild-lock.h" - -#include - -#include - -using boost::format; -using namespace sbuild; - -chroot_source::chroot_source (): - chroot() -{ -} - -chroot_source::~chroot_source () -{ -} - -void -chroot_source::clone_source_setup (chroot::ptr& clone) const -{ - clone->set_name(clone->get_name() + "-source"); - clone->set_description - (clone->get_description() + ' ' + _("(source chroot)")); - clone->set_users(this->get_source_users()); - clone->set_groups(this->get_source_groups()); - clone->set_root_users(this->get_source_root_users()); - clone->set_root_groups(this->get_source_root_groups()); - string_list const& aliases = clone->get_aliases(); - string_list source_aliases; - for (string_list::const_iterator alias = aliases.begin(); - alias != aliases.end(); - ++alias) - source_aliases.push_back(*alias + "-source"); - clone->set_aliases(source_aliases); -} - -string_list const& -chroot_source::get_source_users () const -{ - return this->source_users; -} - -void -chroot_source::set_source_users (string_list const& source_users) -{ - this->source_users = source_users; -} - -string_list const& -chroot_source::get_source_groups () const -{ - return this->source_groups; -} - -void -chroot_source::set_source_groups (string_list const& source_groups) -{ - this->source_groups = source_groups; -} - -string_list const& -chroot_source::get_source_root_users () const -{ - return this->source_root_users; -} - -void -chroot_source::set_source_root_users (string_list const& users) -{ - this->source_root_users = users; -} - -string_list const& -chroot_source::get_source_root_groups () const -{ - return this->source_root_groups; -} - -void -chroot_source::set_source_root_groups (string_list const& groups) -{ - this->source_root_groups = groups; -} - -void -chroot_source::setup_env (environment& env) -{ -} - -void -chroot_source::print_details (std::ostream& stream) const -{ - stream << format_details(_("Source Users"), get_source_users()) - << format_details(_("Source Groups"), get_source_groups()) - << format_details(_("Source Root Users"), get_source_root_users()) - << format_details(_("Source Root Groups"), get_source_root_groups()); -} - -void -chroot_source::get_keyfile (keyfile& keyfile) const -{ - string_list const& source_users = get_source_users(); - keyfile.set_list_value(get_name(), "source-users", - source_users.begin(), source_users.end()); - - string_list const& source_groups = get_source_groups(); - keyfile.set_list_value(get_name(), "source-groups", - source_groups.begin(), source_groups.end()); - - string_list const& source_root_groups = get_source_root_groups(); - keyfile.set_list_value(get_name(), "source-root-groups", - source_root_groups.begin(), source_root_groups.end()); - - string_list const& source_root_users = get_source_root_users(); - keyfile.set_list_value(get_name(), "source-root-users", - source_root_users.begin(), source_root_users.end()); -} - -void -chroot_source::set_keyfile (keyfile const& keyfile) -{ - string_list source_users; - if (keyfile.get_list_value(get_name(), "source-users", - keyfile::PRIORITY_OPTIONAL, - source_users)) - set_source_users(source_users); - - string_list source_groups; - if (keyfile.get_list_value(get_name(), "source-groups", - keyfile::PRIORITY_OPTIONAL, - source_groups)) - set_source_groups(source_groups); - - string_list source_root_users; - if (keyfile.get_list_value(get_name(), "source-root-users", - keyfile::PRIORITY_OPTIONAL, - source_root_users)) - set_source_root_users(source_root_users); - - string_list source_root_groups; - if (keyfile.get_list_value(get_name(), "source-root-groups", - keyfile::PRIORITY_OPTIONAL, - source_root_groups)) - set_source_root_groups(source_root_groups); -} - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/sbuild-chroot-source.h b/schroot/sbuild-chroot-source.h deleted file mode 100644 index 719a62f8..00000000 --- a/schroot/sbuild-chroot-source.h +++ /dev/null @@ -1,172 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#ifndef SBUILD_CHROOT_SOURCE_H -#define SBUILD_CHROOT_SOURCE_H - -#include "sbuild-chroot.h" - -namespace sbuild -{ - - /** - * A chroot may offer a "source" chroot in addition to its normal - * "session" copy, to allow for maintenence of the source data. - * This interface may be implemented by any chroot wishing to - * provide such functionality. - * - * While this is effectively an interface, in practice this derives - * from sbuild::chroot, to allow setting and getting of data from a - * keyfile, including storing the keyfile options. - * - * Chroot types implementing chroot_source should, at a minimum, - * implement clone_source(). This should create and return a source - * chroot, and must call clone_source_setup() to set up the source - * chroot. - */ - class chroot_source : virtual public chroot - { - protected: - /// The constructor. - chroot_source (); - - friend class chroot; - - public: - /// The destructor. - virtual ~chroot_source (); - - virtual chroot::ptr - clone_source () const = 0; - - protected: - /** - * Set the defaults in the cloned source chroot. - * - * @param clone the chroot to set up. - */ - void - clone_source_setup (chroot::ptr& clone) const; - - public: - /** - * Get the users allowed to access the source chroot. - * - * @returns a list of users. - */ - virtual string_list const& - get_source_users () const; - - /** - * Set the users allowed to access the source chroot. - * - * @param users a list of users. - */ - virtual void - set_source_users (string_list const& users); - - /** - * Get the groups allowed to access the source chroot. - * - * @returns a list of groups. - */ - virtual string_list const& - get_source_groups () const; - - /** - * Set the groups allowed to access the source chroot. - * - * @param groups a list of groups. - */ - virtual void - set_source_groups (string_list const& groups); - - /** - * Get the users allowed to access the source chroot as root. - * Mmebers of these users can switch to root without - * authenticating themselves. - * - * @returns a list of users. - */ - virtual string_list const& - get_source_root_users () const; - - /** - * Set the users allowed to access the source chroot as root. - * Mmebers of these users can switch to root without - * authenticating themselves. - * - * @param users a list of users. - */ - virtual void - set_source_root_users (string_list const& users); - - /** - * Get the groups allowed to access the source chroot as root. - * Mmebers of these groups can switch to root without - * authenticating themselves. - * - * @returns a list of groups. - */ - virtual string_list const& - get_source_root_groups () const; - - /** - * Set the groups allowed to access the source chroot as root. - * Mmebers of these groups can switch to root without - * authenticating themselves. - * - * @param groups a list of groups. - */ - virtual void - set_source_root_groups (string_list const& groups); - - void - setup_env (environment& env); - - protected: - void - print_details (std::ostream& stream) const; - - void - get_keyfile (keyfile& keyfile) const; - - void - set_keyfile (keyfile const& keyfile); - - private: - /// Users allowed to access the source chroot. - string_list source_users; - /// Groups allowed to access the source chroot. - string_list source_groups; - /// Users allowed to access the source chroot as root. - string_list source_root_users; - /// Groups allowed to access the source chroot as root. - string_list source_root_groups; - }; - -} - -#endif /* SBUILD_CHROOT_SOURCE_H */ - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/sbuild-chroot.cc b/schroot/sbuild-chroot.cc deleted file mode 100644 index 27d5ae69..00000000 --- a/schroot/sbuild-chroot.cc +++ /dev/null @@ -1,622 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#include - -#include "sbuild-chroot.h" -#include "sbuild-chroot-plain.h" -#include "sbuild-chroot-file.h" -#include "sbuild-chroot-block-device.h" -#include "sbuild-chroot-lvm-snapshot.h" -#include "sbuild-format-detail.h" -#include "sbuild-lock.h" - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include - -using boost::format; -using namespace sbuild; - -namespace -{ - - typedef std::pair emap; - - /** - * This is a list of the supported error codes. It's used to - * construct the real error codes map. - */ - emap init_errors[] = - { - emap(sbuild::chroot::CHROOT_TYPE, N_("Unknown chroot type")), - emap(sbuild::chroot::CHROOT_CREATE, N_("Chroot creation failed")), - emap(sbuild::chroot::CHROOT_DEVICE, N_("Device name not set")), - emap(sbuild::chroot::SESSION_WRITE, N_("Failed to write session file")), - emap(sbuild::chroot::SESSION_UNLINK, N_("Failed to unlink session file")), - emap(sbuild::chroot::FILE_STAT, N_("Failed to stat file")), - emap(sbuild::chroot::FILE_OWNER, N_("File is not owned by user root")), - emap(sbuild::chroot::FILE_PERMS, N_("File has write permissions for others")), - emap(sbuild::chroot::FILE_NOTREG, N_("File is not a regular file")), - emap(sbuild::chroot::FILE_LOCK, N_("Failed to acquire file lock")), - emap(sbuild::chroot::FILE_UNLOCK, N_("Failed to discard file lock")), - emap(sbuild::chroot::DEVICE_STAT, N_("Failed to stat device")), - emap(sbuild::chroot::DEVICE_NOTBLOCK, N_("File is not a block device")), - emap(sbuild::chroot::DEVICE_LOCK, N_("Failed to lock device")), - emap(sbuild::chroot::DEVICE_UNLOCK, N_("Failed to unlock device")) - }; - -} - -template<> -custom_error::map_type -custom_error::error_strings -(init_errors, - init_errors + (sizeof(init_errors) / sizeof(init_errors[0]))); - -sbuild::chroot::chroot (): - name(), - description(), - priority(0), - users(), - groups(), - root_users(), - root_groups(), - aliases(), - mount_location(), - location(), - mount_device(), - active(false), - run_setup_scripts(false), - run_exec_scripts(false), - command_prefix(), - persona( -#ifdef __linux__ - personality("linux") -#else - personality("undefined") -#endif - ) -{ -} - -sbuild::chroot::~chroot () -{ -} - -sbuild::chroot::ptr -sbuild::chroot::create (std::string const& type) -{ - chroot *new_chroot = 0; - - if (type == "plain") - new_chroot = new chroot_plain(); - else if (type == "file") - new_chroot = new chroot_file(); - else if (type == "block-device") - new_chroot = new chroot_block_device(); - else if (type == "lvm-snapshot") - new_chroot = new chroot_lvm_snapshot(); - else - throw error(type, CHROOT_TYPE); - - if (new_chroot == 0) - throw error(CHROOT_CREATE); - - return ptr(new_chroot); -} - -std::string const& -sbuild::chroot::get_name () const -{ - return this->name; -} - -void -sbuild::chroot::set_name (std::string const& name) -{ - this->name = name; -} - -std::string const& -sbuild::chroot::get_description () const -{ - return this->description; -} - -void -sbuild::chroot::set_description (std::string const& description) -{ - this->description = description; -} - -std::string const& -sbuild::chroot::get_mount_location () const -{ - return this->mount_location; -} - -void -sbuild::chroot::set_mount_location (std::string const& location) -{ - this->mount_location = location; -} - -std::string const& -sbuild::chroot::get_location () const -{ - return this->location; -} - -void -sbuild::chroot::set_location (std::string const& location) -{ - this->location = location; -} - -std::string -sbuild::chroot::get_path () const -{ - return get_mount_location() + get_location(); -} - -std::string const& -sbuild::chroot::get_mount_device () const -{ - return this->mount_device; -} - -void -sbuild::chroot::set_mount_device (std::string const& device) -{ - this->mount_device = device; -} - -unsigned int -sbuild::chroot::get_priority () const -{ - return this->priority; -} - -void -sbuild::chroot::set_priority (unsigned int priority) -{ - this->priority = priority; -} - -string_list const& -sbuild::chroot::get_users () const -{ - return this->users; -} - -void -sbuild::chroot::set_users (string_list const& users) -{ - this->users = users; -} - -string_list const& -sbuild::chroot::get_groups () const -{ - return this->groups; -} - -void -sbuild::chroot::set_groups (string_list const& groups) -{ - this->groups = groups; -} - -string_list const& -sbuild::chroot::get_root_users () const -{ - return this->root_users; -} - -void -sbuild::chroot::set_root_users (string_list const& users) -{ - this->root_users = users; -} - -string_list const& -sbuild::chroot::get_root_groups () const -{ - return this->root_groups; -} - -void -sbuild::chroot::set_root_groups (string_list const& groups) -{ - this->root_groups = groups; -} - -string_list const& -sbuild::chroot::get_aliases () const -{ - return this->aliases; -} - -void -sbuild::chroot::set_aliases (string_list const& aliases) -{ - this->aliases = aliases; -} - -bool -sbuild::chroot::get_active () const -{ - return this->active; -} - -void -sbuild::chroot::set_active (bool active) -{ - this->active = active; -} - -bool -sbuild::chroot::get_run_setup_scripts () const -{ - return this->run_setup_scripts; -} - -void -sbuild::chroot::set_run_setup_scripts (bool run_setup_scripts) -{ - this->run_setup_scripts = run_setup_scripts; -} - -bool -sbuild::chroot::get_run_exec_scripts () const -{ - return this->run_exec_scripts; -} - -void -sbuild::chroot::set_run_exec_scripts (bool run_exec_scripts) -{ - this->run_exec_scripts = run_exec_scripts; -} - -string_list const& -sbuild::chroot::get_command_prefix () const -{ - return this->command_prefix; -} - -void -sbuild::chroot::set_command_prefix (string_list const& command_prefix) -{ - this->command_prefix = command_prefix; -} - -personality const& -sbuild::chroot::get_persona () const -{ - return this->persona; -} - -void -sbuild::chroot::set_persona (personality const& persona) -{ - this->persona = persona; -} - -void -sbuild::chroot::setup_env (environment& env) -{ - env.add("CHROOT_TYPE", get_chroot_type()); - env.add("CHROOT_NAME", get_name()); - env.add("CHROOT_DESCRIPTION", get_description()); - env.add("CHROOT_LOCATION", get_location()); - env.add("CHROOT_MOUNT_LOCATION", get_mount_location()); - env.add("CHROOT_PATH", get_path()); - env.add("CHROOT_MOUNT_DEVICE", get_mount_device()); -} - -void -sbuild::chroot::setup_session_info (bool start) -{ - /* Create or unlink session information. */ - std::string file = std::string(SCHROOT_SESSION_DIR) + "/" + get_name(); - - if (start) - { - int fd = open(file.c_str(), O_CREAT|O_EXCL|O_WRONLY, 0664); - if (fd < 0) - throw error(file, SESSION_WRITE, errno); - - // Create a stream buffer from the file descriptor. The fd will - // be closed when the buffer is destroyed. -#ifdef SCHROOT_FILEBUF_OLD - __gnu_cxx::stdio_filebuf fdbuf(fd, std::ios::out, true, BUFSIZ); -#else - __gnu_cxx::stdio_filebuf fdbuf(fd, std::ios::out); -#endif - std::ostream output(&fdbuf); - output.imbue(std::locale("C")); - - sbuild::file_lock lock(fd); - try - { - lock.set_lock(lock::LOCK_EXCLUSIVE, 2); - } - catch (lock::error const& e) - { - throw error(file, FILE_LOCK, e.what()); - } - - keyfile details; - get_keyfile(details); - output << details; - - try - { - lock.unset_lock(); - } - catch (lock::error const& e) - { - throw error(file, FILE_UNLOCK, e.what()); - } - } - else /* start == false */ - { - if (unlink(file.c_str()) != 0) - throw error(file, SESSION_UNLINK, errno); - } -} - -void -sbuild::chroot::lock (setup_type type) -{ - setup_lock(type, true, 0); -} - -void -sbuild::chroot::unlock (setup_type type, - int status) -{ - setup_lock(type, false, status); -} - -void -sbuild::chroot::print_details (std::ostream& stream) const -{ - if (this->active == true) - stream << " " << _("--- Session ---\n"); - else - stream << " " << _("--- Chroot ---\n"); - stream << format_details(_("Name"), get_name()) - << format_details(_("Description"), get_description()) - << format_details(_("Type"), get_chroot_type()) - << format_details(_("Priority"), get_priority()) - << format_details(_("Users"), get_users()) - << format_details(_("Groups"), get_groups()) - << format_details(_("Root Users"), get_root_users()) - << format_details(_("Root Groups"), get_root_groups()) - << format_details(_("Aliases"), get_aliases()) - << format_details(_("Run Setup Scripts"), get_run_setup_scripts()) - << format_details(_("Run Execution Scripts"), - get_run_exec_scripts()) - << format_details(_("Session Managed"), - static_cast(get_session_flags() & - chroot::SESSION_CREATE)); - - if (!get_command_prefix().empty()) - stream << format_details(_("Command Prefix"), get_command_prefix()); - - stream << format_details(_("Personality"), get_persona().get_name()); - - /* Non user-settable properties are listed last. */ - if (!get_location().empty()) - stream << format_details(_("Location"), - get_location()); - if (!get_mount_location().empty()) - stream << format_details(_("Mount Location"), - get_mount_location()); - if (!get_path().empty()) - stream << format_details(_("Path"), - get_path()); - if (!get_mount_device().empty()) - stream << format_details(_("Mount Device"), get_mount_device()); -} - -void -sbuild::chroot::get_keyfile (keyfile& keyfile) const -{ - keyfile.remove_group(this->name); - - keyfile.set_value(this->name, "type", - get_chroot_type()); - - keyfile.set_value(this->name, "active", - get_active()); - - keyfile.set_value(this->name, "run-setup-scripts", - get_run_setup_scripts()); - - keyfile.set_value(this->name, "run-exec-scripts", - get_run_exec_scripts()); - - keyfile.set_value(this->name, "priority", - get_priority()); - - string_list const& aliases = get_aliases(); - keyfile.set_list_value(this->name, "aliases", - aliases.begin(), aliases.end()); - - keyfile.set_value(this->name, "description", - get_description()); - - string_list const& groups = get_groups(); - keyfile.set_list_value(this->name, "groups", - groups.begin(), groups.end()); - - string_list const& users = get_users(); - keyfile.set_list_value(this->name, "users", - users.begin(), users.end()); - - string_list const& root_users = get_root_users(); - keyfile.set_list_value(this->name, "root-users", - root_users.begin(), root_users.end()); - - string_list const& root_groups = get_root_groups(); - keyfile.set_list_value(this->name, "root-groups", - root_groups.begin(), root_groups.end()); - - if (get_active()) - keyfile.set_value(this->name, "mount-location", - get_mount_location()); - - if (get_active()) - keyfile.set_value(this->name, "mount-device", - get_mount_device()); - - string_list const& command_prefix = get_command_prefix(); - keyfile.set_list_value(this->name, "command-prefix", - command_prefix.begin(), command_prefix.end()); - - keyfile.set_value(this->name, "personality", - get_persona().get_name()); -} - -void -sbuild::chroot::set_keyfile (keyfile const& keyfile) -{ - // This is set not in the configuration file, but set in the keyfile - // manually. The user must not have the ability to set this option. - bool active(false); - if (keyfile.get_value(this->name, "active", - keyfile::PRIORITY_REQUIRED, active)) - set_active(active); - - bool run_setup_scripts(false); - if (keyfile.get_value(this->name, "run-setup-scripts", - keyfile::PRIORITY_OPTIONAL, run_setup_scripts)) - set_run_setup_scripts(run_setup_scripts); - - bool run_exec_scripts(false); - if (keyfile.get_value(this->name, "run-session-scripts", - keyfile::PRIORITY_DEPRECATED, run_exec_scripts)) - set_run_exec_scripts(run_exec_scripts); - if (keyfile.get_value(this->name, "run-exec-scripts", - keyfile::PRIORITY_OPTIONAL, run_exec_scripts)) - set_run_exec_scripts(run_exec_scripts); - - int priority(0); - if (keyfile.get_value(this->name, "priority", - keyfile::PRIORITY_OPTIONAL, priority)) - set_priority(priority); - - string_list aliases; - if (keyfile.get_list_value(this->name, "aliases", - keyfile::PRIORITY_OPTIONAL, - aliases)) - set_aliases(aliases); - - std::string description; - if (keyfile.get_locale_string(this->name, "description", - keyfile::PRIORITY_OPTIONAL, description)) - set_description(description); - - string_list users; - if (keyfile.get_list_value(this->name, "users", - keyfile::PRIORITY_OPTIONAL, - users)) - set_users(users); - - string_list groups; - if (keyfile.get_list_value(this->name, "groups", - keyfile::PRIORITY_OPTIONAL, - groups)) - set_groups(groups); - - string_list root_users; - if (keyfile.get_list_value(this->name, "root-users", - keyfile::PRIORITY_OPTIONAL, - root_users)) - set_root_users(root_users); - - string_list root_groups; - if (keyfile.get_list_value(this->name, "root-groups", - keyfile::PRIORITY_OPTIONAL, - root_groups)) - set_root_groups(root_groups); - - std::string mount_location; - if (keyfile.get_value(this->name, "mount-location", - get_active() ? - keyfile::PRIORITY_REQUIRED : keyfile::PRIORITY_DISALLOWED, - mount_location)) - set_mount_location(mount_location); - - std::string mount_device; - if (keyfile.get_value(this->name, "mount-device", - get_active() ? - keyfile::PRIORITY_OPTIONAL : keyfile::PRIORITY_DISALLOWED, - mount_device)) - set_mount_device(mount_device); - - string_list command_prefix; - if (keyfile.get_list_value(this->name, "command-prefix", - keyfile::PRIORITY_OPTIONAL, - command_prefix)) - set_command_prefix(command_prefix); - - std::string persona_name; - if (keyfile.get_value(this->name, "personality", - keyfile::PRIORITY_OPTIONAL, - persona_name)) - { - personality persona (persona_name); - - if (persona.get_name() == "undefined" && - persona.get_name() != persona_name) - { - std::ostringstream plist; - personality::print_personalities(plist); - - log_warning() - << format(_("%1% chroot: personality \"%2%\" is unknown.\n")) - % this->name % persona_name; - log_info() - << format(_("Valid personalities: %1%\n")) % plist.str(); - } - - set_persona(persona); - } -} - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/sbuild-chroot.h b/schroot/sbuild-chroot.h deleted file mode 100644 index b4a975e3..00000000 --- a/schroot/sbuild-chroot.h +++ /dev/null @@ -1,619 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#ifndef SBUILD_CHROOT_H -#define SBUILD_CHROOT_H - -#include "sbuild-config.h" -#include "sbuild-custom-error.h" -#include "sbuild-error.h" -#include "sbuild-environment.h" -#include "sbuild-keyfile.h" -#include "sbuild-personality.h" -#include "sbuild-util.h" - -#include -#include -#include -#include - -#ifdef HAVE_TR1_MEMORY -#include -#elif HAVE_BOOST_SHARED_PTR_HPP -#include -namespace std { namespace tr1 { using boost::shared_ptr; } } -#else -#error A shared_ptr implementation is not available -#endif - -namespace sbuild -{ - - /** - * Common chroot data. This class contains all of the metadata - * associated with a single chroot, for all chroot types. This is - * the in-core representation of a chroot definition in the - * configuration file, and may be initialised directly from an open - * keyfile. - */ - class chroot - { - public: - /// Type of setup to perform. - enum setup_type - { - SETUP_START, ///< Activate a chroot. - SETUP_RECOVER, ///< Reactivate a chroot. - SETUP_STOP, ///< Deactivate a chroot. - EXEC_START, ///< Start executing a command in an active chroot. - EXEC_STOP ///< End executing a command in an active chroot. - }; - - /// Chroot session properties - enum session_flags - { - SESSION_CREATE = 1 << 0 ///< The chroot supports session creation. - }; - - /// Error codes. - enum error_code - { - CHROOT_TYPE, ///< Unknown chroot type. - CHROOT_CREATE, ///< Chroot creation failed. - CHROOT_DEVICE, ///< Chroot device name not set. - SESSION_WRITE, ///< Failed to write session file. - SESSION_UNLINK, ///< Failed to unlink session file. - FILE_STAT, ///< Failed to stat file. - FILE_OWNER, ///< File is not owned by user root. - FILE_PERMS, ///< File has write permissions for others. - FILE_NOTREG, ///< File is not a regular file. - FILE_LOCK, ///< Failed to acquire lock. - FILE_UNLOCK, ///< Failed to discard lock. - DEVICE_STAT, ///< Failed to stat device. - DEVICE_NOTBLOCK, ///< File is not a block device. - DEVICE_LOCK, ///< Failed to lock device. - DEVICE_UNLOCK ///< Failed to unlock device. - }; - - /// Exception type. - typedef custom_error error; - - /// A shared_ptr to a chroot object. - typedef std::tr1::shared_ptr ptr; - - protected: - /// The constructor. - chroot (); - - public: - /// The destructor. - virtual ~chroot (); - - /** - * Create a chroot. This is a factory function. - * - * @param type the type of chroot to create. - * @returns a shared_ptr to the new chroot. - */ - static ptr - create (std::string const& type); - - /** - * Copy the chroot. This is a virtual copy constructor. - * - * @returns a shared_ptr to the new copy of the chroot. - */ - virtual ptr - clone () const = 0; - - /** - * Get the name of the chroot. - * - * @returns the name. - */ - std::string const& - get_name () const; - - /** - * Set the name of the chroot. - * - * @param name the name. - */ - void - set_name (std::string const& name); - - /** - * Get the description of the chroot. - * - * @returns the description. - */ - std::string const& - get_description () const; - - /** - * Set the description of the chroot. - * - * @param description the description. - */ - void - set_description (std::string const& description); - - /** - * Get the mount location of the chroot. - * - * @returns the mount location. - */ - virtual std::string const& - get_mount_location () const; - - /** - * Set the mount location of the chroot. - * - * @param location the mount location. - */ - void - set_mount_location (std::string const& location); - - /** - * Get the location of the chroot. This is the path to the root - * of the chroot, and is typically the same as the mount location, - * but is overridden by the chroot type if required. - * - * @returns the mount location. - */ - virtual std::string const& - get_location () const; - - protected: - /** - * Set the location of the chroot. This is the path to the root - * of the chroot, and is typically the same as the mount location, - * but is overridden by the chroot type if required. - * - * @returns the mount location. - */ - virtual void - set_location (std::string const& location); - - public: - /** - * Get the path to the chroot. This is the absolute path to the - * root of the chroot, and is typically the same as the mount - * location and location concatenated together, but is overridden - * by the chroot type if required. - * - * @returns the path. - */ - virtual std::string - get_path () const; - - /** - * Get the mount device of the chroot. - * - * @returns the device. - */ - virtual std::string const& - get_mount_device () const; - - /** - * Set the mount device of the chroot. - * - * @param device the device. - */ - void - set_mount_device (std::string const& device); - - /** - * Get the priority of the chroot. This is a number indicating - * whether than a ditribution is older than another. - * - * @returns the priority. - */ - unsigned int - get_priority () const; - - /** - * Set the priority of a chroot. This is a number indicating - * whether a distribution is older than another. For example, - * "oldstable" and "oldstable-security" might be 0, while "stable" - * and "stable-security" 1, "testing" 2 and "unstable" 3. The - * values are not important, but the difference between them is. - * - * @param priority the priority. - */ - void - set_priority (unsigned int priority); - - /** - * Get the users allowed to access the chroot. - * - * @returns a list of users. - */ - string_list const& - get_users () const; - - /** - * Set the users allowed to access the chroot. - * - * @param users a list of users. - */ - void - set_users (string_list const& users); - - /** - * Get the groups allowed to access the chroot. - * - * @returns a list of groups. - */ - string_list const& - get_groups () const; - - /** - * Set the users allowed to access the chroot. - * - * @param groups a list of groups. - */ - void - set_groups (string_list const& groups); - - /** - * Get the users allowed to access the chroot as root. Mmebers - * of these users can switch to root without authenticating - * themselves. - * - * @returns a list of users. - */ - string_list const& - get_root_users () const; - - /** - * Set the users allowed to access the chroot as root. Mmebers - * of these users can switch to root without authenticating - * themselves. - * - * @param users a list of users. - */ - void - set_root_users (string_list const& users); - - /** - * Get the groups allowed to access the chroot as root. Mmebers - * of these groups can switch to root without authenticating - * themselves. - * - * @returns a list of groups. - */ - string_list const& - get_root_groups () const; - - /** - * Set the groups allowed to access the chroot as root. Mmebers - * of these groups can switch to root without authenticating - * themselves. - * - * @param groups a list of groups. - */ - void - set_root_groups (string_list const& groups); - - /** - * Get the aliases of the chroot. These are alternative names for - * the chroot. - * - * @returns a list of names. - */ - string_list const& - get_aliases () const; - - /** - * Set the aliases of the chroot. These are alternative names for - * the chroot. - * - * @param aliases a list of names. - */ - void - set_aliases (string_list const& aliases); - - /** - * Get the activity status of the chroot. - * - * @returns true if active, false if inactive - */ - bool - get_active () const; - - /** - * Set the activity status of the chroot. - * - * @param active true if active, false if inactive - */ - void - set_active (bool active); - - /** - * Check if chroot setup scripts will be run. - * - * @returns true if setup scripts will be run, otherwise false. - */ - bool - get_run_setup_scripts () const; - - /** - * Set whether chroot setup scripts will be run. - * - * @param run_setup_scripts true if setup scripts will be run, - * otherwise false. - */ - void - set_run_setup_scripts (bool run_setup_scripts); - - /** - * Check if chroot exec scripts will be run. - * - * @returns true if exec scripts will be run, otherwise false. - */ - bool - get_run_exec_scripts () const; - - /** - * Set whether chroot exec scripts will be run. - * - * @param run_exec_scripts true if exec scripts will be run, - * otherwise false. - */ - void - set_run_exec_scripts (bool run_exec_scripts); - - /** - * Get the command_prefix for the chroot. This is a command to - * prefix to any command run in the chroot. - * - * @returns the command prefix. - */ - string_list const& - get_command_prefix () const; - - /** - * Set the command_prefix for the chroot. This is a command to - * prefix to any command run in the chroot. - * - * @param command_prefix the command prefix. - */ - void - set_command_prefix (string_list const& command_prefix); - - /** - * Get the process execution domain for the chroot. - * - * @returns the command prefix. - */ - personality const& - get_persona () const; - - /** - * Set the process execution domain for the chroot. - * - * @param persona the command prefix. - */ - void - set_persona (personality const& persona); - - /** - * Get the type of the chroot. - * - * @returns the chroot type. - */ - virtual std::string const& - get_chroot_type () const = 0; - - /** - * Set environment. Set the environment that the setup scripts - * will see during execution. - * - * @param env the environment to set. - */ - virtual void - setup_env (environment& env); - - /** - * Lock a chroot during setup. The locking technique (if any) may - * vary depending upon the chroot type and setup stage. For - * example, during creation of an LVM snapshot a block device - * might require locking, but afterwards this will change to the - * new block device. - * - * An error will be thrown on failure. - * - * @param type the type of setup being performed - */ - void - lock (setup_type type); - - /** - * Unlock a chroot during setup. The locking technique (if any) may - * vary depending upon the chroot type and setup stage. For - * example, during creation of an LVM snapshot a block device - * might require locking, but afterwards this will change to the - * new block device. - * - * An error will be thrown on failure. - * - * @param type the type of setup being performed - * @param status the exit status of the setup commands (0 for - * success, nonzero for failure). - */ - void - unlock (setup_type type, - int status); - - protected: - /** - * Set up persistent session information. - * - * @param start true if startion, or false if ending a session. - */ - virtual void - setup_session_info (bool start); - - /** - * Unlock a chroot during setup. The locking technique (if any) may - * vary depending upon the chroot type and setup stage. For - * example, during creation of an LVM snapshot a block device - * might require locking, but afterwards this will change to the - * new block device. - * - * An error will be thrown on failure. - * - * @param type the type of setup being performed - * @param lock true to lock, false to unlock - * @param status the exit status of the setup commands (0 for - * success, nonzero for failure). - */ - virtual void - setup_lock(setup_type type, - bool lock, - int status) = 0; - - public: - /** - * Get the session flags of the chroot. These determine how the - * Session controlling the chroot will operate. - * - * @returns the session flags. - */ - virtual session_flags - get_session_flags () const = 0; - - /** - * Print detailed information about the chroot to a stream. The - * information is printed in plain text with one line per - * property. - * - * @param stream the stream to output to. - * @param rhs the chroot to output. - * @returns the stream. - */ - friend std::ostream& - operator << (std::ostream& stream, - ptr const& rhs) - { - rhs->print_details(stream); - return stream; - } - - /** - * Chroot initialisation from a keyfile. - */ - friend - keyfile const& - operator >> (keyfile const& keyfile, - ptr& rhs) - { - rhs->set_keyfile(keyfile); - return keyfile; - } - - /** - * Chroot serialisation to a keyfile. - */ - friend - keyfile& - operator << (keyfile& keyfile, - ptr const& rhs) - { - rhs->get_keyfile(keyfile); - return keyfile; - } - - - protected: - /** - * Print detailed information about the chroot to a stream. The - * information is printed in plain text with one line per - * property. - * - * @param stream the stream to output to. - */ - virtual void - print_details (std::ostream& stream) const; - - /** - * Copy the chroot properties into a keyfile. The keyfile group - * with the name of the chroot will be set; if it already exists, - * it will be removed before setting it. - * - * @param keyfile the keyfile to use. - */ - virtual void - get_keyfile (keyfile& keyfile) const; - - /** - * Set the chroot properties from a keyfile. The chroot name must - * have previously been set, so that the correct keyfile group may - * be determined. - * - * @param keyfile the keyfile to get the properties from. - */ - virtual void - set_keyfile (keyfile const& keyfile); - - private: - /// Chroot name. - std::string name; - /// Chroot description. - std::string description; - /// Chroot prioroty. - unsigned int priority; - /// Users allowed to access the chroot. - string_list users; - /// Groups allowed to access the chroot. - string_list groups; - /// Users allowed to access the chroot as root. - string_list root_users; - /// Groups allowed to access the chroot as root. - string_list root_groups; - /// Alternative names for the chroot. - string_list aliases; - /// Location to mount chroot in the filesystem (if any). - std::string mount_location; - /// Location inside the mount location root. - std::string location; - /// Block device to mount (if any). - std::string mount_device; - /// Chroot activity status. - bool active; - /// Run chroot setup scripts? - bool run_setup_scripts; - /// Run chroot exec scripts? - bool run_exec_scripts; - /// Command prefix. - string_list command_prefix; - /// Process execution domain (Linux only). - personality persona; - }; - -} - -#endif /* SBUILD_CHROOT_H */ - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/sbuild-config.h.in b/schroot/sbuild-config.h.in deleted file mode 100644 index ff4de033..00000000 --- a/schroot/sbuild-config.h.in +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#ifndef SBUILD_CONFIG_H -#define SBUILD_CONFIG_H - -/* This header contains configuration macros which determine the - correct library to use. This depends upon the libraries found at - configure time. */ - -/* Define to 1 if you have the header file. */ -#undef HAVE_BOOST_FORMAT_HPP - -/* Define to 1 if you have the header file. */ -#undef HAVE_BOOST_PROGRAM_OPTIONS_HPP - -/* Define to 1 if you have the header file. */ -#undef HAVE_BOOST_SHARED_PTR_HPP - -/* Define to 1 if you have the header file. */ -#undef HAVE_BOOST_TUPLE_TUPLE_HPP - -/* Define to 1 if you have the header file. */ -#undef HAVE_TR1_MEMORY - -/* Define to 1 if you have the header file. */ -#undef HAVE_TR1_TUPLE - -#endif /* SBUILD_H */ - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/sbuild-custom-error.h b/schroot/sbuild-custom-error.h deleted file mode 100644 index a16566be..00000000 --- a/schroot/sbuild-custom-error.h +++ /dev/null @@ -1,239 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#ifndef SBUILD_CUSTOM_ERROR_H -#define SBUILD_CUSTOM_ERROR_H - -#include "sbuild-error.h" - -#include -#include - -#include - -namespace sbuild -{ - - /** - * Custom error. - */ - template - class custom_error : public runtime_error - { - public: - typedef T error_type; - typedef std::map map_type; - - /** - * The constructor. - * - * @param error the error code. - */ - custom_error (error_type error): - runtime_error(format_error(std::string(), error)) - { - } - - /** - * The constructor. - * - * @param detail the details of the error. - * @param error the error code. - */ - custom_error (std::string const& detail, - error_type error): - runtime_error(format_error(detail, error)) - { - } - - /** - * The constructor. - * - * @param detail the details of the error. - */ - custom_error (std::string const& detail): - runtime_error(detail) - { - } - - /** - * The constructor. - * - * @param error the error code. - * @param error_number the error number. - */ - custom_error (error_type error, - int error_number): - runtime_error(format_error(std::string(), error, error_number)) - { - } - - /** - * The constructor. - * - * @param detail the details of the error. - * @param error the error code. - * @param error_number the error number. - */ - custom_error (std::string const& detail, - error_type error, - int error_number): - runtime_error(format_error(detail, error, error_number)) - { - } - - /** - * The constructor. - * - * @param detail the details of the error. - * @param error_number the error number. - */ - custom_error (std::string const& detail, - int error_number): - runtime_error(format_error(detail, error_number)) - { - } - - /** - * The constructor. - * - * @param error the error code. - * @param error_string the error string. - */ - custom_error (error_type error, - std::string const& error_string): - runtime_error(format_error(std::string(), error, error_string)) - { - } - - /** - * The constructor. - * - * @param detail the details of the error. - * @param error the error code. - * @param error_string the error string. - */ - custom_error (std::string const& detail, - error_type error, - std::string const& error_string): - runtime_error(format_error(detail, error, error_string)) - { - } - - /** - * The constructor. - * - * @param detail the details of the error. - * @param error_string the error string. - */ - custom_error (std::string const& detail, - std::string const& error_string): - runtime_error(format_error(detail, error_string)) - { - } - - /// The destructor. - virtual ~custom_error () throw () - {} - - private: - /// Mapping between error code and string. - static map_type error_strings; - - /** - * Get a translated error string. - * - * @param error the error code. - * @returns a translated error string. - */ - static const char * - get_error (error_type error); - - /** - * Format an error message. - * - * @param error the error code. - * @param detail the details of the error. - * @returns a translated error message. - */ - static std::string - format_error (std::string const& detail, - error_type error); - - /** - * Format an error message. - * - * @param detail the details of the error. - * @param error the error code. - * @param error_number the error number. - * @returns a translated error message. - */ - static std::string - format_error (std::string const& detail, - error_type error, - int error_number); - - /** - * Format an error message. - * - * @param detail the details of the error. - * @param error_number the error number. - * @returns a translated error message. - */ - static std::string - format_error (std::string const& detail, - int error_number); - - /** - * Format an error message. - * - * @param detail the details of the error. - * @param error the error code. - * @param error_string the error string. - * @returns a translated error message. - */ - static std::string - format_error (std::string const& detail, - error_type error, - std::string const& error_string); - - /** - * Format an error message. - * - * @param detail the details of the error. - * @param error_string the error string. - * @returns a translated error message. - */ - static std::string - format_error (std::string const& detail, - std::string const& error_string); - }; - - -} - -#include "sbuild-custom-error.tcc" - -#endif /* SBUILD_CUSTOM_ERROR_H */ - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/sbuild-custom-error.tcc b/schroot/sbuild-custom-error.tcc deleted file mode 100644 index 37e5ba8b..00000000 --- a/schroot/sbuild-custom-error.tcc +++ /dev/null @@ -1,121 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#ifndef SBUILD_CUSTOM_ERROR_TCC -#define SBUILD_CUSTOM_ERROR_TCC - -#include "sbuild-i18n.h" -#include "sbuild-custom-error.h" - -#include - -template -const char * -sbuild::custom_error::get_error (error_type error) -{ - typename map_type::const_iterator pos = error_strings.find(error); - - if (pos != error_strings.end()) - return gettext(pos->second); - - // Untranslated: it's a programming error to get this message. - return "unknown error"; -} - -template -std::string -sbuild::custom_error::format_error (std::string const& detail, - error_type error) -{ - if (detail.length() > 0) - { - boost::format fmt("%1%: %2%"); - fmt % detail % get_error(error); - return fmt.str(); - } - else - return get_error(error); -} - -template -std::string -sbuild::custom_error::format_error (std::string const& detail, - error_type error, - int error_number) -{ - return format_error(detail, error, std::string(strerror(error_number))); -} - -template -std::string -sbuild::custom_error::format_error (std::string const& detail, - int error_number) -{ - return format_error(detail, std::string(strerror(error_number))); -} - -template -std::string -sbuild::custom_error::format_error (std::string const& detail, - std::string const& error_string) -{ - if (detail.length() > 0) - { - boost::format fmt("%1%: %2%"); - fmt % detail % error_string; - return fmt.str(); - } - else - { - boost::format fmt("%1%"); - fmt % error_string; - return fmt.str(); - } -} - -template -std::string -sbuild::custom_error::format_error (std::string const& detail, - error_type error, - std::string const& error_string) -{ - if (detail.length() > 0) - { - boost::format fmt("%1%: %2%: %3%"); - fmt % detail - % get_error(error) - % error_string; - return fmt.str(); - } - else - { - boost::format fmt("%1%: %2%"); - fmt % get_error(error) - % error_string; - return fmt.str(); - } -} - -#endif /* SBUILD_CUSTOM_ERROR_TCC */ - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/sbuild-environment.cc b/schroot/sbuild-environment.cc deleted file mode 100644 index ea51724a..00000000 --- a/schroot/sbuild-environment.cc +++ /dev/null @@ -1,153 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#include - -#include "sbuild-environment.h" - -using boost::format; -using namespace sbuild; - -environment::environment (): - std::map() -{ -} - -environment::environment (char **environment): - std::map() -{ - add(environment); -} - -environment::~environment () -{ -} - -void -environment::add (char **environment) -{ - if (environment) - { - for (char **ev = environment; ev != 0 && *ev != 0; ++ev) - add(std::string(*ev)); - } -} - -void -environment::add (environment const& environment) -{ - for (const_iterator pos = environment.begin(); - pos != environment.end(); - ++pos) - add(*pos); -} - -void -environment::add (std::string const& value) -{ - std::string::size_type pos = value.find('='); - if (pos != std::string::npos && pos != 0) - { - std::string key = value.substr(0, pos); - std::string val; - if (pos < value.length()) - val = value.substr(pos + 1); - add(std::make_pair(key, val)); - } - else - { - add(std::make_pair(value, std::string())); - } -} - -void -environment::add (value_type const& value) -{ - remove(value); - if (!value.second.empty()) - insert(value); -} - -void -environment::remove (char **environment) -{ - if (environment) - { - for (char **ev = environment; ev != 0 && *ev != 0; ++ev) - remove(std::string(*ev)); - } -} - -void -environment::remove (environment const& environment) -{ - for (const_iterator pos = environment.begin(); - pos != environment.end(); - ++pos) - remove(*pos); -} - -void -environment::remove (std::string const& value) -{ - std::string::size_type pos = value.find('='); - if (pos != std::string::npos && pos != 0) - { - std::string key = value.substr(0, pos); - std::string val; - if (pos < value.length()) - val = value.substr(pos + 1); - remove(std::make_pair(key, val)); - } - else - { - remove(std::make_pair(value, std::string())); - } -} - -void -environment::remove (value_type const& value) -{ - iterator pos = find(value.first); - if (pos != end()) - erase(pos); -} - -char ** -environment::get_strv () const -{ - char **ret = new char *[size() + 1]; - - size_type idx = 0; - for (const_iterator pos = begin(); pos != end(); ++pos, ++idx) - { - std::string envitem = pos->first + "=" + pos->second; - ret[idx] = new char[envitem.length() + 1]; - std::strcpy(ret[idx], envitem.c_str()); - } - ret[size()] = 0; - - return ret; -} - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/sbuild-environment.h b/schroot/sbuild-environment.h deleted file mode 100644 index 1e13e553..00000000 --- a/schroot/sbuild-environment.h +++ /dev/null @@ -1,301 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#ifndef SBUILD_ENVIRONMENT_H -#define SBUILD_ENVIRONMENT_H - -#include "sbuild-log.h" -#include "sbuild-parse-value.h" - -#include -#include -#include - -#include - -namespace sbuild -{ - - /** - * Container of environment variables. - */ - class environment : public std::map - { - public: - using std::map::value_type; - - /// The constructor. - environment (); - - /** - * The constructor. - * - * @param environment the environment to set. - */ - environment (char **environment); - - /// The destructor. - ~environment (); - - /** - * Add environment variables. Any existing variables sharing the - * name of a new value will be replaced. - * - * @param environment the environment variables to add. This is a - * null-terminated array of pointers to char. - */ - void - add (char **environment); - - /** - * Add environment variables. Any existing variables sharing the - * name of a new value will be replaced. - * - * @param environment the environment variables to add. - */ - void - add (environment const& environment); - - /** - * Add environment variable. Any existing variable sharing the - * name will be replaced. - * - * @param value the environment variable to add. - */ - void - add (value_type const& value); - - /** - * Add environment variable. Any existing variable sharing the - * name will be replaced. - * - * @param name the environment variable name - * @param value the environment variable value to add. - */ - void - add (std::string const& name, - std::string const& value) - { - add(std::make_pair(name, value)); - } - - /** - * Add environment variable. Any existing variable sharing the - * name will be replaced. - * - * @param name the environment variable name - * @param value the environment variable value to add. - */ - template - void - add (std::string const& name, - T const& value) - { - std::ostringstream varstring; - varstring.imbue(std::locale("C")); - varstring << std::boolalpha << value; - add(std::make_pair(name, varstring.str())); - } - - /** - * Add environment variable. Any existing variable sharing the - * name will be replaced. - * - * @param value the environment variable to add. This is a string - * in the form key=value. - */ - void - add (std::string const& value); - - /** - * Remove environment variables. Any variables sharing the names - * of a specified value will be removed. - * - * @param environment the environment variables to remove. This - * is a null-terminated array of pointers to char. - */ - void - remove (char **environment); - - /** - * Remove environment variables. Any variables sharing the names - * of a specified value will be removed. - * - * @param environment the environment variables to remove. - */ - void - remove (environment const& environment); - - /** - * Remove environment variable. Any variable sharing the name - * of the specified value will be removed. - * - * @param value the environment variable to remove. - */ - void - remove (std::string const& value); - - /** - * Remove environment variable. Any variable sharing the name - * of the specified value will be removed. - * - * @param value the environment variable to remove. - */ - void - remove (value_type const& value); - - /** - * Get the value of an environment variable. - * - * @param name the name of the environment variable. - * @param value the variable to store the value in on success. - * @returns true on success, false if the variable does not exist, - * or there is a parse error. - */ - template - bool - get (std::string const& name, - T& value) - { - log_debug(DEBUG_INFO) << "Getting environment variable=" << name - << std::endl; - iterator pos = find(name); - if (pos != end()) - { - try - { - value = static_cast(parse_value(pos->second)); - return true; - } - catch (parse_value::error const& e) - { - log_warning() << boost::format("%1%: %2%\n") - % name % e.what(); - return false; - } - } - log_debug(DEBUG_NOTICE) << "name not found: " << name << std::endl; - return false; - } - - /** - * Get the evironment variables as a string vector. This form is - * suitable for use as an envp argument with execve, for example. - * - * @returns a newly-allocated string vector. This is allocated - * with new, and should be freed with strv_delete(). - */ - char ** - get_strv () const; - - /** - * Add variables to the environment. - * - * @param rhs the values to add. - * @returns the modified environment. - */ - template - environment& - operator += (T& rhs) - { - add(rhs); - return *this; - } - - /** - * Remove variables from the environment. - * - * @param rhs the values to remove. - * @returns the modified environment. - */ - template - environment& - operator -= (T& rhs) - { - remove(rhs); - return *this; - } - - /** - * Add variables to the environment. - * - * @param lhs the environment to add to. - * @param rhs the values to add. - * @returns the new environment. - */ - template - friend environment - operator + (environment const& lhs, - T const& rhs) - { - environment ret(lhs); - ret += rhs; - return ret; - } - - /** - * Remove variables from the environment. - * - * @param lhs the environment to remove from. - * @param rhs the values to remove. - * @returns the new environment. - */ - template - friend environment - operator - (environment const& lhs, - T const& rhs) - { - environment ret(lhs); - ret -= rhs; - return ret; - } - - /** - * Output the environment to an ostream. - * - * @param stream the stream to output to. - * @param rhs the environment to output. - * @returns the stream. - */ - template - friend - std::basic_ostream& - operator << (std::basic_ostream& stream, - environment const& rhs) - { - for (environment::const_iterator pos = rhs.begin(); - pos != rhs.end(); - ++pos) - { - stream << pos->first << '=' << pos->second << '\n'; - } - - return stream; - } - }; - -} - -#endif /* SBUILD_ENVIRONMENT_H */ - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/sbuild-error.h b/schroot/sbuild-error.h deleted file mode 100644 index a8609c03..00000000 --- a/schroot/sbuild-error.h +++ /dev/null @@ -1,58 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#ifndef SBUILD_ERROR_H -#define SBUILD_ERROR_H - -#include - -#include - -namespace sbuild -{ - - /** - * Generic runtime error. - */ - class runtime_error : public std::runtime_error - { - public: - /** - * The constructor. - * - * @param error the error message. - */ - runtime_error (std::string const& error): - std::runtime_error(error) - {} - - /// The destructor. - virtual ~runtime_error () throw () - {} - }; - -} - -#endif /* SBUILD_ERROR_H */ - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/sbuild-format-detail.cc b/schroot/sbuild-format-detail.cc deleted file mode 100644 index 7f186087..00000000 --- a/schroot/sbuild-format-detail.cc +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#include - -#include "sbuild-format-detail.h" -#include "sbuild-i18n.h" - -using namespace sbuild; - -template<> -std::ostream& -sbuild::operator << (std::ostream& stream, - format_detail const& rhs) -{ - const char *desc = 0; - if (rhs.value) - desc = _("true"); - else - desc = _("false"); - return stream << format_detail(rhs.name, desc); -} diff --git a/schroot/sbuild-format-detail.h b/schroot/sbuild-format-detail.h deleted file mode 100644 index 6ce89f7a..00000000 --- a/schroot/sbuild-format-detail.h +++ /dev/null @@ -1,149 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#ifndef SBUILD_FORMAT_DETAIL_H -#define SBUILD_FORMAT_DETAIL_H - -#include "sbuild-config.h" -#include "sbuild-types.h" -#include "sbuild-util.h" - -#include -#include -#include - -namespace sbuild -{ - - /** - * Format names and values for output. - */ - template - class format_detail; - - /** - * Output the formatted detail to an ostream. - * - * @param stream the stream to output to. - * @param rhs the formatted detail to output. - * @returns the stream. - */ - template std::ostream& - operator << (std::ostream& stream, - format_detail const& rhs); - - /** - * Output the formatted detail to an ostream. This is a special - * case for boolean values. - * - * @param stream the stream to output to. - * @param rhs the formatted detail to output. - * @returns the stream. - */ - template<> std::ostream& - operator << (std::ostream& stream, - format_detail const& rhs); - - /** - * Output the formatted detail to an ostream. This is a special - * case for string_list values. - * - * @param stream the stream to output to. - * @param rhs the formatted detail to output. - * @returns the stream. - */ - template<> std::ostream& - operator << (std::ostream& stream, - format_detail const& rhs); - - /** - * Helper to perform formatting of chroot details. - */ - template - class format_detail - { - /** - * The constructor. - * - * @param name the name of the property to format. - * @param value the value of the property to format. The value - * type must support output to an ostream. - */ - public: - format_detail (std::string const& name, - T const& value): - name(name), - value(value) - {} - - friend std::ostream& - operator << <>(std::ostream&, format_detail const&); - - private: - /// The name of the property. - std::string const& name; - /// The value of the property. - T const& value; - }; - - template - inline std::ostream& - operator << (std::ostream& stream, - format_detail const& rhs) - { - return stream << " " - << std::setw(21) << std::left << rhs.name - << ' ' << rhs.value << '\n'; - } - - template<> - inline std::ostream& - operator << (std::ostream& stream, - format_detail const& rhs) - { - return stream << - format_detail(rhs.name, - string_list_to_string(rhs.value, " ")); - } - - /** - * Format a name-value pair for output. This is a convenience - * wrapper to construct a format_detail of the appropriate type. - * - * @param name the name to output. - * @param value the value to output. - * @returns a format_detail of the appropriate type. - */ - template - inline format_detail - format_details (std::string const& name, - T const& value) - { - return format_detail(name, value); - } - -} - -#endif /* SBUILD_FORMAT_DETAIL_H */ - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/sbuild-i18n.h b/schroot/sbuild-i18n.h deleted file mode 100644 index 3bed0ffb..00000000 --- a/schroot/sbuild-i18n.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#ifndef SBUILD_I18N_H -#define SBUILD_I18N_H - -#include - -#define _(String) gettext (String) -#ifdef gettext_noop -#define N_(String) gettext_noop (String) -#else -#define N_(String) (String) -#endif - -#endif /* SBUILD_I18N_H */ - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/sbuild-keyfile.cc b/schroot/sbuild-keyfile.cc deleted file mode 100644 index f1e7a9db..00000000 --- a/schroot/sbuild-keyfile.cc +++ /dev/null @@ -1,385 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#include - -#include "sbuild-keyfile.h" - -#include - -#include - -using boost::format; -using namespace sbuild; - -keyfile::keyfile (): - groups(), - separator(',') -{ -} - -keyfile::keyfile (std::string const& file): - groups(), - separator(',') -{ - std::ifstream fs(file.c_str()); - if (fs) - { - fs.imbue(std::locale("C")); - fs >> *this; - } - else - { - throw error(parse_error::BAD_FILE, file); - } -} - -keyfile::keyfile (std::istream& stream): - groups(), - separator(',') -{ - stream >> *this; -} - -keyfile::~keyfile() -{ -} - -string_list -keyfile::get_groups () const -{ - string_list ret; - - for (group_map_type::const_iterator pos = this->groups.begin(); - pos != this->groups.end(); - ++pos) - ret.push_back(pos->first); - - return ret; -} - -string_list -keyfile::get_keys (std::string const& group) const -{ - string_list ret; - - const group_type *found_group = find_group(group); - if (found_group) - { - item_map_type const& items(std::tr1::get<1>(*found_group)); - for (item_map_type::const_iterator pos = items.begin(); - pos != items.end(); - ++pos) - ret.push_back(pos->first); - } - - return ret; -} - -bool -keyfile::has_group (std::string const& group) const -{ - return (find_group(group) != 0); -} - -bool -keyfile::has_key (std::string const& group, - std::string const& key) const -{ - return (find_item(group, key) != 0); -} - -void -keyfile::set_group (std::string const& group, - std::string const& comment) -{ - if (!has_group(group)) - this->groups.insert - (group_map_type::value_type(group, - group_type(group, - item_map_type(), - comment))); -} - -std::string -keyfile::get_comment (std::string const& group) const -{ - const keyfile::group_type *found_group = find_group(group); - if (found_group) - return std::tr1::get<2>(*found_group); - else - return std::string(); -} - -std::string -keyfile::get_comment (std::string const& group, - std::string const& key) const -{ - const item_type *found_item = find_item(group, key); - if (found_item) - return std::tr1::get<2>(*found_item); - else - return std::string(); -} - -bool -keyfile::get_locale_string (std::string const& group, - std::string const& key, - std::string& value) const -{ - std::string localename = std::locale("").name(); - std::string::size_type pos; - bool status = false; - - // Strip off any charset. - if ((pos = localename.find_first_of('.')) != std::string::npos) - localename = localename.substr(0, pos); - status = get_locale_string(group, key, localename, value); - - // Strip off territory. - if (status == false && - (pos = localename.find_first_of('_')) != std::string::npos) - { - localename = localename.substr(0, pos); - status = get_locale_string(group, key, localename, value); - } - - // Fall back to non-localised version. - if (status == false) - status = get_value(group, key, value); - - return status; -} - -bool -keyfile::get_locale_string (std::string const& group, - std::string const& key, - priority priority, - std::string& value) const -{ - bool status = get_locale_string(group, key, value); - check_priority(group, key, priority, status); - return status; -} - -bool -keyfile::get_locale_string (std::string const& group, - std::string const& key, - std::string const& locale, - std::string& value) const -{ - std::string lkey = key + '[' + locale + ']'; - return get_value(group, lkey, value); -} - -bool -keyfile::get_locale_string (std::string const& group, - std::string const& key, - std::string const& locale, - priority priority, - std::string& value) const -{ - bool status = get_locale_string(group, key, locale, value); - check_priority(group, key, priority, status); - return status; -} - -void -keyfile::remove_group (std::string const& group) -{ - group_map_type::iterator pos = this->groups.find(group); - if (pos != this->groups.end()) - this->groups.erase(pos); -} - -void -keyfile::remove_key (std::string const& group, - std::string const& key) -{ - group_type *found_group = find_group(group); - if (found_group) - { - item_map_type& items = std::tr1::get<1>(*found_group); - item_map_type::iterator pos = items.find(key); - if (pos != items.end()) - items.erase(pos); - } -} - -keyfile& -keyfile::operator += (keyfile const& rhs) -{ - for (group_map_type::const_iterator gp = rhs.groups.begin(); - gp != rhs.groups.end(); - ++gp) - { - group_type const& group = gp->second; - std::string const& groupname = std::tr1::get<0>(group); - std::string const& comment = std::tr1::get<2>(group); - set_group(groupname, comment); - - item_map_type const& items(std::tr1::get<1>(group)); - for (item_map_type::const_iterator it = items.begin(); - it != items.end(); - ++it) - { - item_type const& item = it->second; - std::string const& key(std::tr1::get<0>(item)); - std::string const& value(std::tr1::get<1>(item)); - std::string const& comment(std::tr1::get<2>(item)); - set_value(groupname, key, value, comment); - } - } - return *this; -} - -keyfile -operator + (keyfile const& lhs, - keyfile const& rhs) -{ - keyfile ret(lhs); - ret += rhs; - return ret; -} - -const keyfile::group_type * -keyfile::find_group (std::string const& group) const -{ - group_map_type::const_iterator pos = this->groups.find(group); - if (pos != this->groups.end()) - return &pos->second; - - return 0; -} - -keyfile::group_type * -keyfile::find_group (std::string const& group) -{ - group_map_type::iterator pos = this->groups.find(group); - if (pos != this->groups.end()) - return &pos->second; - - return 0; -} - -const keyfile::item_type * -keyfile::find_item (std::string const& group, - std::string const& key) const -{ - const group_type *found_group = find_group(group); - if (found_group) - { - item_map_type const& items = std::tr1::get<1>(*found_group); - item_map_type::const_iterator pos = items.find(key); - if (pos != items.end()) - return &pos->second; - } - - return 0; -} - -keyfile::item_type * -keyfile::find_item (std::string const& group, - std::string const& key) -{ - group_type *found_group = find_group(group); - if (found_group) - { - item_map_type& items = std::tr1::get<1>(*found_group); - item_map_type::iterator pos = items.find(key); - if (pos != items.end()) - return &pos->second; - } - - return 0; -} - -void -keyfile::print_comment (std::string const& comment, - std::ostream& stream) -{ - std::string::size_type last_pos = 0; - std::string::size_type pos = comment.find_first_of('\n', last_pos); - - while (1) - { - if (last_pos == pos) - stream << "#\n"; - else - stream << '#' << comment.substr(last_pos, pos - last_pos) << '\n'; - - // Find next - if (pos < comment.length() - 1) - { - last_pos = pos + 1; - pos = comment.find_first_of('\n', last_pos); - } - else - break; - } -} - -void -keyfile::check_priority (std::string const& group, - std::string const& key, - priority priority, - bool valid) const -{ - if (valid == false) - { - switch (priority) - { - case PRIORITY_REQUIRED: - { - throw error(group, parse_error::MISSING_KEY, key); - } - break; - default: - break; - } - } - else - { - switch (priority) - { - case PRIORITY_DEPRECATED: - log_warning() - << format(_("%1% chroot: A deprecated parameter \"%2%\" has been specified.")) - % group % key - << std::endl; - log_info() - << _("This option will be removed in the future.") << std::endl; - break; - case PRIORITY_OBSOLETE: - log_warning() - << format(_("%1% chroot: An obsolete parameter \"%2%\" has been specified.")) - % group % key - << std::endl; - log_info() - << _("This option has been removed, and no longer has any effect.") << std::endl; - case PRIORITY_DISALLOWED: - { - throw error(group, parse_error::DISALLOWED_KEY, key); - } - break; - default: - break; - } - } -} diff --git a/schroot/sbuild-keyfile.h b/schroot/sbuild-keyfile.h deleted file mode 100644 index d94577ba..00000000 --- a/schroot/sbuild-keyfile.h +++ /dev/null @@ -1,736 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#ifndef SBUILD_KEYFILE_H -#define SBUILD_KEYFILE_H - -#include "sbuild-config.h" -#include "sbuild-error.h" -#include "sbuild-i18n.h" -#include "sbuild-log.h" -#include "sbuild-parse-error.h" -#include "sbuild-parse-value.h" -#include "sbuild-types.h" -#include "sbuild-util.h" - -#include -#include -#include -#include -#include - -#ifdef HAVE_TR1_TUPLE -#include -#elif HAVE_BOOST_TUPLE_TUPLE_HPP -#include -namespace std { namespace tr1 { using boost::tuple; using boost::get; } } -#else -#error A shared_ptr implementation is not available -#endif - -#include - -namespace sbuild -{ - - /** - * Configuration file parser. This class loads an INI-style - * configuration file from a file or stream. The format is - * documented in schroot.conf(5). It is based upon the Glib - * GKeyFile class, which it is intended to replace. - */ - class keyfile - { - private: - /// Key-value-comment tuple. - typedef std::tr1::tuple item_type; - - /// Map between key name and key-value-comment tuple. - typedef std::map item_map_type; - - /// Group-items-comment tuple. - typedef std::tr1::tuple group_type; - - /// Map between group name and group-items-comment tuple. - typedef std::map group_map_type; - - public: - /// Configuration parameter priority. - enum priority - { - PRIORITY_OPTIONAL, ///< The parameter is optional. - PRIORITY_REQUIRED, ///< The parameter is required. - PRIORITY_DISALLOWED, ///< The parameter is not allowed in this context. - PRIORITY_DEPRECATED, ///< The parameter is deprecated, but functional. - PRIORITY_OBSOLETE ///< The parameter is obsolete, and not functional. - }; - - /// Exception type. - typedef parse_error error; - - /// The constructor. - keyfile (); - - /** - * The constructor. - * - * @param file the file to load the configuration from. - */ - keyfile (std::string const& file); - - /** - * The constructor. - * - * @param stream the stream to load the configuration from. - */ - keyfile (std::istream& stream); - - /// The destructor. - virtual ~keyfile (); - - /** - * Get a list of groups. - * - * @returns a list of groups in the keyfile. If no groups exist, - * the list will be empty. - */ - string_list - get_groups () const; - - /** - * Get a list of keys in a group. - * - * @param group the group to use. - * @returns a list of keys in a group. If no keys exist in the - * group, or the group does not exist, the list will be empty. - */ - string_list - get_keys (std::string const& group) const; - - /** - * Check if a group exists. - * - * @param group the group to check for. - * @returns true if the group exists, otherwise false. - */ - bool - has_group (std::string const& group) const; - - /** - * Check if a key exists. - * - * @param group the group the key is in. - * @param key the key to check for. - * @returns true if the key exists, otherwise false. - */ - bool - has_key (std::string const& group, - std::string const& key) const; - - /** - * Set a group. The group will be created (and the comment set) - * only if the group does not already exist. - * - * @param group the group to set. - * @param comment the comment to set. - */ - void - set_group (std::string const& group, - std::string const& comment); - - /** - * Get a group comment. - * - * @param group the group to find. - * @returns the comment. - */ - std::string - get_comment (std::string const& group) const; - - /** - * Get a key comment. - * - * @param group the group to find. - * @param key the key to find. - * @returns the comment. - */ - std::string - get_comment (std::string const& group, - std::string const& key) const; - - /** - * Get a key value. - * - * @param group the group the key is in. - * @param key the key to get. - * @param value the value to store the key's value in. This must - * be settable from an istream and be copyable. - * @returns true if the key was found, otherwise false (in which - * case value will be unchanged). - */ - template - bool - get_value (std::string const& group, - std::string const& key, - T& value) const - { - log_debug(DEBUG_INFO) << "Getting keyfile group=" << group - << ", key=" << key << std::endl; - const item_type *found_item = find_item(group, key); - if (found_item) - { - std::string const& strval(std::tr1::get<1>(*found_item)); - try - { - value = static_cast(parse_value(strval)); - return true; - } - catch (parse_value::error const& e) - { - error ep(group, key, parse_error::NONE, e.what()); - log_warning() << ep.what() << std::endl; - return false; - } - } - log_debug(DEBUG_NOTICE) << "key not found" << std::endl; - return false; - } - - /** - * Get a key value. If the value does not exist, is deprecated or - * obsolete, warn appropriately. - * - * @param group the group the key is in. - * @param key the key to get. - * @param priority the priority of the option. - * @param value the value to store the key's value in. This must - * be settable from an istream and be copyable. - * @returns true if the key was found, otherwise false (in which - * case value will be unchanged). - */ - template - bool - get_value (std::string const& group, - std::string const& key, - priority priority, - T& value) const - { - bool status = get_value(group, key, value); - check_priority(group, key, priority, status); - return status; - } - - /** - * Get a localised key string value. - * - * @param group the group the key is in. - * @param key the key to get. - * @param value the string to store the key's localised value in. - * @returns true if the key was found, otherwise false (in which - * case value will be unchanged). - */ - bool - get_locale_string (std::string const& group, - std::string const& key, - std::string& value) const; - - /** - * Get a localised key string value. If the value does not exist, - * is deprecated or obsolete, warn appropriately. - * - * @param group the group the key is in. - * @param key the key to get. - * @param priority the priority of the option. - * @param value the string to store the key's localised value in. - * @returns true if the key was found, otherwise false (in which - * case value will be unchanged). - */ - bool - get_locale_string (std::string const& group, - std::string const& key, - priority priority, - std::string& value) const; - - /** - * Get a localised key string value for a specific locale. - * - * @param group the group the key is in. - * @param key the key to get. - * @param locale the locale to use. - * @param value the string to store the key's localised value in. - * @returns true if the key was found, otherwise false (in which - * case value will be unchanged). - */ - bool - get_locale_string (std::string const& group, - std::string const& key, - std::string const& locale, - std::string& value) const; - - /** - * Get a localised key string value for a specific locale. If the - * value does not exist, is deprecated or obsolete, warn - * appropriately. - * - * @param group the group the key is in. - * @param key the key to get. - * @param locale the locale to use. - * @param priority the priority of the option. - * @param value the string to store the key's localised value in. - * @returns true if the key was found, otherwise false (in which - * case value will be unchanged). - */ - bool - get_locale_string (std::string const& group, - std::string const& key, - std::string const& locale, - priority priority, - std::string& value) const; - - /** - * Get a key value as a list. - * - * @param group the group the key is in. - * @param key the key to get. - * @param container the container to store the key's value in. - * The value type must be settable from an istream and be - * copyable. The list must be a container with a standard insert - * method. - * @returns true if the key was found, otherwise false (in which - * case value will be undefined). - */ - template - bool - get_list_value (std::string const& group, - std::string const& key, - C& container) const - { - std::string item_value; - if (get_value(group, key, item_value)) - { - string_list items = split_string(item_value, - std::string(1, this->separator)); - for (string_list::const_iterator pos = items.begin(); - pos != items.end(); - ++pos - ) - { - container.push_back(static_cast(parse_value(*pos))); - } - return true; - } - return false; - } - - /** - * Get a key value as a list. If the value does not exist, is - * deprecated or obsolete, warn appropriately. - * - * @param group the group the key is in. - * @param key the key to get. - * @param priority the priority of the option. - * @param container the container to store the key's value in. - * The value type must be settable from an istream and be - * copyable. The list must be a container with a standard insert - * method. - * @returns true if the key was found, otherwise false (in which - * case value will be undefined). - */ - template - bool - get_list_value (std::string const& group, - std::string const& key, - priority priority, - C& container) const - { - bool status = get_list_value(group, key, container); - check_priority(group, key, priority, status); - return status; - } - - /** - * Set a key value. - * - * @param group the group the key is in. - * @param key the key to set. - * @param value the value to get the key's value from. This must - * allow output to an ostream. - */ - template - void - set_value (std::string const& group, - std::string const& key, - T const& value) - { - set_value(group, key, value, std::string()); - } - - /** - * Set a key value. - * - * @param group the group the key is in. - * @param key the key to set. - * @param value the value to get the key's value from. This must - * @param comment the comment for this key. - * allow output to an ostream. - */ - template - void - set_value (std::string const& group, - std::string const& key, - T const& value, - std::string const& comment) - { - std::ostringstream os; - os.imbue(std::locale("C")); - os << std::boolalpha << value; - - set_group(group, ""); - group_type *found_group = find_group(group); - assert (found_group != 0); // should not fail - - item_map_type& items = std::tr1::get<1>(*found_group); - - item_map_type::iterator pos = items.find(key); - if (pos != items.end()) - items.erase(pos); - - items.insert - (item_map_type::value_type(key, - item_type(key, os.str(), comment))); - } - - /** - * Set a key value from a list. - * - * @param group the group the key is in. - * @param key the key to set. - * @param begin an iterator referring to the start of the - * list. The value type must allow output to an ostream. - * @param end an iterator referring to the end of the list. - */ - template - void - set_list_value (std::string const& group, - std::string const& key, - I begin, - I end) - { - set_list_value(group, key, begin, end, std::string()); - } - - /** - * Set a key value from a list. - * - * @param group the group the key is in. - * @param key the key to set. - * @param begin an iterator referring to the start of the - * list. The value type must allow output to an ostream. - * @param end an iterator referring to the end of the list. - * @param comment the comment for this key. - */ - template - void - set_list_value (std::string const& group, - std::string const& key, - I begin, - I end, - std::string const& comment) - { - std::string strval; - - for (I pos = begin; pos != end; ++ pos) - { - std::ostringstream os; - os.imbue(std::locale("C")); - os << std::boolalpha << *pos; - if (os) - { - strval += os.str(); - if (pos + 1 != end) - strval += this->separator; - } - } - - set_value (group, key, strval, comment); - } - - /** - * Remove a group. - * - * @param group the group to remove. - */ - void - remove_group (std::string const& group); - - /** - * Remove a key. - * - * @param group the group the key is in. - * @param key the key to remove. - */ - void - remove_key (std::string const& group, - std::string const& key); - - /** - * Add a keyfile to the keyfile. - * - * @param rhs the keyfile to add. - * @returns the modified keyfile. - */ - keyfile& - operator += (keyfile const& rhs); - - /** - * Add a keyfile to the keyfile. - * - * @param lhs the keyfile to add to. - * @param rhs the values to add. - * @returns the new keyfile. - */ - friend keyfile - operator + (keyfile const& lhs, - keyfile const& rhs); - - /** - * keyfile initialisation from an istream. - */ - template - friend - std::basic_istream& - operator >> (std::basic_istream& stream, - keyfile& kf) - { - keyfile tmp; - size_t linecount = 0; - std::string line; - std::string group; - std::string comment; - std::string key; - std::string value; - - while (std::getline(stream, line)) - { - linecount++; - - if (line.length() == 0) - { - // Empty line; do nothing. - } - else if (line[0] == '#') // Comment line - { - if (!comment.empty()) - comment += '\n'; - comment += line.substr(1); - } - else if (line[0] == '[') // Group - { - std::string::size_type fpos = line.find_first_of(']'); - std::string::size_type lpos = line.find_last_of(']'); - if (fpos == std::string::npos || lpos == std::string::npos || - fpos != lpos) - { - throw error(linecount, parse_error::INVALID_GROUP, line); - } - group = line.substr(1, fpos - 1); - - if (group.length() == 0) - { - throw error(linecount, parse_error::INVALID_GROUP, line); - } - - // Insert group - if (tmp.has_group(group)) - { - error e(linecount, parse_error::DUPLICATE_GROUP, group); - log_warning() << e.what() << std::endl; - } - else - tmp.set_group(group, comment); - comment.clear(); - } - else // Item - { - std::string::size_type pos = line.find_first_of('='); - if (pos == std::string::npos) - { - throw error(linecount, parse_error::INVALID_LINE, line); - } - if (pos == 0) - { - throw error(linecount, parse_error::NO_KEY, line); - } - key = line.substr(0, pos); - if (pos == line.length() - 1) - value = ""; - else - value = line.substr(pos + 1); - - // No group specified - if (group.empty()) - { - throw error(linecount, parse_error::NO_GROUP, line); - } - - // Insert item - if (tmp.has_key(group, key)) - { - error e(linecount, group, parse_error::DUPLICATE_KEY, key); - log_warning() << e.what() << std::endl; - } - else - tmp.set_value(group, key, value, comment); - comment.clear(); - } - } - - kf += tmp; - - return stream; - } - - /** - * keyfile output to an ostream. - */ - template - friend - std::basic_ostream& - operator << (std::basic_ostream& stream, - keyfile const& kf) - { - unsigned int group_count = 0; - - for (group_map_type::const_iterator gp = kf.groups.begin(); - gp != kf.groups.end(); - ++gp, ++group_count) - { - if (group_count > 0) - stream << '\n'; - - group_type const& group = gp->second; - std::string const& groupname = std::tr1::get<0>(group); - std::string const& comment = std::tr1::get<2>(group); - - if (comment.length() > 0) - print_comment(comment, stream); - - stream << '[' << groupname << ']' << '\n'; - - item_map_type const& items(std::tr1::get<1>(group)); - for (item_map_type::const_iterator it = items.begin(); - it != items.end(); - ++it) - { - item_type const& item = it->second; - std::string const& key(std::tr1::get<0>(item)); - std::string const& value(std::tr1::get<1>(item)); - std::string const& comment(std::tr1::get<2>(item)); - - if (comment.length() > 0) - print_comment(comment, stream); - - stream << key << '=' << value << '\n'; - } - } - - return stream; - } - - private: - /** - * Find a group by it's name. - * - * @param group the group to find. - * @returns the group, or 0 if not found. - */ - const group_type * - find_group (std::string const& group) const; - - /** - * Find a group by it's name. - * - * @param group the group to find. - * @returns the group, or 0 if not found. - */ - group_type * - find_group (std::string const& group); - - /** - * Find a key by it's group and name. - * - * @param group the group the key is in. - * @param key the key to find - * @returns the key, or 0 if not found. - */ - const item_type * - find_item (std::string const& group, - std::string const& key) const; - - /** - * Find a key by it's group and name. - * - * @param group the group the key is in. - * @param key the key to find - * @returns the key, or 0 if not found. - */ - item_type * - find_item (std::string const& group, - std::string const& key); - - /** - * Check if a key is missing or present when not permitted. - * - * @param group the group the key is in. - * @param key the key to get. - * @param priority the key priority. - * @param valid true if key exists, false if not existing. - */ - void - check_priority (std::string const& group, - std::string const& key, - priority priority, - bool valid) const; - - /** - * Print a comment to a stream. The comment will have hash ('#') - * marks printed at the start of each line. - * - * @param comment the comment to print. - * @param stream the stream to output to. - */ - static void - print_comment (std::string const& comment, - std::ostream& stream); - - /// The top-level groups. - group_map_type groups; - /// The separator used as a list item delimiter. - char separator; - }; - -} - -#endif /* SBUILD_KEYFILE_H */ - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/sbuild-lock.cc b/schroot/sbuild-lock.cc deleted file mode 100644 index aa0bba84..00000000 --- a/schroot/sbuild-lock.cc +++ /dev/null @@ -1,300 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#include - -#include "sbuild-lock.h" - -#include -#include - -#include -#include -#include - -#include - -#include - -using boost::format; -using namespace sbuild; - -namespace -{ - - typedef std::pair emap; - - /** - * This is a list of the supported error codes. It's used to - * construct the real error codes map. - */ - emap init_errors[] = - { - emap(lock::TIMEOUT_HANDLER, N_("Failed to set timeout handler")), - emap(lock::TIMEOUT_SET, N_("Failed to set timeout")), - emap(lock::TIMEOUT_CANCEL, N_("Failed to cancel timeout")), - emap(lock::LOCK, N_("Failed to acquire lock (timed out)")), - emap(lock::LOCK_TIMEOUT, N_("Failed to acquire lock")), - emap(lock::DEVICE_LOCK, N_("Failed to acquire device lock")), - emap(lock::DEVICE_LOCK_TIMEOUT, N_("Failed to acquire device lock (timed out)")), - emap(lock::DEVICE_TEST, N_("Failed to test device lock")), - emap(lock::DEVICE_RELEASE, N_("Failed to release device lock")), - emap(lock::DEVICE_RELEASE_TIMEOUT, N_("Failed to release device lock (timed out)")) - }; - -} - -template<> -custom_error::map_type -custom_error::error_strings -(init_errors, - init_errors + (sizeof(init_errors) / sizeof(init_errors[0]))); - -namespace -{ - - volatile bool lock_timeout = false; - - /** - * Handle the SIGALRM signal. - * - * @param ignore the signal number. - */ - void - alarm_handler (int ignore) - { - /* This exists so that system calls get interrupted. */ - /* lock_timeout is used for polling for a timeout, rather than - interruption. */ - lock_timeout = true; - } -} - -lock::lock (): - saved_signals() -{ -} - -lock::~lock () -{ -} - -void -lock::set_alarm () -{ - struct sigaction new_sa; - sigemptyset(&new_sa.sa_mask); - new_sa.sa_flags = 0; - new_sa.sa_handler = alarm_handler; - - if (sigaction(SIGALRM, &new_sa, &this->saved_signals) != 0) - throw error(TIMEOUT_HANDLER, errno); -} - -void -lock::clear_alarm () -{ - /* Restore original handler */ - sigaction (SIGALRM, &this->saved_signals, NULL); -} - -void -lock::set_timer(struct itimerval const& timer) -{ - set_alarm(); - - if (setitimer(ITIMER_REAL, &timer, NULL) == -1) - { - clear_alarm(); - throw error(TIMEOUT_SET, errno); - } -} - -void -lock::unset_timer () -{ - struct itimerval disable_timer; - disable_timer.it_interval.tv_sec = disable_timer.it_interval.tv_usec = 0; - disable_timer.it_value.tv_sec = disable_timer.it_value.tv_usec = 0; - - if (setitimer(ITIMER_REAL, &disable_timer, NULL) == -1) - { - clear_alarm(); - throw error(TIMEOUT_CANCEL, errno); - } - - clear_alarm(); -} - -file_lock::file_lock (int fd): - lock(), - fd(fd) -{ -} - -file_lock::~file_lock () -{ -} - -void -file_lock::set_lock (type lock_type, - unsigned int timeout) -{ - try - { - struct itimerval timeout_timer; - timeout_timer.it_interval.tv_sec = timeout_timer.it_interval.tv_usec = 0; - timeout_timer.it_value.tv_sec = timeout; - timeout_timer.it_value.tv_usec = 0; - set_timer(timeout_timer); - - /* Now the signal handler and itimer are set, the function can't - return without stopping the timer and restoring the signal - handler to its original state. */ - - /* Wait on lock until interrupted by a signal if a timeout was set, - otherwise return immediately. */ - struct flock read_lock = - { - lock_type, - SEEK_SET, - 0, - 0, // Lock entire file - 0 - }; - - if (fcntl(this->fd, - (timeout != 0) ? F_SETLKW : F_SETLK, - &read_lock) == -1) - { - if (errno == EINTR) - throw error(LOCK_TIMEOUT); - else - throw error(LOCK, errno); - } - unset_timer(); - } - catch (error const& e) - { - unset_timer(); - throw; - } -} - -void -file_lock::unset_lock () -{ - set_lock(LOCK_NONE, 0); -} - -device_lock::device_lock (std::string const& device): - lock(), - device(device) -{ -} - -device_lock::~device_lock () -{ -} - -void -device_lock::set_lock (type lock_type, - unsigned int timeout) -{ - try - { - lock_timeout = false; - - struct itimerval timeout_timer; - timeout_timer.it_interval.tv_sec = timeout_timer.it_interval.tv_usec = 0; - timeout_timer.it_value.tv_sec = timeout; - timeout_timer.it_value.tv_usec = 0; - set_timer(timeout_timer); - - /* Now the signal handler and itimer are set, the function can't - return without stopping the timer and restoring the signal - handler to its original state. */ - - /* Wait on lock until interrupted by a signal if a timeout was set, - otherwise return immediately. */ - pid_t status = 0; - while (lock_timeout == false) - { - if (lock_type == LOCK_SHARED || lock_type == LOCK_EXCLUSIVE) - { - status = dev_lock(this->device.c_str()); - if (status == 0) // Success - break; - else if (status < 0) // Failure - { - throw error(DEVICE_LOCK); - } - } - else - { - pid_t cur_lock_pid = dev_testlock(this->device.c_str()); - if (cur_lock_pid < 0) // Test failure - { - throw error(DEVICE_TEST); - } - else if (cur_lock_pid > 0 && cur_lock_pid != getpid()) - { - // Another process owns the lock, so we successfully - // "drop" our nonexistent lock. - break; - } - status = dev_unlock(this->device.c_str(), getpid()); - if (status == 0) // Success - break; - else if (status < 0) // Failure - { - throw error(DEVICE_RELEASE); - } - } - } - - if (lock_timeout) - { - - format fmt(_("lock held by pid %1%")); - fmt % status; - throw error(((lock_type == LOCK_SHARED || lock_type == LOCK_EXCLUSIVE) - ? DEVICE_LOCK_TIMEOUT : DEVICE_RELEASE_TIMEOUT), - fmt.str()); - } - unset_timer(); - } - catch (error const& e) - { - unset_timer(); - throw; - } -} - -void -device_lock::unset_lock () -{ - set_lock(LOCK_NONE, 0); -} - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/sbuild-lock.h b/schroot/sbuild-lock.h deleted file mode 100644 index 090c8f46..00000000 --- a/schroot/sbuild-lock.h +++ /dev/null @@ -1,200 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#ifndef SBUILD_LOCK_H -#define SBUILD_LOCK_H - -#include "sbuild-custom-error.h" - -#include - -#include -#include -#include -#include - -namespace sbuild -{ - - /** - * Advisory locking. This class defines a simple interface for - * shared and exclusive locks. - */ - class lock - { - public: - /// Lock type. - enum type - { - LOCK_SHARED = F_RDLCK, ///< A shared (read) lock. - LOCK_EXCLUSIVE = F_WRLCK, ///< An exclusive (write) lock. - LOCK_NONE = F_UNLCK ///< No lock. - }; - - /// Error codes. - enum error_code - { - TIMEOUT_HANDLER, ///< Failed to set timeout handler. - TIMEOUT_SET, ///< Failed to set timeout. - TIMEOUT_CANCEL, ///< Failed to cancel timeout. - LOCK, ///< Failed to acquire lock (timed out). - LOCK_TIMEOUT, ///< Failed to acquire lock. - DEVICE_LOCK, ///< Failed to acquire device lock. - DEVICE_LOCK_TIMEOUT, ///< Failed to acquire device lock (timed out). - DEVICE_TEST, ///< Failed to test device lock. - DEVICE_RELEASE, ///< Failed to release device lock. - DEVICE_RELEASE_TIMEOUT ///< Failed to release device lock (timed out) - }; - - /// Exception type. - typedef custom_error error; - - /** - * Acquire a lock. - * - * @param lock_type the type of lock to acquire. - * @param timeout the time in seconds to wait on the lock. - */ - virtual void - set_lock (type lock_type, - unsigned int timeout) = 0; - - /** - * Release a lock. This is equivalent to set_lock with a - * lock_type of LOCK_NONE and a timeout of 0. - */ - virtual void - unset_lock () = 0; - - protected: - /// The constructor. - lock (); - /// The destructor. - virtual ~lock (); - - /** - * Set the SIGALARM handler. - * - * An error will be thrown on failure. - */ - void - set_alarm (); - - /** - * Restore the state of SIGALRM prior to starting lock - * acquisition. - */ - void - clear_alarm (); - - /** - * Set up an itimer for future expiry. This is used to interrupt - * system calls. This will set a handler for SIGALRM as a side - * effect (using set_alarm). - * - * An error will be thrown on failure. - * - * @param timer the timeout to set. - */ - void - set_timer (struct itimerval const& timer); - - /** - * Remove any itimer currently set up. This will clear any - * SIGALRM handler (using clear_alarm). - * - * An error will be thrown on failure. - */ - void - unset_timer (); - - private: - /// Signals saved during timeout. - struct sigaction saved_signals; - }; - - /** - * File lock. Simple whole-file shared and exclusive advisory - * locking based upon POSIX fcntl byte region locks. - */ - class file_lock : public lock - { - public: - /** - * The constructor. - * - * @param fd the file descriptor to lock. - */ - file_lock (int fd); - - /// The destructor. - virtual ~file_lock (); - - void - set_lock (type lock_type, - unsigned int timeout); - - void - unset_lock (); - - private: - /// The file descriptor to lock. - int fd; - }; - - /** - * Device lock. Set an advisory lock on a device. The lock is - * acquired using liblockdev lock_dev(). Note that a lock_type of - * LOCK_SHARED is equivalent to LOCK_EXCLUSIVE, because this lock - * type does not support shared locks. - */ - class device_lock : public lock - { - public: - /** - * The constructor. - * - * @param device the device to lock (full pathname). - */ - device_lock (std::string const& device); - - /// The destructor. - virtual ~device_lock (); - - void - set_lock (type lock_type, - unsigned int timeout); - - void - unset_lock (); - - private: - /// The device to lock. - std::string device; - }; - -} - -#endif /* SBUILD_LOCK_H */ - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/sbuild-log.cc b/schroot/sbuild-log.cc deleted file mode 100644 index af6c8c05..00000000 --- a/schroot/sbuild-log.cc +++ /dev/null @@ -1,61 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#include - -#include "sbuild-log.h" -#include "sbuild-nostream.h" - -#include - -std::ostream& -sbuild::log_info () -{ - return std::cerr << "I: "; -} - -std::ostream& -sbuild::log_warning () -{ - return std::cerr << "W: "; -} - -std::ostream& -sbuild::log_error () -{ - return std::cerr << "E: "; -} - -std::ostream& -sbuild::log_debug (sbuild::DebugLevel level) -{ - if (debug_level > 0 && - level >= debug_level) - return std::cerr << "D(" << level << "): "; - else - return sbuild::cnull; -} - -sbuild::DebugLevel sbuild::debug_level = sbuild::DEBUG_NONE; - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/sbuild-log.h b/schroot/sbuild-log.h deleted file mode 100644 index ef314959..00000000 --- a/schroot/sbuild-log.h +++ /dev/null @@ -1,84 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#ifndef SBUILD_LOG_H -#define SBUILD_LOG_H - -#include - -namespace sbuild -{ - - /// Debugging level. - enum DebugLevel - { - DEBUG_NONE = -1, ///< No debugging. - DEBUG_NOTICE = 1, ///< Notification messages. - DEBUG_INFO = 2, ///< Informational messages. - DEBUG_WARNING = 3, ///< Warning messages. - DEBUG_CRITICAL = 4 ///< Critical messages. - }; - - /** - * Log an informational message. - * - * @returns an ostream. - */ - std::ostream& - log_info (); - - /** - * Log a warning message. - * - * @returns an ostream. - */ - std::ostream& - log_warning (); - - /** - * Log an error message. - * - * @returns an ostream. - */ - std::ostream& - log_error (); - - /** - * Log a debug message. - * - * @param level the debug level of the message being logged. - * @returns an ostream. This will be a valid stream if level is - * greater or equal to debug_level, or else a null stream will be - * returned, resulting in no output. - */ - std::ostream& - log_debug (DebugLevel level); - - /// The debugging level in use. - extern DebugLevel debug_level; - -} - -#endif /* SBUILD_LOG_H */ - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/sbuild-nostream.cc b/schroot/sbuild-nostream.cc deleted file mode 100644 index e6b34742..00000000 --- a/schroot/sbuild-nostream.cc +++ /dev/null @@ -1,28 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#include "sbuild-nostream.h" - -sbuild::nostream sbuild::cnull; - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/sbuild-nostream.h b/schroot/sbuild-nostream.h deleted file mode 100644 index b233a7b4..00000000 --- a/schroot/sbuild-nostream.h +++ /dev/null @@ -1,86 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#ifndef SBUILD_NOSTREAM_H -#define SBUILD_NOSTREAM_H - -#include -#include - -namespace sbuild -{ - - /** - * Null stream buffer. This stream buffer acts as a bit-bucket, - * discarding all input. - */ - template > - class basic_nbuf: public std::basic_streambuf - { - /** - * Output buffer. EOF is never returned. - * - * @param c the character to output. - * @returns traits::not_eof is always returned, never traits::eof. - */ - typename traits::int_type - overflow (typename traits::int_type c) - { - return traits::not_eof(c); // indicate success - } - }; - - /** - * Null output stream. This ostream discards all input, because it - * uses a basic_nbuf stream buffer. - */ - template > - class basic_nostream: public std::basic_ostream - { - public: - /// The constructor. - basic_nostream (): - std::basic_ios(&nbuf), - std::basic_ostream(&nbuf) - { - init(&nbuf); - } - - private: - /// The stream buffer. - basic_nbuf nbuf; - }; - - /// A null ostream. - typedef basic_nostream nostream; - /// A wide null ostream. - typedef basic_nostream wnostream; - - /// A null ostream. - extern nostream cnull; - -} - -#endif /* SBUILD_NOSTREAM_H */ - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/sbuild-parse-error.cc b/schroot/sbuild-parse-error.cc deleted file mode 100644 index 5045be20..00000000 --- a/schroot/sbuild-parse-error.cc +++ /dev/null @@ -1,242 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#include - -#include "sbuild-i18n.h" -#include "sbuild-parse-error.h" - -#include - -using namespace sbuild; -using boost::format; - -namespace -{ - - typedef std::pair emap; - - /** - * This is a list of the supported error codes. It's used to - * construct the real error codes map. - */ - emap init_errors[] = - { - emap(parse_error::NONE, N_("No error")), - emap(parse_error::BAD_FILE, N_("Can't open file")), - emap(parse_error::BAD_VALUE, N_("Could not parse value")), - emap(parse_error::INVALID_LINE, N_("Invalid line")), - emap(parse_error::NO_GROUP, N_("No group specified")), - emap(parse_error::INVALID_GROUP, N_("Invalid group")), - emap(parse_error::DUPLICATE_GROUP, N_("Duplicate group")), - emap(parse_error::NO_KEY, N_("No key specified")), - emap(parse_error::DUPLICATE_KEY, N_("Duplicate key")), - emap(parse_error::MISSING_KEY, N_("Required key is missing")), - emap(parse_error::DISALLOWED_KEY, N_("Disallowed key used")) - }; - -} - -std::map -parse_error::error_strings -(init_errors, - init_errors + (sizeof(init_errors) / sizeof(init_errors[0]))); - - -parse_error::parse_error (type error, - std::string const& detail): - runtime_error(format_error(error, detail)) -{ -} - -parse_error::parse_error (size_t line, - type error, - std::string const& detail): - runtime_error(format_error(line, error, detail)) -{ -} - -parse_error::parse_error (size_t line, - std::string const& group, - type error, - std::string const& detail): - runtime_error(format_error(line, group, error, detail)) -{ -} - -parse_error::parse_error (size_t line, - std::string const& group, - std::string const& key, - type error, - std::string const& detail): - runtime_error(format_error(line, group, key, error, detail)) -{ -} - -parse_error::parse_error (std::string const& group, - type error, - std::string const& detail): - runtime_error(format_error(group, error, detail)) -{ -} - -parse_error::parse_error (std::string const& group, - std::string const& key, - type error, - std::string const& detail): - runtime_error(format_error(group, key, error, detail)) -{ -} - -const char * -parse_error::get_error (type error) -{ - std::map::const_iterator pos = - error_strings.find(error); - - if (pos != error_strings.end()) - return gettext(pos->second); - - return _("Unknown error"); -} - -std::string -parse_error::format_error (type error, - std::string const& detail) -{ - if (detail.length() > 0) - { - format fmt((error == NONE - ? "%2%" - : _("%1% \"%2%\""))); - fmt % get_error(error) % detail; - return fmt.str(); - } - else - return get_error(error); -} - -std::string -parse_error::format_error (size_t line, - type error, - std::string const& detail) -{ - if (detail.length() > 0) - { - format fmt((error == NONE - ? _("line %1%: %3%") - : _("line %1%: %2% \"%3%\""))); - fmt % line % get_error(error) % detail; - return fmt.str(); - } - else - { - format fmt(_("line %1%: %2%")); - fmt % line % get_error(error); - return fmt.str(); - } -} - -std::string -parse_error::format_error (size_t line, - std::string const& group, - type error, - std::string const& detail) -{ - if (detail.length() > 0) - { - format fmt((error == NONE - ? _("line %1% [%2%]: %4%") - : _("line %1% [%2%]: %3% \"%4%\""))); - fmt % line % group % get_error(error) % detail; - return fmt.str(); - } - else - { - format fmt(_("line %1% [%2%]: %3%")); - fmt % line % group % get_error(error); - return fmt.str(); - } -} - -std::string -parse_error::format_error (size_t line, - std::string const& group, - std::string const& key, - type error, - std::string const& detail) -{ - if (detail.length() > 0) - { - format fmt((error == NONE - ? _("line %1% [%2%] %3%: %5%") - : _("line %1% [%2%] %3%: %4% \"%5%\""))); - fmt % line % group % key % get_error(error) % detail; - return fmt.str(); - } - else - { - format fmt(_("line %1% [%2%] %3%: %4%")); - fmt % line % group % key % get_error(error); - return fmt.str(); - } -} - -std::string -parse_error::format_error (std::string const& group, - type error, - std::string const& detail) -{ - if (detail.length() > 0) - { - format fmt((error == NONE - ? _("[%1%]: %3%") - : _("[%1%]: %2% \"%3%\""))); - fmt % group % get_error(error) % detail; - return fmt.str(); - } - else - { - format fmt(_("[%1%]: %2%")); - fmt % group % get_error(error); - return fmt.str(); - } -} - -std::string -parse_error::format_error (std::string const& group, - std::string const& key, - type error, - std::string const& detail) -{ - if (detail.length() > 0) - { - format fmt((error == NONE - ? _("[%1%] %2%: %4%") - : _("[%1%] %2%: %3% \"%4%\""))); - fmt % group % key % get_error(error) % detail; - return fmt.str(); - } - else - { - format fmt(_("[%1%] %2%: %3%")); - fmt % group % key % get_error(error); - return fmt.str(); - } -} diff --git a/schroot/sbuild-parse-error.h b/schroot/sbuild-parse-error.h deleted file mode 100644 index 5bdc7fa1..00000000 --- a/schroot/sbuild-parse-error.h +++ /dev/null @@ -1,227 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#ifndef SBUILD_PARSE_ERROR_H -#define SBUILD_PARSE_ERROR_H - -#include "sbuild-error.h" -#include "sbuild-log.h" - -#include -#include - -#include - -namespace sbuild -{ - - /** - * Parse error. - */ - class parse_error : public runtime_error - { - public: - enum type - { - NONE, ///< No error occured. Used for detail only. - BAD_FILE, ///< The file to parse couldn't be opened. - BAD_VALUE, ///< The value could not be parsed. - INVALID_LINE, ///< The line is invalid. - NO_GROUP, ///< No group was specified. - INVALID_GROUP, ///< The group is invalid. - DUPLICATE_GROUP, ///< The group is a duplicate. - NO_KEY, ///< No key was specified. - DUPLICATE_KEY, ///< The key is a duplicate. - MISSING_KEY, ///< The key is missing. - DISALLOWED_KEY ///< The key is not allowed. - }; - - /** - * The constructor. - * - * @param error the error code. - * @param detail the details of the error. - */ - parse_error (type error, - std::string const& detail); - - /** - * The constructor. - * - * @param line the line the error occured on. - * @param error the error code. - * @param detail the details of the error. - */ - parse_error (size_t line, - type error, - std::string const& detail); - - /** - * The constructor. - * - * @param line the line the error occured on. - * @param group the group the error occured within. - * @param error the error code. - * @param detail the details of the error. - */ - parse_error (size_t line, - std::string const& group, - type error, - std::string const& detail); - - /** - * The constructor. - * - * @param line the line the error occured on. - * @param group the group the error occured within. - * @param key the key the error occured within. - * @param error the error code. - * @param detail the details of the error. - */ - parse_error (size_t line, - std::string const& group, - std::string const& key, - type error, - std::string const& detail); - - /** - * The constructor. - * - * @param group the group the error occured within. - * @param error the error code. - * @param detail the details of the error. - */ - parse_error (std::string const& group, - type error, - std::string const& detail); - - /** - * The constructor. - * - * @param group the group the error occured within. - * @param key the key the error occured within. - * @param error the error code. - * @param detail the details of the error. - */ - parse_error (std::string const& group, - std::string const& key, - type error, - std::string const& detail); - - private: - /// Mapping between error code and string. - static std::map error_strings; - - /** - * Get a translated error string. - * - * @param error the error code. - * @returns a translated error string. - */ - static const char * - get_error (type error); - - /** - * Format an error message. - * - * @param error the error code. - * @param detail the details of the error. - */ - static std::string - format_error (type error, - std::string const& detail); - - /** - * Format an error message. - * - * @param line the line the error occured on. - * @param error the error code. - * @param detail the details of the error. - */ - static std::string - format_error (size_t line, - type error, - std::string const& detail); - - /** - * Format an error message. - * - * @param line the line the error occured on. - * @param group the group the error occured within. - * @param error the error code. - * @param detail the details of the error. - */ - static std::string - format_error (size_t line, - std::string const& group, - type error, - std::string const& detail); - - /** - * Format an error message. - * - * @param line the line the error occured on. - * @param group the group the error occured within. - * @param key the key the error occured within. - * @param error the error code. - * @param detail the details of the error. - */ - static std::string - format_error (size_t line, - std::string const& group, - std::string const& key, - type error, - std::string const& detail); - - /** - * Format an error message. - * - * @param group the group the error occured within. - * @param error the error code. - * @param detail the details of the error. - */ - static std::string - format_error (std::string const& group, - type error, - std::string const& detail); - - /** - * Format an error message. - * - * @param group the group the error occured within. - * @param key the key the error occured within. - * @param error the error code. - * @param detail the details of the error. - */ - static std::string - format_error (std::string const& group, - std::string const& key, - type error, - std::string const& detail); - }; - -} - -#endif /* SBUILD_PARSE_ERROR_H */ - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/sbuild-parse-value.cc b/schroot/sbuild-parse-value.cc deleted file mode 100644 index 74aa04fb..00000000 --- a/schroot/sbuild-parse-value.cc +++ /dev/null @@ -1,61 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#include - -#include "sbuild-parse-value.h" - -using namespace sbuild; - -parse_value::parse_value (std::string const& value): - value(value) -{ -} - -parse_value::~parse_value () -{ -} - -bool -parse_value::parse (bool& parsed_value) const -{ - if (this->value == "true" || this->value == "yes" || this->value == "1") - parsed_value = true; - else if (this->value == "false" || this->value == "no" || this->value == "0") - parsed_value = false; - else - return false; - - log_debug(DEBUG_NOTICE) << "value=" << parsed_value << std::endl; - return true; -} - -bool -parse_value::parse (std::string& parsed_value) const -{ - parsed_value = this->value; - log_debug(DEBUG_NOTICE) << "value=" << parsed_value << std::endl; - return true; -} - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/sbuild-parse-value.h b/schroot/sbuild-parse-value.h deleted file mode 100644 index c403adff..00000000 --- a/schroot/sbuild-parse-value.h +++ /dev/null @@ -1,119 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#ifndef SBUILD_PARSE_VALUE_H -#define SBUILD_PARSE_VALUE_H - -#include "sbuild-parse-error.h" -#include "sbuild-log.h" - -#include -#include - -namespace sbuild -{ - - /** - * Parse a text string value. This is a wrapper around a string - * value, to convert it into any desired type. - */ - class parse_value - { - public: - /// Exception type. - typedef parse_error error; - - /** - * The constructor. - * @param value the value to parse. - */ - parse_value (std::string const& value); - - /// The destructor. - virtual ~parse_value (); - - /** - * Convert object into any type T. - * @returns an object of type T; an exception will be thrown on - * parse failure. - */ - template - operator T (void) - { - T tmp; - - if (parse(tmp) == false) - { - throw error(parse_error::BAD_VALUE, this->value); - } - - return tmp; - } - - private: - /** - * Parse a boolean value. - * @param parsed_value the variable to store the parsed value. - * @returns true on success, false on failure. - */ - bool - parse (bool& parsed_value) const; - - /** - * Parse a string value. - * @param parsed_value the variable to store the parsed value. - * @returns true on success, false on failure. - */ - bool - parse (std::string& parsed_value) const; - - /** - * Parse a value of type T. - * @param parsed_value the variable to store the parsed value. - * @returns true on success, false on failure. - */ - template - bool - parse (T& parsed_value) const - { - std::istringstream is(this->value); - is.imbue(std::locale("C")); - T tmpval; - if (is >> tmpval) - { - parsed_value = tmpval; - log_debug(DEBUG_NOTICE) << "value=" << parsed_value << std::endl; - return true; - } - log_debug(DEBUG_NOTICE) << "parse error" << std::endl; - return false; - } - - std::string value; - }; - -} - -#endif /* SBUILD_PARSE_VALUE_H */ - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/sbuild-personality.cc b/schroot/sbuild-personality.cc deleted file mode 100644 index 7d420a88..00000000 --- a/schroot/sbuild-personality.cc +++ /dev/null @@ -1,189 +0,0 @@ -/* Copyright © 2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#include - -#include "sbuild-personality.h" - -#include -#include -#include - -#ifdef __linux__ -#include -#endif - -#include - -using boost::format; -using namespace sbuild; - -namespace -{ - - typedef std::pair emap; - - /** - * This is a list of the supported error codes. It's used to - * construct the real error codes map. - */ - emap init_errors[] = - { - emap(sbuild::personality::SET, N_("Failed to set personality")) - }; - - typedef std::pair pmap; - - /** - * This is a list of the supported personalities. It's used to - * construct the real personalities map. - */ - pmap initial_personalities[] = - { - pmap("undefined", 0xffffffff), -#ifdef __linux__ - pmap("linux", PER_LINUX), - pmap("linux_32bit", PER_LINUX_32BIT), - pmap("svr4", PER_SVR4), - pmap("scorvr3", PER_SCOSVR3), - pmap("osr5", PER_OSR5), - pmap("wysev386", PER_WYSEV386), - pmap("iscr4", PER_ISCR4), - pmap("bsd", PER_BSD), - pmap("sunos", PER_SUNOS), - pmap("xenix", PER_XENIX), - pmap("linux32", PER_LINUX32), - pmap("irix32", PER_IRIX32), - pmap("irixn32", PER_IRIXN32), - pmap("irix64", PER_IRIX64), - pmap("riscos", PER_RISCOS), - pmap("solaris", PER_SOLARIS), - pmap("uw7", PER_UW7), - pmap("hpux", PER_HPUX), - pmap("osf4", PER_OSF4), -#endif - }; - -} - -template<> -std::map -custom_error::error_strings -(init_errors, - init_errors + (sizeof(init_errors) / sizeof(init_errors[0]))); - -std::map -sbuild::personality::personalities(initial_personalities, - initial_personalities + (sizeof(initial_personalities) / sizeof(initial_personalities[0]))); - -sbuild::personality::personality (): - persona( -#ifdef __linux__ - ::personality(0xffffffff) -#else - 0xffffffff -#endif - ) -{ -} - -sbuild::personality::personality (type persona): - persona(persona) -{ -} - -sbuild::personality::personality (std::string const& persona): - persona(find_personality(persona)) -{ -} - -sbuild::personality::~personality () -{ -} - -sbuild::personality::type -sbuild::personality::find_personality (std::string const& persona) -{ - std::map::const_iterator pos = - personalities.find(persona); - - if (pos != personalities.end()) - return pos->second; - - return 0xffffffff; -} - -std::string const& -sbuild::personality::find_personality (type persona) -{ - static const std::string unknown("unknown"); - - for (std::map::const_iterator pos = personalities.begin(); - pos != personalities.end(); - ++pos) - if (pos->second == persona) - return pos->first; - - return unknown; -} - -std::string const& -sbuild::personality::get_name () const -{ - return find_personality(this->persona); -} - -sbuild::personality::type -sbuild::personality::get () const -{ - return this->persona; -} - -void -sbuild::personality::set () const -{ -#ifdef __linux__ - /* Set the process execution domain using personality(2). */ - if (this->persona != 0xffffffff && - ::personality (this->persona) < 0) - { - throw error(get_name(), SET, errno); - } -#endif -} - -void -sbuild::personality::print_personalities (std::ostream& stream) -{ - for (std::map::const_iterator pos = personalities.begin(); - pos != personalities.end(); - ++pos) - { - stream << pos->first; - std::map::const_iterator stpos = pos; - if (++stpos != personalities.end()) - stream << ", "; - } -} - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/sbuild-personality.h b/schroot/sbuild-personality.h deleted file mode 100644 index 05a7d17b..00000000 --- a/schroot/sbuild-personality.h +++ /dev/null @@ -1,163 +0,0 @@ -/* Copyright © 2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#ifndef SBUILD_PERSONALITY_H -#define SBUILD_PERSONALITY_H - -#include "sbuild-config.h" -#include "sbuild-custom-error.h" - -#include -#include -#include - -namespace sbuild -{ - - /** - * Chroot personality. A chroot may have a personality (also knows - * as a process execution domain) which is used to run non-native - * binaries. For example, running 32-bit Linux binaries on a 64-bit - * Linux system, or an SVR4 binary on a 32-bit Linux system. This - * is currently a Linux only feature; it does nothing on non-Linux - * systems. This is a wrapper around the personality(2) system - * call. - */ - class personality - { - public: - /// Personality type. - typedef unsigned long type; - - /// Error codes. - enum error_code - { - SET ///< Could not set personality. - }; - - /// Exception type. - typedef custom_error error; - - /** - * The constructor. On Linux systems, this is initialised with - * the current process' personality. On non-Linux systems, it is - * initialised as "undefined". - */ - personality (); - - /** - * The constructor. - * - * @param persona the persona to set. - */ - personality (type persona); - - /** - * The constructor. - * - * @param persona the persona to set. - */ - personality (std::string const& persona); - - ///* The destructor. - ~personality (); - - /** - * Get the name of the personality. - * - * @returns the personality name. - */ - std::string const& get_name () const; - - /** - * Get the personality. - * - * @returns the personality. - */ - type - get () const; - - /** - * Set the process personality. This sets the personality (if valid) using - * the personality(2) system call. If setting the personality - * fails, an error is thown. - */ - void - set () const; - - /** - * Print a list of the available personalities. - * - * @param stream the stream to output to. - */ - static void - print_personalities (std::ostream& stream); - - /** - * Print the personality name to a stream. - * - * @param stream the stream to output to. - * @param rhs the personality to output. - * @returns the stream. - */ - friend std::ostream& - operator << (std::ostream& stream, - personality const& rhs) - { - return stream << find_personality(rhs.persona); - } - - private: - /** - * Find a personality by name. - * - * @param persona the personality to find. - * @returns the personality type; this is -1 if the personality - * was undefined, or -2 if the personality was unknown (not - * found). - */ - static type - find_personality (std::string const& persona); - - /** - * Find a personality by number. - * - * @param persona the personality to find. - * @returns the personality name, "undefined" if the personality was - * not defined, or "unknown" if the personality was not found. - */ - static std::string const& - find_personality (type persona); - - /// The personality type. - type persona; - - /// Mapping between personality name and type. - static std::map personalities; - }; - -} - -#endif /* SBUILD_PERSONALITY_H */ - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/sbuild-session.cc b/schroot/sbuild-session.cc deleted file mode 100644 index 4940a3c9..00000000 --- a/schroot/sbuild-session.cc +++ /dev/null @@ -1,1162 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#include - -#include "sbuild-chroot-plain.h" -#include "sbuild-chroot-lvm-snapshot.h" -#include "sbuild-session.h" - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include - -#include - -using std::cout; -using std::endl; -using boost::format; -using namespace sbuild; - -namespace -{ - - typedef std::pair emap; - - /** - * This is a list of the supported error codes. It's used to - * construct the real error codes map. - */ - emap init_errors[] = - { - emap(session::CHROOT_UNKNOWN, N_("Failed to find chroot")), - emap(session::CHROOT_LOCK, N_("Failed to lock chroot")), - emap(session::CHROOT_UNLOCK, N_("Failed to unlock chroot")), - emap(session::CHROOT_SETUP, N_("Chroot setup failed")), - emap(session::SIGHUP_SET, N_("Failed to set hangup signal handler")), - emap(session::SIGHUP_CATCH, N_("Caught hangup signal")), - emap(session::CHILD_FORK, N_("Failed to fork child")), - emap(session::CHILD_WAIT, N_("Wait for child failed")), - emap(session::CHILD_SIGNAL, N_("Child terminated by signal")), - emap(session::CHILD_CORE, N_("Child dumped core")), - emap(session::CHILD_FAIL, N_("Child exited abnormally (reason unknown; not a signal or core dump)")), - emap(session::USER_SWITCH, N_("User switching is not permitted")) - }; - - /** - * Get the current working directory. If it can't be found, fall - * back to root. - * - * @returns the current working directory. - */ - std::string - getcwd () - { - std::string cwd; - - char *raw_cwd = ::getcwd (NULL, 0); - if (raw_cwd) - cwd = raw_cwd; - else - cwd = "/"; - free(raw_cwd); - - return cwd; - } - - /** - * Check group membership. - * - * @param group the group to check for. - * @returns true if the user is a member of group, otherwise false. - */ - bool - is_group_member (std::string const& group) - { - errno = 0; - struct group *groupbuf = getgrnam(group.c_str()); - if (groupbuf == NULL) - { - if (errno == 0) - log_error() << format(_("%1%: Group not found")) % group << endl; - else - log_error() << format(_("%1%: Group not found: %2%")) - % group % strerror(errno) - << endl; - exit (EXIT_FAILURE); - } - - bool group_member = false; - if (groupbuf->gr_gid == getgid()) - { - group_member = true; - } - else - { - int supp_group_count = getgroups(0, NULL); - if (supp_group_count < 0) - { - log_error() << format(_("Can't get supplementary group count: %1%")) - % strerror(errno) - << endl; - exit (EXIT_FAILURE); - } - if (supp_group_count > 0) - { - gid_t *supp_groups = new gid_t[supp_group_count]; - if (getgroups(supp_group_count, supp_groups) < 1) - { - log_error() << format(_("Can't get supplementary groups: %1%")) - % strerror(errno) - << endl; - exit (EXIT_FAILURE); - } - - for (int i = 0; i < supp_group_count; ++i) - { - if (groupbuf->gr_gid == supp_groups[i]) - group_member = true; - } - delete[] supp_groups; - } - } - - return group_member; - } - - volatile bool sighup_called = false; - - /** - * Handle the SIGALRM signal. - * - * @param ignore the signal number. - */ - void - sighup_handler (int ignore) - { - /* This exists so that system calls get interrupted. */ - sighup_called = true; - } - -#ifdef SBUILD_DEBUG - volatile bool child_wait = true; -#endif - -} - -template<> -std::map -custom_error::error_strings -(init_errors, - init_errors + (sizeof(init_errors) / sizeof(init_errors[0]))); - -session::session (std::string const& service, - config_ptr& config, - operation operation, - sbuild::string_list const& chroots): - auth(service), - config(config), - chroots(chroots), - chroot_status(true), - child_status(0), - session_operation(operation), - session_id(), - force(false), - saved_signals(), - cwd(getcwd()) -{ -} - -session::~session () -{ -} - -session::config_ptr const& -session::get_config () const -{ - return this->config; -} - -void -session::set_config (config_ptr& config) -{ - this->config = config; -} - -string_list const& -session::get_chroots () const -{ - return this->chroots; -} - -void -session::set_chroots (string_list const& chroots) -{ - this->chroots = chroots; -} - -session::operation -session::get_operation () const -{ - return this->session_operation; -} - -void -session::set_operation (operation operation) -{ - this->session_operation = operation; -} - -std::string const& -session::get_session_id () const -{ - return this->session_id; -} - -void -session::set_session_id (std::string const& session_id) -{ - this->session_id = session_id; -} - -bool -session::get_force () const -{ - return this->force; -} - -void -session::set_force (bool force) -{ - this->force = force; -} - -int -session::get_child_status () const -{ - return this->child_status; -} - -auth::status -session::get_chroot_auth_status (auth::status status, - chroot::ptr const& chroot) const -{ - string_list const& users = chroot->get_users(); - string_list const& root_users = chroot->get_root_users(); - string_list const& groups = chroot->get_groups(); - string_list const& root_groups = chroot->get_root_groups(); - - bool in_users = false; - bool in_root_users = false; - bool in_groups = false; - bool in_root_groups = false; - - sbuild::string_list::const_iterator upos = - find(users.begin(), users.end(), get_ruser()); - if (upos != users.end()) - in_users = true; - - sbuild::string_list::const_iterator rupos = - find(root_users.begin(), root_users.end(), get_ruser()); - if (rupos != root_users.end()) - in_root_users = true; - - if (!groups.empty()) - { - for (string_list::const_iterator gp = groups.begin(); - gp != groups.end(); - ++gp) - if (is_group_member(*gp)) - in_groups = true; - } - - if (!root_groups.empty()) - { - for (string_list::const_iterator gp = root_groups.begin(); - gp != root_groups.end(); - ++gp) - if (is_group_member(*gp)) - in_root_groups = true; - } - - /* - * No auth required if in root users or root groups and - * changing to root, or if the uid is not changing. If not - * in user or group, authentication fails immediately. - */ - if ((in_users == true || in_groups == true || - in_root_users == true || in_root_groups == true) && - this->get_ruid() == this->get_uid()) - { - status = change_auth(status, auth::STATUS_NONE); - } - else if ((in_root_users == true || in_root_groups == true) && - this->get_uid() == 0) - { - status = change_auth(status, auth::STATUS_NONE); - } - else if (in_users == true || in_groups == true) - // Auth required if not in root group - { - status = change_auth(status, auth::STATUS_USER); - } - else // Not in any groups - { - if (this->get_ruid() == 0) - status = change_auth(status, auth::STATUS_USER); - else - status = change_auth(status, auth::STATUS_FAIL); - } - - return status; -} - -auth::status -session::get_auth_status () const -{ - assert(!this->chroots.empty()); - if (this->config.get() == 0) return auth::STATUS_FAIL; - - /* - * Note that the root user can't escape authentication. This is - * because pam_rootok.so should be used in the PAM configuration if - * root should automatically be granted access. The only exception - * is that the root group doesn't need to be added to the groups or - * root groups lists. - */ - - auth::status status = auth::STATUS_NONE; - - /* @todo Use set difference rather than iteration and - is_group_member. */ - for (string_list::const_iterator cur = this->chroots.begin(); - cur != this->chroots.end(); - ++cur) - { - const chroot::ptr chroot = this->config->find_alias(*cur); - if (!chroot) // Should never happen, but cater for it anyway. - { - log_warning() << format(_("No chroot found matching alias '%1%'")) - % *cur - << endl; - status = change_auth(status, auth::STATUS_FAIL); - } - - status = change_auth(status, get_chroot_auth_status(status, chroot)); - } - - return status; -} - -void -session::run_impl () -{ - assert(this->config.get() != NULL); - assert(!this->chroots.empty()); - -try - { - sighup_called = false; - set_sighup_handler(); - - for (string_list::const_iterator cur = this->chroots.begin(); - cur != this->chroots.end(); - ++cur) - { - log_debug(DEBUG_NOTICE) - << format("Running session in %1% chroot:") % *cur - << endl; - - const chroot::ptr ch = this->config->find_alias(*cur); - if (!ch) // Should never happen, but cater for it anyway. - { - throw error(*cur, CHROOT_UNKNOWN); - } - - chroot::ptr chroot(ch->clone()); - - /* If restoring a session, set the session ID from the - chroot name, or else generate it. Only chroots which - support session creation append a UUID to the session - ID. */ - if (chroot->get_active() || - !(chroot->get_session_flags() & chroot::SESSION_CREATE)) - { - set_session_id(chroot->get_name()); - } - else - { - uuid_t uuid; - char uuid_str[37]; - uuid_generate(uuid); - uuid_unparse(uuid, uuid_str); - uuid_clear(uuid); - std::string session_id(chroot->get_name() + "-" + uuid_str); - set_session_id(session_id); - } - - /* Activate chroot. */ - chroot->set_active(true); - - /* If a chroot mount location has not yet been set, and the - chroot is not a plain chroot, set a mount location with the - session id. */ - { - chroot_plain *plain = dynamic_cast(chroot.get()); - if (chroot->get_mount_location().empty() && - (plain == 0 || plain->get_run_setup_scripts() == true)) - { - std::string location(std::string(SCHROOT_MOUNT_DIR) + "/" + - this->session_id); - chroot->set_mount_location(location); - } - } - - /* Chroot types which create a session (e.g. LVM devices) - need the chroot name respecifying. */ - if (chroot->get_session_flags() & chroot::SESSION_CREATE) - { - chroot->set_name(this->session_id); - chroot->set_aliases(string_list()); - } - - /* LVM devices need the snapshot device name specifying. */ - chroot_lvm_snapshot *snapshot = 0; - if ((snapshot = dynamic_cast(chroot.get())) != 0) - { - std::string dir(dirname(snapshot->get_device(), '/')); - std::string device(dir + "/" + this->session_id); - snapshot->set_snapshot_device(device); - } - - try - { - /* Run setup-start chroot setup scripts. */ - setup_chroot(chroot, chroot::SETUP_START); - if (this->session_operation == OPERATION_BEGIN) - cout << this->session_id << endl; - - /* Run recover scripts. */ - setup_chroot(chroot, chroot::SETUP_RECOVER); - - try - { - /* Run exec-start scripts. */ - setup_chroot(chroot, chroot::EXEC_START); - - /* Run session if setup succeeded. */ - if (this->session_operation == OPERATION_AUTOMATIC || - this->session_operation == OPERATION_RUN) - run_chroot(chroot); - - /* Run exec-stop scripts whether or not there was an - error. */ - setup_chroot(chroot, chroot::EXEC_STOP); - } - catch (error const& e) - { - setup_chroot(chroot, chroot::EXEC_STOP); - throw; - } - - } - catch (error const& e) - { - try - { - setup_chroot(chroot, chroot::SETUP_STOP); - } - catch (error const& discard) - { - } - chroot->set_active(false); - throw; - } - - /* Run setup-stop chroot setup scripts whether or not there - was an error. */ - setup_chroot(chroot, chroot::SETUP_STOP); - - /* Deactivate chroot. */ - chroot->set_active(false); - } - - clear_sighup_handler(); - } -catch (error const& e) - { - clear_sighup_handler(); - - /* If a command was not run, but something failed, the exit - status still needs setting. */ - if (this->child_status == 0) - this->child_status = EXIT_FAILURE; - throw; - } -} - -string_list -session::get_login_directories () const -{ - string_list ret; - - // Set current working directory. - ret.push_back(this->cwd); - - // Set $HOME. - environment env = get_pam_environment(); - std::string home; - if (env.get("HOME", home) && - std::find(ret.begin(), ret.end(), home) == ret.end()) - ret.push_back(home); - - // Set passwd home. - if (std::find(ret.begin(), ret.end(), get_home()) == ret.end()) - ret.push_back(get_home()); - - // Final fallback to root. - if (std::find(ret.begin(), ret.end(), "/") == ret.end()) - ret.push_back("/"); - - return ret; -} - -string_list -session::get_command_directories () const -{ - string_list ret; - - // Set current working directory. - ret.push_back(this->cwd); - - return ret; -} - -std::string -session::get_shell () const -{ - assert (!auth::get_shell().empty()); - std::string shell = auth::get_shell(); - - struct stat statbuf; - if (stat(shell.c_str(), &statbuf) < 0) - { - if (shell != "/bin/sh") - { - log_warning() << format(_("%1%: Shell not available: %2%")) - % shell % strerror(errno) << endl; - shell = "/bin/sh"; - log_warning() << format(_("Falling back to %1%")) - % shell << endl; - } - } - - return shell; -} - -void -session::get_command (sbuild::chroot::ptr& session_chroot, - std::string& file, - string_list& command) const -{ - /* Run login shell */ - if (command.empty() || - command[0].empty()) // No command - get_login_command(session_chroot, file, command); - else - get_user_command(session_chroot, file, command); -} - -void -session::get_login_command (sbuild::chroot::ptr& session_chroot, - std::string& file, - string_list& command) const -{ - command.clear(); - - std::string shell = get_shell(); - file = shell; - - if (get_environment().empty() && - session_chroot->get_command_prefix().empty()) - // Not keeping environment and can setup argv correctly; login shell - { - std::string shellbase = basename(shell, '/'); - std::string loginshell = "-" + shellbase; - command.push_back(loginshell); - - log_debug(DEBUG_NOTICE) - << format("Running login shell: %1%") % shell << endl; - syslog(LOG_USER|LOG_NOTICE, - "[%s chroot] (%s->%s) Running login shell: \"%s\"", - session_chroot->get_name().c_str(), - get_ruser().c_str(), get_user().c_str(), - shell.c_str()); - } - else - { - command.push_back(shell); - log_debug(DEBUG_NOTICE) - << format("Running shell: %1%") % shell << endl; - syslog(LOG_USER|LOG_NOTICE, - "[%s chroot] (%s->%s) Running shell: \"%s\"", - session_chroot->get_name().c_str(), - get_ruser().c_str(), get_user().c_str(), - shell.c_str()); - } - - if (get_verbosity() != auth::VERBOSITY_QUIET) - { - std::string format_string; - if (get_ruid() == get_uid()) - { - if (get_environment().empty() && - session_chroot->get_command_prefix().empty()) - format_string = _("[%1% chroot] Running login shell: \"%4%\""); - else - format_string = _("[%1% chroot] Running shell: \"%4%\""); - } - else - { - if (get_environment().empty() && - session_chroot->get_command_prefix().empty()) - format_string = _("[%1% chroot] (%2%->%3%) Running login shell: \"%4%\""); - else - format_string = _("[%1% chroot] (%2%->%3%) Running shell: \"%4%\""); - } - - format fmt(format_string); - fmt % session_chroot->get_name() - % get_ruser() % get_user() - % shell; - log_info() << fmt << endl; - } -} - -void -session::get_user_command (sbuild::chroot::ptr& session_chroot, - std::string& file, - string_list& command) const -{ - /* Search for program in path. */ - environment env = get_pam_environment(); - std::string path; - if (!env.get("PATH", path)) - path.clear(); - - file = find_program_in_path(command[0], path, ""); - if (file.empty()) - file = command[0]; - std::string commandstring = string_list_to_string(command, " "); - log_debug(DEBUG_NOTICE) - << format("Running command: %1%") % commandstring << endl; - syslog(LOG_USER|LOG_NOTICE, "[%s chroot] (%s->%s) Running command: \"%s\"", - session_chroot->get_name().c_str(), get_ruser().c_str(), get_user().c_str(), commandstring.c_str()); - - if (get_verbosity() != auth::VERBOSITY_QUIET) - { - std::string format_string; - if (get_ruid() == get_uid()) - format_string = _("[%1% chroot] Running command: \"%4%\""); - else - format_string = (_("[%1% chroot] (%2%->%3%) Running command: \"%4%\"")); - - format fmt(format_string); - fmt % session_chroot->get_name() - % get_ruser() % get_user() - % commandstring; - log_info() << fmt << endl; - } -} - -void -session::setup_chroot (sbuild::chroot::ptr& session_chroot, - sbuild::chroot::setup_type setup_type) -{ - assert(!session_chroot->get_name().empty()); - - if (!((this->session_operation == OPERATION_BEGIN && - setup_type == chroot::SETUP_START) || - (this->session_operation == OPERATION_RECOVER && - setup_type == chroot::SETUP_RECOVER) || - (this->session_operation == OPERATION_END && - setup_type == chroot::SETUP_STOP) || - (this->session_operation == OPERATION_RUN && - (setup_type == chroot::EXEC_START || - setup_type == chroot::EXEC_STOP)) || - (this->session_operation == OPERATION_AUTOMATIC && - (setup_type == chroot::SETUP_START || - setup_type == chroot::SETUP_STOP || - setup_type == chroot::EXEC_START || - setup_type == chroot::EXEC_STOP)))) - return; - - if (((setup_type == chroot::SETUP_START || - setup_type == chroot::SETUP_RECOVER || - setup_type == chroot::SETUP_STOP) && - session_chroot->get_run_setup_scripts() == false) || - ((setup_type == chroot::EXEC_START || - setup_type == chroot::EXEC_STOP) && - session_chroot->get_run_exec_scripts() == false)) - return; - - if (setup_type == chroot::SETUP_START) - this->chroot_status = true; - - try - { - session_chroot->lock(setup_type); - } - catch (chroot::error const& e) - { - this->chroot_status = false; - try - { - // Release lock, which also removes session metadata. - session_chroot->unlock(setup_type, 0); - } - catch (chroot::error const& ignore) - { - } - throw error(session_chroot->get_name(), CHROOT_LOCK, e.what()); - } - - std::string setup_type_string; - if (setup_type == chroot::SETUP_START) - setup_type_string = "setup-start"; - else if (setup_type == chroot::SETUP_RECOVER) - setup_type_string = "setup-recover"; - else if (setup_type == chroot::SETUP_STOP) - setup_type_string = "setup-stop"; - else if (setup_type == chroot::EXEC_START) - setup_type_string = "exec-start"; - else if (setup_type == chroot::EXEC_STOP) - setup_type_string = "exec-stop"; - - std::string chroot_status_string; - if (this->chroot_status) - chroot_status_string = "ok"; - else - chroot_status_string = "fail"; - - string_list arg_list; - arg_list.push_back(RUN_PARTS); // Run run-parts(8) - if (get_verbosity() == auth::VERBOSITY_VERBOSE) - arg_list.push_back("--verbose"); - arg_list.push_back("--lsbsysinit"); - arg_list.push_back("--exit-on-error"); - if (setup_type == chroot::SETUP_STOP || - setup_type == chroot::EXEC_STOP) - arg_list.push_back("--reverse"); - format arg_fmt1("--arg=%1%"); - arg_fmt1 % setup_type_string; - arg_list.push_back(arg_fmt1.str()); - format arg_fmt2("--arg=%1%"); - arg_fmt2 % chroot_status_string; - arg_list.push_back(arg_fmt2.str()); - if (setup_type == chroot::SETUP_START || - setup_type == chroot::SETUP_RECOVER || - setup_type == chroot::SETUP_STOP) - arg_list.push_back(SCHROOT_CONF_SETUP_D); // Setup directory - else - arg_list.push_back(SCHROOT_CONF_EXEC_D); // Run directory - - /* Get a complete list of environment variables to set. We need to - query the chroot here, since this can vary depending upon the - chroot type. */ - environment env; - session_chroot->setup_env(env); - env.add("AUTH_USER", get_user()); - { - const char *verbosity = NULL; - switch (get_verbosity()) - { - case auth::VERBOSITY_QUIET: - verbosity = "quiet"; - break; - case auth::VERBOSITY_NORMAL: - verbosity = "normal"; - break; - case auth::VERBOSITY_VERBOSE: - verbosity = "verbose"; - break; - default: - log_debug(DEBUG_CRITICAL) << format(_("Invalid verbosity level: %1%, falling back to \"normal\"")) - % static_cast(get_verbosity()) - << endl; - verbosity = "normal"; - break; - } - env.add("AUTH_VERBOSITY", verbosity); - } - - env.add("MOUNT_DIR", SCHROOT_MOUNT_DIR); - env.add("LIBEXEC_DIR", SCHROOT_LIBEXEC_DIR); - env.add("PID", getpid()); - env.add("SESSION_ID", this->session_id); - - int exit_status = 0; - pid_t pid; - - if ((pid = fork()) == -1) - { - this->chroot_status = false; - throw error(session_chroot->get_name(), CHILD_FORK, errno); - } - else if (pid == 0) - { - // The setup scripts don't use our syslog fd. - closelog(); - - chdir("/"); - /* This is required to ensure the scripts run with uid=0 and gid=0, - otherwise setuid programs such as mount(8) will fail. This - should always succeed, because our euid=0 and egid=0.*/ - setuid(0); - setgid(0); - initgroups("root", 0); - if (exec (arg_list[0], arg_list, env)) - { - log_error() << format(_("Could not exec \"%1%\": %2%")) - % arg_list[0] % strerror(errno) - << endl; - exit (EXIT_FAILURE); - } - exit (EXIT_FAILURE); /* Should never be reached. */ - } - else - { - wait_for_child(pid, exit_status); - } - - try - { - session_chroot->unlock(setup_type, exit_status); - } - catch (chroot::error const& e) - { - this->chroot_status = false; - throw error(session_chroot->get_name(), CHROOT_UNLOCK, e.what()); - } - - if (exit_status != 0) - { - this->chroot_status = false; - - format fmt(_("stage=%1%")); - fmt % setup_type_string; - throw error(session_chroot->get_name(), CHROOT_SETUP, fmt.str()); - } -} - -void -session::run_child (sbuild::chroot::ptr& session_chroot) -{ - assert(!session_chroot->get_name().empty()); - - assert(!get_user().empty()); - assert(!get_shell().empty()); - assert(auth::pam != NULL); // PAM must be initialised - - // Store before chroot call. - this->cwd = getcwd(); - - std::string location(session_chroot->get_path()); - - /* Child errors result in immediate exit(). Errors are not - propagated back via an exception, because there is no longer any - higher-level handler to catch them. */ - try - { - open_session(); - } - catch (auth::error const& e) - { - log_error() << format(_("PAM error: %1%")) % e.what() - << endl; - exit (EXIT_FAILURE); - } - - /* Set group ID and supplementary groups */ - if (setgid (get_gid())) - { - log_error() << format(_("Could not set gid to '%1%'")) % get_gid() - << endl; - exit (EXIT_FAILURE); - } - if (initgroups (get_user().c_str(), get_gid())) - { - log_error() << _("Could not set supplementary group IDs") << endl; - exit (EXIT_FAILURE); - } - - /* Set the process execution domain. */ - try - { - session_chroot->get_persona().set(); - } - catch (personality::error const& e) - { - log_error() << e.what() << endl; - exit (EXIT_FAILURE); - } - - /* Enter the chroot */ - if (chdir (location.c_str())) - { - log_error() << format(_("Could not chdir to '%1%': %2%")) - % location % strerror(errno) - << endl; - exit (EXIT_FAILURE); - } - if (::chroot (location.c_str())) - { - log_error() << format(_("Could not chroot to '%1%': %2%")) - % location % strerror(errno) - << endl; - exit (EXIT_FAILURE); - } - - /* Set uid and check we are not still root */ - if (setuid (get_uid())) - { - log_error() << format(_("Could not set uid to '%1%'")) % get_uid() - << endl; - exit (EXIT_FAILURE); - } - if (!setuid (0) && get_uid()) - { - log_error() << _("Failed to drop root permissions.") - << endl; - exit (EXIT_FAILURE); - } - - std::string file; - string_list command(auth::get_command()); - - string_list dlist; - if (command.empty() || - command[0].empty()) // No command - dlist = get_login_directories(); - else - dlist = get_command_directories(); - log_debug(DEBUG_NOTICE) - << format("Directory fallbacks: %1%") % string_list_to_string(dlist, ", ") << endl; - - /* Attempt to chdir to current directory. */ - bool dir_changed = false; - for (string_list::const_iterator dpos = dlist.begin(); - dpos != dlist.end(); - ++dpos) - { - if (chdir ((*dpos).c_str()) < 0) - { - ((dpos + 1 == dlist.end()) ? log_error() : log_warning()) - << format(_("Could not chdir to '%1%': %2%")) - % *dpos % strerror(errno) - << endl; - } - else - { - if (dpos != dlist.begin()) - log_warning() << format(_("Falling back to '%1%'")) - % *dpos - << endl; - dir_changed = true; - break; - } - } - - if (dir_changed == false) - exit (EXIT_FAILURE); // Warning already logged. - - /* Fix up the command for exec. */ - get_command(session_chroot, file, command); - - /* Set up environment */ - environment env = get_pam_environment(); - log_debug(DEBUG_INFO) << "Set environment:\n" << env; - - // The user's command does not use our syslog fd. - closelog(); - - // Add command prefix. - string_list full_command(session_chroot->get_command_prefix()); - if (full_command.size() > 0) - file = full_command[0]; - for (string_list::const_iterator pos = command.begin(); - pos != command.end(); - ++pos) - full_command.push_back(*pos); - - /* Execute */ - if (exec (file, full_command, env)) - { - log_error() << format(_("Could not exec \"%1%\": %2%")) - % file % strerror(errno) - << endl; - exit (EXIT_FAILURE); - } - /* This should never be reached */ - exit(EXIT_FAILURE); -} - -void -session::wait_for_child (int pid, - int& child_status) -{ - child_status = EXIT_FAILURE; // Default exit status - - int status; - bool child_killed = false; - - while (1) - { - if (sighup_called && !child_killed) - { - log_error() << _("Caught hangup signal, terminating...") - << endl; - kill(pid, SIGHUP); - this->chroot_status = false; - child_killed = true; - } - - if (wait(&status) != pid) - { - if (errno == EINTR && sighup_called) - continue; // Kill child and wait again. - else - { - throw error(CHILD_WAIT, errno); - } - } - else if (sighup_called) - { - sighup_called = false; - throw error(SIGHUP_CATCH); - } - else - break; - } - - try - { - close_session(); - } - catch (auth::error const& e) - { - // TODO: rethrow or don't catch. - throw error(e.what()); - } - - if (!WIFEXITED(status)) - { - if (WIFSIGNALED(status)) - { - throw error(CHILD_SIGNAL, strsignal(WTERMSIG(status))); - } - else if (WCOREDUMP(status)) - throw error(CHILD_CORE); - else - throw error(CHILD_FAIL); - } - - child_status = WEXITSTATUS(status); -} - -void -session::run_chroot (sbuild::chroot::ptr& session_chroot) -{ - assert(!session_chroot->get_name().empty()); - - pid_t pid; - if ((pid = fork()) == -1) - { - throw error(CHILD_FORK, errno); - } - else if (pid == 0) - { -#ifdef SBUILD_DEBUG - while (child_wait) - ; -#endif - run_child(session_chroot); - exit (EXIT_FAILURE); /* Should never be reached. */ - } - else - { - wait_for_child(pid, this->child_status); - } -} - -int -session::exec (std::string const& file, - string_list const& command, - environment const& env) -{ - char **argv = string_list_to_strv(command); - char **envp = env.get_strv(); - int status; - - if ((status = execve(file.c_str(), argv, envp)) != 0) - { - strv_delete(argv); - strv_delete(envp); - } - - return status; -} - -void -session::set_sighup_handler () -{ - struct sigaction new_sa; - sigemptyset(&new_sa.sa_mask); - new_sa.sa_flags = 0; - new_sa.sa_handler = sighup_handler; - - if (sigaction(SIGHUP, &new_sa, &this->saved_signals) != 0) - { - throw error(SIGHUP_SET, errno); - } -} - -void -session::clear_sighup_handler () -{ - /* Restore original handler */ - sigaction (SIGHUP, &this->saved_signals, NULL); -} - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/sbuild-session.h b/schroot/sbuild-session.h deleted file mode 100644 index 8f40278a..00000000 --- a/schroot/sbuild-session.h +++ /dev/null @@ -1,402 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#ifndef SBUILD_SESSION_H -#define SBUILD_SESSION_H - -#include "sbuild-auth.h" -#include "sbuild-chroot-config.h" -#include "sbuild-custom-error.h" - -#include - -#include -#include -#include -#include -#include - -namespace sbuild -{ - - /** - * Session handler. - * - * This class provides the session handling for schroot. It derives - * from auth, which performs all the necessary PAM actions, - * specialising it by overriding its virtual functions. This allows - * more sophisticated handling of user authorisation (users, groups, - * root-users and root-groups membership in the configuration file) - * and session management (setting up the session, entering the - * chroot and running the requested command or shell). - */ - class session : public auth - { - public: - /// Session operations. - enum operation - { - OPERATION_AUTOMATIC, ///< Begin, end and run a session automatically. - OPERATION_BEGIN, ///< Begin a session. - OPERATION_RECOVER, ///< Recover an existing (but inactive) session. - OPERATION_END, ///< End a session. - OPERATION_RUN ///< Run a command in an existing session. - }; - - /// Error codes. - enum error_code - { - CHROOT_UNKNOWN, ///< Failed to find chroot. - CHROOT_LOCK, ///< Failed to lock chroot. - CHROOT_UNLOCK, ///< Failed to unlock chroot. - CHROOT_SETUP, ///< Setup failed. - SIGHUP_SET, ///< Failed to set SIGHUP handler. - SIGHUP_CATCH, ///< Hangup signal caught. - CHILD_FORK, ///< Failed to fork child. - CHILD_WAIT, ///< Wait for child failed. - CHILD_SIGNAL, ///< Child terminated by signal. - CHILD_CORE, ///< Child dumped core. - CHILD_FAIL, ///< Child exited abnormally (reason unknown) - USER_SWITCH ///< User switching is not permitted. - }; - - /// Exception type. - typedef custom_error error; - - /// A shared_ptr to a chroot_config object. - typedef std::tr1::shared_ptr config_ptr; - - /// A shared_ptr to a session object. - typedef std::tr1::shared_ptr ptr; - - /** - * The constructor. - * - * @param service the PAM service name. - * @param config a shared_ptr to the chroot configuration. - * @param operation the session operation to perform. - * @param chroots the chroots to act upon. - */ - session (std::string const& service, - config_ptr& config, - operation operation, - string_list const& chroots); - - /// The destructor. - virtual ~session (); - - /** - * Get the configuration associated with this session. - * - * @returns a shared_ptr to the configuration. - */ - config_ptr const& - get_config () const; - - /** - * Set the configuration associated with this session. - * - * @param config a shared_ptr to the configuration. - */ - void - set_config (config_ptr& config); - - /** - * Get the chroots to use in this session. - * - * @returns a list of chroots. - */ - string_list const& - get_chroots () const; - - /** - * Set the chroots to use in this session. - * - * @param chroots a list of chroots. - */ - void - set_chroots (string_list const& chroots); - - /** - * Get the operation this session will perform. - * - * @returns the operation. - */ - operation - get_operation () const; - - /** - * Set the operation this session will perform. - * - * @param operation the operation. - */ - void - set_operation (operation operation); - - /** - * Get the session identifier. The session identifier is a unique - * string to identify a session. - * - * @returns the session id. - */ - std::string const& - get_session_id () const; - - /** - * Set the session identifier. The session identifier is a unique - * string to identify a session. - * - * @param session_id the session id. - */ - void - set_session_id (std::string const& session_id); - - /** - * Get the force status of this session. - * - * @returns true if operation will be forced, otherwise false. - */ - bool - get_force () const; - - /** - * Set the force status of this session. - * - * @param force true to force operation, otherwise false. - */ - void - set_force (bool force); - - /** - * Get the exit (wait) status of the last child process to run in this - * session. - * - * @returns the exit status. - */ - int - get_child_status () const; - - protected: - /** - * Check if authentication is required for a single chroot, taking - * users, groups, root-users and root-groups membership into - * account. - */ - virtual auth::status - get_chroot_auth_status (auth::status status, - chroot::ptr const& chroot) const; - - public: - /** - * Check if authentication is required, taking users, groups, - * root-users and root-groups membership of all chroots specified - * into account. - */ - virtual sbuild::auth::status - get_auth_status () const; - - protected: - /** - * Run a session. If a command has been specified, this will be - * run in each of the specified chroots. If no command has been - * specified, a login shell will run in the specified chroot. - * - * An error will be thrown on failure. - */ - virtual void - run_impl (); - - /** - * Get a list of directories to change to when running a login - * shell. Multiple directories are used as fallbacks. - * - * @returns a list of directories - */ - virtual string_list - get_login_directories () const; - - /** - * Get a list of directories to change to when running a command - * Multiple directories are used as fallbacks. - * - * @returns a list of directories - */ - virtual string_list - get_command_directories () const; - - /** - * Get the shell to run. This finds a suitable shell to run in - * the chroot, falling back to /bin/sh if necessary. Note that it - * assumes it is inside the chroot when called. - * - * @returns the shell. - */ - virtual std::string - get_shell () const; - - /** - * Get the command to run. - * - * @param session_chroot the chroot to setup. This must be - * present in the chroot list and the chroot configuration object. - * @param file the filename to pass to execve(2). - * @param command the argv to pass to execve(2). - */ - virtual void - get_command (chroot::ptr& session_chroot, - std::string& file, - string_list& command) const; - - /** - * Get the command to run a login shell. - * - * @param session_chroot the chroot to setup. This must be - * present in the chroot list and the chroot configuration object. - * @param file the filename to pass to execve(2). - * @param command the argv to pass to execve(2). - */ - virtual void - get_login_command (chroot::ptr& session_chroot, - std::string& file, - string_list& command) const; - - /** - * Get the command to run a user command. - * - * @param session_chroot the chroot to setup. This must be - * present in the chroot list and the chroot configuration object. - * @param file the filename to pass to execve(2). - * @param command the argv to pass to execve(2). - */ - virtual void - get_user_command (chroot::ptr& session_chroot, - std::string& file, - string_list& command) const; - - private: - /** - * execve wrapper. Run the command specified by file (an absolute - * pathname), using command and env as the argv and environment, - * respectively. - * - * @param file the program to execute. - * @param command the arguments to pass to the executable. - * @param env the environment. - * @returns the return value of the execve system call on failure. - */ - int - exec (std::string const& file, - string_list const& command, - environment const& env); - /** - * Setup a chroot. This runs all of the commands in setup.d or run.d. - * - * The environment variables CHROOT_NAME, CHROOT_DESCRIPTION, - * CHROOT_LOCATION, AUTH_USER and AUTH_VERBOSITY are set for use in - * setup scripts. See schroot-setup(5) for a complete list. - * - * An error will be thrown on failure. - * - * @param session_chroot the chroot to setup. This must be - * present in the chroot list and the chroot configuration object. - * @param setup_type the type of setup to perform. - */ - void - setup_chroot (chroot::ptr& session_chroot, - chroot::setup_type setup_type); - - /** - * Run command or login shell in the specified chroot. - * - * An error will be thrown on failure. - * - * @param session_chroot the chroot to setup. This must be - * present in the chroot list and the chroot configuration object. - */ - void - run_chroot (chroot::ptr& session_chroot); - - /** - * Run a command or login shell as a child process in the - * specified chroot. This method is only ever to be run in a - * child process, and will never return. - * - * @param session_chroot the chroot to setup. This must be - * present in the chroot list and the chroot configuration object. - */ - void - run_child (chroot::ptr& session_chroot); - - /** - * Wait for a child process to complete, and check its exit status. - * - * An error will be thrown on failure. - * - * @param pid the pid to wait for. - * @param child_status the place to store the child exit status. - */ - void - wait_for_child (int pid, - int& child_status); - - /** - * Set the SIGHUP handler. - * - * An error will be thrown on failure. - */ - void - set_sighup_handler (); - - /** - * Restore the state of SIGHUP prior to setting the handler. - */ - void - clear_sighup_handler (); - - /// The chroot configuration. - config_ptr config; - /// The chroots to run the session operation in. - string_list chroots; - /// The current chroot status. - int chroot_status; - /// The child exit status. - int child_status; - /// The session operation to perform. - operation session_operation; - /// The session identifier. - std::string session_id; - /// The session force status. - bool force; - /// Signals saved while sighup handler is set. - struct sigaction saved_signals; - - protected: - /// Current working directory. - std::string cwd; - }; - -} - -#endif /* SBUILD_SESSION_H */ - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/sbuild-types.h b/schroot/sbuild-types.h deleted file mode 100644 index f5f6d6fe..00000000 --- a/schroot/sbuild-types.h +++ /dev/null @@ -1,117 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#ifndef SBUILD_TYPES_H -#define SBUILD_TYPES_H - -#include -#include -#include -#include -#include - -namespace sbuild -{ - - /// A string vector. - typedef std::vector string_list; - - /// A date representation. - class date - { - public: - date (time_t unix_time): - unix_time(unix_time) - {} - - ~date () - {} - - template - friend - std::basic_ostream& - operator << (std::basic_ostream& stream, - date const& dt) - { - std::ios_base::iostate err = std::ios_base::goodbit; - - std::tm dtm; - if (gmtime_r(&dt.unix_time, &dtm) == 0) - { - err = std::ios_base::badbit; - } - else - { - try - { - typename std::basic_ostream::sentry sentry(stream); - if (sentry) - { - const char nfmt[] = "%d %b %Y"; - charT wfmt[sizeof(nfmt)/sizeof(nfmt[0])]; - std::use_facet >(stream.getloc()) - .widen(nfmt, nfmt + (sizeof(nfmt)/sizeof(nfmt[0])) - 1, wfmt); - - typedef std::time_put > - time_type; - if (std::use_facet(stream.getloc()) - .put(stream, stream, stream.fill(), - &dtm, wfmt + 0, wfmt + sizeof(wfmt)/sizeof(wfmt[0]) - 1) - .failed()) - { - err = std::ios_base::badbit; - } - stream.width(0); - } - } - catch (...) - { - bool flag = false; - try - { - stream.setstate(std::ios::failbit); - } - catch (std::ios_base::failure) - { - flag = true; - } - if (flag) - throw; - } - } - - if (err) - stream.setstate(err); - - return stream; - } - - private: - time_t unix_time; - }; - -} - -#endif /* SBUILD_TYPES_H */ - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/sbuild-util.cc b/schroot/sbuild-util.cc deleted file mode 100644 index 58aeff51..00000000 --- a/schroot/sbuild-util.cc +++ /dev/null @@ -1,232 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#include - -#include "sbuild-util.h" - -#include -#include -#include - -using namespace sbuild; - -namespace -{ - - /** - * Remove duplicate adjacent characters from a string. - * - * @param str the string to check. - * @param dup the duplicate character to check for. - * @returns a string with any duplicates removed. - */ - std::string remove_duplicates (std::string const& str, - char dup) - { - std::string ret; - - for (std::string::size_type pos = 0; - pos < str.length(); - ++pos) - { - ret += str[pos]; - if (str[pos] == dup) - { - while (pos + 1 < str.length() && - str[pos + 1] == dup) - ++pos; - } - } - - return ret; - } - -} - -std::string -sbuild::basename (std::string name, - char separator) -{ - // Remove trailing separators - std::string::size_type cur = name.length(); - while (cur - 1 != 0 && name[cur - 1] == separator) - --cur; - name.resize(cur); - - // Find last separator - std::string::size_type pos = name.rfind(separator); - - std::string ret; - if (pos == std::string::npos) - ret = name; // No separators - else if (pos == 0 && name.length() == 1 && name[0] == separator) - ret = separator; // Only separators - else - ret = name.substr(pos + 1); // Basename only - - return remove_duplicates(ret, separator); -} - -std::string -sbuild::dirname (std::string name, - char separator) -{ - // Remove trailing separators - std::string::size_type cur = name.length(); - while (cur - 1 != 0 && name[cur - 1] == separator) - --cur; - name.resize(cur); - - // Find last separator - std::string::size_type pos = name.rfind(separator); - - std::string ret; - if (pos == std::string::npos) - ret = "."; // No directory components - else if (pos == 0) - ret = separator; - else - ret = name.substr(0, pos); // Dirname part - - return remove_duplicates(ret, separator); -} - -std::string -sbuild::normalname (std::string name, - char separator) -{ - // Remove trailing separators - std::string::size_type cur = name.length(); - while (cur - 1 != 0 && name[cur - 1] == separator) - --cur; - name.resize(cur); - - return remove_duplicates(name, separator); -} - -std::string -sbuild::string_list_to_string (sbuild::string_list const& list, - std::string const& separator) -{ - std::string ret; - - for (string_list::const_iterator cur = list.begin(); - cur != list.end(); - ++cur) - { - ret += *cur; - if (cur + 1 != list.end()) - ret += separator; - } - - return ret; -} - -string_list -sbuild::split_string (std::string const& value, - std::string const& separator) -{ - string_list ret; - - // Skip any separators at the start - std::string::size_type last_pos = - value.find_first_not_of(separator, 0); - // Find first separator. - std::string::size_type pos = value.find_first_of(separator, last_pos); - - while (pos !=std::string::npos || last_pos != std::string::npos) - { - // Add to list - ret.push_back(value.substr(last_pos, pos - last_pos)); - // Find next - last_pos = value.find_first_not_of(separator, pos); - pos = value.find_first_of(separator, last_pos); - } - - return ret; -} - -std::string -sbuild::find_program_in_path (std::string const& program, - std::string const& path, - std::string const& prefix) -{ - if (program.find_first_of('/') != std::string::npos) - return program; - - string_list dirs = split_string(path, std::string(1, ':')); - - for (string_list::const_iterator dir = dirs.begin(); - dir != dirs.end(); - ++dir) - { - std::string realname = *dir + '/' + program; - std::string absname; - if (prefix.length() > 0) - { - absname = prefix; - if (dir->length() > 0 && (*dir)[0] != '/') - absname += '/'; - } - absname += realname; - - struct stat statbuf; - if (stat(absname.c_str(), &statbuf) == 0) - { - if (S_ISREG(statbuf.st_mode) && - access (absname.c_str(), X_OK) == 0) - return realname; - } - } - - return ""; -} - -char ** -sbuild::string_list_to_strv (string_list const& str) -{ - char **ret = new char *[str.size() + 1]; - - for (string_list::size_type i = 0; - i < str.size(); - ++i) - { - ret[i] = new char[str[i].length() + 1]; - std::strcpy(ret[i], str[i].c_str()); - } - ret[str.size()] = 0; - - return ret; -} - - -void -sbuild::strv_delete (char **strv) -{ - for (char **pos = strv; pos != 0 && *pos != 0; ++pos) - delete *pos; - delete[] strv; -} - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/sbuild-util.h b/schroot/sbuild-util.h deleted file mode 100644 index 6837ef3d..00000000 --- a/schroot/sbuild-util.h +++ /dev/null @@ -1,133 +0,0 @@ -/* Copyright © 2005-2006 Roger Leigh - * - * schroot is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * schroot is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - *********************************************************************/ - -#ifndef SBUILD_UTIL_H -#define SBUILD_UTIL_H - -#include "sbuild-types.h" - -#include - -namespace sbuild -{ - - /** - * Strip the directory path from a filename. This is similar to - * basename(3). - * - * @param name the filename to strip of its path. - * @param separator the separation delimiting directories. - * @returns the base name. - */ - std::string - basename (std::string name, - char separator = '/'); - - /** - * Strip the fileame from a pathname. This is similar to - * dirname(3). - * - * @param name the path to strip of its filename. - * @param separator the separation delimiting directories. - * @returns the directory name. - */ - std::string - dirname (std::string name, - char separator = '/'); - - /** - * Normalise a pathname. This strips all trailing separators, and - * duplicate separators within a path. - * - * @param name the path to normalise. - * @param separator the separation delimiting directories. - * @returns the normalised name. - */ - std::string - normalname (std::string name, - char separator = '/'); - - /** - * Convert a string_list into a string. The strings are - * concatenated using separator as a delimiter. - * - * @param list the list to concatenate. - * @param separator the delimiting character. - * @returns a string. - */ - std::string - string_list_to_string (string_list const& list, - std::string const& separator); - - /** - * Split a string into a string_list. The string is split using - * separator as a delimiter. - * - * @param value the string to split. - * @param separator the delimiting character or characters. - * @returns a string_list. - */ - string_list - split_string (std::string const& value, - std::string const& separator); - - /** - * Find a program in the PATH search path. - * - * @param program the program to search for. - * @param path the search path; typically the value of $PATH. - * @param prefix a directory prefix the add to the search path. - * This may be left empty to search the root filesystem. - * @returns the absolute path of the program, or an empty string if - * the program could not be found. - */ - std::string - find_program_in_path (std::string const& program, - std::string const& path, - std::string const& prefix); - - /** - * Create a string vector from a string_list. The strings in the - * vector, as well as the vector itself, are allocated with new, and - * should be freed as a whole with strv_delete. - * - * @param str the string_list to use. - */ - char ** - string_list_to_strv (string_list const& str); - - /** - * Delete a string vector. The strings in the vector, as well as - * the vector itself, must have been previously allocated with new, - * for example sbuild::environment::get_strv. - * - * @param strv the string vector to delete. - */ - void - strv_delete (char **strv); - -} - -#endif /* SBUILD_UTIL_H */ - -/* - * Local Variables: - * mode:C++ - * End: - */ diff --git a/schroot/schroot-listmounts-options.cc b/schroot/schroot-listmounts-options.cc index 83b95399..46853a22 100644 --- a/schroot/schroot-listmounts-options.cc +++ b/schroot/schroot-listmounts-options.cc @@ -19,7 +19,7 @@ #include -#include "sbuild-i18n.h" +#include #include "schroot-listmounts-options.h" diff --git a/schroot/schroot-listmounts.cc b/schroot/schroot-listmounts.cc index 5480f50a..c99fddd8 100644 --- a/schroot/schroot-listmounts.cc +++ b/schroot/schroot-listmounts.cc @@ -19,11 +19,11 @@ #include -#include "sbuild-error.h" -#include "sbuild-i18n.h" -#include "sbuild-log.h" -#include "sbuild-types.h" -#include "sbuild-util.h" +#include +#include +#include +#include +#include #include "schroot-listmounts-options.h" diff --git a/schroot/schroot-main.cc b/schroot/schroot-main.cc index 8e52c4b5..5be08bcc 100644 --- a/schroot/schroot-main.cc +++ b/schroot/schroot-main.cc @@ -19,8 +19,8 @@ #include -#include "sbuild-auth-conv.h" -#include "sbuild-auth-conv-tty.h" +#include +#include #include "schroot-main.h" diff --git a/schroot/schroot-main.h b/schroot/schroot-main.h index 5f2b3a1c..eb858b81 100644 --- a/schroot/schroot-main.h +++ b/schroot/schroot-main.h @@ -20,7 +20,7 @@ #ifndef SCHROOT_MAIN_H #define SCHROOT_MAIN_H -#include "schroot-options-base.h" +#include namespace schroot { diff --git a/schroot/schroot-options-base.h b/schroot/schroot-options-base.h index ab91323e..bfa59670 100644 --- a/schroot/schroot-options-base.h +++ b/schroot/schroot-options-base.h @@ -20,8 +20,8 @@ #ifndef SCHROOT_OPTIONS_BASE_H #define SCHROOT_OPTIONS_BASE_H -#include "sbuild-session.h" -#include "sbuild-types.h" +#include +#include #include #include diff --git a/schroot/schroot-options.h b/schroot/schroot-options.h index ecea381f..b3b9b119 100644 --- a/schroot/schroot-options.h +++ b/schroot/schroot-options.h @@ -20,7 +20,7 @@ #ifndef SCHROOT_OPTIONS_H #define SCHROOT_OPTIONS_H -#include "schroot-options-base.h" +#include namespace schroot { diff --git a/schroot/schroot-releaselock-options.cc b/schroot/schroot-releaselock-options.cc index 4d426955..a97f45e6 100644 --- a/schroot/schroot-releaselock-options.cc +++ b/schroot/schroot-releaselock-options.cc @@ -19,7 +19,7 @@ #include -#include "sbuild-i18n.h" +#include #include "schroot-releaselock-options.h" diff --git a/schroot/schroot-releaselock.cc b/schroot/schroot-releaselock.cc index e27fee49..3c45d774 100644 --- a/schroot/schroot-releaselock.cc +++ b/schroot/schroot-releaselock.cc @@ -19,9 +19,9 @@ #include -#include "sbuild-i18n.h" -#include "sbuild-log.h" -#include "sbuild-types.h" +#include +#include +#include #include "schroot-releaselock-options.h" diff --git a/test/Makefile.am b/test/Makefile.am index 14256b5f..6fb2906f 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -55,7 +55,7 @@ endif libtest_la_SOURCES = \ test-helpers.h \ testmain.cc -libtest_la_LIBADD = ../schroot/libsbuild.la $(CPPUNIT_LIBS) +libtest_la_LIBADD = $(top_builddir)/sbuild/libsbuild.la $(CPPUNIT_LIBS) sbuild_chroot_SOURCES = \ sbuild-chroot.cc \ diff --git a/test/sbuild-chroot-block-device.cc b/test/sbuild-chroot-block-device.cc index 397e03c2..0ae4d803 100644 --- a/test/sbuild-chroot-block-device.cc +++ b/test/sbuild-chroot-block-device.cc @@ -20,13 +20,13 @@ #include #include -#include - -#include +#include #include "test-helpers.h" #include "test-sbuild-chroot.h" +#include + using namespace CppUnit; class chroot_block_device : public sbuild::chroot_block_device diff --git a/test/sbuild-chroot-config.cc b/test/sbuild-chroot-config.cc index eeb2e94e..174b9ad9 100644 --- a/test/sbuild-chroot-config.cc +++ b/test/sbuild-chroot-config.cc @@ -17,15 +17,15 @@ * *********************************************************************/ +#include +#include + #include #include #include #include -#include -#include - using namespace CppUnit; class test_config : public TestFixture diff --git a/test/sbuild-chroot-file.cc b/test/sbuild-chroot-file.cc index 0e0b3222..9c7f1939 100644 --- a/test/sbuild-chroot-file.cc +++ b/test/sbuild-chroot-file.cc @@ -17,16 +17,16 @@ * *********************************************************************/ +#include + +#include "test-helpers.h" +#include "test-sbuild-chroot.h" + #include #include #include -#include - -#include "test-helpers.h" -#include "test-sbuild-chroot.h" - using namespace CppUnit; class chroot_file : public sbuild::chroot_file diff --git a/test/sbuild-chroot-lvm-snapshot.cc b/test/sbuild-chroot-lvm-snapshot.cc index fd74c7ee..f0fd21ed 100644 --- a/test/sbuild-chroot-lvm-snapshot.cc +++ b/test/sbuild-chroot-lvm-snapshot.cc @@ -17,17 +17,17 @@ * *********************************************************************/ +#include +#include + +#include "test-helpers.h" +#include "test-sbuild-chroot.h" + #include #include #include -#include -#include - -#include "test-helpers.h" -#include "test-sbuild-chroot.h" - using namespace CppUnit; class chroot_lvm_snapshot : public sbuild::chroot_lvm_snapshot diff --git a/test/sbuild-chroot-plain.cc b/test/sbuild-chroot-plain.cc index ac0df7ca..9a6c441b 100644 --- a/test/sbuild-chroot-plain.cc +++ b/test/sbuild-chroot-plain.cc @@ -17,16 +17,16 @@ * *********************************************************************/ +#include + +#include "test-helpers.h" +#include "test-sbuild-chroot.h" + #include #include #include -#include - -#include "test-helpers.h" -#include "test-sbuild-chroot.h" - using namespace CppUnit; class chroot_plain : public sbuild::chroot_plain diff --git a/test/sbuild-chroot.cc b/test/sbuild-chroot.cc index 62e124d4..7fdb6645 100644 --- a/test/sbuild-chroot.cc +++ b/test/sbuild-chroot.cc @@ -17,16 +17,16 @@ * *********************************************************************/ +#include + +#include "test-helpers.h" +#include "test-sbuild-chroot.h" + #include #include #include -#include - -#include "test-helpers.h" -#include "test-sbuild-chroot.h" - using namespace CppUnit; class basic_chroot : public sbuild::chroot diff --git a/test/sbuild-environment.cc b/test/sbuild-environment.cc index 7455d184..abad61c5 100644 --- a/test/sbuild-environment.cc +++ b/test/sbuild-environment.cc @@ -17,14 +17,14 @@ * *********************************************************************/ +#include +#include + #include #include #include -#include -#include - using namespace CppUnit; class test_environment : public TestFixture diff --git a/test/sbuild-keyfile.cc b/test/sbuild-keyfile.cc index 2688eecd..54664766 100644 --- a/test/sbuild-keyfile.cc +++ b/test/sbuild-keyfile.cc @@ -17,14 +17,14 @@ * *********************************************************************/ +#include + #include #include #include #include -#include - using namespace CppUnit; class test_keyfile : public TestFixture diff --git a/test/sbuild-lock.cc b/test/sbuild-lock.cc index 834d8c32..8ce67a50 100644 --- a/test/sbuild-lock.cc +++ b/test/sbuild-lock.cc @@ -17,17 +17,17 @@ * *********************************************************************/ +#include + #include #include #include #include -#include - #include -#include +#include using namespace CppUnit; diff --git a/test/sbuild-log.cc b/test/sbuild-log.cc index f4332103..a6b0ea80 100644 --- a/test/sbuild-log.cc +++ b/test/sbuild-log.cc @@ -17,14 +17,14 @@ * *********************************************************************/ +#include + #include #include #include #include -#include - using namespace CppUnit; class test_log : public TestFixture diff --git a/test/sbuild-nostream.cc b/test/sbuild-nostream.cc index 2b3df315..c15010b6 100644 --- a/test/sbuild-nostream.cc +++ b/test/sbuild-nostream.cc @@ -17,12 +17,12 @@ * *********************************************************************/ +#include + #include #include -#include - using namespace CppUnit; class test_nostream : public TestCase diff --git a/test/sbuild-parse-value.cc b/test/sbuild-parse-value.cc index 95767b9b..d4d90862 100644 --- a/test/sbuild-parse-value.cc +++ b/test/sbuild-parse-value.cc @@ -17,9 +17,9 @@ * *********************************************************************/ -#include +#include -#include +#include using namespace CppUnit; diff --git a/test/sbuild-personality.cc b/test/sbuild-personality.cc index 0d6b723b..c6750856 100644 --- a/test/sbuild-personality.cc +++ b/test/sbuild-personality.cc @@ -17,13 +17,13 @@ * *********************************************************************/ +#include + #include #include #include -#include - using namespace CppUnit; class test_personality : public TestCase diff --git a/test/sbuild-util.cc b/test/sbuild-util.cc index 07db84c7..2456fd0a 100644 --- a/test/sbuild-util.cc +++ b/test/sbuild-util.cc @@ -17,12 +17,12 @@ * *********************************************************************/ +#include + #include #include -#include - using namespace CppUnit; class test_util : public TestCase diff --git a/test/test-helpers.h b/test/test-helpers.h index 8f5d54b2..4ea7680c 100644 --- a/test/test-helpers.h +++ b/test/test-helpers.h @@ -20,12 +20,12 @@ #ifndef TEST_HELPERS_H #define TEST_HELPERS_H +#include + #include #include -#include - using namespace CppUnit; template diff --git a/test/test-sbuild-chroot.h b/test/test-sbuild-chroot.h index 256432f5..06baa080 100644 --- a/test/test-sbuild-chroot.h +++ b/test/test-sbuild-chroot.h @@ -20,13 +20,13 @@ #ifndef TEST_SBUILD_CHROOT_H #define TEST_SBUILD_CHROOT_H +#include + #include #include #include -#include - using namespace CppUnit; template diff --git a/test/testmain.cc b/test/testmain.cc index d8e17783..dccdda9e 100644 --- a/test/testmain.cc +++ b/test/testmain.cc @@ -17,13 +17,13 @@ * *********************************************************************/ +#include + #include #include #include -#include - using namespace CppUnit; int -- cgit v1.2.3