xref: /openbsd-src/usr.bin/rdist/distopt.c (revision b2ea75c1b17e1a9a339660e7ed45cd24946b230e)
1 /*	$OpenBSD: distopt.c,v 1.5 1999/02/04 23:18:57 millert Exp $	*/
2 
3 /*
4  * Copyright (c) 1983 Regents of the University of California.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *	This product includes software developed by the University of
18  *	California, Berkeley and its contributors.
19  * 4. Neither the name of the University nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software
21  *    without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  */
35 
36 #ifndef lint
37 #if 0
38 static char RCSid[] =
39 "$From: distopt.c,v 6.10 1996/01/30 01:52:07 mcooper Exp $";
40 #else
41 static char RCSid[] =
42 "$OpenBSD: distopt.c,v 1.5 1999/02/04 23:18:57 millert Exp $";
43 #endif
44 
45 static char sccsid[] = "@(#)distopt.c";
46 
47 static char copyright[] =
48 "@(#) Copyright (c) 1983 Regents of the University of California.\n\
49  All rights reserved.\n";
50 #endif /* !lint */
51 
52 /*
53  * Dist Option functions
54  */
55 
56 #include "defs.h"
57 
58 /*
59  * Distfile Option Information
60  */
61 DISTOPTINFO distoptinfo[] = {
62 	{ DO_CHKNFS,		"chknfs" },
63 	{ DO_CHKREADONLY,	"chkreadonly" },
64 	{ DO_CHKSYM,		"chksym" },
65 	{ DO_COMPARE,		"compare" },
66 	{ DO_FOLLOW,		"follow" },
67 	{ DO_IGNLNKS,		"ignlnks" },
68 	{ DO_NOCHKGROUP,	"nochkgroup" },
69 	{ DO_NOCHKMODE,		"nochkmode" },
70 	{ DO_NOCHKOWNER,	"nochkowner" },
71 	{ DO_NODESCEND,		"nodescend" },
72 	{ DO_NOEXEC,		"noexec" },
73 	{ DO_NUMCHKGROUP,	"numchkgroup" },
74 	{ DO_NUMCHKOWNER,	"numchkowner" },
75 	{ DO_QUIET,		"quiet" },
76 	{ DO_REMOVE,		"remove" },
77 	{ DO_SAVETARGETS,	"savetargets" },
78 	{ DO_SPARSE,            "sparse" },
79 	{ DO_VERIFY,		"verify" },
80 	{ DO_WHOLE,		"whole" },
81 	{ DO_YOUNGER,		"younger" },
82 	{ 0 },
83 };
84 
85 /*
86  * Get a Distfile Option entry named "name".
87  */
88 extern DISTOPTINFO *getdistopt(name)
89 	char *name;
90 {
91 	register int i;
92 
93 	for (i = 0; distoptinfo[i].do_name; ++i)
94 		if (strcasecmp(name, distoptinfo[i].do_name) == 0)
95 			return(&distoptinfo[i]);
96 
97 	return(NULL);
98 }
99 
100 /*
101  * Parse a dist option string.  Set option flags to optptr.
102  * If doerrs is true, print out own error message.  Returns
103  * 0 on success.
104  */
105 extern int parsedistopts(str, optptr, doerrs)
106 	char *str;
107 	opt_t *optptr;
108 	int doerrs;
109 {
110 	register char *string, *optstr;
111 	DISTOPTINFO *distopt;
112 	int negate;
113 
114 	/* strtok() is harmful */
115 	string = xstrdup(str);
116 
117 	for (optstr = strtok(string, ","); optstr;
118 	     optstr = strtok(NULL, ",")) {
119 		if (strncasecmp(optstr, "no", 2) == 0)
120 			negate = TRUE;
121 		else
122 			negate = FALSE;
123 
124 		/*
125 		 * Try looking up option name.  If that fails
126 		 * and the option starts with "no", strip "no"
127 		 * from option and retry lookup.
128 		 */
129 		if ((distopt = getdistopt(optstr))) {
130 			FLAG_ON(*optptr, distopt->do_value);
131 			continue;
132 		}
133 		if (negate && (distopt = getdistopt(optstr+2))) {
134 			FLAG_OFF(*optptr, distopt->do_value);
135 			continue;
136 		}
137 		if (doerrs)
138 			error("Dist option \"%s\" is not valid.", optstr);
139 	}
140 
141 	if (string)
142 		(void) free(string);
143 
144 	return(nerrs);
145 }
146 
147 /*
148  * Get a list of the Distfile Option Entries.
149  */
150 extern char *getdistoptlist()
151 {
152 	register int i;
153 	static char buf[1024];
154 
155 	for (i = 0, buf[0] = CNULL; distoptinfo[i].do_name; ++i) {
156 		if (buf[0] == CNULL)
157 			(void) strcpy(buf, distoptinfo[i].do_name);
158 		else {
159 			(void) strcat(buf, ",");
160 			(void) strcat(buf, distoptinfo[i].do_name);
161 		}
162 	}
163 
164 	return(buf);
165 }
166 
167 /*
168  * Get a list of the Distfile Option Entries for each enabled
169  * value in "opts".
170  */
171 extern char *getondistoptlist(opts)
172 	opt_t opts;
173 {
174 	register int i;
175 	static char buf[1024];
176 
177 	for (i = 0, buf[0] = CNULL; distoptinfo[i].do_name; ++i) {
178 		if (!IS_ON(opts, distoptinfo[i].do_value))
179 			continue;
180 
181 		if (buf[0] == CNULL)
182 			(void) strcpy(buf, distoptinfo[i].do_name);
183 		else {
184 			(void) strcat(buf, ",");
185 			(void) strcat(buf, distoptinfo[i].do_name);
186 		}
187 	}
188 
189 	return(buf);
190 }
191 
192