diff options
author | Kirill Volinsky <mataes2007@gmail.com> | 2012-12-22 21:43:08 +0000 |
---|---|---|
committer | Kirill Volinsky <mataes2007@gmail.com> | 2012-12-22 21:43:08 +0000 |
commit | 07ddfbd5994267e0f1aba52040a25db90ed8924b (patch) | |
tree | e33f1fe629f4e74b4bb31cbdcf41a2c2451bf599 | |
parent | 3c0a624abd362e45502619648670ace62b2efa3e (diff) |
IMO2sProxy reverted. maybe will be needed later
git-svn-id: http://svn.miranda-ng.org/main/trunk@2809 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
61 files changed, 11550 insertions, 0 deletions
diff --git a/plugins/!NotAdopted/IMO2sProxy/Makefile b/plugins/!NotAdopted/IMO2sProxy/Makefile new file mode 100644 index 0000000000..e83db3ec76 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/Makefile @@ -0,0 +1,11 @@ +.PHONY: all imo2sproxy clean + +all : imo2sproxy + +imo2sproxy: + cd src/imo2skype && make imo2sproxy + cd ../.. + mv src/imo2skype/imo2sproxy bin/ + +clean : + rm imo2sproxy diff --git a/plugins/!NotAdopted/IMO2sProxy/README.txt b/plugins/!NotAdopted/IMO2sProxy/README.txt new file mode 100644 index 0000000000..0bd77dc7c2 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/README.txt @@ -0,0 +1,240 @@ +What is the SkypeProxy for imo.im +---------------------------------- +Back in 2005 when I developed the Skype plugin for Miranda IM, I also developed +a very simple protocol to tunnel the Skype API protocol via a socket. +The reason was, that some users wanted the possibility to run Skype on a +machine different to the machine they are using Miranda IM on. +So to tunnel the Skype API remotely over the network SkypeProxy was built and +was shipped with every Skype plugin build. + +The Skype API plugin for Miranda got more and more functions as the API evolved +and finally as I didn't have enough time to continue development, I handed over +development to user "tweety" who did the later versions. +The SkypeProxy-feature is still present in the current versions, as it is very +simple. It just wraps the communiction layer with the Skype API, therefore +this concept can also be adopted by other Skype-Plugins of other IMs. + +Ever since the first version of Skype plugin, people complained that they had to +install the Skype client on their machine in order to get it to work. +The Skype client was always bloated but it got even worse throughout the years. +I abandoned Skype some time ago, as this application is just consuming far too +many system ressources. However, there are some people that are only using Skype +and I need a way to communicate with them. I'm just interested in the chat +feature, so I only need to send and receive messages from other chat users. +So what can we do about it? + +There were some attempts to reverse-engineer the Skype protocol, but nobody +succeeded so far as the protocol relies heavily on cryptography, is proprietary +closed source and the Skype client itself is heaviely protected agains all +kinds of reverse-engineering (decrypts code on the fly, uses anti-debugging +tricks, etc.). + +However some users recently discovered, that there is a new Web 2.0 service that +makes it possible to do Instant messaging via the web browser using the Ajax +framework. The name of the service is imo.im +imo.im managed to provide basic connectivity to the Skype network via SkypeKit +and the nice thing about their service is, that you don't need to register, you +can just use it out of the box. +However most people are not so excited about IM in a web interface, there are +many features that an IM application provides and that are not so convenient in +a webinterface. But as their service is a webservice using jSON calls, +it is relatively easy to talk to their application server and so users of +Instant messengers that provide Skype protocol support can take advantage of +this for providing basic connectivity to the Skype network for instant messaging +without having to install the bloated Skype client application. +Only instant messaging is possible. In fact there is also alpha-Support for +Voicechat via the imo.im flash application, but this currently doesn't work +reliable due to some Macromedia Flash sandboxing issues. +But I think for most users like me that just want to stay in contact with +other Skype users via chat these functions will be enough. + +So as mentioned above the most generic approach to link imo.im services with an +Instant messanger would be to implement this as a wrapper between imo.im and +the Skype API. This way, we don't need to implement an extra plugin and it is +easily adaptable to Skype plugins of IMs, as you only need to use the +application in Skype API emulator mode. The Skype Plugin of the IM would need to do +proper error handling, but if the plugin is coded well (must be compatible with +Skype Protocol V3), this may even work out of the box. +The plugins mustn't assume that an API call always returns something useful on +every call. +The Skype API Emulation currently only works on Windows, other clients would +need to implement the very simple socket protocol for message exchange. +This application was originally developed to work with Miranda IM, so this IM +is officially supported. + +The application runs on Win32 as well as on Unix, so it's a cross-platform layer +that you can also install on your personal Server. By design, it would be even +able to manage multiple users at once, however this feature is currently not +implemented in the SkypeProxy protocol. Depeding on the user's needs, this +can be implemented, most of the code for this is already there. + +For usage with Miranda IM, a special plugin version was written, which +implementes the layer as a plugin so that it can be loaded into Miranda +and the user doesn't have to run the proxy application seperately. +The plugin version also has the advantage that it is able to communicate +with the Skype plugin directly. + +How does it work +---------------- + +Is described in the preamble, this is just a drop-in replacement for the +communication end point of the Skype API. +The classical communication model for Skype API is: + +[ Skype servers ] <--> [ Skype App ] <--> [ Plugin ] + +The SkypeProxy communication model is: + +[ Skype servers ] <--> [ Skype App ] <--> [ SkypeProxy ] <--> [ Plugin ] + +Now with this Drop-in replacement the communication model is: + +[ Skype servers ] <--> [ imo.im ] <--> [ SkypeProxy ] <--> [ Plugin ] + +The application communicates via a socket connection on Port 1402, like +SkypeProxy does. It uses the imo.im services to connect to the Skype network. + +You also have the possibility to emulate the Skype WIN32-API so that +any plugin can communicate with this application instead of Skype. + +As said, there are 3 connection points to communicate with the plugin: + - WIN32 Skype API via Windowmessages, emulates the real Skype API for + compatibility with any Skype plugin. (Windows) + - Socket communication layer via TCP/IP. (Windows/Unix) + - Internal plugin communcation layer used by the Miranda IM plugin to + communicate with Skype plugin versions starting with 0.0.0.46 + (Windows, Miranda IM plugin only) + +How to compile +-------------- +On Unix type systems, just extract this package and type "make". +After compiling, you will find imo2sproxy in the bin/ directory + +On Windows systems, you will find Visual C 6 project files in the +msvc/ subdirectory. +You have Makefiles available for the appropriate modules: +imoskype.mak - Compiles the imo2sproxy standalone executable +imoproxy.mak - Compiles the Miranda IM Plugin + +There are 4 available Targets: +Win32 Release - 32bit Windows Release version +Win64 Release - 64bit Windows Release version +Win32 Debug - 32bit Windows Debug version +Win64 Debug - 64bit Windows Debug version + +i.e.: +nmake -f imoskype.mak CFG="Win32 Release" + +Requirements +------------ +On Linux, libcurl Libraries and the pthread library for threading +are needed in order to get this to work. +You can download CURL on http://curl.haxx.se/download.html +To install, just use libtool as usual. + +On Windows, WININET is required which should be shipped with +Internet Explorer. So on an average Windows System, you shouldn't +need to install any additional libraries. +Please note, that libcurl IS NO LONGER NEEDED on Windows. + +How to use the commandline version +---------------------------------- +Find the precompiled binaries in the bin/ subdirectory. + +imo2sproxy [-d] [-v [-l <Logfile>]] [-t] [-i] + [-m<s|a>] [-h <Bind to IP>] [-p <Port>] <Username> <Password> + +-v - Verbose mode, log commands to console +-l - Set logfile to redirect verbose log to. +-d - Daemonize (detach from console) +-i - Use interactive mode (starts imo.im flash app upon call) +-t - Ignore server timestamp and use current time for messages +-h - Bind to a specific IP, not to all interfaces (default) +-p - Bind to another port (default: 1401) +-m - Specify connection mode to use: + s Socket mode (SkypeProxy protocol) [default] + a Skype API Emulation via Window messages (real Skype API) + +-ma is only available on Windows systems. + +As there is currently only a single-user implementation of this application, you + need to start imo2sproxy with your Skype username and password as parameters. + +Example for using the socket protocol: +imo2sproxy -d -h 127.0.0.1 myuser mypass + +As soon as the imo2sproxy is running, setup your Skype Plugin to use the +SkypeProxy at the machine you are running imo2sproxy on. +If you are running imo2sproxy locally, enter 127.0.0.1 as IP address. +After setting the SkypeProxy, you have to restart Miranda IM. + +If all works well, you should now be able to use Skype via imo.im. +If it doesn't work, you can use the -v parameter to see what's going on and +if the connection works. + +If it all works well, you can also install imo2sproxy on your machine +as a service using srvany. + +Example for using the Skype API Emulation (win32 only): +imo2sproxy.exe -d -ma myuser mypass + +As soon as the imo2sproxy is running, just try to use your Skype plugin and +see if it connects to the imo2sproxy locally. +Of course, if you have the Skype application installed, you mustn't run +it concurrently with the plugin with this configuration. + +How to use the Miranda plugin +----------------------------- +Copy the imoproxy.dll file to your Miranda Plugins-directory. +As the name starts with i and the the Skype plugin name starts with s, +the imoproxy.dll module is loaded prior to the Skype-Plugin DLL which +is important to work properly if you are using the socket method. + +For older versions of the Skype plugin (prior to 0.0.0.46, which is +currently still beta), you should use the socket communication method: +Configure the plugin DLL in the Options dialog Network/Skype Imoproxy. +Bind to address 127.0.0.1, Port 1401 +Make sure that the Skype Proxy settings in your Skype plugin are the +same. The Skypeproxy-Plugin tries to take care of that. +Enter your Username and Password, set the appropriate options and press +OK. The Skypeproxy-plugin restarts itself. Try to reconnect Skype plugin +and see if it works. +The plugin is still experimental and may contain some bugs or stability +problems, so use with care. It may be harder to hunt down bugs with this +Plugin as its running as Miranda plugin and the only logging facility is +a logfile. So if you want to hunt down bugs, you may be better off with +using the standalone version, however the plugin is a start to make the +use of imo2sproxy easier. Feel free to improve the plugin. + +For Skype plugin versions starting with 0.0.0.46, there is an internal +plugin link facility which makes it easier for the user to setup. +Bascially this should work out of the box, just enter your username and +password in the options dialog and ensute that the internal plugin +link service is active. +It will then automatically register to the Skype plugin. + +Module structure +---------------- + +For the structure of the code-modules, please refer to the +structure.txt document. + +SkypeProxy protocol +------------------- + +Plase download the sourcecode of skypeproxy.c of Miranda IM Skype plugin, it's +all well documented in the .c file. Basically the protocol just consists of: + +[UCHAR: number of bytes to send/receive][<char> Data] + +for every line sent or received. + +Contact +------- +Feel free to contact me regarding this project or if you wish to implement +SkypeProxy protocol in your own Skype-plugin implementation. + +leecher@dose.0wnz.at + + +Vienna, 10/07/2009 diff --git a/plugins/!NotAdopted/IMO2sProxy/bin/setupimo.bat b/plugins/!NotAdopted/IMO2sProxy/bin/setupimo.bat new file mode 100644 index 0000000000..9c765c6479 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/bin/setupimo.bat @@ -0,0 +1,24 @@ +@echo off
+SET /P USER=Skype username:
+IF "%USER%"=="" (
+ echo Username is mandatory, aborting.
+ GOTO fini
+)
+SET /P PASS=Skype password:
+IF "%PASS%"=="" (
+ echo Password is mandatory, aborting.
+ GOTO fini
+)
+SET /P IP=Bind to IP [0.0.0.0]:
+SET /P PORT=Bind to Port [1401]:
+SET /P DAEM=Do you want to daemonize [N]:
+IF /I "%DAEM%" NEQ "Y" SET /P VERB=Do you want verbose command output [N]:
+IF /I "%DAEM%"=="Y" SET CMDLINE=%CMDLINE% -d
+IF /I "%VERB%"=="Y" SET CMDLINE=%CMDLINE% -v
+IF NOT "%IP%"=="" SET CMDLINE=%CMDLINE% -h %IP%
+IF NOT "%PORT%"=="" SET CMDLINE=%CMDLINE% -p %PORT%
+SET CMDLINE=%CMDLINE% %USER% %PASS%
+echo imo2sproxy %CMDLINE% >startimo.bat
+echo startimo.bat created.
+:fini
+pause
diff --git a/plugins/!NotAdopted/IMO2sProxy/msvc/imoproxy.dsp b/plugins/!NotAdopted/IMO2sProxy/msvc/imoproxy.dsp new file mode 100644 index 0000000000..d607233428 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/msvc/imoproxy.dsp @@ -0,0 +1,248 @@ +# Microsoft Developer Studio Project File - Name="imoproxy" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** NICHT BEARBEITEN **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=imoproxy - Win32 Debug
+!MESSAGE Dies ist kein gültiges Makefile. Zum Erstellen dieses Projekts mit NMAKE
+!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und führen Sie den Befehl
+!MESSAGE
+!MESSAGE NMAKE /f "imoproxy.mak".
+!MESSAGE
+!MESSAGE Sie können beim Ausführen von NMAKE eine Konfiguration angeben
+!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel:
+!MESSAGE
+!MESSAGE NMAKE /f "imoproxy.mak" CFG="imoproxy - Win32 Debug"
+!MESSAGE
+!MESSAGE Für die Konfiguration stehen zur Auswahl:
+!MESSAGE
+!MESSAGE "imoproxy - Win32 Release" (basierend auf "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "imoproxy - Win32 Debug" (basierend auf "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=xicl6.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "imoproxy - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "imoproxy_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\src\common" /I "..\src\imolib" /I "..\src\imo2skype" /I "F:\miranda09_src\miranda" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "imoproxy_EXPORTS" /FR /YX /FD /c
+# SUBTRACT CPP /X
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0xc07 /d "NDEBUG"
+# ADD RSC /l 0xc07 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=xilink6.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+
+!ELSEIF "$(CFG)" == "imoproxy - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "imoproxy_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\src\common" /I "..\src\imolib" /I "..\src\imo2skype" /I "F:\miranda09_src\miranda" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "imoproxy_EXPORTS" /FR /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0xc07 /d "_DEBUG"
+# ADD RSC /l 0xc07 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=xilink6.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"F:\miranda09_src\miranda\bin\debug\Plugins\imoproxy.dll" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "imoproxy - Win32 Release"
+# Name "imoproxy - Win32 Debug"
+# Begin Group "Quellcodedateien"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=..\src\imo2skype\avatarlist.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imo2skype\buddylist.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imo2skype\callqueue.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\common\cJSON.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\common\fifo.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imo2skype\imo2skypeapi.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imo2skype\imo2sproxy.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imolib\imo_request.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imolib\imo_skype.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imo2skype\miranda\imoproxy.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imo2skype\miranda\io_layer_netlib.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imolib\io_layer_win32.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\common\memlist.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imo2skype\msgqueue.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imo2skype\queue.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imo2skype\miranda\skypepluginlink.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imo2skype\socksproxy.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imo2skype\w32browser.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imo2skype\w32skypeemu.c
+# End Source File
+# End Group
+# Begin Group "Header-Dateien"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=..\src\imo2skype\buddylist.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imo2skype\callqueue.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\common\cJSON.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\common\fifo.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imo2skype\imo2skypeapi.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imo2skype\imo2sproxy.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imolib\imo_request.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imolib\imo_skype.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imolib\io_layer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\common\memlist.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imo2skype\msgqueue.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imo2skype\queue.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imo2skype\miranda\skypepluginlink.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imo2skype\socksproxy.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imo2skype\w32browser.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imo2skype\w32skypeemu.h
+# End Source File
+# End Group
+# Begin Group "Ressourcendateien"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# Begin Source File
+
+SOURCE=..\src\imo2skype\miranda\res.rc
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/plugins/!NotAdopted/IMO2sProxy/msvc/imoproxy.dsw b/plugins/!NotAdopted/IMO2sProxy/msvc/imoproxy.dsw new file mode 100644 index 0000000000..2d4fb49ab6 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/msvc/imoproxy.dsw @@ -0,0 +1,41 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNUNG: DIESE ARBEITSBEREICHSDATEI DARF NICHT BEARBEITET ODER GELÖSCHT WERDEN!
+
+###############################################################################
+
+Project: "imoproxy"=.\imoproxy.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "imoskype"=.\imoskype.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/plugins/!NotAdopted/IMO2sProxy/msvc/imoproxy.mak b/plugins/!NotAdopted/IMO2sProxy/msvc/imoproxy.mak new file mode 100644 index 0000000000..04b4371268 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/msvc/imoproxy.mak @@ -0,0 +1,221 @@ +!IF "$(CFG)" == ""
+CFG=Win32 Debug
+!MESSAGE Keine Konfiguration angegeben. Win32 Debug wird als Standard verwendet.
+!ENDIF
+
+!IF "$(CFG)" != "Win32 Release" && "$(CFG)" != "Win32 Debug" && "$(CFG)" != "Win64 Release" && "$(CFG)" != "Win64 Debug"
+!MESSAGE Ungültige Konfiguration "$(CFG)" angegeben.
+!MESSAGE Sie können beim Ausführen von NMAKE eine Konfiguration angeben
+!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel:
+!MESSAGE
+!MESSAGE NMAKE /f "imoproxy.mak" CFG="Win32 Debug"
+!MESSAGE
+!MESSAGE Für die Konfiguration stehen zur Auswahl:
+!MESSAGE
+!MESSAGE "Win32 Release"
+!MESSAGE "Win32 Debug"
+!MESSAGE "Win64 Release"
+!MESSAGE "Win64 Debug"
+!MESSAGE
+!ERROR Eine ungültige Konfiguration wurde angegeben.
+!ENDIF
+
+!IF "$(OS)" == "Windows_NT"
+NULL=
+!ELSE
+NULL=nul
+!ENDIF
+
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+LINK32=link.exe
+
+LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /dll /pdb:"$(INTDIR)\imoproxy.pdb" /out:"$(OUTDIR)\imoproxy.dll" /implib:"$(INTDIR)\imoproxy.lib"
+INCLUDES=/I "../src/common" /I "../src/imo2skype" /I "../src/imolib" /I "F:\miranda09_src\miranda"
+
+!IF "$(CFG)" == "Win64 Release"
+OUTDIR=..\bin64
+INTDIR=.\Release64
+CPP_PROJ=/nologo /MT /W3 /O2 $(INCLUDES) /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "imoproxy_EXPORTS" /Fp"$(INTDIR)\imoproxy.pch" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
+LINK32_FLAGS=$(LINK32_FLAGS) /incremental:no
+MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32
+RSC_PROJ=/l 0xc07 /fo"$(INTDIR)\res.res" /d "NDEBUG"
+!ELSEIF "$(CFG)" == "Win32 Release"
+OUTDIR=..\bin
+INTDIR=.\Release
+CPP_PROJ=/nologo /MT /W3 /O2 $(INCLUDES) /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "imoproxy_EXPORTS" /Fp"$(INTDIR)\imoproxy.pch" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
+LINK32_FLAGS=$(LINK32_FLAGS) /incremental:no
+MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32
+RSC_PROJ=/l 0xc07 /fo"$(INTDIR)\res.res" /d "NDEBUG"
+!ELSEIF "$(CFG)" == "Win64 Debug"
+OUTDIR=.\Debug64
+INTDIR=$(OUTDIR)
+CPP_PROJ=/nologo /MTd /W3 /Gm /ZI /Od $(INCLUDES) /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "imoproxy_EXPORTS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\imoproxy.pch" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
+LINK32_FLAGS=$(LINK32_FLAGS) /incremental:yes /debug /pdbtype:sept
+MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32
+RSC_PROJ=/l 0xc07 /fo"$(INTDIR)\res.res" /d "_DEBUG"
+!ELSEIF "$(CFG)" == "Win32 Debug"
+OUTDIR=.\Debug
+INTDIR=$(OUTDIR)
+CPP_PROJ=/nologo /MTd /W3 /Gm /ZI /Od $(INCLUDES) /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "imoproxy_EXPORTS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\imoproxy.pch" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
+LINK32_FLAGS=$(LINK32_FLAGS) /incremental:yes /debug /pdbtype:sept
+MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32
+RSC_PROJ=/l 0xc07 /fo"$(INTDIR)\res.res" /d "_DEBUG"
+!ENDIF
+
+LINK32_OBJS= \
+ "$(INTDIR)\avatarlist.obj" \
+ "$(INTDIR)\buddylist.obj" \
+ "$(INTDIR)\callqueue.obj" \
+ "$(INTDIR)\cJSON.obj" \
+ "$(INTDIR)\fifo.obj" \
+ "$(INTDIR)\imo2skypeapi.obj" \
+ "$(INTDIR)\imo2sproxy.obj" \
+ "$(INTDIR)\imo_request.obj" \
+ "$(INTDIR)\imo_skype.obj" \
+ "$(INTDIR)\imoproxy.obj" \
+ "$(INTDIR)\io_layer_win32.obj" \
+ "$(INTDIR)\io_layer_netlib.obj" \
+ "$(INTDIR)\memlist.obj" \
+ "$(INTDIR)\msgqueue.obj" \
+ "$(INTDIR)\queue.obj" \
+ "$(INTDIR)\socksproxy.obj" \
+ "$(INTDIR)\w32browser.obj" \
+ "$(INTDIR)\w32skypeemu.obj" \
+ "$(INTDIR)\res.res" \
+ "$(INTDIR)\skypepluginlink.obj"
+
+
+ALL : "$(OUTDIR)\imoproxy.dll"
+
+
+CLEAN :
+ -@erase "$(INTDIR)\avatarlist.obj"
+ -@erase "$(INTDIR)\buddylist.obj"
+ -@erase "$(INTDIR)\callqueue.obj"
+ -@erase "$(INTDIR)\cJSON.obj"
+ -@erase "$(INTDIR)\fifo.obj"
+ -@erase "$(INTDIR)\imo2skypeapi.obj"
+ -@erase "$(INTDIR)\imo2sproxy.obj"
+ -@erase "$(INTDIR)\imo_request.obj"
+ -@erase "$(INTDIR)\imo_skype.obj"
+ -@erase "$(INTDIR)\imoproxy.obj"
+ -@erase "$(INTDIR)\io_layer_win32.obj"
+ -@erase "$(INTDIR)\io_layer_netlib.obj"
+ -@erase "$(INTDIR)\memlist.obj"
+ -@erase "$(INTDIR)\msgqueue.obj"
+ -@erase "$(INTDIR)\queue.obj"
+ -@erase "$(INTDIR)\res.res"
+ -@erase "$(INTDIR)\skypepluginlink.obj"
+ -@erase "$(INTDIR)\socksproxy.obj"
+ -@erase "$(INTDIR)\vc60.idb"
+ -@erase "$(INTDIR)\w32browser.obj"
+ -@erase "$(INTDIR)\w32skypeemu.obj"
+ -@erase "$(OUTDIR)\imoproxy.dll"
+ -@erase "$(OUTDIR)\imoproxy.exp"
+ -@erase "$(OUTDIR)\imoproxy.lib"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+"$(OUTDIR)\imoproxy.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+!IF "$(NO_EXTERNAL_DEPS)" != "1"
+!IF EXISTS("imoproxy.dep")
+!INCLUDE "imoproxy.dep"
+!ELSE
+!MESSAGE Warning: cannot find "imoproxy.dep"
+!ENDIF
+!ENDIF
+
+
+SOURCE=..\src\imo2skype\avatarlist.c
+"$(INTDIR)\avatarlist.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+SOURCE=..\src\imo2skype\buddylist.c
+"$(INTDIR)\buddylist.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+SOURCE=..\src\imo2skype\callqueue.c
+"$(INTDIR)\callqueue.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+SOURCE=..\src\common\cJSON.c
+"$(INTDIR)\cJSON.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+SOURCE=..\src\common\fifo.c
+"$(INTDIR)\fifo.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+SOURCE=..\src\imo2skype\imo2skypeapi.c
+"$(INTDIR)\imo2skypeapi.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+SOURCE=..\src\imo2skype\imo2sproxy.c
+"$(INTDIR)\imo2sproxy.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+SOURCE=..\src\imolib\imo_request.c
+"$(INTDIR)\imo_request.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+SOURCE=..\src\imolib\imo_skype.c
+"$(INTDIR)\imo_skype.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+SOURCE=..\src\imo2skype\miranda\imoproxy.c
+"$(INTDIR)\imoproxy.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+SOURCE=..\src\imolib\io_layer_win32.c
+"$(INTDIR)\io_layer_win32.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+SOURCE=..\src\common\memlist.c
+"$(INTDIR)\memlist.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+SOURCE=..\src\imo2skype\msgqueue.c
+"$(INTDIR)\msgqueue.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+SOURCE=..\src\imo2skype\queue.c
+"$(INTDIR)\queue.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+SOURCE=..\src\imo2skype\miranda\skypepluginlink.c
+"$(INTDIR)\skypepluginlink.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+SOURCE=..\src\imo2skype\miranda\io_layer_netlib.c
+"$(INTDIR)\io_layer_netlib.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+SOURCE=..\src\imo2skype\socksproxy.c
+"$(INTDIR)\socksproxy.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+SOURCE=..\src\imo2skype\w32browser.c
+"$(INTDIR)\w32browser.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+SOURCE=..\src\imo2skype\w32skypeemu.c
+"$(INTDIR)\w32skypeemu.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+SOURCE=..\src\imo2skype\miranda\res.rc
+"$(INTDIR)\res.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0xc07 /fo"$(INTDIR)\res.res" /i "..\src\imo2skype\miranda" /d "NDEBUG" $(SOURCE)
+
diff --git a/plugins/!NotAdopted/IMO2sProxy/msvc/imoskype.dsp b/plugins/!NotAdopted/IMO2sProxy/msvc/imoskype.dsp new file mode 100644 index 0000000000..00d324b5b8 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/msvc/imoskype.dsp @@ -0,0 +1,230 @@ +# Microsoft Developer Studio Project File - Name="imoskype" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** NICHT BEARBEITEN **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=imoskype - Win32 Debug
+!MESSAGE Dies ist kein gültiges Makefile. Zum Erstellen dieses Projekts mit NMAKE
+!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und führen Sie den Befehl
+!MESSAGE
+!MESSAGE NMAKE /f "imoskype.mak".
+!MESSAGE
+!MESSAGE Sie können beim Ausführen von NMAKE eine Konfiguration angeben
+!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel:
+!MESSAGE
+!MESSAGE NMAKE /f "imoskype.mak" CFG="imoskype - Win32 Debug"
+!MESSAGE
+!MESSAGE Für die Konfiguration stehen zur Auswahl:
+!MESSAGE
+!MESSAGE "imoskype - Win32 Release" (basierend auf "Win32 (x86) Console Application")
+!MESSAGE "imoskype - Win32 Debug" (basierend auf "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=xicl6.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "imoskype - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "../src/common" /I "../src/imo2skype" /I "../src/imolib" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
+# ADD BASE RSC /l 0xc07 /d "NDEBUG"
+# ADD RSC /l 0xc07 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=xilink6.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib /nologo /subsystem:console /machine:I386 /out:"../bin/imo2sproxy.exe"
+
+!ELSEIF "$(CFG)" == "imoskype - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../src/common" /I "../src/imo2skype" /I "../src/imolib" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD BASE RSC /l 0xc07 /d "_DEBUG"
+# ADD RSC /l 0xc07 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=xilink6.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /out:"Debug/imo2sproxy.exe" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "imoskype - Win32 Release"
+# Name "imoskype - Win32 Debug"
+# Begin Group "Quellcodedateien"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=\temp\debug\imo.im\src\imo2skype\avatarlist.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imo2skype\buddylist.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imo2skype\callqueue.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\common\cJSON.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\common\fifo.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imo2skype\imo2skypeapi.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imo2skype\imo2sproxy.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imolib\imo_request.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imolib\imo_skype.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imolib\io_layer_win32.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imo2skype\main.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\common\memlist.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imo2skype\msgqueue.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imo2skype\queue.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imo2skype\socksproxy.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imo2skype\w32browser.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imo2skype\w32skypeemu.c
+# End Source File
+# End Group
+# Begin Group "Header-Dateien"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=\temp\debug\imo.im\src\imo2skype\avatarlist.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imo2skype\buddylist.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imo2skype\callqueue.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\common\cJSON.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\common\fifo.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imo2skype\imo2skypeapi.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imo2skype\imo2sproxy.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imolib\imo_request.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imolib\imo_skype.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imolib\io_layer.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\common\memlist.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imo2skype\msgqueue.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imo2skype\queue.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imo2skype\socksproxy.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imo2skype\w32browser.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\imo2skype\w32skypeemu.h
+# End Source File
+# End Group
+# Begin Group "Ressourcendateien"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/plugins/!NotAdopted/IMO2sProxy/msvc/imoskype.dsw b/plugins/!NotAdopted/IMO2sProxy/msvc/imoskype.dsw new file mode 100644 index 0000000000..a4c512f5e0 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/msvc/imoskype.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNUNG: DIESE ARBEITSBEREICHSDATEI DARF NICHT BEARBEITET ODER GELÖSCHT WERDEN!
+
+###############################################################################
+
+Project: "imoskype"=.\imoskype.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/plugins/!NotAdopted/IMO2sProxy/msvc/imoskype.mak b/plugins/!NotAdopted/IMO2sProxy/msvc/imoskype.mak new file mode 100644 index 0000000000..be7b29f013 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/msvc/imoskype.mak @@ -0,0 +1,193 @@ +!IF "$(CFG)" == ""
+CFG=Win32 Debug
+!MESSAGE Keine Konfiguration angegeben. Win32 Debug wird als Standard verwendet.
+!ENDIF
+
+!IF "$(CFG)" != "Win32 Release" && "$(CFG)" != "Win32 Debug" && "$(CFG)" != "Win64 Release" && "$(CFG)" != "Win64 Debug"
+!MESSAGE Ungltige Konfiguration "$(CFG)" angegeben.
+!MESSAGE Sie k”nnen beim Ausfhren von NMAKE eine Konfiguration angeben
+!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel:
+!MESSAGE
+!MESSAGE NMAKE /f "imoskype.mak" CFG="Win32 Debug"
+!MESSAGE
+!MESSAGE Fr die Konfiguration stehen zur Auswahl:
+!MESSAGE
+!MESSAGE "Win32 Release"
+!MESSAGE "Win32 Debug"
+!MESSAGE "Win64 Release"
+!MESSAGE "Win64 Debug"
+!MESSAGE
+!ERROR Eine ungltige Konfiguration wurde angegeben.
+!ENDIF
+
+!IF "$(OS)" == "Windows_NT"
+NULL=
+!ELSE
+NULL=nul
+!ENDIF
+
+CPP=cl.exe
+RSC=rc.exe
+LINK32=link.exe
+
+LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib ws2_32.lib /nologo /subsystem:console /pdb:"$(INTDIR)\imo2sproxy.pdb" /out:"$(OUTDIR)/imo2sproxy.exe"
+INCLUDES=/I "../src/common" /I "../src/imo2skype" /I "../src/imolib"
+
+!IF "$(CFG)" == "Win64 Release"
+OUTDIR=..\bin64
+INTDIR=.\Release64
+CPP_PROJ=/nologo /MT /W3 /O2 $(INCLUDES) /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\imoskype.pch" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
+LINK32_FLAGS=$(LINK32_FLAGS) /incremental:no
+!ELSEIF "$(CFG)" == "Win32 Release"
+OUTDIR=..\bin
+INTDIR=.\Release
+CPP_PROJ=/nologo /MT /W3 /O2 $(INCLUDES) /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\imoskype.pch" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
+LINK32_FLAGS=$(LINK32_FLAGS) /incremental:no
+!ELSEIF "$(CFG)" == "Win64 Debug"
+OUTDIR=.\Debug64
+INTDIR=$(OUTDIR)
+CPP_PROJ=/nologo /MTd /W3 /Gm /ZI /Od $(INCLUDES) /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Fp"$(INTDIR)\imoskype.pch" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
+LINK32_FLAGS=$(LINK32_FLAGS) /incremental:yes /debug /pdbtype:sept
+!ELSEIF "$(CFG)" == "Win32 Debug"
+OUTDIR=.\Debug
+INTDIR=$(OUTDIR)
+CPP_PROJ=/nologo /MTd /W3 /Gm /ZI /Od $(INCLUDES) /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Fp"$(INTDIR)\imoskype.pch" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
+LINK32_FLAGS=$(LINK32_FLAGS) /incremental:yes /debug /pdbtype:sept
+!ENDIF
+
+LINK32_OBJS= \
+ "$(INTDIR)\avatarlist.obj" \
+ "$(INTDIR)\buddylist.obj" \
+ "$(INTDIR)\callqueue.obj" \
+ "$(INTDIR)\cJSON.obj" \
+ "$(INTDIR)\fifo.obj" \
+ "$(INTDIR)\imo2skypeapi.obj" \
+ "$(INTDIR)\imo2sproxy.obj" \
+ "$(INTDIR)\imo_request.obj" \
+ "$(INTDIR)\imo_skype.obj" \
+ "$(INTDIR)\io_layer_win32.obj" \
+ "$(INTDIR)\main.obj" \
+ "$(INTDIR)\memlist.obj" \
+ "$(INTDIR)\msgqueue.obj" \
+ "$(INTDIR)\queue.obj" \
+ "$(INTDIR)\socksproxy.obj" \
+ "$(INTDIR)\w32browser.obj" \
+ "$(INTDIR)\w32skypeemu.obj"
+
+ALL : "$(OUTDIR)\imo2sproxy.exe"
+
+CLEAN :
+ -@erase "$(INTDIR)\avatarlist.obj"
+ -@erase "$(INTDIR)\buddylist.obj"
+ -@erase "$(INTDIR)\callqueue.obj"
+ -@erase "$(INTDIR)\cJSON.obj"
+ -@erase "$(INTDIR)\fifo.obj"
+ -@erase "$(INTDIR)\imo2skypeapi.obj"
+ -@erase "$(INTDIR)\imo2sproxy.obj"
+ -@erase "$(INTDIR)\imo_request.obj"
+ -@erase "$(INTDIR)\imo_skype.obj"
+ -@erase "$(INTDIR)\io_layer_win32.obj"
+ -@erase "$(INTDIR)\main.obj"
+ -@erase "$(INTDIR)\memlist.obj"
+ -@erase "$(INTDIR)\msgqueue.obj"
+ -@erase "$(INTDIR)\queue.obj"
+ -@erase "$(INTDIR)\socksproxy.obj"
+ -@erase "$(INTDIR)\vc60.idb"
+ -@erase "$(INTDIR)\w32browser.obj"
+ -@erase "$(INTDIR)\w32skypeemu.obj"
+ -@erase "$(INTDIR)\imo2sproxy.ilk"
+ -@erase "$(INTDIR)\imo2sproxy.pdb"
+ -@erase "$(OUTDIR)\imo2sproxy.exe"
+
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+"$(OUTDIR)\imo2sproxy.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+!IF "$(NO_EXTERNAL_DEPS)" != "1"
+!IF EXISTS("imoskype.dep")
+!INCLUDE "imoskype.dep"
+!ELSE
+!MESSAGE Warning: cannot find "imoskype.dep"
+!ENDIF
+!ENDIF
+
+
+SOURCE=..\src\imo2skype\avatarlist.c
+"$(INTDIR)\avatarlist.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+SOURCE=..\src\imo2skype\buddylist.c
+"$(INTDIR)\buddylist.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+SOURCE=..\src\imo2skype\callqueue.c
+"$(INTDIR)\callqueue.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+SOURCE=..\src\common\cJSON.c
+"$(INTDIR)\cJSON.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+SOURCE=..\src\common\fifo.c
+"$(INTDIR)\fifo.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+SOURCE=..\src\imo2skype\imo2skypeapi.c
+"$(INTDIR)\imo2skypeapi.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+SOURCE=..\src\imo2skype\imo2sproxy.c
+"$(INTDIR)\imo2sproxy.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+SOURCE=..\src\imolib\imo_request.c
+"$(INTDIR)\imo_request.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+SOURCE=..\src\imolib\imo_skype.c
+"$(INTDIR)\imo_skype.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+SOURCE=..\src\imolib\io_layer_win32.c
+"$(INTDIR)\io_layer_win32.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+SOURCE=..\src\imo2skype\main.c
+"$(INTDIR)\main.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+SOURCE=..\src\common\memlist.c
+"$(INTDIR)\memlist.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+SOURCE=..\src\imo2skype\msgqueue.c
+"$(INTDIR)\msgqueue.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+SOURCE=..\src\imo2skype\queue.c
+"$(INTDIR)\queue.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+SOURCE=..\src\imo2skype\socksproxy.c
+"$(INTDIR)\socksproxy.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+SOURCE=..\src\imo2skype\w32browser.c
+"$(INTDIR)\w32browser.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+SOURCE=..\src\imo2skype\w32skypeemu.c
+"$(INTDIR)\w32skypeemu.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
diff --git a/plugins/!NotAdopted/IMO2sProxy/msvc/make.bat b/plugins/!NotAdopted/IMO2sProxy/msvc/make.bat new file mode 100644 index 0000000000..a974f238ab --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/msvc/make.bat @@ -0,0 +1,2 @@ +cmd /c make_w32
+cmd /c make_w64
diff --git a/plugins/!NotAdopted/IMO2sProxy/msvc/make_w32.bat b/plugins/!NotAdopted/IMO2sProxy/msvc/make_w32.bat new file mode 100644 index 0000000000..e5f7eafd2f --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/msvc/make_w32.bat @@ -0,0 +1,7 @@ +call "F:\Programme\Microsoft Visual Studio\VC98\Bin\VCVARS32.BAT"
+nmake -f imoproxy.mak CFG="Win32 Release" clean
+nmake -f imoskype.mak CFG="Win32 Release" clean
+nmake -f imoproxy.mak CFG="Win32 Release"
+nmake -f imoskype.mak CFG="Win32 Release"
+nmake -f imoproxy.mak CFG="Win32 Debug"
+nmake -f imoskype.mak CFG="Win32 Debug"
diff --git a/plugins/!NotAdopted/IMO2sProxy/msvc/make_w64.bat b/plugins/!NotAdopted/IMO2sProxy/msvc/make_w64.bat new file mode 100644 index 0000000000..a97d4a2d7d --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/msvc/make_w64.bat @@ -0,0 +1,5 @@ +call f:\PlatformSDK\SetEnv /X64 /RETAIL
+nmake -f imoproxy.mak CFG="Win64 Release" clean
+nmake -f imoskype.mak CFG="Win64 Release" clean
+nmake -f imoproxy.mak CFG="Win64 Release"
+nmake -f imoskype.mak CFG="Win64 Release"
diff --git a/plugins/!NotAdopted/IMO2sProxy/src/common/cJSON.c b/plugins/!NotAdopted/IMO2sProxy/src/common/cJSON.c new file mode 100644 index 0000000000..72f35f6117 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/common/cJSON.c @@ -0,0 +1,365 @@ +/*
+ Copyright (c) 2009 Dave Gamble
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+*/
+
+// cJSON
+// JSON parser in C.
+
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+#include <stdlib.h>
+#include <float.h>
+#include "cJSON.h"
+#ifdef WIN32
+#define strcasecmp stricmp
+#endif
+
+// Internal constructor.
+static cJSON *cJSON_New_Item() { return (cJSON*)calloc(sizeof(cJSON),1); }
+
+// Delete a cJSON structure.
+void cJSON_Delete(cJSON *c)
+{
+ cJSON *next;
+ while (c)
+ {
+ next=c->next;
+ if (c->child) cJSON_Delete(c->child);
+ if (c->valuestring) free(c->valuestring);
+ if (c->string) free(c->string);
+ free(c);
+ c=next;
+ }
+}
+
+// Parse the input text to generate a number, and populate the result into item.
+static const char *parse_number(cJSON *item,const char *num)
+{
+ double n=0,sign=1,scale=0;int subscale=0,signsubscale=1;
+
+ // Could use sscanf for this?
+ if (*num=='-') sign=-1,num++; // Has sign?
+ if (*num=='0') num++; // is zero
+ if (*num>='1' && *num<='9') do n=(n*10.0)+(*num++ -'0'); while (*num>='0' && *num<='9'); // Number?
+ if (*num=='.') {num++; do n=(n*10.0)+(*num++ -'0'),scale--; while (*num>='0' && *num<='9');} // Fractional part?
+ if (*num=='e' || *num=='E') // Exponent?
+ { num++;if (*num=='+') num++; else if (*num=='-') signsubscale=-1,num++; // With sign?
+ while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0'); // Number?
+ }
+
+ n=sign*n*pow(10.0,(scale+subscale*signsubscale)); // number = +/- number.fraction * 10^+/- exponent
+
+ item->valuedouble=n;
+ item->valueint=(int)n;
+ item->type=cJSON_Number;
+ return num;
+}
+
+// Render the number nicely from the given item into a string.
+static char *print_number(cJSON *item)
+{
+ char *str;
+ double d=item->valuedouble;
+ if (fabs(((double)item->valueint)-d)<=DBL_EPSILON)
+ {
+ str=malloc(21); // 2^64+1 can be represented in 21 chars.
+ sprintf(str,"%d",item->valueint);
+ }
+ else
+ {
+ str=malloc(64); // This is a nice tradeoff.
+ if (fabs(d)<1.0e-6 || fabs(d)>1.0e9) sprintf(str,"%e",d);
+ else sprintf(str,"%f",d);
+ }
+ return str;
+}
+
+// Parse the input text into an unescaped cstring, and populate item.
+static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
+static const char *parse_string(cJSON *item,const char *str)
+{
+ const unsigned char *ptr=str+1;
+ unsigned char *ptr2;
+ char *out;int len=0;unsigned uc;
+ if (*str!='\"') return 0; // not a string!
+
+ while (*ptr!='\"' && *ptr>31 && ++len) if (*ptr++ == '\\') ptr++; // Skip escaped quotes.
+
+ out=(char*)malloc(len+1); // This is how long we need for the string, roughly.
+
+ ptr=str+1;ptr2=out;
+ while (*ptr!='\"' && *ptr>31)
+ {
+ if (*ptr!='\\') *ptr2++=*ptr++;
+ else
+ {
+ ptr++;
+ switch (*ptr)
+ {
+ case 'b': *ptr2++='\b'; break;
+ case 'f': *ptr2++='\f'; break;
+ case 'n': *ptr2++='\n'; break;
+ case 'r': *ptr2++='\r'; break;
+ case 't': *ptr2++='\t'; break;
+ case 'u': // transcode utf16 to utf8. DOES NOT SUPPORT SURROGATE PAIRS CORRECTLY.
+ sscanf(ptr+1,"%4x",&uc); // get the unicode char.
+ len=3;if (uc<0x80) len=1;else if (uc<0x800) len=2;ptr2+=len;
+
+ switch (len) {
+ case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
+ case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
+ case 1: *--ptr2 =(uc | firstByteMark[len]);
+ }
+ ptr2+=len;ptr+=4;
+ break;
+ default: *ptr2++=*ptr; break;
+ }
+ ptr++;
+ }
+ }
+ *ptr2=0;
+ if (*ptr=='\"') ptr++;
+ item->valuestring=out;
+ item->type=cJSON_String;
+ return ptr;
+}
+
+// Render the cstring provided to an escaped version that can be printed.
+static char *print_string_ptr(const char *str)
+{
+ const unsigned char *ptr; unsigned char *ptr2,*out;int len=0;
+
+ ptr=str;while (*ptr && ++len) {if (*ptr<32 || *ptr=='\"' || *ptr=='\\') len++;ptr++;}
+
+ out=(char*)malloc(len+3);
+ ptr2=out;ptr=str;
+ *ptr2++='\"';
+ while (*ptr)
+ {
+ if (*ptr>31 && *ptr!='\"' && *ptr!='\\') *ptr2++=*ptr++;
+ else
+ {
+ *ptr2++='\\';
+ switch (*ptr++)
+ {
+ case '\\': *ptr2++='\\'; break;
+ case '\"': *ptr2++='\"'; break;
+ case '\b': *ptr2++='b'; break;
+ case '\f': *ptr2++='f'; break;
+ case '\n': *ptr2++='n'; break;
+ case '\r': *ptr2++='r'; break;
+ case '\t': *ptr2++='t'; break;
+ default: ptr2--; break; // eviscerate with prejudice.
+ }
+ }
+ }
+ *ptr2++='\"';*ptr2++=0;
+ return out;
+}
+// Invote print_string_ptr (which is useful) on an item.
+static char *print_string(cJSON *item) {return print_string_ptr(item->valuestring);}
+
+// Predeclare these prototypes.
+static const char *parse_value(cJSON *item,const char *value);
+static char *print_value(cJSON *item,int depth);
+static const char *parse_array(cJSON *item,const char *value);
+static char *print_array(cJSON *item,int depth);
+static const char *parse_object(cJSON *item,const char *value);
+static char *print_object(cJSON *item,int depth);
+
+// Parse an object - create a new root, and populate.
+cJSON *cJSON_Parse(const char *value) {cJSON *c=cJSON_New_Item();parse_value(c,value);return c;}
+// Render a cJSON item/entity/structure to text.
+char *cJSON_Print(cJSON *item) {return print_value(item,0);}
+
+// Parser core - when encountering text, process appropriately.
+static const char *parse_value(cJSON *item,const char *value)
+{
+ if (!value) return 0; // Fail on null.
+ if (!strncmp(value,"null",4)) { item->type=cJSON_NULL; return value+4; }
+ if (!strncmp(value,"false",5)) { item->type=cJSON_False; return value+5; }
+ if (!strncmp(value,"true",4)) { item->type=cJSON_True; item->valueint=1; return value+4; }
+ if (*value=='\"') { return parse_string(item,value); }
+ if (*value=='-' || (*value>='0' && *value<='9')) { return parse_number(item,value); }
+ if (*value=='[') { return parse_array(item,value); }
+ if (*value=='{') { return parse_object(item,value); }
+
+ return 0; // failure.
+}
+
+// Render a value to text.
+static char *print_value(cJSON *item,int depth)
+{
+ char *out=0;
+ switch (item->type)
+ {
+ case cJSON_NULL: out=strdup("null"); break;
+ case cJSON_False: out=strdup("false");break;
+ case cJSON_True: out=strdup("true"); break;
+ case cJSON_Number: out=print_number(item);break;
+ case cJSON_String: out=print_string(item);break;
+ case cJSON_Array: out=print_array(item,depth);break;
+ case cJSON_Object: out=print_object(item,depth);break;
+ }
+ return out;
+}
+
+// Utility to jump whitespace and cr/lf
+static const char *skip(const char *in) {while (in && *in<=32) in++; return in;}
+
+// Build an array from input text.
+static const char *parse_array(cJSON *item,const char *value)
+{
+ cJSON *child;
+ if (*value!='[') return 0; // not an array!
+
+ item->type=cJSON_Array;
+ value=skip(value+1);
+ if (*value==']') return value+1; // empty array.
+
+ item->child=child=cJSON_New_Item();
+ value=skip(parse_value(child,skip(value))); // skip any spacing, get the value.
+
+ while (*value==',')
+ {
+ cJSON *new_item;
+ if (!(new_item=cJSON_New_Item())) return 0; // memory fail
+ child->next=new_item;new_item->prev=child;child=new_item;
+ value=skip(parse_value(child,skip(value+1)));
+ }
+
+ if (*value==']') return value+1; // end of array
+ return 0; // malformed.
+}
+
+// Render an array to text
+static char *print_array(cJSON *item,int depth)
+{
+ char *out,*ptr,*ret;int len=5;
+ cJSON *child=item->child;
+
+ out=malloc(len);*out='[';
+ ptr=out+1;*ptr=0;
+ while (child)
+ {
+ ret=print_value(child,depth+1);
+ if (!ret) {free(out);return 0;} // Check for failure!
+ len+=strlen(ret)+3;
+ out=realloc(out,len);
+ ptr=out+strlen(out);
+ ptr+=sprintf(ptr,"%s",ret);
+ if (child->next) {*ptr++=',';*ptr++=' ';*ptr=0;}
+ child=child->next;
+ free(ret);
+ }
+ *ptr++=']';*ptr++=0;
+ return out;
+}
+
+// Build an object from the text.
+static const char *parse_object(cJSON *item,const char *value)
+{
+ cJSON *child;
+ if (*value!='{') return 0; // not an object!
+
+ item->type=cJSON_Object;
+ value=skip(value+1);
+ if (*value=='}') return value+1; // empty array.
+
+ item->child=child=cJSON_New_Item();
+ value=skip(parse_string(child,skip(value)));
+ child->string=child->valuestring;child->valuestring=0;
+ if (*value!=':') return 0; // fail!
+ value=skip(parse_value(child,skip(value+1))); // skip any spacing, get the value.
+
+ while (*value==',')
+ {
+ cJSON *new_item;
+ if (!(new_item=cJSON_New_Item())) return 0; // memory fail
+ child->next=new_item;new_item->prev=child;child=new_item;
+ value=skip(parse_string(child,skip(value+1)));
+ child->string=child->valuestring;child->valuestring=0;
+ if (*value!=':') return 0; // fail!
+ value=skip(parse_value(child,skip(value+1))); // skip any spacing, get the value.
+ }
+
+ if (*value=='}') return value+1; // end of array
+ return 0; // malformed.
+}
+
+// Render an object to text.
+static char *print_object(cJSON *item,int depth)
+{
+ char *out,*ptr,*ret,*str;int len=7;//,i;
+ cJSON *child=item->child;
+
+ depth++;out=malloc(len+depth);*out='{';
+ ptr=out+1;*ptr++=' ';*ptr=0;
+ while (child)
+ {
+ str=print_string_ptr(child->string);
+ if (!str) {free(out);return 0;}
+ ret=print_value(child,depth);
+ if (!ret) {free(out);return 0;} // Check for failure!
+ len+=strlen(ret)+strlen(str)+4+depth;
+ out=realloc(out,len);
+ ptr=out+strlen(out);
+// for (i=0;i<depth;i++) *ptr++='\t';
+ ptr+=sprintf(ptr,"%s",str);
+ *ptr++=':';*ptr++=' ';
+ ptr+=sprintf(ptr,"%s",ret);
+ if (child->next) *ptr++=',';
+ *ptr++=' ';*ptr=0;
+ child=child->next;
+ free(str);free(ret);
+ }
+// for (i=0;i<depth-1;i++) *ptr++='\t';
+ *ptr++='}';*ptr++=0;
+ return out;
+}
+
+// Get Array size/item / object item.
+int cJSON_GetArraySize(cJSON *array) {cJSON *c=array->child;int i=0;while(c)i++,c=c->next;return i;}
+cJSON *cJSON_GetArrayItem(cJSON *array,int item) {cJSON *c=array->child; while (c && item) item--,c=c->next; return c;}
+cJSON *cJSON_GetObjectItem(cJSON *object,const char *string) {cJSON *c=object->child; while (c && strcasecmp(c->string,string)) c=c->next; return c;}
+
+// Utility for array list handling.
+static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;}
+
+// Add item to array/object.
+void cJSON_AddItemToArray(cJSON *array, cJSON *item) {cJSON *c=array->child;if (!c) {array->child=item;} else {while (c && c->next) c=c->next; suffix_object(c,item);}}
+void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item) {if (item->string) free(item->string);item->string=strdup(string);cJSON_AddItemToArray(object,item);}
+
+// Create basic types:
+cJSON *cJSON_CreateNull() {cJSON *item=cJSON_New_Item();item->type=cJSON_NULL;return item;}
+cJSON *cJSON_CreateTrue() {cJSON *item=cJSON_New_Item();item->type=cJSON_True;return item;}
+cJSON *cJSON_CreateFalse() {cJSON *item=cJSON_New_Item();item->type=cJSON_False;return item;}
+cJSON *cJSON_CreateNumber(double num) {cJSON *item=cJSON_New_Item();item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int)num;return item;}
+cJSON *cJSON_CreateString(const char *string) {cJSON *item=cJSON_New_Item();item->type=cJSON_String;item->valuestring=strdup(string);return item;}
+cJSON *cJSON_CreateArray() {cJSON *item=cJSON_New_Item();item->type=cJSON_Array;return item;}
+cJSON *cJSON_CreateObject() {cJSON *item=cJSON_New_Item();item->type=cJSON_Object;return item;}
+
+// Create Arrays:
+cJSON *cJSON_CreateIntArray(int *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
+cJSON *cJSON_CreateFloatArray(float *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
+cJSON *cJSON_CreateDoubleArray(double *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
+cJSON *cJSON_CreateStringArray(const char **strings,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;i<count;i++){n=cJSON_CreateString(strings[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
diff --git a/plugins/!NotAdopted/IMO2sProxy/src/common/cJSON.h b/plugins/!NotAdopted/IMO2sProxy/src/common/cJSON.h new file mode 100644 index 0000000000..debda45bc0 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/common/cJSON.h @@ -0,0 +1,97 @@ +/*
+ Copyright (c) 2009 Dave Gamble
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+*/
+
+#ifndef cJSON__h
+#define cJSON__h
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+// cJSON Types:
+#define cJSON_False 0
+#define cJSON_True 1
+#define cJSON_NULL 2
+#define cJSON_Number 3
+#define cJSON_String 4
+#define cJSON_Array 5
+#define cJSON_Object 6
+
+// The cJSON structure:
+typedef struct cJSON {
+ struct cJSON *next,*prev; // next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem
+ struct cJSON *child; // An array or object item will have a child pointer pointing to a chain of the items in the array/object.
+
+ int type; // The type of the item, as above.
+
+ char *valuestring; // The item's string, if type==cJSON_String
+ int valueint; // The item's number, if type==cJSON_Number
+ double valuedouble; // The item's number, if type==cJSON_Number
+
+ char *string; // The item's name string, if this item is the child of, or is in the list of subitems of an object.
+} cJSON;
+
+// Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished.
+extern cJSON *cJSON_Parse(const char *value);
+// Render a cJSON entity to text for transfer/storage. Free the char* when finished.
+extern char *cJSON_Print(cJSON *item);
+// Delete a cJSON entity and all subentities.
+extern void cJSON_Delete(cJSON *c);
+
+// Returns the number of items in an array (or object).
+extern int cJSON_GetArraySize(cJSON *array);
+// Retrieve item number "item" from array "array". Returns NULL if unsuccessful.
+extern cJSON *cJSON_GetArrayItem(cJSON *array,int item);
+// Get item "string" from object. Case insensitive.
+extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);
+
+// These calls create a cJSON item of the appropriate type.
+extern cJSON *cJSON_CreateNull();
+extern cJSON *cJSON_CreateTrue();
+extern cJSON *cJSON_CreateFalse();
+extern cJSON *cJSON_CreateNumber(double num);
+extern cJSON *cJSON_CreateString(const char *string);
+extern cJSON *cJSON_CreateArray();
+extern cJSON *cJSON_CreateObject();
+
+// These utilities create an Array of count items.
+extern cJSON *cJSON_CreateIntArray(int *numbers,int count);
+extern cJSON *cJSON_CreateFloatArray(float *numbers,int count);
+extern cJSON *cJSON_CreateDoubleArray(double *numbers,int count);
+extern cJSON *cJSON_CreateStringArray(const char **strings,int count);
+
+// Append item to the specified array/object.
+extern void cJSON_AddItemToArray(cJSON *array, cJSON *item);
+extern void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item);
+
+#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull())
+#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
+#define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
+#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
+#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/plugins/!NotAdopted/IMO2sProxy/src/common/fifo.c b/plugins/!NotAdopted/IMO2sProxy/src/common/fifo.c new file mode 100644 index 0000000000..d703ac33d4 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/common/fifo.c @@ -0,0 +1,144 @@ +#include <stdlib.h>
+#include <string.h>
+#include "fifo.h"
+
+struct _tagFIFO
+{
+ unsigned int uiCount;
+ unsigned int uiCapacity;
+ unsigned int uiActInd;
+ char *acStorage;
+};
+
+
+TYP_FIFO *Fifo_Init(unsigned int uiCapacity)
+{
+ TYP_FIFO *pstHandle;
+
+ pstHandle = (TYP_FIFO *)malloc(sizeof(TYP_FIFO));
+ if (!pstHandle) return NULL;
+ pstHandle->uiCount = pstHandle->uiActInd = 0;
+ pstHandle->uiCapacity = uiCapacity;
+ if (uiCapacity == 0)
+ pstHandle->acStorage = NULL;
+ else
+ {
+ pstHandle->acStorage = (char *)malloc(uiCapacity);
+ if (!pstHandle->acStorage)
+ {
+ free (pstHandle);
+ return NULL;
+ }
+ }
+ return pstHandle;
+}
+
+void Fifo_Exit(TYP_FIFO *pstHandle)
+{
+ if (pstHandle->acStorage)
+ free (pstHandle->acStorage);
+ free (pstHandle);
+}
+
+char *Fifo_AllocBuffer(TYP_FIFO *pstHandle, unsigned int uiPCount)
+{
+ unsigned int uiCount = pstHandle->uiCount;
+
+ if (!Fifo_Add (pstHandle, NULL, uiPCount)) return NULL;
+ return &pstHandle->acStorage[pstHandle->uiActInd+uiCount];
+
+}
+
+BOOL Fifo_Add(TYP_FIFO *pstHandle, char *acPBytes, unsigned int uiPCount)
+{
+ unsigned int uiFree;
+
+ if (uiPCount == 0) return TRUE;
+ if (pstHandle->uiCapacity == 0)
+ {
+ if (!(pstHandle->acStorage = (char *)calloc(1, uiPCount)))
+ return FALSE;
+ if (acPBytes)
+ memcpy(pstHandle->acStorage, acPBytes, uiPCount);
+ else
+ memset(pstHandle->acStorage, 0, uiPCount);
+ pstHandle->uiCapacity = pstHandle->uiCount = uiPCount;
+ pstHandle->uiActInd = 0;
+ }
+ else
+ {
+ uiFree = pstHandle->uiCapacity-(pstHandle->uiActInd+pstHandle->uiCount);
+ if (uiFree < uiPCount)
+ {
+ if (pstHandle->uiActInd>=uiPCount && pstHandle->uiActInd*4>pstHandle->uiCount)
+ {
+ memmove(pstHandle->acStorage, pstHandle->acStorage+pstHandle->uiActInd, pstHandle->uiCount);
+ pstHandle->uiActInd = 0;
+ }
+ else
+ {
+ char *acBuf;
+ unsigned int uiNewLen;
+
+ if (pstHandle->uiCapacity*2 <
+ pstHandle->uiCount+pstHandle->uiActInd+uiPCount)
+ uiNewLen = pstHandle->uiCount+pstHandle->uiActInd+uiPCount;
+ else
+ uiNewLen = pstHandle->uiCapacity*2;
+ acBuf = realloc(pstHandle->acStorage, uiNewLen);
+ if (acBuf == NULL) return FALSE;
+ pstHandle->acStorage = acBuf;
+ memset (acBuf+pstHandle->uiCapacity, 0, uiNewLen-pstHandle->uiCapacity);
+ pstHandle->uiCapacity = uiNewLen;
+ }
+ }
+ if (acPBytes)
+ memcpy (&pstHandle->acStorage[pstHandle->uiActInd+pstHandle->uiCount], acPBytes, uiPCount);
+ else
+ memset (&pstHandle->acStorage[pstHandle->uiActInd+pstHandle->uiCount], 0, uiPCount);
+
+ pstHandle->uiCount += uiPCount;
+ }
+
+ return TRUE;
+}
+
+BOOL Fifo_AddString(TYP_FIFO *pstHandle, char *pszString)
+{
+ BOOL bRet;
+
+ while (pstHandle->uiCount && pstHandle->acStorage[pstHandle->uiCount+pstHandle->uiActInd-1]==0)
+ pstHandle->uiCount--;
+ bRet = Fifo_Add (pstHandle, pszString, strlen(pszString)+1);
+ return bRet;
+}
+
+char *Fifo_Get (TYP_FIFO *pstHandle, unsigned int *uiPCount)
+{
+ unsigned int uiCount;
+ char *pRet;
+
+ if (!uiPCount) uiCount = pstHandle->uiCount;
+ else
+ {
+ if (pstHandle->uiCount < *uiPCount)
+ *uiPCount = pstHandle->uiCount;
+ uiCount = *uiPCount;
+ }
+ if (!uiCount) return NULL;
+
+ pRet = &pstHandle->acStorage[pstHandle->uiActInd];
+ pstHandle->uiActInd += uiCount;
+ pstHandle->uiCount -= uiCount;
+ return pRet;
+}
+
+void Fifo_Reset (TYP_FIFO *pstHandle)
+{
+ pstHandle->uiCount = pstHandle->uiActInd = 0;
+}
+
+unsigned int Fifo_Count (TYP_FIFO *pstHandle)
+{
+ return pstHandle->uiCount;
+}
diff --git a/plugins/!NotAdopted/IMO2sProxy/src/common/fifo.h b/plugins/!NotAdopted/IMO2sProxy/src/common/fifo.h new file mode 100644 index 0000000000..0ab9f4f469 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/common/fifo.h @@ -0,0 +1,26 @@ +#ifndef __FIFO_H__
+#define __FIFO_H__
+
+struct _tagFIFO;
+typedef struct _tagFIFO TYP_FIFO;
+
+#ifndef BOOL
+#define BOOL int
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+TYP_FIFO *Fifo_Init(unsigned int uiCapacity);
+void Fifo_Exit(TYP_FIFO *pstHandle);
+char *Fifo_AllocBuffer(TYP_FIFO *pstHandle, unsigned int uiPCount);
+BOOL Fifo_Add(TYP_FIFO *pstHandle, char *acPBytes, unsigned int uiPCount);
+BOOL Fifo_AddString(TYP_FIFO *pstHandle, char *pszString);
+char *Fifo_Get (TYP_FIFO *pstHandle, unsigned int *uiPCount);
+unsigned int Fifo_Count (TYP_FIFO *pstHandle);
+void Fifo_Reset (TYP_FIFO *hFifo);
+
+#endif
diff --git a/plugins/!NotAdopted/IMO2sProxy/src/common/memlist.c b/plugins/!NotAdopted/IMO2sProxy/src/common/memlist.c new file mode 100644 index 0000000000..137a03eeac --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/common/memlist.c @@ -0,0 +1,158 @@ +#include "memlist.h"
+#include <string.h>
+#include <stdlib.h>
+
+struct _tagLIST
+{
+ unsigned int uiCount;
+ unsigned int uiCapacity;
+ void **apStorage;
+};
+
+// -----------------------------------------------------------------------------
+// Interface
+// -----------------------------------------------------------------------------
+
+TYP_LIST *List_Init(unsigned int uiCapacity)
+{
+ TYP_LIST *pstHandle;
+
+ pstHandle = (TYP_LIST *)malloc(sizeof(TYP_LIST));
+
+ if (!pstHandle) return NULL;
+ pstHandle->uiCount = 0;
+ pstHandle->uiCapacity = uiCapacity;
+ if (uiCapacity == 0)
+ pstHandle->apStorage = NULL;
+ else
+ {
+ pstHandle->apStorage = (void **)malloc(sizeof(void *)*uiCapacity);
+ if (!pstHandle->apStorage)
+ {
+ free(pstHandle);
+ return NULL;
+ }
+ }
+ return pstHandle;
+}
+
+// -----------------------------------------------------------------------------
+
+void List_Exit(TYP_LIST *pstHandle)
+{
+ if (pstHandle->apStorage)
+ free (pstHandle->apStorage);
+ free (pstHandle);
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL List_Push(TYP_LIST *pstHandle, void *pItem)
+{
+ return List_InsertElementAt(pstHandle, pItem,pstHandle->uiCount);
+}
+
+// -----------------------------------------------------------------------------
+
+void *List_Pop (TYP_LIST *pstHandle)
+{
+ if (pstHandle->uiCount)
+ return List_RemoveElementAt(pstHandle ,pstHandle->uiCount-1);
+ else return NULL;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL List_ReplaceElementAt(TYP_LIST *pstHandle, void *pItem, unsigned int uiPos)
+{
+ if (uiPos >= pstHandle->uiCount) return NULL;
+ pstHandle->apStorage[uiPos]=pItem;
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL List_InsertElementAt(TYP_LIST *pstHandle, void *pItem, unsigned int uiPos)
+{
+ unsigned int uiStep;
+ void **apNewStorage;
+
+ if (uiPos > pstHandle->uiCount)
+ uiPos = pstHandle->uiCount;
+
+ if (pstHandle->uiCount >= pstHandle->uiCapacity)
+ {
+ uiStep = pstHandle->uiCount*2;
+ if (uiStep < 8) uiStep = 8;
+
+ if (!pstHandle->apStorage)
+ apNewStorage = (void **)malloc(sizeof(void *)*uiStep);
+ else
+ apNewStorage = realloc (pstHandle->apStorage, sizeof(void *)*uiStep);
+ if (!apNewStorage) return FALSE;
+ pstHandle->apStorage = apNewStorage;
+ pstHandle->uiCapacity = uiStep;
+ }
+
+ if (uiPos<pstHandle->uiCount)
+ memmove(&pstHandle->apStorage[uiPos+1], &pstHandle->apStorage[uiPos], (pstHandle->uiCount-uiPos)*sizeof(void*));
+ pstHandle->apStorage[uiPos] = pItem;
+ pstHandle->uiCount++;
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------------
+
+void *List_RemoveElementAt(TYP_LIST *pstHandle, unsigned int uiPos)
+{
+ void *pRet;
+
+ pRet = pstHandle->apStorage[uiPos];
+ if (uiPos<pstHandle->uiCount-1)
+ memmove (&pstHandle->apStorage[uiPos], &pstHandle->apStorage[uiPos+1], (pstHandle->uiCount-uiPos-1)*sizeof(void*));
+ pstHandle->uiCount--;
+ return pRet;
+}
+
+// -----------------------------------------------------------------------------
+
+unsigned int List_Count(TYP_LIST *pstHandle)
+{
+ return pstHandle->uiCount;
+}
+
+// -----------------------------------------------------------------------------
+
+void *List_ElementAt(TYP_LIST *pstHandle,unsigned int uiPos)
+{
+ if (uiPos >= pstHandle->uiCount) return NULL;
+ return pstHandle->apStorage[uiPos];
+}
+
+// -----------------------------------------------------------------------------
+
+void *List_Top(TYP_LIST *pstHandle)
+{
+ if (pstHandle->uiCount)
+ return List_ElementAt (pstHandle, pstHandle->uiCount-1);
+ else return NULL;
+}
+
+// -----------------------------------------------------------------------------
+
+void List_Sort(TYP_LIST *pstHandle, int (*pFunc)(const void*,const void*))
+{
+ qsort(pstHandle->apStorage,pstHandle->uiCount,sizeof(void *),pFunc);
+}
+
+// -----------------------------------------------------------------------------
+
+void List_FreeElements(TYP_LIST *pstHandle)
+{
+ void *pEntry;
+
+ while (pEntry = List_Pop(pstHandle))
+ free (pEntry);
+}
+
+// -----------------------------------------------------------------------------
diff --git a/plugins/!NotAdopted/IMO2sProxy/src/common/memlist.h b/plugins/!NotAdopted/IMO2sProxy/src/common/memlist.h new file mode 100644 index 0000000000..be37bbb723 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/common/memlist.h @@ -0,0 +1,30 @@ +#ifndef __LIST_H__
+#define __LIST_H__
+
+#ifndef BOOL
+#define BOOL int
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+struct _tagLIST;
+typedef struct _tagLIST TYP_LIST;
+
+TYP_LIST *List_Init(unsigned int uiCapacity);
+void List_Exit(TYP_LIST *pstHandle);
+BOOL List_Push(TYP_LIST *pstHandle, void *pItem);
+void *List_Pop (TYP_LIST *pstHandle);
+BOOL List_ReplaceElementAt(TYP_LIST *pstHandle, void *pItem, unsigned int uiPos);
+BOOL List_InsertElementAt(TYP_LIST *pstHandle, void *pItem, unsigned int uiPos);
+void *List_RemoveElementAt(TYP_LIST *pstHandle, unsigned int uiPos);
+unsigned int List_Count(TYP_LIST *pstHandle);
+void *List_ElementAt(TYP_LIST *pstHandle,unsigned int uiPos);
+void *List_Top(TYP_LIST *pstHandle);
+void List_FreeElements(TYP_LIST *pstHandle);
+void List_Sort(TYP_LIST *pstHandle, int (*pFunc)(const void*,const void*));
+
+#endif
diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/Makefile b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/Makefile new file mode 100644 index 0000000000..7e4420f87f --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/Makefile @@ -0,0 +1,19 @@ +CFLAGS = -O0 -g -I../common/ -I../imolib/ -lcurl -lpthread -lm +CC = gcc +COMMON = ../common/fifo.c ../common/cJSON.c ../common/memlist.c +IMOLIB = ../imolib/imo_request.c ../imolib/imo_skype.c ../imolib/io_layer.c +IMO2S = buddylist.c queue.c msgqueue.c imo2skypeapi.c callqueue.c socksproxy.c avatarlist.c +.PHONY: all imo2stest imo2sproxy clean + +all : imo2stest imo2sproxy + +imo2stest: $(COMMON) $(IMO2S) $(IMOLIB) imo2stest.c + $(CC) -o imo2stest $(COMMON) $(IMO2S) $(IMOLIB) imo2stest.c $(CFLAGS) + strip imo2stest + +imo2sproxy: $(COMMON) $(IMO2S) $(IMOLIB) imo2sproxy.c main.c + $(CC) -o imo2sproxy $(COMMON) $(IMO2S) $(IMOLIB) imo2sproxy.c main.c $(CFLAGS) +# strip imo2sproxy + +clean : + rm imo2stest imo2sproxy diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/avatarlist.c b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/avatarlist.c new file mode 100644 index 0000000000..f1c78f0567 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/avatarlist.c @@ -0,0 +1,110 @@ +/* Module: avatarlist.c
+ Purpose: Manages the avatars of your buddies
+ Author: leecher
+ Date: 18.08.2011
+*/
+
+#include <stdlib.h>
+#include <string.h>
+#include "memlist.h"
+#include "avatarlist.h"
+
+static void SetEntry(AVATARENTRY *pEntry, cJSON *pNick);
+
+// -----------------------------------------------------------------------------
+// Interface
+// -----------------------------------------------------------------------------
+
+TYP_LIST *AvatarList_Init(void)
+{
+ TYP_LIST *hList = List_Init(16);
+
+ return hList;
+}
+
+// -----------------------------------------------------------------------------
+
+void AvatarList_Exit(TYP_LIST *hList)
+{
+ AVATARENTRY *pEntry;
+
+ while (pEntry=(AVATARENTRY*)List_Pop(hList))
+ {
+ AvatarList_FreeEntry(pEntry);
+ free (pEntry);
+ }
+ List_Exit(hList);
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL AvatarList_Insert(TYP_LIST *hList, cJSON *pIcon)
+{
+ AVATARENTRY *pEntry;
+
+ if (pEntry=AvatarList_Find (hList, cJSON_GetObjectItem(pIcon, "buid")->valuestring))
+ AvatarList_FreeEntry (pEntry);
+ else
+ {
+ if (!(pEntry = calloc (1, sizeof(AVATARENTRY)))) return FALSE;
+ if (!List_Push(hList, pEntry)) return FALSE;
+ }
+ SetEntry(pEntry, pIcon);
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL AvatarList_Remove(TYP_LIST *hList, AVATARENTRY *pEntry)
+{
+ AVATARENTRY *pListEntry;
+ int i, nCount;
+
+ for (i=0, nCount=List_Count(hList); i<nCount; i++)
+ {
+ pListEntry = List_ElementAt (hList, i);
+ if (pListEntry == pEntry) break;
+ }
+ if (i<nCount)
+ {
+ AvatarList_FreeEntry (pEntry);
+ List_RemoveElementAt(hList, i);
+ free (pEntry);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------------
+
+AVATARENTRY *AvatarList_Find(TYP_LIST *hList, char *pszUser)
+{
+ int i, nCount;
+ AVATARENTRY *pEntry;
+
+ for (i=0, nCount=List_Count(hList); i<nCount; i++)
+ {
+ pEntry = List_ElementAt (hList, i);
+ if (strcmp(pEntry->pszUser, pszUser) == 0)
+ return pEntry;
+ }
+ return NULL;
+}
+
+// -----------------------------------------------------------------------------
+
+void AvatarList_FreeEntry(AVATARENTRY *pEntry)
+{
+ if (pEntry->pszUser) free (pEntry->pszUser);
+ if (pEntry->pszIcon) free (pEntry->pszIcon);
+}
+
+// -----------------------------------------------------------------------------
+// Static
+// -----------------------------------------------------------------------------
+
+static void SetEntry(AVATARENTRY *pEntry, cJSON *pNick)
+{
+ pEntry->pszUser = strdup(cJSON_GetObjectItem(pNick, "buid")->valuestring);
+ pEntry->pszIcon = strdup(cJSON_GetObjectItem(pNick, "icon")->valuestring);
+}
diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/avatarlist.h b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/avatarlist.h new file mode 100644 index 0000000000..6a47ed2fa5 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/avatarlist.h @@ -0,0 +1,16 @@ +#include "cJSON.h"
+#include "memlist.h"
+
+typedef struct
+{
+ char *pszUser;
+ char *pszIcon;
+} AVATARENTRY;
+
+TYP_LIST *AvatarList_Init(void);
+void AvatarList_Exit(TYP_LIST *hList);
+
+BOOL AvatarList_Insert(TYP_LIST *hList, cJSON *pIcon);
+BOOL AvatarList_Remove(TYP_LIST *hList, AVATARENTRY *pEntry);
+AVATARENTRY *AvatarList_Find(TYP_LIST *hList, char *pszUser);
+void AvatarList_FreeEntry(AVATARENTRY *pEntry);
diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/buddylist.c b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/buddylist.c new file mode 100644 index 0000000000..6d228ae4b9 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/buddylist.c @@ -0,0 +1,204 @@ +/* Module: buddylist.c
+ Purpose: Manages your list of buddies in memory
+ Author: leecher
+ Date: 30.08.2009
+*/
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include "memlist.h"
+#include "buddylist.h"
+
+static void SetEntry(NICKENTRY *pEntry, cJSON *pNick);
+
+// -----------------------------------------------------------------------------
+// Interface
+// -----------------------------------------------------------------------------
+
+TYP_LIST *BuddyList_Init(void)
+{
+ TYP_LIST *hList = List_Init(16);
+
+ return hList;
+}
+
+// -----------------------------------------------------------------------------
+
+void BuddyList_Exit(TYP_LIST *hList)
+{
+ NICKENTRY *pEntry;
+
+ while (pEntry=(NICKENTRY*)List_Pop(hList))
+ {
+ BuddyList_FreeEntry(pEntry, TRUE);
+ free (pEntry);
+ }
+ List_Exit(hList);
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL BuddyList_Insert(TYP_LIST *hList, cJSON *pNick)
+{
+ NICKENTRY *pEntry;
+ cJSON *pElem;
+
+ if (pEntry=BuddyList_Find (hList, cJSON_GetObjectItem(pNick, "buid")->valuestring))
+ BuddyList_FreeEntry (pEntry, FALSE);
+ else
+ {
+ if (!(pEntry = calloc (1, sizeof(NICKENTRY)))) return FALSE;
+ if ((pElem=cJSON_GetObjectItem(pNick, "group")) && strcmp(pElem->valuestring, "Skype"))
+ {
+ char szBUID[256];
+ NICKENTRY *pGroup;
+
+ // Buddy Belongs to a chatgroup
+ sprintf (szBUID, "%s;", pElem->valuestring);
+ pGroup = BuddyList_Find (hList, szBUID);
+
+ if (pGroup) // Group not yet created? Shouldn't be the case
+ {
+ if (!pGroup->hGCMembers) pGroup->hGCMembers=List_Init(1);
+ hList = pGroup->hGCMembers;
+ pEntry->pGroup = pGroup;
+ }
+ }
+ if (!List_Push(hList, pEntry)) return FALSE;
+ }
+ SetEntry(pEntry, pNick);
+ pEntry->iBuddyStatus = 3;
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL BuddyList_AddTemporaryUser(TYP_LIST *hList, char *pszUser)
+{
+ NICKENTRY *pEntry;
+
+ if (BuddyList_Find (hList, pszUser)) return TRUE;
+ if (!(pEntry = calloc (1, sizeof(NICKENTRY)))) return FALSE;
+ pEntry->pszUser = strdup(pszUser);
+ pEntry->pszAlias = strdup(pszUser);
+ strcpy (pEntry->szStatus, "OFFLINE");
+ pEntry->iBuddyStatus = 2;
+ return List_Push(hList, pEntry);
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL BuddyList_Remove(TYP_LIST *hList, NICKENTRY *pEntry)
+{
+ NICKENTRY *pListEntry;
+ int i, nCount;
+
+ if (pEntry->pGroup) hList=pEntry->pGroup->hGCMembers;
+ for (i=0, nCount=List_Count(hList); i<nCount; i++)
+ {
+ pListEntry = List_ElementAt (hList, i);
+ if (pListEntry == pEntry) break;
+ }
+ if (i<nCount)
+ {
+ BuddyList_FreeEntry (pEntry, TRUE);
+ List_RemoveElementAt(hList, i);
+ free (pEntry);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------------
+
+NICKENTRY *BuddyList_Find(TYP_LIST *hList, char *pszUser)
+{
+ int i, nCount;
+ NICKENTRY *pEntry;
+
+ for (i=0, nCount=List_Count(hList); i<nCount; i++)
+ {
+ pEntry = List_ElementAt (hList, i);
+ if (strcmp(pEntry->pszUser, pszUser) == 0)
+ return pEntry;
+ else if (pEntry->hGCMembers)
+ {
+ if (pEntry = BuddyList_Find(pEntry->hGCMembers, pszUser))
+ return pEntry;
+ }
+ }
+ return NULL;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL BuddyList_SetStatus(TYP_LIST *hList, cJSON *pNick)
+{
+ NICKENTRY *pEntry;
+
+ if ((pEntry = BuddyList_Find(hList, cJSON_GetObjectItem(pNick, "buid")->valuestring)))
+ {
+ BuddyList_FreeEntry(pEntry, FALSE);
+ SetEntry(pEntry, pNick);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------------
+
+void BuddyList_FreeEntry(NICKENTRY *pEntry, BOOL bFreeGC)
+{
+ if (pEntry->pszAlias)
+ {
+ free (pEntry->pszAlias);
+ pEntry->pszAlias = NULL;
+ }
+ if (pEntry->pszUser)
+ {
+ free (pEntry->pszUser);
+ pEntry->pszUser = NULL;
+ }
+ if (pEntry->pszStatusText)
+ {
+ free(pEntry->pszStatusText);
+ pEntry->pszStatusText = NULL;
+ }
+ if (pEntry->pszDisplay)
+ {
+ free(pEntry->pszDisplay);
+ pEntry->pszDisplay = NULL;
+ }
+ if (bFreeGC && pEntry->hGCMembers)
+ {
+ NICKENTRY *pNick;
+
+ while (pNick=(NICKENTRY*)List_Pop(pEntry->hGCMembers))
+ {
+ BuddyList_FreeEntry(pNick, bFreeGC);
+ free (pNick);
+ }
+ List_Exit (pEntry->hGCMembers);
+ pEntry->hGCMembers = NULL;
+ }
+}
+
+// -----------------------------------------------------------------------------
+// Static
+// -----------------------------------------------------------------------------
+
+static void SetEntry(NICKENTRY *pEntry, cJSON *pNick)
+{
+ cJSON *obj;
+
+ if ((obj=cJSON_GetObjectItem(pNick, "alias")) && obj->valuestring)
+ pEntry->pszAlias = strdup(obj->valuestring);
+ pEntry->pszUser = strdup(cJSON_GetObjectItem(pNick, "buid")->valuestring);
+ if ((obj=cJSON_GetObjectItem(pNick, "status")) && obj->valuestring)
+ pEntry->pszStatusText = strdup(obj->valuestring);
+ if ((obj=cJSON_GetObjectItem(pNick, "primitive")) && obj->valuestring)
+ strcpy (pEntry->szStatus, obj->valuestring);
+ if ((obj=cJSON_GetObjectItem(pNick, "display")) && obj->valuestring)
+ pEntry->pszDisplay = strdup(obj->valuestring);
+}
diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/buddylist.h b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/buddylist.h new file mode 100644 index 0000000000..3774ef3e5e --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/buddylist.h @@ -0,0 +1,28 @@ +#include "cJSON.h"
+#include "memlist.h"
+
+struct tag_nickentry;
+typedef struct tag_nickentry NICKENTRY;
+
+struct tag_nickentry
+{
+ char *pszUser;
+ char *pszStatusText;
+ char szStatus[16];
+ char *pszAlias;
+ char *pszDisplay; // Display name, on Groupchat it is topic
+ int iBuddyStatus;
+ TYP_LIST *hGCMembers; // List of groupchat members, if this is a groupchat
+ NICKENTRY *pGroup; // Uplink to Chatgroup, if Groupchat-Member
+};
+
+TYP_LIST *BuddyList_Init(void);
+void BuddyList_Exit(TYP_LIST *hList);
+
+BOOL BuddyList_Insert(TYP_LIST *hList, cJSON *pNick);
+BOOL BuddyList_AddTemporaryUser(TYP_LIST *hList, char *pszUser);
+BOOL BuddyList_Remove(TYP_LIST *hList, NICKENTRY *pEntry);
+NICKENTRY *BuddyList_Find(TYP_LIST *hList, char *pszUser);
+BOOL BuddyList_SetStatus(TYP_LIST *hList, cJSON *pNick);
+void BuddyList_FreeEntry(NICKENTRY *pEntry, BOOL bFreeGC);
+#define BuddyList_IsGroupchat(pEntry) (pEntry->hGCMembers!=NULL)
diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/callqueue.c b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/callqueue.c new file mode 100644 index 0000000000..f579eb184e --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/callqueue.c @@ -0,0 +1,95 @@ +/* Module: callqueue.c
+ Purpose: Queue for incoming calls
+ Author: leecher
+ Date: 02.09.2009
+
+ Fixme: Sort on insert, do a binary search instead of iterating list.
+*/
+
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "callqueue.h"
+
+static volatile unsigned int m_uMsgNr=0;
+static void FreeEntry(void *pPEntry);
+
+// -----------------------------------------------------------------------------
+// Interface
+// -----------------------------------------------------------------------------
+
+TYP_LIST *CallQueue_Init(void)
+{
+ TYP_LIST *hList = List_Init(16);
+
+ return hList;
+}
+
+// -----------------------------------------------------------------------------
+
+void CallQueue_Exit(TYP_LIST *hList)
+{
+ Queue_Exit (hList, FreeEntry);
+}
+
+// -----------------------------------------------------------------------------
+
+CALLENTRY *CallQueue_Insert(TYP_LIST *hList, cJSON *pNick, int iDirection)
+{
+ CALLENTRY *pEntry;
+ cJSON *pStream, *pVal, *pPipe;
+
+ if (!(pEntry = Queue_InsertEntry(hList, sizeof(CALLENTRY), ++m_uMsgNr,
+ FreeEntry))) return NULL;
+ pEntry->pszUser = strdup(cJSON_GetObjectItem(pNick, "buid")->valuestring);
+ time (&pEntry->timestamp);
+ strcpy (pEntry->szStatus, "RINGING");
+
+ if (pStream = cJSON_GetObjectItem(pNick, "send_stream"))
+ {
+ strcpy (pEntry->szSendStream, pStream->valuestring);
+ if (pStream = cJSON_GetObjectItem(pNick, "recv_stream"))
+ strcpy (pEntry->szRecvStream, pStream->valuestring);
+ }
+ else
+ {
+ // Copy pipe to Call object
+ if (pPipe = cJSON_GetObjectItem(pNick, "pipe"))
+ {
+ if (pVal = cJSON_GetObjectItem(pPipe, "ip"))
+ strncpy (pEntry->szIP, pVal->valuestring, sizeof(pEntry->szIP));
+ if (pVal = cJSON_GetObjectItem(pPipe, "conv"))
+ strncpy (pEntry->szConv, pVal->valuestring, sizeof(pEntry->szConv));
+ if (pVal = cJSON_GetObjectItem(pPipe, "role"))
+ pEntry->iRole = pVal->valueint;
+ }
+ }
+ pEntry->iDirection = iDirection;
+ return pEntry;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL CallQueue_Remove(TYP_LIST *hList, unsigned int uMsgNr)
+{
+ return Queue_Remove (hList, uMsgNr, FreeEntry);
+}
+
+// -----------------------------------------------------------------------------
+
+CALLENTRY *CallQueue_Find(TYP_LIST *hList, unsigned int uMsgNr)
+{
+ return (CALLENTRY*)Queue_Find(hList, uMsgNr);
+}
+
+// -----------------------------------------------------------------------------
+// Static
+// -----------------------------------------------------------------------------
+
+static void FreeEntry(void *pPEntry)
+{
+ CALLENTRY *pEntry = (CALLENTRY*)pPEntry;
+
+ free (pEntry->pszUser);
+}
+
diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/callqueue.h b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/callqueue.h new file mode 100644 index 0000000000..0c4fcfd2cf --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/callqueue.h @@ -0,0 +1,32 @@ +#include "cJSON.h"
+#include "queue.h"
+#include <time.h>
+
+#define CALL_INCOMING 0
+#define CALL_OUTGOING 1
+
+typedef struct
+{
+ QUEUEHDR hdr;
+ char *pszUser;
+ char szStatus[16];
+
+ char szSendStream[18];
+ char szRecvStream[18];
+
+ char szConv[18];
+ char szIP[16];
+ int iRole;
+
+ char szCallFile[256];
+ void *hCallWnd;
+ int iDirection;
+ time_t timestamp;
+} CALLENTRY;
+
+TYP_LIST *CallQueue_Init(void);
+void CallQueue_Exit(TYP_LIST *hList);
+
+CALLENTRY *CallQueue_Insert(TYP_LIST *hList, cJSON *pNick, int iDirection);
+BOOL CallQueue_Remove(TYP_LIST *hList, unsigned int uCallNr);
+CALLENTRY *CallQueue_Find(TYP_LIST *hList, unsigned int uCallNr);
diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/crash.c b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/crash.c new file mode 100644 index 0000000000..91ad90032e --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/crash.c @@ -0,0 +1,295 @@ +#include <imagehlp.h>
+#include <malloc.h>
+#pragma comment (lib, "imagehlp.lib")
+
+#define MAXNAMELEN 1024
+#define HEXDUMP_BREAK 16
+
+void HexDump(char *pszOutput, PBYTE pData, int cbLength, BOOL bShow)
+{
+ char *pszLastLine;
+ int i;
+
+ *pszOutput=0;
+ pszLastLine = pszOutput;
+ for (i=0; i<cbLength; i++)
+ {
+ if (i%HEXDUMP_BREAK == 0)
+ {
+ if (i>=HEXDUMP_BREAK)
+ {
+ int j;
+
+ strcat (pszOutput, " ");
+ for (j=i-HEXDUMP_BREAK; j<i; j++) sprintf (pszOutput+strlen(pszOutput), "%c", pData[j]);
+ }
+ sprintf (pszOutput+strlen(pszOutput), "\r\n");
+ if (bShow) LOG (("\t%s", pszLastLine));
+ if (i==0) *pszOutput=0;
+ pszLastLine = pszOutput+strlen(pszOutput);
+ }
+ sprintf (pszOutput+strlen(pszOutput), "%02X ", pData[i]);
+ if (i == cbLength-1)
+ {
+ int j;
+
+ for (j=0; j<HEXDUMP_BREAK - i%HEXDUMP_BREAK - 1; j++) sprintf (pszOutput+strlen(pszOutput), " ");
+ sprintf (pszOutput+strlen(pszOutput), " ");
+ for (j=i-i%HEXDUMP_BREAK; j<i; j++) sprintf (pszOutput+strlen(pszOutput), "%c",
+ (isprint(pData[j]) && pData[j]!=0x0D && pData[j]!=0x0A && pData[j]!=0x09)?pData[j]:'.');
+ if (bShow) LOG (("\t%s", pszLastLine));
+ }
+ }
+}
+
+
+void CrashDumpMem (DWORD dwBase, char *pszName, DWORD dwDwords)
+{
+ int cbLength = sizeof(DWORD) * dwDwords;
+ PBYTE mem = (PBYTE)alloca (cbLength*2);
+ SYSTEM_INFO sysInfo;
+ SIZE_T read=0;
+
+ dwBase &= ~3;
+
+ dwBase-=cbLength; cbLength*=2;
+ GetSystemInfo(&sysInfo);
+ if (dwBase < (DWORD)sysInfo.lpMinimumApplicationAddress || dwBase > (DWORD)sysInfo.lpMaximumApplicationAddress)
+ return;
+
+ if (ReadProcessMemory (GetCurrentProcess(), (PVOID)dwBase, mem, cbLength, &read))
+ {
+ char *pszHexdump = (char *)alloca (((cbLength/HEXDUMP_BREAK)+1)*81);
+
+ LOG (("Memory dump for %s:\n", pszName));
+ HexDump (pszHexdump, mem, read, TRUE);
+ LOG (("\n"));
+ }
+}
+
+
+BOOL ShowThreadStack (HANDLE hThread, CONTEXT *c)
+{
+ STACKFRAME stFrame={0};
+ DWORD dwSymOptions, dwFrameNum=0, dwMachine, dwOffsetFromSym=0;
+ IMAGEHLP_LINE Line={0};
+ IMAGEHLP_MODULE Module={0};
+ HANDLE hProcess = GetCurrentProcess();
+ BYTE pbSym[sizeof(IMAGEHLP_SYMBOL) + MAXNAMELEN];
+ IMAGEHLP_SYMBOL *pSym = (IMAGEHLP_SYMBOL *)&pbSym;
+ char szUndecName[MAXNAMELEN], szUndecFullName[MAXNAMELEN];
+
+ /*
+ if ( ! GetThreadContext( hThread, &c ) )
+ {
+ SetError (NULL, NULL, 0);
+ LOG (("Cannot get thread context%d\n", GetLastError()));
+ return FALSE;
+ }
+ */
+ LOG (("Please wait...\n"));
+ if (!SymInitialize (hProcess, NULL, TRUE))
+ {
+ LOG (("Cannot initialize symbol engine (%08X)\n", GetLastError()));
+ return FALSE;
+ }
+
+ dwSymOptions = SymGetOptions();
+ dwSymOptions |= SYMOPT_LOAD_LINES;
+ dwSymOptions &= ~SYMOPT_UNDNAME;
+ SymSetOptions (dwSymOptions);
+
+ stFrame.AddrPC.Mode = AddrModeFlat;
+ dwMachine = IMAGE_FILE_MACHINE_I386;
+ stFrame.AddrPC.Offset = c->Eip;
+ stFrame.AddrStack.Offset = c->Esp;
+ stFrame.AddrStack.Mode = AddrModeFlat;
+ stFrame.AddrFrame.Offset = c->Ebp;
+ stFrame.AddrFrame.Mode = AddrModeFlat;
+
+ Module.SizeOfStruct = sizeof(Module);
+ Line.SizeOfStruct = sizeof(Module);
+
+ LOG (("\n--# FV EIP----- RetAddr- FramePtr StackPtr Symbol\n"));
+ do
+ {
+ if (!StackWalk (dwMachine, hProcess, hThread, &stFrame, &c, NULL, &SymFunctionTableAccess, &SymGetModuleBase, NULL))
+ break;
+
+ LOG (( "\n%3d %c%c %08lx %08lx %08lx %08lx ",
+ dwFrameNum, stFrame.Far? 'F': '.', stFrame.Virtual? 'V': '.',
+ stFrame.AddrPC.Offset, stFrame.AddrReturn.Offset,
+ stFrame.AddrFrame.Offset, stFrame.AddrStack.Offset ));
+
+ if (stFrame.AddrPC.Offset == 0)
+ {
+ LOG (( "(-nosymbols-)\n" ));
+ }
+ else
+ { // we seem to have a valid PC
+ if (!SymGetSymFromAddr (hProcess, stFrame.AddrPC.Offset, &dwOffsetFromSym, pSym))
+ {
+ if (GetLastError() != 487)
+ {
+ LOG (("Unable to get symbol from addr (%08X)", GetLastError()));
+ }
+ }
+ else
+ {
+ UnDecorateSymbolName (pSym->Name, szUndecName, MAXNAMELEN, UNDNAME_NAME_ONLY );
+ UnDecorateSymbolName (pSym->Name, szUndecFullName, MAXNAMELEN, UNDNAME_COMPLETE );
+ LOG (("%s", szUndecName));
+ if (dwOffsetFromSym) LOG ((" %+ld bytes", (long)dwOffsetFromSym));
+ LOG (("\n Sig: %s\n Decl: %s\n", pSym->Name, szUndecFullName));
+ }
+
+ if (!SymGetLineFromAddr (hProcess, stFrame.AddrPC.Offset, &dwOffsetFromSym, &Line))
+ {
+ if (GetLastError() != 487)
+ {
+ LOG (("Unable to get line from addr (%08X)", GetLastError()));
+ }
+ }
+ else
+ {
+ LOG ((" Line: %s(%lu) %+ld bytes\n", Line.FileName, Line.LineNumber, dwOffsetFromSym ));
+ }
+
+ if (!SymGetModuleInfo (hProcess, stFrame.AddrPC.Offset, &Module))
+ {
+ if (GetLastError() != 487)
+ {
+ LOG (("Unable to get module info (%08X)", GetLastError()));
+ }
+ }
+ else
+ {
+ char ty[80];
+
+ switch ( Module.SymType )
+ {
+ case SymNone:
+ strcpy( ty, "-nosymbols-" );
+ break;
+ case SymCoff:
+ strcpy( ty, "COFF" );
+ break;
+ case SymCv:
+ strcpy( ty, "CV" );
+ break;
+ case SymPdb:
+ strcpy( ty, "PDB" );
+ break;
+ case SymExport:
+ strcpy( ty, "-exported-" );
+ break;
+ case SymDeferred:
+ strcpy( ty, "-deferred-" );
+ break;
+ case SymSym:
+ strcpy( ty, "SYM" );
+ break;
+ default:
+ _snprintf( ty, sizeof ty, "symtype=%ld", (long) Module.SymType );
+ break;
+
+ }
+ LOG (( " Mod: %s[%s], base: %08lxh\n", Module.ModuleName, Module.ImageName, Module.BaseOfImage ));
+ LOG (( " Sym: type: %s, file: %s\n", ty, Module.LoadedImageName));
+ }
+ }
+ dwFrameNum++;
+ } while (stFrame.AddrReturn.Offset);
+ SymCleanup (hProcess);
+ return TRUE;
+}
+
+
+LONG Win32FaultHandler(struct _EXCEPTION_POINTERS * ExInfo)
+{
+ char *FaultTx;
+ int wsFault = ExInfo->ExceptionRecord->ExceptionCode;
+ PVOID CodeAdress = ExInfo->ExceptionRecord->ExceptionAddress;
+#ifndef USE_GUI
+ char choice[10];
+#endif
+
+ if (//IsDebuggerPresent() ||
+ ExInfo->ExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT)
+ return EXCEPTION_CONTINUE_SEARCH;
+
+ switch(ExInfo->ExceptionRecord->ExceptionCode)
+ {
+ case EXCEPTION_ACCESS_VIOLATION : FaultTx = "ACCESS VIOLATION"; break;
+ case EXCEPTION_DATATYPE_MISALIGNMENT : FaultTx = "DATATYPE MISALIGNMENT"; break;
+ case EXCEPTION_FLT_DIVIDE_BY_ZERO : FaultTx = "FLT DIVIDE BY ZERO"; break;
+ case EXCEPTION_ARRAY_BOUNDS_EXCEEDED : FaultTx = "ARRAY BOUNDS EXCEEDED"; break;
+ case EXCEPTION_FLT_DENORMAL_OPERAND : FaultTx = "FLT DENORMAL OPERAND"; break;
+ case EXCEPTION_FLT_INEXACT_RESULT : FaultTx = "FLT INEXACT RESULT"; break;
+ case EXCEPTION_FLT_INVALID_OPERATION : FaultTx = "FLT INVALID OPERATION"; break;
+ case EXCEPTION_FLT_OVERFLOW : FaultTx = "FLT OVERFLOW"; break;
+ case EXCEPTION_FLT_STACK_CHECK : FaultTx = "FLT STACK CHECK"; break;
+ case EXCEPTION_FLT_UNDERFLOW : FaultTx = "FLT UNDERFLOW"; break;
+ case EXCEPTION_ILLEGAL_INSTRUCTION : FaultTx = "ILLEGAL INSTRUCTION"; break;
+ case EXCEPTION_IN_PAGE_ERROR : FaultTx = "IN PAGE ERROR"; break;
+ case EXCEPTION_INT_DIVIDE_BY_ZERO : FaultTx = "INT DEVIDE BY ZERO"; break;
+ case EXCEPTION_INT_OVERFLOW : FaultTx = "INT OVERFLOW"; break;
+ case EXCEPTION_INVALID_DISPOSITION : FaultTx = "INVALID DISPOSITION"; break;
+ case EXCEPTION_NONCONTINUABLE_EXCEPTION:FaultTx= "NONCONTINUABLE EXCEPTION"; break;
+ case EXCEPTION_PRIV_INSTRUCTION : FaultTx = "PRIVILEGED INSTRUCTION";break;
+ case EXCEPTION_SINGLE_STEP : FaultTx = "SINGLE STEP"; break;
+ case EXCEPTION_STACK_OVERFLOW : FaultTx = "STACK OVERFLOW"; break;
+ case DBG_CONTROL_C : return EXCEPTION_EXECUTE_HANDLER;
+ default : FaultTx = "(unknown)"; break;
+ }
+
+ LOG (("****************************************************\n"));
+ LOG (("*** A Program Fault occurred: ***\n"));
+ LOG (("*** Error code %08X: %-24s***\n", wsFault, FaultTx));
+ LOG (("****************************************************\n"));
+ LOG (("*** Address: %08X Flags: %08X ***\n", (int)CodeAdress, ExInfo->ExceptionRecord->ExceptionFlags));
+ LOG (("*** EAX=%08X EBX=%08X ECX=%08X ***\n", ExInfo->ContextRecord->Eax, ExInfo->ContextRecord->Ebx, ExInfo->ContextRecord->Ecx));
+ LOG (("*** EDX=%08X EBP=%08X ESI=%08X ***\n", ExInfo->ContextRecord->Edx, ExInfo->ContextRecord->Ebp, ExInfo->ContextRecord->Esi));
+ LOG (("*** EDI=%08X ESP=%08X EIP=%08X ***\n", ExInfo->ContextRecord->Edi, ExInfo->ContextRecord->Esp, ExInfo->ContextRecord->Eip));
+ LOG (("****************************************************\n"));
+ CrashDumpMem (ExInfo->ContextRecord->Eax, "EAX", 8);
+ CrashDumpMem (ExInfo->ContextRecord->Ebx, "EBX", 8);
+ CrashDumpMem (ExInfo->ContextRecord->Ecx, "ECX", 8);
+ CrashDumpMem (ExInfo->ContextRecord->Edx, "EDX", 8);
+ CrashDumpMem (ExInfo->ContextRecord->Esi, "ESI", 8);
+ CrashDumpMem (ExInfo->ContextRecord->Edi, "EDI", 8);
+ CrashDumpMem (ExInfo->ContextRecord->Esp, "ESP", 32);
+ CrashDumpMem (ExInfo->ContextRecord->Ebp, "EBP", 32);
+ {
+ OSVERSIONINFO ov={0};
+
+ ov.dwOSVersionInfoSize=sizeof(ov);
+ GetVersionEx (&ov);
+ LOG (("Target platform: Microsoft Windows NT %d.%d Build %d %s\n", ov.dwMajorVersion, ov.dwMinorVersion,
+ ov.dwBuildNumber, ov.szCSDVersion));
+ }
+
+ //LogStackFrames(CodeAddress, (char *)ExInfo->ContextRecord->Ebp);
+ ShowThreadStack (GetCurrentThread(), ExInfo->ContextRecord);
+
+#ifdef USE_GUI
+ if (MessageBox(NULL, "A Program Fault occurred. Do you want to continue execution (not recommended)?", "CRASH!", MB_ICONERROR | MB_YESNO) == IDYES)
+#else
+ printf ("Do you want to continue program execution (not recommended) [y/N]? ");
+ fgets(choice, sizeof(choice) - 1, stdin);
+
+ if (*choice=='y' || *choice=='Y')
+#endif
+ {
+ ExInfo->ContextRecord->Eip++;
+ return EXCEPTION_CONTINUE_EXECUTION;
+ }
+ return EXCEPTION_EXECUTE_HANDLER;
+}
+
+void Crash_Init(void)
+{
+//#ifndef _DEBUG
+ SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER) Win32FaultHandler);
+//#endif
+}
diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/crash.h b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/crash.h new file mode 100644 index 0000000000..7f2d790f6c --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/crash.h @@ -0,0 +1 @@ +void Crash_Init(void);
diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/imo2skypeapi.c b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/imo2skypeapi.c new file mode 100644 index 0000000000..de0a9b4028 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/imo2skypeapi.c @@ -0,0 +1,1959 @@ +/* Module: imo2skypeapi.c
+ Purpose: Simple wrapper for imo.im Webservice to SKYPE API to maintain compatibility with Skype-Plugins
+ Author: leecher
+ Date: 30.08.2009
+*/
+
+#define VOICECALL_VERSION 1221873445
+#define IVC_VERSION "98a29c15e305a7af04634b03d5e1425d6c67806e"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <time.h>
+#ifdef WIN32
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <process.h>
+#include <direct.h>
+#include "w32browser.h"
+#define strcasecmp stricmp
+#define strncasecmp strnicmp
+#define thread_t HANDLE
+#define vsnprintf _vsnprintf
+#define GWL_PINST 0
+#define GWL_ORIGWPRC 1*sizeof(PVOID)
+#else
+#define thread_t pthread_t
+#include <unistd.h>
+#include <pthread.h>
+#endif
+#include "imo_skype.h"
+#include "imo_request.h"
+#include "fifo.h"
+#include "memlist.h"
+#include "buddylist.h"
+#include "avatarlist.h"
+#include "msgqueue.h"
+#include "callqueue.h"
+#include "imo2skypeapi.h"
+
+typedef struct
+{
+ char *pszImoStat;
+ char *pszSkypeStat;
+} STATMAP;
+
+struct _tagIMOSAPI
+{
+ IMOSKYPE *hInst;
+ NICKENTRY myUser;
+ char *pszPass;
+ char *pszLogBuf;
+ char *pszClientName;
+ int cbBuf;
+ TYP_LIST *hBuddyList;
+ TYP_LIST *hAvatarList;
+ TYP_LIST *hMsgQueue;
+ TYP_LIST *hCallQueue;
+ int iProtocol;
+ int iLoginStat;
+ IMO2SCB Callback;
+ void *pUser;
+ FILE *fpLog;
+ thread_t hThread;
+ int bFriendsPending;
+ int iFlags;
+ int iShuttingDown;
+ volatile time_t tSetMoodText;
+ char *pszCmdID;
+ char *pszBuddiesToAdd;
+};
+
+static STATMAP m_stMap[] =
+{
+ {"available", "ONLINE"},
+ {"available", "SKYPEME"},
+ {"offline", "OFFLINE"},
+ {"away", "AWAY"},
+ {"busy", "DND"},
+ {"busy", "NA"},
+ {"invisible", "INVISIBLE"}
+};
+
+static int StartCallSWF (IMOSAPI *pInst, CALLENTRY *pCall);
+static int StatusCallback (cJSON *pMsg, void *pUser);
+static void DispatcherThread(void *pUser);
+static int Dispatcher_Start(IMOSAPI *pInst);
+static int Dispatcher_Stop(IMOSAPI *pInst);
+static void Send(IMOSAPI *pInst, const char *pszMsg, ...);
+static void HandleMessage(IMOSAPI *pInst, char *pszMsg);
+
+
+// -----------------------------------------------------------------------------
+// Interface
+// -----------------------------------------------------------------------------
+
+IMOSAPI *Imo2S_Init(IMO2SCB Callback, void *pUser, int iFlags)
+{
+ IMOSAPI *pInst = calloc(1, sizeof(IMOSAPI));
+
+ if (!pInst) return NULL;
+ if (!(pInst->pszLogBuf = malloc(pInst->cbBuf=512)) ||
+ !(pInst->hInst = ImoSkype_Init(StatusCallback, pInst)) ||
+ !(pInst->hBuddyList = BuddyList_Init()) ||
+ !(pInst->hAvatarList = AvatarList_Init()) ||
+ !(pInst->hMsgQueue = MsgQueue_Init()) ||
+#ifdef WIN32
+ ((iFlags & IMO2S_FLAG_ALLOWINTERACT) && W32Browser_Init(0)==-1) ||
+#endif
+ !(pInst->hCallQueue = CallQueue_Init()))
+ {
+ Imo2S_Exit(pInst);
+ return NULL;
+ }
+ pInst->Callback = Callback;
+ pInst->pUser = pUser;
+ pInst->iFlags = iFlags;
+ pInst->myUser.iBuddyStatus = 3;
+ strcpy (pInst->myUser.szStatus, "OFFLINE");
+ pInst->iProtocol = 3;
+ return pInst;
+}
+
+// -----------------------------------------------------------------------------
+
+void Imo2S_SetLog (IMOSAPI *pInst, FILE *fpLog)
+{
+ pInst->fpLog = fpLog;
+}
+
+// -----------------------------------------------------------------------------
+
+void Imo2S_Exit (IMOSAPI *pInst)
+{
+ if (!pInst) return;
+ pInst->iShuttingDown = 1;
+ if (pInst->fpLog) fprintf (pInst->fpLog, "Imo2S_Exit()\n");
+ if (pInst->iLoginStat == 1) Imo2S_Logout(pInst);
+ if (pInst->hInst) ImoSkype_Exit(pInst->hInst);
+ if (pInst->hBuddyList) BuddyList_Exit(pInst->hBuddyList);
+ if (pInst->hAvatarList) AvatarList_Exit(pInst->hAvatarList);
+ if (pInst->hMsgQueue) MsgQueue_Exit(pInst->hMsgQueue);
+ if (pInst->hCallQueue) CallQueue_Exit(pInst->hCallQueue);
+ if (pInst->pszPass) free (pInst->pszPass);
+ if (pInst->pszLogBuf) free(pInst->pszLogBuf);
+ if (pInst->pszClientName) free(pInst->pszClientName);
+#ifdef WIN32
+ if (pInst->iFlags & IMO2S_FLAG_ALLOWINTERACT) W32Browser_Exit();
+#endif
+ BuddyList_FreeEntry(&pInst->myUser, TRUE);
+ memset (pInst, 0, sizeof(IMOSAPI));
+ free (pInst);
+}
+
+// -----------------------------------------------------------------------------
+
+int Imo2S_Login (IMOSAPI *pInst, char *pszUser, char *pszPass, char **ppszError)
+{
+ // In case this module is passing in the original values...
+ char *pszLocalUser, *pszLocalPass;
+
+ if (pInst->fpLog) fprintf (pInst->fpLog, "Imo2S_Login(%s, ****)\n", pszUser);
+ if (pInst->iLoginStat == 1) return pInst->iLoginStat;
+ if (!pInst->hInst) pInst->hInst=ImoSkype_Init(StatusCallback, pInst);
+ pszLocalUser = strdup(pszUser);
+ if (pInst->myUser.pszUser) free (pInst->myUser.pszUser);
+ pInst->myUser.pszUser = pszLocalUser;
+ pszLocalPass = strdup(pszPass);
+ if (pInst->pszPass) free (pInst->pszPass);
+ pInst->pszPass = pszLocalPass;
+ Send(pInst, "CONNSTATUS CONNECTING");
+ pInst->iLoginStat = ImoSkype_Login(pInst->hInst, pszLocalUser, pszLocalPass);
+ if (pInst->iLoginStat == 1)
+ {
+ ImoSkype_GetUnreadMsgs(pInst->hInst);
+ if (IMO_API_VERSION > 0) ImoSkype_GetAlpha(pInst->hInst);
+ Dispatcher_Start(pInst);
+ }
+ else
+ if (ppszError) *ppszError = ImoSkype_GetLastError(pInst->hInst);
+ return pInst->iLoginStat;
+}
+
+// -----------------------------------------------------------------------------
+
+void Imo2S_Logout(IMOSAPI *pInst)
+{
+ if (pInst->fpLog) fprintf (pInst->fpLog, "Imo2S_Logout()\n");
+ Dispatcher_Stop(pInst);
+ if (ImoSkype_Logout(pInst->hInst) == 1)
+ {
+ pInst->iLoginStat = 0;
+ strcpy (pInst->myUser.szStatus, "OFFLINE");
+ }
+
+
+ // If we relogin, user information won't be re-propagated if we
+ // reuse the same connection. Therefore also dispose the connection
+ // to imo.im service (wouldn't be necessary, but to ensure proper
+ // repropagation of contacts on login, we have to do it, sorry)
+ if (!pInst->iShuttingDown)
+ {
+ ImoSkype_Exit(pInst->hInst);
+ pInst->hInst = NULL;
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+int Imo2S_Send (IMOSAPI *pInst, char *pszMsg)
+{
+ char *pszDup = strdup(pszMsg);
+ char *pszRealMsg = pszMsg;
+
+ if (*pszRealMsg=='#')
+ {
+ char *p;
+ if (p = strchr (pszRealMsg, ' ')) pszRealMsg=p+1;
+ }
+ if (pInst->fpLog) fprintf (pInst->fpLog, "Imo2S_Send(%s)\n", pszMsg);
+ if (strlen(pszRealMsg)>15 && strncasecmp (pszRealMsg, "SET ", 4)== 0 &&
+ (strncasecmp (pszRealMsg+4, "USERSTATUS", 10)==0 ||
+ strncasecmp (pszRealMsg+4, "CONNSTATUS", 10)==0))
+ {
+// if (pInst->fpLog) fprintf (pInst->fpLog, "Imo2S_Send: iLoginStat = %d\n",
+// pInst->iLoginStat);
+ if (pInst->iLoginStat == 0)
+ {
+ if (pInst->myUser.pszUser && pInst->pszPass && strncasecmp (pszRealMsg+15, "OFFLINE", 7))
+ {
+ Imo2S_Login(pInst, pInst->myUser.pszUser, pInst->pszPass, NULL);
+ }
+ }
+ else
+ {
+ HandleMessage (pInst, pszDup);
+ if (strncasecmp (pszRealMsg+15, "OFFLINE", 7) == 0)
+ Imo2S_Logout(pInst);
+ free (pszDup);
+ return 0;
+ }
+ }
+ if (pInst->iLoginStat != 1) return -1;
+ HandleMessage(pInst, pszDup);
+ free (pszDup);
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+// Static
+// -----------------------------------------------------------------------------
+
+
+static int StatusCallback (cJSON *pMsg, void *pUser)
+{
+ char *pszName;
+ BOOL bAdded;
+ cJSON *pContent, *pProto;
+ IMOSAPI *pInst = (IMOSAPI*)pUser;
+ int m, iSize = cJSON_GetArraySize(pMsg);
+
+ if (pInst->fpLog)
+ {
+ char *pszMsg = cJSON_Print(pMsg);
+ fprintf (pInst->fpLog, "Imo2S::StatusCallback():%s\n", pszMsg);
+ free(pszMsg);
+ }
+
+ for (m=0; m<iSize; m++)
+ {
+ pContent = cJSON_GetArrayItem(pMsg, m);
+ if (!pContent) return 0;
+ pszName = cJSON_GetObjectItem(pContent,"name")->valuestring;
+
+ if ((pProto = cJSON_GetObjectItem(pContent,"proto")) && strcasecmp (pProto->valuestring, "prpl-skype"))
+ continue;
+
+ if (!strcmp(pszName, "recv_im"))
+ {
+ // I got a message!
+ cJSON *pEdata = cJSON_GetObjectItem(pContent,"edata");
+
+ if (pEdata)
+ {
+ MSGENTRY *pMsg;
+
+ // imo.im sometimes seems to send information about messages you sent yourself.
+ // We have to ignore them.
+ if (strcmp(cJSON_GetObjectItem(pEdata, "buid")->valuestring, pInst->myUser.pszUser) &&
+ (pMsg = MsgQueue_Insert(pInst->hMsgQueue, pEdata)))
+ {
+ if (pInst->iFlags & IMO2S_FLAG_CURRTIMESTAMP) time(&pMsg->timestamp);
+ Send(pInst, "%sMESSAGE %d STATUS %s", pInst->iProtocol>=3?"CHAT":"",
+ pMsg->hdr.uMsgNr, pMsg->szStatus);
+ }
+ }
+ }
+ else if (!strcmp(pszName, "signed_on"))
+ {
+ // I just signed on.
+ cJSON *pEdata = cJSON_GetObjectItem(pContent,"edata");
+ char *pszAlias;
+
+ Send(pInst, "CONNSTATUS ONLINE");
+ if (strcmp(pInst->myUser.szStatus, "OFFLINE")==0)
+ strcpy (pInst->myUser.szStatus, "ONLINE");
+ Send(pInst, "USERSTATUS %s", pInst->myUser.szStatus);
+ if (pEdata && (pszAlias = cJSON_GetObjectItem(pEdata, "alias")->valuestring))
+ {
+ pInst->myUser.pszAlias = strdup(pszAlias);
+ }
+ Send(pInst, "CURRENTUSERHANDLE %s", cJSON_GetObjectItem(pContent, "uid")->valuestring);
+ }
+ else if (!strcmp(pszName, "buddy_icon"))
+ {
+ // Here are the Avatars for the buddies
+ //We have to track them in a seperate list as the buddies may get populated lateron
+ 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))
+ AvatarList_Insert(pInst->hAvatarList, pItem);
+ }
+ }
+ }
+ else if (!strcmp(pszName, "disconnect"))
+ {
+ // I got disconnected (wrong user/pass?)
+ cJSON *pEdata = cJSON_GetObjectItem(pContent,"edata");
+ //char *pszMsg;
+
+ Send(pInst, "CONNSTATUS OFFLINE");
+ Send(pInst, "USERSTATUS OFFLINE");
+ strcpy (pInst->myUser.szStatus, "OFFLINE");
+ /*
+ if (pEdata && (pszMsg = cJSON_GetObjectItem(pEdata, "msg")->valuestring))
+ {
+ if (strcmp(pszMsg, "uidpassword")==0)
+ {
+ fprintf (stderr, "Invalid username / password combination!\n");
+ }
+ }
+ */
+ }
+ else if ((bAdded = !strcmp(pszName, "buddy_added")) || !strcmp(pszName, "buddy_status"))
+ {
+ // Here comes the contact list
+ cJSON *pArray = cJSON_GetObjectItem(pContent,"edata"), *pItem;
+ char *pszLastBUID = NULL, *pszLastGroup = NULL;
+ int i, iCount;
+
+ if (pArray)
+ {
+ TYP_LIST *hListMemToAdd = NULL;
+
+ for (i=0, iCount = cJSON_GetArraySize(pArray); i<iCount; i++)
+ {
+ if (pItem = cJSON_GetArrayItem(pArray, i))
+ {
+ char szQuery[256];
+ char *pszBUID = cJSON_GetObjectItem(pItem, "buid")->valuestring;
+ cJSON *pGroup = cJSON_GetObjectItem(pItem, "group");
+ cJSON *pDisplay = cJSON_GetObjectItem(pItem, "display");
+
+ if (bAdded)
+ {
+ /*
+ if (BuddyList_Find (pInst->hBuddyList, cJSON_GetObjectItem(pItem, "buid")->valuestring))
+ bAdded=FALSE;
+ else
+ */
+ BuddyList_Insert(pInst->hBuddyList, pItem);
+ }
+ else BuddyList_SetStatus(pInst->hBuddyList, pItem);
+
+ if ((!pGroup || strcmp(pGroup->valuestring, "Skype")==0 ||
+ strcmp(pGroup->valuestring, "Offline")==0) &&
+ !pDisplay)
+ {
+ // Normal user, not groupchat, so output this
+ sprintf (szQuery, "GET USER %s ONLINESTATUS", pszBUID);
+ HandleMessage (pInst, szQuery);
+ sprintf (szQuery, "GET USER %s MOOD_TEXT", pszBUID);
+ HandleMessage (pInst, szQuery);
+ }
+ else
+ {
+ // Groupchat created/added
+ MSGENTRY * pMsgEntry = NULL;
+
+ if (bAdded && pInst->pszBuddiesToAdd)
+ {
+ // Process pending ADDs
+ char *pTok, szQuery[256];
+
+ for (pTok = strtok(pInst->pszBuddiesToAdd, ", "); pTok; pTok=strtok(NULL, ", "))
+ ImoSkype_GroupInvite(pInst->hInst, pszBUID, pTok);
+ free (pInst->pszBuddiesToAdd);
+ pInst->pszBuddiesToAdd = NULL;
+ sprintf (szQuery, "GET CHAT %s STATUS", pszBUID);
+ HandleMessage (pInst, szQuery);
+ }
+ else
+ {
+ if (bAdded || !pDisplay)
+ {
+ char szQuery[256], szGroup[256]={0};
+ NICKENTRY *pChat;
+
+ if (pGroup) sprintf (szGroup, "%s;", pGroup->valuestring);
+ if (pGroup && (pChat=BuddyList_Find(pInst->hBuddyList, szGroup)) &&
+ pChat->hGCMembers)
+ {
+ sprintf (szQuery, "GET CHAT %s MEMBERS", szGroup);
+ HandleMessage (pInst, szQuery);
+ }
+ else
+ {
+ if ((bAdded || !pChat) && (!pszLastBUID || strcmp(pszLastBUID, pszBUID)) &&
+ (!pszLastGroup || (pGroup && strcmp(pszLastGroup, pGroup->valuestring))))
+ {
+ if (!hListMemToAdd) hListMemToAdd=List_Init(0);
+ List_Push(hListMemToAdd, pItem);
+ pszLastBUID = pszBUID;
+ if (pGroup) pszLastGroup = pGroup->valuestring;
+ }
+ }
+ }
+ /*
+ else
+ {
+ pMsgEntry = MsgQueue_AddEvent (pInst->hMsgQueue, pszBUID, "SETTOPIC");
+ if (pDisplay->valuestring) pMsgEntry->pszMessage = strdup(pDisplay->valuestring);
+ }
+ */
+ if (pMsgEntry)
+ Send(pInst, "%sMESSAGE %d STATUS %s", pInst->iProtocol>=3?"CHAT":"",
+ pMsgEntry->hdr.uMsgNr, pMsgEntry->szStatus);
+
+ }
+ }
+ }
+ }
+ if (hListMemToAdd)
+ {
+ int nCount;
+
+ for (i=0, nCount=List_Count(hListMemToAdd); i<nCount; i++)
+ {
+ cJSON *pItem = List_ElementAt(hListMemToAdd, i);
+ cJSON *pInviter = cJSON_GetObjectItem(pItem, "inviter");
+ MSGENTRY *pMsgEntry;
+
+ if (pMsgEntry = MsgQueue_AddEvent (pInst->hMsgQueue, cJSON_GetObjectItem(pItem, "buid")->valuestring, "ADDEDMEMBERS")) // MULTI_SUBSCRIBED
+ {
+ if (pInviter) pMsgEntry->pszAuthor = strdup(pInviter->valuestring);
+ Send(pInst, "%sMESSAGE %d STATUS %s", pInst->iProtocol>=3?"CHAT":"",
+ pMsgEntry->hdr.uMsgNr, pMsgEntry->szStatus);
+ }
+ }
+
+ List_Exit(hListMemToAdd);
+ hListMemToAdd = NULL;
+ }
+ if (bAdded && pInst->bFriendsPending)
+ {
+ char szMsg[]="SEARCH FRIENDS";
+ pInst->bFriendsPending = 0;
+ HandleMessage (pInst, szMsg);
+ }
+ }
+ }
+ else if (!strcmp(pszName, "buddy_removed"))
+ {
+ // 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++)
+ {
+ char *pszUser;
+ cJSON *pBuid;
+
+ if (iCount==1) pItem=pArray; else pItem = cJSON_GetArrayItem(pArray, i);
+ if (pItem && (pBuid = cJSON_GetObjectItem(pItem, "buid")) &&
+ (pszUser = pBuid->valuestring))
+ {
+ NICKENTRY *pNick = BuddyList_Find (pInst->hBuddyList, pszUser);
+
+ if (pNick && pNick->pGroup)
+ {
+ MSGENTRY *pMsg = MsgQueue_AddEvent (pInst->hMsgQueue, pszUser, "KICKED");
+ cJSON *pUid = cJSON_GetObjectItem(pContent,"uid");
+ if (pUid) pMsg->pszAuthor = strdup(pUid->valuestring);
+ Send(pInst, "%sMESSAGE %d STATUS %s", pInst->iProtocol>=3?"CHAT":"",
+ pMsg->hdr.uMsgNr, pMsg->szStatus);
+ }
+ else
+ Send (pInst, "USER %s BUDDYSTATUS 1", pszUser);
+ if (pNick)
+ BuddyList_Remove (pInst->hBuddyList, pNick);
+ }
+ }
+ }
+ }
+ else
+ if (/*!strcmp(pszName, "recv") || */!strcmp(pszName, "streams_info"))
+ {
+ cJSON *pEdata = cJSON_GetObjectItem(pContent,"edata"),
+ *pType = cJSON_GetObjectItem(pContent,"type"), *pVal;
+
+ if (pType && pEdata)
+ {
+ if (strcasecmp(pType->valuestring, "call")==0 || strcasecmp(pType->valuestring, "video")==0 ||
+ strcasecmp(pType->valuestring, "av")==0)
+ {
+ // Rring, rrring...
+ int iDirection = ((pVal = cJSON_GetObjectItem(pEdata, "is_initiator")) && pVal->type == cJSON_True)?CALL_OUTGOING:CALL_INCOMING;
+ CALLENTRY *pCall = CallQueue_Insert (pInst->hCallQueue, pEdata, iDirection);
+ if (pCall)
+ {
+ Send (pInst, "CALL %d STATUS %s", pCall->hdr.uMsgNr, pCall->szStatus);
+ if ((pInst->iFlags & IMO2S_FLAG_ALLOWINTERACT) && iDirection == CALL_OUTGOING)
+ StartCallSWF (pInst, pCall);
+ }
+ }
+ }
+ }
+ else
+ if (!strcmp(pszName, "ended"))
+ {
+ cJSON *pEdata = cJSON_GetObjectItem(pContent,"edata"),
+ *pType = cJSON_GetObjectItem(pContent,"type");
+
+ if (pType && pEdata)
+ {
+ if (strcasecmp(pType->valuestring, "call")==0 || strcasecmp(pType->valuestring, "video")==0)
+ {
+ // No call ID, so just hangup all calls to this user
+ int i, nCount = List_Count(pInst->hCallQueue);
+ char *pszUser = cJSON_GetObjectItem(pEdata, "buid")->valuestring;
+
+ for (i=0; i<nCount; i++)
+ {
+ CALLENTRY *pCall = (CALLENTRY*)List_ElementAt(pInst->hCallQueue, i);
+
+ if (!strcmp(pCall->pszUser, pszUser) && strcmp (pCall->szStatus, "FINISHED"))
+ {
+ char szQuery[256];
+
+ sprintf (szQuery, "SET CALL %d STATUS FINISHED", pCall->hdr.uMsgNr);
+ HandleMessage (pInst, szQuery);
+ }
+ }
+ }
+ }
+ }
+ else
+ if (!strcmp(pszName, "reflect")) // Status reflections. We may want to support more of them in the future
+ {
+ cJSON *pEdata = cJSON_GetObjectItem(pContent,"edata"),
+ *pType = cJSON_GetObjectItem(pContent,"type"), *pRname, *pValue;
+
+ if (pEdata && pType && (pRname = cJSON_GetObjectItem(pEdata,"r_name")))
+ {
+ if (strcasecmp(pType->valuestring, "account") == 0)
+ {
+ if (strcasecmp (pRname->valuestring, "set_status") == 0 &&
+ (pValue = cJSON_GetObjectItem(pEdata,"primitive")) )
+ {
+ unsigned int i;
+
+ for (i=0; i<sizeof(m_stMap)/sizeof(m_stMap[0]); i++)
+ {
+ if (!strcasecmp(m_stMap[i].pszImoStat, pValue->valuestring))
+ {
+ strcpy (pInst->myUser.szStatus, m_stMap[i].pszSkypeStat);
+ Send (pInst, "USERSTATUS %s", pInst->myUser.szStatus);
+ break;
+ }
+ }
+
+ // Just ensure that on autoaway we notify imo.im that we are still there
+ if (!strcmp (pValue->valuestring, "away"))
+ ImoSkype_KeepAlive(pInst->hInst);
+
+ if (pValue = cJSON_GetObjectItem(pEdata,"status"))
+ {
+ if (pInst->myUser.pszStatusText) free (pInst->myUser.pszStatusText);
+ pInst->myUser.pszStatusText = NULL;
+ if (*pValue->valuestring)
+ pInst->myUser.pszStatusText = strdup(pValue->valuestring);
+ }
+
+ }
+ }
+ else
+ if (strcasecmp(pType->valuestring, "conv") == 0)
+ {
+ if (strcasecmp (pRname->valuestring, "send_im") == 0)
+ {
+ MSGENTRY *pMsg;
+
+ if (pMsg = MsgQueue_AddReflect(pInst->hMsgQueue, pEdata, pInst->hBuddyList))
+ {
+ if (pInst->iFlags & IMO2S_FLAG_CURRTIMESTAMP) time(&pMsg->timestamp);
+ Send(pInst, "%sMESSAGE %d STATUS %s", pInst->iProtocol>=3?"CHAT":"",
+ pMsg->hdr.uMsgNr, pMsg->szStatus);
+ }
+ }
+
+ }
+ }
+ }
+ else
+ if (!strcmp(pszName, "expired") && m>=iSize-1)
+ {
+ // Session expired, so we have to reconnect
+ Send(pInst, "CONNSTATUS OFFLINE");
+ Send(pInst, "USERSTATUS OFFLINE");
+ strcpy (pInst->myUser.szStatus, "OFFLINE");
+ pInst->iLoginStat = 0;
+ Dispatcher_Stop(pInst);
+ if (pInst->myUser.pszUser && pInst->pszPass)
+ Imo2S_Login(pInst, pInst->myUser.pszUser, pInst->pszPass, NULL);
+ }
+ else
+ if (!strcmp(pszName, "ack"))
+ {
+ MSGENTRY *pMsg;
+ cJSON *pRqId = cJSON_GetObjectItem(pContent,"request_id");
+
+ if (pRqId && (pMsg = MsgQueue_FindByRqId(pInst->hMsgQueue, pRqId->valueint)))
+ {
+ cJSON *pResp, *pTS;
+
+ strcpy (pMsg->szStatus, "SENT");
+ if ((pResp = cJSON_GetObjectItem(pContent,"response")) &&
+ (pTS = cJSON_GetObjectItem(pResp,"timestamp")))
+ pMsg->timestamp = pTS->valueint;
+ Send (pInst, "MESSAGE %d STATUS %s", pMsg->hdr.uMsgNr, pMsg->szStatus);
+ }
+ }
+ else
+ {
+ char *pszMsg = cJSON_Print(pMsg);
+ fprintf (stderr, "%s\n\n", pszMsg);
+ free (pszMsg);
+ }
+ }
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+
+#ifdef WIN32
+// Set call status to finished when closing phone applet window just in case
+// there is no callback by imo.im upon closure
+static LRESULT CallWndFilter(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch (message)
+ {
+ case WM_DESTROY:
+ {
+ IMOSAPI *pInst = (IMOSAPI*)GetWindowLong (hWnd, GWL_PINST);
+ int i, nCount;
+
+ if (!pInst) break;
+ for (i=0, nCount = List_Count(pInst->hCallQueue); i<nCount; i++)
+ {
+ CALLENTRY *pCall = (CALLENTRY*)List_ElementAt(pInst->hCallQueue, i);
+
+ if (pCall->hCallWnd == hWnd)
+ {
+ char szQuery[256];
+
+ sprintf (szQuery, "SET CALL %d STATUS FINISHED", pCall->hdr.uMsgNr);
+ HandleMessage (pInst, szQuery);
+ break;
+ }
+ }
+ break;
+ }
+ }
+ return CallWindowProc((WNDPROC)GetWindowLong (hWnd, GWL_ORIGWPRC), hWnd, message, wParam, lParam);
+}
+#endif
+
+
+// -----------------------------------------------------------------------------
+
+static int StartCallSWF (IMOSAPI *pInst, CALLENTRY *pCall)
+{
+ char szSWF[256], szFlashVars[1024], szID[18];
+ char szHTML[2048];
+ static unsigned int id=100;
+
+
+ /* The flash plugin basically opens rtmp://[host]/mchat in case of type=imo, otherwise rtmp://[host]/ivc
+ Maybe this can also be used with a SIP-phone or Asterisk?
+ */
+#ifndef WIN32
+ FILE *fpTemp;
+ int iFound;
+
+ sprintf (pCall->szCallFile, "xdg-open %s.html", tmpnam(NULL));
+ if (!(fpTemp=fopen(pCall->szCallFile, "w"))) return -1;
+#else
+ // Windows:
+ // Ensure that we are allowed to load the .swf from imo.im
+#ifndef CSIDL_APPDATA
+#define CSIDL_APPDATA 0x001a
+#endif
+ static BOOL bInit = TRUE;
+
+ if (bInit)
+ {
+ char szPath[MAX_PATH]={0};
+ HMODULE hModule;
+ typedef HMODULE (__stdcall *SHGETFOLDERPATH)(HWND, int, HANDLE, DWORD, LPTSTR);
+
+ if (hModule = LoadLibrary("SHFOLDER.DLL"))
+ {
+ SHGETFOLDERPATH fnShGetFolderPath = (SHGETFOLDERPATH)GetProcAddress(hModule, "SHGetFolderPathA");
+
+ if (fnShGetFolderPath && fnShGetFolderPath( NULL, CSIDL_APPDATA, NULL, 0, szPath)==S_OK)
+ {
+ strcat (szPath, "\\Macromedia\\Flash Player");
+ if (GetFileAttributes (szPath) != 0xFFFFFFFF)
+ {
+ strcat (szPath, "\\#Security");
+ _mkdir (szPath);
+ strcat (szPath, "\\FlashPlayerTrust");
+ _mkdir (szPath);
+ strcat (szPath, "\\imo2sproxy.cfg");
+ if (GetFileAttributes (szPath) == 0xFFFFFFFF)
+ {
+ FILE *fp = fopen (szPath, "w");
+
+ if (fp)
+ {
+ fputs ("https://imo.im/images/nchat.swf\nabout:blank\n", fp);
+ fclose (fp);
+ }
+ }
+ }
+ }
+ FreeLibrary(hModule);
+ }
+ bInit = FALSE;
+ }
+#endif
+ sprintf (szSWF, "https://imo.im/images/nchat.swf?%s", IVC_VERSION);
+ ImoRq_CreateID (szID, 16);
+ //sprintf (szID, "imo%d", id++);
+
+ if (*pCall->szSendStream)
+ sprintf (szFlashVars,
+ "type=skype&"
+ "send_stream=%s&"
+ "recv_stream=%s&"
+ "id=skype#%s&"
+ "host=video0.imo.im&"
+ "debug=conv net&"
+ "buddy_icon=https://imo.im/assets/main/icn_default.png&"
+ "setCookie=setCookie&"
+ "getCookie=getCookie&"
+ "removeCookie=removeCookie&"
+ "log=log&"
+ "init_callback=init_callback&"
+ "video_options_changed_cb=video_options_changed_cb&"
+ "options_changed_cb=options_changed_cb&"
+ "mic_changed_cb=mic_changed_cb&"
+ "cam_changed_cb=cam_changed_cb&"
+ "connection_status_cb=connection_status_cb",
+ pCall->szSendStream, pCall->szRecvStream, pCall->szSendStream);
+ else
+ return -1;
+ // sprintf (szFlashVars, "type=imo&conv=%s&role=%d&host=%s&id=%s", pCall->szConv, pCall->iRole, pCall->szIP, szID);
+
+ strcat (szFlashVars, "&audio_only=true");
+ // Currently not supported
+ sprintf (szHTML, "<html>\n"
+ "<head><script language='javascript'>\n"
+ "function log(t, s) { document.all.log.innerHTML+=s+'<br>'; }\n"
+ "function setCookie (N, L, M) { alert ('setcookie av_chat_'+L+' = '+M); }\n"
+ "function getCookie (M, L) { alert ('getcookie av_chat_'+L); }\n"
+ "function removeCookie (M, L) { alert ('removecookie av_chat_'+L); }\n"
+ "function init_callback(L) { }\n"
+ "function video_options_changed_cb(v, t, s) { }\n"
+ "function options_changed_cb(v, t, s) { }\n"
+ "function mic_changed_cb(u, s) { }\n"
+ "function cam_changed_cb(u, t) { }\n"
+ "function connection_status_cb (u, s) { }\n"
+ "</script></head>"
+ "<body>\n"
+ "<object width=\"400\" height=\"208\" type=\"application/x-shockwave-flash\" data=\"%s\" id=\"flash_widget_%s\" "
+ "style=\"visibility: visible; width: 400px; height: 208px;\">\n"
+ "<param name=\"movie\" value=\"%s\">\n"
+ "<param name=\"allowscriptaccess\" value=\"always\">\n"
+ "<param name=\"bgcolor\" value=\"#ffffff\">"
+ "<param name=\"flashvars\" value=\"%s\">\n"
+ "</object><br><div id=\"log\"></div>\n"
+ "</body></html>\n",
+ szSWF, szID, szSWF, szFlashVars);
+
+#ifdef WIN32
+ //OutputDebugString (szHTML);
+ sprintf (szSWF, "Voicechat with %s", pCall->pszUser);
+
+ /*
+
+ {
+ FILE *fpOut = fopen("C:\\TEMP\\CALL.HTML", "w");
+
+ fputs (szHTML, fpOut);
+ fclose (fpOut);
+ system ("\"C:\\Programme\\Internet Explorer\\IEXPLORE.EXE\" C:\\TEMP\\CALL.HTML");
+ }
+ */
+
+ if ((pCall->hCallWnd = W32Browser_ShowHTMLStr (szHTML,420, 280, szSWF))>0)
+ {
+ // Hook WndProc to handle WM_DESTROY so that we generate a CALL %d STATUS FINISHED on
+ // closing the chat window
+#ifdef _WIN64
+ SetWindowLongPtr ((HWND)pCall->hCallWnd, GWL_PINST, (LONG_PTR)pInst);
+ SetWindowLongPtr ((HWND)pCall->hCallWnd, GWL_ORIGWPRC,
+ GetWindowLongPtr ((HWND)pCall->hCallWnd, GWLP_WNDPROC));
+ SetWindowLongPtr ((HWND)pCall->hCallWnd, GWLP_WNDPROC, (LONG_PTR)CallWndFilter);
+#else
+ SetWindowLong ((HWND)pCall->hCallWnd, GWL_PINST, (LONG)pInst);
+ SetWindowLong ((HWND)pCall->hCallWnd, GWL_ORIGWPRC, GetWindowLong ((HWND)pCall->hCallWnd, GWL_WNDPROC));
+ SetWindowLong((HWND)pCall->hCallWnd, GWL_WNDPROC, (LONG)CallWndFilter);
+#endif
+ return 0;
+ }
+ return -1;
+#else
+ fprintf (fpTemp, "%s", szHTML);
+ fclose (fpTemp);
+ iFound = system(pCall->szCallFile);
+ return (iFound == -1 || iFound == 127)?-1:0;
+#endif
+}
+
+// -----------------------------------------------------------------------------
+
+static void DispatcherThread(void *pUser)
+{
+ IMOSAPI *pInst = (IMOSAPI*)pUser;
+ time_t t = 0, tcur;
+
+ if (pInst->fpLog) fprintf (pInst->fpLog, "Imo2S::DispatcherThread() start\n");
+ while (!pInst->iShuttingDown)
+ {
+#if defined(WIN32) && defined(WIN32)
+ char szBuf[128];
+
+ sprintf (szBuf, "DispatcherThread %d loops.\n", GetCurrentThreadId());
+ OutputDebugString (szBuf);
+#endif
+ if (time(&tcur)>=t+300)
+ {
+ t=tcur;
+ //ImoSkype_Ping (pInst->hInst);
+ ImoSkype_KeepAlive(pInst->hInst);
+ }
+
+ // Set status in case this is needed
+ if (pInst->tSetMoodText && tcur>=pInst->tSetMoodText)
+ {
+ int i;
+
+ pInst->tSetMoodText = 0;
+ for (i=0; i<sizeof(m_stMap)/sizeof(m_stMap[0]); i++)
+ {
+ if (!strcasecmp(m_stMap[i].pszSkypeStat, pInst->myUser.szStatus))
+ {
+ ImoSkype_SetStatus(pInst->hInst, m_stMap[i].pszImoStat,
+ pInst->myUser.pszStatusText?pInst->myUser.pszStatusText:"");
+ break;
+ }
+ }
+ }
+ ImoSkype_Poll(pInst->hInst);
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+#ifdef WIN32
+static int Dispatcher_Start(IMOSAPI *pInst)
+{
+ DWORD ThreadID;
+
+ if (pInst->fpLog) fprintf (pInst->fpLog, "Imo2S::Dispatcher_Start()\n");
+ return (pInst->hThread=(thread_t)_beginthreadex(NULL, 0,
+ (unsigned(__stdcall *)(void*))DispatcherThread, pInst, 0, &ThreadID))!=0;
+
+}
+
+static int Dispatcher_Stop(IMOSAPI *pInst)
+{
+ int iRet, iOldShutdown;
+
+ if (pInst->fpLog)
+ {
+ fprintf (pInst->fpLog, "Imo2S::Dispatcher_Stop()\n");
+ fflush(pInst->fpLog);
+ }
+
+ // Shutdown polling socket and wait some time if thread terminates
+ // gracefully, otherwise kill it
+ iOldShutdown = pInst->iShuttingDown;
+ pInst->iShuttingDown = 1;
+ ImoSkype_CancelPolling (pInst->hInst);
+ if (WaitForSingleObject (pInst->hThread, 2000) == WAIT_TIMEOUT)
+ iRet = TerminateThread (pInst->hThread, 0);
+ else iRet = 1;
+ pInst->iShuttingDown = iOldShutdown;
+
+ if (iRet)
+ {
+ CloseHandle (pInst->hThread);
+ pInst->hThread = 0;
+ }
+
+ if (pInst->fpLog)
+ {
+ fprintf (pInst->fpLog, "Imo2S::Dispatcher_Stop() done.\n");
+ pInst->fpLog = NULL;
+ }
+
+ return iRet;
+}
+
+#else
+static int Dispatcher_Start(IMOSAPI *pInst)
+{
+ if (pInst->fpLog) fprintf (pInst->fpLog, "Imo2S::Dispatcher_Start()\n");
+ return pthread_create(&pInst->hThread, NULL, DispatcherThread, pInst)==0;
+}
+
+static int Dispatcher_Stop(IMOSAPI *pInst)
+{
+ if (pInst->fpLog) fprintf (pInst->fpLog, "Imo2S::Dispatcher_Stop()\n");
+ if (pthread_cancel(pInst->hThread))
+ {
+ pInst->hThread=0;
+ return 1;
+ }
+ return 0;
+}
+#endif
+
+// -----------------------------------------------------------------------------
+
+static void Send(IMOSAPI *pInst, const char *pszMsg, ...)
+{
+ va_list ap;
+ int iLen, iLenCmdID;
+ char *pszLogBuf = pInst->pszLogBuf;
+ int cbBuf = pInst->cbBuf;
+
+ iLenCmdID = pInst->pszCmdID?strlen(pInst->pszCmdID)+1:0;
+ do
+ {
+ cbBuf = pInst->cbBuf - iLenCmdID;
+ pszLogBuf = pInst->pszLogBuf + iLenCmdID;
+ va_start(ap, pszMsg);
+ iLen = vsnprintf (pszLogBuf, cbBuf, pszMsg, ap);
+ va_end(ap);
+#ifndef WIN32
+ if (iLen>=cbBuf) iLen=-1;
+#endif
+ if (iLen == -1)
+ {
+ char *pNewBuf;
+
+ if (!(pNewBuf = realloc(pInst->pszLogBuf, pInst->cbBuf*2)))
+ {
+ break;
+ }
+ pInst->cbBuf*=2;
+ pInst->pszLogBuf = pNewBuf;
+ }
+ } while (iLen == -1);
+ if (pInst->pszCmdID && iLenCmdID>1)
+ {
+ memcpy (pInst->pszLogBuf, pInst->pszCmdID, iLenCmdID);
+ pInst->pszLogBuf[iLenCmdID-1]=' ';
+ }
+
+//printf ("%s\n", szBuf);
+ pInst->Callback(pInst->pszLogBuf, pInst->pUser);
+}
+
+// -----------------------------------------------------------------------------
+
+static void HandleMessage(IMOSAPI *pInst, char *pszMsg)
+{
+ char *pszCmd=strtok(pszMsg, " ");
+
+ if (!pInst || !pszCmd || !pInst->hInst) return;
+ if (*pszCmd=='#')
+ {
+ // This is a PROTOCOL 4 feature, but we will support it just in case...
+ pInst->pszCmdID = pszCmd;
+ if (!(pszCmd=strtok(NULL, " ")))
+ {
+ pInst->pszCmdID = NULL;
+ return;
+ }
+ }
+ else pInst->pszCmdID = NULL;
+
+ if (strcasecmp(pszCmd, "PROTOCOL") == 0)
+ {
+ if (pszCmd = strtok(NULL, " "))
+ {
+ pInst->iProtocol = atoi(pszCmd);
+ if (pInst->iProtocol>3) pInst->iProtocol=3;
+ }
+
+ Send (pInst, "PROTOCOL %d", pInst->iProtocol);
+ return;
+ }
+ else
+ if (strcasecmp(pszCmd, "PING") == 0)
+ {
+ Send (pInst, "PONG");
+ return;
+ }
+ else
+ if (strcasecmp(pszCmd, "SEARCH") == 0)
+ {
+ TYP_FIFO *hFifo;
+
+ if (!(pszCmd = strtok(NULL, " ")))
+ {
+ Send (pInst, "ERROR 2 Invalid command");
+ return;
+ }
+
+ if (strcasecmp(pszCmd, "FRIENDS") == 0)
+ {
+ unsigned int nCount =List_Count(pInst->hBuddyList);
+
+ if (!nCount)
+ {
+ pInst->bFriendsPending = 1;
+ return;
+ }
+ if(hFifo=Fifo_Init(512))
+ {
+ unsigned int i;
+ char *pszUsers;
+
+ for (i=0; i<nCount; i++)
+ {
+ NICKENTRY *pEntry = List_ElementAt(pInst->hBuddyList, i);
+ if (!pEntry->pGroup && !pEntry->hGCMembers)
+ {
+ if (i>0) Fifo_AddString (hFifo, ", ");
+ Fifo_AddString (hFifo, pEntry->pszUser);
+ }
+ }
+ if (pszUsers = Fifo_Get(hFifo, NULL))
+ Send (pInst, "USERS %s", pszUsers);
+ else
+ pInst->bFriendsPending = 1;
+ Fifo_Exit(hFifo);
+ }
+ }
+ else if (strcasecmp(pszCmd, "MISSEDMESSAGES") == 0)
+ {
+ unsigned int nCount=List_Count(pInst->hMsgQueue);
+
+ if(nCount && (hFifo=Fifo_Init(512)))
+ {
+ unsigned int i, j=0;
+
+ for (i=0; i<nCount; i++)
+ {
+ MSGENTRY *pEntry = List_ElementAt(pInst->hMsgQueue, i);
+ char szNr[32];
+
+ if (!strcmp(pEntry->szStatus, "RECEIVED"))
+ {
+ if (j>0) Fifo_AddString (hFifo, ", ");
+ sprintf (szNr, "%d", pEntry->hdr.uMsgNr);
+ Fifo_AddString (hFifo, szNr);
+ j++;
+ }
+ }
+ Send (pInst, "MESSAGES %s", Fifo_Get(hFifo, NULL));
+ Fifo_Exit(hFifo);
+ }
+ }
+ else if (strcasecmp(pszCmd, "USERS") == 0)
+ {
+ // There is no possibility to search Skype users in imo.im
+ // therefore just return that the user exists even if it doesn't :(
+ Send (pInst, "USERS %s", pszCmd+6);
+ // We add the user as a temporary contact to our list so that the
+ // client can get the empty properties and set the buddystatus.
+ BuddyList_AddTemporaryUser (pInst->hBuddyList, pszCmd+6);
+ }
+ else if (strcasecmp(pszCmd, "USERSWAITINGMYAUTHORIZATION") == 0)
+ {
+ Send (pInst, "USERS");
+ }
+ else if (strcasecmp(pszCmd, "ACTIVECALLS") == 0)
+ {
+ char szCalls[512];
+ int i, nCount, iOffs=0;
+
+ iOffs = sprintf (szCalls, "CALLS");
+ for (i=0, nCount=List_Count(pInst->hCallQueue); i<nCount; i++)
+ {
+ if (i) iOffs+=sprintf(&szCalls[iOffs], ", ");
+ iOffs+=sprintf(&szCalls[iOffs], "%d", ((CALLENTRY*)List_ElementAt (pInst->hCallQueue, i))->hdr.uMsgNr);
+ if (iOffs+6>=sizeof(szCalls)) break;
+ }
+ Send (pInst, szCalls);
+ }
+ else if (strcasecmp(pszCmd, "RECENTCHATS") == 0)
+ {
+ char szChats[2056];
+ int i, nCount, iOffs=0, j=0;
+
+ iOffs = sprintf (szChats, "CHATS ");
+ for (i=0, nCount=List_Count(pInst->hBuddyList); i<nCount; i++)
+ {
+ NICKENTRY *pChat = (NICKENTRY*)List_ElementAt (pInst->hBuddyList, i);
+
+ if (BuddyList_IsGroupchat(pChat))
+ {
+ if (j) iOffs+=sprintf(&szChats[iOffs], ", ");
+ iOffs+=sprintf(&szChats[iOffs], "%s", pChat->pszUser);
+ if (iOffs+6>=sizeof(szChats)) break;
+ j++;
+ }
+ }
+ Send (pInst, szChats);
+ }
+ return;
+ }
+ else
+ if (strcasecmp(pszCmd, "GET") == 0)
+ {
+ if (!(pszCmd = strtok(NULL, " ")))
+ {
+ Send (pInst, "ERROR 7 Invalid property");
+ return;
+ }
+
+ if (strcasecmp(pszCmd, "USER") == 0)
+ {
+ NICKENTRY *pUser = NULL;
+
+ if (pszCmd = strtok(NULL, " "))
+ {
+ if (!strcasecmp (pszCmd, pInst->myUser.pszUser))
+ pUser = &pInst->myUser;
+ else
+ pUser = BuddyList_Find(pInst->hBuddyList, pszCmd);
+ }
+
+ if (!pUser)
+ {
+ Send (pInst, "ERROR 26 Invalid user handle");
+ return;
+ }
+ if (!(pszCmd = strtok(NULL, " ")))
+ {
+ Send (pInst, "ERROR 10 Invalid property");
+ return;
+ }
+
+ if (!strcasecmp (pszCmd, "HANDLE"))
+ {
+ if (pUser->pszAlias) Send (pInst, "USER %s HANDLE %s", pUser->pszUser, pUser->pszAlias);
+ }
+ else if (!strcasecmp (pszCmd, "FULLNAME")) /* Workaround */
+ Send (pInst, "USER %s FULLNAME %s", pUser->pszUser, pUser->pszAlias);
+ else if (!strcasecmp (pszCmd, "DISPLAYNAME"))
+ Send (pInst, "USER %s DISPLAYNAME %s", pUser->pszUser, pUser->pszAlias);
+ else if (!strcasecmp (pszCmd, "HASCALLEQUIPMENT"))
+ Send (pInst, "USER %s HASCALLEQUIPMENT TRUE", pUser->pszUser);
+ else if (!strcasecmp (pszCmd, "BUDDYSTATUS"))
+ Send (pInst, "USER %s BUDDYSTATUS %d", pUser->pszUser, pUser->iBuddyStatus);
+ else if (!strcasecmp (pszCmd, "ISAUTHORIZED"))
+ Send (pInst, "USER %s ISAUTHORIZED TRUE", pUser->pszUser);
+ else if (!strcasecmp (pszCmd, "MOOD_TEXT"))
+ Send (pInst, "USER %s MOOD_TEXT %s", pUser->pszUser,
+ pUser->pszStatusText?pUser->pszStatusText:"");
+ else if (!strcasecmp (pszCmd, "SEX"))
+ Send (pInst, "USER %s SEX UNKNOWN", pUser->pszUser);
+ else if (!strcasecmp (pszCmd, "BIRTHDAY"))
+ Send (pInst, "USER %s BIRTHDAY 0", pUser->pszUser);
+ else if (!strcasecmp (pszCmd, "ONLINESTATUS"))
+ {
+ unsigned int i;
+
+ for (i=0; i<sizeof(m_stMap)/sizeof(m_stMap[0]); i++)
+ {
+ if (!strcasecmp(m_stMap[i].pszImoStat, pUser->szStatus))
+ {
+ Send (pInst, "USER %s ONLINESTATUS %s", pUser->pszUser, m_stMap[i].pszSkypeStat);
+ break;
+ }
+ }
+ }
+ else if (!strcasecmp (pszCmd, "AVATAR"))
+ {
+ char *pszFile, *pAvatarBuf;
+ unsigned int dwLength;
+ AVATARENTRY *pAvatar;
+ FILE *fp;
+
+ if (!(pszFile = strtok(NULL, " ")) || strcasecmp (pszFile, "1"))
+ {
+ Send (pInst, "ERROR 116 GET invalid ID");
+ return;
+ }
+ if (!(pszFile = strtok(NULL, "\n")))
+ {
+ Send (pInst, "ERROR 7 GET: invalid WHAT");
+ return;
+ }
+ if (fp=fopen(pszFile, "r"))
+ {
+ fseek (fp, 0, SEEK_END);
+ if (ftell(fp))
+ {
+ fclose(fp);
+ Send (pInst, "ERROR 124 GET Destination file is not empty");
+ return;
+ }
+ fclose(fp);
+ }
+ if (!(pAvatar = AvatarList_Find(pInst->hAvatarList, pUser->pszUser)) ||
+ !(pAvatarBuf = ImoSkype_GetAvatar (pInst->hInst, pAvatar->pszIcon, &dwLength)))
+ {
+ // FIXME: Normally we should return default avatar if pAvatar is NULL.
+ // Default avatar from imo.im is PNG, but JPEG is expected, so we
+ // return an error here
+ Send (pInst, "ERROR 122 GET Unable to load avatar");
+ return;
+ }
+ if (!(fp=fopen(pszFile,
+#ifdef WIN32
+ "wb"
+#else
+ "w"
+#endif
+ )))
+ {
+ Send (pInst, "ERROR 121 GET File path doesn't exist");
+ return;
+ }
+ fwrite (pAvatarBuf, dwLength, 1, fp);
+ fclose (fp);
+ Send (pInst, "USER %s AVATAR 1 %s", pUser->pszUser, pszFile);
+ }
+ else
+ {
+ Send(pInst, "ERROR 10 Invalid propery");
+ }
+ return;
+ }
+ else
+ if (strcasecmp(pszCmd, "CURRENTUSERHANDLE") == 0)
+ {
+ if (pInst->myUser.pszUser)
+ Send(pInst, "CURRENTUSERHANDLE %s", pInst->myUser.pszUser);
+ }
+ else
+ if (strcasecmp(pszCmd, "USERSTATUS") == 0)
+ {
+ Send(pInst, "USERSTATUS %s", pInst->myUser.szStatus);
+ }
+ else
+ if (strcasecmp(pszCmd, "MESSAGE") == 0 || strcasecmp(pszCmd, "CHATMESSAGE") == 0)
+ {
+ MSGENTRY *pEntry;
+ char *pszMessage = pszCmd;
+
+ if (!(pszCmd = strtok(NULL, " ")) || !(pEntry = MsgQueue_Find(pInst->hMsgQueue, atol(pszCmd))))
+ {
+ Send (pInst, "ERROR 14 Invalid message id");
+ return;
+ }
+ if (!(pszCmd = strtok(NULL, " ")))
+ {
+ Send (pInst, "ERROR 10 Invalid property");
+ return;
+ }
+ if (!strcasecmp (pszCmd, "TIMESTAMP"))
+ Send (pInst, "%s %d TIMESTAMP %ld", pszMessage, pEntry->hdr.uMsgNr, pEntry->timestamp);
+ else if (!strcasecmp (pszCmd, "PARTNER_HANDLE") || !strcasecmp (pszCmd, "FROM_HANDLE"))
+ {
+ char *pszUser = strdup(pEntry->pszAuthor?pEntry->pszAuthor:pEntry->pszUser), *p, *pszRealUser=pszUser;
+
+ if (p=strtok(pszUser, ";"))
+ {
+ if (!(pszRealUser=strtok(NULL, ";"))) pszRealUser=p;
+ }
+ Send (pInst, "%s %d %s %s", pszMessage, pEntry->hdr.uMsgNr, pszCmd, pszRealUser);
+ free (pszUser);
+ }
+ else if (!strcasecmp (pszCmd, "PARTNER_DISPNAME"))
+ Send (pInst, "%s %d PARTNER_DISPNAME %s", pszMessage, pEntry->hdr.uMsgNr, pEntry->pszAlias);
+ else if (!strcasecmp (pszCmd, "TYPE"))
+ Send (pInst, "%s %d TYPE %s", pszMessage, pEntry->hdr.uMsgNr, pEntry->szType);
+ else if (!strcasecmp (pszCmd, "STATUS"))
+ Send (pInst, "%s %d STATUS %s", pszMessage, pEntry->hdr.uMsgNr, pEntry->szStatus);
+ else if (!strcasecmp (pszCmd, "FAILUREREASON"))
+ Send (pInst, "%s %d FAILUREREASON %s", pszMessage, pEntry->hdr.uMsgNr, pEntry->szFailure);
+ else if (!strcasecmp (pszCmd, "BODY"))
+ Send (pInst, "%s %d BODY %s", pszMessage, pEntry->hdr.uMsgNr, pEntry->pszMessage);
+ else if (!strcasecmp (pszCmd, "CHATNAME"))
+ {
+ if (pEntry->pszAuthor || !pEntry->pszMessage || strchr(pEntry->pszUser, ';')) // Groupchat
+ {
+ char *pszUser = strdup(pEntry->pszUser), *p;
+
+ if (p=strchr(pszUser, ';')) p[1]=0;
+ Send (pInst, "%s %d CHATNAME %s", pszMessage, pEntry->hdr.uMsgNr, pszUser);
+ free (pszUser);
+ }
+ else
+ Send (pInst, "%s %d CHATNAME #%s/$%s", pszMessage, pEntry->hdr.uMsgNr, pInst->myUser.pszUser, pEntry->pszUser);
+ }
+ else if (!strcasecmp (pszCmd, "USERS"))
+ {
+ // On KICK, this is the user who GOT kicked
+ char *pszUser = strchr(pEntry->pszUser, ';');
+ if (pszUser) pszUser++; else pszUser=pEntry->pszUser;
+ Send (pInst, "%s %d USERS %s", pszMessage, pEntry->hdr.uMsgNr, pszUser);
+ }
+ else
+ Send (pInst, "ERROR 10 Invalid property / not implemented");
+ return;
+ }
+ else
+ if (strcasecmp(pszCmd, "PRIVILEGE") == 0)
+ {
+ if (!(pszCmd = strtok(NULL, " ")) ||
+ (strcasecmp (pszCmd, "SKYPEOUT") &&
+ strcasecmp (pszCmd, "SKYPEIN") &&
+ strcasecmp (pszCmd, "VOICEMAIL")))
+ {
+ Send (pInst, "ERROR 40 Unknown Privilege");
+ return;
+ }
+ Send (pInst, "PRIVILEGE %s FALSE", pszCmd);
+ return;
+ }
+ else
+ if (strcasecmp(pszCmd, "CHAT") == 0)
+ {
+ char *pszChat;
+ NICKENTRY *pChat=NULL;
+
+ // A $ sign is in the name of a dialog, otherwise it's a groupchat ID
+ if (!(pszChat = strtok(NULL, " ")) ||
+ (!strchr(pszChat, '$') && !(pChat=BuddyList_Find(pInst->hBuddyList, pszChat))))
+ {
+ Send (pInst, "ERROR 14 Invalid message id");
+ return;
+ }
+
+
+ if (!(pszCmd = strtok(NULL, " ")))
+ {
+ Send (pInst, "ERROR 10 Invalid property");
+ return;
+ }
+
+ if (strcasecmp(pszCmd, "NAME") == 0)
+ Send (pInst, "CHAT %s NAME %s", pszChat, pszChat);
+ else if (strcasecmp(pszCmd, "STATUS") == 0)
+ // A $ sign is in the name of a dialog, otherwise it's a groupchat ID
+ Send (pInst, "CHAT %s STATUS %s", pszChat, pChat?"MULTI_SUBSCRIBED":"LEGACY_DIALOG");
+ else if (strcasecmp(pszCmd, "ADDER") == 0)
+ Send (pInst, "CHAT %s ADDER %s", pszChat, pInst->myUser.pszUser);
+ else if (strcasecmp(pszCmd, "TYPE") == 0)
+ Send (pInst, "CHAT %s TYPE %s", pszChat, pChat?"MULTICHAT":"DIALOG");
+ else if (strcasecmp(pszCmd, "MYROLE") == 0)
+ Send (pInst, "CHAT %s MYROLE USER", pszChat);
+ else if (strcasecmp(pszCmd, "MYSTATUS") == 0)
+ Send (pInst, "CHAT %s MYSTATUS SUBSCRIBED", pszChat);
+ else if ((strcasecmp(pszCmd, "TOPIC") == 0 || strcasecmp(pszCmd, "FRIENDLYNAME") == 0) && pChat)
+ Send (pInst, "CHAT %s %s %s", pszChat, pszCmd, pChat->pszDisplay);
+ else if ((strcasecmp(pszCmd, "ACTIVEMEMBERS") == 0 || strcasecmp(pszCmd, "MEMBERS") == 0) && pChat)
+ {
+ char szMembers[1024]={0};
+ int i, nCount, iOffs=0;
+
+ iOffs = sprintf (szMembers, "CHAT %s %s ", pszChat, pszCmd);
+ for (i=0, nCount=List_Count(pChat->hGCMembers); i<nCount; i++)
+ {
+ NICKENTRY *pMemb = (NICKENTRY*)List_ElementAt (pChat->hGCMembers, i);
+ char szUser[512], *pTok;
+
+ if (i) iOffs+=sprintf(&szMembers[iOffs], " ");
+ strcpy (szUser, pMemb->pszUser);
+ pTok=strtok(szUser, ";");
+ pTok=strtok(NULL, ";");
+ iOffs+=sprintf(&szMembers[iOffs], "%s", pTok);
+ if (iOffs+6>=sizeof(szMembers)) break;
+ }
+ Send (pInst, szMembers);
+ }
+ else
+ Send(pInst, "ERROR 7 Invalid property / not implemented");
+ return;
+ }
+ else
+ if (strcasecmp(pszCmd, "CALL") == 0)
+ {
+ CALLENTRY *pEntry;
+
+ if (!(pszCmd = strtok(NULL, " ")) || !(pEntry = CallQueue_Find(pInst->hCallQueue, atol(pszCmd))))
+ {
+ Send (pInst, "ERROR 11 Invalid call id");
+ return;
+ }
+ if (!(pszCmd = strtok(NULL, " ")))
+ {
+ Send (pInst, "ERROR 10 Invalid property");
+ return;
+ }
+ if (!strcasecmp (pszCmd, "TIMESTAMP"))
+ Send (pInst, "CALL %d TIMESTAMP %ld", pEntry->hdr.uMsgNr, pEntry->timestamp);
+ else if (!strcasecmp (pszCmd, "PARTNER_HANDLE"))
+ Send (pInst, "CALL %d PARTNER_HANDLE %s", pEntry->hdr.uMsgNr, pEntry->pszUser);
+ else if (!strcasecmp (pszCmd, "PARTNER_DISPNAME"))
+ {
+ NICKENTRY *pNick = BuddyList_Find (pInst->hBuddyList, pEntry->pszUser);
+
+ if (pNick)
+ Send (pInst, "CALL %d PARTNER_DISPNAME %s", pEntry->hdr.uMsgNr, pNick->pszAlias);
+ }
+ else if (!strcasecmp (pszCmd, "CONF_ID"))
+ Send (pInst, "CALL %d CONF_ID 0", pEntry->hdr.uMsgNr);
+ else if (!strcasecmp (pszCmd, "TYPE"))
+ Send (pInst, "CALL %d TYPE %s", pEntry->hdr.uMsgNr, pEntry->iDirection==CALL_INCOMING?"INCOMING_P2P":"OUTGOING_P2P");
+ else if (!strcasecmp (pszCmd, "STATUS"))
+ Send (pInst, "CALL %d STATUS %s", pEntry->hdr.uMsgNr, pEntry->szStatus);
+ else if (!strcasecmp (pszCmd, "VIDEO_STATUS"))
+ Send (pInst, "CALL %d VIDEO_STATUS VIDEO_NONE", pEntry->hdr.uMsgNr);
+ else if (!strcasecmp (pszCmd, "VIDEO_SEND_STATUS") || !strcasecmp (pszCmd, "VIDEO_RECEIVE_STATUS"))
+ Send (pInst, "CALL %d %s NOT_AVAILABLE", pEntry->hdr.uMsgNr, pszCmd);
+ else if (!strcasecmp (pszCmd, "FAILUREREASON"))
+ Send (pInst, "CALL %d FAILUREREASON UNKNOWN", pEntry->hdr.uMsgNr);
+ else if (!strcasecmp (pszCmd, "DURATION"))
+ Send (pInst, "CALL %d DURATION 0", pEntry->hdr.uMsgNr);
+ else if (!strcasecmp (pszCmd, "CONF_PARTICIPANTS_COUNT"))
+ Send (pInst, "CALL %d CONF_PARTICIPANTS_COUNT 0", pEntry->hdr.uMsgNr);
+ else
+ Send (pInst, "ERROR 10 Invalid property / not implemented");
+ return;
+ }
+ else
+ if (strcasecmp(pszCmd, "SKYPEVERSION") == 0)
+ {
+ Send (pInst, "SKYPEVERSION 3.8.0.188"); // Fake
+ }
+ else
+ {
+ Send(pInst, "ERROR 7 Invalid property / not implemented");
+ }
+ return;
+ }
+ else
+ if (strcasecmp(pszCmd, "SET") == 0)
+ {
+ if (!(pszCmd = strtok(NULL, " ")))
+ {
+ Send (pInst, "ERROR 7 Invalid property");
+ return;
+ }
+
+ if (strcasecmp(pszCmd, "USER") == 0)
+ {
+ char *pszUser;
+ NICKENTRY *pUser = NULL;
+
+ if (!(pszUser = strtok(NULL, " ")))
+ {
+ Send (pInst, "ERROR 26 Invalid user handle");
+ return;
+ }
+
+ if (!(pszCmd = strtok(NULL, " ")))
+ {
+ Send (pInst, "ERROR 7 Invalid property");
+ return;
+ }
+
+ pUser = BuddyList_Find(pInst->hBuddyList, pszUser);
+
+ if (strcasecmp(pszCmd, "BUDDYSTATUS") == 0)
+ {
+ int iStatus = -1;
+
+ if (pszCmd = strtok(NULL, " "))
+ iStatus = atoi(pszCmd);
+
+ if (!pUser && iStatus < 2)
+ {
+ Send (pInst, "ERROR 26 Invalid user handle");
+ return;
+ }
+ if (iStatus == 2 || (iStatus > 2 && !pUser) || iStatus != pUser->iBuddyStatus)
+ {
+ switch (iStatus)
+ {
+ case 1:
+ if (ImoSkype_DelBuddy (pInst->hInst, pUser->pszUser,
+ strcmp(pUser->szStatus, "OFFLINE")?"Skype":"Offline") == 1)
+ pUser->iBuddyStatus = iStatus;
+ break;
+ case 2:
+ case 3:
+ ImoSkype_AddBuddy (pInst->hInst, pszUser);
+ return;
+ default:
+ Send (pInst, "ERROR 518 Invalid status given for BUDDYSTATUS");
+ return;
+ }
+ }
+ Send (pInst, "USER %s BUDDYSTATUS %d", pUser->pszUser, pUser->iBuddyStatus);
+ return;
+ }
+ else if (!pUser)
+ {
+ Send (pInst, "ERROR 26 Invalid user handle");
+ return;
+ }
+ else
+ {
+ // ISAUTHORIZED
+ Send (pInst, "ERROR 7 Not implemented");
+ }
+ }
+ else
+ if (strcasecmp(pszCmd, "USERSTATUS") == 0)
+ {
+ unsigned int i;
+
+ if (!(pszCmd = strtok(NULL, " ")))
+ {
+ Send (pInst, "ERROR 28 Unknown userstatus");
+ return;
+ }
+
+ if (strcasecmp(pInst->myUser.szStatus, pszCmd))
+ {
+ for (i=0; i<sizeof(m_stMap)/sizeof(m_stMap[0]); i++)
+ {
+ if (!strcasecmp(m_stMap[i].pszSkypeStat, pszCmd))
+ {
+ pInst->tSetMoodText = 0;
+ if (ImoSkype_SetStatus(pInst->hInst, m_stMap[i].pszImoStat,
+ pInst->myUser.pszStatusText?pInst->myUser.pszStatusText:"")>0)
+ strcpy (pInst->myUser.szStatus, pszCmd);
+ Send (pInst, "USERSTATUS %s", pInst->myUser.szStatus);
+ break;
+ }
+ }
+ if (i==sizeof(m_stMap)/sizeof(m_stMap[0]))
+ Send (pInst, "ERROR 28 Unknown userstatus");
+ } else Send (pInst, "USERSTATUS %s", pInst->myUser.szStatus);
+ return;
+ }
+ else
+ if (strcasecmp(pszCmd, "MESSAGE") == 0 || strcasecmp(pszCmd, "CHATMESSAGE") == 0)
+ {
+ MSGENTRY *pEntry;
+ char *pszMessage = pszCmd;
+
+ if (!(pszCmd = strtok(NULL, " ")) || !(pEntry = MsgQueue_Find(pInst->hMsgQueue, atol(pszCmd))))
+ {
+ Send (pInst, "ERROR 14 Invalid message id");
+ return;
+ }
+ if (!(pszCmd = strtok(NULL, " ")))
+ {
+ Send (pInst, "ERROR 10 Invalid property");
+ return;
+ }
+ if (!strcasecmp (pszCmd, "SEEN"))
+ {
+ strcpy (pEntry->szStatus, "READ");
+ Send (pInst, "%s %d STATUS %s", pszMessage, pEntry->hdr.uMsgNr, pEntry->szStatus);
+ }
+ else
+ Send (pInst, "ERROR 10 Invalid property / not implemented");
+ return;
+ }
+ else
+ if (strcasecmp(pszCmd, "CALL") == 0)
+ {
+ CALLENTRY *pEntry;
+
+ if (!(pszCmd = strtok(NULL, " ")) || !(pEntry = CallQueue_Find(pInst->hCallQueue, atol(pszCmd))))
+ {
+ Send (pInst, "ERROR 11 Invalid call id");
+ return;
+ }
+ if (!(pszCmd = strtok(NULL, " ")))
+ {
+ Send (pInst, "ERROR 10 Invalid property");
+ return;
+ }
+ if (!strcasecmp (pszCmd, "STATUS"))
+ {
+ if (!(pszCmd = strtok(NULL, " ")))
+ {
+ Send (pInst, "ERROR 21 Unknown/disallowed call prop");
+ return;
+ }
+ strcpy (pEntry->szStatus, pszCmd);
+ Send (pInst, "CALL %d STATUS %s", pEntry->hdr.uMsgNr, pEntry->szStatus);
+
+ // {RINGING, INPROGRESS, ONHOLD, FINISHED}
+ if (pInst->iFlags & IMO2S_FLAG_ALLOWINTERACT)
+ {
+ if (strcasecmp (pEntry->szStatus, "INPROGRESS") == 0 && pEntry->iDirection == CALL_INCOMING)
+ {
+ StartCallSWF (pInst, pEntry);
+ }
+ else
+ if (strcasecmp (pEntry->szStatus, "FINISHED") == 0 && pEntry->hCallWnd)
+ {
+ if (*pEntry->szCallFile)
+ {
+ unlink(pEntry->szCallFile);
+ *pEntry->szCallFile=0;
+ }
+#ifdef WIN32
+ if (pEntry->hCallWnd)
+ {
+ W32Browser_CloseWindow (pEntry->hCallWnd);
+ pEntry->hCallWnd = NULL;
+ }
+#endif
+
+ // On incoming call, hang up
+ }
+ }
+
+ // Currently we don't support calls, just hang up
+ /* FIXME: Hangup! */
+ return;
+ }
+ return;
+ }
+ else
+ if (strcasecmp(pszCmd, "PROFILE") == 0)
+ {
+ if (!(pszCmd = strtok(NULL, " ")))
+ {
+ Send (pInst, "ERROR 10 Invalid property");
+ return;
+ }
+
+ if (!strcasecmp (pszCmd, "MOOD_TEXT"))
+ {
+ if (!pInst->myUser.pszStatusText ||
+ strcasecmp(pInst->myUser.pszStatusText, pszCmd+10))
+ {
+ time_t t;
+ // Delay setting of MOOD_TEXT, as next command in chain may change online status
+ // and we want to prevent double calls
+ // The polling-thread will take care of this event
+ pInst->tSetMoodText = time(&t)+15;
+ if (pInst->myUser.pszStatusText) free (pInst->myUser.pszStatusText);
+ pInst->myUser.pszStatusText = strdup (pszCmd+10);
+ }
+ }
+ else
+ {
+ Send (pInst, "ERROR 552 Invalid property");
+ return;
+ }
+ }
+ else
+ {
+ Send (pInst, "ERROR 7 Invalid property");
+ return;
+ }
+ }
+ else
+ if (strcasecmp(pszCmd, "MESSAGE") == 0 || strcasecmp(pszCmd, "CHATMESSAGE") == 0)
+ {
+ NICKENTRY *pUser;
+ unsigned int uMsgId;
+ MSGENTRY *pMsg;
+
+ if (!(pszCmd = strtok(NULL, " ")) || !(pUser = BuddyList_Find(pInst->hBuddyList, pszCmd)))
+ {
+ Send (pInst, "ERROR 26 Invalid user handle");
+ return;
+ }
+ pszCmd+=strlen(pszCmd)+1;
+ if (!*pszCmd)
+ {
+ Send (pInst, "ERROR 43 Cannot send empty message");
+ return;
+ }
+ if (!(pMsg = MsgQueue_AddSent (pInst->hMsgQueue, pUser->pszUser, pUser->pszAlias, pszCmd, &uMsgId)))
+ {
+ Send (pInst, "ERROR 9901 Internal error");
+ return;
+ }
+ if (IMO_API_VERSION == 0) Send (pInst, "MESSAGE %d STATUS SENDING", uMsgId);
+ if (ImoSkype_SendMessage(pInst->hInst, pUser->pszUser, pszCmd, &pMsg->uRqId)>0)
+ {
+ if (IMO_API_VERSION == 0) strcpy (pMsg->szStatus, "SENT");
+ }
+ else
+ {
+ strcpy (pMsg->szStatus, "FAILED");
+ strncpy (pMsg->szFailure, ImoSkype_GetLastError(pInst->hInst), sizeof(pMsg->szFailure));
+ }
+ Send (pInst, "MESSAGE %d STATUS %s", uMsgId, pMsg->szStatus);
+ }
+ else
+ if (strcasecmp(pszCmd, "CHAT") == 0)
+ {
+ if (!(pszCmd = strtok(NULL, " ")))
+ {
+ Send (pInst, "ERROR 536 CREATE: no object or type given");
+ return;
+ }
+ if (strcasecmp(pszCmd, "CREATE") == 0)
+ {
+ char szName[128]; // No name given here, so make up a name
+ time_t t;
+
+ time(&t);
+ sprintf (szName, "%d", t);
+ if (ImoSkype_CreateSharedGroup(pInst->hInst, szName)<1) return;
+
+ // Now buddy_added should be called which gives us the ID of the new groupchat
+ // where we can then add members to. However this is not known here yet, so feed
+ // list with users to add to instance and let it be processed by buddy_added handler
+ if (pszCmd = strtok(NULL, "\n"))
+ {
+ if (pInst->pszBuddiesToAdd) free(pInst->pszBuddiesToAdd);
+ pInst->pszBuddiesToAdd = strdup(pszCmd);
+ }
+ }
+ else
+ Send (pInst, "ERROR 503 CHAT: Invalid or unknown action");
+ return;
+ }
+ else
+ if (strcasecmp(pszCmd, "CALL") == 0)
+ {
+ NICKENTRY *pUser;
+
+ if (!(pszCmd = strtok(NULL, " ")) || !(pUser = BuddyList_Find(pInst->hBuddyList, pszCmd)))
+ {
+ Send (pInst, "ERROR 26 Invalid user handle");
+ return;
+ }
+
+ ImoSkype_StartVoiceCall (pInst->hInst, pUser->pszUser);
+ return;
+ }
+ else
+ if (strcasecmp(pszCmd, "OPEN") == 0)
+ {
+ return;
+ }
+ else
+ if (strcasecmp(pszCmd, "CREATE") == 0)
+ {
+ if (!(pszCmd = strtok(NULL, " ")))
+ {
+ Send (pInst, "ERROR 536 CREATE: no object or type given");
+ return;
+ }
+ if (strcasecmp(pszCmd, "APPLICATION") == 0)
+ {
+ if (!(pszCmd = strtok(NULL, " ")) || strcasecmp(pszCmd, "libpurple_typing"))
+ Send (pInst, "ERROR 540 CREATE APPLICATION: Missing or invalid name");
+ else
+ Send (pInst, "CREATE APPLICATION libpurple_typing");
+ }
+ else
+ Send (pInst, "ERROR 537 CREATE: Unknown object type given");
+ return;
+ }
+ else
+ if (strcasecmp(pszCmd, "DELETE") == 0)
+ {
+ if (!(pszCmd = strtok(NULL, " ")))
+ {
+ Send (pInst, "ERROR 538 DELETE: no object or type given");
+ return;
+ }
+ if (strcasecmp(pszCmd, "APPLICATION") == 0)
+ {
+ if (!(pszCmd = strtok(NULL, " ")) || strcasecmp(pszCmd, "libpurple_typing"))
+ Send (pInst, "ERROR 542 DELETE APPLICATION: Missing or invalid application name");
+ else
+ Send (pInst, "DELETE APPLICATION libpurple_typing");
+ }
+ else
+ Send (pInst, "ERROR 539 DELETE: Unknown object type given");
+ return;
+ }
+ else
+ if (strcasecmp(pszCmd, "ALTER") == 0)
+ {
+ if (!(pszCmd = strtok(NULL, " ")))
+ Send (pInst, "ERROR 526 ALTER: no object type given");
+ else
+ {
+ if (strcasecmp(pszCmd, "APPLICATION") == 0)
+ {
+ if (!(pszCmd = strtok(NULL, " ")) || strcasecmp(pszCmd, "libpurple_typing") ||
+ !(pszCmd = strtok(NULL, " ")))
+ Send (pInst, "ERROR 545 ALTER: missing or invalid action");
+ else
+ {
+ NICKENTRY *pUser;
+
+ if (strcasecmp (pszCmd, "CONNECT") == 0)
+ {
+ if (!(pszCmd = strtok(NULL, " ")) || !(pUser = BuddyList_Find(pInst->hBuddyList, pszCmd)))
+ Send (pInst, "ERROR 547 ALTER APPLICATION CONNECT: Invalid user handle");
+ else
+ {
+ Send (pInst, "ALTER APPLICATION libpurple_typing CONNECT %s", pszCmd);
+ Send (pInst, "APPLICATION CONNECTING %s", pszCmd);
+ Send (pInst, "APPLICATION libpurple_typing STREAMS %s:1", pszCmd);
+ // FIXME: Shouldn't we enumerate all STREAMS here? dunno...
+ }
+ } else
+ if (strcasecmp (pszCmd, "DATAGRAM") == 0)
+ {
+ char *pSep;
+
+ if (!(pszCmd = strtok(NULL, " ")) || !(pSep = strchr(pszCmd, ':')))
+ Send (pInst, "ERROR 551 ALTER APPLICATION DATAGRAM: Missing or invalid stream identifier");
+ else
+ {
+ *pSep=0;
+ if (!(pUser = BuddyList_Find(pInst->hBuddyList, pszCmd)))
+ Send (pInst, "ERROR 551 ALTER APPLICATION DATAGRAM: Missing or invalid stream identifier");
+ else
+ {
+ *pSep=':';
+ if (!(pszCmd = strtok(NULL, " ")))
+ Send (pInst, "ERROR 541 APPLICATION: Operation failed");
+ else
+ {
+ if (!strcmp (pszCmd, "PURPLE_TYPING"))
+ ImoSkype_Typing (pInst->hInst, pUser->pszUser, "typing");
+ else if (!strcmp (pszCmd, "PURPLE_TYPED"))
+ ImoSkype_Typing (pInst->hInst, pUser->pszUser, "typed");
+ else if (!strcmp (pszCmd, "PURPLE_NOT_TYPING"))
+ ImoSkype_Typing (pInst->hInst, pUser->pszUser, "not_typing");
+ }
+ }
+ }
+ }
+ }
+
+ }
+ else
+ if (strcasecmp(pszCmd, "CHAT") == 0)
+ {
+ char *pszChat;
+ NICKENTRY *pChat;
+
+ if (!(pszChat = strtok(NULL, " ")) ||
+ !(pChat=BuddyList_Find(pInst->hBuddyList, pszChat)))
+ {
+ Send (pInst, "ERROR 14 Invalid message id");
+ return;
+ }
+
+
+ if (!(pszCmd = strtok(NULL, " ")))
+ {
+ Send (pInst, "ERROR 503 CHAT: Invalid or unknown action");
+ return;
+ }
+
+ if (strcasecmp (pszCmd, "ADDMEMBERS") == 0)
+ {
+ while(pszCmd = strtok(NULL, ", "))
+ {
+ ImoSkype_GroupInvite (pInst->hInst, pChat->pszUser, pszCmd);
+ }
+ }
+ else if (strcasecmp (pszCmd, "KICK") == 0)
+ {
+ while(pszCmd = strtok(NULL, ", "))
+ {
+ ImoSkype_GroupKick (pInst->hInst, pChat->pszUser, pszCmd);
+ }
+ }
+ else if (strcasecmp (pszCmd, "SETTOPIC") == 0)
+ {
+ if(pszCmd = strtok(NULL, ""))
+ {
+ ImoSkype_GroupTopic (pInst->hInst, pChat->pszUser, pszCmd);
+ }
+ }
+ else if (strcasecmp (pszCmd, "LEAVE") == 0)
+ {
+ if(pszCmd = strtok(NULL, ""))
+ {
+ ImoSkype_GroupLeave (pInst->hInst, pChat->pszUser);
+ }
+ }
+ else Send (pInst, "ERROR 503 CHAT: Invalid or unknown action");
+ } else
+ Send (pInst, "ERROR 527 ALTER: unknown object type given");
+ }
+ return;
+ }
+ else
+ if (strcasecmp(pszCmd, "NAME") == 0)
+ {
+ if (pszCmd = strtok(NULL, " "))
+ {
+ if (pInst->pszClientName) free(pInst->pszClientName);
+ pInst->pszClientName = strdup(pszCmd);
+ }
+ Send (pInst, "OK");
+ return;
+ }
+ else
+ {
+ Send (pInst, "ERROR 2 Not Implemented");
+ }
+}
+
+// -----------------------------------------------------------------------------
+
diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/imo2skypeapi.h b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/imo2skypeapi.h new file mode 100644 index 0000000000..fa68dd3899 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/imo2skypeapi.h @@ -0,0 +1,13 @@ +typedef void(*IMO2SCB)(char *pszMsg, void *pUser);
+struct _tagIMOSAPI;
+typedef struct _tagIMOSAPI IMOSAPI;
+
+#define IMO2S_FLAG_CURRTIMESTAMP 1 // Use current timestamp on MSG receive
+#define IMO2S_FLAG_ALLOWINTERACT 2 // Allow GUI interaction (CALL)
+
+IMOSAPI *Imo2S_Init(IMO2SCB Callback, void *pUser, int iFlags);
+void Imo2S_Exit (IMOSAPI *pInst);
+void Imo2S_SetLog (IMOSAPI *pInst, FILE *fpLog);
+int Imo2S_Login (IMOSAPI *pInst, char *pszUser, char *pszPass, char **ppszError);
+void Imo2S_Logout(IMOSAPI *pInst);
+int Imo2S_Send (IMOSAPI *pInst, char *pszMsg);
diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/imo2sproxy.c b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/imo2sproxy.c new file mode 100644 index 0000000000..1615d6ac46 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/imo2sproxy.c @@ -0,0 +1,78 @@ +/* Module: imo2skypeproxy.c
+ Purpose: Implementation of imo2skype API as Skype proxy (for Miranda Skype plugin)
+ Author: leecher
+ Date: 01.09.2009
+
+ Changelog:
+ 1.00 - 01.09.2009 - Initial release
+ 1.01 - 02.09.2009 - Little bugfix for Onlinestatus, introduced mutex for send thread.
+ 1.02 - 02.09.2009 - Added support for incoming call notifications and expired sessions.
+ 1.03 - 03.09.2009 - As WIN32-port of libcurl is a total mess, Win32-version now uses WinINET.
+ 1.04 - 04.09.2009 - Added support for searching, adding and removing buddies
+ 1.05 - 06.09.2009 - * Mapped "busy" to DND, not NA, as forum user AL|EN proposed.
+ * Mood text will now also be sent on status change of a contact
+ (doesn't really have an effect though)
+ * New Parameter -d (daemonize) to launch proxy in background
+ * Fixed a bug with a crash when encoding umlauts on Win32
+ 1.06 - 25.09.2009 - Added parameter -t for local timestamps.
+ 1.07 - 07.10.2009 - Bugfix: Added parsing of multiple JSON messages
+ Added support for writing to logfile while in daemon mode (-l)
+ 1.08 - 18.10.2009 - Added support for voice calls via imo.im flash on WIN32 (-i)
+ - Limited memory queues to 50 entries to reduce memory usage.
+ 1.09 - 07.11.2009 - Split command line main module and proxy module to make proxy
+ accessible by different layers (i.e. new Miranda Plugin layer)
+ 1.10 - 14.12.2009 - Bug in the cJson library. The authors used the String as second
+ sprintf-Parameter which contains the format string instead of
+ ["%s", StringParam] causing problems sending Messages containt a %
+ - Added some space in the dialog for translations and added Translate()
+ function to some strings in the Wrapper-DLL
+ - More verbose output if you enable logging
+ - Fixes a Bug that caused the plugin to block after going offline
+ and reconnecting back online
+ - Hopefully fixed a severe threading problem: The Send-Mutex was not
+ covering a full transaction, but only 1 send causing the receiver
+ the receive garbled data causing "An existing connection was forcibly
+ closed by the remote host." error.
+ - Imo2S_Exit freed the temporary buffer too early resulting in a crash
+ on exit.
+ 1.12 - 19.04.2010 - POST interface changed from www.imo.im/amy to s.imo.im/amy
+ 1.13 - 19.12.2010 - imo.im modified their interface, so tried to adapt the communication
+ routines at low level to be compatible again. There still may be
+ many bugs. Don't forget to turn off history logging in the options
+ at https://imo.im
+ There also seems to be a nice new feature called "reflection" so that
+ you can login from multiple sessions and messages etc. entered there
+ will be reflected to the current session. This may be addressed in one
+ of the next builds...
+ 1.14 - 02.03.2011 - Added a Skype WIN32-API Emulation Layer for better compatibility with
+ other clients that don't want to implement the socks-protocol, so that
+ we are compatible out-of-the-box.
+ - Added a few features to be compatible with libpurple. i.e. we now support
+ message numbering, even tough this is only supported in PROTOCOL 4.
+ - Added Keepalive packet sending to circumvent imo.im AutoAway.
+ 1.15 - 18.07.2012 - Avatar support
+ - Support for new imo.im protocol, can now be compiled to use old or new
+ protocol, in case there are troubles. New protocol enables participation
+ in groupchats generated with native Skype client with at least 3
+ participants (still a bit experimental)
+ - WININET HTTPS communication layer now uses async calls to try to prevent
+ lockups on connection loss.
+*/
+
+#include <memory.h>
+#include "imo2sproxy.h"
+
+// -----------------------------------------------------------------------------
+// PUBLIC
+// -----------------------------------------------------------------------------
+
+void Imo2sproxy_Defaults (IMO2SPROXY_CFG *pCfg)
+{
+ memset (pCfg, 0, sizeof(IMO2SPROXY_CFG));
+ pCfg->fpLog = stdout;
+ pCfg->logerror = fprintf;
+}
+
+/* Real implementation is now in socksproxy.c for the socket communication method
+ and in w32skypeemu.c for the Window messages Skype emulation
+ */
diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/imo2sproxy.h b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/imo2sproxy.h new file mode 100644 index 0000000000..dbdbbf1cf7 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/imo2sproxy.h @@ -0,0 +1,28 @@ +#include <stdio.h>
+#include "imo2skypeapi.h"
+#ifndef WIN32
+#define __cdecl
+#endif
+
+typedef struct
+{
+ int bVerbose;
+ FILE *fpLog;
+ int iFlags;
+ int (__cdecl *logerror)( FILE *stream, const char *format, ...);
+// FIXME: user+pass from cmdline, until there is a possibility for
+// a client to authenticate
+ char *pszUser;
+ char *pszPass;
+} IMO2SPROXY_CFG;
+
+typedef struct tag_imo2sproxy IMO2SPROXY;
+
+struct tag_imo2sproxy
+{
+ int (*Open)(IMO2SPROXY*);
+ void (*Loop)(IMO2SPROXY*);
+ void (*Exit)(IMO2SPROXY*);
+};
+
+void Imo2sproxy_Defaults (IMO2SPROXY_CFG *pCfg);
diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/imo2stest.c b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/imo2stest.c new file mode 100644 index 0000000000..3007e3ce06 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/imo2stest.c @@ -0,0 +1,60 @@ +/* Module: imo2stest.c
+ Purpose: Simple test application for imo2skypeapi
+ Author: leecher
+ Date: 31.08.2009
+*/
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "imo2skypeapi.h"
+
+// -----------------------------------------------------------------------------
+// Static
+// -----------------------------------------------------------------------------
+static void Recv(char *pszMsg, void *pUser)
+{
+ printf ("< %s\n", pszMsg);
+}
+
+// -----------------------------------------------------------------------------
+// EIP
+// -----------------------------------------------------------------------------
+int main(int argc, char **argv)
+{
+ int iRet = -1;
+ IMOSAPI *pInst;
+ char *pszError = NULL;
+
+ if (argc<3)
+ {
+ printf ("Usage: %s [username] [password]\n", argv[0]);
+ return -1;
+ }
+
+ if (!(pInst = Imo2S_Init(Recv, NULL,0)))
+ {
+ fprintf (stderr, "Failed initialization.\n");
+ return -1;
+ }
+
+ /* Logon */
+ if (Imo2S_Login(pInst, argv[1], argv[2], &pszError) == 1)
+ {
+ /* Dispatch loop */
+ char szLine[4096]={0};
+
+ while (gets(szLine))
+ {
+ Imo2S_Send (pInst, szLine);
+ memset (szLine, 0, sizeof(szLine));
+ }
+ }
+ else
+ {
+ fprintf (stderr, "Login failed: %s\n", pszError);
+ return -1;
+ }
+
+ Imo2S_Exit (pInst);
+ return iRet;
+}
diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/main.c b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/main.c new file mode 100644 index 0000000000..872509616d --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/main.c @@ -0,0 +1,197 @@ +/* Module: main.c
+ Purpose: Main commandline dispatcher for imo.im Skypeproxy
+ Author: leecher
+ Date: 07.11.2009
+*/
+#include <stdlib.h>
+#include <stdio.h>
+#include "imo2sproxy.h"
+#include "socksproxy.h"
+#ifdef WIN32
+#include "w32skypeemu.h"
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <winsock2.h>
+#define Daemonize FreeConsole()
+#ifdef _DEBUG
+#define LOG(_args_) printf _args_
+#ifndef _WIN64
+#include "crash.c"
+#endif
+#endif
+#else
+#define Daemonize daemon(0, 0)
+#endif
+
+// -----------------------------------------------------------------------------
+// EIP
+// -----------------------------------------------------------------------------
+int main(int argc, char **argv)
+{
+ int i, j=0, bDaemon = 0;
+ char cMode='s';
+ IMO2SPROXY_CFG stCfg;
+ SOCKSPROXY_CFG stSocksCfg;
+#ifdef WIN32
+ W32SKYPEEMU_CFG stSypeEmuCfg;
+#endif
+ IMO2SPROXY *pProxy;
+
+#ifdef _DEBUG
+ Crash_Init();
+#endif
+
+ Imo2sproxy_Defaults (&stCfg);
+ SocksProxy_Defaults (&stSocksCfg);
+#ifdef WIN32
+ W32SkypeEmu_Defaults(&stSypeEmuCfg);
+#endif
+ if (argc<3)
+ {
+ printf ("imo.im Skypeproxy V1.15 - (c) by leecher 2009-2012\n\n"
+ "%s [-d] [-v [-l <Logfile>]] [-t] [-i]\n"
+ "[-m<s|a>] [-h <Bind to IP>] [-p <Port>] <Username> <Password>\n\n"
+ "-d\t- Daemonize (detach from console)\n"
+ "-v\t- Verbose mode, log commands to console\n"
+ "-l\t- Set logfile to redirect verbose log to.\n"
+ "-t\t- Ignore server timestamp and use current time for messages\n"
+ "-i\t- Use interactive mode (starts imo.im flash app upon call)\n"
+ "-m\t- Specify connection mode to use:\n"
+ "\t\ts\tSocket mode (SkypeProxy protocol) [default]\n"
+#ifdef WIN32
+ "\t\ta\tSkype API Emulation via Window messages (real Skype API)\n"
+#endif
+ "\tParameters for socket mode:\n"
+ "-h\t- Bind to a specific IP, not to all interfaces (default)\n"
+ "-p\t- Bind to another port (default: 1401)\n"
+ "Default: Bind to any interface, Use Port %d\n", argv[0], stSocksCfg.sPort);
+ return EXIT_FAILURE;
+ }
+
+ for (i=1; i<argc; i++)
+ {
+ if (argv[i][0] == '-')
+ {
+ switch (argv[i][1])
+ {
+ case 'v':
+ stCfg.bVerbose = 1;
+ break;
+ case 'l':
+ if (argc<=i+1)
+ {
+ fprintf (stderr, "Please specify logfile for -l\n");
+ return EXIT_FAILURE;
+ }
+ if (!(stCfg.fpLog = fopen(argv[++i], "a")))
+ {
+ fprintf (stderr, "Cannot open logfile %s\n", argv[i]);
+ return EXIT_FAILURE;
+ }
+ break;
+ case 'd':
+ bDaemon = 1;
+ break;
+ case 'h':
+ if (argc<=i+1)
+ {
+ fprintf (stderr, "Please specify bind IP for -h\n");
+ return EXIT_FAILURE;
+ }
+ stSocksCfg.lAddr = inet_addr(argv[++i]);
+ break;
+ case 'p':
+ if (argc<=i+1)
+ {
+ fprintf (stderr, "Please specify port for -p\n");
+ return EXIT_FAILURE;
+ }
+ stSocksCfg.sPort = atoi(argv[++i]);
+ break;
+ case 't':
+ stCfg.iFlags |= IMO2S_FLAG_CURRTIMESTAMP;
+ break;
+ case 'i':
+ stCfg.iFlags |= IMO2S_FLAG_ALLOWINTERACT;
+ break;
+ case 'm':
+ switch (argv[i][2])
+ {
+ case 'a':
+#ifndef WIN32
+ fprintf (stderr, "This mode is not available on your platform!\n");
+ return EXIT_FAILURE;
+#endif
+ case 's':
+ cMode=argv[i][2];
+ break;
+ default:
+ fprintf (stderr, "Unknown mode: %c\n", argv[i][2]);
+ return EXIT_FAILURE;
+ }
+ break;
+ default:
+ printf ("Unknown parameter: %s\n", argv[i]);
+ break;
+ }
+ }
+ else
+ {
+ switch (j)
+ {
+ case 0: stCfg.pszUser = argv[i]; break;
+ case 1: stCfg.pszPass = argv[i]; break;
+ default: printf ("Unknown extra arg: %s\n", argv[i]); break;
+ }
+ j++;
+ }
+ }
+
+ if (!stCfg.pszUser)
+ {
+ fprintf (stderr, "Please specify Username\n");
+ return EXIT_FAILURE;
+ }
+ if (!stCfg.pszPass)
+ {
+ fprintf (stderr, "Please specify Password\n");
+ return EXIT_FAILURE;
+ }
+ if (bDaemon && stCfg.bVerbose && stCfg.fpLog == stdout)
+ {
+ printf ("Parameters Verbose mode and daemonize cannot be used together, if you don't\n"
+ "specify a logfile, not daemonizing.\n");
+ bDaemon = 0;
+ }
+ if (bDaemon) Daemonize;
+
+ switch (cMode)
+ {
+ case 's':
+ if (!(pProxy = SocksProxy_Init (&stCfg, &stSocksCfg)))
+ return EXIT_FAILURE;
+ break;
+ case 'a':
+#ifdef WIN32
+ if (!(pProxy = W32SkypeEmu_Init (&stCfg, &stSypeEmuCfg)))
+ return EXIT_FAILURE;
+#else
+ fprintf (stderr, "Skype API EMulator is only available in WIN32\n");
+ return EXIT_FAILURE;
+#endif
+ break;
+ }
+
+ if (pProxy->Open(pProxy) == 0)
+ pProxy->Loop(pProxy);
+ pProxy->Exit(pProxy);
+
+ if (stCfg.fpLog && stCfg.fpLog != stdout && stCfg.fpLog != stderr)
+ {
+ fclose(stCfg.fpLog);
+ stCfg.fpLog = NULL;
+ }
+
+ return EXIT_SUCCESS;
+}
+
diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/imoproxy.c b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/imoproxy.c new file mode 100644 index 0000000000..195f479ea6 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/imoproxy.c @@ -0,0 +1,882 @@ +/* Module: imoproxy.c
+ Purpose: Proxy-DLL for Miranda IM to load imo2sproxy as plugin
+ Author: leecher
+ Date: 26.10.2009
+*/
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <winsock2.h>
+#include <prsht.h>
+#include <commdlg.h>
+#include <stdlib.h>
+#include <io.h>
+#include <fcntl.h>
+#include <process.h>
+#pragma comment (lib, "Ws2_32.lib")
+#include <stdio.h>
+#include "io_layer.h"
+#include "imo2sproxy.h"
+#include "imo_request.h"
+#include "socksproxy.h"
+#include "w32skypeemu.h"
+#include "skypepluginlink.h"
+#include "include/newpluginapi.h"
+#include "include/m_langpack.h"
+#include "include/m_options.h"
+#include "include/m_database.h"
+#include "include/m_system.h"
+#include "sdk/m_updater.h"
+#include "resource.h"
+
+// Crash dumper
+#ifdef _DEBUG
+void CrashLog (const char *pszFormat, ...)
+{
+ static FILE *fpLog = NULL;
+ char szLine[1024];
+ va_list ap;
+
+ if (!fpLog) fpLog=fopen("imoproxy.log", "a");
+ va_start(ap, pszFormat);
+ _vsnprintf(szLine, sizeof(szLine), pszFormat, ap);
+ va_end(ap);
+
+ if (fpLog)
+ {
+ fprintf (fpLog, "%s", szLine);
+ fflush (fpLog);
+ }
+}
+#define LOG(_args_) CrashLog _args_
+#ifndef _WIN64
+#include "crash.c"
+#endif
+#endif
+
+
+PLUGINLINK *pluginLink;
+HINSTANCE m_hInst;
+static HANDLE m_hOptHook=NULL, m_hPreShutdownHook=NULL, m_hHookModulesLoaded=NULL;
+
+#define PROXY_SOCKS 0
+#define PROXY_W32SKYPEEMU 1
+#define PROXY_SKYPEPLUGIN 2
+#define PROXY_MAX 3
+
+static IMO2SPROXY_CFG m_stCfg;
+static SOCKSPROXY_CFG m_stSocksCfg;
+static W32SKYPEEMU_CFG m_stSypeEmuCfg;
+static SKYPEPLUGINLINK_CFG m_stSkypePluginCfg;
+
+static IMO2SPROXY *m_apProxy[PROXY_MAX] = {0};
+static HANDLE m_hThread[PROXY_MAX]={0}, m_hEvent = INVALID_HANDLE_VALUE;
+static BOOL m_bConsole = FALSE;
+
+#define ANY_SIZE 1
+
+typedef struct _MIB_IPADDRROW {
+ DWORD dwAddr;
+ DWORD dwIndex;
+ DWORD dwMask;
+ DWORD dwBCastAddr;
+ DWORD dwReasmSize;
+ unsigned short unused1;
+ unsigned short wType;
+}MIB_IPADDRROW, *PMIB_IPADDRROW;
+
+typedef struct _MIB_IPADDRTABLE {
+ DWORD dwNumEntries;
+ MIB_IPADDRROW table[ANY_SIZE];
+}MIB_IPADDRTABLE, *PMIB_IPADDRTABLE;
+
+
+// Plugin Info
+#define PINFO \
+ "imo2sproxy-Plugin", \
+ PLUGIN_MAKE_VERSION(1,0,0,15), \
+ "Tunnelling Skype traffic via imo.im Web service", \
+ "leecher", \
+ "leecher@dose.0wnz.at", \
+ "© 2010-2012 leecher", \
+ "http://dose.0wnz.at", \
+ 0, \
+ 0 //doesn't replace anything built-in
+
+
+PLUGININFO pluginInfo = {
+ sizeof(PLUGININFO),
+ PINFO
+};
+
+// New plugininfo
+PLUGININFOEX pluginInfoEx = {
+ sizeof (pluginInfoEx),
+ PINFO,
+ { 0x3005c2b1, 0x4278, 0x470c, { 0x94, 0x98, 0x5, 0x95, 0x3d, 0xfa, 0x4d, 0x88 } } // // {3005C2B1-4278-470c-9498-05953DFA4D88}
+};
+
+// Whatever this is...
+// {95061E8D-B18C-4c1c-8E14-686DE967D851}
+#define MIID_IMOPROXY { 0x95061e8d, 0xb18c, 0x4c1c, { 0x8e, 0x14, 0x68, 0x6d, 0xe9, 0x67, 0xd8, 0x51 } }
+static const MUUID interfaces[] = { MIID_IMOPROXY, MIID_LAST };
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+
+int ShowError( FILE *stream, const char *format, ...)
+{
+ char szBuf[1024];
+ va_list ap;
+ int iRet;
+
+ va_start(ap, format);
+ iRet = _vsnprintf (szBuf, sizeof(szBuf), format, ap);
+ va_end(ap);
+
+ MessageBox (NULL, szBuf, Translate("IMOPROXY Error"), MB_ICONSTOP | MB_OK);
+ return iRet;
+}
+
+// -----------------------------------------------------------------------------
+
+static void LoadSettings(void)
+{
+ DBVARIANT dbv;
+
+ // General config
+ if (!m_bConsole)
+ {
+ if (DBGetContactSetting(NULL, "IMOPROXY", "Logfile", &dbv)==0)
+ {
+ if ((m_stCfg.bVerbose = DBGetContactSettingByte(NULL, "IMOPROXY", "Verbose", 0)) &&
+ *dbv.pszVal)
+ {
+ if (m_stCfg.fpLog) fclose (m_stCfg.fpLog);
+ if (!(m_stCfg.fpLog = fopen(dbv.pszVal, "a")))
+ {
+ char szMsg[MAX_PATH+64];
+
+ sprintf (szMsg, Translate("Cannot open Logfile %s for writing."), dbv.pszVal);
+ MessageBox(NULL,szMsg,"IMOPROXY", MB_OK | MB_ICONWARNING);
+ m_stCfg.bVerbose = FALSE;
+ }
+ }
+ DBFreeVariant(&dbv);
+ }
+ }
+ m_stCfg.iFlags = DBGetContactSettingDword(NULL, "IMOPROXY", "Flags", 0);
+ if (DBGetContactSetting(NULL, "IMOPROXY", "User", &dbv)==0)
+ {
+ if (m_stCfg.pszUser) free(m_stCfg.pszUser);
+ m_stCfg.pszUser = strdup(dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ if (DBGetContactSetting(NULL, "IMOPROXY", "Password", &dbv)==0)
+ {
+ if (m_stCfg.pszPass) free(m_stCfg.pszPass);
+ m_stCfg.pszPass = strdup(dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+
+ // Socks Proxy config
+ m_stSocksCfg.sPort = DBGetContactSettingWord(NULL, "IMOPROXY", "Port", 1401);
+ if (DBGetContactSetting(NULL, "IMOPROXY", "Host", &dbv)==0)
+ {
+ m_stSocksCfg.lAddr = inet_addr(dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+static BOOL CheckSettings(int iMask)
+{
+ DBVARIANT dbv;
+
+ if (iMask & PROXY_SOCKS)
+ {
+ if (DBGetContactSetting(NULL, SKYPE_PROTONAME, "Host", &dbv)==0)
+ {
+ if (DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "UseSkype2Socket", 0) &&
+ (lstrcmp (dbv.pszVal, "127.0.0.1")==0 ||
+ lstrcmp (dbv.pszVal, "localhost")==0) &&
+ DBGetContactSettingWord(NULL, SKYPE_PROTONAME, "Port", 0) ==
+ DBGetContactSettingWord(NULL, "IMOPROXY", "Port", 1401))
+ {
+ DBFreeVariant(&dbv);
+ return TRUE;
+ }
+ DBFreeVariant(&dbv);
+ }
+ }
+ if (DBGetContactSettingByte(NULL, SKYPE_PROTONAME, "FirstRun", 9) == 9)
+ {
+ MessageBox (NULL, Translate("SKYPE plugin may not be installed, this plugin only works together with "
+ "the SKYPE-plugin. Please check if you installed and enabled it."), "IMOPROXY",
+ MB_OK | MB_ICONWARNING);
+ }
+ else
+ {
+
+ if ((iMask & PROXY_SOCKS) && !ServiceExists(SKYPE_PROTONAME PSS_SKYPEAPIMSG) )
+ {
+ if (MessageBox (NULL, Translate("Your Skype plugin currently doesn't seem to be setup to use imo2proxy, "
+ "do you want me to change its settings so that it uses this plugins?"), "IMOPROXY",
+ MB_YESNO | MB_ICONQUESTION) == IDYES)
+ {
+ DBWriteContactSettingByte (NULL, SKYPE_PROTONAME, "UseSkype2Socket", 1);
+ DBWriteContactSettingWord (NULL, SKYPE_PROTONAME, "Port", m_stSocksCfg.sPort);
+ DBWriteContactSettingString (NULL, SKYPE_PROTONAME, "Host", "127.0.0.1");
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------------
+
+static BOOL EnumNetInterfaces (HWND hwndControl)
+{
+ HINSTANCE hLib;
+ BOOL bRet = FALSE;
+
+ if (hLib = LoadLibrary("Iphlpapi.dll"))
+ {
+ PMIB_IPADDRTABLE pTable;
+ ULONG uSize=1;
+ DWORD i;
+ FARPROC GetIpAddrTable;
+
+ if (GetIpAddrTable = (FARPROC)GetProcAddress (hLib, "GetIpAddrTable"))
+ {
+ if ((GetIpAddrTable (&pTable, &uSize, TRUE) == ERROR_INSUFFICIENT_BUFFER) &&
+ (pTable = HeapAlloc (GetProcessHeap(), 0, uSize)))
+ {
+ if (GetIpAddrTable (pTable, &uSize, TRUE) == NO_ERROR)
+ {
+ struct in_addr addr;
+
+ for (i=0; i<pTable->dwNumEntries; i++)
+ {
+ addr.S_un.S_addr = pTable->table[i].dwAddr;
+ SendMessage (hwndControl, CB_ADDSTRING, 0, (LPARAM)inet_ntoa(addr));
+ }
+ bRet = pTable->dwNumEntries > 0;
+ }
+ HeapFree (GetProcessHeap(), 0, pTable);
+ }
+ }
+ FreeLibrary (hLib);
+ }
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+static DWORD WINAPI ProxyThread(IMO2SPROXY *pProxy)
+{
+ if (pProxy->Open(pProxy)<0) return -1;
+ SetEvent (m_hEvent);
+ pProxy->Loop(pProxy);
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+
+static BYTE GetProxies(void)
+{
+ return DBGetContactSettingByte(NULL, "IMOPROXY", "Proxies",
+ (ServiceExists(SKYPE_PROTONAME PSS_SKYPEAPIMSG)?(1<<PROXY_SKYPEPLUGIN):(1<<PROXY_SOCKS)));
+}
+
+// -----------------------------------------------------------------------------
+
+static BOOL StartProxy (int i)
+{
+ DWORD dwThreadId;
+ BOOL bCreateThread = FALSE, bRet = TRUE;
+ BYTE cEnabled = GetProxies();
+ HANDLE ahEvents[2];
+
+ // Username and Password must me available
+ if (!m_stCfg.pszUser || !*m_stCfg.pszUser ||
+ !m_stCfg.pszPass || !*m_stCfg.pszPass || !(cEnabled&(1<<i)) ) return FALSE;
+
+ // Start the proxy, if enabled
+ switch (i)
+ {
+ case PROXY_SOCKS:
+ if (!(m_apProxy[i]))
+ m_apProxy[i] = SocksProxy_Init (&m_stCfg, &m_stSocksCfg);
+ break;
+ case PROXY_W32SKYPEEMU:
+ if (!(m_apProxy[i]))
+ m_apProxy[i] = W32SkypeEmu_Init (&m_stCfg, &m_stSypeEmuCfg);
+ break;
+ case PROXY_SKYPEPLUGIN:
+ if (!(m_apProxy[i]))
+ m_apProxy[i] = SkypePluginLink_Init (&m_stCfg, &m_stSkypePluginCfg);
+ if (m_apProxy[i]->Open(m_apProxy[i])<0)
+ {
+ m_apProxy[i]->Exit(m_apProxy[i]);
+ return FALSE;
+ }
+ return TRUE;
+ default:
+ return FALSE;
+ }
+ if (!m_apProxy[i]) return FALSE;
+
+ // As for example W32SKYPEEMU runs its own messagepump and the Window is
+ // Registered in the Open-Function (as it can fail), we have to start
+ // our Mainloop-Thread and wait for the Open() part to finish.
+ // If it worked ok, the loop will start to run, otherwise we return
+ // an error. So we need a Mutex for synchronisation.
+ m_hEvent = ahEvents[1] = CreateEvent (NULL, FALSE, FALSE, NULL);
+
+ if (!(m_hThread[i] = ahEvents[0] = (HANDLE)_beginthreadex (NULL, 0, ProxyThread, m_apProxy[i], 0, &dwThreadId)))
+ {
+ MessageBox (NULL, Translate("IMOPROXY Cannot start dispatch thread"), "IMOPROXY", MB_OK | MB_ICONSTOP);
+ CloseHandle (m_hEvent);
+ m_apProxy[i]->Exit(m_apProxy[i]);
+ return FALSE;
+ }
+
+ bRet = WaitForMultipleObjects (2, ahEvents, FALSE, INFINITE)==WAIT_OBJECT_0+1;
+ CloseHandle (m_hEvent);
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+static void StopProxy (int i)
+{
+ if (m_apProxy[i])
+ {
+ m_apProxy[i]->Exit(m_apProxy[i]);
+ m_apProxy[i] = NULL;
+ }
+
+ if (m_hThread[i])
+ {
+ if (WaitForSingleObject (m_hThread[i], 3000) != WAIT_OBJECT_0)
+ TerminateThread (m_hThread[i], -1);
+ m_hThread[i] = NULL;
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+static BOOL StartProxies(int iMask)
+{
+ int i;
+ BOOL bRet=TRUE;
+
+ for (i=0; i<PROXY_MAX; i++)
+ if (iMask&(1<<i))
+ bRet &= StartProxy(i);
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+static void StopProxies(int iMask)
+{
+ int i;
+
+ for (i=0; i<PROXY_MAX; i++)
+ if (iMask&(1<<i))
+ StopProxy(i);
+}
+
+// -----------------------------------------------------------------------------
+
+static void UpdateProxyStatus (HWND hWnd, int iID)
+{
+ struct {
+ UINT uStatus;
+ UINT uStart;
+ UINT uStop;
+ } astStatus[] = {
+ {IDC_STATUSSOCKS, IDC_STARTSOCKS, IDC_STOPSOCKS},
+ {IDC_STATUSCOMM, IDC_STARTCOMM, IDC_STOPCOMM},
+ {IDC_STATUSSKYPEPL, IDC_STARTSKYPEPL, IDC_STOPSKYPEPL}
+ };
+
+ if (m_apProxy[iID])
+ {
+ SetDlgItemText (hWnd, astStatus[iID].uStatus, Translate("Running"));
+ EnableWindow ((HWND)GetDlgItem (hWnd, astStatus[iID].uStart), FALSE);
+ EnableWindow ((HWND)GetDlgItem (hWnd, astStatus[iID].uStop), TRUE);
+ }
+ else
+ {
+ BYTE cEnabled = GetProxies();
+
+ SetDlgItemText (hWnd, astStatus[iID].uStatus, Translate("Stopped"));
+ EnableWindow ((HWND)GetDlgItem (hWnd, astStatus[iID].uStart),
+ ((cEnabled&(1<<iID)) && m_stCfg.pszUser && *m_stCfg.pszUser &&
+ m_stCfg.pszPass && *m_stCfg.pszPass)?TRUE:FALSE);
+ EnableWindow ((HWND)GetDlgItem (hWnd, astStatus[iID].uStop), FALSE);
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+static int CALLBACK OptionsDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ static char szOldHost[64]={0}, szOldLog[MAX_PATH]={0}, szOldUser[64], szOldPass[64];
+ static short sOldPort=0;
+ static BOOL bOldVerbose=FALSE;
+ static int iOldFlags = 0, iOldProxies;
+
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ {
+ DBVARIANT dbv;
+
+ TranslateDialogDefault(hWnd);
+ EnumNetInterfaces (GetDlgItem (hWnd, IDC_BINDIP));
+ if (DBGetContactSetting(NULL, "IMOPROXY", "Host", &dbv)==0)
+ {
+ lstrcpyn (szOldHost, dbv.pszVal, sizeof(szOldHost));
+ DBFreeVariant(&dbv);
+ } else lstrcpy (szOldHost, "127.0.0.1");
+ SetDlgItemText (hWnd, IDC_BINDIP,szOldHost);
+ SetDlgItemInt (hWnd, IDC_BINDPORT, sOldPort = DBGetContactSettingWord(NULL, "IMOPROXY", "Port", 1401), FALSE);
+ iOldFlags = DBGetContactSettingDword(NULL, "IMOPROXY", "Flags", 0);
+ if (iOldFlags & IMO2S_FLAG_ALLOWINTERACT) CheckDlgButton (hWnd, IDC_INTERACT, BST_CHECKED);
+ if (iOldFlags & IMO2S_FLAG_CURRTIMESTAMP) CheckDlgButton (hWnd, IDC_CURRTIMESTAMP, BST_CHECKED);
+ if (DBGetContactSetting(NULL, "IMOPROXY", "Logfile", &dbv)==0)
+ {
+ lstrcpyn (szOldLog, dbv.pszVal, sizeof(szOldLog));
+ DBFreeVariant(&dbv);
+ }
+ if (CallService (MS_SYSTEM_GETVERSION, 0, 0) >= 0x080000)
+ {
+ EnableWindow (GetDlgItem (hWnd, IDC_USENETLIB), TRUE);
+ if (DBGetContactSettingByte (NULL, "IMOPROXY", "UseNetlib", 0))
+ CheckDlgButton (hWnd, IDC_USENETLIB, BST_CHECKED);
+ }
+ SetDlgItemText (hWnd, IDC_LOGFILE, szOldLog);
+ if (bOldVerbose = DBGetContactSettingByte(NULL, "IMOPROXY", "Verbose", 0))
+ CheckDlgButton (hWnd, IDC_LOG, BST_CHECKED);
+ else
+ {
+ EnableWindow (GetDlgItem (hWnd, IDC_LOGFILE), FALSE);
+ EnableWindow (GetDlgItem (hWnd, IDC_OPEN), FALSE);
+ }
+ if (DBGetContactSetting(NULL, "IMOPROXY", "User", &dbv)==0)
+ {
+ lstrcpyn (szOldUser, dbv.pszVal, sizeof(szOldUser));
+ DBFreeVariant(&dbv);
+ }
+ SetDlgItemText (hWnd, IDC_USERNAME, szOldUser);
+ if (DBGetContactSetting(NULL, "IMOPROXY", "Password", &dbv)==0)
+ {
+ lstrcpyn (szOldPass, dbv.pszVal, sizeof(szOldPass));
+ DBFreeVariant(&dbv);
+ }
+ iOldProxies= GetProxies();
+ CheckDlgButton (hWnd, IDC_USESOCKS, (iOldProxies&(1<<PROXY_SOCKS))?BST_CHECKED:BST_UNCHECKED);
+ CheckDlgButton (hWnd, IDC_USECOMM, (iOldProxies&(1<<PROXY_W32SKYPEEMU))?BST_CHECKED:BST_UNCHECKED);
+ if (ServiceExists(SKYPE_PROTONAME PSS_SKYPEAPIMSG))
+ {
+ CheckDlgButton (hWnd, IDC_USESKYPEPL, (iOldProxies&(1<<PROXY_SKYPEPLUGIN))?BST_CHECKED:BST_UNCHECKED);
+ UpdateProxyStatus (hWnd, PROXY_SKYPEPLUGIN);
+ }
+ else
+ {
+ EnableWindow (GetDlgItem (hWnd, IDC_USESKYPEPL), FALSE);
+ EnableWindow (GetDlgItem (hWnd, IDC_STARTSKYPEPL), FALSE);
+ }
+ SetDlgItemText (hWnd, IDC_PASSWORD, szOldPass);
+ UpdateProxyStatus (hWnd, PROXY_SOCKS);
+ UpdateProxyStatus (hWnd, PROXY_W32SKYPEEMU);
+#ifdef _DEBUG
+ EnableWindow (GetDlgItem(hWnd, IDC_CONSOLE), TRUE);
+#endif
+ return TRUE;
+ }
+ case WM_NOTIFY:
+ {
+ NMHDR* nmhdr = (NMHDR*)lParam;
+
+ switch (nmhdr->code)
+ {
+ case PSN_APPLY:
+ case PSN_KILLACTIVE:
+ {
+ int iFlags=0, iProxies=0;
+ short sPort;
+ char szHost[64], szLog[MAX_PATH], szUser[64], szPass[64];
+ BOOL bVerbose;
+
+ GetDlgItemText (hWnd, IDC_BINDIP, szHost, sizeof(szHost));
+ DBWriteContactSettingString (NULL, "IMOPROXY", "Host", szHost);
+ DBWriteContactSettingWord (NULL, "IMOPROXY", "Port",
+ (sPort = GetDlgItemInt (hWnd, IDC_BINDPORT, NULL, FALSE)));
+ if (IsDlgButtonChecked (hWnd, IDC_INTERACT)==BST_CHECKED)
+ iFlags|=IMO2S_FLAG_ALLOWINTERACT;
+ if (IsDlgButtonChecked (hWnd, IDC_CURRTIMESTAMP)==BST_CHECKED)
+ iFlags|=IMO2S_FLAG_CURRTIMESTAMP;
+ GetDlgItemText (hWnd, IDC_USERNAME, szUser, sizeof(szUser));
+ DBWriteContactSettingString (NULL, "IMOPROXY", "User", szUser);
+ GetDlgItemText (hWnd, IDC_PASSWORD, szPass, sizeof(szPass));
+ DBWriteContactSettingString (NULL, "IMOPROXY", "Password", szPass);
+ DBWriteContactSettingDword (NULL, "IMOPROXY", "Flags", iFlags);
+ DBWriteContactSettingByte(NULL, "IMOPROXY", "Verbose",
+ (char)(bVerbose = (IsDlgButtonChecked (hWnd, IDC_LOG)==BST_CHECKED)));
+ GetDlgItemText (hWnd, IDC_LOGFILE, szLog, sizeof(szLog));
+ DBWriteContactSettingString (NULL, "IMOPROXY", "Logfile", szLog);
+ if (IsDlgButtonChecked (hWnd, IDC_USESOCKS)==BST_CHECKED)
+ iProxies|=(1<<PROXY_SOCKS);
+ if (IsDlgButtonChecked (hWnd, IDC_USECOMM)==BST_CHECKED)
+ iProxies|=(1<<PROXY_W32SKYPEEMU);
+ if (IsDlgButtonChecked (hWnd, IDC_USESKYPEPL)==BST_CHECKED)
+ iProxies|=(1<<PROXY_SKYPEPLUGIN);
+ DBWriteContactSettingByte(NULL, "IMOPROXY", "UseNetlib",
+ (char)(IsDlgButtonChecked (hWnd, IDC_USENETLIB)==BST_CHECKED));
+ DBWriteContactSettingByte(NULL, "IMOPROXY", "Proxies", (char)iProxies);
+ iProxies^=iOldProxies;
+ if (sPort != sOldPort || lstrcmp (szOldHost, szHost))
+ iProxies|=(1<<PROXY_SOCKS);
+
+ if (lstrcmp (szOldLog, szLog) || bOldVerbose != bVerbose ||
+ lstrcmp (szOldUser, szUser) || lstrcmp(szOldPass, szPass) ||
+ iFlags != iOldFlags)
+ iProxies=(1<<PROXY_MAX)-1;
+
+ /*
+ StopProxies(iProxies);
+ LoadSettings();
+ CheckSettings(iProxies);
+ StartProxies(iProxies);
+ */
+ UpdateProxyStatus (hWnd, PROXY_SOCKS);
+ UpdateProxyStatus (hWnd, PROXY_W32SKYPEEMU);
+ if (ServiceExists(SKYPE_PROTONAME PSS_SKYPEAPIMSG))
+ UpdateProxyStatus (hWnd, PROXY_SKYPEPLUGIN);
+ return TRUE;
+ }
+ }
+ break;
+ }
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case IDC_LOG:
+ {
+ BOOL bEnable = (SendMessage ((HWND)lParam, BM_GETCHECK, 0, 0)==BST_CHECKED);
+
+ EnableWindow (GetDlgItem (hWnd, IDC_LOGFILE), bEnable);
+ EnableWindow (GetDlgItem (hWnd, IDC_OPEN), bEnable);
+ break;
+ }
+ case IDC_OPEN:
+ {
+ char szFilename[MAX_PATH];
+ OPENFILENAME ofn={0};
+
+ GetDlgItemText (hWnd, IDC_LOGFILE, szFilename, sizeof(szFilename));
+ ofn.lStructSize=sizeof(OPENFILENAME);
+ ofn.hwndOwner=hWnd;
+ ofn.Flags=OFN_HIDEREADONLY;
+ ofn.lpstrTitle=Translate("Select where log file will be created");
+ ofn.lpstrFilter=Translate("All files (*.*)\0*.*\0");
+ ofn.lpstrFile=szFilename;
+ ofn.nMaxFile=sizeof(szFilename)-2;
+ ofn.nMaxFileTitle=sizeof(szFilename);
+ if(GetSaveFileName(&ofn))
+ SetDlgItemText(hWnd, IDC_LOGFILE, szFilename);
+ break;
+ }
+ case IDC_STARTSOCKS:
+ case IDC_STARTCOMM:
+ case IDC_STARTSKYPEPL:
+ {
+ int iID;
+
+ switch (LOWORD(wParam))
+ {
+ case IDC_STARTSOCKS:
+ iID = PROXY_SOCKS;
+ break;
+ case IDC_STARTCOMM:
+ iID = PROXY_W32SKYPEEMU;
+ break;
+ case IDC_STARTSKYPEPL:
+ iID = PROXY_SKYPEPLUGIN;
+ break;
+ }
+ EnableWindow ((HWND)lParam, FALSE);
+ LoadSettings();
+ CheckSettings (1<<iID);
+ StartProxy (iID);
+ UpdateProxyStatus (hWnd, iID);
+ break;
+ }
+ case IDC_STOPSOCKS:
+ case IDC_STOPCOMM:
+ case IDC_STOPSKYPEPL:
+ {
+ int iID;
+
+ switch (LOWORD(wParam))
+ {
+ case IDC_STOPSOCKS:
+ iID = PROXY_SOCKS;
+ break;
+ case IDC_STOPCOMM:
+ iID = PROXY_W32SKYPEEMU;
+ break;
+ case IDC_STOPSKYPEPL:
+ iID = PROXY_SKYPEPLUGIN;
+ break;
+ }
+ EnableWindow ((HWND)lParam, FALSE);
+ StopProxy (iID);
+ UpdateProxyStatus (hWnd, iID);
+ break;
+ }
+ case IDC_CONSOLE:
+ {
+ CONSOLE_SCREEN_BUFFER_INFO coninfo;
+ HANDLE hStdHandle;
+ int hConHandle;
+ HMENU hMenu;
+ FILE *fp;
+ HMODULE hKernel32;
+ HWND (WINAPI *_GetConsoleWindow)(void), hWndCon;
+
+ /* Some dirty hack for a simple console. I know this isn't really
+ proper and that I should use my own console, but it's enough for
+ debugging purposes ;-)
+ */
+ if (HIWORD(wParam)!=BN_CLICKED) break;
+ switch (SendMessage ((HWND)lParam, BM_GETCHECK, 0, 0))
+ {
+ case BST_UNCHECKED:
+ if (m_stCfg.fpLog) fclose(m_stCfg.fpLog);
+ m_stCfg.fpLog = NULL;
+ LoadSettings ();
+ FreeConsole();
+ m_stCfg.bVerbose = bOldVerbose;
+ m_bConsole = FALSE;
+ break;
+ case BST_CHECKED:
+ m_bConsole = AllocConsole();
+ hStdHandle = GetStdHandle(STD_OUTPUT_HANDLE);
+ GetConsoleScreenBufferInfo(hStdHandle, &coninfo);
+ coninfo.dwSize.Y = 500;
+ SetConsoleScreenBufferSize(hStdHandle, coninfo.dwSize);
+ hConHandle = _open_osfhandle((long)hStdHandle, _O_TEXT);
+ fp = _fdopen(hConHandle, "w");
+ if (!fp)
+ {
+ FreeConsole();
+ break;
+ }
+ // Only available in Win2k or above
+ // Protect Console form closing, otherwise closing the console
+ // would Shutdown Miranda
+ if ((hKernel32 = GetModuleHandle ("kernel32.dll")) &&
+ (*(FARPROC *)&_GetConsoleWindow =
+ GetProcAddress(hKernel32, "GetConsoleWindow")) &&
+ (hWndCon = _GetConsoleWindow()))
+ {
+ hMenu = GetSystemMenu (hWndCon, FALSE);
+ DeleteMenu (hMenu, SC_CLOSE, MF_BYCOMMAND);
+ }
+ else
+ {
+ fprintf (fp, Translate("WARNING: Only close this console by pushing the Console button "
+ "in the settings dialog, otherwise you sould shutdown Miranda by closing "
+ "the Window!\n"));
+ }
+ setvbuf(fp, NULL, _IONBF, 0 );
+ if (m_stCfg.fpLog && m_stCfg.fpLog != stdout && m_stCfg.fpLog != stderr) fclose(m_stCfg.fpLog);
+ bOldVerbose = m_stCfg.bVerbose;
+ m_stCfg.bVerbose = 1;
+ m_stCfg.fpLog = fp;
+ break;
+ }
+ break;
+ }
+ }
+ SendMessage (GetParent(hWnd), PSM_CHANGED, 0, 0);
+ break;
+ }
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------------
+
+static int RegisterOptions(WPARAM wParam, LPARAM lParam)
+{
+ OPTIONSDIALOGPAGE odp={0};
+
+ odp.cbSize = sizeof(odp);
+ odp.hInstance = m_hInst;
+ odp.pszTemplate = MAKEINTRESOURCE(IDD_OPTIONS);
+ odp.pszGroup = Translate("Network");
+ odp.pszTitle = "Skype Imoproxy";
+ odp.pfnDlgProc = OptionsDlgProc;
+ odp.flags = ODPF_BOLDGROUPS;
+ CallService(MS_OPT_ADDPAGE, wParam, (LPARAM)&odp);
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+
+void RegisterToUpdate(void)
+{
+ //Use for the Updater plugin
+ if(ServiceExists(MS_UPDATE_REGISTER))
+ {
+ Update update = {0};
+ char szVersion[16];
+
+ update.szComponentName = pluginInfo.shortName;
+ update.pbVersion = (BYTE *)CreateVersionStringPlugin((PLUGININFO *)&pluginInfo, szVersion);
+ update.cpbVersion = strlen((char *)update.pbVersion);
+
+#ifdef _WIN64
+ update.szUpdateURL = "http://dose.0wnz.at/miranda/Skype/imo2sproxy_x64_binonly.zip"; // FIXME!!
+ update.szVersionURL = "http://dose.0wnz.at/miranda/Skype/"; // FIXME
+ update.pbVersionPrefix = (BYTE *)"imo2sproxy version "; //FIXME
+ update.szBetaUpdateURL = "http://dose.0wnz.at/miranda/Skype/imo2sproxy_x64_binonly.zip";
+ update.szBetaVersionURL = "http://dose.0wnz.at/miranda/Skype/";
+ update.pbBetaVersionPrefix = (BYTE *)"imo2sproxy version ";
+#else
+ update.szUpdateURL = "http://addons.miranda-im.org/feed.php?dlfile=4146";
+ update.szVersionURL = "http://addons.miranda-im.org/details.php?action=viewfile&id=4146";
+ update.pbVersionPrefix = (BYTE *)"<span class=\"fileNameHeader\">Skype to imo.im Gateway ";
+ update.szBetaUpdateURL = "http://dose.0wnz.at/miranda/Skype/imo2sproxy_w32_binonly.zip";
+ update.szBetaVersionURL = "http://dose.0wnz.at/miranda/Skype/";
+ update.pbBetaVersionPrefix = (BYTE *)"imo2sproxy version ";
+#endif
+
+ update.cpbVersionPrefix = strlen((char *)update.pbVersionPrefix);
+ update.cpbBetaVersionPrefix = strlen((char *)update.pbBetaVersionPrefix);
+
+ CallService(MS_UPDATE_REGISTER, 0, (WPARAM)&update);
+
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+int PreShutdown(WPARAM wParam, LPARAM lParam)
+{
+ OutputDebugString ("IMOPROXY: PreShutdown");
+ StopProxies (-1);
+ if (m_stCfg.fpLog && m_stCfg.fpLog != stdout && m_stCfg.fpLog != stderr)
+ {
+ fclose(m_stCfg.fpLog);
+ m_stCfg.fpLog = NULL;
+ }
+ if (m_stCfg.pszUser)
+ {
+ free(m_stCfg.pszUser);
+ m_stCfg.pszUser = NULL;
+ }
+ if (m_stCfg.pszPass)
+ {
+ free(m_stCfg.pszPass);
+ m_stCfg.pszPass = NULL;
+ }
+
+ FreeConsole();
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+
+int OnModulesLoaded(WPARAM wParam, LPARAM lParam)
+{
+ BYTE CheckSkype = DBGetContactSettingByte (NULL, "IMOPROXY", "CheckSkype", 2);
+ if (CheckSkype) CheckSettings(-1);
+ if (CheckSkype == 2) DBWriteContactSettingByte (NULL, "IMOPROXY", "CheckSkype", 0);
+ RegisterToUpdate();
+
+ // On Miranda 0.0.0.8+ NETLIB suppotrs HTTPS, therefore we can use
+ // Netlib there
+ if (CallService (MS_SYSTEM_GETVERSION, 0, 0) >= 0x080000 &&
+ DBGetContactSettingByte (NULL, "IMOPROXY", "UseNetlib", 0))
+ ImoRq_SetIOLayer (IoLayerNETLIB_Init);
+ StartProxies(-1);
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
+{
+ m_hInst=hinstDLL;
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+
+__declspec(dllexport) PLUGININFO* MirandaPluginInfo(DWORD mirandaVersion)
+{
+ return &pluginInfo;
+}
+
+// -----------------------------------------------------------------------------
+
+// New plugin API
+__declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion)
+{
+ return &pluginInfoEx;
+}
+
+// -----------------------------------------------------------------------------
+
+__declspec(dllexport) const MUUID* MirandaPluginInterfaces(void)
+{
+ return interfaces;
+}
+
+// -----------------------------------------------------------------------------
+
+int __declspec(dllexport) Load(PLUGINLINK *link)
+{
+
+#ifdef _DEBUG
+ Crash_Init();
+#endif
+ pluginLink = link;
+
+ // Init IMO2S config structures
+ Imo2sproxy_Defaults (&m_stCfg);
+ SocksProxy_Defaults (&m_stSocksCfg);
+ W32SkypeEmu_Defaults(&m_stSypeEmuCfg);
+ SkypePluginLink_Defaults(&m_stSkypePluginCfg);
+ m_stCfg.logerror = ShowError;
+ LoadSettings();
+
+ m_hOptHook = HookEvent(ME_OPT_INITIALISE, RegisterOptions);
+ m_hPreShutdownHook = HookEvent(ME_SYSTEM_PRESHUTDOWN, PreShutdown);
+ m_hHookModulesLoaded = HookEvent( ME_SYSTEM_MODULESLOADED, OnModulesLoaded);
+
+ OutputDebugString ("IMOPROXY: Loaded");
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+
+int __declspec(dllexport) Unload(void)
+{
+ OutputDebugString ("IMOPROXY: Unload");
+ UnhookEvent(m_hOptHook);
+ UnhookEvent(m_hPreShutdownHook);
+ UnhookEvent(m_hHookModulesLoaded);
+ return 0;
+}
diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/io_layer_netlib.c b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/io_layer_netlib.c new file mode 100644 index 0000000000..378f72e65f --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/io_layer_netlib.c @@ -0,0 +1,340 @@ +/* Module: io_layer_netlib.c
+ Purpose: IO Layer for Internet communication using Miranda NETLIB
+ Author: leecher
+ Date: 20.04.2011 :=)
+*/
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <winsock2.h>
+#include <stdlib.h>
+#include "include/newpluginapi.h"
+#include "include/m_netlib.h"
+#include "fifo.h"
+#include "memlist.h"
+#include "io_layer.h"
+
+#define USER_AGENT "Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13"
+
+typedef struct
+{
+ IOLAYER vtbl;
+ int iRecursion;
+ NETLIBHTTPREQUEST *nlhrReply;
+ LPVOID lpErrorBuf;
+ HANDLE nlc;
+} IOLAYER_INST;
+
+typedef struct
+{
+ HANDLE hNetlib;
+ TYP_LIST *hCookies;
+ TYP_FIFO *hCookieStr;
+ char *pszCookies;
+ LONG lRefCount;
+ CRITICAL_SECTION cs;
+} IOLAYER_SINGLETON;
+
+static IOLAYER_SINGLETON *m_hNL = NULL;
+
+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);
+static void add_cookies(char *pszCookies);
+static void refresh_cookies();
+static HANDLE *OpenConnection(NETLIBHTTPREQUEST *nlhr);
+
+// -----------------------------------------------------------------------------
+// Interface
+// -----------------------------------------------------------------------------
+
+IOLAYER *IoLayerNETLIB_Init(void)
+{
+ IOLAYER_INST *hIO;
+
+ if (CallService (MS_SYSTEM_GETVERSION, 0, 0) < 0x080000 || // Miranda HTTPS support starting with 0.8.0.0
+ !(hIO = calloc(1, sizeof(IOLAYER_INST))))
+ return NULL;
+
+ // NETLIB only works as singleton
+ if (!m_hNL)
+ {
+ NETLIBUSER nlu={0};
+
+ if (!(m_hNL = calloc (1, sizeof(IOLAYER_SINGLETON))))
+ {
+ free (hIO);
+ return NULL;
+ }
+ m_hNL->lRefCount++;
+
+ // Init Netlib
+ nlu.cbSize = sizeof(nlu);
+ nlu.flags = NUF_OUTGOING;
+ nlu.szDescriptiveName = "imo2sproxy connection";
+ nlu.szSettingsModule = "IMOPROXY";
+ nlu.szHttpGatewayUserAgent = USER_AGENT;
+ if (!(m_hNL->hNetlib = (HANDLE)CallService (MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu)) ||
+ !(m_hNL->hCookies = List_Init(0)) ||
+ !(m_hNL->hCookieStr = Fifo_Init(0)))
+ {
+ IoLayer_Exit((IOLAYER*)hIO);
+ return NULL;
+ }
+ m_hNL->pszCookies = "";
+ InitializeCriticalSection (&m_hNL->cs);
+ } else m_hNL->lRefCount++;
+
+ // 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->nlhrReply) CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT,0,(LPARAM)hIO->nlhrReply);
+ if (hIO->lpErrorBuf) LocalFree(hIO->lpErrorBuf);
+ if (InterlockedDecrement(&m_hNL->lRefCount) <= 0)
+ {
+ if (m_hNL->hNetlib) Netlib_CloseHandle (m_hNL->hNetlib);
+ if (m_hNL->hCookies) {
+ List_FreeElements(m_hNL->hCookies);
+ List_Exit (m_hNL->hCookies);
+ }
+ if (m_hNL->hCookieStr) Fifo_Exit(m_hNL->hCookieStr);
+ DeleteCriticalSection (&m_hNL->cs);
+ free (m_hNL);
+ m_hNL = NULL;
+ }
+ free (hIO);
+}
+
+// -----------------------------------------------------------------------------
+
+static char *IoLayer_Post(IOLAYER *hPIO, char *pszURL, char *pszPostFields, unsigned int cbPostFields, unsigned int *pdwLength)
+{
+ IOLAYER_INST *hIO = (IOLAYER_INST*)hPIO;
+ NETLIBHTTPREQUEST nlhr={0};
+ NETLIBHTTPHEADER headers[5];
+ int i;
+ char *pszCookies = NULL;
+
+
+ /*
+ char szDbg[256];
+ sprintf (szDbg, "Thread %d with hIO %08X requests %s\n", GetCurrentThreadId(), hIO, pszURL);
+ OutputDebugString(szDbg);
+ */
+
+ // Build basic request
+ nlhr.cbSize = sizeof(nlhr);
+ nlhr.flags = NLHRF_GENERATEHOST | NLHRF_SMARTREMOVEHOST | NLHRF_REDIRECT;
+ if (!pdwLength) nlhr.flags |= NLHRF_DUMPASTEXT; // pdwLength needed -> Binary data
+ nlhr.requestType = pszPostFields?REQUEST_POST:REQUEST_GET;
+ nlhr.szUrl = pszURL;
+ nlhr.pData = pszPostFields;
+ nlhr.dataLength = cbPostFields;
+ nlhr.headers = headers;
+
+ // Add headers
+ EnterCriticalSection (&m_hNL->cs);
+ if (m_hNL->pszCookies && *m_hNL->pszCookies)
+ {
+ headers[nlhr.headersCount].szName = "Cookie";
+ headers[nlhr.headersCount++].szValue = pszCookies = strdup(m_hNL->pszCookies);
+ }
+ headers[nlhr.headersCount].szName = "User-Agent";
+ headers[nlhr.headersCount++].szValue = USER_AGENT;
+ headers[nlhr.headersCount].szName = "Accept-Encoding";
+ headers[nlhr.headersCount++].szValue = "deflate, gzip";
+ headers[nlhr.headersCount].szName = "Content-Type";
+ headers[nlhr.headersCount++].szValue = "application/x-www-form-urlencoded; charset=UTF-8";
+ headers[nlhr.headersCount].szName = "X-Requested-With";
+ headers[nlhr.headersCount++].szValue = "XMLHttpRequest";
+ LeaveCriticalSection (&m_hNL->cs);
+
+ // Do the transaction
+ nlhr.nlc = hIO->nlc = OpenConnection (&nlhr);
+ if (hIO->nlhrReply) CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT,0,(LPARAM)hIO->nlhrReply);
+ hIO->nlhrReply = (NETLIBHTTPREQUEST*)CallService (MS_NETLIB_HTTPTRANSACTION, (WPARAM)m_hNL->hNetlib, (LPARAM)&nlhr);
+ hIO->nlc = NULL;
+
+ if (pszCookies) free (pszCookies);
+ if (!hIO->nlhrReply)
+ {
+ FetchLastError (hIO);
+ return NULL;
+ }
+
+ if (!hIO->nlhrReply || !hIO->nlhrReply->dataLength || !hIO->nlhrReply->pData)
+ {
+ if (hIO->lpErrorBuf) LocalFree(hIO->lpErrorBuf);
+ if (hIO->lpErrorBuf = LocalAlloc (LPTR, 64))
+ strcpy (hIO->lpErrorBuf, "Reply contained no data");
+ return NULL;
+ }
+
+ // Error handling
+ if (hIO->nlhrReply->resultCode < 200 || hIO->nlhrReply->resultCode >= 300)
+ {
+ if (hIO->lpErrorBuf) LocalFree(hIO->lpErrorBuf);
+ if (hIO->lpErrorBuf = LocalAlloc (LPTR, 64))
+ sprintf (hIO->lpErrorBuf, "HTTP transaction returned status %d", hIO->nlhrReply->resultCode);
+ return NULL;
+ }
+
+ // Process headers to collect cookies
+ EnterCriticalSection (&m_hNL->cs);
+ for (i=0; i<hIO->nlhrReply->headersCount; i++)
+ {
+ if (!strnicmp(hIO->nlhrReply->headers[i].szName, "Set-Cookie", 10))
+ add_cookies(hIO->nlhrReply->headers[i].szValue);
+ }
+ LeaveCriticalSection (&m_hNL->cs);
+
+ // Return reply
+ if (pdwLength) *pdwLength = hIO->nlhrReply->dataLength;
+ return hIO->nlhrReply->pData;
+}
+
+// -----------------------------------------------------------------------------
+
+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;
+
+ if (hIO->nlc && Netlib_CloseHandle(hIO->nlc))
+ hIO->nlc = NULL;
+}
+
+// -----------------------------------------------------------------------------
+
+static char *IoLayer_GetLastError(IOLAYER *hIO)
+{
+ return (char*)((IOLAYER_INST*)hIO)->lpErrorBuf;
+}
+
+// -----------------------------------------------------------------------------
+
+static char *IoLayer_EscapeString(IOLAYER *hPIO, char *pszData)
+{
+ return (char*)CallService (MS_NETLIB_URLENCODE, 0, (LPARAM)pszData);
+}
+
+// -----------------------------------------------------------------------------
+
+static void IoLayer_FreeEscapeString(char *pszData)
+{
+ HeapFree(GetProcessHeap(), 0, 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);
+}
+
+// -----------------------------------------------------------------------------
+
+static void add_cookies(char *pszCookies)
+{
+ int i, nCount, iLenCmp, iLenCookie;
+ char *p, *pszCookie = NULL;
+
+ if (!(p = strchr(pszCookies, '='))) return;
+ iLenCmp=p-pszCookies+1;
+ if ((p=strchr (p, ';')) || (p=strchr (p, ';'))) iLenCookie = p-pszCookies;
+ else iLenCookie=strlen(pszCookies);
+
+ for (i=0, nCount=List_Count(m_hNL->hCookies); i<nCount; i++)
+ {
+ pszCookie = (char*)List_ElementAt (m_hNL->hCookies, i);
+ if (!strncmp(pszCookie, pszCookies, iLenCmp))
+ break;
+ }
+
+ if (i==nCount) pszCookie = NULL;
+ if (pszCookie = realloc (pszCookie, iLenCookie+1))
+ {
+ strncpy (pszCookie, pszCookies, iLenCookie);
+ pszCookie[iLenCookie]=0;
+ if (i<nCount)
+ List_ReplaceElementAt (m_hNL->hCookies, pszCookie, i);
+ else
+ List_Push (m_hNL->hCookies, pszCookie);
+ }
+ refresh_cookies ();
+}
+
+// -----------------------------------------------------------------------------
+
+static void refresh_cookies()
+{
+ int i, nCount;
+
+ Fifo_Reset (m_hNL->hCookieStr);
+ for (i=0, nCount=List_Count(m_hNL->hCookies); i<nCount; i++)
+ {
+ char *pszCookie = (char*)List_ElementAt (m_hNL->hCookies, i);
+ Fifo_Add (m_hNL->hCookieStr, pszCookie, strlen(pszCookie));
+ Fifo_Add (m_hNL->hCookieStr, "; ", 2);
+ }
+ Fifo_Add (m_hNL->hCookieStr, "", 1);
+ m_hNL->pszCookies = Fifo_Get (m_hNL->hCookieStr, NULL);
+}
+
+// -----------------------------------------------------------------------------
+
+static HANDLE *OpenConnection(NETLIBHTTPREQUEST *nlhr)
+{
+ NETLIBOPENCONNECTION nloc={0};
+ BOOL secur = (nlhr->flags & NLHRF_SSL) || _strnicmp(nlhr->szUrl, "https", 5) == 0;
+ char* phost = strstr(nlhr->szUrl, "://");
+ char *ppath, *pcolon;
+
+ // Poor man's InternetCrackUrl
+ nloc.cbSize = sizeof(NETLIBOPENCONNECTION);
+ if (phost) phost+=3; else phost=nlhr->szUrl;
+ nloc.szHost = _alloca (strlen(phost)+1);
+ strcpy ((char*)nloc.szHost, phost);
+ if (ppath = strchr(nloc.szHost, '/')) *ppath = '\0';
+ if (pcolon = strrchr(nloc.szHost, ':'))
+ {
+ *pcolon = '\0';
+ nloc.wPort = (WORD)strtol(pcolon+1, NULL, 10);
+ }
+ else nloc.wPort = secur ? 443 : 80;
+ nloc.flags = (secur ? NLOCF_SSL : 0) | NLOCF_HTTP;
+ if (secur) nlhr->flags |= NLHRF_SSL; else nlhr->flags &= ~NLHRF_SSL;
+
+ // Open connection
+ return (HANDLE)CallService (MS_NETLIB_OPENCONNECTION, (WPARAM)m_hNL->hNetlib, (LPARAM)&nloc);
+}
\ No newline at end of file diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/res.aps b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/res.aps Binary files differnew file mode 100644 index 0000000000..280086f42b --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/res.aps diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/res.rc b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/res.rc new file mode 100644 index 0000000000..487426fbfe --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/res.rc @@ -0,0 +1,145 @@ +//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Deutsch (Österreich) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEA)
+#ifdef _WIN32
+LANGUAGE LANG_GERMAN, SUBLANG_GERMAN_AUSTRIAN
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_OPTIONS DIALOGEX 0, 0, 287, 224
+STYLE WS_CHILD
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Sans Serif"
+BEGIN
+ GROUPBOX "Account information",IDC_STATIC,7,7,273,31
+ LTEXT "Username:",IDC_STATIC,17,20,53,9
+ EDITTEXT IDC_USERNAME,74,18,56,12,ES_AUTOHSCROLL
+ LTEXT "Password:",IDC_STATIC,135,20,47,9
+ EDITTEXT IDC_PASSWORD,185,18,56,12,ES_PASSWORD | ES_AUTOHSCROLL
+ CONTROL "Support for Voicecalls via imo.im Flash in Internet Explorer",
+ IDC_INTERACT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,42,
+ 273,9
+ CONTROL "Ignore server timestamp and use current time for messages",
+ IDC_CURRTIMESTAMP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
+ 7,60,273,10
+ CONTROL "Log traffic to file:",IDC_LOG,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,7,71,110,10
+ EDITTEXT IDC_LOGFILE,119,71,128,12,ES_AUTOHSCROLL
+ PUSHBUTTON "...",IDC_OPEN,248,71,14,12
+ LTEXT "Status:",IDC_STATIC,126,140,29,10
+ LTEXT "Stopped",IDC_STATUSSOCKS,157,140,54,9,SS_SUNKEN
+ GROUPBOX "Socket Proxy",IDC_STATIC,7,129,273,45
+ LTEXT "Bind to address:",IDC_STATIC,17,157,73,9
+ COMBOBOX IDC_BINDIP,95,155,75,12,CBS_DROPDOWN | CBS_SORT |
+ WS_VSCROLL | WS_TABSTOP
+ LTEXT "Port:",IDC_STATIC,179,157,31,9
+ EDITTEXT IDC_BINDPORT,211,155,31,12,ES_AUTOHSCROLL | ES_NUMBER
+ CONTROL "Use Socket Proxy",IDC_USESOCKS,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,18,140,81,9
+ PUSHBUTTON "Start",IDC_STARTSOCKS,216,137,30,12
+ PUSHBUTTON "Stop",IDC_STOPSOCKS,246,137,30,12,WS_DISABLED
+ GROUPBOX "Skype compatible communication API",IDC_STATIC,7,177,
+ 273,40
+ LTEXT "Caution: Don't use this if you have the Skype application running!",
+ IDC_STATIC,13,188,260,8
+ LTEXT "Status:",IDC_STATIC,126,201,29,10
+ LTEXT "Stopped",IDC_STATUSCOMM,158,201,54,9,SS_SUNKEN
+ CONTROL "Use compatible comm API",IDC_USECOMM,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,18,201,105,9
+ PUSHBUTTON "Start",IDC_STARTCOMM,216,198,30,12
+ PUSHBUTTON "Stop",IDC_STOPCOMM,246,198,30,12,WS_DISABLED
+ CONTROL "Console",IDC_CONSOLE,"Button",BS_AUTOCHECKBOX |
+ BS_PUSHLIKE | WS_TABSTOP,216,87,45,11
+ GROUPBOX "Skype Plugin 0.0.0.46+ internal communication link",
+ IDC_STATIC,7,102,273,25
+ LTEXT "Status:",IDC_STATIC,126,113,29,10
+ LTEXT "Stopped",IDC_STATUSSKYPEPL,158,113,54,9,SS_SUNKEN
+ CONTROL "Use plugin link",IDC_USESKYPEPL,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,18,113,105,9
+ PUSHBUTTON "Start",IDC_STARTSKYPEPL,216,110,30,12
+ PUSHBUTTON "Stop",IDC_STOPSKYPEPL,246,110,30,12,WS_DISABLED
+ CONTROL "Use Netlib instead of WinInet (Experimental)",
+ IDC_USENETLIB,"Button",BS_AUTOCHECKBOX | WS_DISABLED |
+ WS_TABSTOP,7,51,273,9
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+ IDD_OPTIONS, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 280
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 217
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Deutsch (Österreich) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/resource.h b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/resource.h new file mode 100644 index 0000000000..e0da6bef1d --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/resource.h @@ -0,0 +1,39 @@ +//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by res.rc
+//
+#define IDD_OPTIONS 101
+#define IDC_BINDPORT 1001
+#define IDC_BINDIP 1002
+#define IDC_INTERACT 1003
+#define IDC_CURRTIMESTAMP 1004
+#define IDC_LOG 1005
+#define IDC_LOGFILE 1006
+#define IDC_OPEN 1007
+#define IDC_USERNAME 1008
+#define IDC_PASSWORD 1009
+#define IDC_STATUSSOCKS 1010
+#define IDC_STATUSCOMM 1011
+#define IDC_STATUSSKYPEPL 1012
+#define IDC_USESOCKS 1013
+#define IDC_STARTSOCKS 1014
+#define IDC_STOPSOCKS 1015
+#define IDC_USECOMM 1016
+#define IDC_STARTCOMM 1017
+#define IDC_STOPCOMM 1018
+#define IDC_CONSOLE 1019
+#define IDC_USESKYPEPL 1020
+#define IDC_STARTSKYPEPL 1021
+#define IDC_STOPSKYPEPL 1022
+#define IDC_USENETLIB 1023
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 102
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1020
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/sdk/m_updater.h b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/sdk/m_updater.h new file mode 100644 index 0000000000..371b7437a0 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/sdk/m_updater.h @@ -0,0 +1,146 @@ +#ifndef _M_UPDATER_H
+#define _M_UPDATER_H
+
+// NOTES:
+// - For langpack updates, include a string of the following format in the langpack text file:
+// ";FLID: <file listing name> <version>"
+// version must be four numbers seperated by '.', in the range 0-255 inclusive
+// - Updater will disable plugins that are downloaded but were not active prior to the update (this is so that, if an archive contains e.g. ansi and
+// unicode versions, the correct plugin will be the only one active after the new version is installed)...so if you add a support plugin, you may need
+// to install an ini file to make the plugin activate when miranda restarts after the update
+// - Updater will replace all dlls that have the same internal shortName as a downloaded update dll (this is so that msn1.dll and msn2.dll, for example,
+// will both be updated) - so if you have a unicode and a non-unicode version of a plugin in your archive, you should make the internal names different (which will break automatic
+// updates from the file listing if there is only one file listing entry for both versions, unless you use the 'MS_UPDATE_REGISTER' service below)
+// - Updater will install all files in the root of the archive into the plugins folder, except for langpack files that contain the FLID string which go into the root folder (same
+// folder as miranda32.exe)...all folders in the archive will also be copied to miranda's root folder, and their contents transferred into the new folders. The only exception is a
+// special folder called 'root_files' - if there is a folder by that name in the archive, it's contents will also be copied into miranda's root folder - this is intended to be used
+// to install additional dlls etc that a plugin may require)
+
+// if you set Update.szUpdateURL to the following value when registering, as well as setting your beta site and version data,
+// Updater will ignore szVersionURL and pbVersionPrefix, and attempt to find the file listing URL's from the backend XML data.
+// for this to work, the plugin name in pluginInfo.shortName must match the file listing exactly (except for case)
+#define UPDATER_AUTOREGISTER "UpdaterAUTOREGISTER"
+// Updater will also use the backend xml data if you provide URL's that reference the miranda file listing for updates (so you can use that method
+// if e.g. your plugin shortName does not match the file listing) - it will grab the file listing id from the end of these URLs
+
+typedef struct Update_tag {
+ int cbSize;
+ char *szComponentName; // component name as it will appear in the UI (will be translated before displaying)
+
+ char *szVersionURL; // URL where the current version can be found (NULL to disable)
+ BYTE *pbVersionPrefix; // bytes occuring in VersionURL before the version, used to locate the version information within the URL data
+ // (note that this URL could point at a binary file - dunno why, but it could :)
+ int cpbVersionPrefix; // number of bytes pointed to by pbVersionPrefix
+ char *szUpdateURL; // URL where dll/zip is located
+ // set to UPDATER_AUTOREGISTER if you want Updater to find the file listing URLs (ensure plugin shortName matches file listing!)
+
+ char *szBetaVersionURL; // URL where the beta version can be found (NULL to disable betas)
+ BYTE *pbBetaVersionPrefix; // bytes occuring in VersionURL before the version, used to locate the version information within the URL data
+ int cpbBetaVersionPrefix; // number of bytes pointed to by pbVersionPrefix
+ char *szBetaUpdateURL; // URL where dll/zip is located
+
+ BYTE *pbVersion; // bytes of current version, used for comparison with those in VersionURL
+ int cpbVersion; // number of bytes pointed to by pbVersion
+
+ char *szBetaChangelogURL; // url for displaying changelog for beta versions
+} Update;
+
+// register a comonent with Updater
+//
+// wparam = 0
+// lparam = (LPARAM)&Update
+#define MS_UPDATE_REGISTER "Update/Register"
+
+// utility functions to create a version string from a DWORD or from pluginInfo
+// point buf at a buffer at least 16 chars wide - but note the version string returned may be shorter
+//
+__inline static char *CreateVersionString(DWORD version, char *buf) {
+ mir_snprintf(buf, 16, "%d.%d.%d.%d", (version >> 24) & 0xFF, (version >> 16) & 0xFF, (version >> 8) & 0xFF, version & 0xFF);
+ return buf;
+}
+
+__inline static char *CreateVersionStringPlugin(PLUGININFO *pluginInfo, char *buf) {
+ return CreateVersionString(pluginInfo->version, buf);
+}
+
+
+// register the 'easy' way - use this method if you have no beta URL and the plugin is on the miranda file listing
+// NOTE: the plugin version string on the file listing must be the string version of the version in pluginInfo (i.e. 0.0.0.1,
+// four numbers between 0 and 255 inclusivem, so no letters, brackets, etc.)
+//
+// wParam = (int)fileID - this is the file ID from the file listing (i.e. the number at the end of the download link)
+// lParam = (PLUGININFO*)&pluginInfo
+#define MS_UPDATE_REGISTERFL "Update/RegisterFL"
+
+// this function can be used to 'unregister' components - useful for plugins that register non-plugin/langpack components and
+// may need to change those components on the fly
+// lParam = (char *)szComponentName
+#define MS_UPDATE_UNREGISTER "Update/Unregister"
+
+// this event is fired when the startup process is complete, but NOT if a restart is imminent
+// it is designed for status managment plugins to use as a trigger for beggining their own startup process
+// wParam = lParam = 0 (unused)
+// (added in version 0.1.6.0)
+#define ME_UPDATE_STARTUPDONE "Update/StartupDone"
+
+// this service can be used to enable/disable Updater's global status control
+// it can be called from the StartupDone event handler
+// wParam = (BOOL)enable
+// lParam = 0
+// (added in version 0.1.6.0)
+#define MS_UPDATE_ENABLESTATUSCONTROL "Update/EnableStatusControl"
+
+// An description of usage of the above service and event:
+// Say you are a status control plugin that normally sets protocol or global statuses in your ModulesLoaded event handler.
+// In order to make yourself 'Updater compatible', you would move the status control code from ModulesLoaded to another function,
+// say DoStartup. Then, in ModulesLoaded you would check for the existence of the MS_UPDATE_ENABLESTATUSCONTROL service.
+// If it does not exist, call DoStartup. If it does exist, hook the ME_UPDATE_STARTUPDONE event and call DoStartup from there. You may
+// also wish to call MS_UPDATE_ENABLESTATUSCONTROL with wParam == FALSE at this time, to disable Updater's own status control feature.
+
+// this service can be used to determine whether updates are possible for a component with the given name
+// wParam = 0
+// lParam = (char *)szComponentName
+// returns TRUE if updates are supported, FALSE otherwise
+#define MS_UPDATE_ISUPDATESUPPORTED "Update/IsUpdateSupported"
+
+#endif
+
+
+/////////////// Usage Example ///////////////
+
+#ifdef EXAMPLE_CODE
+
+// you need to #include "m_updater.h" and HookEvent(ME_SYSTEM_MODULESLOADED, OnModulesLoaded) in your Load function...
+
+int OnModulesLoaded(WPARAM wParam, LPARAM lParam) {
+
+ Update update = {0}; // for c you'd use memset or ZeroMemory...
+ char szVersion[16];
+
+ update.cbSize = sizeof(Update);
+
+ update.szComponentName = pluginInfo.shortName;
+ update.pbVersion = (BYTE *)CreateVersionString(&pluginInfo, szVersion);
+ update.cpbVersion = strlen((char *)update.pbVersion);
+
+ // these are the three lines that matter - the archive, the page containing the version string, and the text (or data)
+ // before the version that we use to locate it on the page
+ // (note that if the update URL and the version URL point to standard file listing entries, the backend xml
+ // data will be used to check for updates rather than the actual web page - this is not true for beta urls)
+ update.szUpdateURL = "http://scottellis.com.au:81/test/updater.zip";
+ update.szVersionURL = "http://scottellis.com.au:81/test/updater_test.html";
+ update.pbVersionPrefix = (BYTE *)"Updater version ";
+
+ update.cpbVersionPrefix = strlen((char *)update.pbVersionPrefix);
+
+ // do the same for the beta versions of the above struct members if you wish to allow beta updates from another URL
+
+ CallService(MS_UPDATE_REGISTER, 0, (WPARAM)&update);
+
+ // Alternatively, to register a plugin with e.g. file ID 2254 on the file listing...
+ // CallService(MS_UPDATE_REGISTERFL, (WPARAM)2254, (LPARAM)&pluginInfo);
+
+ return 0;
+}
+
+#endif
diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/skypepluginlink.c b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/skypepluginlink.c new file mode 100644 index 0000000000..0109bd6ede --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/skypepluginlink.c @@ -0,0 +1,233 @@ +#include "imo2sproxy.h"
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <stdlib.h>
+#include "skypepluginlink.h"
+#include "include/newpluginapi.h"
+#include "include/m_system.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
+
+
+// -----------------------------------------------------------------------------
+
+struct tag_proxyInst;
+typedef struct tag_proxyInst IMO2SPROXY_INST;
+
+typedef struct
+{
+ IMOSAPI *hInst;
+ IMO2SPROXY_INST *hProxy;
+ mutex_t sendmutex;
+ mutex_t rcvmutex;
+ int iConnectionStat;
+} CONNINST;
+
+struct tag_proxyInst
+{
+ IMO2SPROXY vtbl; // Must be first!
+ IMO2SPROXY_CFG *pCfg;
+ SKYPEPLUGINLINK_CFG *pMyCfg;
+ HANDLE hService;
+ CONNINST stClient; // Currently only 1 connection
+};
+
+
+static CONNINST *m_pConn = NULL;
+
+// -----------------------------------------------------------------------------
+
+static void EventHandler(char *pszMsg, void *pUser);
+static int InitProxy(IMO2SPROXY_INST *hProxy);
+
+static int Imo2sproxy_Open(IMO2SPROXY *hInst);
+static void Imo2sproxy_Loop(IMO2SPROXY *hInst);
+static void Imo2sproxy_Exit(IMO2SPROXY *hInst);
+
+// -----------------------------------------------------------------------------
+static void EventHandler(char *pszMsg, void *pUser)
+{
+ CONNINST *pInst = (CONNINST*)pUser;
+ COPYDATASTRUCT cds;
+ DWORD dwRes = 0;
+
+ //LockMutex (pInst->sendmutex);
+ if (pInst->hProxy->pCfg->bVerbose && pInst->hProxy->pCfg->fpLog)
+ {
+ fprintf (pInst->hProxy->pCfg->fpLog, "> %s\n", pszMsg);
+ fflush (pInst->hProxy->pCfg->fpLog);
+ }
+ cds.dwData = 0;
+ cds.cbData = strlen(pszMsg)+1;
+ cds.lpData = pszMsg;
+ CallService (SKYPE_PROTONAME PSS_SKYPEAPIMSG, 0, (LPARAM)&cds);
+ //UnlockMutex (pInst->sendmutex);
+}
+
+// -----------------------------------------------------------------------------
+
+INT_PTR CallIn(WPARAM wParam,LPARAM lParam)
+{
+ CONNINST *pInst = (CONNINST*)m_pConn;
+ PCOPYDATASTRUCT pCopyData = (PCOPYDATASTRUCT)lParam;
+
+ if (!pInst) return -1;
+
+ if (pInst->hProxy->pMyCfg->bDelayLogin && pInst->iConnectionStat < 1)
+ {
+ LockMutex (pInst->rcvmutex);
+ if (InitProxy(pInst->hProxy)<0)
+ {
+ UnlockMutex(pInst->rcvmutex);
+ return -1;
+ }
+ UnlockMutex(pInst->rcvmutex);
+ }
+
+ if (pInst->hProxy->pCfg->bVerbose && pInst->hProxy->pCfg->fpLog)
+ {
+ fprintf (pInst->hProxy->pCfg->fpLog, "< [%s]\n", pCopyData->lpData);
+ fflush (pInst->hProxy->pCfg->fpLog);
+ }
+ Imo2S_Send (pInst->hInst, pCopyData->lpData);
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+
+static void FreeConnection (CONNINST *pInst)
+{
+ if (!pInst || !pInst->hProxy) return;
+ if (pInst->hProxy->pCfg->bVerbose && pInst->hProxy->pCfg->fpLog)
+ {
+ fprintf (pInst->hProxy->pCfg->fpLog, "SkypePluginLink: Closed connection\n");
+ fflush (pInst->hProxy->pCfg->fpLog);
+ }
+
+ if (pInst->hProxy->hService)
+ {
+ DestroyServiceFunction(pInst->hProxy->hService);
+ pInst->hProxy->hService = NULL;
+ CallService (SKYPE_PROTONAME SKYPE_REGPROXY, 0, 0);
+ }
+ ExitMutex(pInst->sendmutex);
+ ExitMutex(pInst->rcvmutex);
+ if (pInst->hInst)
+ {
+ IMOSAPI *hInst = pInst->hInst;
+ pInst->hInst = NULL;
+ Imo2S_Exit(hInst);
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+static int InitProxy(IMO2SPROXY_INST *hProxy)
+{
+ char *pszError;
+
+ if (!hProxy->stClient.hInst)
+ {
+ if (!(hProxy->stClient.hInst = Imo2S_Init(EventHandler, &hProxy->stClient, hProxy->pCfg->iFlags)))
+ {
+ hProxy->pCfg->logerror (stderr, "SkypePluginLink: Cannot start Imo2Skype instance.\n");
+ return -1;
+ }
+ }
+
+ // FIXME: We should enable logging dependent on a loglevel rather than just enabling it
+ Imo2S_SetLog (hProxy->stClient.hInst, hProxy->pCfg->fpLog);
+
+ if (hProxy->stClient.iConnectionStat == 0 ||
+ (hProxy->stClient.iConnectionStat = Imo2S_Login (hProxy->stClient.hInst,
+ hProxy->pCfg->pszUser, hProxy->pCfg->pszPass, &pszError)) != 1)
+ {
+ hProxy->pCfg->logerror (stderr, "SkypePluginLink: Cannot login with (%s/****): %s\n",
+ hProxy->pCfg->pszUser, pszError);
+ return -1;
+ }
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+// PUBLIC
+// -----------------------------------------------------------------------------
+
+void SkypePluginLink_Defaults (SKYPEPLUGINLINK_CFG *pMyCfg)
+{
+ memset (pMyCfg, 0, sizeof(SKYPEPLUGINLINK_CFG));
+ pMyCfg->bDelayLogin = TRUE;
+}
+
+// -----------------------------------------------------------------------------
+
+IMO2SPROXY *SkypePluginLink_Init (IMO2SPROXY_CFG *pCfg, SKYPEPLUGINLINK_CFG *pMyCfg)
+{
+ IMO2SPROXY_INST *pstInst = calloc(sizeof(IMO2SPROXY_INST), 1);
+
+ pstInst->vtbl.Open = Imo2sproxy_Open;
+ pstInst->vtbl.Loop = Imo2sproxy_Loop;
+ pstInst->vtbl.Exit = Imo2sproxy_Exit;
+ pstInst->pCfg = pCfg;
+ pstInst->pMyCfg = pMyCfg;
+ return (IMO2SPROXY*)pstInst;
+}
+
+// -----------------------------------------------------------------------------
+// IMPLEMENTATION
+// -----------------------------------------------------------------------------
+static int Imo2sproxy_Open(IMO2SPROXY *hInst)
+{
+ IMO2SPROXY_INST *hProxy = (IMO2SPROXY_INST*)hInst;
+ WNDCLASS WndClass ={0};
+
+ if (hProxy->pCfg->bVerbose && hProxy->pCfg->fpLog)
+ fprintf (hProxy->pCfg->fpLog, "SkypePluginLink:Open(Start)\n");
+
+ // Only 1 connection instance, so we can init it right here
+ InitMutex(hProxy->stClient.sendmutex);
+ InitMutex(hProxy->stClient.rcvmutex);
+ hProxy->stClient.hProxy = hProxy;
+ m_pConn = &hProxy->stClient;
+
+ // Register with Skype Plugin
+ hProxy->hService = CreateServiceFunction("IMO2SPROXY" PSS_SKYPEAPIMSG, CallIn);
+ CallService (SKYPE_PROTONAME SKYPE_REGPROXY, 0, (LPARAM)"IMO2SPROXY" PSS_SKYPEAPIMSG);
+ hProxy->stClient.iConnectionStat = -1;
+
+ if (!hProxy->pMyCfg->bDelayLogin)
+ {
+ if (InitProxy(hProxy)<0)
+ {
+ FreeConnection(&hProxy->stClient);
+ return -1;
+ }
+ }
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+
+static void Imo2sproxy_Loop(IMO2SPROXY *hInst)
+{
+ // No loop needed for call-in
+}
+
+
+// -----------------------------------------------------------------------------
+
+static void Imo2sproxy_Exit(IMO2SPROXY *hInst)
+{
+ IMO2SPROXY_INST *hProxy = (IMO2SPROXY_INST*)hInst;
+
+ if (hProxy->pCfg->bVerbose && hProxy->pCfg->fpLog)
+ fprintf (hProxy->pCfg->fpLog, "SkypePluginLink:Exit()\n");
+
+ FreeConnection (&hProxy->stClient);
+ free (hProxy);
+}
+
diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/skypepluginlink.h b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/skypepluginlink.h new file mode 100644 index 0000000000..ecc520ff1e --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/miranda/skypepluginlink.h @@ -0,0 +1,10 @@ +typedef struct {
+ int bDelayLogin;
+} SKYPEPLUGINLINK_CFG;
+
+#define SKYPE_PROTONAME "SKYPE"
+#define PSS_SKYPEAPIMSG "/SendSkypeAPIMsg"
+#define SKYPE_REGPROXY "/RegisterProxySvc"
+
+void SkypePluginLink_Defaults (SKYPEPLUGINLINK_CFG *pMyCfg);
+IMO2SPROXY *SkypePluginLink_Init (IMO2SPROXY_CFG *pCfg, SKYPEPLUGINLINK_CFG *pMyCfg);
diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/msgqueue.c b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/msgqueue.c new file mode 100644 index 0000000000..7f1db504e9 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/msgqueue.c @@ -0,0 +1,158 @@ +/* Module: msgqueue.c
+ Purpose: Message queue for incoming messages
+ Author: leecher
+ Date: 30.08.2009
+
+ Fixme: Sort on insert, do a binary search instead of iterating list.
+*/
+
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "msgqueue.h"
+#include "buddylist.h"
+
+static volatile unsigned int m_uMsgNr=0;
+static void FreeEntry(void *pEntry);
+
+// -----------------------------------------------------------------------------
+// Interface
+// -----------------------------------------------------------------------------
+
+TYP_LIST *MsgQueue_Init(void)
+{
+ TYP_LIST *hList = List_Init(16);
+
+ return hList;
+}
+
+// -----------------------------------------------------------------------------
+
+void MsgQueue_Exit(TYP_LIST *hList)
+{
+ Queue_Exit(hList, FreeEntry);
+}
+
+// -----------------------------------------------------------------------------
+
+MSGENTRY *MsgQueue_Insert(TYP_LIST *hList, cJSON *pNick)
+{
+ MSGENTRY *pEntry;
+ cJSON *pVal;
+
+ if (!(pEntry = Queue_InsertEntry(hList, sizeof(MSGENTRY), ++m_uMsgNr,
+ FreeEntry))) return NULL;
+ pEntry->pszUser = strdup(cJSON_GetObjectItem(pNick, "buid")->valuestring);
+ pEntry->pszAlias = strdup(cJSON_GetObjectItem(pNick, "alias")->valuestring);
+ pEntry->pszMessage = strdup(cJSON_GetObjectItem(pNick, "msg")->valuestring);
+ pEntry->timestamp = cJSON_GetObjectItem(pNick, "timestamp")->valueint;
+ if (pVal = cJSON_GetObjectItem(pNick, "author")) pEntry->pszAuthor=strdup(pVal->valuestring);
+ strcpy (pEntry->szStatus, "RECEIVED");
+ strcpy (pEntry->szType, "TEXT");
+ // imo.im somehow sets group topic via recv_im??
+ if (strcmp(pEntry->pszAlias, pEntry->pszMessage) == 0) strcpy (pEntry->szType, "SETTOPIC");
+ return pEntry;
+}
+
+// -----------------------------------------------------------------------------
+
+MSGENTRY *MsgQueue_AddReflect(TYP_LIST *hList, cJSON *pNick, TYP_LIST *hBuddyList)
+{
+ MSGENTRY *pEntry;
+ cJSON *pVal;
+
+ if (!(pEntry = Queue_InsertEntry(hList, sizeof(MSGENTRY), ++m_uMsgNr,
+ FreeEntry))) return NULL;
+ pEntry->pszUser = strdup(cJSON_GetObjectItem(pNick, "buid")->valuestring);
+
+ // Usually no alias in Reflection, so query buddy list, if available
+ if (pVal = cJSON_GetObjectItem(pNick, "alias"))
+ pEntry->pszAlias = strdup(pVal->valuestring);
+ else
+ {
+ NICKENTRY *pBuddy = hBuddyList?BuddyList_Find (hBuddyList, pEntry->pszUser):NULL;
+ pEntry->pszAlias = strdup (pBuddy?pBuddy->pszAlias:pEntry->pszUser);
+ }
+
+ pEntry->pszMessage = strdup(cJSON_GetObjectItem(pNick, "msg")->valuestring);
+ pEntry->timestamp = cJSON_GetObjectItem(pNick, "timestamp")->valueint;
+ strcpy (pEntry->szStatus, "SENT");
+ return pEntry;
+}
+
+// -----------------------------------------------------------------------------
+
+MSGENTRY *MsgQueue_AddSent(TYP_LIST *hList, char *pszUser, char *pszAlias, char *pszMessage, unsigned int *puMsgId)
+{
+ MSGENTRY *pEntry;
+
+ if (!(pEntry = Queue_InsertEntry(hList, sizeof(MSGENTRY), ++m_uMsgNr,
+ FreeEntry))) return NULL;
+ pEntry->pszUser = strdup(pszUser);
+ pEntry->pszAlias = strdup(pszAlias);
+ pEntry->pszMessage = strdup(pszMessage);
+ time (&pEntry->timestamp);
+ strcpy (pEntry->szStatus, "SENDING");
+ if (puMsgId) *puMsgId = pEntry->hdr.uMsgNr;
+ return pEntry;
+}
+
+// -----------------------------------------------------------------------------
+
+MSGENTRY *MsgQueue_AddEvent(TYP_LIST *hList, char *pszUser, char *pszType)
+{
+ MSGENTRY *pEntry;
+
+ if (!(pEntry = Queue_InsertEntry(hList, sizeof(MSGENTRY), ++m_uMsgNr,
+ FreeEntry))) return NULL;
+ pEntry->pszUser = strdup(pszUser);
+ time (&pEntry->timestamp);
+ strcpy (pEntry->szStatus, "RECEIVED");
+ strcpy (pEntry->szType, pszType);
+ return pEntry;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL MsgQueue_Remove(TYP_LIST *hList, unsigned int uMsgNr)
+{
+ return Queue_Remove(hList, uMsgNr, FreeEntry);
+}
+
+// -----------------------------------------------------------------------------
+
+MSGENTRY *MsgQueue_Find(TYP_LIST *hList, unsigned int uMsgNr)
+{
+ return (MSGENTRY*)Queue_Find(hList, uMsgNr);
+}
+
+// -----------------------------------------------------------------------------
+
+MSGENTRY *MsgQueue_FindByRqId(TYP_LIST *hList, unsigned int uRqId)
+{
+ unsigned int i;
+ MSGENTRY *pEntry;
+
+ for (i=List_Count(hList)-1; (int)i!=-1; i--)
+ {
+ pEntry = (MSGENTRY*)List_ElementAt (hList, i);
+ if (pEntry->uRqId == uRqId)
+ return pEntry;
+ }
+ return NULL;
+}
+
+// -----------------------------------------------------------------------------
+// Static
+// -----------------------------------------------------------------------------
+
+static void FreeEntry(void *pPEntry)
+{
+ MSGENTRY *pEntry = (MSGENTRY*)pPEntry;
+
+ if (pEntry->pszAlias) free (pEntry->pszAlias);
+ free (pEntry->pszUser);
+ if (pEntry->pszMessage) free (pEntry->pszMessage);
+ if (pEntry->pszAuthor) free (pEntry->pszAuthor);
+}
+
diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/msgqueue.h b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/msgqueue.h new file mode 100644 index 0000000000..ac8ce1cf8d --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/msgqueue.h @@ -0,0 +1,28 @@ +#include "cJSON.h"
+#include "queue.h"
+#include <time.h>
+
+typedef struct
+{
+ QUEUEHDR hdr;
+ char *pszUser;
+ char *pszAuthor; // In case of groupchat, pszUser is the Groupchat ID and pszAuthor is the user sending it, if not a GC message, pszAuthor is NULL
+ char *pszAlias;
+ char *pszMessage;
+ time_t timestamp;
+ char szStatus[16];
+ char szFailure[256];
+ char szType[20]; // TEXT, SETTOPIC, ADDEDMEMBERS, CREATEDCHATWITH, LEFT, KICKED, ...
+ unsigned int uRqId;
+} MSGENTRY;
+
+TYP_LIST *MsgQueue_Init(void);
+void MsgQueue_Exit(TYP_LIST *hList);
+
+MSGENTRY *MsgQueue_Insert(TYP_LIST *hList, cJSON *pNick);
+MSGENTRY *MsgQueue_AddReflect(TYP_LIST *hList, cJSON *pNick, TYP_LIST *hBuddyList);
+MSGENTRY *MsgQueue_AddSent(TYP_LIST *hList, char *pszUser, char *pszAlias, char *pszMessage, unsigned int *puMsgId);
+MSGENTRY *MsgQueue_AddEvent(TYP_LIST *hList, char *pszUser, char *pszType);
+BOOL MsgQueue_Remove(TYP_LIST *hList, unsigned int uMsgNr);
+MSGENTRY *MsgQueue_Find(TYP_LIST *hList, unsigned int uMsgNr);
+MSGENTRY *MsgQueue_FindByRqId(TYP_LIST *hList, unsigned int uRqId);
diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/queue.c b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/queue.c new file mode 100644 index 0000000000..a163314c8e --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/queue.c @@ -0,0 +1,94 @@ +/* Module: queue.c
+ Purpose: Queue management
+ Author: leecher
+ Date: 02.09.2009
+*/
+
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "memlist.h"
+#include "queue.h"
+
+// Maximum threshold for queues (So that we don't leak memory)
+#define THRESHOLD 50
+
+// -----------------------------------------------------------------------------
+// Interface
+// -----------------------------------------------------------------------------
+
+void Queue_Exit(TYP_LIST *hList, void (*fpFree)(void *pEntry))
+{
+ void *pEntry;
+
+ while (pEntry=List_Pop(hList))
+ {
+ if (fpFree) fpFree(pEntry);
+ free (pEntry);
+ }
+ List_Exit(hList);
+}
+
+// -----------------------------------------------------------------------------
+
+void* Queue_InsertEntry (TYP_LIST *hList, unsigned int cbSize, unsigned int uMsgNr,
+ void (*fpFree)(void *pEntry))
+{
+ void *pEntry;
+
+ if (!(pEntry = calloc (1, cbSize))) return NULL;
+ if (!List_Push(hList, pEntry))
+ {
+ free (pEntry);
+ return NULL;
+ } else ((QUEUEHDR*)pEntry)->uMsgNr = uMsgNr;
+#ifdef THRESHOLD
+ if (List_Count(hList)>THRESHOLD)
+ {
+ void *pEntry = List_RemoveElementAt(hList, 0);
+
+ if (pEntry) fpFree (pEntry);
+ free (pEntry);
+ }
+#endif
+ return pEntry;
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL Queue_Remove(TYP_LIST *hList, unsigned int uMsgNr, void (*fpFree)(void *pEntry))
+{
+ QUEUEHDR *pListEntry;
+ unsigned int i;
+
+ for (i=List_Count(hList)-1; (int)i!=-1; i--)
+ {
+ pListEntry = List_ElementAt (hList, i);
+ if (pListEntry->uMsgNr == uMsgNr)
+ {
+ if (fpFree) fpFree (pListEntry);
+ List_RemoveElementAt(hList, i);
+ free (pListEntry);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------------
+
+void *Queue_Find(TYP_LIST *hList, unsigned int uMsgNr)
+{
+ unsigned int i;
+ QUEUEHDR *pEntry;
+
+ for (i=List_Count(hList)-1; (int)i!=-1; i--)
+ {
+ pEntry = (QUEUEHDR*)List_ElementAt (hList, i);
+ if (pEntry->uMsgNr == uMsgNr)
+ return pEntry;
+ }
+ return NULL;
+}
+
+// -----------------------------------------------------------------------------
diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/queue.h b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/queue.h new file mode 100644 index 0000000000..4f42a3b42f --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/queue.h @@ -0,0 +1,17 @@ +#ifndef __QUEUE_H__
+#define __QUEUE_H__
+
+#include "memlist.h"
+
+typedef struct
+{
+ unsigned int uMsgNr;
+} QUEUEHDR;
+
+void Queue_Exit(TYP_LIST *hList, void (*fpFree)(void *pEntry));
+void* Queue_InsertEntry (TYP_LIST *hList, unsigned int cbSize, unsigned int uMsgNr,
+ void (*fpFree)(void *pEntry));
+BOOL Queue_Remove(TYP_LIST *hList, unsigned int uMsgNr, void (*fpFree)(void *pEntry));
+void *Queue_Find(TYP_LIST *hList, unsigned int uMsgNr);
+
+#endif
diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/socksproxy.c b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/socksproxy.c new file mode 100644 index 0000000000..20c56a7a66 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/socksproxy.c @@ -0,0 +1,565 @@ +/* Module: imo2skypeproxy.c
+ Purpose: Implementation of imo2skype API as Skype proxy (for Miranda Skype plugin)
+ Author: leecher
+ Date: 01.09.2009
+
+ Changelog:
+ 1.00 - 01.09.2009 - Initial release
+ 1.01 - 02.09.2009 - Little bugfix for Onlinestatus, introduced mutex for send thread.
+ 1.02 - 02.09.2009 - Added support for incoming call notifications and expired sessions.
+ 1.03 - 03.09.2009 - As WIN32-port of libcurl is a total mess, Win32-version now uses WinINET.
+ 1.04 - 04.09.2009 - Added support for searching, adding and removing buddies
+ 1.05 - 06.09.2009 - * Mapped "busy" to DND, not NA, as forum user AL|EN proposed.
+ * Mood text will now also be sent on status change of a contact
+ (doesn't really have an effect though)
+ * New Parameter -d (daemonize) to launch proxy in background
+ * Fixed a bug with a crash when encoding umlauts on Win32
+ 1.06 - 25.09.2009 - Added parameter -t for local timestamps.
+ 1.07 - 07.10.2009 - Bugfix: Added parsing of multiple JSON messages
+ Added support for writing to logfile while in daemon mode (-l)
+ 1.08 - 18.10.2009 - Added support for voice calls via imo.im flash on WIN32 (-i)
+ - Limited memory queues to 50 entries to reduce memory usage.
+ 1.09 - 07.11.2009 - Split command line main module and proxy module to make proxy
+ accessible by different layers (i.e. new Miranda Plugin layer)
+ 1.10 - 14.12.2009 - Bug in the cJson library. The authors used the String as second
+ sprintf-Parameter which contains the format string instead of
+ ["%s", StringParam] causing problems sending Messages containt a %
+ - Added some space in the dialog for translations and added Translate()
+ function to some strings in the Wrapper-DLL
+ - More verbose output if you enable logging
+ - Fixes a Bug that caused the plugin to block after going offline
+ and reconnecting back online
+ - Hopefully fixed a severe threading problem: The Send-Mutex was not
+ covering a full transaction, but only 1 send causing the receiver
+ the receive garbled data causing "An existing connection was forcibly
+ closed by the remote host." error.
+ - Imo2S_Exit freed the temporary buffer too early resulting in a crash
+ on exit.
+ 1.12 - 19.04.2010 - POST interface changed from www.imo.im/amy to s.imo.im/amy
+ 1.13 - 19.12.2010 - imo.im modified their interface, so tried to adapt the communication
+ routines at low level to be compatible again. There still may be
+ many bugs. Don't forget to turn off history logging in the options
+ at https://imo.im
+ There also seems to be a nice new feature called "reflection" so that
+ you can login from multiple sessions and messages etc. entered there
+ will be reflected to the current session. This may be addressed in one
+ of the next builds...
+*/
+
+#include <stdio.h>
+#include "imo2sproxy.h"
+#ifdef WIN32
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <winsock2.h>
+#include <process.h>
+#define thread_t HANDLE
+#define LockMutex(x) EnterCriticalSection (&x)
+#define UnlockMutex(x) LeaveCriticalSection(&x)
+#define InitMutex(x) InitializeCriticalSection(&x)
+#define ExitMutex(x) DeleteCriticalSection(&x)
+#define strcasecmp stricmp
+#define strncasecmp stricmpn
+#define mutex_t CRITICAL_SECTION
+#define SHUT_RD SD_RECEIVE
+#define SHUT_WR SD_SEND
+#define SHUT_RDWR SD_BOTH
+#else
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/select.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <pthread.h>
+#include <errno.h>
+#include <unistd.h>
+#include <pthread.h>
+#define SOCKET int
+#define thread_t pthread_t
+#define mutex_t pthread_mutex_t
+#define INVALID_SOCKET -1
+#define SOCKET_ERROR INVALID_SOCKET
+#define closesocket close
+#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)
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include "memlist.h"
+#include "socksproxy.h"
+
+// -----------------------------------------------------------------------------
+
+#define AUTHENTICATE 0x01
+#define CAPABILITIES 0x02
+#define USE_AUTHENTICATION 0x01
+
+typedef struct
+{
+ IMO2SPROXY vtbl; // Must be first!
+ IMO2SPROXY_CFG *pCfg;
+ SOCKSPROXY_CFG *pMyCfg;
+
+ SOCKET listen_fd;
+ volatile int iRunning;
+ mutex_t loopmutex;
+} IMO2SPROXY_INST;
+
+typedef struct
+{
+ SOCKET hSock;
+ thread_t hThread;
+ IMOSAPI *hInst;
+ int iConnectionStat;
+ mutex_t connected;
+ mutex_t sendmutex;
+ IMO2SPROXY_INST *hProxy;
+} CONNINST;
+
+
+// -----------------------------------------------------------------------------
+
+static void EventHandler(char *pszMsg, void *pUser);
+static void DispatcherThread(void *pUser);
+static int Dispatcher_Start(CONNINST *pInst);
+static int Dispatcher_Stop(CONNINST *pInst);
+static char *GetError(void);
+static int RcvPacket (CONNINST *pInst, void *buf, int len);
+static int SendPacket (CONNINST *pInst, void *buf, int len);
+static void FreeConnection (CONNINST *pInst);
+static void CleanConnections (TYP_LIST *hList);
+static SOCKET Init(unsigned long int lHost, short sPort, int iMaxConn);
+static void Loop(SOCKET listen_fd);
+static void Exit(SOCKET listen_fd);
+
+static int Imo2sproxy_Open(IMO2SPROXY *hInst);
+static void Imo2sproxy_Loop(IMO2SPROXY *hInst);
+static void Imo2sproxy_Exit(IMO2SPROXY *hInst);
+
+// -----------------------------------------------------------------------------
+static void EventHandler(char *pszMsg, void *pUser)
+{
+ CONNINST *pInst = (CONNINST*)pUser;
+ unsigned int uiLen = strlen (pszMsg);
+ static BOOL bFirstLogin = TRUE;
+
+ if (pInst->hProxy->pCfg->bVerbose && pInst->hProxy->pCfg->fpLog)
+ {
+ fprintf (pInst->hProxy->pCfg->fpLog, "%03d> %s\n", pInst->hSock, pszMsg);
+ fflush (pInst->hProxy->pCfg->fpLog);
+ }
+ if (bFirstLogin && strncmp (pszMsg, "CONNSTATUS", 10) == 0 &&
+ strcmp(pszMsg+11, "CONNECTING"))
+ {
+ pInst->iConnectionStat = (strcmp(pszMsg+11, "ONLINE")==0);
+ UnlockMutex (pInst->connected);
+ bFirstLogin = FALSE;
+ }
+ LockMutex(pInst->sendmutex);
+ if (!(SendPacket (pInst, &uiLen, sizeof(uiLen)) && SendPacket (pInst, pszMsg, uiLen)))
+ {
+ //Dispatcher_Stop(pInst);
+ //FreeConnection (pInst);
+ }
+ UnlockMutex(pInst->sendmutex);
+}
+
+// -----------------------------------------------------------------------------
+
+static void DispatcherThread(void *pUser)
+{
+ CONNINST *pInst = (CONNINST*)pUser;
+ char *pszUser, *pszPass, *pszError, *pszMsgBuf=NULL;
+ unsigned int uiLength, cbMsgBuf=0, bAuthenticated = 0, iConnected=0, iLogin=1;
+ char command=0, reply=0;
+
+ if (pInst->hProxy->pCfg->bVerbose && pInst->hProxy->pCfg->fpLog)
+ fprintf (pInst->hProxy->pCfg->fpLog, "Imo2sproxy::DispatcherThread()\n");
+
+ if (!(pInst->hInst = Imo2S_Init(EventHandler, pInst, pInst->hProxy->pCfg->iFlags)))
+ {
+ pInst->hProxy->pCfg->logerror (stderr, "Connection %d: Cannot start Imo2Skype instance.\n", pInst->hSock);
+ FreeConnection (pInst);
+ return;
+ }
+
+ // FIXME: Static user+pass from cmdline, until there is a possibility for
+ // a client to authenticate
+ pszUser = pInst->hProxy->pCfg->pszUser;
+ pszPass = pInst->hProxy->pCfg->pszPass;
+
+ // FIXME: We should enable logging dependent on a loglevel rather than just enabling it
+ if (pInst->hProxy->pCfg->bVerbose)
+ Imo2S_SetLog (pInst->hInst, pInst->hProxy->pCfg->fpLog);
+
+
+ while (pInst->hProxy->iRunning)
+ {
+ if (RcvPacket(pInst, &uiLength, sizeof(uiLength))<=0) break;
+ LockMutex(pInst->sendmutex);
+
+ if (uiLength == 0)
+ {
+ if (RcvPacket(pInst, &command, 1)<=0)
+ {
+ UnlockMutex(pInst->sendmutex);
+ break;
+ }
+ switch (command)
+ {
+ case AUTHENTICATE:
+ if (pInst->hProxy->pMyCfg->pszAuthPass) reply=1;
+ break;
+ case CAPABILITIES:
+ if (pInst->hProxy->pMyCfg->pszAuthPass) reply=USE_AUTHENTICATION;
+ break;
+ }
+ if (SendPacket (pInst, &reply, 1)<=0)
+ {
+ UnlockMutex(pInst->sendmutex);
+ break;
+ }
+ UnlockMutex(pInst->sendmutex);
+ continue;
+ }
+
+ if (uiLength >= cbMsgBuf)
+ {
+ pszMsgBuf = realloc (pszMsgBuf, uiLength+1);
+ if (!pszMsgBuf)
+ {
+ UnlockMutex(pInst->sendmutex);
+ break;
+ }
+ cbMsgBuf=uiLength+1;
+ }
+
+ if (RcvPacket(pInst, pszMsgBuf, uiLength)<=0)
+ {
+ UnlockMutex(pInst->sendmutex);
+ break;
+ }
+
+ if (command)
+ {
+ if (command == AUTHENTICATE)
+ {
+ bAuthenticated = pInst->hProxy->pMyCfg->pszAuthPass && strcmp(pInst->hProxy->pMyCfg->pszAuthPass, pszMsgBuf) == 0;
+ if (SendPacket (pInst, &bAuthenticated, 1)<=0)
+ {
+ UnlockMutex(pInst->sendmutex);
+ break;
+ }
+ }
+ command = 0;
+ }
+ UnlockMutex(pInst->sendmutex);
+
+ if (iLogin) + { + if (Imo2S_Login (pInst->hInst, pszUser, pszPass, &pszError) != 1)
+ {
+ pInst->hProxy->pCfg->logerror (stderr, "Connection %d: Cannot login with (%s/****): %s\n",
+ pInst->hSock, pszUser, pszError);
+ FreeConnection (pInst);
+ return;
+ }
+ iLogin = 0; + } + + if (pInst->hProxy->pMyCfg->pszAuthPass && !bAuthenticated)continue;
+ pszMsgBuf[uiLength]=0;
+ if (pInst->hProxy->pCfg->bVerbose && pInst->hProxy->pCfg->fpLog)
+ {
+ fprintf (pInst->hProxy->pCfg->fpLog, "%03d< [%s]\n", pInst->hSock, pszMsgBuf);
+ fflush (pInst->hProxy->pCfg->fpLog);
+ }
+ if (!iConnected)
+ {
+ LockMutex (pInst->connected);
+ iConnected = pInst->iConnectionStat;
+ if (!iConnected)
+ {
+ pInst->hProxy->pCfg->logerror(stderr, "Invalid username / password");
+ }
+ }
+ Imo2S_Send (pInst->hInst, pszMsgBuf);
+ }
+
+ FreeConnection (pInst);
+ if (pszMsgBuf) free (pszMsgBuf);
+ return;
+}
+
+// -----------------------------------------------------------------------------
+
+#ifdef WIN32
+static int Dispatcher_Start(CONNINST *pInst)
+{
+ DWORD ThreadID;
+
+ return (pInst->hThread=(thread_t)_beginthreadex(NULL, 0,
+ (unsigned(__stdcall *)(void*))DispatcherThread, pInst, 0, &ThreadID))!=0;
+
+}
+
+static int Dispatcher_Stop(CONNINST *pInst)
+{
+ return pInst->hThread?TerminateThread (pInst->hThread, 0):1;
+}
+
+static char *GetError(void)
+{
+ static char szMessage[1024];
+ DWORD dwErr = WSAGetLastError();
+
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwErr, 0, szMessage, sizeof(szMessage), NULL);
+ return szMessage;
+}
+
+#else
+static int Dispatcher_Start(CONNINST *pInst)
+{
+ return pthread_create(&pInst->hThread, NULL, DispatcherThread, pInst)==0;
+}
+
+static int Dispatcher_Stop(CONNINST *pInst)
+{
+ if (!pInst->hThread || pthread_cancel(pInst->hThread))
+ {
+ pInst->hThread=0;
+ return 1;
+ }
+ return 0;
+}
+
+static char *GetError(void)
+{
+ return strerror (errno);
+}
+
+#endif
+
+// -----------------------------------------------------------------------------
+
+static int RcvPacket (CONNINST *pInst, void *buf, int len)
+{
+ int iReceived = recv (pInst->hSock, buf, len, 0);
+ if (iReceived <= 0)
+ pInst->hProxy->pCfg->logerror(stderr, "Connection %d (Receive): %s", pInst->hSock, GetError());
+ return iReceived;
+}
+
+// -----------------------------------------------------------------------------
+
+static int SendPacket (CONNINST *pInst, void *buf, int len)
+{
+ int iSent;
+
+ iSent = send (pInst->hSock, buf, len, 0);
+ if (iSent <= 0)
+ pInst->hProxy->pCfg->logerror (stderr, "Connection %d (Send): %s", pInst->hSock, GetError());
+ return iSent;
+}
+// -----------------------------------------------------------------------------
+
+static void FreeConnection (CONNINST *pInst)
+{
+ if (pInst->hProxy->pCfg->bVerbose && pInst->hProxy->pCfg->fpLog)
+ {
+ fprintf (pInst->hProxy->pCfg->fpLog, "Closed connection %d\n", pInst->hSock);
+ fflush (pInst->hProxy->pCfg->fpLog);
+ }
+ if (pInst->hSock != INVALID_SOCKET)
+ closesocket(pInst->hSock);
+ pInst->hSock = INVALID_SOCKET;
+ pInst->hThread = 0;
+ ExitMutex (pInst->connected);
+ ExitMutex (pInst->sendmutex);
+ if (pInst->hInst)
+ {
+ IMOSAPI *hInst = pInst->hInst;
+ pInst->hInst = NULL;
+ Imo2S_Exit(hInst);
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+static void CleanConnections (TYP_LIST *hList)
+{
+ unsigned int i;
+ CONNINST *hInst;
+
+ for (i=0; i<List_Count(hList); i++)
+ {
+ hInst = List_ElementAt (hList, i);
+ if (hInst->hThread == 0)
+ {
+ free (List_RemoveElementAt(hList, i));
+ i--;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+// PUBLIC
+// -----------------------------------------------------------------------------
+
+void SocksProxy_Defaults (SOCKSPROXY_CFG *pMyCfg)
+{
+ memset (pMyCfg, 0, sizeof(SOCKSPROXY_CFG));
+ pMyCfg->lAddr = htonl(INADDR_ANY);
+ pMyCfg->sPort = 1401;
+ pMyCfg->iMaxConn = SOMAXCONN;
+}
+
+// -----------------------------------------------------------------------------
+
+IMO2SPROXY *SocksProxy_Init (IMO2SPROXY_CFG *pCfg, SOCKSPROXY_CFG *pMyCfg)
+{
+ IMO2SPROXY_INST *pstInst = calloc(sizeof(IMO2SPROXY_INST), 1);
+
+ pstInst->vtbl.Open = Imo2sproxy_Open;
+ pstInst->vtbl.Loop = Imo2sproxy_Loop;
+ pstInst->vtbl.Exit = Imo2sproxy_Exit;
+ pstInst->pCfg = pCfg;
+ pstInst->pMyCfg = pMyCfg;
+ InitMutex(pstInst->loopmutex);
+ return (IMO2SPROXY*)pstInst;
+}
+
+// -----------------------------------------------------------------------------
+// IMPLEMENTATION
+// -----------------------------------------------------------------------------
+static int Imo2sproxy_Open(IMO2SPROXY *hInst)
+{
+ struct sockaddr_in sock={0};
+ int yes = 1;
+ IMO2SPROXY_INST *hProxy = (IMO2SPROXY_INST*)hInst;
+
+#ifdef WIN32
+ WSADATA wsaData;
+
+ if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
+ {
+ hProxy->pCfg->logerror (stderr, "WSAStartup failed");
+ return INVALID_SOCKET;
+ }
+#endif
+ if (hProxy->pCfg->bVerbose && hProxy->pCfg->fpLog)
+ fprintf (hProxy->pCfg->fpLog, "Socksproxy:Loop(Start)\n");
+ hProxy->listen_fd = socket(PF_INET, SOCK_STREAM, 0);
+ if(hProxy->listen_fd == INVALID_SOCKET) return -1;
+ if (setsockopt(hProxy->listen_fd, SOL_SOCKET, SO_REUSEADDR, (char*)&yes, sizeof(int))<0)
+ {
+ hProxy->pCfg->logerror (stderr, "Cannot set socket options to SO_REUSEADDR");
+ closesocket(hProxy->listen_fd);
+ return -1;
+ }
+ sock.sin_family = AF_INET;
+ sock.sin_addr.s_addr = hProxy->pMyCfg->lAddr;
+ sock.sin_port = htons(hProxy->pMyCfg->sPort);
+
+ if (bind(hProxy->listen_fd, (struct sockaddr *) &sock, sizeof(sock)) != 0)
+ {
+ hProxy->pCfg->logerror (stderr, "Cannot bind socket");
+ closesocket(hProxy->listen_fd);
+ return -1;
+ }
+
+ if (listen(hProxy->listen_fd, hProxy->pMyCfg->iMaxConn) < 0)
+ {
+ hProxy->pCfg->logerror (stderr, "Cannot listen on socket");
+ closesocket(hProxy->listen_fd);
+ return -1;
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+
+static void Imo2sproxy_Loop(IMO2SPROXY *hInst)
+{
+ struct sockaddr_in sock;
+ int socklen;
+ SOCKET new_fd;
+ TYP_LIST *hConns = List_Init(32);
+ CONNINST *pInst;
+ IMO2SPROXY_INST *hProxy = (IMO2SPROXY_INST*)hInst;
+ fd_set fdListen;
+
+ if (hProxy->pCfg->bVerbose && hProxy->pCfg->fpLog)
+ fprintf (hProxy->pCfg->fpLog, "Socksproxy:Loop(Start)\n");
+ hProxy->iRunning = 1;
+ LockMutex(hProxy->loopmutex);
+ while (hProxy->iRunning)
+ {
+ FD_ZERO(&fdListen);
+ FD_SET(hProxy->listen_fd, &fdListen);
+ socklen = sizeof(sock);
+ if (select (0, &fdListen, NULL, NULL, NULL) != SOCKET_ERROR && FD_ISSET(hProxy->listen_fd, &fdListen))
+ {
+ new_fd = accept(hProxy->listen_fd, (struct sockaddr *) &sock, &socklen);
+ if (hProxy->pCfg->bVerbose && hProxy->pCfg->fpLog)
+ {
+ fprintf (hProxy->pCfg->fpLog, "Connection from %s:%d -> Connection: %d\n", inet_ntoa(sock.sin_addr),
+ ntohs(sock.sin_port), new_fd);
+ fflush (hProxy->pCfg->fpLog);
+ }
+ if (new_fd != INVALID_SOCKET && (pInst = calloc (1, sizeof(CONNINST))))
+ {
+ CleanConnections (hConns);
+ List_Push(hConns, pInst);
+ pInst->hSock = new_fd;
+ pInst->hProxy = hProxy;
+ InitMutex(pInst->connected);
+ LockMutex(pInst->connected);
+ InitMutex(pInst->sendmutex);
+ Dispatcher_Start(pInst);
+ }
+ }
+ }
+ if (hProxy->pCfg->bVerbose && hProxy->pCfg->fpLog)
+ fprintf (hProxy->pCfg->fpLog, "Socksproxy:Loop(End)\n");
+
+ CleanConnections (hConns);
+ while (pInst=List_Pop(hConns))
+ {
+ Dispatcher_Stop(pInst);
+ FreeConnection(pInst);
+ free (pInst);
+ }
+ List_Exit(hConns);
+ UnlockMutex(hProxy->loopmutex);
+}
+
+
+// -----------------------------------------------------------------------------
+
+static void Imo2sproxy_Exit(IMO2SPROXY *hInst)
+{
+ IMO2SPROXY_INST *hProxy = (IMO2SPROXY_INST*)hInst;
+
+ if (hProxy->pCfg->bVerbose && hProxy->pCfg->fpLog)
+ fprintf (hProxy->pCfg->fpLog, "Socksproxy:Exit()\n");
+
+ hProxy->iRunning = 0;
+ shutdown (hProxy->listen_fd, SHUT_RDWR);
+ closesocket (hProxy->listen_fd);
+ LockMutex(hProxy->loopmutex);
+
+/*
+#ifdef WIN32
+ WSACleanup();
+#endif
+*/
+ UnlockMutex(hProxy->loopmutex);
+ ExitMutex(hProxy->loopmutex);
+ free (hProxy);
+}
+
diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/socksproxy.h b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/socksproxy.h new file mode 100644 index 0000000000..6010e749f1 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/socksproxy.h @@ -0,0 +1,11 @@ +typedef struct
+{
+ char *pszAuthPass;
+ unsigned long int lAddr;
+ short sPort;
+ int iMaxConn;
+} SOCKSPROXY_CFG;
+
+
+void SocksProxy_Defaults (SOCKSPROXY_CFG *pMyCfg);
+IMO2SPROXY *SocksProxy_Init (IMO2SPROXY_CFG *pCfg, SOCKSPROXY_CFG *pMyCfg);
diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/w32browser.c b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/w32browser.c new file mode 100644 index 0000000000..8053a3c16d --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/w32browser.c @@ -0,0 +1,1143 @@ +/* Module: win32_browsewnd.c
+ Purpose: Displays a window with an embedded browser in order to display the Voicechat
+ flash from imo.im
+ This example is bsaed on the work of Jeff Glatt (http://www.codeproject.com/KB/COM/cwebpage.aspx?msg=2852721)
+ Author: leecher, credits go to Jeff Glatt for his excellent work.
+ Date: 18.10.2009
+*/
+
+#include <windows.h>
+#include <exdisp.h>
+#include <mshtml.h>
+#include <mshtmhst.h>
+#include <process.h>
+#include "memlist.h"
+#include "w32browser.h"
+
+#ifndef _WIN64
+#if WINVER<0x0500
+#define SetWindowLongPtr SetWindowLong
+#define GetWindowLongPtr GetWindowLong
+#endif
+#ifndef LONG_PTR
+#define LONG_PTR LONG
+#endif
+#ifndef GWLP_USERDATA
+#define GWLP_USERDATA GWL_USERDATA
+#endif
+#endif
+
+static const SAFEARRAYBOUND ArrayBound = {1, 0};
+static TYP_LIST *m_hWindows = NULL;
+static DWORD m_dwThread = 0;
+static HANDLE m_hThread = NULL, m_hEvent = NULL;
+
+
+HRESULT STDMETHODCALLTYPE Frame_QueryInterface(IOleInPlaceFrame FAR* This, REFIID riid, LPVOID FAR* ppvObj);
+HRESULT STDMETHODCALLTYPE Frame_AddRef(IOleInPlaceFrame FAR* This);
+HRESULT STDMETHODCALLTYPE Frame_Release(IOleInPlaceFrame FAR* This);
+HRESULT STDMETHODCALLTYPE Frame_GetWindow(IOleInPlaceFrame FAR* This, HWND FAR* lphwnd);
+HRESULT STDMETHODCALLTYPE Frame_ContextSensitiveHelp(IOleInPlaceFrame FAR* This, BOOL fEnterMode);
+HRESULT STDMETHODCALLTYPE Frame_GetBorder(IOleInPlaceFrame FAR* This, LPRECT lprectBorder);
+HRESULT STDMETHODCALLTYPE Frame_RequestBorderSpace(IOleInPlaceFrame FAR* This, LPCBORDERWIDTHS pborderwidths);
+HRESULT STDMETHODCALLTYPE Frame_SetBorderSpace(IOleInPlaceFrame FAR* This, LPCBORDERWIDTHS pborderwidths);
+HRESULT STDMETHODCALLTYPE Frame_SetActiveObject(IOleInPlaceFrame FAR* This, IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName);
+HRESULT STDMETHODCALLTYPE Frame_InsertMenus(IOleInPlaceFrame FAR* This, HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths);
+HRESULT STDMETHODCALLTYPE Frame_SetMenu(IOleInPlaceFrame FAR* This, HMENU hmenuShared, HOLEMENU holemenu, HWND hwndActiveObject);
+HRESULT STDMETHODCALLTYPE Frame_RemoveMenus(IOleInPlaceFrame FAR* This, HMENU hmenuShared);
+HRESULT STDMETHODCALLTYPE Frame_SetStatusText(IOleInPlaceFrame FAR* This, LPCOLESTR pszStatusText);
+HRESULT STDMETHODCALLTYPE Frame_EnableModeless(IOleInPlaceFrame FAR* This, BOOL fEnable);
+HRESULT STDMETHODCALLTYPE Frame_TranslateAccelerator(IOleInPlaceFrame FAR* This, LPMSG lpmsg, WORD wID);
+
+IOleInPlaceFrameVtbl MyIOleInPlaceFrameTable = {Frame_QueryInterface,
+Frame_AddRef,
+Frame_Release,
+Frame_GetWindow,
+Frame_ContextSensitiveHelp,
+Frame_GetBorder,
+Frame_RequestBorderSpace,
+Frame_SetBorderSpace,
+Frame_SetActiveObject,
+Frame_InsertMenus,
+Frame_SetMenu,
+Frame_RemoveMenus,
+Frame_SetStatusText,
+Frame_EnableModeless,
+Frame_TranslateAccelerator};
+
+typedef struct {
+ IOleInPlaceFrame frame;
+ HWND window;
+} _IOleInPlaceFrameEx;
+
+HRESULT STDMETHODCALLTYPE Site_QueryInterface(IOleClientSite FAR* This, REFIID riid, void ** ppvObject);
+HRESULT STDMETHODCALLTYPE Site_AddRef(IOleClientSite FAR* This);
+HRESULT STDMETHODCALLTYPE Site_Release(IOleClientSite FAR* This);
+HRESULT STDMETHODCALLTYPE Site_SaveObject(IOleClientSite FAR* This);
+HRESULT STDMETHODCALLTYPE Site_GetMoniker(IOleClientSite FAR* This, DWORD dwAssign, DWORD dwWhichMoniker, IMoniker ** ppmk);
+HRESULT STDMETHODCALLTYPE Site_GetContainer(IOleClientSite FAR* This, LPOLECONTAINER FAR* ppContainer);
+HRESULT STDMETHODCALLTYPE Site_ShowObject(IOleClientSite FAR* This);
+HRESULT STDMETHODCALLTYPE Site_OnShowWindow(IOleClientSite FAR* This, BOOL fShow);
+HRESULT STDMETHODCALLTYPE Site_RequestNewObjectLayout(IOleClientSite FAR* This);
+
+IOleClientSiteVtbl MyIOleClientSiteTable = {Site_QueryInterface,
+Site_AddRef,
+Site_Release,
+Site_SaveObject,
+Site_GetMoniker,
+Site_GetContainer,
+Site_ShowObject,
+Site_OnShowWindow,
+Site_RequestNewObjectLayout};
+
+HRESULT STDMETHODCALLTYPE UI_QueryInterface(IDocHostUIHandler FAR* This, REFIID riid, void ** ppvObject);
+HRESULT STDMETHODCALLTYPE UI_AddRef(IDocHostUIHandler FAR* This);
+HRESULT STDMETHODCALLTYPE UI_Release(IDocHostUIHandler FAR* This);
+HRESULT STDMETHODCALLTYPE UI_ShowContextMenu(IDocHostUIHandler FAR* This, DWORD dwID, POINT __RPC_FAR *ppt, IUnknown __RPC_FAR *pcmdtReserved, IDispatch __RPC_FAR *pdispReserved);
+HRESULT STDMETHODCALLTYPE UI_GetHostInfo(IDocHostUIHandler FAR* This, DOCHOSTUIINFO __RPC_FAR *pInfo);
+HRESULT STDMETHODCALLTYPE UI_ShowUI(IDocHostUIHandler FAR* This, DWORD dwID, IOleInPlaceActiveObject __RPC_FAR *pActiveObject, IOleCommandTarget __RPC_FAR *pCommandTarget, IOleInPlaceFrame __RPC_FAR *pFrame, IOleInPlaceUIWindow __RPC_FAR *pDoc);
+HRESULT STDMETHODCALLTYPE UI_HideUI(IDocHostUIHandler FAR* This);
+HRESULT STDMETHODCALLTYPE UI_UpdateUI(IDocHostUIHandler FAR* This);
+HRESULT STDMETHODCALLTYPE UI_EnableModeless(IDocHostUIHandler FAR* This, BOOL fEnable);
+HRESULT STDMETHODCALLTYPE UI_OnDocWindowActivate(IDocHostUIHandler FAR* This, BOOL fActivate);
+HRESULT STDMETHODCALLTYPE UI_OnFrameWindowActivate(IDocHostUIHandler FAR* This, BOOL fActivate);
+HRESULT STDMETHODCALLTYPE UI_ResizeBorder(IDocHostUIHandler FAR* This, LPCRECT prcBorder, IOleInPlaceUIWindow __RPC_FAR *pUIWindow, BOOL fRameWindow);
+HRESULT STDMETHODCALLTYPE UI_TranslateAccelerator(IDocHostUIHandler FAR* This, LPMSG lpMsg, const GUID __RPC_FAR *pguidCmdGroup, DWORD nCmdID);
+HRESULT STDMETHODCALLTYPE UI_GetOptionKeyPath(IDocHostUIHandler FAR* This, LPOLESTR __RPC_FAR *pchKey, DWORD dw);
+HRESULT STDMETHODCALLTYPE UI_GetDropTarget(IDocHostUIHandler FAR* This, IDropTarget __RPC_FAR *pDropTarget, IDropTarget __RPC_FAR *__RPC_FAR *ppDropTarget);
+HRESULT STDMETHODCALLTYPE UI_GetExternal(IDocHostUIHandler FAR* This, IDispatch __RPC_FAR *__RPC_FAR *ppDispatch);
+HRESULT STDMETHODCALLTYPE UI_TranslateUrl(IDocHostUIHandler FAR* This, DWORD dwTranslate, OLECHAR __RPC_FAR *pchURLIn, OLECHAR __RPC_FAR *__RPC_FAR *ppchURLOut);
+HRESULT STDMETHODCALLTYPE UI_FilterDataObject(IDocHostUIHandler FAR* This, IDataObject __RPC_FAR *pDO, IDataObject __RPC_FAR *__RPC_FAR *ppDORet);
+
+IDocHostUIHandlerVtbl MyIDocHostUIHandlerTable = {UI_QueryInterface,
+UI_AddRef,
+UI_Release,
+UI_ShowContextMenu,
+UI_GetHostInfo,
+UI_ShowUI,
+UI_HideUI,
+UI_UpdateUI,
+UI_EnableModeless,
+UI_OnDocWindowActivate,
+UI_OnFrameWindowActivate,
+UI_ResizeBorder,
+UI_TranslateAccelerator,
+UI_GetOptionKeyPath,
+UI_GetDropTarget,
+UI_GetExternal,
+UI_TranslateUrl,
+UI_FilterDataObject};
+
+HRESULT STDMETHODCALLTYPE InPlace_QueryInterface(IOleInPlaceSite FAR* This, REFIID riid, void ** ppvObject);
+HRESULT STDMETHODCALLTYPE InPlace_AddRef(IOleInPlaceSite FAR* This);
+HRESULT STDMETHODCALLTYPE InPlace_Release(IOleInPlaceSite FAR* This);
+HRESULT STDMETHODCALLTYPE InPlace_GetWindow(IOleInPlaceSite FAR* This, HWND FAR* lphwnd);
+HRESULT STDMETHODCALLTYPE InPlace_ContextSensitiveHelp(IOleInPlaceSite FAR* This, BOOL fEnterMode);
+HRESULT STDMETHODCALLTYPE InPlace_CanInPlaceActivate(IOleInPlaceSite FAR* This);
+HRESULT STDMETHODCALLTYPE InPlace_OnInPlaceActivate(IOleInPlaceSite FAR* This);
+HRESULT STDMETHODCALLTYPE InPlace_OnUIActivate(IOleInPlaceSite FAR* This);
+HRESULT STDMETHODCALLTYPE InPlace_GetWindowContext(IOleInPlaceSite FAR* This, LPOLEINPLACEFRAME FAR* lplpFrame,LPOLEINPLACEUIWINDOW FAR* lplpDoc,LPRECT lprcPosRect,LPRECT lprcClipRect,LPOLEINPLACEFRAMEINFO lpFrameInfo);
+HRESULT STDMETHODCALLTYPE InPlace_Scroll(IOleInPlaceSite FAR* This, SIZE scrollExtent);
+HRESULT STDMETHODCALLTYPE InPlace_OnUIDeactivate(IOleInPlaceSite FAR* This, BOOL fUndoable);
+HRESULT STDMETHODCALLTYPE InPlace_OnInPlaceDeactivate(IOleInPlaceSite FAR* This);
+HRESULT STDMETHODCALLTYPE InPlace_DiscardUndoState(IOleInPlaceSite FAR* This);
+HRESULT STDMETHODCALLTYPE InPlace_DeactivateAndUndo(IOleInPlaceSite FAR* This);
+HRESULT STDMETHODCALLTYPE InPlace_OnPosRectChange(IOleInPlaceSite FAR* This, LPCRECT lprcPosRect);
+
+IOleInPlaceSiteVtbl MyIOleInPlaceSiteTable = {InPlace_QueryInterface,
+InPlace_AddRef,
+InPlace_Release,
+InPlace_GetWindow,
+InPlace_ContextSensitiveHelp,
+InPlace_CanInPlaceActivate,
+InPlace_OnInPlaceActivate,
+InPlace_OnUIActivate,
+InPlace_GetWindowContext,
+InPlace_Scroll,
+InPlace_OnUIDeactivate,
+InPlace_OnInPlaceDeactivate,
+InPlace_DiscardUndoState,
+InPlace_DeactivateAndUndo,
+InPlace_OnPosRectChange};
+
+typedef struct {
+ IOleInPlaceSite inplace;
+ _IOleInPlaceFrameEx frame;
+} _IOleInPlaceSiteEx;
+
+typedef struct {
+ IDocHostUIHandler ui;
+} _IDocHostUIHandlerEx;
+
+typedef struct {
+ IOleClientSite client;
+ _IOleInPlaceSiteEx inplace;
+ _IDocHostUIHandlerEx ui;
+} _IOleClientSiteEx;
+
+#define NOTIMPLEMENTED return(E_NOTIMPL)
+
+typedef struct
+{
+ char *pszHTML;
+ char *pszTitle;
+ int width;
+ int height;
+ HWND hWnd; // out
+} ShowIEWndParam;
+
+
+//////////////////////////////////// My IDocHostUIHandler functions //////////////////////////////////////
+//
+HRESULT STDMETHODCALLTYPE UI_QueryInterface(IDocHostUIHandler FAR* This, REFIID riid, LPVOID FAR* ppvObj)
+{
+ return(Site_QueryInterface((IOleClientSite *)((char *)This - sizeof(IOleClientSite) - sizeof(_IOleInPlaceSiteEx)), riid, ppvObj));
+}
+
+HRESULT STDMETHODCALLTYPE UI_AddRef(IDocHostUIHandler FAR* This)
+{
+ return(1);
+}
+
+HRESULT STDMETHODCALLTYPE UI_Release(IDocHostUIHandler FAR* This)
+{
+ return(1);
+}
+
+HRESULT STDMETHODCALLTYPE UI_ShowContextMenu(IDocHostUIHandler FAR* This, DWORD dwID, POINT __RPC_FAR *ppt, IUnknown __RPC_FAR *pcmdtReserved, IDispatch __RPC_FAR *pdispReserved)
+{
+ return(S_OK);
+}
+
+HRESULT STDMETHODCALLTYPE UI_GetHostInfo(IDocHostUIHandler FAR* This, DOCHOSTUIINFO __RPC_FAR *pInfo)
+{
+ pInfo->cbSize = sizeof(DOCHOSTUIINFO);
+ pInfo->dwFlags = DOCHOSTUIFLAG_NO3DBORDER;
+ pInfo->dwDoubleClick = DOCHOSTUIDBLCLK_DEFAULT;
+ return(S_OK);
+}
+
+HRESULT STDMETHODCALLTYPE UI_ShowUI(IDocHostUIHandler FAR* This, DWORD dwID, IOleInPlaceActiveObject __RPC_FAR *pActiveObject, IOleCommandTarget __RPC_FAR *pCommandTarget, IOleInPlaceFrame __RPC_FAR *pFrame, IOleInPlaceUIWindow __RPC_FAR *pDoc)
+{
+ return(S_OK);
+}
+
+HRESULT STDMETHODCALLTYPE UI_HideUI(IDocHostUIHandler FAR* This)
+{
+ return(S_OK);
+}
+
+HRESULT STDMETHODCALLTYPE UI_UpdateUI(IDocHostUIHandler FAR* This)
+{
+ return(S_OK);
+}
+
+HRESULT STDMETHODCALLTYPE UI_EnableModeless(IDocHostUIHandler FAR* This, BOOL fEnable)
+{
+ return(S_OK);
+}
+
+HRESULT STDMETHODCALLTYPE UI_OnDocWindowActivate(IDocHostUIHandler FAR* This, BOOL fActivate)
+{
+ return(S_OK);
+}
+
+HRESULT STDMETHODCALLTYPE UI_OnFrameWindowActivate(IDocHostUIHandler FAR* This, BOOL fActivate)
+{
+ return(S_OK);
+}
+
+HRESULT STDMETHODCALLTYPE UI_ResizeBorder(IDocHostUIHandler FAR* This, LPCRECT prcBorder, IOleInPlaceUIWindow __RPC_FAR *pUIWindow, BOOL fRameWindow)
+{
+ return(S_OK);
+}
+
+HRESULT STDMETHODCALLTYPE UI_TranslateAccelerator(IDocHostUIHandler FAR* This, LPMSG lpMsg, const GUID __RPC_FAR *pguidCmdGroup, DWORD nCmdID)
+{
+ return(S_FALSE);
+}
+
+HRESULT STDMETHODCALLTYPE UI_GetOptionKeyPath(IDocHostUIHandler FAR* This, LPOLESTR __RPC_FAR *pchKey, DWORD dw)
+{
+ return(S_FALSE);
+}
+
+HRESULT STDMETHODCALLTYPE UI_GetDropTarget(IDocHostUIHandler FAR* This, IDropTarget __RPC_FAR *pDropTarget, IDropTarget __RPC_FAR *__RPC_FAR *ppDropTarget)
+{
+ return(S_FALSE);
+}
+
+HRESULT STDMETHODCALLTYPE UI_GetExternal(IDocHostUIHandler FAR* This, IDispatch __RPC_FAR *__RPC_FAR *ppDispatch)
+{
+ *ppDispatch = 0;
+ return(S_FALSE);
+}
+
+HRESULT STDMETHODCALLTYPE UI_TranslateUrl(IDocHostUIHandler FAR* This, DWORD dwTranslate, OLECHAR __RPC_FAR *pchURLIn, OLECHAR __RPC_FAR *__RPC_FAR *ppchURLOut)
+{
+ *ppchURLOut = 0;
+ return(S_FALSE);
+}
+
+HRESULT STDMETHODCALLTYPE UI_FilterDataObject(IDocHostUIHandler FAR* This, IDataObject __RPC_FAR *pDO, IDataObject __RPC_FAR *__RPC_FAR *ppDORet)
+{
+ *ppDORet = 0;
+ return(S_FALSE);
+}
+
+////////////////////////////////////// My IOleClientSite functions /////////////////////////////////////
+//
+
+HRESULT STDMETHODCALLTYPE Site_QueryInterface(IOleClientSite FAR* This, REFIID riid, void ** ppvObject)
+{
+ if (!memcmp(riid, &IID_IUnknown, sizeof(GUID)) || !memcmp(riid, &IID_IOleClientSite, sizeof(GUID)))
+ *ppvObject = &((_IOleClientSiteEx *)This)->client;
+ else if (!memcmp(riid, &IID_IOleInPlaceSite, sizeof(GUID)))
+ *ppvObject = &((_IOleClientSiteEx *)This)->inplace;
+ else if (!memcmp(riid, &IID_IDocHostUIHandler, sizeof(GUID)))
+ *ppvObject = &((_IOleClientSiteEx *)This)->ui;
+ else
+ {
+ *ppvObject = 0;
+ return(E_NOINTERFACE);
+ }
+
+ return(S_OK);
+}
+
+HRESULT STDMETHODCALLTYPE Site_AddRef(IOleClientSite FAR* This)
+{
+ return(1);
+}
+
+HRESULT STDMETHODCALLTYPE Site_Release(IOleClientSite FAR* This)
+{
+ return(1);
+}
+
+HRESULT STDMETHODCALLTYPE Site_SaveObject(IOleClientSite FAR* This)
+{
+ NOTIMPLEMENTED;
+}
+
+HRESULT STDMETHODCALLTYPE Site_GetMoniker(IOleClientSite FAR* This, DWORD dwAssign, DWORD dwWhichMoniker, IMoniker ** ppmk)
+{
+ NOTIMPLEMENTED;
+}
+
+HRESULT STDMETHODCALLTYPE Site_GetContainer(IOleClientSite FAR* This, LPOLECONTAINER FAR* ppContainer)
+{
+ *ppContainer = 0;
+
+ return(E_NOINTERFACE);
+}
+
+HRESULT STDMETHODCALLTYPE Site_ShowObject(IOleClientSite FAR* This)
+{
+ return(NOERROR);
+}
+
+HRESULT STDMETHODCALLTYPE Site_OnShowWindow(IOleClientSite FAR* This, BOOL fShow)
+{
+ NOTIMPLEMENTED;
+}
+
+HRESULT STDMETHODCALLTYPE Site_RequestNewObjectLayout(IOleClientSite FAR* This)
+{
+ NOTIMPLEMENTED;
+}
+
+
+////////////////////////////////////// My IOleInPlaceSite functions /////////////////////////////////////
+//
+HRESULT STDMETHODCALLTYPE InPlace_QueryInterface(IOleInPlaceSite FAR* This, REFIID riid, LPVOID FAR* ppvObj)
+{
+ return(Site_QueryInterface((IOleClientSite *)((char *)This - sizeof(IOleClientSite)), riid, ppvObj));
+}
+
+HRESULT STDMETHODCALLTYPE InPlace_AddRef(IOleInPlaceSite FAR* This)
+{
+ return(1);
+}
+
+HRESULT STDMETHODCALLTYPE InPlace_Release(IOleInPlaceSite FAR* This)
+{
+ return(1);
+}
+
+HRESULT STDMETHODCALLTYPE InPlace_GetWindow(IOleInPlaceSite FAR* This, HWND FAR* lphwnd)
+{
+ *lphwnd = ((_IOleInPlaceSiteEx FAR*)This)->frame.window;
+ return(S_OK);
+}
+
+HRESULT STDMETHODCALLTYPE InPlace_ContextSensitiveHelp(IOleInPlaceSite FAR* This, BOOL fEnterMode)
+{
+ NOTIMPLEMENTED;
+}
+
+HRESULT STDMETHODCALLTYPE InPlace_CanInPlaceActivate(IOleInPlaceSite FAR* This)
+{
+ return(S_OK);
+}
+
+HRESULT STDMETHODCALLTYPE InPlace_OnInPlaceActivate(IOleInPlaceSite FAR* This)
+{
+ return(S_OK);
+}
+
+HRESULT STDMETHODCALLTYPE InPlace_OnUIActivate(IOleInPlaceSite FAR* This)
+{
+ return(S_OK);
+}
+
+HRESULT STDMETHODCALLTYPE InPlace_GetWindowContext(IOleInPlaceSite FAR* This, LPOLEINPLACEFRAME FAR* lplpFrame, LPOLEINPLACEUIWINDOW FAR* lplpDoc, LPRECT lprcPosRect, LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo)
+{
+ *lplpFrame = (LPOLEINPLACEFRAME)&((_IOleInPlaceSiteEx *)This)->frame;
+ *lplpDoc = 0;
+
+ lpFrameInfo->fMDIApp = FALSE;
+ lpFrameInfo->hwndFrame = ((_IOleInPlaceFrameEx *)*lplpFrame)->window;
+ lpFrameInfo->haccel = 0;
+ lpFrameInfo->cAccelEntries = 0;
+
+ return(S_OK);
+}
+
+HRESULT STDMETHODCALLTYPE InPlace_Scroll(IOleInPlaceSite FAR* This, SIZE scrollExtent)
+{
+ NOTIMPLEMENTED;
+}
+
+HRESULT STDMETHODCALLTYPE InPlace_OnUIDeactivate(IOleInPlaceSite FAR* This, BOOL fUndoable)
+{
+ return(S_OK);
+}
+
+HRESULT STDMETHODCALLTYPE InPlace_OnInPlaceDeactivate(IOleInPlaceSite FAR* This)
+{
+ return(S_OK);
+}
+
+HRESULT STDMETHODCALLTYPE InPlace_DiscardUndoState(IOleInPlaceSite FAR* This)
+{
+ NOTIMPLEMENTED;
+}
+
+HRESULT STDMETHODCALLTYPE InPlace_DeactivateAndUndo(IOleInPlaceSite FAR* This)
+{
+ NOTIMPLEMENTED;
+}
+
+HRESULT STDMETHODCALLTYPE InPlace_OnPosRectChange(IOleInPlaceSite FAR* This, LPCRECT lprcPosRect)
+{
+ IOleObject *browserObject;
+ IOleInPlaceObject *inplace;
+
+ browserObject = *((IOleObject **)((char *)This - sizeof(IOleObject *) - sizeof(IOleClientSite)));
+ if (!browserObject->lpVtbl->QueryInterface(browserObject, &IID_IOleInPlaceObject, (void**)&inplace))
+ {
+ inplace->lpVtbl->SetObjectRects(inplace, lprcPosRect, lprcPosRect);
+ inplace->lpVtbl->Release(inplace);
+ }
+
+ return(S_OK);
+}
+
+
+
+////////////////////////////////////// My IOleInPlaceFrame functions /////////////////////////////////////////
+//
+HRESULT STDMETHODCALLTYPE Frame_QueryInterface(IOleInPlaceFrame FAR* This, REFIID riid, LPVOID FAR* ppvObj)
+{
+ NOTIMPLEMENTED;
+}
+
+HRESULT STDMETHODCALLTYPE Frame_AddRef(IOleInPlaceFrame FAR* This)
+{
+ return(1);
+}
+
+HRESULT STDMETHODCALLTYPE Frame_Release(IOleInPlaceFrame FAR* This)
+{
+ return(1);
+}
+
+HRESULT STDMETHODCALLTYPE Frame_GetWindow(IOleInPlaceFrame FAR* This, HWND FAR* lphwnd)
+{
+ *lphwnd = ((_IOleInPlaceFrameEx *)This)->window;
+ return(S_OK);
+}
+
+HRESULT STDMETHODCALLTYPE Frame_ContextSensitiveHelp(IOleInPlaceFrame FAR* This, BOOL fEnterMode)
+{
+ NOTIMPLEMENTED;
+}
+
+HRESULT STDMETHODCALLTYPE Frame_GetBorder(IOleInPlaceFrame FAR* This, LPRECT lprectBorder)
+{
+ NOTIMPLEMENTED;
+}
+
+HRESULT STDMETHODCALLTYPE Frame_RequestBorderSpace(IOleInPlaceFrame FAR* This, LPCBORDERWIDTHS pborderwidths)
+{
+ NOTIMPLEMENTED;
+}
+
+HRESULT STDMETHODCALLTYPE Frame_SetBorderSpace(IOleInPlaceFrame FAR* This, LPCBORDERWIDTHS pborderwidths)
+{
+ NOTIMPLEMENTED;
+}
+
+HRESULT STDMETHODCALLTYPE Frame_SetActiveObject(IOleInPlaceFrame FAR* This, IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName)
+{
+ return(S_OK);
+}
+
+HRESULT STDMETHODCALLTYPE Frame_InsertMenus(IOleInPlaceFrame FAR* This, HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths)
+{
+ NOTIMPLEMENTED;
+}
+
+HRESULT STDMETHODCALLTYPE Frame_SetMenu(IOleInPlaceFrame FAR* This, HMENU hmenuShared, HOLEMENU holemenu, HWND hwndActiveObject)
+{
+ return(S_OK);
+}
+
+HRESULT STDMETHODCALLTYPE Frame_RemoveMenus(IOleInPlaceFrame FAR* This, HMENU hmenuShared)
+{
+ NOTIMPLEMENTED;
+}
+
+HRESULT STDMETHODCALLTYPE Frame_SetStatusText(IOleInPlaceFrame FAR* This, LPCOLESTR pszStatusText)
+{
+ return(S_OK);
+}
+
+HRESULT STDMETHODCALLTYPE Frame_EnableModeless(IOleInPlaceFrame FAR* This, BOOL fEnable)
+{
+ return(S_OK);
+}
+
+HRESULT STDMETHODCALLTYPE Frame_TranslateAccelerator(IOleInPlaceFrame FAR* This, LPMSG lpmsg, WORD wID)
+{
+ NOTIMPLEMENTED;
+}
+
+
+
+
+/*************************** UnEmbedBrowserObject() ************************
+ * Called to detach the browser object from our host window, and free its
+ * resources, right before we destroy our window.
+ *
+ * hwnd = Handle to the window hosting the browser object.
+ *
+ * NOTE: The pointer to the browser object must have been stored in the
+ * window's USERDATA field. In other words, don't call UnEmbedBrowserObject().
+ * with a HWND that wasn't successfully passed to EmbedBrowserObject().
+ */
+
+void UnEmbedBrowserObject(HWND hwnd)
+{
+ IOleObject **browserHandle;
+ IOleObject *browserObject;
+
+ // Retrieve the browser object's pointer we stored in our window's GWL_USERDATA when
+ // we initially attached the browser object to this window.
+ if ((browserHandle = (IOleObject **)GetWindowLongPtr(hwnd, GWLP_USERDATA)))
+ {
+ // Unembed the browser object, and release its resources.
+ browserObject = *browserHandle;
+ browserObject->lpVtbl->Close(browserObject, OLECLOSE_NOSAVE);
+ browserObject->lpVtbl->Release(browserObject);
+
+ GlobalFree(browserHandle);
+
+ return;
+ }
+}
+
+
+/******************************* DisplayHTMLStr() ****************************
+ * Takes a string containing some HTML BODY, and displays it in the specified
+ * window. For example, perhaps you want to display the HTML text of...
+ *
+ * <P>This is a picture.<P><IMG src="mypic.jpg">
+ *
+ * hwnd = Handle to the window hosting the browser object.
+ * string = Pointer to nul-terminated string containing the HTML BODY.
+ * (NOTE: No <BODY></BODY> tags are required in the string).
+ *
+ * RETURNS: 0 if success, or non-zero if an error.
+ *
+ * NOTE: EmbedBrowserObject() must have been successfully called once with the
+ * specified window, prior to calling this function. You need call
+ * EmbedBrowserObject() once only, and then you can make multiple calls to
+ * this function to display numerous pages in the specified window.
+ */
+
+long DisplayHTMLStr(HWND hwnd, LPCTSTR string)
+{
+ IWebBrowser2 *webBrowser2;
+ LPDISPATCH lpDispatch;
+ IHTMLDocument2 *htmlDoc2;
+ IOleObject *browserObject;
+ SAFEARRAY *sfArray;
+ VARIANT myURL;
+ VARIANT *pVar;
+ BSTR bstr;
+
+ // Retrieve the browser object's pointer we stored in our window's GWL_USERDATA when
+ // we initially attached the browser object to this window.
+ browserObject = *((IOleObject **)GetWindowLongPtr(hwnd, GWLP_USERDATA));
+
+ // Assume an error.
+ bstr = 0;
+
+ // We want to get the base address (ie, a pointer) to the IWebBrowser2 object embedded within the browser
+ // object, so we can call some of the functions in the former's table.
+ if (!browserObject->lpVtbl->QueryInterface(browserObject, &IID_IWebBrowser2, (void**)&webBrowser2))
+ {
+ // Ok, now the pointer to our IWebBrowser2 object is in 'webBrowser2', and so its VTable is
+ // webBrowser2->lpVtbl.
+
+ // Before we can get_Document(), we actually need to have some HTML page loaded in the browser. So,
+ // let's load an empty HTML page. Then, once we have that empty page, we can get_Document() and
+ // write() to stuff our HTML string into it.
+ VariantInit(&myURL);
+ myURL.vt = VT_BSTR;
+ myURL.bstrVal = SysAllocString(L"about:blank");
+
+ // Call the Navigate2() function to actually display the page.
+ webBrowser2->lpVtbl->Navigate2(webBrowser2, &myURL, 0, 0, 0, 0);
+
+ // Free any resources (including the BSTR).
+ VariantClear(&myURL);
+
+ // Call the IWebBrowser2 object's get_Document so we can get its DISPATCH object. I don't know why you
+ // don't get the DISPATCH object via the browser object's QueryInterface(), but you don't.
+ if (!webBrowser2->lpVtbl->get_Document(webBrowser2, &lpDispatch))
+ {
+ // We want to get a pointer to the IHTMLDocument2 object embedded within the DISPATCH
+ // object, so we can call some of the functions in the former's table.
+ if (!lpDispatch->lpVtbl->QueryInterface(lpDispatch, &IID_IHTMLDocument2, (void**)&htmlDoc2))
+ {
+ // Ok, now the pointer to our IHTMLDocument2 object is in 'htmlDoc2', and so its VTable is
+ // htmlDoc2->lpVtbl.
+
+ // Our HTML must be in the form of a BSTR. And it must be passed to write() in an
+ // array of "VARIENT" structs. So let's create all that.
+ if ((sfArray = SafeArrayCreate(VT_VARIANT, 1, (SAFEARRAYBOUND *)&ArrayBound)))
+ {
+ if (!SafeArrayAccessData(sfArray, (void**)&pVar))
+ {
+ pVar->vt = VT_BSTR;
+#ifndef UNICODE
+ {
+ wchar_t *buffer;
+ DWORD size;
+
+ size = MultiByteToWideChar(CP_ACP, 0, string, -1, 0, 0);
+ if (!(buffer = (wchar_t *)GlobalAlloc(GMEM_FIXED, sizeof(wchar_t) * size))) goto bad;
+ MultiByteToWideChar(CP_ACP, 0, string, -1, buffer, size);
+ bstr = SysAllocString(buffer);
+ GlobalFree(buffer);
+ }
+#else
+ bstr = SysAllocString(string);
+#endif
+ // Store our BSTR pointer in the VARIENT.
+ if ((pVar->bstrVal = bstr))
+ {
+ htmlDoc2->lpVtbl->clear(htmlDoc2);
+ // Pass the VARIENT with its BSTR to write() in order to shove our desired HTML string
+ // into the body of that empty page we created above.
+ htmlDoc2->lpVtbl->write(htmlDoc2, sfArray);
+
+ // Close the document. If we don't do this, subsequent calls to DisplayHTMLStr
+ // would append to the current contents of the page
+ htmlDoc2->lpVtbl->close(htmlDoc2);
+
+ // Normally, we'd need to free our BSTR, but SafeArrayDestroy() does it for us
+// SysFreeString(bstr);
+ }
+ }
+
+ // Free the array. This also frees the VARIENT that SafeArrayAccessData created for us,
+ // and even frees the BSTR we allocated with SysAllocString
+ SafeArrayDestroy(sfArray);
+ }
+
+ // Release the IHTMLDocument2 object.
+bad: htmlDoc2->lpVtbl->Release(htmlDoc2);
+ }
+
+ // Release the DISPATCH object.
+ lpDispatch->lpVtbl->Release(lpDispatch);
+ }
+
+ // Release the IWebBrowser2 object.
+ webBrowser2->lpVtbl->Release(webBrowser2);
+ }
+
+ // No error?
+ if (bstr) return(0);
+
+ // An error
+ return(-1);
+}
+
+
+
+/******************************* ResizeBrowser() ****************************
+ * Resizes the browser object for the specified window to the specified
+ * width and height.
+ *
+ * hwnd = Handle to the window hosting the browser object.
+ * width = Width.
+ * height = Height.
+ *
+ * NOTE: EmbedBrowserObject() must have been successfully called once with the
+ * specified window, prior to calling this function. You need call
+ * EmbedBrowserObject() once only, and then you can make multiple calls to
+ * this function to resize the browser object.
+ */
+
+void ResizeBrowser(HWND hwnd, DWORD width, DWORD height)
+{
+ IWebBrowser2 *webBrowser2;
+ IOleObject *browserObject;
+
+ // Retrieve the browser object's pointer we stored in our window's GWL_USERDATA when
+ // we initially attached the browser object to this window.
+ browserObject = *((IOleObject **)GetWindowLongPtr(hwnd, GWLP_USERDATA));
+
+ // We want to get the base address (ie, a pointer) to the IWebBrowser2 object embedded within the browser
+ // object, so we can call some of the functions in the former's table.
+ if (!browserObject->lpVtbl->QueryInterface(browserObject, &IID_IWebBrowser2, (void**)&webBrowser2))
+ {
+ // Ok, now the pointer to our IWebBrowser2 object is in 'webBrowser2', and so its VTable is
+ // webBrowser2->lpVtbl.
+
+ // Call are put_Width() and put_Height() to set the new width/height.
+ webBrowser2->lpVtbl->put_Width(webBrowser2, width);
+ webBrowser2->lpVtbl->put_Height(webBrowser2, height);
+
+ // We no longer need the IWebBrowser2 object (ie, we don't plan to call any more functions in it,
+ // so we can release our hold on it). Note that we'll still maintain our hold on the browser
+ // object.
+ webBrowser2->lpVtbl->Release(webBrowser2);
+ }
+}
+
+
+
+
+
+/***************************** EmbedBrowserObject() **************************
+ * Puts the browser object inside our host window, and save a pointer to this
+ * window's browser object in the window's GWL_USERDATA field.
+ *
+ * hwnd = Handle of our window into which we embed the browser object.
+ *
+ * RETURNS: 0 if success, or non-zero if an error.
+ *
+ * NOTE: We tell the browser object to occupy the entire client area of the
+ * window.
+ *
+ * NOTE: No HTML page will be displayed here. We can do that with a subsequent
+ * call to either DisplayHTMLPage() or DisplayHTMLStr(). This is merely once-only
+ * initialization for using the browser object. In a nutshell, what we do
+ * here is get a pointer to the browser object in our window's GWL_USERDATA
+ * so we can access that object's functions whenever we want, and we also pass
+ * the browser a pointer to our IOleClientSite struct so that the browser can
+ * call our functions in our struct's VTable.
+ */
+
+long EmbedBrowserObject(HWND hwnd)
+{
+ LPCLASSFACTORY pClassFactory;
+ IOleObject *browserObject;
+ IWebBrowser2 *webBrowser2;
+ RECT rect;
+ char *ptr;
+ _IOleClientSiteEx *_iOleClientSiteEx;
+
+ // Our IOleClientSite, IOleInPlaceSite, and IOleInPlaceFrame functions need to get our window handle. We
+ // could store that in some global. But then, that would mean that our functions would work with only that
+ // one window. If we want to create multiple windows, each hosting its own browser object (to display its
+ // own web page), then we need to create unique IOleClientSite, IOleInPlaceSite, and IOleInPlaceFrame
+ // structs for each window. And we'll put an extra field at the end of those structs to store our extra
+ // data such as a window handle. So, our functions won't have to touch global data, and can therefore be
+ // re-entrant and work with multiple objects/windows.
+ //
+ // Remember that a pointer to our IOleClientSite we create here will be passed as the first arg to every
+ // one of our IOleClientSite functions. Ditto with the IOleInPlaceFrame object we create here, and the
+ // IOleInPlaceFrame functions. So, our functions are able to retrieve the window handle we'll store here,
+ // and then, they'll work with all such windows containing a browser control.
+ //
+ // Furthermore, since the browser will be calling our IOleClientSite's QueryInterface to get a pointer to
+ // our IOleInPlaceSite and IDocHostUIHandler objects, that means that our IOleClientSite QueryInterface
+ // must have an easy way to grab those pointers. Probably the easiest thing to do is just embed our
+ // IOleInPlaceSite and IDocHostUIHandler objects inside of an extended IOleClientSite which we'll call
+ // a _IOleClientSiteEx. As long as they come after the pointer to the IOleClientSite VTable, then we're
+ // ok.
+ //
+ // Of course, we need to GlobalAlloc the above structs now. We'll just get all 4 with a single call to
+ // GlobalAlloc, especially since 3 of them are all contained inside of our _IOleClientSiteEx anyway.
+ //
+ // So, we're not actually allocating separate IOleClientSite, IOleInPlaceSite, IOleInPlaceFrame and
+ // IDocHostUIHandler structs.
+ //
+ // One final thing. We're going to allocate extra room to store the pointer to the browser object.
+ if (!(ptr = (char *)GlobalAlloc(GMEM_FIXED, sizeof(_IOleClientSiteEx) + sizeof(IOleObject *))))
+ return(-1);
+
+ // Initialize our IOleClientSite object with a pointer to our IOleClientSite VTable.
+ _iOleClientSiteEx = (_IOleClientSiteEx *)(ptr + sizeof(IOleObject *));
+ _iOleClientSiteEx->client.lpVtbl = &MyIOleClientSiteTable;
+
+ // Initialize our IOleInPlaceSite object with a pointer to our IOleInPlaceSite VTable.
+ _iOleClientSiteEx->inplace.inplace.lpVtbl = &MyIOleInPlaceSiteTable;
+
+ // Initialize our IOleInPlaceFrame object with a pointer to our IOleInPlaceFrame VTable.
+ _iOleClientSiteEx->inplace.frame.frame.lpVtbl = &MyIOleInPlaceFrameTable;
+
+ // Save our HWND (in the IOleInPlaceFrame object) so our IOleInPlaceFrame functions can retrieve it.
+ _iOleClientSiteEx->inplace.frame.window = hwnd;
+
+ // Initialize our IDocHostUIHandler object with a pointer to our IDocHostUIHandler VTable.
+ _iOleClientSiteEx->ui.ui.lpVtbl = &MyIDocHostUIHandlerTable;
+
+ // Get a pointer to the browser object and lock it down (so it doesn't "disappear" while we're using
+ // it in this program). We do this by calling the OS function CoGetClassObject().
+ //
+ // NOTE: We need this pointer to interact with and control the browser. With normal WIN32 controls such as a
+ // Static, Edit, Combobox, etc, you obtain an HWND and send messages to it with SendMessage(). Not so with
+ // the browser object. You need to get a pointer to its "base structure" (as returned by CoGetClassObject()). This
+ // structure contains an array of pointers to functions you can call within the browser object. Actually, the
+ // base structure contains a 'lpVtbl' field that is a pointer to that array. We'll call the array a 'VTable'.
+ //
+ // For example, the browser object happens to have a SetHostNames() function we want to call. So, after we
+ // retrieve the pointer to the browser object (in a local we'll name 'browserObject'), then we can call that
+ // function, and pass it args, as so:
+ //
+ // browserObject->lpVtbl->SetHostNames(browserObject, SomeString, SomeString);
+ //
+ // There's our pointer to the browser object in 'browserObject'. And there's the pointer to the browser object's
+ // VTable in 'browserObject->lpVtbl'. And the pointer to the SetHostNames function happens to be stored in an
+ // field named 'SetHostNames' within the VTable. So we are actually indirectly calling SetHostNames by using
+ // a pointer to it. That's how you use a VTable.
+ //
+ // NOTE: We pass our _IOleClientSiteEx struct and lie -- saying that it's a IOleClientSite. It's ok. A
+ // _IOleClientSiteEx struct starts with an embedded IOleClientSite. So the browser won't care, and we want
+ // this extended struct passed to our IOleClientSite functions.
+
+ // Get a pointer to the browser object's IClassFactory object via CoGetClassObject()
+ pClassFactory = 0;
+ if (!CoGetClassObject(&CLSID_WebBrowser, CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER, NULL, &IID_IClassFactory, (void **)&pClassFactory) && pClassFactory)
+ {
+ // Call the IClassFactory's CreateInstance() to create a browser object
+ if (!pClassFactory->lpVtbl->CreateInstance(pClassFactory, 0, &IID_IOleObject, &browserObject))
+ {
+ // Free the IClassFactory. We need it only to create a browser object instance
+ pClassFactory->lpVtbl->Release(pClassFactory);
+
+ // Ok, we now have the pointer to the browser object in 'browserObject'. Let's save this in the
+ // memory block we allocated above, and then save the pointer to that whole thing in our window's
+ // USERDATA field. That way, if we need multiple windows each hosting its own browser object, we can
+ // call EmbedBrowserObject() for each one, and easily associate the appropriate browser object with
+ // its matching window and its own objects containing per-window data.
+ *((IOleObject **)ptr) = browserObject;
+ SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)ptr);
+
+ // Give the browser a pointer to my IOleClientSite object
+ if (!browserObject->lpVtbl->SetClientSite(browserObject, (IOleClientSite *)_iOleClientSiteEx))
+ {
+ // We can now call the browser object's SetHostNames function. SetHostNames lets the browser object know our
+ // application's name and the name of the document in which we're embedding the browser. (Since we have no
+ // document name, we'll pass a 0 for the latter). When the browser object is opened for editing, it displays
+ // these names in its titlebar.
+ //
+ // We are passing 3 args to SetHostNames. You'll note that the first arg to SetHostNames is the base
+ // address of our browser control. This is something that you always have to remember when working in C
+ // (as opposed to C++). When calling a VTable function, the first arg to that function must always be the
+ // structure which contains the VTable. (In this case, that's the browser control itself). Why? That's
+ // because that function is always assumed to be written in C++. And the first argument to any C++ function
+ // must be its 'this' pointer (ie, the base address of its class, which in this case is our browser object
+ // pointer). In C++, you don't have to pass this first arg, because the C++ compiler is smart enough to
+ // produce an executable that always adds this first arg. In fact, the C++ compiler is smart enough to
+ // know to fetch the function pointer from the VTable, so you don't even need to reference that. In other
+ // words, the C++ equivalent code would be:
+ //
+ // browserObject->SetHostNames(L"My Host Name", 0);
+ //
+ // So, when you're trying to convert C++ code to C, always remember to add this first arg whenever you're
+ // dealing with a VTable (ie, the field is usually named 'lpVtbl') in the standard objects, and also add
+ // the reference to the VTable itself.
+ //
+ // Oh yeah, the L is because we need UNICODE strings. And BTW, the host and document names can be anything
+ // you want.
+ browserObject->lpVtbl->SetHostNames(browserObject, L"My Host Name", 0);
+
+ GetClientRect(hwnd, &rect);
+
+ // Let browser object know that it is embedded in an OLE container.
+ if (!OleSetContainedObject((struct IUnknown *)browserObject, TRUE) &&
+
+ // Set the display area of our browser control the same as our window's size
+ // and actually put the browser object into our window.
+ !browserObject->lpVtbl->DoVerb(browserObject, OLEIVERB_SHOW, NULL, (IOleClientSite *)_iOleClientSiteEx, -1, hwnd, &rect) &&
+
+ // Ok, now things may seem to get even trickier, One of those function pointers in the browser's VTable is
+ // to the QueryInterface() function. What does this function do? It lets us grab the base address of any
+ // other object that may be embedded within the browser object. And this other object has its own VTable
+ // containing pointers to more functions we can call for that object.
+ //
+ // We want to get the base address (ie, a pointer) to the IWebBrowser2 object embedded within the browser
+ // object, so we can call some of the functions in the former's table. For example, one IWebBrowser2 function
+ // we intend to call below will be Navigate2(). So we call the browser object's QueryInterface to get our
+ // pointer to the IWebBrowser2 object.
+ !browserObject->lpVtbl->QueryInterface(browserObject, &IID_IWebBrowser2, (void**)&webBrowser2))
+ {
+ // Ok, now the pointer to our IWebBrowser2 object is in 'webBrowser2', and so its VTable is
+ // webBrowser2->lpVtbl.
+
+ // Let's call several functions in the IWebBrowser2 object to position the browser display area
+ // in our window. The functions we call are put_Left(), put_Top(), put_Width(), and put_Height().
+ // Note that we reference the IWebBrowser2 object's VTable to get pointers to those functions. And
+ // also note that the first arg we pass to each is the pointer to the IWebBrowser2 object.
+ webBrowser2->lpVtbl->put_Left(webBrowser2, 0);
+ webBrowser2->lpVtbl->put_Top(webBrowser2, 0);
+ webBrowser2->lpVtbl->put_Width(webBrowser2, rect.right);
+ webBrowser2->lpVtbl->put_Height(webBrowser2, rect.bottom);
+
+ // We no longer need the IWebBrowser2 object (ie, we don't plan to call any more functions in it
+ // right now, so we can release our hold on it). Note that we'll still maintain our hold on the
+ // browser object until we're done with that object.
+ webBrowser2->lpVtbl->Release(webBrowser2);
+
+ // Success
+ return(0);
+ }
+ }
+
+ // Something went wrong setting up the browser!
+ UnEmbedBrowserObject(hwnd);
+ return(-4);
+ }
+
+ pClassFactory->lpVtbl->Release(pClassFactory);
+ GlobalFree(ptr);
+
+ // Can't create an instance of the browser!
+ return(-3);
+ }
+
+ GlobalFree(ptr);
+
+ // Can't get the web browser's IClassFactory!
+ return(-2);
+}
+
+
+
+
+
+/****************************** WindowProc() ***************************
+ * Our message handler for our window to host the browser.
+ */
+
+LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_SIZE:
+ {
+ // Resize the browser object to fit the window
+ ResizeBrowser(hwnd, LOWORD(lParam), HIWORD(lParam));
+ return(0);
+ }
+
+ case WM_CREATE:
+ {
+ // Embed the browser object into our host window. We need do this only
+ // once. Note that the browser object will start calling some of our
+ // IOleInPlaceFrame and IOleClientSite functions as soon as we start
+ // calling browser object functions in EmbedBrowserObject().
+ if (EmbedBrowserObject(hwnd)) return(-1);
+
+ // Success
+ return(0);
+ }
+
+ case WM_DESTROY:
+ {
+ int i, nCount;
+
+ // Detach the browser object from this window, and free resources.
+ UnEmbedBrowserObject(hwnd);
+
+ // If all the windows are now closed, quit this app
+ if (m_hWindows)
+ {
+ for (i=0, nCount=List_Count(m_hWindows); i<nCount; i++)
+ {
+ if (List_ElementAt (m_hWindows, i)==hwnd)
+ {
+ List_RemoveElementAt (m_hWindows, i);
+ break;
+ }
+ }
+ }
+
+ return(TRUE);
+ }
+
+
+ }
+
+ return(DefWindowProc(hwnd, uMsg, wParam, lParam));
+}
+
+// -----------------------------------------------------------------------------
+
+
+static DWORD WINAPI ShowIEWndFunc(PVOID pLoadWnd)
+{
+ MSG msg;
+ WNDCLASSEX wc={0};
+ HWND hWndCache = NULL;
+ static const TCHAR ClassName[] = "imo.im Voicechat wnd";
+
+ if (CoInitialize(NULL) != S_OK) return -1;
+
+ wc.cbSize = sizeof(WNDCLASSEX);
+ wc.cbWndExtra = 2*sizeof(PVOID); // Extra to be used by caller, as we already make use of GWL_USERDATA
+ wc.hInstance = (HINSTANCE)GetModuleHandle(NULL);
+ wc.lpfnWndProc = WindowProc;
+ wc.lpszClassName = &ClassName[0];
+ RegisterClassEx(&wc);
+
+ m_hWindows = List_Init(0);
+
+ if (pLoadWnd)
+ {
+ // Create an invisible window with IE Control so that the appropriate libraries get loaded
+ // and a new window can be shown more quickly
+ hWndCache = CreateWindowEx(0, wc.lpszClassName, "dummy", WS_OVERLAPPEDWINDOW,
+ CW_USEDEFAULT, CW_USEDEFAULT, 0, 0,
+ HWND_DESKTOP, NULL, wc.hInstance, 0);
+ List_Push (m_hWindows, hWndCache);
+ DisplayHTMLStr(hWndCache, "");
+ }
+
+ while (GetMessage(&msg, 0, 0, 0) == 1)
+ {
+ switch (msg.message)
+ {
+ case WM_USER:
+ {
+ ShowIEWndParam *Param = (ShowIEWndParam *)msg.lParam;
+ if ((Param->hWnd = CreateWindowEx(0, wc.lpszClassName, Param->pszTitle, WS_OVERLAPPEDWINDOW,
+ CW_USEDEFAULT, CW_USEDEFAULT, Param->width, Param->height,
+ HWND_DESKTOP, NULL, wc.hInstance, 0)))
+ {
+ List_Push (m_hWindows, Param->hWnd);
+ DisplayHTMLStr(Param->hWnd, Param->pszHTML);
+ ShowWindow(Param->hWnd, SW_SHOWNORMAL);
+ SetForegroundWindow (Param->hWnd);
+ UpdateWindow(Param->hWnd);
+ }
+ SetEvent (m_hEvent);
+ break;
+ }
+ case WM_USER+1:
+ {
+ DestroyWindow ((HWND)msg.lParam);
+ break;
+ }
+ }
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+
+ UnregisterClass (wc.lpszClassName, wc.hInstance);
+ CoUninitialize();
+ if (m_hWindows) List_Exit (m_hWindows);
+ ExitThread (0);
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+// Interface
+// -----------------------------------------------------------------------------
+
+// bInitBrowser - Tries to initialize a dummy window on start so that subsequent
+// calls are faster as all libraries are already present in
+// memory. Drawback: Higher memory consumption
+int W32Browser_Init(BOOL bInitBrowser)
+{
+ if (m_hThread) W32Browser_Exit();
+ m_hThread = (HANDLE)_beginthreadex(NULL, 0, ShowIEWndFunc, (LPVOID)bInitBrowser, 0, &m_dwThread);
+ if (!m_hThread) return -1;
+ if (!(m_hEvent = CreateEvent (NULL, FALSE, FALSE, NULL)))
+ {
+ TerminateThread (m_hThread, -1);
+ CloseHandle (m_hThread);
+ return -1;
+ }
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+
+void W32Browser_Exit(void)
+{
+ if (m_hWindows)
+ {
+ HWND hWnd;
+
+ while (hWnd = List_Pop(m_hWindows))
+ W32Browser_CloseWindow (hWnd);
+ m_hWindows = NULL;
+ }
+ if (m_hThread)
+ {
+ PostThreadMessage (m_dwThread, WM_QUIT, 0, 0);
+ if (WaitForSingleObject (m_hThread, 2000) == WAIT_TIMEOUT)
+ TerminateThread (m_hThread, -1);
+ CloseHandle (m_hThread);
+ m_hThread = NULL;
+ }
+ if (m_hEvent)
+ {
+ CloseHandle (m_hEvent);
+ m_hEvent = NULL;
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void *W32Browser_ShowHTMLStr(char *pszHTMLStr, int width, int height, char *pszTitle)
+{
+ // Window gets its own thread to not block the Mainthread
+ static ShowIEWndParam Param;
+
+ Param.width = width;
+ Param.height = height;
+ Param.pszHTML = pszHTMLStr;
+ Param.pszTitle = pszTitle;
+ Param.hWnd = 0;
+ PostThreadMessage (m_dwThread, WM_USER, 0, (LPARAM)&Param);
+ WaitForSingleObject (m_hEvent, INFINITE);
+ return (void*)Param.hWnd;
+}
+
+// -----------------------------------------------------------------------------
+
+void W32Browser_CloseWindow (void *pWnd)
+{
+ PostThreadMessage (m_dwThread, WM_USER+1, 0, (LPARAM)pWnd);
+}
diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/w32browser.h b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/w32browser.h new file mode 100644 index 0000000000..effc86998d --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/w32browser.h @@ -0,0 +1,5 @@ +int W32Browser_Init(int bInitBrowser);
+void W32Browser_Exit(void);
+
+void *W32Browser_ShowHTMLStr(char *pszHTMLStr, int width, int height, char *pszTitle);
+void W32Browser_CloseWindow (void *pWnd);
diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/w32skypeemu.c b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/w32skypeemu.c new file mode 100644 index 0000000000..f9cc734cd1 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/w32skypeemu.c @@ -0,0 +1,387 @@ +#include <stdio.h>
+#include "imo2sproxy.h"
+#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 strcasecmp stricmp
+#define strncasecmp stricmpn
+#define mutex_t CRITICAL_SECTION
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include "memlist.h"
+#include "w32skypeemu.h"
+
+#ifndef _WIN64
+#if WINVER<0x0500
+#define SetWindowLongPtr SetWindowLong
+#define GetWindowLongPtr GetWindowLong
+#endif
+#ifndef LONG_PTR
+#define LONG_PTR LONG
+#endif
+#ifndef GWLP_USERDATA
+#define GWLP_USERDATA GWL_USERDATA
+#endif
+#endif
+
+// Skype API defines
+#define SKYPECONTROLAPI_ATTACH_SUCCESS 0
+#define SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION 1
+#define SKYPECONTROLAPI_ATTACH_REFUSED 2
+#define SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE 3
+#define SKYPECONTROLAPI_ATTACH_API_AVAILABLE 0x8001
+
+// -----------------------------------------------------------------------------
+
+typedef struct
+{
+ IMO2SPROXY vtbl; // Must be first!
+ IMO2SPROXY_CFG *pCfg;
+ W32SKYPEEMU_CFG *pMyCfg;
+ HWND hWndDispatch;
+ TYP_LIST *hClients;
+ mutex_t loopmutex;
+ DWORD dwThreadID;
+} IMO2SPROXY_INST;
+
+typedef struct
+{
+ HWND hWnd;
+ IMOSAPI *hInst;
+ IMO2SPROXY_INST *hProxy;
+ mutex_t sendmutex;
+ int iConnectionStat;
+} CONNINST;
+
+static UINT m_ControlAPIAttach = 0;
+static UINT m_ControlAPIDiscover = 0;
+
+// -----------------------------------------------------------------------------
+
+static void EventHandler(char *pszMsg, void *pUser);
+static CONNINST *FindClient(IMO2SPROXY_INST *hProxy, HWND hWnd);
+static void CleanConnections (TYP_LIST *hList);
+static void FreeConnection (CONNINST *pInst);
+static LONG APIENTRY WndProc(HWND hWnd, UINT message, UINT wParam, LONG lParam);
+
+static int Imo2sproxy_Open(IMO2SPROXY *hInst);
+static void Imo2sproxy_Loop(IMO2SPROXY *hInst);
+static void Imo2sproxy_Exit(IMO2SPROXY *hInst);
+
+// -----------------------------------------------------------------------------
+static void EventHandler(char *pszMsg, void *pUser)
+{
+ CONNINST *pInst = (CONNINST*)pUser;
+ COPYDATASTRUCT cds;
+ DWORD dwRes = 0;
+
+ LockMutex(pInst->sendmutex);
+ if (pInst->hProxy->pCfg->bVerbose && pInst->hProxy->pCfg->fpLog)
+ {
+ fprintf (pInst->hProxy->pCfg->fpLog, "%08X> %s\n", pInst->hWnd, pszMsg);
+ fflush (pInst->hProxy->pCfg->fpLog);
+ }
+ cds.dwData = 0;
+ cds.cbData = strlen(pszMsg)+1;
+ cds.lpData = pszMsg;
+ SendMessageTimeout (pInst->hWnd, WM_COPYDATA, (WPARAM)pInst->hProxy->hWndDispatch, (LPARAM)&cds, SMTO_NORMAL, 1000, &dwRes);
+ UnlockMutex(pInst->sendmutex);
+}
+
+// -----------------------------------------------------------------------------
+
+static CONNINST *FindClient(IMO2SPROXY_INST *hProxy, HWND hWnd)
+{
+ int i, nCount;
+ CONNINST *pConn;
+
+ for (i=0, nCount=List_Count(hProxy->hClients); i<nCount; i++)
+ {
+ if ((pConn=(CONNINST*)List_ElementAt (hProxy->hClients, i))->hWnd == hWnd)
+ return pConn;
+ }
+ return NULL;
+}
+
+// -----------------------------------------------------------------------------
+
+static void CleanConnections (TYP_LIST *hList)
+{
+ unsigned int i;
+ CONNINST *pInst;
+
+ for (i=0; i<List_Count(hList); i++)
+ {
+ pInst = List_ElementAt (hList, i);
+ if (!IsWindow (pInst->hWnd))
+ {
+ if (pInst->hInst) FreeConnection(pInst);
+ free (List_RemoveElementAt(hList, i));
+ i--;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+static void FreeConnection (CONNINST *pInst)
+{
+ if (pInst->hProxy->pCfg->bVerbose && pInst->hProxy->pCfg->fpLog)
+ {
+ fprintf (pInst->hProxy->pCfg->fpLog, "Closed connection %08X\n", pInst->hWnd);
+ fflush (pInst->hProxy->pCfg->fpLog);
+ }
+ ExitMutex (pInst->sendmutex);
+ if (pInst->hInst)
+ {
+ IMOSAPI *hInst = pInst->hInst;
+ pInst->hInst = NULL;
+ Imo2S_Exit(hInst);
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+static LONG APIENTRY WndProc(HWND hWnd, UINT message, UINT wParam, LONG lParam)
+{
+ switch (message)
+ {
+ case WM_CREATE:
+ {
+ LPCREATESTRUCT lpCr = (LPCREATESTRUCT)lParam;
+
+ SetWindowLongPtr (hWnd, GWLP_USERDATA, (LONG_PTR)lpCr->lpCreateParams);
+ SetTimer (hWnd, 0, 60000, NULL);
+ break;
+ }
+ case WM_COPYDATA:
+ {
+ PCOPYDATASTRUCT pCopyData = (PCOPYDATASTRUCT)lParam;
+ CONNINST *pInst;
+ IMO2SPROXY_INST *hProxy = (IMO2SPROXY_INST*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
+
+ if (pInst = FindClient (hProxy, (HWND)wParam))
+ {
+ if (pInst->hProxy->pMyCfg->bDelayLogin && pInst->iConnectionStat < 1)
+ {
+ char *pszError;
+
+ if ((pInst->iConnectionStat = Imo2S_Login (pInst->hInst, hProxy->pCfg->pszUser, hProxy->pCfg->pszPass, &pszError)) != 1)
+ {
+ pInst->hProxy->pCfg->logerror (stderr, "Connection %08X: Cannot login with (%s/****): %s\n",
+ pInst->hWnd, hProxy->pCfg->pszUser, pszError);
+ FreeConnection(pInst);
+ free (List_Pop(hProxy->hClients));
+ PostMessage ((HWND)wParam, m_ControlAPIAttach, (WPARAM)hWnd, SKYPECONTROLAPI_ATTACH_REFUSED);
+ return 0;
+ }
+ }
+ LockMutex(pInst->sendmutex);
+ if (pInst->hProxy->pCfg->bVerbose && pInst->hProxy->pCfg->fpLog)
+ {
+ fprintf (pInst->hProxy->pCfg->fpLog, "%08X< [%s]\n", pInst->hWnd, pCopyData->lpData);
+ fflush (pInst->hProxy->pCfg->fpLog);
+ }
+ Imo2S_Send (pInst->hInst, pCopyData->lpData);
+ UnlockMutex(pInst->sendmutex);
+ }
+ return 1;
+ }
+ case WM_TIMER:
+ // Housekeeping timer
+ CleanConnections (((IMO2SPROXY_INST*)GetWindowLongPtr(hWnd, GWLP_USERDATA))->hClients);
+ break;
+ case WM_DESTROY:
+ KillTimer (hWnd, 0);
+ break;
+ default:
+ if (message == m_ControlAPIDiscover)
+ {
+ CONNINST *pInst;
+ IMO2SPROXY_INST *hProxy = (IMO2SPROXY_INST*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
+ char *pszError;
+
+ if (!(pInst = FindClient (hProxy, (HWND)wParam)))
+ {
+ pInst = (CONNINST*)calloc (1, sizeof(CONNINST));
+ if (!pInst) break;
+ List_Push(hProxy->hClients, pInst);
+ pInst->hProxy = hProxy;
+ pInst->hWnd = (HWND)wParam;
+ if (hProxy->pCfg->bVerbose && hProxy->pCfg->fpLog)
+ fprintf (hProxy->pCfg->fpLog, "Imo2sproxy::SkypeControlAPIDiscover\n");
+
+ if (!(pInst->hInst = Imo2S_Init(EventHandler, pInst, hProxy->pCfg->iFlags)))
+ {
+ hProxy->pCfg->logerror (stderr, "Connection %08X: Cannot start Imo2Skype instance.\n", pInst->hWnd);
+ free (List_Pop(hProxy->hClients));
+ PostMessage ((HWND)wParam, m_ControlAPIAttach, (WPARAM)hWnd, SKYPECONTROLAPI_ATTACH_REFUSED);
+ return 0;
+ }
+
+ // FIXME: We should enable logging dependent on a loglevel rather than just enabling it
+ if (hProxy->pCfg->bVerbose)
+ Imo2S_SetLog (pInst->hInst, hProxy->pCfg->fpLog);
+
+ InitMutex(pInst->sendmutex);
+
+ if (!pInst->hProxy->pMyCfg->bDelayLogin)
+ {
+ PostMessage ((HWND)wParam, m_ControlAPIAttach, (WPARAM)hWnd, SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE);
+ if ((pInst->iConnectionStat = Imo2S_Login (pInst->hInst, hProxy->pCfg->pszUser, hProxy->pCfg->pszPass, &pszError)) != 1)
+ {
+ pInst->hProxy->pCfg->logerror (stderr, "Connection %08X: Cannot login with (%s/****): %s\n",
+ pInst->hWnd, hProxy->pCfg->pszUser, pszError);
+ FreeConnection(pInst);
+ free (List_Pop(hProxy->hClients));
+ PostMessage ((HWND)wParam, m_ControlAPIAttach, (WPARAM)hWnd, SKYPECONTROLAPI_ATTACH_REFUSED);
+ return 0;
+ }
+ PostMessage ((HWND)wParam, m_ControlAPIAttach, (WPARAM)hWnd, SKYPECONTROLAPI_ATTACH_API_AVAILABLE);
+ }
+ else
+ {
+ SendMessage ((HWND)wParam, m_ControlAPIAttach, (WPARAM)hWnd, SKYPECONTROLAPI_ATTACH_SUCCESS);
+ }
+ return 0;
+ }
+ else
+ SendMessage ((HWND)wParam, m_ControlAPIAttach, (WPARAM)hWnd, SKYPECONTROLAPI_ATTACH_SUCCESS);
+ return 0;
+ }
+ break;
+ }
+ return (DefWindowProc(hWnd, message, wParam, lParam));
+}
+
+
+
+// -----------------------------------------------------------------------------
+// PUBLIC
+// -----------------------------------------------------------------------------
+
+void W32SkypeEmu_Defaults (W32SKYPEEMU_CFG *pMyCfg)
+{
+ memset (pMyCfg, 0, sizeof(W32SKYPEEMU_CFG));
+ // Login on first command from Client, immediately send SKYPECONTROLAPI_ATTACH_SUCCESS
+ // This is necessary for some broken plugins, i.e. current SVN build of Miranda
+ // Skype plugin, which doesn't correctly poll again if SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE
+ // is sent.
+ pMyCfg->bDelayLogin = TRUE;
+}
+
+// -----------------------------------------------------------------------------
+
+IMO2SPROXY *W32SkypeEmu_Init (IMO2SPROXY_CFG *pCfg, W32SKYPEEMU_CFG *pMyCfg)
+{
+ IMO2SPROXY_INST *pstInst = calloc(sizeof(IMO2SPROXY_INST), 1);
+
+ pstInst->vtbl.Open = Imo2sproxy_Open;
+ pstInst->vtbl.Loop = Imo2sproxy_Loop;
+ pstInst->vtbl.Exit = Imo2sproxy_Exit;
+ pstInst->pCfg = pCfg;
+ pstInst->pMyCfg = pMyCfg;
+ InitMutex(pstInst->loopmutex);
+ return (IMO2SPROXY*)pstInst;
+}
+
+// -----------------------------------------------------------------------------
+// IMPLEMENTATION
+// -----------------------------------------------------------------------------
+static int Imo2sproxy_Open(IMO2SPROXY *hInst)
+{
+ IMO2SPROXY_INST *hProxy = (IMO2SPROXY_INST*)hInst;
+ WNDCLASS WndClass ={0};
+
+ // Start Skype connection
+ if (hProxy->pCfg->bVerbose && hProxy->pCfg->fpLog)
+ fprintf (hProxy->pCfg->fpLog, "W32SkypeEmu:Open(Start)\n");
+ if ((!m_ControlAPIAttach && !(m_ControlAPIAttach=RegisterWindowMessage("SkypeControlAPIAttach"))) ||
+ (!m_ControlAPIDiscover && !(m_ControlAPIDiscover=RegisterWindowMessage("SkypeControlAPIDiscover"))))
+ {
+ hProxy->pCfg->logerror (stderr, "Cannot register Window messages!");
+ return -1;
+ }
+
+ // Create window class
+ WndClass.style = CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS;
+ WndClass.lpfnWndProc = (WNDPROC)WndProc;
+ WndClass.hInstance = GetModuleHandle(NULL);
+ WndClass.lpszClassName = "Imo2SProxyDispatchWindow";
+ RegisterClass(&WndClass);
+
+ if (!(hProxy->hWndDispatch=CreateWindowEx( WS_EX_APPWINDOW|WS_EX_WINDOWEDGE,
+ WndClass.lpszClassName, "", WS_BORDER|WS_SYSMENU|WS_MINIMIZEBOX,
+ CW_USEDEFAULT, CW_USEDEFAULT, 128, 128, NULL, 0, (HINSTANCE)WndClass.hInstance, (LPVOID)hProxy)))
+ {
+ hProxy->pCfg->logerror (stderr, "Unable to create dispatch window!");
+ UnregisterClass (WndClass.lpszClassName, WndClass.hInstance);
+ return -1;
+ }
+
+ hProxy->hClients = List_Init(32);
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+
+static void Imo2sproxy_Loop(IMO2SPROXY *hInst)
+{
+ IMO2SPROXY_INST *hProxy = (IMO2SPROXY_INST*)hInst;
+ MSG Message;
+
+ if (hProxy->pCfg->bVerbose && hProxy->pCfg->fpLog)
+ fprintf (hProxy->pCfg->fpLog, "W32SkypeEmu:Loop(Start)\n");
+
+ // Pump da messages
+ hProxy->dwThreadID = GetCurrentThreadId();
+ LockMutex(hProxy->loopmutex);
+ while (GetMessage(&Message, NULL, 0, 0))
+ {
+ TranslateMessage(&Message);
+ DispatchMessage(&Message);
+ }
+
+ if (hProxy->pCfg->bVerbose && hProxy->pCfg->fpLog)
+ fprintf (hProxy->pCfg->fpLog, "W32SkypeEmu:Loop(End)\n");
+ UnlockMutex(hProxy->loopmutex);
+}
+
+
+// -----------------------------------------------------------------------------
+
+static void Imo2sproxy_Exit(IMO2SPROXY *hInst)
+{
+ IMO2SPROXY_INST *hProxy = (IMO2SPROXY_INST*)hInst;
+ CONNINST *pInst;
+
+ if (hProxy->pCfg->bVerbose && hProxy->pCfg->fpLog)
+ fprintf (hProxy->pCfg->fpLog, "W32SkypeEmu:Exit()\n");
+
+ if (hProxy->hWndDispatch) DestroyWindow (hProxy->hWndDispatch);
+ if (hProxy->dwThreadID) PostThreadMessage (hProxy->dwThreadID, WM_QUIT, 0, 0);
+ LockMutex(hProxy->loopmutex);
+
+ // Kill 'em all!
+ if (hProxy->hClients)
+ {
+ while (pInst=List_Pop(hProxy->hClients))
+ {
+ FreeConnection(pInst);
+ free (pInst);
+ }
+ List_Exit (hProxy->hClients);
+ }
+
+ UnregisterClass ("Imo2SProxyDispatchWindow", GetModuleHandle(NULL));
+
+ UnlockMutex(hProxy->loopmutex);
+ ExitMutex(hProxy->loopmutex);
+
+ free (hProxy);
+}
+
diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/w32skypeemu.h b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/w32skypeemu.h new file mode 100644 index 0000000000..a8291f3357 --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/w32skypeemu.h @@ -0,0 +1,6 @@ +typedef struct {
+ int bDelayLogin;
+} W32SKYPEEMU_CFG;
+
+void W32SkypeEmu_Defaults (W32SKYPEEMU_CFG *pMyCfg);
+IMO2SPROXY *W32SkypeEmu_Init (IMO2SPROXY_CFG *pCfg, W32SKYPEEMU_CFG *pMyCfg);
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(×tamp));
+ 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;
+}
diff --git a/plugins/!NotAdopted/IMO2sProxy/structure.txt b/plugins/!NotAdopted/IMO2sProxy/structure.txt new file mode 100644 index 0000000000..37de021e3a --- /dev/null +++ b/plugins/!NotAdopted/IMO2sProxy/structure.txt @@ -0,0 +1,102 @@ +The communication module is divided into multiple layers that
+are replacable or usable on their own.
+First let's start with a list of files and a short description:
+
++----------------+---+-------------------------------------------------------+
+| Module | T | Description |
++----------------+---+-------------------------------------------------------+
+| fifo.c | M | A simple fifo (First In, First Out) buffer |
+| memlist.c | M | A simple memory list module |
+| io_layer.c | M | Communication layer for HTTP requests |
+| io_layer_win32.| M | Communication layer WIN32 |
+| imo_request.c | M | Posts XMLHHTP-Requests to imo.im server |
+| cJSON.c | M | JSON parser in C (by Dave Gamble, slightly modified |
+| imo_skype.c | M | Communication layer for imo.im Skype |
+| skypetst.c | X | Testing application for Skype imo.im service |
+| queue.c | M | General Queue functions |
+| msgqueue.c | M | Message queue for incoming messages |
+| callqueue.c | M | Queue of incoming calls |
+| buddylist.c | M | Manages your list of buddies in memory |
+| imo2skypeapi.c | M | Wrapper for imo.im Webservice to SKYPE API |
+| imo2stest.c | X | Simple test application for imo2skypeapi |
+| imo2sproxy.c | M | Skypeproxy implementation to wrap imo2skypeapi |
+| w32browser.c | M | C COM Interface to Internet Explorer for call supp. |
+| main.c | X | Commandline interface for imo2sproxy module |
+| imoproxy.c | X | Miranda plugin implementation for imo2sproxy |
+| skypepluginlink| M | Communication layer with Miranda Skype Plugin 0.0.0.46|
+| socksproxy.c | M | Communication layer with socket protocol. |
+| w32skypeemu.c | M | Communication layer via Win32 Skype API emulation |
++----------------+---+-------------------------------------------------------+
+ [T]ype is: M...Module, X...Executable (Application)
+
+
+Now here is the module list with their dependencies divided into layers:
+
+====================================================================
+ IMO.IM Communication layer
+====================================================================
+
++------------------------------------------------------------------+
+| io_layer.c |
++------------------------------------------------------------------+
+| Communication layer for HTTP requests |
+| Depends on: fifo.c, Win32:WinInet, linux:libCURL |
++------------------------------------------------------------------+
+ ||
+ ||
+ \/
++------------------------------------------------------------------+
+| imo_request.c |
++------------------------------------------------------------------+
+| Communication module with imo.im |
+| Depends on: fifo.c, cJSON.c, io_layer.c |
++------------------------------------------------------------------+
+ ||
+ ||
+ \/
++------------------------------------------------------------------+
+| imo_skype.c |
++------------------------------------------------------------------+
+| Description: Skype protocol layer for imo.im |
+| Depends on: imo_request.c, cJSON.c |
+| Test application: skypetst.c |
++------------------------------------------------------------------+
+ ||
+====================================================================
+ imo.im <--> SkypeAPI wrapper
+====================================================================
+ ||
+ \/
++------------------------------------------------------------------+
+| imo2skypeapi.c |
++------------------------------------------------------------------+
+| Description: Mapper for imo.im to simple implementation of |
+| SkypeAPI |
+| Depends on: fifo.c, memlist.c, buddylist.c, msgqueue.c, |
+| imo_skype.c, (w32browser.c),(libpthread) |
+| Test application: imo2stest.c |
++------------------------------------------------------------------+
+ ||
+ ||
+ \/
++------------------------------------------------------------------+
+| imo2sproxy.c |
++------------------------------------------------------------------+
+| Description: Skypeproxy implementation to wrap imo2skypeapi|
+| for Miranda Plugin and potentially others |
+| Depends on: memlist.c, imo2skypeapi.c, (libpthread) |
++------------------------------------------------------------------+
+ || ||
+ || ||
+ \/ \/
++-----------------------------------------++-----------------------------------------+
+| main.c || imoproxy.c |
++-----------------------------------------++-----------------------------------------+
+| Description: Commandline dispatcher || Description: Miranda IM Plugin |
+| Depends on: memlist.c, imo2skypeapi.c, || Depends on: memlist.c, imo2skypeapi.c, |
+| imo2sproxy.c, (libpthread) || imo2sproxy.c, (libpthread) |
++-----------------------------------------++-----------------------------------------+
+ | | | + +-------------------+ | + | | | +Communication layer: socksproxy.c w32skypeemu.c skypepluginlink.c |