|
|
@ -41,7 +41,7 @@
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
// LK_TODO #define USE_SYNC_FLAG
|
|
|
|
//#define USE_SYNC_FLAG
|
|
|
|
|
|
|
|
|
|
|
|
/* FUSE mount point */
|
|
|
|
/* FUSE mount point */
|
|
|
|
char g_fuse_root_path[256] = "";
|
|
|
|
char g_fuse_root_path[256] = "";
|
|
|
@ -164,6 +164,13 @@ struct dirbuf
|
|
|
|
size_t size;
|
|
|
|
size_t size;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct dirbuf1
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
char buf[4096];
|
|
|
|
|
|
|
|
int bytes_in_buf;
|
|
|
|
|
|
|
|
int first_time;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/* FUSE reply types */
|
|
|
|
/* FUSE reply types */
|
|
|
|
#define RT_FUSE_REPLY_OPEN 1
|
|
|
|
#define RT_FUSE_REPLY_OPEN 1
|
|
|
|
#define RT_FUSE_REPLY_CREATE 2
|
|
|
|
#define RT_FUSE_REPLY_CREATE 2
|
|
|
@ -181,6 +188,9 @@ struct xfuse_info
|
|
|
|
int reply_type;
|
|
|
|
int reply_type;
|
|
|
|
int mode;
|
|
|
|
int mode;
|
|
|
|
int type;
|
|
|
|
int type;
|
|
|
|
|
|
|
|
size_t size;
|
|
|
|
|
|
|
|
off_t off;
|
|
|
|
|
|
|
|
struct dirbuf1 dirbuf1;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
typedef struct xfuse_info XFUSE_INFO;
|
|
|
|
typedef struct xfuse_info XFUSE_INFO;
|
|
|
|
|
|
|
|
|
|
|
@ -231,6 +241,9 @@ static int xfuse_does_file_exist(int parent, char *name);
|
|
|
|
static int xfuse_delete_file(int parent, char *name);
|
|
|
|
static int xfuse_delete_file(int parent, char *name);
|
|
|
|
static int xfuse_delete_file_with_xinode(XRDP_INODE *xinode);
|
|
|
|
static int xfuse_delete_file_with_xinode(XRDP_INODE *xinode);
|
|
|
|
static int xfuse_delete_dir_with_xinode(XRDP_INODE *xinode);
|
|
|
|
static int xfuse_delete_dir_with_xinode(XRDP_INODE *xinode);
|
|
|
|
|
|
|
|
static void xfuse_update_xrdpfs_size();
|
|
|
|
|
|
|
|
static void xfuse_enum_dir(fuse_req_t req, fuse_ino_t ino, size_t size,
|
|
|
|
|
|
|
|
off_t off, struct fuse_file_info *fi);
|
|
|
|
|
|
|
|
|
|
|
|
/* forward declarations for calls we make into devredir */
|
|
|
|
/* forward declarations for calls we make into devredir */
|
|
|
|
int dev_redir_get_dir_listing(void *fusep, tui32 device_id, char *path);
|
|
|
|
int dev_redir_get_dir_listing(void *fusep, tui32 device_id, char *path);
|
|
|
@ -255,6 +268,9 @@ static void xfuse_cb_getattr(fuse_req_t req, fuse_ino_t ino,
|
|
|
|
static void xfuse_dirbuf_add(fuse_req_t req, struct dirbuf *b,
|
|
|
|
static void xfuse_dirbuf_add(fuse_req_t req, struct dirbuf *b,
|
|
|
|
const char *name, fuse_ino_t ino);
|
|
|
|
const char *name, fuse_ino_t ino);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int xfuse_dirbuf_add1(fuse_req_t req, struct dirbuf1 *b,
|
|
|
|
|
|
|
|
const char *name, fuse_ino_t ino);
|
|
|
|
|
|
|
|
|
|
|
|
static void xfuse_cb_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
|
|
|
|
static void xfuse_cb_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
|
|
|
|
off_t off, struct fuse_file_info *fi);
|
|
|
|
off_t off, struct fuse_file_info *fi);
|
|
|
|
|
|
|
|
|
|
|
@ -410,6 +426,10 @@ int xfuse_init()
|
|
|
|
#if 0
|
|
|
|
#if 0
|
|
|
|
sprintf(opt, "-o uid=%d,gid=%d", g_getuid(), g_getgid());
|
|
|
|
sprintf(opt, "-o uid=%d,gid=%d", g_getuid(), g_getgid());
|
|
|
|
fuse_opt_add_arg(&args, opt);
|
|
|
|
fuse_opt_add_arg(&args, opt);
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
/* disable multi threading */
|
|
|
|
|
|
|
|
sprintf(opt, "-s");
|
|
|
|
|
|
|
|
fuse_opt_add_arg(&args, opt);
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
if (xfuse_init_lib(&args))
|
|
|
|
if (xfuse_init_lib(&args))
|
|
|
@ -548,12 +568,6 @@ int xfuse_create_share(tui32 device_id, char *dirname)
|
|
|
|
return -1;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if ((fip = calloc(1, sizeof(XFUSE_INFO))) == NULL)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
log_error("system out of memory");
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* create directory entry */
|
|
|
|
/* create directory entry */
|
|
|
|
xinode->parent_inode = 1;
|
|
|
|
xinode->parent_inode = 1;
|
|
|
|
xinode->inode = g_xrdp_fs.next_node++;
|
|
|
|
xinode->inode = g_xrdp_fs.next_node++;
|
|
|
@ -582,6 +596,13 @@ int xfuse_create_share(tui32 device_id, char *dirname)
|
|
|
|
return -1;
|
|
|
|
return -1;
|
|
|
|
xinode->nentries++;
|
|
|
|
xinode->nentries++;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
|
|
|
if ((fip = calloc(1, sizeof(XFUSE_INFO))) == NULL)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
log_error("system out of memory");
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* enumerate root dir, do not call FUSE when done */
|
|
|
|
/* enumerate root dir, do not call FUSE when done */
|
|
|
|
fip->req = NULL;
|
|
|
|
fip->req = NULL;
|
|
|
|
fip->inode = 1; // LK_TODO saved_inode;
|
|
|
|
fip->inode = 1; // LK_TODO saved_inode;
|
|
|
@ -590,6 +611,7 @@ int xfuse_create_share(tui32 device_id, char *dirname)
|
|
|
|
fip->device_id = device_id;
|
|
|
|
fip->device_id = device_id;
|
|
|
|
|
|
|
|
|
|
|
|
dev_redir_get_dir_listing((void *) fip, device_id, "\\");
|
|
|
|
dev_redir_get_dir_listing((void *) fip, device_id, "\\");
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -652,14 +674,6 @@ int xfuse_file_contents_size(int stream_id, int file_size)
|
|
|
|
|
|
|
|
|
|
|
|
static int xfuse_init_lib(struct fuse_args *args)
|
|
|
|
static int xfuse_init_lib(struct fuse_args *args)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// LK_TODO
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < args->argc; i++)
|
|
|
|
|
|
|
|
log_debug("+++++++++++++ argc=%d argv=%s", i, args->argv[i]);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (fuse_parse_cmdline(args, &g_mount_point, 0, 0) < 0)
|
|
|
|
if (fuse_parse_cmdline(args, &g_mount_point, 0, 0) < 0)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
log_error("fuse_parse_cmdline() failed");
|
|
|
|
log_error("fuse_parse_cmdline() failed");
|
|
|
@ -785,7 +799,7 @@ static int xfuse_init_xrdp_fs()
|
|
|
|
xino->ctime = time(0);
|
|
|
|
xino->ctime = time(0);
|
|
|
|
strcpy(xino->name, ".clipboard");
|
|
|
|
strcpy(xino->name, ".clipboard");
|
|
|
|
|
|
|
|
|
|
|
|
g_xrdp_fs.max_entries = 1024;
|
|
|
|
g_xrdp_fs.max_entries = 4096;
|
|
|
|
g_xrdp_fs.num_entries = 3;
|
|
|
|
g_xrdp_fs.num_entries = 3;
|
|
|
|
g_xrdp_fs.next_node = 3;
|
|
|
|
g_xrdp_fs.next_node = 3;
|
|
|
|
|
|
|
|
|
|
|
@ -865,6 +879,7 @@ static void xfuse_create_file(fuse_req_t req, fuse_ino_t parent,
|
|
|
|
|
|
|
|
|
|
|
|
/* insert it in xrdp fs */
|
|
|
|
/* insert it in xrdp fs */
|
|
|
|
g_xrdp_fs.inode_table[xinode->inode] = xinode;
|
|
|
|
g_xrdp_fs.inode_table[xinode->inode] = xinode;
|
|
|
|
|
|
|
|
xfuse_update_xrdpfs_size();
|
|
|
|
log_debug("inserted new dir at inode_table[%d]", (int) xinode->inode);
|
|
|
|
log_debug("inserted new dir at inode_table[%d]", (int) xinode->inode);
|
|
|
|
|
|
|
|
|
|
|
|
xfuse_dump_fs();
|
|
|
|
xfuse_dump_fs();
|
|
|
@ -1064,7 +1079,7 @@ static struct xrdp_inode * xfuse_create_file_in_xrdp_fs(tui32 device_id,
|
|
|
|
log_debug("S_IFDIR=0x%x S_IFREG=0x%x type=0x%x", S_IFDIR, S_IFREG, type);
|
|
|
|
log_debug("S_IFDIR=0x%x S_IFREG=0x%x type=0x%x", S_IFDIR, S_IFREG, type);
|
|
|
|
|
|
|
|
|
|
|
|
xinode->parent_inode = pinode;
|
|
|
|
xinode->parent_inode = pinode;
|
|
|
|
xinode->inode = g_xrdp_fs.next_node++; /* TODO should be thread safe */
|
|
|
|
xinode->inode = g_xrdp_fs.next_node++;
|
|
|
|
xinode->nlink = 1;
|
|
|
|
xinode->nlink = 1;
|
|
|
|
xinode->uid = getuid();
|
|
|
|
xinode->uid = getuid();
|
|
|
|
xinode->gid = getgid();
|
|
|
|
xinode->gid = getgid();
|
|
|
@ -1087,13 +1102,14 @@ static struct xrdp_inode * xfuse_create_file_in_xrdp_fs(tui32 device_id,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
g_xrdp_fs.inode_table[xinode->inode] = xinode;
|
|
|
|
g_xrdp_fs.inode_table[xinode->inode] = xinode;
|
|
|
|
g_xrdp_fs.num_entries++; /* TODO should be thread safe */
|
|
|
|
g_xrdp_fs.num_entries++;
|
|
|
|
|
|
|
|
|
|
|
|
/* bump up lookup count in parent dir */
|
|
|
|
/* bump up lookup count in parent dir */
|
|
|
|
xinodep = g_xrdp_fs.inode_table[pinode];
|
|
|
|
xinodep = g_xrdp_fs.inode_table[pinode];
|
|
|
|
xinodep->nentries++;
|
|
|
|
xinodep->nentries++;
|
|
|
|
|
|
|
|
xfuse_update_xrdpfs_size();
|
|
|
|
|
|
|
|
|
|
|
|
log_debug("LK_TODO: incremented nentries; parent=%d nentries=%d",
|
|
|
|
log_debug("incremented nentries; parent=%d nentries=%d",
|
|
|
|
pinode, xinodep->nentries);
|
|
|
|
pinode, xinodep->nentries);
|
|
|
|
|
|
|
|
|
|
|
|
/* LK_TODO */
|
|
|
|
/* LK_TODO */
|
|
|
@ -1181,6 +1197,85 @@ static int xfuse_delete_dir_with_xinode(XRDP_INODE *xinode)
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void xfuse_update_xrdpfs_size()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
void *vp;
|
|
|
|
|
|
|
|
int diff;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
diff = g_xrdp_fs.max_entries - g_xrdp_fs.num_entries;
|
|
|
|
|
|
|
|
if (diff > 100)
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* extend memory */
|
|
|
|
|
|
|
|
vp = realloc(g_xrdp_fs.inode_table,
|
|
|
|
|
|
|
|
(g_xrdp_fs.max_entries + 100) * sizeof(struct xrdp_inode *));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (vp == NULL)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
log_error("system out of memory");
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* zero newly added memory */
|
|
|
|
|
|
|
|
memset(vp + g_xrdp_fs.max_entries * sizeof(struct xrdp_inode *),
|
|
|
|
|
|
|
|
0,
|
|
|
|
|
|
|
|
100 * sizeof(struct xrdp_inode *));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
g_xrdp_fs.max_entries += 100;
|
|
|
|
|
|
|
|
g_xrdp_fs.inode_table = vp;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void xfuse_enum_dir(fuse_req_t req, fuse_ino_t ino, size_t size,
|
|
|
|
|
|
|
|
off_t off, struct fuse_file_info *fi)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
XRDP_INODE *xinode;
|
|
|
|
|
|
|
|
XRDP_INODE *xinode1;
|
|
|
|
|
|
|
|
struct dirbuf b;
|
|
|
|
|
|
|
|
int first_time = 1;
|
|
|
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
memset(&b, 0, sizeof(struct dirbuf));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (i = FIRST_INODE; i < g_xrdp_fs.num_entries; i++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if ((xinode = g_xrdp_fs.inode_table[i]) == NULL)
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* match parent inode */
|
|
|
|
|
|
|
|
if (xinode->parent_inode != ino)
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (first_time)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
first_time = 0;
|
|
|
|
|
|
|
|
if (ino == 1)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
xfuse_dirbuf_add(req, &b, ".", 1);
|
|
|
|
|
|
|
|
xfuse_dirbuf_add(req, &b, "..", 1);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
xinode1 = g_xrdp_fs.inode_table[ino];
|
|
|
|
|
|
|
|
xfuse_dirbuf_add(req, &b, ".", ino);
|
|
|
|
|
|
|
|
xfuse_dirbuf_add(req, &b, "..", xinode1->parent_inode);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
xfuse_dirbuf_add(req, &b, xinode->name, xinode->inode);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!first_time)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (off < b.size)
|
|
|
|
|
|
|
|
fuse_reply_buf(req, b.p + off, min(b.size - off, size));
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
fuse_reply_buf(req, NULL, 0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (b.p)
|
|
|
|
|
|
|
|
free(b.p);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
/******************************************************************************
|
|
|
|
** **
|
|
|
|
** **
|
|
|
|
** callbacks for devredir **
|
|
|
|
** callbacks for devredir **
|
|
|
@ -1191,47 +1286,63 @@ static int xfuse_delete_dir_with_xinode(XRDP_INODE *xinode)
|
|
|
|
* Add a file or directory to xrdp file system
|
|
|
|
* Add a file or directory to xrdp file system
|
|
|
|
*****************************************************************************/
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
void xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode)
|
|
|
|
/* LK_TODO delete this after testing */
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
|
|
|
void ___xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
XFUSE_INFO *fip = (XFUSE_INFO *) vp;
|
|
|
|
XFUSE_INFO *fip = (XFUSE_INFO *) vp;
|
|
|
|
XRDP_INODE *target_inode;
|
|
|
|
XRDP_INODE *xip = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
log_debug("<<<<<< entered");
|
|
|
|
|
|
|
|
|
|
|
|
if ((fip == NULL) || (xinode == NULL))
|
|
|
|
if ((fip == NULL) || (xinode == NULL))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
log_error("fip or xinode are NULL");
|
|
|
|
log_error("fip or xinode are NULL");
|
|
|
|
|
|
|
|
printf("RASH_TODO: fip or xinode are NULL - leaving\n");
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* LK_TODO */
|
|
|
|
log_debug("req=%p", fip->req);
|
|
|
|
#if 0
|
|
|
|
|
|
|
|
/* do we have a valid inode? */
|
|
|
|
/* do we have a valid inode? */
|
|
|
|
if (!xfuse_is_inode_valid(fip->inode))
|
|
|
|
if (!xfuse_is_inode_valid(fip->inode))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
log_error("inode %d is not valid", fip->inode);
|
|
|
|
log_error("inode %d is not valid", fip->inode);
|
|
|
|
|
|
|
|
printf("RASH_TODO: inode %d is not valid - leaving\n", (tui32) fip->inode);
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* if filename is . or .. don't add it */
|
|
|
|
/* if filename is . or .. don't add it */
|
|
|
|
if ((strcmp(xinode->name, ".") == 0) || (strcmp(xinode->name, "..") == 0))
|
|
|
|
if ((strcmp(xinode->name, ".") == 0) || (strcmp(xinode->name, "..") == 0))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
free(xinode);
|
|
|
|
free(xinode);
|
|
|
|
|
|
|
|
printf("RASH_TODO: not adding ./.. - leaving\n");
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// LK_TODO
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
/* we have a parent inode and a dir name; what we need is the xinode */
|
|
|
|
/* we have a parent inode and a dir name; what we need is the xinode */
|
|
|
|
/* that matches the parent inode and the dir name */
|
|
|
|
/* that matches the parent inode and the dir name */
|
|
|
|
target_inode = xfuse_get_inode_from_pinode_name(fip->inode, fip->name);
|
|
|
|
target_inode = xfuse_get_inode_from_pinode_name(fip->inode, fip->name);
|
|
|
|
if (target_inode == 0)
|
|
|
|
if (target_inode == 0)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
log_debug("did not find entry with inode=%d name=%s",
|
|
|
|
|
|
|
|
fip->inode, fip->name);
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
if (xfuse_does_file_exist(target_inode->inode, xinode->name))
|
|
|
|
if ((xip = xfuse_get_inode_from_pinode_name(fip->inode, xinode->name)) != NULL)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
log_debug("inode=%d name=%s already exists in xrdp_fs; not adding it",
|
|
|
|
|
|
|
|
fip->inode, xinode->name);
|
|
|
|
free(xinode);
|
|
|
|
free(xinode);
|
|
|
|
return;
|
|
|
|
xinode = xip;
|
|
|
|
|
|
|
|
goto update_fuse;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
xinode->parent_inode = target_inode->inode;
|
|
|
|
xinode->parent_inode = fip->inode;
|
|
|
|
xinode->inode = g_xrdp_fs.next_node++;
|
|
|
|
xinode->inode = g_xrdp_fs.next_node++;
|
|
|
|
xinode->uid = getuid();
|
|
|
|
xinode->uid = getuid();
|
|
|
|
xinode->gid = getgid();
|
|
|
|
xinode->gid = getgid();
|
|
|
@ -1239,21 +1350,230 @@ void xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode)
|
|
|
|
|
|
|
|
|
|
|
|
g_xrdp_fs.num_entries++;
|
|
|
|
g_xrdp_fs.num_entries++;
|
|
|
|
|
|
|
|
|
|
|
|
/* insert it in xrdp fs */
|
|
|
|
/* insert it in xrdp fs and update lookup count */
|
|
|
|
g_xrdp_fs.inode_table[xinode->inode] = xinode;
|
|
|
|
g_xrdp_fs.inode_table[xinode->inode] = xinode;
|
|
|
|
|
|
|
|
g_xrdp_fs.inode_table[fip->inode]->nentries;
|
|
|
|
|
|
|
|
xfuse_update_xrdpfs_size();
|
|
|
|
|
|
|
|
|
|
|
|
/* bump up lookup count */
|
|
|
|
update_fuse:
|
|
|
|
xinode = g_xrdp_fs.inode_table[target_inode->inode];
|
|
|
|
|
|
|
|
xinode->nentries++;
|
|
|
|
#if 1
|
|
|
|
|
|
|
|
/* let FUSE know about this entry */
|
|
|
|
|
|
|
|
if (fip->invoke_fuse)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
struct dirbuf b;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
memset(&b, 0, sizeof(struct dirbuf));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* RASH_TODO if we are not using dirbuf, change this code */
|
|
|
|
|
|
|
|
if (fip->dirbuf == NULL)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
fip->dirbuf = calloc(1, sizeof(struct dirbuf));
|
|
|
|
|
|
|
|
xfuse_dirbuf_add(fip->req, &b, ".", xinode->inode);
|
|
|
|
|
|
|
|
xfuse_dirbuf_add(fip->req, &b, "..", xinode->parent_inode);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
xfuse_dirbuf_add(fip->req, &b, xinode->name, xinode->inode);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (fip->off < b.size)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
printf("RASH_TODO: xfuse_devredir_cb_enum_dir(): req=%p off=%d\n",
|
|
|
|
|
|
|
|
fip->req, (tui32) fip->off);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
printf("RASH_TODO: xfuse_devredir_cb_enum_dir(): dumping req b4\n\n");
|
|
|
|
|
|
|
|
g_hexdump((char *) fip->req, 128);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
printf("RASH_TODO: xfuse_devredir_cb_enum_dir(): dumping buf b4\n\n");
|
|
|
|
|
|
|
|
g_hexdump(b.p, b.size);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
printf("RASH_TODO: xfuse_devredir_cb_enum_dir(): calling fuse\n");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fuse_reply_buf(fip->req, b.p, b.size);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
printf("RASH_TODO: xfuse_devredir_cb_enum_dir(): calling fuse...done\n");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
printf("RASH_TODO: xfuse_devredir_cb_enum_dir(): dumping req aft\n\n");
|
|
|
|
|
|
|
|
g_hexdump((char *) fip->req, 128);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
printf("RASH_TODO: xfuse_devredir_cb_enum_dir(): dumping buf aft\n\n");
|
|
|
|
|
|
|
|
g_hexdump(b.p, b.size);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
printf("RASH_TODO: xfuse_devredir_cb_enum_dir(): calling fuse with NULL\n");
|
|
|
|
|
|
|
|
fuse_reply_buf(fip->req, NULL, 0);
|
|
|
|
|
|
|
|
printf("RASH_TODO: xfuse_devredir_cb_enum_dir(): calling fuse with NULL...done\n");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
log_debug("added inode=%d name=%s to FUSE", (tui32) xinode->inode, xinode->name);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
log_debug("leaving");
|
|
|
|
|
|
|
|
printf("RASH_TODO: xfuse_devredir_cb_enum_dir(): leaving\n");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
XFUSE_INFO *fip = (XFUSE_INFO *) vp;
|
|
|
|
|
|
|
|
XRDP_INODE *xip = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ((fip == NULL) || (xinode == NULL))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
log_error("fip or xinode are NULL");
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
log_debug("added %s to pinode=%d, nentries=%d target_inode->inode=%d",
|
|
|
|
|
|
|
|
fip->name, fip->inode, xinode->nentries, target_inode->inode);
|
|
|
|
if (!xfuse_is_inode_valid(fip->inode))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
log_error("inode %d is not valid", fip->inode);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* if filename is . or .. don't add it */
|
|
|
|
|
|
|
|
if ((strcmp(xinode->name, ".") == 0) || (strcmp(xinode->name, "..") == 0))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
free(xinode);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ((xip = xfuse_get_inode_from_pinode_name(fip->inode, xinode->name)) != NULL)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
log_debug("inode=%d name=%s already exists in xrdp_fs; not adding it",
|
|
|
|
|
|
|
|
fip->inode, xinode->name);
|
|
|
|
|
|
|
|
free(xinode);
|
|
|
|
|
|
|
|
xinode = xip;
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
xinode->parent_inode = fip->inode;
|
|
|
|
|
|
|
|
xinode->inode = g_xrdp_fs.next_node++;
|
|
|
|
|
|
|
|
xinode->uid = getuid();
|
|
|
|
|
|
|
|
xinode->gid = getgid();
|
|
|
|
|
|
|
|
xinode->device_id = fip->device_id;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
g_xrdp_fs.num_entries++;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* insert it in xrdp fs and update lookup count */
|
|
|
|
|
|
|
|
g_xrdp_fs.inode_table[xinode->inode] = xinode;
|
|
|
|
|
|
|
|
g_xrdp_fs.inode_table[fip->inode]->nentries;
|
|
|
|
|
|
|
|
xfuse_update_xrdpfs_size();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
*****************************************************************************/
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
void xfuse_devredir_cb_enum_dir_done(void *vp, tui32 IoStatus)
|
|
|
|
void xfuse_devredir_cb_enum_dir_done(void *vp, tui32 IoStatus)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
log_debug(">>>>>> vp=%p IoStatus=0x%x", vp, IoStatus);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (vp == NULL)
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
XRDP_INODE *xinode;
|
|
|
|
|
|
|
|
XRDP_INODE *ti;
|
|
|
|
|
|
|
|
struct dirbuf1 b;
|
|
|
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
int first_time = 1;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
XFUSE_INFO *fip = (XFUSE_INFO *) vp;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (fip == NULL)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
log_debug("fip is NULL");
|
|
|
|
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (IoStatus != 0)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
/* command failed */
|
|
|
|
|
|
|
|
if (fip->invoke_fuse)
|
|
|
|
|
|
|
|
fuse_reply_err(fip->req, ENOENT);
|
|
|
|
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* do we have a valid inode? */
|
|
|
|
|
|
|
|
if (!xfuse_is_inode_valid(fip->inode))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
log_error("inode %d is not valid", fip->inode);
|
|
|
|
|
|
|
|
if (fip->invoke_fuse)
|
|
|
|
|
|
|
|
fuse_reply_err(fip->req, EBADF);
|
|
|
|
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
|
|
|
memset(&b, 0, sizeof(struct dirbuf));
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
b.bytes_in_buf = 0;
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
for (i = FIRST_INODE; i < g_xrdp_fs.num_entries; i++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if ((xinode = g_xrdp_fs.inode_table[i]) == NULL)
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* match parent inode */
|
|
|
|
|
|
|
|
if (xinode->parent_inode != fip->inode)
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
xinode->is_synced = 1;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (first_time)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
first_time = 0;
|
|
|
|
|
|
|
|
ti = g_xrdp_fs.inode_table[fip->inode];
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
|
|
|
xfuse_dirbuf_add(fip->req, &b, ".", fip->inode);
|
|
|
|
|
|
|
|
xfuse_dirbuf_add(fip->req, &b, "..", ti->parent_inode);
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
xfuse_dirbuf_add1(fip->req, &b, ".", fip->inode);
|
|
|
|
|
|
|
|
xfuse_dirbuf_add1(fip->req, &b, "..", ti->parent_inode);
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
|
|
|
xfuse_dirbuf_add(fip->req, &b, xinode->name, xinode->inode);
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
xfuse_dirbuf_add1(fip->req, &b, xinode->name, xinode->inode);
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ((first_time == 0) && (fip->invoke_fuse))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (fip->off < b.bytes_in_buf)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
|
|
|
fuse_reply_buf(fip->req, b.p + fip->off,
|
|
|
|
|
|
|
|
min(b.size - fip->off, fip->size));
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
fuse_reply_buf(fip->req, b.buf, b.bytes_in_buf);
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
fuse_reply_buf(fip->req, NULL, 0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
fuse_reply_buf(fip->req, NULL, 0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
fuse_reply_err(fip->req, ENOENT);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
done:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
|
|
|
if (b.p)
|
|
|
|
|
|
|
|
free(b.p);
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!fip)
|
|
|
|
|
|
|
|
printf("###### %s : %s : %d: fip is NULL\n", __FILE__, __func__, __LINE__);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (fip)
|
|
|
|
|
|
|
|
free(fip);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void xfuse_devredir_cb_enum_dir_done_TODO(void *vp, tui32 IoStatus)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
struct xrdp_inode *xinode;
|
|
|
|
struct xrdp_inode *xinode;
|
|
|
|
struct fuse_entry_param e;
|
|
|
|
struct fuse_entry_param e;
|
|
|
@ -1261,6 +1581,8 @@ void xfuse_devredir_cb_enum_dir_done(void *vp, tui32 IoStatus)
|
|
|
|
|
|
|
|
|
|
|
|
XFUSE_INFO *fip = (XFUSE_INFO *) vp;
|
|
|
|
XFUSE_INFO *fip = (XFUSE_INFO *) vp;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
printf("--------- xfuse_devredir_cb_enum_dir_done() entered\n");
|
|
|
|
|
|
|
|
|
|
|
|
xfuse_dump_fs();
|
|
|
|
xfuse_dump_fs();
|
|
|
|
|
|
|
|
|
|
|
|
if (fip == NULL)
|
|
|
|
if (fip == NULL)
|
|
|
@ -1598,6 +1920,49 @@ void xfuse_devredir_cb_file_close(void *vp)
|
|
|
|
*****************************************************************************/
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
static void xfuse_cb_lookup(fuse_req_t req, fuse_ino_t parent, const char *name)
|
|
|
|
static void xfuse_cb_lookup(fuse_req_t req, fuse_ino_t parent, const char *name)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
XRDP_INODE *xinode;
|
|
|
|
|
|
|
|
struct fuse_entry_param e;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
log_debug("looking for parent=%d name=%s", (int) parent, name);
|
|
|
|
|
|
|
|
xfuse_dump_fs();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!xfuse_is_inode_valid(parent))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
log_error("inode %d is not valid", parent);
|
|
|
|
|
|
|
|
fuse_reply_err(req, EBADF);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
xinode = xfuse_get_inode_from_pinode_name(parent, name);
|
|
|
|
|
|
|
|
if (xinode == NULL)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
log_debug("did not find entry for parent=%d name=%s", parent, name);
|
|
|
|
|
|
|
|
fuse_reply_err(req, ENOENT);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
memset(&e, 0, sizeof(e));
|
|
|
|
|
|
|
|
e.ino = xinode->inode;
|
|
|
|
|
|
|
|
e.attr_timeout = XFUSE_ATTR_TIMEOUT;
|
|
|
|
|
|
|
|
e.entry_timeout = XFUSE_ENTRY_TIMEOUT;
|
|
|
|
|
|
|
|
e.attr.st_ino = xinode->inode;
|
|
|
|
|
|
|
|
e.attr.st_mode = xinode->mode;
|
|
|
|
|
|
|
|
e.attr.st_nlink = xinode->nlink;
|
|
|
|
|
|
|
|
e.attr.st_uid = xinode->uid;
|
|
|
|
|
|
|
|
e.attr.st_gid = xinode->gid;
|
|
|
|
|
|
|
|
e.attr.st_size = xinode->size;
|
|
|
|
|
|
|
|
e.attr.st_atime = xinode->atime;
|
|
|
|
|
|
|
|
e.attr.st_mtime = xinode->mtime;
|
|
|
|
|
|
|
|
e.attr.st_ctime = xinode->ctime;
|
|
|
|
|
|
|
|
e.generation = 1;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fuse_reply_entry(req, &e);
|
|
|
|
|
|
|
|
log_debug("found entry for parent=%d name=%s", parent, name);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void xfuse_cb_lookup_TODO(fuse_req_t req, fuse_ino_t parent, const char *name)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
XFUSE_INFO *fip;
|
|
|
|
XFUSE_INFO *fip;
|
|
|
|
XRDP_INODE *xinode;
|
|
|
|
XRDP_INODE *xinode;
|
|
|
@ -1606,6 +1971,9 @@ static void xfuse_cb_lookup(fuse_req_t req, fuse_ino_t parent, const char *name)
|
|
|
|
char full_path[4096];
|
|
|
|
char full_path[4096];
|
|
|
|
char *cptr;
|
|
|
|
char *cptr;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* SPEEDUP_TODO */
|
|
|
|
|
|
|
|
printf("###### cb_lookup: looking for parent=%d name=%s\n", (int) parent, name);
|
|
|
|
|
|
|
|
|
|
|
|
log_debug("ENTERED: looking for parent=%d name=%s", (int) parent, name);
|
|
|
|
log_debug("ENTERED: looking for parent=%d name=%s", (int) parent, name);
|
|
|
|
|
|
|
|
|
|
|
|
xfuse_dump_fs();
|
|
|
|
xfuse_dump_fs();
|
|
|
@ -1619,7 +1987,7 @@ static void xfuse_cb_lookup(fuse_req_t req, fuse_ino_t parent, const char *name)
|
|
|
|
|
|
|
|
|
|
|
|
if ((xinode = xfuse_get_inode_from_pinode_name(parent, name)) != NULL)
|
|
|
|
if ((xinode = xfuse_get_inode_from_pinode_name(parent, name)) != NULL)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
log_debug("LK_TODO: got match: device_id=%d", xinode->device_id);
|
|
|
|
log_debug("got match: device_id=%d", xinode->device_id);
|
|
|
|
|
|
|
|
|
|
|
|
/* got a full match; if this dir is located on a remote device */
|
|
|
|
/* got a full match; if this dir is located on a remote device */
|
|
|
|
/* and is not synced, do a remote look up */
|
|
|
|
/* and is not synced, do a remote look up */
|
|
|
@ -1659,13 +2027,15 @@ do_remote_lookup:
|
|
|
|
/* if ino belongs to a redirected share, pass the call to devredir; */
|
|
|
|
/* if ino belongs to a redirected share, pass the call to devredir; */
|
|
|
|
/* when done, devredir will invoke xfuse_devredir_cb_enum_dir_done(...) */
|
|
|
|
/* when done, devredir will invoke xfuse_devredir_cb_enum_dir_done(...) */
|
|
|
|
strcpy(full_path, name);
|
|
|
|
strcpy(full_path, name);
|
|
|
|
log_debug("LK_TODO: full_path=%s name=%s", full_path, name);
|
|
|
|
log_debug("full_path=%s name=%s", full_path, name);
|
|
|
|
device_id = xfuse_get_device_id_for_inode((tui32) parent, full_path);
|
|
|
|
device_id = xfuse_get_device_id_for_inode((tui32) parent, full_path);
|
|
|
|
log_debug("device_id=%d", device_id);
|
|
|
|
log_debug("device_id=%d", device_id);
|
|
|
|
if (device_id != 0)
|
|
|
|
if (device_id != 0)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
log_debug("did not find entry; redirecting call to dev_redir");
|
|
|
|
log_debug("did not find entry; redirecting call to dev_redir");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
printf("????????? xfuse_cb_lookup() doing remote lookup for %s\n", name);
|
|
|
|
|
|
|
|
|
|
|
|
if ((fip = calloc(1, sizeof(XFUSE_INFO))) == NULL)
|
|
|
|
if ((fip = calloc(1, sizeof(XFUSE_INFO))) == NULL)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
log_error("system out of memory");
|
|
|
|
log_error("system out of memory");
|
|
|
@ -1729,7 +2099,7 @@ static void xfuse_cb_getattr(fuse_req_t req, fuse_ino_t ino,
|
|
|
|
|
|
|
|
|
|
|
|
(void) fi;
|
|
|
|
(void) fi;
|
|
|
|
|
|
|
|
|
|
|
|
log_debug("ino=%d", (int) ino);
|
|
|
|
log_debug("req=%p ino=%d", req, (int) ino);
|
|
|
|
|
|
|
|
|
|
|
|
/* if ino is not valid, just return */
|
|
|
|
/* if ino is not valid, just return */
|
|
|
|
if (!xfuse_is_inode_valid(ino))
|
|
|
|
if (!xfuse_is_inode_valid(ino))
|
|
|
@ -1740,7 +2110,6 @@ static void xfuse_cb_getattr(fuse_req_t req, fuse_ino_t ino,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
xino = g_xrdp_fs.inode_table[ino];
|
|
|
|
xino = g_xrdp_fs.inode_table[ino];
|
|
|
|
xfuse_dump_xrdp_inode(xino);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
memset(&stbuf, 0, sizeof(stbuf));
|
|
|
|
memset(&stbuf, 0, sizeof(stbuf));
|
|
|
|
stbuf.st_ino = ino;
|
|
|
|
stbuf.st_ino = ino;
|
|
|
@ -1749,6 +2118,7 @@ static void xfuse_cb_getattr(fuse_req_t req, fuse_ino_t ino,
|
|
|
|
stbuf.st_size = xino->size;
|
|
|
|
stbuf.st_size = xino->size;
|
|
|
|
|
|
|
|
|
|
|
|
fuse_reply_attr(req, &stbuf, 1.0);
|
|
|
|
fuse_reply_attr(req, &stbuf, 1.0);
|
|
|
|
|
|
|
|
log_debug("exiting");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -1772,12 +2142,209 @@ static void xfuse_dirbuf_add(fuse_req_t req, struct dirbuf *b,
|
|
|
|
b->size);
|
|
|
|
b->size);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int xfuse_dirbuf_add1(fuse_req_t req, struct dirbuf1 *b,
|
|
|
|
|
|
|
|
const char *name, fuse_ino_t ino)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
struct stat stbuf;
|
|
|
|
|
|
|
|
int len;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
len = fuse_add_direntry(req, NULL, 0, name, NULL, 0);
|
|
|
|
|
|
|
|
if (b->bytes_in_buf + len > 4096)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
log_debug("not adding entry because dirbuf overflow would occur");
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
memset(&stbuf, 0, sizeof(stbuf));
|
|
|
|
|
|
|
|
stbuf.st_ino = ino;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fuse_add_direntry(req,
|
|
|
|
|
|
|
|
&b->buf[b->bytes_in_buf], /* index where new entry will be added to buf */
|
|
|
|
|
|
|
|
4096 - len, /* remaining size of buf */
|
|
|
|
|
|
|
|
name, /* name of entry */
|
|
|
|
|
|
|
|
&stbuf, /* file attributes */
|
|
|
|
|
|
|
|
b->bytes_in_buf + len /* offset of next entry */
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
b->bytes_in_buf += len;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*****************************************************************************/
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
static void xfuse_cb_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
|
|
|
|
static void xfuse_cb_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
|
|
|
|
off_t off, struct fuse_file_info *fi)
|
|
|
|
off_t off, struct fuse_file_info *fi)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
XRDP_INODE *xinode;
|
|
|
|
|
|
|
|
XFUSE_INFO *fip;
|
|
|
|
|
|
|
|
tui32 device_id;
|
|
|
|
|
|
|
|
char full_path[4096];
|
|
|
|
|
|
|
|
char *cptr;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
log_debug("req=%p inode=%d size=%d offset=%d", req, ino, size, off);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!xfuse_is_inode_valid(ino))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
log_error("inode %d is not valid", ino);
|
|
|
|
|
|
|
|
fuse_reply_err(req, EBADF);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
xinode = g_xrdp_fs.inode_table[ino];
|
|
|
|
|
|
|
|
if (xinode->device_id == 0)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
/* enumerate local resources */
|
|
|
|
|
|
|
|
xfuse_enum_dir(req, ino, size, off, fi);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* enumerate resources on a remote device */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// lK_TODO
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
struct dirbuf b;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
memset(&b, 0, sizeof(struct dirbuf));
|
|
|
|
|
|
|
|
xfuse_dirbuf_add(req, &b, ".", 1);
|
|
|
|
|
|
|
|
xfuse_dirbuf_add(req, &b, "..", 1);
|
|
|
|
|
|
|
|
xfuse_dirbuf_add(req, &b, "f2", 2);
|
|
|
|
|
|
|
|
if (off < b.size)
|
|
|
|
|
|
|
|
fuse_reply_buf(req, b.p + off, min(b.size - off, b.size));
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
fuse_reply_buf(req, NULL, 0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
xfuse_dirbuf_add(req, &b, "f3", 3);
|
|
|
|
|
|
|
|
if (off < b.size)
|
|
|
|
|
|
|
|
fuse_reply_buf(req, b.p + off, min(b.size - off, b.size));
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
fuse_reply_buf(req, NULL, 0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
xfuse_dirbuf_add(req, &b, "f4", 4);
|
|
|
|
|
|
|
|
if (off < b.size)
|
|
|
|
|
|
|
|
fuse_reply_buf(req, b.p + off, min(b.size - off, b.size));
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
fuse_reply_buf(req, NULL, 0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
xfuse_dirbuf_add(req, &b, "f5", 5);
|
|
|
|
|
|
|
|
if (off < b.size)
|
|
|
|
|
|
|
|
fuse_reply_buf(req, b.p + off, min(b.size - off, b.size));
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
fuse_reply_buf(req, NULL, 0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
xfuse_dirbuf_add(req, &b, "f6", 6);
|
|
|
|
|
|
|
|
if (off < b.size)
|
|
|
|
|
|
|
|
fuse_reply_buf(req, b.p + off, min(b.size - off, b.size));
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
fuse_reply_buf(req, NULL, 0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
xfuse_dirbuf_add(req, &b, "f7", 7);
|
|
|
|
|
|
|
|
if (off < b.size)
|
|
|
|
|
|
|
|
fuse_reply_buf(req, b.p + off, min(b.size - off, b.size));
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
fuse_reply_buf(req, NULL, 0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
xfuse_dirbuf_add(req, &b, "f8", 8);
|
|
|
|
|
|
|
|
if (off < b.size)
|
|
|
|
|
|
|
|
fuse_reply_buf(req, b.p + off, min(b.size - off, b.size));
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
fuse_reply_buf(req, NULL, 0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
xfuse_dirbuf_add(req, &b, "f9", 9);
|
|
|
|
|
|
|
|
if (off < b.size)
|
|
|
|
|
|
|
|
fuse_reply_buf(req, b.p + off, min(b.size - off, b.size));
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
fuse_reply_buf(req, NULL, 0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
xfuse_dirbuf_add(req, &b, "f10", 10);
|
|
|
|
|
|
|
|
if (off < b.size)
|
|
|
|
|
|
|
|
fuse_reply_buf(req, b.p + off, min(b.size - off, b.size));
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
fuse_reply_buf(req, NULL, 0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
xfuse_dirbuf_add(req, &b, "f11", 11);
|
|
|
|
|
|
|
|
if (off < b.size)
|
|
|
|
|
|
|
|
fuse_reply_buf(req, b.p + off, min(b.size - off, b.size));
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
fuse_reply_buf(req, NULL, 0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
xfuse_dirbuf_add(req, &b, "f12", 12);
|
|
|
|
|
|
|
|
if (off < b.size)
|
|
|
|
|
|
|
|
fuse_reply_buf(req, b.p + off, min(b.size - off, b.size));
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
fuse_reply_buf(req, NULL, 0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fuse_reply_buf(req, NULL, 0);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef USE_SYNC_FLAG
|
|
|
|
|
|
|
|
if (xinode->is_synced)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
xfuse_enum_dir(req, ino, size, off, fi);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
goto do_remote_lookup;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
do_remote_lookup:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
log_debug("did not find entry; redirecting call to dev_redir");
|
|
|
|
|
|
|
|
device_id = xfuse_get_device_id_for_inode((tui32) ino, full_path);
|
|
|
|
|
|
|
|
log_debug("dev_id=%d ino=%d full_path=%s", device_id, ino, full_path);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ((fip = calloc(1, sizeof(XFUSE_INFO))) == NULL)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
log_error("system out of memory");
|
|
|
|
|
|
|
|
fuse_reply_err(req, ENOMEM);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fip->req = req;
|
|
|
|
|
|
|
|
fip->inode = ino;
|
|
|
|
|
|
|
|
fip->size = size;
|
|
|
|
|
|
|
|
fip->off = off;
|
|
|
|
|
|
|
|
fip->fi = fi;
|
|
|
|
|
|
|
|
fip->dirbuf1.first_time = 1;
|
|
|
|
|
|
|
|
fip->dirbuf1.bytes_in_buf = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fip->invoke_fuse = 1;
|
|
|
|
|
|
|
|
fip->device_id = device_id;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* we want path minus 'root node of the share' */
|
|
|
|
|
|
|
|
if ((cptr = strchr(full_path, '/')) == NULL)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
/* enumerate root dir */
|
|
|
|
|
|
|
|
if (dev_redir_get_dir_listing((void *) fip, device_id, "\\"))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
log_error("failed to send dev_redir_get_dir_listing() cmd");
|
|
|
|
|
|
|
|
fuse_reply_buf(req, NULL, 0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (dev_redir_get_dir_listing((void *) fip, device_id, cptr))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
log_error("failed to send dev_redir_get_dir_listing() cmd");
|
|
|
|
|
|
|
|
fuse_reply_buf(req, NULL, 0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void xfuse_cb_readdir_TODO(fuse_req_t req, fuse_ino_t ino, size_t size,
|
|
|
|
|
|
|
|
off_t off, struct fuse_file_info *fi)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
struct xrdp_inode *xinode;
|
|
|
|
struct xrdp_inode *xinode;
|
|
|
|
struct dirbuf b;
|
|
|
|
struct dirbuf b;
|
|
|
@ -1785,6 +2352,9 @@ static void xfuse_cb_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
|
|
|
|
|
|
|
|
|
|
|
|
(void) fi;
|
|
|
|
(void) fi;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* SPEEDUP_TODO */
|
|
|
|
|
|
|
|
printf("++++++ cb_readdir: looking for inode=%d\n", (int) ino);
|
|
|
|
|
|
|
|
|
|
|
|
log_debug("looking for dir with inode=%d", ino);
|
|
|
|
log_debug("looking for dir with inode=%d", ino);
|
|
|
|
|
|
|
|
|
|
|
|
if (!xfuse_is_inode_valid(ino))
|
|
|
|
if (!xfuse_is_inode_valid(ino))
|
|
|
@ -1823,6 +2393,8 @@ static void xfuse_cb_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
|
|
|
|
fuse_reply_buf(req, NULL, 0);
|
|
|
|
fuse_reply_buf(req, NULL, 0);
|
|
|
|
|
|
|
|
|
|
|
|
free(b.p);
|
|
|
|
free(b.p);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
printf("++++++ cb_readdir: leaving\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -2132,7 +2704,7 @@ static void xfuse_create_dir_or_file(fuse_req_t req, fuse_ino_t parent,
|
|
|
|
const char *name, mode_t mode,
|
|
|
|
const char *name, mode_t mode,
|
|
|
|
struct fuse_file_info *fi, int type)
|
|
|
|
struct fuse_file_info *fi, int type)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
XFUSE_INFO *fip; // LK_TODO use only XFUSE_INFO instead of struct
|
|
|
|
XFUSE_INFO *fip;
|
|
|
|
char *cptr;
|
|
|
|
char *cptr;
|
|
|
|
char full_path[1024];
|
|
|
|
char full_path[1024];
|
|
|
|
tui32 device_id;
|
|
|
|
tui32 device_id;
|
|
|
|