xref: /netbsd-src/external/ibm-public/postfix/dist/src/util/dict_debug.c (revision 4d12bfcd155352508213ace5ccc59ce930ea2974)
1 /*	$NetBSD: dict_debug.c,v 1.1.1.2 2013/01/02 18:59:12 tron Exp $	*/
2 
3 /*++
4 /* NAME
5 /*	dict_debug 3
6 /* SUMMARY
7 /*	dictionary manager, logging proxy
8 /* SYNOPSIS
9 /*	#include <dict.h>
10 /*
11 /*	DICT	*dict_debug(dict_handle)
12 /*	DICT	*dict_handle;
13 /*
14 /*	DICT	*DICT_DEBUG(dict_handle)
15 /*	DICT	*dict_handle;
16 /* DESCRIPTION
17 /*	dict_debug() encapsulates the given dictionary object and returns
18 /*	a proxy object that logs all access to the encapsulated object.
19 /*	This is more convenient than having to add logging capability
20 /*	to each individual dictionary access method.
21 /*
22 /*	DICT_DEBUG() is an unsafe macro that returns the original object if
23 /*	the object's debugging flag is not set, and that otherwise encapsulates
24 /*	the object with dict_debug(). This macro simplifies usage by avoiding
25 /*	clumsy expressions. The macro evaluates its argument multiple times.
26 /* DIAGNOSTICS
27 /*	Fatal errors: out of memory.
28 /* LICENSE
29 /* .ad
30 /* .fi
31 /*	The Secure Mailer license must be distributed with this software.
32 /* AUTHOR(S)
33 /*	Wietse Venema
34 /*	IBM T.J. Watson Research
35 /*	P.O. Box 704
36 /*	Yorktown Heights, NY 10598, USA
37 /*--*/
38 
39 /* System libraries. */
40 
41 #include <sys_defs.h>
42 
43 /* Utility library. */
44 
45 #include <msg.h>
46 #include <mymalloc.h>
47 #include <dict.h>
48 
49 /* Application-specific. */
50 
51 typedef struct {
52     DICT    dict;			/* the proxy service */
53     DICT   *real_dict;			/* encapsulated object */
54 } DICT_DEBUG;
55 
56 /* dict_debug_lookup - log lookup operation */
57 
58 static const char *dict_debug_lookup(DICT *dict, const char *key)
59 {
60     DICT_DEBUG *dict_debug = (DICT_DEBUG *) dict;
61     DICT   *real_dict = dict_debug->real_dict;
62     const char *result;
63 
64     result = dict_get(real_dict, key);
65     msg_info("%s:%s lookup: \"%s\" = \"%s\"", dict->type, dict->name, key,
66 	     result ? result : real_dict->error ? "error" : "not_found");
67     DICT_ERR_VAL_RETURN(dict, real_dict->error, result);
68 }
69 
70 /* dict_debug_update - log update operation */
71 
72 static int dict_debug_update(DICT *dict, const char *key, const char *value)
73 {
74     DICT_DEBUG *dict_debug = (DICT_DEBUG *) dict;
75     DICT   *real_dict = dict_debug->real_dict;
76     int     result;
77 
78     result = dict_put(real_dict, key, value);
79     msg_info("%s:%s update: \"%s\" = \"%s\": %s", dict->type, dict->name,
80 	     key, value, result == 0 ? "success" : real_dict->error ?
81 	     "error" : "failed");
82     DICT_ERR_VAL_RETURN(dict, real_dict->error, result);
83 }
84 
85 /* dict_debug_delete - log delete operation */
86 
87 static int dict_debug_delete(DICT *dict, const char *key)
88 {
89     DICT_DEBUG *dict_debug = (DICT_DEBUG *) dict;
90     DICT   *real_dict = dict_debug->real_dict;
91     int     result;
92 
93     result = dict_del(real_dict, key);
94     msg_info("%s:%s delete: \"%s\": %s", dict->type, dict->name, key,
95 	     result == 0 ? "success" : real_dict->error ?
96 	     "error" : "failed");
97     DICT_ERR_VAL_RETURN(dict, real_dict->error, result);
98 }
99 
100 /* dict_debug_sequence - log sequence operation */
101 
102 static int dict_debug_sequence(DICT *dict, int function,
103 			               const char **key, const char **value)
104 {
105     DICT_DEBUG *dict_debug = (DICT_DEBUG *) dict;
106     DICT   *real_dict = dict_debug->real_dict;
107     int     result;
108 
109     result = dict_seq(real_dict, function, key, value);
110     if (result == 0)
111 	msg_info("%s:%s sequence: \"%s\" = \"%s\"", dict->type, dict->name,
112 		 *key, *value);
113     else
114 	msg_info("%s:%s sequence: found EOF", dict->type, dict->name);
115     DICT_ERR_VAL_RETURN(dict, real_dict->error, result);
116 }
117 
118 /* dict_debug_close - log operation */
119 
120 static void dict_debug_close(DICT *dict)
121 {
122     DICT_DEBUG *dict_debug = (DICT_DEBUG *) dict;
123 
124     dict_close(dict_debug->real_dict);
125     dict_free(dict);
126 }
127 
128 /* dict_debug - encapsulate dictionary object and install proxies */
129 
130 DICT   *dict_debug(DICT *real_dict)
131 {
132     DICT_DEBUG *dict_debug;
133 
134     dict_debug = (DICT_DEBUG *) dict_alloc(real_dict->type,
135 				      real_dict->name, sizeof(*dict_debug));
136     dict_debug->dict.flags = real_dict->flags;	/* XXX not synchronized */
137     dict_debug->dict.lookup = dict_debug_lookup;
138     dict_debug->dict.update = dict_debug_update;
139     dict_debug->dict.delete = dict_debug_delete;
140     dict_debug->dict.sequence = dict_debug_sequence;
141     dict_debug->dict.close = dict_debug_close;
142     dict_debug->real_dict = real_dict;
143     return (&dict_debug->dict);
144 }
145