1 /* Copyright (c) 1999 Anthony Towns
2 * Copyright (c) 2000 Matthias Klose
4 * You may freely use, distribute, and modify this program.
7 // Don't rely on /bin/sh and popen!
16 #include <sys/types.h>
19 /* XXX: evil kludge, deal with arbitrary name lengths */
24 int myexec(char *cmd, ...)
32 new_argv[new_argc++] = cmd;
34 while ((new_argv[new_argc++] = va_arg(ap, char *)));
37 switch(child = fork()) {
56 if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
65 int check_predepends(void)
67 return myexec("/usr/bin/dpkg", "--assert-support-predepends", NULL);
70 int dpkg_compare_versions(char *v1, char *op, char *v2)
72 return myexec("/usr/bin/dpkg", "--compare-versions", v1, op, v2, NULL);
75 int dpkg_divert_add(char *pkg, char *file)
77 return myexec("/usr/sbin/dpkg-divert", "--package", pkg, "--add", file, NULL);
80 char *check_diversion(char *diversion_name)
89 switch(child = fork()) {
99 if (dup2(pipedes[STDOUT_FILENO], STDOUT_FILENO) < 0)
101 close(pipedes[STDIN_FILENO]);
102 close(pipedes[STDOUT_FILENO]);
103 execl( "/usr/sbin/dpkg-divert", "/usr/sbin/dpkg-divert",
104 "--list", diversion_name, NULL );
111 static char line[1024];
114 close (pipedes[STDOUT_FILENO]);
115 fcntl (pipedes[STDIN_FILENO], F_SETFD, FD_CLOEXEC);
116 fd = fdopen (pipedes[STDIN_FILENO], "r");
118 while (fgets(line, 1024, fd) != NULL) {
119 line[strlen(line)-1] = '\0';
129 #define FIRST_WITHOUT_SHLINK "2.05b-4"
132 "As bash for Debian is destined to provide a working /bin/sh (pointing to\n"
133 "/bin/bash) your link will be overwritten by a default link.\n\n"
134 "If you don't want further upgrades to overwrite your customization,\n"
135 "please read /usr/share/doc/bash/README.Debian for a more permanent solution.\n\n"
136 "[Press RETURN to continue]";
138 int main(int argc, char *argv[]) {
140 char target[PATH_MAX+1], answer[1024];
143 printf("\nbash/preinst: expected at least one argument\n\n");
147 if (check_predepends() != EXIT_SUCCESS) {
148 printf("\nPlease upgrade to a new version of dpkg\n\n");
153 if [ "$1" = upgrade ] && dpkg --compare-versions "$2" lt FIRST_WITHOUT_SHLINK; then
154 div=$(dpkg-divert --list /bin/sh)
155 if [ -z "$div" ]; then
156 dpkg-divert --package bash --add /bin/sh
159 div=$(dpkg-divert --list /usr/share/man/man1/sh.1.gz)
160 if [ -z "$div" ]; then
161 dpkg-divert --package bash --add /usr/share/man/man1/sh.1.gz
162 ln -sf dash.1.gz /usr/share/man/man1/sh.1.gz
167 if (strcmp(argv[1], "upgrade") == 0) {
169 printf("\nbash/preinst upgrade: expected at least two arguments\n\n");
172 if (dpkg_compare_versions(argv[2], "lt", FIRST_WITHOUT_SHLINK) == EXIT_SUCCESS) {
173 char *diversion = check_diversion("/bin/sh");
175 if (diversion == NULL)
177 // printf("diversion: /%s/\n", diversion);
178 if (strcmp(diversion, "") == 0) {
179 // link is not diverted
180 dpkg_divert_add("bash", "/bin/sh");
183 symlink("dash", "/bin/sh");
186 diversion = check_diversion("/usr/share/man/man1/sh.1.gz");
188 if (diversion == NULL)
190 // printf("diversion: /%s/\n", diversion);
191 if (strcmp(diversion, "") == 0) {
192 // link is not diverted
193 dpkg_divert_add("bash", "/usr/share/man/man1/sh.1.gz");
195 unlink("/usr/share/man/man1/sh.1.gz");
196 symlink("dash.1.gz", "/usr/share/man/man1/sh.1.gz");
203 targetlen = readlink("/bin/sh", target, PATH_MAX);
204 if (targetlen == -1) {
205 // error reading link. Will be overwritten.
206 puts("The bash upgrade discovered that something is wrong with your /bin/sh link.");
208 fgets(answer, 1024, stdin);
211 target[targetlen] = '\0';
212 if (strcmp(target, "bash") != 0 && strcmp(target, "/bin/bash") != 0) {
213 char *diversion = check_diversion("/bin/sh");
215 if (diversion == NULL)
217 // printf("diversion: /%s/\n", diversion);
218 if (strcmp(diversion, "") != 0)
221 printf("The bash upgrade discovered that your /bin/sh link points to %s.\n", target);
223 fgets(answer, 1024, stdin);