40 files changed, 6598 insertions, 0 deletions
diff --git a/kmicromail/libetpan/tools/.libs/libtools.a b/kmicromail/libetpan/tools/.libs/libtools.a Binary files differnew file mode 100644 index 0000000..43424ef --- a/dev/null +++ b/kmicromail/libetpan/tools/.libs/libtools.a diff --git a/kmicromail/libetpan/tools/base64.c b/kmicromail/libetpan/tools/base64.c new file mode 100644 index 0000000..1532bac --- a/dev/null +++ b/kmicromail/libetpan/tools/base64.c @@ -0,0 +1,143 @@ +/* + * libEtPan! -- a mail stuff library + * + * Copyright (C) 2001, 2002 - Juergen Graf + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the libEtPan! project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * $Id$ + */ + +#include "base64.h" + +#include <stdlib.h> + +#define OUTPUT_SIZE 513 +#define CHAR64(c) (((c) < 0 || (c) > 127) ? -1 : index_64[(c)]) + +static char index_64[128] = { + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63, + 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1,-1,-1,-1, + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14, + 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1, + -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, + 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1 +}; + +static char basis_64[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +char * encode_base64(const char * in, int len) +{ + char * output, * tmp; + unsigned char oval; + int out_len; + + out_len = ((len + 2) / 3 * 4) + 1; + + if ((len > 0) && (in == NULL)) + return NULL; + + output = malloc(out_len); + if (!output) + return NULL; + + tmp = output; + while (len >= 3) { + *tmp++ = basis_64[in[0] >> 2]; + *tmp++ = basis_64[((in[0] << 4) & 0x30) | (in[1] >> 4)]; + *tmp++ = basis_64[((in[1] << 2) & 0x3c) | (in[2] >> 6)]; + *tmp++ = basis_64[in[2] & 0x3f]; + in += 3; + len -= 3; + } + if (len > 0) { + *tmp++ = basis_64[in[0] >> 2]; + oval = (in[0] << 4) & 0x30; + if (len > 1) oval |= in[1] >> 4; + *tmp++ = basis_64[oval]; + *tmp++ = (len < 2) ? '=' : basis_64[(in[1] << 2) & 0x3c]; + *tmp++ = '='; + } + + *tmp = '\0'; + + return output; +} + +char * decode_base64(const char * in, int len) +{ + char * output, * out; + int i, c1, c2, c3, c4, out_len; + + out_len = 0; + + output = malloc(OUTPUT_SIZE); + if (output == NULL) + return NULL; + out = output; + + if (in[0] == '+' && in[1] == ' ') + in += 2; + + for (i = 0; i < (len / 4); i++) { + c1 = in[0]; + c2 = in[1]; + c3 = in[2]; + c4 = in[3]; + if (CHAR64(c1) == -1 || CHAR64(c2) == -1 || + (c3 != '=' && CHAR64(c3) == -1) || + (c4 != '=' && CHAR64(c4) == -1)) + return NULL; + + in += 4; + *output++ = (CHAR64(c1) << 2) | (CHAR64(c2) >> 4); + if (++out_len >= OUTPUT_SIZE) + return NULL; + + if (c3 != '=') { + *output++ = ((CHAR64(c2) << 4) & 0xf0) | (CHAR64(c3) >> 2); + if (++out_len >= OUTPUT_SIZE) + return NULL; + + if (c4 != '=') { + *output++ = ((CHAR64(c3) << 6) & 0xc0) | CHAR64(c4); + if (++out_len >= OUTPUT_SIZE) + return NULL; + } + } + } + + *output = 0; + + return out; +} + + diff --git a/kmicromail/libetpan/tools/base64.h b/kmicromail/libetpan/tools/base64.h new file mode 100644 index 0000000..aa5f3e5 --- a/dev/null +++ b/kmicromail/libetpan/tools/base64.h @@ -0,0 +1,59 @@ +/* + * libEtPan! -- a mail stuff library + * + * Copyright (C) 2001, 2002 - Juergen Graf + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the libEtPan! project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * $Id$ + */ + +#ifndef BASE64_H +#define BASE64_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * creates (malloc) a new base64 encoded string from a standard 8bit string + * don't forget to free it when time comes ;) + */ +char * encode_base64(const char * in, int len); + +/** + * creates (malloc) a new standard 8bit string from an base64 encoded string + * don't forget to free it when time comes ;) + */ +char * decode_base64(const char * in, int len); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kmicromail/libetpan/tools/carray.c b/kmicromail/libetpan/tools/carray.c new file mode 100644 index 0000000..a8e78c9 --- a/dev/null +++ b/kmicromail/libetpan/tools/carray.c @@ -0,0 +1,143 @@ + +/* + * libEtPan! -- a mail stuff library + * + * carray - Implements simple dynamic pointer arrays + * + * Copyright (c) 1999-2000, Gaël Roualland <gael.roualland@iname.com> + * interface changes - 2002 - DINH Viet Hoa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the libEtPan! project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * $Id$ + */ + +#include <stdlib.h> +#include <string.h> +#include "carray.h" + +carray * carray_new(unsigned int initsize) { + carray * array; + + array = (carray *) malloc(sizeof(carray)); + if (!array) return NULL; + + array->len = 0; + array->max = initsize; + array->array = (void **) malloc(sizeof(void *) * initsize); + if (!array->array) { + free(array); + return NULL; + } + return array; +} + +int carray_add(carray * array, void * data, unsigned int * index) { + int r; + + r = carray_set_size(array, array->len + 1); + if (r < 0) + return r; + + array->array[array->len - 1] = data; + if (index != NULL) + * index = array->len - 1; + + return 0; +} + +int carray_set_size(carray * array, unsigned int new_size) +{ + if (new_size > array->max) { + unsigned int n = array->max * 2; + void * new; + + while (n <= new_size) + n *= 2; + + new = (void **) realloc(array->array, sizeof(void *) * n); + if (!new) + return -1; + array->array = new; + array->max = n; + } + array->len = new_size; + + return 0; +} + +int carray_delete_fast(carray * array, unsigned int indx) { + if (indx >= array->len) + return -1; + + array->array[indx] = NULL; + + return 0; +} + +int carray_delete(carray * array, unsigned int indx) { + if (indx >= array->len) + return -1; + + if (indx != --array->len) + array->array[indx] = array->array[array->len]; + return 0; +} + +int carray_delete_slow(carray * array, unsigned int indx) { + if (indx >= array->len) + return -1; + + if (indx != --array->len) + memmove(array->array + indx, array->array + indx + 1, + (array->len - indx) * sizeof(void *)); + return 0; +} + +#ifdef NO_MACROS +void ** carray_data(carray * array) { + return array->array; +} + +unsigned int carray_count(carray * array) { + return array->len; +} + +void * carray_get(carray * array, unsigned int indx) { + return array->array[indx]; +} + +void carray_set(carray * array, unsigned int indx, void * value) { + array->array[indx] = value; +} +#endif + +void carray_free(carray * array) { + free(array->array); + free(array); +} diff --git a/kmicromail/libetpan/tools/carray.h b/kmicromail/libetpan/tools/carray.h new file mode 100644 index 0000000..06003aa --- a/dev/null +++ b/kmicromail/libetpan/tools/carray.h @@ -0,0 +1,124 @@ + +/* + * libEtPan! -- a mail stuff library + * + * carray - Implements simple dynamic pointer arrays + * + * Copyright (c) 1999-2000, Gaël Roualland <gael.roualland@iname.com> + * interface changes - 2002 - DINH Viet Hoa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the libEtPan! project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * $Id$ + */ + +#ifndef CARRAY_H +#define CARRAY_H + +#ifdef __cplusplus +extern "C" { +#endif + +struct carray_s { + void ** array; + unsigned int len; + unsigned int max; +}; + +typedef struct carray_s carray; + +/* Creates a new array of pointers, with initsize preallocated cells */ +carray * carray_new(unsigned int initsize); + +/* Adds the pointer to data in the array. + Returns the index of the pointer in the array or -1 on error */ +int carray_add(carray * array, void * data, unsigned int * index); + +int carray_set_size(carray * array, unsigned int new_size); + +/* Removes the cell at this index position. Returns TRUE on success. + Order of elements in the array IS changed. */ +int carray_delete(carray * array, unsigned int indx); + +/* Removes the cell at this index position. Returns TRUE on success. + Order of elements in the array IS not changed. */ +int carray_delete_slow(carray * array, unsigned int indx); + +/* remove without decreasing the size of the array */ +int carray_delete_fast(carray * array, unsigned int indx); + +/* Some of the following routines can be implemented as macros to + be faster. If you don't want it, define NO_MACROS */ +#ifdef NO_MACROS + +/* Returns the array itself */ +void ** carray_data(carray *); + +/* Returns the number of elements in the array */ +int carray_count(carray *); + +/* Returns the contents of one cell */ +void * carray_get(carray * array, unsigned int indx); + +/* Sets the contents of one cell */ +void carray_set(carray * array, unsigned int indx, void * value); + +#else + +#if 0 +#define carray_data(a) (a->array) +#define carray_count(a) (a->len) +#define carray_get(a, indx) (a->array[indx]) +#define carray_set(a, indx, v) do { a->array[indx]=v; } while(0) +#endif + +static inline void ** carray_data(carray * array) { + return array->array; +} + +static inline unsigned int carray_count(carray * array) { + return array->len; +} + +static inline void * carray_get(carray * array, unsigned int indx) { + return array->array[indx]; +} + +static inline void carray_set(carray * array, + unsigned int indx, void * value) { + array->array[indx] = value; +} +#endif + +void carray_free(carray * array); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kmicromail/libetpan/tools/charconv.c b/kmicromail/libetpan/tools/charconv.c new file mode 100644 index 0000000..bf3de51 --- a/dev/null +++ b/kmicromail/libetpan/tools/charconv.c @@ -0,0 +1,251 @@ +/* + * libEtPan! -- a mail stuff library + * + * Copyright (C) 2001, 2002 - DINH Viet Hoa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the libEtPan! project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * $Id$ + */ + +#include "charconv.h" + +#include "config.h" +#ifdef HAVE_ICONV +#include <iconv.h> +#endif +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <errno.h> + +#include "mmapstring.h" + +#ifdef HAVE_ICONV +static size_t mail_iconv (iconv_t cd, const char **inbuf, size_t *inbytesleft, + char **outbuf, size_t *outbytesleft, + char **inrepls, char *outrepl) +{ + /* + XXX - force conversion of (* inbuf) to (char *) + because prototype of iconv() is the following : + + size_t iconv(iconv_t cd, char **restrict inbuf, + size_t *restrict inbytesleft, char **restrict outbuf, + size_t *restrict outbytesleft); + */ + + size_t ret = 0, ret1; + char *ib = (char *) *inbuf; + size_t ibl = *inbytesleft; + char *ob = *outbuf; + size_t obl = *outbytesleft; + + for (;;) + { + ret1 = iconv (cd, &ib, &ibl, &ob, &obl); + if (ret1 != (size_t)-1) + ret += ret1; + if (ibl && obl && errno == EILSEQ) + { + if (inrepls) + { + /* Try replacing the input */ + char **t; + for (t = inrepls; *t; t++) + { + char *ib1 = *t; + size_t ibl1 = strlen (*t); + char *ob1 = ob; + size_t obl1 = obl; + iconv (cd, &ib1, &ibl1, &ob1, &obl1); + if (!ibl1) + { + ++ib, --ibl; + ob = ob1, obl = obl1; + ++ret; + break; + } + } + if (*t) + continue; + } + if (outrepl) + { + /* Try replacing the output */ + size_t n = strlen (outrepl); + if (n <= obl) + { + memcpy (ob, outrepl, n); + ++ib, --ibl; + ob += n, obl -= n; + ++ret; + continue; + } + } + } + *inbuf = ib, *inbytesleft = ibl; + *outbuf = ob, *outbytesleft = obl; + return ret; + } +} +#endif + +int charconv(const char * tocode, const char * fromcode, + const char * str, size_t length, + char ** result) +{ +#ifndef HAVE_ICONV + return MAIL_CHARCONV_ERROR_UNKNOWN_CHARSET; +#else + iconv_t conv; + size_t r; + char * out; + char * pout; + size_t out_size; + size_t old_out_size; + size_t count; + int res; + + conv = iconv_open(tocode, fromcode); + if (conv == (iconv_t) -1) { + res = MAIL_CHARCONV_ERROR_UNKNOWN_CHARSET; + goto err; + } + + out_size = 4 * length; + + out = malloc(out_size + 1); + if (out == NULL) { + res = MAIL_CHARCONV_ERROR_MEMORY; + goto close_iconv; + } + + pout = out; + old_out_size = out_size; + + r = mail_iconv(conv, &str, &length, &pout, &out_size, NULL, "?"); + + if (r == (size_t) -1) { + res = MAIL_CHARCONV_ERROR_CONV; + goto free; + } + + iconv_close(conv); + + * pout = '\0'; + count = old_out_size - out_size; + pout = realloc(out, count + 1); + if (pout != NULL) + out = pout; + + * result = out; + + return MAIL_CHARCONV_NO_ERROR; + + free: + free(out); + close_iconv: + iconv_close(conv); + err: + return res; +#endif +}; + +int charconv_buffer(const char * tocode, const char * fromcode, + const char * str, size_t length, + char ** result, size_t * result_len) +{ +#ifndef HAVE_ICONV + return MAIL_CHARCONV_ERROR_UNKNOWN_CHARSET; +#else + iconv_t conv; + size_t iconv_r; + int r; + char * out; + char * pout; + size_t out_size; + size_t old_out_size; + size_t count; + MMAPString * mmapstr; + int res; + + conv = iconv_open(tocode, fromcode); + if (conv == (iconv_t) -1) { + res = MAIL_CHARCONV_ERROR_UNKNOWN_CHARSET; + goto err; + } + + out_size = 4 * length; + + mmapstr = mmap_string_sized_new(out_size + 1); + if (mmapstr == NULL) { + res = MAIL_CHARCONV_ERROR_MEMORY; + goto err; + } + + out = mmapstr->str; + + pout = out; + old_out_size = out_size; + + iconv_r = mail_iconv(conv, &str, &length, &pout, &out_size, NULL, "?"); + + if (iconv_r == (size_t) -1) { + res = MAIL_CHARCONV_ERROR_CONV; + goto free; + } + + iconv_close(conv); + + * pout = '\0'; + + count = old_out_size - out_size; + + r = mmap_string_ref(mmapstr); + if (r < 0) { + res = MAIL_CHARCONV_ERROR_MEMORY; + goto free; + } + + * result = out; + * result_len = count; + + return MAIL_CHARCONV_NO_ERROR; + + free: + mmap_string_free(mmapstr); + err: + return -1; +#endif +}; + +void charconv_buffer_free(char * str) +{ + mmap_string_unref(str); +} diff --git a/kmicromail/libetpan/tools/charconv.h b/kmicromail/libetpan/tools/charconv.h new file mode 100644 index 0000000..5a435ff --- a/dev/null +++ b/kmicromail/libetpan/tools/charconv.h @@ -0,0 +1,67 @@ +/* + * libEtPan! -- a mail stuff library + * + * Copyright (C) 2001, 2002 - DINH Viet Hoa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the libEtPan! project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * $Id$ + */ + +#ifndef CHARCONV_H + +#define CHARCONV_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <sys/types.h> + +enum { + MAIL_CHARCONV_NO_ERROR = 0, + MAIL_CHARCONV_ERROR_UNKNOWN_CHARSET, + MAIL_CHARCONV_ERROR_MEMORY, + MAIL_CHARCONV_ERROR_CONV, +}; + +int charconv(const char * tocode, const char * fromcode, + const char * str, size_t length, + char ** result); + +int charconv_buffer(const char * tocode, const char * fromcode, + const char * str, size_t length, + char ** result, size_t * result_len); + +void charconv_buffer_free(char * str); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kmicromail/libetpan/tools/chash.c b/kmicromail/libetpan/tools/chash.c new file mode 100644 index 0000000..2055221 --- a/dev/null +++ b/kmicromail/libetpan/tools/chash.c @@ -0,0 +1,395 @@ + +/* + * libEtPan! -- a mail stuff library + * + * chash - Implements generic hash tables. + * + * Copyright (c) 1999-2000, Gaël Roualland <gael.roualland@iname.com> + * interface changes - 2002 - DINH Viet Hoa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the libEtPan! project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * $Id$ + */ + +#include <stdlib.h> +#include <string.h> + +#include "chash.h" + +/* This defines the maximum (average) number of entries per bucket. + The hash is resized everytime inserting an entry makes the + average go over that value. */ +#define CHASH_MAXDEPTH 3 + +static inline unsigned int chash_func(const char * key, unsigned int len) { +#if 0 + register unsigned int c = 0, t; + register const char * k = key; + + while (len--) { + c += (c << 4) + *k++; + if ((t = c & 0xF0000000)) { + c ^= t >> 24; + c ^= t; + } + } + return c; +#endif + register unsigned int c = 5381; + register const char * k = key; + + while (len--) { + c = ((c << 5) + c) + *k++; + } + + return c; +} + +static inline char * chash_dup(const void * data, unsigned int len) +{ + void * r; + + r = (char *) malloc(len); + if (!r) + return NULL; + memcpy(r, data, len); + return r; +} + +chash * chash_new(unsigned int size, int flags) +{ + chash * h; + + h = (chash *) malloc(sizeof(chash)); + if (h == NULL) + return NULL; + + h->count = 0; + h->cells = (struct chashcell **) calloc(size, sizeof(struct chashcell *)); + if (h->cells == NULL) { + free(h); + return NULL; + } + h->size = size; + h->copykey = flags & CHASH_COPYKEY; + h->copyvalue = flags & CHASH_COPYVALUE; + + return h; +} + +int chash_get(chash * hash, + chashdatum * key, chashdatum * result) +{ + unsigned int func; + chashiter * iter; + + func = chash_func(key->data, key->len); + + /* look for the key in existing cells */ + iter = hash->cells[func % hash->size]; + while (iter) { + if (iter->key.len == key->len && iter->func == func + && !memcmp(iter->key.data, key->data, key->len)) { + * result = iter->value; /* found */ + + return 0; + } + iter = iter->next; + } + + return -1; +} + +int chash_set(chash * hash, + chashdatum * key, + chashdatum * value, + chashdatum * oldvalue) +{ + unsigned int func, indx; + chashiter * iter, * cell; + int r; + + if (hash->count > hash->size * CHASH_MAXDEPTH) { + r = chash_resize(hash, (hash->count / CHASH_MAXDEPTH) * 2 + 1); + if (r < 0) + goto err; + } + + func = chash_func(key->data, key->len); + indx = func % hash->size; + + /* look for the key in existing cells */ + iter = hash->cells[indx]; + while (iter) { + if (iter->key.len == key->len && iter->func == func + && !memcmp(iter->key.data, key->data, key->len)) { + /* found, replacing entry */ + if (hash->copyvalue) { + char * data; + + data = chash_dup(value->data, value->len); + if (data == NULL) + goto err; + + free(iter->value.data); + iter->value.data = data; + iter->value.len = value->len; + } else { + if (oldvalue != NULL) { + oldvalue->data = iter->value.data; + oldvalue->len = iter->value.len; + } + iter->value.data = value->data; + iter->value.len = value->len; + } + if (!hash->copykey) + iter->key.data = key->data; + + if (oldvalue != NULL) { + oldvalue->data = value->data; + oldvalue->len = value->len; + } + + return 0; + } + iter = iter->next; + } + + if (oldvalue != NULL) { + oldvalue->data = NULL; + oldvalue->len = 0; + } + + /* not found, adding entry */ + cell = (struct chashcell *) malloc(sizeof(struct chashcell)); + if (cell == NULL) + goto err; + + if (hash->copykey) { + cell->key.data = chash_dup(key->data, key->len); + if (cell->key.data == NULL) + goto free; + } + else + cell->key.data = key->data; + + cell->key.len = key->len; + if (hash->copyvalue) { + cell->value.data = chash_dup(value->data, value->len); + if (cell->value.data == NULL) + goto free_key_data; + } + else + cell->value.data = value->data; + + cell->value.len = value->len; + cell->func = func; + cell->next = hash->cells[indx]; + hash->cells[indx] = cell; + hash->count++; + + return 0; + + free_key_data: + if (hash->copykey) + free(cell->key.data); + free: + free(cell); + err: + return -1; +} + +int chash_delete(chash * hash, chashdatum * key, chashdatum * oldvalue) +{ + /* chashdatum result = { NULL, TRUE }; */ + unsigned int func, indx; + chashiter * iter, * old; + + /* + if (!keylen) + keylen = strlen(key) + 1; + */ + + func = chash_func(key->data, key->len); + indx = func % hash->size; + + /* look for the key in existing cells */ + old = NULL; + iter = hash->cells[indx]; + while (iter) { + if (iter->key.len == key->len && iter->func == func + && !memcmp(iter->key.data, key->data, key->len)) { + /* found, deleting */ + if (old) + old->next = iter->next; + else + hash->cells[indx] = iter->next; + if (hash->copykey) + free(iter->key.data); + if (hash->copyvalue) + free(iter->value.data); + else { + if (oldvalue != NULL) { + oldvalue->data = iter->value.data; + oldvalue->len = iter->value.len; + } + } + free(iter); + hash->count--; + return 0; + } + old = iter; + iter = iter->next; + } + + return -1; /* not found */ +} + +void chash_free(chash * hash) { + unsigned int indx; + chashiter * iter, * next; + + /* browse the hash table */ + for(indx = 0; indx < hash->size; indx++) { + iter = hash->cells[indx]; + while (iter) { + next = iter->next; + if (hash->copykey) + free(iter->key.data); + if (hash->copyvalue) + free(iter->value.data); + free(iter); + iter = next; + } + } + free(hash->cells); + free(hash); +} + +void chash_clear(chash * hash) { + unsigned int indx; + chashiter * iter, * next; + + /* browse the hash table */ + for(indx = 0; indx < hash->size; indx++) { + iter = hash->cells[indx]; + while (iter) { + next = iter->next; + if (hash->copykey) + free(iter->key.data); + if (hash->copyvalue) + free(iter->value.data); + free(iter); + iter = next; + } + } + memset(hash->cells, 0, hash->size * sizeof(* hash->cells)); + hash->count = 0; +} + +chashiter * chash_begin(chash * hash) { + chashiter * iter; + unsigned int indx = 0; + + iter = hash->cells[0]; + while(!iter) { + indx++; + if (indx >= hash->size) + return NULL; + iter = hash->cells[indx]; + } + return iter; +} + +chashiter * chash_next(chash * hash, chashiter * iter) { + unsigned int indx; + + if (!iter) + return NULL; + + indx = iter->func % hash->size; + iter = iter->next; + + while(!iter) { + indx++; + if (indx >= hash->size) + return NULL; + iter = hash->cells[indx]; + } + return iter; +} + +int chash_resize(chash * hash, unsigned int size) +{ + struct chashcell ** cells; + unsigned int indx, nindx; + chashiter * iter, * next; + + if (hash->size == size) + return 0; + + cells = (struct chashcell **) calloc(size, sizeof(struct chashcell *)); + if (!cells) + return -1; + + /* browse initial hash and copy items in second hash */ + for(indx = 0; indx < hash->size; indx++) { + iter = hash->cells[indx]; + while (iter) { + next = iter->next; + nindx = iter->func % size; + iter->next = cells[nindx]; + cells[nindx] = iter; + iter = next; + } + } + free(hash->cells); + hash->size = size; + hash->cells = cells; + + return 0; +} + +#ifdef NO_MACROS +int chash_count(chash * hash) { + return hash->count; +} + +int chash_size(chash * hash) { + return hash->size; +} + +void chash_value(chashiter * iter, chashdatum * result) { + * result = iter->value; +} + +void chash_key(chashiter * iter, chashdatum * result) { + * result = iter->key; +} +#endif diff --git a/kmicromail/libetpan/tools/chash.h b/kmicromail/libetpan/tools/chash.h new file mode 100644 index 0000000..3b2b7d3 --- a/dev/null +++ b/kmicromail/libetpan/tools/chash.h @@ -0,0 +1,166 @@ + +/* + * libEtPan! -- a mail stuff library + * + * chash - Implements generic hash tables. + * + * Copyright (c) 1999-2000, Gaël Roualland <gael.roualland@iname.com> + * interface changes - 2002 - DINH Viet Hoa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the libEtPan! project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * $Id$ + */ + +#ifndef CHASH_H +#define CHASH_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + void * data; + unsigned int len; +} chashdatum; + +struct chash { + unsigned int size; + unsigned int count; + int copyvalue; + int copykey; + struct chashcell ** cells; +}; + +typedef struct chash chash; + +struct chashcell { + unsigned int func; + chashdatum key; + chashdatum value; + struct chashcell * next; +}; + +typedef struct chashcell chashiter; + +#define CHASH_COPYNONE 0 +#define CHASH_COPYKEY 1 +#define CHASH_COPYVALUE 2 +#define CHASH_COPYALL (CHASH_COPYKEY | CHASH_COPYVALUE) + +#define CHASH_DEFAULTSIZE 13 + +/* Allocates a new (empty) hash using this initial size and the given flags, + specifying which data should be copied in the hash. + CHASH_COPYNONE : Keys/Values are not copied. + CHASH_COPYKEY : Keys are dupped and freed as needed in the hash. + CHASH_COPYVALUE : Values are dupped and freed as needed in the hash. + CHASH_COPYALL : Both keys and values are dupped in the hash. + */ +chash * chash_new(unsigned int size, int flags); + +/* Frees a hash */ +void chash_free(chash * hash); + +/* Removes all elements from a hash */ +void chash_clear(chash * hash); + +/* Adds an entry in the hash table. + Length can be 0 if key/value are strings. + If an entry already exists for this key, it is replaced, and its value + is returned. Otherwise, the data pointer will be NULL and the length + field be set to TRUE or FALSe to indicate success or failure. */ +int chash_set(chash * hash, + chashdatum * key, + chashdatum * value, + chashdatum * oldvalue); + +/* Retrieves the data associated to the key if it is found in the hash table. + The data pointer and the length will be NULL if not found*/ +int chash_get(chash * hash, + chashdatum * key, chashdatum * result); + +/* Removes the entry associated to this key if it is found in the hash table, + and returns its contents if not dupped (otherwise, pointer will be NULL + and len TRUE). If entry is not found both pointer and len will be NULL. */ +int chash_delete(chash * hash, + chashdatum * key, + chashdatum * oldvalue); + +/* Resizes the hash table to the passed size. */ +int chash_resize(chash * hash, unsigned int size); + +/* Returns an iterator to the first non-empty entry of the hash table */ +chashiter * chash_begin(chash * hash); + +/* Returns the next non-empty entry of the hash table */ +chashiter * chash_next(chash * hash, chashiter * iter); + +/* Some of the following routines can be implemented as macros to + be faster. If you don't want it, define NO_MACROS */ +#ifdef NO_MACROS +/* Returns the size of the hash table */ +unsigned int chash_size(chash * hash); + +/* Returns the number of entries in the hash table */ +unsigned int chash_count(chash * hash); + +/* Returns the key part of the entry pointed by the iterator */ +void chash_key(chashiter * iter, chashdatum * result); + +/* Returns the value part of the entry pointed by the iterator */ +void chash_value(chashiter * iter, chashdatum * result); + +#else +static inline unsigned int chash_size(chash * hash) +{ + return hash->size; +} + +static inline unsigned int chash_count(chash * hash) +{ + return hash->count; +} + +static inline void chash_key(chashiter * iter, chashdatum * result) +{ + * result = iter->key; +} + +static inline void chash_value(chashiter * iter, chashdatum * result) +{ + * result = iter->value; +} + +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kmicromail/libetpan/tools/cinthash.c b/kmicromail/libetpan/tools/cinthash.c new file mode 100644 index 0000000..02ee727 --- a/dev/null +++ b/kmicromail/libetpan/tools/cinthash.c @@ -0,0 +1,248 @@ +/* + * libEtPan! -- a mail stuff library + * + * Copyright (C) 2001, 2002 - DINH Viet Hoa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the libEtPan! project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * $Id$ + */ + +#include <stdlib.h> +#include "cinthash.h" + +struct cinthash_list { + unsigned long hash; + void * data; + struct cinthash_list * next; +}; + +static struct cinthash_list HASH_LISTHEAD_NEW = { 0, NULL, NULL }; + +static inline int hash_list_add(cinthash_t * table, + unsigned long hash, void * data) +{ + struct cinthash_list * ht; + int index; + + index = hash % table->hashtable_size; + + ht = malloc(sizeof(struct cinthash_list)); + if (ht == NULL) + return -1; + + ht->hash = hash; + ht->data = data; + ht->next = table->table[index].next; + + table->table[index].next = ht; + + return 0; +} + +static inline void hash_list_free(struct cinthash_list * list) +{ + struct cinthash_list * cur; + struct cinthash_list * next; + + next = list; + while (next != NULL) { + cur = next; + next = cur->next; + free(cur); + } +} + +static inline int hash_list_remove(cinthash_t * table, unsigned long hash) +{ + struct cinthash_list * cur; + int index; + + index = hash % table->hashtable_size; + + for(cur = &table->table[index] ; cur->next != NULL ; cur = cur->next) { + if (cur->next->hash == hash) { + struct cinthash_list * hash_data; + + hash_data = cur->next; + cur->next = cur->next->next; + + free(hash_data); + + return 0; + } + } + + return -1; +} + +static inline void * hash_list_find(cinthash_t * table, unsigned long hash) +{ + struct cinthash_list * cur; + int index; + + index = hash % table->hashtable_size; + + for(cur = table->table[index].next ; cur != NULL ; cur = cur->next) { + if (cur->hash == hash) + return cur->data; + } + + return NULL; +} + +cinthash_t * cinthash_new(unsigned long hashtable_size) +{ + cinthash_t * ht; + unsigned long i; + + ht = malloc(sizeof(cinthash_t)); + if (ht == NULL) + return NULL; + + ht->table = malloc(sizeof(struct cinthash_list) * hashtable_size); + if (ht->table == NULL) + return NULL; + + ht->hashtable_size = hashtable_size; + ht->count = 0; + + for(i = 0 ; i < hashtable_size ; i++) + ht->table[i] = HASH_LISTHEAD_NEW; + + return ht; +} + +void cinthash_free(cinthash_t * table) +{ + unsigned long i; + + for(i = 0 ; i < table->hashtable_size ; i++) + hash_list_free(table->table[i].next); + + free(table->table); + + free(table); +} + +int cinthash_add(cinthash_t * table, unsigned long hash, void * data) +{ + int index; + + index = hash % table->hashtable_size; + + if (table->table[index].data == NULL) { + table->table[index].hash = hash; + table->table[index].data = data; + table->table[index].next = NULL; + + table->count ++; + + return 0; + } + else { + int r; + + r = hash_list_add(table, hash, data); + if (r == -1) + return -1; + + table->count ++; + + return 0; + } +} + +int cinthash_remove(cinthash_t * table, unsigned long hash) +{ + int index; + + index = hash % table->hashtable_size; + + if (table->table[index].hash == hash) { + table->table[index].hash = 0; + table->table[index].data = NULL; + + table->count --; + + return 0; + } + else { + int r; + + r = hash_list_remove(table, hash); + + table->count --; + + return 0; + } +} + +void * cinthash_find(cinthash_t * table, unsigned long hash) +{ + int index; + + index = hash % table->hashtable_size; + + if (table->table[index].hash == hash) + return table->table[index].data; + + return hash_list_find(table, hash); +} + +void cinthash_foreach_key(cinthash_t * table, + void (* func)(unsigned long, void *), + void * data) +{ + unsigned long index; + struct cinthash_list * cur; + + for(index = 0 ; index < table->hashtable_size ; index ++) { + if (table->table[index].data != NULL) { + func(table->table[index].hash, data); + for(cur = table->table[index].next ; cur != NULL ; cur = cur->next) + func(cur->hash, data); + } + } +} + +void cinthash_foreach_data(cinthash_t * table, + void (* func)(void *, void *), + void * data) +{ + unsigned long index; + struct cinthash_list * cur; + + for(index = 0 ; index < table->hashtable_size ; index ++) { + if (table->table[index].data != NULL) { + func(table->table[index].data, data); + for(cur = table->table[index].next ; cur != NULL ; cur = cur->next) + func(cur->data, data); + } + } +} diff --git a/kmicromail/libetpan/tools/cinthash.h b/kmicromail/libetpan/tools/cinthash.h new file mode 100644 index 0000000..7e59dff --- a/dev/null +++ b/kmicromail/libetpan/tools/cinthash.h @@ -0,0 +1,69 @@ +/* + * libEtPan! -- a mail stuff library + * + * Copyright (C) 2001, 2002 - DINH Viet Hoa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the libEtPan! project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * $Id$ + */ + +#ifndef CINTHASH_H + +#define CINTHASH_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct cinthash_t { + struct cinthash_list * table; + unsigned long hashtable_size ; + unsigned long count; +} cinthash_t; + +cinthash_t * cinthash_new(unsigned long hashtable_size); +void cinthash_free(cinthash_t * table); + +int cinthash_add(cinthash_t * table, unsigned long hash, void * data); +int cinthash_remove(cinthash_t * table, unsigned long hash); +void * cinthash_find(cinthash_t * table, unsigned long hash); + +void cinthash_foreach_key(cinthash_t * table, + void (* func)(unsigned long, void *), + void * data); + +void cinthash_foreach_data(cinthash_t * table, + void (* fun)(void *, void *), + void * data); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kmicromail/libetpan/tools/clist.c b/kmicromail/libetpan/tools/clist.c new file mode 100644 index 0000000..e5c680d --- a/dev/null +++ b/kmicromail/libetpan/tools/clist.c @@ -0,0 +1,266 @@ + +/* + * libEtPan! -- a mail stuff library + * + * clist - Implements simple generic double-linked pointer lists + * + * Copyright (c) 1999-2000, Gaël Roualland <gael.roualland@iname.com> + * interface changes - 2002 - DINH Viet Hoa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the libEtPan! project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * $Id$ + */ + +#include <stdlib.h> +#include "clist.h" + +clist * clist_new() { + clist * lst; + + lst = (clist *) malloc(sizeof(clist)); + if (!lst) return NULL; + + lst->first = lst->last = NULL; + lst->count = 0; + + return lst; +} + +void clist_free(clist * lst) { + clistcell * l1, * l2; + + l1 = lst->first; + while (l1) { + l2 = l1->next; + free(l1); + l1 = l2; + } + + free(lst); +} + +#ifdef NO_MACROS +int clist_isempty(clist * lst) { + return ((lst->first==lst->last) && (lst->last==NULL)); +} + +clistiter * clist_begin(clist * lst) { + return lst->first; +} + +clistiter * clist_end(clist * lst) { + return lst->last; +} + +clistiter * clist_next(clistiter * iter) { + if (iter) + return iter->next; + else + return NULL; +} + +clistiter * clist_previous(clistiter * iter) { + if (iter) + return iter->previous; + else + return NULL; +} + +void * clist_content(clistiter * iter) { + if (iter) + return iter->data; + else + return NULL; +} + +int clist_count(clist * lst) { + return lst->count; +} + +int clist_prepend(clist * lst, void * data) { + return clist_insert_before(lst, lst->first, data); +} + +int clist_append(clist * lst, void * data) { + return clist_insert_after(lst, lst->last, data); +} +#endif + +int clist_insert_before(clist * lst, clistiter * iter, void * data) { + clistcell * c; + + c = (clistcell *) malloc(sizeof(clistcell)); + if (!c) return -1; + + c->data = data; + lst->count++; + + if (clist_isempty(lst)) { + c->previous = c->next = NULL; + lst->first = lst->last = c; + return 0; + } + + if (!iter) { + c->previous = lst->last; + c->previous->next = c; + c->next = NULL; + lst->last = c; + return 0; + } + + c->previous = iter->previous; + c->next = iter; + c->next->previous = c; + if (c->previous) + c->previous->next = c; + else + lst->first = c; + + return 0; +} + +int clist_insert_after(clist * lst, clistiter * iter, void * data) { + clistcell * c; + + c = (clistcell *) malloc(sizeof(clistcell)); + if (!c) return -1; + + c->data = data; + lst->count++; + + if (clist_isempty(lst)) { + c->previous = c->next = NULL; + lst->first = lst->last = c; + return 0; + } + + if (!iter) { + c->previous = lst->last; + c->previous->next = c; + c->next = NULL; + lst->last = c; + return 0; + } + + c->previous = iter; + c->next = iter->next; + if (c->next) + c->next->previous = c; + else + lst->last = c; + c->previous->next = c; + + return 0; +} + +clistiter * clist_delete(clist * lst, clistiter * iter) { + clistiter * ret; + + if (!iter) return NULL; + + if (iter->previous) + iter->previous->next = iter->next; + else + lst->first = iter->next; + + if (iter->next) { + iter->next->previous = iter->previous; + ret = iter->next; + } else { + lst->last = iter->previous; + ret = NULL; + } + + free(iter); + lst->count--; + + return ret; +} + + + +void clist_foreach(clist * lst, clist_func func, void * data) +{ + clistiter * cur; + + for(cur = clist_begin(lst) ; cur != NULL ; cur = cur->next) + func(cur->data, data); +} + +void clist_concat(clist * dest, clist * src) +{ + if (src->first == NULL) { + /* do nothing */ + } + else if (dest->last == NULL) { + dest->first = src->first; + dest->last = src->last; + } + else { + dest->last->next = src->first; + src->first->previous = dest->last; + dest->last = src->last; + } + + dest->count += src->count; + src->last = src->first = NULL; +} + +static inline clistiter * internal_clist_nth(clist * lst, int index) +{ + clistiter * cur; + + cur = clist_begin(lst); + while ((index > 0) && (cur != NULL)) { + cur = cur->next; + index --; + } + + if (cur == NULL) + return NULL; + + return cur; +} + +void * clist_nth_data(clist * lst, int index) +{ + clistiter * cur; + + cur = internal_clist_nth(lst, index); + if (cur == NULL) + return NULL; + + return cur->data; +} + +clistiter * clist_nth(clist * lst, int index) +{ + return internal_clist_nth(lst, index); +} diff --git a/kmicromail/libetpan/tools/clist.h b/kmicromail/libetpan/tools/clist.h new file mode 100644 index 0000000..bd97f59 --- a/dev/null +++ b/kmicromail/libetpan/tools/clist.h @@ -0,0 +1,134 @@ + +/* + * libEtPan! -- a mail stuff library + * + * clist - Implements simple generic double-linked pointer lists + * + * Copyright (c) 1999-2000, Gaël Roualland <gael.roualland@iname.com> + * interface changes - 2002 - DINH Viet Hoa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the libEtPan! project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * $Id$ + */ + +#ifndef CLIST_H +#define CLIST_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct clistcell_s { + void * data; + struct clistcell_s * previous; + struct clistcell_s * next; +} clistcell; + +struct clist_s { + clistcell * first; + clistcell * last; + int count; +}; + +typedef struct clist_s clist; +typedef clistcell clistiter; + +/* Allocate a new pointer list */ +clist * clist_new(); + +/* Destroys a list. Data pointed by data pointers is NOT freed. */ +void clist_free(clist *); + +/* Some of the following routines can be implemented as macros to + be faster. If you don't want it, define NO_MACROS */ +#ifdef NO_MACROS + +/* Returns TRUE if list is empty */ +int clist_isempty(clist *); + +/* Returns the number of elements in the list */ +int clist_count(clist *); + +/* Returns an iterator to the first element of the list */ +clistiter * clist_begin(clist *); + +/* Returns an iterator to the last element of the list */ +clistiter * clist_end(clist *); + +/* Returns an iterator to the next element of the list */ +clistiter * clist_next(clistiter *); + +/* Returns an iterator to the previous element of the list */ +clistiter * clist_previous(clistiter *); + +/* Returns the data pointer of this element of the list */ +void* clist_content(clistiter *); + +/* Inserts this data pointer at the beginning of the list */ +int clist_prepend(clist *, void *); + +/* Inserts this data pointer at the end of the list */ +int clist_append(clist *, void *); +#else +#define clist_isempty(lst) ((lst->first==lst->last) && (lst->last==NULL)) +#define clist_count(lst) (lst->count) +#define clist_begin(lst) (lst->first) +#define clist_end(lst) (lst->last) +#define clist_next(iter) (iter ? iter->next : NULL) +#define clist_previous(iter) (iter ? iter->previous : NULL) +#define clist_content(iter) (iter ? iter->data : NULL) +#define clist_prepend(lst, data) (clist_insert_before(lst, lst->first, data)) +#define clist_append(lst, data) (clist_insert_after(lst, lst->last, data)) +#endif + +/* Inserts this data pointer before the element pointed by the iterator */ +int clist_insert_before(clist *, clistiter *, void *); + +/* Inserts this data pointer after the element pointed by the iterator */ +int clist_insert_after(clist *, clistiter *, void *); + +/* Deletes the element pointed by the iterator. + Returns an iterator to the next element. */ +clistiter * clist_delete(clist *, clistiter *); + +typedef void (* clist_func)(void *, void *); + +void clist_foreach(clist * lst, clist_func func, void * data); + +void clist_concat(clist * dest, clist * src); + +void * clist_nth_data(clist * lst, int index); + +clistiter * clist_nth(clist * lst, int index); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kmicromail/libetpan/tools/connect.c b/kmicromail/libetpan/tools/connect.c new file mode 100644 index 0000000..c67c18c --- a/dev/null +++ b/kmicromail/libetpan/tools/connect.c @@ -0,0 +1,86 @@ +/* + * libEtPan! -- a mail stuff library + * + * Copyright (C) 2001, 2002 - DINH Viet Hoa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the libEtPan! project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * $Id$ + */ + +#include "connect.h" + +#include <sys/types.h> +#include <string.h> +#include <netdb.h> +#include <netinet/in.h> +#include <sys/socket.h> +#include <unistd.h> + +uint16_t mail_get_service_port(const char * name, char * protocol) +{ + struct servent * service; + + service = getservbyname(name, protocol); + + if (service == NULL) + return 0; + + return service->s_port; +} + +int mail_tcp_connect(const char * server, uint16_t port) +{ + struct hostent * remotehost; + struct sockaddr_in sa; + int s; + int r; + + s = socket(PF_INET, SOCK_STREAM, 0); + if (s == -1) + goto err; + + remotehost = gethostbyname(server); + if (remotehost == NULL) + goto close_socket; + + sa.sin_family = AF_INET; + sa.sin_port = htons(port); + memcpy(&sa.sin_addr, remotehost->h_addr, remotehost->h_length); + + r = connect(s, (struct sockaddr *) &sa, sizeof(struct sockaddr_in)); + if (r == -1) + goto close_socket; + + return s; + + close_socket: + close(s); + err: + return -1; +} diff --git a/kmicromail/libetpan/tools/connect.h b/kmicromail/libetpan/tools/connect.h new file mode 100644 index 0000000..9e44501 --- a/dev/null +++ b/kmicromail/libetpan/tools/connect.h @@ -0,0 +1,54 @@ +/* + * libEtPan! -- a mail stuff library + * + * Copyright (C) 2001, 2002 - DINH Viet Hoa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the libEtPan! project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * $Id$ + */ + +#ifndef CONNECT_H + +#define CONNECT_H + +#include <inttypes.h> + +#ifdef __cplusplus +extern "C" { +#endif + +uint16_t mail_get_service_port(const char * name, char * protocol); +int mail_tcp_connect(const char * server, uint16_t port); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/kmicromail/libetpan/tools/hmac-md5.h b/kmicromail/libetpan/tools/hmac-md5.h new file mode 100644 index 0000000..2ae6098 --- a/dev/null +++ b/kmicromail/libetpan/tools/hmac-md5.h @@ -0,0 +1,94 @@ +/* + * libEtPan! -- a mail stuff library + * + * Copyright (C) 2001, 2002 - DINH Viet Hoa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the libEtPan! project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* hmac-md5.h -- HMAC_MD5 functions + */ + +/* + * $Id$ + */ + +#ifndef HMAC_MD5_H +#define HMAC_MD5_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#define HMAC_MD5_SIZE 16 + +/* intermediate MD5 context */ +typedef struct HMAC_MD5_CTX_s { + MD5_CTX ictx, octx; +} HMAC_MD5_CTX; + +/* intermediate HMAC state + * values stored in network byte order (Big Endian) + */ +typedef struct HMAC_MD5_STATE_s { + UINT4 istate[4]; + UINT4 ostate[4]; +} HMAC_MD5_STATE; + +/* One step hmac computation + * + * digest may be same as text or key + */ +void hmac_md5(const unsigned char *text, int text_len, + const unsigned char *key, int key_len, + unsigned char digest[HMAC_MD5_SIZE]); + +/* create context from key + */ +void hmac_md5_init(HMAC_MD5_CTX *hmac, + const unsigned char *key, int key_len); + +/* precalculate intermediate state from key + */ +void hmac_md5_precalc(HMAC_MD5_STATE *hmac, + const unsigned char *key, int key_len); + +/* initialize context from intermediate state + */ +void hmac_md5_import(HMAC_MD5_CTX *hmac, HMAC_MD5_STATE *state); + +#define hmac_md5_update(hmac, text, text_len) MD5Update(&(hmac)->ictx, (text), (text_len)) + +/* finish hmac from intermediate result. Intermediate result is zeroed. + */ +void hmac_md5_final(unsigned char digest[HMAC_MD5_SIZE], + HMAC_MD5_CTX *hmac); + +#ifdef __cplusplus +} +#endif + +#endif /* HMAC_MD5_H */ diff --git a/kmicromail/libetpan/tools/mail.h b/kmicromail/libetpan/tools/mail.h new file mode 100644 index 0000000..d4c63c4 --- a/dev/null +++ b/kmicromail/libetpan/tools/mail.h @@ -0,0 +1,56 @@ +/* + * libEtPan! -- a mail stuff library + * + * Copyright (C) 2001, 2002 - DINH Viet Hoa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the libEtPan! project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * $Id$ + */ + +#ifndef MAIL_H + +#define MAIL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kmicromail/libetpan/tools/mail_cache_db.c b/kmicromail/libetpan/tools/mail_cache_db.c new file mode 100644 index 0000000..5b6e9c9 --- a/dev/null +++ b/kmicromail/libetpan/tools/mail_cache_db.c @@ -0,0 +1,364 @@ +/* + * libEtPan! -- a mail stuff library + * + * Copyright (C) 2001, 2002 - DINH Viet Hoa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the libEtPan! project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * $Id$ + */ + +#include "mail_cache_db.h" + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdlib.h> +#include <string.h> + +#ifndef CONFIG_H +#define CONFIG_H +#include "config.h" +#endif + +#include "libetpan-config.h" + +#include "maillock.h" + +#if DBVERS >= 1 +#include <db.h> +#endif + +#if DBVERS >= 1 +static struct mail_cache_db * mail_cache_db_new(DB * db) +{ + struct mail_cache_db * cache_db; + + cache_db = malloc(sizeof(* cache_db)); + if (cache_db == NULL) + return NULL; + cache_db->internal_database = db; + + return cache_db; +} + +static void mail_cache_db_free(struct mail_cache_db * cache_db) +{ + free(cache_db); +} +#endif + +int mail_cache_db_open(const char * filename, + struct mail_cache_db ** pcache_db) +{ +#if DBVERS >= 1 + DB * dbp; + int r; + struct mail_cache_db * cache_db; + +#if DB_VERSION_MAJOR >= 3 + r = db_create(&dbp, NULL, 0); + if (r != 0) + goto err; + +#if (DB_VERSION_MAJOR >= 4) && ((DB_VERSION_MAJOR > 4) || (DB_VERSION_MINOR >= 1)) + r = dbp->open(dbp, NULL, filename, NULL, DB_BTREE, DB_CREATE, + S_IRUSR | S_IWUSR); +#else + r = dbp->open(dbp, filename, NULL, DB_BTREE, DB_CREATE, S_IRUSR | S_IWUSR); +#endif + if (r != 0) + goto close_db; +#else +#if DBVERS > 1 + r = db_open(filename, DB_BTREE, DB_CREATE, S_IRUSR | S_IWUSR, + NULL, NULL, &dbp); + if (r != 0) + goto err; +#elif DBVERS == 1 + dbp = dbopen(filename, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, DB_BTREE, NULL); + if (dbp == NULL) + goto err; +#else + goto err; +#endif +#endif + + cache_db = mail_cache_db_new(dbp); + if (cache_db == NULL) + goto close_db; + + * pcache_db = cache_db; + + return 0; + + close_db: +#if DBVERS > 1 + dbp->close(cache_db->internal_database, 0); +#elif DBVERS == 1 + dbp->close(cache_db->internal_database); +#endif + err: + return -1; +#else + return -1; +#endif +} + +void mail_cache_db_close(struct mail_cache_db * cache_db) +{ +#if DBVERS >= 1 + DB * dbp; + + dbp = cache_db->internal_database; + +#if DBVERS > 1 + dbp->close(cache_db->internal_database, 0); +#elif DBVERS == 1 + dbp->close(cache_db->internal_database); +#endif + + mail_cache_db_free(cache_db); +#endif +} + +int mail_cache_db_open_lock(const char * filename, + struct mail_cache_db ** pcache_db) +{ + int r; + struct mail_cache_db * cache_db; + + r = maillock_write_lock(filename, -1); + if (r < 0) + goto err; + + r = mail_cache_db_open(filename, &cache_db); + if (r < 0) + goto unlock; + + * pcache_db = cache_db; + + return 0; + + unlock: + maillock_write_unlock(filename, -1); + err: + return -1; +} + +void mail_cache_db_close_unlock(const char * filename, + struct mail_cache_db * cache_db) +{ + maillock_write_unlock(filename, -1); + mail_cache_db_close(cache_db); +} + + +int mail_cache_db_put(struct mail_cache_db * cache_db, + const void * key, size_t key_len, const void * value, size_t value_len) +{ +#if DBVERS >= 1 + int r; + DBT db_key; + DBT db_data; + DB * dbp; + + dbp = cache_db->internal_database; + + memset(&db_key, 0, sizeof(db_key)); + memset(&db_data, 0, sizeof(db_data)); + db_key.data = (void *) key; + db_key.size = key_len; + db_data.data = (void *) value; + db_data.size = value_len; + +#if DBVERS > 1 + r = dbp->put(dbp, NULL, &db_key, &db_data, 0); +#elif DBVERS == 1 + r = dbp->put(dbp, &db_key, &db_data, 0); +#else + r = -1; +#endif + + return r; +#else + return -1; +#endif +} + +int mail_cache_db_get(struct mail_cache_db * cache_db, + const void * key, size_t key_len, void ** pvalue, size_t * pvalue_len) +{ +#if DBVERS >= 1 + int r; + DBT db_key; + DBT db_data; + DB * dbp; + + dbp = cache_db->internal_database; + + memset(&db_key, 0, sizeof(db_key)); + memset(&db_data, 0, sizeof(db_data)); + db_key.data = (void *) key; + db_key.size = key_len; + +#if DBVERS > 1 + r = dbp->get(dbp, NULL, &db_key, &db_data, 0); +#elif DBVERS == 1 + r = dbp->get(dbp, &db_key, &db_data, 0); +#else + r = -1; +#endif + + if (r != 0) + return r; + + * pvalue = db_data.data; + * pvalue_len = db_data.size; + + return 0; +#else + return -1; +#endif +} + +int mail_cache_db_del(struct mail_cache_db * cache_db, + const void * key, size_t key_len) +{ +#if DBVERS >= 1 + int r; + DBT db_key; + DB * dbp; + + dbp = cache_db->internal_database; + + memset(&db_key, 0, sizeof(db_key)); + db_key.data = (void *) key; + db_key.size = key_len; + +#if DBVERS > 1 + r = dbp->del(dbp, NULL, &db_key, 0); +#elif DBVERS == 1 + r = dbp->del(dbp, &db_key, 0); +#else + r = -1; +#endif + + return r; +#else + return -1; +#endif +} + +#if DBVERS > 1 +int mail_cache_db_clean_up(struct mail_cache_db * cache_db, + chash * exist) +{ + DB * dbp; + int r; + DBC * dbcp; + DBT db_key; + DBT db_data; + + dbp = cache_db->internal_database; + + r = dbp->cursor(dbp, NULL, &dbcp, 0); + if (r != 0) + return r; + + memset(&db_key, 0, sizeof(db_key)); + memset(&db_data, 0, sizeof(db_data)); + + while (1) { + chashdatum hash_key; + chashdatum hash_data; + + r = dbcp->c_get(dbcp, &db_key, &db_data, DB_NEXT); + if (r != 0) + break; + + hash_key.data = db_key.data; + hash_key.len = db_key.size; + + r = chash_get(exist, &hash_key, &hash_data); + if (r < 0) { + r = dbcp->c_del(dbcp, 0); + if (r != 0) + return r; + } + } + + r = dbcp->c_close(dbcp); + if (r != 0) + return r; + + return 0; +} +#elif DBVERS == 1 +int mail_cache_db_clean_up(struct mail_cache_db * cache_db, + chash * exist) +{ + DB * dbp; + int r; + DBT db_key; + DBT db_data; + + dbp = cache_db->internal_database; + + r = dbp->seq(dbp, &db_key, &db_data, R_FIRST); + if (r == -1) + return r; + + while (r == 0) { + chashdatum hash_key; + chashdatum hash_data; + + hash_key.data = db_key.data; + hash_key.len = db_key.size; + + r = chash_get(exist, &hash_key, &hash_data); + if (r < 0) { + r = dbp->del(dbp, &db_key, 0); + if (r != 0) + return r; + } + + r = dbp->seq(dbp, &db_key, &db_data, R_NEXT); + if (r == -1) + return r; + } + + return 0; +} +#else +int mail_cache_db_clean_up(struct mail_cache_db * cache_db, + chash * exist) +{ + return -1; +} +#endif diff --git a/kmicromail/libetpan/tools/mail_cache_db.h b/kmicromail/libetpan/tools/mail_cache_db.h new file mode 100644 index 0000000..0ca17d9 --- a/dev/null +++ b/kmicromail/libetpan/tools/mail_cache_db.h @@ -0,0 +1,138 @@ +/* + * libEtPan! -- a mail stuff library + * + * Copyright (C) 2001, 2002 - DINH Viet Hoa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the libEtPan! project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * $Id$ + */ + +#ifndef MAIL_CACHE_DB_H + +#define MAIL_CACHE_DB_H + +#include <sys/types.h> +#include "mail_cache_db_types.h" +#include "chash.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + this module will handle a database "f(key) -> value" in a file + + berkeley DB or other can be used for implementation of low-level file. +*/ + +/* + mail_cache_db_open() + + This function opens the file "filename". + The pointer return in pcache_db should be used for further references + to the database. +*/ + +int mail_cache_db_open(const char * filename, + struct mail_cache_db ** pcache_db); + +/* + mail_cache_db_close() + + This function closes the opened database. + The pointer cannot be used later. +*/ + +void mail_cache_db_close(struct mail_cache_db * cache_db); + +/* + mail_cache_db_open_lock() + + This function opens and locks the file "filename". + The pointer return in pcache_db should be used for further references + to the database. +*/ + +int mail_cache_db_open_lock(const char * filename, + struct mail_cache_db ** pcache_db); + +/* + mail_cache_db_open_unlock() + + This function closes and unlocks the opened database. + The pointer cannot be used later. +*/ + +void mail_cache_db_close_unlock(const char * filename, + struct mail_cache_db * cache_db); + +/* + mail_cache_db_put() + + This function will store a given key and value in the database. +*/ + +int mail_cache_db_put(struct mail_cache_db * cache_db, + const void * key, size_t key_len, const void * value, size_t value_len); + +/* + mail_cache_db_get() + + This function will retrieve the value corresponding to a given key + from the database. +*/ + +int mail_cache_db_get(struct mail_cache_db * cache_db, + const void * key, size_t key_len, void ** pvalue, size_t * pvalue_len); + +/* + mail_cache_db_del() + + This function will delete the given key and the corresponding value + from the database. +*/ + +int mail_cache_db_del(struct mail_cache_db * cache_db, + const void * key, size_t key_len); + +/* + mail_cache_clean_up() + + This function will delete the key all the key/value pairs of the + database file which key does not exist in the given hash. +*/ + +int mail_cache_db_clean_up(struct mail_cache_db * cache_db, + chash * exist); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kmicromail/libetpan/tools/mail_cache_db_types.h b/kmicromail/libetpan/tools/mail_cache_db_types.h new file mode 100644 index 0000000..f346c5f --- a/dev/null +++ b/kmicromail/libetpan/tools/mail_cache_db_types.h @@ -0,0 +1,52 @@ +/* + * libEtPan! -- a mail stuff library + * + * Copyright (C) 2001, 2002 - DINH Viet Hoa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the libEtPan! project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * $Id$ + */ + +#ifndef MAIL_CACHE_DB_TYPES_H + +#define MAIL_CACHE_DB_TYPES_H + +#ifdef __cplusplus +extern "C" { +#endif + +struct mail_cache_db { + void * internal_database; +}; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kmicromail/libetpan/tools/maillock.c b/kmicromail/libetpan/tools/maillock.c new file mode 100644 index 0000000..6128f34 --- a/dev/null +++ b/kmicromail/libetpan/tools/maillock.c @@ -0,0 +1,286 @@ +/* + * libEtPan! -- a mail stuff library + * + * Copyright (C) 2001, 2002 - DINH Viet Hoa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the libEtPan! project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * $Id $ + */ + +#include "maillock.h" + +#include "libetpan-config.h" + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdio.h> +#include <time.h> +#include <string.h> + +/* ********************************************************************** */ + +/* lock primitives */ + +/* the lock code is modified from the dot lock file code from mail.local.c */ + +/* + SENDMAIL LICENSE + +The following license terms and conditions apply, unless a different +license is obtained from Sendmail, Inc., 6425 Christie Ave, Fourth Floor, +Emeryville, CA 94608, or by electronic mail at license@sendmail.com. + +License Terms: + +Use, Modification and Redistribution (including distribution of any +modified or derived work) in source and binary forms is permitted only if +each of the following conditions is met: + +1. Redistributions qualify as "freeware" or "Open Source Software" under + one of the following terms: + + (a) Redistributions are made at no charge beyond the reasonable cost of + materials and delivery. + + (b) Redistributions are accompanied by a copy of the Source Code or by an + irrevocable offer to provide a copy of the Source Code for up to three + years at the cost of materials and delivery. Such redistributions + must allow further use, modification, and redistribution of the Source + Code under substantially the same terms as this license. For the + purposes of redistribution "Source Code" means the complete compilable + and linkable source code of sendmail including all modifications. + +2. Redistributions of source code must retain the copyright notices as they + appear in each source code file, these license terms, and the + disclaimer/limitation of liability set forth as paragraph 6 below. + +3. Redistributions in binary form must reproduce the Copyright Notice, + these license terms, and the disclaimer/limitation of liability set + forth as paragraph 6 below, in the documentation and/or other materials + provided with the distribution. For the purposes of binary distribution + the "Copyright Notice" refers to the following language: + "Copyright (c) 1998-2002 Sendmail, Inc. All rights reserved." + +4. Neither the name of Sendmail, Inc. nor the University of California nor + the names of their contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. The name "sendmail" is a trademark of Sendmail, Inc. + +5. All redistributions must comply with the conditions imposed by the + University of California on certain embedded code, whose copyright + notice and conditions for redistribution are as follows: + + (a) Copyright (c) 1988, 1993 The Regents of the University of + California. All rights reserved. + + (b) Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + (i) Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + (ii) Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + (iii) Neither the name of the University nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +6. Disclaimer/Limitation of Liability: THIS SOFTWARE IS PROVIDED BY + SENDMAIL, INC. AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + NO EVENT SHALL SENDMAIL, INC., THE REGENTS OF THE UNIVERSITY OF + CALIFORNIA OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +*/ + +/* + TODO : lock, prefer fcntl() over flock() + AND use dotlock code above +*/ + +#define LOCKTO_RM 300 /* timeout for stale lockfile removal */ +#define LOCKTO_GLOB 400 /* global timeout for lockfile creation */ + +static int lock_common(const char * filename, int fd, short locktype) +{ + char lockfilename[PATH_MAX]; + struct flock lock; + /* dot lock file */ + int statfailed = 0; + time_t start; + int r; + int res; + + lock.l_start = 0; + lock.l_len = 0; + lock.l_pid = getpid(); + lock.l_type = locktype; + lock.l_whence = SEEK_SET; + + r = fcntl(fd, F_SETLKW, &lock); + if (r < 0) { + /* WARNING POSIX lock could not be applied */ + } + + /* dot lock file */ + + if (strlen(filename) + 6 > PATH_MAX) { + res = -1; + goto unlock; + } + + snprintf(lockfilename, PATH_MAX, "%s.lock", filename); + + time(&start); + while (1) { + int fd; + struct stat st; + time_t now; + + /* global timeout */ + time(&now); + if (now > start + LOCKTO_GLOB) { + res = -1; + goto unlock; + } + + fd = open(lockfilename, O_WRONLY|O_EXCL|O_CREAT, 0); + if (fd >= 0) { + /* defeat lock checking programs which test pid */ + write(fd, "0", 2); + close(fd); + break; + } + + /* libEtPan! - adds a delay of 5 seconds between each tries */ + sleep(5); + + if (stat(lockfilename, &st) < 0) { + if (statfailed++ > 5) { + res = -1; + goto unlock; + } + continue; + } + statfailed = 0; + time(&now); + + if (now < st.st_ctime + LOCKTO_RM) + continue; + + /* try to remove stale lockfile */ + if (unlink(lockfilename) < 0) { + res = -1; + goto unlock; + } + + /* + libEtPan! - removes this delay of 5 seconds, + maybe it was misplaced ? + */ +#if 0 + sleep(5); +#endif + } + + return 0; + + unlock: + lock.l_start = 0; + lock.l_len = 0; + lock.l_pid = getpid(); + lock.l_type = F_UNLCK; + lock.l_whence = SEEK_SET; + + r = fcntl(fd, F_SETLK, &lock); + if (r < 0) { + /* WARNING POSIX lock could not be applied */ + } + err: + return res; +} + +static int unlock_common(const char * filename, int fd) +{ + char lockfilename[PATH_MAX]; + struct flock lock; + int r; + + if (strlen(filename) + 6 > PATH_MAX) + return -1; + + snprintf(lockfilename, PATH_MAX, "%s.lock", filename); + + unlink(lockfilename); + + lock.l_start = 0; + lock.l_len = 0; + lock.l_pid = getpid(); + lock.l_type = F_UNLCK; + lock.l_whence = SEEK_SET; + + r = fcntl(fd, F_SETLK, &lock); + if (r < 0) { + /* WARNING POSIX lock could not be applied */ + } + + return 0; +} + +int maillock_read_lock(const char * filename, int fd) +{ + return lock_common(filename, fd, F_RDLCK); +} + +int maillock_read_unlock(const char * filename, int fd) +{ + return unlock_common(filename, fd); +} + +int maillock_write_lock(const char * filename, int fd) +{ + return lock_common(filename, fd, F_WRLCK); +} + +int maillock_write_unlock(const char * filename, int fd) +{ + return unlock_common(filename, fd); +} diff --git a/kmicromail/libetpan/tools/maillock.h b/kmicromail/libetpan/tools/maillock.h new file mode 100644 index 0000000..2f64e35 --- a/dev/null +++ b/kmicromail/libetpan/tools/maillock.h @@ -0,0 +1,53 @@ +/* + * libEtPan! -- a mail stuff library + * + * Copyright (C) 2001, 2002 - DINH Viet Hoa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the libEtPan! project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * $Id$ + */ + +#ifndef MAILLOCK_H + +#define MAILLOCK_H + +#ifdef __cplusplus +extern "C" { +#endif + +int maillock_read_lock(const char * filename, int fd); +int maillock_read_unlock(const char * filename, int fd); +int maillock_write_lock(const char * filename, int fd); +int maillock_write_unlock(const char * filename, int fd); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kmicromail/libetpan/tools/mailstream.c b/kmicromail/libetpan/tools/mailstream.c new file mode 100644 index 0000000..0f55e67 --- a/dev/null +++ b/kmicromail/libetpan/tools/mailstream.c @@ -0,0 +1,394 @@ +/* + * libEtPan! -- a mail stuff library + * + * Copyright (C) 2001, 2002 - DINH Viet Hoa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the libEtPan! project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * $Id$ + */ + +#include "mailstream.h" +#include "maillock.h" +#include <string.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/stat.h> + +#define DEFAULT_NETWORK_TIMEOUT 300 + +#ifdef LIBETPAN_MAILSTREAM_DEBUG + +#define STREAM_DEBUG + +#include <stdio.h> + +#define LOG_FILE "libetpan-stream-debug.log" + +int mailstream_debug = 0; + +#define STREAM_LOG_BUF(buf, size) \ + if (mailstream_debug) { \ + FILE * f; \ + mode_t old_mask; \ + \ + old_mask = umask(0077); \ + f = fopen(LOG_FILE, "a"); \ + umask(old_mask); \ + if (f != NULL) { \ + maillock_write_lock(LOG_FILE, fileno(f)); \ + fwrite((buf), 1, (size), f); \ + maillock_write_unlock(LOG_FILE, fileno(f)); \ + fclose(f); \ + } \ + } + +#define STREAM_LOG(str) \ + if (mailstream_debug) { \ + FILE * f; \ + mode_t old_mask; \ + \ + old_mask = umask(0077); \ + f = fopen(LOG_FILE, "a"); \ + umask(old_mask); \ + if (f != NULL) { \ + maillock_write_lock(LOG_FILE, fileno(f)); \ + fputs((str), f); \ + maillock_write_unlock(LOG_FILE, fileno(f)); \ + fclose(f); \ + } \ + } + +#else + +#define STREAM_LOG_BUF(buf, size) do { } while (0) +#define STREAM_LOG(buf) do { } while (0) + +#endif + + +mailstream * mailstream_new(mailstream_low * low, size_t buffer_size) +{ + mailstream * s; + + s = malloc(sizeof(* s)); + if (s == NULL) + goto err; + + s->read_buffer = malloc(buffer_size); + if (s->read_buffer == NULL) + goto free_s; + s->read_buffer_len = 0; + + s->write_buffer = malloc(buffer_size); + if (s->write_buffer == NULL) + goto free_read_buffer; + s->write_buffer_len = 0; + + s->buffer_max_size = buffer_size; + s->low = low; + + return s; + + free_read_buffer: + free(s->read_buffer); + free_s: + free(s); + err: + return NULL; +} + +static size_t write_to_internal_buffer(mailstream * s, + const void * buf, size_t count) +{ + memcpy(s->write_buffer + s->write_buffer_len, buf, count); + s->write_buffer_len += count; + + return count; +} + +static size_t write_direct(mailstream * s, const void * buf, size_t count) +{ + size_t left; + const char * cur_buf; + ssize_t written; + + cur_buf = buf; + left = count; + while (left > 0) { + written = mailstream_low_write(s->low, cur_buf, left); + + if (written == -1) { + if (count == left) + return -1; + else + return count - left; + } + + cur_buf += written; + left -= written; + } + + return count; +} + +ssize_t mailstream_write(mailstream * s, const void * buf, size_t count) +{ + int r; + + if (s == NULL) + return -1; + + if (count + s->write_buffer_len > s->buffer_max_size) { + r = mailstream_flush(s); + if (r == -1) + return -1; + + if (count > s->buffer_max_size) + return write_direct(s, buf, count); + } + +#ifdef STREAM_DEBUG + STREAM_LOG(">>>>>>> send >>>>>>\n"); + STREAM_LOG_BUF(buf, count); + STREAM_LOG("\n"); + STREAM_LOG(">>>>>>> end send >>>>>>\n"); +#endif + + return write_to_internal_buffer(s, buf, count); +} + +int mailstream_flush(mailstream * s) +{ + char * cur_buf; + size_t left; + ssize_t written; + + if (s == NULL) + return -1; + + cur_buf = s->write_buffer; + left = s->write_buffer_len; + while (left > 0) { + written = mailstream_low_write(s->low, cur_buf, left); + + if (written == -1) + goto move_buffer; + cur_buf += written; + left -= written; + } + + s->write_buffer_len = 0; + + return 0; + + move_buffer: + memmove(s->write_buffer, cur_buf, left); + s->write_buffer_len = left; + return -1; +} + +static ssize_t read_from_internal_buffer(mailstream * s, + void * buf, size_t count) +{ + if (count >= s->read_buffer_len) + count = s->read_buffer_len; + if (count != 0) + memcpy(buf, s->read_buffer, count); + + s->read_buffer_len -= count; + if (s->read_buffer_len != 0) + memmove(s->read_buffer, s->read_buffer + count, + s->read_buffer_len); + + return count; +} + +static ssize_t read_through_buffer(mailstream * s, void * buf, size_t count) +{ + size_t left; + char * cur_buf; + ssize_t bytes_read; + + cur_buf = buf; + left = count; + + while (left > 0) { + bytes_read = mailstream_low_read(s->low, cur_buf, left); + + if (bytes_read == -1) { + if (count == left) + return -1; + else + return count - left; + } + else if (bytes_read == 0) + return count - left; + + cur_buf += bytes_read; + left -= bytes_read; + } + + return count; +} + +ssize_t mailstream_read(mailstream * s, void * buf, size_t count) +{ + ssize_t read_bytes; + char * cur_buf; + size_t left; + + if (s == NULL) + return -1; + + left = count; + cur_buf = buf; + read_bytes = read_from_internal_buffer(s, cur_buf, left); + cur_buf += read_bytes; + left -= read_bytes; + + if (left == 0) { +#ifdef STREAM_DEBUG + STREAM_LOG("<<<<<<< read <<<<<<\n"); + STREAM_LOG_BUF(buf, read_bytes); + STREAM_LOG("\n"); + STREAM_LOG("<<<<<<< end read <<<<<<\n"); +#endif + + return read_bytes; + } + + if (left > s->buffer_max_size) { + read_bytes = read_through_buffer(s, cur_buf, left); + if (read_bytes == -1) { + if (count == left) + return -1; + else { + +#ifdef STREAM_DEBUG + STREAM_LOG("<<<<<<< read <<<<<<\n"); + STREAM_LOG_BUF(buf, count - left); + STREAM_LOG("\n"); + STREAM_LOG("<<<<<<< end read <<<<<<\n"); +#endif + + return count - left; + } + } + + cur_buf += read_bytes; + left -= read_bytes; + +#ifdef STREAM_DEBUG + STREAM_LOG("<<<<<<< read <<<<<<\n"); + STREAM_LOG_BUF(buf, count - left); + STREAM_LOG("\n"); + STREAM_LOG("<<<<<<< end read <<<<<<\n"); +#endif + + return count - left; + } + + read_bytes = mailstream_low_read(s->low, s->read_buffer, s->buffer_max_size); + if (read_bytes == -1) { + if (left == count) + return -1; + else { +#ifdef STREAM_DEBUG + STREAM_LOG("<<<<<<< read <<<<<<\n"); + STREAM_LOG_BUF(buf, count - left); + STREAM_LOG("\n"); + STREAM_LOG("<<<<<<< end read <<<<<<\n"); +#endif + + return count - left; + } + } + else + s->read_buffer_len += read_bytes; + + read_bytes = read_from_internal_buffer(s, cur_buf, left); + cur_buf += read_bytes; + left -= read_bytes; + +#ifdef STREAM_DEBUG + STREAM_LOG("<<<<<<< read <<<<<<\n"); + STREAM_LOG_BUF(buf, count - left); + STREAM_LOG("\n"); + STREAM_LOG("<<<<<<< end read <<<<<<\n"); +#endif + + return count - left; +} + +mailstream_low * mailstream_get_low(mailstream * s) +{ + return s->low; +} + +void mailstream_set_low(mailstream * s, mailstream_low * low) +{ + s->low = low; +} + +int mailstream_close(mailstream * s) +{ + mailstream_low_close(s->low); + mailstream_low_free(s->low); + + free(s->read_buffer); + free(s->write_buffer); + + free(s); + + return 0; +} + + + +ssize_t mailstream_feed_read_buffer(mailstream * s) +{ + ssize_t read_bytes; + + if (s == NULL) + return -1; + + if (s->read_buffer_len == 0) { + read_bytes = mailstream_low_read(s->low, s->read_buffer, + s->buffer_max_size); + if (read_bytes == -1) + return -1; + s->read_buffer_len += read_bytes; + } + + return s->read_buffer_len; +} + +struct timeval mailstream_network_delay = + { .tv_sec = DEFAULT_NETWORK_TIMEOUT, .tv_usec = 0 }; + diff --git a/kmicromail/libetpan/tools/mailstream.h b/kmicromail/libetpan/tools/mailstream.h new file mode 100644 index 0000000..a4e35cd --- a/dev/null +++ b/kmicromail/libetpan/tools/mailstream.h @@ -0,0 +1,73 @@ +/* + * libEtPan! -- a mail stuff library + * + * Copyright (C) 2001, 2002 - DINH Viet Hoa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the libEtPan! project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * $Id$ + */ + +#ifndef MAILSTREAM_H + +#define MAILSTREAM_H + +#include <sys/time.h> + +#include <libetpan/mailstream_low.h> +#include <libetpan/mailstream_helper.h> +#include <libetpan/mailstream_socket.h> +#include <libetpan/mailstream_ssl.h> +#include <libetpan/mailstream_types.h> + +#ifdef __cplusplus +extern "C" { +#endif + +mailstream * mailstream_new(mailstream_low * low, size_t buffer_size); +ssize_t mailstream_write(mailstream * s, const void * buf, size_t count); +ssize_t mailstream_read(mailstream * s, void * buf, size_t count); +int mailstream_close(mailstream * s); +int mailstream_flush(mailstream * s); +ssize_t mailstream_feed_read_buffer(mailstream * s); +mailstream_low * mailstream_get_low(mailstream * s); +void mailstream_set_low(mailstream * s, mailstream_low * low); + +#ifdef LIBETPAN_MAILSTREAM_DEBUG +extern int mailstream_debug; +#endif + +#define LIBETPAN_MAILSTREAM_NETWORK_DELAY +extern struct timeval mailstream_network_delay; + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/kmicromail/libetpan/tools/mailstream_helper.c b/kmicromail/libetpan/tools/mailstream_helper.c new file mode 100644 index 0000000..146f955 --- a/dev/null +++ b/kmicromail/libetpan/tools/mailstream_helper.c @@ -0,0 +1,383 @@ +/* + * libEtPan! -- a mail stuff library + * + * Copyright (C) 2001, 2002 - DINH Viet Hoa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the libEtPan! project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * $Id$ + */ + +#include "mailstream_helper.h" +#include <string.h> +#include <stdio.h> +#include "mail.h" + +static void remove_trailing_eol(MMAPString * mmapstr) +{ + if (mmapstr->str[mmapstr->len - 1] == '\n') { + mmapstr->len --; + mmapstr->str[mmapstr->len] = '\0'; + } + if (mmapstr->str[mmapstr->len - 1] == '\r') { + mmapstr->len --; + mmapstr->str[mmapstr->len] = '\0'; + } +} + +char * mailstream_read_line(mailstream * stream, MMAPString * line) +{ + if (mmap_string_assign(line, "") == NULL) + return NULL; + + return mailstream_read_line_append(stream, line); +} + +static char * mailstream_read_len_append(mailstream * stream, + MMAPString * line, + size_t i) +{ + size_t cur_size; + + cur_size = line->len; + if (mmap_string_set_size(line, line->len + i) == NULL) + return NULL; + if (mailstream_read(stream, line->str + cur_size, i) < 0) + return NULL; + return line->str; +} + +char * mailstream_read_line_append(mailstream * stream, MMAPString * line) +{ + if (stream == NULL) + return NULL; + + do { + if (stream->read_buffer_len > 0) { + size_t i; + + i = 0; + while (i < stream->read_buffer_len) { + if (stream->read_buffer[i] == '\n') + return mailstream_read_len_append(stream, line, i + 1); + i++; + } + if (mailstream_read_len_append(stream, line, + stream->read_buffer_len) == NULL) + return NULL; + } + else { + ssize_t r; + + r = mailstream_feed_read_buffer(stream); + if (r == -1) + return NULL; + + if (r == 0) + break; + } + } + while (1); + + return line->str; +} + +char * mailstream_read_line_remove_eol(mailstream * stream, MMAPString * line) +{ + if (!mailstream_read_line(stream, line)) + return NULL; + + remove_trailing_eol(line); + + return line->str; +} + +int mailstream_is_end_multiline(const char * line) +{ + if (line[0] != '.') + return FALSE; + if (line[1] != 0) + return FALSE; + return TRUE; +} + +#if 1 +char * mailstream_read_multiline(mailstream * s, size_t size, + MMAPString * stream_buffer, + MMAPString * multiline_buffer, + size_t progr_rate, + progress_function * progr_fun) +{ + size_t count; + char * line; + size_t last; + + if (mmap_string_assign(multiline_buffer, "") == NULL) + return NULL; + + count = 0; + last = 0; + + while ((line = mailstream_read_line_remove_eol(s, stream_buffer)) != NULL) { + if (mailstream_is_end_multiline(line)) + return multiline_buffer->str; + + if (line[0] == '.') { + if (mmap_string_append(multiline_buffer, line + 1) == NULL) + return NULL; + } + else { + if (mmap_string_append(multiline_buffer, line) == NULL) + return NULL; + } + if (mmap_string_append(multiline_buffer, "\r\n") == NULL) + return NULL; + + count += strlen(line); + if ((size != 0) && (progr_rate != 0) && (progr_fun != NULL)) + if (count - last >= progr_rate) { + (* progr_fun)(count, size); + last = count; + } + } + + return NULL; +} + +#else + +/* + high speed but don't replace the line break with '\n' and neither + remove the '.' +*/ + +static gboolean end_of_multiline(const char * str, gint len) +{ + gint index; + + index = len - 1; + + if (str[index] != '\n') + return FALSE; + if (index == 0) + return FALSE; + + index --; + + if (str[index] == '\r') { + index --; + if (index == 0) + return FALSE; + } + + if (str[index] != '.') + return FALSE; + if (index == 0) + return FALSE; + + index--; + + if (str[index] != '\n') + return FALSE; + + return TRUE; +} + +char * mailstream_read_multiline(mailstream * stream, size_t size, + MMAPString * stream_buffer, + MMAPString * line, + size_t progr_rate, + progress_function * progr_fun) +{ + if (stream == NULL) + return NULL; + + mmap_string_assign(line, ""); + + do { + if (stream->read_buffer_len > 0) { + size_t i; + + i = 0; + while (i < stream->read_buffer_len) { + if (end_of_multiline(stream->read_buffer, i + 1)) + return mailstream_read_len_append(stream, line, i + 1); + i++; + } + if (mailstream_read_len_append(stream, line, + stream->read_buffer_len) == NULL) + return NULL; + if (end_of_multiline(line->str, line->len)) + return line->str; + } + else + if (mailstream_feed_read_buffer(stream) == -1) + return NULL; + } + while (1); + + return line->str; +} +#endif + + + +static ssize_t send_data_line(mailstream * s, const char * line, size_t length) +{ + int fix_eol; + const char * start; + size_t count; + + start = line; + + fix_eol = 0; + count = 0; + + while (1) { + if (length == 0) + break; + + if (* line == '\r') { + line ++; + + count ++; + length --; + + if (* line == '\n') { + line ++; + + count ++; + length --; + + break; + } + } + + if (* line == '\n') { + line ++; + + count ++; + length --; + + fix_eol = 1; + break; + } + + line ++; + length --; + count ++; + } + + if (start[0] == '.') + if (mailstream_write(s, ".", 1) == -1) + goto err; + + if (fix_eol) { + if (mailstream_write(s, start, count - 1) == -1) + goto err; + if (mailstream_write(s, "\r\n", 2) == -1) + goto err; + } + else { + if (mailstream_write(s, start, count) == -1) + goto err; + } + + +#if 0 + while (* line != '\n') { + if (* line == '\r') + pos = line; + if (* line == '\0') + return line; + if (mailstream_write(s, line, 1) == -1) + goto err; + line ++; + } + if (pos + 1 == line) { + if (mailstream_write(s, line, 1) == -1) + goto err; + } + else { + if (mailstream_write(s, "\r\n", 2) == -1) + goto err; + } + line ++; +#endif + + return count; + + err: + return -1; +} + +int mailstream_send_data(mailstream * s, const char * message, + size_t size, + size_t progr_rate, + progress_function * progr_fun) +{ + const char * current; + size_t count; + size_t last; + size_t remaining; + + count = 0; + last = 0; + + current = message; + remaining = size; + + while (remaining > 0) { + ssize_t length; + + length = send_data_line(s, current, remaining); + if (length < 0) + goto err; + + current += length; + + count += length; + if ((progr_rate != 0) && (progr_fun != NULL)) + if (count - last >= progr_rate) { + (* progr_fun)(count, size); + last = count; + } + + remaining -= length; + } + if (mailstream_write(s, "\r\n.\r\n", 5) == -1) + goto err; + + if (mailstream_flush(s) == -1) + goto err; + + return 0; + + err: + return -1; +} diff --git a/kmicromail/libetpan/tools/mailstream_helper.h b/kmicromail/libetpan/tools/mailstream_helper.h new file mode 100644 index 0000000..d030b1d --- a/dev/null +++ b/kmicromail/libetpan/tools/mailstream_helper.h @@ -0,0 +1,70 @@ +/* + * libEtPan! -- a mail stuff library + * + * Copyright (C) 2001, 2002 - DINH Viet Hoa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the libEtPan! project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * $Id$ + */ + +#ifndef MAILSTREAM_HELPER_H + +#define MAILSTREAM_HELPER_H + +#include <libetpan/mmapstring.h> +#include <libetpan/mailstream.h> + +#ifdef __cplusplus +extern "C" { +#endif + +char * mailstream_read_line(mailstream * stream, MMAPString * line); + +char * mailstream_read_line_append(mailstream * stream, MMAPString * line); + +char * mailstream_read_line_remove_eol(mailstream * stream, MMAPString * line); + +char * mailstream_read_multiline(mailstream * s, size_t size, + MMAPString * stream_buffer, + MMAPString * multiline_buffer, + size_t progr_rate, + progress_function * progr_fun); + +int mailstream_is_end_multiline(const char * line); + +int mailstream_send_data(mailstream * s, const char * message, + size_t size, + size_t progr_rate, + progress_function * progr_fun); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kmicromail/libetpan/tools/mailstream_low.c b/kmicromail/libetpan/tools/mailstream_low.c new file mode 100644 index 0000000..34c96f1 --- a/dev/null +++ b/kmicromail/libetpan/tools/mailstream_low.c @@ -0,0 +1,90 @@ +/* + * libEtPan! -- a mail stuff library + * + * Copyright (C) 2001, 2002 - DINH Viet Hoa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the libEtPan! project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * $Id$ + */ + +#include "mailstream_low.h" +#include <stdlib.h> + +/* general functions */ + +mailstream_low * mailstream_low_new(void * data, + mailstream_low_driver * driver) +{ + mailstream_low * s; + + s = malloc(sizeof(* s)); + if (s == NULL) + return NULL; + + s->data = data; + s->driver = driver; + + return s; +} + +int mailstream_low_close(mailstream_low * s) +{ + if (s == NULL) + return -1; + s->driver->mailstream_close(s); + + return 0; +} + +int mailstream_low_get_fd(mailstream_low * s) +{ + if (s == NULL) + return -1; + return s->driver->mailstream_get_fd(s); +} + +void mailstream_low_free(mailstream_low * s) +{ + s->driver->mailstream_free(s); +} + +ssize_t mailstream_low_read(mailstream_low * s, void * buf, size_t count) +{ + if (s == NULL) + return -1; + return s->driver->mailstream_read(s, buf, count); +} + +ssize_t mailstream_low_write(mailstream_low * s, + const void * buf, size_t count) +{ + if (s == NULL) + return -1; + return s->driver->mailstream_write(s, buf, count); +} diff --git a/kmicromail/libetpan/tools/mailstream_low.h b/kmicromail/libetpan/tools/mailstream_low.h new file mode 100644 index 0000000..fb8914c --- a/dev/null +++ b/kmicromail/libetpan/tools/mailstream_low.h @@ -0,0 +1,62 @@ +/* + * libEtPan! -- a mail stuff library + * + * Copyright (C) 2001, 2002 - DINH Viet Hoa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the libEtPan! project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * $Id$ + */ + +#ifndef MAILSTREAM_LOW_H + +#define MAILSTREAM_LOW_H + +#include <sys/types.h> +#include <libetpan/mailstream_types.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* general functions */ + +mailstream_low * mailstream_low_new(void * data, + mailstream_low_driver * driver); +ssize_t mailstream_low_write(mailstream_low * s, + const void * buf, size_t count); +ssize_t mailstream_low_read(mailstream_low * s, void * buf, size_t count); +int mailstream_low_close(mailstream_low * s); +int mailstream_low_get_fd(mailstream_low * s); +void mailstream_low_free(mailstream_low * s); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kmicromail/libetpan/tools/mailstream_socket.c b/kmicromail/libetpan/tools/mailstream_socket.c new file mode 100644 index 0000000..29e50e1 --- a/dev/null +++ b/kmicromail/libetpan/tools/mailstream_socket.c @@ -0,0 +1,239 @@ +/* + * libEtPan! -- a mail stuff library + * + * Copyright (C) 2001, 2002 - DINH Viet Hoa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the libEtPan! project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * $Id$ + */ + +#include "mailstream_socket.h" +#include <unistd.h> +#include <stdlib.h> +#include <fcntl.h> + +/* + these 3 headers MUST be included before <sys/select.h> + to insure compatibility with Mac OS X (this is true for 10.2) +*/ +#include <sys/time.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <unistd.h> +#include <sys/select.h> + +/* mailstream_low, socket */ + +static int mailstream_low_socket_close(mailstream_low * s); +static ssize_t mailstream_low_socket_read(mailstream_low * s, + void * buf, size_t count); +static ssize_t mailstream_low_socket_write(mailstream_low * s, + const void * buf, size_t count); +static void mailstream_low_socket_free(mailstream_low * s); +static int mailstream_low_socket_get_fd(mailstream_low * s); + +static mailstream_low_driver local_mailstream_socket_driver = { + mailstream_read: mailstream_low_socket_read, + mailstream_write: mailstream_low_socket_write, + mailstream_close: mailstream_low_socket_close, + mailstream_free: mailstream_low_socket_free, + mailstream_get_fd: mailstream_low_socket_get_fd, +}; + +mailstream_low_driver * mailstream_socket_driver = +&local_mailstream_socket_driver; + +/* file descriptor must be given in (default) blocking-mode */ + +static struct mailstream_socket_data * socket_data_new(int fd) +{ + struct mailstream_socket_data * socket_data; + + socket_data = malloc(sizeof(* socket_data)); + if (socket_data == NULL) + goto err; + + socket_data->fd = fd; + + return socket_data; + + err: + return NULL; +} + +static void socket_data_free(struct mailstream_socket_data * socket_data) +{ + free(socket_data); +} + +static void socket_data_close(struct mailstream_socket_data * socket_data) +{ + close(socket_data->fd); + socket_data->fd = -1; +} + +mailstream_low * mailstream_low_socket_open(int fd) +{ + mailstream_low * s; + struct mailstream_socket_data * socket_data; + + socket_data = socket_data_new(fd); + if (socket_data == NULL) + goto err; + + s = mailstream_low_new(socket_data, mailstream_socket_driver); + if (s == NULL) + goto free_socket_data; + + return s; + + free_socket_data: + socket_data_free(socket_data); + err: + return NULL; +} + +static int mailstream_low_socket_close(mailstream_low * s) +{ + struct mailstream_socket_data * socket_data; + + socket_data = (struct mailstream_socket_data *) s->data; + socket_data_close(socket_data); + + return 0; +} + +static void mailstream_low_socket_free(mailstream_low * s) +{ + struct mailstream_socket_data * socket_data; + + socket_data = (struct mailstream_socket_data *) s->data; + socket_data_free(socket_data); + s->data = NULL; + + free(s); +} + +static int mailstream_low_socket_get_fd(mailstream_low * s) +{ + struct mailstream_socket_data * socket_data; + + socket_data = (struct mailstream_socket_data *) s->data; + return socket_data->fd; +} + + +static ssize_t mailstream_low_socket_read(mailstream_low * s, + void * buf, size_t count) +{ + struct mailstream_socket_data * socket_data; + + socket_data = (struct mailstream_socket_data *) s->data; + + /* timeout */ + { + fd_set fds_read; + fd_set fds_excp; + struct timeval timeout; + int r; + + timeout = mailstream_network_delay; + + FD_ZERO(&fds_read); + FD_SET(socket_data->fd, &fds_read); + FD_ZERO(&fds_excp); + FD_SET(socket_data->fd, &fds_excp); + r = select(socket_data->fd + 1, &fds_read, NULL, &fds_excp, &timeout); + if (r == 0) + return -1; + if (FD_ISSET(socket_data->fd, &fds_excp)) + return -1; + if (!FD_ISSET(socket_data->fd, &fds_read)) + return 0; + } + return recv(socket_data->fd,buf,count,MSG_NOSIGNAL); + //return read(socket_data->fd, buf, count); +} + +static ssize_t mailstream_low_socket_write(mailstream_low * s, + const void * buf, size_t count) +{ + struct mailstream_socket_data * socket_data; + + socket_data = (struct mailstream_socket_data *) s->data; + /* timeout */ + { + fd_set fds_write; + fd_set fds_excp; + struct timeval timeout; + int r; + + timeout = mailstream_network_delay; + + FD_ZERO(&fds_write); + FD_SET(socket_data->fd, &fds_write); + FD_ZERO(&fds_excp); + FD_SET(socket_data->fd, &fds_excp); + r = select(socket_data->fd + 1, NULL, &fds_write, &fds_excp, &timeout); + if (r == 0) + return -1; + if (FD_ISSET(socket_data->fd, &fds_excp)) + return -1; + if (!FD_ISSET(socket_data->fd, &fds_write)) + return 0; + } + + return send(socket_data->fd,buf,count,MSG_NOSIGNAL); + //return write(socket_data->fd, buf, count); +} + + +/* mailstream */ + +mailstream * mailstream_socket_open(int fd) +{ + mailstream_low * low; + mailstream * s; + + low = mailstream_low_socket_open(fd); + if (low == NULL) + goto err; + + s = mailstream_new(low, 8192); + if (s == NULL) + goto free_low; + + return s; + + free_low: + mailstream_low_close(low); + err: + return NULL; +} + diff --git a/kmicromail/libetpan/tools/mailstream_socket.h b/kmicromail/libetpan/tools/mailstream_socket.h new file mode 100644 index 0000000..6a26e33 --- a/dev/null +++ b/kmicromail/libetpan/tools/mailstream_socket.h @@ -0,0 +1,61 @@ +/* + * libEtPan! -- a mail stuff library + * + * Copyright (C) 2001, 2002 - DINH Viet Hoa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the libEtPan! project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * $Id$ + */ + +#ifndef MAILSTREAM_SOCKET_H + +#define MAILSTREAM_SOCKET_H + +#include <libetpan/mailstream.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* socket */ + +extern mailstream_low_driver * mailstream_socket_driver; + +mailstream_low * mailstream_low_socket_open(int fd); +mailstream * mailstream_socket_open(int fd); + +struct mailstream_socket_data { + int fd; +}; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kmicromail/libetpan/tools/mailstream_ssl.c b/kmicromail/libetpan/tools/mailstream_ssl.c new file mode 100644 index 0000000..9f5008d --- a/dev/null +++ b/kmicromail/libetpan/tools/mailstream_ssl.c @@ -0,0 +1,312 @@ +/* + * libEtPan! -- a mail stuff library + * + * Copyright (C) 2001, 2002 - DINH Viet Hoa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the libEtPan! project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * $Id$ + */ + +/* + NOTE : + + The user has to call himself SSL_library_init() if he wants to + use SSL. +*/ + +#include "mailstream_ssl.h" +#include <unistd.h> +#include <fcntl.h> + +#ifndef CONFIG_H +#define CONFIG_H +#include "config.h" +#endif + +/* + these 3 headers MUST be included before <sys/select.h> + to insure compatibility with Mac OS X (this is true for 10.2) +*/ +#include <sys/time.h> +#include <sys/types.h> +#include <unistd.h> +#include <sys/select.h> + +/* mailstream_low, ssl */ + +#ifdef USE_SSL +#include <openssl/ssl.h> +#include <pthread.h> +#endif + +#ifdef USE_SSL +struct mailstream_ssl_data { + int fd; + SSL * ssl_conn; + SSL_CTX * ssl_ctx; +}; +#endif + +#ifdef USE_SSL +static pthread_mutex_t ssl_lock = PTHREAD_MUTEX_INITIALIZER; +static int ssl_init_done = 0; +#endif + +#ifdef USE_SSL +static int mailstream_low_ssl_close(mailstream_low * s); +static ssize_t mailstream_low_ssl_read(mailstream_low * s, + void * buf, size_t count); +static ssize_t mailstream_low_ssl_write(mailstream_low * s, + const void * buf, size_t count); +static void mailstream_low_ssl_free(mailstream_low * s); +static int mailstream_low_ssl_get_fd(mailstream_low * s); + +static mailstream_low_driver local_mailstream_ssl_driver = { + mailstream_read: mailstream_low_ssl_read, + mailstream_write: mailstream_low_ssl_write, + mailstream_close: mailstream_low_ssl_close, + mailstream_free: mailstream_low_ssl_free, + mailstream_get_fd: mailstream_low_ssl_get_fd, +}; + +mailstream_low_driver * mailstream_ssl_driver = &local_mailstream_ssl_driver; +#endif + +/* file descriptor must be given in (default) blocking-mode */ + +#ifdef USE_SSL +static struct mailstream_ssl_data * ssl_data_new(int fd) +{ + struct mailstream_ssl_data * ssl_data; + SSL * ssl_conn; + int r; + SSL_CTX * tmp_ctx; + int fd_flags; + int old_fd_flags; + + pthread_mutex_lock(&ssl_lock); + if (!ssl_init_done) { + SSL_library_init(); + ssl_init_done = 1; + } + pthread_mutex_unlock(&ssl_lock); + + tmp_ctx = SSL_CTX_new(TLSv1_client_method()); + if (tmp_ctx == NULL) + goto err; + + ssl_conn = (SSL *) SSL_new(tmp_ctx); + if (ssl_conn == NULL) + goto free_ctx; + + if (SSL_set_fd(ssl_conn, fd) == 0) + goto free_ssl_conn; + + SSL_set_read_ahead(ssl_conn, 1); + + r = SSL_connect(ssl_conn); + if (r <= 0) + goto free_ssl_conn; + + fd_flags = fcntl(fd, F_GETFL, 0); + old_fd_flags = fd_flags; + fd_flags |= O_NDELAY; + r = fcntl(fd, F_SETFL, fd_flags); + if (r < 0) + goto free_ssl_conn; + + ssl_data = malloc(sizeof(* ssl_data)); + if (ssl_data == NULL) + goto reset_fd_flags; + + ssl_data->fd = fd; + ssl_data->ssl_conn = ssl_conn; + ssl_data->ssl_ctx = tmp_ctx; + + return ssl_data; + + reset_fd_flags: + fcntl(fd, F_SETFL, old_fd_flags); + free_ctx: + SSL_CTX_free(tmp_ctx); + free_ssl_conn: + SSL_free(ssl_conn); + err: + return NULL; +} + +static void ssl_data_free(struct mailstream_ssl_data * ssl_data) +{ + free(ssl_data); +} + +static void ssl_data_close(struct mailstream_ssl_data * ssl_data) +{ + SSL_free(ssl_data->ssl_conn); + ssl_data->ssl_conn = NULL; + SSL_CTX_free(ssl_data->ssl_ctx); + ssl_data->ssl_ctx = NULL; + close(ssl_data->fd); + ssl_data->fd = -1; +} +#endif + +mailstream_low * mailstream_low_ssl_open(int fd) +{ +#ifdef USE_SSL + mailstream_low * s; + struct mailstream_ssl_data * ssl_data; + + ssl_data = ssl_data_new(fd); + if (ssl_data == NULL) + goto err; + + s = mailstream_low_new(ssl_data, mailstream_ssl_driver); + if (s == NULL) + goto free_ssl_data; + + return s; + + free_ssl_data: + ssl_data_free(ssl_data); + err: + return NULL; +#else + return NULL; +#endif +} + +#ifdef USE_SSL +static int mailstream_low_ssl_close(mailstream_low * s) +{ + struct mailstream_ssl_data * ssl_data; + + ssl_data = (struct mailstream_ssl_data *) s->data; + ssl_data_close(ssl_data); + + return 0; +} + +static void mailstream_low_ssl_free(mailstream_low * s) +{ + struct mailstream_ssl_data * ssl_data; + + ssl_data = (struct mailstream_ssl_data *) s->data; + ssl_data_free(ssl_data); + s->data = NULL; + + free(s); +} + +static int mailstream_low_ssl_get_fd(mailstream_low * s) +{ + struct mailstream_ssl_data * ssl_data; + + ssl_data = (struct mailstream_ssl_data *) s->data; + return ssl_data->fd; +} + +static ssize_t mailstream_low_ssl_read(mailstream_low * s, + void * buf, size_t count) +{ + struct mailstream_ssl_data * ssl_data; + int r; + + ssl_data = (struct mailstream_ssl_data *) s->data; + + while (1) { + int ssl_r; + fd_set fds_read; + struct timeval timeout; + + r = SSL_read(ssl_data->ssl_conn, buf, count); + if (r > 0) + return r; + + ssl_r = SSL_get_error(ssl_data->ssl_conn, r); + switch (ssl_r) { + case SSL_ERROR_NONE: + return r; + + case SSL_ERROR_ZERO_RETURN: + return r; + + case SSL_ERROR_WANT_READ: + timeout = mailstream_network_delay; + + FD_ZERO(&fds_read); + FD_SET(ssl_data->fd, &fds_read); + r = select(ssl_data->fd + 1, &fds_read, NULL, NULL, &timeout); + if (r == 0) + return -1; + break; + + default: + return r; + } + } +} + +static ssize_t mailstream_low_ssl_write(mailstream_low * s, + const void * buf, size_t count) +{ + struct mailstream_ssl_data * ssl_data; + + ssl_data = (struct mailstream_ssl_data *) s->data; + return SSL_write(ssl_data->ssl_conn, buf, count); +} +#endif + +/* mailstream */ + +mailstream * mailstream_ssl_open(int fd) +{ +#ifdef USE_SSL + mailstream_low * low; + mailstream * s; + + low = mailstream_low_ssl_open(fd); + if (low == NULL) + goto err; + + s = mailstream_new(low, 8192); + if (s == NULL) + goto free_low; + + return s; + + free_low: + mailstream_low_close(low); + err: + return NULL; +#else + return NULL; +#endif +} + diff --git a/kmicromail/libetpan/tools/mailstream_ssl.h b/kmicromail/libetpan/tools/mailstream_ssl.h new file mode 100644 index 0000000..a37b3d4 --- a/dev/null +++ b/kmicromail/libetpan/tools/mailstream_ssl.h @@ -0,0 +1,59 @@ +/* + * libEtPan! -- a mail stuff library + * + * Copyright (C) 2001, 2002 - DINH Viet Hoa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the libEtPan! project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * $Id$ + */ + +#ifndef MAILSTREAM_SSL_H + +#define MAILSTREAM_SSL_H + +#include <libetpan/mailstream.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* socket */ + +#ifdef USE_SSL +extern mailstream_low_driver * mailstream_ssl_driver; +#endif + +mailstream_low * mailstream_low_ssl_open(int fd); +mailstream * mailstream_ssl_open(int fd); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kmicromail/libetpan/tools/mailstream_types.h b/kmicromail/libetpan/tools/mailstream_types.h new file mode 100644 index 0000000..2165149 --- a/dev/null +++ b/kmicromail/libetpan/tools/mailstream_types.h @@ -0,0 +1,87 @@ +/* + * libEtPan! -- a mail stuff library + * + * Copyright (C) 2001, 2002 - DINH Viet Hoa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the libEtPan! project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * $Id$ + */ + +#ifndef MAILSTREAM_TYPES_H + +#define MAILSTREAM_TYPES_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define LIBETPAN_MAILSTREAM_DEBUG + +struct _mailstream; + +typedef struct _mailstream mailstream; + +struct _mailstream_low; + +typedef struct _mailstream_low mailstream_low; + +struct _mailstream { + size_t buffer_max_size; + + char * write_buffer; + size_t write_buffer_len; + + char * read_buffer; + size_t read_buffer_len; + + mailstream_low * low; +}; + +struct mailstream_low_driver { + ssize_t (* mailstream_read)(mailstream_low *, void *, size_t); + ssize_t (* mailstream_write)(mailstream_low *, const void *, size_t); + int (* mailstream_close)(mailstream_low *); + int (* mailstream_get_fd)(mailstream_low *); + void (* mailstream_free)(mailstream_low *); +}; + +typedef struct mailstream_low_driver mailstream_low_driver; + +struct _mailstream_low { + void * data; + mailstream_low_driver * driver; +}; + +typedef void progress_function(size_t current, size_t maximum); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kmicromail/libetpan/tools/mapping.c b/kmicromail/libetpan/tools/mapping.c new file mode 100644 index 0000000..426a03c --- a/dev/null +++ b/kmicromail/libetpan/tools/mapping.c @@ -0,0 +1,67 @@ +/* + * libEtPan! -- a mail stuff library + * + * Copyright (C) 2001, 2002 - DINH Viet Hoa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the libEtPan! project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * $Id$ + */ + +#include "mapping.h" + +#include <unistd.h> +#include <sys/mman.h> + +int get_mapping(size_t length, int prot, int flags, + int fd, off_t offset, + void ** presult, void ** pmapping, size_t * pmapping_size) +{ + void * mapping; + size_t mapping_size; + void * result; + size_t page_size; + off_t delta; + + page_size = getpagesize(); + delta = offset % page_size; + + mapping = mmap(NULL, length + offset, prot, flags, fd, offset - delta); + if (mapping == MAP_FAILED) + return -1; + + result = ((char *) mapping) + delta; + + mapping_size = length + offset; + + * pmapping = mapping; + * pmapping_size = mapping_size; + * presult = result; + + return 0; +} diff --git a/kmicromail/libetpan/tools/mapping.h b/kmicromail/libetpan/tools/mapping.h new file mode 100644 index 0000000..8e72f98 --- a/dev/null +++ b/kmicromail/libetpan/tools/mapping.h @@ -0,0 +1,54 @@ +/* + * libEtPan! -- a mail stuff library + * + * Copyright (C) 2001, 2002 - DINH Viet Hoa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the libEtPan! project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * $Id$ + */ + +#ifndef MAPPING_H + +#define MAPPING_H + +#include <sys/types.h> + +#ifdef __cplusplus +extern "C" { +#endif + +int get_mapping(size_t length, int prot, int flags, + int fd, off_t offset, + void ** presult, void ** pmapping, size_t * pmapping_size); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kmicromail/libetpan/tools/md5.c b/kmicromail/libetpan/tools/md5.c new file mode 100644 index 0000000..50307e0 --- a/dev/null +++ b/kmicromail/libetpan/tools/md5.c @@ -0,0 +1,570 @@ +/* + * libEtPan! -- a mail stuff library + * + * Copyright (C) 2001, 2002 - DINH Viet Hoa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the libEtPan! project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * $Id$ + */ + +/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm +*/ + +/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All +rights reserved. + +License to copy and use this software is granted provided that it +is identified as the "RSA Data Security, Inc. MD5 Message-Digest +Algorithm" in all material mentioning or referencing this software +or this function. + +License is also granted to make and use derivative works provided +that such works are identified as "derived from the RSA Data +Security, Inc. MD5 Message-Digest Algorithm" in all material +mentioning or referencing the derived work. + +RSA Data Security, Inc. makes no representations concerning either +the merchantability of this software or the suitability of this +software for any particular purpose. It is provided "as is" +without express or implied warranty of any kind. + +These notices must be retained in any copies of any part of this +documentation and/or software. +*/ + +/* do i need all of this just for htonl()? damn. */ +#include <sys/types.h> +#include <sys/param.h> +#include <sys/socket.h> +#include <netinet/in.h> + +#include "md5global.h" +#include "md5.h" +#include "hmac-md5.h" + +/* Constants for MD5Transform routine. +*/ + +#define S11 7 +#define S12 12 +#define S13 17 +#define S14 22 +#define S21 5 +#define S22 9 +#define S23 14 +#define S24 20 +#define S31 4 +#define S32 11 +#define S33 16 +#define S34 23 +#define S41 6 +#define S42 10 +#define S43 15 +#define S44 21 + +static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64])); +static void Encode PROTO_LIST + ((unsigned char *, UINT4 *, unsigned int)); +static void Decode PROTO_LIST + ((UINT4 *, unsigned char *, unsigned int)); +static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int)); +static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int)); + +static unsigned char PADDING[64] = { + 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, + 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 +}; + +/* F, G, H and I are basic MD5 functions. + + */ +#ifdef I +/* This might be defined via NANA */ +#undef I +#endif + +#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define I(x, y, z) ((y) ^ ((x) | (~z))) + +/* ROTATE_LEFT rotates x left n bits. + + */ + +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) + +/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. +Rotation is separate from addition to prevent recomputation. +*/ + +#define FF(a, b, c, d, x, s, ac) { (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); } +#define GG(a, b, c, d, x, s, ac) { (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); } +#define HH(a, b, c, d, x, s, ac) { (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); } +#define II(a, b, c, d, x, s, ac) { (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); } + +/* MD5 initialization. Begins an MD5 operation, writing a new context. +*/ + +void MD5Init (context) +MD5_CTX *context; /* context */ +{ + context->count[0] = context->count[1] = 0; + + /* Load magic initialization constants. + +*/ + context->state[0] = 0x67452301; + context->state[1] = 0xefcdab89; + context->state[2] = 0x98badcfe; + context->state[3] = 0x10325476; +} + +/* MD5 block update operation. Continues an MD5 message-digest + operation, processing another message block, and updating the context. +*/ + +void MD5Update (context, input, inputLen) +MD5_CTX *context; /* context */ +unsigned char *input; /* input block */ +unsigned int inputLen; /* length of input block */ +{ + unsigned int i, index, partLen; + + /* Compute number of bytes mod 64 */ + index = (unsigned int)((context->count[0] >> 3) & 0x3F); + + /* Update number of bits */ + if ((context->count[0] += ((UINT4)inputLen << 3)) + < ((UINT4)inputLen << 3)) + context->count[1]++; + context->count[1] += ((UINT4)inputLen >> 29); + + partLen = 64 - index; + + /* Transform as many times as possible. + +*/ + if (inputLen >= partLen) { + MD5_memcpy + ((POINTER)&context->buffer[index], (POINTER)input, partLen); MD5Transform + (context->state, context->buffer); + + for (i = partLen; i + 63 < inputLen; i += 64) + MD5Transform (context->state, &input[i]); + + index = 0; + } + else + i = 0; + + /* Buffer remaining input */ + MD5_memcpy + ((POINTER)&context->buffer[index], (POINTER)&input[i], + inputLen-i); + +} + +/* MD5 finalization. Ends an MD5 message-digest operation, writing the + the message digest and zeroizing the context. + + */ + +void MD5Final (digest, context) +unsigned char digest[16]; /* message digest */ +MD5_CTX *context; /* context */ +{ + unsigned char bits[8]; + unsigned int index, padLen; + + /* Save number of bits */ + Encode (bits, context->count, 8); + + /* Pad out to 56 mod 64. + +*/ + index = (unsigned int)((context->count[0] >> 3) & 0x3f); + padLen = (index < 56) ? (56 - index) : (120 - index); + MD5Update (context, PADDING, padLen); + + /* Append length (before padding) */ + MD5Update (context, bits, 8); + + /* Store state in digest */ + Encode (digest, context->state, 16); + + /* Zeroize sensitive information. + +*/ + MD5_memset ((POINTER)context, 0, sizeof (*context)); +} + +/* MD5 basic transformation. Transforms state based on block. + + */ + +static void MD5Transform (state, block) +UINT4 state[4]; +unsigned char block[64]; +{ + UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; + + Decode (x, block, 64); + + /* Round 1 */ + FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ + FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ + FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ + FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ + FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ + FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ + FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ + FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ + FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ + FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ + FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ + FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ + FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ + FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ + FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ + FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ + + /* Round 2 */ + GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ + GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ + GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ + GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ + GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ + GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ + GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ + GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ + GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ + GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ + GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ + GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ + GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ + GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ + GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ + GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ + + /* Round 3 */ + HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ + HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ + HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ + HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ + HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ + HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ + HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ + HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ + HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ + HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ + HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ + HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ + HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ + HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ + HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ + HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ + + /* Round 4 */ + II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ + II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ + II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ + II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ + II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ + II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ + II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ + II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ + II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ + II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ + II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ + II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ + II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ + II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ + II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ + II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + + /* Zeroize sensitive information. + */ + MD5_memset ((POINTER)x, 0, sizeof (x)); +} + +/* Encodes input (UINT4) into output (unsigned char). Assumes len is + a multiple of 4. + + */ + +static void Encode (output, input, len) +unsigned char *output; +UINT4 *input; +unsigned int len; +{ + unsigned int i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) { + output[j] = (unsigned char)(input[i] & 0xff); + output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); + output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); + output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); + } +} + +/* Decodes input (unsigned char) into output (UINT4). Assumes len is + a multiple of 4. + + */ + +static void Decode (output, input, len) +UINT4 *output; +unsigned char *input; +unsigned int len; +{ + unsigned int i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) + output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | (((UINT4)input[j+2]) << 16) + | (((UINT4)input[j+3]) << 24); +} + +/* Note: Replace "for loop" with standard memcpy if possible. + + */ + +static void MD5_memcpy (output, input, len) +POINTER output; +POINTER input; +unsigned int len; +{ + unsigned int i; + + for (i = 0; i < len; i++) + output[i] = input[i]; +} + +/* Note: Replace "for loop" with standard memset if possible. +*/ + +static void MD5_memset (output, value, len) +POINTER output; +int value; +unsigned int len; +{ + unsigned int i; + + for (i = 0; i < len; i++) + ((char *)output)[i] = (char)value; +} + +void hmac_md5_init(HMAC_MD5_CTX *hmac, + const unsigned char *key, + int key_len) +{ + unsigned char k_ipad[65]; /* inner padding - + * key XORd with ipad + */ + unsigned char k_opad[65]; /* outer padding - + * key XORd with opad + */ + unsigned char tk[16]; + int i; + /* if key is longer than 64 bytes reset it to key=MD5(key) */ + if (key_len > 64) { + + MD5_CTX tctx; + + MD5Init(&tctx); + MD5Update(&tctx, key, key_len); + MD5Final(tk, &tctx); + + key = tk; + key_len = 16; + } + + /* + * the HMAC_MD5 transform looks like: + * + * MD5(K XOR opad, MD5(K XOR ipad, text)) + * + * where K is an n byte key + * ipad is the byte 0x36 repeated 64 times + * opad is the byte 0x5c repeated 64 times + * and text is the data being protected + */ + + /* start out by storing key in pads */ + MD5_memset(k_ipad, '\0', sizeof k_ipad); + MD5_memset(k_opad, '\0', sizeof k_opad); + MD5_memcpy( k_ipad, key, key_len); + MD5_memcpy( k_opad, key, key_len); + + /* XOR key with ipad and opad values */ + for (i=0; i<64; i++) { + k_ipad[i] ^= 0x36; + k_opad[i] ^= 0x5c; + } + + MD5Init(&hmac->ictx); /* init inner context */ + MD5Update(&hmac->ictx, k_ipad, 64); /* apply inner pad */ + + MD5Init(&hmac->octx); /* init outer context */ + MD5Update(&hmac->octx, k_opad, 64); /* apply outer pad */ + + /* scrub the pads and key context (if used) */ + MD5_memset(&k_ipad, 0, sizeof(k_ipad)); + MD5_memset(&k_opad, 0, sizeof(k_opad)); + MD5_memset(&tk, 0, sizeof(tk)); + + /* and we're done. */ +} + +/* The precalc and import routines here rely on the fact that we pad + * the key out to 64 bytes and use that to initialize the md5 + * contexts, and that updating an md5 context with 64 bytes of data + * leaves nothing left over; all of the interesting state is contained + * in the state field, and none of it is left over in the count and + * buffer fields. So all we have to do is save the state field; we + * can zero the others when we reload it. Which is why the decision + * was made to pad the key out to 64 bytes in the first place. */ +void hmac_md5_precalc(HMAC_MD5_STATE *state, + const unsigned char *key, + int key_len) +{ + HMAC_MD5_CTX hmac; + unsigned lupe; + + hmac_md5_init(&hmac, key, key_len); + for (lupe = 0; lupe < 4; lupe++) { + state->istate[lupe] = htonl(hmac.ictx.state[lupe]); + state->ostate[lupe] = htonl(hmac.octx.state[lupe]); + } + MD5_memset(&hmac, 0, sizeof(hmac)); +} + + +void hmac_md5_import(HMAC_MD5_CTX *hmac, + HMAC_MD5_STATE *state) +{ + unsigned lupe; + MD5_memset(hmac, 0, sizeof(HMAC_MD5_CTX)); + for (lupe = 0; lupe < 4; lupe++) { + hmac->ictx.state[lupe] = ntohl(state->istate[lupe]); + hmac->octx.state[lupe] = ntohl(state->ostate[lupe]); + } + /* Init the counts to account for our having applied + * 64 bytes of key; this works out to 0x200 (64 << 3; see + * MD5Update above...) */ + hmac->ictx.count[0] = hmac->octx.count[0] = 0x200; +} + +void hmac_md5_final(unsigned char digest[HMAC_MD5_SIZE], + HMAC_MD5_CTX *hmac) +{ + MD5Final(digest, &hmac->ictx); /* Finalize inner md5 */ + MD5Update(&hmac->octx, digest, 16); /* Update outer ctx */ + MD5Final(digest, &hmac->octx); /* Finalize outer md5 */ +} + + +void hmac_md5(text, text_len, key, key_len, digest) +const unsigned char* text; /* pointer to data stream */ +int text_len; /* length of data stream */ +const unsigned char* key; /* pointer to authentication key */ +int key_len; /* length of authentication key */ +unsigned char *digest; /* caller digest to be filled in */ +{ + MD5_CTX context; + + unsigned char k_ipad[65]; /* inner padding - + * key XORd with ipad + */ + unsigned char k_opad[65]; /* outer padding - + * key XORd with opad + */ + unsigned char tk[16]; + int i; + /* if key is longer than 64 bytes reset it to key=MD5(key) */ + if (key_len > 64) { + + MD5_CTX tctx; + + MD5Init(&tctx); + MD5Update(&tctx, key, key_len); + MD5Final(tk, &tctx); + + key = tk; + key_len = 16; + } + + /* + * the HMAC_MD5 transform looks like: + * + * MD5(K XOR opad, MD5(K XOR ipad, text)) + * + * where K is an n byte key + * ipad is the byte 0x36 repeated 64 times + * opad is the byte 0x5c repeated 64 times + * and text is the data being protected + */ + + /* start out by storing key in pads */ + MD5_memset(k_ipad, '\0', sizeof k_ipad); + MD5_memset(k_opad, '\0', sizeof k_opad); + MD5_memcpy( k_ipad, key, key_len); + MD5_memcpy( k_opad, key, key_len); + + /* XOR key with ipad and opad values */ + for (i=0; i<64; i++) { + k_ipad[i] ^= 0x36; + k_opad[i] ^= 0x5c; + } + /* + * perform inner MD5 + */ + + MD5Init(&context); /* init context for 1st + * pass */ + MD5Update(&context, k_ipad, 64); /* start with inner pad */ + MD5Update(&context, text, text_len); /* then text of datagram */ + MD5Final(digest, &context); /* finish up 1st pass */ + + /* + * perform outer MD5 + */ + MD5Init(&context); /* init context for 2nd + * pass */ + MD5Update(&context, k_opad, 64); /* start with outer pad */ + MD5Update(&context, digest, 16); /* then results of 1st + * hash */ + MD5Final(digest, &context); /* finish up 2nd pass */ + +} diff --git a/kmicromail/libetpan/tools/md5.h b/kmicromail/libetpan/tools/md5.h new file mode 100644 index 0000000..e62f157 --- a/dev/null +++ b/kmicromail/libetpan/tools/md5.h @@ -0,0 +1,88 @@ +/* + * libEtPan! -- a mail stuff library + * + * Copyright (C) 2001, 2002 - DINH Viet Hoa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the libEtPan! project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * $Id$ + */ + +/* MD5.H - header file for MD5C.C + */ + +/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All +rights reserved. + +License to copy and use this software is granted provided that it +is identified as the "RSA Data Security, Inc. MD5 Message-Digest +Algorithm" in all material mentioning or referencing this software +or this function. + +License is also granted to make and use derivative works provided +that such works are identified as "derived from the RSA Data +Security, Inc. MD5 Message-Digest Algorithm" in all material +mentioning or referencing the derived work. + +RSA Data Security, Inc. makes no representations concerning either +the merchantability of this software or the suitability of this +software for any particular purpose. It is provided "as is" +without express or implied warranty of any kind. +These notices must be retained in any copies of any part of this +documentation and/or software. + */ + +#include "md5global.h" + +#ifndef MD5_H + +#define MD5_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* MD5 context. */ +typedef struct { + UINT4 state[4]; /* state (ABCD) */ + UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */ + unsigned char buffer[64]; /* input buffer */ +} MD5_CTX; + +void MD5Init PROTO_LIST ((MD5_CTX *)); +void MD5Update PROTO_LIST + ((MD5_CTX *, unsigned char *, unsigned int)); +void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *)); + +void hmac_md5 PROTO_LIST ((unsigned char *, int, unsigned char *, int, caddr_t)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kmicromail/libetpan/tools/md5global.h b/kmicromail/libetpan/tools/md5global.h new file mode 100644 index 0000000..9089c9a --- a/dev/null +++ b/kmicromail/libetpan/tools/md5global.h @@ -0,0 +1,79 @@ +/* + * libEtPan! -- a mail stuff library + * + * Copyright (C) 2001, 2002 - DINH Viet Hoa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the libEtPan! project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * $Id$ + */ + +/* GLOBAL.H - RSAREF types and constants + */ + +#ifndef MD5GLOBAL_H + +#define MD5GLOBAL_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* PROTOTYPES should be set to one if and only if the compiler supports + function argument prototyping. +The following makes PROTOTYPES default to 0 if it has not already + been defined with C compiler flags. + */ +#ifndef PROTOTYPES +#define PROTOTYPES 0 +#endif + +/* POINTER defines a generic pointer type */ +typedef unsigned char *POINTER; + +/* UINT2 defines a two byte word */ +typedef unsigned short int UINT2; + +/* UINT4 defines a four byte word */ +typedef unsigned long int UINT4; + +/* PROTO_LIST is defined depending on how PROTOTYPES is defined above. +If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it + returns an empty list. + */ +#if PROTOTYPES +#define PROTO_LIST(list) list +#else +#define PROTO_LIST(list) () +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kmicromail/libetpan/tools/mmapstring.c b/kmicromail/libetpan/tools/mmapstring.c new file mode 100644 index 0000000..8c44842 --- a/dev/null +++ b/kmicromail/libetpan/tools/mmapstring.c @@ -0,0 +1,526 @@ +/* + * libEtPan! -- a mail stuff library + * + * Copyright (C) 2001, 2002 - DINH Viet Hoa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the libEtPan! project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * $Id$ + */ + +#include "mmapstring.h" + +#include "chash.h" + +#include <stdlib.h> +#include <unistd.h> +#include <sys/mman.h> +#include <string.h> +#include <pthread.h> + +#include "libetpan-config.h" + +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) + +#define MMAP_STRING_DEFAULT_CEIL (8 * 1024 * 1024) + +#define DEFAULT_TMP_PATH "/tmp" + +static char tmpdir[PATH_MAX] = DEFAULT_TMP_PATH; + +static size_t mmap_string_ceil = MMAP_STRING_DEFAULT_CEIL; + +/* MMAPString references */ + +static pthread_mutex_t mmapstring_lock = PTHREAD_MUTEX_INITIALIZER; +static chash * mmapstring_hashtable = NULL; + +static void mmapstring_hashtable_init() +{ + mmapstring_hashtable = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYKEY); +} + +void mmap_string_set_tmpdir(char * directory) +{ + strncpy(tmpdir, directory, PATH_MAX); + tmpdir[PATH_MAX - 1] = 0; +} + + +int mmap_string_ref(MMAPString * string) +{ + chash * ht; + int r; + chashdatum key; + chashdatum data; + + pthread_mutex_lock(&mmapstring_lock); + if (mmapstring_hashtable == NULL) { + mmapstring_hashtable_init(); + } + ht = mmapstring_hashtable; + + if (ht == NULL) { + pthread_mutex_unlock(&mmapstring_lock); + return -1; + } + + key.data = &string->str; + key.len = sizeof(string->str); + data.data = string; + data.len = 0; + + r = chash_set(mmapstring_hashtable, &key, &data, NULL); + pthread_mutex_unlock(&mmapstring_lock); + + if (r < 0) + return r; + + return 0; +} + +int mmap_string_unref(char * str) +{ + MMAPString * string; + chash * ht; + chashdatum key; + chashdatum data; + int r; + + pthread_mutex_lock(&mmapstring_lock); + ht = mmapstring_hashtable; + + if (ht == NULL) { + pthread_mutex_unlock(&mmapstring_lock); + return -1; + } + + key.data = &str; + key.len = sizeof(str); + + r = chash_get(ht, &key, &data); + if (r < 0) + string = NULL; + else + string = data.data; + + if (string != NULL) { + chash_delete(ht, &key, NULL); + if (chash_count(ht) == 0) { + chash_free(ht); + mmapstring_hashtable = NULL; + } + } + + pthread_mutex_unlock(&mmapstring_lock); + + if (string != NULL) { + mmap_string_free(string); + return 0; + } + else + return -1; +} + + + +/* MMAPString */ + +#define MY_MAXSIZE ((size_t) -1) + +static inline size_t +nearest_power (size_t base, size_t num) +{ + if (num > MY_MAXSIZE / 2) { + return MY_MAXSIZE; + } + else { + size_t n = base; + + while (n < num) + n <<= 1; + + return n; + } +} + +void mmap_string_set_ceil(size_t ceil) +{ + mmap_string_ceil = ceil; +} + +/* Strings. + */ + +static MMAPString * mmap_string_realloc_file(MMAPString * string) +{ + char * data; + + if (string->fd == -1) { + char tmpfilename[PATH_MAX]; + int fd; + + * tmpfilename = 0; + strcat(tmpfilename, tmpdir); + strcat(tmpfilename, "/libetpan-mmapstring-XXXXXX"); + + fd = mkstemp(tmpfilename); + if (fd == -1) + return NULL; + + if (unlink(tmpfilename) == -1) { + close(fd); + return NULL; + } + + if (ftruncate(fd, string->allocated_len) == -1) { + close(fd); + return NULL; + } + + data = mmap(NULL, string->allocated_len, PROT_WRITE | PROT_READ, + MAP_SHARED, fd, 0); + + if (data == MAP_FAILED) { + close(fd); + return NULL; + } + + if (string->str != NULL) + memcpy(data, string->str, string->len + 1); + + string->fd = fd; + string->mmapped_size = string->allocated_len; + free(string->str); + string->str = data; + } + else { + if (munmap(string->str, string->mmapped_size) == -1) + return NULL; + + if (ftruncate(string->fd, string->allocated_len) == -1) + return NULL; + + data = mmap(NULL, string->allocated_len, PROT_WRITE | PROT_READ, + MAP_SHARED, string->fd, 0); + + if (data == MAP_FAILED) + return NULL; + + string->mmapped_size = string->allocated_len; + string->str = data; + } + + return string; +} + +static MMAPString * mmap_string_realloc_memory(MMAPString * string) +{ + char * tmp; + + tmp = realloc (string->str, string->allocated_len); + + if (tmp == NULL) + string = NULL; + else + string->str = tmp; + + return string; +} + +static MMAPString * +mmap_string_maybe_expand (MMAPString* string, + size_t len) +{ + if (string->len + len >= string->allocated_len) + { + size_t old_size; + MMAPString * newstring; + + old_size = string->allocated_len; + + string->allocated_len = nearest_power (1, string->len + len + 1); + +#ifndef MMAP_UNAVAILABLE + if (string->allocated_len > mmap_string_ceil) + newstring = mmap_string_realloc_file(string); + else { +#endif + newstring = mmap_string_realloc_memory(string); +#ifndef MMAP_UNAVAILABLE + if (newstring == NULL) + newstring = mmap_string_realloc_file(string); + } +#endif + + if (newstring == NULL) + string->allocated_len = old_size; + } + + return string; +} + +MMAPString* +mmap_string_sized_new (size_t dfl_size) +{ + MMAPString *string; + + string = malloc(sizeof(* string)); + if (string == NULL) + return NULL; + + string->allocated_len = 0; + string->len = 0; + string->str = NULL; + string->fd = -1; + string->mmapped_size = 0; + + if (mmap_string_maybe_expand (string, MAX (dfl_size, 2)) == NULL) + return NULL; + + string->str[0] = 0; + + return string; +} + +MMAPString* +mmap_string_new (const char *init) +{ + MMAPString *string; + + string = mmap_string_sized_new (init ? strlen (init) + 2 : 2); + if (string == NULL) + return NULL; + + if (init) + mmap_string_append (string, init); + + return string; +} + +MMAPString* +mmap_string_new_len (const char *init, + size_t len) +{ + MMAPString *string; + + if (len <= 0) + return mmap_string_new (init); + else + { + string = mmap_string_sized_new (len); + + if (init) + mmap_string_append_len (string, init, len); + + return string; + } +} + +void +mmap_string_free (MMAPString *string) +{ + if (string == NULL) + return; + + if (string->fd != -1) { + munmap(string->str, string->mmapped_size); + close(string->fd); + } + else { + free (string->str); + } + free(string); +} + +MMAPString* +mmap_string_assign (MMAPString *string, + const char *rval) +{ + mmap_string_truncate (string, 0); + if (mmap_string_append (string, rval) == NULL) + return NULL; + + return string; +} + +MMAPString* +mmap_string_truncate (MMAPString *string, + size_t len) +{ + string->len = MIN (len, string->len); + string->str[string->len] = 0; + + return string; +} + +/** + * mmap_string_set_size: + * @string: a #MMAPString + * @len: the new length + * + * Sets the length of a #MMAPString. If the length is less than + * the current length, the string will be truncated. If the + * length is greater than the current length, the contents + * of the newly added area are undefined. (However, as + * always, string->str[string->len] will be a nul byte.) + * + * Return value: @string + **/ +MMAPString* +mmap_string_set_size (MMAPString *string, + size_t len) +{ + if (len >= string->allocated_len) + if (mmap_string_maybe_expand (string, len - string->len) == NULL) + return NULL; + + string->len = len; + string->str[len] = 0; + + return string; +} + +/* +static int in_mapped_zone(MMAPString * string, char * val) +{ + return (val >= string->str) && (val < string->str + string->mmapped_size); +} +*/ + +MMAPString* +mmap_string_insert_len (MMAPString *string, + size_t pos, + const char *val, + size_t len) +{ + if (mmap_string_maybe_expand (string, len) == NULL) + return NULL; + + if (pos < string->len) + memmove (string->str + pos + len, string->str + pos, string->len - pos); + + /* insert the new string */ + memmove (string->str + pos, val, len); + + string->len += len; + + string->str[string->len] = 0; + + return string; +} + +MMAPString* +mmap_string_append (MMAPString *string, + const char *val) +{ + return mmap_string_insert_len (string, string->len, val, strlen(val)); +} + +MMAPString* +mmap_string_append_len (MMAPString *string, + const char *val, + size_t len) +{ + return mmap_string_insert_len (string, string->len, val, len); +} + +MMAPString* +mmap_string_append_c (MMAPString *string, + char c) +{ + return mmap_string_insert_c (string, string->len, c); +} + +MMAPString* +mmap_string_prepend (MMAPString *string, + const char *val) +{ + return mmap_string_insert_len (string, 0, val, strlen(val)); +} + +MMAPString* +mmap_string_prepend_len (MMAPString *string, + const char *val, + size_t len) +{ + return mmap_string_insert_len (string, 0, val, len); +} + +MMAPString* +mmap_string_prepend_c (MMAPString *string, + char c) +{ + return mmap_string_insert_c (string, 0, c); +} + +MMAPString* +mmap_string_insert (MMAPString *string, + size_t pos, + const char *val) +{ + return mmap_string_insert_len (string, pos, val, strlen(val)); +} + +MMAPString* +mmap_string_insert_c (MMAPString *string, + size_t pos, + char c) +{ + if (mmap_string_maybe_expand (string, 1) == NULL) + return NULL; + + /* If not just an append, move the old stuff */ + if (pos < string->len) + memmove (string->str + pos + 1, string->str + pos, string->len - pos); + + string->str[pos] = c; + + string->len += 1; + + string->str[string->len] = 0; + + return string; +} + +MMAPString* +mmap_string_erase (MMAPString *string, + size_t pos, + size_t len) +{ + if ((pos + len) < string->len) + memmove (string->str + pos, string->str + pos + len, + string->len - (pos + len)); + + string->len -= len; + + string->str[string->len] = 0; + + return string; +} diff --git a/kmicromail/libetpan/tools/mmapstring.h b/kmicromail/libetpan/tools/mmapstring.h new file mode 100644 index 0000000..6d7227d --- a/dev/null +++ b/kmicromail/libetpan/tools/mmapstring.h @@ -0,0 +1,136 @@ +/* + * libEtPan! -- a mail stuff library + * + * Copyright (C) 2001, 2002 - DINH Viet Hoa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the libEtPan! project nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * $Id$ + */ + +#ifndef __MMAP_STRING_H__ + +#define __MMAP_STRING_H__ + +#include <sys/types.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* +#define TMPDIR "/tmp" +*/ + +typedef struct _MMAPString MMAPString; + +struct _MMAPString +{ + char * str; + size_t len; + size_t allocated_len; + int fd; + size_t mmapped_size; + /* + char * old_non_mmapped_str; + */ +}; + +/* configure location of mmaped files */ + +void mmap_string_set_tmpdir(char * directory); + +/* Strings + */ + +MMAPString * mmap_string_new (const char * init); + +MMAPString * mmap_string_new_len (const char * init, + size_t len); + +MMAPString * mmap_string_sized_new (size_t dfl_size); + +void mmap_string_free (MMAPString * string); + +MMAPString * mmap_string_assign (MMAPString * string, + const char * rval); + +MMAPString * mmap_string_truncate (MMAPString *string, + size_t len); + +MMAPString * mmap_string_set_size (MMAPString * string, + size_t len); + +MMAPString * mmap_string_insert_len (MMAPString * string, + size_t pos, + const char * val, + size_t len); + +MMAPString * mmap_string_append (MMAPString * string, + const char * val); + +MMAPString * mmap_string_append_len (MMAPString * string, + const char * val, + size_t len); + +MMAPString * mmap_string_append_c (MMAPString * string, + char c); + +MMAPString * mmap_string_prepend (MMAPString * string, + const char * val); + +MMAPString * mmap_string_prepend_c (MMAPString * string, + char c); + +MMAPString * mmap_string_prepend_len (MMAPString * string, + const char * val, + size_t len); + +MMAPString * mmap_string_insert (MMAPString * string, + size_t pos, + const char * val); + +MMAPString * mmap_string_insert_c (MMAPString *string, + size_t pos, + char c); + +MMAPString * mmap_string_erase(MMAPString * string, + size_t pos, + size_t len); + +void mmap_string_set_ceil(size_t ceil); + +int mmap_string_ref(MMAPString * string); +int mmap_string_unref(char * str); + +#ifdef __cplusplus +} +#endif + + +#endif /* __MMAP_STRING_H__ */ |