diff --git a/sys/src/cmd/dossrv/dat.h b/sys/src/cmd/dossrv/dat.h index c2cd53bac..5823e55bd 100644 --- a/sys/src/cmd/dossrv/dat.h +++ b/sys/src/cmd/dossrv/dat.h @@ -142,7 +142,8 @@ enum DOSDIRSIZE = 32, DOSEMPTY = 0xe5, /* first char in name if entry is unused */ DOSRUNE = 13, /* runes per dosdir in a long file name */ - DOSNAMELEN = 261 /* max dos file name length */ + DOSNAMELEN = 261, /* max dos file name length */ + MAXFILELEN = 0xFFFFFFFFUL, }; struct Dosdir{ diff --git a/sys/src/cmd/dossrv/dosfs.c b/sys/src/cmd/dossrv/dosfs.c index eff5e2a8f..783e66d21 100644 --- a/sys/src/cmd/dossrv/dosfs.c +++ b/sys/src/cmd/dossrv/dosfs.c @@ -305,7 +305,7 @@ mk8dot3name(Xfile *f, Dosptr *ndp, char *name, char *sname) * fill in a directory entry for a new file */ static int -mkdentry(Xfs *xf, Dosptr *ndp, char *name, char *sname, int longtype, int nattr, long start, long length) +mkdentry(Xfs *xf, Dosptr *ndp, char *name, char *sname, int longtype, int nattr, long start, ulong length) { Dosdir *nd; @@ -333,10 +333,7 @@ mkdentry(Xfs *xf, Dosptr *ndp, char *name, char *sname, int longtype, int nattr, PSHORT(nd->ctime, GSHORT(nd->time)); nd->ctimetenth = 0; putstart(xf, nd, start); - nd->length[0] = length; - nd->length[1] = length>>8; - nd->length[2] = length>>16; - nd->length[3] = length>>24; + PLONG(nd->length, length); ndp->p->flags |= BMOD; @@ -506,16 +503,13 @@ rread(void) if (!(f=xfile(req->fid, Asis)) || !(f->flags&Oread)) goto error; if(req->count > sizeof repdata) - req->count = sizeof repdata; - if(f->qid.type & QTDIR){ - if(getfile(f) < 0) - goto error; + req->count = sizeof repdata; + if(getfile(f) < 0) + goto error; + if(f->qid.type & QTDIR) r = readdir(f, repdata, req->offset, req->count); - }else{ - if(getfile(f) < 0) - goto error; + else r = readfile(f, repdata, req->offset, req->count); - } putfile(f); if(r < 0){ error: @@ -711,8 +705,8 @@ rwstat(void) Iosect *parp; Dosdir *pard, *d, od; char sname[13]; - ulong oaddr, ooffset; - long start, length; + ulong oaddr, ooffset, length; + long start; int i, longtype, changes, attr; f = xfile(req->fid, Asis); diff --git a/sys/src/cmd/dossrv/dossubs.c b/sys/src/cmd/dossrv/dossubs.c index 8c4af3701..a48f735fb 100644 --- a/sys/src/cmd/dossrv/dossubs.c +++ b/sys/src/cmd/dossrv/dossubs.c @@ -674,7 +674,7 @@ emptydir(Xfile *f) } long -readdir(Xfile *f, void *vbuf, long offset, long count) +readdir(Xfile *f, void *vbuf, vlong offset, long count) { Xfs *xf; Dosbpb *bp; @@ -921,7 +921,7 @@ error: } long -readfile(Xfile *f, void *vbuf, long offset, long count) +readfile(Xfile *f, void *vbuf, vlong offset, long count) { Xfs *xf = f->xf; Dosbpb *bp = xf->ptr; @@ -930,7 +930,12 @@ readfile(Xfile *f, void *vbuf, long offset, long count) int isect, addr, o, c; Iosect *p; uchar *buf; - long length, rcnt; + ulong length, rcnt; + + if(offset >= MAXFILELEN) + return 0; + if(offset+count > MAXFILELEN) + count = MAXFILELEN - offset; rcnt = 0; length = GLONG(d->length); @@ -961,17 +966,24 @@ readfile(Xfile *f, void *vbuf, long offset, long count) } long -writefile(Xfile *f, void *vbuf, long offset, long count) +writefile(Xfile *f, void *vbuf, vlong offset, long count) { Xfs *xf = f->xf; Dosbpb *bp = xf->ptr; Dosptr *dp = f->ptr; Dosdir *d = dp->d; - int isect, addr = 0, o, c; + int isect, addr, o, c; Iosect *p; uchar *buf; - long length, rcnt = 0, dlen; + ulong length, rcnt, dlen; + if(offset >= MAXFILELEN) + return 0; + if(offset+count > MAXFILELEN) + count = MAXFILELEN - offset; + + rcnt = 0; + addr = 0; buf = vbuf; isect = offset/bp->sectsize; o = offset%bp->sectsize; @@ -997,7 +1009,7 @@ writefile(Xfile *f, void *vbuf, long offset, long count) rcnt += c; o = 0; } - if(rcnt <= 0 && addr < 0) + if(addr < 0) return -1; length = 0; dlen = GLONG(d->length); @@ -1016,13 +1028,17 @@ writefile(Xfile *f, void *vbuf, long offset, long count) } int -truncfile(Xfile *f, long length) +truncfile(Xfile *f, vlong length) { Xfs *xf = f->xf; Dosbpb *bp = xf->ptr; Dosptr *dp = f->ptr; Dosdir *d = dp->d; - long clust, next, n; + long clust, next; + vlong n; + + if(length > MAXFILELEN) + return -1; mlock(bp); clust = getstart(f->xf, d); @@ -1093,7 +1109,7 @@ getdir(Xfs *xfs, Dir *dp, Dosdir *d, int addr, int offset) dp->mode |= DMDIR|0111; dp->length = 0; }else - dp->length = GLONG(d->length); + dp->length = (ulong)GLONG(d->length); if(d->attr & DSYSTEM){ dp->mode |= DMEXCL; if(iscontig(xfs, d)) @@ -1898,7 +1914,7 @@ dirdump(void *vdbuf) i = GSHORT(d->adate); s = seprint(s, ebuf, " %2.2d.%2.2d.%2.2d", 80+(i>>9), (i>>5)&15, i&31); - seprint(s, ebuf, " %d %d", GSHORT(d->start), GSHORT(d->length)); + seprint(s, ebuf, " %d %lud", GSHORT(d->start), (ulong)GLONG(d->length)); } chat("%s\n", buf); } diff --git a/sys/src/cmd/dossrv/fns.h b/sys/src/cmd/dossrv/fns.h index 181d10564..277899e17 100644 --- a/sys/src/cmd/dossrv/fns.h +++ b/sys/src/cmd/dossrv/fns.h @@ -46,8 +46,8 @@ void rauth(void); void rclone(void); void rclunk(void); void rcreate(void); -long readdir(Xfile*, void*, long, long); -long readfile(Xfile*, void*, long, long); +long readdir(Xfile*, void*, vlong, long); +long readfile(Xfile*, void*, vlong, long); void refxfs(Xfs*, int); void rflush(void); void rootfile(Xfile*); @@ -61,10 +61,10 @@ void rwstat(void); void rversion(void); int searchdir(Xfile*, char*, Dosptr*, int, int); long sect2clust(Dosbpb*, long); -int truncfile(Xfile*, long length); +int truncfile(Xfile*, vlong length); int utftorunes(Rune*, char*, int); int walkup(Xfile*, Dosptr*); -long writefile(Xfile*, void*, long, long); +long writefile(Xfile*, void*, vlong, long); char *xerrstr(int); Xfile *xfile(int, int); int xfspurge(void);