1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 1999, 2013 Oracle and/or its affiliates.  All rights reserved.
5  *
6  * $Id$
7  */
8 
9 #include "db_config.h"
10 
11 #include "db_int.h"
12 #include "dbinc/db_page.h"
13 #include "dbinc/db_am.h"
14 
15 static int __log_printf_int __P((ENV *, DB_TXN *, const char *, va_list));
16 
17 /*
18  * __log_printf_capi --
19  *	Write a printf-style format string into the DB log.
20  *
21  * PUBLIC: int __log_printf_capi __P((DB_ENV *, DB_TXN *, const char *, ...))
22  * PUBLIC:    __attribute__ ((__format__ (__printf__, 3, 4)));
23  */
24 int
25 #ifdef STDC_HEADERS
__log_printf_capi(DB_ENV * dbenv,DB_TXN * txnid,const char * fmt,...)26 __log_printf_capi(DB_ENV *dbenv, DB_TXN *txnid, const char *fmt, ...)
27 #else
28 __log_printf_capi(dbenv, txnid, fmt, va_alist)
29 	DB_ENV *dbenv;
30 	DB_TXN *txnid;
31 	const char *fmt;
32 	va_dcl
33 #endif
34 {
35 	va_list ap;
36 	int ret;
37 
38 #ifdef STDC_HEADERS
39 	va_start(ap, fmt);
40 #else
41 	va_start(ap);
42 #endif
43 	ret = __log_printf_pp(dbenv, txnid, fmt, ap);
44 	va_end(ap);
45 
46 	return (ret);
47 }
48 
49 /*
50  * __log_printf_pp --
51  *	Handle the arguments and call an internal routine to do the work.
52  *
53  *	The reason this routine isn't just folded into __log_printf_capi
54  *	is because the C++ API has to call a C API routine, and you can
55  *	only pass variadic arguments to a single routine.
56  *
57  * PUBLIC: int __log_printf_pp
58  * PUBLIC:     __P((DB_ENV *, DB_TXN *, const char *, va_list));
59  */
60 int
__log_printf_pp(dbenv,txnid,fmt,ap)61 __log_printf_pp(dbenv, txnid, fmt, ap)
62 	DB_ENV *dbenv;
63 	DB_TXN *txnid;
64 	const char *fmt;
65 	va_list ap;
66 {
67 	DB_THREAD_INFO *ip;
68 	ENV *env;
69 	int ret;
70 
71 	env = dbenv->env;
72 
73 	ENV_REQUIRES_CONFIG(env,
74 	    env->lg_handle, "DB_ENV->log_printf", DB_INIT_LOG);
75 
76 	ENV_ENTER(env, ip);
77 	REPLICATION_WRAP(env, (__log_printf_int(env, txnid, fmt, ap)), 0, ret);
78 	va_end(ap);
79 	ENV_LEAVE(env, ip);
80 	return (ret);
81 }
82 
83 /*
84  * __log_printf --
85  *	Write a printf-style format string into the DB log.
86  *
87  * PUBLIC: int __log_printf __P((ENV *, DB_TXN *, const char *, ...))
88  * PUBLIC:    __attribute__ ((__format__ (__printf__, 3, 4)));
89  */
90 int
91 #ifdef STDC_HEADERS
__log_printf(ENV * env,DB_TXN * txnid,const char * fmt,...)92 __log_printf(ENV *env, DB_TXN *txnid, const char *fmt, ...)
93 #else
94 __log_printf(env, txnid, fmt, va_alist)
95 	ENV *env;
96 	DB_TXN *txnid;
97 	const char *fmt;
98 	va_dcl
99 #endif
100 {
101 	va_list ap;
102 	int ret;
103 
104 #ifdef STDC_HEADERS
105 	va_start(ap, fmt);
106 #else
107 	va_start(ap);
108 #endif
109 	ret = __log_printf_int(env, txnid, fmt, ap);
110 	va_end(ap);
111 
112 	return (ret);
113 }
114 
115 /*
116  * __log_printf_int --
117  *	Write a printf-style format string into the DB log (internal).
118  */
119 static int
__log_printf_int(env,txnid,fmt,ap)120 __log_printf_int(env, txnid, fmt, ap)
121 	ENV *env;
122 	DB_TXN *txnid;
123 	const char *fmt;
124 	va_list ap;
125 {
126 	DBT opdbt, msgdbt;
127 	DB_LSN lsn;
128 	char __logbuf[2048];	/* !!!: END OF THE STACK DON'T TRUST SPRINTF. */
129 
130 	if (!DBENV_LOGGING(env)) {
131 		__db_errx(env, DB_STR("2510",
132 		    "Logging not currently permitted"));
133 		return (EAGAIN);
134 	}
135 
136 	memset(&opdbt, 0, sizeof(opdbt));
137 	opdbt.data = "DIAGNOSTIC";
138 	opdbt.size = sizeof("DIAGNOSTIC") - 1;
139 
140 	memset(&msgdbt, 0, sizeof(msgdbt));
141 	msgdbt.data = __logbuf;
142 	msgdbt.size = (u_int32_t)vsnprintf(__logbuf, sizeof(__logbuf), fmt, ap);
143 
144 	return (__db_debug_log(
145 	    env, txnid, &lsn, 0, &opdbt, -1, &msgdbt, NULL, 0));
146 }
147