1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-25 01:02:24 +00:00

SFTP client now successfully handles cd, ls, get and put.

[originally from svn r939]
This commit is contained in:
Simon Tatham 2001-02-24 12:02:35 +00:00
parent 48b988b439
commit 094dd30d95
3 changed files with 70 additions and 23 deletions

65
psftp.c
View File

@ -4,8 +4,8 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h>
#include <assert.h> #include <assert.h>
#include <unistd.h>
#include "sftp.h" #include "sftp.h"
#include "int64.h" #include "int64.h"
@ -25,6 +25,39 @@ char *dupstr(char *s) {
return p; 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. * 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) { char *canonify(char *name) {
if (name[0] == '/') char *fullname, *canonname;
return fxp_realpath(name, NULL); if (name[0] == '/') {
else fullname = dupstr(name);
return fxp_realpath(pwd, 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; char *dir;
if (cmd->nwords < 2) if (cmd->nwords < 2)
dir = fxp_realpath(".", NULL); dir = dupstr(homedir);
else else
dir = canonify(cmd->words[1]); dir = canonify(cmd->words[1]);
@ -278,7 +321,7 @@ int sftp_cmd_put(struct sftp_command *cmd) {
fname = cmd->words[1]; fname = cmd->words[1];
origoutfname = (cmd->nwords == 2 ? cmd->words[1] : cmd->words[2]); origoutfname = (cmd->nwords == 2 ? cmd->words[1] : cmd->words[2]);
outfname = canonify(origoutfname); outfname = canonify(origoutfname);
~|~ if (!outfname) { if (!outfname) {
printf("%s: %s\n", origoutfname, fxp_error()); printf("%s: %s\n", origoutfname, fxp_error());
return 0; return 0;
} }
@ -309,14 +352,14 @@ int sftp_cmd_put(struct sftp_command *cmd) {
char buffer[4096]; char buffer[4096];
int len; int len;
len = fread(buffer, 1, len, fp); len = fread(buffer, 1, sizeof(buffer), fp);
if (len == -1) { if (len == -1) {
printf("error while reading local file\n"); printf("error while reading local file\n");
break; break;
} else if (len == 0) { } else if (len == 0) {
break; break;
} }
if (!fxp_write(fh, buffer, offset, sizeof(buffer))) { if (!fxp_write(fh, buffer, offset, len)) {
printf("error while writing: %s\n", fxp_error()); printf("error while writing: %s\n", fxp_error());
break; break;
} }
@ -474,7 +517,7 @@ void do_sftp(void) {
/* /*
* Find out where our home directory is. * Find out where our home directory is.
*/ */
homedir = fxp_realpath(".", NULL); homedir = fxp_realpath(".");
if (!homedir) { if (!homedir) {
fprintf(stderr, fprintf(stderr,
"Warning: failed to resolve home directory: %s\n", "Warning: failed to resolve home directory: %s\n",

25
sftp.c
View File

@ -185,6 +185,8 @@ int io_init(void) {
close(0); dup2(to[0], 0); close(to[1]); close(0); dup2(to[0], 0); close(to[1]);
close(1); dup2(from[1], 1); close(from[0]); 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("/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 */ assert(0); /* bomb out if not */
} else { } else {
/* We are parent. Close wrong end of each pipe, assign to glob vars. */ /* 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 * Canonify a pathname.
* with a separating slash, unless the second is NULL.
*/ */
char *fxp_realpath(char *path, char *path2) { char *fxp_realpath(char *path) {
struct sftp_packet *pktin, *pktout; struct sftp_packet *pktin, *pktout;
int id; int id;
@ -354,10 +355,6 @@ char *fxp_realpath(char *path, char *path2) {
sftp_pkt_adduint32(pktout, 0x123); /* request id */ sftp_pkt_adduint32(pktout, 0x123); /* request id */
sftp_pkt_addstring_start(pktout); sftp_pkt_addstring_start(pktout);
sftp_pkt_addstring_str(pktout, path); sftp_pkt_addstring_str(pktout, path);
if (path2) {
sftp_pkt_addstring_str(pktout, "/");
sftp_pkt_addstring_str(pktout, path2);
}
sftp_send(pktout); sftp_send(pktout);
pktin = sftp_recv(); pktin = sftp_recv();
id = sftp_pkt_getuint32(pktin); 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 = smalloc(sizeof(struct fxp_handle));
handle->hstring = mkstr(hstring, len); handle->hstring = mkstr(hstring, len);
handle->hlen = len;
sftp_pkt_free(pktin); sftp_pkt_free(pktin);
return handle; return handle;
} else { } else {
@ -459,6 +457,7 @@ struct fxp_handle *fxp_opendir(char *path) {
} }
handle = smalloc(sizeof(struct fxp_handle)); handle = smalloc(sizeof(struct fxp_handle));
handle->hstring = mkstr(hstring, len); handle->hstring = mkstr(hstring, len);
handle->hlen = len;
sftp_pkt_free(pktin); sftp_pkt_free(pktin);
return handle; return handle;
} else { } else {
@ -476,7 +475,8 @@ void fxp_close(struct fxp_handle *handle) {
pktout = sftp_pkt_init(SSH_FXP_CLOSE); pktout = sftp_pkt_init(SSH_FXP_CLOSE);
sftp_pkt_adduint32(pktout, 0x789); /* request id */ 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); sftp_send(pktout);
pktin = sftp_recv(); pktin = sftp_recv();
id = sftp_pkt_getuint32(pktin); 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); pktout = sftp_pkt_init(SSH_FXP_READ);
sftp_pkt_adduint32(pktout, 0xBCD); /* request id */ 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_adduint64(pktout, offset);
sftp_pkt_adduint32(pktout, len); sftp_pkt_adduint32(pktout, len);
sftp_send(pktout); sftp_send(pktout);
@ -540,7 +541,8 @@ struct fxp_names *fxp_readdir(struct fxp_handle *handle) {
pktout = sftp_pkt_init(SSH_FXP_READDIR); pktout = sftp_pkt_init(SSH_FXP_READDIR);
sftp_pkt_adduint32(pktout, 0xABC); /* request id */ 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); sftp_send(pktout);
pktin = sftp_recv(); pktin = sftp_recv();
id = sftp_pkt_getuint32(pktin); 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); pktout = sftp_pkt_init(SSH_FXP_WRITE);
sftp_pkt_adduint32(pktout, 0xDCB); /* request id */ 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_adduint64(pktout, offset);
sftp_pkt_addstring_start(pktout); sftp_pkt_addstring_start(pktout);
sftp_pkt_addstring_data(pktout, buffer, len); sftp_pkt_addstring_data(pktout, buffer, len);

3
sftp.h
View File

@ -67,6 +67,7 @@ struct fxp_attrs {
struct fxp_handle { struct fxp_handle {
char *hstring; char *hstring;
int hlen;
}; };
struct fxp_name { struct fxp_name {
@ -91,7 +92,7 @@ int fxp_init(void);
* Canonify a pathname. Concatenate the two given path elements * Canonify a pathname. Concatenate the two given path elements
* with a separating slash, unless the second is NULL. * with a separating slash, unless the second is NULL.
*/ */
char *fxp_realpath(char *path, char *path2); char *fxp_realpath(char *path);
/* /*
* Open a file. * Open a file.