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