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