Annotation of src/usr.bin/mail/vars.c, Revision 1.10
1.10 ! millert 1: /* $OpenBSD: vars.c,v 1.9 2002/08/12 00:42:56 aaron Exp $ */
1.2 deraadt 2: /* $NetBSD: vars.c,v 1.4 1996/06/08 19:48:45 christos Exp $ */
3:
1.1 deraadt 4: /*
5: * Copyright (c) 1980, 1993
6: * The Regents of the University of California. All rights reserved.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
1.10 ! millert 16: * 3. Neither the name of the University nor the names of its contributors
1.1 deraadt 17: * may be used to endorse or promote products derived from this software
18: * without specific prior written permission.
19: *
20: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30: * SUCH DAMAGE.
31: */
32:
33: #ifndef lint
1.2 deraadt 34: #if 0
1.7 millert 35: static const char sccsid[] = "@(#)vars.c 8.1 (Berkeley) 6/6/93";
1.2 deraadt 36: #else
1.10 ! millert 37: static const char rcsid[] = "$OpenBSD: vars.c,v 1.9 2002/08/12 00:42:56 aaron Exp $";
1.2 deraadt 38: #endif
1.1 deraadt 39: #endif /* not lint */
40:
41: #include "rcv.h"
42: #include "extern.h"
43:
44: /*
45: * Mail -- a mail program
46: *
47: * Variable handling stuff.
48: */
49:
50: /*
51: * Assign a value to a variable.
52: */
53: void
1.7 millert 54: assign(char *name, char *value)
1.1 deraadt 55: {
1.5 millert 56: struct var *vp;
57: int h;
1.1 deraadt 58:
59: h = hash(name);
60: vp = lookup(name);
1.7 millert 61: if (vp == NULL) {
1.9 aaron 62: if ((vp = (struct var *)calloc(1, sizeof(*vp))) == NULL)
1.8 millert 63: errx(1, "Out of memory");
1.1 deraadt 64: vp->v_name = vcopy(name);
65: vp->v_link = variables[h];
66: variables[h] = vp;
67: }
68: else
69: vfree(vp->v_value);
70: vp->v_value = vcopy(value);
71: }
72:
73: /*
74: * Free up a variable string. We do not bother to allocate
75: * strings whose value is "" since they are expected to be frequent.
76: * Thus, we cannot free same!
77: */
78: void
1.7 millert 79: vfree(char *cp)
1.1 deraadt 80: {
1.7 millert 81:
1.1 deraadt 82: if (*cp)
1.4 millert 83: (void)free(cp);
1.1 deraadt 84: }
85:
86: /*
87: * Copy a variable value into permanent (ie, not collected after each
88: * command) space. Do not bother to alloc space for ""
89: */
90: char *
1.7 millert 91: vcopy(char *str)
1.1 deraadt 92: {
93: char *new;
94:
95: if (*str == '\0')
1.3 millert 96: return("");
1.7 millert 97: if ((new = strdup(str)) == NULL)
1.5 millert 98: errx(1, "Out of memory");
1.3 millert 99: return(new);
1.1 deraadt 100: }
101:
102: /*
103: * Get the value of a variable and return it.
104: * Look in the environment if its not available locally.
105: */
106:
107: char *
1.7 millert 108: value(char *name)
1.1 deraadt 109: {
1.5 millert 110: struct var *vp;
1.6 millert 111: char *env;
1.1 deraadt 112:
1.7 millert 113: if ((vp = lookup(name)) != NULL)
1.6 millert 114: return(vp->v_value);
115: else if ((env = getenv(name)))
116: return(env);
117: /* not set, see if we can provide a default */
118: else if (strcmp(name, "SHELL") == 0)
119: return(_PATH_CSHELL);
120: else if (strcmp(name, "LISTER") == 0)
121: return(_PATH_LS);
122: else if (strcmp(name, "PAGER") == 0)
123: return(_PATH_MORE);
124: else
125: return(NULL);
1.1 deraadt 126: }
127:
128: /*
129: * Locate a variable and return its variable
130: * node.
131: */
132: struct var *
1.7 millert 133: lookup(char *name)
1.1 deraadt 134: {
1.5 millert 135: struct var *vp;
1.1 deraadt 136:
1.7 millert 137: for (vp = variables[hash(name)]; vp != NULL; vp = vp->v_link)
1.1 deraadt 138: if (*vp->v_name == *name && equal(vp->v_name, name))
139: return(vp);
1.7 millert 140: return(NULL);
1.1 deraadt 141: }
142:
143: /*
144: * Locate a group name and return it.
145: */
146: struct grouphead *
1.7 millert 147: findgroup(char *name)
1.1 deraadt 148: {
1.5 millert 149: struct grouphead *gh;
1.1 deraadt 150:
1.7 millert 151: for (gh = groups[hash(name)]; gh != NULL; gh = gh->g_link)
1.1 deraadt 152: if (*gh->g_name == *name && equal(gh->g_name, name))
153: return(gh);
1.7 millert 154: return(NULL);
1.1 deraadt 155: }
156:
157: /*
158: * Print a group out on stdout
159: */
160: void
1.7 millert 161: printgroup(char *name)
1.1 deraadt 162: {
1.5 millert 163: struct grouphead *gh;
164: struct group *gp;
1.1 deraadt 165:
1.7 millert 166: if ((gh = findgroup(name)) == NULL) {
1.1 deraadt 167: printf("\"%s\": not a group\n", name);
168: return;
169: }
170: printf("%s\t", gh->g_name);
1.7 millert 171: for (gp = gh->g_list; gp != NULL; gp = gp->ge_link)
1.1 deraadt 172: printf(" %s", gp->ge_name);
173: putchar('\n');
174: }
175:
176: /*
177: * Hash the passed string and return an index into
178: * the variable or group hash table.
179: */
180: int
1.7 millert 181: hash(char *name)
1.1 deraadt 182: {
1.5 millert 183: int h = 0;
1.1 deraadt 184:
185: while (*name) {
186: h <<= 2;
187: h += *name++;
188: }
189: if (h < 0 && (h = -h) < 0)
190: h = 0;
1.3 millert 191: return(h % HSHSIZE);
1.1 deraadt 192: }