|
|
1.1 root 1: /*
2: * sh/var.c
3: * Bourne shell.
4: * Variables.
5: */
6:
7: #include "sh.h"
8:
9: VAR *vnode();
10:
11: /*
12: * Initial variable list.
13: */
14:
15: /*
16: * Initialize variables.
17: * Clear the list, if any; reset initial values, and initialize
18: * the environment.
19: */
20: initvar(envp)
21: char **envp;
22: {
23: register char **nvp;
24: char *wd;
25: static struct initvals {
26: int i_flag;
27: char *i_name;
28: } initvals[] = {
29: VSET, "IFS= \t\n",
30: VSET, "PS2=> ",
31: VSET, "PS1=$ ",
32: VSET, "MAIL=",
33: VSET, "PATH=:/bin:/usr/bin",
34: VSET, "HOME=",
35: VSET, "CWD=",
36: VSET, "VERSION=" VERSION,
37: 0, NULL
38: };
39: static char lasterror[] = "LASTERROR";
40:
41: if (varp) {
42: register VAR *vp, *tvp;
43:
44: for (vp = varp; tvp = vp; ) {
45: vp = vp->v_next;
46: sfree(tvp->v_strp);
47: sfree(tvp);
48: }
49: varp = NULL;
50: }
51:
52: {
53: register struct initvals *ivp;
54:
55: for (ivp=initvals; ivp->i_name != NULL; ivp+=1)
56: flagvar(ivp->i_name, ivp->i_flag);
57: }
58: if (senvp != NULL) {
59: vfree(senvp);
60: }
61: senvp = envp;
62: for (nvp = senvp; nvp && *nvp != NULL; )
63: setsvar(*nvp++);
64: if (findvar(lasterror) == NULL)
65: flagvar(lasterror, VEXP);
66: if (findvar("CWD") == NULL)
67: flagvar("CWD", VEXP);
68: if ((wd = _getwd()) == NULL)
69: wd = "."; /* _getwd() failed */
70: dstack[dstkp] = wd = duplstr(wd, 1); /* to dstack */
71: assnvar("CWD", wd); /* and to $CWD */
72: }
73:
74: /*
75: * Make sure the given variable name is valid.
76: * Only user settable names are accepted.
77: */
78: namevar(np)
79: char *np;
80: {
81: register int c;
82: register char *cp;
83:
84: cp = np;
85: if (class(*cp, MBVAR)) {
86: do c = *cp++;
87: while (class(c, MRVAR));
88: if (c=='\0' || c=='=')
89: return (1);
90: }
91: return (0);
92: }
93:
94: /*
95: * Return a pointer to the given variable.
96: */
97: VAR *
98: findvar(cp)
99: register char *cp;
100: {
101: register VAR *vp;
102:
103: for (vp=varp; vp; vp=vp->v_next)
104: if (vareq(cp, vp->v_strp))
105: break;
106: return (vp);
107: }
108:
109: /*
110: * Given a variable pointer, return a pointer to a string
111: * containing the value.
112: */
113: char *
114: convvar(vp)
115: register VAR *vp;
116: {
117: register char *cp;
118:
119: cp = vp->v_strp;
120: for (;;) {
121: if (*cp == '\0')
122: return (NULL);
123: if (*cp++ == '=')
124: return (cp);
125: }
126: }
127:
128: /*
129: * Assign a value to the given shell variable.
130: */
131: VAR *
132: assnvar(np, cp)
133: char *np;
134: char *cp;
135: {
136: strt[0] = '\0';
137: strcat(strt, np);
138: strcat(strt, "=");
139: strcat(strt, cp);
140: return (setsvar(strt));
141: }
142:
143: /*
144: * Set the given shell variable.
145: */
146: VAR *
147: setsvar(cp)
148: register char *cp;
149: {
150: register VAR *vp;
151:
152: #ifdef VERBOSE
153: if (xflag)
154: prints("<%d> setsvar(%s)\n", getpid(), cp);
155: #endif
156: if ((vp=findvar(cp)) == NULL)
157: vp = varp = vnode(0, NULL, varp);
158: if (vp->v_flag & VRDO) {
159: printe("Cannot set %s", cp);
160: return (NULL);
161: }
162: sfree(vp->v_strp);
163: vp->v_strp = duplstr(cp, 1);
164: if (vp->v_flag & VSET)
165: setsint(vp->v_strp);
166: return (vp);
167: }
168:
169: /*
170: * Set the internal variable to the shell variable.
171: */
172: setsint(np)
173: register char *np;
174: {
175: register char *cp;
176: static struct intsvals {
177: char *j_name;
178: char **j_save;
179: } intsvals[] = {
180: "HOME", &vhome,
181: "IFS", &vifs,
182: "MAIL", &vmail,
183: "PATH", &vpath,
184: "PS1", &vps1,
185: "PS2", &vps2,
186: NULL, NULL
187: };
188: register struct intsvals *ivp;
189:
190: cp = np;
191: while (*cp != '\0')
192: if (*cp++ == '=')
193: break;
194: for (ivp=intsvals; ivp->j_name != NULL; ivp+=1)
195: if (vareq(ivp->j_name, np)) {
196: *ivp->j_save = cp;
197: break;
198: }
199: }
200:
201: /*
202: * Set flags in the shell variable.
203: */
204: VAR *
205: flagvar(cp, f)
206: register char *cp;
207: {
208: register VAR *vp;
209:
210: if ((vp=findvar(cp)) == NULL)
211: vp = varp = vnode(f, duplstr(cp, 1), varp);
212: else if (index(cp, '=') != NULL
213: && (vp = setsvar(cp)) == NULL)
214: return (NULL);
215: vp->v_flag |= f;
216: if (f & VEXP)
217: setsexp(vp->v_strp);
218: if (f & VSET)
219: setsint(vp->v_strp);
220: return (vp);
221: }
222:
223: setsexp(np)
224: register char *np;
225: {
226: register char **envp;
227:
228: /* New export values supersede inherited ones */
229: for (envp=senvp; envp && *envp; envp+=1)
230: if (vareq(np, *envp)) {
231: do envp[0]=envp[1];
232: while (*envp++ != NULL);
233: break;
234: }
235: }
236:
237: /*
238: * See if two variable names are equal.
239: */
240: vareq(cp1, cp2)
241: register char *cp1;
242: register char *cp2;
243: {
244: int c2;
245: register int c1;
246:
247: for (;;) {
248: if ((c1=*cp1++) == '\0')
249: c1 = '=';
250: if ((c2=*cp2++) == '\0')
251: c2 = '=';
252: if (c1 != c2)
253: return (0);
254: if (c1 == '=')
255: return (1);
256: }
257: }
258:
259: /*
260: * Report function for variables.
261: */
262: tellvar(f)
263: {
264: register VAR *vp;
265: register char **evp;
266:
267: if (f==VEXP)
268: for (evp=senvp; evp && *evp; )
269: prints("%s\n", *evp++);
270: for (vp=varp; vp; vp=vp->v_next)
271: if (f==0 || (vp->v_flag&f))
272: prints("%s\n", vp->v_strp);
273: }
274:
275: /*
276: * Scan the varlist for exportables.
277: * If an exportable matches a variable already in envp, forget it.
278: */
279: char **
280: envlvar(envp)
281: char **envp;
282: {
283: register char **enpp;
284: register char **oenvp;
285: register VAR *vp;
286:
287: for (oenvp=senvp; oenvp && *oenvp; oenvp+=1) {
288: for (enpp=envp; ; enpp+=1)
289: if (*enpp==NULL || vareq(*oenvp, *enpp))
290: break;
291: if (*enpp==NULL)
292: envp = addargl(envp, duplstr(*oenvp, 0));
293: }
294: for (vp=varp; vp; vp=vp->v_next) {
295: if (vp->v_flag&VEXP) {
296: for (enpp=envp; ; enpp+=1)
297: if (*enpp==NULL || vareq(*enpp, vp->v_strp))
298: break;
299: if (*enpp==NULL)
300: envp = addargl(envp, duplstr(vp->v_strp, 0));
301: }
302: }
303: return (envp);
304: }
305:
306: VAR *
307: vnode(f, s, n)
308: char *s;
309: VAR *n;
310: {
311: register VAR *vp;
312:
313: vp = (VAR *)salloc(sizeof *vp);
314: vp->v_flag = f;
315: vp->v_strp = s;
316: vp->v_next = n;
317: return (vp);
318: }
319:
320: /* end of sh/var.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.