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