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 && e->name[0]==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 == 0 || name && (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);
70 if(strcmp(spec, "c") == 0)
76 c = devattach('e', spec);
82 envwalk(Chan *c, Chan *nc, char **name, int nname)
84 return devwalk(c, nc, name, nname, 0, 0, envgen);
88 envstat(Chan *c, uchar *db, int n)
90 if(c->qid.type & QTDIR)
91 c->qid.vers = envgrp(c)->vers;
92 return devstat(c, db, n, 0, 0, envgen);
96 envopen(Chan *c, int omode)
103 if(c->qid.type & QTDIR) {
108 trunc = omode & OTRUNC;
109 if(omode != OREAD && !envwriteable(c))
115 e = envlookup(eg, nil, c->qid.path);
123 if(trunc && e->value) {
134 c->mode = openmode(omode);
141 envcreate(Chan *c, char *name, int omode, ulong)
147 if(c->qid.type != QTDIR)
150 if(strlen(name) >= sizeof(up->genbuf))
153 omode = openmode(omode);
162 if(envlookup(eg, name, -1))
165 e = smalloc(sizeof(Evalue));
166 e->name = smalloc(strlen(name)+1);
167 strcpy(e->name, name);
169 if(eg->nent == eg->ment){
171 ent = smalloc(sizeof(eg->ent[0])*eg->ment);
173 memmove(ent, eg->ent, sizeof(eg->ent[0])*eg->nent);
177 e->qid.path = ++eg->path;
180 eg->ent[eg->nent++] = e;
199 if(c->qid.type & QTDIR)
205 for(i=0; i<eg->nent; i++){
206 if(eg->ent[i]->qid.path == c->qid.path){
209 eg->ent[i] = eg->ent[eg->nent];
227 * cclose can't fail, so errors from remove will be ignored.
228 * since permissions aren't checked,
229 * envremove can't not remove it if its there.
231 if(c->flag & CRCLOSE)
236 envread(Chan *c, void *a, long n, vlong off)
242 if(c->qid.type & QTDIR)
243 return devdirread(c, a, n, 0, 0, envgen);
247 e = envlookup(eg, nil, c->qid.path);
253 if(offset > e->len) /* protects against overflow converting vlong to ulong */
255 else if(offset + n > e->len)
260 memmove(a, e->value+offset, n);
266 envwrite(Chan *c, void *a, long n, vlong off)
276 if(offset > Maxenvsize || n > (Maxenvsize - offset))
281 e = envlookup(eg, nil, c->qid.path);
295 memmove(s, e->value, e->len);
301 memmove(e->value+offset, a, n);
330 envcpy(Egrp *to, Egrp *from)
336 to->ment = (from->nent+31)&~31;
337 to->ent = smalloc(to->ment*sizeof(to->ent[0]));
338 for(i=0; i<from->nent; i++){
340 ne = smalloc(sizeof(Evalue));
341 ne->name = smalloc(strlen(e->name)+1);
342 strcpy(ne->name, e->name);
344 ne->value = smalloc(e->len);
345 memmove(ne->value, e->value, e->len);
348 ne->qid.path = ++to->path;
351 to->nent = from->nent;
362 for(i=0; i<eg->nent; i++){
383 envwriteable(Chan *c)
385 return iseve() || c->aux == nil;
389 * to let the kernel set environment variables
392 ksetenv(char *ename, char *eval, int conf)
395 char buf[2*KNAMELEN];
397 snprint(buf, sizeof(buf), "#e%s/%s", conf?"c":"", ename);
398 c = namec(buf, Acreate, OWRITE, 0600);
399 devtab[c->type]->write(c, eval, strlen(eval), 0);
404 * Return a copy of configuration environment as a sequence of strings.
405 * The strings alternate between name and value. A zero length name string
406 * indicates the end of the list
411 Egrp *eg = &confegrp;
424 for(i=0; i<eg->nent; i++){
426 n += strlen(e->name) + e->len + 2;
432 for(i=0; i<eg->nent; i++){
436 memmove(q, e->value, e->len);
438 /* move up to the first null */