connection.c revision a16e83f45d33ae5f3bd5966416c57c8ad4448ae8
196a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington/* -*- mode: C; c-file-style: "gnu" -*- */
296a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington/* connection.c  Client connections
396a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington *
496a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington * Copyright (C) 2003  Red Hat, Inc.
596a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington *
696a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington * Licensed under the Academic Free License version 1.2
796a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington *
896a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington * This program is free software; you can redistribute it and/or modify
996a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington * it under the terms of the GNU General Public License as published by
1096a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington * the Free Software Foundation; either version 2 of the License, or
1196a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington * (at your option) any later version.
1296a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington *
1396a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington * This program is distributed in the hope that it will be useful,
1496a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington * but WITHOUT ANY WARRANTY; without even the implied warranty of
1596a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1696a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington * GNU General Public License for more details.
1796a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington *
1896a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington * You should have received a copy of the GNU General Public License
1996a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington * along with this program; if not, write to the Free Software
2096a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
2196a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington *
2296a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington */
2396a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington#include "connection.h"
24aff24a72c18a43dbb6f2d85e6d2226a3c2ea8f10Anders Carlsson#include "driver.h"
2596a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington#include "loop.h"
2696a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington#include "services.h"
2796a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington#include <dbus/dbus-list.h>
2896a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
2996a9f80300b7794475a5451a60a07555ea3526beHavoc Penningtonstatic int connection_data_slot;
3096a9f80300b7794475a5451a60a07555ea3526beHavoc Penningtonstatic DBusList *connections = NULL;
3196a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
3296a9f80300b7794475a5451a60a07555ea3526beHavoc Penningtontypedef struct
3396a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington{
3496a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  DBusList *services_owned;
3596a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
36aff24a72c18a43dbb6f2d85e6d2226a3c2ea8f10Anders Carlsson  char *name;
3796a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington} BusConnectionData;
3896a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
3996a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington#define BUS_CONNECTION_DATA(connection) (dbus_connection_get_data ((connection), connection_data_slot))
4096a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
4196a9f80300b7794475a5451a60a07555ea3526beHavoc Penningtonstatic void
420363701c341796278041fb9ea7de80eaaf41479aHavoc Penningtonconnection_disconnect_handler (DBusConnection *connection,
430363701c341796278041fb9ea7de80eaaf41479aHavoc Pennington                               void           *data)
4496a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington{
4596a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  BusConnectionData *d;
4696a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  BusService *service;
471b9a4589f6836641ded324b7b5d003c5cbfb0b78Anders Carlsson
480363701c341796278041fb9ea7de80eaaf41479aHavoc Pennington  _dbus_warn ("Disconnected\n");
4996a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
5096a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  d = BUS_CONNECTION_DATA (connection);
510363701c341796278041fb9ea7de80eaaf41479aHavoc Pennington  _dbus_assert (d != NULL);
5296a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
5396a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  /* Drop any service ownership */
5496a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  while ((service = _dbus_list_get_last (&d->services_owned)))
5596a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington    bus_service_remove_owner (service, connection);
5696a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
57aff24a72c18a43dbb6f2d85e6d2226a3c2ea8f10Anders Carlsson  /* Tell bus driver that we want to get off */
58aff24a72c18a43dbb6f2d85e6d2226a3c2ea8f10Anders Carlsson  bus_driver_remove_connection (connection);
59aff24a72c18a43dbb6f2d85e6d2226a3c2ea8f10Anders Carlsson
6096a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  /* no more watching */
6196a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  dbus_connection_set_watch_functions (connection,
6296a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington                                       NULL, NULL,
6396a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington                                       connection,
6496a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington                                       NULL);
6596a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
6696a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  dbus_connection_set_data (connection,
6796a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington                            connection_data_slot,
6896a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington                            NULL, NULL);
6996a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
7096a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  _dbus_list_remove (&connections, connection);
7196a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  dbus_connection_unref (connection);
7296a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington}
7396a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
7496a9f80300b7794475a5451a60a07555ea3526beHavoc Penningtonstatic void
7596a9f80300b7794475a5451a60a07555ea3526beHavoc Penningtonconnection_watch_callback (DBusWatch     *watch,
7696a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington                           unsigned int   condition,
7796a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington                           void          *data)
7896a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington{
7996a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  DBusConnection *connection = data;
8096a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
8196a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  dbus_connection_handle_watch (connection, watch, condition);
82aff24a72c18a43dbb6f2d85e6d2226a3c2ea8f10Anders Carlsson
83aff24a72c18a43dbb6f2d85e6d2226a3c2ea8f10Anders Carlsson  while (dbus_connection_dispatch_message (connection));
8496a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington}
8596a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
8696a9f80300b7794475a5451a60a07555ea3526beHavoc Penningtonstatic void
8796a9f80300b7794475a5451a60a07555ea3526beHavoc Penningtonadd_connection_watch (DBusWatch      *watch,
8896a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington                      DBusConnection *connection)
8996a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington{
9096a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  bus_loop_add_watch (watch, connection_watch_callback, connection,
9196a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington                      NULL);
9296a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington}
9396a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
9496a9f80300b7794475a5451a60a07555ea3526beHavoc Penningtonstatic void
9596a9f80300b7794475a5451a60a07555ea3526beHavoc Penningtonremove_connection_watch (DBusWatch      *watch,
9696a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington                         DBusConnection *connection)
9796a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington{
9896a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  bus_loop_remove_watch (watch, connection_watch_callback, connection);
9996a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington}
10096a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
10196a9f80300b7794475a5451a60a07555ea3526beHavoc Penningtonstatic void
10296a9f80300b7794475a5451a60a07555ea3526beHavoc Penningtonfree_connection_data (void *data)
10396a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington{
10496a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  BusConnectionData *d = data;
10596a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
10696a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  /* services_owned should be NULL since we should be disconnected */
10796a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  _dbus_assert (d->services_owned == NULL);
108aff24a72c18a43dbb6f2d85e6d2226a3c2ea8f10Anders Carlsson
109aff24a72c18a43dbb6f2d85e6d2226a3c2ea8f10Anders Carlsson  dbus_free (d->name);
11096a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
11196a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  dbus_free (d);
11296a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington}
11396a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
11496a9f80300b7794475a5451a60a07555ea3526beHavoc Penningtondbus_bool_t
11596a9f80300b7794475a5451a60a07555ea3526beHavoc Penningtonbus_connection_init (void)
11696a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington{
11796a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  connection_data_slot = dbus_connection_allocate_data_slot ();
11896a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
11996a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  if (connection_data_slot < 0)
12096a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington    return FALSE;
12196a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
12296a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  return TRUE;
12396a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington}
12496a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
12596a9f80300b7794475a5451a60a07555ea3526beHavoc Penningtondbus_bool_t
12696a9f80300b7794475a5451a60a07555ea3526beHavoc Penningtonbus_connection_setup (DBusConnection *connection)
12796a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington{
12896a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  BusConnectionData *d;
12996a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
1301b9a4589f6836641ded324b7b5d003c5cbfb0b78Anders Carlsson  d = dbus_new0 (BusConnectionData, 1);
1311b9a4589f6836641ded324b7b5d003c5cbfb0b78Anders Carlsson
13296a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  if (d == NULL)
13396a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington    return FALSE;
13496a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
13596a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  if (!dbus_connection_set_data (connection,
13696a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington                                 connection_data_slot,
13796a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington                                 d, free_connection_data))
13896a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington    {
13996a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington      dbus_free (d);
14096a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington      return FALSE;
14196a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington    }
14296a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
14396a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  if (!_dbus_list_append (&connections, connection))
14496a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington    {
14596a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington      /* this will free our data when connection gets finalized */
14696a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington      dbus_connection_disconnect (connection);
14796a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington      return FALSE;
14896a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington    }
14996a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
15096a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  dbus_connection_ref (connection);
15196a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
15296a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  dbus_connection_set_watch_functions (connection,
15396a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington                                       (DBusAddWatchFunction) add_connection_watch,
15496a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington                                       (DBusRemoveWatchFunction) remove_connection_watch,
15596a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington                                       connection,
15696a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington                                       NULL);
15796a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
1580363701c341796278041fb9ea7de80eaaf41479aHavoc Pennington  dbus_connection_set_disconnect_function (connection,
1590363701c341796278041fb9ea7de80eaaf41479aHavoc Pennington                                           connection_disconnect_handler,
1600363701c341796278041fb9ea7de80eaaf41479aHavoc Pennington                                           NULL, NULL);
16196a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
162aff24a72c18a43dbb6f2d85e6d2226a3c2ea8f10Anders Carlsson  if (!bus_driver_add_connection (connection))
163aff24a72c18a43dbb6f2d85e6d2226a3c2ea8f10Anders Carlsson    return FALSE;
164aff24a72c18a43dbb6f2d85e6d2226a3c2ea8f10Anders Carlsson
16596a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  return TRUE;
16696a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington}
16796a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
16896a9f80300b7794475a5451a60a07555ea3526beHavoc Penningtondbus_bool_t
16996a9f80300b7794475a5451a60a07555ea3526beHavoc Penningtonbus_connection_add_owned_service (DBusConnection *connection,
17096a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington                                  BusService     *service)
17196a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington{
17296a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  BusConnectionData *d;
17396a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
17496a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  d = BUS_CONNECTION_DATA (connection);
17596a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  _dbus_assert (d != NULL);
17696a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
17796a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  if (!_dbus_list_append (&d->services_owned,
17896a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington                          service))
17996a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington    return FALSE;
18096a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
18196a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  return TRUE;
18296a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington}
18396a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
18496a9f80300b7794475a5451a60a07555ea3526beHavoc Penningtonvoid
18596a9f80300b7794475a5451a60a07555ea3526beHavoc Penningtonbus_connection_remove_owned_service (DBusConnection *connection,
18696a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington                                     BusService     *service)
18796a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington{
18896a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  BusConnectionData *d;
18996a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
19096a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  d = BUS_CONNECTION_DATA (connection);
19196a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  _dbus_assert (d != NULL);
19296a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington
19396a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington  _dbus_list_remove_last (&d->services_owned, service);
19496a9f80300b7794475a5451a60a07555ea3526beHavoc Pennington}
195aff24a72c18a43dbb6f2d85e6d2226a3c2ea8f10Anders Carlsson
196aff24a72c18a43dbb6f2d85e6d2226a3c2ea8f10Anders Carlssondbus_bool_t
197aff24a72c18a43dbb6f2d85e6d2226a3c2ea8f10Anders Carlssonbus_connection_set_name (DBusConnection   *connection,
198aff24a72c18a43dbb6f2d85e6d2226a3c2ea8f10Anders Carlsson			 const DBusString *name)
199aff24a72c18a43dbb6f2d85e6d2226a3c2ea8f10Anders Carlsson{
200aff24a72c18a43dbb6f2d85e6d2226a3c2ea8f10Anders Carlsson  const char *c_name;
201aff24a72c18a43dbb6f2d85e6d2226a3c2ea8f10Anders Carlsson  BusConnectionData *d;
202aff24a72c18a43dbb6f2d85e6d2226a3c2ea8f10Anders Carlsson
203aff24a72c18a43dbb6f2d85e6d2226a3c2ea8f10Anders Carlsson  d = BUS_CONNECTION_DATA (connection);
204aff24a72c18a43dbb6f2d85e6d2226a3c2ea8f10Anders Carlsson  _dbus_assert (d != NULL);
205aff24a72c18a43dbb6f2d85e6d2226a3c2ea8f10Anders Carlsson  _dbus_assert (d->name == NULL);
206aff24a72c18a43dbb6f2d85e6d2226a3c2ea8f10Anders Carlsson
207aff24a72c18a43dbb6f2d85e6d2226a3c2ea8f10Anders Carlsson  _dbus_string_get_const_data (name, &c_name);
208aff24a72c18a43dbb6f2d85e6d2226a3c2ea8f10Anders Carlsson
209aff24a72c18a43dbb6f2d85e6d2226a3c2ea8f10Anders Carlsson  d->name = _dbus_strdup (c_name);
210aff24a72c18a43dbb6f2d85e6d2226a3c2ea8f10Anders Carlsson
211aff24a72c18a43dbb6f2d85e6d2226a3c2ea8f10Anders Carlsson  if (d->name == NULL)
212aff24a72c18a43dbb6f2d85e6d2226a3c2ea8f10Anders Carlsson    return FALSE;
213aff24a72c18a43dbb6f2d85e6d2226a3c2ea8f10Anders Carlsson
214aff24a72c18a43dbb6f2d85e6d2226a3c2ea8f10Anders Carlsson  return TRUE;
215aff24a72c18a43dbb6f2d85e6d2226a3c2ea8f10Anders Carlsson}
216aff24a72c18a43dbb6f2d85e6d2226a3c2ea8f10Anders Carlsson
217aff24a72c18a43dbb6f2d85e6d2226a3c2ea8f10Anders Carlssonconst char *
218aff24a72c18a43dbb6f2d85e6d2226a3c2ea8f10Anders Carlssonbus_connection_get_name (DBusConnection *connection)
219aff24a72c18a43dbb6f2d85e6d2226a3c2ea8f10Anders Carlsson{
220aff24a72c18a43dbb6f2d85e6d2226a3c2ea8f10Anders Carlsson  BusConnectionData *d;
221aff24a72c18a43dbb6f2d85e6d2226a3c2ea8f10Anders Carlsson
222aff24a72c18a43dbb6f2d85e6d2226a3c2ea8f10Anders Carlsson  d = BUS_CONNECTION_DATA (connection);
223aff24a72c18a43dbb6f2d85e6d2226a3c2ea8f10Anders Carlsson  _dbus_assert (d != NULL);
224aff24a72c18a43dbb6f2d85e6d2226a3c2ea8f10Anders Carlsson
225aff24a72c18a43dbb6f2d85e6d2226a3c2ea8f10Anders Carlsson  return d->name;
226aff24a72c18a43dbb6f2d85e6d2226a3c2ea8f10Anders Carlsson}
227a16e83f45d33ae5f3bd5966416c57c8ad4448ae8Anders Carlsson
228a16e83f45d33ae5f3bd5966416c57c8ad4448ae8Anders Carlssonvoid
229a16e83f45d33ae5f3bd5966416c57c8ad4448ae8Anders Carlssonbus_connection_foreach (BusConnectionForeachFunction  function,
230a16e83f45d33ae5f3bd5966416c57c8ad4448ae8Anders Carlsson			void                         *data)
231a16e83f45d33ae5f3bd5966416c57c8ad4448ae8Anders Carlsson{
232a16e83f45d33ae5f3bd5966416c57c8ad4448ae8Anders Carlsson  _dbus_list_foreach (&connections, function, data);
233a16e83f45d33ae5f3bd5966416c57c8ad4448ae8Anders Carlsson}
234