xref: /original-bsd/usr.bin/mail/vars.c (revision c3e32dec)
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
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
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 *
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 *
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 *
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 *
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
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
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