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	"../port/lib.h"
3
#include	"mem.h"
4
#include	"dat.h"
5
#include	"fns.h"
6
#include	"../port/error.h"
7
 
8
enum
9
{
10
	Qdir = 0,
11
	Qboot = 0x1000,
12
 
13
	Nrootfiles = 32,
14
	Nbootfiles = 32,
15
};
16
 
17
typedef struct Dirlist Dirlist;
18
struct Dirlist
19
{
20
	uint base;
21
	Dirtab *dir;
22
	uchar **data;
23
	int ndir;
24
	int mdir;
25
};
26
 
27
static Dirtab rootdir[Nrootfiles] = {
28
	"#/",		{Qdir, 0, QTDIR},	0,		DMDIR|0555,
29
	"boot",	{Qboot, 0, QTDIR},	0,		DMDIR|0555,
30
};
31
static uchar *rootdata[Nrootfiles];
32
static Dirlist rootlist = 
33
{
34
	0,
35
	rootdir,
36
	rootdata,
37
	2,
38
	Nrootfiles
39
};
40
 
41
static Dirtab bootdir[Nbootfiles] = {
42
	"boot",	{Qboot, 0, QTDIR},	0,		DMDIR|0555,
43
};
44
static uchar *bootdata[Nbootfiles];
45
static Dirlist bootlist =
46
{
47
	Qboot,
48
	bootdir,
49
	bootdata,
50
	1,
51
	Nbootfiles
52
};
53
 
54
/*
55
 *  add a file to the list
56
 */
57
static void
58
addlist(Dirlist *l, char *name, uchar *contents, ulong len, int perm)
59
{
60
	Dirtab *d;
61
 
62
	if(l->ndir >= l->mdir)
63
		panic("too many root files");
64
	l->data[l->ndir] = contents;
65
	d = &l->dir[l->ndir];
66
	strcpy(d->name, name);
67
	d->length = len;
68
	d->perm = perm;
69
	d->qid.type = 0;
70
	d->qid.vers = 0;
71
	d->qid.path = ++l->ndir + l->base;
72
	if(perm & DMDIR)
73
		d->qid.type |= QTDIR;
74
}
75
 
76
/*
77
 *  add a root file
78
 */
79
void
80
addbootfile(char *name, uchar *contents, ulong len)
81
{
82
	addlist(&bootlist, name, contents, len, 0555);
83
}
84
 
85
/*
86
 *  add a root directory
87
 */
88
static void
89
addrootdir(char *name)
90
{
91
	addlist(&rootlist, name, nil, 0, DMDIR|0555);
92
}
93
 
94
static void
95
rootreset(void)
96
{
97
	addrootdir("bin");
98
	addrootdir("dev");
99
	addrootdir("env");
100
	addrootdir("fd");
101
	addrootdir("mnt");
102
	addrootdir("net");
103
	addrootdir("net.alt");
104
	addrootdir("proc");
105
	addrootdir("root");
106
	addrootdir("srv");
107
}
108
 
109
static Chan*
110
rootattach(char *spec)
111
{
112
	return devattach('/', spec);
113
}
114
 
115
static int
116
rootgen(Chan *c, char *name, Dirtab*, int, int s, Dir *dp)
117
{
118
	int t;
119
	Dirtab *d;
120
	Dirlist *l;
121
 
122
	switch((int)c->qid.path){
123
	case Qdir:
124
		if(s == DEVDOTDOT){
125
			devdir(c, (Qid){Qdir, 0, QTDIR}, "#/", 0, eve, 0555, dp);
126
			return 1;
127
		}
128
		return devgen(c, name, rootlist.dir, rootlist.ndir, s, dp);
129
	case Qboot:
130
		if(s == DEVDOTDOT){
131
			devdir(c, (Qid){Qdir, 0, QTDIR}, "#/", 0, eve, 0555, dp);
132
			return 1;
133
		}
134
		return devgen(c, name, bootlist.dir, bootlist.ndir, s, dp);
135
	default:
136
		if(s == DEVDOTDOT){
137
			if((int)c->qid.path < Qboot)
138
				devdir(c, (Qid){Qdir, 0, QTDIR}, "#/", 0, eve, 0555, dp);
139
			else
140
				devdir(c, (Qid){Qboot, 0, QTDIR}, "#/", 0, eve, 0555, dp);
141
			return 1;
142
		}
143
		if(s != 0)
144
			return -1;
145
		if((int)c->qid.path < Qboot){
146
			t = c->qid.path-1;
147
			l = &rootlist;
148
		}else{
149
			t = c->qid.path - Qboot - 1;
150
			l = &bootlist;
151
		}
152
		if(t >= l->ndir)
153
			return -1;
154
if(t < 0){
155
print("rootgen %llud %d %d\n", c->qid.path, s, t);
156
panic("whoops");
157
}
158
		d = &l->dir[t];
159
		devdir(c, d->qid, d->name, d->length, eve, d->perm, dp);
160
		return 1;
161
	}
162
}
163
 
164
static Walkqid*
165
rootwalk(Chan *c, Chan *nc, char **name, int nname)
166
{
167
	return devwalk(c,  nc, name, nname, nil, 0, rootgen);
168
}
169
 
170
static int
171
rootstat(Chan *c, uchar *dp, int n)
172
{
173
	return devstat(c, dp, n, nil, 0, rootgen);
174
}
175
 
176
static Chan*
177
rootopen(Chan *c, int omode)
178
{
179
	return devopen(c, omode, nil, 0, devgen);
180
}
181
 
182
/*
183
 * sysremove() knows this is a nop
184
 */
185
static void
186
rootclose(Chan*)
187
{
188
}
189
 
190
static long
191
rootread(Chan *c, void *buf, long n, vlong off)
192
{
193
	ulong t;
194
	Dirtab *d;
195
	Dirlist *l;
196
	uchar *data;
197
	ulong offset = off;
198
 
199
	t = c->qid.path;
200
	switch(t){
201
	case Qdir:
202
	case Qboot:
203
		return devdirread(c, buf, n, nil, 0, rootgen);
204
	}
205
 
206
	if(t<Qboot)
207
		l = &rootlist;
208
	else{
209
		t -= Qboot;
210
		l = &bootlist;
211
	}
212
 
213
	t--;
214
	if(t >= l->ndir)
215
		error(Egreg);
216
 
217
	d = &l->dir[t];
218
	data = l->data[t];
219
	if(offset >= d->length)
220
		return 0;
221
	if(offset+n > d->length)
222
		n = d->length - offset;
223
#ifdef asdf
224
print("[%d] kaddr %.8ulx base %.8ulx offset %ld (%.8ulx), n %d %.8ulx %.8ulx %.8ulx\n", 
225
		t, buf, data, offset, offset, n,
226
		((ulong*)(data+offset))[0],
227
		((ulong*)(data+offset))[1],
228
		((ulong*)(data+offset))[2]);
229
#endif asdf
230
	memmove(buf, data+offset, n);
231
	return n;
232
}
233
 
234
static long
235
rootwrite(Chan*, void*, long, vlong)
236
{
237
	error(Egreg);
238
	return 0;
239
}
240
 
241
Dev rootdevtab = {
242
	'/',
243
	"root",
244
 
245
	rootreset,
246
	devinit,
247
	devshutdown,
248
	rootattach,
249
	rootwalk,
250
	rootstat,
251
	rootopen,
252
	devcreate,
253
	rootclose,
254
	rootread,
255
	devbread,
256
	rootwrite,
257
	devbwrite,
258
	devremove,
259
	devwstat,
260
};
261