|
|
1.1 root 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: #include "devtab.h"
9:
10: enum
11: {
12: Maxenvsize = 16300,
13: };
14:
15: void
16: envreset(void)
17: {
18: }
19:
20: void
21: envinit(void)
22: {
23: }
24:
25: int
26: envgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp)
27: {
28: Egrp *eg;
29: Evalue *e;
30:
31: USED(tab);
32: USED(ntab);
33:
34: eg = u->p->egrp;
35: qlock(eg);
36:
37: for(e = eg->entries; e && s; e = e->link)
38: s--;
39:
40: if(e == 0) {
41: qunlock(eg);
42: return -1;
43: }
44:
45: devdir(c, (Qid){e->path, 0}, e->name, e->len, eve, 0666, dp);
46: qunlock(eg);
47: return 1;
48: }
49:
50: Chan*
51: envattach(char *spec)
52: {
53: return devattach('e', spec);
54: }
55:
56: Chan*
57: envclone(Chan *c, Chan *nc)
58: {
59: return devclone(c, nc);
60: }
61:
62: int
63: envwalk(Chan *c, char *name)
64: {
65:
66: return devwalk(c, name, 0, 0, envgen);
67: }
68:
69: void
70: envstat(Chan *c, char *db)
71: {
72: devstat(c, db, 0, 0, envgen);
73: }
74:
75: Chan *
76: envopen(Chan *c, int omode)
77: {
78: Egrp *eg;
79: Evalue *e;
80:
81: eg = u->p->egrp;
82: if(c->qid.path & CHDIR) {
83: if(omode != OREAD)
84: error(Eperm);
85: }
86: else {
87: qlock(eg);
88: for(e = eg->entries; e; e = e->link)
89: if(e->path == c->qid.path)
90: break;
91:
92: if(e == 0) {
93: qunlock(eg);
94: error(Enonexist);
95: }
96: if(omode == (OWRITE|OTRUNC) && e->value) {
97: free(e->value);
98: e->value = 0;
99: e->len = 0;
100: }
101: qunlock(eg);
102: }
103: c->mode = openmode(omode);
104: c->flag |= COPEN;
105: c->offset = 0;
106: return c;
107: }
108:
109: void
110: envcreate(Chan *c, char *name, int omode, ulong perm)
111: {
112: Egrp *eg;
113: Evalue *e;
114:
115: USED(perm);
116: if(c->qid.path != CHDIR)
117: error(Eperm);
118:
119: omode = openmode(omode);
120: eg = u->p->egrp;
121:
122: qlock(eg);
123: if(waserror()) {
124: qunlock(eg);
125: nexterror();
126: }
127:
128: for(e = eg->entries; e; e = e->link)
129: if(strcmp(e->name, name) == 0)
130: error(Einuse);
131:
132: e = smalloc(sizeof(Evalue));
133: e->name = smalloc(strlen(name)+1);
134: strcpy(e->name, name);
135:
136: e->path = ++eg->path;
137: e->link = eg->entries;
138: eg->entries = e;
139: c->qid = (Qid){e->path, 0};
140:
141: qunlock(eg);
142: poperror();
143:
144: c->offset = 0;
145: c->mode = omode;
146: c->flag |= COPEN;
147: }
148:
149: void
150: envremove(Chan *c)
151: {
152: Egrp *eg;
153: Evalue *e, **l;
154:
155: if(c->qid.path & CHDIR)
156: error(Eperm);
157:
158: eg = u->p->egrp;
159: qlock(eg);
160:
161: l = &eg->entries;
162: for(e = *l; e; e = e->link) {
163: if(e->path == c->qid.path)
164: break;
165: l = &e->link;
166: }
167:
168: if(e == 0) {
169: qunlock(eg);
170: error(Enonexist);
171: }
172:
173: *l = e->link;
174: qunlock(eg);
175: free(e->name);
176: if(e->value)
177: free(e->value);
178: free(e);
179: }
180:
181: void
182: envwstat(Chan *c, char *db)
183: {
184: USED(c, db);
185: error(Eperm);
186: }
187:
188: void
189: envclose(Chan * c)
190: {
191: USED(c);
192: }
193:
194: long
195: envread(Chan *c, void *a, long n, ulong offset)
196: {
197: Egrp *eg;
198: Evalue *e;
199:
200: if(c->qid.path & CHDIR)
201: return devdirread(c, a, n, 0, 0, envgen);
202:
203: eg = u->p->egrp;
204: qlock(eg);
205: for(e = eg->entries; e; e = e->link)
206: if(e->path == c->qid.path)
207: break;
208:
209: if(e == 0) {
210: qunlock(eg);
211: error(Enonexist);
212: }
213:
214: if(offset + n > e->len)
215: n = e->len - offset;
216: if(n <= 0)
217: n = 0;
218: else
219: memmove(a, e->value+offset, n);
220: qunlock(eg);
221: return n;
222: }
223:
224: long
225: envwrite(Chan *c, void *a, long n, ulong offset)
226: {
227: char *s;
228: int vend;
229: Egrp *eg;
230: Evalue *e;
231:
232: if(n <= 0)
233: return 0;
234:
235: vend = offset+n;
236: if(vend > Maxenvsize)
237: error(Etoobig);
238:
239: eg = u->p->egrp;
240: qlock(eg);
241: for(e = eg->entries; e; e = e->link)
242: if(e->path == c->qid.path)
243: break;
244:
245: if(e == 0) {
246: qunlock(eg);
247: error(Enonexist);
248: }
249:
250: if(vend > e->len) {
251: s = smalloc(offset+n);
252: memmove(s, e->value, e->len);
253: if(e->value)
254: free(e->value);
255: e->value = s;
256: e->len = vend;
257: }
258: memmove(e->value+offset, a, n);
259: qunlock(eg);
260: return n;
261: }
262:
263: void
264: envcpy(Egrp *to, Egrp *from)
265: {
266: Evalue **l, *ne, *e;
267:
268: l = &to->entries;
269: qlock(from);
270: for(e = from->entries; e; e = e->link) {
271: ne = smalloc(sizeof(Evalue));
272: ne->name = smalloc(strlen(e->name)+1);
273: strcpy(ne->name, e->name);
274: if(e->value) {
275: ne->value = smalloc(e->len);
276: memmove(ne->value, e->value, e->len);
277: ne->len = e->len;
278: }
279: ne->path = ++to->path;
280: *l = ne;
281: l = &ne->link;
282: }
283: qunlock(from);
284: }
285:
286: void
287: closeegrp(Egrp *eg)
288: {
289: Evalue *e, *next;
290:
291: if(decref(eg) == 0) {
292: for(e = eg->entries; e; e = next) {
293: next = e->link;
294: free(e->name);
295: if(e->value)
296: free(e->value);
297: free(e);
298: }
299: free(eg);
300: }
301: }
302:
303: /*
304: * to let the kernel set environment variables
305: */
306: void
307: ksetenv(char *ename, char *eval)
308: {
309: Chan *c;
310: char buf[2*NAMELEN];
311:
312: sprint(buf, "#e/%s", ename);
313: c = namec(buf, Acreate, OWRITE, 0600);
314: (*devtab[c->type].write)(c, eval, strlen(eval), 0);
315: close(c);
316: }
317:
318: void
319: ksetterm(char *f)
320: {
321: char buf[2*NAMELEN];
322:
323: sprint(buf, f, conffile);
324: ksetenv("terminal", buf);
325: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.