diff options
| -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 | 
