1 /*
2  * libEtPan! -- a mail stuff library
3  *
4  * Copyright (C) 2001, 2005 - DINH Viet Hoa
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. Neither the name of the libEtPan! project nor the names of its
16  *    contributors may be used to endorse or promote products derived
17  *    from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31 
32 /*
33  * $Id: maildirstorage.c,v 1.11 2008/02/17 13:13:26 hoa Exp $
34  */
35 
36 #ifdef HAVE_CONFIG_H
37 #	include <config.h>
38 #endif
39 
40 #include "maildirstorage.h"
41 #include "mailstorage.h"
42 
43 #include "mail.h"
44 #include "mailmessage.h"
45 #include "maildirdriver.h"
46 #include "maildirdriver_cached.h"
47 #include "maildriver.h"
48 
49 #include <stdlib.h>
50 #include <string.h>
51 
52 /* maildir storage */
53 
54 static int maildir_mailstorage_connect(struct mailstorage * storage);
55 static int
56 maildir_mailstorage_get_folder_session(struct mailstorage * storage,
57     char * pathname, mailsession ** result);
58 static void maildir_mailstorage_uninitialize(struct mailstorage * storage);
59 
60 static mailstorage_driver maildir_mailstorage_driver = {
61   /* sto_name               */ "maildir",
62   /* sto_connect            */ maildir_mailstorage_connect,
63   /* sto_get_folder_session */ maildir_mailstorage_get_folder_session,
64   /* sto_uninitialize       */ maildir_mailstorage_uninitialize
65 };
66 
67 LIBETPAN_EXPORT
maildir_mailstorage_init(struct mailstorage * storage,const char * md_pathname,int md_cached,const char * md_cache_directory,const char * md_flags_directory)68 int maildir_mailstorage_init(struct mailstorage * storage,
69     const char * md_pathname, int md_cached,
70     const char * md_cache_directory, const char * md_flags_directory)
71 {
72   struct maildir_mailstorage * maildir_storage;
73 
74   maildir_storage = malloc(sizeof(* maildir_storage));
75   if (maildir_storage == NULL)
76     goto err;
77 
78   maildir_storage->md_pathname = strdup(md_pathname);
79   if (maildir_storage->md_pathname == NULL)
80     goto free;
81 
82   maildir_storage->md_cached = md_cached;
83 
84   if (md_cached && (md_cache_directory != NULL) &&
85       (md_flags_directory != NULL)) {
86     maildir_storage->md_cache_directory = strdup(md_cache_directory);
87     if (maildir_storage->md_cache_directory == NULL)
88       goto free_pathname;
89 
90     maildir_storage->md_flags_directory = strdup(md_flags_directory);
91     if (maildir_storage->md_flags_directory == NULL)
92       goto free_cache_directory;
93   }
94   else {
95     maildir_storage->md_cached = FALSE;
96     maildir_storage->md_cache_directory = NULL;
97     maildir_storage->md_flags_directory = NULL;
98   }
99 
100   storage->sto_data = maildir_storage;
101   storage->sto_driver = &maildir_mailstorage_driver;
102 
103   return MAIL_NO_ERROR;
104 
105  free_cache_directory:
106   free(maildir_storage->md_cache_directory);
107  free_pathname:
108   free(maildir_storage->md_pathname);
109  free:
110   free(maildir_storage);
111  err:
112   return MAIL_ERROR_MEMORY;
113 }
114 
maildir_mailstorage_uninitialize(struct mailstorage * storage)115 static void maildir_mailstorage_uninitialize(struct mailstorage * storage)
116 {
117   struct maildir_mailstorage * maildir_storage;
118 
119   maildir_storage = storage->sto_data;
120   if (maildir_storage->md_flags_directory != NULL)
121     free(maildir_storage->md_flags_directory);
122   if (maildir_storage->md_cache_directory != NULL)
123     free(maildir_storage->md_cache_directory);
124   free(maildir_storage->md_pathname);
125   free(maildir_storage);
126 
127   storage->sto_data = NULL;
128 }
129 
maildir_mailstorage_connect(struct mailstorage * storage)130 static int maildir_mailstorage_connect(struct mailstorage * storage)
131 {
132   struct maildir_mailstorage * maildir_storage;
133   mailsession_driver * driver;
134   int r;
135   int res;
136   mailsession * session;
137 
138   maildir_storage = storage->sto_data;
139 
140   if (maildir_storage->md_cached)
141     driver = maildir_cached_session_driver;
142   else
143     driver = maildir_session_driver;
144 
145   session = mailsession_new(driver);
146   if (session == NULL) {
147     res = MAIL_ERROR_MEMORY;
148     goto err;
149   }
150 
151   if (maildir_storage->md_cached) {
152     r = mailsession_parameters(session,
153         MAILDIRDRIVER_CACHED_SET_CACHE_DIRECTORY,
154         maildir_storage->md_cache_directory);
155     if (r != MAIL_NO_ERROR) {
156       res = r;
157       goto free;
158     }
159 
160     r = mailsession_parameters(session,
161         MAILDIRDRIVER_CACHED_SET_FLAGS_DIRECTORY,
162         maildir_storage->md_flags_directory);
163     if (r != MAIL_NO_ERROR) {
164       res = r;
165       goto free;
166     }
167   }
168 
169   r = mailsession_connect_path(session, maildir_storage->md_pathname);
170   switch (r) {
171   case MAIL_NO_ERROR_NON_AUTHENTICATED:
172   case MAIL_NO_ERROR_AUTHENTICATED:
173   case MAIL_NO_ERROR:
174     break;
175   default:
176     res = r;
177     goto free;
178   }
179 
180   storage->sto_session = session;
181 
182   return MAIL_NO_ERROR;
183 
184  free:
185   mailsession_free(session);
186  err:
187   return res;
188 }
189 
190 static int
maildir_mailstorage_get_folder_session(struct mailstorage * storage,char * pathname,mailsession ** result)191 maildir_mailstorage_get_folder_session(struct mailstorage * storage,
192     char * pathname, mailsession ** result)
193 {
194   * result = storage->sto_session;
195 
196   return MAIL_NO_ERROR;
197 }
198 
199