da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1985-2010 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Glenn Fowler <gsf@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Phong Vo <kpv@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * string interface to confstr(),pathconf(),sysconf(),sysinfo()
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * extended to allow some features to be set per-process
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzstatic const char id[] = "\n@(#)$Id: getconf (AT&T Research) 2009-07-02 $\0\n";
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#define DEFAULT(o) ((state.std||!dynamic[o].ast)?dynamic[o].std:dynamic[o].ast)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define INITIALIZE() do{if(!state.data)synthesize(NiL,NiL,NiL);}while(0)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#define STANDARD(v) (streq(v,"standard")||streq(v,"strict")||streq(v,"posix")||streq(v,"xopen"))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintypedef struct
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "CONFORMANCE",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "standard",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "GETCONF",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "HOSTTYPE",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "LIBPATH",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "LIBPREFIX",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "LIBSUFFIX",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "PATH_ATTRIBUTES",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "PATH_RESOLVE",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "metaphysical",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "UNIVERSE",
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintypedef struct
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* default initialization from here down */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzstatic State_t state = { "getconf", "_AST_FEATURES", dynamic, -1 };
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic char* feature(const char*, const char*, const char*, unsigned int, Error_f);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * return fmtbuf() copy of s
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * synthesize state for fp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * fp==0 initializes from getenv(state.name)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * value==0 just does lookup
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * otherwise state is set to value
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinsynthesize(register Feature_t* fp, const char* path, const char* value)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* d;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* v;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz register char* p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin error(-2, "astconf synthesize name=%s path=%s value=%s fp=%p%s", fp->name, path, value, fp, state.synthesizing ? " SYNTHESIZING" : "");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (d = s; *d && !isspace(*d); d++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (v = d; *v && !isspace(*v); v++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin feature(s, d, v, 0, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (isspace(*d))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (; isspace(*d); d++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (s = d; *s && !isspace(*s); s++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = s - d;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin value = (const char*)d;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz for (s = p = d + n + 1; *s && !isspace(*s); s++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (; isspace(*s); s++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (v = s; *s && !isspace(*s); s++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = s - v;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if ((!path || *path == *p && strlen(path) == (v - p - 1) && !memcmp(path, p, v - p - 1)) && strneq(v, value, n))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (; isspace(*s); s++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (; *d = *s++; d++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (; *d && !isspace(*d); d++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (; isspace(*d); d++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (; *d && !isspace(*d); d++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (; isspace(*d); d++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (; *d && !isspace(*d); d++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *d++ = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *d++ = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (s = (char*)path; *d = *s++; d++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *d++ = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (s = (char*)value; *d = *s++; d++);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz error(-3, "astconf synthesize %s", state.data - state.prefix);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * initialize the value for fp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * if command!=0 then it is checked for on $PATH
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * synthesize(fp,path,succeed) called on success
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * otherwise synthesize(fp,path,fail) called
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chininitialize(register Feature_t* fp, const char* path, const char* command, const char* succeed, const char* fail)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* p;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin error(-2, "astconf initialize name=%s path=%s command=%s succeed=%s fail=%s fp=%p%s", fp->name, path, command, succeed, fail, fp, state.synthesizing ? " SYNTHESIZING" : "");
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz ok = streq(_UNIV_DEFAULT, DEFAULT(OP_universe));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*FALLTHROUGH...*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int r = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* d = p;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin error(-2, "astconf initialize name=%s ok=%d PATH=%s", fp->name, ok, p);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (*p++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (r = p - d - 1)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (p[0] == 'u' && p[1] == 's' && p[2] == 'r' && p[3] == '/')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (!*p || *p == ':')
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz error(-1, "AHA#%d state.std=%d %s [%s] std=%s ast=%s value=%s ok=%d", __LINE__, state.std, fp->name, ok ? succeed : fail, fp->std, fp->ast, fp->value, ok);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * format synthesized value
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char*
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinformat(register Feature_t* fp, const char* path, const char* value, unsigned int flags, Error_f conferror)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin error(-2, "astconf format name=%s path=%s value=%s flags=%04x fp=%p%s", fp->name, path, value, flags, fp, state.synthesizing ? " SYNTHESIZING" : "");
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz error(-1, "AHA#%d state.std=%d %s [%s] std=%s ast=%s value=%s", __LINE__, state.std, fp->name, value, fp->std, fp->ast, fp->value);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz error(-1, "AHA#%d state.std=%d %s [%s] std=%s ast=%s value=%s", __LINE__, state.std, fp->name, value, fp->std, fp->ast, fp->value);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (sp->std && sp->op && sp->op != OP_conformance)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz error(-1, "AHA#%d state.std=%d %s [%s] std=%s ast=%s value=%s", __LINE__, state.std, fp->name, value, fp->std, fp->ast, fp->value);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->value = fs3d(value ? value[0] ? FS3D_ON : FS3D_OFF : FS3D_TEST) ? "1" : null;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * _PC_PATH_ATTRIBUTES is a bitmap for 'a' to 'z'
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (s >= e)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz initialize(fp, path, NiL, "logical", DEFAULT(OP_path_resolve));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*conferror)(&state, &state, 2, "%s: %s: universe value too large", fp->name, value);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!value && n > 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n <= 0 || n >= univ_max)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!(fp->value = newof(fp->value, char, n, 1)))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz initialize(fp, path, "echo", DEFAULT(OP_universe), "ucb");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * value==0 get feature name
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * value!=0 set feature name
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * 0 returned if error or not defined; otherwise previous value
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char*
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinfeature(const char* name, const char* path, const char* value, unsigned int flags, Error_f conferror)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (fp = state.features; fp && !streq(fp->name, name); fp = fp->next);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin error(-2, "astconf feature name=%s path=%s value=%s flags=%04x fp=%p%s", name, path, value, flags, fp, state.synthesizing ? " SYNTHESIZING" : "");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (state.notify && !(*state.notify)(name, path, value))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*conferror)(&state, &state, 2, "%s: out of space", name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*conferror)(&state, &state, 2, "%s: cannot set readonly symbol", fp->name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (state.notify && !streq(fp->value, value) && !(*state.notify)(name, path, value))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * binary search for name in conf[]
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinlookup(register Lookup_t* look, const char* name, unsigned int flags)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int v;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin look->standard = (flags & ASTCONF_AST) ? CONF_AST : -1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (strneq(name, p->name, p->length) && ((c = name[p->length] == '_' || name[p->length] == '(' || name[p->length] == '#') || (v = isdigit(name[p->length]) && name[p->length + 1] == '_')))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p->call < 0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (name[p->length] == '(' || name[p->length] == '#')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(-2, "astconf normal name=%s standard=%d section=%d call=%d flags=%04x elements=%d", look->name, look->standard, look->section, look->call, flags, conf_elements);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = *((unsigned char*)name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(-3, "astconf lookup name=%s mid=%s", name, mid->name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(v = c - *((unsigned char*)mid->name)) && !(v = strcmp(name, mid->name)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((look->standard < 0 || look->standard == mid->standard) &&
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (look->section < 0 || look->section == mid->section) &&
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((look->standard < 0 || look->standard == mid->standard) &&
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (look->section < 0 || look->section == mid->section) &&
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (v > 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (look->call < 0 && look->standard >= 0 && (look->section <= 1 || (mid->flags & CONF_MINMAX)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(-2, "astconf lookup name=%s standard=%d:%d section=%d:%d call=%d:%d", look->name, look->standard, mid->standard, look->section, mid->section, look->call, mid->call);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * return a tolower'd copy of s
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (c = *s++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * print value line for p
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * if !name then value prefixed by "p->name="
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * if (flags & CONF_MINMAX) then default minmax value used
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinprint(Sfio_t* sp, register Lookup_t* look, const char* name, const char* path, int listflags, Error_f conferror)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin const char* s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int defined;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!name && !(p->flags & CONF_STRING) && (p->flags & (CONF_FEATURE|CONF_LIMIT|CONF_MINMAX)) && (p->flags & (CONF_LIMIT|CONF_PREFIXED)) != CONF_LIMIT)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz error(-1, "astconf name=%s:%s:%s standard=%d section=%d call=%s op=%d flags=|%s%s%s%s%s:|%s%s%s%s%s%s%s%s%s%s"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz , name, look->name, p->name, p->standard, p->section, prefix[p->call + CONF_call].name, p->op
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin , (p->flags & CONF_LIMIT_DEF) ? "LIMIT_DEF|" : (p->flags & CONF_LIMIT) ? "LIMIT|" : ""
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin , (p->flags & CONF_MINMAX_DEF) ? "MINMAX_DEF|" : (p->flags & CONF_MINMAX) ? "MINMAX|" : ""
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin , (p->flags & CONF_NOUNDERSCORE) ? "NOUNDERSCORE|" : ""
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((p->flags & CONF_PREFIX_ONLY) && look->standard < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(flags & CONF_MINMAX) || !(p->flags & CONF_MINMAX))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (p->call)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*conferror)(&state, &state, 2, "%s: path expected", name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*conferror)(&state, &state, 2, "%s: path not expected", name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*conferror)(&state, &state, 2, "%s: path not expected", name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((p->flags & CONF_DEFER_MM) || !(p->flags & CONF_MINMAX_DEF))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (look->standard >= 0 && (name[0] != '_' && ((p->flags & CONF_UNDERSCORE) || look->section <= 1) || name[0] == '_' && (p->flags & CONF_NOUNDERSCORE)) || look->standard < 0 && name[0] == '_')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin defined = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (i = (p->op < 0 || (flags & CONF_MINMAX) && (p->flags & CONF_MINMAX_DEF)) ? 0 : p->call)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin defined = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (v > 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = (const char*)buf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin defined = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin defined = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin defined = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = (const char*)buf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin defined = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin defined = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (streq(p->name, "RELEASE") && (i = open("/proc/version", O_RDONLY)) >= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((p->flags & CONF_MINMAX_DEF) && (!(listflags & ASTCONF_system) || !(p->flags & CONF_DEFER_MM)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if ((p->flags & CONF_LIMIT_DEF) && (!(listflags & ASTCONF_system) || !(p->flags & CONF_DEFER_CALL)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin defined = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!defined)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((p->flags & CONF_FEATURE) || !(p->flags & (CONF_LIMIT|CONF_MINMAX)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*conferror)(&state, &state, ERROR_SYSTEM|2, "%s: %s error", p->name, call);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*conferror)(&state, &state, 2, "%s: unknown name", p->name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((listflags & ASTCONF_defined) && !(flags & (CONF_LIMIT_DEF|CONF_MINMAX_DEF)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *f++ = 'C';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *f++ = 'D';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *f++ = 'F';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *f++ = 'L';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *f++ = 'M';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *f++ = 'N';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *f++ = 'P';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *f++ = 'S';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *f++ = 'U';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *f++ = 'V';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *f++ = 'W';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *f++ = 'X';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sp, "%*s %*s %d %2s %4d %6s ", sizeof(p->name), p->name, sizeof(prefix[p->standard].name), prefix[p->standard].name, p->section, prefix[p->call + CONF_call].name, p->op, flg);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sp, "L[%s] ", (listflags & ASTCONF_quote) ? fmtquote(p->limit.string, "\"", "\"", strlen(p->limit.string), FMT_SHELL) : p->limit.string);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sp, "L[%I*d] ", sizeof(p->limit.number), p->limit.number);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sp, "M[%s] ", (listflags & ASTCONF_quote) ? fmtquote(p->minmax.string, "\"", "\"", strlen(p->minmax.string), FMT_SHELL) : p->minmax.string);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sp, "M[%I*d] ", sizeof(p->minmax.number), p->minmax.number);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (defined)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sp, "%s", (listflags & ASTCONF_quote) ? fmtquote(s, "\"", "\"", strlen(s), FMT_SHELL) : s);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (v != -1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(flags & CONF_PREFIXED) || (listflags & ASTCONF_base))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((p->flags & (CONF_PREFIXED|CONF_STRING)) == (CONF_PREFIXED|CONF_STRING) && (!(listflags & ASTCONF_base) || p->standard != CONF_POSIX))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((p->flags & CONF_UNDERSCORE) && !(listflags & ASTCONF_base))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sp, "%s", (listflags & ASTCONF_lower) ? fmtlower(prefix[p->standard].name) : prefix[p->standard].name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sp, "%s=", (listflags & ASTCONF_lower) ? fmtlower(p->name) : p->name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (defined)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sp, "%s", (listflags & ASTCONF_quote) ? fmtquote(s, "\"", "\"", strlen(s), FMT_SHELL) : s);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (v != -1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!name && !(listflags & ASTCONF_base) && !(p->flags & CONF_STRING) && (p->flags & (CONF_FEATURE|CONF_MINMAX)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sp, "%s", (listflags & ASTCONF_lower) ? fmtlower(prefix[p->standard].name) : prefix[p->standard].name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sp, "_%s=", (listflags & ASTCONF_lower) ? fmtlower(p->name) : p->name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (v != -1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (defined)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * return read stream to native getconf utility
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error(-2, "astconf defer %s %s", _pth_getconf, operand);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ops[0] = PROC_FD_DUP(open("/dev/null",O_WRONLY,0), 2, PROC_FD_CHILD);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*pp = procopen(_pth_getconf, cmd, environ, ops, PROC_READ))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (sp = sfnew(NiL, NiL, SF_UNBOUND, (*pp)->rfd, SF_READ))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * value==0 gets value for name
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * value!=0 sets value for name and returns previous value
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * path==0 implies path=="/"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * settable return values are in permanent store
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * non-settable return values copied to a tmp fmtbuf() buffer
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * if (streq(astgetconf("PATH_RESOLVE", NiL, NiL, 0, 0), "logical"))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * our_way();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * universe = astgetconf("UNIVERSE", NiL, "att", 0, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * astgetconf("UNIVERSE", NiL, universe, 0, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * if (flags&ASTCONF_error)!=0 then error return value is 0
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * otherwise 0 not returned
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinastgetconf(const char* name, const char* path, const char* value, int flags, Error_f conferror)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (state.recent && streq(name, state.recent->name) && (s = format(state.recent, path, value, flags, conferror)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*conferror)(&state, &state, 2, "%s: cannot set value", name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return print(NiL, &look, name, path, flags, conferror);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static const char* dirs[] = { "/usr/lib", "/usr", null };
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*conferror)(&state, &state, 2, "%s: cannot set value", altname);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return print(NiL, &altlook, altname, path, flags, conferror);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (s = altname; *s; s++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((look.standard < 0 || look.standard == CONF_AST) && look.call <= 0 && look.section <= 1 && (s = feature(look.name, path, value, flags, conferror)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*conferror)(&state, &state, 2, "%s: unknown name", name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * astconf() never returns 0
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinastconf(const char* name, const char* path, const char* value)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * set discipline function to be called when features change
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * old discipline function returned
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * list all name=value entries on sp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * path==0 implies path=="/"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinastconflist(Sfio_t* sp, const char* path, int flags, const char* pattern)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(flags & (ASTCONF_read|ASTCONF_write|ASTCONF_parse)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(flags & (ASTCONF_matchcall|ASTCONF_matchname|ASTCONF_matchstandard)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (regcomp(&re, pattern, REG_DISCIPLINE|REG_EXTENDED|REG_LENIENT|REG_NULL))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (look.conf = (Conf_t*)conf; look.conf < (Conf_t*)&conf[conf_elements]; look.conf++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (regexec(&re, prefix[look.conf->call + CONF_call].name, 0, NiL, 0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (regexec(&re, prefix[look.conf->standard].name, 0, NiL, 0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (s = f; *s && *s != '=' && *s != ':' && !isspace(*s); s++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (*s++ = 0; isspace(*s); s++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sp, "%*s %*s %d %2s %4d %5s %s\n", sizeof(conf[0].name), f, sizeof(prefix[look.standard].name), prefix[look.standard].name, look.section, call, 0, "N", s);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sp, "%s=%s\n", f, (flags & ASTCONF_quote) ? fmtquote(s, "\"", "\"", strlen(s), FMT_SHELL) : s);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (regexec(&re, prefix[fp->standard].name, 0, NiL, 0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *f++ = 'A';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *f++ = 'R';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *f++ = 'X';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sp, "%*s %*s %d %2s %4d %5s %s\n", sizeof(conf[0].name), fp->name, sizeof(prefix[fp->standard].name), prefix[fp->standard].name, 1, call, 0, flg, s);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sp, "%s %s - %s\n", state.id, (flags & ASTCONF_lower) ? fmtlower(fp->name) : fp->name, fmtquote(s, "\"", "\"", strlen(s), FMT_SHELL));