← Back to team overview

zorba-coders team mailing list archive

[Merge] lp:~davidagraf/zorba/email-module-crypt into lp:zorba/email-module

 

David Graf has proposed merging lp:~davidagraf/zorba/email-module-crypt into lp:zorba/email-module.

Requested reviews:
  Chris Hillery (ceejatec)
  Cezar Andrei (cezar-andrei)

For more details, see:
https://code.launchpad.net/~davidagraf/zorba/email-module-crypt/+merge/113366

Fixing crypt dependency problem.
-- 
https://code.launchpad.net/~davidagraf/zorba/email-module-crypt/+merge/113366
Your team Zorba Coders is subscribed to branch lp:zorba/email-module.
=== modified file 'src/com/zorba-xquery/www/modules/email/CMakeLists.txt'
--- src/com/zorba-xquery/www/modules/email/CMakeLists.txt	2011-09-30 14:44:37 +0000
+++ src/com/zorba-xquery/www/modules/email/CMakeLists.txt	2012-07-04 11:04:24 +0000
@@ -46,10 +46,17 @@
     INCLUDE_DIRECTORIES(${CCLIENT_INCLUDE_DIRS})
     IF (NOT WIN32 AND NOT CYGWIN)
       LIST(APPEND SMTP_LINK_LIBRARIES ${PAM_LIBRARIES})
+      # append system library crypt if it exists
+      # if it exists, it's needed by c-client
+      CHECK_LIBRARY_EXISTS(crypt crypt "" CRYPT_LIB_EXISTS)
+      IF (CRYPT_LIB_EXISTS)
+        LIST(APPEND SMTP_LINK_LIBRARIES crypt)
+      ENDIF()
+   
     ELSE (NOT WIN32 AND NOT CYGWIN)
       LIST(APPEND SMTP_LINK_LIBRARIES secur32.lib crypt32.lib winmm.lib ws2_32.lib)
     ENDIF (NOT WIN32 AND NOT CYGWIN)
-   
+
     # including shared c-client library
     ADD_LIBRARY (imap_commons STATIC
       cclient/imap_client.cpp

=== modified file 'src/com/zorba-xquery/www/modules/email/smtp.xq.src/mime_handler.cpp'
--- src/com/zorba-xquery/www/modules/email/smtp.xq.src/mime_handler.cpp	2011-09-30 14:44:37 +0000
+++ src/com/zorba-xquery/www/modules/email/smtp.xq.src/mime_handler.cpp	2012-07-04 11:04:24 +0000
@@ -18,12 +18,13 @@
 #include <cstdio>
 #include <sstream>
 
-#include <zorba/zorba_string.h>
+#include <zorba/base64.h>
 #include <zorba/iterator.h>
 #include <zorba/item_factory.h>
 #include <zorba/store_consts.h>
 #include <zorba/user_exception.h>
 #include <zorba/xquery_functions.h>
+#include <zorba/zorba_string.h>
 
 #include "mime_handler.h"
 
@@ -59,6 +60,45 @@
   lChildrenIt->close();
 }
 
+/**
+ * Encodes a zorba String if necessary (if it contains non-ascii chars)
+ * and assigns it to the passed char-pointer-reference.
+ */
+void encodeStringForEMailHeader(const zorba::String& aString, char*& aCClientVal)
+{
+  // check if string contains non ascii chars
+  bool lContainsNonAscii = false;
+  for (
+    zorba::String::const_iterator lIter = aString.begin();
+    lIter != aString.end();
+    ++lIter)
+  {
+    unsigned int u = static_cast<unsigned int>(*lIter);
+    if (!(u == '\t' || u == '\n' || u == '\t' || (u >= 32 && u <= 127)))
+    {
+      lContainsNonAscii = true;
+      break;
+    }
+  }
+
+  if (lContainsNonAscii)
+  {
+    // if string contains non-ascii chars, we encode it with
+    // base64 encoding and generate a header value according to
+    // http://tools.ietf.org/html/rfc2047 (MIME encoded-word syntax).
+    zorba::String lEncodedValue = zorba::encoding::Base64::encode(aString);
+    zorba::String lFullValue = zorba::String("=?UTF-8?B?") 
+                             + lEncodedValue 
+                             + zorba::String("?=");
+    aCClientVal = cpystr(lFullValue.c_str());
+  }
+  else 
+  {
+    // if string contains ascii chars only, do don't encode anything
+    aCClientVal = cpystr(aString.c_str());
+  }
+}
+
 // helper function for retrieving the name and email address from an item
 static void
 getNameAndEmailAddress(
@@ -70,20 +110,18 @@
   Iterator_t lChildren = aEmailItem.getChildren();
   lChildren->open();
   Item lChild;
-  bool lReadName = true;
+  // name might not exist -> empty string by default
+  aName = "";
   while (lChildren->next(lChild)) {
     if (lChild.getNodeKind() != store::StoreConsts::elementNode) {
       continue;
     }
 
-    // as a name is not mandatory, we first check if this is a name node
     String lNodeName;
     getNodeName(lChild, lNodeName);
     if (lNodeName == "name") {
       aName = lChild.getStringValue();
-      lReadName = false;
     } else {
-      aName = "";
       String lEmail = lChild.getStringValue();
       int lIndexOfAt = lEmail.find('@'); 
       aMailbox = lEmail.substr(0, lIndexOfAt).c_str();
@@ -96,9 +134,9 @@
 create_mail_address(String& aName, String& aMailbox, String& aHost)
 {
   mail_address* address = mail_newaddr();
-  address->personal = cpystr(const_cast<char*>(aName.c_str()));
-  address->mailbox = cpystr(const_cast<char*>(aMailbox.c_str()));
-  address->host = cpystr(const_cast<char*>(aHost.c_str()));
+  encodeStringForEMailHeader(aName, address->personal);
+  encodeStringForEMailHeader(aMailbox, address->mailbox);
+  encodeStringForEMailHeader(aHost, address->host);
   return address;
 }
 
@@ -188,7 +226,7 @@
       getNameAndEmailAddress(lChild, lName, lMailbox, lHost);
       theEnvelope->reply_to = create_mail_address(lName, lMailbox, lHost);
     } else if (lNodeName == "subject") {
-      theEnvelope->subject = cpystr(const_cast<char*>(lNodeValue.c_str()));
+      encodeStringForEMailHeader(lNodeValue, theEnvelope->subject);
     } else if (lNodeName == "recipient") {
       Iterator_t lRecipentChildren = lChild.getChildren(); 
       lRecipentChildren->open();
@@ -267,7 +305,7 @@
     std::stringstream lInStream;
     std::stringstream lOutStream;
     // for loop that counts to 64 and then makes a new line
-    lInStream << const_cast<char*>(aMessage.c_str());
+    lInStream << aMessage.c_str();
     char next;
     int counter = 0;
     while (lInStream >> next) {
@@ -383,7 +421,7 @@
       aBody->parameter = create_param("charset", fn::upper_case(lNodeValue), NIL);
     } else if (lNodeName == "contentTransferEncoding") {
       set_encoding(aBody, lNodeValue);  
-    } else if (lNodeName ,"contentDisposition") {
+    } else if (lNodeName == "contentDisposition") {
       aBody->disposition.type = cpystr(fn::upper_case(lNodeValue).c_str()); 
     } else if (lNodeName == "contentDisposition-filename") {
       if (!aBody->disposition.parameter) {  


Follow ups