/* Exchange notifier plugin for Miranda IM Copyright © 2006 Cristian Libotean, Attila Vajda This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "emails.h" CExchangeServer::CExchangeServer() { bConnected = 0; //not connected bTryConnect = 1; //try to connect cConnections = 0; //first attempt } CExchangeServer::~CExchangeServer() { Disconnect(); } int CExchangeServer::Connect(int bForceConnect) { int maxRetries = db_get_b(NULL, ModuleName, "MaxRetries", MAX_EXCHANGE_CONNECT_RETRIES); if (bForceConnect) { bTryConnect = 1; cConnections = 0; } if (cConnections >= maxRetries) { bTryConnect = 0; cConnections = 0; _popupUtil("Maximum number of retries reached.\nPlugin will stop trying to connect automatically."); } if (bTryConnect) { cConnections++; } if ((bTryConnect) && !IsServerAvailable()) { bTryConnect = 0; _popupUtil("Server not available"); } if ((!IsConnected()) && (bTryConnect)) { TCHAR user[1024]; //lovely TCHAR password[1024]; //i know char apassword[1024]; TCHAR server[1024]; int port; GetStringFromDatabase("Username", _T(""), user, _countof(user)); if (ServiceExists(MS_UTILS_REPLACEVARS)) { TCHAR *tmpUser = Utils_ReplaceVarsT(user); _tcsncpy(user, tmpUser, _countof(user)); mir_free(tmpUser); } GetStringFromDatabase("Password", _T(""), password, _countof(password)); strcpy(apassword,mir_t2a(password)); CallService(MS_DB_CRYPT_DECODESTRING, sizeof(apassword), (LPARAM) apassword); _tcsncpy(password,mir_a2t(apassword),_countof(password)); GetStringFromDatabase("Server", _T(""), server, _countof(server)); port = db_get_dw(NULL, ModuleName, "Port", EXCHANGE_PORT); if (_tcslen(server) > 0) //only connect if there's a server to connect to { return DoConnect(user, password, server, port); } else { _popupUtil("Server is not configured ..."); } } return -1; //0 on success, != 0 otherwise } int CExchangeServer::Reconnect() { Disconnect(); Connect(); return 0; } int CExchangeServer::Disconnect() { // if (IsConnected()) // { return DoDisconnect(); // } // return -1; //0 on success, != 0 otherwise } int CExchangeServer::DoConnect(TCHAR *user, TCHAR *password, TCHAR *server, int port) { if (bTryConnect) { bConnected = 0; #ifndef NO_EXCHANGE_TEST if ( InitializeAndLogin( user, password, server )== S_OK) { bConnected = 1; cConnections = 0; //restart connection attempts counter } #endif } return !bConnected; //0 on success, != 0 otherwise } int CExchangeServer::DoDisconnect() { #ifndef NO_EXCHANGE_TEST LogOFF(); #endif bConnected = 0; return bConnected; //0 on success, != 0 otherwise } int CExchangeServer::IsConnected() { #ifndef NO_EXCHANGE_TEST return bConnected; #else return true; #endif } void InitSocketAddr(sockaddr_in *addrServer, char *szServer) { hostent *hp; hp = gethostbyname(szServer); addrServer->sin_family = AF_INET; if (hp == NULL) { addrServer->sin_addr.s_addr = inet_addr(szServer); } else{ memcpy(&(addrServer->sin_addr), hp->h_addr, hp->h_length); } int port = db_get_dw(NULL, ModuleName, "Port", EXCHANGE_PORT); addrServer->sin_port = htons(port); } int CExchangeServer::IsServerAvailable() { int check = db_get_b(NULL, ModuleName, "UsePortCheck", 1); if (check) { SOCKET sServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sServer == INVALID_SOCKET) { return 0; //server is not available } TCHAR szServer[1024]; GetStringFromDatabase("Server", _T(""), szServer, sizeof(szServer)); sockaddr_in addrServer; InitSocketAddr(&addrServer, mir_t2a(szServer)); int res = connect(sServer, (sockaddr *) &addrServer, sizeof(addrServer)); int bAvailable = 0; if (!res) {//if connected then close smtp connection by sending a quit message bAvailable = 1; char message[] = "quit\n"; res = send(sServer, message, strlen(message), 0); } res = closesocket(sServer); //close the socket return bAvailable; } else{ return 1; //if we're not using port check assume the server is available. } } int CExchangeServer::GetUnreadEmailsCount() { int nCount = -1; #ifndef NO_EXCHANGE_TEST HRESULT hRes = CheckForNewMails(nCount); if (hRes!=S_OK) { Reconnect(); if (IsConnected()) { hRes = CheckForNewMails(nCount); } else { nCount = -1; } } #else nCount = 3; #endif return nCount; } int CExchangeServer::GetEmailHeader(int iUnreadEmail, TEmailHeader *emailInfo) { if (!IsConnected()) { //Connect(); return -1; } if (emailInfo->cbSize != sizeof(TEmailHeader)) { return -1; } #ifndef NO_EXCHANGE_TEST if(NULL!=m_HeadersKeeper[iUnreadEmail]) { TCHAR* szSender = m_HeadersKeeper[iUnreadEmail]->m_szSender; TCHAR* szSubject = m_HeadersKeeper[iUnreadEmail]->m_szSubject; if( NULL == szSender) { szSender = _T(""); } if( NULL == szSubject) { szSubject = _T(""); } emailInfo->szSender = szSender; emailInfo->szSubject = szSubject; emailInfo->emailID = (NULL!=m_HeadersKeeper[iUnreadEmail]->m_szEntryID)?m_HeadersKeeper[iUnreadEmail]->m_szEntryID:""; } else { return -1; } #else emailInfo->szSender = ""; emailInfo->szSubject = ""; emailInfo->emailID = "123"; #endif return 0; } int CExchangeServer::MarkEmailAsRead(TCHAR *emailID) { if (!IsConnected()) { return -1; } #ifndef NO_EXCHANGE_TEST MarkAsRead( emailID ); #endif return 0; } int CExchangeServer::OpenMessage(TCHAR *emailID) { if (!IsConnected()) { return -1; } #ifndef NO_EXCHANGE_TEST OpenTheMessage( emailID ); #endif return 0; } int CExchangeServer::Check(int bNoEmailsNotify) { int count = -1; if (IsConnected()) { count = GetUnreadEmailsCount(); if (count==-1) { Reconnect(); if (IsConnected()) { count = GetUnreadEmailsCount(); } else { return -1; } } } else { Reconnect(); if (IsConnected()) { count = GetUnreadEmailsCount(); } else { return -1; } if (count==-1) { return -1; } } if( ( (count > 0) || ((bNoEmailsNotify) && (count >= 0)) )&& (count!=-1)) { TCHAR buffer[1024]; if (count != 1) { mir_sntprintf(buffer,_countof(buffer), TranslateT("You have %d unread emails ..."), count); } else { mir_sntprintf(buffer, _countof(buffer),TranslateT("You have one unread email ...")); } ShowMessage(buffer, count); /*int i; TEmailHeader emailInfo = {0}; char sender[1024]; char subject[1024]; emailInfo.cbSize = sizeof(emailInfo); emailInfo.szSender = sender; emailInfo.szSubject = subject; emailInfo.cSender = sizeof(sender); emailInfo.cSubject = sizeof(subject); for (i = 0; i < count; i++) { GetEmailHeader(i, &emailInfo); sprintf(buffer, "Unread email #%d:\nSender :%s\nSubject :%s", i + 1, sender, subject); ShowMessage(buffer); }*/ } if (count==-1) { _popupUtil("Cannot connect to Exchange server ..."); } return count; } int ShowMessage(TCHAR *message, int cUnreadEmails) { int usePopups = ServiceExists(MS_POPUP_ADDPOPUP) ? db_get_b(NULL, ModuleName, "UsePopups", 0) : 0; if (usePopups) { return ShowPopupMessage(TranslateT("Exchange email"), message, cUnreadEmails); } else{ return ShowMessageBoxMessage(TranslateT("Do you want to see the email headers ?"), message, cUnreadEmails); } return 0; } int ShowPopupMessage(TCHAR *title, TCHAR *message, int cUnreadEmails) { POPUPDATAT popup = {0}; popup.lchContact = NULL; popup.colorBack = NULL; popup.colorText = NULL; popup.lchIcon = hiMailIcon; _tcsncpy(popup.lptzContactName, title,_tcslen(title)); _tcsncpy(popup.lptzText, message,_tcslen(message)); popup.PluginWindowProc = (WNDPROC) DlgProcPopup; popup.PluginData = (int *) cUnreadEmails; return PUAddPopupT(&popup); } int ShowMessageBoxMessage(TCHAR *title, TCHAR *message, int cUnreadEmails) { if (MessageBox(0, message, title, MB_YESNO) == IDYES) { ShowEmailsWindow(cUnreadEmails); } return 0; } int ShowEmailsWindow(int cUnreadEmails) { if (cUnreadEmails > 0) //show window only if there are unread emails { if (!hEmailsDlg) { hEmailsDlg = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_EMAILS), NULL, (DLGPROC)DlgProcEmails); } SetWindowLong(hEmailsDlg, GWLP_USERDATA, cUnreadEmails); if (IsWindowVisible(hEmailsDlg)) { SendMessage(hEmailsDlg, EXM_UPDATE_EMAILS, 0, 0); } else { ShowWindow(hEmailsDlg, SW_SHOW); } } return 0; }