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