From 4f430bdd41ef18c53bcb04e8594cc4d7f03eb47b Mon Sep 17 00:00:00 2001 From: Richard Hansen Date: Sun, 24 May 2020 12:13:18 -0400 Subject: [PATCH 1/3] Fix typo in comment --- parameter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parameter.c b/parameter.c index 92df292..9041836 100644 --- a/parameter.c +++ b/parameter.c @@ -531,7 +531,7 @@ int parse_parameter(int ac, char **av, const char *keyword) { case 'B': /* buildplace */ pc.buildplace = strdup(optarg); break; - case 'c': /* --config */ + case 'c': /* --configfile */ load_ok = load_config_file(optarg, &pc); if (load_ok > 1) { exit(5); -- GitLab From 5c66014c2bd20de0b82d3ede6b7444ab9c86e2d3 Mon Sep 17 00:00:00 2001 From: Richard Hansen Date: Sun, 24 May 2020 12:13:45 -0400 Subject: [PATCH 2/3] Delete unused members of struct pbuilderconfig --- parameter.c | 18 +++++++++--------- parameter.h | 5 ----- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/parameter.c b/parameter.c index 9041836..3457bb9 100644 --- a/parameter.c +++ b/parameter.c @@ -283,9 +283,6 @@ int cpbuilder_dumpconfig(pbuilderconfig *pc) { break; } - DUMPINT(mountproc); - DUMPINT(mountdev); - DUMPINT(mountdevpts); DUMPINT(save_after_login); DUMPINT(debug); @@ -330,6 +327,7 @@ int parse_parameter(int ac, char **av, const char *keyword) { int index_point; int config_ok = -1, load_ok; char *cmdstr = NULL; + static int ignored; static pbuilderconfig pc; static const struct pbuilder_operation_arg operations[] = { @@ -369,12 +367,6 @@ int parse_parameter(int ac, char **av, const char *keyword) { static struct option long_options[] = { {"basepath", required_argument, 0, 'b'}, {"buildplace", required_argument, 0, 'B'}, - {"mountproc", no_argument, &(pc.mountproc), 1}, - {"mountdev", no_argument, &(pc.mountdev), 1}, - {"mountdevpts", no_argument, &(pc.mountdevpts), 1}, - {"nomountproc", no_argument, &(pc.mountproc), 0}, - {"nomountdev", no_argument, &(pc.mountdev), 0}, - {"nomountdevpts", no_argument, &(pc.mountdevpts), 0}, {"save-after-login", no_argument, &(pc.save_after_login), 1}, {"save-after-exec", no_argument, &(pc.save_after_login), 1}, {"help", no_argument, (int *)&(pc.operation), pbuilder_help}, @@ -445,6 +437,14 @@ int parse_parameter(int ac, char **av, const char *keyword) { {"debdelta", no_argument, 0, 'm'}, {"twice", no_argument, 0, 'm'}, + /* deprecated no-op options kept for compatibility */ + {"mountproc", no_argument, &ignored, 1}, + {"mountdev", no_argument, &ignored, 1}, + {"mountdevpts", no_argument, &ignored, 1}, + {"nomountproc", no_argument, &ignored, 0}, + {"nomountdev", no_argument, &ignored, 0}, + {"nomountdevpts", no_argument, &ignored, 0}, + {0, 0, 0, 0}}; /* define pc to be clear. */ diff --git a/parameter.h b/parameter.h index 164ebe7..4984946 100644 --- a/parameter.h +++ b/parameter.h @@ -37,11 +37,6 @@ enum pbuilder_operation { typedef struct pbuilderconfig { /* if you edit here, please add to parameter.c: dumpconfig */ - log_level log_level; - int use_colors; - int mountproc; - int mountdev; - int mountdevpts; int save_after_login; int debug; char *buildplace; /* /var/cache/pbuilder/build/XXX.$$ */ -- GitLab From 9bed964df9ea4522d193a81e186e6adb4ce6464b Mon Sep 17 00:00:00 2001 From: Richard Hansen Date: Sun, 24 May 2020 15:22:19 -0400 Subject: [PATCH 3/3] Propagate settings to the next pbuilderrc config file When reading settings from a pbuilderrc file, initialize the environment with the settings obtained so far. This matches the behavior of pbuilder and makes it possible for the user's `~/.pbuilderrc` to depend on values set in `/etc/pbuilderrc` and `/usr/share/pbuilder/pbuilderrc`. Alternatively, all files could be sourced in a single bash invocation like this: const char *cmd = "env bash -c 'set -e" "; . /usr/share/pbuilder/pbuilderrc" "; . /etc/pbuilderrc" "; . ~/.pbuilderrc" "; set'"; but this approach doesn't support the `--configfile` flag when it is preceded by other settings flags. Closes: #579506 --- parameter.c | 85 +++++++++++++++++++ parameter.h | 2 +- test_parameter.c | 12 ++- ...rameter_propagate_across_pbuilder_a.config | 1 + ...rameter_propagate_across_pbuilder_b.config | 1 + 5 files changed, 99 insertions(+), 2 deletions(-) create mode 100644 test_parameter_propagate_across_pbuilder_a.config create mode 100644 test_parameter_propagate_across_pbuilder_b.config diff --git a/parameter.c b/parameter.c index 3457bb9..e9a36b4 100644 --- a/parameter.c +++ b/parameter.c @@ -29,6 +29,83 @@ #include "parameter.h" #include +static char** deep_copy_environ() { + size_t n = 0; + while (environ[n]) ++n; + char** clone = calloc(n+1, sizeof(char*)); + for (size_t i = 0; i < n; ++i) { + clone[i] = strdup(environ[i]); + } + return clone; +} + +static void free_environ(char **env) { + for (size_t i = 0; env[i]; ++i) free(env[i]); + free(env); +} + +static void xsetenv(const char *name, const char *value) { + if (0 != setenv(name, value, 1)) { + log_printf(log_error, "Failed to set environment variable %s: %s", name, strerror(errno)); + abort(); + } +} + +static void itoa(char *buf, size_t buflen, int x) { + int ret = snprintf(buf, buflen, "%d", x); + if (ret < 0 || ret >= buflen) { + log_printf(log_error, "Failed to convert integer %d to string", x); + abort(); + } +} + +static void update_environ(const pbuilderconfig *pc) { + char buf[1024]; + switch (log_get_filter_level()) { + case log_debug: xsetenv("LOGLEVEL", "D"); break; + case log_info: xsetenv("LOGLEVEL", "I"); break; + case log_warn: xsetenv("LOGLEVEL", "W"); break; + case log_error: xsetenv("LOGLEVEL", "E"); break; + default: break; + } + switch (log_get_use_colors_unresolved()) { + case log_use_colors_auto: xsetenv("USECOLORS", "auto"); break; + case log_use_colors_no: xsetenv("USECOLORS", "no"); break; + case log_use_colors_yes: xsetenv("USECOLORS", "yes"); break; + default: break; + } + if (pc->buildplace) xsetenv("BUILDPLACE", pc->buildplace); + if (pc->buildresult) xsetenv("BUILDRESULT", pc->buildresult); + if (pc->basepath) xsetenv("BASEPATH", pc->basepath); + if (pc->mirror) xsetenv("MIRRORSITE", pc->mirror); + if (pc->distribution) xsetenv("DISTRIBUTION", pc->distribution); + if (pc->components) xsetenv("COMPONENTS", pc->components); + if (pc->extrapackages) xsetenv("EXTRAPACKAGES", pc->extrapackages); + if (pc->othermirror) xsetenv("OTHERMIRROR", pc->othermirror); + if (pc->hookdir) xsetenv("HOOKDIR", pc->hookdir); + if (pc->debbuildopts) xsetenv("DEBBUILDOPTS", pc->debbuildopts); + if (pc->binary_arch == 1 && pc->binary_indep == 0) { + xsetenv("BINARY_ARCH", "binary"); + } else if (pc->binary_arch == 0 && pc->binary_indep == 1) { + xsetenv("BINARY_ARCH", "all"); + } + if (pc->http_proxy) xsetenv("HTTP_PROXY", pc->http_proxy); + xsetenv("ALLOWUNTRUSTED", pc->allow_untrusted ? "yes" : "no"); + itoa(buf, sizeof(buf), pc->buildresultuid); + xsetenv("BUILDRESULTUID", buf); + itoa(buf, sizeof(buf), pc->buildresultgid); + xsetenv("BUILDRESULTGID", buf); + if (pc->no_cowdancer_update) xsetenv("NO_COWDANCER_UPDATE", "1"); + if (pc->debian_etch_workaround) xsetenv("DEBIAN_ETCH_WORKAROUND", "1"); + if (pc->kernel_image) xsetenv("KERNEL_IMAGE", pc->kernel_image); + if (pc->initrd) xsetenv("INITRD", pc->initrd); + if (pc->smp) xsetenv("SMP", pc->smp); + itoa(buf, sizeof(buf), pc->memory_megs); + xsetenv("MEMORY_MEGS", buf); + if (pc->arch) xsetenv("ARCHITECTURE", pc->arch); + if (pc->arch_diskdevice) xsetenv("ARCH_DISKDEVICE", pc->arch_diskdevice); +} + struct pbuilder_operation_arg { const char *arg; enum pbuilder_operation operation; @@ -132,8 +209,16 @@ int load_config_file(const char *config, pbuilderconfig *pc) { char *delim; int result; + char **environ_backup = environ; + environ = deep_copy_environ(); + update_environ(pc); + asprintf(&s, "env bash -c 'set -e ; . %s; set ' 2>&1", config); f = popen(s, "r"); + + free_environ(environ); + environ = environ_backup; + if (NULL == f) { return -1; } diff --git a/parameter.h b/parameter.h index 4984946..f66096a 100644 --- a/parameter.h +++ b/parameter.h @@ -36,7 +36,7 @@ enum pbuilder_operation { }; typedef struct pbuilderconfig { - /* if you edit here, please add to parameter.c: dumpconfig */ + /* if you edit here, please add to parameter.c: dumpconfig and update_environ */ int save_after_login; int debug; char *buildplace; /* /var/cache/pbuilder/build/XXX.$$ */ diff --git a/test_parameter.c b/test_parameter.c index a8cb75b..08fa914 100644 --- a/test_parameter.c +++ b/test_parameter.c @@ -52,15 +52,25 @@ void test_size_of_ntarray() { Test handling of quoted parameter string. */ void test_load_quoted_config() { - pbuilderconfig pc; + pbuilderconfig pc = {}; assert(0 == load_config_file( "tests/102_test_cowbuilder_debbuildopts.config", &pc)); assert(!strcmp("-j2 -I", pc.debbuildopts)); assert(!strcmp("/boot/vmlinuz-x.y.z", pc.kernel_image)); } +void test_propagate_across_pbuilderrc() { + pbuilderconfig pc = {}; + assert(0 == load_config_file( + "test_parameter_propagate_across_pbuilder_a.config", &pc)); + assert(0 == load_config_file( + "test_parameter_propagate_across_pbuilder_b.config", &pc)); + assert(!strcmp("a_b", pc.buildplace)); +} + int main() { test_size_of_ntarray(); test_load_quoted_config(); + test_propagate_across_pbuilderrc(); return 0; } diff --git a/test_parameter_propagate_across_pbuilder_a.config b/test_parameter_propagate_across_pbuilder_a.config new file mode 100644 index 0000000..918615e --- /dev/null +++ b/test_parameter_propagate_across_pbuilder_a.config @@ -0,0 +1 @@ +BUILDPLACE=a diff --git a/test_parameter_propagate_across_pbuilder_b.config b/test_parameter_propagate_across_pbuilder_b.config new file mode 100644 index 0000000..4f836bb --- /dev/null +++ b/test_parameter_propagate_across_pbuilder_b.config @@ -0,0 +1 @@ +BUILDPLACE=${BUILDPLACE}_b -- GitLab