X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/90767715ca41354855c3736df8d8a60115e31ba5..bf1e6912b12754fd79a48dfe6d77760532598dc3:/psftp.c diff --git a/psftp.c b/psftp.c index c3fb62ae..1def80eb 100644 --- a/psftp.c +++ b/psftp.c @@ -1,5 +1,5 @@ /* - * psftp.c: front end for PSFTP. + * psftp.c: (platform-independent) front end for PSFTP. */ #include @@ -1361,45 +1361,34 @@ static int sftp_cmd_help(struct sftp_command *cmd) struct sftp_command *sftp_getcmd(FILE *fp, int mode, int modeflags) { char *line; - int linelen, linesize; struct sftp_command *cmd; char *p, *q, *r; int quoting; - if ((mode == 0) || (modeflags & 1)) { - printf("psftp> "); - } - fflush(stdout); - cmd = snew(struct sftp_command); cmd->words = NULL; cmd->nwords = 0; cmd->wordssize = 0; line = NULL; - linesize = linelen = 0; - while (1) { - int len; - char *ret; - - linesize += 512; - line = sresize(line, linesize, char); - ret = fgets(line + linelen, linesize - linelen, fp); - - if (!ret || (linelen == 0 && line[0] == '\0')) { - cmd->obey = sftp_cmd_quit; - if ((mode == 0) || (modeflags & 1)) - printf("quit\n"); - return cmd; /* eof */ - } - len = linelen + strlen(line + linelen); - linelen += len; - if (line[linelen - 1] == '\n') { - linelen--; - line[linelen] = '\0'; - break; - } + + if (fp) { + if (modeflags & 1) + printf("psftp> "); + line = fgetline(fp); + } else { + line = ssh_sftp_get_cmdline("psftp> "); } + + if (!line || !*line) { + cmd->obey = sftp_cmd_quit; + if ((mode == 0) || (modeflags & 1)) + printf("quit\n"); + return cmd; /* eof */ + } + + line[strcspn(line, "\r\n")] = '\0'; + if (modeflags & 1) { printf("%s\n", line); } @@ -1464,7 +1453,8 @@ struct sftp_command *sftp_getcmd(FILE *fp, int mode, int modeflags) } } - sfree(line); + sfree(line); + /* * Now parse the first word and assign a function. */ @@ -1551,7 +1541,7 @@ void do_sftp(int mode, int modeflags, char *batchfile) */ while (1) { struct sftp_command *cmd; - cmd = sftp_getcmd(stdin, 0, 0); + cmd = sftp_getcmd(NULL, 0, 0); if (!cmd) break; ret = cmd->obey(cmd); @@ -1779,9 +1769,16 @@ static void usage(void) printf(" -C enable compression\n"); printf(" -i key private key file for authentication\n"); printf(" -batch disable all interactive prompts\n"); + printf(" -V print version information\n"); cleanup_exit(1); } +static void version(void) +{ + printf("psftp: %s\n", ver); + cleanup_exit(1); +} + /* * Connect to a host. */ @@ -1805,11 +1802,27 @@ static int psftp_connect(char *userhost, char *user, int portnumber) user = userhost; } - /* Try to load settings for this host */ - do_defaults(host, &cfg); - if (cfg.host[0] == '\0') { - /* No settings for this host; use defaults */ - do_defaults(NULL, &cfg); + /* + * If we haven't loaded session details already (e.g., from -load), + * try looking for a session called "host". + */ + if (!loaded_session) { + /* Try to load settings for `host' into a temporary config */ + Config cfg2; + cfg2.host[0] = '\0'; + do_defaults(host, &cfg2); + if (cfg2.host[0] != '\0') { + /* Settings present and include hostname */ + /* Re-load data into the real config. */ + do_defaults(host, &cfg); + } else { + /* Session doesn't exist or mention a hostname. */ + /* Use `host' as a bare hostname. */ + strncpy(cfg.host, host, sizeof(cfg.host) - 1); + cfg.host[sizeof(cfg.host) - 1] = '\0'; + } + } else { + /* Patch in hostname `host' to session details. */ strncpy(cfg.host, host, sizeof(cfg.host) - 1); cfg.host[sizeof(cfg.host) - 1] = '\0'; } @@ -1824,6 +1837,15 @@ static int psftp_connect(char *userhost, char *user, int portnumber) } /* + * If saved session / Default Settings says SSH-1 (`1 only' or `1'), + * then change it to SSH-2, on the grounds that that's more likely to + * work for SFTP. (Can be overridden with `-1' option.) + * But if it says `2 only' or `2', respect which. + */ + if (cfg.sshprot != 2 && cfg.sshprot != 3) + cfg.sshprot = 2; + + /* * Enact command-line overrides. */ cmdline_run_saved(&cfg); @@ -1838,7 +1860,7 @@ static int psftp_connect(char *userhost, char *user, int portnumber) /* See if host is of the form user@host */ if (cfg.host[0] != '\0') { - char *atsign = strchr(cfg.host, '@'); + char *atsign = strrchr(cfg.host, '@'); /* Make sure we're not overflowing the user field */ if (atsign) { if (atsign - cfg.host < sizeof cfg.username) { @@ -1875,10 +1897,9 @@ static int psftp_connect(char *userhost, char *user, int portnumber) cfg.username[sizeof(cfg.username) - 1] = '\0'; } if (!cfg.username[0]) { - printf("login as: "); - fflush(stdout); - if (!fgets(cfg.username, sizeof(cfg.username), stdin)) { - fprintf(stderr, "psftp: aborting\n"); + if (!console_get_line("login as: ", + cfg.username, sizeof(cfg.username), FALSE)) { + fprintf(stderr, "psftp: no username, aborting\n"); cleanup_exit(1); } else { int len = strlen(cfg.username); @@ -1890,9 +1911,6 @@ static int psftp_connect(char *userhost, char *user, int portnumber) if (portnumber) cfg.port = portnumber; - /* SFTP uses SSH2 by default always */ - cfg.sshprot = 2; - /* * Disable scary things which shouldn't be enabled for simple * things like SCP and SFTP: agent forwarding, port forwarding, @@ -1932,7 +1950,8 @@ static int psftp_connect(char *userhost, char *user, int portnumber) back = &ssh_backend; - err = back->init(NULL, &backhandle, &cfg, cfg.host, cfg.port, &realhost,0); + err = back->init(NULL, &backhandle, &cfg, cfg.host, cfg.port, &realhost, + 0, cfg.tcp_keepalives); if (err != NULL) { fprintf(stderr, "ssh_init: %s\n", err); return 1; @@ -1988,6 +2007,10 @@ int psftp_main(int argc, char *argv[]) userhost = user = NULL; + /* Load Default Settings before doing anything else. */ + do_defaults(NULL, &cfg); + loaded_session = FALSE; + errors = 0; for (i = 1; i < argc; i++) { int ret; @@ -2010,6 +2033,8 @@ int psftp_main(int argc, char *argv[]) } else if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "-?") == 0) { usage(); + } else if (strcmp(argv[i], "-V") == 0) { + version(); } else if (strcmp(argv[i], "-batch") == 0) { console_batch_mode = 1; } else if (strcmp(argv[i], "-b") == 0 && i + 1 < argc) { @@ -2031,6 +2056,15 @@ int psftp_main(int argc, char *argv[]) back = NULL; /* + * If the loaded session provides a hostname, and a hostname has not + * otherwise been specified, pop it in `userhost' so that + * `psftp -load sessname' is sufficient to start a session. + */ + if (!userhost && cfg.host[0] != '\0') { + userhost = dupstr(cfg.host); + } + + /* * If a user@host string has already been provided, connect to * it now. */