From 89c5b2369413025e1fe7dfe5c5d0bf3bedd8558d Mon Sep 17 00:00:00 2001 From: Kirill Volinsky Date: Mon, 23 Jul 2012 13:52:57 +0000 Subject: git-svn-id: http://svn.miranda-ng.org/main/trunk@1123 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- !NotAdopted/Tlen/jabber_util.c | 635 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 635 insertions(+) create mode 100644 !NotAdopted/Tlen/jabber_util.c (limited to '!NotAdopted/Tlen/jabber_util.c') diff --git a/!NotAdopted/Tlen/jabber_util.c b/!NotAdopted/Tlen/jabber_util.c new file mode 100644 index 0000000000..1caa390f10 --- /dev/null +++ b/!NotAdopted/Tlen/jabber_util.c @@ -0,0 +1,635 @@ +/* + +Jabber Protocol Plugin for Miranda IM +Tlen Protocol Plugin for Miranda IM +Copyright (C) 2002-2004 Santithorn Bunchua +Copyright (C) 2004-2007 Piotr Piastucki + +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 "jabber.h" +#include "jabber_list.h" +#include +#include + +HANDLE HookEventObj_Ex(const char *name, TlenProtocol *proto, MIRANDAHOOKOBJ hook) { + proto->hookNum ++; + proto->hHooks = (HANDLE *) mir_realloc(proto->hHooks, sizeof(HANDLE) * (proto->hookNum)); + proto->hHooks[proto->hookNum - 1] = HookEventObj(name, hook, proto); + return proto->hHooks[proto->hookNum - 1] ; +} + +HANDLE CreateServiceFunction_Ex(const char *name, TlenProtocol *proto, MIRANDASERVICEOBJ service) { + proto->serviceNum++; + proto->hServices = (HANDLE *) mir_realloc(proto->hServices, sizeof(HANDLE) * (proto->serviceNum)); + proto->hServices[proto->serviceNum - 1] = CreateServiceFunctionObj(name, service, proto); + return proto->hServices[proto->serviceNum - 1] ; +} + +void UnhookEvents_Ex(TlenProtocol *proto) { + unsigned int i; + for (i=0; ihookNum; ++i) { + if (proto->hHooks[i] != NULL) { + UnhookEvent(proto->hHooks[i]); + } + } + mir_free(proto->hHooks); + proto->hookNum = 0; + proto->hHooks = NULL; +} + +void DestroyServices_Ex(TlenProtocol *proto) { + unsigned int i; + for (i=0; iserviceNum; ++i) { + if (proto->hServices[i] != NULL) { + DestroyServiceFunction(proto->hServices[i]); + } + } + mir_free(proto->hServices); + proto->serviceNum = 0; + proto->hServices = NULL; +} + +void JabberSerialInit(TlenProtocol *proto) +{ + InitializeCriticalSection(&proto->csSerial); + proto->serial = 0; +} + +void JabberSerialUninit(TlenProtocol *proto) +{ + DeleteCriticalSection(&proto->csSerial); +} + +unsigned int JabberSerialNext(TlenProtocol *proto) +{ + unsigned int ret; + + EnterCriticalSection(&proto->csSerial); + ret = proto->serial; + proto->serial++; + LeaveCriticalSection(&proto->csSerial); + return ret; +} + +void JabberLog(TlenProtocol *proto, const char *fmt, ...) +{ +#ifdef ENABLE_LOGGING + char *str; + va_list vararg; + int strsize; + char *text; + char *p, *q; + int extra; + + va_start(vararg, fmt); + str = (char *) mir_alloc(strsize=2048); + while (_vsnprintf(str, strsize, fmt, vararg) == -1) + str = (char *) mir_realloc(str, strsize+=2048); + va_end(vararg); + + extra = 0; + for (p=str; *p!='\0'; p++) + if (*p=='\n' || *p=='\r') + extra++; + text = (char *) mir_alloc(strlen("TLEN")+2+strlen(str)+2+extra); + sprintf(text, "[%s]", "TLEN"); + for (p=str,q=text+strlen(text); *p!='\0'; p++,q++) { + if (*p == '\r') { + *q = '\\'; + *(q+1) = 'r'; + q++; + } + else if (*p == '\n') { + *q = '\\'; + *(q+1) = 'n'; + q++; + } + else + *q = *p; + } + *q = '\n'; + *(q+1) = '\0'; + if (proto->hNetlibUser!=NULL) { + CallService(MS_NETLIB_LOG, (WPARAM) proto->hNetlibUser, (LPARAM) text); + } + //OutputDebugString(text); + mir_free(text); + mir_free(str); +#endif +} + +// Caution: DO NOT use JabberSend() to send binary (non-string) data +int JabberSend(TlenProtocol *proto, const char *fmt, ...) +{ + char *str; + int size; + va_list vararg; + int result = 0; + + EnterCriticalSection(&proto->csSend); + + va_start(vararg,fmt); + size = 512; + str = (char *) mir_alloc(size); + while (_vsnprintf(str, size, fmt, vararg) == -1) { + size += 512; + str = (char *) mir_realloc(str, size); + } + va_end(vararg); + + JabberLog(proto, "SEND:%s", str); + size = (int)strlen(str); + if (proto->threadData != NULL) { + if (proto->threadData->useAES) { + result = JabberWsSendAES(proto, str, size, &proto->threadData->aes_out_context, proto->threadData->aes_out_iv); + } else { + result = JabberWsSend(proto, proto->threadData->s, str, size); + } + } + LeaveCriticalSection(&proto->csSend); + + mir_free(str); + return result; +} + + +char *JabberResourceFromJID(const char *jid) +{ + char *p; + char *nick; + + p=strchr(jid, '/'); + if (p != NULL && p[1]!='\0') { + p++; + if ((nick=(char *) mir_alloc(1+strlen(jid)-(p-jid))) != NULL) { + strncpy(nick, p, strlen(jid)-(p-jid)); + nick[strlen(jid)-(p-jid)] = '\0'; + } + } + else { + nick = mir_strdup(jid); + } + + return nick; +} + +char *JabberNickFromJID(const char *jid) +{ + char *p; + char *nick; + + if ((p=strchr(jid, '@')) == NULL) + p = strchr(jid, '/'); + if (p != NULL) { + if ((nick=(char *) mir_alloc((p-jid)+1)) != NULL) { + strncpy(nick, jid, p-jid); + nick[p-jid] = '\0'; + } + } + else { + nick = mir_strdup(jid); + } + + return nick; +} + +char *JabberLoginFromJID(const char *jid) +{ + char *p; + char *nick; + + p = strchr(jid, '/'); + if (p != NULL) { + if ((nick=(char *) mir_alloc((p-jid)+1)) != NULL) { + strncpy(nick, jid, p-jid); + nick[p-jid] = '\0'; + } + } + else { + nick = mir_strdup(jid); + } + return nick; +} + +char *JabberLocalNickFromJID(const char *jid) +{ + char *p; + char *localNick; + + p = JabberNickFromJID(jid); + localNick = JabberTextDecode(p); + mir_free(p); + return localNick; +} + +char *JabberSha1(char *str) +{ + mir_sha1_ctx sha; + DWORD digest[5]; + char* result; + + if ( str == NULL ) + return NULL; + + mir_sha1_init( &sha ); + mir_sha1_append( &sha, (mir_sha1_byte_t* )str, (int)strlen( str )); + mir_sha1_finish( &sha, (mir_sha1_byte_t* )digest ); + if ((result=(char *)mir_alloc(41)) == NULL) + return NULL; + sprintf(result, "%08x%08x%08x%08x%08x", (int)htonl(digest[0]), (int)htonl(digest[1]), (int)htonl(digest[2]), (int)htonl(digest[3]), (int)htonl(digest[4])); + return result; +} + +char *TlenSha1(char *str, int len) +{ + mir_sha1_ctx sha; + mir_sha1_byte_t digest[20]; + char* result; + int i; + + if ( str == NULL ) + return NULL; + + mir_sha1_init( &sha ); + mir_sha1_append( &sha, (mir_sha1_byte_t* )str, len); + mir_sha1_finish( &sha, digest ); + if (( result=( char* )mir_alloc( 20 )) == NULL ) + return NULL; + for (i=0; i<20; i++) + result[i]=digest[4*(i>>2)+(3-(i&0x3))]; + return result; +} + +char *TlenPasswordHash(const char *str) +{ + int magic1 = 0x50305735, magic2 = 0x12345671, sum = 7; + char *p, *res; + + if (str == NULL) return NULL; + for (p=(char *)str; *p!='\0'; p++) { + if (*p!=' ' && *p!='\t') { + magic1 ^= (((magic1 & 0x3f) + sum) * ((char) *p)) + (magic1 << 8); + magic2 += (magic2 << 8) ^ magic1; + sum += ((char) *p); + } + } + magic1 &= 0x7fffffff; + magic2 &= 0x7fffffff; + res = (char *) mir_alloc(17); + sprintf(res, "%08x%08x", magic1, magic2); + return res; +} + +char *TlenUrlEncode(const char *str) +{ + char *p, *q, *res; + unsigned char c; + + if (str == NULL) return NULL; + res = (char *) mir_alloc(3*strlen(str) + 1); + for (p=(char *)str,q=res; *p!='\0'; p++,q++) { + if (*p == ' ') { + *q = '+'; + } + else if (*p<0x20 || *p>=0x7f || strchr("%&+:'<>\"", *p)!=NULL) { + // Convert first from CP1252 to ISO8859-2 + switch ((unsigned char) *p) { + case 0xa5: c = (unsigned char) 0xa1; break; + case 0x8c: c = (unsigned char) 0xa6; break; + case 0x8f: c = (unsigned char) 0xac; break; + case 0xb9: c = (unsigned char) 0xb1; break; + case 0x9c: c = (unsigned char) 0xb6; break; + case 0x9f: c = (unsigned char) 0xbc; break; + default: c = (unsigned char) *p; break; + } + sprintf(q, "%%%02X", c); + q += 2; + } + else { + *q = *p; + } + } + *q = '\0'; + return res; +} + +void TlenUrlDecode(char *str) +{ + char *p, *q; + unsigned int code; + + if (str == NULL) return; + for (p=q=str; *p!='\0'; p++,q++) { + if (*p == '+') { + *q = ' '; + } + else if (*p=='%' && *(p+1)!='\0' && isxdigit(*(p+1)) && *(p+2)!='\0' && isxdigit(*(p+2))) { + sscanf(p+1, "%2x", &code); + *q = (char) code; + // Convert from ISO8859-2 to CP1252 + switch ((unsigned char) *q) { + case 0xa1: *q = (char) 0xa5; break; + case 0xa6: *q = (char) 0x8c; break; + case 0xac: *q = (char) 0x8f; break; + case 0xb1: *q = (char) 0xb9; break; + case 0xb6: *q = (char) 0x9c; break; + case 0xbc: *q = (char) 0x9f; break; + } + p += 2; + } + else { + *q = *p; + } + } + *q = '\0'; +} + +char * TlenGroupDecode(const char *str) +{ + char *p, *q; + if (str == NULL) return NULL; + p = q = JabberTextDecode(str); + for (; *p!='\0'; p++) { + if (*p == '/') { + *p = '\\'; + } + } + return q; +} + +char * TlenGroupEncode(const char *str) +{ + char *p, *q; + if (str == NULL) return NULL; + p = q = mir_strdup(str); + for (; *p!='\0'; p++) { + if (*p == '\\') { + *p = '/'; + } + } + p = JabberTextEncode(q); + mir_free(q); + return p; +} + +char *JabberTextEncode(const char *str) +{ + char *s1; + + if (str == NULL) return NULL; + if ((s1=TlenUrlEncode(str)) == NULL) + return NULL; + return s1; +} + +char *JabberTextDecode(const char *str) +{ + char *s1; + + if (str == NULL) return NULL; + s1 = mir_strdup(str); + TlenUrlDecode(s1); + return s1; +} + +static char b64table[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +char *JabberBase64Encode(const char *buffer, int bufferLen) +{ + int n; + unsigned char igroup[3]; + char *p, *peob; + char *res, *r; + + if (buffer==NULL || bufferLen<=0) return NULL; + if ((res=(char *) mir_alloc((((bufferLen+2)/3)*4) + 1)) == NULL) return NULL; + + for (p=(char*)buffer,peob=p+bufferLen,r=res; p= peob) break; + igroup[n] = (unsigned char) *p; + p++; + } + if (n > 0) { + r[0] = b64table[ igroup[0]>>2 ]; + r[1] = b64table[ ((igroup[0]&3)<<4) | (igroup[1]>>4) ]; + r[2] = b64table[ ((igroup[1]&0xf)<<2) | (igroup[2]>>6) ]; + r[3] = b64table[ igroup[2]&0x3f ]; + if (n < 3) { + r[3] = '='; + if (n < 2) + r[2] = '='; + } + r += 4; + } + } + *r = '\0'; + + return res; +} + +static unsigned char b64rtable[256]; + +char *JabberBase64Decode(const char *str, int *resultLen) +{ + char *res; + unsigned char *p, *r, igroup[4], a[4]; + int n, num, count; + + if (str==NULL || resultLen==NULL) return NULL; + if ((res=(char *) mir_alloc(((strlen(str)+3)/4)*3)) == NULL) return NULL; + + for (n=0; n<256; n++) + b64rtable[n] = (unsigned char) 0x80; + for (n=0; n<26; n++) + b64rtable['A'+n] = n; + for (n=0; n<26; n++) + b64rtable['a'+n] = n + 26; + for (n=0; n<10; n++) + b64rtable['0'+n] = n + 52; + b64rtable['+'] = 62; + b64rtable['/'] = 63; + b64rtable['='] = 0; + count = 0; + for (p=(unsigned char *)str,r=(unsigned char *)res; *p!='\0';) { + for (n=0; n<4; n++) { + if ( *p == '\r' || *p == '\n' ) { + n--; p++; + continue; + } + + if ( *p=='\0' ) { + if ( n == 0 ) + goto LBL_Exit; + mir_free( res ); + return NULL; + } + + if ( b64rtable[*p]==0x80 ) { + mir_free( res ); + return NULL; + } + + a[n] = *p; + igroup[n] = b64rtable[*p]; + p++; + } + r[0] = igroup[0]<<2 | igroup[1]>>4; + r[1] = igroup[1]<<4 | igroup[2]>>2; + r[2] = igroup[2]<<6 | igroup[3]; + r += 3; + num = ( a[2]=='='?1:( a[3]=='='?2:3 )); + count += num; + if ( num < 3 ) break; + } +LBL_Exit: + *resultLen = count; + return res; +} + +/* + * Apply Polish Daylight Saving Time rules to get "DST-unbiased" timestamp + */ + +time_t TlenTimeToUTC(time_t time) { + struct tm *timestamp; + timestamp = gmtime(&time); + if ( (timestamp->tm_mon > 2 && timestamp->tm_mon < 9) || + (timestamp->tm_mon == 2 && timestamp->tm_mday - timestamp->tm_wday >= 25) || + (timestamp->tm_mon == 9 && timestamp->tm_mday - timestamp->tm_wday < 25)) { + //time -= 3600; + } else { + //time += 3600; + } + return time; +} + +time_t JabberIsoToUnixTime(char *stamp) +{ + struct tm timestamp; + char date[9]; + char *p; + int i, y; + time_t t; + + if (stamp == NULL) return (time_t) 0; + + p = stamp; + + // Get the date part + for (i=0; *p!='\0' && i<8 && isdigit(*p); p++,i++) + date[i] = *p; + + // Parse year + if (i == 6) { + // 2-digit year (1970-2069) + y = (date[0]-'0')*10 + (date[1]-'0'); + if (y < 70) y += 100; + } + else if (i == 8) { + // 4-digit year + y = (date[0]-'0')*1000 + (date[1]-'0')*100 + (date[2]-'0')*10 + date[3]-'0'; + y -= 1900; + } + else + return (time_t) 0; + timestamp.tm_year = y; + // Parse month + timestamp.tm_mon = (date[i-4]-'0')*10 + date[i-3]-'0' - 1; + // Parse date + timestamp.tm_mday = (date[i-2]-'0')*10 + date[i-1]-'0'; + + // Skip any date/time delimiter + for (; *p!='\0' && !isdigit(*p); p++); + + // Parse time + if (sscanf(p, "%d:%d:%d", &(timestamp.tm_hour), &(timestamp.tm_min), &(timestamp.tm_sec)) != 3) + return (time_t) 0; + + timestamp.tm_isdst = 0; // DST is already present in _timezone below + _tzset(); + t = mktime(×tamp); + t -= _timezone; + t = TlenTimeToUTC(t); + + if (t >= 0) + return t; + else + return (time_t) 0; +} + +void JabberStringAppend(char **str, int *sizeAlloced, const char *fmt, ...) +{ + va_list vararg; + char *p; + int size, len; + + if (str == NULL) return; + + if (*str==NULL || *sizeAlloced<=0) { + *sizeAlloced = size = 2048; + *str = (char *) mir_alloc(size); + len = 0; + } + else { + len = (int)strlen(*str); + size = *sizeAlloced - (int)strlen(*str); + } + + p = *str + len; + va_start(vararg, fmt); + while (_vsnprintf(p, size, fmt, vararg) == -1) { + size += 2048; + (*sizeAlloced) += 2048; + *str = (char *) mir_realloc(*str, *sizeAlloced); + p = *str + len; + } + va_end(vararg); +} + +int JabberGetPictureType( const char* buf ) +{ + if ( buf != NULL ) { + if ( memcmp( buf, "GIF89", 5 ) == 0 ) return PA_FORMAT_GIF; + if ( memcmp( buf, "\x89PNG", 4 ) == 0 ) return PA_FORMAT_PNG; + if ( memcmp( buf, "BM", 2 ) == 0 ) return PA_FORMAT_BMP; + if ( memcmp( buf, "\xFF\xD8", 2 ) == 0 ) return PA_FORMAT_JPEG; + } + return PA_FORMAT_UNKNOWN; +} + +BOOL IsAuthorized(TlenProtocol *proto, const char *jid) +{ + JABBER_LIST_ITEM *item = JabberListGetItemPtr(proto, LIST_ROSTER, jid); + if (item != NULL) { + return item->subscription == SUB_BOTH || item->subscription == SUB_FROM; + } + return FALSE; +} + + +void TlenLogMessage(TlenProtocol *proto, HANDLE hContact, DWORD flags, const char *message) +{ + int size = (int)strlen(message) + 2; + char *localMessage = (char *)mir_alloc(size); + strcpy(localMessage, message); + localMessage[size - 1] = '\0'; + JabberDBAddEvent(proto, hContact, EVENTTYPE_MESSAGE, flags, (PBYTE)message, (DWORD)size); + mir_free(localMessage); +} -- cgit v1.2.3