xref: /titanic_41/usr/src/cmd/sendmail/db/db/db_err.c (revision 749f21d359d8fbd020c974a1a5227316221bfc9c)
1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 1996, 1997, 1998
5  *	Sleepycat Software.  All rights reserved.
6  */
7 
8 #include "config.h"
9 
10 #ifndef lint
11 static const char sccsid[] = "@(#)db_err.c	10.42 (Sleepycat) 11/24/98";
12 #endif /* not lint */
13 
14 #ifndef NO_SYSTEM_INCLUDES
15 #include <sys/types.h>
16 
17 #include <errno.h>
18 #include <stdio.h>
19 #include <string.h>
20 
21 #ifdef __STDC__
22 #include <stdarg.h>
23 #else
24 #include <varargs.h>
25 #endif
26 #endif
27 
28 #include "db_int.h"
29 #include "shqueue.h"
30 #include "db_shash.h"
31 #include "lock.h"
32 #include "lock_ext.h"
33 #include "log.h"
34 #include "log_ext.h"
35 #include "mp.h"
36 #include "mp_ext.h"
37 #include "txn.h"
38 #include "txn_ext.h"
39 #include "common_ext.h"
40 #include "clib_ext.h"
41 
42 /*
43  * __db_fchk --
44  *	General flags checking routine.
45  *
46  * PUBLIC: int __db_fchk __P((DB_ENV *, const char *, u_int32_t, u_int32_t));
47  */
48 int
49 __db_fchk(dbenv, name, flags, ok_flags)
50 	DB_ENV *dbenv;
51 	const char *name;
52 	u_int32_t flags, ok_flags;
53 {
54 	return (flags & ~ok_flags ?  __db_ferr(dbenv, name, 0) : 0);
55 }
56 
57 /*
58  * __db_fcchk --
59  *	General combination flags checking routine.
60  *
61  * PUBLIC: int __db_fcchk
62  * PUBLIC:    __P((DB_ENV *, const char *, u_int32_t, u_int32_t, u_int32_t));
63  */
64 int
65 __db_fcchk(dbenv, name, flags, flag1, flag2)
66 	DB_ENV *dbenv;
67 	const char *name;
68 	u_int32_t flags, flag1, flag2;
69 {
70 	return ((flags & flag1) &&
71 	    (flags & flag2) ?  __db_ferr(dbenv, name, 1) : 0);
72 }
73 
74 /*
75  * __db_ferr --
76  *	Common flag errors.
77  *
78  * PUBLIC: int __db_ferr __P((const DB_ENV *, const char *, int));
79  */
80 int
81 __db_ferr(dbenv, name, iscombo)
82 	const DB_ENV *dbenv;
83 	const char *name;
84 	int iscombo;
85 {
86 	__db_err(dbenv, "illegal flag %sspecified to %s",
87 	    iscombo ? "combination " : "", name);
88 	return (EINVAL);
89 }
90 
91 /*
92  * __db_err --
93  *	Standard DB error routine.
94  *
95  * PUBLIC: #ifdef __STDC__
96  * PUBLIC: void __db_err __P((const DB_ENV *dbenv, const char *fmt, ...));
97  * PUBLIC: #else
98  * PUBLIC: void __db_err();
99  * PUBLIC: #endif
100  */
101 void
102 #ifdef __STDC__
103 __db_err(const DB_ENV *dbenv, const char *fmt, ...)
104 #else
105 __db_err(dbenv, fmt, va_alist)
106 	const DB_ENV *dbenv;
107 	const char *fmt;
108 	va_dcl
109 #endif
110 {
111 	va_list ap;
112 	char errbuf[2048];	/* XXX: END OF THE STACK DON'T TRUST SPRINTF. */
113 
114 	if (dbenv == NULL)
115 		return;
116 
117 	if (dbenv->db_errcall != NULL) {
118 #ifdef __STDC__
119          	va_start(ap, fmt);
120 #else
121 	        va_start(ap);
122 #endif
123 		(void)vsnprintf(errbuf, sizeof(errbuf), fmt, ap);
124 		dbenv->db_errcall(dbenv->db_errpfx, errbuf);
125 		va_end(ap);
126 	}
127 	if (dbenv->db_errfile != NULL) {
128 		if (dbenv->db_errpfx != NULL)
129 			(void)fprintf(dbenv->db_errfile, "%s: ",
130 			    dbenv->db_errpfx);
131 #ifdef __STDC__
132          	va_start(ap, fmt);
133 #else
134 	        va_start(ap);
135 #endif
136 		(void)vfprintf(dbenv->db_errfile, fmt, ap);
137 		(void)fprintf(dbenv->db_errfile, "\n");
138 		(void)fflush(dbenv->db_errfile);
139 		va_end(ap);
140 	}
141 }
142 
143 /*
144  * __db_pgerr --
145  *	Error when unable to retrieve a specified page.
146  *
147  * PUBLIC: int __db_pgerr __P((DB *, db_pgno_t));
148  */
149 int
150 __db_pgerr(dbp, pgno)
151 	DB *dbp;
152 	db_pgno_t pgno;
153 {
154 	/*
155 	 * Three things are certain:
156 	 * Death, taxes, and lost data.
157 	 * Guess which has occurred.
158 	 */
159 	__db_err(dbp->dbenv,
160 	    "unable to create/retrieve page %lu", (u_long)pgno);
161 	return (__db_panic(dbp->dbenv, EIO));
162 }
163 
164 /*
165  * __db_pgfmt --
166  *	Error when a page has the wrong format.
167  *
168  * PUBLIC: int __db_pgfmt __P((DB *, db_pgno_t));
169  */
170 int
171 __db_pgfmt(dbp, pgno)
172 	DB *dbp;
173 	db_pgno_t pgno;
174 {
175 	__db_err(dbp->dbenv,
176 	    "page %lu: illegal page type or format", (u_long)pgno);
177 	return (__db_panic(dbp->dbenv, EINVAL));
178 }
179 
180 /*
181  * __db_panic --
182  *	Lock out the tree due to unrecoverable error.
183  *
184  * PUBLIC: int __db_panic __P((DB_ENV *, int));
185  */
186 int
187 __db_panic(dbenv, errval)
188 	DB_ENV *dbenv;
189 	int errval;
190 {
191 	if (dbenv != NULL) {
192 		dbenv->db_panic = errval;
193 
194 		(void)__log_panic(dbenv);
195 		(void)__memp_panic(dbenv);
196 		(void)__lock_panic(dbenv);
197 		(void)__txn_panic(dbenv);
198 
199 		__db_err(dbenv, "PANIC: %s", strerror(errval));
200 
201 		if (dbenv->db_paniccall != NULL)
202 			dbenv->db_paniccall(dbenv, errval);
203 	}
204 
205 	/*
206 	 * Chaos reigns within.
207 	 * Reflect, repent, and reboot.
208 	 * Order shall return.
209 	 */
210 	return (DB_RUNRECOVERY);
211 }
212