diff options
author | Daniel Hartwig <mandyke@gmail.com> | 2012-04-27 15:22:49 +0800 |
---|---|---|
committer | Daniel Hartwig <mandyke@gmail.com> | 2012-04-27 15:30:50 +0800 |
commit | da06db9f7caf61fad54f76005506a67c1f925d5a (patch) | |
tree | 483cf1557d2c0c1cc5afe613bb7d111041d2068b | |
parent | ff930d08f01e6b8c583f4fde2764a4d8a1b310e2 (diff) | |
download | aptitude-da06db9f7caf61fad54f76005506a67c1f925d5a.tar.gz |
Do not call debtags on list update.
This was a rather unsightly kludge and is better suited as
a script for APT::Update::Post-Invoke.
-rw-r--r-- | NEWS | 4 | ||||
-rw-r--r-- | doc/en/aptitude.xml | 32 | ||||
-rw-r--r-- | src/generic/apt/download_update_manager.cc | 245 |
3 files changed, 4 insertions, 277 deletions
@@ -19,6 +19,10 @@ Version 0.6.7 "I said 'Step pause turn ListUpdate was too coarse to suit download_update_manager properly even though it more-or-less worked. + * [all]: Do not call debtags on list update. This was a rather + unsightly kludge is better suited as a script for + APT::Update::Post-Invoke. + - Cosmetic and UI bugs: * [curses]: Apply patch from Ubuntu: don't mention 'su' in 'Become diff --git a/doc/en/aptitude.xml b/doc/en/aptitude.xml index f15b60e0..96777acd 100644 --- a/doc/en/aptitude.xml +++ b/doc/en/aptitude.xml @@ -11115,38 +11115,6 @@ e: Examine !: Apply .: Next ,: Previous</screen> </seg> </seglistitem> - <seglistitem id='configDebtags-Binary'> - <seg><literal>Aptitude::Debtags-Binary</literal></seg> - <seg><literal>/usr/bin/debtags</literal></seg> - - <seg> - The absolute path to the - <systemitem>debtags</systemitem> command. If - configured with <systemitem>libept</systemitem> - support, &aptitude; will invoke this program whenever - the package lists are updated, passing it the - arguments listed in <link - linkend='configDebtags-Update-Options'>Aptitude::Debtags-Update-Options</link>. - </seg> - </seglistitem> - - <seglistitem id='configDebtags-Update-Options'> - <seg><literal>Aptitude::Debtags-Update-Options</literal></seg> - <seg><literal>--local</literal></seg> - - <seg> - Additional options to pass to <literal>debtags - update</literal> when invoking it after the package - lists are updated. These are split at whitespace; - single and double-quoted strings are recognized, so - setting this to <quote><literal>--vocabulary='/file - with a space</literal></quote> will store the - <systemitem>debtags</systemitem> vocabulary in - <quote><filename>/file with a - space</filename></quote>. - </seg> - </seglistitem> - <seglistitem id='configDelete-Unused'> <seg><literal>Aptitude::Delete-Unused</literal></seg> <seg><literal>true</literal></seg> diff --git a/src/generic/apt/download_update_manager.cc b/src/generic/apt/download_update_manager.cc index 215a9e1b..d9a9844d 100644 --- a/src/generic/apt/download_update_manager.cc +++ b/src/generic/apt/download_update_manager.cc @@ -28,14 +28,6 @@ #include <apt-pkg/clean.h> #include <apt-pkg/error.h> -#include <cwidget/generic/util/exception.h> -#include <cwidget/generic/util/ssprintf.h> - -#include <errno.h> -#include <fcntl.h> -#include <sys/types.h> -#include <sys/wait.h> - namespace cw = cwidget; class my_cleaner:public pkgArchiveCleaner @@ -110,167 +102,6 @@ bool download_update_manager::prepare(OpProgress &progress, return true; } -// TODO: this should be lifted to generic code. -namespace -{ - std::string parse_quoted_string(char quote_character, - const std::string &whole_string, - std::string::const_iterator &begin, - std::string::const_iterator end) - { - std::string rval; - - while(begin != end) - { - if(*begin == quote_character) - { - ++begin; - return rval; - } - else if(*begin == '\\') - { - ++begin; - if(begin != end) - rval += *begin; - } - else - rval += *begin; - - ++begin; - } - - _error->Warning(_("Unterminated quoted string in command: %s"), - whole_string.c_str()); - return rval; - } - - /** \brief Parse whitespace-separated arguments from the given - * string, handling both single and double quotes. - * - * Each argument in the string is pushed onto the end of the - * given vector. - */ - void parse_command_arguments(const std::string &command_line, - std::vector<std::string> &arguments) - { - std::string::const_iterator begin = command_line.begin();; - const std::string::const_iterator end = command_line.end(); - - while(begin != end) - { - while(begin != end && isspace(*begin)) - ++begin; - - std::string arg; - - while(begin != end && !isspace(*begin)) - { - if(*begin == '"' || *begin == '\'') - { - ++begin; - arg += parse_quoted_string(*begin, command_line, - begin, end); - } - else - { - arg.push_back(*begin); - ++begin; - } - } - - arguments.push_back(arg); - } - } - - /** \brief An exception indicating that a sub-process could not be run. - */ - class SubprocessException : public cwidget::util::Exception - { - std::string msg; - - public: - SubprocessException(const std::string &_msg) - : msg(_msg) - { - } - - std::string errmsg() const { return msg; } - }; - - /** \brief Run a subprocess and redirect its output to /dev/null. - * - * $PATH is not searched, and the arguments are passed directly to - * the subprocess without shell intervention. The return value is - * the status of the subcommand as it would be returned from - * waitpid(). - */ - int run_in_subprocess_to_devnull(const std::string &command, - const std::vector<std::string> &args) - { - // Merge any new information in the apt cache into the debtags cache - // by running 'debtags update'. Be safe here: don't risk running - // the wrong thing as root by using system() or scanning the PATH. - int pid = fork(); - if(pid < 0) - { - int errnum = errno; - - throw SubprocessException(cw::util::ssprintf(_("fork() failed: %s"), - cw::util::sstrerror(errnum).c_str())); - } - else if(pid == 0) - { - int fdnullin = open("/dev/null", O_RDONLY); - if(fdnullin < 0) - close(0); - else - { - dup2(fdnullin, 0); - close(fdnullin); - } - - int fdnullout = open("/dev/null", O_WRONLY); - if(fdnullout < 0) - { - close(1); - close(2); - } - else - { - dup2(fdnullout, 1); - dup2(fdnullout, 2); - close(fdnullout); - } - - char **argv = new char*[args.size() + 1]; - for(std::vector<std::string>::size_type i = 0; - i < args.size(); ++i) - { - argv[i] = const_cast<char *>(args[i].c_str()); - } - argv[args.size()] = NULL; - - exit(execv(command.c_str(), argv)); - } - else - { - while(true) - { - int status = 0; - errno = 0; - if(waitpid(pid, &status, 0) == pid) - return status; - else if(errno != EINTR) - { - int errnum = errno; - throw SubprocessException(cw::util::ssprintf(_("waitpid() failed: %s"), - cw::util::sstrerror(errnum).c_str())); - } - } - } - } -} - void download_update_manager::finish(pkgAcquire::RunResult res, OpProgress *progress, const sigc::slot1<void, result> &k) @@ -368,82 +199,6 @@ void download_update_manager::finish(pkgAcquire::RunResult res, bool need_autoclean = aptcfg->FindB(PACKAGE "::AutoClean-After-Update", false); -#ifdef HAVE_EPT - std::string debtags = aptcfg->Find(PACKAGE "::Debtags-Binary", "/usr/bin/debtags"); - - if(debtags.size() == 0) - _error->Error(_("The debtags command must not be an empty string.")); - // Keep the user from killing themselves without trying: a relative - // path would open a root exploit. - else if(debtags[0] != '/') - _error->Error(_("The debtags command must be an absolute path.")); - // Check up-front if we can execute the command. This is not ideal - // since there's a race condition (the command could go away before - // we try to execute it) but the worst that will happen is that we - // display a confusing error message (...exited with code 255). - else if(euidaccess(debtags.c_str(), X_OK) != 0) - { - int errnum = errno; - if(errnum == ENOENT) - // Fail silently instead of annoying the user over and over. - ; //_error->Warning(_("The debtags command (%s) does not exist; perhaps you need to install the debtags package?"), - //debtags.c_str()); - else - _error->Error(_("The debtags command (%s) cannot be executed: %s"), - debtags.c_str(), cw::util::sstrerror(errnum).c_str()); - } - else - { - progress->OverallProgress(0, 0, 1, _("Updating debtags database")); - - std::string debtags_options = aptcfg->Find(PACKAGE "::Debtags-Update-Options", "--local"); - - std::vector<std::string> args; - args.push_back(debtags); - args.push_back("update"); - parse_command_arguments(debtags_options, args); - - try - { - int status = run_in_subprocess_to_devnull(debtags, args); - if(WIFSIGNALED(status)) - { - std::string coredumpstr; -#ifdef WCOREDUMP - if(WCOREDUMP(status)) - coredumpstr = std::string(" ") + _("(core dumped)"); -#endif - // ForTranslators: "%s update %s" gets replaced by a command line, do not translate it! - _error->Warning(_("The debtags update process (%s update %s) was killed by signal %d%s."), - debtags.c_str(), debtags_options.c_str(), WTERMSIG(status), - coredumpstr.c_str()); - } - else if(WIFEXITED(status)) - { - if(WEXITSTATUS(status) != 0) - // ForTranslators: "%s update %s" gets replaced by a command line, do not translate it! - _error->Warning(_("The debtags update process (%s update %s) exited abnormally (code %d)."), - debtags.c_str(), debtags_options.c_str(), WEXITSTATUS(status)); - } - else - // This should never happen, but if it does something is - // wrong. - // ForTranslators: "%s update %s" gets replaced by a command line, do not translate it! - _error->Warning(_("The debtags update process (%s update %s) exited in an unexpected way (status %d)."), - debtags.c_str(), debtags_options.c_str(), status); - } - catch(cw::util::Exception &e) - { - // ForTranslators: "%s update %s" gets replaced by a command line, do not translate it! - _error->Warning(_("Updating the debtags database (%s update %s) failed (perhaps debtags is not installed?): %s"), - debtags.c_str(), debtags_options.c_str(), e.errmsg().c_str()); - } - - progress->Progress(1); - progress->Done(); - } -#endif - if(need_forget_new || need_autoclean) apt_load_cache(progress, true); |