xref: /illumos-gate/usr/src/cmd/mailx/vars.c (revision ac91f7fcbb405541a1605c4c45a4de8b5c91089a)
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
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
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
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 *
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 *
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 *
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 *
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
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
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