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 "dat.h" 63e12c5d1SDavid du Colombier #include "fns.h" 73e12c5d1SDavid du Colombier #include "iso9660.h" 83e12c5d1SDavid du Colombier 93e12c5d1SDavid du Colombier static void ireset(void); 103e12c5d1SDavid du Colombier static int iattach(Xfile*); 113e12c5d1SDavid du Colombier static void iclone(Xfile*, Xfile*); 123e12c5d1SDavid du Colombier static void iwalkup(Xfile*); 133e12c5d1SDavid du Colombier static void iwalk(Xfile*, char*); 143e12c5d1SDavid du Colombier static void iopen(Xfile*, int); 153e12c5d1SDavid du Colombier static void icreate(Xfile*, char*, long, int); 163e12c5d1SDavid du Colombier static long ireaddir(Xfile*, void*, long, long); 173e12c5d1SDavid du Colombier static long iread(Xfile*, void*, long, long); 183e12c5d1SDavid du Colombier static long iwrite(Xfile*, void*, long, long); 193e12c5d1SDavid du Colombier static void iclunk(Xfile*); 203e12c5d1SDavid du Colombier static void iremove(Xfile*); 213e12c5d1SDavid du Colombier static void istat(Xfile*, Dir*); 223e12c5d1SDavid du Colombier static void iwstat(Xfile*, Dir*); 233e12c5d1SDavid du Colombier 243e12c5d1SDavid du Colombier static char* nstr(void*, int); 253e12c5d1SDavid du Colombier static char* rdate(void*, int); 263e12c5d1SDavid du Colombier static int getdrec(Xfile*, void*); 273e12c5d1SDavid du Colombier static int opendotdot(Xfile*, Xfile*); 283e12c5d1SDavid du Colombier static int showdrec(int, int, void*); 293e12c5d1SDavid du Colombier static long gtime(void*); 303e12c5d1SDavid du Colombier static long l16(void*); 313e12c5d1SDavid du Colombier static long l32(void*); 323e12c5d1SDavid du Colombier static void newdrec(Xfile*, Drec*); 33bd389b36SDavid du Colombier static int rzdir(int, Dir*, int, Drec*); 343e12c5d1SDavid du Colombier 35bd389b36SDavid du Colombier Xfsub isosub = 36bd389b36SDavid du Colombier { 373e12c5d1SDavid du Colombier ireset, iattach, iclone, iwalkup, iwalk, iopen, icreate, 383e12c5d1SDavid du Colombier ireaddir, iread, iwrite, iclunk, iremove, istat, iwstat 393e12c5d1SDavid du Colombier }; 403e12c5d1SDavid du Colombier 413e12c5d1SDavid du Colombier static void 423e12c5d1SDavid du Colombier ireset(void) 433e12c5d1SDavid du Colombier {} 443e12c5d1SDavid du Colombier 453e12c5d1SDavid du Colombier static int 463e12c5d1SDavid du Colombier iattach(Xfile *root) 473e12c5d1SDavid du Colombier { 483e12c5d1SDavid du Colombier Xfs *cd = root->xf; 493e12c5d1SDavid du Colombier Iobuf *p; Voldesc *v; Isofile *fp; Drec *dp; 503e12c5d1SDavid du Colombier int fmt, blksize; 513e12c5d1SDavid du Colombier 523e12c5d1SDavid du Colombier p = getbuf(cd->d, VOLDESC); 533e12c5d1SDavid du Colombier v = (Voldesc*)(p->iobuf); 543e12c5d1SDavid du Colombier if(memcmp(v->byte, "\01CD001\01", 7) == 0){ /* iso */ 553e12c5d1SDavid du Colombier fmt = 'z'; 563e12c5d1SDavid du Colombier dp = (Drec*)v->z.desc.rootdir; 573e12c5d1SDavid du Colombier blksize = l16(v->z.desc.blksize); 583e12c5d1SDavid du Colombier chat("iso, blksize=%d...", blksize); 593e12c5d1SDavid du Colombier }else if(memcmp(&v->byte[8], "\01CDROM\01", 7) == 0){ /* high sierra */ 603e12c5d1SDavid du Colombier fmt = 'r'; 613e12c5d1SDavid du Colombier dp = (Drec*)v->r.desc.rootdir; 623e12c5d1SDavid du Colombier blksize = l16(v->r.desc.blksize); 633e12c5d1SDavid du Colombier chat("high sierra, blksize=%d...", blksize); 643e12c5d1SDavid du Colombier }else{ 653e12c5d1SDavid du Colombier putbuf(p); 663e12c5d1SDavid du Colombier return -1; 673e12c5d1SDavid du Colombier } 683e12c5d1SDavid du Colombier if(chatty) 693e12c5d1SDavid du Colombier showdrec(2, fmt, dp); 703e12c5d1SDavid du Colombier if(blksize > Sectorsize){ 713e12c5d1SDavid du Colombier chat("blksize too big..."); 723e12c5d1SDavid du Colombier putbuf(p); 733e12c5d1SDavid du Colombier return -1; 743e12c5d1SDavid du Colombier } 753e12c5d1SDavid du Colombier if(waserror()){ 763e12c5d1SDavid du Colombier putbuf(p); 773e12c5d1SDavid du Colombier nexterror(); 783e12c5d1SDavid du Colombier } 793e12c5d1SDavid du Colombier root->len = sizeof(Isofile) - sizeof(Drec) + dp->reclen; 803e12c5d1SDavid du Colombier root->ptr = fp = ealloc(root->len); 813e12c5d1SDavid du Colombier root->xf->isplan9 = (strncmp((char*)v->z.boot.sysid, "PLAN 9", 6)==0); 823e12c5d1SDavid du Colombier fp->fmt = fmt; 833e12c5d1SDavid du Colombier fp->blksize = blksize; 843e12c5d1SDavid du Colombier fp->offset = 0; 853e12c5d1SDavid du Colombier fp->doffset = 0; 863e12c5d1SDavid du Colombier memmove(&fp->d, dp, dp->reclen); 873e12c5d1SDavid du Colombier root->qid.path = CHDIR|l32(dp->addr); 883e12c5d1SDavid du Colombier putbuf(p); 893e12c5d1SDavid du Colombier poperror(); 903e12c5d1SDavid du Colombier return 0; 913e12c5d1SDavid du Colombier } 923e12c5d1SDavid du Colombier 933e12c5d1SDavid du Colombier static void 943e12c5d1SDavid du Colombier iclone(Xfile *of, Xfile *nf) 953e12c5d1SDavid du Colombier { 963e12c5d1SDavid du Colombier USED(of, nf); 973e12c5d1SDavid du Colombier } 983e12c5d1SDavid du Colombier 993e12c5d1SDavid du Colombier static void 1003e12c5d1SDavid du Colombier iwalkup(Xfile *f) 1013e12c5d1SDavid du Colombier { 1023e12c5d1SDavid du Colombier long paddr; 1033e12c5d1SDavid du Colombier uchar dbuf[256]; 1043e12c5d1SDavid du Colombier Drec *d = (Drec *)dbuf; 1053e12c5d1SDavid du Colombier Xfile pf, ppf; 1063e12c5d1SDavid du Colombier Isofile piso, ppiso; 1073e12c5d1SDavid du Colombier 1083e12c5d1SDavid du Colombier memset(&pf, 0, sizeof pf); 1093e12c5d1SDavid du Colombier memset(&ppf, 0, sizeof ppf); 1103e12c5d1SDavid du Colombier pf.ptr = &piso; 1113e12c5d1SDavid du Colombier ppf.ptr = &ppiso; 1123e12c5d1SDavid du Colombier if(opendotdot(f, &pf) < 0) 1133e12c5d1SDavid du Colombier error("can't open pf"); 1143e12c5d1SDavid du Colombier paddr = l32(((Isofile *)pf.ptr)->d.addr); 1153e12c5d1SDavid du Colombier if(l32(((Isofile *)f->ptr)->d.addr) == paddr) 1163e12c5d1SDavid du Colombier return; 1173e12c5d1SDavid du Colombier if(opendotdot(&pf, &ppf) < 0) 1183e12c5d1SDavid du Colombier error("can't open ppf"); 1193e12c5d1SDavid du Colombier while(getdrec(&ppf, d) >= 0){ 1203e12c5d1SDavid du Colombier if(l32(d->addr) == paddr){ 1213e12c5d1SDavid du Colombier newdrec(f, d); 1223e12c5d1SDavid du Colombier f->qid.path = paddr|CHDIR; 1233e12c5d1SDavid du Colombier return; 1243e12c5d1SDavid du Colombier } 1253e12c5d1SDavid du Colombier } 1263e12c5d1SDavid du Colombier error("can't find addr of .."); 1273e12c5d1SDavid du Colombier } 1283e12c5d1SDavid du Colombier 1293e12c5d1SDavid du Colombier static void 1303e12c5d1SDavid du Colombier iwalk(Xfile *f, char *name) 1313e12c5d1SDavid du Colombier { 1323e12c5d1SDavid du Colombier Isofile *ip = f->ptr; 1333e12c5d1SDavid du Colombier uchar dbuf[256]; 134bd389b36SDavid du Colombier char nbuf[NAMELEN]; 1353e12c5d1SDavid du Colombier Drec *d = (Drec*)dbuf; 1363e12c5d1SDavid du Colombier Dir dir; 1373e12c5d1SDavid du Colombier char *p; 138bd389b36SDavid du Colombier int len, vers, dvers; 1393e12c5d1SDavid du Colombier 140bd389b36SDavid du Colombier vers = -1; 141bd389b36SDavid du Colombier if(p = strchr(name, ';')) { /* assign = */ 142bd389b36SDavid du Colombier len = p-name; 1433e12c5d1SDavid du Colombier if(len >= NAMELEN) 144bd389b36SDavid du Colombier len = NAMELEN-1; 145bd389b36SDavid du Colombier memmove(nbuf, name, len); 146bd389b36SDavid du Colombier vers = strtoul(p+1, 0, 10); 1473e12c5d1SDavid du Colombier name = nbuf; 1483e12c5d1SDavid du Colombier } 149bd389b36SDavid du Colombier len = strlen(name); 150bd389b36SDavid du Colombier if(len >= NAMELEN) 151bd389b36SDavid du Colombier len = NAMELEN-1; 152bd389b36SDavid du Colombier name[len] = 0; 153bd389b36SDavid du Colombier 1543e12c5d1SDavid du Colombier chat("%d \"%s\"...", len, name); 1553e12c5d1SDavid du Colombier ip->offset = 0; 156bd389b36SDavid du Colombier while(getdrec(f, d) >= 0) { 157bd389b36SDavid du Colombier dvers = rzdir(f->xf->isplan9, &dir, 'z', d); 1583e12c5d1SDavid du Colombier if(strcmp(name, dir.name) != 0) 1593e12c5d1SDavid du Colombier continue; 1603e12c5d1SDavid du Colombier newdrec(f, d); 1613e12c5d1SDavid du Colombier f->qid.path = dir.qid.path; 162bd389b36SDavid du Colombier USED(dvers); 1633e12c5d1SDavid du Colombier return; 1643e12c5d1SDavid du Colombier } 165bd389b36SDavid du Colombier USED(vers); 1663e12c5d1SDavid du Colombier error(Enonexist); 1673e12c5d1SDavid du Colombier } 1683e12c5d1SDavid du Colombier 1693e12c5d1SDavid du Colombier static void 1703e12c5d1SDavid du Colombier iopen(Xfile *f, int mode) 1713e12c5d1SDavid du Colombier { 1723e12c5d1SDavid du Colombier mode &= ~OCEXEC; 1733e12c5d1SDavid du Colombier if(mode != OREAD && mode != OEXEC) 1743e12c5d1SDavid du Colombier error(Eperm); 1753e12c5d1SDavid du Colombier ((Isofile*)f->ptr)->offset = 0; 1763e12c5d1SDavid du Colombier ((Isofile*)f->ptr)->doffset = 0; 1773e12c5d1SDavid du Colombier } 1783e12c5d1SDavid du Colombier 1793e12c5d1SDavid du Colombier static void 1803e12c5d1SDavid du Colombier icreate(Xfile *f, char *name, long perm, int mode) 1813e12c5d1SDavid du Colombier { 1823e12c5d1SDavid du Colombier USED(f, name, perm, mode); 1833e12c5d1SDavid du Colombier error(Eperm); 1843e12c5d1SDavid du Colombier } 1853e12c5d1SDavid du Colombier 1863e12c5d1SDavid du Colombier static long 1873e12c5d1SDavid du Colombier ireaddir(Xfile *f, char *buf, long offset, long count) 1883e12c5d1SDavid du Colombier { 1893e12c5d1SDavid du Colombier Isofile *ip = f->ptr; 1903e12c5d1SDavid du Colombier Dir d; 1913e12c5d1SDavid du Colombier uchar dbuf[256]; 1923e12c5d1SDavid du Colombier Drec *drec = (Drec *)dbuf; 1933e12c5d1SDavid du Colombier int rcnt = 0; 1943e12c5d1SDavid du Colombier 1953e12c5d1SDavid du Colombier if(offset < ip->doffset){ 1963e12c5d1SDavid du Colombier ip->offset = 0; 1973e12c5d1SDavid du Colombier ip->doffset = 0; 1983e12c5d1SDavid du Colombier } 1993e12c5d1SDavid du Colombier while(rcnt < count && getdrec(f, drec) >= 0){ 2003e12c5d1SDavid du Colombier if(drec->namelen == 1){ 2013e12c5d1SDavid du Colombier if(drec->name[0] == 0) 2023e12c5d1SDavid du Colombier continue; 2033e12c5d1SDavid du Colombier if(drec->name[0] == 1) 2043e12c5d1SDavid du Colombier continue; 2053e12c5d1SDavid du Colombier } 2063e12c5d1SDavid du Colombier if(ip->doffset < offset){ 2073e12c5d1SDavid du Colombier ip->doffset += DIRLEN; 2083e12c5d1SDavid du Colombier continue; 2093e12c5d1SDavid du Colombier } 2103e12c5d1SDavid du Colombier rzdir(f->xf->isplan9, &d, ip->fmt, drec); 2113e12c5d1SDavid du Colombier d.qid.vers = f->qid.vers; 2123e12c5d1SDavid du Colombier rcnt += convD2M(&d, &buf[rcnt]); 2133e12c5d1SDavid du Colombier } 2143e12c5d1SDavid du Colombier ip->doffset += rcnt; 2153e12c5d1SDavid du Colombier return rcnt; 2163e12c5d1SDavid du Colombier } 2173e12c5d1SDavid du Colombier 2183e12c5d1SDavid du Colombier static long 2193e12c5d1SDavid du Colombier iread(Xfile *f, char *buf, long offset, long count) 2203e12c5d1SDavid du Colombier { 2213e12c5d1SDavid du Colombier Isofile *ip = f->ptr; 2223e12c5d1SDavid du Colombier long size, addr, o, n; 2233e12c5d1SDavid du Colombier int rcnt = 0; 2243e12c5d1SDavid du Colombier Iobuf *p; 2253e12c5d1SDavid du Colombier 2263e12c5d1SDavid du Colombier size = l32(ip->d.size); 2273e12c5d1SDavid du Colombier if(offset >= size) 2283e12c5d1SDavid du Colombier return 0; 2293e12c5d1SDavid du Colombier if(offset+count > size) 2303e12c5d1SDavid du Colombier count = size - offset; 2313e12c5d1SDavid du Colombier addr = (l32(ip->d.addr)+ip->d.attrlen)*ip->blksize + offset; 2323e12c5d1SDavid du Colombier o = addr % Sectorsize; 2333e12c5d1SDavid du Colombier addr /= Sectorsize; 2343e12c5d1SDavid du Colombier /*chat("d.addr=0x%x, addr=0x%x, o=0x%x...", l32(ip->d.addr), addr, o);*/ 2353e12c5d1SDavid du Colombier n = Sectorsize - o; 2363e12c5d1SDavid du Colombier 2373e12c5d1SDavid du Colombier while(count > 0){ 2383e12c5d1SDavid du Colombier if(n > count) 2393e12c5d1SDavid du Colombier n = count; 2403e12c5d1SDavid du Colombier p = getbuf(f->xf->d, addr); 2413e12c5d1SDavid du Colombier memmove(&buf[rcnt], &p->iobuf[o], n); 2423e12c5d1SDavid du Colombier putbuf(p); 2433e12c5d1SDavid du Colombier count -= n; 2443e12c5d1SDavid du Colombier rcnt += n; 2453e12c5d1SDavid du Colombier ++addr; 2463e12c5d1SDavid du Colombier o = 0; 2473e12c5d1SDavid du Colombier n = Sectorsize; 2483e12c5d1SDavid du Colombier } 2493e12c5d1SDavid du Colombier return rcnt; 2503e12c5d1SDavid du Colombier } 2513e12c5d1SDavid du Colombier 2523e12c5d1SDavid du Colombier static long 2533e12c5d1SDavid du Colombier iwrite(Xfile *f, uchar *buf, long offset, long count) 2543e12c5d1SDavid du Colombier { 2553e12c5d1SDavid du Colombier USED(f, buf, offset, count); 2563e12c5d1SDavid du Colombier error(Eperm); 2573e12c5d1SDavid du Colombier return 0; 2583e12c5d1SDavid du Colombier } 2593e12c5d1SDavid du Colombier 2603e12c5d1SDavid du Colombier static void 2613e12c5d1SDavid du Colombier iclunk(Xfile *f) 2623e12c5d1SDavid du Colombier { 2633e12c5d1SDavid du Colombier USED(f); 2643e12c5d1SDavid du Colombier } 2653e12c5d1SDavid du Colombier 2663e12c5d1SDavid du Colombier static void 2673e12c5d1SDavid du Colombier iremove(Xfile *f) 2683e12c5d1SDavid du Colombier { 2693e12c5d1SDavid du Colombier USED(f); 2703e12c5d1SDavid du Colombier error(Eperm); 2713e12c5d1SDavid du Colombier } 2723e12c5d1SDavid du Colombier 2733e12c5d1SDavid du Colombier static void 2743e12c5d1SDavid du Colombier istat(Xfile *f, Dir *d) 2753e12c5d1SDavid du Colombier { 2763e12c5d1SDavid du Colombier Isofile *ip = f->ptr; 2773e12c5d1SDavid du Colombier 2783e12c5d1SDavid du Colombier rzdir(f->xf->isplan9, d, ip->fmt, &ip->d); 2793e12c5d1SDavid du Colombier d->qid.vers = f->qid.vers; 2803e12c5d1SDavid du Colombier if(d->qid.path==f->xf->rootqid.path) 2813e12c5d1SDavid du Colombier d->qid.path = CHDIR; 2823e12c5d1SDavid du Colombier } 2833e12c5d1SDavid du Colombier 2843e12c5d1SDavid du Colombier static void 2853e12c5d1SDavid du Colombier iwstat(Xfile *f, Dir *d) 2863e12c5d1SDavid du Colombier { 2873e12c5d1SDavid du Colombier USED(f, d); 2883e12c5d1SDavid du Colombier error(Eperm); 2893e12c5d1SDavid du Colombier } 2903e12c5d1SDavid du Colombier 2913e12c5d1SDavid du Colombier static int 2923e12c5d1SDavid du Colombier showdrec(int fd, int fmt, void *x) 2933e12c5d1SDavid du Colombier { 2943e12c5d1SDavid du Colombier Drec *d = (Drec *)x; 2953e12c5d1SDavid du Colombier int namelen, syslen; 2963e12c5d1SDavid du Colombier 2973e12c5d1SDavid du Colombier if(d->reclen == 0) 2983e12c5d1SDavid du Colombier return 0; 2993e12c5d1SDavid du Colombier fprint(fd, "%d %d %d %d ", 3003e12c5d1SDavid du Colombier d->reclen, d->attrlen, l32(d->addr), l32(d->size)); 3013e12c5d1SDavid du Colombier fprint(fd, "%s 0x%2.2x %d %d %d ", 3023e12c5d1SDavid du Colombier rdate(d->date, fmt), (fmt=='z' ? d->flags : d->r_flags), 3033e12c5d1SDavid du Colombier d->unitsize, d->gapsize, l16(d->vseqno)); 3043e12c5d1SDavid du Colombier fprint(fd, "%d %s", d->namelen, nstr(d->name, d->namelen)); 3053e12c5d1SDavid du Colombier namelen = d->namelen + (1-(d->namelen&1)); 3063e12c5d1SDavid du Colombier syslen = d->reclen - 33 - namelen; 3073e12c5d1SDavid du Colombier if(syslen != 0) 3083e12c5d1SDavid du Colombier fprint(fd, " %s", nstr(&d->name[namelen], syslen)); 3093e12c5d1SDavid du Colombier fprint(fd, "\n"); 3103e12c5d1SDavid du Colombier return d->reclen + (d->reclen&1); 3113e12c5d1SDavid du Colombier } 3123e12c5d1SDavid du Colombier 3133e12c5d1SDavid du Colombier static void 3143e12c5d1SDavid du Colombier newdrec(Xfile *f, Drec *dp) 3153e12c5d1SDavid du Colombier { 3163e12c5d1SDavid du Colombier Isofile *x = f->ptr; 3173e12c5d1SDavid du Colombier Isofile *n; 3183e12c5d1SDavid du Colombier int len; 3193e12c5d1SDavid du Colombier 3203e12c5d1SDavid du Colombier len = sizeof(Isofile) - sizeof(Drec) + dp->reclen; 3213e12c5d1SDavid du Colombier n = ealloc(len); 3223e12c5d1SDavid du Colombier n->fmt = x->fmt; 3233e12c5d1SDavid du Colombier n->blksize = x->blksize; 3243e12c5d1SDavid du Colombier n->offset = 0; 3253e12c5d1SDavid du Colombier n->doffset = 0; 3263e12c5d1SDavid du Colombier memmove(&n->d, dp, dp->reclen); 3273e12c5d1SDavid du Colombier free(x); 3283e12c5d1SDavid du Colombier f->ptr = n; 3293e12c5d1SDavid du Colombier f->len = len; 3303e12c5d1SDavid du Colombier } 3313e12c5d1SDavid du Colombier 3323e12c5d1SDavid du Colombier static int 3333e12c5d1SDavid du Colombier getdrec(Xfile *f, void *buf) 3343e12c5d1SDavid du Colombier { 3353e12c5d1SDavid du Colombier Isofile *ip = f->ptr; 3363e12c5d1SDavid du Colombier int len = 0, boff = 0; 3373e12c5d1SDavid du Colombier long size, addr; 3383e12c5d1SDavid du Colombier Iobuf *p = 0; 3393e12c5d1SDavid du Colombier 3403e12c5d1SDavid du Colombier if(!ip) 3413e12c5d1SDavid du Colombier return -1; 3423e12c5d1SDavid du Colombier size = l32(ip->d.size); 3433e12c5d1SDavid du Colombier while(ip->offset<size){ 3443e12c5d1SDavid du Colombier addr = (l32(ip->d.addr)+ip->d.attrlen)*ip->blksize + ip->offset; 3453e12c5d1SDavid du Colombier boff = addr % Sectorsize; 3463e12c5d1SDavid du Colombier if(boff > Sectorsize-34){ 3473e12c5d1SDavid du Colombier ip->offset += Sectorsize-boff; 3483e12c5d1SDavid du Colombier continue; 3493e12c5d1SDavid du Colombier } 3503e12c5d1SDavid du Colombier p = getbuf(f->xf->d, addr/Sectorsize); 3513e12c5d1SDavid du Colombier len = p->iobuf[boff]; 3523e12c5d1SDavid du Colombier if(len >= 34) 3533e12c5d1SDavid du Colombier break; 3543e12c5d1SDavid du Colombier putbuf(p); 3553e12c5d1SDavid du Colombier p = 0; 3563e12c5d1SDavid du Colombier ip->offset += Sectorsize-boff; 3573e12c5d1SDavid du Colombier } 3583e12c5d1SDavid du Colombier if(p) { 3593e12c5d1SDavid du Colombier memmove(buf, &p->iobuf[boff], len); 3603e12c5d1SDavid du Colombier putbuf(p); 3613e12c5d1SDavid du Colombier ip->offset += len + (len&1); 3623e12c5d1SDavid du Colombier } 363bd389b36SDavid du Colombier if(p) 364bd389b36SDavid du Colombier return 0; 365bd389b36SDavid du Colombier return -1; 3663e12c5d1SDavid du Colombier } 3673e12c5d1SDavid du Colombier 3683e12c5d1SDavid du Colombier static int 3693e12c5d1SDavid du Colombier opendotdot(Xfile *f, Xfile *pf) 3703e12c5d1SDavid du Colombier { 3713e12c5d1SDavid du Colombier uchar dbuf[256]; 3723e12c5d1SDavid du Colombier Drec *d = (Drec *)dbuf; 3733e12c5d1SDavid du Colombier Isofile *ip = f->ptr, *pip = pf->ptr; 3743e12c5d1SDavid du Colombier 3753e12c5d1SDavid du Colombier ip->offset = 0; 3763e12c5d1SDavid du Colombier if(getdrec(f, d) < 0){ 3773e12c5d1SDavid du Colombier chat("opendotdot: getdrec(.) failed..."); 3783e12c5d1SDavid du Colombier return -1; 3793e12c5d1SDavid du Colombier } 3803e12c5d1SDavid du Colombier if(d->namelen != 1 || d->name[0] != 0){ 3813e12c5d1SDavid du Colombier chat("opendotdot: no . entry..."); 3823e12c5d1SDavid du Colombier return -1; 3833e12c5d1SDavid du Colombier } 3843e12c5d1SDavid du Colombier if(l32(d->addr) != l32(ip->d.addr)){ 3853e12c5d1SDavid du Colombier chat("opendotdot: bad . address..."); 3863e12c5d1SDavid du Colombier return -1; 3873e12c5d1SDavid du Colombier } 3883e12c5d1SDavid du Colombier if(getdrec(f, d) < 0){ 3893e12c5d1SDavid du Colombier chat("opendotdot: getdrec(..) failed..."); 3903e12c5d1SDavid du Colombier return -1; 3913e12c5d1SDavid du Colombier } 3923e12c5d1SDavid du Colombier if(d->namelen != 1 || d->name[0] != 1){ 3933e12c5d1SDavid du Colombier chat("opendotdot: no .. entry..."); 3943e12c5d1SDavid du Colombier return -1; 3953e12c5d1SDavid du Colombier } 3963e12c5d1SDavid du Colombier 3973e12c5d1SDavid du Colombier pf->xf = f->xf; 3983e12c5d1SDavid du Colombier pip->fmt = ip->fmt; 3993e12c5d1SDavid du Colombier pip->blksize = ip->blksize; 4003e12c5d1SDavid du Colombier pip->offset = 0; 4013e12c5d1SDavid du Colombier pip->doffset = 0; 4023e12c5d1SDavid du Colombier pip->d = *d; 4033e12c5d1SDavid du Colombier return 0; 4043e12c5d1SDavid du Colombier } 4053e12c5d1SDavid du Colombier 406bd389b36SDavid du Colombier static int 4073e12c5d1SDavid du Colombier rzdir(int isplan9, Dir *d, int fmt, Drec *dp) 4083e12c5d1SDavid du Colombier { 409bd389b36SDavid du Colombier int n, flags, i, nl, vers; 4103e12c5d1SDavid du Colombier uchar *s; 411bd389b36SDavid du Colombier char *p; 4123e12c5d1SDavid du Colombier 413bd389b36SDavid du Colombier flags = 0; 414bd389b36SDavid du Colombier vers = -1; 4153e12c5d1SDavid du Colombier d->qid.path = l32(dp->addr); 4163e12c5d1SDavid du Colombier d->qid.vers = 0; 417bd389b36SDavid du Colombier n = dp->namelen; 418bd389b36SDavid du Colombier if(n >= NAMELEN) 4193e12c5d1SDavid du Colombier n = NAMELEN-1; 4203e12c5d1SDavid du Colombier memset(d->name, 0, NAMELEN); 4213e12c5d1SDavid du Colombier if(n == 1) { 4223e12c5d1SDavid du Colombier switch(dp->name[0]){ 4233e12c5d1SDavid du Colombier case 1: 4243e12c5d1SDavid du Colombier d->name[1] = '.'; 4253e12c5d1SDavid du Colombier /* fall through */ 4263e12c5d1SDavid du Colombier case 0: 4273e12c5d1SDavid du Colombier d->name[0] = '.'; 4283e12c5d1SDavid du Colombier break; 4293e12c5d1SDavid du Colombier default: 4303e12c5d1SDavid du Colombier d->name[0] = tolower(dp->name[0]); 4313e12c5d1SDavid du Colombier } 4323e12c5d1SDavid du Colombier } else { 4333e12c5d1SDavid du Colombier for(i=0; i<n; i++) 4343e12c5d1SDavid du Colombier d->name[i] = tolower(dp->name[i]); 4353e12c5d1SDavid du Colombier } 4363e12c5d1SDavid du Colombier 437bd389b36SDavid du Colombier if(isplan9 && dp->reclen>34+dp->namelen) { 438bd389b36SDavid du Colombier /* 439bd389b36SDavid du Colombier * get gid, uid, mode and possibly name 440bd389b36SDavid du Colombier * from plan9 directory extension 441bd389b36SDavid du Colombier */ 4423e12c5d1SDavid du Colombier s = (uchar*)dp->name + dp->namelen; 4433e12c5d1SDavid du Colombier if(((ulong)s) & 1) 4443e12c5d1SDavid du Colombier s++; 4453e12c5d1SDavid du Colombier nl = *s; 4463e12c5d1SDavid du Colombier if(nl >= NAMELEN) 4473e12c5d1SDavid du Colombier nl = NAMELEN-1; 4483e12c5d1SDavid du Colombier if(nl) { 4493e12c5d1SDavid du Colombier memset(d->name, 0, NAMELEN); 4503e12c5d1SDavid du Colombier memmove(d->name, s+1, nl); 4513e12c5d1SDavid du Colombier } 4523e12c5d1SDavid du Colombier s += 1 + *s; 4533e12c5d1SDavid du Colombier nl = *s; 4543e12c5d1SDavid du Colombier if(nl >= NAMELEN) 4553e12c5d1SDavid du Colombier nl = NAMELEN-1; 4563e12c5d1SDavid du Colombier memset(d->uid, 0, NAMELEN); 4573e12c5d1SDavid du Colombier memmove(d->uid, s+1, nl); 4583e12c5d1SDavid du Colombier s += 1 + *s; 4593e12c5d1SDavid du Colombier nl = *s; 4603e12c5d1SDavid du Colombier if(nl >= NAMELEN) 4613e12c5d1SDavid du Colombier nl = NAMELEN-1; 4623e12c5d1SDavid du Colombier memset(d->gid, 0, NAMELEN); 4633e12c5d1SDavid du Colombier memmove(d->gid, s+1, nl); 4643e12c5d1SDavid du Colombier s += 1 + *s; 4653e12c5d1SDavid du Colombier if(((ulong)s) & 1) 4663e12c5d1SDavid du Colombier s++; 4673e12c5d1SDavid du Colombier d->mode = l32(s); 4683e12c5d1SDavid du Colombier if(d->mode & CHDIR) 4693e12c5d1SDavid du Colombier d->qid.path |= CHDIR; 4703e12c5d1SDavid du Colombier } else { 4713e12c5d1SDavid du Colombier d->mode = 0444; 4723e12c5d1SDavid du Colombier switch(fmt) { 4733e12c5d1SDavid du Colombier case 'z': 4743e12c5d1SDavid du Colombier strcpy(d->gid, "iso"); 4753e12c5d1SDavid du Colombier flags = dp->flags; 4763e12c5d1SDavid du Colombier break; 4773e12c5d1SDavid du Colombier case 'r': 4783e12c5d1SDavid du Colombier strcpy(d->gid, "sierra"); 4793e12c5d1SDavid du Colombier flags = dp->r_flags; 4803e12c5d1SDavid du Colombier break; 4813e12c5d1SDavid du Colombier } 4823e12c5d1SDavid du Colombier if(flags & 0x02){ 4833e12c5d1SDavid du Colombier d->qid.path |= CHDIR; 4843e12c5d1SDavid du Colombier d->mode |= CHDIR|0111; 4853e12c5d1SDavid du Colombier } 4863e12c5d1SDavid du Colombier strcpy(d->uid, "cdrom"); 487bd389b36SDavid du Colombier p = strchr(d->name, ';'); 488bd389b36SDavid du Colombier if(p != 0) { 489bd389b36SDavid du Colombier vers = strtoul(p+1, 0, 10); 490bd389b36SDavid du Colombier memset(p, 0, NAMELEN-(p-d->name)); 491bd389b36SDavid du Colombier } 4923e12c5d1SDavid du Colombier } 4933e12c5d1SDavid du Colombier d->length = 0; 4943e12c5d1SDavid du Colombier if((d->mode & CHDIR) == 0) 4953e12c5d1SDavid du Colombier d->length = l32(dp->size); 4963e12c5d1SDavid du Colombier d->type = 0; 4973e12c5d1SDavid du Colombier d->dev = 0; 4983e12c5d1SDavid du Colombier d->atime = gtime(dp->date); 4993e12c5d1SDavid du Colombier d->mtime = d->atime; 500bd389b36SDavid du Colombier return vers; 5013e12c5d1SDavid du Colombier } 5023e12c5d1SDavid du Colombier 5033e12c5d1SDavid du Colombier static char * 5043e12c5d1SDavid du Colombier nstr(uchar *p, int n) 5053e12c5d1SDavid du Colombier { 5063e12c5d1SDavid du Colombier static char buf[132]; 5073e12c5d1SDavid du Colombier char *q = buf; 508bd389b36SDavid du Colombier 5093e12c5d1SDavid du Colombier while(--n >= 0){ 5103e12c5d1SDavid du Colombier if(*p == '\\') 5113e12c5d1SDavid du Colombier *q++ = '\\'; 5123e12c5d1SDavid du Colombier if(' ' <= *p && *p <= '~') 5133e12c5d1SDavid du Colombier *q++ = *p++; 5143e12c5d1SDavid du Colombier else 5153e12c5d1SDavid du Colombier q += sprint(q, "\\%2.2ux", *p++); 5163e12c5d1SDavid du Colombier } 5173e12c5d1SDavid du Colombier *q = 0; 5183e12c5d1SDavid du Colombier return buf; 5193e12c5d1SDavid du Colombier } 5203e12c5d1SDavid du Colombier 5213e12c5d1SDavid du Colombier static char * 5223e12c5d1SDavid du Colombier rdate(uchar *p, int fmt) 5233e12c5d1SDavid du Colombier { 5243e12c5d1SDavid du Colombier static char buf[64]; 5253e12c5d1SDavid du Colombier int htz, s, n; 5263e12c5d1SDavid du Colombier 5273e12c5d1SDavid du Colombier n = sprint(buf, "%2.2d.%2.2d.%2.2d %2.2d:%2.2d:%2.2d", 5283e12c5d1SDavid du Colombier p[0], p[1], p[2], p[3], p[4], p[5]); 5293e12c5d1SDavid du Colombier if(fmt == 'z'){ 5303e12c5d1SDavid du Colombier htz = p[6]; 5313e12c5d1SDavid du Colombier if(htz >= 128){ 5323e12c5d1SDavid du Colombier htz = 256-htz; 5333e12c5d1SDavid du Colombier s = '-'; 5343e12c5d1SDavid du Colombier }else 5353e12c5d1SDavid du Colombier s = '+'; 5363e12c5d1SDavid du Colombier sprint(&buf[n], " (%c%.1f)", s, (float)htz/2); 5373e12c5d1SDavid du Colombier } 5383e12c5d1SDavid du Colombier return buf; 5393e12c5d1SDavid du Colombier } 5403e12c5d1SDavid du Colombier 541bd389b36SDavid du Colombier static char 542bd389b36SDavid du Colombier dmsize[12] = 543bd389b36SDavid du Colombier { 5443e12c5d1SDavid du Colombier 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 5453e12c5d1SDavid du Colombier }; 546bd389b36SDavid du Colombier 5473e12c5d1SDavid du Colombier static int 5483e12c5d1SDavid du Colombier dysize(int y) 5493e12c5d1SDavid du Colombier { 5503e12c5d1SDavid du Colombier 5513e12c5d1SDavid du Colombier if((y%4) == 0) 5523e12c5d1SDavid du Colombier return 366; 5533e12c5d1SDavid du Colombier return 365; 5543e12c5d1SDavid du Colombier } 555bd389b36SDavid du Colombier 5563e12c5d1SDavid du Colombier static long 5573e12c5d1SDavid du Colombier gtime(uchar *p) /* yMdhmsz */ 5583e12c5d1SDavid du Colombier { 5593e12c5d1SDavid du Colombier long t; 5603e12c5d1SDavid du Colombier int i, y, M, d, h, m, s, tz; 5613e12c5d1SDavid du Colombier y=p[0]; M=p[1]; d=p[2]; 5623e12c5d1SDavid du Colombier h=p[3]; m=p[4]; s=p[5]; tz=p[6]; 5633e12c5d1SDavid du Colombier USED(tz); 5643e12c5d1SDavid du Colombier if (y < 70) 5653e12c5d1SDavid du Colombier return 0; 5663e12c5d1SDavid du Colombier if (M < 1 || M > 12) 5673e12c5d1SDavid du Colombier return 0; 5683e12c5d1SDavid du Colombier if (d < 1 || d > dmsize[M-1]) 5693e12c5d1SDavid du Colombier return 0; 5703e12c5d1SDavid du Colombier if (h > 23) 5713e12c5d1SDavid du Colombier return 0; 5723e12c5d1SDavid du Colombier if (m > 59) 5733e12c5d1SDavid du Colombier return 0; 5743e12c5d1SDavid du Colombier if (s > 59) 5753e12c5d1SDavid du Colombier return 0; 5763e12c5d1SDavid du Colombier y += 1900; 5773e12c5d1SDavid du Colombier t = 0; 5783e12c5d1SDavid du Colombier for(i=1970; i<y; i++) 5793e12c5d1SDavid du Colombier t += dysize(i); 5803e12c5d1SDavid du Colombier if (dysize(y)==366 && M >= 3) 5813e12c5d1SDavid du Colombier t++; 5823e12c5d1SDavid du Colombier while(--M) 5833e12c5d1SDavid du Colombier t += dmsize[M-1]; 5843e12c5d1SDavid du Colombier t += d-1; 5853e12c5d1SDavid du Colombier t = 24*t + h; 5863e12c5d1SDavid du Colombier t = 60*t + m; 5873e12c5d1SDavid du Colombier t = 60*t + s; 5883e12c5d1SDavid du Colombier return t; 5893e12c5d1SDavid du Colombier } 5903e12c5d1SDavid du Colombier 5913e12c5d1SDavid du Colombier #define p ((uchar*)arg) 5923e12c5d1SDavid du Colombier 5933e12c5d1SDavid du Colombier static long 5943e12c5d1SDavid du Colombier l16(void *arg) 5953e12c5d1SDavid du Colombier { 5963e12c5d1SDavid du Colombier long v; 5973e12c5d1SDavid du Colombier 5983e12c5d1SDavid du Colombier v = ((long)p[1]<<8)|p[0]; 5993e12c5d1SDavid du Colombier if (v >= 0x8000L) 6003e12c5d1SDavid du Colombier v -= 0x10000L; 6013e12c5d1SDavid du Colombier return v; 6023e12c5d1SDavid du Colombier } 6033e12c5d1SDavid du Colombier 6043e12c5d1SDavid du Colombier static long 6053e12c5d1SDavid du Colombier l32(void *arg) 6063e12c5d1SDavid du Colombier { 6073e12c5d1SDavid du Colombier return ((((((long)p[3]<<8)|p[2])<<8)|p[1])<<8)|p[0]; 6083e12c5d1SDavid du Colombier } 6093e12c5d1SDavid du Colombier 6103e12c5d1SDavid du Colombier #undef p 611