xref: /inferno-os/emu/port/devroot.c (revision 46439007cf417cbd9ac8049bb4122c890097a0fa)
1 #include	"dat.h"
2 #include	"fns.h"
3 #include	"error.h"
4 
5 extern Rootdata rootdata[];
6 extern Dirtab roottab[];
7 extern int	rootmaxq;
8 
9 static Chan*
10 rootattach(char *spec)
11 {
12 	int i;
13 	ulong len;
14 	Rootdata *r;
15 
16 	if(*spec)
17 		error(Ebadspec);
18 	for (i = 0; i < rootmaxq; i++){
19 		r = &rootdata[i];
20 		if (r->sizep){
21 			len = *r->sizep;
22 			r->size = len;
23 			roottab[i].length = len;
24 		}
25 	}
26 	return devattach('/', spec);
27 }
28 
29 static int
30 rootgen(Chan *c, char *name, Dirtab *tab, int nd, int s, Dir *dp)
31 {
32 	int p, i;
33 	Rootdata *r;
34 
35 	if(s == DEVDOTDOT){
36 		p = rootdata[c->qid.path].dotdot;
37 		c->qid.path = p;
38 		c->qid.type = QTDIR;
39 		name = "#/";
40 		if(p != 0){
41 			for(i = 0; i < rootmaxq; i++)
42 				if(roottab[i].qid.path == c->qid.path){
43 					name = roottab[i].name;
44 					break;
45 				}
46 		}
47 		devdir(c, c->qid, name, 0, eve, 0555, dp);
48 		return 1;
49 	}
50 	if(name != nil){
51 		isdir(c);
52 		r = &rootdata[(int)c->qid.path];
53 		tab = r->ptr;
54 		for(i=0; i<r->size; i++, tab++)
55 			if(strcmp(tab->name, name) == 0){
56 				devdir(c, tab->qid, tab->name, tab->length, eve, tab->perm, dp);
57 				return 1;
58 			}
59 		return -1;
60 	}
61 	if(s >= nd)
62 		return -1;
63 	tab += s;
64 	devdir(c, tab->qid, tab->name, tab->length, eve, tab->perm, dp);
65 	return 1;
66 }
67 
68 static Walkqid*
69 rootwalk(Chan *c, Chan *nc, char **name, int nname)
70 {
71 	ulong p;
72 
73 	p = c->qid.path;
74 	if(nname == 0)
75 		p = rootdata[p].dotdot;
76 	return devwalk(c, nc, name, nname, rootdata[p].ptr, rootdata[p].size, rootgen);
77 }
78 
79 static int
80 rootstat(Chan *c, uchar *dp, int n)
81 {
82 	int p;
83 
84 	p = rootdata[c->qid.path].dotdot;
85 	return devstat(c, dp, n, rootdata[p].ptr, rootdata[p].size, rootgen);
86 }
87 
88 static Chan*
89 rootopen(Chan *c, int omode)
90 {
91 	int p;
92 
93 	p = rootdata[c->qid.path].dotdot;
94 	return devopen(c, omode, rootdata[p].ptr, rootdata[p].size, rootgen);
95 }
96 
97 /*
98  * sysremove() knows this is a nop
99  */
100 static void
101 rootclose(Chan *c)
102 {
103 	USED(c);
104 }
105 
106 static long
107 rootread(Chan *c, void *buf, long n, vlong offset)
108 {
109 	ulong p, len;
110 	uchar *data;
111 
112 	p = c->qid.path;
113 	if(c->qid.type & QTDIR)
114 		return devdirread(c, buf, n, rootdata[p].ptr, rootdata[p].size, rootgen);
115 	len = rootdata[p].size;
116 	if(offset < 0 || offset >= len)
117 		return 0;
118 	if(offset+n > len)
119 		n = len - offset;
120 	data = rootdata[p].ptr;
121 	memmove(buf, data+offset, n);
122 	return n;
123 }
124 
125 static long
126 rootwrite(Chan *c, void *a, long n, vlong off)
127 {
128 	USED(c); USED(a); USED(n); USED(off);
129 	error(Eperm);
130 	return 0;
131 }
132 
133 Dev rootdevtab = {
134 	'/',
135 	"root",
136 
137 	devinit,
138 	rootattach,
139 	rootwalk,
140 	rootstat,
141 	rootopen,
142 	devcreate,
143 	rootclose,
144 	rootread,
145 	devbread,
146 	rootwrite,
147 	devbwrite,
148 	devremove,
149 	devwstat,
150 };
151