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 *);
"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;
char *p, *q, *r;
int quoting;
- printf("psftp> ");
+ if ((mode == 0) || (modeflags & 1)) {
+ printf("psftp> ");
+ }
fflush(stdout);
cmd = smalloc(sizeof(struct sftp_command));
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;
return cmd;
}
-void do_sftp(void)
+void do_sftp(int mode, int modeflags, char *batchfile)
{
+ FILE *fp;
+
/*
* Do protocol initialisation.
*/
}
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);
+
}
}
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");
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;
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;
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;
int type;
};
+static const char *fxp_error_message;
+static int fxp_errtype;
+
/* ----------------------------------------------------------------------
* SFTP packet construction functions.
*/
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)
* 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).
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