Compare commits

...

6 Commits

Author SHA1 Message Date
Chee Yee ed3e2c049b remove smb reference from nfs files 2023-04-13 00:31:50 -07:00
Chee Yee 5d5f22e61b update readme 2023-04-12 21:18:45 -07:00
Chee Yee dbf51d7a7c remove debug 2023-04-12 21:16:59 -07:00
Chee Yee 880ac0042f update readme 2023-04-12 01:17:07 -07:00
Chee Yee 21204b2b55 update readme 2023-04-12 01:05:25 -07:00
Chee Yee 10f3cafa1c add NFS support 2023-04-12 00:56:31 -07:00
11 changed files with 655 additions and 34 deletions
+3 -1
View File
@@ -35,6 +35,7 @@ add_executable(ezremote_client
source/clients/iis.cpp
source/clients/nginx.cpp
source/clients/npxserve.cpp
source/clients/nfsclient.cpp
source/clients/smbclient.cpp
source/clients/webdavclient.cpp
source/clients/sftpclient.cpp
@@ -60,7 +61,7 @@ add_executable(ezremote_client
add_self(ezremote_client)
add_pkg(ezremote_client ${CMAKE_SOURCE_DIR}/data "RMTC00001" "ezRemote Client" "01.06" 32 0)
add_pkg(ezremote_client ${CMAKE_SOURCE_DIR}/data "RMTC00001" "ezRemote Client" "01.07" 32 0)
target_link_libraries(ezremote_client
c
@@ -79,6 +80,7 @@ target_link_libraries(ezremote_client
curl
lexbor
smb2
nfs
minizip
un7zip
unrar
+28 -3
View File
@@ -1,9 +1,9 @@
# ezRemote Client
ezRemote Client is an application that allows you to connect the PS4 to remote FTP/SFTP, SMB, WebDAV, HTTP servers and Google Drive to transfer files. The interface is inspired by Filezilla client which provides a commander like GUI.
ezRemote Client is an application that allows you to connect the PS4 to remote FTP/SFTP, SMB, NFS, WebDAV, HTTP servers and Google Drive to transfer files. The interface is inspired by Filezilla client which provides a commander like GUI.
![Preview](/screenshot.jpg)
## Usage
To distinguish between FTP, SMB, WebDAV or HTTP, the URL must be prefix with **ftp://**, **sftp://**, **smb://**, **webdav://**, **webdavs://**, **http://** and **https://**
To distinguish between FTP, SMB, NFS, WebDAV or HTTP, the URL must be prefix with **ftp://**, **sftp://**, **smb://**, **nfs://**, **webdav://**, **webdavs://**, **http://** and **https://**
- The url format for FTP is
```
@@ -28,6 +28,29 @@ To distinguish between FTP, SMB, WebDAV or HTTP, the URL must be prefix with **f
- sharename is required
```
- The url format for NFS is
```
nfs://hostname[:port]/export_path[?arg=val[&arg=val]*]
- hostname can be the textual hostname or an IP address. hostname is required
- port is optional and defaults to 2049 if not provided
- export_path is required
Special characters in 'path' are escaped using %-hex-hex syntax.
For example '?' must be escaped if it occurs in a path as '?' is also used to
separate the path from the optional list of url arguments.
Example:
nfs://192.168.0.1/my?path?uid=1000&gid=1000
must be escaped as
nfs://192.168.0.1/my%3Fpath?uid=1000&gid=1000
Arguments supported are :
uid=<int> : UID value to use when talking to the server. Defaults to 65534 if not specified.
gid=<int> : GID value to use when talking to the server. Defaults to 65534 if not specified.
```
- The url format for WebDAV is
```
webdav://hostname[:port]/[url_path]
@@ -61,7 +84,7 @@ Tested with following WebDAV server:
Remote Package Installation only works if the WebDAV server allow anonymous access. It's a limitation of the PS4 Installer not able to access protected links. As suggested, use the [Dufs](https://github.com/sigoden/dufs) app for WebDAV.
## Features ##
- Transfer files back and forth between PS4 and FTP/SMB/WebDAV server
- Transfer files back and forth between PS4 and FTP/SMB/NFS/WebDAV server
- Support for connecting to Http Servers like (Apache/Nginx,Microsoft IIS, Serve) with html directory listings to download or install pkg.
- Install Remote Packages from connected WebDAV server
- Ability to connect to your "Google Drive" to transfer files back and fort. Can also install packages from it. The app will download the file to the PS4's harddrive and then install it. You need to keep the app opened. Here is a link to the wiki for what you need to do to make it work. Also able to access files that are shared to you. As of v1.06, Google Shared Drives from Google workspace is supported.
@@ -177,6 +200,8 @@ Build and install lexbor - https://github.com/lexbor/lexbor.git
Build and install libssh2 - https://www.libssh2.org/
Build and install libnfs - https://github.com/cy33hc/libnfs/tree/ps4
Build libjbc - https://github.com/cy33hc/ps4-libjbc/blob/master/README_PS4.md
Build libunrar - https://github.com/cy33hc/libunrar-ps3
+2
View File
@@ -143,3 +143,5 @@ STR_SET_DEFAULT_DIRECTORY=Set Default Folder
STR_SET_DEFAULT_DIRECTORY_MSG=has being set as default direcotry
STR_VIEW_IMAGE=View Image
STR_VIEW_PKG_INFO=Package Information
STR_NFS_EXP_PATH_MISSING_MSG=NFS export path missing in URL
STR_FAIL_INIT_NFS_CONTEXT=Failed to init NFS context
+5
View File
@@ -11,6 +11,7 @@
#include "clients/apache.h"
#include "clients/nginx.h"
#include "clients/npxserve.h"
#include "clients/nfsclient.h"
#include "clients/iis.h"
#include "clients/sftpclient.h"
#include "common.h"
@@ -1146,6 +1147,10 @@ namespace Actions
{
remoteclient = new SFTPClient();
}
else if (strncmp(remote_settings->server, "nfs://", 6) == 0)
{
remoteclient = new NfsClient();
}
else
{
sprintf(status_message, "%s", lang_strings[STR_PROTOCOL_NOT_SUPPORTED]);
+519
View File
@@ -0,0 +1,519 @@
#include <errno.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <arpa/inet.h>
#include <cstring>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <inttypes.h>
#include <errno.h>
#include <orbis/Net.h>
#include "fs.h"
#include "lang.h"
#include "clients/nfsclient.h"
#include "windows.h"
#include "util.h"
#include "system.h"
#define BUF_SIZE 64*1024
NfsClient::NfsClient()
{
}
NfsClient::~NfsClient()
{
}
int NfsClient::Connect(const std::string &url, const std::string &user, const std::string &pass)
{
nfs = nfs_init_context();
if (nfs == nullptr)
{
sprintf(response, "%s", lang_strings[STR_FAIL_INIT_NFS_CONTEXT]);
return 0;
}
struct nfs_url *nfsurl = nfs_parse_url_full(nfs, url.c_str());
if (nfsurl == nullptr) {
sprintf(response, "%s", nfs_get_error(nfs));
nfs_destroy_context(nfs);
return 0;
}
std::string export_path = std::string(nfsurl->path) + nfsurl->file;
int ret = nfs_mount(nfs, nfsurl->server, export_path.c_str());
if (ret != 0)
{
sprintf(response, "%s", nfs_get_error(nfs));
nfs_destroy_url(nfsurl);
nfs_destroy_context(nfs);
nfs = nullptr;
return 0;
}
nfs_destroy_url(nfsurl);
connected = true;
return 1;
}
/*
* LastResponse - return a pointer to the last response received
*/
const char *NfsClient::LastResponse()
{
return (const char *)response;
}
/*
* IsConnected - return true if connected to remote
*/
bool NfsClient::IsConnected()
{
return connected;
}
/*
* Ping - return true if connected to remote
*/
bool NfsClient::Ping()
{
return connected;
}
/*
* Quit - disconnect from remote
*
* return 1 if successful, 0 otherwise
*/
int NfsClient::Quit()
{
if (nfs != nullptr)
{
nfs_umount(nfs);
nfs_destroy_context(nfs);
nfs = nullptr;
}
connected = false;
return 1;
}
/*
* Mkdir - create a directory at server
*
* return 1 if successful, 0 otherwise
*/
int NfsClient::Mkdir(const std::string &ppath)
{
int ret = nfs_mkdir(nfs, ppath.c_str());
if (ret != 0)
{
sprintf(response, "%s", nfs_get_error(nfs));
return 0;
}
return 1;
}
/*
* Rmdir - remove directory and all files under directory at remote
*
* return 1 if successful, 0 otherwise
*/
int NfsClient::_Rmdir(const std::string &ppath)
{
int ret = nfs_rmdir(nfs, ppath.c_str());
if (ret != 0)
{
sprintf(response, "%s", nfs_get_error(nfs));
return 0;
}
return 1;
}
/*
* Rmdir - remove directory and all files under directory at remote
*
* return 1 if successful, 0 otherwise
*/
int NfsClient::Rmdir(const std::string &path, bool recursive)
{
if (stop_activity)
return 1;
std::vector<DirEntry> list = ListDir(path);
int ret;
for (int i = 0; i < list.size(); i++)
{
if (stop_activity)
return 1;
if (list[i].isDir && recursive)
{
if (strcmp(list[i].name, "..") == 0)
continue;
ret = Rmdir(list[i].path, recursive);
if (ret == 0)
{
sprintf(status_message, "%s %s", lang_strings[STR_FAIL_DEL_DIR_MSG], list[i].path);
return 0;
}
}
else
{
sprintf(activity_message, "%s %s\n", lang_strings[STR_DELETING], list[i].path);
ret = Delete(list[i].path);
if (ret == 0)
{
sprintf(status_message, "%s %s", lang_strings[STR_FAIL_DEL_FILE_MSG], list[i].path);
return 0;
}
}
}
ret = _Rmdir(path);
if (ret == 0)
{
sprintf(status_message, "%s %s", lang_strings[STR_FAIL_DEL_DIR_MSG], path.c_str());
return 0;
}
return 1;
}
/*
* Get - issue a GET command and write received data to output
*
* return 1 if successful, 0 otherwise
*/
int NfsClient::Get(const std::string &outputfile, const std::string &ppath, uint64_t offset)
{
if (!Size(ppath.c_str(), &bytes_to_download))
{
sprintf(response, "%s", nfs_get_error(nfs));
return 0;
}
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;
}
FILE* out = FS::Create(outputfile);
if (out == NULL)
{
sprintf(response, "%s", lang_strings[STR_FAILED]);
return 0;
}
void *buff = malloc(BUF_SIZE);
int count = 0;
bytes_transfered = 0;
while ((count = nfs_read(nfs, nfsfh, BUF_SIZE, buff)) > 0)
{
if (count < 0)
{
sprintf(response, "%s", nfs_get_error(nfs));
FS::Close(out);
nfs_close(nfs, nfsfh);
free((void*)buff);
return 0;
}
FS::Write(out, buff, count);
bytes_transfered += count;
}
FS::Close(out);
nfs_close(nfs, nfsfh);
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)
{
sprintf(response, "%s", nfs_get_error(nfs));
return 0;
}
ret = nfs_lseek(nfs, nfsfh, offset, SEEK_SET, NULL);
if (ret != 0)
{
sprintf(response, "%s", nfs_get_error(nfs));
return 0;
}
int count = nfs_read(nfs, nfsfh, size, buffer);
nfs_close(nfs, nfsfh);
if (count != size)
return 0;
return 1;
}
int NfsClient::Copy(const std::string &ffrom, const std::string &tto)
{
sprintf(response, "%s", lang_strings[STR_UNSUPPORTED_OPERATION_MSG]);
return 0;
}
int NfsClient::Move(const std::string &ffrom, const std::string &tto)
{
sprintf(response, "%s", lang_strings[STR_UNSUPPORTED_OPERATION_MSG]);
return 0;
}
bool NfsClient::FileExists(const std::string &ppath)
{
nfs_stat_64 st;
int ret = nfs_stat64(nfs, ppath.c_str(), &st);
if (ret != 0)
{
sprintf(response, "%s", nfs_get_error(nfs));
return 0;
}
return true;
}
/*
* Put - issue a PUT command and send data from input
*
* return 1 if successful, 0 otherwise
*/
int NfsClient::Put(const std::string &inputfile, const std::string &ppath, uint64_t offset)
{
bytes_to_download = FS::GetSize(inputfile);
if (bytes_to_download < 0)
{
sprintf(response, "%s", lang_strings[STR_FAILED]);
return 0;
}
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))
ret = nfs_creat(nfs, ppath.c_str(), 0660, &nfsfh);
else
{
ret = nfs_open(nfs, ppath.c_str(), 0660, &nfsfh);
}
if (ret != 0)
{
sprintf(response, "%s", nfs_get_error(nfs));
return 0;
}
void* buff = malloc(BUF_SIZE);
uint64_t count = 0;
bytes_transfered = 0;
while ((count = FS::Read(in, buff, BUF_SIZE)) > 0)
{
if (count < 0)
{
sprintf(response, "%s", lang_strings[STR_FAILED]);
FS::Close(in);
nfs_close(nfs, nfsfh);
free(buff);
return 0;
}
ret = nfs_write(nfs, nfsfh, count, buff);
if (ret < 0)
{
sprintf(response, "%s", nfs_get_error(nfs));
FS::Close(in);
nfs_close(nfs, nfsfh);
free(buff);
return 0;
}
bytes_transfered += count;
}
FS::Close(in);
nfs_close(nfs, nfsfh);
free(buff);
return 1;
}
int NfsClient::Rename(const std::string &src, const std::string &dst)
{
int ret = nfs_rename(nfs, src.c_str(), dst.c_str());
if (ret != 0)
{
sprintf(response, "%s", nfs_get_error(nfs));
return 0;
}
return 1;
}
int NfsClient::Delete(const std::string &ppath)
{
int ret = nfs_unlink(nfs, ppath.c_str());
if (ret != 0)
{
sprintf(response, "%s", nfs_get_error(nfs));
return 0;
}
return 1;
}
int NfsClient::Size(const std::string &ppath, int64_t *size)
{
nfs_stat_64 st;
int ret = nfs_stat64(nfs, ppath.c_str(), &st);
if (ret != 0)
{
sprintf(response, "%s", nfs_get_error(nfs));
return 0;
}
*size = st.nfs_size;
return 1;
}
std::vector<DirEntry> NfsClient::ListDir(const std::string &path)
{
std::vector<DirEntry> out;
DirEntry entry;
Util::SetupPreviousFolder(path, &entry);
out.push_back(entry);
struct nfsdir *nfsdir;
struct nfsdirent *nfsdirent;
int ret = nfs_opendir(nfs, path.c_str(), &nfsdir);
if (ret != 0) {
sprintf(response, "%s", nfs_get_error(nfs));
return out;
}
while ((nfsdirent = nfs_readdir(nfs, nfsdir)))
{
DirEntry entry;
memset(&entry, 0, sizeof(entry));
if (!show_hidden_files && nfsdirent->name[0] == '.')
continue;
entry.selectable = true;
snprintf(entry.directory, 511, "%s", path.c_str());
snprintf(entry.name, 255, "%s", nfsdirent->name);
if (path.length() > 0 && path[path.length() - 1] == '/')
{
sprintf(entry.path, "%s%s", path.c_str(), nfsdirent->name);
}
else
{
sprintf(entry.path, "%s/%s", path.c_str(), nfsdirent->name);
}
entry.file_size = nfsdirent->size;
struct tm tm = *localtime(&nfsdirent->mtime.tv_sec);
OrbisDateTime gmt;
OrbisDateTime lt;
gmt.day = tm.tm_mday;
gmt.month = tm.tm_mon + 1;
gmt.year = tm.tm_year + 1900;
gmt.hour = tm.tm_hour;
gmt.minute = tm.tm_min;
gmt.second = tm.tm_sec;
convertUtcToLocalTime(&gmt, &lt);
entry.modified.day = lt.day;
entry.modified.month = lt.month;
entry.modified.year = lt.year;
entry.modified.hours = lt.hour;
entry.modified.minutes = lt.minute;
entry.modified.seconds = lt.second;
switch (nfsdirent->mode & S_IFMT)
{
case S_IFLNK:
entry.isLink = true;
entry.file_size = 0;
sprintf(entry.display_size, "%s", lang_strings[STR_LINK]);
break;
case S_IFREG:
DirEntry::SetDisplaySize(&entry);
break;
case S_IFDIR:
entry.isDir = true;
entry.file_size = 0;
sprintf(entry.display_size, "%s", lang_strings[STR_FOLDER]);
break;
default:
continue;
break;
}
if (strcmp(entry.name, "..") != 0 && strcmp(entry.name, ".") != 0)
out.push_back(entry);
}
nfs_closedir(nfs, nfsdir);
return out;
}
std::string NfsClient::GetPath(std::string ppath1, std::string ppath2)
{
std::string path1 = ppath1;
std::string path2 = ppath2;
path1 = Util::Trim(Util::Trim(path1, " "), "/");
path2 = Util::Trim(Util::Trim(path2, " "), "/");
path1 = "/" + path1 + "/" + path2;
return path1;
}
int NfsClient::Head(const std::string &ppath, void *buffer, uint64_t len)
{
if (!FileExists(ppath))
{
return 0;
}
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;
}
int count = nfs_read(nfs, nfsfh, len, buffer);
nfs_close(nfs, nfsfh);
if (count != len)
return 0;
return 1;
}
ClientType NfsClient::clientType()
{
return CLIENT_TYPE_NFS;
}
uint32_t NfsClient::SupportedActions()
{
return REMOTE_ACTION_ALL ^ REMOTE_ACTION_CUT ^ REMOTE_ACTION_COPY ^ REMOTE_ACTION_PASTE;
}
+49
View File
@@ -0,0 +1,49 @@
#ifndef NFSCLIENT_H
#define NFSCLIENT_H
#include <sys/socket.h>
#include <arpa/inet.h>
#include <time.h>
#include <string>
#include <vector>
#include "nfsc/libnfs.h"
#include "nfsc/libnfs-raw.h"
#include "nfsc/libnfs-raw-mount.h"
#include "clients/remote_client.h"
#include "common.h"
class NfsClient : public RemoteClient
{
public:
NfsClient();
~NfsClient();
int Connect(const std::string &url, const std::string &user, const std::string &pass);
int Mkdir(const std::string &path);
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 GetRange(const std::string &path, void *buffer, 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);
bool FileExists(const std::string &path);
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);
bool IsConnected();
bool Ping();
const char *LastResponse();
int Quit();
std::string GetPath(std::string ppath1, std::string ppath2);
int Head(const std::string &path, void *buffer, uint64_t len);
ClientType clientType();
uint32_t SupportedActions();
private:
int _Rmdir(const std::string &ppath);
struct nfs_context *nfs;
char response[1024];
bool connected = false;
};
#endif
+1
View File
@@ -29,6 +29,7 @@ enum ClientType
CLIENT_TYPE_WEBDAV,
CLIENT_TYPE_HTTP_SERVER,
CLIENT_TYPE_GOOGLE,
CLIENT_TYPE_NFS,
CLINET_TYPE_UNKNOWN
};
+4
View File
@@ -98,6 +98,10 @@ namespace CONFIG
{
setting->type = CLIENT_TYPE_HTTP_SERVER;
}
else if (strncmp(setting->server, "nfs://", 6) == 0)
{
setting->type = CLIENT_TYPE_NFS;
}
else
{
setting->type = CLINET_TYPE_UNKNOWN;
+3
View File
@@ -157,6 +157,9 @@ char lang_strings[LANG_STRINGS_NUM][LANG_STR_SIZE] = {
"has being set as default direcotry", // STR_SET_DEFAULT_DIRECTORY_MSG
"View Image", // STR_VIEW_IMAGE
"Package Information", // STR_VIEW_PKG_INFO
"NFS export path missing in URL", // STR_NFS_EXP_PATH_MISSING_MSG
"Failed to init NFS context", // STR_FAIL_INIT_NFS_CONTEXT
"Failed to mount NFS share", // STR_FAIL_MOUNT_NFS_MSG
};
bool needs_extended_font = false;
+5 -2
View File
@@ -148,7 +148,10 @@
FUNC(STR_SET_DEFAULT_DIRECTORY) \
FUNC(STR_SET_DEFAULT_DIRECTORY_MSG) \
FUNC(STR_VIEW_IMAGE) \
FUNC(STR_VIEW_PKG_INFO)
FUNC(STR_VIEW_PKG_INFO) \
FUNC(STR_NFS_EXP_PATH_MISSING_MSG) \
FUNC(STR_FAIL_INIT_NFS_CONTEXT) \
FUNC(STR_FAIL_MOUNT_NFS_MSG)
#define GET_VALUE(x) x,
#define GET_STRING(x) #x,
@@ -158,7 +161,7 @@ enum
FOREACH_STR(GET_VALUE)
};
#define LANG_STRINGS_NUM 145
#define LANG_STRINGS_NUM 148
#define LANG_ID_SIZE 64
#define LANG_STR_SIZE 384
extern char lang_identifiers[LANG_STRINGS_NUM][LANG_ID_SIZE];
+36 -28
View File
@@ -342,6 +342,8 @@ namespace Windows
width = 500;
else if (remote_settings->type == CLIENT_TYPE_GOOGLE)
width = 600;
else if (remote_settings->type == CLIENT_TYPE_NFS)
width = 900;
pos = ImGui::GetCursorPos();
if (ImGui::Button(id, ImVec2(width, 0)))
{
@@ -376,43 +378,49 @@ namespace Windows
ImGui::SameLine();
}
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 5);
ImGui::TextColored(colors[ImGuiCol_ButtonHovered], "%s:", lang_strings[STR_USERNAME]);
ImGui::SameLine();
width = 180;
if (remote_settings->type == CLIENT_TYPE_GOOGLE)
width = 480;
sprintf(id, "%s##username", remote_settings->username);
pos = ImGui::GetCursorPos();
if (ImGui::Button(id, ImVec2(width, 0)))
{
ime_single_field = remote_settings->username;
ResetImeCallbacks();
ime_field_size = 32;
ime_callback = SingleValueImeCallback;
Dialog::initImeDialog(lang_strings[STR_USERNAME], remote_settings->username, 32, ORBIS_TYPE_BASIC_LATIN, pos.x, pos.y);
gui_mode = GUI_MODE_IME;
}
ImGui::SameLine();
if (remote_settings->type != CLIENT_TYPE_GOOGLE)
if (remote_settings->type != CLIENT_TYPE_NFS)
{
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 5);
ImGui::TextColored(colors[ImGuiCol_ButtonHovered], "%s:", lang_strings[STR_PASSWORD]);
ImGui::TextColored(colors[ImGuiCol_ButtonHovered], "%s:", lang_strings[STR_USERNAME]);
ImGui::SameLine();
sprintf(id, "%s##password", hidden_password.c_str());
width = 180;
if (remote_settings->type == CLIENT_TYPE_GOOGLE)
width = 480;
sprintf(id, "%s##username", remote_settings->username);
pos = ImGui::GetCursorPos();
if (ImGui::Button(id, ImVec2(100, 0)))
if (ImGui::Button(id, ImVec2(width, 0)))
{
ime_single_field = remote_settings->password;
ime_single_field = remote_settings->username;
ResetImeCallbacks();
ime_field_size = 127;
ime_field_size = 32;
ime_callback = SingleValueImeCallback;
Dialog::initImeDialog(lang_strings[STR_PASSWORD], remote_settings->password, 127, ORBIS_TYPE_BASIC_LATIN, pos.x, pos.y);
Dialog::initImeDialog(lang_strings[STR_USERNAME], remote_settings->username, 32, ORBIS_TYPE_BASIC_LATIN, pos.x, pos.y);
gui_mode = GUI_MODE_IME;
}
ImGui::SameLine();
}
if (remote_settings->type != CLIENT_TYPE_GOOGLE)
{
if (remote_settings->type != CLIENT_TYPE_NFS)
{
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 5);
ImGui::TextColored(colors[ImGuiCol_ButtonHovered], "%s:", lang_strings[STR_PASSWORD]);
ImGui::SameLine();
sprintf(id, "%s##password", hidden_password.c_str());
pos = ImGui::GetCursorPos();
if (ImGui::Button(id, ImVec2(100, 0)))
{
ime_single_field = remote_settings->password;
ResetImeCallbacks();
ime_field_size = 127;
ime_callback = SingleValueImeCallback;
Dialog::initImeDialog(lang_strings[STR_PASSWORD], remote_settings->password, 127, ORBIS_TYPE_BASIC_LATIN, pos.x, pos.y);
gui_mode = GUI_MODE_IME;
}
}
ImGui::SameLine();
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 5);
@@ -433,7 +441,7 @@ namespace Windows
ImGui::EndTooltip();
}
if ((remote_settings->type == CLIENT_TYPE_SMB || remote_settings->type == CLIENT_TYPE_FTP) && remote_settings->enable_rpi)
if ((remote_settings->type == CLIENT_TYPE_NFS || remote_settings->type == CLIENT_TYPE_SMB || remote_settings->type == CLIENT_TYPE_FTP) && remote_settings->enable_rpi)
{
ImGui::SameLine();
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 5);