aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/9660/conform.c
diff options
context:
space:
mode:
authorwkj <devnull@localhost>2004-06-17 01:47:21 +0000
committerwkj <devnull@localhost>2004-06-17 01:47:21 +0000
commit7285a491c1ce1e630a0751b1011fd33e6b17234b (patch)
treeb2b2e24e333fa4660325a35f6c0f1d333e50e797 /src/cmd/9660/conform.c
parente1dddc053287874e82e2b67f95ccee7d7bc63e22 (diff)
downloadplan9port-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.c141
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);
+}