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