implementation of mbox folder with unique messages numbers
[claws.git] / src / mailmbox_types.c
1 /*
2  * libEtPan! -- a mail stuff library
3  *
4  * Copyright (C) 2001, 2002 - 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 REGENTS 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 REGENTS 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$
34  */
35
36 #include "mailmbox_types.h"
37
38 #include <string.h>
39 #include <stdlib.h>
40
41 #ifndef TRUE
42 #define TRUE 1
43 #endif
44
45 #ifndef FALSE
46 #define FALSE 0
47 #endif
48
49 /* *********************************************************************** */
50
51 int mailmbox_msg_info_update(struct mailmbox_folder * folder,
52                              size_t start, size_t start_len,
53                              size_t headers, size_t headers_len,
54                              size_t body, size_t body_len,
55                              size_t size, size_t padding,
56                              uint32_t uid)
57 {
58   struct mailmbox_msg_info * info;
59   int res;
60   chashdatum key;
61   chashdatum data;
62   int r;
63   
64   key.data = (char *) &uid;
65   key.len = sizeof(uid);
66   r = chash_get(folder->hash, &key, &data);
67   if (r < 0) {
68     uint32_t index;
69
70     info = mailmbox_msg_info_new(start, start_len, headers, headers_len,
71                                  body, body_len, size, padding, uid);
72     if (info == NULL) {
73       res = MAILMBOX_ERROR_MEMORY;
74       goto err;
75     }
76
77     r = carray_add(folder->tab, info, &index);
78     if (r < 0) {
79       mailmbox_msg_info_free(info);
80       res = MAILMBOX_ERROR_MEMORY;
81       goto err;
82     }
83
84     if (uid != 0) {
85       chashdatum key;
86       chashdatum data;
87       
88       key.data = (char *) &uid;
89       key.len = sizeof(uid);
90       data.data = (char *) info;
91       data.len = 0;
92       
93       r = chash_set(folder->hash, &key, &data, NULL);
94       if (r < 0) {
95         mailmbox_msg_info_free(info);
96         carray_delete(folder->tab, index);
97         res = MAILMBOX_ERROR_MEMORY;
98         goto err;
99       }
100     }
101     
102     info->index = index;
103   }
104   else {
105     info = (struct mailmbox_msg_info *) data.data;
106     
107     info->start = start;
108     info->start_len = start_len;
109     info->headers = headers;
110     info->headers_len = headers_len;
111     info->body = body;
112     info->body_len = body_len;
113     info->size = size;
114     info->padding = padding;
115   }
116
117   return MAILMBOX_NO_ERROR;
118
119  err:
120   return res;
121 }
122
123
124 struct mailmbox_msg_info *
125 mailmbox_msg_info_new(size_t start, size_t start_len,
126                       size_t headers, size_t headers_len,
127                       size_t body, size_t body_len,
128                       size_t size, size_t padding,
129                       uint32_t uid)
130 {
131   struct mailmbox_msg_info * info;
132
133   info = malloc(sizeof(* info));
134   if (info == NULL)
135     return NULL;
136
137   info->index = 0;
138   info->uid = uid;
139   if (uid != 0)
140     info->written_uid = TRUE;
141   else
142     info->written_uid = FALSE;
143   info->deleted = FALSE;
144
145   info->start = start;
146   info->start_len = start_len;
147
148   info->headers = headers;
149   info->headers_len = headers_len;
150
151   info->body = body;
152   info->body_len = body_len;
153
154   info->size = size;
155
156   info->padding = padding;
157
158   return info;
159 }
160
161 void mailmbox_msg_info_free(struct mailmbox_msg_info * info)
162 {
163   free(info);
164 }
165
166 /* *********************************************************************** */
167
168 #if 0
169 struct mailmbox_msg_env *
170 mailmbox_msg_env_new(uint32_t index, struct mailimf_fields * fields)
171 {
172   struct mailmbox_msg_env * msg_env;
173
174   msg_env = alloc(struct mailmbox_msg_env, 1);
175   if (msg_env == NULL)
176     return NULL;
177
178   msg_env->index = index;
179   msg_env->fields = fields;
180   
181   return msg_env;
182 }
183
184 void mailmbox_msg_env_free(struct mailmbox_msg_env * msg_env)
185 {
186   if (msg_env->fields != NULL)
187     mailimf_fields_free(msg_env->fields);
188   free(msg_env);
189 }
190 #endif
191
192 /* append info */
193
194 struct mailmbox_append_info *
195 mailmbox_append_info_new(char * message, size_t size)
196 {
197   struct mailmbox_append_info * info;
198
199   info = malloc(sizeof(* info));
200   if (info == NULL)
201     return NULL;
202
203   info->message = message;
204   info->size = size;
205
206   return info;
207 }
208
209 void mailmbox_append_info_free(struct mailmbox_append_info * info)
210 {
211   free(info);
212 }
213
214 #if 0
215 struct mailmbox_append_info_list *
216 mailmbox_append_info_list_new(clist * list)
217 {
218   struct mailmbox_append_info_list * info_list;
219
220   info_list = alloc(struct mailmbox_append_info_list, 1);
221   if (info_list == NULL)
222     return NULL;
223
224   info_list->list = list;
225
226   return info_list;
227 }
228
229 void mailmbox_append_info_list_free(struct mailmbox_append_info_list *
230                                     info_list)
231 {
232   clist_foreach(info_list->list, (clist_func) mailmbox_append_info_free, NULL);
233   free(info_list);
234 }
235 #endif
236
237 struct mailmbox_folder * mailmbox_folder_new(char * filename)
238 {
239   struct mailmbox_folder * folder;
240
241   folder = malloc(sizeof(* folder));
242   if (folder == NULL)
243     goto err;
244
245   strncpy(folder->filename, filename, PATH_MAX);
246
247   folder->mtime = (time_t) -1;
248
249   folder->fd = -1;
250   folder->read_only = TRUE;
251   folder->no_uid = TRUE;
252
253   folder->changed = FALSE;
254   folder->deleted_count = 0;
255   
256   folder->mapping = NULL;
257   folder->mapping_size = 0;
258
259   folder->written_uid = 0;
260   folder->max_uid = 0;
261
262   folder->hash = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYKEY);
263   if (folder->hash == NULL)
264     goto free;
265   
266   folder->tab = carray_new(128);
267   if (folder->tab == NULL)
268     goto free_hash;
269
270   return folder;
271
272  free_hash:
273   chash_free(folder->hash);
274  free:
275   free(folder);
276  err:
277   return NULL;
278 }
279
280 void mailmbox_folder_free(struct mailmbox_folder * folder)
281 {
282   uint32_t i;
283
284   for(i = 0 ; i < folder->tab->len ; i++) {
285     struct mailmbox_msg_info * info;
286
287     info = carray_get(folder->tab, i);
288     if (info != NULL)
289       mailmbox_msg_info_free(info);
290   }
291
292   carray_free(folder->tab);
293   
294   chash_free(folder->hash);
295
296   free(folder);
297 }