shithub: riscv

Download patch

ref: 41013392a1077d5e0171b75cdf1864cd9492e6b6
parent: 2b5dfee06cc6a7b915d6b7fe7cfe2942a660cde0
author: aiju <devnull@localhost>
date: Sun May 27 07:06:07 EDT 2018

sshfs(4): replace the much maligned -r option

--- a/sys/man/4/sshfs
+++ b/sys/man/4/sshfs
@@ -82,8 +82,6 @@
 .B -b
 have the same function as they do with
 .IR mount .
-The default remote root is the user's home directory but can be changed with
-.BR -r .
 .PP
 If
 .B -s
@@ -92,11 +90,20 @@
 .IR srv (3)
 with service name
 .IR service .
-If the service file is mounted, the
-.IR attach (5)
-name can be used to specify which directory on the remote host will be mounted.
-If it is omitted or empty, the user's home directory is used.
-Relative paths are also relative to this directory.
+If the service file is mounted, the attach name (the third argument to
+.IR mount (1)) can be used to specify which directory on the remote host will be mounted.
+.PP
+By default, relative paths are assumed relative to the user's home directory.
+The
+.B -r
+option can be used to specify an alternative base for relative paths.
+The initial mount at
+.B -m
+also uses this directory.
+If an attach name starts with
+.BR ~ ,
+the user's home directory is substituted for
+.BR ~ .
 .PP
 Since the only supported version 3 of the SFTP protocol has no way to look up numeric user and group IDs,
 .I sshfs
--- a/sys/src/cmd/sshfs.c
+++ b/sys/src/cmd/sshfs.c
@@ -600,6 +600,7 @@
 	if(flags & SSH_FILEXFER_ATTR_PERMISSIONS){
 		if(p + 4 > rxpkt + rxlen) return -1;
 		if((GET4(p) & 0170000) != 0040000) qid->type = 0;
+		else qid->type = QTDIR;
 		p += 4;
 	}
 	if(flags & SSH_FILEXFER_ATTR_ACMODTIME){
@@ -722,21 +723,40 @@
 {
 	SFid *sf;
 
-	if(r->ifcall.aname != nil && *r->ifcall.aname != 0 && r->aux == nil){
+	if(r->aux == nil){
+		sf = emalloc9p(sizeof(SFid));
+		if(r->ifcall.aname != nil)
+			switch(*r->ifcall.aname){
+			case '~':
+				switch(r->ifcall.aname[1]){
+				case 0: sf->fn = estrdup9p("."); break;
+				case '/': sf->fn = estrdup9p(r->ifcall.aname + 2); break;
+				default:
+					free(sf);
+					respond(r, "invalid attach name");
+					return;
+				}
+				break;
+			case '/':
+				sf->fn = estrdup9p(r->ifcall.aname);
+				break;
+			case 0:
+				sf->fn = estrdup9p(root);
+				break;
+			default:
+				sf->fn = pathcat(root, r->ifcall.aname);
+			}
+		else
+			sf->fn = estrdup9p(root);
+		r->fid->aux = sf;
 		submitreq(r);
-		return;
+	}else{
+		sf = r->fid->aux;
+		sf->qid = (Qid){qidcalc(sf->fn), 0, QTDIR};
+		r->ofcall.qid = sf->qid;
+		r->fid->qid = sf->qid;
+		respond(r, nil);
 	}
-	sf = emalloc9p(sizeof(SFid));
-	if(r->ifcall.aname != nil && *r->ifcall.aname != 0)
-		sf->fn = estrdup9p(r->ifcall.aname);
-	else
-		sf->fn = estrdup9p(root);
-	root = ".";
-	sf->qid = (Qid){qidcalc(sf->fn), 0, QTDIR};
-	r->ofcall.qid = sf->qid;
-	r->fid->qid = sf->qid;
-	r->fid->aux = sf;
-	respond(r, nil);
 }
 
 void
@@ -783,7 +803,7 @@
 		sf = r->req->fid != nil ? r->req->fid->aux : nil;
 		switch(r->req->ifcall.type){
 		case Tattach:
-			sendpkt("bus", SSH_FXP_STAT, r->reqid, r->req->ifcall.aname, strlen(r->req->ifcall.aname));
+			sendpkt("bus", SSH_FXP_STAT, r->reqid, sf->fn, strlen(sf->fn));
 			break;
 		case Twalk:
 			sendpkt("bus", SSH_FXP_STAT, r->reqid, r->req->aux, strlen(r->req->aux));
@@ -1364,8 +1384,6 @@
 		sshfssrv.wstat = nil;
 		sshfssrv.remove = nil;
 	}
-	if(mtpt == nil)
-		root = ".";
 	
 	if(pflag){
 		rdfd = 0;