* small lsp error fixes * simplify messaging and remove serialize/deserialize - messaging is reverted to API requests and responses only - remove serialize and deserialize functions - implement shared memory (pshm) for overlay callback return values * fix memory leak Fix #64 and #71
This commit is contained in:
parent
5a5dec975f
commit
5ecece7547
|
|
@ -15,7 +15,7 @@ a.out
|
||||||
cmd/pcloudcc/build/pcloudcc
|
cmd/pcloudcc/build/pcloudcc
|
||||||
**/*/.cache/
|
**/*/.cache/
|
||||||
compile_commands.json
|
compile_commands.json
|
||||||
|
compile_commands.events.json
|
||||||
/cmd/pcloudcc/build/
|
/cmd/pcloudcc/build/
|
||||||
/.cache/
|
/.cache/
|
||||||
/lib/poverlay_linux/overlay_client
|
/lib/poverlay_linux/overlay_client
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,8 @@
|
||||||
#include "pclsync/overlay_client.h"
|
#include "pclsync/overlay_client.h"
|
||||||
|
|
||||||
#include "pclsync_lib.h"
|
#include "pclsync_lib.h"
|
||||||
#include "psynclib.h"
|
#include "pclsync/psynclib.h"
|
||||||
|
#include "pclsync/pshm.h"
|
||||||
|
|
||||||
#include "CLI11.hpp"
|
#include "CLI11.hpp"
|
||||||
|
|
||||||
|
|
@ -60,62 +61,10 @@ enum command_ids_ {
|
||||||
STOPSYNC
|
STOPSYNC
|
||||||
};
|
};
|
||||||
|
|
||||||
std::pair<std::string, std::string> split_paths(const std::string &input) {
|
|
||||||
std::string path1, path2;
|
|
||||||
bool in_quotes = false;
|
|
||||||
bool escaped = false;
|
|
||||||
std::string current_path;
|
|
||||||
|
|
||||||
for (char c : input) {
|
|
||||||
if (escaped) {
|
|
||||||
current_path += c;
|
|
||||||
escaped = false;
|
|
||||||
} else if (c == '\\') {
|
|
||||||
escaped = true;
|
|
||||||
} else if (c == '"') {
|
|
||||||
in_quotes = !in_quotes;
|
|
||||||
current_path += c;
|
|
||||||
} else if (c == ' ' && !in_quotes) {
|
|
||||||
if (!current_path.empty()) {
|
|
||||||
if (path1.empty()) {
|
|
||||||
path1 = current_path;
|
|
||||||
} else {
|
|
||||||
path2 = current_path;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
current_path.clear();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
current_path += c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!current_path.empty()) {
|
|
||||||
if (path1.empty()) {
|
|
||||||
path1 = current_path;
|
|
||||||
} else if (path2.empty()) {
|
|
||||||
path2 = current_path;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto remove_quotes = [](std::string &s) {
|
|
||||||
if (s.size() >= 2 && s.front() == '"' && s.back() == '"') {
|
|
||||||
s = s.substr(1, s.size() - 2);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
remove_quotes(path1);
|
|
||||||
remove_quotes(path2);
|
|
||||||
|
|
||||||
return {path1, path2};
|
|
||||||
}
|
|
||||||
|
|
||||||
int list_sync_folders() {
|
int list_sync_folders() {
|
||||||
int ret;
|
int ret;
|
||||||
char *errm;
|
char *errm;
|
||||||
size_t errmsz;
|
size_t errmsz;
|
||||||
void *rep;
|
|
||||||
size_t repsz;
|
|
||||||
int result;
|
int result;
|
||||||
psync_folder_list_t *flist;
|
psync_folder_list_t *flist;
|
||||||
psync_folder_t *folder;
|
psync_folder_t *folder;
|
||||||
|
|
@ -123,51 +72,50 @@ int list_sync_folders() {
|
||||||
|
|
||||||
errm = NULL;
|
errm = NULL;
|
||||||
errmsz = 0;
|
errmsz = 0;
|
||||||
rep = NULL;
|
|
||||||
repsz = 0;
|
|
||||||
rval = 0;
|
rval = 0;
|
||||||
|
|
||||||
result = SendCall(LISTSYNC, "", &ret, &errm, &errmsz, &rep, &repsz);
|
result = SendCall(LISTSYNC, "", &ret, &errm, &errmsz);
|
||||||
|
|
||||||
if (result != 0) {
|
if (result != 0) {
|
||||||
std::cout << "List Sync Folders failed. return is " << ret
|
std::cout << "List Sync Folders failed. return is " << ret
|
||||||
<< " and message is " << (errm ? errm : "no message")
|
<< " and message is " << (errm ? errm : "no message")
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
rval = result;
|
rval = result;
|
||||||
} else if (rep && repsz > 0) {
|
}
|
||||||
flist = static_cast<psync_folder_list_t *>(rep);
|
|
||||||
|
|
||||||
if (repsz < sizeof(psync_folder_list_t)) {
|
if(pshm_read((void**)&flist, NULL)) {
|
||||||
std::cout << "Error: Insufficient data for folder list structure"
|
const int id_width = 12;
|
||||||
<< std::endl;
|
const int path_width = 30;
|
||||||
rval = -1;
|
|
||||||
} else {
|
|
||||||
|
|
||||||
const int id_width = 12;
|
|
||||||
const int path_width = 30;
|
|
||||||
|
|
||||||
|
if(flist->foldercnt > 0) {
|
||||||
std::cout << std::left << std::setw(id_width) << "Folder ID"
|
std::cout << std::left << std::setw(id_width) << "Folder ID"
|
||||||
<< std::setw(path_width) << "Local Path"
|
<< std::setw(path_width) << "Local Path"
|
||||||
<< std::setw(path_width) << "Remote Path" << std::endl;
|
<< std::setw(path_width) << "Remote Path" << std::endl;
|
||||||
std::cout << std::string(id_width, '-')
|
std::cout << std::string(id_width, '-')
|
||||||
<< std::string(path_width - 1, '-')
|
<< std::string(path_width - 1, '-')
|
||||||
<< std::string(path_width - 1, '-') << std::endl;
|
<< std::string(path_width - 1, '-') << std::endl;
|
||||||
|
|
||||||
for (uint32_t i = 0; i < flist->foldercnt; i++) {
|
for (uint32_t i = 0; i < flist->foldercnt; i++) {
|
||||||
folder = &flist->folders[i];
|
folder = &flist->folders[i];
|
||||||
std::cout << std::left << std::setw(id_width) << folder->folderid
|
std::cout << std::left << std::setw(id_width) << folder->folderid
|
||||||
<< std::setw(path_width) << folder->localpath
|
<< std::setw(path_width) << folder->localpath
|
||||||
<< std::setw(path_width) << folder->remotepath << std::endl;
|
<< std::setw(path_width) << folder->remotepath << std::endl;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
std::cout << "No synchronized folders found." << std::endl;
|
||||||
rval = ret;
|
rval = ret;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
std::cout << "No synchronized folders found." << std::endl;
|
|
||||||
rval = ret;
|
rval = ret;
|
||||||
|
|
||||||
|
free(flist);
|
||||||
|
} else {
|
||||||
|
std::cout << "failed to read folder list from shm" << std::endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(errm) {
|
||||||
|
free(errm);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(errm);
|
|
||||||
free(rep);
|
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -176,7 +124,8 @@ int start_crypto(const char *pass) {
|
||||||
char *errm;
|
char *errm;
|
||||||
size_t errm_size;
|
size_t errm_size;
|
||||||
|
|
||||||
int result = SendCall(STARTCRYPTO, pass, &ret, &errm, &errm_size, NULL, NULL);
|
int result = SendCall(STARTCRYPTO, pass, &ret, &errm, &errm_size);
|
||||||
|
|
||||||
if (result != 0 || ret != 0) {
|
if (result != 0 || ret != 0) {
|
||||||
std::cout << "Start Crypto failed. return is " << ret << " and message is "
|
std::cout << "Start Crypto failed. return is " << ret << " and message is "
|
||||||
<< (errm ? errm : "no message") << std::endl;
|
<< (errm ? errm : "no message") << std::endl;
|
||||||
|
|
@ -193,7 +142,7 @@ int stop_crypto() {
|
||||||
char *errm;
|
char *errm;
|
||||||
size_t errm_size;
|
size_t errm_size;
|
||||||
|
|
||||||
int result = SendCall(STOPCRYPTO, "", &ret, &errm, &errm_size, NULL, NULL);
|
int result = SendCall(STOPCRYPTO, "", &ret, &errm, &errm_size);
|
||||||
if (result != 0) {
|
if (result != 0) {
|
||||||
std::cout << "Stop Crypto failed. return is " << ret << " and message is "
|
std::cout << "Stop Crypto failed. return is " << ret << " and message is "
|
||||||
<< (errm ? errm : "no message") << std::endl;
|
<< (errm ? errm : "no message") << std::endl;
|
||||||
|
|
@ -217,7 +166,7 @@ int remove_sync_folder(const char *folderid) {
|
||||||
errmsz = 0;
|
errmsz = 0;
|
||||||
rval = 0;
|
rval = 0;
|
||||||
|
|
||||||
result = SendCall(STOPSYNC, folderid, &ret, &errm, &errmsz, NULL, NULL);
|
result = SendCall(STOPSYNC, folderid, &ret, &errm, &errmsz);
|
||||||
if (result != 0) {
|
if (result != 0) {
|
||||||
std::cout << "Remove Sync Folder failed with unknown error. return is "
|
std::cout << "Remove Sync Folder failed with unknown error. return is "
|
||||||
<< ret << " and message is " << (errm ? errm : "no message")
|
<< ret << " and message is " << (errm ? errm : "no message")
|
||||||
|
|
@ -227,7 +176,10 @@ int remove_sync_folder(const char *folderid) {
|
||||||
std::cout << "Successfully removed sync folder with folderid " << folderid
|
std::cout << "Successfully removed sync folder with folderid " << folderid
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
}
|
}
|
||||||
free(errm);
|
|
||||||
|
if(errm) {
|
||||||
|
free(errm);
|
||||||
|
}
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -237,20 +189,15 @@ int add_sync_folder(std::string localpath, std::string remotepath) {
|
||||||
int ret;
|
int ret;
|
||||||
char *errm;
|
char *errm;
|
||||||
size_t errmsz;
|
size_t errmsz;
|
||||||
void *rep;
|
|
||||||
size_t repsz;
|
|
||||||
int result;
|
int result;
|
||||||
int rval;
|
int rval;
|
||||||
|
|
||||||
errm = NULL;
|
errm = NULL;
|
||||||
errmsz = 0;
|
errmsz = 0;
|
||||||
rep = NULL;
|
|
||||||
repsz = 0;
|
|
||||||
rval = 0;
|
rval = 0;
|
||||||
|
|
||||||
std::string combinedPaths = localpath + '|' + remotepath;
|
std::string combinedPaths = localpath + '|' + remotepath;
|
||||||
result = SendCall(ADDSYNC, combinedPaths.c_str(), &ret, &errm, &errmsz, &rep,
|
result = SendCall(ADDSYNC, combinedPaths.c_str(), &ret, &errm, &errmsz);
|
||||||
&repsz);
|
|
||||||
|
|
||||||
if (result != 0) {
|
if (result != 0) {
|
||||||
if (result == -1) {
|
if (result == -1) {
|
||||||
|
|
@ -262,22 +209,14 @@ int add_sync_folder(std::string localpath, std::string remotepath) {
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
}
|
}
|
||||||
rval = result;
|
rval = result;
|
||||||
} else if (rep && repsz > 0) {
|
|
||||||
if (repsz < sizeof(psync_syncid_t)) {
|
|
||||||
std::cout << "Error: Insufficient data for folder list structure"
|
|
||||||
<< std::endl;
|
|
||||||
rval = -1;
|
|
||||||
} else {
|
|
||||||
rval = ret;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
std::cout << "Error: Did not get a syncid from add_sync_folder."
|
|
||||||
<< std::endl;
|
|
||||||
rval = ret;
|
rval = ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(errm);
|
if(errm) {
|
||||||
free(rep);
|
free(errm);
|
||||||
|
}
|
||||||
|
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -286,11 +225,12 @@ int finalize() {
|
||||||
char *errm;
|
char *errm;
|
||||||
size_t errm_size;
|
size_t errm_size;
|
||||||
|
|
||||||
SendCall(FINALIZE, "", &ret, &errm, &errm_size, NULL, NULL);
|
SendCall(FINALIZE, "", &ret, &errm, &errm_size);
|
||||||
std::cout << "Exiting ..." << std::endl;
|
std::cout << "Exiting ..." << std::endl;
|
||||||
|
|
||||||
if (errm)
|
if (errm){
|
||||||
free(errm);
|
free(errm);
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,8 +26,7 @@ that gets created when the server is started.
|
||||||
socket -> poverlay : request
|
socket -> poverlay : request
|
||||||
poverlay -> poverlay : poverlay_handle_request
|
poverlay -> poverlay : poverlay_handle_request
|
||||||
poverlay -> poverlay : poverlay_get_response
|
poverlay -> poverlay : poverlay_get_response
|
||||||
poverlay -> poverlay : serialize_response_message
|
poverlay -> socket : response
|
||||||
poverlay -> socket : response (serialized)
|
|
||||||
socket -> overlay_client : read_response
|
socket -> overlay_client : read_response
|
||||||
overlay_client -> control_tools : (msg, msgsz, payload, payloadsz)
|
overlay_client -> control_tools : (msg, msgsz, payload, payloadsz)
|
||||||
control_tools -> user : print results
|
control_tools -> user : print results
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@
|
||||||
#include "overlay_client.h"
|
#include "overlay_client.h"
|
||||||
#include "poverlay_protocol.h"
|
#include "poverlay_protocol.h"
|
||||||
|
|
||||||
#define POVERLAY_BUFSIZE 16 * 1024
|
#define POVERLAY_BUFSIZE 512
|
||||||
|
|
||||||
// for easier error tracing...
|
// for easier error tracing...
|
||||||
#define POVERLAY_SOCKET_CREATE_FAILED -100
|
#define POVERLAY_SOCKET_CREATE_FAILED -100
|
||||||
|
|
@ -73,106 +73,8 @@
|
||||||
#define POVERLAY_READ_INCOMPLETE -105
|
#define POVERLAY_READ_INCOMPLETE -105
|
||||||
#define POVERLAY_READ_INVALID_RESPONSE -106
|
#define POVERLAY_READ_INVALID_RESPONSE -106
|
||||||
|
|
||||||
response_message *deserialize_response_message(const char *buffer,
|
void free_response_message(message *resp) {
|
||||||
size_t buffer_size) {
|
|
||||||
if (buffer_size < 2 * sizeof(size_t) + sizeof(uint32_t) + sizeof(uint64_t)) {
|
|
||||||
debug(D_ERROR, "Buffer size too small: %zu", buffer_size);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *ptr = buffer;
|
|
||||||
|
|
||||||
// Allocate response_message
|
|
||||||
response_message *resp = (response_message *)malloc(sizeof(response_message));
|
|
||||||
if (resp == NULL) {
|
|
||||||
debug(D_ERROR, "Failed to allocate response_message");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get message size
|
|
||||||
size_t msg_size = be64toh(*(size_t *)ptr);
|
|
||||||
ptr += sizeof(size_t);
|
|
||||||
|
|
||||||
debug(D_ERROR, "Message size: %zu", msg_size);
|
|
||||||
|
|
||||||
if (msg_size < sizeof(uint32_t) + sizeof(uint64_t)) {
|
|
||||||
debug(D_ERROR, "Invalid message size: %zu", msg_size);
|
|
||||||
free(resp);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allocate message with extra space for the flexible array member
|
|
||||||
size_t alloc_size =
|
|
||||||
sizeof(message) + msg_size - sizeof(uint32_t) - sizeof(uint64_t);
|
|
||||||
resp->msg = (message *)malloc(alloc_size);
|
|
||||||
if (resp->msg == NULL) {
|
|
||||||
debug(D_ERROR, "Failed to allocate message");
|
|
||||||
free(resp);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
resp->msg->type = ntohl(*(uint32_t *)ptr);
|
|
||||||
ptr += sizeof(uint32_t);
|
|
||||||
|
|
||||||
resp->msg->length = be64toh(*(uint64_t *)ptr);
|
|
||||||
ptr += sizeof(uint64_t);
|
|
||||||
|
|
||||||
debug(D_ERROR, "Message type: %u, length: %lu", resp->msg->type,
|
|
||||||
resp->msg->length);
|
|
||||||
|
|
||||||
// Calculate the size of the value array
|
|
||||||
size_t value_size = msg_size - sizeof(uint32_t) - sizeof(uint64_t);
|
|
||||||
|
|
||||||
if (value_size > 0) {
|
|
||||||
if (ptr + value_size > buffer + buffer_size) {
|
|
||||||
debug(D_ERROR, "Buffer overflow detected");
|
|
||||||
free(resp->msg);
|
|
||||||
free(resp);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
memcpy(resp->msg->value, ptr, value_size);
|
|
||||||
ptr += value_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deserialize payload size
|
|
||||||
if (ptr + sizeof(size_t) > buffer + buffer_size) {
|
|
||||||
debug(D_ERROR, "Buffer overflow detected when reading payload size");
|
|
||||||
free(resp->msg);
|
|
||||||
free(resp);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
resp->payloadsz = be64toh(*(size_t *)ptr);
|
|
||||||
ptr += sizeof(size_t);
|
|
||||||
|
|
||||||
debug(D_ERROR, "Payload size: %zu", resp->payloadsz);
|
|
||||||
|
|
||||||
// Deserialize payload
|
|
||||||
if (resp->payloadsz > 0) {
|
|
||||||
if (ptr + resp->payloadsz > buffer + buffer_size) {
|
|
||||||
debug(D_ERROR, "Buffer overflow detected when reading payload");
|
|
||||||
free(resp->msg);
|
|
||||||
free(resp);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
resp->payload = malloc(resp->payloadsz);
|
|
||||||
if (resp->payload == NULL) {
|
|
||||||
debug(D_ERROR, "Failed to allocate payload");
|
|
||||||
free(resp->msg);
|
|
||||||
free(resp);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
memcpy(resp->payload, ptr, resp->payloadsz);
|
|
||||||
} else {
|
|
||||||
resp->payload = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return resp;
|
|
||||||
}
|
|
||||||
|
|
||||||
void free_response_message(response_message *resp) {
|
|
||||||
if (resp) {
|
if (resp) {
|
||||||
free(resp->msg);
|
|
||||||
free(resp->payload);
|
|
||||||
free(resp);
|
free(resp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -182,7 +84,7 @@ int QueryState(pCloud_FileState *state, char *path) {
|
||||||
char *errm;
|
char *errm;
|
||||||
size_t errm_size;
|
size_t errm_size;
|
||||||
|
|
||||||
if (!SendCall(4, path /*IN*/, &rep, &errm, &errm_size, NULL, NULL)) {
|
if (!SendCall(4, path /*IN*/, &rep, &errm, &errm_size)) {
|
||||||
debug(D_NOTICE, "QueryState responese rep[%d] path[%s]", rep, path);
|
debug(D_NOTICE, "QueryState responese rep[%d] path[%s]", rep, path);
|
||||||
if (errm)
|
if (errm)
|
||||||
debug(D_NOTICE, "The error is %s", errm);
|
debug(D_NOTICE, "The error is %s", errm);
|
||||||
|
|
@ -243,15 +145,15 @@ int write_request(int fd, int msgtype, const char *value, char **out,
|
||||||
int size;
|
int size;
|
||||||
char *buf;
|
char *buf;
|
||||||
const char *err;
|
const char *err;
|
||||||
request_message *request;
|
message *request;
|
||||||
char *curbuf;
|
char *curbuf;
|
||||||
|
|
||||||
*ret = 0; // Initialize ret to 0
|
*ret = 0; // Initialize ret to 0
|
||||||
|
|
||||||
len = strlen(value);
|
len = strlen(value);
|
||||||
size = sizeof(request_message) + len + 1;
|
size = sizeof(message) + len + 1;
|
||||||
buf = (char *)malloc(size);
|
buf = (char *)malloc(size);
|
||||||
request = (request_message *)buf;
|
request = (message *)buf;
|
||||||
memset(request, 0, size);
|
memset(request, 0, size);
|
||||||
request->type = msgtype;
|
request->type = msgtype;
|
||||||
strncpy(request->value, value, len + 1);
|
strncpy(request->value, value, len + 1);
|
||||||
|
|
@ -288,122 +190,53 @@ int write_request(int fd, int msgtype, const char *value, char **out,
|
||||||
// write an error message OR an API response value to out (and its
|
// write an error message OR an API response value to out (and its
|
||||||
// size to out_size), a "ret" value to ret (redundant?), and the
|
// size to out_size), a "ret" value to ret (redundant?), and the
|
||||||
// callback's return data to payload and payloadsz.
|
// callback's return data to payload and payloadsz.
|
||||||
int read_response(int fd, char **out, size_t *out_size, int *ret,
|
int read_response(int fd, char **out, size_t *out_size, int *ret) {
|
||||||
void **payload, size_t *payloadsz) {
|
message *msg;
|
||||||
char buffer[POVERLAY_BUFSIZE];
|
ssize_t bytes_read;
|
||||||
ssize_t bytes_read = read(fd, buffer, POVERLAY_BUFSIZE);
|
|
||||||
|
|
||||||
if (bytes_read <= 0) {
|
msg = (message *)malloc(POVERLAY_BUFSIZE);
|
||||||
const char *error_msg =
|
if (msg == NULL) {
|
||||||
(bytes_read == 0) ? "Connection closed" : strerror(errno);
|
const char *error_msg = "Memory allocation failed";
|
||||||
*out = strdup(error_msg);
|
|
||||||
*out_size = strlen(error_msg) + 1;
|
|
||||||
*ret = -1;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bytes_read < sizeof(response_message)) {
|
|
||||||
const char *error_msg = "Incomplete response";
|
|
||||||
*out = strdup(error_msg);
|
|
||||||
*out_size = strlen(error_msg) + 1;
|
|
||||||
*ret = -1;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// response_message *resp = (response_message *)buffer;
|
|
||||||
response_message *resp = deserialize_response_message(buffer, bytes_read);
|
|
||||||
if (resp == NULL) {
|
|
||||||
const char *error_msg = "Failed to deserialize response";
|
|
||||||
*out = strdup(error_msg);
|
|
||||||
*out_size = strlen(error_msg) + 1;
|
|
||||||
*ret = -1;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate the response_message structure
|
|
||||||
if (resp->msg == NULL ||
|
|
||||||
(size_t)bytes_read < sizeof(response_message) + sizeof(message) ||
|
|
||||||
(size_t)bytes_read < sizeof(response_message) + resp->msg->length) {
|
|
||||||
const char *error_msg = "Invalid response structure";
|
|
||||||
*out = strdup(error_msg);
|
|
||||||
*out_size = strlen(error_msg) + 1;
|
|
||||||
*ret = -1;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message *msg = resp->msg;
|
|
||||||
size_t value_size = msg->length - sizeof(message);
|
|
||||||
|
|
||||||
// Validate message length
|
|
||||||
if (msg->length < sizeof(message) ||
|
|
||||||
(size_t)bytes_read < sizeof(response_message) + msg->length) {
|
|
||||||
const char *error_msg = "Invalid message length";
|
|
||||||
*out = strdup(error_msg);
|
|
||||||
*out_size = strlen(error_msg) + 1;
|
|
||||||
*ret = -1;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
*out = malloc(value_size + 1);
|
|
||||||
if (*out == NULL) {
|
|
||||||
const char *error_msg = "Memory allocation failed";
|
|
||||||
*out = strdup(error_msg);
|
|
||||||
*out_size = strlen(error_msg) + 1;
|
|
||||||
*ret = -1;
|
|
||||||
free_response_message(resp);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(*out, msg->value, value_size);
|
|
||||||
(*out)[value_size] = '\0';
|
|
||||||
*out_size = value_size + 1;
|
|
||||||
|
|
||||||
*ret = msg->type;
|
|
||||||
|
|
||||||
if (payload != NULL && payloadsz != NULL) {
|
|
||||||
if (resp->payload != NULL && resp->payloadsz > 0) {
|
|
||||||
*payload = malloc(resp->payloadsz);
|
|
||||||
if (*payload == NULL) {
|
|
||||||
const char *error_msg = "Memory allocation failed for payload";
|
|
||||||
free(*out);
|
|
||||||
*out = strdup(error_msg);
|
*out = strdup(error_msg);
|
||||||
*out_size = strlen(error_msg) + 1;
|
*out_size = strlen(error_msg) + 1;
|
||||||
*ret = -1;
|
*ret = -1;
|
||||||
free_response_message(resp);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
memcpy(*payload, resp->payload, resp->payloadsz);
|
|
||||||
*payloadsz = resp->payloadsz;
|
|
||||||
} else {
|
|
||||||
*payload = NULL;
|
|
||||||
*payloadsz = 0;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
free_response_message(resp);
|
bytes_read = read(fd, msg, POVERLAY_BUFSIZE);
|
||||||
return 0;
|
if (bytes_read <= 0) {
|
||||||
|
const char *error_msg = (bytes_read == 0) ? "Connection closed" : "Read error";
|
||||||
|
free(msg);
|
||||||
|
*out = strdup(error_msg);
|
||||||
|
*out_size = strlen(error_msg) + 1;
|
||||||
|
*ret = -1;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*out = (char *)malloc(msg->length);
|
||||||
|
memcpy(*out, msg->value, msg->length);
|
||||||
|
*out_size = msg->length;
|
||||||
|
*ret = msg->type;
|
||||||
|
|
||||||
|
free(msg);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SendCall(int id /*IN*/, const char *path /*IN*/, int *ret /*OUT*/,
|
// path contains the input argument(s).
|
||||||
char **out /*OUT*/, size_t *out_size, void **reply_data,
|
int SendCall(int id, const char *path, int *ret, char **errm, size_t *errmsz) {
|
||||||
size_t *reply_size) {
|
|
||||||
int result;
|
int result;
|
||||||
int sockfd;
|
int sockfd;
|
||||||
|
|
||||||
sockfd = -1;
|
sockfd = -1;
|
||||||
result = 0;
|
result = 0;
|
||||||
*out = NULL;
|
*errm = NULL;
|
||||||
*out_size = 0;
|
*errmsz = 0;
|
||||||
*ret = 0;
|
*ret = 0;
|
||||||
|
|
||||||
// side effects: modify out, out_size, ret
|
sockfd = socket_connect(POVERLAY_SOCK_PATH, errm, errmsz, ret);
|
||||||
sockfd = socket_connect(POVERLAY_SOCK_PATH, out, out_size, ret);
|
|
||||||
if (sockfd >= 0) {
|
if (sockfd >= 0) {
|
||||||
// side effects: modify out, out_size, ret
|
if ((result = write_request(sockfd, id, path, errm, errmsz, ret)) == 0) {
|
||||||
if ((result = write_request(sockfd, id, path, out, out_size, ret)) == 0) {
|
result = read_response(sockfd, errm, errmsz, ret);
|
||||||
// side effects: modify out, out_size, ret, reply_data, reply_size
|
|
||||||
result =
|
|
||||||
read_response(sockfd, out, out_size, ret, reply_data, reply_size);
|
|
||||||
}
|
}
|
||||||
close(sockfd);
|
close(sockfd);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -48,11 +48,9 @@ typedef enum _pCloud_FileState {
|
||||||
FileStateInvalid
|
FileStateInvalid
|
||||||
} pCloud_FileState;
|
} pCloud_FileState;
|
||||||
|
|
||||||
int QueryState(pCloud_FileState *state /*OUT*/, char *path /*IN*/);
|
int QueryState(pCloud_FileState *, char *);
|
||||||
|
int SendCall(int id, const char *, int *, char **, size_t *);
|
||||||
|
|
||||||
int SendCall(int id /*IN*/, const char *path /*IN*/, int *ret /*OUT*/,
|
|
||||||
char **out /*OUT*/, size_t *out_size, void **reply_data,
|
|
||||||
size_t *reply_size);
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -925,3 +925,4 @@ psync_folder_list_t *psync_list_get_list(char *syncTypes) {
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -55,47 +55,6 @@
|
||||||
int overlays_running = 1;
|
int overlays_running = 1;
|
||||||
int callbacks_running = 1;
|
int callbacks_running = 1;
|
||||||
|
|
||||||
// Serialization function
|
|
||||||
size_t serialize_response_message(const response_message *resp,
|
|
||||||
char **out_buffer) {
|
|
||||||
// Calculate total size needed
|
|
||||||
size_t msg_size = sizeof(uint32_t) + sizeof(uint64_t) + resp->msg->length;
|
|
||||||
size_t total_size =
|
|
||||||
sizeof(size_t) + msg_size + sizeof(size_t) + resp->payloadsz;
|
|
||||||
|
|
||||||
// Allocate buffer
|
|
||||||
*out_buffer = (char *)malloc(total_size);
|
|
||||||
if (*out_buffer == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
char *ptr = *out_buffer;
|
|
||||||
|
|
||||||
// Serialize msg size
|
|
||||||
*(size_t *)ptr = htobe64(msg_size);
|
|
||||||
ptr += sizeof(size_t);
|
|
||||||
|
|
||||||
// Serialize msg
|
|
||||||
*(uint32_t *)ptr = htonl(resp->msg->type);
|
|
||||||
ptr += sizeof(uint32_t);
|
|
||||||
|
|
||||||
*(uint64_t *)ptr = htobe64(resp->msg->length);
|
|
||||||
ptr += sizeof(uint64_t);
|
|
||||||
|
|
||||||
memcpy(ptr, resp->msg->value, resp->msg->length);
|
|
||||||
ptr += resp->msg->length;
|
|
||||||
|
|
||||||
// Serialize payload size
|
|
||||||
*(size_t *)ptr = htobe64(resp->payloadsz);
|
|
||||||
ptr += sizeof(size_t);
|
|
||||||
|
|
||||||
// Serialize payload
|
|
||||||
if (resp->payloadsz > 0 && resp->payload != NULL) {
|
|
||||||
memcpy(ptr, resp->payload, resp->payloadsz);
|
|
||||||
}
|
|
||||||
|
|
||||||
return total_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void psync_overlay_main_loop() {
|
void psync_overlay_main_loop() {
|
||||||
struct sockaddr_un addr;
|
struct sockaddr_un addr;
|
||||||
int fd, cl;
|
int fd, cl;
|
||||||
|
|
@ -144,8 +103,8 @@ void psync_overlay_handle_request(void *lpvParam) {
|
||||||
int readbytes; // total bytes read from request
|
int readbytes; // total bytes read from request
|
||||||
char rqbuf[POVERLAY_BUFSIZE]; // request buffer, contains the request message
|
char rqbuf[POVERLAY_BUFSIZE]; // request buffer, contains the request message
|
||||||
char *rqbufp; // request buffer ptr, for convenient iteration
|
char *rqbufp; // request buffer ptr, for convenient iteration
|
||||||
request_message *request; // request message
|
message *request; // request message
|
||||||
response_message *response; // response message and payload
|
message *response; // response message and payload
|
||||||
|
|
||||||
request = NULL;
|
request = NULL;
|
||||||
response = NULL;
|
response = NULL;
|
||||||
|
|
@ -159,7 +118,7 @@ void psync_overlay_handle_request(void *lpvParam) {
|
||||||
readbytes += rc;
|
readbytes += rc;
|
||||||
rqbufp = rqbufp + rc;
|
rqbufp = rqbufp + rc;
|
||||||
if (readbytes > 12) {
|
if (readbytes > 12) {
|
||||||
request = (request_message *)rqbuf;
|
request = (message *)rqbuf;
|
||||||
if (request->length == (uint64_t)readbytes)
|
if (request->length == (uint64_t)readbytes)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -172,50 +131,23 @@ void psync_overlay_handle_request(void *lpvParam) {
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
// allocate and initialize response message
|
request = (message *)rqbuf;
|
||||||
response = (response_message *)psync_malloc(sizeof(response_message));
|
response = (message *)malloc(POVERLAY_BUFSIZE);
|
||||||
memset(response, 0, sizeof(response_message));
|
|
||||||
response->msg = NULL;
|
|
||||||
response->payload = NULL;
|
|
||||||
response->payloadsz = 0;
|
|
||||||
|
|
||||||
// get the response for the request, and write the response to the
|
|
||||||
// sockfd.
|
|
||||||
request = (request_message *)rqbuf;
|
|
||||||
if (request) {
|
if (request) {
|
||||||
psync_overlay_get_response(request, response);
|
psync_overlay_get_response(request, response);
|
||||||
|
|
||||||
char *rsbufp;
|
ssize_t total_size = sizeof(uint32_t) + sizeof(uint64_t) + response->length;
|
||||||
size_t bytes_written = 0;
|
ssize_t bytes_written = write(*sockfd, response, total_size);
|
||||||
size_t responsesz = serialize_response_message(response, &rsbufp);
|
|
||||||
if (responsesz <= 0) {
|
if (bytes_written == -1) {
|
||||||
debug(D_ERROR, "failed to serialize response message");
|
debug(D_ERROR, "Failed to write to socket: %s", strerror(errno));
|
||||||
return;
|
return;
|
||||||
|
} else if (bytes_written < total_size) {
|
||||||
|
debug(D_ERROR, "Incomplete write to socket: wrote %zd of %zd bytes", bytes_written, total_size);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (bytes_written < responsesz) {
|
debug(D_NOTICE, "Successfully wrote %zd bytes to socket", bytes_written);
|
||||||
ssize_t written =
|
|
||||||
write(*sockfd, rsbufp + bytes_written, responsesz - bytes_written);
|
|
||||||
if (written == -1) {
|
|
||||||
if (errno == EINTR) {
|
|
||||||
// Interrupted by signal, try again
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
debug(D_ERROR, "failed to write to socket: %s", strerror(errno));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
bytes_written += written;
|
|
||||||
}
|
|
||||||
free(rsbufp);
|
|
||||||
if (bytes_written < responsesz) {
|
|
||||||
debug(D_ERROR, "failed to write entire message to socket");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
debug(D_NOTICE,
|
|
||||||
"Successfully sent full reply: %zu bytes structure, %zu bytes "
|
|
||||||
"additional data",
|
|
||||||
response->msg->length, response->payloadsz);
|
|
||||||
} else {
|
} else {
|
||||||
debug(D_ERROR, "No valid request received");
|
debug(D_ERROR, "No valid request received");
|
||||||
}
|
}
|
||||||
|
|
@ -225,12 +157,6 @@ cleanup:
|
||||||
close(*sockfd);
|
close(*sockfd);
|
||||||
}
|
}
|
||||||
if (response) {
|
if (response) {
|
||||||
if (response->msg) {
|
|
||||||
psync_free(response->msg);
|
|
||||||
}
|
|
||||||
if (response->payload) {
|
|
||||||
psync_free(response->payload);
|
|
||||||
}
|
|
||||||
psync_free(response);
|
psync_free(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -264,8 +190,8 @@ void psync_overlay_init_callbacks() {
|
||||||
memset(callbacks, 0, sizeof(poverlay_callback) * callbacks_size);
|
memset(callbacks, 0, sizeof(poverlay_callback) * callbacks_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void psync_overlay_get_status_response(request_message *request,
|
static void psync_overlay_get_status_response(message *request,
|
||||||
response_message *response,
|
message *response,
|
||||||
size_t available_space) {
|
size_t available_space) {
|
||||||
psync_path_status_t stat;
|
psync_path_status_t stat;
|
||||||
|
|
||||||
|
|
@ -276,56 +202,24 @@ static void psync_overlay_get_status_response(request_message *request,
|
||||||
}
|
}
|
||||||
switch (psync_path_status_get_status(stat)) {
|
switch (psync_path_status_get_status(stat)) {
|
||||||
case PSYNC_PATH_STATUS_IN_SYNC:
|
case PSYNC_PATH_STATUS_IN_SYNC:
|
||||||
response->msg->type = 10;
|
response->type = 10;
|
||||||
break;
|
break;
|
||||||
case PSYNC_PATH_STATUS_IN_PROG:
|
case PSYNC_PATH_STATUS_IN_PROG:
|
||||||
response->msg->type = 12;
|
response->type = 12;
|
||||||
break;
|
break;
|
||||||
case PSYNC_PATH_STATUS_PAUSED:
|
case PSYNC_PATH_STATUS_PAUSED:
|
||||||
case PSYNC_PATH_STATUS_REMOTE_FULL:
|
case PSYNC_PATH_STATUS_REMOTE_FULL:
|
||||||
case PSYNC_PATH_STATUS_LOCAL_FULL:
|
case PSYNC_PATH_STATUS_LOCAL_FULL:
|
||||||
response->msg->type = 11;
|
response->type = 11;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
response->msg->type = 13;
|
response->type = 13;
|
||||||
snprintf(response->msg->value, available_space, "No.");
|
snprintf(response->value, available_space, "No.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void psync_overlay_get_overlay_response(message *request,
|
||||||
psync_overlay_get_overlay_response_payload(request_message *request,
|
message *response,
|
||||||
response_message *response) {
|
|
||||||
if (!response->payload) {
|
|
||||||
response->payloadsz = 0;
|
|
||||||
debug(D_NOTICE, "Callback succeeded with no reply data");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (request->type == 23) {
|
|
||||||
// LISTSYNC
|
|
||||||
psync_folder_list_t *folders = (psync_folder_list_t *)response->payload;
|
|
||||||
response->payloadsz = sizeof(psync_folder_list_t) +
|
|
||||||
folders->foldercnt * sizeof(psync_folder_t);
|
|
||||||
} else if (request->type == 24) {
|
|
||||||
// ADDSYNC
|
|
||||||
response->payloadsz = sizeof(psync_syncid_t);
|
|
||||||
} else {
|
|
||||||
// default: response has no payload
|
|
||||||
response->payloadsz = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (response->payload == NULL) {
|
|
||||||
response->payloadsz = 0;
|
|
||||||
debug(D_NOTICE, "No reply data received");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
debug(D_NOTICE, "Callback succeeded with reply data, length: %zu",
|
|
||||||
response->payloadsz);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void psync_overlay_get_overlay_response(request_message *request,
|
|
||||||
response_message *response,
|
|
||||||
size_t available_space) {
|
size_t available_space) {
|
||||||
int cbidx; // callback index (based on message type)
|
int cbidx; // callback index (based on message type)
|
||||||
int cbret; // callback return value
|
int cbret; // callback return value
|
||||||
|
|
@ -335,44 +229,40 @@ static void psync_overlay_get_overlay_response(request_message *request,
|
||||||
|
|
||||||
if (!callbacks_running || (request->type >= ((uint32_t)calbacks_lower_band +
|
if (!callbacks_running || (request->type >= ((uint32_t)calbacks_lower_band +
|
||||||
(uint32_t)callbacks_size))) {
|
(uint32_t)callbacks_size))) {
|
||||||
response->msg->type = 13;
|
response->type = 13;
|
||||||
snprintf(response->msg->value, available_space, "Invalid type.");
|
snprintf(response->value, available_space, "Invalid type.");
|
||||||
debug(D_NOTICE, "Invalid request type: %u", request->type);
|
debug(D_NOTICE, "Invalid request type: %u", request->type);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!callbacks[cbidx]) {
|
if (!callbacks[cbidx]) {
|
||||||
response->msg->type = 13;
|
response->type = 13;
|
||||||
snprintf(response->msg->value, available_space,
|
snprintf(response->value, available_space,
|
||||||
"No callback with this id registered.");
|
"No callback with this id registered.");
|
||||||
debug(D_NOTICE, "No callback registered for type: %u", request->type);
|
debug(D_NOTICE, "No callback registered for type: %u", request->type);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cbret = callbacks[cbidx](request->value, &response->payload);
|
cbret = callbacks[cbidx](request->value);
|
||||||
if (cbret == 0) {
|
if (cbret == 0) {
|
||||||
response->msg->type = 0;
|
response->type = 0;
|
||||||
psync_overlay_get_overlay_response_payload(request, response);
|
|
||||||
} else {
|
} else {
|
||||||
response->msg->type = cbret;
|
response->type = cbret;
|
||||||
snprintf(response->msg->value, available_space,
|
snprintf(response->value, available_space,
|
||||||
"Callback returned error code.");
|
"Callback returned error code.");
|
||||||
debug(D_NOTICE, "Callback failed with return code: %d", cbret);
|
debug(D_NOTICE, "Callback failed with return code: %d", cbret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void psync_overlay_get_response(request_message *request,
|
void psync_overlay_get_response(message *request,
|
||||||
response_message *response) {
|
message *response) {
|
||||||
|
|
||||||
const char *dbgmsg; // debug messages
|
const char *dbgmsg; // debug messages
|
||||||
size_t value_avail; // space available to store value (flexible array)
|
size_t value_avail; // space available to store value (flexible array)
|
||||||
|
|
||||||
dbgmsg = NULL;
|
dbgmsg = NULL;
|
||||||
response->msg = (message *)psync_malloc(POVERLAY_BUFSIZE);
|
memset(response, 0, POVERLAY_BUFSIZE);
|
||||||
memset(response->msg, 0, POVERLAY_BUFSIZE);
|
response->length = 0;
|
||||||
response->msg->length = 0;
|
|
||||||
response->payload = NULL;
|
|
||||||
response->payloadsz = 0;
|
|
||||||
value_avail = POVERLAY_BUFSIZE - sizeof(message);
|
value_avail = POVERLAY_BUFSIZE - sizeof(message);
|
||||||
|
|
||||||
// never print the crypto password to the logs in plain text
|
// never print the crypto password to the logs in plain text
|
||||||
|
|
@ -388,21 +278,21 @@ void psync_overlay_get_response(request_message *request,
|
||||||
|
|
||||||
// a message with a type != 13 and a null string value after
|
// a message with a type != 13 and a null string value after
|
||||||
// processing is considered successful. set value to "Ok."
|
// processing is considered successful. set value to "Ok."
|
||||||
if (response->msg->type != 13 && response->msg->value[0] == '\0') {
|
if (response->type != 13 && response->value[0] == '\0') {
|
||||||
snprintf(response->msg->value, value_avail, "Ok.");
|
snprintf(response->value, value_avail, "Ok.");
|
||||||
} else {
|
} else {
|
||||||
debug(D_WARNING,
|
debug(D_WARNING,
|
||||||
"not updating value to Ok: response->msg->type=%d, "
|
"not updating value to Ok: response->msg->type=%d, "
|
||||||
"response->msg->value=%s",
|
"response->msg->value=%s",
|
||||||
response->msg->type, response->msg->value);
|
response->type, response->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// truncate messages that exceed the buffer boundaries
|
// truncate messages that exceed the buffer boundaries
|
||||||
size_t value_length = strnlen(response->msg->value, value_avail);
|
size_t value_length = strnlen(response->value, value_avail);
|
||||||
response->msg->length = sizeof(message) + value_length + 1;
|
response->length = sizeof(message) + value_length + 1;
|
||||||
if (response->msg->length > POVERLAY_BUFSIZE) {
|
if (response->length > POVERLAY_BUFSIZE) {
|
||||||
response->msg->length = POVERLAY_BUFSIZE;
|
response->length = POVERLAY_BUFSIZE;
|
||||||
response->msg->value[value_avail - 1] = '\0';
|
response->value[value_avail - 1] = '\0';
|
||||||
debug(D_WARNING, "Response message truncated to fit buffer");
|
debug(D_WARNING, "Response message truncated to fit buffer");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,8 +49,7 @@ extern int callbacks_running;
|
||||||
|
|
||||||
void psync_overlay_main_loop(VOID);
|
void psync_overlay_main_loop(VOID);
|
||||||
void psync_overlay_handle_request(LPVOID);
|
void psync_overlay_handle_request(LPVOID);
|
||||||
void psync_overlay_get_response(request_message *rq /*IN*/,
|
void psync_overlay_get_response(message*, message*);
|
||||||
response_message *rs /*OUT*/);
|
|
||||||
void psync_overlay_stop_overlays();
|
void psync_overlay_stop_overlays();
|
||||||
void psync_overlay_start_overlays();
|
void psync_overlay_start_overlays();
|
||||||
void psync_overlay_stop_overlay_callbacks();
|
void psync_overlay_stop_overlay_callbacks();
|
||||||
|
|
@ -59,6 +58,6 @@ int psync_overlay_overlays_running();
|
||||||
int psync_overlay_callbacks_running();
|
int psync_overlay_callbacks_running();
|
||||||
|
|
||||||
void psync_overlay_init_callbacks();
|
void psync_overlay_init_callbacks();
|
||||||
int psync_overlay_register_callback(int id, poverlay_callback callback);
|
int psync_overlay_register_callback(int, poverlay_callback);
|
||||||
|
|
||||||
#endif // POVERLAY_H
|
#endif // POVERLAY_H
|
||||||
|
|
|
||||||
|
|
@ -10,22 +10,10 @@
|
||||||
#define POVERLAY_SOCK_PATH "/tmp/pcloud_unix_soc.sock"
|
#define POVERLAY_SOCK_PATH "/tmp/pcloud_unix_soc.sock"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
typedef struct _message {
|
typedef struct _message {
|
||||||
uint32_t type;
|
uint32_t type;
|
||||||
uint64_t length;
|
uint64_t length;
|
||||||
char value[];
|
char value[];
|
||||||
} message;
|
} message;
|
||||||
|
|
||||||
// represents a request message
|
|
||||||
typedef message request_message;
|
|
||||||
|
|
||||||
// represents a response message; this includes the API response
|
|
||||||
// message and any payload data returned by the callback function.
|
|
||||||
typedef struct {
|
|
||||||
void *payload; // data returned by the callback function
|
|
||||||
size_t payloadsz; // size of payload
|
|
||||||
message *msg; // API response message
|
|
||||||
} response_message;
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -0,0 +1,129 @@
|
||||||
|
#include <sys/ipc.h>
|
||||||
|
#include <sys/shm.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
|
#include "pshm.h"
|
||||||
|
|
||||||
|
key_t pshm_get_key() {
|
||||||
|
char path[PATH_MAX];
|
||||||
|
char *home;
|
||||||
|
|
||||||
|
home = getenv("HOME");
|
||||||
|
if (home == NULL) {
|
||||||
|
debug(D_ERROR, "HOME environment variable is not set");
|
||||||
|
return (key_t)-1;
|
||||||
|
}
|
||||||
|
snprintf(path, sizeof(path), "%s/.pcloud/data.db", home);
|
||||||
|
|
||||||
|
return ftok(path, 'A');
|
||||||
|
}
|
||||||
|
|
||||||
|
int pshm_getid() {
|
||||||
|
key_t key;
|
||||||
|
|
||||||
|
key = pshm_get_key();
|
||||||
|
if(key == -1) {
|
||||||
|
debug(D_ERROR, "failed to get ipc key");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return shmget(key, PSYNC_SHM_SIZE, IPC_CREAT | 0666);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pshm_read(void **data, size_t *datasz) {
|
||||||
|
int shmid;
|
||||||
|
psync_shm *shm;
|
||||||
|
int flag;
|
||||||
|
char *dataArea;
|
||||||
|
|
||||||
|
shmid = pshm_getid();
|
||||||
|
if (shmid == -1) {
|
||||||
|
debug(D_ERROR, "Failed to get shared memory ID");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
shm = (psync_shm*)shmat(shmid, NULL, 0);
|
||||||
|
if (shm == (void*)-1) {
|
||||||
|
debug(D_ERROR, "Failed to attach to shared memory: %s", strerror(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
__atomic_load(&shm->flag, &flag, __ATOMIC_SEQ_CST);
|
||||||
|
if(flag != 1) {
|
||||||
|
shmdt(shm);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(datasz != NULL) {
|
||||||
|
*datasz = shm->datasz;
|
||||||
|
}
|
||||||
|
|
||||||
|
*data = malloc(shm->datasz);
|
||||||
|
if(*data == NULL) {
|
||||||
|
debug(D_ERROR, "Failed to allocate memory for shared data");
|
||||||
|
shmdt(shm);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
dataArea = (char *)shm + sizeof(psync_shm);
|
||||||
|
memcpy(*data, dataArea, shm->datasz);
|
||||||
|
|
||||||
|
__atomic_store_n(&shm->flag, 0, __ATOMIC_SEQ_CST);
|
||||||
|
|
||||||
|
shmdt(shm);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pshm_write(const void *data, size_t datasz) {
|
||||||
|
int shmid;
|
||||||
|
psync_shm* shm;
|
||||||
|
char *dataArea;
|
||||||
|
|
||||||
|
if (datasz > PSYNC_SHM_SIZE - sizeof(psync_shm)) {
|
||||||
|
debug(D_ERROR, "Data size exceeds available shared memory size");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
shmid = pshm_getid();
|
||||||
|
if (shmid == -1) {
|
||||||
|
debug(D_ERROR, "Failed to get shared memory ID");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
shm = (psync_shm*)shmat(shmid, NULL, 0);
|
||||||
|
if (shm == (void*)-1) {
|
||||||
|
debug(D_ERROR, "Failed to attach to shared memory: %s", strerror(errno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shm->flag == 0 && shm->datasz == 0) {
|
||||||
|
debug(D_NOTICE, "Initializing shared memory segment");
|
||||||
|
// Clear the structure first
|
||||||
|
memset(shm, 0, sizeof(psync_shm));
|
||||||
|
// Data area starts right after the structure
|
||||||
|
shm->data = (char *)shm + sizeof(psync_shm);
|
||||||
|
shm->datasz = 0;
|
||||||
|
shm->flag = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
dataArea = (char *)shm + sizeof(psync_shm);
|
||||||
|
memcpy(dataArea, data, datasz);
|
||||||
|
|
||||||
|
shm->datasz = datasz;
|
||||||
|
__atomic_store_n(&shm->flag, 1, __ATOMIC_SEQ_CST);
|
||||||
|
|
||||||
|
if (shmdt(shm) == -1) {
|
||||||
|
debug(D_ERROR, "Failed to detach from shared memory: %s", strerror(errno));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int pshm_cleanup() {
|
||||||
|
return shmctl(pshm_getid(), IPC_RMID, NULL);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
#ifndef __PSHM_H
|
||||||
|
|
||||||
|
#define __PSHM_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <sys/ipc.h>
|
||||||
|
|
||||||
|
#define PSYNC_SHM_SIZE 4096
|
||||||
|
|
||||||
|
// shm is used to get the return values from the underlying pcloud functions
|
||||||
|
// called by the overlay client. this is needed for cases such as
|
||||||
|
// list_sync_folders, where the result should be presented to the user in the
|
||||||
|
// CLI.
|
||||||
|
typedef struct _psync_shm {
|
||||||
|
void *data; // overlay callback return value
|
||||||
|
size_t datasz; // overlay return value size
|
||||||
|
volatile int flag; // new data available
|
||||||
|
} psync_shm;
|
||||||
|
|
||||||
|
void pshm_write(const void *data, size_t datasz);
|
||||||
|
bool pshm_read(void **data, size_t *datasz);
|
||||||
|
int pshm_cleanup();
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -71,6 +71,7 @@
|
||||||
#include "ppathstatus.h"
|
#include "ppathstatus.h"
|
||||||
#include "pscanner.h"
|
#include "pscanner.h"
|
||||||
#include "psettings.h"
|
#include "psettings.h"
|
||||||
|
#include "pshm.h"
|
||||||
#include "pssl.h"
|
#include "pssl.h"
|
||||||
#include "pstatus.h"
|
#include "pstatus.h"
|
||||||
#include "psyncer.h"
|
#include "psyncer.h"
|
||||||
|
|
@ -355,6 +356,9 @@ uint32_t psync_download_state() { return 0; }
|
||||||
|
|
||||||
void psync_destroy() {
|
void psync_destroy() {
|
||||||
psync_do_run = 0;
|
psync_do_run = 0;
|
||||||
|
if (pshm_cleanup() == -1) {
|
||||||
|
debug(D_ERROR, "failed to cleanup shm");
|
||||||
|
}
|
||||||
psync_fs_stop();
|
psync_fs_stop();
|
||||||
psync_terminate_status_waiters();
|
psync_terminate_status_waiters();
|
||||||
psync_send_status_update();
|
psync_send_status_update();
|
||||||
|
|
|
||||||
|
|
@ -1809,7 +1809,7 @@ void psync_get_folder_ownerid(psync_folderid_t folderid,
|
||||||
// void** pointer is null, then do not write any data back out for
|
// void** pointer is null, then do not write any data back out for
|
||||||
// the client.
|
// the client.
|
||||||
//
|
//
|
||||||
typedef int (*poverlay_callback)(const char *, void **);
|
typedef int (*poverlay_callback)(const char *);
|
||||||
|
|
||||||
/* Registers file manager extension callback that will be called when packet
|
/* Registers file manager extension callback that will be called when packet
|
||||||
* with id equals to the give one had arrived from extension. The id must be
|
* with id equals to the give one had arrived from extension. The id must be
|
||||||
|
|
|
||||||
|
|
@ -41,12 +41,15 @@
|
||||||
|
|
||||||
#include "poverlay.h"
|
#include "poverlay.h"
|
||||||
#include "psynclib.h"
|
#include "psynclib.h"
|
||||||
|
#include "pshm.h"
|
||||||
|
|
||||||
#include "pclsync_lib.h"
|
#include "pclsync_lib.h"
|
||||||
|
|
||||||
namespace cc = console_client;
|
namespace cc = console_client;
|
||||||
namespace clib = cc::clibrary;
|
namespace clib = cc::clibrary;
|
||||||
|
|
||||||
|
static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
static const std::string client_name = "pCloud CC v3.0.0";
|
static const std::string client_name = "pCloud CC v3.0.0";
|
||||||
|
|
||||||
clib::pclsync_lib::pclsync_lib()
|
clib::pclsync_lib::pclsync_lib()
|
||||||
|
|
@ -331,16 +334,13 @@ static void status_change(pstatus_t *status) {
|
||||||
psync_free(err);
|
psync_free(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
int clib::pclsync_lib::start_crypto(const char *pass, void **payload) {
|
int clib::pclsync_lib::start_crypto(const char *pass) {
|
||||||
(void)payload;
|
|
||||||
|
|
||||||
std::cout << "calling startcrypto pass: " << pass << std::endl;
|
std::cout << "calling startcrypto pass: " << pass << std::endl;
|
||||||
get_lib().crypto_pass_ = pass;
|
get_lib().crypto_pass_ = pass;
|
||||||
return lib_setup_cripto();
|
return lib_setup_cripto();
|
||||||
}
|
}
|
||||||
|
|
||||||
int clib::pclsync_lib::stop_crypto(const char *path, void **payload) {
|
int clib::pclsync_lib::stop_crypto(const char *path) {
|
||||||
(void)payload;
|
|
||||||
(void)path;
|
(void)path;
|
||||||
|
|
||||||
psync_crypto_stop();
|
psync_crypto_stop();
|
||||||
|
|
@ -348,20 +348,15 @@ int clib::pclsync_lib::stop_crypto(const char *path, void **payload) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int clib::pclsync_lib::finalize(const char *path, void **payload) {
|
int clib::pclsync_lib::finalize(const char *path) {
|
||||||
(void)payload;
|
|
||||||
(void)path;
|
(void)path;
|
||||||
|
|
||||||
psync_destroy();
|
psync_destroy();
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int clib::pclsync_lib::add_sync_folder(const char *path, void **payload) {
|
// path is the local and remote path delimited by '|'
|
||||||
if (payload == nullptr) {
|
int clib::pclsync_lib::add_sync_folder(const char *path) {
|
||||||
std::cerr << "Error: payload pointer is null" << std::endl;
|
|
||||||
return -255;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (path == nullptr) {
|
if (path == nullptr) {
|
||||||
std::cerr << "Error: path is nullptr" << std::endl;
|
std::cerr << "Error: path is nullptr" << std::endl;
|
||||||
return -255;
|
return -255;
|
||||||
|
|
@ -377,53 +372,48 @@ int clib::pclsync_lib::add_sync_folder(const char *path, void **payload) {
|
||||||
|
|
||||||
std::string localpath = combined.substr(0, delimiter_pos);
|
std::string localpath = combined.substr(0, delimiter_pos);
|
||||||
std::string remotepath = combined.substr(delimiter_pos + 1);
|
std::string remotepath = combined.substr(delimiter_pos + 1);
|
||||||
|
psync_syncid_t syncid = psync_add_sync_by_path(localpath.c_str(), remotepath.c_str(), PSYNC_FULL);
|
||||||
|
|
||||||
psync_syncid_t syncid =
|
pthread_mutex_lock(&mtx);
|
||||||
psync_add_sync_by_path(localpath.c_str(), remotepath.c_str(), PSYNC_FULL);
|
|
||||||
|
|
||||||
uint64_t *payload_ptr =
|
|
||||||
static_cast<uint64_t *>(psync_malloc(sizeof(uint64_t)));
|
|
||||||
if (payload_ptr == nullptr) {
|
|
||||||
std::cerr << "Error: Failed to allocate memory for payload" << std::endl;
|
|
||||||
return -255;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (syncid == PSYNC_INVALID_SYNCID) {
|
if (syncid == PSYNC_INVALID_SYNCID) {
|
||||||
std::cerr << "psync_add_sync_by_path returned PSYNC_INVALID_SYNCID"
|
std::cerr << "psync_add_sync_by_path returned PSYNC_INVALID_SYNCID" << std::endl;
|
||||||
<< std::endl;
|
uint64_t error_value = (static_cast<uint64_t>(1) << 32) | PSYNC_INVALID_SYNCID;
|
||||||
*payload_ptr = (static_cast<uint64_t>(1) << 32) |
|
pshm_write(&error_value, sizeof(uint64_t));
|
||||||
static_cast<uint32_t>(PSYNC_INVALID_SYNCID);
|
pthread_mutex_unlock(&mtx);
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
|
||||||
*payload_ptr = static_cast<uint64_t>(syncid);
|
|
||||||
}
|
}
|
||||||
*payload = payload_ptr;
|
pshm_write(&syncid, sizeof(psync_syncid_t));
|
||||||
|
pthread_mutex_unlock(&mtx);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int clib::pclsync_lib::remove_sync_folder(const char *path, void **payload) {
|
// path is the folderid to remove
|
||||||
(void)payload;
|
int clib::pclsync_lib::remove_sync_folder(const char *path) {
|
||||||
psync_folderid_t folderid;
|
psync_folderid_t folderid;
|
||||||
folderid = static_cast<psync_folderid_t>(std::stoull(path, nullptr, 10));
|
folderid = static_cast<psync_folderid_t>(std::stoull(path, nullptr, 10));
|
||||||
return psync_delete_sync_by_folderid(folderid);
|
return psync_delete_sync_by_folderid(folderid);
|
||||||
}
|
}
|
||||||
|
|
||||||
int clib::pclsync_lib::list_sync_folders(const char *path, void **payload) {
|
// path is not used
|
||||||
|
int clib::pclsync_lib::list_sync_folders(const char *path) {
|
||||||
(void)path;
|
(void)path;
|
||||||
|
|
||||||
psync_folder_list_t *folders = psync_get_sync_list();
|
psync_folder_list_t *folders;
|
||||||
|
size_t folderssz;
|
||||||
|
|
||||||
|
folders = psync_get_sync_list();
|
||||||
if (!folders) {
|
if (!folders) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
size_t alloc_size =
|
folderssz =
|
||||||
sizeof(*folders) + folders->foldercnt * sizeof(psync_folder_t);
|
sizeof(psync_folder_list_t) + (folders->foldercnt * sizeof(psync_folder_t));
|
||||||
*payload = psync_malloc(alloc_size);
|
|
||||||
if (*payload == NULL) {
|
pthread_mutex_lock(&mtx);
|
||||||
psync_free(folders);
|
pshm_write(folders, folderssz);
|
||||||
return -1;
|
pthread_mutex_unlock(&mtx);
|
||||||
}
|
|
||||||
memcpy(*payload, folders, alloc_size);
|
|
||||||
psync_free(folders);
|
psync_free(folders);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,12 +29,13 @@
|
||||||
/*
|
/*
|
||||||
Dependencies:
|
Dependencies:
|
||||||
- <string>
|
- <string>
|
||||||
- pclsync_lib_c.h
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PCLSYNC_LIB_H
|
#ifndef PCLSYNC_LIB_H
|
||||||
#define PCLSYNC_LIB_H
|
#define PCLSYNC_LIB_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
struct pstatus_struct_;
|
struct pstatus_struct_;
|
||||||
typedef void (*status_callback_t)(int status, const char *stat_string);
|
typedef void (*status_callback_t)(int status, const char *stat_string);
|
||||||
|
|
||||||
|
|
@ -88,12 +89,12 @@ public:
|
||||||
int init();
|
int init();
|
||||||
// std::string& username, std::string& password, std::string*
|
// std::string& username, std::string& password, std::string*
|
||||||
// crypto_pass, int setup_crypto = 1, int usesrypto_userpass = 0);
|
// crypto_pass, int setup_crypto = 1, int usesrypto_userpass = 0);
|
||||||
static int start_crypto(const char *pass, void **rep);
|
static int start_crypto(const char *pass);
|
||||||
static int stop_crypto(const char *path, void **rep);
|
static int stop_crypto(const char *path);
|
||||||
static int finalize(const char *path, void **rep);
|
static int finalize(const char *path);
|
||||||
static int list_sync_folders(const char *path, void **rep);
|
static int list_sync_folders(const char *path);
|
||||||
static int add_sync_folder(const char *path, void **rep);
|
static int add_sync_folder(const char *path);
|
||||||
static int remove_sync_folder(const char *path, void **rep);
|
static int remove_sync_folder(const char *path);
|
||||||
|
|
||||||
char *get_token();
|
char *get_token();
|
||||||
int logout();
|
int logout();
|
||||||
|
|
@ -107,6 +108,7 @@ private:
|
||||||
std::string crypto_pass_;
|
std::string crypto_pass_;
|
||||||
std::string mount_;
|
std::string mount_;
|
||||||
|
|
||||||
|
|
||||||
bool to_set_mount_;
|
bool to_set_mount_;
|
||||||
bool daemon_;
|
bool daemon_;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue