|
|
|
//=============================================================================
|
|
|
|
// File: attach.cpp
|
|
|
|
// Contents: Definitions for MessageWithAttachments
|
|
|
|
// Maintainer: Doug Sauder <dwsauder@fwb.gulf.net>
|
|
|
|
// WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html
|
|
|
|
//
|
|
|
|
// Copyright (c) 1996, 1997 Douglas W. Sauder
|
|
|
|
// All rights reserved.
|
|
|
|
//
|
|
|
|
// IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT,
|
|
|
|
// INDIRECT, SPECIAL, INCIDENTAL, OR CONSETQUENTIAL DAMAGES ARISING OUT OF
|
|
|
|
// THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER
|
|
|
|
// HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
//
|
|
|
|
// DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT
|
|
|
|
// NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
|
|
|
// PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
|
|
|
|
// BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
|
|
|
|
// SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
|
|
|
//
|
|
|
|
//=============================================================================
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <mimelib/string.h>
|
|
|
|
#include <mimelib/utility.h>
|
|
|
|
#include "attach.h"
|
|
|
|
|
|
|
|
|
|
|
|
MessageWithAttachments::MessageWithAttachments()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
MessageWithAttachments::~MessageWithAttachments()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void MessageWithAttachments::SetText(const DwString& aStr)
|
|
|
|
{
|
|
|
|
// Create a body part and set the necessary fields
|
|
|
|
|
|
|
|
MultipartBodyPart part;
|
|
|
|
part.SetType(DwMime::kTypeText);
|
|
|
|
part.SetSubtype(DwMime::kSubtypePlain);
|
|
|
|
part.SetCte(DwMime::kCte7bit);
|
|
|
|
|
|
|
|
// Set the string as the body of the body part
|
|
|
|
|
|
|
|
part.SetBody(aStr);
|
|
|
|
|
|
|
|
// Set this body part as the first one
|
|
|
|
|
|
|
|
SetBodyPart(0, part);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int MessageWithAttachments::NumberOfAttachments() const
|
|
|
|
{
|
|
|
|
int n = NumberOfParts() - 1;
|
|
|
|
return (n >= 0) ? n : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void MessageWithAttachments::Attach7bitFile(const char* aFilename,
|
|
|
|
int aType, int aSubtype)
|
|
|
|
{
|
|
|
|
// Get the file contents
|
|
|
|
|
|
|
|
DwString str;
|
|
|
|
PutFileInString(aFilename, str);
|
|
|
|
|
|
|
|
// Create a body part and set the necessary fields
|
|
|
|
|
|
|
|
MultipartBodyPart part;
|
|
|
|
part.SetType(aType);
|
|
|
|
part.SetSubtype(aSubtype);
|
|
|
|
part.SetCte(DwMime::kCte7bit);
|
|
|
|
|
|
|
|
// Set content-disposition to attachment, with filename parameter
|
|
|
|
// (see RFC-1806 for information on this *experimental* header field)
|
|
|
|
|
|
|
|
DwString contDisp = "attachment; filename=";
|
|
|
|
contDisp += '\"';
|
|
|
|
contDisp += aFilename;
|
|
|
|
contDisp += '\"';
|
|
|
|
part.SetContentDisposition(contDisp);
|
|
|
|
|
|
|
|
// Set the file contents as the body of the body part
|
|
|
|
|
|
|
|
part.SetBody(str);
|
|
|
|
|
|
|
|
// Make sure this is not the first part, since that is reserved for
|
|
|
|
// the text
|
|
|
|
|
|
|
|
if (NumberOfParts() == 0) {
|
|
|
|
SetBodyPart(1, part);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
AddBodyPart(part);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void MessageWithAttachments::Attach8bitFile(const char* aFilename,
|
|
|
|
int aType, int aSubtype)
|
|
|
|
{
|
|
|
|
// Get the file contents
|
|
|
|
|
|
|
|
DwString str;
|
|
|
|
PutFileInString(aFilename, str);
|
|
|
|
|
|
|
|
// Encode using quoted-printable encoding
|
|
|
|
|
|
|
|
DwString encStr;
|
|
|
|
DwEncodeQuotedPrintable(str, encStr);
|
|
|
|
|
|
|
|
// Create a body part and set the necessary fields
|
|
|
|
|
|
|
|
MultipartBodyPart part;
|
|
|
|
part.SetType(aType);
|
|
|
|
part.SetSubtype(aSubtype);
|
|
|
|
part.SetCte(DwMime::kCteQuotedPrintable);
|
|
|
|
|
|
|
|
// Set content-disposition to attachment, with filename parameter
|
|
|
|
// (see RFC-1806 for information on this *experimental* header field)
|
|
|
|
|
|
|
|
DwString contDisp = "attachment; filename=";
|
|
|
|
contDisp += '\"';
|
|
|
|
contDisp += aFilename;
|
|
|
|
contDisp += '\"';
|
|
|
|
part.SetContentDisposition(contDisp);
|
|
|
|
|
|
|
|
// Set the encoded file contents as the body of the body part
|
|
|
|
|
|
|
|
part.SetBody(encStr);
|
|
|
|
|
|
|
|
// Make sure this is not the first part, since that is reserved for
|
|
|
|
// the text
|
|
|
|
|
|
|
|
if (NumberOfParts() == 0) {
|
|
|
|
SetBodyPart(1, part);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
AddBodyPart(part);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void MessageWithAttachments::AttachBinaryFile(const char* aFilename,
|
|
|
|
int aType, int aSubtype)
|
|
|
|
{
|
|
|
|
// Get the file contents
|
|
|
|
|
|
|
|
DwString str;
|
|
|
|
PutFileInString(aFilename, str);
|
|
|
|
|
|
|
|
// Encode using base64 encoding
|
|
|
|
|
|
|
|
DwString encStr;
|
|
|
|
DwEncodeBase64(str, encStr);
|
|
|
|
|
|
|
|
// Create a body part and set the necessary fields
|
|
|
|
|
|
|
|
MultipartBodyPart part;
|
|
|
|
part.SetType(aType);
|
|
|
|
part.SetSubtype(aSubtype);
|
|
|
|
part.SetCte(DwMime::kCteBase64);
|
|
|
|
|
|
|
|
// Set content-disposition to attachment, with filename parameter
|
|
|
|
// (see RFC-1806 for information on this *experimental* header field)
|
|
|
|
|
|
|
|
DwString contDisp = "attachment; filename=";
|
|
|
|
contDisp += '\"';
|
|
|
|
contDisp += aFilename;
|
|
|
|
contDisp += '\"';
|
|
|
|
part.SetContentDisposition(contDisp);
|
|
|
|
|
|
|
|
// Set the encoded file contents as the body of the body part
|
|
|
|
|
|
|
|
part.SetBody(encStr);
|
|
|
|
|
|
|
|
// Make sure this is not the first part, since that is reserved for
|
|
|
|
// the text
|
|
|
|
|
|
|
|
if (NumberOfParts() == 0) {
|
|
|
|
SetBodyPart(1, part);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
AddBodyPart(part);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int MessageWithAttachments::PutFileInString(const char* aFilename,
|
|
|
|
DwString& str)
|
|
|
|
{
|
|
|
|
// Get the file size
|
|
|
|
struct stat statBuf;
|
|
|
|
int k = stat(aFilename, &statBuf);
|
|
|
|
if (k < 0) {
|
|
|
|
str = "";
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
int fileSize = (int) statBuf.st_size;
|
|
|
|
|
|
|
|
// Allocate a buffer
|
|
|
|
|
|
|
|
int bufSize = fileSize + 8; // a little elbow room added
|
|
|
|
char* buf = new char[bufSize];
|
|
|
|
|
|
|
|
// Read the file into the buffer
|
|
|
|
|
|
|
|
FILE* fp = fopen(aFilename, "rb");
|
|
|
|
if (fp == 0) {
|
|
|
|
delete[] buf;
|
|
|
|
str = "";
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
int len = 0;
|
|
|
|
while (1) {
|
|
|
|
int ch = getc(fp);
|
|
|
|
if (feof(fp) || len == fileSize) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
buf[len++] = ch;
|
|
|
|
}
|
|
|
|
buf[len] = 0;
|
|
|
|
fclose(fp);
|
|
|
|
|
|
|
|
// Place the buffer in the string
|
|
|
|
|
|
|
|
str.TakeBuffer(buf, bufSize, 0, len);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|