diff options
-rw-r--r-- | libshouldbeinlibc/portinfo.c | 445 |
1 files changed, 419 insertions, 26 deletions
diff --git a/libshouldbeinlibc/portinfo.c b/libshouldbeinlibc/portinfo.c index f3c540f5..de087de9 100644 --- a/libshouldbeinlibc/portinfo.c +++ b/libshouldbeinlibc/portinfo.c @@ -19,6 +19,18 @@ #include <sys/types.h> #include <sys/mman.h> +#include <arpa/inet.h> +#include <sys/un.h> + +#include <mach/default_pager.h> +#include <hurd/fsys.h> +#include <hurd/msg.h> +#include <hurd/pci.h> +#include <hurd/process.h> +#include <hurd/socket.h> +#include <hurd/term.h> +#include <hurd/tioctl.h> +#include <hurd.h> #include "portinfo.h" @@ -30,7 +42,7 @@ print_port_info (mach_port_t name, mach_port_type_t type, task_t task, unsigned show, FILE *stream) { int hex_names = (show & PORTINFO_HEX_NAMES); - int first = 1; + int first = 1, subfirst = 1; void comma () { if (first) @@ -38,6 +50,13 @@ print_port_info (mach_port_t name, mach_port_type_t type, task_t task, else fprintf (stream, ", "); } + void subcomma () + { + if (subfirst) + subfirst = 0; + else + fprintf (stream, ","); + } void prefs (mach_port_right_t right) { mach_port_urefs_t refs; @@ -59,7 +78,397 @@ print_port_info (mach_port_t name, mach_port_type_t type, task_t task, { comma (); fprintf (stream, "receive"); - if (show & PORTINFO_DETAILS) + } + if (type & MACH_PORT_TYPE_SEND) + { + comma (); + fprintf (stream, "send"); + } + if (type & MACH_PORT_TYPE_SEND_ONCE) + { + comma (); + fprintf (stream, "send-once"); + } + if (type & MACH_PORT_TYPE_DEAD_NAME) + { + comma (); + fprintf (stream, "dead-name"); + } + if (type & MACH_PORT_TYPE_PORT_SET) + { + comma (); + fprintf (stream, "port-set"); + } + + if (show & PORTINFO_DETAILS) + { + error_t err; + mach_port_t port; + mach_msg_type_name_t acquired_type; + + /* Get the port itself. */ + err = mach_port_extract_right (task, name, + (type & MACH_PORT_TYPE_RECEIVE + ? MACH_MSG_TYPE_MAKE_SEND + : MACH_MSG_TYPE_COPY_SEND), + &port, &acquired_type); + + if (!err) + { + process_t proc = getproc (); + mach_port_t msgport; + pid_t pid; + + err = proc_task2pid (proc, task, &pid); + if (!err) + err = proc_getmsgport (proc, pid, &msgport); + if (!err) + { + /* Check if it is installed as an FD. */ + mach_port_t *dtable = NULL; + mach_msg_type_number_t ndtable = 0; + unsigned i; + + msg_get_dtable (msgport, task, &dtable, &ndtable); + + for (i = 0; i < ndtable; i++) + { + if (dtable[i] == port) + fprintf (stream, " fd(%d)", i); + mach_port_deallocate (mach_task_self (), dtable[i]); + } + vm_deallocate (mach_task_self (), (vm_address_t) dtable, ndtable * sizeof (*dtable)); + + /* First check for init ports. */ + void check_init_port (int num, const char *name) + { + mach_port_t init_port; + + err = msg_get_init_port (msgport, task, num, &init_port); + if (!err) + { + if (port == init_port) + fprintf (stream, " %s", name); + mach_port_deallocate (mach_task_self (), init_port); + } + } + + check_init_port (INIT_PORT_CWDIR, "CWDIR"); + check_init_port (INIT_PORT_CRDIR, "CRDIR"); + check_init_port (INIT_PORT_AUTH, "AUTH"); + check_init_port (INIT_PORT_PROC, "PROC"); + check_init_port (INIT_PORT_CTTYID, "CTTYID"); + check_init_port (INIT_PORT_BOOTSTRAP, "BOOTSTRAP"); + + mach_port_deallocate (mach_task_self (), msgport); + } + + /* Then try to use the ports to see what they are. */ + if (type & MACH_PORT_TYPE_RECEIVE) + { + if (port == msgport) + fprintf (stream, " msg"); + } + else if (type & MACH_PORT_TYPE_SEND) + { + /* auth_t */ + { + uid_t *euids = 0, *auids = 0, *egids = 0, *agids = 0; + mach_msg_type_number_t neuids = 0, nauids = 0, negids = 0, nagids = 0, i; + + err = auth_getids (port, + &euids, &neuids, + &auids, &nauids, + &egids, &negids, + &agids, &nagids); + + if (!err) + { + fprintf (stream, " auth(["); + subfirst = 1; + for (i = 0; i < neuids; i++) + { + subcomma (); + fprintf (stream, "%d", euids[i]); + } + fprintf (stream, "],["); + subfirst = 1; + for (i = 0; i < nauids; i++) + { + subcomma (); + fprintf (stream, "%d", auids[i]); + } + fprintf (stream, "],["); + subfirst = 1; + for (i = 0; i < negids; i++) + { + subcomma (); + fprintf (stream, "%d", egids[i]); + } + fprintf (stream, "],["); + subfirst = 1; + for (i = 0; i < nagids; i++) + { + subcomma (); + fprintf (stream, "%d", agids[i]); + } + fprintf (stream, "])"); + munmap (euids, neuids * sizeof (*euids)); + munmap (auids, nauids * sizeof (*auids)); + munmap (egids, negids * sizeof (*egids)); + munmap (agids, nagids * sizeof (*agids)); + } + } + + /* file_t */ + { + int allowed; + + err = file_check_access (port, &allowed); + + if (!err) + { + int printbar = 0; + void bar (void) + { + if (printbar) + fprintf (stream, "|"); + else + printbar = 1; + } + + fprintf (stream, " file("); + if (allowed & O_READ) + { + bar (); + fprintf (stream, "READ"); + } + if (allowed & O_WRITE) + { + bar (); + fprintf (stream, "WRITE"); + } + if (allowed & O_EXEC) + { + bar (); + fprintf (stream, "EXEC"); + } + fprintf (stream, ")"); + } + } + + /* fsys_t */ + { + string_t source; + + err = fsys_get_source (port, source); + + if (!err) + fprintf (stream, " fsys(%s)", source); + } + + /* io_t */ + { + struct stat st; + + err = io_stat (port, &st); + + if (!err) + fprintf (stream, " io(%llu,%llu)", + (unsigned long long) st.st_ino, + (unsigned long long) st.st_dev); + } + + /* msg */ + { + mach_port_t proc; + + err = msg_get_init_port (port, task, INIT_PORT_PROC, &proc); + if (!err) + { + pid_t pid, ppid; + int orphaned; + + fprintf (stream, " msg"); + err = proc_getpids (port, &pid, &ppid, &orphaned); + if (!err) + fprintf (stream, "(%d)", pid); + + mach_port_deallocate (mach_task_self (), proc); + } + } + + /* pci_t */ + { + vm_size_t ndevs; + + err = pci_get_ndevs (port, &ndevs); + + if (!err) + fprintf (stream, " pci(%d)", ndevs); + } + + /* process_t */ + { + pid_t pid, ppid; + int orphaned; + + err = proc_getpids (port, &pid, &ppid, &orphaned); + + if (!err) + fprintf (stream, " proc(%d)", pid); + } + + /* socket_t */ + { + mach_port_t addr = MACH_PORT_NULL; + int type; + struct sockaddr_storage sa; + char *psa = (char*) &sa; + mach_msg_type_number_t salen = sizeof (sa); + + err = socket_name (port, &addr); + + if (!err) + fprintf (stream, " socket"); + else + addr = port; + + err = socket_whatis_address (addr, &type, &psa, &salen); + if (!err) + { + if (addr == port) + fprintf (stream, " addr_port"); + + if (type == AF_UNIX) + { + struct sockaddr_un *sa_un = (struct sockaddr_un *) psa; + + fprintf (stream, "(UNIX:%s)", sa_un->sun_path); + } + else if (type == AF_INET) + { + struct sockaddr_in *sa_in = (struct sockaddr_in *) psa; + + fprintf (stream, "(INET:%s:%d)", + inet_ntoa (sa_in->sin_addr), + ntohs (sa_in->sin_port)); + } + else if (type == AF_INET6) + { + struct sockaddr_in6 *sa_in6 = (struct sockaddr_in6 *) psa; + char buf[INET6_ADDRSTRLEN]; + const char *s; + + s = inet_ntop (type, &sa_in6->sin6_addr, buf, sizeof (buf)); + fprintf (stream, "(INET6:%s:%d)", s, + ntohs (sa_in6->sin6_port)); + } + else + fprintf (stream, "(%d)", type); + } + if (psa != (char*) &sa) + vm_deallocate (mach_task_self (), (vm_address_t) psa, salen); + + if (addr != port) + mach_port_deallocate (mach_task_self (), addr); + } + + /* terminal */ + { + string_t name; + + err = term_get_nodename (port, name); + + if (!err) + fprintf (stream, " term(%s)", name); + } + + /* default pager */ + { + struct default_pager_info def_pager_info; + + err = default_pager_info (port, &def_pager_info); + + if (!err) + fprintf (stream, " default_pager(%llu)", + (unsigned long long) def_pager_info.dpi_total_space); + } + + /* host_t */ + { + struct host_basic_info info; + mach_msg_type_number_t count = HOST_BASIC_INFO_COUNT; + + err = host_info (port, HOST_BASIC_INFO, + (host_info_t) &info, &count); + + if (!err) + fprintf (stream, " host"); + if (port == mach_host_self ()) + fprintf (stream, "(self)"); + } + + /* memory_object */ + { + boolean_t ready, may_cache; + memory_object_copy_strategy_t strategy; + + err = memory_object_get_attributes (port, &ready, &may_cache, &strategy); + + if (!err) + fprintf (stream, " memory_object"); + } + + /* processor_t */ + { + struct processor_basic_info info; + host_t host; + mach_msg_type_number_t count = PROCESSOR_BASIC_INFO_COUNT; + + err = processor_info (port, PROCESSOR_BASIC_INFO, + &host, (processor_info_t) &info, &count); + + if (!err) + { + fprintf (stream, " processor(%d)", info.slot_num); + mach_port_deallocate (mach_task_self (), host); + } + } + + /* task_t */ + { + pid_t pid; + + err = proc_task2pid (proc, port, &pid); + if (!err) + fprintf (stream, " task(%d)", pid); + if (port == task) + { + if (err) + fprintf (stream, " task"); + fprintf (stream, "(self)"); + } + } + + /* thread_t */ + { + struct thread_basic_info info; + mach_msg_type_number_t count = THREAD_BASIC_INFO_COUNT; + + err = thread_info (port, THREAD_BASIC_INFO, + (thread_info_t) &info, &count); + + if (!err) + fprintf (stream, " thread"); + } + } + + mach_port_deallocate (mach_task_self (), proc); + mach_port_deallocate (mach_task_self (), port); + } + + if (type & MACH_PORT_TYPE_RECEIVE) { struct mach_port_status status; error_t err = mach_port_get_receive_status (task, name, &status); @@ -83,31 +492,14 @@ print_port_info (mach_port_t name, mach_port_type_t type, task_t task, status.mps_nsrequest ? ", ns-req" : ""); } } - } - if (type & MACH_PORT_TYPE_SEND) - { - comma (); - fprintf (stream, "send"); - if (show & PORTINFO_DETAILS) + + if (type & MACH_PORT_TYPE_SEND) prefs (MACH_PORT_RIGHT_SEND); - } - if (type & MACH_PORT_TYPE_SEND_ONCE) - { - comma (); - fprintf (stream, "send-once"); - } - if (type & MACH_PORT_TYPE_DEAD_NAME) - { - comma (); - fprintf (stream, "dead-name"); - if (show & PORTINFO_DETAILS) + + if (type & MACH_PORT_TYPE_DEAD_NAME) prefs (MACH_PORT_RIGHT_DEAD_NAME); - } - if (type & MACH_PORT_TYPE_PORT_SET) - { - comma (); - fprintf (stream, "port-set"); - if (show & PORTINFO_DETAILS) + + if (type & MACH_PORT_TYPE_PORT_SET) { mach_port_t *members = 0; mach_msg_type_number_t members_len = 0, i; @@ -127,8 +519,9 @@ print_port_info (mach_port_t name, mach_port_type_t type, task_t task, munmap ((caddr_t) members, members_len * sizeof *members); } } - } + } } + putc ('\n', stream); return 0; |