static void
process_read(void)
{
	char buf[64*1024];
	u_int32_t id, len;
	int handle, fd, ret, status = SSH2_FX_FAILURE;
	u_int64_t off;

	id = get_int();
	handle = get_handle();
	off = get_int64();
	len = get_int();

	debug("request %u: read \"%s\" (handle %d) off %llu len %d",
	    id, handle_to_name(handle), handle, (unsigned long long)off, len);
	if (len > sizeof buf) {
		len = sizeof buf;
		debug2("read change len %d", len);
	}
	fd = handle_to_fd(handle);
	if (fd >= 0) {
		if (lseek(fd, off, SEEK_SET) < 0) {
			error("process_read: seek failed");
			status = errno_to_portable(errno);
		} else {
			ret = read(fd, buf, len);
			if (ret < 0) {
				status = errno_to_portable(errno);
			} else if (ret == 0) {
				status = SSH2_FX_EOF;
			} else {
				send_data(id, buf, ret);
				status = SSH2_FX_OK;
				handle_update_read(handle, ret);
			}
		}
	}
	if (status != SSH2_FX_OK)
		send_status(id, status);
}
Exemplo n.º 2
0
static void
process_read(u_int32_t id)
{
	u_char buf[64*1024];
	u_int32_t len;
	int r, handle, fd, ret, status = SSH2_FX_FAILURE;
	u_int64_t off;

	if ((r = get_handle(iqueue, &handle)) != 0 ||
	    (r = sshbuf_get_u64(iqueue, &off)) != 0 ||
	    (r = sshbuf_get_u32(iqueue, &len)) != 0)
		fatal("%s: buffer error: %s", __func__, ssh_err(r));

	debug("request %u: read \"%s\" (handle %d) off %llu len %d",
	    id, handle_to_name(handle), handle, (unsigned long long)off, len);
	if (len > sizeof buf) {
		len = sizeof buf;
		debug2("read change len %d", len);
	}
	fd = handle_to_fd(handle);
	if (fd >= 0) {
		if (lseek(fd, off, SEEK_SET) < 0) {
			error("process_read: seek failed");
			status = errno_to_portable(errno);
		} else {
			ret = read(fd, buf, len);
			if (ret < 0) {
				status = errno_to_portable(errno);
			} else if (ret == 0) {
				status = SSH2_FX_EOF;
			} else {
				send_data(id, buf, ret);
				status = SSH2_FX_OK;
				handle_update_read(handle, ret);
			}
		}
	}
	if (status != SSH2_FX_OK)
		send_status(id, status);
}
Exemplo n.º 3
0
void SFTP::process_read(void)
{
	char buf[64*1024];
	u_int32_t id, len;
	int handle, status = SSH2_FX_FAILURE;
	u_int64_t off;

	id = get_int();
	handle = get_handle();
	off = get_int64();
	len = get_int();

#ifdef SLOW_DEBUG
	debug("request %u: read \"%s\" (handle %d) off %llu len %d",
    id, toUTF8(handle_to_name(handle)).c_str (), 
      handle, (unsigned long long)off, len);
#endif
	if (len > sizeof buf) {
		len = sizeof buf;
		debug2("read change len %d", len);
	}
	HANDLE fh = handle_to_fh(handle);
	if (fh != INVALID_HANDLE_VALUE) {
    LARGE_INTEGER largeOffset;
    largeOffset.QuadPart = off;

		if (!::SetFilePointerEx
         (fh, largeOffset, NULL, FILE_BEGIN))
    {
      int err = ::GetLastError ();
      if (!err)
        status = SSH2_FX_EOF;
      else
      {
			  error("process_read: seek failed");
        status = errno_to_portable(err);
      }
		} 
    else 
    {
      DWORD nBytesRed = 0;

			if (!::ReadFile (fh, buf, len, &nBytesRed, 0)) 
      {
				status = errno_to_portable(::GetLastError ());
			} 
      else if (nBytesRed == 0) 
      {
				status = SSH2_FX_EOF;
			} 
      else 
      {
        if (nBytesRed < len)
          debug ("process_read: requested %u, "
                 "%u was red", 
                 (unsigned) len, 
                 (unsigned) nBytesRed); 
				send_data(id, buf, (u_int) nBytesRed);
				status = SSH2_FX_OK;
				handle_update_read(handle, (u_int) nBytesRed);
			}
		}
	}
	if (status != SSH2_FX_OK)
		send_status(id, status);
}