summaryrefslogtreecommitdiff
path: root/src/process.c
diff options
context:
space:
mode:
authorLars Ingebrigtsen <larsi@gnus.org>2019-08-23 04:49:52 +0200
committerLars Ingebrigtsen <larsi@gnus.org>2019-08-23 04:49:52 +0200
commit53cb3d3e0ddb666dc5b7774957ca863c668213cb (patch)
tree011cf32acf25b0cd86debf5b3c22be289e60bd87 /src/process.c
parentb4d3a882a8423e81c418fc56b7a9677f5582fcc7 (diff)
parent29d485fb768fbe375d60fd80cb2dbdbd90f3becc (diff)
downloademacs-53cb3d3e0ddb666dc5b7774957ca863c668213cb.tar.gz
Merge remote-tracking branch 'origin/netsec'
Diffstat (limited to 'src/process.c')
-rw-r--r--src/process.c108
1 files changed, 93 insertions, 15 deletions
diff --git a/src/process.c b/src/process.c
index 066edbc83d6..7097b7ace17 100644
--- a/src/process.c
+++ b/src/process.c
@@ -276,6 +276,10 @@ static int read_process_output (Lisp_Object, int);
static void create_pty (Lisp_Object);
static void exec_sentinel (Lisp_Object, Lisp_Object);
+static Lisp_Object
+network_lookup_address_info_1 (Lisp_Object host, const char *service,
+ struct addrinfo *hints, struct addrinfo **res);
+
/* Number of bits set in connect_wait_mask. */
static int num_pending_connects;
@@ -4106,7 +4110,7 @@ usage: (make-network-process &rest ARGS) */)
if (!NILP (host))
{
struct addrinfo *res, *lres;
- int ret;
+ Lisp_Object msg;
maybe_quit ();
@@ -4115,20 +4119,11 @@ usage: (make-network-process &rest ARGS) */)
hints.ai_family = family;
hints.ai_socktype = socktype;
- ret = getaddrinfo (SSDATA (host), portstring, &hints, &res);
- if (ret)
-#ifdef HAVE_GAI_STRERROR
- {
- synchronize_system_messages_locale ();
- char const *str = gai_strerror (ret);
- if (! NILP (Vlocale_coding_system))
- str = SSDATA (code_convert_string_norecord
- (build_string (str), Vlocale_coding_system, 0));
- error ("%s/%s %s", SSDATA (host), portstring, str);
- }
-#else
- error ("%s/%s getaddrinfo error %d", SSDATA (host), portstring, ret);
-#endif
+ msg = network_lookup_address_info_1 (host, portstring, &hints, &res);
+ if (!EQ(msg, Qt))
+ {
+ error ("%s", SSDATA (msg));
+ }
for (lres = res; lres; lres = lres->ai_next)
addrinfos = Fcons (conv_addrinfo_to_lisp (lres), addrinfos);
@@ -4576,6 +4571,88 @@ Data that is unavailable is returned as nil. */)
#endif
}
+static Lisp_Object
+network_lookup_address_info_1 (Lisp_Object host, const char *service,
+ struct addrinfo *hints, struct addrinfo **res)
+{
+ Lisp_Object msg = Qt;
+ int ret;
+
+ if (STRING_MULTIBYTE (host) && SBYTES (host) != SCHARS (host))
+ error ("Non-ASCII hostname %s detected, please use puny-encode-domain",
+ SSDATA (host));
+ ret = getaddrinfo (SSDATA (host), service, hints, res);
+ if (ret)
+ {
+ if (service == NULL)
+ service = "0";
+#ifdef HAVE_GAI_STRERROR
+ synchronize_system_messages_locale ();
+ char const *str = gai_strerror (ret);
+ if (! NILP (Vlocale_coding_system))
+ str = SSDATA (code_convert_string_norecord
+ (build_string (str), Vlocale_coding_system, 0));
+ AUTO_STRING (format, "%s/%s %s");
+ msg = CALLN (Fformat, format, host, build_string (service), build_string (str));
+#else
+ AUTO_STRING (format, "%s/%s getaddrinfo error %d");
+ msg = CALLN (Fformat, format, host, build_string (service), make_number (ret));
+#endif
+ }
+ return msg;
+}
+
+DEFUN ("network-lookup-address-info", Fnetwork_lookup_address_info,
+ Snetwork_lookup_address_info, 1, 2, 0,
+ doc: /* Look up ip address info of NAME.
+Optional parameter FAMILY controls whether to look up IPv4 or IPv6
+addresses. The default of nil means both, symbol `ipv4' means IPv4
+only, symbol `ipv6' means IPv6 only. Returns a list of addresses, or
+nil if none were found. Each address is a vector of integers. */)
+ (Lisp_Object name, Lisp_Object family)
+{
+ Lisp_Object addresses = Qnil;
+ Lisp_Object msg = Qnil;
+
+ struct addrinfo *res, *lres;
+ struct addrinfo hints;
+
+ memset (&hints, 0, sizeof hints);
+ if (EQ (family, Qnil))
+ hints.ai_family = AF_UNSPEC;
+ else if (EQ (family, Qipv4))
+ hints.ai_family = AF_INET;
+ else if (EQ (family, Qipv6))
+#ifdef AF_INET6
+ hints.ai_family = AF_INET6;
+#else
+ /* If we don't support IPv6, querying will never work anyway */
+ return addresses;
+#endif
+ else
+ error ("Unsupported lookup type");
+ hints.ai_socktype = SOCK_DGRAM;
+
+ msg = network_lookup_address_info_1 (name, NULL, &hints, &res);
+ if (!EQ(msg, Qt))
+ {
+ message ("%s", SSDATA(msg));
+ }
+ else
+ {
+ for (lres = res; lres; lres = lres->ai_next)
+ {
+ addresses = Fcons (conv_sockaddr_to_lisp
+ (lres->ai_addr, lres->ai_addrlen),
+ addresses);
+ }
+ addresses = Fnreverse (addresses);
+
+ freeaddrinfo (res);
+ }
+ return addresses;
+}
+
/* Turn off input and output for process PROC. */
static void
@@ -8345,6 +8422,7 @@ returns non-`nil'. */);
defsubr (&Sset_network_process_option);
defsubr (&Smake_network_process);
defsubr (&Sformat_network_address);
+ defsubr (&Snetwork_lookup_address_info);
defsubr (&Snetwork_interface_list);
defsubr (&Snetwork_interface_info);
#ifdef DATAGRAM_SOCKETS