#include "includes.h"
-RCSID("$OpenBSD: sftp.c,v 1.1 2001/02/04 11:11:54 djm Exp $");
+RCSID("$OpenBSD: sftp.c,v 1.14 2001/04/12 23:17:54 mouring Exp $");
/* XXX: commandline mode */
/* XXX: copy between two remote hosts (commandline) */
#include "sftp-client.h"
#include "sftp-int.h"
+#ifdef HAVE___PROGNAME
+extern char *__progname;
+#else
+char *__progname;
+#endif
+
+int use_ssh1 = 0;
+char *ssh_program = _PATH_SSH_PROGRAM;
+char *sftp_server = NULL;
+FILE* infile;
+
void
connect_to_server(char **args, int *in, int *out, pid_t *sshpid)
{
close(*out);
close(c_in);
close(c_out);
- execv(_PATH_SSH_PROGRAM, args);
- fprintf(stderr, "exec: %s", strerror(errno));
+ execv(ssh_program, args);
+ fprintf(stderr, "exec: %s: %s\n", ssh_program, strerror(errno));
exit(1);
}
/* Init args array */
if (args == NULL) {
- nargs = 4;
+ nargs = 2;
i = 0;
args = xmalloc(sizeof(*args) * nargs);
args[i++] = "ssh";
- args[i++] = "-oProtocol=2";
- args[i++] = "-s";
args[i++] = NULL;
}
return(NULL);
}
+ /* no subsystem if the server-spec contains a '/' */
+ if (sftp_server == NULL || strchr(sftp_server, '/') == NULL)
+ make_ssh_args("-s");
+ make_ssh_args("-oForwardX11=no");
+ make_ssh_args("-oForwardAgent=no");
+ make_ssh_args(use_ssh1 ? "-oProtocol=1" : "-oProtocol=2");
+
/* Otherwise finish up and return the arg array */
- make_ssh_args("sftp");
+ if (sftp_server != NULL)
+ make_ssh_args(sftp_server);
+ else
+ make_ssh_args("sftp");
/* XXX: overflow - doesn't grow debug_buf */
debug_buf[0] = '\0';
void
usage(void)
{
- fprintf(stderr, "usage: sftp [-vC] [-osshopt=value] [user@]host\n");
+ fprintf(stderr, "usage: sftp [-1vC] [-b batchfile] [-osshopt=value] [user@]host[:file [file]]\n");
exit(1);
}
int
main(int argc, char **argv)
{
- int in, out, i, debug_level, compress_flag;
+ int in, out, ch, debug_level, compress_flag;
pid_t sshpid;
- char *cp;
+ char *file1 = NULL;
+ char *host, *userhost, *cp, *file2;
LogLevel ll;
+ extern int optind;
+ extern char *optarg;
+ __progname = get_progname(argv[0]);
+ infile = stdin; /* Read from STDIN unless changed by -b */
debug_level = compress_flag = 0;
- for(i = 1; i < argc && argv[i][0] == '-'; i++) {
- if (!strcmp(argv[i], "-v"))
- debug_level = MIN(3, debug_level + 1);
- else if (!strcmp(argv[i], "-C"))
+
+ while ((ch = getopt(argc, argv, "1hvCo:s:S:b:")) != -1) {
+ switch (ch) {
+ case 'C':
compress_flag = 1;
- else if (!strncmp(argv[i], "-o", 2)) {
- make_ssh_args(argv[i]);
- } else {
- fprintf(stderr, "Unknown option \"%s\"\n", argv[i]);
+ break;
+ case 'v':
+ debug_level = MIN(3, debug_level + 1);
+ break;
+ case 'o':
+ make_ssh_args("-o");
+ make_ssh_args(optarg);
+ break;
+ case '1':
+ use_ssh1 = 1;
+ if (sftp_server == NULL)
+ sftp_server = _PATH_SFTP_SERVER;
+ break;
+ case 's':
+ sftp_server = optarg;
+ break;
+ case 'S':
+ ssh_program = optarg;
+ break;
+ case 'b':
+ if (infile == stdin) {
+ infile = fopen(optarg, "r");
+ if (infile == NULL)
+ fatal("%s (%s).", strerror(errno), optarg);
+ } else
+ fatal("Filename already specified.");
+ break;
+ case 'h':
+ default:
usage();
}
}
- if (i == argc || argc > (i + 1))
+ if (optind == argc || argc > (optind + 2))
usage();
- if ((cp = strchr(argv[i], '@')) == NULL)
- cp = argv[i];
+ userhost = xstrdup(argv[optind]);
+ file2 = argv[optind+1];
+
+ if ((cp = strchr(userhost, ':')) != NULL) {
+ *cp++ = '\0';
+ file1 = cp;
+ }
+
+ if ((host = strchr(userhost, '@')) == NULL)
+ host = userhost;
else {
- *cp = '\0';
- if (!argv[i][0]) {
+ *host++ = '\0';
+ if (!userhost[0]) {
fprintf(stderr, "Missing username\n");
usage();
}
make_ssh_args("-l");
- make_ssh_args(argv[i]);
- cp++;
+ make_ssh_args(userhost);
}
- if (!*cp) {
+ if (!*host) {
fprintf(stderr, "Missing hostname\n");
usage();
}
log_init(argv[0], ll, SYSLOG_FACILITY_USER, 1);
- make_ssh_args(cp);
+ make_ssh_args(host);
- fprintf(stderr, "Connecting to %s...\n", cp);
+ fprintf(stderr, "Connecting to %s...\n", host);
connect_to_server(make_ssh_args(NULL), &in, &out, &sshpid);
- do_init(in, out);
+ interactive_loop(in, out, file1, file2);
- interactive_loop(in, out);
+#if !defined(USE_PIPES)
+ shutdown(in, SHUT_RDWR);
+ shutdown(out, SHUT_RDWR);
+#endif
close(in);
close(out);
+ if (infile != stdin)
+ fclose(infile);
- if (kill(sshpid, SIGHUP) == -1)
- fatal("Couldn't terminate ssh process: %s", strerror(errno));
-
- /* XXX: wait? */
+ if (waitpid(sshpid, NULL, 0) == -1)
+ fatal("Couldn't wait for ssh process: %s", strerror(errno));
exit(0);
}