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