summaryrefslogtreecommitdiff
path: root/sys/src/cmd/sshfs.c
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2017-04-30 18:28:06 +0200
committercinap_lenrek <cinap_lenrek@felloff.net>2017-04-30 18:28:06 +0200
commitc00c60d327168c25e56077c8310cf2380833e9be (patch)
treed635dd7da7637bc7ecfa700387f9c3416cf1bab0 /sys/src/cmd/sshfs.c
parent607e651c0636bd2a73d7888ef1cea863f0bd5c53 (diff)
sshfs: fix -r / retulting in "//foo" paths, memory leaks, use estrdup9p()
just use cleanname() to implement pathcat(), which handles double slashes and ".." elements already. have to free the partial dir structue on error in parsedir(). use estrdup9p() instead of strdup().
Diffstat (limited to 'sys/src/cmd/sshfs.c')
-rw-r--r--sys/src/cmd/sshfs.c72
1 files changed, 31 insertions, 41 deletions
diff --git a/sys/src/cmd/sshfs.c b/sys/src/cmd/sshfs.c
index d8687900f..a44b0dcaf 100644
--- a/sys/src/cmd/sshfs.c
+++ b/sys/src/cmd/sshfs.c
@@ -172,7 +172,7 @@ idlookup(IDEnt **tab, int id)
for(p = tab[(ulong)id % HASH]; p != nil; p = p->next)
if(p->id == id)
- return strdup(p->name);
+ return estrdup9p(p->name);
return smprint("%d", id);
}
@@ -368,18 +368,21 @@ recvpkt(void)
}
void
+freedir1(Dir *d)
+{
+ free(d->name);
+ free(d->uid);
+ free(d->gid);
+ free(d->muid);
+}
+
+void
freedir(SFid *s)
{
int i;
- Dir *d;
- for(i = 0; i < s->ndirent; i++){
- d = &s->dirent[i];
- free(d->name);
- free(d->uid);
- free(d->gid);
- free(d->muid);
- }
+ for(i = 0; i < s->ndirent; i++)
+ freedir1(&s->dirent[i]);
free(s->dirent);
s->dirent = nil;
s->ndirent = 0;
@@ -436,23 +439,13 @@ submitreq(Req *r)
char *
pathcat(char *p, char *c)
{
- if(strcmp(p, ".") == 0)
- return strdup(c);
- return smprint("%s/%s", p, c);
+ return cleanname(smprint("%s/%s", p, c));
}
char *
parentdir(char *p)
{
- char *q, *r;
-
- if(strcmp(p, ".") == 0) return strdup(".");
- if(strcmp(p, "/") == 0) return strdup("/");
- q = strdup(p);
- r = strrchr(q, '/');
- if(r != nil) *r = 0;
- else strcpy(q, ".");
- return q;
+ return pathcat(p, "..");
}
char *
@@ -461,8 +454,8 @@ finalelem(char *p)
char *q;
q = strrchr(p, '/');
- if(q == nil) return strdup(p);
- return strdup(q+1);
+ if(q == nil) return estrdup9p(p);
+ return estrdup9p(q+1);
}
u64int
@@ -524,10 +517,10 @@ attrib2dir(uchar *p0, uchar *ep, Dir *d)
d->uid = idlookup(uidtab, uid);
d->gid = idlookup(gidtab, gid);
}else{
- d->uid = strdup("sshfs");
- d->gid = strdup("sshfs");
+ d->uid = estrdup9p("sshfs");
+ d->gid = estrdup9p("sshfs");
}
- d->muid = strdup(d->uid);
+ d->muid = estrdup9p(d->uid);
if((flags & SSH_FILEXFER_ATTR_PERMISSIONS) != 0){
rc = unpack(p, ep - p, "u", &perm); if(rc < 0) return -1; p += rc;
d->mode = perm & 0777;
@@ -632,17 +625,16 @@ parsedir(SFid *sf)
p = rxpkt + 9;
ep = rxpkt + rxlen;
for(i = 0; i < c; i++){
- rc = unpack(p, ep - p, "ss", &fn, &fns, &ln, &lns); if(rc < 0) goto err; p += rc;
memset(d, 0, sizeof(Dir));
+ rc = unpack(p, ep - p, "ss", &fn, &fns, &ln, &lns); if(rc < 0) goto err; p += rc;
rc = attrib2dir(p, ep, d); if(rc < 0) goto err; p += rc;
if(fn[0] == '.' && (fns == 1 || fns == 2 && fn[1] == '.')){
- free(d->uid);
- free(d->gid);
- free(d->muid);
+ freedir1(d);
continue;
}
d->name = emalloc9p(fns + 1);
memcpy(d->name, fn, fns);
+ d->name[fns] = 0;
s = pathcat(sf->fn, d->name);
d->qid.path = qidcalc(s);
free(s);
@@ -652,6 +644,7 @@ parsedir(SFid *sf)
wunlock(sf);
return 0;
err:
+ freedir1(d);
wunlock(sf);
return -1;
}
@@ -731,9 +724,9 @@ sshfsattach(Req *r)
}
sf = emalloc9p(sizeof(SFid));
if(r->ifcall.aname != nil && *r->ifcall.aname != 0)
- sf->fn = strdup(r->ifcall.aname);
+ sf->fn = estrdup9p(r->ifcall.aname);
else
- sf->fn = strdup(root);
+ sf->fn = estrdup9p(root);
root = ".";
sf->qid = (Qid){qidcalc(sf->fn), 0, QTDIR};
r->ofcall.qid = sf->qid;
@@ -855,8 +848,8 @@ sendproc(void *)
}else if(r->req->aux == (void*)-2){
sendpkt("bus", SSH_FXP_OPENDIR, r->reqid, sf->fn, strlen(sf->fn));
}else{
- sendpkt("bus", SSH_FXP_READDIR, r->reqid, sf->hand, sf->handn);
sf->dirreads++;
+ sendpkt("bus", SSH_FXP_READDIR, r->reqid, sf->hand, sf->handn);
}
wunlock(sf);
}else{
@@ -892,9 +885,9 @@ sendproc(void *)
rlock(sf);
s = parentdir(sf->fn);
t = pathcat(s, r->req->d.name);
- sendpkt("buss", SSH_FXP_RENAME, r->reqid, sf->fn, strlen(sf->fn), t, strlen(t));
free(s);
r->req->aux = t;
+ sendpkt("buss", SSH_FXP_RENAME, r->reqid, sf->fn, strlen(sf->fn), t, strlen(t));
runlock(sf);
break;
}
@@ -1137,7 +1130,7 @@ sshfswalk(Req *r)
r->newfid->qid = r->fid->qid;
s = r->fid->aux;
t = emalloc9p(sizeof(SFid));
- t->fn = strdup(s->fn);
+ t->fn = estrdup9p(s->fn);
t->qid = s->qid;
r->newfid->aux = t;
}else
@@ -1146,12 +1139,9 @@ sshfswalk(Req *r)
respond(r, nil);
return;
}
- p = strdup(t->fn);
+ p = estrdup9p(t->fn);
for(i = 0; i < r->ifcall.nwname; i++){
- if(strcmp(r->ifcall.wname[i], "..") == 0)
- q = parentdir(p);
- else
- q = pathcat(p, r->ifcall.wname[i]);
+ q = pathcat(p, r->ifcall.wname[i]);
free(p);
p = q;
r->ofcall.wqid[i] = (Qid){qidcalc(p), 0, QTDIR};
@@ -1271,7 +1261,7 @@ passwdparse(IDEnt **tab, char *s)
if(p == nil) break;
p++;
e = emalloc9p(sizeof(IDEnt));
- e->name = strdup(n);
+ e->name = estrdup9p(n);
e->id = id;
b = &tab[((ulong)e->id) % HASH];
e->next = *b;