2007-04-03 Murray Cumming <murrayc@murrayc.com>
[modest] / src / maemo / easysetup / modest-presets.c
1 /* Copyright (c) 2006, Nokia Corporation
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  *   notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  *   notice, this list of conditions and the following disclaimer in the
12  *   documentation and/or other materials provided with the distribution.
13  * * Neither the name of the Nokia Corporation nor the names of its
14  *   contributors may be used to endorse or promote products derived from
15  *   this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #include <string.h> /* for strcmp */
31 #include "modest-presets.h"
32
33 #define MODEST_PRESETS_KEY_NAME              "Name"
34 #define MODEST_PRESETS_KEY_DOMAIN            "Domain"
35 #define MODEST_PRESETS_KEY_MCC               "MCC"
36 #define MODEST_PRESETS_KEY_INCOMING          "IncomingMailServer"
37 #define MODEST_PRESETS_KEY_OUTGOING          "OutgoingMailServer"
38 #define MODEST_PRESETS_KEY_MAILBOX_TYPE      "MailboxType"
39 #define MODEST_PRESETS_KEY_MAILBOX_TYPE_POP  "pop"
40 #define MODEST_PRESETS_KEY_MAILBOX_TYPE_IMAP "imap"
41 #define MODEST_PRESETS_KEY_APOP              "APOPSecureLogin"
42 #define MODEST_PRESETS_KEY_SECURE_SMTP       "SecureSMTP"
43 #define MODEST_PRESETS_KEY_TRUE              "true"
44
45 /** An efficient way to store the info for each provider.
46  */
47 typedef enum _ModestPresetsInfo {
48         /* two bits for the server type */
49         MODEST_PRESETS_INFO_NONE             = 0x0000,
50         MODEST_PRESETS_INFO_IMAP             = 0x0001,
51         MODEST_PRESETS_INFO_POP              = 0x0002,
52         MODEST_PRESETS_INFO_SMTP             = 0x0003,
53
54         /* one bit for each of these */
55         MODEST_PRESETS_INFO_APOP             = 0x0004,
56         MODEST_PRESETS_INFO_SECURE_SMTP      = 0x0008,
57         MODEST_PRESETS_INFO_SECURE_INCOMING  = 0x000f   
58 } ModestPresetsInfo;
59
60 /**
61  * modest_presets_get_info:
62  * @self: a valid ModestPresets instance
63  * @provider_id: ID of the provider 
64  * @incoming_server: get the incoming mailserver if TRUE, get the
65  * outgoing server otherwise
66  *
67  * get information about some incoming or outgoing mailserver
68  *
69  * Returns: a ModestPresetsInfo with the required information
70  */
71 static ModestPresetsInfo
72 modest_presets_get_info (ModestPresets *self, const gchar *provider_id, gboolean incoming_server);
73                                                     
74
75 ModestPresets*
76 modest_presets_new (const gchar *presetfile)
77 {
78         ModestPresets *presets = NULL;
79         GError        *err     = NULL;
80         
81         g_return_val_if_fail (presetfile, NULL);
82         
83         presets = g_new (ModestPresets, 1);
84         presets->keyfile = g_key_file_new ();
85
86         if (!presets->keyfile) {
87                 g_printerr ("modest: cannot instantiate GKeyFile\n");
88                 g_free (presets);
89                 return NULL;
90         }
91
92         if (!g_key_file_load_from_file (presets->keyfile, presetfile,
93                                         G_KEY_FILE_NONE, &err)) {
94                 g_printerr ("modest: cannot open keyfile from %s:\n  %s\n", presetfile,
95                             err ? err->message : "unknown reason");
96                 g_error_free (err);
97                 g_free (presets);
98                 return NULL;
99         }
100
101         return presets;
102 }
103
104 gchar**
105 modest_presets_get_providers  (ModestPresets *self, guint mcc,
106                                gboolean include_globals, gchar ***provider_ids)
107 {
108         gchar **all_providers = NULL;
109         gchar **all_provider_ids = NULL;
110         gchar **filtered  = NULL;
111         gchar **filtered_ids = NULL;
112         GError *err       = NULL;
113         guint i, j, len;
114         
115         g_return_val_if_fail (self && self->keyfile, NULL);
116
117         /* Get all the provider IDs: */
118         all_provider_ids = g_key_file_get_groups (self->keyfile, NULL);
119         len = g_strv_length(all_provider_ids);
120
121         /* Get the names for all these providers: */
122         all_providers = g_new0(gchar*, len + 1); /* Provider names. */
123         for (i=0; i != len; ++i) {
124                 const gchar * provider_id = all_provider_ids[i];
125                 if(provider_id) {
126                         gchar* name = g_key_file_get_string(self->keyfile, provider_id, 
127                                 MODEST_PRESETS_KEY_NAME, NULL);
128                                 
129                         /* Be forgiving of missing names.
130                          * If we use NULL then we will null-terminate the array.
131                          */
132                         if(!name)
133                                 name = g_strdup("");
134                                 
135                         all_providers[i] = name;        
136                 }
137                 else
138                         all_providers[i] = NULL;
139         };
140                 
141         /* return *all* providers? */
142         if (mcc == 0 && include_globals) {
143                 *provider_ids = all_provider_ids;
144                 return all_providers;
145         }
146         
147         /* nope: filter them */
148
149         filtered = g_new0(gchar*, len + 1); /* Provider names. */
150         filtered_ids = g_new0(gchar*, len + 1); /* Provider IDs */
151
152         for (i=0, j=0; i != len; ++i) {
153
154                 int this_mcc;
155                 this_mcc = g_key_file_get_integer (self->keyfile, all_provider_ids[i],
156                                                    MODEST_PRESETS_KEY_MCC, &err);
157                 if (err) {
158                         g_strfreev (all_providers);
159                         g_strfreev (all_provider_ids);
160                         g_strfreev (filtered);
161                         g_strfreev (filtered_ids);
162                         
163                         g_printerr ("modest: error parsing keyfile: %s\n", err->message);
164                         g_error_free (err);
165                         
166                         return NULL;
167                 }
168                 
169                 if (this_mcc == mcc || (this_mcc == 0 && include_globals)) {
170                         filtered[j]   = all_providers[i];
171                         filtered_ids[j]   = all_provider_ids[i];
172                         ++j;
173                         filtered[j] = NULL; /* the array must be NULL-terminated */
174                         filtered_ids[j] = NULL; /* the array must be NULL-terminated */
175                         
176                         all_providers[i]  = NULL; /*  g_strfreev: leave it alone */
177                         all_provider_ids[i]  = NULL; /*  g_strfreev: leave it alone */
178                 }
179         }
180         
181         g_strfreev (all_providers);
182         g_strfreev (all_provider_ids);
183         
184         *provider_ids = filtered_ids;
185         return filtered;
186 }
187
188
189 gchar*
190 modest_presets_get_server (ModestPresets *self, const gchar *provider_id,
191                            gboolean incoming_server)
192 {       
193         g_return_val_if_fail (self && self->keyfile, NULL);
194         g_return_val_if_fail (provider_id, NULL);
195
196         return g_key_file_get_string (self->keyfile, provider_id, 
197                                       incoming_server ?
198                                       MODEST_PRESETS_KEY_INCOMING :
199                                       MODEST_PRESETS_KEY_OUTGOING,
200                                       NULL);
201 }
202
203 gchar *                   modest_presets_get_domain      (ModestPresets *self,
204                                                           const gchar *provider_id)
205 {       
206         g_return_val_if_fail (self && self->keyfile, NULL);
207         g_return_val_if_fail (provider_id, NULL);
208
209         return g_key_file_get_string (self->keyfile, provider_id, 
210                                       MODEST_PRESETS_KEY_DOMAIN,
211                                       NULL);
212 }               
213
214
215 ModestPresetsInfo
216 modest_presets_get_info (ModestPresets *self, const gchar *provider_id, gboolean incoming_server)
217 {
218         ModestPresetsInfo info = 0;
219         gchar *val = NULL;
220         
221         g_return_val_if_fail (self && self->keyfile, 0);
222
223         if(incoming_server) {
224                 val = g_key_file_get_string (self->keyfile, provider_id,
225                                                 MODEST_PRESETS_KEY_INCOMING, NULL);
226                 if (val) {
227                         g_free (val);
228                         val = g_key_file_get_string (self->keyfile, provider_id,
229                                                      MODEST_PRESETS_KEY_MAILBOX_TYPE, NULL);
230                         if (strcmp (val, MODEST_PRESETS_KEY_MAILBOX_TYPE_POP) == 0)
231                                 info |= MODEST_PRESETS_INFO_POP;
232                         if (strcmp (val, MODEST_PRESETS_KEY_MAILBOX_TYPE_IMAP) == 0)
233                                 info |= MODEST_PRESETS_INFO_IMAP;
234                         g_free (val);
235         
236                         val = g_key_file_get_string (self->keyfile, provider_id,
237                                                      MODEST_PRESETS_KEY_APOP, NULL);
238                         if (val && strcmp(val, MODEST_PRESETS_KEY_TRUE) == 0)
239                                 info |= MODEST_PRESETS_INFO_APOP;
240                         g_free(val);
241                 }
242         }
243         else /* outgoing: */ {
244                 val = g_key_file_get_string (self->keyfile, provider_id,
245                                              MODEST_PRESETS_KEY_OUTGOING, NULL);
246                 if (val) {
247                         g_free (val);
248                         info |= MODEST_PRESETS_INFO_SMTP;
249                         
250                         val = g_key_file_get_string (self->keyfile, provider_id,
251                                                      MODEST_PRESETS_KEY_SECURE_SMTP, NULL);
252                         if (val && strcmp(val,MODEST_PRESETS_KEY_TRUE) == 0)
253                                 info |= MODEST_PRESETS_INFO_SECURE_SMTP;
254                         g_free(val);
255                 }
256         }
257
258         return info;
259 }
260
261 ModestPresetsServerType
262 modest_presets_get_info_server_type (ModestPresets *self,
263                                                     const gchar *provider_id,
264                                                     gboolean incoming_server)
265 {
266         ModestPresetsInfo info = modest_presets_get_info (self, provider_id, incoming_server);
267
268         /* The server type is stored in the first 2 bits: */
269         info = info & 0x03;
270         
271         /* Convert from the internal enum to the public enum: */
272         if(info == MODEST_PRESETS_INFO_IMAP)
273                 return MODEST_PRESETS_SERVER_TYPE_IMAP;
274         else if(info == MODEST_PRESETS_INFO_POP)
275                 return MODEST_PRESETS_SERVER_TYPE_POP;
276         else if(info == MODEST_PRESETS_INFO_SMTP)
277                 return MODEST_PRESETS_SERVER_TYPE_SMTP;
278         else
279                 return MODEST_PRESETS_SERVER_TYPE_NONE;
280 }
281
282 ModestPresetsSecurity
283 modest_presets_get_info_server_security (ModestPresets *self,
284                                                     const gchar *provider_id,
285                                                     gboolean incoming_server)
286 {
287         ModestPresetsInfo info = modest_presets_get_info (self, provider_id, incoming_server);
288
289         /* The security flags are stored in all except the first 4 bits: */
290         info = info && !0x04;
291         
292         /* Convert from the internal flags to the public flags: */
293         ModestPresetsSecurity security = MODEST_PRESETS_SECURITY_NONE;
294         if(info && MODEST_PRESETS_INFO_APOP)
295                 security = security | MODEST_PRESETS_SECURITY_APOP;
296                 
297         if(info && MODEST_PRESETS_INFO_SECURE_SMTP)
298                 security = security | MODEST_PRESETS_SECURITY_SECURE_SMTP;
299                 
300         if(info && MODEST_PRESETS_INFO_SECURE_INCOMING)
301                 security = security | MODEST_PRESETS_SECURITY_SECURE_INCOMING;
302
303         return security;
304 }
305
306                                                         
307         
308         
309 void
310 modest_presets_destroy (ModestPresets *self)
311 {
312         if (!self)
313                 return;
314
315         g_key_file_free (self->keyfile);
316         self->keyfile = NULL;
317         
318         g_free (self);
319 }