chansrv: work on clipboard file copy

ulab-next
Jay Sorg 12 years ago
parent 900d66dc6e
commit e2ef19098b

@ -33,6 +33,7 @@
#include "os_calls.h" #include "os_calls.h"
#include "chansrv.h" #include "chansrv.h"
#include "chansrv_fuse.h" #include "chansrv_fuse.h"
#include "clipboard_file.h"
#define LLOG_LEVEL 1 #define LLOG_LEVEL 1
#define LLOGLN(_level, _args) \ #define LLOGLN(_level, _args) \
@ -56,6 +57,9 @@ static time_t g_time = 0;
static int g_uid = 0; static int g_uid = 0;
static int g_gid = 0; static int g_gid = 0;
/* used for file data request sent to client */
static fuse_req_t g_req = 0;
struct dirbuf struct dirbuf
{ {
char *p; char *p;
@ -66,6 +70,7 @@ struct dirbuf
struct xfuse_file_info struct xfuse_file_info
{ {
int ino; int ino;
int lindex;
char pathname[256]; char pathname[256];
char filename[256]; char filename[256];
int flags; int flags;
@ -252,8 +257,8 @@ dirbuf_add(fuse_req_t req, struct dirbuf *b, const char *name, fuse_ino_t ino)
} }
g_memset(&stbuf, 0, sizeof(stbuf)); g_memset(&stbuf, 0, sizeof(stbuf));
stbuf.st_ino = ino; stbuf.st_ino = ino;
fuse_add_direntry(req, b->p + oldsize, b->size - oldsize, name, &stbuf, fuse_add_direntry(req, b->p + oldsize, b->size - oldsize, name,
b->size); &stbuf, b->size);
} }
#define lmin(x, y) ((x) < (y) ? (x) : (y)) #define lmin(x, y) ((x) < (y) ? (x) : (y))
@ -331,11 +336,26 @@ xrdp_ll_read(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)
{ {
char *data; char *data;
int stream_id;
struct xfuse_file_info *ffi;
LLOGLN(0, ("xrdp_ll_read: %d %d %d", (int)ino, (int)off, (int)size)); LLOGLN(0, ("xrdp_ll_read: %d %d %d", (int)ino, (int)off, (int)size));
ffi = fuse_find_file_info_by_ino(g_fuse_files, ino);
if (ffi != 0)
{
stream_id = 0;
clipboard_request_file_data(stream_id, ffi->lindex, off, size);
g_req = req;
/* reply later */
return;
}
LLOGLN(0, ("xrdp_ll_read: fuse_find_file_info_by_ino failed"));
data = (char *)g_malloc(size, 1); data = (char *)g_malloc(size, 1);
reply_buf_limited(req, data, size, off, size); fuse_reply_buf(req, data, size);
g_free(data); g_free(data);
} }
/*****************************************************************************/ /*****************************************************************************/
@ -409,7 +429,7 @@ fuse_clear_clip_dir(void)
/*****************************************************************************/ /*****************************************************************************/
/* returns error */ /* returns error */
int APP_CC int APP_CC
fuse_add_clip_dir_item(char *filename, int flags, int size) fuse_add_clip_dir_item(char *filename, int flags, int size, int lindex)
{ {
struct xfuse_file_info *ffi; struct xfuse_file_info *ffi;
struct xfuse_file_info *ffi1; struct xfuse_file_info *ffi1;
@ -422,6 +442,7 @@ fuse_add_clip_dir_item(char *filename, int flags, int size)
g_malloc(sizeof(struct xfuse_file_info), 1); g_malloc(sizeof(struct xfuse_file_info), 1);
ffi1->flags = flags; ffi1->flags = flags;
ffi1->ino = g_ino++; ffi1->ino = g_ino++;
ffi1->lindex = lindex;
ffi1->size = size; ffi1->size = size;
g_strncpy(ffi1->filename, filename, 255); g_strncpy(ffi1->filename, filename, 255);
g_fuse_files = ffi1; g_fuse_files = ffi1;
@ -435,6 +456,7 @@ fuse_add_clip_dir_item(char *filename, int flags, int size)
g_malloc(sizeof(struct xfuse_file_info), 1); g_malloc(sizeof(struct xfuse_file_info), 1);
ffi1->flags = flags; ffi1->flags = flags;
ffi1->ino = g_ino++; ffi1->ino = g_ino++;
ffi1->lindex = lindex;
ffi1->size = size; ffi1->size = size;
g_strncpy(ffi1->filename, filename, 255); g_strncpy(ffi1->filename, filename, 255);
ffi->next = ffi1; ffi->next = ffi1;
@ -549,6 +571,23 @@ fuse_deinit(void)
return 0; return 0;
} }
/*****************************************************************************/
int APP_CC
fuse_file_contents_size(int stream_id, int file_size)
{
LLOGLN(0, ("fuse_file_contents_size: file_size %d", file_size));
return 0;
}
/*****************************************************************************/
int APP_CC
fuse_file_contents_range(int stream_id, char *data, int data_bytes)
{
LLOGLN(0, ("fuse_file_contents_range: data_bytes %d", data_bytes));
fuse_reply_buf(g_req, data, data_bytes);
return 0;
}
#else #else
#include "arch.h" #include "arch.h"
@ -590,7 +629,21 @@ fuse_clear_clip_dir(void)
/*****************************************************************************/ /*****************************************************************************/
int APP_CC int APP_CC
fuse_add_clip_dir_item(char *filename, int flags, int size) fuse_add_clip_dir_item(char *filename, int flags, int size, int lindex)
{
return 0;
}
/*****************************************************************************/
int APP_CC
fuse_file_contents_size(int stream_id, int file_size)
{
return 0;
}
/*****************************************************************************/
int APP_CC
fuse_file_contents_range(int stream_id, char *data, int data_bytes)
{ {
return 0; return 0;
} }

@ -5,7 +5,7 @@
int APP_CC int APP_CC
fuse_clear_clip_dir(void); fuse_clear_clip_dir(void);
int APP_CC int APP_CC
fuse_add_clip_dir_item(char *filename, int flags, int size); fuse_add_clip_dir_item(char *filename, int flags, int size, int lindex);
int APP_CC int APP_CC
fuse_get_wait_objs(tbus *objs, int *count, int *timeout); fuse_get_wait_objs(tbus *objs, int *count, int *timeout);
int APP_CC int APP_CC
@ -15,4 +15,9 @@ fuse_init(void);
int APP_CC int APP_CC
fuse_deinit(void); fuse_deinit(void);
int APP_CC
fuse_file_contents_size(int stream_id, int file_size);
int APP_CC
fuse_file_contents_range(int stream_id, char *data, int data_bytes);
#endif #endif

@ -42,6 +42,76 @@ TIMESTAMP
wininfo - show window info wininfo - show window info
xlsatoms - dump atoms xlsatoms - dump atoms
dolphin 1.4 KDE 4.4.5 copy one file
text/uri-list
text/x-moz-url
text/plain
UTF8_STRING
STRING
TEXT
COMPOUND_TEXT
application/x-qiconlist
TARGETS
MULTIPLE
TIMESTAMP
SAVE_TARGETS
kolourpaint 4.4.5 KDE 4.4.5 copy image area
application/x-kolourpaint-selection-400
application/x-qt-image
image/png
image/bw
image/eps
image/epsf
image/epsi
image/pcx
image/rgb
image/rgba
image/sgi
image/tga
image/bmp
image/ico
image/jp2
image/jpeg
image/jpg
image/ppm
PIXMAP
image/tif
image/tiff
image/xbm
image/xpm
image/xv
TARGETS
MULTIPLE
TIMESTAMP
SAVE_TARGETS
kate 3.4.5 KDE 4.4.5 copy text
text/plain
UTF8_STRING
STRING
TEXT
COMPOUND_TEXT
TARGETS
MULTIPLE
TIMESTAMP
SAVE_TARGETS
gimp 2.6.10 copy image area
TIMESTAMP
TARGETS
MULTIPLE
SAVE_TARGETS
image/png
image/bmp
image/x-bmp
image/x-MS-bmp
image/tiff
image/x-icon
image/x-ico
image/x-win-bitmap
image/jpeg
*/ */
#include <X11/Xlib.h> #include <X11/Xlib.h>
@ -1280,6 +1350,10 @@ clipboard_data_in(struct stream *s, int chan_id, int chan_flags, int length,
rv = clipboard_process_file_request(ls, clip_msg_status, rv = clipboard_process_file_request(ls, clip_msg_status,
clip_msg_len); clip_msg_len);
break; break;
case CB_FILECONTENTS_RESPONSE: /* 9 */
rv = clipboard_process_file_response(ls, clip_msg_status,
clip_msg_len);
break;
default: default:
LLOGLN(0, ("clipboard_data_in: unknown clip_msg_id %d", clip_msg_id)); LLOGLN(0, ("clipboard_data_in: unknown clip_msg_id %d", clip_msg_id));
LOGM((LOG_LEVEL_ERROR, "clipboard_data_in: unknown clip_msg_id %d", LOGM((LOG_LEVEL_ERROR, "clipboard_data_in: unknown clip_msg_id %d",

@ -77,6 +77,7 @@ struct clip_file_desc /* CLIPRDR_FILEDESCRIPTOR */
static struct cb_file_info g_files[64]; static struct cb_file_info g_files[64];
static int g_num_files = 0; static int g_num_files = 0;
static int g_file_request_sent_type = 0;
/* number of seconds from 1 Jan. 1601 00:00 to 1 Jan 1970 00:00 UTC */ /* number of seconds from 1 Jan. 1601 00:00 to 1 Jan 1970 00:00 UTC */
#define CB_EPOCH_DIFF 11644473600LL #define CB_EPOCH_DIFF 11644473600LL
@ -336,7 +337,7 @@ clipboard_send_file_size(int streamId, int lindex)
/*****************************************************************************/ /*****************************************************************************/
/* ask the client to send the file size */ /* ask the client to send the file size */
int APP_CC int APP_CC
clipboard_request_file_size(int streamId, int lindex) clipboard_request_file_size(int stream_id, int lindex)
{ {
struct stream *s; struct stream *s;
int size; int size;
@ -345,12 +346,17 @@ clipboard_request_file_size(int streamId, int lindex)
file_size = g_files[lindex].size; file_size = g_files[lindex].size;
LLOGLN(10, ("clipboard_request_file_size:")); LLOGLN(10, ("clipboard_request_file_size:"));
if (g_file_request_sent_type != 0)
{
LLOGLN(0, ("clipboard_request_file_size: warning, still waiting "
"for CB_FILECONTENTS_RESPONSE"));
}
make_stream(s); make_stream(s);
init_stream(s, 8192); init_stream(s, 8192);
out_uint16_le(s, CB_FILECONTENTS_REQUEST); /* 8 */ out_uint16_le(s, CB_FILECONTENTS_REQUEST); /* 8 */
out_uint16_le(s, 0); out_uint16_le(s, 0);
out_uint32_le(s, 28); out_uint32_le(s, 28);
out_uint32_le(s, streamId); out_uint32_le(s, stream_id);
out_uint32_le(s, lindex); out_uint32_le(s, lindex);
out_uint32_le(s, CB_FILECONTENTS_SIZE); out_uint32_le(s, CB_FILECONTENTS_SIZE);
out_uint32_le(s, 0); /* nPositionLow */ out_uint32_le(s, 0); /* nPositionLow */
@ -362,6 +368,7 @@ clipboard_request_file_size(int streamId, int lindex)
size = (int)(s->end - s->data); size = (int)(s->end - s->data);
rv = send_channel_data(g_cliprdr_chan_id, s->data, size); rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
free_stream(s); free_stream(s);
g_file_request_sent_type = CB_FILECONTENTS_SIZE;
return rv; return rv;
} }
@ -417,6 +424,46 @@ clipboard_send_file_data(int streamId, int lindex,
return rv; return rv;
} }
/*****************************************************************************/
/* ask the client to send the file size */
int APP_CC
clipboard_request_file_data(int stream_id, int lindex, int offset,
int request_bytes)
{
struct stream *s;
int size;
int rv;
int file_size;
file_size = g_files[lindex].size;
LLOGLN(10, ("clipboard_request_file_data:"));
if (g_file_request_sent_type != 0)
{
LLOGLN(0, ("clipboard_request_file_data: warning, still waiting "
"for CB_FILECONTENTS_RESPONSE"));
}
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, stream_id);
out_uint32_le(s, lindex);
out_uint32_le(s, CB_FILECONTENTS_RANGE);
out_uint32_le(s, offset); /* nPositionLow */
out_uint32_le(s, 0); /* nPositionHigh */
out_uint32_le(s, request_bytes); /* 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);
g_file_request_sent_type = CB_FILECONTENTS_RANGE;
return rv;
}
/*****************************************************************************/ /*****************************************************************************/
int APP_CC int APP_CC
clipboard_process_file_request(struct stream *s, int clip_msg_status, clipboard_process_file_request(struct stream *s, int clip_msg_status,
@ -450,6 +497,35 @@ clipboard_process_file_request(struct stream *s, int clip_msg_status,
return 0; return 0;
} }
/*****************************************************************************/
/* server requested info about the file and this is the responce
it's either the file size or file data */
int APP_CC
clipboard_process_file_response(struct stream *s, int clip_msg_status,
int clip_msg_len)
{
int streamId;
int file_size;
char *data;
LLOGLN(0, ("clipboard_process_file_response:"));
if (g_file_request_sent_type == CB_FILECONTENTS_SIZE)
{
in_uint32_le(s, streamId);
in_uint32_le(s, file_size);
LLOGLN(0, ("clipboard_process_file_response: streamId %d "
"file_size %d", streamId, file_size));
fuse_file_contents_size(streamId, file_size);
}
else if (g_file_request_sent_type == CB_FILECONTENTS_RANGE)
{
in_uint32_le(s, streamId);
fuse_file_contents_range(streamId, s->p, clip_msg_len - 4);
}
g_file_request_sent_type = 0;
return 0;
}
/*****************************************************************************/ /*****************************************************************************/
/* read in CLIPRDR_FILEDESCRIPTOR */ /* read in CLIPRDR_FILEDESCRIPTOR */
static int APP_CC static int APP_CC
@ -487,17 +563,17 @@ clipboard_c2s_in_file_info(struct stream *s, struct clip_file_desc *cfd)
int APP_CC int APP_CC
clipboard_c2s_in_files(struct stream *s) clipboard_c2s_in_files(struct stream *s)
{ {
tui32 cItems; int cItems;
int lindex;
struct clip_file_desc cfd; struct clip_file_desc cfd;
in_uint32_le(s, cItems); in_uint32_le(s, cItems);
fuse_clear_clip_dir(); fuse_clear_clip_dir();
LLOGLN(0, ("clipboard_c2s_in_files: cItems %d", cItems)); LLOGLN(0, ("clipboard_c2s_in_files: cItems %d", cItems));
while (cItems > 0) for (lindex = 0; lindex < cItems; lindex++)
{ {
clipboard_c2s_in_file_info(s, &cfd); clipboard_c2s_in_file_info(s, &cfd);
fuse_add_clip_dir_item(cfd.cFileName, 0, cfd.fileSizeLow); fuse_add_clip_dir_item(cfd.cFileName, 0, cfd.fileSizeLow, lindex);
cItems--;
} }
return 0; return 0;
} }

@ -31,6 +31,9 @@ int APP_CC
clipboard_c2s_in_files(struct stream *s); clipboard_c2s_in_files(struct stream *s);
int APP_CC int APP_CC
clipboard_request_file_size(int streamId, int lindex); clipboard_request_file_size(int stream_id, int lindex);
int APP_CC
clipboard_request_file_data(int stream_id, int lindex, int offset,
int request_bytes);
#endif #endif

Loading…
Cancel
Save