2 #include "../port/lib.h"
6 #include "../port/error.h"
13 static Egrp *envgrp(Chan *c);
14 static int envwriteable(Chan *c);
16 static Egrp confegrp; /* global environment group containing the kernel configuration */
19 envlookup(Egrp *eg, char *name, ulong qidpath)
24 for(i=0; i<eg->nent; i++){
26 if(e->qid.path == qidpath || (name != nil && name[0] == e->name[0] && strcmp(e->name, name) == 0))
33 envgen(Chan *c, char *name, Dirtab*, int, int s, Dir *dp)
39 devdir(c, c->qid, "#e", 0, eve, DMDIR|0775, dp);
47 e = envlookup(eg, name, -1);
51 if(e == nil || name != nil && (strlen(e->name) >= sizeof(up->genbuf))) {
56 /* make sure name string continues to exist after we release lock */
57 kstrcpy(up->genbuf, e->name, sizeof up->genbuf);
58 devdir(c, e->qid, up->genbuf, e->len, eve, 0666, dp);
69 if(spec != nil && *spec != '\0') {
70 if(strcmp(spec, "c") != 0)
75 c = devattach('e', spec);
81 envwalk(Chan *c, Chan *nc, char **name, int nname)
83 return devwalk(c, nc, name, nname, 0, 0, envgen);
87 envstat(Chan *c, uchar *db, int n)
89 if(c->qid.type & QTDIR)
90 c->qid.vers = envgrp(c)->vers;
91 return devstat(c, db, n, 0, 0, envgen);
95 envopen(Chan *c, int omode)
102 if(c->qid.type & QTDIR) {
107 trunc = omode & OTRUNC;
108 if(omode != OREAD && !envwriteable(c))
114 e = envlookup(eg, nil, c->qid.path);
122 if(trunc && e->value != nil) {
133 c->mode = openmode(omode);
140 envcreate(Chan *c, char *name, int omode, ulong)
146 if(c->qid.type != QTDIR || !envwriteable(c))
149 if(strlen(name) >= sizeof(up->genbuf))
152 omode = openmode(omode);
161 if(envlookup(eg, name, -1) != nil)
164 e = smalloc(sizeof(Evalue));
165 e->name = smalloc(strlen(name)+1);
166 strcpy(e->name, name);
168 if(eg->nent == eg->ment){
170 ent = smalloc(sizeof(eg->ent[0])*eg->ment);
172 memmove(ent, eg->ent, sizeof(eg->ent[0])*eg->nent);
176 e->qid.path = ++eg->path;
179 eg->ent[eg->nent++] = e;
198 if(c->qid.type & QTDIR || !envwriteable(c))
204 for(i=0; i<eg->nent; i++){
205 if(eg->ent[i]->qid.path == c->qid.path){
208 eg->ent[i] = eg->ent[eg->nent];
225 * cclose can't fail, so errors from remove will be ignored.
226 * since permissions aren't checked,
227 * envremove can't not remove it if its there.
229 if(c->flag & CRCLOSE)
234 envread(Chan *c, void *a, long n, vlong off)
240 if(c->qid.type & QTDIR)
241 return devdirread(c, a, n, 0, 0, envgen);
245 e = envlookup(eg, nil, c->qid.path);
251 if(offset >= e->len || e->value == nil)
253 else if(offset + n > e->len)
258 memmove(a, e->value+offset, n);
264 envwrite(Chan *c, void *a, long n, vlong off)
274 if(offset > Maxenvsize || n > (Maxenvsize - offset))
279 e = envlookup(eg, nil, c->qid.path);
293 memmove(s, e->value, e->len);
299 memmove(e->value+offset, a, n);
328 envcpy(Egrp *to, Egrp *from)
334 to->ment = (from->nent+31)&~31;
335 to->ent = smalloc(to->ment*sizeof(to->ent[0]));
336 for(i=0; i<from->nent; i++){
338 ne = smalloc(sizeof(Evalue));
339 ne->name = smalloc(strlen(e->name)+1);
340 strcpy(ne->name, e->name);
342 ne->value = smalloc(e->len);
343 memmove(ne->value, e->value, e->len);
346 ne->qid.path = ++to->path;
349 to->nent = from->nent;
360 for(i=0; i<eg->nent; i++){
380 envwriteable(Chan *c)
382 return c->aux == nil || c->aux == up->egrp || iseve();
386 * to let the kernel set environment variables
389 ksetenv(char *ename, char *eval, int conf)
392 char buf[2*KNAMELEN];
394 snprint(buf, sizeof(buf), "#e%s/%s", conf?"c":"", ename);
395 c = namec(buf, Acreate, OWRITE, 0600);
396 devtab[c->type]->write(c, eval, strlen(eval), 0);
401 * Return a copy of configuration environment as a sequence of strings.
402 * The strings alternate between name and value. A zero length name string
403 * indicates the end of the list
408 Egrp *eg = &confegrp;
421 for(i=0; i<eg->nent; i++){
423 n += strlen(e->name) + e->len + 2;
429 for(i=0; i<eg->nent; i++){
433 memmove(q, e->value, e->len);
435 /* move up to the first null */