diff options
Diffstat (limited to 'mimelib/msgid.cpp')
-rw-r--r-- | mimelib/msgid.cpp | 399 |
1 files changed, 399 insertions, 0 deletions
diff --git a/mimelib/msgid.cpp b/mimelib/msgid.cpp new file mode 100644 index 000000000..29a8d9550 --- /dev/null +++ b/mimelib/msgid.cpp @@ -0,0 +1,399 @@ +//============================================================================= +// 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[] = "0123456789ABCDEFGHIJKLMNPQRSTUVWXYZ"; + +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) |