aboutsummaryrefslogtreecommitdiff
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
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.
-rw-r--r--archival/dpkg.c24
-rw-r--r--archival/rpm.c3
-rw-r--r--include/mingw.h3
-rw-r--r--miscutils/man.c14
-rw-r--r--shell/ash.c13
-rw-r--r--win32/mingw.c56
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
526int unc_root_len(const char *dir); 526int unc_root_len(const char *dir);
527int root_len(const char *path); 527int root_len(const char *path);
528char *get_system_drive(void);
529int chdir_system_drive(void);
530char *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
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}