lightmelody

changeset 742:d448df1b7665

Merged objectify branch to default
author Arc Riley <arcriley@gmail.com>
date Mon, 15 Dec 2014 05:04:57 +0000
parents bdcb548baf22 3d0dd0aa24fc
children 77f1dcc38add
files .hgignore examples/test-dns.c include/loudmouth/lm-connection.h include/loudmouth/lm-error.h include/loudmouth/lm-message-handler.h include/loudmouth/lm-proxy.h python/_G.c python/__init__.c python/pylm.h python/wscript_build src/lm-asyncns-resolver.c src/lm-asyncns-resolver.h src/lm-blocking-resolver.c src/lm-blocking-resolver.h src/lm-connection.c src/lm-debug.c src/lm-debug.h src/lm-error.c src/lm-message-handler.c src/lm-old-socket.c src/lm-old-socket.h src/lm-proxy.c src/lm-resolver.c src/lm-resolver.h src/lm-sasl.c src/lm-sasl.h src/lm-simple-io.c src/lm-simple-io.h src/lm-xmpp-writer.c src/lm-xmpp-writer.h src/wscript_build vapi/loudmouth.vapi
diffstat 90 files changed, 1734 insertions(+), 8857 deletions(-) [+]
line diff
     1.1 --- a/.hgignore	Wed Dec 25 20:33:47 2013 -0500
     1.2 +++ b/.hgignore	Mon Dec 15 05:04:57 2014 +0000
     1.3 @@ -7,3 +7,4 @@
     1.4  __pycache__
     1.5  *.orig
     1.6  *.backup
     1.7 +genie.pyc
     2.1 --- a/examples/lm-change-password.c	Wed Dec 25 20:33:47 2013 -0500
     2.2 +++ b/examples/lm-change-password.c	Mon Dec 15 05:04:57 2014 +0000
     2.3 @@ -1,5 +1,5 @@
     2.4  /*
     2.5 - *  Copyright (C) 2012 Copyleft Games Group
     2.6 + *  Copyright (C) 2012,2013,2014 Copyleft Games Group
     2.7   *  Copyright (C) 2004 Imendio AB
     2.8   *
     2.9   *  This program is free software; you can redistribute it and/or modify
     3.1 --- a/examples/lm-register.c	Wed Dec 25 20:33:47 2013 -0500
     3.2 +++ b/examples/lm-register.c	Mon Dec 15 05:04:57 2014 +0000
     3.3 @@ -1,5 +1,5 @@
     3.4  /*
     3.5 - *  Copyright (C) 2012 Copyleft Games Group
     3.6 + *  Copyright (C) 2012,2013,2014 Copyleft Games Group
     3.7   *  Copyright (C) 2004 Imendio AB
     3.8   *
     3.9   *  This program is free software; you can redistribute it and/or modify
     4.1 --- a/examples/lm-send-async.c	Wed Dec 25 20:33:47 2013 -0500
     4.2 +++ b/examples/lm-send-async.c	Mon Dec 15 05:04:57 2014 +0000
     4.3 @@ -1,5 +1,5 @@
     4.4  /*
     4.5 - *  Copyright (C) 2012 Copyleft Games Group
     4.6 + *  Copyright (C) 2012,2013,2014 Copyleft Games Group
     4.7   *  Copyright (C) 2003-2006 Imendio AB
     4.8   *
     4.9   *  This program is free software; you can redistribute it and/or modify
     5.1 --- a/examples/test-dns.c	Wed Dec 25 20:33:47 2013 -0500
     5.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.3 @@ -1,81 +0,0 @@
     5.4 -/*
     5.5 - *  Copyright (C) 2012 Copyleft Games Group
     5.6 - *
     5.7 - *  This program is free software; you can redistribute it and/or modify
     5.8 - *  it under the terms of the GNU Affero General Public License as published
     5.9 - *  by the Free Software Foundation, either version 3 of the License, or
    5.10 - *  (at your option) any later version.
    5.11 - *
    5.12 - *  This program is distributed in the hope that it will be useful,
    5.13 - *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    5.14 - *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    5.15 - *  GNU Affero General Public License for more details.
    5.16 - *
    5.17 - *  You should have received a copy of the GNU Affero General Public License
    5.18 - *  along with this program; if not, see http://www.gnu.org/licenses
    5.19 - *
    5.20 - */
    5.21 -
    5.22 -#include <lightmelody.h>
    5.23 -#include "lm-blocking-resolver.h"
    5.24 -
    5.25 -GMainLoop *main_loop;
    5.26 -
    5.27 -static void
    5.28 -resolver_result_cb (LmResolver       *resolver,
    5.29 -                    LmResolverResult  result,
    5.30 -                    gpointer          user_data)
    5.31 -{
    5.32 -    gchar           *host;
    5.33 -    struct addrinfo *addr;
    5.34 -
    5.35 -    g_object_get (resolver, "host", &host, NULL);
    5.36 -
    5.37 -    if (result != LM_RESOLVER_RESULT_OK) {
    5.38 -        g_print ("Failed to lookup %s\n", host);
    5.39 -        g_free (host);
    5.40 -        return;
    5.41 -    }
    5.42 -
    5.43 -    g_print ("In %s\n", G_STRFUNC);
    5.44 -
    5.45 -    while ((addr = lm_resolver_results_get_next (resolver))) {
    5.46 -        g_print ("Result!\n");
    5.47 -    }
    5.48 -
    5.49 -    g_free (host);
    5.50 -
    5.51 -    g_main_loop_quit (main_loop);
    5.52 -}
    5.53 -
    5.54 -int
    5.55 -main (int argc, char **argv)
    5.56 -{
    5.57 -#if 0
    5.58 -    LmResolver *resolver;
    5.59 -#endif
    5.60 -    LmResolver *srv_resolver;
    5.61 -
    5.62 -    g_type_init ();
    5.63 -#if 0
    5.64 -    resolver = lm_resolver_new_for_host ("kenny.imendio.com",
    5.65 -                                         resolver_result_cb,
    5.66 -                                         NULL);
    5.67 -    lm_resolver_lookup (resolver);
    5.68 -#endif
    5.69 -
    5.70 -    srv_resolver = lm_resolver_new_for_service ("jabber.org",
    5.71 -                                                "xmpp-client", "tcp",
    5.72 -                                                resolver_result_cb,
    5.73 -                                                NULL);
    5.74 -    lm_resolver_lookup (srv_resolver);
    5.75 -
    5.76 -    g_print ("Running main loop\n");
    5.77 -
    5.78 -    main_loop = g_main_loop_new (NULL, FALSE);
    5.79 -    g_main_loop_run (main_loop);
    5.80 -
    5.81 -    g_print ("Finished\n");
    5.82 -
    5.83 -    return 0;
    5.84 -}
     6.1 --- a/examples/test-http-proxy.c	Wed Dec 25 20:33:47 2013 -0500
     6.2 +++ b/examples/test-http-proxy.c	Mon Dec 15 05:04:57 2014 +0000
     6.3 @@ -1,5 +1,5 @@
     6.4  /*
     6.5 - *  Copyright (C) 2012 Copyleft Games Group
     6.6 + *  Copyright (C) 2012,2013,2014 Copyleft Games Group
     6.7   *  Copyright (C) 2004 Imendio AB
     6.8   *
     6.9   *  This program is free software; you can redistribute it and/or modify
     7.1 --- a/examples/test-jingle.gs	Wed Dec 25 20:33:47 2013 -0500
     7.2 +++ b/examples/test-jingle.gs	Mon Dec 15 05:04:57 2014 +0000
     7.3 @@ -1,5 +1,5 @@
     7.4  /*
     7.5 - *  Copyright (C) 2012 Copyleft Games Group
     7.6 + *  Copyright (C) 2012,2013,2014 Copyleft Games Group
     7.7   *
     7.8   *  This program is free software; you can redistribute it and/or modify
     7.9   *  it under the terms of the GNU Affero General Public License as published
    7.10 @@ -28,11 +28,11 @@
    7.11      
    7.12      print "LightMelody Jingle Test"
    7.13      var conn = new Lm.Connection("jabber.de")
    7.14 -    conn.set_port(5222)
    7.15 +    conn.port = 5222
    7.16  
    7.17      conn.jid = user
    7.18  
    7.19 -    conn.set_keep_alive_rate(3)
    7.20 +    conn.keep_alive_rate = 3
    7.21  
    7.22      if conn.open_and_block()
    7.23          if conn.authenticate_and_block(user, pwd, "lm-jingle-test")
     8.1 --- a/examples/test-lm.c	Wed Dec 25 20:33:47 2013 -0500
     8.2 +++ b/examples/test-lm.c	Mon Dec 15 05:04:57 2014 +0000
     8.3 @@ -1,5 +1,5 @@
     8.4  /*
     8.5 - *  Copyright (C) 2012 Copyleft Games Group
     8.6 + *  Copyright (C) 2012,2013,2014 Copyleft Games Group
     8.7   *  Copyright (C) 2003-2006 Imendio AB
     8.8   *
     8.9   *  This program is free software; you can redistribute it and/or modify
     9.1 --- a/examples/test-tunnel.c	Wed Dec 25 20:33:47 2013 -0500
     9.2 +++ b/examples/test-tunnel.c	Mon Dec 15 05:04:57 2014 +0000
     9.3 @@ -1,5 +1,5 @@
     9.4  /*
     9.5 - *  Copyright (C) 2012 Copyleft Games Group
     9.6 + *  Copyright (C) 2012,2013,2014 Copyleft Games Group
     9.7   *  Copyright (C) 2003-2004 Imendio AB
     9.8   *
     9.9   *  This program is free software; you can redistribute it and/or modify
    10.1 --- a/examples/wscript_build	Wed Dec 25 20:33:47 2013 -0500
    10.2 +++ b/examples/wscript_build	Mon Dec 15 05:04:57 2014 +0000
    10.3 @@ -1,7 +1,7 @@
    10.4  # encoding: utf-8
    10.5  #
    10.6  #   LightMelody - Lightweight XMPP/Jingle Client Library
    10.7 -#   Copyright (C) 2012 Copyleft Games Group
    10.8 +#   Copyright (C) 2012,2013,2014 Copyleft Games Group
    10.9  #
   10.10  #   This program is free software; you can redistribute it and/or modify
   10.11  #   it under the terms of the GNU Affero General Public License as published
   10.12 @@ -23,7 +23,7 @@
   10.13      source      = bld.path.ant_glob('test-jingle.gs'),
   10.14      vapi_dirs   = '../vapi',
   10.15      use         = 'lightmelody',
   10.16 -    packages    = ['config', 'lightmelody-1', 'nice'],
   10.17 +    packages    = ['config', 'lightmelody-1', 'gee-0.8', 'nice'],
   10.18      includes    = '../include ../build/src',
   10.19      cflags      = ['-g'],
   10.20      uselib      = ['GLIB', 'GEE', 'IDN', 'SSL', 'ASYNCNS', 'GIO'],
    11.1 --- a/genie.py	Wed Dec 25 20:33:47 2013 -0500
    11.2 +++ b/genie.py	Mon Dec 15 05:04:57 2014 +0000
    11.3 @@ -2,7 +2,7 @@
    11.4  # encoding: utf-8
    11.5  # Ali Sabil, 2007
    11.6  # Radosław Szkodziński, 2010
    11.7 -# Arc Riley, 2010, 2011, 2012
    11.8 +# Arc Riley, 2010, 2011, 2012, 2013, 2014
    11.9  
   11.10  """
   11.11  At this point, vala is still unstable, so do not expect
   11.12 @@ -15,240 +15,243 @@
   11.13  from waflib.Configure import conf
   11.14  
   11.15  class valac(Task.Task):
   11.16 -	"""
   11.17 -	Task to compile vala files.
   11.18 -	"""
   11.19 -	vars = ["VALAC", "VALAC_VERSION", "VALAFLAGS"]
   11.20 -	ext_out = ['.h']
   11.21 +    """
   11.22 +    Task to compile vala files.
   11.23 +    """
   11.24 +    vars = ["VALAC", "VALAC_VERSION", "VALAFLAGS"]
   11.25 +    ext_out = ['.h']
   11.26  
   11.27 -	def run(self):
   11.28 -		env = self.env
   11.29 +    def run(self):
   11.30 +        env = self.env
   11.31  
   11.32 -		cmd = [env['VALAC'], '-C', '--quiet']
   11.33 -		cmd.extend(Utils.to_list(env['VALAFLAGS']))
   11.34 +        cmd=self.env.VALAC + self.env.VALAFLAGS
   11.35  
   11.36 -		if self.threading:
   11.37 -			cmd.append('--thread')
   11.38 +        if self.threading:
   11.39 +            cmd.append('--thread')
   11.40  
   11.41 -		if self.profile:
   11.42 -			cmd.append('--profile=%s' % self.profile)
   11.43 +        if self.profile:
   11.44 +            cmd.append('--profile=%s' % self.profile)
   11.45  
   11.46 -		if self.target_glib:
   11.47 -			cmd.append('--target-glib=%s' % self.target_glib)
   11.48 +        if self.target_glib:
   11.49 +            cmd.append('--target-glib=%s' % self.target_glib)
   11.50  
   11.51 -		if self.is_lib:
   11.52 -			output_dir = self.outputs[0].bld_dir()
   11.53 -			cmd.append('--library=' + self.target)
   11.54 -			for x in self.outputs:
   11.55 -				if x.name.endswith('.h'):
   11.56 -					cmd.append('--header=' + x.name)
   11.57 -			if self.gir:
   11.58 -				cmd.append('--gir=%s.gir' % self.gir)
   11.59 +        if self.is_lib:
   11.60 +            output_dir = self.outputs[0].bld_dir()
   11.61 +            cmd.append('--includedir=' + self.name)
   11.62 +            cmd.append('--library=' + self.target)
   11.63 +            cmd.append('--header=%s.h' % (self.target))
   11.64 +            if self.gir:
   11.65 +                cmd.append('--gir=%s.gir' % self.gir)
   11.66  
   11.67 -		for vapi_dir in self.vapi_dirs:
   11.68 -			cmd.append('--vapidir=%s' % vapi_dir)
   11.69 +        for vapi_dir in self.vapi_dirs:
   11.70 +            cmd.append('--vapidir=%s' % vapi_dir)
   11.71  
   11.72 -		for package in self.packages:
   11.73 -			cmd.append('--pkg=%s' % package)
   11.74 +        for package in self.packages:
   11.75 +            cmd.append('--pkg=%s' % package)
   11.76  
   11.77 -		for package in self.packages_private:
   11.78 -			cmd.append('--pkg=%s' % package)
   11.79 +        for package in self.packages_private:
   11.80 +            cmd.append('--pkg=%s' % package)
   11.81  
   11.82 -		for define in self.vala_defines:
   11.83 -			cmd.append('--define=%s' % define)
   11.84 +        for define in self.vala_defines:
   11.85 +            cmd.append('--define=%s' % define)
   11.86  
   11.87 -		cmd.extend([a.abspath() for a in self.inputs])
   11.88 -		ret = self.exec_command(cmd, cwd=self.outputs[0].parent.abspath())
   11.89 +        cmd.extend([a.abspath() for a in self.inputs])
   11.90 +        ret = self.exec_command(cmd, cwd=self.outputs[0].parent.abspath())
   11.91  
   11.92 -		if ret:
   11.93 -			return ret
   11.94 +        if ret:
   11.95 +            return ret
   11.96  
   11.97 -		for x in self.outputs:
   11.98 -			if id(x.parent) != id(self.outputs[0].parent):
   11.99 -				shutil.move(self.outputs[0].parent.abspath() + os.sep + x.name, x.abspath())
  11.100 +        for x in self.outputs:
  11.101 +            if id(x.parent) != id(self.outputs[0].parent):
  11.102 +                shutil.move(self.outputs[0].parent.abspath() + os.sep + x.name,
  11.103 +                            x.abspath())
  11.104  
  11.105 -		if self.packages and getattr(self, 'deps_node', None):
  11.106 -			self.deps_node.write('\n'.join(self.packages))
  11.107 +        if self.packages and getattr(self, 'deps_node', None):
  11.108 +            self.deps_node.write('\n'.join(self.packages))
  11.109  
  11.110 -		return ret
  11.111 +        return ret
  11.112  
  11.113  @extension('.vala', '.gs')
  11.114  def vala_file(self, node):
  11.115 -	"""
  11.116 -	Compile a vala file and bind the task to *self.valatask*. If an existing vala task is already set, add the node
  11.117 -	to its inputs. The typical example is::
  11.118 +    """
  11.119 +    Compile a vala file and bind the task to *self.valatask*. If an existing vala task is already set, add the node
  11.120 +    to its inputs. The typical example is::
  11.121  
  11.122 -		def build(bld):
  11.123 -			bld.program(
  11.124 -				packages      = 'gtk+-2.0',
  11.125 -				target        = 'vala-gtk-example',
  11.126 -				uselib        = 'GTK GLIB',
  11.127 -				source        = 'vala-gtk-example.vala foo.vala',
  11.128 -				vala_defines  = ['DEBUG']
  11.129 -				# the following arguments are for libraries
  11.130 -				#gir          = 'hello-1.0',
  11.131 -				#gir_path     = '/tmp',
  11.132 -				#vapi_path = '/tmp',
  11.133 -				#pkg_name = 'hello'
  11.134 -			)
  11.135 +        def build(bld):
  11.136 +            bld.program(
  11.137 +                packages      = 'gtk+-2.0',
  11.138 +                target        = 'vala-gtk-example',
  11.139 +                uselib        = 'GTK GLIB',
  11.140 +                source        = 'vala-gtk-example.vala foo.vala',
  11.141 +                vala_defines  = ['DEBUG']
  11.142 +                # the following arguments are for libraries
  11.143 +                #gir          = 'hello-1.0',
  11.144 +                #gir_path     = '/tmp',
  11.145 +                #vapi_path = '/tmp',
  11.146 +                #pkg_name = 'hello'
  11.147 +            )
  11.148  
  11.149  
  11.150 -	:param node: vala file
  11.151 -	:type node: :py:class:`waflib.Node.Node`
  11.152 -	"""
  11.153 -	# TODO: the vala task should use self.generator.attribute instead of copying attributes from self to the task
  11.154 -	valatask = getattr(self, "valatask", None)
  11.155 -	# there is only one vala task and it compiles all vala files .. :-/
  11.156 -	if not valatask:
  11.157 -		def _get_api_version():
  11.158 -			api_version = getattr (Context.g_module, 'API_VERSION', None)
  11.159 -			if api_version == None:
  11.160 -				version = Context.g_module.VERSION.split(".")
  11.161 -				if version[0] == "0":
  11.162 -					api_version = "0." + version[1]
  11.163 -				else:
  11.164 -					api_version = version[0]
  11.165 -			return api_version
  11.166 +    :param node: vala file
  11.167 +    :type node: :py:class:`waflib.Node.Node`
  11.168 +    """
  11.169 +    # TODO: the vala task should use self.generator.attribute instead of copying attributes from self to the task
  11.170 +    valatask = getattr(self, "valatask", None)
  11.171 +    # there is only one vala task and it compiles all vala files .. :-/
  11.172 +    if not valatask:
  11.173 +        def _get_api_version():
  11.174 +            api_version = getattr (Context.g_module, 'API_VERSION', None)
  11.175 +            if api_version == None:
  11.176 +                version = Context.g_module.VERSION.split(".")
  11.177 +                if version[0] == "0":
  11.178 +                    api_version = "0." + version[1]
  11.179 +                else:
  11.180 +                    api_version = version[0]
  11.181 +            return api_version
  11.182  
  11.183 -		valatask = self.create_task('valac')
  11.184 -		self.valatask = valatask # this assumes one vala task by task generator
  11.185 -		self.includes = Utils.to_list(getattr(self, 'includes', []))
  11.186 -		self.uselib = self.to_list(getattr(self, 'uselib', []))
  11.187 -		valatask.packages = []
  11.188 -		valatask.packages_private = Utils.to_list(getattr(self, 'packages_private', []))
  11.189 -		valatask.vapi_dirs = []
  11.190 -		valatask.target = self.target
  11.191 -		valatask.threading = False
  11.192 -		valatask.install_path = getattr(self, 'install_path', '')
  11.193 -		valatask.profile = getattr(self, 'profile', 'gobject')
  11.194 -		valatask.vala_defines = getattr(self, 'vala_defines', [])
  11.195 -		valatask.target_glib = None
  11.196 -		valatask.gir = getattr(self, 'gir', None)
  11.197 -		valatask.gir_path = getattr(self, 'gir_path', '${DATAROOTDIR}/gir-1.0')
  11.198 -		valatask.vapi_path = getattr(self, 'vapi_path', '${DATAROOTDIR}/vala/vapi')
  11.199 -		valatask.pkg_name = getattr(self, 'pkg_name', self.env['PACKAGE'])
  11.200 -		valatask.header_path = getattr(self, 'header_path', '${INCLUDEDIR}/%s-%s' % (valatask.pkg_name, _get_api_version()))
  11.201 +        valatask = self.create_task('valac')
  11.202 +        self.valatask = valatask # this assumes one vala task by task generator
  11.203 +        self.includes = Utils.to_list(getattr(self, 'includes', []))
  11.204 +        self.uselib = self.to_list(getattr(self, 'uselib', []))
  11.205 +        valatask.packages = []
  11.206 +        valatask.packages_private = Utils.to_list(getattr(self, 'packages_private', []))
  11.207 +        valatask.vapi_dirs = []
  11.208 +        valatask.name = self.name
  11.209 +        valatask.target = self.target
  11.210 +        valatask.threading = False
  11.211 +        valatask.install_path = getattr(self, 'install_path', '')
  11.212 +        valatask.profile = getattr(self, 'profile', 'gobject')
  11.213 +        valatask.vala_defines = getattr(self, 'vala_defines', [])
  11.214 +        valatask.target_glib = None
  11.215 +        valatask.gir = getattr(self, 'gir', None)
  11.216 +        valatask.gir_path = getattr(self, 'gir_path', '${DATAROOTDIR}/gir-1.0')
  11.217 +        valatask.vapi_path = getattr(self, 'vapi_path', '${DATAROOTDIR}/vala/vapi')
  11.218 +        valatask.pkg_name = getattr(self, 'pkg_name', self.env['PACKAGE'])
  11.219 +        valatask.header_path = getattr(self, 'header_path', '${INCLUDEDIR}/%s-%s' % (valatask.pkg_name, _get_api_version()))
  11.220  
  11.221 -		valatask.is_lib = False
  11.222 -		if not 'cprogram' in self.features:
  11.223 -			valatask.is_lib = True
  11.224 +        valatask.is_lib = False
  11.225 +        if not 'cprogram' in self.features:
  11.226 +            valatask.is_lib = True
  11.227  
  11.228 -		packages = Utils.to_list(getattr(self, 'packages', []))
  11.229 -		vapi_dirs = Utils.to_list(getattr(self, 'vapi_dirs', []))
  11.230 -		includes =  []
  11.231 +        packages = Utils.to_list(getattr(self, 'packages', []))
  11.232 +        vapi_dirs = Utils.to_list(getattr(self, 'vapi_dirs', []))
  11.233 +        includes =  []
  11.234  
  11.235 -		if hasattr(self, 'use'):
  11.236 -			local_packages = Utils.to_list(self.use)[:] # make sure to have a copy
  11.237 -			seen = []
  11.238 -			while len(local_packages) > 0:
  11.239 -				package = local_packages.pop()
  11.240 -				if package in seen:
  11.241 -					continue
  11.242 -				seen.append(package)
  11.243 +        if hasattr(self, 'use'):
  11.244 +            local_packages = Utils.to_list(self.use)[:] # make sure to have a copy
  11.245 +            seen = []
  11.246 +            while len(local_packages) > 0:
  11.247 +                package = local_packages.pop()
  11.248 +                if package in seen:
  11.249 +                    continue
  11.250 +                seen.append(package)
  11.251  
  11.252 -				# check if the package exists
  11.253 -				try:
  11.254 -					package_obj = self.bld.get_tgen_by_name(package)
  11.255 -				except Errors.WafError:
  11.256 -					continue
  11.257 -				package_name = package_obj.target
  11.258 -				package_node = package_obj.path
  11.259 -				package_dir = package_node.path_from(self.path)
  11.260 +                # check if the package exists
  11.261 +                try:
  11.262 +                    package_obj = self.bld.get_tgen_by_name(package)
  11.263 +                except Errors.WafError:
  11.264 +                    continue
  11.265 +                package_name = package_obj.target
  11.266 +                package_node = package_obj.path
  11.267 +                package_dir = package_node.path_from(self.path)
  11.268  
  11.269 -				for task in package_obj.tasks:
  11.270 -					for output in task.outputs:
  11.271 -						if output.name == package_name + ".vapi":
  11.272 -							valatask.set_run_after(task)
  11.273 -							if package_name not in packages:
  11.274 -								packages.append(package_name)
  11.275 -							if package_dir not in vapi_dirs:
  11.276 -								vapi_dirs.append(package_dir)
  11.277 -							if package_dir not in includes:
  11.278 -								includes.append(package_dir)
  11.279 +                for task in package_obj.tasks:
  11.280 +                    for output in task.outputs:
  11.281 +                        if output.name == package_name + ".vapi":
  11.282 +                            valatask.set_run_after(task)
  11.283 +                            if package_name not in packages:
  11.284 +                                packages.append(package_name)
  11.285 +                            if package_dir not in vapi_dirs:
  11.286 +                                vapi_dirs.append(package_dir)
  11.287 +                            if package_dir not in includes:
  11.288 +                                includes.append(package_dir)
  11.289  
  11.290 -				if hasattr(package_obj, 'use'):
  11.291 -					lst = self.to_list(package_obj.use)
  11.292 -					lst.reverse()
  11.293 -					local_packages = [pkg for pkg in lst if pkg not in seen] + local_packages
  11.294 +                if hasattr(package_obj, 'use'):
  11.295 +                    lst = self.to_list(package_obj.use)
  11.296 +                    lst.reverse()
  11.297 +                    local_packages = [pkg for pkg in lst if pkg not in seen] + local_packages
  11.298  
  11.299 -		valatask.packages = packages
  11.300 -		for vapi_dir in vapi_dirs:
  11.301 -			try:
  11.302 -				valatask.vapi_dirs.append(self.path.find_dir(vapi_dir).abspath())
  11.303 -				valatask.vapi_dirs.append(self.path.find_dir(vapi_dir).get_bld().abspath())
  11.304 -			except AttributeError:
  11.305 -				Logs.warn("Unable to locate Vala API directory: '%s'" % vapi_dir)
  11.306 +        valatask.packages = packages
  11.307 +        for vapi_dir in vapi_dirs:
  11.308 +            try:
  11.309 +                valatask.vapi_dirs.append(self.path.find_dir(vapi_dir).abspath())
  11.310 +                valatask.vapi_dirs.append(self.path.find_dir(vapi_dir).get_bld().abspath())
  11.311 +            except AttributeError:
  11.312 +                Logs.warn("Unable to locate Vala API directory: '%s'" % vapi_dir)
  11.313  
  11.314 -		self.includes.append(self.bld.srcnode.abspath())
  11.315 -		self.includes.append(self.bld.bldnode.abspath())
  11.316 -		for include in includes:
  11.317 -			try:
  11.318 -				self.includes.append(self.path.find_dir(include).abspath())
  11.319 -				self.includes.append(self.path.find_dir(include).get_bld().abspath())
  11.320 -			except AttributeError:
  11.321 -				Logs.warn("Unable to locate include directory: '%s'" % include)
  11.322 +        self.includes.append(self.bld.srcnode.abspath())
  11.323 +        self.includes.append(self.bld.bldnode.abspath())
  11.324 +        for include in includes:
  11.325 +            try:
  11.326 +                self.includes.append(self.path.find_dir(include).abspath())
  11.327 +                self.includes.append(self.path.find_dir(include).get_bld().abspath())
  11.328 +            except AttributeError:
  11.329 +                Logs.warn("Unable to locate include directory: '%s'" % include)
  11.330  
  11.331  
  11.332 -		if valatask.profile == 'gobject':
  11.333 -			if hasattr(self, 'target_glib'):
  11.334 -				Logs.warn('target_glib on vala tasks is not supported --vala-target-glib=MAJOR.MINOR from the vala tool options')
  11.335 +        if valatask.profile == 'gobject':
  11.336 +            if hasattr(self, 'target_glib'):
  11.337 +                Logs.warn('target_glib on vala tasks is not supported --vala-target-glib=MAJOR.MINOR from the vala tool options')
  11.338  
  11.339 -			if getattr(Options.options, 'vala_target_glib', None):
  11.340 -				valatask.target_glib = Options.options.vala_target_glib
  11.341 +            if getattr(Options.options, 'vala_target_glib', None):
  11.342 +                valatask.target_glib = Options.options.vala_target_glib
  11.343  
  11.344 -			if not 'GOBJECT' in self.uselib:
  11.345 -				self.uselib.append('GOBJECT')
  11.346 +            if not 'GOBJECT' in self.uselib:
  11.347 +                self.uselib.append('GOBJECT')
  11.348  
  11.349 -		if hasattr(self, 'threading'):
  11.350 -			if valatask.profile == 'gobject':
  11.351 -				valatask.threading = self.threading
  11.352 -				if not 'GTHREAD' in self.uselib:
  11.353 -					self.uselib.append('GTHREAD')
  11.354 -			else:
  11.355 -				#Vala doesn't have threading support for dova nor posix
  11.356 -				Logs.warn("Profile %s does not have threading support" % valatask.profile)
  11.357 +        if hasattr(self, 'threading'):
  11.358 +            if valatask.profile == 'gobject':
  11.359 +                valatask.threading = self.threading
  11.360 +                if not 'GTHREAD' in self.uselib:
  11.361 +                    self.uselib.append('GTHREAD')
  11.362 +            else:
  11.363 +                #Vala doesn't have threading support for dova nor posix
  11.364 +                Logs.warn("Profile %s does not have threading support" % valatask.profile)
  11.365  
  11.366 -		if valatask.is_lib:
  11.367 -			valatask.outputs.append(self.path.find_or_declare('%s.h' % self.name))
  11.368 -			valatask.outputs.append(self.path.find_or_declare('%s.vapi' % self.target))
  11.369 +        if valatask.is_lib:
  11.370 +            valatask.outputs.append(self.path.find_or_declare('%s/%s.h' %
  11.371 +                                                     (self.name, self.target)))
  11.372 +            valatask.outputs.append(self.path.find_or_declare('%s.vapi' %
  11.373 +                                                              self.target))
  11.374  
  11.375 -			if valatask.gir:
  11.376 -				valatask.outputs.append(self.path.find_or_declare('%s.gir' % self.gir))
  11.377 +            if valatask.gir:
  11.378 +                valatask.outputs.append(self.path.find_or_declare('%s.gir' % self.gir))
  11.379  
  11.380 -			if valatask.packages:
  11.381 -				d = self.path.find_or_declare('%s.deps' % self.target)
  11.382 -				valatask.outputs.append(d)
  11.383 -				valatask.deps_node = d
  11.384 +            #if valatask.packages:
  11.385 +            #    d = self.path.find_or_declare('%s.deps' % self.target)
  11.386 +            #    valatask.outputs.append(d)
  11.387 +            #    valatask.deps_node = d
  11.388  
  11.389 -	valatask.inputs.append(node)
  11.390 -	c_node = node.change_ext('.c')
  11.391 +    valatask.inputs.append(node)
  11.392 +    c_node = node.change_ext('.c')
  11.393  
  11.394 -	valatask.outputs.append(c_node)
  11.395 -	self.source.append(c_node)
  11.396 +    valatask.outputs.append(c_node)
  11.397 +    self.source.append(c_node)
  11.398  
  11.399 -	if valatask.is_lib:
  11.400 -		headers_list = [o for o in valatask.outputs if o.suffix() == ".h"]
  11.401 -		try:
  11.402 -			self.install_vheader.source = headers_list
  11.403 -		except AttributeError:
  11.404 -			self.install_vheader = self.bld.install_files(valatask.header_path, headers_list, self.env)
  11.405 +    if valatask.is_lib:
  11.406 +        headers_list = [o for o in valatask.outputs if o.suffix() == ".h"]
  11.407 +        try:
  11.408 +            self.install_vheader.source = headers_list
  11.409 +        except AttributeError:
  11.410 +            self.install_vheader = self.bld.install_files(valatask.header_path, headers_list, self.env)
  11.411  
  11.412 -		vapi_list = [o for o in valatask.outputs if (o.suffix() in (".vapi", ".deps"))]
  11.413 -		try:
  11.414 -			self.install_vapi.source = vapi_list
  11.415 -		except AttributeError:
  11.416 -			self.install_vapi = self.bld.install_files(valatask.vapi_path, vapi_list, self.env)
  11.417 +        vapi_list = [o for o in valatask.outputs if (o.suffix() in (".vapi", ".deps"))]
  11.418 +        try:
  11.419 +            self.install_vapi.source = vapi_list
  11.420 +        except AttributeError:
  11.421 +            self.install_vapi = self.bld.install_files(valatask.vapi_path, vapi_list, self.env)
  11.422  
  11.423 -		gir_list = [o for o in valatask.outputs if o.suffix() == ".gir"]
  11.424 -		try:
  11.425 -			self.install_gir.source = gir_list
  11.426 -		except AttributeError:
  11.427 -			self.install_gir = self.bld.install_files(valatask.gir_path, gir_list, self.env)
  11.428 +        gir_list = [o for o in valatask.outputs if o.suffix() == ".gir"]
  11.429 +        try:
  11.430 +            self.install_gir.source = gir_list
  11.431 +        except AttributeError:
  11.432 +            self.install_gir = self.bld.install_files(valatask.gir_path, gir_list, self.env)
  11.433  
  11.434  valac = Task.update_outputs(valac) # no decorators for python2 classes
  11.435  
  11.436  @conf
  11.437 -def check_vala(self, min_version=(0,11,7), branches=('0.18', '0.16', '0.14', '0.12')):
  11.438 +def check_vala(self, min_version=(0,18,0), 
  11.439 +               branches=('0.26', '0.24', '0.22', '0.20', '0.18')):
  11.440      """
  11.441      Check if vala compiler from a given branch exists of at least a given
  11.442      version.
  11.443 @@ -271,9 +274,9 @@
  11.444      if not valac:
  11.445          valac_name = 'valac'
  11.446          valac = self.find_program(valac_name, var='VALAC')
  11.447 -        
  11.448 -    output = self.cmd_and_log(valac + ' --version')
  11.449 -    if output.find('UNKNOWN') >= 0 :
  11.450 +
  11.451 +    output = self.cmd_and_log(valac + ['--version'])
  11.452 +    if output == "UNKNOWN" :
  11.453          output = branch+'.0' # best guess
  11.454      ver = re.search(r'\d+.\d+.\d+', output).group(0).split('.')
  11.455      valac_version = tuple([int(x) for x in ver])
  11.456 @@ -286,44 +289,44 @@
  11.457  
  11.458  @conf
  11.459  def check_vala_deps(self):
  11.460 -	"""
  11.461 -	Load the gobject and gthread packages if they are missing.
  11.462 -	"""
  11.463 -	if not self.env['HAVE_GOBJECT']:
  11.464 -		pkg_args = {'package':      'gobject-2.0',
  11.465 -		            'uselib_store': 'GOBJECT',
  11.466 -		            'args':         '--cflags --libs'}
  11.467 -		if getattr(Options.options, 'vala_target_glib', None):
  11.468 -			pkg_args['atleast_version'] = Options.options.vala_target_glib
  11.469 -		self.check_cfg(**pkg_args)
  11.470 +    """
  11.471 +    Load the gobject and gthread packages if they are missing.
  11.472 +    """
  11.473 +    if not self.env['HAVE_GOBJECT']:
  11.474 +        pkg_args = {'package':      'gobject-2.0',
  11.475 +                    'uselib_store': 'GOBJECT',
  11.476 +                    'args':         '--cflags --libs'}
  11.477 +        if getattr(Options.options, 'vala_target_glib', None):
  11.478 +            pkg_args['atleast_version'] = Options.options.vala_target_glib
  11.479 +        self.check_cfg(**pkg_args)
  11.480  
  11.481 -	if not self.env['HAVE_GTHREAD']:
  11.482 -		pkg_args = {'package':      'gthread-2.0',
  11.483 -		            'uselib_store': 'GTHREAD',
  11.484 -		            'args':         '--cflags --libs'}
  11.485 -		if getattr(Options.options, 'vala_target_glib', None):
  11.486 -			pkg_args['atleast_version'] = Options.options.vala_target_glib
  11.487 -		self.check_cfg(**pkg_args)
  11.488 +    if not self.env['HAVE_GTHREAD']:
  11.489 +        pkg_args = {'package':      'gthread-2.0',
  11.490 +                    'uselib_store': 'GTHREAD',
  11.491 +                    'args':         '--cflags --libs'}
  11.492 +        if getattr(Options.options, 'vala_target_glib', None):
  11.493 +            pkg_args['atleast_version'] = Options.options.vala_target_glib
  11.494 +        self.check_cfg(**pkg_args)
  11.495  
  11.496  def configure(self):
  11.497 -	"""
  11.498 -	Use the following to enforce minimum vala version::
  11.499 +    """
  11.500 +    Use the following to enforce minimum vala version::
  11.501  
  11.502 -		def configure(conf):
  11.503 -			conf.load('vala', funs='')
  11.504 -			conf.check_vala(min_version=(0,10,0))
  11.505 -	"""
  11.506 -	self.load('gnu_dirs')
  11.507 -	self.check_vala_deps()
  11.508 -	self.check_vala()
  11.509 +        def configure(conf):
  11.510 +            conf.load('vala', funs='')
  11.511 +            conf.check_vala(min_version=(0,10,0))
  11.512 +    """
  11.513 +    self.load('gnu_dirs')
  11.514 +    self.check_vala_deps()
  11.515 +    self.check_vala()
  11.516  
  11.517  def options(opt):
  11.518 -	"""
  11.519 -	Load the :py:mod:`waflib.Tools.gnu_dirs` tool and add the ``--vala-target-glib`` command-line option
  11.520 -	"""
  11.521 -	opt.load('gnu_dirs')
  11.522 -	valaopts = opt.add_option_group('Vala Compiler Options')
  11.523 -	valaopts.add_option ('--vala-target-glib', default=None,
  11.524 -		dest='vala_target_glib', metavar='MAJOR.MINOR',
  11.525 -		help='Target version of glib for Vala GObject code generation')
  11.526 +    """
  11.527 +    Load the :py:mod:`waflib.Tools.gnu_dirs` tool and add the ``--vala-target-glib`` command-line option
  11.528 +    """
  11.529 +    opt.load('gnu_dirs')
  11.530 +    valaopts = opt.add_option_group('Vala Compiler Options')
  11.531 +    valaopts.add_option ('--vala-target-glib', default=None,
  11.532 +        dest='vala_target_glib', metavar='MAJOR.MINOR',
  11.533 +        help='Target version of glib for Vala GObject code generation')
  11.534  
    12.1 --- a/include/loudmouth/lm-connection.h	Wed Dec 25 20:33:47 2013 -0500
    12.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.3 @@ -1,239 +0,0 @@
    12.4 -/*
    12.5 - *  Copyright (C) 2012 Copyleft Games Group
    12.6 - *  Copyright (C) 2003 Imendio AB
    12.7 - *
    12.8 - *  This program is free software; you can redistribute it and/or modify
    12.9 - *  it under the terms of the GNU Affero General Public License as published
   12.10 - *  by the Free Software Foundation, either version 3 of the License, or
   12.11 - *  (at your option) any later version.
   12.12 - *
   12.13 - *  This program is distributed in the hope that it will be useful,
   12.14 - *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   12.15 - *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   12.16 - *  GNU Affero General Public License for more details.
   12.17 - *
   12.18 - *  You should have received a copy of the GNU Affero General Public License
   12.19 - *  along with this program; if not, see http://www.gnu.org/licenses
   12.20 - *
   12.21 - */
   12.22 -
   12.23 -#ifndef __LM_CONNECTION_H__
   12.24 -#define __LM_CONNECTION_H__
   12.25 -
   12.26 -#if !defined (LM_INSIDE_LIGHTMELODY_H) && !defined (LM_COMPILATION)
   12.27 -#error "Only <lightmelody/lightmelody.h> can be included directly, this file may disappear or change contents."
   12.28 -#endif
   12.29 -
   12.30 -#include <loudmouth/lm-message.h>
   12.31 -#include <loudmouth/lm-proxy.h>
   12.32 -#include <loudmouth/lm-ssl.h>
   12.33 -
   12.34 -G_BEGIN_DECLS
   12.35 -
   12.36 -/**
   12.37 - * LM_CONNECTION:
   12.38 - * @o: pointer to cast
   12.39 - *
   12.40 - * Convenience macro used to cast a pointer to a #LmConnection.
   12.41 - */
   12.42 -#define LM_CONNECTION(o) (LmConnection *) o;
   12.43 -
   12.44 -/**
   12.45 - * LM_CONNECTION_DEFAULT_PORT:
   12.46 - *
   12.47 - * Default jabber client port.
   12.48 - */
   12.49 -#define LM_CONNECTION_DEFAULT_PORT     5222
   12.50 -
   12.51 -/**
   12.52 - * LM_CONNECTION_DEFAULT_PORT_SSL:
   12.53 - *
   12.54 - * Default jabber client port when using SSL encryption.
   12.55 - */
   12.56 -#define LM_CONNECTION_DEFAULT_PORT_SSL 5223
   12.57 -
   12.58 -typedef struct _LmConnection LmConnection;
   12.59 -
   12.60 -typedef struct LmMessageHandler LmMessageHandler;
   12.61 -
   12.62 -/**
   12.63 - * LmHandlerResult:
   12.64 - * @LM_HANDLER_RESULT_REMOVE_MESSAGE: Stop calling message handlers. The message handler returning this declares the message has been handled and should be removed.
   12.65 - * @LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS: Return to continue the calling handlers from the handler list. This declares that another handlers should handle the message.
   12.66 - *
   12.67 - * The return type of an LmMessageHandler. This determines whether more message handlers should be called.
   12.68 - */
   12.69 -typedef enum {
   12.70 -    LM_HANDLER_RESULT_REMOVE_MESSAGE,
   12.71 -    LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS
   12.72 -} LmHandlerResult;
   12.73 -
   12.74 -/**
   12.75 - * LmHandlerPriority:
   12.76 - * @LM_HANDLER_PRIORITY_LAST: Call the handler after all handlers with #NORMAL and #FIRST priority.
   12.77 - * @LM_HANDLER_PRIORITY_NORMAL: Called before handlers with priority #LAST and after those with #FIRST.
   12.78 - * @LM_HANDLER_PRIORITY_FIRST: These are called before all other handlers.
   12.79 - *
   12.80 - * Since the handlers decide whether to stop the calling chain with there return values it's sometimes decirable to be able to set priority. For example a handler that only logs all incoming messages and then pass the message on to another handler wants to have priority %LM_HANDLER_PRIORITY_FIRST. An handler that should take all messages that wasn't handled by anything else would want to have priority %LM_HANDLER_PRIORITY_LAST. If several handlers have the same priority nothing can be said about the order the handlers will be called in.
   12.81 - */
   12.82 -typedef enum {
   12.83 -    LM_HANDLER_PRIORITY_LAST   = 1,
   12.84 -    LM_HANDLER_PRIORITY_NORMAL = 2,
   12.85 -    LM_HANDLER_PRIORITY_FIRST  = 3
   12.86 -} LmHandlerPriority;
   12.87 -
   12.88 -/**
   12.89 - * LmDisconnectReason:
   12.90 - * @LM_DISCONNECT_REASON_OK:  * @LM_DISCONNECT_REASON_PING_TIME_OUT: Connection to the server timed out.
   12.91 - * @LM_DISCONNECT_REASON_HUP: The socket emitted that the connection was hung up.
   12.92 - * @LM_DISCONNECT_REASON_ERROR: A generic error somewhere in the transport layer.
   12.93 - * @LM_DISCONNECT_REASON_RESOURCE_CONFLICT:  * @LM_DISCONNECT_REASON_INVALID_XML:  * @LM_DISCONNECT_REASON_UNKNOWN: An unknown error.
   12.94 - *
   12.95 - * Sent with #LmDisconnectFunction to describe why a connection was closed.
   12.96 - */
   12.97 -typedef enum {
   12.98 -    LM_DISCONNECT_REASON_OK,
   12.99 -    LM_DISCONNECT_REASON_PING_TIME_OUT,
  12.100 -    LM_DISCONNECT_REASON_HUP,
  12.101 -    LM_DISCONNECT_REASON_ERROR,
  12.102 -    LM_DISCONNECT_REASON_RESOURCE_CONFLICT,
  12.103 -    LM_DISCONNECT_REASON_INVALID_XML,
  12.104 -    LM_DISCONNECT_REASON_UNKNOWN
  12.105 -} LmDisconnectReason;
  12.106 -
  12.107 -/**
  12.108 - * LmConnectionState:
  12.109 - * @LM_CONNECTION_STATE_CLOSED: The connection is closed.
  12.110 - * @LM_CONNECTION_STATE_OPENING: The connection is in the process of opening.
  12.111 - * @LM_CONNECTION_STATE_OPEN: The connection is open.
  12.112 - * @LM_CONNECTION_STATE_AUTHENTICATING: The connection is in the process of authenticating.
  12.113 - * @LM_CONNECTION_STATE_AUTHENTICATED: The connection is authenticated and is ready to start sending/receiving messages.
  12.114 - *
  12.115 - * Describes the current state of an #LmConnection.
  12.116 - */
  12.117 -typedef enum {
  12.118 -    LM_CONNECTION_STATE_CLOSED,
  12.119 -    LM_CONNECTION_STATE_OPENING,
  12.120 -    LM_CONNECTION_STATE_OPEN,
  12.121 -    LM_CONNECTION_STATE_AUTHENTICATING,
  12.122 -    LM_CONNECTION_STATE_AUTHENTICATED
  12.123 -} LmConnectionState;
  12.124 -
  12.125 -/**
  12.126 - * LmResultFunction:
  12.127 - * @connection: an #LmConnection
  12.128 - * @success: the result, %TRUE if operation succeeded, otherwise %FALSE
  12.129 - * @user_data: User data passed when function being called.
  12.130 - *
  12.131 - * Callback for informing if an asynchronous operation was successful.
  12.132 - */
  12.133 -typedef void          (* LmResultFunction)     (LmConnection       *connection,
  12.134 -                                                gboolean            success,
  12.135 -                                                gpointer            user_data);
  12.136 -
  12.137 -/**
  12.138 - * LmDisconnectFunction:
  12.139 - * @connection: an #LmConnection
  12.140 - * @reason: the reason the connection was closed.
  12.141 - * @user_data: User data passed when function being called.
  12.142 - *
  12.143 - * Callback called when a connection is closed.
  12.144 - */
  12.145 -typedef void         (* LmDisconnectFunction) (LmConnection       *connection,
  12.146 -                                               LmDisconnectReason  reason,
  12.147 -                                               gpointer            user_data);
  12.148 -
  12.149 -LmConnection *lm_connection_new               (const gchar        *server);
  12.150 -LmConnection *lm_connection_new_with_context  (const gchar        *server,
  12.151 -                                               GMainContext       *context);
  12.152 -gboolean      lm_connection_open              (LmConnection       *connection,
  12.153 -                                               LmResultFunction    function,
  12.154 -                                               gpointer            user_data,
  12.155 -                                               GDestroyNotify      notify,
  12.156 -                                               GError            **error);
  12.157 -
  12.158 -gboolean      lm_connection_open_and_block    (LmConnection       *connection,
  12.159 -                                               GError            **error);
  12.160 -
  12.161 -void          lm_connection_cancel_open       (LmConnection      *connection);
  12.162 -gboolean      lm_connection_close             (LmConnection       *connection,
  12.163 -                                               GError            **error);
  12.164 -gboolean      lm_connection_authenticate      (LmConnection       *connection,
  12.165 -                                               const gchar        *username,
  12.166 -                                               const gchar        *password,
  12.167 -                                               const gchar        *resource,
  12.168 -                                               LmResultFunction    function,
  12.169 -                                               gpointer            user_data,
  12.170 -                                               GDestroyNotify      notify,
  12.171 -                                               GError            **error);
  12.172 -gboolean
  12.173 -lm_connection_authenticate_and_block          (LmConnection       *connection,
  12.174 -                                               const gchar        *username,
  12.175 -                                               const gchar        *password,
  12.176 -                                               const gchar        *resource,
  12.177 -                                               GError            **error);
  12.178 -guint         lm_connection_get_keep_alive_rate (LmConnection     *connection);
  12.179 -void        lm_connection_set_keep_alive_rate (LmConnection       *connection,
  12.180 -                                               guint               rate);
  12.181 -
  12.182 -gboolean      lm_connection_is_open           (LmConnection       *connection);
  12.183 -gboolean      lm_connection_is_authenticated  (LmConnection       *connection);
  12.184 -
  12.185 -const gchar * lm_connection_get_server        (LmConnection       *connection);
  12.186 -void          lm_connection_set_server        (LmConnection       *connection,
  12.187 -                                               const gchar        *server);
  12.188 -void          lm_connection_set_jid           (LmConnection       *connection,
  12.189 -                                               const gchar        *jid);
  12.190 -const gchar * lm_connection_get_jid           (LmConnection       *connection);
  12.191 -gchar *       lm_connection_get_full_jid      (LmConnection       *connection);
  12.192 -
  12.193 -guint         lm_connection_get_port          (LmConnection       *connection);
  12.194 -void          lm_connection_set_port          (LmConnection       *connection,
  12.195 -                                               guint               port);
  12.196 -
  12.197 -LmSSL *       lm_connection_get_ssl           (LmConnection       *connection);
  12.198 -void          lm_connection_set_ssl           (LmConnection       *connection,
  12.199 -                                               LmSSL              *ssl);
  12.200 -LmProxy *     lm_connection_get_proxy         (LmConnection       *connection);
  12.201 -void          lm_connection_set_proxy         (LmConnection       *connection,
  12.202 -                                               LmProxy            *proxy);
  12.203 -gboolean      lm_connection_send              (LmConnection       *connection,
  12.204 -                                               LmMessage          *message,
  12.205 -                                               GError            **error);
  12.206 -gboolean      lm_connection_send_with_reply   (LmConnection       *connection,
  12.207 -                                               LmMessage          *message,
  12.208 -                                               LmMessageHandler   *handler,
  12.209 -                                               GError            **error);
  12.210 -LmMessage *
  12.211 -lm_connection_send_with_reply_and_block       (LmConnection       *connection,
  12.212 -                                               LmMessage          *message,
  12.213 -                                               GError            **error);
  12.214 -void
  12.215 -lm_connection_unregister_reply_handler        (LmConnection     *connection,
  12.216 -                                               LmMessageHandler *handler);
  12.217 -void
  12.218 -lm_connection_register_message_handler        (LmConnection       *connection,
  12.219 -                                               LmMessageHandler   *handler,
  12.220 -                                               LmMessageType       type,
  12.221 -                                               LmHandlerPriority   priority);
  12.222 -void
  12.223 -lm_connection_unregister_message_handler      (LmConnection       *connection,
  12.224 -                                               LmMessageHandler   *handler,
  12.225 -                                               LmMessageType       type);
  12.226 -void
  12.227 -lm_connection_set_disconnect_function         (LmConnection       *connection,
  12.228 -                                               LmDisconnectFunction function,
  12.229 -                                               gpointer             user_data,
  12.230 -                                               GDestroyNotify       notify);
  12.231 -
  12.232 -gboolean      lm_connection_send_raw          (LmConnection       *connection,
  12.233 -                                               const gchar        *str,
  12.234 -                                               GError            **error);
  12.235 -LmConnectionState lm_connection_get_state     (LmConnection       *connection);
  12.236 -gchar *       lm_connection_get_local_host    (LmConnection       *connection);
  12.237 -LmConnection* lm_connection_ref               (LmConnection       *connection);
  12.238 -void          lm_connection_unref             (LmConnection       *connection);
  12.239 -
  12.240 -G_END_DECLS
  12.241 -
  12.242 -#endif /* __LM_CONNECTION_H__ */
    13.1 --- a/include/loudmouth/lm-error.h	Wed Dec 25 20:33:47 2013 -0500
    13.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.3 @@ -1,57 +0,0 @@
    13.4 -/*
    13.5 - *  Copyright (C) 2012 Copyleft Games Group
    13.6 - *  Copyright (C) 2003 Imendio AB
    13.7 - *
    13.8 - *  This program is free software; you can redistribute it and/or modify
    13.9 - *  it under the terms of the GNU Affero General Public License as published
   13.10 - *  by the Free Software Foundation, either version 3 of the License, or
   13.11 - *  (at your option) any later version.
   13.12 - *
   13.13 - *  This program is distributed in the hope that it will be useful,
   13.14 - *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   13.15 - *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   13.16 - *  GNU Affero General Public License for more details.
   13.17 - *
   13.18 - *  You should have received a copy of the GNU Affero General Public License
   13.19 - *  along with this program; if not, see http://www.gnu.org/licenses
   13.20 - *
   13.21 - */
   13.22 -
   13.23 -#ifndef __LM_ERROR_H__
   13.24 -#define __LM_ERROR_H__
   13.25 -
   13.26 -#if !defined (LM_INSIDE_LIGHTMELODY_H) && !defined (LM_COMPILATION)
   13.27 -#error "Only <lightmelody/lightmelody.h> can be included directly, this file may disappear or change contents."
   13.28 -#endif
   13.29 -
   13.30 -#include <glib.h>
   13.31 -
   13.32 -G_BEGIN_DECLS
   13.33 -
   13.34 -/**
   13.35 - * LM_ERROR:
   13.36 - *
   13.37 - * Macro for getting the error quark.
   13.38 - */
   13.39 -#define LM_ERROR lm_error_quark ()
   13.40 -
   13.41 -/**
   13.42 - * LmError:
   13.43 - * @LM_ERROR_CONNECTION_NOT_OPEN: Connection not open when trying to send a message
   13.44 - * @LM_ERROR_CONNECTION_OPEN: Connection is already open when trying to open it again.
   13.45 - * @LM_ERROR_AUTH_FAILED: Authentication failed while opening connection
   13.46 - * @LM_ERROR_CONNECTION_FAILED:  *
   13.47 - * Describes the problem of the error.
   13.48 - */
   13.49 -typedef enum {
   13.50 -    LM_ERROR_CONNECTION_NOT_OPEN,
   13.51 -    LM_ERROR_CONNECTION_OPEN,
   13.52 -    LM_ERROR_AUTH_FAILED,
   13.53 -    LM_ERROR_CONNECTION_FAILED
   13.54 -} LmError;
   13.55 -
   13.56 -GQuark lm_error_quark (void) G_GNUC_CONST;
   13.57 -
   13.58 -G_END_DECLS
   13.59 -
   13.60 -#endif /* __LM_ERROR_H__ */
    14.1 --- a/include/loudmouth/lm-message-handler.h	Wed Dec 25 20:33:47 2013 -0500
    14.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.3 @@ -1,58 +0,0 @@
    14.4 -/*
    14.5 - *  Copyright (C) 2012 Copyleft Games Group
    14.6 - *  Copyright (C) 2003 Imendio AB
    14.7 - *
    14.8 - *  This program is free software; you can redistribute it and/or modify
    14.9 - *  it under the terms of the GNU Affero General Public License as published
   14.10 - *  by the Free Software Foundation, either version 3 of the License, or
   14.11 - *  (at your option) any later version.
   14.12 - *
   14.13 - *  This program is distributed in the hope that it will be useful,
   14.14 - *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   14.15 - *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   14.16 - *  GNU Affero General Public License for more details.
   14.17 - *
   14.18 - *  You should have received a copy of the GNU Affero General Public License
   14.19 - *  along with this program; if not, see http://www.gnu.org/licenses
   14.20 - *
   14.21 - */
   14.22 -
   14.23 -#ifndef __LM_MESSAGE_HANDLER_H__
   14.24 -#define __LM_MESSAGE_HANDLER_H__
   14.25 -
   14.26 -#if !defined (LM_INSIDE_LIGHTMELODY_H) && !defined (LM_COMPILATION)
   14.27 -#error "Only <lightmelody/lightmelody.h> can be included directly, this file may disappear or change contents."
   14.28 -#endif
   14.29 -
   14.30 -#include <loudmouth/lm-connection.h>
   14.31 -
   14.32 -G_BEGIN_DECLS
   14.33 -
   14.34 -/**
   14.35 - * LmHandleMessageFunction:
   14.36 - * @handler: an #LmMessageHandler
   14.37 - * @connection: an #LmConnection
   14.38 - * @message: an #LmMessage
   14.39 - * @user_data: user data set when creating the handler
   14.40 - *
   14.41 - * The actual callback function in an #LmMessageHandler. This function is called when an incoming message arrives that haven't been handled by an handler with higher priority.
   14.42 - *
   14.43 - * Returns: #LM_HANDLER_RESULT_REMOVE_MESSAGE to indicate that message has been handled, otherwise #LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS.
   14.44 - */
   14.45 -typedef LmHandlerResult (* LmHandleMessageFunction) (LmMessageHandler *handler,
   14.46 -                                                     LmConnection     *connection,
   14.47 -                                                     LmMessage        *message,
   14.48 -                                                     gpointer          user_data);
   14.49 -
   14.50 -LmMessageHandler *lm_message_handler_new   (LmHandleMessageFunction  function,
   14.51 -                                            gpointer                 user_data,
   14.52 -                                            GDestroyNotify           notify);
   14.53 -void              lm_message_handler_invalidate (LmMessageHandler   *handler);
   14.54 -gboolean          lm_message_handler_is_valid   (LmMessageHandler   *handler);
   14.55 -LmMessageHandler *lm_message_handler_ref   (LmMessageHandler        *handler);
   14.56 -void              lm_message_handler_unref (LmMessageHandler        *handler);
   14.57 -
   14.58 -G_END_DECLS
   14.59 -
   14.60 -#endif /* __LM_MESSAGE_HANDLER_H__ */
   14.61 -
    15.1 --- a/include/loudmouth/lm-message-node.h	Wed Dec 25 20:33:47 2013 -0500
    15.2 +++ b/include/loudmouth/lm-message-node.h	Mon Dec 15 05:04:57 2014 +0000
    15.3 @@ -1,5 +1,5 @@
    15.4  /*
    15.5 - *  Copyright (C) 2012 Copyleft Games Group
    15.6 + *  Copyright (C) 2012,2013,2014 Copyleft Games Group
    15.7   *  Copyright (C) 2003 Imendio AB
    15.8   *
    15.9   *  This program is free software; you can redistribute it and/or modify
    16.1 --- a/include/loudmouth/lm-message.h	Wed Dec 25 20:33:47 2013 -0500
    16.2 +++ b/include/loudmouth/lm-message.h	Mon Dec 15 05:04:57 2014 +0000
    16.3 @@ -1,5 +1,5 @@
    16.4  /*
    16.5 - *  Copyright (C) 2012 Copyleft Games Group
    16.6 + *  Copyright (C) 2012,2013,2014 Copyleft Games Group
    16.7   *  Copyright (C) 2003 Imendio AB
    16.8   *
    16.9   *  This program is free software; you can redistribute it and/or modify
    17.1 --- a/include/loudmouth/lm-proxy.h	Wed Dec 25 20:33:47 2013 -0500
    17.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.3 @@ -1,78 +0,0 @@
    17.4 -/*
    17.5 - *  Copyright (C) 2012 Copyleft Games Group
    17.6 - *  Copyright (C) 2004 Imendio AB
    17.7 - *
    17.8 - *  This program is free software; you can redistribute it and/or modify
    17.9 - *  it under the terms of the GNU Affero General Public License as published
   17.10 - *  by the Free Software Foundation, either version 3 of the License, or
   17.11 - *  (at your option) any later version.
   17.12 - *
   17.13 - *  This program is distributed in the hope that it will be useful,
   17.14 - *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   17.15 - *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   17.16 - *  GNU Affero General Public License for more details.
   17.17 - *
   17.18 - *  You should have received a copy of the GNU Affero General Public License
   17.19 - *  along with this program; if not, see http://www.gnu.org/licenses
   17.20 - *
   17.21 - */
   17.22 -
   17.23 -#ifndef __LM_PROXY_H__
   17.24 -#define __LM_PROXY_H__
   17.25 -
   17.26 -#if !defined (LM_INSIDE_LIGHTMELODY_H) && !defined (LM_COMPILATION)
   17.27 -#error "Only <lightmelody/lightmelody.h> can be included directly, this file may disappear or change contents."
   17.28 -#endif
   17.29 -
   17.30 -G_BEGIN_DECLS
   17.31 -
   17.32 -/**
   17.33 - * LmProxy:
   17.34 - *
   17.35 - * This should not be accessed directly. Use the accessor functions as described below.
   17.36 - */
   17.37 -typedef struct _LmProxy LmProxy;
   17.38 -
   17.39 -/**
   17.40 - * LmProxyType:
   17.41 - * @LM_PROXY_TYPE_NONE: Unused
   17.42 - * @LM_PROXY_TYPE_HTTP: An HTTP proxy.
   17.43 - *
   17.44 - * The type of the proxy.
   17.45 - */
   17.46 -typedef enum {
   17.47 -    LM_PROXY_TYPE_NONE = 0,
   17.48 -    LM_PROXY_TYPE_HTTP
   17.49 -} LmProxyType;
   17.50 -
   17.51 -LmProxy *     lm_proxy_new              (LmProxyType         type);
   17.52 -LmProxy *     lm_proxy_new_with_server  (LmProxyType         type,
   17.53 -                                         const gchar        *server,
   17.54 -                                         guint               port);
   17.55 -
   17.56 -LmProxyType   lm_proxy_get_type         (LmProxy            *proxy);
   17.57 -void          lm_proxy_set_type         (LmProxy            *proxy,
   17.58 -                                         LmProxyType         type);
   17.59 -
   17.60 -const gchar * lm_proxy_get_server       (LmProxy            *proxy);
   17.61 -void          lm_proxy_set_server       (LmProxy            *proxy,
   17.62 -                                         const gchar        *server);
   17.63 -
   17.64 -guint         lm_proxy_get_port         (LmProxy            *proxy);
   17.65 -void          lm_proxy_set_port         (LmProxy            *proxy,
   17.66 -                                         guint               port);
   17.67 -
   17.68 -const gchar * lm_proxy_get_username     (LmProxy            *proxy);
   17.69 -void          lm_proxy_set_username     (LmProxy            *proxy,
   17.70 -                                         const gchar        *username);
   17.71 -
   17.72 -const gchar * lm_proxy_get_password     (LmProxy            *proxy);
   17.73 -void          lm_proxy_set_password     (LmProxy            *proxy,
   17.74 -                                         const gchar        *password);
   17.75 -
   17.76 -LmProxy *     lm_proxy_ref              (LmProxy            *proxy);
   17.77 -void          lm_proxy_unref            (LmProxy            *proxy);
   17.78 -
   17.79 -G_END_DECLS
   17.80 -#endif /* __LM_PROXY_H__ */
   17.81 -
    18.1 --- a/include/loudmouth/lm-ssl.h	Wed Dec 25 20:33:47 2013 -0500
    18.2 +++ b/include/loudmouth/lm-ssl.h	Mon Dec 15 05:04:57 2014 +0000
    18.3 @@ -1,5 +1,5 @@
    18.4  /*
    18.5 - *  Copyright (C) 2012 Copyleft Games Group
    18.6 + *  Copyright (C) 2012,2013,2014 Copyleft Games Group
    18.7   *  Copyright (C) 2003-2004 Imendio AB
    18.8   *
    18.9   *  This program is free software; you can redistribute it and/or modify
    19.1 --- a/include/loudmouth/lm-utils.h	Wed Dec 25 20:33:47 2013 -0500
    19.2 +++ b/include/loudmouth/lm-utils.h	Mon Dec 15 05:04:57 2014 +0000
    19.3 @@ -1,5 +1,5 @@
    19.4  /*
    19.5 - *  Copyright (C) 2012 Copyleft Games Group
    19.6 + *  Copyright (C) 2012,2013,2014 Copyleft Games Group
    19.7   *  Copyright (C) 2003 Imendio AB
    19.8   *
    19.9   *  This program is free software; you can redistribute it and/or modify
    20.1 --- a/include/loudmouth/loudmouth.h	Wed Dec 25 20:33:47 2013 -0500
    20.2 +++ b/include/loudmouth/loudmouth.h	Mon Dec 15 05:04:57 2014 +0000
    20.3 @@ -1,5 +1,5 @@
    20.4  /*
    20.5 - *  Copyright (C) 2012 Copyleft Games Group
    20.6 + *  Copyright (C) 2012,2013,2014 Copyleft Games Group
    20.7   *  Copyright (C) 2003 Imendio AB
    20.8   *
    20.9   *  This program is free software; you can redistribute it and/or modify
   20.10 @@ -22,12 +22,8 @@
   20.11  
   20.12  #define LM_INSIDE_LIGHTMELODY_H 1
   20.13  
   20.14 -#include <loudmouth/lm-connection.h>
   20.15 -#include <loudmouth/lm-error.h>
   20.16  #include <loudmouth/lm-message.h>
   20.17 -#include <loudmouth/lm-message-handler.h>
   20.18  #include <loudmouth/lm-message-node.h>
   20.19 -#include <loudmouth/lm-proxy.h>
   20.20  #include <loudmouth/lm-utils.h>
   20.21  #include <loudmouth/lm-ssl.h>
   20.22  
    21.1 --- a/include/wscript_build	Wed Dec 25 20:33:47 2013 -0500
    21.2 +++ b/include/wscript_build	Mon Dec 15 05:04:57 2014 +0000
    21.3 @@ -1,7 +1,7 @@
    21.4  # encoding: utf-8
    21.5  #
    21.6  #   LightMelody - Lightweight XMPP/Jingle Client Library
    21.7 -#   Copyright (C) 2012 Copyleft Games Group
    21.8 +#   Copyright (C) 2012,2013,2014 Copyleft Games Group
    21.9  #
   21.10  #   This program is free software; you can redistribute it and/or modify
   21.11  #   it under the terms of the GNU Affero General Public License as published
    22.1 --- a/misc/wscript_build	Wed Dec 25 20:33:47 2013 -0500
    22.2 +++ b/misc/wscript_build	Mon Dec 15 05:04:57 2014 +0000
    22.3 @@ -1,7 +1,7 @@
    22.4  # encoding: utf-8
    22.5  #
    22.6  #   LightMelody - Lightweight XMPP/Jingle Client Library
    22.7 -#   Copyright (C) 2012 Copyleft Games Group
    22.8 +#   Copyright (C) 2012,2013,2014 Copyleft Games Group
    22.9  #
   22.10  #   This program is free software; you can redistribute it and/or modify
   22.11  #   it under the terms of the GNU Affero General Public License as published
    23.1 --- a/python/_G.c	Wed Dec 25 20:33:47 2013 -0500
    23.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.3 @@ -1,97 +0,0 @@
    23.4 -/*
    23.5 - *  LightMelody - Lightweight XMPP/Jingle Client Library
    23.6 - *  Copyright (C) 2012 Copyleft Games Group
    23.7 - *
    23.8 - *  This program is free software; you can redistribute it and/or modify
    23.9 - *  it under the terms of the GNU Affero General Public License as published
   23.10 - *  by the Free Software Foundation, either version 3 of the License, or
   23.11 - *  (at your option) any later version.
   23.12 - *
   23.13 - *  This program is distributed in the hope that it will be useful,
   23.14 - *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   23.15 - *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   23.16 - *  GNU Affero General Public License for more details.
   23.17 - *
   23.18 - *  You should have received a copy of the GNU Affero General Public License
   23.19 - *  along with this program; if not, see http://www.gnu.org/licenses
   23.20 - *
   23.21 - */
   23.22 -
   23.23 -#include "pylm.h"
   23.24 -
   23.25 -
   23.26 -static char
   23.27 -PyLM__G_doc[] = "lightmelody._G Type\n"
   23.28 -"\n"
   23.29 -"    This is a base type for all PyLM types that use a lightmelody backend class.\n"
   23.30 -"\n"
   23.31 -"    Its named starting with an underscore as a hint that its not useful to\n"
   23.32 -"    the end user, please take this hint - unless you're implementing a new\n"
   23.33 -"    type in a Python extension class this type serves no purpose to you.\n";
   23.34 -
   23.35 -
   23.36 -PyObject*
   23.37 -PyLM__G_new (PyTypeObject* type, PyObject* args, PyObject* kwds) {
   23.38 -
   23.39 -    PyErr_SetString(PyExc_TypeError, "This class cannot be used directly.");
   23.40 -    return NULL;
   23.41 -}
   23.42 -
   23.43 -
   23.44 -static void
   23.45 -PyLM__G_dealloc (PyLM__G_Object* self) {
   23.46 -    // decref gobject
   23.47 -    if (self->g)
   23.48 -      g_object_unref(self->g);
   23.49 -
   23.50 -    // dealloc base type
   23.51 -    PyObject_Del((PyObject*) self);
   23.52 -}
   23.53 -
   23.54 -
   23.55 -/////////////////////////////////////////////////////////////////////////////
   23.56 -// Type structs
   23.57 -
   23.58 -PyTypeObject PyLM__G_Type = {
   23.59 -    PyVarObject_HEAD_INIT(NULL, 0)
   23.60 -    "lightmelody._G",                                       // tp_name
   23.61 -    sizeof(PyLM__G_Object),                                 // tp_basicsize
   23.62 -    0,                                                      // tp_itemsize
   23.63 -    (destructor) PyLM__G_dealloc,                           // tp_dealloc
   23.64 -    0,                                                      // tp_print
   23.65 -    (getattrfunc) 0,                                        // tp_getattr
   23.66 -    (setattrfunc) 0,                                        // tp_setattr
   23.67 -    0,                                                      // tp_compare
   23.68 -    0,                                                      // tp_repr
   23.69 -    0,                                                      // tp_as_number
   23.70 -    0,                                                      // tp_as_sequence
   23.71 -    0,                                                      // tp_as_mapping
   23.72 -    0,                                                      // tp_hash
   23.73 -    0,                                                      // tp_call
   23.74 -    0,                                                      // tp_str
   23.75 -    (getattrofunc) 0,                                       // tp_getattro
   23.76 -    (setattrofunc) 0,                                       // tp_setattro
   23.77 -    0,                                                      // tp_as_buffer
   23.78 -    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,               // tp_flags
   23.79 -    PyLM__G_doc,                                            // tp_doc
   23.80 -    0,                                                      // tp_traverse
   23.81 -    0,                                                      // tp_clear
   23.82 -    0,                                                      // tp_richcompare
   23.83 -    0,                                                      // tp_weaklistoffset
   23.84 -    0,                                                      // tp_iter
   23.85 -    0,                                                      // tp_iternext
   23.86 -    0,                                                      // tp_methods
   23.87 -    0,                                                      // tp_members
   23.88 -    0,                                                      // tp_getset
   23.89 -    0,                                                      // tp_base
   23.90 -    0,                                                      // tp_dict
   23.91 -    0,                                                      // tp_descr_get
   23.92 -    0,                                                      // tp_descr_set
   23.93 -    0,                                                      // tp_dictoffset
   23.94 -    0,                                                      // tp_init
   23.95 -    0,                                                      // tp_alloc
   23.96 -    PyLM__G_new,                                            // tp_new
   23.97 -    0,                                                      // tp_free
   23.98 -    0,                                                      // tp_is_gc
   23.99 -};
  23.100 -
    24.1 --- a/python/__init__.c	Wed Dec 25 20:33:47 2013 -0500
    24.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.3 @@ -1,91 +0,0 @@
    24.4 -/*
    24.5 - *  LightMelody - Lightweight XMPP/Jingle Client Library
    24.6 - *  Copyright (C) 2012 Copyleft Games Group
    24.7 - *
    24.8 - *  This program is free software; you can redistribute it and/or modify
    24.9 - *  it under the terms of the GNU Affero General Public License as published
   24.10 - *  by the Free Software Foundation, either version 3 of the License, or
   24.11 - *  (at your option) any later version.
   24.12 - *
   24.13 - *  This program is distributed in the hope that it will be useful,
   24.14 - *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   24.15 - *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   24.16 - *  GNU Affero General Public License for more details.
   24.17 - *
   24.18 - *  You should have received a copy of the GNU Affero General Public License
   24.19 - *  along with this program; if not, see http://www.gnu.org/licenses
   24.20 - *
   24.21 - */
   24.22 -
   24.23 -#include "pylm.h"
   24.24 -
   24.25 -
   24.26 -static char
   24.27 -m_doc[] = "lightmelody\n"
   24.28 -"\n";
   24.29 -
   24.30 -static struct PyModuleDef module_def = {
   24.31 -    PyModuleDef_HEAD_INIT,
   24.32 -    "lightmelody",                                         // m_name
   24.33 -    m_doc,                                                 // m_doc
   24.34 -    0,                                                     // m_size
   24.35 -    NULL,                                                  // m_methods
   24.36 -    NULL,                                                  // m_reload
   24.37 -    NULL,                                                  // m_traverse
   24.38 -    NULL,                                                  // m_clear
   24.39 -    NULL                                                   // m_free
   24.40 -};
   24.41 -
   24.42 -
   24.43 -PyMODINIT_FUNC
   24.44 -PyInit_lightmelody(void) {
   24.45 -    PyObject *module, *dict, *sys, *args, *meta_path, *modules, *submodule;
   24.46 -
   24.47 -    /////////////////////////////////////////////////////////////////////////
   24.48 -    // Initialize lightmelody
   24.49 -
   24.50 -    GPyObject = g_quark_from_string("PyObject");
   24.51 -
   24.52 -
   24.53 -    /////////////////////////////////////////////////////////////////////////
   24.54 -    // Initialize all types prior to module creation
   24.55 -    //
   24.56 -    //  int PyType_Ready(PyTypeObject*)
   24.57 -    //    Finalize a type object. This should be called on all type objects to
   24.58 -    //    finish their initialization. This function is responsible for adding
   24.59 -    //    inherited slots from a type's base class.
   24.60 -    //    Return 0 on success, or return -1 and sets an exception on error.
   24.61 -
   24.62 -    // init _G type
   24.63 -    PYLM_TYPEINIT(_G);
   24.64 -
   24.65 -    // additional types above this line in alphabetical order
   24.66 -    /////////////////////////////////////////////////////////////////////////
   24.67 -
   24.68 -
   24.69 -    module = PyModule_Create(&module_def);
   24.70 -    dict = PyModule_GetDict(module);
   24.71 -
   24.72 -    // add additional pydoc strings
   24.73 -    PyModule_AddStringConstant(module, "__credits__", LM_LICENSE);
   24.74 -    PyModule_AddStringConstant(module, "__version__", LM_VERSION);
   24.75 -
   24.76 -
   24.77 -    /////////////////////////////////////////////////////////////////////////
   24.78 -    // add each type to the module object
   24.79 -
   24.80 -    // add _G type
   24.81 -    PYLM_TYPEADD(_G);
   24.82 -
   24.83 -    // additional types above this line in alphabetical order
   24.84 -    /////////////////////////////////////////////////////////////////////////
   24.85 -    // return module
   24.86 -
   24.87 -    if (PyErr_Occurred()) {
   24.88 -        PyErr_SetString(PyExc_ImportError, "lightmelody: module init failed");
   24.89 -        return NULL;
   24.90 -    }
   24.91 -
   24.92 -    return module;
   24.93 -}
   24.94 -
    25.1 --- a/python/pylm.h	Wed Dec 25 20:33:47 2013 -0500
    25.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.3 @@ -1,400 +0,0 @@
    25.4 -/*
    25.5 -    Copyright (C) 2012 Copyleft Games Group
    25.6 -
    25.7 -    This program is free software; you can redistribute it and/or modify
    25.8 -    it under the terms of the GNU Affero General Public License as published
    25.9 -    by the Free Software Foundation, either version 3 of the License, or
   25.10 -    (at your option) any later version.
   25.11 -
   25.12 -    This program is distributed in the hope that it will be useful,
   25.13 -    but WITHOUT ANY WARRANTY; without even the implied warranty of
   25.14 -    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   25.15 -    GNU Affero General Public License for more details.
   25.16 -
   25.17 -    You should have received a copy of the GNU Affero General Public License
   25.18 -    along with this program; if not, see http://www.gnu.org/licenses
   25.19 -*/
   25.20 -
   25.21 -#ifndef __PYLM_H__
   25.22 -#define __PYLM_H__
   25.23 -
   25.24 -
   25.25 -#include <Python.h>
   25.26 -#include <lightmelody.h>
   25.27 -#include <config.h>
   25.28 -#include <gio/gio.h>
   25.29 -
   25.30 -
   25.31 -GQuark GPyObject;
   25.32 -
   25.33 -
   25.34 -/////////////////////////////////////////////////////////////////////////////
   25.35 -// Macros
   25.36 -
   25.37 -#define PYLM_TYPEADD(T) \
   25.38 -    Py_INCREF(&PyLM_ ## T ## _Type);\
   25.39 -    PyModule_AddObject(module, #T, (PyObject*)&PyLM_ ## T ## _Type)
   25.40 -
   25.41 -
   25.42 -#define PYLM_TYPEADD_G(C, T) \
   25.43 -    PYLM_TYPEADD(T);\
   25.44 -    g_type_set_qdata(lm_ ## C ## _get_type (), GPyObject,\
   25.45 -                     &PyLM_ ## T ## _Type)
   25.46 -
   25.47 -
   25.48 -#define PYLM_TYPEINIT(t) \
   25.49 -    if (PyType_Ready(&PyLM_ ## t ## _Type) < 0) return NULL
   25.50 -
   25.51 -
   25.52 -// PYLM_PROP_BOOL
   25.53 -//   C (Class) is the lightmelody Class (lowercase)
   25.54 -//   P (Property) is the lightmelody property (lowercase)
   25.55 -//   ie; PYLM_PROP_BOOL(atoms, color, alpha)
   25.56 -#define PYLM_PROP_BOOL(C, P) \
   25.57 -static PyObject*\
   25.58 -P ## _getter (SELF self, void* closure) {\
   25.59 -    return PyBool_FromLong(lm_ ## C ## _get_ ## P \
   25.60 -                           ((gpointer) self->g) );\
   25.61 -}\
   25.62 -static int \
   25.63 -P ## _setter (SELF self, PyObject* value, void* closure) {\
   25.64 -    int b;\
   25.65 -    if (value==NULL) {\
   25.66 -        PyErr_SetString(PyExc_AttributeError, \
   25.67 -                        "cannot delete " #P " property"); \
   25.68 -        return -1;\
   25.69 -    }\
   25.70 -    b = PyObject_IsTrue(value);\
   25.71 -    if (b == -1) {\
   25.72 -        return -1;\
   25.73 -    }\
   25.74 -    lm_ ## C ## _set_ ## P ((gpointer) self->g, b);\
   25.75 -    return 0;\
   25.76 -}
   25.77 -
   25.78 -// PYLM_PROP_BOOL_RO - Read Only
   25.79 -//   C (Class) is the lightmelody Class (lowercase)
   25.80 -//   P (Property) is the lightmelody property (lowercase)
   25.81 -//   ie; PYLM_PROP_BOOL_RO(atoms, color, alpha)
   25.82 -#define PYLM_PROP_BOOL_RO(C, P) \
   25.83 -static PyObject*\
   25.84 -P ## _getter (SELF self, void* closure) {\
   25.85 -    return PyBool_FromLong(lm_ ## C ## _get_ ## P \
   25.86 -                           ((gpointer) self->g) );\
   25.87 -}
   25.88 -
   25.89 -// PYLM_PROP_UCHAR
   25.90 -//   C (Class) is the lightmelody Class (lowercase)
   25.91 -//   P (Property) is the lightmelody property (lowercase)
   25.92 -//   ie; PYLM_PROP_UCHAR(atoms, color, alpha)
   25.93 -#define PYLM_PROP_UCHAR(C, P) \
   25.94 -static PyObject*\
   25.95 -P ## _getter (SELF self, void* closure) {\
   25.96 -    return PyLong_FromLong(lm_ ## C ## _get_ ## P \
   25.97 -                           ((gpointer) self->g) );\
   25.98 -}\
   25.99 -static int \
  25.100 -P ## _setter (SELF self, PyObject* value, void* closure) {\
  25.101 -    if (value==NULL) {\
  25.102 -        PyErr_SetString(PyExc_AttributeError, \
  25.103 -                        "cannot delete " #P " property"); \
  25.104 -        return -1;\
  25.105 -    }\
  25.106 -    if (!PyLong_Check(value)) {\
  25.107 -        PyErr_SetString(PyExc_TypeError, \
  25.108 -                        "Value must be an integer"); \
  25.109 -        return -1;\
  25.110 -    }\
  25.111 -    lm_ ## C ## _set_ ## P ((gpointer) self->g, \
  25.112 -                                       PyLong_AsLong(value));\
  25.113 -    return 0;\
  25.114 -}
  25.115 -
  25.116 -
  25.117 -// PYLM_PROP_FLOAT
  25.118 -//   C (Class) is the lightmelody Class (lowercase)
  25.119 -//   P (Property) is the lightmelody property (lowercase)
  25.120 -//   ie; PYLM_PROP_FLOAT(atoms, color, alpha)
  25.121 -#define PYLM_PROP_FLOAT(C, P) \
  25.122 -static PyObject*\
  25.123 -P ## _getter (SELF self, void* closure) {\
  25.124 -    return PyFloat_FromDouble(lm_ ## C ## _get_ ## P \
  25.125 -                              ((gpointer) self->g) );\
  25.126 -}\
  25.127 -static int \
  25.128 -P ## _setter (SELF self, PyObject* value, void* closure) {\
  25.129 -    if (value==NULL) {\
  25.130 -        PyErr_SetString(PyExc_AttributeError, \
  25.131 -                        "cannot delete " #P " property"); \
  25.132 -        return -1;\
  25.133 -    }\
  25.134 -    if (!PyNumber_Check(value)) {\
  25.135 -        PyErr_SetString(PyExc_TypeError, \
  25.136 -                        "Value must be a number"); \
  25.137 -        return -1;\
  25.138 -    }\
  25.139 -    lm_ ## C ## _set_ ## P ((gpointer) self->g, \
  25.140 -                                       PyFloat_AsDouble(value));\
  25.141 -    return 0;\
  25.142 -}
  25.143 -
  25.144 -
  25.145 -// PYLM_PROP_FLOAT_RO - Read Only
  25.146 -//   C (Class) is the lightmelody Class (lowercase)
  25.147 -//   P (Property) is the lightmelody property (lowercase)
  25.148 -//   ie; PYLM_PROP_FLOAT(textures, texture, aspect)
  25.149 -#define PYLM_PROP_FLOAT_RO(C, P) \
  25.150 -static PyObject*\
  25.151 -P ## _getter (SELF self, void* closure) {\
  25.152 -    return PyFloat_FromDouble(lm_ ## C ## _get_ ## P \
  25.153 -                              ((gpointer) self->g) );\
  25.154 -}
  25.155 -
  25.156 -
  25.157 -// PYLM_PROP_STRING
  25.158 -//   C (Class) is the lightmelody Class (lowercase)
  25.159 -//   P (Property) is the lightmelody property (lowercase)
  25.160 -//   ie; PYLM_PROP_STRING(atoms, color, hex)
  25.161 -#define PYLM_PROP_STRING(C, P) \
  25.162 -static PyObject*\
  25.163 -P ## _getter (SELF self, void* closure) {\
  25.164 -    return PyUnicode_FromString(lm_ ## C ## _get_ ## P \
  25.165 -                              ((gpointer) self->g) );\
  25.166 -}\
  25.167 -static int \
  25.168 -P ## _setter (SELF self, PyObject* value, void* closure) {\
  25.169 -    PyObject* bytes; \
  25.170 -    if (value==NULL) { \
  25.171 -        PyErr_SetString(PyExc_AttributeError, \
  25.172 -                        "cannot delete " #P " property"); \
  25.173 -        return -1;\
  25.174 -    }\
  25.175 -    if (!PyUnicode_Check(value)) {\
  25.176 -        PyErr_SetString(PyExc_TypeError, \
  25.177 -                        "Value must be a string"); \
  25.178 -        return -1;\
  25.179 -    }\
  25.180 -	bytes = PyUnicode_AsUTF8String(value); \
  25.181 -    lm_ ## C ## _set_ ## P ((gpointer) self->g, \
  25.182 -                                       PyBytes_AsString(bytes));\
  25.183 -    return 0;\
  25.184 -}
  25.185 -
  25.186 -
  25.187 -// PYLM_PROP_OBJECT
  25.188 -//   C (Class) is the lightmelody Class (lowercase)
  25.189 -//   P (Property) is the lightmelody property (lowercase)
  25.190 -//   V (Value) is the PyLM type of property value (as module_Type)
  25.191 -//   ie; PYLM_PROP(scenes, Scene, ambient, atoms_Color);
  25.192 -#define PYLM_PROP_OBJECT(C, P, V) \
  25.193 -static PyObject*\
  25.194 -P ## _getter (SELF self, void* closure) {\
  25.195 -    gpointer g;\
  25.196 -    PyLM__G_Object* ret;\
  25.197 -    g = lm_ ## C ## _get_ ## P ((gpointer) self->g);\
  25.198 -    if (!g) Py_RETURN_NONE;\
  25.199 -    ret = (PyLM__G_Object*) \
  25.200 -          PyType_GenericNew(g_type_get_qdata(G_OBJECT_TYPE(g), GPyObject), \
  25.201 -                            NULL, NULL);\
  25.202 -    if (!ret) return NULL;\
  25.203 -    ret->g = g;\
  25.204 -    g_object_ref(g);\
  25.205 -    return (PyObject*) ret;\
  25.206 -}\
  25.207 -static int \
  25.208 -P ## _setter (SELF self, PyObject* value, void* closure) {\
  25.209 -    if (value==NULL) {\
  25.210 -        PyErr_SetString(PyExc_AttributeError, \
  25.211 -                        "cannot delete " #P " property");\
  25.212 -        return -1;\
  25.213 -    }\
  25.214 -    if (PyObject_IsInstance(value, (PyObject*) &PyLM_ ## V ## _Type)!=1){\
  25.215 -        PyErr_SetString(PyExc_TypeError, \
  25.216 -                        "Incorrect type for " #P " property");\
  25.217 -        return -1;\
  25.218 -    }\
  25.219 -    lm_ ## C ## _set_ ## P ((gpointer) self->g, \
  25.220 -                                       ((PyLM_ ## V ## _Object*) value)->g);\
  25.221 -    return 0;\
  25.222 -}
  25.223 -
  25.224 -
  25.225 -// PYLM_PROP_OBJECT_OWNED
  25.226 -//   C (Class) is the lightmelody Class (lowercase)
  25.227 -//   P (Property) is the lightmelody property (lowercase)
  25.228 -//   V (Value) is the PyLM type of property value (as module_Type)
  25.229 -//   ie; PYLM_PROP_OBJECT_OWNED(scenes, scene, ambient, atoms_Color);
  25.230 -#define PYLM_PROP_OBJECT_OWNED(C, P, V) \
  25.231 -static PyObject*\
  25.232 -P ## _getter (SELF self, void* closure) {\
  25.233 -    gpointer g;\
  25.234 -    PyLM__G_Object* ret;\
  25.235 -    g = lm_ ## C ## _get_ ## P ((gpointer) self->g);\
  25.236 -    if (!g) Py_RETURN_NONE;\
  25.237 -    ret = (PyLM__G_Object*) \
  25.238 -          PyType_GenericNew(g_type_get_qdata(G_OBJECT_TYPE(g), GPyObject), \
  25.239 -                            NULL, NULL);\
  25.240 -    if (!ret) return NULL;\
  25.241 -    ret->g = g;\
  25.242 -    return (PyObject*) ret;\
  25.243 -}\
  25.244 -static int \
  25.245 -P ## _setter (SELF self, PyObject* value, void* closure) {\
  25.246 -    if (value==NULL) {\
  25.247 -        PyErr_SetString(PyExc_AttributeError, \
  25.248 -                        "cannot delete " #P " property");\
  25.249 -        return -1;\
  25.250 -    }\
  25.251 -    if (PyObject_IsInstance(value, (PyObject*) &PyLM_ ## V ## _Type)!=1){\
  25.252 -        PyErr_SetString(PyExc_TypeError, \
  25.253 -                        "Incorrect type for " #P " property");\
  25.254 -        return -1;\
  25.255 -    }\
  25.256 -    lm_ ## C ## _set_ ## P ((gpointer) self->g, \
  25.257 -                                       ((PyLM_ ## V ## _Object*) value)->g);\
  25.258 -    return 0;\
  25.259 -}
  25.260 -
  25.261 -
  25.262 -// PYLM_PROP_OBJECT_DELETABLE
  25.263 -//   C (Class) is the lightmelody Class (lowercase)
  25.264 -//   P (Property) is the lightmelody property (lowercase)
  25.265 -//   V (Value) is the PyLM type of property value (as module_Type)
  25.266 -#define PYLM_PROP_OBJECT_DELETABLE(C, P, V) \
  25.267 -static PyObject*\
  25.268 -P ## _getter (SELF self, void* closure) {\
  25.269 -    gpointer g;\
  25.270 -    PyLM__G_Object* ret;\
  25.271 -    g = lm_ ## C ## _get_ ## P ((gpointer) self->g);\
  25.272 -    if (!g) Py_RETURN_NONE;\
  25.273 -    ret = (PyLM__G_Object*) \
  25.274 -          PyType_GenericNew(g_type_get_qdata(G_OBJECT_TYPE(g), GPyObject), \
  25.275 -                            NULL, NULL);\
  25.276 -    if (!ret) return NULL;\
  25.277 -    ret->g = g;\
  25.278 -    g_object_ref(g);\
  25.279 -    return (PyObject*) ret;\
  25.280 -}\
  25.281 -static int \
  25.282 -P ## _setter (SELF self, PyObject* value, void* closure) {\
  25.283 -    if (value==NULL || value==Py_None) {\
  25.284 -        lm_ ## C ## _set_ ## P ((gpointer) self->g, NULL);\
  25.285 -        return 0;\
  25.286 -    }\
  25.287 -    if (PyObject_IsInstance(value, (PyObject*) &PyLM_ ## V ## _Type)!=1){\
  25.288 -        PyErr_SetString(PyExc_TypeError, \
  25.289 -                        "Incorrect type for " #P " property");\
  25.290 -        return -1;\
  25.291 -    }\
  25.292 -    lm_ ## C ## _set_ ## P ((gpointer) self->g, \
  25.293 -                                       ((PyLM_ ## V ## _Object*) value)->g);\
  25.294 -    return 0;\
  25.295 -}
  25.296 -
  25.297 -
  25.298 -// PYLM_PROP_OBJECT_MEMBER
  25.299 -//   C (Class) is the lightmelody Class (lowercase)
  25.300 -//   T (Type) is the PyLM Type (Titled)
  25.301 -//   P (Property) is the lightmelody property (lowercase)
  25.302 -//   V (Value) is the PyLM type of property value (as module_Type)
  25.303 -//  This works the same as PYLM_PROP_OBJECT but with lightmelody object members
  25.304 -#define PYLM_PROP_OBJECT_MEMBER(C, T, P, V) \
  25.305 -static PyObject*\
  25.306 -PyLM_ ## T ## _ ## P ## _getter (PyLM_ ## T ## _Object*\
  25.307 -                                            self,\
  25.308 -                                            void* closure) {\
  25.309 -    gpointer g;\
  25.310 -    PyLM__G_Object* ret;\
  25.311 -    g = self->g->P;\
  25.312 -    ret = (PyLM__G_Object*) \
  25.313 -          PyType_GenericNew(g_type_get_qdata(G_OBJECT_TYPE(g), GPyObject), \
  25.314 -                            NULL, NULL);\
  25.315 -    if (!ret) return NULL;\
  25.316 -    ret->g = g;\
  25.317 -    g_object_ref(g);\
  25.318 -    return (PyObject*) ret;\
  25.319 -}\
  25.320 -static int \
  25.321 -PyLM_ ## T ## _ ## P ## _setter (PyLM_ ## T ## _Object* \
  25.322 -                                            self, \
  25.323 -                                            PyObject* value, void* closure) {\
  25.324 -    if (value==NULL) {\
  25.325 -        PyErr_SetString(PyExc_AttributeError, \
  25.326 -                        "cannot delete " #P " property");\
  25.327 -        return -1;\
  25.328 -    }\
  25.329 -    if (PyObject_IsInstance(value, (PyObject*) &PyLM_ ## V ## _Type)!=1){\
  25.330 -        PyErr_SetString(PyExc_TypeError, \
  25.331 -                        "Incorrect type for " #P " property");\
  25.332 -        return -1;\
  25.333 -    }\
  25.334 -    if (self->g->P)\
  25.335 -        g_object_unref(self->g->P);\
  25.336 -    if (value==NULL)\
  25.337 -        self->g->P = NULL;\
  25.338 -    else {\
  25.339 -        self->g->P = ((PyLM_ ## V ## _Object*) value)->g;\
  25.340 -        g_object_ref(self->g->P);\
  25.341 -    }\
  25.342 -    return 0;\
  25.343 -}
  25.344 -
  25.345 -// PYLM_PROP_OBJECT_LIST
  25.346 -//  C (Class) is the lightmelody class (lowercase)
  25.347 -//  P (Property) is the property name (lowercase)
  25.348 -//  ie; PYLM_PROP_LIST(models, target, Target, morphs)
  25.349 -#define PYLM_PROP_OBJECT_LIST(C, P) \
  25.350 -static PyObject*\
  25.351 -P ## _getter (SELF self, void* closure) {\
  25.352 -    gint size;\
  25.353 -    gpointer g;\
  25.354 -    PyObject* ret;\
  25.355 -    PyLM__G_Object* obj;\
  25.356 -    GeeArrayList* lst;\
  25.357 -    gint i;\
  25.358 -    lst = lm_ ## C ## _get_ ## P(self->g);\
  25.359 -    size = gee_collection_get_size((GeeCollection*) lst);\
  25.360 -    ret = PyList_New(size);\
  25.361 -    for(i=0;i<size;i++){\
  25.362 -        g = gee_list_get((GeeList*)lst,i);\
  25.363 -        obj = (PyLM__G_Object*) \
  25.364 -          PyType_GenericNew(g_type_get_qdata(G_OBJECT_TYPE(g), GPyObject), \
  25.365 -                            NULL, NULL);\
  25.366 -        if (!obj) return NULL;\
  25.367 -        obj->g = g;\
  25.368 -        g_object_ref(g);\
  25.369 -        Py_INCREF(obj);\
  25.370 -        PyList_SetItem(ret,i,(PyObject*)obj);\
  25.371 -    }\
  25.372 -    Py_INCREF(ret);\
  25.373 -    return ret;\
  25.374 -}\
  25.375 -static int \
  25.376 -P ## _setter (SELF self, PyObject* value, void* closure) {\
  25.377 -    return 0;\
  25.378 -}
  25.379 -
  25.380 -
  25.381 -// PYLM_PROPSTRUCT
  25.382 -//   P (Property) is the property name
  25.383 -#define PYLM_PROPSTRUCT(P) \
  25.384 -    {#P,\
  25.385 -     (getter) P ## _getter,\
  25.386 -     (setter) P ## _setter,\
  25.387 -     P ## _doc,\
  25.388 -     NULL}
  25.389 -
  25.390 -
  25.391 -/////////////////////////////////////////////////////////////////////////////
  25.392 -// lightmelody
  25.393 -
  25.394 -// lightmelody._G
  25.395 -PyTypeObject PyLM__G_Type;
  25.396 -typedef struct {
  25.397 -    PyObject_HEAD
  25.398 -    gpointer g;
  25.399 -} PyLM__G_Object;
  25.400 -#define PyLM__G_Check(op) \
  25.401 -    PyObject_TypeCheck(op, &PyLM__G_Type)
  25.402 -
  25.403 -#endif // __PYLM_H__
    26.1 --- a/python/wscript_build	Wed Dec 25 20:33:47 2013 -0500
    26.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.3 @@ -1,27 +0,0 @@
    26.4 -# encoding: utf-8
    26.5 -#
    26.6 -#   LightMelody - Lightweight XMPP/Jingle Client Library
    26.7 -#   Copyright (C) 2012 Copyleft Games Group
    26.8 -#
    26.9 -#   This program is free software; you can redistribute it and/or modify
   26.10 -#   it under the terms of the GNU Affero General Public License as published
   26.11 -#   by the Free Software Foundation, either version 3 of the License, or
   26.12 -#   (at your option) any later version.
   26.13 -#
   26.14 -#   This program is distributed in the hope that it will be useful,
   26.15 -#   but WITHOUT ANY WARRANTY; without even the implied warranty of
   26.16 -#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   26.17 -#   GNU Affero General Public License for more details.
   26.18 -#
   26.19 -#   You should have received a copy of the GNU Affero General Public License
   26.20 -#   along with this program; if not, see http://www.gnu.org/licenses
   26.21 -
   26.22 -bld.shlib(
   26.23 -    features    = 'pyext',
   26.24 -    name        = 'python-lightmelody',
   26.25 -    source      = bld.path.ant_glob('*.c'),
   26.26 -    target      = 'lightmelody',
   26.27 -    includes    = '../include ../build/src',
   26.28 -    use         = 'lightmelody',
   26.29 -    uselib      = ['GLIB', 'GEE', 'IDN', 'SSL', 'ASYNCNS']
   26.30 -)
    27.1 --- a/src/AuthParameters.gs	Wed Dec 25 20:33:47 2013 -0500
    27.2 +++ b/src/AuthParameters.gs	Mon Dec 15 05:04:57 2014 +0000
    27.3 @@ -1,5 +1,5 @@
    27.4  /*
    27.5 - *  Copyright (C) 2012 Copyleft Games Group
    27.6 + *  Copyright (C) 2012,2013,2014 Copyleft Games Group
    27.7   *
    27.8   *  This program is free software; you can redistribute it and/or modify
    27.9   *  it under the terms of the GNU Affero General Public License as published
    28.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.2 +++ b/src/CertificateStatus.gs	Mon Dec 15 05:04:57 2014 +0000
    28.3 @@ -0,0 +1,28 @@
    28.4 +/*
    28.5 + *  LightMelody - Lightweight XMPP/Jingle Client Library
    28.6 + *  Copyright (C) 2012,2013,2014 Copyleft Games Group
    28.7 + *
    28.8 + *  This program is free software; you can redistribute it and/or modify
    28.9 + *  it under the terms of the GNU Affero General Public License as published
   28.10 + *  by the Free Software Foundation, either version 3 of the License, or
   28.11 + *  (at your option) any later version.
   28.12 + *
   28.13 + *  This program is distributed in the hope that it will be useful,
   28.14 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   28.15 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   28.16 + *  GNU Affero General Public License for more details.
   28.17 + *
   28.18 + *  You should have received a copy of the GNU Affero General Public License
   28.19 + *  along with this program; if not, see http://www.gnu.org/licenses
   28.20 + *
   28.21 + */
   28.22 +
   28.23 +[indent=4]
   28.24 +
   28.25 +
   28.26 +[CCode (cprefix = "LM_CERT_")]
   28.27 +enum Lm.CertificateStatus
   28.28 +    INVALID
   28.29 +    ISSUER_NOT_FOUND
   28.30 +    REVOKED
   28.31 +
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/src/Connection.gs	Mon Dec 15 05:04:57 2014 +0000
    29.3 @@ -0,0 +1,485 @@
    29.4 +/*
    29.5 + *  LightMelody - Lightweight XMPP/Jingle Client Library
    29.6 + *  Copyright (C) 2012,2013,2014 Copyleft Games Group
    29.7 + *
    29.8 + *  This program is free software; you can redistribute it and/or modify
    29.9 + *  it under the terms of the GNU Affero General Public License as published
   29.10 + *  by the Free Software Foundation, either version 3 of the License, or
   29.11 + *  (at your option) any later version.
   29.12 + *
   29.13 + *  This program is distributed in the hope that it will be useful,
   29.14 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   29.15 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   29.16 + *  GNU Affero General Public License for more details.
   29.17 + *
   29.18 + *  You should have received a copy of the GNU Affero General Public License
   29.19 + *  along with this program; if not, see http://www.gnu.org/licenses
   29.20 + *
   29.21 + */
   29.22 +
   29.23 +[indent=4]
   29.24 +
   29.25 +namespace Lm
   29.26 +
   29.27 +    delegate DisconnectFunction (connection : Lm.Connection,
   29.28 +                                 reason : DisconnectReason)
   29.29 +
   29.30 +    delegate ResultFunction (connection : Lm.Connection, success : bool)
   29.31 +
   29.32 +
   29.33 +    [CCode (cprefix = "LM_DISCONNECT_REASON_", has_type_id = false)]
   29.34 +    enum DisconnectReason
   29.35 +        OK
   29.36 +        PING_TIME_OUT
   29.37 +        HUP
   29.38 +        ERROR
   29.39 +        RESOURCE_CONFLICT
   29.40 +        INVALID_XML
   29.41 +        UNKNOWN
   29.42 +
   29.43 +
   29.44 +class Lm.Connection : Object
   29.45 +
   29.46 +    enum State
   29.47 +        CLOSED
   29.48 +        OPENING
   29.49 +        OPEN
   29.50 +        AUTHENTICATING
   29.51 +        AUTHENTICATED
   29.52 +
   29.53 +    _context : MainContext?
   29.54 +
   29.55 +    _server : string?
   29.56 +    _port : int
   29.57 +    stream_id : string?
   29.58 +
   29.59 +    // Stream object to send/receive data regardless of the connection type.
   29.60 +    _stream : IOStream
   29.61 +
   29.62 +    // Connection JID (user@domain/resource)
   29.63 +    _jid : string?
   29.64 +    _effective_jid : string?
   29.65 +    resource : string?
   29.66 +
   29.67 +    _last_id : uint64
   29.68 +
   29.69 +    state : State
   29.70 +    queue : MessageQueue
   29.71 +    // socket
   29.72 +    _ssl : SSL
   29.73 +    _proxy : Proxy
   29.74 +    //parser
   29.75 +
   29.76 +    // Registered Message Handlers
   29.77 +    id_handlers : dict of string, MessageHandler
   29.78 +    stanza_handlers : array of list of MessageHandlerEntry
   29.79 +
   29.80 +    // Basic XMPP Message Handlers
   29.81 +    streamerror_handler : MessageHandler
   29.82 +
   29.83 +    // Authentication
   29.84 +    use_sasl : bool // We're just going to ignore this
   29.85 +    //sasl : SASLA
   29.86 +    tls_started : bool
   29.87 +
   29.88 +    // Keep Alive
   29.89 +    _keep_alive_rate : uint
   29.90 +
   29.91 +    // Deprecated Async Callbacks
   29.92 +    _auth_func : ResultFunction
   29.93 +    _open_func : ResultFunction
   29.94 +
   29.95 +
   29.96 +    init
   29.97 +        self.port = 5222 // default in case a SRV record can't be found
   29.98 +        self.state = State.CLOSED
   29.99 +        self.queue = new MessageQueue(self._message_queue_cb)
  29.100 +
  29.101 +        // Used to ensure unique IQ IDs
  29.102 +        self._last_id = 0
  29.103 +
  29.104 +        // Create handler lists
  29.105 +        self.id_handlers = new dict of string, MessageHandler
  29.106 +        self.stanza_handlers = {
  29.107 +            new list of MessageHandlerEntry, // Lm.Message.Type.MESSAGE
  29.108 +            new list of MessageHandlerEntry, // Lm.Message.Type.PRESENCE
  29.109 +            new list of MessageHandlerEntry, // Lm.Message.Type.IQ
  29.110 +            new list of MessageHandlerEntry, // Lm.Message.Type.STREAM
  29.111 +            new list of MessageHandlerEntry, // Lm.Message.Type.STREAM_ERROR
  29.112 +            new list of MessageHandlerEntry, // Lm.Message.Type.STREAM_FEATURES
  29.113 +            new list of MessageHandlerEntry, // Lm.Message.Type.AUTH
  29.114 +            new list of MessageHandlerEntry, // Lm.Message.Type.CHALLENGE
  29.115 +            new list of MessageHandlerEntry, // Lm.Message.Type.RESPONSE
  29.116 +            new list of MessageHandlerEntry, // Lm.Message.Type.SUCCESS
  29.117 +            new list of MessageHandlerEntry, // Lm.Message.Type.FAILURE
  29.118 +            new list of MessageHandlerEntry, // Lm.Message.Type.PROCEED
  29.119 +            new list of MessageHandlerEntry, // Lm.Message.Type.STARTTLS
  29.120 +            new list of MessageHandlerEntry  // Lm.Message.Type.UNKNOWN
  29.121 +        }
  29.122 +
  29.123 +        // Register core handlers
  29.124 +        self.register_message_handler(new MessageHandler(_stream_error_cb),
  29.125 +                                      Message.Type.STREAM_ERROR,
  29.126 +                                      HandlerPriority.LAST)
  29.127 +
  29.128 +
  29.129 +    construct (server : string?)
  29.130 +        self.server = server
  29.131 +
  29.132 +
  29.133 +    construct with_context (server : string?, context : MainContext)
  29.134 +        self.server = server
  29.135 +        self._context = context
  29.136 +
  29.137 +
  29.138 +    //////////////////////////////////////////////////////////////////////////
  29.139 +    // Callbacks
  29.140 +
  29.141 +    def inline _message_queue_cb(queue : MessageQueue)
  29.142 +        result : HandlerResult
  29.143 +        //handler : MessageHandler
  29.144 +        m : Message = queue.pop_nth(0)
  29.145 +        if m is null
  29.146 +            return
  29.147 +
  29.148 +        if m.get_type() == Message.Type.STREAM
  29.149 +            // connection_stream_received(m)
  29.150 +            return
  29.151 +
  29.152 +
  29.153 +
  29.154 +        if (m.get_type() != Message.Type.IQ ||
  29.155 +            m.sub_type == Message.SubType.ERROR ||
  29.156 +            m.sub_type == Message.SubType.RESULT)
  29.157 +            //result = run_message_handler(m)
  29.158 +            result = HandlerResult.ALLOW_MORE_HANDLERS
  29.159 +            if result == HandlerResult.REMOVE_MESSAGE
  29.160 +                return
  29.161 +
  29.162 +        // Pass message to each handler until we're told to stop
  29.163 +        for entry in stanza_handlers[m.get_type()]
  29.164 +            if (entry.handler.handle_message(entry.handler, self, m)
  29.165 +                is HandlerResult.REMOVE_MESSAGE)
  29.166 +                break
  29.167 +
  29.168 +
  29.169 +    def inline _stream_error_cb(handler : MessageHandler,
  29.170 +                                connection : Connection,
  29.171 +                                message : Message) : HandlerResult
  29.172 +        node : MessageNode = message.node
  29.173 +        reason : DisconnectReason
  29.174 +
  29.175 +        // Resource conflict
  29.176 +         if node.get_child("conflict") is not null
  29.177 +            // lm_verbose ("Stream error: Conflict (resource connected elsewhere)\n");
  29.178 +            reason = DisconnectReason.RESOURCE_CONFLICT
  29.179 +
  29.180 +        // We sent broken XML
  29.181 +        else if node.get_child("xml-not-well-formed") is not null
  29.182 +            // lm_verbose ("Stream error: XML not well formed\n");
  29.183 +            reason = DisconnectReason.INVALID_XML
  29.184 +
  29.185 +        // Something we're too lazy to care about
  29.186 +        else
  29.187 +            //lm_verbose ("Stream error: Unrecognised error\n");
  29.188 +            reason = DisconnectReason.ERROR
  29.189 +
  29.190 +        self.stream_id = node.get_attribute("id")
  29.191 +        //connection_do_close (connection)
  29.192 +        //connection_signal_disconnect (connection, reason)
  29.193 +        return HandlerResult.REMOVE_MESSAGE
  29.194 +
  29.195 +
  29.196 +    //////////////////////////////////////////////////////////////////////////
  29.197 +    // Methods
  29.198 +
  29.199 +    def authenticate (username : string, password : string, resource : string,
  29.200 +                      function : ResultFunction#) : bool raises Error
  29.201 +        domain : string
  29.202 +
  29.203 +        if !self.is_open()
  29.204 +            /* TODO
  29.205 +            g_set_error (error,
  29.206 +                         LM_ERROR,
  29.207 +                         LM_ERROR_CONNECTION_NOT_OPEN,
  29.208 +                         "Connection is not open, call lm_connection_open() first");
  29.209 +            */
  29.210 +            return false
  29.211 +
  29.212 +        state = State.AUTHENTICATING
  29.213 +
  29.214 +        // Store callback
  29.215 +        _auth_func = (owned) function
  29.216 +
  29.217 +        self.resource = resource
  29.218 +        self._effective_jid = self.jid + resource
  29.219 +
  29.220 +        /* TODO get domain
  29.221 +           TODO convert sasl.authenticate to a real async call
  29.222 +
  29.223 +        sasl.authenticate(new AuthParameters(username, password, resource),
  29.224 +                          domain, self._sasl_auth_result)
  29.225 +        */
  29.226 +
  29.227 +        return true
  29.228 +
  29.229 +
  29.230 +    def authenticate_and_block (username : string, password : string,
  29.231 +                                resource : string) : bool raises Error
  29.232 +        // TODO
  29.233 +        return true
  29.234 +
  29.235 +
  29.236 +    def generate_id ( ) : string
  29.237 +        tv : TimeVal = TimeVal()
  29.238 +        val : uint64
  29.239 +        hi : uint
  29.240 +        lo : uint
  29.241 +
  29.242 +        val = (tv.tv_sec * 1000000) + tv.tv_usec
  29.243 +
  29.244 +        // Ensure the ID is unique
  29.245 +        if val <= self._last_id
  29.246 +            val = self._last_id + 1
  29.247 +        self._last_id = val
  29.248 +
  29.249 +        // Split value for printf
  29.250 +        hi = (uint) (val >> 32)
  29.251 +        lo = (uint) (val & 4294967295)
  29.252 +
  29.253 +        return hi.to_string("%.0X") + lo.to_string("%.8X")
  29.254 +
  29.255 +
  29.256 +    def is_open () : bool
  29.257 +        return self.state >= State.OPEN
  29.258 +        
  29.259 +        
  29.260 +    def is_authenticated () : bool 
  29.261 +        return self.state >= State.AUTHENTICATED
  29.262 +
  29.263 +
  29.264 +    def open (function : ResultFunction#) : bool raises Error
  29.265 +        // Bail if the connection is already open
  29.266 +        if is_open()
  29.267 +            /*
  29.268 +            set_error (error,
  29.269 +                       Lm.Error,
  29.270 +                       Lm.Error.CONNECTION_NOT_OPEN,
  29.271 +                       "Connection already open.")
  29.272 +            */
  29.273 +            return false
  29.274 +
  29.275 +        state = State.OPENING
  29.276 +
  29.277 +        // Store callback
  29.278 +        _open_func = (owned) function
  29.279 +
  29.280 +        // Attach message queue
  29.281 +        self.queue.attach(self.context)
  29.282 +
  29.283 +        // Connect using GIO
  29.284 +        client : SocketClient = new SocketClient()
  29.285 +        client.connect_to_service_async.begin(server, "xmpp-client", null,
  29.286 +                                              _open_cb)
  29.287 +        return true
  29.288 +
  29.289 +
  29.290 +    def _open_cb(obj : Object?, res : GLib.AsyncResult)
  29.291 +        var client = (SocketClient) obj
  29.292 +        try
  29.293 +            _stream = client.connect_async.end(res)
  29.294 +
  29.295 +            // Successfully connected
  29.296 +            _open_func(self, true)
  29.297 +        except e : GLib.Error
  29.298 +            // Unsuccessful
  29.299 +            _open_func(self, false)
  29.300 +
  29.301 +
  29.302 +    def open_and_block () : bool raises Error
  29.303 +        client : SocketClient = new SocketClient()
  29.304 +        try
  29.305 +            _stream = client.connect_to_service(server, "xmpp-client", null)
  29.306 +        except e : GLib.Error
  29.307 +            return false
  29.308 +
  29.309 +        state = State.OPENING
  29.310 +
  29.311 +        // Attach message queue
  29.312 +        self.queue.attach(self.context)
  29.313 +
  29.314 +        return true
  29.315 +
  29.316 +
  29.317 +
  29.318 +    /* TODO WIP
  29.319 +    def async open_async () : bool raises Error
  29.320 +        // Bail if the connetion is already open
  29.321 +        //if is_open()
  29.322 +        //    return false
  29.323 +
  29.324 +        client : SocketClient = new SocketClient()
  29.325 +        client.connect_to_service_async.begin(server, "xmpp-client", null)
  29.326 +    */
  29.327 +
  29.328 +
  29.329 +    def send (message : Message) : bool raises Error
  29.330 +        xml_str : string = message.node.to_string()
  29.331 +
  29.332 +        // TODO loudmouth early terminated strings at </stream:stream>
  29.333 +        // so this wouldn't be sent.  Why it did this we can only guess.
  29.334 +
  29.335 +        return self.send_raw(xml_str)
  29.336 +
  29.337 +
  29.338 +    def send_raw (str : string) : bool raises Error
  29.339 +        sent : int
  29.340 +        data : array of uint8
  29.341 +
  29.342 +        if self.state < State.OPENING
  29.343 +            //log (LM_LOG_DOMAIN,LM_LOG_LEVEL_NET, "Connection is not open.\n")
  29.344 +
  29.345 +            raise new Lm.Error.CONNECTION_NOT_OPEN(
  29.346 +                "Connection is not open, call lm_connection_open() first")
  29.347 +
  29.348 +        // TODO? connection_log_send (connection, str, len);
  29.349 +
  29.350 +        /* Check to see if there already is an output buffer, if so, add to the
  29.351 +           buffer and return */
  29.352 +
  29.353 +        // Get string length
  29.354 +        data = (array of uint8) str
  29.355 +        data.length = str.length
  29.356 +
  29.357 +        // HERE
  29.358 +        // Go do the GIO stuff now.
  29.359 +        sent = (int) _stream.output_stream.write(data)
  29.360 +
  29.361 +        if sent < 0
  29.362 +            raise new Lm.Error.CONNECTION_FAILED(
  29.363 +                "Server closed the connection")
  29.364 +
  29.365 +        return true
  29.366 +
  29.367 +
  29.368 +    def send_with_reply (message : Message,
  29.369 +                         handler : MessageHandler) : bool raises Error
  29.370 +        id : string? = message.node.get_attribute("id")
  29.371 +        if id is null
  29.372 +            id = self.generate_id()
  29.373 +            attributes : dict of string, string = new dict of string, string
  29.374 +            attributes["id"] = id
  29.375 +            message.node.set_attributes(attributes)
  29.376 +        self.id_handlers[id] = handler
  29.377 +        return self.send(message)
  29.378 +
  29.379 +
  29.380 +    def register_message_handler (handler : MessageHandler,
  29.381 +                                  type : Message.Type,
  29.382 +                                  priority : HandlerPriority)
  29.383 +        // Bail if unknown message type is passed
  29.384 +        if type >= self.stanza_handlers.length
  29.385 +            return
  29.386 +
  29.387 +        stanza_handlers[type].add(new MessageHandlerEntry(handler, priority))
  29.388 +        stanza_handlers[type].sort((GLib.CompareDataFunc)
  29.389 +                                   MessageHandlerEntry.compare)
  29.390 +
  29.391 +
  29.392 +    def unregister_message_handler (handler : MessageHandler,
  29.393 +                                    type : Message.Type)
  29.394 +        for entry in stanza_handlers[type]
  29.395 +            if entry.handler == handler
  29.396 +                stanza_handlers[type].remove(entry)
  29.397 +                break
  29.398 +
  29.399 +
  29.400 +    //////////////////////////////////////////////////////////////////////////
  29.401 +    // Properties
  29.402 +
  29.403 +    prop readonly context : MainContext?
  29.404 +        get
  29.405 +            return _context
  29.406 +
  29.407 +
  29.408 +    prop readonly full_jid : string
  29.409 +        get
  29.410 +            return self._effective_jid
  29.411 +
  29.412 +
  29.413 +    prop jid : string
  29.414 +        get
  29.415 +            return self._jid
  29.416 +        set
  29.417 +            if self.is_open()
  29.418 +                //TODO log (LOG_DOMAIN, LOG_LEVEL_VERBOSE, "Can't change JID while connected")
  29.419 +                return
  29.420 +            self._jid = value
  29.421 +
  29.422 +
  29.423 +    prop port : int
  29.424 +        get
  29.425 +            return self._port
  29.426 +        set
  29.427 +            if self.is_open()
  29.428 +                //TODO log (LOG_DOMAIN, LOG_LEVEL_VERBOSE, "Can't change port while connected")
  29.429 +                return
  29.430 +            self._port = value
  29.431 +
  29.432 +
  29.433 +    prop keep_alive_rate : uint
  29.434 +        get
  29.435 +            return _keep_alive_rate
  29.436 +        set
  29.437 +            // TODO update Ping feature
  29.438 +            _keep_alive_rate = value
  29.439 +
  29.440 +
  29.441 +    prop server : string?
  29.442 +        get
  29.443 +            // Allow for override
  29.444 +            if self._server is not null
  29.445 +                return self._server
  29.446 +
  29.447 +            // Standard - pull from supplied JID
  29.448 +            if self._jid is not null
  29.449 +                jids : array of string = self._jid.split_set("@/", 3)
  29.450 +                if jids[0] is not null
  29.451 +                    return jids[1]
  29.452 +            // Return null if all else fails
  29.453 +            return null
  29.454 +        set
  29.455 +            self._server = value
  29.456 +
  29.457 +
  29.458 +    prop proxy : Proxy?
  29.459 +        get
  29.460 +            return _proxy
  29.461 +
  29.462 +
  29.463 +    prop ssl : SSL?
  29.464 +        get
  29.465 +            return _ssl
  29.466 +        set
  29.467 +            self._ssl = value
  29.468 +
  29.469 +
  29.470 +    //////////////////////////////////////////////////////////////////////////
  29.471 +    // MessageHandlerEntry
  29.472 +    //
  29.473 +    // This class is for a stanza_handlers to record a handler with a specific
  29.474 +    // priority and allow sorting by priorities.
  29.475 +
  29.476 +    class MessageHandlerEntry : Object
  29.477 +        handler : MessageHandler
  29.478 +        priority : HandlerPriority
  29.479 +
  29.480 +
  29.481 +        construct (handler : MessageHandler, priority : HandlerPriority)
  29.482 +            self.handler = handler
  29.483 +            self.priority = priority
  29.484 +
  29.485 +
  29.486 +        def compare (other : MessageHandlerEntry, user_data : void*) : int
  29.487 +            return other.priority - self.priority
  29.488 +
    30.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.2 +++ b/src/Error.gs	Mon Dec 15 05:04:57 2014 +0000
    30.3 @@ -0,0 +1,26 @@
    30.4 +/*
    30.5 + *  LightMelody - Lightweight XMPP/Jingle Client Library
    30.6 + *  Copyright (C) 2012,2013,2014 Copyleft Games Group
    30.7 + *
    30.8 + *  This program is free software; you can redistribute it and/or modify
    30.9 + *  it under the terms of the GNU Affero General Public License as published
   30.10 + *  by the Free Software Foundation, either version 3 of the License, or
   30.11 + *  (at your option) any later version.
   30.12 + *
   30.13 + *  This program is distributed in the hope that it will be useful,
   30.14 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   30.15 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   30.16 + *  GNU Affero General Public License for more details.
   30.17 + *
   30.18 + *  You should have received a copy of the GNU Affero General Public License
   30.19 + *  along with this program; if not, see http://www.gnu.org/licenses
   30.20 + *
   30.21 + */
   30.22 +
   30.23 +[indent=4]
   30.24 +
   30.25 +exception Lm.Error
   30.26 +    CONNECTION_NOT_OPEN
   30.27 +    CONNECTION_OPEN
   30.28 +    AUTH_FAILED
   30.29 +    CONNECTION_FAILED
    31.1 --- a/src/Feature.Ping.gs	Wed Dec 25 20:33:47 2013 -0500
    31.2 +++ b/src/Feature.Ping.gs	Mon Dec 15 05:04:57 2014 +0000
    31.3 @@ -1,6 +1,6 @@
    31.4  /*
    31.5   *  LightMelody - Lightweight XMPP/Jingle Client Library
    31.6 - *  Copyright (C) 2012 Copyleft Games Group
    31.7 + *  Copyright (C) 2012,2013,2014 Copyleft Games Group
    31.8   *
    31.9   *  This program is free software; you can redistribute it and/or modify
   31.10   *  it under the terms of the GNU Affero General Public License as published
   31.11 @@ -37,9 +37,9 @@
   31.12          if (keep_alive_counter > 3)
   31.13              self.timed_out()
   31.14  
   31.15 -        server : string = connection._get_server();
   31.16 +        server : string = connection.server
   31.17  
   31.18 -        ping : Lm.Message = new Lm.Message.with_sub_type(server, Lm.MessageType.IQ, Lm.MessageSubType.GET);
   31.19 +        ping : Lm.Message = new Lm.Message.with_sub_type(server, Lm.Message.Type.IQ, Message.SubType.GET);
   31.20  
   31.21          ping_node : Lm.MessageNode = ping.node.add_child("ping", null);
   31.22  
   31.23 @@ -47,7 +47,9 @@
   31.24  
   31.25          keep_alive_handler : Lm.MessageHandler = new Lm.MessageHandler (self.reply)
   31.26  
   31.27 -        if (! connection.send_with_reply(ping, keep_alive_handler) )
   31.28 +        try
   31.29 +            connection.send_with_reply(ping, keep_alive_handler)
   31.30 +        except ex : Lm.Error
   31.31              print ("Error while sending ping!\n");
   31.32              // Should be Lm.verbose!
   31.33  
   31.34 @@ -67,7 +69,7 @@
   31.35              keep_alive_source = new TimeoutSource(self.rate * 1000)
   31.36              keep_alive_source.set_callback(self.send_keep_alive)
   31.37  
   31.38 -            keep_alive_source.attach (connection._get_context())
   31.39 +            keep_alive_source.attach (connection.context)
   31.40  
   31.41      def stop() : void
   31.42          if (keep_alive_source != null)
    32.1 --- a/src/Jingle.gs	Wed Dec 25 20:33:47 2013 -0500
    32.2 +++ b/src/Jingle.gs	Mon Dec 15 05:04:57 2014 +0000
    32.3 @@ -1,5 +1,5 @@
    32.4  /*
    32.5 - *  Copyright (C) 2012 Copyleft Games Group
    32.6 + *  Copyright (C) 2012,2013,2014 Copyleft Games Group
    32.7   *
    32.8   *  This program is free software; you can redistribute it and/or modify
    32.9   *  it under the terms of the GNU Affero General Public License as published
    33.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    33.2 +++ b/src/Message.gs	Mon Dec 15 05:04:57 2014 +0000
    33.3 @@ -0,0 +1,237 @@
    33.4 +/*
    33.5 + *  LightMelody - Lightweight XMPP/Jingle Client Library
    33.6 + *  Copyright (C) 2012,2013,2014 Copyleft Games Group
    33.7 + *
    33.8 + *  This program is free software; you can redistribute it and/or modify
    33.9 + *  it under the terms of the GNU Affero General Public License as published
   33.10 + *  by the Free Software Foundation, either version 3 of the License, or
   33.11 + *  (at your option) any later version.
   33.12 + *
   33.13 + *  This program is distributed in the hope that it will be useful,
   33.14 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   33.15 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   33.16 + *  GNU Affero General Public License for more details.
   33.17 + *
   33.18 + *  You should have received a copy of the GNU Affero General Public License
   33.19 + *  along with this program; if not, see http://www.gnu.org/licenses
   33.20 + *
   33.21 + */
   33.22 +
   33.23 +[indent=4]
   33.24 +
   33.25 +
   33.26 +class Lm.Message : Object
   33.27 +
   33.28 +    TypeNames : static dict of Message.Type, string?
   33.29 +    SubTypeNames : static dict of Message.SubType, string?
   33.30 +
   33.31 +    [CCode (cname = "node")]
   33.32 +    node_ : Lm.MessageNode
   33.33 +
   33.34 +    
   33.35 +    init static
   33.36 +        TypeNames[Message.Type.MESSAGE] = "message"
   33.37 +        TypeNames[Message.Type.PRESENCE] = "presence"
   33.38 +        TypeNames[Message.Type.IQ] = "iq"
   33.39 +        TypeNames[Message.Type.STREAM] = "stream:stream"
   33.40 +        TypeNames[Message.Type.STREAM_FEATURES] = "stream:features"
   33.41 +        TypeNames[Message.Type.STREAM_ERROR] = "stream:error"
   33.42 +        TypeNames[Message.Type.AUTH] = "auth"
   33.43 +        TypeNames[Message.Type.CHALLENGE] = "challenge"
   33.44 +        TypeNames[Message.Type.RESPONSE] = "response"
   33.45 +        TypeNames[Message.Type.SUCCESS] = "success"
   33.46 +        TypeNames[Message.Type.FAILURE] = "failure"
   33.47 +        TypeNames[Message.Type.PROCEED] = "proceed"
   33.48 +        TypeNames[Message.Type.STARTTLS] = "starttls"
   33.49 +        TypeNames[Message.Type.UNKNOWN] = null
   33.50 +        
   33.51 +        SubTypeNames[Message.SubType.NORMAL] = "normal"
   33.52 +        SubTypeNames[Message.SubType.CHAT] = "chat"
   33.53 +        SubTypeNames[Message.SubType.GROUPCHAT] = "groupchat"
   33.54 +        SubTypeNames[Message.SubType.HEADLINE] = "headline"
   33.55 +        SubTypeNames[Message.SubType.UNAVAILABLE] = "unavailable"
   33.56 +        SubTypeNames[Message.SubType.PROBE] = "probe"
   33.57 +        SubTypeNames[Message.SubType.SUBSCRIBE] = "subscribe"
   33.58 +        SubTypeNames[Message.SubType.UNSUBSCRIBE] = "unsubscribe"
   33.59 +        SubTypeNames[Message.SubType.SUBSCRIBED] = "subscribed"
   33.60 +        SubTypeNames[Message.SubType.UNSUBSCRIBED] = "unsubscribed"
   33.61 +        SubTypeNames[Message.SubType.GET] = "get"
   33.62 +        SubTypeNames[Message.SubType.SET] = "set"
   33.63 +        SubTypeNames[Message.SubType.RESULT] = "result"
   33.64 +        SubTypeNames[Message.SubType.ERROR] = "error"
   33.65 +
   33.66 +
   33.67 +    enum Type
   33.68 +        MESSAGE
   33.69 +        PRESENCE
   33.70 +        IQ
   33.71 +        STREAM
   33.72 +        STREAM_ERROR
   33.73 +        STREAM_FEATURES
   33.74 +        AUTH
   33.75 +        CHALLENGE
   33.76 +        RESPONSE
   33.77 +        SUCCESS
   33.78 +        FAILURE
   33.79 +        PROCEED
   33.80 +        STARTTLS
   33.81 +        UNKNOWN
   33.82 +
   33.83 +
   33.84 +    enum SubType
   33.85 +        NOT_SET = -10
   33.86 +        AVAILABLE = -1
   33.87 +        NORMAL = 0
   33.88 +        CHAT
   33.89 +        GROUPCHAT
   33.90 +        HEADLINE
   33.91 +        UNAVAILABLE
   33.92 +        PROBE
   33.93 +        SUBSCRIBE
   33.94 +        UNSUBSCRIBE
   33.95 +        SUBSCRIBED
   33.96 +        UNSUBSCRIBED
   33.97 +        GET
   33.98 +        SET
   33.99 +        RESULT
  33.100 +        ERROR
  33.101 +
  33.102 +
  33.103 +    construct (to : string?, msg_type : Message.Type?)
  33.104 +        id : string?
  33.105 +        _msg_type = msg_type
  33.106 +        
  33.107 +        case msg_type
  33.108 +            // A message without type should be handled like a message with
  33.109 +            // type=normal, but we won't set it to that since then the user
  33.110 +            // will not know if it's set or not.
  33.111 +
  33.112 +            when Message.Type.MESSAGE
  33.113 +                _sub_type = Message.SubType.NOT_SET
  33.114 +            when Message.Type.PRESENCE
  33.115 +                _sub_type = Message.SubType.AVAILABLE
  33.116 +            when Message.Type.IQ
  33.117 +                _sub_type = Message.SubType.GET
  33.118 +    
  33.119 +        self.node = new Lm.MessageNode(Message.type_to_string(msg_type))
  33.120 +
  33.121 +        utils : Lm.Utils = new Lm.Utils()
  33.122 +        if (msg_type != Message.Type.STREAM)
  33.123 +            id = utils.generate_id ()
  33.124 +            self.node.set_attribute ("id", id)
  33.125 +
  33.126 +        if (to != null)
  33.127 +            self.node.set_attribute ("to", to)
  33.128 +
  33.129 +        if (msg_type == Message.Type.IQ)
  33.130 +            self.node.set_attribute ("type", "get")
  33.131 +
  33.132 +
  33.133 +    construct with_sub_type (to : string?, msg_type : Message.Type?,
  33.134 +                             sub_type : Message.SubType?)
  33.135 +        type_str : string?
  33.136 +        self(to, msg_type)
  33.137 +
  33.138 +        type_str = sub_type_to_string(sub_type)
  33.139 +
  33.140 +        if (type_str != null) 
  33.141 +            attributes : dict of string, string = new dict of string, string
  33.142 +            attributes["type"] = type_str
  33.143 +            self.node.set_attributes (attributes)
  33.144 +            _sub_type = sub_type
  33.145 +
  33.146 +
  33.147 +    construct from_node (node : Lm.MessageNode)    
  33.148 +        msg_type : Message.Type
  33.149 +        sub_type : Message.SubType
  33.150 +        sub_type_str : string?
  33.151 +    
  33.152 +        msg_type = type_from_string(node.name)
  33.153 +
  33.154 +        if (msg_type == Message.Type.UNKNOWN)
  33.155 +            return
  33.156 +
  33.157 +        sub_type_str = node.get_attribute ("type")
  33.158 +        if (sub_type_str != null)
  33.159 +            sub_type = sub_type_from_string(sub_type_str)
  33.160 +        else
  33.161 +            sub_type = sub_type_when_unset(msg_type)
  33.162 +
  33.163 +        _msg_type = msg_type
  33.164 +        _sub_type = sub_type
  33.165 +
  33.166 +
  33.167 +    // Loudmouth 1.4 provides public member access to node
  33.168 +    prop node : Lm.MessageNode?
  33.169 +        get
  33.170 +            return node_
  33.171 +        set
  33.172 +            node_ = value
  33.173 +
  33.174 +
  33.175 +    prop readonly msg_type : Message.Type?
  33.176 +
  33.177 +
  33.178 +    prop readonly sub_type : Message.SubType?
  33.179 +
  33.180 +
  33.181 +    def static type_from_string (type_str : string?) : Message.Type
  33.182 +        if (type_str == null)
  33.183 +            return Message.Type.UNKNOWN
  33.184 +        start : int = (int) Message.Type.MESSAGE
  33.185 +        end : int = (int) Message.Type.UNKNOWN
  33.186 +        for var i = start to end
  33.187 +            if (type_str == Message.TypeNames[(Message.Type) i])
  33.188 +                return (Message.Type) i
  33.189 +        return Message.Type.UNKNOWN
  33.190 +
  33.191 +
  33.192 +    def static type_to_string (mtype : Message.Type?) : string?
  33.193 +        if (mtype < Message.Type.MESSAGE || mtype > Message.Type.STARTTLS)
  33.194 +            mtype = Message.Type.UNKNOWN
  33.195 +        return Message.TypeNames[mtype]
  33.196 +
  33.197 +
  33.198 +    def static sub_type_from_string (type_str : string?) : Message.SubType
  33.199 +        if (type_str is null)
  33.200 +            return Message.SubType.NOT_SET
  33.201 +
  33.202 +        start : int = (int) Message.SubType.NORMAL
  33.203 +        end : int = (int) Message.SubType.ERROR
  33.204 +        for var i = start to end
  33.205 +            if (type_str.ascii_casecmp(
  33.206 +                    Message.SubTypeNames[(Message.SubType) i]) == 0)
  33.207 +                return ((Message.SubType) i)
  33.208 +
  33.209 +        return Message.SubType.NOT_SET
  33.210 +
  33.211 +
  33.212 +    def static sub_type_to_string (stype : Message.SubType) : string?
  33.213 +        if (stype < Message.SubType.NORMAL || stype > Message.SubType.ERROR)
  33.214 +            return null
  33.215 +
  33.216 +        return Message.SubTypeNames[stype]
  33.217 +
  33.218 +
  33.219 +    def static sub_type_when_unset (mtype : Message.Type) : Message.SubType
  33.220 +        sub_type : Message.SubType
  33.221 +
  33.222 +        case mtype
  33.223 +            when Message.Type.MESSAGE
  33.224 +                /* A message without type should be handled like a message with
  33.225 +                 * type=normal, but we won't set it to that since then the user
  33.226 +                 * will not know if it's set or not.
  33.227 +                 */
  33.228 +                sub_type = Message.SubType.NOT_SET
  33.229 +
  33.230 +            when Message.Type.PRESENCE
  33.231 +                sub_type = Message.SubType.AVAILABLE
  33.232 +
  33.233 +            when Message.Type.IQ
  33.234 +                sub_type = Message.SubType.GET
  33.235 +
  33.236 +            default
  33.237 +                sub_type = Message.SubType.NORMAL
  33.238 +
  33.239 +        return sub_type
  33.240 +
    34.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.2 +++ b/src/MessageHandler.gs	Mon Dec 15 05:04:57 2014 +0000
    34.3 @@ -0,0 +1,57 @@
    34.4 +/*
    34.5 + *  LightMelody - Lightweight XMPP/Jingle Client Library
    34.6 + *  Copyright (C) 2012,2013,2014 Copyleft Games Group
    34.7 + *
    34.8 + *  This program is free software; you can redistribute it and/or modify
    34.9 + *  it under the terms of the GNU Affero General Public License as published
   34.10 + *  by the Free Software Foundation, either version 3 of the License, or
   34.11 + *  (at your option) any later version.
   34.12 + *
   34.13 + *  This program is distributed in the hope that it will be useful,
   34.14 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   34.15 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   34.16 + *  GNU Affero General Public License for more details.
   34.17 + *
   34.18 + *  You should have received a copy of the GNU Affero General Public License
   34.19 + *  along with this program; if not, see http://www.gnu.org/licenses
   34.20 + *
   34.21 + */
   34.22 +
   34.23 +[indent=4]
   34.24 +
   34.25 +namespace Lm
   34.26 +
   34.27 +    [CCode (cprefix = "LM_HANDLER_PRIORITY_", has_type_id = false)]
   34.28 +    enum HandlerPriority
   34.29 +        LAST
   34.30 +        NORMAL
   34.31 +        FIRST
   34.32 +
   34.33 +    [CCode (cprefix = "LM_HANDLER_RESULT_", has_type_id = false)]
   34.34 +    enum HandlerResult
   34.35 +        REMOVE_MESSAGE
   34.36 +        ALLOW_MORE_HANDLERS
   34.37 +
   34.38 +    delegate HandleMessageFunction (handler : MessageHandler,
   34.39 +                                    connection : Connection,
   34.40 +                                    message : Message) : HandlerResult
   34.41 +
   34.42 +
   34.43 +class Lm.MessageHandler
   34.44 +    function : Lm.HandleMessageFunction?
   34.45 +
   34.46 +    construct (function : HandleMessageFunction#)
   34.47 +        self.function = (owned) function
   34.48 +
   34.49 +    def invalidate ()
   34.50 +        self.function = null
   34.51 +
   34.52 +    def is_valid () : bool
   34.53 +        return self.function is not null
   34.54 +
   34.55 +    def handle_message (handler : MessageHandler, connection : Connection,
   34.56 +                        message : Message) : HandlerResult
   34.57 +        if self.function is not null
   34.58 +            return self.function(handler, connection, message)
   34.59 +        return HandlerResult.ALLOW_MORE_HANDLERS
   34.60 +
    35.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    35.2 +++ b/src/MessageNode.gs	Mon Dec 15 05:04:57 2014 +0000
    35.3 @@ -0,0 +1,180 @@
    35.4 +/*
    35.5 + *  LightMelody - Lightweight XMPP/Jingle Client Library
    35.6 + *  Copyright (C) 2012,2013,2014 Copyleft Games Group
    35.7 + *
    35.8 + *  This program is free software; you can redistribute it and/or modify
    35.9 + *  it under the terms of the GNU Affero General Public License as published
   35.10 + *  by the Free Software Foundation, either version 3 of the License, or
   35.11 + *  (at your option) any later version.
   35.12 + *
   35.13 + *  This program is distributed in the hope that it will be useful,
   35.14 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   35.15 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   35.16 + *  GNU Affero General Public License for more details.
   35.17 + *
   35.18 + *  You should have received a copy of the GNU Affero General Public License
   35.19 + *  along with this program; if not, see http://www.gnu.org/licenses
   35.20 + *
   35.21 + */
   35.22 +
   35.23 +[indent=4]
   35.24 +uses GLib
   35.25 +
   35.26 +class Lm.MessageNode
   35.27 +    _name : string?
   35.28 +    _value : string?
   35.29 +    _raw_mode : bool
   35.30 +    _attributes : dict of string,string
   35.31 +    _next : Lm.MessageNode?
   35.32 +    _prev : Lm.MessageNode?
   35.33 +    _parent : Lm.MessageNode?
   35.34 +    _children : Lm.MessageNode?
   35.35 +    
   35.36 +    construct (name : string?)
   35.37 +        self._name = name.dup ()
   35.38 +        self._value = null
   35.39 +        self._raw_mode = false
   35.40 +        self._next       = null
   35.41 +        self._prev       = null
   35.42 +        self._parent     = null
   35.43 +        self._children   = null
   35.44 +        self._attributes = new dict of string,string
   35.45 +        
   35.46 +    def static last_child (node : MessageNode) : MessageNode?
   35.47 +        l : MessageNode
   35.48 +
   35.49 +        if (node._children == null)
   35.50 +            return null
   35.51 +                
   35.52 +        l = node._children;
   35.53 +
   35.54 +        while (l._next != null)
   35.55 +            l = l._next
   35.56 +        return l
   35.57 +    
   35.58 +    def add_child_node (child : MessageNode?)
   35.59 +        prev : MessageNode?
   35.60 +
   35.61 +        prev = last_child (self)
   35.62 +
   35.63 +        if (prev != null)
   35.64 +            prev._next    = child
   35.65 +            child._prev   = prev
   35.66 +        else
   35.67 +            self._children = child
   35.68 +
   35.69 +        child._parent = self
   35.70 +        
   35.71 +    def add_child (name : string, value : string?) : Lm.MessageNode
   35.72 +        child : MessageNode = new MessageNode(name)
   35.73 +        
   35.74 +        child.value = value
   35.75 +        self.add_child_node (child)
   35.76 +        
   35.77 +        return child
   35.78 +    
   35.79 +    def get_child(child_name : string?) : MessageNode?
   35.80 +        l : MessageNode
   35.81 +        l = self._children
   35.82 +        while(l!=null)
   35.83 +            if l._name == child_name
   35.84 +                return l
   35.85 +             l = l._next
   35.86 +        return null
   35.87 +    
   35.88 +    def set_attribute(name : string?, value : string?)
   35.89 +        self._attributes[name] = value
   35.90 +        
   35.91 +    def get_attribute(name : string?) : string?
   35.92 +        if name in self._attributes.keys
   35.93 +            return self._attributes[name]
   35.94 +        else
   35.95 +            return null
   35.96 +
   35.97 +
   35.98 +    def to_string() : string?
   35.99 +        ret : string
  35.100 +        l : dict of string,string
  35.101 +        child : Lm.MessageNode
  35.102 +    
  35.103 +        if (self.name == null)
  35.104 +            return ""
  35.105 +        return null
  35.106 +    
  35.107 +       /* ret = g_string_new ("<");
  35.108 +        g_string_append (ret, node->name);
  35.109 +    
  35.110 +    for (l = node->attributes; l; l = l->next) {
  35.111 +        KeyValuePair *kvp = (KeyValuePair *) l->data;
  35.112 +
  35.113 +        if (node->raw_mode == FALSE) {
  35.114 +            gchar *escaped;
  35.115 +
  35.116 +            escaped = g_markup_escape_text (kvp->value, -1);
  35.117 +            g_string_append_printf (ret, " %s=\"%s\"", 
  35.118 +                                    kvp->key, escaped);
  35.119 +            g_free (escaped);
  35.120 +        } else {
  35.121 +            g_string_append_printf (ret, " %s=\"%s\"", 
  35.122 +                                    kvp->key, kvp->value);
  35.123 +        }
  35.124 +        
  35.125 +    }
  35.126 +    
  35.127 +    g_string_append_c (ret, '>');
  35.128 +    
  35.129 +    if (node->value) {
  35.130 +        gchar *tmp;
  35.131 +
  35.132 +        if (node->raw_mode == FALSE) {
  35.133 +            tmp = g_markup_escape_text (node->value, -1);
  35.134 +            g_string_append (ret,  tmp);
  35.135 +            g_free (tmp);
  35.136 +        } else {
  35.137 +            g_string_append (ret, node->value);
  35.138 +        }
  35.139 +    } 
  35.140 +
  35.141 +    for (child = node->children; child; child = child->next) {
  35.142 +        gchar *child_str = lm_message_node_to_string (child);
  35.143 +        g_string_append_c (ret, ' ');
  35.144 +        g_string_append (ret, child_str);
  35.145 +        g_free (child_str);
  35.146 +    }
  35.147 +
  35.148 +    g_string_append_printf (ret, "</%s>\n", node->name);
  35.149 +    
  35.150 +    return g_string_free (ret, FALSE);
  35.151 +}*/
  35.152 +
  35.153 +            
  35.154 +    def set_attributes(attributes : dict of string,string)
  35.155 +        for attribute_key in attributes.keys
  35.156 +            self.set_attribute(attribute_key, attributes[attribute_key])
  35.157 +        
  35.158 +    prop name : string?
  35.159 +        get
  35.160 +            return self._name
  35.161 +        set
  35.162 +            self._name = value
  35.163 +    prop value : string?
  35.164 +        get
  35.165 +            return self._value    
  35.166 +        set
  35.167 +            self._value = value
  35.168 +
  35.169 +    prop raw_mode : bool
  35.170 +        get
  35.171 +            return self._raw_mode
  35.172 +        set
  35.173 +            self._raw_mode = value
  35.174 +    prop parent : Lm.MessageNode?
  35.175 +        get
  35.176 +            return self._parent
  35.177 +        set
  35.178 +            self._parent = value            
  35.179 +
  35.180 +        
  35.181 +        
  35.182 +        
  35.183 +        
    36.1 --- a/src/MessageQueue.gs	Wed Dec 25 20:33:47 2013 -0500
    36.2 +++ b/src/MessageQueue.gs	Mon Dec 15 05:04:57 2014 +0000
    36.3 @@ -1,5 +1,5 @@
    36.4  /*
    36.5 - *  Copyright (C) 2012 Copyleft Games Group
    36.6 + *  Copyright (C) 2012,2013,2014 Copyleft Games Group
    36.7   *
    36.8   *  This program is free software; you can redistribute it and/or modify
    36.9   *  it under the terms of the GNU Affero General Public License as published
   36.10 @@ -21,7 +21,7 @@
   36.11  uses
   36.12      GLib
   36.13  
   36.14 -class Lm.MessageQueue
   36.15 +class Lm.MessageQueue : Object
   36.16      messages : Queue of Message
   36.17      context : MainContext?
   36.18      source : Source?
   36.19 @@ -31,7 +31,7 @@
   36.20          self.messages = new Queue of Message
   36.21          self.context = null
   36.22          self.source = null
   36.23 -        self.callback = #callback
   36.24 +        self.callback = (owned) callback
   36.25  
   36.26      delegate Callback (queue : MessageQueue)
   36.27  
   36.28 @@ -84,3 +84,4 @@
   36.29              if self.queue.callback is not null
   36.30                  self.queue.callback(self.queue)
   36.31              return true
   36.32 +
    37.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.2 +++ b/src/Parser.gs	Mon Dec 15 05:04:57 2014 +0000
    37.3 @@ -0,0 +1,114 @@
    37.4 +/*
    37.5 + *  LightMelody - Lightweight XMPP/Jingle Client Library
    37.6 + *  Copyright (C) 2012,2013,2014 Copyleft Games Group
    37.7 + *
    37.8 + *  This program is free software; you can redistribute it and/or modify
    37.9 + *  it under the terms of the GNU Affero General Public License as published
   37.10 + *  by the Free Software Foundation, either version 3 of the License, or
   37.11 + *  (at your option) any later version.
   37.12 + *
   37.13 + *  This program is distributed in the hope that it will be useful,
   37.14 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   37.15 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   37.16 + *  GNU Affero General Public License for more details.
   37.17 + *
   37.18 + *  You should have received a copy of the GNU Affero General Public License
   37.19 + *  along with this program; if not, see http://www.gnu.org/licenses
   37.20 + *
   37.21 + */
   37.22 +
   37.23 +[indent=4]
   37.24 +
   37.25 +namespace Lm
   37.26 +    delegate ParserMessageFunction (parser : Lm.Parser, message : Lm.Message)
   37.27 +    
   37.28 +class Lm.Parser
   37.29 +    _function : Lm.ParserMessageFunction?
   37.30 +    _cur_root : Lm.MessageNode
   37.31 +    _cur_node : Lm.MessageNode
   37.32 +        
   37.33 +    _m_parser : MarkupParser
   37.34 +    _context : MarkupParseContext
   37.35 +    
   37.36 +    construct (function : Lm.ParserMessageFunction?)
   37.37 +        self._context = new MarkupParseContext (self._m_parser, 0, self, null)
   37.38 +        self._m_parser.start_element = self._start_node_cb
   37.39 +        self._m_parser.end_element = self._end_node_cb
   37.40 +        self._m_parser.text = self._text_cb
   37.41 +        self._m_parser.error = self._error_cb
   37.42 +
   37.43 +        self._context = new MarkupParseContext (_m_parser, 0, self, null)
   37.44 +
   37.45 +        self._cur_root = null
   37.46 +        self._cur_node = null
   37.47 +    
   37.48 +    
   37.49 +    def _start_node_cb (context : MarkupParseContext,
   37.50 +                        node_name : string,
   37.51 +                        attribute_names : array of string,
   37.52 +                        attribute_values : array of string)
   37.53 +        if (self._cur_root == null)
   37.54 +            /* New toplevel element */
   37.55 +            self._cur_root = new MessageNode(node_name)
   37.56 +            self._cur_node = _cur_root;
   37.57 +        else
   37.58 +            parent_node : MessageNode
   37.59 +        
   37.60 +            parent_node = self._cur_node
   37.61 +            
   37.62 +            self._cur_node = new MessageNode(node_name)
   37.63 +            parent_node.add_child_node (self._cur_node)
   37.64 +
   37.65 +            var i = 0
   37.66 +
   37.67 +            attributes : dict of string, string = new dict of string, string
   37.68 +            for j in attribute_names
   37.69 +                attributes[attribute_names[i]] = attribute_values[i]
   37.70 +                i++
   37.71 +            
   37.72 +            self._cur_node.set_attributes (attributes)
   37.73 +    
   37.74 +            if ("stream:stream" == node_name) 
   37.75 +                self._end_node_cb (context,
   37.76 +                            "stream:stream")
   37.77 +
   37.78 +
   37.79 +    def _end_node_cb (context : MarkupParseContext, 
   37.80 +                            node_name : string?)
   37.81 +
   37.82 +    
   37.83 +        if (self._cur_node == null) 
   37.84 +            /* FIXME: LM-1 should look at this */
   37.85 +            return
   37.86 +        
   37.87 +        if (self._cur_node.name == node_name)
   37.88 +            if (node_name == "stream:stream")
   37.89 +                print ("Got an stream:stream end\n")
   37.90 +            return
   37.91 +
   37.92 +        if (self._cur_node == self._cur_root)
   37.93 +            m : Lm.Message
   37.94 +            
   37.95 +            m = new Message.from_node (self._cur_root)
   37.96 +
   37.97 +            if (m == null)
   37.98 +                return
   37.99 +
  37.100 +            if (self._function != null)
  37.101 +                self._function (self, m)
  37.102 +                
  37.103 +            self._cur_node = self._cur_root = null
  37.104 +        else
  37.105 +            tmp_node : Lm.MessageNode
  37.106 +            tmp_node = self._cur_node
  37.107 +            self._cur_node = self._cur_node.parent
  37.108 +            
  37.109 +    def _text_cb (context : MarkupParseContext?, text : string?, 
  37.110 +                  text_len : size_t)
  37.111 +    
  37.112 +        if (self._cur_node != null and text != "") 
  37.113 +            self._cur_node.value = text
  37.114 +            
  37.115 +    def _error_cb (context : MarkupParseContext, error : GLib.Error)
  37.116 +        return_if_fail(error != null)
  37.117 +
    38.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    38.2 +++ b/src/Proxy.gs	Mon Dec 15 05:04:57 2014 +0000
    38.3 @@ -0,0 +1,61 @@
    38.4 +/*
    38.5 + *  LightMelody - Lightweight XMPP/Jingle Client Library
    38.6 + *  Copyright (C) 2012,2013,2014 Copyleft Games Group
    38.7 + *
    38.8 + *  This program is free software; you can redistribute it and/or modify
    38.9 + *  it under the terms of the GNU Affero General Public License as published
   38.10 + *  by the Free Software Foundation, either version 3 of the License, or
   38.11 + *  (at your option) any later version.
   38.12 + *
   38.13 + *  This program is distributed in the hope that it will be useful,
   38.14 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   38.15 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   38.16 + *  GNU Affero General Public License for more details.
   38.17 + *
   38.18 + *  You should have received a copy of the GNU Affero General Public License
   38.19 + *  along with this program; if not, see http://www.gnu.org/licenses
   38.20 + *
   38.21 + */
   38.22 +
   38.23 +[indent=4]
   38.24 +
   38.25 +class Lm.Proxy
   38.26 +    enum Type
   38.27 +        NONE = 0
   38.28 +        HTTP
   38.29 +
   38.30 +
   38.31 +    construct (type : Type)
   38.32 +        self.set_type(type)
   38.33 +
   38.34 +
   38.35 +    construct with_server (type : Type, server : string, port : uint)
   38.36 +        self.set_type(type)
   38.37 +        self.server = server
   38.38 +        self.port = port
   38.39 +
   38.40 +
   38.41 +    def set_type (type : Type)
   38.42 +        case type
   38.43 +            when Type.HTTP
   38.44 +                self.protocol = "http"
   38.45 +                self.port = 8080
   38.46 +            default
   38.47 +                self.protocol = null
   38.48 +                self.port = 0
   38.49 +
   38.50 +
   38.51 +    prop password : unowned string
   38.52 +
   38.53 +
   38.54 +    prop protocol : unowned string?
   38.55 +
   38.56 +
   38.57 +    prop port : uint
   38.58 +
   38.59 +
   38.60 +    prop server : unowned string
   38.61 +
   38.62 +
   38.63 +    prop username : unowned string
   38.64 +
    39.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    39.2 +++ b/src/SSL.gs	Mon Dec 15 05:04:57 2014 +0000
    39.3 @@ -0,0 +1,70 @@
    39.4 +/*
    39.5 + *  LightMelody - Lightweight XMPP/Jingle Client Library
    39.6 + *  Copyright (C) 2012,2013,2014 Copyleft Games Group
    39.7 + *
    39.8 + *  This program is free software; you can redistribute it and/or modify
    39.9 + *  it under the terms of the GNU Affero General Public License as published
   39.10 + *  by the Free Software Foundation, either version 3 of the License, or
   39.11 + *  (at your option) any later version.
   39.12 + *
   39.13 + *  This program is distributed in the hope that it will be useful,
   39.14 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   39.15 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   39.16 + *  GNU Affero General Public License for more details.
   39.17 + *
   39.18 + *  You should have received a copy of the GNU Affero General Public License
   39.19 + *  along with this program; if not, see http://www.gnu.org/licenses
   39.20 + *
   39.21 + */
   39.22 +
   39.23 +[indent=4]
   39.24 +
   39.25 +
   39.26 +class Lm.SSL : Object
   39.27 +
   39.28 +    delegate Function (ssl : SSL, status : Status) : Response
   39.29 +
   39.30 +
   39.31 +    enum Response
   39.32 +        CONTINUE
   39.33 +        STOP
   39.34 +
   39.35 +
   39.36 +    enum Status
   39.37 +        NO_CERT_FOUND
   39.38 +        UNTRUSTED_CERT
   39.39 +        CERT_EXPIRED
   39.40 +        CERT_NOT_ACTIVATED
   39.41 +        CERT_HOSTNAME_MISMATCH
   39.42 +        CERT_FINGERPRINT_MISMATCH
   39.43 +        GENERIC_ERROR
   39.44 +
   39.45 +
   39.46 +    construct (expected_fingerprint : string, ssl_function : Function)
   39.47 +        _fingerprint = ""
   39.48 +        _require_starttls = true
   39.49 +
   39.50 +
   39.51 +    //////////////////////////////////////////////////////////////////////////
   39.52 +    // Methods
   39.53 +
   39.54 +    def get_use_starttls ( ) : bool
   39.55 +        return true
   39.56 +
   39.57 +
   39.58 +    def is_supported ( ) : bool
   39.59 +        return true
   39.60 +
   39.61 +
   39.62 +    def use_starttls (use_starttls : bool, require : bool)
   39.63 +        return
   39.64 +
   39.65 +
   39.66 +    //////////////////////////////////////////////////////////////////////////
   39.67 +    // Properties
   39.68 +
   39.69 +    prop readonly fingerprint : string
   39.70 +
   39.71 +
   39.72 +    prop readonly require_starttls : bool
   39.73 +
    40.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    40.2 +++ b/src/Sasl.gs	Mon Dec 15 05:04:57 2014 +0000
    40.3 @@ -0,0 +1,27 @@
    40.4 +/*
    40.5 + *  LightMelody - Lightweight XMPP/Jingle Client Library
    40.6 + *  Copyright (C) 2012,2013,2014 Copyleft Games Group
    40.7 + *
    40.8 + *  This program is free software; you can redistribute it and/or modify
    40.9 + *  it under the terms of the GNU Affero General Public License as published
   40.10 + *  by the Free Software Foundation, either version 3 of the License, or
   40.11 + *  (at your option) any later version.
   40.12 + *
   40.13 + *  This program is distributed in the hope that it will be useful,
   40.14 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   40.15 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   40.16 + *  GNU Affero General Public License for more details.
   40.17 + *
   40.18 + *  You should have received a copy of the GNU Affero General Public License
   40.19 + *  along with this program; if not, see http://www.gnu.org/licenses
   40.20 + *
   40.21 + */
   40.22 +
   40.23 +[indent=4]
   40.24 +
   40.25 +interface Lm.Sasl
   40.26 +
   40.27 +    def abstract auth () : string
   40.28 +    prop abstract readonly name : string
   40.29 +    prop abstract readonly priority : int
   40.30 +
    41.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    41.2 +++ b/src/SaslDigest.gs	Mon Dec 15 05:04:57 2014 +0000
    41.3 @@ -0,0 +1,47 @@
    41.4 +/*
    41.5 + *  LightMelody - Lightweight XMPP/Jingle Client Library
    41.6 + *  Copyright (C) 2012,2013,2014 Copyleft Games Group
    41.7 + *
    41.8 + *  This program is free software; you can redistribute it and/or modify
    41.9 + *  it under the terms of the GNU Affero General Public License as published
   41.10 + *  by the Free Software Foundation, either version 3 of the License, or
   41.11 + *  (at your option) any later version.
   41.12 + *
   41.13 + *  This program is distributed in the hope that it will be useful,
   41.14 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   41.15 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   41.16 + *  GNU Affero General Public License for more details.
   41.17 + *
   41.18 + *  You should have received a copy of the GNU Affero General Public License
   41.19 + *  along with this program; if not, see http://www.gnu.org/licenses
   41.20 + *
   41.21 + */
   41.22 +
   41.23 +[indent=4]
   41.24 +
   41.25 +class Lm.SaslDigest : Object implements Lm.Sasl
   41.26 +
   41.27 +    construct (username : string, password : string)
   41.28 +        self.username = username
   41.29 +        self.password = password
   41.30 +
   41.31 +
   41.32 +    def auth () : string
   41.33 +        return ""
   41.34 +
   41.35 +
   41.36 +    ///////////////////////////////////////////////////////////////////////
   41.37 +    // Properties
   41.38 +
   41.39 +    prop readonly name : string
   41.40 +        get
   41.41 +            return "DIGEST-MD5"
   41.42 +
   41.43 +    prop readonly priority : int
   41.44 +        get
   41.45 +            return 1
   41.46 +
   41.47 +    prop username : string
   41.48 +
   41.49 +    prop password : string
   41.50 +
    42.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    42.2 +++ b/src/SaslPlain.gs	Mon Dec 15 05:04:57 2014 +0000
    42.3 @@ -0,0 +1,47 @@
    42.4 +/*
    42.5 + *  LightMelody - Lightweight XMPP/Jingle Client Library
    42.6 + *  Copyright (C) 2012,2013,2014 Copyleft Games Group
    42.7 + *
    42.8 + *  This program is free software; you can redistribute it and/or modify
    42.9 + *  it under the terms of the GNU Affero General Public License as published
   42.10 + *  by the Free Software Foundation, either version 3 of the License, or
   42.11 + *  (at your option) any later version.
   42.12 + *
   42.13 + *  This program is distributed in the hope that it will be useful,
   42.14 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   42.15 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   42.16 + *  GNU Affero General Public License for more details.
   42.17 + *
   42.18 + *  You should have received a copy of the GNU Affero General Public License
   42.19 + *  along with this program; if not, see http://www.gnu.org/licenses
   42.20 + *
   42.21 + */
   42.22 +
   42.23 +[indent=4]
   42.24 +
   42.25 +class Lm.SaslPlain : Object implements Lm.Sasl
   42.26 +
   42.27 +    construct (username : string, password : string)
   42.28 +        self.username = username
   42.29 +        self.password = password
   42.30 +
   42.31 +
   42.32 +    def auth () : string
   42.33 +        return ""
   42.34 +
   42.35 +
   42.36 +    ///////////////////////////////////////////////////////////////////////
   42.37 +    // Properties
   42.38 +
   42.39 +    prop readonly name : string
   42.40 +        get
   42.41 +            return "PLAIN"
   42.42 +
   42.43 +    prop readonly priority : int
   42.44 +        get
   42.45 +            return 0
   42.46 +
   42.47 +    prop username : string
   42.48 +
   42.49 +    prop password : string
   42.50 +
    43.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    43.2 +++ b/src/Utils.gs	Mon Dec 15 05:04:57 2014 +0000
    43.3 @@ -0,0 +1,49 @@
    43.4 +/*
    43.5 + *  LightMelody - Lightweight XMPP/Jingle Client Library
    43.6 + *  Copyright (C) 2012,2013,2014 Copyleft Games Group
    43.7 + *
    43.8 + *  This program is free software; you can redistribute it and/or modify
    43.9 + *  it under the terms of the GNU Affero General Public License as published
   43.10 + *  by the Free Software Foundation, either version 3 of the License, or
   43.11 + *  (at your option) any later version.
   43.12 + *
   43.13 + *  This program is distributed in the hope that it will be useful,
   43.14 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   43.15 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   43.16 + *  GNU Affero General Public License for more details.
   43.17 + *
   43.18 + *  You should have received a copy of the GNU Affero General Public License
   43.19 + *  along with this program; if not, see http://www.gnu.org/licenses
   43.20 + *
   43.21 + */
   43.22 +
   43.23 +[indent=4]
   43.24 +
   43.25 +class Lm.Utils : Object
   43.26 +    
   43.27 +    _last_id : uint64
   43.28 +        
   43.29 +    init
   43.30 +        _last_id = 0
   43.31 +    
   43.32 +    def generate_id ( ) : string
   43.33 +        tv : TimeVal = TimeVal()
   43.34 +        val : uint64
   43.35 +        hi : uint
   43.36 +        lo : uint
   43.37 +
   43.38 +        val = (tv.tv_sec * 1000000) + tv.tv_usec
   43.39 +
   43.40 +        // Ensure the ID is unique
   43.41 +        if val <= self._last_id
   43.42 +            val = self._last_id + 1
   43.43 +        self._last_id = val
   43.44 +
   43.45 +        // Split value for printf
   43.46 +        hi = (uint) (val >> 32)
   43.47 +        lo = (uint) (val & 4294967295)
   43.48 +
   43.49 +        return hi.to_string("%.0X") + lo.to_string("%.8X")
   43.50 +
   43.51 +
   43.52 +        
    44.1 --- a/src/lightmelody.sym	Wed Dec 25 20:33:47 2013 -0500
    44.2 +++ b/src/lightmelody.sym	Mon Dec 15 05:04:57 2014 +0000
    44.3 @@ -1,4 +1,3 @@
    44.4 -lm_blocking_resolver_get_type
    44.5  lm_connection_authenticate
    44.6  lm_connection_authenticate_and_block
    44.7  lm_connection_cancel_open
    44.8 @@ -78,11 +77,6 @@
    44.9  lm_proxy_set_type
   44.10  lm_proxy_set_username
   44.11  lm_proxy_unref
   44.12 -lm_resolver_lookup
   44.13 -lm_resolver_new_for_host
   44.14 -lm_resolver_new_for_service
   44.15 -lm_resolver_results_get_next
   44.16 -lm_resolver_results_reset
   44.17  lm_ssl_get_fingerprint
   44.18  lm_ssl_get_require_starttls
   44.19  lm_ssl_get_use_starttls
    45.1 --- a/src/lm-asyncns-resolver.c	Wed Dec 25 20:33:47 2013 -0500
    45.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    45.3 @@ -1,361 +0,0 @@
    45.4 -/*
    45.5 - *  Copyright (C) 2012 Copyleft Games Group
    45.6 - *  Copyright (C) 2008 Imendio AB
    45.7 - *
    45.8 - *  This program is free software; you can redistribute it and/or modify
    45.9 - *  it under the terms of the GNU Affero General Public License as published
   45.10 - *  by the Free Software Foundation, either version 3 of the License, or
   45.11 - *  (at your option) any later version.
   45.12 - *
   45.13 - *  This program is distributed in the hope that it will be useful,
   45.14 - *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   45.15 - *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   45.16 - *  GNU Affero General Public License for more details.
   45.17 - *
   45.18 - *  You should have received a copy of the GNU Affero General Public License
   45.19 - *  along with this program; if not, see http://www.gnu.org/licenses
   45.20 - *
   45.21 - */
   45.22 -
   45.23 -#include <config.h>
   45.24 -
   45.25 -#include <string.h>
   45.26 -#ifdef HAVE_ASYNCNS
   45.27 -#include <asyncns.h>
   45.28 -#define freeaddrinfo(x) asyncns_freeaddrinfo(x)
   45.29 -
   45.30 -/* Needed on Mac OS X */
   45.31 -#if HAVE_ARPA_NAMESER_COMPAT_H
   45.32 -#include <arpa/nameser_compat.h>
   45.33 -#endif
   45.34 -
   45.35 -#include <arpa/nameser.h>
   45.36 -#include <resolv.h>
   45.37 -
   45.38 -#include "lm-debug.h"
   45.39 -#include <loudmouth/lm-error.h>
   45.40 -#include "lm-internals.h"
   45.41 -#include "lm-marshal.h"
   45.42 -#include "lm-misc.h"
   45.43 -#include "lm-asyncns-resolver.h"
   45.44 -
   45.45 -#define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), LM_TYPE_ASYNCNS_RESOLVER, LmAsyncnsResolverPriv))
   45.46 -
   45.47 -typedef struct LmAsyncnsResolverPriv LmAsyncnsResolverPriv;
   45.48 -struct LmAsyncnsResolverPriv {
   45.49 -    GSource     *watch_resolv;
   45.50 -    asyncns_query_t *resolv_query;
   45.51 -    asyncns_t   *asyncns_ctx;
   45.52 -    GIOChannel  *resolv_channel;
   45.53 -};
   45.54 -
   45.55 -static void     asyncns_resolver_finalize      (GObject     *object);
   45.56 -static void     asyncns_resolver_lookup        (LmResolver  *resolver);
   45.57 -static void     asyncns_resolver_cancel        (LmResolver  *resolver);
   45.58 -
   45.59 -G_DEFINE_TYPE (LmAsyncnsResolver, lm_asyncns_resolver, LM_TYPE_RESOLVER)
   45.60 -
   45.61 -static void
   45.62 -lm_asyncns_resolver_class_init (LmAsyncnsResolverClass *class)
   45.63 -{
   45.64 -    GObjectClass    *object_class = G_OBJECT_CLASS (class);
   45.65 -    LmResolverClass *resolver_class = LM_RESOLVER_CLASS (class);
   45.66 -
   45.67 -    object_class->finalize = asyncns_resolver_finalize;
   45.68 -
   45.69 -    resolver_class->lookup = asyncns_resolver_lookup;
   45.70 -    resolver_class->cancel = asyncns_resolver_cancel;
   45.71 -
   45.72 -    g_type_class_add_private (object_class, sizeof (LmAsyncnsResolverPriv));
   45.73 -}
   45.74 -
   45.75 -static void
   45.76 -lm_asyncns_resolver_init (LmAsyncnsResolver *asyncns_resolver)
   45.77 -{
   45.78 -    (void) GET_PRIV (asyncns_resolver);
   45.79 -}
   45.80 -
   45.81 -static void
   45.82 -asyncns_resolver_finalize (GObject *object)
   45.83 -{
   45.84 -    (void) GET_PRIV (object);
   45.85 -
   45.86 -    (G_OBJECT_CLASS (lm_asyncns_resolver_parent_class)->finalize) (object);
   45.87 -}
   45.88 -
   45.89 -static void
   45.90 -asyncns_resolver_cleanup (LmResolver *resolver)
   45.91 -{
   45.92 -    LmAsyncnsResolverPriv *priv = GET_PRIV (resolver);
   45.93 -
   45.94 -    if (priv->resolv_channel != NULL) {
   45.95 -        g_io_channel_unref (priv->resolv_channel);
   45.96 -        priv->resolv_channel = NULL;
   45.97 -    }
   45.98 -
   45.99 -    if (priv->watch_resolv) {
  45.100 -        g_source_destroy (priv->watch_resolv);
  45.101 -        priv->watch_resolv = NULL;
  45.102 -    }
  45.103 -
  45.104 -    if (priv->asyncns_ctx) {
  45.105 -        asyncns_free (priv->asyncns_ctx);
  45.106 -        priv->asyncns_ctx = NULL;
  45.107 -    }
  45.108 -
  45.109 -    priv->resolv_query = NULL;
  45.110 -}
  45.111 -
  45.112 -static void
  45.113 -asyncns_resolver_done (LmResolver *resolver)
  45.114 -{
  45.115 -    LmAsyncnsResolverPriv *priv = GET_PRIV (resolver);
  45.116 -    struct addrinfo       *ans;
  45.117 -    int                err;
  45.118 -
  45.119 -    err = asyncns_getaddrinfo_done (priv->asyncns_ctx, priv->resolv_query, &ans);
  45.120 -    priv->resolv_query = NULL;
  45.121 -    /* Signal that we are done */
  45.122 -
  45.123 -    g_object_ref (resolver);
  45.124 -
  45.125 -    if (err) {
  45.126 -        _lm_resolver_set_result (resolver,
  45.127 -                                 LM_RESOLVER_RESULT_FAILED,
  45.128 -                                 NULL);
  45.129 -    } else {
  45.130 -        _lm_resolver_set_result (resolver,
  45.131 -                                 LM_RESOLVER_RESULT_OK,
  45.132 -                                 ans);
  45.133 -    }
  45.134 -
  45.135 -    asyncns_resolver_cleanup (resolver);
  45.136 -
  45.137 -    g_object_unref (resolver);
  45.138 -}
  45.139 -
  45.140 -typedef gboolean  (* LmAsyncnsResolverCallback) (LmResolver *resolver);
  45.141 -
  45.142 -static gboolean
  45.143 -asyncns_resolver_io_cb (GSource      *source,
  45.144 -                        GIOCondition  condition,
  45.145 -                        LmResolver   *resolver)
  45.146 -{
  45.147 -    LmAsyncnsResolverPriv     *priv = GET_PRIV (resolver);
  45.148 -    LmAsyncnsResolverCallback  func;
  45.149 -
  45.150 -    asyncns_wait (priv->asyncns_ctx, FALSE);
  45.151 -
  45.152 -    if (!asyncns_isdone (priv->asyncns_ctx, priv->resolv_query)) {
  45.153 -        return TRUE;
  45.154 -    }
  45.155 -
  45.156 -    func = (LmAsyncnsResolverCallback) asyncns_getuserdata (priv->asyncns_ctx,
  45.157 -                                                            priv->resolv_query);
  45.158 -    return func (resolver);
  45.159 -}
  45.160 -
  45.161 -static gboolean
  45.162 -asyncns_resolver_prep (LmResolver *resolver, GError **error)
  45.163 -{
  45.164 -    LmAsyncnsResolverPriv *priv = GET_PRIV (resolver);
  45.165 -    GMainContext          *context;
  45.166 -
  45.167 -    if (priv->asyncns_ctx) {
  45.168 -        return TRUE;
  45.169 -    }
  45.170 -
  45.171 -    priv->asyncns_ctx = asyncns_new (1);
  45.172 -    if (priv->asyncns_ctx == NULL) {
  45.173 -        g_set_error (error,
  45.174 -                     LM_ERROR,
  45.175 -                     LM_ERROR_CONNECTION_FAILED,
  45.176 -                     "can't initialise libasyncns");
  45.177 -        return FALSE;
  45.178 -    }
  45.179 -
  45.180 -    priv->resolv_channel =
  45.181 -        g_io_channel_unix_new (asyncns_fd (priv->asyncns_ctx));
  45.182 -
  45.183 -    g_object_get (resolver, "context", &context, NULL);
  45.184 -
  45.185 -    priv->watch_resolv =
  45.186 -        lm_misc_add_io_watch (context,
  45.187 -                              priv->resolv_channel,
  45.188 -                              G_IO_IN,
  45.189 -                              (GIOFunc) asyncns_resolver_io_cb,
  45.190 -                              resolver);
  45.191 -
  45.192 -    return TRUE;
  45.193 -}
  45.194 -
  45.195 -static void
  45.196 -asyncns_resolver_lookup_host (LmResolver *resolver)
  45.197 -{
  45.198 -    LmAsyncnsResolverPriv *priv = GET_PRIV (resolver);
  45.199 -    gchar               *host;
  45.200 -    struct addrinfo      req;
  45.201 -
  45.202 -    g_object_get (resolver, "host", &host, NULL);
  45.203 -
  45.204 -    memset (&req, 0, sizeof(req));
  45.205 -    req.ai_family   = AF_UNSPEC;
  45.206 -    req.ai_socktype = SOCK_STREAM;
  45.207 -    req.ai_protocol = IPPROTO_TCP;
  45.208 -
  45.209 -    if (!asyncns_resolver_prep (resolver, NULL)) {
  45.210 -        g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_NET, "Signal error\n");
  45.211 -        return;
  45.212 -    }
  45.213 -
  45.214 -    priv->resolv_query =
  45.215 -        asyncns_getaddrinfo (priv->asyncns_ctx,
  45.216 -                             host,
  45.217 -                             NULL,
  45.218 -                             &req);
  45.219 -
  45.220 -    asyncns_setuserdata (priv->asyncns_ctx,
  45.221 -                         priv->resolv_query,
  45.222 -                         (gpointer) asyncns_resolver_done);
  45.223 -}
  45.224 -
  45.225 -static void
  45.226 -asyncns_resolver_srv_done (LmResolver *resolver)
  45.227 -{
  45.228 -    LmAsyncnsResolverPriv *priv = GET_PRIV (resolver);
  45.229 -    unsigned char         *srv_ans;
  45.230 -    int                    srv_len;
  45.231 -    gboolean               result = FALSE;
  45.232 -
  45.233 -    g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_NET, "srv_done callback\n");
  45.234 -
  45.235 -    srv_len = asyncns_res_done (priv->asyncns_ctx,
  45.236 -                                priv->resolv_query, &srv_ans);
  45.237 -
  45.238 -    priv->resolv_query = NULL;
  45.239 -
  45.240 -    if (srv_len <= 0) {
  45.241 -        /* FIXME: Report error */
  45.242 -        g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_NET,
  45.243 -               "Failed to read srv request results");
  45.244 -    } else {
  45.245 -        gchar *new_server;
  45.246 -        guint  new_port;
  45.247 -
  45.248 -        g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_NET,
  45.249 -               "trying to parse srv response\n");
  45.250 -
  45.251 -        result = _lm_resolver_parse_srv_response (srv_ans, srv_len,
  45.252 -                                                  &new_server,
  45.253 -                                                  &new_port);
  45.254 -        if (result == TRUE) {
  45.255 -            g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_NET,
  45.256 -                   "worked, new host/post is %s/%d\n",
  45.257 -                   new_server, new_port);
  45.258 -
  45.259 -            g_object_set (resolver,
  45.260 -                          "host", new_server,
  45.261 -                          "port", new_port,
  45.262 -                          NULL);
  45.263 -            g_free (new_server);
  45.264 -        }
  45.265 -
  45.266 -        /* TODO: Check whether srv_ans needs freeing */
  45.267 -    }
  45.268 -
  45.269 -    asyncns_resolver_cleanup (resolver);
  45.270 -
  45.271 -    g_object_ref (resolver);
  45.272 -    if (result == TRUE) {
  45.273 -        _lm_resolver_set_result (LM_RESOLVER (resolver), LM_RESOLVER_RESULT_OK, NULL);
  45.274 -    } else {
  45.275 -        _lm_resolver_set_result (LM_RESOLVER (resolver), LM_RESOLVER_RESULT_FAILED, NULL);
  45.276 -    }
  45.277 -    g_object_unref (resolver);
  45.278 -}
  45.279 -
  45.280 -static void
  45.281 -asyncns_resolver_lookup_service (LmResolver *resolver)
  45.282 -{
  45.283 -    LmAsyncnsResolverPriv *priv = GET_PRIV (resolver);
  45.284 -    gchar                 *domain;
  45.285 -    gchar                 *service;
  45.286 -    gchar                 *protocol;
  45.287 -    gchar                 *srv;
  45.288 -
  45.289 -    g_object_get (resolver,
  45.290 -                  "domain", &domain,
  45.291 -                  "service", &service,
  45.292 -                  "protocol", &protocol,
  45.293 -                  NULL);
  45.294 -
  45.295 -    srv = _lm_resolver_create_srv_string (domain, service, protocol);
  45.296 -
  45.297 -    g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_NET,
  45.298 -           "ASYNCNS: Looking up service: %s %s %s [%s]\n",
  45.299 -           domain, service, protocol, srv);
  45.300 -
  45.301 -    if (!asyncns_resolver_prep (resolver, /* Use GError? */ NULL)) {
  45.302 -        g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_NET,
  45.303 -               "Failed to initiate the asyncns library");
  45.304 -        /* FIXME: Signal error */
  45.305 -        return;
  45.306 -    }
  45.307 -
  45.308 -    priv->resolv_query =
  45.309 -        asyncns_res_query (priv->asyncns_ctx, srv, C_IN, T_SRV);
  45.310 -
  45.311 -    asyncns_setuserdata (priv->asyncns_ctx,
  45.312 -                         priv->resolv_query,
  45.313 -                         (gpointer) asyncns_resolver_srv_done);
  45.314 -
  45.315 -    g_free (srv);
  45.316 -    g_free (domain);
  45.317 -    g_free (service);
  45.318 -    g_free (protocol);
  45.319 -}
  45.320 -
  45.321 -static void
  45.322 -asyncns_resolver_lookup (LmResolver *resolver)
  45.323 -{
  45.324 -    gint type;
  45.325 -
  45.326 -    /* Start the DNS querying */
  45.327 -
  45.328 -    /* Decide if we are going to lookup a srv or host */
  45.329 -    g_object_get (resolver, "type", &type, NULL);
  45.330 -
  45.331 -    switch (type) {
  45.332 -    case LM_RESOLVER_HOST:
  45.333 -        asyncns_resolver_lookup_host (resolver);
  45.334 -        break;
  45.335 -    case LM_RESOLVER_SRV:
  45.336 -        asyncns_resolver_lookup_service (resolver);
  45.337 -        break;
  45.338 -    };
  45.339 -
  45.340 -    /* End of DNS querying */
  45.341 -}
  45.342 -
  45.343 -static void
  45.344 -asyncns_resolver_cancel (LmResolver *resolver)
  45.345 -{
  45.346 -    LmAsyncnsResolverPriv *priv;
  45.347 -
  45.348 -    g_return_if_fail (LM_IS_ASYNCNS_RESOLVER (resolver));
  45.349 -
  45.350 -    priv = GET_PRIV (resolver);
  45.351 -
  45.352 -    if (priv->asyncns_ctx) {
  45.353 -        if (priv->resolv_query) {
  45.354 -            asyncns_cancel (priv->asyncns_ctx, priv->resolv_query);
  45.355 -            priv->resolv_query = NULL;
  45.356 -        }
  45.357 -
  45.358 -        _lm_resolver_set_result (resolver,
  45.359 -                                 LM_RESOLVER_RESULT_CANCELLED,
  45.360 -                                 NULL);
  45.361 -    }
  45.362 -}
  45.363 -
  45.364 -#endif //HAVE_ASYNCNS
    46.1 --- a/src/lm-asyncns-resolver.h	Wed Dec 25 20:33:47 2013 -0500
    46.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    46.3 @@ -1,52 +0,0 @@
    46.4 -/*
    46.5 - *  Copyright (C) 2012 Copyleft Games Group
    46.6 - *  Copyright (C) 2008 Imendio AB
    46.7 - *
    46.8 - *  This program is free software; you can redistribute it and/or modify
    46.9 - *  it under the terms of the GNU Affero General Public License as published
   46.10 - *  by the Free Software Foundation, either version 3 of the License, or
   46.11 - *  (at your option) any later version.
   46.12 - *
   46.13 - *  This program is distributed in the hope that it will be useful,
   46.14 - *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   46.15 - *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   46.16 - *  GNU Affero General Public License for more details.
   46.17 - *
   46.18 - *  You should have received a copy of the GNU Affero General Public License
   46.19 - *  along with this program; if not, see http://www.gnu.org/licenses
   46.20 - *
   46.21 - */
   46.22 -
   46.23 -#ifndef __LM_ASYNCNS_RESOLVER_H__
   46.24 -#define __LM_ASYNCNS_RESOLVER_H__
   46.25 -
   46.26 -#include <glib-object.h>
   46.27 -
   46.28 -#include "lm-resolver.h"
   46.29 -
   46.30 -G_BEGIN_DECLS
   46.31 -
   46.32 -#define LM_TYPE_ASYNCNS_RESOLVER            (lm_asyncns_resolver_get_type ())
   46.33 -#define LM_ASYNCNS_RESOLVER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), LM_TYPE_ASYNCNS_RESOLVER, LmAsyncnsResolver))
   46.34 -#define LM_ASYNCNS_RESOLVER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), LM_TYPE_ASYNCNS_RESOLVER, LmAsyncnsResolverClass))
   46.35 -#define LM_IS_ASYNCNS_RESOLVER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LM_TYPE_ASYNCNS_RESOLVER))
   46.36 -#define LM_IS_ASYNCNS_RESOLVER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), LM_TYPE_ASYNCNS_RESOLVER))
   46.37 -#define LM_ASYNCNS_RESOLVER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), LM_TYPE_ASYNCNS_RESOLVER, LmAsyncnsResolverClass))
   46.38 -
   46.39 -typedef struct LmAsyncnsResolver      LmAsyncnsResolver;
   46.40 -typedef struct LmAsyncnsResolverClass LmAsyncnsResolverClass;
   46.41 -
   46.42 -struct LmAsyncnsResolver {
   46.43 -    LmResolver parent;
   46.44 -};
   46.45 -
   46.46 -struct LmAsyncnsResolverClass {
   46.47 -    LmResolverClass parent_class;
   46.48 -};
   46.49 -
   46.50 -GType   lm_asyncns_resolver_get_type  (void);
   46.51 -
   46.52 -G_END_DECLS
   46.53 -
   46.54 -#endif /* __LM_ASYNCNS_RESOLVER_H__ */
   46.55 -
    47.1 --- a/src/lm-blocking-resolver.c	Wed Dec 25 20:33:47 2013 -0500
    47.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    47.3 @@ -1,251 +0,0 @@
    47.4 -/*
    47.5 - *  Copyright (C) 2012 Copyleft Games Group
    47.6 - *  Copyright (C) 2008 Imendio AB
    47.7 - *
    47.8 - *  This program is free software; you can redistribute it and/or modify
    47.9 - *  it under the terms of the GNU Affero General Public License as published
   47.10 - *  by the Free Software Foundation, either version 3 of the License, or
   47.11 - *  (at your option) any later version.
   47.12 - *
   47.13 - *  This program is distributed in the hope that it will be useful,
   47.14 - *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   47.15 - *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   47.16 - *  GNU Affero General Public License for more details.
   47.17 - *
   47.18 - *  You should have received a copy of the GNU Affero General Public License
   47.19 - *  along with this program; if not, see http://www.gnu.org/licenses
   47.20 - *
   47.21 - */
   47.22 -
   47.23 -#include <config.h>
   47.24 -
   47.25 -#include <string.h>
   47.26 -#include <sys/types.h>
   47.27 -#include <netdb.h>
   47.28 -
   47.29 -/* Needed on Mac OS X */
   47.30 -#if HAVE_ARPA_NAMESER_COMPAT_H
   47.31 -#include <arpa/nameser_compat.h>
   47.32 -#endif
   47.33 -
   47.34 -#include <arpa/nameser.h>
   47.35 -#include <resolv.h>
   47.36 -
   47.37 -#include "android-resolv.h"
   47.38 -
   47.39 -#include "lm-marshal.h"
   47.40 -#include "lm-misc.h"
   47.41 -
   47.42 -#include "lm-blocking-resolver.h"
   47.43 -
   47.44 -#define SRV_LEN 8192
   47.45 -
   47.46 -#define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), LM_TYPE_BLOCKING_RESOLVER, LmBlockingResolverPriv))
   47.47 -
   47.48 -typedef struct LmBlockingResolverPriv LmBlockingResolverPriv;
   47.49 -struct LmBlockingResolverPriv {
   47.50 -    GSource *idle_source;
   47.51 -};
   47.52 -
   47.53 -static void     blocking_resolver_finalize    (GObject       *object);
   47.54 -static void     blocking_resolver_lookup      (LmResolver    *resolver);
   47.55 -static void     blocking_resolver_cancel      (LmResolver    *resolver);
   47.56 -
   47.57 -G_DEFINE_TYPE (LmBlockingResolver, lm_blocking_resolver, LM_TYPE_RESOLVER)
   47.58 -
   47.59 -static void
   47.60 -lm_blocking_resolver_class_init (LmBlockingResolverClass *class)
   47.61 -{
   47.62 -    GObjectClass    *object_class   = G_OBJECT_CLASS (class);
   47.63 -    LmResolverClass *resolver_class = LM_RESOLVER_CLASS (class);
   47.64 -
   47.65 -    object_class->finalize = blocking_resolver_finalize;
   47.66 -
   47.67 -    resolver_class->lookup = blocking_resolver_lookup;
   47.68 -    resolver_class->cancel = blocking_resolver_cancel;
   47.69 -
   47.70 -    g_type_class_add_private (object_class,
   47.71 -                              sizeof (LmBlockingResolverPriv));
   47.72 -}
   47.73 -
   47.74 -static void
   47.75 -lm_blocking_resolver_init (LmBlockingResolver *blocking_resolver)
   47.76 -{
   47.77 -    (void) GET_PRIV (blocking_resolver);
   47.78 -}
   47.79 -
   47.80 -static void
   47.81 -blocking_resolver_finalize (GObject *object)
   47.82 -{
   47.83 -    (void) GET_PRIV (object);
   47.84 -
   47.85 -    /* Ensure we don't have an idle around */
   47.86 -    blocking_resolver_cancel (LM_RESOLVER (object));
   47.87 -
   47.88 -    (G_OBJECT_CLASS (lm_blocking_resolver_parent_class)->finalize) (object);
   47.89 -}
   47.90 -
   47.91 -static gboolean
   47.92 -blocking_resolver_lookup_host (LmBlockingResolver *resolver)
   47.93 -{
   47.94 -    gchar           *host;
   47.95 -    struct addrinfo  req;
   47.96 -    struct addrinfo *ans;
   47.97 -    int              err;
   47.98 -    gboolean         retval = TRUE;
   47.99 -
  47.100 -    g_object_get (resolver, "host", &host, NULL);
  47.101 -
  47.102 -    /* Lookup */
  47.103 -
  47.104 -    memset (&req, 0, sizeof(req));
  47.105 -    req.ai_family   = PF_UNSPEC;
  47.106 -    req.ai_socktype = SOCK_STREAM;
  47.107 -    req.ai_protocol = IPPROTO_TCP;
  47.108 -
  47.109 -    err = getaddrinfo (host, NULL, &req, &ans);
  47.110 -
  47.111 -    if (err != 0) {
  47.112 -        _lm_resolver_set_result (LM_RESOLVER (resolver), LM_RESOLVER_RESULT_FAILED,
  47.113 -                                 NULL);
  47.114 -
  47.115 -        retval = FALSE;
  47.116 -    }
  47.117 -
  47.118 -    if (ans == NULL) {
  47.119 -        /* Couldn't find any results */
  47.120 -        g_object_ref (resolver);
  47.121 -        _lm_resolver_set_result (LM_RESOLVER (resolver), LM_RESOLVER_RESULT_FAILED,
  47.122 -                                 NULL);
  47.123 -
  47.124 -        g_object_unref (resolver);
  47.125 -        retval = FALSE;
  47.126 -    }
  47.127 -
  47.128 -    /* FIXME: How to set and iterate the results */
  47.129 -    /*priv->results    = ans;
  47.130 -      priv->cur_result = ans; */
  47.131 -
  47.132 -    if (retval) {
  47.133 -        g_object_ref (resolver);
  47.134 -
  47.135 -        _lm_resolver_set_result (LM_RESOLVER (resolver), LM_RESOLVER_RESULT_OK,
  47.136 -                                 ans);
  47.137 -
  47.138 -        g_object_unref (resolver);
  47.139 -    }
  47.140 -
  47.141 -    g_free (host);
  47.142 -
  47.143 -    return retval;
  47.144 -}
  47.145 -
  47.146 -static gboolean
  47.147 -blocking_resolver_lookup_service (LmBlockingResolver *resolver)
  47.148 -{
  47.149 -    gchar *domain;
  47.150 -    gchar *service;
  47.151 -    gchar *protocol;
  47.152 -    gchar *srv;
  47.153 -    gchar *new_server = NULL;
  47.154 -    guint  new_port = 0;
  47.155 -    gboolean  result;
  47.156 -    unsigned char    srv_ans[SRV_LEN];
  47.157 -    int              len;
  47.158 -    gboolean         retval = TRUE;
  47.159 -
  47.160 -    g_object_get (resolver,
  47.161 -                  "domain", &domain,
  47.162 -                  "service", &service,
  47.163 -                  "protocol", &protocol,
  47.164 -                  NULL);
  47.165 -
  47.166 -    srv = _lm_resolver_create_srv_string (domain, service, protocol);
  47.167 -
  47.168 -    res_init ();
  47.169 -
  47.170 -    len = res_query (srv, C_IN, T_SRV, srv_ans, SRV_LEN);
  47.171 -
  47.172 -    result = _lm_resolver_parse_srv_response (srv_ans, len,
  47.173 -                                              &new_server, &new_port);
  47.174 -    if (result == FALSE) {
  47.175 -        retval = FALSE;
  47.176 -    }
  47.177 -
  47.178 -    g_object_set (resolver,
  47.179 -                  "host", new_server,
  47.180 -                  "port", new_port,
  47.181 -                  NULL);
  47.182 -
  47.183 -    g_object_ref (resolver);
  47.184 -    _lm_resolver_set_result (LM_RESOLVER (resolver), LM_RESOLVER_RESULT_OK, NULL);
  47.185 -    g_object_unref (resolver);
  47.186 -
  47.187 -    /* Lookup the new server and the new port */
  47.188 -   /* blocking_resolver_lookup_host (resolver); */
  47.189 -
  47.190 -    g_free (new_server);
  47.191 -    g_free (srv);
  47.192 -    g_free (domain);
  47.193 -    g_free (service);
  47.194 -    g_free (protocol);
  47.195 -
  47.196 -    return retval;
  47.197 -}
  47.198 -
  47.199 -static gboolean
  47.200 -blocking_resolver_idle_lookup (LmBlockingResolver *resolver)
  47.201 -{
  47.202 -    LmBlockingResolverPriv *priv = GET_PRIV (resolver);
  47.203 -    gint                    type;
  47.204 -
  47.205 -    /* Start the DNS querying */
  47.206 -
  47.207 -    /* Decide if we are going to lookup a srv or host */
  47.208 -    g_object_get (resolver, "type", &type, NULL);
  47.209 -
  47.210 -    switch (type) {
  47.211 -    case LM_RESOLVER_HOST:
  47.212 -        blocking_resolver_lookup_host (resolver);
  47.213 -        break;
  47.214 -    case LM_RESOLVER_SRV:
  47.215 -        blocking_resolver_lookup_service (resolver);
  47.216 -        break;
  47.217 -    };
  47.218 -
  47.219 -    /* End of DNS querying */
  47.220 -    priv->idle_source = NULL;
  47.221 -    return FALSE;
  47.222 -}
  47.223 -
  47.224 -static void
  47.225 -blocking_resolver_lookup (LmResolver *resolver)
  47.226 -{
  47.227 -    LmBlockingResolverPriv *priv;
  47.228 -    GMainContext           *context;
  47.229 -
  47.230 -    g_return_if_fail (LM_IS_BLOCKING_RESOLVER (resolver));
  47.231 -
  47.232 -    priv = GET_PRIV (resolver);
  47.233 -
  47.234 -    g_object_get (resolver, "context", &context, NULL);
  47.235 -
  47.236 -    priv->idle_source = lm_misc_add_idle (context,
  47.237 -                                          (GSourceFunc) blocking_resolver_idle_lookup,
  47.238 -                                          resolver);
  47.239 -}
  47.240 -
  47.241 -static void
  47.242 -blocking_resolver_cancel (LmResolver *resolver)
  47.243 -{
  47.244 -    LmBlockingResolverPriv *priv;
  47.245 -
  47.246 -    g_return_if_fail (LM_IS_BLOCKING_RESOLVER (resolver));
  47.247 -
  47.248 -    priv = GET_PRIV (resolver);
  47.249 -
  47.250 -    if (priv->idle_source) {
  47.251 -        g_source_destroy (priv->idle_source);
  47.252 -        priv->idle_source = NULL;
  47.253 -    }
  47.254 -}
    48.1 --- a/src/lm-blocking-resolver.h	Wed Dec 25 20:33:47 2013 -0500
    48.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    48.3 @@ -1,52 +0,0 @@
    48.4 -/*
    48.5 - *  Copyright (C) 2012 Copyleft Games Group
    48.6 - *  Copyright (C) 2008 Imendio AB
    48.7 - *
    48.8 - *  This program is free software; you can redistribute it and/or modify
    48.9 - *  it under the terms of the GNU Affero General Public License as published
   48.10 - *  by the Free Software Foundation, either version 3 of the License, or
   48.11 - *  (at your option) any later version.
   48.12 - *
   48.13 - *  This program is distributed in the hope that it will be useful,
   48.14 - *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   48.15 - *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   48.16 - *  GNU Affero General Public License for more details.
   48.17 - *
   48.18 - *  You should have received a copy of the GNU Affero General Public License
   48.19 - *  along with this program; if not, see http://www.gnu.org/licenses
   48.20 - *
   48.21 - */
   48.22 -
   48.23 -#ifndef __LM_BLOCKING_RESOLVER_H__
   48.24 -#define __LM_BLOCKING_RESOLVER_H__
   48.25 -
   48.26 -#include <glib-object.h>
   48.27 -
   48.28 -#include "lm-resolver.h"
   48.29 -
   48.30 -G_BEGIN_DECLS
   48.31 -
   48.32 -#define LM_TYPE_BLOCKING_RESOLVER            (lm_blocking_resolver_get_type ())
   48.33 -#define LM_BLOCKING_RESOLVER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), LM_TYPE_BLOCKING_RESOLVER, LmBlockingResolver))
   48.34 -#define LM_BLOCKING_RESOLVER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), LM_TYPE_BLOCKING_RESOLVER, LmBlockingResolverClass))
   48.35 -#define LM_IS_BLOCKING_RESOLVER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LM_TYPE_BLOCKING_RESOLVER))
   48.36 -#define LM_IS_BLOCKING_RESOLVER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), LM_TYPE_BLOCKING_RESOLVER))
   48.37 -#define LM_BLOCKING_RESOLVER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), LM_TYPE_BLOCKING_RESOLVER, LmBlockingResolverClass))
   48.38 -
   48.39 -typedef struct LmBlockingResolver      LmBlockingResolver;
   48.40 -typedef struct LmBlockingResolverClass LmBlockingResolverClass;
   48.41 -
   48.42 -struct LmBlockingResolver {
   48.43 -    LmResolver parent;
   48.44 -};
   48.45 -
   48.46 -struct LmBlockingResolverClass {
   48.47 -    LmResolverClass parent_class;
   48.48 -};
   48.49 -
   48.50 -GType   lm_blocking_resolver_get_type  (void);
   48.51 -
   48.52 -G_END_DECLS
   48.53 -
   48.54 -#endif /* __LM_BLOCKING_RESOLVER_H__ */
   48.55 -
    49.1 --- a/src/lm-connection.c	Wed Dec 25 20:33:47 2013 -0500
    49.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    49.3 @@ -1,2224 +0,0 @@
    49.4 -/*
    49.5 - *  Copyright (C) 2012 Copyleft Games Group
    49.6 - *  Copyright (C) 2003-2008 Imendio AB
    49.7 - *  Copyright (C) 2007 Collabora Ltd.
    49.8 - *  Copyright (C) 2006 Nokia Corporation
    49.9 - *
   49.10 - *  This program is free software; you can redistribute it and/or modify
   49.11 - *  it under the terms of the GNU Affero General Public License as published
   49.12 - *  by the Free Software Foundation, either version 3 of the License, or
   49.13 - *  (at your option) any later version.
   49.14 - *
   49.15 - *  This program is distributed in the hope that it will be useful,
   49.16 - *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   49.17 - *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   49.18 - *  GNU Affero General Public License for more details.
   49.19 - *
   49.20 - *  You should have received a copy of the GNU Affero General Public License
   49.21 - *  along with this program; if not, see http://www.gnu.org/licenses
   49.22 - *
   49.23 - */
   49.24 -
   49.25 -/**
   49.26 - * SECTION:lm-connection
   49.27 - * @Title: LmConnection
   49.28 - * @Short_description: A client connection to the server
   49.29 - *
   49.30 - * An example of how to use LightMelody with the synchronous API.
   49.31 - * <informalexample><programlisting>
   49.32 - * int
   49.33 - * main (int argc, char **argv)
   49.34 - * {
   49.35 - *      LmConnection *connection;
   49.36 - *      GError       *error = NULL;
   49.37 - *      gint          i;
   49.38 - *      LmMessage    *m;
   49.39 - *
   49.40 - *      connection = lm_connection_new ("myserver");
   49.41 - *
   49.42 - *      if (!lm_connection_open_and_block (connection, &amp;error)) {
   49.43 - *          g_error ("Failed to open: &percnt;s\n", error->message);
   49.44 - *      }
   49.45 - *
   49.46 - *      if (!lm_connection_authenticate_and_block (connection,
   49.47 - *                                                 "username", "password",
   49.48 - *                                                 "resource",
   49.49 - *                                                 &amp;error)) {
   49.50 - *          g_error ("Failed to authenticate: &percnt;s\n", error->message);
   49.51 - *      }
   49.52 - *
   49.53 - *      m = lm_message_new ("recipient", LM_MESSAGE_TYPE_MESSAGE);
   49.54 - *      lm_message_node_add_child (m->node, "body", "message");
   49.55 - *
   49.56 - *      if (!lm_connection_send (connection, m, &amp;error)) {
   49.57 - *          g_error ("Send failed: &percnt;s\n", error->message);
   49.58 - *      }
   49.59 - *
   49.60 - *      lm_message_unref (m);
   49.61 - *
   49.62 - *      lm_connection_close (connection, NULL);
   49.63 - *      lm_connection_unref (connection);
   49.64 - *
   49.65 - *      return 0;
   49.66 - * }
   49.67 - * </programlisting></informalexample>
   49.68 - */
   49.69 -
   49.70 -#include <config.h>
   49.71 -
   49.72 -#include <string.h>
   49.73 -#include <sys/stat.h>
   49.74 -#include <sys/types.h>
   49.75 -#include <fcntl.h>
   49.76 -
   49.77 -/* Needed on Mac OS X */
   49.78 -#if HAVE_NETINET_IN_H
   49.79 -#include <netinet/in.h>
   49.80 -#endif
   49.81 -
   49.82 -#include <arpa/nameser.h>
   49.83 -#include <resolv.h>
   49.84 -
   49.85 -#include <glib-object.h>
   49.86 -
   49.87 -#include <lightmelody.h>
   49.88 -#include "lm-sock.h"
   49.89 -#include "lm-debug.h"
   49.90 -#include <loudmouth/lm-error.h>
   49.91 -#include "lm-internals.h"
   49.92 -#include "lm-misc.h"
   49.93 -#include "lm-ssl-internals.h"
   49.94 -#include "lm-parser.h"
   49.95 -#include <loudmouth/lm-connection.h>
   49.96 -#include <loudmouth/lm-utils.h>
   49.97 -#include "lm-old-socket.h"
   49.98 -#include "lm-sasl.h"
   49.99 -
  49.100 -typedef struct {
  49.101 -    LmHandlerPriority  priority;
  49.102 -    LmMessageHandler  *handler;
  49.103 -} HandlerData;
  49.104 -
  49.105 -struct _LmConnection {
  49.106 -    /* Parameters */
  49.107 -    GMainContext      *context;
  49.108 -
  49.109 -    /* TODO: Clean up this and make some parameter object for server, jid, effective jid etc */
  49.110 -    gchar             *server;
  49.111 -    gchar             *jid;
  49.112 -    gchar             *effective_jid;
  49.113 -    guint              port;
  49.114 -
  49.115 -    LmOldSocket       *socket;
  49.116 -    LmSSL             *ssl;
  49.117 -    LmProxy           *proxy;
  49.118 -    LmParser          *parser;
  49.119 -
  49.120 -    gchar             *stream_id;
  49.121 -
  49.122 -    GHashTable        *id_handlers;
  49.123 -    GSList            *handlers[LM_MESSAGE_TYPE_UNKNOWN];
  49.124 -
  49.125 -    /* XMPP1.0 stuff (SASL, resource binding, StartTLS) */
  49.126 -    gboolean           use_sasl;
  49.127 -    LmSASL            *sasl;
  49.128 -    gchar             *resource;
  49.129 -    LmMessageHandler  *features_cb;
  49.130 -    LmMessageHandler  *starttls_cb;
  49.131 -    gboolean           tls_started;
  49.132 -
  49.133 -    /* Communication */
  49.134 -    guint              open_id;
  49.135 -    LmCallback        *open_cb;
  49.136 -
  49.137 -    gboolean           cancel_open;
  49.138 -    LmCallback        *auth_cb;
  49.139 -
  49.140 -    LmCallback        *disconnect_cb;
  49.141 -
  49.142 -    LmMessageQueue    *queue;
  49.143 -
  49.144 -    LmConnectionState  state;
  49.145 -
  49.146 -    /* TODO: Move the rate to use the one in LmFeaturePing instead of keeping the two in sync */
  49.147 -    guint              keep_alive_rate;
  49.148 -    LmFeaturePing     *feature_ping;
  49.149 -
  49.150 -    gint               ref_count;
  49.151 -};
  49.152 -
  49.153 -typedef enum {
  49.154 -    AUTH_TYPE_PLAIN  = 1,
  49.155 -    AUTH_TYPE_DIGEST = 2,
  49.156 -    AUTH_TYPE_0K     = 4
  49.157 -} AuthType;
  49.158 -
  49.159 -#define XMPP_NS_BIND "urn:ietf:params:xml:ns:xmpp-bind"
  49.160 -#define XMPP_NS_SESSION "urn:ietf:params:xml:ns:xmpp-session"
  49.161 -#define XMPP_NS_STARTTLS "urn:ietf:params:xml:ns:xmpp-tls"
  49.162 -
  49.163 -static void     connection_free              (LmConnection        *connection);
  49.164 -static void     connection_handle_message    (LmConnection        *connection,
  49.165 -                                              LmMessage           *message);
  49.166 -static void     connection_new_message_cb    (LmParser            *parser,
  49.167 -                                              LmMessage           *message,
  49.168 -                                              LmConnection        *connection);
  49.169 -static gboolean connection_do_open           (LmConnection        *connection,
  49.170 -                                              GError             **error);
  49.171 -void            connection_do_close          (LmConnection        *connection);
  49.172 -static LmMessage *
  49.173 -connection_create_auth_req_msg               (LmAuthParameters    *auth_params);
  49.174 -
  49.175 -static LmMessage *
  49.176 -connection_create_auth_msg                   (LmConnection        *connection,
  49.177 -                                              LmAuthParameters    *auth_params,
  49.178 -                                              gint                 auth_type);
  49.179 -static LmHandlerResult
  49.180 -connection_auth_req_reply                    (LmMessageHandler    *handler,
  49.181 -                                              LmConnection        *connection,
  49.182 -                                              LmMessage           *m,
  49.183 -                                              gpointer             user_data);
  49.184 -static int      connection_check_auth_type   (LmMessage           *auth_req_rpl);
  49.185 -static LmHandlerResult
  49.186 -connection_auth_reply                        (LmMessageHandler    *handler,
  49.187 -                                              LmConnection        *connection,
  49.188 -                                              LmMessage           *m,
  49.189 -                                              gpointer             user_data);
  49.190 -static void     connection_stream_received   (LmConnection        *connection,
  49.191 -                                              LmMessage           *m);
  49.192 -static void     connection_stream_error      (LmConnection        *connection,
  49.193 -                                              LmMessage           *m);
  49.194 -static gint
  49.195 -connection_handler_compare_func              (HandlerData         *a,
  49.196 -                                              HandlerData         *b);
  49.197 -static void     connection_start_keep_alive  (LmConnection        *connection);
  49.198 -static void     connection_stop_keep_alive   (LmConnection        *connection);
  49.199 -static gboolean connection_send              (LmConnection        *connection,
  49.200 -                                              const gchar         *str,
  49.201 -                                              gint                 len,
  49.202 -                                              GError             **error);
  49.203 -static void     connection_message_queue_cb  (LmMessageQueue      *queue,
  49.204 -                                              LmConnection        *connection);
  49.205 -static void
  49.206 -connection_signal_disconnect                 (LmConnection        *connection,
  49.207 -                                              LmDisconnectReason   reason);
  49.208 -static void     connection_incoming_data     (LmOldSocket         *socket,
  49.209 -                                              const gchar         *buf,
  49.210 -                                              LmConnection        *connection);
  49.211 -static void     connection_socket_closed_cb  (LmOldSocket            *socket,
  49.212 -                                              LmDisconnectReason   reason,
  49.213 -                                              LmConnection        *connection);
  49.214 -static void
  49.215 -connection_socket_connect_cb                 (LmOldSocket         *socket,
  49.216 -                                              gboolean             result,
  49.217 -                                              LmConnection        *connection);
  49.218 -static gboolean
  49.219 -connection_get_server_from_jid               (const gchar         *jid,
  49.220 -                                              gchar              **server);
  49.221 -static void
  49.222 -connection_send_stream_header                (LmConnection        *connection);
  49.223 -static LmHandlerResult
  49.224 -connection_features_cb                       (LmMessageHandler    *handler,
  49.225 -                                              LmConnection        *connection,
  49.226 -                                              LmMessage           *message,
  49.227 -                                              gpointer             user_data);
  49.228 -static gboolean connection_old_auth          (LmConnection        *connection,
  49.229 -                                              LmAuthParameters    *auth_params,
  49.230 -                                              GError             **errror);
  49.231 -
  49.232 -static void
  49.233 -connection_free_handlers (LmConnection *connection)
  49.234 -{
  49.235 -    int i;
  49.236 -
  49.237 -    /* Unref handlers */
  49.238 -    for (i = 0; i < LM_MESSAGE_TYPE_UNKNOWN; ++i) {
  49.239 -        GSList *l;
  49.240 -
  49.241 -        for (l = connection->handlers[i]; l; l = l->next) {
  49.242 -            HandlerData *hd = (HandlerData *) l->data;
  49.243 -
  49.244 -            lm_message_handler_unref (hd->handler);
  49.245 -            g_free (hd);
  49.246 -        }
  49.247 -
  49.248 -        g_slist_free (connection->handlers[i]);
  49.249 -    }
  49.250 -}
  49.251 -
  49.252 -static void
  49.253 -connection_free (LmConnection *connection)
  49.254 -{
  49.255 -    /* This needs to be run before starting to free internal states.
  49.256 -     * It used to be run after the handlers where freed which lead to a crash
  49.257 -     * when the connection was freed prior to running lm_connection_close.
  49.258 -     */
  49.259 -    if (connection->state >= LM_CONNECTION_STATE_OPENING) {
  49.260 -        connection_do_close (connection);
  49.261 -    }
  49.262 -
  49.263 -    g_free (connection->server);
  49.264 -    g_free (connection->jid);
  49.265 -    g_free (connection->effective_jid);
  49.266 -    g_free (connection->stream_id);
  49.267 -    g_free (connection->resource);
  49.268 -
  49.269 -    if (connection->sasl) {
  49.270 -        lm_sasl_free (connection->sasl);
  49.271 -    }
  49.272 -
  49.273 -    if (connection->parser) {
  49.274 -        lm_parser_free (connection->parser);
  49.275 -    }
  49.276 -
  49.277 -    connection_free_handlers (connection);
  49.278 -
  49.279 -    g_hash_table_destroy (connection->id_handlers);
  49.280 -
  49.281 -    if (connection->open_cb) {
  49.282 -        _lm_utils_free_callback (connection->open_cb);
  49.283 -    }
  49.284 -
  49.285 -    if (connection->auth_cb) {
  49.286 -        _lm_utils_free_callback (connection->auth_cb);
  49.287 -    }
  49.288 -
  49.289 -    lm_connection_set_disconnect_function (connection, NULL, NULL, NULL);
  49.290 -
  49.291 -    if (connection->proxy) {
  49.292 -        lm_proxy_unref (connection->proxy);
  49.293 -    }
  49.294 -
  49.295 -    lm_message_queue_unref (connection->queue);
  49.296 -
  49.297 -    if (connection->context) {
  49.298 -        g_main_context_unref (connection->context);
  49.299 -    }
  49.300 -
  49.301 -    if (connection->socket) {
  49.302 -        lm_old_socket_unref (connection->socket);
  49.303 -    }
  49.304 -
  49.305 -    g_slice_free (LmConnection, connection);
  49.306 -}
  49.307 -
  49.308 -static LmHandlerResult
  49.309 -connection_run_message_handler (LmConnection *connection, LmMessage *m)
  49.310 -{
  49.311 -    LmMessageHandler *handler;
  49.312 -    const gchar      *id;
  49.313 -    LmHandlerResult   result = LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
  49.314 -
  49.315 -    id = lm_message_node_get_attribute (m->node, "id");
  49.316 -    if (!id) {
  49.317 -        return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
  49.318 -    }
  49.319 -
  49.320 -    handler = g_hash_table_lookup (connection->id_handlers, id);
  49.321 -    if (handler) {
  49.322 -        result = _lm_message_handler_handle_message (handler,
  49.323 -                                                     connection,
  49.324 -                                                     m);
  49.325 -        g_hash_table_remove (connection->id_handlers,
  49.326 -                             id);
  49.327 -    }
  49.328 -
  49.329 -    return result;
  49.330 -}
  49.331 -
  49.332 -static void
  49.333 -connection_handle_message (LmConnection *connection, LmMessage *m)
  49.334 -{
  49.335 -    GSList          *l;
  49.336 -    LmHandlerResult  result = LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
  49.337 -
  49.338 -    lm_connection_ref (connection);
  49.339 -
  49.340 -    if (lm_message_get_type (m) == LM_MESSAGE_TYPE_STREAM) {
  49.341 -        connection_stream_received (connection, m);
  49.342 -        goto out;
  49.343 -    }
  49.344 -
  49.345 -    if ((lm_message_get_type (m) != LM_MESSAGE_TYPE_IQ) ||
  49.346 -        (lm_message_get_sub_type (m) == LM_MESSAGE_SUB_TYPE_ERROR) ||
  49.347 -        (lm_message_get_sub_type (m) == LM_MESSAGE_SUB_TYPE_RESULT)) {
  49.348 -        result = connection_run_message_handler (connection, m);
  49.349 -        if (result == LM_HANDLER_RESULT_REMOVE_MESSAGE) {
  49.350 -            goto out;
  49.351 -        }
  49.352 -    }
  49.353 -
  49.354 -    for (l = connection->handlers[lm_message_get_type (m)];
  49.355 -         l && result == LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
  49.356 -         l = l->next) {
  49.357 -        HandlerData *hd = (HandlerData *) l->data;
  49.358 -
  49.359 -        result = _lm_message_handler_handle_message (hd->handler,
  49.360 -                                                     connection,
  49.361 -                                                     m);
  49.362 -    }
  49.363 -
  49.364 -    if (lm_message_get_type (m) == LM_MESSAGE_TYPE_STREAM_ERROR) {
  49.365 -        connection_stream_error (connection, m);
  49.366 -        goto out;
  49.367 -    }
  49.368 -
  49.369 - out:
  49.370 -    lm_connection_unref (connection);
  49.371 -
  49.372 -    return;
  49.373 -}
  49.374 -
  49.375 -static void
  49.376 -connection_new_message_cb (LmParser     *parser,
  49.377 -                           LmMessage    *m,
  49.378 -                           LmConnection *connection)
  49.379 -{
  49.380 -    const gchar *from;
  49.381 -
  49.382 -    lm_message_ref (m);
  49.383 -
  49.384 -    from = lm_message_node_get_attribute (m->node, "from");
  49.385 -    if (!from) {
  49.386 -        from = "unknown";
  49.387 -    }
  49.388 -
  49.389 -    lm_verbose ("New message with type=\"%s\" from: %s\n",
  49.390 -                _lm_message_type_to_string (lm_message_get_type (m)),
  49.391 -                from);
  49.392 -
  49.393 -    lm_message_queue_push_tail (connection->queue, m);
  49.394 -}
  49.395 -
  49.396 -static void
  49.397 -connection_ping_timed_out (LmFeaturePing *fp, LmConnection *connection)
  49.398 -{
  49.399 -    connection_do_close (connection);
  49.400 -    connection_signal_disconnect (connection,
  49.401 -                                  LM_DISCONNECT_REASON_PING_TIME_OUT);
  49.402 -}
  49.403 -
  49.404 -static void
  49.405 -connection_start_keep_alive (LmConnection *connection)
  49.406 -{
  49.407 -    if (connection->feature_ping) {
  49.408 -        connection_stop_keep_alive (connection);
  49.409 -    }
  49.410 -
  49.411 -    connection->feature_ping = g_object_new (LM_FEATURE_TYPE_PING,
  49.412 -                                             "connection", connection,
  49.413 -                                             "rate", connection->keep_alive_rate,
  49.414 -                                             NULL);
  49.415 -
  49.416 -    g_signal_connect (connection->feature_ping, "timed-out",
  49.417 -                      G_CALLBACK (connection_ping_timed_out),
  49.418 -                      connection);
  49.419 -
  49.420 -    lm_feature_ping_start (connection->feature_ping);
  49.421 -}
  49.422 -
  49.423 -static void
  49.424 -connection_stop_keep_alive (LmConnection *connection)
  49.425 -{
  49.426 -    if (connection->feature_ping) {
  49.427 -        lm_feature_ping_stop (connection->feature_ping);
  49.428 -        g_signal_handlers_disconnect_by_func (connection->feature_ping,
  49.429 -                                              G_CALLBACK (connection_ping_timed_out),
  49.430 -                                              connection);
  49.431 -        g_object_unref (connection->feature_ping);
  49.432 -    }
  49.433 -
  49.434 -    connection->feature_ping = NULL;
  49.435 -}
  49.436 -
  49.437 -static void
  49.438 -connection_log_send (LmConnection *connection,
  49.439 -                     const gchar  *str,
  49.440 -                     gint          len)
  49.441 -{
  49.442 -    g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_NET, "\nSEND:\n");
  49.443 -    g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_NET,
  49.444 -           "-----------------------------------\n");
  49.445 -    g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_NET, "%s\n", str);
  49.446 -    g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_NET,
  49.447 -           "-----------------------------------\n");
  49.448 -}
  49.449 -
  49.450 -static gboolean
  49.451 -connection_send (LmConnection  *connection,
  49.452 -                 const gchar   *str,
  49.453 -                 gint           len,
  49.454 -                 GError       **error)
  49.455 -{
  49.456 -    gint b_written;
  49.457 -
  49.458 -    if (connection->state < LM_CONNECTION_STATE_OPENING) {
  49.459 -        g_log (LM_LOG_DOMAIN,LM_LOG_LEVEL_NET,
  49.460 -               "Connection is not open.\n");
  49.461 -
  49.462 -        g_set_error (error,
  49.463 -                     LM_ERROR,
  49.464 -                     LM_ERROR_CONNECTION_NOT_OPEN,
  49.465 -                     "Connection is not open, call lm_connection_open() first");
  49.466 -        return FALSE;
  49.467 -    }
  49.468 -
  49.469 -    if (len == -1) {
  49.470 -        len = strlen (str);
  49.471 -    }
  49.472 -
  49.473 -    connection_log_send (connection, str, len);
  49.474 -
  49.475 -    /* Check to see if there already is an output buffer, if so, add to the
  49.476 -       buffer and return */
  49.477 -
  49.478 -    b_written = lm_old_socket_write (connection->socket, str, len);
  49.479 -
  49.480 -    if (b_written < 0) {
  49.481 -        g_set_error (error,
  49.482 -                     LM_ERROR,
  49.483 -                     LM_ERROR_CONNECTION_FAILED,
  49.484 -                     "Server closed the connection");
  49.485 -        return FALSE;
  49.486 -    }
  49.487 -
  49.488 -    return TRUE;
  49.489 -}
  49.490 -
  49.491 -static void
  49.492 -connection_message_queue_cb (LmMessageQueue *queue, LmConnection *connection)
  49.493 -{
  49.494 -    LmMessage *m;
  49.495 -
  49.496 -    m = lm_message_queue_pop_nth (connection->queue, 0);
  49.497 -
  49.498 -    if (m) {
  49.499 -        connection_handle_message (connection, m);
  49.500 -        lm_message_unref (m);
  49.501 -    }
  49.502 -}
  49.503 -
  49.504 -/* Returns directly */
  49.505 -/* Setups all data needed to start the connection attempts */
  49.506 -static gboolean
  49.507 -connection_do_open (LmConnection *connection, GError **error)
  49.508 -{
  49.509 -    gchar *domain = NULL;
  49.510 -
  49.511 -    if (lm_connection_is_open (connection)) {
  49.512 -        g_set_error (error,
  49.513 -                     LM_ERROR,
  49.514 -                     LM_ERROR_CONNECTION_NOT_OPEN,
  49.515 -                     "Connection is already open, call lm_connection_close() first");
  49.516 -        return FALSE;
  49.517 -    }
  49.518 -
  49.519 -    domain = _lm_connection_get_server (connection);
  49.520 -
  49.521 -    lm_verbose ("Connecting to: %s:%d\n", connection->server, connection->port);
  49.522 -
  49.523 -    connection->socket = lm_old_socket_create (connection->context,
  49.524 -                                               (IncomingDataFunc) connection_incoming_data,
  49.525 -                                               (SocketClosedFunc) connection_socket_closed_cb,
  49.526 -                                               (ConnectResultFunc) connection_socket_connect_cb,
  49.527 -                                               connection,
  49.528 -                                               connection,
  49.529 -                                               connection->server,
  49.530 -                                               domain,
  49.531 -                                               connection->port,
  49.532 -                                               connection->ssl,
  49.533 -                                               connection->proxy,
  49.534 -                                               error);
  49.535 -
  49.536 -    g_free (domain);
  49.537 -
  49.538 -    if (!connection->socket) {
  49.539 -        return FALSE;
  49.540 -    }
  49.541 -
  49.542 -    lm_message_queue_attach (connection->queue, connection->context);
  49.543 -
  49.544 -    connection->state = LM_CONNECTION_STATE_OPENING;
  49.545 -
  49.546 -    return TRUE;
  49.547 -}
  49.548 -
  49.549 -void
  49.550 -connection_do_close (LmConnection *connection)
  49.551 -{
  49.552 -    connection_stop_keep_alive (connection);
  49.553 -
  49.554 -    if (connection->socket) {
  49.555 -        lm_old_socket_close (connection->socket);
  49.556 -    }
  49.557 -
  49.558 -    lm_message_queue_detach (connection->queue);
  49.559 -
  49.560 -    if (!lm_connection_is_open (connection)) {
  49.561 -        /* lm_connection_is_open is FALSE for state OPENING as well */
  49.562 -        connection->state = LM_CONNECTION_STATE_CLOSED;
  49.563 -        return;
  49.564 -    }
  49.565 -
  49.566 -    connection->state = LM_CONNECTION_STATE_CLOSED;
  49.567 -
  49.568 -    if (connection->sasl) {
  49.569 -        lm_sasl_free (connection->sasl);
  49.570 -        connection->sasl = NULL;
  49.571 -    }
  49.572 -}
  49.573 -
  49.574 -static LmMessage *
  49.575 -connection_create_auth_req_msg (LmAuthParameters *auth_params)
  49.576 -{
  49.577 -    LmMessage     *m;
  49.578 -    LmMessageNode *q_node;
  49.579 -
  49.580 -    m = lm_message_new_with_sub_type (NULL, LM_MESSAGE_TYPE_IQ,
  49.581 -                                      LM_MESSAGE_SUB_TYPE_GET);
  49.582 -    q_node = lm_message_node_add_child (m->node, "query", NULL);
  49.583 -    lm_message_node_set_attributes (q_node,
  49.584 -                                    "xmlns", "jabber:iq:auth",
  49.585 -                                    NULL);
  49.586 -    lm_message_node_add_child (q_node, "username", lm_auth_parameters_get_username (auth_params));
  49.587 -
  49.588 -    return m;
  49.589 -}
  49.590 -
  49.591 -static LmMessage *
  49.592 -connection_create_auth_msg (LmConnection     *connection,
  49.593 -                            LmAuthParameters *auth_params,
  49.594 -                            gint              auth_type)
  49.595 -{
  49.596 -    LmMessage     *auth_msg;
  49.597 -    LmMessageNode *q_node;
  49.598 -
  49.599 -    auth_msg = lm_message_new_with_sub_type (NULL, LM_MESSAGE_TYPE_IQ,
  49.600 -                                             LM_MESSAGE_SUB_TYPE_SET);
  49.601 -
  49.602 -    q_node = lm_message_node_add_child (auth_msg->node, "query", NULL);
  49.603 -
  49.604 -    lm_message_node_set_attributes (q_node,
  49.605 -                                    "xmlns", "jabber:iq:auth",
  49.606 -                                    NULL);
  49.607 -
  49.608 -    lm_message_node_add_child (q_node, "username", lm_auth_parameters_get_username (auth_params));
  49.609 -
  49.610 -    if (auth_type & AUTH_TYPE_0K) {
  49.611 -        lm_verbose ("Using 0k auth (not implemented yet)\n");
  49.612 -        /* TODO: Should probably use this? */
  49.613 -    }
  49.614 -
  49.615 -    if (auth_type & AUTH_TYPE_DIGEST) {
  49.616 -        GChecksum*   checksum;
  49.617 -        gchar *str;
  49.618 -        gchar *digest;
  49.619 -
  49.620 -        lm_verbose ("Using digest\n");
  49.621 -        str = g_strconcat (connection->stream_id, lm_auth_parameters_get_password (auth_params), NULL);
  49.622 -        checksum = g_checksum_new(G_CHECKSUM_SHA1);
  49.623 -        g_checksum_update(checksum, (guchar *) str, strlen(str));
  49.624 -        digest = g_strdup(g_checksum_get_string(checksum));
  49.625 -        g_checksum_free(checksum);
  49.626 -        g_free (str);
  49.627 -        lm_message_node_add_child (q_node, "digest", digest);
  49.628 -        g_free (digest);
  49.629 -    }
  49.630 -    else if (auth_type & AUTH_TYPE_PLAIN) {
  49.631 -        lm_verbose ("Using plaintext auth\n");
  49.632 -        lm_message_node_add_child (q_node, "password", lm_auth_parameters_get_password (auth_params));
  49.633 -    } else {
  49.634 -        /* TODO: Report error somehow */
  49.635 -    }
  49.636 -
  49.637 -    lm_message_node_add_child (q_node, "resource", lm_auth_parameters_get_resource (auth_params));
  49.638 -
  49.639 -    return auth_msg;
  49.640 -}
  49.641 -
  49.642 -static LmHandlerResult
  49.643 -connection_auth_req_reply (LmMessageHandler *handler,
  49.644 -                           LmConnection     *connection,
  49.645 -                           LmMessage        *m,
  49.646 -                           gpointer          user_data)
  49.647 -{
  49.648 -    int               auth_type;
  49.649 -    LmMessage        *auth_msg;
  49.650 -    LmMessageHandler *auth_handler;
  49.651 -    LmAuthParameters *auth_params = (LmAuthParameters *) user_data;
  49.652 -
  49.653 -    auth_type = connection_check_auth_type (m);
  49.654 -
  49.655 -    auth_msg = connection_create_auth_msg (connection, auth_params, auth_type);
  49.656 -
  49.657 -    auth_handler = lm_message_handler_new (connection_auth_reply,
  49.658 -                                           NULL, NULL);
  49.659 -    lm_connection_send_with_reply (connection, auth_msg,
  49.660 -                                   auth_handler, NULL);
  49.661 -    lm_message_handler_unref (auth_handler);
  49.662 -    lm_message_unref (auth_msg);
  49.663 -
  49.664 -    return LM_HANDLER_RESULT_REMOVE_MESSAGE;
  49.665 -}
  49.666 -
  49.667 -static int
  49.668 -connection_check_auth_type (LmMessage *auth_req_rpl)
  49.669 -{
  49.670 -    LmMessageNode *q_node;
  49.671 -    gint           ret_val = 0;
  49.672 -
  49.673 -    q_node = lm_message_node_get_child (auth_req_rpl->node, "query");
  49.674 -
  49.675 -    if (!q_node) {
  49.676 -        return AUTH_TYPE_PLAIN;
  49.677 -    }
  49.678 -
  49.679 -    if (lm_message_node_get_child (q_node, "password")) {
  49.680 -        ret_val |= AUTH_TYPE_PLAIN;
  49.681 -    }
  49.682 -
  49.683 -    if (lm_message_node_get_child (q_node, "digest")) {
  49.684 -        ret_val |= AUTH_TYPE_DIGEST;
  49.685 -    }
  49.686 -
  49.687 -    if (lm_message_node_get_child (q_node, "sequence") &&
  49.688 -        lm_message_node_get_child (q_node, "token")) {
  49.689 -        ret_val |= AUTH_TYPE_0K;
  49.690 -    }
  49.691 -
  49.692 -    return ret_val;
  49.693 -}
  49.694 -
  49.695 -static LmHandlerResult
  49.696 -connection_auth_reply (LmMessageHandler *handler,
  49.697 -                       LmConnection     *connection,
  49.698 -                       LmMessage        *m,
  49.699 -                       gpointer          user_data)
  49.700 -{
  49.701 -    const gchar *type;
  49.702 -    gboolean     result = TRUE;
  49.703 -
  49.704 -    g_return_val_if_fail (connection != NULL,
  49.705 -                          LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS);
  49.706 -
  49.707 -
  49.708 -    type = lm_message_node_get_attribute (m->node, "type");
  49.709 -    if (strcmp (type, "result") == 0) {
  49.710 -        result = TRUE;
  49.711 -        connection->state = LM_CONNECTION_STATE_AUTHENTICATED;
  49.712 -    }
  49.713 -    else if (strcmp (type, "error") == 0) {
  49.714 -        result = FALSE;
  49.715 -        connection->state = LM_CONNECTION_STATE_OPEN;
  49.716 -    }
  49.717 -
  49.718 -    lm_verbose ("AUTH reply: %d\n", result);
  49.719 -
  49.720 -    if (connection->auth_cb) {
  49.721 -        LmCallback *cb = connection->auth_cb;
  49.722 -
  49.723 -        connection->auth_cb = NULL;
  49.724 -
  49.725 -        if (cb->func) {
  49.726 -            (* ((LmResultFunction) cb->func)) (connection,
  49.727 -                                               result,
  49.728 -                                               cb->user_data);
  49.729 -        }
  49.730 -
  49.731 -        _lm_utils_free_callback (cb);
  49.732 -    }
  49.733 -
  49.734 -    return LM_HANDLER_RESULT_REMOVE_MESSAGE;
  49.735 -}
  49.736 -
  49.737 -
  49.738 -static LmHandlerResult
  49.739 -_lm_connection_starttls_cb (LmMessageHandler *handler,
  49.740 -                            LmConnection     *connection,
  49.741 -                            LmMessage        *message,
  49.742 -                            gpointer          user_data)
  49.743 -{
  49.744 -    if (lm_old_socket_starttls (connection->socket)) {
  49.745 -        connection->tls_started = TRUE;
  49.746 -        connection_send_stream_header (connection);
  49.747 -    } else {
  49.748 -        connection_do_close (connection);
  49.749 -        connection_signal_disconnect (connection,
  49.750 -                                      LM_DISCONNECT_REASON_ERROR);
  49.751 -    }
  49.752 -
  49.753 -    return LM_HANDLER_RESULT_REMOVE_MESSAGE;
  49.754 -}
  49.755 -
  49.756 -static void
  49.757 -connection_possibly_register_starttls_handler (LmConnection *connection)
  49.758 -{
  49.759 -    /* if we'd like to use tls and we didn't already start
  49.760 -     * it, prepare for it now */
  49.761 -    if (connection->ssl &&
  49.762 -        lm_old_socket_get_use_starttls (connection->socket) &&
  49.763 -        !connection->starttls_cb) {
  49.764 -        connection->starttls_cb  =
  49.765 -            lm_message_handler_new (_lm_connection_starttls_cb,
  49.766 -                                    NULL, NULL);
  49.767 -        lm_connection_register_message_handler (connection,
  49.768 -                                                connection->starttls_cb,
  49.769 -                                                LM_MESSAGE_TYPE_PROCEED,
  49.770 -                                                LM_HANDLER_PRIORITY_FIRST);
  49.771 -    }
  49.772 -}
  49.773 -
  49.774 -static void
  49.775 -connection_stream_received (LmConnection *connection, LmMessage *m)
  49.776 -{
  49.777 -    gboolean result;
  49.778 -    const char *xmpp_version;
  49.779 -
  49.780 -    g_return_if_fail (connection != NULL);
  49.781 -    g_return_if_fail (m != NULL);
  49.782 -
  49.783 -    connection->stream_id = g_strdup (lm_message_node_get_attribute (m->node,
  49.784 -                                                                     "id"));
  49.785 -
  49.786 -    xmpp_version = lm_message_node_get_attribute (m->node, "version");
  49.787 -    if (xmpp_version && strcmp (xmpp_version, "1.0") == 0) {
  49.788 -        lm_verbose ("XMPP 1.0 stream received: %s\n",
  49.789 -                    connection->stream_id);
  49.790 -
  49.791 -        connection->use_sasl = TRUE;
  49.792 -
  49.793 -        /* stream is started multiple times, but we only want
  49.794 -         * one sasl mechanism */
  49.795 -        if (!connection->sasl) {
  49.796 -            connection->sasl = lm_sasl_new (connection);
  49.797 -        }
  49.798 -
  49.799 -        connection_possibly_register_starttls_handler (connection);
  49.800 -    } else {
  49.801 -        lm_verbose ("Old Jabber stream received: %s\n",
  49.802 -                    connection->stream_id);
  49.803 -    }
  49.804 -
  49.805 -    if (connection->state < LM_CONNECTION_STATE_OPEN) {
  49.806 -        connection->state = LM_CONNECTION_STATE_OPEN;
  49.807 -    }
  49.808 -
  49.809 -    /* Check to see if the stream is correctly set up */
  49.810 -    result = TRUE;
  49.811 -
  49.812 -    connection_start_keep_alive (connection);
  49.813 -
  49.814 -    if (connection->open_cb) {
  49.815 -        LmCallback *cb = connection->open_cb;
  49.816 -
  49.817 -        connection->open_cb = NULL;
  49.818 -
  49.819 -        if (cb->func) {
  49.820 -            (* ((LmResultFunction) cb->func)) (connection, result,
  49.821 -                                               cb->user_data);
  49.822 -        }
  49.823 -        _lm_utils_free_callback (cb);
  49.824 -    }
  49.825 -}
  49.826 -
  49.827 -static void
  49.828 -connection_stream_error (LmConnection *connection, LmMessage *m)
  49.829 -{
  49.830 -    LmMessageNode      *node;
  49.831 -    LmMessageNode      *reason_node;
  49.832 -    LmDisconnectReason  reason;
  49.833 -
  49.834 -    g_return_if_fail (connection != NULL);
  49.835 -    g_return_if_fail (m != NULL);
  49.836 -
  49.837 -    node = m->node;
  49.838 -
  49.839 -    /* Resource conflict */
  49.840 -    reason_node = lm_message_node_get_child (node, "conflict");
  49.841 -    if (reason_node) {
  49.842 -        lm_verbose ("Stream error: Conflict (resource connected elsewhere)\n");
  49.843 -        reason = LM_DISCONNECT_REASON_RESOURCE_CONFLICT;
  49.844 -        return;
  49.845 -    }
  49.846 -
  49.847 -    /* XML is crack */
  49.848 -    reason_node = lm_message_node_get_child (node, "xml-not-well-formed");
  49.849 -    if (reason_node) {
  49.850 -        lm_verbose ("Stream error: XML not well formed\n");
  49.851 -        reason = LM_DISCONNECT_REASON_INVALID_XML;
  49.852 -        return;
  49.853 -    }
  49.854 -
  49.855 -    lm_verbose ("Stream error: Unrecognised error\n");
  49.856 -    reason = LM_DISCONNECT_REASON_ERROR;
  49.857 -    connection->stream_id = g_strdup (lm_message_node_get_attribute (m->node,
  49.858 -                                                                     "id"));
  49.859 -    connection_do_close (connection);
  49.860 -    connection_signal_disconnect (connection, reason);
  49.861 -}
  49.862 -
  49.863 -static gint
  49.864 -connection_handler_compare_func (HandlerData *a, HandlerData *b)
  49.865 -{
  49.866 -    return b->priority - a->priority;
  49.867 -}
  49.868 -
  49.869 -static void
  49.870 -connection_signal_disconnect (LmConnection       *connection,
  49.871 -                              LmDisconnectReason  reason)
  49.872 -{
  49.873 -    if (connection->disconnect_cb && connection->disconnect_cb->func) {
  49.874 -        LmCallback *cb = connection->disconnect_cb;
  49.875 -
  49.876 -        lm_connection_ref (connection);
  49.877 -        (* ((LmDisconnectFunction) cb->func)) (connection,
  49.878 -                                               reason,
  49.879 -                                               cb->user_data);
  49.880 -        lm_connection_unref (connection);
  49.881 -    }
  49.882 -}
  49.883 -
  49.884 -static void
  49.885 -connection_incoming_data (LmOldSocket  *socket,
  49.886 -                          const gchar  *buf,
  49.887 -                          LmConnection *connection)
  49.888 -{
  49.889 -    lm_parser_parse (connection->parser, buf);
  49.890 -}
  49.891 -
  49.892 -static void
  49.893 -connection_socket_closed_cb (LmOldSocket        *socket,
  49.894 -                             LmDisconnectReason reason,
  49.895 -                             LmConnection       *connection)
  49.896 -{
  49.897 -    connection_do_close (connection);
  49.898 -    connection_signal_disconnect (connection, reason);
  49.899 -}
  49.900 -
  49.901 -static void
  49.902 -connection_socket_connect_cb (LmOldSocket  *socket,
  49.903 -                              gboolean      result,
  49.904 -                              LmConnection *connection)
  49.905 -{
  49.906 -    if (result == FALSE) {
  49.907 -        connection_do_close (connection);
  49.908 -
  49.909 -        if (connection->open_cb) {
  49.910 -            LmCallback *cb = connection->open_cb;
  49.911 -
  49.912 -            connection->open_cb = NULL;
  49.913 -
  49.914 -            (* ((LmResultFunction) cb->func)) (connection, FALSE,
  49.915 -                                               cb->user_data);
  49.916 -            _lm_utils_free_callback (cb);
  49.917 -        }
  49.918 -
  49.919 -        return;
  49.920 -    }
  49.921 -
  49.922 -    /* FIXME: Set up according to XMPP 1.0 specification */
  49.923 -    /*        StartTLS and the like */
  49.924 -    if (!connection_send (connection,
  49.925 -                          "<?xml version='1.0' encoding='UTF-8'?>", -1,
  49.926 -                          NULL)) {
  49.927 -        lm_verbose ("Failed to send xml version and encoding\n");
  49.928 -        connection_do_close (connection);
  49.929 -
  49.930 -        return;
  49.931 -    }
  49.932 -
  49.933 -    connection_send_stream_header (connection);
  49.934 -}
  49.935 -
  49.936 -static gboolean
  49.937 -connection_get_server_from_jid (const gchar *jid, gchar **server)
  49.938 -{
  49.939 -    gchar *ch;
  49.940 -    gchar *ch_end;
  49.941 -
  49.942 -    if (jid != NULL && (ch = strchr (jid, '@')) != NULL) {
  49.943 -        ch_end = strchr(ch + 1, '/');
  49.944 -        if (ch_end != NULL) {
  49.945 -            *server = g_strndup (ch + 1, ch_end - ch - 1);
  49.946 -        } else {
  49.947 -            *server = g_strdup (ch + 1);
  49.948 -        }
  49.949 -
  49.950 -        return TRUE;
  49.951 -    }
  49.952 -
  49.953 -    return FALSE;
  49.954 -}
  49.955 -
  49.956 -static void
  49.957 -connection_send_stream_header (LmConnection *connection)
  49.958 -{
  49.959 -    LmMessage *m;
  49.960 -    gchar     *server_from_jid;
  49.961 -
  49.962 -    lm_verbose ("Sending stream header\n");
  49.963 -
  49.964 -    server_from_jid = _lm_connection_get_server (connection);
  49.965 -
  49.966 -    m = lm_message_new (server_from_jid, LM_MESSAGE_TYPE_STREAM);
  49.967 -    lm_message_node_set_attributes (m->node,
  49.968 -                                    "xmlns:stream",
  49.969 -                                    "http://etherx.jabber.org/streams",
  49.970 -                                    "xmlns", "jabber:client",
  49.971 -                                    "version", "1.0",
  49.972 -                                    NULL);
  49.973 -
  49.974 -    g_free (server_from_jid);
  49.975 -
  49.976 -    if (!lm_connection_send (connection, m, NULL)) {
  49.977 -        lm_verbose ("Failed to send stream information\n");
  49.978 -        connection_do_close (connection);
  49.979 -    }
  49.980 -
  49.981 -    lm_message_unref (m);
  49.982 -}
  49.983 -
  49.984 -GMainContext *
  49.985 -_lm_connection_get_context (LmConnection *conn)
  49.986 -{
  49.987 -    g_return_val_if_fail (conn != NULL, NULL);
  49.988 -
  49.989 -    return conn->context;
  49.990 -}
  49.991 -
  49.992 -gchar *
  49.993 -_lm_connection_get_server (LmConnection *conn)
  49.994 -{
  49.995 -    gchar *server;
  49.996 -
  49.997 -    g_return_val_if_fail (conn != NULL, NULL);
  49.998 -
  49.999 -    if (!connection_get_server_from_jid (conn->jid, &server)) {
 49.1000 -        server = g_strdup (conn->server);
 49.1001 -    }
 49.1002 -
 49.1003 -    return server;
 49.1004 -}
 49.1005 -
 49.1006 -static void
 49.1007 -connection_call_auth_cb (LmConnection *connection, gboolean success)
 49.1008 -{
 49.1009 -    if (success) {
 49.1010 -        connection->state = LM_CONNECTION_STATE_AUTHENTICATED;
 49.1011 -    } else {
 49.1012 -        connection->state = LM_CONNECTION_STATE_OPEN;
 49.1013 -    }
 49.1014 -
 49.1015 -    if (connection->auth_cb) {
 49.1016 -        LmCallback *cb = connection->auth_cb;
 49.1017 -
 49.1018 -        connection->auth_cb = NULL;
 49.1019 -
 49.1020 -        if (cb->func) {
 49.1021 -            (* ((LmResultFunction) cb->func)) (connection,
 49.1022 -                                               success,
 49.1023 -                                               cb->user_data);
 49.1024 -        }
 49.1025 -
 49.1026 -        _lm_utils_free_callback (cb);
 49.1027 -    }
 49.1028 -}
 49.1029 -
 49.1030 -static LmHandlerResult
 49.1031 -connection_bind_reply (LmMessageHandler *handler,
 49.1032 -                       LmConnection     *connection,
 49.1033 -                       LmMessage        *message,
 49.1034 -                       gpointer          user_data)
 49.1035 -{
 49.1036 -    LmMessage        *m;
 49.1037 -    LmMessageNode    *session_node;
 49.1038 -    LmMessageNode    *jid_node;
 49.1039 -    int               result;
 49.1040 -    LmMessageSubType  type;
 49.1041 -
 49.1042 -    type = lm_message_get_sub_type (message);
 49.1043 -    if (type == LM_MESSAGE_SUB_TYPE_ERROR) {
 49.1044 -        g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_SASL,
 49.1045 -               "%s: error while binding to resource\n", G_STRFUNC);
 49.1046 -
 49.1047 -        connection_call_auth_cb (connection, FALSE);
 49.1048 -
 49.1049 -        return LM_HANDLER_RESULT_REMOVE_MESSAGE;
 49.1050 -    }
 49.1051 -
 49.1052 -    /* use whatever server returns as our effective jid */
 49.1053 -    jid_node = lm_message_node_find_child (message->node, "jid");
 49.1054 -    if (jid_node) {
 49.1055 -        g_free (connection->effective_jid);
 49.1056 -        connection->effective_jid = g_strdup
 49.1057 -            (lm_message_node_get_value (jid_node));
 49.1058 -    }
 49.1059 -
 49.1060 -
 49.1061 -    m = lm_message_new_with_sub_type (NULL,
 49.1062 -                                      LM_MESSAGE_TYPE_IQ,
 49.1063 -                                      LM_MESSAGE_SUB_TYPE_SET);
 49.1064 -
 49.1065 -    session_node = lm_message_node_add_child (m->node, "session", NULL);
 49.1066 -    lm_message_node_set_attributes (session_node,
 49.1067 -                                    "xmlns", XMPP_NS_SESSION,
 49.1068 -                                    NULL);
 49.1069 -
 49.1070 -    result = lm_connection_send (connection, m, NULL);
 49.1071 -    lm_message_unref (m);
 49.1072 -    if (result < 0) {
 49.1073 -        connection_do_close (connection);
 49.1074 -    }
 49.1075 -
 49.1076 -    /* We may finally tell the client they're authorized */
 49.1077 -    connection_call_auth_cb (connection, TRUE);
 49.1078 -
 49.1079 -    return LM_HANDLER_RESULT_REMOVE_MESSAGE;
 49.1080 -}
 49.1081 -
 49.1082 -static LmHandlerResult
 49.1083 -connection_features_cb (LmMessageHandler *handler,
 49.1084 -                        LmConnection     *connection,
 49.1085 -                        LmMessage        *message,
 49.1086 -                        gpointer          user_data)
 49.1087 -{
 49.1088 -    LmMessageNode *bind_node;
 49.1089 -    LmMessageNode *starttls_node;
 49.1090 -    LmMessageNode *old_auth;
 49.1091 -    LmMessageNode *sasl_mechanisms;
 49.1092 -
 49.1093 -    starttls_node = lm_message_node_find_child (message->node, "starttls");
 49.1094 -    if (connection->ssl && lm_old_socket_get_use_starttls (connection->socket)) {
 49.1095 -        if (starttls_node) {
 49.1096 -            LmMessage *msg;
 49.1097 -
 49.1098 -            msg = lm_message_new (NULL, LM_MESSAGE_TYPE_STARTTLS);
 49.1099 -
 49.1100 -            lm_message_node_set_attributes (
 49.1101 -                msg->node,
 49.1102 -                "xmlns", XMPP_NS_STARTTLS,
 49.1103 -                NULL);
 49.1104 -
 49.1105 -            lm_connection_send (connection, msg, NULL);
 49.1106 -            lm_message_unref (msg);
 49.1107 -
 49.1108 -            return LM_HANDLER_RESULT_REMOVE_MESSAGE;
 49.1109 -        } else if (!connection->tls_started &&
 49.1110 -                   lm_old_socket_get_require_starttls (connection->socket)) {
 49.1111 -            /* If there were no starttls features present and we require it, this is
 49.1112 -             * the place to scream. */
 49.1113 -
 49.1114 -            g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_SASL,
 49.1115 -                   "%s: required StartTLS feature not supported by server\n", G_STRFUNC);
 49.1116 -            connection_do_close (connection);
 49.1117 -            connection_signal_disconnect (connection,
 49.1118 -                                          LM_DISCONNECT_REASON_ERROR);
 49.1119 -            return LM_HANDLER_RESULT_REMOVE_MESSAGE;
 49.1120 -        }
 49.1121 -    }
 49.1122 -
 49.1123 -    bind_node = lm_message_node_find_child (message->node, "bind");
 49.1124 -    if (bind_node) {
 49.1125 -        LmMessageHandler *bind_handler;
 49.1126 -        LmMessage        *bind_msg;
 49.1127 -        const gchar      *ns;
 49.1128 -        int               result;
 49.1129 -
 49.1130 -        ns = lm_message_node_get_attribute (bind_node, "xmlns");
 49.1131 -        if (!ns || strcmp (ns, XMPP_NS_BIND) != 0) {
 49.1132 -            return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
 49.1133 -        }
 49.1134 -
 49.1135 -        bind_msg = lm_message_new_with_sub_type (NULL,
 49.1136 -                                                 LM_MESSAGE_TYPE_IQ,
 49.1137 -                                                 LM_MESSAGE_SUB_TYPE_SET);
 49.1138 -
 49.1139 -        bind_node = lm_message_node_add_child (bind_msg->node,
 49.1140 -                                               "bind", NULL);
 49.1141 -        lm_message_node_set_attributes (bind_node,
 49.1142 -                                        "xmlns", XMPP_NS_BIND,
 49.1143 -                                        NULL);
 49.1144 -
 49.1145 -        lm_message_node_add_child (bind_node, "resource",
 49.1146 -                                   connection->resource);
 49.1147 -
 49.1148 -        bind_handler = lm_message_handler_new (connection_bind_reply,
 49.1149 -                                               NULL, NULL);
 49.1150 -        result = lm_connection_send_with_reply (connection, bind_msg,
 49.1151 -                                                bind_handler, NULL);
 49.1152 -        lm_message_handler_unref (bind_handler);
 49.1153 -        lm_message_unref (bind_msg);
 49.1154 -
 49.1155 -        if (result < 0) {
 49.1156 -            g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_SASL,
 49.1157 -                   "%s: can't send resource binding request\n", G_STRFUNC);
 49.1158 -            connection_do_close (connection);
 49.1159 -        }
 49.1160 -    }
 49.1161 -
 49.1162 -    old_auth = lm_message_node_find_child (message->node, "auth");
 49.1163 -
 49.1164 -    sasl_mechanisms = lm_message_node_find_child (message->node, "mechanisms");
 49.1165 -    if (connection->use_sasl && old_auth != NULL && sasl_mechanisms == NULL) {
 49.1166 -        g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_SASL,
 49.1167 -               "Server uses XEP-0078 (jabber iq auth) instead of SASL\n");
 49.1168 -        /* So the server is XMPP1.0, but doesn't support SASL and uses
 49.1169 -         * obsolete XEP-0078 instead. Let's cope. */
 49.1170 -
 49.1171 -        connection->use_sasl = FALSE;
 49.1172 -
 49.1173 -        if (connection->sasl) {
 49.1174 -            if (lm_sasl_get_auth_params (connection->sasl)) {
 49.1175 -                GError *error = NULL;
 49.1176 -                connection_old_auth (connection, lm_sasl_get_auth_params (connection->sasl),
 49.1177 -                                     &error);
 49.1178 -
 49.1179 -                if (error) {
 49.1180 -                    g_error_free (error);
 49.1181 -                }
 49.1182 -            }
 49.1183 -
 49.1184 -            lm_sasl_free (connection->sasl);
 49.1185 -            connection->sasl = NULL;
 49.1186 -        }
 49.1187 -    }
 49.1188 -
 49.1189 -    return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
 49.1190 -}
 49.1191 -
 49.1192 -/**
 49.1193 - * lm_connection_new:
 49.1194 - * @server: The hostname to the server for the connection.
 49.1195 - *
 49.1196 - * Creates a new closed connection. To open the connection call
 49.1197 - * lm_connection_open(). @server can be #NULL but must be set before calling lm_connection_open().
 49.1198 - *
 49.1199 - * Return value: A newly created LmConnection, should be unreffed with lm_connection_unref().
 49.1200 - **/
 49.1201 -LmConnection *
 49.1202 -lm_connection_new (const gchar *server)
 49.1203 -{
 49.1204 -    LmConnection *connection;
 49.1205 -    gint          i;
 49.1206 -
 49.1207 -    g_type_init (); /* Ensure that the GLib type library is initialized */
 49.1208 -    lm_debug_init ();
 49.1209 -    _lm_sock_library_init ();
 49.1210 -
 49.1211 -    connection = g_slice_new0 (LmConnection);
 49.1212 -
 49.1213 -    if (server) {
 49.1214 -        connection->server  = _lm_utils_hostname_to_punycode (server);
 49.1215 -    }
 49.1216 -
 49.1217 -    connection->port        = LM_CONNECTION_DEFAULT_PORT;
 49.1218 -    connection->queue       = lm_message_queue_new (
 49.1219 -        (LmMessageQueueCallback) connection_message_queue_cb,
 49.1220 -        connection,
 49.1221 -        NULL);
 49.1222 -    connection->state       = LM_CONNECTION_STATE_CLOSED;
 49.1223 -
 49.1224 -    connection->id_handlers = g_hash_table_new_full (g_str_hash,
 49.1225 -                                                     g_str_equal,
 49.1226 -                                                     g_free,
 49.1227 -                                                     (GDestroyNotify) lm_message_handler_unref);
 49.1228 -    connection->ref_count   = 1;
 49.1229 -
 49.1230 -    for (i = 0; i < LM_MESSAGE_TYPE_UNKNOWN; ++i) {
 49.1231 -        connection->handlers[i] = NULL;
 49.1232 -    }
 49.1233 -
 49.1234 -    connection->parser = lm_parser_new
 49.1235 -        ((LmParserMessageFunction) connection_new_message_cb,
 49.1236 -         connection, NULL);
 49.1237 -
 49.1238 -    return connection;
 49.1239 -}
 49.1240 -
 49.1241 -/**
 49.1242 - * lm_connection_new_with_context:
 49.1243 - * @server: The hostname to the server for the connection.
 49.1244 - * @context: The context this connection should be running in.
 49.1245 - *
 49.1246 - * Creates a new closed connection running in a certain context. To open the
 49.1247 - * connection call #lm_connection_open. @server can be #NULL but must be set
 49.1248 - * before calling #lm_connection_open.
 49.1249 - *
 49.1250 - * Return value: A newly created LmConnection, should be unreffed with lm_connection_unref().
 49.1251 - **/
 49.1252 -LmConnection *
 49.1253 -lm_connection_new_with_context (const gchar *server, GMainContext *context)
 49.1254 -{
 49.1255 -    LmConnection *connection;
 49.1256 -
 49.1257 -    connection = lm_connection_new (server);
 49.1258 -    connection->context = context;
 49.1259 -
 49.1260 -    if (context) {
 49.1261 -        g_main_context_ref (connection->context);
 49.1262 -    }
 49.1263 -
 49.1264 -    return connection;
 49.1265 -}
 49.1266 -
 49.1267 -/**
 49.1268 - * lm_connection_open:
 49.1269 - * @connection: #LmConnection to open
 49.1270 - * @function: Callback function that will be called when the connection is open.
 49.1271 - * @user_data: User data that will be passed to @function.
 49.1272 - * @notify: Function for freeing that user_data, can be NULL.
 49.1273 - * @error: location to store error, or %NULL
 49.1274 - *
 49.1275 - * An async call to open @connection. When the connection is open @function will be called.
 49.1276 - *
 49.1277 - * Return value: #TRUE if everything went fine, otherwise #FALSE.
 49.1278 - **/
 49.1279 -gboolean
 49.1280 -lm_connection_open (LmConnection      *connection,
 49.1281 -                    LmResultFunction   function,
 49.1282 -                    gpointer           user_data,
 49.1283 -                    GDestroyNotify     notify,
 49.1284 -                    GError           **error)
 49.1285 -{
 49.1286 -    g_return_val_if_fail (connection != NULL, FALSE);
 49.1287 -
 49.1288 -    connection->open_cb = _lm_utils_new_callback (function,
 49.1289 -                                                  user_data, notify);
 49.1290 -
 49.1291 -    return connection_do_open (connection, error);
 49.1292 -}
 49.1293 -
 49.1294 -/**
 49.1295 - * lm_connection_open_and_block:
 49.1296 - * @connection: an #LmConnection to open
 49.1297 - * @error: location to store error, or %NULL
 49.1298 - *
 49.1299 - * Opens @connection and waits until the stream is setup.
 49.1300 - *
 49.1301 - * Return value: #TRUE if no errors where encountered during opening and stream setup successfully, #FALSE otherwise.
 49.1302 - **/
 49.1303 -gboolean
 49.1304 -lm_connection_open_and_block (LmConnection *connection, GError **error)
 49.1305 -{
 49.1306 -    gboolean result;
 49.1307 -
 49.1308 -    g_return_val_if_fail (connection != NULL, FALSE);
 49.1309 -
 49.1310 -    connection->open_cb = NULL;
 49.1311 -
 49.1312 -    result = connection_do_open (connection, error);
 49.1313 -
 49.1314 -    if (result == FALSE) {
 49.1315 -        return FALSE;
 49.1316 -    }
 49.1317 -
 49.1318 -    while (lm_connection_get_state (connection) == LM_CONNECTION_STATE_OPENING) {
 49.1319 -        if (g_main_context_pending (connection->context)) {
 49.1320 -            g_main_context_iteration (connection->context, TRUE);
 49.1321 -        } else {
 49.1322 -            /* Sleep for 1 millisecond */
 49.1323 -            g_usleep (1000);
 49.1324 -        }
 49.1325 -    }
 49.1326 -
 49.1327 -    if (lm_connection_is_open (connection)) {
 49.1328 -        connection_start_keep_alive (connection);
 49.1329 -        return TRUE;
 49.1330 -    }
 49.1331 -
 49.1332 -    /* Need to set the error here: LM-15 */
 49.1333 -    g_set_error (error,
 49.1334 -                 LM_ERROR,
 49.1335 -                 LM_ERROR_CONNECTION_FAILED,
 49.1336 -                 "Opening the connection failed");
 49.1337 -
 49.1338 -    return FALSE;
 49.1339 -}
 49.1340 -
 49.1341 -/**
 49.1342 - * lm_connection_cancel_open:
 49.1343 - * @connection: an #LmConnection to cancel opening on
 49.1344 - *
 49.1345 - * Cancels the open operation of a connection. The connection should be in the state #LM_CONNECTION_STATE_OPENING.
 49.1346 - **/
 49.1347 -void
 49.1348 -lm_connection_cancel_open (LmConnection *connection)
 49.1349 -{
 49.1350 -    g_return_if_fail (connection != NULL);
 49.1351 -
 49.1352 -    if (connection->open_cb) {
 49.1353 -        _lm_utils_free_callback (connection->open_cb);
 49.1354 -        connection->open_cb = NULL;
 49.1355 -    }
 49.1356 -
 49.1357 -    connection->cancel_open = TRUE;
 49.1358 -
 49.1359 -    lm_old_socket_asyncns_cancel (connection->socket);
 49.1360 -}
 49.1361 -
 49.1362 -/**
 49.1363 - * lm_connection_close:
 49.1364 - * @connection: #LmConnection to close
 49.1365 - * @error: location to store error, or %NULL
 49.1366 - *
 49.1367 - * A synchronous call to close the connection. When returning the connection is considered to be closed and can be opened again with lm_connection_open().
 49.1368 - *
 49.1369 - * Return value: Returns #TRUE if no errors where detected, otherwise #FALSE.
 49.1370 - **/
 49.1371 -gboolean
 49.1372 -lm_connection_close (LmConnection *connection, GError **error)
 49.1373 -{
 49.1374 -    gboolean no_errors = TRUE;
 49.1375 -
 49.1376 -    g_return_val_if_fail (connection != NULL, FALSE);
 49.1377 -
 49.1378 -    if (connection->socket) {
 49.1379 -        lm_old_socket_asyncns_cancel (connection->socket);
 49.1380 -    }
 49.1381 -
 49.1382 -    if (connection->state == LM_CONNECTION_STATE_CLOSED) {
 49.1383 -        g_set_error (error,
 49.1384 -                     LM_ERROR,
 49.1385 -                     LM_ERROR_CONNECTION_NOT_OPEN,
 49.1386 -                     "Connection is not open, call lm_connection_open() first");
 49.1387 -        return FALSE;
 49.1388 -    }
 49.1389 -
 49.1390 -    lm_verbose ("Disconnecting from: %s:%d\n",
 49.1391 -                connection->server, connection->port);
 49.1392 -
 49.1393 -    if (lm_connection_is_open (connection)) {
 49.1394 -        if (!connection_send (connection, "</stream:stream>", -1, error)) {
 49.1395 -            no_errors = FALSE;
 49.1396 -        }
 49.1397 -
 49.1398 -        lm_old_socket_flush (connection->socket);
 49.1399 -    }
 49.1400 -
 49.1401 -    connection_do_close (connection);
 49.1402 -    connection_signal_disconnect (connection, LM_DISCONNECT_REASON_OK);
 49.1403 -
 49.1404 -    return no_errors;
 49.1405 -}
 49.1406 -
 49.1407 -static void
 49.1408 -connection_sasl_auth_finished (LmSASL       *sasl,
 49.1409 -                               LmConnection *connection,
 49.1410 -                               gboolean      success,
 49.1411 -                               const gchar  *reason)
 49.1412 -{
 49.1413 -    if (!success) {
 49.1414 -        lm_verbose ("SASL authentication failed, closing connection\n");
 49.1415 -        connection_call_auth_cb (connection, FALSE);
 49.1416 -        return;
 49.1417 -    }
 49.1418 -
 49.1419 -    connection_send_stream_header (connection);
 49.1420 -}
 49.1421 -
 49.1422 -/**
 49.1423 - * lm_connection_authenticate:
 49.1424 - * @connection: #LmConnection to authenticate.
 49.1425 - * @username: Username used to authenticate.
 49.1426 - * @password: Password corresponding to @username.
 49.1427 - * @resource: Resource used for this connection.
 49.1428 - * @function: Callback called when authentication is finished.
 49.1429 - * @user_data: Userdata passed to @function when called.
 49.1430 - * @notify: Destroy function to free the memory used by @user_data, can be NULL.
 49.1431 - * @error: location to store error, or %NULL
 49.1432 - *
 49.1433 - * Tries to authenticate a user against the server. The #LmResult in the result callback @function will say whether it succeeded or not.
 49.1434 - *
 49.1435 - * Return value: #TRUE if no errors where detected while sending the authentication message, #FALSE otherwise.
 49.1436 - **/
 49.1437 -gboolean
 49.1438 -lm_connection_authenticate (LmConnection      *connection,
 49.1439 -                            const gchar       *username,
 49.1440 -                            const gchar       *password,
 49.1441 -                            const gchar       *resource,
 49.1442 -                            LmResultFunction   function,
 49.1443 -                            gpointer           user_data,
 49.1444 -                            GDestroyNotify     notify,
 49.1445 -                            GError           **error)
 49.1446 -{
 49.1447 -    LmAuthParameters *auth_params;
 49.1448 -    gboolean          ret_val;
 49.1449 -
 49.1450 -    g_return_val_if_fail (connection != NULL, FALSE);
 49.1451 -    g_return_val_if_fail (username != NULL, FALSE);
 49.1452 -    g_return_val_if_fail (password != NULL, FALSE);
 49.1453 -    g_return_val_if_fail (resource != NULL, FALSE);
 49.1454 -
 49.1455 -    auth_params = lm_auth_parameters_new (username, password, resource);
 49.1456 -
 49.1457 -    if (!lm_connection_is_open (connection)) {
 49.1458 -        g_set_error (error,
 49.1459 -                     LM_ERROR,
 49.1460 -                     LM_ERROR_CONNECTION_NOT_OPEN,
 49.1461 -                     "Connection is not open, call lm_connection_open() first");
 49.1462 -        return FALSE;
 49.1463 -    }
 49.1464 -
 49.1465 -    connection->state = LM_CONNECTION_STATE_AUTHENTICATING;
 49.1466 -
 49.1467 -    connection->auth_cb = _lm_utils_new_callback (function,
 49.1468 -                                                  user_data,
 49.1469 -                                                  notify);
 49.1470 -
 49.1471 -    connection->resource = g_strdup (lm_auth_parameters_get_resource (auth_params));
 49.1472 -
 49.1473 -    connection->effective_jid = g_strdup_printf ("%s/%s",
 49.1474 -                                                 connection->jid, connection->resource);
 49.1475 -
 49.1476 -    /* TODO: Break out Credentials (or use the already existing AuthReqData struct for *
 49.1477 -     *       Username/Password and Resource                                            */
 49.1478 -    if (connection->use_sasl) {
 49.1479 -        gchar *domain = NULL;
 49.1480 -
 49.1481 -        if (!connection_get_server_from_jid (connection->jid, &domain)) {
 49.1482 -            domain = g_strdup (connection->server);
 49.1483 -        }
 49.1484 -
 49.1485 -        lm_sasl_authenticate (connection->sasl, auth_params, domain,
 49.1486 -                              connection_sasl_auth_finished);
 49.1487 -        g_free (domain);
 49.1488 -
 49.1489 -        connection->features_cb  =
 49.1490 -            lm_message_handler_new (connection_features_cb,
 49.1491 -                                    NULL, NULL);
 49.1492 -        lm_connection_register_message_handler (connection,
 49.1493 -                                                connection->features_cb,
 49.1494 -                                                LM_MESSAGE_TYPE_STREAM_FEATURES,
 49.1495 -                                                LM_HANDLER_PRIORITY_FIRST);
 49.1496 -
 49.1497 -        ret_val = TRUE;
 49.1498 -    } else {
 49.1499 -        ret_val = connection_old_auth (connection, auth_params, error);
 49.1500 -    }
 49.1501 -
 49.1502 -    lm_auth_parameters_unref (auth_params);
 49.1503 -
 49.1504 -    return ret_val;
 49.1505 -}
 49.1506 -
 49.1507 -static gboolean
 49.1508 -connection_old_auth (LmConnection      *connection,
 49.1509 -                     LmAuthParameters  *auth_params,
 49.1510 -                     GError           **error)
 49.1511 -{
 49.1512 -    LmMessage        *m;
 49.1513 -    LmMessageHandler *handler;
 49.1514 -    gboolean          result;
 49.1515 -
 49.1516 -    m = connection_create_auth_req_msg (auth_params);
 49.1517 -
 49.1518 -    handler = lm_message_handler_new (connection_auth_req_reply,
 49.1519 -                                      lm_auth_parameters_ref (auth_params),
 49.1520 -                                      (GDestroyNotify) lm_auth_parameters_unref);
 49.1521 -    result = lm_connection_send_with_reply (connection, m, handler, error);
 49.1522 -
 49.1523 -    lm_message_handler_unref (handler);
 49.1524 -    lm_message_unref (m);
 49.1525 -
 49.1526 -    return result;
 49.1527 -}
 49.1528 -
 49.1529 -/**
 49.1530 - * lm_connection_authenticate_and_block:
 49.1531 - * @connection: an #LmConnection
 49.1532 - * @username: Username used to authenticate.
 49.1533 - * @password: Password corresponding to @username.
 49.1534 - * @resource: Resource used for this connection.
 49.1535 - * @error: location to store error, or %NULL
 49.1536 - *
 49.1537 - * Tries to authenticate a user against the server. This function blocks until a reply to the authentication attempt is returned and returns whether it was successful or not.
 49.1538 - *
 49.1539 - * Return value: #TRUE if no errors where detected and authentication was successful. #FALSE otherwise.
 49.1540 - **/
 49.1541 -gboolean
 49.1542 -lm_connection_authenticate_and_block (LmConnection  *connection,
 49.1543 -                                      const gchar   *username,
 49.1544 -                                      const gchar   *password,
 49.1545 -                                      const gchar   *resource,
 49.1546 -                                      GError       **error)
 49.1547 -{
 49.1548 -    gboolean result;
 49.1549 -
 49.1550 -    result = lm_connection_authenticate (connection, username, password,
 49.1551 -                                         resource, NULL, NULL, NULL, error);
 49.1552 -
 49.1553 -    if (!result)
 49.1554 -        return result;
 49.1555 -
 49.1556 -    while (lm_connection_get_state (connection) == LM_CONNECTION_STATE_AUTHENTICATING) {
 49.1557 -        if (g_main_context_pending (connection->context)) {
 49.1558 -            g_main_context_iteration (connection->context, TRUE);
 49.1559 -        } else {
 49.1560 -            /* Sleep for 1 millisecond */
 49.1561 -            g_usleep (1000);
 49.1562 -        }
 49.1563 -    }
 49.1564 -
 49.1565 -    switch (lm_connection_get_state (connection)) {
 49.1566 -    case LM_CONNECTION_STATE_AUTHENTICATED:
 49.1567 -        return TRUE;
 49.1568 -        break;
 49.1569 -    case LM_CONNECTION_STATE_OPEN:
 49.1570 -        g_set_error (error,
 49.1571 -                     LM_ERROR,
 49.1572 -                     LM_ERROR_AUTH_FAILED,
 49.1573 -                     "Authentication failed");
 49.1574 -        return FALSE;
 49.1575 -        break;
 49.1576 -    default:
 49.1577 -        g_assert_not_reached ();
 49.1578 -        break;
 49.1579 -    }
 49.1580 -
 49.1581 -    return FALSE;
 49.1582 -}
 49.1583 -
 49.1584 -/**
 49.1585 - * lm_connection_get_keep_alive_rate:
 49.1586 - * @connection: an #LmConnection
 49.1587 - *
 49.1588 - * Get the keep alive rate, in seconds. Zero is returned if no keep alive rate has been set.
 49.1589 - *
 49.1590 - * Since 1.3.5
 49.1591 - **/
 49.1592 -guint
 49.1593 -lm_connection_get_keep_alive_rate (LmConnection *connection)
 49.1594 -{
 49.1595 -    g_return_val_if_fail (connection != NULL, 0);
 49.1596 -
 49.1597 -    return connection->keep_alive_rate;
 49.1598 -}
 49.1599 -
 49.1600 -/**
 49.1601 - * lm_connection_set_keep_alive_rate:
 49.1602 - * @connection: an #LmConnection
 49.1603 - * @rate: Number of seconds between keep alive packages are sent.
 49.1604 - *
 49.1605 - * Set the keep alive rate, in seconds. Set to 0 to prevent keep alive messages to be sent.
 49.1606 - * A keep alive message is a single space character.
 49.1607 - **/
 49.1608 -void
 49.1609 -lm_connection_set_keep_alive_rate (LmConnection *connection, guint rate)
 49.1610 -{
 49.1611 -    g_return_if_fail (connection != NULL);
 49.1612 -
 49.1613 -    connection_stop_keep_alive (connection);
 49.1614 -
 49.1615 -    if (rate == 0) {
 49.1616 -        return;
 49.1617 -    }
 49.1618 -
 49.1619 -    connection->keep_alive_rate = rate;
 49.1620 -
 49.1621 -    if (lm_connection_is_open (connection)) {
 49.1622 -        connection_start_keep_alive (connection);
 49.1623 -    }
 49.1624 -}
 49.1625 -
 49.1626 -/**
 49.1627 - * lm_connection_is_open:
 49.1628 - * @connection: #LmConnection to check if it is open.
 49.1629 - *
 49.1630 - * Check if the @connection is currently open.
 49.1631 - *
 49.1632 - * Return value: #TRUE if connection is open and #FALSE if it is closed.
 49.1633 - **/
 49.1634 -gboolean
 49.1635 -lm_connection_is_open (LmConnection *connection)
 49.1636 -{
 49.1637 -    g_return_val_if_fail (connection != NULL, FALSE);
 49.1638 -
 49.1639 -    return connection->state >= LM_CONNECTION_STATE_OPEN;
 49.1640 -}
 49.1641 -
 49.1642 -/**
 49.1643 - * lm_connection_is_authenticated:
 49.1644 - * @connection: #LmConnection to check if it is authenticated
 49.1645 - *
 49.1646 - * Check if @connection is authenticated.
 49.1647 - *
 49.1648 - * Return value: #TRUE if connection is authenticated, #FALSE otherwise.
 49.1649 - **/
 49.1650 -gboolean
 49.1651 -lm_connection_is_authenticated (LmConnection *connection)
 49.1652 -{
 49.1653 -    g_return_val_if_fail (connection != NULL, FALSE);
 49.1654 -
 49.1655 -    return connection->state >= LM_CONNECTION_STATE_AUTHENTICATED;
 49.1656 -}
 49.1657 -
 49.1658 -/**
 49.1659 - * lm_connection_get_server:
 49.1660 - * @connection: an #LmConnection
 49.1661 - *
 49.1662 - * Fetches the server address that @connection is using.
 49.1663 - *
 49.1664 - * Return value: the server address
 49.1665 - **/
 49.1666 -const gchar *
 49.1667 -lm_connection_get_server (LmConnection *connection)
 49.1668 -{
 49.1669 -    g_return_val_if_fail (connection != NULL, NULL);
 49.1670 -
 49.1671 -    return connection->server;
 49.1672 -}
 49.1673 -
 49.1674 -/**
 49.1675 - * lm_connection_set_server:
 49.1676 - * @connection: an #LmConnection
 49.1677 - * @server: Address of the server
 49.1678 - *
 49.1679 - * Sets the server address for @connection to @server. Notice that @connection
 49.1680 - * can't be open while doing this.
 49.1681 - **/
 49.1682 -void
 49.1683 -lm_connection_set_server (LmConnection *connection, const gchar *server)
 49.1684 -{
 49.1685 -    g_return_if_fail (connection != NULL);
 49.1686 -    g_return_if_fail (server != NULL);
 49.1687 -
 49.1688 -    if (lm_connection_is_open (connection)) {
 49.1689 -        g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_VERBOSE,
 49.1690 -               "Can't change server address while connected");
 49.1691 -        return;
 49.1692 -    }
 49.1693 -
 49.1694 -    g_free (connection->server);
 49.1695 -    connection->server = _lm_utils_hostname_to_punycode (server);
 49.1696 -}
 49.1697 -
 49.1698 -/**
 49.1699 - * lm_connection_get_jid:
 49.1700 - * @connection: an #LmConnection
 49.1701 - *
 49.1702 - * Fetches the jid set for @connection is using.
 49.1703 - *
 49.1704 - * Return value: the jid
 49.1705 - **/
 49.1706 -const gchar *
 49.1707 -lm_connection_get_jid (LmConnection *connection)
 49.1708 -{
 49.1709 -    g_return_val_if_fail (connection != NULL, NULL);
 49.1710 -
 49.1711 -    return connection->jid;
 49.1712 -}
 49.1713 -
 49.1714 -/**
 49.1715 - * lm_connection_get_full_jid:
 49.1716 - * @connection: an #LmConnection
 49.1717 - *
 49.1718 - * Returns the full jid that server set for us after
 49.1719 - * resource binding, complete with the resource.
 49.1720 - *
 49.1721 - * Return value: the jid
 49.1722 - **/
 49.1723 -gchar *
 49.1724 -lm_connection_get_full_jid (LmConnection *connection)
 49.1725 -{
 49.1726 -    g_return_val_if_fail (connection != NULL, NULL);
 49.1727 -
 49.1728 -    return connection->effective_jid;
 49.1729 -}
 49.1730 -
 49.1731 -/**
 49.1732 - * lm_connection_set_jid:
 49.1733 - * @connection: an #LmConnection
 49.1734 - * @jid: JID to be used for @connection
 49.1735 - *
 49.1736 - * Sets the JID to be used for @connection.
 49.1737 - **/
 49.1738 -void
 49.1739 -lm_connection_set_jid (LmConnection *connection, const gchar *jid)
 49.1740 -{
 49.1741 -    g_return_if_fail (connection != NULL);
 49.1742 -
 49.1743 -    if (lm_connection_is_open (connection)) {
 49.1744 -        g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_VERBOSE,
 49.1745 -                   "Can't change JID while connected");
 49.1746 -        return;
 49.1747 -    }
 49.1748 -
 49.1749 -    g_free (connection->jid);
 49.1750 -    connection->jid = g_strdup (jid);
 49.1751 -}
 49.1752 -
 49.1753 -/**
 49.1754 - * lm_connection_get_port:
 49.1755 - * @connection: an #LmConnection
 49.1756 - *
 49.1757 - * Fetches the port that @connection is using.
 49.1758 - *
 49.1759 - * Return value:
 49.1760 - **/
 49.1761 -guint
 49.1762 -lm_connection_get_port (LmConnection *connection)
 49.1763 -{
 49.1764 -    g_return_val_if_fail (connection != NULL, 0);
 49.1765 -
 49.1766 -    return connection->port;
 49.1767 -}
 49.1768 -
 49.1769 -/**
 49.1770 - * lm_connection_set_port:
 49.1771 - * @connection: an #LmConnection
 49.1772 - * @port: server port
 49.1773 - *
 49.1774 - * Sets the server port that @connection will be using.
 49.1775 - **/
 49.1776 -void
 49.1777 -lm_connection_set_port (LmConnection *connection, guint port)
 49.1778 -{
 49.1779 -    g_return_if_fail (connection != NULL);
 49.1780 -
 49.1781 -    if (lm_connection_is_open (connection)) {
 49.1782 -        g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_VERBOSE,
 49.1783 -               "Can't change server port while connected");
 49.1784 -        return;
 49.1785 -    }
 49.1786 -
 49.1787 -    connection->port = port;
 49.1788 -}
 49.1789 -
 49.1790 -/**
 49.1791 - * lm_connection_get_ssl:
 49.1792 - * @connection: an #LmConnection
 49.1793 - *
 49.1794 - * Returns the SSL struct if the connection is using one.
 49.1795 - *
 49.1796 - * Return value: The ssl struct or %NULL if no proxy is used.
 49.1797 - **/
 49.1798 -LmSSL *
 49.1799 -lm_connection_get_ssl (LmConnection *connection)
 49.1800 -{
 49.1801 -    g_return_val_if_fail (connection != NULL, NULL);
 49.1802 -
 49.1803 -    return connection->ssl;
 49.1804 -}
 49.1805 -
 49.1806 -/**
 49.1807 - * lm_connection_set_ssl:
 49.1808 - * @connection: An #LmConnection
 49.1809 - * @ssl: An #LmSSL
 49.1810 - *
 49.1811 - * Sets SSL struct or unset if @ssl is %NULL. If set @connection will use SSL to for the connection.
 49.1812 - */
 49.1813 -void
 49.1814 -lm_connection_set_ssl (LmConnection *connection, LmSSL *ssl)
 49.1815 -{
 49.1816 -    g_return_if_fail (connection != NULL);
 49.1817 -    g_return_if_fail (lm_ssl_is_supported () == TRUE);
 49.1818 -
 49.1819 -    if (connection->ssl) {
 49.1820 -        lm_ssl_unref (connection->ssl);
 49.1821 -    }
 49.1822 -
 49.1823 -    if (ssl) {
 49.1824 -        connection->ssl = lm_ssl_ref (ssl);
 49.1825 -    } else {
 49.1826 -        connection->ssl = NULL;
 49.1827 -    }
 49.1828 -}
 49.1829 -
 49.1830 -/**
 49.1831 - * lm_connection_get_proxy:
 49.1832 - * @connection: an #LmConnection
 49.1833 - *
 49.1834 - * Returns the proxy if the connection is using one.
 49.1835 - *
 49.1836 - * Return value: The proxy or %NULL if no proxy is used.
 49.1837 - **/
 49.1838 -LmProxy *
 49.1839 -lm_connection_get_proxy (LmConnection *connection)
 49.1840 -{
 49.1841 -    g_return_val_if_fail (connection != NULL, NULL);
 49.1842 -
 49.1843 -    return connection->proxy;
 49.1844 -}
 49.1845 -
 49.1846 -/**
 49.1847 - * lm_connection_set_proxy:
 49.1848 - * @connection: an #LmConnection
 49.1849 - * @proxy: an #LmProxy
 49.1850 - *
 49.1851 - * Sets the proxy to use for this connection. To unset pass #NULL.
 49.1852 - *
 49.1853 - **/
 49.1854 -void
 49.1855 -lm_connection_set_proxy (LmConnection *connection, LmProxy *proxy)
 49.1856 -{
 49.1857 -    g_return_if_fail (connection != NULL);
 49.1858 -
 49.1859 -    if (lm_connection_is_open (connection)) {
 49.1860 -        g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_VERBOSE,
 49.1861 -               "Can't change server proxy while connected");
 49.1862 -        return;
 49.1863 -    }
 49.1864 -
 49.1865 -    if (connection->proxy) {
 49.1866 -        lm_proxy_unref (connection->proxy);
 49.1867 -        connection->proxy = NULL;
 49.1868 -    }
 49.1869 -
 49.1870 -    if (proxy && lm_proxy_get_type (proxy) != LM_PROXY_TYPE_NONE) {
 49.1871 -        connection->proxy = lm_proxy_ref (proxy);
 49.1872 -    }
 49.1873 -}
 49.1874 -
 49.1875 -/**
 49.1876 - * lm_connection_send:
 49.1877 - * @connection: #LmConnection to send message over.
 49.1878 - * @message: #LmMessage to send.
 49.1879 - * @error: location to store error, or %NULL
 49.1880 - *
 49.1881 - * Asynchronous call to send a message.
 49.1882 - *
 49.1883 - * Return value: Returns #TRUE if no errors where detected while sending, #FALSE otherwise.
 49.1884 - **/
 49.1885 -gboolean
 49.1886 -lm_connection_send (LmConnection  *connection,
 49.1887 -                    LmMessage     *message,
 49.1888 -                    GError       **error)
 49.1889 -{
 49.1890 -    gchar    *xml_str;
 49.1891 -    gchar    *ch;
 49.1892 -    gboolean  result;
 49.1893 -
 49.1894 -    g_return_val_if_fail (connection != NULL, FALSE);
 49.1895 -    g_return_val_if_fail (message != NULL, FALSE);
 49.1896 -
 49.1897 -    xml_str = lm_message_node_to_string (message->node);
 49.1898 -    if ((ch = strstr (xml_str, "</stream:stream>"))) {
 49.1899 -        *ch = '\0';
 49.1900 -    }
 49.1901 -
 49.1902 -    result = connection_send (connection, xml_str, -1, error);
 49.1903 -    g_free (xml_str);
 49.1904 -
 49.1905 -    return result;
 49.1906 -}
 49.1907 -
 49.1908 -/**
 49.1909 - * lm_connection_send_with_reply:
 49.1910 - * @connection: #LmConnection used to send message.
 49.1911 - * @message: #LmMessage to send.
 49.1912 - * @handler: #LmMessageHandler that will be used when a reply to @message arrives
 49.1913 - * @error: location to store error, or %NULL
 49.1914 - *
 49.1915 - * Send a #LmMessage which will result in a reply.
 49.1916 - *
 49.1917 - * Return value: Returns #TRUE if no errors where detected while sending, #FALSE otherwise.
 49.1918 - **/
 49.1919 -gboolean
 49.1920 -lm_connection_send_with_reply (LmConnection      *connection,
 49.1921 -                               LmMessage         *message,
 49.1922 -                               LmMessageHandler  *handler,
 49.1923 -                               GError           **error)
 49.1924 -{
 49.1925 -    gchar *id;
 49.1926 -
 49.1927 -    g_return_val_if_fail (connection != NULL, FALSE);
 49.1928 -    g_return_val_if_fail (message != NULL, FALSE);
 49.1929 -    g_return_val_if_fail (handler != NULL, FALSE);
 49.1930 -
 49.1931 -    if (lm_message_node_get_attribute (message->node, "id")) {
 49.1932 -        id = g_strdup (lm_message_node_get_attribute (message->node,
 49.1933 -                                                      "id"));
 49.1934 -    } else {
 49.1935 -        id = _lm_utils_generate_id ();
 49.1936 -        lm_message_node_set_attributes (message->node, "id", id, NULL);
 49.1937 -    }
 49.1938 -
 49.1939 -    g_hash_table_insert (connection->id_handlers,
 49.1940 -                         id, lm_message_handler_ref (handler));
 49.1941 -
 49.1942 -    return lm_connection_send (connection, message, error);
 49.1943 -}
 49.1944 -
 49.1945 -/**
 49.1946 - * lm_connection_send_with_reply_and_block:
 49.1947 - * @connection: an #LmConnection
 49.1948 - * @message: an #LmMessage
 49.1949 - * @error: Set if error was detected during sending.
 49.1950 - *
 49.1951 - * Send @message and wait for return.
 49.1952 - *
 49.1953 - * Return value: The reply
 49.1954 - **/
 49.1955 -LmMessage *
 49.1956 -lm_connection_send_with_reply_and_block (LmConnection  *connection,
 49.1957 -                                         LmMessage     *message,
 49.1958 -                                         GError       **error)
 49.1959 -{
 49.1960 -    gchar     *id;
 49.1961 -    LmMessage *reply = NULL;
 49.1962 -
 49.1963 -    g_return_val_if_fail (connection != NULL, NULL);
 49.1964 -    g_return_val_if_fail (message != NULL, NULL);
 49.1965 -
 49.1966 -    if (connection->state < LM_CONNECTION_STATE_OPENING) {
 49.1967 -        g_set_error (error,
 49.1968 -                     LM_ERROR,
 49.1969 -                     LM_ERROR_CONNECTION_NOT_OPEN,
 49.1970 -                     "Connection is not open, call lm_connection_open() first");
 49.1971 -        return FALSE;
 49.1972 -    }
 49.1973 -
 49.1974 -
 49.1975 -    if (lm_message_node_get_attribute (message->node, "id")) {
 49.1976 -        id = g_strdup (lm_message_node_get_attribute (message->node,
 49.1977 -                                                      "id"));
 49.1978 -    } else {
 49.1979 -        id = _lm_utils_generate_id ();
 49.1980 -        lm_message_node_set_attributes (message->node, "id", id, NULL);
 49.1981 -    }
 49.1982 -
 49.1983 -    lm_message_queue_detach (connection->queue);
 49.1984 -
 49.1985 -    lm_connection_send (connection, message, error);
 49.1986 -
 49.1987 -    while (!reply) {
 49.1988 -        const gchar *m_id;
 49.1989 -        guint        n;
 49.1990 -
 49.1991 -        g_main_context_iteration (connection->context, TRUE);
 49.1992 -
 49.1993 -        if (lm_message_queue_is_empty (connection->queue)) {
 49.1994 -            continue;
 49.1995 -        }
 49.1996 -
 49.1997 -        for (n = 0; n < lm_message_queue_get_length (connection->queue); n++) {
 49.1998 -            LmMessage *m;
 49.1999 -
 49.2000 -            m = (LmMessage *) lm_message_queue_peek_nth (connection->queue, n);
 49.2001 -
 49.2002 -            m_id = lm_message_node_get_attribute (m->node, "id");
 49.2003 -
 49.2004 -            if (m_id && strcmp (m_id, id) == 0) {
 49.2005 -                reply = m;
 49.2006 -                lm_message_queue_pop_nth (connection->queue, n);
 49.2007 -                break;
 49.2008 -            }
 49.2009 -        }
 49.2010 -    }
 49.2011 -
 49.2012 -    g_free (id);
 49.2013 -    lm_message_queue_attach (connection->queue, connection->context);
 49.2014 -
 49.2015 -    return reply;
 49.2016 -}
 49.2017 -
 49.2018 -/**
 49.2019 - * lm_connection_unregister_reply_handler:
 49.2020 - * @connection: Connection to unregister a handler for.
 49.2021 - * @handler: The handler to unregister.
 49.2022 - *
 49.2023 - * Unregisters the reply handler for @connection. @handler will no longer be
 49.2024 - * called if an incoming message has the id for which it was registered.
 49.2025 - **/
 49.2026 -void
 49.2027 -lm_connection_unregister_reply_handler (LmConnection     *connection,
 49.2028 -                                        LmMessageHandler *handler)
 49.2029 -{
 49.2030 -    GHashTableIter iter;
 49.2031 -    gpointer key, value;
 49.2032 -
 49.2033 -    g_return_if_fail (connection != NULL);
 49.2034 -    g_return_if_fail (handler != NULL);
 49.2035 -
 49.2036 -    g_hash_table_iter_init (&iter, connection -> id_handlers);
 49.2037 -    while (g_hash_table_iter_next (&iter, &key, &value)) {
 49.2038 -        if (handler == value) {
 49.2039 -            g_hash_table_iter_remove (&iter);
 49.2040 -            break;
 49.2041 -        }
 49.2042 -    }
 49.2043 -}
 49.2044 -
 49.2045 -/**
 49.2046 - * lm_connection_register_message_handler:
 49.2047 - * @connection: Connection to register a handler for.
 49.2048 - * @handler: Message handler to register.
 49.2049 - * @type: Message type that @handler will handle.
 49.2050 - * @priority: The priority in which to call @handler.
 49.2051 - *
 49.2052 - * Registers a #LmMessageHandler to handle incoming messages of a certain type.
 49.2053 - * To unregister the handler call lm_connection_unregister_message_handler().
 49.2054 - **/
 49.2055 -void
 49.2056 -lm_connection_register_message_handler  (LmConnection      *connection,
 49.2057 -                                         LmMessageHandler  *handler,
 49.2058 -                                         LmMessageType      type,
 49.2059 -                                         LmHandlerPriority  priority)
 49.2060 -{
 49.2061 -    HandlerData *hd;
 49.2062 -
 49.2063 -    g_return_if_fail (connection != NULL);
 49.2064 -    g_return_if_fail (handler != NULL);
 49.2065 -    g_return_if_fail (type != LM_MESSAGE_TYPE_UNKNOWN);
 49.2066 -
 49.2067 -    hd = g_new0 (HandlerData, 1);
 49.2068 -    hd->priority = priority;
 49.2069 -    hd->handler  = lm_message_handler_ref (handler);
 49.2070 -
 49.2071 -    connection->handlers[type] = g_slist_insert_sorted (connection->handlers[type],
 49.2072 -                                                        hd,
 49.2073 -                                                        (GCompareFunc) connection_handler_compare_func);
 49.2074 -}
 49.2075 -
 49.2076 -/**
 49.2077 - * lm_connection_unregister_message_handler:
 49.2078 - * @connection: Connection to unregister a handler for.
 49.2079 - * @handler: The handler to unregister.
 49.2080 - * @type: What type of messages to unregister this handler for.
 49.2081 - *
 49.2082 - * Unregisters a handler for @connection. @handler will no longer be called
 49.2083 - * when incoming messages of @type arrive.
 49.2084 - **/
 49.2085 -void
 49.2086 -lm_connection_unregister_message_handler (LmConnection     *connection,
 49.2087 -                                          LmMessageHandler *handler,
 49.2088 -                                          LmMessageType     type)
 49.2089 -{
 49.2090 -    GSList *l;
 49.2091 -
 49.2092 -    g_return_if_fail (connection != NULL);
 49.2093 -    g_return_if_fail (handler != NULL);
 49.2094 -    g_return_if_fail (type != LM_MESSAGE_TYPE_UNKNOWN);
 49.2095 -
 49.2096 -    for (l = connection->handlers[type]; l; l = l->next) {
 49.2097 -        HandlerData *hd = (HandlerData *) l->data;
 49.2098 -
 49.2099 -        if (handler == hd->handler) {
 49.2100 -            connection->handlers[type] = g_slist_remove_link (connection->handlers[type], l);
 49.2101 -            g_slist_free (l);
 49.2102 -            lm_message_handler_unref (hd->handler);
 49.2103 -            g_free (hd);
 49.2104 -            break;
 49.2105 -        }
 49.2106 -    }
 49.2107 -}
 49.2108 -
 49.2109 -/**
 49.2110 - * lm_connection_set_disconnect_function:
 49.2111 - * @connection: Connection to register disconnect callback for.
 49.2112 - * @function: Function to be called when @connection is closed.
 49.2113 - * @user_data: User data passed to @function.
 49.2114 - * @notify: Function that will be called with @user_data when @user_data needs to be freed. Pass #NULL if it shouldn't be freed.
 49.2115 - *
 49.2116 - * Set the callback that will be called when a connection is closed.
 49.2117 - **/
 49.2118 -void
 49.2119 -lm_connection_set_disconnect_function (LmConnection         *connection,
 49.2120 -                                       LmDisconnectFunction  function,
 49.2121 -                                       gpointer              user_data,
 49.2122 -                                       GDestroyNotify        notify)
 49.2123 -{
 49.2124 -    g_return_if_fail (connection != NULL);
 49.2125 -
 49.2126 -    if (connection->disconnect_cb) {
 49.2127 -        _lm_utils_free_callback (connection->disconnect_cb);
 49.2128 -    }
 49.2129 -
 49.2130 -    if (function) {
 49.2131 -        connection->disconnect_cb = _lm_utils_new_callback (function,
 49.2132 -                                                            user_data,
 49.2133 -                                                            notify);
 49.2134 -    } else {
 49.2135 -        connection->disconnect_cb = NULL;
 49.2136 -    }
 49.2137 -}
 49.2138 -
 49.2139 -/**
 49.2140 - * lm_connection_send_raw:
 49.2141 - * @connection: Connection used to send
 49.2142 - * @str: The string to send, the entire string will be sent.
 49.2143 - * @error: Set if error was detected during sending.
 49.2144 - *
 49.2145 - * Asynchronous call to send a raw string. Useful for debugging and testing.
 49.2146 - *
 49.2147 - * Return value: Returns #TRUE if no errors was detected during sending,
 49.2148 - * #FALSE otherwise.
 49.2149 - **/
 49.2150 -gboolean
 49.2151 -lm_connection_send_raw (LmConnection  *connection,
 49.2152 -                        const gchar   *str,
 49.2153 -                        GError       **error)
 49.2154 -{
 49.2155 -    g_return_val_if_fail (connection != NULL, FALSE);
 49.2156 -    g_return_val_if_fail (str != NULL, FALSE);
 49.2157 -
 49.2158 -    return connection_send (connection, str, -1, error);
 49.2159 -}
 49.2160 -/**
 49.2161 - * lm_connection_get_state:
 49.2162 - * @connection: Connection to get state on
 49.2163 - *
 49.2164 - * Returns the state of the connection.
 49.2165 - *
 49.2166 - * Return value: The state of the connection.
 49.2167 - **/
 49.2168 -LmConnectionState
 49.2169 -lm_connection_get_state (LmConnection *connection)
 49.2170 -{
 49.2171 -    g_return_val_if_fail (connection != NULL,
 49.2172 -                          LM_CONNECTION_STATE_CLOSED);
 49.2173 -
 49.2174 -    return connection->state;
 49.2175 -}
 49.2176 -
 49.2177 -/**
 49.2178 - * lm_connection_get_client_host:
 49.2179 - * @connection: An #LmConnection
 49.2180 - *
 49.2181 - * Returns the local host name of the connection.
 49.2182 - *
 49.2183 - * Return value: A newly allocated string representing the local host name.
 49.2184 - **/
 49.2185 -gchar *
 49.2186 -lm_connection_get_local_host (LmConnection *connection)
 49.2187 -{
 49.2188 -    return lm_old_socket_get_local_host (connection->socket);
 49.2189 -}
 49.2190 -
 49.2191 -/**
 49.2192 - * lm_connection_ref:
 49.2193 - * @connection: Connection to add a reference to.
 49.2194 - *
 49.2195 - * Add a reference on @connection. To remove a reference call
 49.2196 - * lm_connection_unref().
 49.2197 - *
 49.2198 - * Return value: Returns the same connection.
 49.2199 - **/
 49.2200 -LmConnection*
 49.2201 -lm_connection_ref (LmConnection *connection)
 49.2202 -{
 49.2203 -    g_return_val_if_fail (connection != NULL, NULL);
 49.2204 -
 49.2205 -    connection->ref_count++;
 49.2206 -
 49.2207 -    return connection;
 49.2208 -}
 49.2209 -
 49.2210 -/**
 49.2211 - * lm_connection_unref:
 49.2212 - * @connection: Connection to remove reference from.
 49.2213 - *
 49.2214 - * Removes a reference on @connection. If there are no references to
 49.2215 - * @connection it will be freed and shouldn't be used again.
 49.2216 - **/
 49.2217 -void
 49.2218 -lm_connection_unref (LmConnection *connection)
 49.2219 -{
 49.2220 -    g_return_if_fail (connection != NULL);
 49.2221 -
 49.2222 -    connection->ref_count--;
 49.2223 -
 49.2224 -    if (connection->ref_count == 0) {
 49.2225 -        connection_free (connection);
 49.2226 -    }
 49.2227 -}
    50.1 --- a/src/lm-debug.c	Wed Dec 25 20:33:47 2013 -0500
    50.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    50.3 @@ -1,106 +0,0 @@
    50.4 -/*
    50.5 - *  Copyright (C) 2012 Copyleft Games Group
    50.6 - *  Copyright (C) 2003 Imendio AB
    50.7 - *
    50.8 - *  This program is free software; you can redistribute it and/or modify
    50.9 - *  it under the terms of the GNU Affero General Public License as published
   50.10 - *  by the Free Software Foundation, either version 3 of the License, or
   50.11 - *  (at your option) any later version.
   50.12 - *
   50.13 - *  This program is distributed in the hope that it will be useful,
   50.14 - *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   50.15 - *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   50.16 - *  GNU Affero General Public License for more details.
   50.17 - *
   50.18 - *  You should have received a copy of the GNU Affero General Public License
   50.19 - *  along with this program; if not, see http://www.gnu.org/licenses
   50.20 - *
   50.21 - */
   50.22 -
   50.23 -#include "lm-debug.h"
   50.24 -
   50.25 -#ifndef LM_NO_DEBUG
   50.26 -
   50.27 -static LmLogLevelFlags debug_flags = 0;
   50.28 -static gboolean initialized = FALSE;
   50.29 -
   50.30 -static const GDebugKey debug_keys[] = {
   50.31 -    {"VERBOSE",      LM_LOG_LEVEL_VERBOSE},
   50.32 -    {"NET",          LM_LOG_LEVEL_NET},
   50.33 -    {"PARSER",       LM_LOG_LEVEL_PARSER},
   50.34 -    {"SSL",          LM_LOG_LEVEL_SSL},
   50.35 -    {"SASL",         LM_LOG_LEVEL_SASL},
   50.36 -    {"ALL",          LM_LOG_LEVEL_ALL}
   50.37 -};
   50.38 -
   50.39 -#define NUM_DEBUG_KEYS (sizeof (debug_keys) / sizeof (GDebugKey))
   50.40 -
   50.41 -static void
   50.42 -debug_log_handler (const gchar    *log_domain,
   50.43 -                   GLogLevelFlags  log_level,
   50.44 -                   const gchar    *message,
   50.45 -                   gpointer        user_data)
   50.46 -{
   50.47 -    if (debug_flags & log_level) {
   50.48 -        if (log_level & LM_LOG_LEVEL_VERBOSE) {
   50.49 -            g_print ("*** ");
   50.50 -        }
   50.51 -        else if (log_level & LM_LOG_LEVEL_PARSER) {
   50.52 -            g_print ("LM-PARSER: ");
   50.53 -        }
   50.54 -        else if (log_level & LM_LOG_LEVEL_SASL) {
   50.55 -            g_print ("LM-SASL: ");
   50.56 -        }
   50.57 -        else if (log_level & LM_LOG_LEVEL_SSL) {
   50.58 -            g_print ("LM-SSL: ");
   50.59 -        }
   50.60 -
   50.61 -        g_print ("%s", message);
   50.62 -    }
   50.63 -}
   50.64 -
   50.65 -/**
   50.66 - * lm_debug_init
   50.67 - *
   50.68 - * Initialized the debug system.
   50.69 - **/
   50.70 -void
   50.71 -lm_debug_init (void)
   50.72 -{
   50.73 -    const gchar *env_lm_debug;
   50.74 -
   50.75 -    if (initialized) {
   50.76 -        return;
   50.77 -    }
   50.78 -
   50.79 -    env_lm_debug = g_getenv ("LM_DEBUG");
   50.80 -    if (env_lm_debug) {
   50.81 -        debug_flags = g_parse_debug_string (env_lm_debug, debug_keys,
   50.82 -                                            NUM_DEBUG_KEYS);
   50.83 -    }
   50.84 -
   50.85 -    g_log_set_handler (LM_LOG_DOMAIN, LM_LOG_LEVEL_ALL,
   50.86 -                       debug_log_handler, NULL);
   50.87 -
   50.88 -    initialized = TRUE;
   50.89 -}
   50.90 -
   50.91 -#else  /* LM_NO_DEBUG */
   50.92 -
   50.93 -static void
   50.94 -do_nothing_log_handler (const gchar    *log_domain,
   50.95 -                        GLogLevelFlags  log_level,
   50.96 -                        const gchar    *message,
   50.97 -                        gpointer        user_data)
   50.98 -{
   50.99 -}
  50.100 -
  50.101 -void
  50.102 -lm_debug_init (void)
  50.103 -{
  50.104 -    g_log_set_handler (LM_LOG_DOMAIN, LM_LOG_LEVEL_ALL,
  50.105 -                       do_nothing_log_handler, NULL);
  50.106 -}
  50.107 -
  50.108 -#endif /* LM_NO_DEBUG */
  50.109 -
    51.1 --- a/src/lm-debug.h	Wed Dec 25 20:33:47 2013 -0500
    51.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    51.3 @@ -1,74 +0,0 @@
    51.4 -/*
    51.5 - *  Copyright (C) 2012 Copyleft Games Group
    51.6 - *  Copyright (C) 2003 Imendio AB
    51.7 - *
    51.8 - *  This program is free software; you can redistribute it and/or modify
    51.9 - *  it under the terms of the GNU Affero General Public License as published
   51.10 - *  by the Free Software Foundation, either version 3 of the License, or
   51.11 - *  (at your option) any later version.
   51.12 - *
   51.13 - *  This program is distributed in the hope that it will be useful,
   51.14 - *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   51.15 - *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   51.16 - *  GNU Affero General Public License for more details.
   51.17 - *
   51.18 - *  You should have received a copy of the GNU Affero General Public License
   51.19 - *  along with this program; if not, see http://www.gnu.org/licenses
   51.20 - *
   51.21 - */
   51.22 -
   51.23 -#ifndef __LM_DEBUG_H__
   51.24 -#define __LM_DEBUG_H__
   51.25 -
   51.26 -#include <glib.h>
   51.27 -
   51.28 -typedef enum {
   51.29 -    LM_LOG_LEVEL_VERBOSE = 1 << (G_LOG_LEVEL_USER_SHIFT),
   51.30 -    LM_LOG_LEVEL_NET     = 1 << (G_LOG_LEVEL_USER_SHIFT + 1),
   51.31 -    LM_LOG_LEVEL_PARSER  = 1 << (G_LOG_LEVEL_USER_SHIFT + 2),
   51.32 -    LM_LOG_LEVEL_SSL     = 1 << (G_LOG_LEVEL_USER_SHIFT + 3),
   51.33 -    LM_LOG_LEVEL_SASL    = 1 << (G_LOG_LEVEL_USER_SHIFT + 4),
   51.34 -    LM_LOG_LEVEL_ALL     = (LM_LOG_LEVEL_NET |
   51.35 -                            LM_LOG_LEVEL_VERBOSE |
   51.36 -                            LM_LOG_LEVEL_PARSER |
   51.37 -                            LM_LOG_LEVEL_SSL |
   51.38 -                            LM_LOG_LEVEL_SASL)
   51.39 -} LmLogLevelFlags;
   51.40 -
   51.41 -#ifndef LM_LOG_DOMAIN
   51.42 -#  define LM_LOG_DOMAIN "LM"
   51.43 -#endif
   51.44 -
   51.45 -#ifdef G_HAVE_ISO_VARARGS
   51.46 -#  ifdef LM_NO_DEBUG
   51.47 -#    define lm_verbose(...)
   51.48 -#  else
   51.49 -#    define lm_verbose(...) \
   51.50 -       g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_VERBOSE, __VA_ARGS__)
   51.51 -#  endif
   51.52 -#elif defined(G_HAVE_GNUC_VARARGS)
   51.53 -#  if LM_NO_DEBUG
   51.54 -#    define lm_verbose(fmt...)
   51.55 -#  else
   51.56 -#    define lm_verbose(fmt...) \
   51.57 -       g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_VERBOSE, fmt)
   51.58 -#  endif
   51.59 -#else
   51.60 -#  if LM_NO_DEBUG
   51.61 -#    define lm_verbose(const gchar *format, ...) {};
   51.62 -#  else
   51.63 -static void
   51.64 -lm_verbose (const gchar *format, ...)
   51.65 -{
   51.66 -    va_list args;
   51.67 -    va_start (args, format);
   51.68 -    g_logv (LM_LOG_DOMAIN, LM_LOG_LEVEL_VERBOSE, format, args);
   51.69 -    va_end (args);
   51.70 -}
   51.71 -#  endif
   51.72 -#endif
   51.73 -
   51.74 -void lm_debug_init (void);
   51.75 -
   51.76 -#endif /* __LM_DEBUG_H__ */
   51.77 -
    52.1 --- a/src/lm-error.c	Wed Dec 25 20:33:47 2013 -0500
    52.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    52.3 @@ -1,40 +0,0 @@
    52.4 -/*
    52.5 - *  Copyright (C) 2012 Copyleft Games Group
    52.6 - *  Copyright (C) 2003 Imendio AB
    52.7 - *
    52.8 - *  This program is free software; you can redistribute it and/or modify
    52.9 - *  it under the terms of the GNU Affero General Public License as published
   52.10 - *  by the Free Software Foundation, either version 3 of the License, or
   52.11 - *  (at your option) any later version.
   52.12 - *
   52.13 - *  This program is distributed in the hope that it will be useful,
   52.14 - *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   52.15 - *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   52.16 - *  GNU Affero General Public License for more details.
   52.17 - *
   52.18 - *  You should have received a copy of the GNU Affero General Public License
   52.19 - *  along with this program; if not, see http://www.gnu.org/licenses
   52.20 - *
   52.21 - */
   52.22 -
   52.23 -/**
   52.24 - * SECTION:lm-error
   52.25 - * @Title: LmError
   52.26 - * @Short_description: Error reporting.
   52.27 - */
   52.28 -
   52.29 -#include <config.h>
   52.30 -#include <glib.h>
   52.31 -#include <loudmouth/lm-error.h>
   52.32 -
   52.33 -GQuark
   52.34 -lm_error_quark (void)
   52.35 -{
   52.36 -    static GQuark q = 0;
   52.37 -
   52.38 -    if (q == 0) {
   52.39 -        q = g_quark_from_static_string ("lm-error-quark");
   52.40 -    }
   52.41 -
   52.42 -    return q;
   52.43 -}
    53.1 --- a/src/lm-internals.h	Wed Dec 25 20:33:47 2013 -0500
    53.2 +++ b/src/lm-internals.h	Mon Dec 15 05:04:57 2014 +0000
    53.3 @@ -1,5 +1,5 @@
    53.4  /*
    53.5 - *  Copyright (C) 2012 Copyleft Games Group
    53.6 + *  Copyright (C) 2012,2013,2014 Copyleft Games Group
    53.7   *  Copyright (C) 2003 Imendio AB
    53.8   *
    53.9   *  This program is free software; you can redistribute it and/or modify
   53.10 @@ -26,9 +26,8 @@
   53.11  
   53.12  #include <sys/types.h>
   53.13  
   53.14 -#include <loudmouth/lm-connection.h>
   53.15 +#include <lightmelody.h>
   53.16  #include <loudmouth/lm-message.h>
   53.17 -#include <loudmouth/lm-message-handler.h>
   53.18  #include <loudmouth/lm-message-node.h>
   53.19  #include "lm-sock.h"
   53.20  #include "lm-old-socket.h"
   53.21 @@ -86,10 +85,6 @@
   53.22  gboolean         _lm_proxy_connect_cb         (GIOChannel            *source,
   53.23                                                 GIOCondition           condition,
   53.24                                                 gpointer               data);
   53.25 -LmHandlerResult
   53.26 -_lm_message_handler_handle_message            (LmMessageHandler      *handler,
   53.27 -                                               LmConnection          *conn,
   53.28 -                                               LmMessage             *messag);
   53.29  gboolean         _lm_sock_library_init        (void);
   53.30  void             _lm_sock_library_shutdown    (void);
   53.31  void             _lm_sock_set_blocking        (LmOldSocketT              sock,
    54.1 --- a/src/lm-message-handler.c	Wed Dec 25 20:33:47 2013 -0500
    54.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    54.3 @@ -1,166 +0,0 @@
    54.4 -/*
    54.5 - *  Copyright (C) 2012 Copyleft Games Group
    54.6 - *  Copyright (C) 2003 Imendio AB
    54.7 - *
    54.8 - *  This program is free software; you can redistribute it and/or modify
    54.9 - *  it under the terms of the GNU Affero General Public License as published
   54.10 - *  by the Free Software Foundation, either version 3 of the License, or
   54.11 - *  (at your option) any later version.
   54.12 - *
   54.13 - *  This program is distributed in the hope that it will be useful,
   54.14 - *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   54.15 - *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   54.16 - *  GNU Affero General Public License for more details.
   54.17 - *
   54.18 - *  You should have received a copy of the GNU Affero General Public License
   54.19 - *  along with this program; if not, see http://www.gnu.org/licenses
   54.20 - *
   54.21 - */
   54.22 -
   54.23 -/**
   54.24 - * SECTION:lm-message-handler
   54.25 - * @Title: LmMessageHandler
   54.26 - * @Short_description: A handler for incoming messages.
   54.27 - *
   54.28 - *  A handler can be registered to listen to incoming messages with lm_connection_register_message_handler(). When a message is recieved the handlers of the correct type will be called.
   54.29 - */
   54.30 -
   54.31 -#include <config.h>
   54.32 -
   54.33 -#include "lm-internals.h"
   54.34 -#include <loudmouth/lm-message-handler.h>
   54.35 -
   54.36 -struct LmMessageHandler {
   54.37 -    gboolean                valid;
   54.38 -    gint                    ref_count;
   54.39 -    LmHandleMessageFunction function;
   54.40 -    gpointer                user_data;
   54.41 -    GDestroyNotify          notify;
   54.42 -};
   54.43 -
   54.44 -LmHandlerResult
   54.45 -_lm_message_handler_handle_message (LmMessageHandler *handler,
   54.46 -                                    LmConnection     *connection,
   54.47 -                                    LmMessage        *message)
   54.48 -{
   54.49 -    g_return_val_if_fail (handler != NULL,
   54.50 -                          LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS);
   54.51 -
   54.52 -    if (!handler->valid) {
   54.53 -        return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
   54.54 -    }
   54.55 -
   54.56 -    if (handler->function) {
   54.57 -        return (* handler->function) (handler, connection,
   54.58 -                                      message, handler->user_data);
   54.59 -    }
   54.60 -
   54.61 -    return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
   54.62 -}
   54.63 -
   54.64 -/**
   54.65 - * lm_message_handler_new:
   54.66 - * @function: a callback
   54.67 - * @user_data: user data passed to function
   54.68 - * @notify: function called when the message handler is freed
   54.69 - *
   54.70 - * Creates a new message handler. This can be set to handle incoming messages
   54.71 - * and when a message of the type the handler is registered to handle is
   54.72 - * received @function will be called and @user_data will be passed to it.
   54.73 - * @notify is called when the message handler is freed, that way any memory
   54.74 - * allocated by @user_data can be freed.
   54.75 - *
   54.76 - * Return value: a newly created message handler
   54.77 - **/
   54.78 -LmMessageHandler *
   54.79 -lm_message_handler_new (LmHandleMessageFunction function,
   54.80 -                        gpointer                user_data,
   54.81 -                        GDestroyNotify          notify)
   54.82 -{
   54.83 -    LmMessageHandler *handler;
   54.84 -
   54.85 -    g_return_val_if_fail (function != NULL, NULL);
   54.86 -
   54.87 -    handler = g_new0 (LmMessageHandler, 1);
   54.88 -
   54.89 -    if (handler == NULL) {
   54.90 -        return NULL;
   54.91 -    }
   54.92 -
   54.93 -    handler->valid     = TRUE;
   54.94 -    handler->ref_count = 1;
   54.95 -    handler->function  = function;
   54.96 -    handler->user_data = user_data;
   54.97 -    handler->notify    = notify;
   54.98 -
   54.99 -    return handler;
  54.100 -}
  54.101 -
  54.102 -/**
  54.103 - * lm_message_handler_invalidate
  54.104 - * @handler: an #LmMessageHandler
  54.105 - *
  54.106 - * Invalidates the handler. Useful if you need to cancel a reply
  54.107 - **/
  54.108 -void
  54.109 -lm_message_handler_invalidate (LmMessageHandler *handler)
  54.110 -{
  54.111 -    handler->valid = FALSE;
  54.112 -}
  54.113 -
  54.114 -/**
  54.115 - * lm_message_handler_is_valid
  54.116 - * @handler: an #LmMessageHandler
  54.117 - *
  54.118 - * Fetches whether the handler is valid or not.
  54.119 - *
  54.120 - * Return value: #TRUE if @handler is valid, otherwise #FALSE
  54.121 - **/
  54.122 -gboolean
  54.123 -lm_message_handler_is_valid (LmMessageHandler *handler)
  54.124 -{
  54.125 -    g_return_val_if_fail (handler != NULL, FALSE);
  54.126 -
  54.127 -    return handler->valid;
  54.128 -}
  54.129 -
  54.130 -/**
  54.131 - * lm_message_handler_ref:
  54.132 - * @handler: an #LmMessageHandler
  54.133 - *
  54.134 - * Adds a reference to @handler.
  54.135 - *
  54.136 - * Return value: the message handler
  54.137 - **/
  54.138 -LmMessageHandler *
  54.139 -lm_message_handler_ref (LmMessageHandler *handler)
  54.140 -{
  54.141 -    g_return_val_if_fail (handler != NULL, NULL);
  54.142 -
  54.143 -    handler->ref_count++;
  54.144 -
  54.145 -    return handler;
  54.146 -}
  54.147 -
  54.148 -/**
  54.149 - * lm_message_handler_unref:
  54.150 - * @handler: an #LmMessagHandler
  54.151 - *
  54.152 - * Removes a reference from @handler. When no more references are present the
  54.153 - * handler is freed.
  54.154 - **/
  54.155 -void
  54.156 -lm_message_handler_unref (LmMessageHandler *handler)
  54.157 -{
  54.158 -    g_return_if_fail (handler != NULL);
  54.159 -
  54.160 -    handler->ref_count --;
  54.161 -
  54.162 -    if (handler->ref_count == 0) {
  54.163 -        if (handler->notify) {
  54.164 -            (* handler->notify) (handler->user_data);
  54.165 -        }
  54.166 -        g_free (handler);
  54.167 -    }
  54.168 -}
  54.169 -
    55.1 --- a/src/lm-message-node.c	Wed Dec 25 20:33:47 2013 -0500
    55.2 +++ b/src/lm-message-node.c	Mon Dec 15 05:04:57 2014 +0000
    55.3 @@ -1,5 +1,5 @@
    55.4  /*
    55.5 - *  Copyright (C) 2012 Copyleft Games Group
    55.6 + *  Copyright (C) 2012,2013,2014 Copyleft Games Group
    55.7   *  Copyright (C) 2003 Imendio AB
    55.8   *
    55.9   *  This program is free software; you can redistribute it and/or modify
    56.1 --- a/src/lm-message.c	Wed Dec 25 20:33:47 2013 -0500
    56.2 +++ b/src/lm-message.c	Mon Dec 15 05:04:57 2014 +0000
    56.3 @@ -1,5 +1,5 @@
    56.4  /*
    56.5 - *  Copyright (C) 2012 Copyleft Games Group
    56.6 + *  Copyright (C) 2012,2013,2014 Copyleft Games Group
    56.7   *  Copyright (C) 2003 Imendio AB
    56.8   *
    56.9   *  This program is free software; you can redistribute it and/or modify
    57.1 --- a/src/lm-misc.c	Wed Dec 25 20:33:47 2013 -0500
    57.2 +++ b/src/lm-misc.c	Mon Dec 15 05:04:57 2014 +0000
    57.3 @@ -1,5 +1,5 @@
    57.4  /*
    57.5 - *  Copyright (C) 2012 Copyleft Games Group
    57.6 + *  Copyright (C) 2012,2013,2014 Copyleft Games Group
    57.7   *  Copyright (C) 2006 Imendio AB
    57.8   *
    57.9   *  This program is free software; you can redistribute it and/or modify
    58.1 --- a/src/lm-misc.h	Wed Dec 25 20:33:47 2013 -0500
    58.2 +++ b/src/lm-misc.h	Mon Dec 15 05:04:57 2014 +0000
    58.3 @@ -1,5 +1,5 @@
    58.4  /*
    58.5 - *  Copyright (C) 2012 Copyleft Games Group
    58.6 + *  Copyright (C) 2012,2013,2014 Copyleft Games Group
    58.7   *  Copyright (C) 2006 Imendio AB
    58.8   *
    58.9   *  This program is free software; you can redistribute it and/or modify
    59.1 --- a/src/lm-old-socket.c	Wed Dec 25 20:33:47 2013 -0500
    59.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    59.3 @@ -1,1086 +0,0 @@
    59.4 -/*
    59.5 - *  Copyright (C) 2012 Copyleft Games Group
    59.6 - *  Copyright (C) 2006-2008 Imendio AB
    59.7 - *  Copyright (C) 2007 Collabora Ltd.
    59.8 - *  Copyright (C) 2006 Nokia Corporation
    59.9 - *
   59.10 - *  This program is free software; you can redistribute it and/or modify
   59.11 - *  it under the terms of the GNU Affero General Public License as published
   59.12 - *  by the Free Software Foundation, either version 3 of the License, or
   59.13 - *  (at your option) any later version.
   59.14 - *
   59.15 - *  This program is distributed in the hope that it will be useful,
   59.16 - *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   59.17 - *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   59.18 - *  GNU Affero General Public License for more details.
   59.19 - *
   59.20 - *  You should have received a copy of the GNU Affero General Public License
   59.21 - *  along with this program; if not, see http://www.gnu.org/licenses
   59.22 - *
   59.23 - */
   59.24 -
   59.25 -#include <config.h>
   59.26 -
   59.27 -#include <string.h>
   59.28 -#include <sys/types.h>
   59.29 -
   59.30 -/* Needed on Mac OS X */
   59.31 -#if HAVE_NETINET_IN_H
   59.32 -#include <netinet/in.h>
   59.33 -#endif
   59.34 -
   59.35 -/* Needed on Mac OS X */
   59.36 -#if HAVE_ARPA_NAMESER_COMPAT_H
   59.37 -#include <arpa/nameser_compat.h>
   59.38 -#endif
   59.39 -
   59.40 -#include <arpa/inet.h>
   59.41 -#include <arpa/nameser.h>
   59.42 -#include <resolv.h>
   59.43 -
   59.44 -#include "lm-debug.h"
   59.45 -#include <loudmouth/lm-error.h>
   59.46 -#include "lm-internals.h"
   59.47 -#include "lm-misc.h"
   59.48 -#include <loudmouth/lm-proxy.h>
   59.49 -#include "lm-resolver.h"
   59.50 -#include <loudmouth/lm-ssl.h>
   59.51 -#include "lm-ssl-internals.h"
   59.52 -#include "lm-sock.h"
   59.53 -#include "lm-old-socket.h"
   59.54 -
   59.55 -#define IN_BUFFER_SIZE 1024
   59.56 -#define SRV_LEN 8192
   59.57 -
   59.58 -struct _LmOldSocket {
   59.59 -    LmConnection      *connection;
   59.60 -    GMainContext      *context;
   59.61 -
   59.62 -    gchar             *domain;
   59.63 -    gchar             *server;
   59.64 -    guint              port;
   59.65 -
   59.66 -    LmSSL             *ssl;
   59.67 -    gboolean           ssl_started;
   59.68 -    LmProxy           *proxy;
   59.69 -
   59.70 -    GIOChannel        *io_channel;
   59.71 -    GSource           *watch_in;
   59.72 -    GSource           *watch_err;
   59.73 -    GSource           *watch_hup;
   59.74 -
   59.75 -    LmOldSocketT       fd;
   59.76 -
   59.77 -    GSource           *watch_connect;
   59.78 -
   59.79 -    gboolean           cancel_open;
   59.80 -
   59.81 -    GSource           *watch_out;
   59.82 -    GString           *out_buf;
   59.83 -
   59.84 -    LmConnectData     *connect_data;
   59.85 -
   59.86 -    IncomingDataFunc   data_func;
   59.87 -    SocketClosedFunc   closed_func;
   59.88 -    ConnectResultFunc  connect_func;
   59.89 -    gpointer           user_data;
   59.90 -
   59.91 -    guint              ref_count;
   59.92 -
   59.93 -    LmResolver        *resolver;
   59.94 -};
   59.95 -
   59.96 -static void         socket_free                    (LmOldSocket    *socket);
   59.97 -static gboolean     socket_do_connect              (LmConnectData  *connect_data);
   59.98 -static gboolean     socket_connect_cb              (GIOChannel     *source,
   59.99 -                                                    GIOCondition    condition,
  59.100 -                                                    LmConnectData  *connect_data);
  59.101 -static gboolean     socket_in_event                (GIOChannel     *source,
  59.102 -                                                    GIOCondition    condition,
  59.103 -                                                    LmOldSocket    *socket);
  59.104 -static gboolean     socket_hup_event               (GIOChannel     *source,
  59.105 -                                                    GIOCondition    condition,
  59.106 -                                                    LmOldSocket    *socket);
  59.107 -static gboolean     socket_error_event             (GIOChannel     *source,
  59.108 -                                                    GIOCondition    condition,
  59.109 -                                                    LmOldSocket    *socket);
  59.110 -static gboolean     socket_buffered_write_cb       (GIOChannel     *source,
  59.111 -                                                    GIOCondition    condition,
  59.112 -                                                    LmOldSocket    *socket);
  59.113 -static void         socket_close_io_channel        (GIOChannel     *io_channel);
  59.114 -static gboolean     old_socket_output_is_buffered  (LmOldSocket    *socket,
  59.115 -                                                    const gchar    *buffer,
  59.116 -                                                    gint            len);
  59.117 -static void         old_socket_setup_output_buffer (LmOldSocket    *socket,
  59.118 -                                                    const gchar    *buffer,
  59.119 -                                                    gint            len);
  59.120 -
  59.121 -static void
  59.122 -socket_free (LmOldSocket *socket)
  59.123 -{
  59.124 -    g_free (socket->server);
  59.125 -    g_free (socket->domain);
  59.126 -
  59.127 -    if (socket->ssl) {
  59.128 -        lm_ssl_unref (socket->ssl);
  59.129 -    }
  59.130 -
  59.131 -    if (socket->proxy) {
  59.132 -        lm_proxy_unref (socket->proxy);
  59.133 -    }
  59.134 -
  59.135 -    if (socket->out_buf) {
  59.136 -        g_string_free (socket->out_buf, TRUE);
  59.137 -    }
  59.138 -
  59.139 -    if (socket->resolver) {
  59.140 -        g_object_unref (socket->resolver);
  59.141 -    }
  59.142 -
  59.143 -    g_free (socket);
  59.144 -}
  59.145 -
  59.146 -static gint
  59.147 -old_socket_do_write (LmOldSocket *socket, const gchar *buf, guint len)
  59.148 -{
  59.149 -    gint b_written;
  59.150 -
  59.151 -    if (socket->ssl_started) {
  59.152 -        b_written = _lm_ssl_send (socket->ssl, buf, len);
  59.153 -    } else {
  59.154 -        GIOStatus io_status = G_IO_STATUS_AGAIN;
  59.155 -        gsize     bytes_written;
  59.156 -
  59.157 -        while (io_status == G_IO_STATUS_AGAIN) {
  59.158 -            io_status = g_io_channel_write_chars (socket->io_channel,
  59.159 -                                                  buf, len,
  59.160 -                                                  &bytes_written,
  59.161 -                                                  NULL);
  59.162 -        }
  59.163 -
  59.164 -        b_written = bytes_written;
  59.165 -
  59.166 -        if (io_status != G_IO_STATUS_NORMAL) {
  59.167 -            b_written = -1;
  59.168 -        }
  59.169 -    }
  59.170 -
  59.171 -    return b_written;
  59.172 -}
  59.173 -
  59.174 -gint
  59.175 -lm_old_socket_write (LmOldSocket *socket, const gchar *buf, gint len)
  59.176 -{
  59.177 -    gint b_written;
  59.178 -
  59.179 -    if (old_socket_output_is_buffered (socket, buf, len)) {
  59.180 -        return len;
  59.181 -    }
  59.182 -
  59.183 -    b_written = old_socket_do_write (socket, buf, len);
  59.184 -
  59.185 -    if (b_written < len && b_written != -1) {
  59.186 -        old_socket_setup_output_buffer (socket,
  59.187 -                                        buf + b_written,
  59.188 -                                        len - b_written);
  59.189 -        return len;
  59.190 -    }
  59.191 -
  59.192 -    return b_written;
  59.193 -}
  59.194 -
  59.195 -static gboolean
  59.196 -socket_read_incoming (LmOldSocket *socket,
  59.197 -                      gchar    *buf,
  59.198 -                      gsize     buf_size,
  59.199 -                      gsize    *bytes_read,
  59.200 -                      gboolean *hangup,
  59.201 -                      gint     *reason)
  59.202 -{
  59.203 -    GIOStatus status;
  59.204 -
  59.205 -    *hangup = FALSE;
  59.206 -
  59.207 -    if (socket->ssl_started) {
  59.208 -        status = _lm_ssl_read (socket->ssl,
  59.209 -                               buf, buf_size - 1, bytes_read);
  59.210 -    } else {
  59.211 -        status = g_io_channel_read_chars (socket->io_channel,
  59.212 -                                          buf, buf_size - 1,
  59.213 -                                          bytes_read,
  59.214 -                                          NULL);
  59.215 -    }
  59.216 -
  59.217 -    if (status != G_IO_STATUS_NORMAL || *bytes_read < 0) {
  59.218 -        switch (status) {
  59.219 -        case G_IO_STATUS_EOF:
  59.220 -            *reason = LM_DISCONNECT_REASON_HUP;
  59.221 -            break;
  59.222 -        case G_IO_STATUS_AGAIN:
  59.223 -            /* No data readable but we didn't hangup */
  59.224 -            return FALSE;
  59.225 -            break;
  59.226 -        case G_IO_STATUS_ERROR:
  59.227 -            *reason = LM_DISCONNECT_REASON_ERROR;
  59.228 -            break;
  59.229 -        default:
  59.230 -            *reason = LM_DISCONNECT_REASON_UNKNOWN;
  59.231 -        }
  59.232 -
  59.233 -        /* Notify connection_in_event that we hangup the connection */
  59.234 -        *hangup = TRUE;
  59.235 -
  59.236 -        return FALSE;
  59.237 -    }
  59.238 -
  59.239 -    buf[*bytes_read] = '\0';
  59.240 -
  59.241 -    /* There is more data to be read */
  59.242 -    return TRUE;
  59.243 -}
  59.244 -
  59.245 -static gboolean
  59.246 -socket_in_event (GIOChannel   *source,
  59.247 -                 GIOCondition  condition,
  59.248 -                 LmOldSocket     *socket)
  59.249 -{
  59.250 -    gchar    buf[IN_BUFFER_SIZE];
  59.251 -    gsize    bytes_read = 0;
  59.252 -    gboolean read_anything = FALSE;
  59.253 -    gboolean hangup = 0;
  59.254 -    gint     reason = 0;
  59.255 -
  59.256 -    if (!socket->io_channel) {
  59.257 -        return FALSE;
  59.258 -    }
  59.259 -
  59.260 -    while (socket_read_incoming (socket, buf, IN_BUFFER_SIZE,
  59.261 -                                 &bytes_read, &hangup, &reason)) {
  59.262 -
  59.263 -        g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_NET, "\nRECV [%d]:\n",
  59.264 -               (int)bytes_read);
  59.265 -        g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_NET,
  59.266 -               "-----------------------------------\n");
  59.267 -        g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_NET, "'%s'\n", buf);
  59.268 -        g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_NET,
  59.269 -               "-----------------------------------\n");
  59.270 -
  59.271 -        lm_verbose ("Read: %d chars\n", (int)bytes_read);
  59.272 -
  59.273 -        (socket->data_func) (socket, buf, socket->user_data);
  59.274 -
  59.275 -        read_anything = TRUE;
  59.276 -    }
  59.277 -
  59.278 -    /* If we have read something, delay the hangup so that the data can be
  59.279 -     * processed. */
  59.280 -    if (hangup && !read_anything) {
  59.281 -        (socket->closed_func) (socket, reason, socket->user_data);
  59.282 -        return FALSE;
  59.283 -    }
  59.284 -
  59.285 -    return TRUE;
  59.286 -}
  59.287 -
  59.288 -static const char *
  59.289 -socket_io_condition_to_str  (GIOCondition condition)
  59.290 -{
  59.291 -    static char buf[256];
  59.292 -
  59.293 -    buf[0] = '\0';
  59.294 -
  59.295 -    if(condition & G_IO_ERR)
  59.296 -        strcat(buf, "G_IO_ERR ");
  59.297 -    if(condition & G_IO_HUP)
  59.298 -        strcat(buf, "G_IO_HUP ");
  59.299 -    if(condition & G_IO_NVAL)
  59.300 -        strcat(buf, "G_IO_NVAL ");
  59.301 -    if(condition & G_IO_IN)
  59.302 -        strcat(buf, "G_IO_IN ");
  59.303 -    if(condition & G_IO_OUT)
  59.304 -        strcat(buf, "G_IO_OUT ");
  59.305 -
  59.306 -    return buf;
  59.307 -}
  59.308 -
  59.309 -static gboolean
  59.310 -socket_hup_event (GIOChannel   *source,
  59.311 -                  GIOCondition  condition,
  59.312 -                  LmOldSocket     *socket)
  59.313 -{
  59.314 -    lm_verbose ("HUP event: %d->'%s'\n",
  59.315 -                condition, socket_io_condition_to_str (condition));
  59.316 -
  59.317 -    if (!socket->io_channel) {
  59.318 -        return FALSE;
  59.319 -    }
  59.320 -
  59.321 -    (socket->closed_func) (socket, LM_DISCONNECT_REASON_HUP,
  59.322 -                           socket->user_data);
  59.323 -
  59.324 -    return TRUE;
  59.325 -}
  59.326 -
  59.327 -static gboolean
  59.328 -socket_error_event (GIOChannel   *source,
  59.329 -                    GIOCondition  condition,
  59.330 -                    LmOldSocket     *socket)
  59.331 -{
  59.332 -    lm_verbose ("ERROR event: %d->'%s'\n",
  59.333 -                condition, socket_io_condition_to_str (condition));
  59.334 -
  59.335 -    if (!socket->io_channel) {
  59.336 -        return FALSE;
  59.337 -    }
  59.338 -
  59.339 -    (socket->closed_func) (socket, LM_DISCONNECT_REASON_ERROR,
  59.340 -                           socket->user_data);
  59.341 -
  59.342 -    return TRUE;
  59.343 -}
  59.344 -
  59.345 -static gboolean
  59.346 -_lm_old_socket_ssl_init (LmOldSocket *socket, gboolean delayed)
  59.347 -{
  59.348 -    GError *error = NULL;
  59.349 -    const gchar *ssl_verify_domain = NULL;
  59.350 -
  59.351 -    lm_verbose ("Setting up SSL...\n");
  59.352 -
  59.353 -    _lm_ssl_initialize (socket->ssl);
  59.354 -
  59.355 -#ifdef HAVE_GNUTLS
  59.356 -    /* GNU TLS requires the socket to be blocking */
  59.357 -    _lm_sock_set_blocking (socket->fd, TRUE);
  59.358 -#endif
  59.359 -
  59.360 -    /* If we're using StartTLS, the correct thing is to verify against
  59.361 -     * the domain. If we're using old SSL, we should verify against the
  59.362 -     * hostname. */
  59.363 -    if (delayed)
  59.364 -        ssl_verify_domain = socket->domain;
  59.365 -    else
  59.366 -        ssl_verify_domain = socket->server;
  59.367 -
  59.368 -    if (!_lm_ssl_begin (socket->ssl, socket->fd, ssl_verify_domain, &error)) {
  59.369 -        lm_verbose ("Could not begin SSL\n");
  59.370 -
  59.371 -        if (error) {
  59.372 -            g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_NET,
  59.373 -                   "%s\n", error->message);
  59.374 -            g_error_free (error);
  59.375 -        }
  59.376 -
  59.377 -        _lm_sock_shutdown (socket->fd);
  59.378 -        _lm_sock_close (socket->fd);
  59.379 -
  59.380 -        if (!delayed && socket->connect_func) {
  59.381 -            (socket->connect_func) (socket, FALSE, socket->user_data);
  59.382 -        }
  59.383 -
  59.384 -        return FALSE;
  59.385 -    }
  59.386 -
  59.387 -#ifdef HAVE_GNUTLS
  59.388 -    _lm_sock_set_blocking (socket->fd, FALSE);
  59.389 -#endif
  59.390 -
  59.391 -    socket->ssl_started = TRUE;
  59.392 -
  59.393 -    return TRUE;
  59.394 -}
  59.395 -
  59.396 -gboolean
  59.397 -lm_old_socket_starttls (LmOldSocket *socket)
  59.398 -{
  59.399 -    g_return_val_if_fail (lm_ssl_get_use_starttls (socket->ssl) == TRUE, FALSE);
  59.400 -
  59.401 -    return _lm_old_socket_ssl_init (socket, TRUE);
  59.402 -}
  59.403 -
  59.404 -
  59.405 -
  59.406 -void
  59.407 -_lm_old_socket_succeeded (LmConnectData *connect_data)
  59.408 -{
  59.409 -    LmOldSocket *socket;
  59.410 -
  59.411 -    socket = connect_data->socket;
  59.412 -
  59.413 -    if (socket->watch_connect) {
  59.414 -        g_source_destroy (socket->watch_connect);
  59.415 -        socket->watch_connect = NULL;
  59.416 -    }
  59.417 -
  59.418 -    /* Need some way to report error/success */
  59.419 -    if (socket->cancel_open) {
  59.420 -        lm_verbose ("Cancelling connection...\n");
  59.421 -        if (socket->connect_func) {
  59.422 -            (socket->connect_func) (socket, FALSE, socket->user_data);
  59.423 -        }
  59.424 -        return;
  59.425 -    }
  59.426 -
  59.427 -    socket->fd = connect_data->fd;
  59.428 -    socket->io_channel = connect_data->io_channel;
  59.429 -
  59.430 -    g_object_unref (socket->resolver);
  59.431 -    socket->resolver = NULL;
  59.432 -
  59.433 -    socket->connect_data = NULL;
  59.434 -    g_free (connect_data);
  59.435 -
  59.436 -    /* old-style ssl should be started immediately */
  59.437 -    if (socket->ssl && (lm_ssl_get_use_starttls (socket->ssl) == FALSE)) {
  59.438 -        if (!_lm_old_socket_ssl_init (socket, FALSE)) {
  59.439 -            return;
  59.440 -        }
  59.441 -    }
  59.442 -
  59.443 -    socket->watch_in =
  59.444 -        lm_misc_add_io_watch (socket->context,
  59.445 -                              socket->io_channel,
  59.446 -                              G_IO_IN,
  59.447 -                              (GIOFunc) socket_in_event,
  59.448 -                              socket);
  59.449 -
  59.450 -    /* FIXME: if we add these, we don't get ANY
  59.451 -     * response from the server, this is to do with the way that
  59.452 -     * windows handles watches, see bug #331214.
  59.453 -     */
  59.454 -#ifndef G_OS_WIN32
  59.455 -    socket->watch_err =
  59.456 -        lm_misc_add_io_watch (socket->context,
  59.457 -                              socket->io_channel,
  59.458 -                              G_IO_ERR,
  59.459 -                              (GIOFunc) socket_error_event,
  59.460 -                              socket);
  59.461 -
  59.462 -    socket->watch_hup =
  59.463 -        lm_misc_add_io_watch (socket->context,
  59.464 -                              socket->io_channel,
  59.465 -                              G_IO_HUP,
  59.466 -                              (GIOFunc) socket_hup_event,
  59.467 -                              socket);
  59.468 -#endif
  59.469 -
  59.470 -    if (socket->connect_func) {
  59.471 -        (socket->connect_func) (socket, TRUE, socket->user_data);
  59.472 -    }
  59.473 -}
  59.474 -
  59.475 -gboolean
  59.476 -_lm_old_socket_failed_with_error (LmConnectData *connect_data, int error)
  59.477 -{
  59.478 -    LmOldSocket *socket;
  59.479 -
  59.480 -    g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_NET,
  59.481 -           "Connection failed: %s (error %d)\n",
  59.482 -           _lm_sock_get_error_str (error), error);
  59.483 -
  59.484 -    socket = lm_old_socket_ref (connect_data->socket);
  59.485 -
  59.486 -    connect_data->current_addr = lm_resolver_results_get_next (socket->resolver);
  59.487 -
  59.488 -    if (socket->watch_connect) {
  59.489 -        g_source_destroy (socket->watch_connect);
  59.490 -        socket->watch_connect = NULL;
  59.491 -    }
  59.492 -
  59.493 -    if (connect_data->io_channel != NULL) {
  59.494 -        socket_close_io_channel (connect_data->io_channel);
  59.495 -        connect_data->io_channel = NULL;
  59.496 -    }
  59.497 -
  59.498 -    if (connect_data->current_addr == NULL) { /*Ran Out Of Addresses*/
  59.499 -        if (socket->connect_func) {
  59.500 -            (socket->connect_func) (socket, FALSE, socket->user_data);
  59.501 -        }
  59.502 -
  59.503 -        /* if the user callback called connection_close(), this is already freed */
  59.504 -        if (socket->connect_data != NULL) {
  59.505 -            if (socket->resolver) {
  59.506 -                g_object_unref (socket->resolver);
  59.507 -            }
  59.508 -
  59.509 -            socket->connect_data = NULL;
  59.510 -            g_free (connect_data);
  59.511 -        }
  59.512 -    } else {
  59.513 -        /* try to connect to the next host */
  59.514 -        return socket_do_connect (connect_data);
  59.515 -    }
  59.516 -
  59.517 -    lm_old_socket_unref (socket);
  59.518 -
  59.519 -    return FALSE;
  59.520 -}
  59.521 -
  59.522 -gboolean
  59.523 -_lm_old_socket_failed (LmConnectData *connect_data)
  59.524 -{
  59.525 -    return _lm_old_socket_failed_with_error (connect_data,
  59.526 -                                             _lm_sock_get_last_error());
  59.527 -}
  59.528 -
  59.529 -static gboolean
  59.530 -socket_connect_cb (GIOChannel   *source,
  59.531 -                   GIOCondition  condition,
  59.532 -                   LmConnectData *connect_data)
  59.533 -{
  59.534 -    LmOldSocket     *socket;
  59.535 -    /* struct addrinfo *addr; */
  59.536 -    int              err;
  59.537 -    socklen_t        len;
  59.538 -    LmOldSocketT     fd;
  59.539 -    gboolean         result = FALSE;
  59.540 -
  59.541 -    socket = lm_old_socket_ref (connect_data->socket);
  59.542 -    /* addr = connect_data->current_addr; */
  59.543 -    fd = g_io_channel_unix_get_fd (source);
  59.544 -
  59.545 -    if (condition == G_IO_ERR) {
  59.546 -        len = sizeof (err);
  59.547 -        _lm_sock_get_error (fd, &err, &len);
  59.548 -        if (!_lm_sock_is_blocking_error (err)) {
  59.549 -            g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_VERBOSE,
  59.550 -                   "Connection failed.\n");
  59.551 -
  59.552 -            /* error condition, but might be possible to recover
  59.553 -             * from it (by connecting to the next host) */
  59.554 -            if (!_lm_old_socket_failed_with_error (connect_data, err)) {
  59.555 -                socket->watch_connect = NULL;
  59.556 -                goto out;
  59.557 -            }
  59.558 -        }
  59.559 -    }
  59.560 -
  59.561 -#if 0
  59.562 -    if (_lm_connection_async_connect_waiting (socket->connection)) {
  59.563 -        gint res;
  59.564 -
  59.565 -        fd = g_io_channel_unix_get_fd (source);
  59.566 -
  59.567 -        res = _lm_sock_connect (fd, addr->ai_addr, (int)addr->ai_addrlen);
  59.568 -        if (res < 0) {
  59.569 -            err = _lm_sock_get_last_error ();
  59.570 -            if (_lm_sock_is_blocking_success (err)) {
  59.571 -                _lm_connection_set_async_connect_waiting (socket->connection, FALSE);
  59.572 -
  59.573 -                g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_NET,
  59.574 -                       "Connection success (1).\n");
  59.575 -
  59.576 -                _lm_old_socket_succeeded (connect_data);
  59.577 -            }
  59.578 -
  59.579 -            if (_lm_connection_async_connect_waiting (socket->connection) &&
  59.580 -                !_lm_sock_is_blocking_error (err)) {
  59.581 -                g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_NET,
  59.582 -                       "Connection failed.\n");
  59.583 -
  59.584 -                _lm_sock_close (connect_data->fd);
  59.585 -                _lm_old_socket_failed_with_error (connect_data, err);
  59.586 -
  59.587 -                socket->watch_connect = NULL;
  59.588 -                goto out;
  59.589 -            }
  59.590 -        }
  59.591 -    } else {
  59.592 -#endif
  59.593 -    {
  59.594 -        /* for blocking sockets, G_IO_OUT means we are connected */
  59.595 -        g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_VERBOSE,
  59.596 -               "Connection success (2).\n");
  59.597 -
  59.598 -        _lm_old_socket_succeeded (connect_data);
  59.599 -    }
  59.600 -
  59.601 -    result = TRUE;
  59.602 -
  59.603 - out:
  59.604 -    lm_old_socket_unref(socket);
  59.605 -
  59.606 -    return result;
  59.607 -}
  59.608 -
  59.609 -static gboolean
  59.610 -socket_do_connect (LmConnectData *connect_data)
  59.611 -{
  59.612 -    LmOldSocket     *socket;
  59.613 -    LmOldSocketT     fd;
  59.614 -    int              res, err;
  59.615 -    int              port;
  59.616 -    char             name[NI_MAXHOST];
  59.617 -    char             portname[NI_MAXSERV];
  59.618 -    struct addrinfo *addr;
  59.619 -
  59.620 -    socket = connect_data->socket;
  59.621 -    addr = connect_data->current_addr;
  59.622 -
  59.623 -    if (socket->port == 0) {
  59.624 -        socket->port = 5222;
  59.625 -    }
  59.626 -
  59.627 -    if (socket->proxy) {
  59.628 -        port = htons (lm_proxy_get_port (socket->proxy));
  59.629 -    } else {
  59.630 -        port = htons (socket->port);
  59.631 -    }
  59.632 -
  59.633 -    ((struct sockaddr_in *) addr->ai_addr)->sin_port = port;
  59.634 -
  59.635 -    res = getnameinfo (addr->ai_addr,
  59.636 -                       (socklen_t)addr->ai_addrlen,
  59.637 -                       name,     sizeof (name),
  59.638 -                       portname, sizeof (portname),
  59.639 -                       NI_NUMERICHOST | NI_NUMERICSERV);
  59.640 -
  59.641 -    if (res < 0) {
  59.642 -        return _lm_old_socket_failed (connect_data);
  59.643 -    }
  59.644 -
  59.645 -    g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_NET,
  59.646 -           "Trying %s port %s...\n", name, portname);
  59.647 -
  59.648 -    fd = _lm_sock_makesocket (addr->ai_family,
  59.649 -                              addr->ai_socktype,
  59.650 -                              addr->ai_protocol);
  59.651 -
  59.652 -    if (!_LM_SOCK_VALID (fd)) {
  59.653 -        g_print("invalid fd\n");
  59.654 -        g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_NET,
  59.655 -               "Failed making socket, error:%d...\n",
  59.656 -               _lm_sock_get_last_error ());
  59.657 -
  59.658 -        return _lm_old_socket_failed (connect_data);
  59.659 -    }
  59.660 -
  59.661 -    /* Even though it says _unix_new(), it is supported by glib on
  59.662 -     * win32 because glib does some cool stuff to find out if it
  59.663 -     * can treat it as a FD or a windows SOCKET.
  59.664 -     */
  59.665 -    connect_data->fd = fd;
  59.666 -    connect_data->io_channel = g_io_channel_unix_new (fd);
  59.667 -
  59.668 -    g_io_channel_set_encoding (connect_data->io_channel, NULL, NULL);
  59.669 -    g_io_channel_set_buffered (connect_data->io_channel, FALSE);
  59.670 -
  59.671 -    _lm_sock_set_blocking (connect_data->fd, FALSE);
  59.672 -
  59.673 -    if (socket->proxy) {
  59.674 -        socket->watch_connect =
  59.675 -            lm_misc_add_io_watch (socket->context,
  59.676 -                                  connect_data->io_channel,
  59.677 -                                  G_IO_OUT|G_IO_ERR,
  59.678 -                                  (GIOFunc) _lm_proxy_connect_cb,
  59.679 -                                  connect_data);
  59.680 -    } else {
  59.681 -        socket->watch_connect =
  59.682 -            lm_misc_add_io_watch (socket->context,
  59.683 -                                  connect_data->io_channel,
  59.684 -                                  G_IO_OUT|G_IO_ERR,
  59.685 -                                  (GIOFunc) socket_connect_cb,
  59.686 -                                  connect_data);
  59.687 -    }
  59.688 -
  59.689 -    res = _lm_sock_connect (connect_data->fd,
  59.690 -                            addr->ai_addr, (int)addr->ai_addrlen);
  59.691 -    if (res < 0) {
  59.692 -        err = _lm_sock_get_last_error ();
  59.693 -        if (!_lm_sock_is_blocking_error (err)) {
  59.694 -            _lm_sock_close (connect_data->fd);
  59.695 -            g_print("unable to connect\n");
  59.696 -            return _lm_old_socket_failed_with_error (connect_data, err);
  59.697 -        }
  59.698 -    }
  59.699 -
  59.700 -    return TRUE;
  59.701 -}
  59.702 -
  59.703 -static gboolean
  59.704 -old_socket_output_is_buffered (LmOldSocket     *socket,
  59.705 -                               const gchar  *buffer,
  59.706 -                               gint          len)
  59.707 -{
  59.708 -    if (socket->out_buf) {
  59.709 -        lm_verbose ("Appending %d bytes to output buffer\n", len);
  59.710 -        g_string_append_len (socket->out_buf, buffer, len);
  59.711 -        return TRUE;
  59.712 -    }
  59.713 -
  59.714 -    return FALSE;
  59.715 -}
  59.716 -
  59.717 -static void
  59.718 -old_socket_setup_output_buffer (LmOldSocket *socket, const gchar *buffer, gint len)
  59.719 -{
  59.720 -    lm_verbose ("OUTPUT BUFFER ENABLED\n");
  59.721 -
  59.722 -    socket->out_buf = g_string_new_len (buffer, len);
  59.723 -
  59.724 -    socket->watch_out =
  59.725 -        lm_misc_add_io_watch (socket->context,
  59.726 -                              socket->io_channel,
  59.727 -                              G_IO_OUT,
  59.728 -                              (GIOFunc) socket_buffered_write_cb,
  59.729 -                              socket);
  59.730 -}
  59.731 -
  59.732 -static gboolean
  59.733 -socket_buffered_write_cb (GIOChannel   *source,
  59.734 -                          GIOCondition  condition,
  59.735 -                          LmOldSocket     *socket)
  59.736 -{
  59.737 -    gint     b_written;
  59.738 -    GString *out_buf;
  59.739 -
  59.740 -    out_buf = socket->out_buf;
  59.741 -    if (!out_buf) {
  59.742 -        /* Should not be possible */
  59.743 -        return FALSE;
  59.744 -    }
  59.745 -
  59.746 -    b_written = old_socket_do_write (socket, out_buf->str, out_buf->len);
  59.747 -
  59.748 -    if (b_written < 0) {
  59.749 -        (socket->closed_func) (socket, LM_DISCONNECT_REASON_ERROR,
  59.750 -                               socket->user_data);
  59.751 -        return FALSE;
  59.752 -    }
  59.753 -
  59.754 -    g_string_erase (out_buf, 0, (gsize) b_written);
  59.755 -    if (out_buf->len == 0) {
  59.756 -        lm_verbose ("Output buffer is empty, going back to normal output\n");
  59.757 -
  59.758 -        if (socket->watch_out) {
  59.759 -            g_source_destroy (socket->watch_out);
  59.760 -            socket->watch_out = NULL;
  59.761 -        }
  59.762 -
  59.763 -        g_string_free (out_buf, TRUE);
  59.764 -        socket->out_buf = NULL;
  59.765 -        return FALSE;
  59.766 -    }
  59.767 -
  59.768 -    return TRUE;
  59.769 -}
  59.770 -
  59.771 -static void
  59.772 -socket_close_io_channel (GIOChannel *io_channel)
  59.773 -{
  59.774 -    gint fd;
  59.775 -
  59.776 -    g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_NET,
  59.777 -           "Freeing up IOChannel and file descriptor\n");
  59.778 -
  59.779 -    fd = g_io_channel_unix_get_fd (io_channel);
  59.780 -
  59.781 -    g_io_channel_unref (io_channel);
  59.782 -
  59.783 -    _lm_sock_close (fd);
  59.784 -}
  59.785 -
  59.786 -static void
  59.787 -old_socket_resolver_host_cb (LmResolver       *resolver,
  59.788 -                             LmResolverResult  result,
  59.789 -                             gpointer          user_data)
  59.790 -{
  59.791 -    LmOldSocket *socket = (LmOldSocket *) user_data;
  59.792 -    char dispbuf[128];
  59.793 -    struct sockaddr_in *addr; /* FIXME:IPv6 */
  59.794 -    const char *converr;
  59.795 -
  59.796 -    lm_verbose ("LmOldSocket::host_cb (result=%d)\n", result);
  59.797 -
  59.798 -    if (result != LM_RESOLVER_RESULT_OK) {
  59.799 -        lm_verbose ("error while resolving, bailing out\n");
  59.800 -        if (socket->connect_func) {
  59.801 -            (socket->connect_func) (socket, FALSE, socket->user_data);
  59.802 -        }
  59.803 -        /*FIXME: Leaking Resolvers Until Clean Up Can Be Properly Handled
  59.804 -        g_object_unref (socket->resolver);
  59.805 -        socket->resolver = NULL;*/
  59.806 -        g_free (socket->connect_data);
  59.807 -        socket->connect_data = NULL;
  59.808 -
  59.809 -        return;
  59.810 -    }
  59.811 -
  59.812 -    socket->connect_data->current_addr =
  59.813 -        lm_resolver_results_get_next (resolver);
  59.814 -
  59.815 -    if (socket->connect_data->current_addr) { /* FIXME:IPv6 */
  59.816 -        addr = (struct sockaddr_in *) (socket->connect_data->current_addr->ai_addr);
  59.817 -        converr = inet_ntop(AF_INET,&(addr->sin_addr),dispbuf,sizeof(dispbuf));
  59.818 -        if (converr) {
  59.819 -            g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_VERBOSE,
  59.820 -                   "Attempting Connection to %s\n",dispbuf);
  59.821 -        } else {
  59.822 -            g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_VERBOSE,
  59.823 -                   "Attempting Connection (unable to convert address to presentable format)\n");
  59.824 -        };
  59.825 -        socket_do_connect (socket->connect_data);
  59.826 -    } else { /* FIXME: IPv6 Support? */
  59.827 -        g_log (LM_LOG_DOMAIN,G_LOG_LEVEL_ERROR,
  59.828 -               "Unable to locate server available over IPv4.\n");
  59.829 -    };
  59.830 -
  59.831 -    /* FIXME: What do we do here?  How to make the mainloop exit with an
  59.832 -       error, while having no ref to said mainloop */
  59.833 -}
  59.834 -
  59.835 -/* FIXME: Need to have a way to only get srv reply and then decide if the
  59.836 - *        resolver should continue to look the host up.
  59.837 - *
  59.838 - *        This is needed for the case when we do a SRV lookup to lookup the
  59.839 - *        real host of the service and then connect to it through a proxy.
  59.840 - */
  59.841 -static void
  59.842 -old_socket_resolver_srv_cb (LmResolver       *resolver,
  59.843 -                            LmResolverResult  result,
  59.844 -                            gpointer          user_data)
  59.845 -{
  59.846 -    LmOldSocket *socket = (LmOldSocket *) user_data;
  59.847 -    const gchar *remote_addr;
  59.848 -
  59.849 -    lm_verbose ("LmOldSocket::srv_cb (result=%d)\n", result);
  59.850 -
  59.851 -    if (result != LM_RESOLVER_RESULT_OK) {
  59.852 -        lm_verbose ("SRV lookup failed, trying jid domain\n");
  59.853 -        socket->server = g_strdup (socket->domain);
  59.854 -    } else {
  59.855 -        g_object_get (resolver, "host", &socket->server, NULL);
  59.856 -        g_object_get (resolver, "port", &socket->port, NULL);
  59.857 -    }
  59.858 -
  59.859 -    if (socket->proxy) {
  59.860 -        remote_addr = lm_proxy_get_server (socket->proxy);
  59.861 -    } else if (socket->server) {
  59.862 -        remote_addr = socket->server;
  59.863 -    }
  59.864 -    else {
  59.865 -        remote_addr = socket->domain;
  59.866 -    }
  59.867 -
  59.868 -    g_object_unref (socket->resolver);
  59.869 -
  59.870 -    socket->resolver =
  59.871 -            lm_resolver_new_for_host (remote_addr,
  59.872 -                                      old_socket_resolver_host_cb,
  59.873 -                                      socket);
  59.874 -
  59.875 -    lm_resolver_lookup (socket->resolver);
  59.876 -}
  59.877 -
  59.878 -LmOldSocket *
  59.879 -lm_old_socket_create (GMainContext      *context,
  59.880 -                      IncomingDataFunc   data_func,
  59.881 -                      SocketClosedFunc   closed_func,
  59.882 -                      ConnectResultFunc  connect_func,
  59.883 -                      gpointer           user_data,
  59.884 -                      LmConnection      *connection,
  59.885 -                      const gchar       *server,
  59.886 -                      const gchar       *domain,
  59.887 -                      guint              port,
  59.888 -                      LmSSL             *ssl,
  59.889 -                      LmProxy           *proxy,
  59.890 -                      GError           **error)
  59.891 -{
  59.892 -    LmOldSocket   *socket;
  59.893 -    LmConnectData *data;
  59.894 -
  59.895 -    g_return_val_if_fail (domain != NULL, NULL);
  59.896 -    g_return_val_if_fail ((port >= LM_MIN_PORT && port <= LM_MAX_PORT), NULL);
  59.897 -    g_return_val_if_fail (data_func != NULL, NULL);
  59.898 -    g_return_val_if_fail (closed_func != NULL, NULL);
  59.899 -    g_return_val_if_fail (connect_func != NULL, NULL);
  59.900 -
  59.901 -    socket = g_new0 (LmOldSocket, 1);
  59.902 -
  59.903 -    socket->ref_count = 1;
  59.904 -
  59.905 -    socket->connection = connection;
  59.906 -    socket->domain = g_strdup (domain);
  59.907 -    socket->server = g_strdup (server);
  59.908 -    socket->port = port;
  59.909 -    socket->cancel_open = FALSE;
  59.910 -    socket->ssl = ssl;
  59.911 -    socket->ssl_started = FALSE;
  59.912 -    socket->proxy = NULL;
  59.913 -
  59.914 -    if (context) {
  59.915 -        socket->context = g_main_context_ref (context);
  59.916 -    }
  59.917 -
  59.918 -    if (proxy) {
  59.919 -        socket->proxy = lm_proxy_ref (proxy);
  59.920 -    }
  59.921 -
  59.922 -    data = g_new0 (LmConnectData, 1);
  59.923 -    data->socket = socket;
  59.924 -    data->connection = socket->connection;
  59.925 -    data->fd = -1;
  59.926 -    socket->connect_data = data;
  59.927 -
  59.928 -    if (!server) {
  59.929 -        socket->resolver = lm_resolver_new_for_service (socket->domain,
  59.930 -                                                        "xmpp-client",
  59.931 -                                                        "tcp",
  59.932 -                                                        old_socket_resolver_srv_cb,
  59.933 -                                                        socket);
  59.934 -    } else {
  59.935 -        socket->resolver =
  59.936 -            lm_resolver_new_for_host (socket->server ? socket->server : socket->domain,
  59.937 -                                      old_socket_resolver_host_cb,
  59.938 -                                      socket);
  59.939 -    }
  59.940 -
  59.941 -    if (socket->context) {
  59.942 -        g_object_set (socket->resolver, "context", context, NULL);
  59.943 -    }
  59.944 -
  59.945 -    socket->data_func = data_func;
  59.946 -    socket->closed_func = closed_func;
  59.947 -    socket->connect_func = connect_func;
  59.948 -    socket->user_data = user_data;
  59.949 -
  59.950 -    lm_resolver_lookup (socket->resolver);
  59.951 -
  59.952 -    return socket;
  59.953 -}
  59.954 -
  59.955 -void
  59.956 -lm_old_socket_flush (LmOldSocket *socket)
  59.957 -{
  59.958 -    g_return_if_fail (socket != NULL);
  59.959 -    g_return_if_fail (socket->io_channel != NULL);
  59.960 -
  59.961 -    g_io_channel_flush (socket->io_channel, NULL);
  59.962 -}
  59.963 -
  59.964 -void
  59.965 -lm_old_socket_close (LmOldSocket *socket)
  59.966 -{
  59.967 -    LmConnectData *data;
  59.968 -
  59.969 -    g_return_if_fail (socket != NULL);
  59.970 -
  59.971 -    if (socket->watch_connect) {
  59.972 -        g_source_destroy (socket->watch_connect);
  59.973 -        socket->watch_connect = NULL;
  59.974 -    }
  59.975 -
  59.976 -    data = socket->connect_data;
  59.977 -    if (data) {
  59.978 -        if (data->io_channel) {
  59.979 -	    socket_close_io_channel (data->io_channel);
  59.980 -        }
  59.981 -        socket->connect_data = NULL;
  59.982 -        g_free (data);
  59.983 -    }
  59.984 -
  59.985 -    /* FIXME: Leaking Resolvers Until Clean Up Can Be Corrected
  59.986 -    if (socket->resolver) {
  59.987 -        g_object_unref (socket->resolver);
  59.988 -        socket->resolver = NULL;
  59.989 -    } */
  59.990 -
  59.991 -    if (socket->io_channel) {
  59.992 -        if (socket->watch_in) {
  59.993 -            g_source_destroy (socket->watch_in);
  59.994 -            socket->watch_in = NULL;
  59.995 -        }
  59.996 -
  59.997 -        if (socket->watch_err) {
  59.998 -            g_source_destroy (socket->watch_err);
  59.999 -            socket->watch_err = NULL;
 59.1000 -        }
 59.1001 -
 59.1002 -        if (socket->watch_hup) {
 59.1003 -            g_source_destroy (socket->watch_hup);
 59.1004 -            socket->watch_hup = NULL;
 59.1005 -        }
 59.1006 -
 59.1007 -        if (socket->watch_out) {
 59.1008 -            g_source_destroy (socket->watch_out);
 59.1009 -            socket->watch_out = NULL;
 59.1010 -        }
 59.1011 -
 59.1012 -        socket_close_io_channel (socket->io_channel);
 59.1013 -
 59.1014 -        socket->io_channel = NULL;
 59.1015 -        socket->fd = -1;
 59.1016 -    }
 59.1017 -
 59.1018 -    if (socket->ssl) {
 59.1019 -        _lm_ssl_close (socket->ssl);
 59.1020 -    }
 59.1021 -}
 59.1022 -
 59.1023 -gchar *
 59.1024 -lm_old_socket_get_local_host (LmOldSocket *socket)
 59.1025 -{
 59.1026 -    return _lm_sock_get_local_host (socket->fd);
 59.1027 -}
 59.1028 -
 59.1029 -LmOldSocket *
 59.1030 -lm_old_socket_ref (LmOldSocket *socket)
 59.1031 -{
 59.1032 -    g_return_val_if_fail (socket != NULL, NULL);
 59.1033 -
 59.1034 -    socket->ref_count++;
 59.1035 -
 59.1036 -    return socket;
 59.1037 -}
 59.1038 -
 59.1039 -void
 59.1040 -lm_old_socket_unref (LmOldSocket *socket)
 59.1041 -{
 59.1042 -    g_return_if_fail (socket != NULL);
 59.1043 -
 59.1044 -    socket->ref_count--;
 59.1045 -
 59.1046 -    if (socket->ref_count <= 0) {
 59.1047 -        socket_free (socket);
 59.1048 -    }
 59.1049 -}
 59.1050 -
 59.1051 -gboolean
 59.1052 -lm_old_socket_set_keepalive (LmOldSocket *socket, int delay)
 59.1053 -{
 59.1054 -#ifdef USE_TCP_KEEPALIVES
 59.1055 -    return _lm_sock_set_keepalive (socket->fd, delay);
 59.1056 -#else
 59.1057 -    return FALSE;
 59.1058 -#endif /* USE_TCP_KEEPALIVES */
 59.1059 -}
 59.1060 -
 59.1061 -void
 59.1062 -lm_old_socket_asyncns_cancel (LmOldSocket *socket)
 59.1063 -{
 59.1064 -    if (!socket->resolver) {
 59.1065 -        return;
 59.1066 -    }
 59.1067 -
 59.1068 -    lm_resolver_cancel (socket->resolver);
 59.1069 -}
 59.1070 -
 59.1071 -gboolean
 59.1072 -lm_old_socket_get_use_starttls (LmOldSocket *socket)
 59.1073 -{
 59.1074 -    if (!socket->ssl) {
 59.1075 -        return FALSE;
 59.1076 -    }
 59.1077 -
 59.1078 -    return lm_ssl_get_use_starttls (socket->ssl);
 59.1079 -}
 59.1080 -
 59.1081 -gboolean
 59.1082 -lm_old_socket_get_require_starttls (LmOldSocket *socket)
 59.1083 -{
 59.1084 -    if (!socket->ssl) {
 59.1085 -        return FALSE;
 59.1086 -    }
 59.1087 -
 59.1088 -    return lm_ssl_get_require_starttls (socket->ssl);
 59.1089 -}
    60.1 --- a/src/lm-old-socket.h	Wed Dec 25 20:33:47 2013 -0500
    60.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    60.3 @@ -1,70 +0,0 @@
    60.4 -/*
    60.5 - *  Copyright (C) 2012 Copyleft Games Group
    60.6 - *  Copyright (C) 2006 Imendio AB
    60.7 - *
    60.8 - *  This program is free software; you can redistribute it and/or modify
    60.9 - *  it under the terms of the GNU Affero General Public License as published
   60.10 - *  by the Free Software Foundation, either version 3 of the License, or
   60.11 - *  (at your option) any later version.
   60.12 - *
   60.13 - *  This program is distributed in the hope that it will be useful,
   60.14 - *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   60.15 - *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   60.16 - *  GNU Affero General Public License for more details.
   60.17 - *
   60.18 - *  You should have received a copy of the GNU Affero General Public License
   60.19 - *  along with this program; if not, see http://www.gnu.org/licenses
   60.20 - *
   60.21 - */
   60.22 -
   60.23 -#ifndef __LM_OLD_SOCKET_H__
   60.24 -#define __LM_OLD_SOCKET_H__
   60.25 -
   60.26 -#include <glib.h>
   60.27 -
   60.28 -#include "lm-internals.h"
   60.29 -
   60.30 -typedef struct _LmOldSocket LmOldSocket;
   60.31 -
   60.32 -typedef void    (* IncomingDataFunc)  (LmOldSocket         *socket,
   60.33 -                                       const gchar         *buf,
   60.34 -                                       gpointer             user_data);
   60.35 -
   60.36 -typedef void    (* SocketClosedFunc)  (LmOldSocket         *socket,
   60.37 -                                       LmDisconnectReason   reason,
   60.38 -                                       gpointer             user_data);
   60.39 -
   60.40 -typedef void    (* ConnectResultFunc) (LmOldSocket         *socket,
   60.41 -                                       gboolean             result,
   60.42 -                                       gpointer             user_data);
   60.43 -
   60.44 -LmOldSocket * lm_old_socket_create          (GMainContext       *context,
   60.45 -                                             IncomingDataFunc    data_func,
   60.46 -                                             SocketClosedFunc    closed_func,
   60.47 -                                             ConnectResultFunc   connect_func,
   60.48 -                                             gpointer            user_data,
   60.49 -                                             LmConnection       *connection,
   60.50 -                                             const gchar        *server,
   60.51 -                                             const gchar        *domain,
   60.52 -                                             guint               port,
   60.53 -                                             LmSSL              *ssl,
   60.54 -                                             LmProxy            *proxy,
   60.55 -                                             GError           **error);
   60.56 -gint           lm_old_socket_write          (LmOldSocket       *socket,
   60.57 -                                             const gchar       *buf,
   60.58 -                                             gint               len);
   60.59 -void           lm_old_socket_flush          (LmOldSocket        *socket);
   60.60 -void           lm_old_socket_close          (LmOldSocket        *socket);
   60.61 -LmOldSocket *  lm_old_socket_ref            (LmOldSocket        *socket);
   60.62 -void           lm_old_socket_unref          (LmOldSocket        *socket);
   60.63 -gboolean       lm_old_socket_starttls       (LmOldSocket        *socket);
   60.64 -gboolean       lm_old_socket_set_keepalive  (LmOldSocket        *socket,
   60.65 -                                             int                 delay);
   60.66 -gchar *        lm_old_socket_get_local_host (LmOldSocket        *socket);
   60.67 -void           lm_old_socket_asyncns_cancel (LmOldSocket        *socket);
   60.68 -
   60.69 -gboolean       lm_old_socket_get_use_starttls (LmOldSocket      *socket);
   60.70 -gboolean       lm_old_socket_get_require_starttls (LmOldSocket  *socket);
   60.71 -
   60.72 -#endif /* __LM_OLD_SOCKET_H__ */
   60.73 -
    61.1 --- a/src/lm-parser.c	Wed Dec 25 20:33:47 2013 -0500
    61.2 +++ b/src/lm-parser.c	Mon Dec 15 05:04:57 2014 +0000
    61.3 @@ -1,5 +1,5 @@
    61.4  /*
    61.5 - *  Copyright (C) 2012 Copyleft Games Group
    61.6 + *  Copyright (C) 2012,2013,2014 Copyleft Games Group
    61.7   *  Copyright (C) 2003 Imendio AB
    61.8   *
    61.9   *  This program is free software; you can redistribute it and/or modify
    62.1 --- a/src/lm-parser.h	Wed Dec 25 20:33:47 2013 -0500
    62.2 +++ b/src/lm-parser.h	Mon Dec 15 05:04:57 2014 +0000
    62.3 @@ -1,5 +1,5 @@
    62.4  /*
    62.5 - *  Copyright (C) 2012 Copyleft Games Group
    62.6 + *  Copyright (C) 2012,2013,2014 Copyleft Games Group
    62.7   *  Copyright (C) 2003 Imendio AB
    62.8   *
    62.9   *  This program is free software; you can redistribute it and/or modify
    63.1 --- a/src/lm-proxy.c	Wed Dec 25 20:33:47 2013 -0500
    63.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    63.3 @@ -1,501 +0,0 @@
    63.4 -/*
    63.5 - *  Copyright (C) 2012 Copyleft Games Group
    63.6 - *  Copyright (C) 2004 Imendio AB
    63.7 - *  Copyright (C) 2004 Josh Beam <josh@3ddrome.com>
    63.8 - *
    63.9 - *  This program is free software; you can redistribute it and/or modify
   63.10 - *  it under the terms of the GNU Affero General Public License as published
   63.11 - *  by the Free Software Foundation, either version 3 of the License, or
   63.12 - *  (at your option) any later version.
   63.13 - *
   63.14 - *  This program is distributed in the hope that it will be useful,
   63.15 - *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   63.16 - *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   63.17 - *  GNU Affero General Public License for more details.
   63.18 - *
   63.19 - *  You should have received a copy of the GNU Affero General Public License
   63.20 - *  along with this program; if not, see http://www.gnu.org/licenses
   63.21 - *
   63.22 - */
   63.23 -
   63.24 -/**
   63.25 - * SECTION:lm-proxy
   63.26 - * @Title: LmProxy
   63.27 - * @Short_description: API for the proxy support in LightMelody
   63.28 - *
   63.29 - * Use this together with an #LmConnection to get the connection to use connect through a proxy. Example of how to use the #LmProxy API.
   63.30 - * <informalexample><programlisting><![CDATA[
   63.31 - * LmConnection *connection;
   63.32 - * LmProxy      *proxy;
   63.33 - *
   63.34 - * connection = lm_connection_new ("myserver");
   63.35 - * proxy = lm_proxy_new_with_server (LM_PROXY_TYPE_HTTP,
   63.36 - *                "myproxyserver",
   63.37 - *                8080);
   63.38 - * lm_connection_set_proxy (connection, proxy);
   63.39 - * ...]]></programlisting></informalexample>
   63.40 - */
   63.41 -
   63.42 -#include <config.h>
   63.43 -
   63.44 -#include <glib.h>
   63.45 -#include <string.h>
   63.46 -
   63.47 -#ifndef G_OS_WIN32
   63.48 -
   63.49 -#include <unistd.h>
   63.50 -#include <sys/socket.h>
   63.51 -
   63.52 -#else  /* G_OS_WIN32 */
   63.53 -
   63.54 -#include <winsock2.h>
   63.55 -
   63.56 -#endif /* G_OS_WIN32 */
   63.57 -
   63.58 -#include "lm-internals.h"
   63.59 -#include <loudmouth/lm-proxy.h>
   63.60 -#include <loudmouth/lm-utils.h>
   63.61 -
   63.62 -struct _LmProxy {
   63.63 -    LmProxyType  type;
   63.64 -    gchar       *server;
   63.65 -    guint        port;
   63.66 -    gchar       *username;
   63.67 -    gchar       *password;
   63.68 -    guint        io_watch;
   63.69 -
   63.70 -    gint         ref_count;
   63.71 -};
   63.72 -
   63.73 -static void          proxy_free              (LmProxy       *proxy);
   63.74 -static gboolean      proxy_http_negotiate    (LmProxy       *proxy,
   63.75 -                                              gint           fd,
   63.76 -                                              const gchar   *server,
   63.77 -                                              guint          port);
   63.78 -static gboolean      proxy_negotiate         (LmProxy       *proxy,
   63.79 -                                              gint           fd,
   63.80 -                                              const gchar   *server,
   63.81 -                                              guint          port);
   63.82 -static gboolean      proxy_http_read_cb      (GIOChannel    *source,
   63.83 -                                              GIOCondition   condition,
   63.84 -                                              gpointer       data);
   63.85 -static gboolean      proxy_read_cb           (GIOChannel    *source,
   63.86 -                                              GIOCondition   condition,
   63.87 -                                              gpointer       data);
   63.88 -
   63.89 -static void
   63.90 -proxy_free (LmProxy *proxy)
   63.91 -{
   63.92 -    g_free (proxy->server);
   63.93 -    g_free (proxy->username);
   63.94 -    g_free (proxy->password);
   63.95 -
   63.96 -    g_free (proxy);
   63.97 -}
   63.98 -
   63.99 -static gboolean
  63.100 -proxy_http_negotiate (LmProxy *proxy, gint fd, const gchar *server, guint port)
  63.101 -{
  63.102 -    gchar *str;
  63.103 -
  63.104 -    if (proxy->username && proxy->password) {
  63.105 -        gchar *tmp1;
  63.106 -        gchar *tmp2;
  63.107 -
  63.108 -        tmp1 = g_strdup_printf ("%s:%s",
  63.109 -                                proxy->username,
  63.110 -                                proxy->password);
  63.111 -        tmp2 = g_base64_encode ((const guchar *) tmp1,
  63.112 -                                (gsize) strlen (tmp1));
  63.113 -        g_free (tmp1);
  63.114 -
  63.115 -        str = g_strdup_printf ("CONNECT %s:%u HTTP/1.1\r\nHost: %s:%u\r\nProxy-Authorization: Basic %s\r\n\r\n",
  63.116 -                               server, port,
  63.117 -                               server, port,
  63.118 -                               tmp2);
  63.119 -        g_free (tmp2);
  63.120 -    } else {
  63.121 -        str = g_strdup_printf ("CONNECT %s:%u HTTP/1.1\r\nHost: %s:%u\r\n\r\n",
  63.122 -                               server, port,
  63.123 -                               server, port);
  63.124 -    }
  63.125 -
  63.126 -    send (fd, str, strlen (str), 0);
  63.127 -    g_free (str);
  63.128 -    return TRUE;
  63.129 -}
  63.130 -
  63.131 -/* returns TRUE when connected through proxy */
  63.132 -static gboolean
  63.133 -proxy_http_read_cb (GIOChannel *source, GIOCondition condition, gpointer data)
  63.134 -{
  63.135 -    gchar          buf[512];
  63.136 -    gsize          bytes_read;
  63.137 -    GError        *error = NULL;
  63.138 -
  63.139 -    g_io_channel_read_chars (source, buf, 512, &bytes_read, &error);
  63.140 -
  63.141 -    if (bytes_read < 16) {
  63.142 -        return FALSE;
  63.143 -    }
  63.144 -
  63.145 -    if (strncmp (buf, "HTTP/1.1 200", 12) != 0 &&
  63.146 -        strncmp (buf, "HTTP/1.0 200", 12) != 0) {
  63.147 -        return FALSE;
  63.148 -    }
  63.149 -
  63.150 -    if (strncmp (buf + (bytes_read - 4), "\r\n\r\n", 4) != 0) {
  63.151 -        return FALSE;
  63.152 -    }
  63.153 -
  63.154 -    return TRUE;
  63.155 -}
  63.156 -
  63.157 -static gboolean
  63.158 -proxy_read_cb (GIOChannel *source, GIOCondition condition, gpointer data)
  63.159 -{
  63.160 -    LmConnectData *connect_data;
  63.161 -    LmConnection  *connection;
  63.162 -    LmProxy       *proxy;
  63.163 -    gboolean       retval = FALSE;
  63.164 -
  63.165 -    connect_data = (LmConnectData *) data;
  63.166 -    connection = connect_data->connection;
  63.167 -    proxy = lm_connection_get_proxy (connection);
  63.168 -
  63.169 -    g_return_val_if_fail (proxy != NULL, FALSE);
  63.170 -
  63.171 -    if (lm_connection_is_open (connection)) {
  63.172 -        return FALSE;
  63.173 -    }
  63.174 -
  63.175 -    switch (lm_proxy_get_type (proxy)) {
  63.176 -    default:
  63.177 -    case LM_PROXY_TYPE_NONE:
  63.178 -        g_assert_not_reached ();
  63.179 -        break;
  63.180 -    case LM_PROXY_TYPE_HTTP:
  63.181 -        retval = proxy_http_read_cb (source, condition, data);
  63.182 -        break;
  63.183 -    }
  63.184 -
  63.185 -    if (retval == TRUE) {
  63.186 -        g_source_remove (proxy->io_watch);
  63.187 -        _lm_old_socket_succeeded ((LmConnectData *) data);
  63.188 -    }
  63.189 -
  63.190 -    return FALSE;
  63.191 -}
  63.192 -
  63.193 -gboolean
  63.194 -proxy_negotiate (LmProxy *proxy, gint fd, const gchar *server, guint port)
  63.195 -{
  63.196 -    g_return_val_if_fail (proxy != NULL, FALSE);
  63.197 -
  63.198 -    switch (proxy->type) {
  63.199 -    case LM_PROXY_TYPE_NONE:
  63.200 -        return TRUE;
  63.201 -    case LM_PROXY_TYPE_HTTP:
  63.202 -        return proxy_http_negotiate (proxy, fd, server, port);
  63.203 -    default:
  63.204 -        g_assert_not_reached ();
  63.205 -    }
  63.206 -
  63.207 -    return FALSE;
  63.208 -}
  63.209 -
  63.210 -gboolean
  63.211 -_lm_proxy_connect_cb (GIOChannel *source, GIOCondition condition, gpointer data)
  63.212 -{
  63.213 -    LmConnection  *connection;
  63.214 -    LmConnectData *connect_data;
  63.215 -    LmProxy       *proxy;
  63.216 -    int            error;
  63.217 -    socklen_t      len;
  63.218 -
  63.219 -    connect_data = (LmConnectData *) data;
  63.220 -    connection = connect_data->connection;
  63.221 -    proxy = lm_connection_get_proxy (connection);
  63.222 -
  63.223 -    g_return_val_if_fail (proxy != NULL, FALSE);
  63.224 -
  63.225 -    if (condition == G_IO_ERR) {
  63.226 -        len = sizeof (error);
  63.227 -        _lm_sock_get_error (connect_data->fd, &error, &len);
  63.228 -        _lm_old_socket_failed_with_error (connect_data, error);
  63.229 -        return FALSE;
  63.230 -    } else if (condition == G_IO_OUT) {
  63.231 -        if (!proxy_negotiate (lm_connection_get_proxy (connection), connect_data->fd, lm_connection_get_server (connection), lm_connection_get_port (connection))) {
  63.232 -            _lm_old_socket_failed (connect_data);
  63.233 -            return FALSE;
  63.234 -        }
  63.235 -
  63.236 -        proxy->io_watch = g_io_add_watch (connect_data->io_channel,
  63.237 -                                          G_IO_IN|G_IO_ERR,
  63.238 -                                          (GIOFunc) proxy_read_cb,
  63.239 -                                          connect_data);
  63.240 -    } else {
  63.241 -        g_assert_not_reached ();
  63.242 -    }
  63.243 -
  63.244 -    return FALSE;
  63.245 -}
  63.246 -
  63.247 -/**
  63.248 - * lm_proxy_new
  63.249 - * @type: the type of the new proxy
  63.250 - *
  63.251 - * Creates a new Proxy. Used #lm_connection_set_proxy to make a connection
  63.252 - * user this proxy.
  63.253 - *
  63.254 - * Return value: a newly create proxy
  63.255 - **/
  63.256 -LmProxy *
  63.257 -lm_proxy_new (LmProxyType type)
  63.258 -{
  63.259 -    LmProxy *proxy;
  63.260 -
  63.261 -    proxy = g_new0 (LmProxy, 1);
  63.262 -
  63.263 -    proxy->ref_count = 1;
  63.264 -    proxy->type = type;
  63.265 -
  63.266 -    switch (proxy->type) {
  63.267 -    case LM_PROXY_TYPE_HTTP:
  63.268 -        proxy->port = 8000;
  63.269 -        break;
  63.270 -    default:
  63.271 -        proxy->port = 0;
  63.272 -    }
  63.273 -
  63.274 -    return proxy;
  63.275 -}
  63.276 -
  63.277 -/**
  63.278 - * lm_proxy_new_with_server
  63.279 - * @type: the type of the new proxy
  63.280 - * @server: the proxy server
  63.281 - * @port: the proxy server port
  63.282 - *
  63.283 - * Creates a new Proxy. Use #lm_connection_set_proxy to make a connection
  63.284 - * user this proxy.
  63.285 - *
  63.286 - * Return value: a newly create proxy
  63.287 - **/
  63.288 -LmProxy *
  63.289 -lm_proxy_new_with_server (LmProxyType  type,
  63.290 -                          const gchar *server,
  63.291 -                          guint        port)
  63.292 -{
  63.293 -    LmProxy *proxy;
  63.294 -
  63.295 -    proxy = lm_proxy_new (type);
  63.296 -    lm_proxy_set_server (proxy, server);
  63.297 -    lm_proxy_set_port (proxy, port);
  63.298 -
  63.299 -    return proxy;
  63.300 -}
  63.301 -
  63.302 -/**
  63.303 - * lm_proxy_get_type
  63.304 - * @proxy: an #LmProxy
  63.305 - *
  63.306 - * Fetches the proxy type
  63.307 - *
  63.308 - * Return value: the type
  63.309 - **/
  63.310 -LmProxyType
  63.311 -lm_proxy_get_type (LmProxy *proxy)
  63.312 -{
  63.313 -    g_return_val_if_fail (proxy != NULL, LM_PROXY_TYPE_NONE);
  63.314 -
  63.315 -    return proxy->type;
  63.316 -}
  63.317 -
  63.318 -/**
  63.319 - * lm_proxy_set_type
  63.320 - * @proxy: an #LmProxy
  63.321 - * @type: an LmProxyType
  63.322 - *
  63.323 - * Sets the proxy type for @proxy to @type.
  63.324 - **/
  63.325 -void
  63.326 -lm_proxy_set_type (LmProxy *proxy, LmProxyType type)
  63.327 -{
  63.328 -    g_return_if_fail (proxy != NULL);
  63.329 -
  63.330 -    proxy->type = type;
  63.331 -}
  63.332 -
  63.333 -/**
  63.334 - * lm_proxy_get_server:
  63.335 - * @proxy: an #LmProxy
  63.336 - *
  63.337 - * Fetches the server address that @proxy is using.
  63.338 - *
  63.339 - * Return value: the proxy server address
  63.340 - **/
  63.341 -const gchar *
  63.342 -lm_proxy_get_server (LmProxy *proxy)
  63.343 -{
  63.344 -    g_return_val_if_fail (proxy != NULL, NULL);
  63.345 -
  63.346 -    return proxy->server;
  63.347 -}
  63.348 -
  63.349 -/**
  63.350 - * lm_proxy_set_server:
  63.351 - * @proxy: an #LmProxy
  63.352 - * @server: Address of the proxy server
  63.353 - *
  63.354 - * Sets the server address for @proxy to @server.
  63.355 - **/
  63.356 -void
  63.357 -lm_proxy_set_server (LmProxy *proxy, const gchar *server)
  63.358 -{
  63.359 -    g_return_if_fail (proxy != NULL);
  63.360 -    g_return_if_fail (server != NULL);
  63.361 -
  63.362 -    g_free (proxy->server);
  63.363 -    proxy->server = _lm_utils_hostname_to_punycode (server);
  63.364 -}
  63.365 -
  63.366 -/**
  63.367 - * lm_proxy_get_port:
  63.368 - * @proxy: an #LmProxy
  63.369 - *
  63.370 - * Fetches the port that @proxy is using.
  63.371 - *
  63.372 - * Return value: The port
  63.373 - **/
  63.374 -guint
  63.375 -lm_proxy_get_port (LmProxy *proxy)
  63.376 -{
  63.377 -    g_return_val_if_fail (proxy != NULL, 0);
  63.378 -
  63.379 -    return proxy->port;
  63.380 -}
  63.381 -
  63.382 -/**
  63.383 - * lm_proxy_set_port:
  63.384 - * @proxy: an #LmProxy
  63.385 - * @port: proxy server port
  63.386 - *
  63.387 - * Sets the server port that @proxy will be using.
  63.388 - **/
  63.389 -void
  63.390 -lm_proxy_set_port (LmProxy *proxy, guint port)
  63.391 -{
  63.392 -    g_return_if_fail (proxy != NULL);
  63.393 -
  63.394 -    proxy->port = port;
  63.395 -}
  63.396 -
  63.397 -/**
  63.398 - * lm_proxy_get_username:
  63.399 - * @proxy: an #LmProxy
  63.400 - *
  63.401 - * Fetches the username that @proxy is using.
  63.402 - *
  63.403 - * Return value: the username
  63.404 - **/
  63.405 -const gchar *
  63.406 -lm_proxy_get_username (LmProxy *proxy)
  63.407 -{
  63.408 -    g_return_val_if_fail (proxy != NULL, NULL);
  63.409 -
  63.410 -    return proxy->username;
  63.411 -}
  63.412 -
  63.413 -/**
  63.414 - * lm_proxy_set_username:
  63.415 - * @proxy: an #LmProxy
  63.416 - * @username: Username
  63.417 - *
  63.418 - * Sets the username for @proxy to @username or %NULL to unset.
  63.419 - **/
  63.420 -void
  63.421 -lm_proxy_set_username (LmProxy *proxy, const gchar *username)
  63.422 -{
  63.423 -    g_return_if_fail (proxy != NULL);
  63.424 -
  63.425 -    g_free (proxy->username);
  63.426 -
  63.427 -    if (username) {
  63.428 -        proxy->username = g_strdup (username);
  63.429 -    } else {
  63.430 -        proxy->username = NULL;
  63.431 -    }
  63.432 -}
  63.433 -/**
  63.434 - * lm_proxy_get_password:
  63.435 - * @proxy: an #LmProxy
  63.436 - *
  63.437 - * Fetches the password that @proxy is using.
  63.438 - *
  63.439 - * Return value: the proxy password
  63.440 - **/
  63.441 -const gchar *
  63.442 -lm_proxy_get_password (LmProxy *proxy)
  63.443 -{
  63.444 -    g_return_val_if_fail (proxy != NULL, NULL);
  63.445 -
  63.446 -    return proxy->password;
  63.447 -}
  63.448 -
  63.449 -/**
  63.450 - * lm_proxy_set_password:
  63.451 - * @proxy: an #LmProxy
  63.452 - * @password: Password
  63.453 - *
  63.454 - * Sets the password for @proxy to @password or %NULL to unset.
  63.455 - **/
  63.456 -void
  63.457 -lm_proxy_set_password (LmProxy *proxy, const gchar *password)
  63.458 -{
  63.459 -    g_return_if_fail (proxy != NULL);
  63.460 -
  63.461 -    g_free (proxy->password);
  63.462 -
  63.463 -    if (password) {
  63.464 -        proxy->password = g_strdup (password);
  63.465 -    } else {
  63.466 -        proxy->password = NULL;
  63.467 -    }
  63.468 -}
  63.469 -
  63.470 -/**
  63.471 - * lm_proxy_ref:
  63.472 - * @proxy: an #LmProxy
  63.473 - *
  63.474 - * Adds a reference to @proxy.
  63.475 - *
  63.476 - * Return value: the proxy
  63.477 - **/
  63.478 -LmProxy *
  63.479 -lm_proxy_ref (LmProxy *proxy)
  63.480 -{
  63.481 -    g_return_val_if_fail (proxy != NULL, NULL);
  63.482 -
  63.483 -    proxy->ref_count++;
  63.484 -    return proxy;
  63.485 -}
  63.486 -
  63.487 -/**
  63.488 - * lm_proxy_unref
  63.489 - * @proxy: an #LmProxy
  63.490 - *
  63.491 - * Removes a reference from @proxy. When no more references are present
  63.492 - * @proxy is freed.
  63.493 - **/
  63.494 -void
  63.495 -lm_proxy_unref (LmProxy *proxy)
  63.496 -{
  63.497 -    g_return_if_fail (proxy != NULL);
  63.498 -
  63.499 -    proxy->ref_count--;
  63.500 -
  63.501 -    if (proxy->ref_count == 0) {
  63.502 -        proxy_free (proxy);
  63.503 -    }
  63.504 -}
    64.1 --- a/src/lm-resolver.c	Wed Dec 25 20:33:47 2013 -0500
    64.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    64.3 @@ -1,507 +0,0 @@
    64.4 -/*
    64.5 - *  Copyright (C) 2012 Copyleft Games Group
    64.6 - *  Copyright (C) 2008 Imendio AB
    64.7 - *
    64.8 - *  This program is free software; you can redistribute it and/or modify
    64.9 - *  it under the terms of the GNU Affero General Public License as published
   64.10 - *  by the Free Software Foundation, either version 3 of the License, or
   64.11 - *  (at your option) any later version.
   64.12 - *
   64.13 - *  This program is distributed in the hope that it will be useful,
   64.14 - *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   64.15 - *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   64.16 - *  GNU Affero General Public License for more details.
   64.17 - *
   64.18 - *  You should have received a copy of the GNU Affero General Public License
   64.19 - *  along with this program; if not, see http://www.gnu.org/licenses
   64.20 - *
   64.21 - */
   64.22 -
   64.23 -#include <config.h>
   64.24 -
   64.25 -#include <string.h>
   64.26 -
   64.27 -/* Needed on Mac OS X */
   64.28 -#if HAVE_ARPA_NAMESER_COMPAT_H
   64.29 -#include <arpa/nameser_compat.h>
   64.30 -#endif
   64.31 -
   64.32 -#include <arpa/nameser.h>
   64.33 -#include <resolv.h>
   64.34 -
   64.35 -#include "android-resolv.h"
   64.36 -
   64.37 -#include "lm-asyncns-resolver.h"
   64.38 -#include "lm-blocking-resolver.h"
   64.39 -#include "lm-debug.h"
   64.40 -#include "lm-internals.h"
   64.41 -#include "lm-marshal.h"
   64.42 -#include "lm-resolver.h"
   64.43 -
   64.44 -#define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), LM_TYPE_RESOLVER, LmResolverPriv))
   64.45 -
   64.46 -typedef struct LmResolverPriv LmResolverPriv;
   64.47 -struct LmResolverPriv {
   64.48 -    GMainContext       *context;
   64.49 -
   64.50 -    LmResolverCallback  callback;
   64.51 -    gpointer            user_data;
   64.52 -
   64.53 -    /* -- Properties -- */
   64.54 -    LmResolverType      type;
   64.55 -    gchar              *host;
   64.56 -    guint               port;
   64.57 -
   64.58 -    /* For SRV lookups */
   64.59 -    gchar              *domain;
   64.60 -    gchar              *service;
   64.61 -    gchar              *protocol;
   64.62 -
   64.63 -    /* The results */
   64.64 -    LmResolverResult    result;
   64.65 -    struct addrinfo    *results;
   64.66 -    struct addrinfo    *current_result;
   64.67 -};
   64.68 -
   64.69 -static void     resolver_finalize            (GObject           *object);
   64.70 -static void     resolver_get_property        (GObject           *object,
   64.71 -                                              guint              param_id,
   64.72 -                                              GValue            *value,
   64.73 -                                              GParamSpec        *pspec);
   64.74 -static void     resolver_set_property        (GObject           *object,
   64.75 -                                              guint              param_id,
   64.76 -                                              const GValue      *value,
   64.77 -                                              GParamSpec        *pspec);
   64.78 -
   64.79 -G_DEFINE_TYPE (LmResolver, lm_resolver, G_TYPE_OBJECT)
   64.80 -
   64.81 -enum {
   64.82 -    PROP_0,
   64.83 -    PROP_CONTEXT,
   64.84 -    PROP_TYPE,
   64.85 -    PROP_HOST,
   64.86 -    PROP_PORT,
   64.87 -    PROP_DOMAIN,
   64.88 -    PROP_SERVICE,
   64.89 -    PROP_PROTOCOL
   64.90 -};
   64.91 -
   64.92 -static void
   64.93 -lm_resolver_class_init (LmResolverClass *class)
   64.94 -{
   64.95 -    GObjectClass *object_class = G_OBJECT_CLASS (class);
   64.96 -
   64.97 -    object_class->finalize     = resolver_finalize;
   64.98 -    object_class->get_property = resolver_get_property;
   64.99 -    object_class->set_property = resolver_set_property;
  64.100 -
  64.101 -    g_object_class_install_property (object_class,
  64.102 -                                     PROP_CONTEXT,
  64.103 -                                     g_param_spec_pointer ("context",
  64.104 -                                                           "Context",
  64.105 -                                                           "Main context to use",
  64.106 -                                                           G_PARAM_READWRITE));
  64.107 -
  64.108 -    g_object_class_install_property (object_class,
  64.109 -                                     PROP_TYPE,
  64.110 -                                     g_param_spec_int ("type",
  64.111 -                                                       "Type",
  64.112 -                                                       "Resolver Type",
  64.113 -                                                       LM_RESOLVER_HOST,
  64.114 -                                                       LM_RESOLVER_SRV,
  64.115 -                                                       LM_RESOLVER_HOST,
  64.116 -                                                       G_PARAM_READWRITE));
  64.117 -
  64.118 -    g_object_class_install_property (object_class,
  64.119 -                                     PROP_HOST,
  64.120 -                                     g_param_spec_string ("host",
  64.121 -                                                          "Host",
  64.122 -                                                          "Host to lookup",
  64.123 -                                                          NULL,
  64.124 -                                                          G_PARAM_READWRITE));
  64.125 -
  64.126 -    g_object_class_install_property (object_class,
  64.127 -                                     PROP_PORT,
  64.128 -                                     g_param_spec_uint ("port",
  64.129 -                                                        "Port",
  64.130 -                                                        "Port number",
  64.131 -                                                        0,
  64.132 -                                                        LM_MAX_PORT,
  64.133 -                                                        0,
  64.134 -                                                        G_PARAM_READWRITE));
  64.135 -
  64.136 -    g_object_class_install_property (object_class,
  64.137 -                                     PROP_DOMAIN,
  64.138 -                                     g_param_spec_string ("domain",
  64.139 -                                                          "Domain",
  64.140 -                                                          "Domain to lookup",
  64.141 -                                                          NULL,
  64.142 -                                                          G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
  64.143 -
  64.144 -    g_object_class_install_property (object_class,
  64.145 -                                     PROP_SERVICE,
  64.146 -                                     g_param_spec_string ("service",
  64.147 -                                                          "Service",
  64.148 -                                                          "Service to lookup",
  64.149 -                                                          NULL,
  64.150 -                                                          G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
  64.151 -
  64.152 -    g_object_class_install_property (object_class,
  64.153 -                                     PROP_PROTOCOL,
  64.154 -                                     g_param_spec_string ("protocol",
  64.155 -                                                          "Protocol",
  64.156 -                                                          "Protocol for SRV lookup",
  64.157 -                                                          NULL,
  64.158 -                                                          G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
  64.159 -
  64.160 -    g_type_class_add_private (object_class, sizeof (LmResolverPriv));
  64.161 -}
  64.162 -
  64.163 -static void
  64.164 -lm_resolver_init (LmResolver *resolver)
  64.165 -{
  64.166 -    (void) GET_PRIV (resolver);
  64.167 -}
  64.168 -
  64.169 -static void
  64.170 -resolver_finalize (GObject *object)
  64.171 -{
  64.172 -    LmResolverPriv *priv;
  64.173 -
  64.174 -    priv = GET_PRIV (object);
  64.175 -
  64.176 -    g_free (priv->host);
  64.177 -    g_free (priv->domain);
  64.178 -    g_free (priv->service);
  64.179 -    g_free (priv->protocol);
  64.180 -
  64.181 -    if (priv->context) {
  64.182 -        g_main_context_unref (priv->context);
  64.183 -    }
  64.184 -
  64.185 -    if (priv->results) {
  64.186 -        freeaddrinfo (priv->results);
  64.187 -    }
  64.188 -
  64.189 -    (G_OBJECT_CLASS (lm_resolver_parent_class)->finalize) (object);
  64.190 -}
  64.191 -
  64.192 -static void
  64.193 -resolver_get_property (GObject    *object,
  64.194 -                       guint       param_id,
  64.195 -                       GValue     *value,
  64.196 -                       GParamSpec *pspec)
  64.197 -{
  64.198 -    LmResolverPriv *priv;
  64.199 -
  64.200 -    priv = GET_PRIV (object);
  64.201 -
  64.202 -    switch (param_id) {
  64.203 -    case PROP_CONTEXT:
  64.204 -        g_value_set_pointer (value, priv->context);
  64.205 -        break;
  64.206 -    case PROP_TYPE:
  64.207 -        g_value_set_int (value, priv->type);
  64.208 -        break;
  64.209 -    case PROP_HOST:
  64.210 -        g_value_set_string (value, priv->host);
  64.211 -        break;
  64.212 -    case PROP_PORT:
  64.213 -        g_value_set_uint (value, priv->port);
  64.214 -        break;
  64.215 -    case PROP_DOMAIN:
  64.216 -        g_value_set_string (value, priv->domain);
  64.217 -        break;
  64.218 -    case PROP_SERVICE:
  64.219 -        g_value_set_string (value, priv->service);
  64.220 -        break;
  64.221 -    case PROP_PROTOCOL:
  64.222 -        g_value_set_string (value, priv->protocol);
  64.223 -        break;
  64.224 -    default:
  64.225 -        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
  64.226 -        break;
  64.227 -    };
  64.228 -}
  64.229 -
  64.230 -static void
  64.231 -resolver_set_property (GObject      *object,
  64.232 -                       guint         param_id,
  64.233 -                       const GValue *value,
  64.234 -                       GParamSpec   *pspec)
  64.235 -{
  64.236 -    LmResolverPriv *priv;
  64.237 -
  64.238 -    priv = GET_PRIV (object);
  64.239 -
  64.240 -    switch (param_id) {
  64.241 -    case PROP_CONTEXT:
  64.242 -        if (priv->context) {
  64.243 -            g_main_context_unref (priv->context);
  64.244 -        }
  64.245 -
  64.246 -        priv->context = (GMainContext *) g_value_get_pointer (value);
  64.247 -        g_main_context_ref (priv->context);
  64.248 -        break;
  64.249 -    case PROP_TYPE:
  64.250 -        priv->type = g_value_get_int (value);
  64.251 -        break;
  64.252 -    case PROP_HOST:
  64.253 -        g_free (priv->host);
  64.254 -        priv->host = g_value_dup_string (value);
  64.255 -        break;
  64.256 -    case PROP_PORT:
  64.257 -        priv->port = g_value_get_uint (value);
  64.258 -        break;
  64.259 -    case PROP_DOMAIN:
  64.260 -        g_free (priv->domain);
  64.261 -        priv->domain = g_value_dup_string (value);
  64.262 -        break;
  64.263 -    case PROP_SERVICE:
  64.264 -        g_free (priv->service);
  64.265 -        priv->service = g_value_dup_string (value);
  64.266 -        break;
  64.267 -    case PROP_PROTOCOL:
  64.268 -        g_free (priv->protocol);
  64.269 -        priv->protocol = g_value_dup_string (value);
  64.270 -        break;
  64.271 -    default:
  64.272 -        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
  64.273 -        break;
  64.274 -    };
  64.275 -}
  64.276 -
  64.277 -LmResolver *
  64.278 -lm_resolver_new (GMainContext *context)
  64.279 -{
  64.280 -    LmResolver *resolver;
  64.281 -
  64.282 -#ifdef HAVE_ASYNCNS
  64.283 -    resolver = g_object_new (LM_TYPE_ASYNCNS_RESOLVER, NULL);
  64.284 -#else
  64.285 -    resolver = g_object_new (LM_TYPE_BLOCKING_RESOLVER, NULL);
  64.286 -#endif
  64.287 -
  64.288 -    g_object_set (resolver, "context", context, NULL);
  64.289 -
  64.290 -    return resolver;
  64.291 -}
  64.292 -
  64.293 -static GType
  64.294 -resolver_get_gtype (void)
  64.295 -{
  64.296 -#ifdef HAVE_ASYNCNS
  64.297 -    return LM_TYPE_ASYNCNS_RESOLVER;
  64.298 -#else
  64.299 -    return LM_TYPE_BLOCKING_RESOLVER;
  64.300 -#endif /* HAVE_ASYNCNS */
  64.301 -}
  64.302 -
  64.303 -LmResolver *
  64.304 -lm_resolver_new_for_host (const gchar        *host,
  64.305 -                          LmResolverCallback  callback,
  64.306 -                          gpointer            user_data)
  64.307 -{
  64.308 -    LmResolver     *resolver;
  64.309 -    LmResolverPriv *priv;
  64.310 -
  64.311 -    g_return_val_if_fail (host != NULL, NULL);
  64.312 -    g_return_val_if_fail (callback != NULL, NULL);
  64.313 -
  64.314 -    resolver =  g_object_new (resolver_get_gtype (),
  64.315 -                              "type", LM_RESOLVER_HOST,
  64.316 -                              "host", host,
  64.317 -                              NULL);
  64.318 -
  64.319 -    priv = GET_PRIV (resolver);
  64.320 -
  64.321 -    priv->callback = callback;
  64.322 -    priv->user_data = user_data;
  64.323 -
  64.324 -    return resolver;
  64.325 -}
  64.326 -
  64.327 -LmResolver *
  64.328 -lm_resolver_new_for_service (const gchar        *domain,
  64.329 -                             const gchar        *service,
  64.330 -                             const gchar        *protocol,
  64.331 -                             LmResolverCallback  callback,
  64.332 -                             gpointer            user_data)
  64.333 -{
  64.334 -    LmResolver     *resolver;
  64.335 -    LmResolverPriv *priv;
  64.336 -
  64.337 -    g_return_val_if_fail (domain != NULL, NULL);
  64.338 -    g_return_val_if_fail (service != NULL, NULL);
  64.339 -    g_return_val_if_fail (protocol != NULL, NULL);
  64.340 -    g_return_val_if_fail (callback != NULL, NULL);
  64.341 -
  64.342 -    resolver = g_object_new (resolver_get_gtype (),
  64.343 -                             "type", LM_RESOLVER_SRV,
  64.344 -                             "domain", domain,
  64.345 -                             "service", service,
  64.346 -                             "protocol", protocol,
  64.347 -                             NULL);
  64.348 -
  64.349 -    priv = GET_PRIV (resolver);
  64.350 -
  64.351 -    priv->callback = callback;
  64.352 -    priv->user_data = user_data;
  64.353 -
  64.354 -    return resolver;
  64.355 -}
  64.356 -
  64.357 -void
  64.358 -lm_resolver_lookup (LmResolver *resolver)
  64.359 -{
  64.360 -    if (!LM_RESOLVER_GET_CLASS(resolver)) {
  64.361 -        g_assert_not_reached ();
  64.362 -    }
  64.363 -
  64.364 -    LM_RESOLVER_GET_CLASS(resolver)->lookup (resolver);
  64.365 -}
  64.366 -
  64.367 -void
  64.368 -lm_resolver_cancel (LmResolver *resolver)
  64.369 -{
  64.370 -    if (!LM_RESOLVER_GET_CLASS(resolver)->cancel) {
  64.371 -        g_assert_not_reached ();
  64.372 -    }
  64.373 -
  64.374 -    LM_RESOLVER_GET_CLASS(resolver)->cancel (resolver);
  64.375 -}
  64.376 -
  64.377 -/* To iterate through the results */
  64.378 -struct addrinfo *
  64.379 -lm_resolver_results_get_next (LmResolver *resolver)
  64.380 -{
  64.381 -    LmResolverPriv  *priv;
  64.382 -    struct addrinfo *ret_val;
  64.383 -
  64.384 -    g_return_val_if_fail (LM_IS_RESOLVER (resolver), NULL);
  64.385 -
  64.386 -    priv = GET_PRIV (resolver);
  64.387 -
  64.388 -skipresult:
  64.389 -    if (!priv->current_result) {
  64.390 -        g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_VERBOSE,
  64.391 -               "no more results from resolver\n");
  64.392 -        return NULL;
  64.393 -    };
  64.394 -
  64.395 -    ret_val = priv->current_result;
  64.396 -    priv->current_result = priv->current_result->ai_next;
  64.397 -    if (ret_val->ai_family != AF_INET) {
  64.398 -        g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_VERBOSE,
  64.399 -               "skipping non-IPv4 resolver entry\n");
  64.400 -        goto skipresult;
  64.401 -    };
  64.402 -
  64.403 -    return ret_val;
  64.404 -}
  64.405 -
  64.406 -void
  64.407 -lm_resolver_results_reset (LmResolver *resolver)
  64.408 -{
  64.409 -    LmResolverPriv *priv;
  64.410 -
  64.411 -    g_return_if_fail (LM_IS_RESOLVER (resolver));
  64.412 -
  64.413 -    priv = GET_PRIV (resolver);
  64.414 -
  64.415 -    priv->current_result = priv->results;
  64.416 -}
  64.417 -
  64.418 -gchar *
  64.419 -_lm_resolver_create_srv_string (const gchar *domain,
  64.420 -                                const gchar *service,
  64.421 -                                const gchar *protocol)
  64.422 -{
  64.423 -    g_return_val_if_fail (domain != NULL, NULL);
  64.424 -    g_return_val_if_fail (service != NULL, NULL);
  64.425 -    g_return_val_if_fail (protocol != NULL, NULL);
  64.426 -
  64.427 -    return g_strdup_printf ("_%s._%s.%s", service, protocol, domain);
  64.428 -}
  64.429 -
  64.430 -void
  64.431 -_lm_resolver_set_result (LmResolver       *resolver,
  64.432 -                         LmResolverResult  result,
  64.433 -                         struct addrinfo  *results)
  64.434 -{
  64.435 -    LmResolverPriv *priv;
  64.436 -
  64.437 -    g_return_if_fail (LM_IS_RESOLVER (resolver));
  64.438 -
  64.439 -    priv = GET_PRIV (resolver);
  64.440 -
  64.441 -    priv->result = result;
  64.442 -    priv->results = priv->current_result = results;
  64.443 -
  64.444 -    lm_verbose ("Calling resolver callback: %s\n", priv->host);
  64.445 -
  64.446 -    priv->callback (resolver, result, priv->user_data);
  64.447 -}
  64.448 -
  64.449 -gboolean
  64.450 -_lm_resolver_parse_srv_response (unsigned char  *srv,
  64.451 -                                 int             srv_len,
  64.452 -                                 gchar         **out_server,
  64.453 -                                 guint          *out_port)
  64.454 -{
  64.455 -    int                  qdcount;
  64.456 -    int                  ancount;
  64.457 -    int                  len;
  64.458 -    const unsigned char *pos;
  64.459 -    unsigned char       *end;
  64.460 -    HEADER              *head;
  64.461 -    char                 name[256];
  64.462 -    char                 pref_name[256];
  64.463 -    guint                pref_port = 0;
  64.464 -    guint                pref_prio = 9999;
  64.465 -
  64.466 -    pref_name[0] = 0;
  64.467 -
  64.468 -    pos = srv + sizeof (HEADER);
  64.469 -    end = srv + srv_len;
  64.470 -    head = (HEADER *) srv;
  64.471 -
  64.472 -    qdcount = ntohs (head->qdcount);
  64.473 -    ancount = ntohs (head->ancount);
  64.474 -
  64.475 -    /* Ignore the questions */
  64.476 -    while (qdcount-- > 0 && (len = dn_expand (srv, end, pos, name, 255)) >= 0) {
  64.477 -        g_assert (len >= 0);
  64.478 -        pos += len + QFIXEDSZ;
  64.479 -    }
  64.480 -
  64.481 -    /* Parse the answers */
  64.482 -    while (ancount-- > 0 && (len = dn_expand (srv, end, pos, name, 255)) >= 0) {
  64.483 -        /* Ignore the initial string */
  64.484 -        uint16_t pref, weight, port;
  64.485 -
  64.486 -        g_assert (len >= 0);
  64.487 -        pos += len;
  64.488 -        /* Ignore type, ttl, class and dlen */
  64.489 -        pos += 10;
  64.490 -        GETSHORT (pref, pos);
  64.491 -        GETSHORT (weight, pos);
  64.492 -        GETSHORT (port, pos);
  64.493 -
  64.494 -        len = dn_expand (srv, end, pos, name, 255);
  64.495 -        if (pref < pref_prio) {
  64.496 -            pref_prio = pref;
  64.497 -            strcpy (pref_name, name);
  64.498 -            pref_port = port;
  64.499 -        }
  64.500 -        pos += len;
  64.501 -    }
  64.502 -
  64.503 -    if (pref_name[0]) {
  64.504 -        *out_server = g_strdup (pref_name);
  64.505 -        *out_port = pref_port;
  64.506 -        return TRUE;
  64.507 -    }
  64.508 -    return FALSE;
  64.509 -}
  64.510 -
    65.1 --- a/src/lm-resolver.h	Wed Dec 25 20:33:47 2013 -0500
    65.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    65.3 @@ -1,97 +0,0 @@
    65.4 -/*
    65.5 - *  Copyright (C) 2012 Copyleft Games Group
    65.6 - *  Copyright (C) 2008 Imendio AB
    65.7 - *
    65.8 - *  This program is free software; you can redistribute it and/or modify
    65.9 - *  it under the terms of the GNU Affero General Public License as published
   65.10 - *  by the Free Software Foundation, either version 3 of the License, or
   65.11 - *  (at your option) any later version.
   65.12 - *
   65.13 - *  This program is distributed in the hope that it will be useful,
   65.14 - *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   65.15 - *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   65.16 - *  GNU Affero General Public License for more details.
   65.17 - *
   65.18 - *  You should have received a copy of the GNU Affero General Public License
   65.19 - *  along with this program; if not, see http://www.gnu.org/licenses
   65.20 - *
   65.21 - */
   65.22 -
   65.23 -#ifndef __LM_RESOLVER_H__
   65.24 -#define __LM_RESOLVER_H__
   65.25 -
   65.26 -#include <glib-object.h>
   65.27 -
   65.28 -G_BEGIN_DECLS
   65.29 -
   65.30 -#define LM_TYPE_RESOLVER            (lm_resolver_get_type ())
   65.31 -#define LM_RESOLVER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), LM_TYPE_RESOLVER, LmResolver))
   65.32 -#define LM_RESOLVER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), LM_TYPE_RESOLVER, LmResolverClass))
   65.33 -#define LM_IS_RESOLVER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LM_TYPE_RESOLVER))
   65.34 -#define LM_IS_RESOLVER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), LM_TYPE_RESOLVER))
   65.35 -#define LM_RESOLVER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), LM_TYPE_RESOLVER, LmResolverClass))
   65.36 -
   65.37 -typedef struct LmResolver      LmResolver;
   65.38 -typedef struct LmResolverClass LmResolverClass;
   65.39 -
   65.40 -struct LmResolver {
   65.41 -    GObject parent;
   65.42 -};
   65.43 -
   65.44 -struct LmResolverClass {
   65.45 -    GObjectClass parent_class;
   65.46 -
   65.47 -    /* <vtable> */
   65.48 -    void (*lookup)  (LmResolver  *resolver);
   65.49 -    void (*cancel)  (LmResolver  *resolver);
   65.50 -};
   65.51 -
   65.52 -typedef enum {
   65.53 -    LM_RESOLVER_HOST,
   65.54 -    LM_RESOLVER_SRV
   65.55 -} LmResolverType;
   65.56 -
   65.57 -typedef enum {
   65.58 -    LM_RESOLVER_RESULT_OK,
   65.59 -    LM_RESOLVER_RESULT_FAILED,
   65.60 -    LM_RESOLVER_RESULT_CANCELLED
   65.61 -} LmResolverResult;
   65.62 -
   65.63 -typedef void (*LmResolverCallback) (LmResolver       *resolver,
   65.64 -                                    LmResolverResult  result,
   65.65 -                                    gpointer          user_data);
   65.66 -
   65.67 -GType             lm_resolver_get_type          (void);
   65.68 -LmResolver *      lm_resolver_new               (GMainContext       *context);
   65.69 -
   65.70 -LmResolver *      lm_resolver_new_for_host      (const gchar        *host,
   65.71 -                                                 LmResolverCallback  callback,
   65.72 -                                                 gpointer            user_data);
   65.73 -LmResolver *      lm_resolver_new_for_service   (const gchar        *domain,
   65.74 -                                                 const gchar        *service,
   65.75 -                                                 const gchar        *protocol,
   65.76 -                                                 LmResolverCallback  callback,
   65.77 -                                                 gpointer            user_data);
   65.78 -void              lm_resolver_lookup            (LmResolver         *resolver);
   65.79 -void              lm_resolver_cancel            (LmResolver         *resolver);
   65.80 -/* To iterate through the results */
   65.81 -struct addrinfo * lm_resolver_results_get_next  (LmResolver         *resolver);
   65.82 -void              lm_resolver_results_reset     (LmResolver         *resolver);
   65.83 -
   65.84 -/* Only for sub classes */
   65.85 -gchar *           _lm_resolver_create_srv_string (const gchar        *domain,
   65.86 -                                                  const gchar        *service,
   65.87 -                                                  const gchar        *protocol);
   65.88 -
   65.89 -void              _lm_resolver_set_result       (LmResolver         *resolver,
   65.90 -                                                 LmResolverResult    result,
   65.91 -                                                 struct addrinfo    *results);
   65.92 -gboolean        _lm_resolver_parse_srv_response (unsigned char      *srv,
   65.93 -                                                 int                 srv_len,
   65.94 -                                                 gchar            **out_server,
   65.95 -                                                 guint              *out_port);
   65.96 -
   65.97 -G_END_DECLS
   65.98 -
   65.99 -#endif /* __LM_RESOLVER_H__ */
  65.100 -
    66.1 --- a/src/lm-sasl.c	Wed Dec 25 20:33:47 2013 -0500
    66.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    66.3 @@ -1,1180 +0,0 @@
    66.4 -/*
    66.5 - *  Copyright (C) 2012 Copyleft Games Group
    66.6 - *  Copyright (C) 2007 Collabora Ltd.
    66.7 - *
    66.8 - *  This program is free software; you can redistribute it and/or modify
    66.9 - *  it under the terms of the GNU Affero General Public License as published
   66.10 - *  by the Free Software Foundation, either version 3 of the License, or
   66.11 - *  (at your option) any later version.
   66.12 - *
   66.13 - *  This program is distributed in the hope that it will be useful,
   66.14 - *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   66.15 - *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   66.16 - *  GNU Affero General Public License for more details.
   66.17 - *
   66.18 - *  You should have received a copy of the GNU Affero General Public License
   66.19 - *  along with this program; if not, see http://www.gnu.org/licenses
   66.20 - *
   66.21 - */
   66.22 -
   66.23 -#include <config.h>
   66.24 -
   66.25 -#include <stdio.h>
   66.26 -#include <string.h>
   66.27 -#include <glib.h>
   66.28 -
   66.29 -#ifdef HAVE_GSSAPI
   66.30 -#include <gssapi.h>
   66.31 -#endif
   66.32 -
   66.33 -#include "lm-sock.h"
   66.34 -#include "lm-debug.h"
   66.35 -#include <loudmouth/lm-error.h>
   66.36 -#include "lm-internals.h"
   66.37 -#include "lm-misc.h"
   66.38 -#include "lm-ssl-internals.h"
   66.39 -#include "lm-parser.h"
   66.40 -#include <loudmouth/lm-connection.h>
   66.41 -#include <loudmouth/lm-utils.h>
   66.42 -#include "lm-old-socket.h"
   66.43 -#include "lm-sasl.h"
   66.44 -
   66.45 -typedef enum {
   66.46 -    AUTH_TYPE_PLAIN  = 1,
   66.47 -    AUTH_TYPE_DIGEST = 2,
   66.48 -    AUTH_TYPE_GSSAPI = 4,
   66.49 -} AuthType;
   66.50 -
   66.51 -typedef enum {
   66.52 -    SASL_AUTH_STATE_NO_MECH,
   66.53 -    SASL_AUTH_STATE_PLAIN_STARTED,
   66.54 -    SASL_AUTH_STATE_DIGEST_MD5_STARTED,
   66.55 -    SASL_AUTH_STATE_DIGEST_MD5_SENT_AUTH_RESPONSE,
   66.56 -    SASL_AUTH_STATE_DIGEST_MD5_SENT_FINAL_RESPONSE,
   66.57 -    SASL_AUTH_STATE_GSSAPI_STARTED,
   66.58 -    SASL_AUTH_STATE_GSSAPI_SENT_AUTH_RESPONSE,
   66.59 -    SASL_AUTH_STATE_GSSAPI_SENT_FINAL_RESPONSE,
   66.60 -} SaslAuthState;
   66.61 -
   66.62 -struct _LmSASL {
   66.63 -    LmConnection        *connection;
   66.64 -    AuthType             auth_type;
   66.65 -    SaslAuthState        state;
   66.66 -    LmAuthParameters    *auth_params;
   66.67 -    gchar               *server;
   66.68 -    gchar               *digest_md5_rspauth;
   66.69 -    LmMessageHandler    *features_cb;
   66.70 -    LmMessageHandler    *challenge_cb;
   66.71 -    LmMessageHandler    *success_cb;
   66.72 -    LmMessageHandler    *failure_cb;
   66.73 -
   66.74 -    gboolean             features_received;
   66.75 -    gboolean             start_auth;
   66.76 -
   66.77 -    LmSASLResultHandler  handler;
   66.78 -
   66.79 -#ifdef HAVE_GSSAPI
   66.80 -    gss_ctx_id_t         gss_ctx;
   66.81 -    gss_name_t           gss_service;
   66.82 -#endif
   66.83 -};
   66.84 -
   66.85 -#define XMPP_NS_SASL_AUTH "urn:ietf:params:xml:ns:xmpp-sasl"
   66.86 -
   66.87 -static LmHandlerResult     sasl_features_cb  (LmMessageHandler *handler,
   66.88 -                                              LmConnection     *connection,
   66.89 -                                              LmMessage        *message,
   66.90 -                                              gpointer          user_data);
   66.91 -
   66.92 -static LmHandlerResult     sasl_challenge_cb (LmMessageHandler *handler,
   66.93 -                                              LmConnection     *connection,
   66.94 -                                              LmMessage        *message,
   66.95 -                                              gpointer          user_data);
   66.96 -
   66.97 -static LmHandlerResult     sasl_success_cb   (LmMessageHandler *handler,
   66.98 -                                              LmConnection     *connection,
   66.99 -                                              LmMessage        *message,
  66.100 -                                              gpointer          user_data);
  66.101 -
  66.102 -static LmHandlerResult     sasl_failure_cb   (LmMessageHandler *handler,
  66.103 -                                              LmConnection     *connection,
  66.104 -                                              LmMessage        *message,
  66.105 -                                              gpointer          user_data);
  66.106 -
  66.107 -
  66.108 -#ifdef HAVE_GSSAPI
  66.109 -static gboolean
  66.110 -sasl_gssapi_handle_challenge (LmSASL *sasl, LmMessageNode *node);
  66.111 -
  66.112 -static void
  66.113 -sasl_gssapi_fail (LmSASL     *sasl,
  66.114 -                  const char *message,
  66.115 -                  guint32     major_status,
  66.116 -                  guint32     minor_status)
  66.117 -{
  66.118 -    guint32         err_major_status;
  66.119 -    guint32         err_minor_status;
  66.120 -    guint32         msg_ctx = 0;
  66.121 -    gss_buffer_desc major_status_string = GSS_C_EMPTY_BUFFER;
  66.122 -    gss_buffer_desc minor_status_string = GSS_C_EMPTY_BUFFER;
  66.123 -
  66.124 -    err_major_status = gss_display_status (&err_minor_status, major_status,
  66.125 -                                           GSS_C_GSS_CODE, GSS_C_NO_OID,
  66.126 -                                           &msg_ctx, &major_status_string);
  66.127 -
  66.128 -    if (!GSS_ERROR(err_major_status)) {
  66.129 -        err_major_status = gss_display_status (&err_minor_status, minor_status,
  66.130 -                                               GSS_C_MECH_CODE, GSS_C_NULL_OID,
  66.131 -                                               &msg_ctx, &minor_status_string);
  66.132 -    }
  66.133 -
  66.134 -    g_log (LM_LOG_DOMAIN, LM_LOG_LEVEL_SASL, "GSSAPI: %s: %s, %s", message,
  66.135 -           (char *)major_status_string.value,
  66.136 -           (char *)minor_status_string.value);
  66.137 -
  66.138 -    if (sasl->handler) {
  66.139 -        sasl->handler (sasl, sasl->connection, FALSE, "GSSAPI failure");
  66.140 -    }
  66.141 -
  66.142 -    gss_release_buffer (&err_minor_status, &major_status_string);
  66.143 -    gss_release_buffer (&err_minor_status, &minor_status_string);
  66.144 -}
  66.145 -
  66.146 -static gss_name_t
  66.147 -sasl_gssapi_get_creds (LmSASL *sasl)
  66.148 -{
  66.149 -    gss_buffer_desc token = GSS_C_EMPTY_BUFFER;
  66.150 -    gss_name_t      service_name = GSS_C_NO_NAME;
  66.151 -    guint32         major_status;
  66.152 -    guint32         minor_status;
  66.153 -
  66.154 -    token.value	= g_strdup_printf ("xmpp@%s", sasl->server);
  66.155 -    token.length = strlen ((char *)token.value);
  66.156 -
  66.157 -    if (token.value == NULL) {
  66.158 -        return GSS_C_NO_NAME;
  66.159 -    }
  66.160 -
  66.161 -    major_status = gss_import_name (&minor_status, &token,
  66.162 -                                    GSS_C_NT_HOSTBASED_SERVICE,
  66.163 -                                    &service_name);
  66.164 -
  66.165 -    if (GSS_ERROR(major_status)) {
  66.166 -        sasl_gssapi_fail (sasl, "while obtaining service principal",
  66.167 -                          major_status, minor_status);
  66.168 -        return GSS_C_NO_NAME;
  66.169 -    }
  66.170 -
  66.171 -    return service_name;
  66.172 -}
  66.173 -
  66.174 -static gboolean
  66.175 -sasl_gssapi_start (LmSASL *sasl, LmMessageNode *node)
  66.176 -{
  66.177 -    gchar           *response64;
  66.178 -    gss_buffer_desc  input_buffer_desc;
  66.179 -    gss_buffer_t     input_buffer;
  66.180 -    gss_buffer_desc  output_buffer_desc;
  66.181 -    gss_buffer_t     output_buffer;
  66.182 -    guint32          major_status;
  66.183 -    guint32          minor_status;
  66.184 -
  66.185 -    sasl->gss_ctx = GSS_C_NO_CONTEXT;
  66.186 -    sasl->gss_service = sasl_gssapi_get_creds (sasl);
  66.187