1*433d6423SLionel Sambuc #include "sysutil.h"
2*433d6423SLionel Sambuc #include <stdlib.h>
3*433d6423SLionel Sambuc #include <string.h>
4*433d6423SLionel Sambuc #include <minix/param.h>
5*433d6423SLionel Sambuc
6*433d6423SLionel Sambuc
7*433d6423SLionel Sambuc /*=========================================================================*
8*433d6423SLionel Sambuc * env_parse *
9*433d6423SLionel Sambuc *=========================================================================*/
env_parse(const char * env,const char * fmt,int field,long * param,long min,long max)10*433d6423SLionel Sambuc int env_parse(const char *env, const char *fmt,
11*433d6423SLionel Sambuc int field, long *param, long min, long max)
12*433d6423SLionel Sambuc {
13*433d6423SLionel Sambuc /* Parse an environment variable setting, something like "DPETH0=300:3".
14*433d6423SLionel Sambuc * Panic if the parsing fails. Return EP_UNSET if the environment variable
15*433d6423SLionel Sambuc * is not set, EP_OFF if it is set to "off", EP_ON if set to "on" or a
16*433d6423SLionel Sambuc * field is left blank, or EP_SET if a field is given (return value through
17*433d6423SLionel Sambuc * *param). Punctuation may be used in the environment and format string,
18*433d6423SLionel Sambuc * fields in the environment string may be empty, and punctuation may be
19*433d6423SLionel Sambuc * missing to skip fields. The format string contains characters 'd', 'o',
20*433d6423SLionel Sambuc * 'x' and 'c' to indicate that 10, 8, 16, or 0 is used as the last argument
21*433d6423SLionel Sambuc * to strtol(). A '*' means that a field should be skipped. If the format
22*433d6423SLionel Sambuc * string contains something like "\4" then the string is repeated 4 characters
23*433d6423SLionel Sambuc * to the left.
24*433d6423SLionel Sambuc */
25*433d6423SLionel Sambuc char *val, *end;
26*433d6423SLionel Sambuc char value[EP_BUF_SIZE];
27*433d6423SLionel Sambuc char PUNCT[] = ":,;.";
28*433d6423SLionel Sambuc long newpar;
29*433d6423SLionel Sambuc int s, i, radix, r;
30*433d6423SLionel Sambuc
31*433d6423SLionel Sambuc if ((s=env_get_param(env, value, sizeof(value))) != 0) {
32*433d6423SLionel Sambuc if (s == ESRCH) return(EP_UNSET); /* only error allowed */
33*433d6423SLionel Sambuc printf("WARNING: env_get_param() failed in env_parse(): %d\n",s);
34*433d6423SLionel Sambuc return(EP_EGETKENV);
35*433d6423SLionel Sambuc }
36*433d6423SLionel Sambuc val = value;
37*433d6423SLionel Sambuc if (strcmp(val, "off") == 0) return(EP_OFF);
38*433d6423SLionel Sambuc if (strcmp(val, "on") == 0) return(EP_ON);
39*433d6423SLionel Sambuc
40*433d6423SLionel Sambuc i = 0;
41*433d6423SLionel Sambuc r = EP_ON;
42*433d6423SLionel Sambuc for (;;) {
43*433d6423SLionel Sambuc while (*val == ' ') val++; /* skip spaces */
44*433d6423SLionel Sambuc if (*val == 0) return(r); /* the proper exit point */
45*433d6423SLionel Sambuc if (*fmt == 0) break; /* too many values */
46*433d6423SLionel Sambuc
47*433d6423SLionel Sambuc if (strchr(PUNCT, *val) != NULL) {
48*433d6423SLionel Sambuc /* Time to go to the next field. */
49*433d6423SLionel Sambuc if (strchr(PUNCT, *fmt) != NULL) i++;
50*433d6423SLionel Sambuc if (*fmt++ == *val) val++;
51*433d6423SLionel Sambuc if (*fmt < 32) fmt -= *fmt; /* step back? */
52*433d6423SLionel Sambuc } else {
53*433d6423SLionel Sambuc /* Environment contains a value, get it. */
54*433d6423SLionel Sambuc switch (*fmt) {
55*433d6423SLionel Sambuc case '*': radix = -1; break;
56*433d6423SLionel Sambuc case 'd': radix = 10; break;
57*433d6423SLionel Sambuc case 'o': radix = 010; break;
58*433d6423SLionel Sambuc case 'x': radix = 0x10; break;
59*433d6423SLionel Sambuc case 'c': radix = 0; break;
60*433d6423SLionel Sambuc default: goto badenv;
61*433d6423SLionel Sambuc }
62*433d6423SLionel Sambuc
63*433d6423SLionel Sambuc if (radix < 0) {
64*433d6423SLionel Sambuc /* Skip. */
65*433d6423SLionel Sambuc while (strchr(PUNCT, *val) == NULL) val++;
66*433d6423SLionel Sambuc continue;
67*433d6423SLionel Sambuc } else {
68*433d6423SLionel Sambuc /* A number. */
69*433d6423SLionel Sambuc newpar = strtol(val, &end, radix);
70*433d6423SLionel Sambuc
71*433d6423SLionel Sambuc if (end == val) break; /* not a number */
72*433d6423SLionel Sambuc val = end;
73*433d6423SLionel Sambuc }
74*433d6423SLionel Sambuc
75*433d6423SLionel Sambuc if (i == field) {
76*433d6423SLionel Sambuc /* The field requested. */
77*433d6423SLionel Sambuc if (newpar < min || newpar > max) break;
78*433d6423SLionel Sambuc *param = newpar;
79*433d6423SLionel Sambuc r = EP_SET;
80*433d6423SLionel Sambuc }
81*433d6423SLionel Sambuc }
82*433d6423SLionel Sambuc }
83*433d6423SLionel Sambuc badenv:
84*433d6423SLionel Sambuc env_panic(env);
85*433d6423SLionel Sambuc return -1;
86*433d6423SLionel Sambuc }
87