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 #include "rcv.h"
42 #include <locale.h>
43
44 /*
45 * mailx -- a modified version of a University of California at Berkeley
46 * mail program
47 *
48 * Variable handling stuff.
49 */
50
51 static struct var *lookup(char name[]);
52
53 /*
54 * Assign a value to a variable.
55 */
56 void
assign(char name[],char value[])57 assign(char name[], char value[])
58 {
59 register struct var *vp;
60 register int h;
61
62 if (name[0]=='-')
63 deassign(name+1);
64 else if (name[0]=='n' && name[1]=='o')
65 deassign(name+2);
66 else {
67 h = hash(name);
68 vp = lookup(name);
69 if (vp == NOVAR) {
70 if ((vp = (struct var *)
71 calloc(sizeof (*vp), 1)) == NULL)
72 panic("Out of memory");
73 vp->v_name = vcopy(name);
74 vp->v_link = variables[h];
75 variables[h] = vp;
76 } else
77 vfree(vp->v_value);
78 vp->v_value = vcopy(value);
79 /*
80 * for efficiency, intercept certain assignments here
81 */
82 if (strcmp(name, "prompt")==0)
83 prompt = vp->v_value;
84 else if (strcmp(name, "debug")==0)
85 debug = 1;
86 if (debug) fprintf(stderr, "assign(%s)=%s\n", vp->v_name, vp->v_value);
87 }
88 }
89
90 int
deassign(register char * s)91 deassign(register char *s)
92 {
93 register struct var *vp, *vp2;
94 register int h;
95
96 if ((vp2 = lookup(s)) == NOVAR) {
97 if (!sourcing) {
98 printf(gettext("\"%s\": undefined variable\n"), s);
99 return(1);
100 }
101 return(0);
102 }
103 if (debug) fprintf(stderr, "deassign(%s)\n", s);
104 if (strcmp(s, "prompt")==0)
105 prompt = NOSTR;
106 else if (strcmp(s, "debug")==0)
107 debug = 0;
108 h = hash(s);
109 if (vp2 == variables[h]) {
110 variables[h] = variables[h]->v_link;
111 vfree(vp2->v_name);
112 vfree(vp2->v_value);
113 free(vp2);
114 return(0);
115 }
116 for (vp = variables[h]; vp->v_link != vp2; vp = vp->v_link)
117 ;
118 vp->v_link = vp2->v_link;
119 vfree(vp2->v_name);
120 vfree(vp2->v_value);
121 free(vp2);
122 return(0);
123 }
124
125 /*
126 * Free up a variable string. We do not bother to allocate
127 * strings whose value is "" since they are expected to be frequent.
128 * Thus, we cannot free same!
129 */
130 void
vfree(register char * cp)131 vfree(register char *cp)
132 {
133 if (!equal(cp, ""))
134 free(cp);
135 }
136
137 /*
138 * Copy a variable value into permanent (ie, not collected after each
139 * command) space. Do not bother to alloc space for ""
140 */
141
142 char *
vcopy(char str[])143 vcopy(char str[])
144 {
145 register char *top, *cp, *cp2;
146
147 if (equal(str, ""))
148 return("");
149 if ((top = (char *)calloc(strlen(str)+1, 1)) == NULL)
150 panic("Out of memory");
151 cp = top;
152 cp2 = str;
153 while (*cp++ = *cp2++)
154 ;
155 return(top);
156 }
157
158 /*
159 * Get the value of a variable and return it.
160 * Look in the environment if its not available locally.
161 */
162
163 char *
value(char name[])164 value(char name[])
165 {
166 register struct var *vp;
167 register char *cp;
168
169 if ((vp = lookup(name)) == NOVAR)
170 cp = getenv(name);
171 else
172 cp = vp->v_value;
173 if (debug) fprintf(stderr, "value(%s)=%s\n", name, (cp)?cp:"");
174 return(cp);
175 }
176
177 /*
178 * Locate a variable and return its variable
179 * node.
180 */
181
182 static struct var *
lookup(char name[])183 lookup(char name[])
184 {
185 register struct var *vp;
186 register int h;
187
188 h = hash(name);
189 for (vp = variables[h]; vp != NOVAR; vp = vp->v_link)
190 if (equal(vp->v_name, name))
191 return(vp);
192 return(NOVAR);
193 }
194
195 /*
196 * Locate a group name and return it.
197 */
198
199 struct grouphead *
findgroup(char name[])200 findgroup(char name[])
201 {
202 register struct grouphead *gh;
203 register int h;
204
205 h = hash(name);
206 for (gh = groups[h]; gh != NOGRP; gh = gh->g_link)
207 if (equal(gh->g_name, name))
208 return(gh);
209 return(NOGRP);
210 }
211
212 /*
213 * Print a group out on stdout
214 */
215 void
printgroup(char name[])216 printgroup(char name[])
217 {
218 register struct grouphead *gh;
219 register struct mgroup *gp;
220
221 if ((gh = findgroup(name)) == NOGRP) {
222 printf(gettext("\"%s\": not a group\n"), name);
223 return;
224 }
225 printf("%s\t", gh->g_name);
226 for (gp = gh->g_list; gp != NOGE; gp = gp->ge_link)
227 printf(" %s", gp->ge_name);
228 printf("\n");
229 }
230
231 /*
232 * Hash the passed string and return an index into
233 * the variable or group hash table.
234 */
235
236 int
hash(char name[])237 hash(char name[])
238 {
239 register unsigned h;
240 register char *cp;
241
242 for (cp = name, h = 0; *cp; h = (h << 2) + *cp++)
243 ;
244 return(h % HSHSIZE);
245 }
246