1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
23 /* All Rights Reserved */
24
25
26 /*
27 * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
28 * Use is subject to license terms.
29 */
30
31 /*
32 * University Copyright- Copyright (c) 1982, 1986, 1988
33 * The Regents of the University of California
34 * All Rights Reserved
35 *
36 * University Acknowledgment- Portions of this document are derived from
37 * software developed by the University of California, Berkeley, and its
38 * contributors.
39 */
40
41 #pragma ident "%Z%%M% %I% %E% SMI"
42
43 #include "rcv.h"
44 #include <locale.h>
45
46 /*
47 * mailx -- a modified version of a University of California at Berkeley
48 * mail program
49 *
50 * Variable handling stuff.
51 */
52
53 static struct var *lookup(char name[]);
54
55 /*
56 * Assign a value to a variable.
57 */
58 void
assign(char name[],char value[])59 assign(char name[], char value[])
60 {
61 register struct var *vp;
62 register int h;
63
64 if (name[0]=='-')
65 deassign(name+1);
66 else if (name[0]=='n' && name[1]=='o')
67 deassign(name+2);
68 else {
69 h = hash(name);
70 vp = lookup(name);
71 if (vp == NOVAR) {
72 if ((vp = (struct var *)
73 calloc(sizeof (*vp), 1)) == NULL)
74 panic("Out of memory");
75 vp->v_name = vcopy(name);
76 vp->v_link = variables[h];
77 variables[h] = vp;
78 } else
79 vfree(vp->v_value);
80 vp->v_value = vcopy(value);
81 /*
82 * for efficiency, intercept certain assignments here
83 */
84 if (strcmp(name, "prompt")==0)
85 prompt = vp->v_value;
86 else if (strcmp(name, "debug")==0)
87 debug = 1;
88 if (debug) fprintf(stderr, "assign(%s)=%s\n", vp->v_name, vp->v_value);
89 }
90 }
91
92 int
deassign(register char * s)93 deassign(register char *s)
94 {
95 register struct var *vp, *vp2;
96 register int h;
97
98 if ((vp2 = lookup(s)) == NOVAR) {
99 if (!sourcing) {
100 printf(gettext("\"%s\": undefined variable\n"), s);
101 return(1);
102 }
103 return(0);
104 }
105 if (debug) fprintf(stderr, "deassign(%s)\n", s);
106 if (strcmp(s, "prompt")==0)
107 prompt = NOSTR;
108 else if (strcmp(s, "debug")==0)
109 debug = 0;
110 h = hash(s);
111 if (vp2 == variables[h]) {
112 variables[h] = variables[h]->v_link;
113 vfree(vp2->v_name);
114 vfree(vp2->v_value);
115 free(vp2);
116 return(0);
117 }
118 for (vp = variables[h]; vp->v_link != vp2; vp = vp->v_link)
119 ;
120 vp->v_link = vp2->v_link;
121 vfree(vp2->v_name);
122 vfree(vp2->v_value);
123 free(vp2);
124 return(0);
125 }
126
127 /*
128 * Free up a variable string. We do not bother to allocate
129 * strings whose value is "" since they are expected to be frequent.
130 * Thus, we cannot free same!
131 */
132 void
vfree(register char * cp)133 vfree(register char *cp)
134 {
135 if (!equal(cp, ""))
136 free(cp);
137 }
138
139 /*
140 * Copy a variable value into permanent (ie, not collected after each
141 * command) space. Do not bother to alloc space for ""
142 */
143
144 char *
vcopy(char str[])145 vcopy(char str[])
146 {
147 register char *top, *cp, *cp2;
148
149 if (equal(str, ""))
150 return("");
151 if ((top = (char *)calloc(strlen(str)+1, 1)) == NULL)
152 panic("Out of memory");
153 cp = top;
154 cp2 = str;
155 while (*cp++ = *cp2++)
156 ;
157 return(top);
158 }
159
160 /*
161 * Get the value of a variable and return it.
162 * Look in the environment if its not available locally.
163 */
164
165 char *
value(char name[])166 value(char name[])
167 {
168 register struct var *vp;
169 register char *cp;
170
171 if ((vp = lookup(name)) == NOVAR)
172 cp = getenv(name);
173 else
174 cp = vp->v_value;
175 if (debug) fprintf(stderr, "value(%s)=%s\n", name, (cp)?cp:"");
176 return(cp);
177 }
178
179 /*
180 * Locate a variable and return its variable
181 * node.
182 */
183
184 static struct var *
lookup(char name[])185 lookup(char name[])
186 {
187 register struct var *vp;
188 register int h;
189
190 h = hash(name);
191 for (vp = variables[h]; vp != NOVAR; vp = vp->v_link)
192 if (equal(vp->v_name, name))
193 return(vp);
194 return(NOVAR);
195 }
196
197 /*
198 * Locate a group name and return it.
199 */
200
201 struct grouphead *
findgroup(char name[])202 findgroup(char name[])
203 {
204 register struct grouphead *gh;
205 register int h;
206
207 h = hash(name);
208 for (gh = groups[h]; gh != NOGRP; gh = gh->g_link)
209 if (equal(gh->g_name, name))
210 return(gh);
211 return(NOGRP);
212 }
213
214 /*
215 * Print a group out on stdout
216 */
217 void
printgroup(char name[])218 printgroup(char name[])
219 {
220 register struct grouphead *gh;
221 register struct mgroup *gp;
222
223 if ((gh = findgroup(name)) == NOGRP) {
224 printf(gettext("\"%s\": not a group\n"), name);
225 return;
226 }
227 printf("%s\t", gh->g_name);
228 for (gp = gh->g_list; gp != NOGE; gp = gp->ge_link)
229 printf(" %s", gp->ge_name);
230 printf("\n");
231 }
232
233 /*
234 * Hash the passed string and return an index into
235 * the variable or group hash table.
236 */
237
238 int
hash(char name[])239 hash(char name[])
240 {
241 register unsigned h;
242 register char *cp;
243
244 for (cp = name, h = 0; *cp; h = (h << 2) + *cp++)
245 ;
246 return(h % HSHSIZE);
247 }
248