diff --git a/CMakeLists.txt b/CMakeLists.txt index fcba2c0..ac48366 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,6 +40,8 @@ add_executable(ezremote_client source/clients/smbclient.cpp source/clients/webdavclient.cpp source/clients/sftpclient.cpp + source/clients/rclone.cpp + source/filehost/gdrive_host.cpp source/server/http_server.cpp source/actions.cpp source/config.cpp @@ -65,6 +67,7 @@ add_self(ezremote_client) add_pkg(ezremote_client ${CMAKE_SOURCE_DIR}/data "RMTC00001" "ezRemote Client" "01.10" 32 0) target_link_libraries(ezremote_client + dbglogger c c++ png diff --git a/source/actions.cpp b/source/actions.cpp index 2c12b74..b0e27cc 100644 --- a/source/actions.cpp +++ b/source/actions.cpp @@ -14,6 +14,7 @@ #include "clients/npxserve.h" #include "clients/nfsclient.h" #include "clients/iis.h" +#include "clients/rclone.h" #include "clients/sftpclient.h" #include "common.h" #include "fs.h" @@ -1133,6 +1134,8 @@ namespace Actions remoteclient = new NginxClient(); else if (strcmp(remote_settings->http_server_type, HTTP_SERVER_NPX_SERVE) == 0) remoteclient = new NpxServeClient(); + else if (strcmp(remote_settings->http_server_type, HTTP_SERVER_RCLONE) == 0) + remoteclient = new RCloneClient(); } else if (strncmp(remote_settings->server, "webdavs://", 10) == 0 || strncmp(remote_settings->server, "webdav://", 9) == 0) { diff --git a/source/clients/apache.cpp b/source/clients/apache.cpp index 3873a70..84ae787 100644 --- a/source/clients/apache.cpp +++ b/source/clients/apache.cpp @@ -12,26 +12,6 @@ using httplib::Client; using httplib::Headers; using httplib::Result; -lxb_dom_node_t *nextChildElement(lxb_dom_element_t *element) -{ - lxb_dom_node_t *node = element->node.first_child; - while (node != nullptr && node->type != LXB_DOM_NODE_TYPE_ELEMENT) - { - node = node->next; - } - return node; -} - -lxb_dom_node_t *nextElement(lxb_dom_node_t *node) -{ - lxb_dom_node_t *next = node->next; - while (next != nullptr && next->type != LXB_DOM_NODE_TYPE_ELEMENT) - { - next = next->next; - } - return next; -} - std::vector ApacheClient::ListDir(const std::string &path) { std::vector out; @@ -101,7 +81,7 @@ std::vector ApacheClient::ListDir(const std::string &path) memset(&entry, 0, sizeof(DirEntry)); element = lxb_dom_collection_element(collection, i); - node = nextChildElement(element); + node = NextChildElement(element); if (node == nullptr) continue; value = lxb_dom_element_local_name(lxb_dom_interface_element(node), &value_len); @@ -114,7 +94,7 @@ std::vector ApacheClient::ListDir(const std::string &path) if (tmp_string.compare("td") == 0) { // get the child img element - lxb_dom_node_t *img = nextChildElement(lxb_dom_interface_element(node)); + lxb_dom_node_t *img = NextChildElement(lxb_dom_interface_element(node)); if (img == nullptr) continue; value = lxb_dom_element_local_name(lxb_dom_interface_element(img), &value_len); @@ -142,7 +122,7 @@ std::vector ApacheClient::ListDir(const std::string &path) else continue; // invalid record // file/folder name - node = nextElement(node); + node = NextElement(node); if (node == nullptr) continue; value = lxb_dom_element_local_name(lxb_dom_interface_element(node), &value_len); tmp_string = std::string((const char *)value, value_len); @@ -165,7 +145,7 @@ std::vector ApacheClient::ListDir(const std::string &path) else continue; // not valid record // datetime - node = nextElement(node); + node = NextElement(node); if (node == nullptr) continue; value = lxb_dom_element_local_name(lxb_dom_interface_element(node), &value_len); tmp_string = std::string((const char *)value, value_len); @@ -195,7 +175,7 @@ std::vector ApacheClient::ListDir(const std::string &path) else continue; // invalid record // filesize - node = nextElement(node); + node = NextElement(node); if (node == nullptr) continue; value = lxb_dom_element_local_name(lxb_dom_interface_element(node), &value_len); tmp_string = std::string((const char *)value, value_len); diff --git a/source/clients/baseclient.cpp b/source/clients/baseclient.cpp index fd59a49..8e78edc 100644 --- a/source/clients/baseclient.cpp +++ b/source/clients/baseclient.cpp @@ -319,3 +319,23 @@ std::string BaseClient::DecodeUrl(const std::string &url) } return ""; } + +lxb_dom_node_t *BaseClient::NextChildElement(lxb_dom_element_t *element) +{ + lxb_dom_node_t *node = element->node.first_child; + while (node != nullptr && node->type != LXB_DOM_NODE_TYPE_ELEMENT) + { + node = node->next; + } + return node; +} + +lxb_dom_node_t *BaseClient::NextElement(lxb_dom_node_t *node) +{ + lxb_dom_node_t *next = node->next; + while (next != nullptr && next->type != LXB_DOM_NODE_TYPE_ELEMENT) + { + next = next->next; + } + return next; +} diff --git a/source/clients/baseclient.h b/source/clients/baseclient.h index 95df28a..e1a7cfb 100644 --- a/source/clients/baseclient.h +++ b/source/clients/baseclient.h @@ -3,6 +3,8 @@ #include #include +#include +#include #include "http/httplib.h" #include "clients/remote_client.h" #include "http/httplib.h" @@ -38,6 +40,8 @@ public: uint32_t SupportedActions(); static std::string EncodeUrl(const std::string &url); static std::string DecodeUrl(const std::string &url); + static lxb_dom_node_t *NextChildElement(lxb_dom_element_t *element); + static lxb_dom_node_t *NextElement(lxb_dom_node_t *node); protected: httplib::Client *client; diff --git a/source/clients/rclone.cpp b/source/clients/rclone.cpp new file mode 100644 index 0000000..d95ade3 --- /dev/null +++ b/source/clients/rclone.cpp @@ -0,0 +1,225 @@ +#include +#include +#include +#include "common.h" +#include "clients/remote_client.h" +#include "clients/rclone.h" +#include "lang.h" +#include "util.h" +#include "system.h" +#include "windows.h" +#include "dbglogger.h" + +using httplib::Client; +using httplib::Headers; +using httplib::Result; + +std::vector RCloneClient::ListDir(const std::string &path) +{ + std::vector out; + DirEntry entry; + Util::SetupPreviousFolder(path, &entry); + out.push_back(entry); + + std::string encoded_path = httplib::detail::encode_url(GetFullPath(path)+"/"); + if (auto res = client->Get(encoded_path)) + { + lxb_status_t status; + lxb_dom_attr_t *attr; + lxb_dom_element_t *tbody_element, *tr_element, *td_element; + lxb_html_document_t *document; + lxb_dom_collection_t *tbody_collection; + lxb_dom_collection_t *tr_collection; + lxb_dom_collection_t *td_collection; + + document = lxb_html_document_create(); + status = lxb_html_document_parse(document, (lxb_char_t *)res->body.c_str(), res->body.length()); + if (status != LXB_STATUS_OK) + { + lxb_html_document_destroy(document); + goto finish; + } + + tbody_collection = lxb_dom_collection_make(&document->dom_document, 1); + if (tbody_collection == NULL) + { + lxb_html_document_destroy(document); + goto finish; + } + + tr_collection = lxb_dom_collection_make(&document->dom_document, 128); + if (tbody_collection == NULL) + { + lxb_html_document_destroy(document); + goto finish; + } + + status = lxb_dom_elements_by_tag_name(lxb_dom_interface_element(document->body), + tbody_collection, (const lxb_char_t *)"tbody", 5); + if (status != LXB_STATUS_OK) + { + lxb_dom_collection_destroy(tr_collection, true); + lxb_dom_collection_destroy(tbody_collection, true); + lxb_html_document_destroy(document); + goto finish; + } + + if (lxb_dom_collection_length(tbody_collection) < 1) + { + lxb_dom_collection_destroy(tr_collection, true); + lxb_dom_collection_destroy(tbody_collection, true); + lxb_html_document_destroy(document); + goto finish; + } + + // Get the first tbody which should only be 1 + tbody_element = lxb_dom_collection_element(tbody_collection, 0); + status = lxb_dom_elements_by_tag_name(tbody_element, + tr_collection, (const lxb_char_t *)"tr", 2); + if (status != LXB_STATUS_OK) + { + lxb_dom_collection_destroy(tr_collection, true); + lxb_dom_collection_destroy(tbody_collection, true); + lxb_html_document_destroy(document); + goto finish; + } + + // skip row 0 , since it has the previous folder header + for (size_t i = 1; i < lxb_dom_collection_length(tr_collection); i++) + { + DirEntry entry; + std::string title, aclass; + memset(&entry.modified, 0, sizeof(DateTime)); + const lxb_char_t *value; + size_t value_len; + std::string tmp_string; + + tr_element = lxb_dom_collection_element(tr_collection, i); + + td_collection = lxb_dom_collection_make(&document->dom_document, 5); + status = lxb_dom_elements_by_tag_name(tr_element, + td_collection, (const lxb_char_t *)"td", 2); + if (status != LXB_STATUS_OK || lxb_dom_collection_length(td_collection) < 0) + { + lxb_dom_collection_destroy(td_collection, true); + lxb_dom_collection_destroy(tr_collection, true); + lxb_dom_collection_destroy(tbody_collection, true); + lxb_html_document_destroy(document); + goto finish; + } + + // td 0 is empty, td 1 is file or folder + td_element = lxb_dom_collection_element(td_collection, 1); + lxb_dom_node_t *use_node = NextChildElement(lxb_dom_interface_element(NextChildElement(td_element))); + value = lxb_dom_element_local_name(lxb_dom_interface_element(use_node), &value_len); + tmp_string = std::string((const char *)value, value_len); + if (tmp_string.compare("use") != 0) + { + lxb_dom_collection_destroy(td_collection, true); + lxb_dom_collection_destroy(tr_collection, true); + lxb_dom_collection_destroy(tbody_collection, true); + lxb_html_document_destroy(document); + goto finish; + } + value = lxb_dom_element_get_attribute(lxb_dom_interface_element(use_node), (const lxb_char_t *)"xlink:href", 10, &value_len); + tmp_string = std::string((const char *)value, value_len); + if (tmp_string.compare("#folder") == 0) + { + entry.isDir = true; + entry.selectable = true; + entry.file_size = 0; + sprintf(entry.display_size, "%s", lang_strings[STR_FOLDER]); + } + else + { + entry.isDir = false; + entry.selectable = true; + } + + // element contains the file/folder name + lxb_dom_node_t *a_node = NextChildElement(lxb_dom_interface_element(NextElement(NextChildElement(td_element)))); + value = lxb_dom_element_get_attribute(lxb_dom_interface_element(a_node), (const lxb_char_t *)"href", 4, &value_len); + tmp_string = std::string((const char *)value, value_len); + if (tmp_string[tmp_string.length()-1] == '/') + tmp_string = tmp_string.substr(0, tmp_string.length()-1); + tmp_string = BaseClient::DecodeUrl(tmp_string); + sprintf(entry.name, "%s", tmp_string.c_str()); + sprintf(entry.directory, "%s", path.c_str()); + if (path.length() > 0 && path[path.length() - 1] == '/') + { + sprintf(entry.path, "%s%s", path.c_str(), entry.name); + } + else + { + sprintf(entry.path, "%s/%s", path.c_str(), entry.name); + } + + // td 3 - filesize + if (!entry.isDir) + { + td_element = lxb_dom_collection_element(td_collection, 2); + lxb_dom_node_t *size_node = NextChildElement(td_element); + value = lxb_dom_node_text_content(size_node->first_child, &value_len); + tmp_string = std::string((const char *)value, value_len); + entry.file_size = atoi(tmp_string.c_str()); + DirEntry::SetDisplaySize(&entry); + } + + // td 4 - datetime + td_element = lxb_dom_collection_element(td_collection, 3); + lxb_dom_node_t *date_node = NextChildElement(td_element); + value = lxb_dom_element_get_attribute(lxb_dom_interface_element(date_node), (const lxb_char_t *)"datetime", 8, &value_len); + tmp_string = std::string((const char *)value, value_len); + std::vector date_time = Util::Split(tmp_string, " "); + + OrbisDateTime gmt; + OrbisDateTime lt; + + if (date_time.size() > 1) + { + std::vector adate = Util::Split(date_time[0], "-"); + if (adate.size() == 3) + { + gmt.year = atoi(adate[0].c_str()); + gmt.month = atoi(adate[1].c_str()); + gmt.day = atoi(adate[2].c_str()); + } + + std::vector atime = Util::Split(date_time[1], ":"); + if (atime.size() == 3) + { + gmt.hour = atoi(atime[0].c_str()); + gmt.minute = atoi(atime[1].c_str()); + + std::vector sec_msec = Util::Split(atime[2], "."); + if (sec_msec.size() > 0) + { + gmt.second = atoi(sec_msec[0].c_str()); + } + } + } + convertUtcToLocalTime(&gmt, <); + entry.modified.day = lt.day; + entry.modified.month = lt.month; + entry.modified.year = lt.year; + entry.modified.hours = lt.hour; + entry.modified.minutes = lt.minute; + entry.modified.seconds = lt.second; + + lxb_dom_collection_destroy(td_collection, true); + out.push_back(entry); + } + + lxb_dom_collection_destroy(tr_collection, true); + lxb_dom_collection_destroy(tbody_collection, true); + lxb_html_document_destroy(document); + } + else + { + sprintf(this->response, "%s", httplib::to_string(res.error()).c_str()); + return out; + } + +finish: + return out; +} \ No newline at end of file diff --git a/source/clients/rclone.h b/source/clients/rclone.h new file mode 100644 index 0000000..575a051 --- /dev/null +++ b/source/clients/rclone.h @@ -0,0 +1,17 @@ +#ifndef RCLONE_H +#define RCLONE_H + +#include +#include +#include "http/httplib.h" +#include "clients/baseclient.h" +#include "clients/remote_client.h" +#include "common.h" + +class RCloneClient : public BaseClient +{ +public: + std::vector ListDir(const std::string &path); +}; + +#endif \ No newline at end of file diff --git a/source/config.cpp b/source/config.cpp index 3c8cee1..fc17499 100644 --- a/source/config.cpp +++ b/source/config.cpp @@ -151,7 +151,7 @@ namespace CONFIG sites = {"Site 1", "Site 2", "Site 3", "Site 4", "Site 5", "Site 6", "Site 7", "Site 8", "Site 9", "Site 10", "Site 11", "Site 12", "Site 13", "Site 14", "Site 15", "Site 16", "Site 17", "Site 18", "Site 19", "Site 20"}; - http_servers = {HTTP_SERVER_APACHE, HTTP_SERVER_MS_IIS, HTTP_SERVER_NGINX, HTTP_SERVER_NPX_SERVE}; + http_servers = {HTTP_SERVER_APACHE, HTTP_SERVER_MS_IIS, HTTP_SERVER_NGINX, HTTP_SERVER_NPX_SERVE, HTTP_SERVER_RCLONE}; text_file_extensions = { ".txt", ".ini", ".log", ".json", ".xml", ".html", ".xhtml", ".conf", ".config" }; image_file_extensions = { ".bmp", ".jpg", ".jpeg", ".png", ".webp" }; diff --git a/source/config.h b/source/config.h index a5fddce..c50dc6e 100644 --- a/source/config.h +++ b/source/config.h @@ -75,6 +75,7 @@ #define HTTP_SERVER_MS_IIS "Microsoft IIS" #define HTTP_SERVER_NGINX "Nginx" #define HTTP_SERVER_NPX_SERVE "Serve" +#define HTTP_SERVER_RCLONE "RClone" #define MAX_EDIT_FILE_SIZE 32768 diff --git a/source/filehost/filehost.h b/source/filehost/filehost.h new file mode 100644 index 0000000..10af5fd --- /dev/null +++ b/source/filehost/filehost.h @@ -0,0 +1,27 @@ +#ifndef FILEHOST_H +#define FILEHOST_H + +#include +#include +#include "openssl/md5.h" + +class FileHost +{ +public: + FileHost(const std::string &url) { this->url = url; }; + virtual ~FileHost(){}; + virtual bool IsValidUrl() = 0; + virtual std::string GetDownloadUrl() = 0; + + std::vector Hash() + { + std::vector res(16); + MD5((const unsigned char *)this->url.c_str(), this->url.length(), res.data()); + return res; + } + +protected: + std::string url; +}; + +#endif \ No newline at end of file diff --git a/source/filehost/gdrive_host.cpp b/source/filehost/gdrive_host.cpp new file mode 100644 index 0000000..2a07a8a --- /dev/null +++ b/source/filehost/gdrive_host.cpp @@ -0,0 +1,86 @@ +#include +#include +#include +#include + +#include "common.h" +#include "gdrive_host.h" + + +#define VALIDATION_REGEX_1 "https:\\/\\/drive\\.google\\.com\\/file\\/d\\/(.*)\\/(edit|view)\\?usp=(.*)" +#define VALIDATION_REGEX_2 "https:\\/\\/drive\\.google\\.com\\/uc\\?export=download&id=(.*)" + +GDriveHost::GDriveHost(const std::string &url) : FileHost(url) +{ +} + +bool GDriveHost::IsValidUrl() +{ + std::regex regex_1(VALIDATION_REGEX_1); + std::regex regex_2(VALIDATION_REGEX_1); + + if (std::regex_match(url, regex_1) || std::regex_match(url, regex_2)) + return true; + return false; +} + +std::string GDriveHost::GetDownloadUrl() +{ + std::regex re("https:\\/\\/drive\\.google\\.com"); + std::string path = std::regex_replace(url, re, ""); + + httplib::Client tmp_client("https://drive.google.com"); + auto res = tmp_client.Head(path); + if (HTTP_SUCCESS(res->status)) + { + std::string content_type = res->get_header_value("Content-Type"); + if (content_type == "application/octet-stream") + return url; + else if (content_type != "text/html") + return ""; + } + else + return ""; + + res = tmp_client.Get(path); + if (HTTP_SUCCESS(res->status)) + { + lxb_status_t status; + lxb_dom_element_t *element; + lxb_html_document_t *document; + lxb_dom_collection_t *collection; + lxb_dom_attr_t *attr; + document = lxb_html_document_create(); + status = lxb_html_document_parse(document, (lxb_char_t *)res->body.c_str(), res->body.length()); + if (status != LXB_STATUS_OK) + return ""; + collection = lxb_dom_collection_make(&document->dom_document, 128); + if (collection == NULL) + { + return ""; + } + status = lxb_dom_elements_by_tag_name(lxb_dom_interface_element(document->body), + collection, (const lxb_char_t *)"form", 4); + if (status != LXB_STATUS_OK) + return ""; + std::string download_url; + for (size_t i = 0; i < lxb_dom_collection_length(collection); i++) + { + element = lxb_dom_collection_element(collection, i); + std::string form_id((char *)element->attr_id->value->data, element->attr_id->value->length); + if (form_id == "download-form") + { + size_t value_len; + const lxb_char_t *value = lxb_dom_element_get_attribute(element, (const lxb_char_t *)"action", 6, &value_len); + download_url = std::string((char *)value, value_len); + break; + } + } + lxb_dom_collection_destroy(collection, true); + lxb_html_document_destroy(document); + + return download_url; + } + + return ""; +} diff --git a/source/filehost/gdrive_host.h b/source/filehost/gdrive_host.h new file mode 100644 index 0000000..ee70599 --- /dev/null +++ b/source/filehost/gdrive_host.h @@ -0,0 +1,14 @@ +#ifndef GDRIVE_HOST_H +#define GDRIVE_HOST_H + +#include "filehost.h" + +class GDriveHost : public FileHost +{ +public: + GDriveHost(const std::string &url); + bool IsValidUrl(); + std::string GetDownloadUrl(); +}; + +#endif \ No newline at end of file diff --git a/source/http/httplib.h b/source/http/httplib.h index 8c6bbc3..6009a2b 100644 --- a/source/http/httplib.h +++ b/source/http/httplib.h @@ -1900,6 +1900,7 @@ namespace detail { std::string encode_query_param(const std::string &value); +std::string encode_url(const std::string &s); std::string decode_url(const std::string &s, bool convert_plus_to_space); void read_file(const std::string &path, std::string &out); diff --git a/source/installer.cpp b/source/installer.cpp index c06dd28..76957eb 100644 --- a/source/installer.cpp +++ b/source/installer.cpp @@ -125,11 +125,14 @@ namespace INSTALLER else { std::string encoded_path = path; + std::string encoded_site_name = remote_settings->site_name; Web::Urn::Path uri(encoded_path); + Web::Urn::Path site_name(encoded_site_name); CURL *curl = curl_easy_init(); encoded_path = uri.quote(curl); + encoded_site_name = site_name.quote(curl); curl_easy_cleanup(curl); - std::string full_url = std::string("http://localhost:") + std::to_string(http_server_port) + "/rmt_inst" + encoded_path; + std::string full_url = std::string("http://localhost:") + std::to_string(http_server_port) + "/rmt_inst" + encoded_site_name + encoded_path; return full_url; } @@ -587,4 +590,4 @@ namespace INSTALLER return true; } -} \ No newline at end of file +} diff --git a/source/main.cpp b/source/main.cpp index de60173..477f0ae 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -11,7 +11,7 @@ #include #include #include -// #include +#include #include "imgui.h" #include "SDL2/SDL.h" @@ -271,8 +271,8 @@ static void terminate() int main() { - // dbglogger_init(); - // dbglogger_log("If you see this you've set up dbglogger correctly."); + dbglogger_init(); + dbglogger_log("If you see this you've set up dbglogger correctly."); int rc; // No buffering setvbuf(stdout, NULL, _IONBF, 0); diff --git a/source/orbis_jbc.c b/source/orbis_jbc.c index 9d31094..dfb4cd6 100644 --- a/source/orbis_jbc.c +++ b/source/orbis_jbc.c @@ -2,9 +2,70 @@ #include #include #include +#include #include #include +#define SYSCALL(nr, fn) __attribute__((naked)) fn\ +{\ + asm volatile("mov $" #nr ", %rax\nmov %rcx, %r10\nsyscall\nret");\ +} + +SYSCALL(22, static int unmount(const char* path, int flags)) +SYSCALL(378, static int nmount(struct iovec* iov, unsigned int niov, int flags)) + +static void build_iovec(struct iovec** iov, int* iovlen, const char* name, const void* val, size_t len) { + int i; + + if (*iovlen < 0) + return; + + i = *iovlen; + *iov = (struct iovec*)realloc(*iov, sizeof **iov * (i + 2)); + if (*iov == NULL) { + *iovlen = -1; + return; + } + + (*iov)[i].iov_base = strdup(name); + (*iov)[i].iov_len = strlen(name) + 1; + ++i; + + (*iov)[i].iov_base = (void*)val; + if (len == (size_t)-1) { + if (val != NULL) + len = strlen((const char*)val) + 1; + else + len = 0; + } + (*iov)[i].iov_len = (int)len; + + *iovlen = ++i; +} + +int mount_large_fs(const char* device, const char* mountpoint, const char* fstype, const char* mode, unsigned int flags) +{ + struct iovec* iov = NULL; + int iovlen = 0; + + unmount(mountpoint, 0); + + build_iovec(&iov, &iovlen, "fstype", fstype, -1); + build_iovec(&iov, &iovlen, "fspath", mountpoint, -1); + build_iovec(&iov, &iovlen, "from", device, -1); + build_iovec(&iov, &iovlen, "large", "yes", -1); + build_iovec(&iov, &iovlen, "timezone", "static", -1); + build_iovec(&iov, &iovlen, "async", "", -1); + build_iovec(&iov, &iovlen, "ignoreacl", "", -1); + + if (mode) { + build_iovec(&iov, &iovlen, "dirmask", mode, -1); + build_iovec(&iov, &iovlen, "mask", mode, -1); + } + + return nmount(iov, iovlen, flags); +} + // Variables for (un)jailbreaking jbc_cred g_Cred; jbc_cred g_RootCreds; diff --git a/source/orbis_jbc.h b/source/orbis_jbc.h index 4e1a1b4..e75cedb 100644 --- a/source/orbis_jbc.h +++ b/source/orbis_jbc.h @@ -1,7 +1,10 @@ #ifndef __ORBIS_JBC_H__ #define __ORBIS_JBC_H__ +#define MNT_UPDATE 0x0000000000010000ULL + int initialize_jbc(); void terminate_jbc(); +int mount_large_fs(const char* device, const char* mountpoint, const char* fstype, const char* mode, unsigned int flags); #endif diff --git a/source/server/http_server.cpp b/source/server/http_server.cpp index 960a7fa..875a3fe 100644 --- a/source/server/http_server.cpp +++ b/source/server/http_server.cpp @@ -920,30 +920,34 @@ namespace HttpServer res.set_content(str.c_str(), "text/plain"); }); - svr->Get("/rmt_inst/(.*)", [&](const Request & req, Response & res) + svr->Get("/rmt_inst/Site (\\d+)(/)(.*)", [&](const Request & req, Response & res) { RemoteClient *tmp_client; - auto path = std::string("/") + std::string(req.matches[1]); + RemoteSettings *tmp_settings; + auto site_idx = std::stoi(req.matches[1])-1; + auto path = std::string("/") + std::string(req.matches[3]); - if (remote_settings->type == CLIENT_TYPE_SFTP) + tmp_settings = &site_settings[sites[site_idx]]; + + if (tmp_settings->type == CLIENT_TYPE_SFTP) { tmp_client = new SFTPClient(); - tmp_client->Connect(remote_settings->server, remote_settings->username, remote_settings->password); + tmp_client->Connect(tmp_settings->server, tmp_settings->username, tmp_settings->password); } - else if (remote_settings->type == CLIENT_TYPE_SMB) + else if (tmp_settings->type == CLIENT_TYPE_SMB) { tmp_client = new SmbClient(); - tmp_client->Connect(remote_settings->server, remote_settings->username, remote_settings->password); + tmp_client->Connect(tmp_settings->server, tmp_settings->username, tmp_settings->password); } - else if (remote_settings->type == CLIENT_TYPE_FTP) + else if (tmp_settings->type == CLIENT_TYPE_FTP) { tmp_client = new FtpClient(); - tmp_client->Connect(remote_settings->server, remote_settings->username, remote_settings->password); + tmp_client->Connect(tmp_settings->server, tmp_settings->username, tmp_settings->password); } - else if (remote_settings->type == CLIENT_TYPE_NFS) + else if (tmp_settings->type == CLIENT_TYPE_NFS) { tmp_client = new NfsClient(); - tmp_client->Connect(remote_settings->server, remote_settings->username, remote_settings->password); + tmp_client->Connect(tmp_settings->server, tmp_settings->username, tmp_settings->password); } else { @@ -1072,4 +1076,4 @@ namespace HttpServer if (svr != nullptr) svr->stop(); } -} \ No newline at end of file +}