1 /* $NetBSD: dict_static.c,v 1.4 2022/10/08 16:12:50 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
dict_static_lookup(DICT * dict,const char * unused_name)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
dict_static_close(DICT * dict)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 if (dict->fold_buf)
79 vstring_free(dict->fold_buf);
80 dict_free(dict);
81 }
82
83 /* dict_static_open - make association with static variable */
84
dict_static_open(const char * name,int open_flags,int dict_flags)85 DICT *dict_static_open(const char *name, int open_flags, int dict_flags)
86 {
87 DICT_STATIC *dict_static;
88 char *err = 0;
89 char *cp, *saved_name = 0;
90 const char *value;
91 VSTRING *base64_buf;
92
93 /*
94 * Let the optimizer worry about eliminating redundant code.
95 */
96 #define DICT_STATIC_OPEN_RETURN(d) do { \
97 DICT *__d = (d); \
98 if (saved_name != 0) \
99 myfree(saved_name); \
100 if (err != 0) \
101 myfree(err); \
102 return (__d); \
103 } while (0)
104
105 /*
106 * Optionally strip surrounding braces and whitespace.
107 */
108 if (name[0] == CHARS_BRACE[0]) {
109 saved_name = cp = mystrdup(name);
110 if ((err = extpar(&cp, CHARS_BRACE, EXTPAR_FLAG_STRIP)) != 0)
111 DICT_STATIC_OPEN_RETURN(dict_surrogate(DICT_TYPE_STATIC, name,
112 open_flags, dict_flags,
113 "bad %s:name syntax: %s",
114 DICT_TYPE_STATIC,
115 err));
116 value = cp;
117 } else {
118 value = name;
119 }
120
121 /*
122 * Bundle up the preliminary result.
123 */
124 dict_static = (DICT_STATIC *) dict_alloc(DICT_TYPE_STATIC, name,
125 sizeof(*dict_static));
126 dict_static->dict.lookup = dict_static_lookup;
127 dict_static->dict.close = dict_static_close;
128 dict_static->dict.flags = dict_flags | DICT_FLAG_FIXED;
129 dict_static->dict.owner.status = DICT_OWNER_TRUSTED;
130 dict_static->value = 0;
131
132 /*
133 * Optionally replace the value with file contents.
134 */
135 if (dict_flags & DICT_FLAG_SRC_RHS_IS_FILE) {
136 if ((base64_buf = dict_file_to_b64(&dict_static->dict, value)) == 0) {
137 err = dict_file_get_error(&dict_static->dict);
138 dict_close(&dict_static->dict);
139 DICT_STATIC_OPEN_RETURN(dict_surrogate(DICT_TYPE_STATIC, name,
140 open_flags, dict_flags,
141 "%s", err));
142 }
143 value = vstring_str(base64_buf);
144 }
145
146 /*
147 * Finalize the result.
148 */
149 dict_static->value = mystrdup(value);
150 dict_file_purge_buffers(&dict_static->dict);
151
152 DICT_STATIC_OPEN_RETURN(DICT_DEBUG (&(dict_static->dict)));
153 }
154