* Higher-level helper functions used in commands.
*/
-/*
- * Determine whether a string is entirely composed of dots.
- */
-static int is_dots(char *str)
-{
- return str[strspn(str, ".")] == '\0';
-}
-
/*
* Attempt to canonify a pathname starting from the pwd. If
* canonification fails, at least fall back to returning a _valid_
ournames = sresize(ournames, namesize, struct fxp_name *);
}
for (i = 0; i < names->nnames; i++)
- if (!is_dots(names->names[i].filename) &&
+ if (strcmp(names->names[i].filename, ".") &&
+ strcmp(names->names[i].filename, "..") &&
(!wildcard || wc_match(wildcard,
- names->names[i].filename)))
- ournames[nnames++] = fxp_dup_name(&names->names[i]);
+ names->names[i].filename))) {
+ if (!vet_filename(names->names[i].filename)) {
+ printf("ignoring potentially dangerous server-"
+ "supplied filename '%s'\n",
+ names->names[i].filename);
+ } else {
+ ournames[nnames++] =
+ fxp_dup_name(&names->names[i]);
+ }
+ }
fxp_free_names(names);
}
sftp_register(req = fxp_close_send(dirhandle));
return -1;
}
+int sftp_cmd_close(struct sftp_command *cmd)
+{
+ if (back == NULL) {
+ printf("psftp: not connected to a host; use \"open host.name\"\n");
+ return 0;
+ }
+
+ if (back != NULL && back->socket(backhandle) != NULL) {
+ char ch;
+ back->special(backhandle, TS_EOF);
+ sftp_recvdata(&ch, 1);
+ }
+ do_sftp_cleanup();
+
+ return 0;
+}
+
/*
* List a directory. If no arguments are given, list pwd; otherwise
* list the directory given in words[1].
struct fxp_names *names;
struct fxp_name **ournames;
int nnames, namesize;
- char *dir, *cdir;
+ char *dir, *cdir, *unwcdir, *wildcard;
struct sftp_packet *pktin;
struct sftp_request *req, *rreq;
int i;
else
dir = cmd->words[1];
+ unwcdir = snewn(1 + strlen(dir), char);
+ if (wc_unescape(unwcdir, dir)) {
+ dir = unwcdir;
+ wildcard = NULL;
+ } else {
+ char *tmpdir;
+ int len, check;
+
+ wildcard = stripslashes(dir, 0);
+ unwcdir = dupstr(dir);
+ len = wildcard - dir;
+ unwcdir[len] = '\0';
+ if (len > 0 && unwcdir[len-1] == '/')
+ unwcdir[len-1] = '\0';
+ tmpdir = snewn(1 + len, char);
+ check = wc_unescape(tmpdir, unwcdir);
+ sfree(tmpdir);
+ if (!check) {
+ printf("Multiple-level wildcards are not supported\n");
+ sfree(unwcdir);
+ return 0;
+ }
+ dir = unwcdir;
+ }
+
cdir = canonify(dir);
if (!cdir) {
printf("%s: %s\n", dir, fxp_error());
+ sfree(unwcdir);
return 0;
}
}
for (i = 0; i < names->nnames; i++)
- ournames[nnames++] = fxp_dup_name(&names->names[i]);
+ if (!wildcard || wc_match(wildcard, names->names[i].filename))
+ ournames[nnames++] = fxp_dup_name(&names->names[i]);
fxp_free_names(names);
}
}
sfree(cdir);
+ sfree(unwcdir);
return 1;
}
if (!multiple && i < cmd->nwords)
outfname = cmd->words[i++];
else
- outfname = stripslashes(origfname, 1);
+ outfname = stripslashes(origfname, 0);
ret = sftp_get_file(fname, outfname, recurse, restart, NULL);
" use commas to separate different modifiers (\"u+rwx,g+s\").\n",
sftp_cmd_chmod
},
+ {
+ "close", TRUE, "finish your SFTP session but do not quit PSFTP",
+ "\n"
+ " Terminates your SFTP session, but does not quit the PSFTP\n"
+ " program. You can then use \"open\" to start another SFTP\n"
+ " session, to the same server or to a different one.\n",
+ sftp_cmd_close
+ },
{
"del", TRUE, "delete a file",
" <filename>\n"
printf("psftp> ");
line = fgetline(fp);
} else {
- line = ssh_sftp_get_cmdline("psftp> ");
+ line = ssh_sftp_get_cmdline("psftp> ", back == NULL);
}
if (!line || !*line) {
sftp_recvdata(&ch, 1);
back->free(backhandle);
sftp_cleanup_request();
+ back = NULL;
+ backhandle = NULL;
}
if (pwd) {
sfree(pwd);
back->special(backhandle, TS_EOF);
sftp_recvdata(&ch, 1);
}
+ do_sftp_cleanup();
random_save_seed();
cmdline_cleanup();
console_provide_logctx(NULL);
- do_sftp_cleanup();
- backhandle = NULL;
- back = NULL;
sk_cleanup();
return 0;