diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2016-11-11 10:10:03 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2016-11-11 10:16:21 +0200 |
commit | a527b0991ddbd8ac3f0ef438c285cb11dd08901b (patch) | |
tree | 32a18c588690d29d3b7d762743120a7c994b0fc2 | |
parent | 89922fc0cd25312d74e8b3fff35b0fb678b2c223 (diff) | |
download | dico-a527b0991ddbd8ac3f0ef438c285cb11dd08901b.tar.gz dico-a527b0991ddbd8ac3f0ef438c285cb11dd08901b.tar.bz2 |
dico: accept UNIX socket as argument to open
* dico/connect.c (dict_connect): Accept UNIX socket pathname as
argument. Improve error checking.
* dico/func.c (ds_open): If one argument given, it can be a socket
pathname.
* doc/dico.texi: Document changes to the "open" command.
-rw-r--r-- | dico/connect.c | 62 | ||||
-rw-r--r-- | dico/func.c | 17 | ||||
-rw-r--r-- | doc/dico.texi | 4 |
3 files changed, 74 insertions, 9 deletions
diff --git a/dico/connect.c b/dico/connect.c index 0654dc1..78fd790 100644 --- a/dico/connect.c +++ b/dico/connect.c @@ -269,6 +269,28 @@ dict_transcript(struct dict_connection *conn, int state) } } +static char const * +urlstr(dico_url_t url) +{ + if (!url->string) { + if (!url->proto) + xdico_assign_string(&url->proto, "dict"); + if (!url->port) + xdico_assign_string(&url->port, DICO_DICT_PORT_STR); + + if (url->host) { + asprintf(&url->string, "%s://%s:%s", + url->proto, + url->host, + url->port); + } else { + asprintf(&url->string, "%s:///%s", url->proto, url->path); + } + } + + return url->string; +} + int dict_connect(struct dict_connection **pconn, dico_url_t url) { @@ -278,7 +300,7 @@ dict_connect(struct dict_connection **pconn, dico_url_t url) struct dict_connection *conn; char const *port = url->port ? url->port : DICO_DICT_PORT_STR; - XDICO_DEBUG_F2(1, _("Connecting to %s:%s\n"), url->host, port); + XDICO_DEBUG_F1(1, _("Connecting to %s\n"), urlstr (url)); if (source_addr) { memset(&hints, 0, sizeof(hints)); @@ -310,7 +332,34 @@ dict_connect(struct dict_connection **pconn, dico_url_t url) memset(&hints, 0, sizeof(hints)); hints.ai_socktype = SOCK_STREAM; - rc = getaddrinfo(url->host, port, &hints, &res); + if (url->host) { + rc = getaddrinfo(url->host, port, &hints, &res); + if (rc) { + dico_log(L_ERR, 0, + _("%s: can't get address: %s"), + url->host, gai_strerror(rc)); + return -1; + } + } else { + struct sockaddr_un *s; + + if (strlen(url->path) >= sizeof s->sun_path) { + dico_log(L_ERR, 0, _("%s: UNIX socket name too long"), url->path); + return -1; + } + + hints.ai_family = AF_UNIX; + hints.ai_addrlen = sizeof(struct sockaddr_un); + + s = xcalloc(1, hints.ai_addrlen); + s->sun_family = AF_UNIX; + strcpy(s->sun_path, url->path); + + hints.ai_addr = (struct sockaddr *)s; + + res = &hints; + } + for (rp = res; rp; rp = rp->ai_next) { if (fd != -1 && family != rp->ai_family) { close(fd); @@ -329,11 +378,16 @@ dict_connect(struct dict_connection **pconn, dico_url_t url) if (connect(fd, rp->ai_addr, rp->ai_addrlen) != -1) break; } - + if (!rp) { - dico_log(L_ERR, 0, _("%s: cannot connect"), url->host); + dico_log(L_ERR, 0, _("%s: cannot connect"), urlstr(url)); return 1; } + + if (res == &hints) + free(res->ai_addr); + else + freeaddrinfo(res); if ((str = dico_fd_io_stream_create(fd, fd)) == NULL) { dico_log(L_ERR, errno, diff --git a/dico/func.c b/dico/func.c index 9d63df5..0278566 100644 --- a/dico/func.c +++ b/dico/func.c @@ -100,7 +100,7 @@ ensure_connection() { check_disconnect(); if (!conn) { - if (!dico_url.host) { + if (!dico_url.host && !dico_url.path) { script_error(_("Please specify server name or IP address")); return 1; } @@ -122,12 +122,19 @@ void ds_open(int argc, char **argv) { if (argc > 1) { - xdico_assign_string(&dico_url.host, argv[1]); - xdico_assign_string(&dico_url.port, - argc == 3 ? argv[2] : DICO_DICT_PORT_STR); + xdico_assign_string(&dico_url.string, NULL); + if (argv[1][0] == '/') { + xdico_assign_string(&dico_url.host, NULL); + xdico_assign_string(&dico_url.port, NULL); + xdico_assign_string(&dico_url.path, argv[1]); + } else { + xdico_assign_string(&dico_url.host, argv[1]); + xdico_assign_string(&dico_url.port, + argc == 3 ? argv[2] : DICO_DICT_PORT_STR); + } } - if (!dico_url.host) { + if (!dico_url.host && !dico_url.path) { script_error(_("Please specify server name or IP address")); return; } diff --git a/doc/dico.texi b/doc/dico.texi index 834d33a..7a7538b 100644 --- a/doc/dico.texi +++ b/doc/dico.texi @@ -5650,6 +5650,10 @@ name is @samp{gnu.org.ua} and the default port number is 2628. Both values can be changed at configuration time, see @ref{Default Server} for a detailed instruction. + When given one argument, @code{open} checks if it begins with a +directory separator (@samp{/}). If so, the argument is handled as the +full file name of a UNIX socket. + Note that you are not required to issue this command. If it is not given, @command{dico} will attempt to establish a connection using its default settings before executing any command that requires a |