summaryrefslogtreecommitdiffstats
path: root/kopete/protocols
diff options
context:
space:
mode:
Diffstat (limited to 'kopete/protocols')
-rw-r--r--kopete/protocols/CMakeLists.txt22
-rw-r--r--kopete/protocols/gadu/CMakeLists.txt50
-rw-r--r--kopete/protocols/gadu/ConfigureChecks.cmake15
-rw-r--r--kopete/protocols/gadu/gadueditcontact.h1
-rw-r--r--kopete/protocols/gadu/icons/CMakeLists.txt12
-rw-r--r--kopete/protocols/gadu/libgadu/COPYING504
-rw-r--r--kopete/protocols/gadu/libgadu/Makefile.am12
-rw-r--r--kopete/protocols/gadu/libgadu/common.c827
-rw-r--r--kopete/protocols/gadu/libgadu/compat.h29
-rw-r--r--kopete/protocols/gadu/libgadu/dcc.c1298
-rw-r--r--kopete/protocols/gadu/libgadu/events.c1580
-rw-r--r--kopete/protocols/gadu/libgadu/http.c522
-rw-r--r--kopete/protocols/gadu/libgadu/libgadu-config.h.in30
-rw-r--r--kopete/protocols/gadu/libgadu/libgadu.c1818
-rw-r--r--kopete/protocols/gadu/libgadu/libgadu.h1310
-rw-r--r--kopete/protocols/gadu/libgadu/pubdir.c689
-rw-r--r--kopete/protocols/gadu/libgadu/pubdir50.c467
-rw-r--r--kopete/protocols/gadu/ui/CMakeLists.txt28
-rw-r--r--kopete/protocols/groupwise/CMakeLists.txt50
-rw-r--r--kopete/protocols/groupwise/icons/CMakeLists.txt12
-rw-r--r--kopete/protocols/groupwise/libgroupwise/CMakeLists.txt53
-rw-r--r--kopete/protocols/groupwise/libgroupwise/qca/CMakeLists.txt12
-rw-r--r--kopete/protocols/groupwise/libgroupwise/qca/src/CMakeLists.txt22
-rw-r--r--kopete/protocols/groupwise/libgroupwise/tasks/CMakeLists.txt38
-rw-r--r--kopete/protocols/groupwise/ui/CMakeLists.txt35
-rw-r--r--kopete/protocols/irc/CMakeLists.txt54
-rw-r--r--kopete/protocols/irc/icons/CMakeLists.txt12
-rw-r--r--kopete/protocols/irc/libkirc/CMakeLists.txt30
-rw-r--r--kopete/protocols/irc/libkirc/kircentity.h2
-rw-r--r--kopete/protocols/irc/ui/CMakeLists.txt30
-rw-r--r--kopete/protocols/jabber/CMakeLists.txt85
-rw-r--r--kopete/protocols/jabber/icons/CMakeLists.txt12
-rw-r--r--kopete/protocols/jabber/jingle/CMakeLists.txt38
-rw-r--r--kopete/protocols/jabber/jingle/jinglevoicecaller.cpp2
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/CMakeLists.txt12
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/CMakeLists.txt19
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/ConfigureChecks.cmake48
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/base/CMakeLists.txt32
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/base/asynctcpsocket.cc1
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/base/bytebuffer.cc1
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/base/host.cc2
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/base/messagequeue.h1
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/base/physicalsocketserver.cc5
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/base/socketadapters.cc1
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/p2p/CMakeLists.txt13
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/p2p/base/CMakeLists.txt52
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/p2p/base/relayserver_main.cc1
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/p2p/base/stun.cc1
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/p2p/base/stunserver.cc1
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/p2p/base/stunserver_main.cc1
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/p2p/client/CMakeLists.txt30
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/session/CMakeLists.txt12
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/session/phone/CMakeLists.txt34
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/session/phone/linphonemediaengine.cc2
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/session/phone/phonesessionclient.cc2
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/third_party/CMakeLists.txt13
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/third_party/mediastreamer/CMakeLists.txt36
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/third_party/mediastreamer/msrtprecv.h2
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/third_party/mediastreamer/msrtpsend.c2
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/third_party/mediastreamer/msrtpsend.h2
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/CMakeLists.txt32
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/avprofile.c281
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/export.c25
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/export.h38
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/jitterctl.c141
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/jitterctl.h38
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/ortp-config.h9
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/ortp.c258
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/ortp.h54
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/payloadtype.c268
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/payloadtype.h136
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/port_fct.c183
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/port_fct.h48
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/posixtimer.c167
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtcp.c294
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtcp.h167
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtcpparse.c218
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtp.h90
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtpmod.c122
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtpmod.h31
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtpparse.c159
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtpport.h308
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtpsession.c1954
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtpsession.h287
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtpsignaltable.c98
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtpsignaltable.h47
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtptimer.c32
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtptimer.h52
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/scheduler.c235
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/scheduler.h70
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/sessionset.c187
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/sessionset.h102
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/str_utils.c297
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/str_utils.h118
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/telephonyevents.c338
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/telephonyevents.h98
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/utils.c44
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/utils.h43
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/xmllite/CMakeLists.txt28
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/xmpp/CMakeLists.txt29
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/xmpp/xmpppassword.h2
-rw-r--r--kopete/protocols/jabber/kioslave/CMakeLists.txt42
-rw-r--r--kopete/protocols/jabber/libiris/CMakeLists.txt14
-rw-r--r--kopete/protocols/jabber/libiris/cutestuff/CMakeLists.txt13
-rw-r--r--kopete/protocols/jabber/libiris/cutestuff/network/CMakeLists.txt27
-rw-r--r--kopete/protocols/jabber/libiris/cutestuff/util/CMakeLists.txt24
-rw-r--r--kopete/protocols/jabber/libiris/iris/CMakeLists.txt15
-rw-r--r--kopete/protocols/jabber/libiris/iris/include/CMakeLists.txt24
-rw-r--r--kopete/protocols/jabber/libiris/iris/jabber/CMakeLists.txt40
-rw-r--r--kopete/protocols/jabber/libiris/iris/xmpp-core/CMakeLists.txt38
-rw-r--r--kopete/protocols/jabber/libiris/iris/xmpp-im/CMakeLists.txt37
-rw-r--r--kopete/protocols/jabber/libiris/qca/CMakeLists.txt12
-rw-r--r--kopete/protocols/jabber/libiris/qca/src/CMakeLists.txt22
-rw-r--r--kopete/protocols/jabber/ui/CMakeLists.txt43
-rw-r--r--kopete/protocols/meanwhile/CMakeLists.txt47
-rw-r--r--kopete/protocols/meanwhile/ConfigureChecks.cmake15
-rw-r--r--kopete/protocols/meanwhile/icons/CMakeLists.txt12
-rw-r--r--kopete/protocols/meanwhile/ui/CMakeLists.txt27
-rw-r--r--kopete/protocols/msn/CMakeLists.txt71
-rw-r--r--kopete/protocols/msn/config/CMakeLists.txt38
-rw-r--r--kopete/protocols/msn/icons/CMakeLists.txt12
-rw-r--r--kopete/protocols/msn/ui/CMakeLists.txt29
-rw-r--r--kopete/protocols/msn/webcam/CMakeLists.txt28
-rw-r--r--kopete/protocols/msn/webcam/libmimic/CMakeLists.txt23
-rw-r--r--kopete/protocols/oscar/CMakeLists.txt42
-rw-r--r--kopete/protocols/oscar/aim/CMakeLists.txt47
-rw-r--r--kopete/protocols/oscar/aim/ui/CMakeLists.txt31
-rw-r--r--kopete/protocols/oscar/icons/CMakeLists.txt12
-rw-r--r--kopete/protocols/oscar/icq/CMakeLists.txt45
-rw-r--r--kopete/protocols/oscar/icq/ui/CMakeLists.txt34
-rw-r--r--kopete/protocols/oscar/liboscar/CMakeLists.txt46
-rw-r--r--kopete/protocols/sms/CMakeLists.txt48
-rw-r--r--kopete/protocols/sms/icons/CMakeLists.txt12
-rw-r--r--kopete/protocols/sms/services/CMakeLists.txt32
-rw-r--r--kopete/protocols/sms/services/ConfigureChecks.cmake30
-rw-r--r--kopete/protocols/sms/services/config.h.cmake1
-rw-r--r--kopete/protocols/sms/ui/CMakeLists.txt24
-rw-r--r--kopete/protocols/testbed/CMakeLists.txt44
-rw-r--r--kopete/protocols/testbed/icons/CMakeLists.txt12
-rw-r--r--kopete/protocols/testbed/testbedaccount.h2
-rw-r--r--kopete/protocols/testbed/ui/CMakeLists.txt25
-rw-r--r--kopete/protocols/winpopup/CMakeLists.txt51
-rw-r--r--kopete/protocols/winpopup/icons/CMakeLists.txt12
-rw-r--r--kopete/protocols/winpopup/libwinpopup/CMakeLists.txt24
-rw-r--r--kopete/protocols/winpopup/ui/CMakeLists.txt25
-rw-r--r--kopete/protocols/yahoo/CMakeLists.txt49
-rw-r--r--kopete/protocols/yahoo/icons/CMakeLists.txt12
-rw-r--r--kopete/protocols/yahoo/libkyahoo/CMakeLists.txt48
-rw-r--r--kopete/protocols/yahoo/libkyahoo/ConfigureChecks.cmake16
-rw-r--r--kopete/protocols/yahoo/ui/CMakeLists.txt30
150 files changed, 9466 insertions, 9096 deletions
diff --git a/kopete/protocols/CMakeLists.txt b/kopete/protocols/CMakeLists.txt
new file mode 100644
index 00000000..14127078
--- /dev/null
+++ b/kopete/protocols/CMakeLists.txt
@@ -0,0 +1,22 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+tde_conditional_add_subdirectory( BUILD_KOPETE_PROTOCOL_TESTBED testbed )
+tde_conditional_add_subdirectory( BUILD_KOPETE_PROTOCOL_GROUPWISE groupwise )
+tde_conditional_add_subdirectory( BUILD_KOPETE_PROTOCOL_MSN msn )
+tde_conditional_add_subdirectory( BUILD_KOPETE_PROTOCOL_IRC irc )
+tde_conditional_add_subdirectory( BUILD_KOPETE_PROTOCOL_OSCAR oscar )
+tde_conditional_add_subdirectory( BUILD_KOPETE_PROTOCOL_YAHOO yahoo )
+tde_conditional_add_subdirectory( BUILD_KOPETE_PROTOCOL_WINPOPUP winpopup )
+tde_conditional_add_subdirectory( BUILD_KOPETE_PROTOCOL_SMS sms )
+tde_conditional_add_subdirectory( BUILD_KOPETE_PROTOCOL_JABBER jabber )
+tde_conditional_add_subdirectory( BUILD_KOPETE_PROTOCOL_GADU gadu )
+tde_conditional_add_subdirectory( BUILD_KOPETE_PROTOCOL_MEANWHILE meanwhile )
diff --git a/kopete/protocols/gadu/CMakeLists.txt b/kopete/protocols/gadu/CMakeLists.txt
new file mode 100644
index 00000000..bb5326d4
--- /dev/null
+++ b/kopete/protocols/gadu/CMakeLists.txt
@@ -0,0 +1,50 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+include( ConfigureChecks.cmake )
+
+add_subdirectory( ui )
+add_subdirectory( icons )
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR}/ui
+ ${CMAKE_BINARY_DIR}/kopete/libkopete/ui
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete/ui
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+ ${GADU_INCLUDE_DIRS}
+)
+
+link_directories(
+ ${TQT_LIBRARY_DIRS}
+)
+
+
+##### other data ################################
+
+install( FILES kopete_gadu.desktop DESTINATION ${SERVICES_INSTALL_DIR} )
+
+
+##### kopete_gadu (module) ######################
+
+tde_add_kpart( kopete_gadu AUTOMOC
+ SOURCES
+ gaduaway.cpp gadueditcontact.cpp gaducommands.cpp
+ gadueditaccount.cpp gadusession.cpp gaducontact.cpp
+ gaduaddcontactpage.cpp gaduprotocol.cpp gaduaccount.cpp
+ gadupubdir.cpp gaduregisteraccount.cpp gaducontactlist.cpp
+ gadurichtextformat.cpp gadudccserver.cpp gadudcctransaction.cpp
+ gadudcc.cpp
+ LINK gaduui-static kopete-shared ${GADU_LIBRARIES}
+ DESTINATION ${PLUGIN_INSTALL_DIR}
+)
diff --git a/kopete/protocols/gadu/ConfigureChecks.cmake b/kopete/protocols/gadu/ConfigureChecks.cmake
new file mode 100644
index 00000000..1511e879
--- /dev/null
+++ b/kopete/protocols/gadu/ConfigureChecks.cmake
@@ -0,0 +1,15 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+pkg_search_module( GADU libgadu )
+if( NOT GADU_FOUND )
+ tde_message_fatal( "libgadu is required, but was not found on your system" )
+endif( )
diff --git a/kopete/protocols/gadu/gadueditcontact.h b/kopete/protocols/gadu/gadueditcontact.h
index e9413a2b..f135d55a 100644
--- a/kopete/protocols/gadu/gadueditcontact.h
+++ b/kopete/protocols/gadu/gadueditcontact.h
@@ -31,7 +31,6 @@ class TQLabel;
class TQString;
class TQWidget;
class GaduContact;
-class GaduContactsList::ContactLine;
class TQListViewItem;
class GaduEditContact : public KDialogBase
diff --git a/kopete/protocols/gadu/icons/CMakeLists.txt b/kopete/protocols/gadu/icons/CMakeLists.txt
new file mode 100644
index 00000000..ba51467b
--- /dev/null
+++ b/kopete/protocols/gadu/icons/CMakeLists.txt
@@ -0,0 +1,12 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+tde_install_icons( DESTINATION ${DATA_INSTALL_DIR}/kopete/icons )
diff --git a/kopete/protocols/gadu/libgadu/COPYING b/kopete/protocols/gadu/libgadu/COPYING
deleted file mode 100644
index 071eee49..00000000
--- a/kopete/protocols/gadu/libgadu/COPYING
+++ /dev/null
@@ -1,504 +0,0 @@
- GNU LESSER GENERAL PUBLIC LICENSE
- Version 2.1, February 1999
-
- Copyright (C) 1991, 1999 Free Software Foundation, Inc.
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-[This is the first released version of the Lesser GPL. It also counts
- as the successor of the GNU Library Public License, version 2, hence
- the version number 2.1.]
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software--to make sure the software is free for all its users.
-
- This license, the Lesser General Public License, applies to some
-specially designated software packages--typically libraries--of the
-Free Software Foundation and other authors who decide to use it. You
-can use it too, but we suggest you first think carefully about whether
-this license or the ordinary General Public License is the better
-strategy to use in any particular case, based on the explanations below.
-
- When we speak of free software, we are referring to freedom of use,
-not price. Our General Public Licenses are designed to make sure that
-you have the freedom to distribute copies of free software (and charge
-for this service if you wish); that you receive source code or can get
-it if you want it; that you can change the software and use pieces of
-it in new free programs; and that you are informed that you can do
-these things.
-
- To protect your rights, we need to make restrictions that forbid
-distributors to deny you these rights or to ask you to surrender these
-rights. These restrictions translate to certain responsibilities for
-you if you distribute copies of the library or if you modify it.
-
- For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you. You must make sure that they, too, receive or can get the source
-code. If you link other code with the library, you must provide
-complete object files to the recipients, so that they can relink them
-with the library after making changes to the library and recompiling
-it. And you must show them these terms so they know their rights.
-
- We protect your rights with a two-step method: (1) we copyright the
-library, and (2) we offer you this license, which gives you legal
-permission to copy, distribute and/or modify the library.
-
- To protect each distributor, we want to make it very clear that
-there is no warranty for the free library. Also, if the library is
-modified by someone else and passed on, the recipients should know
-that what they have is not the original version, so that the original
-author's reputation will not be affected by problems that might be
-introduced by others.
-
- Finally, software patents pose a constant threat to the existence of
-any free program. We wish to make sure that a company cannot
-effectively restrict the users of a free program by obtaining a
-restrictive license from a patent holder. Therefore, we insist that
-any patent license obtained for a version of the library must be
-consistent with the full freedom of use specified in this license.
-
- Most GNU software, including some libraries, is covered by the
-ordinary GNU General Public License. This license, the GNU Lesser
-General Public License, applies to certain designated libraries, and
-is quite different from the ordinary General Public License. We use
-this license for certain libraries in order to permit linking those
-libraries into non-free programs.
-
- When a program is linked with a library, whether statically or using
-a shared library, the combination of the two is legally speaking a
-combined work, a derivative of the original library. The ordinary
-General Public License therefore permits such linking only if the
-entire combination fits its criteria of freedom. The Lesser General
-Public License permits more lax criteria for linking other code with
-the library.
-
- We call this license the "Lesser" General Public License because it
-does Less to protect the user's freedom than the ordinary General
-Public License. It also provides other free software developers Less
-of an advantage over competing non-free programs. These disadvantages
-are the reason we use the ordinary General Public License for many
-libraries. However, the Lesser license provides advantages in certain
-special circumstances.
-
- For example, on rare occasions, there may be a special need to
-encourage the widest possible use of a certain library, so that it becomes
-a de-facto standard. To achieve this, non-free programs must be
-allowed to use the library. A more frequent case is that a free
-library does the same job as widely used non-free libraries. In this
-case, there is little to gain by limiting the free library to free
-software only, so we use the Lesser General Public License.
-
- In other cases, permission to use a particular library in non-free
-programs enables a greater number of people to use a large body of
-free software. For example, permission to use the GNU C Library in
-non-free programs enables many more people to use the whole GNU
-operating system, as well as its variant, the GNU/Linux operating
-system.
-
- Although the Lesser General Public License is Less protective of the
-users' freedom, it does ensure that the user of a program that is
-linked with the Library has the freedom and the wherewithal to run
-that program using a modified version of the Library.
-
- The precise terms and conditions for copying, distribution and
-modification follow. Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library". The
-former contains code derived from the library, whereas the latter must
-be combined with the library in order to run.
-
- GNU LESSER GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License Agreement applies to any software library or other
-program which contains a notice placed by the copyright holder or
-other authorized party saying it may be distributed under the terms of
-this Lesser General Public License (also called "this License").
-Each licensee is addressed as "you".
-
- A "library" means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
- The "Library", below, refers to any such software library or work
-which has been distributed under these terms. A "work based on the
-Library" means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language. (Hereinafter, translation is
-included without limitation in the term "modification".)
-
- "Source code" for a work means the preferred form of the work for
-making modifications to it. For a library, complete source code means
-all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control compilation
-and installation of the library.
-
- Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it). Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-
- 1. You may copy and distribute verbatim copies of the Library's
-complete source code as you receive it, in any medium, provided that
-you conspicuously and appropriately publish on each copy an
-appropriate copyright notice and disclaimer of warranty; keep intact
-all the notices that refer to this License and to the absence of any
-warranty; and distribute a copy of this License along with the
-Library.
-
- You may charge a fee for the physical act of transferring a copy,
-and you may at your option offer warranty protection in exchange for a
-fee.
-
- 2. You may modify your copy or copies of the Library or any portion
-of it, thus forming a work based on the Library, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) The modified work must itself be a software library.
-
- b) You must cause the files modified to carry prominent notices
- stating that you changed the files and the date of any change.
-
- c) You must cause the whole of the work to be licensed at no
- charge to all third parties under the terms of this License.
-
- d) If a facility in the modified Library refers to a function or a
- table of data to be supplied by an application program that uses
- the facility, other than as an argument passed when the facility
- is invoked, then you must make a good faith effort to ensure that,
- in the event an application does not supply such function or
- table, the facility still operates, and performs whatever part of
- its purpose remains meaningful.
-
- (For example, a function in a library to compute square roots has
- a purpose that is entirely well-defined independent of the
- application. Therefore, Subsection 2d requires that any
- application-supplied function or table used by this function must
- be optional: if the application does not supply it, the square
- root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Library,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Library, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote
-it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library. To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License. (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.) Do not make any other change in
-these notices.
-
- Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
- This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
- 4. You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you accompany
-it with the complete corresponding machine-readable source code, which
-must be distributed under the terms of Sections 1 and 2 above on a
-medium customarily used for software interchange.
-
- If distribution of object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the
-source code from the same place satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 5. A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a "work that uses the Library". Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
- However, linking a "work that uses the Library" with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a "work that uses the
-library". The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
- When a "work that uses the Library" uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library. The
-threshold for this to be true is not precisely defined by law.
-
- If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work. (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
- Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-
- 6. As an exception to the Sections above, you may also combine or
-link a "work that uses the Library" with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer's own use and reverse
-engineering for debugging such modifications.
-
- You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License. You must supply a copy of this License. If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License. Also, you must do one
-of these things:
-
- a) Accompany the work with the complete corresponding
- machine-readable source code for the Library including whatever
- changes were used in the work (which must be distributed under
- Sections 1 and 2 above); and, if the work is an executable linked
- with the Library, with the complete machine-readable "work that
- uses the Library", as object code and/or source code, so that the
- user can modify the Library and then relink to produce a modified
- executable containing the modified Library. (It is understood
- that the user who changes the contents of definitions files in the
- Library will not necessarily be able to recompile the application
- to use the modified definitions.)
-
- b) Use a suitable shared library mechanism for linking with the
- Library. A suitable mechanism is one that (1) uses at run time a
- copy of the library already present on the user's computer system,
- rather than copying library functions into the executable, and (2)
- will operate properly with a modified version of the library, if
- the user installs one, as long as the modified version is
- interface-compatible with the version that the work was made with.
-
- c) Accompany the work with a written offer, valid for at
- least three years, to give the same user the materials
- specified in Subsection 6a, above, for a charge no more
- than the cost of performing this distribution.
-
- d) If distribution of the work is made by offering access to copy
- from a designated place, offer equivalent access to copy the above
- specified materials from the same place.
-
- e) Verify that the user has already received a copy of these
- materials or that you have already sent this user a copy.
-
- For an executable, the required form of the "work that uses the
-Library" must include any data and utility programs needed for
-reproducing the executable from it. However, as a special exception,
-the materials to be distributed need not include anything that is
-normally distributed (in either source or binary form) with the major
-components (compiler, kernel, and so on) of the operating system on
-which the executable runs, unless that component itself accompanies
-the executable.
-
- It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system. Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-
- 7. You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
- a) Accompany the combined library with a copy of the same work
- based on the Library, uncombined with any other library
- facilities. This must be distributed under the terms of the
- Sections above.
-
- b) Give prominent notice with the combined library of the fact
- that part of it is a work based on the Library, and explaining
- where to find the accompanying uncombined form of the same work.
-
- 8. You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License. Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library is void, and will automatically terminate your
-rights under this License. However, parties who have received copies,
-or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
- 9. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Library or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
- 10. Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-subject to these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties with
-this License.
-
- 11. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Library at all. For example, if a patent
-license would not permit royalty-free redistribution of the Library by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Library.
-
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply,
-and the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 12. If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library under this License may add
-an explicit geographical distribution limitation excluding those countries,
-so that distribution is permitted only in or among countries not thus
-excluded. In such case, this License incorporates the limitation as if
-written in the body of this License.
-
- 13. The Free Software Foundation may publish revised and/or new
-versions of the Lesser General Public License from time to time.
-Such new versions will be similar in spirit to the present version,
-but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Library
-specifies a version number of this License which applies to it and
-"any later version", you have the option of following the terms and
-conditions either of that version or of any later version published by
-the Free Software Foundation. If the Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-
- 14. If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-write to the author to ask for permission. For software which is
-copyrighted by the Free Software Foundation, write to the Free
-Software Foundation; we sometimes make exceptions for this. Our
-decision will be guided by the two goals of preserving the free status
-of all derivatives of our free software and of promoting the sharing
-and reuse of software generally.
-
- NO WARRANTY
-
- 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Libraries
-
- If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change. You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms of the
-ordinary General Public License).
-
- To apply these terms, attach the following notices to the library. It is
-safest to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least the
-"copyright" line and a pointer to where the full notice is found.
-
- <one line to give the library's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-Also add information on how to contact you by electronic and paper mail.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the library, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the
- library `Frob' (a library for tweaking knobs) written by James Random Hacker.
-
- <signature of Ty Coon>, 1 April 1990
- Ty Coon, President of Vice
-
-That's all there is to it!
-
-
diff --git a/kopete/protocols/gadu/libgadu/Makefile.am b/kopete/protocols/gadu/libgadu/Makefile.am
deleted file mode 100644
index 94693d38..00000000
--- a/kopete/protocols/gadu/libgadu/Makefile.am
+++ /dev/null
@@ -1,12 +0,0 @@
-METASOURCES = AUTO
-noinst_LTLIBRARIES = libgadu_copy.la
-INCLUDES = $(SSL_INCLUDES) $(all_includes)
-libgadu_copy_la_LDFLAGS = $(SSL_LDFLAGS) $(all_libraries)
-libgadu_copy_la_LIBADD = $(LIBSSL) $(LIBPTHREAD)
-libgadu_copy_la_SOURCES = common.c \
- dcc.c \
- events.c \
- http.c \
- libgadu.c \
- pubdir50.c \
- pubdir.c
diff --git a/kopete/protocols/gadu/libgadu/common.c b/kopete/protocols/gadu/libgadu/common.c
deleted file mode 100644
index 9e20422a..00000000
--- a/kopete/protocols/gadu/libgadu/common.c
+++ /dev/null
@@ -1,827 +0,0 @@
-/* $Id$ */
-
-/*
- * (C) Copyright 2001-2002 Wojtek Kaniewski <wojtekka@irc.pl>
- * Robert J. Wo�ny <speedy@ziew.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License Version
- * 2.1 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
- * USA.
- */
-
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#ifdef sun
-# include <sys/filio.h>
-#endif
-
-#include <errno.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "libgadu.h"
-
-FILE *gg_debug_file = NULL;
-
-#ifndef GG_DEBUG_DISABLE
-
-/*
- * gg_debug() // funkcja wewn�trzna
- *
- * wy�wietla komunikat o danym poziomie, o ile u�ytkownik sobie tego �yczy.
- *
- * - level - poziom wiadomo�ci
- * - format... - tre�� wiadomo�ci (kompatybilna z printf())
- */
-void gg_debug(int level, const char *format, ...)
-{
- va_list ap;
- int old_errno = errno;
-
- if (gg_debug_handler) {
- va_start(ap, format);
- (*gg_debug_handler)(level, format, ap);
- va_end(ap);
-
- goto cleanup;
- }
-
- if ((gg_debug_level & level)) {
- va_start(ap, format);
- vfprintf((gg_debug_file) ? gg_debug_file : stderr, format, ap);
- va_end(ap);
- }
-
-cleanup:
- errno = old_errno;
-}
-
-#endif
-
-/*
- * gg_vsaprintf() // funkcja pomocnicza
- *
- * robi dok�adnie to samo, co vsprintf(), tyle �e alokuje sobie wcze�niej
- * miejsce na dane. powinno dzia�a� na tych maszynach, kt�re maj� funkcj�
- * vsnprintf() zgodn� z C99, jak i na wcze�niejszych.
- *
- * - format - opis wy�wietlanego tekstu jak dla printf()
- * - ap - lista argument�w dla printf()
- *
- * zaalokowany bufor, kt�ry nale�y p��niej zwolni�, lub NULL
- * je�li nie uda�o si� wykona� zadania.
- */
-char *gg_vsaprintf(const char *format, va_list ap)
-{
- int size = 0;
- const char *start;
- char *buf = NULL;
-
-#ifdef __GG_LIBGADU_HAVE_VA_COPY
- va_list aq;
-
- va_copy(aq, ap);
-#else
-# ifdef __GG_LIBGADU_HAVE___VA_COPY
- va_list aq;
-
- __va_copy(aq, ap);
-# endif
-#endif
-
- start = format;
-
-#ifndef __GG_LIBGADU_HAVE_C99_VSNPRINTF
- {
- int res;
- char *tmp;
-
- size = 128;
- do {
- size *= 2;
- if (!(tmp = realloc(buf, size))) {
- free(buf);
- return NULL;
- }
- buf = tmp;
- res = vsnprintf(buf, size, format, ap);
- } while (res == size - 1 || res == -1);
- }
-#else
- {
- char tmp[2];
-
- /* libce Solarisa przy buforze NULL zawsze zwracaj� -1, wi�c
- * musimy poda� co� istniej�cego jako cel printf()owania. */
- size = vsnprintf(tmp, sizeof(tmp), format, ap);
- if (!(buf = malloc(size + 1)))
- return NULL;
- }
-#endif
-
- format = start;
-
-#ifdef __GG_LIBGADU_HAVE_VA_COPY
- vsnprintf(buf, size + 1, format, aq);
- va_end(aq);
-#else
-# ifdef __GG_LIBGADU_HAVE___VA_COPY
- vsnprintf(buf, size + 1, format, aq);
- va_end(aq);
-# else
- vsnprintf(buf, size + 1, format, ap);
-# endif
-#endif
-
- return buf;
-}
-
-/*
- * gg_saprintf() // funkcja pomocnicza
- *
- * robi dok�adnie to samo, co sprintf(), tyle �e alokuje sobie wcze�niej
- * miejsce na dane. powinno dzia�a� na tych maszynach, kt�re maj� funkcj�
- * vsnprintf() zgodn� z C99, jak i na wcze�niejszych.
- *
- * - format... - tre�� taka sama jak w funkcji printf()
- *
- * zaalokowany bufor, kt�ry nale�y p��niej zwolni�, lub NULL
- * je�li nie uda�o si� wykona� zadania.
- */
-char *gg_saprintf(const char *format, ...)
-{
- va_list ap;
- char *res;
-
- va_start(ap, format);
- res = gg_vsaprintf(format, ap);
- va_end(ap);
-
- return res;
-}
-
-/*
- * gg_get_line() // funkcja pomocnicza
- *
- * podaje kolejn� lini� z bufora tekstowego. niszczy go bezpowrotnie, dziel�c
- * na kolejne stringi. zdarza si�, nie ma potrzeby pisania funkcji dubluj�cej
- * bufor �eby tylko mie� nieruszone dane wej�ciowe, skoro i tak nie b�d� nam
- * po�niej potrzebne. obcina `\r\n'.
- *
- * - ptr - wska�nik do zmiennej, kt�ra przechowuje aktualn� pozycj�
- * w przemiatanym buforze
- *
- * wska�nik do kolejnej linii tekstu lub NULL, je�li to ju� koniec bufora.
- */
-char *gg_get_line(char **ptr)
-{
- const char *foo;
- char *res;
-
- if (!ptr || !*ptr || !strcmp(*ptr, ""))
- return NULL;
-
- res = *ptr;
-
- if (!(foo = strchr(*ptr, '\n')))
- *ptr += strlen(*ptr);
- else {
- *ptr = foo + 1;
- if (strlen(res) > 1 && res[strlen(res) - 1] == '\r')
- res[strlen(res) - 1] = 0;
- }
-
- return res;
-}
-
-/*
- * gg_connect() // funkcja pomocnicza
- *
- * ��czy si� z serwerem. pierwszy argument jest typu (void *), �eby nie
- * musie� niczego inkludowa� w libgadu.h i nie psu� jaki� g�upich zale�no�ci
- * na dziwnych systemach.
- *
- * - addr - adres serwera (struct in_addr *)
- * - port - port serwera
- * - async - asynchroniczne po��czenie
- *
- * deskryptor gniazda lub -1 w przypadku b��du (kod b��du w zmiennej errno).
- */
-int gg_connect(void *addr, int port, int async)
-{
- int sock, one = 1, errno2;
- struct sockaddr_in sin;
- struct in_addr *a = addr;
- struct sockaddr_in myaddr;
-
- gg_debug(GG_DEBUG_FUNCTION, "** gg_connect(%s, %d, %d);\n", inet_ntoa(*a), port, async);
-
- if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
- gg_debug(GG_DEBUG_MISC, "// gg_connect() socket() failed (errno=%d, %s)\n", errno, strerror(errno));
- return -1;
- }
-
- memset(&myaddr, 0, sizeof(myaddr));
- myaddr.sin_family = AF_INET;
-
- myaddr.sin_addr.s_addr = gg_local_ip;
-
- if (bind(sock, (struct sockaddr *) &myaddr, sizeof(myaddr)) == -1) {
- gg_debug(GG_DEBUG_MISC, "// gg_connect() bind() failed (errno=%d, %s)\n", errno, strerror(errno));
- return -1;
- }
-
-#ifdef ASSIGN_SOCKETS_TO_THREADS
- gg_win32_thread_socket(0, sock);
-#endif
-
- if (async) {
-#ifdef FIONBIO
- if (ioctl(sock, FIONBIO, &one) == -1) {
-#else
- if (fcntl(sock, F_SETFL, O_NONBLOCK) == -1) {
-#endif
- gg_debug(GG_DEBUG_MISC, "// gg_connect() ioctl() failed (errno=%d, %s)\n", errno, strerror(errno));
- errno2 = errno;
- close(sock);
- errno = errno2;
- return -1;
- }
- }
-
- sin.sin_port = htons(port);
- sin.sin_family = AF_INET;
- sin.sin_addr.s_addr = a->s_addr;
-
- if (connect(sock, (struct sockaddr*) &sin, sizeof(sin)) == -1) {
- if (errno && (!async || errno != EINPROGRESS)) {
- gg_debug(GG_DEBUG_MISC, "// gg_connect() connect() failed (errno=%d, %s)\n", errno, strerror(errno));
- errno2 = errno;
- close(sock);
- errno = errno2;
- return -1;
- }
- gg_debug(GG_DEBUG_MISC, "// gg_connect() connect() in progress\n");
- }
-
- return sock;
-}
-
-/*
- * gg_read_line() // funkcja pomocnicza
- *
- * czyta jedn� lini� tekstu z gniazda.
- *
- * - sock - deskryptor gniazda
- * - buf - wska�nik do bufora
- * - length - d�ugo�� bufora
- *
- * je�li trafi na b��d odczytu lub podano nieprawid�owe parametry, zwraca NULL.
- * inaczej zwraca buf.
- */
-char *gg_read_line(int sock, char *buf, int length)
-{
- int ret;
-
- if (!buf || length < 0)
- return NULL;
-
- for (; length > 1; buf++, length--) {
- do {
- if ((ret = read(sock, buf, 1)) == -1 && errno != EINTR) {
- gg_debug(GG_DEBUG_MISC, "// gg_read_line() error on read (errno=%d, %s)\n", errno, strerror(errno));
- *buf = 0;
- return NULL;
- } else if (ret == 0) {
- gg_debug(GG_DEBUG_MISC, "// gg_read_line() eof reached\n");
- *buf = 0;
- return NULL;
- }
- } while (ret == -1 && errno == EINTR);
-
- if (*buf == '\n') {
- buf++;
- break;
- }
- }
-
- *buf = 0;
- return buf;
-}
-
-/*
- * gg_chomp() // funkcja pomocnicza
- *
- * ucina "\r\n" lub "\n" z ko�ca linii.
- *
- * - line - linia do przyci�cia
- */
-void gg_chomp(char *line)
-{
- int len;
-
- if (!line)
- return;
-
- len = strlen(line);
-
- if (len > 0 && line[len - 1] == '\n')
- line[--len] = 0;
- if (len > 0 && line[len - 1] == '\r')
- line[--len] = 0;
-}
-
-/*
- * gg_urlencode() // funkcja wewn�trzna
- *
- * zamienia podany tekst na ci�g znak�w do formularza http. przydaje si�
- * przy r��nych us�ugach katalogu publicznego.
- *
- * - str - ci�g znak�w do zakodowania
- *
- * zaalokowany bufor, kt�ry nale�y p��niej zwolni� albo NULL
- * w przypadku b��du.
- */
-char *gg_urlencode(const char *str)
-{
- char *q, *buf, hex[] = "0123456789abcdef";
- const char *p;
- unsigned int size = 0;
-
- if (!str)
- str = "";
-
- for (p = str; *p; p++, size++) {
- if (!((*p >= 'a' && *p <= 'z') || (*p >= 'A' && *p <= 'Z') || (*p >= '0' && *p <= '9') || *p == ' ') || (*p == '@') || (*p == '.') || (*p == '-'))
- size += 2;
- }
-
- if (!(buf = malloc(size + 1)))
- return NULL;
-
- for (p = str, q = buf; *p; p++, q++) {
- if ((*p >= 'a' && *p <= 'z') || (*p >= 'A' && *p <= 'Z') || (*p >= '0' && *p <= '9') || (*p == '@') || (*p == '.') || (*p == '-'))
- *q = *p;
- else {
- if (*p == ' ')
- *q = '+';
- else {
- *q++ = '%';
- *q++ = hex[*p >> 4 & 15];
- *q = hex[*p & 15];
- }
- }
- }
-
- *q = 0;
-
- return buf;
-}
-
-/*
- * gg_http_hash() // funkcja wewn�trzna
- *
- * funkcja licz�ca hash dla adresu e-mail, has�a i paru innych.
- *
- * - format... - format kolejnych parametr�w ('s' je�li dany parametr jest
- * ci�giem znak�w lub 'u' je�li numerem GG)
- *
- * hash wykorzystywany przy rejestracji i wszelkich manipulacjach w�asnego
- * wpisu w katalogu publicznym.
- */
-int gg_http_hash(const char *format, ...)
-{
- unsigned int a, c, i, j;
- va_list ap;
- int b = -1;
-
- va_start(ap, format);
-
- for (j = 0; j < strlen(format); j++) {
- char *arg, buf[16];
-
- if (format[j] == 'u') {
- snprintf(buf, sizeof(buf), "%d", va_arg(ap, uin_t));
- arg = buf;
- } else {
- if (!(arg = va_arg(ap, char*)))
- arg = "";
- }
-
- i = 0;
- while ((c = (unsigned char) arg[i++]) != 0) {
- a = (c ^ b) + (c << 8);
- b = (a >> 24) | (a << 8);
- }
- }
-
- va_end(ap);
-
- return (b < 0 ? -b : b);
-}
-
-/*
- * gg_gethostbyname() // funkcja pomocnicza
- *
- * odpowiednik gethostbyname() troszcz�cy si� o wsp��bie�no��, gdy mamy do
- * dyspozycji funkcj� gethostbyname_r().
- *
- * - hostname - nazwa serwera
- *
- * zwraca wska�nik na struktur� in_addr, kt�r� nale�y zwolni�.
- */
-struct in_addr *gg_gethostbyname(const char *hostname)
-{
- struct in_addr *addr = NULL;
-
-#ifdef HAVE_GETHOSTBYNAME_R
- char *tmpbuf = NULL, *buf = NULL;
- struct hostent *hp = NULL, *hp2 = NULL;
- int h_errnop, ret;
- size_t buflen = 1024;
- int new_errno;
-
- new_errno = ENOMEM;
-
- if (!(addr = malloc(sizeof(struct in_addr))))
- goto cleanup;
-
- if (!(hp = calloc(1, sizeof(*hp))))
- goto cleanup;
-
- if (!(buf = malloc(buflen)))
- goto cleanup;
-
- tmpbuf = buf;
-
- while ((ret = gethostbyname_r(hostname, hp, buf, buflen, &hp2, &h_errnop)) == ERANGE) {
- buflen *= 2;
-
- if (!(tmpbuf = realloc(buf, buflen)))
- break;
-
- buf = tmpbuf;
- }
-
- if (ret)
- new_errno = h_errnop;
-
- if (ret || !hp2 || !tmpbuf)
- goto cleanup;
-
- memcpy(addr, hp->h_addr, sizeof(struct in_addr));
-
- free(buf);
- free(hp);
-
- return addr;
-
-cleanup:
- errno = new_errno;
-
- if (addr)
- free(addr);
- if (hp)
- free(hp);
- if (buf)
- free(buf);
-
- return NULL;
-#else
- struct hostent *hp;
-
- if (!(addr = malloc(sizeof(struct in_addr)))) {
- goto cleanup;
- }
-
- if (!(hp = gethostbyname(hostname)))
- goto cleanup;
-
- memcpy(addr, hp->h_addr, sizeof(struct in_addr));
-
- return addr;
-
-cleanup:
- if (addr)
- free(addr);
-
- return NULL;
-#endif
-}
-
-#ifdef ASSIGN_SOCKETS_TO_THREADS
-
-typedef struct gg_win32_thread {
- int id;
- int socket;
- struct gg_win32_thread *next;
-} gg_win32_thread;
-
-struct gg_win32_thread *gg_win32_threads = 0;
-
-/*
- * gg_win32_thread_socket() // funkcja pomocnicza, tylko dla win32
- *
- * zwraca deskryptor gniazda, kt�re by�o ostatnio tworzone dla w�tku
- * o podanym identyfikatorze.
- *
- * je�li na win32 przy po��czeniach synchronicznych zapami�tamy w jakim
- * w�tku uruchomili�my funkcj�, kt�ra si� z czymkolwiek ��czy, to z osobnego
- * w�tku mo�emy anulowa� po��czenie poprzez gg_win32_thread_socket(watek, -1);
- *
- * - thread_id - id w�tku. je�li jest r�wne 0, brany jest aktualny w�tek,
- * je�li r�wne -1, usuwa wpis o podanym sockecie.
- * - socket - deskryptor gniazda. je�li r�wne 0, zwraca deskryptor gniazda
- * dla podanego w�tku, je�li r�wne -1, usuwa wpis, je�li co�
- * innego, ustawia dla podanego w�tku dany numer deskryptora.
- *
- * je�li socket jest r�wne 0, zwraca deskryptor gniazda dla podanego w�tku.
- */
-int gg_win32_thread_socket(int thread_id, int socket)
-{
- char close = (thread_id == -1) || socket == -1;
- gg_win32_thread *wsk = gg_win32_threads;
- gg_win32_thread **p_wsk = &gg_win32_threads;
-
- if (!thread_id)
- thread_id = GetCurrentThreadId();
-
- while (wsk) {
- if ((thread_id == -1 && wsk->socket == socket) || wsk->id == thread_id) {
- if (close) {
- /* socket zostaje usuniety */
- closesocket(wsk->socket);
- *p_wsk = wsk->next;
- free(wsk);
- return 1;
- } else if (!socket) {
- /* socket zostaje zwrocony */
- return wsk->socket;
- } else {
- /* socket zostaje ustawiony */
- wsk->socket = socket;
- return socket;
- }
- }
- p_wsk = &(wsk->next);
- wsk = wsk->next;
- }
-
- if (close && socket != -1)
- closesocket(socket);
- if (close || !socket)
- return 0;
-
- /* Dodaje nowy element */
- wsk = malloc(sizeof(gg_win32_thread));
- wsk->id = thread_id;
- wsk->socket = socket;
- wsk->next = 0;
- *p_wsk = wsk;
-
- return socket;
-}
-
-#endif /* ASSIGN_SOCKETS_TO_THREADS */
-
-static char gg_base64_charset[] =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
-/*
- * gg_base64_encode()
- *
- * zapisuje ci�g znak�w w base64.
- *
- * - buf - ci�g znak�w.
- *
- * zaalokowany bufor.
- */
-char *gg_base64_encode(const char *buf)
-{
- char *out, *res;
- unsigned int i = 0, j = 0, k = 0, len = strlen(buf);
-
- res = out = malloc((len / 3 + 1) * 4 + 2);
-
- if (!res)
- return NULL;
-
- while (j <= len) {
- switch (i % 4) {
- case 0:
- k = (buf[j] & 252) >> 2;
- break;
- case 1:
- if (j < len)
- k = ((buf[j] & 3) << 4) | ((buf[j + 1] & 240) >> 4);
- else
- k = (buf[j] & 3) << 4;
-
- j++;
- break;
- case 2:
- if (j < len)
- k = ((buf[j] & 15) << 2) | ((buf[j + 1] & 192) >> 6);
- else
- k = (buf[j] & 15) << 2;
-
- j++;
- break;
- case 3:
- k = buf[j++] & 63;
- break;
- }
- *out++ = gg_base64_charset[k];
- i++;
- }
-
- if (i % 4)
- for (j = 0; j < 4 - (i % 4); j++, out++)
- *out = '=';
-
- *out = 0;
-
- return res;
-}
-
-/*
- * gg_base64_decode()
- *
- * dekoduje ci�g znak�w z base64.
- *
- * - buf - ci�g znak�w.
- *
- * zaalokowany bufor.
- */
-char *gg_base64_decode(const char *buf)
-{
- const char *foo2;
- char *res, *save, *foo, val;
- const char *end;
- unsigned int index = 0;
-
- if (!buf)
- return NULL;
-
- save = res = calloc(1, (strlen(buf) / 4 + 1) * 3 + 2);
-
- if (!save)
- return NULL;
-
- end = buf + strlen(buf);
-
- while (*buf && buf < end) {
- if (*buf == '\r' || *buf == '\n') {
- buf++;
- continue;
- }
- if (!(foo2 = strchr(gg_base64_charset, *buf))) {
- foo = gg_base64_charset;
- }
- else {
- foo = foo2;
- }
- val = (int)(foo - gg_base64_charset);
- buf++;
- switch (index) {
- case 0:
- *res |= val << 2;
- break;
- case 1:
- *res++ |= val >> 4;
- *res |= val << 4;
- break;
- case 2:
- *res++ |= val >> 2;
- *res |= val << 6;
- break;
- case 3:
- *res++ |= val;
- break;
- }
- index++;
- index %= 4;
- }
- *res = 0;
-
- return save;
-}
-
-/*
- * gg_proxy_auth() // funkcja wewn�trzna
- *
- * tworzy nag��wek autoryzacji dla proxy.
- *
- * zaalokowany tekst lub NULL, je�li proxy nie jest w��czone lub nie wymaga
- * autoryzacji.
- */
-char *gg_proxy_auth()
-{
- char *tmp, *enc, *out;
- unsigned int tmp_size;
-
- if (!gg_proxy_enabled || !gg_proxy_username || !gg_proxy_password)
- return NULL;
-
- if (!(tmp = malloc((tmp_size = strlen(gg_proxy_username) + strlen(gg_proxy_password) + 2))))
- return NULL;
-
- snprintf(tmp, tmp_size, "%s:%s", gg_proxy_username, gg_proxy_password);
-
- if (!(enc = gg_base64_encode(tmp))) {
- free(tmp);
- return NULL;
- }
-
- free(tmp);
-
- if (!(out = malloc(strlen(enc) + 40))) {
- free(enc);
- return NULL;
- }
-
- snprintf(out, strlen(enc) + 40, "Proxy-Authorization: Basic %s\r\n", enc);
-
- free(enc);
-
- return out;
-}
-
-static uint32_t gg_crc32_table[256];
-static int gg_crc32_initialized = 0;
-
-/*
- * gg_crc32_make_table() // funkcja wewn�trzna
- */
-static void gg_crc32_make_table()
-{
- uint32_t h = 1;
- unsigned int i, j;
-
- memset(gg_crc32_table, 0, sizeof(gg_crc32_table));
-
- for (i = 128; i; i >>= 1) {
- h = (h >> 1) ^ ((h & 1) ? 0xedb88320L : 0);
-
- for (j = 0; j < 256; j += 2 * i)
- gg_crc32_table[i + j] = gg_crc32_table[j] ^ h;
- }
-
- gg_crc32_initialized = 1;
-}
-
-/*
- * gg_crc32()
- *
- * wyznacza sum� kontroln� CRC32 danego bloku danych.
- *
- * - crc - suma kontrola poprzedniego bloku danych lub 0 je�li pierwszy
- * - buf - bufor danych
- * - size - ilo�� danych
- *
- * suma kontrolna CRC32.
- */
-uint32_t gg_crc32(uint32_t crc, const unsigned char *buf, int len)
-{
- if (!gg_crc32_initialized)
- gg_crc32_make_table();
-
- if (!buf || len < 0)
- return crc;
-
- crc ^= 0xffffffffL;
-
- while (len--)
- crc = (crc >> 8) ^ gg_crc32_table[(crc ^ *buf++) & 0xff];
-
- return crc ^ 0xffffffffL;
-}
-
-
-/*
- * Local variables:
- * c-indentation-style: k&r
- * c-basic-offset: 8
- * indent-tabs-mode: notnil
- * End:
- *
- * vim: shiftwidth=8:
- */
diff --git a/kopete/protocols/gadu/libgadu/compat.h b/kopete/protocols/gadu/libgadu/compat.h
deleted file mode 100644
index 8b9098fe..00000000
--- a/kopete/protocols/gadu/libgadu/compat.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* $Id$ */
-
-/*
- * (C) Copyright 2001-2002 Wojtek Kaniewski <wojtekka@irc.pl>
- * Robert J. Wo¼ny <speedy@ziew.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License Version
- * 2.1 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
- * USA.
- */
-
-#ifndef __COMPAT_H
-#define __COMPAT_H
-
-#ifdef sun
-# define INADDR_NONE ((in_addr_t) 0xffffffff)
-#endif
-
-#endif
diff --git a/kopete/protocols/gadu/libgadu/dcc.c b/kopete/protocols/gadu/libgadu/dcc.c
deleted file mode 100644
index d6b3c7cc..00000000
--- a/kopete/protocols/gadu/libgadu/dcc.c
+++ /dev/null
@@ -1,1298 +0,0 @@
-/* $Id$ */
-
-/*
- * (C) Copyright 2001-2006 Wojtek Kaniewski <wojtekka@irc.pl>
- * Tomasz Chiliñski <chilek@chilan.com>
- * Adam Wysocki <gophi@ekg.chmurka.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License Version
- * 2.1 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
- * USA.
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#ifdef sun
-# include <sys/filio.h>
-#endif
-
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdarg.h>
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "compat.h"
-#include "libgadu.h"
-
-#ifndef GG_DEBUG_DISABLE
-/*
- * gg_dcc_debug_data() // funkcja wewnêtrzna
- *
- * wy¶wietla zrzut pakietu w hexie.
- *
- * - prefix - prefiks zrzutu pakietu
- * - fd - deskryptor gniazda
- * - buf - bufor z danymi
- * - size - rozmiar danych
- */
-static void gg_dcc_debug_data(const char *prefix, int fd, const void *buf, unsigned int size)
-{
- unsigned int i;
-
- gg_debug(GG_DEBUG_MISC, "++ gg_dcc %s (fd=%d,len=%d)", prefix, fd, size);
-
- for (i = 0; i < size; i++)
- gg_debug(GG_DEBUG_MISC, " %.2x", ((unsigned char*) buf)[i]);
-
- gg_debug(GG_DEBUG_MISC, "\n");
-}
-#else
-#define gg_dcc_debug_data(a,b,c,d) do { } while (0)
-#endif
-
-/*
- * gg_dcc_request()
- *
- * wysy³a informacjê o tym, ¿e dany klient powinien siê z nami po³±czyæ.
- * wykorzystywane, kiedy druga strona, której chcemy co¶ wys³aæ jest za
- * maskarad±.
- *
- * - sess - struktura opisuj±ca sesjê GG
- * - uin - numerek odbiorcy
- *
- * patrz gg_send_message_ctcp().
- */
-int gg_dcc_request(struct gg_session *sess, uin_t uin)
-{
- return gg_send_message_ctcp(sess, GG_CLASS_CTCP, uin, "\002", 1);
-}
-
-/*
- * gg_dcc_fill_filetime() // funkcja wewnêtrzna
- *
- * zamienia czas w postaci unixowej na windowsowy.
- *
- * - unix - czas w postaci unixowej
- * - filetime - czas w postaci windowsowej
- */
-static void gg_dcc_fill_filetime(uint32_t ut, uint32_t *ft)
-{
-#ifdef __GG_LIBGADU_HAVE_LONG_LONG
- unsigned long long tmp;
-
- tmp = ut;
- tmp += 11644473600LL;
- tmp *= 10000000LL;
-
-#ifndef __GG_LIBGADU_BIGENDIAN
- ft[0] = (uint32_t) tmp;
- ft[1] = (uint32_t) (tmp >> 32);
-#else
- ft[0] = gg_fix32((uint32_t) (tmp >> 32));
- ft[1] = gg_fix32((uint32_t) tmp);
-#endif
-
-#endif
-}
-
-/*
- * gg_dcc_fill_file_info()
- *
- * wype³nia pola struct gg_dcc niezbêdne do wys³ania pliku.
- *
- * - d - struktura opisuj±ca po³±czenie DCC
- * - filename - nazwa pliku
- *
- * 0, -1.
- */
-int gg_dcc_fill_file_info(struct gg_dcc *d, const char *filename)
-{
- return gg_dcc_fill_file_info2(d, filename, filename);
-}
-
-/*
- * gg_dcc_fill_file_info2()
- *
- * wype³nia pola struct gg_dcc niezbêdne do wys³ania pliku.
- *
- * - d - struktura opisuj±ca po³±czenie DCC
- * - filename - nazwa pliku
- * - local_filename - nazwa na lokalnym systemie plików
- *
- * 0, -1.
- */
-int gg_dcc_fill_file_info2(struct gg_dcc *d, const char *filename, const char *local_filename)
-{
- struct stat st;
- const char *name, *ext, *p;
- unsigned char *q;
- int i, j;
-
- gg_debug(GG_DEBUG_FUNCTION, "** gg_dcc_fill_file_info2(%p, \"%s\", \"%s\");\n", d, filename, local_filename);
-
- if (!d || d->type != GG_SESSION_DCC_SEND) {
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_fill_file_info2() invalid arguments\n");
- errno = EINVAL;
- return -1;
- }
-
- if (stat(local_filename, &st) == -1) {
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_fill_file_info2() stat() failed (%s)\n", strerror(errno));
- return -1;
- }
-
- if ((st.st_mode & S_IFDIR)) {
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_fill_file_info2() that's a directory\n");
- errno = EINVAL;
- return -1;
- }
-
- if ((d->file_fd = open(local_filename, O_RDONLY)) == -1) {
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_fill_file_info2() open() failed (%s)\n", strerror(errno));
- return -1;
- }
-
- memset(&d->file_info, 0, sizeof(d->file_info));
-
- if (!(st.st_mode & S_IWUSR))
- d->file_info.mode |= gg_fix32(GG_DCC_FILEATTR_READONLY);
-
- gg_dcc_fill_filetime(st.st_atime, d->file_info.atime);
- gg_dcc_fill_filetime(st.st_mtime, d->file_info.mtime);
- gg_dcc_fill_filetime(st.st_ctime, d->file_info.ctime);
-
- d->file_info.size = gg_fix32(st.st_size);
- d->file_info.mode = gg_fix32(0x20); /* FILE_ATTRIBUTE_ARCHIVE */
-
- if (!(name = strrchr(filename, '/')))
- name = filename;
- else
- name++;
-
- if (!(ext = strrchr(name, '.')))
- ext = name + strlen(name);
-
- for (i = 0, p = name; i < 8 && p < ext; i++, p++)
- d->file_info.short_filename[i] = toupper(name[i]);
-
- if (i == 8 && p < ext) {
- d->file_info.short_filename[6] = '~';
- d->file_info.short_filename[7] = '1';
- }
-
- if (strlen(ext) > 0) {
- for (j = 0; *ext && j < 4; j++, p++)
- d->file_info.short_filename[i + j] = toupper(ext[j]);
- }
-
- for (q = d->file_info.short_filename; *q; q++) {
- if (*q == 185) {
- *q = 165;
- } else if (*q == 230) {
- *q = 198;
- } else if (*q == 234) {
- *q = 202;
- } else if (*q == 179) {
- *q = 163;
- } else if (*q == 241) {
- *q = 209;
- } else if (*q == 243) {
- *q = 211;
- } else if (*q == 156) {
- *q = 140;
- } else if (*q == 159) {
- *q = 143;
- } else if (*q == 191) {
- *q = 175;
- }
- }
-
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_fill_file_info2() short name \"%s\", dos name \"%s\"\n", name, d->file_info.short_filename);
- strncpy(d->file_info.filename, name, sizeof(d->file_info.filename) - 1);
-
- return 0;
-}
-
-/*
- * gg_dcc_transfer() // funkcja wewnêtrzna
- *
- * inicjuje proces wymiany pliku z danym klientem.
- *
- * - ip - adres ip odbiorcy
- * - port - port odbiorcy
- * - my_uin - w³asny numer
- * - peer_uin - numer obiorcy
- * - type - rodzaj wymiany (GG_SESSION_DCC_SEND lub GG_SESSION_DCC_GET)
- *
- * zaalokowana struct gg_dcc lub NULL je¶li wyst±pi³ b³±d.
- */
-static struct gg_dcc *gg_dcc_transfer(uint32_t ip, uint16_t port, uin_t my_uin, uin_t peer_uin, int type)
-{
- struct gg_dcc *d = NULL;
- struct in_addr addr;
-
- addr.s_addr = ip;
-
- gg_debug(GG_DEBUG_FUNCTION, "** gg_dcc_transfer(%s, %d, %ld, %ld, %s);\n", inet_ntoa(addr), port, my_uin, peer_uin, (type == GG_SESSION_DCC_SEND) ? "SEND" : "GET");
-
- if (!ip || ip == INADDR_NONE || !port || !my_uin || !peer_uin) {
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_transfer() invalid arguments\n");
- errno = EINVAL;
- return NULL;
- }
-
- if (!(d = (void*) calloc(1, sizeof(*d)))) {
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_transfer() not enough memory\n");
- return NULL;
- }
-
- d->check = GG_CHECK_WRITE;
- d->state = GG_STATE_CONNECTING;
- d->type = type;
- d->timeout = GG_DEFAULT_TIMEOUT;
- d->file_fd = -1;
- d->active = 1;
- d->fd = -1;
- d->uin = my_uin;
- d->peer_uin = peer_uin;
-
- if ((d->fd = gg_connect(&addr, port, 1)) == -1) {
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_transfer() connection failed\n");
- free(d);
- return NULL;
- }
-
- return d;
-}
-
-/*
- * gg_dcc_get_file()
- *
- * inicjuje proces odbierania pliku od danego klienta, gdy ten wys³a³ do
- * nas ¿±danie po³±czenia.
- *
- * - ip - adres ip odbiorcy
- * - port - port odbiorcy
- * - my_uin - w³asny numer
- * - peer_uin - numer obiorcy
- *
- * zaalokowana struct gg_dcc lub NULL je¶li wyst±pi³ b³±d.
- */
-struct gg_dcc *gg_dcc_get_file(uint32_t ip, uint16_t port, uin_t my_uin, uin_t peer_uin)
-{
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_get_file() handing over to gg_dcc_transfer()\n");
-
- return gg_dcc_transfer(ip, port, my_uin, peer_uin, GG_SESSION_DCC_GET);
-}
-
-/*
- * gg_dcc_send_file()
- *
- * inicjuje proces wysy³ania pliku do danego klienta.
- *
- * - ip - adres ip odbiorcy
- * - port - port odbiorcy
- * - my_uin - w³asny numer
- * - peer_uin - numer obiorcy
- *
- * zaalokowana struct gg_dcc lub NULL je¶li wyst±pi³ b³±d.
- */
-struct gg_dcc *gg_dcc_send_file(uint32_t ip, uint16_t port, uin_t my_uin, uin_t peer_uin)
-{
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_send_file() handing over to gg_dcc_transfer()\n");
-
- return gg_dcc_transfer(ip, port, my_uin, peer_uin, GG_SESSION_DCC_SEND);
-}
-
-/*
- * gg_dcc_voice_chat()
- *
- * próbuje nawi±zaæ po³±czenie g³osowe.
- *
- * - ip - adres ip odbiorcy
- * - port - port odbiorcy
- * - my_uin - w³asny numer
- * - peer_uin - numer obiorcy
- *
- * zaalokowana struct gg_dcc lub NULL je¶li wyst±pi³ b³±d.
- */
-struct gg_dcc *gg_dcc_voice_chat(uint32_t ip, uint16_t port, uin_t my_uin, uin_t peer_uin)
-{
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_voice_chat() handing over to gg_dcc_transfer()\n");
-
- return gg_dcc_transfer(ip, port, my_uin, peer_uin, GG_SESSION_DCC_VOICE);
-}
-
-/*
- * gg_dcc_set_type()
- *
- * po zdarzeniu GG_EVENT_DCC_CALLBACK nale¿y ustawiæ typ po³±czenia za
- * pomoc± tej funkcji.
- *
- * - d - struktura opisuj±ca po³±czenie
- * - type - typ po³±czenia (GG_SESSION_DCC_SEND lub GG_SESSION_DCC_VOICE)
- */
-void gg_dcc_set_type(struct gg_dcc *d, int type)
-{
- d->type = type;
- d->state = (type == GG_SESSION_DCC_SEND) ? GG_STATE_SENDING_FILE_INFO : GG_STATE_SENDING_VOICE_REQUEST;
-}
-
-/*
- * gg_dcc_callback() // funkcja wewnêtrzna
- *
- * wywo³ywana z struct gg_dcc->callback, odpala gg_dcc_watch_fd i umieszcza
- * rezultat w struct gg_dcc->event.
- *
- * - d - structura opisuj±ca po³±czenie
- *
- * 0, -1.
- */
-static int gg_dcc_callback(struct gg_dcc *d)
-{
- struct gg_event *e = gg_dcc_watch_fd(d);
-
- d->event = e;
-
- return (e != NULL) ? 0 : -1;
-}
-
-/*
- * gg_dcc_socket_create()
- *
- * tworzy gniazdo dla bezpo¶redniej komunikacji miêdzy klientami.
- *
- * - uin - w³asny numer
- * - port - preferowany port, je¶li równy 0 lub -1, próbuje domy¶lnego
- *
- * zaalokowana struct gg_dcc, któr± po¼niej nale¿y zwolniæ funkcj±
- * gg_dcc_free(), albo NULL je¶li wyst±pi³ b³±d.
- */
-struct gg_dcc *gg_dcc_socket_create(uin_t uin, uint16_t port)
-{
- struct gg_dcc *c;
- struct sockaddr_in sin;
- int sock, bound = 0, errno2;
-
- gg_debug(GG_DEBUG_FUNCTION, "** gg_create_dcc_socket(%d, %d);\n", uin, port);
-
- if (!uin) {
- gg_debug(GG_DEBUG_MISC, "// gg_create_dcc_socket() invalid arguments\n");
- errno = EINVAL;
- return NULL;
- }
-
- if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
- gg_debug(GG_DEBUG_MISC, "// gg_create_dcc_socket() can't create socket (%s)\n", strerror(errno));
- return NULL;
- }
-
- if (!port)
- port = GG_DEFAULT_DCC_PORT;
-
- while (!bound) {
- sin.sin_family = AF_INET;
- sin.sin_addr.s_addr = INADDR_ANY;
- sin.sin_port = htons(port);
-
- gg_debug(GG_DEBUG_MISC, "// gg_create_dcc_socket() trying port %d\n", port);
- if (!bind(sock, (struct sockaddr*) &sin, sizeof(sin)))
- bound = 1;
- else {
- if (++port == 65535) {
- gg_debug(GG_DEBUG_MISC, "// gg_create_dcc_socket() no free port found\n");
- close(sock);
- return NULL;
- }
- }
- }
-
- if (listen(sock, 10)) {
- gg_debug(GG_DEBUG_MISC, "// gg_create_dcc_socket() unable to listen (%s)\n", strerror(errno));
- errno2 = errno;
- close(sock);
- errno = errno2;
- return NULL;
- }
-
- gg_debug(GG_DEBUG_MISC, "// gg_create_dcc_socket() bound to port %d\n", port);
-
- if (!(c = malloc(sizeof(*c)))) {
- gg_debug(GG_DEBUG_MISC, "// gg_create_dcc_socket() not enough memory for struct\n");
- close(sock);
- return NULL;
- }
- memset(c, 0, sizeof(*c));
-
- c->port = c->id = port;
- c->fd = sock;
- c->type = GG_SESSION_DCC_SOCKET;
- c->uin = uin;
- c->timeout = -1;
- c->state = GG_STATE_LISTENING;
- c->check = GG_CHECK_READ;
- c->callback = gg_dcc_callback;
- c->destroy = gg_dcc_free;
-
- return c;
-}
-
-/*
- * gg_dcc_voice_send()
- *
- * wysy³a ramkê danych dla rozmowy g³osowej.
- *
- * - d - struktura opisuj±ca po³±czenie dcc
- * - buf - bufor z danymi
- * - length - rozmiar ramki
- *
- * 0, -1.
- */
-int gg_dcc_voice_send(struct gg_dcc *d, char *buf, int length)
-{
- struct packet_s {
- uint8_t type;
- uint32_t length;
- } GG_PACKED;
- struct packet_s packet;
-
- gg_debug(GG_DEBUG_FUNCTION, "++ gg_dcc_voice_send(%p, %p, %d);\n", d, buf, length);
- if (!d || !buf || length < 0 || d->type != GG_SESSION_DCC_VOICE) {
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_voice_send() invalid argument\n");
- errno = EINVAL;
- return -1;
- }
-
- packet.type = 0x03; /* XXX */
- packet.length = gg_fix32(length);
-
- if (write(d->fd, &packet, sizeof(packet)) < (signed)sizeof(packet)) {
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_voice_send() write() failed\n");
- return -1;
- }
- gg_dcc_debug_data("write", d->fd, &packet, sizeof(packet));
-
- if (write(d->fd, buf, length) < length) {
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_voice_send() write() failed\n");
- return -1;
- }
- gg_dcc_debug_data("write", d->fd, buf, length);
-
- return 0;
-}
-
-#define gg_read(fd, buf, size) \
-{ \
- int tmp = read(fd, buf, size); \
- \
- if (tmp < (int) size) { \
- if (tmp == -1) { \
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() read() failed (errno=%d, %s)\n", errno, strerror(errno)); \
- } else if (tmp == 0) { \
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() read() failed, connection broken\n"); \
- } else { \
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() read() failed (%d bytes, %d needed)\n", tmp, size); \
- } \
- e->type = GG_EVENT_DCC_ERROR; \
- e->event.dcc_error = GG_ERROR_DCC_HANDSHAKE; \
- return e; \
- } \
- gg_dcc_debug_data("read", fd, buf, size); \
-}
-
-#define gg_write(fd, buf, size) \
-{ \
- int tmp; \
- gg_dcc_debug_data("write", fd, buf, size); \
- tmp = write(fd, buf, size); \
- if (tmp < (int) size) { \
- if (tmp == -1) { \
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() write() failed (errno=%d, %s)\n", errno, strerror(errno)); \
- } else { \
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() write() failed (%d needed, %d done)\n", size, tmp); \
- } \
- e->type = GG_EVENT_DCC_ERROR; \
- e->event.dcc_error = GG_ERROR_DCC_HANDSHAKE; \
- return e; \
- } \
-}
-
-/*
- * gg_dcc_watch_fd()
- *
- * funkcja, któr± nale¿y wywo³aæ, gdy co¶ siê zmieni na gg_dcc->fd.
- *
- * - h - struktura zwrócona przez gg_create_dcc_socket()
- *
- * zaalokowana struct gg_event lub NULL, je¶li zabrak³o pamiêci na ni±.
- */
-struct gg_event *gg_dcc_watch_fd(struct gg_dcc *h)
-{
- struct gg_event *e;
- int foo;
-
- gg_debug(GG_DEBUG_FUNCTION, "** gg_dcc_watch_fd(%p);\n", h);
-
- if (!h || (h->type != GG_SESSION_DCC && h->type != GG_SESSION_DCC_SOCKET && h->type != GG_SESSION_DCC_SEND && h->type != GG_SESSION_DCC_GET && h->type != GG_SESSION_DCC_VOICE)) {
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() invalid argument\n");
- errno = EINVAL;
- return NULL;
- }
-
- if (!(e = (void*) calloc(1, sizeof(*e)))) {
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() not enough memory\n");
- return NULL;
- }
-
- e->type = GG_EVENT_NONE;
-
- if (h->type == GG_SESSION_DCC_SOCKET) {
- struct sockaddr_in sin;
- struct gg_dcc *c;
- int fd, sin_len = sizeof(sin), one = 1;
-
- if ((fd = accept(h->fd, (struct sockaddr*) &sin, &sin_len)) == -1) {
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() can't accept() new connection (errno=%d, %s)\n", errno, strerror(errno));
- return e;
- }
-
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() new direct connection from %s:%d\n", inet_ntoa(sin.sin_addr), htons(sin.sin_port));
-
-#ifdef FIONBIO
- if (ioctl(fd, FIONBIO, &one) == -1) {
-#else
- if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) {
-#endif
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() can't set nonblocking (errno=%d, %s)\n", errno, strerror(errno));
- close(fd);
- e->type = GG_EVENT_DCC_ERROR;
- e->event.dcc_error = GG_ERROR_DCC_HANDSHAKE;
- return e;
- }
-
- if (!(c = (void*) calloc(1, sizeof(*c)))) {
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() not enough memory for client data\n");
-
- free(e);
- close(fd);
- return NULL;
- }
-
- c->fd = fd;
- c->check = GG_CHECK_READ;
- c->state = GG_STATE_READING_UIN_1;
- c->type = GG_SESSION_DCC;
- c->timeout = GG_DEFAULT_TIMEOUT;
- c->file_fd = -1;
- c->remote_addr = sin.sin_addr.s_addr;
- c->remote_port = ntohs(sin.sin_port);
-
- e->type = GG_EVENT_DCC_NEW;
- e->event.dcc_new = c;
-
- return e;
- } else {
- struct gg_dcc_tiny_packet tiny;
- struct gg_dcc_small_packet small;
- struct gg_dcc_big_packet big;
- int size, tmp, res, res_size = sizeof(res);
- unsigned int utmp;
- char buf[1024], ack[] = "UDAG";
-
- struct gg_dcc_file_info_packet {
- struct gg_dcc_big_packet big;
- struct gg_file_info file_info;
- } GG_PACKED;
- struct gg_dcc_file_info_packet file_info_packet;
-
- switch (h->state) {
- case GG_STATE_READING_UIN_1:
- case GG_STATE_READING_UIN_2:
- {
- uin_t uin;
-
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() GG_READING_UIN_%d\n", (h->state == GG_STATE_READING_UIN_1) ? 1 : 2);
-
- gg_read(h->fd, &uin, sizeof(uin));
-
- if (h->state == GG_STATE_READING_UIN_1) {
- h->state = GG_STATE_READING_UIN_2;
- h->check = GG_CHECK_READ;
- h->timeout = GG_DEFAULT_TIMEOUT;
- h->peer_uin = gg_fix32(uin);
- } else {
- h->state = GG_STATE_SENDING_ACK;
- h->check = GG_CHECK_WRITE;
- h->timeout = GG_DEFAULT_TIMEOUT;
- h->uin = gg_fix32(uin);
- e->type = GG_EVENT_DCC_CLIENT_ACCEPT;
- }
-
- return e;
- }
-
- case GG_STATE_SENDING_ACK:
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() GG_SENDING_ACK\n");
-
- gg_write(h->fd, ack, 4);
-
- h->state = GG_STATE_READING_TYPE;
- h->check = GG_CHECK_READ;
- h->timeout = GG_DEFAULT_TIMEOUT;
-
- return e;
-
- case GG_STATE_READING_TYPE:
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() GG_STATE_READING_TYPE\n");
-
- gg_read(h->fd, &small, sizeof(small));
-
- small.type = gg_fix32(small.type);
-
- switch (small.type) {
- case 0x0003: /* XXX */
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() callback\n");
- h->type = GG_SESSION_DCC_SEND;
- h->state = GG_STATE_SENDING_FILE_INFO;
- h->check = GG_CHECK_WRITE;
- h->timeout = GG_DEFAULT_TIMEOUT;
-
- e->type = GG_EVENT_DCC_CALLBACK;
-
- break;
-
- case 0x0002: /* XXX */
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() dialin\n");
- h->type = GG_SESSION_DCC_GET;
- h->state = GG_STATE_READING_REQUEST;
- h->check = GG_CHECK_READ;
- h->timeout = GG_DEFAULT_TIMEOUT;
- h->incoming = 1;
-
- break;
-
- default:
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() unknown dcc type (%.4x) from %ld\n", small.type, h->peer_uin);
- e->type = GG_EVENT_DCC_ERROR;
- e->event.dcc_error = GG_ERROR_DCC_HANDSHAKE;
- }
-
- return e;
-
- case GG_STATE_READING_REQUEST:
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() GG_STATE_READING_REQUEST\n");
-
- gg_read(h->fd, &small, sizeof(small));
-
- small.type = gg_fix32(small.type);
-
- switch (small.type) {
- case 0x0001: /* XXX */
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() file transfer request\n");
- h->state = GG_STATE_READING_FILE_INFO;
- h->check = GG_CHECK_READ;
- h->timeout = GG_DEFAULT_TIMEOUT;
- break;
-
- case 0x0003: /* XXX */
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() voice chat request\n");
- h->state = GG_STATE_SENDING_VOICE_ACK;
- h->check = GG_CHECK_WRITE;
- h->timeout = GG_DCC_TIMEOUT_VOICE_ACK;
- h->type = GG_SESSION_DCC_VOICE;
- e->type = GG_EVENT_DCC_NEED_VOICE_ACK;
-
- break;
-
- default:
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() unknown dcc request (%.4x) from %ld\n", small.type, h->peer_uin);
- e->type = GG_EVENT_DCC_ERROR;
- e->event.dcc_error = GG_ERROR_DCC_HANDSHAKE;
- }
-
- return e;
-
- case GG_STATE_READING_FILE_INFO:
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() GG_STATE_READING_FILE_INFO\n");
-
- gg_read(h->fd, &file_info_packet, sizeof(file_info_packet));
-
- memcpy(&h->file_info, &file_info_packet.file_info, sizeof(h->file_info));
-
- h->file_info.mode = gg_fix32(h->file_info.mode);
- h->file_info.size = gg_fix32(h->file_info.size);
-
- h->state = GG_STATE_SENDING_FILE_ACK;
- h->check = GG_CHECK_WRITE;
- h->timeout = GG_DCC_TIMEOUT_FILE_ACK;
-
- e->type = GG_EVENT_DCC_NEED_FILE_ACK;
-
- return e;
-
- case GG_STATE_SENDING_FILE_ACK:
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() GG_STATE_SENDING_FILE_ACK\n");
-
- big.type = gg_fix32(0x0006); /* XXX */
- big.dunno1 = gg_fix32(h->offset);
- big.dunno2 = 0;
-
- gg_write(h->fd, &big, sizeof(big));
-
- h->state = GG_STATE_READING_FILE_HEADER;
- h->chunk_size = sizeof(big);
- h->chunk_offset = 0;
- if (!(h->chunk_buf = malloc(sizeof(big)))) {
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() out of memory\n");
- free(e);
- return NULL;
- }
- h->check = GG_CHECK_READ;
- h->timeout = GG_DEFAULT_TIMEOUT;
-
- return e;
-
- case GG_STATE_SENDING_VOICE_ACK:
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() GG_STATE_SENDING_VOICE_ACK\n");
-
- tiny.type = 0x01; /* XXX */
-
- gg_write(h->fd, &tiny, sizeof(tiny));
-
- h->state = GG_STATE_READING_VOICE_HEADER;
- h->check = GG_CHECK_READ;
- h->timeout = GG_DEFAULT_TIMEOUT;
-
- h->offset = 0;
-
- return e;
-
- case GG_STATE_READING_FILE_HEADER:
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() GG_STATE_READING_FILE_HEADER\n");
-
- tmp = read(h->fd, h->chunk_buf + h->chunk_offset, h->chunk_size - h->chunk_offset);
-
- if (tmp == -1) {
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() read() failed (errno=%d, %s)\n", errno, strerror(errno));
- e->type = GG_EVENT_DCC_ERROR;
- e->event.dcc_error = GG_ERROR_DCC_NET;
- return e;
- }
-
- gg_dcc_debug_data("read", h->fd, h->chunk_buf + h->chunk_offset, h->chunk_size - h->chunk_offset);
-
- h->chunk_offset += tmp;
-
- if (h->chunk_offset < h->chunk_size)
- return e;
-
- memcpy(&big, h->chunk_buf, sizeof(big));
- free(h->chunk_buf);
- h->chunk_buf = NULL;
-
- big.type = gg_fix32(big.type);
- h->chunk_size = gg_fix32(big.dunno1);
- h->chunk_offset = 0;
-
- if (big.type == 0x0005) { /* XXX */
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() transfer refused\n");
- e->type = GG_EVENT_DCC_ERROR;
- e->event.dcc_error = GG_ERROR_DCC_REFUSED;
- return e;
- }
-
- if (h->chunk_size == 0) {
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() empty chunk, EOF\n");
- e->type = GG_EVENT_DCC_DONE;
- return e;
- }
-
- h->state = GG_STATE_GETTING_FILE;
- h->check = GG_CHECK_READ;
- h->timeout = GG_DEFAULT_TIMEOUT;
- h->established = 1;
-
- return e;
-
- case GG_STATE_READING_VOICE_HEADER:
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() GG_STATE_READING_VOICE_HEADER\n");
-
- gg_read(h->fd, &tiny, sizeof(tiny));
-
- switch (tiny.type) {
- case 0x03: /* XXX */
- h->state = GG_STATE_READING_VOICE_SIZE;
- h->check = GG_CHECK_READ;
- h->timeout = GG_DEFAULT_TIMEOUT;
- h->established = 1;
- break;
- case 0x04: /* XXX */
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() peer breaking connection\n");
- /* XXX zwracaæ odpowiedni event */
- default:
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() unknown request (%.2x)\n", tiny.type);
- e->type = GG_EVENT_DCC_ERROR;
- e->event.dcc_error = GG_ERROR_DCC_HANDSHAKE;
- }
-
- return e;
-
- case GG_STATE_READING_VOICE_SIZE:
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() GG_STATE_READING_VOICE_SIZE\n");
-
- gg_read(h->fd, &small, sizeof(small));
-
- small.type = gg_fix32(small.type);
-
- if (small.type < 16 || small.type > sizeof(buf)) {
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() invalid voice frame size (%d)\n", small.type);
- e->type = GG_EVENT_DCC_ERROR;
- e->event.dcc_error = GG_ERROR_DCC_NET;
-
- return e;
- }
-
- h->chunk_size = small.type;
- h->chunk_offset = 0;
-
- if (!(h->voice_buf = malloc(h->chunk_size))) {
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() out of memory for voice frame\n");
- free(e);
- return NULL;
- }
-
- h->state = GG_STATE_READING_VOICE_DATA;
- h->check = GG_CHECK_READ;
- h->timeout = GG_DEFAULT_TIMEOUT;
-
- return e;
-
- case GG_STATE_READING_VOICE_DATA:
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() GG_STATE_READING_VOICE_DATA\n");
-
- tmp = read(h->fd, h->voice_buf + h->chunk_offset, h->chunk_size - h->chunk_offset);
- if (tmp < 1) {
- if (tmp == -1) {
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() read() failed (errno=%d, %s)\n", errno, strerror(errno));
- } else {
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() read() failed, connection broken\n");
- }
- e->type = GG_EVENT_DCC_ERROR;
- e->event.dcc_error = GG_ERROR_DCC_NET;
- return e;
- }
-
- gg_dcc_debug_data("read", h->fd, h->voice_buf + h->chunk_offset, tmp);
-
- h->chunk_offset += tmp;
-
- if (h->chunk_offset >= h->chunk_size) {
- e->type = GG_EVENT_DCC_VOICE_DATA;
- e->event.dcc_voice_data.data = h->voice_buf;
- e->event.dcc_voice_data.length = h->chunk_size;
- h->state = GG_STATE_READING_VOICE_HEADER;
- h->voice_buf = NULL;
- }
-
- h->check = GG_CHECK_READ;
- h->timeout = GG_DEFAULT_TIMEOUT;
-
- return e;
-
- case GG_STATE_CONNECTING:
- {
- uin_t uins[2];
-
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() GG_STATE_CONNECTING\n");
-
- res = 0;
- if ((foo = getsockopt(h->fd, SOL_SOCKET, SO_ERROR, &res, &res_size)) || res) {
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() connection failed (fd=%d,errno=%d(%s),foo=%d,res=%d(%s))\n", h->fd, errno, strerror(errno), foo, res, strerror(res));
- e->type = GG_EVENT_DCC_ERROR;
- e->event.dcc_error = GG_ERROR_DCC_HANDSHAKE;
- return e;
- }
-
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() connected, sending uins\n");
-
- uins[0] = gg_fix32(h->uin);
- uins[1] = gg_fix32(h->peer_uin);
-
- gg_write(h->fd, uins, sizeof(uins));
-
- h->state = GG_STATE_READING_ACK;
- h->check = GG_CHECK_READ;
- h->timeout = GG_DEFAULT_TIMEOUT;
-
- return e;
- }
-
- case GG_STATE_READING_ACK:
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() GG_STATE_READING_ACK\n");
-
- gg_read(h->fd, buf, 4);
-
- if (strncmp(buf, ack, 4)) {
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() did't get ack\n");
-
- e->type = GG_EVENT_DCC_ERROR;
- e->event.dcc_error = GG_ERROR_DCC_HANDSHAKE;
- return e;
- }
-
- h->check = GG_CHECK_WRITE;
- h->timeout = GG_DEFAULT_TIMEOUT;
- h->state = GG_STATE_SENDING_REQUEST;
-
- return e;
-
- case GG_STATE_SENDING_VOICE_REQUEST:
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() GG_STATE_SENDING_VOICE_REQUEST\n");
-
- small.type = gg_fix32(0x0003);
-
- gg_write(h->fd, &small, sizeof(small));
-
- h->state = GG_STATE_READING_VOICE_ACK;
- h->check = GG_CHECK_READ;
- h->timeout = GG_DEFAULT_TIMEOUT;
-
- return e;
-
- case GG_STATE_SENDING_REQUEST:
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() GG_STATE_SENDING_REQUEST\n");
-
- small.type = (h->type == GG_SESSION_DCC_GET) ? gg_fix32(0x0003) : gg_fix32(0x0002); /* XXX */
-
- gg_write(h->fd, &small, sizeof(small));
-
- switch (h->type) {
- case GG_SESSION_DCC_GET:
- h->state = GG_STATE_READING_REQUEST;
- h->check = GG_CHECK_READ;
- h->timeout = GG_DEFAULT_TIMEOUT;
- break;
-
- case GG_SESSION_DCC_SEND:
- h->state = GG_STATE_SENDING_FILE_INFO;
- h->check = GG_CHECK_WRITE;
- h->timeout = GG_DEFAULT_TIMEOUT;
-
- if (h->file_fd == -1)
- e->type = GG_EVENT_DCC_NEED_FILE_INFO;
- break;
-
- case GG_SESSION_DCC_VOICE:
- h->state = GG_STATE_SENDING_VOICE_REQUEST;
- h->check = GG_CHECK_WRITE;
- h->timeout = GG_DEFAULT_TIMEOUT;
- break;
- }
-
- return e;
-
- case GG_STATE_SENDING_FILE_INFO:
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() GG_STATE_SENDING_FILE_INFO\n");
-
- if (h->file_fd == -1) {
- e->type = GG_EVENT_DCC_NEED_FILE_INFO;
- return e;
- }
-
- small.type = gg_fix32(0x0001); /* XXX */
-
- gg_write(h->fd, &small, sizeof(small));
-
- file_info_packet.big.type = gg_fix32(0x0003); /* XXX */
- file_info_packet.big.dunno1 = 0;
- file_info_packet.big.dunno2 = 0;
-
- memcpy(&file_info_packet.file_info, &h->file_info, sizeof(h->file_info));
-
- /* zostaj± teraz u nas, wiêc odwracamy z powrotem */
- h->file_info.size = gg_fix32(h->file_info.size);
- h->file_info.mode = gg_fix32(h->file_info.mode);
-
- gg_write(h->fd, &file_info_packet, sizeof(file_info_packet));
-
- h->state = GG_STATE_READING_FILE_ACK;
- h->check = GG_CHECK_READ;
- h->timeout = GG_DCC_TIMEOUT_FILE_ACK;
-
- return e;
-
- case GG_STATE_READING_FILE_ACK:
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() GG_STATE_READING_FILE_ACK\n");
-
- gg_read(h->fd, &big, sizeof(big));
-
- /* XXX sprawdzaæ wynik */
- h->offset = gg_fix32(big.dunno1);
-
- h->state = GG_STATE_SENDING_FILE_HEADER;
- h->check = GG_CHECK_WRITE;
- h->timeout = GG_DEFAULT_TIMEOUT;
-
- e->type = GG_EVENT_DCC_ACK;
-
- return e;
-
- case GG_STATE_READING_VOICE_ACK:
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() GG_STATE_READING_VOICE_ACK\n");
-
- gg_read(h->fd, &tiny, sizeof(tiny));
-
- if (tiny.type != 0x01) {
- gg_debug(GG_DEBUG_MISC, "// invalid reply (%.2x), connection refused\n", tiny.type);
- e->type = GG_EVENT_DCC_ERROR;
- e->event.dcc_error = GG_ERROR_DCC_REFUSED;
- return e;
- }
-
- h->state = GG_STATE_READING_VOICE_HEADER;
- h->check = GG_CHECK_READ;
- h->timeout = GG_DEFAULT_TIMEOUT;
-
- e->type = GG_EVENT_DCC_ACK;
-
- return e;
-
- case GG_STATE_SENDING_FILE_HEADER:
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() GG_STATE_SENDING_FILE_HEADER\n");
-
- h->chunk_offset = 0;
-
- if ((h->chunk_size = h->file_info.size - h->offset) > 4096) {
- h->chunk_size = 4096;
- big.type = gg_fix32(0x0003); /* XXX */
- } else
- big.type = gg_fix32(0x0002); /* XXX */
-
- big.dunno1 = gg_fix32(h->chunk_size);
- big.dunno2 = 0;
-
- gg_write(h->fd, &big, sizeof(big));
-
- h->state = GG_STATE_SENDING_FILE;
- h->check = GG_CHECK_WRITE;
- h->timeout = GG_DEFAULT_TIMEOUT;
- h->established = 1;
-
- return e;
-
- case GG_STATE_SENDING_FILE:
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() GG_STATE_SENDING_FILE\n");
-
- if ((utmp = h->chunk_size - h->chunk_offset) > sizeof(buf))
- utmp = sizeof(buf);
-
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() offset=%d, size=%d\n", h->offset, h->file_info.size);
-
- /* koniec pliku? */
- if (h->file_info.size == 0) {
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() read() reached eof on empty file\n");
- e->type = GG_EVENT_DCC_DONE;
-
- return e;
- }
-
- lseek(h->file_fd, h->offset, SEEK_SET);
-
- size = read(h->file_fd, buf, utmp);
-
- /* b³±d */
- if (size == -1) {
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() read() failed. (errno=%d, %s)\n", errno, strerror(errno));
-
- e->type = GG_EVENT_DCC_ERROR;
- e->event.dcc_error = GG_ERROR_DCC_FILE;
-
- return e;
- }
-
- /* koniec pliku? */
- if (size == 0) {
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() read() reached eof\n");
- e->type = GG_EVENT_DCC_ERROR;
- e->event.dcc_error = GG_ERROR_DCC_EOF;
-
- return e;
- }
-
- /* je¶li wczytali¶my wiêcej, utnijmy. */
- if (h->offset + size > h->file_info.size) {
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() read() too much (read=%d, ofs=%d, size=%d)\n", size, h->offset, h->file_info.size);
- size = h->file_info.size - h->offset;
-
- if (size < 1) {
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() reached EOF after cutting\n");
- e->type = GG_EVENT_DCC_DONE;
- return e;
- }
- }
-
- tmp = write(h->fd, buf, size);
-
- if (tmp == -1) {
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() write() failed (%s)\n", strerror(errno));
- e->type = GG_EVENT_DCC_ERROR;
- e->event.dcc_error = GG_ERROR_DCC_NET;
- return e;
- }
-
- h->offset += size;
-
- if (h->offset >= h->file_info.size) {
- e->type = GG_EVENT_DCC_DONE;
- return e;
- }
-
- h->chunk_offset += size;
-
- if (h->chunk_offset >= h->chunk_size) {
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() chunk finished\n");
- h->state = GG_STATE_SENDING_FILE_HEADER;
- h->timeout = GG_DEFAULT_TIMEOUT;
- } else {
- h->state = GG_STATE_SENDING_FILE;
- h->timeout = GG_DCC_TIMEOUT_SEND;
- }
-
- h->check = GG_CHECK_WRITE;
-
- return e;
-
- case GG_STATE_GETTING_FILE:
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() GG_STATE_GETTING_FILE\n");
-
- if ((utmp = h->chunk_size - h->chunk_offset) > sizeof(buf))
- utmp = sizeof(buf);
-
- size = read(h->fd, buf, utmp);
-
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() ofs=%d, size=%d, read()=%d\n", h->offset, h->file_info.size, size);
-
- /* b³±d */
- if (size == -1) {
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() read() failed. (errno=%d, %s)\n", errno, strerror(errno));
-
- e->type = GG_EVENT_DCC_ERROR;
- e->event.dcc_error = GG_ERROR_DCC_NET;
-
- return e;
- }
-
- /* koniec? */
- if (size == 0) {
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() read() reached eof\n");
- e->type = GG_EVENT_DCC_ERROR;
- e->event.dcc_error = GG_ERROR_DCC_EOF;
-
- return e;
- }
-
- tmp = write(h->file_fd, buf, size);
-
- if (tmp == -1 || tmp < size) {
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() write() failed (%d:fd=%d:res=%d:%s)\n", tmp, h->file_fd, size, strerror(errno));
- e->type = GG_EVENT_DCC_ERROR;
- e->event.dcc_error = GG_ERROR_DCC_NET;
- return e;
- }
-
- h->offset += size;
-
- if (h->offset >= h->file_info.size) {
- e->type = GG_EVENT_DCC_DONE;
- return e;
- }
-
- h->chunk_offset += size;
-
- if (h->chunk_offset >= h->chunk_size) {
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() chunk finished\n");
- h->state = GG_STATE_READING_FILE_HEADER;
- h->timeout = GG_DEFAULT_TIMEOUT;
- h->chunk_offset = 0;
- h->chunk_size = sizeof(big);
- if (!(h->chunk_buf = malloc(sizeof(big)))) {
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() out of memory\n");
- free(e);
- return NULL;
- }
- } else {
- h->state = GG_STATE_GETTING_FILE;
- h->timeout = GG_DCC_TIMEOUT_GET;
- }
-
- h->check = GG_CHECK_READ;
-
- return e;
-
- default:
- gg_debug(GG_DEBUG_MISC, "// gg_dcc_watch_fd() GG_STATE_???\n");
- e->type = GG_EVENT_DCC_ERROR;
- e->event.dcc_error = GG_ERROR_DCC_HANDSHAKE;
-
- return e;
- }
- }
-
- return e;
-}
-
-#undef gg_read
-#undef gg_write
-
-/*
- * gg_dcc_free()
- *
- * zwalnia pamiêæ po strukturze po³±czenia dcc.
- *
- * - d - zwalniana struktura
- */
-void gg_dcc_free(struct gg_dcc *d)
-{
- gg_debug(GG_DEBUG_FUNCTION, "** gg_dcc_free(%p);\n", d);
-
- if (!d)
- return;
-
- if (d->fd != -1)
- close(d->fd);
-
- if (d->chunk_buf) {
- free(d->chunk_buf);
- d->chunk_buf = NULL;
- }
-
- free(d);
-}
-
-/*
- * Local variables:
- * c-indentation-style: k&r
- * c-basic-offset: 8
- * indent-tabs-mode: notnil
- * End:
- *
- * vim: shiftwidth=8:
- */
diff --git a/kopete/protocols/gadu/libgadu/events.c b/kopete/protocols/gadu/libgadu/events.c
deleted file mode 100644
index 1bf67690..00000000
--- a/kopete/protocols/gadu/libgadu/events.c
+++ /dev/null
@@ -1,1580 +0,0 @@
-/* $Id$ */
-
-/*
- * (C) Copyright 2001-2006 Wojtek Kaniewski <wojtekka@irc.pl>
- * Robert J. Wo�ny <speedy@ziew.org>
- * Arkadiusz Mi�kiewicz <arekm@pld-linux.org>
- * Adam Wysocki <gophi@ekg.chmurka.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License Version
- * 2.1 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
- * USA.
- */
-
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#include "libgadu-config.h"
-
-#include <errno.h>
-#ifdef __GG_LIBGADU_HAVE_PTHREAD
-# include <pthread.h>
-#endif
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <time.h>
-#include <unistd.h>
-#ifdef __GG_LIBGADU_HAVE_OPENSSL
-# include <openssl/err.h>
-# include <openssl/x509.h>
-#endif
-
-#include "compat.h"
-#include "libgadu.h"
-
-/*
- * gg_event_free()
- *
- * zwalnia pami�� zajmowan� przez informacj� o zdarzeniu.
- *
- * - e - wska�nik do informacji o zdarzeniu
- */
-void gg_event_free(struct gg_event *e)
-{
- gg_debug(GG_DEBUG_FUNCTION, "** gg_event_free(%p);\n", e);
-
- if (!e)
- return;
-
- switch (e->type) {
- case GG_EVENT_MSG:
- free(e->event.msg.message);
- free(e->event.msg.formats);
- free(e->event.msg.recipients);
- break;
-
- case GG_EVENT_NOTIFY:
- free(e->event.notify);
- break;
-
- case GG_EVENT_NOTIFY60:
- {
- int i;
-
- for (i = 0; e->event.notify60[i].uin; i++)
- free(e->event.notify60[i].descr);
-
- free(e->event.notify60);
-
- break;
- }
-
- case GG_EVENT_STATUS60:
- free(e->event.status60.descr);
- break;
-
- case GG_EVENT_STATUS:
- free(e->event.status.descr);
- break;
-
- case GG_EVENT_NOTIFY_DESCR:
- free(e->event.notify_descr.notify);
- free(e->event.notify_descr.descr);
- break;
-
- case GG_EVENT_DCC_VOICE_DATA:
- free(e->event.dcc_voice_data.data);
- break;
-
- case GG_EVENT_PUBDIR50_SEARCH_REPLY:
- case GG_EVENT_PUBDIR50_READ:
- case GG_EVENT_PUBDIR50_WRITE:
- gg_pubdir50_free(e->event.pubdir50);
- break;
-
- case GG_EVENT_USERLIST:
- free(e->event.userlist.reply);
- break;
-
- case GG_EVENT_IMAGE_REPLY:
- free(e->event.image_reply.filename);
- free(e->event.image_reply.image);
- break;
- }
-
- free(e);
-}
-
-/*
- * gg_image_queue_remove()
- *
- * usuwa z kolejki dany wpis.
- *
- * - s - sesja
- * - q - kolejka
- * - freeq - czy zwolni� kolejk�
- *
- * 0/-1
- */
-int gg_image_queue_remove(struct gg_session *s, struct gg_image_queue *q, int freeq)
-{
- if (!s || !q) {
- errno = EFAULT;
- return -1;
- }
-
- if (s->images == q)
- s->images = q->next;
- else {
- struct gg_image_queue *qq;
-
- for (qq = s->images; qq; qq = qq->next) {
- if (qq->next == q) {
- qq->next = q->next;
- break;
- }
- }
- }
-
- if (freeq) {
- free(q->image);
- free(q->filename);
- free(q);
- }
-
- return 0;
-}
-
-/*
- * gg_image_queue_parse() // funkcja wewn�trzna
- *
- * parsuje przychodz�cy pakiet z obrazkiem.
- *
- * - e - opis zdarzenia
- * -
- */
-static void gg_image_queue_parse(struct gg_event *e, char *p, unsigned int len, struct gg_session *sess, uin_t sender)
-{
- struct gg_msg_image_reply *i = (void*) p;
- struct gg_image_queue *q, *qq;
-
- if (!p || !sess || !e) {
- errno = EFAULT;
- return;
- }
-
- /* znajd� dany obrazek w kolejce danej sesji */
-
- for (qq = sess->images, q = NULL; qq; qq = qq->next) {
- if (sender == qq->sender && i->size == qq->size && i->crc32 == qq->crc32) {
- q = qq;
- break;
- }
- }
-
- if (!q) {
- gg_debug(GG_DEBUG_MISC, "// gg_image_queue_parse() unknown image from %d, size=%d, crc32=%.8x\n", sender, i->size, i->crc32);
- return;
- }
-
- if (p[0] == 0x05) {
- int i, ok = 0;
-
- q->done = 0;
-
- len -= sizeof(struct gg_msg_image_reply);
- p += sizeof(struct gg_msg_image_reply);
-
- /* sprawd�, czy mamy tekst zako�czony \0 */
-
- for (i = 0; i < len; i++) {
- if (!p[i]) {
- ok = 1;
- break;
- }
- }
-
- if (!ok) {
- gg_debug(GG_DEBUG_MISC, "// gg_image_queue_parse() malformed packet from %d, unlimited filename\n", sender);
- return;
- }
-
- if (!(q->filename = strdup(p))) {
- gg_debug(GG_DEBUG_MISC, "// gg_image_queue_parse() not enough memory for filename\n");
- return;
- }
-
- len -= strlen(p) + 1;
- p += strlen(p) + 1;
- } else {
- len -= sizeof(struct gg_msg_image_reply);
- p += sizeof(struct gg_msg_image_reply);
- }
-
- if (q->done + len > q->size)
- len = q->size - q->done;
-
- memcpy(q->image + q->done, p, len);
- q->done += len;
-
- /* je�li sko�czono odbiera� obrazek, wygeneruj zdarzenie */
-
- if (q->done >= q->size) {
- e->type = GG_EVENT_IMAGE_REPLY;
- e->event.image_reply.sender = sender;
- e->event.image_reply.size = q->size;
- e->event.image_reply.crc32 = q->crc32;
- e->event.image_reply.filename = q->filename;
- e->event.image_reply.image = q->image;
-
- gg_image_queue_remove(sess, q, 0);
-
- free(q);
- }
-}
-
-/*
- * gg_handle_recv_msg() // funkcja wewn�trzna
- *
- * obs�uguje pakiet z przychodz�c� wiadomo�ci�, rozbijaj�c go na dodatkowe
- * struktury (konferencje, kolorki) w razie potrzeby.
- *
- * - h - nag��wek pakietu
- * - e - opis zdarzenia
- *
- * 0, -1.
- */
-static int gg_handle_recv_msg(struct gg_header *h, struct gg_event *e, struct gg_session *sess)
-{
- struct gg_recv_msg *r = (struct gg_recv_msg*) ((char*) h + sizeof(struct gg_header));
- char *p, *packet_end = (char*) r + h->length;
-
- gg_debug(GG_DEBUG_FUNCTION, "** gg_handle_recv_msg(%p, %p);\n", h, e);
-
- if (!r->seq && !r->msgclass) {
- gg_debug(GG_DEBUG_MISC, "// gg_handle_recv_msg() oops, silently ignoring the bait\n");
- e->type = GG_EVENT_NONE;
- return 0;
- }
-
- for (p = (char*) r + sizeof(*r); *p; p++) {
- if (*p == 0x02 && p == packet_end - 1) {
- gg_debug(GG_DEBUG_MISC, "// gg_handle_recv_msg() received ctcp packet\n");
- break;
- }
- if (p >= packet_end) {
- gg_debug(GG_DEBUG_MISC, "// gg_handle_recv_msg() malformed packet, message out of bounds (0)\n");
- goto malformed;
- }
- }
-
- p++;
-
- /* przeanalizuj dodatkowe opcje */
- while (p < packet_end) {
- switch (*p) {
- case 0x01: /* konferencja */
- {
- struct gg_msg_recipients *m = (void*) p;
- uint32_t i, count;
-
- p += sizeof(*m);
-
- if (p > packet_end) {
- gg_debug(GG_DEBUG_MISC, "// gg_handle_recv_msg() packet out of bounds (1)\n");
- goto malformed;
- }
-
- count = gg_fix32(m->count);
-
- if (p + count * sizeof(uin_t) > packet_end || p + count * sizeof(uin_t) < p || count > 0xffff) {
- gg_debug(GG_DEBUG_MISC, "// gg_handle_recv_msg() packet out of bounds (1.5)\n");
- goto malformed;
- }
-
- if (!(e->event.msg.recipients = (void*) malloc(count * sizeof(uin_t)))) {
- gg_debug(GG_DEBUG_MISC, "// gg_handle_recv_msg() not enough memory for recipients data\n");
- goto fail;
- }
-
- for (i = 0; i < count; i++, p += sizeof(uint32_t)) {
- uint32_t u;
- memcpy(&u, p, sizeof(uint32_t));
- e->event.msg.recipients[i] = gg_fix32(u);
- }
-
- e->event.msg.recipients_count = count;
-
- break;
- }
-
- case 0x02: /* richtext */
- {
- uint16_t len;
- char *buf;
-
- if (p + 3 > packet_end) {
- gg_debug(GG_DEBUG_MISC, "// gg_handle_recv_msg() packet out of bounds (2)\n");
- goto malformed;
- }
-
- memcpy(&len, p + 1, sizeof(uint16_t));
- len = gg_fix16(len);
-
- if (!(buf = malloc(len))) {
- gg_debug(GG_DEBUG_MISC, "// gg_handle_recv_msg() not enough memory for richtext data\n");
- goto fail;
- }
-
- p += 3;
-
- if (p + len > packet_end) {
- gg_debug(GG_DEBUG_MISC, "// gg_handle_recv_msg() packet out of bounds (3)\n");
- free(buf);
- goto malformed;
- }
-
- memcpy(buf, p, len);
-
- e->event.msg.formats = buf;
- e->event.msg.formats_length = len;
-
- p += len;
-
- break;
- }
-
- case 0x04: /* image_request */
- {
- struct gg_msg_image_request *i = (void*) p;
-
- if (p + sizeof(*i) > packet_end) {
- gg_debug(GG_DEBUG_MISC, "// gg_handle_recv_msg() packet out of bounds (3)\n");
- goto malformed;
- }
-
- e->event.image_request.sender = gg_fix32(r->sender);
- e->event.image_request.size = gg_fix32(i->size);
- e->event.image_request.crc32 = gg_fix32(i->crc32);
-
- e->type = GG_EVENT_IMAGE_REQUEST;
-
- return 0;
- }
-
- case 0x05: /* image_reply */
- case 0x06:
- {
- struct gg_msg_image_reply *rep = (void*) p;
-
- if (p + sizeof(struct gg_msg_image_reply) == packet_end) {
-
- /* pusta odpowied� - klient po drugiej stronie nie ma ��danego obrazka */
-
- e->type = GG_EVENT_IMAGE_REPLY;
- e->event.image_reply.sender = gg_fix32(r->sender);
- e->event.image_reply.size = 0;
- e->event.image_reply.crc32 = gg_fix32(rep->crc32);
- e->event.image_reply.filename = NULL;
- e->event.image_reply.image = NULL;
- return 0;
-
- } else if (p + sizeof(struct gg_msg_image_reply) + 1 > packet_end) {
-
- gg_debug(GG_DEBUG_MISC, "// gg_handle_recv_msg() packet out of bounds (4)\n");
- goto malformed;
- }
-
- rep->size = gg_fix32(rep->size);
- rep->crc32 = gg_fix32(rep->crc32);
- gg_image_queue_parse(e, p, (unsigned int)(packet_end - p), sess, gg_fix32(r->sender));
-
- return 0;
- }
-
- default:
- {
- gg_debug(GG_DEBUG_MISC, "// gg_handle_recv_msg() unknown payload 0x%.2x\n", *p);
- p = packet_end;
- }
- }
- }
-
- e->type = GG_EVENT_MSG;
- e->event.msg.msgclass = gg_fix32(r->msgclass);
- e->event.msg.sender = gg_fix32(r->sender);
- e->event.msg.time = gg_fix32(r->time);
- e->event.msg.message = strdup((char*) r + sizeof(*r));
-
- return 0;
-
-malformed:
- e->type = GG_EVENT_NONE;
-
- free(e->event.msg.recipients);
- free(e->event.msg.formats);
-
- return 0;
-
-fail:
- free(e->event.msg.recipients);
- free(e->event.msg.formats);
- return -1;
-}
-
-/*
- * gg_watch_fd_connected() // funkcja wewn�trzna
- *
- * patrzy na gniazdo, odbiera pakiet i wype�nia struktur� zdarzenia.
- *
- * - sess - struktura opisuj�ca sesj�
- * - e - opis zdarzenia
- *
- * 0, -1.
- */
-static int gg_watch_fd_connected(struct gg_session *sess, struct gg_event *e)
-{
- struct gg_header *h = NULL;
- char *p;
-
- gg_debug(GG_DEBUG_FUNCTION, "** gg_watch_fd_connected(%p, %p);\n", sess, e);
-
- if (!sess) {
- errno = EFAULT;
- return -1;
- }
-
- if (!(h = gg_recv_packet(sess))) {
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd_connected() gg_recv_packet failed (errno=%d, %s)\n", errno, strerror(errno));
- goto fail;
- }
-
- p = (char*) h + sizeof(struct gg_header);
-
- switch (h->type) {
- case GG_RECV_MSG:
- {
- if (h->length >= sizeof(struct gg_recv_msg))
- if (gg_handle_recv_msg(h, e, sess))
- goto fail;
-
- break;
- }
-
- case GG_NOTIFY_REPLY:
- {
- struct gg_notify_reply *n = (void*) p;
- unsigned int count, i;
- char *tmp;
-
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd_connected() received a notify reply\n");
-
- if (h->length < sizeof(*n)) {
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd_connected() incomplete packet\n");
- errno = EINVAL;
- goto fail;
- }
-
- if (gg_fix32(n->status) == GG_STATUS_BUSY_DESCR || gg_fix32(n->status) == GG_STATUS_NOT_AVAIL_DESCR || gg_fix32(n->status) == GG_STATUS_AVAIL_DESCR) {
- e->type = GG_EVENT_NOTIFY_DESCR;
-
- if (!(e->event.notify_descr.notify = (void*) malloc(sizeof(*n) * 2))) {
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd_connected() not enough memory for notify data\n");
- goto fail;
- }
- e->event.notify_descr.notify[1].uin = 0;
- memcpy(e->event.notify_descr.notify, p, sizeof(*n));
- e->event.notify_descr.notify[0].uin = gg_fix32(e->event.notify_descr.notify[0].uin);
- e->event.notify_descr.notify[0].status = gg_fix32(e->event.notify_descr.notify[0].status);
- e->event.notify_descr.notify[0].remote_port = gg_fix16(e->event.notify_descr.notify[0].remote_port);
-
- count = h->length - sizeof(*n);
- if (!(tmp = malloc(count + 1))) {
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd_connected() not enough memory for notify data\n");
- goto fail;
- }
- memcpy(tmp, p + sizeof(*n), count);
- tmp[count] = 0;
- e->event.notify_descr.descr = tmp;
-
- } else {
- e->type = GG_EVENT_NOTIFY;
-
- if (!(e->event.notify = (void*) malloc(h->length + 2 * sizeof(*n)))) {
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd_connected() not enough memory for notify data\n");
- goto fail;
- }
-
- memcpy(e->event.notify, p, h->length);
- count = h->length / sizeof(*n);
- e->event.notify[count].uin = 0;
-
- for (i = 0; i < count; i++) {
- e->event.notify[i].uin = gg_fix32(e->event.notify[i].uin);
- e->event.notify[i].status = gg_fix32(e->event.notify[i].status);
- e->event.notify[i].remote_port = gg_fix16(e->event.notify[i].remote_port);
- }
- }
-
- break;
- }
-
- case GG_STATUS:
- {
- struct gg_status *s = (void*) p;
-
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd_connected() received a status change\n");
-
- if (h->length >= sizeof(*s)) {
- e->type = GG_EVENT_STATUS;
- memcpy(&e->event.status, p, sizeof(*s));
- e->event.status.uin = gg_fix32(e->event.status.uin);
- e->event.status.status = gg_fix32(e->event.status.status);
- if (h->length > sizeof(*s)) {
- int len = h->length - sizeof(*s);
- char *buf = malloc(len + 1);
- if (buf) {
- memcpy(buf, p + sizeof(*s), len);
- buf[len] = 0;
- }
- e->event.status.descr = buf;
- } else
- e->event.status.descr = NULL;
- }
-
- break;
- }
-
- case GG_NOTIFY_REPLY60:
- {
- struct gg_notify_reply60 *n = (void*) p;
- unsigned int length = h->length, i = 0;
-
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd_connected() received a notify reply\n");
-
- e->type = GG_EVENT_NOTIFY60;
- e->event.notify60 = malloc(sizeof(*e->event.notify60));
-
- if (!e->event.notify60) {
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd_connected() not enough memory for notify data\n");
- goto fail;
- }
-
- e->event.notify60[0].uin = 0;
-
- while (length >= sizeof(struct gg_notify_reply60)) {
- uin_t uin = gg_fix32(n->uin);
- char *tmp;
-
- e->event.notify60[i].uin = uin & 0x00ffffff;
- e->event.notify60[i].status = n->status;
- e->event.notify60[i].remote_ip = n->remote_ip;
- e->event.notify60[i].remote_port = gg_fix16(n->remote_port);
- e->event.notify60[i].version = n->version;
- e->event.notify60[i].image_size = n->image_size;
- e->event.notify60[i].descr = NULL;
- e->event.notify60[i].time = 0;
-
- if (uin & 0x40000000)
- e->event.notify60[i].version |= GG_HAS_AUDIO_MASK;
- if (uin & 0x08000000)
- e->event.notify60[i].version |= GG_ERA_OMNIX_MASK;
-
- if (GG_S_D(n->status)) {
- unsigned char descr_len = *((char*) n + sizeof(struct gg_notify_reply60));
-
- if (descr_len < length) {
- if (!(e->event.notify60[i].descr = malloc(descr_len + 1))) {
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd_connected() not enough memory for notify data\n");
- goto fail;
- }
-
- memcpy(e->event.notify60[i].descr, (char*) n + sizeof(struct gg_notify_reply60) + 1, descr_len);
- e->event.notify60[i].descr[descr_len] = 0;
-
- /* XXX czas */
- }
-
- length -= sizeof(struct gg_notify_reply60) + descr_len + 1;
- n = (void*) ((char*) n + sizeof(struct gg_notify_reply60) + descr_len + 1);
- } else {
- length -= sizeof(struct gg_notify_reply60);
- n = (void*) ((char*) n + sizeof(struct gg_notify_reply60));
- }
-
- if (!(tmp = realloc(e->event.notify60, (i + 2) * sizeof(*e->event.notify60)))) {
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd_connected() not enough memory for notify data\n");
- free(e->event.notify60);
- goto fail;
- }
-
- e->event.notify60 = (void*) tmp;
- e->event.notify60[++i].uin = 0;
- }
-
- break;
- }
-
- case GG_STATUS60:
- {
- struct gg_status60 *s = (void*) p;
- uint32_t uin;
-
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd_connected() received a status change\n");
-
- if (h->length < sizeof(*s))
- break;
-
- uin = gg_fix32(s->uin);
-
- e->type = GG_EVENT_STATUS60;
- e->event.status60.uin = uin & 0x00ffffff;
- e->event.status60.status = s->status;
- e->event.status60.remote_ip = s->remote_ip;
- e->event.status60.remote_port = gg_fix16(s->remote_port);
- e->event.status60.version = s->version;
- e->event.status60.image_size = s->image_size;
- e->event.status60.descr = NULL;
- e->event.status60.time = 0;
-
- if (uin & 0x40000000)
- e->event.status60.version |= GG_HAS_AUDIO_MASK;
- if (uin & 0x08000000)
- e->event.status60.version |= GG_ERA_OMNIX_MASK;
-
- if (h->length > sizeof(*s)) {
- int len = h->length - sizeof(*s);
- char *buf = malloc(len + 1);
-
- if (buf) {
- memcpy(buf, (char*) p + sizeof(*s), len);
- buf[len] = 0;
- }
-
- e->event.status60.descr = buf;
-
- if (len > 4 && p[h->length - 5] == 0) {
- uint32_t t;
- memcpy(&t, p + h->length - 4, sizeof(uint32_t));
- e->event.status60.time = gg_fix32(t);
- }
- }
-
- break;
- }
-
- case GG_SEND_MSG_ACK:
- {
- struct gg_send_msg_ack *s = (void*) p;
-
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd_connected() received a message ack\n");
-
- if (h->length < sizeof(*s))
- break;
-
- e->type = GG_EVENT_ACK;
- e->event.ack.status = gg_fix32(s->status);
- e->event.ack.recipient = gg_fix32(s->recipient);
- e->event.ack.seq = gg_fix32(s->seq);
-
- break;
- }
-
- case GG_PONG:
- {
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd_connected() received a pong\n");
-
- e->type = GG_EVENT_PONG;
- sess->last_pong = time(NULL);
-
- break;
- }
-
- case GG_DISCONNECTING:
- {
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd_connected() received disconnection warning\n");
- e->type = GG_EVENT_DISCONNECT;
- break;
- }
-
- case GG_PUBDIR50_REPLY:
- {
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd_connected() received pubdir/search reply\n");
- if (gg_pubdir50_handle_reply(e, p, h->length) == -1)
- goto fail;
- break;
- }
-
- case GG_USERLIST_REPLY:
- {
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd_connected() received userlist reply\n");
-
- if (h->length < 1)
- break;
-
- /* je�li odpowied� na eksport, wywo�aj zdarzenie tylko
- * gdy otrzymano wszystkie odpowiedzi */
- if (p[0] == GG_USERLIST_PUT_REPLY || p[0] == GG_USERLIST_PUT_MORE_REPLY) {
- if (--sess->userlist_blocks)
- break;
-
- p[0] = GG_USERLIST_PUT_REPLY;
- }
-
- if (h->length > 1) {
- char *tmp;
- unsigned int len = (sess->userlist_reply) ? strlen(sess->userlist_reply) : 0;
-
- gg_debug(GG_DEBUG_MISC, "userlist_reply=%p, len=%d\n", sess->userlist_reply, len);
-
- if (!(tmp = realloc(sess->userlist_reply, len + h->length))) {
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd_connected() not enough memory for userlist reply\n");
- free(sess->userlist_reply);
- sess->userlist_reply = NULL;
- goto fail;
- }
-
- sess->userlist_reply = tmp;
- sess->userlist_reply[len + h->length - 1] = 0;
- memcpy(sess->userlist_reply + len, p + 1, h->length - 1);
- }
-
- if (p[0] == GG_USERLIST_GET_MORE_REPLY)
- break;
-
- e->type = GG_EVENT_USERLIST;
- e->event.userlist.type = p[0];
- e->event.userlist.reply = sess->userlist_reply;
- sess->userlist_reply = NULL;
-
- break;
- }
-
- default:
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd_connected() received unknown packet 0x%.2x\n", h->type);
- }
-
- free(h);
- return 0;
-
-fail:
- free(h);
- return -1;
-}
-
-/*
- * gg_watch_fd()
- *
- * funkcja, kt�r� nale�y wywo�a�, gdy co� si� stanie z obserwowanym
- * deskryptorem. zwraca klientowi informacj� o tym, co si� dzieje.
- *
- * - sess - opis sesji
- *
- * wska�nik do struktury gg_event, kt�r� trzeba zwolni� p��niej
- * za pomoc� gg_event_free(). jesli rodzaj zdarzenia jest r�wny
- * GG_EVENT_NONE, nale�y je zignorowa�. je�li zwr�ci�o NULL,
- * sta�o si� co� niedobrego -- albo zabrak�o pami�ci albo zerwa�o
- * po��czenie.
- */
-struct gg_event *gg_watch_fd(struct gg_session *sess)
-{
- struct gg_event *e;
- int res = 0;
- int port = 0;
- int errno2 = 0;
-
- gg_debug(GG_DEBUG_FUNCTION, "** gg_watch_fd(%p);\n", sess);
-
- if (!sess) {
- errno = EFAULT;
- return NULL;
- }
-
- if (!(e = (void*) calloc(1, sizeof(*e)))) {
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() not enough memory for event data\n");
- return NULL;
- }
-
- e->type = GG_EVENT_NONE;
-
- switch (sess->state) {
- case GG_STATE_RESOLVING:
- {
- struct in_addr addr;
- int failed = 0;
-
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() GG_STATE_RESOLVING\n");
-
- if (read(sess->fd, &addr, sizeof(addr)) < (signed)sizeof(addr) || addr.s_addr == INADDR_NONE) {
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() resolving failed\n");
- failed = 1;
- errno2 = errno;
- }
-
- close(sess->fd);
- sess->fd = -1;
-
-#ifndef __GG_LIBGADU_HAVE_PTHREAD
- waitpid(sess->pid, NULL, 0);
- sess->pid = -1;
-#else
- if (sess->resolver) {
- pthread_cancel(*((pthread_t*) sess->resolver));
- free(sess->resolver);
- sess->resolver = NULL;
- }
-#endif
-
- if (failed) {
- errno = errno2;
- goto fail_resolving;
- }
-
- /* je�li jeste�my w resolverze i mamy ustawiony port
- * proxy, znaczy, �e resolvowali�my proxy. zatem
- * wpiszmy jego adres. */
- if (sess->proxy_port)
- sess->proxy_addr = addr.s_addr;
-
- /* zapiszmy sobie adres huba i adres serwera (do
- * bezpo�redniego po��czenia, je�li hub le�y)
- * z resolvera. */
- if (sess->proxy_addr && sess->proxy_port)
- port = sess->proxy_port;
- else {
- sess->server_addr = sess->hub_addr = addr.s_addr;
- port = GG_APPMSG_PORT;
- }
-
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() resolved, connecting to %s:%d\n", inet_ntoa(addr), port);
-
- /* ��czymy si� albo z hubem, albo z proxy, zale�nie
- * od tego, co resolvowali�my. */
- if ((sess->fd = gg_connect(&addr, port, sess->async)) == -1) {
- /* je�li w trybie asynchronicznym gg_connect()
- * zwr�ci b��d, nie ma sensu pr�bowa� dalej. */
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() connection failed (errno=%d, %s), critical\n", errno, strerror(errno));
- goto fail_connecting;
- }
-
- /* je�li podano serwer i ��czmy si� przez proxy,
- * jest to bezpo�rednie po��czenie, inaczej jest
- * do huba. */
- sess->state = (sess->proxy_addr && sess->proxy_port && sess->server_addr) ? GG_STATE_CONNECTING_GG : GG_STATE_CONNECTING_HUB;
- sess->check = GG_CHECK_WRITE;
- sess->timeout = GG_DEFAULT_TIMEOUT;
-
- break;
- }
-
- case GG_STATE_CONNECTING_HUB:
- {
- char buf[1024], *client, *auth;
- int res = 0, res_size = sizeof(res);
- const char *host, *appmsg;
-
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() GG_STATE_CONNECTING_HUB\n");
-
- /* je�li asynchroniczne, sprawdzamy, czy nie wyst�pi�
- * przypadkiem jaki� b��d. */
- if (sess->async && (getsockopt(sess->fd, SOL_SOCKET, SO_ERROR, &res, &res_size) || res)) {
- /* no tak, nie uda�o si� po��czy� z proxy. nawet
- * nie pr�bujemy dalej. */
- if (sess->proxy_addr && sess->proxy_port) {
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() connection to proxy failed (errno=%d, %s)\n", res, strerror(res));
- goto fail_connecting;
- }
-
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() connection to hub failed (errno=%d, %s), trying direct connection\n", res, strerror(res));
- close(sess->fd);
-
- if ((sess->fd = gg_connect(&sess->hub_addr, GG_DEFAULT_PORT, sess->async)) == -1) {
- /* przy asynchronicznych, gg_connect()
- * zwraca -1 przy b��dach socket(),
- * ioctl(), braku routingu itd. dlatego
- * nawet nie pr�bujemy dalej. */
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() direct connection failed (errno=%d, %s), critical\n", errno, strerror(errno));
- goto fail_connecting;
- }
-
- sess->state = GG_STATE_CONNECTING_GG;
- sess->check = GG_CHECK_WRITE;
- sess->timeout = GG_DEFAULT_TIMEOUT;
- break;
- }
-
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() connected to hub, sending query\n");
-
- if (!(client = gg_urlencode((sess->client_version) ? sess->client_version : GG_DEFAULT_CLIENT_VERSION))) {
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() out of memory for client version\n");
- goto fail_connecting;
- }
-
- if (!gg_proxy_http_only && sess->proxy_addr && sess->proxy_port)
- host = "http://" GG_APPMSG_HOST;
- else
- host = "";
-
-#ifdef __GG_LIBGADU_HAVE_OPENSSL
- if (sess->ssl)
- appmsg = "appmsg3.asp";
- else
-#endif
- appmsg = "appmsg2.asp";
-
- auth = gg_proxy_auth();
-
- snprintf(buf, sizeof(buf) - 1,
- "GET %s/appsvc/%s?fmnumber=%u&version=%s&lastmsg=%d HTTP/1.0\r\n"
- "Host: " GG_APPMSG_HOST "\r\n"
- "User-Agent: " GG_HTTP_USERAGENT "\r\n"
- "Pragma: no-cache\r\n"
- "%s"
- "\r\n", host, appmsg, sess->uin, client, sess->last_sysmsg, (auth) ? auth : "");
-
- if (auth)
- free(auth);
-
- free(client);
-
- /* zwolnij pami�� po wersji klienta. */
- if (sess->client_version) {
- free(sess->client_version);
- sess->client_version = NULL;
- }
-
- gg_debug(GG_DEBUG_MISC, "=> -----BEGIN-HTTP-QUERY-----\n%s\n=> -----END-HTTP-QUERY-----\n", buf);
-
- /* zapytanie jest kr�tkie, wi�c zawsze zmie�ci si�
- * do bufora gniazda. je�li write() zwr�ci mniej,
- * sta�o si� co� z�ego. */
- if (write(sess->fd, buf, strlen(buf)) < (signed)strlen(buf)) {
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() sending query failed\n");
-
- e->type = GG_EVENT_CONN_FAILED;
- e->event.failure = GG_FAILURE_WRITING;
- sess->state = GG_STATE_IDLE;
- close(sess->fd);
- sess->fd = -1;
- break;
- }
-
- sess->state = GG_STATE_READING_DATA;
- sess->check = GG_CHECK_READ;
- sess->timeout = GG_DEFAULT_TIMEOUT;
-
- break;
- }
-
- case GG_STATE_READING_DATA:
- {
- char buf[1024], *tmp, *host;
- int port = GG_DEFAULT_PORT;
- struct in_addr addr;
-
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() GG_STATE_READING_DATA\n");
-
- /* czytamy lini� z gniazda i obcinamy \r\n. */
- gg_read_line(sess->fd, buf, sizeof(buf) - 1);
- gg_chomp(buf);
- gg_debug(GG_DEBUG_TRAFFIC, "// gg_watch_fd() received http header (%s)\n", buf);
-
- /* sprawdzamy, czy wszystko w porz�dku. */
- if (strncmp(buf, "HTTP/1.", 7) || strncmp(buf + 9, "200", 3)) {
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() that's not what we've expected, trying direct connection\n");
-
- close(sess->fd);
-
- /* je�li otrzymali�my jakie� dziwne informacje,
- * pr�bujemy si� ��czy� z pomini�ciem huba. */
- if (sess->proxy_addr && sess->proxy_port) {
- if ((sess->fd = gg_connect(&sess->proxy_addr, sess->proxy_port, sess->async)) == -1) {
- /* trudno. nie wysz�o. */
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() connection to proxy failed (errno=%d, %s)\n", errno, strerror(errno));
- goto fail_connecting;
- }
-
- sess->state = GG_STATE_CONNECTING_GG;
- sess->check = GG_CHECK_WRITE;
- sess->timeout = GG_DEFAULT_TIMEOUT;
- break;
- }
-
- sess->port = GG_DEFAULT_PORT;
-
- /* ��czymy si� na port 8074 huba. */
- if ((sess->fd = gg_connect(&sess->hub_addr, sess->port, sess->async)) == -1) {
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() connection failed (errno=%d, %s), trying https\n", errno, strerror(errno));
-
- sess->port = GG_HTTPS_PORT;
-
- /* ��czymy si� na port 443. */
- if ((sess->fd = gg_connect(&sess->hub_addr, sess->port, sess->async)) == -1) {
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() connection failed (errno=%d, %s)\n", errno, strerror(errno));
- goto fail_connecting;
- }
- }
-
- sess->state = GG_STATE_CONNECTING_GG;
- sess->check = GG_CHECK_WRITE;
- sess->timeout = GG_DEFAULT_TIMEOUT;
- break;
- }
-
- /* ignorujemy reszt� nag��wka. */
- while (strcmp(buf, "\r\n") && strcmp(buf, ""))
- gg_read_line(sess->fd, buf, sizeof(buf) - 1);
-
- /* czytamy pierwsz� lini� danych. */
- gg_read_line(sess->fd, buf, sizeof(buf) - 1);
- gg_chomp(buf);
-
- /* je�li pierwsza liczba w linii nie jest r�wna zeru,
- * oznacza to, �e mamy wiadomo�� systemow�. */
- if (atoi(buf)) {
- char tmp[1024], *foo, *sysmsg_buf = NULL;
- int len = 0;
-
- while (gg_read_line(sess->fd, tmp, sizeof(tmp) - 1)) {
- if (!(foo = realloc(sysmsg_buf, len + strlen(tmp) + 2))) {
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() out of memory for system message, ignoring\n");
- break;
- }
-
- sysmsg_buf = foo;
-
- if (!len)
- strcpy(sysmsg_buf, tmp);
- else
- strcat(sysmsg_buf, tmp);
-
- len += strlen(tmp);
- }
-
- e->type = GG_EVENT_MSG;
- e->event.msg.msgclass = atoi(buf);
- e->event.msg.sender = 0;
- e->event.msg.message = sysmsg_buf;
- }
-
- close(sess->fd);
-
- gg_debug(GG_DEBUG_TRAFFIC, "// gg_watch_fd() received http data (%s)\n", buf);
-
- /* analizujemy otrzymane dane. */
- tmp = buf;
-
- while (*tmp && *tmp != ' ')
- tmp++;
- while (*tmp && *tmp == ' ')
- tmp++;
- host = tmp;
- while (*tmp && *tmp != ' ')
- tmp++;
- *tmp = 0;
-
- if ((tmp = (char*)strchr(host, ':'))) {
- *tmp = 0;
- port = atoi(tmp + 1);
- }
-
- if (!strcmp(host, "notoperating")) {
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() service unavailable\n", errno, strerror(errno));
- sess->fd = -1;
- goto fail_unavailable;
- }
-
- addr.s_addr = inet_addr(host);
- sess->server_addr = addr.s_addr;
-
- if (!gg_proxy_http_only && sess->proxy_addr && sess->proxy_port) {
- /* je�li mamy proxy, ��czymy si� z nim. */
- if ((sess->fd = gg_connect(&sess->proxy_addr, sess->proxy_port, sess->async)) == -1) {
- /* nie wysz�o? trudno. */
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() connection to proxy failed (errno=%d, %s)\n", errno, strerror(errno));
- goto fail_connecting;
- }
-
- sess->state = GG_STATE_CONNECTING_GG;
- sess->check = GG_CHECK_WRITE;
- sess->timeout = GG_DEFAULT_TIMEOUT;
- break;
- }
-
- sess->port = port;
-
- /* ��czymy si� z w�a�ciwym serwerem. */
- if ((sess->fd = gg_connect(&addr, sess->port, sess->async)) == -1) {
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() connection failed (errno=%d, %s), trying https\n", errno, strerror(errno));
-
- sess->port = GG_HTTPS_PORT;
-
- /* nie wysz�o? pr�bujemy portu 443. */
- if ((sess->fd = gg_connect(&addr, GG_HTTPS_PORT, sess->async)) == -1) {
- /* ostatnia deska ratunku zawiod�a?
- * w takim razie zwijamy manatki. */
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() connection failed (errno=%d, %s)\n", errno, strerror(errno));
- goto fail_connecting;
- }
- }
-
- sess->state = GG_STATE_CONNECTING_GG;
- sess->check = GG_CHECK_WRITE;
- sess->timeout = GG_DEFAULT_TIMEOUT;
-
- break;
- }
-
- case GG_STATE_CONNECTING_GG:
- {
- int res = 0, res_size = sizeof(res);
-
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() GG_STATE_CONNECTING_GG\n");
-
- /* je�li wyst�pi� b��d podczas ��czenia si�... */
- if (sess->async && (sess->timeout == 0 || getsockopt(sess->fd, SOL_SOCKET, SO_ERROR, &res, &res_size) || res)) {
- /* je�li nie uda�o si� po��czenie z proxy,
- * nie mamy czego pr�bowa� wi�cej. */
- if (sess->proxy_addr && sess->proxy_port) {
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() connection to proxy failed (errno=%d, %s)\n", res, strerror(res));
- goto fail_connecting;
- }
-
- close(sess->fd);
- sess->fd = -1;
-
-#ifdef ETIMEDOUT
- if (sess->timeout == 0)
- errno = ETIMEDOUT;
-#endif
-
-#ifdef __GG_LIBGADU_HAVE_OPENSSL
- /* je�li logujemy si� po TLS, nie pr�bujemy
- * si� ��czy� ju� z niczym innym w przypadku
- * b��du. nie do��, �e nie ma sensu, to i
- * trzeba by si� bawi� w tworzenie na nowo
- * SSL i SSL_CTX. */
-
- if (sess->ssl) {
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() connection failed (errno=%d, %s)\n", res, strerror(res));
- goto fail_connecting;
- }
-#endif
-
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() connection failed (errno=%d, %s), trying https\n", res, strerror(res));
-
- sess->port = GG_HTTPS_PORT;
-
- /* pr�bujemy na port 443. */
- if ((sess->fd = gg_connect(&sess->server_addr, sess->port, sess->async)) == -1) {
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() connection failed (errno=%d, %s)\n", errno, strerror(errno));
- goto fail_connecting;
- }
- }
-
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() connected\n");
-
- if (gg_proxy_http_only)
- sess->proxy_port = 0;
-
- /* je�li mamy proxy, wy�lijmy zapytanie. */
- if (sess->proxy_addr && sess->proxy_port) {
- char buf[100], *auth = gg_proxy_auth();
- struct in_addr addr;
-
- if (sess->server_addr)
- addr.s_addr = sess->server_addr;
- else
- addr.s_addr = sess->hub_addr;
-
- snprintf(buf, sizeof(buf), "CONNECT %s:%d HTTP/1.0\r\n", inet_ntoa(addr), sess->port);
-
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() proxy request:\n// %s", buf);
-
- /* wysy�amy zapytanie. jest ono na tyle kr�tkie,
- * �e musi si� zmie�ci� w buforze gniazda. je�li
- * write() zawiedzie, sta�o si� co� z�ego. */
- if (write(sess->fd, buf, strlen(buf)) < (signed)strlen(buf)) {
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() can't send proxy request\n");
- if (auth)
- free(auth);
- goto fail_connecting;
- }
-
- if (auth) {
- gg_debug(GG_DEBUG_MISC, "// %s", auth);
- if (write(sess->fd, auth, strlen(auth)) < (signed)strlen(auth)) {
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() can't send proxy request\n");
- free(auth);
- goto fail_connecting;
- }
-
- free(auth);
- }
-
- if (write(sess->fd, "\r\n", 2) < 2) {
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() can't send proxy request\n");
- goto fail_connecting;
- }
- }
-
-#ifdef __GG_LIBGADU_HAVE_OPENSSL
- if (sess->ssl) {
- SSL_set_fd(sess->ssl, sess->fd);
-
- sess->state = GG_STATE_TLS_NEGOTIATION;
- sess->check = GG_CHECK_WRITE;
- sess->timeout = GG_DEFAULT_TIMEOUT;
-
- break;
- }
-#endif
-
- sess->state = GG_STATE_READING_KEY;
- sess->check = GG_CHECK_READ;
- sess->timeout = GG_DEFAULT_TIMEOUT;
-
- break;
- }
-
-#ifdef __GG_LIBGADU_HAVE_OPENSSL
- case GG_STATE_TLS_NEGOTIATION:
- {
- int res;
- X509 *peer;
-
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() GG_STATE_TLS_NEGOTIATION\n");
-
- if ((res = SSL_connect(sess->ssl)) <= 0) {
- int err = SSL_get_error(sess->ssl, res);
-
- if (res == 0) {
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() disconnected during TLS negotiation\n");
-
- e->type = GG_EVENT_CONN_FAILED;
- e->event.failure = GG_FAILURE_TLS;
- sess->state = GG_STATE_IDLE;
- close(sess->fd);
- sess->fd = -1;
- break;
- }
-
- if (err == SSL_ERROR_WANT_READ) {
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() SSL_connect() wants to read\n");
-
- sess->state = GG_STATE_TLS_NEGOTIATION;
- sess->check = GG_CHECK_READ;
- sess->timeout = GG_DEFAULT_TIMEOUT;
-
- break;
- } else if (err == SSL_ERROR_WANT_WRITE) {
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() SSL_connect() wants to write\n");
-
- sess->state = GG_STATE_TLS_NEGOTIATION;
- sess->check = GG_CHECK_WRITE;
- sess->timeout = GG_DEFAULT_TIMEOUT;
-
- break;
- } else {
- char buf[1024];
-
- ERR_error_string_n(ERR_get_error(), buf, sizeof(buf));
-
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() SSL_connect() bailed out: %s\n", buf);
-
- e->type = GG_EVENT_CONN_FAILED;
- e->event.failure = GG_FAILURE_TLS;
- sess->state = GG_STATE_IDLE;
- close(sess->fd);
- sess->fd = -1;
- break;
- }
- }
-
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() TLS negotiation succeded:\n// cipher: %s\n", SSL_get_cipher_name(sess->ssl));
-
- peer = SSL_get_peer_certificate(sess->ssl);
-
- if (!peer)
- gg_debug(GG_DEBUG_MISC, "// WARNING! unable to get peer certificate!\n");
- else {
- char buf[1024];
-
- X509_NAME_oneline(X509_get_subject_name(peer), buf, sizeof(buf));
- gg_debug(GG_DEBUG_MISC, "// cert subject: %s\n", buf);
-
- X509_NAME_oneline(X509_get_issuer_name(peer), buf, sizeof(buf));
- gg_debug(GG_DEBUG_MISC, "// cert issuer: %s\n", buf);
- }
-
- sess->state = GG_STATE_READING_KEY;
- sess->check = GG_CHECK_READ;
- sess->timeout = GG_DEFAULT_TIMEOUT;
-
- break;
- }
-#endif
-
- case GG_STATE_READING_KEY:
- {
- struct gg_header *h;
- struct gg_welcome *w;
- struct gg_login60 l;
- unsigned int hash;
- unsigned char *password = sess->password;
- int ret;
-
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() GG_STATE_READING_KEY\n");
-
- memset(&l, 0, sizeof(l));
- l.dunno2 = 0xbe;
-
- /* XXX bardzo, bardzo, bardzo g�upi pomys� na pozbycie
- * si� tekstu wrzucanego przez proxy. */
- if (sess->proxy_addr && sess->proxy_port) {
- char buf[100];
-
- strcpy(buf, "");
- gg_read_line(sess->fd, buf, sizeof(buf) - 1);
- gg_chomp(buf);
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() proxy response:\n// %s\n", buf);
-
- while (strcmp(buf, "")) {
- gg_read_line(sess->fd, buf, sizeof(buf) - 1);
- gg_chomp(buf);
- if (strcmp(buf, ""))
- gg_debug(GG_DEBUG_MISC, "// %s\n", buf);
- }
-
- /* XXX niech czeka jeszcze raz w tej samej
- * fazie. g�upio, ale dzia�a. */
- sess->proxy_port = 0;
-
- break;
- }
-
- /* czytaj pierwszy pakiet. */
- if (!(h = gg_recv_packet(sess))) {
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() didn't receive packet (errno=%d, %s)\n", errno, strerror(errno));
-
- e->type = GG_EVENT_CONN_FAILED;
- e->event.failure = GG_FAILURE_READING;
- sess->state = GG_STATE_IDLE;
- errno2 = errno;
- close(sess->fd);
- errno = errno2;
- sess->fd = -1;
- break;
- }
-
- if (h->type != GG_WELCOME) {
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() invalid packet received\n");
- free(h);
- close(sess->fd);
- sess->fd = -1;
- errno = EINVAL;
- e->type = GG_EVENT_CONN_FAILED;
- e->event.failure = GG_FAILURE_INVALID;
- sess->state = GG_STATE_IDLE;
- break;
- }
-
- w = (struct gg_welcome*) ((char*) h + sizeof(struct gg_header));
- w->key = gg_fix32(w->key);
-
- hash = gg_login_hash(password, w->key);
-
- gg_debug(GG_DEBUG_DUMP, "// gg_watch_fd() challenge %.4x --> hash %.8x\n", w->key, hash);
-
- free(h);
-
- free(sess->password);
- sess->password = NULL;
-
- {
- struct in_addr dcc_ip;
- dcc_ip.s_addr = gg_dcc_ip;
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() gg_dcc_ip = %s\n", inet_ntoa(dcc_ip));
- }
-
- if (gg_dcc_ip == (unsigned long) inet_addr("255.255.255.255")) {
- struct sockaddr_in sin;
- int sin_len = sizeof(sin);
-
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() detecting address\n");
-
- if (!getsockname(sess->fd, (struct sockaddr*) &sin, &sin_len)) {
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() detected address to %s\n", inet_ntoa(sin.sin_addr));
- l.local_ip = sin.sin_addr.s_addr;
- } else {
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() unable to detect address\n");
- l.local_ip = 0;
- }
- } else
- l.local_ip = gg_dcc_ip;
-
- l.uin = gg_fix32(sess->uin);
- l.hash = gg_fix32(hash);
- l.status = gg_fix32(sess->initial_status ? sess->initial_status : GG_STATUS_AVAIL);
- l.version = gg_fix32(sess->protocol_version);
- l.local_port = gg_fix16(gg_dcc_port);
- l.image_size = sess->image_size;
-
- if (sess->external_addr && sess->external_port > 1023) {
- l.external_ip = sess->external_addr;
- l.external_port = gg_fix16(sess->external_port);
- }
-
- gg_debug(GG_DEBUG_TRAFFIC, "// gg_watch_fd() sending GG_LOGIN60 packet\n");
- ret = gg_send_packet(sess, GG_LOGIN60, &l, sizeof(l), sess->initial_descr, (sess->initial_descr) ? strlen(sess->initial_descr) : 0, NULL);
-
- free(sess->initial_descr);
- sess->initial_descr = NULL;
-
- if (ret == -1) {
- gg_debug(GG_DEBUG_TRAFFIC, "// gg_watch_fd() sending packet failed. (errno=%d, %s)\n", errno, strerror(errno));
- errno2 = errno;
- close(sess->fd);
- errno = errno2;
- sess->fd = -1;
- e->type = GG_EVENT_CONN_FAILED;
- e->event.failure = GG_FAILURE_WRITING;
- sess->state = GG_STATE_IDLE;
- break;
- }
-
- sess->state = GG_STATE_READING_REPLY;
-
- break;
- }
-
- case GG_STATE_READING_REPLY:
- {
- struct gg_header *h;
-
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() GG_STATE_READING_REPLY\n");
-
- if (!(h = gg_recv_packet(sess))) {
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() didn't receive packet (errno=%d, %s)\n", errno, strerror(errno));
- e->type = GG_EVENT_CONN_FAILED;
- e->event.failure = GG_FAILURE_READING;
- sess->state = GG_STATE_IDLE;
- errno2 = errno;
- close(sess->fd);
- errno = errno2;
- sess->fd = -1;
- break;
- }
-
- if (h->type == GG_LOGIN_OK || h->type == GG_NEED_EMAIL) {
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() login succeded\n");
- e->type = GG_EVENT_CONN_SUCCESS;
- sess->state = GG_STATE_CONNECTED;
- sess->timeout = -1;
- sess->status = (sess->initial_status) ? sess->initial_status : GG_STATUS_AVAIL;
- free(h);
- break;
- }
-
- if (h->type == GG_LOGIN_FAILED) {
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() login failed\n");
- e->event.failure = GG_FAILURE_PASSWORD;
- errno = EACCES;
- } else if (h->type == GG_DISCONNECTING) {
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() too many incorrect password attempts\n");
- e->event.failure = GG_FAILURE_INTRUDER;
- errno = EACCES;
- } else {
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() invalid packet\n");
- e->event.failure = GG_FAILURE_INVALID;
- errno = EINVAL;
- }
-
- e->type = GG_EVENT_CONN_FAILED;
- sess->state = GG_STATE_IDLE;
- errno2 = errno;
- close(sess->fd);
- errno = errno2;
- sess->fd = -1;
- free(h);
-
- break;
- }
-
- case GG_STATE_CONNECTED:
- {
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() GG_STATE_CONNECTED\n");
-
- sess->last_event = time(NULL);
-
- if ((res = gg_watch_fd_connected(sess, e)) == -1) {
-
- gg_debug(GG_DEBUG_MISC, "// gg_watch_fd() watch_fd_connected failed (errno=%d, %s)\n", errno, strerror(errno));
-
- if (errno == EAGAIN) {
- e->type = GG_EVENT_NONE;
- res = 0;
- } else
- res = -1;
- }
- break;
- }
- }
-
-done:
- if (res == -1) {
- free(e);
- e = NULL;
- }
-
- return e;
-
-fail_connecting:
- if (sess->fd != -1) {
- errno2 = errno;
- close(sess->fd);
- errno = errno2;
- sess->fd = -1;
- }
- e->type = GG_EVENT_CONN_FAILED;
- e->event.failure = GG_FAILURE_CONNECTING;
- sess->state = GG_STATE_IDLE;
- goto done;
-
-fail_resolving:
- e->type = GG_EVENT_CONN_FAILED;
- e->event.failure = GG_FAILURE_RESOLVING;
- sess->state = GG_STATE_IDLE;
- goto done;
-
-fail_unavailable:
- e->type = GG_EVENT_CONN_FAILED;
- e->event.failure = GG_FAILURE_UNAVAILABLE;
- sess->state = GG_STATE_IDLE;
- goto done;
-}
-
-/*
- * Local variables:
- * c-indentation-style: k&r
- * c-basic-offset: 8
- * indent-tabs-mode: notnil
- * End:
- *
- * vim: shiftwidth=8:
- */
diff --git a/kopete/protocols/gadu/libgadu/http.c b/kopete/protocols/gadu/libgadu/http.c
deleted file mode 100644
index 9f7369c5..00000000
--- a/kopete/protocols/gadu/libgadu/http.c
+++ /dev/null
@@ -1,522 +0,0 @@
-/* $Id$ */
-
-/*
- * (C) Copyright 2001-2002 Wojtek Kaniewski <wojtekka@irc.pl>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License Version
- * 2.1 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
- * USA.
- */
-
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#include "libgadu-config.h"
-
-#include <ctype.h>
-#include <errno.h>
-#include <netdb.h>
-#ifdef __GG_LIBGADU_HAVE_PTHREAD
-# include <pthread.h>
-#endif
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "compat.h"
-#include "libgadu.h"
-
-/*
- * gg_http_connect() // funkcja pomocnicza
- *
- * rozpoczyna po��czenie po http.
- *
- * - hostname - adres serwera
- * - port - port serwera
- * - async - asynchroniczne po��czenie
- * - method - metoda http (GET, POST, cokolwiek)
- * - path - �cie�ka do zasobu (musi by� poprzedzona ,,/'')
- * - header - nag��wek zapytania plus ewentualne dane dla POST
- *
- * zaalokowana struct gg_http, kt�r� po�niej nale�y
- * zwolni� funkcj� gg_http_free(), albo NULL je�li wyst�pi� b��d.
- */
-struct gg_http *gg_http_connect(const char *hostname, int port, int async, const char *method, const char *path, const char *header)
-{
- struct gg_http *h;
-
- if (!hostname || !port || !method || !path || !header) {
- gg_debug(GG_DEBUG_MISC, "// gg_http_connect() invalid arguments\n");
- errno = EFAULT;
- return NULL;
- }
-
- if (!(h = malloc(sizeof(*h))))
- return NULL;
- memset(h, 0, sizeof(*h));
-
- h->async = async;
- h->port = port;
- h->fd = -1;
- h->type = GG_SESSION_HTTP;
-
- if (gg_proxy_enabled) {
- char *auth = gg_proxy_auth();
-
- h->query = gg_saprintf("%s http://%s:%d%s HTTP/1.0\r\n%s%s",
- method, hostname, port, path, (auth) ? auth :
- "", header);
- hostname = gg_proxy_host;
- h->port = port = gg_proxy_port;
-
- if (auth)
- free(auth);
- } else {
- h->query = gg_saprintf("%s %s HTTP/1.0\r\n%s",
- method, path, header);
- }
-
- if (!h->query) {
- gg_debug(GG_DEBUG_MISC, "// gg_http_connect() not enough memory for query\n");
- free(h);
- errno = ENOMEM;
- return NULL;
- }
-
- gg_debug(GG_DEBUG_MISC, "=> -----BEGIN-HTTP-QUERY-----\n%s\n=> -----END-HTTP-QUERY-----\n", h->query);
-
- if (async) {
-#ifndef __GG_LIBGADU_HAVE_PTHREAD
- if (gg_resolve(&h->fd, &h->pid, hostname)) {
-#else
- if (gg_resolve_pthread(&h->fd, &h->resolver, hostname)) {
-#endif
- gg_debug(GG_DEBUG_MISC, "// gg_http_connect() resolver failed\n");
- gg_http_free(h);
- errno = ENOENT;
- return NULL;
- }
-
- gg_debug(GG_DEBUG_MISC, "// gg_http_connect() resolver = %p\n", h->resolver);
-
- h->state = GG_STATE_RESOLVING;
- h->check = GG_CHECK_READ;
- h->timeout = GG_DEFAULT_TIMEOUT;
- } else {
- struct in_addr *hn, a;
-
- if (!(hn = gg_gethostbyname(hostname))) {
- gg_debug(GG_DEBUG_MISC, "// gg_http_connect() host not found\n");
- gg_http_free(h);
- errno = ENOENT;
- return NULL;
- } else {
- a.s_addr = hn->s_addr;
- free(hn);
- }
-
- if (!(h->fd = gg_connect(&a, port, 0)) == -1) {
- gg_debug(GG_DEBUG_MISC, "// gg_http_connect() connection failed (errno=%d, %s)\n", errno, strerror(errno));
- gg_http_free(h);
- return NULL;
- }
-
- h->state = GG_STATE_CONNECTING;
-
- while (h->state != GG_STATE_ERROR && h->state != GG_STATE_PARSING) {
- if (gg_http_watch_fd(h) == -1)
- break;
- }
-
- if (h->state != GG_STATE_PARSING) {
- gg_debug(GG_DEBUG_MISC, "// gg_http_connect() some strange error\n");
- gg_http_free(h);
- return NULL;
- }
- }
-
- h->callback = gg_http_watch_fd;
- h->destroy = gg_http_free;
-
- return h;
-}
-
-#define gg_http_error(x) \
- close(h->fd); \
- h->fd = -1; \
- h->state = GG_STATE_ERROR; \
- h->error = x; \
- return 0;
-
-/*
- * gg_http_watch_fd()
- *
- * przy asynchronicznej obs�udze HTTP funkcj� t� nale�y wywo�a�, je�li
- * zmieni�o si� co� na obserwowanym deskryptorze.
- *
- * - h - struktura opisuj�ca po��czenie
- *
- * je�li wszystko posz�o dobrze to 0, inaczej -1. po��czenie b�dzie
- * zako�czone, je�li h->state == GG_STATE_PARSING. je�li wyst�pi jaki�
- * b��d, to b�dzie tam GG_STATE_ERROR i odpowiedni kod b��du w h->error.
- */
-int gg_http_watch_fd(struct gg_http *h)
-{
- gg_debug(GG_DEBUG_FUNCTION, "** gg_http_watch_fd(%p);\n", h);
-
- if (!h) {
- gg_debug(GG_DEBUG_MISC, "// gg_http_watch_fd() invalid arguments\n");
- errno = EFAULT;
- return -1;
- }
-
- if (h->state == GG_STATE_RESOLVING) {
- struct in_addr a;
-
- gg_debug(GG_DEBUG_MISC, "=> http, resolving done\n");
-
- if (read(h->fd, &a, sizeof(a)) < (signed)sizeof(a) || a.s_addr == INADDR_NONE) {
- gg_debug(GG_DEBUG_MISC, "=> http, resolver thread failed\n");
- gg_http_error(GG_ERROR_RESOLVING);
- }
-
- close(h->fd);
- h->fd = -1;
-
-#ifndef __GG_LIBGADU_HAVE_PTHREAD
- waitpid(h->pid, NULL, 0);
-#else
- if (h->resolver) {
- pthread_cancel(*((pthread_t *) h->resolver));
- free(h->resolver);
- h->resolver = NULL;
- }
-#endif
-
- gg_debug(GG_DEBUG_MISC, "=> http, connecting to %s:%d\n", inet_ntoa(a), h->port);
-
- if ((h->fd = gg_connect(&a, h->port, h->async)) == -1) {
- gg_debug(GG_DEBUG_MISC, "=> http, connection failed (errno=%d, %s)\n", errno, strerror(errno));
- gg_http_error(GG_ERROR_CONNECTING);
- }
-
- h->state = GG_STATE_CONNECTING;
- h->check = GG_CHECK_WRITE;
- h->timeout = GG_DEFAULT_TIMEOUT;
-
- return 0;
- }
-
- if (h->state == GG_STATE_CONNECTING) {
- int res = 0;
- unsigned int res_size = sizeof(res);
-
- if (h->async && (getsockopt(h->fd, SOL_SOCKET, SO_ERROR, &res, &res_size) || res)) {
- gg_debug(GG_DEBUG_MISC, "=> http, async connection failed (errno=%d, %s)\n", (res) ? res : errno , strerror((res) ? res : errno));
- close(h->fd);
- h->fd = -1;
- h->state = GG_STATE_ERROR;
- h->error = GG_ERROR_CONNECTING;
- if (res)
- errno = res;
- return 0;
- }
-
- gg_debug(GG_DEBUG_MISC, "=> http, connected, sending request\n");
-
- h->state = GG_STATE_SENDING_QUERY;
- }
-
- if (h->state == GG_STATE_SENDING_QUERY) {
- int res;
-
- if ((res = write(h->fd, h->query, strlen(h->query))) < 1) {
- gg_debug(GG_DEBUG_MISC, "=> http, write() failed (len=%d, res=%d, errno=%d)\n", strlen(h->query), res, errno);
- gg_http_error(GG_ERROR_WRITING);
- }
-
- if (res < strlen(h->query)) {
- gg_debug(GG_DEBUG_MISC, "=> http, partial header sent (led=%d, sent=%d)\n", strlen(h->query), res);
-
- memmove(h->query, h->query + res, strlen(h->query) - res + 1);
- h->state = GG_STATE_SENDING_QUERY;
- h->check = GG_CHECK_WRITE;
- h->timeout = GG_DEFAULT_TIMEOUT;
- } else {
- gg_debug(GG_DEBUG_MISC, "=> http, request sent (len=%d)\n", strlen(h->query));
- free(h->query);
- h->query = NULL;
-
- h->state = GG_STATE_READING_HEADER;
- h->check = GG_CHECK_READ;
- h->timeout = GG_DEFAULT_TIMEOUT;
- }
-
- return 0;
- }
-
- if (h->state == GG_STATE_READING_HEADER) {
- char buf[1024], *tmp;
- int res;
-
- if ((res = read(h->fd, buf, sizeof(buf))) == -1) {
- gg_debug(GG_DEBUG_MISC, "=> http, reading header failed (errno=%d)\n", errno);
- if (h->header) {
- free(h->header);
- h->header = NULL;
- }
- gg_http_error(GG_ERROR_READING);
- }
-
- if (!res) {
- gg_debug(GG_DEBUG_MISC, "=> http, connection reset by peer\n");
- if (h->header) {
- free(h->header);
- h->header = NULL;
- }
- gg_http_error(GG_ERROR_READING);
- }
-
- gg_debug(GG_DEBUG_MISC, "=> http, read %d bytes of header\n", res);
-
- if (!(tmp = realloc(h->header, h->header_size + res + 1))) {
- gg_debug(GG_DEBUG_MISC, "=> http, not enough memory for header\n");
- free(h->header);
- h->header = NULL;
- gg_http_error(GG_ERROR_READING);
- }
-
- h->header = tmp;
-
- memcpy(h->header + h->header_size, buf, res);
- h->header_size += res;
-
- gg_debug(GG_DEBUG_MISC, "=> http, header_buf=%p, header_size=%d\n", h->header, h->header_size);
-
- h->header[h->header_size] = 0;
-
- if ((tmp = strstr(h->header, "\r\n\r\n")) || (tmp = strstr(h->header, "\n\n"))) {
- int sep_len = (*tmp == '\r') ? 4 : 2;
- unsigned int left;
- char *line;
-
- left = h->header_size - ((long)(tmp) - (long)(h->header) + sep_len);
-
- gg_debug(GG_DEBUG_MISC, "=> http, got all header (%d bytes, %d left)\n", h->header_size - left, left);
-
- /* HTTP/1.1 200 OK */
- if (strlen(h->header) < 16 || strncmp(h->header + 9, "200", 3)) {
- gg_debug(GG_DEBUG_MISC, "=> -----BEGIN-HTTP-HEADER-----\n%s\n=> -----END-HTTP-HEADER-----\n", h->header);
-
- gg_debug(GG_DEBUG_MISC, "=> http, didn't get 200 OK -- no results\n");
- free(h->header);
- h->header = NULL;
- gg_http_error(GG_ERROR_CONNECTING);
- }
-
- h->body_size = 0;
- line = h->header;
- *tmp = 0;
-
- gg_debug(GG_DEBUG_MISC, "=> -----BEGIN-HTTP-HEADER-----\n%s\n=> -----END-HTTP-HEADER-----\n", h->header);
-
- while (line) {
- if (!strncasecmp(line, "Content-length: ", 16)) {
- h->body_size = atoi(line + 16);
- }
- line = (char*)strchr(line, '\n');
- if (line)
- line++;
- }
-
- if (h->body_size <= 0) {
- gg_debug(GG_DEBUG_MISC, "=> http, content-length not found\n");
- h->body_size = left;
- }
-
- if (left > h->body_size) {
- gg_debug(GG_DEBUG_MISC, "=> http, oversized reply (%d bytes needed, %d bytes left)\n", h->body_size, left);
- h->body_size = left;
- }
-
- gg_debug(GG_DEBUG_MISC, "=> http, body_size=%d\n", h->body_size);
-
- if (!(h->body = malloc(h->body_size + 1))) {
- gg_debug(GG_DEBUG_MISC, "=> http, not enough memory (%d bytes for body_buf)\n", h->body_size + 1);
- free(h->header);
- h->header = NULL;
- gg_http_error(GG_ERROR_READING);
- }
-
- if (left) {
- memcpy(h->body, tmp + sep_len, left);
- h->body_done = left;
- }
-
- h->body[left] = 0;
-
- h->state = GG_STATE_READING_DATA;
- h->check = GG_CHECK_READ;
- h->timeout = GG_DEFAULT_TIMEOUT;
- }
-
- return 0;
- }
-
- if (h->state == GG_STATE_READING_DATA) {
- char buf[1024];
- int res;
-
- if ((res = read(h->fd, buf, sizeof(buf))) == -1) {
- gg_debug(GG_DEBUG_MISC, "=> http, reading body failed (errno=%d)\n", errno);
- if (h->body) {
- free(h->body);
- h->body = NULL;
- }
- gg_http_error(GG_ERROR_READING);
- }
-
- if (!res) {
- if (h->body_done >= h->body_size) {
- gg_debug(GG_DEBUG_MISC, "=> http, we're done, closing socket\n");
- h->state = GG_STATE_PARSING;
- close(h->fd);
- h->fd = -1;
- } else {
- gg_debug(GG_DEBUG_MISC, "=> http, connection closed while reading (have %d, need %d)\n", h->body_done, h->body_size);
- if (h->body) {
- free(h->body);
- h->body = NULL;
- }
- gg_http_error(GG_ERROR_READING);
- }
-
- return 0;
- }
-
- gg_debug(GG_DEBUG_MISC, "=> http, read %d bytes of body\n", res);
-
- if (h->body_done + res > h->body_size) {
- char *tmp;
-
- gg_debug(GG_DEBUG_MISC, "=> http, too much data (%d bytes, %d needed), enlarging buffer\n", h->body_done + res, h->body_size);
-
- if (!(tmp = realloc(h->body, h->body_done + res + 1))) {
- gg_debug(GG_DEBUG_MISC, "=> http, not enough memory for data (%d needed)\n", h->body_done + res + 1);
- free(h->body);
- h->body = NULL;
- gg_http_error(GG_ERROR_READING);
- }
-
- h->body = tmp;
- h->body_size = h->body_done + res;
- }
-
- h->body[h->body_done + res] = 0;
- memcpy(h->body + h->body_done, buf, res);
- h->body_done += res;
-
- gg_debug(GG_DEBUG_MISC, "=> body_done=%d, body_size=%d\n", h->body_done, h->body_size);
-
- return 0;
- }
-
- if (h->fd != -1)
- close(h->fd);
-
- h->fd = -1;
- h->state = GG_STATE_ERROR;
- h->error = 0;
-
- return -1;
-}
-
-#undef gg_http_error
-
-/*
- * gg_http_stop()
- *
- * je�li po��czenie jest w trakcie, przerywa je. nie zwalnia h->data.
- *
- * - h - struktura opisuj�ca po��czenie
- */
-void gg_http_stop(struct gg_http *h)
-{
- if (!h)
- return;
-
- if (h->state == GG_STATE_ERROR || h->state == GG_STATE_DONE)
- return;
-
- if (h->fd != -1)
- close(h->fd);
- h->fd = -1;
-}
-
-/*
- * gg_http_free_fields() // funkcja wewn�trzna
- *
- * zwalnia pola struct gg_http, ale nie zwalnia samej struktury.
- */
-void gg_http_free_fields(struct gg_http *h)
-{
- if (!h)
- return;
-
- if (h->body) {
- free(h->body);
- h->body = NULL;
- }
-
- if (h->query) {
- free(h->query);
- h->query = NULL;
- }
-
- if (h->header) {
- free(h->header);
- h->header = NULL;
- }
-}
-
-/*
- * gg_http_free()
- *
- * pr�buje zamkn�� po��czenie i zwalnia pami�� po nim.
- *
- * - h - struktura, kt�r� nale�y zlikwidowa�
- */
-void gg_http_free(struct gg_http *h)
-{
- if (!h)
- return;
-
- gg_http_stop(h);
- gg_http_free_fields(h);
- free(h);
-}
-
-/*
- * Local variables:
- * c-indentation-style: k&r
- * c-basic-offset: 8
- * indent-tabs-mode: notnil
- * End:
- *
- * vim: shiftwidth=8:
- */
diff --git a/kopete/protocols/gadu/libgadu/libgadu-config.h.in b/kopete/protocols/gadu/libgadu/libgadu-config.h.in
deleted file mode 100644
index dc4fb435..00000000
--- a/kopete/protocols/gadu/libgadu/libgadu-config.h.in
+++ /dev/null
@@ -1,30 +0,0 @@
-/* Local libgadu configuration. */
-
-#ifndef __GG_LIBGADU_CONFIG_H
-#define __GG_LIBGADU_CONFIG_H
-
-/* Defined if libgadu was compiled for bigendian machine. */
-#undef __GG_LIBGADU_BIGENDIAN
-
-/* Defined if libgadu was compiled and linked with pthread support. */
-#define __GG_LIBGADU_HAVE_PTHREAD
-
-/* Defined if this machine has C99-compiliant vsnprintf(). */
-#undef __GG_LIBGADU_HAVE_C99_VSNPRINTF
-
-/* Defined if this machine has va_copy(). */
-#undef __GG_LIBGADU_HAVE_VA_COPY
-
-/* Defined if this machine has __va_copy(). */
-#undef __GG_LIBGADU_HAVE___VA_COPY
-
-/* Defined if this machine supports long long. */
-#undef __GG_LIBGADU_HAVE_LONG_LONG
-
-/* Defined if libgadu was compiled and linked with TLS support. */
-#undef __GG_LIBGADU_HAVE_OPENSSL
-
-/* Include file containing uintXX_t declarations. */
-#include <inttypes.h>
-
-#endif /* __GG_LIBGADU_CONFIG_H */
diff --git a/kopete/protocols/gadu/libgadu/libgadu.c b/kopete/protocols/gadu/libgadu/libgadu.c
deleted file mode 100644
index 79f0a170..00000000
--- a/kopete/protocols/gadu/libgadu/libgadu.c
+++ /dev/null
@@ -1,1818 +0,0 @@
-/* $Id$ */
-
-/*
- * (C) Copyright 2001-2006 Wojtek Kaniewski <wojtekka@irc.pl>
- * Robert J. Wo¼ny <speedy@ziew.org>
- * Arkadiusz Mi¶kiewicz <arekm@pld-linux.org>
- * Tomasz Chiliñski <chilek@chilan.com>
- * Adam Wysocki <gophi@ekg.chmurka.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License Version
- * 2.1 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
- * USA.
- */
-
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#ifdef sun
-# include <sys/filio.h>
-#endif
-
-#include "libgadu-config.h"
-
-#include <errno.h>
-#include <netdb.h>
-#ifdef __GG_LIBGADU_HAVE_PTHREAD
-# include <pthread.h>
-#endif
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <signal.h>
-#include <unistd.h>
-#ifdef __GG_LIBGADU_HAVE_OPENSSL
-# include <openssl/err.h>
-# include <openssl/rand.h>
-#endif
-
-#include "compat.h"
-#include "libgadu.h"
-
-int gg_debug_level = 0;
-void (*gg_debug_handler)(int level, const char *format, va_list ap) = NULL;
-
-int gg_dcc_port = 0;
-unsigned long gg_dcc_ip = 0;
-
-unsigned long gg_local_ip = 0;
-/*
- * zmienne opisuj±ce parametry proxy http.
- */
-char *gg_proxy_host = NULL;
-int gg_proxy_port = 0;
-int gg_proxy_enabled = 0;
-int gg_proxy_http_only = 0;
-char *gg_proxy_username = NULL;
-char *gg_proxy_password = NULL;
-
-#ifndef lint
-static char rcsid[]
-#ifdef __GNUC__
-__attribute__ ((unused))
-#endif
-= "$Id$";
-#endif
-
-/*
- * gg_libgadu_version()
- *
- * zwraca wersjê libgadu.
- *
- * - brak
- *
- * wersja libgadu.
- */
-const char *gg_libgadu_version()
-{
- return GG_LIBGADU_VERSION;
-}
-
-/*
- * gg_fix32()
- *
- * zamienia kolejno¶æ bajtów w liczbie 32-bitowej tak, by odpowiada³a
- * kolejno¶ci bajtów w protokole GG. ze wzglêdu na LE-owo¶æ serwera,
- * zamienia tylko na maszynach BE-wych.
- *
- * - x - liczba do zamiany
- *
- * liczba z odpowiedni± kolejno¶ci± bajtów.
- */
-uint32_t gg_fix32(uint32_t x)
-{
-#ifndef __GG_LIBGADU_BIGENDIAN
- return x;
-#else
- return (uint32_t)
- (((x & (uint32_t) 0x000000ffU) << 24) |
- ((x & (uint32_t) 0x0000ff00U) << 8) |
- ((x & (uint32_t) 0x00ff0000U) >> 8) |
- ((x & (uint32_t) 0xff000000U) >> 24));
-#endif
-}
-
-/*
- * gg_fix16()
- *
- * zamienia kolejno¶æ bajtów w liczbie 16-bitowej tak, by odpowiada³a
- * kolejno¶ci bajtów w protokole GG. ze wzglêdu na LE-owo¶æ serwera,
- * zamienia tylko na maszynach BE-wych.
- *
- * - x - liczba do zamiany
- *
- * liczba z odpowiedni± kolejno¶ci± bajtów.
- */
-uint16_t gg_fix16(uint16_t x)
-{
-#ifndef __GG_LIBGADU_BIGENDIAN
- return x;
-#else
- return (uint16_t)
- (((x & (uint16_t) 0x00ffU) << 8) |
- ((x & (uint16_t) 0xff00U) >> 8));
-#endif
-}
-
-/*
- * gg_login_hash() // funkcja wewnêtrzna
- *
- * liczy hash z has³a i danego seeda.
- *
- * - password - has³o do hashowania
- * - seed - warto¶æ podana przez serwer
- *
- * hash.
- */
-unsigned int gg_login_hash(const unsigned char *password, unsigned int seed)
-{
- unsigned int x, y, z;
-
- y = seed;
-
- for (x = 0; *password; password++) {
- x = (x & 0xffffff00) | *password;
- y ^= x;
- y += x;
- x <<= 8;
- y ^= x;
- x <<= 8;
- y -= x;
- x <<= 8;
- y ^= x;
-
- z = y & 0x1F;
- y = (y << z) | (y >> (32 - z));
- }
-
- return y;
-}
-
-/*
- * gg_resolve() // funkcja wewnêtrzna
- *
- * tworzy potok, forkuje siê i w drugim procesie zaczyna resolvowaæ
- * podanego hosta. zapisuje w sesji deskryptor potoku. je¶li co¶ tam
- * bêdzie gotowego, znaczy, ¿e mo¿na wczytaæ struct in_addr. je¶li
- * nie znajdzie, zwraca INADDR_NONE.
- *
- * - fd - wska¼nik gdzie wrzuciæ deskryptor
- * - pid - gdzie wrzuciæ pid procesu potomnego
- * - hostname - nazwa hosta do zresolvowania
- *
- * 0, -1.
- */
-int gg_resolve(int *fd, int *pid, const char *hostname)
-{
- int pipes[2], res;
- struct in_addr a;
- int errno2;
-
- gg_debug(GG_DEBUG_FUNCTION, "** gg_resolve(%p, %p, \"%s\");\n", fd, pid, hostname);
-
- if (!fd || !pid) {
- errno = EFAULT;
- return -1;
- }
-
- if (pipe(pipes) == -1)
- return -1;
-
- if ((res = fork()) == -1) {
- errno2 = errno;
- close(pipes[0]);
- close(pipes[1]);
- errno = errno2;
- return -1;
- }
-
- if (!res) {
- close(pipes[0]);
-
- if ((a.s_addr = inet_addr(hostname)) == INADDR_NONE) {
- struct in_addr *hn;
-
- if (!(hn = gg_gethostbyname(hostname)))
- a.s_addr = INADDR_NONE;
- else {
- a.s_addr = hn->s_addr;
- free(hn);
- }
- }
-
- write(pipes[1], &a, sizeof(a));
-
- exit(0);
- }
-
- close(pipes[1]);
-
- *fd = pipes[0];
- *pid = res;
-
- return 0;
-}
-
-#ifdef __GG_LIBGADU_HAVE_PTHREAD
-
-struct gg_resolve_pthread_data {
- char *hostname;
- int fd;
-};
-
-static void *gg_resolve_pthread_thread(void *arg)
-{
- struct gg_resolve_pthread_data *d = arg;
- struct in_addr a;
-
- pthread_detach(pthread_self());
-
- if ((a.s_addr = inet_addr(d->hostname)) == INADDR_NONE) {
- struct in_addr *hn;
-
- if (!(hn = gg_gethostbyname(d->hostname)))
- a.s_addr = INADDR_NONE;
- else {
- a.s_addr = hn->s_addr;
- free(hn);
- }
- }
-
- write(d->fd, &a, sizeof(a));
- close(d->fd);
-
- free(d->hostname);
- d->hostname = NULL;
-
- free(d);
-
- pthread_exit(NULL);
-
- return NULL; /* ¿eby kompilator nie marudzi³ */
-}
-
-/*
- * gg_resolve_pthread() // funkcja wewnêtrzna
- *
- * tworzy potok, nowy w±tek i w nim zaczyna resolvowaæ podanego hosta.
- * zapisuje w sesji deskryptor potoku. je¶li co¶ tam bêdzie gotowego,
- * znaczy, ¿e mo¿na wczytaæ struct in_addr. je¶li nie znajdzie, zwraca
- * INADDR_NONE.
- *
- * - fd - wska¼nik do zmiennej przechowuj±cej desktyptor resolvera
- * - resolver - wska¼nik do wska¼nika resolvera
- * - hostname - nazwa hosta do zresolvowania
- *
- * 0, -1.
- */
-int gg_resolve_pthread(int *fd, void **resolver, const char *hostname)
-{
- struct gg_resolve_pthread_data *d = NULL;
- pthread_t *tmp;
- int pipes[2], new_errno;
-
- gg_debug(GG_DEBUG_FUNCTION, "** gg_resolve_pthread(%p, %p, \"%s\");\n", fd, resolver, hostname);
-
- if (!resolver || !fd || !hostname) {
- gg_debug(GG_DEBUG_MISC, "// gg_resolve_pthread() invalid arguments\n");
- errno = EFAULT;
- return -1;
- }
-
- if (!(tmp = malloc(sizeof(pthread_t)))) {
- gg_debug(GG_DEBUG_MISC, "// gg_resolve_pthread() out of memory for pthread id\n");
- return -1;
- }
-
- if (pipe(pipes) == -1) {
- gg_debug(GG_DEBUG_MISC, "// gg_resolve_pthread() unable to create pipes (errno=%d, %s)\n", errno, strerror(errno));
- free(tmp);
- return -1;
- }
-
- if (!(d = malloc(sizeof(*d)))) {
- gg_debug(GG_DEBUG_MISC, "// gg_resolve_pthread() out of memory\n");
- new_errno = errno;
- goto cleanup;
- }
-
- d->hostname = NULL;
-
- if (!(d->hostname = strdup(hostname))) {
- gg_debug(GG_DEBUG_MISC, "// gg_resolve_pthread() out of memory\n");
- new_errno = errno;
- goto cleanup;
- }
-
- d->fd = pipes[1];
-
- if (pthread_create(tmp, NULL, gg_resolve_pthread_thread, d)) {
- gg_debug(GG_DEBUG_MISC, "// gg_resolve_phread() unable to create thread\n");
- new_errno = errno;
- goto cleanup;
- }
-
- gg_debug(GG_DEBUG_MISC, "// gg_resolve_pthread() %p\n", tmp);
-
- *resolver = tmp;
-
- *fd = pipes[0];
-
- return 0;
-
-cleanup:
- if (d) {
- free(d->hostname);
- free(d);
- }
-
- close(pipes[0]);
- close(pipes[1]);
-
- free(tmp);
-
- errno = new_errno;
-
- return -1;
-}
-
-#endif
-
-/*
- * gg_read() // funkcja pomocnicza
- *
- * czyta z gniazda okre¶lon± ilo¶æ bajtów. bierze pod uwagê, czy mamy
- * po³±czenie zwyk³e czy TLS.
- *
- * - sess - sesja,
- * - buf - bufor,
- * - length - ilo¶æ bajtów,
- *
- * takie same warto¶ci jak read().
- */
-int gg_read(struct gg_session *sess, char *buf, int length)
-{
- int res;
-
-#ifdef __GG_LIBGADU_HAVE_OPENSSL
- if (sess->ssl) {
- int err;
-
- res = SSL_read(sess->ssl, buf, length);
-
- if (res < 0) {
- err = SSL_get_error(sess->ssl, res);
-
- if (err == SSL_ERROR_WANT_READ)
- errno = EAGAIN;
-
- return -1;
- }
- } else
-#endif
- res = read(sess->fd, buf, length);
-
- return res;
-}
-
-/*
- * gg_write() // funkcja pomocnicza
- *
- * zapisuje do gniazda okre¶lon± ilo¶æ bajtów. bierze pod uwagê, czy mamy
- * po³±czenie zwyk³e czy TLS.
- *
- * - sess - sesja,
- * - buf - bufor,
- * - length - ilo¶æ bajtów,
- *
- * takie same warto¶ci jak write().
- */
-int gg_write(struct gg_session *sess, const char *buf, int length)
-{
- int res = 0;
-
-#ifdef __GG_LIBGADU_HAVE_OPENSSL
- if (sess->ssl) {
- int err;
-
- res = SSL_write(sess->ssl, buf, length);
-
- if (res < 0) {
- err = SSL_get_error(sess->ssl, res);
-
- if (err == SSL_ERROR_WANT_WRITE)
- errno = EAGAIN;
-
- return -1;
- }
- } else
-#endif
- {
- int written = 0;
-
- while (written < length) {
- res = write(sess->fd, buf + written, length - written);
-
- if (res == -1) {
- if (errno == EAGAIN)
- continue;
- else
- break;
- } else {
- written += res;
- res = written;
- }
- }
- }
-
- return res;
-}
-
-/*
- * gg_recv_packet() // funkcja wewnêtrzna
- *
- * odbiera jeden pakiet i zwraca wska¼nik do niego. pamiêæ po nim
- * nale¿y zwolniæ za pomoc± free().
- *
- * - sess - opis sesji
- *
- * w przypadku b³êdu NULL, kod b³êdu w errno. nale¿y zwróciæ uwagê, ¿e gdy
- * po³±czenie jest nieblokuj±ce, a kod b³êdu wynosi EAGAIN, nie uda³o siê
- * odczytaæ ca³ego pakietu i nie nale¿y tego traktowaæ jako b³±d.
- */
-void *gg_recv_packet(struct gg_session *sess)
-{
- struct gg_header h;
- char *buf = NULL;
- int ret = 0;
- unsigned int offset, size = 0;
-
- gg_debug(GG_DEBUG_FUNCTION, "** gg_recv_packet(%p);\n", sess);
-
- if (!sess) {
- errno = EFAULT;
- return NULL;
- }
-
- if (sess->recv_left < 1) {
- if (sess->header_buf) {
- memcpy(&h, sess->header_buf, sess->header_done);
- gg_debug(GG_DEBUG_MISC, "// gg_recv_packet() header recv: resuming last read (%d bytes left)\n", sizeof(h) - sess->header_done);
- free(sess->header_buf);
- sess->header_buf = NULL;
- } else
- sess->header_done = 0;
-
- while (sess->header_done < sizeof(h)) {
- ret = gg_read(sess, (char*) &h + sess->header_done, sizeof(h) - sess->header_done);
-
- gg_debug(GG_DEBUG_MISC, "// gg_recv_packet() header recv(%d,%p,%d) = %d\n", sess->fd, &h + sess->header_done, sizeof(h) - sess->header_done, ret);
-
- if (!ret) {
- errno = ECONNRESET;
- gg_debug(GG_DEBUG_MISC, "// gg_recv_packet() header recv() failed: connection broken\n");
- return NULL;
- }
-
- if (ret == -1) {
- if (errno == EINTR) {
- gg_debug(GG_DEBUG_MISC, "// gg_recv_packet() header recv() interrupted system call, resuming\n");
- continue;
- }
-
- if (errno == EAGAIN) {
- gg_debug(GG_DEBUG_MISC, "// gg_recv_packet() header recv() incomplete header received\n");
-
- if (!(sess->header_buf = malloc(sess->header_done))) {
- gg_debug(GG_DEBUG_MISC, "// gg_recv_packet() header recv() not enough memory\n");
- return NULL;
- }
-
- memcpy(sess->header_buf, &h, sess->header_done);
-
- return NULL;
- }
-
- gg_debug(GG_DEBUG_MISC, "// gg_recv_packet() header recv() failed: errno=%d, %s\n", errno, strerror(errno));
-
- return NULL;
- }
-
- sess->header_done += ret;
-
- }
-
- h.type = gg_fix32(h.type);
- h.length = gg_fix32(h.length);
- } else
- memcpy(&h, sess->recv_buf, sizeof(h));
-
- /* jakie¶ sensowne limity na rozmiar pakietu */
- if (h.length > 65535) {
- gg_debug(GG_DEBUG_MISC, "// gg_recv_packet() invalid packet length (%d)\n", h.length);
- errno = ERANGE;
- return NULL;
- }
-
- if (sess->recv_left > 0) {
- gg_debug(GG_DEBUG_MISC, "// gg_recv_packet() resuming last gg_recv_packet()\n");
- size = sess->recv_left;
- offset = sess->recv_done;
- buf = sess->recv_buf;
- } else {
- if (!(buf = malloc(sizeof(h) + h.length + 1))) {
- gg_debug(GG_DEBUG_MISC, "// gg_recv_packet() not enough memory for packet data\n");
- return NULL;
- }
-
- memcpy(buf, &h, sizeof(h));
-
- offset = 0;
- size = h.length;
- }
-
- while (size > 0) {
- ret = gg_read(sess, buf + sizeof(h) + offset, size);
- gg_debug(GG_DEBUG_MISC, "// gg_recv_packet() body recv(%d,%p,%d) = %d\n", sess->fd, buf + sizeof(h) + offset, size, ret);
- if (!ret) {
- gg_debug(GG_DEBUG_MISC, "// gg_recv_packet() body recv() failed: connection broken\n");
- errno = ECONNRESET;
- return NULL;
- }
- if (ret > -1 && ret <= size) {
- offset += ret;
- size -= ret;
- } else if (ret == -1) {
- int errno2 = errno;
-
- gg_debug(GG_DEBUG_MISC, "// gg_recv_packet() body recv() failed (errno=%d, %s)\n", errno, strerror(errno));
- errno = errno2;
-
- if (errno == EAGAIN) {
- gg_debug(GG_DEBUG_MISC, "// gg_recv_packet() %d bytes received, %d left\n", offset, size);
- sess->recv_buf = buf;
- sess->recv_left = size;
- sess->recv_done = offset;
- return NULL;
- }
- if (errno != EINTR) {
- free(buf);
- return NULL;
- }
- }
- }
-
- sess->recv_left = 0;
-
- if ((gg_debug_level & GG_DEBUG_DUMP)) {
- unsigned int i;
-
- gg_debug(GG_DEBUG_DUMP, "// gg_recv_packet(%.2x)", h.type);
- for (i = 0; i < sizeof(h) + h.length; i++)
- gg_debug(GG_DEBUG_DUMP, " %.2x", (unsigned char) buf[i]);
- gg_debug(GG_DEBUG_DUMP, "\n");
- }
-
- return buf;
-}
-
-/*
- * gg_send_packet() // funkcja wewnêtrzna
- *
- * konstruuje pakiet i wysy³a go do serwera.
- *
- * - sock - deskryptor gniazda
- * - type - typ pakietu
- * - payload_1 - pierwsza czê¶æ pakietu
- * - payload_length_1 - d³ugo¶æ pierwszej czê¶ci
- * - payload_2 - druga czê¶æ pakietu
- * - payload_length_2 - d³ugo¶æ drugiej czê¶ci
- * - ... - kolejne czê¶ci pakietu i ich d³ugo¶ci
- * - NULL - koñcowym parametr (konieczny!)
- *
- * je¶li siê powiod³o, zwraca 0, w przypadku b³êdu -1. je¶li errno == ENOMEM,
- * zabrak³o pamiêci. inaczej by³ b³±d przy wysy³aniu pakietu. dla errno == 0
- * nie wys³ano ca³ego pakietu.
- */
-int gg_send_packet(struct gg_session *sess, int type, ...)
-{
- struct gg_header *h;
- char *tmp;
- unsigned int tmp_length;
- void *payload;
- unsigned int payload_length;
- va_list ap;
- int res;
-
- gg_debug(GG_DEBUG_FUNCTION, "** gg_send_packet(%p, 0x%.2x, ...)\n", sess, type);
-
- tmp_length = sizeof(struct gg_header);
-
- if (!(tmp = malloc(tmp_length))) {
- gg_debug(GG_DEBUG_MISC, "// gg_send_packet() not enough memory for packet header\n");
- return -1;
- }
-
- va_start(ap, type);
-
- payload = va_arg(ap, void *);
-
- while (payload) {
- char *tmp2;
-
- payload_length = va_arg(ap, unsigned int);
-
- if (!(tmp2 = realloc(tmp, tmp_length + payload_length))) {
- gg_debug(GG_DEBUG_MISC, "// gg_send_packet() not enough memory for payload\n");
- free(tmp);
- va_end(ap);
- return -1;
- }
-
- tmp = tmp2;
-
- memcpy(tmp + tmp_length, payload, payload_length);
- tmp_length += payload_length;
-
- payload = va_arg(ap, void *);
- }
-
- va_end(ap);
-
- h = (struct gg_header*) tmp;
- h->type = gg_fix32(type);
- h->length = gg_fix32(tmp_length - sizeof(struct gg_header));
-
- if ((gg_debug_level & GG_DEBUG_DUMP)) {
- unsigned int i;
-
- gg_debug(GG_DEBUG_DUMP, "// gg_send_packet(0x%.2x)", gg_fix32(h->type));
- for (i = 0; i < tmp_length; ++i)
- gg_debug(GG_DEBUG_DUMP, " %.2x", (unsigned char) tmp[i]);
- gg_debug(GG_DEBUG_DUMP, "\n");
- }
-
- if ((res = gg_write(sess, tmp, tmp_length)) < tmp_length) {
- gg_debug(GG_DEBUG_MISC, "// gg_send_packet() write() failed. res = %d, errno = %d (%s)\n", res, errno, strerror(errno));
- free(tmp);
- return -1;
- }
-
- free(tmp);
- return 0;
-}
-
-/*
- * gg_session_callback() // funkcja wewnêtrzna
- *
- * wywo³ywany z gg_session->callback, wykonuje gg_watch_fd() i pakuje
- * do gg_session->event jego wynik.
- */
-static int gg_session_callback(struct gg_session *s)
-{
- if (!s) {
- errno = EFAULT;
- return -1;
- }
-
- return ((s->event = gg_watch_fd(s)) != NULL) ? 0 : -1;
-}
-
-/*
- * gg_login()
- *
- * rozpoczyna procedurê ³±czenia siê z serwerem. resztê obs³uguje siê przez
- * gg_watch_fd().
- *
- * UWAGA! program musi obs³u¿yæ SIGCHLD, je¶li ³±czy siê asynchronicznie,
- * ¿eby poprawnie zamkn±æ proces resolvera.
- *
- * - p - struktura opisuj±ca pocz±tkowy stan. wymagane pola: uin,
- * password
- *
- * w przypadku b³êdu NULL, je¶li idzie dobrze (async) albo posz³o
- * dobrze (sync), zwróci wska¼nik do zaalokowanej struct gg_session.
- */
-struct gg_session *gg_login(const struct gg_login_params *p)
-{
- struct gg_session *sess = NULL;
- char *hostname;
- int port;
-
- if (!p) {
- gg_debug(GG_DEBUG_FUNCTION, "** gg_login(%p);\n", p);
- errno = EFAULT;
- return NULL;
- }
-
- gg_debug(GG_DEBUG_FUNCTION, "** gg_login(%p: [uin=%u, async=%d, ...]);\n", p, p->uin, p->async);
-
- if (!(sess = malloc(sizeof(struct gg_session)))) {
- gg_debug(GG_DEBUG_MISC, "// gg_login() not enough memory for session data\n");
- goto fail;
- }
-
- memset(sess, 0, sizeof(struct gg_session));
-
- if (!p->password || !p->uin) {
- gg_debug(GG_DEBUG_MISC, "// gg_login() invalid arguments. uin and password needed\n");
- errno = EFAULT;
- goto fail;
- }
-
- if (!(sess->password = strdup(p->password))) {
- gg_debug(GG_DEBUG_MISC, "// gg_login() not enough memory for password\n");
- goto fail;
- }
-
- if (p->status_descr && !(sess->initial_descr = strdup(p->status_descr))) {
- gg_debug(GG_DEBUG_MISC, "// gg_login() not enough memory for status\n");
- goto fail;
- }
-
- sess->uin = p->uin;
- sess->state = GG_STATE_RESOLVING;
- sess->check = GG_CHECK_READ;
- sess->timeout = GG_DEFAULT_TIMEOUT;
- sess->async = p->async;
- sess->type = GG_SESSION_GG;
- sess->initial_status = p->status;
- sess->callback = gg_session_callback;
- sess->destroy = gg_free_session;
- sess->port = (p->server_port) ? p->server_port : ((gg_proxy_enabled) ? GG_HTTPS_PORT : GG_DEFAULT_PORT);
- sess->server_addr = p->server_addr;
- sess->external_port = p->external_port;
- sess->external_addr = p->external_addr;
- sess->protocol_version = (p->protocol_version) ? p->protocol_version : GG_DEFAULT_PROTOCOL_VERSION;
- if (p->era_omnix)
- sess->protocol_version |= GG_ERA_OMNIX_MASK;
- if (p->has_audio)
- sess->protocol_version |= GG_HAS_AUDIO_MASK;
- sess->client_version = (p->client_version) ? strdup(p->client_version) : NULL;
- sess->last_sysmsg = p->last_sysmsg;
- sess->image_size = p->image_size;
- sess->pid = -1;
-
- if (p->tls == 1) {
-#ifdef __GG_LIBGADU_HAVE_OPENSSL
- char buf[1024];
-
- OpenSSL_add_ssl_algorithms();
-
- if (!RAND_status()) {
- char rdata[1024];
- struct {
- time_t time;
- void *ptr;
- } rstruct;
-
- time(&rstruct.time);
- rstruct.ptr = (void *) &rstruct;
-
- RAND_seed((void *) rdata, sizeof(rdata));
- RAND_seed((void *) &rstruct, sizeof(rstruct));
- }
-
- sess->ssl_ctx = SSL_CTX_new(TLSv1_client_method());
-
- if (!sess->ssl_ctx) {
- ERR_error_string_n(ERR_get_error(), buf, sizeof(buf));
- gg_debug(GG_DEBUG_MISC, "// gg_login() SSL_CTX_new() failed: %s\n", buf);
- goto fail;
- }
-
- SSL_CTX_set_verify(sess->ssl_ctx, SSL_VERIFY_NONE, NULL);
-
- sess->ssl = SSL_new(sess->ssl_ctx);
-
- if (!sess->ssl) {
- ERR_error_string_n(ERR_get_error(), buf, sizeof(buf));
- gg_debug(GG_DEBUG_MISC, "// gg_login() SSL_new() failed: %s\n", buf);
- goto fail;
- }
-#else
- gg_debug(GG_DEBUG_MISC, "// gg_login() client requested TLS but no support compiled in\n");
-#endif
- }
-
- if (gg_proxy_enabled) {
- hostname = gg_proxy_host;
- sess->proxy_port = port = gg_proxy_port;
- } else {
- hostname = GG_APPMSG_HOST;
- port = GG_APPMSG_PORT;
- }
-
- if (!p->async) {
- struct in_addr a;
-
- if (!p->server_addr || !p->server_port) {
- if ((a.s_addr = inet_addr(hostname)) == INADDR_NONE) {
- struct in_addr *hn;
-
- if (!(hn = gg_gethostbyname(hostname))) {
- gg_debug(GG_DEBUG_MISC, "// gg_login() host \"%s\" not found\n", hostname);
- goto fail;
- } else {
- a.s_addr = hn->s_addr;
- free(hn);
- }
- }
- } else {
- a.s_addr = p->server_addr;
- port = p->server_port;
- }
-
- sess->hub_addr = a.s_addr;
-
- if (gg_proxy_enabled)
- sess->proxy_addr = a.s_addr;
-
- if ((sess->fd = gg_connect(&a, port, 0)) == -1) {
- gg_debug(GG_DEBUG_MISC, "// gg_login() connection failed (errno=%d, %s)\n", errno, strerror(errno));
- goto fail;
- }
-
- if (p->server_addr && p->server_port)
- sess->state = GG_STATE_CONNECTING_GG;
- else
- sess->state = GG_STATE_CONNECTING_HUB;
-
- while (sess->state != GG_STATE_CONNECTED) {
- struct gg_event *e;
-
- if (!(e = gg_watch_fd(sess))) {
- gg_debug(GG_DEBUG_MISC, "// gg_login() critical error in gg_watch_fd()\n");
- goto fail;
- }
-
- if (e->type == GG_EVENT_CONN_FAILED) {
- errno = EACCES;
- gg_debug(GG_DEBUG_MISC, "// gg_login() could not login\n");
- gg_event_free(e);
- goto fail;
- }
-
- gg_event_free(e);
- }
-
- return sess;
- }
-
- if (!sess->server_addr || gg_proxy_enabled) {
-#ifndef __GG_LIBGADU_HAVE_PTHREAD
- if (gg_resolve(&sess->fd, &sess->pid, hostname)) {
-#else
- if (gg_resolve_pthread(&sess->fd, &sess->resolver, hostname)) {
-#endif
- gg_debug(GG_DEBUG_MISC, "// gg_login() resolving failed (errno=%d, %s)\n", errno, strerror(errno));
- goto fail;
- }
- } else {
- if ((sess->fd = gg_connect(&sess->server_addr, sess->port, sess->async)) == -1) {
- gg_debug(GG_DEBUG_MISC, "// gg_login() direct connection failed (errno=%d, %s)\n", errno, strerror(errno));
- goto fail;
- }
- sess->state = GG_STATE_CONNECTING_GG;
- sess->check = GG_CHECK_WRITE;
- }
-
- return sess;
-
-fail:
- if (sess) {
- if (sess->password)
- free(sess->password);
- if (sess->initial_descr)
- free(sess->initial_descr);
- free(sess);
- }
-
- return NULL;
-}
-
-/*
- * gg_free_session()
- *
- * próbuje zamkn±æ po³±czenia i zwalnia pamiêæ zajmowan± przez sesjê.
- *
- * - sess - opis sesji
- */
-void gg_free_session(struct gg_session *sess)
-{
- if (!sess)
- return;
-
- /* XXX dopisaæ zwalnianie i zamykanie wszystkiego, co mog³o zostaæ */
-
- if (sess->password)
- free(sess->password);
-
- if (sess->initial_descr)
- free(sess->initial_descr);
-
- if (sess->client_version)
- free(sess->client_version);
-
- if (sess->header_buf)
- free(sess->header_buf);
-
-#ifdef __GG_LIBGADU_HAVE_OPENSSL
- if (sess->ssl)
- SSL_free(sess->ssl);
-
- if (sess->ssl_ctx)
- SSL_CTX_free(sess->ssl_ctx);
-#endif
-
-#ifdef __GG_LIBGADU_HAVE_PTHREAD
- if (sess->resolver) {
- pthread_cancel(*((pthread_t*) sess->resolver));
- free(sess->resolver);
- sess->resolver = NULL;
- }
-#else
- if (sess->pid != -1) {
- kill(sess->pid, SIGTERM);
- waitpid(sess->pid, NULL, WNOHANG);
- }
-#endif
-
- if (sess->fd != -1)
- close(sess->fd);
-
- while (sess->images)
- gg_image_queue_remove(sess, sess->images, 1);
-
- free(sess);
-}
-
-/*
- * gg_change_status()
- *
- * zmienia status u¿ytkownika. przydatne do /away i /busy oraz /quit.
- *
- * - sess - opis sesji
- * - status - nowy status u¿ytkownika
- *
- * 0, -1.
- */
-int gg_change_status(struct gg_session *sess, int status)
-{
- struct gg_new_status p;
-
- gg_debug(GG_DEBUG_FUNCTION, "** gg_change_status(%p, %d);\n", sess, status);
-
- if (!sess) {
- errno = EFAULT;
- return -1;
- }
-
- if (sess->state != GG_STATE_CONNECTED) {
- errno = ENOTCONN;
- return -1;
- }
-
- p.status = gg_fix32(status);
-
- sess->status = status;
-
- return gg_send_packet(sess, GG_NEW_STATUS, &p, sizeof(p), NULL);
-}
-
-/*
- * gg_change_status_descr()
- *
- * zmienia status u¿ytkownika na opisowy.
- *
- * - sess - opis sesji
- * - status - nowy status u¿ytkownika
- * - descr - opis statusu
- *
- * 0, -1.
- */
-int gg_change_status_descr(struct gg_session *sess, int status, const char *descr)
-{
- struct gg_new_status p;
-
- gg_debug(GG_DEBUG_FUNCTION, "** gg_change_status_descr(%p, %d, \"%s\");\n", sess, status, descr);
-
- if (!sess || !descr) {
- errno = EFAULT;
- return -1;
- }
-
- if (sess->state != GG_STATE_CONNECTED) {
- errno = ENOTCONN;
- return -1;
- }
-
- p.status = gg_fix32(status);
-
- sess->status = status;
-
- return gg_send_packet(sess, GG_NEW_STATUS, &p, sizeof(p), descr, (strlen(descr) > GG_STATUS_DESCR_MAXSIZE) ? GG_STATUS_DESCR_MAXSIZE : strlen(descr), NULL);
-}
-
-/*
- * gg_change_status_descr_time()
- *
- * zmienia status u¿ytkownika na opisowy z godzin± powrotu.
- *
- * - sess - opis sesji
- * - status - nowy status u¿ytkownika
- * - descr - opis statusu
- * - time - czas w formacie uniksowym
- *
- * 0, -1.
- */
-int gg_change_status_descr_time(struct gg_session *sess, int status, const char *descr, int time)
-{
- struct gg_new_status p;
- uint32_t newtime;
-
- gg_debug(GG_DEBUG_FUNCTION, "** gg_change_status_descr_time(%p, %d, \"%s\", %d);\n", sess, status, descr, time);
-
- if (!sess || !descr || !time) {
- errno = EFAULT;
- return -1;
- }
-
- if (sess->state != GG_STATE_CONNECTED) {
- errno = ENOTCONN;
- return -1;
- }
-
- p.status = gg_fix32(status);
-
- sess->status = status;
-
- newtime = gg_fix32(time);
-
- return gg_send_packet(sess, GG_NEW_STATUS, &p, sizeof(p), descr, (strlen(descr) > GG_STATUS_DESCR_MAXSIZE) ? GG_STATUS_DESCR_MAXSIZE : strlen(descr), &newtime, sizeof(newtime), NULL);
-}
-
-/*
- * gg_logoff()
- *
- * wylogowuje u¿ytkownika i zamyka po³±czenie, ale nie zwalnia pamiêci.
- *
- * - sess - opis sesji
- */
-void gg_logoff(struct gg_session *sess)
-{
- if (!sess)
- return;
-
- gg_debug(GG_DEBUG_FUNCTION, "** gg_logoff(%p);\n", sess);
-
- if (GG_S_NA(sess->status & ~GG_STATUS_FRIENDS_MASK))
- gg_change_status(sess, GG_STATUS_NOT_AVAIL);
-
-#ifdef __GG_LIBGADU_HAVE_OPENSSL
- if (sess->ssl)
- SSL_shutdown(sess->ssl);
-#endif
-
-#ifdef __GG_LIBGADU_HAVE_PTHREAD
- if (sess->resolver) {
- pthread_cancel(*((pthread_t*) sess->resolver));
- free(sess->resolver);
- sess->resolver = NULL;
- }
-#else
- if (sess->pid != -1) {
- kill(sess->pid, SIGTERM);
- waitpid(sess->pid, NULL, WNOHANG);
- sess->pid = -1;
- }
-#endif
-
- if (sess->fd != -1) {
- shutdown(sess->fd, SHUT_RDWR);
- close(sess->fd);
- sess->fd = -1;
- }
-}
-
-/*
- * gg_image_request()
- *
- * wysy³a ¿±danie wys³ania obrazka o podanych parametrach.
- *
- * - sess - opis sesji
- * - recipient - numer adresata
- * - size - rozmiar obrazka
- * - crc32 - suma kontrolna obrazka
- *
- * 0/-1
- */
-int gg_image_request(struct gg_session *sess, uin_t recipient, int size, uint32_t crc32)
-{
- struct gg_send_msg s;
- struct gg_msg_image_request r;
- char dummy = 0;
- int res;
-
- gg_debug(GG_DEBUG_FUNCTION, "** gg_image_request(%p, %d, %u, 0x%.4x);\n", sess, recipient, size, crc32);
-
- if (!sess) {
- errno = EFAULT;
- return -1;
- }
-
- if (sess->state != GG_STATE_CONNECTED) {
- errno = ENOTCONN;
- return -1;
- }
-
- if (size < 0) {
- errno = EINVAL;
- return -1;
- }
-
- s.recipient = gg_fix32(recipient);
- s.seq = gg_fix32(0);
- s.msgclass = gg_fix32(GG_CLASS_MSG);
-
- r.flag = 0x04;
- r.size = gg_fix32(size);
- r.crc32 = gg_fix32(crc32);
-
- res = gg_send_packet(sess, GG_SEND_MSG, &s, sizeof(s), &dummy, 1, &r, sizeof(r), NULL);
-
- if (!res) {
- struct gg_image_queue *q = malloc(sizeof(*q));
- char *buf;
-
- if (!q) {
- gg_debug(GG_DEBUG_MISC, "// gg_image_request() not enough memory for image queue\n");
- return -1;
- }
-
- buf = malloc(size);
- if (size && !buf)
- {
- gg_debug(GG_DEBUG_MISC, "// gg_image_request() not enough memory for image\n");
- free(q);
- return -1;
- }
-
- memset(q, 0, sizeof(*q));
-
- q->sender = recipient;
- q->size = size;
- q->crc32 = crc32;
- q->image = buf;
-
- if (!sess->images)
- sess->images = q;
- else {
- struct gg_image_queue *qq;
-
- for (qq = sess->images; qq->next; qq = qq->next)
- ;
-
- qq->next = q;
- }
- }
-
- return res;
-}
-
-/*
- * gg_image_reply()
- *
- * wysy³a ¿±dany obrazek.
- *
- * - sess - opis sesji
- * - recipient - numer adresata
- * - filename - nazwa pliku
- * - image - bufor z obrazkiem
- * - size - rozmiar obrazka
- *
- * 0/-1
- */
-int gg_image_reply(struct gg_session *sess, uin_t recipient, const char *filename, const char *image, int size)
-{
- struct gg_msg_image_reply *r;
- struct gg_send_msg s;
- const char *tmp;
- char buf[1910];
- int res = -1;
-
- gg_debug(GG_DEBUG_FUNCTION, "** gg_image_reply(%p, %d, \"%s\", %p, %d);\n", sess, recipient, filename, image, size);
-
- if (!sess || !filename || !image) {
- errno = EFAULT;
- return -1;
- }
-
- if (sess->state != GG_STATE_CONNECTED) {
- errno = ENOTCONN;
- return -1;
- }
-
- if (size < 0) {
- errno = EINVAL;
- return -1;
- }
-
- /* wytnij ¶cie¿ki, zostaw tylko nazwê pliku */
- while ((tmp = strrchr(filename, '/')) || (tmp = strrchr(filename, '\\')))
- filename = tmp + 1;
-
- if (strlen(filename) < 1 || strlen(filename) > 1024) {
- errno = EINVAL;
- return -1;
- }
-
- s.recipient = gg_fix32(recipient);
- s.seq = gg_fix32(0);
- s.msgclass = gg_fix32(GG_CLASS_MSG);
-
- buf[0] = 0;
- r = (void*) &buf[1];
-
- r->flag = 0x05;
- r->size = gg_fix32(size);
- r->crc32 = gg_fix32(gg_crc32(0, image, size));
-
- while (size > 0) {
- int buflen, chunklen;
-
- /* \0 + struct gg_msg_image_reply */
- buflen = sizeof(struct gg_msg_image_reply) + 1;
-
- /* w pierwszym kawa³ku jest nazwa pliku */
- if (r->flag == 0x05) {
- strcpy(buf + buflen, filename);
- buflen += strlen(filename) + 1;
- }
-
- chunklen = (size >= sizeof(buf) - buflen) ? (sizeof(buf) - buflen) : size;
-
- memcpy(buf + buflen, image, chunklen);
- size -= chunklen;
- image += chunklen;
-
- res = gg_send_packet(sess, GG_SEND_MSG, &s, sizeof(s), buf, buflen + chunklen, NULL);
-
- if (res == -1)
- break;
-
- r->flag = 0x06;
- }
-
- return res;
-}
-
-/*
- * gg_send_message_ctcp()
- *
- * wysy³a wiadomo¶æ do innego u¿ytkownika. zwraca losowy numer
- * sekwencyjny, który mo¿na zignorowaæ albo wykorzystaæ do potwierdzenia.
- *
- * - sess - opis sesji
- * - msgclass - rodzaj wiadomo¶ci
- * - recipient - numer adresata
- * - message - tre¶æ wiadomo¶ci
- * - message_len - d³ugo¶æ
- *
- * numer sekwencyjny wiadomo¶ci lub -1 w przypadku b³êdu.
- */
-int gg_send_message_ctcp(struct gg_session *sess, int msgclass, uin_t recipient, const unsigned char *message, int message_len)
-{
- struct gg_send_msg s;
-
- gg_debug(GG_DEBUG_FUNCTION, "** gg_send_message_ctcp(%p, %d, %u, ...);\n", sess, msgclass, recipient);
-
- if (!sess) {
- errno = EFAULT;
- return -1;
- }
-
- if (sess->state != GG_STATE_CONNECTED) {
- errno = ENOTCONN;
- return -1;
- }
-
- s.recipient = gg_fix32(recipient);
- s.seq = gg_fix32(0);
- s.msgclass = gg_fix32(msgclass);
-
- return gg_send_packet(sess, GG_SEND_MSG, &s, sizeof(s), message, message_len, NULL);
-}
-
-/*
- * gg_send_message()
- *
- * wysy³a wiadomo¶æ do innego u¿ytkownika. zwraca losowy numer
- * sekwencyjny, który mo¿na zignorowaæ albo wykorzystaæ do potwierdzenia.
- *
- * - sess - opis sesji
- * - msgclass - rodzaj wiadomo¶ci
- * - recipient - numer adresata
- * - message - tre¶æ wiadomo¶ci
- *
- * numer sekwencyjny wiadomo¶ci lub -1 w przypadku b³êdu.
- */
-int gg_send_message(struct gg_session *sess, int msgclass, uin_t recipient, const unsigned char *message)
-{
- gg_debug(GG_DEBUG_FUNCTION, "** gg_send_message(%p, %d, %u, %p)\n", sess, msgclass, recipient, message);
-
- return gg_send_message_richtext(sess, msgclass, recipient, message, NULL, 0);
-}
-
-/*
- * gg_send_message_richtext()
- *
- * wysy³a kolorow± wiadomo¶æ do innego u¿ytkownika. zwraca losowy numer
- * sekwencyjny, który mo¿na zignorowaæ albo wykorzystaæ do potwierdzenia.
- *
- * - sess - opis sesji
- * - msgclass - rodzaj wiadomo¶ci
- * - recipient - numer adresata
- * - message - tre¶æ wiadomo¶ci
- * - format - informacje o formatowaniu
- * - formatlen - d³ugo¶æ informacji o formatowaniu
- *
- * numer sekwencyjny wiadomo¶ci lub -1 w przypadku b³êdu.
- */
-int gg_send_message_richtext(struct gg_session *sess, int msgclass, uin_t recipient, const unsigned char *message, const unsigned char *format, int formatlen)
-{
- struct gg_send_msg s;
-
- gg_debug(GG_DEBUG_FUNCTION, "** gg_send_message_richtext(%p, %d, %u, %p, %p, %d);\n", sess, msgclass, recipient, message, format, formatlen);
-
- if (!sess) {
- errno = EFAULT;
- return -1;
- }
-
- if (sess->state != GG_STATE_CONNECTED) {
- errno = ENOTCONN;
- return -1;
- }
-
- if (!message) {
- errno = EFAULT;
- return -1;
- }
-
- s.recipient = gg_fix32(recipient);
- if (!sess->seq)
- sess->seq = 0x01740000 | (rand() & 0xffff);
- s.seq = gg_fix32(sess->seq);
- s.msgclass = gg_fix32(msgclass);
- sess->seq += (rand() % 0x300) + 0x300;
-
- if (gg_send_packet(sess, GG_SEND_MSG, &s, sizeof(s), message, strlen(message) + 1, format, formatlen, NULL) == -1)
- return -1;
-
- return gg_fix32(s.seq);
-}
-
-/*
- * gg_send_message_confer()
- *
- * wysy³a wiadomo¶æ do kilku u¿ytkownikow (konferencja). zwraca losowy numer
- * sekwencyjny, który mo¿na zignorowaæ albo wykorzystaæ do potwierdzenia.
- *
- * - sess - opis sesji
- * - msgclass - rodzaj wiadomo¶ci
- * - recipients_count - ilo¶æ adresatów
- * - recipients - numerki adresatów
- * - message - tre¶æ wiadomo¶ci
- *
- * numer sekwencyjny wiadomo¶ci lub -1 w przypadku b³êdu.
- */
-int gg_send_message_confer(struct gg_session *sess, int msgclass, int recipients_count, uin_t *recipients, const unsigned char *message)
-{
- gg_debug(GG_DEBUG_FUNCTION, "** gg_send_message_confer(%p, %d, %d, %p, %p);\n", sess, msgclass, recipients_count, recipients, message);
-
- return gg_send_message_confer_richtext(sess, msgclass, recipients_count, recipients, message, NULL, 0);
-}
-
-/*
- * gg_send_message_confer_richtext()
- *
- * wysy³a kolorow± wiadomo¶æ do kilku u¿ytkownikow (konferencja). zwraca
- * losowy numer sekwencyjny, który mo¿na zignorowaæ albo wykorzystaæ do
- * potwierdzenia.
- *
- * - sess - opis sesji
- * - msgclass - rodzaj wiadomo¶ci
- * - recipients_count - ilo¶æ adresatów
- * - recipients - numerki adresatów
- * - message - tre¶æ wiadomo¶ci
- * - format - informacje o formatowaniu
- * - formatlen - d³ugo¶æ informacji o formatowaniu
- *
- * numer sekwencyjny wiadomo¶ci lub -1 w przypadku b³êdu.
- */
-int gg_send_message_confer_richtext(struct gg_session *sess, int msgclass, int recipients_count, uin_t *recipients, const unsigned char *message, const unsigned char *format, int formatlen)
-{
- struct gg_send_msg s;
- struct gg_msg_recipients r;
- int i, j, k;
- uin_t *recps;
-
- gg_debug(GG_DEBUG_FUNCTION, "** gg_send_message_confer_richtext(%p, %d, %d, %p, %p, %p, %d);\n", sess, msgclass, recipients_count, recipients, message, format, formatlen);
-
- if (!sess) {
- errno = EFAULT;
- return -1;
- }
-
- if (sess->state != GG_STATE_CONNECTED) {
- errno = ENOTCONN;
- return -1;
- }
-
- if (!message || recipients_count <= 0 || recipients_count > 0xffff || !recipients) {
- errno = EINVAL;
- return -1;
- }
-
- r.flag = 0x01;
- r.count = gg_fix32(recipients_count - 1);
-
- if (!sess->seq)
- sess->seq = 0x01740000 | (rand() & 0xffff);
- s.seq = gg_fix32(sess->seq);
- s.msgclass = gg_fix32(msgclass);
-
- recps = malloc(sizeof(uin_t) * recipients_count);
- if (!recps)
- return -1;
-
- for (i = 0; i < recipients_count; i++) {
-
- s.recipient = gg_fix32(recipients[i]);
-
- for (j = 0, k = 0; j < recipients_count; j++)
- if (recipients[j] != recipients[i]) {
- recps[k] = gg_fix32(recipients[j]);
- k++;
- }
-
- if (!i)
- sess->seq += (rand() % 0x300) + 0x300;
-
- if (gg_send_packet(sess, GG_SEND_MSG, &s, sizeof(s), message, strlen(message) + 1, &r, sizeof(r), recps, (recipients_count - 1) * sizeof(uin_t), format, formatlen, NULL) == -1) {
- free(recps);
- return -1;
- }
- }
-
- free(recps);
-
- return gg_fix32(s.seq);
-}
-
-/*
- * gg_ping()
- *
- * wysy³a do serwera pakiet ping.
- *
- * - sess - opis sesji
- *
- * 0, -1.
- */
-int gg_ping(struct gg_session *sess)
-{
- gg_debug(GG_DEBUG_FUNCTION, "** gg_ping(%p);\n", sess);
-
- if (!sess) {
- errno = EFAULT;
- return -1;
- }
-
- if (sess->state != GG_STATE_CONNECTED) {
- errno = ENOTCONN;
- return -1;
- }
-
- return gg_send_packet(sess, GG_PING, NULL);
-}
-
-/*
- * gg_notify_ex()
- *
- * wysy³a serwerowi listê kontaktów (wraz z odpowiadaj±cymi im typami userów),
- * dziêki czemu wie, czyj stan nas interesuje.
- *
- * - sess - opis sesji
- * - userlist - wska¼nik do tablicy numerów
- * - types - wska¼nik do tablicy typów u¿ytkowników
- * - count - ilo¶æ numerków
- *
- * 0, -1.
- */
-int gg_notify_ex(struct gg_session *sess, uin_t *userlist, char *types, int count)
-{
- struct gg_notify *n;
- uin_t *u;
- char *t;
- int i, res = 0;
-
- gg_debug(GG_DEBUG_FUNCTION, "** gg_notify_ex(%p, %p, %p, %d);\n", sess, userlist, types, count);
-
- if (!sess) {
- errno = EFAULT;
- return -1;
- }
-
- if (sess->state != GG_STATE_CONNECTED) {
- errno = ENOTCONN;
- return -1;
- }
-
- if (!userlist || !count)
- return gg_send_packet(sess, GG_LIST_EMPTY, NULL);
-
- while (count > 0) {
- int part_count, packet_type;
-
- if (count > 400) {
- part_count = 400;
- packet_type = GG_NOTIFY_FIRST;
- } else {
- part_count = count;
- packet_type = GG_NOTIFY_LAST;
- }
-
- if (!(n = (struct gg_notify*) malloc(sizeof(*n) * part_count)))
- return -1;
-
- for (u = userlist, t = types, i = 0; i < part_count; u++, t++, i++) {
- n[i].uin = gg_fix32(*u);
- n[i].dunno1 = *t;
- }
-
- if (gg_send_packet(sess, packet_type, n, sizeof(*n) * part_count, NULL) == -1) {
- free(n);
- res = -1;
- break;
- }
-
- count -= part_count;
- userlist += part_count;
- types += part_count;
-
- free(n);
- }
-
- return res;
-}
-
-/*
- * gg_notify()
- *
- * wysy³a serwerowi listê kontaktów, dziêki czemu wie, czyj stan nas
- * interesuje.
- *
- * - sess - opis sesji
- * - userlist - wska¼nik do tablicy numerów
- * - count - ilo¶æ numerków
- *
- * 0, -1.
- */
-int gg_notify(struct gg_session *sess, uin_t *userlist, int count)
-{
- struct gg_notify *n;
- uin_t *u;
- int i, res = 0;
-
- gg_debug(GG_DEBUG_FUNCTION, "** gg_notify(%p, %p, %d);\n", sess, userlist, count);
-
- if (!sess) {
- errno = EFAULT;
- return -1;
- }
-
- if (sess->state != GG_STATE_CONNECTED) {
- errno = ENOTCONN;
- return -1;
- }
-
- if (!userlist || !count)
- return gg_send_packet(sess, GG_LIST_EMPTY, NULL);
-
- while (count > 0) {
- int part_count, packet_type;
-
- if (count > 400) {
- part_count = 400;
- packet_type = GG_NOTIFY_FIRST;
- } else {
- part_count = count;
- packet_type = GG_NOTIFY_LAST;
- }
-
- if (!(n = (struct gg_notify*) malloc(sizeof(*n) * part_count)))
- return -1;
-
- for (u = userlist, i = 0; i < part_count; u++, i++) {
- n[i].uin = gg_fix32(*u);
- n[i].dunno1 = GG_USER_NORMAL;
- }
-
- if (gg_send_packet(sess, packet_type, n, sizeof(*n) * part_count, NULL) == -1) {
- res = -1;
- free(n);
- break;
- }
-
- free(n);
-
- userlist += part_count;
- count -= part_count;
- }
-
- return res;
-}
-
-/*
- * gg_add_notify_ex()
- *
- * dodaje do listy kontaktów dany numer w trakcie po³±czenia.
- * dodawanemu u¿ytkownikowi okre¶lamy jego typ (patrz protocol.html)
- *
- * - sess - opis sesji
- * - uin - numer
- * - type - typ
- *
- * 0, -1.
- */
-int gg_add_notify_ex(struct gg_session *sess, uin_t uin, char type)
-{
- struct gg_add_remove a;
-
- gg_debug(GG_DEBUG_FUNCTION, "** gg_add_notify_ex(%p, %u, %d);\n", sess, uin, type);
-
- if (!sess) {
- errno = EFAULT;
- return -1;
- }
-
- if (sess->state != GG_STATE_CONNECTED) {
- errno = ENOTCONN;
- return -1;
- }
-
- a.uin = gg_fix32(uin);
- a.dunno1 = type;
-
- return gg_send_packet(sess, GG_ADD_NOTIFY, &a, sizeof(a), NULL);
-}
-
-/*
- * gg_add_notify()
- *
- * dodaje do listy kontaktów dany numer w trakcie po³±czenia.
- *
- * - sess - opis sesji
- * - uin - numer
- *
- * 0, -1.
- */
-int gg_add_notify(struct gg_session *sess, uin_t uin)
-{
- return gg_add_notify_ex(sess, uin, GG_USER_NORMAL);
-}
-
-/*
- * gg_remove_notify_ex()
- *
- * usuwa z listy kontaktów w trakcie po³±czenia.
- * usuwanemu u¿ytkownikowi okre¶lamy jego typ (patrz protocol.html)
- *
- * - sess - opis sesji
- * - uin - numer
- * - type - typ
- *
- * 0, -1.
- */
-int gg_remove_notify_ex(struct gg_session *sess, uin_t uin, char type)
-{
- struct gg_add_remove a;
-
- gg_debug(GG_DEBUG_FUNCTION, "** gg_remove_notify_ex(%p, %u, %d);\n", sess, uin, type);
-
- if (!sess) {
- errno = EFAULT;
- return -1;
- }
-
- if (sess->state != GG_STATE_CONNECTED) {
- errno = ENOTCONN;
- return -1;
- }
-
- a.uin = gg_fix32(uin);
- a.dunno1 = type;
-
- return gg_send_packet(sess, GG_REMOVE_NOTIFY, &a, sizeof(a), NULL);
-}
-
-/*
- * gg_remove_notify()
- *
- * usuwa z listy kontaktów w trakcie po³±czenia.
- *
- * - sess - opis sesji
- * - uin - numer
- *
- * 0, -1.
- */
-int gg_remove_notify(struct gg_session *sess, uin_t uin)
-{
- return gg_remove_notify_ex(sess, uin, GG_USER_NORMAL);
-}
-
-/*
- * gg_userlist_request()
- *
- * wysy³a ¿±danie/zapytanie listy kontaktów na serwerze.
- *
- * - sess - opis sesji
- * - type - rodzaj zapytania/¿±dania
- * - request - tre¶æ zapytania/¿±dania (mo¿e byæ NULL)
- *
- * 0, -1
- */
-int gg_userlist_request(struct gg_session *sess, char type, const char *request)
-{
- int len;
-
- if (!sess) {
- errno = EFAULT;
- return -1;
- }
-
- if (sess->state != GG_STATE_CONNECTED) {
- errno = ENOTCONN;
- return -1;
- }
-
- if (!request) {
- sess->userlist_blocks = 1;
- return gg_send_packet(sess, GG_USERLIST_REQUEST, &type, sizeof(type), NULL);
- }
-
- len = strlen(request);
-
- sess->userlist_blocks = 0;
-
- while (len > 2047) {
- sess->userlist_blocks++;
-
- if (gg_send_packet(sess, GG_USERLIST_REQUEST, &type, sizeof(type), request, 2047, NULL) == -1)
- return -1;
-
- if (type == GG_USERLIST_PUT)
- type = GG_USERLIST_PUT_MORE;
-
- request += 2047;
- len -= 2047;
- }
-
- sess->userlist_blocks++;
-
- return gg_send_packet(sess, GG_USERLIST_REQUEST, &type, sizeof(type), request, len, NULL);
-}
-
-/*
- * Local variables:
- * c-indentation-style: k&r
- * c-basic-offset: 8
- * indent-tabs-mode: notnil
- * End:
- *
- * vim: shiftwidth=8:
- */
diff --git a/kopete/protocols/gadu/libgadu/libgadu.h b/kopete/protocols/gadu/libgadu/libgadu.h
deleted file mode 100644
index 85c54953..00000000
--- a/kopete/protocols/gadu/libgadu/libgadu.h
+++ /dev/null
@@ -1,1310 +0,0 @@
-/* $Id$ */
-
-/*
- * (C) Copyright 2001-2003 Wojtek Kaniewski <wojtekka@irc.pl>
- * Robert J. Wo¼ny <speedy@ziew.org>
- * Arkadiusz Mi¶kiewicz <arekm@pld-linux.org>
- * Tomasz Chiliñski <chilek@chilan.com>
- * Piotr Wysocki <wysek@linux.bydg.org>
- * Dawid Jarosz <dawjar@poczta.onet.pl>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License Version
- * 2.1 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
- * USA.
- */
-
-#ifndef __GG_LIBGADU_H
-#define __GG_LIBGADU_H
-
-#ifdef __cplusplus
-#ifdef _WIN32
-#pragma pack(push, 1)
-#endif
-extern "C" {
-#endif
-
-#include <libgadu-config.h>
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#ifdef __GG_LIBGADU_HAVE_OPENSSL
-#include <openssl/ssl.h>
-#endif
-
-/*
- * typedef uin_t
- *
- * typ reprezentuj±cy numer osoby.
- */
-typedef uint32_t uin_t;
-
-/*
- * ogólna struktura opisuj±ca ró¿ne sesje. przydatna w klientach.
- */
-#define gg_common_head(x) \
- int fd; /* podgl±dany deskryptor */ \
- int check; /* sprawdzamy zapis czy odczyt */ \
- int state; /* aktualny stan maszynki */ \
- int error; /* kod b³êdu dla GG_STATE_ERROR */ \
- int type; /* rodzaj sesji */ \
- int id; /* identyfikator */ \
- int timeout; /* sugerowany timeout w sekundach */ \
- int (*callback)(x*); /* callback przy zmianach */ \
- void (*destroy)(x*); /* funkcja niszczenia */
-
-struct gg_common {
- gg_common_head(struct gg_common)
-};
-
-struct gg_image_queue;
-
-/*
- * struct gg_session
- *
- * struktura opisuj±ca dan± sesjê. tworzona przez gg_login(), zwalniana
- * przez gg_free_session().
- */
-struct gg_session {
- gg_common_head(struct gg_session)
-
- int async; /* czy po³±czenie jest asynchroniczne */
- int pid; /* pid procesu resolvera */
- int port; /* port, z którym siê ³±czymy */
- int seq; /* numer sekwencyjny ostatniej wiadomo¶ci */
- int last_pong; /* czas otrzymania ostatniego ping/pong */
- int last_event; /* czas otrzymania ostatniego pakietu */
-
- struct gg_event *event; /* zdarzenie po ->callback() */
-
- uint32_t proxy_addr; /* adres proxy, keszowany */
- uint16_t proxy_port; /* port proxy */
-
- uint32_t hub_addr; /* adres huba po resolvniêciu */
- uint32_t server_addr; /* adres serwera, od huba */
-
- uint32_t client_addr; /* adres klienta */
- uint16_t client_port; /* port, na którym klient s³ucha */
-
- uint32_t external_addr; /* adres zewnetrzny klienta */
- uint16_t external_port; /* port zewnetrzny klienta */
-
- uin_t uin; /* numerek klienta */
- char *password; /* i jego has³o. zwalniane automagicznie */
-
- int initial_status; /* pocz±tkowy stan klienta */
- int status; /* aktualny stan klienta */
-
- char *recv_buf; /* bufor na otrzymywane pakiety */
- int recv_done; /* ile ju¿ wczytano do bufora */
- int recv_left; /* i ile jeszcze trzeba wczytaæ */
-
- int protocol_version; /* wersja u¿ywanego protoko³u */
- char *client_version; /* wersja u¿ywanego klienta */
- int last_sysmsg; /* ostatnia wiadomo¶æ systemowa */
-
- char *initial_descr; /* pocz±tkowy opis stanu klienta */
-
- void *resolver; /* wska¼nik na informacje resolvera */
-
- char *header_buf; /* bufor na pocz±tek nag³ówka */
- unsigned int header_done;/* ile ju¿ mamy */
-
-#ifdef __GG_LIBGADU_HAVE_OPENSSL
- SSL *ssl; /* sesja TLS */
- SSL_CTX *ssl_ctx; /* kontekst sesji? */
-#else
- void *ssl; /* zachowujemy ABI */
- void *ssl_ctx;
-#endif
-
- int image_size; /* maksymalny rozmiar obrazków w KiB */
-
- char *userlist_reply; /* fragment odpowiedzi listy kontaktów */
-
- int userlist_blocks; /* na ile kawa³ków podzielono listê kontaktów */
-
- struct gg_image_queue *images; /* aktualnie wczytywane obrazki */
-};
-
-/*
- * struct gg_http
- *
- * ogólna struktura opisuj±ca stan wszystkich operacji HTTP. tworzona
- * przez gg_http_connect(), zwalniana przez gg_http_free().
- */
-struct gg_http {
- gg_common_head(struct gg_http)
-
- int async; /* czy po³±czenie asynchroniczne */
- int pid; /* pid procesu resolvera */
- int port; /* port, z którym siê ³±czymy */
-
- char *query; /* bufor zapytania http */
- char *header; /* bufor nag³ówka */
- int header_size; /* rozmiar wczytanego nag³ówka */
- char *body; /* bufor otrzymanych informacji */
- unsigned int body_size; /* oczekiwana ilo¶æ informacji */
-
- void *data; /* dane danej operacji http */
-
- char *user_data; /* dane u¿ytkownika, nie s± zwalniane przez gg_http_free() */
-
- void *resolver; /* wska¼nik na informacje resolvera */
-
- unsigned int body_done; /* ile ju¿ tre¶ci odebrano? */
-};
-
-#ifdef __GNUC__
-#define GG_PACKED __attribute__ ((packed))
-#else
-#define GG_PACKED
-#endif
-
-#define GG_MAX_PATH 276
-
-/*
- * struct gg_file_info
- *
- * odpowiednik windowsowej struktury WIN32_FIND_DATA niezbêdnej przy
- * wysy³aniu plików.
- */
-struct gg_file_info {
- uint32_t mode; /* dwFileAttributes */
- uint32_t ctime[2]; /* ftCreationTime */
- uint32_t atime[2]; /* ftLastAccessTime */
- uint32_t mtime[2]; /* ftLastWriteTime */
- uint32_t size_hi; /* nFileSizeHigh */
- uint32_t size; /* nFileSizeLow */
- uint32_t reserved0; /* dwReserved0 */
- uint32_t reserved1; /* dwReserved1 */
- unsigned char filename[GG_MAX_PATH - 14]; /* cFileName */
- unsigned char short_filename[14]; /* cAlternateFileName */
-} GG_PACKED;
-
-/*
- * struct gg_dcc
- *
- * struktura opisuj±ca nas³uchuj±ce gniazdo po³±czeñ miêdzy klientami.
- * tworzona przez gg_dcc_socket_create(), zwalniana przez gg_dcc_free().
- */
-struct gg_dcc {
- gg_common_head(struct gg_dcc)
-
- struct gg_event *event; /* opis zdarzenia */
-
- int active; /* czy to my siê ³±czymy? */
- int port; /* port, na którym siedzi */
- uin_t uin; /* uin klienta */
- uin_t peer_uin; /* uin drugiej strony */
- int file_fd; /* deskryptor pliku */
- unsigned int offset; /* offset w pliku */
- unsigned int chunk_size;/* rozmiar kawa³ka */
- unsigned int chunk_offset;/* offset w aktualnym kawa³ku */
- struct gg_file_info file_info;
- /* informacje o pliku */
- int established; /* po³±czenie ustanowione */
- char *voice_buf; /* bufor na pakiet po³±czenia g³osowego */
- int incoming; /* po³±czenie przychodz±ce */
- char *chunk_buf; /* bufor na kawa³ek danych */
- uint32_t remote_addr; /* adres drugiej strony */
- uint16_t remote_port; /* port drugiej strony */
-};
-
-/*
- * enum gg_session_t
- *
- * rodzaje sesji.
- */
-enum gg_session_t {
- GG_SESSION_GG = 1, /* po³±czenie z serwerem gg */
- GG_SESSION_HTTP, /* ogólna sesja http */
- GG_SESSION_SEARCH, /* szukanie */
- GG_SESSION_REGISTER, /* rejestrowanie */
- GG_SESSION_REMIND, /* przypominanie has³a */
- GG_SESSION_PASSWD, /* zmiana has³a */
- GG_SESSION_CHANGE, /* zmiana informacji o sobie */
- GG_SESSION_DCC, /* ogólne po³±czenie DCC */
- GG_SESSION_DCC_SOCKET, /* nas³uchuj±cy socket */
- GG_SESSION_DCC_SEND, /* wysy³anie pliku */
- GG_SESSION_DCC_GET, /* odbieranie pliku */
- GG_SESSION_DCC_VOICE, /* rozmowa g³osowa */
- GG_SESSION_USERLIST_GET, /* pobieranie userlisty */
- GG_SESSION_USERLIST_PUT, /* wysy³anie userlisty */
- GG_SESSION_UNREGISTER, /* usuwanie konta */
- GG_SESSION_USERLIST_REMOVE, /* usuwanie userlisty */
- GG_SESSION_TOKEN, /* pobieranie tokenu */
-
- GG_SESSION_USER0 = 256, /* zdefiniowana dla u¿ytkownika */
- GG_SESSION_USER1, /* j.w. */
- GG_SESSION_USER2, /* j.w. */
- GG_SESSION_USER3, /* j.w. */
- GG_SESSION_USER4, /* j.w. */
- GG_SESSION_USER5, /* j.w. */
- GG_SESSION_USER6, /* j.w. */
- GG_SESSION_USER7 /* j.w. */
-};
-
-/*
- * enum gg_state_t
- *
- * opisuje stan asynchronicznej maszyny.
- */
-enum gg_state_t {
- /* wspólne */
- GG_STATE_IDLE = 0, /* nie powinno wyst±piæ. */
- GG_STATE_RESOLVING, /* wywo³a³ gethostbyname() */
- GG_STATE_CONNECTING, /* wywo³a³ connect() */
- GG_STATE_READING_DATA, /* czeka na dane http */
- GG_STATE_ERROR, /* wyst±pi³ b³±d. kod w x->error */
-
- /* gg_session */
- GG_STATE_CONNECTING_HUB, /* wywo³a³ connect() na huba */
- GG_STATE_CONNECTING_GG, /* wywo³a³ connect() na serwer */
- GG_STATE_READING_KEY, /* czeka na klucz */
- GG_STATE_READING_REPLY, /* czeka na odpowied¼ */
- GG_STATE_CONNECTED, /* po³±czy³ siê */
-
- /* gg_http */
- GG_STATE_SENDING_QUERY, /* wysy³a zapytanie http */
- GG_STATE_READING_HEADER, /* czeka na nag³ówek http */
- GG_STATE_PARSING, /* przetwarza dane */
- GG_STATE_DONE, /* skoñczy³ */
-
- /* gg_dcc */
- GG_STATE_LISTENING, /* czeka na po³±czenia */
- GG_STATE_READING_UIN_1, /* czeka na uin peera */
- GG_STATE_READING_UIN_2, /* czeka na swój uin */
- GG_STATE_SENDING_ACK, /* wysy³a potwierdzenie dcc */
- GG_STATE_READING_ACK, /* czeka na potwierdzenie dcc */
- GG_STATE_READING_REQUEST, /* czeka na komendê */
- GG_STATE_SENDING_REQUEST, /* wysy³a komendê */
- GG_STATE_SENDING_FILE_INFO, /* wysy³a informacje o pliku */
- GG_STATE_READING_PRE_FILE_INFO, /* czeka na pakiet przed file_info */
- GG_STATE_READING_FILE_INFO, /* czeka na informacje o pliku */
- GG_STATE_SENDING_FILE_ACK, /* wysy³a potwierdzenie pliku */
- GG_STATE_READING_FILE_ACK, /* czeka na potwierdzenie pliku */
- GG_STATE_SENDING_FILE_HEADER, /* wysy³a nag³ówek pliku */
- GG_STATE_READING_FILE_HEADER, /* czeka na nag³ówek */
- GG_STATE_GETTING_FILE, /* odbiera plik */
- GG_STATE_SENDING_FILE, /* wysy³a plik */
- GG_STATE_READING_VOICE_ACK, /* czeka na potwierdzenie voip */
- GG_STATE_READING_VOICE_HEADER, /* czeka na rodzaj bloku voip */
- GG_STATE_READING_VOICE_SIZE, /* czeka na rozmiar bloku voip */
- GG_STATE_READING_VOICE_DATA, /* czeka na dane voip */
- GG_STATE_SENDING_VOICE_ACK, /* wysy³a potwierdzenie voip */
- GG_STATE_SENDING_VOICE_REQUEST, /* wysy³a ¿±danie voip */
- GG_STATE_READING_TYPE, /* czeka na typ po³±czenia */
-
- /* nowe. bez sensu jest to API. */
- GG_STATE_TLS_NEGOTIATION /* negocjuje po³±czenie TLS */
-};
-
-/*
- * enum gg_check_t
- *
- * informuje, co proces klienta powinien sprawdziæ na deskryptorze danego
- * po³±czenia.
- */
-enum gg_check_t {
- GG_CHECK_NONE = 0, /* nic. nie powinno wyst±piæ */
- GG_CHECK_WRITE = 1, /* sprawdzamy mo¿liwo¶æ zapisu */
- GG_CHECK_READ = 2 /* sprawdzamy mo¿liwo¶æ odczytu */
-};
-
-/*
- * struct gg_login_params
- *
- * parametry gg_login(). przeniesiono do struktury, ¿eby unikn±æ problemów
- * z ci±g³ymi zmianami API, gdy dodano co¶ nowego do protoko³u.
- */
-struct gg_login_params {
- uin_t uin; /* numerek */
- char *password; /* has³o */
- int async; /* asynchroniczne sockety? */
- int status; /* pocz±tkowy status klienta */
- char *status_descr; /* opis statusu */
- uint32_t server_addr; /* adres serwera gg */
- uint16_t server_port; /* port serwera gg */
- uint32_t client_addr; /* adres dcc klienta */
- uint16_t client_port; /* port dcc klienta */
- int protocol_version; /* wersja protoko³u */
- char *client_version; /* wersja klienta */
- int has_audio; /* czy ma d¼wiêk? */
- int last_sysmsg; /* ostatnia wiadomo¶æ systemowa */
- uint32_t external_addr; /* adres widziany na zewnatrz */
- uint16_t external_port; /* port widziany na zewnatrz */
- int tls; /* czy ³±czymy po TLS? */
- int image_size; /* maksymalny rozmiar obrazka w KiB */
- int era_omnix; /* czy udawaæ klienta era omnix? */
-
- char dummy[6 * sizeof(int)]; /* miejsce na kolejnych 6 zmiennych,
- * ¿eby z dodaniem parametru nie
- * zmienia³ siê rozmiar struktury */
-};
-
-struct gg_session *gg_login(const struct gg_login_params *p);
-void gg_free_session(struct gg_session *sess);
-void gg_logoff(struct gg_session *sess);
-int gg_change_status(struct gg_session *sess, int status);
-int gg_change_status_descr(struct gg_session *sess, int status, const char *descr);
-int gg_change_status_descr_time(struct gg_session *sess, int status, const char *descr, int time);
-int gg_send_message(struct gg_session *sess, int msgclass, uin_t recipient, const unsigned char *message);
-int gg_send_message_richtext(struct gg_session *sess, int msgclass, uin_t recipient, const unsigned char *message, const unsigned char *format, int formatlen);
-int gg_send_message_confer(struct gg_session *sess, int msgclass, int recipients_count, uin_t *recipients, const unsigned char *message);
-int gg_send_message_confer_richtext(struct gg_session *sess, int msgclass, int recipients_count, uin_t *recipients, const unsigned char *message, const unsigned char *format, int formatlen);
-int gg_send_message_ctcp(struct gg_session *sess, int msgclass, uin_t recipient, const unsigned char *message, int message_len);
-int gg_ping(struct gg_session *sess);
-int gg_userlist_request(struct gg_session *sess, char type, const char *request);
-int gg_image_request(struct gg_session *sess, uin_t recipient, int size, uint32_t crc32);
-int gg_image_reply(struct gg_session *sess, uin_t recipient, const char *filename, const char *image, int size);
-
-uint32_t gg_crc32(uint32_t crc, const unsigned char *buf, int len);
-
-struct gg_image_queue {
- uin_t sender; /* nadawca obrazka */
- uint32_t size; /* rozmiar */
- uint32_t crc32; /* suma kontrolna */
- char *filename; /* nazwa pliku */
- char *image; /* bufor z obrazem */
- uint32_t done; /* ile ju¿ wczytano */
-
- struct gg_image_queue *next; /* nastêpny na li¶cie */
-};
-
-/*
- * enum gg_event_t
- *
- * rodzaje zdarzeñ.
- */
-enum gg_event_t {
- GG_EVENT_NONE = 0, /* nic siê nie wydarzy³o */
- GG_EVENT_MSG, /* otrzymano wiadomo¶æ */
- GG_EVENT_NOTIFY, /* kto¶ siê pojawi³ */
- GG_EVENT_NOTIFY_DESCR, /* kto¶ siê pojawi³ z opisem */
- GG_EVENT_STATUS, /* kto¶ zmieni³ stan */
- GG_EVENT_ACK, /* potwierdzenie wys³ania wiadomo¶ci */
- GG_EVENT_PONG, /* pakiet pong */
- GG_EVENT_CONN_FAILED, /* po³±czenie siê nie uda³o */
- GG_EVENT_CONN_SUCCESS, /* po³±czenie siê powiod³o */
- GG_EVENT_DISCONNECT, /* serwer zrywa po³±czenie */
-
- GG_EVENT_DCC_NEW, /* nowe po³±czenie miêdzy klientami */
- GG_EVENT_DCC_ERROR, /* b³±d po³±czenia miêdzy klientami */
- GG_EVENT_DCC_DONE, /* zakoñczono po³±czenie */
- GG_EVENT_DCC_CLIENT_ACCEPT, /* moment akceptacji klienta */
- GG_EVENT_DCC_CALLBACK, /* klient siê po³±czy³ na ¿±danie */
- GG_EVENT_DCC_NEED_FILE_INFO, /* nale¿y wype³niæ file_info */
- GG_EVENT_DCC_NEED_FILE_ACK, /* czeka na potwierdzenie pliku */
- GG_EVENT_DCC_NEED_VOICE_ACK, /* czeka na potwierdzenie rozmowy */
- GG_EVENT_DCC_VOICE_DATA, /* ramka danych rozmowy g³osowej */
-
- GG_EVENT_PUBDIR50_SEARCH_REPLY, /* odpowiedz wyszukiwania */
- GG_EVENT_PUBDIR50_READ, /* odczytano w³asne dane z katalogu */
- GG_EVENT_PUBDIR50_WRITE, /* wpisano w³asne dane do katalogu */
-
- GG_EVENT_STATUS60, /* kto¶ zmieni³ stan w GG 6.0 */
- GG_EVENT_NOTIFY60, /* kto¶ siê pojawi³ w GG 6.0 */
- GG_EVENT_USERLIST, /* odpowied¼ listy kontaktów w GG 6.0 */
- GG_EVENT_IMAGE_REQUEST, /* pro¶ba o wys³anie obrazka GG 6.0 */
- GG_EVENT_IMAGE_REPLY, /* podes³any obrazek GG 6.0 */
- GG_EVENT_DCC_ACK /* potwierdzenie transmisji */
-};
-
-#define GG_EVENT_SEARCH50_REPLY GG_EVENT_PUBDIR50_SEARCH_REPLY
-
-/*
- * enum gg_failure_t
- *
- * okre¶la powód nieudanego po³±czenia.
- */
-enum gg_failure_t {
- GG_FAILURE_RESOLVING = 1, /* nie znaleziono serwera */
- GG_FAILURE_CONNECTING, /* nie mo¿na siê po³±czyæ */
- GG_FAILURE_INVALID, /* serwer zwróci³ nieprawid³owe dane */
- GG_FAILURE_READING, /* zerwano po³±czenie podczas odczytu */
- GG_FAILURE_WRITING, /* zerwano po³±czenie podczas zapisu */
- GG_FAILURE_PASSWORD, /* nieprawid³owe has³o */
- GG_FAILURE_404, /* XXX nieu¿ywane */
- GG_FAILURE_TLS, /* b³±d negocjacji TLS */
- GG_FAILURE_NEED_EMAIL, /* serwer roz³±czy³ nas z pro¶b± o zmianê emaila */
- GG_FAILURE_INTRUDER, /* za du¿o prób po³±czenia siê z nieprawid³owym has³em */
- GG_FAILURE_UNAVAILABLE /* serwery s± wy³±czone */
-};
-
-/*
- * enum gg_error_t
- *
- * okre¶la rodzaj b³êdu wywo³anego przez dan± operacjê. nie zawiera
- * przesadnie szczegó³owych informacji o powodzie b³êdu, by nie komplikowaæ
- * obs³ugi b³êdów. je¶li wymagana jest wiêksza dok³adno¶æ, nale¿y sprawdziæ
- * zawarto¶æ zmiennej errno.
- */
-enum gg_error_t {
- GG_ERROR_RESOLVING = 1, /* b³±d znajdowania hosta */
- GG_ERROR_CONNECTING, /* b³±d ³aczenia siê */
- GG_ERROR_READING, /* b³±d odczytu */
- GG_ERROR_WRITING, /* b³±d wysy³ania */
-
- GG_ERROR_DCC_HANDSHAKE, /* b³±d negocjacji */
- GG_ERROR_DCC_FILE, /* b³±d odczytu/zapisu pliku */
- GG_ERROR_DCC_EOF, /* plik siê skoñczy³? */
- GG_ERROR_DCC_NET, /* b³±d wysy³ania/odbierania */
- GG_ERROR_DCC_REFUSED /* po³±czenie odrzucone przez usera */
-};
-
-/*
- * struktury dotycz±ce wyszukiwania w GG 5.0. NIE NALE¯Y SIÊ DO NICH
- * ODWO£YWAÆ BEZPO¦REDNIO! do dostêpu do nich s³u¿± funkcje gg_pubdir50_*()
- */
-struct gg_pubdir50_entry {
- int num;
- char *field;
- char *value;
-};
-
-struct gg_pubdir50_s {
- int count;
- uin_t next;
- int type;
- uint32_t seq;
- struct gg_pubdir50_entry *entries;
- int entries_count;
-};
-
-/*
- * typedef gg_pubdir_50_t
- *
- * typ opisuj±cy zapytanie lub wynik zapytania katalogu publicznego
- * z protoko³u GG 5.0. nie nale¿y siê odwo³ywaæ bezpo¶rednio do jego
- * pól -- s³u¿± do tego funkcje gg_pubdir50_*()
- */
-typedef struct gg_pubdir50_s *gg_pubdir50_t;
-
-/*
- * struct gg_event
- *
- * struktura opisuj±ca rodzaj zdarzenia. wychodzi z gg_watch_fd() lub
- * z gg_dcc_watch_fd()
- */
-struct gg_event {
- int type; /* rodzaj zdarzenia -- gg_event_t */
- union { /* @event */
- struct gg_notify_reply *notify; /* informacje o li¶cie kontaktów -- GG_EVENT_NOTIFY */
-
- enum gg_failure_t failure; /* b³±d po³±czenia -- GG_EVENT_FAILURE */
-
- struct gg_dcc *dcc_new; /* nowe po³±czenie bezpo¶rednie -- GG_EVENT_DCC_NEW */
-
- int dcc_error; /* b³±d po³±czenia bezpo¶redniego -- GG_EVENT_DCC_ERROR */
-
- gg_pubdir50_t pubdir50; /* wynik operacji zwi±zanej z katalogiem publicznym -- GG_EVENT_PUBDIR50_* */
-
- struct { /* @msg odebrano wiadomo¶æ -- GG_EVENT_MSG */
- uin_t sender; /* numer nadawcy */
- int msgclass; /* klasa wiadomo¶ci */
- time_t time; /* czas nadania */
- unsigned char *message; /* tre¶æ wiadomo¶ci */
-
- int recipients_count; /* ilo¶æ odbiorców konferencji */
- uin_t *recipients; /* odbiorcy konferencji */
-
- int formats_length; /* d³ugo¶æ informacji o formatowaniu tekstu */
- void *formats; /* informacje o formatowaniu tekstu */
- } msg;
-
- struct { /* @notify_descr informacje o li¶cie kontaktów z opisami stanu -- GG_EVENT_NOTIFY_DESCR */
- struct gg_notify_reply *notify; /* informacje o li¶cie kontaktów */
- char *descr; /* opis stanu */
- } notify_descr;
-
- struct { /* @status zmiana stanu -- GG_EVENT_STATUS */
- uin_t uin; /* numer */
- uint32_t status; /* nowy stan */
- char *descr; /* opis stanu */
- } status;
-
- struct { /* @status60 zmiana stanu -- GG_EVENT_STATUS60 */
- uin_t uin; /* numer */
- int status; /* nowy stan */
- uint32_t remote_ip; /* adres ip */
- uint16_t remote_port; /* port */
- int version; /* wersja klienta */
- int image_size; /* maksymalny rozmiar grafiki w KiB */
- char *descr; /* opis stanu */
- time_t time; /* czas powrotu */
- } status60;
-
- struct { /* @notify60 informacja o li¶cie kontaktów -- GG_EVENT_NOTIFY60 */
- uin_t uin; /* numer */
- int status; /* stan */
- uint32_t remote_ip; /* adres ip */
- uint16_t remote_port; /* port */
- int version; /* wersja klienta */
- int image_size; /* maksymalny rozmiar grafiki w KiB */
- char *descr; /* opis stanu */
- time_t time; /* czas powrotu */
- } *notify60;
-
- struct { /* @ack potwierdzenie wiadomo¶ci -- GG_EVENT_ACK */
- uin_t recipient; /* numer odbiorcy */
- int status; /* stan dorêczenia wiadomo¶ci */
- int seq; /* numer sekwencyjny wiadomo¶ci */
- } ack;
-
- struct { /* @dcc_voice_data otrzymano dane d¼wiêkowe -- GG_EVENT_DCC_VOICE_DATA */
- uint8_t *data; /* dane d¼wiêkowe */
- int length; /* ilo¶æ danych d¼wiêkowych */
- } dcc_voice_data;
-
- struct { /* @userlist odpowied¼ listy kontaktów serwera */
- char type; /* rodzaj odpowiedzi */
- char *reply; /* tre¶æ odpowiedzi */
- } userlist;
-
- struct { /* @image_request pro¶ba o obrazek */
- uin_t sender; /* nadawca pro¶by */
- uint32_t size; /* rozmiar obrazka */
- uint32_t crc32; /* suma kontrolna */
- } image_request;
-
- struct { /* @image_reply odpowied¼ z obrazkiem */
- uin_t sender; /* nadawca odpowiedzi */
- uint32_t size; /* rozmiar obrazka */
- uint32_t crc32; /* suma kontrolna */
- char *filename; /* nazwa pliku */
- char *image; /* bufor z obrazkiem */
- } image_reply;
- } event;
-};
-
-struct gg_event *gg_watch_fd(struct gg_session *sess);
-void gg_event_free(struct gg_event *e);
-#define gg_free_event gg_event_free
-
-/*
- * funkcje obs³ugi listy kontaktów.
- */
-int gg_notify_ex(struct gg_session *sess, uin_t *userlist, char *types, int count);
-int gg_notify(struct gg_session *sess, uin_t *userlist, int count);
-int gg_add_notify_ex(struct gg_session *sess, uin_t uin, char type);
-int gg_add_notify(struct gg_session *sess, uin_t uin);
-int gg_remove_notify_ex(struct gg_session *sess, uin_t uin, char type);
-int gg_remove_notify(struct gg_session *sess, uin_t uin);
-
-/*
- * funkcje obs³ugi http.
- */
-struct gg_http *gg_http_connect(const char *hostname, int port, int async, const char *method, const char *path, const char *header);
-int gg_http_watch_fd(struct gg_http *h);
-void gg_http_stop(struct gg_http *h);
-void gg_http_free(struct gg_http *h);
-void gg_http_free_fields(struct gg_http *h);
-#define gg_free_http gg_http_free
-
-/*
- * struktury opisuj±ca kryteria wyszukiwania dla gg_search(). nieaktualne,
- * zast±pione przez gg_pubdir50_t. pozostawiono je dla zachowania ABI.
- */
-struct gg_search_request {
- int active;
- unsigned int start;
- char *nickname;
- char *first_name;
- char *last_name;
- char *city;
- int gender;
- int min_birth;
- int max_birth;
- char *email;
- char *phone;
- uin_t uin;
-};
-
-struct gg_search {
- int count;
- struct gg_search_result *results;
-};
-
-struct gg_search_result {
- uin_t uin;
- char *first_name;
- char *last_name;
- char *nickname;
- int born;
- int gender;
- char *city;
- int active;
-};
-
-#define GG_GENDER_NONE 0
-#define GG_GENDER_FEMALE 1
-#define GG_GENDER_MALE 2
-
-/*
- * funkcje wyszukiwania.
- */
-struct gg_http *gg_search(const struct gg_search_request *r, int async);
-int gg_search_watch_fd(struct gg_http *f);
-void gg_free_search(struct gg_http *f);
-#define gg_search_free gg_free_search
-
-const struct gg_search_request *gg_search_request_mode_0(char *nickname, char *first_name, char *last_name, char *city, int gender, int min_birth, int max_birth, int active, int start);
-const struct gg_search_request *gg_search_request_mode_1(char *email, int active, int start);
-const struct gg_search_request *gg_search_request_mode_2(char *phone, int active, int start);
-const struct gg_search_request *gg_search_request_mode_3(uin_t uin, int active, int start);
-void gg_search_request_free(struct gg_search_request *r);
-
-/*
- * funkcje obs³ugi katalogu publicznego zgodne z GG 5.0. tym razem funkcje
- * zachowuj± pewien poziom abstrakcji, ¿eby unikn±æ zmian ABI przy zmianach
- * w protokole.
- *
- * NIE NALE¯Y SIÊ ODWO£YWAÆ DO PÓL gg_pubdir50_t BEZPO¦REDNIO!
- */
-uint32_t gg_pubdir50(struct gg_session *sess, gg_pubdir50_t req);
-gg_pubdir50_t gg_pubdir50_new(int type);
-int gg_pubdir50_add(gg_pubdir50_t req, const char *field, const char *value);
-int gg_pubdir50_seq_set(gg_pubdir50_t req, uint32_t seq);
-const char *gg_pubdir50_get(gg_pubdir50_t res, int num, const char *field);
-int gg_pubdir50_type(gg_pubdir50_t res);
-int gg_pubdir50_count(gg_pubdir50_t res);
-uin_t gg_pubdir50_next(gg_pubdir50_t res);
-uint32_t gg_pubdir50_seq(gg_pubdir50_t res);
-void gg_pubdir50_free(gg_pubdir50_t res);
-
-#define GG_PUBDIR50_UIN "FmNumber"
-#define GG_PUBDIR50_STATUS "FmStatus"
-#define GG_PUBDIR50_FIRSTNAME "firstname"
-#define GG_PUBDIR50_LASTNAME "lastname"
-#define GG_PUBDIR50_NICKNAME "nickname"
-#define GG_PUBDIR50_BIRTHYEAR "birthyear"
-#define GG_PUBDIR50_CITY "city"
-#define GG_PUBDIR50_GENDER "gender"
-#define GG_PUBDIR50_GENDER_FEMALE "1"
-#define GG_PUBDIR50_GENDER_MALE "2"
-#define GG_PUBDIR50_GENDER_SET_FEMALE "2"
-#define GG_PUBDIR50_GENDER_SET_MALE "1"
-#define GG_PUBDIR50_ACTIVE "ActiveOnly"
-#define GG_PUBDIR50_ACTIVE_TRUE "1"
-#define GG_PUBDIR50_START "fmstart"
-#define GG_PUBDIR50_FAMILYNAME "familyname"
-#define GG_PUBDIR50_FAMILYCITY "familycity"
-
-int gg_pubdir50_handle_reply(struct gg_event *e, const char *packet, int length);
-
-/*
- * struct gg_pubdir
- *
- * operacje na katalogu publicznym.
- */
-struct gg_pubdir {
- int success; /* czy siê uda³o */
- uin_t uin; /* otrzymany numerek. 0 je¶li b³±d */
-};
-
-/* ogólne funkcje, nie powinny byæ u¿ywane */
-int gg_pubdir_watch_fd(struct gg_http *f);
-void gg_pubdir_free(struct gg_http *f);
-#define gg_free_pubdir gg_pubdir_free
-
-struct gg_token {
- int width; /* szeroko¶æ obrazka */
- int height; /* wysoko¶æ obrazka */
- int length; /* ilo¶æ znaków w tokenie */
- char *tokenid; /* id tokenu */
-};
-
-/* funkcje dotycz±ce tokenów */
-struct gg_http *gg_token(int async);
-int gg_token_watch_fd(struct gg_http *h);
-void gg_token_free(struct gg_http *h);
-
-/* rejestracja nowego numerka */
-struct gg_http *gg_register(const char *email, const char *password, int async);
-struct gg_http *gg_register2(const char *email, const char *password, const char *qa, int async);
-struct gg_http *gg_register3(const char *email, const char *password, const char *tokenid, const char *tokenval, int async);
-#define gg_register_watch_fd gg_pubdir_watch_fd
-#define gg_register_free gg_pubdir_free
-#define gg_free_register gg_pubdir_free
-
-struct gg_http *gg_unregister(uin_t uin, const char *password, const char *email, int async);
-struct gg_http *gg_unregister2(uin_t uin, const char *password, const char *qa, int async);
-struct gg_http *gg_unregister3(uin_t uin, const char *password, const char *tokenid, const char *tokenval, int async);
-#define gg_unregister_watch_fd gg_pubdir_watch_fd
-#define gg_unregister_free gg_pubdir_free
-
-/* przypomnienie has³a e-mailem */
-struct gg_http *gg_remind_passwd(uin_t uin, int async);
-struct gg_http *gg_remind_passwd2(uin_t uin, const char *tokenid, const char *tokenval, int async);
-struct gg_http *gg_remind_passwd3(uin_t uin, const char *email, const char *tokenid, const char *tokenval, int async);
-#define gg_remind_passwd_watch_fd gg_pubdir_watch_fd
-#define gg_remind_passwd_free gg_pubdir_free
-#define gg_free_remind_passwd gg_pubdir_free
-
-/* zmiana has³a */
-struct gg_http *gg_change_passwd(uin_t uin, const char *passwd, const char *newpasswd, const char *newemail, int async);
-struct gg_http *gg_change_passwd2(uin_t uin, const char *passwd, const char *newpasswd, const char *email, const char *newemail, int async);
-struct gg_http *gg_change_passwd3(uin_t uin, const char *passwd, const char *newpasswd, const char *qa, int async);
-struct gg_http *gg_change_passwd4(uin_t uin, const char *email, const char *passwd, const char *newpasswd, const char *tokenid, const char *tokenval, int async);
-#define gg_change_passwd_free gg_pubdir_free
-#define gg_free_change_passwd gg_pubdir_free
-
-/*
- * struct gg_change_info_request
- *
- * opis ¿±dania zmiany informacji w katalogu publicznym.
- */
-struct gg_change_info_request {
- char *first_name; /* imiê */
- char *last_name; /* nazwisko */
- char *nickname; /* pseudonim */
- char *email; /* email */
- int born; /* rok urodzenia */
- int gender; /* p³eæ */
- char *city; /* miasto */
-};
-
-struct gg_change_info_request *gg_change_info_request_new(const char *first_name, const char *last_name, const char *nickname, const char *email, int born, int gender, const char *city);
-void gg_change_info_request_free(struct gg_change_info_request *r);
-
-struct gg_http *gg_change_info(uin_t uin, const char *passwd, const struct gg_change_info_request *request, int async);
-#define gg_change_pubdir_watch_fd gg_pubdir_watch_fd
-#define gg_change_pubdir_free gg_pubdir_free
-#define gg_free_change_pubdir gg_pubdir_free
-
-/*
- * funkcje dotycz±ce listy kontaktów na serwerze.
- */
-struct gg_http *gg_userlist_get(uin_t uin, const char *password, int async);
-int gg_userlist_get_watch_fd(struct gg_http *f);
-void gg_userlist_get_free(struct gg_http *f);
-
-struct gg_http *gg_userlist_put(uin_t uin, const char *password, const char *contacts, int async);
-int gg_userlist_put_watch_fd(struct gg_http *f);
-void gg_userlist_put_free(struct gg_http *f);
-
-struct gg_http *gg_userlist_remove(uin_t uin, const char *password, int async);
-int gg_userlist_remove_watch_fd(struct gg_http *f);
-void gg_userlist_remove_free(struct gg_http *f);
-
-
-
-/*
- * funkcje dotycz±ce komunikacji miêdzy klientami.
- */
-extern int gg_dcc_port; /* port, na którym nas³uchuje klient */
-extern unsigned long gg_dcc_ip; /* adres, na którym nas³uchuje klient */
-
-int gg_dcc_request(struct gg_session *sess, uin_t uin);
-
-struct gg_dcc *gg_dcc_send_file(uint32_t ip, uint16_t port, uin_t my_uin, uin_t peer_uin);
-struct gg_dcc *gg_dcc_get_file(uint32_t ip, uint16_t port, uin_t my_uin, uin_t peer_uin);
-struct gg_dcc *gg_dcc_voice_chat(uint32_t ip, uint16_t port, uin_t my_uin, uin_t peer_uin);
-void gg_dcc_set_type(struct gg_dcc *d, int type);
-int gg_dcc_fill_file_info(struct gg_dcc *d, const char *filename);
-int gg_dcc_fill_file_info2(struct gg_dcc *d, const char *filename, const char *local_filename);
-int gg_dcc_voice_send(struct gg_dcc *d, char *buf, int length);
-
-#define GG_DCC_VOICE_FRAME_LENGTH 195
-#define GG_DCC_VOICE_FRAME_LENGTH_505 326
-
-struct gg_dcc *gg_dcc_socket_create(uin_t uin, uint16_t port);
-#define gg_dcc_socket_free gg_free_dcc
-#define gg_dcc_socket_watch_fd gg_dcc_watch_fd
-
-struct gg_event *gg_dcc_watch_fd(struct gg_dcc *d);
-
-void gg_dcc_free(struct gg_dcc *c);
-#define gg_free_dcc gg_dcc_free
-
-/*
- * je¶li chcemy sobie podebugowaæ, wystarczy ustawiæ `gg_debug_level'.
- * niestety w miarê przybywania wpisów `gg_debug(...)' nie chcia³o mi
- * siê ustawiaæ odpowiednich leveli, wiêc wiêkszo¶æ sz³a do _MISC.
- */
-extern int gg_debug_level; /* poziom debugowania. mapa bitowa sta³ych GG_DEBUG_* */
-
-/*
- * mo¿na podaæ wska¼nik do funkcji obs³uguj±cej wywo³ania gg_debug().
- * nieoficjalne, nieudokumentowane, mo¿e siê zmieniæ. je¶li kto¶ jest
- * zainteresowany, niech da znaæ na ekg-devel.
- */
-extern void (*gg_debug_handler)(int level, const char *format, va_list ap);
-
-/*
- * mo¿na podaæ plik, do którego bêd± zapisywane teksty z gg_debug().
- */
-extern FILE *gg_debug_file;
-
-#define GG_DEBUG_NET 1
-#define GG_DEBUG_TRAFFIC 2
-#define GG_DEBUG_DUMP 4
-#define GG_DEBUG_FUNCTION 8
-#define GG_DEBUG_MISC 16
-
-#ifdef GG_DEBUG_DISABLE
-#define gg_debug(x, y...) do { } while(0)
-#else
-void gg_debug(int level, const char *format, ...);
-#endif
-
-const char *gg_libgadu_version(void);
-
-/*
- * konfiguracja http proxy.
- */
-extern int gg_proxy_enabled; /* w³±cza obs³ugê proxy */
-extern char *gg_proxy_host; /* okre¶la adres serwera proxy */
-extern int gg_proxy_port; /* okre¶la port serwera proxy */
-extern char *gg_proxy_username; /* okre¶la nazwê u¿ytkownika przy autoryzacji serwera proxy */
-extern char *gg_proxy_password; /* okre¶la has³o u¿ytkownika przy autoryzacji serwera proxy */
-extern int gg_proxy_http_only; /* w³±cza obs³ugê proxy wy³±cznie dla us³ug HTTP */
-
-
-/*
- * adres, z którego ¶lemy pakiety (np ³±czymy siê z serwerem)
- * u¿ywany przy gg_connect()
- */
-extern unsigned long gg_local_ip;
-/*
- * -------------------------------------------------------------------------
- * poni¿ej znajduj± siê wewnêtrzne sprawy biblioteki. zwyk³y klient nie
- * powinien ich w ogóle ruszaæ, bo i nie ma po co. wszystko mo¿na za³atwiæ
- * procedurami wy¿szego poziomu, których definicje znajduj± siê na pocz±tku
- * tego pliku.
- * -------------------------------------------------------------------------
- */
-
-#ifdef __GG_LIBGADU_HAVE_PTHREAD
-int gg_resolve_pthread(int *fd, void **resolver, const char *hostname);
-#endif
-
-#ifdef _WIN32
-int gg_thread_socket(int thread_id, int socket);
-#endif
-
-int gg_resolve(int *fd, int *pid, const char *hostname);
-
-#ifdef __GNUC__
-char *gg_saprintf(const char *format, ...) __attribute__ ((format (printf, 1, 2)));
-#else
-char *gg_saprintf(const char *format, ...);
-#endif
-
-char *gg_vsaprintf(const char *format, va_list ap);
-
-#define gg_alloc_sprintf gg_saprintf
-
-char *gg_get_line(char **ptr);
-
-int gg_connect(void *addr, int port, int async);
-struct in_addr *gg_gethostbyname(const char *hostname);
-char *gg_read_line(int sock, char *buf, int length);
-void gg_chomp(char *line);
-char *gg_urlencode(const char *str);
-int gg_http_hash(const char *format, ...);
-int gg_read(struct gg_session *sess, char *buf, int length);
-int gg_write(struct gg_session *sess, const char *buf, int length);
-void *gg_recv_packet(struct gg_session *sess);
-int gg_send_packet(struct gg_session *sess, int type, ...);
-unsigned int gg_login_hash(const unsigned char *password, unsigned int seed);
-uint32_t gg_fix32(uint32_t x);
-uint16_t gg_fix16(uint16_t x);
-#define fix16 gg_fix16
-#define fix32 gg_fix32
-char *gg_proxy_auth(void);
-char *gg_base64_encode(const char *buf);
-char *gg_base64_decode(const char *buf);
-int gg_image_queue_remove(struct gg_session *s, struct gg_image_queue *q, int freeq);
-
-#define GG_APPMSG_HOST "appmsg.gadu-gadu.pl"
-#define GG_APPMSG_PORT 80
-#define GG_PUBDIR_HOST "pubdir.gadu-gadu.pl"
-#define GG_PUBDIR_PORT 80
-#define GG_REGISTER_HOST "register.gadu-gadu.pl"
-#define GG_REGISTER_PORT 80
-#define GG_REMIND_HOST "retr.gadu-gadu.pl"
-#define GG_REMIND_PORT 80
-
-#define GG_DEFAULT_PORT 8074
-#define GG_HTTPS_PORT 443
-#define GG_HTTP_USERAGENT "Mozilla/4.7 [en] (Win98; I)"
-
-#define GG_DEFAULT_CLIENT_VERSION "6, 1, 0, 158"
-#define GG_DEFAULT_PROTOCOL_VERSION 0x24
-#define GG_DEFAULT_TIMEOUT 30
-#define GG_HAS_AUDIO_MASK 0x40000000
-#define GG_ERA_OMNIX_MASK 0x04000000
-#define GG_LIBGADU_VERSION "CVS"
-
-#define GG_DEFAULT_DCC_PORT 1550
-
-struct gg_header {
- uint32_t type; /* typ pakietu */
- uint32_t length; /* d³ugo¶æ reszty pakietu */
-} GG_PACKED;
-
-#define GG_WELCOME 0x0001
-#define GG_NEED_EMAIL 0x0014
-
-struct gg_welcome {
- uint32_t key; /* klucz szyfrowania has³a */
-} GG_PACKED;
-
-#define GG_LOGIN 0x000c
-
-struct gg_login {
- uint32_t uin; /* mój numerek */
- uint32_t hash; /* hash has³a */
- uint32_t status; /* status na dzieñ dobry */
- uint32_t version; /* moja wersja klienta */
- uint32_t local_ip; /* mój adres ip */
- uint16_t local_port; /* port, na którym s³ucham */
-} GG_PACKED;
-
-#define GG_LOGIN_EXT 0x0013
-
-struct gg_login_ext {
- uint32_t uin; /* mój numerek */
- uint32_t hash; /* hash has³a */
- uint32_t status; /* status na dzieñ dobry */
- uint32_t version; /* moja wersja klienta */
- uint32_t local_ip; /* mój adres ip */
- uint16_t local_port; /* port, na którym s³ucham */
- uint32_t external_ip; /* zewnêtrzny adres ip */
- uint16_t external_port; /* zewnêtrzny port */
-} GG_PACKED;
-
-#define GG_LOGIN60 0x0015
-
-struct gg_login60 {
- uint32_t uin; /* mój numerek */
- uint32_t hash; /* hash has³a */
- uint32_t status; /* status na dzieñ dobry */
- uint32_t version; /* moja wersja klienta */
- uint8_t dunno1; /* 0x00 */
- uint32_t local_ip; /* mój adres ip */
- uint16_t local_port; /* port, na którym s³ucham */
- uint32_t external_ip; /* zewnêtrzny adres ip */
- uint16_t external_port; /* zewnêtrzny port */
- uint8_t image_size; /* maksymalny rozmiar grafiki w KiB */
- uint8_t dunno2; /* 0xbe */
-} GG_PACKED;
-
-#define GG_LOGIN_OK 0x0003
-
-#define GG_LOGIN_FAILED 0x0009
-
-#define GG_PUBDIR50_REQUEST 0x0014
-
-#define GG_PUBDIR50_WRITE 0x01
-#define GG_PUBDIR50_READ 0x02
-#define GG_PUBDIR50_SEARCH 0x03
-#define GG_PUBDIR50_SEARCH_REQUEST GG_PUBDIR50_SEARCH
-#define GG_PUBDIR50_SEARCH_REPLY 0x05
-
-struct gg_pubdir50_request {
- uint8_t type; /* GG_PUBDIR50_* */
- uint32_t seq; /* czas wys³ania zapytania */
-} GG_PACKED;
-
-#define GG_PUBDIR50_REPLY 0x000e
-
-struct gg_pubdir50_reply {
- uint8_t type; /* GG_PUBDIR50_* */
- uint32_t seq; /* czas wys³ania zapytania */
-} GG_PACKED;
-
-#define GG_NEW_STATUS 0x0002
-
-#define GG_STATUS_NOT_AVAIL 0x0001 /* niedostêpny */
-#define GG_STATUS_NOT_AVAIL_DESCR 0x0015 /* niedostêpny z opisem (4.8) */
-#define GG_STATUS_AVAIL 0x0002 /* dostêpny */
-#define GG_STATUS_AVAIL_DESCR 0x0004 /* dostêpny z opisem (4.9) */
-#define GG_STATUS_BUSY 0x0003 /* zajêty */
-#define GG_STATUS_BUSY_DESCR 0x0005 /* zajêty z opisem (4.8) */
-#define GG_STATUS_INVISIBLE 0x0014 /* niewidoczny (4.6) */
-#define GG_STATUS_INVISIBLE_DESCR 0x0016 /* niewidoczny z opisem (4.9) */
-#define GG_STATUS_BLOCKED 0x0006 /* zablokowany */
-
-#define GG_STATUS_FRIENDS_MASK 0x8000 /* tylko dla znajomych (4.6) */
-
-#define GG_STATUS_DESCR_MAXSIZE 70
-
-/*
- * makra do ³atwego i szybkiego sprawdzania stanu.
- */
-
-/* GG_S_F() tryb tylko dla znajomych */
-#define GG_S_F(x) (((x) & GG_STATUS_FRIENDS_MASK) != 0)
-
-/* GG_S() stan bez uwzglêdnienia trybu tylko dla znajomych */
-#define GG_S(x) ((x) & ~GG_STATUS_FRIENDS_MASK)
-
-/* GG_S_A() dostêpny */
-#define GG_S_A(x) (GG_S(x) == GG_STATUS_AVAIL || GG_S(x) == GG_STATUS_AVAIL_DESCR)
-
-/* GG_S_NA() niedostêpny */
-#define GG_S_NA(x) (GG_S(x) == GG_STATUS_NOT_AVAIL || GG_S(x) == GG_STATUS_NOT_AVAIL_DESCR)
-
-/* GG_S_B() zajêty */
-#define GG_S_B(x) (GG_S(x) == GG_STATUS_BUSY || GG_S(x) == GG_STATUS_BUSY_DESCR)
-
-/* GG_S_I() niewidoczny */
-#define GG_S_I(x) (GG_S(x) == GG_STATUS_INVISIBLE || GG_S(x) == GG_STATUS_INVISIBLE_DESCR)
-
-/* GG_S_D() stan opisowy */
-#define GG_S_D(x) (GG_S(x) == GG_STATUS_NOT_AVAIL_DESCR || GG_S(x) == GG_STATUS_AVAIL_DESCR || GG_S(x) == GG_STATUS_BUSY_DESCR || GG_S(x) == GG_STATUS_INVISIBLE_DESCR)
-
-/* GG_S_BL() blokowany lub blokuj±cy */
-#define GG_S_BL(x) (GG_S(x) == GG_STATUS_BLOCKED)
-
-struct gg_new_status {
- uint32_t status; /* na jaki zmieniæ? */
-} GG_PACKED;
-
-#define GG_NOTIFY_FIRST 0x000f
-#define GG_NOTIFY_LAST 0x0010
-
-#define GG_NOTIFY 0x0010
-
-struct gg_notify {
- uint32_t uin; /* numerek danej osoby */
- uint8_t dunno1; /* rodzaj wpisu w li¶cie */
-} GG_PACKED;
-
-#define GG_USER_OFFLINE 0x01 /* bêdziemy niewidoczni dla u¿ytkownika */
-#define GG_USER_NORMAL 0x03 /* zwyk³y u¿ytkownik */
-#define GG_USER_BLOCKED 0x04 /* zablokowany u¿ytkownik */
-
-#define GG_LIST_EMPTY 0x0012
-
-#define GG_NOTIFY_REPLY 0x000c /* tak, to samo co GG_LOGIN */
-
-struct gg_notify_reply {
- uint32_t uin; /* numerek */
- uint32_t status; /* status danej osoby */
- uint32_t remote_ip; /* adres ip delikwenta */
- uint16_t remote_port; /* port, na którym s³ucha klient */
- uint32_t version; /* wersja klienta */
- uint16_t dunno2; /* znowu port? */
-} GG_PACKED;
-
-#define GG_NOTIFY_REPLY60 0x0011
-
-struct gg_notify_reply60 {
- uint32_t uin; /* numerek plus flagi w MSB */
- uint8_t status; /* status danej osoby */
- uint32_t remote_ip; /* adres ip delikwenta */
- uint16_t remote_port; /* port, na którym s³ucha klient */
- uint8_t version; /* wersja klienta */
- uint8_t image_size; /* maksymalny rozmiar grafiki w KiB */
- uint8_t dunno1; /* 0x00 */
-} GG_PACKED;
-
-#define GG_STATUS60 0x000f
-
-struct gg_status60 {
- uint32_t uin; /* numerek plus flagi w MSB */
- uint8_t status; /* status danej osoby */
- uint32_t remote_ip; /* adres ip delikwenta */
- uint16_t remote_port; /* port, na którym s³ucha klient */
- uint8_t version; /* wersja klienta */
- uint8_t image_size; /* maksymalny rozmiar grafiki w KiB */
- uint8_t dunno1; /* 0x00 */
-} GG_PACKED;
-
-#define GG_ADD_NOTIFY 0x000d
-#define GG_REMOVE_NOTIFY 0x000e
-
-struct gg_add_remove {
- uint32_t uin; /* numerek */
- uint8_t dunno1; /* bitmapa */
-} GG_PACKED;
-
-#define GG_STATUS 0x0002
-
-struct gg_status {
- uint32_t uin; /* numerek */
- uint32_t status; /* nowy stan */
-} GG_PACKED;
-
-#define GG_SEND_MSG 0x000b
-
-#define GG_CLASS_QUEUED 0x0001
-#define GG_CLASS_OFFLINE GG_CLASS_QUEUED
-#define GG_CLASS_MSG 0x0004
-#define GG_CLASS_CHAT 0x0008
-#define GG_CLASS_CTCP 0x0010
-#define GG_CLASS_ACK 0x0020
-#define GG_CLASS_EXT GG_CLASS_ACK /* kompatybilno¶æ wstecz */
-
-#define GG_MSG_MAXSIZE 2000
-
-struct gg_send_msg {
- uint32_t recipient;
- uint32_t seq;
- uint32_t msgclass;
-} GG_PACKED;
-
-struct gg_msg_richtext {
- uint8_t flag;
- uint16_t length;
-} GG_PACKED;
-
-struct gg_msg_richtext_format {
- uint16_t position;
- uint8_t font;
-} GG_PACKED;
-
-struct gg_msg_richtext_image {
- uint16_t unknown1;
- uint32_t size;
- uint32_t crc32;
-} GG_PACKED;
-
-#define GG_FONT_BOLD 0x01
-#define GG_FONT_ITALIC 0x02
-#define GG_FONT_UNDERLINE 0x04
-#define GG_FONT_COLOR 0x08
-#define GG_FONT_IMAGE 0x80
-
-struct gg_msg_richtext_color {
- uint8_t red;
- uint8_t green;
- uint8_t blue;
-} GG_PACKED;
-
-struct gg_msg_recipients {
- uint8_t flag;
- uint32_t count;
-} GG_PACKED;
-
-struct gg_msg_image_request {
- uint8_t flag;
- uint32_t size;
- uint32_t crc32;
-} GG_PACKED;
-
-struct gg_msg_image_reply {
- uint8_t flag;
- uint32_t size;
- uint32_t crc32;
- /* char filename[]; */
- /* char image[]; */
-} GG_PACKED;
-
-#define GG_SEND_MSG_ACK 0x0005
-
-#define GG_ACK_BLOCKED 0x0001
-#define GG_ACK_DELIVERED 0x0002
-#define GG_ACK_QUEUED 0x0003
-#define GG_ACK_MBOXFULL 0x0004
-#define GG_ACK_NOT_DELIVERED 0x0006
-
-struct gg_send_msg_ack {
- uint32_t status;
- uint32_t recipient;
- uint32_t seq;
-} GG_PACKED;
-
-#define GG_RECV_MSG 0x000a
-
-struct gg_recv_msg {
- uint32_t sender;
- uint32_t seq;
- uint32_t time;
- uint32_t msgclass;
-} GG_PACKED;
-
-#define GG_PING 0x0008
-
-#define GG_PONG 0x0007
-
-#define GG_DISCONNECTING 0x000b
-
-#define GG_USERLIST_REQUEST 0x0016
-
-#define GG_USERLIST_PUT 0x00
-#define GG_USERLIST_PUT_MORE 0x01
-#define GG_USERLIST_GET 0x02
-
-struct gg_userlist_request {
- uint8_t type;
-} GG_PACKED;
-
-#define GG_USERLIST_REPLY 0x0010
-
-#define GG_USERLIST_PUT_REPLY 0x00
-#define GG_USERLIST_PUT_MORE_REPLY 0x02
-#define GG_USERLIST_GET_REPLY 0x06
-#define GG_USERLIST_GET_MORE_REPLY 0x04
-
-struct gg_userlist_reply {
- uint8_t type;
-} GG_PACKED;
-
-/*
- * pakiety, sta³e, struktury dla DCC
- */
-
-struct gg_dcc_tiny_packet {
- uint8_t type; /* rodzaj pakietu */
-} GG_PACKED;
-
-struct gg_dcc_small_packet {
- uint32_t type; /* rodzaj pakietu */
-} GG_PACKED;
-
-struct gg_dcc_big_packet {
- uint32_t type; /* rodzaj pakietu */
- uint32_t dunno1; /* niewiadoma */
- uint32_t dunno2; /* niewiadoma */
-} GG_PACKED;
-
-/*
- * póki co, nie znamy dok³adnie protoko³u. nie wiemy, co czemu odpowiada.
- * nazwy s± niepowa¿ne i tymczasowe.
- */
-#define GG_DCC_WANT_FILE 0x0003 /* peer chce plik */
-#define GG_DCC_HAVE_FILE 0x0001 /* wiêc mu damy */
-#define GG_DCC_HAVE_FILEINFO 0x0003 /* niech ma informacje o pliku */
-#define GG_DCC_GIMME_FILE 0x0006 /* peer jest pewny */
-#define GG_DCC_CATCH_FILE 0x0002 /* wysy³amy plik */
-
-#define GG_DCC_FILEATTR_READONLY 0x0020
-
-#define GG_DCC_TIMEOUT_SEND 1800 /* 30 minut */
-#define GG_DCC_TIMEOUT_GET 1800 /* 30 minut */
-#define GG_DCC_TIMEOUT_FILE_ACK 300 /* 5 minut */
-#define GG_DCC_TIMEOUT_VOICE_ACK 300 /* 5 minut */
-
-#ifdef __cplusplus
-}
-#ifdef _WIN32
-#pragma pack(pop)
-#endif
-#endif
-
-#endif /* __GG_LIBGADU_H */
-
-/*
- * Local variables:
- * c-indentation-style: k&r
- * c-basic-offset: 8
- * indent-tabs-mode: notnil
- * End:
- *
- * vim: shiftwidth=8:
- */
diff --git a/kopete/protocols/gadu/libgadu/pubdir.c b/kopete/protocols/gadu/libgadu/pubdir.c
deleted file mode 100644
index 2741ea4b..00000000
--- a/kopete/protocols/gadu/libgadu/pubdir.c
+++ /dev/null
@@ -1,689 +0,0 @@
-/* $Id$ */
-
-/*
- * (C) Copyright 2001-2006 Wojtek Kaniewski <wojtekka@irc.pl>
- * Dawid Jarosz <dawjar@poczta.onet.pl>
- * Adam Wysocki <gophi@ekg.chmurka.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License Version
- * 2.1 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
- * USA.
- */
-
-#include <ctype.h>
-#include <errno.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "libgadu.h"
-
-/*
- * gg_register3()
- *
- * rozpoczyna rejestracj� u�ytkownika protoko�em GG 6.0. wymaga wcze�niejszego
- * pobrania tokenu za pomoc� funkcji gg_token().
- *
- * - email - adres e-mail klienta
- * - password - has�o klienta
- * - tokenid - identyfikator tokenu
- * - tokenval - warto�� tokenu
- * - async - po��czenie asynchroniczne
- *
- * zaalokowana struct gg_http, kt�r� po�niej nale�y zwolni�
- * funkcj� gg_register_free(), albo NULL je�li wyst�pi� b��d.
- */
-struct gg_http *gg_register3(const char *email, const char *password, const char *tokenid, const char *tokenval, int async)
-{
- struct gg_http *h;
- char *__pwd, *__email, *__tokenid, *__tokenval, *form, *query;
-
- if (!email || !password || !tokenid || !tokenval) {
- gg_debug(GG_DEBUG_MISC, "=> register, NULL parameter\n");
- errno = EFAULT;
- return NULL;
- }
-
- __pwd = gg_urlencode(password);
- __email = gg_urlencode(email);
- __tokenid = gg_urlencode(tokenid);
- __tokenval = gg_urlencode(tokenval);
-
- if (!__pwd || !__email || !__tokenid || !__tokenval) {
- gg_debug(GG_DEBUG_MISC, "=> register, not enough memory for form fields\n");
- free(__pwd);
- free(__email);
- free(__tokenid);
- free(__tokenval);
- return NULL;
- }
-
- form = gg_saprintf("pwd=%s&email=%s&tokenid=%s&tokenval=%s&code=%u",
- __pwd, __email, __tokenid, __tokenval,
- gg_http_hash("ss", email, password));
-
- free(__pwd);
- free(__email);
- free(__tokenid);
- free(__tokenval);
-
- if (!form) {
- gg_debug(GG_DEBUG_MISC, "=> register, not enough memory for form query\n");
- return NULL;
- }
-
- gg_debug(GG_DEBUG_MISC, "=> register, %s\n", form);
-
- query = gg_saprintf(
- "Host: " GG_REGISTER_HOST "\r\n"
- "Content-Type: application/x-www-form-urlencoded\r\n"
- "User-Agent: " GG_HTTP_USERAGENT "\r\n"
- "Content-Length: %d\r\n"
- "Pragma: no-cache\r\n"
- "\r\n"
- "%s",
- (int) strlen(form), form);
-
- free(form);
-
- if (!query) {
- gg_debug(GG_DEBUG_MISC, "=> register, not enough memory for query\n");
- return NULL;
- }
-
- if (!(h = gg_http_connect(GG_REGISTER_HOST, GG_REGISTER_PORT, async, "POST", "/appsvc/fmregister3.asp", query))) {
- gg_debug(GG_DEBUG_MISC, "=> register, gg_http_connect() failed mysteriously\n");
- free(query);
- return NULL;
- }
-
- h->type = GG_SESSION_REGISTER;
-
- free(query);
-
- h->callback = gg_pubdir_watch_fd;
- h->destroy = gg_pubdir_free;
-
- if (!async)
- gg_pubdir_watch_fd(h);
-
- return h;
-}
-
-/*
- * gg_unregister3()
- *
- * usuwa konto u�ytkownika z serwera protoko�em GG 6.0
- *
- * - uin - numerek GG
- * - password - has�o klienta
- * - tokenid - identyfikator tokenu
- * - tokenval - warto�� tokenu
- * - async - po��czenie asynchroniczne
- *
- * zaalokowana struct gg_http, kt�r� po�niej nale�y zwolni�
- * funkcj� gg_unregister_free(), albo NULL je�li wyst�pi� b��d.
- */
-struct gg_http *gg_unregister3(uin_t uin, const char *password, const char *tokenid, const char *tokenval, int async)
-{
- struct gg_http *h;
- char *__fmpwd, *__pwd, *__tokenid, *__tokenval, *form, *query;
-
- if (!password || !tokenid || !tokenval) {
- gg_debug(GG_DEBUG_MISC, "=> unregister, NULL parameter\n");
- errno = EFAULT;
- return NULL;
- }
-
- __pwd = gg_saprintf("%ld", random());
- __fmpwd = gg_urlencode(password);
- __tokenid = gg_urlencode(tokenid);
- __tokenval = gg_urlencode(tokenval);
-
- if (!__fmpwd || !__pwd || !__tokenid || !__tokenval) {
- gg_debug(GG_DEBUG_MISC, "=> unregister, not enough memory for form fields\n");
- free(__pwd);
- free(__fmpwd);
- free(__tokenid);
- free(__tokenval);
- return NULL;
- }
-
- form = gg_saprintf("fmnumber=%d&fmpwd=%s&delete=1&pwd=%s&email=deletedaccount@gadu-gadu.pl&tokenid=%s&tokenval=%s&code=%u", uin, __fmpwd, __pwd, __tokenid, __tokenval, gg_http_hash("ss", "deletedaccount@gadu-gadu.pl", __pwd));
-
- free(__fmpwd);
- free(__pwd);
- free(__tokenid);
- free(__tokenval);
-
- if (!form) {
- gg_debug(GG_DEBUG_MISC, "=> unregister, not enough memory for form query\n");
- return NULL;
- }
-
- gg_debug(GG_DEBUG_MISC, "=> unregister, %s\n", form);
-
- query = gg_saprintf(
- "Host: " GG_REGISTER_HOST "\r\n"
- "Content-Type: application/x-www-form-urlencoded\r\n"
- "User-Agent: " GG_HTTP_USERAGENT "\r\n"
- "Content-Length: %d\r\n"
- "Pragma: no-cache\r\n"
- "\r\n"
- "%s",
- (int) strlen(form), form);
-
- free(form);
-
- if (!query) {
- gg_debug(GG_DEBUG_MISC, "=> unregister, not enough memory for query\n");
- return NULL;
- }
-
- if (!(h = gg_http_connect(GG_REGISTER_HOST, GG_REGISTER_PORT, async, "POST", "/appsvc/fmregister3.asp", query))) {
- gg_debug(GG_DEBUG_MISC, "=> unregister, gg_http_connect() failed mysteriously\n");
- free(query);
- return NULL;
- }
-
- h->type = GG_SESSION_UNREGISTER;
-
- free(query);
-
- h->callback = gg_pubdir_watch_fd;
- h->destroy = gg_pubdir_free;
-
- if (!async)
- gg_pubdir_watch_fd(h);
-
- return h;
-}
-
-/*
- * gg_change_passwd4()
- *
- * wysy�a ��danie zmiany has�a zgodnie z protoko�em GG 6.0. wymaga
- * wcze�niejszego pobrania tokenu za pomoc� funkcji gg_token().
- *
- * - uin - numer
- * - email - adres e-mail
- * - passwd - stare has�o
- * - newpasswd - nowe has�o
- * - tokenid - identyfikator tokenu
- * - tokenval - warto�� tokenu
- * - async - po��czenie asynchroniczne
- *
- * zaalokowana struct gg_http, kt�r� po�niej nale�y zwolni�
- * funkcj� gg_change_passwd_free(), albo NULL je�li wyst�pi� b��d.
- */
-struct gg_http *gg_change_passwd4(uin_t uin, const char *email, const char *passwd, const char *newpasswd, const char *tokenid, const char *tokenval, int async)
-{
- struct gg_http *h;
- char *form, *query, *__email, *__fmpwd, *__pwd, *__tokenid, *__tokenval;
-
- if (!uin || !email || !passwd || !newpasswd || !tokenid || !tokenval) {
- gg_debug(GG_DEBUG_MISC, "=> change, NULL parameter\n");
- errno = EFAULT;
- return NULL;
- }
-
- __fmpwd = gg_urlencode(passwd);
- __pwd = gg_urlencode(newpasswd);
- __email = gg_urlencode(email);
- __tokenid = gg_urlencode(tokenid);
- __tokenval = gg_urlencode(tokenval);
-
- if (!__fmpwd || !__pwd || !__email || !__tokenid || !__tokenval) {
- gg_debug(GG_DEBUG_MISC, "=> change, not enough memory for form fields\n");
- free(__fmpwd);
- free(__pwd);
- free(__email);
- free(__tokenid);
- free(__tokenval);
- return NULL;
- }
-
- if (!(form = gg_saprintf("fmnumber=%d&fmpwd=%s&pwd=%s&email=%s&tokenid=%s&tokenval=%s&code=%u", uin, __fmpwd, __pwd, __email, __tokenid, __tokenval, gg_http_hash("ss", email, newpasswd)))) {
- gg_debug(GG_DEBUG_MISC, "=> change, not enough memory for form fields\n");
- free(__fmpwd);
- free(__pwd);
- free(__email);
- free(__tokenid);
- free(__tokenval);
-
- return NULL;
- }
-
- free(__fmpwd);
- free(__pwd);
- free(__email);
- free(__tokenid);
- free(__tokenval);
-
- gg_debug(GG_DEBUG_MISC, "=> change, %s\n", form);
-
- query = gg_saprintf(
- "Host: " GG_REGISTER_HOST "\r\n"
- "Content-Type: application/x-www-form-urlencoded\r\n"
- "User-Agent: " GG_HTTP_USERAGENT "\r\n"
- "Content-Length: %d\r\n"
- "Pragma: no-cache\r\n"
- "\r\n"
- "%s",
- (int) strlen(form), form);
-
- free(form);
-
- if (!query) {
- gg_debug(GG_DEBUG_MISC, "=> change, not enough memory for query\n");
- return NULL;
- }
-
- if (!(h = gg_http_connect(GG_REGISTER_HOST, GG_REGISTER_PORT, async, "POST", "/appsvc/fmregister3.asp", query))) {
- gg_debug(GG_DEBUG_MISC, "=> change, gg_http_connect() failed mysteriously\n");
- free(query);
- return NULL;
- }
-
- h->type = GG_SESSION_PASSWD;
-
- free(query);
-
- h->callback = gg_pubdir_watch_fd;
- h->destroy = gg_pubdir_free;
-
- if (!async)
- gg_pubdir_watch_fd(h);
-
- return h;
-}
-
-/*
- * gg_remind_passwd3()
- *
- * wysy�a ��danie przypomnienia has�a e-mailem.
- *
- * - uin - numer
- * - email - adres e-mail taki, jak ten zapisany na serwerze
- * - async - po��czenie asynchroniczne
- * - tokenid - identyfikator tokenu
- * - tokenval - warto�� tokenu
- *
- * zaalokowana struct gg_http, kt�r� po�niej nale�y zwolni�
- * funkcj� gg_remind_passwd_free(), albo NULL je�li wyst�pi� b��d.
- */
-struct gg_http *gg_remind_passwd3(uin_t uin, const char *email, const char *tokenid, const char *tokenval, int async)
-{
- struct gg_http *h;
- char *form, *query, *__tokenid, *__tokenval, *__email;
-
- if (!tokenid || !tokenval || !email) {
- gg_debug(GG_DEBUG_MISC, "=> remind, NULL parameter\n");
- errno = EFAULT;
- return NULL;
- }
-
- __tokenid = gg_urlencode(tokenid);
- __tokenval = gg_urlencode(tokenval);
- __email = gg_urlencode(email);
-
- if (!__tokenid || !__tokenval || !__email) {
- gg_debug(GG_DEBUG_MISC, "=> remind, not enough memory for form fields\n");
- free(__tokenid);
- free(__tokenval);
- free(__email);
- return NULL;
- }
-
- if (!(form = gg_saprintf("userid=%d&code=%u&tokenid=%s&tokenval=%s&email=%s", uin, gg_http_hash("u", uin), __tokenid, __tokenval, __email))) {
- gg_debug(GG_DEBUG_MISC, "=> remind, not enough memory for form fields\n");
- free(__tokenid);
- free(__tokenval);
- free(__email);
- return NULL;
- }
-
- free(__tokenid);
- free(__tokenval);
- free(__email);
-
- gg_debug(GG_DEBUG_MISC, "=> remind, %s\n", form);
-
- query = gg_saprintf(
- "Host: " GG_REMIND_HOST "\r\n"
- "Content-Type: application/x-www-form-urlencoded\r\n"
- "User-Agent: " GG_HTTP_USERAGENT "\r\n"
- "Content-Length: %d\r\n"
- "Pragma: no-cache\r\n"
- "\r\n"
- "%s",
- (int) strlen(form), form);
-
- free(form);
-
- if (!query) {
- gg_debug(GG_DEBUG_MISC, "=> remind, not enough memory for query\n");
- return NULL;
- }
-
- if (!(h = gg_http_connect(GG_REMIND_HOST, GG_REMIND_PORT, async, "POST", "/appsvc/fmsendpwd3.asp", query))) {
- gg_debug(GG_DEBUG_MISC, "=> remind, gg_http_connect() failed mysteriously\n");
- free(query);
- return NULL;
- }
-
- h->type = GG_SESSION_REMIND;
-
- free(query);
-
- h->callback = gg_pubdir_watch_fd;
- h->destroy = gg_pubdir_free;
-
- if (!async)
- gg_pubdir_watch_fd(h);
-
- return h;
-}
-
-/*
- * gg_pubdir_watch_fd()
- *
- * przy asynchronicznych operacjach na katalogu publicznym nale�y wywo�ywa�
- * t� funkcj� przy zmianach na obserwowanym deskryptorze.
- *
- * - h - struktura opisuj�ca po��czenie
- *
- * je�li wszystko posz�o dobrze to 0, inaczej -1. operacja b�dzie
- * zako�czona, je�li h->state == GG_STATE_DONE. je�li wyst�pi jaki�
- * b��d, to b�dzie tam GG_STATE_ERROR i odpowiedni kod b��du w h->error.
- */
-int gg_pubdir_watch_fd(struct gg_http *h)
-{
- struct gg_pubdir *p;
- char *tmp;
-
- if (!h) {
- errno = EFAULT;
- return -1;
- }
-
- if (h->state == GG_STATE_ERROR) {
- gg_debug(GG_DEBUG_MISC, "=> pubdir, watch_fd issued on failed session\n");
- errno = EINVAL;
- return -1;
- }
-
- if (h->state != GG_STATE_PARSING) {
- if (gg_http_watch_fd(h) == -1) {
- gg_debug(GG_DEBUG_MISC, "=> pubdir, http failure\n");
- errno = EINVAL;
- return -1;
- }
- }
-
- if (h->state != GG_STATE_PARSING)
- return 0;
-
- h->state = GG_STATE_DONE;
-
- if (!(h->data = p = malloc(sizeof(struct gg_pubdir)))) {
- gg_debug(GG_DEBUG_MISC, "=> pubdir, not enough memory for results\n");
- return -1;
- }
-
- p->success = 0;
- p->uin = 0;
-
- gg_debug(GG_DEBUG_MISC, "=> pubdir, let's parse \"%s\"\n", h->body);
-
- if ((tmp = strstr(h->body, "Tokens okregisterreply_packet.reg.dwUserId="))) {
- p->success = 1;
- p->uin = strtol(tmp + sizeof("Tokens okregisterreply_packet.reg.dwUserId=") - 1, NULL, 0);
- gg_debug(GG_DEBUG_MISC, "=> pubdir, success (okregisterreply, uin=%d)\n", p->uin);
- } else if ((tmp = strstr(h->body, "success")) || (tmp = strstr(h->body, "results"))) {
- p->success = 1;
- if (tmp[7] == ':')
- p->uin = strtol(tmp + 8, NULL, 0);
- gg_debug(GG_DEBUG_MISC, "=> pubdir, success (uin=%d)\n", p->uin);
- } else
- gg_debug(GG_DEBUG_MISC, "=> pubdir, error.\n");
-
- return 0;
-}
-
-/*
- * gg_pubdir_free()
- *
- * zwalnia pami�� po efektach operacji na katalogu publicznym.
- *
- * - h - zwalniana struktura
- */
-void gg_pubdir_free(struct gg_http *h)
-{
- if (!h)
- return;
-
- free(h->data);
- gg_http_free(h);
-}
-
-/*
- * gg_token()
- *
- * pobiera z serwera token do autoryzacji zak�adania konta, usuwania
- * konta i zmiany has�a.
- *
- * zaalokowana struct gg_http, kt�r� po�niej nale�y zwolni�
- * funkcj� gg_token_free(), albo NULL je�li wyst�pi� b��d.
- */
-struct gg_http *gg_token(int async)
-{
- struct gg_http *h;
- const char *query;
-
- query = "Host: " GG_REGISTER_HOST "\r\n"
- "Content-Type: application/x-www-form-urlencoded\r\n"
- "User-Agent: " GG_HTTP_USERAGENT "\r\n"
- "Content-Length: 0\r\n"
- "Pragma: no-cache\r\n"
- "\r\n";
-
- if (!(h = gg_http_connect(GG_REGISTER_HOST, GG_REGISTER_PORT, async, "POST", "/appsvc/regtoken.asp", query))) {
- gg_debug(GG_DEBUG_MISC, "=> token, gg_http_connect() failed mysteriously\n");
- return NULL;
- }
-
- h->type = GG_SESSION_TOKEN;
-
- h->callback = gg_token_watch_fd;
- h->destroy = gg_token_free;
-
- if (!async)
- gg_token_watch_fd(h);
-
- return h;
-}
-
-/*
- * gg_token_watch_fd()
- *
- * przy asynchronicznych operacjach zwi�zanych z tokenem nale�y wywo�ywa�
- * t� funkcj� przy zmianach na obserwowanym deskryptorze.
- *
- * - h - struktura opisuj�ca po��czenie
- *
- * je�li wszystko posz�o dobrze to 0, inaczej -1. operacja b�dzie
- * zako�czona, je�li h->state == GG_STATE_DONE. je�li wyst�pi jaki�
- * b��d, to b�dzie tam GG_STATE_ERROR i odpowiedni kod b��du w h->error.
- */
-int gg_token_watch_fd(struct gg_http *h)
-{
- if (!h) {
- errno = EFAULT;
- return -1;
- }
-
- if (h->state == GG_STATE_ERROR) {
- gg_debug(GG_DEBUG_MISC, "=> token, watch_fd issued on failed session\n");
- errno = EINVAL;
- return -1;
- }
-
- if (h->state != GG_STATE_PARSING) {
- if (gg_http_watch_fd(h) == -1) {
- gg_debug(GG_DEBUG_MISC, "=> token, http failure\n");
- errno = EINVAL;
- return -1;
- }
- }
-
- if (h->state != GG_STATE_PARSING)
- return 0;
-
- /* je�li h->data jest puste, to �ci�gali�my tokenid i url do niego,
- * ale je�li co� tam jest, to znaczy, �e mamy drugi etap polegaj�cy
- * na pobieraniu tokenu. */
- if (!h->data) {
- int width, height, length;
- char *url = NULL, *tokenid = NULL, *path, *headers;
- const char *host;
- struct gg_http *h2;
- struct gg_token *t;
-
- gg_debug(GG_DEBUG_MISC, "=> token body \"%s\"\n", h->body);
-
- if (h->body && (!(url = malloc(strlen(h->body))) || !(tokenid = malloc(strlen(h->body))))) {
- gg_debug(GG_DEBUG_MISC, "=> token, not enough memory for results\n");
- free(url);
- return -1;
- }
-
- if (!h->body || sscanf(h->body, "%d %d %d\r\n%s\r\n%s", &width, &height, &length, tokenid, url) != 5) {
- gg_debug(GG_DEBUG_MISC, "=> token, parsing failed\n");
- free(url);
- free(tokenid);
- errno = EINVAL;
- return -1;
- }
-
- /* dostali�my tokenid i wszystkie niezb�dne informacje,
- * wi�c pobierzmy obrazek z tokenem */
-
- if (strncmp(url, "http://", 7)) {
- path = gg_saprintf("%s?tokenid=%s", url, tokenid);
- host = GG_REGISTER_HOST;
- } else {
- char *slash = (char*)strchr(url + 7, '/');
-
- if (slash) {
- path = gg_saprintf("%s?tokenid=%s", slash, tokenid);
- *slash = 0;
- host = url + 7;
- } else {
- gg_debug(GG_DEBUG_MISC, "=> token, url parsing failed\n");
- free(url);
- free(tokenid);
- errno = EINVAL;
- return -1;
- }
- }
-
- if (!path) {
- gg_debug(GG_DEBUG_MISC, "=> token, not enough memory for token url\n");
- free(url);
- free(tokenid);
- return -1;
- }
-
- if (!(headers = gg_saprintf("Host: %s\r\nUser-Agent: " GG_HTTP_USERAGENT "\r\n\r\n", host))) {
- gg_debug(GG_DEBUG_MISC, "=> token, not enough memory for token url\n");
- free(path);
- free(url);
- free(tokenid);
- return -1;
- }
-
- if (!(h2 = gg_http_connect(host, GG_REGISTER_PORT, h->async, "GET", path, headers))) {
- gg_debug(GG_DEBUG_MISC, "=> token, gg_http_connect() failed mysteriously\n");
- free(headers);
- free(url);
- free(path);
- free(tokenid);
- return -1;
- }
-
- free(headers);
- free(path);
- free(url);
-
- memcpy(h, h2, sizeof(struct gg_http));
- free(h2);
-
- h->type = GG_SESSION_TOKEN;
-
- h->callback = gg_token_watch_fd;
- h->destroy = gg_token_free;
-
- if (!h->async)
- gg_token_watch_fd(h);
-
- if (!(h->data = t = malloc(sizeof(struct gg_token)))) {
- gg_debug(GG_DEBUG_MISC, "=> token, not enough memory for token data\n");
- free(tokenid);
- return -1;
- }
-
- t->width = width;
- t->height = height;
- t->length = length;
- t->tokenid = tokenid;
- } else {
- /* obrazek mamy w h->body */
- h->state = GG_STATE_DONE;
- }
-
- return 0;
-}
-
-/*
- * gg_token_free()
- *
- * zwalnia pami�� po efektach pobierania tokenu.
- *
- * - h - zwalniana struktura
- */
-void gg_token_free(struct gg_http *h)
-{
- struct gg_token *t;
-
- if (!h)
- return;
-
- if ((t = h->data))
- free(t->tokenid);
-
- free(h->data);
- gg_http_free(h);
-}
-
-/*
- * Local variables:
- * c-indentation-style: k&r
- * c-basic-offset: 8
- * indent-tabs-mode: notnil
- * End:
- *
- * vim: shiftwidth=8:
- */
diff --git a/kopete/protocols/gadu/libgadu/pubdir50.c b/kopete/protocols/gadu/libgadu/pubdir50.c
deleted file mode 100644
index 877ab83e..00000000
--- a/kopete/protocols/gadu/libgadu/pubdir50.c
+++ /dev/null
@@ -1,467 +0,0 @@
-/* $Id$ */
-
-/*
- * (C) Copyright 2003 Wojtek Kaniewski <wojtekka@irc.pl>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License Version
- * 2.1 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
- * USA.
- */
-
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-#include "libgadu.h"
-
-/*
- * gg_pubdir50_new()
- *
- * tworzy now± zmienn± typu gg_pubdir50_t.
- *
- * zaalokowana zmienna lub NULL w przypadku braku pamiêci.
- */
-gg_pubdir50_t gg_pubdir50_new(int type)
-{
- gg_pubdir50_t res = malloc(sizeof(struct gg_pubdir50_s));
-
- gg_debug(GG_DEBUG_FUNCTION, "** gg_pubdir50_new(%d);\n", type);
-
- if (!res) {
- gg_debug(GG_DEBUG_MISC, "// gg_pubdir50_new() out of memory\n");
- return NULL;
- }
-
- memset(res, 0, sizeof(struct gg_pubdir50_s));
-
- res->type = type;
-
- return res;
-}
-
-/*
- * gg_pubdir50_add_n() // funkcja wewnêtrzna
- *
- * funkcja dodaje lub zastêpuje istniej±ce pole do zapytania lub odpowiedzi.
- *
- * - req - wska¼nik opisu zapytania,
- * - num - numer wyniku (0 dla zapytania),
- * - field - nazwa pola,
- * - value - warto¶æ pola,
- *
- * 0/-1
- */
-static int gg_pubdir50_add_n(gg_pubdir50_t req, int num, const char *field, const char *value)
-{
- struct gg_pubdir50_entry *tmp = NULL, *entry;
- char *dupfield, *dupvalue;
- int i;
-
- gg_debug(GG_DEBUG_FUNCTION, "** gg_pubdir50_add_n(%p, %d, \"%s\", \"%s\");\n", req, num, field, value);
-
- if (!(dupvalue = strdup(value))) {
- gg_debug(GG_DEBUG_MISC, "// gg_pubdir50_add_n() out of memory\n");
- return -1;
- }
-
- for (i = 0; i < req->entries_count; i++) {
- if (req->entries[i].num != num || strcmp(req->entries[i].field, field))
- continue;
-
- free(req->entries[i].value);
- req->entries[i].value = dupvalue;
-
- return 0;
- }
-
- if (!(dupfield = strdup(field))) {
- gg_debug(GG_DEBUG_MISC, "// gg_pubdir50_add_n() out of memory\n");
- free(dupvalue);
- return -1;
- }
-
- if (!(tmp = realloc(req->entries, sizeof(struct gg_pubdir50_entry) * (req->entries_count + 1)))) {
- gg_debug(GG_DEBUG_MISC, "// gg_pubdir50_add_n() out of memory\n");
- free(dupfield);
- free(dupvalue);
- return -1;
- }
-
- req->entries = tmp;
-
- entry = &req->entries[req->entries_count];
- entry->num = num;
- entry->field = dupfield;
- entry->value = dupvalue;
-
- req->entries_count++;
-
- return 0;
-}
-
-/*
- * gg_pubdir50_add()
- *
- * funkcja dodaje pole do zapytania.
- *
- * - req - wska¼nik opisu zapytania,
- * - field - nazwa pola,
- * - value - warto¶æ pola,
- *
- * 0/-1
- */
-int gg_pubdir50_add(gg_pubdir50_t req, const char *field, const char *value)
-{
- return gg_pubdir50_add_n(req, 0, field, value);
-}
-
-/*
- * gg_pubdir50_seq_set()
- *
- * ustawia numer sekwencyjny zapytania.
- *
- * - req - zapytanie,
- * - seq - nowy numer sekwencyjny.
- *
- * 0/-1.
- */
-int gg_pubdir50_seq_set(gg_pubdir50_t req, uint32_t seq)
-{
- gg_debug(GG_DEBUG_FUNCTION, "** gg_pubdir50_seq_set(%p, %d);\n", req, seq);
-
- if (!req) {
- gg_debug(GG_DEBUG_MISC, "// gg_pubdir50_seq_set() invalid arguments\n");
- errno = EFAULT;
- return -1;
- }
-
- req->seq = seq;
-
- return 0;
-}
-
-/*
- * gg_pubdir50_free()
- *
- * zwalnia pamiêæ po zapytaniu lub rezultacie szukania u¿ytkownika.
- *
- * - s - zwalniana zmienna,
- */
-void gg_pubdir50_free(gg_pubdir50_t s)
-{
- int i;
-
- if (!s)
- return;
-
- for (i = 0; i < s->entries_count; i++) {
- free(s->entries[i].field);
- free(s->entries[i].value);
- }
-
- free(s->entries);
- free(s);
-}
-
-/*
- * gg_pubdir50()
- *
- * wysy³a zapytanie katalogu publicznego do serwera.
- *
- * - sess - sesja,
- * - req - zapytanie.
- *
- * numer sekwencyjny wyszukiwania lub 0 w przypadku b³êdu.
- */
-uint32_t gg_pubdir50(struct gg_session *sess, gg_pubdir50_t req)
-{
- int i, size = 5;
- uint32_t res;
- char *buf, *p;
- struct gg_pubdir50_request *r;
-
- gg_debug(GG_DEBUG_FUNCTION, "** gg_pubdir50(%p, %p);\n", sess, req);
-
- if (!sess || !req) {
- gg_debug(GG_DEBUG_MISC, "// gg_pubdir50() invalid arguments\n");
- errno = EFAULT;
- return 0;
- }
-
- if (sess->state != GG_STATE_CONNECTED) {
- gg_debug(GG_DEBUG_MISC, "// gg_pubdir50() not connected\n");
- errno = ENOTCONN;
- return 0;
- }
-
- for (i = 0; i < req->entries_count; i++) {
- /* wyszukiwanie bierze tylko pierwszy wpis */
- if (req->entries[i].num)
- continue;
-
- size += strlen(req->entries[i].field) + 1;
- size += strlen(req->entries[i].value) + 1;
- }
-
- if (!(buf = malloc(size))) {
- gg_debug(GG_DEBUG_MISC, "// gg_pubdir50() out of memory (%d bytes)\n", size);
- return 0;
- }
-
- r = (struct gg_pubdir50_request*) buf;
- res = time(NULL);
- r->type = req->type;
- r->seq = (req->seq) ? gg_fix32(req->seq) : gg_fix32(time(NULL));
- req->seq = gg_fix32(r->seq);
-
- for (i = 0, p = buf + 5; i < req->entries_count; i++) {
- if (req->entries[i].num)
- continue;
-
- strcpy(p, req->entries[i].field);
- p += strlen(p) + 1;
-
- strcpy(p, req->entries[i].value);
- p += strlen(p) + 1;
- }
-
- if (gg_send_packet(sess, GG_PUBDIR50_REQUEST, buf, size, NULL, 0) == -1)
- res = 0;
-
- free(buf);
-
- return res;
-}
-
-/*
- * gg_pubdir50_handle_reply() // funkcja wewnêtrzna
- *
- * analizuje przychodz±cy pakiet odpowiedzi i zapisuje wynik w struct gg_event.
- *
- * - e - opis zdarzenia
- * - packet - zawarto¶æ pakietu odpowiedzi
- * - length - d³ugo¶æ pakietu odpowiedzi
- *
- * 0/-1
- */
-int gg_pubdir50_handle_reply(struct gg_event *e, const char *packet, int length)
-{
- const char *end = packet + length, *p;
- struct gg_pubdir50_reply *r = (struct gg_pubdir50_reply*) packet;
- gg_pubdir50_t res;
- int num = 0;
-
- gg_debug(GG_DEBUG_FUNCTION, "** gg_pubdir50_handle_reply(%p, %p, %d);\n", e, packet, length);
-
- if (!e || !packet) {
- gg_debug(GG_DEBUG_MISC, "// gg_pubdir50_handle_reply() invalid arguments\n");
- errno = EFAULT;
- return -1;
- }
-
- if (length < 5) {
- gg_debug(GG_DEBUG_MISC, "// gg_pubdir50_handle_reply() packet too short\n");
- errno = EINVAL;
- return -1;
- }
-
- if (!(res = gg_pubdir50_new(r->type))) {
- gg_debug(GG_DEBUG_MISC, "// gg_pubdir50_handle_reply() unable to allocate reply\n");
- return -1;
- }
-
- e->event.pubdir50 = res;
-
- res->seq = gg_fix32(r->seq);
-
- switch (res->type) {
- case GG_PUBDIR50_READ:
- e->type = GG_EVENT_PUBDIR50_READ;
- break;
-
- case GG_PUBDIR50_WRITE:
- e->type = GG_EVENT_PUBDIR50_WRITE;
- break;
-
- default:
- e->type = GG_EVENT_PUBDIR50_SEARCH_REPLY;
- break;
- }
-
- /* brak wyników? */
- if (length == 5)
- return 0;
-
- /* pomiñ pocz±tek odpowiedzi */
- p = packet + 5;
-
- while (p < end) {
- const char *field, *value;
-
- field = p;
-
- /* sprawd¼, czy nie mamy podzia³u na kolejne pole */
- if (!*field) {
- num++;
- field++;
- }
-
- value = NULL;
-
- for (p = field; p < end; p++) {
- /* je¶li mamy koniec tekstu... */
- if (!*p) {
- /* ...i jeszcze nie mieli¶my warto¶ci pola to
- * wiemy, ¿e po tym zerze jest warto¶æ... */
- if (!value)
- value = p + 1;
- else
- /* ...w przeciwym wypadku koniec
- * warto¶ci i mo¿emy wychodziæ
- * grzecznie z pêtli */
- break;
- }
- }
-
- /* sprawd¼my, czy pole nie wychodzi poza pakiet, ¿eby nie
- * mieæ segfaultów, je¶li serwer przestanie zakañczaæ pakietów
- * przez \0 */
-
- if (p == end) {
- gg_debug(GG_DEBUG_MISC, "// gg_pubdir50_handle_reply() premature end of packet\n");
- goto failure;
- }
-
- p++;
-
- /* je¶li dostali¶my namier na nastêpne wyniki, to znaczy ¿e
- * mamy koniec wyników i nie jest to kolejna osoba. */
- if (!strcasecmp(field, "nextstart")) {
- res->next = atoi(value);
- num--;
- } else {
- if (gg_pubdir50_add_n(res, num, field, value) == -1)
- goto failure;
- }
- }
-
- res->count = num + 1;
-
- return 0;
-
-failure:
- gg_pubdir50_free(res);
- return -1;
-}
-
-/*
- * gg_pubdir50_get()
- *
- * pobiera informacjê z rezultatu wyszukiwania.
- *
- * - res - rezultat wyszukiwania,
- * - num - numer odpowiedzi,
- * - field - nazwa pola (wielko¶æ liter nie ma znaczenia).
- *
- * warto¶æ pola lub NULL, je¶li nie znaleziono.
- */
-const char *gg_pubdir50_get(gg_pubdir50_t res, int num, const char *field)
-{
- char *value = NULL;
- int i;
-
- gg_debug(GG_DEBUG_FUNCTION, "** gg_pubdir50_get(%p, %d, \"%s\");\n", res, num, field);
-
- if (!res || num < 0 || !field) {
- gg_debug(GG_DEBUG_MISC, "// gg_pubdir50_get() invalid arguments\n");
- errno = EINVAL;
- return NULL;
- }
-
- for (i = 0; i < res->entries_count; i++) {
- if (res->entries[i].num == num && !strcasecmp(res->entries[i].field, field)) {
- value = res->entries[i].value;
- break;
- }
- }
-
- return value;
-}
-
-/*
- * gg_pubdir50_count()
- *
- * zwraca ilo¶æ wyników danego zapytania.
- *
- * - res - odpowied¼
- *
- * ilo¶æ lub -1 w przypadku b³êdu.
- */
-int gg_pubdir50_count(gg_pubdir50_t res)
-{
- return (!res) ? -1 : res->count;
-}
-
-/*
- * gg_pubdir50_type()
- *
- * zwraca rodzaj zapytania lub odpowiedzi.
- *
- * - res - zapytanie lub odpowied¼
- *
- * ilo¶æ lub -1 w przypadku b³êdu.
- */
-int gg_pubdir50_type(gg_pubdir50_t res)
-{
- return (!res) ? -1 : res->type;
-}
-
-/*
- * gg_pubdir50_next()
- *
- * zwraca numer, od którego nale¿y rozpocz±æ kolejne wyszukiwanie, je¶li
- * zale¿y nam na kolejnych wynikach.
- *
- * - res - odpowied¼
- *
- * numer lub -1 w przypadku b³êdu.
- */
-uin_t gg_pubdir50_next(gg_pubdir50_t res)
-{
- return (!res) ? (unsigned) -1 : res->next;
-}
-
-/*
- * gg_pubdir50_seq()
- *
- * zwraca numer sekwencyjny zapytania lub odpowiedzi.
- *
- * - res - zapytanie lub odpowied¼
- *
- * numer lub -1 w przypadku b³êdu.
- */
-uint32_t gg_pubdir50_seq(gg_pubdir50_t res)
-{
- return (!res) ? (unsigned) -1 : res->seq;
-}
-
-/*
- * Local variables:
- * c-indentation-style: k&r
- * c-basic-offset: 8
- * indent-tabs-mode: notnil
- * End:
- *
- * vim: shiftwidth=8:
- */
diff --git a/kopete/protocols/gadu/ui/CMakeLists.txt b/kopete/protocols/gadu/ui/CMakeLists.txt
new file mode 100644
index 00000000..10b5b07d
--- /dev/null
+++ b/kopete/protocols/gadu/ui/CMakeLists.txt
@@ -0,0 +1,28 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_BINARY_DIR}/kopete/libkopete/ui
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete/ui
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+
+##### gaduui (static) ###########################
+
+tde_add_library( gaduui STATIC_PIC AUTOMOC
+ SOURCES
+ gaduadd.ui gadusearch.ui gadueditaccountui.ui gaduawayui.ui
+ gaduregisteraccountui.ui empty.cpp
+)
diff --git a/kopete/protocols/groupwise/CMakeLists.txt b/kopete/protocols/groupwise/CMakeLists.txt
new file mode 100644
index 00000000..c6df3323
--- /dev/null
+++ b/kopete/protocols/groupwise/CMakeLists.txt
@@ -0,0 +1,50 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+add_subdirectory( icons )
+add_subdirectory( libgroupwise )
+add_subdirectory( ui )
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR}/ui
+ ${CMAKE_CURRENT_SOURCE_DIR}/libgroupwise
+ ${CMAKE_CURRENT_SOURCE_DIR}/libgroupwise/tasks
+ ${CMAKE_CURRENT_SOURCE_DIR}/libgroupwise/qca/src
+ ${CMAKE_CURRENT_SOURCE_DIR}/ui
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete/ui
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+link_directories(
+ ${TQT_LIBRARY_DIRS}
+)
+
+
+##### other data ################################
+
+install( FILES kopete_groupwise.desktop DESTINATION ${SERVICES_INSTALL_DIR} )
+install( FILES gwchatui.rc DESTINATION ${DATA_INSTALL_DIR}/kopete_groupwise )
+
+
+##### kopete_groupwise (module) #################
+
+tde_add_kpart( kopete_groupwise AUTOMOC
+ SOURCES
+ gwprotocol.cpp gwcontact.cpp gwaccount.cpp gwbytestream.cpp
+ gwconnector.cpp gwmessagemanager.cpp gwcontactlist.cpp
+ LINK
+ kopetegroupwiseui-static groupwise-static groupwise_tasks-static
+ groupwise_qca-static kopete-shared
+ DESTINATION ${PLUGIN_INSTALL_DIR}
+)
diff --git a/kopete/protocols/groupwise/icons/CMakeLists.txt b/kopete/protocols/groupwise/icons/CMakeLists.txt
new file mode 100644
index 00000000..ba51467b
--- /dev/null
+++ b/kopete/protocols/groupwise/icons/CMakeLists.txt
@@ -0,0 +1,12 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+tde_install_icons( DESTINATION ${DATA_INSTALL_DIR}/kopete/icons )
diff --git a/kopete/protocols/groupwise/libgroupwise/CMakeLists.txt b/kopete/protocols/groupwise/libgroupwise/CMakeLists.txt
new file mode 100644
index 00000000..ef158cd9
--- /dev/null
+++ b/kopete/protocols/groupwise/libgroupwise/CMakeLists.txt
@@ -0,0 +1,53 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+add_subdirectory( qca )
+add_subdirectory( tasks )
+
+# add_definitions(
+# -DUSE_TLSHANDLER
+# )
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/qca/src
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+
+##### groupwise (static) ########################
+
+tde_add_library( groupwise STATIC_PIC AUTOMOC
+ SOURCES
+ bytestream.cpp chatroommanager.cpp client.cpp connector.cpp
+ coreprotocol.cpp eventprotocol.cpp eventtransfer.cpp
+ gwclientstream.cpp gwerror.cpp gwfield.cpp gwglobal.cpp
+ inputprotocolbase.cpp privacymanager.cpp qcatlshandler.cpp
+ request.cpp requestfactory.cpp response.cpp responseprotocol.cpp
+ rtf.cc safedelete.cpp securestream.cpp stream.cpp task.cpp
+ tlshandler.cpp transfer.cpp transferbase.cpp userdetailsmanager.cpp
+ usertransfer.cpp
+)
+
+
+##### gwtest (static) ###########################
+
+tde_add_library( gwtest STATIC_PIC AUTOMOC
+ SOURCES
+ coreprotocol.cpp eventtransfer.cpp gwfield.cpp request.cpp
+ requestfactory.cpp transfer.cpp usertransfer.cpp client.cpp task.cpp
+ safedelete.cpp gwclientstream.cpp qcatlshandler.cpp stream.cpp
+ tlshandler.cpp response.cpp connector.cpp securestream.cpp
+ bytestream.cpp
+)
diff --git a/kopete/protocols/groupwise/libgroupwise/qca/CMakeLists.txt b/kopete/protocols/groupwise/libgroupwise/qca/CMakeLists.txt
new file mode 100644
index 00000000..7356f221
--- /dev/null
+++ b/kopete/protocols/groupwise/libgroupwise/qca/CMakeLists.txt
@@ -0,0 +1,12 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+add_subdirectory( src )
diff --git a/kopete/protocols/groupwise/libgroupwise/qca/src/CMakeLists.txt b/kopete/protocols/groupwise/libgroupwise/qca/src/CMakeLists.txt
new file mode 100644
index 00000000..9c74e339
--- /dev/null
+++ b/kopete/protocols/groupwise/libgroupwise/qca/src/CMakeLists.txt
@@ -0,0 +1,22 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+
+##### groupwise_qca (static) ####################
+
+tde_add_library( groupwise_qca STATIC_PIC AUTOMOC
+ SOURCES qca.cpp
+)
diff --git a/kopete/protocols/groupwise/libgroupwise/tasks/CMakeLists.txt b/kopete/protocols/groupwise/libgroupwise/tasks/CMakeLists.txt
new file mode 100644
index 00000000..1fc4a60a
--- /dev/null
+++ b/kopete/protocols/groupwise/libgroupwise/tasks/CMakeLists.txt
@@ -0,0 +1,38 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/..
+ ${CMAKE_CURRENT_SOURCE_DIR}/../qca/src
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+
+##### groupwise_tasks (static) ##################
+
+tde_add_library( groupwise_tasks STATIC_PIC AUTOMOC
+ SOURCES
+ requesttask.cpp eventtask.cpp logintask.cpp setstatustask.cpp
+ statustask.cpp conferencetask.cpp createconferencetask.cpp
+ sendmessagetask.cpp getdetailstask.cpp getstatustask.cpp
+ typingtask.cpp connectiontask.cpp sendinvitetask.cpp
+ joinconferencetask.cpp leaveconferencetask.cpp rejectinvitetask.cpp
+ keepalivetask.cpp createcontacttask.cpp modifycontactlisttask.cpp
+ createfoldertask.cpp movecontacttask.cpp updateitemtask.cpp
+ createcontactinstancetask.cpp deleteitemtask.cpp updatefoldertask.cpp
+ updatecontacttask.cpp pollsearchresultstask.cpp privacyitemtask.cpp
+ needfoldertask.cpp searchchattask.cpp searchusertask.cpp
+ searchusertask.h getchatsearchresultstask.cpp chatcountstask.cpp
+ chatpropertiestask.cpp joinchattask.cpp
+)
diff --git a/kopete/protocols/groupwise/ui/CMakeLists.txt b/kopete/protocols/groupwise/ui/CMakeLists.txt
new file mode 100644
index 00000000..2045bef7
--- /dev/null
+++ b/kopete/protocols/groupwise/ui/CMakeLists.txt
@@ -0,0 +1,35 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/../libgroupwise
+ ${CMAKE_CURRENT_SOURCE_DIR}/../libgroupwise/qca/src
+ ${CMAKE_CURRENT_SOURCE_DIR}/..
+ ${CMAKE_BINARY_DIR}/kopete/libkopete/ui
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete/ui
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+
+##### kopetegroupwiseui (static) ################
+
+tde_add_library( kopetegroupwiseui STATIC_PIC AUTOMOC
+ SOURCES
+ gwaccountpreferences.ui gwaddcontactpage.cpp gwaddui.ui
+ gweditaccountwidget.cpp gwreceiveinvitationdialog.cpp
+ gwshowinvitation.ui gwcontactpropswidget.ui gwcontactproperties.cpp
+ gwprivacy.ui gwprivacydialog.cpp gwsearch.cpp gwcustomstatuswidget.ui
+ gwcustomstatusedit.ui gwcontactsearch.ui gwchatsearchwidget.ui
+ gwchatsearchdialog.cpp gwchatpropswidget.ui gwchatpropsdialog.cpp
+)
diff --git a/kopete/protocols/irc/CMakeLists.txt b/kopete/protocols/irc/CMakeLists.txt
new file mode 100644
index 00000000..6c795704
--- /dev/null
+++ b/kopete/protocols/irc/CMakeLists.txt
@@ -0,0 +1,54 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+add_subdirectory( icons )
+add_subdirectory( libkirc )
+add_subdirectory( ui )
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR}/ui
+ ${CMAKE_CURRENT_SOURCE_DIR}/ui
+ ${CMAKE_CURRENT_SOURCE_DIR}/libkirc
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete/ui
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+link_directories(
+ ${TQT_LIBRARY_DIRS}
+)
+
+
+##### other data ################################
+
+install( FILES
+ kopete_irc.desktop irc.protocol
+ DESTINATION ${SERVICES_INSTALL_DIR} )
+
+install( FILES
+ ircnetworks.xml ircchatui.rc
+ DESTINATION ${DATA_INSTALL_DIR}/kopete )
+
+
+##### kopete_irc (module) #######################
+
+tde_add_kpart( kopete_irc AUTOMOC
+ SOURCES
+ ircaccount.cpp ircaddcontactpage.cpp ircchannelcontact.cpp
+ irccontact.cpp ircguiclient.cpp ircprotocol.cpp ircservercontact.cpp
+ ircsignalhandler.cpp irctransferhandler.cpp ircusercontact.cpp
+ irccontactmanager.cpp kcodecaction.cpp ksparser.cpp
+ LINK
+ kopeteircui-static kirc-static kopete-shared
+ DESTINATION ${PLUGIN_INSTALL_DIR}
+)
diff --git a/kopete/protocols/irc/icons/CMakeLists.txt b/kopete/protocols/irc/icons/CMakeLists.txt
new file mode 100644
index 00000000..ba51467b
--- /dev/null
+++ b/kopete/protocols/irc/icons/CMakeLists.txt
@@ -0,0 +1,12 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+tde_install_icons( DESTINATION ${DATA_INSTALL_DIR}/kopete/icons )
diff --git a/kopete/protocols/irc/libkirc/CMakeLists.txt b/kopete/protocols/irc/libkirc/CMakeLists.txt
new file mode 100644
index 00000000..d2b298c2
--- /dev/null
+++ b/kopete/protocols/irc/libkirc/CMakeLists.txt
@@ -0,0 +1,30 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/..
+ ${CMAKE_BINARY_DIR}
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+
+##### kirc (static) #############################
+
+tde_add_library( kirc STATIC_PIC AUTOMOC
+ SOURCES
+ kircengine.cpp kircengine_commands.cpp kircengine_ctcp.cpp
+ kircengine_numericreplies.cpp kircentity.cpp kircmessage.cpp
+ kircmessageredirector.cpp kirctransfer.cpp kirctransferhandler.cpp
+ kirctransferserver.cpp ksslsocket.cpp
+)
diff --git a/kopete/protocols/irc/libkirc/kircentity.h b/kopete/protocols/irc/libkirc/kircentity.h
index d802d8f4..1878a406 100644
--- a/kopete/protocols/irc/libkirc/kircentity.h
+++ b/kopete/protocols/irc/libkirc/kircentity.h
@@ -39,7 +39,7 @@ class Entity
Q_OBJECT
public:
- typedef enum Type
+ enum Type
{
Unknown,
Server,
diff --git a/kopete/protocols/irc/ui/CMakeLists.txt b/kopete/protocols/irc/ui/CMakeLists.txt
new file mode 100644
index 00000000..7d77d5b8
--- /dev/null
+++ b/kopete/protocols/irc/ui/CMakeLists.txt
@@ -0,0 +1,30 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/..
+ ${CMAKE_CURRENT_SOURCE_DIR}/../libkirc
+ ${CMAKE_BINARY_DIR}/kopete/libkopete/ui
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete/ui
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+
+##### kopeteircui (static) ######################
+
+tde_add_library( kopeteircui STATIC_PIC AUTOMOC
+ SOURCES
+ ircadd.ui empty.cpp irceditaccountwidget.cpp irceditaccount.ui
+ channellist.cpp channellistdialog.cpp networkconfig.ui
+)
diff --git a/kopete/protocols/jabber/CMakeLists.txt b/kopete/protocols/jabber/CMakeLists.txt
new file mode 100644
index 00000000..d3fb6d79
--- /dev/null
+++ b/kopete/protocols/jabber/CMakeLists.txt
@@ -0,0 +1,85 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+add_subdirectory( ui )
+add_subdirectory( icons )
+add_subdirectory( libiris )
+add_subdirectory( kioslave )
+
+if( WITH_JINGLE )
+ add_subdirectory( jingle )
+ set( SUPPORT_JINGLE 1 CACHE INTERNAL "" FORCE )
+ set( JINGLE_LIBRARIES
+ kopetejabberjingle-static cricketsessionphone-static cricketxmllite-static
+ cricketp2pclient-static cricketxmpp-static cricketp2pbase-static cricketbase-static
+ mediastreamer-static ortp-static
+ ${GLIB2_LIBRARIES} ${GTHREAD2_LIBRARIES} ${GMODULE2_LIBRARIES}
+ ${EXPAT_LIBRARY} ${SPEEX_LIBRARIES} pthread
+ )
+endif( )
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR}/ui
+ ${CMAKE_CURRENT_BINARY_DIR}/jingle
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/libiris/iris/include
+ ${CMAKE_CURRENT_SOURCE_DIR}/libiris/iris/jabber
+ ${CMAKE_CURRENT_SOURCE_DIR}/libiris/iris/xmpp-im
+ ${CMAKE_CURRENT_SOURCE_DIR}/libiris/qca/src
+ ${CMAKE_CURRENT_SOURCE_DIR}/libiris/cutestuff/util
+ ${CMAKE_CURRENT_SOURCE_DIR}/libiris/cutestuff/network
+ ${CMAKE_CURRENT_SOURCE_DIR}/ui
+ ${CMAKE_CURRENT_SOURCE_DIR}/jingle
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../libkopete
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../libkopete/ui
+ ${CMAKE_BINARY_DIR}
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+link_directories(
+ ${TQT_LIBRARY_DIRS}
+)
+
+
+##### other data ################################
+
+install( FILES kopete_jabber.desktop DESTINATION ${SERVICES_INSTALL_DIR} )
+install( FILES jabberchatui.rc DESTINATION ${DATA_INSTALL_DIR}/kopete_jabber )
+
+
+##### jabberclient (static) #####################
+
+tde_add_library( jabberclient STATIC_PIC AUTOMOC
+ SOURCES
+ jabberclient.cpp jabberconnector.cpp jabberbytestream.cpp
+)
+
+
+##### kopete_jabber (module) ####################
+
+tde_add_kpart( kopete_jabber AUTOMOC
+ SOURCES
+ jabberprotocol.cpp jabberaccount.cpp jabberresource.cpp
+ jabberresourcepool.cpp jabberbasecontact.cpp jabbercontact.cpp
+ jabbergroupcontact.cpp jabbergroupmembercontact.cpp
+ jabbercontactpool.cpp jabberformtranslator.cpp jabberformlineedit.cpp
+ jabberchatsession.cpp jabbergroupchatmanager.cpp
+ jabberfiletransfer.cpp jabbercapabilitiesmanager.cpp
+ jabbertransport.cpp jabberbookmarks.cpp
+ LINK
+ jabberclient-static kopetejabberui-static
+ iris_jabber-static iris_xmpp_core-static iris_xmpp_im-static iris-static
+ qca-static cutestuff_network-static cutestuff_util-static ${JINGLE_LIBRARIES}
+ kopete-shared
+ DESTINATION ${PLUGIN_INSTALL_DIR}
+)
diff --git a/kopete/protocols/jabber/icons/CMakeLists.txt b/kopete/protocols/jabber/icons/CMakeLists.txt
new file mode 100644
index 00000000..37a5c370
--- /dev/null
+++ b/kopete/protocols/jabber/icons/CMakeLists.txt
@@ -0,0 +1,12 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+tde_install_icons( )
diff --git a/kopete/protocols/jabber/jingle/CMakeLists.txt b/kopete/protocols/jabber/jingle/CMakeLists.txt
new file mode 100644
index 00000000..18bbf758
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/CMakeLists.txt
@@ -0,0 +1,38 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+add_subdirectory( libjingle )
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/libjingle
+ ${CMAKE_CURRENT_SOURCE_DIR}/../libiris/iris/include
+ ${CMAKE_CURRENT_SOURCE_DIR}/../libiris/iris/xmpp-im
+ ${CMAKE_CURRENT_SOURCE_DIR}/../libiris/iris/jabber
+ ${CMAKE_CURRENT_SOURCE_DIR}/../libiris/cutestuff/util
+ ${CMAKE_CURRENT_SOURCE_DIR}/..
+ ${CMAKE_BINARY_DIR}
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete/ui
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+
+##### kopetejabberjingle (static) ###############
+
+tde_moc( MOCS voicecaller.h )
+
+tde_add_library( kopetejabberjingle STATIC_PIC AUTOMOC
+ SOURCES
+ jinglevoicecaller.cpp jinglevoicesessiondialogbase.ui
+ jinglevoicesessiondialog.cpp ${MOCS}
+)
diff --git a/kopete/protocols/jabber/jingle/jinglevoicecaller.cpp b/kopete/protocols/jabber/jingle/jinglevoicecaller.cpp
index dd809cea..12e4b93d 100644
--- a/kopete/protocols/jabber/jingle/jinglevoicecaller.cpp
+++ b/kopete/protocols/jabber/jingle/jinglevoicecaller.cpp
@@ -374,3 +374,5 @@ cricket::Thread* JingleVoiceCaller::thread_ = NULL;
cricket::NetworkManager* JingleVoiceCaller::network_manager_ = NULL;
cricket::BasicPortAllocator* JingleVoiceCaller::port_allocator_ = NULL;
cricket::SocketAddress* JingleVoiceCaller::stun_addr_ = NULL;
+
+#include "jinglevoicecaller.moc"
diff --git a/kopete/protocols/jabber/jingle/libjingle/CMakeLists.txt b/kopete/protocols/jabber/jingle/libjingle/CMakeLists.txt
new file mode 100644
index 00000000..0aa34648
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/CMakeLists.txt
@@ -0,0 +1,12 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+add_subdirectory( talk )
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/CMakeLists.txt b/kopete/protocols/jabber/jingle/libjingle/talk/CMakeLists.txt
new file mode 100644
index 00000000..1a1d0416
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/CMakeLists.txt
@@ -0,0 +1,19 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+include( ConfigureChecks.cmake )
+
+add_subdirectory( base )
+add_subdirectory( p2p )
+add_subdirectory( xmllite )
+add_subdirectory( xmpp )
+add_subdirectory( session )
+add_subdirectory( third_party )
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/ConfigureChecks.cmake b/kopete/protocols/jabber/jingle/libjingle/talk/ConfigureChecks.cmake
new file mode 100644
index 00000000..396efa92
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/ConfigureChecks.cmake
@@ -0,0 +1,48 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+# gthread-2.0
+pkg_search_module( GTHREAD2 gthread-2.0 )
+if( NOT GTHREAD2_FOUND )
+ tde_message_fatal( "gthread-2.0 is required, but was not found on your system" )
+endif( )
+
+
+# gmodule-2.0
+pkg_search_module( GMODULE2 gmodule-2.0 )
+if( NOT GMODULE2_FOUND )
+ tde_message_fatal( "gmodule-2.0 are required, but not found on your system" )
+endif( )
+
+
+# speex
+if( WITH_SPEEX )
+ pkg_search_module( SPEEX speex )
+ if( SPEEX_FOUND )
+ set( HAVE_SPEEX 1 CACHE INTERNAL "" FORCE )
+ if( NOT SPEEX_INCLUDE_DIRS )
+ set( SPEEX_INCLUDE_DIRS "/usr/include/speex" )
+ endif( )
+ else( )
+ tde_message_fatal( "speex is required, but was not found on your system" )
+ endif( )
+endif( )
+
+# expat
+check_include_file( expat.h HAVE_EXPAT_H )
+if( HAVE_EXPAT_H )
+ check_library_exists( expat XML_ParserCreate "" HAVE_EXPAT )
+endif( )
+if( HAVE_EXPAT_H AND HAVE_EXPAT )
+ set( EXPAT_LIBRARY expat CACHE INTERNAL "" FORCE )
+else( )
+ tde_message_fatal( "expat is required, but was not found on your system" )
+endif( )
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/base/CMakeLists.txt b/kopete/protocols/jabber/jingle/libjingle/talk/base/CMakeLists.txt
new file mode 100644
index 00000000..8f037a9a
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/base/CMakeLists.txt
@@ -0,0 +1,32 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+add_definitions(
+ -DPOSIX
+)
+
+include_directories(
+ ${CMAKE_CURRENT_SOURCE_DIR}/../..
+ ${CMAKE_BINARY_DIR}
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+
+##### cricketbase (static) ######################
+
+tde_add_library( cricketbase STATIC_PIC
+ SOURCES
+ socketaddress.cc jtime.cc asyncudpsocket.cc messagequeue.cc
+ thread.cc physicalsocketserver.cc bytebuffer.cc asyncpacketsocket.cc
+ network.cc asynctcpsocket.cc socketadapters.cc md5c.c base64.cc
+ task.cc taskrunner.cc host.cc socketaddresspair.cc
+)
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/base/asynctcpsocket.cc b/kopete/protocols/jabber/jingle/libjingle/talk/base/asynctcpsocket.cc
index 6d4697a6..8bf66a38 100644
--- a/kopete/protocols/jabber/jingle/libjingle/talk/base/asynctcpsocket.cc
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/base/asynctcpsocket.cc
@@ -32,6 +32,7 @@
#include "talk/base/byteorder.h"
#include "talk/base/common.h"
#include "talk/base/logging.h"
+#include <cstring>
#if defined(_MSC_VER) && _MSC_VER < 1300
namespace std {
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/base/bytebuffer.cc b/kopete/protocols/jabber/jingle/libjingle/talk/base/bytebuffer.cc
index 067f50ed..e3af08b7 100644
--- a/kopete/protocols/jabber/jingle/libjingle/talk/base/bytebuffer.cc
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/base/bytebuffer.cc
@@ -30,6 +30,7 @@
#include "talk/base/byteorder.h"
#include <algorithm>
#include <cassert>
+#include <cstring>
#if defined(_MSC_VER) && _MSC_VER < 1300
namespace std {
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/base/host.cc b/kopete/protocols/jabber/jingle/libjingle/talk/base/host.cc
index 7b7490d9..f604050f 100644
--- a/kopete/protocols/jabber/jingle/libjingle/talk/base/host.cc
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/base/host.cc
@@ -30,6 +30,8 @@
#include "talk/base/network.h"
#include "talk/base/socket.h"
#include <string>
+#include <cstring>
+#include <cstdlib>
#include <iostream>
#include <cassert>
#include <errno.h>
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/base/messagequeue.h b/kopete/protocols/jabber/jingle/libjingle/talk/base/messagequeue.h
index 2a9cbed6..9b35b9af 100644
--- a/kopete/protocols/jabber/jingle/libjingle/talk/base/messagequeue.h
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/base/messagequeue.h
@@ -32,6 +32,7 @@
#include "talk/base/criticalsection.h"
#include "talk/base/socketserver.h"
#include "talk/base/jtime.h"
+#include <string.h>
#include <vector>
#include <queue>
#include <algorithm>
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/base/physicalsocketserver.cc b/kopete/protocols/jabber/jingle/libjingle/talk/base/physicalsocketserver.cc
index 91d2daad..37836302 100644
--- a/kopete/protocols/jabber/jingle/libjingle/talk/base/physicalsocketserver.cc
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/base/physicalsocketserver.cc
@@ -30,6 +30,7 @@
#endif
#include <cassert>
+#include <algorithm>
#ifdef POSIX
extern "C" {
@@ -37,6 +38,7 @@ extern "C" {
#include <fcntl.h>
#include <sys/time.h>
#include <unistd.h>
+#include <string.h>
}
#endif
@@ -59,9 +61,6 @@ extern "C" {
#include <windows.h>
#undef SetPort
-#include <algorithm>
-#include <iostream>
-
class WinsockInitializer {
public:
WinsockInitializer() {
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/base/socketadapters.cc b/kopete/protocols/jabber/jingle/libjingle/talk/base/socketadapters.cc
index 049e923c..f57043e3 100644
--- a/kopete/protocols/jabber/jingle/libjingle/talk/base/socketadapters.cc
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/base/socketadapters.cc
@@ -42,6 +42,7 @@
#endif
#include <cassert>
+#include <cstring>
#include "talk/base/base64.h"
#include "talk/base/basicdefs.h"
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/p2p/CMakeLists.txt b/kopete/protocols/jabber/jingle/libjingle/talk/p2p/CMakeLists.txt
new file mode 100644
index 00000000..1708f179
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/p2p/CMakeLists.txt
@@ -0,0 +1,13 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+add_subdirectory( base )
+add_subdirectory( client )
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/p2p/base/CMakeLists.txt b/kopete/protocols/jabber/jingle/libjingle/talk/p2p/base/CMakeLists.txt
new file mode 100644
index 00000000..ba05a061
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/p2p/base/CMakeLists.txt
@@ -0,0 +1,52 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+add_definitions(
+ -DPOSIX
+)
+
+include_directories(
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../..
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+
+##### cricketp2pbase (static) ###################
+
+tde_add_library( cricketp2pbase STATIC_PIC
+ SOURCES
+ stun.cc port.cc udpport.cc tcpport.cc helpers.cc sessionmanager.cc
+ session.cc p2psocket.cc relayport.cc stunrequest.cc stunport.cc
+ socketmanager.cc
+)
+
+
+##### relayserver (executable) ##################
+
+tde_add_executable( relayserver
+ SOURCES
+ relayserver.cc relayserver_main.cc
+ LINK
+ cricketbase-static cricketp2pbase-static pthread
+ DESTINATION ${BIN_INSTALL_DIR}
+)
+
+
+##### stunserver (executable) ###################
+
+tde_add_executable( stunserver
+ SOURCES
+ stunserver.cc stunserver_main.cc
+ LINK
+ cricketbase-static cricketp2pbase-static pthread
+ DESTINATION ${BIN_INSTALL_DIR}
+)
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/p2p/base/relayserver_main.cc b/kopete/protocols/jabber/jingle/libjingle/talk/p2p/base/relayserver_main.cc
index 5f624f37..4dfae42c 100644
--- a/kopete/protocols/jabber/jingle/libjingle/talk/p2p/base/relayserver_main.cc
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/p2p/base/relayserver_main.cc
@@ -30,6 +30,7 @@
#include "talk/p2p/base/relayserver.h"
#include <iostream>
#include <assert.h>
+#include <cstring>
#ifdef POSIX
extern "C" {
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/p2p/base/stun.cc b/kopete/protocols/jabber/jingle/libjingle/talk/p2p/base/stun.cc
index 6a22b238..2d6aa67c 100644
--- a/kopete/protocols/jabber/jingle/libjingle/talk/p2p/base/stun.cc
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/p2p/base/stun.cc
@@ -29,6 +29,7 @@
#include "talk/p2p/base/stun.h"
#include <iostream>
#include <cassert>
+#include <cstring>
#if defined(_MSC_VER) && _MSC_VER < 1300
namespace std {
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/p2p/base/stunserver.cc b/kopete/protocols/jabber/jingle/libjingle/talk/p2p/base/stunserver.cc
index 6e4f6b66..c6d9f9f8 100644
--- a/kopete/protocols/jabber/jingle/libjingle/talk/p2p/base/stunserver.cc
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/p2p/base/stunserver.cc
@@ -28,6 +28,7 @@
#include "talk/base/bytebuffer.h"
#include "talk/p2p/base/stunserver.h"
#include <iostream>
+#include <cstring>
#ifdef POSIX
extern "C" {
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/p2p/base/stunserver_main.cc b/kopete/protocols/jabber/jingle/libjingle/talk/p2p/base/stunserver_main.cc
index bd8a96e5..bac3e35f 100644
--- a/kopete/protocols/jabber/jingle/libjingle/talk/p2p/base/stunserver_main.cc
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/p2p/base/stunserver_main.cc
@@ -29,6 +29,7 @@
#include "talk/base/thread.h"
#include "talk/p2p/base/stunserver.h"
#include <iostream>
+#include <cstring>
#ifdef POSIX
extern "C" {
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/p2p/client/CMakeLists.txt b/kopete/protocols/jabber/jingle/libjingle/talk/p2p/client/CMakeLists.txt
new file mode 100644
index 00000000..7ede9820
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/p2p/client/CMakeLists.txt
@@ -0,0 +1,30 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+add_definitions(
+ -DLINUX
+ -DPOSIX
+ -DINTERNAL_BUILD
+)
+
+include_directories(
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../..
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+
+##### cricketp2pclient (static) #################
+
+tde_add_library( cricketp2pclient STATIC_PIC
+ SOURCES
+ sessionclient.cc basicportallocator.cc socketmonitor.cc
+)
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/session/CMakeLists.txt b/kopete/protocols/jabber/jingle/libjingle/talk/session/CMakeLists.txt
new file mode 100644
index 00000000..0b78949f
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/session/CMakeLists.txt
@@ -0,0 +1,12 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+add_subdirectory( phone )
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/session/phone/CMakeLists.txt b/kopete/protocols/jabber/jingle/libjingle/talk/session/phone/CMakeLists.txt
new file mode 100644
index 00000000..3f22e535
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/session/phone/CMakeLists.txt
@@ -0,0 +1,34 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+add_definitions(
+ -DPOSIX
+)
+
+include_directories(
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../..
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../third_party/ortp
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../third_party/mediastreamer
+ ${CMAKE_BINARY_DIR}
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+ ${GLIB2_INCLUDE_DIRS}
+ ${SPEEX_INCLUDE_DIRS}
+)
+
+
+##### cricketsessionphone (static) ##############
+
+tde_add_library( cricketsessionphone STATIC_PIC
+ SOURCES
+ audiomonitor.cc channelmanager.cc voicechannel.cc call.cc
+ phonesessionclient.cc linphonemediaengine.cc
+)
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/session/phone/linphonemediaengine.cc b/kopete/protocols/jabber/jingle/libjingle/talk/session/phone/linphonemediaengine.cc
index e363392c..f3244c54 100644
--- a/kopete/protocols/jabber/jingle/libjingle/talk/session/phone/linphonemediaengine.cc
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/session/phone/linphonemediaengine.cc
@@ -27,7 +27,7 @@ extern "C" {
#include "talk/third_party/mediastreamer/msspeexdec.h"
#endif
}
-#include <ortp/ortp.h>
+#include <ortp.h>
#include <netdb.h>
#include <unistd.h>
#include <fcntl.h>
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/session/phone/phonesessionclient.cc b/kopete/protocols/jabber/jingle/libjingle/talk/session/phone/phonesessionclient.cc
index d8a31df2..7f2ff11f 100644
--- a/kopete/protocols/jabber/jingle/libjingle/talk/session/phone/phonesessionclient.cc
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/session/phone/phonesessionclient.cc
@@ -25,6 +25,8 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <stdio.h>
+
#include "talk/base/logging.h"
#include "talk/session/receiver.h"
#include "talk/session/phone/phonesessionclient.h"
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/CMakeLists.txt b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/CMakeLists.txt
new file mode 100644
index 00000000..da1647c0
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/CMakeLists.txt
@@ -0,0 +1,13 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+add_subdirectory( mediastreamer )
+add_subdirectory( ortp )
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/mediastreamer/CMakeLists.txt b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/mediastreamer/CMakeLists.txt
new file mode 100644
index 00000000..8c5a923b
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/mediastreamer/CMakeLists.txt
@@ -0,0 +1,36 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+add_definitions(
+ -DG_LOG_DOMAIN="MediaStreamer"
+)
+
+include_directories(
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/../ortp
+ ${CMAKE_BINARY_DIR}
+ ${GLIB2_INCLUDE_DIRS}
+ ${SPEEX_INCLUDE_DIRS}
+)
+
+
+##### mediastreamer (static) ####################
+
+tde_add_library( mediastreamer STATIC_PIC
+ SOURCES
+ msfilter.c mscodec.c mssoundread.c mssoundwrite.c msbuffer.c
+ msqueue.c msfifo.c ms.c mssync.c msnosync.c msread.c mswrite.c
+ mscopy.c msosswrite.c msossread.c msringplayer.c msrtprecv.c
+ msrtpsend.c msAlawenc.c msAlawdec.c msMUlawenc.c msMUlawdec.c
+ mstimer.c msqdispatcher.c msfdispatcher.c sndcard.c osscard.c
+ hpuxsndcard.c alsacard.c jackcard.c audiostream.c msspeexenc.c
+ msspeexdec.c msilbcdec.c msilbcenc.c
+)
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/mediastreamer/msrtprecv.h b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/mediastreamer/msrtprecv.h
index 5c8b616c..0f36c379 100644
--- a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/mediastreamer/msrtprecv.h
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/mediastreamer/msrtprecv.h
@@ -28,7 +28,7 @@
/* because of a conflict between config.h from oRTP and config.h from linphone:*/
#undef PACKAGE
#undef VERSION
-#include <ortp/ortp.h>
+#include <ortp.h>
/*this is the class that implements a copy filter*/
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/mediastreamer/msrtpsend.c b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/mediastreamer/msrtpsend.c
index b13dfe28..645a19cd 100644
--- a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/mediastreamer/msrtpsend.c
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/mediastreamer/msrtpsend.c
@@ -19,7 +19,7 @@
*/
#include "msrtpsend.h"
-#include <ortp/telephonyevents.h>
+#include <telephonyevents.h>
#include "mssync.h"
#include "mscodec.h"
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/mediastreamer/msrtpsend.h b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/mediastreamer/msrtpsend.h
index 746e436d..96889964 100644
--- a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/mediastreamer/msrtpsend.h
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/mediastreamer/msrtpsend.h
@@ -27,7 +27,7 @@
#undef PACKAGE
#undef VERSION
-#include <ortp/ortp.h>
+#include <ortp.h>
/*this is the class that implements a sending through rtp filter*/
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/CMakeLists.txt b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/CMakeLists.txt
new file mode 100644
index 00000000..92a73a36
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/CMakeLists.txt
@@ -0,0 +1,32 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+add_definitions(
+ -D_ORTP_SOURCE
+ -DG_LOG_DOMAIN="oRTP"
+)
+
+include_directories(
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_BINARY_DIR}
+ ${GLIB2_INCLUDE_DIRS}
+)
+
+
+##### ortp (static) #############################
+
+tde_add_library( ortp STATIC_PIC
+ SOURCES
+ port_fct.c rtpmod.c rtpparse.c rtpsession.c jitterctl.c
+ rtpsignaltable.c rtptimer.c posixtimer.c ortp.c scheduler.c
+ avprofile.c sessionset.c telephonyevents.c payloadtype.c rtcp.c
+ utils.c rtcpparse.c str_utils.c
+)
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/avprofile.c b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/avprofile.c
new file mode 100644
index 00000000..8917e21b
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/avprofile.c
@@ -0,0 +1,281 @@
+/*
+ The oRTP library is an RTP (Realtime Transport Protocol - rfc1889) stack.
+ Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#include <payloadtype.h>
+
+char offset127=127;
+char offset0xD5=0xD5;
+char offset0=0;
+
+/* IMPORTANT */
+/* some compiler don't support the "field:" syntax. Those macros are there to trap the problem
+This means that if you want to keep portability, payload types must be defined with their fields
+in the right order. */
+
+#if !defined(__hpux) && !defined(WIN32)
+
+#define TYPE(val) type: (val)
+#define CLOCK_RATE(val) clock_rate: (val)
+#define BITS_PER_SAMPLE(val) bits_per_sample: (val)
+#define ZERO_PATTERN(val) zero_pattern: (val)
+#define PATTERN_LENGTH(val) pattern_length: (val)
+#define NORMAL_BITRATE(val) normal_bitrate: (val)
+#define MIME_TYPE(val) mime_type: (val)
+#define FMTP(val) FMTP : (val)
+
+#else
+
+#define TYPE(val) (val)
+#define CLOCK_RATE(val) (val)
+#define BITS_PER_SAMPLE(val) (val)
+#define ZERO_PATTERN(val) (val)
+#define PATTERN_LENGTH(val) (val)
+#define NORMAL_BITRATE(val) (val)
+#define MIME_TYPE(val) (val)
+#define FMTP(val) (val)
+
+#endif
+
+PayloadType pcmu8000={
+ TYPE( PAYLOAD_AUDIO_CONTINUOUS),
+ CLOCK_RATE( 8000),
+ BITS_PER_SAMPLE(8),
+ ZERO_PATTERN( &offset127),
+ PATTERN_LENGTH( 1),
+ NORMAL_BITRATE( 64000),
+ MIME_TYPE ("PCMU")
+};
+
+PayloadType pcma8000={
+ TYPE( PAYLOAD_AUDIO_CONTINUOUS),
+ CLOCK_RATE(8000),
+ BITS_PER_SAMPLE(8),
+ ZERO_PATTERN( &offset0xD5),
+ PATTERN_LENGTH( 1),
+ NORMAL_BITRATE( 64000),
+ MIME_TYPE ("PCMA")
+};
+
+PayloadType pcm8000={
+ TYPE( PAYLOAD_AUDIO_CONTINUOUS),
+ CLOCK_RATE(8000),
+ BITS_PER_SAMPLE(16),
+ ZERO_PATTERN( &offset0),
+ PATTERN_LENGTH(1),
+ NORMAL_BITRATE( 128000),
+ MIME_TYPE ("PCM")
+};
+
+PayloadType lpc1016={
+ TYPE( PAYLOAD_AUDIO_PACKETIZED),
+ CLOCK_RATE(8000),
+ BITS_PER_SAMPLE( 0),
+ ZERO_PATTERN( NULL),
+ PATTERN_LENGTH( 0),
+ NORMAL_BITRATE( 2400),
+ MIME_TYPE ("1016")
+};
+
+
+PayloadType gsm=
+{
+ TYPE( PAYLOAD_AUDIO_PACKETIZED),
+ CLOCK_RATE(8000),
+ BITS_PER_SAMPLE( 0),
+ ZERO_PATTERN(NULL),
+ PATTERN_LENGTH( 0),
+ NORMAL_BITRATE( 13500),
+ MIME_TYPE ("GSM")
+};
+
+PayloadType payload_type_g7231=
+{
+ TYPE( PAYLOAD_AUDIO_PACKETIZED),
+ CLOCK_RATE(8000),
+ BITS_PER_SAMPLE( 0),
+ ZERO_PATTERN(NULL),
+ PATTERN_LENGTH( 0),
+ NORMAL_BITRATE( 6300),
+ MIME_TYPE ("G723")
+};
+
+PayloadType payload_type_g729={
+ TYPE( PAYLOAD_AUDIO_PACKETIZED),
+ CLOCK_RATE(8000),
+ BITS_PER_SAMPLE( 0),
+ ZERO_PATTERN(NULL),
+ PATTERN_LENGTH( 0),
+ NORMAL_BITRATE( 8000),
+ MIME_TYPE ("G729")
+};
+
+PayloadType mpv=
+{
+ TYPE( PAYLOAD_VIDEO),
+ CLOCK_RATE(90000),
+ BITS_PER_SAMPLE(0),
+ ZERO_PATTERN(NULL),
+ PATTERN_LENGTH(0),
+ NORMAL_BITRATE( 256000),
+ MIME_TYPE ("MPV")
+};
+
+
+PayloadType h261={
+ TYPE( PAYLOAD_VIDEO),
+ CLOCK_RATE(90000),
+ BITS_PER_SAMPLE(0),
+ ZERO_PATTERN(NULL),
+ PATTERN_LENGTH(0),
+ NORMAL_BITRATE(0),
+ MIME_TYPE ("H261")
+};
+
+PayloadType h263={
+ TYPE( PAYLOAD_VIDEO),
+ CLOCK_RATE(90000),
+ BITS_PER_SAMPLE(0),
+ ZERO_PATTERN(NULL),
+ PATTERN_LENGTH(0),
+ NORMAL_BITRATE(256000),
+ MIME_TYPE ("H263")
+};
+
+PayloadType truespeech=
+{
+ TYPE( PAYLOAD_AUDIO_PACKETIZED),
+ CLOCK_RATE(8000),
+ BITS_PER_SAMPLE( 0),
+ ZERO_PATTERN(NULL),
+ PATTERN_LENGTH( 0),
+ NORMAL_BITRATE(8536),
+ MIME_TYPE ("TSP0")
+};
+
+
+RtpProfile av_profile;
+
+
+void av_profile_init(RtpProfile *profile)
+{
+ rtp_profile_clear_all(profile);
+ rtp_profile_set_name(profile,"AV profile");
+ rtp_profile_set_payload(profile,0,&pcmu8000);
+ rtp_profile_set_payload(profile,1,&lpc1016);
+ rtp_profile_set_payload(profile,3,&gsm);
+ rtp_profile_set_payload(profile,4,&payload_type_g7231);
+ rtp_profile_set_payload(profile,8,&pcma8000);
+ rtp_profile_set_payload(profile,18,&payload_type_g729);
+ rtp_profile_set_payload(profile,31,&h261);
+ rtp_profile_set_payload(profile,32,&mpv);
+ rtp_profile_set_payload(profile,34,&h263);
+}
+
+/* these are extra payload types that can be used dynamically */
+PayloadType lpc1015={
+ TYPE( PAYLOAD_AUDIO_PACKETIZED),
+ CLOCK_RATE(8000),
+ BITS_PER_SAMPLE(0),
+ ZERO_PATTERN(NULL),
+ PATTERN_LENGTH(0),
+ NORMAL_BITRATE(2400),
+ MIME_TYPE ("1015")
+};
+
+PayloadType speex_nb={
+ TYPE( PAYLOAD_AUDIO_PACKETIZED),
+ CLOCK_RATE(8000),
+ BITS_PER_SAMPLE(0),
+ ZERO_PATTERN(NULL),
+ PATTERN_LENGTH(0),
+ NORMAL_BITRATE(8000), /*not true: 8000 is the minimum*/
+ MIME_TYPE ("speex")
+};
+
+PayloadType speex_wb={
+ TYPE( PAYLOAD_AUDIO_PACKETIZED),
+ CLOCK_RATE(16000),
+ BITS_PER_SAMPLE(0),
+ ZERO_PATTERN(NULL),
+ PATTERN_LENGTH(0),
+ NORMAL_BITRATE(28000),
+ MIME_TYPE ("speex")
+};
+
+PayloadType payload_type_ilbc={
+ TYPE( PAYLOAD_AUDIO_PACKETIZED),
+ CLOCK_RATE(8000),
+ BITS_PER_SAMPLE(0),
+ ZERO_PATTERN(NULL),
+ PATTERN_LENGTH(0),
+ NORMAL_BITRATE(13300), /* the minimum, with 30ms frames */
+ MIME_TYPE ("iLBC"),
+};
+
+PayloadType amr={
+ TYPE(PAYLOAD_AUDIO_PACKETIZED),
+ CLOCK_RATE(8000),
+ BITS_PER_SAMPLE(0),
+ ZERO_PATTERN(NULL),
+ PATTERN_LENGTH(0),
+ NORMAL_BITRATE(0),
+ MIME_TYPE ("AMR")
+};
+
+PayloadType amrwb={
+ TYPE(PAYLOAD_AUDIO_PACKETIZED),
+ CLOCK_RATE(16000),
+ BITS_PER_SAMPLE(0),
+ ZERO_PATTERN(NULL),
+ PATTERN_LENGTH(0),
+ NORMAL_BITRATE(0),
+ MIME_TYPE ("AMR-WB")
+};
+
+PayloadType mp4v={
+ TYPE( PAYLOAD_VIDEO),
+ CLOCK_RATE(90000),
+ BITS_PER_SAMPLE(0),
+ ZERO_PATTERN(NULL),
+ PATTERN_LENGTH(0),
+ NORMAL_BITRATE(0),
+ MIME_TYPE ("MP4V-ES")
+};
+
+
+PayloadType h263_1998={
+ TYPE( PAYLOAD_VIDEO),
+ CLOCK_RATE(90000),
+ BITS_PER_SAMPLE(0),
+ ZERO_PATTERN(NULL),
+ PATTERN_LENGTH(0),
+ NORMAL_BITRATE(0),
+ MIME_TYPE ("H263-1998")
+};
+
+PayloadType h263_2000={
+ TYPE( PAYLOAD_VIDEO),
+ CLOCK_RATE(90000),
+ BITS_PER_SAMPLE(0),
+ ZERO_PATTERN(NULL),
+ PATTERN_LENGTH(0),
+ NORMAL_BITRATE(0),
+ MIME_TYPE ("H263-2000")
+};
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/export.c b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/export.c
new file mode 100644
index 00000000..0f061c36
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/export.c
@@ -0,0 +1,25 @@
+/*
+ * file : export.c
+ *
+ * this file is used when building the oRTP stack as a dynamic loadable library
+ * on win32 OS. Indeed, structures cannot been exported 'as is' using the .def
+ * file. Since we want to use the av_profile and telephone_event instances as defined
+ * in the original source code, We have to implement those 2 functions to retrieve
+ * pointers on them.
+ *
+ */
+
+
+#include "export.h"
+
+
+RtpProfile * get_av_profile( void )
+{
+ return &av_profile;
+}
+
+PayloadType * get_telephone_event( void )
+{
+ return &telephone_event;
+}
+
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/export.h b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/export.h
new file mode 100644
index 00000000..0f5a3992
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/export.h
@@ -0,0 +1,38 @@
+/*
+ * file : export.h
+ *
+ * this file is used when building the oRTP stack as a dynamic loadable library
+ * on win32 OS. Indeed, structures cannot been exported 'as is' using the .def
+ * file. Since we want to use the av_profile and telephone_event instances as defined
+ * in the original source code, We have to implement those 2 functions to retrieve
+ * pointers on them.
+ *
+ */
+
+
+
+#ifndef EXPORT_H
+#define EXPORT_H
+
+
+#if defined __cplusplus
+extern "C"
+{
+#endif
+
+
+#include "payloadtype.h"
+#include "telephonyevents.h"
+
+
+ RtpProfile * get_av_profile( void );
+ PayloadType * get_telephone_event( void );
+
+
+
+#if defined __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/jitterctl.c b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/jitterctl.c
new file mode 100644
index 00000000..5f236f71
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/jitterctl.c
@@ -0,0 +1,141 @@
+/*
+ The oRTP library is an RTP (Realtime Transport Protocol - rfc1889) stack.
+ Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/***************************************************************************
+ * jitterctl.c
+ *
+ * Mon Nov 8 11:53:21 2004
+ * Copyright 2004 Simon MORLAT
+ * Email simon.morlat@linphone.org
+ ****************************************************************************/
+
+#include <rtpsession.h>
+#include <payloadtype.h>
+#include <math.h>
+#include <stdlib.h>
+
+#define JC_BETA 0.03 /*allows a clock slide around 3% */
+#define JC_GAMMA (JC_BETA)
+
+#include "jitterctl.h"
+
+void jitter_control_init(JitterControl *ctl, int base_jiitt_time, PayloadType *payload){
+ ctl->count=0;
+ ctl->slide=0;
+ ctl->jitter=0;
+ ctl->inter_jitter=0;
+ ctl->slide=0;
+ if (base_jiitt_time!=-1) ctl->jitt_comp = base_jiitt_time;
+ /* convert in timestamp unit: */
+ if (payload!=NULL){
+ jitter_control_set_payload(ctl,payload);
+ }
+ ctl->adapt_jitt_comp_ts=ctl->jitt_comp_ts;
+ ctl->corrective_slide=0;
+}
+
+void jitter_control_enable_adaptive(JitterControl *ctl, gboolean val){
+ ctl->adaptive=val;
+}
+
+void jitter_control_set_payload(JitterControl *ctl, PayloadType *pt){
+ ctl->jitt_comp_ts =
+ (gint) (((double) ctl->jitt_comp / 1000.0) * (pt->clock_rate));
+ ctl->corrective_step=(160 * 8000 )/pt->clock_rate; /* This formula got to me after some beers */
+ ctl->adapt_jitt_comp_ts=ctl->jitt_comp_ts;
+}
+
+
+void jitter_control_dump_stats(JitterControl *ctl){
+ g_log("oRTP-stats",G_LOG_LEVEL_MESSAGE,"JitterControl:\n\tslide=%g,jitter=%g,count=%i",
+ ctl->slide,ctl->jitter, ctl->count);
+}
+
+
+/*
+ The algorithm computes two values:
+ slide: an average of difference between the expected and the socket-received timestamp
+ jitter: an average of the absolute value of the difference between socket-received timestamp and slide.
+ slide is used to make clock-slide detection and correction.
+ jitter is added to the initial jitt_comp_time value. It compensates bursty packets arrival (packets
+ not arriving at regular interval ).
+*/
+void jitter_control_new_packet(JitterControl *ctl, guint32 packet_ts, guint32 cur_str_ts, gint32 * slide, gint32 *safe_delay){
+ int diff=packet_ts - cur_str_ts;
+ float gap;
+ int d;
+ //printf("diff=%g\n",diff);
+
+ ctl->count++;
+ ctl->slide= (ctl->slide*(1-JC_BETA)) + ((float)diff*JC_BETA);
+ gap=fabs((float)diff - ctl->slide);
+ ctl->jitter=(ctl->jitter*(1-JC_GAMMA)) + (gap*JC_GAMMA);
+ d=diff-ctl->olddiff;
+ ctl->inter_jitter=ctl->inter_jitter+ (( (float)abs(d) - ctl->inter_jitter)*(1/16.0));
+ ctl->olddiff=diff;
+ if (ctl->adaptive){
+ int tmp;
+ if (ctl->count%50==0) {
+ /*jitter_control_dump_stats(ctl);*/
+ }
+ tmp=(int)(ctl->slide)-ctl->corrective_slide;
+ if (tmp>ctl->corrective_step) ctl->corrective_slide+=ctl->corrective_step;
+ else if (tmp<-ctl->corrective_step) ctl->corrective_slide-=ctl->corrective_step;
+ /* the following is nearly equivalent, but maybe it consumes more CPU: ?*/
+ /*ctl->corrective_slide=(((gint)ctl->slide)/ctl->corrective_step)*ctl->corrective_step;*/
+
+ ctl->adapt_jitt_comp_ts=MAX(ctl->jitt_comp_ts,ctl->jitter);
+
+ *slide=(gint32)ctl->slide;
+ *safe_delay=(gint32)ctl->adapt_jitt_comp_ts;
+ }else {
+ *slide=0;
+ *safe_delay=(gint32)ctl->jitt_comp_ts;
+ }
+ return ;
+}
+
+
+/**
+ *rtp_session_set_jitter_compensation:
+ *@session: a RtpSession
+ *@milisec: the time interval in milisec to be jitter compensed.
+ *
+ * Sets the time interval for which packet are buffered instead of being delivered to the
+ * application.
+ **/
+void
+rtp_session_set_jitter_compensation (RtpSession * session, gint milisec)
+{
+ PayloadType *payload = rtp_profile_get_payload (session->profile,
+ session->
+ payload_type);
+ if (payload==NULL){
+ g_warning("rtp_session_set_jitter_compensation: cannot set because the payload type is unknown");
+ return;
+ }
+ jitter_control_init(&session->rtp.jittctl,milisec,payload);
+}
+
+void rtp_session_enable_adaptive_jitter_compensation(RtpSession *session, gboolean val){
+ jitter_control_enable_adaptive(&session->rtp.jittctl,val);
+}
+
+gboolean rtp_session_adaptive_jitter_compensation_enabled(RtpSession *session){
+ return session->rtp.jittctl.adaptive;
+}
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/jitterctl.h b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/jitterctl.h
new file mode 100644
index 00000000..8e6986a9
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/jitterctl.h
@@ -0,0 +1,38 @@
+/*
+ The oRTP library is an RTP (Realtime Transport Protocol - rfc1889) stack.
+ Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/***************************************************************************
+ * jitterctl.c
+ *
+ * Mon Nov 8 11:53:21 2004
+ * Copyright 2004 Simon MORLAT
+ * Email simon.morlat@linphone.org
+ ****************************************************************************/
+
+#ifndef JITTERCTL_H
+#define JITTERCTL_H
+
+
+void jitter_control_init(JitterControl *ctl, int base_jiitt_time, PayloadType *pt);
+void jitter_control_enable_adaptive(JitterControl *ctl, gboolean val);
+void jitter_control_new_packet(JitterControl *ctl, guint32 packet_ts, guint32 cur_str_ts,
+ gint32 * slide, gint32 *safe_delay);
+#define jitter_control_adaptive_enabled(ctl) ((ctl)->adaptive)
+void jitter_control_set_payload(JitterControl *ctl, PayloadType *pt);
+
+#endif
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/ortp-config.h b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/ortp-config.h
new file mode 100644
index 00000000..049a76d8
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/ortp-config.h
@@ -0,0 +1,9 @@
+#include <config.h>
+
+#define ORTP_MAJOR_VERSION 0
+#define ORTP_MINOR_VERSION 7
+#define ORTP_MICRO_VERSION 1
+#define ORTP_EXTRA_VERSION
+#define ORTP_VERSION "0.7.1"
+
+#define POSIXTIMER_INTERVAL 10000
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/ortp.c b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/ortp.c
new file mode 100644
index 00000000..80e07682
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/ortp.c
@@ -0,0 +1,258 @@
+/*
+ The oRTP library is an RTP (Realtime Transport Protocol - rfc1889) stack.
+ Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <ortp.h>
+#include "scheduler.h"
+#include <stdlib.h>
+
+rtp_stats_t ortp_global_stats;
+
+#ifdef ENABLE_MEMCHECK
+gint ortp_allocations=0;
+#endif
+
+
+RtpScheduler *__ortp_scheduler;
+
+
+void dummy_log(const gchar *log_domain,
+ GLogLevelFlags log_level,
+ const gchar *message,
+ gpointer user_data)
+{
+ return;
+}
+
+extern void av_profile_init(RtpProfile *profile);
+
+static void init_random_number_generator(){
+ struct timeval t;
+ gettimeofday(&t,NULL);
+ srandom(t.tv_usec+t.tv_sec);
+}
+
+/**
+ *ortp_init:
+ *
+ * Initialize the oRTP library. You should call this function first before using
+ * oRTP API.
+**/
+
+void ortp_init()
+{
+ static gboolean initialized=FALSE;
+ if (initialized) return;
+ initialized=TRUE;
+
+#ifdef _WIN32
+ WORD wVersionRequested;
+ WSADATA wsaData;
+
+ wVersionRequested = MAKEWORD( 1, 0 );
+
+ if (WSAStartup(wVersionRequested,&wsaData)!=0)
+ {
+ g_error("Fail to initialise socket api");
+ }
+#endif
+
+#ifdef HAVE_GLIB
+ if (!g_thread_supported()) g_thread_init (NULL);
+#endif
+ av_profile_init(&av_profile);
+ ortp_global_stats_reset();
+ init_random_number_generator();
+ g_message("oRTP-" ORTP_VERSION "initialized.");
+}
+
+
+/**
+ *ortp_scheduler_init:
+ *
+ * Initialize the oRTP scheduler. You only have to do that if you intend to use the
+ * scheduled mode of the #RtpSession in your application.
+ *
+**/
+void ortp_scheduler_init()
+{
+ static gboolean initialized=FALSE;
+ if (initialized) return;
+ initialized=TRUE;
+#ifdef __hpux
+ /* on hpux, we must block sigalrm on the main process, because signal delivery
+ is ?random?, well, sometimes the SIGALRM goes to both the main thread and the
+ scheduler thread */
+ sigset_t set;
+ sigemptyset(&set);
+ sigaddset(&set,SIGALRM);
+ sigprocmask(SIG_BLOCK,&set,NULL);
+#endif /* __hpux */
+ if (!g_thread_supported()) g_thread_init(NULL);
+ __ortp_scheduler=rtp_scheduler_new();
+ rtp_scheduler_start(__ortp_scheduler);
+ //sleep(1);
+}
+
+
+/**
+ *ortp_exit:
+ *
+ * Gracefully uninitialize the library, including shutdowning the scheduler if it was started.
+ *
+**/
+void ortp_exit()
+{
+ if (__ortp_scheduler!=NULL)
+ {
+ rtp_scheduler_destroy(__ortp_scheduler);
+ __ortp_scheduler=NULL;
+ }
+}
+
+/**
+ *ortp_get_scheduler:
+ *
+ * Returns a pointer to the scheduler, NULL if it was not running.
+ * The application developer should have to call this function.
+ *
+ *Returns: a pointer to the scheduler.
+**/
+RtpScheduler * ortp_get_scheduler()
+{
+ if (__ortp_scheduler==NULL) g_error("Cannot use the scheduled mode: the scheduler is not "
+ "started. Call ortp_scheduler_init() at the begginning of the application.");
+ return __ortp_scheduler;
+}
+
+
+void ortp_log(const gchar *log_domain,GLogLevelFlags log_level,
+ const gchar *message,
+ gpointer user_data)
+{
+ gchar *lev;
+ switch(log_level){
+ case G_LOG_LEVEL_MESSAGE:
+ lev="message";
+ break;
+ case G_LOG_LEVEL_WARNING:
+ lev="warning";
+ break;
+ case G_LOG_LEVEL_ERROR:
+ lev="error";
+ default:
+ lev="(unknown log type)";
+ }
+ if (user_data==NULL){
+ user_data=stdout;
+ }
+ fprintf((FILE*)user_data,"%s-%s:%s\n",log_domain,lev,message);
+}
+
+
+/**
+ *ortp_set_debug_file:
+ *@domain: one of "oRTP" or "oRTP-stats" logging domain.
+ *@file: a FILE pointer where to output the messages from the domain.
+ *
+ * Warning: domain is ignored when not compiling with glib support.
+**/
+void ortp_set_debug_file(gchar *domain,FILE *file)
+{
+ if (file!=NULL)
+ g_log_set_handler (domain, G_LOG_LEVEL_MASK, ortp_log, (gpointer)file);
+ else g_log_set_handler (domain, G_LOG_LEVEL_MASK, dummy_log, NULL);
+}
+/**
+ *ortp_set_log_handler:
+ *@domain: one of the "oRTP" or "oRTP-stats" logging domain.
+ *@func: your logging function, compatible with the GLogFunc prototype.
+ *
+ * Warning: domain is ignored when not compiling with glib support.
+**/
+void ortp_set_log_handler(const gchar *domain, GLogFunc func, gpointer userdata){
+ g_log_set_handler(domain,G_LOG_LEVEL_MASK,func,userdata);
+}
+
+
+
+void ortp_global_stats_display()
+{
+ rtp_stats_display(&ortp_global_stats,"Global statistics");
+#ifdef ENABLE_MEMCHECK
+ printf("Unfreed allocations: %i\n",ortp_allocations);
+#endif
+}
+
+
+void rtp_stats_display(rtp_stats_t *stats, char *header)
+{
+
+ g_log("oRTP-stats",G_LOG_LEVEL_MESSAGE,
+ "\n %s :\n"
+ " number of rtp packet sent=%lld\n"
+ " number of rtp bytes sent=%lld bytes\n"
+ " number of rtp packet received=%lld\n"
+ " number of rtp bytes received=%lld bytes\n"
+ " number of incoming rtp bytes successfully delivered to the application=%lld \n"
+ " number of times the application queried a packet that didn't exist=%lld \n"
+ " number of rtp packets received too late=%lld\n"
+ " number of rtp packets skipped=%lld\n"
+ " number of bad formatted rtp packets=%lld\n"
+ " number of packet discarded because of queue overflow=%lld\n",
+ header,
+ (long long)stats->packet_sent,
+ (long long)stats->sent,
+ (long long)stats->packet_recv,
+ (long long)stats->hw_recv,
+ (long long)stats->recv,
+ (long long)stats->unavaillable,
+ (long long)stats->outoftime,
+ (long long)stats->skipped,
+ (long long)stats->bad,
+ (long long)stats->discarded);
+}
+
+void ortp_global_stats_reset(){
+ memset(&ortp_global_stats,0,sizeof(rtp_stats_t));
+}
+
+rtp_stats_t *ortp_get_global_stats(){
+ return &ortp_global_stats;
+}
+
+void rtp_stats_reset(rtp_stats_t *stats){
+ memset((void*)stats,0,sizeof(rtp_stats_t));
+}
+
+
+/**
+ *ortp_min_version_required:
+ *@major:
+ *@minor:
+ *@micro:
+ *
+ * This function give the opportunity to programs to check if the libortp they link to
+ * has the minimum version number they need.
+ *
+ * Returns: true if ortp has a version number greater or equal than the required one.
+**/
+gboolean ortp_min_version_required(int major, int minor, int micro){
+ return ((major*1000000) + (minor*1000) + micro) <=
+ ((ORTP_MAJOR_VERSION*1000000) + (ORTP_MINOR_VERSION*1000) + ORTP_MICRO_VERSION);
+}
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/ortp.h b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/ortp.h
new file mode 100644
index 00000000..a3c8b01c
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/ortp.h
@@ -0,0 +1,54 @@
+/*
+ The oRTP library is an RTP (Realtime Transport Protocol - rfc1889) stack.
+ Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef ORTP_H
+#define ORTP_H
+
+#include <rtpsession.h>
+#include <sessionset.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+gboolean ortp_min_version_required(int major, int minor, int micro);
+void ortp_init();
+void ortp_scheduler_init();
+void ortp_exit();
+
+
+void ortp_set_debug_file(gchar *domain, FILE *file);
+/* domain is ignored when not compiling with glib support */
+void ortp_set_log_handler(const gchar *domain, GLogFunc func, gpointer ud);
+
+extern rtp_stats_t ortp_global_stats;
+
+void ortp_global_stats_reset();
+rtp_stats_t *ortp_get_global_stats();
+
+void ortp_global_stats_display();
+void rtp_stats_display(rtp_stats_t *stats, char *header);
+void rtp_stats_reset(rtp_stats_t *stats);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/payloadtype.c b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/payloadtype.c
new file mode 100644
index 00000000..c4886208
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/payloadtype.c
@@ -0,0 +1,268 @@
+/*
+ The oRTP library is an RTP (Realtime Transport Protocol - rfc1889) stack.
+ Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <payloadtype.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef WIN32
+#define snprintf _snprintf
+#define strcasecmp stricmp
+#endif
+
+/**
+ *rtp_profile_clear_all:
+ *@profile: an RTP profile (#RtpProfile object)
+ *
+ * Initialize the profile to the empty profile (all payload type are unassigned).
+ *
+**/
+
+/**
+ *rtp_profile_set_name:
+ *@profile: a rtp profile object (#RtpProfile)
+ *@nm: a string
+ *
+ * Set a name to the rtp profile. (This is not required)
+ *
+**/
+
+/**
+ *rtp_profile_get_name:
+ *@profile: a rtp profile object (#RtpProfile)
+ *
+ *Returns: the name of the rtp profile. May be NULL.
+**/
+
+/**
+ *rtp_profile_set_payload:
+ *@profile: an RTP profile (a #RtpProfile object)
+ *@index: the payload type number
+ *@pt: the payload type description (a #PayloadType object )
+ *
+ * Assign payload type number @index to payload type desribed in @pt for the RTP profile
+ * @profile.
+ *
+**/
+
+/**
+ *rtp_profile_get_payload:
+ *@profile: an RTP profile (a #RtpProfile object)
+ *@index: the payload type number
+ *
+ * Gets the payload description of the payload type @index in the profile @profile.
+ *
+ *Returns: the payload description (a #PayloadType object)
+**/
+
+/**
+ *rtp_profile_clear_payload:
+ *@profile: an RTP profile (a #RtpProfile object)
+ *@index: the payload type number
+ *
+ * Set payload type number @index unassigned in profile @profile.
+ *
+**/
+
+char *payload_type_get_rtpmap(PayloadType *pt)
+{
+ int len=strlen(pt->mime_type)+15;
+ char *rtpmap=g_malloc(len);
+ snprintf(rtpmap,len,"%s/%i/1",pt->mime_type,pt->clock_rate);
+ return rtpmap;
+}
+
+PayloadType *payload_type_new()
+{
+ PayloadType *newpayload=g_new0(PayloadType,1);
+ newpayload->flags|=PAYLOAD_TYPE_ALLOCATED;
+ return newpayload;
+}
+
+
+PayloadType *payload_type_clone(PayloadType *payload)
+{
+ PayloadType *newpayload=g_new0(PayloadType,1);
+ memcpy(newpayload,payload,sizeof(PayloadType));
+ newpayload->mime_type=g_strdup(payload->mime_type);
+ if (payload->fmtp!=NULL) newpayload->fmtp=g_strdup(payload->fmtp);
+ newpayload->flags|=PAYLOAD_TYPE_ALLOCATED;
+ return newpayload;
+}
+
+void payload_type_destroy(PayloadType *pt)
+{
+ g_free(pt->mime_type);
+ g_free(pt->fmtp);
+ g_free(pt);
+}
+
+gint rtp_profile_get_payload_number_from_mime(RtpProfile *profile,const char *mime)
+{
+ PayloadType *pt;
+ gint i;
+ for (i=0;i<RTP_PROFILE_MAX_PAYLOADS;i++)
+ {
+ pt=rtp_profile_get_payload(profile,i);
+ if (pt!=NULL)
+ {
+ if (strcasecmp(pt->mime_type,mime)==0){
+ return i;
+ }
+ }
+ }
+ return -1;
+}
+
+gint rtp_profile_find_payload_number(RtpProfile*profile,const gchar *mime,int rate)
+{
+ int i;
+ PayloadType *pt;
+ for (i=0;i<RTP_PROFILE_MAX_PAYLOADS;i++)
+ {
+ pt=rtp_profile_get_payload(profile,i);
+ if (pt!=NULL)
+ {
+ if (strcasecmp(pt->mime_type,mime)==0 && pt->clock_rate==rate){
+
+ return i;
+ }
+ }
+ }
+ return -1;
+}
+
+gint rtp_profile_get_payload_number_from_rtpmap(RtpProfile *profile,const char *rtpmap)
+{
+ gint clock_rate,ret;
+ char *p,*mime,*tmp,*c;
+
+ /* parse the rtpmap */
+ tmp=g_strdup(rtpmap);
+ p=strchr(tmp,'/');
+ if (p!=NULL){
+ mime=tmp;
+ *p='\0';
+ c=p+1;
+ p=strchr(c,'/');
+ if (p!=NULL) *p='\0';
+ clock_rate=atoi(c);
+ }else return -1;
+
+ //printf("Searching for payload %s at freq %i",mime,clock_rate);
+ ret=rtp_profile_find_payload_number(profile,mime,clock_rate);
+ g_free(tmp);
+ return ret;
+}
+
+PayloadType * rtp_profile_find_payload(RtpProfile *prof,const gchar *mime,int rate)
+{
+ int i;
+ i=rtp_profile_find_payload_number(prof,mime,rate);
+ if (i>=0) return rtp_profile_get_payload(prof,i);
+ return NULL;
+}
+
+
+PayloadType * rtp_profile_get_payload_from_mime(RtpProfile *profile,const char *mime)
+{
+ int pt;
+ pt=rtp_profile_get_payload_number_from_mime(profile,mime);
+ if (pt==-1) return NULL;
+ else return rtp_profile_get_payload(profile,pt);
+}
+
+
+PayloadType * rtp_profile_get_payload_from_rtpmap(RtpProfile *profile, const char *rtpmap)
+{
+ int pt;
+ pt=rtp_profile_get_payload_number_from_rtpmap(profile,rtpmap);
+ if (pt==-1) return NULL;
+ else return rtp_profile_get_payload(profile,pt);
+}
+
+int rtp_profile_move_payload(RtpProfile *prof,int oldpos,int newpos){
+ prof->payload[newpos]=prof->payload[oldpos];
+ prof->payload[oldpos]=NULL;
+ return 0;
+}
+
+RtpProfile * rtp_profile_new(const char *name)
+{
+ RtpProfile *prof=g_new0(RtpProfile,1);
+ rtp_profile_set_name(prof,name);
+ rtp_profile_clear_all(prof);
+ return prof;
+}
+
+void rtp_profile_set_name(RtpProfile *obj, const char *name){
+ if (obj->name!=NULL) g_free(obj->name);
+ obj->name=g_strdup(name);
+}
+
+/* ! payload are not cloned*/
+RtpProfile * rtp_profile_clone(RtpProfile *prof)
+{
+ int i;
+ PayloadType *pt;
+ RtpProfile *newprof=rtp_profile_new(prof->name);
+ rtp_profile_clear_all(newprof);
+ for (i=0;i<128;i++){
+ pt=rtp_profile_get_payload(prof,i);
+ if (pt!=NULL){
+ rtp_profile_set_payload(newprof,i,pt);
+ }
+ }
+ return newprof;
+}
+
+void rtp_profile_copy(const RtpProfile *orig, RtpProfile *dest){
+ memcpy(dest,orig,sizeof(RtpProfile));
+}
+
+
+/*clone a profile and its payloads */
+RtpProfile * rtp_profile_clone_full(RtpProfile *prof)
+{
+ int i;
+ PayloadType *pt;
+ RtpProfile *newprof=rtp_profile_new(prof->name);
+ rtp_profile_clear_all(newprof);
+ for (i=0;i<RTP_PROFILE_MAX_PAYLOADS;i++){
+ pt=rtp_profile_get_payload(prof,i);
+ if (pt!=NULL){
+ rtp_profile_set_payload(newprof,i,payload_type_clone(pt));
+ }
+ }
+ return newprof;
+}
+
+void rtp_profile_destroy(RtpProfile *prof)
+{
+ int i;
+ PayloadType *payload;
+ for (i=0;i<RTP_PROFILE_MAX_PAYLOADS;i++)
+ {
+ payload=rtp_profile_get_payload(prof,i);
+ if (payload!=NULL && (payload->flags & PAYLOAD_TYPE_ALLOCATED))
+ payload_type_destroy(payload);
+ }
+ g_free(prof);
+}
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/payloadtype.h b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/payloadtype.h
new file mode 100644
index 00000000..e5efa797
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/payloadtype.h
@@ -0,0 +1,136 @@
+/*
+ The oRTP library is an RTP (Realtime Transport Protocol - rfc1889) stack.
+ Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef PAYLOADTYPE_H
+#define PAYLOADTYPE_H
+#include <rtpport.h>
+
+typedef enum{
+ PAYLOAD_TYPE_ALLOCATED = 1
+}PayloadTypeFlags;
+
+struct _PayloadType
+{
+ gint type;
+ #define PAYLOAD_AUDIO_CONTINUOUS 0
+ #define PAYLOAD_AUDIO_PACKETIZED 1
+ #define PAYLOAD_VIDEO 2
+ #define PAYLOAD_OTHER 3 /* ?? */
+ gint clock_rate;
+ char bits_per_sample; /* in case of continuous audio data */
+ char *zero_pattern;
+ gint pattern_length;
+ /* other usefull information */
+ gint normal_bitrate; /*in bit/s */
+ char *mime_type;
+ char *fmtp; /*various parameters, as a string */
+ PayloadTypeFlags flags;
+ void *user_data;
+};
+
+#ifndef PayloadType_defined
+#define PayloadType_defined
+typedef struct _PayloadType PayloadType;
+#endif
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+PayloadType *payload_type_new();
+PayloadType *payload_type_clone(PayloadType *payload);
+void payload_type_destroy(PayloadType *pt);
+#ifdef __cplusplus
+}
+#endif
+
+#define payload_type_set_flag(pt,flag) (pt)->flags|=(flag)
+#define payload_type_unset_flag(pt,flag) (pt)->flags&=(~flag)
+
+#define RTP_PROFILE_MAX_PAYLOADS 128
+
+struct _RtpProfile
+{
+ char *name;
+ PayloadType *payload[RTP_PROFILE_MAX_PAYLOADS];
+};
+
+
+typedef struct _RtpProfile RtpProfile;
+
+
+extern RtpProfile av_profile;
+
+#define payload_type_set_user_data(pt,p) (pt)->user_data=(p)
+#define payload_type_get_user_data(pt) ((pt)->user_data)
+
+
+
+#define rtp_profile_get_name(profile) (const char*)((profile)->name)
+#define rtp_profile_set_payload(profile,index,pt) (profile)->payload[(index)]=(pt)
+#define rtp_profile_clear_payload(profile,index) (profile)->payload[(index)]=NULL
+#define rtp_profile_clear_all(profile) memset((void*)(profile),0,sizeof(RtpProfile))
+#define rtp_profile_get_payload(profile,index) ((profile)->payload[(index)])
+#ifdef __cplusplus
+extern "C"{
+#endif
+void rtp_profile_set_name(RtpProfile *prof, const char *name);
+PayloadType * rtp_profile_get_payload_from_mime(RtpProfile *profile,const char *mime);
+PayloadType * rtp_profile_get_payload_from_rtpmap(RtpProfile *profile, const char *rtpmap);
+gint rtp_profile_get_payload_number_from_mime(RtpProfile *profile,const char *mime);
+gint rtp_profile_get_payload_number_from_rtpmap(RtpProfile *profile, const char *rtpmap);
+gint rtp_profile_find_payload_number(RtpProfile *prof,const gchar *mime,int rate);
+PayloadType * rtp_profile_find_payload(RtpProfile *prof,const gchar *mime,int rate);
+gint rtp_profile_move_payload(RtpProfile *prof,int oldpos,int newpos);
+
+RtpProfile * rtp_profile_new(const char *name);
+/* clone a profile, payload are not cloned */
+RtpProfile * rtp_profile_clone(RtpProfile *prof);
+/* copy a profile into another one; payload are not cloned */
+void rtp_profile_copy(const RtpProfile *orig, RtpProfile *dest);
+
+/*clone a profile and its payloads (ie payload type are newly allocated, not reusing payload types of the reference profile) */
+RtpProfile * rtp_profile_clone_full(RtpProfile *prof);
+/* frees the profile and all its PayloadTypes*/
+void rtp_profile_destroy(RtpProfile *prof);
+#ifdef __cplusplus
+}
+#endif
+
+/* some payload types */
+/* audio */
+extern PayloadType pcmu8000;
+extern PayloadType pcma8000;
+extern PayloadType pcm8000;
+extern PayloadType lpc1016;
+extern PayloadType gsm;
+extern PayloadType lpc1015;
+extern PayloadType speex_nb;
+extern PayloadType speex_wb;
+extern PayloadType payload_type_ilbc;
+extern PayloadType truespeech;
+
+/* video */
+extern PayloadType mpv;
+extern PayloadType h261;
+extern PayloadType h263;
+
+
+
+
+#endif
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/port_fct.c b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/port_fct.c
new file mode 100644
index 00000000..2ad6b4dc
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/port_fct.c
@@ -0,0 +1,183 @@
+
+/*
+ The oRTP library is an RTP (Realtime Transport Protocol - rfc1889) stack.
+ Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/* port_fct.h. define methods to help for portability between unix and win32 */
+
+#include <unistd.h>
+
+#include <rtpport.h>
+#include "port_fct.h"
+
+
+
+/*
+ * this method is an utility method that calls fnctl() on UNIX or
+ * ioctlsocket on Win32.
+ * int retrun the result of the system method
+ */
+int set_non_blocking_socket (gint sock)
+{
+
+
+#ifndef _WIN32
+ return fcntl (sock, F_SETFL, O_NONBLOCK);
+#else
+ unsigned long nonBlock = 1;
+ return ioctlsocket(sock, FIONBIO , &nonBlock);
+#endif
+}
+
+
+/*
+ * this method is an utility method that calls close() on UNIX or
+ * closesocket on Win32.
+ * int retrun the result of the system method
+ */
+#ifndef _WIN32
+ int close_socket(gint sock)
+ {
+ return close (sock);
+ }
+#else
+ int close_socket(SOCKET sock)
+ {
+ return closesocket(sock);
+ }
+#endif
+
+
+
+/*
+ * getSocketError() return a string describing the error
+ */
+#ifdef _WIN32
+char *getSocketError()
+{
+ int error = WSAGetLastError ();
+ static char buf[80];
+
+ switch (error)
+ {
+ case WSANOTINITIALISED: return "Windows sockets not initialized : call WSAStartup";
+ case WSAEADDRINUSE: return "Local Address already in use";
+ case WSAEADDRNOTAVAIL: return "The specified address is not a valid address for this machine";
+// case WSAEFAULT: return "";
+// case WSAEINPROGRESS: return "";
+ case WSAEINVAL: return "The socket is already bound to an address.";
+ case WSAENOBUFS: return "Not enough buffers available, too many connections.";
+ case WSAENOTSOCK: return "The descriptor is not a socket.";
+ case WSAECONNRESET: return "Connection reset by peer";
+/*
+
+ case : return "";
+ case : return "";
+ case : return "";
+ case : return "";
+ case : return "";
+ case : return "";
+*/
+ default :
+ sprintf (buf,"Error code : %d", error);
+ return buf;
+ break;
+ }
+
+ return buf;
+
+}
+#endif
+
+#ifndef _WIN32
+ /* Use UNIX inet_aton method */
+#else
+ int inet_aton (const char * cp, struct in_addr * addr)
+ {
+ unsigned long retval;
+
+ retval = inet_addr (cp);
+
+ if (retval == INADDR_NONE)
+ {
+ return -1;
+ }
+ else
+ {
+ addr->S_un.S_addr = retval;
+ return 1;
+ }
+ }
+#endif
+
+#ifndef HAVE_GLIB
+
+char * g_strdup_vprintf(const char *fmt, va_list ap)
+{
+ /* Guess we need no more than 100 bytes. */
+ int n, size = 100;
+ char *p;
+ if ((p = g_malloc (size)) == NULL)
+ return NULL;
+ while (1)
+ {
+ /* Try to print in the allocated space. */
+ n = vsnprintf (p, size, fmt, ap);
+ /* If that worked, return the string. */
+ if (n > -1 && n < size)
+ return p;
+ //printf("Reallocing space.\n");
+ /* Else try again with more space. */
+ if (n > -1) /* glibc 2.1 */
+ size = n + 1; /* precisely what is needed */
+ else /* glibc 2.0 */
+ size *= 2; /* twice the old size */
+ if ((p = g_realloc (p, size)) == NULL)
+ return NULL;
+ }
+}
+
+
+
+extern void ortp_log(const gchar *log_domain,GLogLevelFlags log_level,
+ const gchar *message,
+ gpointer user_data);
+
+static GLogFunc __log_func=ortp_log;
+static gpointer __log_user_data=(gpointer)NULL;
+
+void g_log(const gchar *log_domain,GLogLevelFlags log_level,const gchar *format,...){
+ va_list args;
+ va_start(args,format);
+ g_logv(log_domain,log_level,format,args);
+ va_end(args);
+}
+
+void g_logv(const gchar *log_domain,GLogLevelFlags log_level,const gchar *format,va_list args){
+ gchar *msg;
+ msg=g_strdup_vprintf(format,args);
+ __log_func(log_domain,log_level,msg,__log_user_data);
+ g_free(msg);
+}
+
+void g_log_set_handler(const gchar *log_domain,GLogLevelFlags log_levels, GLogFunc log_func, gpointer user_data){
+ __log_func=log_func;
+ __log_user_data=user_data;
+}
+
+#endif
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/port_fct.h b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/port_fct.h
new file mode 100644
index 00000000..3b3abe31
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/port_fct.h
@@ -0,0 +1,48 @@
+/*
+ The oRTP library is an RTP (Realtime Transport Protocol - rfc1889) stack.
+ Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/* fct-win32.h. define unix methods that are not defined in win32 env */
+
+#ifndef PORT_FCT_H
+#define PORT_FCT_H
+
+#ifdef _WIN32
+#include <Winsock2.h>
+#else
+#include <fcntl.h>
+#endif
+
+#include <rtpport.h>
+
+#ifndef _WIN32
+/* use unix pthread_t... */
+ extern int close_socket(gint sock);
+#else
+ #define pthread_t HANDLE
+ extern int pthread_create(pthread_t *thread,const void *attr,void *(__cdecl *start)(void *),void* arg);
+ extern int pthread_join(pthread_t thread,void **);
+
+ extern int close_socket(SOCKET sock);
+ extern int inet_aton (const char * cp, struct in_addr * addr);
+#endif
+
+extern int set_non_blocking_socket (int sock);
+extern int set_thread_priority();
+
+#endif
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/posixtimer.c b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/posixtimer.c
new file mode 100644
index 00000000..9e20ead4
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/posixtimer.c
@@ -0,0 +1,167 @@
+/*
+ The oRTP library is an RTP (Realtime Transport Protocol - rfc1889) stack.
+ Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <rtpport.h>
+#include "rtptimer.h"
+
+
+#ifndef _WIN32
+
+#ifdef __linux__
+#include <sys/select.h>
+#endif
+
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+
+static struct timeval orig,cur;
+static guint32 posix_timer_time=0; /*in milisecond */
+
+void posix_timer_init()
+{
+ posix_timer.state=RTP_TIMER_RUNNING;
+ gettimeofday(&orig,NULL);
+ posix_timer_time=0;
+}
+
+
+
+
+void posix_timer_do()
+{
+ gint32 diff,time;
+ struct timeval tv;
+
+ gettimeofday(&cur,NULL);
+ time=((cur.tv_usec-orig.tv_usec)/1000 ) + ((cur.tv_sec-orig.tv_sec)*1000 );
+ if ( (diff=time-posix_timer_time)>50){
+ g_warning("Must catchup %i miliseconds.",diff);
+ }
+ while((diff = posix_timer_time-time) > 0)
+ {
+ tv.tv_sec = diff/1000;
+ tv.tv_usec = (diff%1000)*1000;
+ select(0,NULL,NULL,NULL,&tv);
+ gettimeofday(&cur,NULL);
+ time=((cur.tv_usec-orig.tv_usec)/1000 ) + ((cur.tv_sec-orig.tv_sec)*1000 );
+ }
+ posix_timer_time+=POSIXTIMER_INTERVAL/1000;
+
+}
+
+void posix_timer_uninit()
+{
+ posix_timer.state=RTP_TIMER_STOPPED;
+}
+
+RtpTimer posix_timer={ 0,
+ posix_timer_init,
+ posix_timer_do,
+ posix_timer_uninit,
+ {0,POSIXTIMER_INTERVAL}};
+
+
+#else //WIN32
+
+#include <windows.h>
+#include <mmsystem.h>
+
+
+MMRESULT timerId;
+HANDLE TimeEvent;
+int late_ticks;
+
+
+static DWORD posix_timer_time;
+static DWORD offset_time;
+
+
+#define TIME_INTERVAL 50
+#define TIME_RESOLUTION 10
+#define TIME_TIMEOUT 100
+
+
+
+void CALLBACK timerCb(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
+{
+ // Check timerId
+ if (timerId == uID)
+ {
+ SetEvent(TimeEvent);
+ posix_timer_time += TIME_INTERVAL;
+ }
+}
+
+
+void win_timer_init(void)
+{
+ timerId = timeSetEvent(TIME_INTERVAL,10,timerCb,0,TIME_PERIODIC | TIME_CALLBACK_FUNCTION);
+ TimeEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
+
+ late_ticks = 0;
+
+ offset_time = GetTickCount();
+ posix_timer_time=0;
+}
+
+
+void win_timer_do(void)
+{
+ DWORD diff;
+
+ // If timer have expired while we where out of this method
+ // Try to run after lost time.
+ if (late_ticks > 0)
+ {
+ late_ticks--;
+ posix_timer_time+=TIME_INTERVAL;
+ return;
+ }
+
+
+ diff = GetTickCount() - posix_timer_time - offset_time;
+ if( diff>TIME_INTERVAL && (diff<(1<<31)))
+ {
+ late_ticks = diff/TIME_INTERVAL;
+ g_warning("we must catchup %i ticks.",late_ticks);
+ return;
+ }
+
+ WaitForSingleObject(TimeEvent,TIME_TIMEOUT);
+ return;
+}
+
+
+void win_timer_close(void)
+{
+ timeKillEvent(timerId);
+}
+
+RtpTimer toto;
+
+RtpTimer posix_timer={ 0,
+ win_timer_init,
+ win_timer_do,
+ win_timer_close,
+ {0,TIME_INTERVAL * 1000}};
+
+
+#endif // _WIN32
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtcp.c b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtcp.c
new file mode 100644
index 00000000..78599ae5
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtcp.c
@@ -0,0 +1,294 @@
+/*
+ The oRTP library is an RTP (Realtime Transport Protocol - rfc1889) stack.
+ Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/***************************************************************************
+ * rtcp.c
+ *
+ * Wed Dec 1 11:45:30 2004
+ * Copyright 2004 Simon Morlat
+ * Email simon dot morlat at linphone dot org
+ ****************************************************************************/
+
+#include <rtpsession.h>
+#include <rtcp.h>
+
+extern gint ortp_rtcp_send (RtpSession * session, mblk_t * m);
+
+
+void rtcp_common_header_init(rtcp_common_header_t *ch, RtpSession *s,int type, int rc, int bytes_len){
+ rtcp_common_header_set_version(ch,2);
+ rtcp_common_header_set_padbit(ch,0);
+ rtcp_common_header_set_packet_type(ch,type);
+ rtcp_common_header_set_rc(ch,rc); /* as we don't yet support multi source receiving */
+ rtcp_common_header_set_length(ch,(bytes_len/4)-1);
+}
+
+mblk_t *sdes_chunk_new(guint32 ssrc){
+ mblk_t *m=allocb(RTCP_SDES_CHUNK_DEFAULT_SIZE,0);
+ sdes_chunk_t *sc=(sdes_chunk_t*)m->b_rptr;
+ sc->csrc=htonl(ssrc);
+ m->b_wptr+=sizeof(sc->csrc);
+ return m;
+}
+
+
+mblk_t * sdes_chunk_append_item(mblk_t *m, rtcp_sdes_type_t sdes_type, const gchar *content)
+{
+ if ( content )
+ {
+ sdes_item_t si;
+ si.item_type=sdes_type;
+ si.len=MIN(strlen(content),RTCP_SDES_MAX_STRING_SIZE);
+ m=appendb(m,(char*)&si,RTCP_SDES_ITEM_HEADER_SIZE,FALSE);
+ m=appendb(m,content,si.len,FALSE);
+ }
+ return m;
+}
+
+void sdes_chunk_set_ssrc(mblk_t *m, guint32 ssrc){
+ sdes_chunk_t *sc=(sdes_chunk_t*)m->b_rptr;
+ sc->csrc=htonl(ssrc);
+}
+
+#define sdes_chunk_get_ssrc(m) ntohl(((sdes_chunk_t*)((m)->b_rptr))->csrc)
+
+mblk_t * sdes_chunk_pad(mblk_t *m){
+ return appendb(m,NULL,0,TRUE);
+}
+
+void rtp_session_set_source_description(RtpSession *session,
+ const gchar *cname, const gchar *name, const gchar *email, const gchar *phone,
+ const gchar *loc, const gchar *tool, const gchar *note){
+ mblk_t *chunk = sdes_chunk_new(session->send_ssrc);
+ mblk_t *m=chunk;
+ const gchar *_cname=cname;
+ if (_cname==NULL)
+ {
+ _cname="Unknown";
+ }
+ chunk=sdes_chunk_append_item(chunk, RTCP_SDES_CNAME, _cname);
+ chunk=sdes_chunk_append_item(chunk, RTCP_SDES_NAME, name);
+ chunk=sdes_chunk_append_item(chunk, RTCP_SDES_EMAIL, email);
+ chunk=sdes_chunk_append_item(chunk, RTCP_SDES_PHONE, phone);
+ chunk=sdes_chunk_append_item(chunk, RTCP_SDES_LOC, loc);
+ chunk=sdes_chunk_append_item(chunk, RTCP_SDES_TOOL, tool);
+ chunk=sdes_chunk_append_item(chunk, RTCP_SDES_NOTE, note);
+ chunk=sdes_chunk_pad(chunk);
+ rtp_session_lock(session);
+ if (session->sd!=NULL) freemsg(session->sd);
+ session->sd=m;
+ rtp_session_unlock(session);
+}
+
+void
+rtp_session_add_contributing_source(RtpSession *session, guint32 csrc,
+ const gchar *cname, const gchar *name, const gchar *email, const gchar *phone,
+ const gchar *loc, const gchar *tool, const gchar *note)
+{
+ mblk_t *chunk = sdes_chunk_new(csrc);
+ mblk_t *m=chunk;
+ gchar *_cname=(gchar*)cname;
+ if (_cname==NULL)
+ {
+ _cname="toto";
+ }
+ chunk=sdes_chunk_append_item(chunk, RTCP_SDES_CNAME, cname);
+ chunk=sdes_chunk_append_item(chunk, RTCP_SDES_NAME, name);
+ chunk=sdes_chunk_append_item(chunk, RTCP_SDES_EMAIL, email);
+ chunk=sdes_chunk_append_item(chunk, RTCP_SDES_PHONE, phone);
+ chunk=sdes_chunk_append_item(chunk, RTCP_SDES_LOC, loc);
+ chunk=sdes_chunk_append_item(chunk, RTCP_SDES_TOOL, tool);
+ chunk=sdes_chunk_append_item(chunk, RTCP_SDES_NOTE, note);
+ chunk=sdes_chunk_pad(chunk);
+ rtp_session_lock(session);
+ putq(&session->contributing_sources,m);
+ rtp_session_unlock(session);
+}
+
+
+
+mblk_t* rtp_session_create_rtcp_sdes_packet(RtpSession *session)
+{
+ mblk_t *mp=allocb(sizeof(rtcp_common_header_t),0);
+ rtcp_common_header_t *rtcp;
+ mblk_t *tmp,*m=mp;
+ queue_t *q;
+ int rc=0;
+ rtcp = (rtcp_common_header_t*)mp->b_wptr;
+ mp->b_wptr+=sizeof(rtcp_common_header_t);
+
+ /* concatenate all sdes chunks */
+ sdes_chunk_set_ssrc(session->sd,session->send_ssrc);
+ m=concatb(m,dupmsg(session->sd));
+ rc++;
+
+ q=&session->contributing_sources;
+ for (tmp=qbegin(q); !qend(q,tmp); tmp=qnext(q,mp)){
+ m=concatb(m,dupmsg(tmp));
+ rc++;
+ }
+ rtcp_common_header_init(rtcp,session,RTCP_SDES,rc,msgdsize(mp));
+ return mp;
+}
+
+
+mblk_t *rtcp_create_simple_bye_packet(guint32 ssrc, const gchar *reason)
+{
+ gint strsize=0;
+ gint packet_size;
+ mblk_t *mp;
+ rtcp_bye_t *rtcp;
+ packet_size = RTCP_BYE_HEADER_SIZE + 1 + strsize;
+ if (reason!=NULL)
+ strsize=MIN(strlen(reason),RTCP_BYE_REASON_MAX_STRING_SIZE);
+ mp = allocb(packet_size, 0);
+
+ rtcp = (rtcp_bye_t*)mp->b_rptr;
+
+ rtcp_common_header_init(&rtcp->ch,NULL,RTCP_BYE,1,packet_size);
+ rtcp->ssrc[0] = htonl(ssrc);
+ mp->b_wptr += packet_size;
+ /* append the reason if any*/
+ if (reason!=NULL)
+ appendb(mp,reason,strsize,FALSE);
+ return mp;
+}
+
+void rtp_session_remove_contributing_sources(RtpSession *session, guint32 ssrc)
+{
+ queue_t *q=&session->contributing_sources;
+ mblk_t *tmp;
+ for (tmp=qbegin(q); !qend(q,tmp); tmp=qnext(q,tmp)){
+ guint32 csrc=sdes_chunk_get_ssrc(tmp);
+ if (csrc==ssrc) {
+ remq(q,tmp);
+ break;
+ }
+ }
+ tmp=rtcp_create_simple_bye_packet(ssrc, NULL);
+ ortp_rtcp_send(session,tmp);
+}
+
+void sender_info_init(sender_info_t *info, RtpSession *session){
+ struct timeval tv;
+ guint32 tmp;
+ gettimeofday(&tv,NULL);
+ info->ntp_timestamp_msw=htonl(tv.tv_sec);
+ tmp=(guint32)((double)tv.tv_usec*(double)(1LL<<32)*1.0e-6);
+ info->ntp_timestamp_lsw=htonl(tmp);
+ info->rtp_timestamp=htonl(session->rtp.snd_last_ts);
+ info->senders_packet_count=htonl(session->rtp.stats.packet_sent);
+ info->senders_octet_count=htonl(session->rtp.stats.sent);
+}
+
+
+
+void report_block_init(report_block_t *b, RtpSession *session){
+ guint packet_loss=0;
+ guint8 loss_fraction=0;
+ RtpStream *stream=&session->rtp;
+ guint32 delay_snc_last_sr=0;
+
+ /* compute the statistics */
+ /*printf("hwrcv_extseq.one=%u, hwrcv_seq_at_last_SR=%u hwrcv_since_last_SR=%u\n",
+ stream->hwrcv_extseq.one,
+ stream->hwrcv_seq_at_last_SR,
+ stream->hwrcv_since_last_SR
+ );*/
+ if (stream->hwrcv_seq_at_last_SR!=0){
+ packet_loss=(stream->hwrcv_extseq.one - stream->hwrcv_seq_at_last_SR) - stream->hwrcv_since_last_SR;
+ stream->stats.cum_packet_loss+=packet_loss;
+ loss_fraction=(int)(256.0*(float)packet_loss/(float)stream->hwrcv_since_last_SR);
+ }
+ /* reset them */
+ stream->hwrcv_since_last_SR=0;
+ stream->hwrcv_seq_at_last_SR=stream->hwrcv_extseq.one;
+
+ if (stream->last_rcv_SR_time.tv_sec!=0){
+ struct timeval now;
+ gfloat delay;
+ gettimeofday(&now,NULL);
+ delay=((now.tv_sec-stream->last_rcv_SR_time.tv_sec)*1e6 ) + (now.tv_usec-stream->last_rcv_SR_time.tv_usec);
+ delay=delay*65536*1e-6;
+ delay_snc_last_sr=(guint32) delay;
+ }
+
+ b->ssrc=htonl(session->recv_ssrc);
+ b->fraction_lost=loss_fraction;
+ b->cum_num_packet_lost=hton24(stream->stats.cum_packet_loss);
+ b->interarrival_jitter=htonl((guint32) stream->jittctl.inter_jitter);
+ b->ext_high_seq_num_rec=htonl(stream->hwrcv_extseq.one);
+ b->lsr=htonl(stream->last_rcv_SR_ts);
+ b->delay_snc_last_sr=htonl(delay_snc_last_sr);
+}
+
+
+
+int rtcp_sr_init(RtpSession *session, char *buf, int size){
+ rtcp_sr_t *sr=(rtcp_sr_t*)buf;
+ if (size<sizeof(rtcp_sr_t)) return -1;
+ rtcp_common_header_init(&sr->ch,session,RTCP_SR,1,sizeof(rtcp_sr_t));
+ sr->ssrc=htonl(session->send_ssrc);
+ sender_info_init(&sr->si,session);
+ report_block_init(&sr->rb[0],session);
+ return sizeof(rtcp_sr_t);
+}
+
+int rtcp_rr_init(RtpSession *session, char *buf, int size){
+ rtcp_rr_t *rr=(rtcp_rr_t*)buf;
+ if (size<sizeof(rtcp_rr_t)) return -1;
+ rtcp_common_header_init(&rr->ch,session,RTCP_RR,1,sizeof(rtcp_sr_t));
+ rr->ssrc=htonl(session->send_ssrc);
+ report_block_init(&rr->rb[0],session);
+ return sizeof(rtcp_sr_t);
+}
+
+
+void __rtp_session_rtcp_process(RtpSession *session){
+ mblk_t *cm=NULL;
+ mblk_t *sdes=NULL;
+ if (session->mode==RTP_SESSION_SENDONLY || session->mode==RTP_SESSION_SENDRECV){
+ /* first make a SR packet */
+ cm=allocb(sizeof(rtcp_sr_t),0);
+ cm->b_wptr+=rtcp_sr_init(session,cm->b_wptr,sizeof(rtcp_sr_t));
+ /* make a SDES packet */
+ sdes=rtp_session_create_rtcp_sdes_packet(session);
+ /* link them */
+ cm->b_cont=sdes;
+ }else{
+ /* make a RR packet */
+ cm=allocb(sizeof(rtcp_rr_t),0);
+ cm->b_wptr+=rtcp_rr_init(session,cm->b_wptr,sizeof(rtcp_rr_t));
+ /* if we are recv-only do we need to add SDES packet ? I don't think so
+ as we are not a source */
+ }
+ /* send the compound packet */
+ ortp_rtcp_send(session,cm);
+ ortp_debug("Rtcp compound message sent.");
+}
+
+void rtp_session_rtcp_process(RtpSession *session){
+ RtpStream *st=&session->rtp;
+ if (st->rcv_last_app_ts - st->last_rtcp_report_snt_r > st->rtcp_report_snt_interval
+ || st->snd_last_ts - st->last_rtcp_report_snt_s > st->rtcp_report_snt_interval){
+ st->last_rtcp_report_snt_r=st->rcv_last_app_ts;
+ st->last_rtcp_report_snt_s=st->snd_last_ts;
+ __rtp_session_rtcp_process(session);
+ }
+}
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtcp.h b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtcp.h
new file mode 100644
index 00000000..574bcf91
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtcp.h
@@ -0,0 +1,167 @@
+/*
+ The oRTP library is an RTP (Realtime Transport Protocol - rfc1889) stack.
+ Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef RTCP_H
+#define RTCP_H
+
+#include <rtpport.h>
+
+#define RTCP_MAX_RECV_BUFSIZE 1024
+
+#define RTCP_SENDER_INFO_SIZE 20
+#define RTCP_REPORT_BLOCK_SIZE 24
+#define RTCP_COMMON_HEADER_SIZE 4
+#define RTCP_SSRC_FIELD_SIZE 4
+
+
+/* RTCP common header */
+
+typedef enum {
+ RTCP_SR = 200,
+ RTCP_RR = 201,
+ RTCP_SDES = 202,
+ RTCP_BYE = 203,
+ RTCP_APP = 204
+} rtcp_type_t;
+
+
+typedef struct rtcp_common_header
+{
+#ifdef WORDS_BIGENDIAN
+ guint16 version:2;
+ guint16 padbit:1;
+ guint16 rc:5;
+ guint16 packet_type:8;
+#else
+ guint16 rc:5;
+ guint16 padbit:1;
+ guint16 version:2;
+ guint16 packet_type:8;
+#endif
+ guint16 length:16;
+} rtcp_common_header_t;
+
+#define rtcp_common_header_set_version(ch,v) (ch)->version=v
+#define rtcp_common_header_set_padbit(ch,p) (ch)->padbit=p
+#define rtcp_common_header_set_rc(ch,rc) (ch)->rc=rc
+#define rtcp_common_header_set_packet_type(ch,pt) (ch)->packet_type=pt
+#define rtcp_common_header_set_length(ch,l) (ch)->length=htons(l)
+
+#define rtcp_common_header_get_version(ch,v) ((ch)->version)
+#define rtcp_common_header_get padbit(ch,p) ((ch)->padbit)
+#define rtcp_common_header_get_rc(ch,rc) ((ch)->rc)
+#define rtcp_common_header_get_packet_type(ch,pt) ((ch)->packet_type)
+#define rtcp_common_header_get_length(ch,l) ntohs((ch)->length)
+
+
+/* SR or RR packets */
+
+typedef struct sender_info
+{
+ guint32 ntp_timestamp_msw;
+ guint32 ntp_timestamp_lsw;
+ guint32 rtp_timestamp;
+ guint32 senders_packet_count;
+ guint32 senders_octet_count;
+} sender_info_t;
+
+typedef struct report_block
+{
+ guint32 ssrc;
+ guint32 fraction_lost:8;
+ guint32 cum_num_packet_lost:24; /*cumulative number of packet lost*/
+ guint32 ext_high_seq_num_rec; /*extended highest sequence number received */
+ guint32 interarrival_jitter;
+ guint32 lsr; /*last SR */
+ guint32 delay_snc_last_sr; /*delay since last sr*/
+} report_block_t;
+
+
+/* SDES packets */
+
+typedef enum {
+ RTCP_SDES_END = 0,
+ RTCP_SDES_CNAME = 1,
+ RTCP_SDES_NAME = 2,
+ RTCP_SDES_EMAIL = 3,
+ RTCP_SDES_PHONE = 4,
+ RTCP_SDES_LOC = 5,
+ RTCP_SDES_TOOL = 6,
+ RTCP_SDES_NOTE = 7,
+ RTCP_SDES_PRIV = 8,
+ RTCP_SDES_MAX = 9
+} rtcp_sdes_type_t;
+
+typedef struct sdes_chunk
+{
+ guint32 csrc;
+} sdes_chunk_t;
+
+typedef struct sdes_item
+{
+ guint8 item_type;
+ guint8 len;
+ gchar content[1];
+} sdes_item_t;
+
+#define RTCP_SDES_MAX_STRING_SIZE 255
+#define RTCP_SDES_ITEM_HEADER_SIZE 2
+#define RTCP_SDES_CHUNK_DEFAULT_SIZE 1024
+#define RTCP_SDES_CHUNK_HEADER_SIZE (sizeof(sdes_chunk_t))
+
+/* RTCP bye packet */
+
+typedef struct rtcp_bye_reason
+{
+ guint8 len;
+ gchar content[1];
+} rtcp_bye_reason_t;
+
+typedef struct rtcp_bye
+{
+ rtcp_common_header_t ch;
+ guint32 ssrc[1]; /* the bye may contain several ssrc/csrc */
+} rtcp_bye_t;
+#define RTCP_BYE_HEADER_SIZE sizeof(rtcp_bye_t)
+#define RTCP_BYE_REASON_MAX_STRING_SIZE 255
+
+#define rtcp_bye_set_ssrc(b,pos,ssrc) (b)->ssrc[pos]=htonl(ssrc)
+#define rtcp_bye_get_ssrc(b,pos) ntohl((b)->ssrc[pos])
+
+
+typedef struct rtcp_sr{
+ rtcp_common_header_t ch;
+ guint32 ssrc;
+ sender_info_t si;
+ report_block_t rb[1];
+} rtcp_sr_t;
+
+typedef struct rtcp_rr{
+ rtcp_common_header_t ch;
+ guint32 ssrc;
+ report_block_t rb[1];
+} rtcp_rr_t;
+
+struct _RtpSession;
+void rtp_session_rtcp_process(struct _RtpSession *s);
+
+#define RTCP_DEFAULT_REPORT_INTERVAL 5
+
+#endif
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtcpparse.c b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtcpparse.c
new file mode 100644
index 00000000..77e38245
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtcpparse.c
@@ -0,0 +1,218 @@
+/*
+ The oRTP library is an RTP (Realtime Transport Protocol - rfc1889) stack.
+ Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
+
+ This source code file was written by Nicola Baldo as an extension of
+ the oRTP library. Copyright (C) 2005 Nicola Baldo nicola@baldo.biz
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#include <ortp.h>
+
+
+
+void report_block_parse(RtpSession *session, report_block_t *rb, struct timeval rcv_time_tv)
+{
+ rb->ssrc = ntohl(rb->ssrc);
+
+ if ( rb->ssrc != session->send_ssrc )
+
+ {
+ ortp_debug("Received rtcp report block related to unknown ssrc (not from us)... discarded");
+ return;
+ }
+
+ else
+
+ {
+ guint32 rcv_time_msw;
+ guint32 rcv_time_lsw;
+ guint32 rcv_time;
+ double rtt;
+
+ rcv_time_msw = rcv_time_tv.tv_sec;
+ rcv_time_lsw = (guint32) ((double)rcv_time_tv.tv_usec*(double)(1LL<<32)*1.0e-6);
+ rcv_time = (rcv_time_msw<<16) | (rcv_time_lsw >> 16);
+
+ rb->cum_num_packet_lost = ntoh24(rb->cum_num_packet_lost);
+ rb->ext_high_seq_num_rec = ntohl(rb->ext_high_seq_num_rec);
+ rb->interarrival_jitter = ntohl(rb->interarrival_jitter);
+ rb->lsr = ntohl(rb->lsr);
+ rb->delay_snc_last_sr = ntohl(rb->delay_snc_last_sr);
+
+
+ /* calculating Round Trip Time*/
+ if (rb->lsr != 0)
+ {
+ rtt = (double) (rcv_time - rb->delay_snc_last_sr - rb->lsr);
+ rtt = rtt/65536;
+ //printf("RTT = %f s\n",rtt);
+ }
+
+ }
+
+}
+
+
+void rtcp_parse(RtpSession *session, mblk_t *mp)
+{
+ rtcp_common_header_t *rtcp;
+ int msgsize;
+ int rtcp_pk_size;
+ RtpStream *rtpstream=&session->rtp;
+ struct timeval rcv_time_tv;
+
+
+ gettimeofday(&rcv_time_tv,NULL);
+
+ g_return_if_fail(mp!=NULL);
+
+ msgsize=mp->b_wptr-mp->b_rptr;
+
+
+
+ if (msgsize < RTCP_COMMON_HEADER_SIZE)
+ {
+ ortp_debug("Receiving too short rtcp packet... discarded");
+ return;
+ }
+
+ rtcp=(rtcp_common_header_t *)mp->b_rptr;
+
+
+ /* compound rtcp packet can be composed by more than one rtcp message */
+ while (msgsize >= RTCP_COMMON_HEADER_SIZE)
+
+ {
+
+ if (rtcp->version!=2)
+ {
+ ortp_debug("Receiving rtcp packet with version number !=2...discarded");
+ return;
+ }
+
+ /* convert header data from network order to host order */
+ rtcp->length = ntohs(rtcp->length);
+
+
+ switch (rtcp->packet_type)
+
+ {
+
+ case RTCP_SR:
+
+ {
+ rtcp_sr_t *sr = (rtcp_sr_t *) rtcp;
+ report_block_t *rb;
+ int i;
+
+ if ( ntohl(sr->ssrc) != session->recv_ssrc )
+ {
+ ortp_debug("Receiving rtcp sr packet from unknown ssrc.. discarded");
+ return;
+ }
+
+ if (msgsize < RTCP_COMMON_HEADER_SIZE + RTCP_SSRC_FIELD_SIZE + RTCP_SENDER_INFO_SIZE + (RTCP_REPORT_BLOCK_SIZE*sr->ch.rc))
+ {
+ ortp_debug("Receiving too short rtcp sr packet... discarded");
+ return;
+ }
+
+ /* parsing RTCP Sender Info */
+ sr->si.ntp_timestamp_msw = ntohl(sr->si.ntp_timestamp_msw);
+ sr->si.ntp_timestamp_lsw = ntohl(sr->si.ntp_timestamp_lsw);
+ sr->si.rtp_timestamp = ntohl(sr->si.rtp_timestamp);
+ sr->si.senders_packet_count = ntohl(sr->si.senders_packet_count);
+ sr->si.senders_octet_count = ntohl(sr->si.senders_octet_count);
+
+ /* saving data to fill LSR and DLSR field in next RTCP report to be transmitted */
+ rtpstream->last_rcv_SR_ts = (sr->si.ntp_timestamp_msw << 16) | (sr->si.ntp_timestamp_lsw >> 16);
+ rtpstream->last_rcv_SR_time.tv_usec = rcv_time_tv.tv_usec;
+ rtpstream->last_rcv_SR_time.tv_sec = rcv_time_tv.tv_sec;
+
+
+ /* parsing all RTCP report blocks */
+ for (i=0; i<sr->ch.rc; i++)
+ {
+ rb = &(sr->rb[i]);
+ report_block_parse(session, rb, rcv_time_tv);
+ }
+
+ }
+ break;
+
+
+
+ case RTCP_RR:
+
+ {
+ rtcp_rr_t *rr = (rtcp_rr_t *) rtcp;
+ report_block_t *rb;
+ int i;
+
+ if ( ntohl(rr->ssrc) != session->recv_ssrc )
+ {
+ ortp_debug("Receiving rtcp rr packet from unknown ssrc.. discarded");
+ return;
+ }
+
+ if (msgsize < RTCP_COMMON_HEADER_SIZE + RTCP_SSRC_FIELD_SIZE + (RTCP_REPORT_BLOCK_SIZE*rr->ch.rc))
+ {
+ ortp_debug("Receiving too short rtcp sr packet... discarded");
+ return;
+ }
+
+ /* parsing all RTCP report blocks */
+ for (i=0; i<rr->ch.rc; i++)
+ {
+ rb = &(rr->rb[i]);
+ report_block_parse(session, rb, rcv_time_tv);
+ }
+
+ }
+ break;
+
+
+ case RTCP_SDES:
+ /* to be implemented */
+ break;
+
+
+ case RTCP_BYE:
+ /* to be implemented */
+ break;
+
+
+ case RTCP_APP:
+ /* to be implemented */
+ break;
+
+
+ default:
+
+ ortp_debug("Receiving unknown rtcp packet type... discarded");
+ return;
+
+ }
+
+
+ rtcp_pk_size = ((rtcp->length)+1)*4; /* current RTCP packet size, in octets */
+ msgsize -= rtcp_pk_size; /* size of unparsed portion of UDP packet, in octets */
+ rtcp = (rtcp_common_header_t *) (rtcp_pk_size + (char *) rtcp); /* pointer to next RTCP packet in current UDP packet */
+
+ }
+}
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtp.h b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtp.h
new file mode 100644
index 00000000..625d2111
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtp.h
@@ -0,0 +1,90 @@
+/*
+ The oRTP library is an RTP (Realtime Transport Protocol - rfc1889) stack.
+ Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef RTP_H
+#define RTP_H
+
+#include <rtpport.h>
+
+
+
+
+#define RTP_MAX_RQ_SIZE 100 /* max number of packet allowed to be enqueued */
+
+#define IPMAXLEN 20
+#define UDP_MAX_SIZE 65536
+#define RTP_FIXED_HEADER_SIZE 12
+#define RTP_DEFAULT_JITTER_TIME 80 /*miliseconds*/
+
+
+
+typedef struct rtp_header
+{
+#ifdef WORDS_BIGENDIAN
+ guint16 version:2;
+ guint16 padbit:1;
+ guint16 extbit:1;
+ guint16 cc:4;
+ guint16 markbit:1;
+ guint16 paytype:7;
+#else
+ guint16 cc:4;
+ guint16 extbit:1;
+ guint16 padbit:1;
+ guint16 version:2;
+ guint16 paytype:7;
+ guint16 markbit:1;
+#endif
+ guint16 seq_number;
+ guint32 timestamp;
+ guint32 ssrc;
+ guint32 csrc[16];
+} rtp_header_t;
+
+
+
+
+typedef struct rtp_stats
+{
+ guint64 packet_sent;
+ guint64 sent; /* bytes sent */
+ guint64 recv; /* bytes received and delivered in time to the application */
+ guint64 hw_recv; /* bytes of udp packets received */
+ guint64 packet_recv; /* number of packets received */
+ guint64 unavaillable; /* packets not availlable when they were queried */
+ guint64 outoftime; /* number of packets that were received too late */
+ guint64 skipped; /* number of packets skipped (that the application never queried
+ or that need to be skipped in order to compensate a clock slide (see adaptive jitter control)) */
+ guint64 cum_packet_loss; /* cumulative number of packet lost */
+ guint64 bad; /* packets that did not appear to be RTP */
+ guint64 discarded; /* incoming packets discarded because the queue exceeds its max size */
+} rtp_stats_t;
+
+#define RTP_TIMESTAMP_IS_NEWER_THAN(ts1,ts2) \
+ ((guint32)((guint32)(ts1) - (guint32)(ts2))< (guint32)(1<<31))
+
+#define RTP_TIMESTAMP_IS_STRICTLY_NEWER_THAN(ts1,ts2) \
+ ( ((guint32)((guint32)(ts1) - (guint32)(ts2))< (guint32)(1<<31)) && (ts1)!=(ts2) )
+
+#define TIME_IS_NEWER_THAN(t1,t2) RTP_TIMESTAMP_IS_NEWER_THAN(t1,t2)
+
+#define TIME_IS_STRICTLY_NEWER_THAN(t1,t2) RTP_TIMESTAMP_IS_STRICTLY_NEWER_THAN(t1,t2)
+
+#endif
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtpmod.c b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtpmod.c
new file mode 100644
index 00000000..50aeef10
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtpmod.c
@@ -0,0 +1,122 @@
+/*
+ The oRTP library is an RTP (Realtime Transport Protocol - rfc1889) stack.
+ Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+
+
+#include <rtp.h>
+#include "rtpmod.h"
+
+#define RTP_SEQ_IS_GREATER(seq1,seq2)\
+ ((guint16)((guint16)(seq1) - (guint16)(seq2))< (guint16)(1<<15))
+
+/* put an rtp packet in queue. It is called by rtp_parse()*/
+void rtp_putq(queue_t *q, mblk_t *mp)
+{
+ mblk_t *tmp;
+ rtp_header_t *rtp=(rtp_header_t*)mp->b_rptr,*tmprtp;
+ /* insert message block by increasing time stamp order : the last (at the bottom)
+ message of the queue is the newest*/
+ ortp_debug("rtp_putq(): Enqueuing packet with ts=%i and seq=%i",rtp->timestamp,rtp->seq_number);
+
+ if (qempty(q)) {
+ putq(q,mp);
+ return;
+ }
+ tmp=qlast(q);
+ /* we look at the queue from bottom to top, because enqueued packets have a better chance
+ to be enqueued at the bottom, since there are surely newer */
+ while (!qend(q,tmp))
+ {
+ tmprtp=(rtp_header_t*)tmp->b_rptr;
+ ortp_debug("rtp_putq(): Seeing packet with seq=%i",tmprtp->seq_number);
+
+ if (rtp->seq_number == tmprtp->seq_number)
+ {
+ /* this is a duplicated packet. Don't queue it */
+ ortp_debug("rtp_putq: duplicated message.");
+ freemsg(mp);
+ return;
+ }else if (RTP_SEQ_IS_GREATER(rtp->seq_number,tmprtp->seq_number)){
+
+ insq(q,tmp->b_next,mp);
+ return;
+ }
+ tmp=tmp->b_prev;
+ }
+ /* this packet is the oldest, it has to be
+ placed on top of the queue */
+ insq(q,qfirst(q),mp);
+
+}
+
+
+
+mblk_t *rtp_getq(queue_t *q,guint32 timestamp, int *rejected)
+{
+ mblk_t *tmp,*ret=NULL,*old;
+ rtp_header_t *tmprtp;
+ guint32 oldest;
+ guint32 ts_found=0;
+
+ *rejected=0;
+ ortp_debug("rtp_getq(): Timestamp %i wanted.",timestamp);
+
+ if (qempty(q))
+ {
+ /*ortp_debug("rtp_getq: q is empty.");*/
+ return NULL;
+ }
+ /* prevent somebody to ask for a timestamp that is older than the oldest of the queue */
+ oldest=((rtp_header_t*) qfirst(q)->b_rptr)->timestamp;
+ if (RTP_TIMESTAMP_IS_STRICTLY_NEWER_THAN(oldest,timestamp))
+ {
+ ortp_debug("rtp_getq(): asking for too old packet ! oldest=%i",oldest);
+ return NULL;
+ }
+ ret=NULL;
+ old=NULL;
+ /* return the packet with ts just equal or older than the asked timestamp */
+ while ((tmp=qfirst(q))!=NULL)
+ {
+ tmprtp=(rtp_header_t*)tmp->b_rptr;
+ ortp_debug("rtp_getq: Seeing packet with ts=%i",tmprtp->timestamp);
+ if ( RTP_TIMESTAMP_IS_NEWER_THAN(timestamp,tmprtp->timestamp) )
+ {
+ if (ret!=NULL && tmprtp->timestamp==ts_found) {
+ /* we've found two packets with same timestamp. return the first one */
+ break;
+ }
+ if (old!=NULL) {
+ ortp_debug("rtp_getq: discarding too old packet with ts=%i",ts_found);
+ (*rejected)++;
+ freemsg(old);
+ }
+ ret=getq(q); /* dequeue the packet, since it has an interesting timestamp*/
+ ts_found=tmprtp->timestamp;
+ ortp_debug("rtp_getq: Found packet with ts=%i",tmprtp->timestamp);
+ old=ret;
+ }
+ else
+ {
+ break;
+ }
+ }
+ return ret;
+}
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtpmod.h b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtpmod.h
new file mode 100644
index 00000000..e675394d
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtpmod.h
@@ -0,0 +1,31 @@
+/*
+ The oRTP library is an RTP (Realtime Transport Protocol - rfc1889) stack.
+ Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef RTPMOD_H
+#define RTPMOD_H
+
+#include <rtpport.h>
+#include <str_utils.h>
+#include <rtp.h>
+
+void rtp_putq(queue_t *q, mblk_t *mp);
+mblk_t *rtp_getq(queue_t *q,guint32 timestamp, int *rejected);
+
+#endif
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtpparse.c b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtpparse.c
new file mode 100644
index 00000000..50ecba97
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtpparse.c
@@ -0,0 +1,159 @@
+/*
+ The oRTP library is an RTP (Realtime Transport Protocol - rfc1889) stack.
+ Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#include <ortp.h>
+#include "rtpmod.h"
+#include "jitterctl.h"
+
+
+void split_and_queue(queue_t *q, int maxrqsz, mblk_t *mp, rtp_header_t *rtp, int *discarded)
+{
+ mblk_t *mdata,*tmp;
+ int header_size;
+ *discarded=0;
+ header_size=RTP_FIXED_HEADER_SIZE+ (4*rtp->cc);
+ if ((mp->b_wptr - mp->b_rptr)==header_size){
+ ortp_debug("Rtp packet contains no data.");
+ (*discarded)++;
+ freemsg(mp);
+ return;
+ }
+ /* creates a new mblk_t to be linked with the rtp header*/
+ mdata=dupb(mp);
+
+ mp->b_wptr=mp->b_rptr+header_size;
+ mdata->b_rptr+=header_size;
+ /* link proto with data */
+ mp->b_cont=mdata;
+ /* and then add the packet to the queue */
+
+ rtp_putq(q,mp);
+ /* make some checks: q size must not exceed RtpStream::max_rq_size */
+ while (q->q_mcount > maxrqsz)
+ {
+ /* remove the oldest mblk_t */
+ tmp=getq(q);
+ if (mp!=NULL)
+ {
+ ortp_debug("rtp_putq: Queue is full. Discarding message with ts=%i",((rtp_header_t*)mp->b_rptr)->timestamp);
+ freemsg(tmp);
+ (*discarded)++;
+ }
+ }
+}
+
+void rtp_parse(RtpSession *session, mblk_t *mp, guint32 local_str_ts)
+{
+ gint i;
+ rtp_header_t *rtp;
+ int msgsize;
+ RtpStream *rtpstream=&session->rtp;
+ rtp_stats_t *stats=&rtpstream->stats;
+
+ g_return_if_fail(mp!=NULL);
+
+ msgsize=msgdsize(mp);
+ ortp_global_stats.hw_recv+=msgsize;
+ stats->hw_recv+=msgsize;
+ ortp_global_stats.packet_recv++;
+ stats->packet_recv++;
+
+ session->rtp.hwrcv_since_last_SR++;
+
+ rtp=(rtp_header_t*)mp->b_rptr;
+ if (rtp->version!=2)
+ {
+ ortp_debug("Receiving rtp packet with version number !=2...discarded");
+ stats->bad++;
+ ortp_global_stats.bad++;
+ freemsg(mp);
+ return;
+ }
+
+ /* convert all header data from network order to host order */
+ rtp->seq_number=ntohs(rtp->seq_number);
+ rtp->timestamp=ntohl(rtp->timestamp);
+ rtp->ssrc=ntohl(rtp->ssrc);
+ /* convert csrc if necessary */
+ if (rtp->cc*sizeof(guint32) > (msgsize-RTP_FIXED_HEADER_SIZE)){
+ ortp_debug("Receiving too short rtp packet.");
+ stats->bad++;
+ ortp_global_stats.bad++;
+ freemsg(mp);
+ return;
+ }
+ for (i=0;i<rtp->cc;i++)
+ rtp->csrc[i]=ntohl(rtp->csrc[i]);
+ if (session->recv_ssrc!=0)
+ {
+ /*the ssrc is set, so we must check it */
+ if (session->recv_ssrc!=rtp->ssrc){
+ /*ortp_debug("rtp_parse: bad ssrc - %i",rtp->ssrc);*/
+ session->recv_ssrc=rtp->ssrc;
+ rtp_signal_table_emit(&session->on_ssrc_changed);
+ }
+ }else session->recv_ssrc=rtp->ssrc;
+
+ /* update some statistics */
+ if (rtp->seq_number>rtpstream->hwrcv_extseq.split.lo){
+ rtpstream->hwrcv_extseq.split.lo=rtp->seq_number;
+ }else if (rtp->seq_number<200 && rtpstream->hwrcv_extseq.split.lo>((1<<16) - 200)){
+ /* this is a check for sequence number looping */
+ rtpstream->hwrcv_extseq.split.lo=rtp->seq_number;
+ rtpstream->hwrcv_extseq.split.hi++;
+ }
+
+
+ /* check for possible telephone events */
+ if (rtp->paytype==session->telephone_events_pt){
+ split_and_queue(&session->rtp.tev_rq,session->rtp.max_rq_size,mp,rtp,&i);
+ stats->discarded+=i;
+ ortp_global_stats.discarded+=i;
+ return;
+ }
+
+ if (!(session->flags & RTP_SESSION_RECV_SYNC)){
+ gint32 slide=0;
+ gint32 safe_delay=0;
+ jitter_control_new_packet(&session->rtp.jittctl,rtp->timestamp,local_str_ts,&slide,&safe_delay);
+
+ session->rtp.rcv_diff_ts=session->rtp.hwrcv_diff_ts + slide - safe_delay;
+ ortp_debug(" rcv_diff_ts=%i", session->rtp.rcv_diff_ts);
+
+ /* detect timestamp important jumps in the future, to workaround stupid rtp senders */
+ if (RTP_TIMESTAMP_IS_NEWER_THAN(rtp->timestamp,session->rtp.rcv_last_ts+session->rtp.ts_jump)){
+ ortp_debug("rtp_parse: timestamp jump ?");
+ rtp_signal_table_emit2(&session->on_timestamp_jump,&rtp->timestamp);
+ }
+ else if (RTP_TIMESTAMP_IS_NEWER_THAN(session->rtp.rcv_last_ts,rtp->timestamp)){
+ /* avoid very old packet to enqueued, because the user is no more supposed to get them */
+ ortp_debug("rtp_parse: silently discarding very old packet (ts=%i)",rtp->timestamp);
+ freemsg(mp);
+ stats->outoftime++;
+ ortp_global_stats.outoftime++;
+ return;
+ }
+
+ }
+
+ split_and_queue(&session->rtp.rq,session->rtp.max_rq_size,mp,rtp,&i);
+ stats->discarded+=i;
+ ortp_global_stats.discarded+=i;
+}
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtpport.h b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtpport.h
new file mode 100644
index 00000000..65e48530
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtpport.h
@@ -0,0 +1,308 @@
+/*
+ The oRTP LinPhone RTP library intends to provide basics for a RTP stack.
+ Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+/* this file is responsible of the portability of the stack */
+
+#ifndef RTPPORT_H
+#define RTPPORT_H
+
+#ifdef UGLIB_H
+#define HAVE_GLIB
+#endif
+
+#ifndef _WIN32 /* do not include ortp-config.h when we are on win32 */
+# ifdef _ORTP_SOURCE
+# include <ortp-config.h>
+# else
+# include <ortp-config.h>
+# endif
+#else
+ #include "ortp-config-win32.h"
+#endif
+
+#define INT_TO_POINTER(truc) ((gpointer)(long)(truc))
+#define POINTER_TO_INT(truc) ((int)(long)(truc))
+
+/* defines things that should be defined when we have not glib */
+#ifndef HAVE_GLIB
+
+#include <errno.h>
+#include <sys/types.h>
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+/* integer types */
+typedef uint64_t guint64;
+typedef uint16_t guint16;
+typedef uint32_t guint32;
+typedef signed short gint16;
+typedef int32_t gint32;
+typedef unsigned int guint;
+typedef int gint;
+typedef char gchar;
+typedef unsigned char guchar;
+typedef unsigned char guint8;
+typedef void* gpointer;
+typedef int gboolean;
+typedef double gdouble;
+typedef float gfloat;
+
+#define TRUE 1
+#define FALSE 0
+
+
+/*misc*/
+#define g_return_if_fail(expr) if (!(expr)) {printf("%s:%i- assertion" #expr "failed\n",__FILE__,__LINE__); return;}
+#define g_return_val_if_fail(expr,ret) if (!(expr)) {printf("%s:%i- assertion" #expr "failed\n",__FILE__,__LINE__); return (ret);}
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+typedef enum {
+ /* GLib log levels */
+ G_LOG_LEVEL_ERROR = 1 << 2, /* always fatal */
+ G_LOG_LEVEL_CRITICAL = 1 << 3,
+ G_LOG_LEVEL_WARNING = 1 << 4,
+ G_LOG_LEVEL_MESSAGE = 1 << 5,
+ G_LOG_LEVEL_MASK = ~0
+
+} GLogLevelFlags;
+
+#ifndef G_LOG_DOMAIN
+#define G_LOG_DOMAIN ((const gchar*)"")
+#endif
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void g_log(const gchar *log_domain,GLogLevelFlags log_level,const gchar *format,...);
+void g_logv(const gchar *log_domain,GLogLevelFlags log_level,const gchar *format,va_list args);
+typedef void (*GLogFunc) (const gchar *log_domain,
+ GLogLevelFlags log_level,
+ const gchar *message,
+ gpointer user_data);
+static inline void g_warning(const gchar *fmt,...)
+{
+ va_list args;
+ va_start (args, fmt);
+ g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, fmt, args);
+ va_end (args);
+}
+static inline void g_error(const gchar *fmt,...)
+{
+ va_list args;
+ va_start (args, fmt);
+ g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, fmt, args);
+ va_end (args);
+}
+static inline void g_message(const gchar *fmt,...)
+{
+ va_list args;
+ va_start (args, fmt);
+ g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, fmt, args);
+ va_end (args);
+}
+/* in order to simplify, domain is ignored when using the folowing function, ie all logs will go through your handler
+whatever the domain is */
+void g_log_set_handler(const gchar *domain, GLogLevelFlags levels, GLogFunc func, gpointer ud);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAVE_GLIB */
+
+
+#if defined(TIME_WITH_SYS_TIME)
+#include <time.h>
+#include <sys/time.h>
+#elif defined(HAVE_SYS_TIME_H)
+#include <sys/time.h>
+#endif
+
+
+#ifdef HAVE_GLIB
+
+#ifndef UGLIB_H
+#include <glib.h>
+#endif
+#include <string.h>
+
+
+#else /* not HAVE_GLIB */
+/* things that in glib, but should only be defined when we are not in the HPUX kernel. */
+#include <stdlib.h>
+#include <pthread.h>
+#include <sched.h>
+#include <string.h>
+
+#ifdef ENABLE_MEMCHECK
+extern gint ortp_allocations;
+#endif
+
+/* memory allocation functions */
+static inline void * g_malloc(int sz)
+{
+ void *p=malloc(sz);
+ if (p==NULL) {
+ printf("g_malloc: Failed to allocate %i bytes: %s.\n",sz,strerror(errno));
+ abort();
+ }
+#ifdef ENABLE_MEMCHECK
+ ortp_allocations++;
+#endif
+ return p;
+}
+
+static inline void * g_malloc0(int sz)
+{
+ void *p=malloc(sz);
+ if (p==NULL) {
+ printf("g_malloc: Failed to allocate %i bytes: %s.\n",sz,strerror(errno));
+ abort();
+ }
+ memset(p,0,sz);
+#ifdef ENABLE_MEMCHECK
+ ortp_allocations++;
+#endif
+ return p;
+}
+
+#define g_new(type,count) (type *)g_malloc(sizeof(type)*(count))
+#define g_new0(type, count) (type *)g_malloc0(sizeof(type)*(count))
+#define g_realloc(p,sz) realloc((p),(sz))
+static inline void g_free(void *p)
+{
+#ifdef ENABLE_MEMCHECK
+ ortp_allocations--;
+#endif
+ free(p);
+}
+
+#define g_strdup(machin) strdup(machin)
+
+typedef pthread_mutex_t GMutex;
+static inline GMutex * g_mutex_new()
+{
+ pthread_mutex_t *mutex=g_new(pthread_mutex_t,1);
+ pthread_mutex_init(mutex,NULL);
+ return mutex;
+}
+typedef enum
+{
+ G_THREAD_PRIORITY_LOW,
+ G_THREAD_PRIORITY_NORMAL,
+ G_THREAD_PRIORITY_HIGH,
+ G_THREAD_PRIORITY_URGENT
+} GThreadPriority;
+typedef pthread_t GThread;
+typedef gpointer (*GThreadFunc)(gpointer data);
+static inline GThread *g_thread_create(GThreadFunc func, gpointer data, gboolean joinable, void **error){
+ GThread *thread=g_new(GThread,1);
+ pthread_create(thread,NULL,func,data);
+ return thread;
+}
+
+static inline void g_thread_join(GThread *thread){
+ pthread_join(*thread,NULL);
+ g_free(thread);
+}
+
+static inline void g_thread_set_priority(GThread *thread,GThreadPriority prio){
+ if (prio>G_THREAD_PRIORITY_NORMAL){
+ /* this is unsupported on HPUX */
+ /*
+ struct sched_param param;
+ param.sched_priority=1;
+ sched_setscheduler(*thread,SCHED_RR,&param);
+ */
+ }
+}
+
+#define g_mutex_lock(mutex) pthread_mutex_lock((mutex))
+#define g_mutex_unlock(mutex) pthread_mutex_unlock((mutex))
+#define g_mutex_free(mutex) pthread_mutex_destroy((mutex));g_free((mutex))
+
+typedef pthread_cond_t GCond;
+static inline GCond * g_cond_new()
+{
+ pthread_cond_t *cond=g_new(pthread_cond_t,1);
+ pthread_cond_init(cond,NULL);
+ return cond;
+}
+#define g_cond_wait(cond,mutex) pthread_cond_wait((cond),(mutex))
+#define g_cond_signal(cond) pthread_cond_signal((cond))
+#define g_cond_broadcast(cond) pthread_cond_broadcast((cond))
+#define g_cond_free(cond) pthread_cond_destroy((cond)); g_free((cond))
+
+#define g_thread_init(vtable)
+#define g_thread_supported() (1)
+
+#endif /* HAVE_GLIB */
+
+
+#ifndef RTP_DEBUG
+#define ortp_debug(...)
+#else
+#define ortp_debug g_message
+#endif
+
+#ifdef _WIN32
+extern char *getSocketError();
+#define getSocketErrorCode() WSAGetLastError ()
+#else
+#define getSocketError() strerror(errno)
+#define getSocketErrorCode() (errno)
+#endif
+
+#ifdef UGLIB_H
+#undef HAVE_GLIB
+#endif
+
+#undef MIN
+#define MIN(a,b) (((a)>(b)) ? (b) : (a))
+#undef MAX
+#define MAX(a,b) (((a)>(b)) ? (a) : (b))
+
+typedef struct _dwsplit_t{
+#ifdef WORDS_BIGENDIAN
+ guint16 hi;
+ guint16 lo;
+#else
+ guint16 lo;
+ guint16 hi;
+#endif
+} dwsplit_t;
+
+typedef union{
+ dwsplit_t split;
+ guint32 one;
+} poly32_t;
+
+#ifdef WORDS_BIGENDIAN
+#define hton24(x) (x)
+#else
+#define hton24(x) ((( (x) & 0x00ff0000) >>16) | (( (x) & 0x000000ff) <<16) | ( (x) & 0x0000ff00) )
+#endif
+#define ntoh24(x) hton24(x)
+
+#endif /*RTPPORT_H*/
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtpsession.c b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtpsession.c
new file mode 100644
index 00000000..de6b2e7d
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtpsession.c
@@ -0,0 +1,1954 @@
+/*
+ The oRTP library is an RTP (Realtime Transport Protocol - rfc1889) stack.
+ Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#include <ortp.h>
+#include <telephonyevents.h>
+#include "rtpmod.h"
+#include "jitterctl.h"
+#include "scheduler.h"
+#include "port_fct.h"
+#include "utils.h"
+
+#include <fcntl.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifndef _WIN32
+# include <sys/types.h>
+# include <sys/socket.h>
+# include <netinet/in.h>
+# include <arpa/inet.h>
+# ifdef INET6
+# include <netdb.h>
+# endif
+#else
+# include <winsock2.h>
+# include "errno-win32.h"
+#endif
+
+
+#if defined(HAVE_POLL_H)
+#include <poll.h>
+#elif defined(HAVE_SYS_POLL_H)
+#include <sys/poll.h>
+#endif
+#ifdef HAVE_SYS_UIO_H
+#include <sys/uio.h>
+#define USE_SENDMSG 1
+#endif
+
+
+
+void wait_point_init(WaitPoint *wp){
+ wp->lock=g_mutex_new();
+ wp->cond=g_cond_new();
+ wp->time=0;
+ wp->wakeup=FALSE;
+}
+void wait_point_uninit(WaitPoint *wp){
+ g_cond_free(wp->cond);
+ g_mutex_free(wp->lock);
+}
+
+#define wait_point_lock(wp) g_mutex_lock((wp)->lock)
+#define wait_point_unlock(wp) g_mutex_unlock((wp)->lock)
+
+void wait_point_wakeup_at(WaitPoint *wp, guint32 t, gboolean dosleep){
+ wp->time=t;
+ wp->wakeup=TRUE;
+ if (dosleep) g_cond_wait(wp->cond,wp->lock);
+}
+
+
+gboolean wait_point_check(WaitPoint *wp, guint32 t){
+ gboolean ok=FALSE;
+
+ if (wp->wakeup){
+ if (TIME_IS_NEWER_THAN(t,wp->time)){
+ wp->wakeup=FALSE;
+ ok=TRUE;
+
+ }
+ }
+ return ok;
+}
+#define wait_point_wakeup(wp) g_cond_signal((wp)->cond);
+
+extern void rtp_parse(RtpSession *session, mblk_t *mp, guint32 local_str_ts);
+
+
+static guint32 guint32_random(){
+ return random();
+}
+
+void
+rtp_session_init (RtpSession * session, gint mode)
+{
+ memset (session, 0, sizeof (RtpSession));
+ session->lock = g_mutex_new ();
+ session->rtp.max_rq_size = RTP_MAX_RQ_SIZE;
+ session->mode = mode;
+ if ((mode == RTP_SESSION_RECVONLY) || (mode == RTP_SESSION_SENDRECV))
+ {
+ rtp_session_set_flag (session, RTP_SESSION_RECV_SYNC);
+ rtp_session_set_flag (session, RTP_SESSION_RECV_NOT_STARTED);
+
+ }
+ if ((mode == RTP_SESSION_SENDONLY) || (mode == RTP_SESSION_SENDRECV))
+ {
+ rtp_session_set_flag (session, RTP_SESSION_SEND_NOT_STARTED);
+ rtp_session_set_flag (session, RTP_SESSION_SEND_SYNC);
+ session->send_ssrc=guint32_random();
+ /* set default source description */
+ rtp_session_set_source_description(session,"unknown@unknown",NULL,NULL,
+ NULL,NULL,"oRTP-" ORTP_VERSION,"This is free sofware (LGPL) !");
+ }
+ session->telephone_events_pt=-1; /* not defined a priori */
+ rtp_session_set_profile (session, &av_profile); /*the default profile to work with */
+ session->payload_type=0;/* default to something */
+ qinit(&session->rtp.rq);
+ qinit(&session->rtp.tev_rq);
+ qinit(&session->contributing_sources);
+ /* init signal tables */
+ rtp_signal_table_init (&session->on_ssrc_changed, session,"ssrc_changed");
+ rtp_signal_table_init (&session->on_payload_type_changed, session,"payload_type_changed");
+ rtp_signal_table_init (&session->on_telephone_event, session,"telephone-event");
+ rtp_signal_table_init (&session->on_telephone_event_packet, session,"telephone-event_packet");
+ rtp_signal_table_init (&session->on_timestamp_jump,session,"timestamp_jump");
+ rtp_signal_table_init (&session->on_network_error,session,"network_error");
+ wait_point_init(&session->send_wp);
+ wait_point_init(&session->recv_wp);
+ rtp_session_set_jitter_compensation(session,RTP_DEFAULT_JITTER_TIME);
+ rtp_session_enable_adaptive_jitter_compensation(session,FALSE);
+ rtp_session_set_time_jump_limit(session,5000);
+ session->max_buf_size = UDP_MAX_SIZE;
+}
+
+/**
+ *rtp_session_new:
+ *@mode: One of the #RtpSessionMode flags.
+ *
+ * Creates a new rtp session.
+ * If the session is able to send data (RTP_SESSION_SENDONLY or RTP_SESSION_SENDRECV), then a
+ * random SSRC number is choosed for the outgoing stream.
+ *
+ *Returns: the newly created rtp session.
+**/
+
+RtpSession *
+rtp_session_new (gint mode)
+{
+ RtpSession *session;
+ session = g_malloc (sizeof (RtpSession));
+ rtp_session_init (session, mode);
+ return session;
+}
+
+/**
+ *rtp_session_set_scheduling_mode:
+ *@session: a rtp session.
+ *@yesno: a boolean to indicate the scheduling mode.
+ *
+ * Sets the scheduling mode of the rtp session. If @yesno is TRUE, the rtp session is in
+ * the scheduled mode, that means that you can use session_set_select() to block until it's time
+ * to receive or send on this session according to the timestamp passed to the respective functions.
+ * You can also use blocking mode (see rtp_session_set_blocking_mode() ), to simply block within
+ * the receive and send functions.
+ * If @yesno is FALSE, the ortp scheduler will not manage those sessions, meaning that blocking mode
+ * and the use of session_set_select() for this session are disabled.
+ *
+**/
+
+void
+rtp_session_set_scheduling_mode (RtpSession * session, gint yesno)
+{
+ if (yesno)
+ {
+ RtpScheduler *sched;
+ sched = ortp_get_scheduler ();
+ if (sched != NULL)
+ {
+ rtp_session_set_flag (session, RTP_SESSION_SCHEDULED);
+ session->sched = sched;
+ rtp_scheduler_add_session (sched, session);
+ }
+ else
+ g_warning
+ ("rtp_session_set_scheduling_mode: Cannot use scheduled mode because the "
+ "scheduler is not started. Use ortp_scheduler_init() before.");
+ }
+ else
+ rtp_session_unset_flag (session, RTP_SESSION_SCHEDULED);
+}
+
+
+/**
+ *rtp_session_set_blocking_mode:
+ *@session: a rtp session
+ *@yesno: a boolean
+ *
+ * Using this function implies that you previously enabled scheduled mode on the session
+ * (see rtp_session_set_scheduling_mode() ).
+ * rtp_session_set_blocking_mode() defines the behaviour of the rtp_session_recv_with_ts() and
+ * rtp_session_send_with_ts() functions. If @yesno is TRUE, rtp_session_recv_with_ts()
+ * will block until it is time for the packet to be received, according to the timestamp
+ * passed to the function. After this time, the function returns.
+ * For rtp_session_send_with_ts(), it will block until it is time for the packet to be sent.
+ * If @yesno is FALSE, then the two functions will return immediately.
+ *
+**/
+void
+rtp_session_set_blocking_mode (RtpSession * session, gint yesno)
+{
+ if (yesno)
+ rtp_session_set_flag (session, RTP_SESSION_BLOCKING_MODE);
+ else
+ rtp_session_unset_flag (session, RTP_SESSION_BLOCKING_MODE);
+}
+
+/**
+ *rtp_session_set_profile:
+ *@session: a rtp session
+ *@profile: a rtp profile
+ *
+ * Set the RTP profile to be used for the session. By default, all session are created by
+ * rtp_session_new() are initialized with the AV profile, as defined in RFC 1890. The application
+ * can set any other profile instead using that function.
+ *
+ *
+**/
+
+void
+rtp_session_set_profile (RtpSession * session, RtpProfile * profile)
+{
+ session->profile = profile;
+ rtp_session_telephone_events_supported(session);
+}
+
+
+/**
+ *rtp_session_signal_connect:
+ *@session: a rtp session
+ *@signal: the name of a signal
+ *@cb: a #RtpCallback
+ *@user_data: a pointer to any data to be passed when invoking the callback.
+ *
+ * This function provides the way for an application to be informed of various events that
+ * may occur during a rtp session. @signal is a string identifying the event, and @cb is
+ * a user supplied function in charge of processing it. The application can register
+ * several callbacks for the same signal, in the limit of #RTP_CALLBACK_TABLE_MAX_ENTRIES.
+ * Here are name and meaning of supported signals types:
+ *
+ * "ssrc_changed" : the SSRC of the incoming stream has changed.
+ *
+ * "payload_type_changed" : the payload type of the incoming stream has changed.
+ *
+ * "telephone-event_packet" : a telephone-event rtp packet (RFC2833) is received.
+ *
+ * "telephone-event" : a telephone event has occured. This is a high-level shortcut for "telephone-event_packet".
+ *
+ * "network_error" : a network error happened on a socket. Arguments of the callback functions are
+ * a const char * explaining the error, an int errno error code and the user_data as usual.
+ *
+ * "timestamp_jump" : we have received a packet with timestamp in far future compared to last timestamp received.
+ * The farness of far future is set by rtp_sesssion_set_time_jump_limit()
+ *
+ * Returns: 0 on success, -EOPNOTSUPP if the signal does not exists, -1 if no more callbacks
+ * can be assigned to the signal type.
+**/
+int
+rtp_session_signal_connect (RtpSession * session, const char *signal,
+ RtpCallback cb, gpointer user_data)
+{
+ OList *elem;
+ for (elem=session->signal_tables;elem!=NULL;elem=o_list_next(elem)){
+ RtpSignalTable *s=(RtpSignalTable*) elem->data;
+ if (strcmp(signal,s->signal_name)==0){
+ return rtp_signal_table_add(s,cb,user_data);
+ }
+ }
+ g_warning ("rtp_session_signal_connect: inexistant signal %s",signal);
+ return -1;
+}
+
+
+/**
+ *rtp_session_signal_disconnect_by_callback:
+ *@session: a rtp session
+ *@signal: a signal name
+ *@cb: a callback function.
+ *
+ * Removes callback function @cb to the list of callbacks for signal @signal.
+ *
+ *Returns: 0 on success, -ENOENT if the callbacks was not found.
+**/
+
+int
+rtp_session_signal_disconnect_by_callback (RtpSession * session, const gchar *signal,
+ RtpCallback cb)
+{
+ OList *elem;
+ for (elem=session->signal_tables;elem!=NULL;elem=o_list_next(elem)){
+ RtpSignalTable *s=(RtpSignalTable*) elem->data;
+ if (strcmp(signal,s->signal_name)==0){
+ return rtp_signal_table_remove_by_callback(s,cb);
+ }
+ }
+ g_warning ("rtp_session_signal_connect: inexistant signal %s",signal);
+ return -1;
+}
+
+/**
+ *rtp_session_set_local_addr:
+ *@session: a rtp session freshly created.
+ *@addr: a local IP address in the xxx.xxx.xxx.xxx form.
+ *@port: a local port.
+ *
+ * Specify the local addr to be use to listen for rtp packets or to send rtp packet from.
+ * In case where the rtp session is send-only, then it is not required to call this function:
+ * when calling rtp_session_set_remote_addr(), if no local address has been set, then the
+ * default INADRR_ANY (0.0.0.0) IP address with a random port will be used. Calling
+ * rtp_sesession_set_local_addr() is mandatory when the session is recv-only or duplex.
+ *
+ * Returns: 0 on success.
+**/
+
+gint
+rtp_session_set_local_addr (RtpSession * session, const gchar * addr, gint port)
+{
+ gint err;
+ gint optval = 1;
+#ifdef INET6
+ char num[8];
+ struct addrinfo hints, *res0, *res;
+#endif
+
+ if (session->rtp.socket>0) {
+ /* dont try to rebind, close socket before */
+ close_socket(session->rtp.socket);
+ close_socket(session->rtcp.socket);
+ session->rtp.socket=0;
+ session->rtcp.socket=0;
+ }
+
+#ifdef INET6
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = PF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ snprintf(num, sizeof(num), "%d",port);
+ err = getaddrinfo(addr,num, &hints, &res0);
+ if (err!=0) {
+ g_warning ("Error: %s", gai_strerror(err));
+ return err;
+ }
+
+ for (res = res0; res; res = res->ai_next) {
+ session->rtp.socket = socket(res->ai_family, res->ai_socktype, 0);
+ if (session->rtp.socket < 0)
+ continue;
+
+ err = setsockopt (session->rtp.socket, SOL_SOCKET, SO_REUSEADDR,
+ (void*)&optval, sizeof (optval));
+ if (err < 0)
+ {
+ g_warning ("Fail to set rtp address reusable: %s.", getSocketError());
+ }
+
+ session->rtp.socktype=res->ai_family;
+ memcpy(&session->rtp.loc_addr, res->ai_addr, res->ai_addrlen);
+ err = bind (session->rtp.socket, res->ai_addr, res->ai_addrlen);
+ if (err != 0)
+ {
+ g_warning ("Fail to bind rtp socket to port %i: %s.", port, getSocketError());
+ close_socket (session->rtp.socket);
+ continue;
+ }
+#ifndef __hpux
+ switch (res->ai_family)
+ {
+ case AF_INET:
+ if (IN_MULTICAST(ntohl(((struct sockaddr_in *) res->ai_addr)->sin_addr.s_addr)))
+ {
+ struct ip_mreq mreq;
+ mreq.imr_multiaddr.s_addr = ((struct sockaddr_in *) res->ai_addr)->sin_addr.s_addr;
+ mreq.imr_interface.s_addr = INADDR_ANY;
+ err = setsockopt(session->rtp.socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
+ if (err < 0)
+ {
+ g_warning ("Fail to join address group: %s.", getSocketError());
+ close_socket (session->rtp.socket);
+ continue;
+ }
+ }
+ break;
+ case AF_INET6:
+ if (IN6_IS_ADDR_MULTICAST(&(((struct sockaddr_in6 *) res->ai_addr)->sin6_addr)))
+ {
+ struct ipv6_mreq mreq;
+ mreq.ipv6mr_multiaddr = ((struct sockaddr_in6 *) res->ai_addr)->sin6_addr;
+ mreq.ipv6mr_interface = 0;
+ err = setsockopt(session->rtp.socket, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq));
+ if (err < 0)
+ {
+ g_warning ("Fail to join address group: %s.", getSocketError());
+ close_socket (session->rtp.socket);
+ continue;
+ }
+ }
+ break;
+ }
+#endif
+ break;
+ }
+ freeaddrinfo(res0);
+ if (session->rtp.socket < 0){
+ if (session->mode==RTP_SESSION_RECVONLY) g_warning("Could not create rtp socket with address %s: %s",addr,getSocketError());
+ return -1;
+ }
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = PF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ snprintf(num, sizeof(num), "%d", (port + 1));
+
+ err = getaddrinfo(addr, num, &hints, &res0);
+ if (err!=0) {
+ g_warning ("Error: %s", gai_strerror(err));
+ return err;
+ }
+
+ for (res = res0; res; res = res->ai_next) {
+ session->rtcp.socket = socket(res->ai_family, res->ai_socktype, 0);
+
+ if (session->rtcp.socket < 0)
+ continue;
+
+ err = setsockopt (session->rtcp.socket, SOL_SOCKET, SO_REUSEADDR,
+ (void*)&optval, sizeof (optval));
+ if (err < 0)
+ {
+ g_warning ("Fail to set rtcp address reusable: %s.",getSocketError());
+ }
+ session->rtcp.socktype=res->ai_family;
+ memcpy( &session->rtcp.loc_addr, res->ai_addr, res->ai_addrlen);
+ err = bind (session->rtcp.socket, res->ai_addr, res->ai_addrlen);
+ if (err != 0)
+ {
+ g_warning ("Fail to bind rtp socket to port %i: %s.", port, getSocketError());
+ close_socket (session->rtp.socket);
+ close_socket (session->rtcp.socket);
+ continue;
+ }
+#ifndef __hpux
+ switch (res->ai_family)
+ {
+ case AF_INET:
+ if (IN_MULTICAST(ntohl(((struct sockaddr_in *) res->ai_addr)->sin_addr.s_addr)))
+ {
+ struct ip_mreq mreq;
+ mreq.imr_multiaddr.s_addr = ((struct sockaddr_in *) res->ai_addr)->sin_addr.s_addr;
+ mreq.imr_interface.s_addr = INADDR_ANY;
+ err = setsockopt(session->rtcp.socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
+ if (err < 0)
+ {
+ g_warning ("Fail to join address group: %s.", getSocketError());
+ close_socket (session->rtp.socket);
+ close_socket (session->rtcp.socket);
+ continue;
+ }
+ }
+ break;
+ case AF_INET6:
+ if (IN6_IS_ADDR_MULTICAST(&(((struct sockaddr_in6 *) res->ai_addr)->sin6_addr)))
+ {
+ struct ipv6_mreq mreq;
+ mreq.ipv6mr_multiaddr = ((struct sockaddr_in6 *) res->ai_addr)->sin6_addr;
+ mreq.ipv6mr_interface = 0;
+ err = setsockopt(session->rtcp.socket, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq));
+ if (err < 0)
+ {
+ g_warning ("Fail to join address group: %s.", getSocketError());
+ close_socket (session->rtp.socket);
+ close_socket (session->rtcp.socket);
+ continue;
+ }
+ }
+ break;
+ }
+#endif
+
+ break;
+ }
+ freeaddrinfo(res0);
+ if (session->rtp.socket < 0){
+ g_warning("Could not create rtcp socket with address %s: %s",addr,getSocketError());
+ return -1;
+ }
+#else
+ session->rtp.loc_addr.sin_family = AF_INET;
+
+ err = inet_aton (addr, &session->rtp.loc_addr.sin_addr);
+
+ if (err < 0)
+ {
+ g_warning ("Error in socket address:%s.", getSocketError());
+ return err;
+ }
+ session->rtp.loc_addr.sin_port = htons (port);
+
+ session->rtp.socket = socket (PF_INET, SOCK_DGRAM, 0);
+ g_return_val_if_fail (session->rtp.socket > 0, -1);
+
+ err = setsockopt (session->rtp.socket, SOL_SOCKET, SO_REUSEADDR,
+ (void*)&optval, sizeof (optval));
+ if (err < 0)
+ {
+ g_warning ("Fail to set rtp address reusable: %s.",getSocketError());
+ }
+
+ err = bind (session->rtp.socket,
+ (struct sockaddr *) &session->rtp.loc_addr,
+ sizeof (struct sockaddr_in));
+
+ if (err != 0)
+ {
+ g_warning ("Fail to bind rtp socket to port %i: %s.", port, getSocketError());
+ close_socket (session->rtp.socket);
+ return -1;
+ }
+ memcpy (&session->rtcp.loc_addr, &session->rtp.loc_addr,
+ sizeof (struct sockaddr_in));
+ session->rtcp.loc_addr.sin_port = htons (port + 1);
+ session->rtcp.socket = socket (PF_INET, SOCK_DGRAM, 0);
+ g_return_val_if_fail (session->rtcp.socket > 0, -1);
+
+ err = setsockopt (session->rtcp.socket, SOL_SOCKET, SO_REUSEADDR,
+ (void*)&optval, sizeof (optval));
+ if (err < 0)
+ {
+ g_warning ("Fail to set rtcp address reusable: %s.",getSocketError());
+ }
+
+ err = bind (session->rtcp.socket,
+ (struct sockaddr *) &session->rtcp.loc_addr,
+ sizeof (struct sockaddr_in));
+ if (err != 0)
+ {
+ g_warning ("Fail to bind rtcp socket to port %i: %s.", port + 1, getSocketError());
+ close_socket (session->rtp.socket);
+ close_socket (session->rtcp.socket);
+ return -1;
+ }
+#ifndef __hpux
+ if (IN_MULTICAST(ntohl(session->rtp.loc_addr.sin_addr.s_addr)))
+ {
+ struct ip_mreq mreq;
+ mreq.imr_multiaddr.s_addr = session->rtp.loc_addr.sin_addr.s_addr;
+ mreq.imr_interface.s_addr = INADDR_ANY;
+ err = setsockopt(session->rtp.socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
+ if (err == 0)
+ err = setsockopt(session->rtcp.socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
+ if (err < 0)
+ {
+ g_warning ("Fail to join address group: %s.", getSocketError());
+ close_socket (session->rtp.socket);
+ close_socket (session->rtcp.socket);
+ return -1;
+ }
+ }
+#endif
+#endif
+ /* set RTP socket options */
+ set_non_blocking_socket (session->rtp.socket);
+ /* set RTCP socket options */
+ set_non_blocking_socket (session->rtcp.socket);
+ return 0;
+}
+
+
+/**
+ *rtp_session_set_remote_addr:
+ *@session: a rtp session freshly created.
+ *@addr: a local IP address in the xxx.xxx.xxx.xxx form.
+ *@port: a local port.
+ *
+ * Sets the remote address of the rtp session, ie the destination address where rtp packet
+ * are sent. If the session is recv-only or duplex, it also sets the origin of incoming RTP
+ * packets. Rtp packets that don't come from addr:port are discarded.
+ *
+ * Returns: 0 on success.
+**/
+
+gint
+rtp_session_set_remote_addr (RtpSession * session, const gchar * addr, gint port)
+{
+ gint err;
+#ifdef INET6
+ struct addrinfo hints, *res0, *res;
+ char num[8];
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = PF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ snprintf(num, sizeof(num), "%d", port);
+ err = getaddrinfo(addr, num, &hints, &res0);
+ if (err) {
+ g_warning ("Error in socket address: %s", gai_strerror(err));
+ return err;
+ }
+#endif
+
+ if (session->rtp.socket == 0)
+ {
+ int retry;
+ /* the session has not its socket bound, do it */
+ g_message ("Setting random local addresses.");
+ for (retry=0;retry<10;retry++)
+ {
+ int localport;
+ do
+ {
+ localport = (rand () + 5000) & 0xfffe;
+ }
+ while ((localport < 5000) || (localport > 0xffff));
+#ifdef INET6
+ /* bind to an address type that matches the destination address */
+ if (res0->ai_addr->sa_family==AF_INET6)
+ err = rtp_session_set_local_addr (session, "::", localport);
+ else err=rtp_session_set_local_addr (session, "0.0.0.0", localport);
+#else
+ err = rtp_session_set_local_addr (session, "0.0.0.0", localport);
+#endif
+
+ if (err == 0)
+ break;
+ }
+ if (retry == 10){
+ g_warning("rtp_session_set_remote_addr: Could not find a random local address for socket !");
+ return -1;
+ }
+ }
+
+
+#ifdef INET6
+ err=1;
+ for (res = res0; res; res = res->ai_next) {
+ /* set a destination address that has the same type as the local address */
+ if (res->ai_family==session->rtp.socktype ) {
+ memcpy( &session->rtp.rem_addr, res->ai_addr, res->ai_addrlen);
+ session->rtp.addrlen=res->ai_addrlen;
+ err=0;
+ break;
+ }
+ }
+ freeaddrinfo(res0);
+ if (err) {
+ g_warning("Could not set destination for RTP socket to %s:%i.",addr,port);
+ return -1;
+ }
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = PF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ snprintf(num, sizeof(num), "%d", (port + 1));
+ err = getaddrinfo(addr, num, &hints, &res0);
+ if (err) {
+ g_warning ("Error: %s", gai_strerror(err));
+ return err;
+ }
+ err=1;
+ for (res = res0; res; res = res->ai_next) {
+ /* set a destination address that has the same type as the local address */
+ if (res->ai_family==session->rtp.socktype ) {
+ err=0;
+ memcpy( &session->rtcp.rem_addr, res->ai_addr, res->ai_addrlen);
+ session->rtcp.addrlen=res->ai_addrlen;
+ break;
+ }
+ }
+ freeaddrinfo(res0);
+ if (err) {
+ g_warning("Could not set destination for RCTP socket to %s:%i.",addr,port+1);
+ return -1;
+ }
+#else
+ session->rtp.addrlen=sizeof(session->rtp.rem_addr);
+ session->rtp.rem_addr.sin_family = AF_INET;
+
+ err = inet_aton (addr, &session->rtp.rem_addr.sin_addr);
+ if (err < 0)
+ {
+ g_warning ("Error in socket address:%s.", getSocketError());
+ return err;
+ }
+ session->rtp.rem_addr.sin_port = htons (port);
+
+ memcpy (&session->rtcp.rem_addr, &session->rtp.rem_addr,
+ sizeof (struct sockaddr_in));
+ session->rtcp.rem_addr.sin_port = htons (port + 1);
+ session->rtcp.addrlen=sizeof(session->rtp.rem_addr);
+#endif
+#ifndef NOCONNECT
+ if (session->mode == RTP_SESSION_SENDONLY)
+ {
+ err = connect (session->rtp.socket,
+ (struct sockaddr *) &session->rtp.rem_addr,
+#ifdef INET6
+ session->rtp.addrlen);
+#else
+ sizeof (struct sockaddr_in));
+#endif
+ if (err != 0)
+ {
+ g_message ("Can't connect rtp socket: %s.",getSocketError());
+ return err;
+ }
+ err = connect (session->rtcp.socket,
+ (struct sockaddr *) &session->rtcp.rem_addr,
+#ifdef INET6
+ session->rtcp.addrlen);
+#else
+ sizeof (struct sockaddr_in));
+#endif
+ if (err != 0)
+ {
+ g_message ("Can't connect rtp socket: %s.",getSocketError());
+ return err;
+ }
+ }
+#endif
+ return 0;
+}
+
+void rtp_session_set_sockets(RtpSession *session, gint rtpfd, gint rtcpfd)
+{
+ if (rtpfd>0) set_non_blocking_socket(rtpfd);
+ if (rtcpfd>0) set_non_blocking_socket(rtcpfd);
+ session->rtp.socket=rtpfd;
+ session->rtcp.socket=rtcpfd;
+ session->flags|=RTP_SESSION_USING_EXT_SOCKETS;
+}
+
+/**
+ *rtp_session_flush_sockets:
+ *@session: a rtp session
+ *
+ * Flushes the sockets for all pending incoming packets.
+ * This can be usefull if you did not listen to the stream for a while
+ * and wishes to start to receive again. During the time no receive is made
+ * packets get bufferised into the internal kernel socket structure.
+ *
+**/
+void rtp_session_flush_sockets(RtpSession *session){
+ char trash[4096];
+#ifdef INET6
+ struct sockaddr_storage from;
+#else
+ struct sockaddr from;
+#endif
+ socklen_t fromlen=sizeof(from);
+ if (session->rtp.socket>0){
+ while (recvfrom(session->rtp.socket,(void*)trash,sizeof(trash),0,(struct sockaddr *)&from,&fromlen)>0){};
+ }
+ if (session->rtcp.socket>0){
+ while (recvfrom(session->rtcp.socket,(void*)trash,sizeof(trash),0,(struct sockaddr*)&from,&fromlen)>0){};
+ }
+}
+
+/**
+ *rtp_session_set_seq_number:
+ *@session: a rtp session freshly created.
+ *@addr: a 16 bit unsigned number.
+ *
+ * sets the initial sequence number of a sending session.
+ *
+**/
+void rtp_session_set_seq_number(RtpSession *session, guint16 seq){
+ session->rtp.snd_seq=seq;
+}
+
+
+guint16 rtp_session_get_seq_number(RtpSession *session){
+ return session->rtp.snd_seq;
+}
+
+
+#ifdef USE_SENDMSG
+#define MAX_IOV 10
+static gint rtp_sendmsg(int sock,mblk_t *m, struct sockaddr *rem_addr, int addr_len){
+ int error;
+ struct msghdr msg;
+ struct iovec iov[MAX_IOV];
+ int iovlen;
+ for(iovlen=0; iovlen<MAX_IOV && m!=NULL; m=m->b_cont,iovlen++){
+ iov[iovlen].iov_base=m->b_rptr;
+ iov[iovlen].iov_len=m->b_wptr-m->b_rptr;
+ }
+ msg.msg_name=(void*)rem_addr;
+ msg.msg_namelen=addr_len;
+ msg.msg_iov=&iov[0];
+ msg.msg_iovlen=iovlen;
+ msg.msg_control=NULL;
+ msg.msg_controllen=0;
+ msg.msg_flags=0;
+
+ error=sendmsg(sock,&msg,0);
+ return error;
+}
+#endif
+
+static gint
+ortp_rtp_send (RtpSession * session, mblk_t * m)
+{
+ gint error;
+ int i;
+ rtp_header_t *hdr;
+
+ hdr = (rtp_header_t *) m->b_rptr;
+ /* perform host to network conversions */
+ hdr->ssrc = htonl (hdr->ssrc);
+ hdr->timestamp = htonl (hdr->timestamp);
+ hdr->seq_number = htons (hdr->seq_number);
+ for (i = 0; i < hdr->cc; i++)
+ hdr->csrc[i] = htonl (hdr->csrc[i]);
+
+#ifdef USE_SENDMSG
+ if (session->flags & RTP_SESSION_USING_EXT_SOCKETS){
+ error=rtp_sendmsg(session->rtp.socket,m,(struct sockaddr *)NULL,0);
+ }else {
+ error=rtp_sendmsg(session->rtp.socket,m,(struct sockaddr *) &session->rtp.rem_addr,
+ session->rtp.addrlen);
+ }
+#else
+ if (m->b_cont!=NULL){
+ mblk_t *newm=msgpullup(m,-1);
+ freemsg(m);
+ m=newm;
+ }
+ if (session->flags & RTP_SESSION_USING_EXT_SOCKETS){
+ error=send(session->rtp.socket, m->b_rptr, (m->b_wptr - m->b_rptr),0);
+ }else error = sendto (session->rtp.socket, m->b_rptr,
+ (m->b_wptr - m->b_rptr), 0,
+ (struct sockaddr *) &session->rtp.rem_addr,
+ session->rtp.addrlen);
+#endif
+ if (error < 0){
+ if (session->on_network_error.count>0){
+ rtp_signal_table_emit3(&session->on_network_error,(gpointer)"Error sending RTP packet",INT_TO_POINTER(getSocketErrorCode()));
+ }else g_warning ("Error sending rtp packet: %s ; socket=%i", getSocketError(), session->rtp.socket);
+ }
+ freemsg (m);
+ return error;
+}
+
+gint
+ortp_rtcp_send (RtpSession * session, mblk_t * m)
+{
+ gint error=0;
+ gboolean using_ext_socket=(session->flags & RTP_SESSION_USING_EXT_SOCKETS)!=0;
+ if ( (using_ext_socket && session->rtcp.socket>0 ) || session->rtcp.addrlen>0){
+
+#ifndef USE_SENDMSG
+ if (m->b_cont!=NULL){
+ mblk_t *newm=msgpullup(m,-1);
+ freemsg(m);
+ m=newm;
+ }
+#endif
+ if (using_ext_socket && session->rtcp.socket>0 ){
+#ifdef USE_SENDMSG
+ error=rtp_sendmsg(session->rtcp.socket,m,(struct sockaddr *)NULL,0);
+#else
+ error=send(session->rtcp.socket, m->b_rptr, (m->b_wptr - m->b_rptr),0);
+#endif
+ }else {
+#ifdef USE_SENDMSG
+ error=rtp_sendmsg(session->rtcp.socket,m,(struct sockaddr *) &session->rtcp.rem_addr,
+ session->rtcp.addrlen);
+#else
+ error = sendto (session->rtcp.socket, m->b_rptr,
+ (m->b_wptr - m->b_rptr), 0,
+ (struct sockaddr *) &session->rtcp.rem_addr,
+ session->rtcp.addrlen);
+#endif
+ }
+
+ if (error < 0){
+ if (session->on_network_error.count>0){
+ rtp_signal_table_emit3(&session->on_network_error,(gpointer)"Error sending RTCP packet",INT_TO_POINTER(getSocketErrorCode()));
+ }else g_warning ("Error sending rtcp packet: %s ; socket=%i", getSocketError(), session->rtcp.socket);
+ }
+ }else g_warning("Cannot send rtcp report because I don't know the remote address.");
+ freemsg (m);
+ return error;
+}
+
+
+/**
+ *rtp_session_set_ssrc:
+ *@session: a rtp session.
+ *@ssrc: an unsigned 32bit integer representing the synchronisation source identifier (SSRC).
+ *
+ * Sets the SSRC for the outgoing stream.
+ * If not done, a random ssrc is used.
+ *
+**/
+void
+rtp_session_set_ssrc (RtpSession * session, guint32 ssrc)
+{
+ session->send_ssrc = ssrc;
+}
+
+/* this function initialize all session parameter's that depend on the payload type */
+static void payload_type_changed(RtpSession *session, PayloadType *pt){
+ jitter_control_set_payload(&session->rtp.jittctl,pt);
+ session->rtp.rtcp_report_snt_interval=RTCP_DEFAULT_REPORT_INTERVAL*pt->clock_rate;
+ rtp_session_set_time_jump_limit(session,session->rtp.time_jump);
+}
+
+/**
+ *rtp_session_set_payload_type:
+ *@session: a rtp session
+ *@paytype: the payload type
+ *
+ * Sets the payload type of the rtp session. It decides of the payload types written in the
+ * of the rtp header for the outgoing stream, if the session is SENDRECV or SENDONLY.
+ * For the incoming stream, it sets the waited payload type. If that value does not match
+ * at any time this waited value, then the application can be informed by registering
+ * for the "payload_type_changed" signal, so that it can make the necessary changes
+ * on the downstream decoder that deals with the payload of the packets.
+ *
+ *Returns: 0 on success, -1 if the payload is not defined.
+**/
+
+int
+rtp_session_set_payload_type (RtpSession * session, int paytype)
+{
+ PayloadType *pt;
+ session->payload_type = paytype;
+ pt=rtp_profile_get_payload(session->profile,paytype);
+ if (pt!=NULL){
+ payload_type_changed(session,pt);
+ }
+ return 0;
+}
+
+int rtp_session_get_payload_type(RtpSession *session){
+ return session->payload_type;
+}
+
+
+/**
+ *rtp_session_set_payload_type_with_string:
+ *@session: a rtp session
+ *@paytype: the payload type
+ *
+ * Sets the payload type of the rtp session. It decides of the payload types written in the
+ * of the rtp header for the outgoing stream, if the session is SENDRECV or SENDONLY.
+ * Unlike #rtp_session_set_payload_type(), it takes as argument a string referencing the
+ * payload type (mime type).
+ * For the incoming stream, it sets the waited payload type. If that value does not match
+ * at any time this waited value, then the application can be informed by registering
+ * for the "payload_type_changed" signal, so that it can make the necessary changes
+ * on the downstream decoder that deals with the payload of the packets.
+ *
+ *Returns: 0 on success, -1 if the payload is not defined.
+**/
+
+int
+rtp_session_set_payload_type_with_string (RtpSession * session, const char * mime)
+{
+ int pt;
+ pt=rtp_profile_get_payload_number_from_mime(session->profile,mime);
+ if (pt<0) {
+ g_warning("%s is not a know mime string within the rtpsession's profile.",mime);
+ return -1;
+ }
+ rtp_session_set_payload_type(session,pt);
+ return 0;
+}
+
+
+/**
+ *rtp_session_create_packet:
+ *@session: a rtp session.
+ *@header_size: the rtp header size. For standart size (without extensions), it is #RTP_FIXED_HEADER_SIZE
+ *@payload :data to be copied into the rtp packet.
+ *@payload_size : size of data carried by the rtp packet.
+ *
+ * Allocates a new rtp packet. In the header, ssrc and payload_type according to the session's
+ * context. Timestamp and seq number are not set, there will be set when the packet is going to be
+ * sent with rtp_session_sendm_with_ts().
+ *
+ *Returns: a rtp packet in a mblk_t (message block) structure.
+**/
+mblk_t * rtp_session_create_packet(RtpSession *session,gint header_size, const char *payload, gint payload_size)
+{
+ mblk_t *mp;
+ gint msglen=header_size+payload_size;
+ rtp_header_t *rtp;
+
+ mp=allocb(msglen,BPRI_MED);
+ rtp=(rtp_header_t*)mp->b_rptr;
+ rtp->version = 2;
+ rtp->padbit = 0;
+ rtp->extbit = 0;
+ rtp->markbit= 0;
+ rtp->cc = 0;
+ rtp->paytype = session->payload_type;
+ rtp->ssrc = session->send_ssrc;
+ rtp->timestamp = 0; /* set later, when packet is sended */
+ rtp->seq_number = 0; /*set later, when packet is sended */
+ /*copy the payload */
+ mp->b_wptr+=header_size;
+ memcpy(mp->b_wptr,payload,payload_size);
+ mp->b_wptr+=payload_size;
+ return mp;
+}
+
+/**
+ *rtp_session_create_packet_with_data:
+ *@session: a rtp session.
+ *@payload : the data to be sent with this packet
+ *@payload_size : size of data
+ *@freefn : a function that will be called when the payload buffer is no more needed.
+ *
+ * Creates a new rtp packet using the given payload buffer (no copy). The header will be allocated separetely.
+ * In the header, ssrc and payload_type according to the session's
+ * context. Timestamp and seq number are not set, there will be set when the packet is going to be
+ * sent with rtp_session_sendm_with_ts().
+ * oRTP will send this packet using libc's sendmsg() (if this function is availlable!) so that there will be no
+ * packet concatenation involving copies to be done in user-space.
+ * @freefn can be NULL, in that case payload will be kept untouched.
+ *
+ *Returns: a rtp packet in a mblk_t (message block) structure.
+**/
+
+mblk_t * rtp_session_create_packet_with_data(RtpSession *session, char *payload, gint payload_size, void (*freefn)(void*))
+{
+ mblk_t *mp,*mpayload;
+ gint header_size=RTP_FIXED_HEADER_SIZE; /* revisit when support for csrc is done */
+ rtp_header_t *rtp;
+
+ mp=allocb(header_size,BPRI_MED);
+ rtp=(rtp_header_t*)mp->b_rptr;
+ rtp->version = 2;
+ rtp->padbit = 0;
+ rtp->extbit = 0;
+ rtp->markbit= 0;
+ rtp->cc = 0;
+ rtp->paytype = session->payload_type;
+ rtp->ssrc = session->send_ssrc;
+ rtp->timestamp = 0; /* set later, when packet is sended */
+ rtp->seq_number = 0; /*set later, when packet is sended */
+ mp->b_wptr+=header_size;
+ /* create a mblk_t around the user supplied payload buffer */
+ mpayload=allocb_with_buf(payload,payload_size,BPRI_MED,freefn);
+ mpayload->b_wptr+=payload_size;
+ /* link it with the header */
+ mp->b_cont=mpayload;
+ return mp;
+}
+
+
+/**
+ *rtp_session_create_packet_in_place:
+ *@session: a rtp session.
+ *@buffer: a buffer that contains first just enough place to write a RTP header, then the data to send.
+ *@size : the size of the buffer
+ *@freefn : a function that will be called once the buffer is no more needed (the data has been sent).
+ *
+ * Creates a new rtp packet using the buffer given in arguments (no copy).
+ * In the header, ssrc and payload_type according to the session's
+ * context. Timestamp and seq number are not set, there will be set when the packet is going to be
+ * sent with rtp_session_sendm_with_ts().
+ * @freefn can be NULL, in that case payload will be kept untouched.
+ *
+ *Returns: a rtp packet in a mblk_t (message block) structure.
+**/
+mblk_t * rtp_session_create_packet_in_place(RtpSession *session,char *buffer, gint size, void (*freefn)(void*) )
+{
+ mblk_t *mp;
+ rtp_header_t *rtp;
+
+ mp=allocb_with_buf(buffer,size,BPRI_MED,freefn);
+
+ rtp=(rtp_header_t*)mp->b_rptr;
+ rtp->version = 2;
+ rtp->padbit = 0;
+ rtp->extbit = 0;
+ rtp->markbit= 0;
+ rtp->cc = 0;
+ rtp->paytype = session->payload_type;
+ rtp->ssrc = session->send_ssrc;
+ rtp->timestamp = 0; /* set later, when packet is sended */
+ rtp->seq_number = 0; /*set later, when packet is sended */
+ return mp;
+}
+
+
+/**
+ *rtp_session_sendm_with_ts:
+ *@session : a rtp session.
+ *@mp : a rtp packet presented as a mblk_t.
+ *@timestamp: the timestamp of the data to be sent. Refer to the rfc to know what it is.
+ *
+ * Send the rtp datagram @mp to the destination set by rtp_session_set_remote_addr()
+ * with timestamp @timestamp. For audio data, the timestamp is the number
+ * of the first sample resulting of the data transmitted. See rfc1889 for details.
+ * The packet (@mp) is freed once it is sended.
+ *
+ *Returns: the number of bytes sent over the network.
+**/
+gint
+rtp_session_sendm_with_ts (RtpSession * session, mblk_t *mp, guint32 timestamp)
+{
+ rtp_header_t *rtp;
+ guint32 packet_time;
+ gint error = 0;
+ gint payloadsize;
+ RtpScheduler *sched=session->sched;
+ RtpStream *stream=&session->rtp;
+
+ if (session->flags & RTP_SESSION_SEND_NOT_STARTED)
+ {
+ session->rtp.snd_ts_offset = timestamp;
+ if (session->flags & RTP_SESSION_SCHEDULED)
+ {
+ session->rtp.snd_time_offset = sched->time_;
+ }
+ rtp_session_unset_flag (session,RTP_SESSION_SEND_NOT_STARTED);
+ }
+ /* if we are in blocking mode, then suspend the process until the scheduler it's time to send the
+ * next packet */
+ /* if the timestamp of the packet queued is older than current time, then you we must
+ * not block */
+ if (session->flags & RTP_SESSION_SCHEDULED)
+ {
+ packet_time =
+ rtp_session_ts_to_time (session,
+ timestamp -
+ session->rtp.snd_ts_offset) +
+ session->rtp.snd_time_offset;
+ /*g_message("rtp_session_send_with_ts: packet_time=%i time=%i",packet_time,sched->time_);*/
+ wait_point_lock(&session->send_wp);
+ if (TIME_IS_STRICTLY_NEWER_THAN (packet_time, sched->time_))
+ {
+ wait_point_wakeup_at(&session->send_wp,packet_time,(session->flags & RTP_SESSION_BLOCKING_MODE)!=0);
+ session_set_clr(&sched->w_sessions,session); /* the session has written */
+ }
+ else session_set_set(&sched->w_sessions,session); /*to indicate select to return immediately */
+ wait_point_unlock(&session->send_wp);
+ }
+
+
+ rtp=(rtp_header_t*)mp->b_rptr;
+
+ payloadsize = msgdsize(mp) - RTP_FIXED_HEADER_SIZE - (rtp->cc*sizeof(guint32));
+ rtp_session_lock (session);
+
+ /* set a seq number */
+ rtp->seq_number=session->rtp.snd_seq;
+ rtp->timestamp=timestamp;
+ session->rtp.snd_seq++;
+ session->rtp.snd_last_ts = timestamp;
+
+
+ ortp_global_stats.sent += payloadsize;
+ stream->stats.sent += payloadsize;
+ ortp_global_stats.packet_sent++;
+ stream->stats.packet_sent++;
+
+ error = ortp_rtp_send (session, mp);
+ rtp_session_rtcp_process(session);
+ rtp_session_unlock (session);
+
+ return error;
+}
+
+
+/**
+ *rtp_session_send_with_ts:
+ *@session: a rtp session.
+ *@buffer: a buffer containing the data to be sent in a rtp packet.
+ *@len: the length of the data buffer, in bytes.
+ *@userts: the timestamp of the data to be sent. Refer to the rfc to know what it is.
+ *
+ * Send a rtp datagram to the destination set by rtp_session_set_remote_addr() containing
+ * the data from @buffer with timestamp @userts. This is a high level function that uses
+ * rtp_session_create_packet() and rtp_session_sendm_with_ts() to send the data.
+ *
+ *
+ *Returns: the number of bytes sent over the network.
+**/
+gint
+rtp_session_send_with_ts (RtpSession * session, const gchar * buffer, gint len,
+ guint32 userts)
+{
+ mblk_t *m;
+ int err;
+#ifdef USE_SENDMSG
+ m=rtp_session_create_packet_with_data(session,(gchar*)buffer,len,NULL);
+#else
+ m = rtp_session_create_packet(session,RTP_FIXED_HEADER_SIZE,(gchar*)buffer,len);
+#endif
+ err=rtp_session_sendm_with_ts(session,m,userts);
+ return err;
+}
+
+
+static gint
+rtp_recv (RtpSession * session, guint32 user_ts)
+{
+ gint error;
+ struct sockaddr remaddr;
+ socklen_t addrlen = sizeof (remaddr);
+ char *p;
+ mblk_t *mp;
+ RtpStream *stream=&session->rtp;
+
+ if (session->rtp.socket<1) return -1; /*session has no sockets for the moment*/
+
+
+ while (1)
+ {
+ if (session->rtp.cached_mp==NULL)
+ session->rtp.cached_mp = allocb (session->max_buf_size, 0);
+ mp=session->rtp.cached_mp;
+ if (session->flags & RTP_SESSION_USING_EXT_SOCKETS){
+ error=recv(session->rtp.socket,mp->b_wptr,session->max_buf_size,0);
+ }else error = recvfrom (session->rtp.socket, mp->b_wptr,
+ session->max_buf_size, 0,
+ (struct sockaddr *) &remaddr,
+ &addrlen);
+ if (error > 0)
+ {
+ if (error<RTP_FIXED_HEADER_SIZE){
+ g_warning("Packet too small to be a rtp packet (%i)!",error);
+ stream->stats.bad++;
+ ortp_global_stats.bad++;
+ /* don't free, it will be reused next time */
+ }else{
+ /* resize the memory allocated to fit the udp message */
+
+ p = g_realloc (mp->b_wptr, error);
+ if (p != mp->b_wptr)
+ ortp_debug("The recv area has moved during reallocation.");
+ mp->b_datap->db_base = mp->b_rptr =
+ mp->b_wptr = p;
+ mp->b_wptr += error;
+ mp->b_datap->db_lim = mp->b_wptr;
+ /* then parse the message and put on queue */
+ rtp_parse (session, mp, user_ts + session->rtp.hwrcv_diff_ts);
+ session->rtp.cached_mp=NULL;
+ }
+ }
+ else
+ {
+ if (error == 0)
+ {
+ g_warning
+ ("rtp_recv: strange... recv() returned zero.");
+ }
+ else if (errno!=EWOULDBLOCK && errno!=EAGAIN)
+ {
+ if (session->on_network_error.count>0){
+ rtp_signal_table_emit3(&session->on_network_error,(gpointer)"Error receiving RTP packet",INT_TO_POINTER(getSocketErrorCode()));
+ }else g_warning("Error receiving RTP packet: %s.",getSocketError());
+ }
+ /* don't free the cached_mp, it will be reused next time */
+ return -1; /* avoids an infinite loop ! */
+ }
+ }
+ return error;
+}
+
+extern void rtcp_parse(RtpSession *session, mblk_t *mp);
+
+static gint
+rtcp_recv (RtpSession * session)
+{
+ gint error;
+ struct sockaddr remaddr;
+ socklen_t addrlen=0;
+ char *p;
+ mblk_t *mp;
+
+
+ if (session->rtcp.socket<1) return -1; /*session has no rtcp sockets for the moment*/
+
+
+ while (1)
+ {
+ if (session->rtcp.cached_mp==NULL)
+ session->rtcp.cached_mp = allocb (RTCP_MAX_RECV_BUFSIZE, 0);
+
+ mp=session->rtcp.cached_mp;
+ if (session->flags & RTP_SESSION_USING_EXT_SOCKETS){
+ error=recv(session->rtcp.socket,mp->b_wptr,RTCP_MAX_RECV_BUFSIZE,0);
+ }else {
+ addrlen=sizeof (remaddr);
+ error=recvfrom (session->rtcp.socket, mp->b_wptr,
+ RTCP_MAX_RECV_BUFSIZE, 0,
+ (struct sockaddr *) &remaddr,
+ &addrlen);
+ }
+ if (error > 0)
+ {
+ /* resize the memory allocated to fit the udp message */
+
+ p = g_realloc (mp->b_wptr, error);
+ if (p != mp->b_wptr)
+ ortp_debug("The recv area has moved during reallocation.");
+ mp->b_datap->db_base = mp->b_rptr =
+ mp->b_wptr = p;
+ mp->b_wptr += error;
+ mp->b_datap->db_lim = mp->b_wptr;
+ /* then parse the message */
+ rtcp_parse (session, mp);
+ freemsg(mp);
+ session->rtcp.cached_mp=NULL;
+ if (addrlen>0){
+ /* store the sender rtcp address to send him receiver reports */
+ memcpy(&session->rtcp.rem_addr,&remaddr,addrlen);
+ }
+ }
+ else
+ {
+ if (error == 0)
+ {
+ g_warning
+ ("rtcp_recv: strange... recv() returned zero.");
+ }
+ else if (errno!=EWOULDBLOCK && errno!=EAGAIN)
+ {
+ if (session->on_network_error.count>0){
+ rtp_signal_table_emit3(&session->on_network_error,(gpointer)"Error receiving RTCP packet",INT_TO_POINTER(getSocketErrorCode()));
+ }else g_warning("Error receiving RTCP packet: %s.",getSocketError());
+ }
+ /* don't free the cached_mp, it will be reused next time */
+ return -1; /* avoids an infinite loop ! */
+ }
+ }
+ return error;
+}
+
+
+static void payload_type_changed_incoming(RtpSession *session, int paytype){
+ /* check if we support this payload type */
+ PayloadType *pt=rtp_profile_get_payload(session->profile,paytype);
+ if (pt!=0){
+ g_message ("rtp_parse: payload type changed to %i(%s) !",
+ paytype,pt->mime_type);
+ session->payload_type = paytype;
+ payload_type_changed(session,pt);
+ rtp_signal_table_emit (&session->on_payload_type_changed);
+ }else{
+ g_warning("Receiving packet with unknown payload type %i.",paytype);
+ }
+}
+
+
+/**
+ *rtp_session_recvm_with_ts:
+ *@session: a rtp session.
+ *@user_ts: a timestamp.
+ *
+ * Try to get a rtp packet presented as a mblk_t structure from the rtp session.
+ * The @user_ts parameter is relative to the first timestamp of the incoming stream. In other
+ * words, the application does not have to know the first timestamp of the stream, it can
+ * simply call for the first time this function with @user_ts=0, and then incrementing it
+ * as it want. The RtpSession takes care of synchronisation between the stream timestamp
+ * and the user timestamp given here.
+ *
+ *Returns: a rtp packet presented as a mblk_t.
+**/
+
+mblk_t *
+rtp_session_recvm_with_ts (RtpSession * session, guint32 user_ts)
+{
+ mblk_t *mp = NULL;
+ rtp_header_t *rtp;
+ guint32 ts;
+ guint32 packet_time;
+ RtpScheduler *sched=session->sched;
+ RtpStream *stream=&session->rtp;
+ gint rejected=0;
+
+ /* if we are scheduled, remember the scheduler time at which the application has
+ * asked for its first timestamp */
+
+ if (session->flags & RTP_SESSION_RECV_NOT_STARTED)
+ {
+
+ session->rtp.rcv_query_ts_offset = user_ts;
+ if (session->flags & RTP_SESSION_SCHEDULED)
+ {
+ session->rtp.rcv_time_offset = sched->time_;
+ //g_message("setting snd_time_offset=%i",session->rtp.snd_time_offset);
+ }
+ rtp_session_unset_flag (session,RTP_SESSION_RECV_NOT_STARTED);
+ }
+ session->rtp.rcv_last_app_ts = user_ts;
+ rtp_recv (session, user_ts);
+ rtcp_recv(session);
+ /* check for telephone event first */
+ /* first lock the session */
+ rtp_session_lock (session);
+ mp=getq(&session->rtp.tev_rq);
+ if (mp!=NULL){
+ rtp_signal_table_emit2(&session->on_telephone_event_packet,(gpointer)mp);
+ if (session->on_telephone_event.count>0){
+ rtp_session_check_telephone_events(session,mp);
+ }
+ freemsg(mp);
+ mp=NULL;
+ }
+
+ /* then now try to return a media packet, if possible */
+ /* first condition: if the session is starting, don't return anything
+ * until the queue size reaches jitt_comp */
+
+ if (session->flags & RTP_SESSION_RECV_SYNC)
+ {
+ rtp_header_t *oldest, *newest;
+ queue_t *q = &session->rtp.rq;
+ if (qempty(q))
+ {
+ ortp_debug ("Queue is empty.");
+ goto end;
+ }
+ oldest = (rtp_header_t *) qfirst(q)->b_rptr;
+ newest = (rtp_header_t *) qlast(q)->b_rptr;
+ if ((guint32) (newest->timestamp - oldest->timestamp) <
+ session->rtp.jittctl.jitt_comp_ts)
+ {
+ ortp_debug("Not enough packet bufferised.");
+ goto end;
+ }
+ /* enough packet bufferised */
+ mp = getq (&session->rtp.rq);
+ rtp = (rtp_header_t *) mp->b_rptr;
+ session->rtp.rcv_ts_offset = rtp->timestamp;
+ /* remember the timestamp offset between the stream timestamp (random)
+ * and the user timestamp, that very often starts at zero */
+ session->rtp.rcv_diff_ts = rtp->timestamp - user_ts;
+ /* remember the difference between the last received on the socket timestamp and the user timestamp */
+ session->rtp.hwrcv_diff_ts=session->rtp.rcv_diff_ts + session->rtp.jittctl.jitt_comp_ts;
+ session->rtp.rcv_last_ret_ts = user_ts; /* just to have an init value */
+ session->rtp.rcv_last_ts = rtp->timestamp;
+ session->recv_ssrc = rtp->ssrc;
+ /* delete the recv synchronisation flag */
+ rtp_session_unset_flag (session, RTP_SESSION_RECV_SYNC);
+ ortp_debug("Returning FIRST packet with ts=%i, hwrcv_diff_ts=%i, rcv_diff_ts=%i", rtp->timestamp,
+ session->rtp.hwrcv_diff_ts,session->rtp.rcv_diff_ts);
+
+ goto end;
+ }
+ /* else this the normal case */
+ /*calculate the stream timestamp from the user timestamp */
+ ts = user_ts + session->rtp.rcv_diff_ts;
+ session->rtp.rcv_last_ts = ts;
+ mp = rtp_getq (&session->rtp.rq, ts,&rejected);
+
+ stream->stats.skipped+=rejected;
+ ortp_global_stats.skipped+=rejected;
+
+ /* perhaps we can now make some checks to see if a resynchronization is needed */
+ /* TODO */
+ goto end;
+
+ end:
+ if (mp != NULL)
+ {
+ int msgsize = msgdsize (mp); /* evaluate how much bytes (including header) is received by app */
+ guint32 packet_ts;
+ ortp_global_stats.recv += msgsize;
+ stream->stats.recv += msgsize;
+ rtp = (rtp_header_t *) mp->b_rptr;
+ packet_ts=rtp->timestamp;
+ ortp_debug("Returning mp with ts=%i", packet_ts);
+ /* check for payload type changes */
+ if (session->payload_type != rtp->paytype)
+ {
+ payload_type_changed_incoming(session, rtp->paytype);
+ }
+ /* patch the packet so that it has a timestamp compensated by the
+ adaptive jitter buffer mechanism */
+ if (session->rtp.jittctl.adaptive){
+ rtp->timestamp-=session->rtp.jittctl.corrective_slide;
+ /*printf("Returned packet has timestamp %u, with clock slide compensated it is %u\n",packet_ts,rtp->timestamp);*/
+ }
+ }
+ else
+ {
+ ortp_debug ("No mp for timestamp queried");
+ stream->stats.unavaillable++;
+ ortp_global_stats.unavaillable++;
+ }
+ rtp_session_rtcp_process(session);
+ rtp_session_unlock (session);
+
+ if (session->flags & RTP_SESSION_SCHEDULED)
+ {
+ /* if we are in blocking mode, then suspend the calling process until timestamp
+ * wanted expires */
+ /* but we must not block the process if the timestamp wanted by the application is older
+ * than current time */
+ packet_time =
+ rtp_session_ts_to_time (session,
+ user_ts -
+ session->rtp.rcv_query_ts_offset) +
+ session->rtp.rcv_time_offset;
+ ortp_debug ("rtp_session_recvm_with_ts: packet_time=%i, time=%i",packet_time, sched->time_);
+ wait_point_lock(&session->recv_wp);
+ if (TIME_IS_STRICTLY_NEWER_THAN (packet_time, sched->time_))
+ {
+ wait_point_wakeup_at(&session->recv_wp,packet_time, (session->flags & RTP_SESSION_BLOCKING_MODE)!=0);
+ session_set_clr(&sched->r_sessions,session);
+ }
+ else session_set_set(&sched->r_sessions,session); /*to unblock _select() immediately */
+ wait_point_unlock(&session->recv_wp);
+ }
+ return mp;
+}
+
+
+gint msg_to_buf (mblk_t * mp, char *buffer, gint len)
+{
+ gint rlen = len;
+ mblk_t *m, *mprev;
+ gint mlen;
+ m = mp->b_cont;
+ mprev = mp;
+ while (m != NULL)
+ {
+ mlen = m->b_wptr - m->b_rptr;
+ if (mlen <= rlen)
+ {
+ mblk_t *consumed = m;
+ memcpy (buffer, m->b_rptr, mlen);
+ /* go to next mblk_t */
+ mprev->b_cont = m->b_cont;
+ m = m->b_cont;
+ consumed->b_cont = NULL;
+ freeb (consumed);
+ buffer += mlen;
+ rlen -= mlen;
+ }
+ else
+ { /*if mlen>rlen */
+ memcpy (buffer, m->b_rptr, rlen);
+ m->b_rptr += rlen;
+ return len;
+ }
+ }
+ return len - rlen;
+}
+
+/**
+ *rtp_session_recv_with_ts:
+ *@session: a rtp session.
+ *@buffer: a user supplied buffer to write the data.
+ *@len: the length in bytes of the user supplied buffer.
+ *@time: the timestamp wanted.
+ *@have_more: the address of an integer to indicate if more data is availlable for the given timestamp.
+ *
+ * Tries to read the bytes of the incoming rtp stream related to timestamp @time. In case
+ * where the user supplied buffer @buffer is not large enough to get all the data
+ * related to timestamp @time, then *( @have_more) is set to 1 to indicate that the application
+ * should recall the function with the same timestamp to get more data.
+ *
+ * When the rtp session is scheduled (see rtp_session_set_scheduling_mode() ), and the
+ * blocking mode is on (see rtp_session_set_blocking_mode() ), then the calling thread
+ * is suspended until the timestamp given as argument expires, whatever a received packet
+ * fits the query or not.
+ *
+ * Important note: it is clear that the application cannot know the timestamp of the first
+ * packet of the incoming stream, because it can be random. The @time timestamp given to the
+ * function is used relatively to first timestamp of the stream. In simple words, 0 is a good
+ * value to start calling this function.
+ *
+ * This function internally calls rtp_session_recvm_with_ts() to get a rtp packet. The content
+ * of this packet is then copied into the user supplied buffer in an intelligent manner:
+ * the function takes care of the size of the supplied buffer and the timestamp given in
+ * argument. Using this function it is possible to read continous audio data (e.g. pcma,pcmu...)
+ * with for example a standart buffer of size of 160 with timestamp incrementing by 160 while the incoming
+ * stream has a different packet size.
+ *
+ *Returns: if a packet was availlable with the corresponding timestamp supplied in argument
+ * then the number of bytes written in the user supplied buffer is returned. If no packets
+ * are availlable, either because the sender has not started to send the stream, or either
+ * because silence packet are not transmitted, or either because the packet was lost during
+ * network transport, then the function returns zero.
+**/
+gint rtp_session_recv_with_ts (RtpSession * session, gchar * buffer,
+ gint len, guint32 time, gint * have_more)
+{
+ mblk_t *mp;
+ gint rlen = len;
+ gint wlen, mlen;
+ guint32 ts_int = 0; /*the length of the data returned in the user supplied buffer, in TIMESTAMP UNIT */
+ PayloadType *payload;
+ RtpStream *stream=&session->rtp;
+
+ *have_more = 0;
+
+ mp = rtp_session_recvm_with_ts (session, time);
+ payload =rtp_profile_get_payload (session->profile,
+ session->payload_type);
+ if (payload==NULL){
+ g_warning("rtp_session_recv_with_ts: unable to recv an unsupported payload.");
+ if (mp!=NULL) freemsg(mp);
+ return -1;
+ }
+ if (!(session->flags & RTP_SESSION_RECV_SYNC))
+ {
+ //ortp_debug("time=%i rcv_last_ret_ts=%i",time,session->rtp.rcv_last_ret_ts);
+ if (RTP_TIMESTAMP_IS_STRICTLY_NEWER_THAN
+ (time, session->rtp.rcv_last_ret_ts))
+ {
+ /* the user has missed some data previously, so we are going to give him now. */
+ /* we must tell him to call the function once again with the same timestamp
+ * by setting *have_more=1 */
+ *have_more = 1;
+ }
+ if (payload->type == PAYLOAD_AUDIO_CONTINUOUS)
+ {
+ ts_int = (len * payload->bits_per_sample) >> 3;
+ session->rtp.rcv_last_ret_ts += ts_int;
+ //ortp_debug("ts_int=%i",ts_int);
+ }
+ else
+ ts_int = 0;
+ }
+ else return 0;
+
+ /* try to fill the user buffer */
+ while (1)
+ {
+
+ if (mp != NULL)
+ {
+ mlen = msgdsize (mp->b_cont);
+ wlen = msg_to_buf (mp, buffer, rlen);
+ buffer += wlen;
+ rlen -= wlen;
+ ortp_debug("mlen=%i wlen=%i rlen=%i", mlen, wlen,
+ rlen);
+ /* do we fill all the buffer ? */
+ if (rlen > 0)
+ {
+ /* we did not fill all the buffer */
+ freemsg (mp);
+ /* if we have continuous audio, try to get other packets to fill the buffer,
+ * ie continue the loop */
+ //ortp_debug("User buffer not filled entirely");
+ if (ts_int > 0)
+ {
+ time = session->rtp.rcv_last_ret_ts;
+ ortp_debug("Need more: will ask for %i.",
+ time);
+ }
+ else
+ return len - rlen;
+ }
+ else if (mlen > wlen)
+ {
+ int unread =
+ mlen - wlen + (mp->b_wptr -
+ mp->b_rptr);
+ /* not enough space in the user supplied buffer */
+ /* we re-enqueue the msg with its updated read pointers for next time */
+ ortp_debug ("Re-enqueuing packet.");
+ rtp_session_lock (session);
+ rtp_putq (&session->rtp.rq, mp);
+ rtp_session_unlock (session);
+ /* quite ugly: I change the stats ... */
+ ortp_global_stats.recv -= unread;
+ stream->stats.recv -= unread;
+ return len;
+ }
+ else
+ {
+ /* the entire packet was written to the user buffer */
+ freemsg (mp);
+ return len;
+ }
+ }
+ else
+ {
+ /* fill with a zero pattern (silence) */
+ if (payload->pattern_length != 0)
+ {
+ int i = 0, j = 0;
+ while (i < rlen)
+ {
+ buffer[i] = payload->zero_pattern[j];
+ i++;
+ j++;
+ if (j <= payload->pattern_length)
+ j = 0;
+ }
+ return len;
+ }
+ *have_more = 0;
+ return 0;
+ }
+ mp = rtp_session_recvm_with_ts (session, time);
+ payload = rtp_profile_get_payload (session->profile,
+ session->payload_type);
+ if (payload==NULL){
+ g_warning("rtp_session_recv_with_ts: unable to recv an unsupported payload.");
+ if (mp!=NULL) freemsg(mp);
+ return -1;
+ }
+ }
+ return -1;
+}
+/**
+ *rtp_session_get_current_send_ts:
+ *@session: a rtp session.
+ *
+ * When the rtp session is scheduled and has started to send packets, this function
+ * computes the timestamp that matches to the present time. Using this function can be
+ * usefull when sending discontinuous streams. Some time can be elapsed between the end
+ * of a stream burst and the begin of a new stream burst, and the application may be not
+ * not aware of this elapsed time. In order to get a valid (current) timestamp to pass to
+ * #rtp_session_send_with_ts() or #rtp_session_sendm_with_ts(), the application may
+ * use rtp_session_get_current_send_ts().
+ *
+ *Returns: the current send timestamp for the rtp session.
+**/
+guint32 rtp_session_get_current_send_ts(RtpSession *session)
+{
+ guint32 userts;
+ guint32 session_time;
+ RtpScheduler *sched=session->sched;
+ PayloadType *payload;
+ g_return_val_if_fail (session->payload_type<128, 0);
+ payload=rtp_profile_get_payload(session->profile,session->payload_type);
+ g_return_val_if_fail(payload!=NULL, 0);
+ if ( (session->flags & RTP_SESSION_SCHEDULED)==0 ){
+ g_warning("can't guess current timestamp because session is not scheduled.");
+ return 0;
+ }
+ session_time=sched->time_-session->rtp.snd_time_offset;
+ userts= (guint32)( ( (gdouble)(session_time) * (gdouble) payload->clock_rate )/ 1000.0)
+ + session->rtp.snd_ts_offset;
+ return userts;
+}
+
+/**
+ *rtp_session_get_current_recv_ts:
+ *@session: a rtp session.
+ *
+ * Same thing as rtp_session_get_current_send_ts() except that it's for an incoming stream.
+ * Works only on scheduled mode.
+ *
+ * Returns: the theoritical that would have to be receive now.
+ *
+**/
+guint32 rtp_session_get_current_recv_ts(RtpSession *session){
+ guint32 userts;
+ guint32 session_time;
+ RtpScheduler *sched=ortp_get_scheduler();
+ PayloadType *payload;
+ g_return_val_if_fail (session->payload_type<128, 0);
+ payload=rtp_profile_get_payload(session->profile,session->payload_type);
+ g_return_val_if_fail(payload!=NULL, 0);
+ if ( (session->flags & RTP_SESSION_SCHEDULED)==0 ){
+ g_warning("can't guess current timestamp because session is not scheduled.");
+ return 0;
+ }
+ session_time=sched->time_-session->rtp.rcv_time_offset;
+ userts= (guint32)( ( (gdouble)(session_time) * (gdouble) payload->clock_rate )/ 1000.0)
+ + session->rtp.rcv_ts_offset;
+ return userts;
+}
+
+/**
+ *rtp_session_set_time_jump_limit:
+ *@session: the rtp session
+ *@ts_step: a time interval in miliseconds
+ *
+ * oRTP has the possibility to inform the application through a callback registered
+ * with rtp_session_signal_connect about crazy incoming RTP stream that jumps from
+ * a timestamp N to N+<some crazy value>. This lets the opportunity for the application
+ * to reset the session in order to resynchronize, or any other action like stopping the call
+ * and reporting an error.
+**/
+void rtp_session_set_time_jump_limit(RtpSession *session, gint milisecs){
+ guint32 ts;
+ session->rtp.time_jump=milisecs;
+ ts=rtp_session_time_to_ts(session,milisecs);
+ if (ts==0) session->rtp.ts_jump=1<<31; /* do not detect ts jump */
+ else session->rtp.ts_jump=ts;
+}
+
+void rtp_session_uninit (RtpSession * session)
+{
+ /* first of all remove the session from the scheduler */
+ if (session->flags & RTP_SESSION_SCHEDULED)
+ {
+ rtp_scheduler_remove_session (session->sched,session);
+ }
+ /*flush all queues */
+ flushq (&session->rtp.rq, FLUSHALL);
+
+ /* close sockets */
+ close_socket (session->rtp.socket);
+ close_socket (session->rtcp.socket);
+
+ wait_point_uninit(&session->send_wp);
+ wait_point_uninit(&session->recv_wp);
+ g_mutex_free (session->lock);
+ session->lock=NULL;
+ if (session->current_tev!=NULL) freemsg(session->current_tev);
+ if (session->rtp.cached_mp!=NULL) freemsg(session->rtp.cached_mp);
+ if (session->rtcp.cached_mp!=NULL) freemsg(session->rtcp.cached_mp);
+ if (session->sd!=NULL) freemsg(session->sd);
+}
+
+/**
+ *rtp_session_reset:
+ *@session: a rtp session.
+ *
+ * Reset the session: local and remote addresses are kept unchanged but the internal
+ * queue for ordering and buffering packets is flushed, the session is ready to be
+ * re-synchronised to another incoming stream.
+ *
+**/
+void rtp_session_reset (RtpSession * session)
+{
+
+ if (session->flags & RTP_SESSION_SCHEDULED) rtp_session_lock (session);
+
+ flushq (&session->rtp.rq, FLUSHALL);
+ rtp_session_set_flag (session, RTP_SESSION_RECV_SYNC);
+ rtp_session_set_flag (session, RTP_SESSION_SEND_SYNC);
+ rtp_session_set_flag (session, RTP_SESSION_RECV_NOT_STARTED);
+ rtp_session_set_flag (session, RTP_SESSION_SEND_NOT_STARTED);
+ //session->ssrc=0;
+ session->rtp.snd_time_offset = 0;
+ session->rtp.snd_ts_offset = 0;
+ session->rtp.snd_rand_offset = 0;
+ session->rtp.snd_last_ts = 0;
+ session->rtp.rcv_time_offset = 0;
+ session->rtp.rcv_ts_offset = 0;
+ session->rtp.rcv_query_ts_offset = 0;
+ session->rtp.rcv_diff_ts = 0;
+ session->rtp.rcv_ts = 0;
+ session->rtp.rcv_last_ts = 0;
+ session->rtp.rcv_last_app_ts = 0;
+ session->rtp.hwrcv_extseq.one = 0;
+ session->rtp.hwrcv_since_last_SR=0;
+ session->rtp.snd_seq = 0;
+ rtp_stats_reset(&session->rtp.stats);
+ jitter_control_init(&session->rtp.jittctl,-1,NULL);
+
+ if (session->flags & RTP_SESSION_SCHEDULED) rtp_session_unlock (session);
+
+}
+
+/**
+ *rtp_session_destroy:
+ *@session: a rtp session.
+ *
+ * Destroys a rtp session.
+ *
+**/
+void rtp_session_destroy (RtpSession * session)
+{
+ rtp_session_uninit (session);
+ g_free (session);
+}
+
+guint32 rtp_session_time_to_ts(RtpSession *session, gint time){
+ PayloadType *payload;
+ g_return_val_if_fail (session->payload_type < 127, 0);
+ payload =
+ rtp_profile_get_payload (session->profile,
+ session->payload_type);
+ if (payload == NULL)
+ {
+ g_warning
+ ("rtp_session_ts_to_t: use of unsupported payload type.");
+ return 0;
+ }
+ /* the return value is in milisecond */
+ return (double)payload->clock_rate*(double)time/1000.0;
+}
+
+/* function used by the scheduler only:*/
+guint32 rtp_session_ts_to_time (RtpSession * session, guint32 timestamp)
+{
+ PayloadType *payload;
+ g_return_val_if_fail (session->payload_type < 127, 0);
+ payload =
+ rtp_profile_get_payload (session->profile,
+ session->payload_type);
+ if (payload == NULL)
+ {
+ g_warning
+ ("rtp_session_ts_to_t: use of unsupported payload type.");
+ return 0;
+ }
+ /* the return value is in milisecond */
+ return (guint32) (1000.0 *
+ ((double) timestamp /
+ (double) payload->clock_rate));
+}
+
+
+/* time is the number of miliseconds elapsed since the start of the scheduler */
+void rtp_session_process (RtpSession * session, guint32 time, RtpScheduler *sched)
+{
+ wait_point_lock(&session->send_wp);
+ if (wait_point_check(&session->send_wp,time)){
+ session_set_set(&sched->w_sessions,session);
+ wait_point_wakeup(&session->send_wp);
+ }
+ wait_point_unlock(&session->send_wp);
+
+ wait_point_lock(&session->recv_wp);
+ if (wait_point_check(&session->recv_wp,time)){
+ session_set_set(&sched->r_sessions,session);
+ wait_point_wakeup(&session->recv_wp);
+ }
+ wait_point_unlock(&session->recv_wp);
+}
+
+
+void rtp_session_make_time_distorsion(RtpSession *session, gint milisec)
+{
+ session->rtp.snd_time_offset+=milisec;
+}
+
+
+/* packet api */
+
+void rtp_add_csrc(mblk_t *mp, guint32 csrc)
+{
+ rtp_header_t *hdr=(rtp_header_t*)mp->b_rptr;
+ hdr->csrc[hdr->cc]=csrc;
+ hdr->cc++;
+}
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtpsession.h b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtpsession.h
new file mode 100644
index 00000000..e7702000
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtpsession.h
@@ -0,0 +1,287 @@
+ /*
+ The oRTP library is an RTP (Realtime Transport Protocol - rfc1889) stack.
+ Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef RTPSESSION_H
+#define RTPSESSION_H
+
+
+#include <rtpport.h>
+#include <rtp.h>
+#include <payloadtype.h>
+#include <sessionset.h>
+#include <rtcp.h>
+#include <str_utils.h>
+#include <rtpsignaltable.h>
+
+#include <stdio.h>
+
+
+#ifndef _WIN32
+# include <sys/types.h>
+# include <sys/socket.h>
+# include <errno.h>
+# include <netinet/in.h>
+# ifdef _XOPEN_SOURCE_EXTENDED
+# include <arpa/inet.h>
+# endif
+# include <unistd.h>
+# include <sys/time.h>
+#else
+# include <winsock2.h>
+#endif /* _WIN32 */
+
+
+
+typedef enum {
+ RTP_SESSION_RECVONLY,
+ RTP_SESSION_SENDONLY,
+ RTP_SESSION_SENDRECV
+} RtpSessionMode;
+
+
+
+typedef enum {
+ RTP_SESSION_RECV_SYNC=1, /* the rtp session is synchronising in the incoming stream */
+ RTP_SESSION_SEND_SYNC=1<<1, /* the rtp session is synchronising in the outgoing stream */
+ RTP_SESSION_SCHEDULED=1<<2, /* the rtp session has to be scheduled */
+ RTP_SESSION_BLOCKING_MODE=1<<3, /* in blocking mode */
+ RTP_SESSION_RECV_NOT_STARTED=1<<4, /* the application has not started to try to recv */
+ RTP_SESSION_SEND_NOT_STARTED=1<<5, /* the application has not started to send something */
+ RTP_SESSION_IN_SCHEDULER=1<<6, /* the rtp session is in the scheduler list */
+ RTP_SESSION_USING_EXT_SOCKETS=1<<7 /* the session is using externaly supplied sockets */
+}RtpSessionFlags;
+
+
+typedef struct _JitterControl
+{
+ gint jitt_comp; /* the user jitt_comp in miliseconds*/
+ gint jitt_comp_ts; /* the jitt_comp converted in rtp time (same unit as timestamp) */
+ gint adapt_jitt_comp_ts;
+ float slide;
+ float jitter;
+ gint count;
+ gint olddiff;
+ float inter_jitter; /* interarrival jitter as defined in the RFC */
+ gint corrective_step;
+ gint corrective_slide;
+ gboolean adaptive;
+} JitterControl;
+
+typedef struct _WaitPoint
+{
+ GMutex *lock;
+ GCond *cond;
+ guint32 time;
+ gboolean wakeup;
+} WaitPoint;
+
+typedef struct _RtpStream
+{
+ gint socket;
+ gint socktype;
+ gint max_rq_size;
+ gint time_jump;
+ guint32 ts_jump;
+ queue_t rq;
+ queue_t tev_rq;
+ mblk_t *cached_mp;
+#ifdef INET6
+ struct sockaddr_storage loc_addr;
+ struct sockaddr_storage rem_addr;
+#else
+ struct sockaddr_in loc_addr;
+ struct sockaddr_in rem_addr;
+#endif
+ int addrlen;
+ JitterControl jittctl;
+ guint32 snd_time_offset;/*the scheduler time when the application send its first timestamp*/
+ guint32 snd_ts_offset; /* the first application timestamp sent by the application */
+ guint32 snd_rand_offset; /* a random number added to the user offset to make the stream timestamp*/
+ guint32 snd_last_ts; /* the last stream timestamp sended */
+ guint32 rcv_time_offset; /*the scheduler time when the application ask for its first timestamp*/
+ guint32 rcv_ts_offset; /* the first stream timestamp */
+ guint32 rcv_query_ts_offset; /* the first user timestamp asked by the application */
+ guint32 rcv_diff_ts; /* difference between the first user timestamp and first stream timestamp */
+ guint32 hwrcv_diff_ts;
+ guint32 rcv_ts; /* to be unused */
+ guint32 rcv_last_ts; /* the last stream timestamp got by the application */
+ guint32 rcv_last_app_ts; /* the last application timestamp asked by the application */
+ guint32 rcv_last_ret_ts; /* the timestamp of the last sample returned (only for continuous audio)*/
+ poly32_t hwrcv_extseq; /* last received on socket extended sequence number */
+ guint32 hwrcv_seq_at_last_SR;
+ guint hwrcv_since_last_SR;
+ guint32 last_rcv_SR_ts; /* NTP timestamp (middle 32 bits) of last received SR */
+ struct timeval last_rcv_SR_time; /* time at which last SR was received */
+ guint16 snd_seq; /* send sequence number */
+ guint32 last_rtcp_report_snt_r; /* the time of the last rtcp report sent, in recv timestamp unit */
+ guint32 last_rtcp_report_snt_s; /* the time of the last rtcp report sent, in send timestamp unit */
+ guint32 rtcp_report_snt_interval; /* the interval in timestamp unit between rtcp report sent */
+ rtp_stats_t stats;
+}RtpStream;
+
+typedef struct _RtcpStream
+{
+ gint socket;
+ gint socktype;
+ mblk_t *cached_mp;
+#ifdef INET6
+ struct sockaddr_storage loc_addr;
+ struct sockaddr_storage rem_addr;
+#else
+ struct sockaddr_in loc_addr;
+ struct sockaddr_in rem_addr;
+#endif
+ int addrlen;
+} RtcpStream;
+
+typedef struct _RtpSession RtpSession;
+
+
+
+struct _RtpSession
+{
+ RtpSession *next; /* next RtpSession, when the session are enqueued by the scheduler */
+ RtpProfile *profile;
+ WaitPoint recv_wp;
+ WaitPoint send_wp;
+ GMutex *lock;
+ guint32 send_ssrc;
+ guint32 recv_ssrc;
+ gint payload_type;
+ gint max_buf_size;
+ RtpSignalTable on_ssrc_changed;
+ RtpSignalTable on_payload_type_changed;
+ RtpSignalTable on_telephone_event_packet;
+ RtpSignalTable on_telephone_event;
+ RtpSignalTable on_timestamp_jump;
+ RtpSignalTable on_network_error;
+ struct _OList *signal_tables;
+ RtpStream rtp;
+ RtcpStream rtcp;
+ RtpSessionMode mode;
+ struct _RtpScheduler *sched;
+ guint32 flags;
+ gint mask_pos; /* the position in the scheduler mask of RtpSession */
+ gpointer user_data;
+
+ /* telephony events extension */
+ gint telephone_events_pt; /* the payload type used for telephony events */
+ mblk_t *current_tev; /* the pending telephony events */
+ mblk_t *sd;
+ queue_t contributing_sources;
+};
+
+
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*private */
+void rtp_session_init(RtpSession *session, gint mode);
+#define rtp_session_lock(session) g_mutex_lock(session->lock)
+#define rtp_session_unlock(session) g_mutex_unlock(session->lock)
+#define rtp_session_set_flag(session,flag) (session)->flags|=(flag)
+#define rtp_session_unset_flag(session,flag) (session)->flags&=~(flag)
+void rtp_session_uninit(RtpSession *session);
+
+/* public API */
+RtpSession *rtp_session_new(gint mode);
+void rtp_session_set_scheduling_mode(RtpSession *session, gint yesno);
+void rtp_session_set_blocking_mode(RtpSession *session, gint yesno);
+void rtp_session_set_profile(RtpSession *session,RtpProfile *profile);
+#define rtp_session_get_profile(session) (session)->profile
+int rtp_session_signal_connect(RtpSession *session,const gchar *signal, RtpCallback cb, gpointer user_data);
+int rtp_session_signal_disconnect_by_callback(RtpSession *session,const gchar *signal, RtpCallback cb);
+void rtp_session_set_ssrc(RtpSession *session, guint32 ssrc);
+void rtp_session_set_seq_number(RtpSession *session, guint16 seq);
+guint16 rtp_session_get_seq_number(RtpSession *session);
+void rtp_session_set_jitter_compensation(RtpSession *session, int milisec);
+void rtp_session_enable_adaptive_jitter_compensation(RtpSession *session, gboolean val);
+gboolean rtp_session_adaptive_jitter_compensation_enabled(RtpSession *session);
+void rtp_session_set_time_jump_limit(RtpSession *session, gint miliseconds);
+int rtp_session_set_local_addr(RtpSession *session,const gchar *addr, gint port);
+gint rtp_session_set_remote_addr(RtpSession *session,const gchar *addr, gint port);
+/* alternatively to the set_remote_addr() and set_local_addr(), an application can give
+a valid socket (potentially connect()ed )to be used by the RtpSession */
+void rtp_session_set_sockets(RtpSession *session, gint rtpfd, gint rtcpfd);
+int rtp_session_set_payload_type(RtpSession *session, int paytype);
+int rtp_session_get_payload_type(RtpSession *session);
+int rtp_session_set_payload_type_with_string (RtpSession * session, const char * mime);
+/*low level recv and send functions */
+mblk_t * rtp_session_recvm_with_ts (RtpSession * session, guint32 user_ts);
+mblk_t * rtp_session_create_packet(RtpSession *session,gint header_size, const char *payload, gint payload_size);
+mblk_t * rtp_session_create_packet_with_data(RtpSession *session, char *payload, gint payload_size, void (*freefn)(void*));
+mblk_t * rtp_session_create_packet_in_place(RtpSession *session,char *buffer, gint size, void (*freefn)(void*) );
+gint rtp_session_sendm_with_ts (RtpSession * session, mblk_t *mp, guint32 userts);
+/* high level recv and send functions */
+gint rtp_session_recv_with_ts(RtpSession *session, gchar *buffer, gint len, guint32 time, gint *have_more);
+gint rtp_session_send_with_ts(RtpSession *session, const gchar *buffer, gint len, guint32 userts);
+
+
+guint32 rtp_session_get_current_send_ts(RtpSession *session);
+guint32 rtp_session_get_current_recv_ts(RtpSession *session);
+void rtp_session_flush_sockets(RtpSession *session);
+void rtp_session_reset(RtpSession *session);
+void rtp_session_destroy(RtpSession *session);
+
+#define rtp_session_get_stats(session) (&(session)->stats)
+#define rtp_session_reset_stats(session) memset(&(session)->stats,0,sizeof(rtp_stats_t))
+#define rtp_session_set_data(session,data) (session)->user_data=(data)
+#define rtp_session_get_data(session,data) ((session)->user_data)
+
+#define rtp_session_max_buf_size_set(session,bufsize) (session)->max_buf_size=(bufsize)
+
+/* in use with the scheduler to convert a timestamp in scheduler time unit (ms) */
+guint32 rtp_session_ts_to_time(RtpSession *session,guint32 timestamp);
+guint32 rtp_session_time_to_ts(RtpSession *session, gint time);
+/* this function aims at simulating senders with "imprecise" clocks, resulting in
+rtp packets sent with timestamp uncorrelated with the system clock .
+This is only availlable to sessions working with the oRTP scheduler */
+void rtp_session_make_time_distorsion(RtpSession *session, gint milisec);
+
+/*RTCP functions */
+void rtp_session_set_source_description(RtpSession *session, const gchar *cname,
+ const gchar *name, const gchar *email, const gchar *phone,
+ const gchar *loc, const gchar *tool, const gchar *note);
+void rtp_session_add_contributing_source(RtpSession *session, guint32 csrc,
+ const gchar *cname, const gchar *name, const gchar *email, const gchar *phone,
+ const gchar *loc, const gchar *tool, const gchar *note);
+void rtp_session_remove_contributing_sources(RtpSession *session, guint32 csrc);
+mblk_t* rtp_session_create_rtcp_sdes_packet(RtpSession *session);
+
+
+/* packet api */
+/* the first argument is a mblk_t. The header is supposed to be not splitted */
+#define rtp_set_markbit(mp,value) ((rtp_header_t*)((mp)->b_rptr))->markbit=(value)
+#define rtp_set_seqnumber(mp,seq) ((rtp_header_t*)((mp)->b_rptr))->seq_number=(seq)
+#define rtp_set_timestamp(mp,ts) ((rtp_header_t*)((mp)->b_rptr))->timestamp=(ts)
+#define rtp_set_ssrc(mp,_ssrc) ((rtp_header_t*)((mp)->b_rptr))->ssrc=(_ssrc)
+void rtp_add_csrc(mblk_t *mp,guint32 csrc);
+#define rtp_set_payload_type(mp,pt) ((rtp_header_t*)((mp)->b_rptr))->paytype=(pt)
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtpsignaltable.c b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtpsignaltable.c
new file mode 100644
index 00000000..35b19ae3
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtpsignaltable.c
@@ -0,0 +1,98 @@
+/*
+ The oRTP library is an RTP (Realtime Transport Protocol - rfc1889) stack.
+ Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+
+#include <rtpsession.h>
+#include "utils.h"
+
+
+void rtp_signal_table_init(RtpSignalTable *table,RtpSession *session, char *signal_name)
+{
+ memset(table,0,sizeof(RtpSignalTable));
+ table->session=session;
+ table->signal_name=signal_name;
+ session->signal_tables=o_list_append(session->signal_tables,(gpointer)table);
+}
+
+int rtp_signal_table_add(RtpSignalTable *table,RtpCallback cb, gpointer user_data)
+{
+ gint i;
+
+ for (i=0;i<RTP_CALLBACK_TABLE_MAX_ENTRIES;i++){
+ if (table->callback[i]==NULL){
+ table->callback[i]=cb;
+ table->user_data[i]=user_data;
+ table->count++;
+ return 0;
+ }
+ }
+ return -1;
+}
+
+void rtp_signal_table_emit(RtpSignalTable *table)
+{
+ gint i,c;
+
+ for (i=0,c=0;c<table->count;i++){
+ if (table->callback[i]!=NULL){
+ c++; /*I like it*/
+ table->callback[i](table->session,table->user_data[i]);
+ }
+ }
+}
+
+void rtp_signal_table_emit2(RtpSignalTable *table, gpointer arg)
+{
+ gint i,c;
+
+ for (i=0,c=0;c<table->count;i++){
+ if (table->callback[i]!=NULL){
+ c++; /*I like it*/
+ table->callback[i](table->session,arg,table->user_data[i]);
+ }
+ }
+}
+
+void rtp_signal_table_emit3(RtpSignalTable *table, gpointer arg1, gpointer arg2)
+{
+ gint i,c;
+
+ for (i=0,c=0;c<table->count;i++){
+ if (table->callback[i]!=NULL){
+ c++; /*I like it*/
+ table->callback[i](table->session,arg1,arg2,table->user_data[i]);
+ }
+ }
+}
+
+int rtp_signal_table_remove_by_callback(RtpSignalTable *table,RtpCallback cb)
+{
+ gint i;
+
+ for (i=0;i<RTP_CALLBACK_TABLE_MAX_ENTRIES;i++){
+ if (table->callback[i]==cb){
+ table->callback[i]=NULL;
+ table->user_data[i]=NULL;
+ table->count--;
+ return 0;
+ }
+ }
+ return -1;
+}
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtpsignaltable.h b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtpsignaltable.h
new file mode 100644
index 00000000..c6cbe960
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtpsignaltable.h
@@ -0,0 +1,47 @@
+/*
+ The oRTP library is an RTP (Realtime Transport Protocol - rfc1889) stack.
+ Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#define RTP_CALLBACK_TABLE_MAX_ENTRIES 5
+
+typedef void (*RtpCallback)(struct _RtpSession *, ...);
+
+struct _RtpSignalTable
+{
+ RtpCallback callback[RTP_CALLBACK_TABLE_MAX_ENTRIES];
+ gpointer user_data[RTP_CALLBACK_TABLE_MAX_ENTRIES];
+ struct _RtpSession *session;
+ const char *signal_name;
+ gint count;
+};
+
+typedef struct _RtpSignalTable RtpSignalTable;
+
+void rtp_signal_table_init(RtpSignalTable *table,struct _RtpSession *session, char *signal_name);
+
+int rtp_signal_table_add(RtpSignalTable *table,RtpCallback cb, gpointer user_data);
+
+void rtp_signal_table_emit(RtpSignalTable *table);
+
+/* emit but with a second arg */
+void rtp_signal_table_emit2(RtpSignalTable *table, gpointer arg);
+
+/* emit but with a third arg */
+void rtp_signal_table_emit3(RtpSignalTable *table, gpointer arg1, gpointer arg2);
+
+int rtp_signal_table_remove_by_callback(RtpSignalTable *table,RtpCallback cb);
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtptimer.c b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtptimer.c
new file mode 100644
index 00000000..6ac57e72
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtptimer.c
@@ -0,0 +1,32 @@
+/*
+ The oRTP library is an RTP (Realtime Transport Protocol - rfc1889) stack.
+ Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include "rtptimer.h"
+
+void rtp_timer_set_interval(RtpTimer *timer, struct timeval *interval)
+{
+ if (timer->state==RTP_TIMER_RUNNING){
+ g_warning("Cannot change timer interval while it is running.\n");
+ return;
+ }
+ timer->interval.tv_sec=interval->tv_sec;
+ timer->interval.tv_usec=interval->tv_usec;
+}
+
+
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtptimer.h b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtptimer.h
new file mode 100644
index 00000000..081e0892
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/rtptimer.h
@@ -0,0 +1,52 @@
+/*
+ The oRTP library is an RTP (Realtime Transport Protocol - rfc1889) stack.
+ Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef RTPTIMER_H
+#define RTPTIMER_H
+
+#ifndef _WIN32
+#include <sys/time.h>
+#else
+#include <time.h>
+#include "winsock2.h"
+#endif
+
+#include <rtpport.h>
+
+
+typedef void (*RtpTimerFunc)(void);
+
+struct _RtpTimer
+{
+ gint state;
+#define RTP_TIMER_RUNNING 1
+#define RTP_TIMER_STOPPED 0
+ RtpTimerFunc timer_init;
+ RtpTimerFunc timer_do;
+ RtpTimerFunc timer_uninit;
+ struct timeval interval;
+};
+
+typedef struct _RtpTimer RtpTimer;
+
+void rtp_timer_set_interval(RtpTimer *timer, struct timeval *interval);
+
+extern RtpTimer posix_timer;
+
+#endif
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/scheduler.c b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/scheduler.c
new file mode 100644
index 00000000..17ff6748
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/scheduler.c
@@ -0,0 +1,235 @@
+/*
+ The oRTP library is an RTP (Realtime Transport Protocol - rfc1889) stack.
+ Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _WIN32 /* do not include ortp-config.h when we are on win32 */
+ #include <rtpport.h>
+ #include <sched.h>
+ #include <unistd.h>
+ #include <errno.h>
+#else
+ #include "ortp-config-win32.h"
+#endif
+
+
+
+#include "scheduler.h"
+
+// To avoid warning during compile
+extern void rtp_session_process (RtpSession * session, guint32 time, RtpScheduler *sched);
+
+
+void rtp_scheduler_init(RtpScheduler *sched)
+{
+ sched->list=0;
+ sched->time_=0;
+ /* default to the posix timer */
+ rtp_scheduler_set_timer(sched,&posix_timer);
+ sched->lock=g_mutex_new();
+ //sched->unblock_select_mutex=g_mutex_new();
+ sched->unblock_select_cond=g_cond_new();
+ sched->max_sessions=sizeof(SessionSet)*8;
+ session_set_init(&sched->all_sessions);
+ sched->all_max=0;
+ session_set_init(&sched->r_sessions);
+ sched->r_max=0;
+ session_set_init(&sched->w_sessions);
+ sched->w_max=0;
+ session_set_init(&sched->e_sessions);
+ sched->e_max=0;
+}
+
+RtpScheduler * rtp_scheduler_new()
+{
+ RtpScheduler *sched=g_malloc(sizeof(RtpScheduler));
+ memset(sched,0,sizeof(RtpScheduler));
+ rtp_scheduler_init(sched);
+ return sched;
+}
+
+void rtp_scheduler_set_timer(RtpScheduler *sched,RtpTimer *timer)
+{
+ if (sched->thread_running){
+ g_warning("Cannot change timer while the scheduler is running !!");
+ return;
+ }
+ sched->timer=timer;
+ /* report the timer increment */
+ sched->timer_inc=(timer->interval.tv_usec/1000) + (timer->interval.tv_sec*1000);
+}
+
+void rtp_scheduler_start(RtpScheduler *sched)
+{
+ if (sched->thread_running==0){
+ sched->thread_running=1;
+ g_mutex_lock(sched->lock);
+ sched->thread=g_thread_create((GThreadFunc)rtp_scheduler_schedule,(gpointer)sched,TRUE,NULL);
+ g_cond_wait(sched->unblock_select_cond,sched->lock);
+ g_mutex_unlock(sched->lock);
+ }
+ else g_warning("Scheduler thread already running.");
+
+}
+void rtp_scheduler_stop(RtpScheduler *sched)
+{
+ if (sched->thread_running==1)
+ {
+ sched->thread_running=0;
+ g_thread_join(sched->thread);
+ }
+ else g_warning("Scheduler thread is not running.");
+}
+
+void rtp_scheduler_destroy(RtpScheduler *sched)
+{
+ if (sched->thread_running) rtp_scheduler_stop(sched);
+ g_mutex_free(sched->lock);
+ //g_mutex_free(sched->unblock_select_mutex);
+ g_cond_free(sched->unblock_select_cond);
+ g_free(sched);
+}
+
+gpointer rtp_scheduler_schedule(gpointer psched)
+{
+ RtpScheduler *sched=(RtpScheduler*) psched;
+ RtpTimer *timer=sched->timer;
+ RtpSession *current;
+ int err;
+
+ /* try to get the real time priority by getting root*/
+#ifndef _WIN32
+#ifdef HAVE_SETEUID
+ err=seteuid(0);
+#else
+ err=setuid(0);
+#endif
+ if (err<0) g_message("Could not get root euid: %s",strerror(errno));
+#endif
+ g_message("scheduler: trying to reach real time kernel scheduling...");
+
+ /* take this lock to prevent the thread to start until g_thread_create() returns
+ because we need sched->thread to be initialized */
+ g_mutex_lock(sched->lock);
+ g_cond_signal(sched->unblock_select_cond); /* unblock the starting thread */
+ g_mutex_unlock(sched->lock);
+ g_thread_set_priority(sched->thread,G_THREAD_PRIORITY_HIGH);
+ timer->timer_init();
+ while(sched->thread_running)
+ {
+ /* do the processing here: */
+
+ g_mutex_lock(sched->lock);
+
+ current=sched->list;
+ /* processing all scheduled rtp sessions */
+ while (current!=NULL)
+ {
+ ortp_debug("scheduler: processing session=%p.\n",current);
+ rtp_session_process(current,sched->time_,sched);
+ current=current->next;
+ }
+ /* wake up all the threads that are sleeping in _select() */
+ g_cond_broadcast(sched->unblock_select_cond);
+ g_mutex_unlock(sched->lock);
+
+ /* now while the scheduler is going to sleep, the other threads can compute their
+ result mask and see if they have to leave, or to wait for next tick*/
+ //g_message("scheduler: sleeping.");
+ timer->timer_do();
+ sched->time_+=sched->timer_inc;
+ }
+ /* when leaving the thread, stop the timer */
+ timer->timer_uninit();
+ return NULL;
+}
+
+void rtp_scheduler_add_session(RtpScheduler *sched, RtpSession *session)
+{
+ RtpSession *oldfirst;
+ int i;
+ if (session->flags & RTP_SESSION_IN_SCHEDULER){
+ /* the rtp session is already scheduled, so return silently */
+ return;
+ }
+ rtp_scheduler_lock(sched);
+ /* enqueue the session to the list of scheduled sessions */
+ oldfirst=sched->list;
+ sched->list=session;
+ session->next=oldfirst;
+ if (sched->max_sessions==0){
+ g_error("rtp_scheduler_add_session: max_session=0 !");
+ }
+ /* find a free pos in the session mask*/
+ for (i=0;i<sched->max_sessions;i++){
+ if (!ORTP_FD_ISSET(i,&sched->all_sessions.rtpset)){
+ session->mask_pos=i;
+ session_set_set(&sched->all_sessions,session);
+ /* make a new session scheduled not blockable if it has not started*/
+ if (session->flags & RTP_SESSION_RECV_NOT_STARTED)
+ session_set_set(&sched->r_sessions,session);
+ if (session->flags & RTP_SESSION_SEND_NOT_STARTED)
+ session_set_set(&sched->w_sessions,session);
+ if (i>sched->all_max){
+ sched->all_max=i;
+ }
+ break;
+ }
+ }
+
+ rtp_session_set_flag(session,RTP_SESSION_IN_SCHEDULER);
+ rtp_scheduler_unlock(sched);
+}
+
+void rtp_scheduler_remove_session(RtpScheduler *sched, RtpSession *session)
+{
+ RtpSession *tmp;
+ int cond=1;
+ g_return_if_fail(session!=NULL);
+ if (!(session->flags & RTP_SESSION_IN_SCHEDULER)){
+ /* the rtp session is not scheduled, so return silently */
+ return;
+ }
+
+ rtp_scheduler_lock(sched);
+ tmp=sched->list;
+ if (tmp==session){
+ sched->list=tmp->next;
+ rtp_session_unset_flag(session,RTP_SESSION_IN_SCHEDULER);
+ session_set_clr(&sched->all_sessions,session);
+ rtp_scheduler_unlock(sched);
+ return;
+ }
+ /* go the position of session in the list */
+ while(cond){
+ if (tmp!=NULL){
+ if (tmp->next==session){
+ tmp->next=tmp->next->next;
+ cond=0;
+ }
+ else tmp=tmp->next;
+ }else {
+ /* the session was not found ! */
+ g_warning("rtp_scheduler_remove_session: the session was not found in the scheduler list!");
+ cond=0;
+ }
+ }
+ rtp_session_unset_flag(session,RTP_SESSION_IN_SCHEDULER);
+ /* delete the bit in the mask */
+ session_set_clr(&sched->all_sessions,session);
+ rtp_scheduler_unlock(sched);
+}
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/scheduler.h b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/scheduler.h
new file mode 100644
index 00000000..91cde6a9
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/scheduler.h
@@ -0,0 +1,70 @@
+/*
+ The oRTP library is an RTP (Realtime Transport Protocol - rfc1889) stack.
+ Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef SCHEDULER_H
+#define SCHEDULER_H
+
+#include <rtpsession.h>
+#include <sessionset.h>
+#include "rtptimer.h"
+#include "port_fct.h"
+
+
+struct _RtpScheduler {
+
+ RtpSession *list; /* list of scheduled sessions*/
+ SessionSet all_sessions; /* mask of scheduled sessions */
+ gint all_max; /* the highest pos in the all mask */
+ SessionSet r_sessions; /* mask of sessions that have a recv event */
+ gint r_max;
+ SessionSet w_sessions; /* mask of sessions that have a send event */
+ gint w_max;
+ SessionSet e_sessions; /* mask of session that have error event */
+ gint e_max;
+ gint max_sessions; /* the number of position in the masks */
+ /* GMutex *unblock_select_mutex; */
+ GCond *unblock_select_cond;
+ GMutex *lock;
+ GThread *thread;
+ gint thread_running;
+ struct _RtpTimer *timer;
+ guint32 time_; /*number of miliseconds elapsed since the start of the thread */
+ guint32 timer_inc; /* the timer increment in milisec */
+};
+
+typedef struct _RtpScheduler RtpScheduler;
+
+RtpScheduler * rtp_scheduler_new();
+void rtp_scheduler_set_timer(RtpScheduler *sched,RtpTimer *timer);
+void rtp_scheduler_start(RtpScheduler *sched);
+void rtp_scheduler_stop(RtpScheduler *sched);
+void rtp_scheduler_destroy(RtpScheduler *sched);
+
+void rtp_scheduler_add_session(RtpScheduler *sched, RtpSession *session);
+void rtp_scheduler_remove_session(RtpScheduler *sched, RtpSession *session);
+
+gpointer rtp_scheduler_schedule(gpointer sched);
+
+#define rtp_scheduler_lock(sched) g_mutex_lock((sched)->lock)
+#define rtp_scheduler_unlock(sched) g_mutex_unlock((sched)->lock)
+
+/* void rtp_scheduler_add_set(RtpScheduler *sched, SessionSet *set); */
+
+RtpScheduler * ortp_get_scheduler();
+#endif
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/sessionset.c b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/sessionset.c
new file mode 100644
index 00000000..7b5ad921
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/sessionset.c
@@ -0,0 +1,187 @@
+/*
+ The oRTP library is an RTP (Realtime Transport Protocol - rfc1889) stack.
+ Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <ortp.h>
+#include <sessionset.h>
+#include "scheduler.h"
+
+/**
+ *session_set_init:
+ *@ss: a SessionSet statically allocated.
+ *
+ * Initializes a session set. It is unusefull to call this function on a session set object
+ * returned by session_set_new().
+ *
+**/
+
+
+/**
+ *session_set_new:
+ *
+ * Allocates and initialize a new empty session set.
+ *
+ *Returns: the session set.
+**/
+SessionSet * session_set_new()
+{
+ SessionSet *set=g_malloc(sizeof(SessionSet));
+ session_set_init(set);
+ return set;
+}
+
+
+/**
+ *session_set_destroy:
+ *@set: a SessionSet
+ * Destroys a session set.
+ *
+**/
+
+void session_set_destroy(SessionSet *set)
+{
+ g_free(set);
+}
+
+gint session_set_and(SessionSet *sched_set, gint maxs, SessionSet *user_set, SessionSet *result_set)
+{
+ guint32 *mask1,*mask2,*mask3;
+ gint i=0;
+ gint j,ret=0;
+ mask1=(guint32*)&sched_set->rtpset;
+ mask2=(guint32*)&user_set->rtpset;
+ mask3=(guint32*)&result_set->rtpset;
+ while(i<maxs+1){
+ *mask3=(*mask1) & (*mask2); /* computes the AND between the two masks*/
+ /* and unset the sessions that have been found from the sched_set */
+ *mask1=(*mask1) & (~(*mask3));
+ if ((*mask3)!=0){
+ for (j=0;j<32;j++){
+ if ( ((*mask3)>>j) & 1){
+ ret++;
+ }
+ }
+ }
+ i+=32;
+ mask1++;
+ mask2++;
+ mask3++;
+ }
+ //printf("session_set_and: ret=%i\n",ret);
+ return ret;
+}
+
+/**
+ *session_set_select:
+ *@recvs: a set of rtp sessions to be watched for read events
+ *@sends: a set of rtp sessions to be watched for write events
+ *@errors: a set of rtp sessions to be watched for errors
+ *
+ * This function performs similarly as libc select() function, but performs on #RtpSession
+ * instead of file descriptors.
+ * session_set_select() suspends the calling process until some events arrive on one of the
+ * three sets passed in argument. Two of the sets can be NULL.
+ * The first set @recvs is interpreted as a set of RtpSession waiting for receive events:
+ * a new buffer (perhaps empty) is availlable on one or more sessions of the set, or the last
+ * receive operation with rtp_session_recv_with_ts() would have finished if it were in
+ * blocking mode.
+ * The second set is interpreted as a set of RtpSession waiting for send events, i.e. the last
+ * rtp_session_send_with_ts() call on a session would have finished if it were in blocking mode.
+ *
+ * When some events arrived on some of sets, then the function returns and sets are changed
+ * to indicate the sessions where events happened.
+ * Sessions can be added to sets using session_set_set(), a session has to be tested to be
+ * part of a set using session_set_is_set().
+ *
+ *Returns: the number of sessions on which the selected events happened.
+**/
+int session_set_select(SessionSet *recvs, SessionSet *sends, SessionSet *errors)
+{
+ gint ret=0,bits;
+ SessionSet temp;
+ RtpScheduler *sched=ortp_get_scheduler();
+
+ /*lock the scheduler to not read the masks while they are being modified by the scheduler*/
+ rtp_scheduler_lock(sched);
+
+ while(1){
+ /* computes the SessionSet intersection (in the other words mask intersection) between
+ the mask given by the user and scheduler masks */
+ if (recvs!=NULL){
+ bits=session_set_and(&sched->r_sessions,sched->all_max,recvs,&temp);
+ if (bits>0){
+ ret+=bits;
+ /* copy the result set in the given user set */
+ session_set_copy(recvs,&temp);
+ }
+ }
+ if (sends!=NULL){
+ bits=session_set_and(&sched->w_sessions,sched->all_max,sends,&temp);
+ if (bits>0){
+ ret+=bits;
+ /* copy the result set in the given user set */
+ session_set_copy(sends,&temp);
+ }
+ }
+ if (errors!=NULL){
+ bits=session_set_and(&sched->e_sessions,sched->all_max,errors,&temp);
+ if (bits>0){
+ ret+=bits;
+ /* copy the result set in the given user set */
+ session_set_copy(errors,&temp);
+ }
+ }
+ if (ret>0){
+ /* there are set file descriptors, return immediately */
+ //printf("There are %i sessions set, returning.\n",ret);
+ rtp_scheduler_unlock(sched);
+ return ret;
+ }
+ //printf("There are %i sessions set.\n",ret);
+ /* else we wait until the next loop of the scheduler*/
+ g_cond_wait(sched->unblock_select_cond,sched->lock);
+ }
+
+ return -1;
+}
+
+/**
+ *session_set_set:
+ *@ss: a set (#SessionSet object)
+ *@rtpsession: a rtp session
+ *
+ * This macro adds rtp session @_session to set @_set.
+**/
+
+/**
+ *session_set_is_set:
+ *@ss: a set (#SessionSet object)
+ *@rtpsession: a rtp session
+ *
+ * This macro tests if @_session is part of @_set. 1 is returned if true, 0 else.
+**/
+
+/**
+ *session_set_clr:
+ *@ss: a set of sessions.
+ *@rtpsession: a rtp session.
+ *
+ * Removes the @_session from the _set.
+ *
+ *
+**/
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/sessionset.h b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/sessionset.h
new file mode 100644
index 00000000..623b9d10
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/sessionset.h
@@ -0,0 +1,102 @@
+/*
+ The oRTP library is an RTP (Realtime Transport Protocol - rfc1889) stack.
+ Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef SESSIONSET_H
+#define SESSIONSET_H
+
+
+#include <rtpsession.h>
+
+
+#ifndef _WIN32
+/* UNIX */
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#define ORTP_FD_SET(d, s) FD_SET(d, s)
+#define ORTP_FD_CLR(d, s) FD_CLR(d, s)
+#define ORTP_FD_ISSET(d, s) FD_ISSET(d, s)
+#define ORTP_FD_ZERO(s) FD_ZERO(s)
+
+typedef fd_set ortp_fd_set;
+
+
+#else
+/* WIN32 */
+
+#define ORTP_FD_ZERO(s) \
+ do { \
+ unsigned int __i; \
+ ortp_fd_set *__arr = (s); \
+ for (__i = 0; __i < sizeof (ortp_fd_set) / sizeof (ortp__fd_mask); ++__i) \
+ ORTP__FDS_BITS (__arr)[__i] = 0; \
+ } while (0)
+#define ORTP_FD_SET(d, s) (ORTP__FDS_BITS (s)[ORTP__FDELT(d)] |= ORTP__FDMASK(d))
+#define ORTP_FD_CLR(d, s) (ORTP__FDS_BITS (s)[ORTP__FDELT(d)] &= ~ORTP__FDMASK(d))
+#define ORTP_FD_ISSET(d, s) ((ORTP__FDS_BITS (s)[ORTP__FDELT(d)] & ORTP__FDMASK(d)) != 0)
+
+
+
+/* The fd_set member is required to be an array of longs. */
+typedef long int ortp__fd_mask;
+
+
+/* Number of bits per word of `fd_set' (some code assumes this is 32). */
+#define ORTP__FD_SETSIZE 1024
+
+/* It's easier to assume 8-bit bytes than to get CHAR_BIT. */
+#define ORTP__NFDBITS (8 * sizeof (ortp__fd_mask))
+#define ORTP__FDELT(d) ((d) / ORTP__NFDBITS)
+#define ORTP__FDMASK(d) ((ortp__fd_mask) 1 << ((d) % ORTP__NFDBITS))
+
+
+/* fd_set for select and pselect. */
+typedef struct
+ {
+ ortp__fd_mask fds_bits[ORTP__FD_SETSIZE / ORTP__NFDBITS];
+# define ORTP__FDS_BITS(set) ((set)->fds_bits)
+ } ortp_fd_set;
+
+
+#endif /*end WIN32*/
+
+struct _SessionSet
+{
+ ortp_fd_set rtpset;
+};
+
+
+typedef struct _SessionSet SessionSet;
+
+SessionSet * session_set_new();
+#define session_set_init(ss) ORTP_FD_ZERO(&(ss)->rtpset)
+#define session_set_set(ss,rtpsession) ORTP_FD_SET((rtpsession)->mask_pos,&(ss)->rtpset)
+#define session_set_is_set(ss,rtpsession) ORTP_FD_ISSET((rtpsession)->mask_pos,&(ss)->rtpset)
+#define session_set_clr(ss,rtpsession) ORTP_FD_CLR((rtpsession)->mask_pos,&(ss)->rtpset)
+
+#define session_set_copy(dest,src) memcpy(&(dest)->rtpset,&(src)->rtpset,sizeof(ortp_fd_set))
+
+void session_set_destroy(SessionSet *set);
+
+
+int session_set_select(SessionSet *recvs, SessionSet *sends, SessionSet *errors);
+
+
+#endif
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/str_utils.c b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/str_utils.c
new file mode 100644
index 00000000..813ea707
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/str_utils.c
@@ -0,0 +1,297 @@
+/*
+ The oRTP library is an RTP (Realtime Transport Protocol - rfc1889) stack.
+ Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <rtpport.h>
+#include <rtp.h>
+#include <str_utils.h>
+
+#include <stdio.h>
+
+void qinit(queue_t *q){
+ mblk_init(&q->_q_first);
+ mblk_init(&q->_q_last);
+ q->_q_first.b_next=&q->_q_last;
+ q->_q_last.b_prev=&q->_q_first;
+ q->q_mcount=0;
+}
+
+void mblk_init(mblk_t *mp)
+{
+ mp->b_cont=mp->b_prev=mp->b_next=NULL;
+ mp->b_rptr=mp->b_wptr=NULL;
+}
+
+mblk_t *allocb(int size, int pri)
+{
+ mblk_t *mp;
+ dblk_t *datab;
+ gchar *buf;
+
+ mp=g_malloc(sizeof(mblk_t));
+ mblk_init(mp);
+ datab=g_malloc(sizeof(dblk_t));
+
+ buf=g_malloc(size);
+
+ datab->db_base=buf;
+ datab->db_lim=buf+size;
+ datab->ref_count=1;
+ datab->db_freefn=g_free;
+
+ mp->b_datap=datab;
+ mp->b_rptr=mp->b_wptr=buf;
+ mp->b_next=mp->b_prev=mp->b_cont=NULL;
+ return mp;
+}
+
+mblk_t *allocb_with_buf(char *buf, int size, int pri, void (*freefn)(void*) )
+{
+ mblk_t *mp;
+ dblk_t *datab;
+
+ mp=g_malloc(sizeof(mblk_t));
+ mblk_init(mp);
+ datab=g_malloc(sizeof(dblk_t));
+
+
+ datab->db_base=buf;
+ datab->db_lim=buf+size;
+ datab->ref_count=1;
+ datab->db_freefn=freefn;
+
+ mp->b_datap=datab;
+ mp->b_rptr=mp->b_wptr=buf;
+ mp->b_next=mp->b_prev=mp->b_cont=NULL;
+ return mp;
+}
+
+
+void freeb(mblk_t *mp)
+{
+ g_return_if_fail(mp->b_datap!=NULL);
+ g_return_if_fail(mp->b_datap->db_base!=NULL);
+
+ mp->b_datap->ref_count--;
+ if (mp->b_datap->ref_count==0)
+ {
+ if (mp->b_datap->db_freefn!=NULL)
+ mp->b_datap->db_freefn(mp->b_datap->db_base);
+ g_free(mp->b_datap);
+ }
+ g_free(mp);
+}
+
+void freemsg(mblk_t *mp)
+{
+ mblk_t *tmp1,*tmp2;
+ tmp1=mp;
+ while(tmp1!=NULL)
+ {
+ tmp2=tmp1->b_cont;
+ freeb(tmp1);
+ tmp1=tmp2;
+ }
+}
+
+mblk_t *dupb(mblk_t *mp)
+{
+ mblk_t *newm;
+ g_return_val_if_fail(mp->b_datap!=NULL,NULL);
+ g_return_val_if_fail(mp->b_datap->db_base!=NULL,NULL);
+
+ mp->b_datap->ref_count++;
+ newm=g_malloc(sizeof(mblk_t));
+ mblk_init(newm);
+ newm->b_datap=mp->b_datap;
+ newm->b_rptr=mp->b_rptr;
+ newm->b_wptr=mp->b_wptr;
+ return newm;
+}
+
+/* duplicates a complex mblk_t */
+mblk_t *dupmsg(mblk_t* m)
+{
+ mblk_t *newm=NULL,*mp,*prev;
+ prev=newm=dupb(m);
+ m=m->b_cont;
+ while (m!=NULL){
+ mp=dupb(m);
+ prev->b_cont=mp;
+ prev=mp;
+ m=m->b_cont;
+ }
+ return newm;
+}
+
+void putq(queue_t *q,mblk_t *mp)
+{
+ q->_q_last.b_prev->b_next=mp;
+ mp->b_prev=q->_q_last.b_prev;
+ mp->b_next=&q->_q_last;
+ q->_q_last.b_prev=mp;
+ q->q_mcount++;
+}
+
+mblk_t *getq(queue_t *q)
+{
+ mblk_t *tmp;
+ tmp=q->_q_first.b_next;
+ if (tmp==&q->_q_last) return NULL;
+ q->_q_first.b_next=tmp->b_next;
+ tmp->b_next->b_prev=&q->_q_first;
+ tmp->b_prev=NULL;
+ tmp->b_next=NULL;
+ q->q_mcount--;
+ return tmp;
+}
+
+/* insert mp in q just before emp */
+void insq(queue_t *q,mblk_t *emp, mblk_t *mp)
+{
+ if (emp==NULL){
+ putq(q,mp);
+ return;
+ }
+ q->q_mcount++;
+ emp->b_prev->b_next=mp;
+ mp->b_prev=emp->b_prev;
+ emp->b_prev=mp;
+ mp->b_next=emp;
+}
+
+void remq(queue_t *q, mblk_t *mp){
+ q->q_mcount--;
+ mp->b_prev->b_next=mp->b_next;
+ mp->b_next->b_prev=mp->b_prev;
+ mp->b_next=NULL;
+ mp->b_prev=NULL;
+}
+
+/* remove and free all messages in the q */
+void flushq(queue_t *q, int how)
+{
+ mblk_t *mp;
+
+ while ((mp=getq(q))!=NULL)
+ {
+ freemsg(mp);
+ }
+}
+
+gint msgdsize(mblk_t *mp)
+{
+ gint msgsize=0;
+ while(mp!=NULL){
+ msgsize+=mp->b_wptr-mp->b_rptr;
+ mp=mp->b_cont;
+ }
+ return msgsize;
+}
+
+mblk_t * msgpullup(mblk_t *mp,int len)
+{
+ mblk_t *newm;
+ gint msgsize=msgdsize(mp);
+ gint rlen;
+ gint mlen;
+
+
+ if ((len==-1) || (len>msgsize)) len=msgsize;
+ rlen=len;
+ newm=allocb(len,BPRI_MED);
+
+ while(mp!=NULL){
+ mlen=mp->b_wptr-mp->b_rptr;
+ if (rlen>=mlen)
+ {
+ memcpy(newm->b_wptr,mp->b_rptr,mlen);
+ rlen-=mlen;
+ newm->b_wptr+=mlen;
+ }
+ else /* rlen < mlen */
+ {
+ memcpy(newm->b_wptr,mp->b_rptr,rlen);
+ newm->b_wptr+=rlen;
+
+ /* put the end of the original message at the end of the new */
+ newm->b_cont=dupmsg(mp);
+ newm->b_cont->b_rptr+=rlen;
+ return newm;
+ }
+ mp=mp->b_cont;
+ }
+ return newm;
+}
+
+
+mblk_t *copyb(mblk_t *mp)
+{
+ mblk_t *newm;
+ gint len=mp->b_wptr-mp->b_rptr;
+ newm=allocb(len,BPRI_MED);
+ memcpy(newm->b_wptr,mp->b_rptr,len);
+ newm->b_wptr+=len;
+ return newm;
+}
+
+mblk_t *copymsg(mblk_t *mp)
+{
+ mblk_t *newm=0,*m;
+ m=newm=copyb(mp);
+ mp=mp->b_cont;
+ while(mp!=NULL){
+ m->b_cont=copyb(mp);
+ m=m->b_cont;
+ mp=mp->b_cont;
+ }
+ return newm;
+}
+
+mblk_t * appendb(mblk_t *mp, const char *data, int size, gboolean pad){
+ gint padcnt=0;
+ int i;
+ if (pad){
+ padcnt= (gint)(4L-( (long)(mp->b_wptr+size) % 4L)) % 4L;
+ }
+ if ((mp->b_wptr + size +padcnt) > (char*)mp->b_datap->db_lim){
+ /* buffer is not large enough: append a new block (with the same size ?)*/
+ int plen=(char*)mp->b_datap->db_lim - (char*) mp->b_datap->db_base;
+ mp->b_cont=allocb(MAX(plen,size),0);
+ mp=mp->b_cont;
+ }
+ if (size) memcpy(mp->b_wptr,data,size);
+ mp->b_wptr+=size;
+ for (i=0;i<padcnt;i++){
+ mp->b_wptr[0]=0;
+ mp->b_wptr++;
+ }
+ return mp;
+}
+
+void msgappend(mblk_t *mp, const char *data, int size, gboolean pad){
+ while(mp->b_cont!=NULL) mp=mp->b_cont;
+ appendb(mp,data,size,pad);
+}
+
+mblk_t *concatb(mblk_t *mp, mblk_t *newm){
+ while (mp->b_cont!=NULL) mp=mp->b_cont;
+ mp->b_cont=newm;
+ while(newm->b_cont!=NULL) newm=newm->b_cont;
+ return newm;
+}
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/str_utils.h b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/str_utils.h
new file mode 100644
index 00000000..b605fc2a
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/str_utils.h
@@ -0,0 +1,118 @@
+/*
+ The oRTP library is an RTP (Realtime Transport Protocol - rfc1889) stack.
+ Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef STR_UTILS_H
+#define STR_UTILS_H
+
+
+#include <rtpport.h>
+
+
+typedef struct msgb
+{
+ struct msgb *b_prev;
+ struct msgb *b_next;
+ struct msgb *b_cont;
+ struct datab *b_datap;
+ char *b_rptr;
+ char *b_wptr;
+} mblk_t;
+
+typedef struct datab
+{
+ char *db_base;
+ char *db_lim;
+ void (*db_freefn)(void*);
+ guint ref_count;
+} dblk_t;
+
+typedef struct _queue
+{
+ mblk_t _q_first;
+ mblk_t _q_last;
+ gint q_mcount; /*number of packet in the q */
+} queue_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void qinit(queue_t *q);
+
+void putq(queue_t *q, mblk_t *m);
+mblk_t * getq(queue_t *q);
+
+void insq(queue_t *q,mblk_t *emp, mblk_t *mp);
+
+void remq(queue_t *q, mblk_t *mp);
+
+void mblk_init(mblk_t *mp);
+
+/* allocates a mblk_t, that points to a datab_t, that points to a buffer of size size. */
+mblk_t *allocb(gint size,gint unused);
+#define BPRI_MED 0
+
+/* allocates a mblk_t, that points to a datab_t, that points to buf; buf will be freed using freefn */
+mblk_t *allocb_with_buf(char *buf, int size, int pri, void (*freefn)(void*) );
+
+/* frees a mblk_t, and if the datab ref_count is 0, frees it and the buffer too */
+void freeb(mblk_t *m);
+
+/* frees recursively (follow b_cont) a mblk_t, and if the datab
+ref_count is 0, frees it and the buffer too */
+void freemsg(mblk_t *mp);
+
+/* duplicates a mblk_t , buffer is not duplicated*/
+mblk_t *dupb(mblk_t *m);
+
+/* duplicates a complex mblk_t, buffer is not duplicated */
+mblk_t *dupmsg(mblk_t* m);
+
+/* remove and free all messages in the q */
+#define FLUSHALL 0
+void flushq(queue_t *q, int how);
+
+/* returns the size of data of a message */
+gint msgdsize(mblk_t *mp);
+
+/* concatenates all fragment of a complex message ( a new message is returned, old is untouched*/
+mblk_t * msgpullup(mblk_t *mp,int len);
+
+/* duplicates a single message, but with buffer included */
+mblk_t *copyb(mblk_t *mp);
+
+/* duplicates a complex message with buffer included */
+mblk_t *copymsg(mblk_t *mp);
+
+mblk_t * appendb(mblk_t *mp, const char *data, int size, gboolean pad);
+void msgappend(mblk_t *mp, const char *data, int size, gboolean pad);
+
+mblk_t *concatb(mblk_t *mp, mblk_t *newm);
+
+#define qempty(q) (&(q)->_q_last==(q)->_q_first.b_next)
+#define qfirst(q) ((q)->_q_first.b_next!=&(q)->_q_last ? (q)->_q_first.b_next : NULL)
+#define qbegin(q) ((q)->_q_first.b_next)
+#define qlast(q) ((q)->_q_last.b_prev!=&(q)->_q_first ? (q)->_q_last.b_prev : NULL)
+#define qend(q,mp) ((mp)==&(q)->_q_first || ((mp)==&(q)->_q_last))
+#define qnext(q,mp) ((mp)->b_next)
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/telephonyevents.c b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/telephonyevents.c
new file mode 100644
index 00000000..884226ea
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/telephonyevents.c
@@ -0,0 +1,338 @@
+/*
+ The oRTP library is an RTP (Realtime Transport Protocol - rfc1889) stack.
+ Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <telephonyevents.h>
+
+
+PayloadType telephone_event={
+ PAYLOAD_AUDIO_PACKETIZED, /*type */
+ 8000, /*clock rate */
+ 0, /* bytes per sample N/A */
+ NULL, /* zero pattern N/A*/
+ 0, /*pattern_length N/A */
+ 0, /* normal_bitrate */
+ "telephone-event",
+ 0 /*flags */
+};
+
+/* tell if the session supports telephony events. For this the telephony events payload_type
+ must be present in the rtp profile used by the session */
+/**
+ *rtp_session_telephone_events_supported:
+ *@session : a rtp session
+ *
+ * Tells whether telephony events payload type is supported within the context of the rtp
+ * session.
+ *
+ *Returns: the payload type number used for telephony events if found, -1 if not found.
+**/
+gint rtp_session_telephone_events_supported(RtpSession *session)
+{
+ /* search for a telephony event payload in the current profile */
+ session->telephone_events_pt=rtp_profile_get_payload_number_from_mime(session->profile,"telephone-event");
+ return session->telephone_events_pt;
+}
+
+
+/**
+ *rtp_session_create_telephone_event_packet:
+ *@session: a rtp session.
+ *@start: boolean to indicate if the marker bit should be set.
+ *
+ * Allocates a new rtp packet to be used to add named telephony events. The application can use
+ * then rtp_session_add_telephone_event() to add named events to the packet.
+ * Finally the packet has to be sent with rtp_session_sendm_with_ts().
+ *
+ *Returns: a message block containing the rtp packet if successfull, NULL if the rtp session
+ *cannot support telephony event (because the rtp profile it is bound to does not include
+ *a telephony event payload type).
+**/
+mblk_t *rtp_session_create_telephone_event_packet(RtpSession *session, int start)
+{
+ mblk_t *mp;
+ rtp_header_t *rtp;
+
+ g_return_val_if_fail(session->telephone_events_pt!=-1,NULL);
+
+ mp=allocb(RTP_FIXED_HEADER_SIZE+TELEPHONY_EVENTS_ALLOCATED_SIZE,BPRI_MED);
+ if (mp==NULL) return NULL;
+ rtp=(rtp_header_t*)mp->b_rptr;
+ rtp->version = 2;
+ rtp->markbit=start;
+ rtp->padbit = 0;
+ rtp->extbit = 0;
+ rtp->cc = 0;
+ rtp->ssrc = session->send_ssrc;
+ /* timestamp set later, when packet is sended */
+ /*seq number set later, when packet is sended */
+
+ /*set the payload type */
+ rtp->paytype=session->telephone_events_pt;
+
+ /*copy the payload */
+ mp->b_wptr+=RTP_FIXED_HEADER_SIZE;
+ return mp;
+}
+
+
+/**
+ *rtp_session_add_telephone_event:
+ *@session: a rtp session.
+ *@packet: a rtp packet as a #mblk_t
+ *@event: the event type as described in rfc2833, ie one of the TEV_ macros.
+ *@end: boolean to indicate if the end bit should be set. (end of tone)
+ *@volume: the volume of the telephony tone, as described in rfc2833
+ *@duration:the duration of the telephony tone, in timestamp unit.
+ *
+ * Adds a named telephony event to a rtp packet previously allocated using
+ * rtp_session_create_telephone_event_packet().
+ *
+ *Returns 0 on success.
+**/
+gint rtp_session_add_telephone_event(RtpSession *session,
+ mblk_t *packet, guchar event, gint end, guchar volume, guint16 duration)
+{
+ mblk_t *mp=packet;
+ telephone_event_t *event_hdr;
+
+
+ /* find the place where to add the new telephony event to the packet */
+ while(mp->b_cont!=NULL) mp=mp->b_cont;
+ /* see if we need to allocate a new mblk_t */
+ if ( (long)mp->b_wptr >= (long) mp->b_datap->db_lim){
+ mblk_t *newm=allocb(TELEPHONY_EVENTS_ALLOCATED_SIZE,BPRI_MED);
+ mp->b_cont=newm;
+ mp=mp->b_cont;
+ }
+ if (mp==NULL) return -1;
+ event_hdr=(telephone_event_t*)mp->b_wptr;
+ event_hdr->event=event;
+ event_hdr->R=0;
+ event_hdr->E=end;
+ event_hdr->volume=volume;
+ event_hdr->duration=htons(duration);
+ mp->b_wptr+=sizeof(telephone_event_t);
+ return 0;
+}
+/**
+ *rtp_session_send_dtmf:
+ *@session : a rtp session
+ *@dtmf : a character meaning the dtmf (ex: '1', '#' , '9' ...)
+ *@userts : the timestamp
+ *
+ * This functions creates telephony events packets for @dtmf and sends them.
+ * It uses rtp_session_create_telephone_event_packet() and
+ * rtp_session_add_telephone_event() to create them and finally
+ * rtp_session_sendm_with_ts() to send them.
+ *
+ *Returns: 0 if successfull, -1 if the session cannot support telephony events or if the dtmf
+ * given as argument is not valid.
+**/
+gint rtp_session_send_dtmf(RtpSession *session, gchar dtmf, guint32 userts)
+{
+ mblk_t *m1,*m2,*m3;
+ int tev_type;
+ /* create the first telephony event packet */
+ switch (dtmf){
+ case '1':
+ tev_type=TEV_DTMF_1;
+ break;
+ case '2':
+ tev_type=TEV_DTMF_2;
+ break;
+ case '3':
+ tev_type=TEV_DTMF_3;
+ break;
+ case '4':
+ tev_type=TEV_DTMF_4;
+ break;
+ case '5':
+ tev_type=TEV_DTMF_5;
+ break;
+ case '6':
+ tev_type=TEV_DTMF_6;
+ break;
+ case '7':
+ tev_type=TEV_DTMF_7;
+ break;
+ case '8':
+ tev_type=TEV_DTMF_8;
+ break;
+ case '9':
+ tev_type=TEV_DTMF_9;
+ break;
+ case '*':
+ tev_type=TEV_DTMF_STAR;
+ break;
+ case '0':
+ tev_type=TEV_DTMF_0;
+ break;
+ case '#':
+ tev_type=TEV_DTMF_POUND;
+ break;
+ default:
+ g_warning("Bad dtmf: %c.",dtmf);
+ return -1;
+ }
+
+ m1=rtp_session_create_telephone_event_packet(session,1);
+ if (m1==NULL) return -1;
+ rtp_session_add_telephone_event(session,m1,tev_type,0,0,160);
+ /* create a second packet */
+ m2=rtp_session_create_telephone_event_packet(session,0);
+ if (m2==NULL) return -1;
+ rtp_session_add_telephone_event(session,m2,tev_type,0,0,320);
+
+ /* create a third and final packet */
+ m3=rtp_session_create_telephone_event_packet(session,0);
+ if (m3==NULL) return -1;
+ rtp_session_add_telephone_event(session,m3,tev_type,1,0,480);
+
+ /* and now sends them */
+ rtp_session_sendm_with_ts(session,m1,userts);
+ rtp_session_sendm_with_ts(session,m2,userts);
+ /* the last packet is sent three times in order to improve reliability*/
+ m1=copymsg(m3);
+ m2=copymsg(m3);
+ /* NOTE: */
+ /* we need to copymsg() instead of dupmsg() because the buffers are modified when
+ the packet is sended because of the host-to-network conversion of timestamp,ssrc, csrc, and
+ seq number.
+ It could be avoided by making a copy of the buffer when sending physically the packet, but
+ it add one more copy for every buffer.
+ Using iomapped socket, it is possible to avoid the user to kernel copy.
+ */
+ rtp_session_sendm_with_ts(session,m3,userts);
+ rtp_session_sendm_with_ts(session,m1,userts);
+ rtp_session_sendm_with_ts(session,m2,userts);
+ return 0;
+}
+
+/**
+ *rtp_session_read_telephone_event:
+ *@session: a rtp session from which telephony events are received.
+ *@packet: a rtp packet as a mblk_t.
+ *@tab: the address of a pointer.
+ *
+ * Reads telephony events from a rtp packet. *@tab points to the beginning of the event buffer.
+ *
+ *Returns: the number of events in the packet if successfull, 0 if the packet did not
+ * contain telephony events.
+**/
+gint rtp_session_read_telephone_event(RtpSession *session,
+ mblk_t *packet,telephone_event_t **tab)
+{
+ int datasize;
+ gint num;
+ int i;
+ telephone_event_t *tev;
+ rtp_header_t *hdr=(rtp_header_t*)packet->b_rptr;
+ g_return_val_if_fail(packet->b_cont!=NULL,-1);
+ if (hdr->paytype!=session->telephone_events_pt) return 0; /* this is not tel ev.*/
+ datasize=msgdsize(packet);
+ tev=*tab=(telephone_event_t*)packet->b_cont->b_rptr;
+ /* convert from network to host order what should be */
+ num=datasize/sizeof(telephone_event_t);
+ for (i=0;i<num;i++)
+ {
+ tev[i].duration=ntohs(tev[i].duration);
+ }
+ return num;
+}
+
+
+static void notify_events_ended(RtpSession *session, telephone_event_t *events, int num){
+ int i;
+ for (i=0;i<num;i++){
+ if (events[i].E==1){
+ rtp_signal_table_emit2(&session->on_telephone_event,(gpointer)(long)events[i].event);
+ }
+ }
+}
+
+/* for high level telephony event callback */
+void rtp_session_check_telephone_events(RtpSession *session, mblk_t *m0)
+{
+ telephone_event_t *events,*evbuf;
+ int num;
+ int i;
+ mblk_t *mp;
+ rtp_header_t *hdr;
+ mblk_t *cur_tev;
+
+ hdr=(rtp_header_t*)m0->b_rptr;
+ mp=m0->b_cont;
+
+ num=(mp->b_wptr-mp->b_rptr)/sizeof(telephone_event_t);
+ events=(telephone_event_t*)mp->b_rptr;
+
+
+ if (hdr->markbit==1)
+ {
+ /* this is a start of new events. Store the event buffer for later use*/
+ if (session->current_tev!=NULL) {
+ freemsg(session->current_tev);
+ session->current_tev=NULL;
+ }
+ session->current_tev=copymsg(m0);
+ /* handle the case where the events are short enough to end within the packet that has the marker bit*/
+ notify_events_ended(session,events,num);
+ }
+ /* whatever there is a markbit set or not, we parse the packet and compare it to previously received one */
+ cur_tev=session->current_tev;
+ if (cur_tev!=NULL)
+ {
+ /* first compare timestamp, they must be identical */
+ if (((rtp_header_t*)cur_tev->b_rptr)->timestamp==
+ ((rtp_header_t*)m0->b_rptr)->timestamp)
+ {
+ evbuf=(telephone_event_t*)cur_tev->b_cont;
+ for (i=0;i<num;i++)
+ {
+ if (events[i].E==1)
+ {
+ /* update events that have ended */
+ if (evbuf[i].E==0){
+ evbuf[i].E=1;
+ /* this is a end of event, report it */
+ rtp_signal_table_emit2(&session->on_telephone_event,(gpointer)(long)events[i].event);
+ }
+ }
+ }
+ }
+ else
+ {
+ /* timestamp are not identical: this is not the same events*/
+ if (session->current_tev!=NULL) {
+ freemsg(session->current_tev);
+ session->current_tev=NULL;
+ }
+ session->current_tev=dupmsg(m0);
+ }
+ }
+ else
+ {
+ /* there is no pending events, but we did not received marked bit packet
+ either the sending implementation is not compliant, either it has been lost,
+ we must deal with it anyway.*/
+ session->current_tev=copymsg(m0);
+ /* inform the application if there are tone ends */
+ notify_events_ended(session,events,num);
+ }
+}
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/telephonyevents.h b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/telephonyevents.h
new file mode 100644
index 00000000..6f6936d5
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/telephonyevents.h
@@ -0,0 +1,98 @@
+/*
+ The oRTP library is an RTP (Realtime Transport Protocol - rfc1889) stack.
+ Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef TELEPHONYEVENTS_H
+#define TELEPHONYEVENTS_H
+
+
+#include <rtpsession.h>
+
+
+struct _telephone_event
+{
+#ifdef WORDS_BIGENDIAN
+ guint32 event:8;
+ guint32 E:1;
+ guint32 R:1;
+ guint32 volume:6;
+ guint32 duration:16;
+#else
+ guint32 event:8;
+ guint32 volume:6;
+ guint32 R:1;
+ guint32 E:1;
+ guint32 duration:16;
+#endif
+};
+
+typedef struct _telephone_event telephone_event_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern PayloadType telephone_event;
+
+/* tell if the session supports telephony events. For this the telephony events payload_type
+ must be present in the rtp profile used by the session */
+
+/* low level functions */
+gint rtp_session_telephone_events_supported(RtpSession *session);
+
+mblk_t *rtp_session_create_telephone_event_packet(RtpSession *session, int start);
+
+gint rtp_session_add_telephone_event(RtpSession *session,
+ mblk_t *packet, guchar event, gint end, guchar volume, guint16 duration);
+
+gint rtp_session_read_telephone_event(RtpSession *session,
+ mblk_t *packet,telephone_event_t **tab);
+
+/* high level functions*/
+gint rtp_session_send_dtmf(RtpSession *session, gchar dtmf, guint32 userts);
+/* for high level telephony event callback */
+void rtp_session_check_telephone_events(RtpSession *session, mblk_t *m0);
+
+#ifdef __cplusplus
+}
+#endif
+
+/* the size allocated for telephony events packets */
+#define TELEPHONY_EVENTS_ALLOCATED_SIZE (4*sizeof(telephone_event_t))
+
+/* list of named events */
+#define TEV_DTMF_0 (0)
+#define TEV_DTMF_1 (1)
+#define TEV_DTMF_2 (2)
+#define TEV_DTMF_3 (3)
+#define TEV_DTMF_4 (4)
+#define TEV_DTMF_5 (5)
+#define TEV_DTMF_6 (6)
+#define TEV_DTMF_7 (7)
+#define TEV_DTMF_8 (8)
+#define TEV_DTMF_9 (9)
+#define TEV_DTMF_STAR (10)
+#define TEV_DTMF_POUND (11)
+#define TEV_DTMF_A (12)
+#define TEV_DTMF_B (13)
+#define TEV_DTMF_C (14)
+#define TEV_DTMF_D (15)
+#define TEV_FLASH (16)
+
+
+#endif
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/utils.c b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/utils.c
new file mode 100644
index 00000000..1ae601f4
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/utils.c
@@ -0,0 +1,44 @@
+/***************************************************************************
+ * utils.c
+ *
+ * Wed Feb 23 14:15:36 2005
+ * Copyright 2005 Simon Morlat
+ * Email simon.morlat@linphone.org
+ ****************************************************************************/
+/*
+ The oRTP library is an RTP (Realtime Transport Protocol - rfc1889) stack.
+ Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <rtpport.h>
+#include "utils.h"
+
+OList *o_list_new(void *data){
+ OList *new_elem=g_new0(OList,1);
+ new_elem->data=data;
+ return new_elem;
+}
+
+OList * o_list_append(OList *elem, void * data){
+ OList *new_elem=o_list_new(data);
+ OList *it=elem;
+ if (elem==NULL) return new_elem;
+ while (it->next!=NULL) it=o_list_next(it);
+ it->next=new_elem;
+ new_elem->prev=it;
+ return elem;
+}
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/utils.h b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/utils.h
new file mode 100644
index 00000000..7b71daf8
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/utils.h
@@ -0,0 +1,43 @@
+/***************************************************************************
+ * utils.h
+ *
+ * Wed Feb 23 14:15:36 2005
+ * Copyright 2005 Simon Morlat
+ * Email simon.morlat@linphone.org
+ ****************************************************************************/
+/*
+ The oRTP library is an RTP (Realtime Transport Protocol - rfc1889) stack.
+ Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef UTILS_H
+#define UTILS_H
+
+struct _OList {
+ struct _OList *next;
+ struct _OList *prev;
+ void *data;
+};
+
+typedef struct _OList OList;
+
+
+#define o_list_next(elem) ((elem)->next)
+
+OList * o_list_append(OList *elem, void * data);
+
+#endif
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/CMakeLists.txt b/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/CMakeLists.txt
new file mode 100644
index 00000000..8b2e72d4
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/xmllite/CMakeLists.txt
@@ -0,0 +1,28 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+add_definitions(
+ -DPOSIX
+)
+
+include_directories(
+ ${CMAKE_CURRENT_SOURCE_DIR}/../..
+ ${TQT_INCLUDE_DIRS}
+)
+
+
+##### cricketxmllite (static) ###################
+
+tde_add_library( cricketxmllite STATIC_PIC
+ SOURCES
+ qname.cc xmlbuilder.cc xmlconstants.cc xmlelement.cc xmlnsstack.cc
+ xmlparser.cc xmlprinter.cc
+)
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/xmpp/CMakeLists.txt b/kopete/protocols/jabber/jingle/libjingle/talk/xmpp/CMakeLists.txt
new file mode 100644
index 00000000..c68cc840
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/xmpp/CMakeLists.txt
@@ -0,0 +1,29 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+add_definitions(
+ -DPOSIX
+)
+
+include_directories(
+ ${CMAKE_CURRENT_SOURCE_DIR}/../..
+ ${CMAKE_BINARY_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+
+##### cricketxmpp (static) ######################
+
+tde_add_library( cricketxmpp STATIC_PIC
+ SOURCES
+ constants.cc jid.cc saslmechanism.cc xmppclient.cc xmppengineimpl.cc
+ xmppengineimpl_iq.cc xmpplogintask.cc xmppstanzaparser.cc xmpptask.cc
+)
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/xmpp/xmpppassword.h b/kopete/protocols/jabber/jingle/libjingle/talk/xmpp/xmpppassword.h
index f431b4e5..7a58cd6c 100644
--- a/kopete/protocols/jabber/jingle/libjingle/talk/xmpp/xmpppassword.h
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/xmpp/xmpppassword.h
@@ -31,6 +31,8 @@
#include "talk/base/linked_ptr.h"
#include "talk/base/scoped_ptr.h"
+#include <cstring>
+
namespace buzz {
class XmppPasswordImpl {
diff --git a/kopete/protocols/jabber/kioslave/CMakeLists.txt b/kopete/protocols/jabber/kioslave/CMakeLists.txt
new file mode 100644
index 00000000..12fa4173
--- /dev/null
+++ b/kopete/protocols/jabber/kioslave/CMakeLists.txt
@@ -0,0 +1,42 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/..
+ ${CMAKE_CURRENT_SOURCE_DIR}/../libiris/iris/include
+ ${CMAKE_CURRENT_SOURCE_DIR}/../libiris/iris/jabber
+ ${CMAKE_CURRENT_SOURCE_DIR}/../libiris/iris/xmpp-im
+ ${CMAKE_CURRENT_SOURCE_DIR}/../libiris/cutestuff/util
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+link_directories(
+ ${TQT_LIBRARY_DIRS}
+)
+
+
+##### other data ################################
+
+install( FILES jabberdisco.protocol DESTINATION ${SERVICES_INSTALL_DIR} )
+
+
+##### kio_jabberdisco (module) ##################
+
+tde_add_kpart( kio_jabberdisco AUTOMOC
+ SOURCES jabberdisco.cpp
+ LINK
+ jabberclient-static
+ iris_xmpp_core-static iris_xmpp_im-static iris_jabber-static iris-static
+ qca-static cutestuff_network-static cutestuff_util-static kio-shared
+ DESTINATION ${PLUGIN_INSTALL_DIR}
+)
diff --git a/kopete/protocols/jabber/libiris/CMakeLists.txt b/kopete/protocols/jabber/libiris/CMakeLists.txt
new file mode 100644
index 00000000..6c649aa5
--- /dev/null
+++ b/kopete/protocols/jabber/libiris/CMakeLists.txt
@@ -0,0 +1,14 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+add_subdirectory( iris )
+add_subdirectory( qca )
+add_subdirectory( cutestuff )
diff --git a/kopete/protocols/jabber/libiris/cutestuff/CMakeLists.txt b/kopete/protocols/jabber/libiris/cutestuff/CMakeLists.txt
new file mode 100644
index 00000000..4f8cce38
--- /dev/null
+++ b/kopete/protocols/jabber/libiris/cutestuff/CMakeLists.txt
@@ -0,0 +1,13 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+add_subdirectory( network )
+add_subdirectory( util )
diff --git a/kopete/protocols/jabber/libiris/cutestuff/network/CMakeLists.txt b/kopete/protocols/jabber/libiris/cutestuff/network/CMakeLists.txt
new file mode 100644
index 00000000..151dd407
--- /dev/null
+++ b/kopete/protocols/jabber/libiris/cutestuff/network/CMakeLists.txt
@@ -0,0 +1,27 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/../util
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../qca/src
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+
+##### cutestuff_network (static) ################
+
+tde_add_library( cutestuff_network STATIC_PIC AUTOMOC
+ SOURCES
+ bsocket.cpp httpconnect.cpp httppoll.cpp ndns.cpp servsock.cpp
+ socks.cpp srvresolver.cpp
+)
diff --git a/kopete/protocols/jabber/libiris/cutestuff/util/CMakeLists.txt b/kopete/protocols/jabber/libiris/cutestuff/util/CMakeLists.txt
new file mode 100644
index 00000000..13d55ca8
--- /dev/null
+++ b/kopete/protocols/jabber/libiris/cutestuff/util/CMakeLists.txt
@@ -0,0 +1,24 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+
+##### cutestuff_util (static) ###################
+
+tde_add_library( cutestuff_util STATIC_PIC AUTOMOC
+ SOURCES
+ base64.cpp bytestream.cpp qrandom.cpp safedelete.cpp sha1.cpp
+ showtextdlg.cpp
+)
diff --git a/kopete/protocols/jabber/libiris/iris/CMakeLists.txt b/kopete/protocols/jabber/libiris/iris/CMakeLists.txt
new file mode 100644
index 00000000..d5062694
--- /dev/null
+++ b/kopete/protocols/jabber/libiris/iris/CMakeLists.txt
@@ -0,0 +1,15 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+add_subdirectory( include )
+add_subdirectory( jabber )
+add_subdirectory( xmpp-core )
+add_subdirectory( xmpp-im )
diff --git a/kopete/protocols/jabber/libiris/iris/include/CMakeLists.txt b/kopete/protocols/jabber/libiris/iris/include/CMakeLists.txt
new file mode 100644
index 00000000..ff84643b
--- /dev/null
+++ b/kopete/protocols/jabber/libiris/iris/include/CMakeLists.txt
@@ -0,0 +1,24 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+
+##### iris (static) #############################
+
+tde_moc( SRCS im.h xmpp.h )
+
+tde_add_library( iris STATIC_PIC
+ SOURCES ${SRCS}
+)
diff --git a/kopete/protocols/jabber/libiris/iris/jabber/CMakeLists.txt b/kopete/protocols/jabber/libiris/iris/jabber/CMakeLists.txt
new file mode 100644
index 00000000..e73563f2
--- /dev/null
+++ b/kopete/protocols/jabber/libiris/iris/jabber/CMakeLists.txt
@@ -0,0 +1,40 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/../include
+ ${CMAKE_CURRENT_SOURCE_DIR}/../xmpp-im
+ ${CMAKE_CURRENT_SOURCE_DIR}/../xmpp-core
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../cutestuff/util
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../cutestuff/network
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../qca/src
+ ${CMAKE_BINARY_DIR}
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+
+##### iris_jabber (static) ######################
+
+add_custom_command( OUTPUT s5b.moc
+ COMMAND ${TMOC_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/s5b.cpp -o s5b.moc.cpp
+ COMMAND ${TMOC_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/s5b.h -o s5b.moc.h
+ COMMAND sed -i -e '/^\#include/d' s5b.moc.cpp
+ COMMAND cat s5b.moc.h s5b.moc.cpp > s5b.moc
+ DEPENDS s5b.cpp )
+
+set_source_files_properties( s5b.cpp PROPERTIES OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/s5b.moc )
+
+tde_add_library( iris_jabber STATIC_PIC AUTOMOC
+ SOURCES
+ filetransfer.cpp s5b.cpp xmpp_ibb.cpp xmpp_jidlink.cpp all_mocs.cpp
+)
diff --git a/kopete/protocols/jabber/libiris/iris/xmpp-core/CMakeLists.txt b/kopete/protocols/jabber/libiris/iris/xmpp-core/CMakeLists.txt
new file mode 100644
index 00000000..4361f30e
--- /dev/null
+++ b/kopete/protocols/jabber/libiris/iris/xmpp-core/CMakeLists.txt
@@ -0,0 +1,38 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/../include
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../qca/src
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../cutestuff/util
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../cutestuff/network
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+
+##### iris_xmpp_core (static) ########################
+
+add_custom_command( OUTPUT securestream.moc
+ COMMAND ${TMOC_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/securestream.cpp -o securestream.moc.cpp
+ COMMAND ${TMOC_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/securestream.h -o securestream.moc.h
+ COMMAND sed -i -e '/^\#include/d' securestream.moc.cpp
+ COMMAND cat securestream.moc.h securestream.moc.cpp > securestream.moc
+ DEPENDS securestream.cpp )
+
+set_source_files_properties( securestream.cpp PROPERTIES OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/securestream.moc )
+
+tde_add_library( iris_xmpp_core STATIC_PIC
+ SOURCES
+ connector.cpp jid.cpp securestream.cpp tlshandler.cpp hash.cpp
+ protocol.cpp stream.cpp xmlprotocol.cpp parser.cpp simplesasl.cpp
+)
diff --git a/kopete/protocols/jabber/libiris/iris/xmpp-im/CMakeLists.txt b/kopete/protocols/jabber/libiris/iris/xmpp-im/CMakeLists.txt
new file mode 100644
index 00000000..58a1a034
--- /dev/null
+++ b/kopete/protocols/jabber/libiris/iris/xmpp-im/CMakeLists.txt
@@ -0,0 +1,37 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/../include
+ ${CMAKE_CURRENT_SOURCE_DIR}/../jabber
+ ${CMAKE_CURRENT_SOURCE_DIR}/../xmpp-core
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../cutestuff/util
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+
+##### iris_xmpp_im (static) #####################
+
+add_custom_command( OUTPUT types.moc
+ COMMAND ${TMOC_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/types.cpp -o types.moc
+ COMMAND sed -i -e '/^\#include \"/d' types.moc
+ DEPENDS types.cpp )
+
+set_source_files_properties( types.cpp PROPERTIES OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/types.moc )
+
+tde_moc( MOCS xmpp_tasks.h )
+
+tde_add_library( iris_xmpp_im STATIC_PIC
+ SOURCES
+ client.cpp types.cpp xmpp_tasks.cpp xmpp_vcard.cpp xmpp_xmlcommon.cpp ${MOCS}
+)
diff --git a/kopete/protocols/jabber/libiris/qca/CMakeLists.txt b/kopete/protocols/jabber/libiris/qca/CMakeLists.txt
new file mode 100644
index 00000000..7356f221
--- /dev/null
+++ b/kopete/protocols/jabber/libiris/qca/CMakeLists.txt
@@ -0,0 +1,12 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+add_subdirectory( src )
diff --git a/kopete/protocols/jabber/libiris/qca/src/CMakeLists.txt b/kopete/protocols/jabber/libiris/qca/src/CMakeLists.txt
new file mode 100644
index 00000000..46de2435
--- /dev/null
+++ b/kopete/protocols/jabber/libiris/qca/src/CMakeLists.txt
@@ -0,0 +1,22 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+
+##### qca (static) ##############################
+
+tde_add_library( qca STATIC_PIC AUTOMOC
+ SOURCES qca.cpp
+)
diff --git a/kopete/protocols/jabber/ui/CMakeLists.txt b/kopete/protocols/jabber/ui/CMakeLists.txt
new file mode 100644
index 00000000..a4488d62
--- /dev/null
+++ b/kopete/protocols/jabber/ui/CMakeLists.txt
@@ -0,0 +1,43 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR}/../../../libkopete/ui
+ ${CMAKE_CURRENT_SOURCE_DIR}/..
+ ${CMAKE_CURRENT_SOURCE_DIR}/../libiris/iris/include
+ ${CMAKE_CURRENT_SOURCE_DIR}/../libiris/iris/jabber
+ ${CMAKE_CURRENT_SOURCE_DIR}/../libiris/iris/xmpp-im
+ ${CMAKE_CURRENT_SOURCE_DIR}/../libiris/qca/src
+ ${CMAKE_CURRENT_SOURCE_DIR}/../libiris/cutestuff/util
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../libkopete
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../libkopete/ui
+ ${CMAKE_BINARY_DIR}
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+
+##### kopetejabberui (static) ###################
+
+tde_add_library( kopetejabberui STATIC_PIC AUTOMOC
+ SOURCES
+ dlgsendraw.ui dlgjabbersendraw.cpp dlgaddcontact.ui
+ jabberaddcontactpage.cpp dlgvcard.ui dlgjabbervcard.cpp
+ dlgjabberservices.cpp dlgregister.ui dlgjabberregister.cpp
+ dlgbrowse.ui dlgjabberbrowse.cpp dlgjabbereditaccountwidget.ui
+ jabbereditaccountwidget.cpp dlgjabberregisteraccount.ui
+ jabberregisteraccount.cpp dlgjabberchooseserver.ui
+ jabberchooseserver.cpp dlgchangepassword.ui
+ dlgjabberchangepassword.cpp empty.cpp dlgchatroomslist.ui
+ dlgjabberchatroomslist.cpp dlgchatjoin.ui dlgjabberchatjoin.cpp
+ dlgservices.ui
+)
diff --git a/kopete/protocols/meanwhile/CMakeLists.txt b/kopete/protocols/meanwhile/CMakeLists.txt
new file mode 100644
index 00000000..994f6e31
--- /dev/null
+++ b/kopete/protocols/meanwhile/CMakeLists.txt
@@ -0,0 +1,47 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+include( ConfigureChecks.cmake )
+
+add_subdirectory( ui )
+add_subdirectory( icons )
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR}/ui
+ ${CMAKE_BINARY_DIR}/kopete/libkopete/ui
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete/ui
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+ ${MEANWHILE_INCLUDE_DIRS}
+)
+
+link_directories(
+ ${TQT_LIBRARY_DIRS}
+)
+
+
+##### other data ################################
+
+install( FILES kopete_meanwhile.desktop DESTINATION ${SERVICES_INSTALL_DIR} )
+
+
+##### new_target0 (module) #######################
+
+tde_add_kpart( new_target0 AUTOMOC
+ SOURCES
+ meanwhileprotocol.cpp meanwhileaddcontactpage.cpp
+ meanwhileeditaccountwidget.cpp meanwhileaccount.cpp
+ meanwhilecontact.cpp meanwhilesession.cpp meanwhileplugin.cpp
+ LINK kopetemeanwhileui-static kopete-shared ${MEANWHILE_LIBRARIES}
+ DESTINATION ${PLUGIN_INSTALL_DIR}
+)
diff --git a/kopete/protocols/meanwhile/ConfigureChecks.cmake b/kopete/protocols/meanwhile/ConfigureChecks.cmake
new file mode 100644
index 00000000..58d8c67f
--- /dev/null
+++ b/kopete/protocols/meanwhile/ConfigureChecks.cmake
@@ -0,0 +1,15 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+pkg_search_module( MEANWHILE meanwhile )
+if( NOT MEANWHILE_FOUND )
+ tde_message_fatal( "meanwhile is required, but was not found on your system" )
+endif( )
diff --git a/kopete/protocols/meanwhile/icons/CMakeLists.txt b/kopete/protocols/meanwhile/icons/CMakeLists.txt
new file mode 100644
index 00000000..ba51467b
--- /dev/null
+++ b/kopete/protocols/meanwhile/icons/CMakeLists.txt
@@ -0,0 +1,12 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+tde_install_icons( DESTINATION ${DATA_INSTALL_DIR}/kopete/icons )
diff --git a/kopete/protocols/meanwhile/ui/CMakeLists.txt b/kopete/protocols/meanwhile/ui/CMakeLists.txt
new file mode 100644
index 00000000..434f849b
--- /dev/null
+++ b/kopete/protocols/meanwhile/ui/CMakeLists.txt
@@ -0,0 +1,27 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_BINARY_DIR}/kopete/libkopete/ui
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete/ui
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+
+##### kopetemeanwhileui (static) ################
+
+tde_add_library( kopetemeanwhileui STATIC_PIC AUTOMOC
+ SOURCES
+ empty.cpp meanwhileeditaccountbase.ui meanwhileaddcontactbase.ui
+)
diff --git a/kopete/protocols/msn/CMakeLists.txt b/kopete/protocols/msn/CMakeLists.txt
new file mode 100644
index 00000000..77bd2cc7
--- /dev/null
+++ b/kopete/protocols/msn/CMakeLists.txt
@@ -0,0 +1,71 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+add_subdirectory( ui )
+add_subdirectory( icons )
+add_subdirectory( config )
+
+if( WITH_WEBCAM )
+ add_subdirectory( webcam )
+ add_definitions( -DMSN_WEBCAM )
+ set( WEBCAM_LIBRARIES mimicwrapper-static kopete_videodevice-shared ${GLIB2_LIBRARIES} )
+endif( )
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR}/ui
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/ui
+ ${CMAKE_CURRENT_SOURCE_DIR}/webcam
+ ${CMAKE_BINARY_DIR}
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete/ui
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+link_directories(
+ ${TQT_LIBRARY_DIRS}
+)
+
+
+##### other data ################################
+
+install( FILES kopete_msn.desktop DESTINATION ${SERVICES_INSTALL_DIR} )
+install( FILES msnchatui.rc DESTINATION ${DATA_INSTALL_DIR}/kopete_msn )
+
+
+##### kopete_msn (module) #######################
+
+tde_add_kpart( kopete_msn AUTOMOC
+ SOURCES
+ dummy.cpp webcam.cpp
+ LINK kopete_msn_shared-shared
+ DESTINATION ${PLUGIN_INSTALL_DIR}
+)
+
+
+##### kopete_msn_shared (shared) ################
+
+tde_add_library( kopete_msn_shared SHARED AUTOMOC
+ SOURCES
+ msnprotocol.cpp msnaccount.cpp msnaddcontactpage.cpp msncontact.cpp
+ msnsocket.cpp msnchatsession.cpp msndebugrawcmddlg.cpp
+ msnnotifysocket.cpp msnswitchboardsocket.cpp
+ msnfiletransfersocket.cpp msninvitation.cpp sha1.cpp
+ msnsecureloginhandler.cpp msnchallengehandler.cpp
+ dispatcher.cpp p2p.cpp messageformatter.cpp incomingtransfer.cpp
+ outgoingtransfer.cpp webcam.cpp
+ VERSION 0.0.0
+ LINK
+ kopetemsnui-static ${WEBCAM_LIBRARIES} kopete-shared
+ DESTINATION ${LIB_INSTALL_DIR}
+)
diff --git a/kopete/protocols/msn/config/CMakeLists.txt b/kopete/protocols/msn/config/CMakeLists.txt
new file mode 100644
index 00000000..7e0d1337
--- /dev/null
+++ b/kopete/protocols/msn/config/CMakeLists.txt
@@ -0,0 +1,38 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+link_directories(
+ ${TQT_LIBRARY_DIRS}
+)
+
+
+##### other data ################################
+
+install( FILES
+ kopete_msn_config.desktop
+ DESTINATION ${SERVICES_INSTALL_DIR}/kconfiguredialog )
+
+
+##### kcm_kopete_msn (module) ###################
+
+tde_add_kpart( kcm_kopete_msn AUTOMOC
+ SOURCES
+ msnprefs.ui msnpreferences.cpp
+ LINK kopete-shared
+ DESTINATION ${PLUGIN_INSTALL_DIR}
+)
diff --git a/kopete/protocols/msn/icons/CMakeLists.txt b/kopete/protocols/msn/icons/CMakeLists.txt
new file mode 100644
index 00000000..ba51467b
--- /dev/null
+++ b/kopete/protocols/msn/icons/CMakeLists.txt
@@ -0,0 +1,12 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+tde_install_icons( DESTINATION ${DATA_INSTALL_DIR}/kopete/icons )
diff --git a/kopete/protocols/msn/ui/CMakeLists.txt b/kopete/protocols/msn/ui/CMakeLists.txt
new file mode 100644
index 00000000..bd70ce80
--- /dev/null
+++ b/kopete/protocols/msn/ui/CMakeLists.txt
@@ -0,0 +1,29 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/..
+ ${CMAKE_BINARY_DIR}/kopete/libkopete/ui
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete/ui
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+
+##### kopetemsnui (static) ######################
+
+tde_add_library( kopetemsnui STATIC_PIC AUTOMOC
+ SOURCES
+ msnadd.ui msndebugrawcommand_base.ui msninfo.ui msneditaccountui.ui
+ msneditaccountwidget.cpp
+)
diff --git a/kopete/protocols/msn/webcam/CMakeLists.txt b/kopete/protocols/msn/webcam/CMakeLists.txt
new file mode 100644
index 00000000..aafa2d94
--- /dev/null
+++ b/kopete/protocols/msn/webcam/CMakeLists.txt
@@ -0,0 +1,28 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+add_subdirectory( libmimic )
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+ ${GLIB2_INCLUDE_DIRS}
+)
+
+
+##### mimicwrapper (static) #####################
+
+tde_add_library( mimicwrapper STATIC_PIC AUTOMOC
+ SOURCES mimicwrapper.cpp msnwebcamdialog.cpp
+ LINK mimic-static
+)
diff --git a/kopete/protocols/msn/webcam/libmimic/CMakeLists.txt b/kopete/protocols/msn/webcam/libmimic/CMakeLists.txt
new file mode 100644
index 00000000..d98fc837
--- /dev/null
+++ b/kopete/protocols/msn/webcam/libmimic/CMakeLists.txt
@@ -0,0 +1,23 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+include_directories(
+ ${GLIB2_INCLUDE_DIRS}
+)
+
+
+##### mimic (static) ############################
+
+tde_add_library( mimic STATIC_PIC
+ SOURCES
+ mimic.c encode.c decode.c bitstring.c vlc_common.c vlc_encode.c
+ vlc_decode.c fdct_quant.c idct_dequant.c colorspace.c deblock.c
+)
diff --git a/kopete/protocols/oscar/CMakeLists.txt b/kopete/protocols/oscar/CMakeLists.txt
new file mode 100644
index 00000000..bbffa100
--- /dev/null
+++ b/kopete/protocols/oscar/CMakeLists.txt
@@ -0,0 +1,42 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+add_subdirectory( liboscar )
+add_subdirectory( aim )
+add_subdirectory( icq )
+add_subdirectory( icons )
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/liboscar
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+link_directories(
+ ${TQT_LIBRARY_DIRS}
+)
+
+
+##### kopete_oscar (shared) #####################
+
+tde_add_library( kopete_oscar SHARED AUTOMOC
+ SOURCES
+ oscaraccount.cpp oscarcontact.cpp oscarmyselfcontact.cpp
+ oscarencodingselectionbase.ui oscarencodingselectiondialog.cpp
+ oscarlistcontactsbase.ui oscarlistnonservercontacts.cpp
+ oscarvisibilitybase.ui oscarvisibilitydialog.cpp
+ oscarversionupdater.cpp
+ VERSION 2.0.0
+ LINK oscar-static kopete-shared
+ DESTINATION ${LIB_INSTALL_DIR}
+)
diff --git a/kopete/protocols/oscar/aim/CMakeLists.txt b/kopete/protocols/oscar/aim/CMakeLists.txt
new file mode 100644
index 00000000..75230df3
--- /dev/null
+++ b/kopete/protocols/oscar/aim/CMakeLists.txt
@@ -0,0 +1,47 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+add_subdirectory( ui )
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR}/ui
+ ${CMAKE_CURRENT_SOURCE_DIR}/ui
+ ${CMAKE_CURRENT_SOURCE_DIR}/..
+ ${CMAKE_CURRENT_SOURCE_DIR}/../liboscar
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete/ui
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+link_directories(
+ ${TQT_LIBRARY_DIRS}
+)
+
+
+##### other data ################################
+
+install( FILES
+ kopete_aim.desktop aim.protocol
+ DESTINATION ${SERVICES_INSTALL_DIR} )
+
+
+##### kopete_aim (module) #######################
+
+tde_add_kpart( kopete_aim AUTOMOC
+ SOURCES
+ aimprotocol.cpp aimaccount.cpp aimcontact.cpp aimuserinfo.cpp
+ aimjoinchat.cpp aimchatsession.cpp
+ LINK
+ kopeteaimui-static kopete_oscar-shared
+ DESTINATION ${PLUGIN_INSTALL_DIR}
+)
diff --git a/kopete/protocols/oscar/aim/ui/CMakeLists.txt b/kopete/protocols/oscar/aim/ui/CMakeLists.txt
new file mode 100644
index 00000000..8f5ff329
--- /dev/null
+++ b/kopete/protocols/oscar/aim/ui/CMakeLists.txt
@@ -0,0 +1,31 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/..
+ ${CMAKE_CURRENT_SOURCE_DIR}/../..
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../liboscar
+ ${CMAKE_BINARY_DIR}/kopete/libkopete/ui
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete/ui
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+
+##### kopeteaimui (static) ######################
+
+tde_add_library( kopeteaimui STATIC_PIC AUTOMOC
+ SOURCES
+ aimaddcontactui.ui aimeditaccountui.ui aiminfobase.ui
+ aimjoinchatbase.ui aimaddcontactpage.cpp aimeditaccountwidget.cpp
+)
diff --git a/kopete/protocols/oscar/icons/CMakeLists.txt b/kopete/protocols/oscar/icons/CMakeLists.txt
new file mode 100644
index 00000000..ba51467b
--- /dev/null
+++ b/kopete/protocols/oscar/icons/CMakeLists.txt
@@ -0,0 +1,12 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+tde_install_icons( DESTINATION ${DATA_INSTALL_DIR}/kopete/icons )
diff --git a/kopete/protocols/oscar/icq/CMakeLists.txt b/kopete/protocols/oscar/icq/CMakeLists.txt
new file mode 100644
index 00000000..20f8b11a
--- /dev/null
+++ b/kopete/protocols/oscar/icq/CMakeLists.txt
@@ -0,0 +1,45 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+add_subdirectory( ui )
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/ui
+ ${CMAKE_CURRENT_SOURCE_DIR}/..
+ ${CMAKE_CURRENT_SOURCE_DIR}/../liboscar
+ ${CMAKE_BINARY_DIR}
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete/ui
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+link_directories(
+ ${TQT_LIBRARY_DIRS}
+)
+
+
+##### other data ################################
+
+install( FILES kopete_icq.desktop DESTINATION ${SERVICES_INSTALL_DIR} )
+install( FILES x-icq.desktop DESTINATION ${MIME_INSTALL_DIR}/application )
+
+
+##### kopete_icq (module) #######################
+
+tde_add_kpart( kopete_icq AUTOMOC
+ SOURCES
+ icqpresence.cpp icqaccount.cpp icqcontact.cpp icqprotocol.cpp
+ LINK
+ kopeteicqui-static kopete_oscar-shared
+ DESTINATION ${PLUGIN_INSTALL_DIR}
+)
diff --git a/kopete/protocols/oscar/icq/ui/CMakeLists.txt b/kopete/protocols/oscar/icq/ui/CMakeLists.txt
new file mode 100644
index 00000000..9da3ac25
--- /dev/null
+++ b/kopete/protocols/oscar/icq/ui/CMakeLists.txt
@@ -0,0 +1,34 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/..
+ ${CMAKE_CURRENT_SOURCE_DIR}/../..
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../liboscar
+ ${CMAKE_BINARY_DIR}/kopete/libkopete/ui
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete/ui
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+
+##### kopeteicqui (static) ######################
+
+tde_add_library( kopeteicqui STATIC_PIC AUTOMOC
+ SOURCES
+ icqadd.ui icqeditaccountui.ui icqeditaccountwidget.cpp
+ icqgeneralinfo.ui icqotherinfowidget.ui icqworkinfowidget.ui
+ icqinterestinfowidget.ui icquserinfowidget.cpp icqauthreplyui.ui
+ icqauthreplydialog.cpp icqaddcontactpage.cpp icqsearchbase.ui
+ icqsearchdialog.cpp
+)
diff --git a/kopete/protocols/oscar/liboscar/CMakeLists.txt b/kopete/protocols/oscar/liboscar/CMakeLists.txt
new file mode 100644
index 00000000..6053541f
--- /dev/null
+++ b/kopete/protocols/oscar/liboscar/CMakeLists.txt
@@ -0,0 +1,46 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_BINARY_DIR}
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+
+##### oscar (static) ############################
+
+tde_add_library( oscar STATIC_PIC AUTOMOC
+ SOURCES
+ oscarutils.cpp client.cpp task.cpp connector.cpp
+ inputprotocolbase.cpp coreprotocol.cpp flapprotocol.cpp
+ snacprotocol.cpp transfer.cpp rtf.cc bytestream.cpp
+ oscarclientstream.cpp safedelete.cpp stream.cpp oscarconnector.cpp
+ oscarbytestream.cpp buffer.cpp md5.c logintask.cpp aimlogintask.cpp
+ icqlogintask.cpp closeconnectiontask.cpp rateclassmanager.cpp
+ serverversionstask.cpp rateinfotask.cpp errortask.cpp
+ locationrightstask.cpp profiletask.cpp blmlimitstask.cpp
+ servicesetuptask.cpp icbmparamstask.cpp ssimanager.cpp rateclass.cpp
+ rateclass.h prmparamstask.cpp ssiparamstask.cpp ssilisttask.cpp
+ ssiactivatetask.cpp clientreadytask.cpp senddcinfotask.cpp
+ sendidletimetask.cpp ownuserinfotask.cpp connection.cpp
+ onlinenotifiertask.cpp userdetails.cpp ssimodifytask.cpp
+ oscartypeclasses.cpp oscarmessage.cpp messagereceivertask.cpp
+ sendmessagetask.cpp icqtask.cpp offlinemessagestask.cpp
+ ssiauthtask.cpp userinfotask.cpp icquserinfo.cpp icquserinfotask.cpp
+ usersearchtask.cpp warningtask.cpp changevisibilitytask.cpp
+ typingnotifytask.cpp buddyicontask.cpp serverredirecttask.cpp
+ oscarsettings.cpp chatnavservicetask.cpp connectionhandler.cpp
+ chatservicetask.cpp
+)
diff --git a/kopete/protocols/sms/CMakeLists.txt b/kopete/protocols/sms/CMakeLists.txt
new file mode 100644
index 00000000..017ae01e
--- /dev/null
+++ b/kopete/protocols/sms/CMakeLists.txt
@@ -0,0 +1,48 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+add_subdirectory( ui )
+add_subdirectory( services )
+add_subdirectory( icons )
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR}/ui
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/services
+ ${CMAKE_BINARY_DIR}
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete/ui
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+link_directories(
+ ${TQT_LIBRARY_DIRS}
+)
+
+
+##### other data ################################
+
+install( FILES kopete_sms.desktop DESTINATION ${SERVICES_INSTALL_DIR} )
+
+
+##### kopete_sms (module) #######################
+
+tde_add_kpart( kopete_sms AUTOMOC
+ SOURCES
+ smsaddcontactpage.cpp smscontact.cpp smseditaccountwidget.cpp
+ smsprotocol.cpp serviceloader.cpp smsservice.cpp
+ smsuserpreferences.cpp smsaccount.cpp
+ LINK
+ kopetesmsui-static kopetesmsservices-static kopete-shared
+ DESTINATION ${PLUGIN_INSTALL_DIR}
+)
diff --git a/kopete/protocols/sms/icons/CMakeLists.txt b/kopete/protocols/sms/icons/CMakeLists.txt
new file mode 100644
index 00000000..ba51467b
--- /dev/null
+++ b/kopete/protocols/sms/icons/CMakeLists.txt
@@ -0,0 +1,12 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+tde_install_icons( DESTINATION ${DATA_INSTALL_DIR}/kopete/icons )
diff --git a/kopete/protocols/sms/services/CMakeLists.txt b/kopete/protocols/sms/services/CMakeLists.txt
new file mode 100644
index 00000000..c9942bd6
--- /dev/null
+++ b/kopete/protocols/sms/services/CMakeLists.txt
@@ -0,0 +1,32 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+# FIXME KDE_CXXFLAGS = $(USE_EXCEPTIONS)
+
+include( ConfigureChecks.cmake )
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/..
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+
+##### kopetesmsservices (static) ################
+
+tde_add_library( kopetesmsservices STATIC_PIC AUTOMOC
+ SOURCES
+ smssend.cpp smssendprefs.ui smssendprovider.cpp smsclient.cpp
+ smsclientprefs.ui gsmlib.cpp gsmlibprefs.ui kopete_unix_serial.cpp
+ LINK ${GSM_LIBRARY}
+)
diff --git a/kopete/protocols/sms/services/ConfigureChecks.cmake b/kopete/protocols/sms/services/ConfigureChecks.cmake
new file mode 100644
index 00000000..4ed454b4
--- /dev/null
+++ b/kopete/protocols/sms/services/ConfigureChecks.cmake
@@ -0,0 +1,30 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+if( WITH_GSM )
+
+ tde_save( CMAKE_REQUIRED_INCLUDES )
+ set( CMAKE_REQUIRED_INCLUDES ${TQT_INCLUDE_DIRS} )
+ check_include_file_cxx( gsmlib/gsm_util.h HAVE_GSMLIB_GSM_UTIL_H )
+ tde_restore( CMAKE_REQUIRED_INCLUDES )
+
+ if( HAVE_GSMLIB_GSM_UTIL_H )
+ set( INCLUDE_SMSGSM 1 )
+ find_library( GSM_LIBRARY gsmme )
+ endif( )
+
+ if( NOT (HAVE_GSMLIB_GSM_UTIL_H AND GSM_LIBRARY) )
+ tde_message_fatal( "gsmlib is required, but was not found on your system" )
+ endif( )
+
+endif( )
+
+configure_file( config.h.cmake config.h @ONLY )
diff --git a/kopete/protocols/sms/services/config.h.cmake b/kopete/protocols/sms/services/config.h.cmake
new file mode 100644
index 00000000..9555d535
--- /dev/null
+++ b/kopete/protocols/sms/services/config.h.cmake
@@ -0,0 +1 @@
+#cmakedefine INCLUDE_SMSGSM 1
diff --git a/kopete/protocols/sms/ui/CMakeLists.txt b/kopete/protocols/sms/ui/CMakeLists.txt
new file mode 100644
index 00000000..619f7a88
--- /dev/null
+++ b/kopete/protocols/sms/ui/CMakeLists.txt
@@ -0,0 +1,24 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+
+##### kopetesmsui (static) ######################
+
+tde_add_library( kopetesmsui STATIC_PIC AUTOMOC
+ SOURCES
+ smsadd.ui smsactprefs.ui smsuserprefs.ui empty.cpp
+)
diff --git a/kopete/protocols/testbed/CMakeLists.txt b/kopete/protocols/testbed/CMakeLists.txt
new file mode 100644
index 00000000..6052845a
--- /dev/null
+++ b/kopete/protocols/testbed/CMakeLists.txt
@@ -0,0 +1,44 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+add_subdirectory( icons )
+add_subdirectory( ui )
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/ui
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete/ui
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+link_directories(
+ ${TQT_LIBRARY_DIRS}
+)
+
+
+##### other data ################################
+
+install( FILES kopete_testbed.desktop DESTINATION ${SERVICES_INSTALL_DIR} )
+
+
+##### kopete_testbed (module) ###################
+
+tde_add_kpart( kopete_testbed AUTOMOC
+ SOURCES
+ testbedprotocol.cpp testbedcontact.cpp testbedaccount.cpp
+ testbedaddcontactpage.cpp testbedaddui.ui
+ testbededitaccountwidget.cpp testbedaccountpreferences.ui
+ testbedfakeserver.cpp testbedincomingmessage.cpp
+ LINK kopetetestbedui-static kopete-shared kopete_videodevice-shared
+ DESTINATION ${PLUGIN_INSTALL_DIR}
+)
diff --git a/kopete/protocols/testbed/icons/CMakeLists.txt b/kopete/protocols/testbed/icons/CMakeLists.txt
new file mode 100644
index 00000000..ba51467b
--- /dev/null
+++ b/kopete/protocols/testbed/icons/CMakeLists.txt
@@ -0,0 +1,12 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+tde_install_icons( DESTINATION ${DATA_INSTALL_DIR}/kopete/icons )
diff --git a/kopete/protocols/testbed/testbedaccount.h b/kopete/protocols/testbed/testbedaccount.h
index 52261cb7..b58249c6 100644
--- a/kopete/protocols/testbed/testbedaccount.h
+++ b/kopete/protocols/testbed/testbedaccount.h
@@ -59,7 +59,7 @@ public:
/**
* 'Connect' to the testbed server. Only sets myself() online.
*/
- virtual void connect( const Kopete::OnlineStatus& initialStatus = Kopete::OnlineStatus::OnlineStatus() );
+ virtual void connect( const Kopete::OnlineStatus& initialStatus = Kopete::OnlineStatus() );
/**
* Disconnect from the server. Only sets myself() offline.
*/
diff --git a/kopete/protocols/testbed/ui/CMakeLists.txt b/kopete/protocols/testbed/ui/CMakeLists.txt
new file mode 100644
index 00000000..febe5b7b
--- /dev/null
+++ b/kopete/protocols/testbed/ui/CMakeLists.txt
@@ -0,0 +1,25 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_BINARY_DIR}
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+
+##### kopetetestbedui (static) ##################
+
+tde_add_library( kopetetestbedui STATIC_PIC AUTOMOC
+ SOURCES testbedwebcamdialog.cpp
+)
diff --git a/kopete/protocols/winpopup/CMakeLists.txt b/kopete/protocols/winpopup/CMakeLists.txt
new file mode 100644
index 00000000..e80e8e51
--- /dev/null
+++ b/kopete/protocols/winpopup/CMakeLists.txt
@@ -0,0 +1,51 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+add_subdirectory( ui )
+add_subdirectory( icons )
+add_subdirectory( libwinpopup )
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR}/ui
+ ${CMAKE_CURRENT_SOURCE_DIR}/libwinpopup
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete/ui
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+link_directories(
+ ${TQT_LIBRARY_DIRS}
+)
+
+
+##### other data ################################
+
+install( FILES
+ kopete_wp.desktop
+ DESTINATION ${SERVICES_INSTALL_DIR} )
+
+install( PROGRAMS
+ winpopup-send.sh winpopup-install.sh
+ DESTINATION ${BIN_INSTALL_DIR} )
+
+
+##### kopete_wp (module) ########################
+
+tde_add_kpart( kopete_wp AUTOMOC
+ SOURCES
+ wpprotocol.cpp wpcontact.cpp wpaddcontact.cpp wpeditaccount.cpp
+ wpaccount.cpp wpuserinfo.cpp
+ LINK
+ kopetewpui-static winpopup-static kopete-shared
+ DESTINATION ${PLUGIN_INSTALL_DIR}
+)
diff --git a/kopete/protocols/winpopup/icons/CMakeLists.txt b/kopete/protocols/winpopup/icons/CMakeLists.txt
new file mode 100644
index 00000000..ba51467b
--- /dev/null
+++ b/kopete/protocols/winpopup/icons/CMakeLists.txt
@@ -0,0 +1,12 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+tde_install_icons( DESTINATION ${DATA_INSTALL_DIR}/kopete/icons )
diff --git a/kopete/protocols/winpopup/libwinpopup/CMakeLists.txt b/kopete/protocols/winpopup/libwinpopup/CMakeLists.txt
new file mode 100644
index 00000000..4f11898b
--- /dev/null
+++ b/kopete/protocols/winpopup/libwinpopup/CMakeLists.txt
@@ -0,0 +1,24 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+
+##### winpopup (static) #########################
+
+tde_add_library( winpopup STATIC_PIC AUTOMOC
+ SOURCES libwinpopup.cpp
+)
diff --git a/kopete/protocols/winpopup/ui/CMakeLists.txt b/kopete/protocols/winpopup/ui/CMakeLists.txt
new file mode 100644
index 00000000..d73253ce
--- /dev/null
+++ b/kopete/protocols/winpopup/ui/CMakeLists.txt
@@ -0,0 +1,25 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+
+##### kopetewpui (static) #######################
+
+tde_add_library( kopetewpui STATIC_PIC AUTOMOC
+ SOURCES
+ wpaddcontactbase.ui wpeditaccountbase.ui empty.cpp
+ wpuserinfowidget.ui
+)
diff --git a/kopete/protocols/yahoo/CMakeLists.txt b/kopete/protocols/yahoo/CMakeLists.txt
new file mode 100644
index 00000000..124fc32a
--- /dev/null
+++ b/kopete/protocols/yahoo/CMakeLists.txt
@@ -0,0 +1,49 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+add_subdirectory( libkyahoo )
+add_subdirectory( ui )
+add_subdirectory( icons )
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR}/ui
+ ${CMAKE_BINARY_DIR}/kopete/libkopete/ui
+ ${CMAKE_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/libkyahoo
+ ${CMAKE_CURRENT_SOURCE_DIR}/ui
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete/ui
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+link_directories(
+ ${TQT_LIBRARY_DIRS}
+)
+
+
+##### other data ################################
+
+install( FILES yahooconferenceui.rc yahoochatui.rc DESTINATION ${DATA_INSTALL_DIR}/kopete_yahoo )
+install( FILES kopete_yahoo.desktop DESTINATION ${SERVICES_INSTALL_DIR} )
+
+
+##### kopete_yahoo (module) #####################
+
+tde_add_kpart( kopete_yahoo AUTOMOC
+ SOURCES
+ yahooprotocol.cpp yahooeditaccount.cpp yahooaddcontact.cpp
+ yahooaccount.cpp yahoocontact.cpp yahooconferencemessagemanager.cpp
+ yahoochatsession.cpp yahooverifyaccount.cpp yahoowebcam.cpp
+ LINK kyahoo-static kopeteyahooui-static kopeteui-static kopete-shared kopete_videodevice-shared
+ DESTINATION ${PLUGIN_INSTALL_DIR}
+)
diff --git a/kopete/protocols/yahoo/icons/CMakeLists.txt b/kopete/protocols/yahoo/icons/CMakeLists.txt
new file mode 100644
index 00000000..ba51467b
--- /dev/null
+++ b/kopete/protocols/yahoo/icons/CMakeLists.txt
@@ -0,0 +1,12 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+tde_install_icons( DESTINATION ${DATA_INSTALL_DIR}/kopete/icons )
diff --git a/kopete/protocols/yahoo/libkyahoo/CMakeLists.txt b/kopete/protocols/yahoo/libkyahoo/CMakeLists.txt
new file mode 100644
index 00000000..a4ba8ba0
--- /dev/null
+++ b/kopete/protocols/yahoo/libkyahoo/CMakeLists.txt
@@ -0,0 +1,48 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+include( ConfigureChecks.cmake )
+
+if( HAVE_INTTYPES_H )
+ add_definitions( -DHAVE_INTTYPES_H )
+elseif( HAVE_STDINT_H )
+ add_definitions( -DHAVE_STDINT_H )
+endif()
+
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_BINARY_DIR}
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+
+##### kyahoo (static) ###########################
+
+tde_add_library( kyahoo STATIC_PIC AUTOMOC
+ SOURCES
+ client.cpp task.cpp connector.cpp inputprotocolbase.cpp
+ ymsgprotocol.cpp ymsgtransfer.cpp transfer.cpp
+ yahoobytestream.cpp bytestream.cpp yahooclientstream.cpp
+ yahooconnector.cpp safedelete.cpp stream.cpp sha1.c
+ md5.c crypt.c coreprotocol.cpp logintask.cpp libyahoo.c
+ yahoo_fn.c listtask.cpp statusnotifiertask.cpp
+ mailnotifiertask.cpp messagereceivertask.cpp
+ sendnotifytask.cpp sendmessagetask.cpp logofftask.cpp
+ changestatustask.cpp modifybuddytask.cpp picturenotifiertask.cpp
+ requestpicturetask.cpp yahoobuddyiconloader.cpp
+ stealthtask.cpp sendpicturetask.cpp webcamtask.cpp
+ conferencetask.cpp sendauthresptask.cpp pingtask.cpp
+ yabtask.cpp yabentry.cpp modifyyabtask.cpp chatsessiontask.cpp
+ sendfiletask.cpp filetransfernotifiertask.cpp
+ receivefiletask.cpp yahoochattask.cpp
+)
diff --git a/kopete/protocols/yahoo/libkyahoo/ConfigureChecks.cmake b/kopete/protocols/yahoo/libkyahoo/ConfigureChecks.cmake
new file mode 100644
index 00000000..e7af0c6c
--- /dev/null
+++ b/kopete/protocols/yahoo/libkyahoo/ConfigureChecks.cmake
@@ -0,0 +1,16 @@
+#################################################
+#
+# (C) 2010 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+check_include_file( inttypes.h HAVE_INTTYPES_H )
+check_include_file( stdint.h HAVE_STDINT_H )
+
+check_include_file( string.h HAVE_STRING_H )
+check_include_file( strings.h HAVE_STRINGS_H )
diff --git a/kopete/protocols/yahoo/ui/CMakeLists.txt b/kopete/protocols/yahoo/ui/CMakeLists.txt
new file mode 100644
index 00000000..4da1fb8a
--- /dev/null
+++ b/kopete/protocols/yahoo/ui/CMakeLists.txt
@@ -0,0 +1,30 @@
+#################################################
+#
+# (C) 2010-2011 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+include_directories(
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/..
+ ${CMAKE_SOURCE_DIR}/kopete/libkopete
+ ${TDE_INCLUDE_DIR}
+ ${TQT_INCLUDE_DIRS}
+)
+
+
+##### kopeteyahooui (static) ####################
+
+tde_add_library( kopeteyahooui STATIC_PIC AUTOMOC
+ SOURCES
+ yahooadd.ui yahooeditaccountbase.ui yahooinvitelistbase.ui
+ yahooinvitelistimpl.cpp empty.cpp yahooverifyaccountbase.ui
+ yahoostealthsetting.ui yahoowebcamdialog.cpp yahoogeneralinfowidget.ui
+ yahoouserinfodialog.cpp yahooworkinfowidget.ui
+ yahoootherinfowidget.ui
+)