zarafa/net-mail/zarafa/files/6.40.9.27553/Datux-spamhook.patch

200 lines
9.7 KiB
Diff

diff -rupN zarafa-6.40.0-orig/provider/libserver/ZarafaCmd.cpp zarafa-6.40.0/provider/libserver/ZarafaCmd.cpp
--- zarafa-6.40.0-orig/provider/libserver/ZarafaCmd.cpp 2010-05-31 19:28:59.000000000 +0200
+++ zarafa-6.40.0/provider/libserver/ZarafaCmd.cpp 2010-07-20 17:22:07.995625072 +0200
@@ -7244,6 +7244,166 @@ typedef struct{
SOURCEKEY sSourceKey;
SOURCEKEY sParentSourceKey;
}COPYITEM;
+//SPAM HOOK
+//This function parses an e-mail to the /etc/zarafa/userscripts/junklearn script. With 2 arguments:
+//ham or spam
+//message id
+//and pipes the mail header to the script.
+//This script wil be inhaled by MoveObjects();
+/////////////////////////////////////////////////////////////////////////////////////////////////
+int SpamHook(ECDatabase *lpDatabase,int ulId,int ulDestFolderId)
+{
+
+ ALLOC_DBRESULT();
+ ECRESULT er = erSuccess;
+ std::string shScriptPath = g_lpSessionManager->GetConfig()->GetSetting("junklearn_script");
+
+ //If shScriptPath doesn't exist skip spam hook.
+ if(fopen(shScriptPath.c_str(),"r")) {
+
+ //Get store object ID via message object id
+ unsigned int storeId;
+ er = g_lpSessionManager->GetCacheManager()->GetStore(ulId,&storeId,NULL);
+ if(er != erSuccess)
+ {
+ g_lpSessionManager->GetLogger()->Log(EC_LOGLEVEL_WARNING,"SpamHook: error while retrieve source folder.");
+ goto exit;
+ }
+
+ //get deleted items folder entry id
+ strQuery="SELECT val_binary FROM properties WHERE hierarchyid="+stringify(storeId)+" AND tag="+stringify(PROP_ID(PR_IPM_WASTEBASKET_ENTRYID));
+ er = lpDatabase->DoSelect(strQuery, &lpDBResult);
+ if(er != erSuccess) {
+ g_lpSessionManager->GetLogger()->Log(EC_LOGLEVEL_WARNING,"SpamHook: error while retrieve wastebasket entryid from DB.");
+ goto exit;
+ }
+ lpDBRow = lpDatabase->FetchRow(lpDBResult);
+ lpDBLen = lpDatabase->FetchRowLengths(lpDBResult);
+ int shNumRows=lpDatabase->GetNumRows(lpDBResult);
+ if(shNumRows<1)
+ {
+ g_lpSessionManager->GetLogger()->Log(EC_LOGLEVEL_WARNING,"SpamHook: error while retrieve wastebasket entryid, empty DB result.");
+ goto exit;
+ }
+
+ //Convert 'deleted items' entryid to objectid.
+ entryId* wasteBucketEntryId = new entryId[0];
+ wasteBucketEntryId->__ptr=(unsigned char*)lpDBRow[0];
+ wasteBucketEntryId->__size=lpDBLen[0];
+ unsigned int wasteBucketFolderId;
+ er=g_lpSessionManager->GetCacheManager()->GetObjectFromEntryId(wasteBucketEntryId,&wasteBucketFolderId);
+ delete wasteBucketEntryId;
+ if(er!=erSuccess)
+ {
+ g_lpSessionManager->GetLogger()->Log(EC_LOGLEVEL_WARNING,"SpamHook: error while retrieve wastebasket entryid, converting to objectID.");
+ goto exit;
+ }
+ FREE_DBRESULT();
+
+ //Get 'junk folder' entryId.
+ strQuery="SELECT val_binary FROM receivefolder LEFT JOIN mvproperties ON receivefolder.objid=mvproperties.hierarchyid WHERE receivefolder.storeid="+stringify(storeId)+" AND receivefolder.messageclass='IPC' AND mvproperties.tag="+stringify(PROP_ID(PR_ADDITIONAL_REN_ENTRYIDS))+" AND mvproperties.orderid=4";
+ er = lpDatabase->DoSelect(strQuery, &lpDBResult);
+ if(er != erSuccess) {
+ g_lpSessionManager->GetLogger()->Log(EC_LOGLEVEL_WARNING,"SpamHook: error while retrieve junkfolder entryids from DB.");
+ goto exit;
+ }
+ lpDBRow = lpDatabase->FetchRow(lpDBResult);
+ lpDBLen = lpDatabase->FetchRowLengths(lpDBResult);
+ shNumRows=lpDatabase->GetNumRows(lpDBResult);
+ if(shNumRows<1)
+ {
+ g_lpSessionManager->GetLogger()->Log(EC_LOGLEVEL_WARNING,"SpamHook: error while retrieve junkfolder entryid, empty DB result.");
+ goto exit;
+ }
+
+ //Convert 'junk folder' entryid to objectid.
+ entryId* junkFolderEntryId = new entryId[0];
+ junkFolderEntryId->__ptr=(unsigned char*)lpDBRow[0];
+ junkFolderEntryId->__size=lpDBLen[0];
+ unsigned int junkFolderId;
+ er=g_lpSessionManager->GetCacheManager()->GetObjectFromEntryId(junkFolderEntryId,&junkFolderId);
+ delete junkFolderEntryId;
+ if(er!=erSuccess)
+ {
+ g_lpSessionManager->GetLogger()->Log(EC_LOGLEVEL_WARNING,"SpamHook: error while retrieve junkfolder entryid, converting to objectID.");
+ goto exit;
+ }
+ FREE_DBRESULT();
+
+ //Get source folder object ID. (Actually we should check if mail came from subfolders in the 'deleted items folder', which I think never happens.)
+ unsigned int srcFolderId;
+ er=g_lpSessionManager->GetCacheManager()->GetParent(ulId,&srcFolderId);
+ if(er!=erSuccess)
+ {
+ g_lpSessionManager->GetLogger()->Log(EC_LOGLEVEL_WARNING,"SpamHook: error while retrieve src folder id.");
+ goto exit;
+ }
+
+ //Check if object is ham or spam
+ string shMailStatus;
+ //if destination folder is junk, mark as spam
+ if(ulDestFolderId==junkFolderId)
+ shMailStatus="spam";
+ else
+ {
+ //if destination folder is not TRASH and de source folder is JUNK, mark as ham
+ if(ulDestFolderId!=wasteBucketFolderId && srcFolderId==junkFolderId)
+ shMailStatus="ham";
+ }
+
+ //Only call hook script if the mail is marked as ham or spam.
+ if(!shMailStatus.empty()) {
+
+ //Get the mail from the DB.
+ strQuery="SELECT val_string FROM properties WHERE tag="+stringify(PROP_ID(PR_TRANSPORT_MESSAGE_HEADERS))+" AND hierarchyid= "+stringify(ulId);
+ er = lpDatabase->DoSelect(strQuery, &lpDBResult);
+ if(er != erSuccess) {
+ g_lpSessionManager->GetLogger()->Log(EC_LOGLEVEL_WARNING,"SpamHook: db error while retrieve mail header.");
+ goto exit;
+ }
+ lpDBRow = lpDatabase->FetchRow(lpDBResult);
+ int shNumRows=lpDatabase->GetNumRows(lpDBResult);
+
+ if(shNumRows>0) {
+
+ // Execute the hook:
+ FILE *shFilePtr;
+ shScriptPath=shScriptPath+" "+shMailStatus+" "+stringify(ulId);
+ shFilePtr=popen(shScriptPath.c_str(),"w");
+ fputs(lpDBRow[0],shFilePtr);
+ int shExitCode=pclose(shFilePtr);
+ if(!WIFEXITED(shExitCode)) {
+ g_lpSessionManager->GetLogger()->Log(EC_LOGLEVEL_WARNING,"SpamHook: "+shScriptPath+" was terminated abnormally.");
+ goto exit;
+ }
+ //If script exit with non 0, exit..
+ if(WEXITSTATUS(shExitCode)!=0) {
+ g_lpSessionManager->GetLogger()->Log(EC_LOGLEVEL_WARNING,"SpamHook: error "+shScriptPath+" exits with: "+stringify(shExitCode));
+ er=ZARAFA_E_UNKNOWN;
+ goto exit;
+ }
+ g_lpSessionManager->GetLogger()->Log(EC_LOGLEVEL_INFO,"SpamHook: "+shScriptPath+" successfully executed.");
+ er=erSuccess;
+ }
+ else {
+ g_lpSessionManager->GetLogger()->Log(EC_LOGLEVEL_WARNING,"SpamHook: warning mail header empty or this object is no e-mail");
+ }
+
+ // Free database results
+ FREE_DBRESULT();
+ }
+ }
+ else {
+ g_lpSessionManager->GetLogger()->Log(EC_LOGLEVEL_INFO,"SpamHook: skipping, script "+shScriptPath+" not found");
+ er=erSuccess;
+ }
+exit:
+ // Free database results
+ FREE_DBRESULT();
+
+ return er;
+}
+
// Move one or more messages and/or moved a softdeleted message to a normal message
ECRESULT MoveObjects(ECSession *lpSession, ECDatabase *lpDatabase, ECListInt* lplObjectIds, unsigned int ulDestFolderId, unsigned int ulSyncId)
@@ -8096,6 +8256,17 @@ SOAP_ENTRY_START5(copyObjects, *result,
// @note The object type checking wille be done in MoveObjects or CopyObject
+//SPAMHOOK
+/////////////////////////////////////
+ //Iterate over all mail ids and initiate spamhook.
+ for(iObjectId = lObjectIds.begin(); iObjectId != lObjectIds.end(); iObjectId++)
+ {
+ //Ignore the result
+ int shResult=SpamHook(lpDatabase,*iObjectId,ulDestFolderId);
+ }
+//SPAMHOOK END
+////////////////////////////////////
+
//check copy or a move
if(ulFlags & FOLDER_MOVE ) { // A move
er = MoveObjects(lpecSession, lpDatabase, &lObjectIds, ulDestFolderId, ulSyncId);
diff -rupN zarafa-6.40.0-orig/provider/server/ECServer.cpp zarafa-6.40.0/provider/server/ECServer.cpp
--- zarafa-6.40.0-orig/provider/server/ECServer.cpp 2010-05-31 19:28:59.000000000 +0200
+++ zarafa-6.40.0/provider/server/ECServer.cpp 2010-07-20 17:26:25.119624516 +0200
@@ -670,6 +670,7 @@ int running_server(char *szName, char *s
{ "deletegroup_script", "/etc/zarafa/userscripts/deletegroup", CONFIGSETTING_RELOADABLE},
{ "createcompany_script", "/etc/zarafa/userscripts/createcompany", CONFIGSETTING_RELOADABLE },
{ "deletecompany_script", "/etc/zarafa/userscripts/deletecompany", CONFIGSETTING_RELOADABLE },
+ { "junklearn_script", "/etc/zarafa/userscripts/junklearn", CONFIGSETTING_RELOADABLE },
{ "user_safe_mode", "no", CONFIGSETTING_RELOADABLE },
// Storename format