summaryrefslogtreecommitdiffabout
path: root/libetpan/src/data-types
Unidiff
Diffstat (limited to 'libetpan/src/data-types') (more/less context) (ignore whitespace changes)
-rw-r--r--libetpan/src/data-types/base64.c143
-rw-r--r--libetpan/src/data-types/base64.h59
-rw-r--r--libetpan/src/data-types/carray.c142
-rw-r--r--libetpan/src/data-types/carray.h123
-rw-r--r--libetpan/src/data-types/charconv.c251
-rw-r--r--libetpan/src/data-types/charconv.h67
-rw-r--r--libetpan/src/data-types/chash.c394
-rw-r--r--libetpan/src/data-types/chash.h165
-rw-r--r--libetpan/src/data-types/cinthash.c248
-rw-r--r--libetpan/src/data-types/cinthash.h69
-rw-r--r--libetpan/src/data-types/clist.c265
-rw-r--r--libetpan/src/data-types/clist.h133
-rw-r--r--libetpan/src/data-types/connect.c86
-rw-r--r--libetpan/src/data-types/connect.h54
-rw-r--r--libetpan/src/data-types/hmac-md5.h94
-rw-r--r--libetpan/src/data-types/mail.h56
-rw-r--r--libetpan/src/data-types/mail_cache_db.c403
-rw-r--r--libetpan/src/data-types/mail_cache_db.h148
-rw-r--r--libetpan/src/data-types/mail_cache_db_types.h52
-rw-r--r--libetpan/src/data-types/maillock.c301
-rw-r--r--libetpan/src/data-types/maillock.h53
-rw-r--r--libetpan/src/data-types/mailsem.c114
-rw-r--r--libetpan/src/data-types/mailsem.h51
-rw-r--r--libetpan/src/data-types/mailstream.c399
-rw-r--r--libetpan/src/data-types/mailstream.h73
-rw-r--r--libetpan/src/data-types/mailstream_helper.c515
-rw-r--r--libetpan/src/data-types/mailstream_helper.h77
-rw-r--r--libetpan/src/data-types/mailstream_low.c164
-rw-r--r--libetpan/src/data-types/mailstream_low.h62
-rw-r--r--libetpan/src/data-types/mailstream_socket.c238
-rw-r--r--libetpan/src/data-types/mailstream_socket.h61
-rw-r--r--libetpan/src/data-types/mailstream_ssl.c320
-rw-r--r--libetpan/src/data-types/mailstream_ssl.h59
-rw-r--r--libetpan/src/data-types/mailstream_types.h87
-rw-r--r--libetpan/src/data-types/mapping.c67
-rw-r--r--libetpan/src/data-types/mapping.h54
-rw-r--r--libetpan/src/data-types/md5.c570
-rw-r--r--libetpan/src/data-types/md5.h88
-rw-r--r--libetpan/src/data-types/md5global.h79
-rw-r--r--libetpan/src/data-types/mmapstring.c551
-rw-r--r--libetpan/src/data-types/mmapstring.h136
41 files changed, 7071 insertions, 0 deletions
diff --git a/libetpan/src/data-types/base64.c b/libetpan/src/data-types/base64.c
new file mode 100644
index 0000000..58a2c04
--- a/dev/null
+++ b/libetpan/src/data-types/base64.c
@@ -0,0 +1,143 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2005 - Juergen Graf
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$
34 */
35
36#include "base64.h"
37
38#include <stdlib.h>
39
40#define OUTPUT_SIZE 513
41#define CHAR64(c) (((c) < 0 || (c) > 127) ? -1 : index_64[(c)])
42
43static char index_64[128] = {
44 -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
45 -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
46 -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,
47 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1,-1,-1,-1,
48 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14,
49 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1,
50 -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
51 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1
52};
53
54static char basis_64[] =
55 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
56
57char * encode_base64(const char * in, int len)
58{
59 char * output, * tmp;
60 unsigned char oval;
61 int out_len;
62
63 out_len = ((len + 2) / 3 * 4) + 1;
64
65 if ((len > 0) && (in == NULL))
66 return NULL;
67
68 output = malloc(out_len);
69 if (!output)
70 return NULL;
71
72 tmp = output;
73 while (len >= 3) {
74 *tmp++ = basis_64[in[0] >> 2];
75 *tmp++ = basis_64[((in[0] << 4) & 0x30) | (in[1] >> 4)];
76 *tmp++ = basis_64[((in[1] << 2) & 0x3c) | (in[2] >> 6)];
77 *tmp++ = basis_64[in[2] & 0x3f];
78 in += 3;
79 len -= 3;
80 }
81 if (len > 0) {
82 *tmp++ = basis_64[in[0] >> 2];
83 oval = (in[0] << 4) & 0x30;
84 if (len > 1) oval |= in[1] >> 4;
85 *tmp++ = basis_64[oval];
86 *tmp++ = (len < 2) ? '=' : basis_64[(in[1] << 2) & 0x3c];
87 *tmp++ = '=';
88 }
89
90 *tmp = '\0';
91
92 return output;
93}
94
95char * decode_base64(const char * in, int len)
96{
97 char * output, * out;
98 int i, c1, c2, c3, c4, out_len;
99
100 out_len = 0;
101
102 output = malloc(OUTPUT_SIZE);
103 if (output == NULL)
104 return NULL;
105 out = output;
106
107 if (in[0] == '+' && in[1] == ' ')
108 in += 2;
109
110 for (i = 0; i < (len / 4); i++) {
111 c1 = in[0];
112 c2 = in[1];
113 c3 = in[2];
114 c4 = in[3];
115 if (CHAR64(c1) == -1 || CHAR64(c2) == -1 ||
116 (c3 != '=' && CHAR64(c3) == -1) ||
117 (c4 != '=' && CHAR64(c4) == -1))
118 return NULL;
119
120 in += 4;
121 *output++ = (CHAR64(c1) << 2) | (CHAR64(c2) >> 4);
122 if (++out_len >= OUTPUT_SIZE)
123 return NULL;
124
125 if (c3 != '=') {
126 *output++ = ((CHAR64(c2) << 4) & 0xf0) | (CHAR64(c3) >> 2);
127 if (++out_len >= OUTPUT_SIZE)
128 return NULL;
129
130 if (c4 != '=') {
131 *output++ = ((CHAR64(c3) << 6) & 0xc0) | CHAR64(c4);
132 if (++out_len >= OUTPUT_SIZE)
133 return NULL;
134 }
135 }
136 }
137
138 *output = 0;
139
140 return out;
141}
142
143
diff --git a/libetpan/src/data-types/base64.h b/libetpan/src/data-types/base64.h
new file mode 100644
index 0000000..1430207
--- a/dev/null
+++ b/libetpan/src/data-types/base64.h
@@ -0,0 +1,59 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2005 - Juergen Graf
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$
34 */
35
36#ifndef BASE64_H
37#define BASE64_H
38
39#ifdef __cplusplus
40extern "C" {
41#endif
42
43/**
44 * creates (malloc) a new base64 encoded string from a standard 8bit string
45 * don't forget to free it when time comes ;)
46 */
47char * encode_base64(const char * in, int len);
48
49/**
50 * creates (malloc) a new standard 8bit string from an base64 encoded string
51 * don't forget to free it when time comes ;)
52 */
53char * decode_base64(const char * in, int len);
54
55#ifdef __cplusplus
56}
57#endif
58
59#endif
diff --git a/libetpan/src/data-types/carray.c b/libetpan/src/data-types/carray.c
new file mode 100644
index 0000000..f1e618b
--- a/dev/null
+++ b/libetpan/src/data-types/carray.c
@@ -0,0 +1,142 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * carray - Implements simple dynamic pointer arrays
5 *
6 * Copyright (c) 1999-2005, Gaël Roualland <gael.roualland@iname.com>
7 * interface changes - 2005 - DINH Viet Hoa
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the libEtPan! project nor the names of its
19 * contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35/*
36 * $Id$
37 */
38
39#include <stdlib.h>
40#include <string.h>
41#include "carray.h"
42
43carray * carray_new(unsigned int initsize) {
44 carray * array;
45
46 array = (carray *) malloc(sizeof(carray));
47 if (!array) return NULL;
48
49 array->len = 0;
50 array->max = initsize;
51 array->array = (void **) malloc(sizeof(void *) * initsize);
52 if (!array->array) {
53 free(array);
54 return NULL;
55 }
56 return array;
57}
58
59int carray_add(carray * array, void * data, unsigned int * index) {
60 int r;
61
62 r = carray_set_size(array, array->len + 1);
63 if (r < 0)
64 return r;
65
66 array->array[array->len - 1] = data;
67 if (index != NULL)
68 * index = array->len - 1;
69
70 return 0;
71}
72
73int carray_set_size(carray * array, unsigned int new_size)
74{
75 if (new_size > array->max) {
76 unsigned int n = array->max * 2;
77 void * new;
78
79 while (n <= new_size)
80 n *= 2;
81
82 new = (void **) realloc(array->array, sizeof(void *) * n);
83 if (!new)
84 return -1;
85 array->array = new;
86 array->max = n;
87 }
88 array->len = new_size;
89
90 return 0;
91}
92
93int carray_delete_fast(carray * array, unsigned int indx) {
94 if (indx >= array->len)
95 return -1;
96
97 array->array[indx] = NULL;
98
99 return 0;
100}
101
102int carray_delete(carray * array, unsigned int indx) {
103 if (indx >= array->len)
104 return -1;
105
106 if (indx != --array->len)
107 array->array[indx] = array->array[array->len];
108 return 0;
109}
110
111int carray_delete_slow(carray * array, unsigned int indx) {
112 if (indx >= array->len)
113 return -1;
114
115 if (indx != --array->len)
116 memmove(array->array + indx, array->array + indx + 1,
117 (array->len - indx) * sizeof(void *));
118 return 0;
119}
120
121#ifdef NO_MACROS
122void ** carray_data(carray * array) {
123 return array->array;
124}
125
126unsigned int carray_count(carray * array) {
127 return array->len;
128}
129
130void * carray_get(carray * array, unsigned int indx) {
131 return array->array[indx];
132}
133
134void carray_set(carray * array, unsigned int indx, void * value) {
135 array->array[indx] = value;
136}
137#endif
138
139void carray_free(carray * array) {
140 free(array->array);
141 free(array);
142}
diff --git a/libetpan/src/data-types/carray.h b/libetpan/src/data-types/carray.h
new file mode 100644
index 0000000..f906c57
--- a/dev/null
+++ b/libetpan/src/data-types/carray.h
@@ -0,0 +1,123 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * carray - Implements simple dynamic pointer arrays
5 *
6 * Copyright (c) 1999-2005, Gaël Roualland <gael.roualland@iname.com>
7 * interface changes - 2005 - DINH Viet Hoa
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the libEtPan! project nor the names of its
19 * contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35/*
36 * $Id$
37 */
38
39#ifndef CARRAY_H
40#define CARRAY_H
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46struct carray_s {
47 void ** array;
48 unsigned int len;
49 unsigned int max;
50};
51
52typedef struct carray_s carray;
53
54/* Creates a new array of pointers, with initsize preallocated cells */
55carray * carray_new(unsigned int initsize);
56
57/* Adds the pointer to data in the array.
58 Returns the index of the pointer in the array or -1 on error */
59int carray_add(carray * array, void * data, unsigned int * index);
60
61int carray_set_size(carray * array, unsigned int new_size);
62
63/* Removes the cell at this index position. Returns TRUE on success.
64 Order of elements in the array IS changed. */
65int carray_delete(carray * array, unsigned int indx);
66
67/* Removes the cell at this index position. Returns TRUE on success.
68 Order of elements in the array IS not changed. */
69int carray_delete_slow(carray * array, unsigned int indx);
70
71/* remove without decreasing the size of the array */
72int carray_delete_fast(carray * array, unsigned int indx);
73
74/* Some of the following routines can be implemented as macros to
75 be faster. If you don't want it, define NO_MACROS */
76#ifdef NO_MACROS
77
78/* Returns the array itself */
79void ** carray_data(carray *);
80
81/* Returns the number of elements in the array */
82int carray_count(carray *);
83
84/* Returns the contents of one cell */
85void * carray_get(carray * array, unsigned int indx);
86
87/* Sets the contents of one cell */
88void carray_set(carray * array, unsigned int indx, void * value);
89
90#else
91
92#if 0
93#define carray_data(a) (a->array)
94#define carray_count(a) (a->len)
95#define carray_get(a, indx) (a->array[indx])
96#define carray_set(a, indx, v) do { a->array[indx]=v; } while(0)
97#endif
98
99static inline void ** carray_data(carray * array) {
100 return array->array;
101}
102
103static inline unsigned int carray_count(carray * array) {
104 return array->len;
105}
106
107static inline void * carray_get(carray * array, unsigned int indx) {
108 return array->array[indx];
109}
110
111static inline void carray_set(carray * array,
112 unsigned int indx, void * value) {
113 array->array[indx] = value;
114}
115#endif
116
117void carray_free(carray * array);
118
119#ifdef __cplusplus
120}
121#endif
122
123#endif
diff --git a/libetpan/src/data-types/charconv.c b/libetpan/src/data-types/charconv.c
new file mode 100644
index 0000000..28549c9
--- a/dev/null
+++ b/libetpan/src/data-types/charconv.c
@@ -0,0 +1,251 @@
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$
34 */
35
36#include "charconv.h"
37
38#include "config.h"
39#ifdef HAVE_ICONV
40#include <iconv.h>
41#endif
42#include <stdlib.h>
43#include <string.h>
44#include <stdio.h>
45#include <errno.h>
46
47#include "mmapstring.h"
48
49#ifdef HAVE_ICONV
50static size_t mail_iconv (iconv_t cd, const char **inbuf, size_t *inbytesleft,
51 char **outbuf, size_t *outbytesleft,
52 char **inrepls, char *outrepl)
53{
54 size_t ret = 0, ret1;
55 /* XXX - force const to mutable */
56 char *ib = (char *) *inbuf;
57 size_t ibl = *inbytesleft;
58 char *ob = *outbuf;
59 size_t obl = *outbytesleft;
60
61 for (;;)
62 {
63#ifdef HAVE_ICONV_PROTO_CONST
64 ret1 = iconv (cd, (const char **) &ib, &ibl, &ob, &obl);
65#else
66 ret1 = iconv (cd, &ib, &ibl, &ob, &obl);
67#endif
68 if (ret1 != (size_t)-1)
69 ret += ret1;
70 if (ibl && obl && errno == EILSEQ)
71 {
72 if (inrepls)
73 {
74 /* Try replacing the input */
75 char **t;
76 for (t = inrepls; *t; t++)
77 {
78 char *ib1 = *t;
79 size_t ibl1 = strlen (*t);
80 char *ob1 = ob;
81 size_t obl1 = obl;
82#ifdef HAVE_ICONV_PROTO_CONST
83 iconv (cd, (const char **) &ib1, &ibl1, &ob1, &obl1);
84#else
85 iconv (cd, &ib1, &ibl1, &ob1, &obl1);
86#endif
87 if (!ibl1)
88 {
89 ++ib, --ibl;
90 ob = ob1, obl = obl1;
91 ++ret;
92 break;
93 }
94 }
95 if (*t)
96 continue;
97 }
98 if (outrepl)
99 {
100 /* Try replacing the output */
101 size_t n = strlen (outrepl);
102 if (n <= obl)
103 {
104 memcpy (ob, outrepl, n);
105 ++ib, --ibl;
106 ob += n, obl -= n;
107 ++ret;
108 continue;
109 }
110 }
111 }
112 *inbuf = ib, *inbytesleft = ibl;
113 *outbuf = ob, *outbytesleft = obl;
114 return ret;
115 }
116}
117#endif
118
119int charconv(const char * tocode, const char * fromcode,
120 const char * str, size_t length,
121 char ** result)
122{
123#ifndef HAVE_ICONV
124 return MAIL_CHARCONV_ERROR_UNKNOWN_CHARSET;
125#else
126 iconv_t conv;
127 size_t r;
128 char * out;
129 char * pout;
130 size_t out_size;
131 size_t old_out_size;
132 size_t count;
133 int res;
134
135 conv = iconv_open(tocode, fromcode);
136 if (conv == (iconv_t) -1) {
137 res = MAIL_CHARCONV_ERROR_UNKNOWN_CHARSET;
138 goto err;
139 }
140
141 out_size = 4 * length;
142
143 out = malloc(out_size + 1);
144 if (out == NULL) {
145 res = MAIL_CHARCONV_ERROR_MEMORY;
146 goto close_iconv;
147 }
148
149 pout = out;
150 old_out_size = out_size;
151
152 r = mail_iconv(conv, &str, &length, &pout, &out_size, NULL, "?");
153
154 if (r == (size_t) -1) {
155 res = MAIL_CHARCONV_ERROR_CONV;
156 goto free;
157 }
158
159 iconv_close(conv);
160
161 * pout = '\0';
162 count = old_out_size - out_size;
163 pout = realloc(out, count + 1);
164 if (pout != NULL)
165 out = pout;
166
167 * result = out;
168
169 return MAIL_CHARCONV_NO_ERROR;
170
171 free:
172 free(out);
173 close_iconv:
174 iconv_close(conv);
175 err:
176 return res;
177#endif
178};
179
180int charconv_buffer(const char * tocode, const char * fromcode,
181 const char * str, size_t length,
182 char ** result, size_t * result_len)
183{
184#ifndef HAVE_ICONV
185 return MAIL_CHARCONV_ERROR_UNKNOWN_CHARSET;
186#else
187 iconv_t conv;
188 size_t iconv_r;
189 int r;
190 char * out;
191 char * pout;
192 size_t out_size;
193 size_t old_out_size;
194 size_t count;
195 MMAPString * mmapstr;
196 int res;
197
198 conv = iconv_open(tocode, fromcode);
199 if (conv == (iconv_t) -1) {
200 res = MAIL_CHARCONV_ERROR_UNKNOWN_CHARSET;
201 goto err;
202 }
203
204 out_size = 4 * length;
205
206 mmapstr = mmap_string_sized_new(out_size + 1);
207 if (mmapstr == NULL) {
208 res = MAIL_CHARCONV_ERROR_MEMORY;
209 goto err;
210 }
211
212 out = mmapstr->str;
213
214 pout = out;
215 old_out_size = out_size;
216
217 iconv_r = mail_iconv(conv, &str, &length, &pout, &out_size, NULL, "?");
218
219 if (iconv_r == (size_t) -1) {
220 res = MAIL_CHARCONV_ERROR_CONV;
221 goto free;
222 }
223
224 iconv_close(conv);
225
226 * pout = '\0';
227
228 count = old_out_size - out_size;
229
230 r = mmap_string_ref(mmapstr);
231 if (r < 0) {
232 res = MAIL_CHARCONV_ERROR_MEMORY;
233 goto free;
234 }
235
236 * result = out;
237 * result_len = count;
238
239 return MAIL_CHARCONV_NO_ERROR;
240
241 free:
242 mmap_string_free(mmapstr);
243 err:
244 return -1;
245#endif
246};
247
248void charconv_buffer_free(char * str)
249{
250 mmap_string_unref(str);
251}
diff --git a/libetpan/src/data-types/charconv.h b/libetpan/src/data-types/charconv.h
new file mode 100644
index 0000000..8a68f7b
--- a/dev/null
+++ b/libetpan/src/data-types/charconv.h
@@ -0,0 +1,67 @@
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$
34 */
35
36#ifndef CHARCONV_H
37
38#define CHARCONV_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#include <sys/types.h>
45
46enum {
47 MAIL_CHARCONV_NO_ERROR = 0,
48 MAIL_CHARCONV_ERROR_UNKNOWN_CHARSET,
49 MAIL_CHARCONV_ERROR_MEMORY,
50 MAIL_CHARCONV_ERROR_CONV,
51};
52
53int charconv(const char * tocode, const char * fromcode,
54 const char * str, size_t length,
55 char ** result);
56
57int charconv_buffer(const char * tocode, const char * fromcode,
58 const char * str, size_t length,
59 char ** result, size_t * result_len);
60
61void charconv_buffer_free(char * str);
62
63#ifdef __cplusplus
64}
65#endif
66
67#endif
diff --git a/libetpan/src/data-types/chash.c b/libetpan/src/data-types/chash.c
new file mode 100644
index 0000000..a89eb91
--- a/dev/null
+++ b/libetpan/src/data-types/chash.c
@@ -0,0 +1,394 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * chash - Implements generic hash tables.
5 *
6 * Copyright (c) 1999-2005, Gaël Roualland <gael.roualland@iname.com>
7 * interface changes - 2005 - DINH Viet Hoa
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the libEtPan! project nor the names of its
19 * contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35/*
36 * $Id$
37 */
38
39#include <stdlib.h>
40#include <string.h>
41
42#include "chash.h"
43
44/* This defines the maximum (average) number of entries per bucket.
45 The hash is resized everytime inserting an entry makes the
46 average go over that value. */
47#define CHASH_MAXDEPTH 3
48
49static inline unsigned int chash_func(const char * key, unsigned int len) {
50#if 0
51 register unsigned int c = 0, t;
52 register const char * k = key;
53
54 while (len--) {
55 c += (c << 4) + *k++;
56 if ((t = c & 0xF0000000)) {
57 c ^= t >> 24;
58 c ^= t;
59 }
60 }
61 return c;
62#endif
63 register unsigned int c = 5381;
64 register const char * k = key;
65
66 while (len--) {
67 c = ((c << 5) + c) + *k++;
68 }
69
70 return c;
71}
72
73static inline char * chash_dup(const void * data, unsigned int len)
74{
75 void * r;
76
77 r = (char *) malloc(len);
78 if (!r)
79 return NULL;
80 memcpy(r, data, len);
81 return r;
82}
83
84chash * chash_new(unsigned int size, int flags)
85{
86 chash * h;
87
88 h = (chash *) malloc(sizeof(chash));
89 if (h == NULL)
90 return NULL;
91
92 h->count = 0;
93 h->cells = (struct chashcell **) calloc(size, sizeof(struct chashcell *));
94 if (h->cells == NULL) {
95 free(h);
96 return NULL;
97 }
98 h->size = size;
99 h->copykey = flags & CHASH_COPYKEY;
100 h->copyvalue = flags & CHASH_COPYVALUE;
101
102 return h;
103}
104
105int chash_get(chash * hash,
106 chashdatum * key, chashdatum * result)
107{
108 unsigned int func;
109 chashiter * iter;
110
111 func = chash_func(key->data, key->len);
112
113 /* look for the key in existing cells */
114 iter = hash->cells[func % hash->size];
115 while (iter) {
116 if (iter->key.len == key->len && iter->func == func
117 && !memcmp(iter->key.data, key->data, key->len)) {
118 * result = iter->value; /* found */
119
120 return 0;
121 }
122 iter = iter->next;
123 }
124
125 return -1;
126}
127
128int chash_set(chash * hash,
129 chashdatum * key,
130 chashdatum * value,
131 chashdatum * oldvalue)
132{
133 unsigned int func, indx;
134 chashiter * iter, * cell;
135 int r;
136
137 if (hash->count > hash->size * CHASH_MAXDEPTH) {
138 r = chash_resize(hash, (hash->count / CHASH_MAXDEPTH) * 2 + 1);
139 if (r < 0)
140 goto err;
141 }
142
143 func = chash_func(key->data, key->len);
144 indx = func % hash->size;
145
146 /* look for the key in existing cells */
147 iter = hash->cells[indx];
148 while (iter) {
149 if (iter->key.len == key->len && iter->func == func
150 && !memcmp(iter->key.data, key->data, key->len)) {
151 /* found, replacing entry */
152 if (hash->copyvalue) {
153 char * data;
154
155 data = chash_dup(value->data, value->len);
156 if (data == NULL)
157 goto err;
158
159 free(iter->value.data);
160 iter->value.data = data;
161 iter->value.len = value->len;
162 } else {
163 if (oldvalue != NULL) {
164 oldvalue->data = iter->value.data;
165 oldvalue->len = iter->value.len;
166 }
167 iter->value.data = value->data;
168 iter->value.len = value->len;
169 }
170 if (!hash->copykey)
171 iter->key.data = key->data;
172
173 if (oldvalue != NULL) {
174 oldvalue->data = value->data;
175 oldvalue->len = value->len;
176 }
177
178 return 0;
179 }
180 iter = iter->next;
181 }
182
183 if (oldvalue != NULL) {
184 oldvalue->data = NULL;
185 oldvalue->len = 0;
186 }
187
188 /* not found, adding entry */
189 cell = (struct chashcell *) malloc(sizeof(struct chashcell));
190 if (cell == NULL)
191 goto err;
192
193 if (hash->copykey) {
194 cell->key.data = chash_dup(key->data, key->len);
195 if (cell->key.data == NULL)
196 goto free;
197 }
198 else
199 cell->key.data = key->data;
200
201 cell->key.len = key->len;
202 if (hash->copyvalue) {
203 cell->value.data = chash_dup(value->data, value->len);
204 if (cell->value.data == NULL)
205 goto free_key_data;
206 }
207 else
208 cell->value.data = value->data;
209
210 cell->value.len = value->len;
211 cell->func = func;
212 cell->next = hash->cells[indx];
213 hash->cells[indx] = cell;
214 hash->count++;
215
216 return 0;
217
218 free_key_data:
219 if (hash->copykey)
220 free(cell->key.data);
221 free:
222 free(cell);
223 err:
224 return -1;
225}
226
227int chash_delete(chash * hash, chashdatum * key, chashdatum * oldvalue)
228{
229 /* chashdatum result = { NULL, TRUE }; */
230 unsigned int func, indx;
231 chashiter * iter, * old;
232
233 /*
234 if (!keylen)
235 keylen = strlen(key) + 1;
236 */
237
238 func = chash_func(key->data, key->len);
239 indx = func % hash->size;
240
241 /* look for the key in existing cells */
242 old = NULL;
243 iter = hash->cells[indx];
244 while (iter) {
245 if (iter->key.len == key->len && iter->func == func
246 && !memcmp(iter->key.data, key->data, key->len)) {
247 /* found, deleting */
248 if (old)
249 old->next = iter->next;
250 else
251 hash->cells[indx] = iter->next;
252 if (hash->copykey)
253 free(iter->key.data);
254 if (hash->copyvalue)
255 free(iter->value.data);
256 else {
257 if (oldvalue != NULL) {
258 oldvalue->data = iter->value.data;
259 oldvalue->len = iter->value.len;
260 }
261 }
262 free(iter);
263 hash->count--;
264 return 0;
265 }
266 old = iter;
267 iter = iter->next;
268 }
269
270 return -1; /* not found */
271}
272
273void chash_free(chash * hash) {
274 unsigned int indx;
275 chashiter * iter, * next;
276
277 /* browse the hash table */
278 for(indx = 0; indx < hash->size; indx++) {
279 iter = hash->cells[indx];
280 while (iter) {
281 next = iter->next;
282 if (hash->copykey)
283 free(iter->key.data);
284 if (hash->copyvalue)
285 free(iter->value.data);
286 free(iter);
287 iter = next;
288 }
289 }
290 free(hash->cells);
291 free(hash);
292}
293
294void chash_clear(chash * hash) {
295 unsigned int indx;
296 chashiter * iter, * next;
297
298 /* browse the hash table */
299 for(indx = 0; indx < hash->size; indx++) {
300 iter = hash->cells[indx];
301 while (iter) {
302 next = iter->next;
303 if (hash->copykey)
304 free(iter->key.data);
305 if (hash->copyvalue)
306 free(iter->value.data);
307 free(iter);
308 iter = next;
309 }
310 }
311 memset(hash->cells, 0, hash->size * sizeof(* hash->cells));
312 hash->count = 0;
313}
314
315chashiter * chash_begin(chash * hash) {
316 chashiter * iter;
317 unsigned int indx = 0;
318
319 iter = hash->cells[0];
320 while(!iter) {
321 indx++;
322 if (indx >= hash->size)
323 return NULL;
324 iter = hash->cells[indx];
325 }
326 return iter;
327}
328
329chashiter * chash_next(chash * hash, chashiter * iter) {
330 unsigned int indx;
331
332 if (!iter)
333 return NULL;
334
335 indx = iter->func % hash->size;
336 iter = iter->next;
337
338 while(!iter) {
339 indx++;
340 if (indx >= hash->size)
341 return NULL;
342 iter = hash->cells[indx];
343 }
344 return iter;
345}
346
347int chash_resize(chash * hash, unsigned int size)
348{
349 struct chashcell ** cells;
350 unsigned int indx, nindx;
351 chashiter * iter, * next;
352
353 if (hash->size == size)
354 return 0;
355
356 cells = (struct chashcell **) calloc(size, sizeof(struct chashcell *));
357 if (!cells)
358 return -1;
359
360 /* browse initial hash and copy items in second hash */
361 for(indx = 0; indx < hash->size; indx++) {
362 iter = hash->cells[indx];
363 while (iter) {
364 next = iter->next;
365 nindx = iter->func % size;
366 iter->next = cells[nindx];
367 cells[nindx] = iter;
368 iter = next;
369 }
370 }
371 free(hash->cells);
372 hash->size = size;
373 hash->cells = cells;
374
375 return 0;
376}
377
378#ifdef NO_MACROS
379int chash_count(chash * hash) {
380 return hash->count;
381}
382
383int chash_size(chash * hash) {
384 return hash->size;
385}
386
387void chash_value(chashiter * iter, chashdatum * result) {
388 * result = iter->value;
389}
390
391void chash_key(chashiter * iter, chashdatum * result) {
392 * result = iter->key;
393}
394#endif
diff --git a/libetpan/src/data-types/chash.h b/libetpan/src/data-types/chash.h
new file mode 100644
index 0000000..a9a61e5
--- a/dev/null
+++ b/libetpan/src/data-types/chash.h
@@ -0,0 +1,165 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * chash - Implements generic hash tables.
5 *
6 * Copyright (c) 1999-2005, Gaël Roualland <gael.roualland@iname.com>
7 * interface changes - 2005 - DINH Viet Hoa
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the libEtPan! project nor the names of its
19 * contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35/*
36 * $Id$
37 */
38
39#ifndef CHASH_H
40#define CHASH_H
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46typedef struct {
47 void * data;
48 unsigned int len;
49} chashdatum;
50
51struct chash {
52 unsigned int size;
53 unsigned int count;
54 int copyvalue;
55 int copykey;
56 struct chashcell ** cells;
57};
58
59typedef struct chash chash;
60
61struct chashcell {
62 unsigned int func;
63 chashdatum key;
64 chashdatum value;
65 struct chashcell * next;
66};
67
68typedef struct chashcell chashiter;
69
70#define CHASH_COPYNONE 0
71#define CHASH_COPYKEY 1
72#define CHASH_COPYVALUE 2
73#define CHASH_COPYALL (CHASH_COPYKEY | CHASH_COPYVALUE)
74
75#define CHASH_DEFAULTSIZE 13
76
77/* Allocates a new (empty) hash using this initial size and the given flags,
78 specifying which data should be copied in the hash.
79 CHASH_COPYNONE : Keys/Values are not copied.
80 CHASH_COPYKEY : Keys are dupped and freed as needed in the hash.
81 CHASH_COPYVALUE : Values are dupped and freed as needed in the hash.
82 CHASH_COPYALL : Both keys and values are dupped in the hash.
83 */
84chash * chash_new(unsigned int size, int flags);
85
86/* Frees a hash */
87void chash_free(chash * hash);
88
89/* Removes all elements from a hash */
90void chash_clear(chash * hash);
91
92/* Adds an entry in the hash table.
93 Length can be 0 if key/value are strings.
94 If an entry already exists for this key, it is replaced, and its value
95 is returned. Otherwise, the data pointer will be NULL and the length
96 field be set to TRUE or FALSe to indicate success or failure. */
97int chash_set(chash * hash,
98 chashdatum * key,
99 chashdatum * value,
100 chashdatum * oldvalue);
101
102/* Retrieves the data associated to the key if it is found in the hash table.
103 The data pointer and the length will be NULL if not found*/
104int chash_get(chash * hash,
105 chashdatum * key, chashdatum * result);
106
107/* Removes the entry associated to this key if it is found in the hash table,
108 and returns its contents if not dupped (otherwise, pointer will be NULL
109 and len TRUE). If entry is not found both pointer and len will be NULL. */
110int chash_delete(chash * hash,
111 chashdatum * key,
112 chashdatum * oldvalue);
113
114/* Resizes the hash table to the passed size. */
115int chash_resize(chash * hash, unsigned int size);
116
117/* Returns an iterator to the first non-empty entry of the hash table */
118chashiter * chash_begin(chash * hash);
119
120/* Returns the next non-empty entry of the hash table */
121chashiter * chash_next(chash * hash, chashiter * iter);
122
123/* Some of the following routines can be implemented as macros to
124 be faster. If you don't want it, define NO_MACROS */
125#ifdef NO_MACROS
126/* Returns the size of the hash table */
127unsigned int chash_size(chash * hash);
128
129/* Returns the number of entries in the hash table */
130unsigned int chash_count(chash * hash);
131
132/* Returns the key part of the entry pointed by the iterator */
133void chash_key(chashiter * iter, chashdatum * result);
134
135/* Returns the value part of the entry pointed by the iterator */
136void chash_value(chashiter * iter, chashdatum * result);
137
138#else
139static inline unsigned int chash_size(chash * hash)
140{
141 return hash->size;
142}
143
144static inline unsigned int chash_count(chash * hash)
145{
146 return hash->count;
147}
148
149static inline void chash_key(chashiter * iter, chashdatum * result)
150{
151 * result = iter->key;
152}
153
154static inline void chash_value(chashiter * iter, chashdatum * result)
155{
156 * result = iter->value;
157}
158
159#endif
160
161#ifdef __cplusplus
162}
163#endif
164
165#endif
diff --git a/libetpan/src/data-types/cinthash.c b/libetpan/src/data-types/cinthash.c
new file mode 100644
index 0000000..b59eb86
--- a/dev/null
+++ b/libetpan/src/data-types/cinthash.c
@@ -0,0 +1,248 @@
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$
34 */
35
36#include <stdlib.h>
37#include "cinthash.h"
38
39struct cinthash_list {
40 unsigned long hash;
41 void * data;
42 struct cinthash_list * next;
43};
44
45static struct cinthash_list HASH_LISTHEAD_NEW = { 0, NULL, NULL };
46
47static inline int hash_list_add(cinthash_t * table,
48 unsigned long hash, void * data)
49{
50 struct cinthash_list * ht;
51 int index;
52
53 index = hash % table->hashtable_size;
54
55 ht = malloc(sizeof(struct cinthash_list));
56 if (ht == NULL)
57 return -1;
58
59 ht->hash = hash;
60 ht->data = data;
61 ht->next = table->table[index].next;
62
63 table->table[index].next = ht;
64
65 return 0;
66}
67
68static inline void hash_list_free(struct cinthash_list * list)
69{
70 struct cinthash_list * cur;
71 struct cinthash_list * next;
72
73 next = list;
74 while (next != NULL) {
75 cur = next;
76 next = cur->next;
77 free(cur);
78 }
79}
80
81static inline int hash_list_remove(cinthash_t * table, unsigned long hash)
82{
83 struct cinthash_list * cur;
84 int index;
85
86 index = hash % table->hashtable_size;
87
88 for(cur = &table->table[index] ; cur->next != NULL ; cur = cur->next) {
89 if (cur->next->hash == hash) {
90 struct cinthash_list * hash_data;
91
92 hash_data = cur->next;
93 cur->next = cur->next->next;
94
95 free(hash_data);
96
97 return 0;
98 }
99 }
100
101 return -1;
102}
103
104static inline void * hash_list_find(cinthash_t * table, unsigned long hash)
105{
106 struct cinthash_list * cur;
107 int index;
108
109 index = hash % table->hashtable_size;
110
111 for(cur = table->table[index].next ; cur != NULL ; cur = cur->next) {
112 if (cur->hash == hash)
113 return cur->data;
114 }
115
116 return NULL;
117}
118
119cinthash_t * cinthash_new(unsigned long hashtable_size)
120{
121 cinthash_t * ht;
122 unsigned long i;
123
124 ht = malloc(sizeof(cinthash_t));
125 if (ht == NULL)
126 return NULL;
127
128 ht->table = malloc(sizeof(struct cinthash_list) * hashtable_size);
129 if (ht->table == NULL)
130 return NULL;
131
132 ht->hashtable_size = hashtable_size;
133 ht->count = 0;
134
135 for(i = 0 ; i < hashtable_size ; i++)
136 ht->table[i] = HASH_LISTHEAD_NEW;
137
138 return ht;
139}
140
141void cinthash_free(cinthash_t * table)
142{
143 unsigned long i;
144
145 for(i = 0 ; i < table->hashtable_size ; i++)
146 hash_list_free(table->table[i].next);
147
148 free(table->table);
149
150 free(table);
151}
152
153int cinthash_add(cinthash_t * table, unsigned long hash, void * data)
154{
155 int index;
156
157 index = hash % table->hashtable_size;
158
159 if (table->table[index].data == NULL) {
160 table->table[index].hash = hash;
161 table->table[index].data = data;
162 table->table[index].next = NULL;
163
164 table->count ++;
165
166 return 0;
167 }
168 else {
169 int r;
170
171 r = hash_list_add(table, hash, data);
172 if (r == -1)
173 return -1;
174
175 table->count ++;
176
177 return 0;
178 }
179}
180
181int cinthash_remove(cinthash_t * table, unsigned long hash)
182{
183 int index;
184
185 index = hash % table->hashtable_size;
186
187 if (table->table[index].hash == hash) {
188 table->table[index].hash = 0;
189 table->table[index].data = NULL;
190
191 table->count --;
192
193 return 0;
194 }
195 else {
196 int r;
197
198 r = hash_list_remove(table, hash);
199
200 table->count --;
201
202 return 0;
203 }
204}
205
206void * cinthash_find(cinthash_t * table, unsigned long hash)
207{
208 int index;
209
210 index = hash % table->hashtable_size;
211
212 if (table->table[index].hash == hash)
213 return table->table[index].data;
214
215 return hash_list_find(table, hash);
216}
217
218void cinthash_foreach_key(cinthash_t * table,
219 void (* func)(unsigned long, void *),
220 void * data)
221{
222 unsigned long index;
223 struct cinthash_list * cur;
224
225 for(index = 0 ; index < table->hashtable_size ; index ++) {
226 if (table->table[index].data != NULL) {
227 func(table->table[index].hash, data);
228 for(cur = table->table[index].next ; cur != NULL ; cur = cur->next)
229 func(cur->hash, data);
230 }
231 }
232}
233
234void cinthash_foreach_data(cinthash_t * table,
235 void (* func)(void *, void *),
236 void * data)
237{
238 unsigned long index;
239 struct cinthash_list * cur;
240
241 for(index = 0 ; index < table->hashtable_size ; index ++) {
242 if (table->table[index].data != NULL) {
243 func(table->table[index].data, data);
244 for(cur = table->table[index].next ; cur != NULL ; cur = cur->next)
245 func(cur->data, data);
246 }
247 }
248}
diff --git a/libetpan/src/data-types/cinthash.h b/libetpan/src/data-types/cinthash.h
new file mode 100644
index 0000000..7103d4f
--- a/dev/null
+++ b/libetpan/src/data-types/cinthash.h
@@ -0,0 +1,69 @@
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$
34 */
35
36#ifndef CINTHASH_H
37
38#define CINTHASH_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44typedef struct cinthash_t {
45 struct cinthash_list * table;
46 unsigned long hashtable_size ;
47 unsigned long count;
48} cinthash_t;
49
50cinthash_t * cinthash_new(unsigned long hashtable_size);
51void cinthash_free(cinthash_t * table);
52
53int cinthash_add(cinthash_t * table, unsigned long hash, void * data);
54int cinthash_remove(cinthash_t * table, unsigned long hash);
55void * cinthash_find(cinthash_t * table, unsigned long hash);
56
57void cinthash_foreach_key(cinthash_t * table,
58 void (* func)(unsigned long, void *),
59 void * data);
60
61void cinthash_foreach_data(cinthash_t * table,
62 void (* fun)(void *, void *),
63 void * data);
64
65#ifdef __cplusplus
66}
67#endif
68
69#endif
diff --git a/libetpan/src/data-types/clist.c b/libetpan/src/data-types/clist.c
new file mode 100644
index 0000000..0b216de
--- a/dev/null
+++ b/libetpan/src/data-types/clist.c
@@ -0,0 +1,265 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * clist - Implements simple generic double-linked pointer lists
5 *
6 * Copyright (c) 1999-2005, Gaël Roualland <gael.roualland@iname.com>
7 * interface changes - 2005 - DINH Viet Hoa
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the libEtPan! project nor the names of its
19 * contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35/*
36 * $Id$
37 */
38
39#include <stdlib.h>
40#include "clist.h"
41
42clist * clist_new() {
43 clist * lst;
44
45 lst = (clist *) malloc(sizeof(clist));
46 if (!lst) return NULL;
47
48 lst->first = lst->last = NULL;
49 lst->count = 0;
50
51 return lst;
52}
53
54void clist_free(clist * lst) {
55 clistcell * l1, * l2;
56
57 l1 = lst->first;
58 while (l1) {
59 l2 = l1->next;
60 free(l1);
61 l1 = l2;
62 }
63
64 free(lst);
65}
66
67#ifdef NO_MACROS
68int clist_isempty(clist * lst) {
69 return ((lst->first==lst->last) && (lst->last==NULL));
70}
71
72clistiter * clist_begin(clist * lst) {
73 return lst->first;
74}
75
76clistiter * clist_end(clist * lst) {
77 return lst->last;
78}
79
80clistiter * clist_next(clistiter * iter) {
81 if (iter)
82 return iter->next;
83 else
84 return NULL;
85}
86
87clistiter * clist_previous(clistiter * iter) {
88 if (iter)
89 return iter->previous;
90 else
91 return NULL;
92}
93
94void * clist_content(clistiter * iter) {
95 if (iter)
96 return iter->data;
97 else
98 return NULL;
99}
100
101int clist_count(clist * lst) {
102 return lst->count;
103}
104
105int clist_prepend(clist * lst, void * data) {
106 return clist_insert_before(lst, lst->first, data);
107}
108
109int clist_append(clist * lst, void * data) {
110 return clist_insert_after(lst, lst->last, data);
111}
112#endif
113
114int clist_insert_before(clist * lst, clistiter * iter, void * data) {
115 clistcell * c;
116
117 c = (clistcell *) malloc(sizeof(clistcell));
118 if (!c) return -1;
119
120 c->data = data;
121 lst->count++;
122
123 if (clist_isempty(lst)) {
124 c->previous = c->next = NULL;
125 lst->first = lst->last = c;
126 return 0;
127 }
128
129 if (!iter) {
130 c->previous = lst->last;
131 c->previous->next = c;
132 c->next = NULL;
133 lst->last = c;
134 return 0;
135 }
136
137 c->previous = iter->previous;
138 c->next = iter;
139 c->next->previous = c;
140 if (c->previous)
141 c->previous->next = c;
142 else
143 lst->first = c;
144
145 return 0;
146}
147
148int clist_insert_after(clist * lst, clistiter * iter, void * data) {
149 clistcell * c;
150
151 c = (clistcell *) malloc(sizeof(clistcell));
152 if (!c) return -1;
153
154 c->data = data;
155 lst->count++;
156
157 if (clist_isempty(lst)) {
158 c->previous = c->next = NULL;
159 lst->first = lst->last = c;
160 return 0;
161 }
162
163 if (!iter) {
164 c->previous = lst->last;
165 c->previous->next = c;
166 c->next = NULL;
167 lst->last = c;
168 return 0;
169 }
170
171 c->previous = iter;
172 c->next = iter->next;
173 if (c->next)
174 c->next->previous = c;
175 else
176 lst->last = c;
177 c->previous->next = c;
178
179 return 0;
180}
181
182clistiter * clist_delete(clist * lst, clistiter * iter) {
183 clistiter * ret;
184
185 if (!iter) return NULL;
186
187 if (iter->previous)
188 iter->previous->next = iter->next;
189 else
190 lst->first = iter->next;
191
192 if (iter->next) {
193 iter->next->previous = iter->previous;
194 ret = iter->next;
195 } else {
196 lst->last = iter->previous;
197 ret = NULL;
198 }
199
200 free(iter);
201 lst->count--;
202
203 return ret;
204}
205
206
207
208void clist_foreach(clist * lst, clist_func func, void * data)
209{
210 clistiter * cur;
211
212 for(cur = clist_begin(lst) ; cur != NULL ; cur = cur->next)
213 func(cur->data, data);
214}
215
216void clist_concat(clist * dest, clist * src)
217{
218 if (src->first == NULL) {
219 /* do nothing */
220 }
221 else if (dest->last == NULL) {
222 dest->first = src->first;
223 dest->last = src->last;
224 }
225 else {
226 dest->last->next = src->first;
227 src->first->previous = dest->last;
228 dest->last = src->last;
229 }
230
231 dest->count += src->count;
232 src->last = src->first = NULL;
233}
234
235static inline clistiter * internal_clist_nth(clist * lst, int index)
236{
237 clistiter * cur;
238
239 cur = clist_begin(lst);
240 while ((index > 0) && (cur != NULL)) {
241 cur = cur->next;
242 index --;
243 }
244
245 if (cur == NULL)
246 return NULL;
247
248 return cur;
249}
250
251void * clist_nth_data(clist * lst, int index)
252{
253 clistiter * cur;
254
255 cur = internal_clist_nth(lst, index);
256 if (cur == NULL)
257 return NULL;
258
259 return cur->data;
260}
261
262clistiter * clist_nth(clist * lst, int index)
263{
264 return internal_clist_nth(lst, index);
265}
diff --git a/libetpan/src/data-types/clist.h b/libetpan/src/data-types/clist.h
new file mode 100644
index 0000000..0daf1ed
--- a/dev/null
+++ b/libetpan/src/data-types/clist.h
@@ -0,0 +1,133 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * clist - Implements simple generic double-linked pointer lists
5 *
6 * Copyright (c) 1999-2005, Gaël Roualland <gael.roualland@iname.com>
7 * interface changes - 2005 - DINH Viet Hoa
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the libEtPan! project nor the names of its
19 * contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35/*
36 * $Id$
37 */
38
39#ifndef CLIST_H
40#define CLIST_H
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46typedef struct clistcell_s {
47 void * data;
48 struct clistcell_s * previous;
49 struct clistcell_s * next;
50} clistcell;
51
52struct clist_s {
53 clistcell * first;
54 clistcell * last;
55 int count;
56};
57
58typedef struct clist_s clist;
59typedef clistcell clistiter;
60
61/* Allocate a new pointer list */
62clist * clist_new();
63
64/* Destroys a list. Data pointed by data pointers is NOT freed. */
65void clist_free(clist *);
66
67/* Some of the following routines can be implemented as macros to
68 be faster. If you don't want it, define NO_MACROS */
69#ifdef NO_MACROS
70
71/* Returns TRUE if list is empty */
72int clist_isempty(clist *);
73
74/* Returns the number of elements in the list */
75int clist_count(clist *);
76
77/* Returns an iterator to the first element of the list */
78clistiter * clist_begin(clist *);
79
80/* Returns an iterator to the last element of the list */
81clistiter * clist_end(clist *);
82
83/* Returns an iterator to the next element of the list */
84clistiter * clist_next(clistiter *);
85
86/* Returns an iterator to the previous element of the list */
87clistiter * clist_previous(clistiter *);
88
89/* Returns the data pointer of this element of the list */
90void* clist_content(clistiter *);
91
92/* Inserts this data pointer at the beginning of the list */
93int clist_prepend(clist *, void *);
94
95/* Inserts this data pointer at the end of the list */
96int clist_append(clist *, void *);
97#else
98#define clist_isempty(lst) ((lst->first==lst->last) && (lst->last==NULL))
99#define clist_count(lst) (lst->count)
100#define clist_begin(lst) (lst->first)
101#define clist_end(lst) (lst->last)
102#define clist_next(iter) (iter ? iter->next : NULL)
103#define clist_previous(iter) (iter ? iter->previous : NULL)
104#define clist_content(iter) (iter ? iter->data : NULL)
105#define clist_prepend(lst, data) (clist_insert_before(lst, lst->first, data))
106#define clist_append(lst, data) (clist_insert_after(lst, lst->last, data))
107#endif
108
109/* Inserts this data pointer before the element pointed by the iterator */
110int clist_insert_before(clist *, clistiter *, void *);
111
112/* Inserts this data pointer after the element pointed by the iterator */
113int clist_insert_after(clist *, clistiter *, void *);
114
115/* Deletes the element pointed by the iterator.
116 Returns an iterator to the next element. */
117clistiter * clist_delete(clist *, clistiter *);
118
119typedef void (* clist_func)(void *, void *);
120
121void clist_foreach(clist * lst, clist_func func, void * data);
122
123void clist_concat(clist * dest, clist * src);
124
125void * clist_nth_data(clist * lst, int index);
126
127clistiter * clist_nth(clist * lst, int index);
128
129#ifdef __cplusplus
130}
131#endif
132
133#endif
diff --git a/libetpan/src/data-types/connect.c b/libetpan/src/data-types/connect.c
new file mode 100644
index 0000000..bd8da0e
--- a/dev/null
+++ b/libetpan/src/data-types/connect.c
@@ -0,0 +1,86 @@
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$
34 */
35
36#include "connect.h"
37
38#include <sys/types.h>
39#include <string.h>
40#include <netdb.h>
41#include <netinet/in.h>
42#include <sys/socket.h>
43#include <unistd.h>
44
45uint16_t mail_get_service_port(const char * name, char * protocol)
46{
47 struct servent * service;
48
49 service = getservbyname(name, protocol);
50
51 if (service == NULL)
52 return 0;
53
54 return service->s_port;
55}
56
57int mail_tcp_connect(const char * server, uint16_t port)
58{
59 struct hostent * remotehost;
60 struct sockaddr_in sa;
61 int s;
62 int r;
63
64 s = socket(PF_INET, SOCK_STREAM, 0);
65 if (s == -1)
66 goto err;
67
68 remotehost = gethostbyname(server);
69 if (remotehost == NULL)
70 goto close_socket;
71
72 sa.sin_family = AF_INET;
73 sa.sin_port = htons(port);
74 memcpy(&sa.sin_addr, remotehost->h_addr, remotehost->h_length);
75
76 r = connect(s, (struct sockaddr *) &sa, sizeof(struct sockaddr_in));
77 if (r == -1)
78 goto close_socket;
79
80 return s;
81
82 close_socket:
83 close(s);
84 err:
85 return -1;
86}
diff --git a/libetpan/src/data-types/connect.h b/libetpan/src/data-types/connect.h
new file mode 100644
index 0000000..d8cf1ab
--- a/dev/null
+++ b/libetpan/src/data-types/connect.h
@@ -0,0 +1,54 @@
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$
34 */
35
36#ifndef CONNECT_H
37
38#define CONNECT_H
39
40#include <inttypes.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46uint16_t mail_get_service_port(const char * name, char * protocol);
47int mail_tcp_connect(const char * server, uint16_t port);
48
49#ifdef __cplusplus
50}
51#endif
52
53#endif
54
diff --git a/libetpan/src/data-types/hmac-md5.h b/libetpan/src/data-types/hmac-md5.h
new file mode 100644
index 0000000..87a7d9f
--- a/dev/null
+++ b/libetpan/src/data-types/hmac-md5.h
@@ -0,0 +1,94 @@
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/* hmac-md5.h -- HMAC_MD5 functions
33 */
34
35/*
36 * $Id$
37 */
38
39#ifndef HMAC_MD5_H
40#define HMAC_MD5_H 1
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46#define HMAC_MD5_SIZE 16
47
48/* intermediate MD5 context */
49typedef struct HMAC_MD5_CTX_s {
50 MD5_CTX ictx, octx;
51} HMAC_MD5_CTX;
52
53/* intermediate HMAC state
54 * values stored in network byte order (Big Endian)
55 */
56typedef struct HMAC_MD5_STATE_s {
57 UINT4 istate[4];
58 UINT4 ostate[4];
59} HMAC_MD5_STATE;
60
61/* One step hmac computation
62 *
63 * digest may be same as text or key
64 */
65void hmac_md5(const unsigned char *text, int text_len,
66 const unsigned char *key, int key_len,
67 unsigned char digest[HMAC_MD5_SIZE]);
68
69/* create context from key
70 */
71void hmac_md5_init(HMAC_MD5_CTX *hmac,
72 const unsigned char *key, int key_len);
73
74/* precalculate intermediate state from key
75 */
76void hmac_md5_precalc(HMAC_MD5_STATE *hmac,
77 const unsigned char *key, int key_len);
78
79/* initialize context from intermediate state
80 */
81void hmac_md5_import(HMAC_MD5_CTX *hmac, HMAC_MD5_STATE *state);
82
83#define hmac_md5_update(hmac, text, text_len) MD5Update(&(hmac)->ictx, (text), (text_len))
84
85/* finish hmac from intermediate result. Intermediate result is zeroed.
86 */
87void hmac_md5_final(unsigned char digest[HMAC_MD5_SIZE],
88 HMAC_MD5_CTX *hmac);
89
90#ifdef __cplusplus
91}
92#endif
93
94#endif /* HMAC_MD5_H */
diff --git a/libetpan/src/data-types/mail.h b/libetpan/src/data-types/mail.h
new file mode 100644
index 0000000..447aaf7
--- a/dev/null
+++ b/libetpan/src/data-types/mail.h
@@ -0,0 +1,56 @@
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$
34 */
35
36#ifndef MAIL_H
37
38#define MAIL_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#ifndef TRUE
45#define TRUE 1
46#endif
47
48#ifndef FALSE
49#define FALSE 0
50#endif
51
52#ifdef __cplusplus
53}
54#endif
55
56#endif
diff --git a/libetpan/src/data-types/mail_cache_db.c b/libetpan/src/data-types/mail_cache_db.c
new file mode 100644
index 0000000..0b73775
--- a/dev/null
+++ b/libetpan/src/data-types/mail_cache_db.c
@@ -0,0 +1,403 @@
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$
34 */
35
36#include "mail_cache_db.h"
37
38#include <sys/types.h>
39#include <sys/stat.h>
40#include <fcntl.h>
41#include <stdlib.h>
42#include <string.h>
43
44#ifndef CONFIG_H
45#define CONFIG_H
46#include "config.h"
47#endif
48
49#include "libetpan-config.h"
50
51#include "maillock.h"
52
53#if DBVERS >= 1
54#include <db.h>
55#endif
56
57#if DBVERS >= 1
58static struct mail_cache_db * mail_cache_db_new(DB * db)
59{
60 struct mail_cache_db * cache_db;
61
62 cache_db = malloc(sizeof(* cache_db));
63 if (cache_db == NULL)
64 return NULL;
65 cache_db->internal_database = db;
66
67 return cache_db;
68}
69
70static void mail_cache_db_free(struct mail_cache_db * cache_db)
71{
72 free(cache_db);
73}
74#endif
75
76int mail_cache_db_open(const char * filename,
77 struct mail_cache_db ** pcache_db)
78{
79#if DBVERS >= 1
80 DB * dbp;
81 int r;
82 struct mail_cache_db * cache_db;
83
84#if DB_VERSION_MAJOR >= 3
85 r = db_create(&dbp, NULL, 0);
86 if (r != 0)
87 goto err;
88
89#if (DB_VERSION_MAJOR >= 4) && ((DB_VERSION_MAJOR > 4) || (DB_VERSION_MINOR >= 1))
90 r = dbp->open(dbp, NULL, filename, NULL, DB_BTREE, DB_CREATE,
91 S_IRUSR | S_IWUSR);
92#else
93 r = dbp->open(dbp, filename, NULL, DB_BTREE, DB_CREATE, S_IRUSR | S_IWUSR);
94#endif
95 if (r != 0)
96 goto close_db;
97#else
98#if DBVERS > 1
99 r = db_open(filename, DB_BTREE, DB_CREATE, S_IRUSR | S_IWUSR,
100 NULL, NULL, &dbp);
101 if (r != 0)
102 goto err;
103#elif DBVERS == 1
104 dbp = dbopen(filename, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, DB_BTREE, NULL);
105 if (dbp == NULL)
106 goto err;
107#else
108 goto err;
109#endif
110#endif
111
112 cache_db = mail_cache_db_new(dbp);
113 if (cache_db == NULL)
114 goto close_db;
115
116 * pcache_db = cache_db;
117
118 return 0;
119
120 close_db:
121#if DBVERS > 1
122 dbp->close(dbp, 0);
123#elif DBVERS == 1
124 dbp->close(dbp);
125#endif
126 err:
127 return -1;
128#else
129 return -1;
130#endif
131}
132
133void mail_cache_db_close(struct mail_cache_db * cache_db)
134{
135#if DBVERS >= 1
136 DB * dbp;
137
138 dbp = cache_db->internal_database;
139
140#if DBVERS > 1
141 dbp->close(cache_db->internal_database, 0);
142#elif DBVERS == 1
143 dbp->close(cache_db->internal_database);
144#endif
145
146 mail_cache_db_free(cache_db);
147#endif
148}
149
150int mail_cache_db_open_lock(const char * filename,
151 struct mail_cache_db ** pcache_db)
152{
153 int r;
154 struct mail_cache_db * cache_db;
155
156 r = maillock_write_lock(filename, -1);
157 if (r < 0)
158 goto err;
159
160 r = mail_cache_db_open(filename, &cache_db);
161 if (r < 0)
162 goto unlock;
163
164 * pcache_db = cache_db;
165
166 return 0;
167
168 unlock:
169 maillock_write_unlock(filename, -1);
170 err:
171 return -1;
172}
173
174void mail_cache_db_close_unlock(const char * filename,
175 struct mail_cache_db * cache_db)
176{
177 maillock_write_unlock(filename, -1);
178 mail_cache_db_close(cache_db);
179}
180
181
182int mail_cache_db_put(struct mail_cache_db * cache_db,
183 const void * key, size_t key_len, const void * value, size_t value_len)
184{
185#if DBVERS >= 1
186 int r;
187 DBT db_key;
188 DBT db_data;
189 DB * dbp;
190
191 dbp = cache_db->internal_database;
192
193 memset(&db_key, 0, sizeof(db_key));
194 memset(&db_data, 0, sizeof(db_data));
195 db_key.data = (void *) key;
196 db_key.size = key_len;
197 db_data.data = (void *) value;
198 db_data.size = value_len;
199
200#if DBVERS > 1
201 r = dbp->put(dbp, NULL, &db_key, &db_data, 0);
202#elif DBVERS == 1
203 r = dbp->put(dbp, &db_key, &db_data, 0);
204#else
205 r = -1;
206#endif
207
208 return r;
209#else
210 return -1;
211#endif
212}
213
214int mail_cache_db_get(struct mail_cache_db * cache_db,
215 const void * key, size_t key_len, void ** pvalue, size_t * pvalue_len)
216{
217#if DBVERS >= 1
218 int r;
219 DBT db_key;
220 DBT db_data;
221 DB * dbp;
222
223 dbp = cache_db->internal_database;
224
225 memset(&db_key, 0, sizeof(db_key));
226 memset(&db_data, 0, sizeof(db_data));
227 db_key.data = (void *) key;
228 db_key.size = key_len;
229
230#if DBVERS > 1
231 r = dbp->get(dbp, NULL, &db_key, &db_data, 0);
232#elif DBVERS == 1
233 r = dbp->get(dbp, &db_key, &db_data, 0);
234#else
235 r = -1;
236#endif
237
238 if (r != 0)
239 return r;
240
241 * pvalue = db_data.data;
242 * pvalue_len = db_data.size;
243
244 return 0;
245#else
246 return -1;
247#endif
248}
249
250int mail_cache_db_del(struct mail_cache_db * cache_db,
251 const void * key, size_t key_len)
252{
253#if DBVERS >= 1
254 int r;
255 DBT db_key;
256 DB * dbp;
257
258 dbp = cache_db->internal_database;
259
260 memset(&db_key, 0, sizeof(db_key));
261 db_key.data = (void *) key;
262 db_key.size = key_len;
263
264#if DBVERS > 1
265 r = dbp->del(dbp, NULL, &db_key, 0);
266#elif DBVERS == 1
267 r = dbp->del(dbp, &db_key, 0);
268#else
269 r = -1;
270#endif
271
272 return r;
273#else
274 return -1;
275#endif
276}
277
278#if DBVERS > 1
279int mail_cache_db_clean_up(struct mail_cache_db * cache_db,
280 chash * exist)
281{
282 DB * dbp;
283 int r;
284 DBC * dbcp;
285 DBT db_key;
286 DBT db_data;
287
288 dbp = cache_db->internal_database;
289
290 r = dbp->cursor(dbp, NULL, &dbcp, 0);
291 if (r != 0)
292 return r;
293
294 memset(&db_key, 0, sizeof(db_key));
295 memset(&db_data, 0, sizeof(db_data));
296
297 while (1) {
298 chashdatum hash_key;
299 chashdatum hash_data;
300
301 r = dbcp->c_get(dbcp, &db_key, &db_data, DB_NEXT);
302 if (r != 0)
303 break;
304
305 hash_key.data = db_key.data;
306 hash_key.len = db_key.size;
307
308 r = chash_get(exist, &hash_key, &hash_data);
309 if (r < 0) {
310 r = dbcp->c_del(dbcp, 0);
311 if (r != 0)
312 return r;
313 }
314 }
315
316 r = dbcp->c_close(dbcp);
317 if (r != 0)
318 return r;
319
320 return 0;
321}
322#elif DBVERS == 1
323int mail_cache_db_clean_up(struct mail_cache_db * cache_db,
324 chash * exist)
325{
326 DB * dbp;
327 int r;
328 DBT db_key;
329 DBT db_data;
330
331 dbp = cache_db->internal_database;
332
333 r = dbp->seq(dbp, &db_key, &db_data, R_FIRST);
334 if (r == -1)
335 return r;
336
337 while (r == 0) {
338 chashdatum hash_key;
339 chashdatum hash_data;
340
341 hash_key.data = db_key.data;
342 hash_key.len = db_key.size;
343
344 r = chash_get(exist, &hash_key, &hash_data);
345 if (r < 0) {
346 r = dbp->del(dbp, &db_key, 0);
347 if (r != 0)
348 return r;
349 }
350
351 r = dbp->seq(dbp, &db_key, &db_data, R_NEXT);
352 if (r == -1)
353 return r;
354 }
355
356 return 0;
357}
358#else
359int mail_cache_db_clean_up(struct mail_cache_db * cache_db,
360 chash * exist)
361{
362 return -1;
363}
364#endif
365
366int mail_cache_db_get_size(struct mail_cache_db * cache_db,
367 const void * key, size_t key_len, size_t * pvalue_len)
368{
369#if DBVERS >= 1
370 int r;
371 DBT db_key;
372 DBT db_data;
373 DB * dbp;
374
375 dbp = cache_db->internal_database;
376
377 memset(&db_key, 0, sizeof(db_key));
378 memset(&db_data, 0, sizeof(db_data));
379 db_key.data = (void *) key;
380 db_key.size = key_len;
381#if DBVERS > 1
382 db_data.flags = DB_DBT_USERMEM;
383 db_data.ulen = 0;
384#endif
385
386#if DBVERS > 1
387 r = dbp->get(dbp, NULL, &db_key, &db_data, 0);
388#elif DBVERS == 1
389 r = dbp->get(dbp, &db_key, &db_data, 0);
390#else
391 r = -1;
392#endif
393
394 if (r != 0)
395 return r;
396
397 * pvalue_len = db_data.size;
398
399 return 0;
400#else
401 return -1;
402#endif
403}
diff --git a/libetpan/src/data-types/mail_cache_db.h b/libetpan/src/data-types/mail_cache_db.h
new file mode 100644
index 0000000..9ce915c
--- a/dev/null
+++ b/libetpan/src/data-types/mail_cache_db.h
@@ -0,0 +1,148 @@
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$
34 */
35
36#ifndef MAIL_CACHE_DB_H
37
38#define MAIL_CACHE_DB_H
39
40#include <sys/types.h>
41#include "mail_cache_db_types.h"
42#include "chash.h"
43
44#ifdef __cplusplus
45extern "C" {
46#endif
47
48/*
49 this module will handle a database "f(key) -> value" in a file
50
51 berkeley DB or other can be used for implementation of low-level file.
52*/
53
54/*
55 mail_cache_db_open()
56
57 This function opens the file "filename".
58 The pointer return in pcache_db should be used for further references
59 to the database.
60*/
61
62int mail_cache_db_open(const char * filename,
63 struct mail_cache_db ** pcache_db);
64
65/*
66 mail_cache_db_close()
67
68 This function closes the opened database.
69 The pointer cannot be used later.
70*/
71
72void mail_cache_db_close(struct mail_cache_db * cache_db);
73
74/*
75 mail_cache_db_open_lock()
76
77 This function opens and locks the file "filename".
78 The pointer return in pcache_db should be used for further references
79 to the database.
80*/
81
82int mail_cache_db_open_lock(const char * filename,
83 struct mail_cache_db ** pcache_db);
84
85/*
86 mail_cache_db_open_unlock()
87
88 This function closes and unlocks the opened database.
89 The pointer cannot be used later.
90*/
91
92void mail_cache_db_close_unlock(const char * filename,
93 struct mail_cache_db * cache_db);
94
95/*
96 mail_cache_db_put()
97
98 This function will store a given key and value in the database.
99*/
100
101int mail_cache_db_put(struct mail_cache_db * cache_db,
102 const void * key, size_t key_len, const void * value, size_t value_len);
103
104/*
105 mail_cache_db_get()
106
107 This function will retrieve the value corresponding to a given key
108 from the database.
109*/
110
111int mail_cache_db_get(struct mail_cache_db * cache_db,
112 const void * key, size_t key_len, void ** pvalue, size_t * pvalue_len);
113
114/*
115 mail_cache_db_get_size()
116
117 This function will retrieve the size of the value corresponding
118 to a given key from the database.
119*/
120
121int mail_cache_db_get_size(struct mail_cache_db * cache_db,
122 const void * key, size_t key_len, size_t * pvalue_len);
123
124/*
125 mail_cache_db_del()
126
127 This function will delete the given key and the corresponding value
128 from the database.
129*/
130
131int mail_cache_db_del(struct mail_cache_db * cache_db,
132 const void * key, size_t key_len);
133
134/*
135 mail_cache_clean_up()
136
137 This function will delete the key all the key/value pairs of the
138 database file which key does not exist in the given hash.
139*/
140
141int mail_cache_db_clean_up(struct mail_cache_db * cache_db,
142 chash * exist);
143
144#ifdef __cplusplus
145}
146#endif
147
148#endif
diff --git a/libetpan/src/data-types/mail_cache_db_types.h b/libetpan/src/data-types/mail_cache_db_types.h
new file mode 100644
index 0000000..aff77e5
--- a/dev/null
+++ b/libetpan/src/data-types/mail_cache_db_types.h
@@ -0,0 +1,52 @@
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$
34 */
35
36#ifndef MAIL_CACHE_DB_TYPES_H
37
38#define MAIL_CACHE_DB_TYPES_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44struct mail_cache_db {
45 void * internal_database;
46};
47
48#ifdef __cplusplus
49}
50#endif
51
52#endif
diff --git a/libetpan/src/data-types/maillock.c b/libetpan/src/data-types/maillock.c
new file mode 100644
index 0000000..b1741d0
--- a/dev/null
+++ b/libetpan/src/data-types/maillock.c
@@ -0,0 +1,301 @@
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$
34 */
35
36#include "maillock.h"
37
38#include "libetpan-config.h"
39
40#include <sys/types.h>
41#include <sys/stat.h>
42#include <fcntl.h>
43#include <unistd.h>
44#include <stdio.h>
45#include <time.h>
46#include <string.h>
47#include "config.h"
48
49#ifdef HAVE_LIBLOCKFILE
50#include <lockfile.h>
51#endif
52
53/* ********************************************************************** */
54
55/* lock primitives */
56
57/* the lock code is modified from the dot lock file code from mail.local.c */
58
59/*
60 SENDMAIL LICENSE
61
62The following license terms and conditions apply, unless a different
63license is obtained from Sendmail, Inc., 6425 Christie Ave, Fourth Floor,
64Emeryville, CA 94608, or by electronic mail at license@sendmail.com.
65
66License Terms:
67
68Use, Modification and Redistribution (including distribution of any
69modified or derived work) in source and binary forms is permitted only if
70each of the following conditions is met:
71
721. Redistributions qualify as "freeware" or "Open Source Software" under
73 one of the following terms:
74
75 (a) Redistributions are made at no charge beyond the reasonable cost of
76 materials and delivery.
77
78 (b) Redistributions are accompanied by a copy of the Source Code or by an
79 irrevocable offer to provide a copy of the Source Code for up to three
80 years at the cost of materials and delivery. Such redistributions
81 must allow further use, modification, and redistribution of the Source
82 Code under substantially the same terms as this license. For the
83 purposes of redistribution "Source Code" means the complete compilable
84 and linkable source code of sendmail including all modifications.
85
862. Redistributions of source code must retain the copyright notices as they
87 appear in each source code file, these license terms, and the
88 disclaimer/limitation of liability set forth as paragraph 6 below.
89
903. Redistributions in binary form must reproduce the Copyright Notice,
91 these license terms, and the disclaimer/limitation of liability set
92 forth as paragraph 6 below, in the documentation and/or other materials
93 provided with the distribution. For the purposes of binary distribution
94 the "Copyright Notice" refers to the following language:
95 "Copyright (c) 1998-2002 Sendmail, Inc. All rights reserved."
96
974. Neither the name of Sendmail, Inc. nor the University of California nor
98 the names of their contributors may be used to endorse or promote
99 products derived from this software without specific prior written
100 permission. The name "sendmail" is a trademark of Sendmail, Inc.
101
1025. All redistributions must comply with the conditions imposed by the
103 University of California on certain embedded code, whose copyright
104 notice and conditions for redistribution are as follows:
105
106 (a) Copyright (c) 1988, 1993 The Regents of the University of
107 California. All rights reserved.
108
109 (b) Redistribution and use in source and binary forms, with or without
110 modification, are permitted provided that the following conditions
111 are met:
112
113 (i) Redistributions of source code must retain the above copyright
114 notice, this list of conditions and the following disclaimer.
115
116 (ii) Redistributions in binary form must reproduce the above
117 copyright notice, this list of conditions and the following
118 disclaimer in the documentation and/or other materials provided
119 with the distribution.
120
121 (iii) Neither the name of the University nor the names of its
122 contributors may be used to endorse or promote products derived
123 from this software without specific prior written permission.
124
1256. Disclaimer/Limitation of Liability: THIS SOFTWARE IS PROVIDED BY
126 SENDMAIL, INC. AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
127 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
128 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
129 NO EVENT SHALL SENDMAIL, INC., THE REGENTS OF THE UNIVERSITY OF
130 CALIFORNIA OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
131 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
132 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
133 USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
134 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
135 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
136 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
137*/
138
139/*
140 TODO : lock, prefer fcntl() over flock()
141 AND use dotlock code above
142*/
143
144 #define LOCKTO_RM 300/* timeout for stale lockfile removal */
145 #define LOCKTO_GLOB 400/* global timeout for lockfile creation */
146
147static int lock_common(const char * filename, int fd, short locktype)
148{
149 char lockfilename[PATH_MAX];
150 struct flock lock;
151 /* dot lock file */
152 int statfailed = 0;
153 time_t start;
154 int r;
155 int res;
156
157 /* dot lock file */
158
159 if (strlen(filename) + 6 > PATH_MAX) {
160 res = -1;
161 goto err;
162 }
163
164 snprintf(lockfilename, PATH_MAX, "%s.lock", filename);
165
166#ifdef HAVE_LIBLOCKFILE
167 return lockfile_create(lockfilename, LOCKTO_GLOB, 0);
168#else
169
170 lock.l_start = 0;
171 lock.l_len = 0;
172 lock.l_pid = getpid();
173 lock.l_type = locktype;
174 lock.l_whence = SEEK_SET;
175
176 r = fcntl(fd, F_SETLKW, &lock);
177 if (r < 0) {
178 /* WARNING POSIX lock could not be applied */
179 }
180
181 time(&start);
182 while (1) {
183 int fd;
184 struct stat st;
185 time_t now;
186
187 /* global timeout */
188 time(&now);
189 if (now > start + LOCKTO_GLOB) {
190 res = -1;
191 goto unlock;
192 }
193
194 fd = open(lockfilename, O_WRONLY|O_EXCL|O_CREAT, 0);
195 if (fd >= 0) {
196 /* defeat lock checking programs which test pid */
197 write(fd, "0", 2);
198 close(fd);
199 break;
200 }
201
202 /* libEtPan! - adds a delay of 5 seconds between each tries */
203 sleep(5);
204
205 if (stat(lockfilename, &st) < 0) {
206 if (statfailed++ > 5) {
207 res = -1;
208 goto unlock;
209 }
210 continue;
211 }
212 statfailed = 0;
213 time(&now);
214
215 if (now < st.st_ctime + LOCKTO_RM)
216 continue;
217
218 /* try to remove stale lockfile */
219 if (unlink(lockfilename) < 0) {
220 res = -1;
221 goto unlock;
222 }
223
224 /*
225 libEtPan! - removes this delay of 5 seconds,
226 maybe it was misplaced ?
227 */
228#if 0
229 sleep(5);
230#endif
231 }
232
233 return 0;
234
235 unlock:
236 lock.l_start = 0;
237 lock.l_len = 0;
238 lock.l_pid = getpid();
239 lock.l_type = F_UNLCK;
240 lock.l_whence = SEEK_SET;
241
242 r = fcntl(fd, F_SETLK, &lock);
243 if (r < 0) {
244 /* WARNING POSIX lock could not be applied */
245 }
246#endif
247 err:
248 return res;
249}
250
251static int unlock_common(const char * filename, int fd)
252{
253 char lockfilename[PATH_MAX];
254 struct flock lock;
255 int r;
256
257 if (strlen(filename) + 6 > PATH_MAX)
258 return -1;
259
260 snprintf(lockfilename, PATH_MAX, "%s.lock", filename);
261
262#ifdef HAVE_LIBLOCKFILE
263 return lockfile_remove(lockfilename);
264#else
265
266 unlink(lockfilename);
267
268 lock.l_start = 0;
269 lock.l_len = 0;
270 lock.l_pid = getpid();
271 lock.l_type = F_UNLCK;
272 lock.l_whence = SEEK_SET;
273
274 r = fcntl(fd, F_SETLK, &lock);
275 if (r < 0) {
276 /* WARNING POSIX lock could not be applied */
277 }
278
279 return 0;
280#endif
281}
282
283int maillock_read_lock(const char * filename, int fd)
284{
285 return lock_common(filename, fd, F_RDLCK);
286}
287
288int maillock_read_unlock(const char * filename, int fd)
289{
290 return unlock_common(filename, fd);
291}
292
293int maillock_write_lock(const char * filename, int fd)
294{
295 return lock_common(filename, fd, F_WRLCK);
296}
297
298int maillock_write_unlock(const char * filename, int fd)
299{
300 return unlock_common(filename, fd);
301}
diff --git a/libetpan/src/data-types/maillock.h b/libetpan/src/data-types/maillock.h
new file mode 100644
index 0000000..8d166c6
--- a/dev/null
+++ b/libetpan/src/data-types/maillock.h
@@ -0,0 +1,53 @@
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$
34 */
35
36#ifndef MAILLOCK_H
37
38#define MAILLOCK_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44int maillock_read_lock(const char * filename, int fd);
45int maillock_read_unlock(const char * filename, int fd);
46int maillock_write_lock(const char * filename, int fd);
47int maillock_write_unlock(const char * filename, int fd);
48
49#ifdef __cplusplus
50}
51#endif
52
53#endif
diff --git a/libetpan/src/data-types/mailsem.c b/libetpan/src/data-types/mailsem.c
new file mode 100644
index 0000000..383d953
--- a/dev/null
+++ b/libetpan/src/data-types/mailsem.c
@@ -0,0 +1,114 @@
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$
34 */
35
36#include "mailsem.h"
37#include <semaphore.h>
38#include <stdlib.h>
39#include <stdio.h>
40#include <sys/stat.h>
41#include <sys/types.h>
42#include <fcntl.h>
43
44enum {
45 SEMKIND_SEMOPEN,
46 SEMKIND_SEMINIT,
47};
48
49#define SEMNAME_LEN 64
50
51struct mailsem * mailsem_new(void)
52{
53 struct mailsem * sem;
54 int r;
55
56 sem = malloc(sizeof(* sem));
57 if (sem == NULL)
58 goto err;
59
60 r = sem_init(sem->sem_sem, 0, 0);
61 if (r < 0) {
62 char name[SEMNAME_LEN];
63
64 free(sem->sem_sem);
65
66 snprintf(name, sizeof(name), "sem-%p", sem);
67
68#ifndef __CYGWIN__
69 sem->sem_sem = sem_open(name, O_CREAT, 0600, 0);
70 if (sem->sem_sem == NULL)
71 goto err;
72
73 sem->sem_kind = SEMKIND_SEMOPEN;
74#else
75 goto err;
76#endif
77 }
78 else {
79 sem->sem_kind = SEMKIND_SEMINIT;
80 }
81
82 return sem;
83
84 err:
85 return NULL;
86}
87
88void mailsem_free(struct mailsem * sem)
89{
90 if (sem->sem_kind == SEMKIND_SEMOPEN) {
91 char name[SEMNAME_LEN];
92
93#ifndef __CYGWIN__
94 sem_close((sem_t *) sem->sem_sem);
95 snprintf(name, sizeof(name), "sem-%p", sem);
96 sem_unlink(name);
97#endif
98 }
99 else {
100 sem_destroy((sem_t *) sem->sem_sem);
101 free(sem->sem_sem);
102 }
103 free(sem);
104}
105
106int mailsem_up(struct mailsem * sem)
107{
108 return sem_wait((sem_t *) sem->sem_sem);
109}
110
111int mailsem_down(struct mailsem * sem)
112{
113 return sem_post((sem_t *) sem->sem_sem);
114}
diff --git a/libetpan/src/data-types/mailsem.h b/libetpan/src/data-types/mailsem.h
new file mode 100644
index 0000000..3a6d7bc
--- a/dev/null
+++ b/libetpan/src/data-types/mailsem.h
@@ -0,0 +1,51 @@
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$
34 */
35
36#ifndef MAILSEM_H
37
38#define MAILSEM_H
39
40struct mailsem {
41 void * sem_sem;
42 int sem_kind;
43};
44
45struct mailsem * mailsem_new(void);
46void mailsem_free(struct mailsem * sem);
47
48int mailsem_up(struct mailsem * sem);
49int mailsem_down(struct mailsem * sem);
50
51#endif
diff --git a/libetpan/src/data-types/mailstream.c b/libetpan/src/data-types/mailstream.c
new file mode 100644
index 0000000..ceb0ced
--- a/dev/null
+++ b/libetpan/src/data-types/mailstream.c
@@ -0,0 +1,399 @@
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$
34 */
35
36#include "mailstream.h"
37#include "maillock.h"
38#include <string.h>
39#include <stdlib.h>
40#include <sys/types.h>
41#include <sys/stat.h>
42
43#define DEFAULT_NETWORK_TIMEOUT 300
44
45#if 0
46#ifdef LIBETPAN_MAILSTREAM_DEBUG
47
48#define STREAM_DEBUG
49
50#include <stdio.h>
51
52#define LOG_FILE "libetpan-stream-debug.log"
53
54int mailstream_debug = 0;
55
56#define STREAM_LOG_BUF(buf, size) \
57 if (mailstream_debug) { \
58 FILE * f; \
59 mode_t old_mask; \
60 \
61 old_mask = umask(0077); \
62 f = fopen(LOG_FILE, "a"); \
63 umask(old_mask); \
64 if (f != NULL) { \
65 maillock_write_lock(LOG_FILE, fileno(f)); \
66 fwrite((buf), 1, (size), f); \
67 maillock_write_unlock(LOG_FILE, fileno(f)); \
68 fclose(f); \
69 } \
70 }
71
72#define STREAM_LOG(str) \
73 if (mailstream_debug) { \
74 FILE * f; \
75 mode_t old_mask; \
76 \
77 old_mask = umask(0077); \
78 f = fopen(LOG_FILE, "a"); \
79 umask(old_mask); \
80 if (f != NULL) { \
81 maillock_write_lock(LOG_FILE, fileno(f)); \
82 fputs((str), f); \
83 maillock_write_unlock(LOG_FILE, fileno(f)); \
84 fclose(f); \
85 } \
86 }
87
88#else
89
90#define STREAM_LOG_BUF(buf, size) do { } while (0)
91#define STREAM_LOG(buf) do { } while (0)
92
93#endif
94#endif
95
96#define STREAM_LOG_BUF(buf, size) do { } while (0)
97#define STREAM_LOG(buf) do { } while (0)
98
99
100mailstream * mailstream_new(mailstream_low * low, size_t buffer_size)
101{
102 mailstream * s;
103
104 s = malloc(sizeof(* s));
105 if (s == NULL)
106 goto err;
107
108 s->read_buffer = malloc(buffer_size);
109 if (s->read_buffer == NULL)
110 goto free_s;
111 s->read_buffer_len = 0;
112
113 s->write_buffer = malloc(buffer_size);
114 if (s->write_buffer == NULL)
115 goto free_read_buffer;
116 s->write_buffer_len = 0;
117
118 s->buffer_max_size = buffer_size;
119 s->low = low;
120
121 return s;
122
123 free_read_buffer:
124 free(s->read_buffer);
125 free_s:
126 free(s);
127 err:
128 return NULL;
129}
130
131static size_t write_to_internal_buffer(mailstream * s,
132 const void * buf, size_t count)
133{
134 memcpy(s->write_buffer + s->write_buffer_len, buf, count);
135 s->write_buffer_len += count;
136
137 return count;
138}
139
140static size_t write_direct(mailstream * s, const void * buf, size_t count)
141{
142 size_t left;
143 const char * cur_buf;
144 ssize_t written;
145
146 cur_buf = buf;
147 left = count;
148 while (left > 0) {
149 written = mailstream_low_write(s->low, cur_buf, left);
150
151 if (written == -1) {
152 if (count == left)
153 return -1;
154 else
155 return count - left;
156 }
157
158 cur_buf += written;
159 left -= written;
160 }
161
162 return count;
163}
164
165ssize_t mailstream_write(mailstream * s, const void * buf, size_t count)
166{
167 int r;
168
169 if (s == NULL)
170 return -1;
171
172 if (count + s->write_buffer_len > s->buffer_max_size) {
173 r = mailstream_flush(s);
174 if (r == -1)
175 return -1;
176
177 if (count > s->buffer_max_size)
178 return write_direct(s, buf, count);
179 }
180
181#ifdef STREAM_DEBUG
182 STREAM_LOG(">>>>>>> send >>>>>>\n");
183 STREAM_LOG_BUF(buf, count);
184 STREAM_LOG("\n");
185 STREAM_LOG(">>>>>>> end send >>>>>>\n");
186#endif
187
188 return write_to_internal_buffer(s, buf, count);
189}
190
191int mailstream_flush(mailstream * s)
192{
193 char * cur_buf;
194 size_t left;
195 ssize_t written;
196
197 if (s == NULL)
198 return -1;
199
200 cur_buf = s->write_buffer;
201 left = s->write_buffer_len;
202 while (left > 0) {
203 written = mailstream_low_write(s->low, cur_buf, left);
204
205 if (written == -1)
206 goto move_buffer;
207 cur_buf += written;
208 left -= written;
209 }
210
211 s->write_buffer_len = 0;
212
213 return 0;
214
215 move_buffer:
216 memmove(s->write_buffer, cur_buf, left);
217 s->write_buffer_len = left;
218 return -1;
219}
220
221static ssize_t read_from_internal_buffer(mailstream * s,
222 void * buf, size_t count)
223{
224 if (count >= s->read_buffer_len)
225 count = s->read_buffer_len;
226 if (count != 0)
227 memcpy(buf, s->read_buffer, count);
228
229 s->read_buffer_len -= count;
230 if (s->read_buffer_len != 0)
231 memmove(s->read_buffer, s->read_buffer + count,
232 s->read_buffer_len);
233
234 return count;
235}
236
237static ssize_t read_through_buffer(mailstream * s, void * buf, size_t count)
238{
239 size_t left;
240 char * cur_buf;
241 ssize_t bytes_read;
242
243 cur_buf = buf;
244 left = count;
245
246 while (left > 0) {
247 bytes_read = mailstream_low_read(s->low, cur_buf, left);
248
249 if (bytes_read == -1) {
250 if (count == left)
251 return -1;
252 else
253 return count - left;
254 }
255 else if (bytes_read == 0)
256 return count - left;
257
258 cur_buf += bytes_read;
259 left -= bytes_read;
260 }
261
262 return count;
263}
264
265ssize_t mailstream_read(mailstream * s, void * buf, size_t count)
266{
267 ssize_t read_bytes;
268 char * cur_buf;
269 size_t left;
270
271 if (s == NULL)
272 return -1;
273
274 left = count;
275 cur_buf = buf;
276 read_bytes = read_from_internal_buffer(s, cur_buf, left);
277 cur_buf += read_bytes;
278 left -= read_bytes;
279
280 if (left == 0) {
281#ifdef STREAM_DEBUG
282 STREAM_LOG("<<<<<<< read <<<<<<\n");
283 STREAM_LOG_BUF(buf, read_bytes);
284 STREAM_LOG("\n");
285 STREAM_LOG("<<<<<<< end read <<<<<<\n");
286#endif
287
288 return read_bytes;
289 }
290
291 if (left > s->buffer_max_size) {
292 read_bytes = read_through_buffer(s, cur_buf, left);
293 if (read_bytes == -1) {
294 if (count == left)
295 return -1;
296 else {
297
298#ifdef STREAM_DEBUG
299 STREAM_LOG("<<<<<<< read <<<<<<\n");
300 STREAM_LOG_BUF(buf, count - left);
301 STREAM_LOG("\n");
302 STREAM_LOG("<<<<<<< end read <<<<<<\n");
303#endif
304
305 return count - left;
306 }
307 }
308
309 cur_buf += read_bytes;
310 left -= read_bytes;
311
312#ifdef STREAM_DEBUG
313 STREAM_LOG("<<<<<<< read <<<<<<\n");
314 STREAM_LOG_BUF(buf, count - left);
315 STREAM_LOG("\n");
316 STREAM_LOG("<<<<<<< end read <<<<<<\n");
317#endif
318
319 return count - left;
320 }
321
322 read_bytes = mailstream_low_read(s->low, s->read_buffer, s->buffer_max_size);
323 if (read_bytes == -1) {
324 if (left == count)
325 return -1;
326 else {
327#ifdef STREAM_DEBUG
328 STREAM_LOG("<<<<<<< read <<<<<<\n");
329 STREAM_LOG_BUF(buf, count - left);
330 STREAM_LOG("\n");
331 STREAM_LOG("<<<<<<< end read <<<<<<\n");
332#endif
333
334 return count - left;
335 }
336 }
337 else
338 s->read_buffer_len += read_bytes;
339
340 read_bytes = read_from_internal_buffer(s, cur_buf, left);
341 cur_buf += read_bytes;
342 left -= read_bytes;
343
344#ifdef STREAM_DEBUG
345 STREAM_LOG("<<<<<<< read <<<<<<\n");
346 STREAM_LOG_BUF(buf, count - left);
347 STREAM_LOG("\n");
348 STREAM_LOG("<<<<<<< end read <<<<<<\n");
349#endif
350
351 return count - left;
352}
353
354mailstream_low * mailstream_get_low(mailstream * s)
355{
356 return s->low;
357}
358
359void mailstream_set_low(mailstream * s, mailstream_low * low)
360{
361 s->low = low;
362}
363
364int mailstream_close(mailstream * s)
365{
366 mailstream_low_close(s->low);
367 mailstream_low_free(s->low);
368
369 free(s->read_buffer);
370 free(s->write_buffer);
371
372 free(s);
373
374 return 0;
375}
376
377
378
379ssize_t mailstream_feed_read_buffer(mailstream * s)
380{
381 ssize_t read_bytes;
382
383 if (s == NULL)
384 return -1;
385
386 if (s->read_buffer_len == 0) {
387 read_bytes = mailstream_low_read(s->low, s->read_buffer,
388 s->buffer_max_size);
389 if (read_bytes == -1)
390 return -1;
391 s->read_buffer_len += read_bytes;
392 }
393
394 return s->read_buffer_len;
395}
396
397struct timeval mailstream_network_delay =
398 { .tv_sec = DEFAULT_NETWORK_TIMEOUT, .tv_usec = 0 };
399
diff --git a/libetpan/src/data-types/mailstream.h b/libetpan/src/data-types/mailstream.h
new file mode 100644
index 0000000..04a5ae3
--- a/dev/null
+++ b/libetpan/src/data-types/mailstream.h
@@ -0,0 +1,73 @@
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$
34 */
35
36#ifndef MAILSTREAM_H
37
38#define MAILSTREAM_H
39
40#include <sys/time.h>
41
42#include <libetpan/mailstream_low.h>
43#include <libetpan/mailstream_helper.h>
44#include <libetpan/mailstream_socket.h>
45#include <libetpan/mailstream_ssl.h>
46#include <libetpan/mailstream_types.h>
47
48#ifdef __cplusplus
49extern "C" {
50#endif
51
52mailstream * mailstream_new(mailstream_low * low, size_t buffer_size);
53ssize_t mailstream_write(mailstream * s, const void * buf, size_t count);
54ssize_t mailstream_read(mailstream * s, void * buf, size_t count);
55int mailstream_close(mailstream * s);
56int mailstream_flush(mailstream * s);
57ssize_t mailstream_feed_read_buffer(mailstream * s);
58mailstream_low * mailstream_get_low(mailstream * s);
59void mailstream_set_low(mailstream * s, mailstream_low * low);
60
61#ifdef LIBETPAN_MAILSTREAM_DEBUG
62extern int mailstream_debug;
63#endif
64
65#define LIBETPAN_MAILSTREAM_NETWORK_DELAY
66extern struct timeval mailstream_network_delay;
67
68#ifdef __cplusplus
69}
70#endif
71
72#endif
73
diff --git a/libetpan/src/data-types/mailstream_helper.c b/libetpan/src/data-types/mailstream_helper.c
new file mode 100644
index 0000000..2f0b9ae
--- a/dev/null
+++ b/libetpan/src/data-types/mailstream_helper.c
@@ -0,0 +1,515 @@
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$
34 */
35
36#include "mailstream_helper.h"
37#include <string.h>
38#include <stdio.h>
39#include "mail.h"
40
41static void remove_trailing_eol(MMAPString * mmapstr)
42{
43 if (mmapstr->str[mmapstr->len - 1] == '\n') {
44 mmapstr->len --;
45 mmapstr->str[mmapstr->len] = '\0';
46 }
47 if (mmapstr->str[mmapstr->len - 1] == '\r') {
48 mmapstr->len --;
49 mmapstr->str[mmapstr->len] = '\0';
50 }
51}
52
53char * mailstream_read_line(mailstream * stream, MMAPString * line)
54{
55 if (mmap_string_assign(line, "") == NULL)
56 return NULL;
57
58 return mailstream_read_line_append(stream, line);
59}
60
61static char * mailstream_read_len_append(mailstream * stream,
62 MMAPString * line,
63 size_t i)
64{
65 size_t cur_size;
66
67 cur_size = line->len;
68 if (mmap_string_set_size(line, line->len + i) == NULL)
69 return NULL;
70 if (mailstream_read(stream, line->str + cur_size, i) < 0)
71 return NULL;
72 return line->str;
73}
74
75char * mailstream_read_line_append(mailstream * stream, MMAPString * line)
76{
77 if (stream == NULL)
78 return NULL;
79
80 do {
81 if (stream->read_buffer_len > 0) {
82 size_t i;
83
84 i = 0;
85 while (i < stream->read_buffer_len) {
86 if (stream->read_buffer[i] == '\n')
87 return mailstream_read_len_append(stream, line, i + 1);
88 i++;
89 }
90 if (mailstream_read_len_append(stream, line,
91 stream->read_buffer_len) == NULL)
92 return NULL;
93 }
94 else {
95 ssize_t r;
96
97 r = mailstream_feed_read_buffer(stream);
98 if (r == -1)
99 return NULL;
100
101 if (r == 0)
102 break;
103 }
104 }
105 while (1);
106
107 return line->str;
108}
109
110char * mailstream_read_line_remove_eol(mailstream * stream, MMAPString * line)
111{
112 if (!mailstream_read_line(stream, line))
113 return NULL;
114
115 remove_trailing_eol(line);
116
117 return line->str;
118}
119
120int mailstream_is_end_multiline(const char * line)
121{
122 if (line[0] != '.')
123 return FALSE;
124 if (line[1] != 0)
125 return FALSE;
126 return TRUE;
127}
128
129#if 1
130char * mailstream_read_multiline(mailstream * s, size_t size,
131 MMAPString * stream_buffer,
132 MMAPString * multiline_buffer,
133 size_t progr_rate,
134 progress_function * progr_fun)
135{
136 size_t count;
137 char * line;
138 size_t last;
139
140 if (mmap_string_assign(multiline_buffer, "") == NULL)
141 return NULL;
142
143 count = 0;
144 last = 0;
145
146 while ((line = mailstream_read_line_remove_eol(s, stream_buffer)) != NULL) {
147 if (mailstream_is_end_multiline(line))
148 return multiline_buffer->str;
149
150 if (line[0] == '.') {
151 if (mmap_string_append(multiline_buffer, line + 1) == NULL)
152 return NULL;
153 }
154 else {
155 if (mmap_string_append(multiline_buffer, line) == NULL)
156 return NULL;
157 }
158 if (mmap_string_append(multiline_buffer, "\r\n") == NULL)
159 return NULL;
160
161 count += strlen(line);
162 if ((size != 0) && (progr_rate != 0) && (progr_fun != NULL))
163 if (count - last >= progr_rate) {
164 (* progr_fun)(count, size);
165 last = count;
166 }
167 }
168
169 return NULL;
170}
171
172#else
173
174/*
175 high speed but don't replace the line break with '\n' and neither
176 remove the '.'
177*/
178
179static gboolean end_of_multiline(const char * str, gint len)
180{
181 gint index;
182
183 index = len - 1;
184
185 if (str[index] != '\n')
186 return FALSE;
187 if (index == 0)
188 return FALSE;
189
190 index --;
191
192 if (str[index] == '\r') {
193 index --;
194 if (index == 0)
195 return FALSE;
196 }
197
198 if (str[index] != '.')
199 return FALSE;
200 if (index == 0)
201 return FALSE;
202
203 index--;
204
205 if (str[index] != '\n')
206 return FALSE;
207
208 return TRUE;
209}
210
211char * mailstream_read_multiline(mailstream * stream, size_t size,
212 MMAPString * stream_buffer,
213 MMAPString * line,
214 size_t progr_rate,
215 progress_function * progr_fun)
216{
217 if (stream == NULL)
218 return NULL;
219
220 mmap_string_assign(line, "");
221
222 do {
223 if (stream->read_buffer_len > 0) {
224 size_t i;
225
226 i = 0;
227 while (i < stream->read_buffer_len) {
228 if (end_of_multiline(stream->read_buffer, i + 1))
229 return mailstream_read_len_append(stream, line, i + 1);
230 i++;
231 }
232 if (mailstream_read_len_append(stream, line,
233 stream->read_buffer_len) == NULL)
234 return NULL;
235 if (end_of_multiline(line->str, line->len))
236 return line->str;
237 }
238 else
239 if (mailstream_feed_read_buffer(stream) == -1)
240 return NULL;
241 }
242 while (1);
243
244 return line->str;
245}
246#endif
247
248
249
250static inline ssize_t send_data_line(mailstream * s,
251 const char * line, size_t length)
252{
253 int fix_eol;
254 const char * start;
255 size_t count;
256
257 start = line;
258
259 fix_eol = 0;
260 count = 0;
261
262 while (1) {
263 if (length == 0)
264 break;
265
266 if (* line == '\r') {
267 line ++;
268
269 count ++;
270 length --;
271
272 if (length == 0) {
273 fix_eol = 1;
274 break;
275 }
276
277 if (* line == '\n') {
278 line ++;
279
280 count ++;
281 length --;
282
283 break;
284 }
285 else {
286 fix_eol = 1;
287 break;
288 }
289 }
290 else if (* line == '\n') {
291 line ++;
292
293 count ++;
294 length --;
295
296 fix_eol = 1;
297 break;
298 }
299
300 line ++;
301 length --;
302 count ++;
303 }
304
305 if (fix_eol) {
306 if (mailstream_write(s, start, count - 1) == -1)
307 goto err;
308 if (mailstream_write(s, "\r\n", 2) == -1)
309 goto err;
310 }
311 else {
312 if (mailstream_write(s, start, count) == -1)
313 goto err;
314 }
315
316
317#if 0
318 while (* line != '\n') {
319 if (* line == '\r')
320 pos = line;
321 if (* line == '\0')
322 return line;
323 if (mailstream_write(s, line, 1) == -1)
324 goto err;
325 line ++;
326 }
327 if (pos + 1 == line) {
328 if (mailstream_write(s, line, 1) == -1)
329 goto err;
330 }
331 else {
332 if (mailstream_write(s, "\r\n", 2) == -1)
333 goto err;
334 }
335 line ++;
336#endif
337
338 return count;
339
340 err:
341 return -1;
342}
343
344static inline int send_data_crlf(mailstream * s, const char * message,
345 size_t size,
346 int quoted,
347 size_t progr_rate,
348 progress_function * progr_fun)
349{
350 const char * current;
351 size_t count;
352 size_t last;
353 size_t remaining;
354
355 count = 0;
356 last = 0;
357
358 current = message;
359 remaining = size;
360
361 while (remaining > 0) {
362 ssize_t length;
363
364 if (quoted) {
365 if (current[0] == '.')
366 if (mailstream_write(s, ".", 1) == -1)
367 goto err;
368 }
369
370 length = send_data_line(s, current, remaining);
371 if (length < 0)
372 goto err;
373
374 current += length;
375
376 count += length;
377 if ((progr_rate != 0) && (progr_fun != NULL))
378 if (count - last >= progr_rate) {
379 (* progr_fun)(count, size);
380 last = count;
381 }
382
383 remaining -= length;
384 }
385
386 return 0;
387
388 err:
389 return -1;
390}
391
392int mailstream_send_data_crlf(mailstream * s, const char * message,
393 size_t size,
394 size_t progr_rate,
395 progress_function * progr_fun)
396{
397 return send_data_crlf(s, message, size, 0, progr_rate, progr_fun);
398}
399
400int mailstream_send_data(mailstream * s, const char * message,
401 size_t size,
402 size_t progr_rate,
403 progress_function * progr_fun)
404{
405 if (send_data_crlf(s, message, size, 1, progr_rate, progr_fun) == -1)
406 goto err;
407
408 if (mailstream_write(s, "\r\n.\r\n", 5) == -1)
409 goto err;
410
411 if (mailstream_flush(s) == -1)
412 goto err;
413
414 return 0;
415
416 err:
417 return -1;
418}
419
420static inline ssize_t get_data_size(const char * line, size_t length,
421 size_t * result)
422{
423 int fix_eol;
424 const char * start;
425 size_t count;
426 size_t fixed_count;
427
428 start = line;
429
430 fix_eol = 0;
431 count = 0;
432 fixed_count = 0;
433
434 while (1) {
435 if (length == 0)
436 break;
437
438 if (* line == '\r') {
439 line ++;
440
441 count ++;
442 length --;
443
444 if (length == 0) {
445 fix_eol = 1;
446 fixed_count ++;
447 break;
448 }
449
450 if (* line == '\n') {
451 line ++;
452
453 count ++;
454 length --;
455
456 break;
457 }
458 else {
459 fix_eol = 1;
460 fixed_count ++;
461 break;
462 }
463 }
464 else if (* line == '\n') {
465 line ++;
466
467 count ++;
468 length --;
469
470 fix_eol = 1;
471 fixed_count ++;
472 break;
473 }
474
475 line ++;
476 length --;
477 count ++;
478 }
479
480 * result = count + fixed_count;
481
482 return count;
483}
484
485size_t mailstream_get_data_crlf_size(const char * message, size_t size)
486{
487 const char * current;
488 size_t count;
489 size_t last;
490 size_t remaining;
491 size_t fixed_count;
492
493 count = 0;
494 last = 0;
495 fixed_count = 0;
496
497 current = message;
498 remaining = size;
499
500 while (remaining > 0) {
501 ssize_t length;
502 size_t line_count;
503
504 length = get_data_size(current, remaining, &line_count);
505
506 fixed_count += line_count;
507 current += length;
508
509 count += length;
510
511 remaining -= length;
512 }
513
514 return fixed_count;
515}
diff --git a/libetpan/src/data-types/mailstream_helper.h b/libetpan/src/data-types/mailstream_helper.h
new file mode 100644
index 0000000..1bc36a2
--- a/dev/null
+++ b/libetpan/src/data-types/mailstream_helper.h
@@ -0,0 +1,77 @@
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$
34 */
35
36#ifndef MAILSTREAM_HELPER_H
37
38#define MAILSTREAM_HELPER_H
39
40#include <libetpan/mmapstring.h>
41#include <libetpan/mailstream.h>
42
43#ifdef __cplusplus
44extern "C" {
45#endif
46
47char * mailstream_read_line(mailstream * stream, MMAPString * line);
48
49char * mailstream_read_line_append(mailstream * stream, MMAPString * line);
50
51char * mailstream_read_line_remove_eol(mailstream * stream, MMAPString * line);
52
53char * mailstream_read_multiline(mailstream * s, size_t size,
54 MMAPString * stream_buffer,
55 MMAPString * multiline_buffer,
56 size_t progr_rate,
57 progress_function * progr_fun);
58
59int mailstream_is_end_multiline(const char * line);
60
61int mailstream_send_data_crlf(mailstream * s, const char * message,
62 size_t size,
63 size_t progr_rate,
64 progress_function * progr_fun);
65
66int mailstream_send_data(mailstream * s, const char * message,
67 size_t size,
68 size_t progr_rate,
69 progress_function * progr_fun);
70
71size_t mailstream_get_data_crlf_size(const char * message, size_t size);
72
73#ifdef __cplusplus
74}
75#endif
76
77#endif
diff --git a/libetpan/src/data-types/mailstream_low.c b/libetpan/src/data-types/mailstream_low.c
new file mode 100644
index 0000000..ab268bb
--- a/dev/null
+++ b/libetpan/src/data-types/mailstream_low.c
@@ -0,0 +1,164 @@
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$
34 */
35
36#include "mailstream_low.h"
37#include <stdlib.h>
38
39#ifdef LIBETPAN_MAILSTREAM_DEBUG
40
41#define STREAM_DEBUG
42
43#include <stdio.h>
44#include <sys/types.h>
45#include <sys/stat.h>
46#include "maillock.h"
47
48#define LOG_FILE "libetpan-stream-debug.log"
49
50int mailstream_debug = 0;
51
52#define STREAM_LOG_BUF(buf, size) \
53 if (mailstream_debug) { \
54 FILE * f; \
55 mode_t old_mask; \
56 \
57 old_mask = umask(0077); \
58 f = fopen(LOG_FILE, "a"); \
59 umask(old_mask); \
60 if (f != NULL) { \
61 maillock_write_lock(LOG_FILE, fileno(f)); \
62 fwrite((buf), 1, (size), f); \
63 maillock_write_unlock(LOG_FILE, fileno(f)); \
64 fclose(f); \
65 } \
66 }
67
68#define STREAM_LOG(str) \
69 if (mailstream_debug) { \
70 FILE * f; \
71 mode_t old_mask; \
72 \
73 old_mask = umask(0077); \
74 f = fopen(LOG_FILE, "a"); \
75 umask(old_mask); \
76 if (f != NULL) { \
77 maillock_write_lock(LOG_FILE, fileno(f)); \
78 fputs((str), f); \
79 maillock_write_unlock(LOG_FILE, fileno(f)); \
80 fclose(f); \
81 } \
82 }
83
84#else
85
86#define STREAM_LOG_BUF(buf, size) do { } while (0)
87#define STREAM_LOG(buf) do { } while (0)
88
89#endif
90
91
92/* general functions */
93
94mailstream_low * mailstream_low_new(void * data,
95 mailstream_low_driver * driver)
96{
97 mailstream_low * s;
98
99 s = malloc(sizeof(* s));
100 if (s == NULL)
101 return NULL;
102
103 s->data = data;
104 s->driver = driver;
105
106 return s;
107}
108
109int mailstream_low_close(mailstream_low * s)
110{
111 if (s == NULL)
112 return -1;
113 s->driver->mailstream_close(s);
114
115 return 0;
116}
117
118int mailstream_low_get_fd(mailstream_low * s)
119{
120 if (s == NULL)
121 return -1;
122 return s->driver->mailstream_get_fd(s);
123}
124
125void mailstream_low_free(mailstream_low * s)
126{
127 s->driver->mailstream_free(s);
128}
129
130ssize_t mailstream_low_read(mailstream_low * s, void * buf, size_t count)
131{
132 ssize_t r;
133
134 if (s == NULL)
135 return -1;
136 r = s->driver->mailstream_read(s, buf, count);
137
138#ifdef STREAM_DEBUG
139 if (r > 0) {
140 STREAM_LOG("<<<<<<< read <<<<<<\n");
141 STREAM_LOG_BUF(buf, r);
142 STREAM_LOG("\n");
143 STREAM_LOG("<<<<<<< end read <<<<<<\n");
144 }
145#endif
146
147 return r;
148}
149
150ssize_t mailstream_low_write(mailstream_low * s,
151 const void * buf, size_t count)
152{
153 if (s == NULL)
154 return -1;
155
156#ifdef STREAM_DEBUG
157 STREAM_LOG(">>>>>>> send >>>>>>\n");
158 STREAM_LOG_BUF(buf, count);
159 STREAM_LOG("\n");
160 STREAM_LOG(">>>>>>> end send >>>>>>\n");
161#endif
162
163 return s->driver->mailstream_write(s, buf, count);
164}
diff --git a/libetpan/src/data-types/mailstream_low.h b/libetpan/src/data-types/mailstream_low.h
new file mode 100644
index 0000000..e3fff1f
--- a/dev/null
+++ b/libetpan/src/data-types/mailstream_low.h
@@ -0,0 +1,62 @@
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$
34 */
35
36#ifndef MAILSTREAM_LOW_H
37
38#define MAILSTREAM_LOW_H
39
40#include <sys/types.h>
41#include <libetpan/mailstream_types.h>
42
43#ifdef __cplusplus
44extern "C" {
45#endif
46
47/* general functions */
48
49mailstream_low * mailstream_low_new(void * data,
50 mailstream_low_driver * driver);
51ssize_t mailstream_low_write(mailstream_low * s,
52 const void * buf, size_t count);
53ssize_t mailstream_low_read(mailstream_low * s, void * buf, size_t count);
54int mailstream_low_close(mailstream_low * s);
55int mailstream_low_get_fd(mailstream_low * s);
56void mailstream_low_free(mailstream_low * s);
57
58#ifdef __cplusplus
59}
60#endif
61
62#endif
diff --git a/libetpan/src/data-types/mailstream_socket.c b/libetpan/src/data-types/mailstream_socket.c
new file mode 100644
index 0000000..bd58571
--- a/dev/null
+++ b/libetpan/src/data-types/mailstream_socket.c
@@ -0,0 +1,238 @@
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$
34 */
35
36#include "mailstream_socket.h"
37#include <unistd.h>
38#include <stdlib.h>
39#include <fcntl.h>
40#include <sys/socket.h>
41
42/*
43 these 3 headers MUST be included before <sys/select.h>
44 to insure compatibility with Mac OS X (this is true for 10.2)
45*/
46#include <sys/time.h>
47#include <sys/types.h>
48#include <unistd.h>
49#include <sys/select.h>
50
51/* mailstream_low, socket */
52
53static int mailstream_low_socket_close(mailstream_low * s);
54static ssize_t mailstream_low_socket_read(mailstream_low * s,
55 void * buf, size_t count);
56static ssize_t mailstream_low_socket_write(mailstream_low * s,
57 const void * buf, size_t count);
58static void mailstream_low_socket_free(mailstream_low * s);
59static int mailstream_low_socket_get_fd(mailstream_low * s);
60
61static mailstream_low_driver local_mailstream_socket_driver = {
62 mailstream_read: mailstream_low_socket_read,
63 mailstream_write: mailstream_low_socket_write,
64 mailstream_close: mailstream_low_socket_close,
65 mailstream_free: mailstream_low_socket_free,
66 mailstream_get_fd: mailstream_low_socket_get_fd,
67};
68
69mailstream_low_driver * mailstream_socket_driver =
70&local_mailstream_socket_driver;
71
72/* file descriptor must be given in (default) blocking-mode */
73
74static struct mailstream_socket_data * socket_data_new(int fd)
75{
76 struct mailstream_socket_data * socket_data;
77
78 socket_data = malloc(sizeof(* socket_data));
79 if (socket_data == NULL)
80 goto err;
81
82 socket_data->fd = fd;
83
84 return socket_data;
85
86 err:
87 return NULL;
88}
89
90static void socket_data_free(struct mailstream_socket_data * socket_data)
91{
92 free(socket_data);
93}
94
95static void socket_data_close(struct mailstream_socket_data * socket_data)
96{
97 close(socket_data->fd);
98 socket_data->fd = -1;
99}
100
101mailstream_low * mailstream_low_socket_open(int fd)
102{
103 mailstream_low * s;
104 struct mailstream_socket_data * socket_data;
105
106 socket_data = socket_data_new(fd);
107 if (socket_data == NULL)
108 goto err;
109
110 s = mailstream_low_new(socket_data, mailstream_socket_driver);
111 if (s == NULL)
112 goto free_socket_data;
113
114 return s;
115
116 free_socket_data:
117 socket_data_free(socket_data);
118 err:
119 return NULL;
120}
121
122static int mailstream_low_socket_close(mailstream_low * s)
123{
124 struct mailstream_socket_data * socket_data;
125
126 socket_data = (struct mailstream_socket_data *) s->data;
127 socket_data_close(socket_data);
128
129 return 0;
130}
131
132static void mailstream_low_socket_free(mailstream_low * s)
133{
134 struct mailstream_socket_data * socket_data;
135
136 socket_data = (struct mailstream_socket_data *) s->data;
137 socket_data_free(socket_data);
138 s->data = NULL;
139
140 free(s);
141}
142
143static int mailstream_low_socket_get_fd(mailstream_low * s)
144{
145 struct mailstream_socket_data * socket_data;
146
147 socket_data = (struct mailstream_socket_data *) s->data;
148 return socket_data->fd;
149}
150
151
152static ssize_t mailstream_low_socket_read(mailstream_low * s,
153 void * buf, size_t count)
154{
155 struct mailstream_socket_data * socket_data;
156
157 socket_data = (struct mailstream_socket_data *) s->data;
158
159 /* timeout */
160 {
161 fd_set fds_read;
162 fd_set fds_excp;
163 struct timeval timeout;
164 int r;
165
166 timeout = mailstream_network_delay;
167
168 FD_ZERO(&fds_read);
169 FD_SET(socket_data->fd, &fds_read);
170 FD_ZERO(&fds_excp);
171 FD_SET(socket_data->fd, &fds_excp);
172 r = select(socket_data->fd + 1, &fds_read, NULL, &fds_excp, &timeout);
173 if (r == 0)
174 return -1;
175 if (FD_ISSET(socket_data->fd, &fds_excp))
176 return -1;
177 if (!FD_ISSET(socket_data->fd, &fds_read))
178 return 0;
179 }
180
181 return read(socket_data->fd, buf, count);
182}
183
184static ssize_t mailstream_low_socket_write(mailstream_low * s,
185 const void * buf, size_t count)
186{
187 struct mailstream_socket_data * socket_data;
188
189 socket_data = (struct mailstream_socket_data *) s->data;
190 /* timeout */
191 {
192 fd_set fds_write;
193 fd_set fds_excp;
194 struct timeval timeout;
195 int r;
196
197 timeout = mailstream_network_delay;
198
199 FD_ZERO(&fds_write);
200 FD_SET(socket_data->fd, &fds_write);
201 FD_ZERO(&fds_excp);
202 FD_SET(socket_data->fd, &fds_excp);
203 r = select(socket_data->fd + 1, NULL, &fds_write, &fds_excp, &timeout);
204 if (r == 0)
205 return -1;
206 if (FD_ISSET(socket_data->fd, &fds_excp))
207 return -1;
208 if (!FD_ISSET(socket_data->fd, &fds_write))
209 return 0;
210 }
211
212 return write(socket_data->fd, buf, count);
213}
214
215
216/* mailstream */
217
218mailstream * mailstream_socket_open(int fd)
219{
220 mailstream_low * low;
221 mailstream * s;
222
223 low = mailstream_low_socket_open(fd);
224 if (low == NULL)
225 goto err;
226
227 s = mailstream_new(low, 8192);
228 if (s == NULL)
229 goto free_low;
230
231 return s;
232
233 free_low:
234 mailstream_low_close(low);
235 err:
236 return NULL;
237}
238
diff --git a/libetpan/src/data-types/mailstream_socket.h b/libetpan/src/data-types/mailstream_socket.h
new file mode 100644
index 0000000..9cf6ada
--- a/dev/null
+++ b/libetpan/src/data-types/mailstream_socket.h
@@ -0,0 +1,61 @@
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$
34 */
35
36#ifndef MAILSTREAM_SOCKET_H
37
38#define MAILSTREAM_SOCKET_H
39
40#include <libetpan/mailstream.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46/* socket */
47
48extern mailstream_low_driver * mailstream_socket_driver;
49
50mailstream_low * mailstream_low_socket_open(int fd);
51mailstream * mailstream_socket_open(int fd);
52
53struct mailstream_socket_data {
54 int fd;
55};
56
57#ifdef __cplusplus
58}
59#endif
60
61#endif
diff --git a/libetpan/src/data-types/mailstream_ssl.c b/libetpan/src/data-types/mailstream_ssl.c
new file mode 100644
index 0000000..e57fa22
--- a/dev/null
+++ b/libetpan/src/data-types/mailstream_ssl.c
@@ -0,0 +1,320 @@
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$
34 */
35
36/*
37 NOTE :
38
39 The user has to call himself SSL_library_init() if he wants to
40 use SSL.
41*/
42
43#include "mailstream_ssl.h"
44#include <unistd.h>
45#include <fcntl.h>
46
47#ifndef CONFIG_H
48#define CONFIG_H
49#include "config.h"
50#endif
51
52/*
53 these 3 headers MUST be included before <sys/select.h>
54 to insure compatibility with Mac OS X (this is true for 10.2)
55*/
56#include <sys/time.h>
57#include <sys/types.h>
58#include <unistd.h>
59#include <sys/select.h>
60
61/* mailstream_low, ssl */
62
63#ifdef USE_SSL
64#include <openssl/ssl.h>
65#ifdef LIBETPAN_REENTRANT
66#include <pthread.h>
67#endif
68#endif
69
70#ifdef USE_SSL
71struct mailstream_ssl_data {
72 int fd;
73 SSL * ssl_conn;
74 SSL_CTX * ssl_ctx;
75};
76#endif
77
78#ifdef USE_SSL
79#ifdef LIBETPAN_REENTRANT
80static pthread_mutex_t ssl_lock = PTHREAD_MUTEX_INITIALIZER;
81#endif
82static int ssl_init_done = 0;
83#endif
84
85#ifdef USE_SSL
86static int mailstream_low_ssl_close(mailstream_low * s);
87static ssize_t mailstream_low_ssl_read(mailstream_low * s,
88 void * buf, size_t count);
89static ssize_t mailstream_low_ssl_write(mailstream_low * s,
90 const void * buf, size_t count);
91static void mailstream_low_ssl_free(mailstream_low * s);
92static int mailstream_low_ssl_get_fd(mailstream_low * s);
93
94static mailstream_low_driver local_mailstream_ssl_driver = {
95 mailstream_read: mailstream_low_ssl_read,
96 mailstream_write: mailstream_low_ssl_write,
97 mailstream_close: mailstream_low_ssl_close,
98 mailstream_free: mailstream_low_ssl_free,
99 mailstream_get_fd: mailstream_low_ssl_get_fd,
100};
101
102mailstream_low_driver * mailstream_ssl_driver = &local_mailstream_ssl_driver;
103#endif
104
105/* file descriptor must be given in (default) blocking-mode */
106
107#ifdef USE_SSL
108static struct mailstream_ssl_data * ssl_data_new(int fd)
109{
110 struct mailstream_ssl_data * ssl_data;
111 SSL * ssl_conn;
112 int r;
113 SSL_CTX * tmp_ctx;
114 int fd_flags;
115 int old_fd_flags;
116
117#ifdef LIBETPAN_REENTRANT
118 pthread_mutex_lock(&ssl_lock);
119#endif
120 if (!ssl_init_done) {
121 SSL_library_init();
122 ssl_init_done = 1;
123 }
124#ifdef LIBETPAN_REENTRANT
125 pthread_mutex_unlock(&ssl_lock);
126#endif
127
128 tmp_ctx = SSL_CTX_new(TLSv1_client_method());
129 if (tmp_ctx == NULL)
130 goto err;
131
132 ssl_conn = (SSL *) SSL_new(tmp_ctx);
133 if (ssl_conn == NULL)
134 goto free_ctx;
135
136 if (SSL_set_fd(ssl_conn, fd) == 0)
137 goto free_ssl_conn;
138
139 SSL_set_read_ahead(ssl_conn, 1);
140
141 r = SSL_connect(ssl_conn);
142 if (r <= 0)
143 goto free_ssl_conn;
144
145 fd_flags = fcntl(fd, F_GETFL, 0);
146 old_fd_flags = fd_flags;
147 fd_flags |= O_NDELAY;
148 r = fcntl(fd, F_SETFL, fd_flags);
149 if (r < 0)
150 goto free_ssl_conn;
151
152 ssl_data = malloc(sizeof(* ssl_data));
153 if (ssl_data == NULL)
154 goto reset_fd_flags;
155
156 ssl_data->fd = fd;
157 ssl_data->ssl_conn = ssl_conn;
158 ssl_data->ssl_ctx = tmp_ctx;
159
160 return ssl_data;
161
162 reset_fd_flags:
163 fcntl(fd, F_SETFL, old_fd_flags);
164 free_ctx:
165 SSL_CTX_free(tmp_ctx);
166 free_ssl_conn:
167 SSL_free(ssl_conn);
168 err:
169 return NULL;
170}
171
172static void ssl_data_free(struct mailstream_ssl_data * ssl_data)
173{
174 free(ssl_data);
175}
176
177static void ssl_data_close(struct mailstream_ssl_data * ssl_data)
178{
179 SSL_free(ssl_data->ssl_conn);
180 ssl_data->ssl_conn = NULL;
181 SSL_CTX_free(ssl_data->ssl_ctx);
182 ssl_data->ssl_ctx = NULL;
183 close(ssl_data->fd);
184 ssl_data->fd = -1;
185}
186#endif
187
188mailstream_low * mailstream_low_ssl_open(int fd)
189{
190#ifdef USE_SSL
191 mailstream_low * s;
192 struct mailstream_ssl_data * ssl_data;
193
194 ssl_data = ssl_data_new(fd);
195 if (ssl_data == NULL)
196 goto err;
197
198 s = mailstream_low_new(ssl_data, mailstream_ssl_driver);
199 if (s == NULL)
200 goto free_ssl_data;
201
202 return s;
203
204 free_ssl_data:
205 ssl_data_free(ssl_data);
206 err:
207 return NULL;
208#else
209 return NULL;
210#endif
211}
212
213#ifdef USE_SSL
214static int mailstream_low_ssl_close(mailstream_low * s)
215{
216 struct mailstream_ssl_data * ssl_data;
217
218 ssl_data = (struct mailstream_ssl_data *) s->data;
219 ssl_data_close(ssl_data);
220
221 return 0;
222}
223
224static void mailstream_low_ssl_free(mailstream_low * s)
225{
226 struct mailstream_ssl_data * ssl_data;
227
228 ssl_data = (struct mailstream_ssl_data *) s->data;
229 ssl_data_free(ssl_data);
230 s->data = NULL;
231
232 free(s);
233}
234
235static int mailstream_low_ssl_get_fd(mailstream_low * s)
236{
237 struct mailstream_ssl_data * ssl_data;
238
239 ssl_data = (struct mailstream_ssl_data *) s->data;
240 return ssl_data->fd;
241}
242
243static ssize_t mailstream_low_ssl_read(mailstream_low * s,
244 void * buf, size_t count)
245{
246 struct mailstream_ssl_data * ssl_data;
247 int r;
248
249 ssl_data = (struct mailstream_ssl_data *) s->data;
250
251 while (1) {
252 int ssl_r;
253 fd_set fds_read;
254 struct timeval timeout;
255
256 r = SSL_read(ssl_data->ssl_conn, buf, count);
257 if (r > 0)
258 return r;
259
260 ssl_r = SSL_get_error(ssl_data->ssl_conn, r);
261 switch (ssl_r) {
262 case SSL_ERROR_NONE:
263 return r;
264
265 case SSL_ERROR_ZERO_RETURN:
266 return r;
267
268 case SSL_ERROR_WANT_READ:
269 timeout = mailstream_network_delay;
270
271 FD_ZERO(&fds_read);
272 FD_SET(ssl_data->fd, &fds_read);
273 r = select(ssl_data->fd + 1, &fds_read, NULL, NULL, &timeout);
274 if (r == 0)
275 return -1;
276 break;
277
278 default:
279 return r;
280 }
281 }
282}
283
284static ssize_t mailstream_low_ssl_write(mailstream_low * s,
285 const void * buf, size_t count)
286{
287 struct mailstream_ssl_data * ssl_data;
288
289 ssl_data = (struct mailstream_ssl_data *) s->data;
290 return SSL_write(ssl_data->ssl_conn, buf, count);
291}
292#endif
293
294/* mailstream */
295
296mailstream * mailstream_ssl_open(int fd)
297{
298#ifdef USE_SSL
299 mailstream_low * low;
300 mailstream * s;
301
302 low = mailstream_low_ssl_open(fd);
303 if (low == NULL)
304 goto err;
305
306 s = mailstream_new(low, 8192);
307 if (s == NULL)
308 goto free_low;
309
310 return s;
311
312 free_low:
313 mailstream_low_close(low);
314 err:
315 return NULL;
316#else
317 return NULL;
318#endif
319}
320
diff --git a/libetpan/src/data-types/mailstream_ssl.h b/libetpan/src/data-types/mailstream_ssl.h
new file mode 100644
index 0000000..bc14d25
--- a/dev/null
+++ b/libetpan/src/data-types/mailstream_ssl.h
@@ -0,0 +1,59 @@
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$
34 */
35
36#ifndef MAILSTREAM_SSL_H
37
38#define MAILSTREAM_SSL_H
39
40#include <libetpan/mailstream.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46/* socket */
47
48#ifdef USE_SSL
49extern mailstream_low_driver * mailstream_ssl_driver;
50#endif
51
52mailstream_low * mailstream_low_ssl_open(int fd);
53mailstream * mailstream_ssl_open(int fd);
54
55#ifdef __cplusplus
56}
57#endif
58
59#endif
diff --git a/libetpan/src/data-types/mailstream_types.h b/libetpan/src/data-types/mailstream_types.h
new file mode 100644
index 0000000..b560ebb
--- a/dev/null
+++ b/libetpan/src/data-types/mailstream_types.h
@@ -0,0 +1,87 @@
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$
34 */
35
36#ifndef MAILSTREAM_TYPES_H
37
38#define MAILSTREAM_TYPES_H
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#define LIBETPAN_MAILSTREAM_DEBUG
45
46struct _mailstream;
47
48typedef struct _mailstream mailstream;
49
50struct _mailstream_low;
51
52typedef struct _mailstream_low mailstream_low;
53
54struct _mailstream {
55 size_t buffer_max_size;
56
57 char * write_buffer;
58 size_t write_buffer_len;
59
60 char * read_buffer;
61 size_t read_buffer_len;
62
63 mailstream_low * low;
64};
65
66struct mailstream_low_driver {
67 ssize_t (* mailstream_read)(mailstream_low *, void *, size_t);
68 ssize_t (* mailstream_write)(mailstream_low *, const void *, size_t);
69 int (* mailstream_close)(mailstream_low *);
70 int (* mailstream_get_fd)(mailstream_low *);
71 void (* mailstream_free)(mailstream_low *);
72};
73
74typedef struct mailstream_low_driver mailstream_low_driver;
75
76struct _mailstream_low {
77 void * data;
78 mailstream_low_driver * driver;
79};
80
81typedef void progress_function(size_t current, size_t maximum);
82
83#ifdef __cplusplus
84}
85#endif
86
87#endif
diff --git a/libetpan/src/data-types/mapping.c b/libetpan/src/data-types/mapping.c
new file mode 100644
index 0000000..5f2c4a4
--- a/dev/null
+++ b/libetpan/src/data-types/mapping.c
@@ -0,0 +1,67 @@
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$
34 */
35
36#include "mapping.h"
37
38#include <unistd.h>
39#include <sys/mman.h>
40
41int get_mapping(size_t length, int prot, int flags,
42 int fd, off_t offset,
43 void ** presult, void ** pmapping, size_t * pmapping_size)
44{
45 void * mapping;
46 size_t mapping_size;
47 void * result;
48 size_t page_size;
49 off_t delta;
50
51 page_size = getpagesize();
52 delta = offset % page_size;
53
54 mapping = mmap(NULL, length + offset, prot, flags, fd, offset - delta);
55 if (mapping == MAP_FAILED)
56 return -1;
57
58 result = ((char *) mapping) + delta;
59
60 mapping_size = length + offset;
61
62 * pmapping = mapping;
63 * pmapping_size = mapping_size;
64 * presult = result;
65
66 return 0;
67}
diff --git a/libetpan/src/data-types/mapping.h b/libetpan/src/data-types/mapping.h
new file mode 100644
index 0000000..d33f035
--- a/dev/null
+++ b/libetpan/src/data-types/mapping.h
@@ -0,0 +1,54 @@
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$
34 */
35
36#ifndef MAPPING_H
37
38#define MAPPING_H
39
40#include <sys/types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46int get_mapping(size_t length, int prot, int flags,
47 int fd, off_t offset,
48 void ** presult, void ** pmapping, size_t * pmapping_size);
49
50#ifdef __cplusplus
51}
52#endif
53
54#endif
diff --git a/libetpan/src/data-types/md5.c b/libetpan/src/data-types/md5.c
new file mode 100644
index 0000000..3c46b5e
--- a/dev/null
+++ b/libetpan/src/data-types/md5.c
@@ -0,0 +1,570 @@
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$
34 */
35
36/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
37*/
38
39/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
40rights reserved.
41
42License to copy and use this software is granted provided that it
43is identified as the "RSA Data Security, Inc. MD5 Message-Digest
44Algorithm" in all material mentioning or referencing this software
45or this function.
46
47License is also granted to make and use derivative works provided
48that such works are identified as "derived from the RSA Data
49Security, Inc. MD5 Message-Digest Algorithm" in all material
50mentioning or referencing the derived work.
51
52RSA Data Security, Inc. makes no representations concerning either
53the merchantability of this software or the suitability of this
54software for any particular purpose. It is provided "as is"
55without express or implied warranty of any kind.
56
57These notices must be retained in any copies of any part of this
58documentation and/or software.
59*/
60
61/* do i need all of this just for htonl()? damn. */
62#include <sys/types.h>
63#include <sys/param.h>
64#include <sys/socket.h>
65#include <netinet/in.h>
66
67#include "md5global.h"
68#include "md5.h"
69#include "hmac-md5.h"
70
71/* Constants for MD5Transform routine.
72*/
73
74#define S11 7
75#define S12 12
76#define S13 17
77#define S14 22
78#define S21 5
79#define S22 9
80#define S23 14
81#define S24 20
82#define S31 4
83#define S32 11
84#define S33 16
85#define S34 23
86#define S41 6
87#define S42 10
88#define S43 15
89#define S44 21
90
91static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
92static void Encode PROTO_LIST
93 ((unsigned char *, UINT4 *, unsigned int));
94static void Decode PROTO_LIST
95 ((UINT4 *, unsigned char *, unsigned int));
96static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
97static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));
98
99static unsigned char PADDING[64] = {
100 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
101 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
102};
103
104/* F, G, H and I are basic MD5 functions.
105
106 */
107#ifdef I
108/* This might be defined via NANA */
109#undef I
110#endif
111
112#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
113#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
114#define H(x, y, z) ((x) ^ (y) ^ (z))
115#define I(x, y, z) ((y) ^ ((x) | (~z)))
116
117/* ROTATE_LEFT rotates x left n bits.
118
119 */
120
121#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
122
123/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
124Rotation is separate from addition to prevent recomputation.
125*/
126
127#define FF(a, b, c, d, x, s, ac) { (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); }
128#define GG(a, b, c, d, x, s, ac) { (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); }
129#define HH(a, b, c, d, x, s, ac) { (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); }
130#define II(a, b, c, d, x, s, ac) { (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); }
131
132/* MD5 initialization. Begins an MD5 operation, writing a new context.
133*/
134
135void MD5Init (context)
136MD5_CTX *context; /* context */
137{
138 context->count[0] = context->count[1] = 0;
139
140 /* Load magic initialization constants.
141
142*/
143 context->state[0] = 0x67452301;
144 context->state[1] = 0xefcdab89;
145 context->state[2] = 0x98badcfe;
146 context->state[3] = 0x10325476;
147}
148
149/* MD5 block update operation. Continues an MD5 message-digest
150 operation, processing another message block, and updating the context.
151*/
152
153void MD5Update (context, input, inputLen)
154MD5_CTX *context; /* context */
155unsigned char *input; /* input block */
156unsigned int inputLen; /* length of input block */
157{
158 unsigned int i, index, partLen;
159
160 /* Compute number of bytes mod 64 */
161 index = (unsigned int)((context->count[0] >> 3) & 0x3F);
162
163 /* Update number of bits */
164 if ((context->count[0] += ((UINT4)inputLen << 3))
165 < ((UINT4)inputLen << 3))
166 context->count[1]++;
167 context->count[1] += ((UINT4)inputLen >> 29);
168
169 partLen = 64 - index;
170
171 /* Transform as many times as possible.
172
173*/
174 if (inputLen >= partLen) {
175 MD5_memcpy
176 ((POINTER)&context->buffer[index], (POINTER)input, partLen); MD5Transform
177 (context->state, context->buffer);
178
179 for (i = partLen; i + 63 < inputLen; i += 64)
180 MD5Transform (context->state, &input[i]);
181
182 index = 0;
183 }
184 else
185 i = 0;
186
187 /* Buffer remaining input */
188 MD5_memcpy
189 ((POINTER)&context->buffer[index], (POINTER)&input[i],
190 inputLen-i);
191
192}
193
194/* MD5 finalization. Ends an MD5 message-digest operation, writing the
195 the message digest and zeroizing the context.
196
197 */
198
199void MD5Final (digest, context)
200unsigned char digest[16]; /* message digest */
201MD5_CTX *context; /* context */
202{
203 unsigned char bits[8];
204 unsigned int index, padLen;
205
206 /* Save number of bits */
207 Encode (bits, context->count, 8);
208
209 /* Pad out to 56 mod 64.
210
211*/
212 index = (unsigned int)((context->count[0] >> 3) & 0x3f);
213 padLen = (index < 56) ? (56 - index) : (120 - index);
214 MD5Update (context, PADDING, padLen);
215
216 /* Append length (before padding) */
217 MD5Update (context, bits, 8);
218
219 /* Store state in digest */
220 Encode (digest, context->state, 16);
221
222 /* Zeroize sensitive information.
223
224*/
225 MD5_memset ((POINTER)context, 0, sizeof (*context));
226}
227
228/* MD5 basic transformation. Transforms state based on block.
229
230 */
231
232static void MD5Transform (state, block)
233UINT4 state[4];
234unsigned char block[64];
235{
236 UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
237
238 Decode (x, block, 64);
239
240 /* Round 1 */
241 FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
242 FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
243 FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
244 FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
245 FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
246 FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
247 FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
248 FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
249 FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
250 FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
251 FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
252 FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
253 FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
254 FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
255 FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
256 FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
257
258 /* Round 2 */
259 GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
260 GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
261 GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
262 GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
263 GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
264 GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
265 GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
266 GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
267 GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
268 GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
269 GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
270 GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
271 GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
272 GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
273 GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
274 GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
275
276 /* Round 3 */
277 HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
278 HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
279 HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
280 HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
281 HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
282 HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
283 HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
284 HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
285 HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
286 HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
287 HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
288 HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
289 HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
290 HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
291 HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
292 HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
293
294 /* Round 4 */
295 II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
296 II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
297 II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
298 II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
299 II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
300 II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
301 II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
302 II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
303 II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
304 II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
305 II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
306 II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
307 II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
308 II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
309 II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
310 II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
311
312 state[0] += a;
313 state[1] += b;
314 state[2] += c;
315 state[3] += d;
316
317 /* Zeroize sensitive information.
318 */
319 MD5_memset ((POINTER)x, 0, sizeof (x));
320}
321
322/* Encodes input (UINT4) into output (unsigned char). Assumes len is
323 a multiple of 4.
324
325 */
326
327static void Encode (output, input, len)
328unsigned char *output;
329UINT4 *input;
330unsigned int len;
331{
332 unsigned int i, j;
333
334 for (i = 0, j = 0; j < len; i++, j += 4) {
335 output[j] = (unsigned char)(input[i] & 0xff);
336 output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
337 output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
338 output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
339 }
340}
341
342/* Decodes input (unsigned char) into output (UINT4). Assumes len is
343 a multiple of 4.
344
345 */
346
347static void Decode (output, input, len)
348UINT4 *output;
349unsigned char *input;
350unsigned int len;
351{
352 unsigned int i, j;
353
354 for (i = 0, j = 0; j < len; i++, j += 4)
355 output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | (((UINT4)input[j+2]) << 16)
356 | (((UINT4)input[j+3]) << 24);
357}
358
359/* Note: Replace "for loop" with standard memcpy if possible.
360
361 */
362
363static void MD5_memcpy (output, input, len)
364POINTER output;
365POINTER input;
366unsigned int len;
367{
368 unsigned int i;
369
370 for (i = 0; i < len; i++)
371 output[i] = input[i];
372}
373
374/* Note: Replace "for loop" with standard memset if possible.
375*/
376
377static void MD5_memset (output, value, len)
378POINTER output;
379int value;
380unsigned int len;
381{
382 unsigned int i;
383
384 for (i = 0; i < len; i++)
385 ((char *)output)[i] = (char)value;
386}
387
388void hmac_md5_init(HMAC_MD5_CTX *hmac,
389 const unsigned char *key,
390 int key_len)
391{
392 unsigned char k_ipad[65]; /* inner padding -
393 * key XORd with ipad
394 */
395 unsigned char k_opad[65]; /* outer padding -
396 * key XORd with opad
397 */
398 unsigned char tk[16];
399 int i;
400 /* if key is longer than 64 bytes reset it to key=MD5(key) */
401 if (key_len > 64) {
402
403 MD5_CTX tctx;
404
405 MD5Init(&tctx);
406 MD5Update(&tctx, key, key_len);
407 MD5Final(tk, &tctx);
408
409 key = tk;
410 key_len = 16;
411 }
412
413 /*
414 * the HMAC_MD5 transform looks like:
415 *
416 * MD5(K XOR opad, MD5(K XOR ipad, text))
417 *
418 * where K is an n byte key
419 * ipad is the byte 0x36 repeated 64 times
420 * opad is the byte 0x5c repeated 64 times
421 * and text is the data being protected
422 */
423
424 /* start out by storing key in pads */
425 MD5_memset(k_ipad, '\0', sizeof k_ipad);
426 MD5_memset(k_opad, '\0', sizeof k_opad);
427 MD5_memcpy( k_ipad, key, key_len);
428 MD5_memcpy( k_opad, key, key_len);
429
430 /* XOR key with ipad and opad values */
431 for (i=0; i<64; i++) {
432 k_ipad[i] ^= 0x36;
433 k_opad[i] ^= 0x5c;
434 }
435
436 MD5Init(&hmac->ictx); /* init inner context */
437 MD5Update(&hmac->ictx, k_ipad, 64); /* apply inner pad */
438
439 MD5Init(&hmac->octx); /* init outer context */
440 MD5Update(&hmac->octx, k_opad, 64); /* apply outer pad */
441
442 /* scrub the pads and key context (if used) */
443 MD5_memset(&k_ipad, 0, sizeof(k_ipad));
444 MD5_memset(&k_opad, 0, sizeof(k_opad));
445 MD5_memset(&tk, 0, sizeof(tk));
446
447 /* and we're done. */
448}
449
450/* The precalc and import routines here rely on the fact that we pad
451 * the key out to 64 bytes and use that to initialize the md5
452 * contexts, and that updating an md5 context with 64 bytes of data
453 * leaves nothing left over; all of the interesting state is contained
454 * in the state field, and none of it is left over in the count and
455 * buffer fields. So all we have to do is save the state field; we
456 * can zero the others when we reload it. Which is why the decision
457 * was made to pad the key out to 64 bytes in the first place. */
458void hmac_md5_precalc(HMAC_MD5_STATE *state,
459 const unsigned char *key,
460 int key_len)
461{
462 HMAC_MD5_CTX hmac;
463 unsigned lupe;
464
465 hmac_md5_init(&hmac, key, key_len);
466 for (lupe = 0; lupe < 4; lupe++) {
467 state->istate[lupe] = htonl(hmac.ictx.state[lupe]);
468 state->ostate[lupe] = htonl(hmac.octx.state[lupe]);
469 }
470 MD5_memset(&hmac, 0, sizeof(hmac));
471}
472
473
474void hmac_md5_import(HMAC_MD5_CTX *hmac,
475 HMAC_MD5_STATE *state)
476{
477 unsigned lupe;
478 MD5_memset(hmac, 0, sizeof(HMAC_MD5_CTX));
479 for (lupe = 0; lupe < 4; lupe++) {
480 hmac->ictx.state[lupe] = ntohl(state->istate[lupe]);
481 hmac->octx.state[lupe] = ntohl(state->ostate[lupe]);
482 }
483 /* Init the counts to account for our having applied
484 * 64 bytes of key; this works out to 0x200 (64 << 3; see
485 * MD5Update above...) */
486 hmac->ictx.count[0] = hmac->octx.count[0] = 0x200;
487}
488
489void hmac_md5_final(unsigned char digest[HMAC_MD5_SIZE],
490 HMAC_MD5_CTX *hmac)
491{
492 MD5Final(digest, &hmac->ictx); /* Finalize inner md5 */
493 MD5Update(&hmac->octx, digest, 16); /* Update outer ctx */
494 MD5Final(digest, &hmac->octx); /* Finalize outer md5 */
495}
496
497
498void hmac_md5(text, text_len, key, key_len, digest)
499const unsigned char* text; /* pointer to data stream */
500int text_len; /* length of data stream */
501const unsigned char* key; /* pointer to authentication key */
502int key_len; /* length of authentication key */
503unsigned char *digest; /* caller digest to be filled in */
504{
505 MD5_CTX context;
506
507 unsigned char k_ipad[65]; /* inner padding -
508 * key XORd with ipad
509 */
510 unsigned char k_opad[65]; /* outer padding -
511 * key XORd with opad
512 */
513 unsigned char tk[16];
514 int i;
515 /* if key is longer than 64 bytes reset it to key=MD5(key) */
516 if (key_len > 64) {
517
518 MD5_CTX tctx;
519
520 MD5Init(&tctx);
521 MD5Update(&tctx, key, key_len);
522 MD5Final(tk, &tctx);
523
524 key = tk;
525 key_len = 16;
526 }
527
528 /*
529 * the HMAC_MD5 transform looks like:
530 *
531 * MD5(K XOR opad, MD5(K XOR ipad, text))
532 *
533 * where K is an n byte key
534 * ipad is the byte 0x36 repeated 64 times
535 * opad is the byte 0x5c repeated 64 times
536 * and text is the data being protected
537 */
538
539 /* start out by storing key in pads */
540 MD5_memset(k_ipad, '\0', sizeof k_ipad);
541 MD5_memset(k_opad, '\0', sizeof k_opad);
542 MD5_memcpy( k_ipad, key, key_len);
543 MD5_memcpy( k_opad, key, key_len);
544
545 /* XOR key with ipad and opad values */
546 for (i=0; i<64; i++) {
547 k_ipad[i] ^= 0x36;
548 k_opad[i] ^= 0x5c;
549 }
550 /*
551 * perform inner MD5
552 */
553
554 MD5Init(&context); /* init context for 1st
555 * pass */
556 MD5Update(&context, k_ipad, 64); /* start with inner pad */
557 MD5Update(&context, text, text_len); /* then text of datagram */
558 MD5Final(digest, &context); /* finish up 1st pass */
559
560 /*
561 * perform outer MD5
562 */
563 MD5Init(&context); /* init context for 2nd
564 * pass */
565 MD5Update(&context, k_opad, 64); /* start with outer pad */
566 MD5Update(&context, digest, 16); /* then results of 1st
567 * hash */
568 MD5Final(digest, &context); /* finish up 2nd pass */
569
570}
diff --git a/libetpan/src/data-types/md5.h b/libetpan/src/data-types/md5.h
new file mode 100644
index 0000000..971652e
--- a/dev/null
+++ b/libetpan/src/data-types/md5.h
@@ -0,0 +1,88 @@
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$
34 */
35
36/* MD5.H - header file for MD5C.C
37 */
38
39/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
40rights reserved.
41
42License to copy and use this software is granted provided that it
43is identified as the "RSA Data Security, Inc. MD5 Message-Digest
44Algorithm" in all material mentioning or referencing this software
45or this function.
46
47License is also granted to make and use derivative works provided
48that such works are identified as "derived from the RSA Data
49Security, Inc. MD5 Message-Digest Algorithm" in all material
50mentioning or referencing the derived work.
51
52RSA Data Security, Inc. makes no representations concerning either
53the merchantability of this software or the suitability of this
54software for any particular purpose. It is provided "as is"
55without express or implied warranty of any kind.
56These notices must be retained in any copies of any part of this
57documentation and/or software.
58 */
59
60#include "md5global.h"
61
62#ifndef MD5_H
63
64#define MD5_H
65
66#ifdef __cplusplus
67extern "C" {
68#endif
69
70/* MD5 context. */
71typedef struct {
72 UINT4 state[4]; /* state (ABCD) */
73 UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
74 unsigned char buffer[64]; /* input buffer */
75} MD5_CTX;
76
77void MD5Init PROTO_LIST ((MD5_CTX *));
78void MD5Update PROTO_LIST
79 ((MD5_CTX *, unsigned char *, unsigned int));
80void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *));
81
82void hmac_md5 PROTO_LIST ((unsigned char *, int, unsigned char *, int, caddr_t));
83
84#ifdef __cplusplus
85}
86#endif
87
88#endif
diff --git a/libetpan/src/data-types/md5global.h b/libetpan/src/data-types/md5global.h
new file mode 100644
index 0000000..093d0c9
--- a/dev/null
+++ b/libetpan/src/data-types/md5global.h
@@ -0,0 +1,79 @@
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$
34 */
35
36/* GLOBAL.H - RSAREF types and constants
37 */
38
39#ifndef MD5GLOBAL_H
40
41#define MD5GLOBAL_H
42
43#ifdef __cplusplus
44extern "C" {
45#endif
46
47/* PROTOTYPES should be set to one if and only if the compiler supports
48 function argument prototyping.
49The following makes PROTOTYPES default to 0 if it has not already
50 been defined with C compiler flags.
51 */
52#ifndef PROTOTYPES
53#define PROTOTYPES 0
54#endif
55
56/* POINTER defines a generic pointer type */
57typedef unsigned char *POINTER;
58
59/* UINT2 defines a two byte word */
60typedef unsigned short int UINT2;
61
62/* UINT4 defines a four byte word */
63typedef unsigned long int UINT4;
64
65/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
66If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
67 returns an empty list.
68 */
69#if PROTOTYPES
70#define PROTO_LIST(list) list
71#else
72#define PROTO_LIST(list) ()
73#endif
74
75#ifdef __cplusplus
76}
77#endif
78
79#endif
diff --git a/libetpan/src/data-types/mmapstring.c b/libetpan/src/data-types/mmapstring.c
new file mode 100644
index 0000000..37c681c
--- a/dev/null
+++ b/libetpan/src/data-types/mmapstring.c
@@ -0,0 +1,551 @@
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$
34 */
35
36#include "mmapstring.h"
37
38#include "chash.h"
39
40#ifndef CONFIG_H
41#define CONFIG_H
42#include "config.h"
43#endif
44
45#include <stdlib.h>
46#include <unistd.h>
47#include <sys/mman.h>
48#include <string.h>
49#ifdef LIBETPAN_REENTRANT
50#include <pthread.h>
51#endif
52
53#include "libetpan-config.h"
54
55#define MMAPSTRING_MAX(a, b) ((a) > (b) ? (a) : (b))
56#define MMAPSTRING_MIN(a, b) ((a) < (b) ? (a) : (b))
57
58#define MMAP_STRING_DEFAULT_CEIL (8 * 1024 * 1024)
59
60#define DEFAULT_TMP_PATH "/tmp"
61
62static char tmpdir[PATH_MAX] = DEFAULT_TMP_PATH;
63
64static size_t mmap_string_ceil = MMAP_STRING_DEFAULT_CEIL;
65
66/* MMAPString references */
67
68#ifdef LIBETPAN_REENTRANT
69static pthread_mutex_t mmapstring_lock = PTHREAD_MUTEX_INITIALIZER;
70#endif
71static chash * mmapstring_hashtable = NULL;
72
73static void mmapstring_hashtable_init()
74{
75 mmapstring_hashtable = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYKEY);
76}
77
78void mmap_string_set_tmpdir(char * directory)
79{
80 strncpy(tmpdir, directory, PATH_MAX);
81 tmpdir[PATH_MAX - 1] = 0;
82}
83
84
85int mmap_string_ref(MMAPString * string)
86{
87 chash * ht;
88 int r;
89 chashdatum key;
90 chashdatum data;
91
92#ifdef LIBETPAN_REENTRANT
93 pthread_mutex_lock(&mmapstring_lock);
94#endif
95 if (mmapstring_hashtable == NULL) {
96 mmapstring_hashtable_init();
97 }
98 ht = mmapstring_hashtable;
99
100 if (ht == NULL) {
101#ifdef LIBETPAN_REENTRANT
102 pthread_mutex_unlock(&mmapstring_lock);
103#endif
104 return -1;
105 }
106
107 key.data = &string->str;
108 key.len = sizeof(string->str);
109 data.data = string;
110 data.len = 0;
111
112 r = chash_set(mmapstring_hashtable, &key, &data, NULL);
113#ifdef LIBETPAN_REENTRANT
114 pthread_mutex_unlock(&mmapstring_lock);
115#endif
116
117 if (r < 0)
118 return r;
119
120 return 0;
121}
122
123int mmap_string_unref(char * str)
124{
125 MMAPString * string;
126 chash * ht;
127 chashdatum key;
128 chashdatum data;
129 int r;
130
131#ifdef LIBETPAN_REENTRANT
132 pthread_mutex_lock(&mmapstring_lock);
133#endif
134 ht = mmapstring_hashtable;
135
136 if (ht == NULL) {
137#ifdef LIBETPAN_REENTRANT
138 pthread_mutex_unlock(&mmapstring_lock);
139#endif
140 return -1;
141 }
142
143 key.data = &str;
144 key.len = sizeof(str);
145
146 r = chash_get(ht, &key, &data);
147 if (r < 0)
148 string = NULL;
149 else
150 string = data.data;
151
152 if (string != NULL) {
153 chash_delete(ht, &key, NULL);
154 if (chash_count(ht) == 0) {
155 chash_free(ht);
156 mmapstring_hashtable = NULL;
157 }
158 }
159
160#ifdef LIBETPAN_REENTRANT
161 pthread_mutex_unlock(&mmapstring_lock);
162#endif
163
164 if (string != NULL) {
165 mmap_string_free(string);
166 return 0;
167 }
168 else
169 return -1;
170}
171
172
173
174/* MMAPString */
175
176#define MY_MAXSIZE ((size_t) -1)
177
178static inline size_t
179nearest_power (size_t base, size_t num)
180{
181 if (num > MY_MAXSIZE / 2) {
182 return MY_MAXSIZE;
183 }
184 else {
185 size_t n = base;
186
187 while (n < num)
188 n <<= 1;
189
190 return n;
191 }
192}
193
194void mmap_string_set_ceil(size_t ceil)
195{
196 mmap_string_ceil = ceil;
197}
198
199/* Strings.
200 */
201
202static MMAPString * mmap_string_realloc_file(MMAPString * string)
203{
204 char * data;
205
206 if (string->fd == -1) {
207 char tmpfilename[PATH_MAX];
208 int fd;
209
210 * tmpfilename = 0;
211 strcat(tmpfilename, tmpdir);
212 strcat(tmpfilename, "/libetpan-mmapstring-XXXXXX");
213
214 fd = mkstemp(tmpfilename);
215 if (fd == -1)
216 return NULL;
217
218 if (unlink(tmpfilename) == -1) {
219 close(fd);
220 return NULL;
221 }
222
223 if (ftruncate(fd, string->allocated_len) == -1) {
224 close(fd);
225 return NULL;
226 }
227
228 data = mmap(NULL, string->allocated_len, PROT_WRITE | PROT_READ,
229 MAP_SHARED, fd, 0);
230
231 if (data == MAP_FAILED) {
232 close(fd);
233 return NULL;
234 }
235
236 if (string->str != NULL)
237 memcpy(data, string->str, string->len + 1);
238
239 string->fd = fd;
240 string->mmapped_size = string->allocated_len;
241 free(string->str);
242 string->str = data;
243 }
244 else {
245 if (munmap(string->str, string->mmapped_size) == -1)
246 return NULL;
247
248 if (ftruncate(string->fd, string->allocated_len) == -1)
249 return NULL;
250
251 data = mmap(NULL, string->allocated_len, PROT_WRITE | PROT_READ,
252 MAP_SHARED, string->fd, 0);
253
254 if (data == MAP_FAILED)
255 return NULL;
256
257 string->mmapped_size = string->allocated_len;
258 string->str = data;
259 }
260
261 return string;
262}
263
264static MMAPString * mmap_string_realloc_memory(MMAPString * string)
265{
266 char * tmp;
267
268 tmp = realloc (string->str, string->allocated_len);
269
270 if (tmp == NULL)
271 string = NULL;
272 else
273 string->str = tmp;
274
275 return string;
276}
277
278static MMAPString *
279mmap_string_maybe_expand (MMAPString* string,
280 size_t len)
281{
282 if (string->len + len >= string->allocated_len)
283 {
284 size_t old_size;
285 MMAPString * newstring;
286
287 old_size = string->allocated_len;
288
289 string->allocated_len = nearest_power (1, string->len + len + 1);
290
291#ifndef MMAP_UNAVAILABLE
292 if (string->allocated_len > mmap_string_ceil)
293 newstring = mmap_string_realloc_file(string);
294 else {
295#endif
296 newstring = mmap_string_realloc_memory(string);
297#ifndef MMAP_UNAVAILABLE
298 if (newstring == NULL)
299 newstring = mmap_string_realloc_file(string);
300 }
301#endif
302
303 if (newstring == NULL)
304 string->allocated_len = old_size;
305
306 return newstring;
307 }
308
309 return string;
310}
311
312MMAPString*
313mmap_string_sized_new (size_t dfl_size)
314{
315 MMAPString *string;
316
317 string = malloc(sizeof(* string));
318 if (string == NULL)
319 return NULL;
320
321 string->allocated_len = 0;
322 string->len = 0;
323 string->str = NULL;
324 string->fd = -1;
325 string->mmapped_size = 0;
326
327 if (mmap_string_maybe_expand (string, MMAPSTRING_MAX (dfl_size, 2)) == NULL)
328 return NULL;
329
330 string->str[0] = 0;
331
332 return string;
333}
334
335MMAPString*
336mmap_string_new (const char *init)
337{
338 MMAPString *string;
339
340 string = mmap_string_sized_new (init ? strlen (init) + 2 : 2);
341 if (string == NULL)
342 return NULL;
343
344 if (init)
345 mmap_string_append (string, init);
346
347 return string;
348}
349
350MMAPString*
351mmap_string_new_len (const char *init,
352 size_t len)
353{
354 MMAPString *string;
355
356 if (len <= 0)
357 return mmap_string_new ("");
358 else
359 {
360 string = mmap_string_sized_new (len);
361 if (string == NULL)
362 return string;
363
364 if (init)
365 mmap_string_append_len (string, init, len);
366
367 return string;
368 }
369}
370
371void
372mmap_string_free (MMAPString *string)
373{
374 if (string == NULL)
375 return;
376
377 if (string->fd != -1) {
378 munmap(string->str, string->mmapped_size);
379 close(string->fd);
380 }
381 else {
382 free (string->str);
383 }
384 free(string);
385}
386
387MMAPString*
388mmap_string_assign (MMAPString *string,
389 const char *rval)
390{
391 mmap_string_truncate (string, 0);
392 if (mmap_string_append (string, rval) == NULL)
393 return NULL;
394
395 return string;
396}
397
398MMAPString*
399mmap_string_truncate (MMAPString *string,
400 size_t len)
401{
402 string->len = MMAPSTRING_MIN (len, string->len);
403 string->str[string->len] = 0;
404
405 return string;
406}
407
408/**
409 * mmap_string_set_size:
410 * @string: a #MMAPString
411 * @len: the new length
412 *
413 * Sets the length of a #MMAPString. If the length is less than
414 * the current length, the string will be truncated. If the
415 * length is greater than the current length, the contents
416 * of the newly added area are undefined. (However, as
417 * always, string->str[string->len] will be a nul byte.)
418 *
419 * Return value: @string
420 **/
421MMAPString*
422mmap_string_set_size (MMAPString *string,
423 size_t len)
424{
425 if (len >= string->allocated_len)
426 if (mmap_string_maybe_expand (string, len - string->len) == NULL)
427 return NULL;
428
429 string->len = len;
430 string->str[len] = 0;
431
432 return string;
433}
434
435/*
436static int in_mapped_zone(MMAPString * string, char * val)
437{
438 return (val >= string->str) && (val < string->str + string->mmapped_size);
439}
440*/
441
442MMAPString*
443mmap_string_insert_len (MMAPString *string,
444 size_t pos,
445 const char *val,
446 size_t len)
447{
448 if (mmap_string_maybe_expand (string, len) == NULL)
449 return NULL;
450
451 if (pos < string->len)
452 memmove (string->str + pos + len, string->str + pos, string->len - pos);
453
454 /* insert the new string */
455 memmove (string->str + pos, val, len);
456
457 string->len += len;
458
459 string->str[string->len] = 0;
460
461 return string;
462}
463
464MMAPString*
465mmap_string_append (MMAPString *string,
466 const char *val)
467{
468 return mmap_string_insert_len (string, string->len, val, strlen(val));
469}
470
471MMAPString*
472 mmap_string_append_len (MMAPString *string,
473 const char *val,
474 size_t len)
475{
476 return mmap_string_insert_len (string, string->len, val, len);
477}
478
479MMAPString*
480mmap_string_append_c (MMAPString *string,
481 char c)
482{
483 return mmap_string_insert_c (string, string->len, c);
484}
485
486MMAPString*
487mmap_string_prepend (MMAPString *string,
488 const char *val)
489{
490 return mmap_string_insert_len (string, 0, val, strlen(val));
491}
492
493MMAPString*
494 mmap_string_prepend_len (MMAPString *string,
495 const char *val,
496 size_t len)
497{
498 return mmap_string_insert_len (string, 0, val, len);
499}
500
501MMAPString*
502mmap_string_prepend_c (MMAPString *string,
503 char c)
504{
505 return mmap_string_insert_c (string, 0, c);
506}
507
508MMAPString*
509mmap_string_insert (MMAPString *string,
510 size_t pos,
511 const char *val)
512{
513 return mmap_string_insert_len (string, pos, val, strlen(val));
514}
515
516MMAPString*
517mmap_string_insert_c (MMAPString *string,
518 size_t pos,
519 char c)
520{
521 if (mmap_string_maybe_expand (string, 1) == NULL)
522 return NULL;
523
524 /* If not just an append, move the old stuff */
525 if (pos < string->len)
526 memmove (string->str + pos + 1, string->str + pos, string->len - pos);
527
528 string->str[pos] = c;
529
530 string->len += 1;
531
532 string->str[string->len] = 0;
533
534 return string;
535}
536
537MMAPString*
538mmap_string_erase (MMAPString *string,
539 size_t pos,
540 size_t len)
541{
542 if ((pos + len) < string->len)
543 memmove (string->str + pos, string->str + pos + len,
544 string->len - (pos + len));
545
546 string->len -= len;
547
548 string->str[string->len] = 0;
549
550 return string;
551}
diff --git a/libetpan/src/data-types/mmapstring.h b/libetpan/src/data-types/mmapstring.h
new file mode 100644
index 0000000..573e354
--- a/dev/null
+++ b/libetpan/src/data-types/mmapstring.h
@@ -0,0 +1,136 @@
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$
34 */
35
36#ifndef __MMAP_STRING_H__
37
38#define __MMAP_STRING_H__
39
40#include <sys/types.h>
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46/*
47#define TMPDIR "/tmp"
48*/
49
50typedef struct _MMAPString MMAPString;
51
52struct _MMAPString
53{
54 char * str;
55 size_t len;
56 size_t allocated_len;
57 int fd;
58 size_t mmapped_size;
59 /*
60 char * old_non_mmapped_str;
61 */
62};
63
64/* configure location of mmaped files */
65
66void mmap_string_set_tmpdir(char * directory);
67
68/* Strings
69 */
70
71MMAPString * mmap_string_new (const char * init);
72
73MMAPString * mmap_string_new_len (const char * init,
74 size_t len);
75
76MMAPString * mmap_string_sized_new (size_t dfl_size);
77
78void mmap_string_free (MMAPString * string);
79
80MMAPString * mmap_string_assign (MMAPString * string,
81 const char * rval);
82
83MMAPString * mmap_string_truncate (MMAPString *string,
84 size_t len);
85
86MMAPString * mmap_string_set_size (MMAPString * string,
87 size_t len);
88
89MMAPString * mmap_string_insert_len (MMAPString * string,
90 size_t pos,
91 const char * val,
92 size_t len);
93
94MMAPString * mmap_string_append (MMAPString * string,
95 const char * val);
96
97MMAPString * mmap_string_append_len (MMAPString * string,
98 const char * val,
99 size_t len);
100
101MMAPString * mmap_string_append_c (MMAPString * string,
102 char c);
103
104MMAPString * mmap_string_prepend (MMAPString * string,
105 const char * val);
106
107MMAPString * mmap_string_prepend_c (MMAPString * string,
108 char c);
109
110MMAPString * mmap_string_prepend_len (MMAPString * string,
111 const char * val,
112 size_t len);
113
114MMAPString * mmap_string_insert (MMAPString * string,
115 size_t pos,
116 const char * val);
117
118MMAPString * mmap_string_insert_c (MMAPString *string,
119 size_t pos,
120 char c);
121
122MMAPString * mmap_string_erase(MMAPString * string,
123 size_t pos,
124 size_t len);
125
126void mmap_string_set_ceil(size_t ceil);
127
128int mmap_string_ref(MMAPString * string);
129int mmap_string_unref(char * str);
130
131#ifdef __cplusplus
132}
133#endif
134
135
136#endif /* __MMAP_STRING_H__ */