X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=pscp.c;h=f63e6b5986538acfe18ecdbd80281ea800d812f9;hb=HEAD;hp=0dbe1e34e7bad95e4ff71ea3280cc95dffb8c101;hpb=da32db15957789d13b7e37b298f733cfc1099218;p=PuTTY_svn.git diff --git a/pscp.c b/pscp.c index 0dbe1e34..f63e6b59 100644 --- a/pscp.c +++ b/pscp.c @@ -41,6 +41,7 @@ static int try_sftp = 1; static int main_cmd_is_sftp = 0; static int fallback_cmd_is_sftp = 0; static int using_sftp = 0; +static int uploading = 0; static Backend *back; static void *backhandle; @@ -129,6 +130,19 @@ void modalfatalbox(char *fmt, ...) cleanup_exit(1); } +void nonfatal(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); + tell_str(stderr, str2); + sfree(str2); + errs++; +} void connection_fatal(void *frontend, char *fmt, ...) { char *str, *str2; @@ -218,11 +232,12 @@ int from_backend_untrusted(void *frontend_handle, const char *data, int len) int from_backend_eof(void *frontend) { /* - * We expect to be the party deciding when to close the + * We usually expect to be the party deciding when to close the * connection, so if we see EOF before we sent it ourselves, we - * should panic. + * should panic. The exception is if we're using old-style scp and + * downloading rather than uploading. */ - if (!sent_eof) { + if ((using_sftp || uploading) && !sent_eof) { connection_fatal(frontend, "Received unexpected end-of-file from server"); } @@ -355,15 +370,9 @@ static void do_cmd(char *host, char *user, char *cmd) bump("Empty host name"); /* - * Remove fiddly bits of address: remove a colon suffix, and - * the square brackets around an IPv6 literal address. + * Remove a colon suffix. */ - if (host[0] == '[') { - host++; - host[strcspn(host, "]")] = '\0'; - } else { - host[strcspn(host, ":")] = '\0'; - } + host[host_strcspn(host, ":")] = '\0'; /* * If we haven't loaded session details already (e.g., from -load), @@ -526,7 +535,7 @@ static void do_cmd(char *host, char *user, char *cmd) console_provide_logctx(logctx); ssh_scp_init(); if (verbose && realhost != NULL && errs == 0) - tell_user(stderr, "Connected to %s\n", realhost); + tell_user(stderr, "Connected to %s", realhost); sfree(realhost); } @@ -598,17 +607,7 @@ static char *colon(char *str) if (str[0] == '\0' || str[0] == ':' || (str[0] != '[' && str[1] == ':')) return (NULL); - while (*str != '\0' && *str != ':' && *str != '/' && *str != '\\') { - if (*str == '[') { - /* Skip over IPv6 literal addresses - * (eg: 'jeroen@[2001:db8::1]:myfile.txt') */ - char *ipv6_end = strchr(str, ']'); - if (ipv6_end) { - str = ipv6_end; - } - } - str++; - } + str += host_strcspn(str, ":/\\"); if (*str == ':') return (str); else @@ -675,7 +674,7 @@ static int response(void) } while (p < sizeof(rbuf) && ch != '\n'); rbuf[p - 1] = '\0'; if (resp == 1) - tell_user(stderr, "%s\n", rbuf); + tell_user(stderr, "%s", rbuf); else bump("%s", rbuf); errs++; @@ -773,6 +772,8 @@ void scp_sftp_listdir(char *dirname) */ for (i = 0; i < nnames; i++) printf("%s\n", ournames[i].longname); + + sfree(ournames); } } @@ -891,6 +892,7 @@ int scp_send_filename(char *name, uint64 size, int permissions) if (!scp_sftp_filehandle) { tell_user(stderr, "pscp: unable to open %s: %s", fullname, fxp_error()); + sfree(fullname); errs++; return 1; } @@ -927,7 +929,9 @@ int scp_send_filedata(char *data, int len) pktin = sftp_recv(); ret = xfer_upload_gotpkt(scp_sftp_xfer, pktin); if (ret <= 0) { - tell_user(stderr, "error while writing: %s\n", fxp_error()); + tell_user(stderr, "error while writing: %s", fxp_error()); + if (ret == INT_MIN) /* pktin not even freed */ + sfree(pktin); errs++; return 1; } @@ -968,7 +972,9 @@ int scp_send_finish(void) pktin = sftp_recv(); ret = xfer_upload_gotpkt(scp_sftp_xfer, pktin); if (ret <= 0) { - tell_user(stderr, "error while writing: %s\n", fxp_error()); + tell_user(stderr, "error while writing: %s", fxp_error()); + if (ret == INT_MIN) /* pktin not even freed */ + sfree(pktin); errs++; return 1; } @@ -986,7 +992,7 @@ int scp_send_finish(void) pktin = sftp_wait_for_reply(req); ret = fxp_fsetstat_recv(pktin, req); if (!ret) { - tell_user(stderr, "unable to set file times: %s\n", fxp_error()); + tell_user(stderr, "unable to set file times: %s", fxp_error()); errs++; } } @@ -1055,6 +1061,7 @@ int scp_send_dirname(char *name, int modes) !(attrs.permissions & 0040000)) { tell_user(stderr, "unable to create directory %s: %s", fullname, err); + sfree(fullname); errs++; return 1; } @@ -1110,6 +1117,9 @@ int scp_sink_setup(char *source, int preserve, int recursive) if (!wc_unescape(newsource, source)) { /* Yes, here we go; it's a wildcard. Bah. */ char *dupsource, *lastpart, *dirpart, *wildcard; + + sfree(newsource); + dupsource = dupstr(source); lastpart = stripslashes(dupsource, 0); wildcard = dupstr(lastpart); @@ -1275,6 +1285,7 @@ int scp_get_sink_action(struct scp_sink_action *act) if (!ret || !(attrs.flags & SSH_FILEXFER_ATTR_PERMISSIONS)) { tell_user(stderr, "unable to identify %s: %s", fname, ret ? "file type not supplied" : fxp_error()); + if (must_free_fname) sfree(fname); errs++; return 1; } @@ -1328,7 +1339,7 @@ int scp_get_sink_action(struct scp_sink_action *act) dirhandle = fxp_opendir_recv(pktin, req); if (!dirhandle) { - tell_user(stderr, "scp: unable to open directory %s: %s", + tell_user(stderr, "pscp: unable to open directory %s: %s", fname, fxp_error()); if (must_free_fname) sfree(fname); errs++; @@ -1346,8 +1357,13 @@ int scp_get_sink_action(struct scp_sink_action *act) if (names == NULL) { if (fxp_error_type() == SSH_FX_EOF) break; - tell_user(stderr, "scp: reading directory %s: %s\n", + tell_user(stderr, "pscp: reading directory %s: %s", fname, fxp_error()); + + req = fxp_close_send(dirhandle); + pktin = sftp_wait_for_reply(req); + fxp_close_recv(pktin, req); + if (must_free_fname) sfree(fname); sfree(ournames); errs++; @@ -1371,7 +1387,7 @@ int scp_get_sink_action(struct scp_sink_action *act) */ } else if (!vet_filename(names->names[i].filename)) { tell_user(stderr, "ignoring potentially dangerous server-" - "supplied filename '%s'\n", + "supplied filename '%s'", names->names[i].filename); } else ournames[nnames++] = names->names[i]; @@ -1474,7 +1490,7 @@ int scp_get_sink_action(struct scp_sink_action *act) act->buf[i - 1] = '\0'; switch (action) { case '\01': /* error */ - tell_user(stderr, "%s\n", act->buf); + tell_user(stderr, "%s", act->buf); errs++; continue; /* go round again */ case '\02': /* fatal error */ @@ -1561,6 +1577,8 @@ int scp_recv_filedata(char *data, int len) ret = xfer_download_gotpkt(scp_sftp_xfer, pktin); if (ret <= 0) { tell_user(stderr, "pscp: error while reading: %s", fxp_error()); + if (ret == INT_MIN) /* pktin not even freed */ + sfree(pktin); errs++; return -1; } @@ -1606,6 +1624,8 @@ int scp_finish_filerecv(void) ret = xfer_download_gotpkt(scp_sftp_xfer, pktin); if (ret <= 0) { tell_user(stderr, "pscp: error while reading: %s", fxp_error()); + if (ret == INT_MIN) /* pktin not even freed */ + sfree(pktin); errs++; return -1; } @@ -1635,7 +1655,7 @@ static void run_err(const char *fmt, ...) va_start(ap, fmt); errs++; str = dupvprintf(fmt, ap); - str2 = dupcat("scp: ", str, "\n", NULL); + str2 = dupcat("pscp: ", str, "\n", NULL); sfree(str); scp_send_errmsg(str2); tell_user(stderr, "%s", str2); @@ -1704,8 +1724,10 @@ static void source(char *src) return; } if (preserve) { - if (scp_send_filetimes(mtime, atime)) + if (scp_send_filetimes(mtime, atime)) { + close_rfile(f); return; + } } if (verbose) { @@ -1713,8 +1735,10 @@ static void source(char *src) uint64_decimal(size, sizestr); tell_user(stderr, "Sending file %s, size=%s", last, sizestr); } - if (scp_send_filename(last, size, permissions)) + if (scp_send_filename(last, size, permissions)) { + close_rfile(f); return; + } stat_bytes = uint64_make(0,0); stat_starttime = time(NULL); @@ -1917,27 +1941,34 @@ static void sink(char *targ, char *src) if (act.action == SCP_SINK_DIR) { if (exists && attr != FILE_TYPE_DIRECTORY) { run_err("%s: Not a directory", destfname); + sfree(destfname); continue; } if (!exists) { if (!create_directory(destfname)) { run_err("%s: Cannot create directory", destfname); + sfree(destfname); continue; } } sink(destfname, NULL); /* can we set the timestamp for directories ? */ + sfree(destfname); continue; } f = open_new_file(destfname, act.permissions); if (f == NULL) { run_err("%s: Cannot create file", destfname); + sfree(destfname); continue; } - if (scp_accept_filexfer()) + if (scp_accept_filexfer()) { + sfree(destfname); + close_wfile(f); return; + } stat_bytes = uint64_make(0, 0); stat_starttime = time(NULL); @@ -1984,6 +2015,7 @@ static void sink(char *targ, char *src) close_wfile(f); if (wrerror) { run_err("%s: Write error", destfname); + sfree(destfname); continue; } (void) scp_finish_filerecv(); @@ -2001,6 +2033,8 @@ static void toremote(int argc, char *argv[]) char *cmd; int i, wc_type; + uploading = 1; + targ = argv[argc - 1]; /* Separate host from filename */ @@ -2090,6 +2124,8 @@ static void tolocal(int argc, char *argv[]) char *src, *targ, *host, *user; char *cmd; + uploading = 0; + if (argc != 2) bump("More than one remote source not supported"); @@ -2255,6 +2291,9 @@ void cmdline_error(char *p, ...) exit(1); } +const int share_can_be_downstream = TRUE; +const int share_can_be_upstream = FALSE; + /* * Main program. (Called `psftp_main' because it gets called from * *sftp.c; bit silly, I know, but it had to be called _something_.)