* 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
|
||||
**/*/.cache/
|
||||
compile_commands.json
|
||||
|
||||
compile_commands.events.json
|
||||
/cmd/pcloudcc/build/
|
||||
/.cache/
|
||||
/lib/poverlay_linux/overlay_client
|
||||
|
|
|
|||
|
|
@ -41,7 +41,8 @@
|
|||
#include "pclsync/overlay_client.h"
|
||||
|
||||
#include "pclsync_lib.h"
|
||||
#include "psynclib.h"
|
||||
#include "pclsync/psynclib.h"
|
||||
#include "pclsync/pshm.h"
|
||||
|
||||
#include "CLI11.hpp"
|
||||
|
||||
|
|
@ -60,62 +61,10 @@ enum command_ids_ {
|
|||
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 ret;
|
||||
char *errm;
|
||||
size_t errmsz;
|
||||
void *rep;
|
||||
size_t repsz;
|
||||
int result;
|
||||
psync_folder_list_t *flist;
|
||||
psync_folder_t *folder;
|
||||
|
|
@ -123,51 +72,50 @@ int list_sync_folders() {
|
|||
|
||||
errm = NULL;
|
||||
errmsz = 0;
|
||||
rep = NULL;
|
||||
repsz = 0;
|
||||
rval = 0;
|
||||
|
||||
result = SendCall(LISTSYNC, "", &ret, &errm, &errmsz, &rep, &repsz);
|
||||
result = SendCall(LISTSYNC, "", &ret, &errm, &errmsz);
|
||||
|
||||
if (result != 0) {
|
||||
std::cout << "List Sync Folders failed. return is " << ret
|
||||
<< " and message is " << (errm ? errm : "no message")
|
||||
<< std::endl;
|
||||
rval = result;
|
||||
} else if (rep && repsz > 0) {
|
||||
flist = static_cast<psync_folder_list_t *>(rep);
|
||||
}
|
||||
|
||||
if (repsz < sizeof(psync_folder_list_t)) {
|
||||
std::cout << "Error: Insufficient data for folder list structure"
|
||||
<< std::endl;
|
||||
rval = -1;
|
||||
} else {
|
||||
|
||||
const int id_width = 12;
|
||||
const int path_width = 30;
|
||||
if(pshm_read((void**)&flist, NULL)) {
|
||||
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::setw(path_width) << "Local Path"
|
||||
<< std::setw(path_width) << "Remote Path" << std::endl;
|
||||
std::cout << std::string(id_width, '-')
|
||||
<< std::string(path_width - 1, '-')
|
||||
<< std::string(path_width - 1, '-') << std::endl;
|
||||
|
||||
for (uint32_t i = 0; i < flist->foldercnt; i++) {
|
||||
folder = &flist->folders[i];
|
||||
std::cout << std::left << std::setw(id_width) << folder->folderid
|
||||
<< std::setw(path_width) << folder->localpath
|
||||
<< std::setw(path_width) << folder->remotepath << std::endl;
|
||||
}
|
||||
} else {
|
||||
std::cout << "No synchronized folders found." << std::endl;
|
||||
rval = ret;
|
||||
}
|
||||
} else {
|
||||
std::cout << "No synchronized folders found." << std::endl;
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -176,7 +124,8 @@ int start_crypto(const char *pass) {
|
|||
char *errm;
|
||||
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) {
|
||||
std::cout << "Start Crypto failed. return is " << ret << " and message is "
|
||||
<< (errm ? errm : "no message") << std::endl;
|
||||
|
|
@ -193,7 +142,7 @@ int stop_crypto() {
|
|||
char *errm;
|
||||
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) {
|
||||
std::cout << "Stop Crypto failed. return is " << ret << " and message is "
|
||||
<< (errm ? errm : "no message") << std::endl;
|
||||
|
|
@ -217,7 +166,7 @@ int remove_sync_folder(const char *folderid) {
|
|||
errmsz = 0;
|
||||
rval = 0;
|
||||
|
||||
result = SendCall(STOPSYNC, folderid, &ret, &errm, &errmsz, NULL, NULL);
|
||||
result = SendCall(STOPSYNC, folderid, &ret, &errm, &errmsz);
|
||||
if (result != 0) {
|
||||
std::cout << "Remove Sync Folder failed with unknown error. return is "
|
||||
<< 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::endl;
|
||||
}
|
||||
free(errm);
|
||||
|
||||
if(errm) {
|
||||
free(errm);
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
|
|
@ -237,20 +189,15 @@ int add_sync_folder(std::string localpath, std::string remotepath) {
|
|||
int ret;
|
||||
char *errm;
|
||||
size_t errmsz;
|
||||
void *rep;
|
||||
size_t repsz;
|
||||
int result;
|
||||
int rval;
|
||||
|
||||
errm = NULL;
|
||||
errmsz = 0;
|
||||
rep = NULL;
|
||||
repsz = 0;
|
||||
rval = 0;
|
||||
|
||||
std::string combinedPaths = localpath + '|' + remotepath;
|
||||
result = SendCall(ADDSYNC, combinedPaths.c_str(), &ret, &errm, &errmsz, &rep,
|
||||
&repsz);
|
||||
result = SendCall(ADDSYNC, combinedPaths.c_str(), &ret, &errm, &errmsz);
|
||||
|
||||
if (result != 0) {
|
||||
if (result == -1) {
|
||||
|
|
@ -262,22 +209,14 @@ int add_sync_folder(std::string localpath, std::string remotepath) {
|
|||
<< std::endl;
|
||||
}
|
||||
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 {
|
||||
std::cout << "Error: Did not get a syncid from add_sync_folder."
|
||||
<< std::endl;
|
||||
rval = ret;
|
||||
}
|
||||
|
||||
free(errm);
|
||||
free(rep);
|
||||
if(errm) {
|
||||
free(errm);
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
|
|
@ -286,11 +225,12 @@ int finalize() {
|
|||
char *errm;
|
||||
size_t errm_size;
|
||||
|
||||
SendCall(FINALIZE, "", &ret, &errm, &errm_size, NULL, NULL);
|
||||
SendCall(FINALIZE, "", &ret, &errm, &errm_size);
|
||||
std::cout << "Exiting ..." << std::endl;
|
||||
|
||||
if (errm)
|
||||
free(errm);
|
||||
if (errm){
|
||||
free(errm);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,8 +26,7 @@ that gets created when the server is started.
|
|||
socket -> poverlay : request
|
||||
poverlay -> poverlay : poverlay_handle_request
|
||||
poverlay -> poverlay : poverlay_get_response
|
||||
poverlay -> poverlay : serialize_response_message
|
||||
poverlay -> socket : response (serialized)
|
||||
poverlay -> socket : response
|
||||
socket -> overlay_client : read_response
|
||||
overlay_client -> control_tools : (msg, msgsz, payload, payloadsz)
|
||||
control_tools -> user : print results
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@
|
|||
#include "overlay_client.h"
|
||||
#include "poverlay_protocol.h"
|
||||
|
||||
#define POVERLAY_BUFSIZE 16 * 1024
|
||||
#define POVERLAY_BUFSIZE 512
|
||||
|
||||
// for easier error tracing...
|
||||
#define POVERLAY_SOCKET_CREATE_FAILED -100
|
||||
|
|
@ -73,106 +73,8 @@
|
|||
#define POVERLAY_READ_INCOMPLETE -105
|
||||
#define POVERLAY_READ_INVALID_RESPONSE -106
|
||||
|
||||
response_message *deserialize_response_message(const char *buffer,
|
||||
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) {
|
||||
void free_response_message(message *resp) {
|
||||
if (resp) {
|
||||
free(resp->msg);
|
||||
free(resp->payload);
|
||||
free(resp);
|
||||
}
|
||||
}
|
||||
|
|
@ -182,7 +84,7 @@ int QueryState(pCloud_FileState *state, char *path) {
|
|||
char *errm;
|
||||
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);
|
||||
if (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;
|
||||
char *buf;
|
||||
const char *err;
|
||||
request_message *request;
|
||||
message *request;
|
||||
char *curbuf;
|
||||
|
||||
*ret = 0; // Initialize ret to 0
|
||||
|
||||
len = strlen(value);
|
||||
size = sizeof(request_message) + len + 1;
|
||||
size = sizeof(message) + len + 1;
|
||||
buf = (char *)malloc(size);
|
||||
request = (request_message *)buf;
|
||||
request = (message *)buf;
|
||||
memset(request, 0, size);
|
||||
request->type = msgtype;
|
||||
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
|
||||
// size to out_size), a "ret" value to ret (redundant?), and the
|
||||
// callback's return data to payload and payloadsz.
|
||||
int read_response(int fd, char **out, size_t *out_size, int *ret,
|
||||
void **payload, size_t *payloadsz) {
|
||||
char buffer[POVERLAY_BUFSIZE];
|
||||
ssize_t bytes_read = read(fd, buffer, POVERLAY_BUFSIZE);
|
||||
int read_response(int fd, char **out, size_t *out_size, int *ret) {
|
||||
message *msg;
|
||||
ssize_t bytes_read;
|
||||
|
||||
if (bytes_read <= 0) {
|
||||
const char *error_msg =
|
||||
(bytes_read == 0) ? "Connection closed" : strerror(errno);
|
||||
*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);
|
||||
msg = (message *)malloc(POVERLAY_BUFSIZE);
|
||||
if (msg == 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(*payload, resp->payload, resp->payloadsz);
|
||||
*payloadsz = resp->payloadsz;
|
||||
} else {
|
||||
*payload = NULL;
|
||||
*payloadsz = 0;
|
||||
}
|
||||
}
|
||||
|
||||
free_response_message(resp);
|
||||
return 0;
|
||||
bytes_read = read(fd, msg, POVERLAY_BUFSIZE);
|
||||
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*/,
|
||||
char **out /*OUT*/, size_t *out_size, void **reply_data,
|
||||
size_t *reply_size) {
|
||||
// path contains the input argument(s).
|
||||
int SendCall(int id, const char *path, int *ret, char **errm, size_t *errmsz) {
|
||||
int result;
|
||||
int sockfd;
|
||||
|
||||
sockfd = -1;
|
||||
result = 0;
|
||||
*out = NULL;
|
||||
*out_size = 0;
|
||||
*errm = NULL;
|
||||
*errmsz = 0;
|
||||
*ret = 0;
|
||||
|
||||
// side effects: modify out, out_size, ret
|
||||
sockfd = socket_connect(POVERLAY_SOCK_PATH, out, out_size, ret);
|
||||
sockfd = socket_connect(POVERLAY_SOCK_PATH, errm, errmsz, ret);
|
||||
if (sockfd >= 0) {
|
||||
// side effects: modify out, out_size, ret
|
||||
if ((result = write_request(sockfd, id, path, out, out_size, ret)) == 0) {
|
||||
// side effects: modify out, out_size, ret, reply_data, reply_size
|
||||
result =
|
||||
read_response(sockfd, out, out_size, ret, reply_data, reply_size);
|
||||
if ((result = write_request(sockfd, id, path, errm, errmsz, ret)) == 0) {
|
||||
result = read_response(sockfd, errm, errmsz, ret);
|
||||
}
|
||||
close(sockfd);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -48,11 +48,9 @@ typedef enum _pCloud_FileState {
|
|||
FileStateInvalid
|
||||
} 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
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -925,3 +925,4 @@ psync_folder_list_t *psync_list_get_list(char *syncTypes) {
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -55,47 +55,6 @@
|
|||
int overlays_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() {
|
||||
struct sockaddr_un addr;
|
||||
int fd, cl;
|
||||
|
|
@ -144,8 +103,8 @@ void psync_overlay_handle_request(void *lpvParam) {
|
|||
int readbytes; // total bytes read from request
|
||||
char rqbuf[POVERLAY_BUFSIZE]; // request buffer, contains the request message
|
||||
char *rqbufp; // request buffer ptr, for convenient iteration
|
||||
request_message *request; // request message
|
||||
response_message *response; // response message and payload
|
||||
message *request; // request message
|
||||
message *response; // response message and payload
|
||||
|
||||
request = NULL;
|
||||
response = NULL;
|
||||
|
|
@ -159,7 +118,7 @@ void psync_overlay_handle_request(void *lpvParam) {
|
|||
readbytes += rc;
|
||||
rqbufp = rqbufp + rc;
|
||||
if (readbytes > 12) {
|
||||
request = (request_message *)rqbuf;
|
||||
request = (message *)rqbuf;
|
||||
if (request->length == (uint64_t)readbytes)
|
||||
break;
|
||||
}
|
||||
|
|
@ -172,50 +131,23 @@ void psync_overlay_handle_request(void *lpvParam) {
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
// allocate and initialize response message
|
||||
response = (response_message *)psync_malloc(sizeof(response_message));
|
||||
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;
|
||||
request = (message *)rqbuf;
|
||||
response = (message *)malloc(POVERLAY_BUFSIZE);
|
||||
if (request) {
|
||||
psync_overlay_get_response(request, response);
|
||||
|
||||
char *rsbufp;
|
||||
size_t bytes_written = 0;
|
||||
size_t responsesz = serialize_response_message(response, &rsbufp);
|
||||
if (responsesz <= 0) {
|
||||
debug(D_ERROR, "failed to serialize response message");
|
||||
return;
|
||||
ssize_t total_size = sizeof(uint32_t) + sizeof(uint64_t) + response->length;
|
||||
ssize_t bytes_written = write(*sockfd, response, total_size);
|
||||
|
||||
if (bytes_written == -1) {
|
||||
debug(D_ERROR, "Failed to write to socket: %s", strerror(errno));
|
||||
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) {
|
||||
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);
|
||||
debug(D_NOTICE, "Successfully wrote %zd bytes to socket", bytes_written);
|
||||
} else {
|
||||
debug(D_ERROR, "No valid request received");
|
||||
}
|
||||
|
|
@ -225,12 +157,6 @@ cleanup:
|
|||
close(*sockfd);
|
||||
}
|
||||
if (response) {
|
||||
if (response->msg) {
|
||||
psync_free(response->msg);
|
||||
}
|
||||
if (response->payload) {
|
||||
psync_free(response->payload);
|
||||
}
|
||||
psync_free(response);
|
||||
}
|
||||
|
||||
|
|
@ -264,8 +190,8 @@ void psync_overlay_init_callbacks() {
|
|||
memset(callbacks, 0, sizeof(poverlay_callback) * callbacks_size);
|
||||
}
|
||||
|
||||
static void psync_overlay_get_status_response(request_message *request,
|
||||
response_message *response,
|
||||
static void psync_overlay_get_status_response(message *request,
|
||||
message *response,
|
||||
size_t available_space) {
|
||||
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)) {
|
||||
case PSYNC_PATH_STATUS_IN_SYNC:
|
||||
response->msg->type = 10;
|
||||
response->type = 10;
|
||||
break;
|
||||
case PSYNC_PATH_STATUS_IN_PROG:
|
||||
response->msg->type = 12;
|
||||
response->type = 12;
|
||||
break;
|
||||
case PSYNC_PATH_STATUS_PAUSED:
|
||||
case PSYNC_PATH_STATUS_REMOTE_FULL:
|
||||
case PSYNC_PATH_STATUS_LOCAL_FULL:
|
||||
response->msg->type = 11;
|
||||
response->type = 11;
|
||||
break;
|
||||
default:
|
||||
response->msg->type = 13;
|
||||
snprintf(response->msg->value, available_space, "No.");
|
||||
response->type = 13;
|
||||
snprintf(response->value, available_space, "No.");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
psync_overlay_get_overlay_response_payload(request_message *request,
|
||||
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,
|
||||
static void psync_overlay_get_overlay_response(message *request,
|
||||
message *response,
|
||||
size_t available_space) {
|
||||
int cbidx; // callback index (based on message type)
|
||||
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 +
|
||||
(uint32_t)callbacks_size))) {
|
||||
response->msg->type = 13;
|
||||
snprintf(response->msg->value, available_space, "Invalid type.");
|
||||
response->type = 13;
|
||||
snprintf(response->value, available_space, "Invalid type.");
|
||||
debug(D_NOTICE, "Invalid request type: %u", request->type);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!callbacks[cbidx]) {
|
||||
response->msg->type = 13;
|
||||
snprintf(response->msg->value, available_space,
|
||||
response->type = 13;
|
||||
snprintf(response->value, available_space,
|
||||
"No callback with this id registered.");
|
||||
debug(D_NOTICE, "No callback registered for type: %u", request->type);
|
||||
return;
|
||||
}
|
||||
|
||||
cbret = callbacks[cbidx](request->value, &response->payload);
|
||||
cbret = callbacks[cbidx](request->value);
|
||||
if (cbret == 0) {
|
||||
response->msg->type = 0;
|
||||
psync_overlay_get_overlay_response_payload(request, response);
|
||||
response->type = 0;
|
||||
} else {
|
||||
response->msg->type = cbret;
|
||||
snprintf(response->msg->value, available_space,
|
||||
response->type = cbret;
|
||||
snprintf(response->value, available_space,
|
||||
"Callback returned error code.");
|
||||
debug(D_NOTICE, "Callback failed with return code: %d", cbret);
|
||||
}
|
||||
}
|
||||
|
||||
void psync_overlay_get_response(request_message *request,
|
||||
response_message *response) {
|
||||
void psync_overlay_get_response(message *request,
|
||||
message *response) {
|
||||
|
||||
const char *dbgmsg; // debug messages
|
||||
size_t value_avail; // space available to store value (flexible array)
|
||||
|
||||
dbgmsg = NULL;
|
||||
response->msg = (message *)psync_malloc(POVERLAY_BUFSIZE);
|
||||
memset(response->msg, 0, POVERLAY_BUFSIZE);
|
||||
response->msg->length = 0;
|
||||
response->payload = NULL;
|
||||
response->payloadsz = 0;
|
||||
memset(response, 0, POVERLAY_BUFSIZE);
|
||||
response->length = 0;
|
||||
value_avail = POVERLAY_BUFSIZE - sizeof(message);
|
||||
|
||||
// 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
|
||||
// processing is considered successful. set value to "Ok."
|
||||
if (response->msg->type != 13 && response->msg->value[0] == '\0') {
|
||||
snprintf(response->msg->value, value_avail, "Ok.");
|
||||
if (response->type != 13 && response->value[0] == '\0') {
|
||||
snprintf(response->value, value_avail, "Ok.");
|
||||
} else {
|
||||
debug(D_WARNING,
|
||||
"not updating value to Ok: response->msg->type=%d, "
|
||||
"response->msg->value=%s",
|
||||
response->msg->type, response->msg->value);
|
||||
response->type, response->value);
|
||||
}
|
||||
|
||||
// truncate messages that exceed the buffer boundaries
|
||||
size_t value_length = strnlen(response->msg->value, value_avail);
|
||||
response->msg->length = sizeof(message) + value_length + 1;
|
||||
if (response->msg->length > POVERLAY_BUFSIZE) {
|
||||
response->msg->length = POVERLAY_BUFSIZE;
|
||||
response->msg->value[value_avail - 1] = '\0';
|
||||
size_t value_length = strnlen(response->value, value_avail);
|
||||
response->length = sizeof(message) + value_length + 1;
|
||||
if (response->length > POVERLAY_BUFSIZE) {
|
||||
response->length = POVERLAY_BUFSIZE;
|
||||
response->value[value_avail - 1] = '\0';
|
||||
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_handle_request(LPVOID);
|
||||
void psync_overlay_get_response(request_message *rq /*IN*/,
|
||||
response_message *rs /*OUT*/);
|
||||
void psync_overlay_get_response(message*, message*);
|
||||
void psync_overlay_stop_overlays();
|
||||
void psync_overlay_start_overlays();
|
||||
void psync_overlay_stop_overlay_callbacks();
|
||||
|
|
@ -59,6 +58,6 @@ int psync_overlay_overlays_running();
|
|||
int psync_overlay_callbacks_running();
|
||||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -10,22 +10,10 @@
|
|||
#define POVERLAY_SOCK_PATH "/tmp/pcloud_unix_soc.sock"
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct _message {
|
||||
uint32_t type;
|
||||
uint64_t length;
|
||||
char value[];
|
||||
} 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
|
||||
|
|
@ -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 "pscanner.h"
|
||||
#include "psettings.h"
|
||||
#include "pshm.h"
|
||||
#include "pssl.h"
|
||||
#include "pstatus.h"
|
||||
#include "psyncer.h"
|
||||
|
|
@ -355,6 +356,9 @@ uint32_t psync_download_state() { return 0; }
|
|||
|
||||
void psync_destroy() {
|
||||
psync_do_run = 0;
|
||||
if (pshm_cleanup() == -1) {
|
||||
debug(D_ERROR, "failed to cleanup shm");
|
||||
}
|
||||
psync_fs_stop();
|
||||
psync_terminate_status_waiters();
|
||||
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
|
||||
// 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
|
||||
* with id equals to the give one had arrived from extension. The id must be
|
||||
|
|
|
|||
|
|
@ -41,12 +41,15 @@
|
|||
|
||||
#include "poverlay.h"
|
||||
#include "psynclib.h"
|
||||
#include "pshm.h"
|
||||
|
||||
#include "pclsync_lib.h"
|
||||
|
||||
namespace cc = console_client;
|
||||
namespace clib = cc::clibrary;
|
||||
|
||||
static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
static const std::string client_name = "pCloud CC v3.0.0";
|
||||
|
||||
clib::pclsync_lib::pclsync_lib()
|
||||
|
|
@ -331,16 +334,13 @@ static void status_change(pstatus_t *status) {
|
|||
psync_free(err);
|
||||
}
|
||||
|
||||
int clib::pclsync_lib::start_crypto(const char *pass, void **payload) {
|
||||
(void)payload;
|
||||
|
||||
int clib::pclsync_lib::start_crypto(const char *pass) {
|
||||
std::cout << "calling startcrypto pass: " << pass << std::endl;
|
||||
get_lib().crypto_pass_ = pass;
|
||||
return lib_setup_cripto();
|
||||
}
|
||||
|
||||
int clib::pclsync_lib::stop_crypto(const char *path, void **payload) {
|
||||
(void)payload;
|
||||
int clib::pclsync_lib::stop_crypto(const char *path) {
|
||||
(void)path;
|
||||
|
||||
psync_crypto_stop();
|
||||
|
|
@ -348,20 +348,15 @@ int clib::pclsync_lib::stop_crypto(const char *path, void **payload) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int clib::pclsync_lib::finalize(const char *path, void **payload) {
|
||||
(void)payload;
|
||||
int clib::pclsync_lib::finalize(const char *path) {
|
||||
(void)path;
|
||||
|
||||
psync_destroy();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int clib::pclsync_lib::add_sync_folder(const char *path, void **payload) {
|
||||
if (payload == nullptr) {
|
||||
std::cerr << "Error: payload pointer is null" << std::endl;
|
||||
return -255;
|
||||
}
|
||||
|
||||
// path is the local and remote path delimited by '|'
|
||||
int clib::pclsync_lib::add_sync_folder(const char *path) {
|
||||
if (path == nullptr) {
|
||||
std::cerr << "Error: path is nullptr" << std::endl;
|
||||
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 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 =
|
||||
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;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&mtx);
|
||||
if (syncid == PSYNC_INVALID_SYNCID) {
|
||||
std::cerr << "psync_add_sync_by_path returned PSYNC_INVALID_SYNCID"
|
||||
<< std::endl;
|
||||
*payload_ptr = (static_cast<uint64_t>(1) << 32) |
|
||||
static_cast<uint32_t>(PSYNC_INVALID_SYNCID);
|
||||
return -1;
|
||||
} else {
|
||||
*payload_ptr = static_cast<uint64_t>(syncid);
|
||||
std::cerr << "psync_add_sync_by_path returned PSYNC_INVALID_SYNCID" << std::endl;
|
||||
uint64_t error_value = (static_cast<uint64_t>(1) << 32) | PSYNC_INVALID_SYNCID;
|
||||
pshm_write(&error_value, sizeof(uint64_t));
|
||||
pthread_mutex_unlock(&mtx);
|
||||
return -1;
|
||||
}
|
||||
*payload = payload_ptr;
|
||||
pshm_write(&syncid, sizeof(psync_syncid_t));
|
||||
pthread_mutex_unlock(&mtx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int clib::pclsync_lib::remove_sync_folder(const char *path, void **payload) {
|
||||
(void)payload;
|
||||
// path is the folderid to remove
|
||||
int clib::pclsync_lib::remove_sync_folder(const char *path) {
|
||||
psync_folderid_t folderid;
|
||||
folderid = static_cast<psync_folderid_t>(std::stoull(path, nullptr, 10));
|
||||
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;
|
||||
|
||||
psync_folder_list_t *folders = psync_get_sync_list();
|
||||
psync_folder_list_t *folders;
|
||||
size_t folderssz;
|
||||
|
||||
folders = psync_get_sync_list();
|
||||
if (!folders) {
|
||||
return -1;
|
||||
}
|
||||
size_t alloc_size =
|
||||
sizeof(*folders) + folders->foldercnt * sizeof(psync_folder_t);
|
||||
*payload = psync_malloc(alloc_size);
|
||||
if (*payload == NULL) {
|
||||
psync_free(folders);
|
||||
return -1;
|
||||
}
|
||||
memcpy(*payload, folders, alloc_size);
|
||||
folderssz =
|
||||
sizeof(psync_folder_list_t) + (folders->foldercnt * sizeof(psync_folder_t));
|
||||
|
||||
pthread_mutex_lock(&mtx);
|
||||
pshm_write(folders, folderssz);
|
||||
pthread_mutex_unlock(&mtx);
|
||||
|
||||
psync_free(folders);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,12 +29,13 @@
|
|||
/*
|
||||
Dependencies:
|
||||
- <string>
|
||||
- pclsync_lib_c.h
|
||||
*/
|
||||
|
||||
#ifndef PCLSYNC_LIB_H
|
||||
#define PCLSYNC_LIB_H
|
||||
|
||||
#include <string>
|
||||
|
||||
struct pstatus_struct_;
|
||||
typedef void (*status_callback_t)(int status, const char *stat_string);
|
||||
|
||||
|
|
@ -88,12 +89,12 @@ public:
|
|||
int init();
|
||||
// std::string& username, std::string& password, std::string*
|
||||
// crypto_pass, int setup_crypto = 1, int usesrypto_userpass = 0);
|
||||
static int start_crypto(const char *pass, void **rep);
|
||||
static int stop_crypto(const char *path, void **rep);
|
||||
static int finalize(const char *path, void **rep);
|
||||
static int list_sync_folders(const char *path, void **rep);
|
||||
static int add_sync_folder(const char *path, void **rep);
|
||||
static int remove_sync_folder(const char *path, void **rep);
|
||||
static int start_crypto(const char *pass);
|
||||
static int stop_crypto(const char *path);
|
||||
static int finalize(const char *path);
|
||||
static int list_sync_folders(const char *path);
|
||||
static int add_sync_folder(const char *path);
|
||||
static int remove_sync_folder(const char *path);
|
||||
|
||||
char *get_token();
|
||||
int logout();
|
||||
|
|
@ -107,6 +108,7 @@ private:
|
|||
std::string crypto_pass_;
|
||||
std::string mount_;
|
||||
|
||||
|
||||
bool to_set_mount_;
|
||||
bool daemon_;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue