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