Compare commits

...

11 Commits

Author SHA1 Message Date
cy33hc d34df2cf94 Update README.md 2023-03-14 11:59:03 -07:00
Chee Yee f6cf00974b changed RPI install message 2023-03-13 22:35:03 -07:00
Chee Yee 9788b7e963 disable upload if remote server does not support it 2023-03-13 22:24:20 -07:00
Chee Yee aa9ef34991 some bug fixes related to RPI and add option to show hidden files 2023-03-13 22:07:57 -07:00
Chee Yee fc96b76260 fix for bug #7 2023-03-13 19:39:14 -07:00
Chee Yee c54fc8fcbc Merge branch 'master' of github.com:cy33hc/ps4-ezremote-client 2023-03-13 04:56:12 -07:00
Chee Yee 5ca56b47df add copy/paste function in text editor 2023-03-13 04:56:04 -07:00
cy33hc 05d253edd8 Update README.md 2023-03-11 18:36:16 -08:00
cy33hc d752dd8fed Update README.md 2023-03-11 18:35:08 -08:00
cy33hc 45320ed2ca Update README.md 2023-03-10 23:30:36 -08:00
cy33hc 8aef5d0233 Update README.md 2023-03-10 21:08:40 -08:00
16 changed files with 97 additions and 37 deletions
+1 -1
View File
@@ -58,7 +58,7 @@ add_executable(ezremote_client
add_self(ezremote_client)
add_pkg(ezremote_client ${CMAKE_SOURCE_DIR}/data "RMTC00001" "ezRemote Client" "01.04" 32 0)
add_pkg(ezremote_client ${CMAKE_SOURCE_DIR}/data "RMTC00001" "ezRemote Client" "01.05" 32 0)
target_link_libraries(ezremote_client
c
+6 -2
View File
@@ -13,7 +13,7 @@ To distinguish between FTP, SMB, WebDAV or HTTP, the URL must be prefix with **f
- hostname can be the textual hostname or an IP address. hostname is required
- port is optional and defaults to 21(ftp) and 22(sftp) if not provided
```
For Secure FTP (sftp), use of identity files is possible. Put both the **id_rsa** and **id_rsa.pub** into a folder in the PS4 hard drive. Then in the password field in the UI, instead of putting a password reference the folder where id_rsa and id_rsa.pub is place. Prefix the folder with **"file://"**
For Secure FTP (sftp), use of identity files is possible. Put both the **id_rsa** and **id_rsa.pub** into a folder in the PS4 hard drive. Then in the password field in the UI, instead of putting a password reference the folder where id_rsa and id_rsa.pub is place. Prefix the folder with **"file://"** and **do not** password protect the identity file.
```
Example: If you had placed the id_rsa and id_rsa.pub files into the folder /data/ezremote-client,
then in the password field enter file:///data/ezremote-client
@@ -72,7 +72,7 @@ Remote Package Installation only works if the WebDAV server allow anonymous acce
- Create Zip files on PS4 local drive or usb drive
- Extract from zip, 7zip and rar files
- File management function include cut/copy/paste/rename/delete/new folder/file for files on PS4 local drive or usb or WebDAV Server.
- Simple Text Editor to make simply changes to config text files.
- Simple Text Editor to make simply changes to config text files. Limited to edit files over 32kb and limited to edit lines up to 1023 characters. If you try edit lines longer then 1023 characters, it will be truncated.
## Installation
@@ -172,12 +172,16 @@ Build and install libsmb2 - https://github.com/cy33hc/libsmb2/blob/ps4/README_PS
Build and install lexbor - https://github.com/lexbor/lexbor.git
Build and install libssh2 - https://www.libssh2.org/
Build libjbc - https://github.com/cy33hc/ps4-libjbc/blob/master/README_PS4.md
Build libunrar - https://github.com/cy33hc/libunrar-ps3
Build libun7zip - https://github.com/cy33hc/libun7zip
Build libjson-c - https://github.com/json-c/json-c
I have included the source code from the following 2 projects embedded into this repo.
<br/>https://github.com/yhirose/cpp-httplib
<br/>https://github.com/CloudPolis/webdav-client-cpp
Binary file not shown.
+5 -2
View File
@@ -107,9 +107,9 @@ STR_CANT_COPY_TO_SUBDIR_MSG=Cannot copy parent directory to sub subdirectory
STR_UNSUPPORTED_OPERATION_MSG=Operation not supported
STR_HTTP_PORT=Http Port
STR_REINSTALL_CONFIRM_MSG=The content has already been installed. Do you want to continue installing
STR_REMOTE_NOT_SUPPORT_MSG=Remote server requires at least a username.
STR_REMOTE_NOT_SUPPORT_MSG=Remote package installation is not supported for protected servers.
STR_CANNOT_CONNECT_REMOTE_MSG=Remote HTTP Server not reachable.
STR_DOWNLOAD_INSTALL_MSG=Remote Package Install not possible. Would you like to download package and install?
STR_DOWNLOAD_INSTALL_MSG=Remote Package Install not possible. Would you like to download package and install instead?
STR_CHECKING_REMOTE_SERVER_MSG=Checking remote server for Remote Package Install.
STR_ENABLE_RPI=RPI
STR_ENABLE_RPI_FTP_SMB_MSG=This option enables Remote Package Installation. This requires a HTTP Server setup on the same host sharing the same folder with anonymous access.
@@ -136,3 +136,6 @@ STR_CLIENT_ID=Client ID
STR_CLIENT_SECRET=Client Secret
STR_GLOBAL=Global
STR_GOOGLE=Google
STR_COPY_LINE=Copy selected line
STR_PASTE_LINE=Paste into selected line
STR_SHOW_HIDDEN_FILES=Show hidden files
+4
View File
@@ -0,0 +1,4 @@
#pragma once
#define ICON_OF_SQUARE "\xee\x83\x8b" // U+E0CB
#define ICON_OF_TRIANGLE "\xee\x83\x9e" // U+E0CB
+2 -1
View File
@@ -81,9 +81,10 @@ std::vector<DirEntry> NginxClient::ListDir(const std::string &path)
tmp = std::string((const char *)value, value_len);
if (tmp.compare("a") == 0)
{
value = lxb_dom_node_text_content(node, &value_len);
value = lxb_dom_element_get_attribute(lxb_dom_interface_element(node), (const lxb_char_t *)"href", 4, &value_len);
tmp = std::string((const char *)value, value_len);
tmp = Util::Rtrim(tmp, "/");
tmp = BaseClient::DecodeUrl(tmp);
if (tmp.compare("..") != 0)
{
sprintf(entry.directory, "%s", path.c_str());
+13 -10
View File
@@ -399,10 +399,10 @@ int SFTPClient::Move(const std::string &from, const std::string &to)
int SFTPClient::Head(const std::string &path, void *buffer, uint64_t len)
{
if (!Size(path.c_str(), &bytes_to_download))
{
return 0;
}
if (!Size(path.c_str(), &bytes_to_download))
{
return 0;
}
LIBSSH2_SFTP_HANDLE *sftp_handle = libssh2_sftp_open(sftp_session, path.c_str(), LIBSSH2_FXF_READ, 0);
if (!sftp_handle)
@@ -410,12 +410,12 @@ int SFTPClient::Head(const std::string &path, void *buffer, uint64_t len)
return 0;
}
int count = libssh2_sftp_read(sftp_handle, (char*)buffer, len);
libssh2_sftp_close(sftp_handle);
if (count != len)
return 0;
int count = libssh2_sftp_read(sftp_handle, (char *)buffer, len);
libssh2_sftp_close(sftp_handle);
if (count != len)
return 0;
return 1;
return 1;
}
bool SFTPClient::FileExists(const std::string &path)
@@ -455,6 +455,9 @@ std::vector<DirEntry> SFTPClient::ListDir(const std::string &path)
continue;
;
if (!show_hidden_files && new_path[0] == '.')
continue;
sprintf(entry.name, "%s", new_path.c_str());
sprintf(entry.directory, "%s", path.c_str());
if (path.length() > 0 && path[path.length() - 1] == '/')
@@ -493,7 +496,7 @@ std::vector<DirEntry> SFTPClient::ListDir(const std::string &path)
entry.selectable = false;
}
struct tm tm = *localtime((const time_t*)&attrs.mtime);
struct tm tm = *localtime((const time_t *)&attrs.mtime);
OrbisDateTime gmt;
OrbisDateTime lt;
+6 -1
View File
@@ -34,6 +34,7 @@ char favorite_urls[MAX_FAVORITE_URLS][512];
bool auto_delete_tmp_pkg;
int max_edit_file_size;
GoogleAppInfo gg_app;
bool show_hidden_files;
unsigned char cipher_key[32] = {'s', '5', 'v', '8', 'y', '/', 'B', '?', 'E', '(', 'H', '+', 'M', 'b', 'Q', 'e', 'T', 'h', 'W', 'm', 'Z', 'q', '4', 't', '7', 'w', '9', 'z', '$', 'C', '&', 'F'};
unsigned char cipher_iv[16] = {'Y', 'p', '3', 's', '6', 'v', '9', 'y', '$', 'B', '&', 'E', ')', 'H', '@', 'M'};
@@ -168,6 +169,9 @@ namespace CONFIG
max_edit_file_size = ReadInt(CONFIG_GLOBAL, CONFIG_MAX_EDIT_FILE_SIZE, MAX_EDIT_FILE_SIZE);
WriteInt(CONFIG_GLOBAL, CONFIG_MAX_EDIT_FILE_SIZE, max_edit_file_size);
show_hidden_files = ReadBool(CONFIG_GLOBAL, CONFIG_SHOW_HIDDEN_FILES, false);
WriteBool(CONFIG_GLOBAL, CONFIG_SHOW_HIDDEN_FILES, show_hidden_files);
// Load Google Account Info
sprintf(gg_app.client_id, "%s", ReadString(CONFIG_GOOGLE, CONFIG_GOOGLE_CLIENT_ID, ""));
WriteString(CONFIG_GOOGLE, CONFIG_GOOGLE_CLIENT_ID, gg_app.client_id);
@@ -306,7 +310,7 @@ namespace CONFIG
WriteBool(last_site, CONFIG_ENABLE_RPI, remote_settings->enable_rpi);
WriteString(last_site, CONFIG_REMOTE_HTTP_SERVER_TYPE, remote_settings->http_server_type);
WriteString(CONFIG_GLOBAL, CONFIG_LAST_SITE, last_site);
WriteBool(CONFIG_GLOBAL, CONFIG_AUTO_DELETE_TMP_PKG, auto_delete_tmp_pkg);
std::string encrypted_token;
if (strlen(remote_settings->gg_account.access_token) > 0)
Encrypt(remote_settings->gg_account.access_token, encrypted_token);
@@ -338,6 +342,7 @@ namespace CONFIG
WriteString(CONFIG_GOOGLE, CONFIG_GOOGLE_CLIENT_ID, gg_app.client_id);
WriteString(CONFIG_GOOGLE, CONFIG_GOOGLE_PERMISSIONS, gg_app.permissions);
WriteBool(CONFIG_GLOBAL, CONFIG_AUTO_DELETE_TMP_PKG, auto_delete_tmp_pkg);
WriteBool(CONFIG_GLOBAL, CONFIG_SHOW_HIDDEN_FILES, show_hidden_files);
WriteIniFile(CONFIG_INI_FILE);
CloseIniFile();
}
+3
View File
@@ -17,6 +17,8 @@
#define CONFIG_GLOBAL "Global"
#define CONFIG_SHOW_HIDDEN_FILES "show_hidden_files"
#define CONFIG_GOOGLE "Google"
#define CONFIG_GOOGLE_CLIENT_ID "google_client_id"
#define CONFIG_GOOGLE_CLIENT_SECRET "google_client_secret"
@@ -123,6 +125,7 @@ extern int max_edit_file_size;
extern unsigned char cipher_key[32];
extern unsigned char cipher_iv[16];
extern GoogleAppInfo gg_app;
extern bool show_hidden_files;
namespace CONFIG
{
+1 -1
View File
@@ -1200,7 +1200,7 @@ typedef ImBitArray<ImGuiKey_NamedKey_COUNT, -ImGuiKey_NamedKey_BEGIN> ImBitAr
#define ImGuiKey_NavGamepadTweakFast ImGuiKey_GamepadR1
#define ImGuiKey_NavGamepadActivate ImGuiKey_GamepadFaceDown
#define ImGuiKey_NavGamepadCancel ImGuiKey_GamepadFaceRight
#define ImGuiKey_NavGamepadMenu ImGuiKey_GamepadFaceLeft
#define ImGuiKey_NavGamepadMenu ImGuiKey_Keypad0
#define ImGuiKey_NavGamepadInput ImGuiKey_GamepadFaceUp
enum ImGuiInputEventType
+17 -10
View File
@@ -97,7 +97,7 @@ namespace INSTALLER
s_bgft_initialized = false;
}
std::string getRemoteUrl(const std::string filename)
std::string getRemoteUrl(const std::string filename, bool encodeUrl)
{
if (remoteclient->clientType() == CLIENT_TYPE_WEBDAV || remoteclient->clientType() == CLIENT_TYPE_HTTP_SERVER)
{
@@ -109,11 +109,14 @@ namespace INSTALLER
std::string host = full_url.substr(0, root_pos);
std::string path = full_url.substr(root_pos);
Web::Urn::Path uri(path);
CURL *curl = curl_easy_init();
path = uri.quote(curl);
curl_easy_cleanup(curl);
if (encodeUrl)
{
Web::Urn::Path uri(path);
CURL *curl = curl_easy_init();
path = uri.quote(curl);
curl_easy_cleanup(curl);
}
return host + path;
}
else
@@ -129,9 +132,12 @@ namespace INSTALLER
host = host.substr(0, port_pos);
std::string path = std::string(filename);
Web::Urn::Path uri(path);
CURL *curl = curl_easy_init();
path = uri.quote(curl);
if (encodeUrl)
{
Web::Urn::Path uri(path);
CURL *curl = curl_easy_init();
path = uri.quote(curl);
}
return "http://" + host + ":" + std::to_string(remote_settings->http_port) + path;
}
@@ -161,6 +167,7 @@ namespace INSTALLER
tmp_client.Connect(host.c_str(), "", "", false);
WebDAV::dict_t response_headers{};
int ret = tmp_client.GetHeaders(path.c_str(), &response_headers);
if (!ret)
{
sprintf(confirm_message, "%s %s", lang_strings[STR_CANNOT_CONNECT_REMOTE_MSG], lang_strings[STR_DOWNLOAD_INSTALL_MSG]);
@@ -173,7 +180,7 @@ namespace INSTALLER
int InstallRemotePkg(const std::string &filename, pkg_header *header)
{
std::string url = getRemoteUrl(filename);
std::string url = getRemoteUrl(filename, true);
if (url.empty())
return 0;
+1 -1
View File
@@ -111,7 +111,7 @@ namespace INSTALLER
void Exit(void);
bool canInstallRemotePkg(const std::string &url);
std::string getRemoteUrl(const std::string filename);
std::string getRemoteUrl(const std::string filename, bool encodeUrl=false);
int InstallRemotePkg(const std::string &filename, pkg_header *header);
int InstallLocalPkg(const std::string &filename, pkg_header *header, bool remove_after_install=false);
}
+4 -1
View File
@@ -119,7 +119,7 @@ char lang_strings[LANG_STRINGS_NUM][LANG_STR_SIZE] = {
"Operation not supported", // STR_UNSUPPORTED_OPERATION_MSG
"Http Port", // STR_HTTP_PORT
"The content has already been installed. Do you want to continue installing", // STR_REINSTALL_CONFIRM_MSG
"Remote server requires at least a username.", // STR_REMOTE_NOT_SUPPORT_MSG
"Remote package installation is not supported for protected servers.", // STR_REMOTE_NOT_SUPPORT_MSG
"Remote HTTP Server not reachable.", // STR_CANNOT_CONNECT_REMOTE_MSG
"Remote Package Install not possible. Would you like to download package and install?", // STR_DOWNLOAD_INSTALL_MSG
"Checking remote server for Remote Package Install.", // STR_CHECKING_REMOTE_SERVER_MSG
@@ -150,6 +150,9 @@ char lang_strings[LANG_STRINGS_NUM][LANG_STR_SIZE] = {
"Client Secret", // STR_CLIENT_SECRET
"Global", // STR_GLOBAL
"Google", // STR_GOOGLE
"Copy selected line", // STR_COPY_LINE
"Paste into selected line", // STR_PASTE_LINE
"Show hidden files", // STR_SHOW_HIDDEN_FILES
};
bool needs_extended_font = false;
+5 -2
View File
@@ -141,7 +141,10 @@
FUNC(STR_CLIENT_ID) \
FUNC(STR_CLIENT_SECRET) \
FUNC(STR_GLOBAL) \
FUNC(STR_GOOGLE)
FUNC(STR_GOOGLE) \
FUNC(STR_COPY_LINE) \
FUNC(STR_PASTE_LINE) \
FUNC(STR_SHOW_HIDDEN_FILES)
#define GET_VALUE(x) x,
#define GET_STRING(x) #x,
@@ -151,7 +154,7 @@ enum
FOREACH_STR(GET_VALUE)
};
#define LANG_STRINGS_NUM 138
#define LANG_STRINGS_NUM 141
#define LANG_ID_SIZE 64
#define LANG_STR_SIZE 384
extern char lang_identifiers[LANG_STRINGS_NUM][LANG_ID_SIZE];
+9 -3
View File
@@ -99,7 +99,7 @@ void InitImgui()
0,
};
static const ImWchar icons[] {
static const ImWchar fa_icons[] {
0xF07B, 0xF07B, // folder
0xF65E, 0xF65E, // new folder
0xF15B, 0xF15B, // file
@@ -127,6 +127,12 @@ void InitImgui()
0,
};
static const ImWchar of_icons[] {
0xE0CB, 0xE0CB, // square
0xE0DE, 0xE0DE, // triangle
0,
};
std::string lang = std::string(language);
int32_t lang_idx;
sceSystemServiceParamGetInt( ORBIS_SYSTEM_SERVICE_PARAM_ID_LANG, &lang_idx );
@@ -177,7 +183,8 @@ void InitImgui()
ImFontConfig config;
config.MergeMode = true;
config.GlyphMinAdvanceX = 13.0f; // Use if you want to make the icon monospaced
io.Fonts->AddFontFromFileTTF("/app0/assets/fonts/fa-solid-900.ttf", 20.0f, &config, icons);
io.Fonts->AddFontFromFileTTF("/app0/assets/fonts/fa-solid-900.ttf", 20.0f, &config, fa_icons);
io.Fonts->AddFontFromFileTTF("/app0/assets/fonts/OpenFontIcons.ttf", 20.0f, &config, of_icons);
io.Fonts->Flags |= ImFontAtlasFlags_NoPowerOfTwoHeight;
io.Fonts->Build();
@@ -307,7 +314,6 @@ int main()
ImGui_ImplSDL2_InitForSDLRenderer(window, renderer);
ImGui_ImplSDLRenderer_Init(renderer);
ImGui_ImplSDLRenderer_CreateFontsTexture();
ImGui_ImplSDL2_DisableButton(SDL_CONTROLLER_BUTTON_X, true);
if (!initialize_jbc())
{
+20 -2
View File
@@ -13,6 +13,7 @@
#include "lang.h"
#include "ime_dialog.h"
#include "IconsFontAwesome6.h"
#include "OpenFontIcons.h"
#include "server/http_server.h"
#include "clients/gdrive.h"
@@ -77,6 +78,7 @@ char label[256];
bool editor_modified = false;
char edit_file[256];
int edit_line_to_select = -1;
std::string copy_text;
// Overwrite dialog variables
bool dont_prompt_overwrite = false;
@@ -1057,7 +1059,7 @@ namespace Windows
ImGui::Separator();
flags = getSelectableFlag(REMOTE_ACTION_UPLOAD);
if (remote_browser_selected && remoteclient != nullptr && !(remoteclient->SupportedActions() & REMOTE_ACTION_UPLOAD))
if (local_browser_selected && remoteclient != nullptr && !(remoteclient->SupportedActions() & REMOTE_ACTION_UPLOAD))
{
flags = ImGuiSelectableFlags_Disabled;
}
@@ -1519,6 +1521,15 @@ namespace Windows
editor_modified = true;
edit_line_to_select = j;
}
else if (ImGui::IsKeyPressed(ImGuiKey_GamepadFaceLeft, false))
{
copy_text = std::string(it->c_str());
}
else if (ImGui::IsKeyPressed(ImGuiKey_GamepadFaceUp, false))
{
it->clear();
it->append(copy_text);
}
}
j++;
}
@@ -1534,7 +1545,8 @@ namespace Windows
ImGui::Text("%s%s", (editor_modified ? "**" : ""), edit_file);
ImGui::Separator();
ImGui::Text("L1 - %s R1 - %s", lang_strings[STR_DELETE_LINE], lang_strings[STR_INSERT_LINE]);
ImGui::Text("L1 - %s R1 - %s %s - %s %s - %s", lang_strings[STR_DELETE_LINE], lang_strings[STR_INSERT_LINE],
ICON_OF_SQUARE, lang_strings[STR_COPY_LINE], ICON_OF_TRIANGLE, lang_strings[STR_PASTE_LINE]);
ImGui::EndPopup();
}
}
@@ -1564,6 +1576,12 @@ namespace Windows
ImGui::SetCursorPosX(705);
ImGui::Checkbox("##auto_delete_tmp_pkg", &auto_delete_tmp_pkg);
ImGui::Separator();
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 15);
ImGui::Text("%s", lang_strings[STR_SHOW_HIDDEN_FILES]);
ImGui::SameLine();
ImGui::SetCursorPosX(705);
ImGui::Checkbox("##show_hidden_files", &show_hidden_files);
ImGui::Separator();
ImGui::TextColored(colors[ImGuiCol_ButtonHovered], "%s", lang_strings[STR_GOOGLE]);
ImGui::Separator();
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 15);