|
|
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: /*
111: * Destroy a given variable. Returns -1 if the variable could not be found.
112: */
113:
114: int unsetvar (cp) char * cp; {
115: register VAR * vp, * prev;
116:
117: for (vp = varp, prev = NULL ; vp != NULL ; vp = (prev = vp)->v_next)
118: if (vareq (cp, vp->v_strp)) {
119: if (prev == NULL)
120: varp = vp->v_next;
121: else
122: prev->v_next = vp->v_next;
123: sfree (vp->v_strp);
124: sfree (vp);
125: return 0;
126: }
127: return -1;
128: }
129:
130:
131: /*
132: * Given a variable pointer, return a pointer to a string
133: * containing the value.
134: */
135: char *
136: convvar(vp)
137: register VAR *vp;
138: {
139: register char *cp;
140:
141: cp = vp->v_strp;
142: for (;;) {
143: if (*cp == '\0')
144: return (NULL);
145: if (*cp++ == '=')
146: return (cp);
147: }
148: }
149:
150: /*
151: * Assign a value to the given shell variable.
152: */
153: VAR *
154: assnvar(np, cp)
155: char *np;
156: char *cp;
157: {
158: strt[0] = '\0';
159: strcat(strt, np);
160: strcat(strt, "=");
161: strcat(strt, cp);
162: return (setsvar(strt));
163: }
164:
165: /*
166: * Set the given shell variable.
167: */
168: VAR *
169: setsvar(cp)
170: register char *cp;
171: {
172: register VAR *vp;
173:
174: #ifdef VERBOSE
175: if (xflag)
176: prints("<%d> setsvar(%s)\n", getpid(), cp);
177: #endif
178: if ((vp=findvar(cp)) == NULL)
179: vp = varp = vnode(0, NULL, varp);
180: if (vp->v_flag & VRDO) {
181: printe("Cannot set %s", cp);
182: return (NULL);
183: }
184: sfree(vp->v_strp);
185: vp->v_strp = duplstr(cp, 1);
186: if (vp->v_flag & VSET)
187: setsint(vp->v_strp);
188: return (vp);
189: }
190:
191: /*
192: * Set the internal variable to the shell variable.
193: */
194: setsint(np)
195: register char *np;
196: {
197: register char *cp;
198: static struct intsvals {
199: char *j_name;
200: char **j_save;
201: } intsvals[] = {
202: "HOME", &vhome,
203: "IFS", &vifs,
204: "MAIL", &vmail,
205: "PATH", &vpath,
206: "PS1", &vps1,
207: "PS2", &vps2,
208: NULL, NULL
209: };
210: register struct intsvals *ivp;
211:
212: cp = np;
213: while (*cp != '\0')
214: if (*cp++ == '=')
215: break;
216: for (ivp=intsvals; ivp->j_name != NULL; ivp+=1)
217: if (vareq(ivp->j_name, np)) {
218: *ivp->j_save = cp;
219: break;
220: }
221: }
222:
223: /*
224: * Set flags in the shell variable.
225: */
226: VAR *
227: flagvar(cp, f)
228: register char *cp;
229: {
230: register VAR *vp;
231:
232: if ((vp=findvar(cp)) == NULL)
233: vp = varp = vnode(f, duplstr(cp, 1), varp);
234: else if (index(cp, '=') != NULL
235: && (vp = setsvar(cp)) == NULL)
236: return (NULL);
237: vp->v_flag |= f;
238: if (f & VEXP)
239: setsexp(vp->v_strp);
240: if (f & VSET)
241: setsint(vp->v_strp);
242: return (vp);
243: }
244:
245: setsexp(np)
246: register char *np;
247: {
248: register char **envp;
249:
250: /* New export values supersede inherited ones */
251: for (envp=senvp; envp && *envp; envp+=1)
252: if (vareq(np, *envp)) {
253: do envp[0]=envp[1];
254: while (*envp++ != NULL);
255: break;
256: }
257: }
258:
259: /*
260: * See if two variable names are equal.
261: */
262: vareq(cp1, cp2)
263: register char *cp1;
264: register char *cp2;
265: {
266: int c2;
267: register int c1;
268:
269: for (;;) {
270: if ((c1=*cp1++) == '\0')
271: c1 = '=';
272: if ((c2=*cp2++) == '\0')
273: c2 = '=';
274: if (c1 != c2)
275: return (0);
276: if (c1 == '=')
277: return (1);
278: }
279: }
280:
281: /*
282: * Report function for variables.
283: */
284: tellvar(f)
285: {
286: register VAR *vp;
287: register char **evp;
288:
289: if (f==VEXP)
290: for (evp=senvp; evp && *evp; )
291: prints("%s\n", *evp++);
292: for (vp=varp; vp; vp=vp->v_next)
293: if (f==0 || (vp->v_flag&f))
294: prints("%s\n", vp->v_strp);
295: }
296:
297: /*
298: * Scan the varlist for exportables.
299: * If an exportable matches a variable already in envp, forget it.
300: */
301: char **
302: envlvar(envp)
303: char **envp;
304: {
305: register char **enpp;
306: register char **oenvp;
307: register VAR *vp;
308:
309: for (oenvp=senvp; oenvp && *oenvp; oenvp+=1) {
310: for (enpp=envp; ; enpp+=1)
311: if (*enpp==NULL || vareq(*oenvp, *enpp))
312: break;
313: if (*enpp==NULL)
314: envp = addargl(envp, duplstr(*oenvp, 0));
315: }
316: for (vp=varp; vp; vp=vp->v_next) {
317: if (vp->v_flag&VEXP) {
318: for (enpp=envp; ; enpp+=1)
319: if (*enpp==NULL || vareq(*enpp, vp->v_strp))
320: break;
321: if (*enpp==NULL)
322: envp = addargl(envp, duplstr(vp->v_strp, 0));
323: }
324: }
325: return (envp);
326: }
327:
328: VAR *
329: vnode(f, s, n)
330: char *s;
331: VAR *n;
332: {
333: register VAR *vp;
334:
335: vp = (VAR *)salloc(sizeof *vp);
336: vp->v_flag = f;
337: vp->v_strp = s;
338: vp->v_next = n;
339: return (vp);
340: }
341:
342: /* end of sh/var.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.