mirror of
https://github.com/signalwire/freeswitch.git
synced 2026-10-09 21:14:02 +00:00
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:
@@ -0,0 +1,3 @@
|
||||
.libs
|
||||
Makefile
|
||||
*.la
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
}
|
||||
@@ -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_ */
|
||||
@@ -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));
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
.libs
|
||||
*.la
|
||||
*.lo
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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 */
|
||||
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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__ */
|
||||
@@ -0,0 +1,2 @@
|
||||
.libs
|
||||
*.la
|
||||
@@ -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
|
||||
@@ -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
Reference in New Issue
Block a user