diff options
-rw-r--r-- | src/core/dbus-socket.c | 62 | ||||
-rw-r--r-- | src/core/socket.c | 22 | ||||
-rw-r--r-- | src/core/socket.h | 2 | ||||
-rw-r--r-- | src/systemctl/systemctl.c | 66 |
4 files changed, 152 insertions, 0 deletions
diff --git a/src/core/dbus-socket.c b/src/core/dbus-socket.c index 2092a63694..728958131d 100644 --- a/src/core/dbus-socket.c +++ b/src/core/dbus-socket.c @@ -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) }, diff --git a/src/core/socket.c b/src/core/socket.c index d6d531d377..f3cbe08a44 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -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); diff --git a/src/core/socket.h b/src/core/socket.h index e0bae299b3..dbc363217b 100644 --- a/src/core/socket.h +++ b/src/core/socket.h @@ -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); diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 6bd2e34f58..4f4d334794 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -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") && |