chiark / gitweb /
Add Listen* to dbus properties
authorOleksii Shevchuk <alxchk@gmail.com>
Mon, 1 Apr 2013 20:09:45 +0000 (23:09 +0300)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 2 Apr 2013 03:43:48 +0000 (23:43 -0400)
sockets.socket - Test
  Loaded: loaded (/home/alxchk/.config/systemd/user/sockets.socket; static)
  Active: inactive (dead)
  Listen: Stream: /tmp/stream1
          Stream: @stream4
          Stream: [::]:9999
          Stream: 127.0.0.2:9996
          Stream: [::1]:9996
          Datagram: /tmp/stream2
          Datagram: @stream5
          Datagram: [::]:9998
          Datagram: 127.0.0.2:9995
          Datagram: [::1]:9995
          SequentialPacket: @stream6
          SequentialPacket: /tmp/stream3
          FIFO: /tmp/fifo1
          Special: /dev/input/event9
          Netlink: kobject-uevent 0
          MessageQueue: /msgqueue1

[zj: - minor cleanups,
     - free i.listen,
     - remove sorting, because the order or sockets matters.]

src/core/dbus-socket.c
src/core/socket.c
src/core/socket.h
src/systemctl/systemctl.c

index 2092a63..7289581 100644 (file)
@@ -63,6 +63,7 @@
         "  <property name=\"NConnections\" type=\"u\" access=\"read\"/>\n" \
         "  <property name=\"MessageQueueMaxMessages\" type=\"x\" access=\"read\"/>\n" \
         "  <property name=\"MessageQueueMessageSize\" type=\"x\" access=\"read\"/>\n" \
+        "  <property name=\"Listen\" type=\"a(ss)\" access=\"read\"/>\n"    \
         "  <property name=\"Result\" type=\"s\" access=\"read\"/>\n"    \
         "  <property name=\"SmackLabel\" type=\"s\" access=\"read\"/>\n" \
         "  <property name=\"SmackLabelIPIn\" type=\"s\" access=\"read\"/>\n" \
@@ -98,6 +99,66 @@ const char bus_socket_invalidating_properties[] =
 static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_socket_append_bind_ipv6_only, socket_address_bind_ipv6_only, SocketAddressBindIPv6Only);
 static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_socket_append_socket_result, socket_result, SocketResult);
 
+static int bus_socket_append_listen(DBusMessageIter *i, const char *property, void *data) {
+
+        Socket *s = SOCKET(data);
+        SocketPort *p;
+        DBusMessageIter array, stru;
+
+        assert(data);
+        assert(property);
+        assert(s);
+
+        if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "(ss)", &array))
+                return log_oom();
+
+        LIST_FOREACH(port, p, s->ports) {
+                const char *type = socket_port_type_to_string(p);
+                char _cleanup_free_ *address = NULL;
+                const char *a;
+
+                if (!dbus_message_iter_open_container(&array, DBUS_TYPE_STRUCT, NULL, &stru))
+                        return log_oom();
+
+                if (!dbus_message_iter_append_basic(&stru, DBUS_TYPE_STRING, &type))
+                        return log_oom();
+
+                switch (p->type) {
+                        case SOCKET_SOCKET: {
+                                int r;
+
+                                r = socket_address_print(&p->address, &address);
+                                if (r) {
+                                        log_error("socket_address_print failed: %s", strerror(-r));
+                                        return r;
+                                }
+                                a = address;
+                                break;
+                        }
+
+                        case SOCKET_SPECIAL:
+                        case SOCKET_MQUEUE:
+                        case SOCKET_FIFO:
+                                a = p->path;
+                                break;
+
+                        default:
+                                a = type;
+                }
+
+                if (!dbus_message_iter_append_basic(&stru, DBUS_TYPE_STRING, &a))
+                        return -ENOMEM;
+
+                if (!dbus_message_iter_close_container(&array, &stru))
+                        return -ENOMEM;
+        }
+
+        if (!dbus_message_iter_close_container(i, &array))
+                return -ENOMEM;
+
+        return 0;
+}
+
 static const BusProperty bus_socket_properties[] = {
         { "BindIPv6Only",   bus_socket_append_bind_ipv6_only,  "s", offsetof(Socket, bind_ipv6_only)  },
         { "Backlog",        bus_property_append_unsigned,      "u", offsetof(Socket, backlog)         },
@@ -123,6 +184,7 @@ static const BusProperty bus_socket_properties[] = {
         { "Broadcast",      bus_property_append_bool,          "b", offsetof(Socket, broadcast)       },
         { "PassCredentials",bus_property_append_bool,          "b", offsetof(Socket, pass_cred)       },
         { "PassSecurity",   bus_property_append_bool,          "b", offsetof(Socket, pass_sec)        },
+        { "Listen",         bus_socket_append_listen,      "a(ss)", 0,                                },
         { "Mark",           bus_property_append_int,           "i", offsetof(Socket, mark)            },
         { "MaxConnections", bus_property_append_unsigned,      "u", offsetof(Socket, max_connections) },
         { "NConnections",   bus_property_append_unsigned,      "u", offsetof(Socket, n_connections)   },
index d6d531d..f3cbe08 100644 (file)
@@ -1969,6 +1969,28 @@ static const char *socket_sub_state_to_string(Unit *u) {
         return socket_state_to_string(SOCKET(u)->state);
 }
 
+const char* socket_port_type_to_string(SocketPort *p) {
+
+        assert(p);
+
+        switch (p->type) {
+                case SOCKET_SOCKET:
+                        switch (p->address.type) {
+                                case SOCK_STREAM: return "Stream";
+                                case SOCK_DGRAM: return "Datagram";
+                                case SOCK_SEQPACKET: return "SequentialPacket";
+                                case SOCK_RAW:
+                                        if (socket_address_family(&p->address) == AF_NETLINK)
+                                                return "Netlink";
+                                default: return "Invalid";
+                        }
+                case SOCKET_SPECIAL: return "Special";
+                case SOCKET_MQUEUE: return "MessageQueue";
+                case SOCKET_FIFO: return "FIFO";
+                default: return NULL;
+        }
+}
+
 static bool socket_check_gc(Unit *u) {
         Socket *s = SOCKET(u);
 
index e0bae29..dbc3632 100644 (file)
@@ -175,3 +175,5 @@ SocketExecCommand socket_exec_command_from_string(const char *s);
 
 const char* socket_result_to_string(SocketResult i);
 SocketResult socket_result_from_string(const char *s);
+
+const char* socket_port_type_to_string(SocketPort *p);
index 6bd2e34..4f4d334 100644 (file)
@@ -2255,6 +2255,8 @@ typedef struct UnitStatusInfo {
         unsigned n_connections;
         bool accept;
 
+        char **listen;
+
         /* Device */
         const char *sysfs_path;
 
@@ -2386,6 +2388,19 @@ static void print_status_info(UnitStatusInfo *i) {
                 }
         }
 
+        if (!strv_isempty(i->listen)) {
+                char **t;
+                bool first = true;
+
+                STRV_FOREACH(t, i->listen) {
+                        if (first) {
+                                printf("\t  Listen: %s\n", *t);
+                                first = false;
+                        } else
+                                printf("\t          %s\n", *t);
+                }
+        }
+
         if (i->accept)
                 printf("\tAccepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
 
@@ -2736,6 +2751,37 @@ static int status_property(const char *name, DBusMessageIter *iter, UnitStatusIn
 
                                 dbus_message_iter_next(&sub);
                         }
+
+                } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && streq(name, "Listen")) {
+                        DBusMessageIter sub, sub2;
+
+                        dbus_message_iter_recurse(iter, &sub);
+                        while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) {
+                                const char *type, *path;
+
+                                dbus_message_iter_recurse(&sub, &sub2);
+
+                                if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &type, true) >= 0 &&
+                                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &path, false) >= 0) {
+                                        char * buf, **l;
+                                        if (asprintf(&buf, "%s: %s", type, path) < 0)
+                                                return -ENOMEM;
+
+                                        l = strv_append(i->listen, buf);
+                                        free(buf);
+
+                                        if (!l)
+                                                return -ENOMEM;
+
+                                        strv_free(i->listen);
+                                        i->listen = l;
+                                }
+
+                                dbus_message_iter_next(&sub);
+                        }
+
+                        return 0;
+
                 } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRING &&
                            streq(name, "Documentation")) {
 
@@ -2866,6 +2912,7 @@ static int print_property(const char *name, DBusMessageIter *iter) {
                         DBusMessageIter sub, sub2;
 
                         dbus_message_iter_recurse(iter, &sub);
+
                         while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) {
                                 const char *type, *path;
 
@@ -2880,6 +2927,24 @@ static int print_property(const char *name, DBusMessageIter *iter) {
 
                         return 0;
 
+                } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && streq(name, "Listen")) {
+                        DBusMessageIter sub, sub2;
+
+                        dbus_message_iter_recurse(iter, &sub);
+                        while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) {
+                                const char *type, *path;
+
+                                dbus_message_iter_recurse(&sub, &sub2);
+
+                                if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &type, true) >= 0 &&
+                                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &path, false) >= 0)
+                                        printf("Listen%s=%s\n", type, path);
+
+                                dbus_message_iter_next(&sub);
+                        }
+
+                        return 0;
+
                 } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && streq(name, "Timers")) {
                         DBusMessageIter sub, sub2;
 
@@ -3055,6 +3120,7 @@ static int show_one(const char *verb, DBusConnection *bus, const char *path, boo
         }
 
         strv_free(info.documentation);
+        strv_free(info.listen);
 
         if (!streq_ptr(info.active_state, "active") &&
             !streq_ptr(info.active_state, "reloading") &&