2 * Heirloom mailx - a mail user agent derived from Berkeley Mail.
4 * Copyright (c) 2000-2004 Gunnar Ritter, Freiburg i. Br., Germany.
7 * Copyright (c) 1980, 1993
8 * The Regents of the University of California. All rights reserved.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the University of
21 * California, Berkeley and its contributors.
22 * 4. Neither the name of the University nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
41 static char sccsid
[] = "@(#)vars.c 2.12 (gritter) 10/1/08";
49 * Mail -- a mail program
51 * Variable handling stuff.
54 static char *canonify(const char *vn
);
55 static void vfree(char *cp
);
56 static struct var
*lookup(const char *name
);
57 static void remove_grouplist(struct grouphead
*gh
);
60 * If a variable name begins with a lowercase-character and contains at
61 * least one '@', it is converted to all-lowercase. This is necessary
62 * for lookups of names based on email addresses.
64 * Following the standard, only the part following the last '@' should
65 * be lower-cased, but practice has established otherwise here.
68 canonify(const char *vn
)
72 if (upperchar(*vn
&0377))
74 for (vp
= vn
; *vp
&& *vp
!= '@'; vp
++);
81 * Assign a value to a variable.
84 assign(const char *name
, const char *value
)
89 name
= canonify(name
);
93 vp
= (struct var
*)scalloc(1, sizeof *vp
);
94 vp
->v_name
= vcopy(name
);
95 vp
->v_link
= variables
[h
];
100 vp
->v_value
= vcopy(value
);
104 * Free up a variable string. We do not bother to allocate
105 * strings whose value is "" since they are expected to be frequent.
106 * Thus, we cannot free same!
116 * Copy a variable value into permanent (ie, not collected after each
117 * command) space. Do not bother to alloc space for ""
121 vcopy(const char *str
)
128 len
= strlen(str
) + 1;
130 memcpy(new, str
, (int) len
);
135 * Get the value of a variable and return it.
136 * Look in the environment if its not available locally.
140 value(const char *name
)
145 name
= canonify(name
);
146 if ((vp
= lookup(name
)) == NULL
) {
147 if ((vs
= getenv(name
)) != NULL
&& *vs
)
155 * Locate a variable and return its variable
160 lookup(const char *name
)
164 for (vp
= variables
[hash(name
)]; vp
!= NULL
; vp
= vp
->v_link
)
165 if (*vp
->v_name
== *name
&& equal(vp
->v_name
, name
))
171 * Locate a group name and return it.
175 findgroup(char *name
)
177 struct grouphead
*gh
;
179 for (gh
= groups
[hash(name
)]; gh
!= NULL
; gh
= gh
->g_link
)
180 if (*gh
->g_name
== *name
&& equal(gh
->g_name
, name
))
186 * Print a group out on stdout
189 printgroup(char *name
)
191 struct grouphead
*gh
;
194 if ((gh
= findgroup(name
)) == NULL
) {
195 printf(catgets(catd
, CATSET
, 202, "\"%s\": not a group\n"),
199 printf("%s\t", gh
->g_name
);
200 for (gp
= gh
->g_list
; gp
!= NULL
; gp
= gp
->ge_link
)
201 printf(" %s", gp
->ge_name
);
206 * Hash the passed string and return an index into
207 * the variable or group hash table.
210 hash(const char *name
)
218 if (h
< 0 && (h
= -h
) < 0)
220 return (h
% HSHSIZE
);
224 unset_internal(const char *name
)
226 struct var
*vp
, *vp2
;
229 name
= canonify(name
);
230 if ((vp2
= lookup(name
)) == NULL
) {
231 if (!sourcing
&& !unset_allow_undefined
) {
232 printf(catgets(catd
, CATSET
, 203,
233 "\"%s\": undefined variable\n"), name
);
239 if (vp2
== variables
[h
]) {
240 variables
[h
] = variables
[h
]->v_link
;
246 for (vp
= variables
[h
]; vp
->v_link
!= vp2
; vp
= vp
->v_link
);
247 vp
->v_link
= vp2
->v_link
;
255 remove_grouplist(struct grouphead
*gh
)
257 struct group
*gp
, *gq
;
259 if ((gp
= gh
->g_list
) != NULL
) {
260 for (; gp
; gp
= gq
) {
269 remove_group(const char *name
)
271 struct grouphead
*gh
, *gp
= NULL
;
274 for (gh
= groups
[h
]; gh
!= NULL
; gh
= gh
->g_link
) {
275 if (*gh
->g_name
== *name
&& equal(gh
->g_name
, name
)) {
276 remove_grouplist(gh
);
279 gp
->g_link
= gh
->g_link
;