xref: /netbsd-src/external/ibm-public/postfix/dist/src/util/dict_debug.c (revision b1c86f5f087524e68db12794ee9c3e3da1ab17a0)
1 /*	$NetBSD: dict_debug.c,v 1.1.1.1 2009/06/23 10:08:59 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     const char *result;
62 
63     result = dict_get(dict_debug->real_dict, key);
64     msg_info("%s:%s lookup: \"%s\" = \"%s\"", dict->type, dict->name, key,
65 	     result ? result : dict_errno ? "try again" : "not_found");
66     return (result);
67 }
68 
69 /* dict_debug_update - log update operation */
70 
71 static void dict_debug_update(DICT *dict, const char *key, const char *value)
72 {
73     DICT_DEBUG *dict_debug = (DICT_DEBUG *) dict;
74 
75     msg_info("%s:%s update: \"%s\" = \"%s\"", dict->type, dict->name,
76 	     key, value);
77     dict_put(dict_debug->real_dict, key, value);
78 }
79 
80 /* dict_debug_delete - log delete operation */
81 
82 static int dict_debug_delete(DICT *dict, const char *key)
83 {
84     DICT_DEBUG *dict_debug = (DICT_DEBUG *) dict;
85     int     result;
86 
87     result = dict_del(dict_debug->real_dict, key);
88     msg_info("%s:%s delete: \"%s\" = \"%s\"", dict->type, dict->name, key,
89 	     result ? "failed" : "success");
90     return (result);
91 }
92 
93 /* dict_debug_sequence - log sequence operation */
94 
95 static int dict_debug_sequence(DICT *dict, int function,
96 			               const char **key, const char **value)
97 {
98     DICT_DEBUG *dict_debug = (DICT_DEBUG *) dict;
99     int     result;
100 
101     result = dict_seq(dict_debug->real_dict, function, key, value);
102     if (result == 0)
103 	msg_info("%s:%s sequence: \"%s\" = \"%s\"", dict->type, dict->name,
104 		 *key, *value);
105     else
106 	msg_info("%s:%s sequence: found EOF", dict->type, dict->name);
107     return (result);
108 }
109 
110 /* dict_debug_close - log operation */
111 
112 static void dict_debug_close(DICT *dict)
113 {
114     DICT_DEBUG *dict_debug = (DICT_DEBUG *) dict;
115 
116     dict_close(dict_debug->real_dict);
117     dict_free(dict);
118 }
119 
120 /* dict_debug - encapsulate dictionary object and install proxies */
121 
122 DICT   *dict_debug(DICT *real_dict)
123 {
124     DICT_DEBUG *dict_debug;
125 
126     dict_debug = (DICT_DEBUG *) dict_alloc(real_dict->type,
127 				      real_dict->name, sizeof(*dict_debug));
128     dict_debug->dict.flags = real_dict->flags;	/* XXX not synchronized */
129     dict_debug->dict.lookup = dict_debug_lookup;
130     dict_debug->dict.update = dict_debug_update;
131     dict_debug->dict.delete = dict_debug_delete;
132     dict_debug->dict.sequence = dict_debug_sequence;
133     dict_debug->dict.close = dict_debug_close;
134     dict_debug->real_dict = real_dict;
135     return (&dict_debug->dict);
136 }
137