mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-10 01:48:00 +00:00
Clean up handling of the return value from sftp_find_request. In many
places we simply enforce by assertion that it will match the request we sent out a moment ago: in fact it can also return NULL, so it makes more sense to report a proper error message if it doesn't return the expected value, and while we're at it, have that error message whatever message was helpfully left in fxp_error() by sftp_find_request when it failed. To do this, I've written a centralised function in psftp.c called sftp_wait_for_reply, which is handed a request that's just been sent out and deals with the mechanics of waiting for its reply, returning the reply when it arrives, and aborting with a sensible error if anything else arrives instead. The numerous sites in psftp.c which called sftp_find_request have all been rewritten to do this instead, and as a side effect they now look more sensible. The only other uses of sftp_find_request were in xfer_*load_gotpkt, which had to be tweaked in its own way. While I'm here, also fix memory management in sftp_find_request, which was freeing its input packet on some but not all error return paths. [originally from svn r9894]
This commit is contained in:
parent
bbc9709b48
commit
2c586ee2cd
170
pscp.c
170
pscp.c
@ -319,6 +319,29 @@ static void bump(char *fmt, ...)
|
|||||||
cleanup_exit(1);
|
cleanup_exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wait for the reply to a single SFTP request. Parallels the same
|
||||||
|
* function in psftp.c (but isn't centralised into sftp.c because the
|
||||||
|
* latter module handles SFTP only and shouldn't assume that SFTP is
|
||||||
|
* the only thing going on by calling connection_fatal).
|
||||||
|
*/
|
||||||
|
struct sftp_packet *sftp_wait_for_reply(struct sftp_request *req)
|
||||||
|
{
|
||||||
|
struct sftp_packet *pktin;
|
||||||
|
struct sftp_request *rreq;
|
||||||
|
|
||||||
|
sftp_register(req);
|
||||||
|
pktin = sftp_recv();
|
||||||
|
if (pktin == NULL)
|
||||||
|
connection_fatal(NULL, "did not receive SFTP response packet "
|
||||||
|
"from server");
|
||||||
|
rreq = sftp_find_request(pktin);
|
||||||
|
if (rreq != req)
|
||||||
|
connection_fatal(NULL, "unable to understand SFTP response packet "
|
||||||
|
"from server: %s", fxp_error());
|
||||||
|
return pktin;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Open an SSH connection to user@host and execute cmd.
|
* Open an SSH connection to user@host and execute cmd.
|
||||||
*/
|
*/
|
||||||
@ -685,7 +708,7 @@ void scp_sftp_listdir(char *dirname)
|
|||||||
struct fxp_names *names;
|
struct fxp_names *names;
|
||||||
struct fxp_name *ournames;
|
struct fxp_name *ournames;
|
||||||
struct sftp_packet *pktin;
|
struct sftp_packet *pktin;
|
||||||
struct sftp_request *req, *rreq;
|
struct sftp_request *req;
|
||||||
int nnames, namesize;
|
int nnames, namesize;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -697,10 +720,9 @@ void scp_sftp_listdir(char *dirname)
|
|||||||
|
|
||||||
printf("Listing directory %s\n", dirname);
|
printf("Listing directory %s\n", dirname);
|
||||||
|
|
||||||
sftp_register(req = fxp_opendir_send(dirname));
|
req = fxp_opendir_send(dirname);
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
pktin = sftp_wait_for_reply(req);
|
||||||
assert(rreq == req);
|
dirh = fxp_opendir_recv(pktin, req);
|
||||||
dirh = fxp_opendir_recv(pktin, rreq);
|
|
||||||
|
|
||||||
if (dirh == NULL) {
|
if (dirh == NULL) {
|
||||||
printf("Unable to open %s: %s\n", dirname, fxp_error());
|
printf("Unable to open %s: %s\n", dirname, fxp_error());
|
||||||
@ -710,10 +732,9 @@ void scp_sftp_listdir(char *dirname)
|
|||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
|
|
||||||
sftp_register(req = fxp_readdir_send(dirh));
|
req = fxp_readdir_send(dirh);
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
pktin = sftp_wait_for_reply(req);
|
||||||
assert(rreq == req);
|
names = fxp_readdir_recv(pktin, req);
|
||||||
names = fxp_readdir_recv(pktin, rreq);
|
|
||||||
|
|
||||||
if (names == NULL) {
|
if (names == NULL) {
|
||||||
if (fxp_error_type() == SSH_FX_EOF)
|
if (fxp_error_type() == SSH_FX_EOF)
|
||||||
@ -736,10 +757,9 @@ void scp_sftp_listdir(char *dirname)
|
|||||||
names->nnames = 0; /* prevent free_names */
|
names->nnames = 0; /* prevent free_names */
|
||||||
fxp_free_names(names);
|
fxp_free_names(names);
|
||||||
}
|
}
|
||||||
sftp_register(req = fxp_close_send(dirh));
|
req = fxp_close_send(dirh);
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
pktin = sftp_wait_for_reply(req);
|
||||||
assert(rreq == req);
|
fxp_close_recv(pktin, req);
|
||||||
fxp_close_recv(pktin, rreq);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now we have our filenames. Sort them by actual file
|
* Now we have our filenames. Sort them by actual file
|
||||||
@ -786,7 +806,7 @@ int scp_source_setup(char *target, int shouldbedir)
|
|||||||
* directory.
|
* directory.
|
||||||
*/
|
*/
|
||||||
struct sftp_packet *pktin;
|
struct sftp_packet *pktin;
|
||||||
struct sftp_request *req, *rreq;
|
struct sftp_request *req;
|
||||||
struct fxp_attrs attrs;
|
struct fxp_attrs attrs;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -796,10 +816,9 @@ int scp_source_setup(char *target, int shouldbedir)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
sftp_register(req = fxp_stat_send(target));
|
req = fxp_stat_send(target);
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
pktin = sftp_wait_for_reply(req);
|
||||||
assert(rreq == req);
|
ret = fxp_stat_recv(pktin, req, &attrs);
|
||||||
ret = fxp_stat_recv(pktin, rreq, &attrs);
|
|
||||||
|
|
||||||
if (!ret || !(attrs.flags & SSH_FILEXFER_ATTR_PERMISSIONS))
|
if (!ret || !(attrs.flags & SSH_FILEXFER_ATTR_PERMISSIONS))
|
||||||
scp_sftp_targetisdir = 0;
|
scp_sftp_targetisdir = 0;
|
||||||
@ -850,7 +869,7 @@ int scp_send_filename(char *name, uint64 size, int permissions)
|
|||||||
if (using_sftp) {
|
if (using_sftp) {
|
||||||
char *fullname;
|
char *fullname;
|
||||||
struct sftp_packet *pktin;
|
struct sftp_packet *pktin;
|
||||||
struct sftp_request *req, *rreq;
|
struct sftp_request *req;
|
||||||
struct fxp_attrs attrs;
|
struct fxp_attrs attrs;
|
||||||
|
|
||||||
if (scp_sftp_targetisdir) {
|
if (scp_sftp_targetisdir) {
|
||||||
@ -862,12 +881,11 @@ int scp_send_filename(char *name, uint64 size, int permissions)
|
|||||||
attrs.flags = 0;
|
attrs.flags = 0;
|
||||||
PUT_PERMISSIONS(attrs, permissions);
|
PUT_PERMISSIONS(attrs, permissions);
|
||||||
|
|
||||||
sftp_register(req = fxp_open_send(fullname, SSH_FXF_WRITE |
|
req = fxp_open_send(fullname,
|
||||||
SSH_FXF_CREAT | SSH_FXF_TRUNC,
|
SSH_FXF_WRITE | SSH_FXF_CREAT | SSH_FXF_TRUNC,
|
||||||
&attrs));
|
&attrs);
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
pktin = sftp_wait_for_reply(req);
|
||||||
assert(rreq == req);
|
scp_sftp_filehandle = fxp_open_recv(pktin, req);
|
||||||
scp_sftp_filehandle = fxp_open_recv(pktin, rreq);
|
|
||||||
|
|
||||||
if (!scp_sftp_filehandle) {
|
if (!scp_sftp_filehandle) {
|
||||||
tell_user(stderr, "pscp: unable to open %s: %s",
|
tell_user(stderr, "pscp: unable to open %s: %s",
|
||||||
@ -907,7 +925,7 @@ int scp_send_filedata(char *data, int len)
|
|||||||
while (!xfer_upload_ready(scp_sftp_xfer)) {
|
while (!xfer_upload_ready(scp_sftp_xfer)) {
|
||||||
pktin = sftp_recv();
|
pktin = sftp_recv();
|
||||||
ret = xfer_upload_gotpkt(scp_sftp_xfer, pktin);
|
ret = xfer_upload_gotpkt(scp_sftp_xfer, pktin);
|
||||||
if (!ret) {
|
if (ret <= 0) {
|
||||||
tell_user(stderr, "error while writing: %s\n", fxp_error());
|
tell_user(stderr, "error while writing: %s\n", fxp_error());
|
||||||
errs++;
|
errs++;
|
||||||
return 1;
|
return 1;
|
||||||
@ -942,12 +960,17 @@ int scp_send_finish(void)
|
|||||||
if (using_sftp) {
|
if (using_sftp) {
|
||||||
struct fxp_attrs attrs;
|
struct fxp_attrs attrs;
|
||||||
struct sftp_packet *pktin;
|
struct sftp_packet *pktin;
|
||||||
struct sftp_request *req, *rreq;
|
struct sftp_request *req;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
while (!xfer_done(scp_sftp_xfer)) {
|
while (!xfer_done(scp_sftp_xfer)) {
|
||||||
pktin = sftp_recv();
|
pktin = sftp_recv();
|
||||||
xfer_upload_gotpkt(scp_sftp_xfer, pktin);
|
ret = xfer_upload_gotpkt(scp_sftp_xfer, pktin);
|
||||||
|
if (ret <= 0) {
|
||||||
|
tell_user(stderr, "error while writing: %s\n", fxp_error());
|
||||||
|
errs++;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
xfer_cleanup(scp_sftp_xfer);
|
xfer_cleanup(scp_sftp_xfer);
|
||||||
|
|
||||||
@ -958,19 +981,17 @@ int scp_send_finish(void)
|
|||||||
attrs.flags = SSH_FILEXFER_ATTR_ACMODTIME;
|
attrs.flags = SSH_FILEXFER_ATTR_ACMODTIME;
|
||||||
attrs.atime = scp_sftp_atime;
|
attrs.atime = scp_sftp_atime;
|
||||||
attrs.mtime = scp_sftp_mtime;
|
attrs.mtime = scp_sftp_mtime;
|
||||||
sftp_register(req = fxp_fsetstat_send(scp_sftp_filehandle, attrs));
|
req = fxp_fsetstat_send(scp_sftp_filehandle, attrs);
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
pktin = sftp_wait_for_reply(req);
|
||||||
assert(rreq == req);
|
ret = fxp_fsetstat_recv(pktin, req);
|
||||||
ret = fxp_fsetstat_recv(pktin, rreq);
|
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
tell_user(stderr, "unable to set file times: %s\n", fxp_error());
|
tell_user(stderr, "unable to set file times: %s\n", fxp_error());
|
||||||
errs++;
|
errs++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sftp_register(req = fxp_close_send(scp_sftp_filehandle));
|
req = fxp_close_send(scp_sftp_filehandle);
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
pktin = sftp_wait_for_reply(req);
|
||||||
assert(rreq == req);
|
fxp_close_recv(pktin, req);
|
||||||
fxp_close_recv(pktin, rreq);
|
|
||||||
scp_has_times = 0;
|
scp_has_times = 0;
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
@ -1000,7 +1021,7 @@ int scp_send_dirname(char *name, int modes)
|
|||||||
char const *err;
|
char const *err;
|
||||||
struct fxp_attrs attrs;
|
struct fxp_attrs attrs;
|
||||||
struct sftp_packet *pktin;
|
struct sftp_packet *pktin;
|
||||||
struct sftp_request *req, *rreq;
|
struct sftp_request *req;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (scp_sftp_targetisdir) {
|
if (scp_sftp_targetisdir) {
|
||||||
@ -1016,20 +1037,18 @@ int scp_send_dirname(char *name, int modes)
|
|||||||
* exists and is a directory we will assume we were either
|
* exists and is a directory we will assume we were either
|
||||||
* successful or it didn't matter.
|
* successful or it didn't matter.
|
||||||
*/
|
*/
|
||||||
sftp_register(req = fxp_mkdir_send(fullname));
|
req = fxp_mkdir_send(fullname);
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
pktin = sftp_wait_for_reply(req);
|
||||||
assert(rreq == req);
|
ret = fxp_mkdir_recv(pktin, req);
|
||||||
ret = fxp_mkdir_recv(pktin, rreq);
|
|
||||||
|
|
||||||
if (!ret)
|
if (!ret)
|
||||||
err = fxp_error();
|
err = fxp_error();
|
||||||
else
|
else
|
||||||
err = "server reported no error";
|
err = "server reported no error";
|
||||||
|
|
||||||
sftp_register(req = fxp_stat_send(fullname));
|
req = fxp_stat_send(fullname);
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
pktin = sftp_wait_for_reply(req);
|
||||||
assert(rreq == req);
|
ret = fxp_stat_recv(pktin, req, &attrs);
|
||||||
ret = fxp_stat_recv(pktin, rreq, &attrs);
|
|
||||||
|
|
||||||
if (!ret || !(attrs.flags & SSH_FILEXFER_ATTR_PERMISSIONS) ||
|
if (!ret || !(attrs.flags & SSH_FILEXFER_ATTR_PERMISSIONS) ||
|
||||||
!(attrs.permissions & 0040000)) {
|
!(attrs.permissions & 0040000)) {
|
||||||
@ -1179,7 +1198,7 @@ int scp_get_sink_action(struct scp_sink_action *act)
|
|||||||
int must_free_fname;
|
int must_free_fname;
|
||||||
struct fxp_attrs attrs;
|
struct fxp_attrs attrs;
|
||||||
struct sftp_packet *pktin;
|
struct sftp_packet *pktin;
|
||||||
struct sftp_request *req, *rreq;
|
struct sftp_request *req;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!scp_sftp_dirstack_head) {
|
if (!scp_sftp_dirstack_head) {
|
||||||
@ -1248,10 +1267,9 @@ int scp_get_sink_action(struct scp_sink_action *act)
|
|||||||
* Now we have a filename. Stat it, and see if it's a file
|
* Now we have a filename. Stat it, and see if it's a file
|
||||||
* or a directory.
|
* or a directory.
|
||||||
*/
|
*/
|
||||||
sftp_register(req = fxp_stat_send(fname));
|
req = fxp_stat_send(fname);
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
pktin = sftp_wait_for_reply(req);
|
||||||
assert(rreq == req);
|
ret = fxp_stat_recv(pktin, req, &attrs);
|
||||||
ret = fxp_stat_recv(pktin, rreq, &attrs);
|
|
||||||
|
|
||||||
if (!ret || !(attrs.flags & SSH_FILEXFER_ATTR_PERMISSIONS)) {
|
if (!ret || !(attrs.flags & SSH_FILEXFER_ATTR_PERMISSIONS)) {
|
||||||
tell_user(stderr, "unable to identify %s: %s", fname,
|
tell_user(stderr, "unable to identify %s: %s", fname,
|
||||||
@ -1304,10 +1322,9 @@ int scp_get_sink_action(struct scp_sink_action *act)
|
|||||||
* list), we must push the other (target,namelist) pair
|
* list), we must push the other (target,namelist) pair
|
||||||
* on a stack.
|
* on a stack.
|
||||||
*/
|
*/
|
||||||
sftp_register(req = fxp_opendir_send(fname));
|
req = fxp_opendir_send(fname);
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
pktin = sftp_wait_for_reply(req);
|
||||||
assert(rreq == req);
|
dirhandle = fxp_opendir_recv(pktin, req);
|
||||||
dirhandle = fxp_opendir_recv(pktin, rreq);
|
|
||||||
|
|
||||||
if (!dirhandle) {
|
if (!dirhandle) {
|
||||||
tell_user(stderr, "scp: unable to open directory %s: %s",
|
tell_user(stderr, "scp: unable to open directory %s: %s",
|
||||||
@ -1321,10 +1338,9 @@ int scp_get_sink_action(struct scp_sink_action *act)
|
|||||||
while (1) {
|
while (1) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
sftp_register(req = fxp_readdir_send(dirhandle));
|
req = fxp_readdir_send(dirhandle);
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
pktin = sftp_wait_for_reply(req);
|
||||||
assert(rreq == req);
|
names = fxp_readdir_recv(pktin, req);
|
||||||
names = fxp_readdir_recv(pktin, rreq);
|
|
||||||
|
|
||||||
if (names == NULL) {
|
if (names == NULL) {
|
||||||
if (fxp_error_type() == SSH_FX_EOF)
|
if (fxp_error_type() == SSH_FX_EOF)
|
||||||
@ -1362,10 +1378,9 @@ int scp_get_sink_action(struct scp_sink_action *act)
|
|||||||
names->nnames = 0; /* prevent free_names */
|
names->nnames = 0; /* prevent free_names */
|
||||||
fxp_free_names(names);
|
fxp_free_names(names);
|
||||||
}
|
}
|
||||||
sftp_register(req = fxp_close_send(dirhandle));
|
req = fxp_close_send(dirhandle);
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
pktin = sftp_wait_for_reply(req);
|
||||||
assert(rreq == req);
|
fxp_close_recv(pktin, req);
|
||||||
fxp_close_recv(pktin, rreq);
|
|
||||||
|
|
||||||
newitem = snew(struct scp_sftp_dirstack);
|
newitem = snew(struct scp_sftp_dirstack);
|
||||||
newitem->next = scp_sftp_dirstack_head;
|
newitem->next = scp_sftp_dirstack_head;
|
||||||
@ -1510,13 +1525,11 @@ int scp_accept_filexfer(void)
|
|||||||
{
|
{
|
||||||
if (using_sftp) {
|
if (using_sftp) {
|
||||||
struct sftp_packet *pktin;
|
struct sftp_packet *pktin;
|
||||||
struct sftp_request *req, *rreq;
|
struct sftp_request *req;
|
||||||
|
|
||||||
sftp_register(req = fxp_open_send(scp_sftp_currentname, SSH_FXF_READ,
|
req = fxp_open_send(scp_sftp_currentname, SSH_FXF_READ, NULL);
|
||||||
NULL));
|
pktin = sftp_wait_for_reply(req);
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
scp_sftp_filehandle = fxp_open_recv(pktin, req);
|
||||||
assert(rreq == req);
|
|
||||||
scp_sftp_filehandle = fxp_open_recv(pktin, rreq);
|
|
||||||
|
|
||||||
if (!scp_sftp_filehandle) {
|
if (!scp_sftp_filehandle) {
|
||||||
tell_user(stderr, "pscp: unable to open %s: %s",
|
tell_user(stderr, "pscp: unable to open %s: %s",
|
||||||
@ -1545,8 +1558,7 @@ int scp_recv_filedata(char *data, int len)
|
|||||||
xfer_download_queue(scp_sftp_xfer);
|
xfer_download_queue(scp_sftp_xfer);
|
||||||
pktin = sftp_recv();
|
pktin = sftp_recv();
|
||||||
ret = xfer_download_gotpkt(scp_sftp_xfer, pktin);
|
ret = xfer_download_gotpkt(scp_sftp_xfer, pktin);
|
||||||
|
if (ret <= 0) {
|
||||||
if (ret < 0) {
|
|
||||||
tell_user(stderr, "pscp: error while reading: %s", fxp_error());
|
tell_user(stderr, "pscp: error while reading: %s", fxp_error());
|
||||||
errs++;
|
errs++;
|
||||||
return -1;
|
return -1;
|
||||||
@ -1577,7 +1589,7 @@ int scp_finish_filerecv(void)
|
|||||||
{
|
{
|
||||||
if (using_sftp) {
|
if (using_sftp) {
|
||||||
struct sftp_packet *pktin;
|
struct sftp_packet *pktin;
|
||||||
struct sftp_request *req, *rreq;
|
struct sftp_request *req;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ensure that xfer_done() will work correctly, so we can
|
* Ensure that xfer_done() will work correctly, so we can
|
||||||
@ -1587,19 +1599,23 @@ int scp_finish_filerecv(void)
|
|||||||
xfer_set_error(scp_sftp_xfer);
|
xfer_set_error(scp_sftp_xfer);
|
||||||
while (!xfer_done(scp_sftp_xfer)) {
|
while (!xfer_done(scp_sftp_xfer)) {
|
||||||
void *vbuf;
|
void *vbuf;
|
||||||
int len;
|
int ret, len;
|
||||||
|
|
||||||
pktin = sftp_recv();
|
pktin = sftp_recv();
|
||||||
xfer_download_gotpkt(scp_sftp_xfer, pktin);
|
ret = xfer_download_gotpkt(scp_sftp_xfer, pktin);
|
||||||
|
if (ret <= 0) {
|
||||||
|
tell_user(stderr, "pscp: error while reading: %s", fxp_error());
|
||||||
|
errs++;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
if (xfer_download_data(scp_sftp_xfer, &vbuf, &len))
|
if (xfer_download_data(scp_sftp_xfer, &vbuf, &len))
|
||||||
sfree(vbuf);
|
sfree(vbuf);
|
||||||
}
|
}
|
||||||
xfer_cleanup(scp_sftp_xfer);
|
xfer_cleanup(scp_sftp_xfer);
|
||||||
|
|
||||||
sftp_register(req = fxp_close_send(scp_sftp_filehandle));
|
req = fxp_close_send(scp_sftp_filehandle);
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
pktin = sftp_wait_for_reply(req);
|
||||||
assert(rreq == req);
|
fxp_close_recv(pktin, req);
|
||||||
fxp_close_recv(pktin, rreq);
|
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
back->send(backhandle, "", 1);
|
back->send(backhandle, "", 1);
|
||||||
|
292
psftp.c
292
psftp.c
@ -39,6 +39,26 @@ static void *backhandle;
|
|||||||
static Conf *conf;
|
static Conf *conf;
|
||||||
int sent_eof = FALSE;
|
int sent_eof = FALSE;
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------
|
||||||
|
* Manage sending requests and waiting for replies.
|
||||||
|
*/
|
||||||
|
struct sftp_packet *sftp_wait_for_reply(struct sftp_request *req)
|
||||||
|
{
|
||||||
|
struct sftp_packet *pktin;
|
||||||
|
struct sftp_request *rreq;
|
||||||
|
|
||||||
|
sftp_register(req);
|
||||||
|
pktin = sftp_recv();
|
||||||
|
if (pktin == NULL)
|
||||||
|
connection_fatal(NULL, "did not receive SFTP response packet "
|
||||||
|
"from server");
|
||||||
|
rreq = sftp_find_request(pktin);
|
||||||
|
if (rreq != req)
|
||||||
|
connection_fatal(NULL, "unable to understand SFTP response packet "
|
||||||
|
"from server: %s", fxp_error());
|
||||||
|
return pktin;
|
||||||
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
* Higher-level helper functions used in commands.
|
* Higher-level helper functions used in commands.
|
||||||
*/
|
*/
|
||||||
@ -52,7 +72,7 @@ char *canonify(char *name)
|
|||||||
{
|
{
|
||||||
char *fullname, *canonname;
|
char *fullname, *canonname;
|
||||||
struct sftp_packet *pktin;
|
struct sftp_packet *pktin;
|
||||||
struct sftp_request *req, *rreq;
|
struct sftp_request *req;
|
||||||
|
|
||||||
if (name[0] == '/') {
|
if (name[0] == '/') {
|
||||||
fullname = dupstr(name);
|
fullname = dupstr(name);
|
||||||
@ -65,10 +85,9 @@ char *canonify(char *name)
|
|||||||
fullname = dupcat(pwd, slash, name, NULL);
|
fullname = dupcat(pwd, slash, name, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
sftp_register(req = fxp_realpath_send(fullname));
|
req = fxp_realpath_send(fullname);
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
pktin = sftp_wait_for_reply(req);
|
||||||
assert(rreq == req);
|
canonname = fxp_realpath_recv(pktin, req);
|
||||||
canonname = fxp_realpath_recv(pktin, rreq);
|
|
||||||
|
|
||||||
if (canonname) {
|
if (canonname) {
|
||||||
sfree(fullname);
|
sfree(fullname);
|
||||||
@ -123,13 +142,12 @@ char *canonify(char *name)
|
|||||||
*/
|
*/
|
||||||
fullname[i] = '\0'; /* separate the string */
|
fullname[i] = '\0'; /* separate the string */
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
sftp_register(req = fxp_realpath_send("/"));
|
req = fxp_realpath_send("/");
|
||||||
} else {
|
} else {
|
||||||
sftp_register(req = fxp_realpath_send(fullname));
|
req = fxp_realpath_send(fullname);
|
||||||
}
|
}
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
pktin = sftp_wait_for_reply(req);
|
||||||
assert(rreq == req);
|
canonname = fxp_realpath_recv(pktin, req);
|
||||||
canonname = fxp_realpath_recv(pktin, rreq);
|
|
||||||
|
|
||||||
if (!canonname) {
|
if (!canonname) {
|
||||||
/* Even that failed. Restore our best guess at the
|
/* Even that failed. Restore our best guess at the
|
||||||
@ -208,7 +226,7 @@ int sftp_get_file(char *fname, char *outfname, int recurse, int restart)
|
|||||||
{
|
{
|
||||||
struct fxp_handle *fh;
|
struct fxp_handle *fh;
|
||||||
struct sftp_packet *pktin;
|
struct sftp_packet *pktin;
|
||||||
struct sftp_request *req, *rreq;
|
struct sftp_request *req;
|
||||||
struct fxp_xfer *xfer;
|
struct fxp_xfer *xfer;
|
||||||
uint64 offset;
|
uint64 offset;
|
||||||
WFile *file;
|
WFile *file;
|
||||||
@ -223,10 +241,9 @@ int sftp_get_file(char *fname, char *outfname, int recurse, int restart)
|
|||||||
if (recurse) {
|
if (recurse) {
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
sftp_register(req = fxp_stat_send(fname));
|
req = fxp_stat_send(fname);
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
pktin = sftp_wait_for_reply(req);
|
||||||
assert(rreq == req);
|
result = fxp_stat_recv(pktin, req, &attrs);
|
||||||
result = fxp_stat_recv(pktin, rreq, &attrs);
|
|
||||||
|
|
||||||
if (result &&
|
if (result &&
|
||||||
(attrs.flags & SSH_FILEXFER_ATTR_PERMISSIONS) &&
|
(attrs.flags & SSH_FILEXFER_ATTR_PERMISSIONS) &&
|
||||||
@ -252,10 +269,9 @@ int sftp_get_file(char *fname, char *outfname, int recurse, int restart)
|
|||||||
* Now get the list of filenames in the remote
|
* Now get the list of filenames in the remote
|
||||||
* directory.
|
* directory.
|
||||||
*/
|
*/
|
||||||
sftp_register(req = fxp_opendir_send(fname));
|
req = fxp_opendir_send(fname);
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
pktin = sftp_wait_for_reply(req);
|
||||||
assert(rreq == req);
|
dirhandle = fxp_opendir_recv(pktin, req);
|
||||||
dirhandle = fxp_opendir_recv(pktin, rreq);
|
|
||||||
|
|
||||||
if (!dirhandle) {
|
if (!dirhandle) {
|
||||||
printf("%s: unable to open directory: %s\n",
|
printf("%s: unable to open directory: %s\n",
|
||||||
@ -267,10 +283,9 @@ int sftp_get_file(char *fname, char *outfname, int recurse, int restart)
|
|||||||
while (1) {
|
while (1) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
sftp_register(req = fxp_readdir_send(dirhandle));
|
req = fxp_readdir_send(dirhandle);
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
pktin = sftp_wait_for_reply(req);
|
||||||
assert(rreq == req);
|
names = fxp_readdir_recv(pktin, req);
|
||||||
names = fxp_readdir_recv(pktin, rreq);
|
|
||||||
|
|
||||||
if (names == NULL) {
|
if (names == NULL) {
|
||||||
if (fxp_error_type() == SSH_FX_EOF)
|
if (fxp_error_type() == SSH_FX_EOF)
|
||||||
@ -301,10 +316,9 @@ int sftp_get_file(char *fname, char *outfname, int recurse, int restart)
|
|||||||
}
|
}
|
||||||
fxp_free_names(names);
|
fxp_free_names(names);
|
||||||
}
|
}
|
||||||
sftp_register(req = fxp_close_send(dirhandle));
|
req = fxp_close_send(dirhandle);
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
pktin = sftp_wait_for_reply(req);
|
||||||
assert(rreq == req);
|
fxp_close_recv(pktin, req);
|
||||||
fxp_close_recv(pktin, rreq);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sort the names into a clear order. This ought to
|
* Sort the names into a clear order. This ought to
|
||||||
@ -384,16 +398,14 @@ int sftp_get_file(char *fname, char *outfname, int recurse, int restart)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sftp_register(req = fxp_stat_send(fname));
|
req = fxp_stat_send(fname);
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
pktin = sftp_wait_for_reply(req);
|
||||||
assert(rreq == req);
|
if (!fxp_stat_recv(pktin, req, &attrs))
|
||||||
if (!fxp_stat_recv(pktin, rreq, &attrs))
|
|
||||||
attrs.flags = 0;
|
attrs.flags = 0;
|
||||||
|
|
||||||
sftp_register(req = fxp_open_send(fname, SSH_FXF_READ, NULL));
|
req = fxp_open_send(fname, SSH_FXF_READ, NULL);
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
pktin = sftp_wait_for_reply(req);
|
||||||
assert(rreq == req);
|
fh = fxp_open_recv(pktin, req);
|
||||||
fh = fxp_open_recv(pktin, rreq);
|
|
||||||
|
|
||||||
if (!fh) {
|
if (!fh) {
|
||||||
printf("%s: open for read: %s\n", fname, fxp_error());
|
printf("%s: open for read: %s\n", fname, fxp_error());
|
||||||
@ -409,10 +421,9 @@ int sftp_get_file(char *fname, char *outfname, int recurse, int restart)
|
|||||||
if (!file) {
|
if (!file) {
|
||||||
printf("local: unable to open %s\n", outfname);
|
printf("local: unable to open %s\n", outfname);
|
||||||
|
|
||||||
sftp_register(req = fxp_close_send(fh));
|
req = fxp_close_send(fh);
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
pktin = sftp_wait_for_reply(req);
|
||||||
assert(rreq == req);
|
fxp_close_recv(pktin, req);
|
||||||
fxp_close_recv(pktin, rreq);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -423,10 +434,9 @@ int sftp_get_file(char *fname, char *outfname, int recurse, int restart)
|
|||||||
close_wfile(file);
|
close_wfile(file);
|
||||||
printf("reget: cannot restart %s - file too large\n",
|
printf("reget: cannot restart %s - file too large\n",
|
||||||
outfname);
|
outfname);
|
||||||
sftp_register(req = fxp_close_send(fh));
|
req = fxp_close_send(fh);
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
pktin = sftp_wait_for_reply(req);
|
||||||
assert(rreq == req);
|
fxp_close_recv(pktin, req);
|
||||||
fxp_close_recv(pktin, rreq);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -454,8 +464,7 @@ int sftp_get_file(char *fname, char *outfname, int recurse, int restart)
|
|||||||
xfer_download_queue(xfer);
|
xfer_download_queue(xfer);
|
||||||
pktin = sftp_recv();
|
pktin = sftp_recv();
|
||||||
ret = xfer_download_gotpkt(xfer, pktin);
|
ret = xfer_download_gotpkt(xfer, pktin);
|
||||||
|
if (ret <= 0) {
|
||||||
if (ret < 0) {
|
|
||||||
if (!shown_err) {
|
if (!shown_err) {
|
||||||
printf("error while reading: %s\n", fxp_error());
|
printf("error while reading: %s\n", fxp_error());
|
||||||
shown_err = TRUE;
|
shown_err = TRUE;
|
||||||
@ -490,10 +499,9 @@ int sftp_get_file(char *fname, char *outfname, int recurse, int restart)
|
|||||||
|
|
||||||
close_wfile(file);
|
close_wfile(file);
|
||||||
|
|
||||||
sftp_register(req = fxp_close_send(fh));
|
req = fxp_close_send(fh);
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
pktin = sftp_wait_for_reply(req);
|
||||||
assert(rreq == req);
|
fxp_close_recv(pktin, req);
|
||||||
fxp_close_recv(pktin, rreq);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -503,7 +511,7 @@ int sftp_put_file(char *fname, char *outfname, int recurse, int restart)
|
|||||||
struct fxp_handle *fh;
|
struct fxp_handle *fh;
|
||||||
struct fxp_xfer *xfer;
|
struct fxp_xfer *xfer;
|
||||||
struct sftp_packet *pktin;
|
struct sftp_packet *pktin;
|
||||||
struct sftp_request *req, *rreq;
|
struct sftp_request *req;
|
||||||
uint64 offset;
|
uint64 offset;
|
||||||
RFile *file;
|
RFile *file;
|
||||||
int ret, err, eof;
|
int ret, err, eof;
|
||||||
@ -526,17 +534,15 @@ int sftp_put_file(char *fname, char *outfname, int recurse, int restart)
|
|||||||
* First, attempt to create the destination directory,
|
* First, attempt to create the destination directory,
|
||||||
* unless it already exists.
|
* unless it already exists.
|
||||||
*/
|
*/
|
||||||
sftp_register(req = fxp_stat_send(outfname));
|
req = fxp_stat_send(outfname);
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
pktin = sftp_wait_for_reply(req);
|
||||||
assert(rreq == req);
|
result = fxp_stat_recv(pktin, req, &attrs);
|
||||||
result = fxp_stat_recv(pktin, rreq, &attrs);
|
|
||||||
if (!result ||
|
if (!result ||
|
||||||
!(attrs.flags & SSH_FILEXFER_ATTR_PERMISSIONS) ||
|
!(attrs.flags & SSH_FILEXFER_ATTR_PERMISSIONS) ||
|
||||||
!(attrs.permissions & 0040000)) {
|
!(attrs.permissions & 0040000)) {
|
||||||
sftp_register(req = fxp_mkdir_send(outfname));
|
req = fxp_mkdir_send(outfname);
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
pktin = sftp_wait_for_reply(req);
|
||||||
assert(rreq == req);
|
result = fxp_mkdir_recv(pktin, req);
|
||||||
result = fxp_mkdir_recv(pktin, rreq);
|
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
printf("%s: create directory: %s\n",
|
printf("%s: create directory: %s\n",
|
||||||
@ -586,10 +592,9 @@ int sftp_put_file(char *fname, char *outfname, int recurse, int restart)
|
|||||||
while (i < nnames) {
|
while (i < nnames) {
|
||||||
char *nextoutfname;
|
char *nextoutfname;
|
||||||
nextoutfname = dupcat(outfname, "/", ournames[i], NULL);
|
nextoutfname = dupcat(outfname, "/", ournames[i], NULL);
|
||||||
sftp_register(req = fxp_stat_send(nextoutfname));
|
req = fxp_stat_send(nextoutfname);
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
pktin = sftp_wait_for_reply(req);
|
||||||
assert(rreq == req);
|
result = fxp_stat_recv(pktin, req, &attrs);
|
||||||
result = fxp_stat_recv(pktin, rreq, &attrs);
|
|
||||||
sfree(nextoutfname);
|
sfree(nextoutfname);
|
||||||
if (!result)
|
if (!result)
|
||||||
break;
|
break;
|
||||||
@ -646,15 +651,14 @@ int sftp_put_file(char *fname, char *outfname, int recurse, int restart)
|
|||||||
attrs.flags = 0;
|
attrs.flags = 0;
|
||||||
PUT_PERMISSIONS(attrs, permissions);
|
PUT_PERMISSIONS(attrs, permissions);
|
||||||
if (restart) {
|
if (restart) {
|
||||||
sftp_register(req = fxp_open_send(outfname, SSH_FXF_WRITE, &attrs));
|
req = fxp_open_send(outfname, SSH_FXF_WRITE, &attrs);
|
||||||
} else {
|
} else {
|
||||||
sftp_register(req = fxp_open_send(outfname, SSH_FXF_WRITE |
|
req = fxp_open_send(outfname,
|
||||||
SSH_FXF_CREAT | SSH_FXF_TRUNC,
|
SSH_FXF_WRITE | SSH_FXF_CREAT | SSH_FXF_TRUNC,
|
||||||
&attrs));
|
&attrs);
|
||||||
}
|
}
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
pktin = sftp_wait_for_reply(req);
|
||||||
assert(rreq == req);
|
fh = fxp_open_recv(pktin, req);
|
||||||
fh = fxp_open_recv(pktin, rreq);
|
|
||||||
|
|
||||||
if (!fh) {
|
if (!fh) {
|
||||||
close_rfile(file);
|
close_rfile(file);
|
||||||
@ -667,10 +671,9 @@ int sftp_put_file(char *fname, char *outfname, int recurse, int restart)
|
|||||||
struct fxp_attrs attrs;
|
struct fxp_attrs attrs;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
sftp_register(req = fxp_fstat_send(fh));
|
req = fxp_fstat_send(fh);
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
pktin = sftp_wait_for_reply(req);
|
||||||
assert(rreq == req);
|
ret = fxp_fstat_recv(pktin, req, &attrs);
|
||||||
ret = fxp_fstat_recv(pktin, rreq, &attrs);
|
|
||||||
|
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
close_rfile(file);
|
close_rfile(file);
|
||||||
@ -729,10 +732,9 @@ int sftp_put_file(char *fname, char *outfname, int recurse, int restart)
|
|||||||
|
|
||||||
xfer_cleanup(xfer);
|
xfer_cleanup(xfer);
|
||||||
|
|
||||||
sftp_register(req = fxp_close_send(fh));
|
req = fxp_close_send(fh);
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
pktin = sftp_wait_for_reply(req);
|
||||||
assert(rreq == req);
|
fxp_close_recv(pktin, req);
|
||||||
fxp_close_recv(pktin, rreq);
|
|
||||||
|
|
||||||
close_rfile(file);
|
close_rfile(file);
|
||||||
|
|
||||||
@ -754,7 +756,7 @@ typedef struct SftpWildcardMatcher {
|
|||||||
SftpWildcardMatcher *sftp_begin_wildcard_matching(char *name)
|
SftpWildcardMatcher *sftp_begin_wildcard_matching(char *name)
|
||||||
{
|
{
|
||||||
struct sftp_packet *pktin;
|
struct sftp_packet *pktin;
|
||||||
struct sftp_request *req, *rreq;
|
struct sftp_request *req;
|
||||||
char *wildcard;
|
char *wildcard;
|
||||||
char *unwcdir, *tmpdir, *cdir;
|
char *unwcdir, *tmpdir, *cdir;
|
||||||
int len, check;
|
int len, check;
|
||||||
@ -785,10 +787,9 @@ SftpWildcardMatcher *sftp_begin_wildcard_matching(char *name)
|
|||||||
|
|
||||||
cdir = canonify(unwcdir);
|
cdir = canonify(unwcdir);
|
||||||
|
|
||||||
sftp_register(req = fxp_opendir_send(cdir));
|
req = fxp_opendir_send(cdir);
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
pktin = sftp_wait_for_reply(req);
|
||||||
assert(rreq == req);
|
dirh = fxp_opendir_recv(pktin, req);
|
||||||
dirh = fxp_opendir_recv(pktin, rreq);
|
|
||||||
|
|
||||||
if (dirh) {
|
if (dirh) {
|
||||||
swcm = snew(SftpWildcardMatcher);
|
swcm = snew(SftpWildcardMatcher);
|
||||||
@ -811,7 +812,7 @@ char *sftp_wildcard_get_filename(SftpWildcardMatcher *swcm)
|
|||||||
{
|
{
|
||||||
struct fxp_name *name;
|
struct fxp_name *name;
|
||||||
struct sftp_packet *pktin;
|
struct sftp_packet *pktin;
|
||||||
struct sftp_request *req, *rreq;
|
struct sftp_request *req;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (swcm->names && swcm->namepos >= swcm->names->nnames) {
|
if (swcm->names && swcm->namepos >= swcm->names->nnames) {
|
||||||
@ -820,10 +821,9 @@ char *sftp_wildcard_get_filename(SftpWildcardMatcher *swcm)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!swcm->names) {
|
if (!swcm->names) {
|
||||||
sftp_register(req = fxp_readdir_send(swcm->dirh));
|
req = fxp_readdir_send(swcm->dirh);
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
pktin = sftp_wait_for_reply(req);
|
||||||
assert(rreq == req);
|
swcm->names = fxp_readdir_recv(pktin, req);
|
||||||
swcm->names = fxp_readdir_recv(pktin, rreq);
|
|
||||||
|
|
||||||
if (!swcm->names) {
|
if (!swcm->names) {
|
||||||
if (fxp_error_type() != SSH_FX_EOF)
|
if (fxp_error_type() != SSH_FX_EOF)
|
||||||
@ -875,12 +875,11 @@ char *sftp_wildcard_get_filename(SftpWildcardMatcher *swcm)
|
|||||||
void sftp_finish_wildcard_matching(SftpWildcardMatcher *swcm)
|
void sftp_finish_wildcard_matching(SftpWildcardMatcher *swcm)
|
||||||
{
|
{
|
||||||
struct sftp_packet *pktin;
|
struct sftp_packet *pktin;
|
||||||
struct sftp_request *req, *rreq;
|
struct sftp_request *req;
|
||||||
|
|
||||||
sftp_register(req = fxp_close_send(swcm->dirh));
|
req = fxp_close_send(swcm->dirh);
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
pktin = sftp_wait_for_reply(req);
|
||||||
assert(rreq == req);
|
fxp_close_recv(pktin, req);
|
||||||
fxp_close_recv(pktin, rreq);
|
|
||||||
|
|
||||||
if (swcm->names)
|
if (swcm->names)
|
||||||
fxp_free_names(swcm->names);
|
fxp_free_names(swcm->names);
|
||||||
@ -1011,7 +1010,7 @@ int sftp_cmd_ls(struct sftp_command *cmd)
|
|||||||
int nnames, namesize;
|
int nnames, namesize;
|
||||||
char *dir, *cdir, *unwcdir, *wildcard;
|
char *dir, *cdir, *unwcdir, *wildcard;
|
||||||
struct sftp_packet *pktin;
|
struct sftp_packet *pktin;
|
||||||
struct sftp_request *req, *rreq;
|
struct sftp_request *req;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (back == NULL) {
|
if (back == NULL) {
|
||||||
@ -1058,10 +1057,9 @@ int sftp_cmd_ls(struct sftp_command *cmd)
|
|||||||
|
|
||||||
printf("Listing directory %s\n", cdir);
|
printf("Listing directory %s\n", cdir);
|
||||||
|
|
||||||
sftp_register(req = fxp_opendir_send(cdir));
|
req = fxp_opendir_send(cdir);
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
pktin = sftp_wait_for_reply(req);
|
||||||
assert(rreq == req);
|
dirh = fxp_opendir_recv(pktin, req);
|
||||||
dirh = fxp_opendir_recv(pktin, rreq);
|
|
||||||
|
|
||||||
if (dirh == NULL) {
|
if (dirh == NULL) {
|
||||||
printf("Unable to open %s: %s\n", dir, fxp_error());
|
printf("Unable to open %s: %s\n", dir, fxp_error());
|
||||||
@ -1071,10 +1069,9 @@ int sftp_cmd_ls(struct sftp_command *cmd)
|
|||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
|
|
||||||
sftp_register(req = fxp_readdir_send(dirh));
|
req = fxp_readdir_send(dirh);
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
pktin = sftp_wait_for_reply(req);
|
||||||
assert(rreq == req);
|
names = fxp_readdir_recv(pktin, req);
|
||||||
names = fxp_readdir_recv(pktin, rreq);
|
|
||||||
|
|
||||||
if (names == NULL) {
|
if (names == NULL) {
|
||||||
if (fxp_error_type() == SSH_FX_EOF)
|
if (fxp_error_type() == SSH_FX_EOF)
|
||||||
@ -1098,10 +1095,9 @@ int sftp_cmd_ls(struct sftp_command *cmd)
|
|||||||
|
|
||||||
fxp_free_names(names);
|
fxp_free_names(names);
|
||||||
}
|
}
|
||||||
sftp_register(req = fxp_close_send(dirh));
|
req = fxp_close_send(dirh);
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
pktin = sftp_wait_for_reply(req);
|
||||||
assert(rreq == req);
|
fxp_close_recv(pktin, req);
|
||||||
fxp_close_recv(pktin, rreq);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now we have our filenames. Sort them by actual file
|
* Now we have our filenames. Sort them by actual file
|
||||||
@ -1133,7 +1129,7 @@ int sftp_cmd_cd(struct sftp_command *cmd)
|
|||||||
{
|
{
|
||||||
struct fxp_handle *dirh;
|
struct fxp_handle *dirh;
|
||||||
struct sftp_packet *pktin;
|
struct sftp_packet *pktin;
|
||||||
struct sftp_request *req, *rreq;
|
struct sftp_request *req;
|
||||||
char *dir;
|
char *dir;
|
||||||
|
|
||||||
if (back == NULL) {
|
if (back == NULL) {
|
||||||
@ -1151,10 +1147,9 @@ int sftp_cmd_cd(struct sftp_command *cmd)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
sftp_register(req = fxp_opendir_send(dir));
|
req = fxp_opendir_send(dir);
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
pktin = sftp_wait_for_reply(req);
|
||||||
assert(rreq == req);
|
dirh = fxp_opendir_recv(pktin, req);
|
||||||
dirh = fxp_opendir_recv(pktin, rreq);
|
|
||||||
|
|
||||||
if (!dirh) {
|
if (!dirh) {
|
||||||
printf("Directory %s: %s\n", dir, fxp_error());
|
printf("Directory %s: %s\n", dir, fxp_error());
|
||||||
@ -1162,10 +1157,9 @@ int sftp_cmd_cd(struct sftp_command *cmd)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
sftp_register(req = fxp_close_send(dirh));
|
req = fxp_close_send(dirh);
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
pktin = sftp_wait_for_reply(req);
|
||||||
assert(rreq == req);
|
fxp_close_recv(pktin, req);
|
||||||
fxp_close_recv(pktin, rreq);
|
|
||||||
|
|
||||||
sfree(pwd);
|
sfree(pwd);
|
||||||
pwd = dir;
|
pwd = dir;
|
||||||
@ -1414,7 +1408,7 @@ int sftp_cmd_mkdir(struct sftp_command *cmd)
|
|||||||
{
|
{
|
||||||
char *dir;
|
char *dir;
|
||||||
struct sftp_packet *pktin;
|
struct sftp_packet *pktin;
|
||||||
struct sftp_request *req, *rreq;
|
struct sftp_request *req;
|
||||||
int result;
|
int result;
|
||||||
int i, ret;
|
int i, ret;
|
||||||
|
|
||||||
@ -1436,10 +1430,9 @@ int sftp_cmd_mkdir(struct sftp_command *cmd)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
sftp_register(req = fxp_mkdir_send(dir));
|
req = fxp_mkdir_send(dir);
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
pktin = sftp_wait_for_reply(req);
|
||||||
assert(rreq == req);
|
result = fxp_mkdir_recv(pktin, req);
|
||||||
result = fxp_mkdir_recv(pktin, rreq);
|
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
printf("mkdir %s: %s\n", dir, fxp_error());
|
printf("mkdir %s: %s\n", dir, fxp_error());
|
||||||
@ -1456,13 +1449,12 @@ int sftp_cmd_mkdir(struct sftp_command *cmd)
|
|||||||
static int sftp_action_rmdir(void *vctx, char *dir)
|
static int sftp_action_rmdir(void *vctx, char *dir)
|
||||||
{
|
{
|
||||||
struct sftp_packet *pktin;
|
struct sftp_packet *pktin;
|
||||||
struct sftp_request *req, *rreq;
|
struct sftp_request *req;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
sftp_register(req = fxp_rmdir_send(dir));
|
req = fxp_rmdir_send(dir);
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
pktin = sftp_wait_for_reply(req);
|
||||||
assert(rreq == req);
|
result = fxp_rmdir_recv(pktin, req);
|
||||||
result = fxp_rmdir_recv(pktin, rreq);
|
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
printf("rmdir %s: %s\n", dir, fxp_error());
|
printf("rmdir %s: %s\n", dir, fxp_error());
|
||||||
@ -1498,13 +1490,12 @@ int sftp_cmd_rmdir(struct sftp_command *cmd)
|
|||||||
static int sftp_action_rm(void *vctx, char *fname)
|
static int sftp_action_rm(void *vctx, char *fname)
|
||||||
{
|
{
|
||||||
struct sftp_packet *pktin;
|
struct sftp_packet *pktin;
|
||||||
struct sftp_request *req, *rreq;
|
struct sftp_request *req;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
sftp_register(req = fxp_remove_send(fname));
|
req = fxp_remove_send(fname);
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
pktin = sftp_wait_for_reply(req);
|
||||||
assert(rreq == req);
|
result = fxp_remove_recv(pktin, req);
|
||||||
result = fxp_remove_recv(pktin, rreq);
|
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
printf("rm %s: %s\n", fname, fxp_error());
|
printf("rm %s: %s\n", fname, fxp_error());
|
||||||
@ -1540,14 +1531,13 @@ int sftp_cmd_rm(struct sftp_command *cmd)
|
|||||||
static int check_is_dir(char *dstfname)
|
static int check_is_dir(char *dstfname)
|
||||||
{
|
{
|
||||||
struct sftp_packet *pktin;
|
struct sftp_packet *pktin;
|
||||||
struct sftp_request *req, *rreq;
|
struct sftp_request *req;
|
||||||
struct fxp_attrs attrs;
|
struct fxp_attrs attrs;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
sftp_register(req = fxp_stat_send(dstfname));
|
req = fxp_stat_send(dstfname);
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
pktin = sftp_wait_for_reply(req);
|
||||||
assert(rreq == req);
|
result = fxp_stat_recv(pktin, req, &attrs);
|
||||||
result = fxp_stat_recv(pktin, rreq, &attrs);
|
|
||||||
|
|
||||||
if (result &&
|
if (result &&
|
||||||
(attrs.flags & SSH_FILEXFER_ATTR_PERMISSIONS) &&
|
(attrs.flags & SSH_FILEXFER_ATTR_PERMISSIONS) &&
|
||||||
@ -1566,7 +1556,7 @@ static int sftp_action_mv(void *vctx, char *srcfname)
|
|||||||
{
|
{
|
||||||
struct sftp_context_mv *ctx = (struct sftp_context_mv *)vctx;
|
struct sftp_context_mv *ctx = (struct sftp_context_mv *)vctx;
|
||||||
struct sftp_packet *pktin;
|
struct sftp_packet *pktin;
|
||||||
struct sftp_request *req, *rreq;
|
struct sftp_request *req;
|
||||||
const char *error;
|
const char *error;
|
||||||
char *finalfname, *newcanon = NULL;
|
char *finalfname, *newcanon = NULL;
|
||||||
int ret, result;
|
int ret, result;
|
||||||
@ -1591,10 +1581,9 @@ static int sftp_action_mv(void *vctx, char *srcfname)
|
|||||||
finalfname = ctx->dstfname;
|
finalfname = ctx->dstfname;
|
||||||
}
|
}
|
||||||
|
|
||||||
sftp_register(req = fxp_rename_send(srcfname, finalfname));
|
req = fxp_rename_send(srcfname, finalfname);
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
pktin = sftp_wait_for_reply(req);
|
||||||
assert(rreq == req);
|
result = fxp_rename_recv(pktin, req);
|
||||||
result = fxp_rename_recv(pktin, rreq);
|
|
||||||
|
|
||||||
error = result ? NULL : fxp_error();
|
error = result ? NULL : fxp_error();
|
||||||
|
|
||||||
@ -1663,15 +1652,14 @@ static int sftp_action_chmod(void *vctx, char *fname)
|
|||||||
{
|
{
|
||||||
struct fxp_attrs attrs;
|
struct fxp_attrs attrs;
|
||||||
struct sftp_packet *pktin;
|
struct sftp_packet *pktin;
|
||||||
struct sftp_request *req, *rreq;
|
struct sftp_request *req;
|
||||||
int result;
|
int result;
|
||||||
unsigned oldperms, newperms;
|
unsigned oldperms, newperms;
|
||||||
struct sftp_context_chmod *ctx = (struct sftp_context_chmod *)vctx;
|
struct sftp_context_chmod *ctx = (struct sftp_context_chmod *)vctx;
|
||||||
|
|
||||||
sftp_register(req = fxp_stat_send(fname));
|
req = fxp_stat_send(fname);
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
pktin = sftp_wait_for_reply(req);
|
||||||
assert(rreq == req);
|
result = fxp_stat_recv(pktin, req, &attrs);
|
||||||
result = fxp_stat_recv(pktin, rreq, &attrs);
|
|
||||||
|
|
||||||
if (!result || !(attrs.flags & SSH_FILEXFER_ATTR_PERMISSIONS)) {
|
if (!result || !(attrs.flags & SSH_FILEXFER_ATTR_PERMISSIONS)) {
|
||||||
printf("get attrs for %s: %s\n", fname,
|
printf("get attrs for %s: %s\n", fname,
|
||||||
@ -1688,10 +1676,9 @@ static int sftp_action_chmod(void *vctx, char *fname)
|
|||||||
if (oldperms == newperms)
|
if (oldperms == newperms)
|
||||||
return 1; /* no need to do anything! */
|
return 1; /* no need to do anything! */
|
||||||
|
|
||||||
sftp_register(req = fxp_setstat_send(fname, attrs));
|
req = fxp_setstat_send(fname, attrs);
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
pktin = sftp_wait_for_reply(req);
|
||||||
assert(rreq == req);
|
result = fxp_setstat_recv(pktin, req);
|
||||||
result = fxp_setstat_recv(pktin, rreq);
|
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
printf("set attrs for %s: %s\n", fname, fxp_error());
|
printf("set attrs for %s: %s\n", fname, fxp_error());
|
||||||
@ -2341,7 +2328,7 @@ struct sftp_command *sftp_getcmd(FILE *fp, int mode, int modeflags)
|
|||||||
static int do_sftp_init(void)
|
static int do_sftp_init(void)
|
||||||
{
|
{
|
||||||
struct sftp_packet *pktin;
|
struct sftp_packet *pktin;
|
||||||
struct sftp_request *req, *rreq;
|
struct sftp_request *req;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do protocol initialisation.
|
* Do protocol initialisation.
|
||||||
@ -2355,10 +2342,9 @@ static int do_sftp_init(void)
|
|||||||
/*
|
/*
|
||||||
* Find out where our home directory is.
|
* Find out where our home directory is.
|
||||||
*/
|
*/
|
||||||
sftp_register(req = fxp_realpath_send("."));
|
req = fxp_realpath_send(".");
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
pktin = sftp_wait_for_reply(req);
|
||||||
assert(rreq == req);
|
homedir = fxp_realpath_recv(pktin, req);
|
||||||
homedir = fxp_realpath_recv(pktin, rreq);
|
|
||||||
|
|
||||||
if (!homedir) {
|
if (!homedir) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
|
5
sftp.c
5
sftp.c
@ -366,7 +366,6 @@ struct sftp_request *sftp_find_request(struct sftp_packet *pktin)
|
|||||||
|
|
||||||
if (!req || !req->registered) {
|
if (!req || !req->registered) {
|
||||||
fxp_internal_error("request ID mismatch\n");
|
fxp_internal_error("request ID mismatch\n");
|
||||||
sftp_pkt_free(pktin);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1203,6 +1202,8 @@ int xfer_download_gotpkt(struct fxp_xfer *xfer, struct sftp_packet *pktin)
|
|||||||
struct req *rr;
|
struct req *rr;
|
||||||
|
|
||||||
rreq = sftp_find_request(pktin);
|
rreq = sftp_find_request(pktin);
|
||||||
|
if (!rreq)
|
||||||
|
return 0; /* this packet doesn't even make sense */
|
||||||
rr = (struct req *)fxp_get_userdata(rreq);
|
rr = (struct req *)fxp_get_userdata(rreq);
|
||||||
if (!rr)
|
if (!rr)
|
||||||
return 0; /* this packet isn't ours */
|
return 0; /* this packet isn't ours */
|
||||||
@ -1383,6 +1384,8 @@ int xfer_upload_gotpkt(struct fxp_xfer *xfer, struct sftp_packet *pktin)
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
rreq = sftp_find_request(pktin);
|
rreq = sftp_find_request(pktin);
|
||||||
|
if (!rreq)
|
||||||
|
return 0; /* this packet doesn't even make sense */
|
||||||
rr = (struct req *)fxp_get_userdata(rreq);
|
rr = (struct req *)fxp_get_userdata(rreq);
|
||||||
if (!rr)
|
if (!rr)
|
||||||
return 0; /* this packet isn't ours */
|
return 0; /* this packet isn't ours */
|
||||||
|
Loading…
Reference in New Issue
Block a user