You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdepim/mimelib/msgid.cpp

400 lines
9.3 KiB

//=============================================================================
// File: msgid.cpp
// Contents: Definitions for DwMsgId
// 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 CONSEQUENTIAL 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.
//
//=============================================================================
#define DW_IMPLEMENTATION
#include <mimelib/config.h>
#include <mimelib/debug.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
// UNIX specific includes
//#if defined(__unix__) || defined(__unix)
#if defined(DW_UNIX)
# include <unistd.h>
# if defined(__SUNPRO_CC)
# include <sysent.h>
# endif // defined(__SUNPRO_CC)
#endif // defined (DW_UNIX)
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
// WIN32 specific includes
#if defined(DW_WIN32)
# include <windows.h>
#endif // defined(DW_WIN32)
#include <mimelib/string.h>
#include <mimelib/msgid.h>
#include <mimelib/token.h>
static void GetHostName(char* buf, int bufLen);
static DwUint32 GetPid();
const char* const DwMsgId::sClassName = "DwMsgId";
const char* DwMsgId::sHostName = 0;
DwMsgId* (*DwMsgId::sNewMsgId)(const DwString&, DwMessageComponent*) = 0;
DwMsgId* DwMsgId::NewMsgId(const DwString& aStr, DwMessageComponent* aParent)
{
if (sNewMsgId) {
return sNewMsgId(aStr, aParent);
}
else {
return new DwMsgId(aStr, aParent);
}
}
DwMsgId::DwMsgId()
{
mClassId = kCidMsgId;
mClassName = sClassName;
}
DwMsgId::DwMsgId(const DwMsgId& aMsgId)
: DwFieldBody(aMsgId),
mLocalPart(aMsgId.mLocalPart),
mDomain(aMsgId.mDomain)
{
mClassId = kCidMsgId;
mClassName = sClassName;
}
DwMsgId::DwMsgId(const DwString& aStr, DwMessageComponent* aParent)
: DwFieldBody(aStr, aParent)
{
mClassId = kCidMsgId;
mClassName = sClassName;
}
DwMsgId::~DwMsgId()
{
}
const DwMsgId& DwMsgId::operator = (const DwMsgId& aMsgId)
{
if (this == &aMsgId) return *this;
DwFieldBody::operator = (aMsgId);
mLocalPart = aMsgId.mLocalPart;
mDomain = aMsgId.mDomain;
return *this;
}
const DwString& DwMsgId::LocalPart() const
{
return mLocalPart;
}
void DwMsgId::SetLocalPart(const DwString& aLocalPart)
{
mLocalPart = aLocalPart;
SetModified();
}
const DwString& DwMsgId::Domain() const
{
return mDomain;
}
void DwMsgId::SetDomain(const DwString& aDomain)
{
mDomain = aDomain;
SetModified();
}
void DwMsgId::Parse()
{
mIsModified = 0;
int ch;
DwRfc822Tokenizer tokenizer(mString);
// Advance to '<'
int type = tokenizer.Type();
int found = 0;
while (!found && type != eTkNull) {
if (type == eTkSpecial && tokenizer.Token()[0] == '<') {
found = 1;
}
++tokenizer;
type = tokenizer.Type();
}
// Get the local part
found = 0;
while (type != eTkNull && !found) {
switch (type) {
case eTkSpecial:
ch = tokenizer.Token()[0];
switch (ch) {
case '@':
found = 1;
break;
case '.':
mLocalPart += tokenizer.Token();
break;
}
break;
case eTkAtom:
case eTkQuotedString:
mLocalPart += tokenizer.Token();
break;
}
++tokenizer;
type = tokenizer.Type();
}
// Get the domain
found = 0;
while (type != eTkNull && !found) {
switch (type) {
case eTkSpecial:
ch = tokenizer.Token()[0];
switch (ch) {
case '>':
found = 1;
break;
case '.':
mDomain += tokenizer.Token();
break;
}
break;
case eTkAtom:
mDomain += tokenizer.Token();
break;
case eTkDomainLiteral:
mDomain += tokenizer.Token();
break;
}
++tokenizer;
type = tokenizer.Type();
}
}
void DwMsgId::Assemble()
{
if (!mIsModified) return;
mString = "<";
mString += mLocalPart;
mString += "@";
mString += mDomain;
mString += ">";
mIsModified = 0;
}
DwMessageComponent* DwMsgId::Clone() const
{
return new DwMsgId(*this);
}
static char base35chars[] = "0123456789ABCDEFGHIJKLMNPTQRSTUVWXYZ";
void DwMsgId::CreateDefault()
{
char hostname[80];
hostname[0] = 0;
GetHostName(hostname, 80);
hostname[79] = 0;
char scratch[80];
time_t tt = time(NULL);
struct tm tms = *localtime(&tt);
int pos = 0;
scratch[pos++] = '<';
int n = tms.tm_year;
scratch[pos++] = char(n / 10 % 10 + '0');
scratch[pos++] = char(n % 10 + '0');
n = tms.tm_mon + 1;
scratch[pos++] = char(n / 10 % 10 + '0');
scratch[pos++] = char(n % 10 + '0');
n = tms.tm_mday;
scratch[pos++] = char(n / 10 % 10 + '0');
scratch[pos++] = char(n % 10 + '0');
n = tms.tm_hour;
scratch[pos++] = char(n / 10 % 10 + '0');
scratch[pos++] = char(n % 10 + '0');
n = tms.tm_min;
scratch[pos++] = char(n / 10 % 10 + '0');
scratch[pos++] = char(n % 10 + '0');
n = tms.tm_sec;
scratch[pos++] = char(n / 10 % 10 + '0');
scratch[pos++] = char(n % 10 + '0');
static int counter = 0;
scratch[pos++] = base35chars[counter/35%35];
scratch[pos++] = base35chars[counter %35];
++counter;
scratch[pos++] = '.';
DwUint32 pid = GetPid();
scratch[pos++] = char(pid / 10000 % 10 + '0');
scratch[pos++] = char(pid / 1000 % 10 + '0');
scratch[pos++] = char(pid / 100 % 10 + '0');
scratch[pos++] = char(pid / 10 % 10 + '0');
scratch[pos++] = char(pid % 10 + '0');
scratch[pos++] = '@';
char* cp = hostname;
while (*cp && pos < 79) {
scratch[pos++] = *cp++;
}
scratch[pos++] = '>';
scratch[pos] = 0;
mString = scratch;
mIsModified = 0;
Parse();
}
#if defined (DW_DEBUG_VERSION)
void DwMsgId::PrintDebugInfo(std::ostream& aStrm, int /*aDepth*/) const
{
aStrm <<
"----------------- Debug info for DwMsgId class -----------------\n";
_PrintDebugInfo(aStrm);
}
#else
void DwMsgId::PrintDebugInfo(std::ostream& , int ) const {}
#endif // defined (DW_DEBUG_VERSION)
#if defined (DW_DEBUG_VERSION)
void DwMsgId::_PrintDebugInfo(std::ostream& aStrm) const
{
DwFieldBody::_PrintDebugInfo(aStrm);
aStrm << "Local part: " << mLocalPart << '\n';
aStrm << "Domain: " << mDomain << '\n';
}
#else
void DwMsgId::_PrintDebugInfo(std::ostream& ) const {}
#endif // defined (DW_DEBUG_VERSION)
void DwMsgId::CheckInvariants() const
{
#if defined (DW_DEBUG_VERSION)
DwFieldBody::CheckInvariants();
mLocalPart.CheckInvariants();
mDomain.CheckInvariants();
#endif // defined (DW_DEBUG_VERSION)
}
//============================================================================
// Platform dependent code follows
//============================================================================
//----------------------------------------------------------------------------
// WIN32
//----------------------------------------------------------------------------
#if defined(DW_WIN32)
#if defined(WINSOCK)
// Winsock version
static void GetHostName(char* buf, int bufLen)
{
WORD wVersionRequested = MAKEWORD(1, 1);
WSADATA wsaData;
int err = WSAStartup(wVersionRequested, &wsaData);
// check winsock version 1.1
if (LOBYTE(wsaData.wVersion) == 1 &&
HIBYTE(wsaData.wVersion) == 1 &&
err == 0) {
buf[0] = '\0';
if (!gethostname(buf, bufLen))
buf[bufLen-1] = '\0';
}
else {
// cannot find winsock
if (DwMsgId::sHostName) {
strcpy(hostname, DwMsgId::sHostName);
}
else {
strcpy(hostname, "noname");
}
}
WSACleanup();
}
#else // !defined(WINSOCK)
// Generic version (no Winsock). Requires that DwMsgId::sHostName be set.
static void GetHostName(char* buf, int bufLen)
{
if (DwMsgId::sHostName) {
strncpy(buf, DwMsgId::sHostName, bufLen);
buf[bufLen-1] = 0;
}
else {
strcpy(buf, "noname");
}
}
#endif // !defined(WINSOCK)
typedef unsigned pid_t;
static DwUint32 GetPid()
{
return GetCurrentProcessId();
}
#endif // defined(DW_WIN32)
//----------------------------------------------------------------------------
// UNIX
//----------------------------------------------------------------------------
#if defined(DW_UNIX)
static void GetHostName(char* buf, int bufLen)
{
buf[0] = '\0';
if (!gethostname(buf, bufLen))
buf[bufLen-1] = '\0';
}
static DwUint32 GetPid()
{
return getpid();
}
#endif // defined(DW_UNIX)