diff --git a/CHANGES b/CHANGES index 3771f3383d..1809657c65 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,5 @@ +4824. [port] Add iOS hooks to dig. [RT #42011] + 4823. [test] Refactor reclimit system test to improve its reliability and speed. [RT #46632] diff --git a/bin/dig/dig.c b/bin/dig/dig.c index abd150a07e..ec923acdae 100644 --- a/bin/dig/dig.c +++ b/bin/dig/dig.c @@ -109,6 +109,11 @@ print_usage(FILE *fp) { " [ host [@local-server] {local-d-opt} [...]]\n", fp); } +#if TARGET_OS_IPHONE +static void usage(void) { + fprintf(stderr, "Press for complete list of options\n"); +} +#else ISC_PLATFORM_NORETURN_PRE static void usage(void) ISC_PLATFORM_NORETURN_POST; @@ -119,6 +124,7 @@ usage(void) { "for complete list of options\n", stderr); exit(1); } +#endif /*% version */ static void @@ -818,8 +824,10 @@ plus_option(const char *option, isc_boolean_t is_batchfile, goto invalid_option; result = parse_uint(&num, value, COMMSIZE, "buffer size"); - if (result != ISC_R_SUCCESS) - fatal("Couldn't parse buffer size"); + if (result != ISC_R_SUCCESS) { + warn("Couldn't parse buffer size"); + goto exit_or_usage; + } lookup->udpsize = num; break; default: @@ -864,8 +872,10 @@ plus_option(const char *option, isc_boolean_t is_batchfile, if (value != NULL) { n = strlcpy(hexcookie, value, sizeof(hexcookie)); - if (n >= sizeof(hexcookie)) - fatal("COOKIE data too large"); + if (n >= sizeof(hexcookie)) { + warn("COOKIE data too large"); + goto exit_or_usage; + } lookup->cookie = hexcookie; } else lookup->cookie = NULL; @@ -916,8 +926,10 @@ plus_option(const char *option, isc_boolean_t is_batchfile, if (value == NULL) goto need_value; result = parse_uint(&num, value, 0x3f, "DSCP"); - if (result != ISC_R_SUCCESS) - fatal("Couldn't parse DSCP value"); + if (result != ISC_R_SUCCESS) { + warn("Couldn't parse DSCP value"); + goto exit_or_usage; + } lookup->dscp = num; break; default: @@ -946,9 +958,11 @@ plus_option(const char *option, isc_boolean_t is_batchfile, value, 255, "edns"); - if (result != ISC_R_SUCCESS) - fatal("Couldn't parse " + if (result != ISC_R_SUCCESS) { + warn("Couldn't parse " "edns"); + goto exit_or_usage; + } lookup->edns = num; break; case 'f': @@ -965,9 +979,11 @@ plus_option(const char *option, isc_boolean_t is_batchfile, value, 0xffff, "ednsflags"); - if (result != ISC_R_SUCCESS) - fatal("Couldn't parse " + if (result != ISC_R_SUCCESS) { + warn("Couldn't parse " "ednsflags"); + goto exit_or_usage; + } lookup->ednsflags = num; break; case 'n': @@ -980,10 +996,12 @@ plus_option(const char *option, isc_boolean_t is_batchfile, lookup->ednsoptscnt = 0; break; } - if (value == NULL) - fatal("ednsopt no " - "code point " - "specified"); + if (value == NULL) { + warn("ednsopt no " + "code point " + "specified"); + goto exit_or_usage; + } code = next_token(&value, ":"); save_opt(lookup, code, value); break; @@ -1098,8 +1116,10 @@ plus_option(const char *option, isc_boolean_t is_batchfile, if (!state) goto invalid_option; result = parse_uint(&num, value, MAXNDOTS, "ndots"); - if (result != ISC_R_SUCCESS) - fatal("Couldn't parse ndots"); + if (result != ISC_R_SUCCESS) { + warn("Couldn't parse ndots"); + goto exit_or_usage; + } ndots = num; break; case 's': @@ -1161,8 +1181,10 @@ plus_option(const char *option, isc_boolean_t is_batchfile, break; } result = parse_uint(&num, value, 15, "opcode"); - if (result != ISC_R_SUCCESS) - fatal("Couldn't parse opcode"); + if (result != ISC_R_SUCCESS) { + warn("Couldn't parse opcode"); + goto exit_or_usage; + } lookup->opcode = (dns_opcode_t)num; break; default: @@ -1176,8 +1198,10 @@ plus_option(const char *option, isc_boolean_t is_batchfile, if (value == NULL) goto need_value; result = parse_uint(&num, value, 512, "padding"); - if (result != ISC_R_SUCCESS) - fatal("Couldn't parse padding"); + if (result != ISC_R_SUCCESS) { + warn("Couldn't parse padding"); + goto exit_or_usage; + } lookup->padding = (isc_uint16_t)num; break; case 'q': @@ -1216,8 +1240,10 @@ plus_option(const char *option, isc_boolean_t is_batchfile, goto invalid_option; result = parse_uint(&lookup->retries, value, MAXTRIES - 1, "retries"); - if (result != ISC_R_SUCCESS) - fatal("Couldn't parse retries"); + if (result != ISC_R_SUCCESS) { + warn("Couldn't parse retries"); + goto exit_or_usage; + } lookup->retries++; break; default: @@ -1300,8 +1326,10 @@ plus_option(const char *option, isc_boolean_t is_batchfile, */ if (splitwidth) splitwidth += 3; - if (result != ISC_R_SUCCESS) - fatal("Couldn't parse split"); + if (result != ISC_R_SUCCESS) { + warn("Couldn't parse split"); + goto exit_or_usage; + } break; case 't': /* stats */ FULLCHECK("stats"); @@ -1325,8 +1353,10 @@ plus_option(const char *option, isc_boolean_t is_batchfile, lookup->ecs_addr = NULL; } result = parse_netprefix(&lookup->ecs_addr, value); - if (result != ISC_R_SUCCESS) - fatal("Couldn't parse client"); + if (result != ISC_R_SUCCESS) { + warn("Couldn't parse client"); + goto exit_or_usage; + } break; default: goto invalid_option; @@ -1349,8 +1379,10 @@ plus_option(const char *option, isc_boolean_t is_batchfile, goto invalid_option; result = parse_uint(&timeout, value, MAXTIMEOUT, "timeout"); - if (result != ISC_R_SUCCESS) - fatal("Couldn't parse timeout"); + if (result != ISC_R_SUCCESS) { + warn("Couldn't parse timeout"); + goto exit_or_usage; + } if (timeout == 0) timeout = 1; break; @@ -1386,8 +1418,10 @@ plus_option(const char *option, isc_boolean_t is_batchfile, goto invalid_option; result = parse_uint(&lookup->retries, value, MAXTRIES, "tries"); - if (result != ISC_R_SUCCESS) - fatal("Couldn't parse tries"); + if (result != ISC_R_SUCCESS) { + warn("Couldn't parse tries"); + goto exit_or_usage; + } if (lookup->retries == 0) lookup->retries = 1; break; @@ -1444,11 +1478,19 @@ plus_option(const char *option, isc_boolean_t is_batchfile, default: invalid_option: need_value: +#if TARGET_OS_IPHONE + exit_or_usage: +#endif fprintf(stderr, "Invalid option: +%s\n", option); usage(); } return; + +#if ! TARGET_OS_IPHONE + exit_or_usage: + digexit(); +#endif } /*% diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c index 1b3191a0e0..c4d96d2aa7 100644 --- a/bin/dig/dighost.c +++ b/bin/dig/dighost.c @@ -375,6 +375,46 @@ get_reverse(char *reverse, size_t len, char *value, isc_boolean_t ip6_int, } } +void (*dighost_pre_exit_hook)(void) = NULL; + +#if TARGET_OS_IPHONE +void +warn(const char *format, ...) { + va_list args; + + fflush(stdout); + fprintf(stderr, ";; Warning: "); + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + fprintf(stderr, "\n"); +} +#else +void +warn(const char *format, ...) { + va_list args; + + fflush(stdout); + fprintf(stderr, "%s: ", progname); + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + fprintf(stderr, "\n"); +} +#endif + +void +digexit(void) { + if (exitcode < 10) + exitcode = 10; + if (fatalexit != 0) + exitcode = fatalexit; + if (dighost_pre_exit_hook != NULL) { + dighost_pre_exit_hook(); + } + exit(exitcode); +} + void fatal(const char *format, ...) { va_list args; @@ -385,11 +425,7 @@ fatal(const char *format, ...) { vfprintf(stderr, format, args); va_end(args); fprintf(stderr, "\n"); - if (exitcode < 10) - exitcode = 10; - if (fatalexit != 0) - exitcode = fatalexit; - exit(exitcode); + digexit(); } void @@ -2161,9 +2197,13 @@ setup_lookup(dig_lookup_t *lookup) { if (result != ISC_R_SUCCESS) { dns_message_puttempname(lookup->sendmsg, &lookup->name); - fatal("'%s' is not a legal name " + warn("'%s' is not a legal name " "(%s)", lookup->textname, isc_result_totext(result)); +#if TARGET_OS_IPHONE + check_next_lookup(current_lookup); + return (ISC_FALSE); +#endif } } dns_name_format(lookup->name, store, sizeof(store)); diff --git a/bin/dig/include/dig/dig.h b/bin/dig/include/dig/dig.h index e34ee02f48..748a0a5ead 100644 --- a/bin/dig/include/dig/dig.h +++ b/bin/dig/include/dig/dig.h @@ -26,6 +26,10 @@ #include #include +#ifdef __APPLE__ +#include +#endif + #define MXSERV 20 #define MXNAME (DNS_NAME_MAXTEXT+1) #define MXRD 32 @@ -282,6 +286,13 @@ ISC_PLATFORM_NORETURN_PRE void fatal(const char *format, ...) ISC_FORMAT_PRINTF(1, 2) ISC_PLATFORM_NORETURN_POST; +void +warn(const char *format, ...) ISC_FORMAT_PRINTF(1, 2); + +ISC_PLATFORM_NORETURN_PRE void +digexit(void) +ISC_PLATFORM_NORETURN_POST; + void debug(const char *format, ...) ISC_FORMAT_PRINTF(1, 2); @@ -384,6 +395,9 @@ extern void extern void (*dighost_shutdown)(void); +extern void +(*dighost_pre_exit_hook)(void); + void save_opt(dig_lookup_t *lookup, char *code, char *value); void setup_file_key(void);