* mail_util.h was not self-contained.
* Added a few missing breaks in MailProtocolThread::MessageReceived()! * Minor coding style update. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42808 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
|
* Copyright 2011, Haiku, Inc. All rights reserved.
|
||||||
* Copyright 2001-2003 Dr. Zoidberg Enterprises. All rights reserved.
|
* Copyright 2001-2003 Dr. Zoidberg Enterprises. All rights reserved.
|
||||||
*/
|
*/
|
||||||
#ifndef ZOIDBERG_GARGOYLE_MAIL_UTIL_H
|
#ifndef ZOIDBERG_GARGOYLE_MAIL_UTIL_H
|
||||||
@@ -10,9 +11,10 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include <Node.h>
|
#include <DataIO.h>
|
||||||
|
|
||||||
#include <E-mail.h>
|
#include <E-mail.h>
|
||||||
|
#include <Message.h>
|
||||||
|
#include <Node.h>
|
||||||
|
|
||||||
|
|
||||||
// TODO: this should only be preserved for gcc2 compatibility
|
// TODO: this should only be preserved for gcc2 compatibility
|
||||||
@@ -60,7 +62,7 @@ ssize_t utf8_to_rfc2047(char **bufp, ssize_t length,uint32 charset, char encodin
|
|||||||
// Unidentified charsets and conversion errors cause
|
// Unidentified charsets and conversion errors cause
|
||||||
// the offending text to be skipped.
|
// the offending text to be skipped.
|
||||||
|
|
||||||
void FoldLineAtWhiteSpaceAndAddCRLF (BString &string);
|
void FoldLineAtWhiteSpaceAndAddCRLF(BString &string);
|
||||||
// Insert CRLF at various spots in the given string (before white space) so
|
// Insert CRLF at various spots in the given string (before white space) so
|
||||||
// that the line length is mostly under 78 bytes. Also makes sure there is a
|
// that the line length is mostly under 78 bytes. Also makes sure there is a
|
||||||
// CRLF at the very end.
|
// CRLF at the very end.
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2011, Haiku, Inc. All rights reserved.
|
* Copyright 2011, Haiku, Inc. All rights reserved.
|
||||||
* Copyright 2011, Clemens Zeidler <[email protected]>
|
* Copyright 2011, Clemens Zeidler <[email protected]>
|
||||||
|
* Copyright 2001-2003 Dr. Zoidberg Enterprises. All rights reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -17,9 +18,8 @@
|
|||||||
|
|
||||||
|
|
||||||
struct mail_header_field {
|
struct mail_header_field {
|
||||||
const char *rfc_name;
|
const char* rfc_name;
|
||||||
|
const char* attr_name;
|
||||||
const char *attr_name;
|
|
||||||
type_code attr_type;
|
type_code attr_type;
|
||||||
// currently either B_STRING_TYPE and B_TIME_TYPE
|
// currently either B_STRING_TYPE and B_TIME_TYPE
|
||||||
};
|
};
|
||||||
@@ -65,7 +65,7 @@ HaikuMailFormatFilter::HeaderFetched(const entry_ref& ref, BFile* file)
|
|||||||
file->Seek(0, SEEK_SET);
|
file->Seek(0, SEEK_SET);
|
||||||
|
|
||||||
BMessage attributes;
|
BMessage attributes;
|
||||||
// TODO attributes.AddInt32(B_MAIL_ATTR_CONTENT, length);
|
// TODO: attributes.AddInt32(B_MAIL_ATTR_CONTENT, length);
|
||||||
attributes.AddInt32(B_MAIL_ATTR_ACCOUNT_ID, fAccountID);
|
attributes.AddInt32(B_MAIL_ATTR_ACCOUNT_ID, fAccountID);
|
||||||
attributes.AddString(B_MAIL_ATTR_ACCOUNT, fAccountName);
|
attributes.AddString(B_MAIL_ATTR_ACCOUNT, fAccountName);
|
||||||
|
|
||||||
@@ -83,6 +83,7 @@ HaikuMailFormatFilter::HeaderFetched(const entry_ref& ref, BFile* file)
|
|||||||
gDefaultFields[i].rfc_name, target);
|
gDefaultFields[i].rfc_name, target);
|
||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
switch (gDefaultFields[i].attr_type){
|
switch (gDefaultFields[i].attr_type){
|
||||||
case B_STRING_TYPE:
|
case B_STRING_TYPE:
|
||||||
attributes.AddString(gDefaultFields[i].attr_name, target);
|
attributes.AddString(gDefaultFields[i].attr_name, target);
|
||||||
@@ -111,8 +112,9 @@ HaikuMailFormatFilter::HeaderFetched(const entry_ref& ref, BFile* file)
|
|||||||
if (name.Length() <= 0)
|
if (name.Length() <= 0)
|
||||||
name = "No Subject";
|
name = "No Subject";
|
||||||
attributes.AddString(B_MAIL_ATTR_THREAD, name);
|
attributes.AddString(B_MAIL_ATTR_THREAD, name);
|
||||||
|
// Avoid hidden files, starting with a dot.
|
||||||
if (name[0] == '.')
|
if (name[0] == '.')
|
||||||
name.Prepend ("_"); // Avoid hidden files, starting with a dot.
|
name.Prepend ("_");
|
||||||
|
|
||||||
// Convert the date into a year-month-day fixed digit width format, so that
|
// Convert the date into a year-month-day fixed digit width format, so that
|
||||||
// sorting by file name will give all the messages with the same subject in
|
// sorting by file name will give all the messages with the same subject in
|
||||||
@@ -120,23 +122,20 @@ HaikuMailFormatFilter::HeaderFetched(const entry_ref& ref, BFile* file)
|
|||||||
time_t dateAsTime = 0;
|
time_t dateAsTime = 0;
|
||||||
const time_t* datePntr;
|
const time_t* datePntr;
|
||||||
ssize_t dateSize;
|
ssize_t dateSize;
|
||||||
char numericDateString [40];
|
char numericDateString[40];
|
||||||
struct tm timeFields;
|
struct tm timeFields;
|
||||||
|
|
||||||
if (attributes.FindData(B_MAIL_ATTR_WHEN, B_TIME_TYPE,
|
if (attributes.FindData(B_MAIL_ATTR_WHEN, B_TIME_TYPE,
|
||||||
(const void**)&datePntr, &dateSize) == B_OK)
|
(const void**)&datePntr, &dateSize) == B_OK)
|
||||||
dateAsTime = *datePntr;
|
dateAsTime = *datePntr;
|
||||||
localtime_r(&dateAsTime, &timeFields);
|
localtime_r(&dateAsTime, &timeFields);
|
||||||
sprintf(numericDateString, "%04d%02d%02d%02d%02d%02d",
|
snprintf(numericDateString, sizeof(numericDateString),
|
||||||
timeFields.tm_year + 1900,
|
"%04d%02d%02d%02d%02d%02d",
|
||||||
timeFields.tm_mon + 1,
|
timeFields.tm_year + 1900, timeFields.tm_mon + 1, timeFields.tm_mday,
|
||||||
timeFields.tm_mday,
|
timeFields.tm_hour, timeFields.tm_min, timeFields.tm_sec);
|
||||||
timeFields.tm_hour,
|
|
||||||
timeFields.tm_min,
|
|
||||||
timeFields.tm_sec);
|
|
||||||
name << " " << numericDateString;
|
name << " " << numericDateString;
|
||||||
|
|
||||||
BString worker = attributes.FindString("MAIL:from");
|
BString worker = attributes.FindString(B_MAIL_ATTR_FROM);
|
||||||
extract_address_name(worker);
|
extract_address_name(worker);
|
||||||
name << " " << worker;
|
name << " " << worker;
|
||||||
|
|
||||||
@@ -149,8 +148,9 @@ HaikuMailFormatFilter::HeaderFetched(const entry_ref& ref, BFile* file)
|
|||||||
name.ReplaceAll('!', '_');
|
name.ReplaceAll('!', '_');
|
||||||
name.ReplaceAll('<', '_');
|
name.ReplaceAll('<', '_');
|
||||||
name.ReplaceAll('>', '_');
|
name.ReplaceAll('>', '_');
|
||||||
while (name.FindFirst(" ") >= 0) // Remove multiple spaces.
|
// Remove multiple spaces.
|
||||||
name.Replace(" " /* Old */, " " /* New */, 1024 /* Count */);
|
while (name.FindFirst(" ") >= 0)
|
||||||
|
name.Replace(" ", " ", 1024);
|
||||||
|
|
||||||
worker = name;
|
worker = name;
|
||||||
int32 identicalNumber = 1;
|
int32 identicalNumber = 1;
|
||||||
@@ -162,10 +162,10 @@ HaikuMailFormatFilter::HeaderFetched(const entry_ref& ref, BFile* file)
|
|||||||
worker << "_" << identicalNumber;
|
worker << "_" << identicalNumber;
|
||||||
status = _SetFileName(ref, worker);
|
status = _SetFileName(ref, worker);
|
||||||
}
|
}
|
||||||
if (status < B_OK)
|
if (status < B_OK) {
|
||||||
printf("FolderFilter::ProcessMailMessage: could not rename mail (%s)! "
|
printf("FolderFilter::ProcessMailMessage: could not rename mail (%s)! "
|
||||||
"(should be: %s)\n",strerror(status), worker.String());
|
"(should be: %s)\n",strerror(status), worker.String());
|
||||||
else {
|
} else {
|
||||||
entry_ref to(ref.device, ref.directory, worker);
|
entry_ref to(ref.device, ref.directory, worker);
|
||||||
fMailProtocol.FileRenamed(ref, to);
|
fMailProtocol.FileRenamed(ref, to);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/* BMailProtocol - the base class for protocol filters
|
/*
|
||||||
**
|
* Copyright 2011, Haiku, Inc. All rights reserved.
|
||||||
** Copyright 2001-2003 Dr. Zoidberg Enterprises. All rights reserved.
|
* Copyright 2001-2003 Dr. Zoidberg Enterprises. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -35,56 +35,65 @@
|
|||||||
using std::map;
|
using std::map;
|
||||||
|
|
||||||
|
|
||||||
|
const uint32 kMsgSyncMessages = '&SyM';
|
||||||
|
const uint32 kMsgDeleteMessage = '&DeM';
|
||||||
|
const uint32 kMsgAppendMessage = '&ApM';
|
||||||
|
|
||||||
|
const uint32 kMsgMoveFile = '&MoF';
|
||||||
|
const uint32 kMsgDeleteFile = '&DeF';
|
||||||
|
const uint32 kMsgFileRenamed = '&FiR';
|
||||||
|
const uint32 kMsgFileDeleted = '&FDe';
|
||||||
|
const uint32 kMsgInit = '&Ini';
|
||||||
|
|
||||||
|
const uint32 kMsgSendMessage = '&SeM';
|
||||||
|
|
||||||
|
|
||||||
MailFilter::MailFilter(MailProtocol& protocol, AddonSettings* settings)
|
MailFilter::MailFilter(MailProtocol& protocol, AddonSettings* settings)
|
||||||
:
|
:
|
||||||
fMailProtocol(protocol),
|
fMailProtocol(protocol),
|
||||||
fAddonSettings(settings)
|
fAddonSettings(settings)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MailFilter::~MailFilter()
|
MailFilter::~MailFilter()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
MailFilter::HeaderFetched(const entry_ref& ref, BFile* file)
|
MailFilter::HeaderFetched(const entry_ref& ref, BFile* file)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
MailFilter::BodyFetched(const entry_ref& ref, BFile* file)
|
MailFilter::BodyFetched(const entry_ref& ref, BFile* file)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
MailFilter::MailboxSynced(status_t status)
|
MailFilter::MailboxSynced(status_t status)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
MailFilter::MessageReadyToSend(const entry_ref& ref, BFile* file)
|
MailFilter::MessageReadyToSend(const entry_ref& ref, BFile* file)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
MailFilter::MessageSent(const entry_ref& ref, BFile* file)
|
MailFilter::MessageSent(const entry_ref& ref, BFile* file)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
MailProtocol::MailProtocol(BMailAccountSettings* settings)
|
MailProtocol::MailProtocol(BMailAccountSettings* settings)
|
||||||
:
|
:
|
||||||
fMailNotifier(NULL),
|
fMailNotifier(NULL),
|
||||||
@@ -379,6 +388,9 @@ MailProtocol::_LoadFilter(AddonSettings* filterSettings)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
InboundProtocol::InboundProtocol(BMailAccountSettings* settings)
|
InboundProtocol::InboundProtocol(BMailAccountSettings* settings)
|
||||||
:
|
:
|
||||||
MailProtocol(settings)
|
MailProtocol(settings)
|
||||||
@@ -408,6 +420,9 @@ InboundProtocol::MarkMessageAsRead(const entry_ref& ref, read_flags flag)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
OutboundProtocol::OutboundProtocol(BMailAccountSettings* settings)
|
OutboundProtocol::OutboundProtocol(BMailAccountSettings* settings)
|
||||||
:
|
:
|
||||||
MailProtocol(settings)
|
MailProtocol(settings)
|
||||||
@@ -422,11 +437,7 @@ OutboundProtocol::~OutboundProtocol()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const uint32 kMsgMoveFile = '&MoF';
|
// #pragma mark -
|
||||||
const uint32 kMsgDeleteFile = '&DeF';
|
|
||||||
const uint32 kMsgFileRenamed = '&FiR';
|
|
||||||
const uint32 kMsgFileDeleted = '&FDe';
|
|
||||||
const uint32 kMsgInit = '&Ini';
|
|
||||||
|
|
||||||
|
|
||||||
MailProtocolThread::MailProtocolThread(MailProtocol* protocol)
|
MailProtocolThread::MailProtocolThread(MailProtocol* protocol)
|
||||||
@@ -478,6 +489,7 @@ MailProtocolThread::MessageReceived(BMessage* message)
|
|||||||
entry_ref to;
|
entry_ref to;
|
||||||
message->FindRef("to", &to);
|
message->FindRef("to", &to);
|
||||||
fMailProtocol->FileRenamed(from, to);
|
fMailProtocol->FileRenamed(from, to);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case kMsgFileDeleted:
|
case kMsgFileDeleted:
|
||||||
@@ -486,6 +498,7 @@ MailProtocolThread::MessageReceived(BMessage* message)
|
|||||||
message->FindInt32("device",&node.device);
|
message->FindInt32("device",&node.device);
|
||||||
message->FindInt64("node", &node.node);
|
message->FindInt64("node", &node.node);
|
||||||
fMailProtocol->FileDeleted(node);
|
fMailProtocol->FileDeleted(node);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -538,9 +551,7 @@ MailProtocolThread::TriggerFileDeleted(const node_ref& node)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const uint32 kMsgSyncMessages = '&SyM';
|
// #pragma mark -
|
||||||
const uint32 kMsgDeleteMessage = '&DeM';
|
|
||||||
const uint32 kMsgAppendMessage = '&ApM';
|
|
||||||
|
|
||||||
|
|
||||||
InboundProtocolThread::InboundProtocolThread(InboundProtocol* protocol)
|
InboundProtocolThread::InboundProtocolThread(InboundProtocol* protocol)
|
||||||
@@ -613,6 +624,7 @@ InboundProtocolThread::MessageReceived(BMessage* message)
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
MailProtocolThread::MessageReceived(message);
|
MailProtocolThread::MessageReceived(message);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -671,7 +683,7 @@ InboundProtocolThread::_NotiyMailboxSynced(status_t status)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const uint32 kMsgSendMessage = '&SeM';
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
OutboundProtocolThread::OutboundProtocolThread(OutboundProtocol* protocol)
|
OutboundProtocolThread::OutboundProtocolThread(OutboundProtocol* protocol)
|
||||||
|
|||||||
+170
-192
@@ -1,15 +1,10 @@
|
|||||||
/* mail util - header parsing
|
/*
|
||||||
**
|
* Copyright 2011, Haiku, Inc. All rights reserved.
|
||||||
** Copyright 2001-2003 Dr. Zoidberg Enterprises. All rights reserved.
|
* Copyright 2001-2003 Dr. Zoidberg Enterprises. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <UTF8.h>
|
#include <mail_util.h>
|
||||||
#include <Message.h>
|
|
||||||
#include <String.h>
|
|
||||||
#include <Locker.h>
|
|
||||||
#include <DataIO.h>
|
|
||||||
#include <List.h>
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -18,27 +13,30 @@
|
|||||||
#include <regex.h>
|
#include <regex.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <List.h>
|
||||||
|
#include <Locker.h>
|
||||||
#include <parsedate.h>
|
#include <parsedate.h>
|
||||||
|
#include <String.h>
|
||||||
|
#include <UTF8.h>
|
||||||
|
|
||||||
#include <mail_encoding.h>
|
#include <mail_encoding.h>
|
||||||
|
|
||||||
#include <mail_util.h>
|
|
||||||
|
|
||||||
#include <CharacterSet.h>
|
#include <CharacterSet.h>
|
||||||
#include <CharacterSetRoster.h>
|
#include <CharacterSetRoster.h>
|
||||||
|
|
||||||
|
|
||||||
using namespace BPrivate;
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
|
||||||
#define CRLF "\r\n"
|
#define CRLF "\r\n"
|
||||||
|
|
||||||
struct CharsetConversionEntry
|
struct CharsetConversionEntry {
|
||||||
{
|
|
||||||
const char *charset;
|
const char *charset;
|
||||||
uint32 flavor;
|
uint32 flavor;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const CharsetConversionEntry mail_charsets [] =
|
extern const CharsetConversionEntry mail_charsets[] = {
|
||||||
{
|
|
||||||
// In order of authority, so when searching for the name for a particular
|
// In order of authority, so when searching for the name for a particular
|
||||||
// numbered conversion, start at the beginning of the array.
|
// numbered conversion, start at the beginning of the array.
|
||||||
{"iso-8859-1", B_ISO1_CONVERSION}, // MIME STANDARD
|
{"iso-8859-1", B_ISO1_CONVERSION}, // MIME STANDARD
|
||||||
@@ -86,6 +84,74 @@ extern const CharsetConversionEntry mail_charsets [] =
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static int32 gLocker = 0;
|
||||||
|
static size_t gNsub = 1;
|
||||||
|
static re_pattern_buffer gRe;
|
||||||
|
static re_pattern_buffer *gRebuf = NULL;
|
||||||
|
static unsigned char gTranslation[256];
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
handle_non_rfc2047_encoding(char **buffer, size_t *bufferLength,
|
||||||
|
size_t *sourceLength)
|
||||||
|
{
|
||||||
|
char *string = *buffer;
|
||||||
|
int32 length = *sourceLength;
|
||||||
|
int32 i;
|
||||||
|
|
||||||
|
// check for 8-bit characters
|
||||||
|
for (i = 0;i < length;i++)
|
||||||
|
if (string[i] & 0x80)
|
||||||
|
break;
|
||||||
|
if (i == length)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// check for groups of 8-bit characters - this code is not very smart;
|
||||||
|
// it just can detect some sort of single-byte encoded stuff, the rest
|
||||||
|
// is regarded as UTF-8
|
||||||
|
|
||||||
|
int32 singletons = 0,doubles = 0;
|
||||||
|
|
||||||
|
for (i = 0;i < length;i++)
|
||||||
|
{
|
||||||
|
if (string[i] & 0x80)
|
||||||
|
{
|
||||||
|
if ((string[i + 1] & 0x80) == 0)
|
||||||
|
singletons++;
|
||||||
|
else doubles++;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (singletons != 0) // can't be valid UTF-8 anymore, so we assume ISO-Latin-1
|
||||||
|
{
|
||||||
|
int32 state = 0;
|
||||||
|
// just to be sure
|
||||||
|
int32 destLength = length * 4 + 1;
|
||||||
|
int32 destBufferLength = destLength;
|
||||||
|
char *dest = (char*)malloc(destLength);
|
||||||
|
if (dest == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (convert_to_utf8(B_ISO1_CONVERSION, string, &length,dest,
|
||||||
|
&destLength, &state) == B_OK) {
|
||||||
|
*buffer = dest;
|
||||||
|
*bufferLength = destBufferLength;
|
||||||
|
*sourceLength = destLength;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
free(dest);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we assume a valid UTF-8 string here, but yes, we don't check it
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
write_read_attr(BNode& node, read_flags flag)
|
write_read_attr(BNode& node, read_flags flag)
|
||||||
{
|
{
|
||||||
@@ -93,7 +159,6 @@ write_read_attr(BNode& node, read_flags flag)
|
|||||||
< 0)
|
< 0)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
#if R5_COMPATIBLE
|
|
||||||
// manage the status string only if it currently has a "read" status
|
// manage the status string only if it currently has a "read" status
|
||||||
BString currentStatus;
|
BString currentStatus;
|
||||||
if (node.ReadAttrString(B_MAIL_ATTR_STATUS, ¤tStatus) == B_OK) {
|
if (node.ReadAttrString(B_MAIL_ATTR_STATUS, ¤tStatus) == B_OK) {
|
||||||
@@ -103,12 +168,12 @@ write_read_attr(BNode& node, read_flags flag)
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* statusString = (flag == B_READ) ? "Read"
|
const char* statusString = flag == B_READ ? "Read"
|
||||||
: (flag == B_SEEN) ? "Seen" : "New";
|
: flag == B_SEEN ? "Seen" : "New";
|
||||||
if (node.WriteAttr(B_MAIL_ATTR_STATUS, B_STRING_TYPE, 0, statusString,
|
if (node.WriteAttr(B_MAIL_ATTR_STATUS, B_STRING_TYPE, 0, statusString,
|
||||||
strlen(statusString)) < 0)
|
strlen(statusString)) < 0)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
#endif
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,7 +185,6 @@ read_read_attr(BNode& node, read_flags& flag)
|
|||||||
== sizeof(int32))
|
== sizeof(int32))
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
#if R5_COMPATIBLE
|
|
||||||
BString statusString;
|
BString statusString;
|
||||||
if (node.ReadAttrString(B_MAIL_ATTR_STATUS, &statusString) == B_OK) {
|
if (node.ReadAttrString(B_MAIL_ATTR_STATUS, &statusString) == B_OK) {
|
||||||
if (statusString.ICompare("New"))
|
if (statusString.ICompare("New"))
|
||||||
@@ -130,24 +194,20 @@ read_read_attr(BNode& node, read_flags& flag)
|
|||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// The next couple of functions are our wrapper around convert_to_utf8 and
|
// The next couple of functions are our wrapper around convert_to_utf8 and
|
||||||
// convert_from_utf8 so that they can also convert from UTF-8 to UTF-8 by
|
// convert_from_utf8 so that they can also convert from UTF-8 to UTF-8 by
|
||||||
// specifying the B_MAIL_UTF8_CONVERSION constant as the conversion operation. It
|
// specifying the B_MAIL_UTF8_CONVERSION constant as the conversion operation.
|
||||||
// also lets us add new conversions, like B_MAIL_US_ASCII_CONVERSION.
|
// It also lets us add new conversions, like B_MAIL_US_ASCII_CONVERSION.
|
||||||
|
|
||||||
_EXPORT status_t mail_convert_to_utf8 (
|
|
||||||
uint32 srcEncoding,
|
status_t
|
||||||
const char *src,
|
mail_convert_to_utf8(uint32 srcEncoding, const char *src, int32 *srcLen,
|
||||||
int32 *srcLen,
|
char *dst, int32 *dstLen, int32 *state, char substitute)
|
||||||
char *dst,
|
|
||||||
int32 *dstLen,
|
|
||||||
int32 *state,
|
|
||||||
char substitute)
|
|
||||||
{
|
{
|
||||||
int32 copyAmount;
|
int32 copyAmount;
|
||||||
char *originalDst = dst;
|
char *originalDst = dst;
|
||||||
@@ -203,14 +263,9 @@ _EXPORT status_t mail_convert_to_utf8 (
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
_EXPORT status_t mail_convert_from_utf8 (
|
status_t
|
||||||
uint32 dstEncoding,
|
mail_convert_from_utf8(uint32 dstEncoding, const char *src, int32 *srcLen,
|
||||||
const char *src,
|
char *dst, int32 *dstLen, int32 *state, char substitute)
|
||||||
int32 *srcLen,
|
|
||||||
char *dst,
|
|
||||||
int32 *dstLen,
|
|
||||||
int32 *state,
|
|
||||||
char substitute)
|
|
||||||
{
|
{
|
||||||
int32 copyAmount;
|
int32 copyAmount;
|
||||||
status_t errorCode;
|
status_t errorCode;
|
||||||
@@ -218,8 +273,7 @@ _EXPORT status_t mail_convert_from_utf8 (
|
|||||||
int32 tempDstLen;
|
int32 tempDstLen;
|
||||||
int32 tempSrcLen;
|
int32 tempSrcLen;
|
||||||
|
|
||||||
if (dstEncoding == B_MAIL_UTF8_CONVERSION)
|
if (dstEncoding == B_MAIL_UTF8_CONVERSION) {
|
||||||
{
|
|
||||||
copyAmount = *srcLen;
|
copyAmount = *srcLen;
|
||||||
if (*dstLen < copyAmount)
|
if (*dstLen < copyAmount)
|
||||||
copyAmount = *dstLen;
|
copyAmount = *dstLen;
|
||||||
@@ -229,8 +283,7 @@ _EXPORT status_t mail_convert_from_utf8 (
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dstEncoding == B_MAIL_US_ASCII_CONVERSION)
|
if (dstEncoding == B_MAIL_US_ASCII_CONVERSION) {
|
||||||
{
|
|
||||||
int32 characterLength;
|
int32 characterLength;
|
||||||
int32 dstRemaining = *dstLen;
|
int32 dstRemaining = *dstLen;
|
||||||
unsigned char letter;
|
unsigned char letter;
|
||||||
@@ -288,7 +341,8 @@ _EXPORT status_t mail_convert_from_utf8 (
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
errorCode = convert_from_utf8 (dstEncoding, src, srcLen, dst, dstLen, state, substitute);
|
errorCode = convert_from_utf8(dstEncoding, src, srcLen, dst, dstLen, state,
|
||||||
|
substitute);
|
||||||
if (errorCode != B_OK)
|
if (errorCode != B_OK)
|
||||||
return errorCode;
|
return errorCode;
|
||||||
|
|
||||||
@@ -308,7 +362,7 @@ _EXPORT status_t mail_convert_from_utf8 (
|
|||||||
if (tempDstLen < 3) // Not enough space remaining in the output.
|
if (tempDstLen < 3) // Not enough space remaining in the output.
|
||||||
return B_OK; // Sort of an error, but we did convert the rest OK.
|
return B_OK; // Sort of an error, but we did convert the rest OK.
|
||||||
tempSrcLen = 1;
|
tempSrcLen = 1;
|
||||||
errorCode = convert_from_utf8 (dstEncoding, "a", &tempSrcLen,
|
errorCode = convert_from_utf8(dstEncoding, "a", &tempSrcLen,
|
||||||
dst + *dstLen, &tempDstLen, state, substitute);
|
dst + *dstLen, &tempDstLen, state, substitute);
|
||||||
if (errorCode != B_OK)
|
if (errorCode != B_OK)
|
||||||
return errorCode;
|
return errorCode;
|
||||||
@@ -317,64 +371,8 @@ _EXPORT status_t mail_convert_from_utf8 (
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ssize_t
|
||||||
static int handle_non_rfc2047_encoding(char **buffer,size_t *bufferLength,size_t *sourceLength)
|
rfc2047_to_utf8(char **bufp, size_t *bufLen, size_t strLen)
|
||||||
{
|
|
||||||
char *string = *buffer;
|
|
||||||
int32 length = *sourceLength;
|
|
||||||
int32 i;
|
|
||||||
|
|
||||||
// check for 8-bit characters
|
|
||||||
for (i = 0;i < length;i++)
|
|
||||||
if (string[i] & 0x80)
|
|
||||||
break;
|
|
||||||
if (i == length)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// check for groups of 8-bit characters - this code is not very smart;
|
|
||||||
// it just can detect some sort of single-byte encoded stuff, the rest
|
|
||||||
// is regarded as UTF-8
|
|
||||||
|
|
||||||
int32 singletons = 0,doubles = 0;
|
|
||||||
|
|
||||||
for (i = 0;i < length;i++)
|
|
||||||
{
|
|
||||||
if (string[i] & 0x80)
|
|
||||||
{
|
|
||||||
if ((string[i + 1] & 0x80) == 0)
|
|
||||||
singletons++;
|
|
||||||
else doubles++;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (singletons != 0) // can't be valid UTF-8 anymore, so we assume ISO-Latin-1
|
|
||||||
{
|
|
||||||
int32 state = 0;
|
|
||||||
// just to be sure
|
|
||||||
int32 destLength = length * 4 + 1;
|
|
||||||
int32 destBufferLength = destLength;
|
|
||||||
char *dest = (char*)malloc(destLength);
|
|
||||||
if (dest == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (convert_to_utf8(B_ISO1_CONVERSION, string, &length,dest,
|
|
||||||
&destLength, &state) == B_OK) {
|
|
||||||
*buffer = dest;
|
|
||||||
*bufferLength = destBufferLength;
|
|
||||||
*sourceLength = destLength;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
free(dest);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// we assume a valid UTF-8 string here, but yes, we don't check it
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
_EXPORT ssize_t rfc2047_to_utf8(char **bufp, size_t *bufLen, size_t strLen)
|
|
||||||
{
|
{
|
||||||
char *head, *tail;
|
char *head, *tail;
|
||||||
char *charset, *encoding, *end;
|
char *charset, *encoding, *end;
|
||||||
@@ -437,22 +435,22 @@ _EXPORT ssize_t rfc2047_to_utf8(char **bufp, size_t *bufLen, size_t strLen)
|
|||||||
size_t cLen = encoding - 1 - charset;
|
size_t cLen = encoding - 1 - charset;
|
||||||
bool base64encoded = toupper(*encoding) == 'B';
|
bool base64encoded = toupper(*encoding) == 'B';
|
||||||
|
|
||||||
uint32 convert_id = B_MAIL_NULL_CONVERSION;
|
uint32 convertID = B_MAIL_NULL_CONVERSION;
|
||||||
char charset_string[cLen+1];
|
char charsetName[cLen + 1];
|
||||||
memcpy(charset_string, charset, cLen);
|
memcpy(charsetName, charset, cLen);
|
||||||
charset_string[cLen] = '\0';
|
charsetName[cLen] = '\0';
|
||||||
if (strcasecmp(charset_string, "us-ascii") == 0) {
|
if (strcasecmp(charsetName, "us-ascii") == 0) {
|
||||||
convert_id = B_MAIL_US_ASCII_CONVERSION;
|
convertID = B_MAIL_US_ASCII_CONVERSION;
|
||||||
} else if (strcasecmp(charset_string, "utf-8") == 0) {
|
} else if (strcasecmp(charsetName, "utf-8") == 0) {
|
||||||
convert_id = B_MAIL_UTF8_CONVERSION;
|
convertID = B_MAIL_UTF8_CONVERSION;
|
||||||
} else {
|
} else {
|
||||||
const BCharacterSet * cs = BCharacterSetRoster::FindCharacterSetByName(charset_string);
|
const BCharacterSet* charSet
|
||||||
if (cs != NULL) {
|
= BCharacterSetRoster::FindCharacterSetByName(charsetName);
|
||||||
convert_id = cs->GetConversionID();
|
if (charSet != NULL) {
|
||||||
|
convertID = charSet->GetConversionID();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (convert_id == B_MAIL_NULL_CONVERSION)
|
if (convertID == B_MAIL_NULL_CONVERSION) {
|
||||||
{
|
|
||||||
// unidentified charset
|
// unidentified charset
|
||||||
// what to do? doing nothing skips the encoded text;
|
// what to do? doing nothing skips the encoded text;
|
||||||
// but we should keep it: we copy it to the output.
|
// but we should keep it: we copy it to the output.
|
||||||
@@ -480,9 +478,9 @@ _EXPORT ssize_t rfc2047_to_utf8(char **bufp, size_t *bufLen, size_t strLen)
|
|||||||
//
|
//
|
||||||
// do the conversion
|
// do the conversion
|
||||||
//
|
//
|
||||||
ret = mail_convert_to_utf8(convert_id, src, &cvLen, dst, &dstLen, &convState);
|
ret = mail_convert_to_utf8(convertID, src, &cvLen, dst, &dstLen,
|
||||||
if (ret != B_OK)
|
&convState);
|
||||||
{
|
if (ret != B_OK) {
|
||||||
// what to do? doing nothing skips the encoded text
|
// what to do? doing nothing skips the encoded text
|
||||||
// but we should keep it: we copy it to the output.
|
// but we should keep it: we copy it to the output.
|
||||||
|
|
||||||
@@ -524,10 +522,8 @@ _EXPORT ssize_t rfc2047_to_utf8(char **bufp, size_t *bufLen, size_t strLen)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
else
|
else {
|
||||||
{
|
if (dstLen > end-string) {
|
||||||
if (dstLen > end-string)
|
|
||||||
{
|
|
||||||
// copy the string forward...
|
// copy the string forward...
|
||||||
memmove(string+dstLen, end, strLen - (end-head) + 1);
|
memmove(string+dstLen, end, strLen - (end-head) + 1);
|
||||||
strLen += string+dstLen - end;
|
strLen += string+dstLen - end;
|
||||||
@@ -553,7 +549,9 @@ _EXPORT ssize_t rfc2047_to_utf8(char **bufp, size_t *bufLen, size_t strLen)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
_EXPORT ssize_t utf8_to_rfc2047 (char **bufp, ssize_t length, uint32 charset, char encoding) {
|
ssize_t
|
||||||
|
utf8_to_rfc2047 (char **bufp, ssize_t length, uint32 charset, char encoding)
|
||||||
|
{
|
||||||
struct word {
|
struct word {
|
||||||
BString originalWord;
|
BString originalWord;
|
||||||
BString convertedWord;
|
BString convertedWord;
|
||||||
@@ -748,9 +746,8 @@ _EXPORT ssize_t utf8_to_rfc2047 (char **bufp, ssize_t length, uint32 charset, ch
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//====================================================================
|
void
|
||||||
|
FoldLineAtWhiteSpaceAndAddCRLF(BString &string)
|
||||||
void FoldLineAtWhiteSpaceAndAddCRLF (BString &string)
|
|
||||||
{
|
{
|
||||||
int inputLength = string.Length();
|
int inputLength = string.Length();
|
||||||
int lineStartIndex;
|
int lineStartIndex;
|
||||||
@@ -827,21 +824,18 @@ void FoldLineAtWhiteSpaceAndAddCRLF (BString &string)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//====================================================================
|
ssize_t
|
||||||
|
readfoldedline(FILE *file, char **buffer, size_t *buflen)
|
||||||
_EXPORT ssize_t readfoldedline(FILE *file, char **buffer, size_t *buflen)
|
|
||||||
{
|
{
|
||||||
ssize_t len = buflen && *buflen ? *buflen : 0;
|
ssize_t len = buflen && *buflen ? *buflen : 0;
|
||||||
char * buf = buffer && *buffer ? *buffer : NULL;
|
char * buf = buffer && *buffer ? *buffer : NULL;
|
||||||
ssize_t cnt = 0; // Number of characters currently in the buffer.
|
ssize_t cnt = 0; // Number of characters currently in the buffer.
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
while (true)
|
while (true) {
|
||||||
{
|
|
||||||
// Make sure there is space in the buffer for two more characters (one
|
// Make sure there is space in the buffer for two more characters (one
|
||||||
// for the next character, and one for the end of string NUL byte).
|
// for the next character, and one for the end of string NUL byte).
|
||||||
if (buf == NULL || cnt + 2 >= len)
|
if (buf == NULL || cnt + 2 >= len) {
|
||||||
{
|
|
||||||
char *temp = (char *)realloc(buf, len + 64);
|
char *temp = (char *)realloc(buf, len + 64);
|
||||||
if (temp == NULL) {
|
if (temp == NULL) {
|
||||||
// Out of memory, however existing buffer remains allocated.
|
// Out of memory, however existing buffer remains allocated.
|
||||||
@@ -898,7 +892,6 @@ _EXPORT ssize_t readfoldedline(FILE *file, char **buffer, size_t *buflen)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (buf != NULL && cnt >= 0)
|
if (buf != NULL && cnt >= 0)
|
||||||
buf[cnt] = '\0';
|
buf[cnt] = '\0';
|
||||||
|
|
||||||
@@ -914,9 +907,8 @@ _EXPORT ssize_t readfoldedline(FILE *file, char **buffer, size_t *buflen)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//====================================================================
|
ssize_t
|
||||||
|
readfoldedline(BPositionIO &in, char **buffer, size_t *buflen)
|
||||||
_EXPORT ssize_t readfoldedline(BPositionIO &in, char **buffer, size_t *buflen)
|
|
||||||
{
|
{
|
||||||
ssize_t len = buflen && *buflen ? *buflen : 0;
|
ssize_t len = buflen && *buflen ? *buflen : 0;
|
||||||
char * buf = buffer && *buffer ? *buffer : NULL;
|
char * buf = buffer && *buffer ? *buffer : NULL;
|
||||||
@@ -924,12 +916,10 @@ _EXPORT ssize_t readfoldedline(BPositionIO &in, char **buffer, size_t *buflen)
|
|||||||
char c;
|
char c;
|
||||||
status_t errorCode;
|
status_t errorCode;
|
||||||
|
|
||||||
while (true)
|
while (true) {
|
||||||
{
|
|
||||||
// Make sure there is space in the buffer for two more characters (one
|
// Make sure there is space in the buffer for two more characters (one
|
||||||
// for the next character, and one for the end of string NUL byte).
|
// for the next character, and one for the end of string NUL byte).
|
||||||
if (buf == NULL || cnt + 2 >= len)
|
if (buf == NULL || cnt + 2 >= len) {
|
||||||
{
|
|
||||||
char *temp = (char *)realloc(buf, len + 64);
|
char *temp = (char *)realloc(buf, len + 64);
|
||||||
if (temp == NULL) {
|
if (temp == NULL) {
|
||||||
// Out of memory, however existing buffer remains allocated.
|
// Out of memory, however existing buffer remains allocated.
|
||||||
@@ -1005,7 +995,7 @@ _EXPORT ssize_t readfoldedline(BPositionIO &in, char **buffer, size_t *buflen)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
_EXPORT ssize_t
|
ssize_t
|
||||||
nextfoldedline(const char** header, char **buffer, size_t *buflen)
|
nextfoldedline(const char** header, char **buffer, size_t *buflen)
|
||||||
{
|
{
|
||||||
ssize_t len = buflen && *buflen ? *buflen : 0;
|
ssize_t len = buflen && *buflen ? *buflen : 0;
|
||||||
@@ -1085,7 +1075,7 @@ nextfoldedline(const char** header, char **buffer, size_t *buflen)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
_EXPORT void
|
void
|
||||||
trim_white_space(BString &string)
|
trim_white_space(BString &string)
|
||||||
{
|
{
|
||||||
int32 i;
|
int32 i;
|
||||||
@@ -1105,12 +1095,11 @@ trim_white_space(BString &string)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Tries to return a human-readable name from the specified
|
/*! Tries to return a human-readable name from the specified
|
||||||
* header parameter (should be from "To:" or "From:").
|
header parameter (should be from "To:" or "From:").
|
||||||
* Tries to return the name rather than the eMail address.
|
Tries to return the name rather than the eMail address.
|
||||||
*/
|
*/
|
||||||
|
void
|
||||||
_EXPORT void
|
|
||||||
extract_address_name(BString &header)
|
extract_address_name(BString &header)
|
||||||
{
|
{
|
||||||
BString name;
|
BString name;
|
||||||
@@ -1198,19 +1187,13 @@ extract_address_name(BString &header)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! Given a subject in a BString, remove the extraneous RE: re: and other stuff
|
||||||
// Given a subject in a BString, remove the extraneous RE: re: and other stuff
|
to get down to the core subject string, which should be identical for all
|
||||||
// to get down to the core subject string, which should be identical for all
|
messages posted about a topic. The input string is modified in place to
|
||||||
// messages posted about a topic. The input string is modified in place to
|
become the output core subject string.
|
||||||
// become the output core subject string.
|
*/
|
||||||
|
void
|
||||||
static int32 gLocker = 0;
|
SubjectToThread (BString &string)
|
||||||
static size_t gNsub = 1;
|
|
||||||
static re_pattern_buffer gRe;
|
|
||||||
static re_pattern_buffer *gRebuf = NULL;
|
|
||||||
static unsigned char gTranslation[256];
|
|
||||||
|
|
||||||
_EXPORT void SubjectToThread (BString &string)
|
|
||||||
{
|
{
|
||||||
// a regex that matches a non-ASCII UTF8 character:
|
// a regex that matches a non-ASCII UTF8 character:
|
||||||
#define U8C \
|
#define U8C \
|
||||||
@@ -1230,8 +1213,7 @@ _EXPORT void SubjectToThread (BString &string)
|
|||||||
"|^( +| *(\\<(\\w|" U8C "){2,3} *(\\[[^\\]]*\\])? *:)+ *)" \
|
"|^( +| *(\\<(\\w|" U8C "){2,3} *(\\[[^\\]]*\\])? *:)+ *)" \
|
||||||
"| *\\(fwd\\) *$"
|
"| *\\(fwd\\) *$"
|
||||||
|
|
||||||
if (gRebuf == NULL && atomic_add(&gLocker,1) == 0)
|
if (gRebuf == NULL && atomic_add(&gLocker, 1) == 0) {
|
||||||
{
|
|
||||||
// the idea is to compile the regexp once to speed up testing
|
// the idea is to compile the regexp once to speed up testing
|
||||||
|
|
||||||
for (int i=0; i<256; ++i) gTranslation[i]=i;
|
for (int i=0; i<256; ++i) gTranslation[i]=i;
|
||||||
@@ -1256,16 +1238,13 @@ _EXPORT void SubjectToThread (BString &string)
|
|||||||
gRebuf = &gRe;
|
gRebuf = &gRe;
|
||||||
else
|
else
|
||||||
fprintf(stderr, "Failed to compile the regex: %s\n", err);
|
fprintf(stderr, "Failed to compile the regex: %s\n", err);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
int32 tries = 200;
|
int32 tries = 200;
|
||||||
while (gRebuf == NULL && tries-- > 0)
|
while (gRebuf == NULL && tries-- > 0)
|
||||||
snooze(10000);
|
snooze(10000);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gRebuf)
|
if (gRebuf) {
|
||||||
{
|
|
||||||
struct re_registers regs;
|
struct re_registers regs;
|
||||||
// can't be static if this function is to be thread-safe
|
// can't be static if this function is to be thread-safe
|
||||||
|
|
||||||
@@ -1273,11 +1252,8 @@ _EXPORT void SubjectToThread (BString &string)
|
|||||||
regs.start = (regoff_t*)malloc(gNsub*sizeof(regoff_t));
|
regs.start = (regoff_t*)malloc(gNsub*sizeof(regoff_t));
|
||||||
regs.end = (regoff_t*)malloc(gNsub*sizeof(regoff_t));
|
regs.end = (regoff_t*)malloc(gNsub*sizeof(regoff_t));
|
||||||
|
|
||||||
for (int start=0;
|
for (int start = 0; (start = re_search(gRebuf, string.String(),
|
||||||
(start=re_search(gRebuf, string.String(), string.Length(),
|
string.Length(), 0, string.Length(), ®s)) >= 0;) {
|
||||||
0, string.Length(), ®s)) >= 0;
|
|
||||||
)
|
|
||||||
{
|
|
||||||
//
|
//
|
||||||
// we found something
|
// we found something
|
||||||
//
|
//
|
||||||
@@ -1287,7 +1263,8 @@ _EXPORT void SubjectToThread (BString &string)
|
|||||||
start = regs.start[2];
|
start = regs.start[2];
|
||||||
|
|
||||||
string.Remove(start,regs.end[0]-start);
|
string.Remove(start,regs.end[0]-start);
|
||||||
if (start) string.Insert(' ',1,start);
|
if (start)
|
||||||
|
string.Insert(' ',1,start);
|
||||||
|
|
||||||
// TODO: for some subjects this results in an endless loop, check
|
// TODO: for some subjects this results in an endless loop, check
|
||||||
// why this happen.
|
// why this happen.
|
||||||
@@ -1306,16 +1283,16 @@ _EXPORT void SubjectToThread (BString &string)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! Converts a date to a time. Handles numeric time zones too, unlike
|
||||||
// Converts a date to a time. Handles numeric time zones too, unlike
|
parsedate(). Returns -1 if it fails.
|
||||||
// parsedate. Returns -1 if it fails.
|
*/
|
||||||
|
time_t
|
||||||
_EXPORT time_t ParseDateWithTimeZone (const char *DateString)
|
ParseDateWithTimeZone(const char *DateString)
|
||||||
{
|
{
|
||||||
time_t currentTime;
|
time_t currentTime;
|
||||||
time_t dateAsTime;
|
time_t dateAsTime;
|
||||||
char tempDateString [80];
|
char tempDateString[80];
|
||||||
char tempZoneString [6];
|
char tempZoneString[6];
|
||||||
time_t zoneDeltaTime;
|
time_t zoneDeltaTime;
|
||||||
int zoneIndex;
|
int zoneIndex;
|
||||||
char *zonePntr;
|
char *zonePntr;
|
||||||
@@ -1390,10 +1367,9 @@ _EXPORT time_t ParseDateWithTimeZone (const char *DateString)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Parses a mail header and fills the headers BMessage
|
/*! Parses a mail header and fills the headers BMessage
|
||||||
*/
|
*/
|
||||||
|
status_t
|
||||||
_EXPORT status_t
|
|
||||||
parse_header(BMessage &headers, BPositionIO &input)
|
parse_header(BMessage &headers, BPositionIO &input)
|
||||||
{
|
{
|
||||||
char *buffer = NULL;
|
char *buffer = NULL;
|
||||||
@@ -1417,10 +1393,12 @@ parse_header(BMessage &headers, BPositionIO &input)
|
|||||||
// unified case for later fetch
|
// unified case for later fetch
|
||||||
|
|
||||||
delimiter++; // Skip the colon.
|
delimiter++; // Skip the colon.
|
||||||
while (isspace (*delimiter))
|
// Skip over leading white space and tabs.
|
||||||
delimiter++; // Skip over leading white space and tabs. To do: (comments in brackets).
|
// TODO: (comments in brackets).
|
||||||
|
while (isspace(*delimiter))
|
||||||
|
delimiter++;
|
||||||
|
|
||||||
// ToDo: implement joining of multiple header tags (i.e. multiple "Cc:"s)
|
// TODO: implement joining of multiple header tags (i.e. multiple "Cc:"s)
|
||||||
headers.AddString(header.String(), delimiter);
|
headers.AddString(header.String(), delimiter);
|
||||||
}
|
}
|
||||||
free(buffer);
|
free(buffer);
|
||||||
@@ -1429,7 +1407,7 @@ parse_header(BMessage &headers, BPositionIO &input)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
_EXPORT status_t
|
status_t
|
||||||
extract_from_header(const BString& header, const BString& field,
|
extract_from_header(const BString& header, const BString& field,
|
||||||
BString& target)
|
BString& target)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user