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