Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c3cc6d5954 | |||
| cfcb420b9d | |||
| 294455c735 | |||
| 4ff119b34d | |||
| 114c1974e1 | |||
| a99bf163d8 | |||
| b9ab71577f | |||
| f80b3112c6 | |||
| e0c72c85e5 | |||
| 01f568feac | |||
| 2046a0e096 |
+3
-2
@@ -1,4 +1,4 @@
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
project(ezremote_client)
|
||||
|
||||
@@ -25,6 +25,7 @@ add_executable(ezremote_client
|
||||
source/http/httplib.cpp
|
||||
source/clients/baseclient.cpp
|
||||
source/clients/apache.cpp
|
||||
source/clients/archiveorg.cpp
|
||||
source/clients/ftpclient.cpp
|
||||
source/clients/gdrive.cpp
|
||||
source/clients/iis.cpp
|
||||
@@ -67,7 +68,7 @@ add_executable(ezremote_client
|
||||
|
||||
add_self(ezremote_client)
|
||||
|
||||
add_pkg(ezremote_client ${CMAKE_SOURCE_DIR}/data "RMTC00001" "ezRemote Client" "01.26" 32 0)
|
||||
add_pkg(ezremote_client ${CMAKE_SOURCE_DIR}/data "RMTC00001" "ezRemote Client" "01.28" 32 0)
|
||||
|
||||
target_link_libraries(ezremote_client
|
||||
c
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 115 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 104 KiB |
@@ -160,3 +160,4 @@ STR_LANGUAGE=Language
|
||||
STR_TEMP_DIRECTORY=Temp Directory
|
||||
STR_REALDEBRID=Real-Debrid
|
||||
STR_BACKGROUND_INSTALL_INPROGRESS=Package install is running in the background. Don't close the app while install is in progress
|
||||
STR_ENABLE_DISC_CACHE_MSG=Enable disk caching. Can improve package install speed in cases where connection to remote is slow
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+46
-5
@@ -10,6 +10,7 @@
|
||||
#include "clients/smbclient.h"
|
||||
#include "clients/webdav.h"
|
||||
#include "clients/apache.h"
|
||||
#include "clients/archiveorg.h"
|
||||
#include "clients/nginx.h"
|
||||
#include "clients/npxserve.h"
|
||||
#include "clients/nfsclient.h"
|
||||
@@ -712,13 +713,39 @@ namespace Actions
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string url = INSTALLER::getRemoteUrl(it->path, true);
|
||||
std::string title = INSTALLER::GetRemotePkgTitle(remoteclient, it->path, &header);
|
||||
if (remote_settings->enable_disk_cache)
|
||||
{
|
||||
SplitPkgInstallData *install_data = (SplitPkgInstallData*) malloc(sizeof(SplitPkgInstallData));
|
||||
memset(install_data, 0, sizeof(SplitPkgInstallData));
|
||||
|
||||
if (INSTALLER::InstallRemotePkg(url, &header, title, true) == 0)
|
||||
failed++;
|
||||
OrbisTick tick;
|
||||
sceRtcGetCurrentTick(&tick);
|
||||
std::string install_pkg_path = std::string(temp_folder) + "/" + std::to_string(tick.mytick) + ".pkg";
|
||||
SplitFile *sp = new SplitFile(install_pkg_path, INSTALL_ARCHIVE_PKG_SPLIT_SIZE/2);
|
||||
|
||||
install_data->split_file = sp;
|
||||
install_data->remote_client = remoteclient;
|
||||
install_data->path = it->path;
|
||||
remoteclient->Size(it->path, &install_data->size);
|
||||
install_data->stop_write_thread = false;
|
||||
install_data->delete_client = false;
|
||||
|
||||
int ret = pthread_create(&install_data->thread, NULL, DownloadSplitPkg, install_data);
|
||||
|
||||
if (INSTALLER::InstallSplitPkg(it->path, install_data, false) == 0)
|
||||
failed++;
|
||||
else
|
||||
success++;
|
||||
}
|
||||
else
|
||||
success++;
|
||||
{
|
||||
std::string url = INSTALLER::getRemoteUrl(it->path, true);
|
||||
std::string title = INSTALLER::GetRemotePkgTitle(remoteclient, it->path, &header);
|
||||
if (INSTALLER::InstallRemotePkg(url, &header, title, true) == 0)
|
||||
failed++;
|
||||
else
|
||||
success++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -821,6 +848,18 @@ namespace Actions
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *DownloadSplitPkg(void *argp)
|
||||
{
|
||||
SplitPkgInstallData *install_data = (SplitPkgInstallData*) argp;
|
||||
SplitFile *sp = install_data->split_file;
|
||||
|
||||
/* loop over file contents and write to fd */
|
||||
sp->Open();
|
||||
install_data->remote_client->Get(sp, install_data->path);
|
||||
sp->Close();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *InstallLocalPkgsThread(void *argp)
|
||||
{
|
||||
int failed = 0;
|
||||
@@ -1208,6 +1247,8 @@ namespace Actions
|
||||
remoteclient = new NpxServeClient();
|
||||
else if (strcmp(remote_settings->http_server_type, HTTP_SERVER_RCLONE) == 0)
|
||||
remoteclient = new RCloneClient();
|
||||
else if (strcmp(remote_settings->http_server_type, HTTP_SERVER_ARCHIVEORG) == 0)
|
||||
remoteclient = new ArchiveOrgClient();
|
||||
}
|
||||
else if (strncmp(remote_settings->server, "webdavs://", 10) == 0 || strncmp(remote_settings->server, "webdav://", 9) == 0)
|
||||
{
|
||||
|
||||
@@ -120,6 +120,7 @@ namespace Actions
|
||||
void CreateLocalFile(char *filename);
|
||||
void CreateRemoteFile(char *filename);
|
||||
void *ExtractArchivePkg(void *argp);
|
||||
void *DownloadSplitPkg(void *argp);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,237 @@
|
||||
#include <lexbor/html/parser.h>
|
||||
#include <lexbor/dom/interfaces/element.h>
|
||||
#include <lexbor/dom/interfaces/node.h>
|
||||
#include <fstream>
|
||||
#include <map>
|
||||
#include "common.h"
|
||||
#include "clients/remote_client.h"
|
||||
#include "clients/archiveorg.h"
|
||||
#include "lang.h"
|
||||
#include "util.h"
|
||||
#include "system.h"
|
||||
#include "windows.h"
|
||||
|
||||
using httplib::Client;
|
||||
using httplib::Headers;
|
||||
using httplib::Result;
|
||||
|
||||
static std::map<std::string, int> month_map = {{"Jan", 1}, {"Feb", 2}, {"Mar", 3}, {"Apr", 4}, {"May", 5}, {"Jun", 6}, {"Jul", 7}, {"Aug", 8}, {"Sep", 9}, {"Oct", 10}, {"Nov", 11}, {"Dec", 12}};
|
||||
|
||||
std::vector<DirEntry> ArchiveOrgClient::ListDir(const std::string &path)
|
||||
{
|
||||
std::vector<DirEntry> 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 *table_element, *tr_element, *td_element;
|
||||
lxb_html_document_t *document;
|
||||
lxb_dom_collection_t *table_collection;
|
||||
lxb_dom_collection_t *tr_collection;
|
||||
lxb_dom_collection_t *td_collection;
|
||||
std::string tmp_string;
|
||||
const lxb_char_t *value;
|
||||
size_t value_len;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
table_collection = lxb_dom_collection_make(&document->dom_document, 1);
|
||||
if (table_collection == NULL)
|
||||
{
|
||||
lxb_html_document_destroy(document);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
tr_collection = lxb_dom_collection_make(&document->dom_document, 128);
|
||||
if (tr_collection == NULL)
|
||||
{
|
||||
lxb_html_document_destroy(document);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
status = lxb_dom_elements_by_tag_name(lxb_dom_interface_element(document->body),
|
||||
table_collection, (const lxb_char_t *)"table", 5);
|
||||
if (status != LXB_STATUS_OK)
|
||||
{
|
||||
lxb_dom_collection_destroy(tr_collection, true);
|
||||
lxb_dom_collection_destroy(table_collection, true);
|
||||
lxb_html_document_destroy(document);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (lxb_dom_collection_length(table_collection) < 1)
|
||||
{
|
||||
lxb_dom_collection_destroy(tr_collection, true);
|
||||
lxb_dom_collection_destroy(table_collection, true);
|
||||
lxb_html_document_destroy(document);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < lxb_dom_collection_length(table_collection); i++)
|
||||
{
|
||||
table_element = lxb_dom_collection_element(table_collection, i);
|
||||
value = lxb_dom_element_class(table_element, &value_len);
|
||||
tmp_string = std::string((const char *)value, value_len);
|
||||
if (tmp_string.compare("directory-listing-table") == 0)
|
||||
break;
|
||||
table_element = nullptr;
|
||||
}
|
||||
|
||||
if (table_element == nullptr)
|
||||
{
|
||||
lxb_dom_collection_destroy(tr_collection, true);
|
||||
lxb_dom_collection_destroy(table_collection, true);
|
||||
lxb_html_document_destroy(document);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
status = lxb_dom_elements_by_tag_name(table_element,
|
||||
tr_collection, (const lxb_char_t *)"tr", 2);
|
||||
if (status != LXB_STATUS_OK && lxb_dom_collection_length(tr_collection) < 2)
|
||||
{
|
||||
lxb_dom_collection_destroy(tr_collection, true);
|
||||
lxb_dom_collection_destroy(table_collection, true);
|
||||
lxb_html_document_destroy(document);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
// skip row 0 , since it has the previous folder header
|
||||
for (size_t i = 2; i < lxb_dom_collection_length(tr_collection); i++)
|
||||
{
|
||||
DirEntry entry;
|
||||
std::string title, aclass;
|
||||
memset(&entry.modified, 0, sizeof(DateTime));
|
||||
|
||||
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) < 3)
|
||||
{
|
||||
lxb_dom_collection_destroy(td_collection, true);
|
||||
lxb_dom_collection_destroy(tr_collection, true);
|
||||
lxb_dom_collection_destroy(table_collection, true);
|
||||
lxb_html_document_destroy(document);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
// td0 contains the <a> tag
|
||||
td_element = lxb_dom_collection_element(td_collection, 0);
|
||||
lxb_dom_node_t *a_node = NextChildElement(td_element);
|
||||
value = lxb_dom_element_local_name(lxb_dom_interface_element(a_node), &value_len);
|
||||
tmp_string = std::string((const char *)value, value_len);
|
||||
if (tmp_string.compare("a") != 0)
|
||||
{
|
||||
lxb_dom_collection_destroy(td_collection, true);
|
||||
lxb_dom_collection_destroy(tr_collection, true);
|
||||
lxb_dom_collection_destroy(table_collection, true);
|
||||
lxb_html_document_destroy(document);
|
||||
goto finish;
|
||||
}
|
||||
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::UnEscape(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);
|
||||
}
|
||||
|
||||
// next td contains the date
|
||||
td_element = lxb_dom_collection_element(td_collection, 1);
|
||||
value = lxb_dom_node_text_content(NextChildTextNode(td_element), &value_len);
|
||||
tmp_string = std::string((const char *)value, value_len);
|
||||
std::vector<std::string> date_time = Util::Split(tmp_string, " ");
|
||||
|
||||
if (date_time.size() > 1)
|
||||
{
|
||||
std::vector<std::string> adate = Util::Split(date_time[0], "-");
|
||||
if (adate.size() == 3)
|
||||
{
|
||||
entry.modified.day = atoi(adate[0].c_str());
|
||||
entry.modified.month = month_map[adate[1]];
|
||||
entry.modified.year = atoi(adate[2].c_str());
|
||||
}
|
||||
|
||||
std::vector<std::string> atime = Util::Split(date_time[1], ":");
|
||||
if (atime.size() == 2)
|
||||
{
|
||||
entry.modified.hours = atoi(atime[0].c_str());
|
||||
entry.modified.minutes = atoi(atime[1].c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// next td contains file size, if fize size is "-", then it's a directory
|
||||
td_element = lxb_dom_collection_element(td_collection, 2);
|
||||
value = lxb_dom_node_text_content(NextChildTextNode(td_element), &value_len);
|
||||
tmp_string = std::string((const char *)value, value_len);
|
||||
|
||||
if (tmp_string.compare("-") == 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;
|
||||
uint64_t multiplier = 0;
|
||||
float fsize = std::stof(tmp_string.substr(0, tmp_string.size()-1));
|
||||
switch (tmp_string[tmp_string.size()-1]) {
|
||||
case 'B':
|
||||
multiplier = 1;
|
||||
break;
|
||||
case 'K':
|
||||
multiplier = 1024;
|
||||
break;
|
||||
case 'M':
|
||||
multiplier = 1048576;
|
||||
break;
|
||||
case 'G':
|
||||
multiplier = 1073741824;
|
||||
break;
|
||||
default:
|
||||
multiplier = 1;
|
||||
}
|
||||
entry.file_size = fsize * multiplier;
|
||||
DirEntry::SetDisplaySize(&entry);
|
||||
}
|
||||
|
||||
lxb_dom_collection_destroy(td_collection, true);
|
||||
out.push_back(entry);
|
||||
}
|
||||
|
||||
lxb_dom_collection_destroy(tr_collection, true);
|
||||
lxb_dom_collection_destroy(table_collection, true);
|
||||
lxb_html_document_destroy(document);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(this->response, "%s", httplib::to_string(res.error()).c_str());
|
||||
return out;
|
||||
}
|
||||
|
||||
finish:
|
||||
return out;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#ifndef EZ_ARCHIVEORG_H
|
||||
#define EZ_ARCHIVEORG_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "http/httplib.h"
|
||||
#include "clients/remote_client.h"
|
||||
#include "clients/baseclient.h"
|
||||
#include "common.h"
|
||||
|
||||
class ArchiveOrgClient : public BaseClient
|
||||
{
|
||||
public:
|
||||
std::vector<DirEntry> ListDir(const std::string &path);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -122,6 +122,29 @@ int BaseClient::Get(const std::string &outputfile, const std::string &path, uint
|
||||
return 0;
|
||||
}
|
||||
|
||||
int BaseClient::Get(SplitFile *split_file, const std::string &path, uint64_t offset)
|
||||
{
|
||||
if (auto res = client->Get(GetFullPath(path),
|
||||
[&](const char *data, size_t data_length)
|
||||
{
|
||||
if (!split_file->IsClosed())
|
||||
{
|
||||
split_file->Write((char*)data, data_length);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(this->response, "%s", httplib::to_string(res.error()).c_str());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int BaseClient::GetRange(const std::string &path, DataSink &sink, uint64_t size, uint64_t offset)
|
||||
{
|
||||
char range_header[64];
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "http/httplib.h"
|
||||
#include "clients/remote_client.h"
|
||||
#include "http/httplib.h"
|
||||
#include "split_file.h"
|
||||
#include "common.h"
|
||||
|
||||
class BaseClient : public RemoteClient
|
||||
@@ -21,6 +22,7 @@ public:
|
||||
int Rmdir(const std::string &path, bool recursive);
|
||||
int Size(const std::string &path, int64_t *size);
|
||||
int Get(const std::string &outputfile, const std::string &path, uint64_t offset=0);
|
||||
int Get(SplitFile *split_file, const std::string &path, uint64_t offset=0);
|
||||
int GetRange(const std::string &path, void *buffer, uint64_t size, uint64_t offset);
|
||||
int GetRange(const std::string &path, DataSink &sink, uint64_t size, uint64_t offset);
|
||||
int GetRange(void *fp, void *buffer, uint64_t size, uint64_t offset);
|
||||
|
||||
@@ -880,6 +880,32 @@ int FtpClient::FtpXfer(const std::string &localfile, const std::string &path, ft
|
||||
return FtpClose(nData);
|
||||
}
|
||||
|
||||
/*
|
||||
* FtpXfer - issue a command and transfer data
|
||||
*
|
||||
* return 1 if successful, 0 otherwise
|
||||
*/
|
||||
int FtpClient::FtpXfer(SplitFile *split_file, const std::string &path, ftphandle *nControl, accesstype type, transfermode mode)
|
||||
{
|
||||
int l, c;
|
||||
char *dbuf;
|
||||
ftphandle *nData;
|
||||
|
||||
if (!FtpAccess(path, type, mode, nControl, &nData))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
dbuf = static_cast<char *>(malloc(FTP_CLIENT_BUFSIZ));
|
||||
while ((l = FtpRead(dbuf, FTP_CLIENT_BUFSIZ, nData)) > 0)
|
||||
{
|
||||
split_file->Write(dbuf, l);
|
||||
}
|
||||
|
||||
free(dbuf);
|
||||
return FtpClose(nData);
|
||||
}
|
||||
|
||||
/*
|
||||
* FtpWrite - write to a data connection
|
||||
*/
|
||||
@@ -1283,6 +1309,15 @@ int FtpClient::Get(const std::string &outputfile, const std::string &path, uint6
|
||||
return FtpXfer(outputfile, path, mp_ftphandle, FtpClient::filereadappend, FtpClient::transfermode::image);
|
||||
}
|
||||
|
||||
int FtpClient::Get(SplitFile *split_file, const std::string &path, uint64_t offset)
|
||||
{
|
||||
mp_ftphandle->offset = offset;
|
||||
if (offset == 0)
|
||||
return FtpXfer(split_file, path, mp_ftphandle, FtpClient::fileread, FtpClient::transfermode::image);
|
||||
else
|
||||
return FtpXfer(split_file, path, mp_ftphandle, FtpClient::filereadappend, FtpClient::transfermode::image);
|
||||
}
|
||||
|
||||
int FtpClient::GetRange(const std::string &path, DataSink &sink, uint64_t size, uint64_t offset)
|
||||
{
|
||||
ftphandle *nData;
|
||||
@@ -1787,7 +1822,7 @@ int FtpClient::Head(const std::string &path, void *buffer, uint64_t len)
|
||||
|
||||
void *FtpClient::Open(const std::string &path, int flags)
|
||||
{
|
||||
return nullptr;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void FtpClient::Close(void *fp)
|
||||
@@ -1796,10 +1831,10 @@ void FtpClient::Close(void *fp)
|
||||
|
||||
int FtpClient::GetRange(void *fp, DataSink &sink, uint64_t size, uint64_t offset)
|
||||
{
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int FtpClient::GetRange(void *fp, void *buffer, uint64_t size, uint64_t offset)
|
||||
{
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -79,6 +79,7 @@ public:
|
||||
int Rmdir(const std::string &path, bool recursive);
|
||||
int Size(const std::string &path, int64_t *size);
|
||||
int Get(const std::string &outputfile, const std::string &path, uint64_t offset = 0);
|
||||
int Get(SplitFile *split_file, const std::string &path, uint64_t offset=0);
|
||||
int GetRange(const std::string &path, void *buffer, uint64_t size, uint64_t offset);
|
||||
int GetRange(const std::string &path, DataSink &sink, uint64_t size, uint64_t offset);
|
||||
int GetRange(void *fp, void *buffer, uint64_t size, uint64_t offset);
|
||||
@@ -128,6 +129,7 @@ private:
|
||||
int CorrectPasvResponse(int *v);
|
||||
int FtpAccess(const std::string &path, accesstype type, transfermode mode, ftphandle *nControl, ftphandle **nData);
|
||||
int FtpXfer(const std::string &localfile, const std::string &path, ftphandle *nControl, accesstype type, transfermode mode);
|
||||
int FtpXfer(SplitFile *split_file, const std::string &path, ftphandle *nControl, accesstype type, transfermode mode);
|
||||
int FtpWrite(void *buf, int len, ftphandle *nData);
|
||||
int FtpRead(void *buf, int max, ftphandle *nData);
|
||||
int FtpClose(ftphandle *nData);
|
||||
|
||||
@@ -332,6 +332,34 @@ int GDriveClient::Get(const std::string &outputfile, const std::string &path, ui
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GDriveClient::Get(SplitFile *split_file, const std::string &path, uint64_t offset)
|
||||
{
|
||||
std::string id = GetValue(path_id_map, path);
|
||||
std::string drive_id = GetDriveId(path);
|
||||
std::string url = std::string("/drive/v3/files/") + BaseClient::Escape(id) + "?alt=media";
|
||||
if (!drive_id.empty())
|
||||
url += "&supportsAllDrives=true";
|
||||
if (auto res = client->Get(url,
|
||||
[&](const char *data, size_t data_length)
|
||||
{
|
||||
if (!split_file->IsClosed())
|
||||
{
|
||||
split_file->Write((char*)data, data_length);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(this->response, "%s", httplib::to_string(res.error()).c_str());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GDriveClient::GetRange(const std::string &path, DataSink &sink, uint64_t size, uint64_t offset)
|
||||
{
|
||||
size_t bytes_read = 0;
|
||||
|
||||
@@ -20,6 +20,7 @@ public:
|
||||
int Connect(const std::string &url, const std::string &user, const std::string &pass);
|
||||
int Rename(const std::string &src, const std::string &dst);
|
||||
int Get(const std::string &outputfile, const std::string &path, uint64_t offset=0);
|
||||
int Get(SplitFile *split_file, const std::string &path, uint64_t offset=0);
|
||||
int GetRange(const std::string &path, void *buffer, uint64_t size, uint64_t offset);
|
||||
int GetRange(const std::string &path, DataSink &sink, uint64_t size, uint64_t offset);
|
||||
int GetRange(void *fp, void *buffer, uint64_t size, uint64_t offset);
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#include "util.h"
|
||||
#include "system.h"
|
||||
|
||||
#define BUF_SIZE 256*1024
|
||||
#define BUF_SIZE 256 * 1024
|
||||
|
||||
NfsClient::NfsClient()
|
||||
{
|
||||
@@ -37,7 +37,8 @@ int NfsClient::Connect(const std::string &url, const std::string &user, const st
|
||||
}
|
||||
|
||||
struct nfs_url *nfsurl = nfs_parse_url_full(nfs, url.c_str());
|
||||
if (nfsurl == nullptr) {
|
||||
if (nfsurl == nullptr)
|
||||
{
|
||||
sprintf(response, "%s", nfs_get_error(nfs));
|
||||
nfs_destroy_context(nfs);
|
||||
return 0;
|
||||
@@ -203,7 +204,7 @@ int NfsClient::Get(const std::string &outputfile, const std::string &ppath, uint
|
||||
return 0;
|
||||
}
|
||||
|
||||
FILE* out = FS::Create(outputfile);
|
||||
FILE *out = FS::Create(outputfile);
|
||||
if (out == NULL)
|
||||
{
|
||||
sprintf(response, "%s", lang_strings[STR_FAILED]);
|
||||
@@ -221,7 +222,7 @@ int NfsClient::Get(const std::string &outputfile, const std::string &ppath, uint
|
||||
sprintf(response, "%s", nfs_get_error(nfs));
|
||||
FS::Close(out);
|
||||
nfs_close(nfs, nfsfh);
|
||||
free((void*)buff);
|
||||
free((void *)buff);
|
||||
return 0;
|
||||
}
|
||||
FS::Write(out, buff, count);
|
||||
@@ -229,7 +230,36 @@ int NfsClient::Get(const std::string &outputfile, const std::string &ppath, uint
|
||||
}
|
||||
FS::Close(out);
|
||||
nfs_close(nfs, nfsfh);
|
||||
free((void*)buff);
|
||||
free((void *)buff);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int NfsClient::Get(SplitFile *split_file, const std::string &ppath, uint64_t offset)
|
||||
{
|
||||
struct nfsfh *nfsfh = nullptr;
|
||||
int ret = nfs_open(nfs, ppath.c_str(), 0400, &nfsfh);
|
||||
if (ret != 0)
|
||||
{
|
||||
sprintf(response, "%s", nfs_get_error(nfs));
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *buff = malloc(BUF_SIZE);
|
||||
int count = 0;
|
||||
while ((count = nfs_read(nfs, nfsfh, BUF_SIZE, buff)) > 0)
|
||||
{
|
||||
if (count < 0)
|
||||
{
|
||||
sprintf(response, "%s", nfs_get_error(nfs));
|
||||
nfs_close(nfs, nfsfh);
|
||||
free((void *)buff);
|
||||
return 0;
|
||||
}
|
||||
split_file->Write((char *)buff, count);
|
||||
}
|
||||
nfs_close(nfs, nfsfh);
|
||||
free((void *)buff);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -260,29 +290,29 @@ int NfsClient::GetRange(void *fp, DataSink &sink, uint64_t size, uint64_t offset
|
||||
}
|
||||
|
||||
void *buff = malloc(BUF_SIZE);
|
||||
int count = 0;
|
||||
size_t bytes_remaining = size;
|
||||
do
|
||||
{
|
||||
size_t bytes_to_read = std::min<size_t>(BUF_SIZE, bytes_remaining);
|
||||
count = nfs_read(nfs, nfsfh, bytes_to_read, buff);
|
||||
if (count > 0)
|
||||
{
|
||||
bytes_remaining -= count;
|
||||
bool ok = sink.write((char*)buff, count);
|
||||
int count = 0;
|
||||
size_t bytes_remaining = size;
|
||||
do
|
||||
{
|
||||
size_t bytes_to_read = std::min<size_t>(BUF_SIZE, bytes_remaining);
|
||||
count = nfs_read(nfs, nfsfh, bytes_to_read, buff);
|
||||
if (count > 0)
|
||||
{
|
||||
bytes_remaining -= count;
|
||||
bool ok = sink.write((char *)buff, count);
|
||||
if (!ok)
|
||||
{
|
||||
free((void *)buff);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
} while (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
} while (1);
|
||||
|
||||
free((void *)buff);
|
||||
free((void *)buff);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -304,7 +334,7 @@ int NfsClient::GetRange(const std::string &ppath, void *buffer, uint64_t size, u
|
||||
|
||||
int NfsClient::GetRange(void *fp, void *buffer, uint64_t size, uint64_t offset)
|
||||
{
|
||||
struct nfsfh *nfsfh = (struct nfsfh *) fp;
|
||||
struct nfsfh *nfsfh = (struct nfsfh *)fp;
|
||||
|
||||
int ret = nfs_lseek(nfs, nfsfh, offset, SEEK_SET, NULL);
|
||||
if (ret != 0)
|
||||
@@ -358,13 +388,13 @@ int NfsClient::Put(const std::string &inputfile, const std::string &ppath, uint6
|
||||
return 0;
|
||||
}
|
||||
|
||||
FILE* in = FS::OpenRead(inputfile);
|
||||
FILE *in = FS::OpenRead(inputfile);
|
||||
if (in == NULL)
|
||||
{
|
||||
sprintf(response, "%s", lang_strings[STR_FAILED]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct nfsfh *nfsfh = nullptr;
|
||||
int ret;
|
||||
if (!FileExists(ppath))
|
||||
@@ -380,7 +410,7 @@ int NfsClient::Put(const std::string &inputfile, const std::string &ppath, uint6
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* buff = malloc(BUF_SIZE);
|
||||
void *buff = malloc(BUF_SIZE);
|
||||
uint64_t count = 0;
|
||||
bytes_transfered = 0;
|
||||
sceRtcGetCurrentTick(&prev_tick);
|
||||
@@ -459,7 +489,8 @@ std::vector<DirEntry> NfsClient::ListDir(const std::string &path)
|
||||
struct nfsdirent *nfsdirent;
|
||||
|
||||
int ret = nfs_opendir(nfs, path.c_str(), &nfsdir);
|
||||
if (ret != 0) {
|
||||
if (ret != 0)
|
||||
{
|
||||
sprintf(response, "%s", nfs_get_error(nfs));
|
||||
return out;
|
||||
}
|
||||
@@ -526,7 +557,6 @@ std::vector<DirEntry> NfsClient::ListDir(const std::string &path)
|
||||
}
|
||||
if (strcmp(entry.name, "..") != 0 && strcmp(entry.name, ".") != 0)
|
||||
out.push_back(entry);
|
||||
|
||||
}
|
||||
nfs_closedir(nfs, nfsdir);
|
||||
|
||||
@@ -569,13 +599,14 @@ int NfsClient::Head(const std::string &ppath, void *buffer, uint64_t len)
|
||||
void *NfsClient::Open(const std::string &path, int flags)
|
||||
{
|
||||
struct nfsfh *nfsfh = nullptr;
|
||||
nfs_open(nfs, path.c_str(), 0400, &nfsfh);;
|
||||
nfs_open(nfs, path.c_str(), 0400, &nfsfh);
|
||||
;
|
||||
return nfsfh;
|
||||
}
|
||||
|
||||
void NfsClient::Close(void *fp)
|
||||
{
|
||||
nfs_close(nfs, (struct nfsfh*)fp);
|
||||
nfs_close(nfs, (struct nfsfh *)fp);
|
||||
}
|
||||
|
||||
ClientType NfsClient::clientType()
|
||||
|
||||
@@ -23,6 +23,7 @@ public:
|
||||
int Rmdir(const std::string &path, bool recursive);
|
||||
int Size(const std::string &path, int64_t *size);
|
||||
int Get(const std::string &outputfile, const std::string &path, uint64_t offset=0);
|
||||
int Get(SplitFile *split_file, const std::string &path, uint64_t offset=0);
|
||||
int GetRange(const std::string &path, void *buffer, uint64_t size, uint64_t offset);
|
||||
int GetRange(const std::string &path, DataSink &sink, uint64_t size, uint64_t offset);
|
||||
int GetRange(void *fp, void *buffer, uint64_t size, uint64_t offset);
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <vector>
|
||||
#include "common.h"
|
||||
#include "http/httplib.h"
|
||||
#include "split_file.h"
|
||||
|
||||
enum RemoteActions
|
||||
{
|
||||
@@ -49,6 +50,7 @@ public:
|
||||
virtual int Rmdir(const std::string &path, bool recursive) = 0;
|
||||
virtual int Size(const std::string &path, int64_t *size) = 0;
|
||||
virtual int Get(const std::string &outputfile, const std::string &path, uint64_t offset=0) = 0;
|
||||
virtual int Get(SplitFile *split_file, const std::string &path, uint64_t offset=0) = 0;
|
||||
virtual int Put(const std::string &inputfile, const std::string &path, uint64_t offset=0) = 0;
|
||||
virtual int Rename(const std::string &src, const std::string &dst) = 0;
|
||||
virtual int Delete(const std::string &path) = 0;
|
||||
|
||||
@@ -306,6 +306,36 @@ int SFTPClient::Get(const std::string &outputfile, const std::string &path, uint
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SFTPClient::Get(SplitFile *split_file, const std::string &path, uint64_t offset)
|
||||
{
|
||||
LIBSSH2_SFTP_HANDLE *sftp_handle = libssh2_sftp_open(sftp_session, path.c_str(), LIBSSH2_FXF_READ, 0);
|
||||
if (!sftp_handle)
|
||||
{
|
||||
sprintf(response, "Unable to open file with SFTP: %ld", libssh2_sftp_last_error(sftp_session));
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *buff = (char *)malloc(FTP_CLIENT_BUFSIZ);
|
||||
int rc, count = 0;
|
||||
|
||||
do
|
||||
{
|
||||
rc = libssh2_sftp_read(sftp_handle, buff, FTP_CLIENT_BUFSIZ);
|
||||
if (rc > 0)
|
||||
{
|
||||
split_file->Write(buff, rc);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
} while (1);
|
||||
free((char *)buff);
|
||||
libssh2_sftp_close(sftp_handle);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SFTPClient::GetRange(const std::string &path, DataSink &sink, uint64_t size, uint64_t offset)
|
||||
{
|
||||
LIBSSH2_SFTP_HANDLE *sftp_handle = libssh2_sftp_open(sftp_session, path.c_str(), LIBSSH2_FXF_READ, 0);
|
||||
@@ -323,8 +353,8 @@ int SFTPClient::GetRange(const std::string &path, DataSink &sink, uint64_t size,
|
||||
|
||||
int SFTPClient::GetRange(void *fp, DataSink &sink, uint64_t size, uint64_t offset)
|
||||
{
|
||||
LIBSSH2_SFTP_HANDLE *sftp_handle = (LIBSSH2_SFTP_HANDLE *) fp;
|
||||
|
||||
LIBSSH2_SFTP_HANDLE *sftp_handle = (LIBSSH2_SFTP_HANDLE *)fp;
|
||||
|
||||
libssh2_sftp_seek64(sftp_handle, offset);
|
||||
|
||||
char *buff = (char *)malloc(FTP_CLIENT_BUFSIZ);
|
||||
@@ -352,7 +382,7 @@ int SFTPClient::GetRange(void *fp, DataSink &sink, uint64_t size, uint64_t offse
|
||||
|
||||
free((char *)buff);
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SFTPClient::GetRange(const std::string &path, void *buffer, uint64_t size, uint64_t offset)
|
||||
@@ -377,7 +407,7 @@ int SFTPClient::GetRange(const std::string &path, void *buffer, uint64_t size, u
|
||||
|
||||
int SFTPClient::GetRange(void *fp, void *buffer, uint64_t size, uint64_t offset)
|
||||
{
|
||||
LIBSSH2_SFTP_HANDLE *sftp_handle = (LIBSSH2_SFTP_HANDLE *) fp;
|
||||
LIBSSH2_SFTP_HANDLE *sftp_handle = (LIBSSH2_SFTP_HANDLE *)fp;
|
||||
|
||||
libssh2_sftp_seek64(sftp_handle, offset);
|
||||
int count = libssh2_sftp_read(sftp_handle, (char *)buffer, size);
|
||||
|
||||
@@ -20,6 +20,7 @@ public:
|
||||
int Rmdir(const std::string &path);
|
||||
int Size(const std::string &path, int64_t *size);
|
||||
int Get(const std::string &outputfile, const std::string &path, uint64_t offset=0);
|
||||
int Get(SplitFile *split_file, const std::string &path, uint64_t offset=0);
|
||||
int GetRange(const std::string &path, void *buffer, uint64_t size, uint64_t offset);
|
||||
int GetRange(const std::string &path, DataSink &sink, uint64_t size, uint64_t offset);
|
||||
int GetRange(void *fp, void *buffer, uint64_t size, uint64_t offset);
|
||||
|
||||
@@ -197,21 +197,21 @@ int SmbClient::Get(const std::string &outputfile, const std::string &ppath, uint
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct smb2fh* in = smb2_open(smb2, path.c_str(), O_RDONLY);
|
||||
struct smb2fh *in = smb2_open(smb2, path.c_str(), O_RDONLY);
|
||||
if (in == NULL)
|
||||
{
|
||||
sprintf(response, "%s", smb2_get_error(smb2));
|
||||
return 0;
|
||||
}
|
||||
|
||||
FILE* out = FS::Create(outputfile);
|
||||
FILE *out = FS::Create(outputfile);
|
||||
if (out == NULL)
|
||||
{
|
||||
sprintf(response, "%s", lang_strings[STR_FAILED]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t *buff = (uint8_t*)malloc(max_read_size);
|
||||
uint8_t *buff = (uint8_t *)malloc(max_read_size);
|
||||
int count = 0;
|
||||
bytes_transfered = 0;
|
||||
sceRtcGetCurrentTick(&prev_tick);
|
||||
@@ -223,7 +223,7 @@ int SmbClient::Get(const std::string &outputfile, const std::string &ppath, uint
|
||||
sprintf(response, "%s", smb2_get_error(smb2));
|
||||
FS::Close(out);
|
||||
smb2_close(smb2, in);
|
||||
free((void*)buff);
|
||||
free((void *)buff);
|
||||
return 0;
|
||||
}
|
||||
FS::Write(out, buff, count);
|
||||
@@ -231,7 +231,39 @@ int SmbClient::Get(const std::string &outputfile, const std::string &ppath, uint
|
||||
}
|
||||
FS::Close(out);
|
||||
smb2_close(smb2, in);
|
||||
free((void*)buff);
|
||||
free((void *)buff);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SmbClient::Get(SplitFile *split_file, const std::string &ppath, uint64_t offset)
|
||||
{
|
||||
std::string path = std::string(ppath);
|
||||
path = Util::Trim(path, "/");
|
||||
|
||||
struct smb2fh *in = smb2_open(smb2, path.c_str(), O_RDONLY);
|
||||
if (in == NULL)
|
||||
{
|
||||
sprintf(response, "%s", smb2_get_error(smb2));
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t *buff = (uint8_t *)malloc(max_read_size);
|
||||
int count = 0;
|
||||
|
||||
while ((count = smb2_read(smb2, in, buff, max_read_size)) > 0)
|
||||
{
|
||||
if (count < 0)
|
||||
{
|
||||
sprintf(response, "%s", smb2_get_error(smb2));
|
||||
smb2_close(smb2, in);
|
||||
free((void *)buff);
|
||||
return 0;
|
||||
}
|
||||
split_file->Write((char*)buff, count);
|
||||
}
|
||||
|
||||
smb2_close(smb2, in);
|
||||
free((void *)buff);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -239,7 +271,7 @@ int SmbClient::GetRange(const std::string &ppath, DataSink &sink, uint64_t size,
|
||||
{
|
||||
std::string path = std::string(ppath);
|
||||
path = Util::Trim(path, "/");
|
||||
struct smb2fh* in = smb2_open(smb2, path.c_str(), O_RDONLY);
|
||||
struct smb2fh *in = smb2_open(smb2, path.c_str(), O_RDONLY);
|
||||
if (in == NULL)
|
||||
{
|
||||
return 0;
|
||||
@@ -253,34 +285,34 @@ int SmbClient::GetRange(const std::string &ppath, DataSink &sink, uint64_t size,
|
||||
|
||||
int SmbClient::GetRange(void *fp, DataSink &sink, uint64_t size, uint64_t offset)
|
||||
{
|
||||
struct smb2fh* in = (struct smb2fh*)fp;
|
||||
struct smb2fh *in = (struct smb2fh *)fp;
|
||||
|
||||
smb2_lseek(smb2, in, offset, SEEK_SET, NULL);
|
||||
smb2_lseek(smb2, in, offset, SEEK_SET, NULL);
|
||||
|
||||
uint8_t *buff = (uint8_t*)malloc(max_read_size);
|
||||
int count = 0;
|
||||
size_t bytes_remaining = size;
|
||||
do
|
||||
{
|
||||
size_t bytes_to_read = std::min<size_t>(max_read_size, bytes_remaining);
|
||||
count = smb2_read(smb2, in, buff, bytes_to_read);
|
||||
if (count > 0)
|
||||
{
|
||||
bytes_remaining -= count;
|
||||
bool ok = sink.write((char*)buff, count);
|
||||
uint8_t *buff = (uint8_t *)malloc(max_read_size);
|
||||
int count = 0;
|
||||
size_t bytes_remaining = size;
|
||||
do
|
||||
{
|
||||
size_t bytes_to_read = std::min<size_t>(max_read_size, bytes_remaining);
|
||||
count = smb2_read(smb2, in, buff, bytes_to_read);
|
||||
if (count > 0)
|
||||
{
|
||||
bytes_remaining -= count;
|
||||
bool ok = sink.write((char *)buff, count);
|
||||
if (!ok)
|
||||
{
|
||||
free((uint8_t *)buff);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
} while (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
} while (1);
|
||||
|
||||
free((char *)buff);
|
||||
free((char *)buff);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -295,7 +327,7 @@ int SmbClient::GetRange(const std::string &ppath, void *buffer, uint64_t size, u
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct smb2fh* in = smb2_open(smb2, path.c_str(), O_RDONLY);
|
||||
struct smb2fh *in = smb2_open(smb2, path.c_str(), O_RDONLY);
|
||||
if (in == NULL)
|
||||
{
|
||||
return 0;
|
||||
@@ -309,13 +341,27 @@ int SmbClient::GetRange(const std::string &ppath, void *buffer, uint64_t size, u
|
||||
|
||||
int SmbClient::GetRange(void *fp, void *buffer, uint64_t size, uint64_t offset)
|
||||
{
|
||||
struct smb2fh* in = (struct smb2fh*) fp;
|
||||
struct smb2fh *in = (struct smb2fh *)fp;
|
||||
|
||||
smb2_lseek(smb2, in, offset, SEEK_SET, NULL);
|
||||
|
||||
int count = smb2_read(smb2, in, (uint8_t*)buffer, size);
|
||||
if (count != size)
|
||||
return 0;
|
||||
uint8_t *buff = (uint8_t *)buffer;
|
||||
int count = 0;
|
||||
size_t bytes_remaining = size;
|
||||
do
|
||||
{
|
||||
size_t bytes_to_read = std::min<size_t>(max_read_size, bytes_remaining);
|
||||
count = smb2_read(smb2, in, buff, bytes_to_read);
|
||||
if (count > 0)
|
||||
{
|
||||
bytes_remaining -= count;
|
||||
buff += count;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
} while (1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -342,14 +388,14 @@ int SmbClient::CopyToSocket(const std::string &ppath, int socket_fd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct smb2fh* in = smb2_open(smb2, path.c_str(), O_RDONLY);
|
||||
struct smb2fh *in = smb2_open(smb2, path.c_str(), O_RDONLY);
|
||||
if (in == NULL)
|
||||
{
|
||||
sprintf(response, "%s", smb2_get_error(smb2));
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t *buff = (uint8_t*)malloc(max_read_size);
|
||||
uint8_t *buff = (uint8_t *)malloc(max_read_size);
|
||||
int count = 0;
|
||||
while ((count = smb2_read(smb2, in, buff, max_read_size)) > 0)
|
||||
{
|
||||
@@ -357,7 +403,7 @@ int SmbClient::CopyToSocket(const std::string &ppath, int socket_fd)
|
||||
{
|
||||
sprintf(response, "%s", smb2_get_error(smb2));
|
||||
smb2_close(smb2, in);
|
||||
free((void*)buff);
|
||||
free((void *)buff);
|
||||
return 0;
|
||||
}
|
||||
int ret = sceNetSend(socket_fd, buff, count, 0);
|
||||
@@ -367,7 +413,7 @@ int SmbClient::CopyToSocket(const std::string &ppath, int socket_fd)
|
||||
}
|
||||
}
|
||||
smb2_close(smb2, in);
|
||||
free((void*)buff);
|
||||
free((void *)buff);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -403,21 +449,21 @@ int SmbClient::Put(const std::string &inputfile, const std::string &ppath, uint6
|
||||
return 0;
|
||||
}
|
||||
|
||||
FILE* in = FS::OpenRead(inputfile);
|
||||
FILE *in = FS::OpenRead(inputfile);
|
||||
if (in == NULL)
|
||||
{
|
||||
sprintf(response, "%s", lang_strings[STR_FAILED]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct smb2fh* out = smb2_open(smb2, path.c_str(), O_WRONLY | O_CREAT | O_TRUNC);
|
||||
|
||||
struct smb2fh *out = smb2_open(smb2, path.c_str(), O_WRONLY | O_CREAT | O_TRUNC);
|
||||
if (out == NULL)
|
||||
{
|
||||
sprintf(response, "%s", smb2_get_error(smb2));
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t* buff = (uint8_t*)malloc(max_write_size);
|
||||
uint8_t *buff = (uint8_t *)malloc(max_write_size);
|
||||
int count = 0;
|
||||
bytes_transfered = 0;
|
||||
sceRtcGetCurrentTick(&prev_tick);
|
||||
@@ -440,7 +486,6 @@ int SmbClient::Put(const std::string &inputfile, const std::string &ppath, uint6
|
||||
free(buff);
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
int SmbClient::Rename(const std::string &src, const std::string &dst)
|
||||
@@ -574,13 +619,13 @@ int SmbClient::Head(const std::string &ppath, void *buffer, uint64_t len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct smb2fh* in = smb2_open(smb2, path.c_str(), O_RDONLY);
|
||||
struct smb2fh *in = smb2_open(smb2, path.c_str(), O_RDONLY);
|
||||
if (in == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int count = smb2_read(smb2, in, (uint8_t*)buffer, len);
|
||||
int count = smb2_read(smb2, in, (uint8_t *)buffer, len);
|
||||
smb2_close(smb2, in);
|
||||
if (count != len)
|
||||
return 0;
|
||||
@@ -593,13 +638,13 @@ void *SmbClient::Open(const std::string &ppath, int flags)
|
||||
std::string path = std::string(ppath);
|
||||
path = Util::Trim(path, "/");
|
||||
|
||||
struct smb2fh* in = smb2_open(smb2, path.c_str(), flags);
|
||||
return in;
|
||||
struct smb2fh *in = smb2_open(smb2, path.c_str(), flags);
|
||||
return in;
|
||||
}
|
||||
|
||||
void SmbClient::Close(void *fp)
|
||||
{
|
||||
smb2_close(smb2, (struct smb2fh*)fp);
|
||||
smb2_close(smb2, (struct smb2fh *)fp);
|
||||
}
|
||||
|
||||
ClientType SmbClient::clientType()
|
||||
|
||||
@@ -24,6 +24,7 @@ public:
|
||||
int Rmdir(const std::string &path, bool recursive);
|
||||
int Size(const std::string &path, int64_t *size);
|
||||
int Get(const std::string &outputfile, const std::string &path, uint64_t offset=0);
|
||||
int Get(SplitFile *split_file, const std::string &path, uint64_t offset=0);
|
||||
int GetRange(const std::string &path, void *buffer, uint64_t size, uint64_t offset);
|
||||
int GetRange(const std::string &path, DataSink &sink, uint64_t size, uint64_t offset);
|
||||
int GetRange(void *fp, void *buffer, uint64_t size, uint64_t offset);
|
||||
|
||||
+53
-13
@@ -10,10 +10,10 @@
|
||||
#include "windows.h"
|
||||
|
||||
using httplib::Client;
|
||||
using httplib::ContentProvider;
|
||||
using httplib::Headers;
|
||||
using httplib::Progress;
|
||||
using httplib::Result;
|
||||
using httplib::ContentProvider;
|
||||
|
||||
static const char *months[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
|
||||
|
||||
@@ -43,6 +43,50 @@ Result WebDAVClient::PropFind(const std::string &path, int depth)
|
||||
return client->send(req);
|
||||
}
|
||||
|
||||
int WebDAVClient::Size(const std::string &path, int64_t *size)
|
||||
{
|
||||
std::string encoded_path = httplib::detail::encode_url(GetFullPath(path));
|
||||
if (auto res = PropFind(encoded_path, 0))
|
||||
{
|
||||
if (HTTP_SUCCESS(res->status))
|
||||
{
|
||||
pugi::xml_document document;
|
||||
document.load_buffer(res->body.c_str(), res->body.length());
|
||||
auto multistatus = document.select_node("*[local-name()='multistatus']").node();
|
||||
auto responses = multistatus.select_nodes("*[local-name()='response']");
|
||||
for (auto response : responses)
|
||||
{
|
||||
pugi::xml_node href = response.node().select_node("*[local-name()='href']").node();
|
||||
std::string resource_path = httplib::detail::decode_url(href.first_child().value(), true);
|
||||
|
||||
auto target_path_without_sep = GetFullPath(path);
|
||||
if (!target_path_without_sep.empty() && target_path_without_sep.back() == '/')
|
||||
target_path_without_sep.resize(target_path_without_sep.length() - 1);
|
||||
auto resource_path_without_sep = resource_path.erase(resource_path.find_last_not_of('/') + 1);
|
||||
size_t pos = resource_path_without_sep.find(this->host_url);
|
||||
if (pos != std::string::npos)
|
||||
resource_path_without_sep.erase(pos, this->host_url.length());
|
||||
|
||||
if (resource_path_without_sep != target_path_without_sep)
|
||||
continue;
|
||||
|
||||
auto propstat = response.node().select_node("*[local-name()='propstat']").node();
|
||||
auto prop = propstat.select_node("*[local-name()='prop']").node();
|
||||
std::string content_length = prop.select_node("*[local-name()='getcontentlength']").node().first_child().value();
|
||||
|
||||
*size = std::strtoll(content_length.c_str(), nullptr, 10);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(this->response, "%s", httplib::to_string(res.error()).c_str());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::vector<DirEntry> WebDAVClient::ListDir(const std::string &path)
|
||||
{
|
||||
std::vector<DirEntry> out;
|
||||
@@ -152,12 +196,11 @@ int WebDAVClient::Put(const std::string &inputfile, const std::string &path, uin
|
||||
size_t bytes_remaining = FS::GetSize(inputfile);
|
||||
bytes_transfered = 0;
|
||||
sceRtcGetCurrentTick(&prev_tick);
|
||||
|
||||
FILE* in = FS::OpenRead(inputfile);
|
||||
|
||||
if (auto res = client->Put(GetFullPath(path),
|
||||
[&](size_t offset, DataSink &sink)
|
||||
{
|
||||
FILE *in = FS::OpenRead(inputfile);
|
||||
|
||||
if (auto res = client->Put(GetFullPath(path), [&](size_t offset, DataSink &sink)
|
||||
{
|
||||
size_t buf_size = MIN(bytes_remaining, CPPHTTPLIB_RECV_BUFSIZ);
|
||||
char* buf = (char*) malloc(buf_size);
|
||||
FS::Seek(in, offset);
|
||||
@@ -171,9 +214,7 @@ int WebDAVClient::Put(const std::string &inputfile, const std::string &path, uin
|
||||
}
|
||||
sink.done();
|
||||
free(buf);
|
||||
return true;
|
||||
},
|
||||
"application/octet-stream"))
|
||||
return true; }, "application/octet-stream"))
|
||||
{
|
||||
if (HTTP_SUCCESS(res->status))
|
||||
{
|
||||
@@ -230,15 +271,14 @@ int WebDAVClient::Delete(const std::string &path)
|
||||
if (HTTP_SUCCESS(res->status))
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WebDAVClient::Copy(const std::string &from, const std::string &to)
|
||||
{
|
||||
Request req;
|
||||
Headers header = {{"Accept", "*/*"}, {"Destination", httplib::detail::encode_url(GetFullPath(to)) }};
|
||||
Headers header = {{"Accept", "*/*"}, {"Destination", httplib::detail::encode_url(GetFullPath(to))}};
|
||||
|
||||
req.method = "COPY";
|
||||
req.path = httplib::detail::encode_url(GetFullPath(from));
|
||||
@@ -257,7 +297,7 @@ int WebDAVClient::Copy(const std::string &from, const std::string &to)
|
||||
int WebDAVClient::Move(const std::string &from, const std::string &to)
|
||||
{
|
||||
Request req;
|
||||
Headers header = {{"Accept", "*/*"}, {"Destination", httplib::detail::encode_url(GetFullPath(to)) }};
|
||||
Headers header = {{"Accept", "*/*"}, {"Destination", httplib::detail::encode_url(GetFullPath(to))}};
|
||||
|
||||
req.method = "MOVE";
|
||||
req.path = httplib::detail::encode_url(GetFullPath(from));
|
||||
|
||||
@@ -19,6 +19,7 @@ public:
|
||||
int Copy(const std::string &from, const std::string &to);
|
||||
int Move(const std::string &from, const std::string &to);
|
||||
int Put(const std::string &inputfile, const std::string &path, uint64_t offset = 0);
|
||||
int Size(const std::string &path, int64_t *size);
|
||||
std::vector<DirEntry> ListDir(const std::string &path);
|
||||
ClientType clientType();
|
||||
uint32_t SupportedActions();
|
||||
|
||||
+5
-1
@@ -159,7 +159,7 @@ namespace CONFIG
|
||||
"Hungarian", "Indonesian", "Italiano", "Japanese", "Korean", "Polish", "Portuguese_BR", "Russian", "Romanian", "Ryukyuan", "Spanish", "Turkish",
|
||||
"Simplified Chinese", "Traditional Chinese", "Thai", "Ukrainian"};
|
||||
|
||||
http_servers = {HTTP_SERVER_APACHE, HTTP_SERVER_MS_IIS, HTTP_SERVER_NGINX, HTTP_SERVER_NPX_SERVE, HTTP_SERVER_RCLONE};
|
||||
http_servers = {HTTP_SERVER_APACHE, HTTP_SERVER_MS_IIS, HTTP_SERVER_NGINX, HTTP_SERVER_NPX_SERVE, HTTP_SERVER_RCLONE, HTTP_SERVER_ARCHIVEORG};
|
||||
text_file_extensions = { ".txt", ".ini", ".log", ".json", ".xml", ".html", ".xhtml", ".conf", ".config" };
|
||||
image_file_extensions = { ".bmp", ".jpg", ".jpeg", ".png", ".webp" };
|
||||
|
||||
@@ -298,6 +298,9 @@ namespace CONFIG
|
||||
setting.enable_rpi = ReadBool(sites[i].c_str(), CONFIG_ENABLE_RPI, true);
|
||||
WriteBool(sites[i].c_str(), CONFIG_ENABLE_RPI, setting.enable_rpi);
|
||||
|
||||
setting.enable_disk_cache = ReadBool(sites[i].c_str(), CONFIG_REMOTE_ENABLE_DISK_CACHE, false);
|
||||
WriteBool(sites[i].c_str(), CONFIG_REMOTE_ENABLE_DISK_CACHE, setting.enable_disk_cache);
|
||||
|
||||
sprintf(setting.http_server_type, "%s", ReadString(sites[i].c_str(), CONFIG_REMOTE_HTTP_SERVER_TYPE, HTTP_SERVER_APACHE));
|
||||
WriteString(sites[i].c_str(), CONFIG_REMOTE_HTTP_SERVER_TYPE, setting.http_server_type);
|
||||
|
||||
@@ -371,6 +374,7 @@ namespace CONFIG
|
||||
WriteString(last_site, CONFIG_REMOTE_SERVER_USER, remote_settings->username);
|
||||
WriteString(last_site, CONFIG_REMOTE_SERVER_PASSWORD, encrypted_text.c_str());
|
||||
WriteBool(last_site, CONFIG_ENABLE_RPI, remote_settings->enable_rpi);
|
||||
WriteBool(last_site, CONFIG_REMOTE_ENABLE_DISK_CACHE, remote_settings->enable_disk_cache);
|
||||
WriteString(last_site, CONFIG_REMOTE_HTTP_SERVER_TYPE, remote_settings->http_server_type);
|
||||
WriteString(last_site, CONFIG_REMOTE_DEFAULT_DIRECTORY, remote_settings->default_directory);
|
||||
WriteString(CONFIG_GLOBAL, CONFIG_LAST_SITE, last_site);
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
#define CONFIG_ENABLE_RPI "remote_server_enable_rpi"
|
||||
#define CONFIG_REMOTE_HTTP_SERVER_TYPE "remote_server_http_server_type"
|
||||
#define CONFIG_REMOTE_DEFAULT_DIRECTORY "remote_server_default_directory"
|
||||
#define CONFIG_REMOTE_ENABLE_DISK_CACHE "remote_server_enable_disk_cache"
|
||||
|
||||
#define CONFIG_ALLDEBRID_API_KEY "alldebrid_api_key"
|
||||
#define CONFIG_REALDEBRID_API_KEY "realdebrid_api_key"
|
||||
@@ -81,6 +82,7 @@
|
||||
#define HTTP_SERVER_NGINX "Nginx"
|
||||
#define HTTP_SERVER_NPX_SERVE "Serve"
|
||||
#define HTTP_SERVER_RCLONE "RClone"
|
||||
#define HTTP_SERVER_ARCHIVEORG "Archive.org"
|
||||
|
||||
#define MAX_EDIT_FILE_SIZE 32768
|
||||
|
||||
@@ -110,6 +112,7 @@ struct RemoteSettings
|
||||
char http_server_type[24];
|
||||
GoogleAccountInfo gg_account;
|
||||
char default_directory[256];
|
||||
bool enable_disk_cache;
|
||||
};
|
||||
|
||||
struct PackageUrlInfo
|
||||
|
||||
@@ -84,6 +84,8 @@
|
||||
#define BUTTON_RIGHT 0x00000020
|
||||
#define BUTTON_UP 0x00000040
|
||||
#define BUTTON_DOWN 0x00000080
|
||||
#define BUTTON_C 0x00000100
|
||||
#define BUTTON_D 0x00000200
|
||||
|
||||
static uint32_t previous_down = 0;
|
||||
static int repeat_count = 0;
|
||||
@@ -531,8 +533,15 @@ static void ImGui_ImplSDL2_UpdateGamepads()
|
||||
down |= BUTTON_DOWN;
|
||||
else if (SDL_GameControllerGetAxis(game_controller, SDL_CONTROLLER_AXIS_LEFTY) < -ANALOG_THRESHOLD)
|
||||
down |= BUTTON_UP;
|
||||
else if (SDL_GameControllerGetAxis(game_controller, SDL_CONTROLLER_AXIS_TRIGGERLEFT) > ANALOG_THRESHOLD)
|
||||
down |= BUTTON_C;
|
||||
else if (SDL_GameControllerGetAxis(game_controller, SDL_CONTROLLER_AXIS_TRIGGERRIGHT) > ANALOG_THRESHOLD)
|
||||
down |= BUTTON_D;
|
||||
|
||||
uint32_t pressed = down & ~previous_down;
|
||||
io.AddKeyEvent(ImGuiKey_C, (pressed & BUTTON_C) != 0);
|
||||
io.AddKeyEvent(ImGuiKey_D, (pressed & BUTTON_D) != 0);
|
||||
|
||||
if (previous_down == down)
|
||||
{
|
||||
uint64_t delay = 300;
|
||||
|
||||
+250
-44
@@ -26,7 +26,8 @@
|
||||
|
||||
struct BgProgressCheck
|
||||
{
|
||||
ArchivePkgInstallData* pkg_data;
|
||||
ArchivePkgInstallData *archive_pkg_data;
|
||||
SplitPkgInstallData *split_pkg_data;
|
||||
int task_id;
|
||||
std::string hash;
|
||||
};
|
||||
@@ -36,6 +37,7 @@ static OrbisBgftInitParams s_bgft_init_params;
|
||||
static bool s_bgft_initialized = false;
|
||||
|
||||
static std::map<std::string, ArchivePkgInstallData *> archive_pkg_install_data_list;
|
||||
static std::map<std::string, SplitPkgInstallData *> split_pkg_install_data_list;
|
||||
|
||||
namespace INSTALLER
|
||||
{
|
||||
@@ -107,22 +109,22 @@ namespace INSTALLER
|
||||
s_bgft_initialized = false;
|
||||
}
|
||||
|
||||
std::string GetRemotePkgTitle(RemoteClient *client, const std::string &path, pkg_header *header)
|
||||
{
|
||||
std::string GetRemotePkgTitle(RemoteClient *client, const std::string &path, pkg_header *header)
|
||||
{
|
||||
size_t entry_count = BE32(header->pkg_entry_count);
|
||||
uint32_t entry_table_offset = BE32(header->pkg_table_offset);
|
||||
uint64_t entry_table_size = entry_count * sizeof(pkg_table_entry);
|
||||
void *entry_table_data = malloc(entry_table_size);
|
||||
|
||||
int ret = client->GetRange(path, entry_table_data, entry_table_size, entry_table_offset);
|
||||
if (ret == 0)
|
||||
{
|
||||
free(entry_table_data);
|
||||
return "";
|
||||
}
|
||||
int ret = client->GetRange(path, entry_table_data, entry_table_size, entry_table_offset);
|
||||
if (ret == 0)
|
||||
{
|
||||
free(entry_table_data);
|
||||
return "";
|
||||
}
|
||||
|
||||
pkg_table_entry *entries = (pkg_table_entry *)entry_table_data;
|
||||
void* param_sfo_data = nullptr;
|
||||
void *param_sfo_data = nullptr;
|
||||
uint32_t param_sfo_offset = 0;
|
||||
uint32_t param_sfo_size = 0;
|
||||
for (size_t i = 0; i < entry_count; ++i)
|
||||
@@ -132,7 +134,7 @@ namespace INSTALLER
|
||||
param_sfo_offset = BE32(entries[i].offset);
|
||||
param_sfo_size = BE32(entries[i].size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(entry_table_data);
|
||||
|
||||
@@ -140,10 +142,10 @@ namespace INSTALLER
|
||||
if (param_sfo_offset > 0 && param_sfo_size > 0)
|
||||
{
|
||||
param_sfo_data = malloc(param_sfo_size);
|
||||
int ret = client->GetRange(path, param_sfo_data, param_sfo_size, param_sfo_offset);
|
||||
if (ret)
|
||||
int ret = client->GetRange(path, param_sfo_data, param_sfo_size, param_sfo_offset);
|
||||
if (ret)
|
||||
{
|
||||
const char* tmp_title = SFO::GetString((const char*)param_sfo_data, param_sfo_size, "TITLE");
|
||||
const char *tmp_title = SFO::GetString((const char *)param_sfo_data, param_sfo_size, "TITLE");
|
||||
if (tmp_title != nullptr)
|
||||
title = std::string(tmp_title);
|
||||
}
|
||||
@@ -151,7 +153,7 @@ namespace INSTALLER
|
||||
}
|
||||
|
||||
return title;
|
||||
}
|
||||
}
|
||||
|
||||
std::string GetLocalPkgTitle(const std::string &path, pkg_header *header)
|
||||
{
|
||||
@@ -165,7 +167,7 @@ namespace INSTALLER
|
||||
FS::Read(fd, entry_table_data, entry_table_size);
|
||||
|
||||
pkg_table_entry *entries = (pkg_table_entry *)entry_table_data;
|
||||
void* param_sfo_data = NULL;
|
||||
void *param_sfo_data = NULL;
|
||||
uint32_t param_sfo_offset = 0;
|
||||
uint32_t param_sfo_size = 0;
|
||||
void *icon0_png_data = NULL;
|
||||
@@ -188,7 +190,7 @@ namespace INSTALLER
|
||||
param_sfo_data = malloc(param_sfo_size);
|
||||
FS::Seek(fd, param_sfo_offset);
|
||||
FS::Read(fd, param_sfo_data, param_sfo_size);
|
||||
const char* tmp_title = SFO::GetString((const char*)param_sfo_data, param_sfo_size, "TITLE");
|
||||
const char *tmp_title = SFO::GetString((const char *)param_sfo_data, param_sfo_size, "TITLE");
|
||||
if (tmp_title != nullptr)
|
||||
title = std::string(tmp_title);
|
||||
free(param_sfo_data);
|
||||
@@ -219,8 +221,8 @@ namespace INSTALLER
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string encoded_path = httplib::detail::encode_url(path);
|
||||
std::string encoded_site_name = httplib::detail::encode_url(remote_settings->site_name);
|
||||
std::string encoded_path = httplib::detail::encode_url(path);
|
||||
std::string encoded_site_name = httplib::detail::encode_url(remote_settings->site_name);
|
||||
std::string full_url = std::string("http://localhost:") + std::to_string(http_server_port) + "/rmt_inst/" + encoded_site_name + encoded_path;
|
||||
return full_url;
|
||||
}
|
||||
@@ -232,7 +234,7 @@ namespace INSTALLER
|
||||
{
|
||||
bool completed = false;
|
||||
OrbisBgftTaskProgress progress_info;
|
||||
BgProgressCheck *bg_check_data = (BgProgressCheck*) argp;
|
||||
BgProgressCheck *bg_check_data = (BgProgressCheck *)argp;
|
||||
int ret;
|
||||
|
||||
while (!completed)
|
||||
@@ -253,15 +255,27 @@ namespace INSTALLER
|
||||
sceKernelUsleep(500000);
|
||||
}
|
||||
finish:
|
||||
if (bg_check_data->pkg_data != nullptr)
|
||||
if (bg_check_data->archive_pkg_data != nullptr)
|
||||
{
|
||||
bg_check_data->pkg_data->stop_write_thread = true;
|
||||
pthread_join(bg_check_data->pkg_data->thread, NULL);
|
||||
delete(bg_check_data->pkg_data->split_file);
|
||||
free(bg_check_data->pkg_data);
|
||||
bg_check_data->archive_pkg_data->stop_write_thread = true;
|
||||
pthread_join(bg_check_data->archive_pkg_data->thread, NULL);
|
||||
delete (bg_check_data->archive_pkg_data->split_file);
|
||||
free(bg_check_data->archive_pkg_data);
|
||||
RemoveArchivePkgInstallData(bg_check_data->hash);
|
||||
free(bg_check_data);
|
||||
}
|
||||
else if (bg_check_data->split_pkg_data != nullptr)
|
||||
{
|
||||
bg_check_data->split_pkg_data->stop_write_thread = true;
|
||||
bg_check_data->split_pkg_data->split_file->Close();
|
||||
pthread_join(bg_check_data->split_pkg_data->thread, NULL);
|
||||
delete (bg_check_data->split_pkg_data->split_file);
|
||||
if (bg_check_data->split_pkg_data->delete_client)
|
||||
delete (bg_check_data->split_pkg_data->remote_client);
|
||||
free(bg_check_data->split_pkg_data);
|
||||
RemoveSplitPkgInstallData(bg_check_data->hash);
|
||||
free(bg_check_data);
|
||||
}
|
||||
activity_inprogess = false;
|
||||
file_transfering = false;
|
||||
Windows::SetModalMode(false);
|
||||
@@ -388,7 +402,7 @@ namespace INSTALLER
|
||||
if (prompt)
|
||||
{
|
||||
file_transfering = true;
|
||||
bytes_to_download = 100;
|
||||
bytes_to_download = header->pkg_content_size;
|
||||
bytes_transfered = 0;
|
||||
sceRtcGetCurrentTick(&prev_tick);
|
||||
|
||||
@@ -398,7 +412,7 @@ namespace INSTALLER
|
||||
ret = sceBgftServiceDownloadGetProgress(task_id, &progress_info);
|
||||
if (ret || (progress_info.transferred > 0 && progress_info.errorResult != 0))
|
||||
return 0;
|
||||
|
||||
|
||||
if (progress_info.length > 0)
|
||||
{
|
||||
completed = progress_info.transferred == progress_info.length;
|
||||
@@ -410,9 +424,10 @@ namespace INSTALLER
|
||||
}
|
||||
else
|
||||
{
|
||||
BgProgressCheck *bg_check_data = (BgProgressCheck*) malloc(sizeof(BgProgressCheck));
|
||||
BgProgressCheck *bg_check_data = (BgProgressCheck *)malloc(sizeof(BgProgressCheck));
|
||||
memset(bg_check_data, 0, sizeof(BgProgressCheck));
|
||||
bg_check_data->pkg_data = nullptr;
|
||||
bg_check_data->archive_pkg_data = nullptr;
|
||||
bg_check_data->split_pkg_data = nullptr;
|
||||
bg_check_data->task_id = task_id;
|
||||
bg_check_data->hash = "";
|
||||
ret = pthread_create(&bk_install_thid, NULL, CheckBgInstallTaskThread, bg_check_data);
|
||||
@@ -489,7 +504,7 @@ namespace INSTALLER
|
||||
Util::Notify("%s queued", display_title.c_str());
|
||||
|
||||
file_transfering = true;
|
||||
bytes_to_download = 100;
|
||||
bytes_to_download = header.pkg_content_size;
|
||||
bytes_transfered = 0;
|
||||
sceRtcGetCurrentTick(&prev_tick);
|
||||
|
||||
@@ -518,13 +533,13 @@ namespace INSTALLER
|
||||
{
|
||||
int ret;
|
||||
bool completed = false;
|
||||
|
||||
|
||||
if (strncmp(path.c_str(), "/data/", 6) != 0 &&
|
||||
strncmp(path.c_str(), "/user/data/", 11) != 0 &&
|
||||
strncmp(path.c_str(), "/mnt/usb", 8) != 0)
|
||||
return -1;
|
||||
|
||||
std::string filename = path.substr(path.find_last_of("/")+1);
|
||||
std::string filename = path.substr(path.find_last_of("/") + 1);
|
||||
char filepath[1024];
|
||||
snprintf(filepath, 1023, "%s", path.c_str());
|
||||
if (strncmp(path.c_str(), "/data/", 6) == 0)
|
||||
@@ -602,7 +617,7 @@ namespace INSTALLER
|
||||
}
|
||||
|
||||
sprintf(activity_message, "%s", lang_strings[STR_WAIT_FOR_INSTALL_MSG]);
|
||||
bytes_to_download = 1;
|
||||
bytes_to_download = header->pkg_content_size;
|
||||
bytes_transfered = 0;
|
||||
sceRtcGetCurrentTick(&prev_tick);
|
||||
|
||||
@@ -644,7 +659,7 @@ namespace INSTALLER
|
||||
FS::Read(fd, entry_table_data, entry_table_size);
|
||||
|
||||
pkg_table_entry *entries = (pkg_table_entry *)entry_table_data;
|
||||
void* param_sfo_data = NULL;
|
||||
void *param_sfo_data = NULL;
|
||||
uint32_t param_sfo_offset = 0;
|
||||
uint32_t param_sfo_size = 0;
|
||||
void *icon0_png_data = NULL;
|
||||
@@ -715,7 +730,7 @@ namespace INSTALLER
|
||||
return false;
|
||||
|
||||
pkg_table_entry *entries = (pkg_table_entry *)entry_table_data;
|
||||
void* param_sfo_data = NULL;
|
||||
void *param_sfo_data = NULL;
|
||||
uint32_t param_sfo_offset = 0;
|
||||
uint32_t param_sfo_size = 0;
|
||||
void *icon0_png_data = NULL;
|
||||
@@ -783,7 +798,7 @@ namespace INSTALLER
|
||||
|
||||
void AddArchivePkgInstallData(const std::string &hash, ArchivePkgInstallData *pkg_data)
|
||||
{
|
||||
std::pair<std::string, ArchivePkgInstallData*> pair = std::make_pair(hash, pkg_data);
|
||||
std::pair<std::string, ArchivePkgInstallData *> pair = std::make_pair(hash, pkg_data);
|
||||
archive_pkg_install_data_list.erase(hash);
|
||||
archive_pkg_install_data_list.insert(pair);
|
||||
}
|
||||
@@ -793,10 +808,10 @@ namespace INSTALLER
|
||||
archive_pkg_install_data_list.erase(hash);
|
||||
}
|
||||
|
||||
bool InstallArchivePkg(const std::string &path, ArchivePkgInstallData* pkg_data, bool bg)
|
||||
bool InstallArchivePkg(const std::string &path, ArchivePkgInstallData *pkg_data, bool bg)
|
||||
{
|
||||
pkg_header header;
|
||||
pkg_data->split_file->Read((char*)&header, sizeof(pkg_header), 0);
|
||||
pkg_data->split_file->Read((char *)&header, sizeof(pkg_header), 0);
|
||||
|
||||
int ret;
|
||||
std::string cid = std::string((char *)header.pkg_content_id);
|
||||
@@ -920,7 +935,7 @@ namespace INSTALLER
|
||||
if (!bg)
|
||||
{
|
||||
file_transfering = true;
|
||||
bytes_to_download = 100;
|
||||
bytes_to_download = header.pkg_content_size;
|
||||
bytes_transfered = 0;
|
||||
sceRtcGetCurrentTick(&prev_tick);
|
||||
|
||||
@@ -933,7 +948,6 @@ namespace INSTALLER
|
||||
ret = 0;
|
||||
goto finish;
|
||||
}
|
||||
bytes_transfered = (uint32_t)(((float)progress_info.transferred / progress_info.length) * 100.f);
|
||||
if (progress_info.length > 0)
|
||||
{
|
||||
completed = progress_info.transferred == progress_info.length;
|
||||
@@ -945,9 +959,10 @@ namespace INSTALLER
|
||||
}
|
||||
else
|
||||
{
|
||||
BgProgressCheck *bg_check_data = (BgProgressCheck*) malloc(sizeof(BgProgressCheck));
|
||||
BgProgressCheck *bg_check_data = (BgProgressCheck *)malloc(sizeof(BgProgressCheck));
|
||||
memset(bg_check_data, 0, sizeof(BgProgressCheck));
|
||||
bg_check_data->pkg_data = pkg_data;
|
||||
bg_check_data->archive_pkg_data = pkg_data;
|
||||
bg_check_data->split_pkg_data = nullptr;
|
||||
bg_check_data->task_id = task_id;
|
||||
bg_check_data->hash = hash;
|
||||
ret = pthread_create(&bk_install_thid, NULL, CheckBgInstallTaskThread, bg_check_data);
|
||||
@@ -957,11 +972,202 @@ namespace INSTALLER
|
||||
finish:
|
||||
pkg_data->stop_write_thread = true;
|
||||
pthread_join(pkg_data->thread, NULL);
|
||||
delete(pkg_data->split_file);
|
||||
delete (pkg_data->split_file);
|
||||
free(pkg_data);
|
||||
RemoveArchivePkgInstallData(hash);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
SplitPkgInstallData *GetSplitPkgInstallData(const std::string &hash)
|
||||
{
|
||||
return split_pkg_install_data_list[hash];
|
||||
}
|
||||
|
||||
void AddSplitPkgInstallData(const std::string &hash, SplitPkgInstallData *pkg_data)
|
||||
{
|
||||
std::pair<std::string, SplitPkgInstallData *> pair = std::make_pair(hash, pkg_data);
|
||||
split_pkg_install_data_list.erase(hash);
|
||||
split_pkg_install_data_list.insert(pair);
|
||||
}
|
||||
|
||||
void RemoveSplitPkgInstallData(const std::string &hash)
|
||||
{
|
||||
split_pkg_install_data_list.erase(hash);
|
||||
}
|
||||
|
||||
bool InstallSplitPkg(const std::string &path, SplitPkgInstallData *pkg_data, bool bg)
|
||||
{
|
||||
pkg_header header;
|
||||
pkg_data->split_file->Read((char *)&header, sizeof(pkg_header), 0);
|
||||
|
||||
int ret;
|
||||
std::string cid = std::string((char *)header.pkg_content_id);
|
||||
cid = cid.substr(cid.find_first_of("-") + 1, 9);
|
||||
std::string display_title = cid;
|
||||
int user_id;
|
||||
ret = sceUserServiceGetForegroundUser(&user_id);
|
||||
const char *package_type;
|
||||
uint32_t content_type = BE32(header.pkg_content_type);
|
||||
uint32_t flags = BE32(header.pkg_content_flags);
|
||||
bool is_patch = false;
|
||||
bool completed = false;
|
||||
|
||||
switch (content_type)
|
||||
{
|
||||
case PKG_CONTENT_TYPE_GD:
|
||||
package_type = "PS4GD";
|
||||
break;
|
||||
case PKG_CONTENT_TYPE_AC:
|
||||
package_type = "PS4AC";
|
||||
break;
|
||||
case PKG_CONTENT_TYPE_AL:
|
||||
package_type = "PS4AL";
|
||||
break;
|
||||
case PKG_CONTENT_TYPE_DP:
|
||||
package_type = "PS4DP";
|
||||
break;
|
||||
default:
|
||||
package_type = NULL;
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (flags & PKG_CONTENT_FLAGS_FIRST_PATCH ||
|
||||
flags & PKG_CONTENT_FLAGS_SUBSEQUENT_PATCH ||
|
||||
flags & PKG_CONTENT_FLAGS_DELTA_PATCH ||
|
||||
flags & PKG_CONTENT_FLAGS_CUMULATIVE_PATCH)
|
||||
{
|
||||
is_patch = true;
|
||||
}
|
||||
|
||||
std::string hash = Util::UrlHash(path);
|
||||
std::string full_url = std::string("http://localhost:") + std::to_string(http_server_port) + "/split_inst/" + hash;
|
||||
AddSplitPkgInstallData(hash, pkg_data);
|
||||
|
||||
OrbisBgftTaskProgress progress_info;
|
||||
OrbisBgftDownloadParam params;
|
||||
memset(¶ms, 0, sizeof(params));
|
||||
{
|
||||
params.userId = user_id;
|
||||
params.entitlementType = 5;
|
||||
params.id = (char *)header.pkg_content_id;
|
||||
params.contentUrl = full_url.c_str();
|
||||
params.contentName = display_title.c_str();
|
||||
params.iconPath = "";
|
||||
params.playgoScenarioId = "0";
|
||||
params.option = ORBIS_BGFT_TASK_OPT_DISABLE_CDN_QUERY_PARAM;
|
||||
params.packageType = package_type;
|
||||
params.packageSubType = "";
|
||||
params.packageSize = BE64(header.pkg_size);
|
||||
}
|
||||
|
||||
retry:
|
||||
int task_id = -1;
|
||||
if (!is_patch)
|
||||
ret = sceBgftServiceIntDownloadRegisterTask(¶ms, &task_id);
|
||||
else
|
||||
ret = sceBgftServiceIntDebugDownloadRegisterPkg(¶ms, &task_id);
|
||||
if (ret == 0x80990088 || ret == 0x80990015)
|
||||
{
|
||||
if (!bg)
|
||||
{
|
||||
sprintf(confirm_message, "%s - %s?", display_title.c_str(), lang_strings[STR_REINSTALL_CONFIRM_MSG]);
|
||||
confirm_state = CONFIRM_WAIT;
|
||||
action_to_take = selected_action;
|
||||
activity_inprogess = false;
|
||||
while (confirm_state == CONFIRM_WAIT)
|
||||
{
|
||||
sceKernelUsleep(100000);
|
||||
}
|
||||
activity_inprogess = true;
|
||||
selected_action = action_to_take;
|
||||
|
||||
if (confirm_state == CONFIRM_YES)
|
||||
{
|
||||
ret = sceAppInstUtilAppUnInstall(cid.c_str());
|
||||
if (ret != 0)
|
||||
{
|
||||
ret = 0;
|
||||
goto finish;
|
||||
}
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = sceAppInstUtilAppUnInstall(cid.c_str());
|
||||
if (ret != 0)
|
||||
{
|
||||
ret = 0;
|
||||
goto finish;
|
||||
}
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
else if (ret > 0)
|
||||
{
|
||||
ret = 0;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
ret = sceBgftServiceDownloadStartTask(task_id);
|
||||
if (ret)
|
||||
{
|
||||
ret = 0;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
Util::Notify("%s queued", display_title.c_str());
|
||||
|
||||
if (!bg)
|
||||
{
|
||||
file_transfering = true;
|
||||
bytes_to_download = pkg_data->size;
|
||||
bytes_transfered = 0;
|
||||
sceRtcGetCurrentTick(&prev_tick);
|
||||
|
||||
while (!completed)
|
||||
{
|
||||
memset(&progress_info, 0, sizeof(progress_info));
|
||||
ret = sceBgftServiceDownloadGetProgress(task_id, &progress_info);
|
||||
if (ret || (progress_info.transferred > 0 && progress_info.errorResult != 0))
|
||||
{
|
||||
ret = 0;
|
||||
goto finish;
|
||||
}
|
||||
if (progress_info.length > 0)
|
||||
{
|
||||
completed = progress_info.transferred == progress_info.length;
|
||||
bytes_to_download = progress_info.length;
|
||||
bytes_transfered = progress_info.transferred;
|
||||
}
|
||||
sceSystemServicePowerTick();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BgProgressCheck *bg_check_data = (BgProgressCheck *)malloc(sizeof(BgProgressCheck));
|
||||
memset(bg_check_data, 0, sizeof(BgProgressCheck));
|
||||
bg_check_data->split_pkg_data = pkg_data;
|
||||
bg_check_data->archive_pkg_data = nullptr;
|
||||
bg_check_data->task_id = task_id;
|
||||
bg_check_data->hash = hash;
|
||||
ret = pthread_create(&bk_install_thid, NULL, CheckBgInstallTaskThread, bg_check_data);
|
||||
return 1;
|
||||
}
|
||||
ret = 1;
|
||||
finish:
|
||||
pkg_data->stop_write_thread = true;
|
||||
pkg_data->split_file->Close();
|
||||
pthread_join(pkg_data->thread, NULL);
|
||||
delete (pkg_data->split_file);
|
||||
if (pkg_data->delete_client)
|
||||
delete (pkg_data->remote_client);
|
||||
free(pkg_data);
|
||||
RemoveSplitPkgInstallData(hash);
|
||||
activity_inprogess = false;
|
||||
file_transfering = false;
|
||||
Windows::SetModalMode(false);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,6 +129,17 @@ struct ArchivePkgInstallData
|
||||
bool stop_write_thread;
|
||||
};
|
||||
|
||||
struct SplitPkgInstallData
|
||||
{
|
||||
SplitFile *split_file;
|
||||
RemoteClient *remote_client;
|
||||
std::string path;
|
||||
int64_t size;
|
||||
pthread_t thread;
|
||||
bool stop_write_thread;
|
||||
bool delete_client;
|
||||
};
|
||||
|
||||
static pthread_t bk_install_thid;
|
||||
|
||||
namespace INSTALLER
|
||||
@@ -149,4 +160,8 @@ namespace INSTALLER
|
||||
void AddArchivePkgInstallData(const std::string &hash, ArchivePkgInstallData *pkg_data);
|
||||
void RemoveArchivePkgInstallData(const std::string &hash);
|
||||
bool InstallArchivePkg(const std::string &path, ArchivePkgInstallData* pkg_data, bool bg = false);
|
||||
SplitPkgInstallData *GetSplitPkgInstallData(const std::string &hash);
|
||||
void AddSplitPkgInstallData(const std::string &hash, SplitPkgInstallData *pkg_data);
|
||||
void RemoveSplitPkgInstallData(const std::string &hash);
|
||||
bool InstallSplitPkg(const std::string &path, SplitPkgInstallData* pkg_data, bool bg = false);
|
||||
}
|
||||
@@ -172,6 +172,8 @@ char lang_strings[LANG_STRINGS_NUM][LANG_STR_SIZE] = {
|
||||
"Temp Directory", // STR_TEMP_DIRECTORY
|
||||
"Real-Debrid", // STR_REALDEBRID
|
||||
"Package install is running in the background. Don't close the app while install is in progress", // STR_BACKGROUND_INSTALL_INPROGRESS
|
||||
"Enable disk caching. Can improve package install speed in cases where connection to remote is slow", // STR_ENABLE_DISC_CACHE_MSG
|
||||
"DC", // STR_ENABLE_DISK_CACHE
|
||||
};
|
||||
|
||||
bool needs_extended_font = false;
|
||||
|
||||
+4
-2
@@ -165,7 +165,9 @@
|
||||
FUNC(STR_LANGUAGE) \
|
||||
FUNC(STR_TEMP_DIRECTORY) \
|
||||
FUNC(STR_REALDEBRID) \
|
||||
FUNC(STR_BACKGROUND_INSTALL_INPROGRESS)
|
||||
FUNC(STR_BACKGROUND_INSTALL_INPROGRESS) \
|
||||
FUNC(STR_ENABLE_DISC_CACHE_MSG) \
|
||||
FUNC(STR_ENABLE_DISK_CACHE)
|
||||
|
||||
#define GET_VALUE(x) x,
|
||||
#define GET_STRING(x) #x,
|
||||
@@ -175,7 +177,7 @@ enum
|
||||
FOREACH_STR(GET_VALUE)
|
||||
};
|
||||
|
||||
#define LANG_STRINGS_NUM 162
|
||||
#define LANG_STRINGS_NUM 164
|
||||
#define LANG_ID_SIZE 64
|
||||
#define LANG_STR_SIZE 384
|
||||
extern char lang_identifiers[LANG_STRINGS_NUM][LANG_ID_SIZE];
|
||||
|
||||
+106
-12
@@ -10,6 +10,7 @@
|
||||
#include "clients/nfsclient.h"
|
||||
#include "clients/webdav.h"
|
||||
#include "clients/apache.h"
|
||||
#include "clients/archiveorg.h"
|
||||
#include "clients/iis.h"
|
||||
#include "clients/nginx.h"
|
||||
#include "clients/npxserve.h"
|
||||
@@ -23,7 +24,6 @@
|
||||
#include "zip_util.h"
|
||||
#include "util.h"
|
||||
#include "installer.h"
|
||||
// #include "dbglogger.h"
|
||||
|
||||
#define SERVER_CERT_FILE "/app0/assets/certs/domain.crt"
|
||||
#define SERVER_PRIVATE_KEY_FILE "/app0/assets/certs/domain.key"
|
||||
@@ -250,6 +250,8 @@ namespace HttpServer
|
||||
tmp_client = new NpxServeClient();
|
||||
else if (strcmp(remote_settings->http_server_type, HTTP_SERVER_RCLONE) == 0)
|
||||
tmp_client = new RCloneClient();
|
||||
else if (strcmp(remote_settings->http_server_type, HTTP_SERVER_ARCHIVEORG) == 0)
|
||||
tmp_client = new ArchiveOrgClient();
|
||||
}
|
||||
|
||||
if (tmp_client->clientType() != CLIENT_TYPE_GOOGLE)
|
||||
@@ -1169,12 +1171,69 @@ namespace HttpServer
|
||||
});
|
||||
} });
|
||||
|
||||
svr->Get("/split_inst/(.*)", [&](const Request &req, Response &res)
|
||||
{
|
||||
std::string hash = req.matches[1];
|
||||
|
||||
SplitPkgInstallData *pkg_data = INSTALLER::GetSplitPkgInstallData(hash);
|
||||
|
||||
if (req.method == "HEAD")
|
||||
{
|
||||
res.status = 204;
|
||||
res.set_header("Content-Length", std::to_string(pkg_data->size));
|
||||
res.set_header("Accept-Ranges", "bytes");
|
||||
return;
|
||||
}
|
||||
|
||||
if (req.ranges.empty())
|
||||
{
|
||||
res.status = 200;
|
||||
res.set_content_provider(
|
||||
131072, "application/octet-stream",
|
||||
[pkg_data](size_t offset, size_t length, DataSink &sink) {
|
||||
char *buf = (char*) malloc(131072);
|
||||
size_t bytes_read = pkg_data->split_file->Read(buf, 131072, offset);
|
||||
sink.write(buf, bytes_read);
|
||||
free(buf);
|
||||
return true;
|
||||
},
|
||||
[](bool success) {
|
||||
return true;
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
res.status = 206;
|
||||
size_t range_len = (req.ranges[0].second - req.ranges[0].first) + 1;
|
||||
if (req.ranges[0].second >= 18000000000000000000ul)
|
||||
{
|
||||
range_len = PKG_INITIAL_REQUEST_SIZE;
|
||||
res.set_header("Content-Length", std::to_string(range_len));
|
||||
res.set_header("Content-Range", std::string("bytes ") + std::to_string(req.ranges[0].first)+"-" + std::to_string(req.ranges[0].first+PKG_INITIAL_REQUEST_SIZE-1) + "/"+std::to_string(range_len));
|
||||
sceRtcGetCurrentTick(&prev_tick);
|
||||
}
|
||||
std::pair<ssize_t, ssize_t> range = req.ranges[0];
|
||||
res.set_content_provider(
|
||||
range_len, "application/octet-stream",
|
||||
[pkg_data, range, range_len](size_t offset, size_t length, DataSink &sink) {
|
||||
char *buf = (char*) malloc(range_len);
|
||||
size_t bytes_read = pkg_data->split_file->Read(buf, range_len, range.first);
|
||||
sink.write(buf, bytes_read);
|
||||
free(buf);
|
||||
return true;
|
||||
},
|
||||
[](bool success) {
|
||||
return true;
|
||||
});
|
||||
} });
|
||||
|
||||
svr->Post("/__local__/install_url", [&](const Request &req, Response &res)
|
||||
{
|
||||
std::string url;
|
||||
const char *url_param;
|
||||
bool use_alldebrid = false;
|
||||
bool use_realdebrid = false;
|
||||
bool use_disk_cache = false;
|
||||
|
||||
json_object *jobj = json_tokener_parse(req.body.c_str());
|
||||
if (jobj != nullptr)
|
||||
@@ -1182,6 +1241,8 @@ namespace HttpServer
|
||||
url_param = json_object_get_string(json_object_object_get(jobj, "url"));
|
||||
use_alldebrid = json_object_get_boolean(json_object_object_get(jobj, "use_alldebrid"));
|
||||
use_realdebrid = json_object_get_boolean(json_object_object_get(jobj, "use_realdebrid"));
|
||||
use_disk_cache = json_object_get_boolean(json_object_object_get(jobj, "use_disk_cache"));
|
||||
|
||||
if (url_param == nullptr)
|
||||
{
|
||||
bad_request(res, "Required url_param parameter missing");
|
||||
@@ -1228,7 +1289,6 @@ namespace HttpServer
|
||||
Windows::SetModalMode(true);
|
||||
return;
|
||||
}
|
||||
|
||||
delete(filehost);
|
||||
|
||||
size_t scheme_pos = download_url.find("://");
|
||||
@@ -1242,20 +1302,53 @@ namespace HttpServer
|
||||
baseclient->Head(path, &header, sizeof(pkg_header));
|
||||
|
||||
if (BE32(header.pkg_magic) == 0x7F434E54)
|
||||
{
|
||||
{
|
||||
bytes_to_download = header.pkg_content_size;
|
||||
FileHost::AddCacheDownloadUrl(hash, download_url);
|
||||
std::string title = INSTALLER::GetRemotePkgTitle(baseclient, path, &header);
|
||||
delete(baseclient);
|
||||
|
||||
std::string remote_install_url = std::string("http://localhost:") + std::to_string(http_server_port) + "/rmt_inst/Site%2099/" + hash;
|
||||
int rc = INSTALLER::InstallRemotePkg(remote_install_url, &header, title, false);
|
||||
if (rc == 0)
|
||||
if (!use_disk_cache)
|
||||
{
|
||||
failed(res, 200, lang_strings[STR_FAIL_INSTALL_FROM_URL_MSG]);
|
||||
activity_inprogess = false;
|
||||
file_transfering = false;
|
||||
Windows::SetModalMode(true);
|
||||
return;
|
||||
std::string remote_install_url = std::string("http://localhost:") + std::to_string(http_server_port) + "/rmt_inst/Site%2099/" + hash;
|
||||
int rc = INSTALLER::InstallRemotePkg(remote_install_url, &header, title, false);
|
||||
if (rc == 0)
|
||||
{
|
||||
failed(res, 200, lang_strings[STR_FAIL_INSTALL_FROM_URL_MSG]);
|
||||
activity_inprogess = false;
|
||||
file_transfering = false;
|
||||
Windows::SetModalMode(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SplitPkgInstallData *install_data = (SplitPkgInstallData*) malloc(sizeof(SplitPkgInstallData));
|
||||
memset(install_data, 0, sizeof(SplitPkgInstallData));
|
||||
|
||||
OrbisTick tick;
|
||||
sceRtcGetCurrentTick(&tick);
|
||||
std::string install_pkg_path = std::string(temp_folder) + "/" + std::to_string(tick.mytick) + ".pkg";
|
||||
SplitFile *sp = new SplitFile(install_pkg_path, INSTALL_ARCHIVE_PKG_SPLIT_SIZE/2);
|
||||
|
||||
install_data->split_file = sp;
|
||||
install_data->remote_client = baseclient;
|
||||
install_data->path = path;
|
||||
baseclient->Size(path, &install_data->size);
|
||||
install_data->stop_write_thread = false;
|
||||
install_data->delete_client = true;
|
||||
|
||||
int ret = pthread_create(&install_data->thread, NULL, Actions::DownloadSplitPkg, install_data);
|
||||
|
||||
ret = INSTALLER::InstallSplitPkg(download_url, install_data, true);
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
failed(res, 200, lang_strings[STR_FAIL_INSTALL_FROM_URL_MSG]);
|
||||
activity_inprogess = false;
|
||||
file_transfering = false;
|
||||
Windows::SetModalMode(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1282,6 +1375,7 @@ namespace HttpServer
|
||||
failed(res, 200, lang_strings[STR_FAIL_INSTALL_FROM_URL_MSG]);
|
||||
activity_inprogess = false;
|
||||
file_transfering = false;
|
||||
free(install_data);
|
||||
Windows::SetModalMode(false);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ size_t SplitFile::Write(char *buf, size_t buf_size)
|
||||
size_t total_bytes_written = 0;
|
||||
size_t remaining_to_write = buf_size;
|
||||
|
||||
while (remaining_to_write > 0)
|
||||
while (remaining_to_write > 0 && !this->complete)
|
||||
{
|
||||
block_space_remaining = this->block_size - block_in_progress->size;
|
||||
bytes_to_write = MIN(remaining_to_write, block_space_remaining);
|
||||
@@ -192,6 +192,9 @@ size_t SplitFile::Write(char *buf, size_t buf_size)
|
||||
|
||||
int SplitFile::Close()
|
||||
{
|
||||
if (this->complete)
|
||||
return 0;
|
||||
|
||||
if (block_in_progress->fd != nullptr)
|
||||
{
|
||||
fflush(block_in_progress->fd);
|
||||
@@ -207,6 +210,11 @@ int SplitFile::Close()
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool SplitFile::IsClosed()
|
||||
{
|
||||
return this->complete;
|
||||
}
|
||||
|
||||
FileBlock *SplitFile::NewBlock()
|
||||
{
|
||||
FileBlock *block = (FileBlock *)malloc(sizeof(FileBlock));
|
||||
|
||||
@@ -31,6 +31,7 @@ public:
|
||||
size_t Write(char* buf, size_t buf_size);
|
||||
int Open();
|
||||
int Close();
|
||||
bool IsClosed();
|
||||
|
||||
private:
|
||||
std::vector<FileBlock*> file_blocks;
|
||||
|
||||
@@ -455,6 +455,26 @@ namespace Windows
|
||||
ImGui::PopTextWrapPos();
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 5);
|
||||
ImGui::TextColored(colors[ImGuiCol_ButtonHovered], "%s:", lang_strings[STR_ENABLE_DISK_CACHE]);
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Checkbox("###enable_disk_cache", &remote_settings->enable_disk_cache))
|
||||
{
|
||||
CONFIG::SaveConfig();
|
||||
}
|
||||
if (ImGui::IsItemHovered())
|
||||
{
|
||||
ImGui::SetNextWindowSize(ImVec2(550, 85));
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + 540);
|
||||
ImGui::Text("%s", lang_strings[STR_ENABLE_DISC_CACHE_MSG]);
|
||||
ImGui::PopTextWrapPos();
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
|
||||
ImGui::PopStyleVar();
|
||||
|
||||
ImGui::SameLine();
|
||||
@@ -856,6 +876,23 @@ namespace Windows
|
||||
ImGui::Columns(1);
|
||||
ImGui::EndChild();
|
||||
EndGroupPanel();
|
||||
|
||||
if (ImGui::IsKeyPressed(ImGuiKey_C) && !paused)
|
||||
{
|
||||
if (selected_browser & LOCAL_BROWSER)
|
||||
{
|
||||
selected_local_file = local_files[0];
|
||||
selected_action = ACTION_CHANGE_LOCAL_DIRECTORY;
|
||||
}
|
||||
else if (selected_browser & REMOTE_BROWSER)
|
||||
{
|
||||
if (remoteclient != nullptr && remote_files.size() > 0)
|
||||
{
|
||||
selected_remote_file = remote_files[0];
|
||||
selected_action = ACTION_CHANGE_REMOTE_DIRECTORY;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StatusPanel()
|
||||
@@ -2556,6 +2593,10 @@ namespace Windows
|
||||
if (ime_result == IME_DIALOG_RESULT_FINISHED)
|
||||
{
|
||||
CONFIG::SetClientType(remote_settings);
|
||||
if (strncasecmp(remote_settings->server, "https://archive.org/", 20) == 0)
|
||||
{
|
||||
sprintf(remote_settings->http_server_type, "%s", HTTP_SERVER_ARCHIVEORG);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+10
-21
@@ -290,7 +290,7 @@ namespace ZipUtil
|
||||
static int extract2fd(struct archive *a, const std::string &pathname, int fd)
|
||||
{
|
||||
ssize_t len;
|
||||
unsigned char *buffer = (unsigned char *) malloc(ARCHIVE_TRANSFER_SIZE);
|
||||
unsigned char *buffer = (unsigned char *)malloc(ARCHIVE_TRANSFER_SIZE);
|
||||
bytes_transfered = 0;
|
||||
sceRtcGetCurrentTick(&prev_tick);
|
||||
|
||||
@@ -312,7 +312,7 @@ namespace ZipUtil
|
||||
return 0;
|
||||
}
|
||||
bytes_transfered += len;
|
||||
|
||||
|
||||
if (write(fd, buffer, len) != len)
|
||||
{
|
||||
sprintf(status_message, "error write('%s')", pathname.c_str());
|
||||
@@ -479,7 +479,7 @@ namespace ZipUtil
|
||||
ret = data->client->GetRange((data->fp), data->buf, to_read, data->offset);
|
||||
else
|
||||
ret = data->client->GetRange(data->path, data->buf, to_read, data->offset);
|
||||
|
||||
|
||||
if (ret == 0)
|
||||
return -1;
|
||||
data->offset = data->offset + to_read;
|
||||
@@ -521,7 +521,7 @@ namespace ZipUtil
|
||||
return data->offset;
|
||||
}
|
||||
|
||||
int64_t SkipRemoteArchive(struct archive *, void *client_data, int64_t request)
|
||||
int64_t SkipRemoteArchive(struct archive *, void *client_data, int64_t request)
|
||||
{
|
||||
RemoteArchiveData *data = (RemoteArchiveData *)client_data;
|
||||
|
||||
@@ -529,7 +529,7 @@ namespace ZipUtil
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Main loop: open the zipfile, iterate over its contents and decide what
|
||||
* to do with each entry.
|
||||
@@ -577,10 +577,6 @@ namespace ZipUtil
|
||||
ret = archive_read_open2(a, client_data, NULL, ReadRemoteArchive, SkipRemoteArchive, CloseRemoteArchive);
|
||||
if (ret < ARCHIVE_OK)
|
||||
{
|
||||
if (client_data != nullptr)
|
||||
{
|
||||
free(client_data);
|
||||
}
|
||||
sprintf(status_message, "%s", "archive_read_open failed");
|
||||
return 0;
|
||||
}
|
||||
@@ -622,7 +618,10 @@ namespace ZipUtil
|
||||
int ret;
|
||||
|
||||
if ((a = archive_read_new()) == NULL)
|
||||
{
|
||||
sprintf(status_message, "%s", "archive_read_new failed");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
archive_read_support_format_all(a);
|
||||
archive_read_support_filter_all(a);
|
||||
@@ -656,10 +655,6 @@ namespace ZipUtil
|
||||
ret = archive_read_open2(a, client_data, NULL, ReadRemoteArchive, SkipRemoteArchive, CloseRemoteArchive);
|
||||
if (ret < ARCHIVE_OK)
|
||||
{
|
||||
if (client_data != nullptr)
|
||||
{
|
||||
free(client_data);
|
||||
}
|
||||
sprintf(status_message, "%s", "archive_read_open_filename failed");
|
||||
return nullptr;
|
||||
}
|
||||
@@ -672,16 +667,14 @@ namespace ZipUtil
|
||||
if (ret < ARCHIVE_OK)
|
||||
{
|
||||
sprintf(status_message, "%s", "archive_read_next_header failed");
|
||||
if (client_data != nullptr)
|
||||
{
|
||||
free(client_data);
|
||||
}
|
||||
archive_read_free(a);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (ret == ARCHIVE_EOF)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if ((pathname = pathdup(archive_entry_pathname(e))) == NULL)
|
||||
{
|
||||
@@ -750,10 +743,6 @@ namespace ZipUtil
|
||||
if (ret < ARCHIVE_OK)
|
||||
{
|
||||
sprintf(status_message, "%s", "archive_read_next_header failed");
|
||||
if (client_data != nullptr)
|
||||
{
|
||||
free(client_data);
|
||||
}
|
||||
archive_read_free(a);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@
|
||||
#include "common.h"
|
||||
#include "fs.h"
|
||||
|
||||
#define ARCHIVE_TRANSFER_SIZE 5242880
|
||||
#define ARCHIVE_TRANSFER_SIZE 20971520
|
||||
|
||||
static uint8_t MAGIC_ZIP_1[4] = {0x50, 0x4B, 0x03, 0x04};
|
||||
static uint8_t MAGIC_ZIP_2[4] = {0x50, 0x4B, 0x05, 0x06};
|
||||
|
||||
Reference in New Issue
Block a user