X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/71decbbc7b32f17449aa88c0297263c3ab324780..58c5e5b287f2ef7b6a855b30eb0c2be1edd5ab42:/sbr/client.c?ds=sidebyside diff --git a/sbr/client.c b/sbr/client.c index 9704f89c..1a7cb7fd 100644 --- a/sbr/client.c +++ b/sbr/client.c @@ -1,6 +1,4 @@ - -/* - * client.c -- connect to a server +/* client.c -- connect to a server * * This code is Copyright (c) 2002, by the authors of nmh. See the * COPYRIGHT file in the root directory of the nmh distribution for @@ -10,45 +8,24 @@ #include #include #include -#include #include #include #include #include - -#define MAXARGS 1000 - -/* - * static prototypes - */ - -/* client's own static version of several nmh subroutines */ -static char **client_brkstring (char *, char *, char *); -static int client_brkany (char, char *); -static char **client_copyip (char **, char **, int); -static char *client_getcpy (char *); -static void client_freelist(char **); +#include int -client (char *args, char *service, char *response, int len_response, int debug) +client (char *server, char *service, char *response, int len_response, + int debug) { int sd, rc; - char **ap, *arguments[MAXARGS]; struct addrinfo hints, *res, *ai; - ap = arguments; - if (args != NULL && *args != 0) { - ap = client_copyip (client_brkstring (client_getcpy (args), " ", "\n"), - ap, MAXARGS); - } else { - if (servers != NULL && *servers != 0) - ap = client_copyip (client_brkstring (client_getcpy (servers), " ", "\n"), - ap, MAXARGS); - } - if (ap == arguments) { - *ap++ = client_getcpy ("localhost"); - *ap = NULL; + if (!server || *server == '\0') { + snprintf(response, len_response, "Internal error: NULL server name " + "passed to client()"); + return NOTOK; } memset(&hints, 0, sizeof(hints)); @@ -58,150 +35,69 @@ client (char *args, char *service, char *response, int len_response, int debug) hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; - for (ap = arguments; *ap; ap++) { - - if (debug) { - fprintf(stderr, "Trying to connect to \"%s\" ...\n", *ap); - } - - rc = getaddrinfo(*ap, service, &hints, &res); - - if (rc) { - if (debug) { - fprintf(stderr, "Lookup of \"%s\" failed: %s\n", *ap, - gai_strerror(rc)); - } - continue; - } - - for (ai = res; ai != NULL; ai = ai->ai_next) { - if (debug) { - char address[NI_MAXHOST]; - char port[NI_MAXSERV]; - - rc = getnameinfo(ai->ai_addr, ai->ai_addrlen, address, - sizeof(address), port, sizeof port, - NI_NUMERICHOST | NI_NUMERICSERV); - - fprintf(stderr, "Connecting to %s:%s...\n", - rc ? "unknown" : address, - rc ? "--" : port); - } - - sd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); - - if (sd < 0) { - if (debug) - fprintf(stderr, "socket() failed: %s\n", strerror(errno)); - continue; - } - - if (connect(sd, ai->ai_addr, ai->ai_addrlen) == 0) { - freeaddrinfo(res); - client_freelist(arguments); - return sd; - } - - if (debug) { - fprintf(stderr, "Connection failed: %s\n", strerror(errno)); - } + if (debug) { + fprintf(stderr, "Trying to connect to \"%s\" ...\n", server); + } - close(sd); - } + rc = getaddrinfo(server, service, &hints, &res); - freeaddrinfo(res); + if (rc) { + snprintf(response, len_response, "Lookup of \"%s\" failed: %s", + server, gai_strerror(rc)); + return NOTOK; } - client_freelist(arguments); - strncpy (response, "no servers available", len_response); - return NOTOK; -} + for (ai = res; ai != NULL; ai = ai->ai_next) { + if (debug) { + char address[NI_MAXHOST]; + char port[NI_MAXSERV]; + rc = getnameinfo(ai->ai_addr, ai->ai_addrlen, address, + sizeof(address), port, sizeof port, + NI_NUMERICHOST | NI_NUMERICSERV); -/* - * Free a list of strings - */ + fprintf(stderr, "Connecting to %s:%s...\n", + rc ? "unknown" : address, rc ? "--" : port); + } -static void -client_freelist(char **list) -{ - free(*list); -} + sd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + if (sd < 0) { + if (debug) + fprintf(stderr, "socket() failed: %s\n", strerror(errno)); + rc = errno; + continue; + } -/* - * static copies of three nmh subroutines - */ + if (connect(sd, ai->ai_addr, ai->ai_addrlen) == 0) { + freeaddrinfo(res); + return sd; + } -static char *broken[MAXARGS + 1]; + rc = errno; -static char ** -client_brkstring (char *strg, char *brksep, char *brkterm) -{ - register int bi; - register char c, *sp; - - sp = strg; - - for (bi = 0; bi < MAXARGS; bi++) { - while (client_brkany (c = *sp, brksep)) - *sp++ = 0; - if (!c || client_brkany (c, brkterm)) { - *sp = 0; - broken[bi] = 0; - return broken; + if (debug) { + fprintf(stderr, "Connection failed: %s\n", strerror(errno)); } - broken[bi] = sp; - while ((c = *++sp) && !client_brkany (c, brksep) && !client_brkany (c, brkterm)) - continue; + close(sd); } - broken[MAXARGS] = 0; - return broken; -} + /* + * Improve error handling a bit. If we were given multiple IP addresses + * then return the old "no servers available" error, but point the user + * to -snoop (hopefully that's universal). Otherwise report a specific + * error. + */ + if (res->ai_next) + snprintf(response, len_response, "no servers available (use -snoop " + "for details"); + else + snprintf(response, len_response, "Connection to \"%s\" failed: %s", + server, strerror(errno)); -/* - * returns 1 if chr in strg, 0 otherwise - */ -static int -client_brkany (char chr, char *strg) -{ - register char *sp; + freeaddrinfo(res); - if (strg) - for (sp = strg; *sp; sp++) - if (chr == *sp) - return 1; - return 0; -} - - -/* - * copy a string array and return pointer to end - */ -static char ** -client_copyip (char **p, char **q, int len_q) -{ - while (*p && --len_q > 0) - *q++ = *p++; - - *q = NULL; - - return q; -} - - -static char * -client_getcpy (char *str) -{ - char *cp; - size_t len; - - len = strlen(str) + 1; - cp = mh_xmalloc(len); - - memcpy (cp, str, len); - return cp; + return NOTOK; }