xref: /plan9/sys/src/9/port/devroot.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
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 #include	"devtab.h"
8 
9 enum{
10 	Qdir=	0,
11 	Qbin,
12 	Qdev,
13 	Qenv,
14 	Qproc,
15 	Qnet,
16 	Qboot,		/* readable files */
17 
18 	Nfiles=13,	/* max root files */
19 };
20 
21 extern ulong	bootlen;
22 extern uchar	bootcode[];
23 
24 Dirtab rootdir[Nfiles]={
25 		"bin",		{Qbin|CHDIR},	0,	0777,
26 		"dev",		{Qdev|CHDIR},	0,	0777,
27 		"env",		{Qenv|CHDIR},	0,	0777,
28 		"proc",		{Qproc|CHDIR},	0,	0777,
29 		"net",		{Qnet|CHDIR},	0,	0777,
30 };
31 
32 static uchar	*rootdata[Nfiles];
33 static int	nroot = Qboot - 1;
34 
35 /*
36  *  add a root file
37  */
38 void
39 addrootfile(char *name, uchar *contents, ulong len)
40 {
41 	Dirtab *d;
42 
43 
44 	if(nroot >= Nfiles)
45 		panic("too many root files");
46 	rootdata[nroot] = contents;
47 	d = &rootdir[nroot];
48 	strcpy(d->name, name);
49 	d->length = len;
50 	d->perm = 0555;
51 	d->qid.path = nroot+1;
52 	nroot++;
53 }
54 
55 void
56 rootreset(void)
57 {
58 	addrootfile("boot", bootcode, bootlen);	/* always have a boot file */
59 }
60 
61 void
62 rootinit(void)
63 {
64 }
65 
66 Chan*
67 rootattach(char *spec)
68 {
69 	return devattach('/', spec);
70 }
71 
72 Chan*
73 rootclone(Chan *c, Chan *nc)
74 {
75 	return devclone(c, nc);
76 }
77 
78 int
79 rootwalk(Chan *c, char *name)
80 {
81 	if(strcmp(name, "..") == 0) {
82 		c->qid.path = Qdir|CHDIR;
83 		return 1;
84 	}
85 	if((c->qid.path & ~CHDIR) != Qdir)
86 		return 0;
87 	return devwalk(c, name, rootdir, nroot, devgen);
88 }
89 
90 void
91 rootstat(Chan *c, char *dp)
92 {
93 	devstat(c, dp, rootdir, nroot, devgen);
94 }
95 
96 Chan*
97 rootopen(Chan *c, int omode)
98 {
99 	return devopen(c, omode, rootdir, nroot, devgen);
100 }
101 
102 void
103 rootcreate(Chan *c, char *name, int omode, ulong perm)
104 {
105 	USED(c, name, omode, perm);
106 	error(Eperm);
107 }
108 
109 /*
110  * sysremove() knows this is a nop
111  */
112 void
113 rootclose(Chan *c)
114 {
115 	USED(c);
116 }
117 
118 long
119 rootread(Chan *c, void *buf, long n, ulong offset)
120 {
121 	ulong t;
122 	Dirtab *d;
123 	uchar *data;
124 
125 	t = c->qid.path & ~CHDIR;
126 	if(t == Qdir)
127 		return devdirread(c, buf, n, rootdir, nroot, devgen);
128 	if(t < Qboot)
129 		return 0;
130 
131 	d = &rootdir[t-1];
132 	data = rootdata[t-1];
133 	if(offset >= d->length)
134 		return 0;
135 	if(offset+n > d->length)
136 		n = d->length - offset;
137 	memmove(buf, data+offset, n);
138 	return n;
139 }
140 
141 long
142 rootwrite(Chan *c, void *buf, long n, ulong offset)
143 {
144 	USED(c, buf, n, offset);
145 	error(Egreg);
146 	return 0;	/* not reached */
147 }
148 
149 void
150 rootremove(Chan *c)
151 {
152 	USED(c);
153 	error(Eperm);
154 }
155 
156 void
157 rootwstat(Chan *c, char *dp)
158 {
159 	USED(c, dp);
160 	error(Eperm);
161 }
162