- djm@cvs.openbsd.org 2013/01/03 12:54:49
     [sftp-server.8 sftp-server.c]
     allow specification of an alternate start directory for sftp-server(8)
     "I like this" markus@
diff --git a/sftp-server.c b/sftp-server.c
index 9d01c7d..c885814 100644
--- a/sftp-server.c
+++ b/sftp-server.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sftp-server.c,v 1.94 2011/06/17 21:46:16 djm Exp $ */
+/* $OpenBSD: sftp-server.c,v 1.95 2013/01/03 12:54:49 djm Exp $ */
 /*
  * Copyright (c) 2000-2004 Markus Friedl.  All rights reserved.
  *
@@ -1402,7 +1402,7 @@
 	int in, out, max, ch, skipargs = 0, log_stderr = 0;
 	ssize_t len, olen, set_size;
 	SyslogFacility log_facility = SYSLOG_FACILITY_AUTH;
-	char *cp, buf[4*4096];
+	char *cp, *homedir = NULL, buf[4*4096];
 	long mask;
 
 	extern char *optarg;
@@ -1411,7 +1411,9 @@
 	__progname = ssh_get_progname(argv[0]);
 	log_init(__progname, log_level, log_facility, log_stderr);
 
-	while (!skipargs && (ch = getopt(argc, argv, "f:l:u:cehR")) != -1) {
+	pw = pwcopy(user_pw);
+
+	while (!skipargs && (ch = getopt(argc, argv, "d:f:l:u:cehR")) != -1) {
 		switch (ch) {
 		case 'R':
 			readonly = 1;
@@ -1436,6 +1438,12 @@
 			if (log_facility == SYSLOG_FACILITY_NOT_SET)
 				error("Invalid log facility \"%s\"", optarg);
 			break;
+		case 'd':
+			cp = tilde_expand_filename(optarg, user_pw->pw_uid);
+			homedir = percent_expand(cp, "d", user_pw->pw_dir,
+			    "u", user_pw->pw_name, (char *)NULL);
+			free(cp);
+			break;
 		case 'u':
 			errno = 0;
 			mask = strtol(optarg, &cp, 8);
@@ -1463,8 +1471,6 @@
 	} else
 		client_addr = xstrdup("UNKNOWN");
 
-	pw = pwcopy(user_pw);
-
 	logit("session opened for local user %s from [%s]",
 	    pw->pw_name, client_addr);
 
@@ -1489,6 +1495,13 @@
 	rset = (fd_set *)xmalloc(set_size);
 	wset = (fd_set *)xmalloc(set_size);
 
+	if (homedir != NULL) {
+		if (chdir(homedir) != 0) {
+			error("chdir to \"%s\" failed: %s", homedir,
+			    strerror(errno));
+		}
+	}
+
 	for (;;) {
 		memset(rset, 0, set_size);
 		memset(wset, 0, set_size);