1: /* $Header: /home/hyperion/mu/christos/src/sys/tcsh-6.00/RCS/tw.init.c,v 3.0 1991/07/04 21:49:28 christos Exp $ */ 2: /* 3: * tw.init.c: TwENEX initializations 4: */ 5: /*- 6: * Copyright (c) 1980, 1991 The Regents of the University of California. 7: * All rights reserved. 8: * 9: * Redistribution and use in source and binary forms, with or without 10: * modification, are permitted provided that the following conditions 11: * are met: 12: * 1. Redistributions of source code must retain the above copyright 13: * notice, this list of conditions and the following disclaimer. 14: * 2. Redistributions in binary form must reproduce the above copyright 15: * notice, this list of conditions and the following disclaimer in the 16: * documentation and/or other materials provided with the distribution. 17: * 3. All advertising materials mentioning features or use of this software 18: * must display the following acknowledgement: 19: * This product includes software developed by the University of 20: * California, Berkeley and its contributors. 21: * 4. Neither the name of the University nor the names of its contributors 22: * may be used to endorse or promote products derived from this software 23: * without specific prior written permission. 24: * 25: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 26: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 29: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35: * SUCH DAMAGE. 36: */ 37: #include "config.h" 38: #if !defined(lint) && !defined(pdp11) 39: static char *rcsid() 40: { return "$Id: tw.init.c,v 3.0 1991/07/04 21:49:28 christos Exp $"; } 41: #endif 42: 43: #include "sh.h" 44: #include "tw.h" 45: 46: /* 47: * Build the command name list (and print the results). This is a HACK until 48: * I can get the rehash command to include its results in the command list. 49: */ 50: 51: static int maxcommands = 0; 52: 53: 54: void 55: tw_clear_comm_list() 56: { 57: register int i; 58: 59: have_sorted = 0; 60: if (numcommands != 0) { 61: /* for (i = 0; com_list[i]; i++) { */ 62: for (i = 0; i < numcommands; i++) { 63: xfree((ptr_t) com_list[i]); 64: com_list[i] = NULL; 65: } 66: numcommands = 0; 67: } 68: } 69: 70: void 71: tw_sort_comms() 72: { /* could be re-written */ 73: register int i, forward; 74: 75: /* sort the list. */ 76: qsort((ptr_t) com_list, (size_t) numcommands, sizeof(com_list[0]), 77: (int (*) __P((const void *, const void *))) fcompare); 78: 79: /* get rid of multiple entries */ 80: for (i = 0, forward = 0; i < numcommands - 1; i++) { 81: if (Strcmp(com_list[i], com_list[i + 1]) == 0) { /* garbage */ 82: xfree((ptr_t) com_list[i]); 83: forward++; /* increase the forward ref. count */ 84: } 85: else if (forward) { 86: com_list[i - forward] = com_list[i]; 87: } 88: } 89: /* Fix fencepost error -- Theodore Ts'o <tytso@athena.mit.edu> */ 90: if (forward) 91: com_list[i - forward] = com_list[i]; 92: numcommands -= forward; 93: com_list[numcommands] = (Char *) NULL; 94: 95: have_sorted = 1; 96: } 97: 98: void 99: tw_comm_name_add(name) /* this is going to be called a LOT at startup */ 100: Char *name; 101: { 102: register int length; 103: register long i; 104: register Char **ncl, **p1, **p2; 105: 106: if (maxcommands == 0) { 107: com_list = (Char **) xmalloc((size_t) (NUMCMDS_START * 108: sizeof(com_list[0]))); 109: maxcommands = NUMCMDS_START; 110: for (i = 0, p2 = com_list; i < maxcommands; i++) 111: *p2++ = NULL; /* jpn: if need to loop, might as well do it all */ 112: } 113: else if (numcommands >= maxcommands) { 114: ncl = (Char **) xmalloc((size_t) ((maxcommands + NUMCMDS_INCR) * 115: sizeof(com_list[0]))); 116: for (i = 0, p1 = com_list, p2 = ncl; i < numcommands; i++) 117: *p2++ = *p1++; 118: for (; i < maxcommands + NUMCMDS_INCR; i++) 119: *p2++ = NULL; 120: xfree((ptr_t) com_list); 121: com_list = ncl; 122: #ifdef COMMENT 123: com_list = (Char **) xrealloc(com_list, (maxcommands + 124: NUMCMDS_INCR) * sizeof(com_list[0])); 125: #endif 126: maxcommands += NUMCMDS_INCR; 127: } 128: 129: if (name[0] == '.') 130: return; /* no dot commands... */ 131: if (name[0] == '#') 132: return; /* no Emacs buffer checkpoints */ 133: 134: length = Strlen(name) + 1; 135: 136: if (name[length - 2] == '~') 137: return; /* and no Emacs backups either */ 138: 139: com_list[numcommands] = (Char *) xmalloc((size_t) (length * 140: sizeof(Char))); 141: 142: copyn(com_list[numcommands], name, MAXNAMLEN); 143: numcommands++; 144: } 145: 146: void 147: tw_builtins_add() 148: { 149: register struct biltins *bptr; 150: 151: for (bptr = bfunc; bptr < &bfunc[nbfunc]; bptr++) { 152: if (bptr->bname) 153: tw_comm_name_add(str2short(bptr->bname)); 154: } 155: } 156: 157: void 158: tw_aliases_add() 159: { 160: register struct varent *p; 161: register struct varent *c; 162: 163: p = &aliases; 164: for (;;) { 165: while (p->v_left) 166: p = p->v_left; 167: x: 168: if (p->v_parent == 0) /* is it the header? */ 169: return; 170: if (p->v_name) 171: tw_comm_name_add(p->v_name); 172: if (p->v_right) { 173: p = p->v_right; 174: continue; 175: } 176: do { 177: c = p; 178: p = p->v_parent; 179: } while (p->v_right == c); 180: goto x; 181: } 182: 183: } 184: 185: struct varent * 186: tw_shell_list_start() 187: { 188: register struct varent *p; 189: register struct varent *c; 190: 191: p = &shvhed; /* start at beginning of variable list */ 192: 193: for (;;) { 194: while (p->v_left) 195: p = p->v_left; 196: x: 197: if (p->v_parent == 0) /* is it the header? */ 198: return (NULL); 199: if (p->v_name) 200: return (p); /* found first one */ 201: if (p->v_right) { 202: p = p->v_right; 203: continue; 204: } 205: do { 206: c = p; 207: p = p->v_parent; 208: } while (p->v_right == c); 209: goto x; 210: } 211: } 212: 213: Char * 214: tw_n_shell_var(vptr) 215: struct varent **vptr; 216: { 217: register struct varent *p; 218: register struct varent *c; 219: register Char *cp; 220: 221: if ((p = *vptr) == NULL) 222: return (NULL); /* just in case */ 223: 224: cp = p->v_name; /* we know that this name is here now */ 225: 226: /* now find the next one */ 227: for (;;) { 228: if (p->v_right) { /* if we can go right */ 229: p = p->v_right; 230: while (p->v_left) 231: p = p->v_left; 232: } 233: else { /* else go up */ 234: do { 235: c = p; 236: p = p->v_parent; 237: } while (p->v_right == c); 238: } 239: if (p->v_parent == 0) { /* is it the header? */ 240: *vptr = NULL; 241: return (cp); 242: } 243: if (p->v_name) { 244: *vptr = p; /* save state for the next call */ 245: return (cp); 246: } 247: } 248: 249: } 250: 251: Char ** 252: tw_env_list_start() 253: { 254: return (STR_environ); 255: } 256: 257: Char * 258: Getenv(str) 259: Char *str; 260: { 261: Char **var; 262: int len, res; 263: 264: len = Strlen(str); 265: for (var = STR_environ; var != NULL && *var != NULL; var++) 266: if ((*var)[len] == '=') { 267: (*var)[len] = '\0'; 268: res = StrQcmp(*var, str); 269: (*var)[len] = '='; 270: if (res == 0) 271: return (&((*var)[len + 1])); 272: } 273: return (NULL); 274: } 275: 276: Char * 277: tw_n_env_var(evp) 278: Char ***evp; 279: { 280: static Char buffer[MAXVARLEN + 1]; 281: Char *ps, *pd; 282: 283: if (*evp == NULL || **evp == NULL) 284: return (NULL); 285: for (ps = **evp, pd = buffer; 286: *ps && *ps != '=' && pd <= &buffer[MAXVARLEN]; *pd++ = *ps++); 287: *pd = '\0'; 288: (*evp)++; 289: return (buffer); 290: }