summaryrefslogtreecommitdiffstats
path: root/mimelib/msgid.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mimelib/msgid.cpp')
-rw-r--r--mimelib/msgid.cpp399
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)