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