libsmtp
API User Manual
Version 1.0.01
|
Version |
Date |
Change Log |
|
V1.0.00 |
2008/12/05 |
1. Document created |
|
V1.0.01 |
2009/01/08 |
1. Specify the environment tested |
|
V1.0.02 |
2011/02/23 |
1. Add libsmtp_multipart_end API 2. Update example code |
Description
Libsmtp allows programs to send mail directly through
SMTP (no sendmail needed) and attaching and encoding
mail in MIME standards. It is licensed under the LGPL. It is designed to be
simple, secure, and small. It can send mail to multiple recipients in one go,
and supports sending to CC and BCC recipients too. The
development version has support for attachments (this being multiple body
parts), different character sets and transport encodings.
This document introduces the wrapped APIs which
support a friendly interface to send email can easier. This document provides
an example and a figure of Calls Flow for user to understand how to use these
APIs.
Requirements
Glib 1.2.0
(Build perquisite)
Please
install above glib 1.2.0 library before using libsmtp
library.
libsmtp_session_initialize
Initialize
the session structure.
<SYNOPSIS>
#include <libsmtp.h>
struct libsmtp_session_struct
*libsmtp_session_initialize(void);
<DESCRIPTION>
What you should setup before you initiate a
connection .Use
this function to initialize the session structure. This will malloc memory and initialize the structure's GStrings and GLists. Please be
sure to clean the initialized struct up with libsmtp_free after you finish using it. Session data is saved in a struct pointer that is passed between all functions, so
that you can have multiple sessions running at any one time.This
is the definition of the struct:
struct libsmtp_session_struct
{
int
serverflags; /* Server capability flags */
int
socket; /* socket handle */
/* authorization */
int
server_auth, auth_type;
GString
*username;
GString
*password;
unsigned short
pop3port;
GString
*pop3server;
GString *From; /* From address */
GList *To; /* All recipients addresses */
GList *CC; /* All Carbon Copy recipients addresses */
GList *BCC; /* All Blind Carbon Copy recipients addresses */
int
NumFailedTo; /* number of rejected recipients */
int
NumFailedCC; /* number of rejected CC recipients */
int
NumFailedBCC; /* number of rejected BCC recipients */
GList *ToResponse; /* List of failed recipients containing the response for
each failure */
GList *CCResponse; /* The same for CC recipients */
GList *BCCResponse; /* And for BCC recipients */
GString
*Subject; /* Mail subject */
GString *LastResponse; /* Last SMTP response string from server */
int
LastResponseCode; /* Last SMTP response code from server */
int
ErrorCode; /* Internal libsmtp error code
from last error */
GString *ErrorModule; /* Module were error was caused */
int
Stage; /* SMTP transfer stage */
unsigned int DialogueSent; /* Number of SMTP dialogue lines sent */
unsigned int DialogueBytes; /* Bytes of SMTP dialogue data sent */
unsigned int HeadersSent; /* Number of header lines sent */
unsigned int HeaderBytes; /* Bytes of header data sent */
unsigned long int BodyBytes; /* Bytes of body data sent */
#ifdef WITH_MIME
GNode
*Parts; /* N-Tree of body parts (MIME stuff) */
int NumParts; /* Number of body parts */
struct libsmtp_part_struct
*PartNow; /* Part we are sending now */
GNode
*PartNowNode; /* Node of the part we are just sending */
struct libsmtp_part_struct
* mainpart; /* main part
header */
#endif
};
<PARAMETERS>
None
<RETURN VALUE>
libsmtp_session_initialize() returns the session structure pointer to the newly
allocated memory, or NULL if the request fails.
libsmtp_set_environment
<SYNOPSIS>
#include < libsmtp.h>
int libsmtp_set_environment
(char *libsmtp_int_From, char *libsmtp_int_Subject,
unsigned int libsmtp_int_flags,
struct libsmtp_session_struct
*libsmtp_session)
<DESCRIPTION>
With this
function you can set additional session parameters for this session. This
should be set before the dialogue is begun.
<PARAMETERS>
libsmtp_int_From
Address of the sender
libsmtp_int_Subject
Subject line of message
libsmtp_int_flags
libsmtp_int_flags doesn't have any meaning at the moment.
libsmtp_session
A handle returned by libsmtp_session_initialize ().
<RETURN VALUE>
Returns: 0 for success (see libsmtp_errno)
libsmtp_set_authorization
Enable
authentication and optionally choose the method.
<SYNOPSIS>
#include < libsmtp.h>
int libsmtp_set_authorization(unsigned
int Auth_type, char *auth_username, char *auth_password,
unsigned short pop_port, char *pop_server,
struct libsmtp_session_struct
*libsmtp_session)
<DESCRIPTION>
With this function you can set about
authorize parameters for this session.
<PARAMETERS>
Auth_type
Set the SMTP authentication type, we support five authentication methods, see below
typedef enum {
NO_AUTH,
LOGIN,
PLAIN,
CRAM_MD5,
DIGEST_MD5,
POP_RELAY
} AUTH_TYPE;
auth_username
Specify
username for SMTP authentication
auth_password
Specify
password for SMTP authentication
pop_port
Specify
POP server port, if SMTP AUTH is POP-Relay
pop_server
Specify
POP server address, if SMTP AUTH is POP-Relay
libsmtp_session
A handle returned by libsmtp_session_initialize ().
<RETURN VALUE>
Returns: 0 for success (see libsmtp_errno)
libsmtp_add_recipient
Add the address to the recipient of this session
<SYNOPSIS>
#include < libsmtp.h>
int libsmtp_add_recipient
(int libsmtp_int_rec_type,
char *libsmtp_int_address,
struct libsmtp_session_struct
*libsmtp_session)
<DESCRIPTION>
This
function will add the address to the recipient of this session. This will be
added to the linked list internally.
An address must be of the RFC822-compliant type.
<PARAMETERS>
libsmtp_int_rec_type
libsmtp_int_rec_type may be one of LIBSMTP_REC_TO, LIBSMTP_REC_CC, LIBSMTP_REC_BCC.
libsmtp_int_address
Specify
the address to the recipient.
libsmtp_session
A handle returned by libsmtp_session_initialize ().
<RETURN VALUE>
Returns: 0 for success,
otherwise see libsmtp_errno.
libsmtp_connect
Connect to a mail server.
<SYNOPSIS>
#include < libsmtp.h>
int libsmtp_connect
(char *libsmtp_server, unsigned int
libsmtp_port, int wait_timeout,
struct
libsmtp_session_struct *libsmtp_session)
<DESCRIPTION>
After
initial setup is done for a session, you can use this function to connect to a mail server. The
string server can either be a hostname or an IP address. Port can be left at 0,
then the default SMTP port (25) can be used. The libsmtp_session_struct should be initialized beforehand.
Please be sure to clean up with libsmtp_free. Set a
timeout limit for a connecting device that stops responding after having
initiated the TCP handshake process. If an expected handshake response is not
received from the connecting device in this amount of time, an error occurs.
<PARAMETERS>
libsmtp_server
Specify SMTP server address
libsmtp_port
Specify SMTP server port
wait_timeout
Set
connection handshake timeout in seconds.
libsmtp_session
A handle returned by libsmtp_session_initialize ().
<RETURN VALUE>
A libsmtp_errno
error code or 0 for success.
libsmtp_dialogue
Use
this function to make libsmtp run the SMTP dialogue.
<SYNOPSIS>
#include < libsmtp.h>
int libsmtp_dialogue
(struct libsmtp_session_struct
*libsmtp_session)
<DESCRIPTION>
This function will handle the SMTP dialogue for you.
The SMTP response minus response code can be read from the libsmtp_session->LastResponse string (which is a GString!)
<PARAMETERS>
libsmtp_session
A handle returned by libsmtp_session_initialize ().
<RETURN VALUE>
A libsmtp_errno
error code or 0 for success.
libsmtp_headers
Send
the headers
<SYNOPSIS>
#include < libsmtp.h>
int libsmtp_headers (struct
libsmtp_session_struct *libsmtp_session)
<DESCRIPTION>
<PARAMETERS>
libsmtp_session
A handle returned by libsmtp_session_initialize ().
<RETURN VALUE>
A libsmtp_errno
error code or 0 for success.
libsmtp_send_notify_message
Send the notify message
<SYNOPSIS>
#include < libsmtp.h>
int libsmtp_send_notify_message(char
*message, struct libsmtp_session_struct
*mailsession)
<DESCRIPTION>
Dialogue stage finishes beginning to send the content
of mails. This function only send notify message, and default Content-Type is
text/plain, text encoding type using 7bit code encoder.
<PARAMETERS>
message
specify body data
libsmtp_session
A handle returned by libsmtp_session_initialize ().
<RETURN VALUE>
A libsmtp_errno
error code or 0 for success.
libsmtp_send_bdata
Send
the data of binary format
<SYNOPSIS>
#include < libsmtp.h>
int libsmtp_send_bdata(int mime_type, int mime_subtype , char *udname, char *rawdata, int size,
struct
libsmtp_session_struct *mailsession)
<DESCRIPTION>
Dialogue stage finishes beginning to send the content
of mails. This function only send binary format data
via memory address and support multipart type of MIME & base64 encoder.
<PARAMETERS>
mime_type
#define LIBSMTP_MIME_TEXT 0
#define LIBSMTP_MIME_MESSAGE 1
#define LIBSMTP_MIME_IMAGE 2
#define LIBSMTP_MIME_AUDIO 3
#define LIBSMTP_MIME_VIDEO 4
#define
LIBSMTP_MIME_APPLICATION 5
#define
LIBSMTP_MIME_MULTIPART 6
#define LIBSMTP_MIME_CUSTOM 7
mime_subtype
/* 0
to 999 are TEXT subtypes */
#define
LIBSMTP_MIME_SUB_PLAIN 0
#define
LIBSMTP_MIME_SUB_HTML 1
#define
LIBSMTP_MIME_SUB_ENGLISH 2
#define
LIBSMTP_MIME_SUB_RICHTEXT 3
/*
1000 to 1999 are MESSAGE subtypes */
#define LIBSMTP_MIME_SUB_RFC822 1000
#define
LIBSMTP_MIME_SUB_PARTIAL 1001
/*
2000 to 2999 are IMAGE subtypes */
#define LIBSMTP_MIME_SUB_GIF 2000
#define LIBSMTP_MIME_SUB_JPG 2001
#define LIBSMTP_MIME_SUB_PNG 2002
#define
LIBSMTP_MIME_SUB_TIFF 2003
#define
LIBSMTP_MIME_SUB_MS_BMP 2004
#define
LIBSMTP_MIME_SUB_XBITMAP 2005
#define
LIBSMTP_MIME_SUB_XPIXMAP 2006
#define
LIBSMTP_MIME_SUB_PORTABLE_ANYMAP 2007
#define
LIBSMTP_MIME_SUB_PORTABLE_BITMAP 2008
#define
LIBSMTP_MIME_SUB_PORTABLE_GRAYMAP 2009
#define
LIBSMTP_MIME_SUB_PORTABLE_PIXMAP 2010
/*
3000 to 3999 are AUDIO subtypes */
#define
LIBSMTP_MIME_SUB_MPEGAUD 3000
#define
LIBSMTP_MIME_SUB_MIDI 3001
#define LIBSMTP_MIME_SUB_WAV 3002
#define
LIBSMTP_MIME_SUB_AIFF 3003
/*
4000 to 4999 are VIDEO subtypes */
#define
LIBSMTP_MIME_SUB_MPEGVID 4000
#define
LIBSMTP_MIME_SUB_MSVIDEO 4001
#define
LIBSMTP_MIME_SUB_QUICKTIME 4002
#define LIBSMTP_MIME_SUB_FLI 4003
/* 5000
to 5999 are APPLICATION subtypes */
#define LIBSMTP_MIME_SUB_RTF 5000
#define
LIBSMTP_MIME_SUB_POSTSCRIPT 5001
#define LIBSMTP_MIME_SUB_PDF 5002
#define LIBSMTP_MIME_SUB_ZIP 5003
#define
LIBSMTP_MIME_SUB_DEBIAN_PACKAGE 5004
#define
LIBSMTP_MIME_SUB_EXECUTABLE 5005
#define
LIBSMTP_MIME_SUB_GTAR 5006
#define
LIBSMTP_MIME_SUB_SHELLSCRIPT 5007
#define LIBSMTP_MIME_SUB_TAR 5008
#define
LIBSMTP_MIME_SUB_OCTET_STREAM 5009
/*
6000 to 6999 are MULTIPART subtypes */
#define LIBSMTP_MIME_SUB_MIXED 6000
#define
LIBSMTP_MIME_SUB_PARALLEL 6001
#define
LIBSMTP_MIME_SUB_DIGEST 6002
#define
LIBSMTP_MIME_SUB_ALTERNATIVE 6003
udname
Attached
file name
rawdata
A pointer to a memory address which you
want to send data
size
data size
libsmtp_session
A handle returned by libsmtp_session_initialize ().
<RETURN VALUE>
A libsmtp_errno
error code or 0 for success.
libsmtp_multipart_header
Ready to send multipart/mixed type header of MIME
<SYNOPSIS>
#include < libsmtp.h>
#include < libsmtp_mime.h>
int libsmtp_multipart_header
(struct libsmtp_session_struct
*mailsession)
<DESCRIPTION>
Dialogue stage finishes beginning to send the content
of mails. If you want to send multipart/mixed
type of MIME, libsmtp_multipart_header() must be call it first, it will
be send a complete and
standard mime parent header.
<PARAMETERS>
libsmtp_session
A handle returned by libsmtp_session_initialize ().
<RETURN VALUE>
A libsmtp_errno
error code or 0 for success.
libsmtp_send_multipart
Send content of multipart.
<SYNOPSIS>
#include < libsmtp.h>
#include < libsmtp_mime.h>
int libsmtp_send_multipart(int libsmtp_int_type, int libsmtp_int_subtype, int libsmtp_int_encoding,
int libsmtp_int_charset,
char * udname, char *snddata, int datasize,
struct libsmtp_session_struct
*mailsession)
<DESCRIPTION>
If you want to send the content of many kinds of
different format or many images, you can call libsmtp_send_multipart() many times.
<PARAMETERS>
libsmtp_int_type
Refer libsmtp_send_bdata() mime_type parameters
libsmtp_int_subtype
Refer libsmtp_send_bdata() mime_subtype parameters
libsmtp_int_encoding
/* Encoding types */
#define
LIBSMTP_ENC_7BIT 0
#define
LIBSMTP_ENC_BASE64 3
libsmtp_int_charset
/* Charset values */
#define
LIBSMTP_CHARSET_NOCHARSET -1
#define
LIBSMTP_CHARSET_USASCII 0
#define
LIBSMTP_CHARSET_ISO8859_1 1
#define
LIBSMTP_CHARSET_ISO8859_2 2
#define
LIBSMTP_CHARSET_ISO8859_3 3
udname
Attached
file name
snddata
A pointer to a memory address which you
want to send data
datasize
Data
length or size
libsmtp_session
A handle returned by libsmtp_session_initialize ().
<RETURN VALUE>
A libsmtp_errno
error code or 0 for success.
libsmtp_multipart_end
Free
memory the parent part of the multipart format
<SYNOPSIS>
#include < libsmtp.h>
void libsmtp_multipart_end
(struct libsmtp_session_struct
*libsmtp_session)
<DESCRIPTION>
When perform the libsmtp_send_multipart() completed, must call
this function to free memory the parent part of the multipart format.
<PARAMETERS>
libsmtp_session
A handle returned by libsmtp_session_initialize ().
libsmtp_body_end
This
ends the body part
<SYNOPSIS>
#include < libsmtp.h>
int libsmtp_body_end (struct libsmtp_session_struct *libsmtp_session)
<DESCRIPTION>
This function ends the body part. It can only be used
in certain stages
<PARAMETERS>
libsmtp_session
A handle returned by libsmtp_session_initialize ().
<RETURN VALUE>
A libsmtp_errno
error code or 0 for success.
libsmtp_quit
This
ends the connection gracefully
<SYNOPSIS>
#include < libsmtp.h>
int libsmtp_quit
(struct libsmtp_session_struct
*libsmtp_session)
<DESCRIPTION>
This function ends the SMTP session. It can only be used
in certain stages, notably in all dialogue modes.
<PARAMETERS>
libsmtp_session
A handle returned by libsmtp_session_initialize ().
<RETURN VALUE>
A libsmtp_errno
error code or 0 for success.
libsmtp_close
Close
the SMTP connection
<SYNOPSIS>
#include < libsmtp.h>
int libsmtp_close
(struct libsmtp_session_struct
*libsmtp_session)
<DESCRIPTION>
This function will close the SMTP connection.
<PARAMETERS>
libsmtp_session
A handle returned by libsmtp_session_initialize ().
<RETURN VALUE>
A libsmtp_errno
error code or 0 for success.
libsmtp_free
Frees
the allocated session structure memory
<SYNOPSIS>
#include < libsmtp.h>
int libsmtp_free
(struct libsmtp_session_struct
* libsmtp_session);
<DESCRIPTION>
Use
this to free the session structure. You should do this to clean up memory
usage.
<PARAMETERS>
libsmtp_session
A handle returned by libsmtp_session_initialize ().
<RETURN VALUE>
Returns: 0 for success (see libsmtp_errno)
Client Server
Calls Flow

Testing Environments
Test case 1:
SMTP Server: smtp.pchome.com.tw
The
server support authorization: DIGEST-MD5, CRAM-MD5, PLAIN, LOGIN
Sender:
<USERACCOUNT>@pchome.com.tw
|
Step |
Expected Result |
Actual
Result (if different from expected) |
|
Authentication mechanism: DIGEST-MD5 |
235 Authentication successful |
|
|
Authentication mechanism: CRAM-MD5 |
235 Authentication successful |
|
|
Authentication mechanism: PLAIN |
235 Authentication successful |
|
|
Authentication mechanism: LOGIN |
235 Authentication successful |
|
|
Authentication mechanism: POP_RELAY |
501 Syntax error in parameter or arguments. |
|
Test case 2:
SMTP
Server: smtp.acti.com
The server
support authorization: LOGIN
Sender:
<USERACCOUNT>@acti.com
|
Step |
Expected Result |
Actual
Result (if different from expected) |
|
Authentication mechanism: LOGIN |
235 Authentication successful |
|
|
Authentication mechanism: DIGEST-MD5 |
501 Syntax error in parameter or arguments. |
|
|
Authentication mechanism: CRAM-MD5 |
501 Syntax error in parameter or arguments. |
|
|
Authentication mechanism: PLAIN |
501 Syntax error in parameter or arguments. |
|
|
Authentication mechanism: POP_RELAY |
501 Syntax error in parameter or arguments. |
|
Example
int main(void)
{
unsigned
char *jpegbuffer, sender[64], subject[64], notify_message[128];
unsigned
char server[64], to[64], user[64], password[64];
char vbuff[1024*1000];
int
fd, rcv_vbuffsz, auth;
struct
libsmtp_part_struct *mutlipart;
/* This
struct holds all session data. You need one per mail
server
connection */
struct libsmtp_session_struct
*mailsession;
struct libsmtp_part_struct
*mainpart;
sprintf(subject,
"SENDMAIL: multipart test");
strcpy(sender,
"cathy.chiang@acti.com");
strcpy(server,
"smtp.acti.com");
strcpy(user,
"cathy.chiang@acti.com");
strcpy(password, "123456");
sprintf(to, “cathy.chiang@acti.com;cathys516@gmail.com”);
auth
= LOGIN;
/* This
mallocs the structs mem and initializes variables in it */
mailsession = libsmtp_session_initialize();
if (mailsession == NULL) {
printf("Low
memory....\n");
return -1;
}
/* Set session environment
(from address, subject) */
if
(libsmtp_set_environment (sender, subject, 0, mailsession)) {
libsmtp_free (mailsession);
return mailsession->ErrorCode;
}
#if HAVE_AUTH
if (libsmtp_set_authorization(auth, user, password, 110,
"msa.hinet.net", mailsession)) {
libsmtp_free (mailsession);
return mailsession->ErrorCode;
}
#endif
/* Now we add some
recipients */
libsmtp_add_recipient
(LIBSMTP_REC_TO, to, mailsession);
/* This
starts the SMTP connection */
if
(libsmtp_connect (server, 0, 10, mailsession))
{
libsmtp_free (mailsession);
return mailsession->ErrorCode;
}
printf ("SMTP connection running.\n");
/* This
will conduct the SMTP dialogue */
if
(libsmtp_dialogue (mailsession))
{
libsmtp_free (mailsession);
return mailsession->ErrorCode;
}
printf ("Dialogue finished.\n");
/*
Now lets send the headers - you can send your own
headers too */
if (libsmtp_headers (mailsession)) {
libsmtp_free (mailsession);
return mailsession->ErrorCode;
}
printf ("SMTP headers
sent.\n");
#ifdef
SEND_MIME_TEXTPLAIN
/* This
sends a line of message body */
sprintf(notify_message, "test libsmtp_send_singlepart
by cathy");
if (libsmtp_send_notify_message(notify_message,
mailsession)) {
libsmtp_free (mailsession);
return mailsession->ErrorCode;
}
#endif
fd = open("/var/www/images/test.jpg", O_RDWR);
rcv_vbuffsz = read(fd, vbuff, sizeof(vbuff));
printf("
image size = %d\n", rcv_vbuffsz);
#ifdef
SEND_MIME_BINARY_DATA
if (libsmtp_send_bdata(LIBSMTP_MIME_APPLICATION,
LIBSMTP_MIME_SUB_ZIP, \
"imagexx.jpg", vbuff, rcv_vbuffsz, mailsession)) {
libsmtp_free
(mailsession);
return mailsession->ErrorCode;
}
#endif
#ifdef
SEND_MIME_MIXED
libsmtp_multipart_header(mailsession);
sprintf(notify_message, "test libsmtp_send_singlepart
by cathy");
libsmtp_send_multipart(LIBSMTP_MIME_TEXT, LIBSMTP_MIME_SUB_PLAIN,
LIBSMTP_ENC_7BIT,
LIBSMTP_CHARSET_USASCII,NULL,notify_message, strlen(notify_message),mailsession );
libsmtp_send_multipart(LIBSMTP_MIME_IMAGE, LIBSMTP_MIME_SUB_JPG,
LIBSMTP_ENC_BASE64,
LIBSMTP_CHARSET_NOCHARSET,"a.jpg",vbuff, rcv_vbuffsz,mailsession
);
libsmtp_send_multipart(LIBSMTP_MIME_IMAGE, LIBSMTP_MIME_SUB_JPG,
LIBSMTP_ENC_BASE64,
LIBSMTP_CHARSET_NOCHARSET,"b.jpg",vbuff, rcv_vbuffsz,mailsession
);
libsmtp_send_multipart(LIBSMTP_MIME_IMAGE, LIBSMTP_MIME_SUB_JPG,
LIBSMTP_ENC_BASE64,
LIBSMTP_CHARSET_NOCHARSET,"c.jpg",vbuff, rcv_vbuffsz,mailsession
);
Libsmtp_multipart_end(mailsession);
#endif
close(fd);
/*
This ends the body part */
if (libsmtp_body_end (mailsession))
{
libsmtp_free
(mailsession);
return mailsession->ErrorCode;
}
/* This ends
the connection gracefully */
libsmtp_quit (mailsession);
/* Free the
allocated struct mem */
libsmtp_free (mailsession);
return 0;
}
Reference
http://freshmeat.net/redir/libsmtp/5725/url_homepage/libsmtp.berlios.de
http://www.linuxfromscratch.org/blfs/view/6.1/general/glib.html