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