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