aboutsummaryrefslogtreecommitdiff
path: root/win32
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2019-03-28 12:52:44 +0000
committerRon Yorston <rmy@pobox.com>2019-03-28 13:09:50 +0000
commit548ec7045bc7c80eaf03e92f390d1da2c9e9cd86 (patch)
treeb4c0102539c8889eeeec9eef8afa863510c7592b /win32
parent215e01e70f13f28d1a4dbe297f095b25de04ee21 (diff)
downloadbusybox-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.c56
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
1648char *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
1663int 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 */
1686char *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}