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: mhstorage.c,v 1.14 2008/02/17 13:13:26 hoa Exp $
34  */
35 
36 #ifdef HAVE_CONFIG_H
37 #	include <config.h>
38 #endif
39 
40 #include "mhstorage.h"
41 
42 #include "mhdriver.h"
43 #include "mhdriver_cached.h"
44 #include "mail.h"
45 
46 #include <stdlib.h>
47 #include <string.h>
48 
49 /* mh storage */
50 
51 static int mh_mailstorage_connect(struct mailstorage * storage);
52 static int mh_mailstorage_get_folder_session(struct mailstorage * storage,
53     char * pathname, mailsession ** result);
54 static void mh_mailstorage_uninitialize(struct mailstorage * storage);
55 
56 static mailstorage_driver mh_mailstorage_driver = {
57   /* sto_name               */ "mh",
58   /* sto_connect            */ mh_mailstorage_connect,
59   /* sto_get_folder_session */ mh_mailstorage_get_folder_session,
60   /* sto_uninitialize       */ mh_mailstorage_uninitialize
61 };
62 
63 LIBETPAN_EXPORT
mh_mailstorage_init(struct mailstorage * storage,const char * mh_pathname,int mh_cached,const char * mh_cache_directory,const char * mh_flags_directory)64 int mh_mailstorage_init(struct mailstorage * storage,
65     const char * mh_pathname, int mh_cached,
66     const char * mh_cache_directory, const char * mh_flags_directory)
67 {
68   struct mh_mailstorage * mh_storage;
69 
70   mh_storage = malloc(sizeof(* mh_storage));
71   if (mh_storage == NULL)
72     goto err;
73 
74   mh_storage->mh_pathname = strdup(mh_pathname);
75   if (mh_storage->mh_pathname == NULL)
76     goto free;
77 
78   mh_storage->mh_cached = mh_cached;
79 
80   if (mh_cached && (mh_cache_directory != NULL) &&
81       (mh_flags_directory != NULL)) {
82     mh_storage->mh_cache_directory = strdup(mh_cache_directory);
83     if (mh_storage->mh_cache_directory == NULL)
84       goto free_pathname;
85     mh_storage->mh_flags_directory = strdup(mh_flags_directory);
86     if (mh_storage->mh_flags_directory == NULL)
87       goto free_cache_directory;
88   }
89   else {
90     mh_storage->mh_cached = FALSE;
91     mh_storage->mh_cache_directory = NULL;
92     mh_storage->mh_flags_directory = NULL;
93   }
94 
95   storage->sto_data = mh_storage;
96   storage->sto_driver = &mh_mailstorage_driver;
97 
98   return MAIL_NO_ERROR;
99 
100  free_cache_directory:
101   free(mh_storage->mh_cache_directory);
102  free_pathname:
103   free(mh_storage->mh_pathname);
104  free:
105   free(mh_storage);
106  err:
107   return MAIL_ERROR_MEMORY;
108 }
109 
mh_mailstorage_uninitialize(struct mailstorage * storage)110 static void mh_mailstorage_uninitialize(struct mailstorage * storage)
111 {
112   struct mh_mailstorage * mh_storage;
113 
114   mh_storage = storage->sto_data;
115   if (mh_storage->mh_flags_directory != NULL)
116     free(mh_storage->mh_flags_directory);
117   if (mh_storage->mh_cache_directory != NULL)
118     free(mh_storage->mh_cache_directory);
119   free(mh_storage->mh_pathname);
120   free(mh_storage);
121 
122   storage->sto_data = NULL;
123 }
124 
mh_mailstorage_connect(struct mailstorage * storage)125 static int mh_mailstorage_connect(struct mailstorage * storage)
126 {
127   struct mh_mailstorage * mh_storage;
128   mailsession_driver * driver;
129   int r;
130   int res;
131   mailsession * session;
132 
133   mh_storage = storage->sto_data;
134 
135   if (mh_storage->mh_cached)
136     driver = mh_cached_session_driver;
137   else
138     driver = mh_session_driver;
139 
140   session = mailsession_new(driver);
141   if (session == NULL) {
142     res = MAIL_ERROR_MEMORY;
143     goto err;
144   }
145 
146   if (mh_storage->mh_cached) {
147     r = mailsession_parameters(session,
148         MHDRIVER_CACHED_SET_CACHE_DIRECTORY,
149         mh_storage->mh_cache_directory);
150     if (r != MAIL_NO_ERROR) {
151       res = r;
152       goto free;
153     }
154 
155     r = mailsession_parameters(session,
156         MHDRIVER_CACHED_SET_FLAGS_DIRECTORY,
157         mh_storage->mh_flags_directory);
158     if (r != MAIL_NO_ERROR) {
159       res = r;
160       goto free;
161     }
162   }
163 
164   r = mailsession_connect_path(session, mh_storage->mh_pathname);
165   switch (r) {
166   case MAIL_NO_ERROR_NON_AUTHENTICATED:
167   case MAIL_NO_ERROR_AUTHENTICATED:
168   case MAIL_NO_ERROR:
169     break;
170   default:
171     res = r;
172     goto free;
173   }
174 
175   storage->sto_session = session;
176 
177   return MAIL_NO_ERROR;
178 
179  free:
180   mailsession_free(session);
181  err:
182   return res;
183 }
184 
mh_mailstorage_get_folder_session(struct mailstorage * storage,char * pathname,mailsession ** result)185 static int mh_mailstorage_get_folder_session(struct mailstorage * storage,
186     char * pathname, mailsession ** result)
187 {
188   int r;
189 
190   r = mailsession_select_folder(storage->sto_session, pathname);
191   if (r != MAIL_NO_ERROR)
192     return r;
193 
194   * result = storage->sto_session;
195 
196   return MAIL_NO_ERROR;
197 }
198