retitle 546528 dash's preinst shouldn't rely on /bin/sh tag 546528 +patch thanks
* Matthias Klose <d...@debian.org> [2009-10-22 20:08]: > changing that to a pre-dependency, but dash's preinst shouldn't rely > on /bin/sh. bash's preinst is a C binary for that reason. Here's a patch that makes dash's preinst a C binary too. Regards David --- debian/dash.preinst | 32 ---------- debian/dash.preinst.c | 151 +++++++++++++++++++++++++++++++++++++++++++++++++ debian/rules | 7 ++- 3 files changed, 157 insertions(+), 33 deletions(-) delete mode 100644 debian/dash.preinst create mode 100644 debian/dash.preinst.c diff --git a/debian/dash.preinst b/debian/dash.preinst deleted file mode 100644 index 6be584d..0000000 --- a/debian/dash.preinst +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/sh -set -e - -divert() { - div=$(dpkg-divert --list $1) - distrib=${3:-$1.distrib} - if [ -z "$div" ]; then - dpkg-divert --package dash --divert $distrib --add $1 - cp -dp $1 $distrib - ln -sf $2 $1 - fi -} - -divert /bin/sh dash -divert /usr/share/man/man1/sh.1.gz dash.1.gz \ - /usr/share/man/man1/sh.distrib.1.gz -#!/bin/sh -set -e - -divert() { - div=$(dpkg-divert --list $1) - distrib=${3:-$1.distrib} - if [ -z "$div" ]; then - dpkg-divert --package dash --divert $distrib --add $1 - cp -dp $1 $distrib - ln -sf $2 $1 - fi -} - -divert /bin/sh dash -divert /usr/share/man/man1/sh.1.gz dash.1.gz \ - /usr/share/man/man1/sh.distrib.1.gz diff --git a/debian/dash.preinst.c b/debian/dash.preinst.c new file mode 100644 index 0000000..cf32596 --- /dev/null +++ b/debian/dash.preinst.c @@ -0,0 +1,151 @@ +/* Copyright (c) 2009 David Riebenbuaer <davr...@liegesta.at> + * + * You may freely use, distribute, and modify this program. + */ + +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <err.h> +#include <errno.h> +#include <error.h> + +#define DPKG_DIVERT "/usr/bin/dpkg-divert" +#define LINE_LEN 1024 + +void run_op(const char *const op[]) +{ + pid_t child; + + switch (child = fork()) { + case -1: + // fork failed + { + err(EXIT_FAILURE, "fork failed"); + } + + + case 0: + // child + { + execvp(op[0], (char *const *)(op)); + + err(EXIT_FAILURE, "failed to exec %s", op[0]); + } + + + default: + // parent + { + int status; + pid_t pid; + + pid = waitpid(child, &status, 0); + + if (pid != -1) { + if (WIFEXITED(status)) { + if (WEXITSTATUS(status) == 0) { + return; + } + else { + exit(WEXITSTATUS(status)); + } + } + else { + fprintf(stderr, "child didn't exit normally"); + exit(EXIT_FAILURE); + } + } + else { + err(EXIT_FAILURE, "wait failed"); + } + + break; + } + } +} + +void divert(const char *target, const char *source, const char *distrib) +{ + pid_t child; + int pipedes[2]; + static char line[LINE_LEN]; + + memset(line, '\0', LINE_LEN); + + if (pipe(pipedes)) { + err(EXIT_FAILURE, "pipe creation failed"); + } + + switch(child = fork()) { + case -1: + // fork failed + { + int errnum = errno; + + close(pipedes[0]); + close(pipedes[1]); + error(EXIT_FAILURE, errnum, "fork failed"); + } + + + case 0: + // child + { + if (dup2(pipedes[STDOUT_FILENO], STDOUT_FILENO) < 0) { + err(EXIT_FAILURE, "replacing stdout with pipe failed"); + } + + close(pipedes[STDIN_FILENO]); + close(pipedes[STDOUT_FILENO]); + + execlp(DPKG_DIVERT, DPKG_DIVERT, "--list", target, NULL); + + err(EXIT_FAILURE, "dpkg-divert exec failed"); + } + + + default: + // parent + { + FILE *fd; + + close(pipedes[STDOUT_FILENO]); + fcntl(pipedes[STDIN_FILENO], F_SETFD, FD_CLOEXEC); + fd = fdopen(pipedes[STDIN_FILENO], "r"); + + while (fgets(line, LINE_LEN, fd) != NULL) { + line[strlen(line)-1] = '\0'; + break; + } + fclose(fd); + + break; + } + } + + if (strlen(line) == 0) { + const char *const dpkg_divert_op[] = {DPKG_DIVERT, "--package", "dash", + "--divert", distrib, "--add", target, NULL}; + const char *const cp_op[] = {"cp", "-pd", target, distrib, NULL}; + const char *const ln_op[] = {"ln", "-fs", source, target, NULL}; + + run_op(dpkg_divert_op); + run_op(cp_op); + run_op(ln_op); + } +} + +int main(void) +{ + divert("/bin/sh", "dash", "/bin/sh.distrib"); + divert("/usr/share/man/man1/sh.1.gz", "dash.1.gz", + "/usr/share/man/man1/sh.distrib.1.gz"); + + return EXIT_SUCCESS; +} + diff --git a/debian/rules b/debian/rules index b5f6d7f..c67b3e2 100755 --- a/debian/rules +++ b/debian/rules @@ -36,7 +36,7 @@ configure-stamp: patch-stamp exec ../configure --host='$(DEB_HOST_GNU_TYPE)') touch configure-stamp -build: deb-checkdir build-stamp +build: preinst-build deb-checkdir build-stamp build-stamp: configure-stamp -$(CC) -v (cd build-tmp && exec $(MAKE) CFLAGS='$(CFLAGS)') || \ @@ -55,6 +55,11 @@ clean: deb-checkdir deb-checkuid rm -f configure-stamp patch-stamp build-stamp po-templates-stamp rm -rf '$(DIR)' '$(DIRA)' rm -f debian/files debian/substvars debian/dash.templates changelog + rm -f debian/dash.preinst + +preinst-build: debian/dash.preinst +debian/dash.preinst: debian/dash.preinst.c + $(CC) -O2 -s -o debian/dash.preinst debian/dash.preinst.c install: install-indep install-arch install-indep: deb-checkdir deb-checkuid -- To UNSUBSCRIBE, email to debian-bugs-rc-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org