diff options
Diffstat (limited to 'plugins/CmdLine/src/mimcmd_handlers.cpp')
-rw-r--r-- | plugins/CmdLine/src/mimcmd_handlers.cpp | 2307 |
1 files changed, 2307 insertions, 0 deletions
diff --git a/plugins/CmdLine/src/mimcmd_handlers.cpp b/plugins/CmdLine/src/mimcmd_handlers.cpp new file mode 100644 index 0000000000..9b2d89b696 --- /dev/null +++ b/plugins/CmdLine/src/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", "<unknown>", 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 |