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