GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/cvs/modules.c Lines: 15 111 13.5 %
Date: 2017-11-07 Branches: 1 76 1.3 %

Line Branch Exec Source
1
/*	$OpenBSD: modules.c,v 1.19 2015/11/05 09:48:21 nicm Exp $	*/
2
/*
3
 * Copyright (c) 2008 Joris Vink <joris@openbsd.org>
4
 *
5
 * Permission to use, copy, modify, and distribute this software for any
6
 * purpose with or without fee is hereby granted, provided that the above
7
 * copyright notice and this permission notice appear in all copies.
8
 *
9
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
 */
17
18
#include <sys/types.h>
19
#include <sys/dirent.h>
20
#include <sys/resource.h>
21
22
#include <ctype.h>
23
#include <stdlib.h>
24
#include <string.h>
25
26
#include "cvs.h"
27
#include "config.h"
28
29
TAILQ_HEAD(, module_info)	modules;
30
31
struct module_checkout *current_module = NULL;
32
char *module_repo_root = NULL;
33
34
void
35
cvs_parse_modules(void)
36
{
37
80
	cvs_log(LP_TRACE, "cvs_parse_modules()");
38
39
40
	TAILQ_INIT(&modules);
40
40
	cvs_read_config(CVS_PATH_MODULES, modules_parse_line);
41
40
}
42
43
void
44
cvs_modules_list(void)
45
{
46
	struct module_info *mi;
47
48
	TAILQ_FOREACH(mi, &modules, m_list)
49
		cvs_printf("%s\n", mi->mi_str);
50
}
51
52
int
53
modules_parse_line(char *line, int lineno)
54
{
55
	int flags;
56
	struct module_info *mi;
57
	char *bline, *val, *p, *module, *sp, *dp;
58
	char *dirname, fpath[PATH_MAX], *prog;
59
60
	prog = NULL;
61
	bline = xstrdup(line);
62
63
	flags = 0;
64
	p = val = line;
65
	while (!isspace((unsigned char)*p) && *p != '\0')
66
		p++;
67
68
	if (*p == '\0')
69
		goto bad;
70
71
	*(p++) = '\0';
72
	module = val;
73
74
	while (isspace((unsigned char)*p))
75
		p++;
76
77
	if (*p == '\0')
78
		goto bad;
79
80
	val = p;
81
	while (!isspace((unsigned char)*p) && *p != '\0')
82
		p++;
83
84
	while (val[0] == '-') {
85
		p = val;
86
		while (!isspace((unsigned char)*p) && *p != '\0')
87
			p++;
88
89
		if (*p == '\0')
90
			goto bad;
91
92
		*(p++) = '\0';
93
94
		switch (val[1]) {
95
		case 'a':
96
			if (flags & MODULE_TARGETDIR) {
97
				cvs_log(LP_NOTICE, "cannot use -a with -d");
98
				goto bad;
99
			}
100
			flags |= MODULE_ALIAS;
101
			break;
102
		case 'd':
103
			if (flags & MODULE_ALIAS) {
104
				cvs_log(LP_NOTICE, "cannot use -d with -a");
105
				goto bad;
106
			}
107
			flags |= MODULE_TARGETDIR;
108
			break;
109
		case 'l':
110
			flags |= MODULE_NORECURSE;
111
			break;
112
		case 'o':
113
			if (flags != 0 || prog != NULL) {
114
				cvs_log(LP_NOTICE,
115
				    "-o cannot be used with other flags");
116
				goto bad;
117
			}
118
119
			val = p;
120
			while (!isspace((unsigned char)*val) && *val != '\0')
121
				val++;
122
			if (*val == '\0')
123
				goto bad;
124
125
			*(val++) = '\0';
126
			prog = xstrdup(p);
127
			p = val;
128
			flags |= MODULE_RUN_ON_CHECKOUT;
129
			break;
130
		case 'i':
131
			if (flags != 0 || prog != NULL) {
132
				cvs_log(LP_NOTICE,
133
				    "-i cannot be used with other flags");
134
				goto bad;
135
			}
136
137
			if ((val = strchr(p, ' ' )) == NULL)
138
				goto bad;
139
140
			*(val++) = '\0';
141
			prog = xstrdup(p);
142
			p = val;
143
			flags |= MODULE_RUN_ON_COMMIT;
144
			break;
145
		default:
146
			goto bad;
147
		}
148
149
		val = p;
150
	}
151
152
	if (*val == '\0')
153
		goto bad;
154
155
	mi = xmalloc(sizeof(*mi));
156
	mi->mi_name = xstrdup(module);
157
	mi->mi_flags = flags;
158
	mi->mi_prog = prog;
159
	mi->mi_str = bline;
160
161
	dirname = NULL;
162
	RB_INIT(&(mi->mi_modules));
163
	RB_INIT(&(mi->mi_ignores));
164
165
	for (sp = val; *sp != '\0'; sp = dp) {
166
		dp = sp;
167
		while (!isspace((unsigned char)*dp) && *dp != '\0')
168
			dp++;
169
		if (*dp != '\0')
170
			*(dp++) = '\0';
171
172
		if (mi->mi_flags & MODULE_ALIAS) {
173
			if (sp[0] == '!') {
174
				if (strlen(sp) < 2)
175
					fatal("invalid ! pattern");
176
				cvs_file_get((sp + 1), 0,
177
				    &(mi->mi_ignores), 0);
178
			} else {
179
				cvs_file_get(sp, 0,
180
				    &(mi->mi_modules), 0);
181
			}
182
		} else if (sp == val) {
183
			dirname = sp;
184
		} else {
185
			if (sp[0] == '!') {
186
				if (strlen(sp) < 2)
187
					fatal("invalid ! pattern");
188
189
				sp++;
190
				(void)xsnprintf(fpath, sizeof(fpath), "%s/%s",
191
				    dirname, sp);
192
				cvs_file_get(fpath, 0,
193
				    &(mi->mi_ignores), 0);
194
			} else {
195
				(void)xsnprintf(fpath, sizeof(fpath), "%s/%s",
196
				    dirname, sp);
197
				cvs_file_get(fpath, 0,
198
				    &(mi->mi_modules), 0);
199
			}
200
		}
201
	}
202
203
	if (!(mi->mi_flags & MODULE_ALIAS) && RB_EMPTY(&(mi->mi_modules)))
204
		cvs_file_get(dirname, 0, &(mi->mi_modules), 0);
205
206
	TAILQ_INSERT_TAIL(&modules, mi, m_list);
207
	return (0);
208
209
bad:
210
	free(prog);
211
	free(bline);
212
	cvs_log(LP_NOTICE, "malformed line in CVSROOT/modules: %d", lineno);
213
	return (0);
214
}
215
216
struct module_checkout *
217
cvs_module_lookup(char *name)
218
{
219
	struct module_checkout *mc;
220
	struct module_info *mi;
221
222
32
	mc = xmalloc(sizeof(*mc));
223
224
32
	TAILQ_FOREACH(mi, &modules, m_list) {
225
		if (!strcmp(name, mi->mi_name)) {
226
			mc->mc_modules = mi->mi_modules;
227
			mc->mc_ignores = mi->mi_ignores;
228
			mc->mc_canfree = 0;
229
			mc->mc_name = mi->mi_name;
230
			mc->mc_flags = mi->mi_flags;
231
			mc->mc_prog = mi->mi_prog;
232
			return (mc);
233
		}
234
	}
235
236
16
	RB_INIT(&(mc->mc_modules));
237
16
	RB_INIT(&(mc->mc_ignores));
238
16
	cvs_file_get(name, 0, &(mc->mc_modules), 0);
239
16
	mc->mc_canfree = 1;
240
16
	mc->mc_name = name;
241
16
	mc->mc_flags = MODULE_ALIAS;
242
16
	mc->mc_prog = NULL;
243
244
16
	return (mc);
245
16
}