summaryrefslogtreecommitdiff
path: root/plugins/Spamotron/src/utils.cpp
diff options
context:
space:
mode:
authorRozhuk Ivan <rozhuk.im@gmail.com>2014-11-29 18:29:21 +0000
committerRozhuk Ivan <rozhuk.im@gmail.com>2014-11-29 18:29:21 +0000
commit2245a46af23ba3407572d1f2d377fb240f0a3bbe (patch)
tree1d8b1fd90f4451e45d268f33248019d6686d6bab /plugins/Spamotron/src/utils.cpp
parent47ef7460d44bd169ada52ae8b1a2c7fa6f27d0d4 (diff)
Spamotron: code refactoring. Review and tests required.
git-svn-id: http://svn.miranda-ng.org/main/trunk@11153 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/Spamotron/src/utils.cpp')
-rw-r--r--plugins/Spamotron/src/utils.cpp1034
1 files changed, 514 insertions, 520 deletions
diff --git a/plugins/Spamotron/src/utils.cpp b/plugins/Spamotron/src/utils.cpp
index ce8730a7b9..2fd9dff20f 100644
--- a/plugins/Spamotron/src/utils.cpp
+++ b/plugins/Spamotron/src/utils.cpp
@@ -1,520 +1,514 @@
-#include "common.h"
-#include <locale.h>
-
-TCHAR *_tcstolower(TCHAR *dst)
-{
- unsigned int i = 0;
- setlocale(LC_ALL, "");
- if (!dst)
- return NULL;
- for (i = 0; i < _tcslen(dst); i++)
- dst[i] = _totlower(dst[i]);
- return dst;
-}
-
-TCHAR *_tcstoupper(TCHAR *dst)
-{
- unsigned int i = 0;
- setlocale(LC_ALL, "");
- if (!dst)
- return NULL;
- for (i = 0; i < _tcslen(dst); i++)
- dst[i] = _totupper(dst[i]);
- return dst;
-}
-
-BOOL _isregex(TCHAR* strSearch)
-{
- BOOL ret = FALSE;
- pcre16 *re;
- const char *error;
- int erroroffs, rc;
- TCHAR *regex;
- TCHAR regex_parse[] = _T("/(.*)/([igsm]*)");
- int ovector[9];
-
- re = pcre16_compile(regex_parse, 0, &error, &erroroffs, NULL);
- if (!re)
- return FALSE;
-
- regex = mir_tstrdup(strSearch);
- rc = pcre16_exec(re, NULL, regex, (int)lstrlen(regex), 0, 0, ovector, 9);
- if (rc == 3)
- ret = TRUE;
-
- if (re)
- pcre16_free(re);
- if (regex)
- mir_free(regex);
-
- return ret;
-}
-
-BOOL _isvalidregex(TCHAR* strSearch)
-{
- BOOL ret;
- pcre16 *re;
- const char *error;
- int erroroffs, rc;
- TCHAR *regex, *regexp, *mod;
- int opts = 0;
- TCHAR regex_parse[] = _T("/(.*)/([igsm]*)");
- int ovector[9];
-
- re = pcre16_compile(regex_parse, 0, &error, &erroroffs, NULL);
- if (!re)
- return FALSE;
-
- regex = mir_tstrdup(strSearch);
- rc = pcre16_exec(re, NULL, regex, (int)lstrlen(regex), 0, 0, ovector, 9);
- pcre16_free(re);
-
- if (rc == 3) {
- regexp = regex + ovector[2];
- regexp[ovector[3]-ovector[2]] = 0;
- mod = regex + ovector[4];
- mod[ovector[5]-ovector[4]] = 0;
-
- if (_tcsstr(mod, _T("i")))
- opts |= PCRE_CASELESS;
- if (_tcsstr(mod, _T("m")))
- opts |= PCRE_MULTILINE;
- if (_tcsstr(mod, _T("s")))
- opts |= PCRE_DOTALL;
-
- re = pcre16_compile(regexp, opts, &error, &erroroffs, NULL);
- ret = (re) ? TRUE : FALSE;
- }
-
- if (re)
- pcre16_free(re);
- if (regex)
- mir_free(regex);
-
- return ret;
-}
-
-BOOL _regmatch(TCHAR* str, TCHAR* strSearch)
-{
- BOOL ret;
- pcre16 *re;
- const char *error;
- int erroroffs, rc;
- TCHAR *regex, *regexp, *data, *mod;
- int opts = 0;
- TCHAR regex_parse[] = _T("^/(.*)/([igsm]*)");
- int ovector[9];
-
- re = pcre16_compile(regex_parse, 0, &error, &erroroffs, NULL);
- if (!re)
- return FALSE; // [TODO] and log some error
-
- regex = mir_tstrdup(strSearch);
- rc = pcre16_exec(re, NULL, regex, (int)lstrlen(regex), 0, 0, ovector, 9);
- if (rc != 3) {
- mir_free(regex);
- return FALSE; // [TODO] and log some error (better check for valid regex on options save)
- }
-
- regexp = regex + ovector[2];
- regexp[ovector[3]-ovector[2]] = 0;
- mod = regex + ovector[4];
- mod[ovector[5]-ovector[4]] = 0;
- pcre16_free(re);
-
- data = mir_tstrdup(str);
-
- if (_tcsstr(mod, _T("i")))
- opts |= PCRE_CASELESS;
- if (_tcsstr(mod, _T("m")))
- opts |= PCRE_MULTILINE;
- if (_tcsstr(mod, _T("s")))
- opts |= PCRE_DOTALL;
-
- re = pcre16_compile(regexp, opts, &error, &erroroffs, NULL);
- if (!re) {
- mir_free(regex);
- mir_free(data);
- return FALSE;
- }
-
- rc = pcre16_exec(re, NULL, data, (int)lstrlen(data), 0, 0, NULL, 0);
- if (rc < 0) {
- ret = FALSE;
- } else {
- ret = TRUE;
- }
-
- if (re)
- pcre16_free(re);
- if (regex)
- mir_free(regex);
- if (data)
- mir_free(data);
-
- return ret;
-}
-
-int get_response_id(const TCHAR* strvar)
-{
- int ret;
- pcre16 *re;
- const char *error;
- int erroroffs, rc;
- TCHAR *_str, *_strvar;
- int opts = 0;
- TCHAR regex[] = _T("^%response([#-_]([0-9]+))?%$");
- int ovector[9];
-
- re = pcre16_compile(regex, 0, &error, &erroroffs, NULL);
- if (!re)
- return FALSE; // [TODO] and log some error
-
- _strvar = mir_tstrdup(strvar);
- rc = pcre16_exec(re, NULL, _strvar, (int)lstrlen(_strvar), 0, 0, ovector, 9);
- if (rc < 0) {
- ret = -1;
- } else if (rc == 3) {
- _str = _strvar + ovector[4];
- _str[ovector[5]-ovector[4]] = 0;
- ret = _ttoi(_str);
- } else
- ret = 0;
-
- if (re)
- pcre16_free(re);
- if (_strvar)
- mir_free(_strvar);
-
- return ret;
-}
-
-int get_response_num(const TCHAR *str)
-{
- int i = 0;
- TCHAR *tmp, *strc = NULL;
- strc = (TCHAR*)malloc((_tcslen(str)+1)*sizeof(TCHAR));
- if (strc != NULL) {
- _tcscpy(strc, str);
- tmp = _tcstok(strc, L"\r\n");
- while(tmp) {
- i++;
- tmp = _tcstok(NULL, L"\r\n");
- }
- free(strc);
- }
- return i;
-}
-
-TCHAR* get_response(TCHAR *dst, unsigned int dstlen, int num)
-{
- if (num < 0)
- return dst;
- TCHAR *src = (TCHAR*)malloc(MAX_BUFFER_LENGTH * sizeof(TCHAR));
- int i = 0;
- if (src != NULL) {
- _getOptS(src, MAX_BUFFER_LENGTH, "Response", defaultResponse);
- _tcsncpy(dst, src, dstlen);
- TCHAR *tmp = _tcstok(src, L"\r\n");
- while (tmp) {
- if (i == num) {
- _tcsncpy(dst, tmp, dstlen);
- free(src);
- return dst;
- }
- i++;
- tmp = _tcstok(src, L"\r\n");
- }
- free(src);
- }
- return dst;
-}
-
-TCHAR* _tcsstr_cc(TCHAR* str, TCHAR* strSearch, BOOL cc)
-{
- if (cc)
- return _tcsstr(str, strSearch);
- else {
- TCHAR *ret;
- TCHAR *_str = (TCHAR*)malloc((_tcslen(str)+1)*sizeof(TCHAR));
- TCHAR *_strSearch = (TCHAR*)malloc((_tcslen(strSearch)+1)*sizeof(TCHAR));
- _tcscpy(_str, str);
- _tcscpy(_strSearch, strSearch);
- ret = _tcsstr(_tcstolower(_str), _tcstolower(_strSearch));
- if (ret != NULL)
- ret = (ret-_str) + str;
- free(_str);
- free(_strSearch);
- return ret;
- }
-}
-
-BOOL Contains(TCHAR* dst, TCHAR* src) // Checks for occurence of substring from src in dst
-{
- int i = 0, n = 0, value = 0;
- TCHAR *tsrc = (TCHAR *)malloc((_tcslen(src)+1)*sizeof(TCHAR));
- TCHAR *tdst = (TCHAR *)malloc((_tcslen(dst)+1)*sizeof(TCHAR));
- TCHAR **tokens = NULL;
- TCHAR *token = NULL;
- _tcscpy(tdst, dst);
- _tcscpy(tsrc, src);
- token = _tcstok(tsrc, _T(","));
- while (token) {
- tokens = (TCHAR **) realloc(tokens, (n+1)*sizeof(TCHAR *));
- tokens[n] = (TCHAR *)malloc((_tcslen(token)+1)*sizeof(TCHAR));
- while(!_tcsncmp(token, _T(" "), 1)) {++token;}
- while(_tcschr(token+_tcslen(token)-1, _T(' '))) {
- token[_tcslen(token)-1] = _T('\0');
- }
- _tcscpy(tokens[n], token);
- token = _tcstok(NULL, _T(","));
- ++n;
- }
- for (i = 0; i < n; i++) {
-
- if (_tcsstr(_tcstoupper(tdst), _tcstoupper(tokens[i]))) {
- value = 1;
- break;
- }
- }
- free(tsrc);
- if (tokens) {
- for(i = 0; i < n; i++)
- free(tokens[i]);
- free(tokens);
- }
- return value;
-}
-
-BOOL isOneDay(DWORD timestamp1, DWORD timestamp2)
-{
- time_t t1, t2;
- int at1[3], at2[3];
- struct tm *tm;
- if (!timestamp1 || !timestamp2)
- return FALSE;
- t1 = (time_t)timestamp1;
- t2 = (time_t)timestamp2;
- tm = gmtime(&t1);
- at1[0] = tm->tm_mday;
- at1[1] = tm->tm_mon;
- at1[2] = tm->tm_year;
- tm = gmtime(&t2);
- at2[0] = tm->tm_mday;
- at2[1] = tm->tm_mon;
- at2[2] = tm->tm_year;
- if (memcmp(&at1, &at2, 3*sizeof(int)) == 0)
- return TRUE;
- return FALSE;
-}
-
-TCHAR* ReplaceVar(TCHAR *dst, unsigned int len, const TCHAR *var, const TCHAR *rvar)
-{
- TCHAR *_rvar = (TCHAR*)malloc((_tcslen(rvar)+1)*sizeof(TCHAR));
- TCHAR *__rvar = NULL;
- TCHAR *var_start, *tmp = NULL;
- TCHAR *src = NULL;
- int response_id = get_response_id(var);
-
- src = (TCHAR*)malloc((_tcslen(dst)+1)*sizeof(TCHAR));
- _tcscpy(_rvar, rvar);
- __rvar = _rvar;
-/*
- if (response_id >= 0) {
- __rvar = _tcstok(_rvar, L"\r\n");
- while(response_id--) {
- __rvar = _tcstok(NULL, L"\r\n");
- }
- } else {
- __rvar = _rvar;
- }
-*/
- if (!dst)
- return NULL;
- _tcscpy(src, dst);
- var_start = _tcsstr(dst, var);
- while (var_start) {
- tmp = (TCHAR*)realloc(tmp, sizeof(TCHAR)*(_tcslen(dst) + _tcslen(__rvar) - _tcslen(var) + 1));
- _tcsncpy(tmp, dst, var_start - dst);
- tmp[var_start - dst] = 0;
- _tcscat(tmp, __rvar);
- _tcscat(tmp, var_start + _tcslen(var));
- if (len < (_tcslen(src)+1)*sizeof(TCHAR)) {
- free(tmp);
- return NULL;
- }
- _tcscpy(dst, tmp);
- var_start = _tcsstr(dst, var);
- }
- if (tmp)
- free(tmp);
- if (_rvar)
- free(_rvar);
- if (src)
- free(src);
- return dst;
-}
-
-TCHAR* ReplaceVars(TCHAR *dst, unsigned int len)
-{
- return ReplaceVarsNum(dst, len, -1);
-}
-
-TCHAR* ReplaceVarsNum(TCHAR *dst, unsigned int len, int num)
-{
- TCHAR response[2048];
- int ret, i = 1;
- pcre16 *re;
- const char *error;
- int erroroffs, rc;
- TCHAR *_str, *tmp;
- TCHAR **r;
- TCHAR *ttmp, *dstcopy;
- int opts = 0;
- TCHAR regex[] = _T("%response([#-_]([0-9]+))?%");
- int ovector[9];
-
- re = pcre16_compile(regex, 0, &error, &erroroffs, NULL);
- if (!re)
- return FALSE; // [TODO] and log some error
-
- _getOptS(response, 2048, "Response", defaultResponse);
-
- r = (TCHAR**)malloc(sizeof(char*));
- ttmp = _tcstok(response, L"\r\n");
- r[0] = ttmp;
- while(ttmp) {
- ttmp = _tcstok(NULL, L"\r\n");
- if (ttmp != NULL) {
- r = (TCHAR**)realloc(r, (i+1)*sizeof(TCHAR*));
- r[i++] = ttmp;
- }
- }
-
- do {
- _str = mir_tstrdup(dst);
- dstcopy = (TCHAR*)malloc((_tcslen(dst)+1)*sizeof(TCHAR));
- _tcscpy(dstcopy, dst);
-
- rc = pcre16_exec(re, NULL, _str, (int)lstrlen(_str), 0, 0, ovector, 9);
- if (rc < 0) {
- ret = -1;
- } else if (rc == 3) {
- ttmp = dstcopy + ovector[0];
- ttmp[ovector[1]-ovector[0]] = 0;
- tmp = _str + ovector[4];
- tmp[ovector[5]-ovector[4]] = 0;
- ret = _ttoi(tmp);
- } else {
- ttmp = dstcopy + ovector[0];
- ttmp[ovector[1]-ovector[0]] = 0;
- ret = 0;
- }
-
- if (ret >= 0) {
- if (ret > i)
- ReplaceVar(dst, len, ttmp, r[0]);
- else if (ret == 0 && num > 0 && num < i)
- ReplaceVar(dst, len, ttmp, r[num]);
- else
- ReplaceVar(dst, len, ttmp, r[ret == 0 ? 0 : ret-1]);
- }
-
- if (_str)
- mir_free(_str);
- if (dstcopy)
- free(dstcopy);
- } while (rc >= 0);
-
- if (re)
- pcre16_free(re);
-
- return dst;
-}
-
-int _notify(MCONTACT hContact, BYTE type, TCHAR *message, TCHAR *origmessage)
-{
- char *tmp, *tmporig;
- TCHAR msg[MAX_BUFFER_LENGTH];
- mir_sntprintf(msg, MAX_BUFFER_LENGTH, message, CONTACT_NAME(hContact));
-
- if (_getOptB("LogActions", defaultLogActions)) {
- tmp = mir_u2a(msg);
- tmporig = mir_u2a(origmessage);
- LogToSystemHistory(tmp, origmessage ? tmporig : NULL);
- mir_free(tmp);
- mir_free(tmporig);
- }
-
- if (_NOTIFYP) {
- if (type == POPUP_BLOCKED) {
- if (_getOptB("NotifyPopupBlocked", defaultNotifyPopupBlocked))
- ShowPopup(hContact, type, NULL, msg);
- } else if (type == POPUP_APPROVED) {
- if (_getOptB("NotifyPopupApproved", defaultNotifyPopupApproved))
- ShowPopup(hContact, type, NULL, msg);
- } else if (type == POPUP_CHALLENGE) {
- if (_getOptB("NotifyPopupChallenge", defaultNotifyPopupChallenge))
- ShowPopup(hContact, type, NULL, msg);
- } else {
- ShowPopup(hContact, type, NULL, msg);
- }
- }
- return 0;
-}
-#define DOT(a) (a[strlen(a)-1] == 46) ? "" : "."
-int LogToSystemHistory(char *message, char *origmessage)
-{
- char *msg = (char*)malloc(MAX_BUFFER_LENGTH);
- time_t tm;
- DBEVENTINFO dbei;
- dbei.cbSize = sizeof(DBEVENTINFO);
- dbei.timestamp = time(&tm);
- dbei.szModule = PLUGIN_NAME;
- if (origmessage)
- mir_snprintf(msg, MAX_BUFFER_LENGTH, "%s: %s%s %s: %s", PLUGIN_NAME, message, DOT(message), Translate("Their message was"), origmessage);
- else
- mir_snprintf(msg, MAX_BUFFER_LENGTH, "%s: %s%s", PLUGIN_NAME, message, DOT(message));
- dbei.pBlob = (PBYTE)msg;
- dbei.cbBlob = (DWORD)strlen(msg)+1;
- dbei.eventType = EVENTTYPE_MESSAGE;
- dbei.flags = DBEF_READ;
- db_event_add(NULL, &dbei);
- return 0;
-}
-
-void MarkUnread(MCONTACT hContact)
-{
- // We're not actually marking anything. We just pushing saved events to the database from a temporary location
- DBVARIANT _dbv = {0};
- PBYTE pos;
-
- if (hContact == NULL)
- return;
-
- if (db_get(hContact, PLUGIN_NAME, "LastMsgEvents", &_dbv) == 0) {
- pos = _dbv.pbVal;
- while (pos - _dbv.pbVal < _dbv.cpbVal) {
- DBEVENTINFO _dbei;
- ZeroMemory(&_dbei, sizeof(_dbei));
- _dbei.cbSize = sizeof(_dbei);
-
- memcpy(&_dbei.eventType, pos, sizeof(WORD)); pos += sizeof(WORD);
- memcpy(&_dbei.flags, pos, sizeof(DWORD)); pos += sizeof(DWORD);
- memcpy(&_dbei.timestamp, pos, sizeof(DWORD)); pos += sizeof(DWORD);
-
- _dbei.szModule = (char*)malloc(strlen((const char*)pos)+1);
- strcpy(_dbei.szModule, (const char*)pos);
- pos += strlen((const char*)pos)+1;
-
- memcpy(&_dbei.cbBlob, pos, sizeof(DWORD)); pos += sizeof(DWORD);
- _dbei.pBlob = (PBYTE)malloc(_dbei.cbBlob);
- memcpy(_dbei.pBlob, pos, _dbei.cbBlob);
- pos += _dbei.cbBlob;
-
- db_event_add(hContact,&_dbei);
- }
- db_free(&_dbv);
- db_unset(hContact, PLUGIN_NAME, "LastMsgEvents");
- }
-}
+#include "common.h"
+#include <locale.h>
+
+
+TCHAR *_tcstolower(TCHAR *dst)
+{
+ if (dst == NULL)
+ return NULL;
+ setlocale(LC_ALL, "");
+ SIZE_T dst_len = _tcslen(dst);
+ for (SIZE_T i = 0; i < dst_len; i ++)
+ dst[i] = _totlower(dst[i]);
+ return dst;
+}
+
+TCHAR *_tcstoupper(TCHAR *dst)
+{
+ if (dst == NULL)
+ return NULL;
+ setlocale(LC_ALL, "");
+ SIZE_T dst_len = _tcslen(dst);
+ for (SIZE_T i = 0; i < dst_len; i ++)
+ dst[i] = _totupper(dst[i]);
+ return dst;
+}
+
+BOOL _isregex(TCHAR* strSearch)
+{
+ BOOL ret = FALSE;
+ pcre16 *re;
+ const char *error;
+ int erroroffs, rc;
+ TCHAR *regex;
+ TCHAR regex_parse[] = _T("/(.*)/([igsm]*)");
+ int ovector[9];
+
+ if (strSearch == NULL)
+ return FALSE;
+ re = pcre16_compile(regex_parse, 0, &error, &erroroffs, NULL);
+ if (re == NULL)
+ return FALSE;
+ regex = mir_tstrdup(strSearch);
+ if (regex == NULL)
+ goto err_out;
+ rc = pcre16_exec(re, NULL, regex, _tcslen(regex), 0, 0, ovector, 9);
+ if (rc == 3)
+ ret = TRUE;
+ mir_free(regex);
+err_out:
+ pcre16_free(re);
+
+ return ret;
+}
+
+BOOL _isvalidregex(TCHAR* strSearch)
+{
+ BOOL ret = FALSE;
+ pcre16 *re;
+ const char *error;
+ int erroroffs, rc;
+ TCHAR *regex, *regexp, *mod;
+ int opts = 0;
+ TCHAR regex_parse[] = _T("/(.*)/([igsm]*)");
+ int ovector[9];
+
+ if (strSearch == NULL)
+ return FALSE;
+ re = pcre16_compile(regex_parse, 0, &error, &erroroffs, NULL);
+ if (re == NULL)
+ return FALSE;
+ regex = mir_tstrdup(strSearch);
+ if (regex == NULL) {
+ pcre16_free(re);
+ return FALSE;
+ }
+ rc = pcre16_exec(re, NULL, regex, _tcslen(regex), 0, 0, ovector, 9);
+ pcre16_free(re);
+ if (rc != 3)
+ goto err_out;
+ regexp = regex + ovector[2];
+ regexp[ovector[3] - ovector[2]] = 0;
+ mod = regex + ovector[4];
+ mod[ovector[5] - ovector[4]] = 0;
+
+ if (_tcsstr(mod, _T("i")))
+ opts |= PCRE_CASELESS;
+ if (_tcsstr(mod, _T("m")))
+ opts |= PCRE_MULTILINE;
+ if (_tcsstr(mod, _T("s")))
+ opts |= PCRE_DOTALL;
+
+ re = pcre16_compile(regexp, opts, &error, &erroroffs, NULL);
+ if (re != NULL) {
+ pcre16_free(re);
+ ret = TRUE;
+ }
+err_out:
+ mir_free(regex);
+
+ return ret;
+}
+
+BOOL _regmatch(TCHAR* str, TCHAR* strSearch)
+{
+ BOOL ret = FALSE;
+ pcre16 *re;
+ const char *error;
+ int erroroffs, rc;
+ TCHAR *regex, *regexp, *data = NULL, *mod;
+ int opts = 0;
+ TCHAR regex_parse[] = _T("^/(.*)/([igsm]*)");
+ int ovector[9];
+
+ if (str == NULL || strSearch == NULL)
+ return FALSE;
+ re = pcre16_compile(regex_parse, 0, &error, &erroroffs, NULL);
+ if (re == NULL)
+ return FALSE; // [TODO] and log some error
+ regex = mir_tstrdup(strSearch);
+ if (regex == NULL) {
+ pcre16_free(re);
+ return FALSE;
+ }
+ rc = pcre16_exec(re, NULL, regex, _tcslen(regex), 0, 0, ovector, 9);
+ pcre16_free(re);
+ if (rc != 3)
+ goto err_out; // [TODO] and log some error (better check for valid regex on options save)
+ regexp = regex + ovector[2];
+ regexp[ovector[3] - ovector[2]] = 0;
+ mod = regex + ovector[4];
+ mod[ovector[5] - ovector[4]] = 0;
+
+ data = mir_tstrdup(str);
+ if (data == NULL)
+ goto err_out;
+ if (_tcsstr(mod, _T("i")))
+ opts |= PCRE_CASELESS;
+ if (_tcsstr(mod, _T("m")))
+ opts |= PCRE_MULTILINE;
+ if (_tcsstr(mod, _T("s")))
+ opts |= PCRE_DOTALL;
+
+ re = pcre16_compile(regexp, opts, &error, &erroroffs, NULL);
+ if (re == NULL)
+ goto err_out;
+ rc = pcre16_exec(re, NULL, data, _tcslen(data), 0, 0, NULL, 0);
+ pcre16_free(re);
+ if (rc >= 0)
+ ret = TRUE;
+err_out:
+ mir_free(regex);
+ mir_free(data);
+
+ return ret;
+}
+
+int get_response_id(const TCHAR* strvar)
+{
+ int ret = 0;
+ pcre16 *re;
+ const char *error;
+ int erroroffs, rc;
+ TCHAR *_str, *_strvar;
+ int opts = 0;
+ TCHAR regex[] = _T("^%response([#-_]([0-9]+))?%$");
+ int ovector[9];
+
+ if (strvar == NULL)
+ return 0;
+ re = pcre16_compile(regex, 0, &error, &erroroffs, NULL);
+ if (re == NULL)
+ return 0; // [TODO] and log some error
+ _strvar = mir_tstrdup(strvar);
+ if (_strvar == NULL) {
+ pcre16_free(re);
+ return 0;
+ }
+ rc = pcre16_exec(re, NULL, _strvar, _tcslen(_strvar), 0, 0, ovector, 9);
+ pcre16_free(re);
+ if (rc < 0) {
+ ret = -1;
+ } else if (rc == 3) {
+ _str = _strvar + ovector[4];
+ _str[ovector[5] - ovector[4]] = 0;
+ ret = _ttoi(_str);
+ }
+ mir_free(_strvar);
+
+ return ret;
+}
+
+int get_response_num(const TCHAR *str)
+{
+ int i = 0;
+ TCHAR *tmp, *strc;
+
+ if (str == NULL)
+ return 0;
+ strc = mir_tstrdup(str);
+ if (strc == NULL)
+ return 0;
+ tmp = _tcstok(strc, _T("\r\n"));
+ while (tmp) {
+ i ++;
+ tmp = _tcstok(NULL, _T("\r\n")); /* Move next. */
+ }
+ mir_free(strc);
+
+ return i;
+}
+
+TCHAR* get_response(TCHAR* dst, unsigned int dstlen, int num)
+{
+ int i = 0;
+ TCHAR *tmp, *src;
+
+ if (dst == NULL || dstlen == 0 || num < 0)
+ return dst;
+ src = (TCHAR*)mir_alloc(MAX_BUFFER_LENGTH * sizeof(TCHAR));
+ if (src == NULL)
+ goto err_out;
+ _getOptS(src, MAX_BUFFER_LENGTH, "Response", defaultResponse);
+ tmp = _tcstok(src, _T("\r\n"));
+ while (tmp) {
+ if (i == num) {
+ _tcscpy(dst, tmp);
+ mir_free(src);
+ return dst;
+ }
+ i ++;
+ tmp = _tcstok(NULL, _T("\r\n")); /* Move next. */
+ }
+ mir_free(src);
+err_out:
+ dst[0] = 0;
+ return dst;
+}
+
+TCHAR* _tcsstr_cc(TCHAR* str, TCHAR* strSearch, BOOL cc)
+{
+ TCHAR *ret = NULL, *_str = NULL, *_strSearch = NULL;
+
+ if (cc)
+ return _tcsstr(str, strSearch);
+
+ _str = mir_tstrdup(str);
+ if (_str == NULL)
+ goto err_out;
+ _strSearch = mir_tstrdup(strSearch);
+ if (_strSearch == NULL)
+ goto err_out;
+ ret = _tcsstr(_tcstolower(_str), _tcstolower(_strSearch));
+ if (ret != NULL)
+ ret = ((ret - _str) + str);
+err_out:
+ mir_free(_str);
+ mir_free(_strSearch);
+
+ return ret;
+}
+
+BOOL Contains(TCHAR* dst, TCHAR* src) // Checks for occurence of substring from src in dst
+{
+ BOOL ret = FALSE;
+ TCHAR *tsrc = NULL, *tdst = NULL, *token, *token_end;
+ SIZE_T dst_len;
+
+ if (dst == NULL || src == NULL)
+ return FALSE;
+ tsrc = mir_tstrdup(src);
+ if (tsrc == NULL)
+ goto err_out;
+ tdst = mir_tstrdup(dst);
+ if (tdst == NULL)
+ goto err_out;
+ tdst = _tcstoupper(tdst);
+ dst_len = _tcslen(tdst);
+ token = _tcstok(tsrc, _T(","));
+ while (token) {
+ token_end = (token + _tcslen(token));
+ while (!_tcsncmp(token, _T(" "), 1)) { /* Skeep spaces at start. */
+ token ++;
+ }
+ /* Skeep spaces at end. */
+ while (token > token_end && _tcschr((token_end - 1), _T(' '))) {
+ token_end --;
+ token_end[0] = 0;
+ }
+ /* Compare. */
+ if (dst_len == (token_end - token) &&
+ 0 == memcmp(tdst, _tcstoupper(token), (dst_len * sizeof(TCHAR)))) {
+ ret = TRUE;
+ break;
+ }
+ token = _tcstok(NULL, _T(",")); /* Move next. */
+ }
+err_out:
+ mir_free(tsrc);
+ mir_free(tdst);
+ return ret;
+}
+
+BOOL isOneDay(DWORD timestamp1, DWORD timestamp2)
+{
+ time_t t1, t2;
+ int at1[3], at2[3];
+ struct tm *tm;
+ if (!timestamp1 || !timestamp2)
+ return FALSE;
+ t1 = (time_t)timestamp1;
+ t2 = (time_t)timestamp2;
+ tm = gmtime(&t1);
+ at1[0] = tm->tm_mday;
+ at1[1] = tm->tm_mon;
+ at1[2] = tm->tm_year;
+ tm = gmtime(&t2);
+ at2[0] = tm->tm_mday;
+ at2[1] = tm->tm_mon;
+ at2[2] = tm->tm_year;
+ if (memcmp(&at1, &at2, 3*sizeof(int)) == 0)
+ return TRUE;
+ return FALSE;
+}
+
+TCHAR* ReplaceVar(TCHAR *dst, unsigned int len, const TCHAR *var, const TCHAR *rvar)
+{
+ TCHAR *var_start;
+ SIZE_T dst_len, var_len, rvar_len;
+
+ if (dst == NULL || var == NULL || rvar == NULL)
+ return NULL;
+ dst_len = _tcslen(dst);
+ var_len = _tcslen(var);
+ rvar_len = _tcslen(rvar);
+ var_start = _tcsstr(dst, var);
+ while (var_start) {
+ if (len < (dst_len + rvar_len - var_len + 1))
+ return NULL; /* Out of buf space. */
+ memmove((var_start + rvar_len),
+ (var_start + var_len),
+ (((dst + dst_len + 1) - (var_start + var_len)) * sizeof(TCHAR)));
+ if (var_len >= rvar_len) { /* Buf data size not changed or decreased. */
+ dst_len -= (var_len - rvar_len);
+ } else { /* Buf data size increased. */
+ dst_len += (rvar_len - var_len);
+ }
+ memcpy(var_start, rvar, (rvar_len * sizeof(TCHAR)));
+ var_start = _tcsstr(dst, var); /* Move next. */
+ }
+
+ return dst;
+}
+
+TCHAR* ReplaceVars(TCHAR *dst, unsigned int len)
+{
+ return ReplaceVarsNum(dst, len, -1);
+}
+
+TCHAR* ReplaceVarsNum(TCHAR *dst, unsigned int len, int num)
+{
+ TCHAR response[MAX_BUFFER_LENGTH];
+ int ret, i;
+ pcre16 *re;
+ const char *error;
+ int erroroffs, rc;
+ TCHAR *_str, *tmp, **r = NULL, **tr, *ttmp, *dstcopy;
+ TCHAR regex[] = _T("%response([#-_]([0-9]+))?%");
+ int ovector[9];
+
+ re = pcre16_compile(regex, 0, &error, &erroroffs, NULL);
+ if (re == NULL)
+ return FALSE; // [TODO] and log some error
+ _getOptS(response, SIZEOF(response), "Response", defaultResponse);
+
+ ttmp = _tcstok(response, _T("\r\n"));
+ for (i = 0; ttmp != NULL; i ++) {
+ tr = (TCHAR**)mir_realloc(r, ((i + 1) * sizeof(TCHAR*)));
+ if (tr == NULL)
+ goto err_out;
+ r = tr;
+ r[i] = ttmp;
+ ttmp = _tcstok(NULL, _T("\r\n")); /* Move next. */
+ }
+
+ do {
+ _str = mir_tstrdup(dst);
+ dstcopy = mir_tstrdup(dst);
+ if (_str == NULL || dstcopy == NULL) {
+ mir_free(_str);
+ mir_free(dstcopy);
+ goto err_out;
+ }
+ rc = pcre16_exec(re, NULL, _str, _tcslen(_str), 0, 0, ovector, 9);
+ if (rc < 0) {
+ ret = -1;
+ } else if (rc == 3) {
+ ttmp = dstcopy + ovector[0];
+ ttmp[ovector[1] - ovector[0]] = 0;
+ tmp = _str + ovector[4];
+ tmp[ovector[5] - ovector[4]] = 0;
+ ret = _ttoi(tmp);
+ } else {
+ ttmp = dstcopy + ovector[0];
+ ttmp[ovector[1] - ovector[0]] = 0;
+ ret = 0;
+ }
+
+ if (ret >= 0) {
+ if (ret > i)
+ ReplaceVar(dst, len, ttmp, r[0]);
+ else if (ret == 0 && num > 0 && num < i)
+ ReplaceVar(dst, len, ttmp, r[num]);
+ else
+ ReplaceVar(dst, len, ttmp, r[ret == 0 ? 0 : (ret - 1)]);
+ }
+
+ mir_free(_str);
+ mir_free(dstcopy);
+ } while (rc >= 0);
+err_out:
+ mir_free(r);
+ pcre16_free(re);
+
+ return dst;
+}
+
+int _notify(MCONTACT hContact, BYTE type, TCHAR *message, TCHAR *origmessage)
+{
+ char *tmp, *tmporig;
+ TCHAR msg[MAX_BUFFER_LENGTH];
+ mir_sntprintf(msg, MAX_BUFFER_LENGTH, message, CONTACT_NAME(hContact));
+
+ if (_getOptB("LogActions", defaultLogActions)) {
+ tmp = mir_u2a(msg);
+ tmporig = mir_u2a(origmessage);
+ LogToSystemHistory(tmp, origmessage ? tmporig : NULL);
+ mir_free(tmp);
+ mir_free(tmporig);
+ }
+
+ if (_NOTIFYP) {
+ if (type == POPUP_BLOCKED) {
+ if (_getOptB("NotifyPopupBlocked", defaultNotifyPopupBlocked))
+ ShowPopup(hContact, type, NULL, msg);
+ } else if (type == POPUP_APPROVED) {
+ if (_getOptB("NotifyPopupApproved", defaultNotifyPopupApproved))
+ ShowPopup(hContact, type, NULL, msg);
+ } else if (type == POPUP_CHALLENGE) {
+ if (_getOptB("NotifyPopupChallenge", defaultNotifyPopupChallenge))
+ ShowPopup(hContact, type, NULL, msg);
+ } else {
+ ShowPopup(hContact, type, NULL, msg);
+ }
+ }
+ return 0;
+}
+#define DOT(a) (a[strlen(a)-1] == 46) ? "" : "."
+int LogToSystemHistory(char *message, char *origmessage)
+{
+ char msg[MAX_BUFFER_LENGTH];
+ time_t tm;
+ DBEVENTINFO dbei;
+
+ if (message == NULL)
+ return 0;
+ dbei.cbSize = sizeof(DBEVENTINFO);
+ dbei.timestamp = time(&tm);
+ dbei.szModule = PLUGIN_NAME;
+ dbei.pBlob = (PBYTE)msg;
+ if (origmessage)
+ dbei.cbBlob = (1 + mir_snprintf(msg, MAX_BUFFER_LENGTH, "%s: %s%s %s: %s", PLUGIN_NAME, message, DOT(message), Translate("Their message was"), origmessage));
+ else
+ dbei.cbBlob = (1 + mir_snprintf(msg, MAX_BUFFER_LENGTH, "%s: %s%s", PLUGIN_NAME, message, DOT(message)));
+ dbei.eventType = EVENTTYPE_MESSAGE;
+ dbei.flags = DBEF_READ;
+ db_event_add(NULL, &dbei);
+ return 0;
+}
+
+void MarkUnread(MCONTACT hContact)
+{
+ // We're not actually marking anything. We just pushing saved events to the database from a temporary location
+ DBVARIANT _dbv = {0};
+ PBYTE pos;
+
+ if (hContact == NULL)
+ return;
+
+ if (db_get(hContact, PLUGIN_NAME, "LastMsgEvents", &_dbv) == 0) {
+ pos = _dbv.pbVal;
+ while (pos - _dbv.pbVal < _dbv.cpbVal) {
+ DBEVENTINFO _dbei;
+ ZeroMemory(&_dbei, sizeof(_dbei));
+ _dbei.cbSize = sizeof(_dbei);
+
+ memcpy(&_dbei.eventType, pos, sizeof(WORD)); pos += sizeof(WORD);
+ memcpy(&_dbei.flags, pos, sizeof(DWORD)); pos += sizeof(DWORD);
+ memcpy(&_dbei.timestamp, pos, sizeof(DWORD)); pos += sizeof(DWORD);
+
+ _dbei.szModule = (char*)malloc(strlen((const char*)pos)+1);
+ strcpy(_dbei.szModule, (const char*)pos);
+ pos += strlen((const char*)pos)+1;
+
+ memcpy(&_dbei.cbBlob, pos, sizeof(DWORD)); pos += sizeof(DWORD);
+ _dbei.pBlob = (PBYTE)malloc(_dbei.cbBlob);
+ memcpy(_dbei.pBlob, pos, _dbei.cbBlob);
+ pos += _dbei.cbBlob;
+
+ db_event_add(hContact,&_dbei);
+ }
+ db_free(&_dbv);
+ db_unset(hContact, PLUGIN_NAME, "LastMsgEvents");
+ }
+}