diff options
Diffstat (limited to 'kopete/protocols')
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,¶m); +		*/ +	} +} + +#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 +)  | 
