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:
parent
15cf1e664b
commit
4a0fb28883
167
psftp.c
167
psftp.c
@ -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
77
sftp.c
@ -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
15
sftp.h
@ -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.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user