From 28b985649f929597874fdfb5c4a2d7aa4e073700 Mon Sep 17 00:00:00 2001 From: Levi Neely <141506390+lneely@users.noreply.github.com> Date: Sun, 9 Mar 2025 20:20:33 +0100 Subject: [PATCH] rpcclient is now part of the CLI program (#126) --- control_tools.cpp | 33 ++++++++---- pclsync/plibs.h | 9 ++++ pclsync/rpcclient.h | 57 -------------------- pclsync/rpcclient.c => rpcclient.cpp | 77 ++++++---------------------- rpcclient.h | 28 ++++++++++ 5 files changed, 77 insertions(+), 127 deletions(-) delete mode 100644 pclsync/rpcclient.h rename pclsync/rpcclient.c => rpcclient.cpp (57%) create mode 100644 rpcclient.h diff --git a/control_tools.cpp b/control_tools.cpp index 0128d60..8cc3449 100644 --- a/control_tools.cpp +++ b/control_tools.cpp @@ -42,9 +42,9 @@ #include "pclsync_lib.h" #include "pclsync/pshm.h" #include "pclsync/pfoldersync.h" -#include "pclsync/rpcclient.h" #include "pclsync/pcommands.h" +#include "rpcclient.h" #include "CLI11.hpp" namespace cc = console_client; @@ -112,7 +112,9 @@ void setup_app(CLI::App *app) { app->add_subcommand("finalize", "Finalize and exit")->alias("f")->callback([] { char *errm = NULL; size_t errm_size = 0; - rpc_call(FINALIZE, "", &errm, &errm_size); + RpcClient *rpc = new RpcClient(); + rpc->Call(FINALIZE, "", &errm, &errm_size); + delete rpc; std::cout << "Exiting ..." << std::endl; if (errm) { free(errm); } exit(0); @@ -129,11 +131,14 @@ void setup_app(CLI::App *app) { start_crypto_cmd->callback([] { char *errm = NULL; size_t errm_size = 0; - if(int result = rpc_call(STARTCRYPTO, start_crypto_pwd.c_str(), &errm, &errm_size) != 0) { + RpcClient *rpc = new RpcClient(); + if(int result = rpc->Call(STARTCRYPTO, start_crypto_pwd.c_str(), &errm, &errm_size) != 0) { std::cout << "Start Crypto failed: " << (errm ? errm : "no message") << std::endl; if (errm) { free(errm); } + delete rpc; return result; } + delete rpc; std::cout << "Crypto started." << std::endl; if (errm) { free(errm); } return 0; @@ -143,12 +148,14 @@ void setup_app(CLI::App *app) { crypto_cmd->add_subcommand("stop", "Stop crypto")->callback([] { char *errm = NULL; size_t errm_size = 0; - if(int result = rpc_call(STOPCRYPTO, "", &errm, &errm_size) != 0) { + RpcClient *rpc = new RpcClient(); + if(int result = rpc->Call(STOPCRYPTO, "", &errm, &errm_size) != 0) { std::cout << "Stop Crypto failed: "<< (errm ? errm : "no message") << std::endl; if (errm) { free(errm); } + delete rpc; return result; } - + delete rpc; std::cout << "Crypto Stopped." << std::endl; if (errm) { free(errm); } return 0; @@ -158,12 +165,15 @@ void setup_app(CLI::App *app) { sync_cmd->add_subcommand("list", "List sync folders")->alias("ls")->callback([] { char *errm = NULL; size_t errmsz = 0; + RpcClient *rpc = new RpcClient(); - if(int result = rpc_call(LISTSYNC, "", &errm, &errmsz) != 0) { + if(int result = rpc->Call(LISTSYNC, "", &errm, &errmsz) != 0) { std::cout << "List Sync Folders failed: " << (errm ? errm : "no message") << std::endl; if (errm) { free(errm); } + delete rpc; return result; } + delete rpc; psync_folder_list_t *flist = NULL; if(pshm_read((void**)&flist, NULL)) { @@ -206,16 +216,18 @@ void setup_app(CLI::App *app) { size_t errmsz = 0; std::string combinedPaths = localpath + '|' + remotepath; - if(int result = rpc_call(ADDSYNC, combinedPaths.c_str(), &errm, &errmsz) != 0) { + RpcClient *rpc = new RpcClient(); + if(int result = rpc->Call(ADDSYNC, combinedPaths.c_str(), &errm, &errmsz) != 0) { if (result == -1) { std::cout << "Add Sync Folders failed: remote folder " << remotepath << " not found." << std::endl; } else { std::cout << "Add Sync Folders failed:" << (errm ? errm : "no message") << std::endl; } if (errm) { free(errm); } + delete rpc; return result; } - + delete rpc; if(errm) { free(errm); } return 0; }); @@ -229,11 +241,14 @@ void setup_app(CLI::App *app) { size_t errmsz = 0; const char *folderid = syncrm_fid.c_str(); - if(int result = rpc_call(STOPSYNC, folderid, &errm, &errmsz) != 0) { + RpcClient *rpc = new RpcClient(); + if(int result = rpc->Call(STOPSYNC, folderid, &errm, &errmsz) != 0) { std::cout << "Remove Sync Folder failed: " << (errm ? errm : "no message") << std::endl; if (errm) { free(errm); } + delete rpc; return result; } + delete rpc; std::cout << "Successfully removed sync folder with folderid " << folderid << std::endl; if(errm) { free(errm); } diff --git a/pclsync/plibs.h b/pclsync/plibs.h index 52ec91e..835ec9a 100644 --- a/pclsync/plibs.h +++ b/pclsync/plibs.h @@ -32,6 +32,10 @@ #ifndef _PSYNC_LIBS_H #define _PSYNC_LIBS_H +#ifdef __cplusplus +extern "C" { +#endif + #include #include "pcompiler.h" @@ -536,4 +540,9 @@ static inline size_t psync_strlcpy(char *dst, const char *src, size_t size) { } else return 0; } + +#ifdef __cplusplus +} +#endif + #endif diff --git a/pclsync/rpcclient.h b/pclsync/rpcclient.h deleted file mode 100644 index d33ae92..0000000 --- a/pclsync/rpcclient.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - Copyright (c) 2013-2015 pCloud Ltd. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided with - the distribution. Neither the name of pCloud Ltd nor the names of - its contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL pCloud - Ltd BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. -*/ - -/* -Dependencies: - - stddef.h - */ - -#ifndef OVERLAY_CLIENT_H -#define OVERLAY_CLIENT_H - -#define PCLOUD_TESTING -#ifdef __cplusplus -extern "C" { -#endif - -#include - -typedef enum _pCloud_FileState { - FileStateInSync = 0, - FileStateNoSync, - FileStateInProgress, - FileStateInvalid -} pCloud_FileState; - -int rpc_get_state(pCloud_FileState *, char *); -int rpc_call(int id, const char *path, char **errm, size_t *errmsz); - -#ifdef __cplusplus -} -#endif -#endif // OVERLAY_CLIENT_H diff --git a/pclsync/rpcclient.c b/rpcclient.cpp similarity index 57% rename from pclsync/rpcclient.c rename to rpcclient.cpp index d45f0ee..b408be9 100644 --- a/pclsync/rpcclient.c +++ b/rpcclient.cpp @@ -1,53 +1,3 @@ -/* - Copyright (c) 2013-2015 pCloud Ltd. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided with - the distribution. Neither the name of pCloud Ltd nor the names of - its contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL pCloud - Ltd BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. -*/ - -/* - overlay_client is responsible for invoking the pCloud API and - directing the result back to the calling function. It defines the - core logic of the request-response flow: - - - SendCall (this function) writes the request to the socket. - - - instance_thread reads the request from the socket and calls - get_response (see poverlay.c). - - - get_response invokes the appropriate callback function and - generates a response_message. The callback functions are - registered in pclsync_lib.cpp using psync_add_overlay_callback - (see poverlay.c). - - - instance_thread writes the resulting response_message to the - socket (see poverlay.c). - - - SendCall reads the response from the socket. It writes the - response output data back to its caller (see control_tools.cpp). -*/ - #include #include #include @@ -62,9 +12,9 @@ #include "plibs.h" #include "prpc.h" + #define POVERLAY_BUFSIZE 512 -// for easier error tracing... #define POVERLAY_SOCKET_CREATE_FAILED -100 #define POVERLAY_SOCKET_CONNECT_FAILED -101 #define POVERLAY_WRITE_SOCK_ERR -102 @@ -73,11 +23,17 @@ #define POVERLAY_READ_INCOMPLETE -105 #define POVERLAY_READ_INVALID_RESPONSE -106 +RpcClient::RpcClient() { + this->sockpath = "/tmp/pcloud_unix_soc.sock"; +} + +RpcClient::~RpcClient() {} + // socket_connect creates and connects to a unix socket at the // specified sockpath. it may write an error message and error message // size to out and out_size, and a "ret" value to ret (i think this is // redundant maybe...) -static int socket_connect(const char *sockpath, char **out, size_t *out_size) { +int RpcClient::connectSocket(const char *sockpath, char **out, size_t *out_size) { int fd; struct sockaddr_un addr; const char *error_msg; @@ -101,7 +57,7 @@ static int socket_connect(const char *sockpath, char **out, size_t *out_size) { return fd; } -static int write_request(int fd, int msgtype, const char *value, char **out, size_t *out_size) { +int RpcClient::writeRequest(int fd, int msgtype, const char *value, char **out, size_t *out_size) { uint64_t bytes_written; int len = strlen(value); int size = sizeof(rpc_message_t) + len + 1; @@ -145,7 +101,7 @@ static int write_request(int fd, int msgtype, const char *value, char **out, siz return writeerr; } -static int read_response(int fd, char **out, size_t *out_size) { +int RpcClient::readResponse(int fd, char **out, size_t *out_size) { rpc_message_t *msg = (rpc_message_t *)malloc(POVERLAY_BUFSIZE); if (msg == NULL) { @@ -172,12 +128,12 @@ static int read_response(int fd, char **out, size_t *out_size) { return 0; } -int rpc_get_state(pCloud_FileState *state, char *path) { +int RpcClient::GetState(pCloud_FileState *state, char *path) { char *errm = NULL; size_t errm_size = 0; int rep = 0; - if ((rep = rpc_call(4, path, &errm, &errm_size) == 0)) { + if ((rep = this->Call(4, path, &errm, &errm_size) == 0)) { debug(D_NOTICE, "rpc_get_state responese rep[%d] path[%s]", rep, path); if (errm) { debug(D_NOTICE, "The error is %s", errm); @@ -200,15 +156,14 @@ int rpc_get_state(pCloud_FileState *state, char *path) { return 0; } -// path contains the input argument(s). -int rpc_call(int id, const char *path, char **errm, size_t *errmsz) { +int RpcClient::Call(int id, const char *path, char **errm, size_t *errmsz) { int result = 0; int sockfd = -1; - sockfd = socket_connect(PRPC_SOCK_PATH, errm, errmsz); + sockfd = this->connectSocket(PRPC_SOCK_PATH, errm, errmsz); if (sockfd >= 0) { - if ((result = write_request(sockfd, id, path, errm, errmsz)) == 0) { - result = read_response(sockfd, errm, errmsz); + if ((result = this->writeRequest(sockfd, id, path, errm, errmsz)) == 0) { + result = this->readResponse(sockfd, errm, errmsz); } close(sockfd); } else { diff --git a/rpcclient.h b/rpcclient.h new file mode 100644 index 0000000..be42ccc --- /dev/null +++ b/rpcclient.h @@ -0,0 +1,28 @@ +#ifndef __RPCCLIENT_H +#define __RPCCLIENT_H + +#include + +typedef enum _pCloud_FileState { + FileStateInSync = 0, + FileStateNoSync, + FileStateInProgress, + FileStateInvalid +} pCloud_FileState; + +class RpcClient { + +private: + const char *sockpath; + + int connectSocket(const char *sockpath, char **out, size_t *out_size); + int writeRequest(int fd, int msgtype, const char *value, char **out, size_t *out_size); + int readResponse(int fd, char **out, size_t *out_size); +public: + RpcClient(); + ~RpcClient(); + int GetState(pCloud_FileState *, char *); + int Call(int id, const char *path, char **errm, size_t *errmsz); +}; + +#endif \ No newline at end of file