1/*++
2/* NAME
3/*	dict_env 3
4/* SUMMARY
5/*	dictionary manager interface to environment variables
6/* SYNOPSIS
7/*	#include <dict_env.h>
8/*
9/*	DICT	*dict_env_open(name, dummy, dict_flags)
10/*	const char *name;
11/*	int	dummy;
12/*	int	dict_flags;
13/* DESCRIPTION
14/*	dict_env_open() opens the environment variable array and
15/*	makes it accessible via the generic operations documented
16/*	in dict_open(3). The \fIname\fR and \fIdummy\fR arguments
17/*	are ignored.
18/* SEE ALSO
19/*	dict(3) generic dictionary manager
20/*	safe_getenv(3) safe getenv() interface
21/* LICENSE
22/* .ad
23/* .fi
24/*	The Secure Mailer license must be distributed with this software.
25/* AUTHOR(S)
26/*	Wietse Venema
27/*	IBM T.J. Watson Research
28/*	P.O. Box 704
29/*	Yorktown Heights, NY 10598, USA
30/*--*/
31
32/* System library. */
33
34#include "sys_defs.h"
35#include <stdio.h>			/* sprintf() prototype */
36#include <stdlib.h>
37#include <unistd.h>
38#include <string.h>
39
40/* Utility library. */
41
42#include "mymalloc.h"
43#include "msg.h"
44#include "safe.h"
45#include "stringops.h"
46#include "dict.h"
47#include "dict_env.h"
48
49/* dict_env_update - update environment array */
50
51static int dict_env_update(DICT *dict, const char *name, const char *value)
52{
53    dict->error = 0;
54
55    /*
56     * Optionally fold the key.
57     */
58    if (dict->flags & DICT_FLAG_FOLD_FIX) {
59	if (dict->fold_buf == 0)
60	    dict->fold_buf = vstring_alloc(10);
61	vstring_strcpy(dict->fold_buf, name);
62	name = lowercase(vstring_str(dict->fold_buf));
63    }
64    if (setenv(name, value, 1))
65	msg_fatal("setenv: %m");
66
67    return (DICT_STAT_SUCCESS);
68}
69
70/* dict_env_lookup - access environment array */
71
72static const char *dict_env_lookup(DICT *dict, const char *name)
73{
74    dict->error = 0;
75
76    /*
77     * Optionally fold the key.
78     */
79    if (dict->flags & DICT_FLAG_FOLD_FIX) {
80	if (dict->fold_buf == 0)
81	    dict->fold_buf = vstring_alloc(10);
82	vstring_strcpy(dict->fold_buf, name);
83	name = lowercase(vstring_str(dict->fold_buf));
84    }
85    return (safe_getenv(name));
86}
87
88/* dict_env_close - close environment dictionary */
89
90static void dict_env_close(DICT *dict)
91{
92    if (dict->fold_buf)
93	vstring_free(dict->fold_buf);
94    dict_free(dict);
95}
96
97/* dict_env_open - make association with environment array */
98
99DICT   *dict_env_open(const char *name, int unused_flags, int dict_flags)
100{
101    DICT   *dict;
102
103    dict = dict_alloc(DICT_TYPE_ENVIRON, name, sizeof(*dict));
104    dict->lookup = dict_env_lookup;
105    dict->update = dict_env_update;
106    dict->close = dict_env_close;
107    dict->flags = dict_flags | DICT_FLAG_FIXED;
108    if (dict_flags & DICT_FLAG_FOLD_FIX)
109	dict->fold_buf = vstring_alloc(10);
110    dict->owner.status = DICT_OWNER_TRUSTED;
111    return (DICT_DEBUG (dict));
112}
113