X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=psftp.c;h=e0e027a1abf2894cc3198c59f2cde767e6e6cd5b;hb=89da2ddf564a93414ee9ab2df3f053608094e417;hp=65d0dc50ada89282e6907313514660279dd087cd;hpb=779466f0b0089b7d7b35d7acd39498d57d62a539;p=PuTTY.git diff --git a/psftp.c b/psftp.c index 65d0dc50..e0e027a1 100644 --- a/psftp.c +++ b/psftp.c @@ -68,7 +68,7 @@ struct sftp_packet *sftp_wait_for_reply(struct sftp_request *req) * canonification fails, at least fall back to returning a _valid_ * pathname (though it may be ugly, eg /home/simon/../foobar). */ -char *canonify(char *name) +char *canonify(const char *name) { char *fullname, *canonname; struct sftp_packet *pktin; @@ -77,7 +77,7 @@ char *canonify(char *name) if (name[0] == '/') { fullname = dupstr(name); } else { - char *slash; + const char *slash; if (pwd[strlen(pwd) - 1] == '/') slash = ""; else @@ -172,8 +172,13 @@ char *canonify(char *name) /* * Return a pointer to the portion of str that comes after the last * slash (or backslash or colon, if `local' is TRUE). + * + * This function has the annoying strstr() property of taking a const + * char * and returning a char *. You should treat it as if it was a + * pair of overloaded functions, one mapping mutable->mutable and the + * other const->const :-( */ -static char *stripslashes(char *str, int local) +static char *stripslashes(const char *str, int local) { char *p; @@ -190,7 +195,7 @@ static char *stripslashes(char *str, int local) if (p) str = p+1; } - return str; + return (char *)str; } /* @@ -291,6 +296,11 @@ int sftp_get_file(char *fname, char *outfname, int recurse, int restart) if (fxp_error_type() == SSH_FX_EOF) break; printf("%s: reading directory: %s\n", fname, fxp_error()); + + req = fxp_close_send(dirhandle); + pktin = sftp_wait_for_reply(req); + fxp_close_recv(pktin, req); + sfree(ournames); return 0; } @@ -463,6 +473,8 @@ int sftp_get_file(char *fname, char *outfname, int recurse, int restart) printf("error while reading: %s\n", fxp_error()); shown_err = TRUE; } + if (ret == INT_MIN) /* pktin not even freed */ + sfree(pktin); ret = 0; } @@ -661,21 +673,19 @@ int sftp_put_file(char *fname, char *outfname, int recurse, int restart) if (restart) { char decbuf[30]; struct fxp_attrs attrs; - int ret; req = fxp_fstat_send(fh); pktin = sftp_wait_for_reply(req); ret = fxp_fstat_recv(pktin, req, &attrs); if (!ret) { - close_rfile(file); printf("read size of %s: %s\n", outfname, fxp_error()); - return 0; + goto cleanup; } if (!(attrs.flags & SSH_FILEXFER_ATTR_SIZE)) { - close_rfile(file); printf("read size of %s: size was not given\n", outfname); - return 0; + ret = 0; + goto cleanup; } offset = attrs.size; uint64_decimal(offset, decbuf); @@ -715,15 +725,20 @@ int sftp_put_file(char *fname, char *outfname, int recurse, int restart) if (!xfer_done(xfer)) { pktin = sftp_recv(); ret = xfer_upload_gotpkt(xfer, pktin); - if (ret <= 0 && !err) { - printf("error while writing: %s\n", fxp_error()); - err = 1; + if (ret <= 0) { + if (ret == INT_MIN) /* pktin not even freed */ + sfree(pktin); + if (!err) { + printf("error while writing: %s\n", fxp_error()); + err = 1; + } } } } xfer_cleanup(xfer); + cleanup: req = fxp_close_send(fh); pktin = sftp_wait_for_reply(req); fxp_close_recv(pktin, req); @@ -911,6 +926,7 @@ int wildcard_iterate(char *filename, int (*func)(void *, char *), void *ctx) printf("%s: canonify: %s\n", newname, fxp_error()); ret = 0; } + sfree(newname); matched = TRUE; ret &= func(ctx, cname); sfree(cname); @@ -1000,7 +1016,8 @@ int sftp_cmd_ls(struct sftp_command *cmd) struct fxp_names *names; struct fxp_name **ournames; int nnames, namesize; - char *dir, *cdir, *unwcdir, *wildcard; + const char *dir; + char *cdir, *unwcdir, *wildcard; struct sftp_packet *pktin; struct sftp_request *req; int i; @@ -1023,6 +1040,7 @@ int sftp_cmd_ls(struct sftp_command *cmd) char *tmpdir; int len, check; + sfree(unwcdir); wildcard = stripslashes(dir, 0); unwcdir = dupstr(dir); len = wildcard - dir; @@ -1245,7 +1263,9 @@ int sftp_general_get(struct sftp_command *cmd, int restart, int multiple) fname = canonify(origwfname); if (!fname) { + sftp_finish_wildcard_matching(swcm); printf("%s: canonify: %s\n", origwfname, fxp_error()); + sfree(origwfname); sfree(unwcfname); return 0; } @@ -1887,7 +1907,7 @@ static int sftp_cmd_pling(struct sftp_command *cmd) static int sftp_cmd_help(struct sftp_command *cmd); static struct sftp_cmd_lookup { - char *name; + const char *name; /* * For help purposes, there are two kinds of command: * @@ -1901,8 +1921,8 @@ static struct sftp_cmd_lookup { * contains the help that should double up for this command. */ int listed; /* do we list this in primary help? */ - char *shorthelp; - char *longhelp; + const char *shorthelp; + const char *longhelp; int (*obey) (struct sftp_command *); } sftp_lookup[] = { /* @@ -2125,7 +2145,7 @@ static struct sftp_cmd_lookup { } }; -const struct sftp_cmd_lookup *lookup_command(char *name) +const struct sftp_cmd_lookup *lookup_command(const char *name) { int i, j, k, cmp; @@ -2221,6 +2241,7 @@ struct sftp_command *sftp_getcmd(FILE *fp, int mode, int modeflags) cmd->obey = sftp_cmd_quit; if ((mode == 0) || (modeflags & 1)) printf("quit\n"); + sfree(line); return cmd; /* eof */ } @@ -2435,7 +2456,7 @@ static int verbose = 0; /* * Print an error message and perform a fatal exit. */ -void fatalbox(char *fmt, ...) +void fatalbox(const char *fmt, ...) { char *str, *str2; va_list ap; @@ -2449,7 +2470,7 @@ void fatalbox(char *fmt, ...) cleanup_exit(1); } -void modalfatalbox(char *fmt, ...) +void modalfatalbox(const char *fmt, ...) { char *str, *str2; va_list ap; @@ -2463,7 +2484,19 @@ void modalfatalbox(char *fmt, ...) cleanup_exit(1); } -void connection_fatal(void *frontend, char *fmt, ...) +void nonfatal(const char *fmt, ...) +{ + char *str, *str2; + va_list ap; + va_start(ap, fmt); + str = dupvprintf(fmt, ap); + str2 = dupcat("Error: ", str, "\n", NULL); + sfree(str); + va_end(ap); + fputs(str2, stderr); + sfree(str2); +} +void connection_fatal(void *frontend, const char *fmt, ...) { char *str, *str2; va_list ap; @@ -2478,16 +2511,7 @@ void connection_fatal(void *frontend, char *fmt, ...) cleanup_exit(1); } -void ldisc_send(void *handle, char *buf, int len, int interactive) -{ - /* - * This is only here because of the calls to ldisc_send(NULL, - * 0) in ssh.c. Nothing in PSFTP actually needs to use the - * ldisc as an ldisc. So if we get called with any real data, I - * want to know about it. - */ - assert(len == 0); -} +void ldisc_echoedit_update(void *handle) { } /* * In psftp, all agent requests should be synchronous, so this is a @@ -2640,9 +2664,11 @@ static void usage(void) printf(" -1 -2 force use of particular SSH protocol version\n"); printf(" -4 -6 force use of IPv4 or IPv6\n"); printf(" -C enable compression\n"); - printf(" -i key private key file for authentication\n"); + printf(" -i key private key file for user authentication\n"); printf(" -noagent disable use of Pageant\n"); printf(" -agent enable use of Pageant\n"); + printf(" -hostkey aa:bb:cc:...\n"); + printf(" manually specify a host key (may be repeated)\n"); printf(" -batch disable all interactive prompts\n"); cleanup_exit(1); } @@ -2694,6 +2720,7 @@ static int psftp_connect(char *userhost, char *user, int portnumber) /* Use `host' as a bare hostname. */ conf_set_str(conf, CONF_host, host); } + conf_free(conf2); } else { /* Patch in hostname `host' to session details. */ conf_set_str(conf, CONF_host, host); @@ -2845,7 +2872,7 @@ static int psftp_connect(char *userhost, char *user, int portnumber) return 0; } -void cmdline_error(char *p, ...) +void cmdline_error(const char *p, ...) { va_list ap; fprintf(stderr, "psftp: "); @@ -2856,6 +2883,9 @@ void cmdline_error(char *p, ...) exit(1); } +const int share_can_be_downstream = TRUE; +const int share_can_be_upstream = FALSE; + /* * Main program. Parse arguments etc. */