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