Browse Source

support hole punching when _DELETE commands are received... If the

server doesn't support it, EOPNOTSUPP is returned..
remotes/client/ssh-main
John-Mark Gurney 4 years ago
parent
commit
3711c67c08
1 changed files with 55 additions and 1 deletions
  1. +55
    -1
      ggatessh/ggatessh.c

+ 55
- 1
ggatessh/ggatessh.c View File

@@ -387,11 +387,11 @@ req_thread(void *arg __unused)
buf = NULL;
break;

case BIO_DELETE:
case BIO_FLUSH:
greq->r_ggio.gctl_data = NULL;
break;

case BIO_DELETE:
default:
greq->r_ggio.gctl_error = EOPNOTSUPP;
g_gate_ioctl(G_GATE_CMD_DONE, &greq->r_ggio);
@@ -426,6 +426,27 @@ req_thread(void *arg __unused)
return (NULL);
}

static const char *
sftperrno_str(int err)
{
const char *strs[] = {
[0] = "ok",
[1] = "eof",
[2] = "no such file",
[3] = "permission denied",
[4] = "failure",
[5] = "bad message",
[6] = "no connection",
[7] = "connection lost",
[8] = "op unsupported",
};

if (err < 0 || err >= (int)nitems(strs))
return "invalid errno";

return strs[err];
}

static int
process_pending(struct ggs_reqqueue *req_pending,
struct ggs_sessqueue *sessqueue)
@@ -433,6 +454,7 @@ process_pending(struct ggs_reqqueue *req_pending,
struct ggs_req *greq, *greq2;
char *errmsg;
int rc;
int sftperrno;
int didwork;

didwork = 0;
@@ -505,6 +527,38 @@ again:
/* NOTREACHABLE */
break;

case BIO_DELETE:
g_gate_log(LOG_DEBUG, "sftp_punchhole(%p)", greq);
rc = libssh2_sftp_punchhole(greq->r_handle,
greq->r_ggio.gctl_offset, greq->r_ggio.gctl_length);

didwork = 1; /* assume this always does work */
switch (rc) {
case LIBSSH2_ERROR_SFTP_PROTOCOL:
greq->r_ggio.gctl_error = EOPNOTSUPP;
sftperrno = libssh2_sftp_last_error(
greq->r_session);
g_gate_log(LOG_DEBUG, "sftp_punchhole(%p) errno: %s(%d)", greq,
sftperrno_str(sftperrno), sftperrno);
goto completeio;

case LIBSSH2_ERROR_EAGAIN:
continue;

case 0: /* success */
goto completeio;

default:
libssh2_session_last_error(greq->r_ssh_session,
&errmsg, NULL, 0);
g_gate_log(LOG_ERR, "sftp_punchhole(%p) ret %d: %s",
greq, rc, errmsg);
greq->r_ggio.gctl_error = EIO;
goto completeio;
}
/* NOTREACHABLE */
break;

default:
rc = 0;
g_gate_log(LOG_ERR, "unhandled op: %d",


Loading…
Cancel
Save