| Return Type | Function name | Arguments |
|---|---|---|
| hzEcode | hzEmail::Import | (const hzChain&,bool,) |
Declared in file: hzMailer.h
Defined in file : hzMailer.cpp
Function Logic:
Function body:
hzEcode hzEmail::Import (const hzChain& emRaw, bool bHead)
{
_hzfunc("hzEmail::Import") ;
hzChain Part ;
chIter zi ;
chIter xi ;
chIter endHdr ;
chIter bodyStart ;
hzEmpart epart ;
hzEmaddr emtmp ;
hzString filepath ;
hzString mark ;
hzString markStart ;
hzString markEnd ;
hzString strval ;
hzString episId ;
uint32_t nP ;
uint32_t nLen ;
hzEcode rc = E_OK ;
Clear() ;
m_Err.Clear() ;
zi = emRaw ;
for (; !zi.eof() ;)
{
if (*zi == CHAR_CR)
{
if (zi == "\r\n\r\n")
{ zi += 4; break ; }
if (zi == "\r\n")
zi += 2;
}
_find_hdr_end(endHdr, zi) ;
switch (*zi)
{
case CHAR_LC_B:
case CHAR_UC_B: if (zi.Equiv("Bcc: "))
{
zi += 5;
if (!_reademaddr(strval, emtmp, zi))
rc = E_SYNTAX ;
m_BCC.Add(emtmp) ;
threadLog("Bcc: Added %s\n", *emtmp) ;
}
break ;
case CHAR_LC_C:
case CHAR_UC_C: if (zi.Equiv("Cc: "))
{
zi += 4;
if (!_reademaddr(strval, emtmp, zi))
rc = E_SYNTAX ;
m_CC.Add(emtmp) ;
threadLog("Cc: Added %s\n", *emtmp) ;
break ;
}
if (zi.Equiv("Content-Type: "))
{
zi += 14;
if (zi.Equiv("text/plain;")) { zi += 11;m_ContType = HZ_CONTENT_TYPE_TEXT_PLAIN ; }
else if (zi.Equiv("text/html;")) { zi += 10;m_ContType = HZ_CONTENT_TYPE_TEXT_HTML ; }
else if (zi.Equiv("multipart/alternative;")) { zi += 22;m_ContType = HZ_CONTENT_TYPE_MULTI_ALTERNATIVE ; }
else if (zi.Equiv("multipart/mixed;")) { zi += 16;m_ContType = HZ_CONTENT_TYPE_MULTI_MIXED ; }
else if (zi.Equiv("multipart/related;")) { zi += 18;m_ContType = HZ_CONTENT_TYPE_MULTI_RELATED ; }
else
{
rc = E_SYNTAX ;
threadLog("Unknown Content-Type\n") ;
}
if (m_ContType == HZ_CONTENT_TYPE_MULTI_MIXED || m_ContType == HZ_CONTENT_TYPE_MULTI_ALTERNATIVE || m_ContType == HZ_CONTENT_TYPE_MULTI_RELATED)
{
if (mark)
{
rc = E_FORMAT ;
threadLog("MULTIPART MIX/ALT/REL: Boundary already specified\n") ;
}
else
{
for (; *zi ; zi++)
{
if (*zi == CHAR_LC_B)
{
if (zi == "boundary=")
{
zi += 9;
_readStrval(mark, zi) ;
break ;
}
}
}
if (!mark)
{ rc = E_SYNTAX ; threadLog("MULTIPART MIX/ALT/REL: Expected a boundary to be specified\n") ; }
}
}
break ;
}
if (zi == "Content-Transfer-Encoding: ")
{
zi += 27;
if (zi == "7bit") m_Encoding = HZ_CONTENT_ENCODE_7BIT ;
else if (zi == "8bit") m_Encoding = HZ_CONTENT_ENCODE_8BIT ;
else if (zi == "binary") m_Encoding = HZ_CONTENT_ENCODE_8BIT ;
else if (zi == "base64") m_Encoding = HZ_CONTENT_ENCODE_BASE64 ;
else if (zi == "quoted-printable") m_Encoding = HZ_CONTENT_ENCODE_QUOTE_PRINT ;
else
{ rc = E_SYNTAX ; threadLog("Unknown Content-Transfer-Encoding value\n") ; }
}
break ;
case CHAR_LC_D:
case CHAR_UC_D: if (zi.Equiv("Date: "))
{
zi += 6;
nLen = IsFormalDate(m_Date, zi) ;
if (!nLen)
threadLog("Date arg must amount to legal date\n") ;
}
break ;
case CHAR_UC_F: if (zi == "From: ")
{
zi += 6;
if (!_reademaddr(m_RealFrom, m_AddrFrom, zi))
{ rc = E_SYNTAX ; m_Err << "From: arg must amount to an email address\n" ; }
}
break ;
case CHAR_UC_M: if (zi == "Message-ID: ")
{
zi += 12;
_readangle(m_Id, zi) ;
}
break ;
case CHAR_LC_R:
case CHAR_UC_R: if (zi.Equiv("Return-Path:"))
{
zi += 12;
if (!_reademaddr(strval, m_AddrReturn, zi))
{ rc = E_SYNTAX ; threadLog("Return-Path must amount to an email address\n") ; }
break ;
}
if (zi.Equiv("Reply-To:"))
{
zi += 9;
if (!_reademaddr(m_RealReply, m_AddrReply, zi))
{ rc = E_SYNTAX ; threadLog("Reply-To: arg must amount to an email address\n") ; }
}
break ;
case CHAR_LC_S:
case CHAR_UC_S: if (zi.Equiv("Subject: "))
{
zi += 9;
_readStrval(strval, zi) ;
m_Subject = strval ;
CharsetStringDecode(m_Subject, strval) ;
}
break ;
case CHAR_LC_T:
case CHAR_UC_T: if (zi.Equiv("To: "))
{
zi += 4;
if (!_reademaddr(m_RealTo, emtmp, zi))
{ rc = E_SYNTAX ; threadLog("To: arg must amount to an email address\n") ; }
if (!m_AddrTo)
m_AddrTo = emtmp ;
m_Recipients.Add(emtmp) ;
}
break ;
case CHAR_LC_X:
case CHAR_UC_X: if (zi.Equiv("X-Epistula-ServerID: "))
{
zi += 21;
_readangle(episId, zi) ;
break ;
}
if (zi.Equiv("X-Epistula-Ingress: "))
{
zi += 20;
if (!_reademaddr(strval, m_AddrRelay, zi))
{ rc = E_SYNTAX ; threadLog("X-Epistula-Ingress: arg must amount to an email address\n") ; }
}
break ;
}
zi = endHdr ;
}
if (rc != E_OK)
{
threadLog("IMPORT FAILED\n") ;
threadLog(m_Err) ;
threadLog("--end--\n") ;
return rc ;
}
if (!m_Date)
{ rc = E_BADVALUE ; threadLog("WARNING: No date header\n") ; }
if (!m_AddrFrom)
{ rc = E_BADVALUE ; threadLog("No From address\n") ; }
if (!m_AddrTo)
{ rc = E_BADVALUE ; threadLog("No recipients\n") ; }
if (!m_Id)
m_Id = episId ;
if (!m_Id)
{ rc = E_BADVALUE ; threadLog("No mail id\n") ; }
if (rc != E_OK)
{
threadLog("IMPORT FAILED\n") ;
return rc ;
}
if (bHead)
return rc ;
/*
** ** Process the body. This may or may not come in blocks marked out by the boundary.
** */
if (!mark)
{
Part.Clear() ;
for (; !zi.eof() ; zi++)
{
if (*zi == CHAR_CR)
{
if (zi == "\r\n.\r\n")
break ;
}
Part.AddByte(*zi) ;
}
if (m_ContType == HZ_CONTENT_TYPE_TEXT_HTML)
_part_decode(m_Html, Part, m_Encoding) ;
else
_part_decode(m_Text, Part, m_Encoding) ;
threadLog("Processed a non-part message\n") ;
return rc ;
}
markStart = "--" + mark ;
markEnd = markStart + "--" ;
threadLog("Operating with BOUNDARY=%s\n", *mark) ;
if (zi != markStart)
{
threadLog("Unexpected data\n") ;
zi.Skipwhite() ;
}
for (nP = 0; rc == E_OK && zi == markStart ; nP++)
{
if (zi == markEnd)
break ;
threadLog("Processing part %u\n", nP) ;
rc = _part_process(zi, mark, 1);
}
return rc ;
}