xref: /illumos-gate/usr/src/cmd/filesync/debug.c (revision 7c478bd9)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright 1995-2003 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate /*
28*7c478bd9Sstevel@tonic-gate  * module:
29*7c478bd9Sstevel@tonic-gate  *	debug.c
30*7c478bd9Sstevel@tonic-gate  *
31*7c478bd9Sstevel@tonic-gate  * purpose:
32*7c478bd9Sstevel@tonic-gate  *	utility routines for debugging filesync (tracing, diagnostics,
33*7c478bd9Sstevel@tonic-gate  *	and error simulation)
34*7c478bd9Sstevel@tonic-gate  *
35*7c478bd9Sstevel@tonic-gate  * contents:
36*7c478bd9Sstevel@tonic-gate  *	showflags	display a word of flags symbolicly
37*7c478bd9Sstevel@tonic-gate  *	dbg_usage	printout usage info for -D switch
38*7c478bd9Sstevel@tonic-gate  *	err_usage	printout usage info for -E switch
39*7c478bd9Sstevel@tonic-gate  *	dbg_set_error	enable an error simulation
40*7c478bd9Sstevel@tonic-gate  *	dbg_check_error	check for error simulation
41*7c478bd9Sstevel@tonic-gate  *
42*7c478bd9Sstevel@tonic-gate  *
43*7c478bd9Sstevel@tonic-gate  * note:
44*7c478bd9Sstevel@tonic-gate  *	there are numerous flag words and bit fields in this
45*7c478bd9Sstevel@tonic-gate  *	program, and it would be horrendous to just print them
46*7c478bd9Sstevel@tonic-gate  *	out in hex (in debugging output).  These routines use
47*7c478bd9Sstevel@tonic-gate  *	a "flaglist" data structure to map between bits and
48*7c478bd9Sstevel@tonic-gate  *	character string names or descriptions.
49*7c478bd9Sstevel@tonic-gate  *
50*7c478bd9Sstevel@tonic-gate  *	a flaglist is merely a list of paired bits and name strings.
51*7c478bd9Sstevel@tonic-gate  */
52*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
53*7c478bd9Sstevel@tonic-gate 
54*7c478bd9Sstevel@tonic-gate #include <stdio.h>
55*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
56*7c478bd9Sstevel@tonic-gate #include <string.h>
57*7c478bd9Sstevel@tonic-gate #include <ctype.h>
58*7c478bd9Sstevel@tonic-gate #include <errno.h>
59*7c478bd9Sstevel@tonic-gate 
60*7c478bd9Sstevel@tonic-gate #include "filesync.h"
61*7c478bd9Sstevel@tonic-gate #include "database.h"
62*7c478bd9Sstevel@tonic-gate #include "debug.h"
63*7c478bd9Sstevel@tonic-gate 
64*7c478bd9Sstevel@tonic-gate 
65*7c478bd9Sstevel@tonic-gate /* bits in opt_debug for usage message					*/
66*7c478bd9Sstevel@tonic-gate static struct flaglist dbgflags[] =
67*7c478bd9Sstevel@tonic-gate {	DBG_BASE,	"BASE: base include building",
68*7c478bd9Sstevel@tonic-gate 	DBG_RULE,	"RULE: rule tree building",
69*7c478bd9Sstevel@tonic-gate 	DBG_STAT,	"STAT: file stats",
70*7c478bd9Sstevel@tonic-gate 	DBG_ANAL,	"ANAL: difference analysis",
71*7c478bd9Sstevel@tonic-gate 	DBG_RECON,	"RECO: reconciliation list processing",
72*7c478bd9Sstevel@tonic-gate 	DBG_VARS,	"VARS: qualification and expansion",
73*7c478bd9Sstevel@tonic-gate 	DBG_FILES,	"FILE: rule and baseline files",
74*7c478bd9Sstevel@tonic-gate 	DBG_LIST,	"LIST: tree building",
75*7c478bd9Sstevel@tonic-gate 	DBG_EVAL,	"EVAL: tree walking",
76*7c478bd9Sstevel@tonic-gate 	DBG_IGNORE,	"IGNO: ignore list",
77*7c478bd9Sstevel@tonic-gate 	DBG_MISC,	"MISC: everything else",
78*7c478bd9Sstevel@tonic-gate 	0,		0
79*7c478bd9Sstevel@tonic-gate };
80*7c478bd9Sstevel@tonic-gate 
81*7c478bd9Sstevel@tonic-gate /* bits in opt_debug for dsiplay					*/
82*7c478bd9Sstevel@tonic-gate struct flaglist dbgmap[] =
83*7c478bd9Sstevel@tonic-gate {	DBG_BASE,	"BASE",
84*7c478bd9Sstevel@tonic-gate 	DBG_RULE,	"RULE",
85*7c478bd9Sstevel@tonic-gate 	DBG_STAT,	"STAT",
86*7c478bd9Sstevel@tonic-gate 	DBG_ANAL,	"ANAL",
87*7c478bd9Sstevel@tonic-gate 	DBG_RECON,	"RECO",
88*7c478bd9Sstevel@tonic-gate 	DBG_VARS,	"VARS",
89*7c478bd9Sstevel@tonic-gate 	DBG_FILES,	"FILE",
90*7c478bd9Sstevel@tonic-gate 	DBG_LIST,	"LIST",
91*7c478bd9Sstevel@tonic-gate 	DBG_EVAL,	"EVAL",
92*7c478bd9Sstevel@tonic-gate 	DBG_IGNORE,	"IGNO",
93*7c478bd9Sstevel@tonic-gate 	DBG_MISC,	"MISC",
94*7c478bd9Sstevel@tonic-gate 	0,		0
95*7c478bd9Sstevel@tonic-gate };
96*7c478bd9Sstevel@tonic-gate 
97*7c478bd9Sstevel@tonic-gate /* bits in the rules flag field					*/
98*7c478bd9Sstevel@tonic-gate struct flaglist rflags[] =
99*7c478bd9Sstevel@tonic-gate {	R_IGNORE, 	"IGNORE",
100*7c478bd9Sstevel@tonic-gate 	R_PROGRAM,	"PROGRAM",
101*7c478bd9Sstevel@tonic-gate 	R_WILD,		"WILD",
102*7c478bd9Sstevel@tonic-gate 	R_NEW,		"NEW",
103*7c478bd9Sstevel@tonic-gate 	R_BOGUS,	"BOGUS",
104*7c478bd9Sstevel@tonic-gate 	R_RESTRICT,	"RESTRICT",
105*7c478bd9Sstevel@tonic-gate 	0,		0
106*7c478bd9Sstevel@tonic-gate };
107*7c478bd9Sstevel@tonic-gate 
108*7c478bd9Sstevel@tonic-gate /* bits in the files flag field					*/
109*7c478bd9Sstevel@tonic-gate struct flaglist fileflags[] =
110*7c478bd9Sstevel@tonic-gate {	F_NEW, 		"new",
111*7c478bd9Sstevel@tonic-gate 	F_IN_BASELINE,	"base",
112*7c478bd9Sstevel@tonic-gate 	F_IN_SOURCE,	"srce",
113*7c478bd9Sstevel@tonic-gate 	F_IN_DEST,	"dest",
114*7c478bd9Sstevel@tonic-gate 	F_EVALUATE,	"eval",
115*7c478bd9Sstevel@tonic-gate 	F_SPARSE,	"sparse",
116*7c478bd9Sstevel@tonic-gate 	F_REMOVE,	"remove",
117*7c478bd9Sstevel@tonic-gate 	F_CONFLICT,	"conflict",
118*7c478bd9Sstevel@tonic-gate 	F_LISTED,	"listed",
119*7c478bd9Sstevel@tonic-gate 	F_STAT_ERROR,	"statfail",
120*7c478bd9Sstevel@tonic-gate 	0,		0
121*7c478bd9Sstevel@tonic-gate };
122*7c478bd9Sstevel@tonic-gate 
123*7c478bd9Sstevel@tonic-gate /* bits in the file src/dst difference mask			*/
124*7c478bd9Sstevel@tonic-gate struct flaglist diffmap[] = {
125*7c478bd9Sstevel@tonic-gate 	D_CREATE,	"create",
126*7c478bd9Sstevel@tonic-gate 	D_DELETE,	"delete",
127*7c478bd9Sstevel@tonic-gate 	D_MTIME,	"modtime",
128*7c478bd9Sstevel@tonic-gate 	D_SIZE,		"size",
129*7c478bd9Sstevel@tonic-gate 	D_UID,		"uid",
130*7c478bd9Sstevel@tonic-gate 	D_GID,		"gid",
131*7c478bd9Sstevel@tonic-gate 	D_PROT,		"modes",
132*7c478bd9Sstevel@tonic-gate 	D_LINKS,	"links",
133*7c478bd9Sstevel@tonic-gate 	D_TYPE,		"type",
134*7c478bd9Sstevel@tonic-gate 	D_FACLS,	"facls",
135*7c478bd9Sstevel@tonic-gate 	D_RENAME_TO,	"rename2",
136*7c478bd9Sstevel@tonic-gate 	D_RENAME_FROM,	"renamed",
137*7c478bd9Sstevel@tonic-gate 	0,		0
138*7c478bd9Sstevel@tonic-gate };
139*7c478bd9Sstevel@tonic-gate 
140*7c478bd9Sstevel@tonic-gate /* bits in the exit error code mask				*/
141*7c478bd9Sstevel@tonic-gate struct flaglist errmap[] = {
142*7c478bd9Sstevel@tonic-gate 	ERR_RESOLVABLE,	"resolvable",
143*7c478bd9Sstevel@tonic-gate 	ERR_UNRESOLVED,	"unresolvable",
144*7c478bd9Sstevel@tonic-gate 	ERR_MISSING,	"missing files",
145*7c478bd9Sstevel@tonic-gate 	ERR_PERM,	"permissions",
146*7c478bd9Sstevel@tonic-gate 	ERR_FILES,	"rule/base errors",
147*7c478bd9Sstevel@tonic-gate 	ERR_INVAL,	"invalid arguments",
148*7c478bd9Sstevel@tonic-gate 	ERR_NOBASE,	"bad base dir",
149*7c478bd9Sstevel@tonic-gate 	ERR_OTHER,	"other",
150*7c478bd9Sstevel@tonic-gate 	0,		0
151*7c478bd9Sstevel@tonic-gate };
152*7c478bd9Sstevel@tonic-gate 
153*7c478bd9Sstevel@tonic-gate /*
154*7c478bd9Sstevel@tonic-gate  * routine:
155*7c478bd9Sstevel@tonic-gate  *	showflags
156*7c478bd9Sstevel@tonic-gate  *
157*7c478bd9Sstevel@tonic-gate  * purpose:
158*7c478bd9Sstevel@tonic-gate  *	format flags for printing
159*7c478bd9Sstevel@tonic-gate  *
160*7c478bd9Sstevel@tonic-gate  * parameters:
161*7c478bd9Sstevel@tonic-gate  *	pointer to map
162*7c478bd9Sstevel@tonic-gate  *	mask to be interpreted \
163*7c478bd9Sstevel@tonic-gate  *
164*7c478bd9Sstevel@tonic-gate  * returns:
165*7c478bd9Sstevel@tonic-gate  *	pointer to a static buffer
166*7c478bd9Sstevel@tonic-gate  */
167*7c478bd9Sstevel@tonic-gate char *
168*7c478bd9Sstevel@tonic-gate showflags(struct flaglist *map, long mask)
169*7c478bd9Sstevel@tonic-gate {	int i;
170*7c478bd9Sstevel@tonic-gate 	static char outbuf[MAX_NAME];
171*7c478bd9Sstevel@tonic-gate 
172*7c478bd9Sstevel@tonic-gate 	outbuf[0] = 0;
173*7c478bd9Sstevel@tonic-gate 	for (i = 0; map[i].fl_mask; i++)
174*7c478bd9Sstevel@tonic-gate 		if (mask & map[i].fl_mask) {
175*7c478bd9Sstevel@tonic-gate 			if (outbuf[0])
176*7c478bd9Sstevel@tonic-gate 				strcat(outbuf, "|");
177*7c478bd9Sstevel@tonic-gate 			strcat(outbuf, map[i].fl_name);
178*7c478bd9Sstevel@tonic-gate 		}
179*7c478bd9Sstevel@tonic-gate 
180*7c478bd9Sstevel@tonic-gate 	return (outbuf);
181*7c478bd9Sstevel@tonic-gate }
182*7c478bd9Sstevel@tonic-gate 
183*7c478bd9Sstevel@tonic-gate /*
184*7c478bd9Sstevel@tonic-gate  * routines:
185*7c478bd9Sstevel@tonic-gate  *	dbg_usage, err_usage
186*7c478bd9Sstevel@tonic-gate  *
187*7c478bd9Sstevel@tonic-gate  * purpose:
188*7c478bd9Sstevel@tonic-gate  *	to print out usage messages for the secret debugging flags
189*7c478bd9Sstevel@tonic-gate  *
190*7c478bd9Sstevel@tonic-gate  * returns:
191*7c478bd9Sstevel@tonic-gate  *	void
192*7c478bd9Sstevel@tonic-gate  */
193*7c478bd9Sstevel@tonic-gate void
194*7c478bd9Sstevel@tonic-gate dbg_usage(void)
195*7c478bd9Sstevel@tonic-gate {	int i;
196*7c478bd9Sstevel@tonic-gate 
197*7c478bd9Sstevel@tonic-gate 	fprintf(stderr, "Usage:\tfilesync -Dmask ...\n");
198*7c478bd9Sstevel@tonic-gate 	for (i = 0; dbgflags[i].fl_mask; i++)
199*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, "\t0x%04lx .... %s\n",
200*7c478bd9Sstevel@tonic-gate 			dbgflags[i].fl_mask, dbgflags[i].fl_name);
201*7c478bd9Sstevel@tonic-gate 	fprintf(stderr, "\n");
202*7c478bd9Sstevel@tonic-gate }
203*7c478bd9Sstevel@tonic-gate 
204*7c478bd9Sstevel@tonic-gate #ifdef	DBG_ERRORS
205*7c478bd9Sstevel@tonic-gate /*
206*7c478bd9Sstevel@tonic-gate  * The -E flag is a debugging feature that enables the user to request
207*7c478bd9Sstevel@tonic-gate  * the simulation of difficult to trigger error conditions in order
208*7c478bd9Sstevel@tonic-gate  * to test out the error handling code in filesync.  We maintain a
209*7c478bd9Sstevel@tonic-gate  * registry that specifies a file name and an operation, and an errno
210*7c478bd9Sstevel@tonic-gate  * to be returned if the specified operation is attempted on the
211*7c478bd9Sstevel@tonic-gate  * specified file.
212*7c478bd9Sstevel@tonic-gate  */
213*7c478bd9Sstevel@tonic-gate void
214*7c478bd9Sstevel@tonic-gate err_usage(void)
215*7c478bd9Sstevel@tonic-gate {
216*7c478bd9Sstevel@tonic-gate 	fprintf(stderr, "Usage:\tfilesync -E<errno>,<code>,<filename>\n");
217*7c478bd9Sstevel@tonic-gate 	fprintf(stderr, "\ts ... eval stat source\n");
218*7c478bd9Sstevel@tonic-gate 	fprintf(stderr, "\tS ... eval stat destination\n");
219*7c478bd9Sstevel@tonic-gate 	fprintf(stderr, "\tn ... eval nftw source\n");
220*7c478bd9Sstevel@tonic-gate 	fprintf(stderr, "\tN ... eval nftw destination\n");
221*7c478bd9Sstevel@tonic-gate 	fprintf(stderr, "\tc ... reconcile copy create\n");
222*7c478bd9Sstevel@tonic-gate 	fprintf(stderr, "\to ... reconcile copy open\n");
223*7c478bd9Sstevel@tonic-gate 	fprintf(stderr, "\tr ... reconcile copy read/readlink\n");
224*7c478bd9Sstevel@tonic-gate 	fprintf(stderr, "\tw ... reconcile copy write\n");
225*7c478bd9Sstevel@tonic-gate 	fprintf(stderr, "\tl ... reconcile link/symlink\n");
226*7c478bd9Sstevel@tonic-gate 	fprintf(stderr, "\tu ... reconcile unlink\n");
227*7c478bd9Sstevel@tonic-gate 	fprintf(stderr, "\td ... reconcile mkdir/mknod\n");
228*7c478bd9Sstevel@tonic-gate 	fprintf(stderr, "\tD ... reconcile rmdir\n");
229*7c478bd9Sstevel@tonic-gate 	fprintf(stderr, "\tm ... reconcile rename\n");
230*7c478bd9Sstevel@tonic-gate 	fprintf(stderr, "\tR ... reconcile restat\n");
231*7c478bd9Sstevel@tonic-gate 	fprintf(stderr, "\tp ... reconcile protection (chmod)");
232*7c478bd9Sstevel@tonic-gate 	fprintf(stderr, "\ta ... reconcile access control (setfacl)");
233*7c478bd9Sstevel@tonic-gate 	fprintf(stderr, "\tO ... reconcile ownership (chown)");
234*7c478bd9Sstevel@tonic-gate 	fprintf(stderr, "\tZ ... out of space on target\n");
235*7c478bd9Sstevel@tonic-gate 	fprintf(stderr, "\n");
236*7c478bd9Sstevel@tonic-gate }
237*7c478bd9Sstevel@tonic-gate 
238*7c478bd9Sstevel@tonic-gate /*
239*7c478bd9Sstevel@tonic-gate  * this data structure us used to keep track of the error simulations
240*7c478bd9Sstevel@tonic-gate  * that have been requested.
241*7c478bd9Sstevel@tonic-gate  */
242*7c478bd9Sstevel@tonic-gate static struct errsim {
243*7c478bd9Sstevel@tonic-gate 	int Errno;		/* error number to return	*/
244*7c478bd9Sstevel@tonic-gate 	char code;		/* event triggering the error	*/
245*7c478bd9Sstevel@tonic-gate 	char *file;		/* file name triggering error	*/
246*7c478bd9Sstevel@tonic-gate } errsim[ DBG_MAX_ERR ];
247*7c478bd9Sstevel@tonic-gate 
248*7c478bd9Sstevel@tonic-gate static int num_errs;		/* number of simulated errors	*/
249*7c478bd9Sstevel@tonic-gate 
250*7c478bd9Sstevel@tonic-gate 
251*7c478bd9Sstevel@tonic-gate /*
252*7c478bd9Sstevel@tonic-gate  * routine:
253*7c478bd9Sstevel@tonic-gate  *	dbg_set_error
254*7c478bd9Sstevel@tonic-gate  *
255*7c478bd9Sstevel@tonic-gate  * purpose:
256*7c478bd9Sstevel@tonic-gate  * 	note that we have been requested to simulate file access errors
257*7c478bd9Sstevel@tonic-gate  *
258*7c478bd9Sstevel@tonic-gate  * parameters:
259*7c478bd9Sstevel@tonic-gate  *	argument string <errno>,<errcode>,<filename>
260*7c478bd9Sstevel@tonic-gate  *
261*7c478bd9Sstevel@tonic-gate  * returns:
262*7c478bd9Sstevel@tonic-gate  *	error mask
263*7c478bd9Sstevel@tonic-gate  */
264*7c478bd9Sstevel@tonic-gate int
265*7c478bd9Sstevel@tonic-gate dbg_set_error(char *arg)
266*7c478bd9Sstevel@tonic-gate {	char *s;
267*7c478bd9Sstevel@tonic-gate 	char error_type;
268*7c478bd9Sstevel@tonic-gate 	int error_no;
269*7c478bd9Sstevel@tonic-gate 
270*7c478bd9Sstevel@tonic-gate 	if (num_errs >= DBG_MAX_ERR) {
271*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, "ERROR: only %d -E specifications allowed\n",
272*7c478bd9Sstevel@tonic-gate 				DBG_MAX_ERR);
273*7c478bd9Sstevel@tonic-gate 		return (ERR_INVAL);
274*7c478bd9Sstevel@tonic-gate 	}
275*7c478bd9Sstevel@tonic-gate 
276*7c478bd9Sstevel@tonic-gate 	/* get the error number		*/
277*7c478bd9Sstevel@tonic-gate 	if (!isdigit(arg[0]))
278*7c478bd9Sstevel@tonic-gate 		return (ERR_INVAL);
279*7c478bd9Sstevel@tonic-gate 	error_no = strtol(arg, &s, 0);
280*7c478bd9Sstevel@tonic-gate 
281*7c478bd9Sstevel@tonic-gate 	/* get the error condition	*/
282*7c478bd9Sstevel@tonic-gate 	if (*s++ != ',' || !isalpha(*s))
283*7c478bd9Sstevel@tonic-gate 		return (ERR_INVAL);
284*7c478bd9Sstevel@tonic-gate 	error_type = *s;
285*7c478bd9Sstevel@tonic-gate 
286*7c478bd9Sstevel@tonic-gate 	/* get the file name		*/
287*7c478bd9Sstevel@tonic-gate 	while (*s && *s != ',') s++;
288*7c478bd9Sstevel@tonic-gate 	if (*s++ != ',' || *s == 0)
289*7c478bd9Sstevel@tonic-gate 		return (ERR_INVAL);
290*7c478bd9Sstevel@tonic-gate 
291*7c478bd9Sstevel@tonic-gate 	/* register the error simulation	*/
292*7c478bd9Sstevel@tonic-gate 	errsim[num_errs].Errno = error_no;
293*7c478bd9Sstevel@tonic-gate 	errsim[num_errs].code  = error_type;
294*7c478bd9Sstevel@tonic-gate 	errsim[num_errs].file  = s;
295*7c478bd9Sstevel@tonic-gate 
296*7c478bd9Sstevel@tonic-gate 	if (opt_debug & DBG_MISC)
297*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, "MISC: errsim[%d] %c(%s) -> %d\n",
298*7c478bd9Sstevel@tonic-gate 			num_errs, error_type, s, error_no);
299*7c478bd9Sstevel@tonic-gate 
300*7c478bd9Sstevel@tonic-gate 	num_errs++;
301*7c478bd9Sstevel@tonic-gate 
302*7c478bd9Sstevel@tonic-gate 	return (0);
303*7c478bd9Sstevel@tonic-gate }
304*7c478bd9Sstevel@tonic-gate 
305*7c478bd9Sstevel@tonic-gate /*
306*7c478bd9Sstevel@tonic-gate  * routine:
307*7c478bd9Sstevel@tonic-gate  *	dbg_chk_error
308*7c478bd9Sstevel@tonic-gate  *
309*7c478bd9Sstevel@tonic-gate  * purpose:
310*7c478bd9Sstevel@tonic-gate  *	determine whether or not we have been asked to simulate an
311*7c478bd9Sstevel@tonic-gate  *	error for a specified file.
312*7c478bd9Sstevel@tonic-gate  *
313*7c478bd9Sstevel@tonic-gate  * parameters:
314*7c478bd9Sstevel@tonic-gate  *	file name
315*7c478bd9Sstevel@tonic-gate  *
316*7c478bd9Sstevel@tonic-gate  * returns:
317*7c478bd9Sstevel@tonic-gate  *	errno (or zero if no error)
318*7c478bd9Sstevel@tonic-gate  */
319*7c478bd9Sstevel@tonic-gate int
320*7c478bd9Sstevel@tonic-gate dbg_chk_error(const char *name, char code)
321*7c478bd9Sstevel@tonic-gate {	int i;
322*7c478bd9Sstevel@tonic-gate 
323*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < num_errs; i++) {
324*7c478bd9Sstevel@tonic-gate 		/* see if this code matches any registered condition	*/
325*7c478bd9Sstevel@tonic-gate 		if (code != errsim[i].code)
326*7c478bd9Sstevel@tonic-gate 			continue;
327*7c478bd9Sstevel@tonic-gate 
328*7c478bd9Sstevel@tonic-gate 		/* see if this also matches the file name	*/
329*7c478bd9Sstevel@tonic-gate 		if (!suffix(name, errsim[i].file))
330*7c478bd9Sstevel@tonic-gate 			continue;
331*7c478bd9Sstevel@tonic-gate 
332*7c478bd9Sstevel@tonic-gate 		/* we have a winner				*/
333*7c478bd9Sstevel@tonic-gate 		if (opt_debug & DBG_MISC)
334*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, "MISC: trigger %d for file %c(%s)\n",
335*7c478bd9Sstevel@tonic-gate 				errsim[i].Errno, code, name);
336*7c478bd9Sstevel@tonic-gate 		return (errsim[i].Errno);
337*7c478bd9Sstevel@tonic-gate 	}
338*7c478bd9Sstevel@tonic-gate 	return (0);
339*7c478bd9Sstevel@tonic-gate }
340*7c478bd9Sstevel@tonic-gate 
341*7c478bd9Sstevel@tonic-gate #else	/* ! DBG_ERRORS	*/
342*7c478bd9Sstevel@tonic-gate void
343*7c478bd9Sstevel@tonic-gate err_usage(void)
344*7c478bd9Sstevel@tonic-gate {
345*7c478bd9Sstevel@tonic-gate 	fprintf(stderr, "ERROR: this filesync does not support -E\n");
346*7c478bd9Sstevel@tonic-gate }
347*7c478bd9Sstevel@tonic-gate 
348*7c478bd9Sstevel@tonic-gate int
349*7c478bd9Sstevel@tonic-gate dbg_set_error(char *arg)
350*7c478bd9Sstevel@tonic-gate {
351*7c478bd9Sstevel@tonic-gate 	return (ERR_INVAL);
352*7c478bd9Sstevel@tonic-gate }
353*7c478bd9Sstevel@tonic-gate 
354*7c478bd9Sstevel@tonic-gate int
355*7c478bd9Sstevel@tonic-gate dbg_chk_error(const char *name, char code)
356*7c478bd9Sstevel@tonic-gate {
357*7c478bd9Sstevel@tonic-gate 	return (0);
358*7c478bd9Sstevel@tonic-gate }
359*7c478bd9Sstevel@tonic-gate #endif
360