xref: /plan9/sys/src/cmd/venti/srv/ifile.c (revision fececb924262ae5acb31c5c448a4a6a523887b15)
1368c31abSDavid du Colombier #include "stdinc.h"
2368c31abSDavid du Colombier #include "dat.h"
3368c31abSDavid du Colombier #include "fns.h"
4368c31abSDavid du Colombier 
5*fececb92SDavid du Colombier static char vcmagic[] = "venti config\n";
6*fececb92SDavid du Colombier 
7*fececb92SDavid du Colombier enum {
8*fececb92SDavid du Colombier 	Maxconfig = 8 * 1024,
9*fececb92SDavid du Colombier 	Maglen = sizeof vcmagic - 1,
10*fececb92SDavid du Colombier };
11*fececb92SDavid du Colombier 
12368c31abSDavid du Colombier int
readifile(IFile * f,char * name)13368c31abSDavid du Colombier readifile(IFile *f, char *name)
14368c31abSDavid du Colombier {
15368c31abSDavid du Colombier 	Part *p;
16368c31abSDavid du Colombier 	ZBlock *b;
17368c31abSDavid du Colombier 	u8int *z;
18368c31abSDavid du Colombier 
19368c31abSDavid du Colombier 	p = initpart(name, OREAD);
20368c31abSDavid du Colombier 	if(p == nil)
21368c31abSDavid du Colombier 		return -1;
22*fececb92SDavid du Colombier 	b = alloczblock(Maxconfig+1, 1, 0);
23368c31abSDavid du Colombier 	if(b == nil){
24368c31abSDavid du Colombier 		seterr(EOk, "can't alloc for %s: %R", name);
25368c31abSDavid du Colombier 		return -1;
26368c31abSDavid du Colombier 	}
27368c31abSDavid du Colombier 	if(p->size > PartBlank){
28368c31abSDavid du Colombier 		/*
29*fececb92SDavid du Colombier 		 * this is likely a real venti partition, in which case we're
30*fececb92SDavid du Colombier 		 * looking for the config file stored as 8k at end of PartBlank.
31368c31abSDavid du Colombier 		 */
32*fececb92SDavid du Colombier 		if(readpart(p, PartBlank-Maxconfig, b->data, Maxconfig) < 0){
33368c31abSDavid du Colombier 			seterr(EOk, "can't read %s: %r", name);
34368c31abSDavid du Colombier 			freezblock(b);
35368c31abSDavid du Colombier 			freepart(p);
36368c31abSDavid du Colombier 			return -1;
37368c31abSDavid du Colombier 		}
38*fececb92SDavid du Colombier 		b->data[Maxconfig] = '\0';
39*fececb92SDavid du Colombier 		if(memcmp(b->data, vcmagic, Maglen) != 0){
40368c31abSDavid du Colombier 			seterr(EOk, "bad venti config magic in %s", name);
41368c31abSDavid du Colombier 			freezblock(b);
42368c31abSDavid du Colombier 			freepart(p);
43368c31abSDavid du Colombier 			return -1;
44368c31abSDavid du Colombier 		}
45*fececb92SDavid du Colombier 		/*
46*fececb92SDavid du Colombier 		 * if we change b->data+b->_size, freezblock
47*fececb92SDavid du Colombier 		 * will blow an assertion, so don't.
48*fececb92SDavid du Colombier 		 */
49*fececb92SDavid du Colombier 		b->data  += Maglen;
50*fececb92SDavid du Colombier 		b->_size -= Maglen;
51*fececb92SDavid du Colombier 		b->len   -= Maglen;
52*fececb92SDavid du Colombier 		z = memchr(b->data, '\0', b->len);
53368c31abSDavid du Colombier 		if(z)
54368c31abSDavid du Colombier 			b->len = z - b->data;
55*fececb92SDavid du Colombier 	}else if(p->size > Maxconfig){
56368c31abSDavid du Colombier 		seterr(EOk, "config file is too large");
57368c31abSDavid du Colombier 		freepart(p);
58368c31abSDavid du Colombier 		freezblock(b);
59368c31abSDavid du Colombier 		return -1;
60368c31abSDavid du Colombier 	}else{
61368c31abSDavid du Colombier 		freezblock(b);
62368c31abSDavid du Colombier 		b = readfile(name);
63368c31abSDavid du Colombier 		if(b == nil){
64368c31abSDavid du Colombier 			freepart(p);
65368c31abSDavid du Colombier 			return -1;
66368c31abSDavid du Colombier 		}
67368c31abSDavid du Colombier 	}
68368c31abSDavid du Colombier 	freepart(p);
69368c31abSDavid du Colombier 	f->name = name;
70368c31abSDavid du Colombier 	f->b = b;
71368c31abSDavid du Colombier 	f->pos = 0;
72368c31abSDavid du Colombier 	return 0;
73368c31abSDavid du Colombier }
74368c31abSDavid du Colombier 
75368c31abSDavid du Colombier void
freeifile(IFile * f)76368c31abSDavid du Colombier freeifile(IFile *f)
77368c31abSDavid du Colombier {
78368c31abSDavid du Colombier 	freezblock(f->b);
79368c31abSDavid du Colombier 	f->b = nil;
80368c31abSDavid du Colombier 	f->pos = 0;
81368c31abSDavid du Colombier }
82368c31abSDavid du Colombier 
83368c31abSDavid du Colombier int
partifile(IFile * f,Part * part,u64int start,u32int size)84368c31abSDavid du Colombier partifile(IFile *f, Part *part, u64int start, u32int size)
85368c31abSDavid du Colombier {
86368c31abSDavid du Colombier 	ZBlock *b;
87368c31abSDavid du Colombier 
88368c31abSDavid du Colombier 	b = alloczblock(size, 0, part->blocksize);
89368c31abSDavid du Colombier 	if(b == nil)
90368c31abSDavid du Colombier 		return -1;
91368c31abSDavid du Colombier 	if(readpart(part, start, b->data, size) < 0){
92368c31abSDavid du Colombier 		seterr(EAdmin, "can't read %s: %r", part->name);
93368c31abSDavid du Colombier 		freezblock(b);
94368c31abSDavid du Colombier 		return -1;
95368c31abSDavid du Colombier 	}
96368c31abSDavid du Colombier 	f->name = part->name;
97368c31abSDavid du Colombier 	f->b = b;
98368c31abSDavid du Colombier 	f->pos = 0;
99368c31abSDavid du Colombier 	return 0;
100368c31abSDavid du Colombier }
101368c31abSDavid du Colombier 
102368c31abSDavid du Colombier /*
103368c31abSDavid du Colombier  * return the next non-blank input line,
104368c31abSDavid du Colombier  * stripped of leading white space and with # comments eliminated
105368c31abSDavid du Colombier  */
106368c31abSDavid du Colombier char*
ifileline(IFile * f)107368c31abSDavid du Colombier ifileline(IFile *f)
108368c31abSDavid du Colombier {
109368c31abSDavid du Colombier 	char *s, *e, *t;
110368c31abSDavid du Colombier 	int c;
111368c31abSDavid du Colombier 
112368c31abSDavid du Colombier 	for(;;){
113368c31abSDavid du Colombier 		s = (char*)&f->b->data[f->pos];
114368c31abSDavid du Colombier 		e = memchr(s, '\n', f->b->len - f->pos);
115368c31abSDavid du Colombier 		if(e == nil)
116368c31abSDavid du Colombier 			return nil;
117368c31abSDavid du Colombier 		*e++ = '\0';
118368c31abSDavid du Colombier 		f->pos = e - (char*)f->b->data;
119368c31abSDavid du Colombier 		t = strchr(s, '#');
120368c31abSDavid du Colombier 		if(t != nil)
121368c31abSDavid du Colombier 			*t = '\0';
122368c31abSDavid du Colombier 		for(; c = *s; s++)
123368c31abSDavid du Colombier 			if(c != ' ' && c != '\t' && c != '\r')
124368c31abSDavid du Colombier 				return s;
125368c31abSDavid du Colombier 	}
126368c31abSDavid du Colombier }
127368c31abSDavid du Colombier 
128368c31abSDavid du Colombier int
ifilename(IFile * f,char * dst)129368c31abSDavid du Colombier ifilename(IFile *f, char *dst)
130368c31abSDavid du Colombier {
131368c31abSDavid du Colombier 	char *s;
132368c31abSDavid du Colombier 
133368c31abSDavid du Colombier 	s = ifileline(f);
134368c31abSDavid du Colombier 	if(s == nil || strlen(s) >= ANameSize)
135368c31abSDavid du Colombier 		return -1;
136368c31abSDavid du Colombier 	namecp(dst, s);
137368c31abSDavid du Colombier 	return 0;
138368c31abSDavid du Colombier }
139368c31abSDavid du Colombier 
140368c31abSDavid du Colombier int
ifileu32int(IFile * f,u32int * r)141368c31abSDavid du Colombier ifileu32int(IFile *f, u32int *r)
142368c31abSDavid du Colombier {
143368c31abSDavid du Colombier 	char *s;
144368c31abSDavid du Colombier 
145368c31abSDavid du Colombier 	s = ifileline(f);
146368c31abSDavid du Colombier 	if(s == nil)
147368c31abSDavid du Colombier 		return -1;
148368c31abSDavid du Colombier 	return stru32int(s, r);
149368c31abSDavid du Colombier }
150