vars.c revision 99112
1144518Sdavidxu/* 2144518Sdavidxu * Copyright (c) 1980, 1993 3144518Sdavidxu * The Regents of the University of California. All rights reserved. 4144518Sdavidxu * 5144518Sdavidxu * Redistribution and use in source and binary forms, with or without 6144518Sdavidxu * modification, are permitted provided that the following conditions 7144518Sdavidxu * are met: 8144518Sdavidxu * 1. Redistributions of source code must retain the above copyright 9144518Sdavidxu * notice, this list of conditions and the following disclaimer. 10144518Sdavidxu * 2. Redistributions in binary form must reproduce the above copyright 11144518Sdavidxu * notice, this list of conditions and the following disclaimer in the 12144518Sdavidxu * documentation and/or other materials provided with the distribution. 13144518Sdavidxu * 3. All advertising materials mentioning features or use of this software 14144518Sdavidxu * must display the following acknowledgement: 15144518Sdavidxu * This product includes software developed by the University of 16144518Sdavidxu * California, Berkeley and its contributors. 17144518Sdavidxu * 4. Neither the name of the University nor the names of its contributors 18144518Sdavidxu * may be used to endorse or promote products derived from this software 19144518Sdavidxu * without specific prior written permission. 20144518Sdavidxu * 21144518Sdavidxu * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22144518Sdavidxu * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23144518Sdavidxu * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24144518Sdavidxu * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25144518Sdavidxu * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26144518Sdavidxu * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27144518Sdavidxu * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28144518Sdavidxu * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29144518Sdavidxu * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30144518Sdavidxu * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31144518Sdavidxu * SUCH DAMAGE. 32144518Sdavidxu */ 33177853Sdavidxu 34177853Sdavidxu#ifndef lint 35177853Sdavidxu#if 0 36177853Sdavidxustatic char sccsid[] = "@(#)vars.c 8.1 (Berkeley) 6/6/93"; 37177853Sdavidxu#endif 38177853Sdavidxu#endif /* not lint */ 39177853Sdavidxu#include <sys/cdefs.h> 40177853Sdavidxu__FBSDID("$FreeBSD: head/usr.bin/mail/vars.c 99112 2002-06-30 05:25:07Z obrien $"); 41177853Sdavidxu 42163334Sdavidxu#include "rcv.h" 43163334Sdavidxu#include "extern.h" 44163334Sdavidxu 45163334Sdavidxu/* 46163334Sdavidxu * Mail -- a mail program 47163334Sdavidxu * 48163334Sdavidxu * Variable handling stuff. 49163334Sdavidxu */ 50212077Sdavidxu 51212077Sdavidxu/* 52212077Sdavidxu * Assign a value to a variable. 53212077Sdavidxu */ 54212077Sdavidxuvoid 55212077Sdavidxuassign(name, value) 56212077Sdavidxu const char *name, *value; 57144518Sdavidxu{ 58179970Sdavidxu struct var *vp; 59161680Sdavidxu int h; 60179970Sdavidxu 61179970Sdavidxu h = hash(name); 62179970Sdavidxu vp = lookup(name); 63179970Sdavidxu if (vp == NULL) { 64179970Sdavidxu vp = calloc(sizeof(*vp), 1); 65179970Sdavidxu vp->v_name = vcopy(name); 66179970Sdavidxu vp->v_link = variables[h]; 67179970Sdavidxu variables[h] = vp; 68179970Sdavidxu } 69179970Sdavidxu else 70179970Sdavidxu vfree(vp->v_value); 71179970Sdavidxu vp->v_value = vcopy(value); 72179970Sdavidxu} 73179970Sdavidxu 74179970Sdavidxu/* 75161680Sdavidxu * Free up a variable string. We do not bother to allocate 76161680Sdavidxu * strings whose value is "" since they are expected to be frequent. 77216641Sdavidxu * Thus, we cannot free same! 78216641Sdavidxu */ 79161680Sdavidxuvoid 80216641Sdavidxuvfree(cp) 81216641Sdavidxu char *cp; 82216641Sdavidxu{ 83216641Sdavidxu if (*cp != '\0') 84216641Sdavidxu (void)free(cp); 85216641Sdavidxu} 86216641Sdavidxu 87216641Sdavidxu/* 88216641Sdavidxu * Copy a variable value into permanent (ie, not collected after each 89216641Sdavidxu * command) space. Do not bother to alloc space for "" 90216641Sdavidxu */ 91216641Sdavidxu 92216641Sdavidxuchar * 93216641Sdavidxuvcopy(str) 94216641Sdavidxu const char *str; 95216641Sdavidxu{ 96216641Sdavidxu char *new; 97216641Sdavidxu unsigned len; 98216641Sdavidxu 99216641Sdavidxu if (*str == '\0') 100216641Sdavidxu return (""); 101216641Sdavidxu len = strlen(str) + 1; 102216641Sdavidxu if ((new = malloc(len)) == NULL) 103216641Sdavidxu err(1, "Out of memory"); 104216641Sdavidxu bcopy(str, new, (int)len); 105216641Sdavidxu return (new); 106216641Sdavidxu} 107216641Sdavidxu 108216641Sdavidxu/* 109216641Sdavidxu * Get the value of a variable and return it. 110216641Sdavidxu * Look in the environment if its not available locally. 111179970Sdavidxu */ 112232144Sdavidxu 113161680Sdavidxuchar * 114232144Sdavidxuvalue(name) 115232144Sdavidxu const char *name; 116179970Sdavidxu{ 117179970Sdavidxu struct var *vp; 118179970Sdavidxu 119232144Sdavidxu if ((vp = lookup(name)) == NULL) 120232144Sdavidxu return (getenv(name)); 121232144Sdavidxu return (vp->v_value); 122232144Sdavidxu} 123232144Sdavidxu 124232144Sdavidxu/* 125232144Sdavidxu * Locate a variable and return its variable 126232144Sdavidxu * node. 127232144Sdavidxu */ 128232144Sdavidxu 129179970Sdavidxustruct var * 130179970Sdavidxulookup(name) 131179970Sdavidxu const char *name; 132179970Sdavidxu{ 133179970Sdavidxu struct var *vp; 134232144Sdavidxu 135232144Sdavidxu for (vp = variables[hash(name)]; vp != NULL; vp = vp->v_link) 136179970Sdavidxu if (*vp->v_name == *name && equal(vp->v_name, name)) 137179970Sdavidxu return (vp); 138179970Sdavidxu return (NULL); 139179970Sdavidxu} 140179970Sdavidxu 141179970Sdavidxu/* 142179970Sdavidxu * Locate a group name and return it. 143232144Sdavidxu */ 144232144Sdavidxu 145179970Sdavidxustruct grouphead * 146179970Sdavidxufindgroup(name) 147179970Sdavidxu char name[]; 148179970Sdavidxu{ 149179970Sdavidxu struct grouphead *gh; 150179970Sdavidxu 151179970Sdavidxu for (gh = groups[hash(name)]; gh != NULL; gh = gh->g_link) 152161680Sdavidxu if (*gh->g_name == *name && equal(gh->g_name, name)) 153161680Sdavidxu return (gh); 154161680Sdavidxu return (NULL); 155179970Sdavidxu} 156161680Sdavidxu 157177853Sdavidxu/* 158161680Sdavidxu * Print a group out on stdout 159161680Sdavidxu */ 160161680Sdavidxuvoid 161163334Sdavidxuprintgroup(name) 162161680Sdavidxu char name[]; 163177853Sdavidxu{ 164161680Sdavidxu struct grouphead *gh; 165161680Sdavidxu struct group *gp; 166161680Sdavidxu 167161680Sdavidxu if ((gh = findgroup(name)) == NULL) { 168161680Sdavidxu printf("\"%s\": not a group\n", name); 169161680Sdavidxu return; 170177853Sdavidxu } 171161680Sdavidxu printf("%s\t", gh->g_name); 172161680Sdavidxu for (gp = gh->g_list; gp != NULL; gp = gp->ge_link) 173161680Sdavidxu printf(" %s", gp->ge_name); 174173801Sdavidxu printf("\n"); 175144518Sdavidxu} 176144518Sdavidxu 177144518Sdavidxu/* 178144518Sdavidxu * Hash the passed string and return an index into 179177853Sdavidxu * the variable or group hash table. 180177853Sdavidxu */ 181144518Sdavidxuint 182144518Sdavidxuhash(name) 183144518Sdavidxu const char *name; 184178647Sdavidxu{ 185144518Sdavidxu int h = 0; 186173801Sdavidxu 187173801Sdavidxu while (*name != '\0') { 188173801Sdavidxu h <<= 2; 189178647Sdavidxu h += *name++; 190178647Sdavidxu } 191178647Sdavidxu if (h < 0 && (h = -h) < 0) 192173801Sdavidxu h = 0; 193173801Sdavidxu return (h % HSHSIZE); 194173801Sdavidxu} 195216641Sdavidxu