diff --git a/sphaira/include/fs.hpp b/sphaira/include/fs.hpp index 6ba086b..5b7f75c 100644 --- a/sphaira/include/fs.hpp +++ b/sphaira/include/fs.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include "defines.hpp" namespace fs { @@ -168,7 +169,7 @@ struct FsPath { return path[0] == str[0]; } - char s[FS_MAX_PATH]{}; + char s[PATH_MAX]{}; }; inline FsPath operator+(const char* v, const FsPath& fp) { @@ -187,8 +188,12 @@ inline FsPath operator+(const std::string_view& v, const FsPath& fp) { } // Fs seems to be limted to file paths of 255 characters. +// i've disabled this as network mounts will often have very long paths +// that do not have this limit. +// a proper fix would be to return an error if the path is too long and the path +// is native. struct FsPathReal { - static constexpr inline size_t FS_REAL_MAX_LENGTH = 255; + static constexpr inline size_t FS_REAL_MAX_LENGTH = PATH_MAX; constexpr FsPathReal(const FsPath& str) : FsPathReal{str.s} { } explicit constexpr FsPathReal(const char* str) { @@ -215,7 +220,7 @@ struct FsPathReal { constexpr operator const char*() const { return s; } constexpr operator std::string_view() const { return s; } - char s[FS_MAX_PATH]; + char s[PATH_MAX]; }; // fwd diff --git a/sphaira/include/swkbd.hpp b/sphaira/include/swkbd.hpp index 346204c..0255292 100644 --- a/sphaira/include/swkbd.hpp +++ b/sphaira/include/swkbd.hpp @@ -2,10 +2,11 @@ #include #include +#include namespace sphaira::swkbd { -Result ShowText(std::string& out, const char* guide = nullptr, const char* initial = nullptr, s64 len_min = -1, s64 len_max = FS_MAX_PATH); -Result ShowNumPad(s64& out, const char* guide = nullptr, const char* initial = nullptr, s64 len_min = -1, s64 len_max = FS_MAX_PATH); +Result ShowText(std::string& out, const char* guide = nullptr, const char* initial = nullptr, s64 len_min = -1, s64 len_max = PATH_MAX); +Result ShowNumPad(s64& out, const char* guide = nullptr, const char* initial = nullptr, s64 len_min = -1, s64 len_max = PATH_MAX); } // namespace sphaira::swkbd diff --git a/sphaira/include/ui/sidebar.hpp b/sphaira/include/ui/sidebar.hpp index 1a98a3d..60f875c 100644 --- a/sphaira/include/ui/sidebar.hpp +++ b/sphaira/include/ui/sidebar.hpp @@ -7,6 +7,7 @@ #include #include #include +#include namespace sphaira::ui { @@ -174,7 +175,7 @@ private: class SidebarEntryTextInput final : public SidebarEntryTextBase { public: - explicit SidebarEntryTextInput(const std::string& title, const std::string& value, const std::string& guide = {}, s64 len_min = -1, s64 len_max = FS_MAX_PATH, const std::string& info = ""); + explicit SidebarEntryTextInput(const std::string& title, const std::string& value, const std::string& guide = {}, s64 len_min = -1, s64 len_max = PATH_MAX, const std::string& info = ""); private: const std::string m_guide; diff --git a/sphaira/source/option.cpp b/sphaira/source/option.cpp index cec5ec0..bb77876 100644 --- a/sphaira/source/option.cpp +++ b/sphaira/source/option.cpp @@ -20,7 +20,7 @@ auto OptionBase::GetInternal(const char* name) -> T { } else if constexpr(std::is_same_v) { m_value = ini_getf(m_section.c_str(), name, m_default_value, App::CONFIG_PATH); } else if constexpr(std::is_same_v) { - char buf[FS_MAX_PATH]; + char buf[PATH_MAX]{}; ini_gets(m_section.c_str(), name, m_default_value.c_str(), buf, sizeof(buf), App::CONFIG_PATH); m_value = buf; } diff --git a/sphaira/source/swkbd.cpp b/sphaira/source/swkbd.cpp index b5be771..37717ee 100644 --- a/sphaira/source/swkbd.cpp +++ b/sphaira/source/swkbd.cpp @@ -6,7 +6,7 @@ namespace sphaira::swkbd { namespace { struct Config { - char out_text[FS_MAX_PATH]{}; + char out_text[PATH_MAX]{}; bool numpad{}; }; diff --git a/sphaira/source/utils/devoptab_bfsar.cpp b/sphaira/source/utils/devoptab_bfsar.cpp index 1fd95d8..4bc03c7 100644 --- a/sphaira/source/utils/devoptab_bfsar.cpp +++ b/sphaira/source/utils/devoptab_bfsar.cpp @@ -92,7 +92,7 @@ int devoptab_open(struct _reent *r, void *fileStruct, const char *_path, int fla auto file = static_cast(fileStruct); std::memset(file, 0, sizeof(*file)); - char path[FS_MAX_PATH]; + char path[PATH_MAX]; if (!common::fix_path(_path, path)) { return set_errno(r, ENOENT); } @@ -161,7 +161,7 @@ DIR_ITER* devoptab_diropen(struct _reent *r, DIR_ITER *dirState, const char *_pa auto dir = static_cast(dirState->dirStruct); std::memset(dir, 0, sizeof(*dir)); - char path[FS_MAX_PATH]; + char path[PATH_MAX]; if (!common::fix_path(_path, path)) { set_errno(r, ENOENT); return NULL; @@ -244,7 +244,7 @@ int devoptab_dirclose(struct _reent *r, DIR_ITER *dirState) { int devoptab_lstat(struct _reent *r, const char *_path, struct stat *st) { auto device = (Device*)r->deviceData; - char path[FS_MAX_PATH]; + char path[PATH_MAX]; if (!common::fix_path(_path, path)) { return set_errno(r, ENOENT); } diff --git a/sphaira/source/utils/devoptab_http.cpp b/sphaira/source/utils/devoptab_http.cpp index e6edb69..05c58cf 100644 --- a/sphaira/source/utils/devoptab_http.cpp +++ b/sphaira/source/utils/devoptab_http.cpp @@ -13,11 +13,14 @@ #include #include #include +#include #include namespace sphaira::devoptab { namespace { +constexpr int DEFAULT_HTTP_TIMEOUT = 3000; // 3 seconds. + #define CURL_EASY_SETOPT_LOG(handle, opt, v) \ if (auto r = curl_easy_setopt(handle, opt, v); r != CURLE_OK) { \ log_write("curl_easy_setopt(%s, %s) msg: %s\n", #opt, #v, curl_easy_strerror(r)); \ @@ -33,6 +36,8 @@ struct HttpMountConfig { std::string url{}; std::string user{}; std::string pass{}; + std::optional port{}; + int timeout{DEFAULT_HTTP_TIMEOUT}; }; using HttpMountConfigs = std::vector; @@ -128,9 +133,8 @@ std::string build_url(const std::string& base, const std::string& path, bool is_ void http_set_common_options(Device& client, const std::string& url) { curl_easy_reset(client.curl); CURL_EASY_SETOPT_LOG(client.curl, CURLOPT_URL, url.c_str()); - // todo: make the timeouts configurable. - CURL_EASY_SETOPT_LOG(client.curl, CURLOPT_TIMEOUT, 5L); - CURL_EASY_SETOPT_LOG(client.curl, CURLOPT_CONNECTTIMEOUT, 5L); + CURL_EASY_SETOPT_LOG(client.curl, CURLOPT_TIMEOUT, (long)client.config.timeout); + CURL_EASY_SETOPT_LOG(client.curl, CURLOPT_CONNECTTIMEOUT, (long)client.config.timeout); CURL_EASY_SETOPT_LOG(client.curl, CURLOPT_AUTOREFERER, 1L); CURL_EASY_SETOPT_LOG(client.curl, CURLOPT_FOLLOWLOCATION, 1L); CURL_EASY_SETOPT_LOG(client.curl, CURLOPT_SSL_VERIFYPEER, 0L); @@ -140,6 +144,10 @@ void http_set_common_options(Device& client, const std::string& url) { CURL_EASY_SETOPT_LOG(client.curl, CURLOPT_NOPROGRESS, 0L); CURL_EASY_SETOPT_LOG(client.curl, CURLOPT_BUFFERSIZE, 1024L * 512L); + if (client.config.port) { + CURL_EASY_SETOPT_LOG(client.curl, CURLOPT_PORT, (long)client.config.port.value()); + } + // enable all forms of compression supported by libcurl. CURL_EASY_SETOPT_LOG(client.curl, CURLOPT_ACCEPT_ENCODING, ""); @@ -345,10 +353,11 @@ int devoptab_open(struct _reent *r, void *fileStruct, const char *_path, int fla // todo: add this check to all devoptabs. if ((flags & O_ACCMODE) != O_RDONLY) { + log_write("[HTTP] Only read-only mode is supported\n"); return set_errno(r, EINVAL); } - char path[FS_MAX_PATH]{}; + char path[PATH_MAX]{}; if (!common::fix_path(_path, path)) { return set_errno(r, ENOENT); } @@ -359,10 +368,12 @@ int devoptab_open(struct _reent *r, void *fileStruct, const char *_path, int fla struct stat st; if (!http_stat(*device, path, &st, false)) { + log_write("[HTTP] http_stat() failed for file: %s\n", path); return set_errno(r, ENOENT); } if (st.st_mode & S_IFDIR) { + log_write("[HTTP] Attempted to open a directory as a file: %s\n", path); return set_errno(r, EISDIR); } @@ -425,7 +436,7 @@ DIR_ITER* devoptab_diropen(struct _reent *r, DIR_ITER *dirState, const char *_pa std::memset(dir, 0, sizeof(*dir)); SCOPED_MUTEX(&device->mutex); - char path[FS_MAX_PATH]; + char path[PATH_MAX]; if (!common::fix_path(_path, path)) { set_errno(r, ENOENT); return NULL; @@ -493,7 +504,7 @@ int devoptab_lstat(struct _reent *r, const char *_path, struct stat *st) { auto device = (Device*)r->deviceData; SCOPED_MUTEX(&device->mutex); - char path[FS_MAX_PATH]; + char path[PATH_MAX]; if (!common::fix_path(_path, path)) { return set_errno(r, ENOENT); } @@ -559,13 +570,17 @@ Result MountHttpAll() { e->emplace_back(Section); } - HttpMountConfig config; - if (std::strcmp(Key, "url") == 0) { - config.url = Value; - } else if (std::strcmp(Key, "user") == 0) { - config.user = Value; - } else if (std::strcmp(Key, "pass") == 0) { - config.pass = Value; + if (!std::strcmp(Key, "url")) { + e->back().url = Value; + } else if (!std::strcmp(Key, "user")) { + e->back().user = Value; + } else if (!std::strcmp(Key, "pass")) { + e->back().pass = Value; + } else if (!std::strcmp(Key, "port")) { + // todo: idk what the default should be. + e->back().port = ini_parse_getl(Value, 8000); + } else if (!std::strcmp(Key, "timeout")) { + e->back().timeout = ini_parse_getl(Value, DEFAULT_HTTP_TIMEOUT); } else { log_write("[HTTP] INI: Unknown key %s=%s\n", Key, Value); } @@ -607,8 +622,8 @@ Result MountHttpAll() { entry->devoptab.name = entry->name; entry->devoptab.deviceData = &entry->device; entry->device.config = config; - std::snprintf(entry->name, sizeof(entry->name), "%s", config.name.c_str()); - std::snprintf(entry->mount, sizeof(entry->mount), "%s:/", config.name.c_str()); + std::snprintf(entry->name, sizeof(entry->name), "[HTTP] %s", config.name.c_str()); + std::snprintf(entry->mount, sizeof(entry->mount), "[HTTP] %s:/", config.name.c_str()); R_UNLESS(AddDevice(&entry->devoptab) >= 0, 0x1); log_write("[HTTP] DEVICE SUCCESS %s %s\n", entry->device.config.url.c_str(), entry->name); diff --git a/sphaira/source/utils/devoptab_nca.cpp b/sphaira/source/utils/devoptab_nca.cpp index d8f1dbc..ba98d21 100644 --- a/sphaira/source/utils/devoptab_nca.cpp +++ b/sphaira/source/utils/devoptab_nca.cpp @@ -164,7 +164,7 @@ int devoptab_open(struct _reent *r, void *fileStruct, const char *_path, int fla auto file = static_cast(fileStruct); std::memset(file, 0, sizeof(*file)); - char path[FS_MAX_PATH]; + char path[PATH_MAX]; if (!common::fix_path(_path, path)) { return set_errno(r, ENOENT); } @@ -232,7 +232,7 @@ DIR_ITER* devoptab_diropen(struct _reent *r, DIR_ITER *dirState, const char *_pa auto dir = static_cast(dirState->dirStruct); std::memset(dir, 0, sizeof(*dir)); - char path[FS_MAX_PATH]; + char path[PATH_MAX]; if (!common::fix_path(_path, path)) { set_errno(r, ENOENT); return NULL; @@ -320,7 +320,7 @@ int devoptab_dirclose(struct _reent *r, DIR_ITER *dirState) { int devoptab_lstat(struct _reent *r, const char *_path, struct stat *st) { auto device = (Device*)r->deviceData; - char path[FS_MAX_PATH]; + char path[PATH_MAX]; if (!common::fix_path(_path, path)) { return set_errno(r, ENOENT); } diff --git a/sphaira/source/utils/devoptab_nfs.cpp b/sphaira/source/utils/devoptab_nfs.cpp index e936b52..7b32a89 100644 --- a/sphaira/source/utils/devoptab_nfs.cpp +++ b/sphaira/source/utils/devoptab_nfs.cpp @@ -15,16 +15,25 @@ namespace sphaira::devoptab { namespace { +constexpr int DEFAULT_NFS_UID = 0; +constexpr int DEFAULT_NFS_GID = 0; +constexpr int DEFAULT_NFS_VERSION = 3; +constexpr int DEFAULT_NFS_TIMEOUT = 3000; // 3 seconds. + struct NfsMountConfig { std::string name{}; std::string url{}; - std::string path{}; + int uid{DEFAULT_NFS_UID}; + int gid{DEFAULT_NFS_GID}; + int version{DEFAULT_NFS_VERSION}; + int timeout{DEFAULT_NFS_TIMEOUT}; bool read_only{}; }; using NfsMountConfigs = std::vector; struct Device { nfs_context* nfs{}; + nfs_url* url{}; NfsMountConfig config; bool mounted{}; Mutex mutex{}; @@ -51,9 +60,31 @@ bool mount_nfs(Device& device) { log_write("[NFS] nfs_init_context() failed\n"); return false; } + + nfs_set_uid(device.nfs, device.config.uid); + nfs_set_gid(device.nfs, device.config.gid); + nfs_set_version(device.nfs, device.config.version); + nfs_set_timeout(device.nfs, device.config.timeout); + nfs_set_readonly(device.nfs, device.config.read_only); + // nfs_set_mountport(device.nfs, device.url->port); } - const auto ret = nfs_mount(device.nfs, device.config.url.c_str(), device.config.path.c_str()); + // fix the url if needed. + if (!device.config.url.starts_with("nfs://")) { + log_write("[NFS] Prepending nfs:// to url: %s\n", device.config.url.c_str()); + device.config.url = "nfs://" + device.config.url; + } + + if (!device.url) { + // todo: check all parse options. + device.url = nfs_parse_url_dir(device.nfs, device.config.url.c_str()); + if (!device.url) { + log_write("[NFS] nfs_parse_url() failed for url: %s\n", device.config.url.c_str()); + return false; + } + } + + const auto ret = nfs_mount(device.nfs, device.url->server, device.url->path); if (ret) { log_write("[NFS] nfs_mount() failed: %s errno: %s\n", nfs_get_error(device.nfs), std::strerror(-ret)); return false; @@ -78,7 +109,7 @@ int devoptab_open(struct _reent *r, void *fileStruct, const char *_path, int fla return set_errno(r, EROFS); } - char path[FS_MAX_PATH]{}; + char path[PATH_MAX]{}; if (!common::fix_path(_path, path)) { return set_errno(r, ENOENT); } @@ -209,7 +240,7 @@ int devoptab_unlink(struct _reent *r, const char *_path) { auto device = static_cast(r->deviceData); SCOPED_MUTEX(&device->mutex); - char path[FS_MAX_PATH]{}; + char path[PATH_MAX]{}; if (!common::fix_path(_path, path)) { return set_errno(r, ENOENT); } @@ -231,12 +262,12 @@ int devoptab_rename(struct _reent *r, const char *_oldName, const char *_newName auto device = static_cast(r->deviceData); SCOPED_MUTEX(&device->mutex); - char oldName[FS_MAX_PATH]{}; + char oldName[PATH_MAX]{}; if (!common::fix_path(_oldName, oldName)) { return set_errno(r, ENOENT); } - char newName[FS_MAX_PATH]{}; + char newName[PATH_MAX]{}; if (!common::fix_path(_newName, newName)) { return set_errno(r, ENOENT); } @@ -258,7 +289,7 @@ int devoptab_mkdir(struct _reent *r, const char *_path, int mode) { auto device = static_cast(r->deviceData); SCOPED_MUTEX(&device->mutex); - char path[FS_MAX_PATH]{}; + char path[PATH_MAX]{}; if (!common::fix_path(_path, path)) { return set_errno(r, ENOENT); } @@ -280,7 +311,7 @@ int devoptab_rmdir(struct _reent *r, const char *_path) { auto device = static_cast(r->deviceData); SCOPED_MUTEX(&device->mutex); - char path[FS_MAX_PATH]{}; + char path[PATH_MAX]{}; if (!common::fix_path(_path, path)) { return set_errno(r, ENOENT); } @@ -304,7 +335,7 @@ DIR_ITER* devoptab_diropen(struct _reent *r, DIR_ITER *dirState, const char *_pa std::memset(dir, 0, sizeof(*dir)); SCOPED_MUTEX(&device->mutex); - char path[FS_MAX_PATH]{}; + char path[PATH_MAX]{}; if (!common::fix_path(_path, path)) { set_errno(r, ENOENT); return nullptr; @@ -380,7 +411,7 @@ int devoptab_lstat(struct _reent *r, const char *_path, struct stat *st) { auto device = static_cast(r->deviceData); SCOPED_MUTEX(&device->mutex); - char path[FS_MAX_PATH]{}; + char path[PATH_MAX]{}; if (!common::fix_path(_path, path)) { return set_errno(r, ENOENT); } @@ -415,7 +446,7 @@ int devoptab_statvfs(struct _reent *r, const char *_path, struct statvfs *buf) { auto device = static_cast(r->deviceData); SCOPED_MUTEX(&device->mutex); - char path[FS_MAX_PATH]{}; + char path[PATH_MAX]{}; if (!common::fix_path(_path, path)) { return set_errno(r, ENOENT); } @@ -455,7 +486,7 @@ int devoptab_utimes(struct _reent *r, const char *_path, const struct timeval ti return set_errno(r, EINVAL); } - char path[FS_MAX_PATH]{}; + char path[PATH_MAX]{}; if (!common::fix_path(_path, path)) { return set_errno(r, ENOENT); } @@ -514,6 +545,11 @@ struct Entry { if (device.mounted) { nfs_umount(device.nfs); } + + if (device.url) { + nfs_destroy_url(device.url); + } + nfs_destroy_context(device.nfs); } @@ -542,10 +578,16 @@ Result MountNfsAll() { if (!std::strcmp(Key, "url")) { e->back().url = Value; - } else if (!std::strcmp(Key, "path")) { - e->back().path = Value; } else if (!std::strcmp(Key, "name")) { e->back().name = Value; + } else if (!std::strcmp(Key, "uid")) { + e->back().uid = ini_parse_getl(Value, DEFAULT_NFS_UID); + } else if (!std::strcmp(Key, "gid")) { + e->back().gid = ini_parse_getl(Value, DEFAULT_NFS_GID); + } else if (!std::strcmp(Key, "version")) { + e->back().version = ini_parse_getl(Value, DEFAULT_NFS_VERSION); + } else if (!std::strcmp(Key, "timeout")) { + e->back().timeout = ini_parse_getl(Value, DEFAULT_NFS_TIMEOUT); } else if (!std::strcmp(Key, "read_only")) { e->back().read_only = ini_parse_getbool(Value, false); } else { @@ -590,8 +632,8 @@ Result MountNfsAll() { entry->devoptab.name = entry->name; entry->devoptab.deviceData = &entry->device; entry->device.config = config; - std::snprintf(entry->name, sizeof(entry->name), "%s", config.name.c_str()); - std::snprintf(entry->mount, sizeof(entry->mount), "%s:/", config.name.c_str()); + std::snprintf(entry->name, sizeof(entry->name), "[NFS] %s", config.name.c_str()); + std::snprintf(entry->mount, sizeof(entry->mount), "[NFS] %s:/", config.name.c_str()); common::update_devoptab_for_read_only(&entry->devoptab, config.read_only); R_UNLESS(AddDevice(&entry->devoptab) >= 0, 0x1); diff --git a/sphaira/source/utils/devoptab_nro.cpp b/sphaira/source/utils/devoptab_nro.cpp index 21ae28c..761b98d 100644 --- a/sphaira/source/utils/devoptab_nro.cpp +++ b/sphaira/source/utils/devoptab_nro.cpp @@ -128,7 +128,7 @@ int devoptab_open(struct _reent *r, void *fileStruct, const char *_path, int fla auto file = static_cast(fileStruct); std::memset(file, 0, sizeof(*file)); - char path[FS_MAX_PATH]; + char path[PATH_MAX]; if (!common::fix_path(_path, path)) { return set_errno(r, ENOENT); } @@ -198,7 +198,7 @@ DIR_ITER* devoptab_diropen(struct _reent *r, DIR_ITER *dirState, const char *_pa auto dir = static_cast(dirState->dirStruct); std::memset(dir, 0, sizeof(*dir)); - char path[FS_MAX_PATH]; + char path[PATH_MAX]; if (!common::fix_path(_path, path)) { set_errno(r, ENOENT); return NULL; @@ -282,7 +282,7 @@ int devoptab_dirclose(struct _reent *r, DIR_ITER *dirState) { int devoptab_lstat(struct _reent *r, const char *_path, struct stat *st) { auto device = (Device*)r->deviceData; - char path[FS_MAX_PATH]; + char path[PATH_MAX]; if (!common::fix_path(_path, path)) { return set_errno(r, ENOENT); } diff --git a/sphaira/source/utils/devoptab_nsp.cpp b/sphaira/source/utils/devoptab_nsp.cpp index 0942d55..a11fb01 100644 --- a/sphaira/source/utils/devoptab_nsp.cpp +++ b/sphaira/source/utils/devoptab_nsp.cpp @@ -44,7 +44,7 @@ int devoptab_open(struct _reent *r, void *fileStruct, const char *_path, int fla auto file = static_cast(fileStruct); std::memset(file, 0, sizeof(*file)); - char path[FS_MAX_PATH]; + char path[PATH_MAX]; if (!common::fix_path(_path, path)) { return set_errno(r, ENOENT); } @@ -112,7 +112,7 @@ DIR_ITER* devoptab_diropen(struct _reent *r, DIR_ITER *dirState, const char *_pa auto dir = static_cast(dirState->dirStruct); std::memset(dir, 0, sizeof(*dir)); - char path[FS_MAX_PATH]; + char path[PATH_MAX]; if (!common::fix_path(_path, path)) { set_errno(r, ENOENT); return NULL; @@ -165,7 +165,7 @@ int devoptab_dirclose(struct _reent *r, DIR_ITER *dirState) { int devoptab_lstat(struct _reent *r, const char *_path, struct stat *st) { auto device = (Device*)r->deviceData; - char path[FS_MAX_PATH]; + char path[PATH_MAX]; if (!common::fix_path(_path, path)) { return set_errno(r, ENOENT); } diff --git a/sphaira/source/utils/devoptab_save.cpp b/sphaira/source/utils/devoptab_save.cpp index 82a9943..3781bb3 100644 --- a/sphaira/source/utils/devoptab_save.cpp +++ b/sphaira/source/utils/devoptab_save.cpp @@ -51,7 +51,7 @@ int devoptab_open(struct _reent *r, void *fileStruct, const char *_path, int fla auto file = static_cast(fileStruct); std::memset(file, 0, sizeof(*file)); - char path[FS_MAX_PATH]; + char path[PATH_MAX]; if (!common::fix_path(_path, path)) { return set_errno(r, ENOENT); } @@ -117,7 +117,7 @@ DIR_ITER* devoptab_diropen(struct _reent *r, DIR_ITER *dirState, const char *_pa auto dir = static_cast(dirState->dirStruct); std::memset(dir, 0, sizeof(*dir)); - char path[FS_MAX_PATH]; + char path[PATH_MAX]; if (!common::fix_path(_path, path)) { set_errno(r, ENOENT); return NULL; @@ -204,7 +204,7 @@ int devoptab_dirclose(struct _reent *r, DIR_ITER *dirState) { int devoptab_lstat(struct _reent *r, const char *_path, struct stat *st) { auto device = (Device*)r->deviceData; - char path[FS_MAX_PATH]; + char path[PATH_MAX]; if (!common::fix_path(_path, path)) { return set_errno(r, ENOENT); } diff --git a/sphaira/source/utils/devoptab_smb2.cpp b/sphaira/source/utils/devoptab_smb2.cpp index ca19023..c05e113 100644 --- a/sphaira/source/utils/devoptab_smb2.cpp +++ b/sphaira/source/utils/devoptab_smb2.cpp @@ -16,11 +16,16 @@ namespace sphaira::devoptab { namespace { +constexpr int DEFAULT_SMB2_TIMEOUT = 3000; // 3 seconds. + struct Smb2MountConfig { std::string name{}; std::string url{}; std::string user{}; std::string pass{}; + std::string domain{}; + std::string workstation{}; + int timeout{DEFAULT_SMB2_TIMEOUT}; bool read_only{}; }; using Smb2MountConfigs = std::vector; @@ -64,6 +69,16 @@ bool mount_smb2(Device& device) { if (!device.config.pass.empty()) { smb2_set_password(device.smb2, device.config.pass.c_str()); } + + if (!device.config.domain.empty()) { + smb2_set_domain(device.smb2, device.config.domain.c_str()); + } + + if (!device.config.workstation.empty()) { + smb2_set_workstation(device.smb2, device.config.workstation.c_str()); + } + + smb2_set_timeout(device.smb2, device.config.timeout); } if (!device.url) { @@ -74,10 +89,6 @@ bool mount_smb2(Device& device) { } } - log_write("[SMB2] Connecting to %s/%s as %s\n", - device.url->server, - device.url->share, - device.url->user ? device.url->user : "guest"); const auto ret = smb2_connect_share(device.smb2, device.url->server, device.url->share, device.url->user); if (ret) { log_write("[SMB2] smb2_connect_share() failed: %s errno: %s\n", smb2_get_error(device.smb2), std::strerror(-ret)); @@ -127,7 +138,7 @@ int devoptab_open(struct _reent *r, void *fileStruct, const char *_path, int fla return set_errno(r, EROFS); } - char path[FS_MAX_PATH]{}; + char path[PATH_MAX]{}; if (!fix_path(_path, path)) { return set_errno(r, ENOENT); } @@ -217,7 +228,7 @@ int devoptab_unlink(struct _reent *r, const char *_path) { auto device = static_cast(r->deviceData); SCOPED_MUTEX(&device->mutex); - char path[FS_MAX_PATH]{}; + char path[PATH_MAX]{}; if (!fix_path(_path, path)) { return set_errno(r, ENOENT); } @@ -239,12 +250,12 @@ int devoptab_rename(struct _reent *r, const char *_oldName, const char *_newName auto device = static_cast(r->deviceData); SCOPED_MUTEX(&device->mutex); - char oldName[FS_MAX_PATH]{}; + char oldName[PATH_MAX]{}; if (!fix_path(_oldName, oldName)) { return set_errno(r, ENOENT); } - char newName[FS_MAX_PATH]{}; + char newName[PATH_MAX]{}; if (!fix_path(_newName, newName)) { return set_errno(r, ENOENT); } @@ -266,7 +277,7 @@ int devoptab_mkdir(struct _reent *r, const char *_path, int mode) { auto device = static_cast(r->deviceData); SCOPED_MUTEX(&device->mutex); - char path[FS_MAX_PATH]{}; + char path[PATH_MAX]{}; if (!fix_path(_path, path)) { return set_errno(r, ENOENT); } @@ -288,7 +299,7 @@ int devoptab_rmdir(struct _reent *r, const char *_path) { auto device = static_cast(r->deviceData); SCOPED_MUTEX(&device->mutex); - char path[FS_MAX_PATH]{}; + char path[PATH_MAX]{}; if (!fix_path(_path, path)) { return set_errno(r, ENOENT); } @@ -312,7 +323,7 @@ DIR_ITER* devoptab_diropen(struct _reent *r, DIR_ITER *dirState, const char *_pa std::memset(dir, 0, sizeof(*dir)); SCOPED_MUTEX(&device->mutex); - char path[FS_MAX_PATH]{}; + char path[PATH_MAX]{}; if (!fix_path(_path, path)) { set_errno(r, ENOENT); return nullptr; @@ -376,7 +387,7 @@ int devoptab_lstat(struct _reent *r, const char *_path, struct stat *st) { std::memset(st, 0, sizeof(*st)); SCOPED_MUTEX(&device->mutex); - char path[FS_MAX_PATH]{}; + char path[PATH_MAX]{}; if (!fix_path(_path, path)) { return set_errno(r, ENOENT); } @@ -413,7 +424,7 @@ int devoptab_statvfs(struct _reent *r, const char *_path, struct statvfs *buf) { auto device = static_cast(r->deviceData); SCOPED_MUTEX(&device->mutex); - char path[FS_MAX_PATH]{}; + char path[PATH_MAX]{}; if (!fix_path(_path, path)) { return set_errno(r, ENOENT); } @@ -532,6 +543,12 @@ Result MountSmb2All() { e->back().user = Value; } else if (!std::strcmp(Key, "pass")) { e->back().pass = Value; + } else if (!std::strcmp(Key, "domain")) { + e->back().domain = Value; + } else if (!std::strcmp(Key, "workstation")) { + e->back().workstation = Value; + } else if (!std::strcmp(Key, "timeout")) { + e->back().timeout = ini_parse_getl(Value, DEFAULT_SMB2_TIMEOUT); } else if (!std::strcmp(Key, "read_only")) { e->back().read_only = ini_parse_getbool(Value, false); } else { @@ -576,8 +593,8 @@ Result MountSmb2All() { entry->devoptab.name = entry->name; entry->devoptab.deviceData = &entry->device; entry->device.config = config; - std::snprintf(entry->name, sizeof(entry->name), "%s", config.name.c_str()); - std::snprintf(entry->mount, sizeof(entry->mount), "%s:/", config.name.c_str()); + std::snprintf(entry->name, sizeof(entry->name), "[SMB] %s", config.name.c_str()); + std::snprintf(entry->mount, sizeof(entry->mount), "[SMB] %s:/", config.name.c_str()); common::update_devoptab_for_read_only(&entry->devoptab, config.read_only); R_UNLESS(AddDevice(&entry->devoptab) >= 0, 0x1); diff --git a/sphaira/source/utils/devoptab_xci.cpp b/sphaira/source/utils/devoptab_xci.cpp index 2c9c2cc..73f0a97 100644 --- a/sphaira/source/utils/devoptab_xci.cpp +++ b/sphaira/source/utils/devoptab_xci.cpp @@ -44,7 +44,7 @@ int devoptab_open(struct _reent *r, void *fileStruct, const char *_path, int fla auto file = static_cast(fileStruct); std::memset(file, 0, sizeof(*file)); - char path[FS_MAX_PATH]; + char path[PATH_MAX]; if (!common::fix_path(_path, path)) { return set_errno(r, ENOENT); } @@ -114,7 +114,7 @@ DIR_ITER* devoptab_diropen(struct _reent *r, DIR_ITER *dirState, const char *_pa auto dir = static_cast(dirState->dirStruct); std::memset(dir, 0, sizeof(*dir)); - char path[FS_MAX_PATH]; + char path[PATH_MAX]; if (!common::fix_path(_path, path)) { set_errno(r, ENOENT); return NULL; @@ -184,7 +184,7 @@ int devoptab_dirclose(struct _reent *r, DIR_ITER *dirState) { int devoptab_lstat(struct _reent *r, const char *_path, struct stat *st) { auto device = (Device*)r->deviceData; - char path[FS_MAX_PATH]; + char path[PATH_MAX]; if (!common::fix_path(_path, path)) { return set_errno(r, ENOENT); } diff --git a/sphaira/source/utils/devoptab_zip.cpp b/sphaira/source/utils/devoptab_zip.cpp index e20a129..adbb43e 100644 --- a/sphaira/source/utils/devoptab_zip.cpp +++ b/sphaira/source/utils/devoptab_zip.cpp @@ -204,7 +204,7 @@ int devoptab_open(struct _reent *r, void *fileStruct, const char *_path, int fla auto file = static_cast(fileStruct); std::memset(file, 0, sizeof(*file)); - char path[FS_MAX_PATH]{}; + char path[PATH_MAX]{}; if (!common::fix_path(_path, path)) { return set_errno(r, ENOENT); } @@ -382,7 +382,7 @@ DIR_ITER* devoptab_diropen(struct _reent *r, DIR_ITER *dirState, const char *_pa auto dir = static_cast(dirState->dirStruct); std::memset(dir, 0, sizeof(*dir)); - char path[FS_MAX_PATH]; + char path[PATH_MAX]; if (!common::fix_path(_path, path)) { set_errno(r, ENOENT); return NULL; @@ -451,7 +451,7 @@ int devoptab_lstat(struct _reent *r, const char *_path, struct stat *st) { return set_errno(r, ENOENT); } - char path[FS_MAX_PATH]; + char path[PATH_MAX]; if (!common::fix_path(_path, path)) { return set_errno(r, ENOENT); } diff --git a/sphaira/source/web.cpp b/sphaira/source/web.cpp index 29fa380..4cd161b 100644 --- a/sphaira/source/web.cpp +++ b/sphaira/source/web.cpp @@ -11,8 +11,6 @@ auto WebShow(const std::string& url) -> Result { WebCommonReply reply{}; WebExitReason reason{}; AccountUid account_uid{}; - char last_url[FS_MAX_PATH]{}; - size_t last_url_len{}; // WebBackgroundKind_Unknown1 = shows background // WebBackgroundKind_Unknown2 = shows background faded @@ -54,8 +52,6 @@ auto WebShow(const std::string& url) -> Result { if (R_FAILED(webConfigShow(&config, &reply))) { log_write("failed: webConfigShow\n"); } if (R_FAILED(webReplyGetExitReason(&reply, &reason))) { log_write("failed: webReplyGetExitReason\n"); } - if (R_FAILED(webReplyGetLastUrl(&reply, last_url, sizeof(last_url), &last_url_len))) { log_write("failed: webReplyGetLastUrl\n"); } - log_write("last url: %s\n", last_url); R_SUCCEED(); }