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 "stdinc.h"
2
#include "dat.h"
3
#include "fns.h"
4
 
5
static char vcmagic[] = "venti config\n";
6
 
7
enum {
8
	Maxconfig = 8 * 1024,
9
	Maglen = sizeof vcmagic - 1,
10
};
11
 
12
int
13
readifile(IFile *f, char *name)
14
{
15
	Part *p;
16
	ZBlock *b;
17
	u8int *z;
18
 
19
	p = initpart(name, OREAD);
20
	if(p == nil)
21
		return -1;
22
	b = alloczblock(Maxconfig+1, 1, 0);
23
	if(b == nil){
24
		seterr(EOk, "can't alloc for %s: %R", name);
25
		return -1;
26
	}
27
	if(p->size > PartBlank){
28
		/*
29
		 * this is likely a real venti partition, in which case we're
30
		 * looking for the config file stored as 8k at end of PartBlank.
31
		 */
32
		if(readpart(p, PartBlank-Maxconfig, b->data, Maxconfig) < 0){
33
			seterr(EOk, "can't read %s: %r", name);
34
			freezblock(b);
35
			freepart(p);
36
			return -1;
37
		}
38
		b->data[Maxconfig] = '\0';
39
		if(memcmp(b->data, vcmagic, Maglen) != 0){
40
			seterr(EOk, "bad venti config magic in %s", name);
41
			freezblock(b);
42
			freepart(p);
43
			return -1;
44
		}
45
		/*
46
		 * if we change b->data+b->_size, freezblock
47
		 * will blow an assertion, so don't.
48
		 */
49
		b->data  += Maglen;
50
		b->_size -= Maglen;
51
		b->len   -= Maglen;
52
		z = memchr(b->data, '\0', b->len);
53
		if(z)
54
			b->len = z - b->data;
55
	}else if(p->size > Maxconfig){
56
		seterr(EOk, "config file is too large");
57
		freepart(p);
58
		freezblock(b);
59
		return -1;
60
	}else{
61
		freezblock(b);
62
		b = readfile(name);
63
		if(b == nil){
64
			freepart(p);
65
			return -1;
66
		}
67
	}
68
	freepart(p);
69
	f->name = name;
70
	f->b = b;
71
	f->pos = 0;
72
	return 0;
73
}
74
 
75
void
76
freeifile(IFile *f)
77
{
78
	freezblock(f->b);
79
	f->b = nil;
80
	f->pos = 0;
81
}
82
 
83
int
84
partifile(IFile *f, Part *part, u64int start, u32int size)
85
{
86
	ZBlock *b;
87
 
88
	b = alloczblock(size, 0, part->blocksize);
89
	if(b == nil)
90
		return -1;
91
	if(readpart(part, start, b->data, size) < 0){
92
		seterr(EAdmin, "can't read %s: %r", part->name);
93
		freezblock(b);
94
		return -1;
95
	}
96
	f->name = part->name;
97
	f->b = b;
98
	f->pos = 0;
99
	return 0;
100
}
101
 
102
/*
103
 * return the next non-blank input line,
104
 * stripped of leading white space and with # comments eliminated
105
 */
106
char*
107
ifileline(IFile *f)
108
{
109
	char *s, *e, *t;
110
	int c;
111
 
112
	for(;;){
113
		s = (char*)&f->b->data[f->pos];
114
		e = memchr(s, '\n', f->b->len - f->pos);
115
		if(e == nil)
116
			return nil;
117
		*e++ = '\0';
118
		f->pos = e - (char*)f->b->data;
119
		t = strchr(s, '#');
120
		if(t != nil)
121
			*t = '\0';
122
		for(; c = *s; s++)
123
			if(c != ' ' && c != '\t' && c != '\r')
124
				return s;
125
	}
126
}
127
 
128
int
129
ifilename(IFile *f, char *dst)
130
{
131
	char *s;
132
 
133
	s = ifileline(f);
134
	if(s == nil || strlen(s) >= ANameSize)
135
		return -1;
136
	namecp(dst, s);
137
	return 0;
138
}
139
 
140
int
141
ifileu32int(IFile *f, u32int *r)
142
{
143
	char *s;
144
 
145
	s = ifileline(f);
146
	if(s == nil)
147
		return -1;
148
	return stru32int(s, r);
149
}