Пример #1
0
static struct vsf_transfer_ret
do_file_recv(struct vsf_session* p_sess, int file_fd, int is_ascii)
{
  static char* p_recvbuf;
  unsigned int num_to_write;
  struct vsf_transfer_ret ret_struct = { 0, 0 };
  unsigned int chunk_size = get_chunk_size();
  int prev_cr = 0;
  if (p_recvbuf == 0)
  {
    /* Now that we do ASCII conversion properly, the plus one is to cater for
     * the fact we may need to stick a '\r' at the front of the buffer if the
     * last buffer fragment eneded in a '\r' and the current buffer fragment
     * does not start with a '\n'.
     */
    vsf_secbuf_alloc(&p_recvbuf, VSFTP_DATA_BUFSIZE + 1);
  }
  while (1)
  {
    const char* p_writebuf = p_recvbuf + 1;
    int retval = ftp_read_data(p_sess, p_recvbuf + 1, chunk_size);
    if (vsf_sysutil_retval_is_error(retval))
    {
      ret_struct.retval = -2;
      return ret_struct;
    }
    else if (retval == 0 && !prev_cr)
    {
      /* Transfer done, nifty */
      return ret_struct;
    }
    num_to_write = (unsigned int) retval;
    ret_struct.transferred += num_to_write;
    if (is_ascii)
    {
      /* Handle ASCII conversion if we have to. Note that using the same
       * buffer for source and destination is safe, because the ASCII ->
       * binary transform only ever results in a smaller file.
       */
      struct ascii_to_bin_ret ret =
        vsf_ascii_ascii_to_bin(p_recvbuf, num_to_write, prev_cr);
      num_to_write = ret.stored;
      prev_cr = ret.last_was_cr;
      p_writebuf = ret.p_buf;
    }
    retval = vsf_sysutil_write_loop(file_fd, p_writebuf, num_to_write);
    if (vsf_sysutil_retval_is_error(retval) ||
        (unsigned int) retval != num_to_write)
    {
      ret_struct.retval = -1;
      return ret_struct;
    }
  }
}
Пример #2
0
static struct vsf_transfer_ret
do_file_recv(struct vsf_session* p_sess, int file_fd, int is_ascii)
{
    static char* p_recvbuf;
    unsigned int num_to_write;
    struct vsf_transfer_ret ret_struct = { 0, 0 };
    unsigned int chunk_size = get_chunk_size();
    if (p_recvbuf == 0)
    {
        vsf_secbuf_alloc(&p_recvbuf, VSFTP_DATA_BUFSIZE);
    }
    while (1)
    {
        int retval = ftp_read_data(p_sess, p_recvbuf, chunk_size);
        if (vsf_sysutil_retval_is_error(retval))
        {
            vsf_cmdio_write(p_sess, FTP_BADSENDNET,
                            "Failure reading network stream.");
            ret_struct.retval = -1;
            return ret_struct;
        }
        else if (retval == 0)
        {
            /* Transfer done, nifty */
            vsf_cmdio_write(p_sess, FTP_TRANSFEROK, "File receive OK.");
            return ret_struct;
        }
        num_to_write = (unsigned int) retval;
        ret_struct.transferred += num_to_write;
        if (is_ascii)
        {
            /* Handle ASCII conversion if we have to. Note that using the same
             * buffer for source and destination is safe, because the ASCII ->
             * binary transform only ever results in a smaller file.
             */
            num_to_write = vsf_ascii_ascii_to_bin(p_recvbuf, p_recvbuf,
                                                  num_to_write);
        }
        retval = vsf_sysutil_write_loop(file_fd, p_recvbuf, num_to_write);
        if (vsf_sysutil_retval_is_error(retval) ||
                (unsigned int) retval != num_to_write)
        {
            vsf_cmdio_write(p_sess, FTP_BADSENDFILE,
                            "Failure writing to local file.");
            ret_struct.retval = -1;
            return ret_struct;
        }
    }
}