diff options
author | rsc <devnull@localhost> | 2004-03-15 01:56:49 +0000 |
---|---|---|
committer | rsc <devnull@localhost> | 2004-03-15 01:56:49 +0000 |
commit | 3d77c87e81bf16aeaf52ba0f523af6708c5c4964 (patch) | |
tree | 203efc00dc66aaef99a91197dba77ce88edfd0dd /src/cmd/vac/pack.c | |
parent | 333c1dccc2f9af67b9c3d8513cca492d022fab4f (diff) | |
download | plan9port-3d77c87e81bf16aeaf52ba0f523af6708c5c4964.tar.gz plan9port-3d77c87e81bf16aeaf52ba0f523af6708c5c4964.tar.bz2 plan9port-3d77c87e81bf16aeaf52ba0f523af6708c5c4964.zip |
Vac works.
Diffstat (limited to 'src/cmd/vac/pack.c')
-rw-r--r-- | src/cmd/vac/pack.c | 246 |
1 files changed, 174 insertions, 72 deletions
diff --git a/src/cmd/vac/pack.c b/src/cmd/vac/pack.c index b16834d9..074152ea 100644 --- a/src/cmd/vac/pack.c +++ b/src/cmd/vac/pack.c @@ -12,7 +12,7 @@ struct MetaChunk { ushort index; }; -static int stringUnpack(char **s, uchar **p, int *n); +static int stringunpack(char **s, uchar **p, int *n); /* * integer conversion routines @@ -23,35 +23,35 @@ static int stringUnpack(char **s, uchar **p, int *n); #define U48GET(p) (((uvlong)U16GET(p)<<32)|(uvlong)U32GET((p)+2)) #define U64GET(p) (((uvlong)U32GET(p)<<32)|(uvlong)U32GET((p)+4)) -#define U8PUT(p,v) (p)[0]=(v) -#define U16PUT(p,v) (p)[0]=(v)>>8;(p)[1]=(v) -#define U32PUT(p,v) (p)[0]=(v)>>24;(p)[1]=(v)>>16;(p)[2]=(v)>>8;(p)[3]=(v) +#define U8PUT(p,v) (p)[0]=(v)&0xFF +#define U16PUT(p,v) (p)[0]=((v)>>8)&0xFF;(p)[1]=(v)&0xFF +#define U32PUT(p,v) (p)[0]=((v)>>24)&0xFF;(p)[1]=((v)>>16)&0xFF;(p)[2]=((v)>>8)&0xFF;(p)[3]=(v)&0xFF #define U48PUT(p,v,t32) t32=(v)>>32;U16PUT(p,t32);t32=(v);U32PUT((p)+2,t32) #define U64PUT(p,v,t32) t32=(v)>>32;U32PUT(p,t32);t32=(v);U32PUT((p)+4,t32) static int -stringUnpack(char **s, uchar **p, int *n) +stringunpack(char **s, uchar **p, int *n) { int nn; if(*n < 2) - return 0; + return -1; nn = U16GET(*p); *p += 2; *n -= 2; if(nn > *n) - return 0; - *s = vtMemAlloc(nn+1); + return -1; + *s = vtmalloc(nn+1); memmove(*s, *p, nn); (*s)[nn] = 0; *p += nn; *n -= nn; - return 1; + return 0; } static int -stringPack(char *s, uchar *p) +stringpack(char *s, uchar *p) { int n; @@ -63,7 +63,7 @@ stringPack(char *s, uchar *p) int -mbUnpack(MetaBlock *mb, uchar *p, int n) +mbunpack(MetaBlock *mb, uchar *p, int n) { u32int magic; @@ -72,13 +72,13 @@ mbUnpack(MetaBlock *mb, uchar *p, int n) if(n == 0) { memset(mb, 0, sizeof(MetaBlock)); - return 1; + return 0; } magic = U32GET(p); if(magic != MetaMagic && magic != MetaMagic+1) { - vtSetError("bad meta block magic"); - return 0; + werrstr("bad meta block magic"); + return -1; } mb->size = U16GET(p+4); mb->free = U16GET(p+6); @@ -87,22 +87,22 @@ mbUnpack(MetaBlock *mb, uchar *p, int n) mb->unbotch = (magic == MetaMagic+1); if(mb->size > n) { - vtSetError("bad meta block size"); - return 0; + werrstr("bad meta block size"); + return -1; } p += MetaHeaderSize; n -= MetaHeaderSize; USED(p); if(n < mb->maxindex*MetaIndexSize) { - vtSetError("truncated meta block 2"); - return 0; + werrstr("truncated meta block 2"); + return -1; } - return 1; + return 0; } void -mbPack(MetaBlock *mb) +mbpack(MetaBlock *mb) { uchar *p; @@ -117,7 +117,7 @@ mbPack(MetaBlock *mb) void -mbDelete(MetaBlock *mb, int i, MetaEntry *me) +mbdelete(MetaBlock *mb, int i, MetaEntry *me) { uchar *p; int n; @@ -137,7 +137,7 @@ mbDelete(MetaBlock *mb, int i, MetaEntry *me) } void -mbInsert(MetaBlock *mb, int i, MetaEntry *me) +mbinsert(MetaBlock *mb, int i, MetaEntry *me) { uchar *p; int o, n; @@ -161,14 +161,14 @@ mbInsert(MetaBlock *mb, int i, MetaEntry *me) } int -meUnpack(MetaEntry *me, MetaBlock *mb, int i) +meunpack(MetaEntry *me, MetaBlock *mb, int i) { uchar *p; int eo, en; if(i < 0 || i >= mb->nindex) { - vtSetError("bad meta entry index"); - return 0; + werrstr("bad meta entry index"); + return -1; } p = mb->buf + MetaHeaderSize + i*MetaIndexSize; @@ -177,32 +177,32 @@ meUnpack(MetaEntry *me, MetaBlock *mb, int i) if(0)print("eo = %d en = %d\n", eo, en); if(eo < MetaHeaderSize + mb->maxindex*MetaIndexSize) { - vtSetError("corrupted entry in meta block"); - return 0; + werrstr("corrupted entry in meta block"); + return -1; } if(eo+en > mb->size) { - vtSetError("truncated meta block"); - return 0; + werrstr("truncated meta block"); + return -1; } p = mb->buf + eo; /* make sure entry looks ok and includes an elem name */ if(en < 8 || U32GET(p) != DirMagic || en < 8 + U16GET(p+6)) { - vtSetError("corrupted meta block entry"); - return 0; + werrstr("corrupted meta block entry"); + return -1; } me->p = p; me->size = en; - return 1; + return 0; } /* assumes a small amount of checking has been done in mbEntry */ int -meCmp(MetaEntry *me, char *s) +mecmp(MetaEntry *me, char *s) { int n; uchar *p; @@ -230,7 +230,7 @@ meCmp(MetaEntry *me, char *s) } int -meCmpNew(MetaEntry *me, char *s) +mecmpnew(MetaEntry *me, char *s) { int n; uchar *p; @@ -258,9 +258,9 @@ meCmpNew(MetaEntry *me, char *s) } static int -offsetCmp(void *s0, void *s1) +offsetcmp(const void *s0, const void *s1) { - MetaChunk *mc0, *mc1; + const MetaChunk *mc0, *mc1; mc0 = s0; mc1 = s1; @@ -272,13 +272,13 @@ offsetCmp(void *s0, void *s1) } static MetaChunk * -metaChunks(MetaBlock *mb) +metachunks(MetaBlock *mb) { MetaChunk *mc; int oo, o, n, i; uchar *p; - mc = vtMemAlloc(mb->nindex*sizeof(MetaChunk)); + mc = vtmalloc(mb->nindex*sizeof(MetaChunk)); p = mb->buf + MetaHeaderSize; for(i = 0; i<mb->nindex; i++) { mc[i].offset = U16GET(p); @@ -287,7 +287,7 @@ metaChunks(MetaBlock *mb) p += MetaIndexSize; } - qsort(mc, mb->nindex, sizeof(MetaChunk), offsetCmp); + qsort(mc, mb->nindex, sizeof(MetaChunk), offsetcmp); /* check block looks ok */ oo = MetaHeaderSize + mb->maxindex*MetaIndexSize; @@ -307,12 +307,12 @@ metaChunks(MetaBlock *mb) return mc; Err: - vtMemFree(mc); + vtfree(mc); return nil; } static void -mbCompact(MetaBlock *mb, MetaChunk *mc) +mbcompact(MetaBlock *mb, MetaChunk *mc) { int oo, o, n, i; @@ -333,7 +333,7 @@ mbCompact(MetaBlock *mb, MetaChunk *mc) } uchar * -mbAlloc(MetaBlock *mb, int n) +mballoc(MetaBlock *mb, int n) { int i, o; MetaChunk *mc; @@ -346,33 +346,33 @@ mbAlloc(MetaBlock *mb, int n) if(mb->maxsize - mb->size + mb->free < n) return nil; - mc = metaChunks(mb); + mc = metachunks(mb); /* look for hole */ o = MetaHeaderSize + mb->maxindex*MetaIndexSize; for(i=0; i<mb->nindex; i++) { if(mc[i].offset - o >= n) { - vtMemFree(mc); + vtfree(mc); return mb->buf + o; } o = mc[i].offset + mc[i].size; } if(mb->maxsize - o >= n) { - vtMemFree(mc); + vtfree(mc); return mb->buf + o; } /* compact and return off the end */ - mbCompact(mb, mc); - vtMemFree(mc); + mbcompact(mb, mc); + vtfree(mc); assert(mb->maxsize - mb->size >= n); return mb->buf + mb->size; } int -vdSize(VacDir *dir) +vdsize(VacDir *dir) { int n; @@ -399,17 +399,17 @@ vdSize(VacDir *dir) n += 2 + strlen(dir->mid); /* optional sections */ - if(dir->qidSpace) { + if(dir->qidspace) { n += 3 + /* option header */ - 8 + /* qidOffset */ - 8; /* qid Max */ + 8 + /* qid offset */ + 8; /* qid max */ } return n; } void -vdPack(VacDir *dir, MetaEntry *me) +vdpack(VacDir *dir, MetaEntry *me) { uchar *p; ulong t32; @@ -420,7 +420,7 @@ vdPack(VacDir *dir, MetaEntry *me) U16PUT(p+4, 9); /* version */ p += 6; - p += stringPack(dir->elem, p); + p += stringpack(dir->elem, p); U32PUT(p, dir->entry); U32PUT(p+4, dir->gen); @@ -429,9 +429,9 @@ vdPack(VacDir *dir, MetaEntry *me) U64PUT(p+16, dir->qid, t32); p += 24; - p += stringPack(dir->uid, p); - p += stringPack(dir->gid, p); - p += stringPack(dir->mid, p); + p += stringpack(dir->uid, p); + p += stringpack(dir->gid, p); + p += stringpack(dir->mid, p); U32PUT(p, dir->mtime); U32PUT(p+4, dir->mcount); @@ -440,12 +440,12 @@ vdPack(VacDir *dir, MetaEntry *me) U32PUT(p+16, dir->mode); p += 5*4; - if(dir->qidSpace) { + if(dir->qidspace) { U8PUT(p, DirQidSpaceEntry); U16PUT(p+1, 2*8); p += 3; - U64PUT(p, dir->qidOffset, t32); - U64PUT(p+8, dir->qidMax, t32); + U64PUT(p, dir->qidoffset, t32); + U64PUT(p+8, dir->qidmax, t32); } assert(p == me->p + me->size); @@ -453,7 +453,7 @@ vdPack(VacDir *dir, MetaEntry *me) int -vdUnpack(VacDir *dir, MetaEntry *me) +vdunpack(VacDir *dir, MetaEntry *me) { int t, nn, n, version; uchar *p; @@ -483,7 +483,7 @@ if(0)print("vdUnpack: got magic\n"); if(0)print("vdUnpack: got version\n"); /* elem */ - if(!stringUnpack(&dir->elem, &p, &n)) + if(stringunpack(&dir->elem, &p, &n) < 0) goto Err; if(0)print("vdUnpack: got elem\n"); @@ -532,15 +532,15 @@ if(0)print("vdUnpack: got qid\n"); } /* uid */ - if(!stringUnpack(&dir->uid, &p, &n)) + if(stringunpack(&dir->uid, &p, &n) < 0) goto Err; /* gid */ - if(!stringUnpack(&dir->gid, &p, &n)) + if(stringunpack(&dir->gid, &p, &n) < 0) goto Err; /* mid */ - if(!stringUnpack(&dir->mid, &p, &n)) + if(stringunpack(&dir->mid, &p, &n) < 0) goto Err; if(0)print("vdUnpack: got ids\n"); @@ -584,11 +584,11 @@ if(0)print("vdUnpack: got times\n"); break; break; case DirQidSpaceEntry: - if(dir->qidSpace || nn != 16) + if(dir->qidspace || nn != 16) goto Err; - dir->qidSpace = 1; - dir->qidOffset = U64GET(p); - dir->qidMax = U64GET(p+8); + dir->qidspace = 1; + dir->qidoffset = U64GET(p); + dir->qidmax = U64GET(p+8); break; } p += nn; @@ -600,10 +600,112 @@ if(0)print("vdUnpack: got options\n"); goto Err; if(0)print("vdUnpack: correct size\n"); - return 1; + return 0; Err: if(0)print("vdUnpack: XXXXXXXXXXXX EbadMeta\n"); - vtSetError(EBadMeta); - vdCleanup(dir); - return 0; + werrstr(EBadMeta); + vdcleanup(dir); + return -1; +} + +void +vdcleanup(VacDir *dir) +{ + vtfree(dir->elem); + dir->elem = nil; + vtfree(dir->uid); + dir->uid = nil; + vtfree(dir->gid); + dir->gid = nil; + vtfree(dir->mid); + dir->mid = nil; +} + +void +vdcopy(VacDir *dst, VacDir *src) +{ + *dst = *src; + dst->elem = vtstrdup(dst->elem); + dst->uid = vtstrdup(dst->uid); + dst->gid = vtstrdup(dst->gid); + dst->mid = vtstrdup(dst->mid); +} + +int +mbsearch(MetaBlock *mb, char *elem, int *ri, MetaEntry *me) +{ + int i; + int b, t, x; + + /* binary search within block */ + b = 0; + t = mb->nindex; + while(b < t) { + i = (b+t)>>1; + if(meunpack(me, mb, i) < 0) + return 0; + if(mb->unbotch) + x = mecmpnew(me, elem); + else + x = mecmp(me, elem); + + if(x == 0) { + *ri = i; + return 1; + } + + if(x < 0) + b = i+1; + else /* x > 0 */ + t = i; + } + + assert(b == t); + + *ri = b; /* b is the index to insert this entry */ + memset(me, 0, sizeof(*me)); + + return 1; +} + +void +mbinit(MetaBlock *mb, uchar *p, int n) +{ + memset(mb, 0, sizeof(MetaBlock)); + mb->maxsize = n; + mb->buf = p; + mb->maxindex = n/100; + mb->size = MetaHeaderSize + mb->maxindex*MetaIndexSize; +} + +int +mbresize(MetaBlock *mb, MetaEntry *me, int n) +{ + uchar *p, *ep; + + /* easy case */ + if(n <= me->size){ + me->size = n; + return 0; + } + + /* try and expand entry */ + + p = me->p + me->size; + ep = mb->buf + mb->maxsize; + while(p < ep && *p == 0) + p++; + if(n <= p - me->p){ + me->size = n; + return 0; + } + + p = mballoc(mb, n); + if(p != nil){ + me->p = p; + me->size = n; + return 0; + } + + return -1; } |