o Added smtp/ to providers tree under camel o Added makefiles and source

Thu Apr  6 22:56:44 EDT 2000  Jeffrey Stedfast <fejj@stampede.org>
  o Added smtp/ to providers tree under camel
  o Added makefiles and source for an smtp module (untested as of yet)

svn path=/trunk/; revision=2317
This commit is contained in:
EDT 2000 Jeffrey Stedfast
2000-04-07 03:49:48 +00:00
committed by Jeffrey Stedfast
parent 0bdfacc11b
commit a032d78dae
6 changed files with 1370 additions and 2 deletions

View File

@ -1,6 +1,6 @@
## Process this file with automake to produce Makefile.in
SUBDIRS = mbox pop3 sendmail
SUBDIRS = mbox pop3 sendmail smtp
# these ones are disabled for the moment.
# MH maildir
# MH maildir imap smtp

View File

@ -0,0 +1,25 @@
## Process this file with automake to produce Makefile.in
SUBDIRS =
libcamelsmtpincludedir = $(includedir)/camel
providerdir = $(pkglibdir)/camel-providers/$(VERSION)
provider_LTLIBRARIES = libcamelsmtp.la
INCLUDES = -I.. -I$(srcdir)/.. -I$(includedir) \
-I$(top_srcdir)/intl \
$(GTK_INCLUDEDIR) -I$(top_srcdir)/camel
libcamelpop3_la_SOURCES = \
camel-smtp-provider.c \
camel-smtp-transport.c
libcamelpop3include_HEADERS = \
camel-smtp-transport.h
libcamelsmtp_la_LDFLAGS = -version-info 0:0:0 -rpath $(libdir)
EXTRA_DIST =

View File

@ -0,0 +1,527 @@
# Makefile.in generated automatically by automake 1.4 from Makefile.am
# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
SHELL = @SHELL@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
sbindir = @sbindir@
libexecdir = @libexecdir@
datadir = @datadir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@
localstatedir = @localstatedir@
libdir = @libdir@
infodir = @infodir@
mandir = @mandir@
includedir = @includedir@
oldincludedir = /usr/include
DESTDIR =
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ../../..
ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
transform = @program_transform_name@
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
host_alias = @host_alias@
host_triplet = @host@
AS = @AS@
BONOBO_GNOME_CFLAGS = @BONOBO_GNOME_CFLAGS@
BONOBO_GNOME_LIBS = @BONOBO_GNOME_LIBS@
BONOBO_HTML_GNOME_CFLAGS = @BONOBO_HTML_GNOME_CFLAGS@
BONOBO_HTML_GNOME_LIBS = @BONOBO_HTML_GNOME_LIBS@
BONOBO_VFS_GNOME_CFLAGS = @BONOBO_VFS_GNOME_CFLAGS@
BONOBO_VFS_GNOME_LIBS = @BONOBO_VFS_GNOME_LIBS@
CAPPLET_LIBS = @CAPPLET_LIBS@
CATALOGS = @CATALOGS@
CATOBJEXT = @CATOBJEXT@
CC = @CC@
CPP = @CPP@
DATADIRNAME = @DATADIRNAME@
DLLTOOL = @DLLTOOL@
EXTRA_GNOME_CFLAGS = @EXTRA_GNOME_CFLAGS@
EXTRA_GNOME_LIBS = @EXTRA_GNOME_LIBS@
GENCAT = @GENCAT@
GLIB_CFLAGS = @GLIB_CFLAGS@
GLIB_LIBS = @GLIB_LIBS@
GMOFILES = @GMOFILES@
GMSGFMT = @GMSGFMT@
GNOMEGNORBA_LIBS = @GNOMEGNORBA_LIBS@
GNOMEUI_LIBS = @GNOMEUI_LIBS@
GNOME_APPLETS_LIBS = @GNOME_APPLETS_LIBS@
GNOME_CAPPLET_LIBS = @GNOME_CAPPLET_LIBS@
GNOME_CONFIG = @GNOME_CONFIG@
GNOME_INCLUDEDIR = @GNOME_INCLUDEDIR@
GNOME_LIBDIR = @GNOME_LIBDIR@
GNOME_LIBS = @GNOME_LIBS@
GNOME_PILOT_CFLAGS = @GNOME_PILOT_CFLAGS@
GNOME_PILOT_CONFIG = @GNOME_PILOT_CONFIG@
GNOME_PILOT_LIBS = @GNOME_PILOT_LIBS@
GNOME_PRINT_CFLAGS = @GNOME_PRINT_CFLAGS@
GNOME_PRINT_LIBS = @GNOME_PRINT_LIBS@
GNORBA_CFLAGS = @GNORBA_CFLAGS@
GNORBA_LIBS = @GNORBA_LIBS@
GTKHTML_CFLAGS = @GTKHTML_CFLAGS@
GTKHTML_LIBS = @GTKHTML_LIBS@
GTKXMHTML_LIBS = @GTKXMHTML_LIBS@
GTK_CFLAGS = @GTK_CFLAGS@
GTK_CONFIG = @GTK_CONFIG@
GTK_LIBS = @GTK_LIBS@
GT_NO = @GT_NO@
GT_YES = @GT_YES@
INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@
INSTOBJEXT = @INSTOBJEXT@
INTLDEPS = @INTLDEPS@
INTLLIBS = @INTLLIBS@
INTLOBJS = @INTLOBJS@
LD = @LD@
LEX = @LEX@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MKINSTALLDIRS = @MKINSTALLDIRS@
NM = @NM@
OBJDUMP = @OBJDUMP@
ORBIT_CFLAGS = @ORBIT_CFLAGS@
ORBIT_CONFIG = @ORBIT_CONFIG@
ORBIT_IDL = @ORBIT_IDL@
ORBIT_LIBS = @ORBIT_LIBS@
PACKAGE = @PACKAGE@
PILOT_BINS = @PILOT_BINS@
PILOT_LIBS = @PILOT_LIBS@
PISOCK_INCLUDEDIR = @PISOCK_INCLUDEDIR@
PISOCK_LIBDIR = @PISOCK_LIBDIR@
PISOCK_LIBS = @PISOCK_LIBS@
POFILES = @POFILES@
POSUB = @POSUB@
PTHREAD_LIB = @PTHREAD_LIB@
RANLIB = @RANLIB@
SENDMAIL = @SENDMAIL@
UNICODE_CFLAGS = @UNICODE_CFLAGS@
UNICODE_LIBS = @UNICODE_LIBS@
USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
USE_NLS = @USE_NLS@
VERSION = @VERSION@
XPM_LIBS = @XPM_LIBS@
YACC = @YACC@
ZVT_LIBS = @ZVT_LIBS@
cflags_set = @cflags_set@
cxxflags_set = @cxxflags_set@
l = @l@
SUBDIRS =
libcamelpop3includedir = $(includedir)/camel
providerdir = $(pkglibdir)/camel-providers/$(VERSION)
provider_LTLIBRARIES = libcamelpop3.la
INCLUDES = -I.. -I$(srcdir)/.. -I$(includedir) -I$(top_srcdir)/intl $(GTK_INCLUDEDIR) -I$(top_srcdir)/camel -I$(srcdir)/../mbox
libcamelpop3_la_SOURCES = camel-pop3-folder.c camel-pop3-provider.c camel-pop3-store.c
libcamelpop3include_HEADERS = camel-pop3-folder.h camel-pop3-store.h
libcamelpop3_la_LDFLAGS = -version-info 0:0:0 -rpath $(libdir)
EXTRA_DIST =
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = ../../../config.h
CONFIG_CLEAN_FILES =
LTLIBRARIES = $(provider_LTLIBRARIES)
DEFS = @DEFS@ -I. -I$(srcdir) -I../../..
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
libcamelpop3_la_LIBADD =
libcamelpop3_la_OBJECTS = camel-pop3-folder.lo camel-pop3-provider.lo \
camel-pop3-store.lo
CFLAGS = @CFLAGS@
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
HEADERS = $(libcamelpop3include_HEADERS)
DIST_COMMON = Makefile.am Makefile.in
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = tar
GZIP_ENV = --best
DEP_FILES = .deps/camel-pop3-folder.P .deps/camel-pop3-provider.P \
.deps/camel-pop3-store.P
SOURCES = $(libcamelpop3_la_SOURCES)
OBJECTS = $(libcamelpop3_la_OBJECTS)
all: all-redirect
.SUFFIXES:
.SUFFIXES: .S .c .lo .o .s
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && $(AUTOMAKE) --gnu camel/providers/pop3/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
mostlyclean-providerLTLIBRARIES:
clean-providerLTLIBRARIES:
-test -z "$(provider_LTLIBRARIES)" || rm -f $(provider_LTLIBRARIES)
distclean-providerLTLIBRARIES:
maintainer-clean-providerLTLIBRARIES:
install-providerLTLIBRARIES: $(provider_LTLIBRARIES)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(providerdir)
@list='$(provider_LTLIBRARIES)'; for p in $$list; do \
if test -f $$p; then \
echo "$(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(providerdir)/$$p"; \
$(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(providerdir)/$$p; \
else :; fi; \
done
uninstall-providerLTLIBRARIES:
@$(NORMAL_UNINSTALL)
list='$(provider_LTLIBRARIES)'; for p in $$list; do \
$(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(providerdir)/$$p; \
done
.s.o:
$(COMPILE) -c $<
.S.o:
$(COMPILE) -c $<
mostlyclean-compile:
-rm -f *.o core *.core
clean-compile:
distclean-compile:
-rm -f *.tab.c
maintainer-clean-compile:
.s.lo:
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
.S.lo:
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
maintainer-clean-libtool:
libcamelpop3.la: $(libcamelpop3_la_OBJECTS) $(libcamelpop3_la_DEPENDENCIES)
$(LINK) -rpath $(providerdir) $(libcamelpop3_la_LDFLAGS) $(libcamelpop3_la_OBJECTS) $(libcamelpop3_la_LIBADD) $(LIBS)
install-libcamelpop3includeHEADERS: $(libcamelpop3include_HEADERS)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(libcamelpop3includedir)
@list='$(libcamelpop3include_HEADERS)'; for p in $$list; do \
if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \
echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(libcamelpop3includedir)/$$p"; \
$(INSTALL_DATA) $$d$$p $(DESTDIR)$(libcamelpop3includedir)/$$p; \
done
uninstall-libcamelpop3includeHEADERS:
@$(NORMAL_UNINSTALL)
list='$(libcamelpop3include_HEADERS)'; for p in $$list; do \
rm -f $(DESTDIR)$(libcamelpop3includedir)/$$p; \
done
# This directory's subdirectories are mostly independent; you can cd
# into them and run `make' without going through this Makefile.
# To change the values of `make' variables: instead of editing Makefiles,
# (1) if the variable is set in `config.status', edit `config.status'
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
@SET_MAKE@
all-recursive install-data-recursive install-exec-recursive \
installdirs-recursive install-recursive uninstall-recursive \
check-recursive installcheck-recursive info-recursive dvi-recursive:
@set fnord $(MAKEFLAGS); amf=$$2; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
mostlyclean-recursive clean-recursive distclean-recursive \
maintainer-clean-recursive:
@set fnord $(MAKEFLAGS); amf=$$2; \
dot_seen=no; \
rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
rev="$$subdir $$rev"; \
test "$$subdir" = "." && dot_seen=yes; \
done; \
test "$$dot_seen" = "no" && rev=". $$rev"; \
target=`echo $@ | sed s/-recursive//`; \
for subdir in $$rev; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done && test -z "$$fail"
tags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
done
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP)
list='$(SOURCES) $(HEADERS)'; \
unique=`for i in $$list; do echo $$i; done | \
awk ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
here=`pwd` && cd $(srcdir) \
&& mkid -f$$here/ID $$unique $(LISP)
TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
fi; \
done; \
list='$(SOURCES) $(HEADERS)'; \
unique=`for i in $$list; do echo $$i; done | \
awk ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
|| (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
mostlyclean-tags:
clean-tags:
distclean-tags:
-rm -f TAGS ID
maintainer-clean-tags:
distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
subdir = camel/providers/pop3
distdir: $(DISTFILES)
here=`cd $(top_builddir) && pwd`; \
top_distdir=`cd $(top_distdir) && pwd`; \
distdir=`cd $(distdir) && pwd`; \
cd $(top_srcdir) \
&& $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu camel/providers/pop3/Makefile
@for file in $(DISTFILES); do \
d=$(srcdir); \
if test -d $$d/$$file; then \
cp -pr $$/$$file $(distdir)/$$file; \
else \
test -f $(distdir)/$$file \
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|| cp -p $$d/$$file $(distdir)/$$file || :; \
fi; \
done
for subdir in $(SUBDIRS); do \
if test "$$subdir" = .; then :; else \
test -d $(distdir)/$$subdir \
|| mkdir $(distdir)/$$subdir \
|| exit 1; \
chmod 777 $(distdir)/$$subdir; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(top_distdir) distdir=../$(distdir)/$$subdir distdir) \
|| exit 1; \
fi; \
done
DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
-include $(DEP_FILES)
mostlyclean-depend:
clean-depend:
distclean-depend:
-rm -rf .deps
maintainer-clean-depend:
%.o: %.c
@echo '$(COMPILE) -c $<'; \
$(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
@-cp .deps/$(*F).pp .deps/$(*F).P; \
tr ' ' '\012' < .deps/$(*F).pp \
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
>> .deps/$(*F).P; \
rm .deps/$(*F).pp
%.lo: %.c
@echo '$(LTCOMPILE) -c $<'; \
$(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
@-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
< .deps/$(*F).pp > .deps/$(*F).P; \
tr ' ' '\012' < .deps/$(*F).pp \
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
>> .deps/$(*F).P; \
rm -f .deps/$(*F).pp
info-am:
info: info-recursive
dvi-am:
dvi: dvi-recursive
check-am: all-am
check: check-recursive
installcheck-am:
installcheck: installcheck-recursive
install-exec-am:
install-exec: install-exec-recursive
install-data-am: install-providerLTLIBRARIES \
install-libcamelpop3includeHEADERS
install-data: install-data-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
install: install-recursive
uninstall-am: uninstall-providerLTLIBRARIES \
uninstall-libcamelpop3includeHEADERS
uninstall: uninstall-recursive
all-am: Makefile $(LTLIBRARIES) $(HEADERS)
all-redirect: all-recursive
install-strip:
$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
installdirs: installdirs-recursive
installdirs-am:
$(mkinstalldirs) $(DESTDIR)$(providerdir) \
$(DESTDIR)$(libcamelpop3includedir)
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES)
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
maintainer-clean-generic:
mostlyclean-am: mostlyclean-providerLTLIBRARIES mostlyclean-compile \
mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
mostlyclean-generic
mostlyclean: mostlyclean-recursive
clean-am: clean-providerLTLIBRARIES clean-compile clean-libtool \
clean-tags clean-depend clean-generic mostlyclean-am
clean: clean-recursive
distclean-am: distclean-providerLTLIBRARIES distclean-compile \
distclean-libtool distclean-tags distclean-depend \
distclean-generic clean-am
-rm -f libtool
distclean: distclean-recursive
maintainer-clean-am: maintainer-clean-providerLTLIBRARIES \
maintainer-clean-compile maintainer-clean-libtool \
maintainer-clean-tags maintainer-clean-depend \
maintainer-clean-generic distclean-am
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
maintainer-clean: maintainer-clean-recursive
.PHONY: mostlyclean-providerLTLIBRARIES distclean-providerLTLIBRARIES \
clean-providerLTLIBRARIES maintainer-clean-providerLTLIBRARIES \
uninstall-providerLTLIBRARIES install-providerLTLIBRARIES \
mostlyclean-compile distclean-compile clean-compile \
maintainer-clean-compile mostlyclean-libtool distclean-libtool \
clean-libtool maintainer-clean-libtool \
uninstall-libcamelpop3includeHEADERS install-libcamelpop3includeHEADERS \
install-data-recursive uninstall-data-recursive install-exec-recursive \
uninstall-exec-recursive installdirs-recursive uninstalldirs-recursive \
all-recursive check-recursive installcheck-recursive info-recursive \
dvi-recursive mostlyclean-recursive distclean-recursive clean-recursive \
maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
distclean-tags clean-tags maintainer-clean-tags distdir \
mostlyclean-depend distclean-depend clean-depend \
maintainer-clean-depend info-am info dvi-am dvi check check-am \
installcheck-am installcheck install-exec-am install-exec \
install-data-am install-data install-am install uninstall-am uninstall \
all-redirect all-am all installdirs-am installdirs mostlyclean-generic \
distclean-generic clean-generic maintainer-clean-generic clean \
mostlyclean distclean maintainer-clean
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@ -0,0 +1,54 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/* camel-smtp-provider.c: smtp provider registration code */
/*
* Authors :
* Jeffrey Stedfast <fejj@stampede.org>
*
* Copyright (C) 2000 Helix Code, Inc. (www.helixcode.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*/
#include "config.h"
#include "camel-smtp-transport.h"
#include "camel-provider.h"
#include "camel-log.h"
static CamelProvider _smtp_provider = {
(GtkType) 0,
PROVIDER_TRANSPORT,
0,
"SMTP",
"Camel default SMTP provider",
"This is a provider that sends to a SMTP server.",
(GModule *) NULL
};
CamelProvider *
camel_provider_module_init (void);
CamelProvider *
camel_provider_module_init (void)
{
_smtp_provider.object_type = camel_smtp_transport_get_type();
return &_smtp_provider;
}

View File

@ -0,0 +1,694 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/* camel-smtp-transport.c : class for a smtp transport */
/*
* Authors:
* Jeffrey Stedfast <fejj@stampede.org>
*
* Copyright (C) 2000 Helix Code, Inc. (www.helixcode.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*/
#include "config.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "camel-smtp-transport.h"
#include "camel-mime-message.h"
#include "camel-stream-buffer.h"
#include "camel-stream-fs.h"
#include "camel-session.h"
#include "camel-exception.h"
#include "md5-utils.h"
#include "url-util.h"
/* Specified in RFC ???? */
#define SMTP_PORT 25
static CamelServiceClass *service_class = NULL;
/* camel smtp transport class prototypes */
static gboolean _can_send (CamelTransport *transport, CamelMedium *message);
static gboolean _send (CamelTransport *transport, CamelMedium *message, CamelException *ex);
static gboolean _send_to (CamelTransport *transport, CamelMedium *message, GList *recipients, CamelException *ex);
/* support prototypes */
static gboolean smtp_connect (CamelService *service, CamelException *ex);
static gboolean smtp_disconnect (CamelService *service, CamelException *ex);
static void esmtp_get_authtypes(gchar *buffer);
static GList *query_auth_types (CamelService *service);
static void free_auth_types (CamelService *service, GList *authtypes);
static gchar *smtp_get_email_addr_from_text (gchar *text);
static gboolean smtp_helo (CamelSmtpTransport *transport, CamelException *ex);
static gboolean smtp_mail (CamelSmtpTransport *transport, gchar *sender, CamelException *ex);
static gboolean smtp_rcpt (CamelSmtpTransport *transport, gchar *recipient, CamelException *ex);
static gboolean smtp_data (CamelSmtpTransport *transport, gchar *message, CamelException *ex);
static gboolean smtp_rset (CamelSmtpTransport *transport, CamelException *ex);
static gboolean smtp_quit (CamelSmtpTransport *transport, CamelException *ex);
static gboolean smtp_is_esmtp = FALSE;
static GList *esmtp_supported_authtypes = NULL;
static void
camel_smtp_transport_class_init (CamelSmtpTransportClass *camel_smtp_transport_class)
{
CamelTransportClass *camel_transport_class =
CAMEL_TRANSPORT_CLASS (camel_smtp_transport_class);
CamelServiceClass *camel_service_class =
CAMEL_SERVICE_CLASS (camel_smtp_store_class);
/* virtual method overload */
camel_service_class->connect = smtp_connect;
camel_service_class->disconnect = smtp_disconnect;
camel_service_class->query_auth_types = query_auth_types;
camel_service_class->free_auth_types = free_auth_types;
camel_transport_class->can_send = _can_send;
camel_transport_class->send = _send;
camel_transport_class->send_to = _send_to;
}
GtkType
camel_smtp_transport_get_type (void)
{
static GtkType camel_smtp_transport_type = 0;
if (!camel_smtp_transport_type) {
GtkTypeInfo camel_smtp_transport_info =
{
"CamelSmtpTransport",
sizeof (CamelSmtpTransport),
sizeof (CamelSmtpTransportClass),
(GtkClassInitFunc) camel_smtp_transport_class_init,
(GtkObjectInitFunc) NULL,
/* reserved_1 */ NULL,
/* reserved_2 */ NULL,
(GtkClassInitFunc) NULL,
};
camel_smtp_transport_type = gtk_type_unique (CAMEL_TRANSPORT_TYPE, &camel_smtp_transport_info);
}
return camel_smtp_transport_type;
}
static gboolean
smtp_connect (CamelService *service, CamelException *ex)
{
struct hostent *h;
struct sockaddr_in sin;
gint port, fd, status;
gchar *buf, *pass;
CamelSmtpStore *transport = CAMEL_SMTP_TRANSPORT (service);
if (!service_class->connect (service, ex))
return FALSE;
h = camel_service_gethost (service, ex);
if (!h)
return FALSE;
port = camel_service_getport (service, "smtp", SMTP_PORT, "tcp", ex);
if (port == -1)
return FALSE;
sin.sin_family = h->h_addrtype;
sin.sin_port = port;
memcpy (&sin.sin_addr, h->h_addr, sizeof (sin.sin_addr));
fd = socket (h->h_addrtype, SOCK_STREAM, 0);
if (fd == -1 || connect (fd, (struct sockaddr *)&sin, sizeof(sin)) == -1)
{
camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
"Could not connect to %s (port %s): %s",
service->url->host, service->url->port,
strerror(errno));
if (fd > -1)
close (fd);
g_free (pass);
return FALSE;
}
transport->ostream = camel_stream_fs_new_with_fd (fd);
transport->istream = camel_stream_buffer_new (store->ostream,
CAMEL_STREAM_BUFFER_READ);
/* Read the greeting, note whether the server is ESMTP and if it requests AUTH. */
do
{
/* Check for "220" */
g_free(respbuf);
respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (transport->istream));
if ( !respbuf || strncmp(respbuf, "220", 3) )
{
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
"Welcome response error: "
"%s: possibly non-fatal",
g_strerror (errno));
return FALSE;
}
if (strstr(respbuf, "ESMTP"))
smtp_is_esmtp = TRUE;
if (smtp_is_esmtp && strstr(respbuf, "AUTH"))
{
/* parse for supported AUTH types */
esmtp_get_authtypes(respbuf);
}
} while ( *(respbuf+3) == '-' ); /* if we got "220-" then loop again */
g_free(respbuf);
return TRUE;
}
static gboolean
smtp_disconnect (CamelService *service, CamelException *ex)
{
CamelSmtpTransport *transport = CAMEL_SMTP_TRANSPORT (service);
if (!service->connected)
return TRUE;
/* send the QUIT command to the SMTP server */
smtp_quit(service, ex);
if (!service_class->disconnect (service, ex))
return FALSE;
/* Closing the buffered write stream will close the
* unbuffered read stream wrapped inside it as well.
*/
camel_stream_close (transport->ostream);
gtk_object_unref (GTK_OBJECT (transport->ostream));
store->ostream = NULL;
store->istream = NULL;
return TRUE;
}
static GList
esmtp_get_authtypes(gchar *buffer)
{
GList *ret = NULL;
return ret;
}
static CamelServiceAuthType password_authtype = {
"Password/CRAM-MD5",
"This option will connect to the ESMTP server using the CRAM-MD5 "
"authentication if possible.",
"",
TRUE
};
static GList
*query_auth_types (CamelService *service)
{
GList *ret;
ret = g_list_append (NULL, &password_authtype);
return ret;
}
static void
free_auth_types (CamelService *service, GList *authtypes)
{
g_list_free (authtypes);
}
static gboolean
_can_send (CamelTransport *transport, CamelMedium *message)
{
return CAMEL_IS_MIME_MESSAGE (message);
}
static gboolean
_send_to (CamelTransport *transport, CamelMedium *message,
GList *recipients, CamelException *ex)
{
GList *r, *s;
gchar *recipient;
gboolean status;
guint i, len;
CamelService *service = CAMEL_SERVICE (transport);
if (!camel_service_is_connected (service))
smtp_connect (service, ex);
s = camel_mime_message_get_recipients ((CamelMimeMessage *) message, "From");
if (!s)
{
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
"Cannot send message: "
"sender address not defined.");
return FALSE;
}
else
smtp_mail(service, s->data, ex);
g_list_free(s);
if (!(len = g_list_length(recipients)))
{
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
"Cannot send message: "
"no recipients defined.");
return FALSE;
}
for (i = 0, r = recipients; i < len; i++, r = r->next)
{
recipient = smtp_get_addr_from_text(r->data);
if (!smtp_rcpt(service, recipient; ex))
{
g_free(recipient);
return FALSE;
}
g_free(recipient);
}
if (!smtp_data(service, message, ex))
return FALSE;
/* reset the service for our next transfer session */
smtp_rset(service, ex);
return status;
}
static gboolean
_send (CamelTransport *transport, CamelMedium *message,
CamelException *ex)
{
GList *recipients;
recipients = camel_mime_message_get_recipients ((CamelMimeMessage *) message, "To");
recipients = g_list_append(recipients,
camel_mime_message_get_recipients ((CamelMimeMessage *) message, "Cc");
recipients = g_list_append(recipients,
camel_mime_message_get_recipients ((CamelMimeMessage *) message, "Bcc");
return _send_to (transport, message, recipients, ex);
}
static gchar
*smtp_get_email_addr_from_text (gchar *text)
{
/* get the actual email address from the string passed and place it in addr
* we can assume the address will be in one of the following forms:
* 1) The Name <person@host.com>
* 2) <person@host.com>
* 3) person@host.com
* 4) person@host.com (The Name)
*/
gchar *tmp, *addr = NULL;
gchar *addr_strt; /* points to start of addr */
gchar *addr_end; /* points to end of addr */
gchar *ptr1, *ptr2;
/* check the incoming args */
if (!text || !*text)
return NULL;
/* scan the string for an open brace */
for (addr_strt = text; *addr_strt; addr_strt++)
if (*addr_strt == '<')
break;
if (*addr_strt) /* we found an open brace */
{
/* let's look for it's counterpart */
for (addr_end = addr_strt; *addr_end; addr_end++)
if (*addr_end == '>')
break;
/* if we didn't find it, or braces are empty... */
if (!(*addr_end) || (addr_strt == addr_end - 1))
return NULL;
/* addr_strt points to '<' and addr_end points to '>'.
* Now let's adjust 'em slightly to point to the beginning
* and ending of the email addy
*/
addr_strt++;
addr_end--;
}
else /* no open brace...assume type 3 or 4? */
{
addr_strt = text;
/* find the end of the email addr/string */
for (addr_end = addr_strt; *addr_end || *addr_end == ' '; addr_end++);
addr_end--; /* points to NULL, move it back one char */
}
/* now addr_strt & addr_end point to the beginning & ending of the email addy */
/* copy the string into addr */
addr = g_strndup(addr_strt, (gint)(addr_end - addr_strt));
for (ptr1 = addr_strt; ptr1 <= addr_end; ptr1++) /* look for an '@' sign */
if (*ptr1 == '@')
break;
if (*ptr1 != '@')
{
/* here we found out the name doesn't have an '@' part
* let's figure out what machine we're on & stick it on the end
* woops.. forgot the '@' sign, gotta stick that in the reply
* ptr2 should still point to the next place to copy to in addr
*/
gchar hostname[MAXHOSTNAMELEN];
if (gethostname(hostname, MAXHOSTNAMELEN))
{
g_free(addr);
return NULL;
}
tmp = addr;
addr = g_strconcat(tmp, "@", hostname, NULL);
g_free(tmp);
}
else /* there's an @ sign already in the email addy */
*ptr2 = '\0'; /* add a null to the end of the string */
return addr;
}
static gboolean
smtp_helo (CamelSmtpTransport *transport, CamelException *ex)
{
/* say hello to the server */
gchar *cmdbuf, *respbuf = NULL;
gchar localhost[MAXHOSTNAMELEN + MAXHOSTNAMELEN + 2];
gchar domainname[MAXHOSTNAMELEN];
gint n;
/* get the localhost name */
memset(localhost, 0, sizeof(localhost));
gethostname (localhost, MAXHOSTNAMELEN);
memset(domainname, 0, sizeof(domainname));
getdomainname(domainname, MAXHOSTNAMELEN);
if (*domainname && strcmp(domainname, "(none)"))
{
strcat(localhost, ".");
strcat(localhost, domainname);
}
/* hiya server! how are you today? */
cmdbuf = g_strdup_printf ("HELO %s\r\n", localhost);
if ( camel_stream_write (transport->ostream, cmdbuf, strlen(cmdbuf)) == -1)
{
g_free(cmdbuf);
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
"HELO request timed out: "
"%s: non-fatal",
g_strerror (errno));
return FALSE;
}
g_free(cmdbuf);
do
{
/* Check for "250" */
g_free(respbuf);
respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (transport->istream));
if ( !respbuf || strncmp(respbuf, "250", 3) )
{
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
"HELO response error: "
"%s: non-fatal",
g_strerror (errno));
return FALSE;
}
} while ( *(respbuf+3) == '-' ); /* if we got "250-" then loop again */
g_free(respbuf);
return TRUE;
}
static gboolean
smtp_mail (CamelSmtpTransport *transport, gchar *sender, CamelException *ex)
{
/* we gotta tell the smtp server who we are. (our email addy) */
gchar *cmdbuf, *respbuf = NULL;
/* enclose address in <>'s since some SMTP daemons *require* that */
cmdbuf = g_strdup_printf("MAIL FROM: <%s>\r\n", sender);
if ( camel_stream_write (transport->ostream, cmdbuf, strlen(cmdbuf)) == -1)
{
g_free(cmdbuf);
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
"MAIL FROM request timed out: "
"%s: mail not sent",
g_strerror (errno));
return FALSE;
}
g_free(cmdbuf);
do
{
/* Check for "250 Sender OK..." */
g_free(respbuf);
respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (transport->istream));
if ( !respbuf || strncmp(respbuf, "250", 3) )
{
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
"MAIL FROM response error: "
"%s: mail not sent",
g_strerror (errno));
return FALSE;
}
} while ( *(respbuf+3) == '-' ); /* if we got "250-" then loop again */
g_free(respbuf);
return TRUE;
}
static gboolean
smtp_rcpt (CamelSmtpTransport *transport, gchar *recipient, CamelException *ex)
{
/* we gotta tell the smtp server who we are going to be sending
* our email to */
gchar *cmdbuf, *respbuf = NULL;
/* enclose address in <>'s since some SMTP daemons *require* that */
cmdbuf = g_strdup_printf("RCPT TO: <%s>\r\n", recipient);
if ( camel_stream_write (transport->ostream, cmdbuf, strlen(cmdbuf)) == -1)
{
g_free(cmdbuf);
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
"RCPT TO request timed out: "
"%s: mail not sent",
g_strerror (errno));
return FALSE;
}
g_free(cmdbuf);
do
{
/* Check for "250 Sender OK..." */
g_free(respbuf);
respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (transport->istream));
if ( !respbuf || strncmp(respbuf, "250", 3) )
{
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
"RCPT TO response error: "
"%s: mail not sent",
g_strerror (errno));
return FALSE;
}
} while ( *(respbuf+3) == '-' ); /* if we got "250-" then loop again */
g_free(respbuf);
return TRUE;
}
static gboolean
smtp_data (CamelSmtpTransport *transport, gchar *message, CamelException *ex)
{
/* now we can actually send what's important :p */
gchar *cmdbuf, *respbuf = NULL;
gchar *tmp, *chunk, *begin, *end;
/* enclose address in <>'s since some SMTP daemons *require* that */
cmdbuf = g_strdup("DATA\r\n");
if ( camel_stream_write (transport->ostream, cmdbuf, strlen(cmdbuf)) == -1)
{
g_free(cmdbuf);
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
"DATA request timed out: "
"%s: mail not sent",
g_strerror (errno));
return FALSE;
}
g_free(cmdbuf);
respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (transport->istream));
if ( !respbuf || strncmp(respbuf, "354", 3) )
{
/* we should have gotten instructions on how to use the DATA command:
* 354 Enter mail, end with "." on a line by itself
*/
g_free(respbuf);
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
"DATA response error: "
"%s: mail not sent",
g_strerror (errno));
return FALSE;
}
/* now to send the actual data */
for (begin = message; *begin; begin++)
{
/* send 1 line at a time */
for (end = begin; *end && *end != '\n'; end++);
end--;
tmp = g_strndup(begin, (gint)(end - begin));
/* check for a lone '.' */
if (!strcmp(tmp, "."))
chunk = g_strconcat(tmp, ".\r\n", NULL);
else
chunk = g_strconcat(tmp, "\r\n", NULL);
g_free(tmp);
/* write the line */
if ( camel_stream_write (transport->ostream, chunk, strlen(chunk)) == -1)
{
g_free(chunk);
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
"DATA send timed out: message body: "
"%s: mail not sent",
g_strerror (errno));
return FALSE;
}
g_free(chunk);
}
/* terminate the message body */
if ( camel_stream_write (transport->ostream, "\r\n.\r\n", 5) == -1)
{
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
"DATA send timed out: message termination: "
"%s: mail not sent",
g_strerror (errno));
return FALSE;
}
do
{
/* Check for "250 Sender OK..." */
g_free(respbuf);
respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (transport->istream));
if ( !respbuf || strncmp(respbuf, "250", 3) )
{
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
"DATA response error: message termination: "
"%s: mail not sent",
g_strerror (errno));
return FALSE;
}
} while ( *(respbuf+3) == '-' ); /* if we got "250-" then loop again */
g_free(respbuf);
return TRUE;
}
static gboolean
smtp_rset (CamelSmtpTransport *transport, CamelException *ex)
{
/* we are going to reset the smtp server (just to be nice) */
gchar *cmdbuf, *respbuf = NULL;
cmdbuf = g_strdup ("RSET\r\n");
if ( camel_stream_write (transport->ostream, cmdbuf, strlen(cmdbuf)) == -1)
{
g_free(cmdbuf);
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
"RSET request timed out: "
"%s",
g_strerror (errno));
return FALSE;
}
g_free(cmdbuf);
do
{
/* Check for "250" */
g_free(respbuf);
respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (transport->istream));
if ( !respbuf || strncmp(respbuf, "250", 3) )
{
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
"RSET response error: "
"%s",
g_strerror (errno));
return FALSE;
}
} while ( *(respbuf+3) == '-' ); /* if we got "250-" then loop again */
g_free(respbuf);
return TRUE;
}
static gboolean
smtp_quit (CamelSmtpTransport *transport, CamelException *ex)
{
/* we are going to reset the smtp server (just to be nice) */
gchar *cmdbuf, *respbuf = NULL;
cmdbuf = g_strdup ("QUIT\r\n");
if ( camel_stream_write (transport->ostream, cmdbuf, strlen(cmdbuf)) == -1)
{
g_free(cmdbuf);
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
"QUIT request timed out: "
"%s: non-fatal",
g_strerror (errno));
return FALSE;
}
g_free(cmdbuf);
do
{
/* Check for "221" */
g_free(respbuf);
respbuf = camel_stream_buffer_read_line (CAMEL_STREAM_BUFFER (transport->istream));
if ( !respbuf || strncmp(respbuf, "221", 3) )
{
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
"QUIT response error: "
"%s: non-fatal",
g_strerror (errno));
return FALSE;
}
} while ( *(respbuf+3) == '-' ); /* if we got "221-" then loop again */
g_free(respbuf);
return TRUE;
}

View File

@ -0,0 +1,68 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/* camel-smtp-transport.h : class for an smtp transfer */
/*
* Authors:
* Jeffrey Stedfast <fejj@stampede.org>
*
* Copyright (C) 2000 Helix Code, Inc. (www.helixcode.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*/
#ifndef CAMEL_SMTP_TRANSPORT_H
#define CAMEL_SMTP_TRANSPORT_H 1
#ifdef __cplusplus
extern "C" {
#pragma }
#endif /* __cplusplus }*/
#include "camel-transport.h"
#define CAMEL_SMTP_TRANSPORT_TYPE (camel_smtp_transport_get_type ())
#define CAMEL_SMTP_TRANSPORT(obj) (GTK_CHECK_CAST((obj), CAMEL_SMTP_TRANSPORT_TYPE, CamelSmtpTransport))
#define CAMEL_SMTP_TRANSPORT_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), CAMEL_SMTP_TRANSPORT_TYPE, CamelSmtpTransportClass))
#define IS_CAMEL_SMTP_TRANSPORT(o) (GTK_CHECK_TYPE((o), CAMEL_SMTP_TRANSPORT_TYPE))
typedef struct {
CamelTransport parent_object;
CamelStream *istream, *ostream;
} CamelSmtpTransport;
typedef struct {
CamelTransferClass parent_class;
} CamelSmtpTransportClass;
/* Standard Gtk function */
GtkType camel_smtp_transport_get_type (void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* CAMEL_SMTP_TRANSPORT_H */