vars.c revision 216370
1118824Sharti/*
2118824Sharti * Copyright (c) 1980, 1993
3118824Sharti *	The Regents of the University of California.  All rights reserved.
4118824Sharti *
5118824Sharti * Redistribution and use in source and binary forms, with or without
6118824Sharti * modification, are permitted provided that the following conditions
7118824Sharti * are met:
8118824Sharti * 1. Redistributions of source code must retain the above copyright
9118824Sharti *    notice, this list of conditions and the following disclaimer.
10118824Sharti * 2. Redistributions in binary form must reproduce the above copyright
11118824Sharti *    notice, this list of conditions and the following disclaimer in the
12118824Sharti *    documentation and/or other materials provided with the distribution.
13118824Sharti * 4. Neither the name of the University nor the names of its contributors
14118824Sharti *    may be used to endorse or promote products derived from this software
15118824Sharti *    without specific prior written permission.
16118824Sharti *
17118824Sharti * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18118824Sharti * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19118824Sharti * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20118824Sharti * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21118824Sharti * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22118824Sharti * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23118824Sharti * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24118824Sharti * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25118824Sharti * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26118824Sharti * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27129357Sru * SUCH DAMAGE.
28118824Sharti */
29118824Sharti
30118824Sharti#ifndef lint
31118824Sharti#if 0
32118824Shartistatic char sccsid[] = "@(#)vars.c	8.1 (Berkeley) 6/6/93";
33118824Sharti#endif
34118824Sharti#endif /* not lint */
35118824Sharti#include <sys/cdefs.h>
36118824Sharti__FBSDID("$FreeBSD: head/usr.bin/mail/vars.c 216370 2010-12-11 08:32:16Z joel $");
37118824Sharti
38118824Sharti#include "rcv.h"
39118824Sharti#include "extern.h"
40129357Sru
41129357Sru/*
42129357Sru * Mail -- a mail program
43118824Sharti *
44118824Sharti * Variable handling stuff.
45118824Sharti */
46129357Sru
47118824Sharti/*
48118824Sharti * Assign a value to a variable.
49118824Sharti */
50118824Shartivoid
51118824Shartiassign(name, value)
52129357Sru	const char *name, *value;
53129357Sru{
54118824Sharti	struct var *vp;
55118824Sharti	int h;
56129357Sru
57118824Sharti	h = hash(name);
58118824Sharti	vp = lookup(name);
59129357Sru	if (vp == NULL) {
60118824Sharti		vp = calloc(sizeof(*vp), 1);
61118824Sharti		vp->v_name = vcopy(name);
62118824Sharti		vp->v_link = variables[h];
63118824Sharti		variables[h] = vp;
64118824Sharti	}
65129357Sru	else
66118824Sharti		vfree(vp->v_value);
67118824Sharti	vp->v_value = vcopy(value);
68118824Sharti}
69118824Sharti
70129357Sru/*
71118824Sharti * Free up a variable string.  We do not bother to allocate
72129357Sru * strings whose value is "" since they are expected to be frequent.
73118824Sharti * Thus, we cannot free same!
74129357Sru */
75118824Shartivoid
76129357Sruvfree(cp)
77118824Sharti	char *cp;
78118824Sharti{
79129357Sru	if (*cp != '\0')
80118824Sharti		(void)free(cp);
81118824Sharti}
82129357Sru
83118824Sharti/*
84129357Sru * Copy a variable value into permanent (ie, not collected after each
85129357Sru * command) space.  Do not bother to alloc space for ""
86118824Sharti */
87129357Sru
88129357Sruchar *
89129357Sruvcopy(str)
90118824Sharti	const char *str;
91129357Sru{
92129357Sru	char *new;
93281999Sbapt	unsigned len;
94118824Sharti
95118824Sharti	if (*str == '\0')
96118824Sharti		return ("");
97118824Sharti	len = strlen(str) + 1;
98118824Sharti	if ((new = malloc(len)) == NULL)
99129357Sru		err(1, "Out of memory");
100118824Sharti	bcopy(str, new, (int)len);
101129357Sru	return (new);
102118824Sharti}
103129357Sru
104118824Sharti/*
105129357Sru * Get the value of a variable and return it.
106118824Sharti * Look in the environment if its not available locally.
107129357Sru */
108118824Sharti
109129357Sruchar *
110118824Shartivalue(name)
111129357Sru	const char *name;
112118824Sharti{
113118824Sharti	struct var *vp;
114118824Sharti
115118824Sharti	if ((vp = lookup(name)) == NULL)
116129357Sru		return (getenv(name));
117118824Sharti	return (vp->v_value);
118118824Sharti}
119118824Sharti
120118824Sharti/*
121118824Sharti * Locate a variable and return its variable
122118824Sharti * node.
123118824Sharti */
124129357Sru
125118824Shartistruct var *
126118824Shartilookup(name)
127118824Sharti	const char *name;
128118824Sharti{
129118824Sharti	struct var *vp;
130118824Sharti
131118824Sharti	for (vp = variables[hash(name)]; vp != NULL; vp = vp->v_link)
132129357Sru		if (*vp->v_name == *name && equal(vp->v_name, name))
133118824Sharti			return (vp);
134118824Sharti	return (NULL);
135118824Sharti}
136129357Sru
137118824Sharti/*
138118824Sharti * Locate a group name and return it.
139118824Sharti */
140118824Sharti
141118824Shartistruct grouphead *
142118824Shartifindgroup(name)
143118824Sharti	char name[];
144129357Sru{
145129357Sru	struct grouphead *gh;
146118824Sharti
147129357Sru	for (gh = groups[hash(name)]; gh != NULL; gh = gh->g_link)
148118824Sharti		if (*gh->g_name == *name && equal(gh->g_name, name))
149118824Sharti			return (gh);
150118824Sharti	return (NULL);
151118824Sharti}
152129357Sru
153118824Sharti/*
154118824Sharti * Print a group out on stdout
155118824Sharti */
156118824Shartivoid
157118824Shartiprintgroup(name)
158118824Sharti	char name[];
159118824Sharti{
160118824Sharti	struct grouphead *gh;
161118824Sharti	struct group *gp;
162118824Sharti
163118824Sharti	if ((gh = findgroup(name)) == NULL) {
164118824Sharti		printf("\"%s\": not a group\n", name);
165118824Sharti		return;
166118824Sharti	}
167118824Sharti	printf("%s\t", gh->g_name);
168118824Sharti	for (gp = gh->g_list; gp != NULL; gp = gp->ge_link)
169129357Sru		printf(" %s", gp->ge_name);
170118824Sharti	printf("\n");
171118824Sharti}
172118824Sharti
173118824Sharti/*
174118824Sharti * Hash the passed string and return an index into
175118824Sharti * the variable or group hash table.
176118824Sharti */
177118824Shartiint
178118824Shartihash(name)
179118824Sharti	const char *name;
180129357Sru{
181118824Sharti	int h = 0;
182118824Sharti
183118824Sharti	while (*name != '\0') {
184118824Sharti		h <<= 2;
185118824Sharti		h += *name++;
186118824Sharti	}
187118824Sharti	if (h < 0 && (h = -h) < 0)
188129357Sru		h = 0;
189118824Sharti	return (h % HSHSIZE);
190129357Sru}
191129357Sru