add libetpan 0.48 to in tree libs

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@3763 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Michael Jerris
2006-12-20 20:28:56 +00:00
parent 94568cb6cc
commit 838eb8aaec
459 changed files with 266317 additions and 0 deletions
+3
View File
@@ -0,0 +1,3 @@
.libs
Makefile
*.la
+68
View File
@@ -0,0 +1,68 @@
top_builddir = ..
prefix = @prefix@
exec_prefix = @exec_prefix@
libdir = @libdir@
includedir = @includedir@
mandir = @mandir@
bindir = @bindir@
SHELL = /bin/sh
RM = rm -fr
INSTALL = @INSTALL@
LIBTOOL = @LIBTOOL@
@SET_MAKE@
TARGET = libetpan@LIBSUFFIX@.la
VERSINFO = @API_VERSION@
CC = @CC@
LDFLAGS = @LDFLAGS@ @LIBS@ @SSLLIBS@ @LIBICONV@ @DBLIB@ @GNUTLSLIB@ @SASLLIBS@
SUBLIBS = data-types/libdata-types.la \
low-level/liblow-level.la \
driver/libdriver.la \
main/libmain.la \
engine/libengine.la
SUBDIRS = data-types \
low-level \
driver \
main \
engine
all: $(TARGET)
$(TARGET): Makefile $(SUBLIBS)
$(LIBTOOL) --mode=link $(CC) $(LDFLAGS) -o $@ $(SUBLIBS) \
-rpath $(libdir) -version-info $(VERSINFO)
$(SUBLIBS): all-recursive
install: all install-dirs install-recursive
$(LIBTOOL) --mode=install $(INSTALL) -m 644 $(TARGET) $(DESTDIR)$(libdir)
install-dirs:
$(INSTALL) -d -m 755 $(DESTDIR)$(libdir)
clean: clean-recursive
$(RM) -fr $(TARGET) .libs
prepare: prepare-recursive
all-recursive install-recursive clean-recursive \
distclean-recursive prepare-recursive:
@set fnord $(MAKEFLAGS); amf=$$2; \
list='$(SUBDIRS)'; for subdir in $$list; do \
target=`echo $@ | sed s/-recursive//`; \
echo "Making $$target in $$subdir"; \
(cd $$subdir && $(MAKE) $$target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done && test -z "$$fail"
Makefile: Makefile.in ../config.status
cd ${top_builddir} && CONFIG_FILES=src/Makefile CONFIG_HEADERS= ./config.status
distclean: clean
rm -rf Makefile
+149
View File
@@ -0,0 +1,149 @@
/* $NetBSD: getopt.c,v 1.26 2003/08/07 16:43:40 agc Exp $ */
/*
* Copyright (c) 1987, 1993, 1994
* The Regents of the University of California. 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. 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.
*
* 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.
*/
/*
Modified by Sebastien Marinier for windows OS
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)getopt.c 8.3 (Berkeley) 4/27/95";
#endif /* LIBC_SCCS and not lint */
#ifdef _MSC_VER
# define _getprogname() nargv[0]
#else
# include <sys/cdefs.h>
__FBSDID("$FreeBSD: /repoman/r/ncvs/src/lib/libc/stdlib/getopt.c,v 1.7 2004/03/06 17:05:45 ache Exp $");
#include "namespace.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "un-namespace.h"
#include "libc_private.h"
#endif
int opterr = 1, /* if error message should be printed */
optind = 1, /* index into parent argv vector */
optopt, /* character checked for validity */
optreset; /* reset getopt */
char *optarg; /* argument associated with option */
#define BADCH (int)'?'
#define BADARG (int)':'
#define EMSG ""
/*
* getopt --
* Parse argc/argv argument vector.
*/
int
getopt(nargc, nargv, ostr)
int nargc;
char * const nargv[];
const char *ostr;
{
static char *place = EMSG; /* option letter processing */
char *oli; /* option letter list index */
if (optreset || *place == 0) { /* update scanning pointer */
optreset = 0;
place = nargv[optind];
if (optind >= nargc || *place++ != '-') {
/* Argument is absent or is not an option */
place = EMSG;
return (-1);
}
optopt = *place++;
if (optopt == '-' && *place == 0) {
/* "--" => end of options */
++optind;
place = EMSG;
return (-1);
}
if (optopt == 0) {
/* Solitary '-', treat as a '-' option
if the program (eg su) is looking for it. */
place = EMSG;
if (strchr(ostr, '-') == NULL)
return (-1);
optopt = '-';
}
} else
optopt = *place++;
/* See if option letter is one the caller wanted... */
if (optopt == ':' || (oli = strchr(ostr, optopt)) == NULL) {
if (*place == 0)
++optind;
if (opterr && *ostr != ':')
(void)fprintf(stderr,
"%s: illegal option -- %c\n", _getprogname(),
optopt);
return (BADCH);
}
/* Does this option need an argument? */
if (oli[1] != ':') {
/* don't need argument */
optarg = NULL;
if (*place == 0)
++optind;
} else {
/* Option-argument is either the rest of this argument or the
entire next argument. */
if (*place)
optarg = place;
else if (nargc > ++optind)
optarg = nargv[optind];
else {
/* option-argument absent */
place = EMSG;
if (*ostr == ':')
return (BADARG);
if (opterr)
(void)fprintf(stderr,
"%s: option requires an argument -- %c\n",
_getprogname(), optopt);
return (BADCH);
}
place = EMSG;
++optind;
}
return (optopt); /* return option letter */
}
+93
View File
@@ -0,0 +1,93 @@
/* $NetBSD: getopt.h,v 1.4 2000/07/07 10:43:54 ad Exp $ */
/* $FreeBSD: /repoman/r/ncvs/src/include/getopt.h,v 1.6 2004/02/24 08:09:20 ache Exp $ */
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Dieter Baron and Thomas Klausner.
*
* 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, 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 THE FOUNDATION 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.
*/
/*
Modified by Sebastien Marinier for windows OS
*/
#ifndef _GETOPT_H_
#define _GETOPT_H_
#ifdef _MSC_VER
# define __BEGIN_DECLS
# define __END_DECLS
#else
# include <sys/cdefs.h>
#endif
/*
* GNU-like getopt_long()/getopt_long_only() with 4.4BSD optreset extension.
* getopt() is declared here too for GNU programs.
*/
#define no_argument 0
#define required_argument 1
#define optional_argument 2
struct option {
/* name of long option */
const char *name;
/*
* one of no_argument, required_argument, and optional_argument:
* whether option takes an argument
*/
int has_arg;
/* if not NULL, set *flag to val when option found */
int *flag;
/* if flag not NULL, value to set *flag to; else return value */
int val;
};
__BEGIN_DECLS
int getopt_long(int, char * const *, const char *,
const struct option *, int *);
int getopt_long_only(int, char * const *, const char *,
const struct option *, int *);
#ifndef _GETOPT_DECLARED
#define _GETOPT_DECLARED
int getopt(int, char * const [], const char *);
extern char *optarg; /* getopt(3) external variables */
extern int optind, opterr, optopt;
#endif
#ifndef _OPTRESET_DECLARED
#define _OPTRESET_DECLARED
extern int optreset; /* getopt(3) external variable */
#endif
__END_DECLS
#endif /* !_GETOPT_H_ */
+651
View File
@@ -0,0 +1,651 @@
/* $OpenBSD: getopt_long.c,v 1.17 2004/06/03 18:46:52 millert Exp $ */
/* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */
/*
* Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Sponsored in part by the Defense Advanced Research Projects
* Agency (DARPA) and Air Force Research Laboratory, Air Force
* Materiel Command, USAF, under agreement number F39502-99-1-0512.
*/
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Dieter Baron and Thomas Klausner.
*
* 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, 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 THE FOUNDATION 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.
*/
/*
Modified by Sebastien Marinier for windows OS
*/
#if 0
#if defined(LIBC_SCCS) && !defined(lint)
static char *rcsid = "$OpenBSD: getopt_long.c,v 1.16 2004/02/04 18:17:25 millert Exp $";
#endif /* LIBC_SCCS and not lint */
#endif
#ifdef _MSC_VER
#include "getopt.h"
static void warnx() {
}
#else
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: /repoman/r/ncvs/src/lib/libc/stdlib/getopt_long.c,v 1.12 2004/07/06 13:58:45 ache Exp $");
#include <err.h>
#include <errno.h>
#include <getopt.h>
#endif
#include <stdlib.h>
#include <string.h>
#define GNU_COMPATIBLE /* Be more compatible, configure's use us! */
#ifndef GNU_COMPATIBLE
#define REPLACE_GETOPT /* use this getopt as the system getopt(3) */
#endif
#ifdef REPLACE_GETOPT
int opterr = 1; /* if error message should be printed */
int optind = 1; /* index into parent argv vector */
int optopt = '?'; /* character checked for validity */
int optreset; /* reset getopt */
char *optarg; /* argument associated with option */
#endif
#define PRINT_ERROR ((opterr) && (*options != ':'))
#define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */
#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */
#define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */
/* return values */
#define BADCH (int)'?'
#define BADARG ((*options == ':') ? (int)':' : (int)'?')
#define INORDER (int)1
#define EMSG ""
#ifdef GNU_COMPATIBLE
#define NO_PREFIX (-1)
#define D_PREFIX 0
#define DD_PREFIX 1
#define W_PREFIX 2
#endif
static int getopt_internal(int, char * const *, const char *,
const struct option *, int *, int);
static int parse_long_options(char * const *, const char *,
const struct option *, int *, int, int);
static int gcd(int, int);
static void permute_args(int, int, int, char * const *);
static char *place = EMSG; /* option letter processing */
/* XXX: set optreset to 1 rather than these two */
static int nonopt_start = -1; /* first non option argument (for permute) */
static int nonopt_end = -1; /* first option after non options (for permute) */
/* Error messages */
static const char recargchar[] = "option requires an argument -- %c";
static const char illoptchar[] = "illegal option -- %c"; /* From P1003.2 */
#ifdef GNU_COMPATIBLE
static int dash_prefix = NO_PREFIX;
static const char gnuoptchar[] = "invalid option -- %c";
static const char recargstring[] = "option `%s%s' requires an argument";
static const char ambig[] = "option `%s%.*s' is ambiguous";
static const char noarg[] = "option `%s%.*s' doesn't allow an argument";
static const char illoptstring[] = "unrecognized option `%s%s'";
#else
static const char recargstring[] = "option requires an argument -- %s";
static const char ambig[] = "ambiguous option -- %.*s";
static const char noarg[] = "option doesn't take an argument -- %.*s";
static const char illoptstring[] = "unknown option -- %s";
#endif
/*
* Compute the greatest common divisor of a and b.
*/
static int
gcd(int a, int b)
{
int c;
c = a % b;
while (c != 0) {
a = b;
b = c;
c = a % b;
}
return (b);
}
/*
* Exchange the block from nonopt_start to nonopt_end with the block
* from nonopt_end to opt_end (keeping the same order of arguments
* in each block).
*/
static void
permute_args(int panonopt_start, int panonopt_end, int opt_end,
char * const *nargv)
{
int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;
char *swap;
/*
* compute lengths of blocks and number and size of cycles
*/
nnonopts = panonopt_end - panonopt_start;
nopts = opt_end - panonopt_end;
ncycle = gcd(nnonopts, nopts);
cyclelen = (opt_end - panonopt_start) / ncycle;
for (i = 0; i < ncycle; i++) {
cstart = panonopt_end+i;
pos = cstart;
for (j = 0; j < cyclelen; j++) {
if (pos >= panonopt_end)
pos -= nnonopts;
else
pos += nopts;
swap = nargv[pos];
/* LINTED const cast */
((char **) nargv)[pos] = nargv[cstart];
/* LINTED const cast */
((char **)nargv)[cstart] = swap;
}
}
}
/*
* parse_long_options --
* Parse long options in argc/argv argument vector.
* Returns -1 if short_too is set and the option does not match long_options.
*/
static int
parse_long_options(char * const *nargv, const char *options,
const struct option *long_options, int *idx, int short_too, int flags)
{
char *current_argv, *has_equal;
#ifdef GNU_COMPATIBLE
char *current_dash;
#endif
size_t current_argv_len;
int i, match, exact_match, second_partial_match;
current_argv = place;
#ifdef GNU_COMPATIBLE
switch (dash_prefix) {
case D_PREFIX:
current_dash = "-";
break;
case DD_PREFIX:
current_dash = "--";
break;
case W_PREFIX:
current_dash = "-W ";
break;
default:
current_dash = "";
break;
}
#endif
match = -1;
exact_match = 0;
second_partial_match = 0;
optind++;
if ((has_equal = strchr(current_argv, '=')) != NULL) {
/* argument found (--option=arg) */
current_argv_len = has_equal - current_argv;
has_equal++;
} else
current_argv_len = strlen(current_argv);
for (i = 0; long_options[i].name; i++) {
/* find matching long option */
if (strncmp(current_argv, long_options[i].name,
current_argv_len))
continue;
if (strlen(long_options[i].name) == current_argv_len) {
/* exact match */
match = i;
exact_match = 1;
break;
}
/*
* If this is a known short option, don't allow
* a partial match of a single character.
*/
if (short_too && current_argv_len == 1)
continue;
if (match == -1) /* first partial match */
match = i;
else if ((flags & FLAG_LONGONLY) ||
long_options[i].has_arg !=
long_options[match].has_arg ||
long_options[i].flag != long_options[match].flag ||
long_options[i].val != long_options[match].val)
second_partial_match = 1;
}
if (!exact_match && second_partial_match) {
/* ambiguous abbreviation */
if (PRINT_ERROR)
warnx(ambig,
#ifdef GNU_COMPATIBLE
current_dash,
#endif
(int)current_argv_len,
current_argv);
optopt = 0;
return (BADCH);
}
if (match != -1) { /* option found */
if (long_options[match].has_arg == no_argument
&& has_equal) {
if (PRINT_ERROR)
warnx(noarg,
#ifdef GNU_COMPATIBLE
current_dash,
#endif
(int)current_argv_len,
current_argv);
/*
* XXX: GNU sets optopt to val regardless of flag
*/
if (long_options[match].flag == NULL)
optopt = long_options[match].val;
else
optopt = 0;
#ifdef GNU_COMPATIBLE
return (BADCH);
#else
return (BADARG);
#endif
}
if (long_options[match].has_arg == required_argument ||
long_options[match].has_arg == optional_argument) {
if (has_equal)
optarg = has_equal;
else if (long_options[match].has_arg ==
required_argument) {
/*
* optional argument doesn't use next nargv
*/
optarg = nargv[optind++];
}
}
if ((long_options[match].has_arg == required_argument)
&& (optarg == NULL)) {
/*
* Missing argument; leading ':' indicates no error
* should be generated.
*/
if (PRINT_ERROR)
warnx(recargstring,
#ifdef GNU_COMPATIBLE
current_dash,
#endif
current_argv);
/*
* XXX: GNU sets optopt to val regardless of flag
*/
if (long_options[match].flag == NULL)
optopt = long_options[match].val;
else
optopt = 0;
--optind;
return (BADARG);
}
} else { /* unknown option */
if (short_too) {
--optind;
return (-1);
}
if (PRINT_ERROR)
warnx(illoptstring,
#ifdef GNU_COMPATIBLE
current_dash,
#endif
current_argv);
optopt = 0;
return (BADCH);
}
if (idx)
*idx = match;
if (long_options[match].flag) {
*long_options[match].flag = long_options[match].val;
return (0);
} else
return (long_options[match].val);
}
/*
* getopt_internal --
* Parse argc/argv argument vector. Called by user level routines.
*/
static int
getopt_internal(int nargc, char * const *nargv, const char *options,
const struct option *long_options, int *idx, int flags)
{
char *oli; /* option letter list index */
int optchar, short_too;
int posixly_correct;
if (options == NULL)
return (-1);
/*
* Disable GNU extensions if POSIXLY_CORRECT is set or options
* string begins with a '+'.
*/
posixly_correct = (getenv("POSIXLY_CORRECT") != NULL);
#ifdef GNU_COMPATIBLE
if (*options == '-')
flags |= FLAG_ALLARGS;
else if (posixly_correct || *options == '+')
flags &= ~FLAG_PERMUTE;
#else
if (posixly_correct || *options == '+')
flags &= ~FLAG_PERMUTE;
else if (*options == '-')
flags |= FLAG_ALLARGS;
#endif
if (*options == '+' || *options == '-')
options++;
/*
* XXX Some GNU programs (like cvs) set optind to 0 instead of
* XXX using optreset. Work around this braindamage.
*/
if (optind == 0)
optind = optreset = 1;
optarg = NULL;
if (optreset)
nonopt_start = nonopt_end = -1;
start:
if (optreset || !*place) { /* update scanning pointer */
optreset = 0;
if (optind >= nargc) { /* end of argument vector */
place = EMSG;
if (nonopt_end != -1) {
/* do permutation, if we have to */
permute_args(nonopt_start, nonopt_end,
optind, nargv);
optind -= nonopt_end - nonopt_start;
}
else if (nonopt_start != -1) {
/*
* If we skipped non-options, set optind
* to the first of them.
*/
optind = nonopt_start;
}
nonopt_start = nonopt_end = -1;
return (-1);
}
if (*(place = nargv[optind]) != '-' ||
#ifdef GNU_COMPATIBLE
place[1] == '\0') {
#else
(place[1] == '\0' && strchr(options, '-') == NULL)) {
#endif
place = EMSG; /* found non-option */
if (flags & FLAG_ALLARGS) {
/*
* GNU extension:
* return non-option as argument to option 1
*/
optarg = nargv[optind++];
return (INORDER);
}
if (!(flags & FLAG_PERMUTE)) {
/*
* If no permutation wanted, stop parsing
* at first non-option.
*/
return (-1);
}
/* do permutation */
if (nonopt_start == -1)
nonopt_start = optind;
else if (nonopt_end != -1) {
permute_args(nonopt_start, nonopt_end,
optind, nargv);
nonopt_start = optind -
(nonopt_end - nonopt_start);
nonopt_end = -1;
}
optind++;
/* process next argument */
goto start;
}
if (nonopt_start != -1 && nonopt_end == -1)
nonopt_end = optind;
/*
* If we have "-" do nothing, if "--" we are done.
*/
if (place[1] != '\0' && *++place == '-' && place[1] == '\0') {
optind++;
place = EMSG;
/*
* We found an option (--), so if we skipped
* non-options, we have to permute.
*/
if (nonopt_end != -1) {
permute_args(nonopt_start, nonopt_end,
optind, nargv);
optind -= nonopt_end - nonopt_start;
}
nonopt_start = nonopt_end = -1;
return (-1);
}
}
/*
* Check long options if:
* 1) we were passed some
* 2) the arg is not just "-"
* 3) either the arg starts with -- we are getopt_long_only()
*/
if (long_options != NULL && place != nargv[optind] &&
(*place == '-' || (flags & FLAG_LONGONLY))) {
short_too = 0;
#ifdef GNU_COMPATIBLE
dash_prefix = D_PREFIX;
#endif
if (*place == '-') {
place++; /* --foo long option */
#ifdef GNU_COMPATIBLE
dash_prefix = DD_PREFIX;
#endif
} else if (*place != ':' && strchr(options, *place) != NULL)
short_too = 1; /* could be short option too */
optchar = parse_long_options(nargv, options, long_options,
idx, short_too, flags);
if (optchar != -1) {
place = EMSG;
return (optchar);
}
}
if ((optchar = (int)*place++) == (int)':' ||
(optchar == (int)'-' && *place != '\0') ||
(oli = strchr(options, optchar)) == NULL) {
/*
* If the user specified "-" and '-' isn't listed in
* options, return -1 (non-option) as per POSIX.
* Otherwise, it is an unknown option character (or ':').
*/
if (optchar == (int)'-' && *place == '\0')
return (-1);
if (!*place)
++optind;
#ifdef GNU_COMPATIBLE
if (PRINT_ERROR)
warnx(posixly_correct ? illoptchar : gnuoptchar,
optchar);
#else
if (PRINT_ERROR)
warnx(illoptchar, optchar);
#endif
optopt = optchar;
return (BADCH);
}
if (long_options != NULL && optchar == 'W' && oli[1] == ';') {
/* -W long-option */
if (*place) /* no space */
/* NOTHING */;
else if (++optind >= nargc) { /* no arg */
place = EMSG;
if (PRINT_ERROR)
warnx(recargchar, optchar);
optopt = optchar;
return (BADARG);
} else /* white space */
place = nargv[optind];
#ifdef GNU_COMPATIBLE
dash_prefix = W_PREFIX;
#endif
optchar = parse_long_options(nargv, options, long_options,
idx, 0, flags);
place = EMSG;
return (optchar);
}
if (*++oli != ':') { /* doesn't take argument */
if (!*place)
++optind;
} else { /* takes (optional) argument */
optarg = NULL;
if (*place) /* no white space */
optarg = place;
/* XXX: disable test for :: if PC? (GNU doesn't) */
else if (oli[1] != ':') { /* arg not optional */
if (++optind >= nargc) { /* no arg */
place = EMSG;
if (PRINT_ERROR)
warnx(recargchar, optchar);
optopt = optchar;
return (BADARG);
} else
optarg = nargv[optind];
} else if (!(flags & FLAG_PERMUTE)) {
/*
* If permutation is disabled, we can accept an
* optional arg separated by whitespace so long
* as it does not start with a dash (-).
*/
if (optind + 1 < nargc && *nargv[optind + 1] != '-')
optarg = nargv[++optind];
}
place = EMSG;
++optind;
}
/* dump back option letter */
return (optchar);
}
#ifdef REPLACE_GETOPT
/*
* getopt --
* Parse argc/argv argument vector.
*
* [eventually this will replace the BSD getopt]
*/
int
getopt(int nargc, char * const *nargv, const char *options)
{
/*
* We don't pass FLAG_PERMUTE to getopt_internal() since
* the BSD getopt(3) (unlike GNU) has never done this.
*
* Furthermore, since many privileged programs call getopt()
* before dropping privileges it makes sense to keep things
* as simple (and bug-free) as possible.
*/
return (getopt_internal(nargc, nargv, options, NULL, NULL, 0));
}
#endif /* REPLACE_GETOPT */
/*
* getopt_long --
* Parse argc/argv argument vector.
*/
int
getopt_long(nargc, nargv, options, long_options, idx)
int nargc;
char * const *nargv;
const char *options;
const struct option *long_options;
int *idx;
{
return (getopt_internal(nargc, nargv, options, long_options, idx,
FLAG_PERMUTE));
}
/*
* getopt_long_only --
* Parse argc/argv argument vector.
*/
int
getopt_long_only(nargc, nargv, options, long_options, idx)
int nargc;
char * const *nargv;
const char *options;
const struct option *long_options;
int *idx;
{
return (getopt_internal(nargc, nargv, options, long_options, idx,
FLAG_PERMUTE|FLAG_LONGONLY));
}
+3
View File
@@ -0,0 +1,3 @@
.libs
*.la
*.lo
+17
View File
@@ -0,0 +1,17 @@
top_builddir = ../..
TARGET = libdata-types
HEADERS = mmapstring.h mailstream.h mailstream_helper.h mail.h \
mailstream_low.h \
mailstream_socket.h mailstream_ssl.h \
mailstream_types.h \
carray.h clist.h chash.h cinthash.h \
charconv.h mailsem.h maillock.h
SOURCES = connect.c md5.c mmapstring.c \
mailstream_helper.c mailstream_low.c \
mailstream.c mailstream_socket.c mailstream_ssl.c \
mapping.c cinthash.c carray.c clist.c chash.c \
charconv.c maillock.c base64.c \
mail_cache_db.c mailsem.c mailsasl.c
include $(top_builddir)/Rules
+145
View File
@@ -0,0 +1,145 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: base64.c,v 1.3 2005/06/01 12:21:57 smarinier Exp $
*/
#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+/";
LIBETPAN_EXPORT
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;
}
LIBETPAN_EXPORT
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;
}
+65
View File
@@ -0,0 +1,65 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: base64.h,v 1.3 2005/06/01 12:21:57 smarinier Exp $
*/
#ifndef BASE64_H
#define BASE64_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef LIBETPAN_CONFIG_H
# include "libetpan-config.h"
#endif
/**
* creates (malloc) a new base64 encoded string from a standard 8bit string
* don't forget to free it when time comes ;)
*/
LIBETPAN_EXPORT
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 ;)
*/
LIBETPAN_EXPORT
char * decode_base64(const char * in, int len);
#ifdef __cplusplus
}
#endif
#endif
+162
View File
@@ -0,0 +1,162 @@
/*
* libEtPan! -- a mail stuff library
*
* carray - Implements simple dynamic pointer arrays
*
* Copyright (c) 1999-2005, Gaël Roualland <gael.roualland@iname.com>
* interface changes - 2005 - 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 AUTHORS 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 AUTHORS 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: carray.c,v 1.10 2006/05/22 13:39:40 hoa Exp $
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdlib.h>
#include <string.h>
#include "carray.h"
#define MIN_ARRAY_SIZE 4
LIBETPAN_EXPORT
carray * carray_new(unsigned int initsize) {
carray * array;
array = (carray *) malloc(sizeof(carray));
if (!array) return NULL;
if (initsize < MIN_ARRAY_SIZE)
initsize = MIN_ARRAY_SIZE;
array->len = 0;
array->max = initsize;
array->array = (void **) malloc(sizeof(void *) * initsize);
if (!array->array) {
free(array);
return NULL;
}
return array;
}
LIBETPAN_EXPORT
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;
}
LIBETPAN_EXPORT
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;
}
LIBETPAN_EXPORT
int carray_delete_fast(carray * array, unsigned int indx) {
if (indx >= array->len)
return -1;
array->array[indx] = NULL;
return 0;
}
LIBETPAN_EXPORT
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;
}
LIBETPAN_EXPORT
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
LIBETPAN_EXPORT
void ** carray_data(carray * array) {
return array->array;
}
LIBETPAN_EXPORT
unsigned int carray_count(carray * array) {
return array->len;
}
LIBETPAN_EXPORT
void * carray_get(carray * array, unsigned int indx) {
return array->array[indx];
}
LIBETPAN_EXPORT
void carray_set(carray * array, unsigned int indx, void * value) {
array->array[indx] = value;
}
#endif
LIBETPAN_EXPORT
void carray_free(carray * array) {
free(array->array);
free(array);
}
+138
View File
@@ -0,0 +1,138 @@
/*
* libEtPan! -- a mail stuff library
*
* carray - Implements simple dynamic pointer arrays
*
* Copyright (c) 1999-2005, Gaël Roualland <gael.roualland@iname.com>
* interface changes - 2005 - 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 AUTHORS 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 AUTHORS 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: carray.h,v 1.16 2006/03/22 08:10:47 hoa Exp $
*/
#ifndef CARRAY_H
#define CARRAY_H
#ifndef LIBETPAN_CONFIG_H
# include <libetpan/libetpan-config.h>
#endif
#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 */
LIBETPAN_EXPORT
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 */
LIBETPAN_EXPORT
int carray_add(carray * array, void * data, unsigned int * index);
LIBETPAN_EXPORT
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. */
LIBETPAN_EXPORT
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. */
LIBETPAN_EXPORT
int carray_delete_slow(carray * array, unsigned int indx);
/* remove without decreasing the size of the array */
LIBETPAN_EXPORT
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 */
LIBETPAN_EXPORT
void ** carray_data(carray *);
/* Returns the number of elements in the array */
LIBETPAN_EXPORT
unsigned int carray_count(carray *);
/* Returns the contents of one cell */
LIBETPAN_EXPORT
void * carray_get(carray * array, unsigned int indx);
/* Sets the contents of one cell */
LIBETPAN_EXPORT
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
LIBETPAN_EXPORT
void carray_free(carray * array);
#ifdef __cplusplus
}
#endif
#endif
+316
View File
@@ -0,0 +1,316 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: charconv.c,v 1.22 2006/07/03 16:36:08 skunk Exp $
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "charconv.h"
#ifdef HAVE_ICONV
#include <iconv.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include "mmapstring.h"
int (*extended_charconv)(const char * tocode, const char * fromcode, const char * str, size_t length,
char * result, size_t* result_len) = NULL;
#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)
{
size_t ret = 0, ret1;
/* XXX - force const to mutable */
char *ib = (char *) *inbuf;
size_t ibl = *inbytesleft;
char *ob = *outbuf;
size_t obl = *outbytesleft;
for (;;)
{
#ifdef HAVE_ICONV_PROTO_CONST
ret1 = iconv (cd, (const char **) &ib, &ibl, &ob, &obl);
#else
ret1 = iconv (cd, &ib, &ibl, &ob, &obl);
#endif
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;
#ifdef HAVE_ICONV_PROTO_CONST
iconv (cd, (const char **) &ib1, &ibl1, &ob1, &obl1);
#else
iconv (cd, &ib1, &ibl1, &ob1, &obl1);
#endif
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
LIBETPAN_EXPORT
int charconv(const char * tocode, const char * fromcode,
const char * str, size_t length,
char ** result)
{
#ifdef HAVE_ICONV
iconv_t conv;
size_t r;
char * pout;
size_t out_size;
size_t old_out_size;
size_t count;
#endif
char * out;
int res;
if (extended_charconv != NULL) {
size_t result_length;
result_length = length * 6;
*result = malloc( length * 6 + 1);
if (*result == NULL) {
res = MAIL_CHARCONV_ERROR_MEMORY;
} else {
res = (*extended_charconv)( tocode, fromcode, str, length, *result, &result_length);
if (res != MAIL_CHARCONV_NO_ERROR) {
free( *result);
} else {
out = realloc( *result, result_length + 1);
if (out != NULL) *result = out;
/* also a cstring, just in case */
(*result)[result_length] = '\0';
}
}
if (res != MAIL_CHARCONV_ERROR_UNKNOWN_CHARSET)
return res;
/* else, let's try with iconv, if available */
}
#ifndef HAVE_ICONV
return MAIL_CHARCONV_ERROR_UNKNOWN_CHARSET;
#else
conv = iconv_open(tocode, fromcode);
if (conv == (iconv_t) -1) {
res = MAIL_CHARCONV_ERROR_UNKNOWN_CHARSET;
goto err;
}
out_size = 6 * length; /* UTF-8 can be encoded up to 6 bytes */
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
}
LIBETPAN_EXPORT
int charconv_buffer(const char * tocode, const char * fromcode,
const char * str, size_t length,
char ** result, size_t * result_len)
{
#ifdef HAVE_ICONV
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;
#endif
int res;
MMAPString * mmapstr;
if (extended_charconv != NULL) {
size_t result_length;
result_length = length * 6;
mmapstr = mmap_string_sized_new( result_length + 1);
*result_len = 0;
if (mmapstr == NULL) {
res = MAIL_CHARCONV_ERROR_MEMORY;
} else {
res = (*extended_charconv)( tocode, fromcode, str, length, mmapstr->str, &result_length);
if (res != MAIL_CHARCONV_ERROR_UNKNOWN_CHARSET) {
if (res == MAIL_CHARCONV_NO_ERROR) {
*result = mmapstr->str;
res = mmap_string_ref(mmapstr);
if (res < 0) {
res = MAIL_CHARCONV_ERROR_MEMORY;
mmap_string_free(mmapstr);
} else {
mmap_string_set_size( mmapstr, result_length); /* can't fail */
*result_len = result_length;
}
}
free( *result);
}
return res;
}
/* else, let's try with iconv, if available */
}
#ifndef HAVE_ICONV
return MAIL_CHARCONV_ERROR_UNKNOWN_CHARSET;
#else
conv = iconv_open(tocode, fromcode);
if (conv == (iconv_t) -1) {
res = MAIL_CHARCONV_ERROR_UNKNOWN_CHARSET;
goto err;
}
out_size = 6 * length; /* UTF-8 can be encoded up to 6 bytes */
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 res;
#endif
}
LIBETPAN_EXPORT
void charconv_buffer_free(char * str)
{
mmap_string_unref(str);
}
+84
View File
@@ -0,0 +1,84 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: charconv.h,v 1.13 2006/06/16 09:25:23 smarinier Exp $
*/
#ifndef CHARCONV_H
#define CHARCONV_H
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/types.h>
#ifndef LIBETPAN_CONFIG_H
# include <libetpan/libetpan-config.h>
#endif
enum {
MAIL_CHARCONV_NO_ERROR = 0,
MAIL_CHARCONV_ERROR_UNKNOWN_CHARSET,
MAIL_CHARCONV_ERROR_MEMORY,
MAIL_CHARCONV_ERROR_CONV
};
/**
* define your own conversion.
* - result is big enough to contain your converted string
* - result_len contain the maximum size available (out value must contain the final converted size)
* - your conversion return an error code based on upper enum values
*/
LIBETPAN_EXPORT
extern int (*extended_charconv)(const char * tocode, const char * fromcode, const char * str, size_t length,
char * result, size_t* result_len);
LIBETPAN_EXPORT
int charconv(const char * tocode, const char * fromcode,
const char * str, size_t length,
char ** result);
LIBETPAN_EXPORT
int charconv_buffer(const char * tocode, const char * fromcode,
const char * str, size_t length,
char ** result, size_t * result_len);
LIBETPAN_EXPORT
void charconv_buffer_free(char * str);
#ifdef __cplusplus
}
#endif
#endif
+414
View File
@@ -0,0 +1,414 @@
/*
* libEtPan! -- a mail stuff library
*
* chash - Implements generic hash tables.
*
* Copyright (c) 1999-2005, Gaël Roualland <gael.roualland@iname.com>
* interface changes - 2005 - 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 AUTHORS 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 AUTHORS 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: chash.c,v 1.16 2006/05/22 13:39:40 hoa Exp $
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#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;
}
LIBETPAN_EXPORT
chash * chash_new(unsigned int size, int flags)
{
chash * h;
h = (chash *) malloc(sizeof(chash));
if (h == NULL)
return NULL;
if (size < CHASH_DEFAULTSIZE)
size = CHASH_DEFAULTSIZE;
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;
}
LIBETPAN_EXPORT
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;
}
LIBETPAN_EXPORT
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;
}
LIBETPAN_EXPORT
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 */
}
LIBETPAN_EXPORT
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);
}
LIBETPAN_EXPORT
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;
}
LIBETPAN_EXPORT
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;
}
LIBETPAN_EXPORT
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;
}
LIBETPAN_EXPORT
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
LIBETPAN_EXPORT
int chash_count(chash * hash) {
return hash->count;
}
LIBETPAN_EXPORT
int chash_size(chash * hash) {
return hash->size;
}
LIBETPAN_EXPORT
void chash_value(chashiter * iter, chashdatum * result) {
* result = iter->value;
}
LIBETPAN_EXPORT
void chash_key(chashiter * iter, chashdatum * result) {
* result = iter->key;
}
#endif
+182
View File
@@ -0,0 +1,182 @@
/*
* libEtPan! -- a mail stuff library
*
* chash - Implements generic hash tables.
*
* Copyright (c) 1999-2005, Gaël Roualland <gael.roualland@iname.com>
* interface changes - 2005 - 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 AUTHORS 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 AUTHORS 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: chash.h,v 1.15 2006/03/22 08:10:47 hoa Exp $
*/
#ifndef CHASH_H
#define CHASH_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef LIBETPAN_CONFIG_H
# include <libetpan/libetpan-config.h>
#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.
*/
LIBETPAN_EXPORT
chash * chash_new(unsigned int size, int flags);
/* Frees a hash */
LIBETPAN_EXPORT
void chash_free(chash * hash);
/* Removes all elements from a hash */
LIBETPAN_EXPORT
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. */
LIBETPAN_EXPORT
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*/
LIBETPAN_EXPORT
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. */
LIBETPAN_EXPORT
int chash_delete(chash * hash,
chashdatum * key,
chashdatum * oldvalue);
/* Resizes the hash table to the passed size. */
LIBETPAN_EXPORT
int chash_resize(chash * hash, unsigned int size);
/* Returns an iterator to the first non-empty entry of the hash table */
LIBETPAN_EXPORT
chashiter * chash_begin(chash * hash);
/* Returns the next non-empty entry of the hash table */
LIBETPAN_EXPORT
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 */
LIBETPAN_EXPORT
unsigned int chash_size(chash * hash);
/* Returns the number of entries in the hash table */
LIBETPAN_EXPORT
unsigned int chash_count(chash * hash);
/* Returns the key part of the entry pointed by the iterator */
LIBETPAN_EXPORT
void chash_key(chashiter * iter, chashdatum * result);
/* Returns the value part of the entry pointed by the iterator */
LIBETPAN_EXPORT
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
+255
View File
@@ -0,0 +1,255 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: cinthash.c,v 1.9 2006/05/22 13:39:40 hoa Exp $
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#ifndef LIBETPAN_CONFIG_H
# include "libetpan-config.h"
#endif
#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);
}
}
}
+69
View File
@@ -0,0 +1,69 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: cinthash.h,v 1.6 2004/11/21 21:53:31 hoa Exp $
*/
#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
+273
View File
@@ -0,0 +1,273 @@
/*
* libEtPan! -- a mail stuff library
*
* clist - Implements simple generic double-linked pointer lists
*
* Copyright (c) 1999-2005, Gaël Roualland <gael.roualland@iname.com>
* interface changes - 2005 - 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 AUTHORS 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 AUTHORS 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: clist.c,v 1.10 2006/05/22 13:39:40 hoa Exp $
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdlib.h>
#ifndef LIBETPAN_CONFIG_H
# include "libetpan-config.h"
#endif
#include "clist.h"
clist * clist_new(void) {
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);
}
+133
View File
@@ -0,0 +1,133 @@
/*
* libEtPan! -- a mail stuff library
*
* clist - Implements simple generic double-linked pointer lists
*
* Copyright (c) 1999-2005, Gaël Roualland <gael.roualland@iname.com>
* interface changes - 2005 - 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 AUTHORS 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 AUTHORS 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: clist.h,v 1.10 2006/05/22 13:39:40 hoa Exp $
*/
#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(void);
/* 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
+141
View File
@@ -0,0 +1,141 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: connect.c,v 1.16 2006/07/15 12:24:26 hoa Exp $
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "connect.h"
#include <sys/types.h>
#include <string.h>
#include <stdio.h>
#ifdef _MSC_VER
# include "win_etpan.h"
#else
# include <netdb.h>
# include <netinet/in.h>
# include <sys/socket.h>
# include <unistd.h>
#endif
uint16_t mail_get_service_port(const char * name, char * protocol)
{
struct servent * service;
service = getservbyname(name, protocol);
if (service == NULL)
return 0;
return ntohs(service->s_port);
}
int mail_tcp_connect(const char * server, uint16_t port)
{
#ifndef HAVE_IPV6
struct hostent * remotehost;
struct sockaddr_in sa;
#else /* HAVE_IPV6 */
struct addrinfo hints, *res, *ai;
char port_str[6];
#endif
#ifdef WIN32
SOCKET s;
#else
int s;
#endif
int r;
#ifndef HAVE_IPV6
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;
#else /* HAVE_IPV6 */
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
/* convert port from integer to string. */
snprintf(port_str, sizeof(port_str), "%d", port);
if (getaddrinfo(server, port_str, &hints, &res) != 0)
goto err;
for (ai = res; ai != NULL; ai = ai->ai_next) {
s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
if (s == -1)
continue;
r = connect(s, ai->ai_addr, ai->ai_addrlen);
if (r == 0)
break;
}
if (res != NULL)
freeaddrinfo(res);
if (ai == NULL)
goto err;
#endif
return s;
#ifndef HAVE_IPV6
close_socket:
#ifdef WIN32
closesocket(s);
#else
close(s);
#endif
#endif
err:
return -1;
}
+56
View File
@@ -0,0 +1,56 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: connect.h,v 1.15 2006/05/22 13:39:40 hoa Exp $
*/
#ifndef CONNECT_H
#define CONNECT_H
#ifdef HAVE_INTTYPES_H
# include <inttypes.h>
#endif
#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
+94
View File
@@ -0,0 +1,94 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: hmac-md5.h,v 1.4 2004/11/21 21:53:31 hoa Exp $
*/
#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 */
+56
View File
@@ -0,0 +1,56 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: mail.h,v 1.8 2004/11/21 21:53:31 hoa Exp $
*/
#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
@@ -0,0 +1,500 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: mail_cache_db.c,v 1.20 2006/05/22 13:39:40 hoa Exp $
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "mail_cache_db.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#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;
#if DBVERS > 1
int r;
#endif
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(dbp, 0);
#elif DBVERS == 1
dbp->close(dbp);
#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)
{
mail_cache_db_close(cache_db);
maillock_write_unlock(filename, -1);
}
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
if (r != 0)
return -1;
return 0;
#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 -1;
* 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
if (r != 0)
return -1;
return 0;
#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;
#if DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR < 6
r = dbp->cursor(dbp, NULL, &dbcp);
#else
r = dbp->cursor(dbp, NULL, &dbcp, 0);
#endif
if (r != 0)
return -1;
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 -1;
}
}
r = dbcp->c_close(dbcp);
if (r != 0)
return -1;
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 -1;
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 -1;
}
r = dbp->seq(dbp, &db_key, &db_data, R_NEXT);
if (r < 0)
return -1;
}
return 0;
}
#else
int mail_cache_db_clean_up(struct mail_cache_db * cache_db,
chash * exist)
{
return -1;
}
#endif
int mail_cache_db_get_size(struct mail_cache_db * cache_db,
const void * key, size_t key_len, 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
db_data.flags = DB_DBT_USERMEM;
db_data.ulen = 0;
#endif
#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 -1;
* pvalue_len = db_data.size;
return 0;
#else
return -1;
#endif
}
#if DBVERS > 1
int mail_cache_db_get_keys(struct mail_cache_db * cache_db,
chash * keys)
{
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 -1;
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;
hash_data.data = NULL;
hash_data.len = 0;
r = chash_set(keys, &hash_key, &hash_data, NULL);
if (r < 0) {
return -1;
}
}
r = dbcp->c_close(dbcp);
if (r != 0)
return -1;
return 0;
}
#elif DBVERS == 1
int mail_cache_db_get_keys(struct mail_cache_db * cache_db,
chash * keys)
{
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 -1;
while (r == 0) {
chashdatum hash_key;
chashdatum hash_data;
hash_key.data = db_key.data;
hash_key.len = db_key.size;
hash_data.data = NULL;
hash_data.len = 0;
r = chash_set(keys, &hash_key, &hash_data, NULL);
if (r < 0) {
return -1;
}
r = dbp->seq(dbp, &db_key, &db_data, R_NEXT);
if (r < 0)
return -1;
}
return 0;
}
#else
int mail_cache_db_get_keys(struct mail_cache_db * cache_db,
chash * keys)
{
return -1;
}
#endif
@@ -0,0 +1,158 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: mail_cache_db.h,v 1.6 2005/04/07 00:05:25 hoa Exp $
*/
#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_get_size()
This function will retrieve the size of the value corresponding
to a given key from the database.
*/
int mail_cache_db_get_size(struct mail_cache_db * cache_db,
const void * key, size_t key_len, 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);
/*
mail_cache_db_get_keys()
This function will get all keys of the database and will
store them to the given chash.
*/
int mail_cache_db_get_keys(struct mail_cache_db * cache_db,
chash * keys);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,52 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: mail_cache_db_types.h,v 1.2 2004/11/21 21:53:31 hoa Exp $
*/
#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
+356
View File
@@ -0,0 +1,356 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: maillock.c,v 1.15 2006/08/05 02:34:06 hoa Exp $
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "maillock.h"
#include "libetpan-config.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <stdio.h>
#include <time.h>
#include <string.h>
#ifdef _MSC_VER
# include "win_etpan.h"
#endif
#ifdef HAVE_LIBLOCKFILE
#include <lockfile.h>
#endif
/* ********************************************************************** */
/* 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 */
#ifdef WIN32
# define F_RDLCK 0
# define F_WRLCK 1
# include <sys/locking.h>
#endif
static int lock_common(const char * filename, int fd, short locktype)
{
#ifdef WIN32
time_t start;
/* SEB try implementation */
if (fd != -1) {
lseek( fd, 0L, SEEK_SET );
if (_locking( fd, _LK_NBLCK, LONG_MAX) == 0) return 0;
time(&start);
while (1) {
time_t now;
sleep( 5);
if (_locking( fd, _LK_NBLCK, LONG_MAX) == 0) return 0;
time(&now);
if (now > start + LOCKTO_GLOB) {
return -1;
}
}
}
#else
char lockfilename[PATH_MAX];
#ifndef HAVE_LIBLOCKFILE
struct flock lock;
/* dot lock file */
int statfailed = 0;
time_t start;
int r;
#endif
int res;
/* dot lock file */
if (strlen(filename) + 6 > PATH_MAX) {
res = -1;
goto err;
}
snprintf(lockfilename, PATH_MAX, "%s.lock", filename);
#ifdef HAVE_LIBLOCKFILE
return lockfile_create(lockfilename, LOCKTO_GLOB, 0);
#else
if (fd != -1) {
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 */
}
}
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:
if (fd != -1) {
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 */
}
}
#endif
err:
return res;
#endif /* WIN32 */
}
static int unlock_common(const char * filename, int fd)
{
/* SEB */
#ifdef WIN32
if (fd != -1) {
lseek( fd, 0L, SEEK_SET );
_locking( fd, _LK_UNLCK, LONG_MAX);
}
return 0;
#else
char lockfilename[PATH_MAX];
#ifndef HAVE_LIBLOCKFILE
struct flock lock;
int r;
#endif
if (strlen(filename) + 6 > PATH_MAX)
return -1;
snprintf(lockfilename, PATH_MAX, "%s.lock", filename);
#ifdef HAVE_LIBLOCKFILE
return lockfile_remove(lockfilename);
#else
unlink(lockfilename);
if (fd != -1) {
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;
#endif
#endif /* WIN32 */
}
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);
}
+53
View File
@@ -0,0 +1,53 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: maillock.h,v 1.5 2004/11/21 21:53:31 hoa Exp $
*/
#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
+71
View File
@@ -0,0 +1,71 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "mailsasl.h"
#ifdef USE_SASL
#ifdef LIBETPAN_REENTRANT
#include <pthread.h>
#endif
#include <sasl/sasl.h>
#ifdef LIBETPAN_REENTRANT
static pthread_mutex_t sasl_lock = PTHREAD_MUTEX_INITIALIZER;
#endif
static int sasl_use_count = 0;
void mailsasl_external_ref(void)
{
#ifdef LIBETPAN_REENTRANT
pthread_mutex_lock(&sasl_lock);
#endif
sasl_use_count ++;
#ifdef LIBETPAN_REENTRANT
pthread_mutex_unlock(&sasl_lock);
#endif
}
void mailsasl_ref(void)
{
#ifdef LIBETPAN_REENTRANT
pthread_mutex_lock(&sasl_lock);
#endif
sasl_use_count ++;
if (sasl_use_count == 1)
sasl_client_init(NULL);
#ifdef LIBETPAN_REENTRANT
pthread_mutex_unlock(&sasl_lock);
#endif
}
void mailsasl_unref(void)
{
#ifdef LIBETPAN_REENTRANT
pthread_mutex_lock(&sasl_lock);
#endif
sasl_use_count --;
if (sasl_use_count == 0) {
sasl_done();
}
#ifdef LIBETPAN_REENTRANT
pthread_mutex_unlock(&sasl_lock);
#endif
}
#else
void mailsasl_external_ref(void)
{
}
void mailsasl_ref(void)
{
}
void mailsasl_unref(void)
{
}
#endif
+11
View File
@@ -0,0 +1,11 @@
#ifndef MAILSASL_H
#define MAILSASL_H
/* if Cyrus-SASL is used outside of libetpan */
void mailsasl_external_ref(void);
void mailsasl_ref(void);
void mailsasl_unref(void);
#endif
+322
View File
@@ -0,0 +1,322 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: mailsem.c,v 1.11 2006/05/22 13:39:40 hoa Exp $
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "mailsem.h"
#include <stdlib.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#ifdef LIBETPAN_REENTRANT
#include <pthread.h>
#include <semaphore.h>
#endif
struct mailsem_internal {
/* Current count of the semaphore. */
unsigned int count;
/* Number of threads that have called <sema_wait>. */
unsigned long waiters_count;
#ifdef LIBETPAN_REENTRANT
/* Serialize access to <count> and <waiters_count>. */
pthread_mutex_t lock;
/* Condition variable that blocks the <count> 0. */
pthread_cond_t count_nonzero;
#endif
};
static int mailsem_internal_init(struct mailsem_internal * s,
unsigned int initial_count)
{
#ifdef LIBETPAN_REENTRANT
int r;
r = pthread_mutex_init(&s->lock, NULL);
if (r != 0)
goto err;
r = pthread_cond_init(&s->count_nonzero, NULL);
if (r != 0)
goto destroy_mutex;
s->count = initial_count;
s->waiters_count = 0;
return 0;
destroy_mutex:
pthread_mutex_destroy(&s->lock);
err:
return -1;
#else
return -1;
#endif
}
static void mailsem_internal_destroy(struct mailsem_internal * s)
{
#ifdef LIBETPAN_REENTRANT
pthread_cond_destroy(&s->count_nonzero);
pthread_mutex_destroy(&s->lock);
#endif
}
int mailsem_internal_wait(struct mailsem_internal * s)
{
#ifdef LIBETPAN_REENTRANT
int r;
/* Acquire mutex to enter critical section. */
r = pthread_mutex_lock(&s->lock);
if (r != 0)
goto err;
/* Keep track of the number of waiters so that <sema_post> works correctly. */
s->waiters_count ++;
/* Wait until the semaphore count is > 0, then atomically release */
/* <lock> and wait for <count_nonzero> to be signaled. */
while (s->count == 0) {
r = pthread_cond_wait(&s->count_nonzero, &s->lock);
if (r != 0)
goto unlock;
}
/* <s->lock> is now held. */
/* Decrement the waiters count. */
s->waiters_count --;
/* Decrement the semaphore's count. */
s->count --;
/* Release mutex to leave critical section. */
pthread_mutex_unlock(&s->lock);
return 0;
unlock:
pthread_mutex_unlock(&s->lock);
err:
return -1;
#else
return -1;
#endif
}
static int mailsem_internal_post(struct mailsem_internal * s)
{
#ifdef LIBETPAN_REENTRANT
int r;
r = pthread_mutex_lock(&s->lock);
if (r != 0)
goto err;
/* Always allow one thread to continue if it is waiting. */
if (s->waiters_count > 0) {
r = pthread_cond_signal(&s->count_nonzero);
if (r != 0)
goto unlock;
}
/* Increment the semaphore's count. */
s->count ++;
pthread_mutex_unlock(&s->lock);
return 0;
unlock:
pthread_mutex_unlock(&s->lock);
err:
return -1;
#else
return -1;
#endif
}
enum {
SEMKIND_SEMOPEN,
SEMKIND_SEMINIT,
SEMKIND_INTERNAL
};
#if 0
#define SEMNAME_LEN 64
struct mailsem * mailsem_new(void)
{
#ifdef LIBETPAN_REENTRANT
struct mailsem * sem;
int r;
sem = malloc(sizeof(* sem));
if (sem == NULL)
goto err;
sem->sem_sem = malloc(sizeof(sem_t));
if (sem->sem_sem == NULL)
goto free_sem;
r = sem_init(sem->sem_sem, 0, 0);
if (r < 0) {
char name[SEMNAME_LEN];
pid_t pid;
free(sem->sem_sem);
pid = getpid();
snprintf(name, sizeof(name), "sem-%p-%i", sem, pid);
#ifndef __CYGWIN__
sem->sem_sem = sem_open(name, O_CREAT | O_EXCL, 0700, 0);
if (sem->sem_sem == (sem_t *) SEM_FAILED)
goto free_sem;
sem->sem_kind = SEMKIND_SEMOPEN;
#else
goto free_sem;
#endif
}
else {
sem->sem_kind = SEMKIND_SEMINIT;
}
return sem;
free_sem:
free(sem);
err:
return NULL;
#else
return NULL;
#endif
}
void mailsem_free(struct mailsem * sem)
{
#ifdef LIBETPAN_REENTRANT
if (sem->sem_kind == SEMKIND_SEMOPEN) {
char name[SEMNAME_LEN];
pid_t pid;
pid = getpid();
#ifndef __CYGWIN__
sem_close((sem_t *) sem->sem_sem);
snprintf(name, sizeof(name), "sem-%p-%i", sem, pid);
sem_unlink(name);
#endif
}
else {
sem_destroy((sem_t *) sem->sem_sem);
free(sem->sem_sem);
}
free(sem);
#endif
}
int mailsem_up(struct mailsem * sem)
{
#ifdef LIBETPAN_REENTRANT
return sem_post((sem_t *) sem->sem_sem);
#else
return -1;
#endif
}
int mailsem_down(struct mailsem * sem)
{
#ifdef LIBETPAN_REENTRANT
return sem_wait((sem_t *) sem->sem_sem);
#else
return -1;
#endif
}
#endif
struct mailsem * mailsem_new(void)
{
struct mailsem * sem;
int r;
sem = malloc(sizeof(* sem));
if (sem == NULL)
goto err;
sem->sem_sem = malloc(sizeof(struct mailsem_internal));
if (sem->sem_sem == NULL)
goto free;
r = mailsem_internal_init(sem->sem_sem, 0);
if (r < 0)
goto free_sem;
return sem;
free_sem:
free(sem->sem_sem);
free:
free(sem);
err:
return NULL;
}
void mailsem_free(struct mailsem * sem)
{
mailsem_internal_destroy(sem->sem_sem);
free(sem->sem_sem);
free(sem);
}
int mailsem_up(struct mailsem * sem)
{
return mailsem_internal_post(sem->sem_sem);
}
int mailsem_down(struct mailsem * sem)
{
return mailsem_internal_wait(sem->sem_sem);
}
+51
View File
@@ -0,0 +1,51 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: mailsem.h,v 1.2 2004/11/21 21:53:31 hoa Exp $
*/
#ifndef MAILSEM_H
#define MAILSEM_H
struct mailsem {
void * sem_sem;
int sem_kind;
};
struct mailsem * mailsem_new(void);
void mailsem_free(struct mailsem * sem);
int mailsem_up(struct mailsem * sem);
int mailsem_down(struct mailsem * sem);
#endif
+403
View File
@@ -0,0 +1,403 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: mailstream.c,v 1.18 2006/06/28 06:13:47 skunk Exp $
*/
#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
#if 0
#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
#endif
#define STREAM_LOG_BUF(buf, size) do { } while (0)
#define STREAM_LOG(buf) do { } while (0)
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;
}
#if ! defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
struct timeval mailstream_network_delay =
{ DEFAULT_NETWORK_TIMEOUT, 0 };
#else
struct timeval mailstream_network_delay =
{ .tv_sec = DEFAULT_NETWORK_TIMEOUT, .tv_usec = 0 };
#endif
+81
View File
@@ -0,0 +1,81 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: mailstream.h,v 1.16 2005/07/15 16:12:33 hoa Exp $
*/
#ifndef MAILSTREAM_H
#define MAILSTREAM_H
#ifndef _MSC_VER
# include <sys/time.h>
#endif
#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
LIBETPAN_EXPORT
extern int mailstream_debug;
/* direction is 1 for send, 0 for receive, -1 when it does not apply */
LIBETPAN_EXPORT
extern void (* mailstream_logger)(int direction,
const char * str, size_t size);
#endif
#define LIBETPAN_MAILSTREAM_NETWORK_DELAY
extern struct timeval mailstream_network_delay;
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,519 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: mailstream_helper.c,v 1.17 2006/05/22 13:39:40 hoa Exp $
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#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 inline 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 (length == 0) {
fix_eol = 1;
break;
}
if (* line == '\n') {
line ++;
count ++;
length --;
break;
}
else {
fix_eol = 1;
break;
}
}
else if (* line == '\n') {
line ++;
count ++;
length --;
fix_eol = 1;
break;
}
line ++;
length --;
count ++;
}
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;
}
static inline int send_data_crlf(mailstream * s, const char * message,
size_t size,
int quoted,
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;
if (quoted) {
if (current[0] == '.')
if (mailstream_write(s, ".", 1) == -1)
goto err;
}
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;
}
return 0;
err:
return -1;
}
int mailstream_send_data_crlf(mailstream * s, const char * message,
size_t size,
size_t progr_rate,
progress_function * progr_fun)
{
return send_data_crlf(s, message, size, 0, progr_rate, progr_fun);
}
int mailstream_send_data(mailstream * s, const char * message,
size_t size,
size_t progr_rate,
progress_function * progr_fun)
{
if (send_data_crlf(s, message, size, 1, progr_rate, progr_fun) == -1)
goto err;
if (mailstream_write(s, "\r\n.\r\n", 5) == -1)
goto err;
if (mailstream_flush(s) == -1)
goto err;
return 0;
err:
return -1;
}
static inline ssize_t get_data_size(const char * line, size_t length,
size_t * result)
{
int fix_eol;
const char * start;
size_t count;
size_t fixed_count;
start = line;
fix_eol = 0;
count = 0;
fixed_count = 0;
while (1) {
if (length == 0)
break;
if (* line == '\r') {
line ++;
count ++;
length --;
if (length == 0) {
fix_eol = 1;
fixed_count ++;
break;
}
if (* line == '\n') {
line ++;
count ++;
length --;
break;
}
else {
fix_eol = 1;
fixed_count ++;
break;
}
}
else if (* line == '\n') {
line ++;
count ++;
length --;
fix_eol = 1;
fixed_count ++;
break;
}
line ++;
length --;
count ++;
}
* result = count + fixed_count;
return count;
}
size_t mailstream_get_data_crlf_size(const char * message, size_t size)
{
const char * current;
size_t count;
size_t last;
size_t remaining;
size_t fixed_count;
count = 0;
last = 0;
fixed_count = 0;
current = message;
remaining = size;
while (remaining > 0) {
ssize_t length;
size_t line_count;
length = get_data_size(current, remaining, &line_count);
fixed_count += line_count;
current += length;
count += length;
remaining -= length;
}
return fixed_count;
}
@@ -0,0 +1,77 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: mailstream_helper.h,v 1.12 2004/11/21 21:53:31 hoa Exp $
*/
#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_crlf(mailstream * s, const char * message,
size_t size,
size_t progr_rate,
progress_function * progr_fun);
int mailstream_send_data(mailstream * s, const char * message,
size_t size,
size_t progr_rate,
progress_function * progr_fun);
size_t mailstream_get_data_crlf_size(const char * message, size_t size);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,186 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: mailstream_low.c,v 1.17 2006/05/22 13:39:40 hoa Exp $
*/
#include "mailstream_low.h"
#include <stdlib.h>
#ifdef LIBETPAN_MAILSTREAM_DEBUG
#define STREAM_DEBUG
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include "maillock.h"
#ifdef _MSC_VER
# include "win_etpan.h"
#endif
#define LOG_FILE "libetpan-stream-debug.log"
LIBETPAN_EXPORT
int mailstream_debug = 0;
LIBETPAN_EXPORT
void (* mailstream_logger)(int direction,
const char * str, size_t size) = NULL;
#define STREAM_LOG_BUF(direction, buf, size) \
if (mailstream_debug) { \
if (mailstream_logger != NULL) { \
mailstream_logger(direction, buf, size); \
} \
else { \
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(direction, str) \
if (mailstream_debug) { \
if (mailstream_logger != NULL) { \
mailstream_logger(direction, str, strlen(str) + 1); \
} \
else { \
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(direction, buf, size) do { } while (0)
#define STREAM_LOG(direction, buf) do { } while (0)
#endif
/* 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)
{
ssize_t r;
if (s == NULL)
return -1;
r = s->driver->mailstream_read(s, buf, count);
#ifdef STREAM_DEBUG
if (r > 0) {
STREAM_LOG(0, "<<<<<<< read <<<<<<\n");
STREAM_LOG_BUF(0, buf, r);
STREAM_LOG(0, "\n");
STREAM_LOG(0, "<<<<<<< end read <<<<<<\n");
}
#endif
return r;
}
ssize_t mailstream_low_write(mailstream_low * s,
const void * buf, size_t count)
{
if (s == NULL)
return -1;
#ifdef STREAM_DEBUG
STREAM_LOG(1, ">>>>>>> send >>>>>>\n");
STREAM_LOG_BUF(1, buf, count);
STREAM_LOG(1, "\n");
STREAM_LOG(1, ">>>>>>> end send >>>>>>\n");
#endif
return s->driver->mailstream_write(s, buf, count);
}
@@ -0,0 +1,62 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: mailstream_low.h,v 1.9 2004/11/21 21:53:31 hoa Exp $
*/
#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
@@ -0,0 +1,279 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: mailstream_socket.c,v 1.22 2006/06/26 11:50:26 hoa Exp $
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "mailstream_socket.h"
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <stdlib.h>
#include <fcntl.h>
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#ifdef HAVE_STRING_H
# include <string.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)
*/
#ifndef _MSC_VER
# include <sys/time.h>
# include <sys/types.h>
# ifdef HAVE_SYS_SELECT_H
# include <sys/select.h>
# endif
#endif
/* 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 = {
#if ! defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
/* SEB */
mailstream_low_socket_read,
mailstream_low_socket_write,
mailstream_low_socket_close,
mailstream_low_socket_get_fd,
mailstream_low_socket_free
#else
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,
#endif
};
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 = (struct mailstream_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)
{
#ifdef _MSC_VER
/* SEB */
closesocket(socket_data->fd);
#else
close(socket_data->fd);
#endif
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;
}
/* SEB why not for all os ? */
#ifdef WIN32
return recv(socket_data->fd, buf, count, 0);
#else
return read(socket_data->fd, buf, count);
#endif
}
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;
}
/* SEB (bis) why not for all os? */
#ifdef WIN32
return send(socket_data->fd, buf, count, 0);
#else
return write(socket_data->fd, buf, count);
#endif
}
/* 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;
}
@@ -0,0 +1,61 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: mailstream_socket.h,v 1.9 2004/11/21 21:53:31 hoa Exp $
*/
#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
@@ -0,0 +1,701 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: mailstream_ssl.c,v 1.41 2006/09/25 17:33:03 colinleroy Exp $
*/
/*
NOTE :
The user has to call himself SSL_library_init() if he wants to
use SSL.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "mailstream_ssl.h"
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif
#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)
*/
#ifndef _MSC_VER
# include <sys/time.h>
# include <sys/types.h>
# ifdef HAVE_SYS_SELECT_H
# include <sys/select.h>
# endif
#endif
/* mailstream_low, ssl */
#ifdef USE_SSL
# ifndef USE_GNUTLS
# include <openssl/ssl.h>
# else
# include <errno.h>
# include <gnutls/gnutls.h>
# include <gnutls/x509.h>
# endif
# ifdef LIBETPAN_REENTRANT
# include <pthread.h>
# endif
#endif
#ifdef USE_SSL
#ifndef USE_GNUTLS
struct mailstream_ssl_data {
int fd;
SSL * ssl_conn;
SSL_CTX * ssl_ctx;
};
#else
struct mailstream_ssl_data {
int fd;
gnutls_session session;
};
#endif
#endif
#ifdef USE_SSL
#ifdef LIBETPAN_REENTRANT
static pthread_mutex_t ssl_lock = PTHREAD_MUTEX_INITIALIZER;
#endif
static int gnutls_init_done = 0;
static int openssl_init_done = 0;
#endif
void mailstream_gnutls_init_not_required(void)
{
#ifdef USE_SSL
#ifdef LIBETPAN_REENTRANT
pthread_mutex_lock(&ssl_lock);
#endif
gnutls_init_done = 1;
#ifdef LIBETPAN_REENTRANT
pthread_mutex_unlock(&ssl_lock);
#endif
#endif
}
void mailstream_openssl_init_not_required(void)
{
#ifdef USE_SSL
#ifdef LIBETPAN_REENTRANT
pthread_mutex_lock(&ssl_lock);
#endif
openssl_init_done = 1;
#ifdef LIBETPAN_REENTRANT
pthread_mutex_unlock(&ssl_lock);
#endif
#endif
}
void mailstream_ssl_init_not_required(void)
{
mailstream_gnutls_init_not_required();
mailstream_openssl_init_not_required();
}
static inline void mailstream_ssl_init(void)
{
#ifdef USE_SSL
#ifdef LIBETPAN_REENTRANT
pthread_mutex_lock(&ssl_lock);
#endif
#ifndef USE_GNUTLS
if (!openssl_init_done) {
SSL_library_init();
openssl_init_done = 1;
}
#else
if (!gnutls_init_done) {
gnutls_global_init();
gnutls_init_done = 1;
}
#endif
#ifdef LIBETPAN_REENTRANT
pthread_mutex_unlock(&ssl_lock);
#endif
#endif
}
#ifdef USE_SSL
static inline int mailstream_prepare_fd(int fd)
{
#ifndef WIN32
int fd_flags;
int r;
fd_flags = fcntl(fd, F_GETFL, 0);
fd_flags |= O_NDELAY;
r = fcntl(fd, F_SETFL, fd_flags);
if (r < 0)
return -1;
#endif
return 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);
#if defined (_MSC_VER) || defined (__SUNPRO_CC) || defined (__SUNPRO_C)
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,
#else
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,
#endif
};
mailstream_low_driver * mailstream_ssl_driver = &local_mailstream_ssl_driver;
#endif
/* file descriptor must be given in (default) blocking-mode */
#ifdef USE_SSL
#ifndef USE_GNUTLS
static struct mailstream_ssl_data * ssl_data_new_full(int fd, SSL_METHOD *method)
{
struct mailstream_ssl_data * ssl_data;
SSL * ssl_conn;
int r;
SSL_CTX * tmp_ctx;
mailstream_ssl_init();
tmp_ctx = SSL_CTX_new(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;
r = SSL_connect(ssl_conn);
if (r <= 0)
goto free_ssl_conn;
r = mailstream_prepare_fd(fd);
if (r < 0)
goto free_ssl_conn;
ssl_data = malloc(sizeof(* ssl_data));
if (ssl_data == NULL)
goto free_ctx;
ssl_data->fd = fd;
ssl_data->ssl_conn = ssl_conn;
ssl_data->ssl_ctx = tmp_ctx;
return ssl_data;
free_ctx:
SSL_CTX_free(tmp_ctx);
free_ssl_conn:
SSL_free(ssl_conn);
err:
return NULL;
}
static struct mailstream_ssl_data * ssl_data_new(int fd)
{
return ssl_data_new_full(fd, SSLv23_client_method());
}
static struct mailstream_ssl_data * tls_data_new(int fd)
{
return ssl_data_new_full(fd, TLSv1_client_method());
}
#else
static struct mailstream_ssl_data * ssl_data_new(int fd)
{
struct mailstream_ssl_data * ssl_data;
gnutls_session session;
const int cipher_prio[] = { GNUTLS_CIPHER_AES_128_CBC,
GNUTLS_CIPHER_3DES_CBC,
GNUTLS_CIPHER_AES_256_CBC,
GNUTLS_CIPHER_ARCFOUR_128, 0 };
const int kx_prio[] = { GNUTLS_KX_DHE_RSA,
GNUTLS_KX_RSA,
GNUTLS_KX_DHE_DSS, 0 };
const int mac_prio[] = { GNUTLS_MAC_SHA1,
GNUTLS_MAC_MD5, 0 };
const int proto_prio[] = { GNUTLS_TLS1,
GNUTLS_SSL3, 0 };
gnutls_certificate_credentials_t xcred;
int r;
mailstream_ssl_init();
if (gnutls_certificate_allocate_credentials (&xcred) != 0)
return NULL;
r = gnutls_init(&session, GNUTLS_CLIENT);
if (session == NULL || r != 0)
return NULL;
gnutls_set_default_priority(session);
gnutls_protocol_set_priority (session, proto_prio);
gnutls_cipher_set_priority (session, cipher_prio);
gnutls_kx_set_priority (session, kx_prio);
gnutls_mac_set_priority (session, mac_prio);
gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred);
gnutls_transport_set_ptr(session, (gnutls_transport_ptr) fd);
do {
r = gnutls_handshake(session);
} while (r == GNUTLS_E_AGAIN || r == GNUTLS_E_INTERRUPTED);
if (r < 0) {
goto free_ssl_conn;
}
r = mailstream_prepare_fd(fd);
if (r < 0)
goto free_ssl_conn;
ssl_data = malloc(sizeof(* ssl_data));
if (ssl_data == NULL)
goto err;
ssl_data->fd = fd;
ssl_data->session = session;
return ssl_data;
free_ssl_conn:
gnutls_deinit(session);
err:
return NULL;
}
static struct mailstream_ssl_data * tls_data_new(int fd)
{
return ssl_data_new(fd);
}
#endif
static void ssl_data_free(struct mailstream_ssl_data * ssl_data)
{
free(ssl_data);
}
#ifndef USE_GNUTLS
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;
}
#else
static void ssl_data_close(struct mailstream_ssl_data * ssl_data)
{
gnutls_deinit(ssl_data->session);
ssl_data->session = NULL;
close(ssl_data->fd);
ssl_data->fd = -1;
}
#endif
#endif
mailstream_low * mailstream_low_ssl_open_full(int fd, int starttls)
{
#ifdef USE_SSL
mailstream_low * s;
struct mailstream_ssl_data * ssl_data;
if (starttls)
ssl_data = tls_data_new(fd);
else
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
}
mailstream_low * mailstream_low_ssl_open(int fd)
{
return mailstream_low_ssl_open_full(fd, 0);
}
mailstream_low * mailstream_low_tls_open(int fd)
{
return mailstream_low_ssl_open_full(fd, 1);
}
#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;
}
#ifndef USE_GNUTLS
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 -1;
}
}
}
#else
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 = gnutls_record_recv(ssl_data->session, buf, count);
if (r > 0)
return r;
switch (r) {
case 0: /* closed connection */
return -1;
case GNUTLS_E_AGAIN:
case GNUTLS_E_INTERRUPTED:
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 -1;
}
}
}
#endif
#ifndef USE_GNUTLS
static ssize_t mailstream_low_ssl_write(mailstream_low * s,
const void * buf, size_t count)
{
struct mailstream_ssl_data * ssl_data;
int ssl_r;
fd_set fds_write;
fd_set fds_excp;
struct timeval timeout;
int r;
ssl_data = (struct mailstream_ssl_data *) s->data;
timeout = mailstream_network_delay;
FD_ZERO(&fds_write);
FD_SET(ssl_data->fd, &fds_write);
FD_ZERO(&fds_excp);
FD_SET(ssl_data->fd, &fds_excp);
r = select(ssl_data->fd + 1, NULL, &fds_write, &fds_excp, &timeout);
if (r == 0)
return -1;
if (FD_ISSET(ssl_data->fd, &fds_excp))
return -1;
if (!FD_ISSET(ssl_data->fd, &fds_write))
return 0;
r = SSL_write(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 -1;
case SSL_ERROR_WANT_WRITE:
return 0;
default:
return r;
}
}
#else
static ssize_t mailstream_low_ssl_write(mailstream_low * s,
const void * buf, size_t count)
{
struct mailstream_ssl_data * ssl_data;
int ssl_r;
fd_set fds_write;
fd_set fds_excp;
struct timeval timeout;
int r;
ssl_data = (struct mailstream_ssl_data *) s->data;
timeout = mailstream_network_delay;
FD_ZERO(&fds_write);
FD_SET(ssl_data->fd, &fds_write);
FD_ZERO(&fds_excp);
FD_SET(ssl_data->fd, &fds_excp);
r = select(ssl_data->fd + 1, NULL, &fds_write, &fds_excp, &timeout);
if (r == 0)
return -1;
if (FD_ISSET(ssl_data->fd, &fds_excp))
return -1;
if (!FD_ISSET(ssl_data->fd, &fds_write))
return 0;
r = gnutls_record_send(ssl_data->session, buf, count);
if (r > 0)
return r;
switch (r) {
case 0:
return -1;
case GNUTLS_E_AGAIN:
case GNUTLS_E_INTERRUPTED:
return 0;
default:
return r;
}
}
#endif
#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
}
int mailstream_ssl_get_certificate(mailstream *stream, unsigned char **cert_DER)
{
#ifdef USE_SSL
struct mailstream_ssl_data *data = NULL;
int len = 0;
#ifndef USE_GNUTLS
SSL *ssl_conn = NULL;
X509 *cert = NULL;
#else
gnutls_session session = NULL;
const gnutls_datum *raw_cert_list;
unsigned int raw_cert_list_length;
char *exported_cert = NULL;
gnutls_x509_crt cert = NULL;
char output[10*1024];
#endif
if (cert_DER == NULL || stream == NULL || stream->low == NULL)
return -1;
data = stream->low->data;
if (data == NULL)
return -1;
#ifndef USE_GNUTLS
ssl_conn = data->ssl_conn;
if (ssl_conn == NULL)
return -1;
cert = SSL_get_peer_certificate(ssl_conn);
if (cert == NULL)
return -1;
*cert_DER = NULL;
len = i2d_X509(cert, cert_DER);
return len;
#else
session = data->session;
raw_cert_list = gnutls_certificate_get_peers(session, &raw_cert_list_length);
if (raw_cert_list
&& gnutls_certificate_type_get(session) == GNUTLS_CRT_X509
&& gnutls_x509_crt_init(&cert) >= 0
&& gnutls_x509_crt_import(cert, &raw_cert_list[0], GNUTLS_X509_FMT_DER) >= 0) {
len = 10*1024;
if (gnutls_x509_crt_export(cert, GNUTLS_X509_FMT_DER, output, &len) < 0)
return -1;
if (len >= 0) {
*cert_DER = malloc (len + 1);
if (*cert_DER == NULL)
return -1;
memcpy (*cert_DER, output, len);
}
gnutls_x509_crt_deinit(cert);
return len;
}
#endif
#endif
return -1;
}
@@ -0,0 +1,65 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: mailstream_ssl.h,v 1.12 2006/02/17 20:45:14 colinleroy Exp $
*/
#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_low * mailstream_low_tls_open(int fd);
mailstream * mailstream_ssl_open(int fd);
void mailstream_gnutls_init_not_required(void);
void mailstream_openssl_init_not_required(void);
void mailstream_ssl_init_not_required(void);
int mailstream_ssl_get_certificate(mailstream *stream, unsigned char **cert_DER);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,90 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: mailstream_types.h,v 1.13 2006/03/22 08:10:47 hoa Exp $
*/
#ifndef MAILSTREAM_TYPES_H
#define MAILSTREAM_TYPES_H
#ifdef __cplusplus
extern "C" {
#endif
#define LIBETPAN_MAILSTREAM_DEBUG
#ifndef LIBETPAN_CONFIG_H
# include <libetpan/libetpan-config.h>
#endif
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
+67
View File
@@ -0,0 +1,67 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: mapping.c,v 1.7 2006/06/26 11:50:26 hoa Exp $
*/
#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 == (void *)MAP_FAILED)
return -1;
result = ((char *) mapping) + delta;
mapping_size = length + offset;
* pmapping = mapping;
* pmapping_size = mapping_size;
* presult = result;
return 0;
}
+54
View File
@@ -0,0 +1,54 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: mapping.h,v 1.6 2004/11/21 21:53:31 hoa Exp $
*/
#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
+572
View File
@@ -0,0 +1,572 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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.c,v 1.9 2006/06/02 15:44:29 smarinier Exp $
*/
/* 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>
#ifndef _MSC_VER
# include <sys/param.h>
# include <sys/socket.h>
# include <netinet/in.h>
#endif
#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], const unsigned char [64]));
static void Encode PROTO_LIST
((unsigned char *, UINT4 *, unsigned int));
static void Decode PROTO_LIST
((UINT4 *, const unsigned char *, unsigned int));
static void MD5_memcpy PROTO_LIST ((POINTER, CONST_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 */
const 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];
const 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;
const 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;
CONST_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], 0, sizeof(k_ipad));
MD5_memset(&k_opad[0], 0, sizeof(k_opad));
MD5_memset(&tk[0], 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((POINTER) &hmac, 0, sizeof(hmac));
}
void hmac_md5_import(HMAC_MD5_CTX *hmac,
HMAC_MD5_STATE *state)
{
unsigned lupe;
MD5_memset((POINTER) 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 */
}
+88
View File
@@ -0,0 +1,88 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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,v 1.11 2006/06/02 15:44:29 smarinier Exp $
*/
/* 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 *, const unsigned char *, unsigned int));
void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *));
void hmac_md5 PROTO_LIST ((const unsigned char *, int, const unsigned char *, int, unsigned char *));
#ifdef __cplusplus
}
#endif
#endif
+80
View File
@@ -0,0 +1,80 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: md5global.h,v 1.7 2006/06/02 15:44:29 smarinier Exp $
*/
/* 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 1
#endif
/* POINTER defines a generic pointer type */
typedef unsigned char *POINTER;
typedef const unsigned char *CONST_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
+583
View File
@@ -0,0 +1,583 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: mmapstring.c,v 1.22 2006/06/26 11:50:26 hoa Exp $
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "mmapstring.h"
#include "chash.h"
#include <stdlib.h>
#ifdef _MSC_VER
# include "win_etpan.h"
#else
# include <unistd.h>
# include <sys/mman.h>
#endif
#include <string.h>
#ifdef LIBETPAN_REENTRANT
# ifndef WIN32
# include <pthread.h>
# endif
#endif
#include "libetpan-config.h"
#define MMAPSTRING_MAX(a, b) ((a) > (b) ? (a) : (b))
#define MMAPSTRING_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 */
#ifdef LIBETPAN_REENTRANT
# ifdef WIN32
static CRITICAL_SECTION mmapstring_lock ;
static CRITICAL_SECTION* _get_critical() {
InitializeCriticalSection(&mmapstring_lock);
return &mmapstring_lock;
}
static int _lock_initialized = 0;
static void __mutex_lock(CRITICAL_SECTION* section) {
if (!_lock_initialized)
InitializeCriticalSection(section);
EnterCriticalSection( section);
}
static void __mutex_unlock(CRITICAL_SECTION* section) {
if (!_lock_initialized)
InitializeCriticalSection(section);
LeaveCriticalSection( section);
}
# define MUTEX_LOCK(x) __mutex_lock(x)
# define MUTEX_UNLOCK(x) __mutex_unlock(x)
# else
static pthread_mutex_t mmapstring_lock = PTHREAD_MUTEX_INITIALIZER;
# define MUTEX_LOCK(x) pthread_mutex_lock(x)
# define MUTEX_UNLOCK(x) pthread_mutex_unlock(x)
# endif
#else
# define MUTEX_LOCK(x)
# define MUTEX_UNLOCK(x)
#endif
static chash * mmapstring_hashtable = NULL;
static void mmapstring_hashtable_init(void)
{
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;
MUTEX_LOCK(&mmapstring_lock);
if (mmapstring_hashtable == NULL) {
mmapstring_hashtable_init();
}
ht = mmapstring_hashtable;
if (ht == NULL) {
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);
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;
MUTEX_LOCK(&mmapstring_lock);
ht = mmapstring_hashtable;
if (ht == NULL) {
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;
}
}
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.
*/
/* SEB */
#ifndef MMAP_UNAVAILABLE
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 == (char *)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 == (char *)MAP_FAILED)
return NULL;
string->mmapped_size = string->allocated_len;
string->str = data;
}
return string;
}
#endif
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 newstring;
}
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, MMAPSTRING_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 ("");
else
{
string = mmap_string_sized_new (len);
if (string == NULL)
return string;
if (init)
mmap_string_append_len (string, init, len);
return string;
}
}
void
mmap_string_free (MMAPString *string)
{
if (string == NULL)
return;
/* SEB */
#ifndef MMAP_UNAVAILABLE
if (string->fd != -1) {
munmap(string->str, string->mmapped_size);
close(string->fd);
}
else
#endif
{
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 = MMAPSTRING_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;
}
+156
View File
@@ -0,0 +1,156 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: mmapstring.h,v 1.13 2006/03/22 08:10:47 hoa Exp $
*/
#ifndef __MMAP_STRING_H__
#define __MMAP_STRING_H__
#include <sys/types.h>
#ifndef LIBETPAN_CONFIG_H
# include <libetpan/libetpan-config.h>
#endif
#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
*/
LIBETPAN_EXPORT
MMAPString * mmap_string_new (const char * init);
LIBETPAN_EXPORT
MMAPString * mmap_string_new_len (const char * init,
size_t len);
LIBETPAN_EXPORT
MMAPString * mmap_string_sized_new (size_t dfl_size);
LIBETPAN_EXPORT
void mmap_string_free (MMAPString * string);
LIBETPAN_EXPORT
MMAPString * mmap_string_assign (MMAPString * string,
const char * rval);
LIBETPAN_EXPORT
MMAPString * mmap_string_truncate (MMAPString *string,
size_t len);
LIBETPAN_EXPORT
MMAPString * mmap_string_set_size (MMAPString * string,
size_t len);
LIBETPAN_EXPORT
MMAPString * mmap_string_insert_len (MMAPString * string,
size_t pos,
const char * val,
size_t len);
LIBETPAN_EXPORT
MMAPString * mmap_string_append (MMAPString * string,
const char * val);
LIBETPAN_EXPORT
MMAPString * mmap_string_append_len (MMAPString * string,
const char * val,
size_t len);
LIBETPAN_EXPORT
MMAPString * mmap_string_append_c (MMAPString * string,
char c);
LIBETPAN_EXPORT
MMAPString * mmap_string_prepend (MMAPString * string,
const char * val);
LIBETPAN_EXPORT
MMAPString * mmap_string_prepend_c (MMAPString * string,
char c);
LIBETPAN_EXPORT
MMAPString * mmap_string_prepend_len (MMAPString * string,
const char * val,
size_t len);
LIBETPAN_EXPORT
MMAPString * mmap_string_insert (MMAPString * string,
size_t pos,
const char * val);
LIBETPAN_EXPORT
MMAPString * mmap_string_insert_c (MMAPString *string,
size_t pos,
char c);
LIBETPAN_EXPORT
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__ */
+2
View File
@@ -0,0 +1,2 @@
.libs
*.la
+15
View File
@@ -0,0 +1,15 @@
top_builddir = ../..
SUBLIBS = interface/libinterface.la \
tools/libtools.la \
implementation/libimplementation.la
SUBDIRS = interface \
tools \
implementation
TARGET = libdriver
include $(top_builddir)/Rules
+9
View File
@@ -0,0 +1,9 @@
- get_message_list() will disconnect and reconnect POP3 box
- add UID to non-cached drivers, help clients to recognize messages
- move IMAP UID cache to non-cached driver
- fix message size (put it in cache)
- XXX : fetch body in nntp do not use generic_fetch_body
- add flags prototype to add or remove flags
- cache bodystructures
- search is not implemented
- list of folder new implementation
@@ -0,0 +1,2 @@
.libs
*.la
@@ -0,0 +1,28 @@
SUBLIBS = data-message/libdata-message.la \
imap/libimap.la \
maildir/libmaildir.la \
mbox/libmbox.la \
mh/libmh.la \
mime-message/libmime-message.la \
nntp/libnntp.la \
pop3/libpop3.la \
hotmail/libhotmail.la \
db/libdb.la
SUBDIRS = data-message \
imap \
maildir \
mbox \
mh \
mime-message \
nntp \
pop3 \
hotmail \
db
TARGET = libimplementation
top_builddir = ../../..
include $(top_builddir)/Rules
@@ -0,0 +1,3 @@
.libs
*.la
*.lo
@@ -0,0 +1,14 @@
top_builddir = ../../../..
HEADERS = \
data_message_driver.h
SOURCES = \
data_message_driver.c
TARGET = libdata-message
INCLUDES = -I../../interface
include $(top_builddir)/Rules
@@ -0,0 +1,152 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: data_message_driver.c,v 1.10 2006/06/26 11:50:26 hoa Exp $
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "data_message_driver.h"
#include "mailmessage.h"
#include "mailmessage_tools.h"
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef HAVE_SYS_MMAN_H
# include <sys/mman.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
static int fetch_size(mailmessage * msg, size_t * result)
{
struct generic_message_t * msg_data;
msg_data = msg->msg_data;
* result = msg_data->msg_length;
return MAIL_NO_ERROR;
}
static mailmessage_driver local_data_message_driver = {
#if ! defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
/* msg_name */ "data",
/* msg_initialize */ mailmessage_generic_initialize,
/* msg_uninitialize */ mailmessage_generic_uninitialize,
/* msg_flush */ mailmessage_generic_flush,
/* msg_check */ NULL,
/* msg_fetch_result_free */ mailmessage_generic_fetch_result_free,
/* msg_fetch */ mailmessage_generic_fetch,
/* msg_fetch_header */ mailmessage_generic_fetch_header,
/* msg_fetch_body */ mailmessage_generic_fetch_body,
/* msg_fetch_size */ fetch_size,
/* msg_get_bodystructure */ mailmessage_generic_get_bodystructure,
/* msg_fetch_section */ mailmessage_generic_fetch_section,
/* msg_fetch_section_header */ mailmessage_generic_fetch_section_header,
/* msg_fetch_section_mime */ mailmessage_generic_fetch_section_mime,
/* msg_fetch_section_body */ mailmessage_generic_fetch_section_body,
/* msg_fetch_envelope */ mailmessage_generic_fetch_envelope,
/* msg_get_flags */ NULL,
#else
.msg_name = "data",
.msg_initialize = mailmessage_generic_initialize,
.msg_uninitialize = mailmessage_generic_uninitialize,
.msg_flush = mailmessage_generic_flush,
.msg_check = NULL,
.msg_fetch_result_free = mailmessage_generic_fetch_result_free,
.msg_fetch = mailmessage_generic_fetch,
.msg_fetch_header = mailmessage_generic_fetch_header,
.msg_fetch_body = mailmessage_generic_fetch_body,
.msg_fetch_size = fetch_size,
.msg_get_bodystructure = mailmessage_generic_get_bodystructure,
.msg_fetch_section = mailmessage_generic_fetch_section,
.msg_fetch_section_header = mailmessage_generic_fetch_section_header,
.msg_fetch_section_mime = mailmessage_generic_fetch_section_mime,
.msg_fetch_section_body = mailmessage_generic_fetch_section_body,
.msg_fetch_envelope = mailmessage_generic_fetch_envelope,
.msg_get_flags = NULL,
#endif
};
mailmessage_driver * data_message_driver = &local_data_message_driver;
mailmessage * data_message_init(char * data, size_t len)
{
struct generic_message_t * msg_data;
mailmessage * msg;
int r;
msg = mailmessage_new();
if (msg == NULL)
goto err;
r = mailmessage_init(msg, NULL, data_message_driver, 0, len);
if (r < 0)
goto free;
msg_data = msg->msg_data;
msg_data->msg_fetched = 1;
msg_data->msg_message = data;
msg_data->msg_length = len;
return msg;
free:
mailmessage_free(msg);
err:
return NULL;
}
void data_message_detach_mime(mailmessage * msg)
{
msg->msg_mime = NULL;
}
@@ -0,0 +1,50 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: data_message_driver.h,v 1.4 2004/11/21 21:53:31 hoa Exp $
*/
#ifndef DATA_MESSAGE_DRIVER_H
#define DATA_MESSAGE_DRIVER_H
#include <libetpan/mailmessage.h>
#define LIBETPAN_DATA_MESSAGE
extern mailmessage_driver * data_message_driver;
mailmessage * data_message_init(char * data, size_t len);
void data_message_detach_mime(mailmessage * msg);
#endif
@@ -0,0 +1,3 @@
.libs
*.la
*.lo
@@ -0,0 +1,24 @@
top_builddir = ../../../..
HEADERS = \
dbdriver.h \
dbdriver_message.h \
dbdriver_types.h \
dbstorage.h
SOURCES = \
dbdriver.c \
dbdriver_message.c \
dbstorage.c
TARGET = libdb
INCLUDES = -I../../interface \
-I../../tools \
-I$(srcdir)/low-level/mime \
-I$(srcdir)/low-level/imf \
-I$(srcdir)/data-types
include $(top_builddir)/Rules
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,53 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: dbdriver.h,v 1.2 2004/11/21 21:53:31 hoa Exp $
*/
#ifndef DBDRIVER_H
#define DBDRIVER_H
#include <libetpan/dbdriver_message.h>
#include <libetpan/dbdriver_types.h>
#ifdef __cplusplus
extern "C" {
#endif
extern mailsession_driver * db_session_driver;
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,337 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: dbdriver_message.c,v 1.6 2006/06/26 11:50:26 hoa Exp $
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "dbdriver_message.h"
#include "dbdriver.h"
#include "mail_cache_db.h"
#include "mailmessage_tools.h"
#include "generic_cache.h"
#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
static int fetch_envelope(mailmessage * msg_info,
struct mailimf_fields ** result);
static int get_flags(mailmessage * msg_info,
struct mail_flags ** result);
static int prefetch(mailmessage * msg_info);
static void prefetch_free(struct generic_message_t * msg);
static int initialize(mailmessage * msg_info);
static void check(mailmessage * msg_info);
static mailmessage_driver local_db_message_driver = {
#if ! defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
/* msg_name */ "db",
/* msg_initialize */ initialize,
/* msg_uninitialize */ mailmessage_generic_uninitialize,
/* msg_flush */ mailmessage_generic_flush,
/* msg_check */ check,
/* msg_fetch_result_free */ mailmessage_generic_fetch_result_free,
/* msg_fetch */ mailmessage_generic_fetch,
/* msg_fetch_header */ mailmessage_generic_fetch_header,
/* msg_fetch_body */ mailmessage_generic_fetch_header,
/* msg_fetch_size */ NULL,
/* msg_get_bodystructure */ mailmessage_generic_get_bodystructure,
/* msg_fetch_section */ mailmessage_generic_fetch_section,
/* msg_fetch_section_header */ mailmessage_generic_fetch_section_header,
/* msg_fetch_section_mime */ mailmessage_generic_fetch_section_mime,
/* msg_fetch_section_body */ mailmessage_generic_fetch_section_body,
/* msg_fetch_envelope */ fetch_envelope,
/* msg_get_flags */ get_flags,
#else
.msg_name = "db",
.msg_initialize = initialize,
.msg_uninitialize = mailmessage_generic_uninitialize,
.msg_flush = mailmessage_generic_flush,
.msg_check = check,
.msg_fetch_result_free = mailmessage_generic_fetch_result_free,
.msg_fetch = mailmessage_generic_fetch,
.msg_fetch_header = mailmessage_generic_fetch_header,
.msg_fetch_body = mailmessage_generic_fetch_header,
.msg_fetch_size = NULL,
.msg_get_bodystructure = mailmessage_generic_get_bodystructure,
.msg_fetch_section = mailmessage_generic_fetch_section,
.msg_fetch_section_header = mailmessage_generic_fetch_section_header,
.msg_fetch_section_mime = mailmessage_generic_fetch_section_mime,
.msg_fetch_section_body = mailmessage_generic_fetch_section_body,
.msg_fetch_envelope = fetch_envelope,
.msg_get_flags = get_flags,
#endif
};
mailmessage_driver * db_message_driver = &local_db_message_driver;
struct db_msg_data {
MMAPString * msg_content;
};
static inline struct db_session_state_data *
get_session_data(mailmessage * msg)
{
return msg->msg_session->sess_data;
}
static int prefetch(mailmessage * msg_info)
{
struct generic_message_t * msg;
int res;
struct db_msg_data * data;
struct db_session_state_data * sess_data;
MMAPString * msg_content;
struct mail_cache_db * maildb;
int r;
char key[PATH_MAX];
void * msg_data;
size_t msg_data_len;
sess_data = get_session_data(msg_info);
r = mail_cache_db_open_lock(sess_data->db_filename, &maildb);
if (r < 0) {
res = MAIL_ERROR_FILE;
goto err;
}
snprintf(key, sizeof(key), "%lu", (unsigned long) msg_info->msg_index);
r = mail_cache_db_get(maildb, key, strlen(key), &msg_data, &msg_data_len);
if (r < 0) {
res = MAIL_ERROR_MSG_NOT_FOUND;
goto close_db;
}
msg_content = mmap_string_new_len(msg_data, msg_data_len);
if (msg_content == NULL) {
res = MAIL_ERROR_MEMORY;
goto close_db;
}
data = malloc(sizeof(* data));
if (data == NULL) {
res = MAIL_ERROR_MEMORY;
goto free_mmapstr;
}
data->msg_content = msg_content;
msg = msg_info->msg_data;
msg->msg_data = data;
msg->msg_message = msg_content->str;
msg->msg_length = msg_content->len;
mail_cache_db_close_unlock(sess_data->db_filename, maildb);
return MAIL_NO_ERROR;
free_mmapstr:
mmap_string_free(msg_content);
close_db:
mail_cache_db_close_unlock(sess_data->db_filename, maildb);
err:
return res;
}
static void prefetch_free(struct generic_message_t * msg)
{
if (msg->msg_message != NULL) {
struct db_msg_data * data;
data = msg->msg_data;
mmap_string_free(data->msg_content);
data->msg_content = NULL;
free(data);
msg->msg_message = NULL;
}
}
static int initialize(mailmessage * msg_info)
{
struct generic_message_t * msg;
int r;
char key[PATH_MAX];
snprintf(key, sizeof(key), "%lu", (unsigned long) msg_info->msg_index);
msg_info->msg_uid = strdup(key);
if (msg_info->msg_uid == NULL)
return MAIL_ERROR_MEMORY;
r = mailmessage_generic_initialize(msg_info);
if (r != MAIL_NO_ERROR)
return r;
msg = msg_info->msg_data;
msg->msg_prefetch = prefetch;
msg->msg_prefetch_free = prefetch_free;
return MAIL_NO_ERROR;
}
static void check(mailmessage * msg_info)
{
int r;
if (msg_info->msg_flags != NULL) {
r = mail_flags_store_set(get_session_data(msg_info)->db_flags_store,
msg_info);
/* ignore errors */
}
}
static int fetch_envelope(mailmessage * msg_info,
struct mailimf_fields ** result)
{
char key[PATH_MAX];
int r;
struct db_session_state_data * sess_data;
struct mail_cache_db * maildb;
int res;
struct mailimf_fields * fields;
MMAPString * mmapstr;
sess_data = get_session_data(msg_info);
r = mail_cache_db_open_lock(sess_data->db_filename, &maildb);
if (r < 0) {
res = MAIL_ERROR_FILE;
goto err;
}
snprintf(key, sizeof(key), "%lu-envelope",
(unsigned long) msg_info->msg_index);
mmapstr = mmap_string_new("");
if (mmapstr == NULL) {
res = MAIL_ERROR_MEMORY;
goto close_db;
}
r = generic_cache_fields_read(maildb, mmapstr,
key, &fields);
mmap_string_free(mmapstr);
if (r != MAIL_NO_ERROR) {
res = MAIL_ERROR_MSG_NOT_FOUND;
goto close_db;
}
mail_cache_db_close_unlock(sess_data->db_filename, maildb);
* result = fields;
return MAIL_NO_ERROR;
close_db:
mail_cache_db_close_unlock(sess_data->db_filename, maildb);
err:
return res;
}
static int get_flags(mailmessage * msg_info,
struct mail_flags ** result)
{
char key[PATH_MAX];
int r;
struct db_session_state_data * sess_data;
struct mail_cache_db * maildb;
int res;
MMAPString * mmapstr;
sess_data = get_session_data(msg_info);
r = mail_cache_db_open_lock(sess_data->db_filename, &maildb);
if (r < 0) {
res = MAIL_ERROR_FILE;
goto err;
}
snprintf(key, sizeof(key), "%lu-flags", (unsigned long) msg_info->msg_index);
mmapstr = mmap_string_new("");
if (mmapstr == NULL) {
res = MAIL_ERROR_MEMORY;
goto close_db;
}
r = generic_cache_flags_read(maildb, mmapstr,
key, &msg_info->msg_flags);
mmap_string_free(mmapstr);
if (r != MAIL_NO_ERROR) {
msg_info->msg_flags = mail_flags_new_empty();
if (msg_info->msg_flags == NULL) {
res = MAIL_ERROR_MEMORY;
goto close_db;
}
}
mail_cache_db_close_unlock(sess_data->db_filename, maildb);
* result = msg_info->msg_flags;
return MAIL_NO_ERROR;
close_db:
mail_cache_db_close_unlock(sess_data->db_filename, maildb);
err:
return res;
}
@@ -0,0 +1,52 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: dbdriver_message.h,v 1.2 2004/11/21 21:53:31 hoa Exp $
*/
#ifndef DBDRIVER_MESSAGE_H
#define DBDRIVER_MESSAGE_H
#include <libetpan/dbdriver_types.h>
#ifdef __cplusplus
extern "C" {
#endif
extern mailmessage_driver * db_message_driver;
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,71 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: dbdriver_types.h,v 1.2 2004/11/21 21:53:31 hoa Exp $
*/
#ifndef DBDRIVER_TYPES_H
#define DBDRIVER_TYPES_H
#include <libetpan/libetpan-config.h>
#include <libetpan/maildriver_types.h>
#include <libetpan/generic_cache_types.h>
#include <libetpan/mailstorage_types.h>
#ifdef __cplusplus
extern "C" {
#endif
struct db_session_state_data {
char db_filename[PATH_MAX];
struct mail_flags_store * db_flags_store;
};
/* db storage */
/*
db_mailstorage is the state data specific to the db storage.
- pathname is the path of the db storage.
*/
struct db_mailstorage {
char * db_pathname;
};
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,156 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: dbstorage.c,v 1.6 2006/06/26 11:50:26 hoa Exp $
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "dbstorage.h"
#include "mailstorage.h"
#include "mail.h"
#include "mailmessage.h"
#include "dbdriver.h"
#include "maildriver.h"
#include <stdlib.h>
#include <string.h>
/* db storage */
static int db_mailstorage_connect(struct mailstorage * storage);
static int
db_mailstorage_get_folder_session(struct mailstorage * storage,
char * pathname, mailsession ** result);
static void db_mailstorage_uninitialize(struct mailstorage * storage);
static mailstorage_driver db_mailstorage_driver = {
#if ! defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
/* sto_name */ "db",
/* sto_connect */ db_mailstorage_connect,
/* sto_get_folder_session */ db_mailstorage_get_folder_session,
/* sto_uninitialize */ db_mailstorage_uninitialize,
#else
.sto_name = "db",
.sto_connect = db_mailstorage_connect,
.sto_get_folder_session = db_mailstorage_get_folder_session,
.sto_uninitialize = db_mailstorage_uninitialize,
#endif
};
LIBETPAN_EXPORT
int db_mailstorage_init(struct mailstorage * storage,
char * db_pathname)
{
struct db_mailstorage * db_storage;
db_storage = malloc(sizeof(* db_storage));
if (db_storage == NULL)
goto err;
db_storage->db_pathname = strdup(db_pathname);
if (db_storage->db_pathname == NULL)
goto free;
storage->sto_data = db_storage;
storage->sto_driver = &db_mailstorage_driver;
return MAIL_NO_ERROR;
free:
free(db_storage);
err:
return MAIL_ERROR_MEMORY;
}
static void db_mailstorage_uninitialize(struct mailstorage * storage)
{
struct db_mailstorage * db_storage;
db_storage = storage->sto_data;
free(db_storage->db_pathname);
free(db_storage);
storage->sto_data = NULL;
}
static int db_mailstorage_connect(struct mailstorage * storage)
{
struct db_mailstorage * db_storage;
mailsession_driver * driver;
int r;
int res;
mailsession * session;
db_storage = storage->sto_data;
driver = db_session_driver;
session = mailsession_new(driver);
if (session == NULL) {
res = MAIL_ERROR_MEMORY;
goto err;
}
r = mailsession_connect_path(session, db_storage->db_pathname);
switch (r) {
case MAIL_NO_ERROR_NON_AUTHENTICATED:
case MAIL_NO_ERROR_AUTHENTICATED:
case MAIL_NO_ERROR:
break;
default:
res = r;
goto free;
}
storage->sto_session = session;
return MAIL_NO_ERROR;
free:
mailsession_free(session);
err:
return res;
}
static int
db_mailstorage_get_folder_session(struct mailstorage * storage,
char * pathname, mailsession ** result)
{
* result = storage->sto_session;
return MAIL_NO_ERROR;
}
@@ -0,0 +1,62 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: dbstorage.h,v 1.3 2005/06/01 12:21:57 smarinier Exp $
*/
#ifndef DBSTORAGE_H
#define DBSTORAGE_H
#include <libetpan/dbdriver_types.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
db_mailstorage_init is the constructor for a DB storage.
@param storage this is the storage to initialize.
@param pathname is the directory that contains the mailbox.
*/
LIBETPAN_EXPORT
int db_mailstorage_init(struct mailstorage * storage,
char * db_pathname);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,3 @@
.libs
*.la
*.lo
@@ -0,0 +1,16 @@
top_builddir = ../../../..
HEADERS = \
hotmailstorage.h
SOURCES = \
hotmailstorage.c
TARGET = libhotmail
INCLUDES = -I../../interface \
-I../pop3
include $(top_builddir)/Rules
@@ -0,0 +1,67 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: hotmailstorage.c,v 1.4 2006/05/22 13:39:40 hoa Exp $
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "hotmailstorage.h"
#include "pop3storage.h"
#include "pop3driver_types.h"
/*
hotway is a gateway from hotmail to POP3
http://hotwayd.sourceforge.net/
*/
static char hotway_command[512] = "/usr/bin/hotwayd";
LIBETPAN_EXPORT
int hotmail_mailstorage_init(struct mailstorage * storage,
char * hotmail_login, char * hotmail_password,
int hotmail_cached, char * hotmail_cache_directory,
char * hotmail_flags_directory)
{
return pop3_mailstorage_init(storage,
"hotmail.dummy", 0,
hotway_command,
CONNECTION_TYPE_COMMAND, POP3_AUTH_TYPE_PLAIN,
hotmail_login, hotmail_password,
hotmail_cached, hotmail_cache_directory,
hotmail_flags_directory);
}
@@ -0,0 +1,57 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: hotmailstorage.h,v 1.3 2005/06/01 12:21:58 smarinier Exp $
*/
#ifndef HOTMAILSTORAGE_H
#define HOTMAILSTORAGE_H
#ifdef __cplusplus
extern "C" {
#endif
#include "mailstorage_types.h"
LIBETPAN_EXPORT
int hotmail_mailstorage_init(struct mailstorage * storage,
char * hotmail_login, char * hotmail_password,
int hotmail_cached, char * hotmail_cache_directory,
char * hotmail_flags_directory);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,3 @@
.libs
*.la
*.lo
@@ -0,0 +1,30 @@
top_builddir = ../../../..
HEADERS = \
imapdriver.h \
imapdriver_message.h \
imapdriver_cached.h \
imapdriver_cached_message.h \
imapdriver_types.h \
imapstorage.h
SOURCES = \
imapdriver.c \
imapdriver_cached.c \
imapdriver_cached_message.c \
imapdriver_message.c \
imapdriver_tools.c \
imapstorage.c
TARGET = libimap
INCLUDES = -I../../interface \
-I../../tools \
-I$(srcdir)/low-level/imap \
-I$(srcdir)/low-level/mime \
-I$(srcdir)/low-level/imf \
-I$(srcdir)/data-types
include $(top_builddir)/Rules
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,52 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: imapdriver.h,v 1.12 2004/11/21 21:53:32 hoa Exp $
*/
#ifndef IMAPDRIVER_H
#define IMAPDRIVER_H
#ifdef __cplusplus
extern "C" {
#endif
#include <libetpan/imapdriver_types.h>
extern mailsession_driver * imap_session_driver;
#ifdef __cplusplus
}
#endif
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,52 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: imapdriver_cached.h,v 1.11 2004/11/21 21:53:32 hoa Exp $
*/
#ifndef IMAPDRIVER_CACHED_H
#define IMAPDRIVER_CACHED_H
#include <libetpan/imapdriver_types.h>
#ifdef __cplusplus
extern "C" {
#endif
extern mailsession_driver * imap_cached_session_driver;
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,693 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: imapdriver_cached_message.c,v 1.25 2006/06/26 11:50:26 hoa Exp $
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "imapdriver_cached_message.h"
#include "imapdriver_tools.h"
#include "imapdriver_message.h"
#include "imapdriver_cached.h"
#include "imapdriver_types.h"
#include "imapdriver.h"
#include "mailmessage.h"
#include "generic_cache.h"
#include "mail_cache_db.h"
#include <string.h>
#include <stdlib.h>
static int imap_initialize(mailmessage * msg_info);
static void imap_uninitialize(mailmessage * msg_info);
static void imap_flush(mailmessage * msg_info);
static void imap_check(mailmessage * msg_info);
static void imap_fetch_result_free(mailmessage * msg_info,
char * msg);
static int imap_fetch(mailmessage * msg_info,
char ** result,
size_t * result_len);
static int imap_fetch_header(mailmessage * msg_info,
char ** result,
size_t * result_len);
static int imap_fetch_body(mailmessage * msg_info,
char ** result, size_t * result_len);
static int imap_fetch_size(mailmessage * msg_info,
size_t * result);
static int imap_get_bodystructure(mailmessage * msg_info,
struct mailmime ** result);
static int imap_fetch_section(mailmessage * msg_info,
struct mailmime * mime,
char ** result, size_t * result_len);
static int imap_fetch_section_header(mailmessage * msg_info,
struct mailmime * mime,
char ** result,
size_t * result_len);
static int imap_fetch_section_mime(mailmessage * msg_info,
struct mailmime * mime,
char ** result,
size_t * result_len);
static int imap_fetch_section_body(mailmessage * msg_info,
struct mailmime * mime,
char ** result,
size_t * result_len);
static int imap_fetch_envelope(mailmessage * msg_info,
struct mailimf_fields ** result);
static int imap_get_flags(mailmessage * msg_info,
struct mail_flags ** result);
static mailmessage_driver local_imap_cached_message_driver = {
#if ! defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
/* msg_name */ "imap-cached",
/* msg_initialize */ imap_initialize,
/* msg_uninitialize */ imap_uninitialize,
/* msg_flush */ imap_flush,
/* msg_check */ imap_check,
/* msg_fetch_result_free */ imap_fetch_result_free,
/* msg_fetch */ imap_fetch,
/* msg_fetch_header */ imap_fetch_header,
/* msg_fetch_body */ imap_fetch_body,
/* msg_fetch_size */ imap_fetch_size,
/* msg_get_bodystructure */ imap_get_bodystructure,
/* msg_fetch_section */ imap_fetch_section,
/* msg_fetch_section_header */ imap_fetch_section_header,
/* msg_fetch_section_mime */ imap_fetch_section_mime,
/* msg_fetch_section_body */ imap_fetch_section_body,
/* msg_fetch_envelope */ imap_fetch_envelope,
/* msg_get_flags */ imap_get_flags,
#else
.msg_name = "imap-cached",
.msg_initialize = imap_initialize,
.msg_uninitialize = imap_uninitialize,
.msg_flush = imap_flush,
.msg_check = imap_check,
.msg_fetch_result_free = imap_fetch_result_free,
.msg_fetch = imap_fetch,
.msg_fetch_header = imap_fetch_header,
.msg_fetch_body = imap_fetch_body,
.msg_fetch_size = imap_fetch_size,
.msg_get_bodystructure = imap_get_bodystructure,
.msg_fetch_section = imap_fetch_section,
.msg_fetch_section_header = imap_fetch_section_header,
.msg_fetch_section_mime = imap_fetch_section_mime,
.msg_fetch_section_body = imap_fetch_section_body,
.msg_fetch_envelope = imap_fetch_envelope,
.msg_get_flags = imap_get_flags,
#endif
};
mailmessage_driver * imap_cached_message_driver =
&local_imap_cached_message_driver;
static inline struct imap_cached_session_state_data *
get_cached_session_data(mailmessage * msg)
{
return msg->msg_session->sess_data;
}
static inline mailmessage * get_ancestor(mailmessage * msg_info)
{
return msg_info->msg_data;
}
static inline struct imap_cached_session_state_data *
cached_session_get_data(mailsession * s)
{
return s->sess_data;
}
static inline mailsession * cached_session_get_ancestor(mailsession * s)
{
return cached_session_get_data(s)->imap_ancestor;
}
static inline struct imap_session_state_data *
cached_session_get_ancestor_data(mailsession * s)
{
return cached_session_get_ancestor(s)->sess_data;
}
static inline mailimap *
cached_session_get_imap_session(mailsession * session)
{
return cached_session_get_ancestor_data(session)->imap_session;
}
static inline mailimap * get_imap_session(mailmessage * msg)
{
return cached_session_get_imap_session(msg->msg_session);
}
static inline mailsession * get_ancestor_session(mailmessage * msg_info)
{
return cached_session_get_ancestor(msg_info->msg_session);
}
static void generate_key_from_mime_section(char * key, size_t size,
struct mailmime * mime)
{
clistiter * cur;
MMAPString * gstr;
struct mailmime_section * part;
int r;
snprintf(key, size, "unvalid");
r = mailmime_get_section_id(mime, &part);
if (r != MAILIMF_NO_ERROR)
goto err;
gstr = mmap_string_new("part");
if (gstr == NULL)
goto free_section;
for(cur = clist_begin(part->sec_list) ;
cur != NULL ; cur = clist_next(cur)) {
char s[20];
snprintf(s, 20, ".%u", * (uint32_t *) clist_content(cur));
if (mmap_string_append(gstr, s) == NULL)
goto free_str;
}
snprintf(key, size, "%s", gstr->str);
mmap_string_free(gstr);
mailmime_section_free(part);
return;
free_str:
mmap_string_free(gstr);
free_section:
mailmime_section_free(part);
err:;
}
static void generate_key_from_section(char * key, size_t size,
mailmessage * msg_info,
struct mailmime * mime, int type)
{
char section_str[PATH_MAX];
generate_key_from_mime_section(section_str, PATH_MAX, mime);
switch (type) {
case IMAP_SECTION_MESSAGE:
snprintf(key, size, "%s-%s", msg_info->msg_uid, section_str);
break;
case IMAP_SECTION_HEADER:
snprintf(key, size, "%s-%s-header", msg_info->msg_uid, section_str);
break;
case IMAP_SECTION_MIME:
snprintf(key, size, "%s-%s-mime", msg_info->msg_uid, section_str);
break;
case IMAP_SECTION_BODY:
snprintf(key, size, "%s-%s-text", msg_info->msg_uid, section_str);
break;
}
}
static void generate_key_from_message(char * key, size_t size,
mailmessage * msg_info,
int type)
{
switch (type) {
case MAILIMAP_MSG_ATT_RFC822:
snprintf(key, size, "%s-rfc822", msg_info->msg_uid);
break;
case MAILIMAP_MSG_ATT_RFC822_HEADER:
snprintf(key, size, "%s-rfc822-header", msg_info->msg_uid);
break;
case MAILIMAP_MSG_ATT_RFC822_TEXT:
snprintf(key, size, "%s-rfc822-text", msg_info->msg_uid);
break;
case MAILIMAP_MSG_ATT_ENVELOPE:
snprintf(key, size, "%s-envelope", msg_info->msg_uid);
break;
}
}
static void build_cache_name(char * filename, size_t size,
mailmessage * msg, char * key)
{
char * quoted_mb;
quoted_mb = get_cached_session_data(msg)->imap_quoted_mb;
snprintf(filename, size, "%s/%s", quoted_mb, key);
}
static int imap_initialize(mailmessage * msg_info)
{
mailmessage * ancestor;
int r;
char key[PATH_MAX];
char * uid;
mailimap * imap;
ancestor = mailmessage_new();
if (ancestor == NULL)
return MAIL_ERROR_MEMORY;
r = mailmessage_init(ancestor, get_ancestor_session(msg_info),
imap_message_driver,
msg_info->msg_index, 0);
if (r != MAIL_NO_ERROR) {
mailmessage_free(ancestor);
return r;
}
imap = get_imap_session(msg_info);
snprintf(key, PATH_MAX, "%u-%u",
imap->imap_selection_info->sel_uidvalidity, msg_info->msg_index);
uid = strdup(key);
if (uid == NULL) {
mailmessage_free(ancestor);
return MAIL_ERROR_MEMORY;
}
msg_info->msg_data = ancestor;
msg_info->msg_uid = uid;
return MAIL_NO_ERROR;
}
static void imap_uninitialize(mailmessage * msg_info)
{
mailmessage_free(get_ancestor(msg_info));
msg_info->msg_data = NULL;
}
static void imap_flush(mailmessage * msg_info)
{
if (msg_info->msg_mime != NULL) {
mailmime_free(msg_info->msg_mime);
msg_info->msg_mime = NULL;
}
}
static void imap_check(mailmessage * msg_info)
{
get_ancestor(msg_info)->msg_flags = msg_info->msg_flags;
mailmessage_check(get_ancestor(msg_info));
get_ancestor(msg_info)->msg_flags = NULL;
}
static void imap_fetch_result_free(mailmessage * msg_info,
char * msg)
{
mailmessage_fetch_result_free(get_ancestor(msg_info), msg);
}
static int imap_fetch(mailmessage * msg_info,
char ** result,
size_t * result_len)
{
char key[PATH_MAX];
char filename[PATH_MAX];
int r;
char * str;
size_t len;
generate_key_from_message(key, PATH_MAX,
msg_info, MAILIMAP_MSG_ATT_RFC822);
build_cache_name(filename, PATH_MAX, msg_info, key);
r = generic_cache_read(filename, &str, &len);
if (r == MAIL_NO_ERROR) {
* result = str;
* result_len = len;
return MAIL_NO_ERROR;
}
r = mailmessage_fetch(get_ancestor(msg_info),
result, result_len);
if (r == MAIL_NO_ERROR)
generic_cache_store(filename, * result, strlen(* result));
return r;
}
static int imap_fetch_header(mailmessage * msg_info,
char ** result,
size_t * result_len)
{
char key[PATH_MAX];
char filename[PATH_MAX];
int r;
char * str;
size_t len;
generate_key_from_message(key, PATH_MAX,
msg_info, MAILIMAP_MSG_ATT_RFC822_HEADER);
build_cache_name(filename, PATH_MAX, msg_info, key);
r = generic_cache_read(filename, &str, &len);
if (r == MAIL_NO_ERROR) {
* result = str;
* result_len = len;
return MAIL_NO_ERROR;
}
r = mailmessage_fetch_header(get_ancestor(msg_info), result,
result_len);
if (r == MAIL_NO_ERROR)
generic_cache_store(filename, * result, * result_len);
return r;
}
static int imap_fetch_body(mailmessage * msg_info,
char ** result, size_t * result_len)
{
char key[PATH_MAX];
char filename[PATH_MAX];
int r;
char * str;
size_t len;
generate_key_from_message(key, PATH_MAX,
msg_info, MAILIMAP_MSG_ATT_RFC822_TEXT);
build_cache_name(filename, PATH_MAX, msg_info, key);
r = generic_cache_read(filename, &str, &len);
if (r == MAIL_NO_ERROR) {
* result = str;
* result_len = len;
return MAIL_NO_ERROR;
}
r = mailmessage_fetch_body(get_ancestor(msg_info), result,
result_len);
if (r == MAIL_NO_ERROR)
generic_cache_store(filename, * result, * result_len);
return r;
}
static int imap_fetch_size(mailmessage * msg_info,
size_t * result)
{
return mailmessage_fetch_size(get_ancestor(msg_info), result);
}
static int imap_get_bodystructure(mailmessage * msg_info,
struct mailmime ** result)
{
int r;
if (msg_info->msg_mime != NULL) {
* result = msg_info->msg_mime;
return MAIL_NO_ERROR;
}
r = mailmessage_get_bodystructure(get_ancestor(msg_info),
result);
if (r == MAIL_NO_ERROR) {
msg_info->msg_mime = get_ancestor(msg_info)->msg_mime;
get_ancestor(msg_info)->msg_mime = NULL;
}
return r;
}
static int imap_fetch_section(mailmessage * msg_info,
struct mailmime * mime,
char ** result, size_t * result_len)
{
char key[PATH_MAX];
char filename[PATH_MAX];
int r;
char * str;
size_t len;
generate_key_from_section(key, PATH_MAX,
msg_info, mime, IMAP_SECTION_MESSAGE);
build_cache_name(filename, PATH_MAX, msg_info, key);
r = generic_cache_read(filename, &str, &len);
if (r == MAIL_NO_ERROR) {
* result = str;
* result_len = len;
return MAIL_NO_ERROR;
}
r = mailmessage_fetch_section(get_ancestor(msg_info),
mime, result, result_len);
if (r == MAIL_NO_ERROR)
generic_cache_store(filename, * result, * result_len);
return r;
}
static int imap_fetch_section_header(mailmessage * msg_info,
struct mailmime * mime,
char ** result,
size_t * result_len)
{
char key[PATH_MAX];
char filename[PATH_MAX];
int r;
char * str;
size_t len;
generate_key_from_section(key, PATH_MAX,
msg_info, mime, IMAP_SECTION_HEADER);
build_cache_name(filename, PATH_MAX, msg_info, key);
r = generic_cache_read(filename, &str, &len);
if (r == MAIL_NO_ERROR) {
* result = str;
* result_len = len;
return MAIL_NO_ERROR;
}
r = mailmessage_fetch_section_header(get_ancestor(msg_info),
mime, result, result_len);
if (r == MAIL_NO_ERROR)
generic_cache_store(filename, * result, * result_len);
return r;
}
static int imap_fetch_section_mime(mailmessage * msg_info,
struct mailmime * mime,
char ** result,
size_t * result_len)
{
char key[PATH_MAX];
char filename[PATH_MAX];
int r;
char * str;
size_t len;
generate_key_from_section(key, PATH_MAX,
msg_info, mime, IMAP_SECTION_MIME);
build_cache_name(filename, PATH_MAX, msg_info, key);
r = generic_cache_read(filename, &str, &len);
if (r == MAIL_NO_ERROR) {
* result = str;
* result_len = len;
return MAIL_NO_ERROR;
}
r = mailmessage_fetch_section_mime(get_ancestor(msg_info),
mime, result, result_len);
if (r == MAIL_NO_ERROR)
generic_cache_store(filename, * result, * result_len);
return r;
}
static int imap_fetch_section_body(mailmessage * msg_info,
struct mailmime * mime,
char ** result,
size_t * result_len)
{
char key[PATH_MAX];
char filename[PATH_MAX];
int r;
char * str;
size_t len;
generate_key_from_section(key, PATH_MAX,
msg_info, mime, IMAP_SECTION_BODY);
build_cache_name(filename, PATH_MAX, msg_info, key);
r = generic_cache_read(filename, &str, &len);
if (r == MAIL_NO_ERROR) {
* result = str;
* result_len = len;
return MAIL_NO_ERROR;
}
r = mailmessage_fetch_section_body(get_ancestor(msg_info),
mime, result, result_len);
if (r == MAIL_NO_ERROR)
generic_cache_store(filename, * result, * result_len);
return r;
}
static int imap_get_flags(mailmessage * msg_info,
struct mail_flags ** result)
{
int r;
struct mail_flags * flags;
if (msg_info->msg_flags != NULL) {
* result = msg_info->msg_flags;
return MAIL_NO_ERROR;
}
r = mailmessage_get_flags(get_ancestor(msg_info), &flags);
if (r != MAIL_NO_ERROR)
return r;
get_ancestor(msg_info)->msg_flags = NULL;
msg_info->msg_flags = flags;
* result = flags;
return MAIL_NO_ERROR;
}
#define ENV_NAME "env.db"
static int imap_fetch_envelope(mailmessage * msg_info,
struct mailimf_fields ** result)
{
struct mailimf_fields * fields;
int r;
struct mail_cache_db * cache_db;
MMAPString * mmapstr;
char filename[PATH_MAX];
struct imap_cached_session_state_data * data;
int res;
data = get_cached_session_data(msg_info);
if (data->imap_quoted_mb == NULL) {
res = MAIL_ERROR_BAD_STATE;
goto err;
}
snprintf(filename, PATH_MAX, "%s/%s", data->imap_quoted_mb, ENV_NAME);
r = mail_cache_db_open_lock(filename, &cache_db);
if (r < 0) {
res = MAIL_ERROR_MEMORY;
goto err;
}
mmapstr = mmap_string_new("");
if (mmapstr == NULL) {
res = MAIL_ERROR_MEMORY;
goto close_db;
}
r = imapdriver_get_cached_envelope(cache_db, mmapstr,
msg_info->msg_session, msg_info, &fields);
if ((r != MAIL_ERROR_CACHE_MISS) && (r != MAIL_NO_ERROR)) {
res = r;
goto close_db;
}
r = mailmessage_fetch_envelope(get_ancestor(msg_info), &fields);
if (r != MAIL_NO_ERROR) {
res = r;
goto close_db;
}
r = imapdriver_write_cached_envelope(cache_db, mmapstr,
msg_info->msg_session, msg_info, fields);
* result = fields;
mmap_string_free(mmapstr);
mail_cache_db_close_unlock(filename, cache_db);
return MAIL_NO_ERROR;
close_db:
mail_cache_db_close_unlock(filename, cache_db);
err:
return res;
}
@@ -0,0 +1,52 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: imapdriver_cached_message.h,v 1.6 2004/11/21 21:53:32 hoa Exp $
*/
#ifndef IMAPDRIVER_CACHED_MESSAGE_H
#define IMAPDRIVER_CACHED_MESSAGE_H
#include <libetpan/imapdriver_types.h>
#ifdef __cplusplus
extern "C" {
#endif
extern mailmessage_driver * imap_cached_message_driver;
#ifdef __cplusplus
}
#endif
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,52 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: imapdriver_message.h,v 1.6 2004/11/21 21:53:32 hoa Exp $
*/
#ifndef IMAPDRIVER_MESSAGE_H
#define IMAPDRIVER_MESSAGE_H
#include <libetpan/imapdriver_types.h>
#ifdef __cplusplus
extern "C" {
#endif
extern mailmessage_driver * imap_message_driver;
#ifdef __cplusplus
}
#endif
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,116 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: imapdriver_tools.h,v 1.8 2004/11/21 21:53:32 hoa Exp $
*/
#ifndef IMAPDRIVER_TOOLS_H
#define IMAPDRIVER_TOOLS_H
#include "mailimap.h"
#include "mailmime.h"
#include "imapdriver_types.h"
#include "mail_cache_db.h"
#ifdef __cplusplus
extern "C" {
#endif
int imap_list_to_list(clist * imap_list, struct mail_list ** result);
int
section_to_imap_section(struct mailmime_section * section, int type,
struct mailimap_section ** result);
int imap_get_msg_att_info(struct mailimap_msg_att * msg_att,
uint32_t * puid,
struct mailimap_envelope ** pimap_envelope,
char ** preferences,
size_t * pref_size,
struct mailimap_msg_att_dynamic ** patt_dyn,
struct mailimap_body ** pimap_body);
int imap_add_envelope_fetch_att(struct mailimap_fetch_type * fetch_type);
int imap_env_to_fields(struct mailimap_envelope * env,
char * ref_str, size_t ref_size,
struct mailimf_fields ** result);
int
imap_fetch_result_to_envelop_list(clist * fetch_result,
struct mailmessage_list * env_list);
int imap_body_to_body(struct mailimap_body * imap_body,
struct mailmime ** result);
#if 0
int mail_search_to_imap_search(struct mail_search_key * key,
struct mailimap_search_key ** result);
#endif
int msg_list_to_imap_set(clist * msg_list,
struct mailimap_set ** result);
int imap_error_to_mail_error(int error);
int imap_store_flags(mailimap * imap, uint32_t first, uint32_t last,
struct mail_flags * flags);
int imap_fetch_flags(mailimap * imap,
uint32_t index, struct mail_flags ** result);
int imap_get_messages_list(mailimap * imap,
mailsession * session, mailmessage_driver * driver,
uint32_t first_index,
struct mailmessage_list ** result);
int
imapdriver_get_cached_envelope(struct mail_cache_db * cache_db,
MMAPString * mmapstr,
mailsession * session, mailmessage * msg,
struct mailimf_fields ** result);
int
imapdriver_write_cached_envelope(struct mail_cache_db * cache_db,
MMAPString * mmapstr,
mailsession * session, mailmessage * msg,
struct mailimf_fields * fields);
int imap_flags_to_imap_flags(struct mail_flags * flags,
struct mailimap_flag_list ** result);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,157 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: imapdriver_types.h,v 1.25 2006/05/22 13:39:40 hoa Exp $
*/
#ifndef IMAPDRIVER_TYPES_H
#define IMAPDRIVER_TYPES_H
#include <libetpan/libetpan-config.h>
#include <libetpan/mailimap.h>
#include <libetpan/maildriver_types.h>
#include <libetpan/generic_cache_types.h>
#include <libetpan/mailstorage_types.h>
#ifdef __cplusplus
extern "C" {
#endif
/* IMAP driver for session */
struct imap_session_state_data {
mailimap * imap_session;
char * imap_mailbox;
struct mail_flags_store * imap_flags_store;
};
enum {
IMAP_SECTION_MESSAGE,
IMAP_SECTION_HEADER,
IMAP_SECTION_MIME,
IMAP_SECTION_BODY
};
/* cached IMAP driver for session */
enum {
IMAPDRIVER_CACHED_SET_CACHE_DIRECTORY = 1
};
struct imap_cached_session_state_data {
mailsession * imap_ancestor;
char * imap_quoted_mb;
char imap_cache_directory[PATH_MAX];
carray * imap_uid_list;
uint32_t imap_uidvalidity;
};
/* IMAP storage */
/*
imap_mailstorage is the state data specific to the IMAP4rev1 storage.
- servername this is the name of the IMAP4rev1 server
- port is the port to connect to, on the server.
you give 0 to use the default port.
- command, if non-NULL the command used to connect to the
server instead of allowing normal TCP connections to be used.
- connection_type is the type of socket layer to use.
The value can be CONNECTION_TYPE_PLAIN, CONNECTION_TYPE_STARTTLS,
CONNECTION_TYPE_TRY_STARTTLS, CONNECTION_TYPE_TLS or
CONNECTION_TYPE_COMMAND.
- auth_type is the authenticate mechanism to use.
The value can be IMAP_AUTH_TYPE_PLAIN.
Other values are not yet implemented.
- login is the login of the IMAP4rev1 account.
- password is the password of the IMAP4rev1 account.
- cached if this value is != 0, a persistant cache will be
stored on local system.
- cache_directory is the location of the cache
*/
struct imap_mailstorage {
char * imap_servername;
uint16_t imap_port;
char * imap_command;
int imap_connection_type;
int imap_auth_type;
char * imap_login; /* deprecated */
char * imap_password; /* deprecated */
int imap_cached;
char * imap_cache_directory;
struct {
int sasl_enabled;
char * sasl_auth_type;
char * sasl_server_fqdn;
char * sasl_local_ip_port;
char * sasl_remote_ip_port;
char * sasl_login;
char * sasl_auth_name;
char * sasl_password;
char * sasl_realm;
} imap_sasl;
};
/* this is the type of IMAP4rev1 authentication */
enum {
IMAP_AUTH_TYPE_PLAIN, /* plain text authentication */
IMAP_AUTH_TYPE_SASL_ANONYMOUS, /* SASL anonymous */
IMAP_AUTH_TYPE_SASL_CRAM_MD5, /* SASL CRAM MD5 */
IMAP_AUTH_TYPE_SASL_KERBEROS_V4, /* SASL KERBEROS V4 */
IMAP_AUTH_TYPE_SASL_PLAIN, /* SASL plain */
IMAP_AUTH_TYPE_SASL_SCRAM_MD5, /* SASL SCRAM MD5 */
IMAP_AUTH_TYPE_SASL_GSSAPI, /* SASL GSSAPI */
IMAP_AUTH_TYPE_SASL_DIGEST_MD5 /* SASL digest MD5 */
};
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,427 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: imapstorage.c,v 1.17 2006/06/26 11:50:26 hoa Exp $
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "imapstorage.h"
#include <stdlib.h>
#include <string.h>
#include "mail.h"
#include "imapdriver.h"
#include "imapdriver_cached.h"
#include "mailstorage_tools.h"
#include "maildriver.h"
/* imap storage */
#define IMAP_DEFAULT_PORT 143
#define IMAPS_DEFAULT_PORT 993
static int imap_mailstorage_connect(struct mailstorage * storage);
static int
imap_mailstorage_get_folder_session(struct mailstorage * storage,
char * pathname, mailsession ** result);
static void imap_mailstorage_uninitialize(struct mailstorage * storage);
static mailstorage_driver imap_mailstorage_driver = {
#if ! defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
/* sto_name */ "imap",
/* sto_connect */ imap_mailstorage_connect,
/* sto_get_folder_session */ imap_mailstorage_get_folder_session,
/* sto_uninitialize */ imap_mailstorage_uninitialize,
#else
.sto_name = "imap",
.sto_connect = imap_mailstorage_connect,
.sto_get_folder_session = imap_mailstorage_get_folder_session,
.sto_uninitialize = imap_mailstorage_uninitialize,
#endif
};
LIBETPAN_EXPORT
int imap_mailstorage_init(struct mailstorage * storage,
const char * imap_servername, uint16_t imap_port,
const char * imap_command,
int imap_connection_type, int imap_auth_type,
const char * imap_login, const char * imap_password,
int imap_cached, const char * imap_cache_directory)
{
struct imap_mailstorage * imap_storage;
int r;
r = imap_mailstorage_init_sasl(storage,
imap_servername, imap_port,
imap_command,
imap_connection_type,
NULL,
NULL,
NULL, NULL,
imap_login, imap_login,
imap_password, NULL,
imap_cached, imap_cache_directory);
if (r == MAIL_NO_ERROR) {
imap_storage = storage->sto_data;
imap_storage->imap_auth_type = imap_auth_type;
imap_storage->imap_login = imap_storage->imap_sasl.sasl_login;
imap_storage->imap_password = imap_storage->imap_sasl.sasl_password;
}
return r;
}
LIBETPAN_EXPORT
int imap_mailstorage_init_sasl(struct mailstorage * storage,
const char * imap_servername, uint16_t imap_port,
const char * imap_command,
int imap_connection_type,
const char * auth_type,
const char * server_fqdn,
const char * local_ip_port,
const char * remote_ip_port,
const char * login, const char * auth_name,
const char * password, const char * realm,
int imap_cached, const char * imap_cache_directory)
{
struct imap_mailstorage * imap_storage;
imap_storage = malloc(sizeof(* imap_storage));
if (imap_storage == NULL)
goto err;
imap_storage->imap_servername = strdup(imap_servername);
if (imap_storage->imap_servername == NULL)
goto free;
imap_storage->imap_connection_type = imap_connection_type;
if (imap_port == 0) {
switch (imap_connection_type) {
case CONNECTION_TYPE_PLAIN:
case CONNECTION_TYPE_TRY_STARTTLS:
case CONNECTION_TYPE_STARTTLS:
case CONNECTION_TYPE_COMMAND:
case CONNECTION_TYPE_COMMAND_TRY_STARTTLS:
case CONNECTION_TYPE_COMMAND_STARTTLS:
imap_port = IMAP_DEFAULT_PORT;
break;
case CONNECTION_TYPE_TLS:
case CONNECTION_TYPE_COMMAND_TLS:
imap_port = IMAPS_DEFAULT_PORT;
break;
}
}
imap_storage->imap_port = imap_port;
if (imap_command != NULL) {
imap_storage->imap_command = strdup(imap_command);
if (imap_storage->imap_command == NULL)
goto free_servername;
}
else
imap_storage->imap_command = NULL;
imap_storage->imap_auth_type = IMAP_AUTH_TYPE_PLAIN;
imap_storage->imap_sasl.sasl_enabled = (auth_type != NULL);
if (auth_type != NULL) {
imap_storage->imap_sasl.sasl_auth_type = strdup(auth_type);
if (imap_storage->imap_sasl.sasl_auth_type == NULL)
goto free_command;
}
else
imap_storage->imap_sasl.sasl_auth_type = NULL;
if (server_fqdn != NULL) {
imap_storage->imap_sasl.sasl_server_fqdn = strdup(server_fqdn);
if (imap_storage->imap_sasl.sasl_server_fqdn == NULL)
goto free_auth_type;
}
else
imap_storage->imap_sasl.sasl_server_fqdn = NULL;
if (local_ip_port != NULL) {
imap_storage->imap_sasl.sasl_local_ip_port = strdup(local_ip_port);
if (imap_storage->imap_sasl.sasl_local_ip_port == NULL)
goto free_server_fqdn;
}
else
imap_storage->imap_sasl.sasl_local_ip_port = NULL;
if (remote_ip_port != NULL) {
imap_storage->imap_sasl.sasl_remote_ip_port = strdup(remote_ip_port);
if (imap_storage->imap_sasl.sasl_remote_ip_port == NULL)
goto free_local_ip_port;
}
else
imap_storage->imap_sasl.sasl_remote_ip_port = NULL;
if (login != NULL) {
imap_storage->imap_sasl.sasl_login = strdup(login);
if (imap_storage->imap_sasl.sasl_login == NULL)
goto free_remote_ip_port;
}
else
imap_storage->imap_sasl.sasl_login = NULL;
if (auth_name != NULL) {
imap_storage->imap_sasl.sasl_auth_name = strdup(auth_name);
if (imap_storage->imap_sasl.sasl_auth_name == NULL)
goto free_login;
}
else
imap_storage->imap_sasl.sasl_auth_name = NULL;
if (password != NULL) {
imap_storage->imap_sasl.sasl_password = strdup(password);
if (imap_storage->imap_sasl.sasl_password == NULL)
goto free_auth_name;
}
else
imap_storage->imap_sasl.sasl_password = NULL;
if (realm != NULL) {
imap_storage->imap_sasl.sasl_realm = strdup(realm);
if (imap_storage->imap_sasl.sasl_realm == NULL)
goto free_password;
}
else
imap_storage->imap_sasl.sasl_realm = NULL;
imap_storage->imap_cached = imap_cached;
if (imap_cached && (imap_cache_directory != NULL)) {
imap_storage->imap_cache_directory = strdup(imap_cache_directory);
if (imap_storage->imap_cache_directory == NULL)
goto free_realm;
}
else {
imap_storage->imap_cached = FALSE;
imap_storage->imap_cache_directory = NULL;
}
storage->sto_data = imap_storage;
storage->sto_driver = &imap_mailstorage_driver;
return MAIL_NO_ERROR;
free_realm:
free(imap_storage->imap_sasl.sasl_realm);
free_password:
free(imap_storage->imap_sasl.sasl_password);
free_auth_name:
free(imap_storage->imap_sasl.sasl_auth_name);
free_login:
free(imap_storage->imap_sasl.sasl_login);
free_remote_ip_port:
free(imap_storage->imap_sasl.sasl_remote_ip_port);
free_local_ip_port:
free(imap_storage->imap_sasl.sasl_local_ip_port);
free_server_fqdn:
free(imap_storage->imap_sasl.sasl_server_fqdn);
free_auth_type:
free(imap_storage->imap_sasl.sasl_auth_type);
free_command:
free(imap_storage->imap_command);
free_servername:
free(imap_storage->imap_servername);
free:
free(imap_storage);
err:
return MAIL_ERROR_MEMORY;
}
static void imap_mailstorage_uninitialize(struct mailstorage * storage)
{
struct imap_mailstorage * imap_storage;
imap_storage = storage->sto_data;
if (imap_storage->imap_cache_directory != NULL)
free(imap_storage->imap_cache_directory);
free(imap_storage->imap_sasl.sasl_realm);
free(imap_storage->imap_sasl.sasl_password);
free(imap_storage->imap_sasl.sasl_auth_name);
free(imap_storage->imap_sasl.sasl_login);
free(imap_storage->imap_sasl.sasl_remote_ip_port);
free(imap_storage->imap_sasl.sasl_local_ip_port);
free(imap_storage->imap_sasl.sasl_server_fqdn);
free(imap_storage->imap_sasl.sasl_auth_type);
if (imap_storage->imap_command != NULL)
free(imap_storage->imap_command);
free(imap_storage->imap_servername);
free(imap_storage);
storage->sto_data = NULL;
}
static int imap_connect(struct mailstorage * storage,
mailsession ** result)
{
struct imap_mailstorage * imap_storage;
mailsession_driver * driver;
int r;
int res;
mailsession * session;
imap_storage = storage->sto_data;
if (imap_storage->imap_cached)
driver = imap_cached_session_driver;
else
driver = imap_session_driver;
r = mailstorage_generic_connect(driver,
imap_storage->imap_servername,
imap_storage->imap_port,
imap_storage->imap_command,
imap_storage->imap_connection_type,
IMAPDRIVER_CACHED_SET_CACHE_DIRECTORY,
imap_storage->imap_cache_directory,
0, NULL,
&session);
switch (r) {
case MAIL_NO_ERROR_NON_AUTHENTICATED:
case MAIL_NO_ERROR_AUTHENTICATED:
case MAIL_NO_ERROR:
break;
default:
res = r;
goto err;
}
if (imap_storage->imap_sasl.sasl_enabled) {
r = mailstorage_generic_auth_sasl(session, r,
imap_storage->imap_sasl.sasl_auth_type,
imap_storage->imap_sasl.sasl_server_fqdn,
imap_storage->imap_sasl.sasl_local_ip_port,
imap_storage->imap_sasl.sasl_remote_ip_port,
imap_storage->imap_sasl.sasl_login,
imap_storage->imap_sasl.sasl_auth_name,
imap_storage->imap_sasl.sasl_password,
imap_storage->imap_sasl.sasl_realm);
}
else {
r = mailstorage_generic_auth(session, r,
imap_storage->imap_auth_type,
imap_storage->imap_sasl.sasl_login,
imap_storage->imap_sasl.sasl_password);
}
if (r != MAIL_NO_ERROR) {
res = r;
goto free;
}
* result = session;
return MAIL_NO_ERROR;
free:
mailsession_free(session);
err:
return res;
}
static int imap_mailstorage_connect(struct mailstorage * storage)
{
mailsession * session;
int r;
int res;
r = imap_connect(storage, &session);
if (r != MAIL_NO_ERROR) {
res = r;
goto err;
}
r = mailsession_select_folder(session, "INBOX");
if (r != MAIL_NO_ERROR) {
mailsession_logout(session);
res = r;
goto err;
}
storage->sto_session = session;
storage->sto_driver = &imap_mailstorage_driver;
return MAIL_NO_ERROR;
err:
return res;
}
static int
imap_mailstorage_get_folder_session(struct mailstorage * storage,
char * pathname, mailsession ** result)
{
mailsession * session;
int r;
int res;
if (strcasecmp(pathname, "INBOX") == 0) {
session = storage->sto_session;
}
else {
r = imap_connect(storage, &session);
if (r != MAIL_NO_ERROR) {
res = r;
goto err;
}
r = mailsession_select_folder(session, pathname);
if (r != MAIL_NO_ERROR) {
mailsession_logout(session);
res = r;
goto free;
}
}
* result = session;
return MAIL_NO_ERROR;
free:
mailsession_free(session);
err:
return res;
}
@@ -0,0 +1,104 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: imapstorage.h,v 1.12 2006/06/02 15:44:29 smarinier Exp $
*/
#ifndef IMAPSTORAGE_H
#define IMAPSTORAGE_H
#ifdef __cplusplus
extern "C" {
#endif
#include <libetpan/imapdriver_types.h>
/*
imap_mailstorage_init is the constructor for a IMAP4rev1 storage
@param storage this is the storage to initialize.
@param servername this is the name of the IMAP4rev1 server
@param port is the port to connect to, on the server.
you give 0 to use the default port.
@param command the command used to connect to the server instead of
allowing normal TCP connections to be used.
@param connection_type is the type of socket layer to use.
The value can be CONNECTION_TYPE_PLAIN, CONNECTION_TYPE_STARTTLS,
CONNECTION_TYPE_TRY_STARTTLS, CONNECTION_TYPE_TLS,
CONNECTION_TYPE_COMMAND, CONNECTION_TYPE_COMMAND_STARTTLS,
CONNECTION_TYPE_COMMAND_TRY_STARTTLS, CONNECTION_TYPE_COMMAND_TLS,.
@param auth_type is the authenticate mechanism to use.
The value can be IMAP_AUTH_TYPE_PLAIN.
Other values are not yet implemented.
@param login is the login of the IMAP4rev1 account.
@param password is the password of the IMAP4rev1 account.
@param cached if this value is != 0, a persistant cache will be
stored on local system.
@param cache_directory is the location of the cache
*/
LIBETPAN_EXPORT
int imap_mailstorage_init(struct mailstorage * storage,
const char * imap_servername, uint16_t imap_port,
const char * imap_command,
int imap_connection_type, int imap_auth_type,
const char * imap_login, const char * imap_password,
int imap_cached, const char * imap_cache_directory);
LIBETPAN_EXPORT
int imap_mailstorage_init_sasl(struct mailstorage * storage,
const char * imap_servername, uint16_t imap_port,
const char * imap_command,
int imap_connection_type,
const char * auth_type,
const char * server_fqdn,
const char * local_ip_port,
const char * remote_ip_port,
const char * login, const char * auth_name,
const char * password, const char * realm,
int imap_cached, const char * imap_cache_directory);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,3 @@
.libs
*.la
*.lo
@@ -0,0 +1,30 @@
top_builddir = ../../../..
HEADERS = \
maildirdriver.h \
maildirdriver_cached.h \
maildirdriver_cached_message.h \
maildirdriver_message.h \
maildirdriver_types.h \
maildirstorage.h
SOURCES = \
maildirdriver.c \
maildirdriver_cached.c \
maildirdriver_cached_message.c \
maildirdriver_message.c \
maildirdriver_tools.c \
maildirstorage.c
TARGET = libmaildir
INCLUDES = -I../../interface \
-I../../tools \
-I$(srcdir)/low-level/maildir \
-I$(srcdir)/low-level/mime \
-I$(srcdir)/low-level/imf \
-I$(srcdir)/data-types
include $(top_builddir)/Rules
@@ -0,0 +1,738 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: maildirdriver.c,v 1.15 2006/06/28 06:13:47 skunk Exp $
*/
/*
flags directory MUST be kept so that we can have other flags
than standards
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "maildirdriver.h"
#include <stdio.h>
#include <sys/types.h>
#ifdef _MSC_VER
# include "win_etpan.h"
#else
# include <dirent.h>
# include <unistd.h>
# include <sys/mman.h>
#endif
#include <sys/stat.h>
#include <ctype.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include "maildir.h"
#include "maildriver_tools.h"
#include "maildirdriver_message.h"
#include "maildirdriver_tools.h"
#include "mailmessage.h"
#include "generic_cache.h"
static int initialize(mailsession * session);
static void uninitialize(mailsession * session);
static int connect_path(mailsession * session, const char * path);
static int logout(mailsession * session);
static int expunge_folder(mailsession * session);
static int status_folder(mailsession * session, const char * mb,
uint32_t * result_messages, uint32_t * result_recent,
uint32_t * result_unseen);
static int recent_number(mailsession * session, const char * mb,
uint32_t * result);
static int unseen_number(mailsession * session, const char * mb,
uint32_t * result);
static int messages_number(mailsession * session, const char * mb,
uint32_t * result);
static int append_message(mailsession * session,
const char * message, size_t size);
static int append_message_flags(mailsession * session,
const char * message, size_t size, struct mail_flags * flags);
static int get_messages_list(mailsession * session,
struct mailmessage_list ** result);
static int get_envelopes_list(mailsession * session,
struct mailmessage_list * env_list);
static int check_folder(mailsession * session);
static int get_message_by_uid(mailsession * session,
const char * uid, mailmessage ** result);
static mailsession_driver local_maildir_session_driver = {
#if ! defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
/* sess_name */ "maildir",
/* sess_initialize */ initialize,
/* sess_uninitialize */ uninitialize,
/* sess_parameters */ NULL,
/* sess_connect_stream */ NULL,
/* sess_connect_path */ connect_path,
/* sess_starttls */ NULL,
/* sess_login */ NULL,
/* sess_logout */ logout,
/* sess_noop */ NULL,
/* sess_build_folder_name */ NULL,
/* sess_create_folder */ NULL,
/* sess_delete_folder */ NULL,
/* sess_rename_folder */ NULL,
/* sess_check_folder */ check_folder,
/* sess_examine_folder */ NULL,
/* sess_select_folder */ NULL,
/* sess_expunge_folder */ expunge_folder,
/* sess_status_folder */ status_folder,
/* sess_messages_number */ messages_number,
/* sess_recent_number */ recent_number,
/* sess_unseen_number */ unseen_number,
/* sess_list_folders */ NULL,
/* sess_lsub_folders */ NULL,
/* sess_subscribe_folder */ NULL,
/* sess_unsubscribe_folder */ NULL,
/* sess_append_message */ append_message,
/* sess_append_message_flags */ append_message_flags,
/* sess_copy_message */ NULL,
/* sess_move_message */ NULL,
/* sess_get_message */ NULL,
/* sess_get_message_by_uid */ get_message_by_uid,
/* sess_get_messages_list */ get_messages_list,
/* sess_get_envelopes_list */ get_envelopes_list,
/* sess_remove_message */ NULL,
#if 0
/* sess_search_messages */ maildriver_generic_search_messages,
#endif
/* sess_login_sasl */ NULL,
#else
.sess_name = "maildir",
.sess_initialize = initialize,
.sess_uninitialize = uninitialize,
.sess_parameters = NULL,
.sess_connect_stream = NULL,
.sess_connect_path = connect_path,
.sess_starttls = NULL,
.sess_login = NULL,
.sess_logout = logout,
.sess_noop = NULL,
.sess_build_folder_name = NULL,
.sess_create_folder = NULL,
.sess_delete_folder = NULL,
.sess_rename_folder = NULL,
.sess_check_folder = check_folder,
.sess_examine_folder = NULL,
.sess_select_folder = NULL,
.sess_expunge_folder = expunge_folder,
.sess_status_folder = status_folder,
.sess_messages_number = messages_number,
.sess_recent_number = recent_number,
.sess_unseen_number = unseen_number,
.sess_list_folders = NULL,
.sess_lsub_folders = NULL,
.sess_subscribe_folder = NULL,
.sess_unsubscribe_folder = NULL,
.sess_append_message = append_message,
.sess_append_message_flags = append_message_flags,
.sess_copy_message = NULL,
.sess_move_message = NULL,
.sess_get_messages_list = get_messages_list,
.sess_get_envelopes_list = get_envelopes_list,
.sess_remove_message = NULL,
#if 0
.sess_search_messages = maildriver_generic_search_messages,
#endif
.sess_get_message = NULL,
.sess_get_message_by_uid = get_message_by_uid,
.sess_login_sasl = NULL,
#endif
};
mailsession_driver * maildir_session_driver = &local_maildir_session_driver;
static int flags_store_process(struct maildir * md,
struct mail_flags_store * flags_store);
static inline struct maildir_session_state_data * get_data(mailsession * session)
{
return session->sess_data;
}
static struct maildir * get_maildir_session(mailsession * session)
{
return get_data(session)->md_session;
}
static int initialize(mailsession * session)
{
struct maildir_session_state_data * data;
data = malloc(sizeof(* data));
if (data == NULL)
goto err;
data->md_session = NULL;
data->md_flags_store = mail_flags_store_new();
if (data->md_flags_store == NULL)
goto free;
session->sess_data = data;
return MAIL_NO_ERROR;
free:
free(data);
err:
return MAIL_ERROR_MEMORY;
}
static void uninitialize(mailsession * session)
{
struct maildir_session_state_data * data;
data = get_data(session);
if (data->md_session != NULL)
flags_store_process(data->md_session, data->md_flags_store);
mail_flags_store_free(data->md_flags_store);
if (data->md_session != NULL)
maildir_free(data->md_session);
free(data);
session->sess_data = NULL;
}
static int connect_path(mailsession * session, const char * path)
{
struct maildir * md;
int res;
int r;
if (get_maildir_session(session) != NULL) {
res = MAIL_ERROR_BAD_STATE;
goto err;
}
md = maildir_new(path);
if (md == NULL) {
res = MAIL_ERROR_MEMORY;
goto err;
}
r = maildir_update(md);
if (r != MAILDIR_NO_ERROR) {
res = maildirdriver_maildir_error_to_mail_error(r);
goto free;
}
get_data(session)->md_session = md;
return MAIL_NO_ERROR;
free:
maildir_free(md);
err:
return res;
}
static int logout(mailsession * session)
{
struct maildir * md;
check_folder(session);
md = get_maildir_session(session);
if (md == NULL)
return MAIL_ERROR_BAD_STATE;
maildir_free(md);
get_data(session)->md_session = NULL;
return MAIL_NO_ERROR;
}
/* folders operations */
static int status_folder(mailsession * session, const char * mb,
uint32_t * result_messages, uint32_t * result_recent,
uint32_t * result_unseen)
{
int r;
struct maildir * md;
unsigned int i;
uint32_t messages;
uint32_t recent;
uint32_t unseen;
check_folder(session);
md = get_maildir_session(session);
if (md == NULL)
return MAIL_ERROR_BAD_STATE;
r = maildir_update(md);
if (r != MAILDIR_NO_ERROR)
return maildirdriver_maildir_error_to_mail_error(r);
messages = 0;
recent = 0;
unseen = 0;
for(i = 0 ; i < carray_count(md->mdir_msg_list) ; i ++) {
struct maildir_msg * msg;
msg = carray_get(md->mdir_msg_list, i);
if ((msg->msg_flags & MAILDIR_FLAG_NEW) != 0)
recent ++;
if ((msg->msg_flags & MAILDIR_FLAG_SEEN) == 0)
unseen ++;
messages ++;
}
* result_messages = messages;
* result_recent = recent;
* result_unseen = unseen;
return MAIL_NO_ERROR;
}
static int messages_number(mailsession * session, const char * mb,
uint32_t * result)
{
struct maildir * md;
int r;
md = get_maildir_session(session);
if (md == NULL)
return MAIL_ERROR_BAD_STATE;
r = maildir_update(md);
if (r != MAILDIR_NO_ERROR)
return maildirdriver_maildir_error_to_mail_error(r);
* result = carray_count(md->mdir_msg_list);
return MAIL_NO_ERROR;
}
static int unseen_number(mailsession * session, const char * mb,
uint32_t * result)
{
uint32_t messages;
uint32_t recent;
uint32_t unseen;
int r;
r = status_folder(session, mb, &messages, &recent, &unseen);
if (r != MAIL_NO_ERROR)
return r;
* result = unseen;
return MAIL_NO_ERROR;
}
static int recent_number(mailsession * session, const char * mb,
uint32_t * result)
{
uint32_t messages;
uint32_t recent;
uint32_t unseen;
int r;
r = status_folder(session, mb, &messages, &recent, &unseen);
if (r != MAIL_NO_ERROR)
return r;
* result = recent;
return MAIL_NO_ERROR;
}
/* messages operations */
static int append_message(mailsession * session,
const char * message, size_t size)
{
#if 0
struct maildir * md;
int r;
md = get_maildir_session(session);
if (md == NULL)
return MAIL_ERROR_BAD_STATE;
r = maildir_message_add(md, message, size);
if (r != MAILDIR_NO_ERROR)
return maildirdriver_maildir_error_to_mail_error(r);
return MAIL_NO_ERROR;
#endif
return append_message_flags(session, message, size, NULL);
}
static int append_message_flags(mailsession * session,
const char * message, size_t size, struct mail_flags * flags)
{
struct maildir * md;
int r;
char uid[PATH_MAX];
struct maildir_msg * md_msg;
chashdatum key;
chashdatum value;
uint32_t md_flags;
md = get_maildir_session(session);
if (md == NULL)
return MAIL_ERROR_BAD_STATE;
r = maildir_message_add_uid(md, message, size,
uid, sizeof(uid));
if (r != MAILDIR_NO_ERROR)
return maildirdriver_maildir_error_to_mail_error(r);
if (flags == NULL)
goto exit;
key.data = uid;
key.len = strlen(uid);
r = chash_get(md->mdir_msg_hash, &key, &value);
if (r < 0)
goto exit;
md_msg = value.data;
md_flags = maildirdriver_flags_to_maildir_flags(flags->fl_flags);
r = maildir_message_change_flags(md, uid, md_flags);
if (r != MAILDIR_NO_ERROR)
goto exit;
return MAIL_NO_ERROR;
exit:
return MAIL_NO_ERROR;
}
static int get_messages_list(mailsession * session,
struct mailmessage_list ** result)
{
struct maildir * md;
int r;
struct mailmessage_list * env_list;
int res;
md = get_maildir_session(session);
if (md == NULL)
return MAIL_ERROR_BAD_STATE;
r = maildir_update(md);
if (r != MAILDIR_NO_ERROR) {
res = maildirdriver_maildir_error_to_mail_error(r);
goto err;
}
r = maildir_get_messages_list(session, md,
maildir_message_driver, &env_list);
if (r != MAILDIR_NO_ERROR) {
res = r;
goto free_list;
}
* result = env_list;
return MAIL_NO_ERROR;
free_list:
mailmessage_list_free(env_list);
err:
return res;
}
static int get_envelopes_list(mailsession * session,
struct mailmessage_list * env_list)
{
int r;
struct maildir * md;
unsigned int i;
int res;
check_folder(session);
md = get_maildir_session(session);
if (md == NULL) {
res = MAIL_ERROR_BAD_STATE;
goto err;
}
r = maildir_update(md);
if (r != MAILDIR_NO_ERROR) {
res = maildirdriver_maildir_error_to_mail_error(r);
goto err;
}
r = maildriver_generic_get_envelopes_list(session, env_list);
if (r != MAIL_NO_ERROR) {
res = r;
goto err;
}
for(i = 0 ; i < carray_count(env_list->msg_tab) ; i++) {
struct maildir_msg * md_msg;
mailmessage * msg;
uint32_t driver_flags;
clist * ext;
chashdatum key;
chashdatum value;
msg = carray_get(env_list->msg_tab, i);
key.data = msg->msg_uid;
key.len = strlen(msg->msg_uid);
r = chash_get(md->mdir_msg_hash, &key, &value);
if (r < 0)
continue;
md_msg = value.data;
driver_flags = maildirdriver_maildir_flags_to_flags(md_msg->msg_flags);
if (msg->msg_flags == NULL) {
ext = clist_new();
if (ext == NULL) {
res = MAIL_ERROR_MEMORY;
continue;
}
msg->msg_flags = mail_flags_new(driver_flags, ext);
if (msg->msg_flags == NULL) {
clist_free(ext);
res = MAIL_ERROR_MEMORY;
continue;
}
if ((md_msg->msg_flags & MAILDIR_FLAG_NEW) != 0) {
mail_flags_store_set(get_data(session)->md_flags_store, msg);
}
}
else {
msg->msg_flags->fl_flags &= MAIL_FLAG_FORWARDED;
msg->msg_flags->fl_flags |= driver_flags;
}
}
return MAIL_NO_ERROR;
err:
return res;
}
static int expunge_folder(mailsession * session)
{
unsigned int i;
int r;
int res;
struct maildir * md;
check_folder(session);
md = get_maildir_session(session);
if (md == NULL)
return MAIL_ERROR_BAD_STATE;
r = maildir_update(md);
if (r != MAILDIR_NO_ERROR) {
res = maildirdriver_maildir_error_to_mail_error(r);
goto err;
}
for(i = 0 ; i < carray_count(md->mdir_msg_list) ; i++) {
struct maildir_msg * md_msg;
md_msg = carray_get(md->mdir_msg_list, i);
if ((md_msg->msg_flags & MAILDIR_FLAG_TRASHED) != 0)
maildir_message_remove(md, md_msg->msg_uid);
}
return MAIL_NO_ERROR;
err:
return res;
}
static int flags_store_process(struct maildir * md,
struct mail_flags_store * flags_store)
{
unsigned int i;
if (carray_count(flags_store->fls_tab) == 0)
return MAIL_NO_ERROR;
for(i = 0 ; i < carray_count(flags_store->fls_tab) ; i ++) {
mailmessage * msg;
uint32_t md_flags;
msg = carray_get(flags_store->fls_tab, i);
md_flags = maildirdriver_flags_to_maildir_flags(msg->msg_flags->fl_flags);
md_flags &= ~MAILDIR_FLAG_NEW;
maildir_message_change_flags(md, msg->msg_uid, md_flags);
}
mail_flags_store_clear(flags_store);
return MAIL_NO_ERROR;
}
static int check_folder(mailsession * session)
{
struct mail_flags_store * flags_store;
struct maildir_session_state_data * data;
struct maildir * md;
md = get_maildir_session(session);
if (md == NULL)
return MAIL_ERROR_BAD_STATE;
data = get_data(session);
flags_store = data->md_flags_store;
return flags_store_process(md, flags_store);
}
static int get_message_by_uid(mailsession * session,
const char * uid, mailmessage ** result)
{
int r;
struct maildir * md;
int res;
mailmessage * msg;
char * msg_filename;
struct stat stat_info;
md = get_maildir_session(session);
/* update maildir data */
r = maildir_update(md);
if (r != MAILDIR_NO_ERROR) {
res = maildirdriver_maildir_error_to_mail_error(r);
goto err;
}
msg_filename = maildir_message_get(md, uid);
if (msg_filename == NULL) {
res = MAIL_ERROR_INVAL;
goto err;
}
r = stat(msg_filename, &stat_info);
free(msg_filename);
if (r < 0) {
res = MAIL_ERROR_INVAL;
goto err;
}
/* create message */
msg = mailmessage_new();
if (msg == NULL) {
res = MAIL_ERROR_MEMORY;
goto err;
}
r = mailmessage_init(msg, session, maildir_message_driver,
0, stat_info.st_size);
if (r != MAIL_NO_ERROR) {
mailmessage_free(msg);
res = r;
goto err;
}
msg->msg_uid = strdup(uid);
if (msg->msg_uid == NULL) {
mailmessage_free(msg);
res = r;
goto err;
}
* result = msg;
return MAIL_NO_ERROR;
err:
return res;
}
@@ -0,0 +1,53 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: maildirdriver.h,v 1.4 2004/11/21 21:53:32 hoa Exp $
*/
#ifndef MAILDIRDRIVER_H
#define MAILDIRDRIVER_H
#include <libetpan/maildriver.h>
#include <libetpan/maildirdriver_types.h>
#ifdef __cplusplus
extern "C" {
#endif
extern mailsession_driver * maildir_session_driver;
#ifdef __cplusplus
}
#endif
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,53 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: maildirdriver_cached.h,v 1.4 2004/11/21 21:53:32 hoa Exp $
*/
#ifndef MAILDIRDRIVER_CACHED_H
#define MAILDIRDRIVER_CACHED_H
#include <libetpan/maildriver.h>
#include <libetpan/maildirdriver_types.h>
#ifdef __cplusplus
extern "C" {
#endif
extern mailsession_driver * maildir_cached_session_driver;
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,370 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: maildirdriver_cached_message.c,v 1.9 2006/06/26 11:50:26 hoa Exp $
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "maildirdriver_message.h"
#include "mailmessage_tools.h"
#include "maildirdriver.h"
#include "maildir.h"
#include "generic_cache.h"
#include "mail_cache_db.h"
#include "maildirdriver_tools.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_SYS_MMAN_H
# include <sys/mman.h>
#endif
#ifdef _MSC_VER
# include "win_etpan.h"
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
static int get_flags(mailmessage * msg_info,
struct mail_flags ** result);
static int prefetch(mailmessage * msg_info);
static void prefetch_free(struct generic_message_t * msg);
static int initialize(mailmessage * msg_info);
static void check(mailmessage * msg_info);
static mailmessage_driver local_maildir_cached_message_driver = {
#if ! defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
/* msg_name */ "maildir-cached",
/* msg_initialize */ initialize,
/* msg_uninitialize */ mailmessage_generic_uninitialize,
/* msg_flush */ mailmessage_generic_flush,
/* msg_check */ check,
/* msg_fetch_result_free */ mailmessage_generic_fetch_result_free,
/* msg_fetch */ mailmessage_generic_fetch,
/* msg_fetch_header */ mailmessage_generic_fetch_header,
/* msg_fetch_body */ mailmessage_generic_fetch_header,
/* msg_fetch_size */ NULL,
/* msg_get_bodystructure */ mailmessage_generic_get_bodystructure,
/* msg_fetch_section */ mailmessage_generic_fetch_section,
/* msg_fetch_section_header */ mailmessage_generic_fetch_section_header,
/* msg_fetch_section_mime */ mailmessage_generic_fetch_section_mime,
/* msg_fetch_section_body */ mailmessage_generic_fetch_section_body,
/* msg_fetch_envelope */ mailmessage_generic_fetch_envelope,
/* msg_get_flags */ get_flags,
#else
.msg_name = "maildir-cached",
.msg_initialize = initialize,
.msg_uninitialize = mailmessage_generic_uninitialize,
.msg_flush = mailmessage_generic_flush,
.msg_check = check,
.msg_fetch_result_free = mailmessage_generic_fetch_result_free,
.msg_fetch = mailmessage_generic_fetch,
.msg_fetch_header = mailmessage_generic_fetch_header,
.msg_fetch_body = mailmessage_generic_fetch_header,
.msg_fetch_size = NULL,
.msg_get_bodystructure = mailmessage_generic_get_bodystructure,
.msg_fetch_section = mailmessage_generic_fetch_section,
.msg_fetch_section_header = mailmessage_generic_fetch_section_header,
.msg_fetch_section_mime = mailmessage_generic_fetch_section_mime,
.msg_fetch_section_body = mailmessage_generic_fetch_section_body,
.msg_fetch_envelope = mailmessage_generic_fetch_envelope,
.msg_get_flags = get_flags,
#endif
};
mailmessage_driver * maildir_cached_message_driver =
&local_maildir_cached_message_driver;
struct maildir_msg_data {
int fd;
};
#if 0
static inline struct maildir_cached_session_state_data *
get_cached_session_data(mailmessage * msg)
{
return msg->session->data;
}
static inline mailsession * cached_session_get_ancestor(mailsession * session)
{
return get_data(session)->session;
}
static inline struct maildir_session_state_data *
cached_session_get_ancestor_data(mailsession * session)
{
return get_ancestor(session)->data;
}
static struct maildir * get_maildir_session(mailmessage * msg)
{
return cached_session_get_ancestor_data(msg->session)->session;
}
#endif
static inline struct maildir_cached_session_state_data *
get_cached_session_data(mailmessage * msg)
{
return msg->msg_session->sess_data;
}
static inline struct maildir_cached_session_state_data *
cached_session_get_data(mailsession * s)
{
return s->sess_data;
}
static inline mailsession * cached_session_get_ancestor(mailsession * s)
{
return cached_session_get_data(s)->md_ancestor;
}
static inline struct maildir_session_state_data *
cached_session_get_ancestor_data(mailsession * s)
{
return cached_session_get_ancestor(s)->sess_data;
}
static inline struct maildir_session_state_data *
get_session_ancestor_data(mailmessage * msg)
{
return cached_session_get_ancestor_data(msg->msg_session);
}
static inline struct maildir *
cached_session_get_maildir_session(mailsession * session)
{
return cached_session_get_ancestor_data(session)->md_session;
}
static inline struct maildir * get_maildir_session(mailmessage * msg)
{
return cached_session_get_maildir_session(msg->msg_session);
}
static int prefetch(mailmessage * msg_info)
{
struct generic_message_t * msg;
int res;
struct maildir_msg_data * data;
char * filename;
int fd;
char * mapping;
struct maildir * md;
md = get_maildir_session(msg_info);
filename = maildir_message_get(md, msg_info->msg_uid);
if (filename == NULL) {
res = MAIL_ERROR_MEMORY;
goto err;
}
fd = open(filename, O_RDONLY);
free(filename);
if (fd == -1) {
res = MAIL_ERROR_FILE;
goto err;
}
mapping = mmap(NULL, msg_info->msg_size, PROT_READ, MAP_PRIVATE, fd, 0);
if (mapping == (char *)MAP_FAILED) {
res = MAIL_ERROR_FILE;
goto close;
}
data = malloc(sizeof(* data));
if (data == NULL) {
res = MAIL_ERROR_MEMORY;
goto unmap;
}
data->fd = fd;
msg = msg_info->msg_data;
msg->msg_data = data;
msg->msg_message = mapping;
msg->msg_length = msg_info->msg_size;
return MAIL_NO_ERROR;
unmap:
munmap(mapping, msg_info->msg_size);
close:
close(fd);
err:
return res;
}
static void prefetch_free(struct generic_message_t * msg)
{
if (msg->msg_message != NULL) {
struct maildir_msg_data * data;
munmap(msg->msg_message, msg->msg_length);
msg->msg_message = NULL;
data = msg->msg_data;
close(data->fd);
free(data);
}
}
static int initialize(mailmessage * msg_info)
{
struct generic_message_t * msg;
int r;
r = mailmessage_generic_initialize(msg_info);
if (r != MAIL_NO_ERROR)
return r;
msg = msg_info->msg_data;
msg->msg_prefetch = prefetch;
msg->msg_prefetch_free = prefetch_free;
return MAIL_NO_ERROR;
}
static void check(mailmessage * msg_info)
{
int r;
if (msg_info->msg_flags != NULL) {
r = mail_flags_store_set(get_session_ancestor_data(msg_info)->md_flags_store, msg_info);
r = mail_flags_store_set(get_cached_session_data(msg_info)->md_flags_store, msg_info);
/* ignore errors */
}
}
#define FLAGS_NAME "flags.db"
static int get_flags(mailmessage * msg_info,
struct mail_flags ** result)
{
struct mail_cache_db * cache_db_flags;
chashdatum key;
chashdatum value;
struct maildir * md;
struct mail_flags * flags;
struct maildir_cached_session_state_data * data;
struct maildir_msg * md_msg;
int r;
uint32_t driver_flags;
char filename_flags[PATH_MAX];
char keyname[PATH_MAX];
MMAPString * mmapstr;
if (msg_info->msg_flags != NULL) {
* result = msg_info->msg_flags;
return MAIL_NO_ERROR;
}
data = get_cached_session_data(msg_info);
flags = mail_flags_store_get(data->md_flags_store,
msg_info->msg_index);
if (flags != NULL) {
msg_info->msg_flags = flags;
* result = msg_info->msg_flags;
return MAIL_NO_ERROR;
}
snprintf(filename_flags, PATH_MAX, "%s%c%s%c%s",
data->md_flags_directory, MAIL_DIR_SEPARATOR, data->md_quoted_mb,
MAIL_DIR_SEPARATOR, FLAGS_NAME);
r = mail_cache_db_open_lock(filename_flags, &cache_db_flags);
if (r < 0)
return MAIL_ERROR_FILE;
snprintf(keyname, PATH_MAX, "%s-flags", msg_info->msg_uid);
mmapstr = mmap_string_new("");
if (mmapstr == NULL) {
mail_cache_db_close_unlock(filename_flags, cache_db_flags);
return MAIL_ERROR_MEMORY;
}
r = generic_cache_flags_read(cache_db_flags, mmapstr, keyname, &flags);
mmap_string_free(mmapstr);
mail_cache_db_close_unlock(filename_flags, cache_db_flags);
if (r != MAIL_NO_ERROR) {
flags = mail_flags_new_empty();
if (flags == NULL)
return MAIL_ERROR_MEMORY;
}
md = get_maildir_session(msg_info);
if (md == NULL)
return MAIL_ERROR_BAD_STATE;
key.data = msg_info->msg_uid;
key.len = strlen(msg_info->msg_uid);
r = chash_get(md->mdir_msg_hash, &key, &value);
if (r < 0)
return MAIL_ERROR_MSG_NOT_FOUND;
md_msg = value.data;
driver_flags = maildirdriver_maildir_flags_to_flags(md_msg->msg_flags);
flags->fl_flags = driver_flags;
msg_info->msg_flags = flags;
* result = msg_info->msg_flags;
return MAIL_NO_ERROR;
}
@@ -0,0 +1,52 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: maildirdriver_cached_message.h,v 1.3 2004/11/21 21:53:32 hoa Exp $
*/
#ifndef MAILDIRDRIVER_CACHED_MESSAGE_H
#define MAILDIRDRIVER_CACHED_MESSAGE_H
#include <libetpan/maildirdriver_types.h>
#ifdef __cplusplus
extern "C" {
#endif
extern mailmessage_driver * maildir_cached_message_driver;
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,292 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: maildirdriver_message.c,v 1.9 2006/06/26 11:50:26 hoa Exp $
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "maildirdriver_message.h"
#include "maildirdriver_tools.h"
#include "mailmessage_tools.h"
#include "maildirdriver.h"
#include "maildir.h"
#include "generic_cache.h"
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef HAVE_SYS_MMAN_H
# include <sys/mman.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#ifdef _MSC_VER
# include "win_etpan.h"
#endif
static int get_flags(mailmessage * msg_info,
struct mail_flags ** result);
static int prefetch(mailmessage * msg_info);
static void prefetch_free(struct generic_message_t * msg);
static int initialize(mailmessage * msg_info);
static void check(mailmessage * msg_info);
static mailmessage_driver local_maildir_message_driver = {
#if ! defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
/* msg_name */ "maildir",
/* msg_initialize */ initialize,
/* msg_uninitialize */ mailmessage_generic_uninitialize,
/* msg_flush */ mailmessage_generic_flush,
/* msg_check */ check,
/* msg_fetch_result_free */ mailmessage_generic_fetch_result_free,
/* msg_fetch */ mailmessage_generic_fetch,
/* msg_fetch_header */ mailmessage_generic_fetch_header,
/* msg_fetch_body */ mailmessage_generic_fetch_header,
/* msg_fetch_size */ NULL,
/* msg_get_bodystructure */ mailmessage_generic_get_bodystructure,
/* msg_fetch_section */ mailmessage_generic_fetch_section,
/* msg_fetch_section_header */ mailmessage_generic_fetch_section_header,
/* msg_fetch_section_mime */ mailmessage_generic_fetch_section_mime,
/* msg_fetch_section_body */ mailmessage_generic_fetch_section_body,
/* msg_fetch_envelope */ mailmessage_generic_fetch_envelope,
/* msg_get_flags */ get_flags
#else
.msg_name = "maildir",
.msg_initialize = initialize,
.msg_uninitialize = mailmessage_generic_uninitialize,
.msg_flush = mailmessage_generic_flush,
.msg_check = check,
.msg_fetch_result_free = mailmessage_generic_fetch_result_free,
.msg_fetch = mailmessage_generic_fetch,
.msg_fetch_header = mailmessage_generic_fetch_header,
.msg_fetch_body = mailmessage_generic_fetch_header,
.msg_fetch_size = NULL,
.msg_get_bodystructure = mailmessage_generic_get_bodystructure,
.msg_fetch_section = mailmessage_generic_fetch_section,
.msg_fetch_section_header = mailmessage_generic_fetch_section_header,
.msg_fetch_section_mime = mailmessage_generic_fetch_section_mime,
.msg_fetch_section_body = mailmessage_generic_fetch_section_body,
.msg_fetch_envelope = mailmessage_generic_fetch_envelope,
.msg_get_flags = get_flags,
#endif
};
mailmessage_driver * maildir_message_driver = &local_maildir_message_driver;
struct maildir_msg_data {
int fd;
};
static inline struct maildir_session_state_data *
get_session_data(mailmessage * msg)
{
return msg->msg_session->sess_data;
}
static struct maildir * get_maildir_session(mailmessage * msg)
{
return get_session_data(msg)->md_session;
}
static int prefetch(mailmessage * msg_info)
{
struct generic_message_t * msg;
int res;
struct maildir_msg_data * data;
char * filename;
int fd;
char * mapping;
struct maildir * md;
md = get_maildir_session(msg_info);
if (msg_info->msg_uid == NULL) {
res = MAIL_ERROR_INVAL;
goto err;
}
filename = maildir_message_get(md, msg_info->msg_uid);
if (filename == NULL) {
res = MAIL_ERROR_MEMORY;
goto err;
}
fd = open(filename, O_RDONLY);
free(filename);
if (fd == -1) {
res = MAIL_ERROR_FILE;
goto err;
}
mapping = mmap(NULL, msg_info->msg_size, PROT_READ, MAP_PRIVATE, fd, 0);
if (mapping == (char *)MAP_FAILED) {
res = MAIL_ERROR_FILE;
goto close;
}
data = malloc(sizeof(* data));
if (data == NULL) {
res = MAIL_ERROR_MEMORY;
goto unmap;
}
data->fd = fd;
msg = msg_info->msg_data;
msg->msg_data = data;
msg->msg_message = mapping;
msg->msg_length = msg_info->msg_size;
return MAIL_NO_ERROR;
unmap:
munmap(mapping, msg_info->msg_size);
close:
close(fd);
err:
return res;
}
static void prefetch_free(struct generic_message_t * msg)
{
if (msg->msg_message != NULL) {
struct maildir_msg_data * data;
munmap(msg->msg_message, msg->msg_length);
msg->msg_message = NULL;
data = msg->msg_data;
close(data->fd);
free(data);
}
}
static int initialize(mailmessage * msg_info)
{
struct generic_message_t * msg;
int r;
r = mailmessage_generic_initialize(msg_info);
if (r != MAIL_NO_ERROR)
return r;
msg = msg_info->msg_data;
msg->msg_prefetch = prefetch;
msg->msg_prefetch_free = prefetch_free;
return MAIL_NO_ERROR;
}
static void check(mailmessage * msg_info)
{
int r;
if (msg_info->msg_flags != NULL) {
r = mail_flags_store_set(get_session_data(msg_info)->md_flags_store,
msg_info);
/* ignore errors */
}
}
static int get_flags(mailmessage * msg_info,
struct mail_flags ** result)
{
chashdatum key;
chashdatum value;
struct maildir * md;
struct mail_flags * flags;
struct maildir_session_state_data * data;
struct maildir_msg * md_msg;
int r;
uint32_t driver_flags;
clist * ext;
if (msg_info->msg_flags != NULL) {
* result = msg_info->msg_flags;
return MAIL_NO_ERROR;
}
data = get_session_data(msg_info);
flags = mail_flags_store_get(data->md_flags_store,
msg_info->msg_index);
if (flags != NULL) {
msg_info->msg_flags = flags;
* result = msg_info->msg_flags;
return MAIL_NO_ERROR;
}
md = get_maildir_session(msg_info);
if (md == NULL)
return MAIL_ERROR_BAD_STATE;
key.data = msg_info->msg_uid;
key.len = strlen(msg_info->msg_uid);
r = chash_get(md->mdir_msg_hash, &key, &value);
if (r < 0)
return MAIL_ERROR_MSG_NOT_FOUND;
md_msg = value.data;
driver_flags = maildirdriver_maildir_flags_to_flags(md_msg->msg_flags);
ext = clist_new();
if (ext == NULL)
return MAIL_ERROR_MEMORY;
msg_info->msg_flags = mail_flags_new(driver_flags, ext);
* result = msg_info->msg_flags;
return MAIL_NO_ERROR;
}
@@ -0,0 +1,52 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: maildirdriver_message.h,v 1.3 2004/11/21 21:53:32 hoa Exp $
*/
#ifndef MAILDIRDRIVER_MESSAGE_H
#define MAILDIRDRIVER_MESSAGE_H
#include <libetpan/maildirdriver_types.h>
#ifdef __cplusplus
extern "C" {
#endif
extern mailmessage_driver * maildir_message_driver;
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,202 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: maildirdriver_tools.c,v 1.7 2006/05/22 13:39:40 hoa Exp $
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "mailmessage.h"
#include "maildirdriver_tools.h"
#include "maildir.h"
#include "generic_cache.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
int maildirdriver_maildir_error_to_mail_error(int error)
{
switch (error) {
case MAILDIR_NO_ERROR:
return MAIL_NO_ERROR;
case MAILDIR_ERROR_CREATE:
return MAIL_ERROR_FILE;
case MAILDIR_ERROR_DIRECTORY:
return MAIL_ERROR_FILE;
case MAILDIR_ERROR_MEMORY:
return MAIL_ERROR_MEMORY;
case MAILDIR_ERROR_FILE:
return MAIL_ERROR_FILE;
case MAILDIR_ERROR_FOLDER:
return MAIL_ERROR_FOLDER;
case MAILDIR_ERROR_NOT_FOUND:
return MAIL_ERROR_MSG_NOT_FOUND;
default:
return MAIL_ERROR_INVAL;
}
}
uint32_t maildirdriver_maildir_flags_to_flags(uint32_t md_flags)
{
uint32_t flags;
flags = 0;
if ((md_flags & MAILDIR_FLAG_NEW) != 0)
flags |= MAIL_FLAG_NEW;
if ((md_flags & MAILDIR_FLAG_SEEN) != 0)
flags |= MAIL_FLAG_SEEN;
if ((md_flags & MAILDIR_FLAG_REPLIED) != 0)
flags |= MAIL_FLAG_ANSWERED;
if ((md_flags & MAILDIR_FLAG_FLAGGED) != 0)
flags |= MAIL_FLAG_FLAGGED;
if ((md_flags & MAILDIR_FLAG_TRASHED) != 0)
flags |= MAIL_FLAG_DELETED;
return flags;
}
uint32_t maildirdriver_flags_to_maildir_flags(uint32_t flags)
{
uint32_t md_flags;
md_flags = 0;
if ((flags & MAIL_FLAG_NEW) != 0)
md_flags |= MAILDIR_FLAG_NEW;
if ((flags & MAIL_FLAG_SEEN) != 0)
md_flags |= MAILDIR_FLAG_SEEN;
if ((flags & MAIL_FLAG_ANSWERED) != 0)
md_flags |= MAILDIR_FLAG_REPLIED;
if ((flags & MAIL_FLAG_FLAGGED) != 0)
md_flags |= MAILDIR_FLAG_FLAGGED;
if ((flags & MAIL_FLAG_DELETED) != 0)
md_flags |= MAILDIR_FLAG_TRASHED;
return md_flags;
}
int maildir_get_messages_list(mailsession * session, struct maildir * md,
mailmessage_driver * message_driver,
struct mailmessage_list ** result)
{
unsigned int i;
struct mailmessage_list * env_list;
int r;
carray * tab;
int res;
tab = carray_new(128);
if (tab == NULL) {
res = MAIL_ERROR_MEMORY;
goto err;
}
for(i = 0 ; i < carray_count(md->mdir_msg_list) ; i++) {
struct maildir_msg * md_msg;
mailmessage * msg;
char * filename;
struct stat stat_info;
md_msg = carray_get(md->mdir_msg_list, i);
filename = maildir_message_get(md, md_msg->msg_uid);
r = stat(filename, &stat_info);
free(filename);
if (r < 0)
continue;
msg = mailmessage_new();
if (msg == NULL) {
res = MAIL_ERROR_MEMORY;
goto free_list;
}
r = mailmessage_init(msg, session, message_driver,
i + 1, stat_info.st_size);
if (r != MAIL_NO_ERROR) {
mailmessage_free(msg);
res = r;
goto free_list;
}
msg->msg_uid = strdup(md_msg->msg_uid);
if (msg->msg_uid == NULL) {
mailmessage_free(msg);
res = MAIL_ERROR_MEMORY;
goto free_list;
}
r = carray_add(tab, msg, NULL);
if (r < 0) {
mailmessage_free(msg);
res = MAIL_ERROR_MEMORY;
goto free_list;
}
}
env_list = mailmessage_list_new(tab);
if (env_list == NULL) {
res = MAIL_ERROR_MEMORY;
goto free_list;
}
* result = env_list;
return MAIL_NO_ERROR;
free_list:
for(i = 0 ; i < carray_count(tab) ; i ++)
mailmessage_free(carray_get(tab, i));
carray_free(tab);
err:
return res;
}
@@ -0,0 +1,53 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: maildirdriver_tools.h,v 1.3 2004/11/21 21:53:32 hoa Exp $
*/
#ifndef MAILDIRDRIVER_TOOLS_H
#define MAILDIRDRIVER_TOOLS_H
#include "maildriver_types.h"
#include "maildir.h"
int maildirdriver_maildir_error_to_mail_error(int error);
uint32_t maildirdriver_maildir_flags_to_flags(uint32_t md_flags);
uint32_t maildirdriver_flags_to_maildir_flags(uint32_t flags);
int maildir_get_messages_list(mailsession * session, struct maildir * md,
mailmessage_driver * message_driver,
struct mailmessage_list ** result);
#endif
@@ -0,0 +1,96 @@
/*
* libEtPan! -- a mail stuff library
*
* Copyright (C) 2001, 2005 - 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 AUTHORS 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 AUTHORS 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: maildirdriver_types.h,v 1.6 2006/05/22 13:39:40 hoa Exp $
*/
#ifndef MAILDIRDRIVER_TYPES_H
#define MAILDIRDRIVER_TYPES_H
#include <libetpan/libetpan-config.h>
#include <libetpan/maildriver_types.h>
#include <libetpan/maildir.h>
#include <libetpan/generic_cache_types.h>
#include <libetpan/mailstorage_types.h>
#ifdef __cplusplus
extern "C" {
#endif
struct maildir_session_state_data {
struct maildir * md_session;
struct mail_flags_store * md_flags_store;
};
enum {
MAILDIRDRIVER_CACHED_SET_CACHE_DIRECTORY = 1,
MAILDIRDRIVER_CACHED_SET_FLAGS_DIRECTORY
};
struct maildir_cached_session_state_data {
mailsession * md_ancestor;
char * md_quoted_mb;
struct mail_flags_store * md_flags_store;
char md_cache_directory[PATH_MAX];
char md_flags_directory[PATH_MAX];
};
/* maildir storage */
/*
maildir_mailstorage is the state data specific to the maildir storage.
- pathname is the path of the maildir storage.
- cached if this value is != 0, a persistant cache will be
stored on local system.
- cache_directory is the location of the cache.
- flags_directory is the location of the flags.
*/
struct maildir_mailstorage {
char * md_pathname;
int md_cached;
char * md_cache_directory;
char * md_flags_directory;
};
#ifdef __cplusplus
}
#endif
#endif

Some files were not shown because too many files have changed in this diff Show More