Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 114c1974e1 | |||
| a99bf163d8 | |||
| b9ab71577f | |||
| f80b3112c6 | |||
| e0c72c85e5 | |||
| 01f568feac | |||
| 2046a0e096 | |||
| 49f535dfde | |||
| 5a250a4182 | |||
| 89fa9aba69 | |||
| 0feff205d2 | |||
| 5df5447eb0 | |||
| b87dc91c6f | |||
| 14b32504e0 | |||
| d35345a270 | |||
| f041172768 | |||
| 232a6233ca | |||
| c620478691 |
+2
-1
@@ -62,11 +62,12 @@ add_executable(ezremote_client
|
||||
source/windows.cpp
|
||||
source/zip_util.cpp
|
||||
source/split_file.cpp
|
||||
source/mem_file.cpp
|
||||
)
|
||||
|
||||
add_self(ezremote_client)
|
||||
|
||||
add_pkg(ezremote_client ${CMAKE_SOURCE_DIR}/data "RMTC00001" "ezRemote Client" "01.22" 32 0)
|
||||
add_pkg(ezremote_client ${CMAKE_SOURCE_DIR}/data "RMTC00001" "ezRemote Client" "01.27" 32 0)
|
||||
|
||||
target_link_libraries(ezremote_client
|
||||
c
|
||||
|
||||
@@ -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,8 +1,8 @@
|
||||
STR_CONNECTION_SETTINGS=连接设置
|
||||
STR_SITE=地点
|
||||
STR_LOCAL=当地的
|
||||
STR_REMOTE=偏僻的
|
||||
STR_MESSAGES=留言
|
||||
STR_SITE=站点
|
||||
STR_LOCAL=本地
|
||||
STR_REMOTE=远程路径
|
||||
STR_MESSAGES=信息
|
||||
STR_UPDATE_SOFTWARE=更新软件
|
||||
STR_CONNECT=连接
|
||||
STR_DISCONNECT=断开
|
||||
@@ -11,51 +11,123 @@ STR_REFRESH=刷新
|
||||
STR_SERVER=服务器
|
||||
STR_USERNAME=用户名
|
||||
STR_PASSWORD=密码
|
||||
STR_PORT=港口
|
||||
STR_PASV=帕夫
|
||||
STR_PORT=端口
|
||||
STR_PASV=被动模式
|
||||
STR_DIRECTORY=目录
|
||||
STR_FILTER=筛选
|
||||
STR_YES=是的
|
||||
STR_NO=不
|
||||
STR_FILTER=过滤器
|
||||
STR_YES=是
|
||||
STR_NO=否
|
||||
STR_CANCEL=取消
|
||||
STR_CONTINUE=继续
|
||||
STR_CLOSE=关闭
|
||||
STR_FOLDER=文件夹
|
||||
STR_FILE=文件
|
||||
STR_TYPE=类型
|
||||
STR_NAME=姓名
|
||||
STR_SIZE=尺寸
|
||||
STR_NAME=名称
|
||||
STR_SIZE=大小
|
||||
STR_DATE=日期
|
||||
STR_NEW_FOLDER=新建文件夹
|
||||
STR_RENAME=改名
|
||||
STR_RENAME=重命名
|
||||
STR_DELETE=删除
|
||||
STR_UPLOAD=上传
|
||||
STR_DOWNLOAD=下载
|
||||
STR_SELECT_ALL=全选
|
||||
STR_CLEAR_ALL=全部清除
|
||||
STR_UPLOADING=上传
|
||||
STR_DOWNLOADING=下载
|
||||
STR_CLEAR_ALL=取消全选
|
||||
STR_UPLOADING=上传中
|
||||
STR_DOWNLOADING=下载中
|
||||
STR_OVERWRITE=覆盖
|
||||
STR_DONT_OVERWRITE=不要覆盖
|
||||
STR_ASK_FOR_CONFIRM=要求确认
|
||||
STR_DONT_ASK_CONFIRM=不要要求确认
|
||||
STR_DONT_OVERWRITE=不覆盖
|
||||
STR_ASK_FOR_CONFIRM=确认请求
|
||||
STR_DONT_ASK_CONFIRM=不确认请求
|
||||
STR_ALLWAYS_USE_OPTION=始终使用此选项,不再询问
|
||||
STR_ACTIONS=行动
|
||||
STR_CONFIRM=确认
|
||||
STR_OVERWRITE_OPTIONS=覆盖选项
|
||||
STR_PROPERTIES=特性
|
||||
STR_PROGRESS=进步
|
||||
STR_PROPERTIES=属性
|
||||
STR_PROGRESS=进度
|
||||
STR_UPDATES=更新
|
||||
STR_DEL_CONFIRM_MSG=您确定要删除此文件/文件夹吗?
|
||||
STR_CANCEL_ACTION_MSG=取消。 等待最后一个动作完成
|
||||
STR_DEL_CONFIRM_MSG=您确定要删除此文件/文件夹?
|
||||
STR_CANCEL_ACTION_MSG=取消中。请等待最后一个操作结束
|
||||
STR_FAIL_UPLOAD_MSG=上传文件失败
|
||||
STR_FAIL_DOWNLOAD_MSG=下载文件失败
|
||||
STR_FAIL_READ_LOCAL_DIR_MSG=读取目录内容失败或文件夹不存在。
|
||||
STR_CONNECTION_CLOSE_ERR_MSG=426 连接已关闭。
|
||||
STR_REMOTE_TERM_CONN_MSG=426 远程服务器已终止连接。
|
||||
STR_FAIL_LOGIN_MSG=300 登录失败。 请检查您的用户名或密码。
|
||||
STR_FAIL_TIMEOUT_MSG=426 失败。 连接超时。
|
||||
STR_FAIL_LOGIN_MSG=300 登录失败。请检查您的用户名或密码。
|
||||
STR_FAIL_TIMEOUT_MSG=426 失败。连接超时。
|
||||
STR_FAIL_DEL_DIR_MSG=删除目录失败
|
||||
STR_DELETING=删除
|
||||
STR_DELETING=删除中
|
||||
STR_FAIL_DEL_FILE_MSG=删除文件失败
|
||||
STR_DELETED=已删除
|
||||
STR_DELETED=删除完毕
|
||||
STR_LINK=链接
|
||||
STR_SHARE=分享
|
||||
STR_FAILED=310 失败
|
||||
STR_FAIL_CREATE_LOCAL_FILE_MSG=310 无法本地创建文件
|
||||
STR_INSTALL=安装
|
||||
STR_INSTALLING=正在安装中
|
||||
STR_INSTALL_SUCCESS=成功
|
||||
STR_INSTALL_FAILED=失败
|
||||
STR_INSTALL_SKIPPED=已忽略
|
||||
STR_CHECK_HTTP_MSG=正在检查与远程HTTP服务器的连接
|
||||
STR_FAILED_HTTP_CHECK=连接到HTTP服务器失败
|
||||
STR_REMOTE_NOT_HTTP=远程不是HTTP服务器
|
||||
STR_INSTALL_FROM_DATA_MSG=文件包不在/data或/mnt/usbX文件夹中
|
||||
STR_ALREADY_INSTALLED_MSG=文件包已经安装
|
||||
STR_INSTALL_FROM_URL=从网址安装
|
||||
STR_CANNOT_READ_PKG_HDR_MSG=无法读取包文件头信息
|
||||
STR_FAVORITE_URLS=收藏网址
|
||||
STR_SLOT=槽位
|
||||
STR_EDIT=编辑
|
||||
STR_ONETIME_URL=一次性网址
|
||||
STR_NOT_A_VALID_PACKAGE=不是有效的程序包
|
||||
STR_WAIT_FOR_INSTALL_MSG=正在等待包完成安装
|
||||
STR_FAIL_INSTALL_TMP_PKG_MSG=未能安装pkg文件。请手动删除tmp pkg
|
||||
STR_AUTO_DELETE_TMP_PKG=安装后自动删除临时下载的pkg文件
|
||||
STR_PROTOCOL_NOT_SUPPORTED=不支持该协议
|
||||
STR_COULD_NOT_RESOLVE_HOST=无法解析主机名
|
||||
STR_EXTRACT=提取
|
||||
STR_EXTRACTING=提取中
|
||||
STR_FAILED_TO_EXTRACT=提取失败
|
||||
STR_EXTRACT_LOCATION=提取位置
|
||||
STR_COMPRESS=压缩
|
||||
STR_ZIP_FILE_PATH=Zip 文件名
|
||||
STR_COMPRESSING=压缩中
|
||||
STR_ERROR_CREATE_ZIP=正在创建zip文件时出现错误
|
||||
STR_UNSUPPORTED_FILE_FORMAT=不支持的压缩文件格式
|
||||
STR_CUT=剪切
|
||||
STR_COPY=复制
|
||||
STR_PASTE=粘贴
|
||||
STR_MOVING=移动中
|
||||
STR_COPYING=复制中
|
||||
STR_FAIL_MOVE_MSG=移动文件失败
|
||||
STR_FAIL_COPY_MSG=复制文件事变
|
||||
STR_CANT_MOVE_TO_SUBDIR_MSG=无法将父目录移动到子目录
|
||||
STR_CANT_COPY_TO_SUBDIR_MSG=无法将父目录复制到子目录
|
||||
STR_UNSUPPORTED_OPERATION_MSG=不支持操作
|
||||
STR_HTTP_PORT=Http 端口
|
||||
STR_REINSTALL_CONFIRM_MSG=内容已安装。是否要继续安装
|
||||
STR_REMOTE_NOT_SUPPORT_MSG=受保护的服务器不支持远程程序包安装。
|
||||
STR_CANNOT_CONNECT_REMOTE_MSG=无法访问远程HTTP服务器。
|
||||
STR_DOWNLOAD_INSTALL_MSG=无法安装远程程序包。是否下载软件包并进行安装?
|
||||
STR_CHECKING_REMOTE_SERVER_MSG=正在检查远程服务器的远程包安装。
|
||||
STR_FILES=文件
|
||||
STR_EDITOR=编辑器
|
||||
STR_SAVE=保存
|
||||
STR_MAX_EDIT_FILE_SIZE_MSG=无法编辑大于全部的文件。
|
||||
STR_DELETE_LINE=删除所选行
|
||||
STR_INSERT_LINE=在所选行下方插入
|
||||
STR_MODIFIED=已修改
|
||||
STR_FAIL_GET_TOKEN_MSG=无法从获取访问令牌
|
||||
STR_GET_TOKEN_SUCCESS_MSG=登录成功。您可以关闭浏览器并返回应用程序
|
||||
STR_NEW_FILE=新文件
|
||||
STR_SETTINGS=设置
|
||||
STR_GLOBAL=全局
|
||||
STR_COPY_LINE=复制所选行
|
||||
STR_PASTE_LINE=粘贴到所选行
|
||||
STR_SHOW_HIDDEN_FILES=显示隐藏文件
|
||||
STR_SET_DEFAULT_DIRECTORY=设置默认文件夹
|
||||
STR_SET_DEFAULT_DIRECTORY_MSG=已设置为默认目录
|
||||
STR_NFS_EXP_PATH_MISSING_MSG=URL中缺少NFS导出路径
|
||||
STR_FAIL_INIT_NFS_CONTEXT=无法初始化NFS上下文
|
||||
STR_FAIL_MOUNT_NFS_MSG=挂在 NFS 共享失败
|
||||
STR_VIEW_IMAGE=查看图片
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+54
-6
@@ -364,6 +364,7 @@ namespace Actions
|
||||
|
||||
if (confirm_state == CONFIRM_YES)
|
||||
{
|
||||
sceRtcGetCurrentTick(&prev_tick);
|
||||
return remoteclient->Put(src, dest);
|
||||
}
|
||||
|
||||
@@ -409,6 +410,7 @@ namespace Actions
|
||||
snprintf(activity_message, 1024, "%s %s", lang_strings[STR_UPLOADING], entries[i].path);
|
||||
bytes_to_download = entries[i].file_size;
|
||||
bytes_transfered = 0;
|
||||
sceRtcGetCurrentTick(&prev_tick);
|
||||
ret = UploadFile(entries[i].path, new_path);
|
||||
if (ret <= 0)
|
||||
{
|
||||
@@ -486,6 +488,7 @@ namespace Actions
|
||||
int DownloadFile(const char *src, const char *dest)
|
||||
{
|
||||
bytes_transfered = 0;
|
||||
sceRtcGetCurrentTick(&prev_tick);
|
||||
if (!remoteclient->Size(src, &bytes_to_download))
|
||||
{
|
||||
remoteclient->Quit();
|
||||
@@ -517,6 +520,7 @@ namespace Actions
|
||||
|
||||
if (confirm_state == CONFIRM_YES)
|
||||
{
|
||||
sceRtcGetCurrentTick(&prev_tick);
|
||||
return remoteclient->Get(dest, src);
|
||||
}
|
||||
|
||||
@@ -708,20 +712,46 @@ 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
|
||||
skipped++;
|
||||
}
|
||||
}
|
||||
else if (Util::EndsWith(path,".zip") || Util::EndsWith(path,".rar") ||
|
||||
else if (Util::EndsWith(path,".zip") || Util::EndsWith(path,".rar") || Util::EndsWith(path,".7z") ||
|
||||
Util::EndsWith(path,".tar.xz") || Util::EndsWith(path,".tar.gz"))
|
||||
{
|
||||
ArchiveEntry *entry = ZipUtil::GetPackageEntry(it->path, remoteclient);
|
||||
@@ -817,6 +847,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;
|
||||
@@ -1067,6 +1109,7 @@ namespace Actions
|
||||
void *InstallUrlPkgThread(void *argp)
|
||||
{
|
||||
bytes_transfered = 0;
|
||||
sceRtcGetCurrentTick(&prev_tick);
|
||||
sprintf(status_message, "%s", "");
|
||||
pkg_header header;
|
||||
char filename[2000];
|
||||
@@ -1337,6 +1380,7 @@ namespace Actions
|
||||
|
||||
if (confirm_state == CONFIRM_YES)
|
||||
{
|
||||
sceRtcGetCurrentTick(&prev_tick);
|
||||
if (isCopy)
|
||||
return FS::Copy(src, dest);
|
||||
else
|
||||
@@ -1384,6 +1428,7 @@ namespace Actions
|
||||
snprintf(activity_message, 1024, "%s %s", isCopy ? lang_strings[STR_COPYING] : lang_strings[STR_MOVING], entries[i].path);
|
||||
bytes_to_download = entries[i].file_size;
|
||||
bytes_transfered = 0;
|
||||
sceRtcGetCurrentTick(&prev_tick);
|
||||
ret = CopyOrMoveLocalFile(entries[i].path, new_path, isCopy);
|
||||
if (ret <= 0)
|
||||
{
|
||||
@@ -1538,6 +1583,7 @@ namespace Actions
|
||||
|
||||
if (confirm_state == CONFIRM_YES)
|
||||
{
|
||||
sceRtcGetCurrentTick(&prev_tick);
|
||||
if (isCopy)
|
||||
return remoteclient->Copy(src, dest);
|
||||
else
|
||||
@@ -1633,6 +1679,7 @@ namespace Actions
|
||||
snprintf(activity_message, 1024, "%s %s", lang_strings[STR_COPYING], entries[i].path);
|
||||
bytes_to_download = entries[i].file_size;
|
||||
bytes_transfered = 0;
|
||||
sceRtcGetCurrentTick(&prev_tick);
|
||||
ret = CopyOrMoveRemoteFile(entries[i].path, new_path, true);
|
||||
if (ret <= 0)
|
||||
{
|
||||
@@ -1726,6 +1773,7 @@ namespace Actions
|
||||
sprintf(activity_message, "%s %s to %s", lang_strings[STR_DOWNLOADING], filename.c_str(), local_file);
|
||||
remoteclient->Size(filename, &bytes_to_download);
|
||||
bytes_transfered = 0;
|
||||
sceRtcGetCurrentTick(&prev_tick);
|
||||
file_transfering = true;
|
||||
int ret = remoteclient->Get(local_file, filename);
|
||||
if (ret == 0)
|
||||
|
||||
+3
-2
@@ -1,5 +1,5 @@
|
||||
#ifndef ACTIONS_H
|
||||
#define ACTIONS_H
|
||||
#ifndef EZ_ACTIONS_H
|
||||
#define EZ_ACTIONS_H
|
||||
|
||||
#include <pthread.h>
|
||||
#include "installer.h"
|
||||
@@ -120,6 +120,7 @@ namespace Actions
|
||||
void CreateLocalFile(char *filename);
|
||||
void CreateRemoteFile(char *filename);
|
||||
void *ExtractArchivePkg(void *argp);
|
||||
void *DownloadSplitPkg(void *argp);
|
||||
}
|
||||
|
||||
#endif
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
#ifndef BASE64_H_
|
||||
#define BASE64_H_
|
||||
#ifndef EZ_BASE64_H_
|
||||
#define EZ_BASE64_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef APACHE_H
|
||||
#define APACHE_H
|
||||
#ifndef EZ_APACHE_H
|
||||
#define EZ_APACHE_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -102,6 +102,8 @@ int BaseClient::Get(const std::string &outputfile, const std::string &path, uint
|
||||
{
|
||||
std::ofstream file_stream(outputfile, std::ios::binary);
|
||||
bytes_transfered = 0;
|
||||
sceRtcGetCurrentTick(&prev_tick);
|
||||
|
||||
if (auto res = client->Get(GetFullPath(path),
|
||||
[&](const char *data, size_t data_length)
|
||||
{
|
||||
@@ -120,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];
|
||||
@@ -345,3 +370,26 @@ std::string BaseClient::UnEscape(const std::string &url)
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
void *BaseClient::Open(const std::string &path, int flags)
|
||||
{
|
||||
sprintf(this->response, "%s", lang_strings[STR_UNSUPPORTED_OPERATION_MSG]);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void BaseClient::Close(void *fp)
|
||||
{
|
||||
sprintf(this->response, "%s", lang_strings[STR_UNSUPPORTED_OPERATION_MSG]);
|
||||
}
|
||||
|
||||
int BaseClient::GetRange(void *fp, DataSink &sink, uint64_t size, uint64_t offset)
|
||||
{
|
||||
sprintf(this->response, "%s", lang_strings[STR_UNSUPPORTED_OPERATION_MSG]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int BaseClient::GetRange(void *fp, void *buffer, uint64_t size, uint64_t offset)
|
||||
{
|
||||
sprintf(this->response, "%s", lang_strings[STR_UNSUPPORTED_OPERATION_MSG]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef BASESERVER_H
|
||||
#define BASESERVER_H
|
||||
#ifndef EZ_BASESERVER_H
|
||||
#define EZ_BASESERVER_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -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,8 +22,11 @@ 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);
|
||||
int GetRange(void *fp, DataSink &sink, uint64_t size, uint64_t offset);
|
||||
int Put(const std::string &inputfile, const std::string &path, uint64_t offset=0);
|
||||
int Rename(const std::string &src, const std::string &dst);
|
||||
int Delete(const std::string &path);
|
||||
@@ -33,6 +37,8 @@ public:
|
||||
std::vector<DirEntry> ListDir(const std::string &path);
|
||||
std::string GetPath(std::string path1, std::string path2);
|
||||
std::string GetFullPath(std::string path1);
|
||||
void *Open(const std::string &path, int flags);
|
||||
void Close(void *fp);
|
||||
bool IsConnected();
|
||||
bool Ping();
|
||||
const char *LastResponse();
|
||||
|
||||
@@ -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;
|
||||
@@ -1744,7 +1779,7 @@ ClientType FtpClient::clientType()
|
||||
|
||||
uint32_t FtpClient::SupportedActions()
|
||||
{
|
||||
return REMOTE_ACTION_ALL ^ REMOTE_ACTION_CUT ^ REMOTE_ACTION_COPY ^ REMOTE_ACTION_PASTE;
|
||||
return REMOTE_ACTION_ALL ^ REMOTE_ACTION_CUT ^ REMOTE_ACTION_COPY ^ REMOTE_ACTION_PASTE ^ REMOTE_ACTION_RAW_READ;
|
||||
}
|
||||
|
||||
std::string FtpClient::GetPath(std::string ppath1, std::string ppath2)
|
||||
@@ -1783,4 +1818,23 @@ int FtpClient::Head(const std::string &path, void *buffer, uint64_t len)
|
||||
if (l != len)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
void *FtpClient::Open(const std::string &path, int flags)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void FtpClient::Close(void *fp)
|
||||
{
|
||||
}
|
||||
|
||||
int FtpClient::GetRange(void *fp, DataSink &sink, uint64_t size, uint64_t offset)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int FtpClient::GetRange(void *fp, void *buffer, uint64_t size, uint64_t offset)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef FTPCLIENT_H
|
||||
#define FTPCLIENT_H
|
||||
#ifndef EZ_FTPCLIENT_H
|
||||
#define EZ_FTPCLIENT_H
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
@@ -79,14 +79,19 @@ 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);
|
||||
int GetRange(void *fp, DataSink &sink, uint64_t size, uint64_t offset);
|
||||
int Put(const std::string &inputfile, const std::string &path, uint64_t offset = 0);
|
||||
int Rename(const std::string &src, const std::string &dst);
|
||||
int Delete(const std::string &path);
|
||||
int Copy(const std::string &from, const std::string &to);
|
||||
int Move(const std::string &from, const std::string &to);
|
||||
int Head(const std::string &path, void *buffer, uint64_t len);
|
||||
void *Open(const std::string &path, int flags);
|
||||
void Close(void *fp);
|
||||
std::vector<DirEntry> ListDir(const std::string &path);
|
||||
void SetCallbackXferFunction(FtpCallbackXfer pointer);
|
||||
void SetCallbackArg(void *arg);
|
||||
@@ -124,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);
|
||||
|
||||
@@ -307,6 +307,7 @@ int GDriveClient::Get(const std::string &outputfile, const std::string &path, ui
|
||||
{
|
||||
std::ofstream file_stream(outputfile, std::ios::binary);
|
||||
bytes_transfered = 0;
|
||||
sceRtcGetCurrentTick(&prev_tick);
|
||||
|
||||
std::string id = GetValue(path_id_map, path);
|
||||
std::string drive_id = GetDriveId(path);
|
||||
@@ -331,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;
|
||||
@@ -399,9 +428,9 @@ int GDriveClient::Update(const std::string &inputfile, const std::string &path)
|
||||
{
|
||||
bytes_to_download = FS::GetSize(inputfile);
|
||||
bytes_transfered = 0;
|
||||
sceRtcGetCurrentTick(&prev_tick);
|
||||
|
||||
std::ifstream file_stream(inputfile, std::ios::binary);
|
||||
bytes_transfered = 0;
|
||||
|
||||
std::string id = GetValue(path_id_map, path);
|
||||
std::string drive_id = GetDriveId(path);
|
||||
@@ -473,9 +502,9 @@ int GDriveClient::Put(const std::string &inputfile, const std::string &path, uin
|
||||
|
||||
bytes_to_download = FS::GetSize(inputfile);
|
||||
bytes_transfered = 0;
|
||||
sceRtcGetCurrentTick(&prev_tick);
|
||||
|
||||
std::ifstream file_stream(inputfile, std::ios::binary);
|
||||
bytes_transfered = 0;
|
||||
|
||||
size_t path_pos = path.find_last_of("/");
|
||||
std::string parent_dir;
|
||||
@@ -887,7 +916,7 @@ ClientType GDriveClient::clientType()
|
||||
|
||||
uint32_t GDriveClient::SupportedActions()
|
||||
{
|
||||
return REMOTE_ACTION_ALL ^ REMOTE_ACTION_CUT ^ REMOTE_ACTION_COPY ^ REMOTE_ACTION_PASTE;
|
||||
return REMOTE_ACTION_ALL ^ REMOTE_ACTION_CUT ^ REMOTE_ACTION_COPY ^ REMOTE_ACTION_PASTE ^ REMOTE_ACTION_RAW_READ;
|
||||
}
|
||||
|
||||
void *GDriveClient::RefreshTokenThread(void *argp)
|
||||
@@ -941,4 +970,27 @@ void GDriveClient::SetAccessToken(const std::string &token)
|
||||
{
|
||||
if (this->client != nullptr)
|
||||
this->client->set_bearer_token_auth(token);
|
||||
}
|
||||
}
|
||||
|
||||
void *GDriveClient::Open(const std::string &path, int flags)
|
||||
{
|
||||
sprintf(this->response, "%s", lang_strings[STR_UNSUPPORTED_OPERATION_MSG]);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void GDriveClient::Close(void *fp)
|
||||
{
|
||||
sprintf(this->response, "%s", lang_strings[STR_UNSUPPORTED_OPERATION_MSG]);
|
||||
}
|
||||
|
||||
int GDriveClient::GetRange(void *fp, DataSink &sink, uint64_t size, uint64_t offset)
|
||||
{
|
||||
sprintf(this->response, "%s", lang_strings[STR_UNSUPPORTED_OPERATION_MSG]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int GDriveClient::GetRange(void *fp, void *buffer, uint64_t size, uint64_t offset)
|
||||
{
|
||||
sprintf(this->response, "%s", lang_strings[STR_UNSUPPORTED_OPERATION_MSG]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef GDRIVE_H
|
||||
#define GDRIVE_H
|
||||
#ifndef EZ_GDRIVE_H
|
||||
#define EZ_GDRIVE_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -20,8 +20,11 @@ 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);
|
||||
int GetRange(void *fp, DataSink &sink, uint64_t size, uint64_t offset);
|
||||
int Put(const std::string &inputfile, const std::string &path, uint64_t offset=0);
|
||||
int Head(const std::string &path, void *buffer, uint64_t len);
|
||||
int Update(const std::string &inputfile, const std::string &path);
|
||||
@@ -32,6 +35,8 @@ public:
|
||||
bool FileExists(const std::string &path);
|
||||
void SetAccessToken(const std::string &token);
|
||||
std::vector<DirEntry> ListDir(const std::string &path);
|
||||
void *Open(const std::string &path, int flags);
|
||||
void Close(void *fp);
|
||||
static void *RefreshTokenThread(void *argp);
|
||||
static void StartRefreshToken();
|
||||
static void StopRefreshToken();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef IIS_H
|
||||
#define IIS_H
|
||||
#ifndef EZ_IIS_H
|
||||
#define EZ_IIS_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -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]);
|
||||
@@ -213,6 +214,7 @@ int NfsClient::Get(const std::string &outputfile, const std::string &ppath, uint
|
||||
void *buff = malloc(BUF_SIZE);
|
||||
int count = 0;
|
||||
bytes_transfered = 0;
|
||||
sceRtcGetCurrentTick(&prev_tick);
|
||||
while ((count = nfs_read(nfs, nfsfh, BUF_SIZE, buff)) > 0)
|
||||
{
|
||||
if (count < 0)
|
||||
@@ -220,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);
|
||||
@@ -228,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;
|
||||
}
|
||||
@@ -242,49 +273,51 @@ int NfsClient::GetRange(const std::string &path, DataSink &sink, uint64_t size,
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = nfs_lseek(nfs, nfsfh, offset, SEEK_SET, NULL);
|
||||
ret = this->GetRange((void *)nfsfh, sink, size, offset);
|
||||
nfs_close(nfs, nfsfh);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int NfsClient::GetRange(void *fp, DataSink &sink, uint64_t size, uint64_t offset)
|
||||
{
|
||||
struct nfsfh *nfsfh = (struct nfsfh *)fp;
|
||||
|
||||
int ret = nfs_lseek(nfs, nfsfh, offset, SEEK_SET, NULL);
|
||||
if (ret != 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
nfs_close(nfs, nfsfh);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
} while (1);
|
||||
|
||||
free((void *)buff);
|
||||
nfs_close(nfs, nfsfh);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
} while (1);
|
||||
|
||||
free((void *)buff);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int NfsClient::GetRange(const std::string &ppath, void *buffer, uint64_t size, uint64_t offset)
|
||||
{
|
||||
if (!FileExists(ppath))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct nfsfh *nfsfh = nullptr;
|
||||
int ret = nfs_open(nfs, ppath.c_str(), 0400, &nfsfh);
|
||||
if (ret != 0)
|
||||
@@ -293,7 +326,17 @@ int NfsClient::GetRange(const std::string &ppath, void *buffer, uint64_t size, u
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = nfs_lseek(nfs, nfsfh, offset, SEEK_SET, NULL);
|
||||
ret = this->GetRange(nfsfh, buffer, size, offset);
|
||||
nfs_close(nfs, nfsfh);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int NfsClient::GetRange(void *fp, void *buffer, uint64_t size, uint64_t offset)
|
||||
{
|
||||
struct nfsfh *nfsfh = (struct nfsfh *)fp;
|
||||
|
||||
int ret = nfs_lseek(nfs, nfsfh, offset, SEEK_SET, NULL);
|
||||
if (ret != 0)
|
||||
{
|
||||
sprintf(response, "%s", nfs_get_error(nfs));
|
||||
@@ -301,7 +344,6 @@ int NfsClient::GetRange(const std::string &ppath, void *buffer, uint64_t size, u
|
||||
}
|
||||
|
||||
int count = nfs_read(nfs, nfsfh, size, buffer);
|
||||
nfs_close(nfs, nfsfh);
|
||||
if (count != size)
|
||||
return 0;
|
||||
|
||||
@@ -346,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))
|
||||
@@ -368,9 +410,10 @@ 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);
|
||||
while ((count = FS::Read(in, buff, BUF_SIZE)) > 0)
|
||||
{
|
||||
if (count < 0)
|
||||
@@ -446,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;
|
||||
}
|
||||
@@ -513,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);
|
||||
|
||||
@@ -553,6 +596,19 @@ int NfsClient::Head(const std::string &ppath, void *buffer, uint64_t len)
|
||||
return 1;
|
||||
}
|
||||
|
||||
void *NfsClient::Open(const std::string &path, int flags)
|
||||
{
|
||||
struct nfsfh *nfsfh = nullptr;
|
||||
nfs_open(nfs, path.c_str(), 0400, &nfsfh);
|
||||
;
|
||||
return nfsfh;
|
||||
}
|
||||
|
||||
void NfsClient::Close(void *fp)
|
||||
{
|
||||
nfs_close(nfs, (struct nfsfh *)fp);
|
||||
}
|
||||
|
||||
ClientType NfsClient::clientType()
|
||||
{
|
||||
return CLIENT_TYPE_NFS;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef NFSCLIENT_H
|
||||
#define NFSCLIENT_H
|
||||
#ifndef EZ_NFSCLIENT_H
|
||||
#define EZ_NFSCLIENT_H
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
@@ -23,8 +23,11 @@ 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);
|
||||
int GetRange(void *fp, DataSink &sink, uint64_t size, uint64_t offset);
|
||||
int Put(const std::string &inputfile, const std::string &path, uint64_t offset=0);
|
||||
int Rename(const std::string &src, const std::string &dst);
|
||||
int Delete(const std::string &path);
|
||||
@@ -32,6 +35,8 @@ public:
|
||||
int Copy(const std::string &from, const std::string &to);
|
||||
int Move(const std::string &from, const std::string &to);
|
||||
std::vector<DirEntry> ListDir(const std::string &path);
|
||||
void *Open(const std::string &path, int flags);
|
||||
void Close(void *fp);
|
||||
bool IsConnected();
|
||||
bool Ping();
|
||||
const char *LastResponse();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef NGINX_H
|
||||
#define NGINX_H
|
||||
#ifndef EZ_NGINX_H
|
||||
#define EZ_NGINX_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef NPXSERVE_H
|
||||
#define NPXSERVE_H
|
||||
#ifndef EZ_NPXSERVE_H
|
||||
#define EZ_NPXSERVE_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef RCLONE_H
|
||||
#define RCLONE_H
|
||||
#ifndef EZ_RCLONE_H
|
||||
#define EZ_RCLONE_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
#ifndef REMOTECLIENT_H
|
||||
#define REMOTECLIENT_H
|
||||
#ifndef EZ_REMOTECLIENT_H
|
||||
#define EZ_REMOTECLIENT_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "common.h"
|
||||
#include "http/httplib.h"
|
||||
#include "split_file.h"
|
||||
|
||||
enum RemoteActions
|
||||
{
|
||||
@@ -21,7 +22,8 @@ enum RemoteActions
|
||||
REMOTE_ACTION_EDIT = 512,
|
||||
REMOTE_ACTION_NEW_FILE = 1024,
|
||||
REMOTE_ACTION_EXTRACT = 2048,
|
||||
REMOTE_ACTION_ALL = 4095
|
||||
REMOTE_ACTION_RAW_READ = 4096,
|
||||
REMOTE_ACTION_ALL = 8191
|
||||
};
|
||||
|
||||
enum ClientType
|
||||
@@ -48,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;
|
||||
@@ -56,8 +59,12 @@ public:
|
||||
virtual int Head(const std::string &path, void *buffer, uint64_t len) = 0;
|
||||
virtual int GetRange(const std::string &path, void *buffer, uint64_t size, uint64_t offset) = 0;
|
||||
virtual int GetRange(const std::string &path, DataSink &sink, uint64_t size, uint64_t offset) = 0;
|
||||
virtual int GetRange(void *fp, void *buffer, uint64_t size, uint64_t offset) = 0;
|
||||
virtual int GetRange(void *fp, DataSink &sink, uint64_t size, uint64_t offset) = 0;
|
||||
virtual bool FileExists(const std::string &path) = 0;
|
||||
virtual std::vector<DirEntry> ListDir(const std::string &path) = 0;
|
||||
virtual void *Open(const std::string &path, int flags) = 0;
|
||||
virtual void Close(void *fp) = 0;
|
||||
virtual std::string GetPath(std::string path1, std::string path2) = 0;
|
||||
virtual bool IsConnected() = 0;
|
||||
virtual bool Ping() = 0;
|
||||
|
||||
@@ -284,6 +284,8 @@ int SFTPClient::Get(const std::string &outputfile, const std::string &path, uint
|
||||
char *buff = (char *)malloc(FTP_CLIENT_BUFSIZ);
|
||||
int rc, count = 0;
|
||||
bytes_transfered = 0;
|
||||
sceRtcGetCurrentTick(&prev_tick);
|
||||
|
||||
do
|
||||
{
|
||||
rc = libssh2_sftp_read(sftp_handle, buff, FTP_CLIENT_BUFSIZ);
|
||||
@@ -304,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);
|
||||
@@ -313,6 +345,16 @@ int SFTPClient::GetRange(const std::string &path, DataSink &sink, uint64_t size,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ret = this->GetRange((void *)sftp_handle, sink, size, offset);
|
||||
libssh2_sftp_close(sftp_handle);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SFTPClient::GetRange(void *fp, DataSink &sink, uint64_t size, uint64_t offset)
|
||||
{
|
||||
LIBSSH2_SFTP_HANDLE *sftp_handle = (LIBSSH2_SFTP_HANDLE *)fp;
|
||||
|
||||
libssh2_sftp_seek64(sftp_handle, offset);
|
||||
|
||||
char *buff = (char *)malloc(FTP_CLIENT_BUFSIZ);
|
||||
@@ -329,7 +371,6 @@ int SFTPClient::GetRange(const std::string &path, DataSink &sink, uint64_t size,
|
||||
if (!ok)
|
||||
{
|
||||
free((char *)buff);
|
||||
libssh2_sftp_close(sftp_handle);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -340,9 +381,8 @@ int SFTPClient::GetRange(const std::string &path, DataSink &sink, uint64_t size,
|
||||
} while (1);
|
||||
|
||||
free((char *)buff);
|
||||
libssh2_sftp_close(sftp_handle);
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SFTPClient::GetRange(const std::string &path, void *buffer, uint64_t size, uint64_t offset)
|
||||
@@ -359,9 +399,18 @@ int SFTPClient::GetRange(const std::string &path, void *buffer, uint64_t size, u
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ret = this->GetRange(sftp_handle, buffer, size, offset);
|
||||
libssh2_sftp_close(sftp_handle);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SFTPClient::GetRange(void *fp, void *buffer, uint64_t size, uint64_t offset)
|
||||
{
|
||||
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);
|
||||
libssh2_sftp_close(sftp_handle);
|
||||
if (count != size)
|
||||
return 0;
|
||||
|
||||
@@ -401,6 +450,8 @@ int SFTPClient::Put(const std::string &inputfile, const std::string &path, uint6
|
||||
buff = (char *)malloc(FTP_CLIENT_BUFSIZ);
|
||||
int nread, count = 0;
|
||||
bytes_transfered = 0;
|
||||
sceRtcGetCurrentTick(&prev_tick);
|
||||
|
||||
do
|
||||
{
|
||||
nread = FS::Read(in, buff, FTP_CLIENT_BUFSIZ);
|
||||
@@ -642,6 +693,16 @@ int SFTPClient::Quit()
|
||||
return 1;
|
||||
}
|
||||
|
||||
void *SFTPClient::Open(const std::string &path, int flags)
|
||||
{
|
||||
return libssh2_sftp_open(sftp_session, path.c_str(), LIBSSH2_FXF_READ, 0);
|
||||
}
|
||||
|
||||
void SFTPClient::Close(void *fp)
|
||||
{
|
||||
libssh2_sftp_close((LIBSSH2_SFTP_HANDLE *)fp);
|
||||
}
|
||||
|
||||
ClientType SFTPClient::clientType()
|
||||
{
|
||||
return CLIENT_TYPE_SFTP;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef SFTPCLIENT_H
|
||||
#define SFTPCLIENT_H
|
||||
#ifndef EZ_SFTPCLIENT_H
|
||||
#define EZ_SFTPCLIENT_H
|
||||
|
||||
#include <libssh2.h>
|
||||
#include <libssh2_sftp.h>
|
||||
@@ -20,8 +20,11 @@ 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);
|
||||
int GetRange(void *fp, DataSink &sink, uint64_t size, uint64_t offset);
|
||||
int Put(const std::string &inputfile, const std::string &path, uint64_t offset=0);
|
||||
int Rename(const std::string &src, const std::string &dst);
|
||||
int Delete(const std::string &path);
|
||||
@@ -30,6 +33,8 @@ public:
|
||||
int Head(const std::string &path, void *buffer, uint64_t len);
|
||||
bool FileExists(const std::string &path);
|
||||
std::vector<DirEntry> ListDir(const std::string &path);
|
||||
void *Open(const std::string &path, int flags);
|
||||
void Close(void *fp);
|
||||
std::string GetPath(std::string path1, std::string path2);
|
||||
bool IsConnected();
|
||||
bool Ping();
|
||||
|
||||
+123
-43
@@ -197,23 +197,25 @@ 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);
|
||||
|
||||
while ((count = smb2_read(smb2, in, buff, max_read_size)) > 0)
|
||||
{
|
||||
if (count < 0)
|
||||
@@ -221,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);
|
||||
@@ -229,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;
|
||||
}
|
||||
|
||||
@@ -237,40 +271,48 @@ 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;
|
||||
}
|
||||
|
||||
smb2_lseek(smb2, in, offset, SEEK_SET, NULL);
|
||||
int ret = this->GetRange((void *)in, sink, size, offset);
|
||||
smb2_close(smb2, in);
|
||||
|
||||
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);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SmbClient::GetRange(void *fp, DataSink &sink, uint64_t size, uint64_t offset)
|
||||
{
|
||||
struct smb2fh *in = (struct smb2fh *)fp;
|
||||
|
||||
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);
|
||||
if (!ok)
|
||||
{
|
||||
free((uint8_t *)buff);
|
||||
smb2_close(smb2, in);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
} while (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
} while (1);
|
||||
|
||||
free((char *)buff);
|
||||
smb2_close(smb2, in);
|
||||
free((char *)buff);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -285,18 +327,41 @@ 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;
|
||||
}
|
||||
|
||||
int ret = this->GetRange(in, buffer, size, offset);
|
||||
smb2_close(smb2, in);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SmbClient::GetRange(void *fp, void *buffer, uint64_t size, uint64_t offset)
|
||||
{
|
||||
struct smb2fh *in = (struct smb2fh *)fp;
|
||||
|
||||
smb2_lseek(smb2, in, offset, SEEK_SET, NULL);
|
||||
|
||||
int count = smb2_read(smb2, in, (uint8_t*)buffer, size);
|
||||
smb2_close(smb2, in);
|
||||
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;
|
||||
}
|
||||
@@ -323,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)
|
||||
{
|
||||
@@ -338,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);
|
||||
@@ -348,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;
|
||||
}
|
||||
|
||||
@@ -384,23 +449,25 @@ 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);
|
||||
|
||||
while ((count = FS::Read(in, buff, max_write_size)) > 0)
|
||||
{
|
||||
if (count < 0)
|
||||
@@ -419,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)
|
||||
@@ -553,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;
|
||||
@@ -567,6 +633,20 @@ int SmbClient::Head(const std::string &ppath, void *buffer, uint64_t len)
|
||||
return 1;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void SmbClient::Close(void *fp)
|
||||
{
|
||||
smb2_close(smb2, (struct smb2fh *)fp);
|
||||
}
|
||||
|
||||
ClientType SmbClient::clientType()
|
||||
{
|
||||
return CLIENT_TYPE_SMB;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef SMBCLIENT_H
|
||||
#define SMBCLIENT_H
|
||||
#ifndef EZ_SMBCLIENT_H
|
||||
#define EZ_SMBCLIENT_H
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
@@ -24,8 +24,11 @@ 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);
|
||||
int GetRange(void *fp, DataSink &sink, uint64_t size, uint64_t offset);
|
||||
int Put(const std::string &inputfile, const std::string &path, uint64_t offset=0);
|
||||
int Rename(const std::string &src, const std::string &dst);
|
||||
int Delete(const std::string &path);
|
||||
@@ -34,6 +37,8 @@ public:
|
||||
int Move(const std::string &from, const std::string &to);
|
||||
int CopyToSocket(const std::string &path, int socket_fd);
|
||||
std::vector<DirEntry> ListDir(const std::string &path);
|
||||
void *Open(const std::string &path, int flags);
|
||||
void Close(void *fp);
|
||||
bool IsConnected();
|
||||
bool Ping();
|
||||
const char *LastResponse();
|
||||
|
||||
+55
-14
@@ -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;
|
||||
@@ -151,12 +195,12 @@ int WebDAVClient::Put(const std::string &inputfile, const std::string &path, uin
|
||||
{
|
||||
size_t bytes_remaining = FS::GetSize(inputfile);
|
||||
bytes_transfered = 0;
|
||||
|
||||
FILE* in = FS::OpenRead(inputfile);
|
||||
sceRtcGetCurrentTick(&prev_tick);
|
||||
|
||||
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);
|
||||
@@ -170,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))
|
||||
{
|
||||
@@ -229,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));
|
||||
@@ -256,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));
|
||||
@@ -279,5 +320,5 @@ ClientType WebDAVClient::clientType()
|
||||
|
||||
uint32_t WebDAVClient::SupportedActions()
|
||||
{
|
||||
return REMOTE_ACTION_ALL;
|
||||
return REMOTE_ACTION_ALL ^ REMOTE_ACTION_RAW_READ;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef WEBDAV_H
|
||||
#define WEBDAV_H
|
||||
#ifndef EZ_WEBDAV_H
|
||||
#define EZ_WEBDAV_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -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();
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
#ifndef COMMON_H
|
||||
#define COMMON_H
|
||||
#ifndef EZ_COMMON_H
|
||||
#define EZ_COMMON_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -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);
|
||||
|
||||
+4
-2
@@ -1,5 +1,5 @@
|
||||
#ifndef LAUNCHER_CONFIG_H
|
||||
#define LAUNCHER_CONFIG_H
|
||||
#ifndef EZ_CONFIG_H
|
||||
#define EZ_CONFIG_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -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"
|
||||
@@ -110,6 +111,7 @@ struct RemoteSettings
|
||||
char http_server_type[24];
|
||||
GoogleAccountInfo gg_account;
|
||||
char default_directory[256];
|
||||
bool enable_disk_cache;
|
||||
};
|
||||
|
||||
struct PackageUrlInfo
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef FICHIER_HOST_H
|
||||
#define FICHIER_HOST_H
|
||||
#ifndef EZ_FICHIER_HOST_H
|
||||
#define EZ_FICHIER_HOST_H
|
||||
|
||||
#include "filehost.h"
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef ALLDEBRID_HOST_H
|
||||
#define ALLDEBRID_HOST_H
|
||||
#ifndef EZ_ALLDEBRID_HOST_H
|
||||
#define EZ_ALLDEBRID_HOST_H
|
||||
|
||||
#include "filehost.h"
|
||||
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
#include <regex>
|
||||
#include <lexbor/html/parser.h>
|
||||
#include <lexbor/dom/interfaces/element.h>
|
||||
#include <http/httplib.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef DIRECT_HOST_H
|
||||
#define DIRECT_HOST_H
|
||||
#ifndef EZ_DIRECT_HOST_H
|
||||
#define EZ_DIRECT_HOST_H
|
||||
|
||||
#include "filehost.h"
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef FILEHOST_H
|
||||
#define FILEHOST_H
|
||||
#ifndef EZ_FILEHOST_H
|
||||
#define EZ_FILEHOST_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef GDRIVE_HOST_H
|
||||
#define GDRIVE_HOST_H
|
||||
#ifndef EZ_GDRIVE_HOST_H
|
||||
#define EZ_GDRIVE_HOST_H
|
||||
|
||||
#include "filehost.h"
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef MEDIAFIRE_HOST_H
|
||||
#define MEDIAFIRE_HOST_H
|
||||
#ifndef EZ_MEDIAFIRE_HOST_H
|
||||
#define EZ_MEDIAFIRE_HOST_H
|
||||
|
||||
#include "filehost.h"
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef PIXELDRAIN_HOST_H
|
||||
#define PIXELDRAIN_HOST_H
|
||||
#ifndef EZ_PIXELDRAIN_HOST_H
|
||||
#define EZ_PIXELDRAIN_HOST_H
|
||||
|
||||
#include "filehost.h"
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef REALDEBRID_HOST_H
|
||||
#define REALDEBRID_HOST_H
|
||||
#ifndef EZ_REALDEBRID_HOST_H
|
||||
#define EZ_REALDEBRID_HOST_H
|
||||
|
||||
#include "filehost.h"
|
||||
|
||||
|
||||
@@ -510,6 +510,8 @@ namespace FS
|
||||
|
||||
size_t bytes_read = 0;
|
||||
bytes_transfered = 0;
|
||||
sceRtcGetCurrentTick(&prev_tick);
|
||||
|
||||
const size_t buf_size = 0x10000;
|
||||
unsigned char *buf = new unsigned char[buf_size];
|
||||
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
#ifndef LAUNCHER_FS_H
|
||||
#define LAUNCHER_FS_H
|
||||
#ifndef EZ_FS_H
|
||||
#define EZ_FS_H
|
||||
|
||||
#pragma once
|
||||
#include <string.h>
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
#ifndef LAUNCHER_GUI_H
|
||||
#define LAUNCHER_GUI_H
|
||||
#ifndef EZ_GUI_H
|
||||
#define EZ_GUI_H
|
||||
|
||||
#include <string>
|
||||
#include "SDL2/SDL.h"
|
||||
|
||||
+2
-2
@@ -16,8 +16,8 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __IME_DIALOG_H__
|
||||
#define __IME_DIALOG_H__
|
||||
#ifndef __EZ_IME_DIALOG_H__
|
||||
#define __EZ_IME_DIALOG_H__
|
||||
|
||||
#define IME_DIALOG_RESULT_NONE 0
|
||||
#define IME_DIALOG_RESULT_RUNNING 1
|
||||
|
||||
+258
-45
@@ -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);
|
||||
@@ -385,19 +399,20 @@ namespace INSTALLER
|
||||
}
|
||||
|
||||
Util::Notify("%s queued", display_title.c_str());
|
||||
|
||||
if (prompt)
|
||||
{
|
||||
file_transfering = true;
|
||||
bytes_to_download = 100;
|
||||
bytes_to_download = header->pkg_content_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))
|
||||
return 0;
|
||||
|
||||
|
||||
if (progress_info.length > 0)
|
||||
{
|
||||
completed = progress_info.transferred == progress_info.length;
|
||||
@@ -409,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);
|
||||
@@ -488,8 +504,10 @@ 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);
|
||||
|
||||
while (!completed)
|
||||
{
|
||||
memset(&progress_info, 0, sizeof(progress_info));
|
||||
@@ -515,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)
|
||||
@@ -599,8 +617,10 @@ 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);
|
||||
|
||||
while (!completed)
|
||||
{
|
||||
memset(&progress_info, 0, sizeof(progress_info));
|
||||
@@ -639,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;
|
||||
@@ -710,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;
|
||||
@@ -778,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);
|
||||
}
|
||||
@@ -788,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);
|
||||
@@ -915,8 +935,10 @@ namespace INSTALLER
|
||||
if (!bg)
|
||||
{
|
||||
file_transfering = true;
|
||||
bytes_to_download = 100;
|
||||
bytes_to_download = header.pkg_content_size;
|
||||
bytes_transfered = 0;
|
||||
sceRtcGetCurrentTick(&prev_tick);
|
||||
|
||||
while (!completed)
|
||||
{
|
||||
memset(&progress_info, 0, sizeof(progress_info));
|
||||
@@ -926,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;
|
||||
@@ -938,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);
|
||||
@@ -950,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;
|
||||
|
||||
+6
-4
@@ -1,5 +1,5 @@
|
||||
#ifndef __LANG_H__
|
||||
#define __LANG_H__
|
||||
#ifndef __EZ_LANG_H__
|
||||
#define __EZ_LANG_H__
|
||||
|
||||
#include "config.h"
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -0,0 +1,197 @@
|
||||
#include <stdio.h>
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
|
||||
#include "common.h"
|
||||
#include "mem_file.h"
|
||||
|
||||
MemFile::MemFile(const std::string &path, size_t block_size)
|
||||
{
|
||||
this->block_size = block_size;
|
||||
this->complete = false;
|
||||
sem_init(&this->block_ready, 0, 0);
|
||||
}
|
||||
|
||||
MemFile::~MemFile()
|
||||
{
|
||||
for (int i = 0; i < this->mem_blocks.size(); i++)
|
||||
{
|
||||
if (this->mem_blocks[i] != nullptr && this->mem_blocks[i]->status != MEM_BLOCK_STATUS_DELETED)
|
||||
{
|
||||
if (this->mem_blocks[i]->buf != nullptr)
|
||||
{
|
||||
free(this->mem_blocks[i]->buf);
|
||||
this->mem_blocks[i]->buf = nullptr;
|
||||
}
|
||||
free(this->mem_blocks[i]);
|
||||
}
|
||||
}
|
||||
sem_destroy(&this->block_ready);
|
||||
};
|
||||
|
||||
int MemFile::Open()
|
||||
{
|
||||
this->block_in_progress = NewBlock();
|
||||
this->block_in_progress->buf = malloc(block_size);
|
||||
|
||||
return (block_in_progress->buf == nullptr);
|
||||
}
|
||||
|
||||
size_t MemFile::Read(char *buf, size_t buf_size, size_t offset)
|
||||
{
|
||||
int first_block_num, block_num;
|
||||
size_t block_offset;
|
||||
size_t remaining;
|
||||
size_t bytes_read;
|
||||
size_t total_bytes_read;
|
||||
MemBlock *block;
|
||||
char *p;
|
||||
|
||||
first_block_num= offset / this->block_size;
|
||||
block_num = first_block_num;
|
||||
block_offset = offset % this->block_size;
|
||||
|
||||
while ((block_num >= this->mem_blocks.size() && !this->complete) ||
|
||||
(block_num < this->mem_blocks.size() && this->mem_blocks[block_num]->status == MEM_BLOCK_STATUS_NOT_EXISTS))
|
||||
{
|
||||
sem_wait(&this->block_ready);
|
||||
}
|
||||
|
||||
block = this->mem_blocks[block_num];
|
||||
if (block->status == MEM_BLOCK_STATUS_DELETED)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (block_offset > block->size - 1 && this->complete)
|
||||
{
|
||||
// requested offset is pass the end of split file
|
||||
return 0;
|
||||
}
|
||||
|
||||
remaining = buf_size;
|
||||
bool eof = false;
|
||||
total_bytes_read = 0;
|
||||
p = buf;
|
||||
|
||||
while (remaining > 0 && !eof)
|
||||
{
|
||||
uint8_t *src = (uint8_t*)block->buf;
|
||||
src += block_offset;
|
||||
bytes_read = block_size - block_offset;
|
||||
memcpy(p, src, bytes_read);
|
||||
|
||||
if (bytes_read == remaining)
|
||||
{
|
||||
p += bytes_read;
|
||||
total_bytes_read += bytes_read;
|
||||
}
|
||||
else
|
||||
{
|
||||
p += bytes_read;
|
||||
total_bytes_read += bytes_read;
|
||||
if (block->is_last)
|
||||
{
|
||||
eof = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
remaining -= bytes_read;
|
||||
|
||||
if (remaining == 0)
|
||||
continue;
|
||||
|
||||
block_num++;
|
||||
block_offset = 0;
|
||||
|
||||
while ((block_num > this->mem_blocks.size() - 1 && !this->complete) ||
|
||||
this->mem_blocks[block_num]->status == MEM_BLOCK_STATUS_NOT_EXISTS)
|
||||
{
|
||||
sem_wait(&this->block_ready);
|
||||
}
|
||||
|
||||
block = this->mem_blocks[block_num];
|
||||
}
|
||||
|
||||
// delete blocks before the first read offset block. Assumuption, that reads are always
|
||||
// forward and won't read previously already read blocks. For safety, keeping only current block and 2 previous blocks
|
||||
for (int j=0; j < first_block_num - 2; j++)
|
||||
{
|
||||
if (this->mem_blocks[j]->status == MEM_BLOCK_STATUS_CREATED)
|
||||
{
|
||||
if (this->mem_blocks[j]->buf != nullptr)
|
||||
{
|
||||
free(this->mem_blocks[j]->buf);
|
||||
this->mem_blocks[j]->buf = nullptr;
|
||||
}
|
||||
this->mem_blocks[j]->status = MEM_BLOCK_STATUS_DELETED;
|
||||
}
|
||||
}
|
||||
|
||||
return total_bytes_read;
|
||||
}
|
||||
|
||||
size_t MemFile::Write(char *buf, size_t buf_size)
|
||||
{
|
||||
size_t bytes_written;
|
||||
size_t block_space_remaining;
|
||||
size_t bytes_to_write;
|
||||
|
||||
char *p = buf;
|
||||
size_t total_bytes_written = 0;
|
||||
size_t remaining_to_write = buf_size;
|
||||
|
||||
while (remaining_to_write > 0)
|
||||
{
|
||||
block_space_remaining = this->block_size - block_in_progress->size;
|
||||
bytes_to_write = MIN(remaining_to_write, block_space_remaining);
|
||||
memcpy(block_in_progress->buf, p, bytes_to_write);
|
||||
bytes_written = bytes_to_write;
|
||||
block_in_progress->size += bytes_written;
|
||||
total_bytes_written += bytes_written;
|
||||
remaining_to_write -= bytes_written;
|
||||
block_space_remaining -= bytes_written;
|
||||
p += bytes_written;
|
||||
|
||||
// error if bytes_to_write != bytes_written
|
||||
if (bytes_written != bytes_to_write)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (block_space_remaining == 0)
|
||||
{
|
||||
block_in_progress->status = MEM_BLOCK_STATUS_CREATED;
|
||||
this->mem_blocks.push_back(block_in_progress);
|
||||
sem_post(&this->block_ready);
|
||||
|
||||
block_in_progress = NewBlock();
|
||||
}
|
||||
}
|
||||
|
||||
return total_bytes_written;
|
||||
}
|
||||
|
||||
int MemFile::Close()
|
||||
{
|
||||
block_in_progress->status = MEM_BLOCK_STATUS_CREATED;
|
||||
block_in_progress->is_last = true;
|
||||
this->mem_blocks.push_back(block_in_progress);
|
||||
this->complete = true;
|
||||
sem_post(&this->block_ready);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
MemBlock *MemFile::NewBlock()
|
||||
{
|
||||
MemBlock *block = (MemBlock *)malloc(sizeof(MemBlock));
|
||||
memset(block, 0, sizeof(MemBlock));
|
||||
|
||||
block->is_last = false;
|
||||
block->size = 0;
|
||||
block->buf = malloc(block_size);
|
||||
|
||||
return block;
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
#ifndef EZ_MEM_FILE_H
|
||||
#define EZ_MEM_FILE_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <mutex>
|
||||
#include <pthread.h>
|
||||
|
||||
enum MemBlockStatus
|
||||
{
|
||||
MEM_BLOCK_STATUS_NOT_EXISTS,
|
||||
MEM_BLOCK_STATUS_CREATED,
|
||||
MEM_BLOCK_STATUS_DELETED
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
size_t size;
|
||||
void* buf;
|
||||
bool is_last;
|
||||
MemBlockStatus status;
|
||||
} MemBlock;
|
||||
|
||||
class MemFile
|
||||
{
|
||||
public:
|
||||
MemFile(const std::string& path, size_t block_size);
|
||||
~MemFile();
|
||||
size_t Read(char* buf, size_t buf_size, size_t offset);
|
||||
size_t Write(char* buf, size_t buf_size);
|
||||
int Open();
|
||||
int Close();
|
||||
|
||||
private:
|
||||
std::vector<MemBlock*> mem_blocks;
|
||||
size_t write_offset;
|
||||
size_t block_size;
|
||||
int write_error;
|
||||
bool complete;
|
||||
MemBlock *block_in_progress;
|
||||
sem_t block_ready;
|
||||
|
||||
MemBlock *NewBlock();
|
||||
};
|
||||
|
||||
#endif
|
||||
+322
-170
@@ -8,6 +8,12 @@
|
||||
#include "clients/smbclient.h"
|
||||
#include "clients/ftpclient.h"
|
||||
#include "clients/nfsclient.h"
|
||||
#include "clients/webdav.h"
|
||||
#include "clients/apache.h"
|
||||
#include "clients/iis.h"
|
||||
#include "clients/nginx.h"
|
||||
#include "clients/npxserve.h"
|
||||
#include "clients/rclone.h"
|
||||
#include "filehost/filehost.h"
|
||||
#include "config.h"
|
||||
#include "fs.h"
|
||||
@@ -24,9 +30,18 @@
|
||||
#define SUCCESS_MSG "{ \"result\": { \"success\": true, \"error\": null } }"
|
||||
#define FAILURE_MSG "{ \"result\": { \"success\": false, \"error\": \"%s\" } }"
|
||||
#define SUCCESS_MSG_LEN 48
|
||||
#define PKG_INITIAL_REQUEST_SIZE 8388608ul
|
||||
|
||||
using namespace httplib;
|
||||
|
||||
struct RemoteDownloadData
|
||||
{
|
||||
RemoteClient *client = nullptr;
|
||||
std::map<std::string, void *> fp_handles;
|
||||
};
|
||||
|
||||
static RemoteDownloadData remote_data[100];
|
||||
|
||||
Server *svr;
|
||||
int http_server_port = 8080;
|
||||
char compressed_file_path[1024];
|
||||
@@ -91,22 +106,22 @@ namespace HttpServer
|
||||
return s;
|
||||
}
|
||||
|
||||
void failed(Response & res, int status, const std::string &msg)
|
||||
void failed(Response &res, int status, const std::string &msg)
|
||||
{
|
||||
res.status = status;
|
||||
char response_msg[msg.length()+strlen(FAILURE_MSG)+2];
|
||||
char response_msg[msg.length() + strlen(FAILURE_MSG) + 2];
|
||||
snprintf(response_msg, sizeof(response_msg), "{ \"result\": { \"success\": false, \"error\": \"%s\" } }", msg.c_str());
|
||||
res.set_content(response_msg, strlen(response_msg), "application/json");
|
||||
return;
|
||||
}
|
||||
|
||||
void bad_request(Response & res, const std::string &msg)
|
||||
void bad_request(Response &res, const std::string &msg)
|
||||
{
|
||||
failed(res, 200, msg);
|
||||
return;
|
||||
}
|
||||
|
||||
void success(Response & res)
|
||||
void success(Response &res)
|
||||
{
|
||||
res.status = 200;
|
||||
res.set_content(SUCCESS_MSG, SUCCESS_MSG_LEN, "application/json");
|
||||
@@ -182,15 +197,87 @@ namespace HttpServer
|
||||
return 1;
|
||||
}
|
||||
|
||||
static RemoteClient *GetRemoteClient(int site_idx, bool new_client)
|
||||
{
|
||||
RemoteClient *tmp_client;
|
||||
RemoteSettings *tmp_settings = &site_settings[sites[site_idx]];
|
||||
|
||||
if (!new_client)
|
||||
{
|
||||
tmp_client = remote_data[site_idx].client;
|
||||
if (tmp_client != nullptr)
|
||||
return tmp_client;
|
||||
}
|
||||
|
||||
if (tmp_settings->type == CLIENT_TYPE_SFTP)
|
||||
{
|
||||
tmp_client = new SFTPClient();
|
||||
}
|
||||
else if (tmp_settings->type == CLIENT_TYPE_SMB)
|
||||
{
|
||||
tmp_client = new SmbClient();
|
||||
}
|
||||
else if (tmp_settings->type == CLIENT_TYPE_FTP)
|
||||
{
|
||||
tmp_client = new FtpClient();
|
||||
}
|
||||
else if (tmp_settings->type == CLIENT_TYPE_NFS)
|
||||
{
|
||||
tmp_client = new NfsClient();
|
||||
}
|
||||
else if (tmp_settings->type == CLIENT_TYPE_WEBDAV)
|
||||
{
|
||||
tmp_client = new WebDAVClient();
|
||||
}
|
||||
else if (tmp_settings->type == CLIENT_TYPE_GOOGLE)
|
||||
{
|
||||
if (remoteclient != nullptr && remoteclient->clientType() == CLIENT_TYPE_GOOGLE)
|
||||
tmp_client = remoteclient;
|
||||
else
|
||||
tmp_client = new GDriveClient();
|
||||
tmp_client->Connect("", "", "");
|
||||
}
|
||||
else if (tmp_settings->type == CLIENT_TYPE_HTTP_SERVER)
|
||||
{
|
||||
if (strcmp(remote_settings->http_server_type, HTTP_SERVER_APACHE) == 0)
|
||||
tmp_client = new ApacheClient();
|
||||
else if (strcmp(remote_settings->http_server_type, HTTP_SERVER_MS_IIS) == 0)
|
||||
tmp_client = new IISClient();
|
||||
else if (strcmp(remote_settings->http_server_type, HTTP_SERVER_NGINX) == 0)
|
||||
tmp_client = new NginxClient();
|
||||
else if (strcmp(remote_settings->http_server_type, HTTP_SERVER_NPX_SERVE) == 0)
|
||||
tmp_client = new NpxServeClient();
|
||||
else if (strcmp(remote_settings->http_server_type, HTTP_SERVER_RCLONE) == 0)
|
||||
tmp_client = new RCloneClient();
|
||||
}
|
||||
|
||||
if (tmp_client->clientType() != CLIENT_TYPE_GOOGLE)
|
||||
tmp_client->Connect(tmp_settings->server, tmp_settings->username, tmp_settings->password);
|
||||
|
||||
if (!new_client && tmp_client->clientType() != CLIENT_TYPE_FTP)
|
||||
{
|
||||
remote_data[site_idx].client = tmp_client;
|
||||
}
|
||||
|
||||
return tmp_client;
|
||||
}
|
||||
|
||||
static void DeleteRemoteClient(RemoteClient *tmp_client, int site_idx)
|
||||
{
|
||||
if (tmp_client != nullptr && tmp_client->clientType() != CLIENT_TYPE_GOOGLE)
|
||||
{
|
||||
tmp_client->Quit();
|
||||
delete tmp_client;
|
||||
}
|
||||
}
|
||||
|
||||
void *ServerThread(void *argp)
|
||||
{
|
||||
svr->Get("/", [&](const Request & req, Response & res)
|
||||
{
|
||||
res.set_redirect("/index.html");
|
||||
});
|
||||
svr->Get("/", [&](const Request &req, Response &res)
|
||||
{ res.set_redirect("/index.html"); });
|
||||
|
||||
svr->Get("/index.html", [&](const Request & req, Response & res)
|
||||
{
|
||||
svr->Get("/index.html", [&](const Request &req, Response &res)
|
||||
{
|
||||
FILE *in = FS::OpenRead("/mnt/sandbox/pfsmnt/RMTC00001-app0/assets/index.html");
|
||||
size_t size = FS::GetSize("/mnt/sandbox/pfsmnt/RMTC00001-app0/assets/index.html");
|
||||
res.set_content_provider(
|
||||
@@ -206,11 +293,10 @@ namespace HttpServer
|
||||
},
|
||||
[in](bool success) {
|
||||
FS::Close(in);
|
||||
});
|
||||
});
|
||||
}); });
|
||||
|
||||
svr->Get("/favicon.ico", [&](const Request & req, Response & res)
|
||||
{
|
||||
svr->Get("/favicon.ico", [&](const Request &req, Response &res)
|
||||
{
|
||||
FILE *in = FS::OpenRead("/mnt/sandbox/pfsmnt/RMTC00001-app0/assets/favicon.ico");
|
||||
size_t size = FS::GetSize("/mnt/sandbox/pfsmnt/RMTC00001-app0/assets/favicon.ico");
|
||||
res.set_content_provider(
|
||||
@@ -226,11 +312,10 @@ namespace HttpServer
|
||||
},
|
||||
[in](bool success) {
|
||||
FS::Close(in);
|
||||
});
|
||||
});
|
||||
}); });
|
||||
|
||||
svr->Post("/__local__/list", [&](const Request & req, Response & res)
|
||||
{
|
||||
svr->Post("/__local__/list", [&](const Request &req, Response &res)
|
||||
{
|
||||
const char *path;
|
||||
bool onlyFolders = false;
|
||||
json_object *jobj = json_tokener_parse(req.body.c_str());
|
||||
@@ -276,11 +361,10 @@ namespace HttpServer
|
||||
json_object_object_add(results, "result", json_files);
|
||||
const char *results_str = json_object_to_json_string(results);
|
||||
res.status = 200;
|
||||
res.set_content(results_str, strlen(results_str), "application/json");
|
||||
});
|
||||
res.set_content(results_str, strlen(results_str), "application/json"); });
|
||||
|
||||
svr->Post("/__local__/rename", [&](const Request & req, Response & res)
|
||||
{
|
||||
svr->Post("/__local__/rename", [&](const Request &req, Response &res)
|
||||
{
|
||||
const char *item;
|
||||
const char *newItemPath;
|
||||
json_object *jobj = json_tokener_parse(req.body.c_str());
|
||||
@@ -302,11 +386,10 @@ namespace HttpServer
|
||||
|
||||
FS::Rename(item, newItemPath);
|
||||
success(res);
|
||||
return;
|
||||
});
|
||||
return; });
|
||||
|
||||
svr->Post("/__local__/move", [&](const Request & req, Response & res)
|
||||
{
|
||||
svr->Post("/__local__/move", [&](const Request &req, Response &res)
|
||||
{
|
||||
const json_object *items;
|
||||
const char *newPath;
|
||||
json_object *jobj = json_tokener_parse(req.body.c_str());
|
||||
@@ -357,11 +440,10 @@ namespace HttpServer
|
||||
failed(res, 200, error_msg);
|
||||
}
|
||||
else
|
||||
success(res);
|
||||
});
|
||||
success(res); });
|
||||
|
||||
svr->Post("/__local__/copy", [&](const Request & req, Response & res)
|
||||
{
|
||||
svr->Post("/__local__/copy", [&](const Request &req, Response &res)
|
||||
{
|
||||
const json_object *items;
|
||||
const char *newPath;
|
||||
const char *singleFilename;
|
||||
@@ -432,11 +514,10 @@ namespace HttpServer
|
||||
failed(res, 200, error_msg);
|
||||
}
|
||||
else
|
||||
success(res);
|
||||
});
|
||||
success(res); });
|
||||
|
||||
svr->Post("/__local__/remove", [&](const Request & req, Response & res)
|
||||
{
|
||||
svr->Post("/__local__/remove", [&](const Request &req, Response &res)
|
||||
{
|
||||
json_object *items;
|
||||
json_object *jobj = json_tokener_parse(req.body.c_str());
|
||||
if (jobj != nullptr)
|
||||
@@ -472,11 +553,10 @@ namespace HttpServer
|
||||
failed(res, 200, error_msg);
|
||||
}
|
||||
else
|
||||
success(res);
|
||||
});
|
||||
success(res); });
|
||||
|
||||
svr->Post("/__local__/install", [&](const Request & req, Response & res)
|
||||
{
|
||||
svr->Post("/__local__/install", [&](const Request &req, Response &res)
|
||||
{
|
||||
json_object *items;
|
||||
json_object *jobj = json_tokener_parse(req.body.c_str());
|
||||
if (jobj != nullptr)
|
||||
@@ -509,11 +589,10 @@ namespace HttpServer
|
||||
failed(res, 200, error_msg);
|
||||
}
|
||||
else
|
||||
success(res);
|
||||
});
|
||||
success(res); });
|
||||
|
||||
svr->Post("/__local__/edit", [&](const Request & req, Response & res)
|
||||
{
|
||||
svr->Post("/__local__/edit", [&](const Request &req, Response &res)
|
||||
{
|
||||
const char *item;
|
||||
const char *content;
|
||||
size_t content_len;
|
||||
@@ -543,11 +622,10 @@ namespace HttpServer
|
||||
return;
|
||||
}
|
||||
|
||||
success(res);
|
||||
});
|
||||
success(res); });
|
||||
|
||||
svr->Post("/__local__/getContent", [&](const Request & req, Response & res)
|
||||
{
|
||||
svr->Post("/__local__/getContent", [&](const Request &req, Response &res)
|
||||
{
|
||||
const char *item;
|
||||
json_object *jobj = json_tokener_parse(req.body.c_str());
|
||||
if (jobj != nullptr)
|
||||
@@ -570,11 +648,10 @@ namespace HttpServer
|
||||
json_object_object_add(result, "result", json_object_new_string(content.data()));
|
||||
const char *result_str = json_object_to_json_string(result);
|
||||
res.status = 200;
|
||||
res.set_content(result_str, strlen(result_str), "application/json");
|
||||
});
|
||||
res.set_content(result_str, strlen(result_str), "application/json"); });
|
||||
|
||||
svr->Post("/__local__/createFolder", [&](const Request & req, Response & res)
|
||||
{
|
||||
svr->Post("/__local__/createFolder", [&](const Request &req, Response &res)
|
||||
{
|
||||
const char *newPath;
|
||||
json_object *jobj = json_tokener_parse(req.body.c_str());
|
||||
if (jobj != nullptr)
|
||||
@@ -593,16 +670,13 @@ namespace HttpServer
|
||||
}
|
||||
|
||||
FS::MkDirs(newPath);
|
||||
success(res);
|
||||
});
|
||||
success(res); });
|
||||
|
||||
svr->Post("/__local__/permission", [&](const Request & req, Response & res)
|
||||
{
|
||||
failed(res, 200, "Operation not supported");
|
||||
});
|
||||
svr->Post("/__local__/permission", [&](const Request &req, Response &res)
|
||||
{ failed(res, 200, "Operation not supported"); });
|
||||
|
||||
svr->Post("/__local__/compress", [&](const Request & req, Response & res)
|
||||
{
|
||||
svr->Post("/__local__/compress", [&](const Request &req, Response &res)
|
||||
{
|
||||
json_object *items;
|
||||
const char* destination;
|
||||
const char* compressedFilename;
|
||||
@@ -652,11 +726,10 @@ namespace HttpServer
|
||||
else
|
||||
{
|
||||
failed(res, 200, "Failed to create zip");
|
||||
}
|
||||
});
|
||||
} });
|
||||
|
||||
svr->Post("/__local__/extract", [&](const Request & req, Response & res)
|
||||
{
|
||||
svr->Post("/__local__/extract", [&](const Request &req, Response &res)
|
||||
{
|
||||
const char* item;
|
||||
const char* destination;
|
||||
const char* folderName;
|
||||
@@ -692,11 +765,10 @@ namespace HttpServer
|
||||
else if (ret == -1)
|
||||
failed(res, 200, "Unsupported compressed file format");
|
||||
else
|
||||
success(res);
|
||||
});
|
||||
success(res); });
|
||||
|
||||
svr->Get("/__local__/uploadResumeSize", [&](const Request &req, Response &res)
|
||||
{
|
||||
{
|
||||
std::string destination = req.get_param_value("destination");
|
||||
std::string filename = req.get_param_value("filename");
|
||||
std::string file_path = destination + "/" + filename;
|
||||
@@ -705,11 +777,10 @@ namespace HttpServer
|
||||
size = FS::GetSize(file_path);
|
||||
std::string result_str = "{\"size\":" + std::to_string(size) + "}";
|
||||
res.status = 200;
|
||||
res.set_content(result_str.c_str(), result_str.length(), "application/json");
|
||||
});
|
||||
res.set_content(result_str.c_str(), result_str.length(), "application/json"); });
|
||||
|
||||
svr->Post("/__local__/upload", [&](const Request &req, Response &res, const ContentReader &content_reader)
|
||||
{
|
||||
{
|
||||
MultipartFormDataItems items;
|
||||
std::string destination;
|
||||
size_t chunk_size = 0;
|
||||
@@ -775,12 +846,11 @@ namespace HttpServer
|
||||
{
|
||||
FS::Close(out);
|
||||
}
|
||||
success(res);
|
||||
});
|
||||
success(res); });
|
||||
|
||||
// Download multiple files as ZIP
|
||||
svr->Get("/__local__/downloadMultiple", [&](const Request & req, Response & res)
|
||||
{
|
||||
svr->Get("/__local__/downloadMultiple", [&](const Request &req, Response &res)
|
||||
{
|
||||
if (req.get_param_value_count("items") == 0 || req.get_param_value_count("toFilename") == 0)
|
||||
{
|
||||
failed(res, 200, "Required items and toFilename parameter missing");
|
||||
@@ -834,12 +904,11 @@ namespace HttpServer
|
||||
else
|
||||
{
|
||||
failed(res, 200, "Failed to create zip");
|
||||
}
|
||||
});
|
||||
} });
|
||||
|
||||
// Download single file
|
||||
svr->Get("/__local__/downloadFile", [&](const Request & req, Response & res)
|
||||
{
|
||||
svr->Get("/__local__/downloadFile", [&](const Request &req, Response &res)
|
||||
{
|
||||
std::string path = req.get_param_value("path", 0);
|
||||
if (path.empty())
|
||||
{
|
||||
@@ -869,11 +938,10 @@ namespace HttpServer
|
||||
},
|
||||
[in](bool success) {
|
||||
FS::Close(in);
|
||||
});
|
||||
});
|
||||
}); });
|
||||
|
||||
svr->Get("/google_auth", [](const Request &req, Response &res)
|
||||
{
|
||||
{
|
||||
std::string auth_code = req.get_param_value("code");
|
||||
Client client(GOOGLE_OAUTH_HOST);
|
||||
client.set_follow_location(true);
|
||||
@@ -919,12 +987,11 @@ namespace HttpServer
|
||||
}
|
||||
login_state = -1;
|
||||
std::string str = std::string(lang_strings[STR_FAIL_GET_TOKEN_MSG]) + " Google";
|
||||
res.set_content(str.c_str(), "text/plain");
|
||||
});
|
||||
res.set_content(str.c_str(), "text/plain"); });
|
||||
|
||||
svr->Get("/rmt_inst/Site (\\d+)(/)(.*)", [&](const Request & req, Response & res)
|
||||
{
|
||||
RemoteClient *tmp_client;
|
||||
svr->Get("/rmt_inst/Site (\\d+)(/)(.*)", [&](const Request &req, Response &res)
|
||||
{
|
||||
RemoteClient *tmp_client = nullptr;
|
||||
RemoteSettings *tmp_settings;
|
||||
auto site_idx = std::stoi(req.matches[1])-1;
|
||||
std::string path;
|
||||
@@ -932,33 +999,6 @@ namespace HttpServer
|
||||
if (site_idx != 98)
|
||||
{
|
||||
path = std::string("/") + std::string(req.matches[3]);
|
||||
|
||||
tmp_settings = &site_settings[sites[site_idx]];
|
||||
|
||||
if (tmp_settings->type == CLIENT_TYPE_SFTP)
|
||||
{
|
||||
tmp_client = new SFTPClient();
|
||||
tmp_client->Connect(tmp_settings->server, tmp_settings->username, tmp_settings->password);
|
||||
}
|
||||
else if (tmp_settings->type == CLIENT_TYPE_SMB)
|
||||
{
|
||||
tmp_client = new SmbClient();
|
||||
tmp_client->Connect(tmp_settings->server, tmp_settings->username, tmp_settings->password);
|
||||
}
|
||||
else if (tmp_settings->type == CLIENT_TYPE_FTP)
|
||||
{
|
||||
tmp_client = new FtpClient();
|
||||
tmp_client->Connect(tmp_settings->server, tmp_settings->username, tmp_settings->password);
|
||||
}
|
||||
else if (tmp_settings->type == CLIENT_TYPE_NFS)
|
||||
{
|
||||
tmp_client = new NfsClient();
|
||||
tmp_client->Connect(tmp_settings->server, tmp_settings->username, tmp_settings->password);
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp_client = remoteclient;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -973,33 +1013,34 @@ namespace HttpServer
|
||||
tmp_client->Connect(host, "", "");
|
||||
}
|
||||
|
||||
if (tmp_client == nullptr || !tmp_client->IsConnected())
|
||||
{
|
||||
res.status = 404;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (req.method == "HEAD")
|
||||
{
|
||||
int64_t file_size;
|
||||
int ret;
|
||||
if (site_idx != 98)
|
||||
tmp_client = GetRemoteClient(site_idx, true);
|
||||
|
||||
ret = tmp_client->Size(path, &file_size);
|
||||
if (!ret)
|
||||
{
|
||||
res.status = 500;
|
||||
DeleteRemoteClient(tmp_client, site_idx);
|
||||
return;
|
||||
}
|
||||
|
||||
res.status = 204;
|
||||
res.set_header("Content-Length", std::to_string(file_size));
|
||||
res.set_header("Accept-Ranges", "bytes");
|
||||
DeleteRemoteClient(tmp_client, site_idx);
|
||||
return;
|
||||
}
|
||||
|
||||
if (req.ranges.empty())
|
||||
{
|
||||
res.status = 200;
|
||||
if (site_idx != 98)
|
||||
tmp_client = GetRemoteClient(site_idx, true);
|
||||
|
||||
res.set_content_provider(
|
||||
(1024*128), "application/octet-stream",
|
||||
[tmp_client, path](size_t offset, size_t length, DataSink &sink) {
|
||||
@@ -1007,15 +1048,7 @@ namespace HttpServer
|
||||
return (ret == 1);
|
||||
},
|
||||
[tmp_client, path, site_idx](bool success) {
|
||||
if (tmp_client != nullptr && (tmp_client->clientType() == CLIENT_TYPE_SFTP
|
||||
|| tmp_client->clientType() == CLIENT_TYPE_SMB
|
||||
|| tmp_client->clientType() == CLIENT_TYPE_FTP
|
||||
|| tmp_client->clientType() == CLIENT_TYPE_NFS
|
||||
|| (tmp_client->clientType() == CLIENT_TYPE_HTTP_SERVER && site_idx == 98)))
|
||||
{
|
||||
tmp_client->Quit();
|
||||
delete tmp_client;
|
||||
}
|
||||
DeleteRemoteClient(tmp_client, site_idx);
|
||||
});
|
||||
}
|
||||
else
|
||||
@@ -1024,33 +1057,61 @@ namespace HttpServer
|
||||
size_t range_len = (req.ranges[0].second - req.ranges[0].first) + 1;
|
||||
if (req.ranges[0].second >= 18000000000000000000ul)
|
||||
{
|
||||
range_len = 524288ul;
|
||||
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+524288ul-1) + "/"+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);
|
||||
if (site_idx != 98)
|
||||
tmp_client = GetRemoteClient(site_idx, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (site_idx != 98)
|
||||
tmp_client = GetRemoteClient(site_idx, false);
|
||||
}
|
||||
|
||||
std::pair<ssize_t, ssize_t> range = req.ranges[0];
|
||||
res.set_content_provider(
|
||||
range_len, "application/octet-stream",
|
||||
[tmp_client, path, range, range_len](size_t offset, size_t length, DataSink &sink) {
|
||||
int ret = tmp_client->GetRange(path, sink, range_len, range.first);
|
||||
return (ret == 1);
|
||||
},
|
||||
[tmp_client, site_idx, path, range, range_len](bool success) {
|
||||
if (tmp_client != nullptr && (tmp_client->clientType() == CLIENT_TYPE_SFTP
|
||||
|| tmp_client->clientType() == CLIENT_TYPE_SMB
|
||||
|| tmp_client->clientType() == CLIENT_TYPE_FTP
|
||||
|| tmp_client->clientType() == CLIENT_TYPE_NFS
|
||||
|| (tmp_client->clientType() == CLIENT_TYPE_HTTP_SERVER && site_idx == 98)))
|
||||
[tmp_client, path, range, range_len, site_idx](size_t offset, size_t length, DataSink &sink) {
|
||||
int ret;
|
||||
if (range_len == PKG_INITIAL_REQUEST_SIZE)
|
||||
{
|
||||
tmp_client->Quit();
|
||||
delete tmp_client;
|
||||
ret = tmp_client->GetRange(path, sink, range_len, range.first);
|
||||
}
|
||||
else if ((tmp_client->SupportedActions() & REMOTE_ACTION_RAW_READ) == 0)
|
||||
{
|
||||
ret = tmp_client->GetRange(path, sink, range_len, range.first);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::map<std::string, void *>::iterator it = remote_data[site_idx].fp_handles.find(path);
|
||||
void *fp;
|
||||
if (it == remote_data[site_idx].fp_handles.end())
|
||||
{
|
||||
fp = tmp_client->Open(path, O_RDONLY);
|
||||
remote_data[site_idx].fp_handles[path] = fp;
|
||||
}
|
||||
else
|
||||
{
|
||||
fp = it->second;
|
||||
}
|
||||
ret = tmp_client->GetRange(fp, sink, range_len, range.first);
|
||||
}
|
||||
return (ret==1);
|
||||
},
|
||||
[tmp_client, path, range, site_idx](bool success) {
|
||||
if (range.second >= 18000000000000000000ul ||
|
||||
(tmp_client->clientType() == CLIENT_TYPE_HTTP_SERVER && site_idx == 98) ||
|
||||
tmp_client->clientType() == CLIENT_TYPE_FTP)
|
||||
{
|
||||
DeleteRemoteClient(tmp_client, site_idx);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
} });
|
||||
|
||||
svr->Get("/archive_inst/(.*)", [&](const Request & req, Response & res)
|
||||
{
|
||||
svr->Get("/archive_inst/(.*)", [&](const Request &req, Response &res)
|
||||
{
|
||||
RemoteClient *tmp_client;
|
||||
RemoteSettings *tmp_settings;
|
||||
std::string hash = req.matches[1];
|
||||
@@ -1087,9 +1148,10 @@ namespace HttpServer
|
||||
size_t range_len = (req.ranges[0].second - req.ranges[0].first) + 1;
|
||||
if (req.ranges[0].second >= 18000000000000000000ul)
|
||||
{
|
||||
range_len = 524288ul;
|
||||
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+524288ul-1) + "/"+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(
|
||||
@@ -1104,15 +1166,71 @@ namespace HttpServer
|
||||
[](bool success) {
|
||||
return true;
|
||||
});
|
||||
}
|
||||
});
|
||||
} });
|
||||
|
||||
svr->Post("/__local__/install_url", [&](const Request & req, Response & res)
|
||||
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)
|
||||
@@ -1120,6 +1238,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");
|
||||
@@ -1153,6 +1273,8 @@ namespace HttpServer
|
||||
file_transfering = true;
|
||||
bytes_to_download = 100;
|
||||
bytes_transfered = 0;
|
||||
sceRtcGetCurrentTick(&prev_tick);
|
||||
|
||||
Windows::SetModalMode(true);
|
||||
|
||||
std::string download_url = filehost->GetDownloadUrl();
|
||||
@@ -1164,7 +1286,6 @@ namespace HttpServer
|
||||
Windows::SetModalMode(true);
|
||||
return;
|
||||
}
|
||||
|
||||
delete(filehost);
|
||||
|
||||
size_t scheme_pos = download_url.find("://");
|
||||
@@ -1178,20 +1299,54 @@ 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;
|
||||
free(install_data);
|
||||
Windows::SetModalMode(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1218,6 +1373,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;
|
||||
}
|
||||
@@ -1231,21 +1387,17 @@ namespace HttpServer
|
||||
return;
|
||||
}
|
||||
}
|
||||
success(res);
|
||||
});
|
||||
success(res); });
|
||||
|
||||
svr->Get("/stop", [&](const Request & /*req*/, Response & /*res*/)
|
||||
{
|
||||
svr->stop();
|
||||
});
|
||||
{ svr->stop(); });
|
||||
|
||||
svr->set_error_handler([](const Request & /*req*/, Response &res)
|
||||
{
|
||||
{
|
||||
const char *fmt = "<p>Error Status: <span style='color:red;'>%d</span></p>";
|
||||
char buf[BUFSIZ];
|
||||
snprintf(buf, sizeof(buf), fmt, res.status);
|
||||
res.set_content(buf, "text/html");
|
||||
});
|
||||
res.set_content(buf, "text/html"); });
|
||||
|
||||
/*
|
||||
svr->set_logger([](const Request &req, const Response &res)
|
||||
@@ -1257,7 +1409,7 @@ namespace HttpServer
|
||||
svr->set_payload_max_length(1024 * 1024 * 12);
|
||||
svr->set_tcp_nodelay(true);
|
||||
svr->set_mount_point("/", "/");
|
||||
|
||||
|
||||
if (web_server_enabled)
|
||||
svr->listen("0.0.0.0", http_server_port);
|
||||
else
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef HTTP_SERVER_H
|
||||
#define HTTP_SERVER_H
|
||||
#ifndef EZ_HTTP_SERVER_H
|
||||
#define EZ_HTTP_SERVER_H
|
||||
|
||||
#include "http/httplib.h"
|
||||
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
#ifndef LAUNCHER_SFO_H
|
||||
#define LAUNCHER_SFO_H
|
||||
#ifndef EZ_SFO_H
|
||||
#define EZ_SFO_H
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
@@ -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));
|
||||
|
||||
+3
-2
@@ -1,5 +1,5 @@
|
||||
#ifndef SPLIT_FILE_H
|
||||
#define SPLIT_FILE_H
|
||||
#ifndef EZ_SPLIT_FILE_H
|
||||
#define EZ_SPLIT_FILE_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -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;
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
#ifndef EZ_SYSTEM_H
|
||||
#define EZ_SYSTEM_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -42,3 +45,5 @@ void convertLocalTimeToUtc(const OrbisDateTime *local_time, OrbisDateTime *utc);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
#ifndef LAUNCHER_TEXTURES_H
|
||||
#define LAUNCHER_TEXTURES_H
|
||||
#ifndef EZ_TEXTURES_H
|
||||
#define EZ_TEXTURES_H
|
||||
|
||||
#include <string>
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
+83
-2
@@ -14,10 +14,11 @@
|
||||
#include "util.h"
|
||||
#include "lang.h"
|
||||
#include "ime_dialog.h"
|
||||
#include "IconsFontAwesome6.h"
|
||||
#include "IconsFontAwesome6.h"
|
||||
#include "OpenFontIcons.h"
|
||||
#include "textures.h"
|
||||
#include "sfo.h"
|
||||
#include "system.h"
|
||||
|
||||
#define MAX_IMAGE_HEIGHT 980
|
||||
#define MAX_IMAGE_WIDTH 1820
|
||||
@@ -30,6 +31,9 @@ extern "C"
|
||||
bool paused = false;
|
||||
int view_mode;
|
||||
static float scroll_direction = 0.0f;
|
||||
static int selected_local_position = -1;
|
||||
static int selected_remote_position = -1;
|
||||
|
||||
static ime_callback_t ime_callback = nullptr;
|
||||
static ime_callback_t ime_after_update = nullptr;
|
||||
static ime_callback_t ime_before_update = nullptr;
|
||||
@@ -43,6 +47,8 @@ static char txt_http_server_port[6];
|
||||
bool handle_updates = false;
|
||||
int64_t bytes_transfered;
|
||||
int64_t bytes_to_download;
|
||||
OrbisTick prev_tick;
|
||||
|
||||
std::vector<DirEntry> local_files;
|
||||
std::vector<DirEntry> remote_files;
|
||||
std::set<DirEntry> multi_selected_local_files;
|
||||
@@ -449,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(450, 70));
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + 440);
|
||||
ImGui::Text("%s", lang_strings[STR_ENABLE_DISC_CACHE_MSG]);
|
||||
ImGui::PopTextWrapPos();
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
|
||||
ImGui::PopStyleVar();
|
||||
|
||||
ImGui::SameLine();
|
||||
@@ -614,6 +640,22 @@ namespace Windows
|
||||
ImGui::Text("%s", item.name);
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
if (ImGui::IsKeyPressed(ImGuiKey_GamepadDpadUp) && !paused)
|
||||
{
|
||||
if (j == 0)
|
||||
{
|
||||
selected_local_position = local_files.size()-1;
|
||||
scroll_direction = 0.0f;
|
||||
}
|
||||
}
|
||||
else if (ImGui::IsKeyPressed(ImGuiKey_GamepadDpadDown) && !paused)
|
||||
{
|
||||
if (j == local_files.size()-1)
|
||||
{
|
||||
selected_local_position = 0;
|
||||
scroll_direction = 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows))
|
||||
{
|
||||
@@ -623,6 +665,12 @@ namespace Windows
|
||||
ImGui::SetScrollHereY(0.5f);
|
||||
sprintf(local_file_to_select, "");
|
||||
}
|
||||
if (selected_local_position == j && !paused)
|
||||
{
|
||||
SetNavFocusHere();
|
||||
ImGui::SetScrollHereY(scroll_direction);
|
||||
selected_local_position = -1;
|
||||
}
|
||||
selected_browser |= LOCAL_BROWSER;
|
||||
}
|
||||
ImGui::NextColumn();
|
||||
@@ -779,6 +827,22 @@ namespace Windows
|
||||
ImGui::Text("%s", item.name);
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
if (ImGui::IsKeyPressed(ImGuiKey_GamepadDpadUp) && !paused)
|
||||
{
|
||||
if (j == 0)
|
||||
{
|
||||
selected_remote_position = remote_files.size()-1;
|
||||
scroll_direction = 0.0f;
|
||||
}
|
||||
}
|
||||
else if (ImGui::IsKeyPressed(ImGuiKey_GamepadDpadDown) && !paused)
|
||||
{
|
||||
if (j == remote_files.size()-1)
|
||||
{
|
||||
selected_remote_position = 0;
|
||||
scroll_direction = 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGui::PopID();
|
||||
if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows))
|
||||
@@ -789,6 +853,12 @@ namespace Windows
|
||||
ImGui::SetScrollHereY(0.5f);
|
||||
sprintf(remote_file_to_select, "");
|
||||
}
|
||||
if (selected_remote_position == j && !paused)
|
||||
{
|
||||
SetNavFocusHere();
|
||||
ImGui::SetScrollHereY(scroll_direction);
|
||||
selected_remote_position = -1;
|
||||
}
|
||||
selected_browser |= REMOTE_BROWSER;
|
||||
}
|
||||
ImGui::NextColumn();
|
||||
@@ -1356,8 +1426,19 @@ namespace Windows
|
||||
if (file_transfering)
|
||||
{
|
||||
static float progress = 0.0f;
|
||||
static double transfer_speed = 0.0f;
|
||||
static char progress_text[32];
|
||||
static OrbisTick cur_tick;
|
||||
static double tick_delta;
|
||||
|
||||
sceRtcGetCurrentTick(&cur_tick);
|
||||
tick_delta = (cur_tick.mytick - prev_tick.mytick) * 1.0f / 1000000.0f;
|
||||
|
||||
progress = bytes_transfered * 1.0f / (float)bytes_to_download;
|
||||
ImGui::ProgressBar(progress, ImVec2(625, 0));
|
||||
transfer_speed = (bytes_transfered * 1.0f / tick_delta) / 1048576.0f;
|
||||
|
||||
sprintf(progress_text, "%.2f MB/s", transfer_speed);
|
||||
ImGui::ProgressBar(progress, ImVec2(625, 0), progress_text);
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
+4
-2
@@ -1,5 +1,5 @@
|
||||
#ifndef LAUNCHER_WINDOWS_H
|
||||
#define LAUNCHER_WINDOWS_H
|
||||
#ifndef EZ_WINDOWS_H
|
||||
#define EZ_WINDOWS_H
|
||||
|
||||
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||
#include <set>
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "imgui_internal.h"
|
||||
#include "common.h"
|
||||
#include "actions.h"
|
||||
#include "system.h"
|
||||
#include "SDL2/SDL.h"
|
||||
|
||||
#define LOCAL_BROWSER 1
|
||||
@@ -16,6 +17,7 @@ extern int view_mode;
|
||||
extern bool handle_updates;
|
||||
extern int64_t bytes_transfered;
|
||||
extern int64_t bytes_to_download;
|
||||
extern OrbisTick prev_tick;
|
||||
extern std::vector<DirEntry> local_files;
|
||||
extern std::vector<DirEntry> remote_files;
|
||||
extern std::set<DirEntry> multi_selected_local_files;
|
||||
|
||||
+71
-21
@@ -72,6 +72,8 @@ namespace ZipUtil
|
||||
convertToZipTime(file_stat.st_mtim.tv_sec, &zi.tmz_date);
|
||||
|
||||
bytes_transfered = 0;
|
||||
sceRtcGetCurrentTick(&prev_tick);
|
||||
|
||||
bytes_to_download = file_stat.st_size;
|
||||
|
||||
// Large file?
|
||||
@@ -288,8 +290,9 @@ 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);
|
||||
|
||||
/* loop over file contents and write to fd */
|
||||
for (int n = 0;; n++)
|
||||
@@ -309,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());
|
||||
@@ -451,6 +454,10 @@ namespace ZipUtil
|
||||
client->Size(file, &data->size);
|
||||
data->client = client;
|
||||
data->path = file;
|
||||
if (client->SupportedActions() & REMOTE_ACTION_RAW_READ)
|
||||
{
|
||||
data->fp = client->Open(file, O_RDONLY);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -468,7 +475,11 @@ namespace ZipUtil
|
||||
return 0;
|
||||
|
||||
to_read = MIN(to_read, ARCHIVE_TRANSFER_SIZE);
|
||||
ret = data->client->GetRange(data->path, data->buf, to_read, data->offset);
|
||||
if (data->client->SupportedActions() & REMOTE_ACTION_RAW_READ)
|
||||
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;
|
||||
@@ -479,10 +490,46 @@ namespace ZipUtil
|
||||
static int CloseRemoteArchive(struct archive *a, void *client_data)
|
||||
{
|
||||
if (client_data != nullptr)
|
||||
{
|
||||
RemoteArchiveData *data = (RemoteArchiveData *)client_data;
|
||||
if (data->client->SupportedActions() & REMOTE_ACTION_RAW_READ)
|
||||
data->client->Close(data->fp);
|
||||
free(client_data);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int64_t SeekRemoteArchive(struct archive *, void *client_data, int64_t offset, int whence)
|
||||
{
|
||||
RemoteArchiveData *data = (RemoteArchiveData *)client_data;
|
||||
|
||||
if (whence == SEEK_SET)
|
||||
{
|
||||
data->offset = offset;
|
||||
}
|
||||
else if (whence == SEEK_CUR)
|
||||
{
|
||||
data->offset = data->offset + offset - 1;
|
||||
}
|
||||
else if (whence == SEEK_END)
|
||||
{
|
||||
data->offset = data->size - 1;
|
||||
}
|
||||
else
|
||||
return ARCHIVE_FATAL;
|
||||
|
||||
return data->offset;
|
||||
}
|
||||
|
||||
int64_t SkipRemoteArchive(struct archive *, void *client_data, int64_t request)
|
||||
{
|
||||
RemoteArchiveData *data = (RemoteArchiveData *)client_data;
|
||||
|
||||
data->offset = data->offset + request - 1;
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
/*
|
||||
* Main loop: open the zipfile, iterate over its contents and decide what
|
||||
* to do with each entry.
|
||||
@@ -520,13 +567,16 @@ namespace ZipUtil
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = archive_read_open(a, client_data, NULL, ReadRemoteArchive, CloseRemoteArchive);
|
||||
ret = archive_read_set_seek_callback(a, SeekRemoteArchive);
|
||||
if (ret < ARCHIVE_OK)
|
||||
{
|
||||
sprintf(status_message, "archive_read_set_seek_callback failed - %s", archive_error_string(a));
|
||||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -568,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);
|
||||
@@ -592,13 +645,16 @@ namespace ZipUtil
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ret = archive_read_open(a, client_data, NULL, ReadRemoteArchive, CloseRemoteArchive);
|
||||
ret = archive_read_set_seek_callback(a, SeekRemoteArchive);
|
||||
if (ret < ARCHIVE_OK)
|
||||
{
|
||||
sprintf(status_message, "archive_read_set_seek_callback failed - %s", archive_error_string(a));
|
||||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -611,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)
|
||||
{
|
||||
@@ -689,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;
|
||||
}
|
||||
|
||||
+4
-3
@@ -1,5 +1,5 @@
|
||||
#ifndef ZIP_UTIL_H
|
||||
#define ZIP_UTIL_H
|
||||
#ifndef EZ_ZIP_UTIL_H
|
||||
#define EZ_ZIP_UTIL_H
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
@@ -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};
|
||||
@@ -30,6 +30,7 @@ enum CompressFileType {
|
||||
|
||||
struct RemoteArchiveData
|
||||
{
|
||||
void *fp;
|
||||
std::string path;
|
||||
ssize_t size;
|
||||
ssize_t offset;
|
||||
|
||||
Reference in New Issue
Block a user