diff --git a/bin/loader.cpp b/bin/loader.cpp index 6f066e3..c28c9ba 100644 --- a/bin/loader.cpp +++ b/bin/loader.cpp @@ -454,11 +454,9 @@ std::string find_exe(const std::string &name) // if name is a path, then it doesn't exist. if (name.find('/') != name.npos) return std::string(); + std::string path = MPW::RootDir(); + if (path.empty()) return path; - const char *mpw = getenv("MPW"); - if (!mpw || !*mpw) return std::string(); - - std::string path(mpw); if (path.back() != '/') path.push_back('/'); path.append("Tools/"); @@ -468,47 +466,6 @@ std::string find_exe(const std::string &name) return std::string(); - - -#if 0 - std::string subpath; - // check in $MPW/name. - const char *cpath = getenv("mpw_path"); - if (!cpath) return std::string(); - - path = cpath; - // split on : - - if (path.empty()) return std::string(); - - int start = 0, end = 0; - - while ((end = path.find(':', start)) != path.npos) - { - subpath = path.substr(start, end - start); - - if (subpath.length()) - { - subpath.push_back('/'); - subpath.append(name); - - if (file_exists(subpath)) return subpath; - } - - start = end + 1; - } - - subpath = path.substr(start); - if (subpath.length()) - { - subpath.push_back('/'); - subpath.append(name); - - if (file_exists(subpath)) return subpath; - } - - return std::string(); -#endif } diff --git a/mpw/mpw.cpp b/mpw/mpw.cpp index 74bc03e..c66b37a 100644 --- a/mpw/mpw.cpp +++ b/mpw/mpw.cpp @@ -14,6 +14,8 @@ #include #include #include +#include +#include #include #include @@ -91,6 +93,100 @@ namespace MPW } + static bool isdir(const std::string &path) + { + struct stat st; + if (stat(path.c_str(), &st) < 0) return false; + return S_ISDIR(st.st_mode); + } + + const std::string RootDir() + { + static bool initialized = false; + static std::string path; + + static const std::string paths[] = { + "/usr/local/share/mpw", + "/usr/share/mpw", + }; + + char *cp; + struct passwd *pw; + + if (initialized) return path; + + initialized = true; + + // check $MPW, $HOME/mpw, /usr/local/share/mpw/, /usr/share/mpw + // for a directory. + + cp = getenv("MPW"); + if (cp && *cp) + { + std::string s(cp); + if (isdir(s)) + { + path = std::move(s); + return path; + } + } + + // home/mpw + pw = getpwuid(getuid()); + if (pw && pw->pw_dir && pw->pw_dir[0]) + { + std::string s(pw->pw_dir); + if (s.back() != '/') s.push_back('/'); + s.append("mpw"); + + if (isdir(s)) + { + path = std::move(s); + return path; + } + } +#if 0 + // thread-safe + { + int size; + + size = sysconf(_SC_GETPW_R_SIZE_MAX); + if (size >= 0) + { + struct passwd pwd, *result = nullptr; + char *buffer = alloca(size); + + if (getpwuid_r(getuid(), &pwd, buffer, size, &result) == 0 && result) + { + std::string s(pwd.pw_dir); + if (s.back() != '/') s.push_back('/'); + s.append("mpw"); + if (isdir(s)) + { + path = std::move(s); + return path; + } + } + } + } +#endif + for (auto &iter : paths) + { + if (isdir(iter)) + { + path = iter; + return path; + } + + } + + + + return path; // unknown. + } + + + uint16_t Init(int argc, char **argv) { /* @@ -194,20 +290,18 @@ namespace MPW { std::unordered_map env; - const char *mpw = getenv("MPW"); - if (mpw && *mpw) + std::string m(RootDir()); + if (!m.empty()) { - std::string m(mpw); - m = ToolBox::UnixToMac(m); - if (m.back() != ':') m.push_back(':'); + std::string mm = ToolBox::UnixToMac(m); + if (mm.back() != ':') mm.push_back(':'); - env.emplace(std::string("MPW"), m); + env.emplace(std::string("MPW"), mm); } env.emplace(std::string("Command"), command); - if (mpw && *mpw) + if (!m.empty()) { - std::string m(mpw); void LoadEnvironment(std::string &envfile, std::unordered_map &env); diff --git a/mpw/mpw.h b/mpw/mpw.h index ef55c43..5a56611 100644 --- a/mpw/mpw.h +++ b/mpw/mpw.h @@ -2,6 +2,7 @@ #define __mpw_mpw_h__ #include +#include namespace MPW { @@ -91,6 +92,7 @@ namespace MPW { }; + const std::string RootDir(); // should add argc/argv/envp... uint16_t Init(int argc, char **argv);