// ---------------------------------------------------------------------------80
// ICQ plugin for Miranda Instant Messenger
// ________________________________________
//
// Copyright © 2000,2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
// Copyright © 2001,2002 Jon Keating, Richard Hughes
// Copyright © 2002,2003,2004 Martin Öberg, Sam Kothari, Robert Rainwater
// Copyright © 2004,2005,2006 Joe Kucera
//
// 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.
//
// -----------------------------------------------------------------------------
//
// File name : $Source: /cvsroot/miranda/miranda/protocols/IcqOscarJ/icq_xtraz.c,v $
// Revision : $Revision: 2874 $
// Last change on : $Date: 2006-05-16 23:38:00 +0200 (út, 16 V 2006) $
// Last change by : $Author: ghazan $
//
// DESCRIPTION:
//
// Internal Xtraz API
//
// -----------------------------------------------------------------------------
#include "icqoscar.h"
extern HANDLE hsmsgrequest;
void handleXtrazNotify(DWORD dwUin, DWORD dwMID, DWORD dwMID2, WORD wCookie, char* szMsg, int nMsgLen, BOOL bThruDC)
{
char *szWork, *szEnd, *szNotify, *szQuery;
int nNotifyLen, nQueryLen;
HANDLE hContact;
szNotify = strstr(szMsg, "");
szQuery = strstr(szMsg, "");
hContact = HContactFromUIN(dwUin, NULL);
if (hContact) // user sent us xtraz, he supports it
SetContactCapabilities(hContact, CAPF_XTRAZ);
if (szNotify && szQuery)
{ // valid request
szNotify += 8;
szQuery += 7;
szEnd = strstr(szMsg, "");
if (!szEnd) szEnd = szMsg + nMsgLen;
nNotifyLen = (szEnd - szNotify);
szEnd = strstr(szMsg, "");
if (!szEnd) szEnd = szNotify;
szNotify = DemangleXml(szNotify, nNotifyLen);
nQueryLen = (szEnd - szQuery);
szQuery = DemangleXml(szQuery, nQueryLen);
szWork = strstr(szQuery, "");
szEnd = strstr(szQuery, "");
#ifdef _DEBUG
NetLog_Server("Query: %s", szQuery);
NetLog_Server("Notify: %s", szNotify);
#endif
if (szWork && szEnd)
{ // this is our plugin
szWork += 10;
*szEnd = '\0';
if (!stricmp(szWork, "srvMng") && strstr(szNotify, "AwayStat"))
{
char* szSender = strstr(szNotify, "");
char* szEndSend = strstr(szNotify, "");
if (szSender && szEndSend)
{
szSender += 10;
*szEndSend = '\0';
if ((DWORD)atoi(szSender) == dwUin)
{
char *szResponse;
int nResponseLen;
char *szXName, *szXMsg;
BYTE dwXId = ICQGetContactSettingByte(NULL, DBSETTING_XSTATUSID, 0);
if (dwXId && validateStatusMessageRequest(hContact, MTYPE_SCRIPT_NOTIFY))
{ // apply privacy rules
NotifyEventHooks(hsmsgrequest, (WPARAM)MTYPE_SCRIPT_NOTIFY, (LPARAM)dwUin);
szXName = ICQGetContactSettingUtf(NULL, DBSETTING_XSTATUSNAME, "");
szXMsg = ICQGetContactSettingUtf(NULL, DBSETTING_XSTATUSMSG, "");
nResponseLen = 212 + strlennull(szXName) + strlennull(szXMsg) + UINMAXLEN + 2;
szResponse = (char*)_alloca(nResponseLen + 1);
// send response
nResponseLen = null_snprintf(szResponse, nResponseLen,
""
"cAwaySrv"
""
""
"%d"
"%d"
"%s"
"%s",
dwLocalUIN, dwXId, szXName, szXMsg);
SAFE_FREE(&szXName);
SAFE_FREE(&szXMsg);
if (gbXStatusEnabled)
{
rate_record rr = {0};
rr.bType = RIT_XSTATUS_RESPONSE;
rr.dwUin = dwUin;
rr.dwMid1 = dwMID;
rr.dwMid2 = dwMID2;
rr.wCookie = wCookie;
rr.szData = szResponse;
rr.bThruDC = bThruDC;
rr.rate_group = 0x102;
if (bThruDC || !handleRateItem(&rr, TRUE))
SendXtrazNotifyResponse(dwUin, dwMID, dwMID2, wCookie, szResponse, nResponseLen, bThruDC);
}
else
NetLog_Server("Error: XStatus Disabled");
}
else if (dwXId)
NetLog_Server("Privacy: Ignoring XStatus request");
else
NetLog_Server("Error: We are not in XStatus, skipping");
}
else
NetLog_Server("Error: Invalid sender information");
}
else
NetLog_Server("Error: Missing sender information");
}
else
NetLog_Server("Error: Unknown plugin \"%s\" in Xtraz message", szWork);
}
else
NetLog_Server("Error: Missing PluginID in Xtraz message");
SAFE_FREE(&szNotify);
SAFE_FREE(&szQuery);
}
else
NetLog_Server("Error: Invalid Xtraz Notify message");
}
void handleXtrazNotifyResponse(DWORD dwUin, HANDLE hContact, WORD wCookie, char* szMsg, int nMsgLen)
{
char *szMem, *szRes, *szEnd;
int nResLen;
#ifdef _DEBUG
NetLog_Server("Received Xtraz Notify Response");
#endif
szRes = strstr(szMsg, "");
szEnd = strstr(szMsg, "");
if (szRes && szEnd)
{ // valid response
char *szNode, *szWork;
szRes += 5;
nResLen = szEnd - szRes;
szMem = szRes = DemangleXml(szRes, nResLen);
#ifdef _DEBUG
NetLog_Server("Response: %s", szRes);
#endif
ICQBroadcastAck(hContact, ICQACKTYPE_XTRAZNOTIFY_RESPONSE, ACKRESULT_SUCCESS, (HANDLE)wCookie, (LPARAM)szRes);
NextVal:
szNode = strstr(szRes, "");
szEnd = strstr(szWork, "");
if (szNode && szEnd)
{
szNode += 5;
*szEnd = '\0';
if ((DWORD)atoi(szNode) == dwUin)
{
*szEnd = ' ';
szNode = strstr(szWork, "");
szEnd = strstr(szWork, "");
if (szNode && szEnd)
{
szNode += 7;
*szEnd = '\0';
if (atoi(szNode) != ICQGetContactSettingByte(hContact, DBSETTING_XSTATUSID, 0))
{ // this is strange - but go on
NetLog_Server("Warning: XStatusIds do not match!");
}
*szEnd = ' ';
}
szNode = strstr(szWork, "");
szEnd = strstr(szWork, "");
if (szNode && szEnd)
{ // we got XStatus title, save it
szNode += 7;
*szEnd = '\0';
ICQWriteContactSettingUtf(hContact, DBSETTING_XSTATUSNAME, szNode);
*szEnd = ' ';
}
szNode = strstr(szWork, "");
szEnd = strstr(szWork, "");
if (szNode && szEnd)
{ // we got XStatus mode msg, save it
szNode += 6;
*szEnd = '\0';
ICQWriteContactSettingUtf(hContact, DBSETTING_XSTATUSMSG, szNode);
}
ICQBroadcastAck(hContact, ICQACKTYPE_XSTATUS_RESPONSE, ACKRESULT_SUCCESS, (HANDLE)wCookie, 0);
}
else
NetLog_Server("Error: Invalid sender information");
}
else
NetLog_Server("Error: Missing sender information");
}
else
{
char *szSrvEnd = strstr(szEnd, "");
if (szSrvEnd && strstr(szSrvEnd, "%s%s", szQueryBody, szNotifyBody);
SAFE_FREE(&szQueryBody);
SAFE_FREE(&szNotifyBody);
// Set up the ack type
pCookieData = CreateMessageCookie(MTYPE_SCRIPT_NOTIFY, ACKTYPE_CLIENT);
dwCookie = AllocateCookie(CKT_MESSAGE, 0, dwUin, (void*)pCookieData);
// have we a open DC, send through that
if (gbDCMsgEnabled && IsDirectConnectionOpen(hContact, DIRECTCONN_STANDARD))
icq_sendXtrazRequestDirect(dwUin, hContact, dwCookie, szBody, nBodyLen, MTYPE_SCRIPT_NOTIFY);
else
icq_sendXtrazRequestServ(dwUin, dwCookie, szBody, nBodyLen, pCookieData);
return dwCookie;
}
void SendXtrazNotifyResponse(DWORD dwUin, DWORD dwMID, DWORD dwMID2, WORD wCookie, char* szResponse, int nResponseLen, BOOL bThruDC)
{
char *szResBody = MangleXml(szResponse, nResponseLen);
int nBodyLen = strlennull(szResBody) + 21;
char *szBody = (char*)_alloca(nBodyLen);
HANDLE hContact = HContactFromUIN(dwUin, NULL);
if (hContact != INVALID_HANDLE_VALUE && !CheckContactCapabilities(hContact, CAPF_XTRAZ))
{
SAFE_FREE(&szResBody);
return; // Contact does not support xtraz, do not send anything
}
nBodyLen = null_snprintf(szBody, nBodyLen, "%s", szResBody);
SAFE_FREE(&szResBody);
// Was request received thru DC and have we a open DC, send through that
if (bThruDC && IsDirectConnectionOpen(hContact, DIRECTCONN_STANDARD))
icq_sendXtrazResponseDirect(dwUin, hContact, wCookie, szBody, nBodyLen, MTYPE_SCRIPT_NOTIFY);
else
icq_sendXtrazResponseServ(dwUin, dwMID, dwMID2, wCookie, szBody, nBodyLen, MTYPE_SCRIPT_NOTIFY);
}