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