1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 1999-2021 Free Software Foundation, Inc.
3
4 GNU Mailutils is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
8
9 GNU Mailutils is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
16
17 /* Global MH state. */
18
19 #include <mh.h>
20
21 static const char *current_folder = NULL;
22 int rcpt_mask = RCPT_DEFAULT;
23 int mh_auto_install = 1;
24
25 mu_property_t
mh_read_property_file(char * name,int ro)26 mh_read_property_file (char *name, int ro)
27 {
28 mu_property_t prop;
29 struct mu_mh_prop *mhprop;
30 int rc;
31
32 mhprop = mu_zalloc (sizeof (mhprop[0]));
33 mhprop->filename = name;
34 mhprop->ro = ro;
35 rc = mu_property_create_init (&prop, mu_mh_property_init, mhprop);
36 if (rc)
37 {
38 mu_diag_funcall (MU_DIAG_ERROR, "mu_property_create_init", name, rc);
39 exit (1);
40 }
41 return prop;
42 }
43
44 static int
prop_merger(const char * field,const char * value,void * data)45 prop_merger (const char *field, const char *value, void *data)
46 {
47 mu_property_t dst = data;
48 return mu_property_set_value (dst, field, value, 1);
49 }
50
51 void
mh_property_merge(mu_property_t dst,mu_property_t src)52 mh_property_merge (mu_property_t dst, mu_property_t src)
53 {
54 int rc;
55
56 if (!src)
57 return;
58 rc = mu_mhprop_iterate (src, prop_merger, dst);
59 if (rc)
60 {
61 mu_diag_funcall (MU_DIAG_ERROR, "mu_mhprop_iterate", NULL, rc);
62 exit (1);
63 }
64 }
65
66 /* Global profile */
67
68 void
_mh_init_global_context()69 _mh_init_global_context ()
70 {
71 char *p, *ctx_name;
72
73 if (mu_mh_context)
74 return;
75 p = getenv ("CONTEXT");
76 if (!p)
77 p = MH_CONTEXT_FILE;
78 ctx_name = mh_expand_name (NULL, p, NAME_ANY);
79
80 mu_mh_context = mh_read_property_file (ctx_name, 0);
81
82 if (!current_folder)
83 current_folder = mh_global_context_get ("Current-Folder",
84 mh_global_profile_get ("Inbox",
85 "inbox"));
86 }
87
88 void
mh_read_profile()89 mh_read_profile ()
90 {
91 char *p;
92 const char *fallback;
93
94 p = getenv ("MH");
95 if (p)
96 p = mu_tilde_expansion (p, MU_HIERARCHY_DELIMITER, NULL);
97 else
98 {
99 char *home = mu_get_homedir ();
100 if (!home)
101 abort (); /* shouldn't happen */
102 p = mh_safe_make_file_name (home, MH_USER_PROFILE);
103 free (home);
104 }
105
106 if (mh_auto_install && access (p, R_OK))
107 mh_install (p, 1);
108
109 mu_mh_profile = mh_read_property_file (p, 0);
110
111 mu_set_folder_directory (mh_get_dir ());
112
113 mh_set_reply_regex (mh_global_profile_get ("Reply-Regex", NULL));
114 fallback = mh_global_profile_get ("Decode-Fallback", NULL);
115 if (fallback && mu_set_default_fallback (fallback))
116 mu_error (_("Incorrect value for decode-fallback"));
117
118 _mh_init_global_context ();
119 }
120
121 /* Global context */
122
123 const char *
mh_current_folder()124 mh_current_folder ()
125 {
126 return mh_global_context_get ("Current-Folder",
127 mh_global_profile_get ("Inbox", "inbox"));
128 }
129
130 const char *
mh_set_current_folder(const char * val)131 mh_set_current_folder (const char *val)
132 {
133 int rc = mh_global_context_set ("Current-Folder", val);
134 if (rc)
135 {
136 mu_diag_funcall (MU_DIAG_ERROR, "mh_global_context_set",
137 "Current-Folder", rc);
138 exit (1);
139 }
140 current_folder = mh_current_folder ();
141 return current_folder;
142 }
143
144 /* Global sequences */
145 mu_property_t
mh_mailbox_get_property(mu_mailbox_t mbox)146 mh_mailbox_get_property (mu_mailbox_t mbox)
147 {
148 mu_property_t prop;
149 int rc = mu_mailbox_get_property (mbox, &prop);
150 if (rc)
151 {
152 mu_diag_funcall (MU_DIAG_ERROR, "mu_mailbox_get_property", NULL, rc);
153 exit (1);
154 }
155 return prop;
156 }
157
158 void
mh_global_sequences_drop(mu_mailbox_t mbox)159 mh_global_sequences_drop (mu_mailbox_t mbox)
160 {
161 mu_property_t prop = mh_mailbox_get_property (mbox);
162 int rc = mu_property_clear (prop);
163 if (rc)
164 {
165 mu_diag_funcall (MU_DIAG_ERROR, "mu_property_clear", NULL, rc);
166 exit (1);
167 }
168 }
169
170 const char *
mh_global_sequences_get(mu_mailbox_t mbox,const char * name,const char * defval)171 mh_global_sequences_get (mu_mailbox_t mbox, const char *name,
172 const char *defval)
173 {
174 mu_property_t prop = mh_mailbox_get_property (mbox);
175 const char *s;
176 int rc = mu_property_sget_value (prop, name, &s);
177 if (rc == MU_ERR_NOENT)
178 s = defval;
179 else if (rc)
180 {
181 mu_diag_funcall (MU_DIAG_ERROR, "mu_property_sget_value", name, rc);
182 exit (1);
183 }
184 return s;
185 }
186
187 void
mh_global_sequences_set(mu_mailbox_t mbox,const char * name,const char * value)188 mh_global_sequences_set (mu_mailbox_t mbox, const char *name,
189 const char *value)
190 {
191 mu_property_t prop = mh_mailbox_get_property (mbox);
192 int rc = mu_property_set_value (prop, name, value, 1);
193 if (rc && !(!value && rc == MU_ERR_NOENT))
194 {
195 mu_diag_funcall (MU_DIAG_ERROR, "mu_property_set_value", name, rc);
196 exit (1);
197 }
198 }
199
200 void
mh_global_sequences_iterate(mu_mailbox_t mbox,mu_mhprop_iterator_t fp,void * data)201 mh_global_sequences_iterate (mu_mailbox_t mbox,
202 mu_mhprop_iterator_t fp, void *data)
203 {
204 int rc;
205 mu_iterator_t itr;
206 mu_property_t prop = mh_mailbox_get_property (mbox);
207
208 rc = mu_property_get_iterator (prop, &itr);
209 if (rc)
210 {
211 mu_diag_funcall (MU_DIAG_ERROR, "mu_property_get_iterator", NULL, rc);
212 exit (1);
213 }
214 mu_mhprop_iterate (prop, fp, data);
215 }
216
217 /* Global state */
218
219 void
mh_global_save_state()220 mh_global_save_state ()
221 {
222 int rc;
223
224 mh_global_context_set ("Current-Folder", current_folder);
225 rc = mu_property_save (mu_mh_context);
226 if (rc)
227 {
228 mu_diag_funcall (MU_DIAG_ERROR, "mu_property_save", "context", rc);
229 exit (1);
230 }
231 }
232
233
234