1 /* $NetBSD: dict_debug.c,v 1.1.1.3 2017/02/14 01:13:44 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 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 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 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 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 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 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