summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sesman/chansrv/chansrv_fuse.c669
-rw-r--r--sesman/chansrv/chansrv_fuse.h1
-rw-r--r--sesman/chansrv/clipboard_file.c10
-rw-r--r--sesman/chansrv/devredir.c1
4 files changed, 204 insertions, 477 deletions
diff --git a/sesman/chansrv/chansrv_fuse.c b/sesman/chansrv/chansrv_fuse.c
index 76608be0..1e77eebc 100644
--- a/sesman/chansrv/chansrv_fuse.c
+++ b/sesman/chansrv/chansrv_fuse.c
@@ -18,24 +18,20 @@
/*
* TODO
- * o need to support sym links
* o when creating dir/file, ensure it does not already exist
- * o enable changing metadata for files/folders (time, owner, mode etc)
* o do not allow dirs to be created in ino==1 except for .clipbard and share mounts
- * o xrdp_fs needs to grow dynamically - currently it is fixed at 1k or 4k
* o fix the HACK where I have to use my own buf instead of g_buffer
* this is in func xfuse_check_wait_objs()
* o if fuse mount point is already mounted, I get segfault
* o in open, check for modes such as O_TRUNC, O_APPEND
* o copying over an existing file does not work
- * o need to keep track of open files, reqd during rename
- * o need to use dir notification for changed files and update xrdp fs
- * o copying over an existing file does not work
* o after a dir is created, the device cannot be unmounted on the client side
* so something is holding it up
+ * o in thunar, when I move a file by dragging to another folder, the file
+ * is getting copied instead of being moved
+ * o unable to edit files in vi
* o fuse ops to support
* o touch does not work
- * o keep track of lookup_count
* o chmod must work
* o cat >> file is not working
*
@@ -45,6 +41,7 @@
/* FUSE mount point */
char g_fuse_root_path[256] = "";
+char g_fuse_clipboard_path[256] = ""; /* for clipboard use */
#ifndef XRDP_FUSE
@@ -104,6 +101,7 @@ void xfuse_devredir_cb_file_close(void *vp) {}
#include "arch.h"
#include "os_calls.h"
#include "chansrv_fuse.h"
+#include "list.h"
#define min(x, y) ((x) < (y) ? (x) : (y))
@@ -201,8 +199,17 @@ struct xfuse_handle
};
typedef struct xfuse_handle XFUSE_HANDLE;
-/* globals */
+/* used for file data request sent to client */
+struct req_list_item
+{
+ fuse_req_t req;
+ int stream_id;
+ int lindex;
+ int off;
+ int size;
+};
+static struct list *g_req_list = 0;
static struct xrdp_fs g_xrdp_fs; /* an inst of xrdp file system */
static char *g_mount_point = 0; /* our FUSE mount point */
static struct fuse_lowlevel_ops g_xfuse_ops; /* setup FUSE callbacks */
@@ -257,6 +264,8 @@ int dev_redir_file_read(void *fusep, tui32 device_id, tui32 FileId,
int dev_redir_file_write(void *fusep, tui32 device_id, tui32 FileId,
const char *buf, tui32 Length, tui64 Offset);
+int devredir_file_close(void *fusep, tui32 device_id, tui32 FileId);
+
/* forward declarations for FUSE callbacks */
static void xfuse_cb_lookup(fuse_req_t req, fuse_ino_t parent,
const char *name);
@@ -311,36 +320,9 @@ static void xfuse_cb_create(fuse_req_t req, fuse_ino_t parent,
const char *name, mode_t mode,
struct fuse_file_info *fi);
-// LK_TODO may not need to be implemented
-#if 0
-static void xfuse_cb_statfs(fuse_req_t req, fuse_ino_t ino);
-
-static void xfuse_cb_setxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
- const char *value, size_t size, int flags);
-
-static void xfuse_cb_getxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
- size_t size);
-
-static void xfuse_cb_listxattr(fuse_req_t req, fuse_ino_t ino, size_t size);
-
-static void xfuse_cb_access(fuse_req_t req, fuse_ino_t ino, int mask);
-
-static void xfuse_cb_getlk(fuse_req_t req, fuse_ino_t ino,
- struct fuse_file_info *fi, struct flock *lock);
-
-static void xfuse_cb_setlk(fuse_req_t req, fuse_ino_t ino,
- struct fuse_file_info *fi, struct flock *lock,
- int sleep);
-
-static void xfuse_cb_ioctl(fuse_req_t req, fuse_ino_t ino, int cmd, void *arg,
- struct fuse_file_info *fi, unsigned flags,
- const void *in_buf, size_t in_bufsz,
- size_t out_bufsz);
-
-static void xfuse_cb_poll(fuse_req_t req, fuse_ino_t ino,
- struct fuse_file_info *fi,
- struct fuse_pollhandle *ph);
-#endif
+/* clipboard calls */
+int clipboard_request_file_data(int stream_id, int lindex, int offset,
+ int request_bytes);
static void xfuse_cb_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr,
int to_set, struct fuse_file_info *fi);
@@ -360,7 +342,6 @@ static void xfuse_cb_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr,
int xfuse_init()
{
struct fuse_args args = FUSE_ARGS_INIT(0, NULL);
- char opt[1024];
/* if already inited, just return */
if (g_xfuse_inited)
@@ -377,6 +358,7 @@ int xfuse_init()
/* define FUSE mount point to ~/xrdp_client */
g_snprintf(g_fuse_root_path, 255, "%s/xrdp_client", g_getenv("HOME"));
+ g_snprintf(g_fuse_clipboard_path, 255, "%s/.clipboard", g_fuse_root_path);
/* if FUSE mount point does not exist, create it */
if (!g_directory_exist(g_fuse_root_path))
@@ -409,28 +391,8 @@ int xfuse_init()
g_xfuse_ops.getattr = xfuse_cb_getattr;
g_xfuse_ops.setattr = xfuse_cb_setattr;
-#if 0
- g_xfuse_ops.statfs = xfuse_cb_statfs;
- g_xfuse_ops.listxattr = xfuse_cb_listxattr;
- g_xfuse_ops.getlk = xfuse_cb_getlk;
- g_xfuse_ops.setlk = xfuse_cb_setlk;
- g_xfuse_ops.ioctl = xfuse_cb_ioctl;
- g_xfuse_ops.poll = xfuse_cb_poll;
- g_xfuse_ops.access = xfuse_cb_access;
- g_xfuse_ops.setxattr = xfuse_cb_setxattr;
- g_xfuse_ops.getxattr = xfuse_cb_getxattr;
-#endif
-
fuse_opt_add_arg(&args, "xrdp-chansrv");
fuse_opt_add_arg(&args, g_fuse_root_path);
-#if 0
- sprintf(opt, "-o uid=%d,gid=%d", g_getuid(), g_getgid());
- fuse_opt_add_arg(&args, opt);
-#else
- /* disable multi threading */
- sprintf(opt, "-s");
- fuse_opt_add_arg(&args, opt);
-#endif
if (xfuse_init_lib(&args))
{
@@ -471,6 +433,12 @@ int xfuse_deinit()
g_buffer = 0;
}
+ if (g_req_list != 0)
+ {
+ list_delete(g_req_list);
+ g_req_list = 0;
+ }
+
g_xfuse_inited = 0;
return 0;
}
@@ -553,11 +521,11 @@ int xfuse_get_wait_objs(tbus *objs, int *count, int *timeout)
int xfuse_create_share(tui32 device_id, char *dirname)
{
- /* LK_TODO need to specify parent dir, mode */
-
+#if 0
XFUSE_INFO *fip;
+#endif
XRDP_INODE *xinode;
- tui32 saved_inode;
+ /* tui32 saved_inode; */
if (dirname == NULL || strlen(dirname) == 0)
return -1;
@@ -583,7 +551,7 @@ int xfuse_create_share(tui32 device_id, char *dirname)
xinode->device_id = device_id;
g_xrdp_fs.num_entries++;
- saved_inode = xinode->inode;
+ /* saved_inode = xinode->inode; */
/* insert it in xrdp fs */
g_xrdp_fs.inode_table[xinode->inode] = xinode;
@@ -605,7 +573,7 @@ int xfuse_create_share(tui32 device_id, char *dirname)
/* enumerate root dir, do not call FUSE when done */
fip->req = NULL;
- fip->inode = 1; // LK_TODO saved_inode;
+ fip->inode = 1; /* TODO saved_inode; */
strncpy(fip->name, dirname, 1024);
fip->name[1023] = 0;
fip->device_id = device_id;
@@ -617,36 +585,107 @@ int xfuse_create_share(tui32 device_id, char *dirname)
}
/**
+ * Clear all clipboard entries in xrdp_fs
*
+ * This function is called by clipboard code
*
* @return 0 on success, -1 on failure
*****************************************************************************/
int xfuse_clear_clip_dir(void)
{
- return 0; // CLIPBOARD_TODO
+ int i;
+ XRDP_INODE *xinode;
+ XRDP_INODE *xip;
+
+ log_debug("entered");
+
+ /* xinode for .clipboard */
+ xip = g_xrdp_fs.inode_table[2];
+
+ for (i = FIRST_INODE; i < g_xrdp_fs.num_entries; i++)
+ {
+ if ((xinode = g_xrdp_fs.inode_table[i]) == NULL)
+ continue;
+
+ if (xinode->parent_inode == 2)
+ {
+ g_xrdp_fs.inode_table[i] = NULL;
+ free(xinode);
+ xip->nentries--;
+ }
+ }
+
+ return 0;
}
/**
- *
+ * Return clipboard data to fuse
*
* @return 0 on success, -1 on failure
*****************************************************************************/
int xfuse_file_contents_range(int stream_id, char *data, int data_bytes)
{
- return 0; // CLIPBOARD_TODO
+ log_debug("entered: stream_id=%d data_bytes=%d", stream_id, data_bytes);
+
+ struct req_list_item *rli;
+
+ if ((rli = (struct req_list_item *) list_get_item(g_req_list, 0)) == NULL)
+ {
+ log_error("range error!");
+ return -1;
+ }
+
+ log_debug("lindex=%d off=%d size=%d", rli->lindex, rli->off, rli->size);
+
+ fuse_reply_buf(rli->req, data, data_bytes);
+
+ list_remove_item(g_req_list, 0);
+ if (g_req_list->count <= 0)
+ {
+ log_debug("completed all requests");
+ return 0;
+ }
+
+ /* send next request */
+ rli = (struct req_list_item *) list_get_item(g_req_list, 0);
+ if (rli == NULL)
+ {
+ log_error("range error!");
+ return -1;
+ }
+
+ log_debug("requesting clipboard file data");
+
+ clipboard_request_file_data(rli->stream_id, rli->lindex,
+ rli->off, rli->size);
+
+ return 0;
}
/**
+ * Create a file in .clipboard dir
*
+ * This function is called by clipboard code
*
* @return 0 on success, -1 on failure
*****************************************************************************/
int xfuse_add_clip_dir_item(char *filename, int flags, int size, int lindex)
{
- return 0; // CLIPBOARD_TODO
+ log_debug("entered: filename=%s flags=%d size=%d lindex=%d",
+ filename, flags, size, lindex);
+
+ /* add entry to xrdp_fs */
+ XRDP_INODE *xinode = xfuse_create_file_in_xrdp_fs(0, /* device id */
+ 2, /* parent inode */
+ filename,
+ S_IFREG);
+ xinode->size = size;
+ xinode->lindex = lindex;
+
+ return 0;
}
/**
@@ -657,7 +696,8 @@ int xfuse_add_clip_dir_item(char *filename, int flags, int size, int lindex)
int xfuse_file_contents_size(int stream_id, int file_size)
{
- return 0; // CLIPBOARD_TODO
+ log_debug("entered: stream_id=%d file_size=%d", stream_id, file_size);
+ return 0;
}
/*****************************************************************************
@@ -705,6 +745,9 @@ static int xfuse_init_lib(struct fuse_args *args)
g_buffer = calloc(g_bufsize, 1);
g_fd = fuse_chan_fd(g_ch);
+ g_req_list = list_create();
+ g_req_list->auto_free = 1;
+
return 0;
}
@@ -789,7 +832,7 @@ static int xfuse_init_xrdp_fs()
g_xrdp_fs.inode_table[2] = xino;
xino->parent_inode = 1;
xino->inode = 2;
- xino->nentries = 1;
+ xino->nentries = 0;
xino->mode = S_IFDIR | 0755;
xino->uid = getuid();
xino->gid = getgid();
@@ -1076,8 +1119,6 @@ static struct xrdp_inode * xfuse_create_file_in_xrdp_fs(tui32 device_id,
return NULL;
}
- log_debug("S_IFDIR=0x%x S_IFREG=0x%x type=0x%x", S_IFDIR, S_IFREG, type);
-
xinode->parent_inode = pinode;
xinode->inode = g_xrdp_fs.next_node++;
xinode->nlink = 1;
@@ -1458,7 +1499,7 @@ void xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode)
/* 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;
+ g_xrdp_fs.inode_table[fip->inode]->nentries++; /* this was missing */
xfuse_update_xrdpfs_size();
}
@@ -1759,7 +1800,6 @@ done:
void xfuse_devredir_cb_read_file(void *vp, char *buf, size_t length)
{
- XFUSE_HANDLE *fh;
XFUSE_INFO *fip;
fip = (XFUSE_INFO *) vp;
@@ -1773,7 +1813,6 @@ void xfuse_devredir_cb_read_file(void *vp, char *buf, size_t length)
void xfuse_devredir_cb_write_file(void *vp, char *buf, size_t length)
{
XRDP_INODE *xinode;
- XFUSE_HANDLE *fh;
XFUSE_INFO *fip;
fip = (XFUSE_INFO *) vp;
@@ -1962,131 +2001,6 @@ static void xfuse_cb_lookup(fuse_req_t req, fuse_ino_t parent, const char *name)
return;
}
-static void xfuse_cb_lookup_TODO(fuse_req_t req, fuse_ino_t parent, const char *name)
-{
- XFUSE_INFO *fip;
- XRDP_INODE *xinode;
- struct fuse_entry_param e;
- tui32 device_id;
- char full_path[4096];
- 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);
-
- xfuse_dump_fs();
-
- if (!xfuse_is_inode_valid(parent))
- {
- log_error("inode %d is not valid", parent);
- fuse_reply_err(req, EBADF);
- return;
- }
-
- if ((xinode = xfuse_get_inode_from_pinode_name(parent, name)) != NULL)
- {
- log_debug("got match: device_id=%d", xinode->device_id);
-
- /* got a full match; if this dir is located on a remote device */
- /* and is not synced, do a remote look up */
-#ifdef USE_SYNC_FLAG
- if ((xinode->device_id != 0) && (!xinode->is_synced))
- goto do_remote_lookup;
-#else
- if (xinode->device_id != 0)
- goto do_remote_lookup;
-#endif
- 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 in xrdp fs; returning");
- return;
- }
- else
- {
- log_debug("xinode is NULL for parent=%d name=%s", (int) parent, name);
- }
-
-do_remote_lookup:
-
- /* if ino belongs to a redirected share, pass the call to devredir; */
- /* when done, devredir will invoke xfuse_devredir_cb_enum_dir_done(...) */
- strcpy(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);
- log_debug("device_id=%d", device_id);
- if (device_id != 0)
- {
- 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)
- {
- log_error("system out of memory");
- fuse_reply_err(req, ENOMEM);
- return;
- }
- fip->req = req;
- fip->inode = parent;
- strncpy(fip->name, name, 1024);
- fip->name[1023] = 0;
- fip->invoke_fuse = 1;
- fip->device_id = device_id;
-
- if (parent != 1)
- {
- strcat(full_path, "/");
- strcat(full_path, name);
- }
-
- /* 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
- {
- log_debug("dev_redir_get_dir_listing() called");
- }
-
- }
- 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);
- }
- }
-
- log_debug("cmd sent; reting");
- return;
- }
-
- log_debug("parent=%d name=%s not found", (int) parent, name);
- fuse_reply_err(req, ENOENT);
-}
-
/**
* Get file attributes
*****************************************************************************/
@@ -2202,85 +2116,6 @@ static void xfuse_cb_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
/* 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)
{
@@ -2337,66 +2172,6 @@ do_remote_lookup:
}
}
-
-
-
-
-
-
-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 dirbuf b;
- int i;
-
- (void) fi;
-
- /* SPEEDUP_TODO */
- printf("++++++ cb_readdir: looking for inode=%d\n", (int) ino);
-
- log_debug("looking for dir with inode=%d", ino);
-
- if (!xfuse_is_inode_valid(ino))
- {
- log_error("inode %d is not valid", ino);
- fuse_reply_err(req, EBADF);
- return;
- }
-
- /* does this dir have any entries? */
- xinode = g_xrdp_fs.inode_table[ino];
- memset(&b, 0, sizeof(b));
- if (ino == 1)
- {
- xfuse_dirbuf_add(req, &b, ".", 1);
- xfuse_dirbuf_add(req, &b, "..", 1);
- }
- else
- {
- xfuse_dirbuf_add(req, &b, ".", xinode->inode);
- xfuse_dirbuf_add(req, &b, "..", xinode->parent_inode);
- }
-
- for (i = FIRST_INODE; i < g_xrdp_fs.num_entries; i++)
- {
- if ((xinode = g_xrdp_fs.inode_table[i]) == NULL)
- continue;
-
- if (xinode->parent_inode == ino)
- xfuse_dirbuf_add(req, &b, xinode->name, xinode->inode);
- }
-
- if (off < b.size)
- fuse_reply_buf(req, b.p + off, min(b.size - off, size));
- else
- fuse_reply_buf(req, NULL, 0);
-
- free(b.p);
-
- printf("++++++ cb_readdir: leaving\n");
-}
-
/**
* Create a directory
*****************************************************************************/
@@ -2816,56 +2591,53 @@ static void xfuse_cb_open(fuse_req_t req, fuse_ino_t ino,
}
device_id = xfuse_get_device_id_for_inode((tui32) ino, full_path);
- if (device_id)
+ if (device_id == 0)
{
- /* specified file resides on redirected share */
+ /* specified file is a local resource */
+ XFUSE_HANDLE *fh = calloc(1, sizeof(XFUSE_HANDLE));
+ fi->fh = (uint64_t) ((long) fh);
+ fuse_reply_open(req, fi);
+ return;
+ }
- if ((fip = calloc(1, sizeof(XFUSE_INFO))) == NULL)
- {
- log_error("system out of memory");
- fuse_reply_err(req, ENOMEM);
- return;
- }
+ /* specified file resides on redirected share */
+ 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->invoke_fuse = 1;
- fip->device_id = device_id;
- fip->fi = fi;
- strncpy(fip->name, full_path, 1024);
- fip->name[1023] = 0;
- fip->reply_type = RT_FUSE_REPLY_OPEN;
+ fip->req = req;
+ fip->inode = ino;
+ fip->invoke_fuse = 1;
+ fip->device_id = device_id;
+ fip->fi = fi;
+ strncpy(fip->name, full_path, 1024);
+ fip->name[1023] = 0;
+ fip->reply_type = RT_FUSE_REPLY_OPEN;
- /* LK_TODO need to handle open permissions */
+ /* LK_TODO need to handle open permissions */
- /* we want path minus 'root node of the share' */
- if ((cptr = strchr(full_path, '/')) == NULL)
- {
- /* get dev_redir to open the remote file */
- if (dev_redir_file_open((void *) fip, device_id, "\\",
- fi->flags, S_IFREG, NULL))
- {
- log_error("failed to send dev_redir_open_file() cmd");
- fuse_reply_err(req, EREMOTEIO);
- }
- }
- else
- {
- if (dev_redir_file_open((void *) fip, device_id, cptr,
- fi->flags, S_IFREG, NULL))
- {
- log_error("failed to send dev_redir_get_dir_listing() cmd");
- fuse_reply_err(req, EREMOTEIO);
- }
- }
+ /* we want path minus 'root node of the share' */
+ if ((cptr = strchr(full_path, '/')) == NULL)
+ {
+ /* get dev_redir to open the remote file */
+ if (dev_redir_file_open((void *) fip, device_id, "\\",
+ fi->flags, S_IFREG, NULL))
+ {
+ log_error("failed to send dev_redir_open_file() cmd");
+ fuse_reply_err(req, EREMOTEIO);
+ }
}
else
{
- /* specified file is a local resource */
- //XFUSE_HANDLE *fh;
-
- log_debug("LK_TODO: this is still a TODO");
- fuse_reply_err(req, EINVAL);
+ if (dev_redir_file_open((void *) fip, device_id, cptr,
+ fi->flags, S_IFREG, NULL))
+ {
+ log_error("failed to send dev_redir_get_dir_listing() cmd");
+ fuse_reply_err(req, EREMOTEIO);
+ }
}
}
@@ -2885,8 +2657,7 @@ static void xfuse_cb_flush(fuse_req_t req, fuse_ino_t ino, struct
if (handle->DeviceId == 0)
{
/* specified file is a local resource */
- log_debug("LK_TODO: this is still a TODO");
- fuse_reply_err(req, EBADF);
+ fuse_reply_err(req, 0);
return;
}
@@ -2918,11 +2689,13 @@ static void xfuse_cb_flush(fuse_req_t req, fuse_ino_t ino, struct
static void xfuse_cb_read(fuse_req_t req, fuse_ino_t ino, size_t size,
off_t off, struct fuse_file_info *fi)
{
- XFUSE_HANDLE *fh;
- XFUSE_INFO *fusep;
- long handle;
+ XFUSE_HANDLE *fh;
+ XFUSE_INFO *fusep;
+ XRDP_INODE *xinode;
+ struct req_list_item *rli;
+ long handle;
- log_debug("want_bytes %d bytes at off %d", size, off);
+ log_debug("want_bytes %ld bytes at off %ld", size, off);
if (fi->fh == 0)
{
@@ -2936,7 +2709,35 @@ static void xfuse_cb_read(fuse_req_t req, fuse_ino_t ino, size_t size,
if (fh->DeviceId == 0)
{
/* target file is in .clipboard dir */
- log_debug(">>>>>>>>>>>>>>>>> THIS IS STILL A TODO!");
+
+ log_debug("target file is in .clipboard dir");
+
+ if ((xinode = g_xrdp_fs.inode_table[ino]) == NULL)
+ {
+ log_error("ino does not exist in xrdp_fs");
+ fuse_reply_buf(req, 0, 0);
+ return;
+ }
+
+ rli = (struct req_list_item *)
+ g_malloc(sizeof(struct req_list_item), 1);
+
+ rli->stream_id = 0;
+ rli->req = req;
+ rli->lindex = xinode->lindex;
+ rli->off = off;
+ rli->size = size;
+ list_add_item(g_req_list, (tbus) rli);
+
+ if (g_req_list->count == 1)
+ {
+ log_debug("requesting clipboard file data lindex = %d off = %d size = %d",
+ rli->lindex, (int) off, (int) size);
+
+ clipboard_request_file_data(rli->stream_id, rli->lindex,
+ (int) off, (int) size);
+ }
+
return;
}
@@ -3007,88 +2808,12 @@ static void xfuse_cb_create(fuse_req_t req, fuse_ino_t parent,
xfuse_create_dir_or_file(req, parent, name, mode, fi, S_IFREG);
}
-// LK_TODO may not need to implement the following funcs
-
-#if 0
-static void xfuse_cb_statfs(fuse_req_t req, fuse_ino_t ino)
-{
- log_debug(">>>>>>>>>>>>>>>> LK_TODO: entered");
- fuse_reply_err(req, ENOMEM);
-}
-
-static void xfuse_cb_setxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
- const char *value, size_t size, int flags)
-{
- log_debug(">>>>>>>>>>>>>>>> LK_TODO: entered");
- fuse_reply_err(req, ENOMEM);
-
-}
-
-static void xfuse_cb_getxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
- size_t size)
-{
- log_debug(">>>>>>>>>>>>>>>> LK_TODO: entered");
- fuse_reply_err(req, ENOMEM);
-
-}
-
-static void xfuse_cb_listxattr(fuse_req_t req, fuse_ino_t ino, size_t size)
-{
- log_debug(">>>>>>>>>>>>>>>> LK_TODO: entered");
- fuse_reply_err(req, ENOMEM);
-
-}
-
-static void xfuse_cb_access(fuse_req_t req, fuse_ino_t ino, int mask)
-{
- log_debug(">>>>>>>>>>>>>>>> LK_TODO: entered");
- fuse_reply_err(req, ENOMEM);
-
-}
-
-static void xfuse_cb_getlk(fuse_req_t req, fuse_ino_t ino,
- struct fuse_file_info *fi, struct flock *lock)
-{
- log_debug(">>>>>>>>>>>>>>>> LK_TODO: entered");
- fuse_reply_err(req, ENOMEM);
-
-}
-
-static void xfuse_cb_setlk(fuse_req_t req, fuse_ino_t ino,
- struct fuse_file_info *fi, struct flock *lock,
- int sleep)
-{
- log_debug(">>>>>>>>>>>>>>>> LK_TODO: entered");
- fuse_reply_err(req, ENOMEM);
-
-}
-
-static void xfuse_cb_ioctl(fuse_req_t req, fuse_ino_t ino, int cmd, void *arg,
- struct fuse_file_info *fi, unsigned flags,
- const void *in_buf, size_t in_bufsz,
- size_t out_bufsz)
-{
- log_debug(">>>>>>>>>>>>>>>> LK_TODO: entered");
- fuse_reply_err(req, ENOMEM);
-
-}
-
-static void xfuse_cb_poll(fuse_req_t req, fuse_ino_t ino,
- struct fuse_file_info *fi,
- struct fuse_pollhandle *ph)
-{
- log_debug(">>>>>>>>>>>>>>>> LK_TODO: entered");
- fuse_reply_err(req, ENOMEM);
-
-}
-#endif
-
static void xfuse_cb_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr,
int to_set, struct fuse_file_info *fi)
{
XRDP_INODE *xinode;
- log_debug(">>>>>>>>>>>>>>>> LK_TODO: entered to_set=0x%x", to_set);
+ log_debug("entered to_set=0x%x", to_set);
if (!xfuse_is_inode_valid(ino))
{
@@ -3102,20 +2827,20 @@ static void xfuse_cb_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr,
if (to_set & FUSE_SET_ATTR_MODE)
{
xinode->mode = attr->st_mode;
- log_debug(">>>>>>>>>>>>>>>> LK_TODO: FUSE_SET_ATTR_MODE");
+ log_debug("FUSE_SET_ATTR_MODE");
}
if (to_set & FUSE_SET_ATTR_UID)
{
xinode->uid = attr->st_uid;
- log_debug(">>>>>>>>>>>>>>>> LK_TODO: FUSE_SET_ATTR_UID");
+ log_debug("FUSE_SET_ATTR_UID");
}
if (to_set & FUSE_SET_ATTR_GID)
{
xinode->gid = attr->st_gid;
- log_debug(">>>>>>>>>>>>>>>> LK_TODO: FUSE_SET_ATTR_GID");
+ log_debug("FUSE_SET_ATTR_GID");
}
if (to_set & FUSE_SET_ATTR_SIZE)
@@ -3128,25 +2853,25 @@ static void xfuse_cb_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr,
if (to_set & FUSE_SET_ATTR_ATIME)
{
xinode->atime = attr->st_atime;
- log_debug(">>>>>>>>>>>>>>>> LK_TODO: FUSE_SET_ATTR_ATIME");
+ log_debug("FUSE_SET_ATTR_ATIME");
}
if (to_set & FUSE_SET_ATTR_MTIME)
{
xinode->mtime = attr->st_mtime;
- log_debug(">>>>>>>>>>>>>>>> LK_TODO: FUSE_SET_ATTR_MTIME");
+ log_debug("FUSE_SET_ATTR_MTIME");
}
if (to_set & FUSE_SET_ATTR_ATIME_NOW)
{
xinode->atime = attr->st_atime;
- log_debug(">>>>>>>>>>>>>>>> LK_TODO: FUSE_SET_ATTR_ATIME_NOW");
+ log_debug("FUSE_SET_ATTR_ATIME_NOW");
}
if (to_set & FUSE_SET_ATTR_MTIME_NOW)
{
xinode->mtime = attr->st_mtime;
- log_debug(">>>>>>>>>>>>>>>> LK_TODO: FUSE_SET_ATTR_MTIME_NOW");
+ log_debug("FUSE_SET_ATTR_MTIME_NOW");
}
fuse_reply_attr(req, attr, 1.0); /* LK_TODO just faking for now */
diff --git a/sesman/chansrv/chansrv_fuse.h b/sesman/chansrv/chansrv_fuse.h
index e5dbbdc5..de4edc0b 100644
--- a/sesman/chansrv/chansrv_fuse.h
+++ b/sesman/chansrv/chansrv_fuse.h
@@ -38,6 +38,7 @@ struct xrdp_inode
tui32 device_id; /* for file system redirection */
char is_synced; /* dir struct has been read from */
/* remote device, done just once */
+ int lindex; /* used in clipboard operations */
};
typedef struct xrdp_inode XRDP_INODE; // LK_TODO use this instead of using struct xrdp_inode
diff --git a/sesman/chansrv/clipboard_file.c b/sesman/chansrv/clipboard_file.c
index 1942999d..42b5d4a3 100644
--- a/sesman/chansrv/clipboard_file.c
+++ b/sesman/chansrv/clipboard_file.c
@@ -53,7 +53,7 @@ extern int g_cliprdr_chan_id; /* in chansrv.c */
extern struct clip_s2c g_clip_s2c; /* in clipboard.c */
extern struct clip_c2s g_clip_c2s; /* in clipboard.c */
-extern char g_fuse_root_path[]; /* in chansrv_fuse.c */
+extern char g_fuse_clipboard_path[];
struct cb_file_info
{
@@ -454,7 +454,9 @@ clipboard_request_file_data(int stream_id, int lindex, int offset,
int size;
int rv;
- LLOGLN(10, ("clipboard_request_file_data:"));
+ LLOGLN(10, ("clipboard_request_file_data: stream_id=%d lindex=%d off=%d request_bytes=%d",
+ stream_id, lindex, offset, request_bytes));
+
if (g_file_request_sent_type != 0)
{
LLOGLN(0, ("clipboard_request_file_data: warning, still waiting "
@@ -625,8 +627,8 @@ clipboard_c2s_in_files(struct stream *s, char *file_list)
g_strcpy(ptr, "file://");
ptr += 7;
- str_len = g_strlen(g_fuse_root_path);
- g_strcpy(ptr, g_fuse_root_path);
+ str_len = g_strlen(g_fuse_clipboard_path);
+ g_strcpy(ptr, g_fuse_clipboard_path);
ptr += str_len;
*ptr = '/';
diff --git a/sesman/chansrv/devredir.c b/sesman/chansrv/devredir.c
index f09d7f07..50e1d961 100644
--- a/sesman/chansrv/devredir.c
+++ b/sesman/chansrv/devredir.c
@@ -1024,7 +1024,6 @@ int devredir_file_close(void *fusep, tui32 device_id, tui32 FileId)
if ((irp = dev_redir_irp_find_by_fileid(FileId)) == NULL)
{
log_error("no IRP found with FileId = %d", FileId);
- xfuse_devredir_cb_read_file(fusep, NULL, 0);
return -1;
}
#endif