]> git.saurik.com Git - apt.git/blame - apt-pkg/aptconfiguration.cc
Fix the test suite harder
[apt.git] / apt-pkg / aptconfiguration.cc
CommitLineData
e878aedb
DK
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
3/* ######################################################################
4
5 Provide access methods to various configuration settings,
6 setup defaults and returns validate settings.
7
8 ##################################################################### */
9 /*}}}*/
10// Include Files /*{{{*/
ea542140
DK
11#include <config.h>
12
e878aedb
DK
13#include <apt-pkg/aptconfiguration.h>
14#include <apt-pkg/configuration.h>
9f9717fa 15#include <apt-pkg/error.h>
d7cf5923
DK
16#include <apt-pkg/fileutl.h>
17#include <apt-pkg/macros.h>
18#include <apt-pkg/strutl.h>
e878aedb 19
3f2d77b5 20#include <dirent.h>
8aec002f 21#include <stdio.h>
b9ed63d3 22#include <fcntl.h>
453b82a3
DK
23#include <ctype.h>
24#include <stddef.h>
25#include <stdlib.h>
26#include <string.h>
27#include <unistd.h>
8bd02d8b 28#include <algorithm>
3f2d77b5
DK
29#include <string>
30#include <vector>
453b82a3 31
e878aedb
DK
32 /*}}}*/
33namespace APT {
3809194b
DK
34// setDefaultConfigurationForCompressors /*{{{*/
35static void setDefaultConfigurationForCompressors() {
36 // Set default application paths to check for optional compression types
37 _config->CndSet("Dir::Bin::bzip2", "/bin/bzip2");
38 _config->CndSet("Dir::Bin::xz", "/usr/bin/xz");
39 if (FileExists(_config->FindFile("Dir::Bin::xz")) == true) {
40 _config->Set("Dir::Bin::lzma", _config->FindFile("Dir::Bin::xz"));
41 _config->Set("APT::Compressor::lzma::Binary", "xz");
42 if (_config->Exists("APT::Compressor::lzma::CompressArg") == false) {
43 _config->Set("APT::Compressor::lzma::CompressArg::", "--format=lzma");
44 _config->Set("APT::Compressor::lzma::CompressArg::", "-9");
45 }
46 if (_config->Exists("APT::Compressor::lzma::UncompressArg") == false) {
47 _config->Set("APT::Compressor::lzma::UncompressArg::", "--format=lzma");
48 _config->Set("APT::Compressor::lzma::UncompressArg::", "-d");
49 }
50 } else {
51 _config->CndSet("Dir::Bin::lzma", "/usr/bin/lzma");
52 if (_config->Exists("APT::Compressor::lzma::CompressArg") == false) {
53 _config->Set("APT::Compressor::lzma::CompressArg::", "--suffix=");
54 _config->Set("APT::Compressor::lzma::CompressArg::", "-9");
55 }
56 if (_config->Exists("APT::Compressor::lzma::UncompressArg") == false) {
57 _config->Set("APT::Compressor::lzma::UncompressArg::", "--suffix=");
58 _config->Set("APT::Compressor::lzma::UncompressArg::", "-d");
59 }
60 }
61}
62 /*}}}*/
1e3f4083 63// getCompressionTypes - Return Vector of usable compressiontypes /*{{{*/
e878aedb 64// ---------------------------------------------------------------------
1e3f4083 65/* return a vector of compression types in the preferred order. */
e878aedb
DK
66std::vector<std::string>
67const Configuration::getCompressionTypes(bool const &Cached) {
68 static std::vector<std::string> types;
69 if (types.empty() == false) {
70 if (Cached == true)
71 return types;
72 else
73 types.clear();
74 }
75
8bd02d8b
DK
76 // setup the defaults for the compressiontypes => method mapping
77 _config->CndSet("Acquire::CompressionTypes::bz2","bzip2");
b2430e6d 78 _config->CndSet("Acquire::CompressionTypes::xz","xz");
8bd02d8b
DK
79 _config->CndSet("Acquire::CompressionTypes::lzma","lzma");
80 _config->CndSet("Acquire::CompressionTypes::gz","gzip");
81
03bef784 82 setDefaultConfigurationForCompressors();
858fd39f 83 std::vector<APT::Configuration::Compressor> const compressors = getCompressors();
e878aedb 84
8bd02d8b
DK
85 // load the order setting into our vector
86 std::vector<std::string> const order = _config->FindVector("Acquire::CompressionTypes::Order");
87 for (std::vector<std::string>::const_iterator o = order.begin();
f7f0d6c7 88 o != order.end(); ++o) {
8bd02d8b
DK
89 if ((*o).empty() == true)
90 continue;
91 // ignore types we have no method ready to use
79b207bc
DK
92 std::string const method = std::string("Acquire::CompressionTypes::").append(*o);
93 if (_config->Exists(method) == false)
8bd02d8b
DK
94 continue;
95 // ignore types we have no app ready to use
79b207bc 96 std::string const app = _config->Find(method);
858fd39f
DK
97 std::vector<APT::Configuration::Compressor>::const_iterator c = compressors.begin();
98 for (; c != compressors.end(); ++c)
79b207bc 99 if (c->Name == app)
858fd39f
DK
100 break;
101 if (c == compressors.end())
102 continue;
8bd02d8b 103 types.push_back(*o);
e878aedb
DK
104 }
105
8bd02d8b 106 // move again over the option tree to add all missing compression types
e878aedb
DK
107 ::Configuration::Item const *Types = _config->Tree("Acquire::CompressionTypes");
108 if (Types != 0)
109 Types = Types->Child;
110
111 for (; Types != 0; Types = Types->Next) {
8bd02d8b
DK
112 if (Types->Tag == "Order" || Types->Tag.empty() == true)
113 continue;
114 // ignore types we already have in the vector
115 if (std::find(types.begin(),types.end(),Types->Tag) != types.end())
116 continue;
117 // ignore types we have no app ready to use
858fd39f
DK
118 std::vector<APT::Configuration::Compressor>::const_iterator c = compressors.begin();
119 for (; c != compressors.end(); ++c)
120 if (c->Name == Types->Value)
121 break;
122 if (c == compressors.end())
123 continue;
e878aedb
DK
124 types.push_back(Types->Tag);
125 }
126
5d885723
DK
127 // add the special "uncompressed" type
128 if (std::find(types.begin(), types.end(), "uncompressed") == types.end())
129 {
8f3ba4e8 130 std::string const uncompr = _config->FindFile("Dir::Bin::uncompressed", "");
5d885723
DK
131 if (uncompr.empty() == true || FileExists(uncompr) == true)
132 types.push_back("uncompressed");
133 }
134
e878aedb
DK
135 return types;
136}
137 /*}}}*/
45df0ad2
DK
138// GetLanguages - Return Vector of Language Codes /*{{{*/
139// ---------------------------------------------------------------------
1e3f4083 140/* return a vector of language codes in the preferred order.
45df0ad2
DK
141 the special word "environment" will be replaced with the long and the short
142 code of the local settings and it will be insured that this will not add
143 duplicates. So in an german local the setting "environment, de_DE, en, de"
144 will result in "de_DE, de, en".
145 The special word "none" is the stopcode for the not-All code vector */
146std::vector<std::string> const Configuration::getLanguages(bool const &All,
d7cf5923 147 bool const &Cached, char const ** const Locale) {
45df0ad2
DK
148 using std::string;
149
150 // The detection is boring and has a lot of cornercases,
151 // so we cache the results to calculated it only once.
152 std::vector<string> static allCodes;
153 std::vector<string> static codes;
154
155 // we have something in the cache
156 if (codes.empty() == false || allCodes.empty() == false) {
157 if (Cached == true) {
158 if(All == true && allCodes.empty() == false)
159 return allCodes;
160 else
161 return codes;
162 } else {
163 allCodes.clear();
164 codes.clear();
165 }
166 }
167
3f2d77b5
DK
168 // Include all Language codes we have a Translation file for in /var/lib/apt/lists
169 // so they will be all included in the Cache.
170 std::vector<string> builtin;
171 DIR *D = opendir(_config->FindDir("Dir::State::lists").c_str());
62d8a765 172 if (D != NULL) {
3f2d77b5
DK
173 builtin.push_back("none");
174 for (struct dirent *Ent = readdir(D); Ent != 0; Ent = readdir(D)) {
527df5a2 175 string const name = SubstVar(Ent->d_name, "%5f", "_");
3f2d77b5 176 size_t const foundDash = name.rfind("-");
7cb28948 177 size_t const foundUnderscore = name.rfind("_", foundDash);
3f2d77b5
DK
178 if (foundDash == string::npos || foundUnderscore == string::npos ||
179 foundDash <= foundUnderscore ||
180 name.substr(foundUnderscore+1, foundDash-(foundUnderscore+1)) != "Translation")
181 continue;
182 string const c = name.substr(foundDash+1);
183 if (unlikely(c.empty() == true) || c == "en")
184 continue;
185 // Skip unusual files, like backups or that alike
186 string::const_iterator s = c.begin();
187 for (;s != c.end(); ++s) {
7cb28948 188 if (isalpha(*s) == 0 && *s != '_')
3f2d77b5
DK
189 break;
190 }
191 if (s != c.end())
192 continue;
193 if (std::find(builtin.begin(), builtin.end(), c) != builtin.end())
194 continue;
195 builtin.push_back(c);
196 }
62d8a765 197 closedir(D);
3f2d77b5
DK
198 }
199
45df0ad2
DK
200 // FIXME: Remove support for the old APT::Acquire::Translation
201 // it was undocumented and so it should be not very widthly used
202 string const oldAcquire = _config->Find("APT::Acquire::Translation","");
203 if (oldAcquire.empty() == false && oldAcquire != "environment") {
9f9717fa
DK
204 // TRANSLATORS: the two %s are APT configuration options
205 _error->Notice("Option '%s' is deprecated. Please use '%s' instead, see 'man 5 apt.conf' for details.",
206 "APT::Acquire::Translation", "Acquire::Languages");
45df0ad2
DK
207 if (oldAcquire != "none")
208 codes.push_back(oldAcquire);
3f2d77b5 209 codes.push_back("en");
d7cf5923 210 allCodes = codes;
3f2d77b5
DK
211 for (std::vector<string>::const_iterator b = builtin.begin();
212 b != builtin.end(); ++b)
213 if (std::find(allCodes.begin(), allCodes.end(), *b) == allCodes.end())
214 allCodes.push_back(*b);
215 if (All == true)
216 return allCodes;
217 else
218 return codes;
45df0ad2
DK
219 }
220
ab53c018
DK
221 // get the environment language codes: LC_MESSAGES (and later LANGUAGE)
222 // we extract both, a long and a short code and then we will
223 // check if we actually need both (rare) or if the short is enough
f8043f21 224 string const envMsg = string(Locale == 0 ? ::setlocale(LC_MESSAGES, NULL) : *Locale);
ab53c018
DK
225 size_t const lenShort = (envMsg.find('_') != string::npos) ? envMsg.find('_') : 2;
226 size_t const lenLong = (envMsg.find_first_of(".@") != string::npos) ? envMsg.find_first_of(".@") : (lenShort + 3);
227
228 string const envLong = envMsg.substr(0,lenLong);
229 string const envShort = envLong.substr(0,lenShort);
230
231 // It is very likely we will need the environment codes later,
d7cf5923
DK
232 // so let us generate them now from LC_MESSAGES and LANGUAGE
233 std::vector<string> environment;
eb3947c6
DK
234 if (envShort != "C") {
235 // take care of LC_MESSAGES
ab53c018 236 if (envLong != envShort)
eb3947c6
DK
237 environment.push_back(envLong);
238 environment.push_back(envShort);
239 // take care of LANGUAGE
240 const char *language_env = getenv("LANGUAGE") == 0 ? "" : getenv("LANGUAGE");
241 string envLang = Locale == 0 ? language_env : *(Locale+1);
242 if (envLang.empty() == false) {
243 std::vector<string> env = VectorizeString(envLang,':');
244 short addedLangs = 0; // add a maximum of 3 fallbacks from the environment
245 for (std::vector<string>::const_iterator e = env.begin();
246 e != env.end() && addedLangs < 3; ++e) {
247 if (unlikely(e->empty() == true) || *e == "en")
248 continue;
249 if (*e == envLong || *e == envShort)
250 continue;
251 if (std::find(environment.begin(), environment.end(), *e) != environment.end())
d7cf5923 252 continue;
eb3947c6
DK
253 ++addedLangs;
254 environment.push_back(*e);
d7cf5923 255 }
d7cf5923 256 }
eb3947c6 257 } else {
a5414e56 258 // cornercase: LANG=C, so we use only "en" Translation
eb3947c6 259 environment.push_back("en");
d7cf5923
DK
260 }
261
a5414e56 262 std::vector<string> const lang = _config->FindVector("Acquire::Languages", "environment,en");
45df0ad2
DK
263 // the configs define the order, so add the environment
264 // then needed and ensure the codes are not listed twice.
265 bool noneSeen = false;
266 for (std::vector<string>::const_iterator l = lang.begin();
f7f0d6c7 267 l != lang.end(); ++l) {
45df0ad2 268 if (*l == "environment") {
d7cf5923
DK
269 for (std::vector<string>::const_iterator e = environment.begin();
270 e != environment.end(); ++e) {
271 if (std::find(allCodes.begin(), allCodes.end(), *e) != allCodes.end())
272 continue;
45df0ad2 273 if (noneSeen == false)
d7cf5923
DK
274 codes.push_back(*e);
275 allCodes.push_back(*e);
45df0ad2
DK
276 }
277 continue;
278 } else if (*l == "none") {
279 noneSeen = true;
280 continue;
d7cf5923 281 } else if (std::find(allCodes.begin(), allCodes.end(), *l) != allCodes.end())
45df0ad2
DK
282 continue;
283
284 if (noneSeen == false)
285 codes.push_back(*l);
286 allCodes.push_back(*l);
287 }
3f2d77b5 288
a5414e56
DK
289 if (allCodes.empty() == false) {
290 for (std::vector<string>::const_iterator b = builtin.begin();
291 b != builtin.end(); ++b)
292 if (std::find(allCodes.begin(), allCodes.end(), *b) == allCodes.end())
293 allCodes.push_back(*b);
294 } else {
295 // "none" was forced
296 allCodes.push_back("none");
297 }
3f2d77b5 298
45df0ad2
DK
299 if (All == true)
300 return allCodes;
301 else
302 return codes;
303}
304 /*}}}*/
c45233ea 305// checkLanguage - are we interested in the given Language? /*{{{*/
d64e130a 306bool Configuration::checkLanguage(std::string Lang, bool const All) {
c45233ea
DK
307 // the empty Language is always interesting as it is the original
308 if (Lang.empty() == true)
309 return true;
310 // filenames are encoded, so undo this
311 Lang = SubstVar(Lang, "%5f", "_");
312 std::vector<std::string> const langs = getLanguages(All, true);
313 return (std::find(langs.begin(), langs.end(), Lang) != langs.end());
314}
315 /*}}}*/
1e3f4083 316// getArchitectures - Return Vector of preferred Architectures /*{{{*/
5dd4c8b8
DK
317std::vector<std::string> const Configuration::getArchitectures(bool const &Cached) {
318 using std::string;
319
320 std::vector<string> static archs;
321 if (likely(Cached == true) && archs.empty() == false)
322 return archs;
323
3152f4aa 324 string const arch = _config->Find("APT::Architecture");
8aec002f
DK
325 archs = _config->FindVector("APT::Architectures");
326
3152f4aa
DK
327 if (unlikely(arch.empty() == true))
328 return archs;
329
8aec002f
DK
330 // FIXME: It is a bit unclean to have debian specific code hereā€¦
331 if (archs.empty() == true) {
332 archs.push_back(arch);
b9ed63d3
DK
333
334 // Generate the base argument list for dpkg
335 std::vector<const char *> Args;
336 string Tmp = _config->Find("Dir::Bin::dpkg","dpkg");
337 {
338 string const dpkgChrootDir = _config->FindDir("DPkg::Chroot-Directory", "/");
339 size_t dpkgChrootLen = dpkgChrootDir.length();
340 if (dpkgChrootDir != "/" && Tmp.find(dpkgChrootDir) == 0) {
341 if (dpkgChrootDir[dpkgChrootLen - 1] == '/')
342 --dpkgChrootLen;
343 Tmp = Tmp.substr(dpkgChrootLen);
344 }
345 }
346 Args.push_back(Tmp.c_str());
347
348 // Stick in any custom dpkg options
349 ::Configuration::Item const *Opts = _config->Tree("DPkg::Options");
350 if (Opts != 0) {
351 Opts = Opts->Child;
352 for (; Opts != 0; Opts = Opts->Next)
353 {
354 if (Opts->Value.empty() == true)
355 continue;
356 Args.push_back(Opts->Value.c_str());
357 }
358 }
359
360 Args.push_back("--print-foreign-architectures");
361 Args.push_back(NULL);
362
363 int external[2] = {-1, -1};
364 if (pipe(external) != 0)
365 {
366 _error->WarningE("getArchitecture", "Can't create IPC pipe for dpkg --print-foreign-architectures");
367 return archs;
368 }
369
370 pid_t dpkgMultiArch = ExecFork();
371 if (dpkgMultiArch == 0) {
372 close(external[0]);
373 std::string const chrootDir = _config->FindDir("DPkg::Chroot-Directory");
b9ed63d3
DK
374 int const nullfd = open("/dev/null", O_RDONLY);
375 dup2(nullfd, STDIN_FILENO);
376 dup2(external[1], STDOUT_FILENO);
377 dup2(nullfd, STDERR_FILENO);
2510eea4 378 if (chrootDir != "/" && chroot(chrootDir.c_str()) != 0 && chdir("/") != 0)
36a0c0f7 379 _error->WarningE("getArchitecture", "Couldn't chroot into %s for dpkg --print-foreign-architectures", chrootDir.c_str());
17019a09 380 execvp(Args[0], (char**) &Args[0]);
b9ed63d3
DK
381 _error->WarningE("getArchitecture", "Can't detect foreign architectures supported by dpkg!");
382 _exit(100);
383 }
384 close(external[1]);
385
386 FILE *dpkg = fdopen(external[0], "r");
8aec002f 387 if(dpkg != NULL) {
69c2ecbd 388 char buf[1024];
4df62de6 389 while (fgets(buf, sizeof(buf), dpkg) != NULL) {
8aec002f
DK
390 char* arch = strtok(buf, " ");
391 while (arch != NULL) {
392 for (; isspace(*arch) != 0; ++arch);
bdb3d92c 393 if (arch[0] != '\0') {
8aec002f
DK
394 char const* archend = arch;
395 for (; isspace(*archend) == 0 && *archend != '\0'; ++archend);
dd7233af
DK
396 string a(arch, (archend - arch));
397 if (std::find(archs.begin(), archs.end(), a) == archs.end())
398 archs.push_back(a);
8aec002f
DK
399 }
400 arch = strtok(NULL, " ");
401 }
402 }
b9ed63d3 403 fclose(dpkg);
8aec002f 404 }
b9ed63d3 405 ExecWait(dpkgMultiArch, "dpkg --print-foreign-architectures", true);
8aec002f
DK
406 return archs;
407 }
408
5dd4c8b8
DK
409 if (archs.empty() == true ||
410 std::find(archs.begin(), archs.end(), arch) == archs.end())
bd9d81e3 411 archs.insert(archs.begin(), arch);
3152f4aa
DK
412
413 // erase duplicates and empty strings
414 for (std::vector<string>::reverse_iterator a = archs.rbegin();
415 a != archs.rend(); ++a) {
416 if (a->empty() == true || std::find(a + 1, archs.rend(), *a) != archs.rend())
417 archs.erase(a.base()-1);
418 if (a == archs.rend())
419 break;
420 }
421
5dd4c8b8
DK
422 return archs;
423}
424 /*}}}*/
425// checkArchitecture - are we interested in the given Architecture? /*{{{*/
d64e130a 426bool Configuration::checkArchitecture(std::string const &Arch) {
5dd4c8b8
DK
427 if (Arch == "all")
428 return true;
429 std::vector<std::string> const archs = getArchitectures(true);
430 return (std::find(archs.begin(), archs.end(), Arch) != archs.end());
431}
432 /*}}}*/
ce7f128c 433// getCompressors - Return Vector of usealbe compressors /*{{{*/
03bef784
DK
434// ---------------------------------------------------------------------
435/* return a vector of compressors used by apt-ftparchive in the
436 multicompress functionality or to detect data.tar files */
437std::vector<APT::Configuration::Compressor>
438const Configuration::getCompressors(bool const Cached) {
439 static std::vector<APT::Configuration::Compressor> compressors;
440 if (compressors.empty() == false) {
441 if (Cached == true)
442 return compressors;
443 else
444 compressors.clear();
445 }
446
447 setDefaultConfigurationForCompressors();
448
e29d7e3e 449 compressors.push_back(Compressor(".", "", "", NULL, NULL, 1));
03bef784
DK
450 if (_config->Exists("Dir::Bin::gzip") == false || FileExists(_config->FindFile("Dir::Bin::gzip")) == true)
451 compressors.push_back(Compressor("gzip",".gz","gzip","-9n","-d",2));
8dd623db
DK
452#ifdef HAVE_ZLIB
453 else
e29d7e3e 454 compressors.push_back(Compressor("gzip",".gz","false", NULL, NULL, 2));
8dd623db 455#endif
03bef784
DK
456 if (_config->Exists("Dir::Bin::bzip2") == false || FileExists(_config->FindFile("Dir::Bin::bzip2")) == true)
457 compressors.push_back(Compressor("bzip2",".bz2","bzip2","-9","-d",3));
c4997486
DK
458#ifdef HAVE_BZ2
459 else
e29d7e3e 460 compressors.push_back(Compressor("bzip2",".bz2","false", NULL, NULL, 3));
c4997486 461#endif
03bef784 462 if (_config->Exists("Dir::Bin::xz") == false || FileExists(_config->FindFile("Dir::Bin::xz")) == true)
2024154c 463 compressors.push_back(Compressor("xz",".xz","xz","-6","-d",4));
7f350a37
DK
464#ifdef HAVE_LZMA
465 else
466 compressors.push_back(Compressor("xz",".xz","false", NULL, NULL, 4));
467#endif
2024154c
DK
468 if (_config->Exists("Dir::Bin::lzma") == false || FileExists(_config->FindFile("Dir::Bin::lzma")) == true)
469 compressors.push_back(Compressor("lzma",".lzma","lzma","-9","-d",5));
7f350a37
DK
470#ifdef HAVE_LZMA
471 else
472 compressors.push_back(Compressor("lzma",".lzma","false", NULL, NULL, 5));
473#endif
03bef784
DK
474
475 std::vector<std::string> const comp = _config->FindVector("APT::Compressor");
476 for (std::vector<std::string>::const_iterator c = comp.begin();
477 c != comp.end(); ++c) {
8056a00c 478 if (c->empty() || *c == "." || *c == "gzip" || *c == "bzip2" || *c == "lzma" || *c == "xz")
03bef784
DK
479 continue;
480 compressors.push_back(Compressor(c->c_str(), std::string(".").append(*c).c_str(), c->c_str(), "-9", "-d", 100));
481 }
482
483 return compressors;
484}
485 /*}}}*/
b0e1a43f
DK
486// getCompressorExtensions - supported data.tar extensions /*{{{*/
487// ---------------------------------------------------------------------
488/* */
489std::vector<std::string> const Configuration::getCompressorExtensions() {
490 std::vector<APT::Configuration::Compressor> const compressors = getCompressors();
491 std::vector<std::string> ext;
492 for (std::vector<APT::Configuration::Compressor>::const_iterator c = compressors.begin();
493 c != compressors.end(); ++c)
494 if (c->Extension.empty() == false && c->Extension != ".")
495 ext.push_back(c->Extension);
496 return ext;
497}
498 /*}}}*/
03bef784
DK
499// Compressor constructor /*{{{*/
500// ---------------------------------------------------------------------
501/* */
502Configuration::Compressor::Compressor(char const *name, char const *extension,
503 char const *binary,
504 char const *compressArg, char const *uncompressArg,
505 unsigned short const cost) {
2024154c 506 std::string const config = std::string("APT::Compressor::").append(name).append("::");
03bef784
DK
507 Name = _config->Find(std::string(config).append("Name"), name);
508 Extension = _config->Find(std::string(config).append("Extension"), extension);
509 Binary = _config->Find(std::string(config).append("Binary"), binary);
510 Cost = _config->FindI(std::string(config).append("Cost"), cost);
511 std::string const compConf = std::string(config).append("CompressArg");
512 if (_config->Exists(compConf) == true)
513 CompressArgs = _config->FindVector(compConf);
514 else if (compressArg != NULL)
515 CompressArgs.push_back(compressArg);
516 std::string const uncompConf = std::string(config).append("UncompressArg");
517 if (_config->Exists(uncompConf) == true)
518 UncompressArgs = _config->FindVector(uncompConf);
519 else if (uncompressArg != NULL)
520 UncompressArgs.push_back(uncompressArg);
521}
522 /*}}}*/
ce7f128c
DK
523// getBuildProfiles - return a vector of enabled build profiles /*{{{*/
524std::vector<std::string> const Configuration::getBuildProfiles() {
525 // order is: override value (~= commandline), environment variable, list (~= config file)
526 std::string profiles_env = getenv("DEB_BUILD_PROFILES") == 0 ? "" : getenv("DEB_BUILD_PROFILES");
527 if (profiles_env.empty() == false) {
528 profiles_env = SubstVar(profiles_env, " ", ",");
529 std::string const bp = _config->Find("APT::Build-Profiles");
530 _config->Clear("APT::Build-Profiles");
531 if (bp.empty() == false)
532 _config->Set("APT::Build-Profiles", bp);
533 }
534 return _config->FindVector("APT::Build-Profiles", profiles_env);
535}
536std::string const Configuration::getBuildProfilesString() {
537 std::vector<std::string> profiles = getBuildProfiles();
538 if (profiles.empty() == true)
539 return "";
540 std::vector<std::string>::const_iterator p = profiles.begin();
541 std::string list = *p;
7a223b93 542 for (++p; p != profiles.end(); ++p)
ce7f128c
DK
543 list.append(",").append(*p);
544 return list;
545}
546 /*}}}*/
e878aedb 547}