xref: /plan9/sys/src/cmd/disk/9660/conform.c (revision 73ee67a1775bb9176ad6f77775e030678f092526)
180ee5cbfSDavid du Colombier #include <u.h>
280ee5cbfSDavid du Colombier #include <libc.h>
380ee5cbfSDavid du Colombier #include <bio.h>
480ee5cbfSDavid du Colombier #include <libsec.h>
580ee5cbfSDavid du Colombier #include <ctype.h>
680ee5cbfSDavid du Colombier #include "iso9660.h"
780ee5cbfSDavid du Colombier 
880ee5cbfSDavid du Colombier /*
980ee5cbfSDavid du Colombier  * We keep an array sorted by bad atom pointer.
1080ee5cbfSDavid du Colombier  * The theory is that since we don't free memory very often,
1180ee5cbfSDavid du Colombier  * the array will be mostly sorted already and insertions will
1280ee5cbfSDavid du Colombier  * usually be near the end, so we won't spend much time
1380ee5cbfSDavid du Colombier  * keeping it sorted.
1480ee5cbfSDavid du Colombier  */
1580ee5cbfSDavid du Colombier 
1680ee5cbfSDavid du Colombier /*
1780ee5cbfSDavid du Colombier  * Binary search a Tx list.
1880ee5cbfSDavid du Colombier  * If no entry is found, return a pointer to
1980ee5cbfSDavid du Colombier  * where a new such entry would go.
2080ee5cbfSDavid du Colombier  */
2180ee5cbfSDavid du Colombier static Tx*
txsearch(char * atom,Tx * t,int n)2280ee5cbfSDavid du Colombier txsearch(char *atom, Tx *t, int n)
2380ee5cbfSDavid du Colombier {
2480ee5cbfSDavid du Colombier 	while(n > 0) {
2580ee5cbfSDavid du Colombier 		if(atom < t[n/2].bad)
2680ee5cbfSDavid du Colombier 			n = n/2;
2780ee5cbfSDavid du Colombier 		else if(atom > t[n/2].bad) {
2880ee5cbfSDavid du Colombier 			t += n/2+1;
2980ee5cbfSDavid du Colombier 			n -= (n/2+1);
3080ee5cbfSDavid du Colombier 		} else
3180ee5cbfSDavid du Colombier 			return &t[n/2];
3280ee5cbfSDavid du Colombier 	}
3380ee5cbfSDavid du Colombier 	return t;
3480ee5cbfSDavid du Colombier }
3580ee5cbfSDavid du Colombier 
3680ee5cbfSDavid du Colombier void
addtx(char * b,char * g)3780ee5cbfSDavid du Colombier addtx(char *b, char *g)
3880ee5cbfSDavid du Colombier {
3980ee5cbfSDavid du Colombier 	Tx *t;
4080ee5cbfSDavid du Colombier 	Conform *c;
4180ee5cbfSDavid du Colombier 
4280ee5cbfSDavid du Colombier 	if(map == nil)
4380ee5cbfSDavid du Colombier 		map = emalloc(sizeof(*map));
4480ee5cbfSDavid du Colombier 	c = map;
4580ee5cbfSDavid du Colombier 
4680ee5cbfSDavid du Colombier 	if(c->nt%32 == 0)
4780ee5cbfSDavid du Colombier 		c->t = erealloc(c->t, (c->nt+32)*sizeof(c->t[0]));
4880ee5cbfSDavid du Colombier 	t = txsearch(b, c->t, c->nt);
4980ee5cbfSDavid du Colombier 	if(t < c->t+c->nt && t->bad == b) {
5080ee5cbfSDavid du Colombier 		fprint(2, "warning: duplicate entry for %s in _conform.map\n", b);
5180ee5cbfSDavid du Colombier 		return;
5280ee5cbfSDavid du Colombier 	}
5380ee5cbfSDavid du Colombier 
5480ee5cbfSDavid du Colombier 	if(t != c->t+c->nt)
5580ee5cbfSDavid du Colombier 		memmove(t+1, t, (c->t+c->nt - t)*sizeof(Tx));
5680ee5cbfSDavid du Colombier 	t->bad = b;
5780ee5cbfSDavid du Colombier 	t->good = g;
5880ee5cbfSDavid du Colombier 	c->nt++;
5980ee5cbfSDavid du Colombier }
6080ee5cbfSDavid du Colombier 
6180ee5cbfSDavid du Colombier char*
conform(char * s,int isdir)6280ee5cbfSDavid du Colombier conform(char *s, int isdir)
6380ee5cbfSDavid du Colombier {
6480ee5cbfSDavid du Colombier 	Tx *t;
6580ee5cbfSDavid du Colombier 	char buf[10], *g;
6680ee5cbfSDavid du Colombier 	Conform *c;
6780ee5cbfSDavid du Colombier 
6880ee5cbfSDavid du Colombier 	c = map;
6980ee5cbfSDavid du Colombier 	s = atom(s);
7080ee5cbfSDavid du Colombier 	if(c){
7180ee5cbfSDavid du Colombier 		t = txsearch(s, c->t, c->nt);
7280ee5cbfSDavid du Colombier 		if(t < c->t+c->nt && t->bad == s)
7380ee5cbfSDavid du Colombier 			return t->good;
7480ee5cbfSDavid du Colombier 	}
7580ee5cbfSDavid du Colombier 
7680ee5cbfSDavid du Colombier 	sprint(buf, "%c%.6d", isdir ? 'D' : 'F', c ? c->nt : 0);
7780ee5cbfSDavid du Colombier 	g = atom(buf);
7880ee5cbfSDavid du Colombier 	addtx(s, g);
7980ee5cbfSDavid du Colombier 	return g;
8080ee5cbfSDavid du Colombier }
8180ee5cbfSDavid du Colombier 
8280ee5cbfSDavid du Colombier #ifdef NOTUSED
8380ee5cbfSDavid du Colombier static int
isalldigit(char * s)8480ee5cbfSDavid du Colombier isalldigit(char *s)
8580ee5cbfSDavid du Colombier {
8680ee5cbfSDavid du Colombier 	while(*s)
8780ee5cbfSDavid du Colombier 		if(!isdigit(*s++))
8880ee5cbfSDavid du Colombier 			return 0;
8980ee5cbfSDavid du Colombier 	return 1;
9080ee5cbfSDavid du Colombier }
9180ee5cbfSDavid du Colombier #endif
9280ee5cbfSDavid du Colombier 
9380ee5cbfSDavid du Colombier static int
goodcmp(const void * va,const void * vb)9480ee5cbfSDavid du Colombier goodcmp(const void *va, const void *vb)
9580ee5cbfSDavid du Colombier {
9680ee5cbfSDavid du Colombier 	Tx *a, *b;
9780ee5cbfSDavid du Colombier 
9880ee5cbfSDavid du Colombier 	a = (Tx*)va;
9980ee5cbfSDavid du Colombier 	b = (Tx*)vb;
10080ee5cbfSDavid du Colombier 	return strcmp(a->good, b->good);
10180ee5cbfSDavid du Colombier }
10280ee5cbfSDavid du Colombier 
10380ee5cbfSDavid du Colombier static int
badatomcmp(const void * va,const void * vb)10480ee5cbfSDavid du Colombier badatomcmp(const void *va, const void *vb)
10580ee5cbfSDavid du Colombier {
10680ee5cbfSDavid du Colombier 	Tx *a, *b;
10780ee5cbfSDavid du Colombier 
10880ee5cbfSDavid du Colombier 	a = (Tx*)va;
10980ee5cbfSDavid du Colombier 	b = (Tx*)vb;
11080ee5cbfSDavid du Colombier 	if(a->good < b->good)
11180ee5cbfSDavid du Colombier 		return -1;
11280ee5cbfSDavid du Colombier 	if(a->good > b->good)
11380ee5cbfSDavid du Colombier 		return 1;
11480ee5cbfSDavid du Colombier 	return 0;
11580ee5cbfSDavid du Colombier }
11680ee5cbfSDavid du Colombier 
11780ee5cbfSDavid du Colombier void
wrconform(Cdimg * cd,int n,ulong * pblock,uvlong * plength)118*73ee67a1SDavid du Colombier wrconform(Cdimg *cd, int n, ulong *pblock, uvlong *plength)
11980ee5cbfSDavid du Colombier {
1209a747e4fSDavid du Colombier 	char buf[1024];
12180ee5cbfSDavid du Colombier 	int i;
12280ee5cbfSDavid du Colombier 	Conform *c;
12380ee5cbfSDavid du Colombier 
12480ee5cbfSDavid du Colombier 	c = map;
12580ee5cbfSDavid du Colombier 	*pblock = cd->nextblock;
12680ee5cbfSDavid du Colombier 	if(c==nil || n==c->nt){
12780ee5cbfSDavid du Colombier 		*plength = 0;
12880ee5cbfSDavid du Colombier 		return;
12980ee5cbfSDavid du Colombier 	}
13080ee5cbfSDavid du Colombier 
131*73ee67a1SDavid du Colombier 	Cwseek(cd, (vlong)cd->nextblock * Blocksize);
13280ee5cbfSDavid du Colombier 	qsort(c->t, c->nt, sizeof(c->t[0]), goodcmp);
13380ee5cbfSDavid du Colombier 	for(i=n; i<c->nt; i++) {
13480ee5cbfSDavid du Colombier 		snprint(buf, sizeof buf, "%s %s\n", c->t[i].good, c->t[i].bad);
13580ee5cbfSDavid du Colombier 		Cwrite(cd, buf, strlen(buf));
13680ee5cbfSDavid du Colombier 	}
13780ee5cbfSDavid du Colombier 	qsort(c->t, c->nt, sizeof(c->t[0]), badatomcmp);
138*73ee67a1SDavid du Colombier 	*plength = Cwoffset(cd) - (vlong)*pblock * Blocksize;
139*73ee67a1SDavid du Colombier 	chat("write _conform.map at %lud+%llud\n", *pblock, *plength);
14080ee5cbfSDavid du Colombier 	Cpadblock(cd);
14180ee5cbfSDavid du Colombier }
142