[GB.NET.SMTP]

* NEW: Support for any mime type and any charset in SmtpClient.


git-svn-id: svn://localhost/gambas/trunk@3954 867c0c6c-44f3-4631-809d-bfa615b0a4ec
This commit is contained in:
Benoît Minisini 2011-07-29 23:19:51 +00:00
parent 4d13341c3e
commit 0b51c634ff
5 changed files with 114 additions and 589 deletions

View File

@ -29,88 +29,14 @@
static char *_tmp = NULL;
typedef
struct {
char *constant;
int value;
}
MIME_FIND;
static MIME_FIND _types[] =
{
{ "text", LIBSMTP_MIME_TEXT },
{ "message", LIBSMTP_MIME_MESSAGE },
{ "image", LIBSMTP_MIME_IMAGE },
{ "audio", LIBSMTP_MIME_AUDIO },
{ "video", LIBSMTP_MIME_VIDEO },
{ "application", LIBSMTP_MIME_APPLICATION },
{ "multipart", LIBSMTP_MIME_MULTIPART },
{ "custom!!", LIBSMTP_MIME_CUSTOM },
{ "plain", LIBSMTP_MIME_SUB_PLAIN },
{ "html", LIBSMTP_MIME_SUB_HTML },
{ "english", LIBSMTP_MIME_SUB_ENGLISH },
{ "richtext", LIBSMTP_MIME_SUB_RICHTEXT },
{ "rfc822", LIBSMTP_MIME_SUB_RFC822 },
{ "partial", LIBSMTP_MIME_SUB_PARTIAL },
{ "gif", LIBSMTP_MIME_SUB_GIF },
{ "jpeg", LIBSMTP_MIME_SUB_JPG },
{ "png", LIBSMTP_MIME_SUB_PNG },
{ "tiff", LIBSMTP_MIME_SUB_TIFF },
{ "x-ms-bmp", LIBSMTP_MIME_SUB_MS_BMP },
{ "x-xbitmap", LIBSMTP_MIME_SUB_XBITMAP },
{ "x-xpixmap", LIBSMTP_MIME_SUB_XPIXMAP },
{ "x-portable-anymap", LIBSMTP_MIME_SUB_PORTABLE_ANYMAP },
{ "x-portable-bitmap", LIBSMTP_MIME_SUB_PORTABLE_BITMAP },
{ "x-portable-graymap", LIBSMTP_MIME_SUB_PORTABLE_GRAYMAP },
{ "x-portable-pixmap", LIBSMTP_MIME_SUB_PORTABLE_PIXMAP },
{ "mpeg", LIBSMTP_MIME_SUB_MPEGAUD },
{ "midi", LIBSMTP_MIME_SUB_MIDI },
{ "x-wav", LIBSMTP_MIME_SUB_WAV },
{ "x-aiff", LIBSMTP_MIME_SUB_AIFF },
{ "mpeg", LIBSMTP_MIME_SUB_MPEGVID },
{ "x-ms-video", LIBSMTP_MIME_SUB_MSVIDEO },
{ "quicktime", LIBSMTP_MIME_SUB_QUICKTIME },
{ "fli", LIBSMTP_MIME_SUB_FLI },
{ "rtf", LIBSMTP_MIME_SUB_RTF },
{ "postscript", LIBSMTP_MIME_SUB_POSTSCRIPT },
{ "pdf", LIBSMTP_MIME_SUB_PDF },
{ "zip", LIBSMTP_MIME_SUB_ZIP },
{ "x-debian-package", LIBSMTP_MIME_SUB_DEBIAN_PACKAGE },
{ "x-executable", LIBSMTP_MIME_SUB_EXECUTABLE },
{ "x-gtar", LIBSMTP_MIME_SUB_GTAR },
{ "x-shellscript", LIBSMTP_MIME_SUB_SHELLSCRIPT },
{ "x-tar", LIBSMTP_MIME_SUB_TAR },
{ "octet-stream", LIBSMTP_MIME_SUB_OCTET_STREAM },
{ "mixed", LIBSMTP_MIME_SUB_MIXED },
{ "parallel", LIBSMTP_MIME_SUB_PARALLEL },
{ "digest", LIBSMTP_MIME_SUB_DIGEST },
{ "alternative", LIBSMTP_MIME_SUB_ALTERNATIVE },
{ NULL, 0 }
};
static MIME_FIND _charsets[] =
{
{ "us-ascii", LIBSMTP_CHARSET_USASCII },
{ "iso-8859-1", LIBSMTP_CHARSET_ISO8859_1 },
{ "iso-8859-2", LIBSMTP_CHARSET_ISO8859_2 },
{ "iso-8859-3", LIBSMTP_CHARSET_ISO8859_3 },
{ "iso-8859-15", LIBSMTP_CHARSET_ISO8859_15 },
{ "utf-8", LIBSMTP_CHARSET_UTF_8 },
{ NULL, 0 }
};
static char *_mime_type = NULL;
static char *_mime_subtype = NULL;
static char *_mime_charset = NULL;
static int _mime_encoding = 0;
static char *get_address(char *address)
{
long len;
int len;
GB.FreeString(&_tmp);
@ -144,38 +70,21 @@ static bool send_recipient(struct libsmtp_session_struct *session, GB_ARRAY rec,
return FALSE;
}
static int find_constant(MIME_FIND *table, char *str, int len)
{
if (len <= 0)
len = strlen(str);
if (len >= 2 && str[0] == '"' && str[len -1] == '"')
{
str++;
len--;
}
while (table->constant)
{
if (strncasecmp(table->constant, str, len) == 0)
return table->value;
table++;
}
return (-1);
}
static int decode_mime(char *mime, int *type, int *subtype, int *encoding, int *charset)
static int decode_mime(char *mime)
{
char *p, *p2;
*charset = find_constant(_charsets, GB.System.Charset(), 0);
GB.FreeString(&_mime_type);
GB.FreeString(&_mime_subtype);
GB.FreeString(&_mime_charset);
_mime_charset = GB.NewZeroString(GB.System.Charset());
if (!mime || !*mime)
{
*type = LIBSMTP_MIME_TEXT;
*subtype = LIBSMTP_MIME_SUB_PLAIN;
*encoding = LIBSMTP_ENC_QUOTED;
_mime_type = GB.NewZeroString("text");
_mime_subtype = GB.NewZeroString("plain");
_mime_encoding = LIBSMTP_ENC_QUOTED;
return FALSE;
}
@ -187,18 +96,14 @@ static int decode_mime(char *mime, int *type, int *subtype, int *encoding, int *
return TRUE;
}
*type = find_constant(_types, p, p2 - p);
if (*type < 0)
{
GB.Error("Unknown MIME type");
return TRUE;
}
_mime_type = GB.NewString(p, p2 - p);
p = p2 + 1;
p2 = index(p, ';');
if (p2)
{
*subtype = find_constant(_types, p, p2 - p);
_mime_subtype = GB.NewString(p, p2 - p);
p = p2 + 1;
if (strncasecmp(p, "CHARSET=", 8))
{
@ -206,37 +111,23 @@ static int decode_mime(char *mime, int *type, int *subtype, int *encoding, int *
return TRUE;
}
p += 8;
*charset = find_constant(_charsets, p, &mime[strlen(mime)] - p);
_mime_charset = GB.NewString(p, &mime[strlen(mime)] - p);
}
else
{
*subtype = find_constant(_types, p, &mime[strlen(mime)] - p);
_mime_subtype = GB.NewString(p, &mime[strlen(mime)] - p);
}
if (*subtype < 0)
if (!strcmp(_mime_type, "text") || !strcmp(_mime_type, "message"))
{
GB.Error("Unknown MIME subtype");
return TRUE;
}
if (*type == LIBSMTP_MIME_TEXT || *type == LIBSMTP_MIME_MESSAGE)
{
*encoding = LIBSMTP_ENC_QUOTED;
if (*charset < 0)
{
GB.Error("Unknown MIME charset");
return TRUE;
}
_mime_encoding = LIBSMTP_ENC_QUOTED;
}
else
{
*charset = LIBSMTP_CHARSET_NOCHARSET;
if (*type == LIBSMTP_MIME_MULTIPART)
*encoding = LIBSMTP_ENC_7BIT;
if (!strcmp(_mime_type, "multipart"))
_mime_encoding = LIBSMTP_ENC_7BIT;
else
*encoding = LIBSMTP_ENC_BASE64;
_mime_encoding = LIBSMTP_ENC_BASE64;
}
return FALSE;
@ -304,7 +195,6 @@ static bool begin_session(CSMTPCLIENT *_object)
int parent;
struct libsmtp_part_struct *parent_part;
int i;
int type, subtype, encoding, charset;
char buffer[24];
char *name;
@ -333,7 +223,7 @@ static bool begin_session(CSMTPCLIENT *_object)
{
p = &THIS->parts[0];
if (decode_mime(p->mime, &type, &subtype, &encoding, &charset))
if (decode_mime(p->mime))
return TRUE;
name = p->name;
@ -342,7 +232,7 @@ static bool begin_session(CSMTPCLIENT *_object)
parent_part = NULL;
part = libsmtp_part_new(parent_part, type, subtype, encoding, charset, name, -1, THIS->session);
part = libsmtp_part_new(parent_part, _mime_type, _mime_subtype, _mime_encoding, _mime_charset, name, -1, THIS->session);
if (!part)
{
GB.Error("Cannot add part: &1", libsmtp_strerr(THIS->session));
@ -361,14 +251,14 @@ static bool begin_session(CSMTPCLIENT *_object)
for (i = 0; i < npart; i++)
{
if (decode_mime(THIS->parts[i].mime, &type, &subtype, &encoding, &charset))
if (decode_mime(THIS->parts[i].mime))
return TRUE;
}
if (THIS->alternative)
main_part = libsmtp_part_new(NULL, LIBSMTP_MIME_MULTIPART, LIBSMTP_MIME_SUB_ALTERNATIVE, LIBSMTP_ENC_7BIT, LIBSMTP_CHARSET_NOCHARSET, "MIME main part", -1, THIS->session);
main_part = libsmtp_part_new(NULL, "multipart", "alternative", LIBSMTP_ENC_7BIT, NULL, "MIME main part", -1, THIS->session);
else
main_part = libsmtp_part_new(NULL, LIBSMTP_MIME_MULTIPART, LIBSMTP_MIME_SUB_MIXED, LIBSMTP_ENC_7BIT, LIBSMTP_CHARSET_NOCHARSET, "MIME main part", -1, THIS->session);
main_part = libsmtp_part_new(NULL, "multipart", "mixed", LIBSMTP_ENC_7BIT, NULL, "MIME main part", -1, THIS->session);
#ifdef DEBUG_ME
fprintf(stderr, "main part = %p alternative = %d\n", main_part, THIS->alternative);
@ -383,7 +273,7 @@ static bool begin_session(CSMTPCLIENT *_object)
parent_part = main_part;
decode_mime(p->mime, &type, &subtype, &encoding, &charset);
decode_mime(p->mime);
name = p->name;
if (!name || !*name)
@ -392,7 +282,7 @@ static bool begin_session(CSMTPCLIENT *_object)
name = buffer;
}
part = libsmtp_part_new(parent_part, type, subtype, encoding, charset, name, -1, THIS->session);
part = libsmtp_part_new(parent_part, _mime_type, _mime_subtype, _mime_encoding, _mime_charset, name, -1, THIS->session);
if (!part)
{
GB.Error("Cannot add part: &1", libsmtp_strerr(THIS->session));
@ -695,12 +585,23 @@ BEGIN_PROPERTY(SmtpClient_NoGreeting)
END_PROPERTY
BEGIN_METHOD_VOID(SmtpClient_exit)
GB.FreeString(&_tmp);
GB.FreeString(&_mime_type);
GB.FreeString(&_mime_subtype);
GB.FreeString(&_mime_charset);
END_METHOD
GB_DESC CSmtpClientDesc[] =
{
GB_DECLARE("_SmtpClient", sizeof(CSMTPCLIENT)),
GB_METHOD("_new", NULL, SmtpClient_new, NULL),
GB_METHOD("_free", NULL, SmtpClient_free, NULL),
GB_STATIC_METHOD("_exit", NULL, SmtpClient_exit, NULL),
GB_PROPERTY("Debug", "b", SmtpClient_Debug),
GB_PROPERTY("_Stream", "Stream", SmtpClient_Stream),

View File

@ -66,9 +66,7 @@ Thu Aug 16 2001 */
int libsmtp_mime_headers (struct libsmtp_session_struct *libsmtp_session)
{
/* If we use the MIME functionality, we need to send some stuff */
int libsmtp_temp;
GString *libsmtp_temp_gstring;
char *libsmtp_temp_string;
struct libsmtp_part_struct *libsmtp_temp_part;
libsmtp_temp_gstring=g_string_new (NULL);
@ -139,18 +137,16 @@ int libsmtp_mime_headers (struct libsmtp_session_struct *libsmtp_session)
libsmtp_temp_part=libsmtp_session->Parts->data;
/* We should check for valied MIME settings first */
if ((libsmtp_temp=libsmtp_int_check_part (libsmtp_temp_part)))
/*if ((libsmtp_temp=libsmtp_int_check_part (libsmtp_temp_part)))
{
libsmtp_session->ErrorCode=libsmtp_temp;
return libsmtp_temp;
}
}*/
/* Then we look up the names of the MIME settings of the main body part
and send them as headers */
g_string_sprintf (libsmtp_temp_gstring, "Content-Type: %s/%s", \
libsmtp_int_lookup_mime_type (libsmtp_temp_part), \
libsmtp_int_lookup_mime_subtype (libsmtp_temp_part));
g_string_sprintf(libsmtp_temp_gstring, "Content-Type: %s/%s", libsmtp_temp_part->Type->str, libsmtp_temp_part->Subtype->str);
#ifdef LIBSMTP_DEBUG
printf ("libsmtp_mime_headers: %s. Type: %d/%d\n", libsmtp_temp_gstring->str, \
@ -163,7 +159,7 @@ int libsmtp_mime_headers (struct libsmtp_session_struct *libsmtp_session)
/* Multipart parts need a boundary set. We define it as a fixed string
at the moment, with an added dynamic number. This is always 1 here. */
if (libsmtp_temp_part->Type==LIBSMTP_MIME_MULTIPART)
if (libsmtp_part_is_type(libsmtp_temp_part, "multipart"))
{
libsmtp_set_boundary(libsmtp_temp_part, 0);
@ -179,25 +175,22 @@ int libsmtp_mime_headers (struct libsmtp_session_struct *libsmtp_session)
}
/* Text and message parts will have a charset setting */
if ((libsmtp_temp_part->Type==LIBSMTP_MIME_TEXT) ||
(libsmtp_temp_part->Type==LIBSMTP_MIME_MESSAGE))
if ((libsmtp_temp_string = (char *)libsmtp_int_lookup_mime_charset(libsmtp_temp_part)))
{
g_string_sprintf (libsmtp_temp_gstring, "; charset=\"%s\"", \
libsmtp_temp_string);
if (libsmtp_part_is_type(libsmtp_temp_part, "text") || libsmtp_part_is_type(libsmtp_temp_part, "message"))
if (!g_string_is_void(libsmtp_temp_part->Charset))
{
g_string_sprintf (libsmtp_temp_gstring, "; charset=\"%s\"", libsmtp_temp_part->Charset->str);
if (libsmtp_int_send (libsmtp_temp_gstring, libsmtp_session, 1))
return LIBSMTP_ERRORSENDFATAL;
if (libsmtp_int_send (libsmtp_temp_gstring, libsmtp_session, 1))
return LIBSMTP_ERRORSENDFATAL;
#ifdef LIBSMTP_DEBUG
printf ("libsmtp_mime_headers: %s", libsmtp_temp_gstring->str);
#endif
}
#ifdef LIBSMTP_DEBUG
printf ("libsmtp_mime_headers: %s", libsmtp_temp_gstring->str);
#endif
}
/* We need a transfer encoding, too */
g_string_sprintf (libsmtp_temp_gstring, "\r\nContent-Transfer-Encoding: %s\r\n", \
libsmtp_int_lookup_mime_encoding (libsmtp_temp_part));
g_string_sprintf (libsmtp_temp_gstring, "\r\nContent-Transfer-Encoding: %s\r\n", libsmtp_int_lookup_mime_encoding (libsmtp_temp_part));
#ifdef LIBSMTP_DEBUG
printf ("libsmtp_mime_headers: %s\n", libsmtp_temp_gstring);

View File

@ -29,6 +29,8 @@
#include <glib.h>
#endif
#define g_string_is_void(_str) (!(_str)->str || !*((_str)->str))
//#define LIBSMTP_DEBUG
#define WITH_MIME

View File

@ -32,107 +32,6 @@
#define LIB_SMTP_MIME_H
/* MIME types */
#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
#define LIBSMTP_MAX_MIME 7
/* MIME subtypes */
/* 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
#define LIBSMTP_MAX_MIME_SUB0 3
/* 1000 to 1999 are MESSAGE subtypes */
#define LIBSMTP_MIME_SUB_RFC822 1000
#define LIBSMTP_MIME_SUB_PARTIAL 1001
#define LIBSMTP_MAX_MIME_SUB1 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
#define LIBSMTP_MAX_MIME_SUB2 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
#define LIBSMTP_MAX_MIME_SUB3 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
#define LIBSMTP_MAX_MIME_SUB4 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
#define LIBSMTP_MAX_MIME_SUB5 5008
/* 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
#define LIBSMTP_MAX_MIME_SUB6 6003
/* 30000 (for signed ints!!) is the CUSTOM subtype */
#define LIBSMTP_MIME_SUB_CUSTOM 30000
/* Encoding types */
@ -145,41 +44,25 @@
#define LIBSMTP_MAX_ENC 4
/* 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
#define LIBSMTP_CHARSET_ISO8859_15 4
#define LIBSMTP_CHARSET_UTF_8 5
/* Need to define more here ... */
#define LIBSMTP_MAX_CHARSET 5
struct libsmtp_part_struct {
int internal_id; /* internal id number */
int Type; /* MIME type */
GString *CustomType; /* optional custom MIME type */
int Subtype; /* MIME subtype */
GString *CustomSubtype; /* optional custom MIME subtype */
GString *Type; /* MIME type */
GString *Subtype; /* MIME subtype */
int Encoding; /* MIME transfer encoding */
int Charset; /* optional charset for text MIME types */
GString *Charset; /* optional charset for text MIME types */
GString *Description; /* MIME part description */
GString *Boundary; /* optional Multipart boundary string */
int Tag; /* tag for user */
int length; // part length
};
bool libsmtp_part_is_type(struct libsmtp_part_struct *part, const char *type);
struct libsmtp_part_struct *libsmtp_part_new
(struct libsmtp_part_struct *, int, int, int, int, char *, int,
struct libsmtp_session_struct *libsmtp_session);
int libsmtp_mime_type_custom (char *, struct libsmtp_part_struct *);
int libsmtp_mime_subtype_custom (char *, struct libsmtp_part_struct *);
(struct libsmtp_part_struct *libsmtp_int_parent_part, const char *type,
const char *subtype, int libsmtp_int_encoding, const char *charset,
char *libsmtp_int_desc, int length, struct libsmtp_session_struct *libsmtp_session);
struct libsmtp_part_struct *libsmtp_part_query (struct libsmtp_session_struct *);
int libsmtp_mime_headers (struct libsmtp_session_struct *);
@ -190,14 +73,6 @@ int libsmtp_part_next (struct libsmtp_session_struct *);
/* internal functions */
int libsmtp_int_check_part (struct libsmtp_part_struct *);
const char *libsmtp_int_lookup_mime_type (struct libsmtp_part_struct *);
const char *libsmtp_int_lookup_mime_subtype (struct libsmtp_part_struct *);
const char *libsmtp_int_lookup_mime_charset (struct libsmtp_part_struct *);
const char *libsmtp_int_lookup_mime_encoding (struct libsmtp_part_struct *);
int libsmtp_int_nextpart (struct libsmtp_session_struct *);

View File

@ -97,14 +97,22 @@ char *libsmtp_mime_encodings[] = {
char *libsmtp_mime_charsets[] = {
"us-ascii", "iso-8859-1", "iso-8859-2", "iso-8859-3", "iso-8859-15", "utf-8"};
bool libsmtp_part_is_type(struct libsmtp_part_struct *part, const char *type)
{
if (g_string_is_void(part->Type))
return FALSE;
else
return strcmp(part->Type->str, type) == 0;
}
/* This function creates a new body part, checks for conformance to RFC822
and RFC 2045 and maybe attaches it to the session. It is taken care in here
that only multipart and message parts can contain children! Charset is
ignored unless you set a text or message part */
struct libsmtp_part_struct *libsmtp_part_new \
(struct libsmtp_part_struct *libsmtp_int_parent_part, int libsmtp_int_type,\
int libsmtp_int_subtype, int libsmtp_int_encoding, int libsmtp_int_charset, \
struct libsmtp_part_struct *libsmtp_part_new
(struct libsmtp_part_struct *libsmtp_int_parent_part, const char *type,
const char *subtype, int libsmtp_int_encoding, const char *charset,
char *libsmtp_int_desc, int length, struct libsmtp_session_struct *libsmtp_session)
{
struct libsmtp_part_struct *libsmtp_int_part;
@ -122,11 +130,10 @@ struct libsmtp_part_struct *libsmtp_part_new \
/* Ok, it is non-null. Now the parent part this pointer points to has
to be some kind of multipart */
if ((libsmtp_int_parent_part->Type!=LIBSMTP_MIME_MULTIPART) &&
(libsmtp_int_parent_part->Type!=LIBSMTP_MIME_MESSAGE))
if (!libsmtp_part_is_type(libsmtp_int_parent_part, "multipart") && !libsmtp_part_is_type(libsmtp_int_parent_part, "message"))
{
/* No, it isn't multipart. We can't append new parts to it. */
libsmtp_session->ErrorCode=LIBSMTP_NOMULTIPART;
libsmtp_session->ErrorCode = LIBSMTP_NOMULTIPART;
return NULL;
}
}
@ -161,24 +168,22 @@ struct libsmtp_part_struct *libsmtp_part_new \
return NULL;
/* The GStrings must be initialized */
libsmtp_int_part->CustomType = g_string_new (NULL);
libsmtp_int_part->CustomSubtype = g_string_new (NULL);
libsmtp_int_part->Description = g_string_new (NULL);
libsmtp_int_part->Boundary = g_string_new (NULL);
libsmtp_int_part->Type = libsmtp_int_type;
libsmtp_int_part->Subtype=libsmtp_int_subtype;
libsmtp_int_part->Encoding=libsmtp_int_encoding;
libsmtp_int_part->Description=g_string_new (libsmtp_int_desc);
libsmtp_int_part->Charset=libsmtp_int_charset;
libsmtp_int_part->Type = g_string_new(type);
libsmtp_int_part->Subtype = g_string_new(subtype);
libsmtp_int_part->Encoding = libsmtp_int_encoding;
libsmtp_int_part->Description = g_string_new(libsmtp_int_desc);
libsmtp_int_part->Charset = g_string_new(charset);
libsmtp_int_part->length = length;
if (libsmtp_int_check_part (libsmtp_int_part))
/*if (libsmtp_int_check_part (libsmtp_int_part))
{
libsmtp_session->ErrorCode = LIBSMTP_BADARGS;
return NULL;
}
}*/
/* We adjust the counters */
libsmtp_session->NumParts++;
@ -212,31 +217,6 @@ struct libsmtp_part_struct *libsmtp_part_new \
return libsmtp_int_part;
}
int libsmtp_mime_type_custom (char *libsmtp_int_custom_type, \
struct libsmtp_part_struct *libsmtp_int_part)
{
/* Is this a custom type ? */
if (libsmtp_int_part->Type != LIBSMTP_MIME_CUSTOM)
return LIBSMTP_BADMIME;
g_string_assign (libsmtp_int_part->CustomType, libsmtp_int_custom_type);
return LIBSMTP_NOERR;
}
int libsmtp_mime_subtype_custom (char *libsmtp_int_custom_subtype, \
struct libsmtp_part_struct *libsmtp_int_part)
{
/* Is this a custom subtype ? */
if (libsmtp_int_part->Subtype != LIBSMTP_MIME_SUB_CUSTOM)
return LIBSMTP_BADMIME;
g_string_assign (libsmtp_int_part->CustomSubtype, libsmtp_int_custom_subtype);
return LIBSMTP_NOERR;
}
void libsmtp_set_boundary(struct libsmtp_part_struct *part, int index)
{
static char pattern[33];
@ -258,9 +238,8 @@ int libsmtp_int_nextpart (struct libsmtp_session_struct *libsmtp_session)
{
GNode *libsmtp_temp_now;
struct libsmtp_part_struct *libsmtp_temp_part;
GString *libsmtp_temp_gstring=0;
char *libsmtp_temp_string;
int libsmtp_temp_int, libsmtp_int_travel=0;
GString *libsmtp_temp_gstring = NULL;
int libsmtp_int_travel = 0;
libsmtp_temp_gstring = g_string_new (NULL);
@ -275,7 +254,7 @@ int libsmtp_int_nextpart (struct libsmtp_session_struct *libsmtp_session)
#endif
/* If this is a Multipart part, we must send the standard MIME blurb */
if (libsmtp_session->PartNow->Type == LIBSMTP_MIME_MULTIPART)
if (libsmtp_part_is_type(libsmtp_session->PartNow, "multipart"))
{
g_string_assign (libsmtp_temp_gstring, \
"This is a MIME multipart message.\r\n");
@ -363,7 +342,7 @@ int libsmtp_int_nextpart (struct libsmtp_session_struct *libsmtp_session)
else
{
/* Ok, we don't need to travel. Is this a multipart part? */
if (libsmtp_temp_part->Type==LIBSMTP_MIME_MULTIPART)
if (libsmtp_part_is_type(libsmtp_temp_part, "multipart"))
{
/* Yes, is the boundary string set? */
if (libsmtp_temp_part->Boundary->len == 0)
@ -400,24 +379,22 @@ int libsmtp_int_nextpart (struct libsmtp_session_struct *libsmtp_session)
libsmtp_temp_part=libsmtp_session->PartNow;
/* We should check for valied MIME settings first */
if ((libsmtp_temp_int=libsmtp_int_check_part (libsmtp_temp_part)))
/*if ((libsmtp_temp_int=libsmtp_int_check_part (libsmtp_temp_part)))
{
libsmtp_session->ErrorCode=libsmtp_temp_int;
return libsmtp_temp_int;
}
}*/
/* Then we look up the names of the MIME settings of the main body part
and send them as headers */
g_string_sprintf (libsmtp_temp_gstring, "Content-Type: %s/%s", \
libsmtp_int_lookup_mime_type (libsmtp_temp_part), \
libsmtp_int_lookup_mime_subtype (libsmtp_temp_part));
g_string_sprintf(libsmtp_temp_gstring, "Content-Type: %s/%s", libsmtp_temp_part->Type->str, libsmtp_temp_part->Subtype->str);
if (strlen(libsmtp_temp_part->Description->str))
if (!g_string_is_void(libsmtp_temp_part->Description))
{
g_string_append (libsmtp_temp_gstring, "; name=\"");
g_string_append (libsmtp_temp_gstring, libsmtp_temp_part->Description->str);
g_string_append (libsmtp_temp_gstring, "\"");
g_string_append(libsmtp_temp_gstring, "; name=\"");
g_string_append(libsmtp_temp_gstring, libsmtp_temp_part->Description->str);
g_string_append(libsmtp_temp_gstring, "\"");
}
#ifdef LIBSMTP_DEBUG
@ -430,30 +407,27 @@ int libsmtp_int_nextpart (struct libsmtp_session_struct *libsmtp_session)
/* Multiparts have a boundary */
if (libsmtp_temp_part->Type == LIBSMTP_MIME_MULTIPART)
if (libsmtp_part_is_type(libsmtp_temp_part, "multipart"))
{
g_string_sprintf (libsmtp_temp_gstring, "; boundary=\"%s\"", libsmtp_temp_part->Boundary->str);
if (libsmtp_int_send (libsmtp_temp_gstring, libsmtp_session, 1))
if (libsmtp_int_send(libsmtp_temp_gstring, libsmtp_session, 1))
return LIBSMTP_ERRORSENDFATAL;
}
/* Text and message parts will have a charset setting */
if ((libsmtp_temp_part->Type==LIBSMTP_MIME_TEXT) ||
(libsmtp_temp_part->Type==LIBSMTP_MIME_MESSAGE))
if ((libsmtp_temp_string = (char *)libsmtp_int_lookup_mime_charset(libsmtp_temp_part)))
{
g_string_sprintf (libsmtp_temp_gstring, "; charset=\"%s\"", \
libsmtp_temp_string);
if (!g_string_is_void(libsmtp_temp_part->Charset))
{
g_string_sprintf (libsmtp_temp_gstring, "; charset=\"%s\"", libsmtp_temp_part->Charset->str);
if (libsmtp_int_send (libsmtp_temp_gstring, libsmtp_session, 1))
return LIBSMTP_ERRORSENDFATAL;
if (libsmtp_int_send(libsmtp_temp_gstring, libsmtp_session, 1))
return LIBSMTP_ERRORSENDFATAL;
#ifdef LIBSMTP_DEBUG
printf ("libsmtp_mime_headers: %s", libsmtp_temp_gstring->str);
#endif
}
#ifdef LIBSMTP_DEBUG
printf ("libsmtp_mime_headers: %s", libsmtp_temp_gstring->str);
#endif
}
if (libsmtp_temp_part->length > 0)
{
@ -469,7 +443,7 @@ int libsmtp_int_nextpart (struct libsmtp_session_struct *libsmtp_session)
/* We need a transfer encoding, too */
if (libsmtp_temp_part->Type != LIBSMTP_MIME_MULTIPART)
if (!libsmtp_part_is_type(libsmtp_temp_part, "multipart"))
{
g_string_sprintf (libsmtp_temp_gstring, "\r\nContent-Transfer-Encoding: %s\r\n", \
libsmtp_int_lookup_mime_encoding (libsmtp_temp_part));
@ -490,7 +464,7 @@ int libsmtp_int_nextpart (struct libsmtp_session_struct *libsmtp_session)
}
}
if (libsmtp_temp_part->Type==LIBSMTP_MIME_MULTIPART)
if (libsmtp_part_is_type(libsmtp_temp_part, "multipart"))
{
#ifdef LIBSMTP_DEBUG
printf ("libsmtp_int_nextpart: Part %s is Multipart, so we jump to the first child\n", libsmtp_session->PartNow->Description->str);
@ -522,8 +496,7 @@ int libsmtp_int_nextpart (struct libsmtp_session_struct *libsmtp_session)
can be used at any time to find out what part is currently being sent, of
course. */
struct libsmtp_part_struct *libsmtp_part_query \
(struct libsmtp_session_struct *libsmtp_session)
struct libsmtp_part_struct *libsmtp_part_query(struct libsmtp_session_struct *libsmtp_session)
{
/* Are we in data stage? */
if ((libsmtp_session->Stage < LIBSMTP_HEADERS_STAGE) ||
@ -555,229 +528,10 @@ struct libsmtp_part_struct *libsmtp_part_query \
}
/* libsmtp_int_check_part checks a part for correct settings */
int libsmtp_int_check_part (struct libsmtp_part_struct *libsmtp_int_part)
{
/* Now we check if any invalid MIME arguments have been given.*/
if ((libsmtp_int_part->Type < 0) || (libsmtp_int_part->Type > LIBSMTP_MAX_MIME))
{
return LIBSMTP_BADARGS;
}
/* Now the same for the subtype argument. This must correspond to the
selected type */
switch (libsmtp_int_part->Type)
{
case (LIBSMTP_MIME_TEXT):
if ((libsmtp_int_part->Subtype < 0) || (libsmtp_int_part->Subtype > LIBSMTP_MAX_MIME_SUB0))
{
return LIBSMTP_BADMIME;
}
/* Text types can have any encoding */
if ((libsmtp_int_part->Encoding < 0) || (libsmtp_int_part->Encoding > LIBSMTP_MAX_ENC))
{
return LIBSMTP_BADENCODING;
}
/* Text types must have a valid charset */
if ((libsmtp_int_part->Charset < 0) || (libsmtp_int_part->Charset > LIBSMTP_MAX_CHARSET))
{
return LIBSMTP_BADCHARSET;
}
break;
case (LIBSMTP_MIME_MESSAGE):
if ((libsmtp_int_part->Subtype < 1000) || (libsmtp_int_part->Subtype > LIBSMTP_MAX_MIME_SUB1))
{
return LIBSMTP_BADMIME;
}
/* Message types can have any encoding */
if ((libsmtp_int_part->Encoding < 0) || (libsmtp_int_part->Encoding > LIBSMTP_MAX_ENC))
{
return LIBSMTP_BADENCODING;
}
/* Message types must have a valid charset */
if ((libsmtp_int_part->Charset < 0) || (libsmtp_int_part->Charset > LIBSMTP_MAX_CHARSET))
{
return LIBSMTP_BADCHARSET;
}
break;
case (LIBSMTP_MIME_IMAGE):
if ((libsmtp_int_part->Subtype < 2000) || (libsmtp_int_part->Subtype > LIBSMTP_MAX_MIME_SUB2))
{
return LIBSMTP_BADMIME;
}
/* Image types must be in a non-text encoding */
if ((libsmtp_int_part->Encoding < LIBSMTP_ENC_BINARY) || (libsmtp_int_part->Encoding > LIBSMTP_MAX_ENC))
{
return LIBSMTP_BADENCODING;
}
/* Charset is set to -1 because it won't matter here */
libsmtp_int_part->Charset = -1;
break;
case (LIBSMTP_MIME_AUDIO):
if ((libsmtp_int_part->Subtype < 3000) || (libsmtp_int_part->Subtype > LIBSMTP_MAX_MIME_SUB3))
{
return LIBSMTP_BADMIME;
}
/* Audio types must be in a non-text encoding */
if ((libsmtp_int_part->Encoding < LIBSMTP_ENC_BINARY) || (libsmtp_int_part->Encoding > LIBSMTP_MAX_ENC))
{
return LIBSMTP_BADENCODING;
}
/* Charset is set to -1 because it won't matter here */
libsmtp_int_part->Charset = -1;
break;
case (LIBSMTP_MIME_VIDEO):
if ((libsmtp_int_part->Subtype < 4000) || (libsmtp_int_part->Subtype > LIBSMTP_MAX_MIME_SUB4))
{
return LIBSMTP_BADMIME;
}
/* Video types must be in a non-text encoding */
if ((libsmtp_int_part->Encoding < LIBSMTP_ENC_BINARY) || (libsmtp_int_part->Encoding > LIBSMTP_MAX_ENC))
{
return LIBSMTP_BADENCODING;
}
/* Charset is set to -1 because it won't matter here */
libsmtp_int_part->Charset = -1;
break;
case (LIBSMTP_MIME_APPLICATION):
if ((libsmtp_int_part->Subtype < 5000) || (libsmtp_int_part->Subtype > LIBSMTP_MAX_MIME_SUB5))
{
return LIBSMTP_BADMIME;
}
/* Application types must be in a non-text encoding */
if ((libsmtp_int_part->Encoding < LIBSMTP_ENC_BINARY) || (libsmtp_int_part->Encoding > LIBSMTP_MAX_ENC))
{
return LIBSMTP_BADENCODING;
}
/* Charset is set to -1 because it won't matter here */
libsmtp_int_part->Charset = -1;
break;
case (LIBSMTP_MIME_MULTIPART):
if ((libsmtp_int_part->Subtype < 6000) || (libsmtp_int_part->Subtype > LIBSMTP_MAX_MIME_SUB6))
{
return LIBSMTP_BADMIME;
}
/* Application types must be in a text encoding, and should only be
7bit */
if (libsmtp_int_part->Encoding != LIBSMTP_ENC_7BIT)
{
return LIBSMTP_BADENCODING;
}
/* Charset is set to -1 because it won't matter here */
libsmtp_int_part->Charset = -1;
break;
case (LIBSMTP_MIME_CUSTOM):
if (libsmtp_int_part->Subtype != LIBSMTP_MIME_SUB_CUSTOM)
{
return LIBSMTP_BADMIME;
}
/* Custom type can have any encoding, of course */
if ((libsmtp_int_part->Encoding < 0) || (libsmtp_int_part->Encoding > LIBSMTP_MAX_ENC))
{
return LIBSMTP_BADENCODING;
}
/* Custom types must have a valid charset or NOCHARSET */
if ((libsmtp_int_part->Charset < LIBSMTP_CHARSET_NOCHARSET) || (libsmtp_int_part->Charset > LIBSMTP_MAX_CHARSET))
{
return LIBSMTP_BADCHARSET;
}
break;
}
return 0;
}
/* These functions lookup the name of types, subtypes and encodings for a
part. They only perform glancing checking of parameters, so you should
check the mime settings beforehand with libsmtp_int_check_parts */
const char *libsmtp_int_lookup_mime_type (struct libsmtp_part_struct *libsmtp_int_part)
{
if ((libsmtp_int_part->Type >= 0) && (libsmtp_int_part->Type <= LIBSMTP_MAX_MIME))
{
if (libsmtp_int_part->Type == LIBSMTP_MIME_CUSTOM)
return libsmtp_int_part->CustomType->str;
else
return libsmtp_mime_types[libsmtp_int_part->Type];
}
else
return NULL;
}
const char *libsmtp_int_lookup_mime_subtype (struct libsmtp_part_struct *libsmtp_int_part)
{
switch (libsmtp_int_part->Type)
{
case LIBSMTP_MIME_TEXT:
return libsmtp_mime_subtypes0[libsmtp_int_part->Subtype];
case LIBSMTP_MIME_MESSAGE:
return libsmtp_mime_subtypes1[libsmtp_int_part->Subtype-1000];
case LIBSMTP_MIME_IMAGE:
return libsmtp_mime_subtypes2[libsmtp_int_part->Subtype-2000];
case LIBSMTP_MIME_AUDIO:
return libsmtp_mime_subtypes3[libsmtp_int_part->Subtype-3000];
case LIBSMTP_MIME_VIDEO:
return libsmtp_mime_subtypes4[libsmtp_int_part->Subtype-4000];
case LIBSMTP_MIME_APPLICATION:
return libsmtp_mime_subtypes5[libsmtp_int_part->Subtype-5000];
case LIBSMTP_MIME_MULTIPART:
return libsmtp_mime_subtypes6[libsmtp_int_part->Subtype-6000];
case LIBSMTP_MIME_CUSTOM:
return libsmtp_int_part->CustomSubtype->str;
default:
return NULL;
}
}
const char *libsmtp_int_lookup_mime_charset (struct libsmtp_part_struct *libsmtp_int_part)
{
/* Only textual parts can have a charset */
if ((libsmtp_int_part->Type == LIBSMTP_MIME_TEXT) || \
(libsmtp_int_part->Type == LIBSMTP_MIME_MESSAGE))
{
if ((libsmtp_int_part->Charset >= 0) && (libsmtp_int_part->Charset <= LIBSMTP_MAX_CHARSET))
{
return libsmtp_mime_charsets[libsmtp_int_part->Charset];
}
}
return NULL;
}
const char *libsmtp_int_lookup_mime_encoding (struct libsmtp_part_struct *libsmtp_int_part)
{
if ((libsmtp_int_part->Encoding >= 0) && (libsmtp_int_part->Encoding <= LIBSMTP_MAX_ENC))