From c90d55ec2adeb5864f9629116f735457f296009a Mon Sep 17 00:00:00 2001 From: Kirill Volinsky Date: Sat, 7 Jul 2012 22:13:58 +0000 Subject: CmdLine: adopted, MimCmd not adopted yet git-svn-id: http://svn.miranda-ng.org/main/trunk@839 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/CmdLine/mimcmd_handlers.cpp | 2307 +++++++++++++++++++++++++++++++++++ 1 file changed, 2307 insertions(+) create mode 100644 plugins/CmdLine/mimcmd_handlers.cpp (limited to 'plugins/CmdLine/mimcmd_handlers.cpp') diff --git a/plugins/CmdLine/mimcmd_handlers.cpp b/plugins/CmdLine/mimcmd_handlers.cpp new file mode 100644 index 0000000000..9b2d89b696 --- /dev/null +++ b/plugins/CmdLine/mimcmd_handlers.cpp @@ -0,0 +1,2307 @@ +/* +CmdLine plugin for Miranda IM + +Copyright © 2007 Cristian Libotean + +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 "commonheaders.h" + +#define STATE_UNKNOWN -1 +#define STATE_OFF 0 +#define STATE_ON 1 +#define STATE_TOGGLE 2 + +#define PROXY_SOCKS4 1 +#define PROXY_SOCKS5 2 +#define PROXY_HTTP 3 +#define PROXY_HTTPS 4 + +#define VALUE_UNKNOWN -1 +#define VALUE_ERROR 0 +#define VALUE_BYTE 1 +#define VALUE_WORD 2 +#define VALUE_DWORD 3 +#define VALUE_STRING 4 +#define VALUE_WIDE 5 + +__inline static int matches(char *command, char *lower) +{ + return ((strcmp(lower, command) == 0) || (strcmp(lower, Translate(command)) == 0)); +} + +int Get2StateValue(char *state) +{ + char lower[512]; + STRNCPY(lower, state, sizeof(lower)); + _strlwr(lower); + + //if ((strcmp(lower, "enable") == 0) || (strcmp(lower, "show") == 0) || (strcmp(lower, "on") == 0)) + if ((matches("enable", lower)) || (matches("show", lower)) || (matches("on", lower))) + { + return STATE_ON; + } + + //if ((strcmp(lower, "disable") == 0) || (strcmp(lower, "hide") == 0) || (strcmp(lower, "off") == 0)) + if ((matches("disable", lower)) || (matches("hide", lower)) || (matches("off", lower))) + { + return STATE_OFF; + } + + //if (strcmp(lower, "toggle") == 0) + if (matches("toggle", lower)) + { + return STATE_TOGGLE; + } + + return STATE_UNKNOWN; +} + +int AccountName2Protocol(const char *accountName, OUT char *uniqueProtocolName, size_t length) +{ + int count; + PROTOACCOUNT **accounts = NULL; + + ProtoEnumAccounts(&count, &accounts); + + STRNCPY(uniqueProtocolName, accountName, length); + + for (int i = 0; i < count; i++) + { + if (accounts[i]->bIsEnabled) + { + if (_stricmp(accountName, accounts[i]->tszAccountName) == 0) + { + STRNCPY(uniqueProtocolName, accounts[i]->szModuleName, length); + + return 0; + } + + //the account name may be unicode, try comparing with an unicode string too + char *account = mir_u2a((wchar_t *) accounts[i]->tszAccountName); + if (_stricmp(accountName, account) == 0) + { + STRNCPY(uniqueProtocolName, accounts[i]->szModuleName, length); + + mir_free(account); + return 0; + } + + mir_free(account); + } + } + + return 1; +} + +void HandleCommand(PCommand command, TArgument *argv, int argc, PReply reply) +{ + switch (command->ID) + { + case MIMCMD_STATUS: + { + HandleStatusCommand(command, argv, argc, reply); + + break; + } + + case MIMCMD_AWAYMSG: + { + HandleAwayMsgCommand(command, argv, argc, reply); + + break; + } + // + //case MIMCMD_XSTATUS: + //{ + // + // break; + //} + + case MIMCMD_POPUPS: + { + HandlePopupsCommand(command, argv, argc, reply); + + break; + } + + case MIMCMD_SOUNDS: + { + HandleSoundsCommand(command, argv, argc, reply); + + break; + } + + case MIMCMD_CLIST: + { + HandleClistCommand(command, argv, argc, reply); + + break; + } + + case MIMCMD_QUIT: + { + HandleQuitCommand(command, argv, argc, reply); + + break; + } + + case MIMCMD_EXCHANGE: + { + HandleExchangeCommand(command, argv, argc, reply); + + break; + } + + case MIMCMD_YAMN: + { + HandleYAMNCommand(command, argv, argc, reply); + + break; + } + + case MIMCMD_CALLSERVICE: + { + HandleCallServiceCommand(command, argv, argc, reply); + + break; + } + + case MIMCMD_MESSAGE: + { + HandleMessageCommand(command, argv, argc, reply); + + break; + } + + case MIMCMD_DATABASE: + { + HandleDatabaseCommand(command, argv, argc, reply); + + break; + } + + case MIMCMD_PROXY: + { + HandleProxyCommand(command, argv, argc, reply); + + break; + } + + case MIMCMD_CONTACTS: + { + HandleContactsCommand(command, argv, argc, reply); + + break; + } + + case MIMCMD_HISTORY: + { + HandleHistoryCommand(command, argv, argc, reply); + + break; + } + + case MIMCMD_VERSION: + { + HandleVersionCommand(command, argv, argc, reply); + + break; + } + + case MIMCMD_SETNICKNAME: + { + HandleSetNicknameCommand(command, argv, argc, reply); + + break; + } + + case MIMCMD_IGNORE: + { + HandleIgnoreCommand(command, argv, argc, reply); + + break; + } + + default: + { + reply->code = MIMRES_NOTFOUND; + mir_snprintf(reply->message, reply->cMessage, Translate("Command '%s' is not currently supported."), command->command); + + break; + } + } +} + +void HandleWrongParametersCount(PCommand command, PReply reply) +{ + reply->code = MIMRES_WRONGPARAMSCOUNT; + mir_snprintf(reply->message, reply->cMessage, Translate("Wrong number of parameters for command '%s'."), command->command); +} + +void HandleUnknownParameter(PCommand command, char *param, PReply reply) +{ + reply->code = MIMRES_UNKNOWNPARAM; + mir_snprintf(reply->message, reply->cMessage, Translate("Unknown parameter '%s' for command '%s'."), param, command->command); +} + +int ParseValueParam(char *param, void *&result) +{ + int ok = VALUE_UNKNOWN; + if (strlen(param) > 0) + { + switch (*param) + { + case 's': + { + size_t len = strlen(param); //- 1 + 1 + result = (char *) malloc(len * sizeof(char)); + STRNCPY((char *) result, param + 1, len); + ((char *) result)[len - 1] = 0; + + ok = VALUE_STRING; + + break; + } + + case 'w': + { + size_t len = strlen(param); + result = (WCHAR *) malloc(len * sizeof(WCHAR)); + char *buffer = (char *) malloc(len * sizeof(WCHAR)); + STRNCPY(buffer, param + 1, len); + + MultiByteToWideChar(CP_ACP, 0, buffer, -1, (WCHAR *) result, (int) len); + + free(buffer); + + ok = VALUE_WIDE; + + break; + } + + case 'b': + { + result = (char *) malloc(sizeof(char)); + long tmp; + char *stop; + + tmp = strtol(param + 1, &stop, 10); + * ((char *) result) = tmp; + + ok = (*stop == 0) ? VALUE_BYTE : VALUE_ERROR; + + break; + } + + case 'i': + { + result = (int *) malloc(sizeof(int)); + long tmp; + char *stop; + + tmp = strtol(param + 1, &stop, 10); + * ((int *) result) = tmp; + + ok = (*stop == 0) ? VALUE_WORD : VALUE_ERROR; + + break; + } + + case 'd': + { + result = (long *) malloc(sizeof(long)); + char *stop; + * ((long *) result) = strtol(param + 1, &stop, 10); + + ok = (*stop == 0) ? VALUE_DWORD : VALUE_ERROR; + + break; + } + } + } + + return ok; +} + +int ParseStatusParam(char *status) +{ + int res = 0; + char lower[256]; + STRNCPY(lower, status, sizeof(lower)); + + if (strcmp(lower, "offline") == 0) + { + res = ID_STATUS_OFFLINE; + } + else{ + if (strcmp(lower, "online") == 0) + { + res = ID_STATUS_ONLINE; + } + else{ + if (strcmp(lower, "away") == 0) + { + res = ID_STATUS_AWAY; + } + else{ + if (strcmp(lower, "dnd") == 0) + { + res = ID_STATUS_DND; + } + else{ + if (strcmp(lower, "na") == 0) + { + res = ID_STATUS_NA; + } + else{ + if (strcmp(lower, "occupied") == 0) + { + res = ID_STATUS_OCCUPIED; + } + else{ + if (strcmp(lower, "freechat") == 0) + { + res = ID_STATUS_FREECHAT; + } + else{ + if (strcmp(lower, "invisible") == 0) + { + res = ID_STATUS_INVISIBLE; + } + else{ + if (strcmp(lower, "onthephone") == 0) + { + res = ID_STATUS_ONTHEPHONE; + } + else{ + if (strcmp(lower, "outtolunch") == 0) + { + res = ID_STATUS_OUTTOLUNCH; + }//outtolunch + }//onthephone + }//invisible + }//freechat + }//occupied + }//na + } //dnd + } //away + } //online + } //offline + + return res; +} + +char *PrettyStatusMode(int status, char *buffer, int size) +{ + *buffer = 0; + char *data = (char *) CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, status, 0); + if (data) + { + STRNCPY(buffer, data, size); + } + + return buffer; +} + +void HandleStatusCommand(PCommand command, TArgument *argv, int argc, PReply reply) +{ + switch (argc) + { + case 2: + { + INT_PTR status = CallService(MS_CLIST_GETSTATUSMODE, 0, 0); + char pretty[128]; + PrettyStatusMode(status, pretty, sizeof(pretty)); + + const int cPerAccountStatus = 1024 * 5; + char *perAccountStatus = (char *) malloc(cPerAccountStatus); + + perAccountStatus[0] = 0; + + int count; + PROTOACCOUNT **accounts = NULL; + + char pn[128]; + + ProtoEnumAccounts(&count, &accounts); + + for (int i = 0; i < count; i++) + { + if (accounts[i]->bIsEnabled) + { + INT_PTR status = CallProtoService(accounts[i]->szModuleName, PS_GETSTATUS, 0, 0); + PrettyStatusMode(status, pn, sizeof(pn)); + + strncat(perAccountStatus, "\n", cPerAccountStatus); + + char *account = mir_u2a((wchar_t *) accounts[i]->tszAccountName); + strncat(perAccountStatus, account, cPerAccountStatus); + mir_free(account); + + strncat(perAccountStatus, ": ", cPerAccountStatus); + strncat(perAccountStatus, pn, cPerAccountStatus); + } + } + + reply->code = MIMRES_SUCCESS; + mir_snprintf(reply->message, reply->cMessage, Translate("Current global status: %s.%s"), pretty, perAccountStatus); + + free(perAccountStatus); + + break; + } + + case 3: + { + int status = ParseStatusParam(argv[2]); + if (status) + { + INT_PTR old = CallService(MS_CLIST_GETSTATUSMODE, 0, 0); + char po[128]; + if (ServiceExists(MS_KS_ANNOUNCESTATUSCHANGE)) + { + announce_status_change(NULL, status, NULL); + } + + PrettyStatusMode(old, po, sizeof(po)); + CallService(MS_CLIST_SETSTATUSMODE, status, 0); + char pn[128]; + PrettyStatusMode(status, pn, sizeof(pn)); + + reply->code = MIMRES_SUCCESS; + mir_snprintf(reply->message, reply->cMessage, Translate("Changed global status to '%s' (previous status was '%s')."), pn, po); + } + else{ + HandleUnknownParameter(command, argv[2], reply); + } + + break; + } + + case 4: + { + int status = ParseStatusParam(argv[2]); + if (status) + { + char protocol[128]; + char *account = argv[3]; + AccountName2Protocol(account, protocol, sizeof(protocol)); + + INT_PTR old = CallProtoService(protocol, PS_GETSTATUS, 0, 0); + char po[128]; + if (ServiceExists(MS_KS_ANNOUNCESTATUSCHANGE)) + { + announce_status_change(protocol, status, NULL); + } + + PrettyStatusMode(old, po, sizeof(po)); + INT_PTR res = CallProtoService(protocol, PS_SETSTATUS, status, 0); + char pn[128]; + PrettyStatusMode(status, pn, sizeof(pn)); + + switch (res) + { + case 0: + { + reply->code = MIMRES_SUCCESS; + mir_snprintf(reply->message, reply->cMessage, Translate("Changed '%s' status to '%s' (previous status was '%s')."), account, pn, po); + + break; + } + + case CALLSERVICE_NOTFOUND: + { + reply->code = MIMRES_FAILURE; + mir_snprintf(reply->message, reply->cMessage, Translate("'%s' doesn't seem to be a valid account."), account); + + break; + } + + default: + { + reply->code = MIMRES_FAILURE; + mir_snprintf(reply->message, reply->cMessage, Translate("Failed to change status for account '%s' to '%s'."), account, pn); + + break; + } + } + } + else{ + HandleUnknownParameter(command, argv[2], reply); + } + + break; + } + + default: + { + HandleWrongParametersCount(command, reply); + + break; + } + } +} + +void GetProtocols(int *count, PROTOCOLDESCRIPTOR ***protocols) +{ + CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM) count, (LPARAM) protocols); +} + +void HandleAwayMsgCommand(PCommand command, TArgument *argv, int argc, PReply reply) +{ + switch (argc) + { + case 3: + { + char *awayMsg = argv[2]; + int count = 0; + PROTOACCOUNT **accounts = NULL; + ProtoEnumAccounts(&count, &accounts); + + int i; + INT_PTR status; + INT_PTR res = 0; + char *protocol; + char buffer[1024]; + char pn[128]; + for (i = 0; i < count; i++) + { + if (accounts[i]->bIsEnabled) + { + protocol = accounts[i]->szModuleName; + if ((CallProtoService(protocol, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_MODEMSGSEND) != 0) //if the protocol supports away messages + { + status = CallProtoService(protocol, PS_GETSTATUS, 0, 0); + res = CallProtoService(protocol, PS_SETAWAYMSG, status, (LPARAM) awayMsg); + PrettyStatusMode(status, pn, sizeof(pn)); + if (res) + { + mir_snprintf(buffer, sizeof(buffer), Translate("Failed to set '%S' status message to '%s' (status is '%s')."), accounts[i]->tszAccountName , awayMsg, pn); + } + else{ + mir_snprintf(buffer, sizeof(buffer), Translate("Successfully set '%S' status message to '%s' (status is '%s')."), accounts[i]->tszAccountName, awayMsg, pn); + } + } + else{ + mir_snprintf(buffer, sizeof(buffer), Translate("Account '%S' does not support away messages, skipping."), accounts[i]->tszAccountName); + } + + if (i != 0) + { + strncat(reply->message, "\n", reply->cMessage); + strncat(reply->message, buffer, reply->cMessage); + } + else{ + STRNCPY(reply->message, buffer, reply->cMessage); + } + } + } + reply->code = MIMRES_SUCCESS; + + break; + } + + case 4: + { + char *awayMsg = argv[2]; + char protocol[128]; + char *account = argv[3]; + AccountName2Protocol(account, protocol, sizeof(protocol)); + + INT_PTR res = 0; + char pn[128]; + if ((res = CallProtoService(protocol, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_MODEMSGSEND) != 0) //if the protocol supports away messages + { + INT_PTR status = CallProtoService(protocol, PS_GETSTATUS, 0, 0); + res = CallProtoService(protocol, PS_SETAWAYMSG, status, (LPARAM) awayMsg); + + PrettyStatusMode(status, pn, sizeof(pn)); + } + else{ + if (CallProtoService(protocol, PS_GETSTATUS, 0, 0) == CALLSERVICE_NOTFOUND) + { + res = CALLSERVICE_NOTFOUND; + } + else { + res = -2; + } + } + + switch (res) + { + case 0: + { + reply->code = MIMRES_SUCCESS; + mir_snprintf(reply->message, reply->cMessage, Translate("Changed '%s' status message to '%s' (status is '%s')."), account, awayMsg, pn); + + break; + } + + case CALLSERVICE_NOTFOUND: + { + reply->code = MIMRES_FAILURE; + mir_snprintf(reply->message, reply->cMessage, Translate("'%s' doesn't seem to be a valid account."), account); + + break; + } + + case -2: + { + reply->code = MIMRES_FAILURE; + mir_snprintf(reply->message, reply->cMessage, Translate("Account '%s' does not support away messages, skipping."), account); + + break; + } + + default: + { + reply->code = MIMRES_FAILURE; + mir_snprintf(reply->message, reply->cMessage, Translate("Failed to change status message for account '%s' to '%s' (status is '%s')."), account, awayMsg, pn); + + break; + } + } + + break; + } + + default: + { + HandleWrongParametersCount(command, reply); + + break; + } + } +} + +void Set2StateReply(PReply reply, int state, int failure, char *successTrue, char *failureTrue, char *successFalse, char *failureFalse) +{ + if (state) + { + if (failure) + { + reply->code = MIMRES_FAILURE; + mir_snprintf(reply->message, reply->cMessage, Translate(failureTrue)); + } + else{ + reply->code = MIMRES_SUCCESS; + mir_snprintf(reply->message, reply->cMessage, Translate(successTrue)); + } + } + else{ + if (failure) + { + reply->code = MIMRES_FAILURE; + mir_snprintf(reply->message, reply->cMessage, Translate(failureFalse)); + } + else{ + reply->code = MIMRES_SUCCESS; + mir_snprintf(reply->message, reply->cMessage, Translate(successFalse)); + } + } +} + +void HandlePopupsCommand(PCommand command, TArgument *argv, int argc, PReply reply) +{ + switch (argc) + { + case 2: + { + int state = CallService(MS_POPUP_QUERY, PUQS_GETSTATUS, 0); + Set2StateReply(reply, state, 0, "Popups are currently enabled.", "", "Popups are currently disabled.", ""); + + break; + } + + case 3: + { + int failure; + int state = 0; + int error = 0; + + switch (Get2StateValue(argv[2])) + { + case STATE_ON: + { + failure = CallService(MS_POPUP_QUERY, PUQS_ENABLEPOPUPS, 0); + state = TRUE; + + break; + } + + case STATE_OFF: + { + failure = CallService(MS_POPUP_QUERY, PUQS_DISABLEPOPUPS, 0); + state = FALSE; + + break; + } + + case STATE_TOGGLE: + { + int state = CallService(MS_POPUP_QUERY, PUQS_GETSTATUS, 0); + failure = CallService(MS_POPUP_QUERY, (state) ? PUQS_DISABLEPOPUPS : PUQS_ENABLEPOPUPS, 0); + state = 1 - state; + + break; + } + + default: + { + HandleUnknownParameter(command, argv[2], reply); + error = 1; + + break; + } + } + if (!error) + { + Set2StateReply(reply, state, failure, "Popups were enabled successfully.", "Popups could not be enabled.", "Popups were disabled successfully.", "Popups could not be disabled."); + } + + break; + } + + default: + { + HandleWrongParametersCount(command, reply); + + break; + } + + } +} + +void HandleSoundsCommand(PCommand command, TArgument *argv, int argc, PReply reply) +{ + switch (argc) + { + case 2: + { + int state = CallService(MS_POPUP_QUERY, PUQS_GETSTATUS, 0); + Set2StateReply(reply, state, 0, "Sounds are currently enabled.", "", "Sounds are currently disabled.", ""); + + break; + } + + case 3: + { + int failure; + int state = 0; + int error = 0; + + switch (Get2StateValue(argv[2])) + { + case STATE_ON: + { + failure = 0; + DBWriteContactSettingByte(NULL, "Skin", "UseSound", 1); + state = TRUE; + + break; + } + + case STATE_OFF: + { + failure = 0; + DBWriteContactSettingByte(NULL, "Skin", "UseSound", 0); + state = FALSE; + + break; + } + + case STATE_TOGGLE: + { + state = DBGetContactSettingByte(NULL, "Skin", "UseSound", 1); + + failure = 0; + state = 1 - state; + DBWriteContactSettingByte(NULL, "Skin", "UseSound", state); + + break; + } + + default: + { + HandleUnknownParameter(command, argv[2], reply); + error = 1; + + break; + } + } + if (!error) + { + Set2StateReply(reply, state, failure, "Sounds were enabled successfully.", "Sounds could not be enabled.", "Sounds were disabled successfully.", "Sounds could not be disabled."); + } + + break; + } + + default: + { + HandleWrongParametersCount(command, reply); + + break; + } + } +} + +void HandleClistCommand(PCommand command, TArgument *argv, int argc, PReply reply) +{ + switch (argc) + { + case 2: + { + HWND hClist = (HWND) CallService(MS_CLUI_GETHWND, 0, 0); + int state = IsWindowVisible(hClist); + Set2StateReply(reply, state, 0, "Contact list is currectly shown.", "", "Contact list is currently hidden.", ""); + + break; + } + + case 3: + { + int failure; + int state = 0; + int error = 0; + HWND hClist = (HWND) CallService(MS_CLUI_GETHWND, 0, 0); + + switch (Get2StateValue(argv[2])) + { + case STATE_ON: + { + failure = 0; + ShowWindow(hClist, SW_SHOW); + + state = TRUE; + + break; + } + + case STATE_OFF: + { + failure = 0; + ShowWindow(hClist, SW_HIDE); + state = FALSE; + + break; + } + + case STATE_TOGGLE: + { + state = IsWindowVisible(hClist); + + failure = 0; + state = 1 - state; + ShowWindow(hClist, (state) ? SW_SHOW : SW_HIDE); + + break; + } + + default: + { + HandleUnknownParameter(command, argv[2], reply); + error = 1; + + break; + } + } + if (!error) + { + Set2StateReply(reply, state, failure, "Contact list was shown successfully.", "Contact list could not be shown.", "Contact list was hidden successfully.", "Contact list could not be hidden."); + } + + break; + } + + default: + { + HandleWrongParametersCount(command, reply); + + break; + } + } +} + +void HandleQuitCommand(PCommand command, TArgument *argv, int argc, PReply reply) +{ + switch (argc) + { + case 2: + { + CallService("CloseAction", 0, 0); + + //try another quit method + HWND hWndMiranda = (HWND)CallService(MS_CLUI_GETHWND, 0, 0); + PostMessage(hWndMiranda, WM_COMMAND, ID_ICQ_EXIT, 0); + + reply->code = MIMRES_SUCCESS; + mir_snprintf(reply->message, reply->cMessage, "Issued a quit command."); + + break; + } + + case 3: + { + char lower[128]; + STRNCPY(lower, argv[2], sizeof(lower)); + _strlwr(lower); + + if (strcmp(lower, "wait") == 0) + { + CallService("CloseAction", 0, 0); + + //try another quit method + HWND hWndMiranda = (HWND)CallService(MS_CLUI_GETHWND, 0, 0); + PostMessage(hWndMiranda, WM_COMMAND, ID_ICQ_EXIT, 0); + + reply->code = MIMRES_SUCCESS; + mir_snprintf(reply->message, reply->cMessage, "Issued a quit and wait command."); + + SetEvent(heServerBufferFull); + + bWaitForUnload = 1; + + while (bWaitForUnload) + { + Sleep(250); //wait for Miranda to quit. + } + } + else{ + HandleUnknownParameter(command, argv[2], reply); + } + + break; + } + + default: + { + HandleWrongParametersCount(command, reply); + + break; + } + } +} + +void HandleExchangeCommand(PCommand command, TArgument *argv, int argc, PReply reply) +{ + switch (argc) + { + case 3: + { + char lower[128]; + STRNCPY(lower, argv[2], sizeof(lower)); + _strlwr(lower); + if (strcmp(lower, "check") == 0) + { + if (ServiceExists(MS_EXCHANGE_CHECKEMAIL)) + { + CallService(MS_EXCHANGE_CHECKEMAIL, 0, 0); + + reply->code = MIMRES_SUCCESS; + mir_snprintf(reply->message, reply->cMessage, Translate("Issued check email command to Exchange plugin.")); + } + else{ + reply->code = MIMRES_FAILURE; + mir_snprintf(reply->message, reply->cMessage, Translate("Exchange plugin is not running.")); + } + } + else{ + HandleUnknownParameter(command, argv[2], reply); + } + + break; + } + + default: + { + HandleWrongParametersCount(command, reply); + + break; + } + + } +} + +void HandleYAMNCommand(PCommand command, TArgument *argv, int argc, PReply reply) +{ + switch (argc) + { + case 3: + { + char lower[128]; + STRNCPY(lower, argv[2], sizeof(lower)); + _strlwr(lower); + if (strcmp(lower, "check") == 0) + { + if (ServiceExists(MS_YAMN_FORCECHECK)) + { + CallService(MS_YAMN_FORCECHECK, 0, 0); + + reply->code = MIMRES_SUCCESS; + mir_snprintf(reply->message, reply->cMessage, Translate("Issued check email command to YAMN plugin.")); + } + else{ + reply->code = MIMRES_FAILURE; + mir_snprintf(reply->message, reply->cMessage, Translate("YAMN plugin is not running.")); + } + } + else{ + HandleUnknownParameter(command, argv[2], reply); + } + + break; + } + + default: + { + HandleWrongParametersCount(command, reply); + + break; + } + + } +} + +void HandleCallServiceCommand(PCommand command, TArgument *argv, int argc, PReply reply) +{ + switch (argc) + { + case 5: + { + char *service = argv[2]; + if (ServiceExists(service)) + { + void *wParam = NULL; + void *lParam = NULL; + INT_PTR res1 = ParseValueParam(argv[3], wParam); + INT_PTR res2 = ParseValueParam(argv[4], lParam); + if ((res1 != 0) && (res2 != 0)) + { + //very dangerous but the user asked + INT_PTR res = CallService(service, ((res1 == 1) ? *((long *) wParam) : (WPARAM) wParam), (LPARAM) ((res2 == 1) ? *((long *) lParam) : (LPARAM) lParam)); + + reply->code = MIMRES_SUCCESS; + mir_snprintf(reply->message, reply->cMessage, Translate("CallService call successful: service '%s' returned %p."), service, res); + } + else{ + reply->code = MIMRES_FAILURE; + mir_snprintf(reply->message, reply->cMessage, Translate("Invalid parameter '%s' passed to CallService command."), (wParam) ? argv[4] : argv[3]); + } + + if (wParam) { free(wParam); } + if (lParam) { free(lParam); } + + } + else{ + reply->code = MIMRES_FAILURE; + mir_snprintf(reply->message, reply->cMessage, Translate("Service '%s' does not exist."), service); + } + + break; + } + + default: + { + HandleWrongParametersCount(command, reply); + } + } +} + + +HANDLE ParseContactParam(char *contact) +{ + char name[512]; + char account[128]; + char protocol[128]; + char *p = strrchr(contact, ':'); + HANDLE hContact = NULL; + if (p) + { + *p = 0; + STRNCPY(name, contact, p - contact + 1); + STRNCPY(account, p + 1, sizeof(account)); + *p = ':'; + AccountName2Protocol(account, protocol, sizeof(protocol)); + + hContact = GetContactFromID(name, protocol); + + } + else{ + hContact = GetContactFromID(contact, (char *) NULL); + } + + return hContact; +} + +void HandleMessageCommand(PCommand command, TArgument *argv, int argc, PReply reply) +{ + if (argc >= 4) + { + char *message = argv[argc - 1]; //get the message + int i; + char *contact; + char buffer[1024]; + HANDLE hContact; + HANDLE hProcess = NULL; + ACKDATA *ack = NULL; + for (i = 2; i < argc - 1; i++) + { + contact = argv[i]; + hContact = ParseContactParam(contact); + + if (hContact) + { + bShouldProcessAcks = TRUE; + hProcess = (HANDLE) CallContactService(hContact, PSS_MESSAGE, 0, (LPARAM) message); + const int MAX_COUNT = 60; + int counter = 0; + while (((ack = GetAck(hProcess)) == NULL) && (counter < MAX_COUNT)) + { + SleepEx(250, TRUE); + counter++; + } + bShouldProcessAcks = FALSE; + + if (counter < MAX_COUNT) + { + if (ack->result == ACKRESULT_SUCCESS) + { + if (ack->szModule) + { + mir_snprintf(buffer, sizeof(buffer), Translate("Message sent to '%s'."), contact); + + DBEVENTINFO e = {0}; + char module[128]; + e.cbSize = sizeof(DBEVENTINFO); + e.eventType = EVENTTYPE_MESSAGE; + e.flags = DBEF_SENT; + + e.pBlob = (PBYTE) message; + e.cbBlob = (DWORD) strlen((char *) message) + 1; + + STRNCPY(module, ack->szModule, sizeof(module)); + e.szModule = module; + e.timestamp = (DWORD) time(NULL); + + CallService(MS_DB_EVENT_ADD, (WPARAM) ack->hContact, (LPARAM) &e); + } + else{ + mir_snprintf(buffer, sizeof(buffer), Translate("Message to '%s' was marked as sent but the account seems to be offline"), contact); + } + } + else{ + mir_snprintf(buffer, sizeof(buffer), Translate("Could not send message to '%s'."), contact); + } + } + else{ + mir_snprintf(buffer, sizeof(buffer), Translate("Timed out while waiting for acknowledgement for contact '%s'."), contact); + } + } + else{ + mir_snprintf(buffer, sizeof(buffer), Translate("Could not find contact handle for contact '%s'."), contact); + } + + if (i == 3) + { + STRNCPY(reply->message, buffer, reply->cMessage); + } + else{ + strncat(reply->message, "\n", reply->cMessage); + strncat(reply->message, buffer, reply->cMessage); + } + } + } + else{ + HandleWrongParametersCount(command, reply); + } +} + +int ParseDatabaseData(DBVARIANT *var, char *buffer, int size, int free) +{ + int ok = 1; + switch (var->type) + { + case DBVT_BYTE: + { + mir_snprintf(buffer, size, "byte:%d", var->bVal); + + break; + } + + case DBVT_WORD: + { + mir_snprintf(buffer, size, "word:%d", var->wVal); + + break; + } + + case DBVT_DWORD: + { + mir_snprintf(buffer, size, "dword:%ld", var->dVal); + + break; + } + + case DBVT_ASCIIZ: + { + mir_snprintf(buffer, size, "string:'%s'", var->pszVal); + if (free) { mir_free(var->pszVal); } + + break; + } + + case DBVT_WCHAR: + { + mir_snprintf(buffer, size, "wide string:'%S'", var->pwszVal); + if (free) { mir_free(var->pwszVal); } + + break; + } + + case DBVT_UTF8: + { + mir_snprintf(buffer, size, "utf8:'%s'", var->pszVal); + if (free) { mir_free(var->pszVal); } + } + + case DBVT_BLOB: + { + mir_snprintf(buffer, size, "blob:N/A"); + if (free) { mir_free(var->pbVal); } + + break; + } + + + default: + { + ok = 0; + mir_snprintf(buffer, size, "unknown value"); + + break; + } + } + + return ok; +} + +void HandleDatabaseCommand(PCommand command, TArgument *argv, int argc, PReply reply) +{ + if (argc >= 3) //we have something to parse + { + char dbcmd[128]; + STRNCPY(dbcmd, argv[2], sizeof(dbcmd)); + dbcmd[sizeof(dbcmd) - 1] = 0; + _strlwr(dbcmd); + if (strcmp(dbcmd, "delete") == 0) + { + if (argc == 5) + { + char *module = argv[3]; + char *key = argv[4]; + + DBDeleteContactSetting(NULL, module, key); + + reply->code = MIMRES_SUCCESS; + mir_snprintf(reply->message, reply->cMessage, Translate("Setting '%s/%s' deleted."), module, key); + } + else{ + HandleWrongParametersCount(command, reply); + } + } + else{ + if (strcmp(dbcmd, "set") == 0) + { + if (argc == 6) + { + char *module = argv[3]; + char *key = argv[4]; + + int ok = 1; + + void *value = NULL; + char *wrote = NULL; + int type = ParseValueParam(argv[5], value); + + + switch (type) + { + case VALUE_STRING: + { + DBWriteContactSettingString(NULL, module, key, (char *) value); + wrote = "string"; + + break; + } + + case VALUE_BYTE: + { + DBWriteContactSettingByte(NULL, module, key, (* (char *) value)); + wrote = "byte"; + + break; + } + + case VALUE_WORD: + { + DBWriteContactSettingWord(NULL, module, key, (* (WORD *) value)); + wrote = "word"; + + break; + } + + case VALUE_DWORD: + { + DBWriteContactSettingDword(NULL, module, key, (* (DWORD *) value)); + wrote = "dword"; + + break; + } + + case VALUE_WIDE: + { + DBWriteContactSettingWString(NULL, module, key, (WCHAR *) value); + wrote = "wide string"; + + break; + } + + default: + { + HandleUnknownParameter(command, argv[5], reply); + ok = 0; + + break; + } + } + + if (ok) + { + reply->code = MIMRES_SUCCESS; + mir_snprintf(reply->message, reply->cMessage, Translate("Wrote '%s:%s' to database entry '%s/%s'."), wrote, argv[5] + 1, module, key); + } + + if (value) + { + free(value); + } + } + else{ + HandleWrongParametersCount(command, reply); + } + } + else{ + if (strcmp(dbcmd, "get") == 0) + { + if (argc == 5) + { + char *module = argv[3]; + char *key = argv[4]; + + DBVARIANT var = {0}; + + int res = DBGetContactSetting(NULL, module, key, &var); + if (!res) + { + char buffer[1024]; + + if (ParseDatabaseData(&var, buffer, sizeof(buffer), TRUE)) + { + reply->code = MIMRES_SUCCESS; + mir_snprintf(reply->message, reply->cMessage, Translate("'%s/%s' - %s."), module, key, buffer); + } + else{ + reply->code = MIMRES_FAILURE; + mir_snprintf(reply->message, reply->cMessage, Translate("Could not retrieve setting '%s/%s': %s."), module, key, buffer); + } + } + else{ + reply->code = MIMRES_FAILURE; + mir_snprintf(reply->message, reply->cMessage, Translate("Setting '%s/%s' was not found."), module, key); + } + + } + else{ + HandleWrongParametersCount(command, reply); + } + } + else{ + HandleUnknownParameter(command, dbcmd, reply); + } + } + + } + + } + else{ + HandleWrongParametersCount(command, reply); + } +} + +int ParseProxyType(char *type) +{ + char lower[128]; + STRNCPY(lower, type, sizeof(lower)); + lower[sizeof(lower) - 1] = 0; + _strlwr(lower); + int proxy = 0; + + if (strcmp(lower, "socks4") == 0) + { + proxy = PROXY_SOCKS4; + } + else{ + if (strcmp(lower, "socks5") == 0) + { + proxy = PROXY_SOCKS5; + } + else{ + if (strcmp(lower, "http") == 0) + { + proxy = PROXY_HTTP; + } + else{ + if (strcmp(lower, "https") == 0) + { + proxy = PROXY_HTTPS; + } + } + } + } + + return proxy; +} + +char *PrettyProxyType(int type, char *buffer, int size) +{ + char *pretty = ""; + switch (type) + { + case PROXY_SOCKS4: + { + pretty = "SOCKS4"; + + break; + } + + case PROXY_SOCKS5: + { + pretty = "SOCKS5"; + + break; + } + + case PROXY_HTTP: + { + pretty = "HTTP"; + + break; + } + + case PROXY_HTTPS: + { + pretty = "HTTPS"; + + break; + } + + default: + { + pretty = "Unknown"; + + break; + } + } + + STRNCPY(buffer, pretty, size); + + return buffer; +} + +void HandleProtocolProxyCommand(PCommand command, TArgument *argv, int argc, PReply reply, char *module, char *protocol) +{ + char proxycmd[128]; + STRNCPY(proxycmd, argv[3], sizeof(proxycmd)); + proxycmd[sizeof(proxycmd) - 1] = 0; + _strlwr(proxycmd); + + char buffer[1024]; + int ok = 1; + + + if (strcmp(proxycmd, "status") == 0) + {//status command + switch (argc) + { + case 4: + { + int value = DBGetContactSettingByte(NULL, module, "NLUseProxy", 0); + + reply->code = MIMRES_SUCCESS; + mir_snprintf(buffer, sizeof(buffer), "%s proxy status is %s", protocol, (value) ? "enabled" : "disabled"); + + break; + } + + case 5: + { + int state = Get2StateValue(argv[4]); + switch (state) + { + case STATE_OFF: + { + DBWriteContactSettingByte(NULL, module, "NLUseProxy", 0); + + reply->code = MIMRES_SUCCESS; + mir_snprintf(buffer, sizeof(buffer), Translate("'%s' proxy was disabled."), protocol); + + break; + } + + case STATE_ON: + { + DBWriteContactSettingByte(NULL, module, "NLUseProxy", 1); + + reply->code = MIMRES_SUCCESS; + mir_snprintf(buffer, sizeof(buffer), Translate("'%s' proxy was enabled."), protocol); + + break; + } + + case STATE_TOGGLE: + { + int value = DBGetContactSettingByte(NULL, module, "NLUseProxy", 0); + value = 1 - value; + DBWriteContactSettingByte(NULL, module, "NLUseProxy", value); + + reply->code = MIMRES_SUCCESS; + mir_snprintf(buffer, sizeof(buffer), (value) ? Translate("'%s' proxy was enabled.") : Translate("'%s' proxy was disabled.")); + + break; + } + + default: + { + HandleUnknownParameter(command, argv[4], reply); + + break; + } + } + + break; + } + + default: + { + HandleWrongParametersCount(command, reply); + ok = 0; + + break; + } + } + } + else{ + if (strcmp(proxycmd, "server") == 0) + { + switch (argc) + { + case 4: + { + char host[256]; + int port; + char type[256]; + GetStringFromDatabase(NULL, module, "NLProxyServer", "", host, sizeof(host)); + port = DBGetContactSettingWord(NULL, module, "NLProxyPort", 0); + PrettyProxyType(DBGetContactSettingByte(NULL, module, "NLProxyType", 0), type, sizeof(type)); + + reply->code = MIMRES_SUCCESS; + mir_snprintf(buffer, sizeof(buffer), Translate("%s proxy server: %s %s:%d."), protocol, type, host, port); + + break; + } + + case 7: + { + int type = ParseProxyType(argv[4]); + char *host = argv[5]; + long port; + char *stop = NULL; + port = strtol(argv[6], &stop, 10); + + if ((*stop == 0) && (type > 0)) + { + DBWriteContactSettingString(NULL, module, "NLProxyServer", host); + DBWriteContactSettingWord(NULL, module, "NLProxyPort", port); + DBWriteContactSettingByte(NULL, module, "NLProxyType", type); + + reply->code = MIMRES_SUCCESS; + mir_snprintf(buffer, sizeof(buffer), Translate("%s proxy set to %s %s:%d."), protocol, argv[4], host, port); + } + else { + reply->code = MIMRES_FAILURE; + mir_snprintf(buffer, sizeof(buffer), Translate("%s The port or the proxy type parameter is invalid."), protocol); + } + + break; + } + + default: + { + HandleWrongParametersCount(command, reply); + ok = 0; + + break; + } + } + } + else{ + ok = 0; + HandleUnknownParameter(command, proxycmd, reply); + } + } + + + if (ok) + { + if (strlen(reply->message) > 0) + { + strncat(reply->message, "\n", reply->cMessage); + strncat(reply->message, buffer, reply->cMessage); + reply->message[reply->cMessage - 1] = 0; + } + else{ + mir_snprintf(reply->message, reply->cMessage, buffer); + } + } +} + +void HandleProxyCommand(PCommand command, TArgument *argv, int argc, PReply reply) +{ + if (argc >= 4) + { + char account[128]; + char protocol[128]; + STRNCPY(account, argv[2], sizeof(account)); + account[sizeof(account) - 1] = 0; + + AccountName2Protocol(account, protocol, sizeof(protocol)); + + int count = 0; + PROTOACCOUNT **accounts = NULL; + ProtoEnumAccounts(&count, &accounts); + + int i; + int global = (strcmp(protocol, "GLOBAL") == 0); + + reply->message[0] = 0; + + int found = 0; + if (global) + { + HandleProtocolProxyCommand(command, argv, argc, reply, "Netlib", protocol); + found = 1; + } + + char *match; + + for (i = 0; i < count; i++) + { + if (accounts[i]->bIsEnabled) + { + match = accounts[i]->szModuleName; + if ((global) || (strcmp(protocol, match) == 0)) + { + HandleProtocolProxyCommand(command, argv, argc, reply, match, match); + found = 1; + } + } + } + + if (!found) + { + reply->code = MIMRES_FAILURE; + mir_snprintf(reply->message, reply->cMessage, Translate("'%s' doesn't seem to be a valid account."), account); + } + } + else{ + HandleWrongParametersCount(command, reply); + } +} + +int ContactMatchSearch(HANDLE hContact, char *contact, char *id, char *account, TArgument *argv, int argc) +{ + int matches = 1; + int i; + + char lwrName[2048] = "\0"; + char lwrAccount[128] = "\0"; + char lwrKeyword[512] = "\0"; + char lwrID[512] = "\0"; + char *pos; + + STRNCPY(lwrName, contact, sizeof(lwrName)); + STRNCPY(lwrAccount, account, sizeof(lwrAccount)); + + if (id) { STRNCPY(lwrID, id, sizeof(lwrID)); } + + _strlwr(lwrName); + _strlwr(lwrAccount); + _strlwr(lwrID); + + for (i = 0; i < argc; i++) + { + STRNCPY(lwrKeyword, argv[i], sizeof(lwrKeyword)); + _strlwr(lwrKeyword); + + pos = strstr(lwrKeyword, "account:"); + if (pos) + { + pos += 8; + if (strstr(lwrAccount, pos) == NULL) + { + matches = 0; + + break; + } + } + else{ + pos = strstr(lwrKeyword, "status:"); + if (pos) + { + int searchStatus = ParseStatusParam(pos + 7); + char protocol[128]; + + AccountName2Protocol(account, protocol, sizeof(protocol)); + WORD contactStatus = DBGetContactSettingWord(hContact, protocol, "Status", ID_STATUS_ONLINE); + + if (searchStatus != contactStatus) + { + matches = 0; + + break; + } + } + else{ + pos = strstr(lwrKeyword, "id:"); + if (pos) + { + pos += 3; + if (strstr(lwrID, pos) == NULL) + { + matches = 0; + + break; + } + } + else{ + if ((strstr(lwrName, lwrKeyword) == NULL)) + { + matches = 0; + + break; + } + } + } + } + } + + return matches; +} + +DWORD WINAPI OpenMessageWindowThread(void *data) +{ + HANDLE hContact = (HANDLE) data; + if (hContact) + { + CallServiceSync(MS_MSG_SENDMESSAGE, (WPARAM) hContact, 0); + CallServiceSync("SRMsg/LaunchMessageWindow", (WPARAM) hContact, 0); + } + + return 0; +} + + +void HandleContactsCommand(PCommand command, TArgument *argv, int argc, PReply reply) +{ + if (argc >= 3) + { + if (_stricmp(argv[2], "list") == 0) + { + HANDLE hContact = NULL; + char buffer[1024]; + char protocol[128]; + + hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + int count = 0; + + reply->code = MIMRES_SUCCESS; + while (hContact) + { + + GetContactProtocol(hContact, protocol, sizeof(protocol)); + + char *contact = GetContactName(hContact, protocol); + char *id = GetContactID(hContact, protocol); + if (ContactMatchSearch(hContact, contact, id, protocol, &argv[3], argc - 3)) + { + mir_snprintf(buffer, sizeof(buffer), "%s:[%s]:%s (%08d)", contact, id, protocol, hContact); + if (count) + { + strncat(reply->message, "\n", reply->cMessage); + strncat(reply->message, buffer, reply->cMessage); + } + else{ + STRNCPY(reply->message, buffer, reply->cMessage); + } + + if (strlen(reply->message) > 4096) + { + SetEvent(heServerBufferFull); + Sleep(750); //wait a few milliseconds for the event to be processed + count = 0; + *reply->message = 0; + } + + count++; + } + + free(contact); + free(id); + + hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0); + } + } + else{ + if (_stricmp(argv[2], "open") == 0) + { + if (argc > 3) + { + HANDLE hContact = NULL; + char protocol[128]; + hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + + reply->code = MIMRES_SUCCESS; + *reply->message = 0; + while (hContact) + { + GetContactProtocol(hContact, protocol, sizeof(protocol)); + + char *contact = GetContactName(hContact, protocol); + char *id = GetContactID(hContact, protocol); + if (ContactMatchSearch(hContact, contact, id, protocol, &argv[3], argc - 3)) + { + DWORD threadID; + HANDLE thread = CreateThread(NULL, NULL, OpenMessageWindowThread, hContact, NULL, &threadID); + } + + free(contact); + free(id); + + hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0); + } + } + else{ + if (argc == 3) + { + HANDLE hContact = NULL; + hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + + reply->code = MIMRES_SUCCESS; + *reply->message = 0; + + while (hContact) + { + HANDLE hUnreadEvent = (HANDLE) CallService(MS_DB_EVENT_FINDFIRSTUNREAD, (WPARAM) hContact, 0); + if (hUnreadEvent != NULL) + { + DWORD threadID; + HANDLE thread = CreateThread(NULL, NULL, OpenMessageWindowThread, hContact, NULL, &threadID); + } + + hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0); + } + } + else { + HandleWrongParametersCount(command, reply); + } + } + } + else{ + HandleUnknownParameter(command, argv[2], reply); + } + } + } + else{ + HandleWrongParametersCount(command, reply); + } +} + +void AddHistoryEvent(DBEVENTINFO *dbEvent, char *contact, PReply reply) +{ + struct tm * tEvent = localtime((time_t *) &dbEvent->timestamp); + char timestamp[256]; + + strftime(timestamp, sizeof(timestamp), "%H:%M:%S %d/%b/%Y", tEvent); + + static char buffer[6144]; + char *sender = (dbEvent->flags & DBEF_SENT) ? Translate("[me]") : contact; + + char message[4096] = {0}; + STRNCPY(message, (char *) dbEvent->pBlob, sizeof(message)); + message[dbEvent->cbBlob] = message[strlen(message)] = 0; + + //if ((strlen(message) <= 0) && (dbEvent->cbBlob > 0)) + //{ + // WCHAR *tmp = (WCHAR *) dbEvent->pBlob[dbEvent->cbBlob + 1]; + // WideCharToMultiByte(CP_ACP, 0, tmp, -1, message, sizeof(message), NULL, NULL); + //} + + mir_snprintf(buffer, sizeof(buffer), "[%s] %15s: %s", timestamp, sender, message); + + + if (strlen(reply->message) > 0) + { + strncat(reply->message, "\n", reply->cMessage); + strncat(reply->message, buffer, reply->cMessage); + } + else{ + STRNCPY(reply->message, buffer, reply->cMessage); + } + + if (strlen(reply->message) > (reply->cMessage / 2)) + { + SetEvent(heServerBufferFull); + + Sleep(750); + strcpy(reply->message, "\n"); + } +} + +void HandleHistoryCommand(PCommand command, TArgument *argv, int argc, PReply reply) +{ + if (argc >= 3) + { + char *cmd = argv[2]; + switch (argc) + { + case 3: + { + if (_stricmp(cmd, "unread") == 0) + { + HANDLE hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + char buffer[4096]; + int count; + int contacts = 0; + DBEVENTINFO dbEvent = {0}; + dbEvent.cbSize = sizeof(DBEVENTINFO); + + reply->code = MIMRES_SUCCESS; + mir_snprintf(reply->message, reply->cMessage, Translate("No unread messages found.")); + + while (hContact) + { + HANDLE hEvent = (HANDLE) CallService(MS_DB_EVENT_FINDFIRSTUNREAD, (WPARAM) hContact, 0); + if (hEvent != NULL) + { + char *contact; + char protocol[128]; + + count = 0; + while (hEvent != NULL) + { + if (!CallService(MS_DB_EVENT_GET, (WPARAM) hEvent, (LPARAM) &dbEvent)) + { + if (!(dbEvent.flags & DBEF_READ)) + { + count++; + } + } + + hEvent = (HANDLE) CallService(MS_DB_EVENT_FINDNEXT, (WPARAM) hEvent, 0); + } + + GetContactProtocol(hContact, protocol, sizeof(protocol)); + contact = GetContactName(hContact, protocol); + mir_snprintf(buffer, sizeof(buffer), Translate("%s:%s - %d unread events."), contact, protocol, count); + + if (contacts > 0) + { + strncat(reply->message, "\n", reply->cMessage); + strncat(reply->message, buffer, reply->cMessage); + } + else{ + STRNCPY(reply->message, buffer, reply->cMessage); + } + contacts++; + + free(contact); + } + + hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0); + } + } + else{ + if (_stricmp(cmd, "show") == 0) + { + HandleWrongParametersCount(command, reply); + } + else{ + HandleUnknownParameter(command, cmd, reply); + } + } + + break; + } + + case 4: + { + char *contact = argv[3]; + HANDLE hContact = ParseContactParam(contact); + if (hContact) + { + if (_stricmp(cmd, "unread") == 0) + { + HANDLE hEvent = (HANDLE) CallService(MS_DB_EVENT_FINDFIRSTUNREAD, (WPARAM) hContact, 0); + DBEVENTINFO dbEvent = {0}; + dbEvent.cbSize = sizeof(DBEVENTINFO); + + char *message[4096]; + dbEvent.pBlob = (PBYTE) message; + + reply->code = MIMRES_SUCCESS; + + while (hEvent) + { + dbEvent.cbBlob = sizeof(message); + if (!CallService(MS_DB_EVENT_GET, (WPARAM) hEvent, (LPARAM) &dbEvent)) //if successful call + { + if (!(dbEvent.flags & DBEF_READ)) + { + AddHistoryEvent(&dbEvent, contact, reply); + } + } + + hEvent = (HANDLE) CallService(MS_DB_EVENT_FINDNEXT, (WPARAM) hEvent, 0); + } + } + else{ + if (_stricmp(cmd, "show") == 0) + { + int count = CallService(MS_DB_EVENT_GETCOUNT, (WPARAM) hContact, 0); + + reply->code = MIMRES_SUCCESS; + mir_snprintf(reply->message, reply->cMessage, Translate("Contact '%s' has '%d' events in history."), contact, count); + } + else{ + HandleUnknownParameter(command, cmd, reply); + } + } + } + else{ + reply->code = MIMRES_FAILURE; + mir_snprintf(reply->message, reply->cMessage, Translate("Could not find contact handle for contact '%s'."), contact); + } + + break; + } + + case 6: + { + char *contact = argv[3]; + HANDLE hContact = ParseContactParam(contact); + + if (hContact) + { + if (_stricmp(cmd, "show") == 0) + { + char *stop1 = NULL; + char *stop2 = NULL; + long start = strtol(argv[4], &stop1, 10); + long stop = strtol(argv[5], &stop2, 10); + if (!(*stop1) && !(*stop2)) + { + int size = CallService(MS_DB_EVENT_GETCOUNT, (WPARAM) hContact, 0); + if (start < 0) { start = size + start + 1; } + if (stop < 0) { stop = size + stop + 1; } + + reply->code = MIMRES_SUCCESS; + + int count = stop - start + 1; + if (count > 0) + { + int index = 0; + HANDLE hEvent = (HANDLE) CallService(MS_DB_EVENT_FINDFIRST, (WPARAM) hContact, 0); + DBEVENTINFO dbEvent = {0}; + dbEvent.cbSize = sizeof(DBEVENTINFO); + char message[4096]; + dbEvent.pBlob = (PBYTE) message; + + while (hEvent) + { + dbEvent.cbBlob = sizeof(message); + if (!CallService(MS_DB_EVENT_GET, (WPARAM) hEvent, (LPARAM) &dbEvent)) // if successful call + { + dbEvent.pBlob[dbEvent.cbBlob] = 0; + if ((index >= start) && (index <= stop)) + { + AddHistoryEvent(&dbEvent, contact, reply); + } + } + + if (index > stop) + { + break; + } + + hEvent = (HANDLE) CallService(MS_DB_EVENT_FINDNEXT, (WPARAM) hEvent, 0); + index++; + } + } + } + else{ + HandleUnknownParameter(command, (*stop1) ? argv[4] : argv[5], reply); + } + } + else{ + if (_stricmp(cmd, "unread") == 0) + { + HandleWrongParametersCount(command, reply); + } + else{ + HandleUnknownParameter(command, cmd, reply); + } + } + } + else{ + reply->code = MIMRES_FAILURE; + mir_snprintf(reply->message, reply->cMessage, Translate("Could not find contact handle for contact '%s'."), contact); + } + + break; + } + + default: + { + HandleWrongParametersCount(command, reply); + + break; + } + } + } + else{ + HandleWrongParametersCount(command, reply); + } +} + +void HandleVersionCommand(PCommand command, TArgument *argv, int argc, PReply reply) +{ + if (argc == 2) + { + reply->code = MIMRES_SUCCESS; + if (ServiceExists(MS_VERSIONINFO_GETINFO)) + { + char *data; + CallService(MS_VERSIONINFO_GETINFO, (WPARAM) FALSE, (LPARAM) &data); + mir_snprintf(reply->message, reply->cMessage, data); + mir_free(data); + } + else{ + char miranda[512]; + char cmdline[512]; + DWORD v = pluginInfo.version; + CallService(MS_SYSTEM_GETVERSIONTEXT, (WPARAM) sizeof(miranda), (LPARAM) miranda); + mir_snprintf(cmdline, sizeof(cmdline), "%d.%d.%d.%d", ((v >> 24) & 0xFF), ((v >> 16) & 0xFF), ((v >> 8) & 0xFF), (v & 0xFF)); + mir_snprintf(reply->message, reply->cMessage, "Miranda %s\nCmdLine v.%s", miranda, cmdline); + } + } + else{ + HandleWrongParametersCount(command, reply); + } +} +void HandleSetNicknameCommand(PCommand command, TArgument *argv, int argc, PReply reply) +{ + if (argc == 4) + { + char protocol[512]; + char nickname[512]; + strcpy(protocol, argv[2]); + strcpy(nickname, argv[3]); + + int res = CallProtoService(protocol, PS_SETMYNICKNAME, SMNN_TCHAR, (LPARAM) nickname); + + if (res == 0) + { + reply->code = MIMRES_SUCCESS; + *reply->message = 0; + } + else { + reply->code = MIMRES_FAILURE; + mir_snprintf(reply->message, reply->cMessage, Translate("Error setting nickname to '%s' for protocol '%s'"), nickname, protocol); + } + } + else { + HandleWrongParametersCount(command, reply); + } +} + +void HandleIgnoreCommand(PCommand command, TArgument *argv, int argc, PReply reply) +{ + if (argc >= 4) + { + BOOL block = FALSE; + BOOL goodCommand = FALSE; + if (_stricmp(argv[2], "block") == 0) + { + block = TRUE; + goodCommand = TRUE; + } + + if (_stricmp(argv[2], "unblock") == 0) + { + block = FALSE; + goodCommand = TRUE; + } + + if (!goodCommand) + { + HandleUnknownParameter(command, argv[2], reply); + + return; + } + + HANDLE hContact = NULL; + char *contact; + + for (int i = 3; i < argc; i++) + { + contact = argv[i]; + hContact = ParseContactParam(contact); + + if (hContact) + { + CallService(block ? MS_IGNORE_IGNORE : MS_IGNORE_UNIGNORE, (WPARAM) hContact, IGNOREEVENT_ALL); + } + } + + reply->code = MIMRES_SUCCESS; + *reply->message = 0; + } + else { + HandleWrongParametersCount(command, reply); + } +} \ No newline at end of file -- cgit v1.2.3