- djm@cvs.openbsd.org 2002/02/04 21:53:12
     [sftp.1 sftp.c]
     Add "-P" option to directly connect to a local sftp-server. Should be useful
     for regression testing; ok markus@
diff --git a/sftp.c b/sftp.c
index 97f670d..3748d05 100644
--- a/sftp.c
+++ b/sftp.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001 Damien Miller.  All rights reserved.
+ * Copyright (c) 2001,2002 Damien Miller.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -24,9 +24,8 @@
 
 #include "includes.h"
 
-RCSID("$OpenBSD: sftp.c,v 1.22 2001/12/19 07:18:56 deraadt Exp $");
+RCSID("$OpenBSD: sftp.c,v 1.23 2002/02/04 21:53:12 djm Exp $");
 
-/* XXX: commandline mode */
 /* XXX: short-form remote directory listings (like 'ls -C') */
 
 #include "buffer.h"
@@ -46,11 +45,10 @@
 char *__progname;
 #endif
 
-char *ssh_program = _PATH_SSH_PROGRAM;
 FILE* infile;
 
 static void
-connect_to_server(char **args, int *in, int *out, pid_t *sshpid)
+connect_to_server(char *path, char **args, int *in, int *out, pid_t *sshpid)
 {
 	int c_in, c_out;
 #ifdef USE_PIPES
@@ -81,8 +79,8 @@
 		close(*out);
 		close(c_in);
 		close(c_out);
-		execv(ssh_program, args);
-		fprintf(stderr, "exec: %s: %s\n", ssh_program, strerror(errno));
+		execv(path, args);
+		fprintf(stderr, "exec: %s: %s\n", path, strerror(errno));
 		exit(1);
 	}
 
@@ -107,6 +105,7 @@
 	char *host, *userhost, *cp, *file2;
 	int debug_level = 0, sshver = 2;
 	char *file1 = NULL, *sftp_server = NULL;
+	char *ssh_program = _PATH_SSH_PROGRAM, *sftp_direct = NULL;
 	LogLevel ll = SYSLOG_LEVEL_INFO;
 	arglist args;
 	extern int optind;
@@ -122,7 +121,7 @@
 	ll = SYSLOG_LEVEL_INFO;
 	infile = stdin;		/* Read from STDIN unless changed by -b */
 
-	while ((ch = getopt(argc, argv, "1hvCo:s:S:b:F:")) != -1) {
+	while ((ch = getopt(argc, argv, "1hvCo:s:S:b:F:P:")) != -1) {
 		switch (ch) {
 		case 'C':
 			addargs(&args, "-C");
@@ -157,55 +156,68 @@
 			} else
 				fatal("Filename already specified.");
 			break;
+		case 'P':
+			sftp_direct = optarg;
+			break;
 		case 'h':
 		default:
 			usage();
 		}
 	}
 
-	if (optind == argc || argc > (optind + 2))
-		usage();
+	if (sftp_direct == NULL) {
+		if (optind == argc || argc > (optind + 2))
+			usage();
 
-	userhost = xstrdup(argv[optind]);
-	file2 = argv[optind+1];
+		userhost = xstrdup(argv[optind]);
+		file2 = argv[optind+1];
 
-	if ((cp = colon(userhost)) != NULL) {
-		*cp++ = '\0';
-		file1 = cp;
-	}
+		if ((cp = colon(userhost)) != NULL) {
+			*cp++ = '\0';
+			file1 = cp;
+		}
 
-	if ((host = strchr(userhost, '@')) == NULL)
-		host = userhost;
-	else {
-		*host++ = '\0';
-		if (!userhost[0]) {
-			fprintf(stderr, "Missing username\n");
+		if ((host = strchr(userhost, '@')) == NULL)
+			host = userhost;
+		else {
+			*host++ = '\0';
+			if (!userhost[0]) {
+				fprintf(stderr, "Missing username\n");
+				usage();
+			}
+			addargs(&args, "-l%s",userhost);
+		}
+
+		host = cleanhostname(host);
+		if (!*host) {
+			fprintf(stderr, "Missing hostname\n");
 			usage();
 		}
-		addargs(&args, "-l%s",userhost);
+
+		log_init(argv[0], ll, SYSLOG_FACILITY_USER, 1);
+		addargs(&args, "-oProtocol %d", sshver);
+
+		/* no subsystem if the server-spec contains a '/' */
+		if (sftp_server == NULL || strchr(sftp_server, '/') == NULL)
+			addargs(&args, "-s");
+
+		addargs(&args, "%s", host);
+		addargs(&args, "%s", (sftp_server != NULL ? 
+		    sftp_server : "sftp"));
+		args.list[0] = ssh_program;
+
+		fprintf(stderr, "Connecting to %s...\n", host);
+		connect_to_server(ssh_program, args.list, &in, &out, 
+		    &sshpid);
+	} else {
+		args.list = NULL;
+		addargs(&args, "sftp-server");
+
+		fprintf(stderr, "Attaching to %s...\n", sftp_direct);
+		connect_to_server(sftp_direct, args.list, &in, &out, 
+		    &sshpid);
 	}
 
-	host = cleanhostname(host);
-	if (!*host) {
-		fprintf(stderr, "Missing hostname\n");
-		usage();
-	}
-
-	log_init(argv[0], ll, SYSLOG_FACILITY_USER, 1);
-	addargs(&args, "-oProtocol %d", sshver);
-
-	/* no subsystem if the server-spec contains a '/' */
-	if (sftp_server == NULL || strchr(sftp_server, '/') == NULL)
-		addargs(&args, "-s");
-
-	addargs(&args, "%s", host);
-	addargs(&args, "%s", (sftp_server != NULL ? sftp_server : "sftp"));
-	args.list[0] = ssh_program;
-
-	fprintf(stderr, "Connecting to %s...\n", host);
-
-	connect_to_server(args.list, &in, &out, &sshpid);
-
 	interactive_loop(in, out, file1, file2);
 
 #if !defined(USE_PIPES)