diff options
author | wkj <devnull@localhost> | 2004-06-17 01:47:21 +0000 |
---|---|---|
committer | wkj <devnull@localhost> | 2004-06-17 01:47:21 +0000 |
commit | 7285a491c1ce1e630a0751b1011fd33e6b17234b (patch) | |
tree | b2b2e24e333fa4660325a35f6c0f1d333e50e797 /src/cmd/9660/conform.c | |
parent | e1dddc053287874e82e2b67f95ccee7d7bc63e22 (diff) | |
download | plan9port-7285a491c1ce1e630a0751b1011fd33e6b17234b.tar.gz plan9port-7285a491c1ce1e630a0751b1011fd33e6b17234b.tar.bz2 plan9port-7285a491c1ce1e630a0751b1011fd33e6b17234b.zip |
Dump9660 (and mk9660). Until we either do something
intelligent with symlinks or put in a switch for things
like dump9660, this is of rather limited utility under Unix.
Diffstat (limited to 'src/cmd/9660/conform.c')
-rw-r--r-- | src/cmd/9660/conform.c | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/src/cmd/9660/conform.c b/src/cmd/9660/conform.c new file mode 100644 index 00000000..530b4d56 --- /dev/null +++ b/src/cmd/9660/conform.c @@ -0,0 +1,141 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> +#include <libsec.h> +#include <ctype.h> +#include "iso9660.h" + +/* + * We keep an array sorted by bad atom pointer. + * The theory is that since we don't free memory very often, + * the array will be mostly sorted already and insertions will + * usually be near the end, so we won't spend much time + * keeping it sorted. + */ + +/* + * Binary search a Tx list. + * If no entry is found, return a pointer to + * where a new such entry would go. + */ +static Tx* +txsearch(char *atom, Tx *t, int n) +{ + while(n > 0) { + if(atom < t[n/2].bad) + n = n/2; + else if(atom > t[n/2].bad) { + t += n/2+1; + n -= (n/2+1); + } else + return &t[n/2]; + } + return t; +} + +void +addtx(char *b, char *g) +{ + Tx *t; + Conform *c; + + if(map == nil) + map = emalloc(sizeof(*map)); + c = map; + + if(c->nt%32 == 0) + c->t = erealloc(c->t, (c->nt+32)*sizeof(c->t[0])); + t = txsearch(b, c->t, c->nt); + if(t < c->t+c->nt && t->bad == b) { + fprint(2, "warning: duplicate entry for %s in _conform.map\n", b); + return; + } + + if(t != c->t+c->nt) + memmove(t+1, t, (c->t+c->nt - t)*sizeof(Tx)); + t->bad = b; + t->good = g; + c->nt++; +} + +char* +conform(char *s, int isdir) +{ + Tx *t; + char buf[10], *g; + Conform *c; + + c = map; + s = atom(s); + if(c){ + t = txsearch(s, c->t, c->nt); + if(t < c->t+c->nt && t->bad == s) + return t->good; + } + + sprint(buf, "%c%.6d", isdir ? 'D' : 'F', c ? c->nt : 0); + g = atom(buf); + addtx(s, g); + return g; +} + +#ifdef NOTUSED +static int +isalldigit(char *s) +{ + while(*s) + if(!isdigit(*s++)) + return 0; + return 1; +} +#endif + +static int +goodcmp(const void *va, const void *vb) +{ + Tx *a, *b; + + a = (Tx*)va; + b = (Tx*)vb; + return strcmp(a->good, b->good); +} + +static int +badatomcmp(const void *va, const void *vb) +{ + Tx *a, *b; + + a = (Tx*)va; + b = (Tx*)vb; + if(a->good < b->good) + return -1; + if(a->good > b->good) + return 1; + return 0; +} + +void +wrconform(Cdimg *cd, int n, ulong *pblock, ulong *plength) +{ + char buf[1024]; + int i; + Conform *c; + + c = map; + *pblock = cd->nextblock; + if(c==nil || n==c->nt){ + *plength = 0; + return; + } + + Cwseek(cd, cd->nextblock*Blocksize); + qsort(c->t, c->nt, sizeof(c->t[0]), goodcmp); + for(i=n; i<c->nt; i++) { + snprint(buf, sizeof buf, "%s %s\n", c->t[i].good, c->t[i].bad); + Cwrite(cd, buf, strlen(buf)); + } + qsort(c->t, c->nt, sizeof(c->t[0]), badatomcmp); + *plength = Cwoffset(cd) - *pblock*Blocksize; + chat("write _conform.map at %lud+%lud\n", *pblock, *plength); + Cpadblock(cd); +} |