1 /*
2 * Copyright (c) 1980, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 */
7
8 #ifndef lint
9 static char sccsid[] = "@(#)vars.c 8.1 (Berkeley) 06/06/93";
10 #endif /* not lint */
11
12 #include "rcv.h"
13 #include "extern.h"
14
15 /*
16 * Mail -- a mail program
17 *
18 * Variable handling stuff.
19 */
20
21 /*
22 * Assign a value to a variable.
23 */
24 void
assign(name,value)25 assign(name, value)
26 char name[], value[];
27 {
28 register struct var *vp;
29 register int h;
30
31 h = hash(name);
32 vp = lookup(name);
33 if (vp == NOVAR) {
34 vp = (struct var *) calloc(sizeof *vp, 1);
35 vp->v_name = vcopy(name);
36 vp->v_link = variables[h];
37 variables[h] = vp;
38 }
39 else
40 vfree(vp->v_value);
41 vp->v_value = vcopy(value);
42 }
43
44 /*
45 * Free up a variable string. We do not bother to allocate
46 * strings whose value is "" since they are expected to be frequent.
47 * Thus, we cannot free same!
48 */
49 void
vfree(cp)50 vfree(cp)
51 char *cp;
52 {
53 if (*cp)
54 free(cp);
55 }
56
57 /*
58 * Copy a variable value into permanent (ie, not collected after each
59 * command) space. Do not bother to alloc space for ""
60 */
61
62 char *
vcopy(str)63 vcopy(str)
64 char str[];
65 {
66 char *new;
67 unsigned len;
68
69 if (*str == '\0')
70 return "";
71 len = strlen(str) + 1;
72 if ((new = malloc(len)) == NULL)
73 panic("Out of memory");
74 bcopy(str, new, (int) len);
75 return new;
76 }
77
78 /*
79 * Get the value of a variable and return it.
80 * Look in the environment if its not available locally.
81 */
82
83 char *
value(name)84 value(name)
85 char name[];
86 {
87 register struct var *vp;
88
89 if ((vp = lookup(name)) == NOVAR)
90 return(getenv(name));
91 return(vp->v_value);
92 }
93
94 /*
95 * Locate a variable and return its variable
96 * node.
97 */
98
99 struct var *
lookup(name)100 lookup(name)
101 register char name[];
102 {
103 register struct var *vp;
104
105 for (vp = variables[hash(name)]; vp != NOVAR; vp = vp->v_link)
106 if (*vp->v_name == *name && equal(vp->v_name, name))
107 return(vp);
108 return(NOVAR);
109 }
110
111 /*
112 * Locate a group name and return it.
113 */
114
115 struct grouphead *
findgroup(name)116 findgroup(name)
117 register char name[];
118 {
119 register struct grouphead *gh;
120
121 for (gh = groups[hash(name)]; gh != NOGRP; gh = gh->g_link)
122 if (*gh->g_name == *name && equal(gh->g_name, name))
123 return(gh);
124 return(NOGRP);
125 }
126
127 /*
128 * Print a group out on stdout
129 */
130 void
printgroup(name)131 printgroup(name)
132 char name[];
133 {
134 register struct grouphead *gh;
135 register struct group *gp;
136
137 if ((gh = findgroup(name)) == NOGRP) {
138 printf("\"%s\": not a group\n", name);
139 return;
140 }
141 printf("%s\t", gh->g_name);
142 for (gp = gh->g_list; gp != NOGE; gp = gp->ge_link)
143 printf(" %s", gp->ge_name);
144 putchar('\n');
145 }
146
147 /*
148 * Hash the passed string and return an index into
149 * the variable or group hash table.
150 */
151 int
hash(name)152 hash(name)
153 register char *name;
154 {
155 register h = 0;
156
157 while (*name) {
158 h <<= 2;
159 h += *name++;
160 }
161 if (h < 0 && (h = -h) < 0)
162 h = 0;
163 return (h % HSHSIZE);
164 }
165