1: /* 2: * Copyright (c) 1980 Regents of the University of California. 3: * All rights reserved. 4: * 5: * Redistribution and use in source and binary forms, with or without 6: * modification, are permitted provided that the following conditions 7: * are met: 8: * 1. Redistributions of source code must retain the above copyright 9: * notice, this list of conditions and the following disclaimer. 10: * 2. Redistributions in binary form must reproduce the above copyright 11: * notice, this list of conditions and the following disclaimer in the 12: * documentation and/or other materials provided with the distribution. 13: * 3. All advertising materials mentioning features or use of this software 14: * must display the following acknowledgement: 15: * This product includes software developed by the University of 16: * California, Berkeley and its contributors. 17: * 4. Neither the name of the University nor the names of its contributors 18: * may be used to endorse or promote products derived from this software 19: * without specific prior written permission. 20: * 21: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31: * SUCH DAMAGE. 32: */ 33: 34: #if !defined(lint) && defined(DOSCCS) 35: static char sccsid[] = "@(#)vars.c 5.6 (Berkeley) 6/1/90"; 36: #endif 37: 38: #include "rcv.h" 39: 40: /* 41: * Mail -- a mail program 42: * 43: * Variable handling stuff. 44: */ 45: 46: /* 47: * Assign a value to a variable. 48: */ 49: 50: assign(name, value) 51: char name[], value[]; 52: { 53: register struct var *vp; 54: register int h; 55: 56: h = hash(name); 57: vp = lookup(name); 58: if (vp == NOVAR) { 59: vp = (struct var *) calloc(sizeof *vp, 1); 60: vp->v_name = vcopy(name); 61: vp->v_link = variables[h]; 62: variables[h] = vp; 63: } 64: else 65: vfree(vp->v_value); 66: vp->v_value = vcopy(value); 67: } 68: 69: /* 70: * Free up a variable string. We do not bother to allocate 71: * strings whose value is "" since they are expected to be frequent. 72: * Thus, we cannot free same! 73: */ 74: 75: vfree(cp) 76: char *cp; 77: { 78: if (*cp) 79: free(cp); 80: } 81: 82: /* 83: * Copy a variable value into permanent (ie, not collected after each 84: * command) space. Do not bother to alloc space for "" 85: */ 86: 87: char * 88: vcopy(str) 89: char str[]; 90: { 91: char *new; 92: unsigned len; 93: 94: if (*str == '\0') 95: return ""; 96: len = strlen(str) + 1; 97: if ((new = malloc(len)) == NULL) 98: panic("Out of memory"); 99: bcopy(str, new, (int) len); 100: return new; 101: } 102: 103: /* 104: * Get the value of a variable and return it. 105: * Look in the environment if its not available locally. 106: */ 107: 108: char * 109: value(name) 110: char name[]; 111: { 112: register struct var *vp; 113: 114: if ((vp = lookup(name)) == NOVAR) 115: return(getenv(name)); 116: return(vp->v_value); 117: } 118: 119: /* 120: * Locate a variable and return its variable 121: * node. 122: */ 123: 124: struct var * 125: lookup(name) 126: register char name[]; 127: { 128: register struct var *vp; 129: 130: for (vp = variables[hash(name)]; vp != NOVAR; vp = vp->v_link) 131: if (*vp->v_name == *name && equal(vp->v_name, name)) 132: return(vp); 133: return(NOVAR); 134: } 135: 136: /* 137: * Locate a group name and return it. 138: */ 139: 140: struct grouphead * 141: findgroup(name) 142: register char name[]; 143: { 144: register struct grouphead *gh; 145: 146: for (gh = groups[hash(name)]; gh != NOGRP; gh = gh->g_link) 147: if (*gh->g_name == *name && equal(gh->g_name, name)) 148: return(gh); 149: return(NOGRP); 150: } 151: 152: /* 153: * Print a group out on stdout 154: */ 155: 156: printgroup(name) 157: char name[]; 158: { 159: register struct grouphead *gh; 160: register struct group *gp; 161: 162: if ((gh = findgroup(name)) == NOGRP) { 163: printf("\"%s\": not a group\n", name); 164: return; 165: } 166: printf("%s\t", gh->g_name); 167: for (gp = gh->g_list; gp != NOGE; gp = gp->ge_link) 168: printf(" %s", gp->ge_name); 169: putchar('\n'); 170: } 171: 172: /* 173: * Hash the passed string and return an index into 174: * the variable or group hash table. 175: */ 176: 177: hash(name) 178: register char *name; 179: { 180: register h = 0; 181: 182: while (*name) { 183: h <<= 2; 184: h += *name++; 185: } 186: if (h < 0 && (h = -h) < 0) 187: h = 0; 188: return (h % HSHSIZE); 189: }