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