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