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