diff options
| author | Ron Yorston <rmy@pobox.com> | 2019-03-28 12:52:44 +0000 |
|---|---|---|
| committer | Ron Yorston <rmy@pobox.com> | 2019-03-28 13:09:50 +0000 |
| commit | 548ec7045bc7c80eaf03e92f390d1da2c9e9cd86 (patch) | |
| tree | b4c0102539c8889eeeec9eef8afa863510c7592b | |
| parent | 215e01e70f13f28d1a4dbe297f095b25de04ee21 (diff) | |
| download | busybox-w32-548ec7045bc7c80eaf03e92f390d1da2c9e9cd86.tar.gz busybox-w32-548ec7045bc7c80eaf03e92f390d1da2c9e9cd86.tar.bz2 busybox-w32-548ec7045bc7c80eaf03e92f390d1da2c9e9cd86.zip | |
win32: interpret absolute paths as relative to %SYSTEMDRIVE%
BusyBox contains hardcoded references to absolute paths which
are unique in the *nix world but on Microsoft Windows are
interpreted as being on the current drive. To make these unique
again consider them to be relative to %SYSTEMDRIVE%.
Support this by adding functions to:
- determine the system drive (not using the environment variable);
- change a process's current directory to the root of the system drive;
- make relative paths absolute before changing directory (if needed).
The following applications have been modified:
- ash references /etc/profile from the system drive;
- dpkg places its data store on and installs files to the system drive;
- rpm installs files to the system drive;
- man looks for configuration files and man pages on the system drive.
See GitHub issue #158.
| -rw-r--r-- | archival/dpkg.c | 24 | ||||
| -rw-r--r-- | archival/rpm.c | 3 | ||||
| -rw-r--r-- | include/mingw.h | 3 | ||||
| -rw-r--r-- | miscutils/man.c | 14 | ||||
| -rw-r--r-- | shell/ash.c | 13 | ||||
| -rw-r--r-- | win32/mingw.c | 56 |
6 files changed, 112 insertions, 1 deletions
diff --git a/archival/dpkg.c b/archival/dpkg.c index 8b25cfd47..08f15ad44 100644 --- a/archival/dpkg.c +++ b/archival/dpkg.c | |||
| @@ -1752,6 +1752,10 @@ int dpkg_main(int argc UNUSED_PARAM, char **argv) | |||
| 1752 | int state_status; | 1752 | int state_status; |
| 1753 | int status_num; | 1753 | int status_num; |
| 1754 | int i; | 1754 | int i; |
| 1755 | #if ENABLE_PLATFORM_MINGW32 | ||
| 1756 | char **ptr, *path; | ||
| 1757 | int fd; | ||
| 1758 | #endif | ||
| 1755 | #if ENABLE_LONG_OPTS | 1759 | #if ENABLE_LONG_OPTS |
| 1756 | static const char dpkg_longopts[] ALIGN1 = | 1760 | static const char dpkg_longopts[] ALIGN1 = |
| 1757 | // FIXME: we use -C non-compatibly, should be: | 1761 | // FIXME: we use -C non-compatibly, should be: |
| @@ -1796,6 +1800,26 @@ int dpkg_main(int argc UNUSED_PARAM, char **argv) | |||
| 1796 | bb_show_usage(); | 1800 | bb_show_usage(); |
| 1797 | } | 1801 | } |
| 1798 | 1802 | ||
| 1803 | #if ENABLE_PLATFORM_MINGW32 | ||
| 1804 | if (opt & OPT_install) { | ||
| 1805 | /* add system drive prefix to filenames, if necessary */ | ||
| 1806 | for (ptr = argv; *ptr; ++ptr) { | ||
| 1807 | *ptr = xabsolute_path(*ptr); | ||
| 1808 | } | ||
| 1809 | } | ||
| 1810 | |||
| 1811 | chdir_system_drive(); | ||
| 1812 | |||
| 1813 | /* initialise data store */ | ||
| 1814 | path = xstrdup("/var/lib/dpkg/info"); | ||
| 1815 | bb_make_directory(path, -1, FILEUTILS_RECUR); | ||
| 1816 | free(path); | ||
| 1817 | |||
| 1818 | fd = open("/var/lib/dpkg/status", O_RDWR|O_CREAT, 0666); | ||
| 1819 | if (fd >= 0) | ||
| 1820 | xclose(fd); | ||
| 1821 | #endif | ||
| 1822 | |||
| 1799 | /* puts("(Reading database ... xxxxx files and directories installed.)"); */ | 1823 | /* puts("(Reading database ... xxxxx files and directories installed.)"); */ |
| 1800 | index_status_file("/var/lib/dpkg/status"); | 1824 | index_status_file("/var/lib/dpkg/status"); |
| 1801 | 1825 | ||
diff --git a/archival/rpm.c b/archival/rpm.c index 3dd4d4777..c9e8785e2 100644 --- a/archival/rpm.c +++ b/archival/rpm.c | |||
| @@ -303,6 +303,9 @@ static void extract_cpio(int fd, const char *source_rpm) | |||
| 303 | 303 | ||
| 304 | if (source_rpm != NULL) { | 304 | if (source_rpm != NULL) { |
| 305 | /* Binary rpm (it was built from some SRPM), install to root */ | 305 | /* Binary rpm (it was built from some SRPM), install to root */ |
| 306 | #if ENABLE_PLATFORM_MINGW32 | ||
| 307 | if (chdir_system_drive()) | ||
| 308 | #endif | ||
| 306 | xchdir("/"); | 309 | xchdir("/"); |
| 307 | } /* else: SRPM, install to current dir */ | 310 | } /* else: SRPM, install to current dir */ |
| 308 | 311 | ||
diff --git a/include/mingw.h b/include/mingw.h index 7c9423cad..d77a9beb9 100644 --- a/include/mingw.h +++ b/include/mingw.h | |||
| @@ -525,3 +525,6 @@ void hide_console(void); | |||
| 525 | 525 | ||
| 526 | int unc_root_len(const char *dir); | 526 | int unc_root_len(const char *dir); |
| 527 | int root_len(const char *path); | 527 | int root_len(const char *path); |
| 528 | char *get_system_drive(void); | ||
| 529 | int chdir_system_drive(void); | ||
| 530 | char *xabsolute_path(char *path); | ||
diff --git a/miscutils/man.c b/miscutils/man.c index 3c1a79085..0bc11e623 100644 --- a/miscutils/man.c +++ b/miscutils/man.c | |||
| @@ -253,11 +253,22 @@ int man_main(int argc UNUSED_PARAM, char **argv) | |||
| 253 | int cur_mp; | 253 | int cur_mp; |
| 254 | int opt, not_found; | 254 | int opt, not_found; |
| 255 | char *token[2]; | 255 | char *token[2]; |
| 256 | #if ENABLE_PLATFORM_MINGW32 | ||
| 257 | char **ptr; | ||
| 258 | #endif | ||
| 256 | 259 | ||
| 257 | INIT_G(); | 260 | INIT_G(); |
| 258 | 261 | ||
| 259 | opt = getopt32(argv, "^+" "aw" "\0" "-1"/*at least one arg*/); | 262 | opt = getopt32(argv, "^+" "aw" "\0" "-1"/*at least one arg*/); |
| 260 | argv += optind; | 263 | argv += optind; |
| 264 | #if ENABLE_PLATFORM_MINGW32 | ||
| 265 | /* add system drive prefix to filenames, if necessary */ | ||
| 266 | for (ptr = argv; *ptr; ++ptr) { | ||
| 267 | if (strchr(*ptr, '/') || strchr(*ptr, '\\')) | ||
| 268 | *ptr = xabsolute_path(*ptr); | ||
| 269 | } | ||
| 270 | chdir_system_drive(); | ||
| 271 | #endif | ||
| 261 | 272 | ||
| 262 | sec_list = xstrdup("0p:1:1p:2:3:3p:4:5:6:7:8:9"); | 273 | sec_list = xstrdup("0p:1:1p:2:3:3p:4:5:6:7:8:9"); |
| 263 | 274 | ||
| @@ -311,7 +322,8 @@ int man_main(int argc UNUSED_PARAM, char **argv) | |||
| 311 | char *relpath = concat_path_file(dirname(exepath), "man"); | 322 | char *relpath = concat_path_file(dirname(exepath), "man"); |
| 312 | if (count_mp == 0) { | 323 | if (count_mp == 0) { |
| 313 | /* default must match path set above */ | 324 | /* default must match path set above */ |
| 314 | man_path_list = add_MANPATH(man_path_list, &count_mp, "/usr/man"); | 325 | man_path_list = add_MANPATH(man_path_list, &count_mp, |
| 326 | (char *)"/usr/man"); | ||
| 315 | } | 327 | } |
| 316 | man_path_list = add_MANPATH(man_path_list, &count_mp, relpath); | 328 | man_path_list = add_MANPATH(man_path_list, &count_mp, relpath); |
| 317 | free(relpath); | 329 | free(relpath); |
diff --git a/shell/ash.c b/shell/ash.c index 34ddc14f1..40965bafa 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
| @@ -14906,6 +14906,9 @@ int ash_main(int argc UNUSED_PARAM, char **argv) | |||
| 14906 | struct jmploc jmploc; | 14906 | struct jmploc jmploc; |
| 14907 | struct stackmark smark; | 14907 | struct stackmark smark; |
| 14908 | int login_sh; | 14908 | int login_sh; |
| 14909 | #if ENABLE_PLATFORM_MINGW32 | ||
| 14910 | char *sd; | ||
| 14911 | #endif | ||
| 14909 | 14912 | ||
| 14910 | /* Initialize global data */ | 14913 | /* Initialize global data */ |
| 14911 | INIT_G_misc(); | 14914 | INIT_G_misc(); |
| @@ -15014,6 +15017,16 @@ int ash_main(int argc UNUSED_PARAM, char **argv) | |||
| 15014 | #endif | 15017 | #endif |
| 15015 | 15018 | ||
| 15016 | state = 1; | 15019 | state = 1; |
| 15020 | #if ENABLE_PLATFORM_MINGW32 | ||
| 15021 | sd = get_system_drive(); | ||
| 15022 | if (sd) { | ||
| 15023 | char *path = xasprintf("%s/etc/profile", sd); | ||
| 15024 | read_profile(path); | ||
| 15025 | free(sd); | ||
| 15026 | free(path); | ||
| 15027 | } | ||
| 15028 | else | ||
| 15029 | #endif | ||
| 15017 | read_profile("/etc/profile"); | 15030 | read_profile("/etc/profile"); |
| 15018 | state1: | 15031 | state1: |
| 15019 | state = 2; | 15032 | state = 2; |
diff --git a/win32/mingw.c b/win32/mingw.c index 3ee1a2496..1d5644f92 100644 --- a/win32/mingw.c +++ b/win32/mingw.c | |||
| @@ -1644,3 +1644,59 @@ int root_len(const char *path) | |||
| 1644 | return 2; | 1644 | return 2; |
| 1645 | return unc_root_len(path); | 1645 | return unc_root_len(path); |
| 1646 | } | 1646 | } |
| 1647 | |||
| 1648 | char *get_system_drive(void) | ||
| 1649 | { | ||
| 1650 | struct passwd *pwd; | ||
| 1651 | char *drive = NULL; | ||
| 1652 | int len; | ||
| 1653 | |||
| 1654 | pwd = getpwuid(0); | ||
| 1655 | if (pwd != NULL && (len=root_len(pwd->pw_dir))) { | ||
| 1656 | drive = xstrdup(pwd->pw_dir); | ||
| 1657 | drive[len] = '\0'; | ||
| 1658 | } | ||
| 1659 | |||
| 1660 | return drive; | ||
| 1661 | } | ||
| 1662 | |||
| 1663 | int chdir_system_drive(void) | ||
| 1664 | { | ||
| 1665 | char *sd = get_system_drive(); | ||
| 1666 | int ret = -1; | ||
| 1667 | |||
| 1668 | if (sd) { | ||
| 1669 | strcat(sd, "/"); | ||
| 1670 | ret = chdir(sd); | ||
| 1671 | } | ||
| 1672 | free(sd); | ||
| 1673 | return ret; | ||
| 1674 | } | ||
| 1675 | |||
| 1676 | /* | ||
| 1677 | * This function is used to make relative paths absolute before a call | ||
| 1678 | * to chdir_system_drive(). It's unlikely to be useful in other cases. | ||
| 1679 | * | ||
| 1680 | * If the argument is an absolute path or a relative path which resolves | ||
| 1681 | * to a path on the system drive return 'path'. If it's a relative path | ||
| 1682 | * which resolves to a path that isn't on the system drive return an | ||
| 1683 | * allocated string containing the resolved path. Die on failure, | ||
| 1684 | * which is most likely because the file doesn't exist. | ||
| 1685 | */ | ||
| 1686 | char *xabsolute_path(char *path) | ||
| 1687 | { | ||
| 1688 | char *rpath, *sd; | ||
| 1689 | |||
| 1690 | if (root_len(path) != 0) | ||
| 1691 | return path; // absolute path | ||
| 1692 | rpath = xmalloc_realpath(path); | ||
| 1693 | if (rpath) { | ||
| 1694 | sd = auto_string(get_system_drive()); | ||
| 1695 | if (sd && is_prefixed_with_case(rpath, sd)) { | ||
| 1696 | free(rpath); | ||
| 1697 | return path; // resolved path is on system drive | ||
| 1698 | } | ||
| 1699 | return rpath; | ||
| 1700 | } | ||
| 1701 | bb_perror_msg_and_die("can't open '%s'", path); | ||
| 1702 | } | ||
