diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-08-01 19:42:46 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-08-01 19:42:46 +0200 |
commit | 9408978a438ac6c3becb2216d663216d27b59eab (patch) | |
tree | 5f5e4be84543ba3b91570d7cab3f2e9a673a97c8 | |
parent | d01c9aa7ca949220e76d28972359f97dd0b040b1 (diff) | |
download | busybox-w32-9408978a438ac6c3becb2216d663216d27b59eab.tar.gz busybox-w32-9408978a438ac6c3becb2216d663216d27b59eab.tar.bz2 busybox-w32-9408978a438ac6c3becb2216d663216d27b59eab.zip |
nslookup: add support for search domains, closes 11161
function old new delta
parse_resolvconf - 311 +311
add_query_with_search - 105 +105
nslookup_main 873 757 -116
------------------------------------------------------------------------------
(add/remove: 2/0 grow/shrink: 0/1 up/down: 416/-116) Total: 300 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | networking/nslookup.c | 104 |
1 files changed, 82 insertions, 22 deletions
diff --git a/networking/nslookup.c b/networking/nslookup.c index 3a614b0c6..e153eb585 100644 --- a/networking/nslookup.c +++ b/networking/nslookup.c | |||
@@ -318,6 +318,8 @@ struct globals { | |||
318 | unsigned serv_count; | 318 | unsigned serv_count; |
319 | struct ns *server; | 319 | struct ns *server; |
320 | struct query *query; | 320 | struct query *query; |
321 | char *search; | ||
322 | smalluint have_search_directive; | ||
321 | } FIX_ALIASING; | 323 | } FIX_ALIASING; |
322 | #define G (*(struct globals*)bb_common_bufsiz1) | 324 | #define G (*(struct globals*)bb_common_bufsiz1) |
323 | #define INIT_G() do { \ | 325 | #define INIT_G() do { \ |
@@ -667,24 +669,60 @@ static void parse_resolvconf(void) | |||
667 | 669 | ||
668 | resolv = fopen("/etc/resolv.conf", "r"); | 670 | resolv = fopen("/etc/resolv.conf", "r"); |
669 | if (resolv) { | 671 | if (resolv) { |
670 | char line[128], *p; | 672 | char line[512]; /* "search" is defined to be up to 256 chars */ |
671 | 673 | ||
672 | while (fgets(line, sizeof(line), resolv)) { | 674 | while (fgets(line, sizeof(line), resolv)) { |
673 | p = strtok(line, " \t\n"); | 675 | char *p, *arg; |
674 | 676 | ||
675 | if (!p || strcmp(p, "nameserver") != 0) | 677 | p = strtok(line, " \t\n"); |
678 | if (!p) | ||
679 | continue; | ||
680 | dbg("resolv_key:'%s'\n", p); | ||
681 | arg = strtok(NULL, "\n"); | ||
682 | dbg("resolv_arg:'%s'\n", arg); | ||
683 | if (!arg) | ||
676 | continue; | 684 | continue; |
677 | 685 | ||
678 | p = strtok(NULL, " \t\n"); | 686 | if (strcmp(p, "domain") == 0) { |
687 | /* domain DOM */ | ||
688 | if (!G.have_search_directive) | ||
689 | goto set_search; | ||
690 | continue; | ||
691 | } | ||
692 | if (strcmp(p, "search") == 0) { | ||
693 | /* search DOM1 DOM2... */ | ||
694 | G.have_search_directive = 1; | ||
695 | set_search: | ||
696 | free(G.search); | ||
697 | G.search = xstrdup(arg); | ||
698 | dbg("search='%s'\n", G.search); | ||
699 | continue; | ||
700 | } | ||
679 | 701 | ||
680 | if (!p) | 702 | if (strcmp(p, "nameserver") != 0) |
681 | continue; | 703 | continue; |
682 | 704 | ||
683 | add_ns(xstrdup(p)); | 705 | /* nameserver DNS */ |
706 | add_ns(xstrdup(arg)); | ||
684 | } | 707 | } |
685 | 708 | ||
686 | fclose(resolv); | 709 | fclose(resolv); |
687 | } | 710 | } |
711 | |||
712 | if (!G.search) { | ||
713 | /* default search domain is domain part of hostname */ | ||
714 | char *h = safe_gethostname(); | ||
715 | char *d = strchr(h, '.'); | ||
716 | if (d) { | ||
717 | G.search = d + 1; | ||
718 | dbg("search='%s' (from hostname)\n", G.search); | ||
719 | } | ||
720 | /* else free(h); */ | ||
721 | } | ||
722 | |||
723 | /* Cater for case of "domain ." in resolv.conf */ | ||
724 | if (G.search && LONE_CHAR(G.search, '.')) | ||
725 | G.search = NULL; | ||
688 | } | 726 | } |
689 | 727 | ||
690 | static void add_query(int type, const char *dname) | 728 | static void add_query(int type, const char *dname) |
@@ -695,7 +733,7 @@ static void add_query(int type, const char *dname) | |||
695 | 733 | ||
696 | count = G.query_count++; | 734 | count = G.query_count++; |
697 | 735 | ||
698 | G.query = xrealloc_vector(G.query, /*2=2^1:*/ 1, count); | 736 | G.query = xrealloc_vector(G.query, /*4=2^2:*/ 2, count); |
699 | new_q = &G.query[count]; | 737 | new_q = &G.query[count]; |
700 | 738 | ||
701 | dbg("new query#%u type %u for '%s'\n", count, type, dname); | 739 | dbg("new query#%u type %u for '%s'\n", count, type, dname); |
@@ -709,6 +747,28 @@ static void add_query(int type, const char *dname) | |||
709 | new_q->qlen = qlen; | 747 | new_q->qlen = qlen; |
710 | } | 748 | } |
711 | 749 | ||
750 | static void add_query_with_search(int type, const char *dname) | ||
751 | { | ||
752 | char *s; | ||
753 | |||
754 | if (type == T_PTR || !G.search || strchr(dname, '.')) { | ||
755 | add_query(type, dname); | ||
756 | return; | ||
757 | } | ||
758 | |||
759 | s = G.search; | ||
760 | for (;;) { | ||
761 | char *fullname, *e; | ||
762 | |||
763 | e = skip_non_whitespace(s); | ||
764 | fullname = xasprintf("%s.%.*s", dname, (int)(e - s), s); | ||
765 | add_query(type, fullname); | ||
766 | s = skip_whitespace(e); | ||
767 | if (!*s) | ||
768 | break; | ||
769 | } | ||
770 | } | ||
771 | |||
712 | static char *make_ptr(const char *addrstr) | 772 | static char *make_ptr(const char *addrstr) |
713 | { | 773 | { |
714 | unsigned char addr[16]; | 774 | unsigned char addr[16]; |
@@ -833,6 +893,18 @@ int nslookup_main(int argc UNUSED_PARAM, char **argv) | |||
833 | } | 893 | } |
834 | } | 894 | } |
835 | 895 | ||
896 | /* Use given DNS server if present */ | ||
897 | if (argv[1]) { | ||
898 | if (argv[2]) | ||
899 | bb_show_usage(); | ||
900 | add_ns(argv[1]); | ||
901 | } else { | ||
902 | parse_resolvconf(); | ||
903 | /* Fall back to localhost if we could not find NS in resolv.conf */ | ||
904 | if (G.serv_count == 0) | ||
905 | add_ns("127.0.0.1"); | ||
906 | } | ||
907 | |||
836 | if (types == 0) { | 908 | if (types == 0) { |
837 | /* No explicit type given, guess query type. | 909 | /* No explicit type given, guess query type. |
838 | * If we can convert the domain argument into a ptr (means that | 910 | * If we can convert the domain argument into a ptr (means that |
@@ -846,31 +918,19 @@ int nslookup_main(int argc UNUSED_PARAM, char **argv) | |||
846 | if (ptr) { | 918 | if (ptr) { |
847 | add_query(T_PTR, ptr); | 919 | add_query(T_PTR, ptr); |
848 | } else { | 920 | } else { |
849 | add_query(T_A, argv[0]); | 921 | add_query_with_search(T_A, argv[0]); |
850 | #if ENABLE_FEATURE_IPV6 | 922 | #if ENABLE_FEATURE_IPV6 |
851 | add_query(T_AAAA, argv[0]); | 923 | add_query_with_search(T_AAAA, argv[0]); |
852 | #endif | 924 | #endif |
853 | } | 925 | } |
854 | } else { | 926 | } else { |
855 | int c; | 927 | int c; |
856 | for (c = 0; c < ARRAY_SIZE(qtypes); c++) { | 928 | for (c = 0; c < ARRAY_SIZE(qtypes); c++) { |
857 | if (types & (1 << c)) | 929 | if (types & (1 << c)) |
858 | add_query(qtypes[c].type, argv[0]); | 930 | add_query_with_search(qtypes[c].type, argv[0]); |
859 | } | 931 | } |
860 | } | 932 | } |
861 | 933 | ||
862 | /* Use given DNS server if present */ | ||
863 | if (argv[1]) { | ||
864 | if (argv[2]) | ||
865 | bb_show_usage(); | ||
866 | add_ns(argv[1]); | ||
867 | } else { | ||
868 | parse_resolvconf(); | ||
869 | /* Fall back to localhost if we could not find NS in resolv.conf */ | ||
870 | if (G.serv_count == 0) | ||
871 | add_ns("127.0.0.1"); | ||
872 | } | ||
873 | |||
874 | for (rc = 0; rc < G.serv_count;) { | 934 | for (rc = 0; rc < G.serv_count;) { |
875 | int c; | 935 | int c; |
876 | 936 | ||