Issue #1829 - Revert "Issue #1751"

This commit is contained in:
Brian Smith 2022-04-26 11:34:08 -05:00 committed by roytam1
commit 13fcc4a046
949 changed files with 95662 additions and 444 deletions

View file

@ -35,6 +35,16 @@ SOURCES += [
'nsURLFetcher.cpp',
]
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
SOURCES += [
'nsMsgAppleDoubleEncode.cpp',
'nsMsgAppleEncode.cpp',
]
EXPORTS += [
'nsMsgAppleCodes.h',
'nsMsgAppleDouble.h',
]
EXTRA_COMPONENTS += [
'nsSMTPProtocolHandler.js',
'nsSMTPProtocolHandler.manifest',

View file

@ -0,0 +1,106 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
** AD_Codes.h
**
** ---------------
**
** Head file for Apple Decode/Encode essential codes.
**
**
*/
#ifndef ad_codes_h
#define ad_codes_h
/*
** applefile definitions used
*/
#if PRAGMA_STRUCT_ALIGN
#pragma options align=mac68k
#endif
#define APPLESINGLE_MAGIC 0x00051600L
#define APPLEDOUBLE_MAGIC 0x00051607L
#define VERSION 0x00020000
#define NUM_ENTRIES 6
#define ENT_DFORK 1L
#define ENT_RFORK 2L
#define ENT_NAME 3L
#define ENT_COMMENT 4L
#define ENT_DATES 8L
#define ENT_FINFO 9L
#define CONVERT_TIME 1265437696L
/*
** data type used in the encoder/decoder.
*/
typedef struct ap_header
{
int32_t magic;
int32_t version;
char fill[16];
int16_t entries;
} ap_header;
typedef struct ap_entry
{
int32_t id;
int32_t offset;
int32_t length;
} ap_entry;
typedef struct ap_dates
{
int32_t create, modify, backup, access;
} ap_dates;
typedef struct myFInfo /* the mac FInfo structure for the cross platform. */
{
int32_t fdType, fdCreator;
int16_t fdFlags;
int32_t fdLocation; /* it really should be a pointer, but just a place-holder */
int16_t fdFldr;
} myFInfo;
PR_BEGIN_EXTERN_C
/*
** string utils.
*/
int write_stream(appledouble_encode_object *p_ap_encode_obj, const char *s,int len);
int fill_apple_mime_header(appledouble_encode_object *p_ap_encode_obj);
int ap_encode_file_infor(appledouble_encode_object *p_ap_encode_obj);
int ap_encode_header(appledouble_encode_object* p_ap_encode_obj, bool firstTime);
int ap_encode_data( appledouble_encode_object* p_ap_encode_obj, bool firstTime);
/*
** the prototypes for the ap_decoder.
*/
int fetch_a_line(appledouble_decode_object* p_ap_decode_obj, char *buff);
int ParseFileHeader(appledouble_decode_object* p_ap_decode_obj);
int ap_seek_part_start(appledouble_decode_object* p_ap_decode_obj);
void parse_param(char *p, char **param, char**define, char **np);
int ap_seek_to_boundary(appledouble_decode_object* p_ap_decode_obj, bool firstime);
int ap_parse_header(appledouble_decode_object* p_ap_decode_obj,bool firstime);
int ap_decode_file_infor(appledouble_decode_object* p_ap_decode_obj);
int ap_decode_process_header(appledouble_decode_object* p_ap_decode_obj, bool firstime);
int ap_decode_process_data( appledouble_decode_object* p_ap_decode_obj, bool firstime);
PR_END_EXTERN_C
#if PRAGMA_STRUCT_ALIGN
#pragma options align=reset
#endif
#endif /* ad_codes_h */

View file

@ -0,0 +1,207 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* AppleDouble.h
* -------------
*
* The header file for a stream based apple single/double encodor/decodor.
*
* 2aug95 mym
*
*/
#ifndef AppleDouble_h
#define AppleDouble_h
#include "msgCore.h"
#include "nsComposeStrings.h"
#include "nsIOutputStream.h"
#include "nsCOMPtr.h"
#include <CoreServices/CoreServices.h>
#define NOERR 0
#define errDone 1
/* Done with current operation. */
#define errEOB 2
/* End of a buffer. */
#define errEOP 3
/* End of a Part. */
#define errFileOpen NS_ERROR_GET_CODE(NS_MSG_UNABLE_TO_OPEN_TMP_FILE)
#define errFileWrite -202 /*Error writing temporary file.*/
#define errUsrCancel -2 /*MK_INTERRUPTED */
#define errDecoding -1
/*
** The envirment block data type.
*/
enum
{
kInit,
kDoingHeaderPortion,
kDoneHeaderPortion,
kDoingDataPortion,
kDoneDataPortion
};
typedef struct _appledouble_encode_object
{
char fname[256];
FSIORefNum fileId; /* the id for the open file (data/resource fork) */
int state;
int text_file_type; /* if the file has a text file type with it. */
char *boundary; /* the boundary string. */
int status; /* the error code if anyerror happens. */
char b_overflow[200];
int s_overflow;
int state64; /* the left over state of base64 enocding */
int ct; /* the character count of base64 encoding */
int c1, c2; /* the left of the last base64 encoding */
char *outbuff; /* the outbuff by the caller. */
int s_outbuff; /* the size of the buffer. */
int pos_outbuff; /* the offset in the current buffer. */
} appledouble_encode_object;
/* The possible content transfer encodings */
enum
{
kEncodeNone,
kEncodeQP,
kEncodeBase64,
kEncodeUU
};
enum
{
kGeneralMine,
kAppleDouble,
kAppleSingle
};
enum
{
kInline,
kDontCare
};
enum
{
kHeaderPortion,
kDataPortion
};
/* the decode states. */
enum
{
kBeginParseHeader = 3,
kParsingHeader,
kBeginSeekBoundary,
kSeekingBoundary,
kBeginHeaderPortion,
kProcessingHeaderPortion,
kBeginDataPortion,
kProcessingDataPortion,
kFinishing
};
/* uuencode states */
enum
{
kWaitingForBegin = (int) 0,
kBegin,
kMainBody,
kEnd
};
typedef struct _appledouble_decode_object
{
int is_binary;
int is_apple_single; /* if the object encoded is in apple single */
int write_as_binhex;
int messagetype;
char* boundary0; /* the boundary for the enclosure. */
int deposition; /* the deposition. */
int encoding; /* the encoding method. */
int which_part;
char fname[256];
// nsIOFileStream *fileSpec; /* the stream for data fork work. */
int state;
int rksize; /* the resource fork size count. */
int dksize; /* the data fork size count. */
int status; /* the error code if anyerror happens. */
char b_leftover[256];
int s_leftover;
int encode; /* the encode type of the message. */
int state64; /* the left over state of base64 enocding */
int left; /* the character count of base64 encoding */
int c[4]; /* the left of the last base64 encoding */
int uu_starts_line; /* is decoder at the start of a line? (uuencode) */
int uu_state; /* state w/r/t the uuencode body */
int uu_bytes_written; /* bytes written from the current tuple (uuencode) */
int uu_line_bytes; /* encoded bytes remaining in the current line (uuencode) */
char *inbuff; /* the outbuff by the caller. */
int s_inbuff; /* the size of the buffer. */
int pos_inbuff; /* the offset in the current buffer. */
nsCOMPtr <nsIFile> tmpFile; /* the temp file to hold the decode data fork */
/* when doing the binhex exporting. */
nsCOMPtr <nsIOutputStream> tmpFileStream; /* The output File Stream */
int32_t data_size; /* the size of the data in the tmp file. */
} appledouble_decode_object;
/*
** The protypes.
*/
PR_BEGIN_EXTERN_C
int ap_encode_init(appledouble_encode_object *p_ap_encode_obj,
const char* fname,
char* separator);
int ap_encode_next(appledouble_encode_object* p_ap_encode_obj,
char *to_buff,
int32_t buff_size,
int32_t* real_size);
int ap_encode_end(appledouble_encode_object* p_ap_encode_obj,
bool is_aborting);
int ap_decode_init(appledouble_decode_object* p_ap_decode_obj,
bool is_apple_single,
bool write_as_bin_hex,
void *closure);
int ap_decode_next(appledouble_decode_object* p_ap_decode_obj,
char *in_buff,
int32_t buff_size);
int ap_decode_end(appledouble_decode_object* p_ap_decode_obj,
bool is_aborting);
PR_END_EXTERN_C
#endif

View file

@ -0,0 +1,266 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
*
* apple-double.c
* --------------
*
* The codes to do apple double encoding/decoding.
*
* 02aug95 mym created.
*
*/
#include "nsID.h"
#include "nscore.h"
#include "nsStringGlue.h"
#include "nsMsgAppleDouble.h"
#include "nsMsgAppleCodes.h"
#include "nsMsgCompUtils.h"
#include "nsCExternalHandlerService.h"
#include "nsIMIMEService.h"
#include "nsMimeTypes.h"
#include "prmem.h"
#include "nsNetUtil.h"
void
MacGetFileType(nsIFile *fs,
bool *useDefault,
char **fileType,
char **encoding)
{
if ((fs == NULL) || (fileType == NULL) || (encoding == NULL))
return;
bool exists = false;
fs->Exists(&exists);
if (!exists)
return;
*useDefault = TRUE;
*fileType = NULL;
*encoding = NULL;
nsCOMPtr<nsILocalFileMac> macFile = do_QueryInterface(fs);
FSRef fsRef;
FSCatalogInfo catalogInfo;
OSErr err = errFileOpen;
if (NS_SUCCEEDED(macFile->GetFSRef(&fsRef)))
err = ::FSGetCatalogInfo(&fsRef, kFSCatInfoFinderInfo, &catalogInfo, nullptr, nullptr, nullptr);
if ( (err != noErr) || (((FileInfo*)(&catalogInfo.finderInfo))->fileType == 'TEXT') )
*fileType = strdup(APPLICATION_OCTET_STREAM);
else
{
// At this point, we should call the mime service and
// see what we can find out?
nsresult rv;
nsCOMPtr <nsIURI> tURI;
if (NS_SUCCEEDED(NS_NewFileURI(getter_AddRefs(tURI), fs)) && tURI)
{
nsCOMPtr<nsIMIMEService> mimeFinder (do_GetService(NS_MIMESERVICE_CONTRACTID, &rv));
if (NS_SUCCEEDED(rv) && mimeFinder)
{
nsAutoCString mimeType;
rv = mimeFinder->GetTypeFromURI(tURI, mimeType);
if (NS_SUCCEEDED(rv))
{
*fileType = ToNewCString(mimeType);
return;
}
}
}
// If we hit here, return something...default to this...
*fileType = strdup(APPLICATION_OCTET_STREAM);
}
}
//#pragma cplusplus reset
/*
* ap_encode_init
* --------------
*
* Setup the encode envirment
*/
int ap_encode_init( appledouble_encode_object *p_ap_encode_obj,
const char *fname,
char *separator)
{
nsCOMPtr <nsIFile> myFile;
NS_NewNativeLocalFile(nsDependentCString(fname), true, getter_AddRefs(myFile));
bool exists;
if (myFile && NS_SUCCEEDED(myFile->Exists(&exists)) && !exists)
return -1;
nsCOMPtr<nsILocalFileMac> macFile = do_QueryInterface(myFile);
nsAutoCString path;
macFile->GetNativePath(path);
memset(p_ap_encode_obj, 0, sizeof(appledouble_encode_object));
/*
** Fill out the source file inforamtion.
*/
memcpy(p_ap_encode_obj->fname, path.get(), path.Length());
p_ap_encode_obj->fname[path.Length()] = '\0';
p_ap_encode_obj->boundary = strdup(separator);
return noErr;
}
/*
** ap_encode_next
** --------------
**
** return :
** noErr : everything is ok
** errDone : when encoding is done.
** errors : otherwise.
*/
int ap_encode_next(
appledouble_encode_object* p_ap_encode_obj,
char *to_buff,
int32_t buff_size,
int32_t* real_size)
{
int status;
/*
** install the out buff now.
*/
p_ap_encode_obj->outbuff = to_buff;
p_ap_encode_obj->s_outbuff = buff_size;
p_ap_encode_obj->pos_outbuff = 0;
/*
** first copy the outstandind data in the overflow buff to the out buffer.
*/
if (p_ap_encode_obj->s_overflow)
{
status = write_stream(p_ap_encode_obj,
(const char*)(p_ap_encode_obj->b_overflow),
p_ap_encode_obj->s_overflow);
if (status != noErr)
return status;
p_ap_encode_obj->s_overflow = 0;
}
/*
** go the next processing stage based on the current state.
*/
switch (p_ap_encode_obj->state)
{
case kInit:
/*
** We are in the starting position, fill out the header.
*/
status = fill_apple_mime_header(p_ap_encode_obj);
if (status != noErr)
break; /* some error happens */
p_ap_encode_obj->state = kDoingHeaderPortion;
status = ap_encode_header(p_ap_encode_obj, true);
/* it is the first time to calling */
if (status == errDone)
{
p_ap_encode_obj->state = kDoneHeaderPortion;
}
else
{
break; /* we need more work on header portion. */
}
/*
** we are done with the header, so let's go to the data port.
*/
p_ap_encode_obj->state = kDoingDataPortion;
status = ap_encode_data(p_ap_encode_obj, true);
/* it is first time call do data portion */
if (status == errDone)
{
p_ap_encode_obj->state = kDoneDataPortion;
status = noErr;
}
break;
case kDoingHeaderPortion:
status = ap_encode_header(p_ap_encode_obj, false);
/* continue with the header portion. */
if (status == errDone)
{
p_ap_encode_obj->state = kDoneHeaderPortion;
}
else
{
break; /* we need more work on header portion. */
}
/*
** start the data portion.
*/
p_ap_encode_obj->state = kDoingDataPortion;
status = ap_encode_data(p_ap_encode_obj, true);
/* it is the first time calling */
if (status == errDone)
{
p_ap_encode_obj->state = kDoneDataPortion;
status = noErr;
}
break;
case kDoingDataPortion:
status = ap_encode_data(p_ap_encode_obj, false);
/* it is not the first time */
if (status == errDone)
{
p_ap_encode_obj->state = kDoneDataPortion;
status = noErr;
}
break;
case kDoneDataPortion:
status = errDone; /* we are really done. */
break;
}
*real_size = p_ap_encode_obj->pos_outbuff;
return status;
}
/*
** ap_encode_end
** -------------
**
** clear the apple encoding.
*/
int ap_encode_end(
appledouble_encode_object *p_ap_encode_obj,
bool is_aborting)
{
/*
** clear up the apple doubler.
*/
if (p_ap_encode_obj == NULL)
return noErr;
if (p_ap_encode_obj->fileId) /* close the file if it is open. */
::FSCloseFork(p_ap_encode_obj->fileId);
PR_FREEIF(p_ap_encode_obj->boundary); /* the boundary string. */
return noErr;
}

View file

@ -0,0 +1,703 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
*
* apple_double_encode.c
* ---------------------
*
* The routines doing the Apple Double Encoding.
*
* 2aug95 mym Created.
*
*/
#include "nscore.h"
#include "nsStringGlue.h"
#include "nsMimeTypes.h"
#include "prprf.h"
#include "nsServiceManagerUtils.h"
#include "nsMsgAppleDouble.h"
#include "nsMsgAppleCodes.h"
#include "nsILocalFileMac.h"
/*
** Local Functions prototypes.
*/
static int output64chunk( appledouble_encode_object* p_ap_encode_obj,
int c1, int c2, int c3, int pads);
static int to64(appledouble_encode_object* p_ap_encode_obj,
char *p,
int in_size);
static int finish64(appledouble_encode_object* p_ap_encode_obj);
#define BUFF_LEFT(p) ((p)->s_outbuff - (p)->pos_outbuff)
/*
** write_stream.
*/
int write_stream(
appledouble_encode_object *p_ap_encode_obj,
const char *out_string,
int len)
{
if (p_ap_encode_obj->pos_outbuff + len < p_ap_encode_obj->s_outbuff)
{
memcpy(p_ap_encode_obj->outbuff + p_ap_encode_obj->pos_outbuff,
out_string,
len);
p_ap_encode_obj->pos_outbuff += len;
return noErr;
}
else
{
/*
** If the buff doesn't have enough space, use the overflow buffer then.
*/
int s_len = p_ap_encode_obj->s_outbuff - p_ap_encode_obj->pos_outbuff;
memcpy(p_ap_encode_obj->outbuff + p_ap_encode_obj->pos_outbuff,
out_string,
s_len);
memcpy(p_ap_encode_obj->b_overflow + p_ap_encode_obj->s_overflow,
out_string + s_len,
p_ap_encode_obj->s_overflow += (len - s_len));
p_ap_encode_obj->pos_outbuff += s_len;
return errEOB;
}
}
int fill_apple_mime_header(
appledouble_encode_object *p_ap_encode_obj)
{
int status;
char tmpstr[266];
#if 0
// strcpy(tmpstr, "Content-Type: multipart/mixed; boundary=\"-\"\n\n---\n");
// status = write_stream(p_ap_encode_env,
// tmpstr,
// strlen(tmpstr));
// if (status != noErr)
// return status;
PR_snprintf(tmpstr, sizeof(tmpstr),
"Content-Type: multipart/appledouble; boundary=\"=\"; name=\"");
status = write_stream(p_ap_encode_obj, (const char*)tmpstr, strlen(tmpstr));
if (status != noErr)
return status;
status = write_stream(p_ap_encode_obj,
p_ap_encode_obj->fname,
strlen(p_ap_encode_obj->fname));
if (status != noErr)
return status;
PR_snprintf(tmpstr, sizeof(tmpstr),
"\"\r\nContent-Disposition: inline; filename=\"%s\"\r\n\r\n\r\n--=\r\n",
p_ap_encode_obj->fname);
#endif /* 0 */
PR_snprintf(tmpstr, sizeof(tmpstr), "--%s" CRLF, p_ap_encode_obj->boundary);
status = write_stream(p_ap_encode_obj, (const char*)tmpstr, strlen(tmpstr));
return status;
}
int ap_encode_file_infor(
appledouble_encode_object *p_ap_encode_obj)
{
ap_header head;
ap_entry entries[NUM_ENTRIES];
ap_dates dates;
short i;
long comlen;
char comment[256];
int status;
nsCOMPtr <nsIFile> resFile;
NS_NewNativeLocalFile(nsDependentCString(p_ap_encode_obj->fname), true,
getter_AddRefs(resFile));
if (!resFile)
return errFileOpen;
FSRef ref;
nsCOMPtr <nsILocalFileMac> macFile = do_QueryInterface(resFile);
if (NS_FAILED(macFile->GetFSRef(&ref)))
return errFileOpen;
FSCatalogInfo catalogInfo;
if (::FSGetCatalogInfo(&ref, kFSCatInfoFinderInfo, &catalogInfo, nullptr, nullptr, nullptr) != noErr)
{
return errFileOpen;
}
/* get a file comment, if possible */
#if 1
// Carbon doesn't support GetWDInfo(). (Bug 555684)
// not sure why working directories are needed here...
comlen = 0;
#else
long procID;
procID = 0;
GetWDInfo(p_ap_encode_obj->vRefNum, &fpb->ioVRefNum, &fpb->ioDirID, &procID);
IOParam vinfo;
memset((void *) &vinfo, '\0', sizeof (vinfo));
GetVolParmsInfoBuffer vp;
vinfo.ioCompletion = nil;
vinfo.ioVRefNum = fpb->ioVRefNum;
vinfo.ioBuffer = (Ptr) &vp;
vinfo.ioReqCount = sizeof (vp);
comlen = 0;
if (PBHGetVolParmsSync((HParmBlkPtr) &vinfo) == noErr &&
((vp.vMAttrib >> bHasDesktopMgr) & 1))
{
DTPBRec dtp;
memset((void *) &dtp, '\0', sizeof (dtp));
dtp.ioVRefNum = fpb->ioVRefNum;
if (PBDTGetPath(&dtp) == noErr)
{
dtp.ioCompletion = nil;
dtp.ioDTBuffer = (Ptr) comment;
dtp.ioNamePtr = fpb->ioNamePtr;
dtp.ioDirID = fpb->ioFlParID;
if (PBDTGetCommentSync(&dtp) == noErr)
comlen = dtp.ioDTActCount;
}
}
#endif /* ! 1 */
/* write header */
// head.magic = dfork ? APPLESINGLE_MAGIC : APPLEDOUBLE_MAGIC;
head.magic = APPLEDOUBLE_MAGIC; /* always do apple double */
head.version = VERSION;
memset(head.fill, '\0', sizeof (head.fill));
head.entries = NUM_ENTRIES - 1;
status = to64(p_ap_encode_obj,
(char *) &head,
sizeof (head));
if (status != noErr)
return status;
/* write entry descriptors */
nsAutoCString leafname;
macFile->GetNativeLeafName(leafname);
entries[0].offset = sizeof (head) + sizeof (ap_entry) * head.entries;
entries[0].id = ENT_NAME;
entries[0].length = leafname.Length();
entries[1].id = ENT_FINFO;
entries[1].length = sizeof (FInfo) + sizeof (FXInfo);
entries[2].id = ENT_DATES;
entries[2].length = sizeof (ap_dates);
entries[3].id = ENT_COMMENT;
entries[3].length = comlen;
entries[4].id = ENT_RFORK;
entries[4].length = catalogInfo.rsrcLogicalSize;
entries[5].id = ENT_DFORK;
entries[5].length = catalogInfo.dataLogicalSize;
/* correct the link in the entries. */
for (i = 1; i < NUM_ENTRIES; ++i)
{
entries[i].offset = entries[i-1].offset + entries[i-1].length;
}
status = to64(p_ap_encode_obj,
(char *) entries,
sizeof (ap_entry) * head.entries);
if (status != noErr)
return status;
/* write name */
status = to64(p_ap_encode_obj,
(char *) leafname.get(),
leafname.Length());
if (status != noErr)
return status;
/* write finder info */
status = to64(p_ap_encode_obj,
(char *) &catalogInfo.finderInfo,
sizeof (FInfo));
if (status != noErr)
return status;
status = to64(p_ap_encode_obj,
(char *) &catalogInfo.extFinderInfo,
sizeof (FXInfo));
if (status != noErr)
return status;
/* write dates */
dates.create = catalogInfo.createDate.lowSeconds + CONVERT_TIME;
dates.modify = catalogInfo.contentModDate.lowSeconds + CONVERT_TIME;
dates.backup = catalogInfo.backupDate.lowSeconds + CONVERT_TIME;
dates.access = catalogInfo.accessDate.lowSeconds + CONVERT_TIME;
status = to64(p_ap_encode_obj,
(char *) &dates,
sizeof (ap_dates));
if (status != noErr)
return status;
/* write comment */
if (comlen)
{
status = to64(p_ap_encode_obj,
comment,
comlen * sizeof(char));
}
/*
** Get some help information on deciding the file type.
*/
if (((FileInfo*)(&catalogInfo.finderInfo))->fileType == 'TEXT' ||
((FileInfo*)(&catalogInfo.finderInfo))->fileType == 'text')
{
p_ap_encode_obj->text_file_type = true;
}
return status;
}
/*
** ap_encode_header
**
** encode the file header and the resource fork.
**
*/
int ap_encode_header(
appledouble_encode_object* p_ap_encode_obj,
bool firstime)
{
char rd_buff[256];
FSIORefNum fileId;
OSErr retval = noErr;
int status;
ByteCount inCount;
if (firstime)
{
PL_strcpy(rd_buff,
"Content-Type: application/applefile\r\nContent-Transfer-Encoding: base64\r\n\r\n");
status = write_stream(p_ap_encode_obj, (const char*)rd_buff, strlen(rd_buff));
if (status != noErr)
return status;
status = ap_encode_file_infor(p_ap_encode_obj);
if (status != noErr)
return status;
/*
** preparing to encode the resource fork.
*/
nsCOMPtr <nsIFile> myFile;
NS_NewNativeLocalFile(nsDependentCString(p_ap_encode_obj->fname), true, getter_AddRefs(myFile));
if (!myFile)
return errFileOpen;
FSRef ref;
nsCOMPtr <nsILocalFileMac> macFile = do_QueryInterface(myFile);
if (NS_FAILED(macFile->GetFSRef(&ref)))
return errFileOpen;
HFSUniStr255 forkName;
::FSGetResourceForkName(&forkName);
retval = ::FSOpenFork(&ref, forkName.length, forkName.unicode, fsRdPerm, &p_ap_encode_obj->fileId);
if (retval != noErr)
return retval;
}
fileId = p_ap_encode_obj->fileId;
while (retval == noErr)
{
if (BUFF_LEFT(p_ap_encode_obj) < 400)
break;
inCount = 0;
retval = ::FSReadFork(fileId, fsAtMark, 0, 256, rd_buff, &inCount);
if (inCount)
{
status = to64(p_ap_encode_obj,
rd_buff,
inCount);
if (status != noErr)
return status;
}
}
if (retval == eofErr)
{
::FSCloseFork(fileId);
p_ap_encode_obj->fileId = 0;
status = finish64(p_ap_encode_obj);
if (status != noErr)
return status;
/*
** write out the boundary
*/
PR_snprintf(rd_buff, sizeof(rd_buff),
CRLF "--%s" CRLF,
p_ap_encode_obj->boundary);
status = write_stream(p_ap_encode_obj, (const char*)rd_buff, strlen(rd_buff));
if (status == noErr)
status = errDone;
}
return status;
}
#if 0
// This is unused for now and Clang complains about that is it is ifdefed out
static void replace(char *p, int len, char frm, char to)
{
for (; len > 0; len--, p++)
if (*p == frm) *p = to;
}
#endif
/* Description of the various file formats and their magic numbers */
struct magic
{
const char *name; /* Name of the file format */
const char *num; /* The magic number */
int len; /* Length (0 means strlen(magicnum)) */
};
/* The magic numbers of the file formats we know about */
static struct magic magic[] =
{
{ "image/gif", "GIF", 0 },
{ "image/jpeg", "\377\330\377", 0 },
{ "video/mpeg", "\0\0\001\263", 4 },
{ "application/postscript", "%!", 0 },
};
static int num_magic = MOZ_ARRAY_LENGTH(magic);
static const char *text_type = TEXT_PLAIN; /* the text file type. */
static const char *default_type = APPLICATION_OCTET_STREAM;
/*
* Determins the format of the file "inputf". The name
* of the file format (or NULL on error) is returned.
*/
static const char *magic_look(char *inbuff, int numread)
{
int i, j;
for (i=0; i<num_magic; i++)
{
if (magic[i].len == 0)
magic[i].len = strlen(magic[i].num);
}
for (i=0; i<num_magic; i++)
{
if (numread >= magic[i].len)
{
for (j=0; j<magic[i].len; j++)
{
if (inbuff[j] != magic[i].num[j]) break;
}
if (j == magic[i].len)
return magic[i].name;
}
}
return default_type;
}
/*
** ap_encode_data
**
** ---------------
**
** encode on the data fork.
**
*/
int ap_encode_data(
appledouble_encode_object* p_ap_encode_obj,
bool firstime)
{
char rd_buff[256];
FSIORefNum fileId;
OSErr retval = noErr;
ByteCount in_count;
int status;
if (firstime)
{
const char* magic_type;
/*
** preparing to encode the data fork.
*/
nsCOMPtr <nsIFile> resFile;
NS_NewNativeLocalFile(nsDependentCString(p_ap_encode_obj->fname), true,
getter_AddRefs(resFile));
if (!resFile)
return errFileOpen;
FSRef ref;
nsCOMPtr <nsILocalFileMac> macFile = do_QueryInterface(resFile);
if (NS_FAILED(macFile->GetFSRef(&ref)))
return errFileOpen;
HFSUniStr255 forkName;
::FSGetDataForkName(&forkName);
retval = ::FSOpenFork(&ref, forkName.length, forkName.unicode, fsRdPerm, &fileId);
if (retval != noErr)
return retval;
p_ap_encode_obj->fileId = fileId;
if (!p_ap_encode_obj->text_file_type)
{
/*
** do a smart check for the file type.
*/
in_count = 0;
retval = ::FSReadFork(fileId, fsFromStart, 0, 256, rd_buff, &in_count);
magic_type = magic_look(rd_buff, in_count);
/* don't forget to rewind the index to start point. */
::FSSetForkPosition(fileId, fsFromStart, 0);
/* and reset retVal just in case... */
if (retval == eofErr)
retval = noErr;
}
else
{
magic_type = text_type; /* we already know it is a text type. */
}
/*
** the data portion header information.
*/
nsAutoCString leafName;
resFile->GetNativeLeafName(leafName);
PR_snprintf(rd_buff, sizeof(rd_buff),
"Content-Type: %s; name=\"%s\"" CRLF "Content-Transfer-Encoding: base64" CRLF "Content-Disposition: inline; filename=\"%s\"" CRLF CRLF,
magic_type,
leafName.get(),
leafName.get());
status = write_stream(p_ap_encode_obj, (const char*)rd_buff, strlen(rd_buff));
if (status != noErr)
return status;
}
while (retval == noErr)
{
if (BUFF_LEFT(p_ap_encode_obj) < 400)
break;
in_count = 0;
retval = ::FSReadFork(p_ap_encode_obj->fileId, fsAtMark, 0, 256, rd_buff, &in_count);
if (in_count)
{
#if 0
/* replace(rd_buff, in_count, '\r', '\n'); */
#endif
/* ** may be need to do character set conversion here for localization. ** */
status = to64(p_ap_encode_obj,
rd_buff,
in_count);
if (status != noErr)
return status;
}
}
if (retval == eofErr)
{
::FSCloseFork(p_ap_encode_obj->fileId);
p_ap_encode_obj->fileId = 0;
status = finish64(p_ap_encode_obj);
if (status != noErr)
return status;
/* write out the boundary */
PR_snprintf(rd_buff, sizeof(rd_buff),
CRLF "--%s--" CRLF CRLF,
p_ap_encode_obj->boundary);
status = write_stream(p_ap_encode_obj, (const char*)rd_buff, strlen(rd_buff));
if (status == noErr)
status = errDone;
}
return status;
}
static char basis_64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/*
** convert the stream in the inbuff to 64 format and put it in the out buff.
** To make the life easier, the caller will responcable of the cheking of the outbuff's bundary.
*/
static int
to64(appledouble_encode_object* p_ap_encode_obj,
char *p,
int in_size)
{
int status;
int c1, c2, c3, ct;
unsigned char *inbuff = (unsigned char*)p;
ct = p_ap_encode_obj->ct; /* the char count left last time. */
/*
** resume the left state of the last conversion.
*/
switch (p_ap_encode_obj->state64)
{
case 0:
p_ap_encode_obj->c1 = c1 = *inbuff ++;
if (--in_size <= 0)
{
p_ap_encode_obj->state64 = 1;
return noErr;
}
p_ap_encode_obj->c2 = c2 = *inbuff ++;
if (--in_size <= 0)
{
p_ap_encode_obj->state64 = 2;
return noErr;
}
c3 = *inbuff ++; --in_size;
break;
case 1:
c1 = p_ap_encode_obj->c1;
p_ap_encode_obj->c2 = c2 = *inbuff ++;
if (--in_size <= 0)
{
p_ap_encode_obj->state64 = 2;
return noErr;
}
c3 = *inbuff ++; --in_size;
break;
case 2:
c1 = p_ap_encode_obj->c1;
c2 = p_ap_encode_obj->c2;
c3 = *inbuff ++; --in_size;
break;
}
while (in_size >= 0)
{
status = output64chunk(p_ap_encode_obj,
c1,
c2,
c3,
0);
if (status != noErr)
return status;
ct += 4;
if (ct > 71)
{
status = write_stream(p_ap_encode_obj,
CRLF,
2);
if (status != noErr)
return status;
ct = 0;
}
if (in_size <= 0)
{
p_ap_encode_obj->state64 = 0;
break;
}
c1 = (int)*inbuff++;
if (--in_size <= 0)
{
p_ap_encode_obj->c1 = c1;
p_ap_encode_obj->state64 = 1;
break;
}
c2 = *inbuff++;
if (--in_size <= 0)
{
p_ap_encode_obj->c1 = c1;
p_ap_encode_obj->c2 = c2;
p_ap_encode_obj->state64 = 2;
break;
}
c3 = *inbuff++;
in_size--;
}
p_ap_encode_obj->ct = ct;
return status;
}
/*
** clear the left base64 encodes.
*/
static int
finish64(appledouble_encode_object* p_ap_encode_obj)
{
int status;
switch (p_ap_encode_obj->state64)
{
case 0:
break;
case 1:
status = output64chunk(p_ap_encode_obj,
p_ap_encode_obj->c1,
0,
0,
2);
break;
case 2:
status = output64chunk(p_ap_encode_obj,
p_ap_encode_obj->c1,
p_ap_encode_obj->c2,
0,
1);
break;
}
status = write_stream(p_ap_encode_obj, CRLF, 2);
p_ap_encode_obj->state64 = 0;
p_ap_encode_obj->ct = 0;
return status;
}
static int output64chunk(
appledouble_encode_object* p_ap_encode_obj,
int c1, int c2, int c3, int pads)
{
char tmpstr[32];
char *p = tmpstr;
*p++ = basis_64[c1>>2];
*p++ = basis_64[((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4)];
if (pads == 2)
{
*p++ = '=';
*p++ = '=';
}
else if (pads)
{
*p++ = basis_64[((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6)];
*p++ = '=';
}
else
{
*p++ = basis_64[((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6)];
*p++ = basis_64[c3 & 0x3F];
}
return write_stream(p_ap_encode_obj, (const char*) tmpstr, p-tmpstr);
}

View file

@ -36,6 +36,77 @@
#include "mozilla/mailnews/MimeEncoder.h"
#include "nsIPrincipal.h"
///////////////////////////////////////////////////////////////////////////
// Mac Specific Attachment Handling for AppleDouble Encoded Files
///////////////////////////////////////////////////////////////////////////
#ifdef XP_MACOSX
#define AD_WORKING_BUFF_SIZE FILE_IO_BUFFER_SIZE
extern void MacGetFileType(nsIFile *fs, bool *useDefault, char **type, char **encoding);
#include "nsILocalFileMac.h"
/* static */
nsresult nsSimpleZipper::Zip(nsIFile *aInputFile, nsIFile *aOutputFile)
{
// create zipwriter object
nsresult rv;
nsCOMPtr<nsIZipWriter> zipWriter = do_CreateInstance("@mozilla.org/zipwriter;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = zipWriter->Open(aOutputFile, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE);
NS_ENSURE_SUCCESS(rv, rv);
rv = AddToZip(zipWriter, aInputFile, EmptyCString());
NS_ENSURE_SUCCESS(rv, rv);
// we're done.
zipWriter->Close();
return rv;
}
/* static */
nsresult nsSimpleZipper::AddToZip(nsIZipWriter *aZipWriter,
nsIFile *aFile,
const nsACString &aPath)
{
// find out the path this file/dir should have in the zip
nsCString leafName;
aFile->GetNativeLeafName(leafName);
nsCString currentPath(aPath);
currentPath += leafName;
bool isDirectory;
aFile->IsDirectory(&isDirectory);
// append slash for a directory entry
if (isDirectory)
currentPath.Append('/');
// add the file or directory entry to the zip
nsresult rv = aZipWriter->AddEntryFile(currentPath, nsIZipWriter::COMPRESSION_DEFAULT, aFile, false);
NS_ENSURE_SUCCESS(rv, rv);
// if it's a directory, add all its contents too
if (isDirectory) {
nsCOMPtr<nsISimpleEnumerator> e;
nsresult rv = aFile->GetDirectoryEntries(getter_AddRefs(e));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDirectoryEnumerator> dirEnumerator = do_QueryInterface(e, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIFile> currentFile;
while (NS_SUCCEEDED(dirEnumerator->GetNextFile(getter_AddRefs(currentFile))) && currentFile) {
rv = AddToZip(aZipWriter, currentFile, currentPath);
NS_ENSURE_SUCCESS(rv, rv);
}
}
return NS_OK;
}
#endif // XP_MACOSX
//
// Class implementation...
//
@ -168,7 +239,12 @@ NS_IMETHODIMP nsMsgAttachmentHandler::GetAlreadyEncoded(bool* aAlreadyEncoded)
void
nsMsgAttachmentHandler::CleanupTempFile()
{
/** Mac Stub **/
#ifdef XP_MACOSX
if (mEncodedWorkingFile) {
mEncodedWorkingFile->Remove(false);
mEncodedWorkingFile = nullptr;
}
#endif // XP_MACOSX
}
void
@ -473,8 +549,13 @@ FetcherURLDoneCallback(nsresult aStatus,
ma->m_size = totalSize;
if (!aContentType.IsEmpty())
{
// can't send appledouble on non-macs
#ifdef XP_MACOSX
//Do not change the type if we are dealing with an encoded (e.g., appledouble or zip) file
if (!ma->mEncodedWorkingFile)
#else
// can't send appledouble on non-macs
if (!aContentType.EqualsLiteral("multipart/appledouble"))
#endif
ma->m_type = aContentType;
}
@ -617,6 +698,15 @@ done:
return rv;
}
#ifdef XP_MACOSX
bool nsMsgAttachmentHandler::HasResourceFork(FSRef *fsRef)
{
FSCatalogInfo catalogInfo;
OSErr err = FSGetCatalogInfo(fsRef, kFSCatInfoDataSizes + kFSCatInfoRsrcSizes, &catalogInfo, nullptr, nullptr, nullptr);
return (err == noErr && catalogInfo.rsrcLogicalSize != 0);
}
#endif
nsresult
nsMsgAttachmentHandler::SnarfAttachment(nsMsgCompFields *compFields)
{
@ -657,6 +747,33 @@ nsMsgAttachmentHandler::SnarfAttachment(nsMsgCompFields *compFields)
nsCString sourceURISpec;
rv = mURL->GetSpec(sourceURISpec);
NS_ENSURE_SUCCESS(rv, rv);
#ifdef XP_MACOSX
if (!m_bogus_attachment && StringBeginsWith(sourceURISpec, NS_LITERAL_CSTRING("file://")))
{
// Unescape the path (i.e. un-URLify it) before making a FSSpec
nsAutoCString filePath;
filePath.Adopt(nsMsgGetLocalFileFromURL(sourceURISpec.get()));
nsAutoCString unescapedFilePath;
MsgUnescapeString(filePath, 0, unescapedFilePath);
nsCOMPtr<nsIFile> sourceFile;
NS_NewNativeLocalFile(unescapedFilePath, true, getter_AddRefs(sourceFile));
if (!sourceFile)
return NS_ERROR_FAILURE;
// check if it is a bundle. if it is, we'll zip it.
// if not, we'll apple encode it (applesingle or appledouble)
nsCOMPtr<nsILocalFileMac> macFile(do_QueryInterface(sourceFile));
bool isPackage;
macFile->IsPackage(&isPackage);
if (isPackage)
rv = ConvertToZipFile(macFile);
else
rv = ConvertToAppleEncoding(sourceURISpec, unescapedFilePath, macFile);
NS_ENSURE_SUCCESS(rv, rv);
}
#endif /* XP_MACOSX */
//
// Ok, here we are, we need to fire the URL off and get the data
@ -676,6 +793,236 @@ nsMsgAttachmentHandler::SnarfAttachment(nsMsgCompFields *compFields)
return fetcher->FireURLRequest(mURL, mTmpFile, mOutFile, FetcherURLDoneCallback, this);
}
#ifdef XP_MACOSX
nsresult
nsMsgAttachmentHandler::ConvertToZipFile(nsILocalFileMac *aSourceFile)
{
// append ".zip" to the real file name
nsAutoCString zippedName;
nsresult rv = aSourceFile->GetNativeLeafName(zippedName);
NS_ENSURE_SUCCESS(rv, rv);
zippedName.AppendLiteral(".zip");
// create a temporary file that we'll work on
nsCOMPtr <nsIFile> tmpFile;
rv = nsMsgCreateTempFile(zippedName.get(), getter_AddRefs(tmpFile));
NS_ENSURE_SUCCESS(rv, rv);
mEncodedWorkingFile = do_QueryInterface(tmpFile);
// point our URL at the zipped temp file
NS_NewFileURI(getter_AddRefs(mURL), mEncodedWorkingFile);
// zip it!
rv = nsSimpleZipper::Zip(aSourceFile, mEncodedWorkingFile);
NS_ENSURE_SUCCESS(rv, rv);
// set some metadata for this attachment, that will affect the MIME headers.
m_type = APPLICATION_ZIP;
m_realName = zippedName.get();
return NS_OK;
}
nsresult
nsMsgAttachmentHandler::ConvertToAppleEncoding(const nsCString &aFileURI,
const nsCString &aFilePath,
nsILocalFileMac *aSourceFile)
{
// convert the apple file to AppleDouble first, and then patch the
// address in the url.
//We need to retrieve the file type and creator...
char fileInfo[32];
OSType type, creator;
nsresult rv = aSourceFile->GetFileType(&type);
if (NS_FAILED(rv))
return rv;
PR_snprintf(fileInfo, sizeof(fileInfo), "%X", type);
m_xMacType = fileInfo;
rv = aSourceFile->GetFileCreator(&creator);
if (NS_FAILED(rv))
return rv;
PR_snprintf(fileInfo, sizeof(fileInfo), "%X", creator);
m_xMacCreator = fileInfo;
FSRef fsRef;
aSourceFile->GetFSRef(&fsRef);
bool sendResourceFork = HasResourceFork(&fsRef);
// if we have a resource fork, check the filename extension, maybe we don't need the resource fork!
if (sendResourceFork)
{
nsCOMPtr<nsIURL> fileUrl(do_CreateInstance(NS_STANDARDURL_CONTRACTID));
if (fileUrl)
{
rv = fileUrl->SetSpec(aFileURI);
if (NS_SUCCEEDED(rv))
{
nsAutoCString ext;
rv = fileUrl->GetFileExtension(ext);
if (NS_SUCCEEDED(rv) && !ext.IsEmpty())
{
sendResourceFork =
PL_strcasecmp(ext.get(), "TXT") &&
PL_strcasecmp(ext.get(), "JPG") &&
PL_strcasecmp(ext.get(), "GIF") &&
PL_strcasecmp(ext.get(), "TIF") &&
PL_strcasecmp(ext.get(), "HTM") &&
PL_strcasecmp(ext.get(), "HTML") &&
PL_strcasecmp(ext.get(), "ART") &&
PL_strcasecmp(ext.get(), "XUL") &&
PL_strcasecmp(ext.get(), "XML") &&
PL_strcasecmp(ext.get(), "CSS") &&
PL_strcasecmp(ext.get(), "JS");
}
}
}
}
// Only use appledouble if we aren't uuencoding.
if( sendResourceFork )
{
char *separator;
separator = mime_make_separator("ad");
if (!separator)
return NS_ERROR_OUT_OF_MEMORY;
nsCOMPtr <nsIFile> tmpFile;
nsresult rv = nsMsgCreateTempFile("appledouble", getter_AddRefs(tmpFile));
if (NS_SUCCEEDED(rv))
mEncodedWorkingFile = do_QueryInterface(tmpFile);
if (!mEncodedWorkingFile)
{
PR_FREEIF(separator);
return NS_ERROR_OUT_OF_MEMORY;
}
//
// RICHIE_MAC - ok, here's the deal, we have a file that we need
// to encode in appledouble encoding for the resource fork and put that
// into the mEncodedWorkingFile location. Then, we need to patch the new file
// spec into the array and send this as part of the 2 part appledouble/mime
// encoded mime part.
//
AppleDoubleEncodeObject *obj = new (AppleDoubleEncodeObject);
if (obj == NULL)
{
mEncodedWorkingFile = nullptr;
PR_FREEIF(separator);
return NS_ERROR_OUT_OF_MEMORY;
}
rv = MsgGetFileStream(mEncodedWorkingFile, getter_AddRefs(obj->fileStream));
if (NS_FAILED(rv) || !obj->fileStream)
{
PR_FREEIF(separator);
delete obj;
return NS_ERROR_OUT_OF_MEMORY;
}
char *working_buff = (char *) PR_Malloc(AD_WORKING_BUFF_SIZE);
if (!working_buff)
{
PR_FREEIF(separator);
delete obj;
return NS_ERROR_OUT_OF_MEMORY;
}
obj->buff = working_buff;
obj->s_buff = AD_WORKING_BUFF_SIZE;
//
// Setup all the need information on the apple double encoder.
//
ap_encode_init(&(obj->ap_encode_obj), aFilePath.get(), separator);
int32_t count;
OSErr status = noErr;
m_size = 0;
while (status == noErr)
{
status = ap_encode_next(&(obj->ap_encode_obj), obj->buff, obj->s_buff, &count);
if (status == noErr || status == errDone)
{
//
// we got the encode data, so call the next stream to write it to the disk.
//
uint32_t bytesWritten;
obj->fileStream->Write(obj->buff, count, &bytesWritten);
if (bytesWritten != (uint32_t) count)
status = errFileWrite;
}
}
ap_encode_end(&(obj->ap_encode_obj), (status >= 0)); // if this is true, ok, false abort
if (obj->fileStream)
obj->fileStream->Close();
PR_FREEIF(obj->buff); /* free the working buff. */
PR_FREEIF(obj);
nsCOMPtr <nsIURI> fileURI;
NS_NewFileURI(getter_AddRefs(fileURI), mEncodedWorkingFile);
nsCOMPtr<nsIFileURL> theFileURL = do_QueryInterface(fileURI, &rv);
NS_ENSURE_SUCCESS(rv,rv);
nsCString newURLSpec;
rv = fileURI->GetSpec(newURLSpec);
NS_ENSURE_SUCCESS(rv, rv);
if (newURLSpec.IsEmpty())
{
PR_FREEIF(separator);
return NS_ERROR_OUT_OF_MEMORY;
}
if (NS_FAILED(nsMsgNewURL(getter_AddRefs(mURL), newURLSpec.get())))
{
PR_FREEIF(separator);
return NS_ERROR_OUT_OF_MEMORY;
}
// Now after conversion, also patch the types.
char tmp[128];
PR_snprintf(tmp, sizeof(tmp), MULTIPART_APPLEDOUBLE ";\r\n boundary=\"%s\"", separator);
PR_FREEIF(separator);
m_type = tmp;
}
else
{
if ( sendResourceFork )
{
// For now, just do the encoding, but in the old world we would ask the
// user about doing this conversion
printf("...we could ask the user about this conversion, but for now, nahh..\n");
}
bool useDefault;
char *macType, *macEncoding;
if (m_type.IsEmpty() || m_type.LowerCaseEqualsLiteral(TEXT_PLAIN))
{
# define TEXT_TYPE 0x54455854 /* the characters 'T' 'E' 'X' 'T' */
# define text_TYPE 0x74657874 /* the characters 't' 'e' 'x' 't' */
if (type != TEXT_TYPE && type != text_TYPE)
{
MacGetFileType(aSourceFile, &useDefault, &macType, &macEncoding);
m_type = macType;
}
}
// don't bother to set the types if we failed in getting the file info.
}
return NS_OK;
}
#endif // XP_MACOSX
nsresult
nsMsgAttachmentHandler::LoadDataFromFile(nsIFile *file, nsString &sigData, bool charsetConversion)
{

View file

@ -16,6 +16,42 @@
#include "nsAutoPtr.h"
#include "nsIMsgAttachmentHandler.h"
#ifdef XP_MACOSX
#include "nsMsgAppleDouble.h"
#include "nsILocalFileMac.h"
class AppleDoubleEncodeObject
{
public:
appledouble_encode_object ap_encode_obj;
char *buff; // the working buff
int32_t s_buff; // the working buff size
nsCOMPtr <nsIOutputStream> fileStream; // file to hold the encoding
};
class nsILocalFileMac;
class nsIZipWriter;
/* Simple utility class that will synchronously zip any file
(or folder hierarchy) you give it. */
class nsSimpleZipper
{
public:
// Synchronously zips the input file/folder and writes all
// data to the output file.
static nsresult Zip(nsIFile *aInputFile, nsIFile *aOutputFile);
private:
// Recursively adds the file or folder to aZipWriter.
static nsresult AddToZip(nsIZipWriter *aZipWriter,
nsIFile *aFile,
const nsACString &aPath);
};
#endif // XP_MACOSX
namespace mozilla {
namespace mailnews {
class MimeEncoder;
@ -59,6 +95,14 @@ private:
bool UseUUEncode_p(void);
void AnalyzeDataChunk (const char *chunk, int32_t chunkSize);
nsresult LoadDataFromFile(nsIFile *file, nsString &sigData, bool charsetConversion); //A similar function already exist in nsMsgCompose!
#ifdef XP_MACOSX
nsresult ConvertToAppleEncoding(const nsCString &aFileSpecURI,
const nsCString &aFilePath,
nsILocalFileMac *aSourceFile);
// zips this attachment and does the work to make this attachment handler handle it properly.
nsresult ConvertToZipFile(nsILocalFileMac *aSourceFile);
bool HasResourceFork(FSRef *fsRef);
#endif
//
public:
@ -69,6 +113,12 @@ public:
nsMsgCompFields *mCompFields; // Message composition fields for the sender
bool m_bogus_attachment; // This is to catch problem children...
#ifdef XP_MACOSX
// if we need to encode this file into for example an appledouble, or zip file,
// this file is our working file. currently only needed on mac.
nsCOMPtr<nsIFile> mEncodedWorkingFile;
#endif
nsCString m_xMacType; // Mac file type
nsCString m_xMacCreator; // Mac file creator

View file

@ -2088,7 +2088,9 @@ nsMsgComposeAndSend::AddCompFieldLocalAttachments()
if (NS_SUCCEEDED(rv) && !fileExt.IsEmpty()) {
nsAutoCString type;
mimeFinder->GetTypeFromExtension(fileExt, type);
#ifndef XP_MACOSX
if (!type.Equals("multipart/appledouble")) // can't do apple double on non-macs
#endif
m_attachments[newLoc]->m_type = type;
}
}
@ -2103,7 +2105,9 @@ nsMsgComposeAndSend::AddCompFieldLocalAttachments()
if (NS_SUCCEEDED(rv) && !fileExt.IsEmpty()) {
nsAutoCString type;
mimeFinder->GetTypeFromExtension(fileExt, type);
#ifndef XP_MACOSX
if (!type.Equals("multipart/appledouble")) // can't do apple double on non-macs
#endif
m_attachments[newLoc]->m_type = type;
// rtf and vcs files may look like text to sniffers,
// but they're not human readable.