From: simon Date: Sat, 24 Feb 2001 12:02:35 +0000 (+0000) Subject: SFTP client now successfully handles cd, ls, get and put. X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/commitdiff_plain/f9e162aa7d74067d3eccca409dec510edf397364 SFTP client now successfully handles cd, ls, get and put. git-svn-id: svn://svn.tartarus.org/sgt/putty@939 cda61777-01e9-0310-a592-d414129be87e --- diff --git a/psftp.c b/psftp.c index 4445b8b7..50be4582 100644 --- a/psftp.c +++ b/psftp.c @@ -4,8 +4,8 @@ #include #include +#include #include -#include #include "sftp.h" #include "int64.h" @@ -25,6 +25,39 @@ char *dupstr(char *s) { return p; } +/* Allocate the concatenation of N strings. Terminate arg list with NULL. */ +char *dupcat(char *s1, ...) { + int len; + char *p, *q, *sn; + va_list ap; + + len = strlen(s1); + va_start(ap, s1); + while (1) { + sn = va_arg(ap, char *); + if (!sn) + break; + len += strlen(sn); + } + va_end(ap); + + p = smalloc(len+1); + strcpy(p, s1); + q = p + strlen(p); + + va_start(ap, s1); + while (1) { + sn = va_arg(ap, char *); + if (!sn) + break; + strcpy(q, sn); + q += strlen(q); + } + va_end(ap); + + return p; +} + /* ---------------------------------------------------------------------- * sftp client state. */ @@ -36,13 +69,23 @@ char *pwd, *homedir; */ /* - * Canonify a pathname starting from the pwd. + * Attempt to canonify a pathname starting from the pwd. If + * canonification fails, at least fall back to returning a _valid_ + * pathname (though it may be ugly, eg /home/simon/../foobar). */ char *canonify(char *name) { - if (name[0] == '/') - return fxp_realpath(name, NULL); - else - return fxp_realpath(pwd, name); + char *fullname, *canonname; + if (name[0] == '/') { + fullname = dupstr(name); + } else { + fullname = dupcat(pwd, "/", name, NULL); + } + canonname = fxp_realpath(name); + if (canonname) { + sfree(fullname); + return canonname; + } else + return fullname; } /* ---------------------------------------------------------------------- @@ -158,7 +201,7 @@ int sftp_cmd_cd(struct sftp_command *cmd) { char *dir; if (cmd->nwords < 2) - dir = fxp_realpath(".", NULL); + dir = dupstr(homedir); else dir = canonify(cmd->words[1]); @@ -278,7 +321,7 @@ int sftp_cmd_put(struct sftp_command *cmd) { fname = cmd->words[1]; origoutfname = (cmd->nwords == 2 ? cmd->words[1] : cmd->words[2]); outfname = canonify(origoutfname); -~|~ if (!outfname) { + if (!outfname) { printf("%s: %s\n", origoutfname, fxp_error()); return 0; } @@ -309,14 +352,14 @@ int sftp_cmd_put(struct sftp_command *cmd) { char buffer[4096]; int len; - len = fread(buffer, 1, len, fp); + len = fread(buffer, 1, sizeof(buffer), fp); if (len == -1) { printf("error while reading local file\n"); break; } else if (len == 0) { break; } - if (!fxp_write(fh, buffer, offset, sizeof(buffer))) { + if (!fxp_write(fh, buffer, offset, len)) { printf("error while writing: %s\n", fxp_error()); break; } @@ -474,7 +517,7 @@ void do_sftp(void) { /* * Find out where our home directory is. */ - homedir = fxp_realpath(".", NULL); + homedir = fxp_realpath("."); if (!homedir) { fprintf(stderr, "Warning: failed to resolve home directory: %s\n", diff --git a/sftp.c b/sftp.c index 6b519b69..51384be2 100644 --- a/sftp.c +++ b/sftp.c @@ -185,6 +185,8 @@ int io_init(void) { close(0); dup2(to[0], 0); close(to[1]); close(1); dup2(from[1], 1); close(from[0]); execl("/home/simon/src/openssh/openssh_cvs/prefix/bin/ssh", "ssh", "-2", "simon@localhost", "-s", "sftp", NULL); + //execl("/root/ssh-research/ssh-2.4.0/apps/ssh/sftp-server2", "sftp-server2", NULL); + //execl("/usr/lib/sftp-server", "sftp-server", NULL); assert(0); /* bomb out if not */ } else { /* We are parent. Close wrong end of each pipe, assign to glob vars. */ @@ -343,10 +345,9 @@ int fxp_init(void) { } /* - * Canonify a pathname. Concatenate the two given path elements - * with a separating slash, unless the second is NULL. + * Canonify a pathname. */ -char *fxp_realpath(char *path, char *path2) { +char *fxp_realpath(char *path) { struct sftp_packet *pktin, *pktout; int id; @@ -354,10 +355,6 @@ char *fxp_realpath(char *path, char *path2) { sftp_pkt_adduint32(pktout, 0x123); /* request id */ sftp_pkt_addstring_start(pktout); sftp_pkt_addstring_str(pktout, path); - if (path2) { - sftp_pkt_addstring_str(pktout, "/"); - sftp_pkt_addstring_str(pktout, path2); - } sftp_send(pktout); pktin = sftp_recv(); id = sftp_pkt_getuint32(pktin); @@ -421,6 +418,7 @@ struct fxp_handle *fxp_open(char *path, int type) { } handle = smalloc(sizeof(struct fxp_handle)); handle->hstring = mkstr(hstring, len); + handle->hlen = len; sftp_pkt_free(pktin); return handle; } else { @@ -459,6 +457,7 @@ struct fxp_handle *fxp_opendir(char *path) { } handle = smalloc(sizeof(struct fxp_handle)); handle->hstring = mkstr(hstring, len); + handle->hlen = len; sftp_pkt_free(pktin); return handle; } else { @@ -476,7 +475,8 @@ void fxp_close(struct fxp_handle *handle) { pktout = sftp_pkt_init(SSH_FXP_CLOSE); sftp_pkt_adduint32(pktout, 0x789); /* request id */ - sftp_pkt_addstring(pktout, handle->hstring); + sftp_pkt_addstring_start(pktout); + sftp_pkt_addstring_data(pktout, handle->hstring, handle->hlen); sftp_send(pktout); pktin = sftp_recv(); id = sftp_pkt_getuint32(pktin); @@ -501,7 +501,8 @@ int fxp_read(struct fxp_handle *handle, char *buffer, uint64 offset, int len) { pktout = sftp_pkt_init(SSH_FXP_READ); sftp_pkt_adduint32(pktout, 0xBCD); /* request id */ - sftp_pkt_addstring(pktout, handle->hstring); + sftp_pkt_addstring_start(pktout); + sftp_pkt_addstring_data(pktout, handle->hstring, handle->hlen); sftp_pkt_adduint64(pktout, offset); sftp_pkt_adduint32(pktout, len); sftp_send(pktout); @@ -540,7 +541,8 @@ struct fxp_names *fxp_readdir(struct fxp_handle *handle) { pktout = sftp_pkt_init(SSH_FXP_READDIR); sftp_pkt_adduint32(pktout, 0xABC); /* request id */ - sftp_pkt_addstring(pktout, handle->hstring); + sftp_pkt_addstring_start(pktout); + sftp_pkt_addstring_data(pktout, handle->hstring, handle->hlen); sftp_send(pktout); pktin = sftp_recv(); id = sftp_pkt_getuint32(pktin); @@ -579,7 +581,8 @@ int fxp_write(struct fxp_handle *handle, char *buffer, uint64 offset, int len) { pktout = sftp_pkt_init(SSH_FXP_WRITE); sftp_pkt_adduint32(pktout, 0xDCB); /* request id */ - sftp_pkt_addstring(pktout, handle->hstring); + sftp_pkt_addstring_start(pktout); + sftp_pkt_addstring_data(pktout, handle->hstring, handle->hlen); sftp_pkt_adduint64(pktout, offset); sftp_pkt_addstring_start(pktout); sftp_pkt_addstring_data(pktout, buffer, len); diff --git a/sftp.h b/sftp.h index f62f2a12..bee6bbeb 100644 --- a/sftp.h +++ b/sftp.h @@ -67,6 +67,7 @@ struct fxp_attrs { struct fxp_handle { char *hstring; + int hlen; }; struct fxp_name { @@ -91,7 +92,7 @@ int fxp_init(void); * Canonify a pathname. Concatenate the two given path elements * with a separating slash, unless the second is NULL. */ -char *fxp_realpath(char *path, char *path2); +char *fxp_realpath(char *path); /* * Open a file.