Fix FSF address (Tobias Mueller, #470445)
[platform/upstream/evolution-data-server.git] / camel / providers / local / camel-local-provider.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
2  * 
3  * Authors: Michael Zucchi <notzed@ximian.com>
4  *
5  * Copyright (C) 2000 Ximian (www.ximian.com).
6  *
7  * This program is free software; you can redistribute it and/or 
8  * modify it under the terms of version 2 of the GNU Lesser General Public 
9  * License as published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
19  * USA
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <stdio.h>
27 #include <string.h>
28
29 #include <glib/gi18n-lib.h>
30
31 #include "camel-provider.h"
32 #include "camel-session.h"
33 #include "camel-url.h"
34
35 #include "camel-maildir-store.h"
36 #include "camel-mbox-store.h"
37 #include "camel-mh-store.h"
38 #include "camel-spool-store.h"
39
40 #define d(x)
41
42 #ifndef G_OS_WIN32
43
44 static CamelProviderConfEntry mh_conf_entries[] = {
45         CAMEL_PROVIDER_CONF_DEFAULT_PATH,
46         { CAMEL_PROVIDER_CONF_SECTION_START, "general", NULL, N_("Options") },
47         { CAMEL_PROVIDER_CONF_CHECKBOX, "dotfolders", NULL,
48           N_("Use the `.folders' folder summary file (exmh)"), "0" },
49         { CAMEL_PROVIDER_CONF_SECTION_END },
50         { CAMEL_PROVIDER_CONF_END }
51 };
52
53 static CamelProvider mh_provider = {
54         "mh",
55         N_("MH-format mail directories"),
56         N_("For storing local mail in MH-like mail directories."),
57         "mail",
58         CAMEL_PROVIDER_IS_SOURCE | CAMEL_PROVIDER_IS_STORAGE | CAMEL_PROVIDER_IS_LOCAL,
59         CAMEL_URL_NEED_PATH | CAMEL_URL_NEED_PATH_DIR | CAMEL_URL_PATH_IS_ABSOLUTE | CAMEL_URL_FRAGMENT_IS_PATH,
60         mh_conf_entries,
61         /* ... */
62 };
63
64 #endif
65
66 static CamelProviderConfEntry mbox_conf_entries[] = {
67         CAMEL_PROVIDER_CONF_DEFAULT_PATH,
68         { CAMEL_PROVIDER_CONF_END }
69 };
70
71 static CamelProvider mbox_provider = {
72         "mbox",
73         N_("Local delivery"),
74         N_("For retrieving (moving) local mail from standard mbox-formatted spools into folders managed by Evolution."),
75         "mail",
76         CAMEL_PROVIDER_IS_SOURCE | CAMEL_PROVIDER_IS_STORAGE | CAMEL_PROVIDER_IS_LOCAL,
77         CAMEL_URL_NEED_PATH | CAMEL_URL_NEED_PATH_DIR |CAMEL_URL_PATH_IS_ABSOLUTE | CAMEL_URL_FRAGMENT_IS_PATH,
78         mbox_conf_entries,
79         /* ... */
80 };
81
82 #ifndef G_OS_WIN32
83
84 static CamelProviderConfEntry maildir_conf_entries[] = {
85         CAMEL_PROVIDER_CONF_DEFAULT_PATH,
86         { CAMEL_PROVIDER_CONF_SECTION_START, "general", NULL, N_("Options") },
87         { CAMEL_PROVIDER_CONF_CHECKBOX, "filter", NULL,
88           N_("Apply filters to new messages in INBOX"), "0" },
89         { CAMEL_PROVIDER_CONF_SECTION_END },
90         { CAMEL_PROVIDER_CONF_END }
91 };
92
93 static CamelProvider maildir_provider = {
94         "maildir",
95         N_("Maildir-format mail directories"),
96         N_("For storing local mail in maildir directories."),
97         "mail",
98         CAMEL_PROVIDER_IS_SOURCE | CAMEL_PROVIDER_IS_STORAGE | CAMEL_PROVIDER_IS_LOCAL,
99         CAMEL_URL_NEED_PATH | CAMEL_URL_NEED_PATH_DIR | CAMEL_URL_PATH_IS_ABSOLUTE | CAMEL_URL_FRAGMENT_IS_PATH,
100         maildir_conf_entries,
101         /* ... */
102 };
103
104 static CamelProviderConfEntry spool_conf_entries[] = {
105         CAMEL_PROVIDER_CONF_DEFAULT_PATH,
106         { CAMEL_PROVIDER_CONF_SECTION_START, "general", NULL, N_("Options") },
107         { CAMEL_PROVIDER_CONF_CHECKBOX, "filter", NULL, N_("Apply filters to new messages in INBOX"), "0" },
108         { CAMEL_PROVIDER_CONF_CHECKBOX, "xstatus", NULL, N_("Store status headers in Elm/Pine/Mutt format"), "0" },
109         { CAMEL_PROVIDER_CONF_SECTION_END },
110         { CAMEL_PROVIDER_CONF_END }
111 };
112
113 static CamelProvider spool_file_provider = {
114         "spool",
115         N_("Standard Unix mbox spool file"),
116         N_("For reading and storing local mail in external standard mbox spool files.\nMay also be used to read a tree of Elm, Pine, or Mutt style folders."),
117         "mail",
118         CAMEL_PROVIDER_IS_SOURCE | CAMEL_PROVIDER_IS_STORAGE,
119         CAMEL_URL_NEED_PATH | CAMEL_URL_PATH_IS_ABSOLUTE | CAMEL_URL_FRAGMENT_IS_PATH,
120         spool_conf_entries,
121         /* ... */
122 };
123
124 static CamelProvider spool_directory_provider = {
125         "spooldir",
126         N_("Standard Unix mbox spool directory"),
127         N_("For reading and storing local mail in external standard mbox spool files.\nMay also be used to read a tree of Elm, Pine, or Mutt style folders."),
128         "mail",
129         CAMEL_PROVIDER_IS_SOURCE | CAMEL_PROVIDER_IS_STORAGE,
130         CAMEL_URL_NEED_PATH | CAMEL_URL_NEED_PATH_DIR | CAMEL_URL_PATH_IS_ABSOLUTE | CAMEL_URL_FRAGMENT_IS_PATH,
131         spool_conf_entries,
132         /* ... */
133 };
134
135 #endif
136
137 /* build a canonical 'path' */
138 static char *
139 make_can_path(char *p, char *o)
140 {
141         char c, last, *start = o;
142
143         d(printf("canonical '%s' = ", p));
144
145         last = 0;
146         while ((c = *p++)) {
147                 if (c!='/'
148                     || (c=='/' && last != '/'))
149                         *o++ = c;
150                 last = c;
151         }
152         if (o>start && o[-1] == '/')
153                 o[-1] = 0;
154         else
155                 *o = 0;
156
157         d(printf("'%s'\n", start));
158
159         return start;
160 }
161
162 /* 'helper' function for it */
163 #define get_can_path(p) ((p == NULL) ? NULL : (make_can_path ((p), g_alloca (strlen (p) + 1))))
164
165 static guint
166 local_url_hash (const void *v)
167 {
168         const CamelURL *u = v;
169         guint hash = 0;
170         
171 #define ADD_HASH(s) if (s) hash ^= g_str_hash (s);
172         
173         ADD_HASH (u->protocol);
174         ADD_HASH (u->user);
175         ADD_HASH (u->authmech);
176         ADD_HASH (u->host);
177         if (u->path)
178                 hash ^= g_str_hash(get_can_path(u->path));
179         ADD_HASH (u->path);
180         ADD_HASH (u->query);
181         hash ^= u->port;
182         
183         return hash;
184 }
185
186 static int
187 check_equal (char *s1, char *s2)
188 {
189         if (s1 == NULL || *s1 == 0) {
190                 if (s2 == NULL || *s2 == 0)
191                         return TRUE;
192                 else
193                         return FALSE;
194         }
195         
196         if (s2 == NULL)
197                 return FALSE;
198
199         return strcmp (s1, s2) == 0;
200 }
201
202 static int
203 local_url_equal(const void *v, const void *v2)
204 {
205         const CamelURL *u1 = v, *u2 = v2;
206         char *p1, *p2;
207
208         p1 = get_can_path(u1->path);
209         p2 = get_can_path(u2->path);
210         return check_equal(p1, p2)
211                 && check_equal(u1->protocol, u2->protocol);
212 }
213
214 void camel_provider_module_init(void)
215 {
216 #ifndef G_OS_WIN32
217         char *path;
218 #endif
219         static int init = 0;
220
221         if (init)
222                 abort();
223         init = 1;
224
225 #ifndef G_OS_WIN32
226         mh_conf_entries[0].value = "";  /* default path */
227         mh_provider.object_types[CAMEL_PROVIDER_STORE] = camel_mh_store_get_type ();
228         mh_provider.url_hash = local_url_hash;
229         mh_provider.url_equal = local_url_equal;
230         mh_provider.translation_domain = GETTEXT_PACKAGE;
231         camel_provider_register(&mh_provider);
232 #endif
233
234 #ifndef G_OS_WIN32
235         if (!(path = getenv ("MAIL")))
236                 path = g_strdup_printf (SYSTEM_MAIL_DIR "/%s", g_get_user_name ());
237         mbox_conf_entries[0].value = path;  /* default path */
238 #else
239         mbox_conf_entries[0].value = "";  /* default path */
240 #endif
241         mbox_provider.object_types[CAMEL_PROVIDER_STORE] = camel_mbox_store_get_type ();
242         mbox_provider.url_hash = local_url_hash;
243         mbox_provider.url_equal = local_url_equal;
244         mbox_provider.translation_domain = GETTEXT_PACKAGE;
245         camel_provider_register(&mbox_provider);
246
247 #ifndef G_OS_WIN32
248         spool_conf_entries[0].value = path;  /* default path - same as mbox; it's for both file and directory */
249         spool_file_provider.object_types[CAMEL_PROVIDER_STORE] = camel_spool_store_get_type ();
250         spool_file_provider.url_hash = local_url_hash;
251         spool_file_provider.url_equal = local_url_equal;
252         spool_file_provider.translation_domain = GETTEXT_PACKAGE;
253         camel_provider_register(&spool_file_provider);
254
255         spool_directory_provider.object_types[CAMEL_PROVIDER_STORE] = camel_spool_store_get_type ();
256         spool_directory_provider.url_hash = local_url_hash;
257         spool_directory_provider.url_equal = local_url_equal;
258         spool_directory_provider.translation_domain = GETTEXT_PACKAGE;
259         camel_provider_register(&spool_directory_provider);
260
261         path = getenv("MAILDIR");
262         maildir_conf_entries[0].value = path ? path : "";  /* default path */
263         maildir_provider.object_types[CAMEL_PROVIDER_STORE] = camel_maildir_store_get_type ();
264         maildir_provider.url_hash = local_url_hash;
265         maildir_provider.url_equal = local_url_equal;
266         maildir_provider.translation_domain = GETTEXT_PACKAGE;
267         camel_provider_register(&maildir_provider);
268 #endif
269 }