/* Plugin of Miranda IM for communicating with users of the AIM protocol. Copyright (c) 2008-2012 Boris Krasnovskiy Copyright (C) 2005-2006 Aaron Myles Landwehr 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, see . */ #include "aim.h" void CAimProto::broadcast_status(int status) { LOG("Broadcast Status: %d",status); int old_status = m_iStatus; m_iStatus = status; if (m_iStatus == ID_STATUS_OFFLINE) { shutdown_file_transfers(); shutdown_chat_conn(); if (hServerConn) { aim_sendflap(hServerConn,0x04,0,NULL,seqno); Netlib_Shutdown(hServerConn); } if (hMailConn && hMailConn != (HANDLE)1) { aim_sendflap(hMailConn,0x04,0,NULL,mail_seqno); Netlib_Shutdown(hMailConn); } else if (hMailConn == (HANDLE)1) hMailConn = NULL; if (hAvatarConn && hAvatarConn != (HANDLE)1) { aim_sendflap(hAvatarConn,0x04,0,NULL,avatar_seqno); Netlib_Shutdown(hAvatarConn); } else if (hAvatarConn == (HANDLE)1) hAvatarConn = NULL; if (hChatNavConn && hChatNavConn != (HANDLE)1) { aim_sendflap(hChatNavConn,0x04,0,NULL,chatnav_seqno); Netlib_Shutdown(hChatNavConn); } else if (hChatNavConn == (HANDLE)1) hChatNavConn = NULL; idle = false; instantidle = false; list_received = false; state = 0; m_iDesiredStatus = ID_STATUS_OFFLINE; mir_free(last_status_msg); last_status_msg = NULL; avatar_id_lg = 0; avatar_id_sm = 0; mir_free(hash_lg); hash_lg = NULL; mir_free(hash_sm); hash_sm = NULL; pd_flags = 0; pd_info_id = 0; pd_mode = 0; seqno = 0; mail_seqno = 0; avatar_seqno = 0; chatnav_seqno = 0; admin_seqno = 0; } ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus); } void CAimProto::start_connection(void *arg) { int status = (int)arg; if (m_iStatus<=ID_STATUS_OFFLINE) { offline_contacts(); DBVARIANT dbv; if (!getString(AIM_KEY_SN, &dbv)) db_free(&dbv); else { ShowPopup(LPGEN("Please, enter a username in the options dialog."), 0); broadcast_status(ID_STATUS_OFFLINE); return; } if (!getString(AIM_KEY_PW, &dbv)) db_free(&dbv); else { ShowPopup(LPGEN("Please, enter a password in the options dialog."), 0); broadcast_status(ID_STATUS_OFFLINE); return; } bool use_ssl = !getByte(AIM_KEY_DSSL, 0); char* login_url = getSetting(AIM_KEY_HN); if (login_url == NULL) login_url = mir_strdup(use_ssl ? AIM_DEFAULT_SERVER : AIM_DEFAULT_SERVER_NS); hServerConn = aim_connect(login_url, get_default_port(), use_ssl, login_url); mir_free(login_url); pref1_flags = 0x77ffff; pref1_set_flags = 0x77ffff; mir_free(pref2_flags); pref2_flags = NULL; pref2_len = 0; mir_free(pref2_set_flags); pref2_set_flags = NULL; pref2_set_len = 0; if (hServerConn) aim_connection_authorization(); else broadcast_status(ID_STATUS_OFFLINE); } } bool CAimProto::wait_conn(HANDLE& hConn, HANDLE& hEvent, unsigned short service) { if (m_iStatus == ID_STATUS_OFFLINE) return false; EnterCriticalSection(&connMutex); if (hConn == NULL && hServerConn) { LOG("Starting Connection."); hConn = (HANDLE)1; //set so no additional service request attempts are made while aim is still processing the request aim_new_service_request(hServerConn, seqno, service) ;//general service connection! } LeaveCriticalSection(&connMutex); if (WaitForSingleObjectEx(hEvent, 10000, TRUE) != WAIT_OBJECT_0) return false; if (Miranda_Terminated() || m_iStatus == ID_STATUS_OFFLINE) return false; return true; } unsigned short CAimProto::get_default_port(void) { return getWord(AIM_KEY_PN, getByte(AIM_KEY_DSSL, 0) ? AIM_DEFAULT_PORT : AIM_DEFAULT_SSL_PORT); } bool CAimProto::is_my_contact(HANDLE hContact) { const char* szProto = GetContactProto(hContact); return szProto != NULL && strcmp(m_szModuleName, szProto) == 0; } HANDLE CAimProto::find_chat_contact(const char* room) { for (HANDLE hContact = db_find_first(m_szModuleName); hContact; hContact = db_find_next(hContact, m_szModuleName)) { DBVARIANT dbv; if (!getString(hContact, "ChatRoomID", &dbv)) { bool found = !strcmp(room, dbv.pszVal); db_free(&dbv); if (found) return hContact; } } return NULL; } HANDLE CAimProto::contact_from_sn(const char* sn, bool addIfNeeded, bool temporary) { ptrA norm_sn( normalize_name(sn)); for (HANDLE hContact = db_find_first(m_szModuleName); hContact; hContact = db_find_next(hContact, m_szModuleName)) { DBVARIANT dbv; if (!getString(hContact, AIM_KEY_SN, &dbv)) { bool found = !strcmp(norm_sn, dbv.pszVal); db_free(&dbv); if (found) return hContact; } } if (addIfNeeded) { HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_ADD, 0, 0); if (hContact) { if (CallService(MS_PROTO_ADDTOCONTACT, (WPARAM) hContact, (LPARAM) m_szModuleName) == 0) { setString(hContact, AIM_KEY_SN, norm_sn); setString(hContact, AIM_KEY_NK, sn); LOG("Adding contact %s to client side list.",norm_sn); if (temporary) db_set_b(hContact, "CList", "NotOnList", 1); return hContact; } CallService(MS_DB_CONTACT_DELETE, (WPARAM)hContact, 0); } } return NULL; } void CAimProto::update_server_group(const char* group, unsigned short group_id) { unsigned short user_id_array_size; unsigned short* user_id_array; if (group_id) user_id_array = get_members_of_group(group_id, user_id_array_size); else { user_id_array_size = (unsigned short)group_list.getCount(); user_id_array = (unsigned short*)mir_alloc(user_id_array_size * sizeof(unsigned short)); for (unsigned short i=0; i