#include <apt-pkg/fileutl.h>
#include <apt-pkg/aptconfiguration.h>
#include <apt-pkg/configuration.h>
+#include <system.h>
#include <vector>
#include <string>
+#include <algorithm>
/*}}}*/
namespace APT {
// getCompressionTypes - Return Vector of usbale compressiontypes /*{{{*/
types.clear();
}
+ // setup the defaults for the compressiontypes => method mapping
+ _config->CndSet("Acquire::CompressionTypes::bz2","bzip2");
+ _config->CndSet("Acquire::CompressionTypes::lzma","lzma");
+ _config->CndSet("Acquire::CompressionTypes::gz","gzip");
+
// Set default application paths to check for optional compression types
_config->CndSet("Dir::Bin::lzma", "/usr/bin/lzma");
_config->CndSet("Dir::Bin::bzip2", "/bin/bzip2");
- ::Configuration::Item const *Opts = _config->Tree("Acquire::CompressionTypes");
- if (Opts != 0)
- Opts = Opts->Child;
-
- // at first, move over the options to setup at least the default options
- bool foundLzma=false, foundBzip2=false, foundGzip=false;
- for (; Opts != 0; Opts = Opts->Next) {
- if (Opts->Value == "lzma")
- foundLzma = true;
- else if (Opts->Value == "bz2")
- foundBzip2 = true;
- else if (Opts->Value == "gz")
- foundGzip = true;
- }
+ // accept non-list order as override setting for config settings on commandline
+ std::string const overrideOrder = _config->Find("Acquire::CompressionTypes::Order","");
+ if (overrideOrder.empty() == false)
+ types.push_back(overrideOrder);
- // setup the defaults now
- if (!foundBzip2)
- _config->Set("Acquire::CompressionTypes::bz2","bzip2");
- if (!foundLzma)
- _config->Set("Acquire::CompressionTypes::lzma","lzma");
- if (!foundGzip)
- _config->Set("Acquire::CompressionTypes::gz","gzip");
+ // load the order setting into our vector
+ std::vector<std::string> const order = _config->FindVector("Acquire::CompressionTypes::Order");
+ for (std::vector<std::string>::const_iterator o = order.begin();
+ o != order.end(); o++) {
+ if ((*o).empty() == true)
+ continue;
+ // ignore types we have no method ready to use
+ if (_config->Exists(string("Acquire::CompressionTypes::").append(*o)) == false)
+ continue;
+ // ignore types we have no app ready to use
+ string const appsetting = string("Dir::Bin::").append(*o);
+ if (_config->Exists(appsetting) == true) {
+ std::string const app = _config->FindFile(appsetting.c_str(), "");
+ if (app.empty() == false && FileExists(app) == false)
+ continue;
+ }
+ types.push_back(*o);
+ }
- // move again over the option tree to finially calculate our result
+ // move again over the option tree to add all missing compression types
::Configuration::Item const *Types = _config->Tree("Acquire::CompressionTypes");
if (Types != 0)
Types = Types->Child;
for (; Types != 0; Types = Types->Next) {
+ if (Types->Tag == "Order" || Types->Tag.empty() == true)
+ continue;
+ // ignore types we already have in the vector
+ if (std::find(types.begin(),types.end(),Types->Tag) != types.end())
+ continue;
+ // ignore types we have no app ready to use
string const appsetting = string("Dir::Bin::").append(Types->Value);
- // ignore compression types we have no app ready to use
if (appsetting.empty() == false && _config->Exists(appsetting) == true) {
std::string const app = _config->FindFile(appsetting.c_str(), "");
if (app.empty() == false && FileExists(app) == false)
return types;
}
/*}}}*/
+// GetLanguages - Return Vector of Language Codes /*{{{*/
+// ---------------------------------------------------------------------
+/* return a vector of language codes in the prefered order.
+ the special word "environment" will be replaced with the long and the short
+ code of the local settings and it will be insured that this will not add
+ duplicates. So in an german local the setting "environment, de_DE, en, de"
+ will result in "de_DE, de, en".
+ The special word "none" is the stopcode for the not-All code vector */
+std::vector<std::string> const Configuration::getLanguages(bool const &All,
+ bool const &Cached, char const * const Locale) {
+ using std::string;
+
+ // The detection is boring and has a lot of cornercases,
+ // so we cache the results to calculated it only once.
+ std::vector<string> static allCodes;
+ std::vector<string> static codes;
+
+ // we have something in the cache
+ if (codes.empty() == false || allCodes.empty() == false) {
+ if (Cached == true) {
+ if(All == true && allCodes.empty() == false)
+ return allCodes;
+ else
+ return codes;
+ } else {
+ allCodes.clear();
+ codes.clear();
+ }
+ }
+
+ // get the environment language code
+ // we extract both, a long and a short code and then we will
+ // check if we actually need both (rare) or if the short is enough
+ string const envMsg = string(Locale == 0 ? std::setlocale(LC_MESSAGES, NULL) : Locale);
+ size_t const lenShort = (envMsg.find('_') != string::npos) ? envMsg.find('_') : 2;
+ size_t const lenLong = (envMsg.find('.') != string::npos) ? envMsg.find('.') : (lenShort + 3);
+
+ string envLong = envMsg.substr(0,lenLong);
+ string const envShort = envLong.substr(0,lenShort);
+ bool envLongIncluded = true, envShortIncluded = false;
+
+ // first cornercase: LANG=C, so we use only "en" Translation
+ if (envLong == "C") {
+ codes.push_back("en");
+ return codes;
+ }
+
+ if (envLong != envShort) {
+ // to save the servers from unneeded queries, we only try also long codes
+ // for languages it is realistic to have a long code translation file...
+ char const *needLong[] = { "cs", "en", "pt", "sv", "zh", NULL };
+ for (char const **l = needLong; *l != NULL; l++)
+ if (envShort.compare(*l) == 0) {
+ envLongIncluded = false;
+ break;
+ }
+ }
+
+ // we don't add the long code, but we allow the user to do so
+ if (envLongIncluded == true)
+ envLong.clear();
+
+ // FIXME: Remove support for the old APT::Acquire::Translation
+ // it was undocumented and so it should be not very widthly used
+ string const oldAcquire = _config->Find("APT::Acquire::Translation","");
+ if (oldAcquire.empty() == false && oldAcquire != "environment") {
+ if (oldAcquire != "none")
+ codes.push_back(oldAcquire);
+ return codes;
+ }
+
+ // Support settings like Acquire::Translation=none on the command line to
+ // override the configuration settings vector of languages.
+ string const forceLang = _config->Find("Acquire::Languages","");
+ if (forceLang.empty() == false) {
+ if (forceLang == "environment") {
+ if (envLongIncluded == false)
+ codes.push_back(envLong);
+ if (envShortIncluded == false)
+ codes.push_back(envShort);
+ return codes;
+ } else if (forceLang != "none")
+ codes.push_back(forceLang);
+ return codes;
+ }
+
+ std::vector<string> const lang = _config->FindVector("Acquire::Languages");
+ // the default setting -> "environment, en"
+ if (lang.empty() == true) {
+ if (envLongIncluded == false)
+ codes.push_back(envLong);
+ if (envShortIncluded == false)
+ codes.push_back(envShort);
+ if (envShort != "en")
+ codes.push_back("en");
+ return codes;
+ }
+
+ // the configs define the order, so add the environment
+ // then needed and ensure the codes are not listed twice.
+ bool noneSeen = false;
+ for (std::vector<string>::const_iterator l = lang.begin();
+ l != lang.end(); l++) {
+ if (*l == "environment") {
+ if (envLongIncluded == true && envShortIncluded == true)
+ continue;
+ if (envLongIncluded == false) {
+ envLongIncluded = true;
+ if (noneSeen == false)
+ codes.push_back(envLong);
+ allCodes.push_back(envLong);
+ }
+ if (envShortIncluded == false) {
+ envShortIncluded = true;
+ if (noneSeen == false)
+ codes.push_back(envShort);
+ allCodes.push_back(envShort);
+ }
+ continue;
+ } else if (*l == "none") {
+ noneSeen = true;
+ continue;
+ } else if ((envLongIncluded == true && *l == envLong) ||
+ (envShortIncluded == true && *l == envShort))
+ continue;
+
+ if (noneSeen == false)
+ codes.push_back(*l);
+ allCodes.push_back(*l);
+ }
+ if (All == true)
+ return allCodes;
+ else
+ return codes;
+}
+ /*}}}*/
+// getArchitectures - Return Vector of prefered Architectures /*{{{*/
+std::vector<std::string> const Configuration::getArchitectures(bool const &Cached) {
+ using std::string;
+
+ std::vector<string> static archs;
+ if (likely(Cached == true) && archs.empty() == false)
+ return archs;
+
+ string const arch = _config->Find("APT::Architecture");
+ archs = _config->FindVector("APT::Architectures");
+ if (archs.empty() == true ||
+ std::find(archs.begin(), archs.end(), arch) == archs.end())
+ archs.push_back(arch);
+ return archs;
+}
+ /*}}}*/
+// checkArchitecture - are we interested in the given Architecture? /*{{{*/
+bool const Configuration::checkArchitecture(std::string const &Arch) {
+ if (Arch == "all")
+ return true;
+ std::vector<std::string> const archs = getArchitectures(true);
+ return (std::find(archs.begin(), archs.end(), Arch) != archs.end());
+}
+ /*}}}*/
}