/* 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 "stdafx.h" #include "dlg_handlers.h" #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 = g_plugin.getByte("MaxRetries", MAX_EXCHANGE_CONNECT_RETRIES); if (bForceConnect) { bTryConnect = 1; cConnections = 0; } if (cConnections >= maxRetries) { bTryConnect = 0; cConnections = 0; _popupUtil(TranslateT("Maximum number of retries reached.\nPlugin will stop trying to connect automatically.")); } if (bTryConnect) cConnections++; if ((bTryConnect) && !IsServerAvailable()) { bTryConnect = 0; _popupUtil(TranslateT("Server not available")); } if ( !IsConnected() && bTryConnect) { wchar_t user[1024]; //lovely wchar_t password[1024]; //i know wchar_t server[1024]; GetStringFromDatabase("Username", L"", user, _countof(user)); wcsncpy_s(user, VARSW(user), _TRUNCATE); GetStringFromDatabase("Password", L"", password, _countof(password)); GetStringFromDatabase("Server", L"", server, _countof(server)); int port = g_plugin.getDword("Port", EXCHANGE_PORT); if (mir_wstrlen(server) > 0) //only connect if there's a server to connect to return DoConnect(user, password, server, port); _popupUtil(TranslateT("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(wchar_t *user, wchar_t *password, wchar_t *server, int) { 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 == nullptr) addrServer->sin_addr.s_addr = inet_addr(szServer); else memcpy(&(addrServer->sin_addr), hp->h_addr, hp->h_length); int port = g_plugin.getDword("Port", EXCHANGE_PORT); addrServer->sin_port = htons(port); } int CExchangeServer::IsServerAvailable() { if (!g_plugin.getByte("UsePortCheck", 1)) return 1; SOCKET sServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sServer == INVALID_SOCKET) return 0; //server is not available wchar_t szServer[1024]; GetStringFromDatabase("Server", L"", szServer, sizeof(szServer)); sockaddr_in addrServer; InitSocketAddr(&addrServer, mir_u2a(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"; send(sServer, message, (int)mir_strlen(message), 0); } res = closesocket(sServer); //close the socket return bAvailable; } 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()) return -1; if (emailInfo->cbSize != sizeof(TEmailHeader)) return -1; #ifndef NO_EXCHANGE_TEST if (nullptr != m_HeadersKeeper[iUnreadEmail]) { wchar_t* szSender = m_HeadersKeeper[iUnreadEmail]->m_szSender; wchar_t* szSubject = m_HeadersKeeper[iUnreadEmail]->m_szSubject; if (nullptr == szSender) szSender = L""; if (nullptr == szSubject) szSubject = L""; 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(wchar_t *emailID) { if (!IsConnected()) return -1; #ifndef NO_EXCHANGE_TEST MarkAsRead( emailID ); #endif return 0; } int CExchangeServer::OpenMessage(wchar_t *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)) { wchar_t buffer[1024]; if (count != 1) mir_snwprintf(buffer, TranslateT("You have %d unread emails..."), count); else mir_snwprintf(buffer, TranslateT("You have one unread email...")); ShowMessage(buffer, count); } if (count==-1) _popupUtil(TranslateT("Cannot connect to Exchange server...")); return count; } int ShowMessage(wchar_t *message, int cUnreadEmails) { int usePopups = ServiceExists(MS_POPUP_ADDPOPUPT) ? g_plugin.getByte("UsePopups", 0) : 0; if (usePopups) return ShowPopupMessage(TranslateT("Exchange email"), message, cUnreadEmails); return ShowMessageBoxMessage(TranslateT("Do you want to see the email headers?"), message, cUnreadEmails); } int ShowPopupMessage(wchar_t *title, wchar_t *message, int cUnreadEmails) { POPUPDATAT popup = {0}; popup.lchContact = NULL; popup.colorBack = NULL; popup.colorText = NULL; popup.lchIcon = hiMailIcon; wcsncpy_s(popup.lptzContactName, MAX_CONTACTNAME, title, _TRUNCATE); wcsncpy_s(popup.lptzText, MAX_SECONDLINE, message, _TRUNCATE); popup.PluginWindowProc = DlgProcPopup; popup.PluginData = (int *) cUnreadEmails; return PUAddPopupT(&popup); } int ShowMessageBoxMessage(wchar_t *title, wchar_t *message, int cUnreadEmails) { if (MessageBox(nullptr, 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(g_plugin.getInst(), MAKEINTRESOURCE(IDD_EMAILS), nullptr, DlgProcEmails); SetWindowLongPtr(hEmailsDlg, GWLP_USERDATA, cUnreadEmails); if (IsWindowVisible(hEmailsDlg)) SendMessage(hEmailsDlg, EXM_UPDATE_EMAILS, 0, 0); else ShowWindow(hEmailsDlg, SW_SHOW); } return 0; }