From 3a02925103a21d6ca0a4c4b4ae4e52bcfd9257bf Mon Sep 17 00:00:00 2001 From: Brad House Date: Sun, 15 Dec 2024 12:28:35 -0500 Subject: [PATCH] adig and ahost should return failure exit codes on resolution failures --- docs/adig.1 | 15 +++++++++++++++ docs/ahost.1 | 16 ++++++++++++++++ src/tools/adig.c | 29 ++++++++++++++++++++--------- src/tools/ahost.c | 23 +++++++++++++++++------ 4 files changed, 68 insertions(+), 15 deletions(-) diff --git a/docs/adig.1 b/docs/adig.1 index e0b81c91e3..b13ded1101 100644 --- a/docs/adig.1 +++ b/docs/adig.1 @@ -170,6 +170,21 @@ Alias for +[no]tcp ${XDG_CONFIG_HOME}/adigrc +.SH RETURN VALUES +.TP +\fB0\fR +Success +.TP +\fB1\fR +Internal System Error +.TP +\fB2\fR +Command line misuse +.TP +\fB3\fR +At least one DNS query failed +.TP + .SH "REPORTING BUGS" Report bugs to the c-ares github issues tracker .br diff --git a/docs/ahost.1 b/docs/ahost.1 index e17057273f..a3c9a99163 100644 --- a/docs/ahost.1 +++ b/docs/ahost.1 @@ -41,6 +41,22 @@ Specify the \fIdomain\fP to search instead of using the default values from /etc/resolv.conf for DNS configuration; it has no effect on other platforms (such as Win32 or Android). + +.SH RETURN VALUES +.TP +\fB0\fR +Success +.TP +\fB1\fR +Internal System Error +.TP +\fB2\fR +Command line misuse +.TP +\fB3\fR +At least one DNS query failed +.TP + .SH "REPORTING BUGS" Report bugs to the c-ares mailing list: .br diff --git a/src/tools/adig.c b/src/tools/adig.c index fce210a805..c44ed0397d 100644 --- a/src/tools/adig.c +++ b/src/tools/adig.c @@ -56,6 +56,12 @@ # define PATH_MAX 1024 #endif +#define RV_OK 0 /* Success */ +#define RV_SYSERR 1 /* Internal system failure */ +#define RV_MISUSE 2 /* Misuse (command line) */ +#define RV_FAIL 3 /* Resolution failure */ +static int final_rv = RV_OK; + typedef struct { unsigned short port; size_t tries; @@ -773,6 +779,10 @@ static void callback(void *arg, ares_status_t status, size_t timeouts, (void)arg; (void)timeouts; + if (status != ARES_SUCCESS) { + final_rv = RV_FAIL; + } + if (global_config.opts.display_comments) { /* We got a "Server status" */ if (status >= ARES_SUCCESS && status <= ARES_EREFUSED) { @@ -1484,7 +1494,6 @@ int main(int argc, char **argv) { ares_channel_t *channel = NULL; ares_status_t status; - int rv = 0; #ifdef USE_WINSOCK WORD wVersionRequested = MAKEWORD(USE_WINSOCK, USE_WINSOCK); @@ -1495,7 +1504,7 @@ int main(int argc, char **argv) status = (ares_status_t)ares_library_init(ARES_LIB_INIT_ALL); if (status != ARES_SUCCESS) { fprintf(stderr, "ares_library_init: %s\n", ares_strerror((int)status)); - return 1; + return RV_SYSERR; } config_defaults(); @@ -1503,7 +1512,7 @@ int main(int argc, char **argv) if (!read_cmdline(argc, (const char * const *)argv, 1)) { printf("\n** ERROR: %s\n\n", global_config.error); print_help(); - rv = 1; + final_rv = RV_MISUSE; goto done; } @@ -1519,7 +1528,7 @@ int main(int argc, char **argv) if (global_config.name == NULL) { printf("missing query name\n"); print_help(); - rv = 1; + final_rv = RV_MISUSE; goto done; } @@ -1529,7 +1538,7 @@ int main(int argc, char **argv) global_config.optmask); if (status != ARES_SUCCESS) { fprintf(stderr, "ares_init_options: %s\n", ares_strerror((int)status)); - rv = 1; + final_rv = RV_SYSERR; goto done; } @@ -1539,7 +1548,7 @@ int main(int argc, char **argv) if (status != ARES_SUCCESS) { fprintf(stderr, "ares_set_servers_ports_csv: %s: %s\n", ares_strerror((int)status), global_config.servers); - rv = 1; + final_rv = RV_MISUSE; goto done; } } @@ -1556,12 +1565,14 @@ int main(int argc, char **argv) if (status != ARES_SUCCESS) { fprintf(stderr, "Failed to create query for %s: %s\n", global_config.name, ares_strerror((int)status)); - rv = 1; + final_rv = RV_MISUSE; goto done; } /* Process events */ - rv = event_loop(channel); + if (event_loop(channel) != 0) { + final_rv = RV_SYSERR; + } done: free_config(); @@ -1571,5 +1582,5 @@ int main(int argc, char **argv) #ifdef USE_WINSOCK WSACleanup(); #endif - return rv; + return final_rv; } diff --git a/src/tools/ahost.c b/src/tools/ahost.c index 7d1d4a86dc..680bb4b594 100644 --- a/src/tools/ahost.c +++ b/src/tools/ahost.c @@ -44,12 +44,21 @@ #include "ares_str.h" +#define RV_OK 0 /* Success */ +#define RV_SYSERR 1 /* Internal system failure */ +#define RV_MISUSE 2 /* Misuse (command line) */ +#define RV_FAIL 3 /* Resolution failure */ +static int final_rv = RV_OK; + + static void callback(void *arg, int status, int timeouts, struct hostent *host); static void ai_callback(void *arg, int status, int timeouts, struct ares_addrinfo *result); static void usage(void); static void print_help_info_ahost(void); + + int main(int argc, char **argv) { struct ares_options options; @@ -79,7 +88,7 @@ int main(int argc, char **argv) status = ares_library_init(ARES_LIB_INIT_ALL); if (status != ARES_SUCCESS) { fprintf(stderr, "ares_library_init: %s\n", ares_strerror(status)); - return 1; + return RV_SYSERR; } ares_getopt_init(&state, argc, (const char * const *)argv); @@ -139,7 +148,7 @@ int main(int argc, char **argv) if (status != ARES_SUCCESS) { free(servers); fprintf(stderr, "ares_init: %s\n", ares_strerror(status)); - return 1; + return RV_SYSERR; } if (servers) { @@ -148,7 +157,7 @@ int main(int argc, char **argv) fprintf(stderr, "ares_set_serveres_csv: %s\n", ares_strerror(status)); free(servers); usage(); - return 1; + return RV_MISUSE; } free(servers); } @@ -197,7 +206,7 @@ int main(int argc, char **argv) WSACleanup(); #endif - return 0; + return final_rv; } static void callback(void *arg, int status, int timeouts, struct hostent *host) @@ -208,6 +217,7 @@ static void callback(void *arg, int status, int timeouts, struct hostent *host) if (status != ARES_SUCCESS) { fprintf(stderr, "%s: %s\n", (char *)arg, ares_strerror(status)); + final_rv = RV_FAIL; return; } @@ -229,6 +239,7 @@ static void ai_callback(void *arg, int status, int timeouts, if (status != ARES_SUCCESS) { fprintf(stderr, "%s: %s\n", (char *)arg, ares_strerror(status)); + final_rv = RV_FAIL; return; } @@ -257,7 +268,7 @@ static void usage(void) { fprintf(stderr, "usage: ahost [-h] [-d] [[-D {domain}] ...] [-s {server}] " "[-t {a|aaaa|u}] {host|addr} ...\n"); - exit(1); + exit(RV_MISUSE); } /* Information from the man page. Formatting taken from man -h */ @@ -282,5 +293,5 @@ static void print_help_info_ahost(void) " If type is \"aaaa\", print the AAAA record.\n" " If type is \"u\" (default), print both A and AAAA records.\n" "\n"); - exit(0); + exit(RV_OK); }