diff --git a/common/file.c b/common/file.c index c8be7af5..05f243ca 100644 --- a/common/file.c +++ b/common/file.c @@ -242,8 +242,19 @@ l_file_read_section(int fd, int max_file_size, const char *section, for (index = 0; index < len; index++) { + if (!s_check_rem(s, 1)) + { + break; + } in_uint8(s, c); - + if ((c == '#') || (c == ';')) + { + file_read_line(s, text); + in_it = 0; + in_it_index = 0; + g_memset(text, 0, 512); + continue; + } if (c == '[') { in_it = 1; @@ -253,7 +264,6 @@ l_file_read_section(int fd, int max_file_size, const char *section, if (g_strcasecmp(section, text) == 0) { file_read_line(s, text); - while (file_read_line(s, text) == 0) { if (g_strlen(text) > 0) @@ -296,7 +306,6 @@ l_file_read_section(int fd, int max_file_size, const char *section, } } } - free_stream(s); return 1; } 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 diff --git a/tests/gtcp_proxy/hexdump.c b/tests/gtcp_proxy/hexdump.c new file mode 100644 index 00000000..c84b1d16 --- /dev/null +++ b/tests/gtcp_proxy/hexdump.c @@ -0,0 +1,130 @@ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Laxmikant Rashinkar 2013 LK.Rashinkar@gmail.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +/** + * An optimized hexdump function + * + * @param address address to display in address column + * @param buf data to hexdump + * @param len number of bytes to dump + *****************************************************************************/ + +void hexdump(int address, char *buf, int len) +{ + uint32_t addr; + char outbuf[80]; + int blocks; + int residual; + int i; + int j; + int buf_index; + int index2; /* data column */ + int index3; /* ascii column */ + + unsigned char c; + + char cvt[] = {'0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; + + if ((buf == NULL) || (len <= 0)) + return; + + addr = (address < 0) ? 0 : address; + blocks = len / 16; + residual = len - blocks * 16; + buf_index = 0; + + for (i = 0; i < blocks; i++) + { + index2 = 10; + index3 = 60; + + outbuf[9] = ' '; + outbuf[8] = ' '; + outbuf[7] = cvt[(addr >> 0) & 0x0000000f]; + outbuf[6] = cvt[(addr >> 4) & 0x0000000f]; + outbuf[5] = cvt[(addr >> 8) & 0x0000000f]; + outbuf[4] = cvt[(addr >> 12) & 0x0000000f]; + outbuf[3] = cvt[(addr >> 16) & 0x0000000f]; + outbuf[2] = cvt[(addr >> 20) & 0x0000000f]; + outbuf[1] = cvt[(addr >> 24) & 0x0000000f]; + outbuf[0] = cvt[(addr >> 28) & 0x0000000f]; + addr += 16; + + /* insert spaces */ + outbuf[8] = ' '; + outbuf[9] = ' '; + outbuf[58] = ' '; + outbuf[59] = ' '; + + for (j = 0; j < 16; j++) + { + c = buf[buf_index++]; + + outbuf[index2++] = cvt[(c >> 4) & 0x0f]; + outbuf[index2++] = cvt[(c >> 0) & 0x0f]; + outbuf[index2++] = ' '; + + if ((c >= 0x20) && (c <= 0x7e)) + outbuf[index3++] = c; + else + outbuf[index3++] = '.'; + } + + outbuf[index3] = 0; + puts(outbuf); + } + + if (!residual) + return; + + outbuf[7] = cvt[(addr >> 0) & 0x0000000f]; + outbuf[6] = cvt[(addr >> 4) & 0x0000000f]; + outbuf[5] = cvt[(addr >> 8) & 0x0000000f]; + outbuf[4] = cvt[(addr >> 12) & 0x0000000f]; + outbuf[3] = cvt[(addr >> 16) & 0x0000000f]; + outbuf[2] = cvt[(addr >> 20) & 0x0000000f]; + outbuf[1] = cvt[(addr >> 24) & 0x0000000f]; + outbuf[0] = cvt[(addr >> 28) & 0x0000000f]; + addr += 16; + + index2 = 10; + index3 = 60; + memset(&outbuf[8], ' ', 68); + + for (j = 0; j < residual; j++) + { + c = buf[buf_index++]; + + outbuf[index2++] = cvt[(c >> 4) & 0x0f]; + outbuf[index2++] = cvt[(c >> 0) & 0x0f]; + outbuf[index2++] = ' '; + + if ((c >= 0x20) && (c <= 0x7e)) + outbuf[index3++] = c; + else + outbuf[index3++] = '.'; + } + + outbuf[index3] = 0; + puts(outbuf); +}