Minor fixes and improvements. Deleted some not needed debug verboses.
[platform/upstream/dbus.git] / dbus / dbus-transport-kdbus.c
1 /*
2  * dbus-transport-kdbus.c
3  *
4  * Transport layer using kdbus
5  *
6  *  Created on: Jun 20, 2013
7  *      Author: r.pajak
8  *
9  *
10  */
11
12 #include "dbus-transport.h"
13 #include "dbus-transport-kdbus.h"
14 #include <dbus/dbus-transport-protected.h>
15 #include "dbus-connection-internal.h"
16 #include "kdbus.h"
17 #include "dbus-watch.h"
18 #include "dbus-errors.h"
19 #include "dbus-bus.h"
20 #include <linux/types.h>
21 #include <fcntl.h>
22 #include <errno.h>
23 #include <fcntl.h>
24 #include <sys/ioctl.h>
25 #include <stdio.h>
26 #include <string.h>
27 #include <stdlib.h>
28 #include <unistd.h>
29 #include <sys/mman.h>
30
31 #define KDBUS_ALIGN8(l) (((l) + 7) & ~7)
32 #define KDBUS_PART_HEADER_SIZE offsetof(struct kdbus_item, data)
33 #define KDBUS_ITEM_SIZE(s) KDBUS_ALIGN8((s) + KDBUS_PART_HEADER_SIZE)
34
35 #define KDBUS_PART_NEXT(part) \
36         (typeof(part))(((uint8_t *)part) + KDBUS_ALIGN8((part)->size))
37 #define KDBUS_PART_FOREACH(part, head, first)                           \
38         for (part = (head)->first;                                      \
39              (uint8_t *)(part) < (uint8_t *)(head) + (head)->size;      \
40              part = KDBUS_PART_NEXT(part))
41 #define POOL_SIZE (16 * 1024LU * 1024LU)  //todo pool size to be decided
42
43 /**
44  * Opaque object representing a socket file descriptor transport.
45  */
46 typedef struct DBusTransportSocket DBusTransportSocket;
47
48 /**
49  * Implementation details of DBusTransportSocket. All members are private.
50  */
51 struct DBusTransportSocket
52 {
53   DBusTransport base;                   /**< Parent instance */
54   int fd;                               /**< File descriptor. */
55   DBusWatch *read_watch;                /**< Watch for readability. */
56   DBusWatch *write_watch;               /**< Watch for writability. */
57
58   int max_bytes_read_per_iteration;     /**< To avoid blocking too long. */
59   int max_bytes_written_per_iteration;  /**< To avoid blocking too long. */
60
61   int message_bytes_written;            /**< Number of bytes of current
62                                          *   outgoing message that have
63                                          *   been written.
64                                          */
65   DBusString encoded_outgoing;          /**< Encoded version of current
66                                          *   outgoing message.
67                                          */
68   DBusString encoded_incoming;          /**< Encoded version of current
69                                          *   incoming data.
70                                          */
71   void* kdbus_mmap_ptr;
72 };
73
74
75
76 static dbus_bool_t
77 socket_get_socket_fd (DBusTransport *transport,
78                       int           *fd_p)
79 {
80   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
81
82   *fd_p = socket_transport->fd;
83
84   return TRUE;
85 }
86
87 /*
88  * Adds locally generated message to received messages queue
89  *
90  */
91 static dbus_bool_t add_message_to_received(DBusMessage *message, DBusTransport *transport)
92 {
93         DBusList *message_link;
94
95         message_link = _dbus_list_alloc_link (message);
96         if (message_link == NULL)
97         {
98                 /* it's OK to unref this, nothing that could have attached a callback
99                  * has ever seen it */
100                 dbus_message_unref (message);
101                 return FALSE;
102         }
103
104         _dbus_connection_queue_synthesized_message_link(transport->connection, message_link);
105
106         return TRUE;
107 }
108
109 static int kdbus_write_msg(DBusTransport *transport, DBusMessage *message, int fd)
110 {
111         struct kdbus_msg *msg;
112         struct kdbus_item *item;
113         uint64_t size;
114         const char *name;
115         uint64_t dst_id = KDBUS_DST_ID_BROADCAST;
116     const DBusString *header;
117     const DBusString *body;
118     uint64_t ret_size;
119     uint64_t body_size;
120
121 //    uint64_t i;
122
123     if((name = dbus_message_get_destination(message)))
124     {
125         if((name[0] == ':') && (name[1] == '1') && (name[2] == '.')) //if name starts with :1. it is a unique name and should be send as number
126         {
127                 dst_id = strtoll(&name[3], NULL, 10);
128                 name = NULL;
129         }
130         else
131                 dst_id = KDBUS_DST_ID_WELL_KNOWN_NAME;
132     }
133
134     _dbus_message_get_network_data (message, &header, &body);
135     ret_size = _dbus_string_get_length(header);
136     body_size = _dbus_string_get_length(body);
137
138   /*  fprintf (stderr, "\nheader:\n");
139     for(i=0; i < ret_size; i++)
140     {
141         fprintf (stderr, "%02x", _dbus_string_get_byte(header,i));
142     }
143     fprintf (stderr, "\nret size: %lu, i: %lu\n", ret_size, i);*/
144
145     size = sizeof(struct kdbus_msg);
146         size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
147         if(body_size) //body can be empty
148                 size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
149         if (name)
150                 size += KDBUS_ITEM_SIZE(strlen(name) + 1);
151         else if (dst_id == KDBUS_DST_ID_BROADCAST)
152                 size += KDBUS_PART_HEADER_SIZE + 64;
153
154         msg = malloc(size);
155         if (!msg)
156         {
157                 _dbus_verbose("Error allocating memory for: %s,%s\n", _dbus_strerror (errno), _dbus_error_from_errno (errno));
158                 return -1;
159         }
160
161         memset(msg, 0, size);
162         msg->size = size;
163         msg->src_id = strtoll(dbus_bus_get_unique_name(transport->connection), NULL , 10);
164         msg->dst_id = name ? 0 : dst_id;
165         msg->cookie = dbus_message_get_serial(message);
166         msg->payload_type = KDBUS_PAYLOAD_DBUS1;
167
168         item = msg->items;
169
170         if (name)
171         {
172                 item->type = KDBUS_MSG_DST_NAME;
173                 item->size = KDBUS_PART_HEADER_SIZE + strlen(name) + 1;
174                 strcpy(item->str, name);
175                 item = KDBUS_PART_NEXT(item);
176         }
177
178         item->type = KDBUS_MSG_PAYLOAD_VEC;
179         item->size = KDBUS_PART_HEADER_SIZE + sizeof(struct kdbus_vec);
180         item->vec.address = (unsigned long) _dbus_string_get_const_data(header);
181         item->vec.size = ret_size;
182
183         if(body_size)
184         {
185                 item = KDBUS_PART_NEXT(item);
186                 item->type = KDBUS_MSG_PAYLOAD_VEC;
187                 item->size = KDBUS_PART_HEADER_SIZE + sizeof(struct kdbus_vec);
188                 item->vec.address = (unsigned long) _dbus_string_get_const_data(body);
189                 item->vec.size = body_size;
190                 ret_size += body_size;
191         }
192
193   /*  fprintf (stderr, "\nbody:\n");
194     for(i=0; i < item->vec.size; i++)
195     {
196         fprintf (stderr, "%02x", _dbus_string_get_byte(body,i));
197     }
198     fprintf (stderr, "\nitem->vec.size: %llu, i: %lu\n", item->vec.size, i);*/
199
200         if (dst_id == KDBUS_DST_ID_BROADCAST)
201         {
202                 item = KDBUS_PART_NEXT(item);
203                 item->type = KDBUS_MSG_BLOOM;
204                 item->size = KDBUS_PART_HEADER_SIZE + 64;
205         }
206
207         again:
208         if (ioctl(fd, KDBUS_CMD_MSG_SEND, msg))
209         {
210                 if(errno == EINTR)
211                         goto again;
212                 if(errno == ENXIO)  //when recipient is not available on the bus
213                 {
214                         DBusMessage *errMessage;
215
216                         errMessage = generate_local_error_message(msg->cookie, "org.freedesktop.DBus.Error.ServiceUnknown", NULL);
217                         if(errMessage == NULL)
218                         {
219                                 ret_size = -1;
220                                 goto out;
221                         }
222                         dbus_message_set_reply_serial(errMessage, dbus_message_get_reply_serial(message));
223                         if (!add_message_to_received(errMessage, transport))
224                                 ret_size = -1;
225                         goto out;
226                 }
227                 _dbus_verbose("kdbus error sending message: err %d (%m)\n", errno);
228                 ret_size = -1;
229         }
230
231 out:
232         free(msg);
233         return ret_size;
234 }
235
236 static int kdbus_write_msg_encoded(DBusMessage *message, DBusTransportSocket *socket_transport)
237 {
238         struct kdbus_msg *msg;
239         struct kdbus_item *item;
240         uint64_t size;
241         const char *name;
242         uint64_t dst_id = KDBUS_DST_ID_BROADCAST;
243     uint64_t ret_size;
244
245     if((name = dbus_message_get_destination(message)))
246     {
247         if((name[0] == ':') && (name[1] == '1') && (name[2] == '.'))
248         {
249                 dst_id = strtoll(&name[2], NULL, 10);
250                 name = NULL;
251         }
252         else
253                 dst_id = KDBUS_DST_ID_WELL_KNOWN_NAME;
254     }
255
256     size = sizeof(struct kdbus_msg);
257         size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
258         if (name)
259                 size += KDBUS_ITEM_SIZE(strlen(name) + 1);
260         else if (dst_id == KDBUS_DST_ID_BROADCAST)
261                 size += KDBUS_PART_HEADER_SIZE + 64;
262
263         msg = malloc(size);
264         if (!msg)
265         {
266                 _dbus_verbose("Error allocating memory for: %s,%s\n", _dbus_strerror (errno), _dbus_error_from_errno (errno));
267                 return -1;
268         }
269
270         memset(msg, 0, size);
271         msg->size = size;
272         msg->src_id = strtoll(dbus_bus_get_unique_name(socket_transport->base.connection), NULL , 10);
273         _dbus_verbose("sending encoded msg, src_id=%llu\n", msg->src_id);
274         msg->dst_id = name ? 0 : dst_id;
275         msg->cookie = dbus_message_get_serial(message);
276         msg->payload_type = KDBUS_PAYLOAD_DBUS1;
277
278         item = msg->items;
279
280         if (name)
281         {
282                 item->type = KDBUS_MSG_DST_NAME;
283                 item->size = KDBUS_PART_HEADER_SIZE + strlen(name) + 1;
284                 strcpy(item->str, name);
285                 item = KDBUS_PART_NEXT(item);
286         }
287
288         item->type = KDBUS_MSG_PAYLOAD_VEC;
289         item->size = KDBUS_PART_HEADER_SIZE + sizeof(struct kdbus_vec);
290         item->vec.address = (unsigned long) &socket_transport->encoded_outgoing;
291         item->vec.size = _dbus_string_get_length (&socket_transport->encoded_outgoing);
292
293         if (dst_id == KDBUS_DST_ID_BROADCAST)
294         {
295                 item = KDBUS_PART_NEXT(item);
296                 item->type = KDBUS_MSG_BLOOM;
297                 item->size = KDBUS_PART_HEADER_SIZE + 64;
298         }
299
300         again:
301         if (ioctl(socket_transport->fd, KDBUS_CMD_MSG_SEND, msg))
302         {
303                 if(errno == EINTR)
304                         goto again;
305                 if(errno == ENXIO)  //when recipient is not available on the bus
306                 {
307                         DBusMessage *errMessage = NULL;
308
309                         errMessage = generate_local_error_message(msg->cookie, "org.freedesktop.DBus.Error.ServiceUnknown", NULL);
310                         if(errMessage == NULL)
311                         {
312                                 ret_size = -1;
313                                 goto out;
314                         }
315                         dbus_message_set_reply_serial(errMessage, dbus_message_get_reply_serial(message));
316                         if (!add_message_to_received(errMessage, &socket_transport->base))
317                                 ret_size = -1;
318                         goto out;
319                 }
320                 _dbus_verbose("error sending encoded message: err %d (%m)\n", errno);
321                 ret_size = -1;
322         }
323
324 out:
325         free(msg);
326         return ret_size;
327 }
328
329 //todo functions from kdbus-utli.c for printing messages - maybe to remove at the end
330 static char *msg_id(uint64_t id, char *buf)
331 {
332         if (id == 0)
333                 return "KERNEL";
334         if (id == ~0ULL)
335                 return "BROADCAST";
336         sprintf(buf, "%llu", (unsigned long long)id);
337         return buf;
338 }
339
340 struct kdbus_enum_table {
341         long long id;
342         const char *name;
343 };
344 #define _STRINGIFY(x) #x
345 #define STRINGIFY(x) _STRINGIFY(x)
346 #define ELEMENTSOF(x) (sizeof(x)/sizeof((x)[0]))
347 #define TABLE(what) static struct kdbus_enum_table kdbus_table_##what[]
348 #define ENUM(_id) { .id=_id, .name=STRINGIFY(_id) }
349 #define LOOKUP(what)                                                            \
350         const char *enum_##what(long long id) {                                 \
351         size_t i; \
352                 for (i = 0; i < ELEMENTSOF(kdbus_table_##what); i++)    \
353                         if (id == kdbus_table_##what[i].id)                     \
354                                 return kdbus_table_##what[i].name;              \
355                 return "UNKNOWN";                                               \
356         }
357 const char *enum_MSG(long long id);
358 TABLE(MSG) = {
359         ENUM(_KDBUS_MSG_NULL),
360         ENUM(KDBUS_MSG_PAYLOAD_VEC),
361         ENUM(KDBUS_MSG_PAYLOAD_OFF),
362         ENUM(KDBUS_MSG_PAYLOAD_MEMFD),
363         ENUM(KDBUS_MSG_FDS),
364         ENUM(KDBUS_MSG_BLOOM),
365         ENUM(KDBUS_MSG_DST_NAME),
366         ENUM(KDBUS_MSG_SRC_CREDS),
367         ENUM(KDBUS_MSG_SRC_PID_COMM),
368         ENUM(KDBUS_MSG_SRC_TID_COMM),
369         ENUM(KDBUS_MSG_SRC_EXE),
370         ENUM(KDBUS_MSG_SRC_CMDLINE),
371         ENUM(KDBUS_MSG_SRC_CGROUP),
372         ENUM(KDBUS_MSG_SRC_CAPS),
373         ENUM(KDBUS_MSG_SRC_SECLABEL),
374         ENUM(KDBUS_MSG_SRC_AUDIT),
375         ENUM(KDBUS_MSG_SRC_NAMES),
376         ENUM(KDBUS_MSG_TIMESTAMP),
377         ENUM(KDBUS_MSG_NAME_ADD),
378         ENUM(KDBUS_MSG_NAME_REMOVE),
379         ENUM(KDBUS_MSG_NAME_CHANGE),
380         ENUM(KDBUS_MSG_ID_ADD),
381         ENUM(KDBUS_MSG_ID_REMOVE),
382         ENUM(KDBUS_MSG_REPLY_TIMEOUT),
383         ENUM(KDBUS_MSG_REPLY_DEAD),
384 };
385 LOOKUP(MSG);
386 const char *enum_PAYLOAD(long long id);
387 TABLE(PAYLOAD) = {
388         ENUM(KDBUS_PAYLOAD_KERNEL),
389         ENUM(KDBUS_PAYLOAD_DBUS1),
390         ENUM(KDBUS_PAYLOAD_GVARIANT),
391 };
392 LOOKUP(PAYLOAD);
393
394 static int put_message_into_data(DBusMessage *message, char* data)
395 {
396         int ret_size;
397     const DBusString *header;
398     const DBusString *body;
399     int size;
400
401     dbus_message_lock (message);
402     _dbus_message_get_network_data (message, &header, &body);
403     ret_size = _dbus_string_get_length(header);
404         memcpy(data, _dbus_string_get_const_data(header), ret_size);
405         data += ret_size;
406         size = _dbus_string_get_length(body);
407         memcpy(data, _dbus_string_get_const_data(body), size);
408         ret_size += size;
409
410         return ret_size;
411 }
412
413 static int kdbus_decode_msg(const struct kdbus_msg* msg, char *data, void* mmap_ptr)
414 {
415         const struct kdbus_item *item = msg->items;
416         char buf[32];  //todo to be removed after development
417         int ret_size = 0;
418         DBusMessage *message = NULL;
419         DBusMessageIter args;
420         char* pStringMallocked = NULL;
421         const char* dbus = "org.freedesktop.DBus";
422         const char* emptyString = "";
423
424     const char* pString = NULL;
425
426         _dbus_verbose("MESSAGE: %s (%llu bytes) flags=0x%llx, %s â†’ %s, cookie=%llu, timeout=%llu\n",
427                 enum_PAYLOAD(msg->payload_type), (unsigned long long) msg->size,
428                 (unsigned long long) msg->flags,
429                 msg_id(msg->src_id, buf), msg_id(msg->dst_id, buf),
430                 (unsigned long long) msg->cookie, (unsigned long long) msg->timeout_ns);
431
432         KDBUS_PART_FOREACH(item, msg, items)
433         {
434                 if (item->size <= KDBUS_PART_HEADER_SIZE)
435                 {
436                         _dbus_verbose("  +%s (%llu bytes) invalid data record\n", enum_MSG(item->type), item->size);
437                         break;  //todo to be discovered and rewritten
438                 }
439
440                 switch (item->type)
441                 {
442                         case KDBUS_MSG_PAYLOAD_OFF:
443                                 memcpy(data, (char *)mmap_ptr + item->vec.offset, item->vec.size);
444                                 data += item->vec.size;
445                                 ret_size += item->vec.size;
446
447                                 _dbus_verbose("  +%s (%llu bytes) off=%llu size=%llu\n",
448                                            enum_MSG(item->type), item->size,
449                                            (unsigned long long)item->vec.offset,
450                                            (unsigned long long)item->vec.size);
451                         break;
452
453                         case KDBUS_MSG_PAYLOAD_MEMFD:  //todo
454                         {
455                                 char *buf;
456                                 uint64_t size;
457
458                                 buf = mmap(NULL, item->memfd.size, PROT_READ, MAP_SHARED, item->memfd.fd, 0);
459                                 if (buf == MAP_FAILED) {
460                                         _dbus_verbose("mmap() fd=%i failed:%m", item->memfd.fd);
461                                         break;
462                                 }
463
464                                 if (ioctl(item->memfd.fd, KDBUS_CMD_MEMFD_SIZE_GET, &size) < 0) {
465                                         _dbus_verbose("KDBUS_CMD_MEMFD_SIZE_GET failed: %m\n");
466                                         break;
467                                 }
468
469                                 _dbus_verbose("  +%s (%llu bytes) fd=%i size=%llu filesize=%llu '%s'\n",
470                                            enum_MSG(item->type), item->size, item->memfd.fd,
471                                            (unsigned long long)item->memfd.size, (unsigned long long)size, buf);
472
473                                 memcpy(data, buf, size);
474                                 data += size;
475                                 ret_size += size;
476                                 break;
477                         }
478
479                 /*      case KDBUS_MSG_SRC_CREDS:
480                                 _dbus_verbose("  +%s (%llu bytes) uid=%lld, gid=%lld, pid=%lld, tid=%lld, starttime=%lld\n",
481                                         enum_MSG(item->type), item->size,
482                                         item->creds.uid, item->creds.gid,
483                                         item->creds.pid, item->creds.tid,
484                                         item->creds.starttime);
485                         break;
486
487                         case KDBUS_MSG_SRC_PID_COMM:
488                         case KDBUS_MSG_SRC_TID_COMM:
489                         case KDBUS_MSG_SRC_EXE:
490                         case KDBUS_MSG_SRC_CGROUP:
491                         case KDBUS_MSG_SRC_SECLABEL:
492                         case KDBUS_MSG_DST_NAME:
493                                 _dbus_verbose("  +%s (%llu bytes) '%s' (%zu)\n",
494                                            enum_MSG(item->type), item->size, item->str, strlen(item->str));
495                                 break;
496
497                         case KDBUS_MSG_SRC_CMDLINE:
498                         case KDBUS_MSG_SRC_NAMES: {
499                                 size_t size = item->size - KDBUS_PART_HEADER_SIZE;
500                                 const char *str = item->str;
501                                 int count = 0;
502
503                                 _dbus_verbose("  +%s (%llu bytes) ", enum_MSG(item->type), item->size);
504                                 while (size) {
505                                         _dbus_verbose("'%s' ", str);
506                                         size -= strlen(str) + 1;
507                                         str += strlen(str) + 1;
508                                         count++;
509                                 }
510
511                                 _dbus_verbose("(%d string%s)\n", count, (count == 1) ? "" : "s");
512                                 break;
513                         }
514
515                         case KDBUS_MSG_SRC_AUDIT:
516                                 _dbus_verbose("  +%s (%llu bytes) loginuid=%llu sessionid=%llu\n",
517                                            enum_MSG(item->type), item->size,
518                                            (unsigned long long)item->data64[0],
519                                            (unsigned long long)item->data64[1]);
520                                 break;
521
522                         case KDBUS_MSG_SRC_CAPS: {
523                                 int n;
524                                 const uint32_t *cap;
525                                 int i;
526
527                                 _dbus_verbose("  +%s (%llu bytes) len=%llu bytes)\n",
528                                            enum_MSG(item->type), item->size,
529                                            (unsigned long long)item->size - KDBUS_PART_HEADER_SIZE);
530
531                                 cap = item->data32;
532                                 n = (item->size - KDBUS_PART_HEADER_SIZE) / 4 / sizeof(uint32_t);
533
534                                 _dbus_verbose("    CapInh=");
535                                 for (i = 0; i < n; i++)
536                                         _dbus_verbose("%08x", cap[(0 * n) + (n - i - 1)]);
537
538                                 _dbus_verbose(" CapPrm=");
539                                 for (i = 0; i < n; i++)
540                                         _dbus_verbose("%08x", cap[(1 * n) + (n - i - 1)]);
541
542                                 _dbus_verbose(" CapEff=");
543                                 for (i = 0; i < n; i++)
544                                         _dbus_verbose("%08x", cap[(2 * n) + (n - i - 1)]);
545
546                                 _dbus_verbose(" CapInh=");
547                                 for (i = 0; i < n; i++)
548                                         _dbus_verbose("%08x", cap[(3 * n) + (n - i - 1)]);
549                                 _dbus_verbose("\n");
550                                 break;
551                         }
552
553                         case KDBUS_MSG_TIMESTAMP:
554                                 _dbus_verbose("  +%s (%llu bytes) realtime=%lluns monotonic=%lluns\n",
555                                            enum_MSG(item->type), item->size,
556                                            (unsigned long long)item->timestamp.realtime_ns,
557                                            (unsigned long long)item->timestamp.monotonic_ns);
558                                 break;*/
559
560                         case KDBUS_MSG_REPLY_TIMEOUT:
561                                 _dbus_verbose("  +%s (%llu bytes) cookie=%llu\n",
562                                            enum_MSG(item->type), item->size, msg->cookie_reply);
563
564                                 message = generate_local_error_message(msg->cookie_reply, "org.freedesktop.DBus.Error.NoReply", NULL);
565                                 if(message == NULL)
566                                 {
567                                         ret_size = -1;
568                                         goto out;
569                                 }
570
571                                 ret_size = put_message_into_data(message, data);
572                         break;
573
574                         case KDBUS_MSG_NAME_ADD:
575                                 _dbus_verbose("  +%s (%llu bytes) '%s', old id=%lld, new id=%lld, flags=0x%llx\n",
576                                         enum_MSG(item->type), (unsigned long long) item->size,
577                                         item->name_change.name, item->name_change.old_id,
578                                         item->name_change.new_id, item->name_change.flags);
579
580                                 pStringMallocked = malloc (sizeof(item->name_change.new_id)*2.5 + 4);
581                                 if(pStringMallocked)
582                                 {
583                                         strcpy(pStringMallocked,":1.");
584                                         sprintf(&pStringMallocked[3],"%llu",item->name_change.new_id);
585                                 }
586                                 else
587                                         return -1;
588
589                                 message = dbus_message_new_signal("/org/freedesktop/DBus", // object name of the signal
590                                             dbus, // interface name of the signal
591                                             "NameOwnerChanged"); // name of the signal
592                                 if(message == NULL)
593                                 {
594                                         ret_size = -1;
595                                         goto out;
596                                 }
597
598                                 pString = item->name_change.name;
599                                 _dbus_verbose ("Name added: %s\n", pString);
600                             dbus_message_iter_init_append(message, &args);
601                             if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING,&pString))
602                                 {
603                                         ret_size = -1;
604                                 goto out;
605                                 }
606                             if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &emptyString))
607                                 {
608                                         ret_size = -1;
609                                 goto out;
610                                 }
611                             if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &pStringMallocked))
612                                 {
613                                         ret_size = -1;
614                                 goto out;
615                                 }
616
617                                 dbus_message_set_sender(message, dbus);
618                                 dbus_message_set_serial(message, 1);
619
620                                 ret_size = put_message_into_data(message, data);
621                         break;
622
623                         case KDBUS_MSG_NAME_REMOVE:
624                                 _dbus_verbose("  +%s (%llu bytes) '%s', old id=%lld, new id=%lld, flags=0x%llx\n",
625                                         enum_MSG(item->type), (unsigned long long) item->size,
626                                         item->name_change.name, item->name_change.old_id,
627                                         item->name_change.new_id, item->name_change.flags);
628
629                                 pStringMallocked = malloc (sizeof(item->name_change.old_id)*2.5 + 4);
630                                 if(pStringMallocked)
631                                 {
632                                         strcpy(pStringMallocked,":1.");
633                                         sprintf(&pStringMallocked[3],"%llu",item->name_change.old_id);
634                                 }
635                                 else
636                                         return -1;
637
638                                 message = dbus_message_new_signal("/org/freedesktop/DBus", // object name of the signal
639                                             dbus, // interface name of the signal
640                                             "NameOwnerChanged"); // name of the signal
641                                 if(message == NULL)
642                                 {
643                                         ret_size = -1;
644                                         goto out;
645                                 }
646
647                                 pString = item->name_change.name;
648                                 _dbus_verbose ("Name removed: %s\n", pString);
649                             dbus_message_iter_init_append(message, &args);
650                             if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING,&pString))
651                                 {
652                                         ret_size = -1;
653                                 goto out;
654                                 }
655                             if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &pStringMallocked))
656                                 {
657                                         ret_size = -1;
658                                 goto out;
659                                 }
660                             if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &emptyString))
661                                 {
662                                         ret_size = -1;
663                                 goto out;
664                                 }
665
666                                 dbus_message_set_sender(message, dbus);
667                                 dbus_message_set_serial(message, 1);
668
669                                 ret_size = put_message_into_data(message, data);
670                         break;
671
672                         case KDBUS_MSG_NAME_CHANGE:
673                                 _dbus_verbose("  +%s (%llu bytes) '%s', old id=%lld, new id=%lld, flags=0x%llx\n",
674                                         enum_MSG(item->type), (unsigned long long) item->size,
675                                         item->name_change.name, item->name_change.old_id,
676                                         item->name_change.new_id, item->name_change.flags);
677
678                                 pStringMallocked = malloc (sizeof(item->name_change.new_id)*2.5 + 4);
679                                 if(pStringMallocked)
680                                 {
681                                         strcpy(pStringMallocked,":1.");
682                                         sprintf(&pStringMallocked[3],"%llu",item->name_change.old_id);
683                                 }
684                                 else
685                                         return -1;
686
687                                 message = dbus_message_new_signal("/org/freedesktop/DBus", // object name of the signal
688                                             dbus, // interface name of the signal
689                                             "NameOwnerChanged"); // name of the signal
690                                 if(message == NULL)
691                                 {
692                                         ret_size = -1;
693                                         goto out;
694                                 }
695
696                                 pString = item->name_change.name;
697                                 _dbus_verbose ("Name changed: %s\n", pString);
698                             dbus_message_iter_init_append(message, &args);
699                             if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING,&pString))
700                                 {
701                                         ret_size = -1;
702                                 goto out;
703                                 }
704                             if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &pStringMallocked))
705                                 {
706                                         ret_size = -1;
707                                 goto out;
708                                 }
709                             sprintf(&pStringMallocked[3],"%llu",item->name_change.new_id);
710                             _dbus_verbose ("New id: %s\n", pStringMallocked);  //todo to be removed
711                             if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &pStringMallocked))
712                                 {
713                                         ret_size = -1;
714                                 goto out;
715                                 }
716
717                                 dbus_message_set_sender(message, dbus);
718                                 dbus_message_set_serial(message, 1);
719
720                                 ret_size = put_message_into_data(message, data);
721                         break;
722
723                         case KDBUS_MSG_ID_ADD:
724                                 _dbus_verbose("  +%s (%llu bytes) id=%llu flags=%llu\n",
725                                            enum_MSG(item->type), (unsigned long long) item->size,
726                                            (unsigned long long) item->id_change.id,
727                                            (unsigned long long) item->id_change.flags);
728
729                                 pStringMallocked = malloc (sizeof(item->id_change.id)*2.5 + 4);
730                                 if(pStringMallocked)
731                                 {
732                                         strcpy(pStringMallocked,":1.");
733                                         sprintf(&pStringMallocked[3],"%llu",item->id_change.id);
734                                 }
735                                 else
736                                         return -1;
737
738                                 message = dbus_message_new_signal("/org/freedesktop/DBus", // object name of the signal
739                                             dbus, // interface name of the signal
740                                             "NameOwnerChanged"); // name of the signal
741                                 if(message == NULL)
742                                 {
743                                         ret_size = -1;
744                                         goto out;
745                                 }
746
747                             dbus_message_iter_init_append(message, &args);
748                             if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &pStringMallocked))
749                                 {
750                                         ret_size = -1;
751                                 goto out;
752                                 }
753                             if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &emptyString))
754                                 {
755                                         ret_size = -1;
756                                 goto out;
757                                 }
758                             if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &pStringMallocked))
759                                 {
760                                         ret_size = -1;
761                                 goto out;
762                                 }
763
764                                 dbus_message_set_sender(message, dbus);
765                                 dbus_message_set_serial(message, 1);
766
767                                 ret_size = put_message_into_data(message, data);
768                         break;
769
770                         case KDBUS_MSG_ID_REMOVE:
771                                 _dbus_verbose("  +%s (%llu bytes) id=%llu flags=%llu\n",
772                                            enum_MSG(item->type), (unsigned long long) item->size,
773                                            (unsigned long long) item->id_change.id,
774                                            (unsigned long long) item->id_change.flags);
775
776                                 pStringMallocked = malloc (sizeof(item->id_change.id)*2.5 + 4);
777                                 if(pStringMallocked)
778                                 {
779                                         strcpy(pStringMallocked,":1.");
780                                         sprintf(&pStringMallocked[3],"%llu",item->id_change.id);
781                                 }
782                                 else
783                                         return -1;
784
785                                 message = dbus_message_new_signal("/org/freedesktop/DBus", // object name of the signal
786                                             dbus, // interface name of the signal
787                                             "NameOwnerChanged"); // name of the signal
788                                 if(message == NULL)
789                                 {
790                                         ret_size = -1;
791                                         goto out;
792                                 }
793
794                             dbus_message_iter_init_append(message, &args);
795                             if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &pStringMallocked))
796                                 {
797                                         ret_size = -1;
798                                 goto out;
799                                 }
800                             if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &pStringMallocked))
801                                 {
802                                         ret_size = -1;
803                                 goto out;
804                                 }
805                             if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &emptyString))
806                                 {
807                                         ret_size = -1;
808                                 goto out;
809                                 }
810
811                                 dbus_message_set_sender(message, dbus);
812                                 dbus_message_set_serial(message, 1);
813
814                                 ret_size = put_message_into_data(message, data);
815                         break;
816
817                 /*      default:
818                                 _dbus_verbose("  +%s (%llu bytes)\n", enum_MSG(item->type), item->size);
819                                 break;*/
820                 }
821         }
822
823         /*if ((char *)item - ((char *)msg + msg->size) >= 8)
824                 _dbus_verbose("invalid padding at end of message\n");*/
825
826 out:
827         if(message)
828                 dbus_message_unref(message);
829         if(pStringMallocked)
830                 free((void*)pStringMallocked);
831         return ret_size;
832 }
833
834 static int kdbus_read_message(DBusTransportSocket *socket_transport, DBusString *buffer)
835 {
836         int ret_size;
837         uint64_t offset;
838         struct kdbus_msg *msg;
839 //      int start;
840         char *data;
841
842         _dbus_assert (socket_transport->max_bytes_read_per_iteration >= 0);
843 //      start = _dbus_string_get_length (buffer);
844 //      _dbus_verbose("read start: %d                          !!!!!!!!!!!!!!!   \n", start);
845         if (!_dbus_string_lengthen (buffer, socket_transport->max_bytes_read_per_iteration))
846         {
847                 errno = ENOMEM;
848             return -1;
849         }
850         data = _dbus_string_get_data_len (buffer, /*start*/0, socket_transport->max_bytes_read_per_iteration);
851
852         again:
853         if (ioctl(socket_transport->fd, KDBUS_CMD_MSG_RECV, &offset) < 0)
854         {
855                 if(errno == EINTR)
856                         goto again;
857                 _dbus_verbose("kdbus error receiving message: %d (%m)\n", errno);
858                 _dbus_string_set_length (buffer, /*start*/0);
859                 return -1;
860         }
861
862         msg = (struct kdbus_msg *)((char*)socket_transport->kdbus_mmap_ptr + offset);
863
864         ret_size = kdbus_decode_msg(msg, data, socket_transport->kdbus_mmap_ptr);
865         _dbus_string_set_length (buffer, /*start +*/ ret_size);
866
867         again2:
868         if (ioctl(socket_transport->fd, KDBUS_CMD_MSG_RELEASE, &offset) < 0)
869         {
870                 if(errno == EINTR)
871                         goto again2;
872                 _dbus_verbose("kdbus error freeing message: %d (%m)\n", errno);
873                 return -1;
874         }
875
876         return ret_size;
877 }
878
879 static void
880 free_watches (DBusTransport *transport)
881 {
882   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
883
884   _dbus_verbose ("start\n");
885
886   if (socket_transport->read_watch)
887     {
888       if (transport->connection)
889         _dbus_connection_remove_watch_unlocked (transport->connection,
890                                                 socket_transport->read_watch);
891       _dbus_watch_invalidate (socket_transport->read_watch);
892       _dbus_watch_unref (socket_transport->read_watch);
893       socket_transport->read_watch = NULL;
894     }
895
896   if (socket_transport->write_watch)
897     {
898       if (transport->connection)
899         _dbus_connection_remove_watch_unlocked (transport->connection,
900                                                 socket_transport->write_watch);
901       _dbus_watch_invalidate (socket_transport->write_watch);
902       _dbus_watch_unref (socket_transport->write_watch);
903       socket_transport->write_watch = NULL;
904     }
905
906   _dbus_verbose ("end\n");
907 }
908
909 static void
910 socket_finalize (DBusTransport *transport)
911 {
912   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
913
914   _dbus_verbose ("\n");
915
916   free_watches (transport);
917
918   _dbus_string_free (&socket_transport->encoded_outgoing);
919   _dbus_string_free (&socket_transport->encoded_incoming);
920
921   _dbus_transport_finalize_base (transport);
922
923   _dbus_assert (socket_transport->read_watch == NULL);
924   _dbus_assert (socket_transport->write_watch == NULL);
925
926   dbus_free (transport);
927 }
928
929 static void
930 check_write_watch (DBusTransport *transport)
931 {
932   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
933   dbus_bool_t needed;
934
935   if (transport->connection == NULL)
936     return;
937
938   if (transport->disconnected)
939     {
940       _dbus_assert (socket_transport->write_watch == NULL);
941       return;
942     }
943
944   _dbus_transport_ref (transport);
945
946   if (_dbus_transport_get_is_authenticated (transport))
947     needed = _dbus_connection_has_messages_to_send_unlocked (transport->connection);
948   else
949     {
950       if (transport->send_credentials_pending)
951         needed = TRUE;
952       else
953         {
954           DBusAuthState auth_state;
955
956           auth_state = _dbus_auth_do_work (transport->auth);
957
958           /* If we need memory we install the write watch just in case,
959            * if there's no need for it, it will get de-installed
960            * next time we try reading.
961            */
962           if (auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND ||
963               auth_state == DBUS_AUTH_STATE_WAITING_FOR_MEMORY)
964             needed = TRUE;
965           else
966             needed = FALSE;
967         }
968     }
969
970   _dbus_verbose ("check_write_watch(): needed = %d on connection %p watch %p fd = %d outgoing messages exist %d\n",
971                  needed, transport->connection, socket_transport->write_watch,
972                  socket_transport->fd,
973                  _dbus_connection_has_messages_to_send_unlocked (transport->connection));
974
975   _dbus_connection_toggle_watch_unlocked (transport->connection,
976                                           socket_transport->write_watch,
977                                           needed);
978
979   _dbus_transport_unref (transport);
980 }
981
982 static void
983 check_read_watch (DBusTransport *transport)
984 {
985   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
986   dbus_bool_t need_read_watch;
987
988   _dbus_verbose ("fd = %d\n",socket_transport->fd);
989
990   if (transport->connection == NULL)
991     return;
992
993   if (transport->disconnected)
994     {
995       _dbus_assert (socket_transport->read_watch == NULL);
996       return;
997     }
998
999   _dbus_transport_ref (transport);
1000
1001   if (_dbus_transport_get_is_authenticated (transport))
1002     need_read_watch =
1003       (_dbus_counter_get_size_value (transport->live_messages) < transport->max_live_messages_size) &&
1004       (_dbus_counter_get_unix_fd_value (transport->live_messages) < transport->max_live_messages_unix_fds);
1005   else
1006     {
1007       if (transport->receive_credentials_pending)
1008         need_read_watch = TRUE;
1009       else
1010         {
1011           /* The reason to disable need_read_watch when not WAITING_FOR_INPUT
1012            * is to avoid spinning on the file descriptor when we're waiting
1013            * to write or for some other part of the auth process
1014            */
1015           DBusAuthState auth_state;
1016
1017           auth_state = _dbus_auth_do_work (transport->auth);
1018
1019           /* If we need memory we install the read watch just in case,
1020            * if there's no need for it, it will get de-installed
1021            * next time we try reading. If we're authenticated we
1022            * install it since we normally have it installed while
1023            * authenticated.
1024            */
1025           if (auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT ||
1026               auth_state == DBUS_AUTH_STATE_WAITING_FOR_MEMORY ||
1027               auth_state == DBUS_AUTH_STATE_AUTHENTICATED)
1028             need_read_watch = TRUE;
1029           else
1030             need_read_watch = FALSE;
1031         }
1032     }
1033
1034   _dbus_verbose ("  setting read watch enabled = %d\n", need_read_watch);
1035   _dbus_connection_toggle_watch_unlocked (transport->connection,
1036                                           socket_transport->read_watch,
1037                                           need_read_watch);
1038
1039   _dbus_transport_unref (transport);
1040 }
1041
1042 static void
1043 do_io_error (DBusTransport *transport)
1044 {
1045   _dbus_transport_ref (transport);
1046   _dbus_transport_disconnect (transport);
1047   _dbus_transport_unref (transport);
1048 }
1049
1050 /* return value is whether we successfully read any new data. */
1051 static dbus_bool_t
1052 read_data_into_auth (DBusTransport *transport,
1053                      dbus_bool_t   *oom)
1054 {
1055   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1056   DBusString *buffer;
1057   int bytes_read;
1058
1059   *oom = FALSE;
1060
1061   _dbus_auth_get_buffer (transport->auth, &buffer);
1062
1063   bytes_read = kdbus_read_message(socket_transport, buffer);
1064
1065   _dbus_auth_return_buffer (transport->auth, buffer,
1066                             bytes_read > 0 ? bytes_read : 0);
1067
1068   if (bytes_read > 0)
1069     {
1070       _dbus_verbose (" read %d bytes in auth phase\n", bytes_read);
1071       return TRUE;
1072     }
1073   else if (bytes_read < 0)
1074     {
1075       /* EINTR already handled for us */
1076
1077       if (_dbus_get_is_errno_enomem ())
1078         {
1079           *oom = TRUE;
1080         }
1081       else if (_dbus_get_is_errno_eagain_or_ewouldblock ())
1082         ; /* do nothing, just return FALSE below */
1083       else
1084         {
1085           _dbus_verbose ("Error reading from remote app: %s\n",
1086                          _dbus_strerror_from_errno ());
1087           do_io_error (transport);
1088         }
1089
1090       return FALSE;
1091     }
1092   else
1093     {
1094       _dbus_assert (bytes_read == 0);
1095
1096       _dbus_verbose ("Disconnected from remote app\n");
1097       do_io_error (transport);
1098
1099       return FALSE;
1100     }
1101 }
1102
1103 /* Return value is whether we successfully wrote any bytes */
1104 static dbus_bool_t
1105 write_data_from_auth (DBusTransport *transport)  //todo change to kdbus
1106 {
1107   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1108   int bytes_written;
1109   const DBusString *buffer;
1110
1111   if (!_dbus_auth_get_bytes_to_send (transport->auth,
1112                                      &buffer))
1113     return FALSE;
1114
1115   bytes_written = _dbus_write_socket (socket_transport->fd,
1116                                       buffer,
1117                                       0, _dbus_string_get_length (buffer));
1118
1119   if (bytes_written > 0)
1120     {
1121       _dbus_auth_bytes_sent (transport->auth, bytes_written);
1122       return TRUE;
1123     }
1124   else if (bytes_written < 0)
1125     {
1126       /* EINTR already handled for us */
1127
1128       if (_dbus_get_is_errno_eagain_or_ewouldblock ())
1129         ;
1130       else
1131         {
1132           _dbus_verbose ("Error writing to remote app: %s\n",
1133                          _dbus_strerror_from_errno ());
1134           do_io_error (transport);
1135         }
1136     }
1137
1138   return FALSE;
1139 }
1140
1141 /* FALSE on OOM */
1142 static dbus_bool_t
1143 exchange_credentials (DBusTransport *transport,
1144                       dbus_bool_t    do_reading,
1145                       dbus_bool_t    do_writing)
1146 {
1147   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1148   DBusError error = DBUS_ERROR_INIT;
1149
1150   _dbus_verbose ("exchange_credentials: do_reading = %d, do_writing = %d\n",
1151                   do_reading, do_writing);
1152
1153   if (do_writing && transport->send_credentials_pending)
1154     {
1155       if (_dbus_send_credentials_socket (socket_transport->fd,
1156                                          &error))
1157         {
1158           transport->send_credentials_pending = FALSE;
1159         }
1160       else
1161         {
1162           _dbus_verbose ("Failed to write credentials: %s\n", error.message);
1163           dbus_error_free (&error);
1164           do_io_error (transport);
1165         }
1166     }
1167
1168   if (do_reading && transport->receive_credentials_pending)
1169     {
1170       /* FIXME this can fail due to IO error _or_ OOM, broken
1171        * (somewhat tricky to fix since the OOM error can be set after
1172        * we already read the credentials byte, so basically we need to
1173        * separate reading the byte and storing it in the
1174        * transport->credentials). Does not really matter for now
1175        * because storing in credentials never actually fails on unix.
1176        */
1177       if (_dbus_read_credentials_socket (socket_transport->fd,
1178                                          transport->credentials,
1179                                          &error))
1180         {
1181           transport->receive_credentials_pending = FALSE;
1182         }
1183       else
1184         {
1185           _dbus_verbose ("Failed to read credentials %s\n", error.message);
1186           dbus_error_free (&error);
1187           do_io_error (transport);
1188         }
1189     }
1190
1191   if (!(transport->send_credentials_pending ||
1192         transport->receive_credentials_pending))
1193     {
1194       if (!_dbus_auth_set_credentials (transport->auth,
1195                                        transport->credentials))
1196         return FALSE;
1197     }
1198
1199   return TRUE;
1200 }
1201
1202 static dbus_bool_t
1203 do_authentication (DBusTransport *transport,
1204                    dbus_bool_t    do_reading,
1205                    dbus_bool_t    do_writing,
1206                    dbus_bool_t   *auth_completed)
1207 {
1208   dbus_bool_t oom;
1209   dbus_bool_t orig_auth_state;
1210
1211   oom = FALSE;
1212
1213   orig_auth_state = _dbus_transport_get_is_authenticated (transport);
1214
1215   /* This is essential to avoid the check_write_watch() at the end,
1216    * we don't want to add a write watch in do_iteration before
1217    * we try writing and get EAGAIN
1218    */
1219   if (orig_auth_state)
1220     {
1221       if (auth_completed)
1222         *auth_completed = FALSE;
1223       return TRUE;
1224     }
1225
1226   _dbus_transport_ref (transport);
1227
1228   while (!_dbus_transport_get_is_authenticated (transport) &&
1229          _dbus_transport_get_is_connected (transport))
1230     {
1231       if (!exchange_credentials (transport, do_reading, do_writing))
1232         {
1233           /* OOM */
1234           oom = TRUE;
1235           goto out;
1236         }
1237
1238       if (transport->send_credentials_pending ||
1239           transport->receive_credentials_pending)
1240         {
1241           _dbus_verbose ("send_credentials_pending = %d receive_credentials_pending = %d\n",
1242                          transport->send_credentials_pending,
1243                          transport->receive_credentials_pending);
1244           goto out;
1245         }
1246
1247 #define TRANSPORT_SIDE(t) ((t)->is_server ? "server" : "client")
1248       switch (_dbus_auth_do_work (transport->auth))
1249         {
1250         case DBUS_AUTH_STATE_WAITING_FOR_INPUT:
1251           _dbus_verbose (" %s auth state: waiting for input\n",
1252                          TRANSPORT_SIDE (transport));
1253           if (!do_reading || !read_data_into_auth (transport, &oom))
1254             goto out;
1255           break;
1256
1257         case DBUS_AUTH_STATE_WAITING_FOR_MEMORY:
1258           _dbus_verbose (" %s auth state: waiting for memory\n",
1259                          TRANSPORT_SIDE (transport));
1260           oom = TRUE;
1261           goto out;
1262           break;
1263
1264         case DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND:
1265           _dbus_verbose (" %s auth state: bytes to send\n",
1266                          TRANSPORT_SIDE (transport));
1267           if (!do_writing || !write_data_from_auth (transport))
1268             goto out;
1269           break;
1270
1271         case DBUS_AUTH_STATE_NEED_DISCONNECT:
1272           _dbus_verbose (" %s auth state: need to disconnect\n",
1273                          TRANSPORT_SIDE (transport));
1274           do_io_error (transport);
1275           break;
1276
1277         case DBUS_AUTH_STATE_AUTHENTICATED:
1278           _dbus_verbose (" %s auth state: authenticated\n",
1279                          TRANSPORT_SIDE (transport));
1280           break;
1281         }
1282     }
1283
1284  out:
1285   if (auth_completed)
1286     *auth_completed = (orig_auth_state != _dbus_transport_get_is_authenticated (transport));
1287
1288   check_read_watch (transport);
1289   check_write_watch (transport);
1290   _dbus_transport_unref (transport);
1291
1292   if (oom)
1293     return FALSE;
1294   else
1295     return TRUE;
1296 }
1297
1298 /* returns false on oom */
1299 static dbus_bool_t
1300 do_writing (DBusTransport *transport)
1301 {
1302         int total;
1303         DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1304         dbus_bool_t oom;
1305
1306         /* No messages without authentication! */
1307         if (!_dbus_transport_get_is_authenticated (transport))
1308     {
1309                 _dbus_verbose ("Not authenticated, not writing anything\n");
1310                 return TRUE;
1311     }
1312
1313         if (transport->disconnected)
1314     {
1315                 _dbus_verbose ("Not connected, not writing anything\n");
1316                 return TRUE;
1317     }
1318
1319 #if 1
1320         _dbus_verbose ("do_writing(), have_messages = %d, fd = %d\n",
1321                  _dbus_connection_has_messages_to_send_unlocked (transport->connection),
1322                  socket_transport->fd);
1323 #endif
1324
1325         oom = FALSE;
1326         total = 0;
1327
1328         while (!transport->disconnected && _dbus_connection_has_messages_to_send_unlocked (transport->connection))
1329     {
1330                 int bytes_written;
1331                 DBusMessage *message;
1332                 const DBusString *header;
1333                 const DBusString *body;
1334                 int total_bytes_to_write;
1335
1336
1337                 if (total > socket_transport->max_bytes_written_per_iteration)
1338         {
1339                         _dbus_verbose ("%d bytes exceeds %d bytes written per iteration, returning\n",
1340                          total, socket_transport->max_bytes_written_per_iteration);
1341                         goto out;
1342         }
1343
1344                 message = _dbus_connection_get_message_to_send (transport->connection);
1345                 _dbus_assert (message != NULL);
1346                 dbus_message_lock (message);
1347                 _dbus_message_get_network_data (message, &header, &body);
1348
1349                 if (_dbus_auth_needs_encoding (transport->auth))
1350         {
1351                         // Does fd passing even make sense with encoded data?
1352                         _dbus_assert(!DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport));
1353
1354                         if (_dbus_string_get_length (&socket_transport->encoded_outgoing) == 0)
1355             {
1356                                 if (!_dbus_auth_encode_data (transport->auth,
1357                                            header, &socket_transport->encoded_outgoing))
1358                 {
1359                                         oom = TRUE;
1360                                         goto out;
1361                 }
1362
1363                                 if (!_dbus_auth_encode_data (transport->auth,
1364                                            body, &socket_transport->encoded_outgoing))
1365                 {
1366                                         _dbus_string_set_length (&socket_transport->encoded_outgoing, 0);
1367                                         oom = TRUE;
1368                                         goto out;
1369                 }
1370             }
1371
1372                         total_bytes_to_write = _dbus_string_get_length (&socket_transport->encoded_outgoing);
1373                         bytes_written = kdbus_write_msg_encoded(message, socket_transport);
1374         }
1375                 else
1376                 {
1377                         total_bytes_to_write = _dbus_string_get_length(header) + _dbus_string_get_length(body);
1378                         bytes_written = kdbus_write_msg(transport, message, socket_transport->fd);
1379                 }
1380
1381                 if (bytes_written < 0)
1382                 {
1383                         /* EINTR already handled for us */
1384
1385           /* For some discussion of why we also ignore EPIPE here, see
1386            * http://lists.freedesktop.org/archives/dbus/2008-March/009526.html
1387            */
1388
1389                         if (_dbus_get_is_errno_eagain_or_ewouldblock () || _dbus_get_is_errno_epipe ())
1390                                 goto out;
1391                         else
1392                         {
1393                                 _dbus_verbose ("Error writing to remote app: %s\n",
1394                                                          _dbus_strerror_from_errno ());
1395                                 do_io_error (transport);
1396                                 goto out;
1397                         }
1398                 }
1399                 else
1400                 {
1401                         _dbus_verbose (" wrote %d bytes of %d\n", bytes_written,
1402                          total_bytes_to_write);
1403
1404                         total += bytes_written;
1405                         socket_transport->message_bytes_written += bytes_written;
1406
1407                         _dbus_assert (socket_transport->message_bytes_written <=
1408                         total_bytes_to_write);
1409
1410                           if (socket_transport->message_bytes_written == total_bytes_to_write)
1411                           {
1412                                   socket_transport->message_bytes_written = 0;
1413                                   _dbus_string_set_length (&socket_transport->encoded_outgoing, 0);
1414                                   _dbus_string_compact (&socket_transport->encoded_outgoing, 2048);
1415
1416                                   _dbus_connection_message_sent_unlocked (transport->connection,
1417                                                                                                                   message);
1418                           }
1419                 }
1420     }
1421
1422         out:
1423         if (oom)
1424                 return FALSE;
1425         else
1426                 return TRUE;
1427 }
1428
1429 /* returns false on out-of-memory */
1430 static dbus_bool_t
1431 do_reading (DBusTransport *transport)
1432 {
1433   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1434   DBusString *buffer;
1435   int bytes_read;
1436   int total;
1437   dbus_bool_t oom;
1438
1439   _dbus_verbose ("fd = %d\n",socket_transport->fd);
1440
1441   /* No messages without authentication! */
1442   if (!_dbus_transport_get_is_authenticated (transport))
1443     return TRUE;
1444
1445   oom = FALSE;
1446
1447   total = 0;
1448
1449  again:
1450
1451   /* See if we've exceeded max messages and need to disable reading */
1452   check_read_watch (transport);
1453
1454   if (total > socket_transport->max_bytes_read_per_iteration)
1455     {
1456       _dbus_verbose ("%d bytes exceeds %d bytes read per iteration, returning\n",
1457                      total, socket_transport->max_bytes_read_per_iteration);
1458       goto out;
1459     }
1460
1461   _dbus_assert (socket_transport->read_watch != NULL ||
1462                 transport->disconnected);
1463
1464   if (transport->disconnected)
1465     goto out;
1466
1467   if (!dbus_watch_get_enabled (socket_transport->read_watch))
1468     return TRUE;
1469
1470   if (_dbus_auth_needs_decoding (transport->auth))
1471     {
1472       /* Does fd passing even make sense with encoded data? */
1473     /*  _dbus_assert(!DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport));
1474
1475       if (_dbus_string_get_length (&socket_transport->encoded_incoming) > 0)
1476         bytes_read = _dbus_string_get_length (&socket_transport->encoded_incoming);
1477       else
1478         bytes_read = _dbus_read_socket (socket_transport->fd,
1479                                         &socket_transport->encoded_incoming,
1480                                         socket_transport->max_bytes_read_per_iteration);*/
1481
1482           bytes_read = kdbus_read_message(socket_transport,  &socket_transport->encoded_incoming);
1483
1484       _dbus_assert (_dbus_string_get_length (&socket_transport->encoded_incoming) ==
1485                     bytes_read);
1486
1487       if (bytes_read > 0)
1488         {
1489           int orig_len;
1490
1491           _dbus_message_loader_get_buffer (transport->loader,
1492                                            &buffer);
1493
1494           orig_len = _dbus_string_get_length (buffer);
1495
1496           if (!_dbus_auth_decode_data (transport->auth,
1497                                        &socket_transport->encoded_incoming,
1498                                        buffer))
1499             {
1500               _dbus_verbose ("Out of memory decoding incoming data\n");
1501               _dbus_message_loader_return_buffer (transport->loader,
1502                                               buffer,
1503                                               _dbus_string_get_length (buffer) - orig_len);
1504
1505               oom = TRUE;
1506               goto out;
1507             }
1508
1509           _dbus_message_loader_return_buffer (transport->loader,
1510                                               buffer,
1511                                               _dbus_string_get_length (buffer) - orig_len);
1512
1513           _dbus_string_set_length (&socket_transport->encoded_incoming, 0);
1514           _dbus_string_compact (&socket_transport->encoded_incoming, 2048);
1515         }
1516     }
1517   else
1518     {
1519       _dbus_message_loader_get_buffer (transport->loader,
1520                                        &buffer);
1521
1522       bytes_read = kdbus_read_message(socket_transport, buffer);
1523
1524       _dbus_message_loader_return_buffer (transport->loader,
1525                                           buffer,
1526                                           bytes_read < 0 ? 0 : bytes_read);
1527     }
1528
1529   if (bytes_read < 0)
1530     {
1531       /* EINTR already handled for us */
1532
1533       if (_dbus_get_is_errno_enomem ())
1534         {
1535           _dbus_verbose ("Out of memory in read()/do_reading()\n");
1536           oom = TRUE;
1537           goto out;
1538         }
1539       else if (_dbus_get_is_errno_eagain_or_ewouldblock ())
1540         goto out;
1541       else
1542         {
1543           _dbus_verbose ("Error reading from remote app: %s\n",
1544                          _dbus_strerror_from_errno ());
1545           do_io_error (transport);
1546           goto out;
1547         }
1548     }
1549   else if (bytes_read == 0)
1550     {
1551       _dbus_verbose ("Disconnected from remote app\n");
1552       do_io_error (transport);
1553       goto out;
1554     }
1555   else
1556     {
1557       _dbus_verbose (" read %d bytes\n", bytes_read);
1558
1559       total += bytes_read;
1560
1561       if (!_dbus_transport_queue_messages (transport))
1562         {
1563           oom = TRUE;
1564           _dbus_verbose (" out of memory when queueing messages we just read in the transport\n");
1565           goto out;
1566         }
1567
1568       /* Try reading more data until we get EAGAIN and return, or
1569        * exceed max bytes per iteration.  If in blocking mode of
1570        * course we'll block instead of returning.
1571        */
1572       goto again;
1573     }
1574
1575  out:
1576   if (oom)
1577     return FALSE;
1578   else
1579     return TRUE;
1580 }
1581
1582 static dbus_bool_t
1583 unix_error_with_read_to_come (DBusTransport *itransport,
1584                               DBusWatch     *watch,
1585                               unsigned int   flags)
1586 {
1587   DBusTransportSocket *transport = (DBusTransportSocket *) itransport;
1588
1589   if (!(flags & DBUS_WATCH_HANGUP || flags & DBUS_WATCH_ERROR))
1590     return FALSE;
1591
1592   /* If we have a read watch enabled ...
1593      we -might have data incoming ... => handle the HANGUP there */
1594   if (watch != transport->read_watch &&
1595       _dbus_watch_get_enabled (transport->read_watch))
1596     return FALSE;
1597
1598   return TRUE;
1599 }
1600
1601 static dbus_bool_t
1602 socket_handle_watch (DBusTransport *transport,
1603                    DBusWatch     *watch,
1604                    unsigned int   flags)
1605 {
1606   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1607
1608   _dbus_assert (watch == socket_transport->read_watch ||
1609                 watch == socket_transport->write_watch);
1610   _dbus_assert (watch != NULL);
1611
1612   /* If we hit an error here on a write watch, don't disconnect the transport yet because data can
1613    * still be in the buffer and do_reading may need several iteration to read
1614    * it all (because of its max_bytes_read_per_iteration limit).
1615    */
1616   if (!(flags & DBUS_WATCH_READABLE) && unix_error_with_read_to_come (transport, watch, flags))
1617     {
1618       _dbus_verbose ("Hang up or error on watch\n");
1619       _dbus_transport_disconnect (transport);
1620       return TRUE;
1621     }
1622
1623   if (watch == socket_transport->read_watch &&
1624       (flags & DBUS_WATCH_READABLE))
1625     {
1626       dbus_bool_t auth_finished;
1627 #if 1
1628       _dbus_verbose ("handling read watch %p flags = %x\n",
1629                      watch, flags);
1630 #endif
1631       if (!do_authentication (transport, TRUE, FALSE, &auth_finished))
1632         return FALSE;
1633
1634       /* We don't want to do a read immediately following
1635        * a successful authentication.  This is so we
1636        * have a chance to propagate the authentication
1637        * state further up.  Specifically, we need to
1638        * process any pending data from the auth object.
1639        */
1640       if (!auth_finished)
1641         {
1642           if (!do_reading (transport))
1643             {
1644               _dbus_verbose ("no memory to read\n");
1645               return FALSE;
1646             }
1647         }
1648       else
1649         {
1650           _dbus_verbose ("Not reading anything since we just completed the authentication\n");
1651         }
1652     }
1653   else if (watch == socket_transport->write_watch &&
1654            (flags & DBUS_WATCH_WRITABLE))
1655     {
1656 #if 1
1657       _dbus_verbose ("handling write watch, have_outgoing_messages = %d\n",
1658                      _dbus_connection_has_messages_to_send_unlocked (transport->connection));
1659 #endif
1660       if (!do_authentication (transport, FALSE, TRUE, NULL))
1661         return FALSE;
1662
1663       if (!do_writing (transport))
1664         {
1665           _dbus_verbose ("no memory to write\n");
1666           return FALSE;
1667         }
1668
1669       /* See if we still need the write watch */
1670       check_write_watch (transport);
1671     }
1672 #ifdef DBUS_ENABLE_VERBOSE_MODE
1673   else
1674     {
1675       if (watch == socket_transport->read_watch)
1676         _dbus_verbose ("asked to handle read watch with non-read condition 0x%x\n",
1677                        flags);
1678       else if (watch == socket_transport->write_watch)
1679         _dbus_verbose ("asked to handle write watch with non-write condition 0x%x\n",
1680                        flags);
1681       else
1682         _dbus_verbose ("asked to handle watch %p on fd %d that we don't recognize\n",
1683                        watch, dbus_watch_get_socket (watch));
1684     }
1685 #endif /* DBUS_ENABLE_VERBOSE_MODE */
1686
1687   return TRUE;
1688 }
1689
1690 static void
1691 socket_disconnect (DBusTransport *transport)
1692 {
1693   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1694
1695   _dbus_verbose ("\n");
1696
1697   free_watches (transport);
1698
1699   _dbus_close_socket (socket_transport->fd, NULL);
1700   socket_transport->fd = -1;
1701 }
1702
1703 static dbus_bool_t
1704 socket_connection_set (DBusTransport *transport)
1705 {
1706   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1707
1708   _dbus_watch_set_handler (socket_transport->write_watch,
1709                            _dbus_connection_handle_watch,
1710                            transport->connection, NULL);
1711
1712   _dbus_watch_set_handler (socket_transport->read_watch,
1713                            _dbus_connection_handle_watch,
1714                            transport->connection, NULL);
1715
1716   if (!_dbus_connection_add_watch_unlocked (transport->connection,
1717                                             socket_transport->write_watch))
1718     return FALSE;
1719
1720   if (!_dbus_connection_add_watch_unlocked (transport->connection,
1721                                             socket_transport->read_watch))
1722     {
1723       _dbus_connection_remove_watch_unlocked (transport->connection,
1724                                               socket_transport->write_watch);
1725       return FALSE;
1726     }
1727
1728   check_read_watch (transport);
1729   check_write_watch (transport);
1730
1731   return TRUE;
1732 }
1733
1734 /**
1735  * @todo We need to have a way to wake up the select sleep if
1736  * a new iteration request comes in with a flag (read/write) that
1737  * we're not currently serving. Otherwise a call that just reads
1738  * could block a write call forever (if there are no incoming
1739  * messages).
1740  */
1741 static  void
1742 kdbus_do_iteration (DBusTransport *transport,
1743                    unsigned int   flags,
1744                    int            timeout_milliseconds)
1745 {
1746         DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1747         DBusPollFD poll_fd;
1748         int poll_res;
1749         int poll_timeout;
1750
1751         _dbus_verbose (" iteration flags = %s%s timeout = %d read_watch = %p write_watch = %p fd = %d\n",
1752                  flags & DBUS_ITERATION_DO_READING ? "read" : "",
1753                  flags & DBUS_ITERATION_DO_WRITING ? "write" : "",
1754                  timeout_milliseconds,
1755                  socket_transport->read_watch,
1756                  socket_transport->write_watch,
1757                  socket_transport->fd);
1758
1759   /* the passed in DO_READING/DO_WRITING flags indicate whether to
1760    * read/write messages, but regardless of those we may need to block
1761    * for reading/writing to do auth.  But if we do reading for auth,
1762    * we don't want to read any messages yet if not given DO_READING.
1763    */
1764
1765   poll_fd.fd = socket_transport->fd;
1766   poll_fd.events = 0;
1767
1768   if (_dbus_transport_get_is_authenticated (transport))
1769     {
1770       /* This is kind of a hack; if we have stuff to write, then try
1771        * to avoid the poll. This is probably about a 5% speedup on an
1772        * echo client/server.
1773        *
1774        * If both reading and writing were requested, we want to avoid this
1775        * since it could have funky effects:
1776        *   - both ends spinning waiting for the other one to read
1777        *     data so they can finish writing
1778        *   - prioritizing all writing ahead of reading
1779        */
1780       if ((flags & DBUS_ITERATION_DO_WRITING) &&
1781           !(flags & (DBUS_ITERATION_DO_READING | DBUS_ITERATION_BLOCK)) &&
1782           !transport->disconnected &&
1783           _dbus_connection_has_messages_to_send_unlocked (transport->connection))
1784         {
1785           do_writing (transport);
1786
1787           if (transport->disconnected ||
1788               !_dbus_connection_has_messages_to_send_unlocked (transport->connection))
1789             goto out;
1790         }
1791
1792       /* If we get here, we decided to do the poll() after all */
1793       _dbus_assert (socket_transport->read_watch);
1794       if (flags & DBUS_ITERATION_DO_READING)
1795         poll_fd.events |= _DBUS_POLLIN;
1796
1797       _dbus_assert (socket_transport->write_watch);
1798       if (flags & DBUS_ITERATION_DO_WRITING)
1799         poll_fd.events |= _DBUS_POLLOUT;
1800     }
1801   else
1802     {
1803       DBusAuthState auth_state;
1804
1805       auth_state = _dbus_auth_do_work (transport->auth);
1806
1807       if (transport->receive_credentials_pending ||
1808           auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT)
1809         poll_fd.events |= _DBUS_POLLIN;
1810
1811       if (transport->send_credentials_pending ||
1812           auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND)
1813         poll_fd.events |= _DBUS_POLLOUT;
1814     }
1815
1816   if (poll_fd.events)
1817     {
1818       if (flags & DBUS_ITERATION_BLOCK)
1819         poll_timeout = timeout_milliseconds;
1820       else
1821         poll_timeout = 0;
1822
1823       /* For blocking selects we drop the connection lock here
1824        * to avoid blocking out connection access during a potentially
1825        * indefinite blocking call. The io path is still protected
1826        * by the io_path_cond condvar, so we won't reenter this.
1827        */
1828       if (flags & DBUS_ITERATION_BLOCK)
1829         {
1830           _dbus_verbose ("unlock pre poll\n");
1831           _dbus_connection_unlock (transport->connection);
1832         }
1833
1834     again:
1835       poll_res = _dbus_poll (&poll_fd, 1, poll_timeout);
1836
1837       if (poll_res < 0 && _dbus_get_is_errno_eintr ())
1838       {
1839           _dbus_verbose ("Error from _dbus_poll(): %s\n",
1840                          _dbus_strerror_from_errno ());
1841           goto again;
1842       }
1843
1844       if (flags & DBUS_ITERATION_BLOCK)
1845         {
1846           _dbus_verbose ("lock post poll\n");
1847           _dbus_connection_lock (transport->connection);
1848         }
1849
1850       if (poll_res >= 0)
1851         {
1852           if (poll_res == 0)
1853             poll_fd.revents = 0; /* some concern that posix does not guarantee this;
1854                                   * valgrind flags it as an error. though it probably
1855                                   * is guaranteed on linux at least.
1856                                   */
1857
1858           if (poll_fd.revents & _DBUS_POLLERR)
1859             do_io_error (transport);
1860           else
1861             {
1862               dbus_bool_t need_read = (poll_fd.revents & _DBUS_POLLIN) > 0;
1863               dbus_bool_t need_write = (poll_fd.revents & _DBUS_POLLOUT) > 0;
1864               dbus_bool_t authentication_completed;
1865
1866               _dbus_verbose ("in iteration, need_read=%d need_write=%d\n",
1867                              need_read, need_write);
1868               do_authentication (transport, need_read, need_write,
1869                                  &authentication_completed);
1870
1871               /* See comment in socket_handle_watch. */
1872               if (authentication_completed)
1873                 goto out;
1874
1875               if (need_read && (flags & DBUS_ITERATION_DO_READING))
1876                 do_reading (transport);
1877               if (need_write && (flags & DBUS_ITERATION_DO_WRITING))
1878                 do_writing (transport);
1879             }
1880         }
1881       else
1882         {
1883           _dbus_verbose ("Error from _dbus_poll(): %s\n",
1884                          _dbus_strerror_from_errno ());
1885         }
1886     }
1887
1888
1889  out:
1890   /* We need to install the write watch only if we did not
1891    * successfully write everything. Note we need to be careful that we
1892    * don't call check_write_watch *before* do_writing, since it's
1893    * inefficient to add the write watch, and we can avoid it most of
1894    * the time since we can write immediately.
1895    *
1896    * However, we MUST always call check_write_watch(); DBusConnection code
1897    * relies on the fact that running an iteration will notice that
1898    * messages are pending.
1899    */
1900   check_write_watch (transport);
1901
1902   _dbus_verbose (" ... leaving do_iteration()\n");
1903 }
1904
1905 static void
1906 socket_live_messages_changed (DBusTransport *transport)
1907 {
1908   /* See if we should look for incoming messages again */
1909   check_read_watch (transport);
1910 }
1911
1912 static const DBusTransportVTable kdbus_vtable = {
1913   socket_finalize,
1914   socket_handle_watch,
1915   socket_disconnect,
1916   socket_connection_set,
1917   kdbus_do_iteration,
1918   socket_live_messages_changed,
1919   socket_get_socket_fd
1920 };
1921
1922 /**
1923  * Creates a new transport for the given kdbus file descriptor.  The file
1924  * descriptor must be nonblocking (use _dbus_set_fd_nonblocking() to
1925  * make it so).
1926  *
1927  * @param fd the file descriptor.
1928  * @param server_guid non-#NULL if this transport is on the server side of a connection
1929  * @param address the transport's address
1930  * @returns the new transport, or #NULL if no memory.
1931  */
1932 static DBusTransport*
1933 _dbus_transport_new_for_socket_kdbus (int       fd,
1934                                           const DBusString *server_guid,
1935                                           const DBusString *address)
1936 {
1937         DBusTransportSocket *socket_transport;
1938
1939   socket_transport = dbus_new0 (DBusTransportSocket, 1);
1940   if (socket_transport == NULL)
1941     return NULL;
1942
1943   if (!_dbus_string_init (&socket_transport->encoded_outgoing))
1944     goto failed_0;
1945
1946   if (!_dbus_string_init (&socket_transport->encoded_incoming))
1947     goto failed_1;
1948
1949   socket_transport->write_watch = _dbus_watch_new (fd,
1950                                                  DBUS_WATCH_WRITABLE,
1951                                                  FALSE,
1952                                                  NULL, NULL, NULL);
1953   if (socket_transport->write_watch == NULL)
1954     goto failed_2;
1955
1956   socket_transport->read_watch = _dbus_watch_new (fd,
1957                                                 DBUS_WATCH_READABLE,
1958                                                 FALSE,
1959                                                 NULL, NULL, NULL);
1960   if (socket_transport->read_watch == NULL)
1961     goto failed_3;
1962
1963   if (!_dbus_transport_init_base (&socket_transport->base,
1964                                   &kdbus_vtable,
1965                                   server_guid, address))
1966     goto failed_4;
1967
1968 #ifdef HAVE_UNIX_FD_PASSING
1969   _dbus_auth_set_unix_fd_possible(socket_transport->base.auth, _dbus_socket_can_pass_unix_fd(fd));
1970 #endif
1971
1972   socket_transport->fd = fd;
1973   socket_transport->message_bytes_written = 0;
1974
1975   /* These values should probably be tunable or something. */
1976   socket_transport->max_bytes_read_per_iteration = POOL_SIZE;
1977   socket_transport->max_bytes_written_per_iteration = 2048;
1978
1979   socket_transport->kdbus_mmap_ptr = NULL;
1980
1981   return (DBusTransport*) socket_transport;
1982
1983  failed_4:
1984   _dbus_watch_invalidate (socket_transport->read_watch);
1985   _dbus_watch_unref (socket_transport->read_watch);
1986  failed_3:
1987   _dbus_watch_invalidate (socket_transport->write_watch);
1988   _dbus_watch_unref (socket_transport->write_watch);
1989  failed_2:
1990   _dbus_string_free (&socket_transport->encoded_incoming);
1991  failed_1:
1992   _dbus_string_free (&socket_transport->encoded_outgoing);
1993  failed_0:
1994   dbus_free (socket_transport);
1995   return NULL;
1996 }
1997
1998
1999 /**
2000  * Creates a connection to the kdbus bus
2001   *
2002  * This will set FD_CLOEXEC for the socket returned.
2003  *
2004  * @param path the path to UNIX domain socket
2005  * @param error return location for error code
2006  * @returns connection file descriptor or -1 on error
2007  */
2008 static int _dbus_connect_kdbus (const char *path, DBusError *error)
2009 {
2010         int fd;
2011
2012         _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2013         _dbus_verbose ("connecting to kdbus bus %s\n", path);
2014
2015         fd = open(path, O_RDWR|O_CLOEXEC|O_NONBLOCK); //[RP] | O_NONBLOCK added here, in dbus added separately in section commented out below
2016         if (fd < 0)
2017         {
2018                 dbus_set_error(error, _dbus_error_from_errno (errno), "Failed to open file descriptor: %s", _dbus_strerror (errno));
2019                 _DBUS_ASSERT_ERROR_IS_SET(error);
2020                 return -1;  //[RP] not needed here if commented block below is removed
2021         }
2022
2023         /*if (!_dbus_set_fd_nonblocking (fd, error))
2024     {
2025                 _DBUS_ASSERT_ERROR_IS_SET (error);
2026                 _dbus_close (fd, NULL);
2027                 return -1;
2028     }*/
2029
2030         return fd;
2031 }
2032
2033 static dbus_bool_t kdbus_mmap(DBusTransport* transport)
2034 {
2035         DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
2036
2037         socket_transport->kdbus_mmap_ptr = mmap(NULL, POOL_SIZE, PROT_READ, MAP_SHARED, socket_transport->fd, 0);
2038         if (socket_transport->kdbus_mmap_ptr == MAP_FAILED)
2039                 return FALSE;
2040
2041         return TRUE;
2042 }
2043
2044 /**
2045  * Creates a new transport for kdbus.
2046  * This creates a client-side of a transport.
2047  *
2048  * @param path the path to the domain socket.
2049  * @param error address where an error can be returned.
2050  * @returns a new transport, or #NULL on failure.
2051  */
2052 static DBusTransport* _dbus_transport_new_for_kdbus (const char *path, DBusError *error)
2053 {
2054         int fd;
2055         DBusTransport *transport;
2056         DBusString address;
2057
2058         _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2059
2060         if (!_dbus_string_init (&address))
2061     {
2062                 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2063                 return NULL;
2064     }
2065
2066         fd = -1;
2067
2068         if ((!_dbus_string_append (&address, "kdbus:path=")) || (!_dbus_string_append (&address, path)))
2069     {
2070                 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2071                 goto failed_0;
2072     }
2073
2074         fd = _dbus_connect_kdbus (path, error);
2075         if (fd < 0)
2076     {
2077                 _DBUS_ASSERT_ERROR_IS_SET (error);
2078                 goto failed_0;
2079     }
2080
2081         _dbus_verbose ("Successfully connected to kdbus bus %s\n", path);
2082
2083         transport = _dbus_transport_new_for_socket_kdbus (fd, NULL, &address);
2084         if (transport == NULL)
2085     {
2086                 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2087                 goto failed_1;
2088     }
2089
2090         _dbus_string_free (&address);
2091
2092         return transport;
2093
2094         failed_1:
2095                 _dbus_close_socket (fd, NULL);
2096         failed_0:
2097                 _dbus_string_free (&address);
2098         return NULL;
2099 }
2100
2101
2102 /**
2103  * Opens kdbus transport.
2104  *
2105  * @param entry the address entry to try opening
2106  * @param transport_p return location for the opened transport
2107  * @param error error to be set
2108  * @returns result of the attempt
2109  */
2110 DBusTransportOpenResult _dbus_transport_open_kdbus(DBusAddressEntry  *entry,
2111                                                            DBusTransport    **transport_p,
2112                                                            DBusError         *error)
2113 {
2114         const char *method;
2115
2116         method = dbus_address_entry_get_method (entry);
2117         _dbus_assert (method != NULL);
2118
2119         if (strcmp (method, "kdbus") == 0)
2120     {
2121                 const char *path = dbus_address_entry_get_value (entry, "path");
2122
2123                 if (path == NULL)
2124         {
2125                         _dbus_set_bad_address (error, "kdbus", "path", NULL);
2126                         return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
2127         }
2128
2129         *transport_p = _dbus_transport_new_for_kdbus (path, error);
2130
2131         if (*transport_p == NULL)
2132         {
2133                 _DBUS_ASSERT_ERROR_IS_SET (error);
2134                 return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT;
2135         }
2136         else
2137         {
2138                 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2139                 return DBUS_TRANSPORT_OPEN_OK;
2140         }
2141     }
2142         else
2143     {
2144                 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2145                 return DBUS_TRANSPORT_OPEN_NOT_HANDLED;
2146     }
2147 }
2148
2149 static struct kdbus_policy *make_policy_name(const char *name)
2150 {
2151         struct kdbus_policy *p;
2152         __u64 size;
2153
2154         size = offsetof(struct kdbus_policy, name) + strlen(name) + 1;
2155         p = malloc(size);
2156         if (!p)
2157                 return NULL;
2158         memset(p, 0, size);
2159         p->size = size;
2160         p->type = KDBUS_POLICY_NAME;
2161         strcpy(p->name, name);
2162
2163         return p;
2164 }
2165
2166 static struct kdbus_policy *make_policy_access(__u64 type, __u64 bits, __u64 id)
2167 {
2168         struct kdbus_policy *p;
2169         __u64 size = sizeof(*p);
2170
2171         p = malloc(size);
2172         if (!p)
2173                 return NULL;
2174
2175         memset(p, 0, size);
2176         p->size = size;
2177         p->type = KDBUS_POLICY_ACCESS;
2178         p->access.type = type;
2179         p->access.bits = bits;
2180         p->access.id = id;
2181
2182         return p;
2183 }
2184
2185 static void append_policy(struct kdbus_cmd_policy *cmd_policy, struct kdbus_policy *policy, __u64 max_size)
2186 {
2187         struct kdbus_policy *dst = (struct kdbus_policy *) ((char *) cmd_policy + cmd_policy->size);
2188
2189         if (cmd_policy->size + policy->size > max_size)
2190                 return;
2191
2192         memcpy(dst, policy, policy->size);
2193         cmd_policy->size += KDBUS_ALIGN8(policy->size);
2194         free(policy);
2195 }
2196
2197 dbus_bool_t bus_register_policy_kdbus(const char* name, DBusConnection *connection, DBusError *error)
2198 {
2199         struct kdbus_cmd_policy *cmd_policy;
2200         struct kdbus_policy *policy;
2201         int size = 0xffff;
2202         int fd;
2203
2204         if(!dbus_connection_get_socket(connection, &fd))
2205         {
2206                 dbus_set_error (error, "Failed to get fd for registering policy", NULL);
2207                 return FALSE;
2208         }
2209
2210         cmd_policy = (struct kdbus_cmd_policy *) alloca(size);
2211         memset(cmd_policy, 0, size);
2212
2213         policy = (struct kdbus_policy *) cmd_policy->policies;
2214         cmd_policy->size = offsetof(struct kdbus_cmd_policy, policies);
2215
2216         policy = make_policy_name(name);                //todo to be verified or changed when meaning will be known
2217         append_policy(cmd_policy, policy, size);
2218
2219         policy = make_policy_access(KDBUS_POLICY_ACCESS_USER, KDBUS_POLICY_OWN, getuid());
2220         append_policy(cmd_policy, policy, size);
2221
2222         policy = make_policy_access(KDBUS_POLICY_ACCESS_WORLD, KDBUS_POLICY_RECV, 0);
2223         append_policy(cmd_policy, policy, size);
2224
2225         policy = make_policy_access(KDBUS_POLICY_ACCESS_WORLD, KDBUS_POLICY_SEND, 0);
2226         append_policy(cmd_policy, policy, size);
2227
2228         if (ioctl(fd, KDBUS_CMD_EP_POLICY_SET, cmd_policy) < 0)
2229         {
2230                 dbus_set_error(error,_dbus_error_from_errno (errno), "Error setting EP policy: %s", _dbus_strerror (errno));
2231                 return FALSE;
2232         }
2233
2234         _dbus_verbose("Policy %s set correctly\n", name);
2235         return TRUE;
2236 }
2237
2238 dbus_bool_t bus_register_kdbus(char* name, DBusConnection *connection, DBusError *error)
2239 {
2240         struct kdbus_cmd_hello hello;
2241         int fd;
2242
2243         memset(&hello, 0, sizeof(hello));
2244         hello.conn_flags = KDBUS_HELLO_ACCEPT_FD |
2245                            KDBUS_HELLO_ATTACH_COMM |
2246                            KDBUS_HELLO_ATTACH_EXE |
2247                            KDBUS_HELLO_ATTACH_CMDLINE |
2248                            KDBUS_HELLO_ATTACH_CAPS |
2249                            KDBUS_HELLO_ATTACH_CGROUP |
2250                            KDBUS_HELLO_ATTACH_SECLABEL |
2251                            KDBUS_HELLO_ATTACH_AUDIT;
2252         hello.size = sizeof(struct kdbus_cmd_hello);
2253         hello.pool_size = POOL_SIZE;
2254
2255         if(!dbus_connection_get_socket(connection, &fd))
2256         {
2257                 dbus_set_error (error, "failed to get fd for bus registration", NULL);
2258                 return FALSE;
2259         }
2260         if (ioctl(fd, KDBUS_CMD_HELLO, &hello))
2261         {
2262                 dbus_set_error(error,_dbus_error_from_errno (errno), "Failed to send hello: %s", _dbus_strerror (errno));
2263                 return FALSE;
2264         }
2265
2266         _dbus_verbose("-- Our peer ID is: %llu\n", (unsigned long long)hello.id);
2267         sprintf(name, "%llu", (unsigned long long)hello.id);
2268
2269         if(!kdbus_mmap(dbus_connection_get_transport(connection)))
2270         {
2271                 dbus_set_error(error,_dbus_error_from_errno (errno), "Error when mmap: %s", _dbus_strerror (errno));
2272                 return FALSE;
2273         }
2274
2275         return TRUE;
2276 }
2277
2278 uint64_t bus_request_name_kdbus(DBusConnection *connection, const char *name, const uint64_t flags, DBusError *error)
2279 {
2280         struct kdbus_cmd_name *cmd_name;
2281         int fd;
2282         uint64_t size = sizeof(*cmd_name) + strlen(name) + 1;
2283         uint64_t flags_kdbus = 0;
2284
2285         cmd_name = alloca(size);
2286
2287         memset(cmd_name, 0, size);
2288         strcpy(cmd_name->name, name);
2289         cmd_name->size = size;
2290
2291         if(flags & DBUS_NAME_FLAG_ALLOW_REPLACEMENT)
2292                 flags_kdbus |= KDBUS_NAME_ALLOW_REPLACEMENT;
2293         if(!(flags & DBUS_NAME_FLAG_DO_NOT_QUEUE))
2294                 flags_kdbus |= KDBUS_NAME_QUEUE;
2295         if(flags & DBUS_NAME_FLAG_REPLACE_EXISTING)
2296                 flags_kdbus |= KDBUS_NAME_REPLACE_EXISTING;
2297
2298         cmd_name->conn_flags = flags_kdbus;
2299
2300         if(!dbus_connection_get_socket(connection, &fd))
2301         {
2302                 dbus_set_error (error, "failed to get fd for name request", NULL);
2303                 return FALSE;
2304         }
2305
2306         _dbus_verbose("Request name - flags sent: 0x%llx       !!!!!!!!!\n", cmd_name->conn_flags);
2307
2308         _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2309         if (ioctl(fd, KDBUS_CMD_NAME_ACQUIRE, cmd_name))
2310         {
2311                 dbus_set_error(error,_dbus_error_from_errno (errno), "error acquiring name: %s", _dbus_strerror (errno));
2312                 if(errno == EEXIST)
2313                         return DBUS_REQUEST_NAME_REPLY_EXISTS;
2314                 return FALSE;
2315         }
2316
2317         _dbus_verbose("Request name - received flag: 0x%llx       !!!!!!!!!\n", cmd_name->conn_flags);
2318
2319         if(cmd_name->conn_flags & KDBUS_NAME_IN_QUEUE)
2320                 return DBUS_REQUEST_NAME_REPLY_IN_QUEUE;
2321         else
2322                 return DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER;
2323         //todo now 1 code is never returned -  DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER
2324 }
2325
2326 /**
2327  * Checks if the connection's transport is kdbus on the basis of its address
2328  *
2329  * @param pointer to the connection
2330  * @returns TRUE if kdbus transport, otherwise FALSE
2331  */
2332 dbus_bool_t dbus_transport_is_kdbus(DBusConnection *connection)
2333 {
2334         const char* address = _dbus_connection_get_address(connection);
2335
2336         if(address == strstr(address, "kdbus:path="))
2337                 return TRUE;
2338         else
2339                 return FALSE;
2340 }
2341
2342 void dbus_bus_add_match_kdbus (DBusConnection *connection, const char *rule, DBusError *error)
2343 {
2344         struct kdbus_cmd_match cmd_match;
2345         int fd;
2346
2347         memset(&cmd_match, 0, sizeof(cmd_match));
2348
2349         if(!dbus_connection_get_socket(connection, &fd))
2350         {
2351                 dbus_set_error (error, "failed to get fd for add match", NULL);
2352                 return;
2353         }
2354
2355         cmd_match.size = sizeof(cmd_match);
2356
2357         //todo add matching rules from *rule when it will be docuemnted in kdbus
2358
2359
2360         cmd_match.src_id = KDBUS_MATCH_SRC_ID_ANY;
2361
2362         if (ioctl(fd, KDBUS_CMD_MATCH_ADD, &cmd_match))
2363                 dbus_set_error(error,_dbus_error_from_errno (errno), "error adding match: %s", _dbus_strerror (errno));
2364
2365         _dbus_verbose("Finished adding match bus rule %s\n", rule);
2366 }