mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-03-22 14:39:24 -05: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:
parent
15cf1e664b
commit
4a0fb28883
167
psftp.c
167
psftp.c
@ -460,6 +460,94 @@ int sftp_cmd_put(struct sftp_command *cmd)
|
|||||||
return 0;
|
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 {
|
static struct sftp_cmd_lookup {
|
||||||
char *name;
|
char *name;
|
||||||
int (*obey) (struct sftp_command *);
|
int (*obey) (struct sftp_command *);
|
||||||
@ -475,13 +563,16 @@ static struct sftp_cmd_lookup {
|
|||||||
"exit", sftp_cmd_quit}, {
|
"exit", sftp_cmd_quit}, {
|
||||||
"get", sftp_cmd_get}, {
|
"get", sftp_cmd_get}, {
|
||||||
"ls", sftp_cmd_ls}, {
|
"ls", sftp_cmd_ls}, {
|
||||||
|
"mkdir", sftp_cmd_mkdir}, {
|
||||||
"put", sftp_cmd_put}, {
|
"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.
|
* Command line reading and parsing.
|
||||||
*/
|
*/
|
||||||
struct sftp_command *sftp_getcmd(void)
|
struct sftp_command *sftp_getcmd(FILE *fp, int mode, int modeflags)
|
||||||
{
|
{
|
||||||
char *line;
|
char *line;
|
||||||
int linelen, linesize;
|
int linelen, linesize;
|
||||||
@ -489,7 +580,9 @@ struct sftp_command *sftp_getcmd(void)
|
|||||||
char *p, *q, *r;
|
char *p, *q, *r;
|
||||||
int quoting;
|
int quoting;
|
||||||
|
|
||||||
printf("psftp> ");
|
if ((mode == 0) || (modeflags & 1)) {
|
||||||
|
printf("psftp> ");
|
||||||
|
}
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
||||||
cmd = smalloc(sizeof(struct sftp_command));
|
cmd = smalloc(sizeof(struct sftp_command));
|
||||||
@ -505,7 +598,10 @@ struct sftp_command *sftp_getcmd(void)
|
|||||||
|
|
||||||
linesize += 512;
|
linesize += 512;
|
||||||
line = srealloc(line, linesize);
|
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')) {
|
if (!ret || (linelen == 0 && line[0] == '\0')) {
|
||||||
cmd->obey = sftp_cmd_quit;
|
cmd->obey = sftp_cmd_quit;
|
||||||
@ -596,8 +692,10 @@ struct sftp_command *sftp_getcmd(void)
|
|||||||
return cmd;
|
return cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_sftp(void)
|
void do_sftp(int mode, int modeflags, char *batchfile)
|
||||||
{
|
{
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do protocol initialisation.
|
* Do protocol initialisation.
|
||||||
*/
|
*/
|
||||||
@ -621,16 +719,42 @@ void do_sftp(void)
|
|||||||
}
|
}
|
||||||
pwd = dupstr(homedir);
|
pwd = dupstr(homedir);
|
||||||
|
|
||||||
/* ------------------------------------------------------------------
|
/*
|
||||||
* Now we're ready to do Real Stuff.
|
* Batch mode?
|
||||||
*/
|
*/
|
||||||
while (1) {
|
if (mode == 0) {
|
||||||
struct sftp_command *cmd;
|
|
||||||
cmd = sftp_getcmd();
|
/* ------------------------------------------------------------------
|
||||||
if (!cmd)
|
* Now we're ready to do Real Stuff.
|
||||||
break;
|
*/
|
||||||
if (cmd->obey(cmd) < 0)
|
while (1) {
|
||||||
break;
|
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("%s\n", ver);
|
||||||
printf("Usage: psftp [options] user@host\n");
|
printf("Usage: psftp [options] user@host\n");
|
||||||
printf("Options:\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(" -v show verbose messages\n");
|
||||||
printf(" -P port connect to specified port\n");
|
printf(" -P port connect to specified port\n");
|
||||||
printf(" -pw passw login with specified password\n");
|
printf(" -pw passw login with specified password\n");
|
||||||
@ -987,6 +1114,9 @@ int main(int argc, char *argv[])
|
|||||||
int portnumber = 0;
|
int portnumber = 0;
|
||||||
char *user, *host, *userhost, *realhost;
|
char *user, *host, *userhost, *realhost;
|
||||||
char *err;
|
char *err;
|
||||||
|
int mode = 0;
|
||||||
|
int modeflags = 0;
|
||||||
|
char *batchfile = NULL;
|
||||||
|
|
||||||
flags = FLAG_STDERR;
|
flags = FLAG_STDERR;
|
||||||
ssh_get_line = &get_line;
|
ssh_get_line = &get_line;
|
||||||
@ -1012,6 +1142,13 @@ int main(int argc, char *argv[])
|
|||||||
portnumber = atoi(argv[++i]);
|
portnumber = atoi(argv[++i]);
|
||||||
} else if (strcmp(argv[i], "-pw") == 0 && i + 1 < argc) {
|
} else if (strcmp(argv[i], "-pw") == 0 && i + 1 < argc) {
|
||||||
password = argv[++i];
|
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) {
|
} else if (strcmp(argv[i], "--") == 0) {
|
||||||
i++;
|
i++;
|
||||||
break;
|
break;
|
||||||
@ -1092,7 +1229,7 @@ int main(int argc, char *argv[])
|
|||||||
if (verbose && realhost != NULL)
|
if (verbose && realhost != NULL)
|
||||||
printf("Connected to %s\n", realhost);
|
printf("Connected to %s\n", realhost);
|
||||||
|
|
||||||
do_sftp();
|
do_sftp(mode, modeflags, batchfile);
|
||||||
|
|
||||||
if (back != NULL && back->socket() != NULL) {
|
if (back != NULL && back->socket() != NULL) {
|
||||||
char ch;
|
char ch;
|
||||||
|
77
sftp.c
77
sftp.c
@ -33,6 +33,9 @@ struct sftp_packet {
|
|||||||
int type;
|
int type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char *fxp_error_message;
|
||||||
|
static int fxp_errtype;
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
* SFTP packet construction functions.
|
* SFTP packet construction functions.
|
||||||
*/
|
*/
|
||||||
@ -62,6 +65,7 @@ static struct sftp_packet *sftp_pkt_init(int pkt_type)
|
|||||||
pkt->length = 0;
|
pkt->length = 0;
|
||||||
pkt->maxlen = 0;
|
pkt->maxlen = 0;
|
||||||
sftp_pkt_addbyte(pkt, (unsigned char) pkt_type);
|
sftp_pkt_addbyte(pkt, (unsigned char) pkt_type);
|
||||||
|
fxp_error_message = NULL;
|
||||||
return pkt;
|
return pkt;
|
||||||
}
|
}
|
||||||
static void sftp_pkt_addbool(struct sftp_packet *pkt, unsigned char value)
|
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.
|
* SFTP primitives.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static const char *fxp_error_message;
|
|
||||||
static int fxp_errtype;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Deal with (and free) an FXP_STATUS packet. Return 1 if
|
* 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).
|
* 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);
|
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
|
* 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
|
* error, or possibly 0 if EOF. (I'm not entirely sure whether it
|
||||||
|
15
sftp.h
15
sftp.h
@ -121,6 +121,21 @@ struct fxp_handle *fxp_opendir(char *path);
|
|||||||
*/
|
*/
|
||||||
void fxp_close(struct fxp_handle *handle);
|
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.
|
* Read from a file.
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user