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