GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/mail/vars.c Lines: 33 54 61.1 %
Date: 2017-11-07 Branches: 16 42 38.1 %

Line Branch Exec Source
1
/*	$OpenBSD: vars.c,v 1.13 2015/10/16 17:56:07 mmcc Exp $	*/
2
/*	$NetBSD: vars.c,v 1.4 1996/06/08 19:48:45 christos Exp $	*/
3
4
/*
5
 * Copyright (c) 1980, 1993
6
 *	The Regents of the University of California.  All rights reserved.
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 * 1. Redistributions of source code must retain the above copyright
12
 *    notice, this list of conditions and the following disclaimer.
13
 * 2. Redistributions in binary form must reproduce the above copyright
14
 *    notice, this list of conditions and the following disclaimer in the
15
 *    documentation and/or other materials provided with the distribution.
16
 * 3. Neither the name of the University nor the names of its contributors
17
 *    may be used to endorse or promote products derived from this software
18
 *    without specific prior written permission.
19
 *
20
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30
 * SUCH DAMAGE.
31
 */
32
33
#include "rcv.h"
34
#include "extern.h"
35
36
/*
37
 * Mail -- a mail program
38
 *
39
 * Variable handling stuff.
40
 */
41
42
/*
43
 * Assign a value to a variable.
44
 */
45
void
46
assign(char *name, char *value)
47
{
48
	struct var *vp;
49
	int h;
50
51
16
	h = hash(name);
52
8
	vp = lookup(name);
53
8
	if (vp == NULL) {
54
8
		if ((vp = calloc(1, sizeof(*vp))) == NULL)
55
			err(1, "calloc");
56
8
		vp->v_name = vcopy(name);
57
8
		vp->v_link = variables[h];
58
8
		variables[h] = vp;
59
8
	}
60
	else
61
		vfree(vp->v_value);
62
8
	vp->v_value = vcopy(value);
63
8
}
64
65
/*
66
 * Free up a variable string.  We do not bother to allocate
67
 * strings whose value is "" since they are expected to be frequent.
68
 * Thus, we cannot free same!
69
 */
70
void
71
vfree(char *cp)
72
{
73
74
	if (*cp)
75
		(void)free(cp);
76
}
77
78
/*
79
 * Copy a variable value into permanent (ie, not collected after each
80
 * command) space.  Do not bother to alloc space for ""
81
 */
82
char *
83
vcopy(char *str)
84
{
85
	char *new;
86
87
32
	if (*str == '\0')
88
8
		return("");
89
8
	if ((new = strdup(str)) == NULL)
90
		err(1, "strdup");
91
8
	return(new);
92
16
}
93
94
/*
95
 * Get the value of a variable and return it.
96
 * Look in the environment if it's not available locally.
97
 */
98
99
char *
100
value(char *name)
101
{
102
	struct var *vp;
103
	char *env;
104
105
52
	if ((vp = lookup(name)) != NULL)
106
		return(vp->v_value);
107
26
	else if ((env = getenv(name)))
108
		return(env);
109
	/* not set, see if we can provide a default */
110
26
	else if (strcmp(name, "SHELL") == 0)
111
		return(_PATH_CSHELL);
112
26
	else if (strcmp(name, "LISTER") == 0)
113
		return(_PATH_LS);
114
26
	else if (strcmp(name, "PAGER") == 0)
115
		return(_PATH_MORE);
116
	else
117
26
		return(NULL);
118
26
}
119
120
/*
121
 * Locate a variable and return its variable
122
 * node.
123
 */
124
struct var *
125
lookup(char *name)
126
{
127
	struct var *vp;
128
129
102
	for (vp = variables[hash(name)]; vp != NULL; vp = vp->v_link)
130
		if (*vp->v_name == *name && equal(vp->v_name, name))
131
			return(vp);
132
34
	return(NULL);
133
34
}
134
135
/*
136
 * Locate a group name and return it.
137
 */
138
struct grouphead *
139
findgroup(char *name)
140
{
141
	struct grouphead *gh;
142
143
6
	for (gh = groups[hash(name)]; gh != NULL; gh = gh->g_link)
144
		if (*gh->g_name == *name && equal(gh->g_name, name))
145
			return(gh);
146
2
	return(NULL);
147
2
}
148
149
/*
150
 * Print a group out on stdout
151
 */
152
void
153
printgroup(char *name)
154
{
155
	struct grouphead *gh;
156
	struct group *gp;
157
158
	if ((gh = findgroup(name)) == NULL) {
159
		printf("\"%s\": not a group\n", name);
160
		return;
161
	}
162
	printf("%s\t", gh->g_name);
163
	for (gp = gh->g_list; gp != NULL; gp = gp->ge_link)
164
		printf(" %s", gp->ge_name);
165
	putchar('\n');
166
}
167
168
/*
169
 * Hash the passed string and return an index into
170
 * the variable or group hash table.
171
 */
172
int
173
hash(char *name)
174
{
175
	int h = 0;
176
177
1272
	while (*name) {
178
528
		h <<= 2;
179
528
		h += *name++;
180
	}
181
76
	if (h < 0 && (h = -h) < 0)
182
		h = 0;
183
72
	return(h % HSHSIZE);
184
}