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