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; } } }
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; } } }