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