hjfs: fix wstat

- rename to same name is ok
- only truncate when file size is different
- check for uid/gid *change*, not if it is specified or not
This commit is contained in:
cinap_lenrek 2015-06-15 01:57:54 +02:00
parent 5adf0606f1
commit 13ec55922f

View file

@ -688,6 +688,8 @@ chanwstat(Chan *ch, Dir *di)
if(willmodify(ch->fs, ch->loc, ch->flags & CHFNOLOCK) < 0) if(willmodify(ch->fs, ch->loc, ch->flags & CHFNOLOCK) < 0)
goto error; goto error;
if(*di->name){ if(*di->name){
FLoc f;
if(!namevalid(di->name) || ch->loc->next == nil) if(!namevalid(di->name) || ch->loc->next == nil)
goto inval; goto inval;
pb = getbuf(ch->fs->d, ch->loc->next->blk, TDENTRY, 0); pb = getbuf(ch->fs->d, ch->loc->next->blk, TDENTRY, 0);
@ -699,9 +701,13 @@ chanwstat(Chan *ch, Dir *di)
if((ch->flags & CHFNOPERM) == 0) if((ch->flags & CHFNOPERM) == 0)
if(!permcheck(ch->fs, d, ch->uid, OWRITE)) if(!permcheck(ch->fs, d, ch->uid, OWRITE))
goto perm; goto perm;
rc = findentry(ch->fs, ch->loc->next, pb, di->name, nil, ch->flags & CHFDUMP); rc = findentry(ch->fs, ch->loc->next, pb, di->name, &f, ch->flags & CHFDUMP);
if(rc > 0) if(rc > 0){
werrstr(Eexists); if(f.blk == ch->loc->blk && f.deind == ch->loc->deind)
rc = 0;
else
werrstr(Eexists);
}
if(rc != 0) if(rc != 0)
goto error; goto error;
} }
@ -727,17 +733,19 @@ chanwstat(Chan *ch, Dir *di)
goto perm; goto perm;
if(di->mode != ~0 && !owner) if(di->mode != ~0 && !owner)
goto perm; goto perm;
nuid = NOUID; nuid = d->uid;
ngid = NOUID; ngid = d->gid;
if(*di->uid != 0 && name2uid(ch->fs, di->uid, &nuid) < 0) if(*di->uid != 0 && name2uid(ch->fs, di->uid, &nuid) < 0)
goto inval; goto inval;
if(*di->gid != 0 && name2uid(ch->fs, di->gid, &ngid) < 0) if(*di->gid != 0 && name2uid(ch->fs, di->gid, &ngid) < 0)
goto inval; goto inval;
if(nuid != NOUID && (ch->fs->flags & FSCHOWN) == 0) if(nuid != d->uid && (ch->fs->flags & FSCHOWN) == 0)
goto inval;
if((nuid != NOUID || ngid != NOUID) && !owner)
goto perm; goto perm;
if(di->length != ~0 && !isdir){ if((nuid != d->uid || ngid != d->gid) && !owner)
goto perm;
d->uid = nuid;
d->gid = ngid;
if(di->length != ~0 && di->length != d->size && !isdir){
trunc(ch->fs, ch->loc, b, di->length); trunc(ch->fs, ch->loc, b, di->length);
modified(ch, d); modified(ch, d);
} }
@ -751,10 +759,6 @@ chanwstat(Chan *ch, Dir *di)
memset(d->name, 0, NAMELEN); memset(d->name, 0, NAMELEN);
strcpy(d->name, di->name); strcpy(d->name, di->name);
} }
if(nuid != NOUID)
d->uid = nuid;
if(ngid != NOUID)
d->gid = ngid;
b->op |= BDELWRI; b->op |= BDELWRI;
if(pb != nil) if(pb != nil)
putbuf(pb); putbuf(pb);