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 /win32 | |
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.
Diffstat (limited to 'win32')
-rw-r--r-- | win32/mingw.c | 56 |
1 files changed, 56 insertions, 0 deletions
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 | } | ||