summaryrefslogtreecommitdiff
path: root/plugins/!NotAdopted/IMO2sProxy/src/imolib
diff options
context:
space:
mode:
authorVadim Dashevskiy <watcherhd@gmail.com>2012-07-28 19:25:08 +0000
committerVadim Dashevskiy <watcherhd@gmail.com>2012-07-28 19:25:08 +0000
commit66526765714b08969548a414d3fa87dbe333242d (patch)
treed3fc2027140f97edfdfc5023e70ff8b4db920c11 /plugins/!NotAdopted/IMO2sProxy/src/imolib
parent3ccd712341ed9e76252bd595c5a797d6c8ea8992 (diff)
"!Deprecated" folders moved from root directory to plugins
git-svn-id: http://svn.miranda-ng.org/main/trunk@1230 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/!NotAdopted/IMO2sProxy/src/imolib')
-rw-r--r--plugins/!NotAdopted/IMO2sProxy/src/imolib/Makefile14
-rw-r--r--plugins/!NotAdopted/IMO2sProxy/src/imolib/imo_request.c388
-rw-r--r--plugins/!NotAdopted/IMO2sProxy/src/imolib/imo_request.h36
-rw-r--r--plugins/!NotAdopted/IMO2sProxy/src/imolib/imo_skype.c707
-rw-r--r--plugins/!NotAdopted/IMO2sProxy/src/imolib/imo_skype.h37
-rw-r--r--plugins/!NotAdopted/IMO2sProxy/src/imolib/io_layer.c175
-rw-r--r--plugins/!NotAdopted/IMO2sProxy/src/imolib/io_layer.h25
-rw-r--r--plugins/!NotAdopted/IMO2sProxy/src/imolib/io_layer_win32.c440
-rw-r--r--plugins/!NotAdopted/IMO2sProxy/src/imolib/skypetst.c211
9 files changed, 2033 insertions, 0 deletions
diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imolib/Makefile b/plugins/!NotAdopted/IMO2sProxy/src/imolib/Makefile
new file mode 100644
index 0000000000..30775becec
--- /dev/null
+++ b/plugins/!NotAdopted/IMO2sProxy/src/imolib/Makefile
@@ -0,0 +1,14 @@
+CFLAGS = -I../common/ -lcurl -lpthread -lm -O0 -g
+CC = gcc
+COMMON = ../common/fifo.c ../common/cJSON.c
+OBJS = imo_request.c imo_skype.c skypetst.c io_layer.c
+
+.PHONY: all skypetst clean
+
+all : skypetst
+
+skypetst: $(COMMON) $(OBJS)
+ $(CC) -o skypetst $(COMMON) $(OBJS) $(CFLAGS)
+
+clean :
+ rm skypetst
diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imolib/imo_request.c b/plugins/!NotAdopted/IMO2sProxy/src/imolib/imo_request.c
new file mode 100644
index 0000000000..732a7e3e48
--- /dev/null
+++ b/plugins/!NotAdopted/IMO2sProxy/src/imolib/imo_request.c
@@ -0,0 +1,388 @@
+/* Module: imo_request.c
+ Purpose: Posts XMLHHTP-Requests to imo.im server
+ Author: leecher
+ Date: 30.08.2009
+*/
+#ifdef _WIN32
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#define LockMutex(x) EnterCriticalSection (&x)
+#define UnlockMutex(x) LeaveCriticalSection(&x)
+#define InitMutex(x) InitializeCriticalSection(&x)
+#define ExitMutex(x) DeleteCriticalSection(&x)
+#define mutex_t CRITICAL_SECTION
+#else
+#include <pthread.h>
+#define LockMutex(x) pthread_mutex_lock(&x)
+#define UnlockMutex(x) pthread_mutex_unlock(&x)
+#define InitMutex(x) pthread_mutex_init(&x, NULL);
+#define ExitMutex(x)
+#define mutex_t pthread_mutex_t
+#endif
+#include <time.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "fifo.h"
+#include "imo_request.h"
+#include "io_layer.h"
+
+#define SSID_LENGTH 16
+
+struct _tagIMORQ
+{
+ IOLAYER *hIO;
+ char szSessId[SSID_LENGTH+2];
+ unsigned long send_ack; // Some Sending ACK number
+ unsigned long send_seq; // Within one ACK there seems to be a SEQ-Number?
+ unsigned long *psend_ack; // Pointer to send_ack to use
+ unsigned long *psend_seq; // Pointer to send_seq to use
+ mutex_t mutex; // Mutex for securing psend_ack and psend_seq read/write
+ BOOL bIsClone; // Indicates that the current handle is a clone
+ char *pszHost; // Login host
+ char szReqURL[32]; // Request-URL
+};
+
+static IOLAYER *(*IoLayer_Init)(void) =
+#ifdef WIN32
+IoLayerW32_Init;
+#else
+IoLayerCURL_Init;
+#endif
+
+// Forward declaration of private functions
+static size_t add_data(char *data, size_t size, size_t nmemb, void *ctx);
+static IMORQ *Init(void);
+
+// -----------------------------------------------------------------------------
+// Interface
+// -----------------------------------------------------------------------------
+
+void ImoRq_SetIOLayer(IOLAYER *(*fp_Init)(void))
+{
+ IoLayer_Init = fp_Init;
+}
+
+// -----------------------------------------------------------------------------
+
+IMORQ *ImoRq_Init(void)
+{
+
+ IMORQ *hRq;
+
+ if (hRq = Init())
+ {
+ /* Create session ID */
+ ImoRq_CreateID (hRq->szSessId, SSID_LENGTH+1);
+
+ hRq->psend_seq = &hRq->send_seq;
+ hRq->psend_ack = &hRq->send_ack;
+ InitMutex(hRq->mutex);
+
+ /* Disptch version of imo.im protocol */
+ switch (IMO_API_VERSION)
+ {
+ case 0:
+ hRq->pszHost = "https://o.imo.im/";
+ break;
+ case 1:
+ hRq->pszHost = "https://imo.im/";
+ break;
+ }
+ sprintf (hRq->szReqURL, "%simo", hRq->pszHost);
+
+ /* Fetch start page to get cookies */
+ if (hRq->hIO->Get (hRq->hIO, hRq->pszHost, NULL))
+
+ /* Get new session ID from system */
+ {
+ char *pszRPC = ImoRq_ResetRPC (hRq), *pszRPCRes;
+ if (pszRPC)
+ {
+ if ((pszRPCRes = strstr(pszRPC, "ssid\":\"")) || (pszRPCRes = strstr(pszRPC, "ssid\": \"")))
+ strcpy (hRq->szSessId, strtok (pszRPCRes+7, "\""));
+ }
+ } else {
+ ImoRq_Exit(hRq);
+ hRq = NULL;
+ }
+ }
+
+ return hRq;
+}
+
+// -----------------------------------------------------------------------------
+
+IMORQ *ImoRq_Clone (IMORQ *hRq)
+{
+ IMORQ *hDup;
+
+ if (!(hDup = Init())) return NULL;
+ strcpy (hDup->szSessId, hRq->szSessId);
+ hDup->psend_seq = hRq->psend_seq;
+ hDup->psend_ack = hRq->psend_ack;
+ hDup->mutex = hRq->mutex;
+ hDup->bIsClone = TRUE;
+ hDup->pszHost = hRq->pszHost;
+ strcpy (hDup->szReqURL, hRq->szReqURL);
+ return hDup;
+}
+
+// -----------------------------------------------------------------------------
+
+void ImoRq_Exit (IMORQ *hRq)
+{
+ if (hRq->hIO) hRq->hIO->Exit(hRq->hIO);
+ if (!hRq->bIsClone) ExitMutex (hRq->mutex);
+ free (hRq);
+}
+// -----------------------------------------------------------------------------
+
+void ImoRq_Cancel (IMORQ *hRq)
+{
+ if (hRq->hIO) hRq->hIO->Cancel(hRq->hIO);
+}
+
+// -----------------------------------------------------------------------------
+
+char *ImoRq_PostImo(IMORQ *hRq, char *pszMethod, cJSON *data)
+{
+ TYP_FIFO *hPostString;
+ char *pszData, *pszEscData;
+ unsigned int uiCount = -1;
+
+ if (!(pszData = cJSON_Print(data))) return NULL;
+printf ("-> %s\n", pszData);
+#ifdef _WIN32
+OutputDebugString (pszData);
+OutputDebugString ("\n");
+#endif
+ pszEscData = hRq->hIO->EscapeString(hRq->hIO, pszData);
+ free (pszData);
+ if (!pszEscData || !(hPostString = Fifo_Init(strlen(pszEscData)+32)))
+ {
+ if (pszEscData) hRq->hIO->FreeEscapeString (pszEscData);
+ return NULL;
+ }
+ Fifo_AddString (hPostString, "method=");
+ Fifo_AddString (hPostString, pszMethod);
+ Fifo_AddString (hPostString, "&data=");
+ Fifo_AddString (hPostString, pszEscData);
+ hRq->hIO->FreeEscapeString (pszEscData);
+ pszEscData = Fifo_Get(hPostString, &uiCount);
+ pszData = hRq->hIO->Post (hRq->hIO, hRq->szReqURL, pszEscData,
+ uiCount-1, NULL);
+ Fifo_Exit(hPostString);
+printf ("<- %s\n", pszData);
+ return pszData;
+}
+
+// -----------------------------------------------------------------------------
+
+char *ImoRq_PostSystem(IMORQ *hRq, char *pszMethod, char *pszSysTo, char *pszSysFrom, cJSON *data, int bFreeData)
+{
+ cJSON *root, *msgs, *msg, *to, *from;
+ char *pszRet;
+
+ if (!(root=cJSON_CreateObject())) return NULL;
+ LockMutex (hRq->mutex);
+ cJSON_AddNumberToObject (root, "ack", *hRq->psend_ack);
+ if (*hRq->szSessId) cJSON_AddStringToObject (root, "ssid", hRq->szSessId);
+ else cJSON_AddNumberToObject (root, "ssid", 0);
+ cJSON_AddItemToObject (root, "messages", (msgs = cJSON_CreateArray()));
+ if (data)
+ {
+ msg=cJSON_CreateObject();
+ cJSON_AddItemToObject(msg, "data", data);
+ to = cJSON_CreateObject();
+ cJSON_AddStringToObject (to, "system", pszSysTo);
+ cJSON_AddItemToObject(msg, "to", to);
+ from = cJSON_CreateObject();
+ cJSON_AddStringToObject (from, "system", pszSysFrom);
+ if (*hRq->szSessId) cJSON_AddStringToObject (from, "ssid", hRq->szSessId);
+ else cJSON_AddNumberToObject (from, "ssid", 0);
+ cJSON_AddItemToObject(msg, "from", from);
+ cJSON_AddNumberToObject (msg, "seq", (*hRq->psend_seq)++);
+ cJSON_AddItemToArray (msgs, msg);
+ }
+ UnlockMutex (hRq->mutex);
+ pszRet = ImoRq_PostImo (hRq, pszMethod, root);
+ if (data && !bFreeData)
+ {
+ msg->child = data->next;
+ data->next = NULL;
+ }
+ cJSON_Delete (root);
+ return pszRet;
+}
+
+// -----------------------------------------------------------------------------
+
+char *ImoRq_ResetRPC(IMORQ *hRq)
+{
+ cJSON *root, *ssid;
+ char *pszRet;
+
+ if (!(root=cJSON_CreateObject())) return NULL;
+ cJSON_AddStringToObject (root, "method", (IMO_API_VERSION==0?"get_ssid":"get_cookie_and_ssid"));
+ ssid=cJSON_CreateObject();
+ cJSON_AddStringToObject (ssid, "ssid", hRq->szSessId);
+ if (IMO_API_VERSION > 0)
+ {
+ cJSON_AddStringToObject (ssid, "kind", "reui");
+ cJSON_AddStringToObject (ssid, "version", "1336611734.48");
+ }
+ cJSON_AddItemToObject(root, "data", ssid);
+ if (IMO_API_VERSION == 0) *hRq->szSessId = 0;
+ pszRet = ImoRq_PostSystem (hRq, "rest_rpc", (IMO_API_VERSION==0?"ssid":"session"), "client", root, 1);
+ LockMutex (hRq->mutex);
+ *hRq->psend_seq=0;
+ UnlockMutex (hRq->mutex);
+ return pszRet;
+}
+
+// -----------------------------------------------------------------------------
+
+char *ImoRq_UserActivity(IMORQ *hRq)
+{
+ cJSON *ssid;
+
+ ssid=cJSON_CreateObject();
+ cJSON_AddStringToObject (ssid, "ssid", hRq->szSessId);
+ return ImoRq_PostToSys (hRq, "observed_user_activity", "session", ssid, 1, NULL);
+}
+
+// -----------------------------------------------------------------------------
+
+char *ImoRq_Echo(IMORQ *hRq)
+{
+ cJSON *data;
+ time_t t;
+ char szTime[16], *pszRet;
+
+ if (!(data=cJSON_CreateObject())) return NULL;
+ sprintf (szTime, "%ld", time(&t)*1000);
+ cJSON_AddStringToObject (data, "t", szTime);
+ pszRet = ImoRq_PostImo (hRq, "echo", data);
+ cJSON_Delete (data);
+ return pszRet;
+}
+
+// -----------------------------------------------------------------------------
+
+char *ImoRq_Reui_Session(IMORQ *hRq)
+{
+ cJSON *ssid;
+
+ ssid=cJSON_CreateObject();
+ cJSON_AddStringToObject (ssid, "ssid", hRq->szSessId);
+ return ImoRq_PostToSys (hRq, "reui_session", "session", ssid, 1, NULL);
+}
+
+// -----------------------------------------------------------------------------
+
+char *ImoRq_PostToSys(IMORQ *hRq, char *pszMethod, char *pszSysTo, cJSON *data, int bFreeData, int *pireqid)
+{
+ cJSON *root;
+ char *pszRet;
+
+ if (!(root=cJSON_CreateObject())) return NULL;
+ cJSON_AddStringToObject (root, "method", pszMethod);
+ if (pireqid) cJSON_AddNumberToObject(root, "request_id", *pireqid);
+ cJSON_AddItemToObject(root, "data", data);
+ pszRet = ImoRq_PostSystem (hRq, "forward_to_server", pszSysTo, "client", root, bFreeData);
+ if (!bFreeData)
+ {
+ data->prev->next = data->next;
+ if (data->next) data->next->prev = data->prev;
+ data->prev = data->next = NULL;
+ cJSON_Delete (root);
+ }
+ return pszRet;
+}
+// -----------------------------------------------------------------------------
+
+char *ImoRq_PostAmy(IMORQ *hRq, char *pszMethod, cJSON *data)
+{
+ return ImoRq_PostToSys (hRq, pszMethod, "im", data, FALSE, NULL);
+}
+
+// -----------------------------------------------------------------------------
+
+char *ImoRq_SessId(IMORQ *hRq)
+{
+ return hRq->szSessId;
+}
+
+// -----------------------------------------------------------------------------
+
+char *ImoRq_GetLastError(IMORQ *hRq)
+{
+ return hRq->hIO->GetLastError (hRq->hIO);
+}
+
+// -----------------------------------------------------------------------------
+char *ImoRq_GetHost(IMORQ *hRq)
+{
+ return hRq->pszHost;
+}
+
+// -----------------------------------------------------------------------------
+void ImoRq_UpdateAck(IMORQ *hRq, unsigned long lAck)
+{
+ LockMutex (hRq->mutex);
+ *hRq->psend_ack = lAck;
+ UnlockMutex (hRq->mutex);
+}
+// -----------------------------------------------------------------------------
+unsigned long ImoRq_GetSeq(IMORQ *hRq)
+{
+ unsigned long lRet;
+
+ LockMutex (hRq->mutex);
+ lRet = *hRq->psend_seq;
+ UnlockMutex (hRq->mutex);
+ return lRet;
+}
+// -----------------------------------------------------------------------------
+
+void ImoRq_CreateID(char *pszID, int cbID)
+{
+ int i, r;
+ time_t curtime;
+
+ srand(time(&curtime));
+ for (i=0; i<cbID; i++)
+ {
+ r = rand()%62;
+ if (r<26) pszID[i]='A'+r; else
+ if (r<52) pszID[i]='a'+(r-26); else
+ pszID[i]='0'+(r-52);
+ }
+ pszID[i]=0;
+ return;
+}
+
+// -----------------------------------------------------------------------------
+
+char *ImoRq_HTTPGet(IMORQ *hRq, char *pszURL, unsigned int *pdwLength)
+{
+ return hRq->hIO->Get (hRq->hIO, pszURL, pdwLength);
+}
+
+// -----------------------------------------------------------------------------
+
+static IMORQ *Init(void)
+{
+ IMORQ *hRq = calloc(1, sizeof(IMORQ));
+
+ /* Setup CURL */
+ if (!hRq) return NULL;
+ if (!(hRq->hIO = IoLayer_Init()))
+ {
+ ImoRq_Exit(hRq);
+ return NULL;
+ }
+ return hRq;
+}
+
diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imolib/imo_request.h b/plugins/!NotAdopted/IMO2sProxy/src/imolib/imo_request.h
new file mode 100644
index 0000000000..42da000bc2
--- /dev/null
+++ b/plugins/!NotAdopted/IMO2sProxy/src/imolib/imo_request.h
@@ -0,0 +1,36 @@
+#ifndef _IMO_REQUEST_H_
+#define _IMO_REQUEST_H_
+
+#include "cJSON.h"
+
+// 1 - New imo.im api
+// 0 - o.imo.im api
+#define IMO_API_VERSION 1
+
+struct _tagIMORQ;
+typedef struct _tagIMORQ IMORQ;
+
+#ifdef _IOLAYER_H_
+void ImoRq_SetIOLayer(IOLAYER *(*fp_Init)(void));
+#endif
+
+IMORQ *ImoRq_Init(void);
+IMORQ *ImoRq_Clone (IMORQ *hRq);
+void ImoRq_Cancel (IMORQ *hRq);
+void ImoRq_Exit (IMORQ *hRq);
+
+char *ImoRq_SessId(IMORQ *hRq);
+char *ImoRq_GetLastError(IMORQ *hRq);
+char *ImoRq_GetHost(IMORQ *hRq);
+char *ImoRq_PostAmy(IMORQ *hRq, char *pszMethod, cJSON *data);
+void ImoRq_CreateID(char *pszID, int cbID);
+char *ImoRq_PostSystem(IMORQ *hRq, char *pszMethod, char *pszSysTo, char *pszSysFrom, cJSON *data, int bFreeData);
+char *ImoRq_PostToSys(IMORQ *hRq, char *pszMethod, char *pszSysTo, cJSON *data, int bFreeData, int *pireqid);
+void ImoRq_UpdateAck(IMORQ *hRq, unsigned long lAck);
+unsigned long ImoRq_GetSeq(IMORQ *hRq);
+char *ImoRq_UserActivity(IMORQ *hRq);
+char *ImoRq_ResetRPC(IMORQ *hRq);
+char *ImoRq_Reui_Session(IMORQ *hRq);
+char *ImoRq_Echo(IMORQ *hRq);
+char *ImoRq_HTTPGet(IMORQ *hRq, char *pszURL, unsigned int *pdwLength);
+#endif
diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imolib/imo_skype.c b/plugins/!NotAdopted/IMO2sProxy/src/imolib/imo_skype.c
new file mode 100644
index 0000000000..f2bca4d7b8
--- /dev/null
+++ b/plugins/!NotAdopted/IMO2sProxy/src/imolib/imo_skype.c
@@ -0,0 +1,707 @@
+/* Module: imo_skype.c
+ Purpose: Communication layer for imo.im Skype
+ Author: leecher
+ Date: 30.08.2009
+*/
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "imo_request.h"
+#include "imo_skype.h"
+
+#ifdef _WIN64
+#pragma comment (lib, "bufferoverflowU.lib")
+#endif
+
+#define PROTO "prpl-skype"
+
+struct _tagIMOSKYPE
+{
+ IMORQ *hRq;
+ IMORQ *hPoll;
+ char *pszUser;
+ IMOSTATCB StatusCb;
+ char *pszLastRes;
+ void *pUser;
+ int request_id;
+};
+
+static int CheckReturn (IMOSKYPE *hSkype, char *pszMsg, char *pszExpected);
+static int ManageBuddy(IMOSKYPE *hSkype, char *pszAction, char *pszBuddy, char *pszGroup);
+
+// -----------------------------------------------------------------------------
+// Interface
+// -----------------------------------------------------------------------------
+
+IMOSKYPE *ImoSkype_Init(IMOSTATCB StatusCb, void *pUser)
+{
+ IMOSKYPE *hSkype = calloc(1, sizeof(IMOSKYPE));
+
+ if (!hSkype) return NULL;
+ if (!(hSkype->hRq = ImoRq_Init()) || !(hSkype->hPoll = ImoRq_Clone(hSkype->hRq)))
+ {
+ ImoSkype_Exit(hSkype);
+ return NULL;
+ }
+ hSkype->StatusCb = StatusCb;
+ hSkype->pUser = pUser;
+ return hSkype;
+}
+
+// -----------------------------------------------------------------------------
+
+void ImoSkype_Exit(IMOSKYPE *hSkype)
+{
+ if (!hSkype) return;
+ if (hSkype->hRq) ImoRq_Exit(hSkype->hRq);
+ if (hSkype->hPoll) ImoRq_Exit(hSkype->hPoll);
+ if (hSkype->pszUser) free(hSkype->pszUser);
+ free (hSkype);
+}
+
+// -----------------------------------------------------------------------------
+
+void ImoSkype_CancelPolling(IMOSKYPE *hSkype)
+{
+ if (hSkype->hPoll)
+ ImoRq_Cancel(hSkype->hPoll);
+}
+
+// -----------------------------------------------------------------------------
+
+char *ImoSkype_GetLastError(IMOSKYPE *hSkype)
+{
+ char *pszRet = ImoRq_GetLastError(hSkype->hRq);
+
+ if (!pszRet || !*pszRet) return hSkype->pszLastRes;
+ return pszRet;
+}
+
+// -----------------------------------------------------------------------------
+
+char *ImoSkype_GetUserHandle(IMOSKYPE *hSkype)
+{
+ return hSkype->pszUser;
+}
+
+// -----------------------------------------------------------------------------
+
+// -1 - Error
+// 0 - Login failed
+// 1 - Login successful
+int ImoSkype_Login(IMOSKYPE *hSkype, char *pszUser, char *pszPass)
+{
+ cJSON *root;
+ char *pszRet;
+ int iRet = -1;
+
+ if (!hSkype) return 0;
+ if (IMO_API_VERSION == 0)
+ {
+ if (!(root=cJSON_CreateObject())) return 0;
+ cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq));
+ if (pszRet = ImoRq_PostToSys(hSkype->hRq, "cookie_login", "session", root, 1, NULL))
+ iRet = CheckReturn(hSkype, pszRet, "ok")>0;
+ }
+
+ if (!(root=cJSON_CreateObject())) return 0;
+ if (hSkype->pszUser) free (hSkype->pszUser);
+ cJSON_AddStringToObject(root, "uid", hSkype->pszUser = strdup(pszUser));
+ cJSON_AddStringToObject(root, "proto", PROTO);
+ cJSON_AddStringToObject(root, "passwd", pszPass);
+ cJSON_AddNullToObject(root, "captcha"); // Uh-oh, thay may get annoying in the future! :(
+ cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq));
+ if (pszRet = ImoRq_PostAmy(hSkype->hRq, "account_login", root))
+ iRet = CheckReturn(hSkype, pszRet, "ok")>0;
+ cJSON_Delete(root);
+
+ return iRet;
+}
+
+// -----------------------------------------------------------------------------
+
+// -1 - Error
+// 0 - Logout failed
+// 1 - Logout successful
+int ImoSkype_Logout(IMOSKYPE *hSkype)
+{
+ cJSON *root;
+ char *pszRet;
+ int iRet = -1;
+
+ if (!hSkype || !(root=cJSON_CreateObject())) return 0;
+ cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq));
+ if (pszRet = ImoRq_PostToSys(hSkype->hRq, "signoff_all", "session", root, 1, NULL))
+ iRet = CheckReturn(hSkype, pszRet, "ok")>0;
+ return iRet;
+}
+
+// -----------------------------------------------------------------------------
+
+// -1 - Error
+// 0 - Received unknown answer
+// 1 - Got back information, called notification callback
+// 2 - Received PING [deprecated]
+int ImoSkype_Poll(IMOSKYPE *hSkype)
+{
+ char *pszRet;
+
+ if (!hSkype || !hSkype->hPoll) return 0;
+ pszRet = ImoRq_PostSystem(hSkype->hPoll, "forward_to_server", NULL, NULL, NULL, 1);
+ if (!pszRet) return -1;
+ return CheckReturn (hSkype, pszRet, "ping");
+}
+
+// -----------------------------------------------------------------------------
+
+int ImoSkype_KeepAlive(IMOSKYPE *hSkype)
+{
+ char *pszRet;
+
+ /* In case we want to receive Promo-Infos...
+ {
+ cJSON *edata = cJSON_CreateObject(), *root;
+
+ root=cJSON_CreateObject();
+ cJSON_AddStringToObject(edata, "kind", "web");
+ cJSON_AddNumberToObject(edata, "quantity", 1);
+ cJSON_AddItemToObject(root, "edata", edata);
+ if (pszRet = ImoRq_PostToSys(hSkype->hRq, "get_promos", "promo", root, 1))
+ CheckReturn(hSkype, pszRet, "ok");
+ }
+ */
+
+ if (!hSkype) return 0;
+ pszRet = ImoRq_UserActivity(hSkype->hPoll);
+ if (!pszRet) return -1;
+ return CheckReturn (hSkype, pszRet, "ok");
+}
+
+// -----------------------------------------------------------------------------
+
+// pszStatus:
+// Valid states:
+// typing
+// typed
+// not_typing
+//
+// -1 - Error
+// 0 - Typing notification failed
+// 1 - Typing notification successful
+int ImoSkype_Typing(IMOSKYPE *hSkype, char *pszBuddy, char *pszStatus)
+{
+ cJSON *root;
+ char *pszRet;
+ int iRet = -1;
+
+ if (!hSkype || !hSkype->pszUser || !(root=cJSON_CreateObject())) return 0;
+ cJSON_AddStringToObject(root, "uid", hSkype->pszUser);
+ cJSON_AddStringToObject(root, "proto", PROTO);
+ cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq));
+ cJSON_AddStringToObject(root, "buid", pszBuddy);
+ cJSON_AddStringToObject(root, "typing_state", pszStatus);
+ if (pszRet = ImoRq_PostAmy(hSkype->hRq, "im_typing", root))
+ iRet = CheckReturn(hSkype, pszRet, "ok")>0;
+ cJSON_Delete(root);
+ return iRet;
+}
+
+// -----------------------------------------------------------------------------
+
+// -1 - Error
+// 0 - Sending failed
+// 1 - Send pending
+int ImoSkype_SendMessage(IMOSKYPE *hSkype, char *pszBuddy, char *pszMessage, int *prequest_id)
+{
+ cJSON *root;
+ char *pszRet;
+ int iRet = -1;
+
+ if (!hSkype || !hSkype->pszUser || !(root=cJSON_CreateObject())) return 0;
+ cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq));
+ cJSON_AddStringToObject(root, "uid", hSkype->pszUser);
+ cJSON_AddStringToObject(root, "proto", PROTO);
+ cJSON_AddStringToObject(root, "buid", pszBuddy);
+ cJSON_AddStringToObject(root, "msg", pszMessage);
+ if (pszRet = (IMO_API_VERSION==0?ImoRq_PostAmy(hSkype->hRq, "send_im", root):ImoRq_PostToSys (hSkype->hRq, "send_im", "im", root, 0, &hSkype->request_id)))
+ iRet = CheckReturn(hSkype, pszRet, "ok")>0;
+ if (prequest_id) *prequest_id = hSkype->request_id;
+ hSkype->request_id++;
+ cJSON_Delete(root);
+ return iRet;
+}
+
+// -----------------------------------------------------------------------------
+
+// pszStatus:
+// Valid states:
+// available
+// away
+// busy
+// invisible
+//
+// -1 - Error
+// 0 - Failed
+// 1 - OK
+int ImoSkype_SetStatus(IMOSKYPE *hSkype, char *pszStatus, char *pszStatusMsg)
+{
+ cJSON *root;
+ char *pszRet;
+ int iRet = -1;
+
+ /*
+ if (!hSkype->pszUser || !(root=cJSON_CreateObject())) return 0;
+ cJSON_AddStringToObject(root, "uid", hSkype->pszUser);
+ cJSON_AddStringToObject(root, "proto", PROTO);
+ cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq));
+ cJSON_AddStringToObject(root, "ad", "");
+ cJSON_AddStringToObject(root, "primitive", pszStatus);
+ cJSON_AddStringToObject(root, "status", pszStatusMsg);
+ if (pszRet = ImoRq_PostAmy(hSkype->hRq, "set_status", root))
+ iRet = CheckReturn(hSkype, pszRet, "ok")>0;
+ */
+
+ if (!hSkype || !hSkype->pszUser || !(root=cJSON_CreateObject())) return 0;
+ cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq));
+ cJSON_AddStringToObject(root, "ad", "");
+ cJSON_AddStringToObject(root, "primitive", pszStatus);
+ cJSON_AddStringToObject(root, "status", pszStatusMsg);
+ cJSON_AddFalseToObject (root, "auto_away");
+ if (pszRet = ImoRq_PostToSys(hSkype->hRq, "set_status", "session", root, 0, NULL))
+ iRet = CheckReturn(hSkype, pszRet, "ok")>0;
+
+ cJSON_Delete(root);
+ return iRet;
+}
+
+// -----------------------------------------------------------------------------
+
+// -1 - Error
+// 0 - Failed
+// 1 - OK
+int ImoSkype_AddBuddy(IMOSKYPE *hSkype, char *pszBuddy)
+{
+ return ManageBuddy (hSkype, "add_buddy", pszBuddy, "Offline");
+}
+
+// -----------------------------------------------------------------------------
+
+// pszGroup = "Offline" if the user if offline, otherwise "Skype" or "Buddies"
+// -1 - Error
+// 0 - Failed
+// 1 - OK
+int ImoSkype_DelBuddy(IMOSKYPE *hSkype, char *pszBuddy, char *pszGroup)
+{
+ int iRet = ManageBuddy (hSkype, "del_buddy", pszBuddy, pszGroup);
+
+ if (iRet<1 && strcmp(pszGroup, "Skype")==0)
+ return ManageBuddy (hSkype, "del_buddy", pszBuddy, "Buddies");
+ return iRet;
+}
+// -----------------------------------------------------------------------------
+
+int ImoSkype_BlockBuddy(IMOSKYPE *hSkype, char *pszBuddy)
+{
+ return ManageBuddy (hSkype, "block_buddy", pszBuddy, NULL);
+}
+
+// -----------------------------------------------------------------------------
+
+int ImoSkype_UnblockBuddy(IMOSKYPE *hSkype, char *pszBuddy)
+{
+ return ManageBuddy (hSkype, "unblock_buddy", pszBuddy, NULL);
+}
+
+// -----------------------------------------------------------------------------
+
+int ImoSkype_ChangeAlias(IMOSKYPE *hSkype, char *pszBuddy, char *pszNewAlias)
+{
+ cJSON *root;
+ char *pszRet;
+ int iRet = -1;
+
+ if (!hSkype->pszUser || !(root=cJSON_CreateObject())) return 0;
+ cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq));
+ cJSON_AddStringToObject(root, "uid", hSkype->pszUser);
+ cJSON_AddStringToObject(root, "proto", PROTO);
+ cJSON_AddStringToObject(root, "buid", pszBuddy);
+ cJSON_AddStringToObject(root, "alias", pszNewAlias);
+ if (pszRet = ImoRq_PostAmy(hSkype->hRq, "change_buddy_alias", root))
+ iRet = CheckReturn(hSkype, pszRet, "ok")>0;
+ cJSON_Delete(root);
+ return iRet;
+}
+
+// -----------------------------------------------------------------------------
+
+int ImoSkype_StartVoiceCall(IMOSKYPE *hSkype, char *pszBuddy)
+{
+ cJSON *root;
+ char *pszRet;
+ int iRet = -1;
+
+ if (!hSkype->pszUser || !(root=cJSON_CreateObject())) return 0;
+ cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq));
+ cJSON_AddStringToObject(root, "uid", hSkype->pszUser);
+ cJSON_AddStringToObject(root, "proto", PROTO);
+ cJSON_AddStringToObject(root, "buid", pszBuddy);
+ if (pszRet = ImoRq_PostToSys (hSkype->hRq, "start_audio_chat", "av", root, 1, NULL))
+ iRet = CheckReturn(hSkype, pszRet, "ok")>0;
+ return iRet;
+}
+
+// -----------------------------------------------------------------------------
+
+int ImoSkype_Ping(IMOSKYPE *hSkype)
+{
+ char *pszRet;
+ int iRet = -1;
+
+ if (pszRet = ImoRq_Echo(hSkype->hRq))
+ iRet = CheckReturn(hSkype, pszRet, "ok")>0;
+ return iRet;
+}
+
+// -----------------------------------------------------------------------------
+
+char *ImoSkype_GetAvatar(IMOSKYPE *hSkype, char *pszID, unsigned int *pdwLength)
+{
+ char szURL[256];
+
+ sprintf (szURL, "%sb/%s", ImoRq_GetHost(hSkype->hRq), pszID);
+ return ImoRq_HTTPGet (hSkype->hRq, szURL, pdwLength);
+}
+
+// -----------------------------------------------------------------------------
+
+int ImoSkype_GetUnreadMsgs(IMOSKYPE *hSkype)
+{
+ cJSON *root;
+ char *pszRet;
+ int iRet = -1;
+
+ if (!hSkype->pszUser || !(root=cJSON_CreateObject())) return 0;
+ cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq));
+ cJSON_AddStringToObject(root, "uid", hSkype->pszUser);
+ cJSON_AddStringToObject(root, "proto", PROTO);
+ if (pszRet = ImoRq_PostAmy(hSkype->hRq, "get_unread_msgs", root))
+ iRet = CheckReturn(hSkype, pszRet, "ok")>0;
+ cJSON_Delete(root);
+ return iRet;
+}
+
+// -----------------------------------------------------------------------------
+
+int ImoSkype_GetAlpha(IMOSKYPE *hSkype)
+{
+ cJSON *root;
+ char *pszRet;
+ int iRet = -1;
+
+ if (!hSkype->pszUser || !(root=cJSON_CreateObject())) return 0;
+ cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq));
+ cJSON_AddStringToObject(root, "uid", hSkype->pszUser);
+ cJSON_AddStringToObject(root, "proto", PROTO);
+ if (pszRet = ImoRq_PostToSys (hSkype->hRq, "get_alpha_for_user", "alpha", root, 1, NULL))
+ iRet = CheckReturn(hSkype, pszRet, "ok")>0;
+ return iRet;
+}
+
+// -----------------------------------------------------------------------------
+
+
+int ImoSkype_CreateSharedGroup(IMOSKYPE *hSkype, char *pszName)
+{
+ cJSON *root;
+ char *pszRet;
+ int iRet = -1;
+
+ if (!hSkype->pszUser || !(root=cJSON_CreateObject())) return 0;
+ cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq));
+ cJSON_AddStringToObject(root, "uid", hSkype->pszUser);
+ cJSON_AddStringToObject(root, "proto", PROTO);
+ cJSON_AddFalseToObject(root, "is_native"); // TRUE would be great, but not yet supported?
+ cJSON_AddStringToObject(root, "name", pszName);
+ if (pszRet = ImoRq_PostAmy(hSkype->hRq, "create_shared_group", root))
+ iRet = CheckReturn(hSkype, pszRet, "ok")>0;
+ cJSON_Delete(root);
+ return iRet;
+}
+
+// -----------------------------------------------------------------------------
+
+int ImoSkype_GroupInvite(IMOSKYPE *hSkype, char *pszGroup, char *pszUser)
+{
+ cJSON *root;
+ char *pszRet, *p, *pszGroupDup = strdup(pszGroup);
+ int iRet = -1;
+
+ if (p=strrchr(pszGroupDup, ';')) *p=0;
+ if (!hSkype->pszUser || !(root=cJSON_CreateObject())) return 0;
+ cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq));
+ cJSON_AddStringToObject(root, "uid", hSkype->pszUser);
+ cJSON_AddStringToObject(root, "proto", PROTO);
+ cJSON_AddStringToObject(root, "gid", pszGroupDup);
+ cJSON_AddStringToObject(root, "iproto", PROTO);
+ cJSON_AddStringToObject(root, "iuid", hSkype->pszUser);
+ cJSON_AddStringToObject(root, "ibuid", pszUser);
+ if (pszRet = ImoRq_PostAmy(hSkype->hRq, "invite_to_group", root))
+ iRet = CheckReturn(hSkype, pszRet, "ok")>0;
+ free (pszGroupDup);
+ cJSON_Delete(root);
+ return iRet;
+}
+
+// -----------------------------------------------------------------------------
+
+int ImoSkype_GroupKick(IMOSKYPE *hSkype, char *pszGroup, char *pszUser)
+{
+ cJSON *root;
+ char *pszRet, *p, *pszGroupDup = strdup(pszGroup), szBUID[256];
+ int iRet = -1;
+
+ if (p=strrchr(pszGroupDup, ';')) *p=0;
+ sprintf (szBUID, "%s;%s;"PROTO, pszGroupDup, pszUser);
+ if (!hSkype->pszUser || !(root=cJSON_CreateObject())) return 0;
+ cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq));
+ cJSON_AddStringToObject(root, "uid", hSkype->pszUser);
+ cJSON_AddStringToObject(root, "proto", PROTO);
+ cJSON_AddStringToObject(root, "buid", szBUID);
+ if (pszRet = ImoRq_PostAmy(hSkype->hRq, "kick_member", root))
+ iRet = CheckReturn(hSkype, pszRet, "ok")>0;
+ free (pszGroupDup);
+ cJSON_Delete(root);
+ return iRet;
+}
+
+// -----------------------------------------------------------------------------
+
+int ImoSkype_GroupTopic(IMOSKYPE *hSkype, char *pszGroup, char *pszTopic)
+{
+ cJSON *root;
+ char *pszRet, *p, *pszGroupDup = strdup(pszGroup);
+ int iRet = -1;
+
+ if (p=strrchr(pszGroupDup, ';')) *p=0;
+ if (!hSkype->pszUser || !(root=cJSON_CreateObject())) return 0;
+ cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq));
+ cJSON_AddStringToObject(root, "uid", hSkype->pszUser);
+ cJSON_AddStringToObject(root, "proto", PROTO);
+ cJSON_AddStringToObject(root, "gid", pszGroupDup);
+ cJSON_AddStringToObject(root, "topic", pszTopic);
+ if (pszRet = ImoRq_PostAmy(hSkype->hRq, "set_group_topic", root))
+ iRet = CheckReturn(hSkype, pszRet, "ok")>0;
+ free (pszGroupDup);
+ cJSON_Delete(root);
+ return iRet;
+}
+
+// -----------------------------------------------------------------------------
+
+int ImoSkype_GroupLeave(IMOSKYPE *hSkype, char *pszGroup)
+{
+ cJSON *root;
+ char *pszRet, *p, *pszGroupDup = strdup(pszGroup);
+ int iRet = -1;
+
+ if (p=strrchr(pszGroupDup, ';')) *p=0;
+ if (!hSkype->pszUser || !(root=cJSON_CreateObject())) return 0;
+ cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq));
+ cJSON_AddStringToObject(root, "uid", hSkype->pszUser);
+ cJSON_AddStringToObject(root, "proto", PROTO);
+ cJSON_AddStringToObject(root, "gid", pszGroupDup);
+ if (pszRet = ImoRq_PostAmy(hSkype->hRq, "leave_group", root))
+ iRet = CheckReturn(hSkype, pszRet, "ok")>0;
+ free (pszGroupDup);
+ cJSON_Delete(root);
+ return iRet;
+}
+
+// -----------------------------------------------------------------------------
+// Static
+// -----------------------------------------------------------------------------
+static void PostDisconnect(IMOSKYPE *hSkype)
+{
+ cJSON *arr, *root;
+
+ if (arr = cJSON_CreateArray())
+ {
+ if (!(root=cJSON_CreateObject())) return;
+ cJSON_AddStringToObject(root, "name", "disconnect");
+ cJSON_AddItemToArray (arr, root);
+ hSkype->StatusCb(arr, hSkype->pUser);
+ cJSON_Delete(arr);
+ }
+}
+
+// 0 - Unexpected answer
+// 1 - Got back JSON data, notified callback
+// 2 - Received expected message pszExpected [deprecated]
+static int CheckReturn (IMOSKYPE *hSkype, char *pszMsg, char *pszExpected)
+{
+ cJSON *root, *data, *msgs, *msg, *sys, *arr, *prefs, *pref;
+ char *pszMethod, *pszSys;
+
+ hSkype->pszLastRes = pszMsg;
+ if (root = cJSON_Parse(pszMsg))
+ {
+ // Now let's see if this one is interesting for our system
+ if ((data = cJSON_GetObjectItem(root,"method")) &&
+ (pszMethod = data->valuestring) &&
+ strcmp(pszMethod, "forward_to_client") == 0 &&
+ (data = cJSON_GetObjectItem(root,"data")) &&
+ (msgs = cJSON_GetObjectItem(data,"messages")))
+ {
+ int i, iCount = cJSON_GetArraySize(msgs);
+
+ if (!iCount && pszExpected && strcmp(pszExpected, "ok") == 0)
+ {
+ if ((sys = cJSON_GetObjectItem(data,"ack")) && (unsigned long)sys->valueint >= ImoRq_GetSeq(hSkype->hRq))
+ return 2; // imoim ACKnowledged this
+ else
+ {
+ if (sys && sys->valueint==0)
+ {
+ // ACK error, reset to 0, better reset the connection
+ PostDisconnect(hSkype);
+ }
+ return 0; // No ACK, sequence number not incremented :(
+ }
+ }
+ for (i=0; i<iCount; i++)
+ {
+ if (msg = cJSON_GetArrayItem(msgs, i))
+ {
+ // Is this for me?
+ if ((sys = cJSON_GetObjectItem(msg,"to")) &&
+ (pszSys = cJSON_GetObjectItem(sys, "system")->valuestring) &&
+ strcmp (pszSys, "client") == 0)
+ {
+ if (sys = cJSON_GetObjectItem(msg,"seq"))
+ {
+ ImoRq_UpdateAck(hSkype->hRq, sys->valueint+1);
+ ImoRq_UpdateAck(hSkype->hPoll, sys->valueint+1);
+ }
+
+ // Callback is only called for system IM
+ if ((sys = cJSON_GetObjectItem(msg,"from")) &&
+ (pszSys = cJSON_GetObjectItem(sys, "system")->valuestring))
+ {
+ if ((strcmp (pszSys, "im") == 0 || strcmp (pszSys, "av") == 0) &&
+ (data = cJSON_GetObjectItem(msg,"data")) &&
+ (arr = cJSON_CreateArray()))
+ {
+ // Pack data into array for Callback backwards
+ // compatibility
+ cJSON *next;
+
+ next = data->next;
+ data->next = NULL;
+ cJSON_AddItemToArray (arr, data);
+ hSkype->StatusCb(arr, hSkype->pUser);
+ data->next = next;
+ free(arr);
+ }
+ else if (strcmp (pszSys, "internal") == 0 &&
+ (data = cJSON_GetObjectItem(msg,"data")) &&
+ (arr = cJSON_CreateArray()))
+ {
+ // Pack ACK msgs into a fake "ack" method so that callback
+ // function can dispatch them without interface change
+ cJSON *next;
+
+ cJSON_AddStringToObject (data, "name", "ack");
+ next = data->next;
+ data->next = NULL;
+ cJSON_AddItemToArray (arr, data);
+ hSkype->StatusCb(arr, hSkype->pUser);
+ data->next = next;
+ free(arr);
+ }
+ // Ensure to disable annoying autoaway
+ else if (strcmp (pszSys, "preference") == 0 &&
+ (data = cJSON_GetObjectItem(msg,"data")) &&
+ (prefs = cJSON_GetObjectItem(data, "preferences")))
+ {
+ int j, nPrefs = cJSON_GetArraySize(prefs);
+ cJSON *kind, *thispref, *value, *prefdata;
+
+ for (j=0; j<nPrefs; j++)
+ {
+ if ((pref = cJSON_GetArrayItem(prefs, j)) &&
+ (kind = cJSON_GetObjectItem(pref, "kind")) &&
+ strcmp (kind->valuestring, "impref") == 0 &&
+ (thispref = cJSON_GetObjectItem(pref, "pref")) &&
+ strcmp (thispref->valuestring, "auto_away") == 0 &&
+ (value = cJSON_GetObjectItem(pref, "value")) &&
+ value->type == cJSON_True && hSkype->pszUser &&
+ (prefdata = cJSON_CreateObject()))
+ {
+ cJSON *accs, *acc, *setprefs, *newpref;
+
+ if (accs = cJSON_CreateArray())
+ {
+ if (acc = cJSON_CreateObject())
+ {
+ cJSON_AddStringToObject(acc, "uid", hSkype->pszUser);
+ cJSON_AddStringToObject(acc, "proto", PROTO);
+ cJSON_AddItemToArray (accs, acc);
+ }
+ cJSON_AddItemToObject(prefdata, "accounts", accs);
+ }
+ if (setprefs = cJSON_CreateArray())
+ {
+ if (newpref = cJSON_CreateObject())
+ {
+ cJSON_AddStringToObject(newpref, "kind", kind->valuestring);
+ cJSON_AddStringToObject(newpref, "pref", thispref->valuestring);
+ cJSON_AddFalseToObject (newpref, "value");
+ cJSON_AddItemToArray (setprefs, newpref);
+ }
+ cJSON_AddItemToObject(prefdata, "preferences", setprefs);
+ }
+ ImoRq_PostToSys (hSkype->hRq, "set", "preference", prefdata, 1, NULL);
+ }
+ }
+ }
+ else if (strcmp (pszSys, "reset") == 0)
+ {
+ // System requested to reset connection
+ // Let's issue a "disconnect" to the callback to let it handle
+ // this situation
+ }
+ }
+ }
+ }
+ }
+ }
+ cJSON_Delete(root);
+ return 1;
+ }
+ else
+ {
+ if (pszExpected && strcmp(pszMsg, pszExpected)==0)
+ return 2;
+ }
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+
+static int ManageBuddy(IMOSKYPE *hSkype, char *pszAction, char *pszBuddy, char *pszGroup)
+{
+ cJSON *root;
+ char *pszRet;
+ int iRet = -1;
+
+ if (!hSkype->pszUser || !(root=cJSON_CreateObject())) return 0;
+ cJSON_AddStringToObject(root, "ssid", ImoRq_SessId(hSkype->hRq));
+ cJSON_AddStringToObject(root, "uid", hSkype->pszUser);
+ cJSON_AddStringToObject(root, "proto", PROTO);
+ cJSON_AddStringToObject(root, "buid", pszBuddy);
+ if (pszGroup) cJSON_AddStringToObject(root, "group", pszGroup);
+ if (pszRet = ImoRq_PostAmy(hSkype->hRq, pszAction, root))
+ iRet = CheckReturn(hSkype, pszRet, "ok")>0;
+ cJSON_Delete(root);
+ return iRet;
+}
diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imolib/imo_skype.h b/plugins/!NotAdopted/IMO2sProxy/src/imolib/imo_skype.h
new file mode 100644
index 0000000000..d9e1697ed6
--- /dev/null
+++ b/plugins/!NotAdopted/IMO2sProxy/src/imolib/imo_skype.h
@@ -0,0 +1,37 @@
+#include "cJSON.h"
+
+struct _tagIMOSKYPE;
+typedef struct _tagIMOSKYPE IMOSKYPE;
+// 0 - Message received, you may delete the cJSON object now
+// 1 - Don't delete cJSON object, callback will take care of freeing
+typedef int(*IMOSTATCB)(cJSON *pMsg, void *pUser);
+
+IMOSKYPE *ImoSkype_Init(IMOSTATCB StatusCb, void *pUser);
+void ImoSkype_Exit(IMOSKYPE *hSkype);
+void ImoSkype_CancelPolling(IMOSKYPE *hSkype);
+char *ImoSkype_GetLastError(IMOSKYPE *hSkype);
+char *ImoSkype_GetUserHandle(IMOSKYPE *hSkype);
+
+int ImoSkype_Login(IMOSKYPE *hSkype, char *pszUser, char *pszPass);
+int ImoSkype_Logout(IMOSKYPE *hSkype);
+int ImoSkype_Poll(IMOSKYPE *hSkype);
+int ImoSkype_Typing(IMOSKYPE *hSkype, char *pszBuddy, char *pszStatus);
+int ImoSkype_SetStatus(IMOSKYPE *hSkype, char *pszStatus, char *pszStatusMsg);
+int ImoSkype_SendMessage(IMOSKYPE *hSkype, char *pszBuddy, char *pszMessage, int *prequest_id);
+int ImoSkype_AddBuddy(IMOSKYPE *hSkype, char *pszBuddy);
+int ImoSkype_DelBuddy(IMOSKYPE *hSkype, char *pszBuddy, char *pszGroup);
+int ImoSkype_BlockBuddy(IMOSKYPE *hSkype, char *pszBuddy);
+int ImoSkype_UnblockBuddy(IMOSKYPE *hSkype, char *pszBuddy);
+int ImoSkype_ChangeAlias(IMOSKYPE *hSkype, char *pszBuddy, char *pszNewAlias);
+int ImoSkype_StartVoiceCall(IMOSKYPE *hSkype, char *pszBuddy);
+int ImoSkype_KeepAlive(IMOSKYPE *hSkype);
+int ImoSkype_Ping(IMOSKYPE *hSkype);
+char *ImoSkype_GetAvatar(IMOSKYPE *hSkype, char *pszID, unsigned int *pdwLength);
+int ImoSkype_GetUnreadMsgs(IMOSKYPE *hSkype);
+int ImoSkype_GetAlpha(IMOSKYPE *hSkype);
+
+int ImoSkype_CreateSharedGroup(IMOSKYPE *hSkype, char *pszName);
+int ImoSkype_GroupInvite(IMOSKYPE *hSkype, char *pszGroup, char *pszUser);
+int ImoSkype_GroupKick(IMOSKYPE *hSkype, char *pszGroup, char *pszUser);
+int ImoSkype_GroupTopic(IMOSKYPE *hSkype, char *pszGroup, char *pszTopic);
+int ImoSkype_GroupLeave(IMOSKYPE *hSkype, char *pszGroup);
diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imolib/io_layer.c b/plugins/!NotAdopted/IMO2sProxy/src/imolib/io_layer.c
new file mode 100644
index 0000000000..1e18464682
--- /dev/null
+++ b/plugins/!NotAdopted/IMO2sProxy/src/imolib/io_layer.c
@@ -0,0 +1,175 @@
+/* Module: io_layer.c
+ Purpose: IO Layer for Internet communication using libcurl
+ Author: leecher
+ Date: 30.08.2009
+*/
+#include <curl/curl.h>
+#include <time.h>
+#include <stdlib.h>
+#include <string.h>
+#include "fifo.h"
+#include "io_layer.h"
+
+typedef struct
+{
+ IOLAYER vtbl;
+ CURL *hCurl;
+ TYP_FIFO *hResult;
+ char szErrorBuf[CURL_ERROR_SIZE+1];
+} IOLAYER_INST;
+
+static void IoLayer_Exit (IOLAYER *hPIO);
+static char *IoLayer_Post(IOLAYER *hPIO, char *pszUrl, char *pszPostFields, unsigned int cbPostFields, unsigned int *pdwLength);
+static char *IoLayer_Get(IOLAYER *hPIO, char *pszUrl, unsigned int *pdwLength);
+static void IoLayer_Cancel(IOLAYER *hIO);
+static char *IoLayer_GetLastError(IOLAYER *hIO);
+static char *IoLayer_EscapeString(IOLAYER *hIO, char *pszData);
+static void IoLayer_FreeEscapeString(char *pszData);
+static size_t add_data(char *data, size_t size, size_t nmemb, void *ctx);
+
+// -----------------------------------------------------------------------------
+// Interface
+// -----------------------------------------------------------------------------
+
+IOLAYER *IoLayerCURL_Init(void)
+{
+ IOLAYER_INST *hIO;
+
+ if (!(hIO = calloc(1, sizeof(IOLAYER_INST))))
+ return NULL;
+
+ if (!(hIO->hCurl = curl_easy_init()))
+ {
+ free (hIO);
+ return NULL;
+ }
+
+ if (!(hIO->hResult = Fifo_Init(1024)))
+ {
+ IoLayer_Exit((IOLAYER*)hIO);
+ return NULL;
+ }
+
+ curl_easy_setopt(hIO->hCurl, CURLOPT_USERAGENT, "XMLHttpRequest/1.0");
+ curl_easy_setopt(hIO->hCurl, CURLOPT_HEADER, 0);
+ curl_easy_setopt(hIO->hCurl, CURLOPT_AUTOREFERER, 1);
+// curl_easy_setopt(hRq->hCurl, CURLOPT_RETURNTRANSFER, 1);
+ curl_easy_setopt(hIO->hCurl, CURLOPT_SSL_VERIFYPEER, 0);
+ curl_easy_setopt(hIO->hCurl, CURLOPT_SSL_VERIFYHOST, 0);
+ curl_easy_setopt(hIO->hCurl, CURLOPT_ERRORBUFFER, hIO->szErrorBuf);
+ curl_easy_setopt(hIO->hCurl, CURLOPT_COOKIEFILE, "cookies.txt");
+ curl_easy_setopt(hIO->hCurl, CURLOPT_COOKIEJAR, "cookies.txt");
+ curl_easy_setopt(hIO->hCurl, CURLOPT_WRITEFUNCTION, add_data);
+ curl_easy_setopt(hIO->hCurl, CURLOPT_FILE, hIO);
+
+ // Init Vtbl
+ hIO->vtbl.Exit = IoLayer_Exit;
+ hIO->vtbl.Post = IoLayer_Post;
+ hIO->vtbl.Get = IoLayer_Get;
+ hIO->vtbl.Cancel = IoLayer_Cancel;
+ hIO->vtbl.GetLastError = IoLayer_GetLastError;
+ hIO->vtbl.EscapeString = IoLayer_EscapeString;
+ hIO->vtbl.FreeEscapeString = IoLayer_FreeEscapeString;
+
+ return (IOLAYER*)hIO;
+}
+
+// -----------------------------------------------------------------------------
+
+static void IoLayer_Exit (IOLAYER *hPIO)
+{
+ IOLAYER_INST *hIO = (IOLAYER_INST*)hPIO;
+
+ if (hIO->hCurl) curl_easy_cleanup(hIO->hCurl);
+ if (hIO->hResult) Fifo_Exit(hIO->hResult);
+ free (hIO);
+}
+
+// -----------------------------------------------------------------------------
+
+static char *IoLayer_Post(IOLAYER *hPIO, char *pszUrl, char *pszPostFields, unsigned int cbPostFields, unsigned int *pdwLength)
+{
+ IOLAYER_INST *hIO = (IOLAYER_INST*)hPIO;
+
+ curl_easy_setopt(hIO->hCurl, CURLOPT_POST, 1);
+ curl_easy_setopt(hIO->hCurl, CURLOPT_URL, pszUrl);
+ curl_easy_setopt(hIO->hCurl, CURLOPT_POSTFIELDS, pszPostFields);
+ curl_easy_setopt(hIO->hCurl, CURLOPT_POSTFIELDSIZE, cbPostFields);
+ if (curl_easy_perform(hIO->hCurl)) return NULL;
+ if (!pdwLength)
+ {
+ // Get string
+ Fifo_Add (hIO->hResult, "", 1);
+ return Fifo_Get (hIO->hResult, NULL);
+ }
+ else
+ {
+ // Get binary, return size of buffer
+ *pdwLength = (unsigned int)-1;
+ return Fifo_Get (hIO->hResult, pdwLength);
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+static char *IoLayer_Get(IOLAYER *hPIO, char *pszUrl, unsigned int *pdwLength)
+{
+ IOLAYER_INST *hIO = (IOLAYER_INST*)hPIO;
+
+ curl_easy_setopt(hIO->hCurl, CURLOPT_POST, 0);
+ curl_easy_setopt(hIO->hCurl, CURLOPT_URL, pszUrl);
+ if (curl_easy_perform(hIO->hCurl)) return NULL;
+ if (!pdwLength)
+ {
+ // Get string
+ Fifo_Add (hIO->hResult, "", 1);
+ return Fifo_Get (hIO->hResult, NULL);
+ }
+ else
+ {
+ // Get binary, return size of buffer
+ *pdwLength = (unsigned int)-1;
+ return Fifo_Get (hIO->hResult, pdwLength);
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+static void IoLayer_Cancel(IOLAYER *hIO)
+{
+ // FIXME: Currently not implemented
+}
+
+// -----------------------------------------------------------------------------
+
+static char *IoLayer_GetLastError(IOLAYER *hIO)
+{
+ return ((IOLAYER_INST*)hIO)->szErrorBuf;
+}
+
+// -----------------------------------------------------------------------------
+
+static char *IoLayer_EscapeString(IOLAYER *hIO, char *pszData)
+{
+ return curl_easy_escape(((IOLAYER_INST*)hIO)->hCurl, pszData, 0);
+}
+
+// -----------------------------------------------------------------------------
+
+static void IoLayer_FreeEscapeString(char *pszData)
+{
+ curl_free(pszData);
+}
+
+// -----------------------------------------------------------------------------
+// Static
+// -----------------------------------------------------------------------------
+
+static size_t add_data(char *data, size_t size, size_t nmemb, void *ctx)
+{
+ IOLAYER_INST *hIO = (IOLAYER_INST*)ctx;
+
+ if (Fifo_Add(hIO->hResult, data, size * nmemb)) return size * nmemb;
+ return 0;
+}
+
diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imolib/io_layer.h b/plugins/!NotAdopted/IMO2sProxy/src/imolib/io_layer.h
new file mode 100644
index 0000000000..13e10cf888
--- /dev/null
+++ b/plugins/!NotAdopted/IMO2sProxy/src/imolib/io_layer.h
@@ -0,0 +1,25 @@
+#ifndef _IOLAYER_H_
+#define _IOLAYER_H_
+
+struct _tagIOLAYER;
+typedef struct _tagIOLAYER IOLAYER;
+
+struct _tagIOLAYER
+{
+ void (*Exit) (IOLAYER *hIO);
+
+ char *(*Post) (IOLAYER *hIO, char *pszURL, char *pszPostFields, unsigned int cbPostFields, unsigned int *pdwLength);
+ char *(*Get) (IOLAYER *hIO, char *pszURL, unsigned int *pdwLength);
+ void (*Cancel) (IOLAYER *hIO);
+ char *(*GetLastError) (IOLAYER *hIO);
+ char *(*EscapeString) (IOLAYER *hIO, char *pszData);
+ void (*FreeEscapeString) (char *pszData);
+};
+
+#ifdef WIN32
+IOLAYER *IoLayerW32_Init(void);
+IOLAYER *IoLayerNETLIB_Init(void);
+#endif
+IOLAYER *IoLayerCURL_Init(void);
+
+#endif
diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imolib/io_layer_win32.c b/plugins/!NotAdopted/IMO2sProxy/src/imolib/io_layer_win32.c
new file mode 100644
index 0000000000..1fd425ced7
--- /dev/null
+++ b/plugins/!NotAdopted/IMO2sProxy/src/imolib/io_layer_win32.c
@@ -0,0 +1,440 @@
+/* Module: io_layer_win32.c
+ Purpose: IO Layer for Internet communication using WININET (Win32)
+ Author: leecher
+ Date: 30.08.2009
+*/
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <wininet.h>
+#include <time.h>
+#include <stdlib.h>
+#include <string.h>
+#include "fifo.h"
+#include "io_layer.h"
+
+#ifndef LongToPtr
+#define DWORD_PTR DWORD
+#endif
+
+/* Set this to use asynchronous I/O
+ This is needed as synchronous WININET functions tend to block forever on connection
+ loss or other occasions leading to a deadlock of the whole application
+ */
+#define ASYNC
+#define ASYNC_CONN_TIMEOUT 5000 // Connection timeout in ms
+#define ASYNC_REQ_TIMEOUT 40000 // HttpSendRequest timeout in ms in async mode (Should be at least 30 sec!)
+
+#pragma comment(lib,"wininet.lib")
+
+#define INET_FLAGS INTERNET_FLAG_IGNORE_CERT_CN_INVALID | INTERNET_FLAG_IGNORE_CERT_DATE_INVALID | \
+ INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_UI | \
+ INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_SECURE
+
+typedef struct
+{
+ IOLAYER vtbl;
+ HINTERNET hInet;
+ HINTERNET hRequest;
+#ifdef ASYNC
+ INTERNET_ASYNC_RESULT stAsyncRes;
+ HANDLE hConnectedEvent;
+ HANDLE hRequestCompleteEvent;
+#endif
+ TYP_FIFO *hResult;
+ LPVOID lpErrorBuf;
+} IOLAYER_INST;
+
+static void IoLayer_Exit (IOLAYER *hPIO);
+static char *IoLayer_Post(IOLAYER *hPIO, char *pszURL, char *pszPostFields, unsigned int cbPostFields, unsigned int *pdwLength);
+static char *IoLayer_Get(IOLAYER *hIO, char *pszURL, unsigned int *pdwLength);
+static void IoLayer_Cancel(IOLAYER *hIO);
+static char *IoLayer_GetLastError(IOLAYER *hIO);
+static char *IoLayer_EscapeString(IOLAYER *hPIO, char *pszData);
+static void IoLayer_FreeEscapeString(char *pszData);
+static void FetchLastError (IOLAYER_INST *hIO);
+#ifdef ASYNC
+static void __stdcall Callback(HINTERNET hInternet, DWORD dwContext, DWORD dwInternetStatus,
+ LPVOID lpStatusInfo, DWORD dwStatusInfoLen);
+#endif
+
+// -----------------------------------------------------------------------------
+// Interface
+// -----------------------------------------------------------------------------
+
+IOLAYER *IoLayerW32_Init(void)
+{
+ IOLAYER_INST *hIO;
+
+ if (!(hIO = calloc(1, sizeof(IOLAYER_INST))))
+ return NULL;
+
+ // Init Inet
+ if (!(hIO->hInet = InternetOpen ("Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13",
+ INTERNET_OPEN_TYPE_PRECONFIG, NULL, "<local>",
+#ifdef ASYNC
+ INTERNET_FLAG_ASYNC
+#else
+ 0
+#endif
+ )))
+ {
+ free (hIO);
+ return NULL;
+ }
+
+ if (!(hIO->hResult = Fifo_Init(1024)))
+ {
+ IoLayer_Exit((IOLAYER*)hIO);
+ return NULL;
+ }
+
+#ifdef ASYNC
+ if (InternetSetStatusCallback(hIO->hInet, (INTERNET_STATUS_CALLBACK)&Callback) == INTERNET_INVALID_STATUS_CALLBACK)
+ {
+ IoLayer_Exit((IOLAYER*)hIO);
+ return NULL;
+ }
+
+ hIO->hConnectedEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+ hIO->hRequestCompleteEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+#endif
+
+ //InternetSetCookie ("https://o.imo.im/", "proto", "prpl-skype");
+
+ // Init Vtbl
+ hIO->vtbl.Exit = IoLayer_Exit;
+ hIO->vtbl.Post = IoLayer_Post;
+ hIO->vtbl.Get = IoLayer_Get;
+ hIO->vtbl.Cancel = IoLayer_Cancel;
+ hIO->vtbl.GetLastError = IoLayer_GetLastError;
+ hIO->vtbl.EscapeString = IoLayer_EscapeString;
+ hIO->vtbl.FreeEscapeString = IoLayer_FreeEscapeString;
+
+ return (IOLAYER*)hIO;
+}
+// -----------------------------------------------------------------------------
+
+static void IoLayer_Exit (IOLAYER *hPIO)
+{
+ IOLAYER_INST *hIO = (IOLAYER_INST*)hPIO;
+
+ if (hIO->hInet) InternetCloseHandle (hIO->hInet);
+ if (hIO->lpErrorBuf) LocalFree(hIO->lpErrorBuf);
+ if (hIO->hResult) Fifo_Exit(hIO->hResult);
+
+#ifdef ASYNC
+ if (hIO->hConnectedEvent) CloseHandle (hIO->hConnectedEvent);
+ if (hIO->hRequestCompleteEvent) CloseHandle (hIO->hRequestCompleteEvent);
+#endif
+ free (hIO);
+}
+
+// -----------------------------------------------------------------------------
+
+static char *IoLayer_Post(IOLAYER *hPIO, char *pszURL, char *pszPostFields, unsigned int cbPostFields, unsigned int *pdwLength)
+{
+ IOLAYER_INST *hIO = (IOLAYER_INST*)hPIO;
+ URL_COMPONENTS urlInfo = {0};
+ HINTERNET hUrl;
+ DWORD dwFlags = 0, cbFlags = sizeof(dwFlags), dwRemaining = 0;
+ char szHostName[INTERNET_MAX_HOST_NAME_LENGTH],
+ szURLPath[INTERNET_MAX_URL_LENGTH], *p;
+#ifdef ASYNC
+ INTERNET_BUFFERS InetBuff={0};
+ InetBuff.dwStructSize = sizeof(InetBuff);
+
+ ResetEvent (hIO->hConnectedEvent);
+ ResetEvent (hIO->hRequestCompleteEvent);
+#endif
+
+//OutputDebugString(pszPostFields);
+ urlInfo.dwStructSize = sizeof (URL_COMPONENTS);
+ urlInfo.lpszHostName = szHostName;
+ urlInfo.dwHostNameLength = sizeof(szHostName);
+ urlInfo.lpszUrlPath = szURLPath;
+ urlInfo.dwUrlPathLength = sizeof(szURLPath);
+ if (!InternetCrackUrl(pszURL, strlen(pszURL), 0, &urlInfo)) return NULL;
+ /*
+ if (!pszPostFields)
+ {
+ if (pszPostFields=strchr (pszURL, '?'))
+ cbPostFields = strlen(pszPostFields);
+ }
+ */
+ if (!(hUrl = InternetConnect (hIO->hInet, szHostName,
+ INTERNET_DEFAULT_HTTPS_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, (DWORD_PTR)hIO)))
+ {
+#ifdef ASYNC
+ if (GetLastError() == ERROR_IO_PENDING)
+ {
+ if (WaitForSingleObject(hIO->hConnectedEvent, ASYNC_CONN_TIMEOUT) == WAIT_OBJECT_0)
+ {
+ hUrl = (HINTERNET)hIO->stAsyncRes.dwResult;
+ hIO->stAsyncRes.dwResult = 0;
+ SetLastError(hIO->stAsyncRes.dwError);
+ }
+ }
+ if (!hUrl)
+#endif
+ {
+ FetchLastError (hIO);
+ return NULL;
+ }
+ }
+
+ hIO->hRequest = HttpOpenRequest (hUrl, pszPostFields?"POST":"GET", szURLPath, NULL, "https://imo.im/", NULL,
+ INET_FLAGS, (DWORD_PTR)hIO);
+ if (!hIO->hRequest)
+ {
+#ifdef ASYNC
+ if (GetLastError() == ERROR_IO_PENDING)
+ {
+ if (WaitForSingleObject(hIO->hConnectedEvent, ASYNC_CONN_TIMEOUT) == WAIT_OBJECT_0)
+ {
+ hIO->hRequest = (HINTERNET)hIO->stAsyncRes.dwResult;
+ hIO->stAsyncRes.dwResult = 0;
+ SetLastError(hIO->stAsyncRes.dwError);
+ }
+ }
+ if (!hUrl)
+#endif
+ {
+ FetchLastError (hIO);
+ InternetCloseHandle (hUrl);
+ return NULL;
+ }
+ }
+
+ InternetQueryOption (hIO->hRequest, INTERNET_OPTION_SECURITY_FLAGS, (LPVOID)&dwFlags, &cbFlags);
+ dwFlags |= SECURITY_FLAG_IGNORE_UNKNOWN_CA;
+ InternetSetOption (hIO->hRequest, INTERNET_OPTION_SECURITY_FLAGS, &dwFlags, sizeof (dwFlags));
+
+ /*
+ {
+ char szCookies[4096];
+ DWORD cbCookies, dwIndex=0;
+
+ OutputDebugString ("Sending headers:\n");
+ do
+ {
+ cbCookies=sizeof(szCookies);
+ if (!HttpQueryInfo (hIO->hRequest, HTTP_QUERY_FLAG_REQUEST_HEADERS|HTTP_QUERY_RAW_HEADERS_CRLF, szCookies, &cbCookies, &dwIndex) ||
+ GetLastError() != ERROR_SUCCESS)
+ break;
+ OutputDebugString (szCookies);
+ } while (1);
+ }
+ */
+
+// ASYNC: This needs to block for at least 30 seconds on poll!
+ if (!(HttpSendRequest (hIO->hRequest, "Content-Type: application/x-www-form-urlencoded; charset=UTF-8\r\n"
+ "X-Requested-With: XMLHttpRequest", -1,
+ pszPostFields, cbPostFields)))
+ {
+#ifdef ASYNC
+ BOOL bRes = FALSE;
+
+ if (GetLastError() == ERROR_IO_PENDING)
+ {
+ if (WaitForSingleObject(hIO->hRequestCompleteEvent, ASYNC_REQ_TIMEOUT) == WAIT_OBJECT_0)
+ {
+ bRes = hIO->stAsyncRes.dwResult;
+ hIO->stAsyncRes.dwResult = 0;
+ SetLastError(hIO->stAsyncRes.dwError);
+ }
+ }
+ if (!bRes)
+#endif
+ {
+ FetchLastError (hIO);
+ InternetCloseHandle (hIO->hRequest);
+ hIO->hRequest = NULL;
+ InternetCloseHandle (hUrl);
+ return NULL;
+ }
+ }
+#ifdef ASYNC
+ else WaitForSingleObject(hIO->hRequestCompleteEvent, ASYNC_REQ_TIMEOUT);
+#endif
+
+ /*
+ {
+ char szCookies[4096];
+ DWORD cbCookies, dwIndex=0;
+
+ OutputDebugString ("Received headers:\n");
+ do
+ {
+ cbCookies=sizeof(szCookies);
+ if (!HttpQueryInfo (hIO->hRequest, HTTP_QUERY_FLAG_REQUEST_HEADERS|HTTP_QUERY_RAW_HEADERS_CRLF, szCookies, &cbCookies, &dwIndex) ||
+ GetLastError() != ERROR_SUCCESS)
+ break;
+ OutputDebugString (szCookies);
+ } while (1);
+ }
+ */
+
+#ifdef ASYNC
+ do
+ {
+ if (!InternetQueryDataAvailable (hIO->hRequest, &InetBuff.dwBufferLength, 0, 0))
+ {
+ BOOL bRes = FALSE;
+
+ if (GetLastError() == ERROR_IO_PENDING)
+ {
+ if (WaitForSingleObject(hIO->hRequestCompleteEvent, ASYNC_REQ_TIMEOUT) == WAIT_OBJECT_0)
+ {
+ bRes = hIO->stAsyncRes.dwResult;
+ hIO->stAsyncRes.dwResult = 0;
+ SetLastError(hIO->stAsyncRes.dwError);
+ }
+ }
+ if (!bRes) break;
+ }
+ if (InetBuff.dwBufferLength == 0) break;
+ if (InetBuff.lpvBuffer = Fifo_AllocBuffer (hIO->hResult, InetBuff.dwBufferLength))
+ {
+ if (!InternetReadFileEx (hIO->hRequest, &InetBuff, 0, (DWORD_PTR)hIO))
+ {
+ BOOL bRes=FALSE;
+
+ if (GetLastError() == ERROR_IO_PENDING)
+ {
+ if (WaitForSingleObject(hIO->hRequestCompleteEvent, ASYNC_REQ_TIMEOUT) == WAIT_OBJECT_0)
+ {
+ bRes = hIO->stAsyncRes.dwResult;
+ hIO->stAsyncRes.dwResult = 0;
+ SetLastError(hIO->stAsyncRes.dwError);
+ }
+ }
+ if (!bRes) break;
+ }
+ }
+ }
+ while(InetBuff.dwBufferLength);
+#else
+ while (InternetQueryDataAvailable (hIO->hRequest, &dwRemaining, 0, 0) && dwRemaining > 0)
+ {
+ if (p = Fifo_AllocBuffer (hIO->hResult, dwRemaining))
+ InternetReadFile (hIO->hRequest, p, dwRemaining, &dwRemaining);
+ }
+#endif
+
+ if (!pdwLength)
+ {
+ // Get string
+ Fifo_Add (hIO->hResult, "", 1);
+ p = Fifo_Get (hIO->hResult, NULL);
+ }
+ else
+ {
+ // Get binary, return size of buffer
+ *pdwLength = (unsigned int)-1;
+ p = Fifo_Get (hIO->hResult, pdwLength);
+ }
+ InternetCloseHandle (hIO->hRequest);
+ hIO->hRequest = NULL;
+ InternetCloseHandle (hUrl);
+OutputDebugString(p);
+OutputDebugString("\n");
+ return p;
+}
+
+// -----------------------------------------------------------------------------
+
+static char *IoLayer_Get(IOLAYER *hIO, char *pszURL, unsigned int *pdwLength)
+{
+ return IoLayer_Post (hIO, pszURL, NULL, 0, pdwLength);
+}
+
+// -----------------------------------------------------------------------------
+
+static void IoLayer_Cancel(IOLAYER *hPIO)
+{
+ IOLAYER_INST *hIO = (IOLAYER_INST*)hPIO;
+
+#ifdef ASYNC
+ if (hIO->hRequest)
+ {
+ hIO->stAsyncRes.dwResult = 0;
+ hIO->stAsyncRes.dwError = ERROR_CANCELLED;
+ SetEvent(hIO->hRequestCompleteEvent);
+ }
+#else
+ if (hIO->hRequest && InternetCloseHandle(hIO->hRequest))
+ hIO->hRequest = NULL;
+#endif
+}
+
+// -----------------------------------------------------------------------------
+
+static char *IoLayer_GetLastError(IOLAYER *hIO)
+{
+ return (char*)((IOLAYER_INST*)hIO)->lpErrorBuf;
+}
+
+// -----------------------------------------------------------------------------
+
+static char *IoLayer_EscapeString(IOLAYER *hPIO, char *pszData)
+{
+ IOLAYER_INST *hIO = (IOLAYER_INST*)hPIO;
+ TYP_FIFO *hFifo;
+ char szBuf[8], *pszRet;
+ unsigned char *p;
+
+ if (!(hFifo = Fifo_Init(strlen(pszData)))) return NULL;
+ for (p=pszData; *p; p++)
+ {
+ if (isalnum(*p)) Fifo_Add (hFifo, p, 1);
+ else {
+ wsprintf (szBuf, "%%%02X", *p);
+ Fifo_Add (hFifo, szBuf, 3);
+ }
+ }
+ Fifo_Add (hFifo, "", 1);
+ if (pszRet = Fifo_Get(hFifo, NULL))
+ pszRet = strdup(pszRet);
+ Fifo_Exit(hFifo);
+ return pszRet;
+}
+
+// -----------------------------------------------------------------------------
+
+static void IoLayer_FreeEscapeString(char *pszData)
+{
+ free (pszData);
+}
+
+// -----------------------------------------------------------------------------
+// Static
+// -----------------------------------------------------------------------------
+
+static void FetchLastError (IOLAYER_INST *hIO)
+{
+ if (hIO->lpErrorBuf) LocalFree(hIO->lpErrorBuf);
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL,
+ GetLastError(), MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
+ (LPTSTR)&hIO->lpErrorBuf, 0, NULL);
+}
+
+#ifdef ASYNC
+static void __stdcall Callback(HINTERNET hInternet, DWORD dwContext, DWORD dwInternetStatus,
+ LPVOID lpStatusInfo, DWORD dwStatusInfoLen)
+{
+ IOLAYER_INST *hIO = (IOLAYER_INST*)dwContext;
+
+
+ switch(dwInternetStatus)
+ {
+ case INTERNET_STATUS_HANDLE_CREATED:
+ SetEvent (hIO->hConnectedEvent);
+ break;
+ case INTERNET_STATUS_REQUEST_COMPLETE:
+ hIO->stAsyncRes = *((INTERNET_ASYNC_RESULT *)lpStatusInfo);
+ SetEvent(hIO->hRequestCompleteEvent);
+ break;
+ }
+}
+#endif \ No newline at end of file
diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imolib/skypetst.c b/plugins/!NotAdopted/IMO2sProxy/src/imolib/skypetst.c
new file mode 100644
index 0000000000..5c80533eaf
--- /dev/null
+++ b/plugins/!NotAdopted/IMO2sProxy/src/imolib/skypetst.c
@@ -0,0 +1,211 @@
+/* Module: skypetst.c
+ Purpose: Very simple and straight forward testing application for Skype imo.im service
+ Author: leecher
+ Date: 30.08.2009
+*/
+
+#include <stdio.h>
+#include <signal.h>
+#include <string.h>
+#include <stdlib.h>
+#include <time.h>
+#ifdef WIN32
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#else
+#include <unistd.h>
+#include <pthread.h>
+#endif
+#include "imo_skype.h"
+
+static IMOSKYPE *m_hInst = NULL;
+
+// -----------------------------------------------------------------------------
+// Static
+// -----------------------------------------------------------------------------
+static int StatusCallback (cJSON *pMsg, void *pUser)
+{
+ char *pszName;
+ cJSON *pContent = cJSON_GetArrayItem(pMsg, 0);
+
+ if (!pContent) return;
+ pszName = cJSON_GetObjectItem(pContent,"name")->valuestring;
+
+ if (!strcmp(pszName, "recv_im"))
+ {
+ // I got a message!
+ cJSON *pEdata = cJSON_GetObjectItem(pContent,"edata");
+
+ if (pEdata)
+ {
+ time_t timestamp = (time_t)cJSON_GetObjectItem(pEdata, "timestamp")->valueint;
+ char szTimestamp[32];
+
+ strftime (szTimestamp, sizeof(szTimestamp), "%d.%m.%Y %H.%M.%S", localtime(&timestamp));
+ printf ("[%s] %s: %s\n", szTimestamp,
+ cJSON_GetObjectItem(pEdata, "alias")->valuestring,
+ cJSON_GetObjectItem(pEdata, "msg")->valuestring);
+ }
+ }
+ else if (!strcmp(pszName, "signed_on"))
+ {
+ // I just signed on.
+ cJSON *pEdata = cJSON_GetObjectItem(pContent,"edata");
+ char *pszAlias;
+
+ if (pEdata && (pszAlias = cJSON_GetObjectItem(pEdata, "alias")->valuestring))
+ {
+ printf ("My alias is: %s\n", pszAlias);
+ }
+ }
+ else if (!strcmp(pszName, "buddy_added") || !strcmp(pszName, "buddy_status"))
+ {
+ // Here comes the contact list
+ cJSON *pArray = cJSON_GetObjectItem(pContent,"edata"), *pItem;
+ int i, iCount;
+
+ if (pArray)
+ {
+ for (i=0, iCount = cJSON_GetArraySize(pArray); i<iCount; i++)
+ {
+ if (pItem = cJSON_GetArrayItem(pArray, i))
+ {
+ printf ("%s (%s)\t-\t%s\n",
+ cJSON_GetObjectItem(pItem, "alias")->valuestring,
+ cJSON_GetObjectItem(pItem, "buid")->valuestring,
+ cJSON_GetObjectItem(pItem, "primitive")->valuestring);
+ }
+ }
+ }
+ }
+ else
+ {
+ char *pszMsg = cJSON_Print(pMsg);
+ fprintf (stderr, "%s\n\n", pszMsg);
+ free (pszMsg);
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+
+static void DispatcherThread(void *pDummy)
+{
+ while (1)
+ ImoSkype_Poll(m_hInst);
+}
+
+// -----------------------------------------------------------------------------
+
+#ifdef WIN32
+static HANDLE m_hThread;
+
+static int Dispatcher_Start(void)
+{
+ DWORD ThreadID;
+
+ return (m_hThread=CreateThread(NULL, 0,
+ (LPTHREAD_START_ROUTINE)DispatcherThread, NULL, 0, &ThreadID))!=0;
+
+}
+
+static int Dispatcher_Stop(void)
+{
+ return TerminateThread (m_hThread, 0);
+}
+
+#else
+static pthread_t m_hThread;
+
+static int Dispatcher_Start(void)
+{
+ return pthread_create(&m_hThread, NULL, DispatcherThread, NULL)==0;
+}
+
+static int Dispatcher_Stop(void)
+{
+ if (pthread_cancel(m_hThread))
+ {
+ m_hThread=0;
+ return 1;
+ }
+ return 0;
+}
+#endif
+
+// -----------------------------------------------------------------------------
+// EIP
+// -----------------------------------------------------------------------------
+
+int main(int argc, char **argv)
+{
+ int iRet = -1;
+
+ if (argc<3)
+ {
+ printf ("Usage: %s [username] [password]\n", argv[0]);
+ return -1;
+ }
+
+ /* Logon */
+ if (!(m_hInst = ImoSkype_Init(StatusCallback, NULL)))
+ {
+ fprintf (stderr, "Initializing failed.\n");
+ return -1;
+ }
+ if (ImoSkype_Login(m_hInst, argv[1], argv[2]) == 1)
+ {
+ /* Dispatch loop */
+ char szLine[4096]={0};
+
+ Dispatcher_Start();
+ printf ("> ");
+ fflush(stdout);
+ while (gets(szLine))
+ {
+ if (strcmp(szLine, "exit") == 0) break;
+ if (strcmp(szLine, "help") == 0)
+ {
+ printf ("msg [buddy] [message]\nstatus [available|away|busy|invisible] <Statusmessage>\nexit\n");
+ } else
+ if (strncmp(szLine, "msg ", 4) == 0)
+ {
+ char *pszBuddy;
+
+ if (pszBuddy = strtok (szLine+4, " "))
+ {
+ if (ImoSkype_SendMessage(m_hInst, pszBuddy, pszBuddy+strlen(pszBuddy)+1))
+ printf ("Sent.\n");
+ else
+ printf ("Sending failed: %s.\n", ImoSkype_GetLastError(m_hInst));
+ }
+ } else
+ if (strncmp(szLine, "status ", 7) == 0)
+ {
+ char *pszStatus;
+
+ if (pszStatus = strtok (szLine+7, " "))
+ {
+ if (ImoSkype_SetStatus(m_hInst, pszStatus, pszStatus+strlen(pszStatus)+1))
+ printf ("Status set.\n");
+ else
+ printf ("Setting status failed: %s.\n", ImoSkype_GetLastError(m_hInst));
+ }
+ }
+ memset (szLine, 0, sizeof(szLine));
+ printf ("> ");
+ fflush(stdout);
+ }
+ Dispatcher_Stop();
+ ImoSkype_Logout(m_hInst);
+ }
+ else
+ {
+ fprintf (stderr, "Login failed: %s\n", ImoSkype_GetLastError(m_hInst));
+ return -1;
+ }
+
+ ImoSkype_Exit(m_hInst);
+ return iRet;
+}