13e12c5d1SDavid du Colombier #include <u.h> 23e12c5d1SDavid du Colombier #include <libc.h> 3*219b2ee8SDavid du Colombier #include <auth.h> 43e12c5d1SDavid du Colombier #include <fcall.h> 53e12c5d1SDavid du Colombier #include "iotrack.h" 63e12c5d1SDavid du Colombier #include "dat.h" 73e12c5d1SDavid du Colombier #include "fns.h" 83e12c5d1SDavid du Colombier 93e12c5d1SDavid du Colombier extern Fcall thdr; 103e12c5d1SDavid du Colombier extern Fcall rhdr; 113e12c5d1SDavid du Colombier extern char data[sizeof(Fcall)+MAXFDATA]; 123e12c5d1SDavid du Colombier extern char fdata[MAXFDATA]; 133e12c5d1SDavid du Colombier extern int errno; 143e12c5d1SDavid du Colombier 153e12c5d1SDavid du Colombier void 163e12c5d1SDavid du Colombier rnop(void) 173e12c5d1SDavid du Colombier { 183e12c5d1SDavid du Colombier chat("nop..."); 193e12c5d1SDavid du Colombier } 203e12c5d1SDavid du Colombier void 213e12c5d1SDavid du Colombier rsession(void) 223e12c5d1SDavid du Colombier { 23*219b2ee8SDavid du Colombier memset(thdr.authid, 0, sizeof(thdr.authid)); 24*219b2ee8SDavid du Colombier memset(thdr.authdom, 0, sizeof(thdr.authdom)); 25*219b2ee8SDavid du Colombier memset(thdr.chal, 0, sizeof(thdr.chal)); 263e12c5d1SDavid du Colombier chat("session..."); 273e12c5d1SDavid du Colombier } 283e12c5d1SDavid du Colombier void 293e12c5d1SDavid du Colombier rflush(void) 303e12c5d1SDavid du Colombier { 313e12c5d1SDavid du Colombier chat("flush..."); 323e12c5d1SDavid du Colombier } 333e12c5d1SDavid du Colombier void 343e12c5d1SDavid du Colombier rattach(void) 353e12c5d1SDavid du Colombier { 36*219b2ee8SDavid du Colombier Xfs *xf; 37*219b2ee8SDavid du Colombier Xfile *root; 383e12c5d1SDavid du Colombier Dosptr *dp; 393e12c5d1SDavid du Colombier 403e12c5d1SDavid du Colombier chat("attach(fid=%d,uname=\"%s\",aname=\"%s\",auth=\"%s\")...", 413e12c5d1SDavid du Colombier thdr.fid, thdr.uname, thdr.aname, thdr.auth); 423e12c5d1SDavid du Colombier 433e12c5d1SDavid du Colombier root = xfile(thdr.fid, Clean); 443e12c5d1SDavid du Colombier if(!root){ 453e12c5d1SDavid du Colombier errno = Enomem; 463e12c5d1SDavid du Colombier goto error; 473e12c5d1SDavid du Colombier } 483e12c5d1SDavid du Colombier root->xf = xf = getxfs(thdr.aname); 493e12c5d1SDavid du Colombier if(!xf) 503e12c5d1SDavid du Colombier goto error; 513e12c5d1SDavid du Colombier if(xf->fmt==0 && dosfs(xf)<0){ 523e12c5d1SDavid du Colombier errno = Eformat; 533e12c5d1SDavid du Colombier goto error; 543e12c5d1SDavid du Colombier } 553e12c5d1SDavid du Colombier root->qid.path = CHDIR; 563e12c5d1SDavid du Colombier root->qid.vers = 0; 573e12c5d1SDavid du Colombier root->xf->rootqid = root->qid; 583e12c5d1SDavid du Colombier dp = malloc(sizeof(Dosptr)); 593e12c5d1SDavid du Colombier memset(dp, 0, sizeof(Dosptr)); 603e12c5d1SDavid du Colombier root->ptr = dp; 613e12c5d1SDavid du Colombier rhdr.qid = root->qid; 623e12c5d1SDavid du Colombier return; 633e12c5d1SDavid du Colombier error: 643e12c5d1SDavid du Colombier if(root) 653e12c5d1SDavid du Colombier xfile(thdr.fid, Clunk); 663e12c5d1SDavid du Colombier return; 673e12c5d1SDavid du Colombier } 683e12c5d1SDavid du Colombier void 693e12c5d1SDavid du Colombier rclone(void) 703e12c5d1SDavid du Colombier { 713e12c5d1SDavid du Colombier Xfile *of = xfile(thdr.fid, Asis); 723e12c5d1SDavid du Colombier Xfile *nf = xfile(thdr.newfid, Clean); 733e12c5d1SDavid du Colombier 743e12c5d1SDavid du Colombier chat("clone(fid=%d,newfid=%d)...", thdr.fid, thdr.newfid); 753e12c5d1SDavid du Colombier if(!of) 763e12c5d1SDavid du Colombier errno = Eio; 773e12c5d1SDavid du Colombier else if(!nf) 783e12c5d1SDavid du Colombier errno = Enomem; 793e12c5d1SDavid du Colombier else{ 803e12c5d1SDavid du Colombier Xfile *next = nf->next; 813e12c5d1SDavid du Colombier Dosptr *dp = malloc(sizeof(Dosptr)); 823e12c5d1SDavid du Colombier *nf = *of; 833e12c5d1SDavid du Colombier nf->next = next; 843e12c5d1SDavid du Colombier nf->fid = thdr.newfid; 853e12c5d1SDavid du Colombier nf->ptr = dp; 863e12c5d1SDavid du Colombier refxfs(nf->xf, 1); 873e12c5d1SDavid du Colombier memmove(dp, of->ptr, sizeof(Dosptr)); 883e12c5d1SDavid du Colombier dp->p = 0; 893e12c5d1SDavid du Colombier dp->d = 0; 903e12c5d1SDavid du Colombier } 913e12c5d1SDavid du Colombier } 923e12c5d1SDavid du Colombier void 933e12c5d1SDavid du Colombier rwalk(void) 943e12c5d1SDavid du Colombier { 953e12c5d1SDavid du Colombier Xfile *f=xfile(thdr.fid, Asis); 963e12c5d1SDavid du Colombier Dosptr dp[1]; 973e12c5d1SDavid du Colombier int r; 983e12c5d1SDavid du Colombier 993e12c5d1SDavid du Colombier chat("walk(fid=%d,name=\"%s\")...", thdr.fid, thdr.name); 1003e12c5d1SDavid du Colombier if(!f){ 1013e12c5d1SDavid du Colombier chat("no xfile..."); 1023e12c5d1SDavid du Colombier goto error; 1033e12c5d1SDavid du Colombier } 1043e12c5d1SDavid du Colombier if(!(f->qid.path & CHDIR)){ 1053e12c5d1SDavid du Colombier chat("qid.path=0x%x...", f->qid.path); 1063e12c5d1SDavid du Colombier goto error; 1073e12c5d1SDavid du Colombier } 1083e12c5d1SDavid du Colombier if(strcmp(thdr.name, ".")==0){ 1093e12c5d1SDavid du Colombier rhdr.qid = f->qid; 1103e12c5d1SDavid du Colombier return; 1113e12c5d1SDavid du Colombier }else if(strcmp(thdr.name, "..")==0){ 1123e12c5d1SDavid du Colombier if(f->qid.path==f->xf->rootqid.path){ 1133e12c5d1SDavid du Colombier chat("walkup from root..."); 114*219b2ee8SDavid du Colombier rhdr.qid = f->qid; 115*219b2ee8SDavid du Colombier return; 1163e12c5d1SDavid du Colombier } 1173e12c5d1SDavid du Colombier r = walkup(f, dp); 1183e12c5d1SDavid du Colombier if(r < 0) 1193e12c5d1SDavid du Colombier goto error; 1203e12c5d1SDavid du Colombier memmove(f->ptr, dp, sizeof(Dosptr)); 1213e12c5d1SDavid du Colombier if(dp->addr == 0) 1223e12c5d1SDavid du Colombier f->qid.path = f->xf->rootqid.path; 1233e12c5d1SDavid du Colombier else{ 1243e12c5d1SDavid du Colombier Iosect *p; Dosdir *xd; 1253e12c5d1SDavid du Colombier p = getsect(f->xf, dp->addr); 1263e12c5d1SDavid du Colombier if(p == 0) 1273e12c5d1SDavid du Colombier goto error; 1283e12c5d1SDavid du Colombier xd = (Dosdir *)&p->iobuf[dp->offset]; 1293e12c5d1SDavid du Colombier f->qid.path = CHDIR | GSHORT(xd->start); 1303e12c5d1SDavid du Colombier putsect(p); 1313e12c5d1SDavid du Colombier } 1323e12c5d1SDavid du Colombier }else{ 1333e12c5d1SDavid du Colombier if(getfile(f) < 0) 1343e12c5d1SDavid du Colombier goto error; 1353e12c5d1SDavid du Colombier r = searchdir(f, thdr.name, dp, 0); 1363e12c5d1SDavid du Colombier putfile(f); 1373e12c5d1SDavid du Colombier if(r < 0) 1383e12c5d1SDavid du Colombier goto error; 1393e12c5d1SDavid du Colombier memmove(f->ptr, dp, sizeof(Dosptr)); 1403e12c5d1SDavid du Colombier f->qid.path = GSHORT(dp->d->start); 1413e12c5d1SDavid du Colombier if(f->qid.path == 0) 1423e12c5d1SDavid du Colombier f->qid.path = f->xf->rootqid.path; 1433e12c5d1SDavid du Colombier else if(dp->d->attr & DDIR) 1443e12c5d1SDavid du Colombier f->qid.path |= CHDIR; 1453e12c5d1SDavid du Colombier putfile(f); 1463e12c5d1SDavid du Colombier } 1473e12c5d1SDavid du Colombier rhdr.qid = f->qid; 1483e12c5d1SDavid du Colombier return; 1493e12c5d1SDavid du Colombier error: 1503e12c5d1SDavid du Colombier errno = Enonexist; 1513e12c5d1SDavid du Colombier return; 1523e12c5d1SDavid du Colombier } 1533e12c5d1SDavid du Colombier void 1543e12c5d1SDavid du Colombier ropen(void) 1553e12c5d1SDavid du Colombier { 1563e12c5d1SDavid du Colombier Xfile *f; 1573e12c5d1SDavid du Colombier Dosptr *dp; 1583e12c5d1SDavid du Colombier int attr, omode=0; 1593e12c5d1SDavid du Colombier 1603e12c5d1SDavid du Colombier chat("open(fid=%d,mode=%d)...", thdr.fid, thdr.mode); 1613e12c5d1SDavid du Colombier f = xfile(thdr.fid, Asis); 1623e12c5d1SDavid du Colombier if(!f || (f->flags&Omodes)){ 1633e12c5d1SDavid du Colombier errno = Eio; 1643e12c5d1SDavid du Colombier return; 1653e12c5d1SDavid du Colombier } 1663e12c5d1SDavid du Colombier dp = f->ptr; 1673e12c5d1SDavid du Colombier if(dp->paddr && (thdr.mode & ORCLOSE)){ 1683e12c5d1SDavid du Colombier /* 1693e12c5d1SDavid du Colombier * check on parent directory of file to be deleted 1703e12c5d1SDavid du Colombier */ 1713e12c5d1SDavid du Colombier Iosect *p = getsect(f->xf, dp->paddr); 1723e12c5d1SDavid du Colombier if(p == 0){ 1733e12c5d1SDavid du Colombier errno = Eio; 1743e12c5d1SDavid du Colombier return; 1753e12c5d1SDavid du Colombier } 1763e12c5d1SDavid du Colombier attr = ((Dosdir *)&p->iobuf[dp->poffset])->attr; 1773e12c5d1SDavid du Colombier putsect(p); 1783e12c5d1SDavid du Colombier if(attr & DRONLY){ 1793e12c5d1SDavid du Colombier errno = Eperm; 1803e12c5d1SDavid du Colombier return; 1813e12c5d1SDavid du Colombier } 1823e12c5d1SDavid du Colombier omode |= Orclose; 1833e12c5d1SDavid du Colombier }else if(thdr.mode & ORCLOSE) 1843e12c5d1SDavid du Colombier omode |= Orclose; 1853e12c5d1SDavid du Colombier if(getfile(f) < 0){ 1863e12c5d1SDavid du Colombier errno = Enonexist; 1873e12c5d1SDavid du Colombier return; 1883e12c5d1SDavid du Colombier } 1893e12c5d1SDavid du Colombier if(dp->addr) 1903e12c5d1SDavid du Colombier attr = dp->d->attr; 1913e12c5d1SDavid du Colombier else 1923e12c5d1SDavid du Colombier attr = DDIR; 1933e12c5d1SDavid du Colombier switch(thdr.mode & 7){ 1943e12c5d1SDavid du Colombier case OREAD: 1953e12c5d1SDavid du Colombier case OEXEC: 1963e12c5d1SDavid du Colombier omode |= Oread; 1973e12c5d1SDavid du Colombier break; 1983e12c5d1SDavid du Colombier case ORDWR: 1993e12c5d1SDavid du Colombier omode |= Oread; 2003e12c5d1SDavid du Colombier /* fall through */ 2013e12c5d1SDavid du Colombier case OWRITE: 2023e12c5d1SDavid du Colombier omode |= Owrite; 2033e12c5d1SDavid du Colombier if(attr & DRONLY){ 2043e12c5d1SDavid du Colombier errno = Eperm; 2053e12c5d1SDavid du Colombier goto out; 2063e12c5d1SDavid du Colombier } 2073e12c5d1SDavid du Colombier break; 2083e12c5d1SDavid du Colombier default: 2093e12c5d1SDavid du Colombier errno = Eio; 2103e12c5d1SDavid du Colombier goto out; 2113e12c5d1SDavid du Colombier } 2123e12c5d1SDavid du Colombier if(thdr.mode & OTRUNC){ 2133e12c5d1SDavid du Colombier if(attr & DDIR || attr & DRONLY){ 2143e12c5d1SDavid du Colombier errno = Eperm; 2153e12c5d1SDavid du Colombier goto out; 2163e12c5d1SDavid du Colombier } 2173e12c5d1SDavid du Colombier if(truncfile(f, 0) < 0){ 2183e12c5d1SDavid du Colombier errno = Eio; 2193e12c5d1SDavid du Colombier goto out; 2203e12c5d1SDavid du Colombier } 2213e12c5d1SDavid du Colombier } 2223e12c5d1SDavid du Colombier f->flags |= omode; 2233e12c5d1SDavid du Colombier chat("f->qid=0x%8.8lux...", f->qid.path); 2243e12c5d1SDavid du Colombier rhdr.qid = f->qid; 2253e12c5d1SDavid du Colombier out: 2263e12c5d1SDavid du Colombier putfile(f); 2273e12c5d1SDavid du Colombier } 2283e12c5d1SDavid du Colombier void 2293e12c5d1SDavid du Colombier rcreate(void) 2303e12c5d1SDavid du Colombier { 2313e12c5d1SDavid du Colombier Dosbpb *bp; 2323e12c5d1SDavid du Colombier Xfile *f; 2333e12c5d1SDavid du Colombier Dosptr *pdp, *ndp; 2343e12c5d1SDavid du Colombier Iosect *xp; 2353e12c5d1SDavid du Colombier Dosdir *pd, *nd, *xd; 2363e12c5d1SDavid du Colombier int attr, omode=0, start; 2373e12c5d1SDavid du Colombier 2383e12c5d1SDavid du Colombier chat("create(fid=%d,name=\"%s\",perm=%uo,mode=%d)...", 2393e12c5d1SDavid du Colombier thdr.fid, thdr.name, thdr.perm, thdr.mode); 2403e12c5d1SDavid du Colombier f = xfile(thdr.fid, Asis); 2413e12c5d1SDavid du Colombier if(!f || (f->flags&Omodes) || getfile(f)<0){ 2423e12c5d1SDavid du Colombier errno = Eio; 2433e12c5d1SDavid du Colombier return; 2443e12c5d1SDavid du Colombier } 2453e12c5d1SDavid du Colombier ndp = malloc(sizeof(Dosptr)); 2463e12c5d1SDavid du Colombier pdp = f->ptr; 2473e12c5d1SDavid du Colombier pd = pdp->addr ? pdp->d : 0; 2483e12c5d1SDavid du Colombier attr = pd ? pd->attr : DDIR; 2493e12c5d1SDavid du Colombier if(!(attr & DDIR) || (attr & DRONLY)){ 2503e12c5d1SDavid du Colombier badperm: 2513e12c5d1SDavid du Colombier if(ndp) 2523e12c5d1SDavid du Colombier free(ndp); 2533e12c5d1SDavid du Colombier putfile(f); 2543e12c5d1SDavid du Colombier errno = Eperm; 2553e12c5d1SDavid du Colombier return; 2563e12c5d1SDavid du Colombier } 2573e12c5d1SDavid du Colombier if(thdr.mode & ORCLOSE) 2583e12c5d1SDavid du Colombier omode |= Orclose; 2593e12c5d1SDavid du Colombier switch(thdr.mode & 7){ 2603e12c5d1SDavid du Colombier case OREAD: 2613e12c5d1SDavid du Colombier case OEXEC: 2623e12c5d1SDavid du Colombier omode |= Oread; 2633e12c5d1SDavid du Colombier break; 2643e12c5d1SDavid du Colombier case ORDWR: 2653e12c5d1SDavid du Colombier omode |= Oread; 2663e12c5d1SDavid du Colombier /* fall through */ 2673e12c5d1SDavid du Colombier case OWRITE: 2683e12c5d1SDavid du Colombier omode |= Owrite; 2693e12c5d1SDavid du Colombier if(thdr.perm & CHDIR) 2703e12c5d1SDavid du Colombier goto badperm; 2713e12c5d1SDavid du Colombier break; 2723e12c5d1SDavid du Colombier default: 2733e12c5d1SDavid du Colombier goto badperm; 2743e12c5d1SDavid du Colombier } 2753e12c5d1SDavid du Colombier if(strcmp(thdr.name, ".") == 0 || strcmp(thdr.name, "..") == 0) 2763e12c5d1SDavid du Colombier goto badperm; 2773e12c5d1SDavid du Colombier if(searchdir(f, thdr.name, ndp, 1) < 0) 2783e12c5d1SDavid du Colombier goto badperm; 2793e12c5d1SDavid du Colombier bp = f->xf->ptr; 2803e12c5d1SDavid du Colombier lock(bp); 2813e12c5d1SDavid du Colombier start = falloc(f->xf); 2823e12c5d1SDavid du Colombier unlock(bp); 2833e12c5d1SDavid du Colombier if(start <= 0){ 2843e12c5d1SDavid du Colombier if(ndp) 2853e12c5d1SDavid du Colombier free(ndp); 2863e12c5d1SDavid du Colombier putfile(f); 2873e12c5d1SDavid du Colombier errno = Eio; 2883e12c5d1SDavid du Colombier return; 2893e12c5d1SDavid du Colombier } 2903e12c5d1SDavid du Colombier /* 2913e12c5d1SDavid du Colombier * now we're committed 2923e12c5d1SDavid du Colombier */ 2933e12c5d1SDavid du Colombier if(pd){ 294*219b2ee8SDavid du Colombier puttime(pd, 0); 2953e12c5d1SDavid du Colombier pdp->p->flags |= BMOD; 2963e12c5d1SDavid du Colombier } 2973e12c5d1SDavid du Colombier f->ptr = ndp; 2983e12c5d1SDavid du Colombier f->qid.path = start; 2993e12c5d1SDavid du Colombier ndp->p = getsect(f->xf, ndp->addr); 3003e12c5d1SDavid du Colombier if(ndp->p == 0) 3013e12c5d1SDavid du Colombier goto badio; 3023e12c5d1SDavid du Colombier ndp->d = (Dosdir *)&ndp->p->iobuf[ndp->offset]; 3033e12c5d1SDavid du Colombier nd = ndp->d; 3043e12c5d1SDavid du Colombier memset(nd, 0, sizeof(Dosdir)); 3053e12c5d1SDavid du Colombier putname(thdr.name, nd); 3063e12c5d1SDavid du Colombier if((thdr.perm & 0222) == 0) 3073e12c5d1SDavid du Colombier nd->attr |= DRONLY; 308*219b2ee8SDavid du Colombier puttime(nd, 0); 3093e12c5d1SDavid du Colombier nd->start[0] = start; 3103e12c5d1SDavid du Colombier nd->start[1] = start>>8; 3113e12c5d1SDavid du Colombier if(thdr.perm & CHDIR){ 3123e12c5d1SDavid du Colombier nd->attr |= DDIR; 3133e12c5d1SDavid du Colombier f->qid.path |= CHDIR; 3143e12c5d1SDavid du Colombier xp = getsect(f->xf, bp->dataaddr+(start-2)*bp->clustsize); 3153e12c5d1SDavid du Colombier if(xp == 0) 3163e12c5d1SDavid du Colombier goto badio; 3173e12c5d1SDavid du Colombier xd = (Dosdir *)&xp->iobuf[0]; 3183e12c5d1SDavid du Colombier memmove(xd, nd, sizeof(Dosdir)); 3193e12c5d1SDavid du Colombier memset(xd->name, ' ', sizeof xd->name+sizeof xd->ext); 3203e12c5d1SDavid du Colombier xd->name[0] = '.'; 3213e12c5d1SDavid du Colombier xd = (Dosdir *)&xp->iobuf[sizeof(Dosdir)]; 3223e12c5d1SDavid du Colombier if(pd) 3233e12c5d1SDavid du Colombier memmove(xd, pd, sizeof(Dosdir)); 3243e12c5d1SDavid du Colombier else{ 3253e12c5d1SDavid du Colombier memset(xd, 0, sizeof(Dosdir)); 326*219b2ee8SDavid du Colombier puttime(xd, 0); 3273e12c5d1SDavid du Colombier xd->attr = DDIR; 3283e12c5d1SDavid du Colombier } 3293e12c5d1SDavid du Colombier memset(xd->name, ' ', sizeof xd->name+sizeof xd->ext); 3303e12c5d1SDavid du Colombier xd->name[0] = '.'; 3313e12c5d1SDavid du Colombier xd->name[1] = '.'; 3323e12c5d1SDavid du Colombier xp->flags |= BMOD; 3333e12c5d1SDavid du Colombier putsect(xp); 3343e12c5d1SDavid du Colombier } 3353e12c5d1SDavid du Colombier ndp->p->flags |= BMOD; 3363e12c5d1SDavid du Colombier putfile(f); 3373e12c5d1SDavid du Colombier putsect(pdp->p); 3383e12c5d1SDavid du Colombier free(pdp); 3393e12c5d1SDavid du Colombier f->flags |= omode; 3403e12c5d1SDavid du Colombier chat("f->qid=0x%8.8lux...", f->qid.path); 3413e12c5d1SDavid du Colombier rhdr.qid = f->qid; 3423e12c5d1SDavid du Colombier return; 3433e12c5d1SDavid du Colombier badio: 3443e12c5d1SDavid du Colombier if(ndp->p) 3453e12c5d1SDavid du Colombier putfile(f); 3463e12c5d1SDavid du Colombier putsect(pdp->p); 3473e12c5d1SDavid du Colombier free(pdp); 3483e12c5d1SDavid du Colombier errno = Eio; 3493e12c5d1SDavid du Colombier } 3503e12c5d1SDavid du Colombier void 3513e12c5d1SDavid du Colombier rread(void) 3523e12c5d1SDavid du Colombier { 3533e12c5d1SDavid du Colombier Xfile *f; int r; 3543e12c5d1SDavid du Colombier 3553e12c5d1SDavid du Colombier chat("read(fid=%d,offset=%d,count=%d)...", 3563e12c5d1SDavid du Colombier thdr.fid, thdr.offset, thdr.count); 3573e12c5d1SDavid du Colombier if (!(f=xfile(thdr.fid, Asis)) || !(f->flags&Oread)) 3583e12c5d1SDavid du Colombier goto error; 3593e12c5d1SDavid du Colombier if(f->qid.path & CHDIR){ 360*219b2ee8SDavid du Colombier thdr.count = (thdr.count/DIRLEN)*DIRLEN; 361*219b2ee8SDavid du Colombier if(thdr.count<DIRLEN || thdr.offset%DIRLEN){ 362*219b2ee8SDavid du Colombier chat("count=%d,offset=%d,DIRLEN=%d...", 363*219b2ee8SDavid du Colombier thdr.count, thdr.offset, DIRLEN); 3643e12c5d1SDavid du Colombier goto error; 3653e12c5d1SDavid du Colombier } 3663e12c5d1SDavid du Colombier if(getfile(f) < 0) 3673e12c5d1SDavid du Colombier goto error; 3683e12c5d1SDavid du Colombier r = readdir(f, fdata, thdr.offset, thdr.count); 3693e12c5d1SDavid du Colombier }else{ 3703e12c5d1SDavid du Colombier if(getfile(f) < 0) 3713e12c5d1SDavid du Colombier goto error; 3723e12c5d1SDavid du Colombier r = readfile(f, fdata, thdr.offset, thdr.count); 3733e12c5d1SDavid du Colombier } 3743e12c5d1SDavid du Colombier putfile(f); 3753e12c5d1SDavid du Colombier if(r < 0){ 3763e12c5d1SDavid du Colombier error: 3773e12c5d1SDavid du Colombier errno = Eio; 3783e12c5d1SDavid du Colombier }else{ 3793e12c5d1SDavid du Colombier rhdr.count = r; 3803e12c5d1SDavid du Colombier rhdr.data = fdata; 3813e12c5d1SDavid du Colombier chat("rcnt=%d...", r); 3823e12c5d1SDavid du Colombier } 3833e12c5d1SDavid du Colombier } 3843e12c5d1SDavid du Colombier void 3853e12c5d1SDavid du Colombier rwrite(void) 3863e12c5d1SDavid du Colombier { 3873e12c5d1SDavid du Colombier Xfile *f; int r; 3883e12c5d1SDavid du Colombier 3893e12c5d1SDavid du Colombier chat("write(fid=%d,offset=%d,count=%d)...", 3903e12c5d1SDavid du Colombier thdr.fid, thdr.offset, thdr.count); 3913e12c5d1SDavid du Colombier if (!(f=xfile(thdr.fid, Asis)) || !(f->flags&Owrite)) 3923e12c5d1SDavid du Colombier goto error; 3933e12c5d1SDavid du Colombier if(getfile(f) < 0) 3943e12c5d1SDavid du Colombier goto error; 3953e12c5d1SDavid du Colombier r = writefile(f, thdr.data, thdr.offset, thdr.count); 3963e12c5d1SDavid du Colombier putfile(f); 3973e12c5d1SDavid du Colombier if(r < 0){ 3983e12c5d1SDavid du Colombier error: 3993e12c5d1SDavid du Colombier errno = Eio; 4003e12c5d1SDavid du Colombier }else{ 4013e12c5d1SDavid du Colombier rhdr.count = r; 4023e12c5d1SDavid du Colombier chat("rcnt=%d...", r); 4033e12c5d1SDavid du Colombier } 4043e12c5d1SDavid du Colombier } 4053e12c5d1SDavid du Colombier void 4063e12c5d1SDavid du Colombier rclunk(void) 4073e12c5d1SDavid du Colombier { 4083e12c5d1SDavid du Colombier chat("clunk(fid=%d)...", thdr.fid); 4093e12c5d1SDavid du Colombier xfile(thdr.fid, Clunk); 4103e12c5d1SDavid du Colombier sync(); 4113e12c5d1SDavid du Colombier } 4123e12c5d1SDavid du Colombier void 4133e12c5d1SDavid du Colombier rremove(void) 4143e12c5d1SDavid du Colombier { 4153e12c5d1SDavid du Colombier Xfile *f=xfile(thdr.fid, Asis); 4163e12c5d1SDavid du Colombier Dosptr *dp; 4173e12c5d1SDavid du Colombier Iosect *parp; Dosdir *pard; 4183e12c5d1SDavid du Colombier 4193e12c5d1SDavid du Colombier chat("remove(fid=%d,name=\"%s\")...", thdr.fid, thdr.name); 4203e12c5d1SDavid du Colombier if(!f){ 4213e12c5d1SDavid du Colombier errno = Eio; 4223e12c5d1SDavid du Colombier goto out; 4233e12c5d1SDavid du Colombier } 4243e12c5d1SDavid du Colombier dp = f->ptr; 4253e12c5d1SDavid du Colombier if(!dp->addr){ 4263e12c5d1SDavid du Colombier chat("root..."); 4273e12c5d1SDavid du Colombier errno = Eperm; 4283e12c5d1SDavid du Colombier goto out; 4293e12c5d1SDavid du Colombier } 4303e12c5d1SDavid du Colombier /* 4313e12c5d1SDavid du Colombier * check on parent directory of file to be deleted 4323e12c5d1SDavid du Colombier */ 4333e12c5d1SDavid du Colombier parp = getsect(f->xf, dp->paddr); 4343e12c5d1SDavid du Colombier if(parp == 0){ 4353e12c5d1SDavid du Colombier errno = Eio; 4363e12c5d1SDavid du Colombier goto out; 4373e12c5d1SDavid du Colombier } 4383e12c5d1SDavid du Colombier pard = (Dosdir *)&parp->iobuf[dp->poffset]; 4393e12c5d1SDavid du Colombier if(dp->paddr && (pard->attr & DRONLY)){ 440*219b2ee8SDavid du Colombier chat("parent read-only..."); 441*219b2ee8SDavid du Colombier putsect(parp); 4423e12c5d1SDavid du Colombier errno = Eperm; 4433e12c5d1SDavid du Colombier goto out; 4443e12c5d1SDavid du Colombier } 4453e12c5d1SDavid du Colombier if(getfile(f) < 0){ 4463e12c5d1SDavid du Colombier chat("getfile failed..."); 4473e12c5d1SDavid du Colombier putsect(parp); 4483e12c5d1SDavid du Colombier errno = Eio; 4493e12c5d1SDavid du Colombier goto out; 4503e12c5d1SDavid du Colombier } 4513e12c5d1SDavid du Colombier if((dp->d->attr & DDIR) && emptydir(f) < 0){ 4523e12c5d1SDavid du Colombier chat("non-empty dir..."); 4533e12c5d1SDavid du Colombier putfile(f); 4543e12c5d1SDavid du Colombier putsect(parp); 4553e12c5d1SDavid du Colombier errno = Eperm; 4563e12c5d1SDavid du Colombier goto out; 4573e12c5d1SDavid du Colombier } 458*219b2ee8SDavid du Colombier if(dp->paddr == 0 && (dp->d->attr&DRONLY)){ 459*219b2ee8SDavid du Colombier chat("read-only file in root directory..."); 460*219b2ee8SDavid du Colombier putfile(f); 461*219b2ee8SDavid du Colombier putsect(parp); 462*219b2ee8SDavid du Colombier errno = Eperm; 463*219b2ee8SDavid du Colombier goto out; 464*219b2ee8SDavid du Colombier } 4653e12c5d1SDavid du Colombier if(dp->paddr){ 466*219b2ee8SDavid du Colombier puttime(pard, 0); 4673e12c5d1SDavid du Colombier parp->flags |= BMOD; 4683e12c5d1SDavid du Colombier } 4693e12c5d1SDavid du Colombier putsect(parp); 4703e12c5d1SDavid du Colombier if(truncfile(f, 1) < 0) 4713e12c5d1SDavid du Colombier errno = Eio; 4723e12c5d1SDavid du Colombier dp->d->name[0] = 0xe5; 4733e12c5d1SDavid du Colombier dp->p->flags |= BMOD; 4743e12c5d1SDavid du Colombier putfile(f); 4753e12c5d1SDavid du Colombier out: 4763e12c5d1SDavid du Colombier xfile(thdr.fid, Clunk); 4773e12c5d1SDavid du Colombier sync(); 4783e12c5d1SDavid du Colombier } 4793e12c5d1SDavid du Colombier void 4803e12c5d1SDavid du Colombier rstat(void) 4813e12c5d1SDavid du Colombier { 4823e12c5d1SDavid du Colombier Dir dir; 4833e12c5d1SDavid du Colombier Xfile *f=xfile(thdr.fid, Asis); 4843e12c5d1SDavid du Colombier Dosptr *dp = f->ptr; 4853e12c5d1SDavid du Colombier 4863e12c5d1SDavid du Colombier chat("stat(fid=%d)...", thdr.fid); 4873e12c5d1SDavid du Colombier if(!f || getfile(f)< 0) 4883e12c5d1SDavid du Colombier errno = Eio; 4893e12c5d1SDavid du Colombier else{ 4903e12c5d1SDavid du Colombier getdir(&dir, dp->addr ? dp->d : 0); 4913e12c5d1SDavid du Colombier convD2M(&dir, rhdr.stat); 4923e12c5d1SDavid du Colombier putfile(f); 4933e12c5d1SDavid du Colombier } 4943e12c5d1SDavid du Colombier } 495*219b2ee8SDavid du Colombier 496*219b2ee8SDavid du Colombier static char isfrog[256]={ 497*219b2ee8SDavid du Colombier /*NUL*/ 1, 1, 1, 1, 1, 1, 1, 1, 498*219b2ee8SDavid du Colombier /*BKS*/ 1, 1, 1, 1, 1, 1, 1, 1, 499*219b2ee8SDavid du Colombier /*DLE*/ 1, 1, 1, 1, 1, 1, 1, 1, 500*219b2ee8SDavid du Colombier /*CAN*/ 1, 1, 1, 1, 1, 1, 1, 1, 501*219b2ee8SDavid du Colombier [' '] 1, 502*219b2ee8SDavid du Colombier ['/'] 1, 503*219b2ee8SDavid du Colombier [0x7f] 1, 504*219b2ee8SDavid du Colombier }; 505*219b2ee8SDavid du Colombier 506*219b2ee8SDavid du Colombier static int 507*219b2ee8SDavid du Colombier nameok(char *elem) 508*219b2ee8SDavid du Colombier { 509*219b2ee8SDavid du Colombier char *eelem; 510*219b2ee8SDavid du Colombier 511*219b2ee8SDavid du Colombier eelem = elem+NAMELEN; 512*219b2ee8SDavid du Colombier while(*elem){ 513*219b2ee8SDavid du Colombier if(isfrog[*(uchar*)elem]) 514*219b2ee8SDavid du Colombier return -1; 515*219b2ee8SDavid du Colombier elem++; 516*219b2ee8SDavid du Colombier if(elem >= eelem) 517*219b2ee8SDavid du Colombier return -1; 518*219b2ee8SDavid du Colombier } 519*219b2ee8SDavid du Colombier return 0; 520*219b2ee8SDavid du Colombier } 521*219b2ee8SDavid du Colombier 5223e12c5d1SDavid du Colombier void 5233e12c5d1SDavid du Colombier rwstat(void) 5243e12c5d1SDavid du Colombier { 5253e12c5d1SDavid du Colombier errno = Eperm; 5263e12c5d1SDavid du Colombier } 527