summaryrefslogtreecommitdiff
path: root/miranda-wine/protocols/IcqOscarJ/chan_02data.c
diff options
context:
space:
mode:
Diffstat (limited to 'miranda-wine/protocols/IcqOscarJ/chan_02data.c')
-rw-r--r--miranda-wine/protocols/IcqOscarJ/chan_02data.c216
1 files changed, 216 insertions, 0 deletions
diff --git a/miranda-wine/protocols/IcqOscarJ/chan_02data.c b/miranda-wine/protocols/IcqOscarJ/chan_02data.c
new file mode 100644
index 0000000..ee10bff
--- /dev/null
+++ b/miranda-wine/protocols/IcqOscarJ/chan_02data.c
@@ -0,0 +1,216 @@
+// ---------------------------------------------------------------------------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/chan_02data.c,v $
+// Revision : $Revision: 2874 $
+// Last change on : $Date: 2006-05-17 01:38:00 +0400 (Срд, 17 Май 2006) $
+// Last change by : $Author: ghazan $
+//
+// DESCRIPTION:
+//
+// Handle channel 2 (Data) packets
+//
+// -----------------------------------------------------------------------------
+
+#include "icqoscar.h"
+
+
+void handleDataChannel(unsigned char *pBuffer, WORD wBufferLength, serverthread_info *info)
+{
+ snac_header snacHeader = {0};
+
+
+ if (!unpackSnacHeader(&snacHeader, &pBuffer, &wBufferLength) || !snacHeader.bValid)
+ {
+ NetLog_Server("Error: Failed to parse SNAC header");
+ }
+ else
+ {
+#ifdef _DEBUG
+ NetLog_Server(" Received SNAC(x%02X,x%02X)", snacHeader.wFamily, snacHeader.wSubtype);
+#endif
+
+ switch (snacHeader.wFamily)
+ {
+
+ case ICQ_SERVICE_FAMILY:
+ handleServiceFam(pBuffer, wBufferLength, &snacHeader, info);
+ break;
+
+ case ICQ_LOCATION_FAMILY:
+ handleLocationFam(pBuffer, wBufferLength, &snacHeader);
+ break;
+
+ case ICQ_BUDDY_FAMILY:
+ handleBuddyFam(pBuffer, wBufferLength, &snacHeader);
+ break;
+
+ case ICQ_MSG_FAMILY:
+ handleMsgFam(pBuffer, wBufferLength, &snacHeader);
+ break;
+
+ case ICQ_BOS_FAMILY:
+ handleBosFam(pBuffer, wBufferLength, &snacHeader);
+ break;
+
+ case ICQ_LOOKUP_FAMILY:
+ handleLookupFam(pBuffer, wBufferLength, &snacHeader);
+ break;
+
+ case ICQ_STATS_FAMILY:
+ handleStatusFam(pBuffer, wBufferLength, &snacHeader);
+ break;
+
+ case ICQ_LISTS_FAMILY:
+ handleServClistFam(pBuffer, wBufferLength, &snacHeader, info);
+ break;
+
+ case ICQ_EXTENSIONS_FAMILY:
+ handleIcqExtensionsFam(pBuffer, wBufferLength, &snacHeader);
+ break;
+
+ case ICQ_AUTHORIZATION_FAMILY:
+ handleAuthorizationFam(pBuffer, wBufferLength, &snacHeader, info);
+ break;
+
+ default:
+ NetLog_Server("Ignoring SNAC(x%02X,x%02X) - FAMILYx%02X not implemented", snacHeader.wFamily, snacHeader.wSubtype, snacHeader.wFamily);
+ break;
+
+ }
+ }
+}
+
+
+
+int unpackSnacHeader(snac_header* pSnacHeader, unsigned char **pBuffer, WORD* pwBufferLength)
+{
+ WORD wRef1, wRef2;
+
+ // Check header
+ if (!pSnacHeader) return 0;
+
+ // 10 bytes is the minimum size of a header
+ if (*pwBufferLength < 10)
+ {
+ // Buffer overflow
+ pSnacHeader->bValid = FALSE;
+ return 1;
+ }
+
+ // Unpack all the standard data
+ unpackWord(pBuffer, &(pSnacHeader->wFamily));
+ unpackWord(pBuffer, &(pSnacHeader->wSubtype));
+ unpackWord(pBuffer, &(pSnacHeader->wFlags));
+ unpackWord(pBuffer, &wRef1); // unpack reference id (sequence)
+ unpackWord(pBuffer, &wRef2); // command
+ pSnacHeader->dwRef = wRef1 | (wRef2<<0x10);
+
+ *pwBufferLength -= 10;
+
+ // If flag bit 15 is set, we also have a version tag
+ // (...at least that is what I think it is)
+ if (pSnacHeader->wFlags & 0x8000)
+ {
+ if (*pwBufferLength >= 2)
+ {
+ WORD wExtraBytes = 0;
+
+ unpackWord(pBuffer, &wExtraBytes);
+ *pwBufferLength -= 2;
+
+ if (*pwBufferLength >= wExtraBytes)
+ {
+ if (wExtraBytes == 6)
+ {
+ *pBuffer += 4; // TLV type and length?
+ unpackWord(pBuffer, &(pSnacHeader->wVersion));
+ *pwBufferLength -= 6;
+ pSnacHeader->bValid = TRUE;
+ }
+ else
+ {
+ *pwBufferLength -= wExtraBytes;
+ *pBuffer += wExtraBytes;
+ pSnacHeader->bValid = TRUE;
+ }
+ }
+ else
+ {
+ // Buffer overflow
+ pSnacHeader->bValid = FALSE;
+ }
+ }
+ else
+ {
+ // Buffer overflow
+ pSnacHeader->bValid = FALSE;
+ }
+ }
+ else
+ {
+ pSnacHeader->bValid = TRUE;
+ }
+
+ return 1;
+}
+
+
+
+void LogFamilyError(WORD wFamily, WORD wError)
+{
+ char *msg;
+
+ switch(wError)
+ {
+ case 0x01: msg = "Invalid SNAC header"; break;
+ case 0x02: msg = "Server rate limit exceeded"; break;
+ case 0x03: msg = "Client rate limit exceeded"; break;
+ case 0x04: msg = "Recipient is not logged in"; break;
+ case 0x05: msg = "Requested service unavailable"; break;
+ case 0x06: msg = "Requested service not defined"; break;
+ case 0x07: msg = "You sent obsolete SNAC"; break;
+ case 0x08: msg = "Not supported by server"; break;
+ case 0x09: msg = "Not supported by client"; break;
+ case 0x0A: msg = "Refused by client"; break;
+ case 0x0B: msg = "Reply too big"; break;
+ case 0x0C: msg = "Responses lost"; break;
+ case 0x0D: msg = "Request denied"; break;
+ case 0x0E: msg = "Incorrect SNAC format"; break;
+ case 0x0F: msg = "Insufficient rights"; break;
+ case 0x10: msg = "In local permit/deny (recipient blocked)"; break;
+ case 0x11: msg = "Sender too evil"; break;
+ case 0x12: msg = "Receiver too evil"; break;
+ case 0x13: msg = "User temporarily unavailable"; break;
+ case 0x14: msg = "No match"; break;
+ case 0x15: msg = "List overflow"; break;
+ case 0x16: msg = "Request ambiguous"; break;
+ case 0x17: msg = "Server queue full"; break;
+ case 0x18: msg = "Not while on AOL"; break;
+ default: msg = ""; break;
+ }
+
+ NetLog_Server("SNAC(x%02X,x01) - Error(%u): %s", wFamily, wError, msg);
+}