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