hgfs: allow "tip" as revision, do perm checking

This commit is contained in:
cinap_lenrek 2011-06-27 23:01:19 +00:00
parent 5f7342a461
commit e715b511e0

View file

@ -147,10 +147,10 @@ fsmkqid(Qid *q, int level, void *aux)
break; break;
case Qtree: case Qtree:
nd = aux; nd = aux;
if(nd->hash){ if(nd->down){
q->type = 0;
} else {
q->type = QTDIR; q->type = QTDIR;
} else {
q->type = 0;
} }
q->path = nd->path; q->path = nd->path;
q->vers = 0; q->vers = 0;
@ -300,6 +300,8 @@ findrev(Revlog *rl, char *name)
int n, i, rev; int n, i, rev;
char *s; char *s;
if(strcmp(name, "tip") == 0)
return rl->nmap-1;
rev = strtol(name, &s, 10); rev = strtol(name, &s, 10);
if(s > name && (*s == 0 || ispunct(*s))) if(s > name && (*s == 0 || ispunct(*s)))
return rev; return rev;
@ -452,7 +454,18 @@ fsdestroyfid(Fid *fid)
static void static void
fsopen(Req *r) fsopen(Req *r)
{ {
Revfile *rf;
rf = r->fid->aux;
switch(r->ifcall.mode & 3){
case OEXEC:
if(rf->node == nil || rf->node->mode != 'x')
break;
case OREAD:
respond(r, nil); respond(r, nil);
return;
}
respond(r, "permission denied");
} }
static int static int
@ -495,17 +508,16 @@ static void
fsread(Req *r) fsread(Req *r)
{ {
Revfile *rf; Revfile *rf;
char buf[MAXPATH];
Revlog rl;
char *s;
int i, n;
rf = r->fid->aux; rf = r->fid->aux;
if(r->fid->qid.type == QTDIR){
switch(rf->level){ switch(rf->level){
default:
respond(r, "bug in fsread");
return;
case Qroot: case Qroot:
revlogupdate(&changelog); revlogupdate(&changelog);
revlogupdate(&manifest); revlogupdate(&manifest);
dirread9p(r, rootgen, nil); dirread9p(r, rootgen, nil);
respond(r, nil); respond(r, nil);
return; return;
@ -513,34 +525,11 @@ fsread(Req *r)
dirread9p(r, revgen, rf->info); dirread9p(r, revgen, rf->info);
respond(r, nil); respond(r, nil);
return; return;
case Qtree:
case Qfiles:
case Qchanges:
dirread9p(r, treegen, rf->node->down);
respond(r, nil);
return;
}
} else {
char buf[MAXPATH];
Revlog rl;
char *s;
int i, n;
switch(rf->level){
default:
respond(r, "bug in fsread");
return;
case Qlog:
if(rf->fd >= 0)
break;
if((rf->fd = revlogopentemp(&changelog, hashrev(&changelog, rf->info->chash))) < 0){
responderror(r);
return;
}
break;
case Qrev1: case Qrev1:
case Qrev2: case Qrev2:
s = nil; s = nil;
if(rf->buf)
goto Strgen;
if((i = hashrev(&changelog, rf->info->chash)) >= 0){ if((i = hashrev(&changelog, rf->info->chash)) >= 0){
if(rf->level == Qrev1) if(rf->level == Qrev1)
i = changelog.map[i].p1rev; i = changelog.map[i].p1rev;
@ -550,6 +539,14 @@ fsread(Req *r)
snprint(s = buf, sizeof(buf), "%d.%H", i, changelog.map[i].hash); snprint(s = buf, sizeof(buf), "%d.%H", i, changelog.map[i].hash);
} }
goto Strgen; goto Strgen;
case Qlog:
if(rf->fd >= 0)
goto Fdgen;
if((rf->fd = revlogopentemp(&changelog, hashrev(&changelog, rf->info->chash))) < 0){
responderror(r);
return;
}
goto Fdgen;
case Qwho: case Qwho:
s = rf->info->who; s = rf->info->who;
goto Strgen; goto Strgen;
@ -562,8 +559,15 @@ fsread(Req *r)
respond(r, nil); respond(r, nil);
return; return;
case Qtree: case Qtree:
if(rf->node->down){
case Qfiles:
case Qchanges:
dirread9p(r, treegen, rf->node->down);
respond(r, nil);
return;
}
if(rf->fd >= 0) if(rf->fd >= 0)
break; goto Fdgen;
nodepath(seprint(buf, buf+sizeof(buf), ".hg/store/data"), buf+sizeof(buf), rf->node); nodepath(seprint(buf, buf+sizeof(buf), ".hg/store/data"), buf+sizeof(buf), rf->node);
if(revlogopen(&rl, buf, OREAD) < 0){ if(revlogopen(&rl, buf, OREAD) < 0){
responderror(r); responderror(r);
@ -575,15 +579,16 @@ fsread(Req *r)
return; return;
} }
revlogclose(&rl); revlogclose(&rl);
break; Fdgen:
}
if((n = pread(rf->fd, r->ofcall.data, r->ifcall.count, r->ifcall.offset)) < 0){ if((n = pread(rf->fd, r->ofcall.data, r->ifcall.count, r->ifcall.offset)) < 0){
responderror(r); responderror(r);
return; return;
} }
r->ofcall.count = n; r->ofcall.count = n;
respond(r, nil); respond(r, nil);
return;
} }
respond(r, "bug in fsread");
} }
Srv fs = Srv fs =