1 /* $NetBSD: dict_static.c,v 1.3 2020/03/18 19:05:21 christos Exp $ */ 2 3 /*++ 4 /* NAME 5 /* dict_static 3 6 /* SUMMARY 7 /* dictionary manager interface to static variables 8 /* SYNOPSIS 9 /* #include <dict_static.h> 10 /* 11 /* DICT *dict_static_open(name, name, dict_flags) 12 /* const char *name; 13 /* int dummy; 14 /* int dict_flags; 15 /* DESCRIPTION 16 /* dict_static_open() implements a dummy dictionary that returns 17 /* as lookup result the dictionary name, regardless of the lookup 18 /* key value. 19 /* SEE ALSO 20 /* dict(3) generic dictionary manager 21 /* LICENSE 22 /* .ad 23 /* .fi 24 /* The Secure Mailer license must be distributed with this software. 25 /* AUTHOR(S) 26 /* jeffm 27 /* ghostgun.com 28 /* 29 /* Wietse Venema 30 /* Google, Inc. 31 /* 111 8th Avenue 32 /* New York, NY 10011, USA 33 /*--*/ 34 35 /* System library. */ 36 37 #include "sys_defs.h" 38 #include <stdio.h> /* sprintf() prototype */ 39 #include <stdlib.h> 40 #include <unistd.h> 41 #include <string.h> 42 43 /* Utility library. */ 44 45 #include "mymalloc.h" 46 #include "msg.h" 47 #include "stringops.h" 48 #include "dict.h" 49 #include "dict_static.h" 50 51 /* 52 * Subclass of DICT. 53 */ 54 typedef struct { 55 DICT dict; /* parent class */ 56 char *value; 57 } DICT_STATIC; 58 59 #define STR(x) vstring_str(x) 60 61 /* dict_static_lookup - access static value*/ 62 63 static const char *dict_static_lookup(DICT *dict, const char *unused_name) 64 { 65 DICT_STATIC *dict_static = (DICT_STATIC *) dict; 66 67 DICT_ERR_VAL_RETURN(dict, DICT_ERR_NONE, dict_static->value); 68 } 69 70 /* dict_static_close - close static dictionary */ 71 72 static void dict_static_close(DICT *dict) 73 { 74 DICT_STATIC *dict_static = (DICT_STATIC *) dict; 75 76 if (dict_static->value) 77 myfree(dict_static->value); 78 dict_free(dict); 79 } 80 81 /* dict_static_open - make association with static variable */ 82 83 DICT *dict_static_open(const char *name, int open_flags, int dict_flags) 84 { 85 DICT_STATIC *dict_static; 86 char *err = 0; 87 char *cp, *saved_name = 0; 88 const char *value; 89 VSTRING *base64_buf; 90 91 /* 92 * Let the optimizer worry about eliminating redundant code. 93 */ 94 #define DICT_STATIC_OPEN_RETURN(d) do { \ 95 DICT *__d = (d); \ 96 if (saved_name != 0) \ 97 myfree(saved_name); \ 98 if (err != 0) \ 99 myfree(err); \ 100 return (__d); \ 101 } while (0) 102 103 /* 104 * Optionally strip surrounding braces and whitespace. 105 */ 106 if (name[0] == CHARS_BRACE[0]) { 107 saved_name = cp = mystrdup(name); 108 if ((err = extpar(&cp, CHARS_BRACE, EXTPAR_FLAG_STRIP)) != 0) 109 DICT_STATIC_OPEN_RETURN(dict_surrogate(DICT_TYPE_STATIC, name, 110 open_flags, dict_flags, 111 "bad %s:name syntax: %s", 112 DICT_TYPE_STATIC, 113 err)); 114 value = cp; 115 } else { 116 value = name; 117 } 118 119 /* 120 * Bundle up the preliminary result. 121 */ 122 dict_static = (DICT_STATIC *) dict_alloc(DICT_TYPE_STATIC, name, 123 sizeof(*dict_static)); 124 dict_static->dict.lookup = dict_static_lookup; 125 dict_static->dict.close = dict_static_close; 126 dict_static->dict.flags = dict_flags | DICT_FLAG_FIXED; 127 dict_static->dict.owner.status = DICT_OWNER_TRUSTED; 128 dict_static->value = 0; 129 130 /* 131 * Optionally replace the value with file contents. 132 */ 133 if (dict_flags & DICT_FLAG_SRC_RHS_IS_FILE) { 134 if ((base64_buf = dict_file_to_b64(&dict_static->dict, value)) == 0) { 135 err = dict_file_get_error(&dict_static->dict); 136 dict_close(&dict_static->dict); 137 DICT_STATIC_OPEN_RETURN(dict_surrogate(DICT_TYPE_STATIC, name, 138 open_flags, dict_flags, 139 "%s", err)); 140 } 141 value = vstring_str(base64_buf); 142 } 143 144 /* 145 * Finalize the result. 146 */ 147 dict_static->value = mystrdup(value); 148 dict_file_purge_buffers(&dict_static->dict); 149 150 DICT_STATIC_OPEN_RETURN(DICT_DEBUG (&(dict_static->dict))); 151 } 152