Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include <u.h>
2
#include <libc.h>
3
#include <bio.h>
4
#include <libsec.h>
5
#include <ctype.h>
6
#include "iso9660.h"
7
 
8
/*
9
 * We keep an array sorted by bad atom pointer.
10
 * The theory is that since we don't free memory very often,
11
 * the array will be mostly sorted already and insertions will
12
 * usually be near the end, so we won't spend much time
13
 * keeping it sorted.
14
 */
15
 
16
/*
17
 * Binary search a Tx list.
18
 * If no entry is found, return a pointer to
19
 * where a new such entry would go.
20
 */
21
static Tx*
22
txsearch(char *atom, Tx *t, int n)
23
{
24
	while(n > 0) {
25
		if(atom < t[n/2].bad)
26
			n = n/2;
27
		else if(atom > t[n/2].bad) {
28
			t += n/2+1;
29
			n -= (n/2+1);
30
		} else
31
			return &t[n/2];
32
	}
33
	return t;
34
}
35
 
36
void
37
addtx(char *b, char *g)
38
{
39
	Tx *t;
40
	Conform *c;
41
 
42
	if(map == nil)
43
		map = emalloc(sizeof(*map));
44
	c = map;
45
 
46
	if(c->nt%32 == 0)
47
		c->t = erealloc(c->t, (c->nt+32)*sizeof(c->t[0]));
48
	t = txsearch(b, c->t, c->nt);
49
	if(t < c->t+c->nt && t->bad == b) {
50
		fprint(2, "warning: duplicate entry for %s in _conform.map\n", b);
51
		return;
52
	}
53
 
54
	if(t != c->t+c->nt)
55
		memmove(t+1, t, (c->t+c->nt - t)*sizeof(Tx));
56
	t->bad = b;
57
	t->good = g;
58
	c->nt++;
59
}
60
 
61
char*
62
conform(char *s, int isdir)
63
{
64
	Tx *t;
65
	char buf[10], *g;
66
	Conform *c;
67
 
68
	c = map;
69
	s = atom(s);
70
	if(c){
71
		t = txsearch(s, c->t, c->nt);
72
		if(t < c->t+c->nt && t->bad == s)
73
			return t->good;
74
	}
75
 
76
	sprint(buf, "%c%.6d", isdir ? 'D' : 'F', c ? c->nt : 0);
77
	g = atom(buf);
78
	addtx(s, g);
79
	return g;
80
}
81
 
82
#ifdef NOTUSED
83
static int
84
isalldigit(char *s)
85
{
86
	while(*s)
87
		if(!isdigit(*s++))
88
			return 0;
89
	return 1;
90
}
91
#endif
92
 
93
static int
94
goodcmp(const void *va, const void *vb)
95
{
96
	Tx *a, *b;
97
 
98
	a = (Tx*)va;
99
	b = (Tx*)vb;
100
	return strcmp(a->good, b->good);
101
}
102
 
103
static int
104
badatomcmp(const void *va, const void *vb)
105
{
106
	Tx *a, *b;
107
 
108
	a = (Tx*)va;
109
	b = (Tx*)vb;
110
	if(a->good < b->good)
111
		return -1;
112
	if(a->good > b->good)
113
		return 1;
114
	return 0;
115
}
116
 
117
void
118
wrconform(Cdimg *cd, int n, ulong *pblock, uvlong *plength)
119
{
120
	char buf[1024];
121
	int i;
122
	Conform *c;
123
 
124
	c = map;
125
	*pblock = cd->nextblock;
126
	if(c==nil || n==c->nt){
127
		*plength = 0;
128
		return;
129
	}
130
 
131
	Cwseek(cd, (vlong)cd->nextblock * Blocksize);
132
	qsort(c->t, c->nt, sizeof(c->t[0]), goodcmp);
133
	for(i=n; i<c->nt; i++) {
134
		snprint(buf, sizeof buf, "%s %s\n", c->t[i].good, c->t[i].bad);
135
		Cwrite(cd, buf, strlen(buf));
136
	}
137
	qsort(c->t, c->nt, sizeof(c->t[0]), badatomcmp);
138
	*plength = Cwoffset(cd) - (vlong)*pblock * Blocksize;
139
	chat("write _conform.map at %lud+%llud\n", *pblock, *plength);
140
	Cpadblock(cd);
141
}