1 /* $NetBSD: dict_debug.c,v 1.2 2017/02/14 01:16:49 christos 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
dict_debug_lookup(DICT * dict,const char * key)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 real_dict->flags = dict->flags;
65 result = dict_get(real_dict, key);
66 dict->flags = real_dict->flags;
67 msg_info("%s:%s lookup: \"%s\" = \"%s\"", dict->type, dict->name, key,
68 result ? result : real_dict->error ? "error" : "not_found");
69 DICT_ERR_VAL_RETURN(dict, real_dict->error, result);
70 }
71
72 /* dict_debug_update - log update operation */
73
dict_debug_update(DICT * dict,const char * key,const char * value)74 static int dict_debug_update(DICT *dict, const char *key, const char *value)
75 {
76 DICT_DEBUG *dict_debug = (DICT_DEBUG *) dict;
77 DICT *real_dict = dict_debug->real_dict;
78 int result;
79
80 real_dict->flags = dict->flags;
81 result = dict_put(real_dict, key, value);
82 dict->flags = real_dict->flags;
83 msg_info("%s:%s update: \"%s\" = \"%s\": %s", dict->type, dict->name,
84 key, value, result == 0 ? "success" : real_dict->error ?
85 "error" : "failed");
86 DICT_ERR_VAL_RETURN(dict, real_dict->error, result);
87 }
88
89 /* dict_debug_delete - log delete operation */
90
dict_debug_delete(DICT * dict,const char * key)91 static int dict_debug_delete(DICT *dict, const char *key)
92 {
93 DICT_DEBUG *dict_debug = (DICT_DEBUG *) dict;
94 DICT *real_dict = dict_debug->real_dict;
95 int result;
96
97 real_dict->flags = dict->flags;
98 result = dict_del(real_dict, key);
99 dict->flags = real_dict->flags;
100 msg_info("%s:%s delete: \"%s\": %s", dict->type, dict->name, key,
101 result == 0 ? "success" : real_dict->error ?
102 "error" : "failed");
103 DICT_ERR_VAL_RETURN(dict, real_dict->error, result);
104 }
105
106 /* dict_debug_sequence - log sequence operation */
107
dict_debug_sequence(DICT * dict,int function,const char ** key,const char ** value)108 static int dict_debug_sequence(DICT *dict, int function,
109 const char **key, const char **value)
110 {
111 DICT_DEBUG *dict_debug = (DICT_DEBUG *) dict;
112 DICT *real_dict = dict_debug->real_dict;
113 int result;
114
115 real_dict->flags = dict->flags;
116 result = dict_seq(real_dict, function, key, value);
117 dict->flags = real_dict->flags;
118 if (result == 0)
119 msg_info("%s:%s sequence: \"%s\" = \"%s\"", dict->type, dict->name,
120 *key, *value);
121 else
122 msg_info("%s:%s sequence: found EOF", dict->type, dict->name);
123 DICT_ERR_VAL_RETURN(dict, real_dict->error, result);
124 }
125
126 /* dict_debug_close - log operation */
127
dict_debug_close(DICT * dict)128 static void dict_debug_close(DICT *dict)
129 {
130 DICT_DEBUG *dict_debug = (DICT_DEBUG *) dict;
131
132 dict_close(dict_debug->real_dict);
133 dict_free(dict);
134 }
135
136 /* dict_debug - encapsulate dictionary object and install proxies */
137
dict_debug(DICT * real_dict)138 DICT *dict_debug(DICT *real_dict)
139 {
140 DICT_DEBUG *dict_debug;
141
142 dict_debug = (DICT_DEBUG *) dict_alloc(real_dict->type,
143 real_dict->name, sizeof(*dict_debug));
144 dict_debug->dict.flags = real_dict->flags; /* XXX not synchronized */
145 dict_debug->dict.lookup = dict_debug_lookup;
146 dict_debug->dict.update = dict_debug_update;
147 dict_debug->dict.delete = dict_debug_delete;
148 dict_debug->dict.sequence = dict_debug_sequence;
149 dict_debug->dict.close = dict_debug_close;
150 dict_debug->real_dict = real_dict;
151 return (&dict_debug->dict);
152 }
153