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