1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-09 17:38:00 +00:00

Patch to PSFTP: implement mkdir, rmdir, rm and scripting. Still to

do: wildcards, chmod, mv, probably other things.

[originally from svn r1168]
This commit is contained in:
Simon Tatham 2001-08-04 14:19:51 +00:00
parent 15cf1e664b
commit 4a0fb28883
3 changed files with 241 additions and 18 deletions

167
psftp.c
View File

@ -460,6 +460,94 @@ int sftp_cmd_put(struct sftp_command *cmd)
return 0;
}
int sftp_cmd_mkdir(struct sftp_command *cmd)
{
char *dir;
int result;
if (cmd->nwords < 2) {
printf("mkdir: expects a directory\n");
return 0;
}
dir = canonify(cmd->words[1]);
if (!dir) {
printf("%s: %s\n", dir, fxp_error());
return 0;
}
result = fxp_mkdir(dir);
if (!result) {
printf("mkdir %s: %s\n", dir, fxp_error());
sfree(dir);
return 0;
}
sfree(dir);
return 0;
}
int sftp_cmd_rmdir(struct sftp_command *cmd)
{
char *dir;
int result;
if (cmd->nwords < 2) {
printf("rmdir: expects a directory\n");
return 0;
}
dir = canonify(cmd->words[1]);
if (!dir) {
printf("%s: %s\n", dir, fxp_error());
return 0;
}
result = fxp_rmdir(dir);
if (!result) {
printf("rmdir %s: %s\n", dir, fxp_error());
sfree(dir);
return 0;
}
sfree(dir);
return 0;
}
int sftp_cmd_rm(struct sftp_command *cmd)
{
char *fname;
int result;
if (cmd->nwords < 2) {
printf("rm: expects a filename\n");
return 0;
}
fname = canonify(cmd->words[1]);
if (!fname) {
printf("%s: %s\n", fname, fxp_error());
return 0;
}
result = fxp_rm(fname);
if (!result) {
printf("rm %s: %s\n", fname, fxp_error());
sfree(fname);
return 0;
}
sfree(fname);
return 0;
}
static struct sftp_cmd_lookup {
char *name;
int (*obey) (struct sftp_command *);
@ -475,13 +563,16 @@ static struct sftp_cmd_lookup {
"exit", sftp_cmd_quit}, {
"get", sftp_cmd_get}, {
"ls", sftp_cmd_ls}, {
"mkdir", sftp_cmd_mkdir}, {
"put", sftp_cmd_put}, {
"quit", sftp_cmd_quit},};
"quit", sftp_cmd_quit}, {
"rm", sftp_cmd_rm}, {
"rmdir", sftp_cmd_rmdir},};
/* ----------------------------------------------------------------------
* Command line reading and parsing.
*/
struct sftp_command *sftp_getcmd(void)
struct sftp_command *sftp_getcmd(FILE *fp, int mode, int modeflags)
{
char *line;
int linelen, linesize;
@ -489,7 +580,9 @@ struct sftp_command *sftp_getcmd(void)
char *p, *q, *r;
int quoting;
printf("psftp> ");
if ((mode == 0) || (modeflags & 1)) {
printf("psftp> ");
}
fflush(stdout);
cmd = smalloc(sizeof(struct sftp_command));
@ -505,7 +598,10 @@ struct sftp_command *sftp_getcmd(void)
linesize += 512;
line = srealloc(line, linesize);
ret = fgets(line + linelen, linesize - linelen, stdin);
ret = fgets(line + linelen, linesize - linelen, fp);
if (modeflags & 1) {
printf("%s", ret);
}
if (!ret || (linelen == 0 && line[0] == '\0')) {
cmd->obey = sftp_cmd_quit;
@ -596,8 +692,10 @@ struct sftp_command *sftp_getcmd(void)
return cmd;
}
void do_sftp(void)
void do_sftp(int mode, int modeflags, char *batchfile)
{
FILE *fp;
/*
* Do protocol initialisation.
*/
@ -621,16 +719,42 @@ void do_sftp(void)
}
pwd = dupstr(homedir);
/* ------------------------------------------------------------------
* Now we're ready to do Real Stuff.
/*
* Batch mode?
*/
while (1) {
struct sftp_command *cmd;
cmd = sftp_getcmd();
if (!cmd)
break;
if (cmd->obey(cmd) < 0)
break;
if (mode == 0) {
/* ------------------------------------------------------------------
* Now we're ready to do Real Stuff.
*/
while (1) {
struct sftp_command *cmd;
cmd = sftp_getcmd(stdin, 0, 0);
if (!cmd)
break;
if (cmd->obey(cmd) < 0)
break;
}
} else {
fp = fopen(batchfile, "r");
if (!fp) {
printf("Fatal: unable to open %s\n", batchfile);
return;
}
while (1) {
struct sftp_command *cmd;
cmd = sftp_getcmd(fp, mode, modeflags);
if (!cmd)
break;
if (cmd->obey(cmd) < 0)
break;
if (fxp_error() != NULL) {
if (!(modeflags & 2))
break;
}
}
fclose(fp);
}
}
@ -972,6 +1096,9 @@ static void usage(void)
printf("%s\n", ver);
printf("Usage: psftp [options] user@host\n");
printf("Options:\n");
printf(" -b file use specified batchfile\n");
printf(" -bc output batchfile commands\n");
printf(" -be don't stop batchfile processing if errors\n");
printf(" -v show verbose messages\n");
printf(" -P port connect to specified port\n");
printf(" -pw passw login with specified password\n");
@ -987,6 +1114,9 @@ int main(int argc, char *argv[])
int portnumber = 0;
char *user, *host, *userhost, *realhost;
char *err;
int mode = 0;
int modeflags = 0;
char *batchfile = NULL;
flags = FLAG_STDERR;
ssh_get_line = &get_line;
@ -1012,6 +1142,13 @@ int main(int argc, char *argv[])
portnumber = atoi(argv[++i]);
} else if (strcmp(argv[i], "-pw") == 0 && i + 1 < argc) {
password = argv[++i];
} else if (strcmp(argv[i], "-b") == 0 && i + 1 < argc) {
mode = 1;
batchfile = argv[++i];
} else if (strcmp(argv[i], "-bc") == 0 && i + 1 < argc) {
modeflags = modeflags | 1;
} else if (strcmp(argv[i], "-be") == 0 && i + 1 < argc) {
modeflags = modeflags | 2;
} else if (strcmp(argv[i], "--") == 0) {
i++;
break;
@ -1092,7 +1229,7 @@ int main(int argc, char *argv[])
if (verbose && realhost != NULL)
printf("Connected to %s\n", realhost);
do_sftp();
do_sftp(mode, modeflags, batchfile);
if (back != NULL && back->socket() != NULL) {
char ch;

77
sftp.c
View File

@ -33,6 +33,9 @@ struct sftp_packet {
int type;
};
static const char *fxp_error_message;
static int fxp_errtype;
/* ----------------------------------------------------------------------
* SFTP packet construction functions.
*/
@ -62,6 +65,7 @@ static struct sftp_packet *sftp_pkt_init(int pkt_type)
pkt->length = 0;
pkt->maxlen = 0;
sftp_pkt_addbyte(pkt, (unsigned char) pkt_type);
fxp_error_message = NULL;
return pkt;
}
static void sftp_pkt_addbool(struct sftp_packet *pkt, unsigned char value)
@ -234,9 +238,6 @@ static char *mkstr(char *s, int len)
* SFTP primitives.
*/
static const char *fxp_error_message;
static int fxp_errtype;
/*
* Deal with (and free) an FXP_STATUS packet. Return 1 if
* SSH_FX_OK, 0 if SSH_FX_EOF, and -1 for anything else (error).
@ -480,6 +481,76 @@ void fxp_close(struct fxp_handle *handle)
sfree(handle);
}
int fxp_mkdir(char *path)
{
struct sftp_packet *pktin, *pktout;
int id;
pktout = sftp_pkt_init(SSH_FXP_MKDIR);
sftp_pkt_adduint32(pktout, 0x234); /* request id */
sftp_pkt_addstring_start(pktout);
sftp_pkt_addstring_data(pktout, path, strlen(path));
sftp_pkt_adduint32(pktout, 0); /* (FIXME) empty ATTRS structure */
sftp_send(pktout);
pktin = sftp_recv();
id = sftp_pkt_getuint32(pktin);
if (id != 0x234) {
fxp_internal_error("request ID mismatch\n");
return 0;
}
id = fxp_got_status(pktin);
if (id != 1) {
return 0;
}
return 1;
}
int fxp_rmdir(char *path)
{
struct sftp_packet *pktin, *pktout;
int id;
pktout = sftp_pkt_init(SSH_FXP_RMDIR);
sftp_pkt_adduint32(pktout, 0x345); /* request id */
sftp_pkt_addstring_start(pktout);
sftp_pkt_addstring_data(pktout, path, strlen(path));
sftp_send(pktout);
pktin = sftp_recv();
id = sftp_pkt_getuint32(pktin);
if (id != 0x345) {
fxp_internal_error("request ID mismatch\n");
return 0;
}
id = fxp_got_status(pktin);
if (id != 1) {
return 0;
}
return 1;
}
int fxp_rm(char *fname)
{
struct sftp_packet *pktin, *pktout;
int id;
pktout = sftp_pkt_init(SSH_FXP_REMOVE);
sftp_pkt_adduint32(pktout, 0x678); /* request id */
sftp_pkt_addstring_start(pktout);
sftp_pkt_addstring_data(pktout, fname, strlen(fname));
sftp_send(pktout);
pktin = sftp_recv();
id = sftp_pkt_getuint32(pktin);
if (id != 0x678) {
fxp_internal_error("request ID mismatch\n");
return 0;
}
id = fxp_got_status(pktin);
if (id != 1) {
return 0;
}
return 1;
}
/*
* Read from a file. Returns the number of bytes read, or -1 on an
* error, or possibly 0 if EOF. (I'm not entirely sure whether it

15
sftp.h
View File

@ -121,6 +121,21 @@ struct fxp_handle *fxp_opendir(char *path);
*/
void fxp_close(struct fxp_handle *handle);
/*
* Makes a directory
*/
int fxp_mkdir(char *path);
/*
* Removes a directory
*/
int fxp_rmdir(char *path);
/*
* Removes a file
*/
int fxp_rm(char *fname);
/*
* Read from a file.
*/