diff options
author | Jay Sorg <jay.sorg@gmail.com> | 2012-11-03 18:47:04 -0700 |
---|---|---|
committer | Jay Sorg <jay.sorg@gmail.com> | 2012-11-03 18:47:04 -0700 |
commit | 900d66dc6e3541f52a884e0755d903cde7ce90ef (patch) | |
tree | 559ecb17d8db04ef4ffb2df79077b1e63459b747 /sesman/chansrv | |
parent | cdb039080f47ee31e97dcb88591e8194e03f3878 (diff) | |
download | xrdp-proprietary-900d66dc6e3541f52a884e0755d903cde7ce90ef.tar.gz xrdp-proprietary-900d66dc6e3541f52a884e0755d903cde7ce90ef.zip |
chansrv: work on clipboard file copy paste
Diffstat (limited to 'sesman/chansrv')
-rw-r--r-- | sesman/chansrv/chansrv.c | 3 | ||||
-rw-r--r-- | sesman/chansrv/chansrv_fuse.c | 306 | ||||
-rw-r--r-- | sesman/chansrv/chansrv_fuse.h | 14 | ||||
-rw-r--r-- | sesman/chansrv/clipboard.c | 12 | ||||
-rw-r--r-- | sesman/chansrv/clipboard_file.c | 55 | ||||
-rw-r--r-- | sesman/chansrv/clipboard_file.h | 3 |
6 files changed, 267 insertions, 126 deletions
diff --git a/sesman/chansrv/chansrv.c b/sesman/chansrv/chansrv.c index f48aa891..836a693b 100644 --- a/sesman/chansrv/chansrv.c +++ b/sesman/chansrv/chansrv.c @@ -373,6 +373,7 @@ process_message_channel_setup(struct stream *s) if (g_cliprdr_index >= 0) { clipboard_init(); + fuse_init(); } if (g_rdpsnd_index >= 0) @@ -396,8 +397,6 @@ process_message_channel_setup(struct stream *s) drdynvc_init(); } - fuse_init(); - return rv; } diff --git a/sesman/chansrv/chansrv_fuse.c b/sesman/chansrv/chansrv_fuse.c index d6a0daa5..b63a4ed0 100644 --- a/sesman/chansrv/chansrv_fuse.c +++ b/sesman/chansrv/chansrv_fuse.c @@ -56,9 +56,6 @@ static time_t g_time = 0; static int g_uid = 0; static int g_gid = 0; -extern struct file_item *g_file_items; /* in chansrv_file.c */ -extern int g_file_items_count; /* in chansrv_file.c */ - struct dirbuf { char *p; @@ -66,42 +63,103 @@ struct dirbuf int alloc_bytes; }; +struct xfuse_file_info +{ + int ino; + char pathname[256]; + char filename[256]; + int flags; + int size; + tui64 time; + struct xfuse_file_info* child; + struct xfuse_file_info* parent; + struct xfuse_file_info* next; + struct xfuse_file_info* prev; +}; + +static struct xfuse_file_info *g_fuse_files = 0; +static struct fuse_lowlevel_ops g_xrdp_ll_oper; +static int g_ino = 2; + /*****************************************************************************/ -static int APP_CC -xrdp_stat(fuse_ino_t ino, struct stat *stbuf) +static struct xfuse_file_info *APP_CC +fuse_find_file_info_by_name(struct xfuse_file_info *ffi, const char *filename) +{ + struct xfuse_file_info *rv; + struct xfuse_file_info *rv1; + + rv = ffi; + while (rv != 0) + { + if (g_strcmp(rv->filename, filename) == 0) + { + return rv; + } + if (rv->flags & 1) + { + rv1 = fuse_find_file_info_by_name(rv->child, filename); + if (rv1 != 0) + { + return rv1; + } + } + rv = rv->next; + } + return 0; +} + +/*****************************************************************************/ +static struct xfuse_file_info *APP_CC +fuse_find_file_info_by_ino(struct xfuse_file_info *ffi, int ino) { - int index; + struct xfuse_file_info *rv; + struct xfuse_file_info *rv1; - LLOGLN(10, ("xrdp_stat: ino %d", (int)ino)); - stbuf->st_ino = ino; - switch (ino) + rv = ffi; + while (rv != 0) { - case 1: /* . */ - case 2: /* .. */ - stbuf->st_mode = S_IFDIR | 0755; - stbuf->st_nlink = 2; - stbuf->st_uid = g_uid; - stbuf->st_gid = g_gid; - stbuf->st_atime = g_time; - stbuf->st_mtime = g_time; - stbuf->st_ctime = g_time; - break; - - default: - index = ino - 3; - if (index < 0 || index >= g_file_items_count) + if (rv->ino == ino) + { + return rv; + } + if (rv->flags & 1) + { + rv1 = fuse_find_file_info_by_ino(rv->child, ino); + if (rv1 != 0) { - return -1; + return rv1; } - stbuf->st_mode = S_IFREG | 0444; - stbuf->st_nlink = 1; - stbuf->st_size = g_file_items[index].data_bytes; - stbuf->st_uid = g_uid; - stbuf->st_gid = g_gid; - stbuf->st_atime = g_time; - stbuf->st_mtime = g_time; - stbuf->st_ctime = g_time; - break; + } + rv = rv->next; + } + return 0; +} + +/*****************************************************************************/ +static int APP_CC +xrdp_ffi2stat(struct xfuse_file_info *ffi, struct stat *stbuf) +{ + stbuf->st_ino = ffi->ino; + if (ffi->flags & 1) + { + stbuf->st_mode = S_IFDIR | 0755; + stbuf->st_nlink = 2; + stbuf->st_uid = g_uid; + stbuf->st_gid = g_gid; + stbuf->st_atime = g_time; + stbuf->st_mtime = g_time; + stbuf->st_ctime = g_time; + } + else + { + stbuf->st_mode = S_IFREG | 0444; + stbuf->st_nlink = 1; + stbuf->st_size = ffi->size; + stbuf->st_uid = g_uid; + stbuf->st_gid = g_gid; + stbuf->st_atime = g_time; + stbuf->st_mtime = g_time; + stbuf->st_ctime = g_time; } return 0; } @@ -110,28 +168,27 @@ xrdp_stat(fuse_ino_t ino, struct stat *stbuf) static void DEFAULT_CC xrdp_ll_lookup(fuse_req_t req, fuse_ino_t parent, const char *name) { + struct xfuse_file_info *ffi; struct fuse_entry_param e; - int index; - LLOGLN(10, ("xrdp_ll_lookup: name %s", name)); + LLOGLN(0, ("xrdp_ll_lookup: name %s", name)); if (parent != 1) { fuse_reply_err(req, ENOENT); } else { - for (index = 0; index < g_file_items_count; index++) + ffi = fuse_find_file_info_by_name(g_fuse_files, name); + if (ffi != 0) { - if (g_strcmp(name, g_file_items[index].filename) == 0) - { - g_memset(&e, 0, sizeof(e)); - e.ino = g_file_items[index].ino; - e.attr_timeout = 1.0; - e.entry_timeout = 1.0; - xrdp_stat(e.ino, &e.attr); - fuse_reply_entry(req, &e); - return; - } + LLOGLN(0, ("xrdp_ll_lookup: name %s ino %d", name, ffi->ino)); + g_memset(&e, 0, sizeof(e)); + e.ino = ffi->ino; + e.attr_timeout = 1.0; + e.entry_timeout = 1.0; + xrdp_ffi2stat(ffi, &e.attr); + fuse_reply_entry(req, &e); + return; } } fuse_reply_err(req, ENOENT); @@ -142,9 +199,28 @@ static void DEFAULT_CC xrdp_ll_getattr(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi) { struct stat stbuf; + struct xfuse_file_info *ffi; + LLOGLN(0, ("xrdp_ll_getattr: ino %d", ino)); g_memset(&stbuf, 0, sizeof(stbuf)); - if (xrdp_stat(ino, &stbuf) == -1) + if (ino == 1) + { + stbuf.st_mode = S_IFDIR | 0755; + stbuf.st_nlink = 2; + stbuf.st_uid = g_uid; + stbuf.st_gid = g_gid; + stbuf.st_atime = g_time; + stbuf.st_mtime = g_time; + stbuf.st_ctime = g_time; + fuse_reply_attr(req, &stbuf, 1.0); + return; + } + ffi = fuse_find_file_info_by_ino(g_fuse_files, ino); + if (ffi == 0) + { + fuse_reply_err(req, ENOENT); + } + else if (xrdp_ffi2stat(ffi, &stbuf) == -1) { fuse_reply_err(req, ENOENT); } @@ -204,22 +280,25 @@ static void DEFAULT_CC xrdp_ll_readdir(fuse_req_t req, fuse_ino_t ino, size_t size, off_t off, struct fuse_file_info *fi) { + struct xfuse_file_info *ffi; struct dirbuf b; - int index; + LLOGLN(0, ("xrdp_ll_readdir: ino %d", ino)); if (ino != 1) { fuse_reply_err(req, ENOTDIR); } else { + ffi = g_fuse_files; g_memset(&b, 0, sizeof(b)); dirbuf_add(req, &b, ".", 1); - dirbuf_add(req, &b, "..", 2); - for (index = 0; index < g_file_items_count; index++) + dirbuf_add(req, &b, "..", 1); + while (ffi != 0) { - dirbuf_add(req, &b, g_file_items[index].filename, - g_file_items[index].ino); + LLOGLN(10, ("xrdp_ll_readdir: %s", ffi->filename)); + dirbuf_add(req, &b, ffi->filename, ffi->ino); + ffi = ffi->next; } reply_buf_limited(req, b.p, b.size, off, size); g_free(b.p); @@ -230,7 +309,7 @@ xrdp_ll_readdir(fuse_req_t req, fuse_ino_t ino, size_t size, static void DEFAULT_CC xrdp_ll_open(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi) { - LLOGLN(10, ("xrdp_ll_open: ino %d", (int)ino)); + LLOGLN(0, ("xrdp_ll_open: ino %d", (int)ino)); if (ino == 1 || ino == 2) { fuse_reply_err(req, EISDIR); @@ -242,6 +321,7 @@ xrdp_ll_open(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi) else { fuse_reply_open(req, fi); + clipboard_request_file_size(0, 0); } } @@ -250,30 +330,14 @@ static void DEFAULT_CC xrdp_ll_read(fuse_req_t req, fuse_ino_t ino, size_t size, off_t off, struct fuse_file_info *fi) { - int index; + char *data; - LLOGLN(10, ("xrdp_ll_read: %d %d %d", (int)ino, (int)off, (int)size)); - index = ino - 3; - if (index < 0 || index >= g_file_items_count) - { - } - else - { - reply_buf_limited(req, g_file_items[index].data, - g_file_items[index].data_bytes, - off, size); - } + LLOGLN(0, ("xrdp_ll_read: %d %d %d", (int)ino, (int)off, (int)size)); + data = (char *)g_malloc(size, 1); + reply_buf_limited(req, data, size, off, size); + g_free(data); } -static struct fuse_lowlevel_ops xrdp_ll_oper = -{ - .lookup = xrdp_ll_lookup, - .getattr = xrdp_ll_getattr, - .readdir = xrdp_ll_readdir, - .open = xrdp_ll_open, - .read = xrdp_ll_read, -}; - /*****************************************************************************/ /* returns error */ static int APP_CC @@ -296,8 +360,8 @@ fuse_init_lib(int argc, char **argv) fuse_opt_free_args(&args); return 1; } - g_se = fuse_lowlevel_new(&args, &xrdp_ll_oper, - sizeof(xrdp_ll_oper), 0); + g_se = fuse_lowlevel_new(&args, &g_xrdp_ll_oper, + sizeof(g_xrdp_ll_oper), 0); if (g_se == 0) { LLOGLN(0, ("fuse_init_lib: fuse_lowlevel_new failed")); @@ -315,16 +379,65 @@ fuse_init_lib(int argc, char **argv) } /*****************************************************************************/ +static int APP_CC +fuse_delete_dir_items(struct xfuse_file_info *ffi) +{ + struct xfuse_file_info *ffi1; + + while (ffi != 0) + { + if (ffi->flags & 1) + { + fuse_delete_dir_items(ffi->child); + } + ffi1 = ffi; + ffi = ffi->next; + g_free(ffi1); + } + return 0; +} + +/*****************************************************************************/ +int APP_CC +fuse_clear_clip_dir(void) +{ + fuse_delete_dir_items(g_fuse_files); + g_fuse_files = 0; + return 0; +} + +/*****************************************************************************/ /* returns error */ int APP_CC -fuse_set_dir_item(int index, char *filename, int flags, char *data, - int data_bytes, int ino) +fuse_add_clip_dir_item(char *filename, int flags, int size) { - g_strncpy(g_file_items[index].filename, filename, 255); - g_file_items[index].flags = flags; - g_memcpy(g_file_items[index].data, data, data_bytes); - g_file_items[index].data_bytes = data_bytes; - g_file_items[index].ino = ino; + struct xfuse_file_info *ffi; + struct xfuse_file_info *ffi1; + + LLOGLN(0, ("fuse_add_clip_dir_item: adding %s", filename)); + ffi = g_fuse_files; + if (ffi == 0) + { + ffi1 = (struct xfuse_file_info *) + g_malloc(sizeof(struct xfuse_file_info), 1); + ffi1->flags = flags; + ffi1->ino = g_ino++; + ffi1->size = size; + g_strncpy(ffi1->filename, filename, 255); + g_fuse_files = ffi1; + return 0; + } + while (ffi->next != 0) + { + ffi = ffi->next; + } + ffi1 = (struct xfuse_file_info *) + g_malloc(sizeof(struct xfuse_file_info), 1); + ffi1->flags = flags; + ffi1->ino = g_ino++; + ffi1->size = size; + g_strncpy(ffi1->filename, filename, 255); + ffi->next = ffi1; return 0; } @@ -399,11 +512,12 @@ fuse_init(void) argv[1] = root_path; argv[2] = 0; - g_file_items = g_malloc(sizeof(struct file_item) * 3, 1); - fuse_set_dir_item(0, "File1", 0, "1\n", 2, 3); - fuse_set_dir_item(1, "File2", 0, "2\n", 2, 4); - fuse_set_dir_item(2, "File3", 0, "3\n", 2, 5); - g_file_items_count = 3; + g_memset(&g_xrdp_ll_oper, 0, sizeof(g_xrdp_ll_oper)); + g_xrdp_ll_oper.lookup = xrdp_ll_lookup; + g_xrdp_ll_oper.getattr = xrdp_ll_getattr; + g_xrdp_ll_oper.readdir = xrdp_ll_readdir; + g_xrdp_ll_oper.open = xrdp_ll_open; + g_xrdp_ll_oper.read = xrdp_ll_read; return fuse_init_lib(2, argv); } @@ -432,12 +546,6 @@ fuse_deinit(void) g_free(g_buffer); g_buffer = 0; } - if (g_file_items != 0) - { - g_free(g_file_items); - g_file_items = 0; - g_file_items_count = 0; - } return 0; } @@ -475,8 +583,14 @@ fuse_deinit(void) /*****************************************************************************/ int APP_CC -fuse_set_dir_item(int index, char *filename, int flags, char *data, - int data_bytes, int ino) +fuse_clear_clip_dir(void) +{ + return 0; +} + +/*****************************************************************************/ +int APP_CC +fuse_add_clip_dir_item(char *filename, int flags, int size) { return 0; } diff --git a/sesman/chansrv/chansrv_fuse.h b/sesman/chansrv/chansrv_fuse.h index 8a9df8ab..80427699 100644 --- a/sesman/chansrv/chansrv_fuse.h +++ b/sesman/chansrv/chansrv_fuse.h @@ -2,18 +2,10 @@ #if !defined(CHANSRV_FUSE_H) #define CHANSRV_FUSE_H -struct file_item -{ - char filename[256]; - int flags; - char data[256]; - int data_bytes; - int ino; -}; - int APP_CC -fuse_set_dir_item(int index, char *filename, int flags, char *data, - int data_bytes, int ino); +fuse_clear_clip_dir(void); +int APP_CC +fuse_add_clip_dir_item(char *filename, int flags, int size); int APP_CC fuse_get_wait_objs(tbus *objs, int *count, int *timeout); int APP_CC diff --git a/sesman/chansrv/clipboard.c b/sesman/chansrv/clipboard.c index 3963cfef..9a2ab708 100644 --- a/sesman/chansrv/clipboard.c +++ b/sesman/chansrv/clipboard.c @@ -205,7 +205,6 @@ clipboard_init(void) fuse_init(); xcommon_init(); - clipboard_deinit(); g_incr_max_req_size = XMaxRequestSize(g_display) * 4 - 24; g_memset(&g_clip_c2s, 0, sizeof(g_clip_c2s)); g_memset(&g_clip_s2c, 0, sizeof(g_clip_s2c)); @@ -843,6 +842,7 @@ clipboard_process_format_announce(struct stream *s, int clip_msg_status, int count; int bytes; int got_file; + int file_format_id; char desc[256]; char *holdp; @@ -853,6 +853,7 @@ clipboard_process_format_announce(struct stream *s, int clip_msg_status, desc[0] = 0; g_num_formatIds = 0; got_file = 0; + file_format_id = 0; while (clip_msg_len > 3) { in_uint32_le(s, formatId); @@ -884,9 +885,12 @@ clipboard_process_format_announce(struct stream *s, int clip_msg_status, { LLOGLN(10, ("clipboard_process_format_announce: max formats")); } - if (formatId == 0x0000c0c8) + //if (formatId == 0x0000c0c8) + //if (formatId == 0x0000c0ed) + if (g_strcmp(desc, "FileGroupDescriptorW") == 0) { got_file = 1; + file_format_id = formatId; } } @@ -894,7 +898,9 @@ clipboard_process_format_announce(struct stream *s, int clip_msg_status, { LLOGLN(0, ("clipboard_process_format_announce: sending file list request")); g_clip_c2s.xrdp_clip_type = XRDP_CB_FILE; - clipboard_send_data_request(0x0000c0c8); + //clipboard_send_data_request(0x0000c0c8); + //clipboard_send_data_request(0x0000c0ed); + clipboard_send_data_request(file_format_id); return 0; } diff --git a/sesman/chansrv/clipboard_file.c b/sesman/chansrv/clipboard_file.c index 9175bfaf..e169d89f 100644 --- a/sesman/chansrv/clipboard_file.c +++ b/sesman/chansrv/clipboard_file.c @@ -47,14 +47,14 @@ } \ while (0) -struct file_item *g_file_items = 0; -int g_file_items_count = 0; - 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 struct file_item *g_file_items; /* in chansrv_fuse.c */ +//extern int g_file_items_count; /* in chansrv_fuse.c */ + struct cb_file_info { char pathname[256]; @@ -244,6 +244,7 @@ clipboard_get_files(char *files, int bytes) /*****************************************************************************/ /* server to client */ +/* response to client asking for clipboard contents that is file list */ int APP_CC clipboard_send_data_response_for_file(char *data, int data_size) { @@ -303,6 +304,7 @@ clipboard_send_data_response_for_file(char *data, int data_size) } /*****************************************************************************/ +/* send the file size from server to the client */ static int APP_CC clipboard_send_file_size(int streamId, int lindex) { @@ -332,6 +334,39 @@ clipboard_send_file_size(int streamId, int lindex) } /*****************************************************************************/ +/* ask the client to send the file size */ +int APP_CC +clipboard_request_file_size(int streamId, int lindex) +{ + struct stream *s; + int size; + int rv; + int file_size; + + file_size = g_files[lindex].size; + LLOGLN(10, ("clipboard_request_file_size:")); + make_stream(s); + init_stream(s, 8192); + out_uint16_le(s, CB_FILECONTENTS_REQUEST); /* 8 */ + out_uint16_le(s, 0); + out_uint32_le(s, 28); + out_uint32_le(s, streamId); + out_uint32_le(s, lindex); + out_uint32_le(s, CB_FILECONTENTS_SIZE); + out_uint32_le(s, 0); /* nPositionLow */ + out_uint32_le(s, 0); /* nPositionHigh */ + out_uint32_le(s, 0); /* cbRequested */ + out_uint32_le(s, 0); /* clipDataId */ + out_uint32_le(s, 0); + s_mark_end(s); + size = (int)(s->end - s->data); + rv = send_channel_data(g_cliprdr_chan_id, s->data, size); + free_stream(s); + return rv; +} + +/*****************************************************************************/ +/* send a chunk of the file from server to client */ static int APP_CC clipboard_send_file_data(int streamId, int lindex, int nPositionLow, int cbRequested) @@ -454,22 +489,14 @@ clipboard_c2s_in_files(struct stream *s) { tui32 cItems; struct clip_file_desc cfd; - int ino; - int index; in_uint32_le(s, cItems); - g_file_items_count = cItems; - g_free(g_file_items); - g_file_items = g_malloc(sizeof(struct file_item) * g_file_items_count, 1); - LLOGLN(10, ("clipboard_c2s_in_files: cItems %d", cItems)); - ino = 3; - index = 0; + fuse_clear_clip_dir(); + LLOGLN(0, ("clipboard_c2s_in_files: cItems %d", cItems)); while (cItems > 0) { clipboard_c2s_in_file_info(s, &cfd); - fuse_set_dir_item(index, cfd.cFileName, 0, "1\n", 2, ino); - index++; - ino++; + fuse_add_clip_dir_item(cfd.cFileName, 0, cfd.fileSizeLow); cItems--; } return 0; diff --git a/sesman/chansrv/clipboard_file.h b/sesman/chansrv/clipboard_file.h index 4537f1fe..37391c4c 100644 --- a/sesman/chansrv/clipboard_file.h +++ b/sesman/chansrv/clipboard_file.h @@ -30,4 +30,7 @@ clipboard_process_file_request(struct stream *s, int clip_msg_status, int APP_CC clipboard_c2s_in_files(struct stream *s); +int APP_CC +clipboard_request_file_size(int streamId, int lindex); + #endif |