|
|
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.