xref: /netbsd-src/external/ibm-public/postfix/dist/src/util/dict_debug.c (revision e89934bbf778a6d6d6894877c4da59d0c7835b0f)
1*e89934bbSchristos /*	$NetBSD: dict_debug.c,v 1.2 2017/02/14 01:16:49 christos Exp $	*/
241fbaed0Stron 
341fbaed0Stron /*++
441fbaed0Stron /* NAME
541fbaed0Stron /*	dict_debug 3
641fbaed0Stron /* SUMMARY
741fbaed0Stron /*	dictionary manager, logging proxy
841fbaed0Stron /* SYNOPSIS
941fbaed0Stron /*	#include <dict.h>
1041fbaed0Stron /*
1141fbaed0Stron /*	DICT	*dict_debug(dict_handle)
1241fbaed0Stron /*	DICT	*dict_handle;
1341fbaed0Stron /*
1441fbaed0Stron /*	DICT	*DICT_DEBUG(dict_handle)
1541fbaed0Stron /*	DICT	*dict_handle;
1641fbaed0Stron /* DESCRIPTION
1741fbaed0Stron /*	dict_debug() encapsulates the given dictionary object and returns
1841fbaed0Stron /*	a proxy object that logs all access to the encapsulated object.
1941fbaed0Stron /*	This is more convenient than having to add logging capability
2041fbaed0Stron /*	to each individual dictionary access method.
2141fbaed0Stron /*
2241fbaed0Stron /*	DICT_DEBUG() is an unsafe macro that returns the original object if
2341fbaed0Stron /*	the object's debugging flag is not set, and that otherwise encapsulates
2441fbaed0Stron /*	the object with dict_debug(). This macro simplifies usage by avoiding
2541fbaed0Stron /*	clumsy expressions. The macro evaluates its argument multiple times.
2641fbaed0Stron /* DIAGNOSTICS
2741fbaed0Stron /*	Fatal errors: out of memory.
2841fbaed0Stron /* LICENSE
2941fbaed0Stron /* .ad
3041fbaed0Stron /* .fi
3141fbaed0Stron /*	The Secure Mailer license must be distributed with this software.
3241fbaed0Stron /* AUTHOR(S)
3341fbaed0Stron /*	Wietse Venema
3441fbaed0Stron /*	IBM T.J. Watson Research
3541fbaed0Stron /*	P.O. Box 704
3641fbaed0Stron /*	Yorktown Heights, NY 10598, USA
3741fbaed0Stron /*--*/
3841fbaed0Stron 
3941fbaed0Stron /* System libraries. */
4041fbaed0Stron 
4141fbaed0Stron #include <sys_defs.h>
4241fbaed0Stron 
4341fbaed0Stron /* Utility library. */
4441fbaed0Stron 
4541fbaed0Stron #include <msg.h>
4641fbaed0Stron #include <mymalloc.h>
4741fbaed0Stron #include <dict.h>
4841fbaed0Stron 
4941fbaed0Stron /* Application-specific. */
5041fbaed0Stron 
5141fbaed0Stron typedef struct {
5241fbaed0Stron     DICT    dict;			/* the proxy service */
5341fbaed0Stron     DICT   *real_dict;			/* encapsulated object */
5441fbaed0Stron } DICT_DEBUG;
5541fbaed0Stron 
5641fbaed0Stron /* dict_debug_lookup - log lookup operation */
5741fbaed0Stron 
dict_debug_lookup(DICT * dict,const char * key)5841fbaed0Stron static const char *dict_debug_lookup(DICT *dict, const char *key)
5941fbaed0Stron {
6041fbaed0Stron     DICT_DEBUG *dict_debug = (DICT_DEBUG *) dict;
61a30b880eStron     DICT   *real_dict = dict_debug->real_dict;
6241fbaed0Stron     const char *result;
6341fbaed0Stron 
64e262b48eSchristos     real_dict->flags = dict->flags;
65a30b880eStron     result = dict_get(real_dict, key);
66e262b48eSchristos     dict->flags = real_dict->flags;
6741fbaed0Stron     msg_info("%s:%s lookup: \"%s\" = \"%s\"", dict->type, dict->name, key,
68a30b880eStron 	     result ? result : real_dict->error ? "error" : "not_found");
69a30b880eStron     DICT_ERR_VAL_RETURN(dict, real_dict->error, result);
7041fbaed0Stron }
7141fbaed0Stron 
7241fbaed0Stron /* dict_debug_update - log update operation */
7341fbaed0Stron 
dict_debug_update(DICT * dict,const char * key,const char * value)74a30b880eStron static int dict_debug_update(DICT *dict, const char *key, const char *value)
7541fbaed0Stron {
7641fbaed0Stron     DICT_DEBUG *dict_debug = (DICT_DEBUG *) dict;
77a30b880eStron     DICT   *real_dict = dict_debug->real_dict;
78a30b880eStron     int     result;
7941fbaed0Stron 
80e262b48eSchristos     real_dict->flags = dict->flags;
81a30b880eStron     result = dict_put(real_dict, key, value);
82e262b48eSchristos     dict->flags = real_dict->flags;
83a30b880eStron     msg_info("%s:%s update: \"%s\" = \"%s\": %s", dict->type, dict->name,
84a30b880eStron 	     key, value, result == 0 ? "success" : real_dict->error ?
85a30b880eStron 	     "error" : "failed");
86a30b880eStron     DICT_ERR_VAL_RETURN(dict, real_dict->error, result);
8741fbaed0Stron }
8841fbaed0Stron 
8941fbaed0Stron /* dict_debug_delete - log delete operation */
9041fbaed0Stron 
dict_debug_delete(DICT * dict,const char * key)9141fbaed0Stron static int dict_debug_delete(DICT *dict, const char *key)
9241fbaed0Stron {
9341fbaed0Stron     DICT_DEBUG *dict_debug = (DICT_DEBUG *) dict;
94a30b880eStron     DICT   *real_dict = dict_debug->real_dict;
9541fbaed0Stron     int     result;
9641fbaed0Stron 
97e262b48eSchristos     real_dict->flags = dict->flags;
98a30b880eStron     result = dict_del(real_dict, key);
99e262b48eSchristos     dict->flags = real_dict->flags;
100a30b880eStron     msg_info("%s:%s delete: \"%s\": %s", dict->type, dict->name, key,
101a30b880eStron 	     result == 0 ? "success" : real_dict->error ?
102a30b880eStron 	     "error" : "failed");
103a30b880eStron     DICT_ERR_VAL_RETURN(dict, real_dict->error, result);
10441fbaed0Stron }
10541fbaed0Stron 
10641fbaed0Stron /* dict_debug_sequence - log sequence operation */
10741fbaed0Stron 
dict_debug_sequence(DICT * dict,int function,const char ** key,const char ** value)10841fbaed0Stron static int dict_debug_sequence(DICT *dict, int function,
10941fbaed0Stron 			               const char **key, const char **value)
11041fbaed0Stron {
11141fbaed0Stron     DICT_DEBUG *dict_debug = (DICT_DEBUG *) dict;
112a30b880eStron     DICT   *real_dict = dict_debug->real_dict;
11341fbaed0Stron     int     result;
11441fbaed0Stron 
115e262b48eSchristos     real_dict->flags = dict->flags;
116a30b880eStron     result = dict_seq(real_dict, function, key, value);
117e262b48eSchristos     dict->flags = real_dict->flags;
11841fbaed0Stron     if (result == 0)
11941fbaed0Stron 	msg_info("%s:%s sequence: \"%s\" = \"%s\"", dict->type, dict->name,
12041fbaed0Stron 		 *key, *value);
12141fbaed0Stron     else
12241fbaed0Stron 	msg_info("%s:%s sequence: found EOF", dict->type, dict->name);
123a30b880eStron     DICT_ERR_VAL_RETURN(dict, real_dict->error, result);
12441fbaed0Stron }
12541fbaed0Stron 
12641fbaed0Stron /* dict_debug_close - log operation */
12741fbaed0Stron 
dict_debug_close(DICT * dict)12841fbaed0Stron static void dict_debug_close(DICT *dict)
12941fbaed0Stron {
13041fbaed0Stron     DICT_DEBUG *dict_debug = (DICT_DEBUG *) dict;
13141fbaed0Stron 
13241fbaed0Stron     dict_close(dict_debug->real_dict);
13341fbaed0Stron     dict_free(dict);
13441fbaed0Stron }
13541fbaed0Stron 
13641fbaed0Stron /* dict_debug - encapsulate dictionary object and install proxies */
13741fbaed0Stron 
dict_debug(DICT * real_dict)13841fbaed0Stron DICT   *dict_debug(DICT *real_dict)
13941fbaed0Stron {
14041fbaed0Stron     DICT_DEBUG *dict_debug;
14141fbaed0Stron 
14241fbaed0Stron     dict_debug = (DICT_DEBUG *) dict_alloc(real_dict->type,
14341fbaed0Stron 				      real_dict->name, sizeof(*dict_debug));
14441fbaed0Stron     dict_debug->dict.flags = real_dict->flags;	/* XXX not synchronized */
14541fbaed0Stron     dict_debug->dict.lookup = dict_debug_lookup;
14641fbaed0Stron     dict_debug->dict.update = dict_debug_update;
14741fbaed0Stron     dict_debug->dict.delete = dict_debug_delete;
14841fbaed0Stron     dict_debug->dict.sequence = dict_debug_sequence;
14941fbaed0Stron     dict_debug->dict.close = dict_debug_close;
15041fbaed0Stron     dict_debug->real_dict = real_dict;
15141fbaed0Stron     return (&dict_debug->dict);
15241fbaed0Stron }
153