x11: refactor fuse code
This commit is contained in:
parent
e7d2f62ce6
commit
b972d70a9e
@ -42,7 +42,6 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#define WIN32_FILETIME_TO_UNIX_EPOCH_USEC UINT64_C(116444736000000000)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <winpr/crt.h>
|
#include <winpr/crt.h>
|
||||||
@ -61,6 +60,7 @@
|
|||||||
#define TAG CLIENT_TAG("x11")
|
#define TAG CLIENT_TAG("x11")
|
||||||
|
|
||||||
#define MAX_CLIPBOARD_FORMATS 255
|
#define MAX_CLIPBOARD_FORMATS 255
|
||||||
|
#define WIN32_FILETIME_TO_UNIX_EPOCH_USEC UINT64_C(116444736000000000)
|
||||||
|
|
||||||
struct xf_cliprdr_format
|
struct xf_cliprdr_format
|
||||||
{
|
{
|
||||||
@ -77,8 +77,8 @@ struct xf_cliprdr_fuse_stream
|
|||||||
/* must be one of FILECONTENTS_SIZE or FILECONTENTS_RANGE*/
|
/* must be one of FILECONTENTS_SIZE or FILECONTENTS_RANGE*/
|
||||||
UINT32 req_type;
|
UINT32 req_type;
|
||||||
fuse_req_t req;
|
fuse_req_t req;
|
||||||
/*for FILECONTENTS_SIZE must be xfCliprdrFuseInode* */
|
/*for FILECONTENTS_SIZE must be ino number* */
|
||||||
void* req_data;
|
size_t req_ino;
|
||||||
};
|
};
|
||||||
typedef struct xf_cliprdr_fuse_stream xfCliprdrFuseStream;
|
typedef struct xf_cliprdr_fuse_stream xfCliprdrFuseStream;
|
||||||
|
|
||||||
@ -108,8 +108,9 @@ void xf_cliprdr_fuse_inode_free(void* obj)
|
|||||||
inode->name = NULL;
|
inode->name = NULL;
|
||||||
inode->child_inos = NULL;
|
inode->child_inos = NULL;
|
||||||
free(inode);
|
free(inode);
|
||||||
inode = NULL;
|
|
||||||
}
|
}
|
||||||
|
static inline xfCliprdrFuseInode* xf_cliprdr_fuse_util_get_inode(wArrayList* ino_list,
|
||||||
|
fuse_ino_t ino);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct xf_clipboard
|
struct xf_clipboard
|
||||||
@ -1323,23 +1324,46 @@ xf_cliprdr_server_file_contents_response(CliprdrClientContext* context,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!found)
|
||||||
if (found)
|
|
||||||
{
|
{
|
||||||
switch (stream->req_type)
|
ArrayList_Unlock(clipboard->stream_list);
|
||||||
|
return CHANNEL_RC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
fuse_req_t req = stream->req;
|
||||||
|
UINT32 req_type = stream->req_type;
|
||||||
|
size_t req_ino = stream->req_ino;
|
||||||
|
|
||||||
|
ArrayList_RemoveAt(clipboard->stream_list, index);
|
||||||
|
ArrayList_Unlock(clipboard->stream_list);
|
||||||
|
|
||||||
|
switch (req_type)
|
||||||
{
|
{
|
||||||
case FILECONTENTS_SIZE:
|
case FILECONTENTS_SIZE:
|
||||||
ino = (xfCliprdrFuseInode*)stream->req_data;
|
/* fileContentsResponse->cbRequested should be 64bit*/
|
||||||
/** ino must be exists and fileContentsResponse->cbRequested should be 64bit */
|
if (data_len != sizeof(UINT64))
|
||||||
if (!ino || data_len != sizeof(UINT64))
|
|
||||||
{
|
{
|
||||||
fuse_reply_err(stream->req, EIO);
|
fuse_reply_err(req, EIO);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
UINT64 size;
|
UINT64 size;
|
||||||
wStream* s = Stream_New((BYTE*)data, data_len);
|
wStream* s = Stream_New((BYTE*)data, data_len);
|
||||||
|
if (!s)
|
||||||
|
{
|
||||||
|
fuse_reply_err(req, ENOMEM);
|
||||||
|
break;
|
||||||
|
}
|
||||||
Stream_Read_UINT64(s, size);
|
Stream_Read_UINT64(s, size);
|
||||||
Stream_Free(s, FALSE);
|
Stream_Free(s, FALSE);
|
||||||
|
ArrayList_Lock(clipboard->ino_list);
|
||||||
|
ino = xf_cliprdr_fuse_util_get_inode(clipboard->ino_list, req_ino);
|
||||||
|
/* ino must be exists and */
|
||||||
|
if (!ino)
|
||||||
|
{
|
||||||
|
ArrayList_Unlock(clipboard->ino_list);
|
||||||
|
fuse_reply_err(req, EIO);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
ino->st_size = size;
|
ino->st_size = size;
|
||||||
ino->size_set = TRUE;
|
ino->size_set = TRUE;
|
||||||
@ -1353,15 +1377,13 @@ xf_cliprdr_server_file_contents_response(CliprdrClientContext* context,
|
|||||||
e.attr.st_nlink = 1;
|
e.attr.st_nlink = 1;
|
||||||
e.attr.st_size = ino->st_size;
|
e.attr.st_size = ino->st_size;
|
||||||
e.attr.st_mtime = ino->st_mtim.tv_sec;
|
e.attr.st_mtime = ino->st_mtim.tv_sec;
|
||||||
fuse_reply_entry(stream->req, &e);
|
ArrayList_Unlock(clipboard->ino_list);
|
||||||
|
fuse_reply_entry(req, &e);
|
||||||
break;
|
break;
|
||||||
case FILECONTENTS_RANGE:
|
case FILECONTENTS_RANGE:
|
||||||
fuse_reply_buf(stream->req, (const char*)data, data_len);
|
fuse_reply_buf(req, (const char*)data, data_len);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ArrayList_RemoveAt(clipboard->stream_list, index);
|
|
||||||
}
|
|
||||||
ArrayList_Unlock(clipboard->stream_list);
|
|
||||||
return CHANNEL_RC_OK;
|
return CHANNEL_RC_OK;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1611,22 +1633,31 @@ static char* xf_cliprdr_fuse_split_basename(char* name, int len)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
static xfCliprdrFuseInode* xf_cliprdr_fuse_create_root_node()
|
||||||
* Generate inode list for fuse
|
|
||||||
*
|
|
||||||
* @return TRUE on success, FALSE on fail
|
|
||||||
*/
|
|
||||||
static BOOL xf_cliprdr_fuse_generate_list(xfClipboard* clipboard, const BYTE* data, UINT32 size)
|
|
||||||
{
|
{
|
||||||
if (size < 4)
|
xfCliprdrFuseInode* rootNode = (xfCliprdrFuseInode*)calloc(1, sizeof(xfCliprdrFuseInode));
|
||||||
{
|
if (!rootNode)
|
||||||
WLog_ERR(TAG, "size of format data response invalid");
|
return NULL;
|
||||||
return FALSE;
|
rootNode->ino = 1;
|
||||||
}
|
rootNode->parent_ino = 1;
|
||||||
|
rootNode->st_mode = S_IFDIR | 0755;
|
||||||
|
rootNode->name = _strdup("/");
|
||||||
|
rootNode->child_inos = ArrayList_New(TRUE);
|
||||||
|
rootNode->st_mtim.tv_sec = time(NULL);
|
||||||
|
rootNode->st_size = 0;
|
||||||
|
rootNode->size_set = TRUE;
|
||||||
|
|
||||||
|
if (!rootNode->child_inos || !rootNode->name)
|
||||||
|
{
|
||||||
|
xf_cliprdr_fuse_inode_free(rootNode);
|
||||||
|
WLog_ERR(TAG, "fail to alloc rootNode's member");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return rootNode;
|
||||||
|
}
|
||||||
|
static BOOL xf_cliprdr_fuse_check_stream(wStream* s, size_t count)
|
||||||
|
{
|
||||||
UINT32 nrDescriptors;
|
UINT32 nrDescriptors;
|
||||||
size_t count = (size - 4) / sizeof(FILEDESCRIPTORW);
|
|
||||||
wStream* s = Stream_New((BYTE*)data, size);
|
|
||||||
if (Stream_GetRemainingLength(s) < sizeof(UINT32))
|
if (Stream_GetRemainingLength(s) < sizeof(UINT32))
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "too short serialized format list");
|
WLog_ERR(TAG, "too short serialized format list");
|
||||||
@ -1634,52 +1665,28 @@ static BOOL xf_cliprdr_fuse_generate_list(xfClipboard* clipboard, const BYTE* da
|
|||||||
}
|
}
|
||||||
|
|
||||||
Stream_Read_UINT32(s, nrDescriptors);
|
Stream_Read_UINT32(s, nrDescriptors);
|
||||||
if (count < 1 || count != nrDescriptors)
|
if (count != nrDescriptors)
|
||||||
{
|
{
|
||||||
WLog_WARN(TAG, "format data response mismatch");
|
WLog_WARN(TAG, "format data response mismatch");
|
||||||
goto error;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
size_t lindex;
|
static BOOL xf_cliprdr_fuse_create_nodes(xfClipboard* clipboard, wStream* s, size_t count,
|
||||||
wHashTable* mapDir;
|
xfCliprdrFuseInode* rootNode)
|
||||||
/* prevent conflict between fuse_thread and this */
|
{
|
||||||
ArrayList_Lock(clipboard->ino_list);
|
BOOL status = FALSE;
|
||||||
xfCliprdrFuseInode* rootNode = (xfCliprdrFuseInode*)calloc(1, sizeof(xfCliprdrFuseInode));
|
size_t lindex = 0;
|
||||||
if (!rootNode)
|
char* curName = NULL;
|
||||||
{
|
char* dirName = NULL;
|
||||||
WLog_ERR(TAG, "fail to alloc rootNode");
|
char* baseName = NULL;
|
||||||
goto error;
|
xfCliprdrFuseInode* inode;
|
||||||
}
|
wHashTable* mapDir = HashTable_New(TRUE);
|
||||||
rootNode->ino = 1;
|
|
||||||
rootNode->parent_ino = 1;
|
|
||||||
rootNode->name = _strdup("/");
|
|
||||||
if (!rootNode->name)
|
|
||||||
{
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
rootNode->st_mode = S_IFDIR | 0755;
|
|
||||||
rootNode->child_inos = ArrayList_New(TRUE);
|
|
||||||
if (!rootNode->child_inos || !rootNode->name)
|
|
||||||
{
|
|
||||||
xf_cliprdr_fuse_inode_free(rootNode);
|
|
||||||
WLog_ERR(TAG, "fail to alloc rootNode's member");
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
rootNode->st_mtim.tv_sec = time(NULL);
|
|
||||||
rootNode->st_size = 0;
|
|
||||||
rootNode->size_set = TRUE;
|
|
||||||
if (ArrayList_Add(clipboard->ino_list, rootNode) < 0)
|
|
||||||
{
|
|
||||||
xf_cliprdr_fuse_inode_free(rootNode);
|
|
||||||
WLog_ERR(TAG, "fail to alloc rootNode to ino_list");
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
mapDir = HashTable_New(TRUE);
|
|
||||||
if (!mapDir)
|
if (!mapDir)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "fail to alloc hashtable");
|
WLog_ERR(TAG, "fail to alloc hashtable");
|
||||||
goto error2;
|
return FALSE;
|
||||||
}
|
}
|
||||||
mapDir->keyFree = HashTable_StringFree;
|
mapDir->keyFree = HashTable_StringFree;
|
||||||
mapDir->keyClone = HashTable_StringClone;
|
mapDir->keyClone = HashTable_StringClone;
|
||||||
@ -1690,38 +1697,30 @@ static BOOL xf_cliprdr_fuse_generate_list(xfClipboard* clipboard, const BYTE* da
|
|||||||
if (!descriptor)
|
if (!descriptor)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "fail to alloc FILEDESCRIPTORW");
|
WLog_ERR(TAG, "fail to alloc FILEDESCRIPTORW");
|
||||||
goto error3;
|
goto error;
|
||||||
}
|
}
|
||||||
char* curName;
|
|
||||||
char* dirName;
|
|
||||||
xfCliprdrFuseInode* inode;
|
|
||||||
/* here we assume that parent folder always appears before its children */
|
/* here we assume that parent folder always appears before its children */
|
||||||
for (lindex = 0; lindex < count; lindex++)
|
for (; lindex < count; lindex++)
|
||||||
{
|
{
|
||||||
Stream_Read(s, descriptor, sizeof(FILEDESCRIPTORW));
|
Stream_Read(s, descriptor, sizeof(FILEDESCRIPTORW));
|
||||||
inode = (xfCliprdrFuseInode*)calloc(1, sizeof(xfCliprdrFuseInode));
|
inode = (xfCliprdrFuseInode*)calloc(1, sizeof(xfCliprdrFuseInode));
|
||||||
if (!inode)
|
if (!inode)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "fail to alloc ino");
|
WLog_ERR(TAG, "fail to alloc ino");
|
||||||
goto error4;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t curLen = _wcsnlen(descriptor->cFileName, ARRAYSIZE(descriptor->cFileName));
|
size_t curLen = _wcsnlen(descriptor->cFileName, ARRAYSIZE(descriptor->cFileName));
|
||||||
curName = NULL;
|
|
||||||
int newLen = ConvertFromUnicode(CP_UTF8, 0, descriptor->cFileName, (int)curLen, &curName, 0,
|
int newLen = ConvertFromUnicode(CP_UTF8, 0, descriptor->cFileName, (int)curLen, &curName, 0,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
if (!curName)
|
if (!curName)
|
||||||
{
|
break;
|
||||||
goto error5;
|
|
||||||
}
|
|
||||||
char* split_point = xf_cliprdr_fuse_split_basename(curName, newLen);
|
char* split_point = xf_cliprdr_fuse_split_basename(curName, newLen);
|
||||||
|
|
||||||
char* baseName = NULL;
|
|
||||||
UINT64 ticks;
|
UINT64 ticks;
|
||||||
xfCliprdrFuseInode* parent;
|
xfCliprdrFuseInode* parent;
|
||||||
|
|
||||||
dirName = NULL;
|
|
||||||
|
|
||||||
inode->lindex = lindex;
|
inode->lindex = lindex;
|
||||||
inode->ino = lindex + 2;
|
inode->ino = lindex + 2;
|
||||||
|
|
||||||
@ -1729,43 +1728,32 @@ static BOOL xf_cliprdr_fuse_generate_list(xfClipboard* clipboard, const BYTE* da
|
|||||||
{
|
{
|
||||||
baseName = _strdup(curName);
|
baseName = _strdup(curName);
|
||||||
if (!baseName)
|
if (!baseName)
|
||||||
{
|
break;
|
||||||
goto error6;
|
|
||||||
}
|
|
||||||
inode->parent_ino = 1;
|
inode->parent_ino = 1;
|
||||||
inode->name = baseName;
|
inode->name = baseName;
|
||||||
if (ArrayList_Add(rootNode->child_inos, (void*)inode->ino) < 0)
|
if (ArrayList_Add(rootNode->child_inos, (void*)inode->ino) < 0)
|
||||||
{
|
break;
|
||||||
goto error6;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dirName = calloc(split_point - curName + 1, sizeof(char));
|
dirName = calloc(split_point - curName + 1, sizeof(char));
|
||||||
if (!dirName)
|
if (!dirName)
|
||||||
{
|
break;
|
||||||
goto error6;
|
|
||||||
}
|
|
||||||
_snprintf(dirName, split_point - curName + 1, "%s", curName);
|
_snprintf(dirName, split_point - curName + 1, "%s", curName);
|
||||||
/* drop last '\\' */
|
/* drop last '\\' */
|
||||||
baseName = _strdup(split_point + 1);
|
baseName = _strdup(split_point + 1);
|
||||||
if (!baseName)
|
if (!baseName)
|
||||||
{
|
break;
|
||||||
goto error7;
|
|
||||||
}
|
|
||||||
|
|
||||||
parent = (xfCliprdrFuseInode*)HashTable_GetItemValue(mapDir, dirName);
|
parent = (xfCliprdrFuseInode*)HashTable_GetItemValue(mapDir, dirName);
|
||||||
if (!parent)
|
if (!parent)
|
||||||
{
|
break;
|
||||||
goto error7;
|
|
||||||
}
|
|
||||||
inode->parent_ino = parent->ino;
|
inode->parent_ino = parent->ino;
|
||||||
inode->name = baseName;
|
inode->name = baseName;
|
||||||
if (ArrayList_Add(parent->child_inos, (void*)inode->ino) < 0)
|
if (ArrayList_Add(parent->child_inos, (void*)inode->ino) < 0)
|
||||||
{
|
break;
|
||||||
goto error7;
|
|
||||||
}
|
|
||||||
free(dirName);
|
free(dirName);
|
||||||
|
dirName = NULL;
|
||||||
}
|
}
|
||||||
/* TODO: check FD_ATTRIBUTES in dwFlags
|
/* TODO: check FD_ATTRIBUTES in dwFlags
|
||||||
However if this flag is not valid how can we determine file/folder?
|
However if this flag is not valid how can we determine file/folder?
|
||||||
@ -1775,20 +1763,16 @@ static BOOL xf_cliprdr_fuse_generate_list(xfClipboard* clipboard, const BYTE* da
|
|||||||
inode->st_mode = S_IFDIR | 0755;
|
inode->st_mode = S_IFDIR | 0755;
|
||||||
inode->child_inos = ArrayList_New(TRUE);
|
inode->child_inos = ArrayList_New(TRUE);
|
||||||
if (!inode->child_inos)
|
if (!inode->child_inos)
|
||||||
{
|
break;
|
||||||
goto error6;
|
|
||||||
}
|
|
||||||
inode->st_size = 0;
|
inode->st_size = 0;
|
||||||
inode->size_set = TRUE;
|
inode->size_set = TRUE;
|
||||||
char* tmpName = _strdup(curName);
|
char* tmpName = _strdup(curName);
|
||||||
if (!tmpName)
|
if (!tmpName)
|
||||||
{
|
break;
|
||||||
goto error6;
|
|
||||||
}
|
|
||||||
if (HashTable_Add(mapDir, tmpName, inode) < 0)
|
if (HashTable_Add(mapDir, tmpName, inode) < 0)
|
||||||
{
|
{
|
||||||
free(tmpName);
|
free(tmpName);
|
||||||
goto error6;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1807,6 +1791,7 @@ static BOOL xf_cliprdr_fuse_generate_list(xfClipboard* clipboard, const BYTE* da
|
|||||||
}
|
}
|
||||||
|
|
||||||
free(curName);
|
free(curName);
|
||||||
|
curName = NULL;
|
||||||
|
|
||||||
if ((descriptor->dwFlags & FD_WRITESTIME) != 0)
|
if ((descriptor->dwFlags & FD_WRITESTIME) != 0)
|
||||||
{
|
{
|
||||||
@ -1824,32 +1809,71 @@ static BOOL xf_cliprdr_fuse_generate_list(xfClipboard* clipboard, const BYTE* da
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ArrayList_Add(clipboard->ino_list, inode) < 0)
|
if (ArrayList_Add(clipboard->ino_list, inode) < 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* clean up incomplete ino_list*/
|
||||||
|
if (lindex != count)
|
||||||
{
|
{
|
||||||
goto error5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ArrayList_Unlock(clipboard->ino_list);
|
|
||||||
free(descriptor);
|
|
||||||
HashTable_Free(mapDir);
|
|
||||||
|
|
||||||
Stream_Free(s, FALSE);
|
|
||||||
return TRUE;
|
|
||||||
error7:
|
|
||||||
free(dirName);
|
free(dirName);
|
||||||
error6:
|
|
||||||
free(curName);
|
free(curName);
|
||||||
error5:
|
/* baseName is freed in xf_cliprdr_fuse_inode_free*/
|
||||||
xf_cliprdr_fuse_inode_free(inode);
|
xf_cliprdr_fuse_inode_free(inode);
|
||||||
error4:
|
|
||||||
free(descriptor);
|
|
||||||
error3:
|
|
||||||
HashTable_Free(mapDir);
|
|
||||||
error2:
|
|
||||||
ArrayList_Clear(clipboard->ino_list);
|
ArrayList_Clear(clipboard->ino_list);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
status = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(descriptor);
|
||||||
|
|
||||||
error:
|
error:
|
||||||
ArrayList_Unlock(clipboard->ino_list);
|
HashTable_Free(mapDir);
|
||||||
Stream_Free(s, FALSE);
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate inode list for fuse
|
||||||
|
*
|
||||||
|
* @return TRUE on success, FALSE on fail
|
||||||
|
*/
|
||||||
|
static BOOL xf_cliprdr_fuse_generate_list(xfClipboard* clipboard, const BYTE* data, UINT32 size)
|
||||||
|
{
|
||||||
|
BOOL status = FALSE;
|
||||||
|
if (size < 4)
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "size of format data response invalid : %d", size);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
}
|
||||||
|
size_t count = (size - 4) / sizeof(FILEDESCRIPTORW);
|
||||||
|
if (count < 1)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
wStream* s = Stream_New((BYTE*)data, size);
|
||||||
|
if (!s || !xf_cliprdr_fuse_check_stream(s, count))
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "Stream_New failed");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* prevent conflict between fuse_thread and this */
|
||||||
|
ArrayList_Lock(clipboard->ino_list);
|
||||||
|
xfCliprdrFuseInode* rootNode = xf_cliprdr_fuse_create_root_node();
|
||||||
|
|
||||||
|
if (!rootNode || ArrayList_Add(clipboard->ino_list, rootNode) < 0)
|
||||||
|
{
|
||||||
|
xf_cliprdr_fuse_inode_free(rootNode);
|
||||||
|
WLog_ERR(TAG, "fail to alloc rootNode to ino_list");
|
||||||
|
goto error2;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = xf_cliprdr_fuse_create_nodes(clipboard, s, count, rootNode);
|
||||||
|
|
||||||
|
error2:
|
||||||
|
ArrayList_Unlock(clipboard->ino_list);
|
||||||
|
error:
|
||||||
|
Stream_Free(s, FALSE);
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1875,6 +1899,12 @@ xf_cliprdr_server_format_data_response(CliprdrClientContext* context,
|
|||||||
xfClipboard* clipboard = (xfClipboard*)context->custom;
|
xfClipboard* clipboard = (xfClipboard*)context->custom;
|
||||||
xfContext* xfc = clipboard->xfc;
|
xfContext* xfc = clipboard->xfc;
|
||||||
|
|
||||||
|
if (formatDataResponse->msgFlags == CB_RESPONSE_FAIL)
|
||||||
|
{
|
||||||
|
WLog_WARN(TAG, "Format Data Response PDU msgFlags is CB_RESPONSE_FAIL");
|
||||||
|
return CHANNEL_RC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
if (!clipboard->respond)
|
if (!clipboard->respond)
|
||||||
return CHANNEL_RC_OK;
|
return CHANNEL_RC_OK;
|
||||||
|
|
||||||
@ -1902,7 +1932,7 @@ xf_cliprdr_server_format_data_response(CliprdrClientContext* context,
|
|||||||
{
|
{
|
||||||
#ifdef WITH_FUSE
|
#ifdef WITH_FUSE
|
||||||
/* Build inode table for FILEDESCRIPTORW*/
|
/* Build inode table for FILEDESCRIPTORW*/
|
||||||
if (xf_cliprdr_fuse_generate_list(clipboard, data, size) == FALSE)
|
if (!xf_cliprdr_fuse_generate_list(clipboard, data, size))
|
||||||
{
|
{
|
||||||
/* just continue */
|
/* just continue */
|
||||||
WLog_WARN(TAG, "fail to generate list for FILEDESCRIPTOR");
|
WLog_WARN(TAG, "fail to generate list for FILEDESCRIPTOR");
|
||||||
@ -2166,37 +2196,121 @@ static UINT xf_cliprdr_clipboard_file_range_failure(wClipboardDelegate* delegate
|
|||||||
|
|
||||||
#ifdef WITH_FUSE
|
#ifdef WITH_FUSE
|
||||||
/* For better understanding the relationship between ino and index of arraylist*/
|
/* For better understanding the relationship between ino and index of arraylist*/
|
||||||
static inline xfCliprdrFuseInode* xf_cliprdr_get_inode(wArrayList* ino_list, fuse_ino_t ino)
|
static inline xfCliprdrFuseInode* xf_cliprdr_fuse_util_get_inode(wArrayList* ino_list,
|
||||||
|
fuse_ino_t ino)
|
||||||
{
|
{
|
||||||
size_t list_index = ino - 1;
|
size_t list_index = ino - 1;
|
||||||
return (xfCliprdrFuseInode*)ArrayList_GetItem(ino_list, list_index);
|
return (xfCliprdrFuseInode*)ArrayList_GetItem(ino_list, list_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xf_cliprdr_fuse_getattr(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info* fi)
|
/* fuse helper functions*/
|
||||||
|
static int xf_cliprdr_fuse_util_stat(xfClipboard* clipboard, fuse_ino_t ino, struct stat* stbuf)
|
||||||
{
|
{
|
||||||
double timeout = 0;
|
int err = 0;
|
||||||
struct stat stbuf;
|
|
||||||
|
|
||||||
xfCliprdrFuseInode* node;
|
xfCliprdrFuseInode* node;
|
||||||
xfClipboard* clipboard = (xfClipboard*)fuse_req_userdata(req);
|
|
||||||
|
|
||||||
ArrayList_Lock(clipboard->ino_list);
|
ArrayList_Lock(clipboard->ino_list);
|
||||||
node = xf_cliprdr_get_inode(clipboard->ino_list, ino);
|
|
||||||
|
node = xf_cliprdr_fuse_util_get_inode(clipboard->ino_list, ino);
|
||||||
|
|
||||||
if (!node)
|
if (!node)
|
||||||
{
|
{
|
||||||
ArrayList_Unlock(clipboard->ino_list);
|
err = ENOENT;
|
||||||
fuse_reply_err(req, ENOENT);
|
goto error;
|
||||||
}
|
}
|
||||||
else
|
memset(stbuf, 0, sizeof(*stbuf));
|
||||||
|
stbuf->st_ino = ino;
|
||||||
|
stbuf->st_mode = node->st_mode;
|
||||||
|
stbuf->st_mtime = node->st_mtim.tv_sec;
|
||||||
|
stbuf->st_nlink = 1;
|
||||||
|
error:
|
||||||
|
ArrayList_Unlock(clipboard->ino_list);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int xf_cliprdr_fuse_util_stmode(xfClipboard* clipboard, fuse_ino_t ino, mode_t* mode)
|
||||||
|
{
|
||||||
|
int err = 0;
|
||||||
|
xfCliprdrFuseInode* node;
|
||||||
|
ArrayList_Lock(clipboard->ino_list);
|
||||||
|
|
||||||
|
node = xf_cliprdr_fuse_util_get_inode(clipboard->ino_list, ino);
|
||||||
|
if (!node)
|
||||||
{
|
{
|
||||||
memset(&stbuf, 0, sizeof(stbuf));
|
err = ENOENT;
|
||||||
stbuf.st_ino = ino;
|
goto error;
|
||||||
stbuf.st_mode = node->st_mode;
|
|
||||||
stbuf.st_mtime = node->st_mtim.tv_sec;
|
|
||||||
stbuf.st_nlink = 1;
|
|
||||||
ArrayList_Unlock(clipboard->ino_list);
|
|
||||||
fuse_reply_attr(req, &stbuf, timeout);
|
|
||||||
}
|
}
|
||||||
|
*mode = node->st_mode;
|
||||||
|
error:
|
||||||
|
ArrayList_Unlock(clipboard->ino_list);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int xf_cliprdr_fuse_util_lindex(xfClipboard* clipboard, fuse_ino_t ino, UINT32* lindex)
|
||||||
|
{
|
||||||
|
int err = 0;
|
||||||
|
xfCliprdrFuseInode* node;
|
||||||
|
ArrayList_Lock(clipboard->ino_list);
|
||||||
|
|
||||||
|
node = xf_cliprdr_fuse_util_get_inode(clipboard->ino_list, ino);
|
||||||
|
if (!node)
|
||||||
|
{
|
||||||
|
err = ENOENT;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if ((node->st_mode & S_IFDIR) != 0)
|
||||||
|
{
|
||||||
|
err = EISDIR;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
*lindex = node->lindex;
|
||||||
|
|
||||||
|
error:
|
||||||
|
ArrayList_Unlock(clipboard->ino_list);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int xf_cliprdr_fuse_util_add_stream_list(xfClipboard* clipboard, fuse_req_t req,
|
||||||
|
UINT32* stream_id)
|
||||||
|
{
|
||||||
|
int err = 0;
|
||||||
|
xfCliprdrFuseStream* stream = (xfCliprdrFuseStream*)calloc(1, sizeof(xfCliprdrFuseStream));
|
||||||
|
if (!stream)
|
||||||
|
{
|
||||||
|
err = ENOMEM;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
ArrayList_Lock(clipboard->stream_list);
|
||||||
|
stream->req = req;
|
||||||
|
stream->req_type = FILECONTENTS_RANGE;
|
||||||
|
stream->stream_id = clipboard->current_stream_id;
|
||||||
|
*stream_id = stream->stream_id;
|
||||||
|
stream->req_ino = 0;
|
||||||
|
clipboard->current_stream_id++;
|
||||||
|
if (ArrayList_Add(clipboard->stream_list, stream) < 0)
|
||||||
|
{
|
||||||
|
err = ENOMEM;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
error:
|
||||||
|
ArrayList_Unlock(clipboard->stream_list);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void xf_cliprdr_fuse_getattr(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info* fi)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
struct stat stbuf;
|
||||||
|
|
||||||
|
xfClipboard* clipboard = (xfClipboard*)fuse_req_userdata(req);
|
||||||
|
|
||||||
|
err = xf_cliprdr_fuse_util_stat(clipboard, ino, &stbuf);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
fuse_reply_err(req, err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fuse_reply_attr(req, &stbuf, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xf_cliprdr_fuse_readdir(fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
|
static void xf_cliprdr_fuse_readdir(fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
|
||||||
@ -2214,7 +2328,7 @@ static void xf_cliprdr_fuse_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
|
|||||||
xfClipboard* clipboard = (xfClipboard*)fuse_req_userdata(req);
|
xfClipboard* clipboard = (xfClipboard*)fuse_req_userdata(req);
|
||||||
|
|
||||||
ArrayList_Lock(clipboard->ino_list);
|
ArrayList_Lock(clipboard->ino_list);
|
||||||
node = xf_cliprdr_get_inode(clipboard->ino_list, ino);
|
node = xf_cliprdr_fuse_util_get_inode(clipboard->ino_list, ino);
|
||||||
|
|
||||||
if (!node || !node->child_inos)
|
if (!node || !node->child_inos)
|
||||||
{
|
{
|
||||||
@ -2272,7 +2386,7 @@ static void xf_cliprdr_fuse_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
|
|||||||
/* execlude . and .. */
|
/* execlude . and .. */
|
||||||
child_ino = (size_t)ArrayList_GetItem(node->child_inos, index - 2);
|
child_ino = (size_t)ArrayList_GetItem(node->child_inos, index - 2);
|
||||||
/* previous lock for ino_list still work*/
|
/* previous lock for ino_list still work*/
|
||||||
child_node = xf_cliprdr_get_inode(clipboard->ino_list, child_ino);
|
child_node = xf_cliprdr_fuse_util_get_inode(clipboard->ino_list, child_ino);
|
||||||
if (!child_node)
|
if (!child_node)
|
||||||
break;
|
break;
|
||||||
stbuf.st_ino = child_node->ino;
|
stbuf.st_ino = child_node->ino;
|
||||||
@ -2294,24 +2408,23 @@ static void xf_cliprdr_fuse_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
|
|||||||
|
|
||||||
static void xf_cliprdr_fuse_open(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info* fi)
|
static void xf_cliprdr_fuse_open(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info* fi)
|
||||||
{
|
{
|
||||||
xfCliprdrFuseInode* node;
|
int err;
|
||||||
|
mode_t mode = 0;
|
||||||
xfClipboard* clipboard = (xfClipboard*)fuse_req_userdata(req);
|
xfClipboard* clipboard = (xfClipboard*)fuse_req_userdata(req);
|
||||||
|
|
||||||
ArrayList_Lock(clipboard->ino_list);
|
err = xf_cliprdr_fuse_util_stmode(clipboard, ino, &mode);
|
||||||
node = xf_cliprdr_get_inode(clipboard->ino_list, ino);
|
if (err)
|
||||||
if (!node)
|
|
||||||
{
|
{
|
||||||
ArrayList_Unlock(clipboard->ino_list);
|
fuse_reply_err(req, err);
|
||||||
fuse_reply_err(req, ENOENT);
|
return;
|
||||||
}
|
}
|
||||||
else if ((node->st_mode & S_IFDIR) != 0)
|
|
||||||
|
if ((mode & S_IFDIR) != 0)
|
||||||
{
|
{
|
||||||
ArrayList_Unlock(clipboard->ino_list);
|
|
||||||
fuse_reply_err(req, EISDIR);
|
fuse_reply_err(req, EISDIR);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ArrayList_Unlock(clipboard->ino_list);
|
|
||||||
/* Important for KDE to get file correctly*/
|
/* Important for KDE to get file correctly*/
|
||||||
fi->direct_io = 1;
|
fi->direct_io = 1;
|
||||||
fuse_reply_open(req, fi);
|
fuse_reply_open(req, fi);
|
||||||
@ -2326,48 +2439,24 @@ static void xf_cliprdr_fuse_read(fuse_req_t req, fuse_ino_t ino, size_t size, of
|
|||||||
fuse_reply_err(req, ENONET);
|
fuse_reply_err(req, ENONET);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
xfCliprdrFuseInode* node;
|
int err;
|
||||||
xfClipboard* clipboard = (xfClipboard*)fuse_req_userdata(req);
|
xfClipboard* clipboard = (xfClipboard*)fuse_req_userdata(req);
|
||||||
UINT32 lindex;
|
UINT32 lindex;
|
||||||
UINT32 stream_id;
|
UINT32 stream_id;
|
||||||
|
|
||||||
ArrayList_Lock(clipboard->ino_list);
|
err = xf_cliprdr_fuse_util_lindex(clipboard, ino, &lindex);
|
||||||
node = xf_cliprdr_get_inode(clipboard->ino_list, ino);
|
if (err)
|
||||||
if (!node)
|
|
||||||
{
|
{
|
||||||
ArrayList_Unlock(clipboard->ino_list);
|
fuse_reply_err(req, err);
|
||||||
fuse_reply_err(req, ENONET);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if ((node->st_mode & S_IFDIR) != 0)
|
|
||||||
{
|
|
||||||
ArrayList_Unlock(clipboard->ino_list);
|
|
||||||
fuse_reply_err(req, EISDIR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
lindex = node->lindex;
|
|
||||||
ArrayList_Unlock(clipboard->ino_list);
|
|
||||||
|
|
||||||
xfCliprdrFuseStream* stream = (xfCliprdrFuseStream*)calloc(1, sizeof(xfCliprdrFuseStream));
|
err = xf_cliprdr_fuse_util_add_stream_list(clipboard, req, &stream_id);
|
||||||
if (!stream)
|
if (err)
|
||||||
{
|
{
|
||||||
fuse_reply_err(req, ENOMEM);
|
fuse_reply_err(req, err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ArrayList_Lock(clipboard->stream_list);
|
|
||||||
stream->req = req;
|
|
||||||
stream->req_type = FILECONTENTS_RANGE;
|
|
||||||
stream->stream_id = clipboard->current_stream_id;
|
|
||||||
stream_id = stream->stream_id;
|
|
||||||
stream->req_data = NULL;
|
|
||||||
clipboard->current_stream_id++;
|
|
||||||
if (ArrayList_Add(clipboard->stream_list, stream) < 0)
|
|
||||||
{
|
|
||||||
ArrayList_Unlock(clipboard->stream_list);
|
|
||||||
fuse_reply_err(req, ENOMEM);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ArrayList_Unlock(clipboard->stream_list);
|
|
||||||
|
|
||||||
UINT32 nPositionLow = (off >> 0) & 0xFFFFFFFF;
|
UINT32 nPositionLow = (off >> 0) & 0xFFFFFFFF;
|
||||||
UINT32 nPositionHigh = (off >> 32) & 0xFFFFFFFF;
|
UINT32 nPositionHigh = (off >> 32) & 0xFFFFFFFF;
|
||||||
@ -2388,7 +2477,7 @@ static void xf_cliprdr_fuse_lookup(fuse_req_t req, fuse_ino_t parent, const char
|
|||||||
xfClipboard* clipboard = (xfClipboard*)fuse_req_userdata(req);
|
xfClipboard* clipboard = (xfClipboard*)fuse_req_userdata(req);
|
||||||
|
|
||||||
ArrayList_Lock(clipboard->ino_list);
|
ArrayList_Lock(clipboard->ino_list);
|
||||||
parent_node = xf_cliprdr_get_inode(clipboard->ino_list, parent);
|
parent_node = xf_cliprdr_fuse_util_get_inode(clipboard->ino_list, parent);
|
||||||
|
|
||||||
if (!parent_node || !parent_node->child_inos)
|
if (!parent_node || !parent_node->child_inos)
|
||||||
{
|
{
|
||||||
@ -2402,7 +2491,7 @@ static void xf_cliprdr_fuse_lookup(fuse_req_t req, fuse_ino_t parent, const char
|
|||||||
for (index = 0; index < count; index++)
|
for (index = 0; index < count; index++)
|
||||||
{
|
{
|
||||||
child_ino = (size_t)ArrayList_GetItem(parent_node->child_inos, index);
|
child_ino = (size_t)ArrayList_GetItem(parent_node->child_inos, index);
|
||||||
child_node = xf_cliprdr_get_inode(clipboard->ino_list, child_ino);
|
child_node = xf_cliprdr_fuse_util_get_inode(clipboard->ino_list, child_ino);
|
||||||
if (child_node && strcmp(name, child_node->name) == 0)
|
if (child_node && strcmp(name, child_node->name) == 0)
|
||||||
{
|
{
|
||||||
found = TRUE;
|
found = TRUE;
|
||||||
@ -2410,8 +2499,15 @@ static void xf_cliprdr_fuse_lookup(fuse_req_t req, fuse_ino_t parent, const char
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ArrayList_Unlock(parent_node->child_inos);
|
ArrayList_Unlock(parent_node->child_inos);
|
||||||
if (found == TRUE)
|
|
||||||
|
if (!found)
|
||||||
{
|
{
|
||||||
|
ArrayList_Unlock(clipboard->ino_list);
|
||||||
|
fuse_reply_err(req, ENOENT);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int res;
|
||||||
UINT32 stream_id;
|
UINT32 stream_id;
|
||||||
BOOL size_set = child_node->size_set;
|
BOOL size_set = child_node->size_set;
|
||||||
size_t lindex = child_node->lindex;
|
size_t lindex = child_node->lindex;
|
||||||
@ -2420,10 +2516,10 @@ static void xf_cliprdr_fuse_lookup(fuse_req_t req, fuse_ino_t parent, const char
|
|||||||
off_t st_size = child_node->st_size;
|
off_t st_size = child_node->st_size;
|
||||||
time_t tv_sec = child_node->st_mtim.tv_sec;
|
time_t tv_sec = child_node->st_mtim.tv_sec;
|
||||||
ArrayList_Unlock(clipboard->ino_list);
|
ArrayList_Unlock(clipboard->ino_list);
|
||||||
if (size_set != TRUE)
|
|
||||||
|
if (!size_set)
|
||||||
{
|
{
|
||||||
xfCliprdrFuseStream* stream =
|
xfCliprdrFuseStream* stream = (xfCliprdrFuseStream*)calloc(1, sizeof(xfCliprdrFuseStream));
|
||||||
(xfCliprdrFuseStream*)calloc(1, sizeof(xfCliprdrFuseStream));
|
|
||||||
if (!stream)
|
if (!stream)
|
||||||
{
|
{
|
||||||
fuse_reply_err(req, ENOMEM);
|
fuse_reply_err(req, ENOMEM);
|
||||||
@ -2434,19 +2530,17 @@ static void xf_cliprdr_fuse_lookup(fuse_req_t req, fuse_ino_t parent, const char
|
|||||||
stream->req_type = FILECONTENTS_SIZE;
|
stream->req_type = FILECONTENTS_SIZE;
|
||||||
stream->stream_id = clipboard->current_stream_id;
|
stream->stream_id = clipboard->current_stream_id;
|
||||||
stream_id = stream->stream_id;
|
stream_id = stream->stream_id;
|
||||||
/* child_node is not guaranteed to be valid */
|
stream->req_ino = ino;
|
||||||
stream->req_data = (void*)child_node;
|
|
||||||
clipboard->current_stream_id++;
|
clipboard->current_stream_id++;
|
||||||
if (ArrayList_Add(clipboard->stream_list, stream) < 0)
|
res = ArrayList_Add(clipboard->stream_list, stream);
|
||||||
{
|
|
||||||
ArrayList_Unlock(clipboard->stream_list);
|
ArrayList_Unlock(clipboard->stream_list);
|
||||||
|
if (res < 0)
|
||||||
|
{
|
||||||
fuse_reply_err(req, ENOMEM);
|
fuse_reply_err(req, ENOMEM);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ArrayList_Unlock(clipboard->stream_list);
|
xf_cliprdr_send_client_file_contents(clipboard, stream_id, lindex, FILECONTENTS_SIZE, 0, 0,
|
||||||
|
0);
|
||||||
xf_cliprdr_send_client_file_contents(clipboard, stream_id, lindex, FILECONTENTS_SIZE, 0,
|
|
||||||
0, 0);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memset(&e, 0, sizeof(e));
|
memset(&e, 0, sizeof(e));
|
||||||
@ -2460,34 +2554,28 @@ static void xf_cliprdr_fuse_lookup(fuse_req_t req, fuse_ino_t parent, const char
|
|||||||
e.attr.st_size = st_size;
|
e.attr.st_size = st_size;
|
||||||
e.attr.st_mtime = tv_sec;
|
e.attr.st_mtime = tv_sec;
|
||||||
fuse_reply_entry(req, &e);
|
fuse_reply_entry(req, &e);
|
||||||
}
|
return;
|
||||||
else
|
|
||||||
{
|
|
||||||
ArrayList_Unlock(clipboard->ino_list);
|
|
||||||
fuse_reply_err(req, ENOENT);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xf_cliprdr_fuse_opendir(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info* fi)
|
static void xf_cliprdr_fuse_opendir(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info* fi)
|
||||||
{
|
{
|
||||||
xfCliprdrFuseInode* node;
|
int err;
|
||||||
|
mode_t mode = 0;
|
||||||
xfClipboard* clipboard = (xfClipboard*)fuse_req_userdata(req);
|
xfClipboard* clipboard = (xfClipboard*)fuse_req_userdata(req);
|
||||||
|
|
||||||
ArrayList_Lock(clipboard->ino_list);
|
err = xf_cliprdr_fuse_util_stmode(clipboard, ino, &mode);
|
||||||
node = xf_cliprdr_get_inode(clipboard->ino_list, ino);
|
if (err)
|
||||||
if (!node)
|
|
||||||
{
|
{
|
||||||
ArrayList_Unlock(clipboard->ino_list);
|
fuse_reply_err(req, err);
|
||||||
fuse_reply_err(req, ENOENT);
|
return;
|
||||||
}
|
}
|
||||||
else if ((node->st_mode & S_IFDIR) == 0)
|
|
||||||
|
if ((mode & S_IFDIR) == 0)
|
||||||
{
|
{
|
||||||
ArrayList_Unlock(clipboard->ino_list);
|
|
||||||
fuse_reply_err(req, ENOTDIR);
|
fuse_reply_err(req, ENOTDIR);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ArrayList_Unlock(clipboard->ino_list);
|
|
||||||
fuse_reply_open(req, fi);
|
fuse_reply_open(req, fi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2505,7 +2593,6 @@ static DWORD WINAPI xf_cliprdr_fuse_thread(LPVOID arg)
|
|||||||
{
|
{
|
||||||
xfClipboard* clipboard = (xfClipboard*)arg;
|
xfClipboard* clipboard = (xfClipboard*)arg;
|
||||||
|
|
||||||
/* TODO: set up a filesystem base path for local URI */
|
|
||||||
/* TODO get basePath from config or use default*/
|
/* TODO get basePath from config or use default*/
|
||||||
UINT32 basePathSize;
|
UINT32 basePathSize;
|
||||||
char* basePath;
|
char* basePath;
|
||||||
@ -2813,7 +2900,7 @@ void xf_clipboard_free(xfClipboard* clipboard)
|
|||||||
CloseHandle(clipboard->fuse_thread);
|
CloseHandle(clipboard->fuse_thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clipboard->delegate->basePath)
|
if (clipboard->delegate)
|
||||||
free(clipboard->delegate->basePath);
|
free(clipboard->delegate->basePath);
|
||||||
|
|
||||||
// fuse related
|
// fuse related
|
||||||
|
@ -4,10 +4,9 @@
|
|||||||
# FUSE_LIBRARIES - List of libraries when using FUSE.
|
# FUSE_LIBRARIES - List of libraries when using FUSE.
|
||||||
# FUSE_FOUND - True if FUSE lib is found.
|
# FUSE_FOUND - True if FUSE lib is found.
|
||||||
|
|
||||||
# check if already in cache, be silent
|
unset(FUSE_LIBRARIES CACHE)
|
||||||
IF (FUSE_INCLUDE_DIR)
|
unset(FUSE_INCLUDE_DIR CACHE)
|
||||||
SET (FUSE_FIND_QUIETLY TRUE)
|
unset(FUSE_API_VERSION CACHE)
|
||||||
ENDIF (FUSE_INCLUDE_DIR)
|
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
include(FindPackageHandleStandardArgs)
|
||||||
|
|
||||||
@ -79,6 +78,7 @@ else()
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
find_package_handle_standard_args ("FUSE" DEFAULT_MSG
|
find_package_handle_standard_args ("FUSE" DEFAULT_MSG
|
||||||
FUSE_LIBRARIES FUSE_INCLUDE_DIR FUSE_API_VERSION)
|
FUSE_LIBRARIES FUSE_INCLUDE_DIR FUSE_API_VERSION)
|
||||||
|
|
||||||
|
@ -665,6 +665,7 @@ static void* convert_filedescriptors_to_file_list(wClipboard* clipboard, UINT32
|
|||||||
size_t curLen = _wcsnlen(descriptors[x].cFileName, ARRAYSIZE(descriptors[x].cFileName));
|
size_t curLen = _wcsnlen(descriptors[x].cFileName, ARRAYSIZE(descriptors[x].cFileName));
|
||||||
alloc += WideCharToMultiByte(CP_UTF8, 0, descriptors[x].cFileName, (int)curLen, NULL, 0,
|
alloc += WideCharToMultiByte(CP_UTF8, 0, descriptors[x].cFileName, (int)curLen, NULL, 0,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
|
/* # (1 char) -> %23 (3 chars) , the first char is replaced inplace */
|
||||||
alloc += count_special_chars(descriptors[x].cFileName) * 2;
|
alloc += count_special_chars(descriptors[x].cFileName) * 2;
|
||||||
alloc += decoration_len;
|
alloc += decoration_len;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user