xref: /netbsd-src/external/ibm-public/postfix/dist/src/util/dict_static.c (revision 67b9b338a7386232ac596b5fd0cd5a9cc8a03c71)
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